diff --git a/cosmrs/src/bank.rs b/cosmrs/src/bank.rs index cf5ecdff..de6c8a59 100644 --- a/cosmrs/src/bank.rs +++ b/cosmrs/src/bank.rs @@ -60,3 +60,145 @@ impl From<&MsgSend> for proto::cosmos::bank::v1beta1::MsgSend { } } } + +/// MsgMultiSend represents an arbitrary multi-in, multi-out send message. +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +pub struct MsgMultiSend { + /// Sender account/amount pairs. + pub inputs: Vec, + + /// Recipient account/amount pairs. + pub outputs: Vec, +} + +impl Msg for MsgMultiSend { + type Proto = proto::cosmos::bank::v1beta1::MsgMultiSend; +} + +impl TryFrom for MsgMultiSend { + type Error = ErrorReport; + + fn try_from(proto: proto::cosmos::bank::v1beta1::MsgMultiSend) -> Result { + MsgMultiSend::try_from(&proto) + } +} + +impl TryFrom<&proto::cosmos::bank::v1beta1::MsgMultiSend> for MsgMultiSend { + type Error = ErrorReport; + + fn try_from(proto: &proto::cosmos::bank::v1beta1::MsgMultiSend) -> Result { + Ok(MsgMultiSend { + inputs: proto + .inputs + .iter() + .map(TryFrom::try_from) + .collect::>()?, + outputs: proto + .outputs + .iter() + .map(TryFrom::try_from) + .collect::>()?, + }) + } +} + +impl From for proto::cosmos::bank::v1beta1::MsgMultiSend { + fn from(coin: MsgMultiSend) -> proto::cosmos::bank::v1beta1::MsgMultiSend { + proto::cosmos::bank::v1beta1::MsgMultiSend::from(&coin) + } +} + +impl From<&MsgMultiSend> for proto::cosmos::bank::v1beta1::MsgMultiSend { + fn from(msg: &MsgMultiSend) -> proto::cosmos::bank::v1beta1::MsgMultiSend { + proto::cosmos::bank::v1beta1::MsgMultiSend { + inputs: msg.inputs.iter().map(Into::into).collect(), + outputs: msg.outputs.iter().map(Into::into).collect(), + } + } +} + +/// Represents a MultiSend Input or Output +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +pub struct MultiSendIo { + /// The address that `coins` will be sent to/from + pub address: AccountId, + + /// The coins to send to/from `address` + pub coins: Vec, +} + +impl TryFrom for MultiSendIo { + type Error = ErrorReport; + + fn try_from(proto: proto::cosmos::bank::v1beta1::Input) -> Result { + MultiSendIo::try_from(&proto) + } +} + +impl TryFrom<&proto::cosmos::bank::v1beta1::Input> for MultiSendIo { + type Error = ErrorReport; + + fn try_from(proto: &proto::cosmos::bank::v1beta1::Input) -> Result { + Ok(MultiSendIo { + address: proto.address.parse()?, + coins: proto + .coins + .iter() + .map(TryFrom::try_from) + .collect::>()?, + }) + } +} + +impl TryFrom for MultiSendIo { + type Error = ErrorReport; + + fn try_from(proto: proto::cosmos::bank::v1beta1::Output) -> Result { + MultiSendIo::try_from(&proto) + } +} + +impl TryFrom<&proto::cosmos::bank::v1beta1::Output> for MultiSendIo { + type Error = ErrorReport; + + fn try_from(proto: &proto::cosmos::bank::v1beta1::Output) -> Result { + Ok(MultiSendIo { + address: proto.address.parse()?, + coins: proto + .coins + .iter() + .map(TryFrom::try_from) + .collect::>()?, + }) + } +} + +impl From for proto::cosmos::bank::v1beta1::Output { + fn from(output: MultiSendIo) -> proto::cosmos::bank::v1beta1::Output { + proto::cosmos::bank::v1beta1::Output::from(&output) + } +} + +impl From<&MultiSendIo> for proto::cosmos::bank::v1beta1::Output { + fn from(output: &MultiSendIo) -> proto::cosmos::bank::v1beta1::Output { + proto::cosmos::bank::v1beta1::Output { + address: output.address.to_string(), + coins: output.coins.iter().map(Into::into).collect(), + } + } +} + +impl From for proto::cosmos::bank::v1beta1::Input { + fn from(input: MultiSendIo) -> proto::cosmos::bank::v1beta1::Input { + proto::cosmos::bank::v1beta1::Input::from(&input) + } +} + +impl From<&MultiSendIo> for proto::cosmos::bank::v1beta1::Input { + fn from(input: &MultiSendIo) -> proto::cosmos::bank::v1beta1::Input { + proto::cosmos::bank::v1beta1::Input { + address: input.address.to_string(), + coins: input.coins.iter().map(Into::into).collect(), + } + } +} diff --git a/cosmrs/src/tx/msg.rs b/cosmrs/src/tx/msg.rs index 6de6de5d..cd0e089d 100644 --- a/cosmrs/src/tx/msg.rs +++ b/cosmrs/src/tx/msg.rs @@ -61,6 +61,10 @@ impl MsgProto for proto::cosmos::bank::v1beta1::MsgSend { const TYPE_URL: &'static str = "/cosmos.bank.v1beta1.MsgSend"; } +impl MsgProto for proto::cosmos::bank::v1beta1::MsgMultiSend { + const TYPE_URL: &'static str = "/cosmos.bank.v1beta1.MsgMultiSend"; +} + impl MsgProto for proto::cosmos::distribution::v1beta1::MsgSetWithdrawAddress { const TYPE_URL: &'static str = "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress"; }