diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 958fb84337..640dac082d 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -3445,6 +3445,31 @@ impl EthCoin { Box::new(fut.boxed().compat()) } + async fn sign_and_send_transaction_async( + &self, + value: U256, + action: Action, + data: Vec<u8>, + gas: U256, + ) -> Result<SignedEthTx, TransactionErr> { + let ctx = MmArc::from_weak(&self.ctx) + .ok_or("!ctx") + .map_err(|e| TransactionErr::Plain(e.to_string()))?; + let coin = self.clone(); + match coin.priv_key_policy { + EthPrivKeyPolicy::Iguana(ref key_pair) + | EthPrivKeyPolicy::HDWallet { + activated_key: ref key_pair, + .. + } => sign_and_send_transaction_with_keypair(ctx, &coin, key_pair, value, action, data, gas).await, + EthPrivKeyPolicy::Trezor => Err(TransactionErr::Plain(ERRL!("Trezor is not supported for EVM yet!"))), + #[cfg(target_arch = "wasm32")] + EthPrivKeyPolicy::Metamask(_) => { + sign_and_send_transaction_with_metamask(coin, value, action, data, gas).await + }, + } + } + pub fn send_to_address(&self, address: Address, value: U256) -> EthTxFut { match &self.coin_type { EthCoinType::Eth => self.sign_and_send_transaction(value, Action::Call(address), vec![], U256::from(21000)), @@ -6387,26 +6412,28 @@ impl EthCoin { let function = ERC1155_CONTRACT.function("safeTransferFrom")?; let amount_u256 = U256::from_dec_str(&args.amount.to_string()) .map_err(|e| NumConversError::new(e.to_string()))?; - let _data = function.encode_input(&[ + let data = function.encode_input(&[ Token::Address(self.my_address), Token::Address(swap_contract_address), Token::Uint(token_id_u256), Token::Uint(amount_u256), Token::Bytes(htlc_data), ])?; - let _gas = U256::from(ETH_GAS); - todo!() + let gas = U256::from(ETH_GAS); + self.sign_and_send_transaction_async(0.into(), Action::Call(token_address), data, gas) + .await }, ContractType::Erc721 => { let function = ERC721_CONTRACT.function("safeTransferFrom")?; - let _data = function.encode_input(&[ + let data = function.encode_input(&[ Token::Address(self.my_address), Token::Address(swap_contract_address), Token::Uint(token_id_u256), Token::Bytes(htlc_data), ])?; - let _gas = U256::from(ETH_GAS); - todo!() + let gas = U256::from(ETH_GAS); + self.sign_and_send_transaction_async(0.into(), Action::Call(token_address), data, gas) + .await }, }, EthCoinType::Erc20 { .. } => Err(TransactionErr::ProtocolNotSupported( diff --git a/mm2src/mm2_main/tests/docker_tests/nft_swap_proto_v2_tests.rs b/mm2src/mm2_main/tests/docker_tests/nft_swap_proto_v2_tests.rs index 091daaa4c3..ee52516ea9 100644 --- a/mm2src/mm2_main/tests/docker_tests/nft_swap_proto_v2_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/nft_swap_proto_v2_tests.rs @@ -1,14 +1,15 @@ -use super::eth_docker_tests::{eth_coin_with_random_privkey, global_nft_with_random_privkey, nft_swap_contract}; +use super::eth_docker_tests::{erc721_contract, eth_coin_with_random_privkey, global_nft_with_random_privkey, + nft_swap_contract}; use coins::eth::EthCoin; use coins::nft::nft_structs::{Chain, ContractType}; -use coins::{CoinAssocTypes, SendNftMakerPaymentArgs, SwapOps, ToBytes}; -use common::now_sec; +use coins::{CoinAssocTypes, MakerNftSwapOpsV2, SendNftMakerPaymentArgs, SwapOps, ToBytes}; +use common::{block_on, now_sec}; use mm2_number::BigUint; #[test] fn send_and_spend_erc721_maker_payment() { // TODO generate pair of utxo & eth coins from same random secret for maker / taker - let _maker_global_nft = global_nft_with_random_privkey(nft_swap_contract()); + let maker_global_nft = global_nft_with_random_privkey(nft_swap_contract()); // in prod we will need to enable global NFT for taker or add new field (for nft swap address) in EthCoin, // as EtomicSwapNft will have its own contract address, due to EIP-170 contract size limitations. // TODO need to add NFT conf in coin conf and refactor enable nft a bit @@ -17,17 +18,18 @@ fn send_and_spend_erc721_maker_payment() { let time_lock = now_sec() - 100; let taker_pubkey = taker_eth_coin.derive_htlc_pubkey(&[]); - let _send_payment_args: SendNftMakerPaymentArgs<EthCoin> = SendNftMakerPaymentArgs { + let send_payment_args: SendNftMakerPaymentArgs<EthCoin> = SendNftMakerPaymentArgs { time_lock, - taker_secret_hash: &[], - maker_secret_hash: &[], + taker_secret_hash: &[0; 32], + maker_secret_hash: &[0; 32], amount: 1.into(), taker_pub: &taker_eth_coin.parse_pubkey(&taker_pubkey).unwrap(), swap_unique_data: &[], - token_address: &[], + token_address: &erc721_contract().to_bytes(), token_id: &BigUint::from(1u32).to_bytes(), chain: &Chain::Eth.to_bytes(), contract_type: &ContractType::Erc721.to_bytes(), swap_contract_address: nft_swap_contract().as_bytes(), }; + block_on(maker_global_nft.send_nft_maker_payment_v2(send_payment_args)).unwrap(); }