sui_json_rpc_api/transaction_builder.rs
1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use fastcrypto::encoding::Base64;
5use jsonrpsee::core::RpcResult;
6use jsonrpsee::proc_macros::rpc;
7
8use sui_json::SuiJsonValue;
9use sui_json_rpc_types::{
10 RPCTransactionRequestParams, SuiTransactionBlockBuilderMode, SuiTypeTag, TransactionBlockBytes,
11};
12use sui_open_rpc_macros::open_rpc;
13use sui_types::base_types::{ObjectID, SuiAddress};
14use sui_types::sui_serde::BigInt;
15
16#[open_rpc(namespace = "unsafe", tag = "Transaction Builder API")]
17#[rpc(server, client, namespace = "unsafe")]
18pub trait TransactionBuilder {
19 /// Create an unsigned transaction to transfer an object from one address to another. The object's type
20 /// must allow public transfers
21 #[method(name = "transferObject")]
22 async fn transfer_object(
23 &self,
24 /// the transaction signer's Sui address
25 signer: SuiAddress,
26 /// the ID of the object to be transferred
27 object_id: ObjectID,
28 /// gas object to be used in this transaction, node will pick one from the signer's possession if not provided
29 gas: Option<ObjectID>,
30 /// the gas budget, the transaction will fail if the gas cost exceed the budget
31 gas_budget: BigInt<u64>,
32 /// the recipient's Sui address
33 recipient: SuiAddress,
34 ) -> RpcResult<TransactionBlockBytes>;
35
36 /// Create an unsigned transaction to send SUI coin object to a Sui address. The SUI object is also used as the gas object.
37 #[method(name = "transferSui")]
38 async fn transfer_sui(
39 &self,
40 /// the transaction signer's Sui address
41 signer: SuiAddress,
42 /// the Sui coin object to be used in this transaction
43 sui_object_id: ObjectID,
44 /// the gas budget, the transaction will fail if the gas cost exceed the budget
45 gas_budget: BigInt<u64>,
46 /// the recipient's Sui address
47 recipient: SuiAddress,
48 /// the amount to be split out and transferred
49 amount: Option<BigInt<u64>>,
50 ) -> RpcResult<TransactionBlockBytes>;
51
52 /// Send `Coin<T>` to a list of addresses, where `T` can be any coin type, following a list of amounts,
53 /// The object specified in the `gas` field will be used to pay the gas fee for the transaction.
54 /// The gas object can not appear in `input_coins`. If the gas object is not specified, the RPC server
55 /// will auto-select one.
56 #[method(name = "pay")]
57 async fn pay(
58 &self,
59 /// the transaction signer's Sui address
60 signer: SuiAddress,
61 /// the Sui coins to be used in this transaction
62 input_coins: Vec<ObjectID>,
63 /// the recipients' addresses, the length of this vector must be the same as amounts.
64 recipients: Vec<SuiAddress>,
65 /// the amounts to be transferred to recipients, following the same order
66 amounts: Vec<BigInt<u64>>,
67 /// gas object to be used in this transaction, node will pick one from the signer's possession if not provided
68 gas: Option<ObjectID>,
69 /// the gas budget, the transaction will fail if the gas cost exceed the budget
70 gas_budget: BigInt<u64>,
71 ) -> RpcResult<TransactionBlockBytes>;
72
73 /// Send SUI coins to a list of addresses, following a list of amounts.
74 /// This is for SUI coin only and does not require a separate gas coin object.
75 /// Specifically, what pay_sui does are:
76 /// 1. debit each input_coin to create new coin following the order of
77 /// amounts and assign it to the corresponding recipient.
78 /// 2. accumulate all residual SUI from input coins left and deposit all SUI to the first
79 /// input coin, then use the first input coin as the gas coin object.
80 /// 3. the balance of the first input coin after tx is sum(input_coins) - sum(amounts) - actual_gas_cost
81 /// 4. all other input coints other than the first one are deleted.
82 #[method(name = "paySui")]
83 async fn pay_sui(
84 &self,
85 /// the transaction signer's Sui address
86 signer: SuiAddress,
87 /// the Sui coins to be used in this transaction, including the coin for gas payment.
88 input_coins: Vec<ObjectID>,
89 /// the recipients' addresses, the length of this vector must be the same as amounts.
90 recipients: Vec<SuiAddress>,
91 /// the amounts to be transferred to recipients, following the same order
92 amounts: Vec<BigInt<u64>>,
93 /// the gas budget, the transaction will fail if the gas cost exceed the budget
94 gas_budget: BigInt<u64>,
95 ) -> RpcResult<TransactionBlockBytes>;
96
97 /// Send all SUI coins to one recipient.
98 /// This is for SUI coin only and does not require a separate gas coin object.
99 /// Specifically, what pay_all_sui does are:
100 /// 1. accumulate all SUI from input coins and deposit all SUI to the first input coin
101 /// 2. transfer the updated first coin to the recipient and also use this first coin as gas coin object.
102 /// 3. the balance of the first input coin after tx is sum(input_coins) - actual_gas_cost.
103 /// 4. all other input coins other than the first are deleted.
104 #[method(name = "payAllSui")]
105 async fn pay_all_sui(
106 &self,
107 /// the transaction signer's Sui address
108 signer: SuiAddress,
109 /// the Sui coins to be used in this transaction, including the coin for gas payment.
110 input_coins: Vec<ObjectID>,
111 /// the recipient address,
112 recipient: SuiAddress,
113 /// the gas budget, the transaction will fail if the gas cost exceed the budget
114 gas_budget: BigInt<u64>,
115 ) -> RpcResult<TransactionBlockBytes>;
116
117 /// Create an unsigned transaction to execute a Move call on the network, by calling the specified function in the module of a given package.
118 #[method(name = "moveCall")]
119 async fn move_call(
120 &self,
121 /// the transaction signer's Sui address
122 signer: SuiAddress,
123 /// the Move package ID, e.g. `0x2`
124 package_object_id: ObjectID,
125 /// the Move module name, e.g. `pay`
126 module: String,
127 /// the move function name, e.g. `split`
128 function: String,
129 /// the type arguments of the Move function
130 type_arguments: Vec<SuiTypeTag>,
131 /// the arguments to be passed into the Move function, in [SuiJson](https://docs.sui.io/build/sui-json) format
132 arguments: Vec<SuiJsonValue>,
133 /// gas object to be used in this transaction, node will pick one from the signer's possession if not provided
134 gas: Option<ObjectID>,
135 /// the gas budget, the transaction will fail if the gas cost exceed the budget
136 gas_budget: BigInt<u64>,
137 /// Whether this is a Normal transaction or a Dev Inspect Transaction. Default to be `SuiTransactionBlockBuilderMode::Commit` when it's None.
138 execution_mode: Option<SuiTransactionBlockBuilderMode>,
139 ) -> RpcResult<TransactionBlockBytes>;
140
141 /// Create an unsigned transaction to publish a Move package.
142 #[method(name = "publish")]
143 async fn publish(
144 &self,
145 /// the transaction signer's Sui address
146 sender: SuiAddress,
147 /// the compiled bytes of a Move package
148 compiled_modules: Vec<Base64>,
149 /// a list of transitive dependency addresses that this set of modules depends on.
150 dependencies: Vec<ObjectID>,
151 /// gas object to be used in this transaction, node will pick one from the signer's possession if not provided
152 gas: Option<ObjectID>,
153 /// the gas budget, the transaction will fail if the gas cost exceed the budget
154 gas_budget: BigInt<u64>,
155 ) -> RpcResult<TransactionBlockBytes>;
156
157 /// Create an unsigned transaction to split a coin object into multiple coins.
158 #[method(name = "splitCoin")]
159 async fn split_coin(
160 &self,
161 /// the transaction signer's Sui address
162 signer: SuiAddress,
163 /// the coin object to be spilt
164 coin_object_id: ObjectID,
165 /// the amounts to split out from the coin
166 split_amounts: Vec<BigInt<u64>>,
167 /// gas object to be used in this transaction, node will pick one from the signer's possession if not provided
168 gas: Option<ObjectID>,
169 /// the gas budget, the transaction will fail if the gas cost exceed the budget
170 gas_budget: BigInt<u64>,
171 ) -> RpcResult<TransactionBlockBytes>;
172
173 /// Create an unsigned transaction to split a coin object into multiple equal-size coins.
174 #[method(name = "splitCoinEqual")]
175 async fn split_coin_equal(
176 &self,
177 /// the transaction signer's Sui address
178 signer: SuiAddress,
179 /// the coin object to be spilt
180 coin_object_id: ObjectID,
181 /// the number of coins to split into
182 split_count: BigInt<u64>,
183 /// gas object to be used in this transaction, node will pick one from the signer's possession if not provided
184 gas: Option<ObjectID>,
185 /// the gas budget, the transaction will fail if the gas cost exceed the budget
186 gas_budget: BigInt<u64>,
187 ) -> RpcResult<TransactionBlockBytes>;
188
189 /// Create an unsigned transaction to merge multiple coins into one coin.
190 #[method(name = "mergeCoins")]
191 async fn merge_coin(
192 &self,
193 /// the transaction signer's Sui address
194 signer: SuiAddress,
195 /// the coin object to merge into, this coin will remain after the transaction
196 primary_coin: ObjectID,
197 /// the coin object to be merged, this coin will be destroyed, the balance will be added to `primary_coin`
198 coin_to_merge: ObjectID,
199 /// gas object to be used in this transaction, node will pick one from the signer's possession if not provided
200 gas: Option<ObjectID>,
201 /// the gas budget, the transaction will fail if the gas cost exceed the budget
202 gas_budget: BigInt<u64>,
203 ) -> RpcResult<TransactionBlockBytes>;
204
205 /// Create an unsigned batched transaction.
206 #[method(name = "batchTransaction")]
207 async fn batch_transaction(
208 &self,
209 /// the transaction signer's Sui address
210 signer: SuiAddress,
211 /// list of transaction request parameters
212 single_transaction_params: Vec<RPCTransactionRequestParams>,
213 /// gas object to be used in this transaction, node will pick one from the signer's possession if not provided
214 gas: Option<ObjectID>,
215 /// the gas budget, the transaction will fail if the gas cost exceed the budget
216 gas_budget: BigInt<u64>,
217 /// Whether this is a regular transaction or a Dev Inspect Transaction
218 txn_builder_mode: Option<SuiTransactionBlockBuilderMode>,
219 ) -> RpcResult<TransactionBlockBytes>;
220
221 /// Add stake to a validator's staking pool using multiple coins and amount.
222 #[method(name = "requestAddStake")]
223 async fn request_add_stake(
224 &self,
225 /// the transaction signer's Sui address
226 signer: SuiAddress,
227 /// Coin<SUI> object to stake
228 coins: Vec<ObjectID>,
229 /// stake amount
230 amount: Option<BigInt<u64>>,
231 /// the validator's Sui address
232 validator: SuiAddress,
233 /// gas object to be used in this transaction, node will pick one from the signer's possession if not provided
234 gas: Option<ObjectID>,
235 /// the gas budget, the transaction will fail if the gas cost exceed the budget
236 gas_budget: BigInt<u64>,
237 ) -> RpcResult<TransactionBlockBytes>;
238
239 /// Withdraw stake from a validator's staking pool.
240 #[method(name = "requestWithdrawStake")]
241 async fn request_withdraw_stake(
242 &self,
243 /// the transaction signer's Sui address
244 signer: SuiAddress,
245 /// StakedSui object ID
246 staked_sui: ObjectID,
247 /// gas object to be used in this transaction, node will pick one from the signer's possession if not provided
248 gas: Option<ObjectID>,
249 /// the gas budget, the transaction will fail if the gas cost exceed the budget
250 gas_budget: BigInt<u64>,
251 ) -> RpcResult<TransactionBlockBytes>;
252}