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";
}