Skip to content

Commit

Permalink
Add TransferSui to wallet and gateway (MystenLabs#2493)
Browse files Browse the repository at this point in the history
  • Loading branch information
lxfind authored Jun 9, 2022
1 parent b032f42 commit 7c9d300
Show file tree
Hide file tree
Showing 9 changed files with 824 additions and 650 deletions.
25 changes: 25 additions & 0 deletions crates/sui-core/src/gateway_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,16 @@ pub trait GatewayAPI {
recipient: SuiAddress,
) -> Result<TransactionData, anyhow::Error>;

/// Send SUI coin object to a Sui address. The SUI object is also used as the gas object.
async fn transfer_sui(
&self,
signer: SuiAddress,
sui_object_id: ObjectID,
gas_budget: u64,
recipient: SuiAddress,
amount: Option<u64>,
) -> Result<TransactionData, anyhow::Error>;

/// Synchronise account state with a random authorities, updates all object_ids
/// from account_addr, request only goes out to one authority.
/// this method doesn't guarantee data correctness, caller will have to handle potential byzantine authority
Expand Down Expand Up @@ -940,6 +950,21 @@ where
Ok(data)
}

async fn transfer_sui(
&self,
signer: SuiAddress,
sui_object_id: ObjectID,
gas_budget: u64,
recipient: SuiAddress,
amount: Option<u64>,
) -> Result<TransactionData, anyhow::Error> {
let object = self.get_object_internal(&sui_object_id).await?;
let object_ref = object.compute_object_reference();
let data =
TransactionData::new_transfer_sui(recipient, signer, amount, object_ref, gas_budget);
Ok(data)
}

// TODO: Get rid of the sync API.
// https://github.com/MystenLabs/sui/issues/1045
async fn sync_account_state(&self, account_addr: SuiAddress) -> Result<(), anyhow::Error> {
Expand Down
11 changes: 11 additions & 0 deletions crates/sui-gateway/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,17 @@ pub trait RpcTransactionBuilder {
recipient: SuiAddress,
) -> RpcResult<TransactionBytes>;

/// Send SUI coin object to a Sui address. The SUI object is also used as the gas object.
#[method(name = "transferSui")]
async fn transfer_sui(
&self,
signer: SuiAddress,
sui_object_id: ObjectID,
gas_budget: u64,
recipient: SuiAddress,
amount: Option<u64>,
) -> RpcResult<TransactionBytes>;

/// Execute a Move call transaction by calling the specified function in the module of a given package.
#[method(name = "moveCall")]
async fn move_call(
Expand Down
15 changes: 15 additions & 0 deletions crates/sui-gateway/src/rpc_gateway.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,21 @@ impl RpcTransactionBuilderServer for TransactionBuilderImpl {
Ok(TransactionBytes::from_data(data)?)
}

async fn transfer_sui(
&self,
signer: SuiAddress,
sui_object_id: ObjectID,
gas_budget: u64,
recipient: SuiAddress,
amount: Option<u64>,
) -> RpcResult<TransactionBytes> {
let data = self
.client
.transfer_sui(signer, sui_object_id, gas_budget, recipient, amount)
.await?;
Ok(TransactionBytes::from_data(data)?)
}

async fn publish(
&self,
sender: SuiAddress,
Expand Down
15 changes: 15 additions & 0 deletions crates/sui-gateway/src/rpc_gateway_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,21 @@ impl GatewayAPI for RpcGatewayClient {
bytes.to_data()
}

async fn transfer_sui(
&self,
signer: SuiAddress,
sui_object_id: ObjectID,
gas_budget: u64,
recipient: SuiAddress,
amount: Option<u64>,
) -> Result<TransactionData, Error> {
let bytes: TransactionBytes = self
.client
.transfer_sui(signer, sui_object_id, gas_budget, recipient, amount)
.await?;
bytes.to_data()
}

async fn sync_account_state(&self, account_addr: SuiAddress) -> Result<(), Error> {
self.client.sync_account_state(account_addr).await?;
Ok(())
Expand Down
46 changes: 23 additions & 23 deletions crates/sui-open-rpc/samples/objects.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@
"fields": {
"description": "An NFT created by the wallet Command Line Tool",
"id": {
"id": "0xd40f205ba6714c5705bb7e4a56ed6d133bb6b17f",
"id": "0xd0600eeaf253af872aff58147ab7b3ecac8c1633",
"version": 1
},
"name": "Example NFT",
"url": "ipfs://bafkreibngqhl3gaa7daob4i2vccziay2jjlp435cf66vhono7nrvww53ty"
}
},
"owner": {
"AddressOwner": "0xc351a284ca3459ae13b93d28705ead0b48d267cb"
"AddressOwner": "0xde7e8f2d751e3a29eb601115c3a667763154981b"
},
"previousTransaction": "EMyDz8fQFL5glyf+UCZa/TPkayBs1ESoWKLfV2XEvx8=",
"previousTransaction": "aP1o9K+Y/nccPj595ll82lk1wnYsmip9SUlGB7dUlHg=",
"storageRebate": 25,
"reference": {
"objectId": "0xd40f205ba6714c5705bb7e4a56ed6d133bb6b17f",
"objectId": "0xd0600eeaf253af872aff58147ab7b3ecac8c1633",
"version": 1,
"digest": "TXIabU+Kn70EYPAeY2OLKH2BrQ6kaFmda8Bw+twkQFs="
"digest": "erw9tP3tOdaNCMKvM4XAOTSQy02oVivHsyDztrInXn4="
}
}
},
Expand All @@ -36,20 +36,20 @@
"fields": {
"balance": 100000,
"id": {
"id": "0x019cbc050b0b3aa641449fee88843f45c64a0a9f",
"id": "0x12560dfb0c81a1b8f84e7ae49d657534166e827b",
"version": 0
}
}
},
"owner": {
"AddressOwner": "0xc351a284ca3459ae13b93d28705ead0b48d267cb"
"AddressOwner": "0xde7e8f2d751e3a29eb601115c3a667763154981b"
},
"previousTransaction": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
"storageRebate": 0,
"reference": {
"objectId": "0x019cbc050b0b3aa641449fee88843f45c64a0a9f",
"objectId": "0x12560dfb0c81a1b8f84e7ae49d657534166e827b",
"version": 0,
"digest": "dgIsdxebsRLd7IbEJiPhJf6P3MSfto5z++mXoZK0LZk="
"digest": "I7AN0gssk9Nu1bU8563JajqIAiMK8Aoj11ZqY+76uPs="
}
}
},
Expand All @@ -59,16 +59,16 @@
"data": {
"dataType": "package",
"disassembled": {
"M1": "// Move bytecode v5\nmodule 93f12dc603a3d1f1435ee02b3aa8e4175adff6d2.M1 {\nstruct Forge has store, key {\n\tid: VersionedID,\n\tswords_created: u64\n}\nstruct Sword has store, key {\n\tid: VersionedID,\n\tmagic: u64,\n\tstrength: u64\n}\n\ninit(Arg0: &mut TxContext) {\nB0:\n\t0: CopyLoc[0](Arg0: &mut TxContext)\n\t1: Call[6](new_id(&mut TxContext): VersionedID)\n\t2: LdU64(0)\n\t3: Pack[0](Forge)\n\t4: StLoc[1](loc0: Forge)\n\t5: MoveLoc[1](loc0: Forge)\n\t6: MoveLoc[0](Arg0: &mut TxContext)\n\t7: FreezeRef\n\t8: Call[7](sender(&TxContext): address)\n\t9: Call[0](transfer<Forge>(Forge, address))\n\t10: Ret\n}\npublic magic(Arg0: &Sword): u64 {\nB0:\n\t0: MoveLoc[0](Arg0: &Sword)\n\t1: ImmBorrowField[0](Sword.magic: u64)\n\t2: ReadRef\n\t3: Ret\n}\npublic strength(Arg0: &Sword): u64 {\nB0:\n\t0: MoveLoc[0](Arg0: &Sword)\n\t1: ImmBorrowField[1](Sword.strength: u64)\n\t2: ReadRef\n\t3: Ret\n}\npublic(script) sword_create(Arg0: &mut Forge, Arg1: u64, Arg2: u64, Arg3: address, Arg4: &mut TxContext) {\nB0:\n\t0: MoveLoc[4](Arg4: &mut TxContext)\n\t1: Call[6](new_id(&mut TxContext): VersionedID)\n\t2: MoveLoc[1](Arg1: u64)\n\t3: MoveLoc[2](Arg2: u64)\n\t4: Pack[1](Sword)\n\t5: StLoc[5](loc0: Sword)\n\t6: MoveLoc[5](loc0: Sword)\n\t7: MoveLoc[3](Arg3: address)\n\t8: Call[1](transfer<Sword>(Sword, address))\n\t9: CopyLoc[0](Arg0: &mut Forge)\n\t10: ImmBorrowField[2](Forge.swords_created: u64)\n\t11: ReadRef\n\t12: LdU64(1)\n\t13: Add\n\t14: MoveLoc[0](Arg0: &mut Forge)\n\t15: MutBorrowField[2](Forge.swords_created: u64)\n\t16: WriteRef\n\t17: Ret\n}\npublic(script) sword_transfer(Arg0: Sword, Arg1: address) {\nB0:\n\t0: MoveLoc[0](Arg0: Sword)\n\t1: MoveLoc[1](Arg1: address)\n\t2: Call[1](transfer<Sword>(Sword, address))\n\t3: Ret\n}\npublic swords_created(Arg0: &Forge): u64 {\nB0:\n\t0: MoveLoc[0](Arg0: &Forge)\n\t1: ImmBorrowField[2](Forge.swords_created: u64)\n\t2: ReadRef\n\t3: Ret\n}\n}"
"M1": "// Move bytecode v5\nmodule 46e286497c6a965cbcf06665fd710a50eca39dd4.M1 {\nstruct Forge has store, key {\n\tid: VersionedID,\n\tswords_created: u64\n}\nstruct Sword has store, key {\n\tid: VersionedID,\n\tmagic: u64,\n\tstrength: u64\n}\n\ninit(Arg0: &mut TxContext) {\nB0:\n\t0: CopyLoc[0](Arg0: &mut TxContext)\n\t1: Call[6](new_id(&mut TxContext): VersionedID)\n\t2: LdU64(0)\n\t3: Pack[0](Forge)\n\t4: StLoc[1](loc0: Forge)\n\t5: MoveLoc[1](loc0: Forge)\n\t6: MoveLoc[0](Arg0: &mut TxContext)\n\t7: FreezeRef\n\t8: Call[7](sender(&TxContext): address)\n\t9: Call[0](transfer<Forge>(Forge, address))\n\t10: Ret\n}\npublic magic(Arg0: &Sword): u64 {\nB0:\n\t0: MoveLoc[0](Arg0: &Sword)\n\t1: ImmBorrowField[0](Sword.magic: u64)\n\t2: ReadRef\n\t3: Ret\n}\npublic strength(Arg0: &Sword): u64 {\nB0:\n\t0: MoveLoc[0](Arg0: &Sword)\n\t1: ImmBorrowField[1](Sword.strength: u64)\n\t2: ReadRef\n\t3: Ret\n}\npublic(script) sword_create(Arg0: &mut Forge, Arg1: u64, Arg2: u64, Arg3: address, Arg4: &mut TxContext) {\nB0:\n\t0: MoveLoc[4](Arg4: &mut TxContext)\n\t1: Call[6](new_id(&mut TxContext): VersionedID)\n\t2: MoveLoc[1](Arg1: u64)\n\t3: MoveLoc[2](Arg2: u64)\n\t4: Pack[1](Sword)\n\t5: StLoc[5](loc0: Sword)\n\t6: MoveLoc[5](loc0: Sword)\n\t7: MoveLoc[3](Arg3: address)\n\t8: Call[1](transfer<Sword>(Sword, address))\n\t9: CopyLoc[0](Arg0: &mut Forge)\n\t10: ImmBorrowField[2](Forge.swords_created: u64)\n\t11: ReadRef\n\t12: LdU64(1)\n\t13: Add\n\t14: MoveLoc[0](Arg0: &mut Forge)\n\t15: MutBorrowField[2](Forge.swords_created: u64)\n\t16: WriteRef\n\t17: Ret\n}\npublic(script) sword_transfer(Arg0: Sword, Arg1: address) {\nB0:\n\t0: MoveLoc[0](Arg0: Sword)\n\t1: MoveLoc[1](Arg1: address)\n\t2: Call[1](transfer<Sword>(Sword, address))\n\t3: Ret\n}\npublic swords_created(Arg0: &Forge): u64 {\nB0:\n\t0: MoveLoc[0](Arg0: &Forge)\n\t1: ImmBorrowField[2](Forge.swords_created: u64)\n\t2: ReadRef\n\t3: Ret\n}\n}"
}
},
"owner": "Immutable",
"previousTransaction": "BV+ENlrr/4LzK21i+EMppyfXWwgiT/qlwnvLmLjCaNM=",
"previousTransaction": "Z1Ma9b5Ucr3Yl6hK1pybL107aMITS/FwfWOgAIUafSY=",
"storageRebate": 0,
"reference": {
"objectId": "0x93f12dc603a3d1f1435ee02b3aa8e4175adff6d2",
"objectId": "0x46e286497c6a965cbcf06665fd710a50eca39dd4",
"version": 1,
"digest": "Y++I17UKXUykUcUt+x2Xnb2He5sBeE+UOvXbHF2gfMU="
"digest": "ieD2/8vi1miAhCnWo+GZFkX4SbxCpEQRmlx1RpQ+cmg="
}
}
},
Expand All @@ -77,21 +77,21 @@
"details": {
"data": {
"dataType": "moveObject",
"type": "0x82ad443c062bd5698c804b344d121d1a3ddc6358::Hero::Hero",
"type": "0x9e08927dec0a84063d79be6db5dc31e1ba632e04::Hero::Hero",
"fields": {
"experience": 0,
"game_id": "0xfb616378b4cc45a91ebdcb2eeb0c854d2f9b1063",
"game_id": "0xae556790e572a8786a5a45a1a34a1338853097fc",
"hp": 100,
"id": {
"id": "0xc050ecf215e5ab37c907e2c95040d6fcf9778f97",
"id": "0x9dbaee096b32ef1b706a889383e9c4973d54f85b",
"version": 1
},
"sword": {
"type": "0x82ad443c062bd5698c804b344d121d1a3ddc6358::Hero::Sword",
"type": "0x9e08927dec0a84063d79be6db5dc31e1ba632e04::Hero::Sword",
"fields": {
"game_id": "0xfb616378b4cc45a91ebdcb2eeb0c854d2f9b1063",
"game_id": "0xae556790e572a8786a5a45a1a34a1338853097fc",
"id": {
"id": "0xd407820ba2aacd462b01d975b3a52c0aed12ecd7",
"id": "0x75105e77236b46af9c127985bc0fb7345dc92e0c",
"version": 0
},
"magic": 10,
Expand All @@ -101,14 +101,14 @@
}
},
"owner": {
"AddressOwner": "0xc351a284ca3459ae13b93d28705ead0b48d267cb"
"AddressOwner": "0xde7e8f2d751e3a29eb601115c3a667763154981b"
},
"previousTransaction": "d2/3R9oF2ijpTsvr0ax9SfpZ7J3jNGek1HxW+cqqXB4=",
"previousTransaction": "9YqDK9rPEEmSjjn4BawtooMaRCLmVgS98vNZa83YXWE=",
"storageRebate": 22,
"reference": {
"objectId": "0xc050ecf215e5ab37c907e2c95040d6fcf9778f97",
"objectId": "0x9dbaee096b32ef1b706a889383e9c4973d54f85b",
"version": 1,
"digest": "5N3DSruRaL6BRS9IlFjY5PJ+v/Ud5+yH5hbVRYLci7Y="
"digest": "Phsdj2jYlt48gxXeZa076wfzLy8W1+AAKdhYH2xWr8M="
}
}
}
Expand Down
Loading

0 comments on commit 7c9d300

Please sign in to comment.