'New' API on 'send'

This commit is contained in:
Jędrzej Stuczyński
2022-06-01 16:52:26 +01:00
parent dbbd94d64c
commit 87e8666b86
4 changed files with 100 additions and 104 deletions
@@ -1,6 +1,7 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::nymd::Coin;
use cosmrs::tx;
use serde::{Deserialize, Serialize};
@@ -14,6 +15,15 @@ pub enum Fee {
Auto(Option<f32>),
}
impl Fee {
pub fn try_get_manual_amount(&self) -> Option<Vec<Coin>> {
match self {
Fee::Manual(tx_fee) => Some(tx_fee.amount.iter().cloned().map(Into::into).collect()),
Fee::Auto(_) => None,
}
}
}
impl From<tx::Fee> for Fee {
fn from(fee: tx::Fee) -> Self {
Fee::Manual(fee)
+26 -54
View File
@@ -10,36 +10,23 @@ use validator_client::nymd::GasPrice;
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/Gas.ts")
)]
#[derive(Deserialize, Serialize, Clone)]
#[derive(Deserialize, Serialize, Copy, Clone, Debug)]
pub struct Gas {
/// units of gas used
pub gas_units: u64,
}
impl Gas {
pub fn from_cosmrs_gas(value: CosmrsGas, _denom_minor: &str) -> Result<Gas, TypesError> {
Ok(Gas {
gas_units: value.value(),
})
// // TODO: use simulator struct to do conversion to fee
// let value_u128 = Uint128::from(value.value());
// let amount = Decimal::new(value_u128) * Decimal::from_str("0.0025")?;
// Ok(Gas {
// gas_units: value.value(),
// amount: MajorCurrencyAmount::from_minor_decimal_and_denom(amount, denom_minor)?,
// })
pub fn from_u64(value: u64) -> Gas {
Gas { gas_units: value }
}
pub fn from_u64(value: u64, _denom_minor: &str) -> Result<Gas, TypesError> {
Ok(Gas { gas_units: value })
// todo!()
// // TODO: use simulator struct to do conversion to fee
// let value_u128 = Uint128::from(value);
// let amount = Decimal::new(value_u128) * Decimal::from_str("0.0025")?;
// Ok(Gas {
// gas_units: value,
// amount: MajorCurrencyAmount::from_minor_decimal_and_denom(amount, denom_minor)?,
// })
}
impl From<CosmrsGas> for Gas {
fn from(gas: CosmrsGas) -> Self {
Gas {
gas_units: gas.value(),
}
}
}
@@ -48,44 +35,29 @@ impl Gas {
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/GasInfo.ts")
)]
#[derive(Deserialize, Serialize)]
#[derive(Deserialize, Serialize, Copy, Clone, Debug)]
pub struct GasInfo {
/// GasWanted is the maximum units of work we allow this tx to perform.
pub gas_wanted: u64,
pub gas_wanted: Gas,
/// GasUsed is the amount of gas actually consumed.
pub gas_used: u64,
pub gas_used: Gas,
}
/// gas units converted to fee as major coin amount
pub fee: MajorCurrencyAmount,
impl From<ValidatorClientGasInfo> for GasInfo {
fn from(info: ValidatorClientGasInfo) -> Self {
GasInfo {
gas_wanted: info.gas_wanted.into(),
gas_used: info.gas_used.into(),
}
}
}
impl GasInfo {
pub fn from_validator_client_gas_info(
value: ValidatorClientGasInfo,
denom_minor: &str,
) -> Result<GasInfo, TypesError> {
// terrible workaround, but I don't want to break the current flow (just yet)
let gas_price = GasPrice::new_with_default_price(denom_minor)?;
let fee = (&gas_price) * value.gas_used;
Ok(GasInfo {
gas_wanted: value.gas_wanted.value(),
gas_used: value.gas_used.value(),
fee: fee.into(),
})
}
pub fn from_u64(
gas_wanted: u64,
gas_used: u64,
denom_minor: &str,
) -> Result<GasInfo, TypesError> {
// terrible workaround, but I don't want to break the current flow (just yet)
let gas_price = GasPrice::new_with_default_price(denom_minor)?;
let fee = (&gas_price) * CosmrsGas::from(gas_used);
Ok(GasInfo {
gas_wanted,
gas_used,
fee: fee.into(),
})
pub fn from_u64(gas_wanted: u64, gas_used: u64) -> GasInfo {
GasInfo {
gas_wanted: Gas::from_u64(gas_wanted),
gas_used: Gas::from_u64(gas_used),
}
}
}
+50 -34
View File
@@ -1,9 +1,10 @@
use crate::currency::MajorCurrencyAmount;
use crate::currency::{DecCoin, MajorCurrencyAmount};
use crate::error::TypesError;
use crate::gas::GasInfo;
use crate::gas::{Gas, GasInfo};
use log::warn;
use serde::{Deserialize, Serialize};
use validator_client::nymd::cosmwasm_client::types::ExecuteResult;
use validator_client::nymd::TxResponse;
use validator_client::nymd::{Coin, TxResponse};
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
@@ -15,31 +16,37 @@ pub struct SendTxResult {
pub block_height: u64,
pub code: u32,
pub details: TransactionDetails,
pub gas_used: u64,
pub gas_wanted: u64,
pub gas_used: Gas,
pub gas_wanted: Gas,
pub tx_hash: String,
// pub fee: MajorCurrencyAmount,
pub fee: Option<DecCoin>,
}
impl SendTxResult {
pub fn new(
t: TxResponse,
details: TransactionDetails,
_denom_minor: &str,
) -> Result<SendTxResult, TypesError> {
Ok(SendTxResult {
pub fn new(t: TxResponse, details: TransactionDetails, fee: Option<Vec<Coin>>) -> SendTxResult {
let fee = match fee {
None => None,
Some(mut fee) => {
if fee.len() > 1 {
warn!("our tx fee contained more than a single denomination. using the first one for display")
}
if fee.is_empty() {
warn!("our tx has had an unknown fee set");
None
} else {
Some(fee.pop().unwrap().into())
}
}
};
SendTxResult {
block_height: t.height.value(),
code: t.tx_result.code.value(),
details,
gas_used: t.tx_result.gas_used.value(),
gas_wanted: t.tx_result.gas_wanted.value(),
gas_used: t.tx_result.gas_used.into(),
gas_wanted: t.tx_result.gas_wanted.into(),
tx_hash: t.hash.to_string(),
// that is completely wrong: fee is what you told the validator to use beforehand
// fee: MajorCurrencyAmount::from_decimal_and_denom(
// Decimal::new(Uint128::from(t.tx_result.gas_used.value())),
// denom_minor.to_string(),
// )?,
})
fee,
}
}
}
@@ -50,11 +57,21 @@ impl SendTxResult {
)]
#[derive(Deserialize, Serialize, Debug)]
pub struct TransactionDetails {
pub amount: MajorCurrencyAmount,
pub amount: DecCoin,
pub from_address: String,
pub to_address: String,
}
impl TransactionDetails {
pub fn new(amount: DecCoin, from_address: String, to_address: String) -> Self {
TransactionDetails {
amount,
from_address,
to_address,
}
}
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
@@ -74,8 +91,9 @@ impl TransactionExecuteResult {
value: ExecuteResult,
denom_minor: &str,
) -> Result<TransactionExecuteResult, TypesError> {
let gas_info = GasInfo::from_validator_client_gas_info(value.gas_info, denom_minor)?;
let fee = gas_info.fee.clone();
let gas_info = GasInfo::from(value.gas_info);
// let fee = gas_info.fee.clone();
let fee = todo!();
Ok(TransactionExecuteResult {
gas_info,
transaction_hash: value.transaction_hash.to_string(),
@@ -97,25 +115,23 @@ pub struct RpcTransactionResponse {
pub tx_result_json: String,
pub block_height: u64,
pub transaction_hash: String,
pub gas_info: GasInfo,
pub gas_used: Gas,
pub gas_wanted: Gas,
// pub fee: MajorCurrencyAmount,
}
impl RpcTransactionResponse {
pub fn from_tx_response(
value: &TxResponse,
t: &TxResponse,
denom_minor: &str,
) -> Result<RpcTransactionResponse, TypesError> {
Ok(RpcTransactionResponse {
index: value.index,
gas_info: GasInfo::from_u64(
value.tx_result.gas_wanted.value(),
value.tx_result.gas_used.value(),
denom_minor,
)?,
transaction_hash: value.hash.to_string(),
tx_result_json: ::serde_json::to_string_pretty(&value.tx_result)?,
block_height: value.height.value(),
index: t.index,
gas_used: t.tx_result.gas_used.into(),
gas_wanted: t.tx_result.gas_wanted.into(),
transaction_hash: t.hash.to_string(),
tx_result_json: ::serde_json::to_string_pretty(&t.tx_result)?,
block_height: t.height.value(),
// wrong
// fee: MajorCurrencyAmount::from_decimal_and_denom(
// Decimal::new(Uint128::from(value.tx_result.gas_used.value())),
@@ -1,7 +1,7 @@
use crate::error::BackendError;
use crate::nymd_client;
use crate::state::State;
use nym_types::currency::MajorCurrencyAmount;
use nym_types::currency::DecCoin;
use nym_types::transaction::{SendTxResult, TransactionDetails};
use std::str::FromStr;
use std::sync::Arc;
@@ -11,36 +11,34 @@ use validator_client::nymd::{AccountId, Fee};
#[tauri::command]
pub async fn send(
address: &str,
amount: MajorCurrencyAmount,
amount: DecCoin,
memo: String,
fee: Option<Fee>,
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<SendTxResult, BackendError> {
let denom_minor = state.read().await.current_network().denom();
let address = AccountId::from_str(address)?;
let guard = state.read().await;
let amount_base = guard.attempt_convert_to_base_coin(amount.clone())?;
let to_address = AccountId::from_str(address)?;
let from_address = nymd_client!(state).address().to_string();
let amount2 = amount.clone().into();
let fee_amount = fee.as_ref().and_then(|fee| fee.try_get_manual_amount());
log::info!(
">>> Send: amount = {}, minor_amount = {:?}, from = {}, to = {}, fee = {:?}",
">>> Send: display_amount = {}, base_amount = {}, from = {}, to = {}, fee = {:?}",
amount,
amount2,
amount_base,
from_address,
address.as_ref(),
to_address,
fee,
);
let raw_res = nymd_client!(state)
.send(&address, vec![amount2], memo, fee)
.send(&to_address, vec![amount_base], memo, fee)
.await?;
log::info!("<<< tx hash = {}", raw_res.hash.to_string());
let res = SendTxResult::new(
raw_res,
TransactionDetails {
from_address,
to_address: address.to_string(),
amount,
},
denom_minor.as_ref(),
)?;
TransactionDetails::new(amount, from_address, to_address.to_string()),
fee_amount,
);
log::trace!("<<< {:?}", res);
Ok(res)
}