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}