diff --git a/coins/monero/tests/wallet-rpc-compatibility.rs b/coins/monero/tests/wallet-rpc-compatibility.rs index 12353db8..230faec2 100644 --- a/coins/monero/tests/wallet-rpc-compatibility.rs +++ b/coins/monero/tests/wallet-rpc-compatibility.rs @@ -3,26 +3,52 @@ use std::{ str::FromStr, }; -use rand_core::{RngCore, OsRng}; +use rand_core::{OsRng, RngCore}; + +use serde::Deserialize; +use serde_json::json; use monero_rpc::{ - monero::{Amount, Address}, - TransferOptions, + monero::{ + Amount, Address, + cryptonote::{hash::Hash, subaddress::Index}, + util::address::PaymentId, + }, + TransferOptions, WalletClient, }; use monero_serai::{ wallet::address::{Network, AddressSpec, SubaddressIndex}, - wallet::Scanner, + wallet::{Scanner, address::MoneroAddress}, + rpc::Rpc, + transaction::Transaction, }; mod runner; -async fn test_from_wallet_rpc_to_self(spec: AddressSpec) { +async fn make_integrated_address(payment_id: [u8; 8]) -> String { + #[derive(Deserialize, Debug)] + struct IntegratedAddressResponse { + integrated_address: String, + } + + let rpc = Rpc::new("http://127.0.0.1:6061".to_string()).unwrap(); + let res = rpc + .json_rpc_call::( + "make_integrated_address", + Some(json!({ "payment_id": hex::encode(payment_id) })), + ) + .await + .unwrap(); + + res.integrated_address +} + +async fn initialize_rpcs() -> (WalletClient, Rpc, monero_rpc::monero::Address) { let wallet_rpc = monero_rpc::RpcClientBuilder::new().build("http://127.0.0.1:6061").unwrap().wallet(); let daemon_rpc = runner::rpc().await; - // initialize wallet rpc let address_resp = wallet_rpc.get_address(0, None).await; let wallet_rpc_addr = if address_resp.is_ok() { address_resp.unwrap().address @@ -32,6 +58,12 @@ async fn test_from_wallet_rpc_to_self(spec: AddressSpec) { daemon_rpc.generate_blocks(&addr.to_string(), 70).await.unwrap(); addr }; + (wallet_rpc, daemon_rpc, wallet_rpc_addr) +} + +async fn test_from_wallet_rpc_to_self(spec: AddressSpec) { + // initialize rpc + let (wallet_rpc, daemon_rpc, wallet_rpc_addr) = initialize_rpcs().await; // make an addr let (_, view_pair, _) = runner::random_address(); @@ -89,3 +121,82 @@ async_sequential!( test_from_wallet_rpc_to_self(AddressSpec::Integrated(payment_id)).await; } ); + +test!( + test_send_to_wallet_rpc_standard, + ( + |_, mut builder: Builder, _| async move { + // initialize rpc + let (wallet_rpc, _, wallet_rpc_addr) = initialize_rpcs().await; + + // add destination + builder.add_payment( + MoneroAddress::from_str(Network::Mainnet, &wallet_rpc_addr.to_string()).unwrap(), + 1000000, + ); + (builder.build().unwrap(), (wallet_rpc,)) + }, + |_, tx: Transaction, _, data: (WalletClient,)| async move { + // confirm receipt + data.0.refresh(None).await.unwrap(); + let transfer = + data.0.get_transfer(Hash::from_slice(&tx.hash()), None).await.unwrap().unwrap(); + assert_eq!(transfer.amount.as_pico(), 1000000); + assert_eq!(transfer.subaddr_index, Index { major: 0, minor: 0 }); + }, + ), +); + +test!( + test_send_to_wallet_rpc_subaddress, + ( + |_, mut builder: Builder, _| async move { + // initialize rpc + let (wallet_rpc, _, _) = initialize_rpcs().await; + + // make the addr + let (subaddress, index) = wallet_rpc.create_address(0, None).await.unwrap(); + + builder.add_payment( + MoneroAddress::from_str(Network::Mainnet, &subaddress.to_string()).unwrap(), + 1000000, + ); + (builder.build().unwrap(), (wallet_rpc, index)) + }, + |_, tx: Transaction, _, data: (WalletClient, u32)| async move { + // confirm receipt + data.0.refresh(None).await.unwrap(); + let transfer = + data.0.get_transfer(Hash::from_slice(&tx.hash()), None).await.unwrap().unwrap(); + assert_eq!(transfer.amount.as_pico(), 1000000); + assert_eq!(transfer.subaddr_index, Index { major: 0, minor: data.1 }); + }, + ), +); + +test!( + test_send_to_wallet_rpc_integrated, + ( + |_, mut builder: Builder, _| async move { + // initialize rpc + let (wallet_rpc, _, _) = initialize_rpcs().await; + + // make the addr + let mut payment_id = [0u8; 8]; + OsRng.fill_bytes(&mut payment_id); + let addr = make_integrated_address(payment_id).await; + + builder.add_payment(MoneroAddress::from_str(Network::Mainnet, &addr).unwrap(), 1000000); + (builder.build().unwrap(), (wallet_rpc, payment_id)) + }, + |_, tx: Transaction, _, data: (WalletClient, [u8; 8])| async move { + // confirm receipt + data.0.refresh(None).await.unwrap(); + let transfer = + data.0.get_transfer(Hash::from_slice(&tx.hash()), None).await.unwrap().unwrap(); + assert_eq!(transfer.amount.as_pico(), 1000000); + assert_eq!(transfer.subaddr_index, Index { major: 0, minor: 0 }); + assert_eq!(transfer.payment_id.0, PaymentId::from_slice(&data.1)); + }, + ), +);