'New' API on 'send'
This commit is contained in:
@@ -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
@@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user