Merge pull request #934 from nymtech/feature/client_on_behalf
Feature/client on behalf
This commit is contained in:
@@ -15,6 +15,9 @@ use mixnet_contract::{Delegation, GatewayBond, MixNodeBond};
|
||||
use mixnet_contract::{
|
||||
MixnetContractVersion, MixnodeRewardingStatusResponse, RewardingIntervalResponse,
|
||||
};
|
||||
|
||||
#[cfg(feature = "nymd-client")]
|
||||
use std::str::FromStr;
|
||||
use url::Url;
|
||||
|
||||
#[cfg(feature = "nymd-client")]
|
||||
@@ -22,6 +25,7 @@ pub struct Config {
|
||||
api_url: Url,
|
||||
nymd_url: Url,
|
||||
mixnet_contract_address: Option<cosmrs::AccountId>,
|
||||
vesting_contract_address: Option<cosmrs::AccountId>,
|
||||
|
||||
mixnode_page_limit: Option<u32>,
|
||||
gateway_page_limit: Option<u32>,
|
||||
@@ -34,10 +38,12 @@ impl Config {
|
||||
nymd_url: Url,
|
||||
api_url: Url,
|
||||
mixnet_contract_address: Option<cosmrs::AccountId>,
|
||||
vesting_contract_address: Option<cosmrs::AccountId>,
|
||||
) -> Self {
|
||||
Config {
|
||||
nymd_url,
|
||||
mixnet_contract_address,
|
||||
vesting_contract_address,
|
||||
api_url,
|
||||
mixnode_page_limit: None,
|
||||
gateway_page_limit: None,
|
||||
@@ -64,6 +70,7 @@ impl Config {
|
||||
#[cfg(feature = "nymd-client")]
|
||||
pub struct Client<C> {
|
||||
mixnet_contract_address: Option<cosmrs::AccountId>,
|
||||
vesting_contract_address: Option<cosmrs::AccountId>,
|
||||
mnemonic: Option<bip39::Mnemonic>,
|
||||
|
||||
mixnode_page_limit: Option<u32>,
|
||||
@@ -85,11 +92,13 @@ impl Client<SigningNymdClient> {
|
||||
let nymd_client = NymdClient::connect_with_mnemonic(
|
||||
config.nymd_url.as_str(),
|
||||
config.mixnet_contract_address.clone(),
|
||||
config.vesting_contract_address.clone(),
|
||||
mnemonic.clone(),
|
||||
)?;
|
||||
|
||||
Ok(Client {
|
||||
mixnet_contract_address: config.mixnet_contract_address,
|
||||
vesting_contract_address: config.vesting_contract_address,
|
||||
mnemonic: Some(mnemonic),
|
||||
mixnode_page_limit: config.mixnode_page_limit,
|
||||
gateway_page_limit: config.gateway_page_limit,
|
||||
@@ -103,6 +112,7 @@ impl Client<SigningNymdClient> {
|
||||
self.nymd = NymdClient::connect_with_mnemonic(
|
||||
new_endpoint.as_ref(),
|
||||
self.mixnet_contract_address.clone(),
|
||||
self.vesting_contract_address.clone(),
|
||||
self.mnemonic.clone().unwrap(),
|
||||
)?;
|
||||
Ok(())
|
||||
@@ -115,16 +125,19 @@ impl Client<QueryNymdClient> {
|
||||
let validator_api_client = validator_api::Client::new(config.api_url.clone());
|
||||
let nymd_client = NymdClient::connect(
|
||||
config.nymd_url.as_str(),
|
||||
config
|
||||
.mixnet_contract_address
|
||||
.clone()
|
||||
.ok_or(ValidatorClientError::NymdError(
|
||||
NymdError::NoContractAddressAvailable,
|
||||
))?,
|
||||
config.mixnet_contract_address.clone().unwrap_or_else(|| {
|
||||
cosmrs::AccountId::from_str(network_defaults::DEFAULT_MIXNET_CONTRACT_ADDRESS)
|
||||
.unwrap()
|
||||
}),
|
||||
config.vesting_contract_address.clone().unwrap_or_else(|| {
|
||||
cosmrs::AccountId::from_str(network_defaults::DEFAULT_VESTING_CONTRACT_ADDRESS)
|
||||
.unwrap()
|
||||
}),
|
||||
)?;
|
||||
|
||||
Ok(Client {
|
||||
mixnet_contract_address: config.mixnet_contract_address,
|
||||
vesting_contract_address: config.vesting_contract_address,
|
||||
mnemonic: None,
|
||||
mixnode_page_limit: config.mixnode_page_limit,
|
||||
gateway_page_limit: config.gateway_page_limit,
|
||||
@@ -138,6 +151,7 @@ impl Client<QueryNymdClient> {
|
||||
self.nymd = NymdClient::connect(
|
||||
new_endpoint.as_ref(),
|
||||
self.mixnet_contract_address.clone().unwrap(),
|
||||
self.vesting_contract_address.clone().unwrap(),
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -310,6 +310,33 @@ pub trait SigningCosmWasmClient: CosmWasmClient {
|
||||
.await
|
||||
}
|
||||
|
||||
async fn send_tokens_multiple<I>(
|
||||
&self,
|
||||
sender_address: &AccountId,
|
||||
msgs: I,
|
||||
fee: Fee,
|
||||
memo: impl Into<String> + Send + 'static,
|
||||
) -> Result<broadcast::tx_commit::Response, NymdError>
|
||||
where
|
||||
I: IntoIterator<Item = (AccountId, Vec<Coin>)> + Send,
|
||||
{
|
||||
let messages = msgs
|
||||
.into_iter()
|
||||
.map(|(to_address, amount)| {
|
||||
MsgSend {
|
||||
from_address: sender_address.clone(),
|
||||
to_address,
|
||||
amount,
|
||||
}
|
||||
.to_any()
|
||||
.map_err(|_| NymdError::SerializationError("MsgExecuteContract".to_owned()))
|
||||
})
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
self.sign_and_broadcast_commit(sender_address, messages, fee, memo)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn delegate_tokens(
|
||||
&self,
|
||||
delegator_address: &AccountId,
|
||||
|
||||
@@ -17,12 +17,18 @@ pub enum Operation {
|
||||
Send,
|
||||
|
||||
BondMixnode,
|
||||
BondMixnodeOnBehalf,
|
||||
UnbondMixnode,
|
||||
UnbondMixnodeOnBehalf,
|
||||
DelegateToMixnode,
|
||||
DelegateToMixnodeOnBehalf,
|
||||
UndelegateFromMixnode,
|
||||
UndelegateFromMixnodeOnBehalf,
|
||||
|
||||
BondGateway,
|
||||
BondGatewayOnBehalf,
|
||||
UnbondGateway,
|
||||
UnbondGatewayOnBehalf,
|
||||
|
||||
UpdateStateParams,
|
||||
|
||||
@@ -43,11 +49,19 @@ impl fmt::Display for Operation {
|
||||
Operation::ChangeAdmin => f.write_str("ChangeAdmin"),
|
||||
Operation::Send => f.write_str("Send"),
|
||||
Operation::BondMixnode => f.write_str("BondMixnode"),
|
||||
Operation::BondMixnodeOnBehalf => f.write_str("BondMixnodeOnBehalf"),
|
||||
Operation::UnbondMixnode => f.write_str("UnbondMixnode"),
|
||||
Operation::UnbondMixnodeOnBehalf => f.write_str("UnbondMixnodeOnBehalf"),
|
||||
Operation::BondGateway => f.write_str("BondGateway"),
|
||||
Operation::BondGatewayOnBehalf => f.write_str("BondGatewayOnBehalf"),
|
||||
Operation::UnbondGateway => f.write_str("UnbondGateway"),
|
||||
Operation::UnbondGatewayOnBehalf => f.write_str("UnbondGatewayOnBehalf"),
|
||||
Operation::DelegateToMixnode => f.write_str("DelegateToMixnode"),
|
||||
Operation::DelegateToMixnodeOnBehalf => f.write_str("DelegateToMixnodeOnBehalf"),
|
||||
Operation::UndelegateFromMixnode => f.write_str("UndelegateFromMixnode"),
|
||||
Operation::UndelegateFromMixnodeOnBehalf => {
|
||||
f.write_str("UndelegateFromMixnodeOnBehalf")
|
||||
}
|
||||
Operation::UpdateStateParams => f.write_str("UpdateStateParams"),
|
||||
Operation::BeginMixnodeRewarding => f.write_str("BeginMixnodeRewarding"),
|
||||
Operation::FinishMixnodeRewarding => f.write_str("FinishMixnodeRewarding"),
|
||||
@@ -66,12 +80,18 @@ impl Operation {
|
||||
Operation::Send => 80_000u64.into(),
|
||||
|
||||
Operation::BondMixnode => 175_000u64.into(),
|
||||
Operation::BondMixnodeOnBehalf => 200_000u64.into(),
|
||||
Operation::UnbondMixnode => 175_000u64.into(),
|
||||
Operation::UnbondMixnodeOnBehalf => 175_000u64.into(),
|
||||
Operation::DelegateToMixnode => 175_000u64.into(),
|
||||
Operation::DelegateToMixnodeOnBehalf => 175_000u64.into(),
|
||||
Operation::UndelegateFromMixnode => 175_000u64.into(),
|
||||
Operation::UndelegateFromMixnodeOnBehalf => 175_000u64.into(),
|
||||
|
||||
Operation::BondGateway => 175_000u64.into(),
|
||||
Operation::BondGatewayOnBehalf => 200_000u64.into(),
|
||||
Operation::UnbondGateway => 175_000u64.into(),
|
||||
Operation::UnbondGatewayOnBehalf => 200_000u64.into(),
|
||||
|
||||
Operation::UpdateStateParams => 175_000u64.into(),
|
||||
Operation::BeginMixnodeRewarding => 175_000u64.into(),
|
||||
|
||||
@@ -44,7 +44,8 @@ pub mod wallet;
|
||||
#[derive(Debug)]
|
||||
pub struct NymdClient<C> {
|
||||
client: C,
|
||||
contract_address: Option<AccountId>,
|
||||
mixnet_contract_address: Option<AccountId>,
|
||||
vesting_contract_address: Option<AccountId>,
|
||||
client_address: Option<Vec<AccountId>>,
|
||||
gas_price: GasPrice,
|
||||
custom_gas_limits: HashMap<Operation, Gas>,
|
||||
@@ -53,14 +54,16 @@ pub struct NymdClient<C> {
|
||||
impl NymdClient<QueryNymdClient> {
|
||||
pub fn connect<U>(
|
||||
endpoint: U,
|
||||
contract_address: AccountId,
|
||||
mixnet_contract_address: AccountId,
|
||||
vesting_contract_address: AccountId,
|
||||
) -> Result<NymdClient<QueryNymdClient>, NymdError>
|
||||
where
|
||||
U: TryInto<HttpClientUrl, Error = TendermintRpcError>,
|
||||
{
|
||||
Ok(NymdClient {
|
||||
client: QueryNymdClient::new(endpoint)?,
|
||||
contract_address: Some(contract_address),
|
||||
mixnet_contract_address: Some(mixnet_contract_address),
|
||||
vesting_contract_address: Some(vesting_contract_address),
|
||||
client_address: None,
|
||||
gas_price: Default::default(),
|
||||
custom_gas_limits: Default::default(),
|
||||
@@ -72,7 +75,8 @@ impl NymdClient<SigningNymdClient> {
|
||||
// maybe the wallet could be made into a generic, but for now, let's just have this one implementation
|
||||
pub fn connect_with_signer<U>(
|
||||
endpoint: U,
|
||||
contract_address: Option<AccountId>,
|
||||
mixnet_contract_address: Option<AccountId>,
|
||||
vesting_contract_address: Option<AccountId>,
|
||||
signer: DirectSecp256k1HdWallet,
|
||||
) -> Result<NymdClient<SigningNymdClient>, NymdError>
|
||||
where
|
||||
@@ -86,7 +90,8 @@ impl NymdClient<SigningNymdClient> {
|
||||
|
||||
Ok(NymdClient {
|
||||
client: SigningNymdClient::connect_with_signer(endpoint, signer)?,
|
||||
contract_address,
|
||||
mixnet_contract_address,
|
||||
vesting_contract_address,
|
||||
client_address: Some(client_address),
|
||||
gas_price: Default::default(),
|
||||
custom_gas_limits: Default::default(),
|
||||
@@ -95,7 +100,8 @@ impl NymdClient<SigningNymdClient> {
|
||||
|
||||
pub fn connect_with_mnemonic<U>(
|
||||
endpoint: U,
|
||||
contract_address: Option<AccountId>,
|
||||
mixnet_contract_address: Option<AccountId>,
|
||||
vesting_contract_address: Option<AccountId>,
|
||||
mnemonic: bip39::Mnemonic,
|
||||
) -> Result<NymdClient<SigningNymdClient>, NymdError>
|
||||
where
|
||||
@@ -110,7 +116,8 @@ impl NymdClient<SigningNymdClient> {
|
||||
|
||||
Ok(NymdClient {
|
||||
client: SigningNymdClient::connect_with_signer(endpoint, wallet)?,
|
||||
contract_address,
|
||||
mixnet_contract_address,
|
||||
vesting_contract_address,
|
||||
client_address: Some(client_address),
|
||||
gas_price: Default::default(),
|
||||
custom_gas_limits: Default::default(),
|
||||
@@ -135,15 +142,21 @@ impl<C> NymdClient<C> {
|
||||
self.custom_gas_limits.clone()
|
||||
}
|
||||
|
||||
pub fn contract_address(&self) -> Result<&AccountId, NymdError> {
|
||||
self.contract_address
|
||||
pub fn mixnet_contract_address(&self) -> Result<&AccountId, NymdError> {
|
||||
self.mixnet_contract_address
|
||||
.as_ref()
|
||||
.ok_or(NymdError::NoContractAddressAvailable)
|
||||
}
|
||||
|
||||
pub fn vesting_contract_address(&self) -> Result<&AccountId, NymdError> {
|
||||
self.vesting_contract_address
|
||||
.as_ref()
|
||||
.ok_or(NymdError::NoContractAddressAvailable)
|
||||
}
|
||||
|
||||
// now the question is as follows: will denom always be in the format of `u{prefix}`?
|
||||
pub fn denom(&self) -> Result<Denom, NymdError> {
|
||||
Ok(format!("u{}", self.contract_address()?.prefix())
|
||||
Ok(format!("u{}", self.mixnet_contract_address()?.prefix())
|
||||
.parse()
|
||||
.unwrap())
|
||||
}
|
||||
@@ -168,6 +181,16 @@ impl<C> NymdClient<C> {
|
||||
operation.determine_fee(&self.gas_price, gas_limit)
|
||||
}
|
||||
|
||||
pub fn get_fee_multiple(&self, operation: Operation, times: u64) -> Fee {
|
||||
let default_gas_limit = operation.default_gas_limit();
|
||||
let gas_limit_unit = self
|
||||
.custom_gas_limits
|
||||
.get(&operation)
|
||||
.unwrap_or(&default_gas_limit);
|
||||
let gas_limit = Gas::from(gas_limit_unit.value() * times);
|
||||
Operation::determine_custom_fee(&self.gas_price, gas_limit)
|
||||
}
|
||||
|
||||
pub fn calculate_custom_fee(&self, gas_limit: impl Into<Gas>) -> Fee {
|
||||
Operation::determine_custom_fee(&self.gas_price, gas_limit.into())
|
||||
}
|
||||
@@ -214,7 +237,7 @@ impl<C> NymdClient<C> {
|
||||
{
|
||||
let request = QueryMsg::StateParams {};
|
||||
self.client
|
||||
.query_contract_smart(self.contract_address()?, &request)
|
||||
.query_contract_smart(self.mixnet_contract_address()?, &request)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -224,7 +247,7 @@ impl<C> NymdClient<C> {
|
||||
{
|
||||
let request = QueryMsg::GetContractVersion {};
|
||||
self.client
|
||||
.query_contract_smart(self.contract_address()?, &request)
|
||||
.query_contract_smart(self.mixnet_contract_address()?, &request)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -236,7 +259,7 @@ impl<C> NymdClient<C> {
|
||||
{
|
||||
let request = QueryMsg::CurrentRewardingInterval {};
|
||||
self.client
|
||||
.query_contract_smart(self.contract_address()?, &request)
|
||||
.query_contract_smart(self.mixnet_contract_address()?, &request)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -253,7 +276,7 @@ impl<C> NymdClient<C> {
|
||||
rewarding_interval_nonce,
|
||||
};
|
||||
self.client
|
||||
.query_contract_smart(self.contract_address()?, &request)
|
||||
.query_contract_smart(self.mixnet_contract_address()?, &request)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -263,7 +286,7 @@ impl<C> NymdClient<C> {
|
||||
{
|
||||
let request = QueryMsg::LayerDistribution {};
|
||||
self.client
|
||||
.query_contract_smart(self.contract_address()?, &request)
|
||||
.query_contract_smart(self.mixnet_contract_address()?, &request)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -273,7 +296,7 @@ impl<C> NymdClient<C> {
|
||||
{
|
||||
let request = QueryMsg::GetRewardPool {};
|
||||
self.client
|
||||
.query_contract_smart(self.contract_address()?, &request)
|
||||
.query_contract_smart(self.mixnet_contract_address()?, &request)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -283,7 +306,7 @@ impl<C> NymdClient<C> {
|
||||
{
|
||||
let request = QueryMsg::GetCirculatingSupply {};
|
||||
self.client
|
||||
.query_contract_smart(self.contract_address()?, &request)
|
||||
.query_contract_smart(self.mixnet_contract_address()?, &request)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -293,7 +316,7 @@ impl<C> NymdClient<C> {
|
||||
{
|
||||
let request = QueryMsg::GetSybilResistancePercent {};
|
||||
self.client
|
||||
.query_contract_smart(self.contract_address()?, &request)
|
||||
.query_contract_smart(self.mixnet_contract_address()?, &request)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -303,7 +326,7 @@ impl<C> NymdClient<C> {
|
||||
{
|
||||
let request = QueryMsg::GetEpochRewardPercent {};
|
||||
self.client
|
||||
.query_contract_smart(self.contract_address()?, &request)
|
||||
.query_contract_smart(self.mixnet_contract_address()?, &request)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -317,7 +340,7 @@ impl<C> NymdClient<C> {
|
||||
};
|
||||
let response: MixOwnershipResponse = self
|
||||
.client
|
||||
.query_contract_smart(self.contract_address()?, &request)
|
||||
.query_contract_smart(self.mixnet_contract_address()?, &request)
|
||||
.await?;
|
||||
Ok(response.mixnode)
|
||||
}
|
||||
@@ -332,7 +355,7 @@ impl<C> NymdClient<C> {
|
||||
};
|
||||
let response: GatewayOwnershipResponse = self
|
||||
.client
|
||||
.query_contract_smart(self.contract_address()?, &request)
|
||||
.query_contract_smart(self.mixnet_contract_address()?, &request)
|
||||
.await?;
|
||||
Ok(response.gateway)
|
||||
}
|
||||
@@ -350,7 +373,7 @@ impl<C> NymdClient<C> {
|
||||
limit: page_limit,
|
||||
};
|
||||
self.client
|
||||
.query_contract_smart(self.contract_address()?, &request)
|
||||
.query_contract_smart(self.mixnet_contract_address()?, &request)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -367,7 +390,7 @@ impl<C> NymdClient<C> {
|
||||
limit: page_limit,
|
||||
};
|
||||
self.client
|
||||
.query_contract_smart(self.contract_address()?, &request)
|
||||
.query_contract_smart(self.mixnet_contract_address()?, &request)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -387,7 +410,7 @@ impl<C> NymdClient<C> {
|
||||
limit: page_limit,
|
||||
};
|
||||
self.client
|
||||
.query_contract_smart(self.contract_address()?, &request)
|
||||
.query_contract_smart(self.mixnet_contract_address()?, &request)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -405,7 +428,7 @@ impl<C> NymdClient<C> {
|
||||
limit: page_limit,
|
||||
};
|
||||
self.client
|
||||
.query_contract_smart(self.contract_address()?, &request)
|
||||
.query_contract_smart(self.mixnet_contract_address()?, &request)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -425,7 +448,7 @@ impl<C> NymdClient<C> {
|
||||
limit: page_limit,
|
||||
};
|
||||
self.client
|
||||
.query_contract_smart(self.contract_address()?, &request)
|
||||
.query_contract_smart(self.mixnet_contract_address()?, &request)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -443,7 +466,7 @@ impl<C> NymdClient<C> {
|
||||
delegator: delegator.to_string(),
|
||||
};
|
||||
self.client
|
||||
.query_contract_smart(self.contract_address()?, &request)
|
||||
.query_contract_smart(self.mixnet_contract_address()?, &request)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -463,6 +486,21 @@ impl<C> NymdClient<C> {
|
||||
.await
|
||||
}
|
||||
|
||||
/// Send funds from one address to multiple others
|
||||
pub async fn send_multiple(
|
||||
&self,
|
||||
msgs: Vec<(AccountId, Vec<CosmosCoin>)>,
|
||||
memo: impl Into<String> + Send + 'static,
|
||||
) -> Result<broadcast::tx_commit::Response, NymdError>
|
||||
where
|
||||
C: SigningCosmWasmClient + Sync,
|
||||
{
|
||||
let fee = self.get_fee_multiple(Operation::Send, msgs.len() as u64);
|
||||
self.client
|
||||
.send_tokens_multiple(self.address(), msgs, fee, memo)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn execute<M>(
|
||||
&self,
|
||||
contract_address: &AccountId,
|
||||
@@ -590,7 +628,7 @@ impl<C> NymdClient<C> {
|
||||
self.client
|
||||
.execute(
|
||||
self.address(),
|
||||
self.contract_address()?,
|
||||
self.mixnet_contract_address()?,
|
||||
&req,
|
||||
fee,
|
||||
"Bonding mixnode from rust!",
|
||||
@@ -599,6 +637,68 @@ impl<C> NymdClient<C> {
|
||||
.await
|
||||
}
|
||||
|
||||
/// Announce a mixnode on behalf of the owner, paying a fee.
|
||||
pub async fn bond_mixnode_on_behalf(
|
||||
&self,
|
||||
mixnode: MixNode,
|
||||
owner: String,
|
||||
bond: Coin,
|
||||
) -> Result<ExecuteResult, NymdError>
|
||||
where
|
||||
C: SigningCosmWasmClient + Sync,
|
||||
{
|
||||
let fee = self.get_fee(Operation::BondMixnodeOnBehalf);
|
||||
|
||||
let req = ExecuteMsg::BondMixnodeOnBehalf {
|
||||
mix_node: mixnode,
|
||||
owner,
|
||||
};
|
||||
self.client
|
||||
.execute(
|
||||
self.address(),
|
||||
self.mixnet_contract_address()?,
|
||||
&req,
|
||||
fee,
|
||||
"Bonding mixnode on behalf from rust!",
|
||||
vec![cosmwasm_coin_to_cosmos_coin(bond)],
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Announce multiple mixnodes on behalf of other owners, paying a fee.
|
||||
pub async fn bond_multiple_mixnodes_on_behalf(
|
||||
&self,
|
||||
mixnode_bonds: Vec<MixNodeBond>,
|
||||
) -> Result<ExecuteResult, NymdError>
|
||||
where
|
||||
C: SigningCosmWasmClient + Sync,
|
||||
{
|
||||
let fee = self.get_fee_multiple(Operation::BondMixnodeOnBehalf, mixnode_bonds.len() as u64);
|
||||
|
||||
let reqs: Vec<(ExecuteMsg, Vec<CosmosCoin>)> = mixnode_bonds
|
||||
.into_iter()
|
||||
.map(|bond| {
|
||||
(
|
||||
ExecuteMsg::BondMixnodeOnBehalf {
|
||||
mix_node: bond.mix_node,
|
||||
owner: bond.owner.to_string(),
|
||||
},
|
||||
vec![cosmwasm_coin_to_cosmos_coin(bond.bond_amount)],
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
self.client
|
||||
.execute_multiple(
|
||||
self.address(),
|
||||
self.mixnet_contract_address()?,
|
||||
reqs,
|
||||
fee,
|
||||
"Bonding multiple mixnodes on behalf from rust!",
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Unbond a mixnode, removing it from the network and reclaiming staked coins
|
||||
pub async fn unbond_mixnode(&self) -> Result<ExecuteResult, NymdError>
|
||||
where
|
||||
@@ -610,7 +710,7 @@ impl<C> NymdClient<C> {
|
||||
self.client
|
||||
.execute(
|
||||
self.address(),
|
||||
self.contract_address()?,
|
||||
self.mixnet_contract_address()?,
|
||||
&req,
|
||||
fee,
|
||||
"Unbonding mixnode from rust!",
|
||||
@@ -619,6 +719,26 @@ impl<C> NymdClient<C> {
|
||||
.await
|
||||
}
|
||||
|
||||
/// Unbond a mixnode on behalf of the owner, removing it from the network and reclaiming staked coins
|
||||
pub async fn unbond_mixnode_on_behalf(&self, owner: String) -> Result<ExecuteResult, NymdError>
|
||||
where
|
||||
C: SigningCosmWasmClient + Sync,
|
||||
{
|
||||
let fee = self.get_fee(Operation::UnbondMixnodeOnBehalf);
|
||||
|
||||
let req = ExecuteMsg::UnbondMixnodeOnBehalf { owner };
|
||||
self.client
|
||||
.execute(
|
||||
self.address(),
|
||||
self.mixnet_contract_address()?,
|
||||
&req,
|
||||
fee,
|
||||
"Unbonding mixnode on behalf from rust!",
|
||||
Vec::new(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Delegates specified amount of stake to particular mixnode.
|
||||
pub async fn delegate_to_mixnode(
|
||||
&self,
|
||||
@@ -636,7 +756,7 @@ impl<C> NymdClient<C> {
|
||||
self.client
|
||||
.execute(
|
||||
self.address(),
|
||||
self.contract_address()?,
|
||||
self.mixnet_contract_address()?,
|
||||
&req,
|
||||
fee,
|
||||
"Delegating to mixnode from rust!",
|
||||
@@ -645,6 +765,72 @@ impl<C> NymdClient<C> {
|
||||
.await
|
||||
}
|
||||
|
||||
/// Delegates specified amount of stake to particular mixnode on
|
||||
/// behalf of a particular delegator.
|
||||
pub async fn delegate_to_mixnode_on_behalf(
|
||||
&self,
|
||||
mix_identity: &str,
|
||||
delegate: &str,
|
||||
amount: &Coin,
|
||||
) -> Result<ExecuteResult, NymdError>
|
||||
where
|
||||
C: SigningCosmWasmClient + Sync,
|
||||
{
|
||||
let fee = self.get_fee(Operation::DelegateToMixnodeOnBehalf);
|
||||
|
||||
let req = ExecuteMsg::DelegateToMixnodeOnBehalf {
|
||||
mix_identity: mix_identity.to_string(),
|
||||
delegate: delegate.to_string(),
|
||||
};
|
||||
self.client
|
||||
.execute(
|
||||
self.address(),
|
||||
self.mixnet_contract_address()?,
|
||||
&req,
|
||||
fee,
|
||||
"Delegating to mixnode on behalf from rust!",
|
||||
vec![cosmwasm_coin_ptr_to_cosmos_coin(amount)],
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Delegates specified amount of stake to multiple mixnodes on behalf of multiple delegators.
|
||||
pub async fn delegate_to_multiple_mixnodes_on_behalf(
|
||||
&self,
|
||||
mixnode_delegations: Vec<Delegation>,
|
||||
) -> Result<ExecuteResult, NymdError>
|
||||
where
|
||||
C: SigningCosmWasmClient + Sync,
|
||||
{
|
||||
let fee = self.get_fee_multiple(
|
||||
Operation::DelegateToMixnodeOnBehalf,
|
||||
mixnode_delegations.len() as u64,
|
||||
);
|
||||
|
||||
let reqs: Vec<(ExecuteMsg, Vec<CosmosCoin>)> = mixnode_delegations
|
||||
.into_iter()
|
||||
.map(|delegation| {
|
||||
(
|
||||
ExecuteMsg::DelegateToMixnodeOnBehalf {
|
||||
mix_identity: delegation.node_identity(),
|
||||
delegate: delegation.owner().to_string(),
|
||||
},
|
||||
vec![cosmwasm_coin_to_cosmos_coin(delegation.amount().clone())],
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
self.client
|
||||
.execute_multiple(
|
||||
self.address(),
|
||||
self.mixnet_contract_address()?,
|
||||
reqs,
|
||||
fee,
|
||||
"Delegating to multiple mixnodes on behalf from rust!",
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Removes stake delegation from a particular mixnode.
|
||||
pub async fn remove_mixnode_delegation(
|
||||
&self,
|
||||
@@ -661,7 +847,7 @@ impl<C> NymdClient<C> {
|
||||
self.client
|
||||
.execute(
|
||||
self.address(),
|
||||
self.contract_address()?,
|
||||
self.mixnet_contract_address()?,
|
||||
&req,
|
||||
fee,
|
||||
"Removing mixnode delegation from rust!",
|
||||
@@ -670,6 +856,33 @@ impl<C> NymdClient<C> {
|
||||
.await
|
||||
}
|
||||
|
||||
/// Removes stake delegation from a particular mixnode on behalf of a particular delegator.
|
||||
pub async fn remove_mixnode_delegation_on_behalf(
|
||||
&self,
|
||||
mix_identity: &str,
|
||||
delegate: &str,
|
||||
) -> Result<ExecuteResult, NymdError>
|
||||
where
|
||||
C: SigningCosmWasmClient + Sync,
|
||||
{
|
||||
let fee = self.get_fee(Operation::UndelegateFromMixnodeOnBehalf);
|
||||
|
||||
let req = ExecuteMsg::UndelegateFromMixnodeOnBehalf {
|
||||
mix_identity: mix_identity.to_string(),
|
||||
delegate: delegate.to_string(),
|
||||
};
|
||||
self.client
|
||||
.execute(
|
||||
self.address(),
|
||||
self.mixnet_contract_address()?,
|
||||
&req,
|
||||
fee,
|
||||
"Removing mixnode delegation on behalf from rust!",
|
||||
Vec::new(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Announce a gateway, paying a fee.
|
||||
pub async fn bond_gateway(
|
||||
&self,
|
||||
@@ -685,7 +898,7 @@ impl<C> NymdClient<C> {
|
||||
self.client
|
||||
.execute(
|
||||
self.address(),
|
||||
self.contract_address()?,
|
||||
self.mixnet_contract_address()?,
|
||||
&req,
|
||||
fee,
|
||||
"Bonding gateway from rust!",
|
||||
@@ -694,6 +907,65 @@ impl<C> NymdClient<C> {
|
||||
.await
|
||||
}
|
||||
|
||||
/// Announce a gateway on behalf of the owner, paying a fee.
|
||||
pub async fn bond_gateway_on_behalf(
|
||||
&self,
|
||||
gateway: Gateway,
|
||||
owner: String,
|
||||
bond: Coin,
|
||||
) -> Result<ExecuteResult, NymdError>
|
||||
where
|
||||
C: SigningCosmWasmClient + Sync,
|
||||
{
|
||||
let fee = self.get_fee(Operation::BondGatewayOnBehalf);
|
||||
|
||||
let req = ExecuteMsg::BondGatewayOnBehalf { gateway, owner };
|
||||
self.client
|
||||
.execute(
|
||||
self.address(),
|
||||
self.mixnet_contract_address()?,
|
||||
&req,
|
||||
fee,
|
||||
"Bonding gateway on behalf from rust!",
|
||||
vec![cosmwasm_coin_to_cosmos_coin(bond)],
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Announce multiple gateways on behalf of other owners, paying a fee.
|
||||
pub async fn bond_multiple_gateways_on_behalf(
|
||||
&self,
|
||||
gateway_bonds: Vec<GatewayBond>,
|
||||
) -> Result<ExecuteResult, NymdError>
|
||||
where
|
||||
C: SigningCosmWasmClient + Sync,
|
||||
{
|
||||
let fee = self.get_fee_multiple(Operation::BondGatewayOnBehalf, gateway_bonds.len() as u64);
|
||||
|
||||
let reqs: Vec<(ExecuteMsg, Vec<CosmosCoin>)> = gateway_bonds
|
||||
.into_iter()
|
||||
.map(|bond| {
|
||||
(
|
||||
ExecuteMsg::BondGatewayOnBehalf {
|
||||
gateway: bond.gateway,
|
||||
owner: bond.owner.to_string(),
|
||||
},
|
||||
vec![cosmwasm_coin_to_cosmos_coin(bond.bond_amount)],
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
self.client
|
||||
.execute_multiple(
|
||||
self.address(),
|
||||
self.mixnet_contract_address()?,
|
||||
reqs,
|
||||
fee,
|
||||
"Bonding multiple gateways on behalf from rust!",
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Unbond a gateway, removing it from the network and reclaiming staked coins
|
||||
pub async fn unbond_gateway(&self) -> Result<ExecuteResult, NymdError>
|
||||
where
|
||||
@@ -705,7 +977,7 @@ impl<C> NymdClient<C> {
|
||||
self.client
|
||||
.execute(
|
||||
self.address(),
|
||||
self.contract_address()?,
|
||||
self.mixnet_contract_address()?,
|
||||
&req,
|
||||
fee,
|
||||
"Unbonding gateway from rust!",
|
||||
@@ -714,6 +986,27 @@ impl<C> NymdClient<C> {
|
||||
.await
|
||||
}
|
||||
|
||||
/// Unbond a gateway on behalf of the owner, removing it from the
|
||||
/// network and reclaiming staked coins
|
||||
pub async fn unbond_gateway_on_behalf(&self, owner: String) -> Result<ExecuteResult, NymdError>
|
||||
where
|
||||
C: SigningCosmWasmClient + Sync,
|
||||
{
|
||||
let fee = self.get_fee(Operation::UnbondGatewayOnBehalf);
|
||||
|
||||
let req = ExecuteMsg::UnbondGatewayOnBehalf { owner };
|
||||
self.client
|
||||
.execute(
|
||||
self.address(),
|
||||
self.mixnet_contract_address()?,
|
||||
&req,
|
||||
fee,
|
||||
"Unbonding gateway on behalf from rust!",
|
||||
Vec::new(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn update_contract_settings(
|
||||
&self,
|
||||
new_params: ContractStateParams,
|
||||
@@ -727,7 +1020,7 @@ impl<C> NymdClient<C> {
|
||||
self.client
|
||||
.execute(
|
||||
self.address(),
|
||||
self.contract_address()?,
|
||||
self.mixnet_contract_address()?,
|
||||
&req,
|
||||
fee,
|
||||
"Updating contract state from rust!",
|
||||
@@ -751,7 +1044,7 @@ impl<C> NymdClient<C> {
|
||||
self.client
|
||||
.execute(
|
||||
self.address(),
|
||||
self.contract_address()?,
|
||||
self.mixnet_contract_address()?,
|
||||
&req,
|
||||
fee,
|
||||
"Beginning mixnode rewarding procedure",
|
||||
@@ -775,7 +1068,7 @@ impl<C> NymdClient<C> {
|
||||
self.client
|
||||
.execute(
|
||||
self.address(),
|
||||
self.contract_address()?,
|
||||
self.mixnet_contract_address()?,
|
||||
&req,
|
||||
fee,
|
||||
"Finishing mixnode rewarding procedure",
|
||||
|
||||
@@ -63,6 +63,7 @@ pub fn default_api_endpoints() -> Vec<Url> {
|
||||
}
|
||||
|
||||
pub const DEFAULT_MIXNET_CONTRACT_ADDRESS: &str = "punk10pyejy66429refv3g35g2t7am0was7yalwrzen";
|
||||
pub const DEFAULT_VESTING_CONTRACT_ADDRESS: &str = "";
|
||||
pub const REWARDING_VALIDATOR_ADDRESS: &str = "punk1v9qauwdq5terag6uvfsdytcs2d0sdmfdy7hgk3";
|
||||
|
||||
/// How much bandwidth (in bytes) one token can buy
|
||||
|
||||
@@ -224,8 +224,12 @@ fn new_nymd_client() -> validator_client::Client<QueryNymdClient> {
|
||||
let nymd_url = default_nymd_endpoints()[0].clone();
|
||||
let api_url = default_api_endpoints()[0].clone();
|
||||
|
||||
let client_config =
|
||||
validator_client::Config::new(nymd_url, api_url, Some(mixnet_contract.parse().unwrap()));
|
||||
let client_config = validator_client::Config::new(
|
||||
nymd_url,
|
||||
api_url,
|
||||
Some(mixnet_contract.parse().unwrap()),
|
||||
None,
|
||||
);
|
||||
|
||||
validator_client::Client::new_query(client_config).expect("Failed to connect to nymd!")
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ impl ERC20Bridge {
|
||||
let nymd_client = NymdClient::connect_with_mnemonic(
|
||||
nymd_url.as_ref(),
|
||||
AccountId::from_str(COSMOS_CONTRACT_ADDRESS).ok(),
|
||||
None,
|
||||
mnemonic,
|
||||
)
|
||||
.expect("Could not create nymd client");
|
||||
@@ -100,7 +101,7 @@ impl ERC20Bridge {
|
||||
credential: &TokenCredential,
|
||||
) -> Result<(), RequestHandlingError> {
|
||||
// It's ok to unwrap here, as the cosmos contract and denom are set correctly
|
||||
let contract_address = self.nymd_client.contract_address().unwrap();
|
||||
let contract_address = self.nymd_client.mixnet_contract_address().unwrap();
|
||||
let coin = CosmosCoin {
|
||||
denom: Denom::from_str(DENOM).unwrap(),
|
||||
amount: Decimal::from(100000u64),
|
||||
|
||||
@@ -41,7 +41,7 @@ pub async fn connect_with_mnemonic(
|
||||
client = _connect_with_mnemonic(mnemonic, &r_state.config());
|
||||
}
|
||||
|
||||
let contract_address = match client.contract_address() {
|
||||
let contract_address = match client.mixnet_contract_address() {
|
||||
Ok(address) => address.to_string(),
|
||||
Err(e) => return Err(format_err!(e)),
|
||||
};
|
||||
@@ -106,6 +106,7 @@ fn _connect_with_mnemonic(mnemonic: Mnemonic, config: &Config) -> NymdClient<Sig
|
||||
match NymdClient::connect_with_mnemonic(
|
||||
config.get_nymd_validator_url().unwrap(),
|
||||
Some(AccountId::from_str(&config.get_mixnet_contract_address()).unwrap()),
|
||||
None,
|
||||
mnemonic,
|
||||
) {
|
||||
Ok(client) => client,
|
||||
|
||||
@@ -5,11 +5,17 @@ export type Operation =
|
||||
| "ChangeAdmin"
|
||||
| "Send"
|
||||
| "BondMixnode"
|
||||
| "BondMixnodeOnBehalf"
|
||||
| "UnbondMixnode"
|
||||
| "UnbondMixnodeOnBehalf"
|
||||
| "DelegateToMixnode"
|
||||
| "DelegateToMixnodeOnBehalf"
|
||||
| "UndelegateFromMixnode"
|
||||
| "UndelegateFromMixnodeOnBehalf"
|
||||
| "BondGateway"
|
||||
| "BondGatewayOnBehalf"
|
||||
| "UnbondGateway"
|
||||
| "UnbondGatewayOnBehalf"
|
||||
| "UpdateStateParams"
|
||||
| "BeginMixnodeRewarding"
|
||||
| "FinishMixnodeRewarding";
|
||||
@@ -45,7 +45,8 @@ impl Client<QueryNymdClient> {
|
||||
.parse()
|
||||
.expect("the mixnet contract address is invalid!");
|
||||
|
||||
let client_config = validator_client::Config::new(nymd_url, api_url, Some(mixnet_contract));
|
||||
let client_config =
|
||||
validator_client::Config::new(nymd_url, api_url, Some(mixnet_contract), None);
|
||||
let inner =
|
||||
validator_client::Client::new_query(client_config).expect("Failed to connect to nymd!");
|
||||
|
||||
@@ -71,7 +72,8 @@ impl Client<SigningNymdClient> {
|
||||
.parse()
|
||||
.expect("the mnemonic is invalid!");
|
||||
|
||||
let client_config = validator_client::Config::new(nymd_url, api_url, Some(mixnet_contract));
|
||||
let client_config =
|
||||
validator_client::Config::new(nymd_url, api_url, Some(mixnet_contract), None);
|
||||
let inner = validator_client::Client::new_signing(client_config, mnemonic)
|
||||
.expect("Failed to connect to nymd!");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user