use crate::nyxd::contract_traits::NymContractsProvider;
use crate::nyxd::cosmwasm_client::types::ExecuteResult;
use crate::nyxd::error::NyxdError;
use crate::nyxd::{Coin, Fee, SigningCosmWasmClient};
use crate::signing::signer::OfflineSigner;
use async_trait::async_trait;
use nym_ecash_contract_common::msg::ExecuteMsg as EcashExecuteMsg;
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait EcashSigningClient {
async fn execute_ecash_contract(
&self,
fee: Option<Fee>,
msg: EcashExecuteMsg,
memo: String,
funds: Vec<Coin>,
) -> Result<ExecuteResult, NyxdError>;
async fn make_ticketbook_deposit(
&self,
public_key: String,
deposit_amount: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let req = EcashExecuteMsg::DepositTicketBookFunds {
identity_key: public_key,
};
self.execute_ecash_contract(fee, req, "Ecash::Deposit".to_string(), vec![deposit_amount])
.await
}
async fn request_ticket_redemption(
&self,
commitment_bs58: String,
number_of_tickets: u16,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let req = EcashExecuteMsg::RequestRedemption {
commitment_bs58,
number_of_tickets,
};
self.execute_ecash_contract(fee, req, Default::default(), vec![])
.await
}
async fn update_admin(
&self,
admin: String,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let req = EcashExecuteMsg::UpdateAdmin { admin };
self.execute_ecash_contract(fee, req, "Ecash::UpdateAdmin".to_string(), vec![])
.await
}
async fn update_deposit_value(
&self,
new_deposit: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let req = EcashExecuteMsg::UpdateDefaultDepositValue {
new_deposit: new_deposit.into(),
};
self.execute_ecash_contract(fee, req, "Ecash::UpdateDepositValue".to_string(), vec![])
.await
}
async fn set_reduced_deposit_price(
&self,
address: String,
deposit: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let req = EcashExecuteMsg::SetReducedDepositPrice {
address,
deposit: deposit.into(),
};
self.execute_ecash_contract(
fee,
req,
"Ecash::SetReducedDepositPrice".to_string(),
vec![],
)
.await
}
async fn remove_reduced_deposit_price(
&self,
address: String,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let req = EcashExecuteMsg::RemoveReducedDepositPrice { address };
self.execute_ecash_contract(
fee,
req,
"Ecash::RemoveReducedDepositPrice".to_string(),
vec![],
)
.await
}
async fn propose_for_blacklist(
&self,
public_key: String,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let req = EcashExecuteMsg::ProposeToBlacklist { public_key };
self.execute_ecash_contract(fee, req, "Ecash::ProposeToBlacklist".to_string(), vec![])
.await
}
}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl<C> EcashSigningClient for C
where
C: SigningCosmWasmClient + NymContractsProvider + Sync,
NyxdError: From<<Self as OfflineSigner>::Error>,
{
async fn execute_ecash_contract(
&self,
fee: Option<Fee>,
msg: EcashExecuteMsg,
memo: String,
funds: Vec<Coin>,
) -> Result<ExecuteResult, NyxdError> {
let ecash_contract_address = self
.ecash_contract_address()
.ok_or_else(|| NyxdError::unavailable_contract_address("coconut bandwidth contract"))?;
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier())));
let signer_address = &self.signer_addresses()[0];
self.execute(
signer_address,
ecash_contract_address,
&msg,
fee,
memo,
funds,
)
.await
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::nyxd::contract_traits::tests::{mock_coin, IgnoreValue};
use nym_ecash_contract_common::msg::ExecuteMsg;
#[allow(dead_code)]
fn all_execute_variants_are_covered<C: EcashSigningClient + Send + Sync>(
client: C,
msg: EcashExecuteMsg,
) {
match msg {
EcashExecuteMsg::DepositTicketBookFunds { identity_key } => client
.make_ticketbook_deposit(identity_key.to_string(), mock_coin(), None)
.ignore(),
EcashExecuteMsg::AddToBlacklist { public_key: _ } => unimplemented!(), EcashExecuteMsg::ProposeToBlacklist { public_key } => {
client.propose_for_blacklist(public_key, None).ignore()
}
ExecuteMsg::RequestRedemption {
commitment_bs58,
number_of_tickets,
} => client
.request_ticket_redemption(commitment_bs58, number_of_tickets, None)
.ignore(),
ExecuteMsg::RedeemTickets { .. } => unimplemented!(), ExecuteMsg::UpdateAdmin { admin } => client.update_admin(admin, None).ignore(),
ExecuteMsg::UpdateDefaultDepositValue { new_deposit } => client
.update_deposit_value(new_deposit.into(), None)
.ignore(),
ExecuteMsg::SetReducedDepositPrice { address, deposit } => client
.set_reduced_deposit_price(address, deposit.into(), None)
.ignore(),
ExecuteMsg::RemoveReducedDepositPrice { address } => {
client.remove_reduced_deposit_price(address, None).ignore()
}
};
}
}