sui_cluster_test/test_case/
native_transfer_test.rs1use async_trait::async_trait;
5use jsonrpsee::rpc_params;
6use tracing::info;
7
8use sui_json_rpc_types::SuiTransactionBlockResponse;
9use sui_types::{
10 base_types::{ObjectID, SuiAddress},
11 crypto::{AccountKeyPair, get_key_pair},
12 object::Owner,
13};
14
15use crate::{
16 TestCaseImpl, TestContext,
17 helper::{BalanceChangeChecker, ObjectChecker},
18};
19
20pub struct NativeTransferTest;
21
22#[async_trait]
23impl TestCaseImpl for NativeTransferTest {
24 fn name(&self) -> &'static str {
25 "NativeTransfer"
26 }
27
28 fn description(&self) -> &'static str {
29 "Test tranferring SUI coins natively"
30 }
31
32 async fn run(&self, ctx: &mut TestContext) -> Result<(), anyhow::Error> {
33 info!("Testing gas coin transfer");
34 let mut sui_objs = ctx.get_sui_from_faucet(Some(1)).await;
35 let gas_obj = ctx.get_sui_from_faucet(Some(1)).await.swap_remove(0);
36
37 let signer = ctx.get_wallet_address();
38 let (recipient_addr, _): (_, AccountKeyPair) = get_key_pair();
39 let obj_to_transfer: ObjectID = *sui_objs.swap_remove(0).id();
41 let params = rpc_params![
42 signer,
43 obj_to_transfer,
44 Some(*gas_obj.id()),
45 (2_000_000).to_string(),
46 recipient_addr
47 ];
48 let data = ctx
49 .build_transaction_remotely("unsafe_transferObject", params)
50 .await?;
51 let mut response = ctx.sign_and_execute(data, "coin transfer").await;
52
53 Self::examine_response(ctx, &mut response, signer, recipient_addr, obj_to_transfer).await;
54
55 let mut sui_objs_2 = ctx.get_sui_from_faucet(Some(1)).await;
56 let obj_to_transfer_2 = *sui_objs_2.swap_remove(0).id();
58 let params = rpc_params![
59 signer,
60 obj_to_transfer_2,
61 (2_000_000).to_string(),
62 recipient_addr,
63 None::<u64>
64 ];
65 let data = ctx
66 .build_transaction_remotely("unsafe_transferSui", params)
67 .await?;
68 let mut response = ctx.sign_and_execute(data, "coin transfer").await;
69
70 Self::examine_response(ctx, &mut response, signer, recipient_addr, obj_to_transfer).await;
71 Ok(())
72 }
73}
74
75impl NativeTransferTest {
76 async fn examine_response(
77 ctx: &TestContext,
78 response: &mut SuiTransactionBlockResponse,
79 signer: SuiAddress,
80 recipient: SuiAddress,
81 obj_to_transfer_id: ObjectID,
82 ) {
83 let balance_changes = &mut response.balance_changes.as_mut().unwrap();
84 assert_eq!(
86 balance_changes.len(),
87 2,
88 "Expect 2 balance changes emitted, but got {}",
89 balance_changes.len()
90 );
91 if balance_changes[0].owner.get_owner_address().unwrap() == signer {
94 balance_changes.reverse()
95 }
96 BalanceChangeChecker::new()
97 .owner(Owner::AddressOwner(recipient))
98 .coin_type("0x2::sui::SUI")
99 .check(&balance_changes.remove(0));
100 BalanceChangeChecker::new()
101 .owner(Owner::AddressOwner(signer))
102 .coin_type("0x2::sui::SUI")
103 .check(&balance_changes.remove(0));
104 ctx.let_fullnode_sync(vec![response.digest], 5).await;
106
107 let _ = ObjectChecker::new(obj_to_transfer_id)
108 .owner(Owner::AddressOwner(recipient))
109 .check(ctx.get_fullnode_client())
110 .await;
111 }
112}