diff --git a/cosmos-sdk-rs/src/distribution.rs b/cosmos-sdk-rs/src/distribution.rs new file mode 100644 index 00000000..d975c89b --- /dev/null +++ b/cosmos-sdk-rs/src/distribution.rs @@ -0,0 +1,291 @@ +//! Distribution module support +//! +//! + +use crate::{ + proto, + tx::{Msg, MsgType}, + AccountId, Coin, Result, +}; +use std::convert::{TryFrom, TryInto}; + +/// MsgSetWithdrawAddress represents a message to set a withdraw address for staking rewards. +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +pub struct MsgSetWithdrawAddress { + /// Delegator's address. + pub delegator_address: AccountId, + + /// withdraw address. + pub withdraw_address: AccountId, +} + +impl MsgType for MsgSetWithdrawAddress { + fn from_msg(msg: &Msg) -> Result { + proto::cosmos::distribution::v1beta1::MsgSetWithdrawAddress::from_msg(msg) + .and_then(TryInto::try_into) + } + + fn to_msg(&self) -> Result { + proto::cosmos::distribution::v1beta1::MsgSetWithdrawAddress::from(self).to_msg() + } +} + +impl TryFrom + for MsgSetWithdrawAddress +{ + type Error = eyre::Report; + + fn try_from( + proto: proto::cosmos::distribution::v1beta1::MsgSetWithdrawAddress, + ) -> Result { + MsgSetWithdrawAddress::try_from(&proto) + } +} + +impl TryFrom<&proto::cosmos::distribution::v1beta1::MsgSetWithdrawAddress> + for MsgSetWithdrawAddress +{ + type Error = eyre::Report; + + fn try_from( + proto: &proto::cosmos::distribution::v1beta1::MsgSetWithdrawAddress, + ) -> Result { + Ok(MsgSetWithdrawAddress { + delegator_address: proto.delegator_address.parse()?, + withdraw_address: proto.withdraw_address.parse()?, + }) + } +} + +impl From for proto::cosmos::distribution::v1beta1::MsgSetWithdrawAddress { + fn from( + coin: MsgSetWithdrawAddress, + ) -> proto::cosmos::distribution::v1beta1::MsgSetWithdrawAddress { + proto::cosmos::distribution::v1beta1::MsgSetWithdrawAddress::from(&coin) + } +} + +impl From<&MsgSetWithdrawAddress> for proto::cosmos::distribution::v1beta1::MsgSetWithdrawAddress { + fn from( + msg: &MsgSetWithdrawAddress, + ) -> proto::cosmos::distribution::v1beta1::MsgSetWithdrawAddress { + proto::cosmos::distribution::v1beta1::MsgSetWithdrawAddress { + delegator_address: msg.delegator_address.to_string(), + withdraw_address: msg.withdraw_address.to_string(), + } + } +} + +/// MsgWithdrawDelegatorReward represents a message to withdraw a delegator's reward from a validator. +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +pub struct MsgWithdrawDelegatorReward { + /// Delegator's address. + pub delegator_address: AccountId, + + /// Validator's address. + pub validator_address: AccountId, +} + +impl MsgType for MsgWithdrawDelegatorReward { + fn from_msg(msg: &Msg) -> Result { + proto::cosmos::distribution::v1beta1::MsgWithdrawDelegatorReward::from_msg(msg) + .and_then(TryInto::try_into) + } + + fn to_msg(&self) -> Result { + proto::cosmos::distribution::v1beta1::MsgWithdrawDelegatorReward::from(self).to_msg() + } +} + +impl TryFrom + for MsgWithdrawDelegatorReward +{ + type Error = eyre::Report; + + fn try_from( + proto: proto::cosmos::distribution::v1beta1::MsgWithdrawDelegatorReward, + ) -> Result { + MsgWithdrawDelegatorReward::try_from(&proto) + } +} + +impl TryFrom<&proto::cosmos::distribution::v1beta1::MsgWithdrawDelegatorReward> + for MsgWithdrawDelegatorReward +{ + type Error = eyre::Report; + + fn try_from( + proto: &proto::cosmos::distribution::v1beta1::MsgWithdrawDelegatorReward, + ) -> Result { + Ok(MsgWithdrawDelegatorReward { + delegator_address: proto.delegator_address.parse()?, + validator_address: proto.validator_address.parse()?, + }) + } +} + +impl From + for proto::cosmos::distribution::v1beta1::MsgWithdrawDelegatorReward +{ + fn from( + coin: MsgWithdrawDelegatorReward, + ) -> proto::cosmos::distribution::v1beta1::MsgWithdrawDelegatorReward { + proto::cosmos::distribution::v1beta1::MsgWithdrawDelegatorReward::from(&coin) + } +} + +impl From<&MsgWithdrawDelegatorReward> + for proto::cosmos::distribution::v1beta1::MsgWithdrawDelegatorReward +{ + fn from( + msg: &MsgWithdrawDelegatorReward, + ) -> proto::cosmos::distribution::v1beta1::MsgWithdrawDelegatorReward { + proto::cosmos::distribution::v1beta1::MsgWithdrawDelegatorReward { + delegator_address: msg.delegator_address.to_string(), + validator_address: msg.validator_address.to_string(), + } + } +} + +/// WithdrawValidatorCommission represents a message to withdraw a validator's staking commission. +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +pub struct MsgWithdrawValidatorCommission { + /// Validator's address. + pub validator_address: AccountId, +} + +impl MsgType for MsgWithdrawValidatorCommission { + fn from_msg(msg: &Msg) -> Result { + proto::cosmos::distribution::v1beta1::MsgWithdrawValidatorCommission::from_msg(msg) + .and_then(TryInto::try_into) + } + + fn to_msg(&self) -> Result { + proto::cosmos::distribution::v1beta1::MsgWithdrawValidatorCommission::from(self).to_msg() + } +} + +impl TryFrom + for MsgWithdrawValidatorCommission +{ + type Error = eyre::Report; + + fn try_from( + proto: proto::cosmos::distribution::v1beta1::MsgWithdrawValidatorCommission, + ) -> Result { + MsgWithdrawValidatorCommission::try_from(&proto) + } +} + +impl TryFrom<&proto::cosmos::distribution::v1beta1::MsgWithdrawValidatorCommission> + for MsgWithdrawValidatorCommission +{ + type Error = eyre::Report; + + fn try_from( + proto: &proto::cosmos::distribution::v1beta1::MsgWithdrawValidatorCommission, + ) -> Result { + Ok(MsgWithdrawValidatorCommission { + validator_address: proto.validator_address.parse()?, + }) + } +} + +impl From + for proto::cosmos::distribution::v1beta1::MsgWithdrawValidatorCommission +{ + fn from( + coin: MsgWithdrawValidatorCommission, + ) -> proto::cosmos::distribution::v1beta1::MsgWithdrawValidatorCommission { + proto::cosmos::distribution::v1beta1::MsgWithdrawValidatorCommission::from(&coin) + } +} + +impl From<&MsgWithdrawValidatorCommission> + for proto::cosmos::distribution::v1beta1::MsgWithdrawValidatorCommission +{ + fn from( + msg: &MsgWithdrawValidatorCommission, + ) -> proto::cosmos::distribution::v1beta1::MsgWithdrawValidatorCommission { + proto::cosmos::distribution::v1beta1::MsgWithdrawValidatorCommission { + validator_address: msg.validator_address.to_string(), + } + } +} + +/// MsgFundCommunityPool represents a message to send coins from depositor to the community pool. +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +pub struct MsgFundCommunityPool { + /// Depositor's address. + pub depositor: AccountId, + + /// Amount to deposit. + pub amount: Vec, +} + +impl MsgType for MsgFundCommunityPool { + fn from_msg(msg: &Msg) -> Result { + proto::cosmos::distribution::v1beta1::MsgFundCommunityPool::from_msg(msg) + .and_then(TryInto::try_into) + } + + fn to_msg(&self) -> Result { + proto::cosmos::distribution::v1beta1::MsgFundCommunityPool::from(self).to_msg() + } +} + +impl TryFrom for MsgFundCommunityPool { + type Error = eyre::Report; + + fn try_from( + proto: proto::cosmos::distribution::v1beta1::MsgFundCommunityPool, + ) -> Result { + MsgFundCommunityPool::try_from(&proto) + } +} + +impl TryFrom<&proto::cosmos::distribution::v1beta1::MsgFundCommunityPool> for MsgFundCommunityPool { + type Error = eyre::Report; + + fn try_from( + proto: &proto::cosmos::distribution::v1beta1::MsgFundCommunityPool, + ) -> Result { + let mut amounts = vec![]; + for amount in proto.amount.iter() { + amounts.push(Coin { + denom: amount.denom.parse()?, + amount: amount.amount.parse()?, + }) + } + Ok(MsgFundCommunityPool { + depositor: proto.depositor.parse()?, + amount: amounts, + }) + } +} + +impl From for proto::cosmos::distribution::v1beta1::MsgFundCommunityPool { + fn from( + coin: MsgFundCommunityPool, + ) -> proto::cosmos::distribution::v1beta1::MsgFundCommunityPool { + proto::cosmos::distribution::v1beta1::MsgFundCommunityPool::from(&coin) + } +} + +impl From<&MsgFundCommunityPool> for proto::cosmos::distribution::v1beta1::MsgFundCommunityPool { + fn from( + msg: &MsgFundCommunityPool, + ) -> proto::cosmos::distribution::v1beta1::MsgFundCommunityPool { + let mut amounts = vec![]; + for amount in msg.amount.iter() { + amounts.push(proto::cosmos::base::v1beta1::Coin { + denom: amount.denom.to_string(), + amount: amount.amount.to_string(), + }) + } + proto::cosmos::distribution::v1beta1::MsgFundCommunityPool { + depositor: "".to_string(), + amount: amounts, + } + } +} diff --git a/cosmos-sdk-rs/src/lib.rs b/cosmos-sdk-rs/src/lib.rs index ed5fadbd..cbd51891 100644 --- a/cosmos-sdk-rs/src/lib.rs +++ b/cosmos-sdk-rs/src/lib.rs @@ -28,6 +28,7 @@ pub mod bank; pub mod crypto; +pub mod distribution; pub mod staking; pub mod tx; diff --git a/cosmos-sdk-rs/src/tx/msg.rs b/cosmos-sdk-rs/src/tx/msg.rs index d3dff987..bb532be6 100644 --- a/cosmos-sdk-rs/src/tx/msg.rs +++ b/cosmos-sdk-rs/src/tx/msg.rs @@ -76,6 +76,22 @@ impl MsgProto for proto::cosmos::bank::v1beta1::MsgSend { const TYPE_URL: &'static str = "/cosmos.bank.v1beta1.MsgSend"; } +impl MsgProto for proto::cosmos::distribution::v1beta1::MsgSetWithdrawAddress { + const TYPE_URL: &'static str = "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress"; +} + +impl MsgProto for proto::cosmos::distribution::v1beta1::MsgWithdrawDelegatorReward { + const TYPE_URL: &'static str = "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward"; +} + +impl MsgProto for proto::cosmos::distribution::v1beta1::MsgWithdrawValidatorCommission { + const TYPE_URL: &'static str = "/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommission"; +} + +impl MsgProto for proto::cosmos::distribution::v1beta1::MsgFundCommunityPool { + const TYPE_URL: &'static str = "/cosmos.distribution.v1beta1.MsgFundCommunityPool"; +} + impl MsgProto for proto::cosmos::staking::v1beta1::MsgDelegate { const TYPE_URL: &'static str = "/cosmos.staking.v1beta1.MsgDelegate"; }