Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions mm2src/coins/coin_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,7 @@ impl From<Web3RpcError> for ValidatePaymentError {
| Web3RpcError::Timeout(internal)
| Web3RpcError::NumConversError(internal)
| Web3RpcError::InvalidGasApiConfig(internal) => ValidatePaymentError::InternalError(internal),
Web3RpcError::NftProtocolNotSupported => {
ValidatePaymentError::ProtocolNotSupported("Nft protocol is not supported".to_string())
},
Web3RpcError::ProtocolNotSupported(e) => ValidatePaymentError::ProtocolNotSupported(e),
}
}
}
Expand Down
180 changes: 124 additions & 56 deletions mm2src/coins/eth.rs

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions mm2src/coins/eth/eth_rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

use super::web3_transport::FeeHistoryResult;
use super::{web3_transport::Web3Transport, EthCoin};
use crate::eth::tron::TronAddress;
use common::log::warn;
use common::{custom_futures::timeout::FutureTimerExt, log::debug};
use compatible_time::Duration;
use serde_json::Value;
Expand Down Expand Up @@ -155,6 +157,15 @@ impl EthCoin {

/// Get balance of given address
pub(crate) async fn balance(&self, address: Address, block: Option<BlockNumber>) -> Result<U256, web3::Error> {
if self.is_tron() {
// TODO use Tron client
let sun = U256::zero();
warn!(
"Using stub implementation for Tron address_balance for {}, returning {sun} SUN",
format!("{:?}", TronAddress::from(&address)),
);
return Ok(sun);
}
Comment on lines +160 to +168
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't we wanna do such a check in most places since we now merged CoinType::Eth into CoinType::TRX?

let address = helpers::serialize(&address);
let block = helpers::serialize(&block.unwrap_or(BlockNumber::Latest));

Expand Down
10 changes: 6 additions & 4 deletions mm2src/coins/eth/eth_swap_v2/eth_maker_swap_v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ impl EthCoin {
.await
},
EthCoinType::Nft { .. } => Err(TransactionErr::ProtocolNotSupported(ERRL!(
"NFT protocol is not supported for ETH and ERC20 Swaps"
"{} protocol is not supported for ETH and ERC20 Swaps",
self.coin_type
))),
}
}
Expand Down Expand Up @@ -162,9 +163,10 @@ impl EthCoin {
validate_erc20_maker_payment_data(&decoded, &validation_args, function, token_addr)?;
},
EthCoinType::Nft { .. } => {
return MmError::err(ValidatePaymentError::ProtocolNotSupported(
"NFT protocol is not supported for ETH and ERC20 Swaps".to_string(),
));
return MmError::err(ValidatePaymentError::ProtocolNotSupported(format!(
"{} protocol is not supported for ETH and ERC20 Swaps",
self.coin_type
)));
},
}
Ok(())
Expand Down
37 changes: 22 additions & 15 deletions mm2src/coins/eth/eth_swap_v2/eth_taker_swap_v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ impl EthCoin {
.await
},
EthCoinType::Nft { .. } => Err(TransactionErr::ProtocolNotSupported(ERRL!(
"NFT protocol is not supported for ETH and ERC20 Swaps"
"{} protocol is not supported for ETH and ERC20 Swaps",
self.coin_type
))),
}
}
Expand Down Expand Up @@ -196,9 +197,10 @@ impl EthCoin {
validate_erc20_taker_payment_data(&decoded, &validation_args, function, token_addr)?;
},
EthCoinType::Nft { .. } => {
return MmError::err(ValidateSwapV2TxError::ProtocolNotSupported(
"NFT protocol is not supported for ETH and ERC20 Swaps".to_string(),
));
return MmError::err(ValidateSwapV2TxError::ProtocolNotSupported(format!(
"{} protocol is not supported for ETH and ERC20 Swaps",
self.coin_type
)));
},
}
Ok(())
Expand All @@ -214,7 +216,8 @@ impl EthCoin {
EthCoinType::Eth | EthCoinType::Erc20 { .. } => U256::from(self.gas_limit_v2.taker.approve_payment),
EthCoinType::Nft { .. } => {
return Err(TransactionErr::ProtocolNotSupported(ERRL!(
"NFT protocol is not supported for ETH and ERC20 Swaps"
"{} protocol is not supported for ETH and ERC20 Swaps",
self.coin_type
)))
},
};
Expand Down Expand Up @@ -563,9 +566,10 @@ impl EthCoin {
])?
},
EthCoinType::Nft { .. } => {
return Err(PrepareTxDataError::Internal(
"NFT protocol is not supported for ETH and ERC20 Swaps".into(),
))
return Err(PrepareTxDataError::Internal(format!(
"{} protocol is not supported for ETH and ERC20 Swaps",
self.coin_type
)))
},
};
Ok(data)
Expand Down Expand Up @@ -609,9 +613,10 @@ impl EthCoin {
])?;
Ok(data)
},
EthCoinType::Nft { .. } => Err(PrepareTxDataError::Internal(
"NFT protocol is not supported for ETH and ERC20 Swaps".to_string(),
)),
EthCoinType::Nft { .. } => Err(PrepareTxDataError::Internal(format!(
"{} protocol is not supported for ETH and ERC20 Swaps",
self.coin_type
))),
}
}

Expand All @@ -629,7 +634,8 @@ impl EthCoin {
EthCoinType::Erc20 { token_addr, .. } => (try_tx_s!(TAKER_SWAP_V2.function(erc20_func_name)), token_addr),
EthCoinType::Nft { .. } => {
return Err(TransactionErr::ProtocolNotSupported(ERRL!(
"NFT protocol is not supported for ETH and ERC20 Swaps"
"{} protocol is not supported for ETH and ERC20 Swaps",
self.coin_type
)))
},
};
Expand All @@ -650,9 +656,10 @@ impl EthCoin {
EthCoinType::Eth => TAKER_SWAP_V2.function(ETH_TAKER_PAYMENT)?,
EthCoinType::Erc20 { .. } => TAKER_SWAP_V2.function(ERC20_TAKER_PAYMENT)?,
EthCoinType::Nft { .. } => {
return Err(PrepareTxDataError::Internal(
"NFT protocol is not supported for ETH and ERC20 Swaps".to_string(),
));
return Err(PrepareTxDataError::Internal(format!(
"{} protocol is not supported for ETH and ERC20 Swaps",
self.coin_type
)));
},
};
decode_contract_call(func, tx.unsigned().data())?
Expand Down
5 changes: 4 additions & 1 deletion mm2src/coins/eth/eth_swap_v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@ impl EthCoin {
match &self.coin_type {
EthCoinType::Eth => Ok(Address::default()),
EthCoinType::Erc20 { token_addr, .. } => Ok(*token_addr),
EthCoinType::Nft { .. } => Err("NFT protocol is not supported for ETH and ERC20 Swaps".to_string()),
EthCoinType::Nft { .. } => Err(format!(
"{} protocol is not supported for ETH and ERC20 Swaps",
self.coin_type
)),
}
}

Expand Down
7 changes: 6 additions & 1 deletion mm2src/coins/eth/eth_withdraw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,12 @@ where
let data = function.encode_input(&[Token::Address(to_addr), Token::Uint(wei_amount)])?;
(0.into(), data, *token_addr, platform.as_str())
},
EthCoinType::Nft { .. } => return MmError::err(WithdrawError::NftProtocolNotSupported),
EthCoinType::Nft { .. } => {
return MmError::err(WithdrawError::ProtocolNotSupported(format!(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this is not directly related to this PR,
but we have the ProtocolNotSupported error variant and at the same time a text description attached, which means the same. We could refactor such variants like that:

#[display(fmt = "Protocol {} not supported", _0)]  // Such an attribute could be added for RPC-level errors
ProtocolNotSupported { protocol: String }

"{} protocol is not supported",
coin.coin_type
)))
},
};
let eth_value_dec = u256_to_big_decimal(eth_value, coin.decimals).map_mm_err()?;

Expand Down
2 changes: 1 addition & 1 deletion mm2src/coins/eth/for_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ pub(crate) fn eth_coin_from_keypair(
let conf = json!({ "coins": [eth_sepolia_conf()] });
let ctx = MmCtxBuilder::new().with_conf(conf).into_mm_arc();
let ticker = match coin_type {
EthCoinType::Eth => "ETH".to_string(),
EthCoinType::Erc20 { .. } => "JST".to_string(),
EthCoinType::Nft { ref platform } => platform.to_string(),
_ => coin_type.to_string(),
};
let my_address = key_pair.address();
let coin_conf = coin_conf(&ctx, &ticker);
Expand Down
12 changes: 8 additions & 4 deletions mm2src/coins/eth/nft_swap_v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ impl EthCoin {
.await
},
EthCoinType::Eth | EthCoinType::Erc20 { .. } => Err(TransactionErr::ProtocolNotSupported(ERRL!(
"ETH and ERC20 protocols are not supported for NFT swaps."
"{} protocol is not supported for NFT swaps.",
self.coin_type
))),
}
}
Expand Down Expand Up @@ -162,7 +163,8 @@ impl EthCoin {
.await
},
EthCoinType::Eth | EthCoinType::Erc20 { .. } => Err(TransactionErr::ProtocolNotSupported(ERRL!(
"ETH and ERC20 protocols are not supported for NFT swaps."
"{} protocol is not supported for NFT swaps.",
self.coin_type
))),
}
}
Expand Down Expand Up @@ -199,7 +201,8 @@ impl EthCoin {
.await
},
EthCoinType::Eth | EthCoinType::Erc20 { .. } => Err(TransactionErr::ProtocolNotSupported(ERRL!(
"ETH and ERC20 protocols are not supported for NFT swaps."
"{} protocol is not supported for NFT swaps.",
self.coin_type
))),
}
}
Expand Down Expand Up @@ -237,7 +240,8 @@ impl EthCoin {
.await
},
EthCoinType::Eth | EthCoinType::Erc20 { .. } => Err(TransactionErr::ProtocolNotSupported(ERRL!(
"ETH and ERC20 protocols are not supported for NFT swaps."
"{} protocol is not supported for NFT swaps.",
self.coin_type
))),
}
}
Expand Down
25 changes: 23 additions & 2 deletions mm2src/coins/eth/tron.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
mod address;
pub use address::Address as TronAddress;

use ethereum_types::U256;

#[expect(dead_code)]
const TRX_DECIMALS: u32 = 6;
const ONE_TRX: u64 = 1_000_000; // 1 TRX = 1,000,000 SUN

/// Represents TRON chain/network.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum Network {
Expand All @@ -13,12 +19,27 @@ pub enum Network {
// TODO: Add more networks as needed.
}

/// Placeholder for a TRON client.
/// Draft TRON clients structure.
#[derive(Clone, Debug)]
pub struct TronClient;
pub struct TronClients {
pub clients: Vec<TronClient>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct TronClient {
pub endpoint: String,
pub network: Network,
#[serde(default)]
pub komodo_proxy: bool, // should be true for any net which requires api key
}

/// Placeholder for TRON fee params.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct TronFeeParams {
// TODO: Add TRON-specific fields in future steps.
}

#[expect(dead_code)]
// Helper function to convert TRX to SUN using U256 type
// Returns None if multiplication would overflow
fn trx_to_sun_u256(trx: u64) -> Option<U256> { trx.checked_mul(ONE_TRX).map(U256::from) }
34 changes: 34 additions & 0 deletions mm2src/coins/eth/tron/address.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! TRON address handling (base58, hex, validation, serde).

use ethereum_types::Address as EthAddress;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::convert::{TryFrom, TryInto};
use std::fmt;
Expand Down Expand Up @@ -80,6 +81,14 @@ impl Address {

/// Return the 21 bytes (0x41 + 20).
pub fn as_bytes(&self) -> &[u8] { &self.inner }

/// Construct TRON address from raw 20-byte Ethereum address bytes
fn from_eth_bytes(bytes: &[u8; 20]) -> Self {
let mut inner = [0u8; ADDRESS_BYTES_LEN];
inner[0] = ADDRESS_PREFIX;
inner[1..].copy_from_slice(bytes);
Self { inner }
}
}

impl TryFrom<[u8; ADDRESS_BYTES_LEN]> for Address {
Expand Down Expand Up @@ -144,6 +153,14 @@ impl FromStr for Address {
}
}

impl From<EthAddress> for Address {
fn from(eth_addr: EthAddress) -> Self { Address::from_eth_bytes(eth_addr.as_fixed_bytes()) }
}

impl From<&EthAddress> for Address {
fn from(eth_addr: &EthAddress) -> Self { Address::from_eth_bytes(eth_addr.as_fixed_bytes()) }
}

#[cfg(test)]
mod test {
use super::*;
Expand All @@ -164,4 +181,21 @@ mod test {
assert!(Address::from_str("foo").is_err());
assert!(Address::from_str("0xdeadbeef").is_err());
}

#[test]
fn test_convert_eth_address_to_tron() {
use ethereum_types::Address as EthAddress;

let eth_hex = "8840e6c55b9ada326d211d818c34a994aeced808";
let eth_bytes = hex::decode(eth_hex).unwrap();
let eth_address = EthAddress::from_slice(&eth_bytes);

let tron_address = Address::from(eth_address);

let expected_hex = format!("41{}", eth_hex);
assert_eq!(tron_address.to_hex(), expected_hex);

let expected_base58 = "TNPeeaaFB7K9cmo4uQpcU32zGK8G1NYqeL";
assert_eq!(tron_address.to_base58(), expected_base58);
}
}
1 change: 1 addition & 0 deletions mm2src/coins/eth/v2_activation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,7 @@ pub async fn eth_coin_from_conf_and_request_v2(
)
.await?;

// TODO support for tron specific instances instead of web3
let web3_instances = match (req.rpc_mode, &priv_key_policy) {
(EthRpcMode::Default, EthPrivKeyPolicy::Iguana(_) | EthPrivKeyPolicy::HDWallet { .. })
| (EthRpcMode::Default, EthPrivKeyPolicy::Trezor)
Expand Down
15 changes: 8 additions & 7 deletions mm2src/coins/lp_coins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2686,14 +2686,16 @@ pub enum TradePreimageError {
required: BigDecimal,
},
#[display(fmt = "The amount {} less than minimum transaction amount {}", amount, threshold)]
AmountIsTooSmall { amount: BigDecimal, threshold: BigDecimal },
AmountIsTooSmall {
amount: BigDecimal,
threshold: BigDecimal,
},
#[display(fmt = "Transport error: {}", _0)]
Transport(String),
#[from_stringify("NumConversError", "UnexpectedDerivationMethod")]
#[display(fmt = "Internal error: {}", _0)]
InternalError(String),
#[display(fmt = "Nft Protocol is not supported yet!")]
NftProtocolNotSupported,
ProtocolNotSupported(String),
}

impl TradePreimageError {
Expand Down Expand Up @@ -3181,8 +3183,7 @@ pub enum WithdrawError {
my_address: String,
token_owner: String,
},
#[display(fmt = "Nft Protocol is not supported yet!")]
NftProtocolNotSupported,
ProtocolNotSupported(String),
#[display(fmt = "Chain id must be set for typed transaction for coin {}", coin)]
NoChainIdSet {
coin: String,
Expand Down Expand Up @@ -3227,7 +3228,7 @@ impl HttpStatusCode for WithdrawError {
WithdrawError::HwError(_) => StatusCode::GONE,
#[cfg(target_arch = "wasm32")]
WithdrawError::BroadcastExpected(_) => StatusCode::BAD_REQUEST,
WithdrawError::InternalError(_) | WithdrawError::DbError(_) | WithdrawError::NftProtocolNotSupported => {
WithdrawError::InternalError(_) | WithdrawError::DbError(_) | WithdrawError::ProtocolNotSupported(_) => {
StatusCode::INTERNAL_SERVER_ERROR
},
WithdrawError::Transport(_) => StatusCode::BAD_GATEWAY,
Expand Down Expand Up @@ -3323,7 +3324,7 @@ impl From<EthGasDetailsErr> for WithdrawError {
},
EthGasDetailsErr::Internal(e) => WithdrawError::InternalError(e),
EthGasDetailsErr::Transport(e) => WithdrawError::Transport(e),
EthGasDetailsErr::NftProtocolNotSupported => WithdrawError::NftProtocolNotSupported,
EthGasDetailsErr::ProtocolNotSupported(e) => WithdrawError::ProtocolNotSupported(e),
}
}
}
Expand Down
5 changes: 2 additions & 3 deletions mm2src/mm2_main/src/lp_swap/check_balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,8 @@ impl CheckBalanceError {
threshold,
},
TradePreimageError::Transport(transport) => CheckBalanceError::Transport(transport),
TradePreimageError::InternalError(internal) => CheckBalanceError::InternalError(internal),
TradePreimageError::NftProtocolNotSupported => {
CheckBalanceError::InternalError("Nft Protocol is not supported yet!".to_string())
TradePreimageError::InternalError(internal) | TradePreimageError::ProtocolNotSupported(internal) => {
CheckBalanceError::InternalError(internal)
},
}
}
Expand Down
Loading
Loading