@mysten/docs 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/dist/bcs/index.md +358 -0
- package/dist/bcs/llms-index.md +4 -0
- package/dist/codegen/index.md +441 -0
- package/dist/codegen/llms-index.md +4 -0
- package/dist/dapp-kit/actions/connect-wallet.md +69 -0
- package/dist/dapp-kit/actions/disconnect-wallet.md +38 -0
- package/dist/dapp-kit/actions/sign-and-execute-transaction.md +96 -0
- package/dist/dapp-kit/actions/sign-personal-message.md +58 -0
- package/dist/dapp-kit/actions/sign-transaction.md +65 -0
- package/dist/dapp-kit/actions/switch-account.md +37 -0
- package/dist/dapp-kit/actions/switch-network.md +37 -0
- package/dist/dapp-kit/dapp-kit-instance.md +162 -0
- package/dist/dapp-kit/getting-started/create-dapp.md +151 -0
- package/dist/dapp-kit/getting-started/next-js.md +162 -0
- package/dist/dapp-kit/getting-started/react.md +172 -0
- package/dist/dapp-kit/getting-started/vue.md +193 -0
- package/dist/dapp-kit/index.md +70 -0
- package/dist/dapp-kit/llms-index.md +26 -0
- package/dist/dapp-kit/react/components/connect-button.md +42 -0
- package/dist/dapp-kit/react/components/connect-modal.md +51 -0
- package/dist/dapp-kit/react/components/index.md +13 -0
- package/dist/dapp-kit/react/dapp-kit-provider.md +86 -0
- package/dist/dapp-kit/react/hooks/index.md +25 -0
- package/dist/dapp-kit/react/hooks/use-current-account.md +33 -0
- package/dist/dapp-kit/react/hooks/use-current-client.md +36 -0
- package/dist/dapp-kit/react/hooks/use-current-network.md +28 -0
- package/dist/dapp-kit/react/hooks/use-current-wallet.md +36 -0
- package/dist/dapp-kit/react/hooks/use-dapp-kit.md +100 -0
- package/dist/dapp-kit/react/hooks/use-wallet-connection.md +48 -0
- package/dist/dapp-kit/react/hooks/use-wallets.md +33 -0
- package/dist/dapp-kit/state.md +169 -0
- package/dist/dapp-kit/theming.md +196 -0
- package/dist/dapp-kit/web-components/connect-button.md +89 -0
- package/dist/dapp-kit/web-components/connect-modal.md +177 -0
- package/dist/kiosk/advanced-examples.md +101 -0
- package/dist/kiosk/from-v1.md +320 -0
- package/dist/kiosk/index.md +22 -0
- package/dist/kiosk/kiosk-client/introduction.md +52 -0
- package/dist/kiosk/kiosk-client/kiosk-transaction/examples.md +119 -0
- package/dist/kiosk/kiosk-client/kiosk-transaction/kiosk-transaction.md +103 -0
- package/dist/kiosk/kiosk-client/kiosk-transaction/managing.md +235 -0
- package/dist/kiosk/kiosk-client/kiosk-transaction/purchasing.md +110 -0
- package/dist/kiosk/kiosk-client/querying.md +237 -0
- package/dist/kiosk/kiosk-client/transfer-policy-transaction/introduction.md +79 -0
- package/dist/kiosk/kiosk-client/transfer-policy-transaction/using-the-manager.md +115 -0
- package/dist/kiosk/llms-index.md +8 -0
- package/dist/llms-index.md +125 -0
- package/dist/payment-kit/getting-started.md +256 -0
- package/dist/payment-kit/index.md +132 -0
- package/dist/payment-kit/llms-index.md +8 -0
- package/dist/payment-kit/payment-kit-sdk.md +747 -0
- package/dist/payment-kit/payment-processing.md +372 -0
- package/dist/payment-kit/registry-management.md +529 -0
- package/dist/seal/index.md +85 -0
- package/dist/seal/llms-index.md +4 -0
- package/dist/slush-wallet/dapp.md +95 -0
- package/dist/slush-wallet/deep-linking.md +465 -0
- package/dist/slush-wallet/index.md +7 -0
- package/dist/slush-wallet/llms-index.md +6 -0
- package/dist/sui/bcs.md +134 -0
- package/dist/sui/clients/core.md +606 -0
- package/dist/sui/clients/graphql.md +101 -0
- package/dist/sui/clients/grpc.md +155 -0
- package/dist/sui/clients/index.md +95 -0
- package/dist/sui/clients/json-rpc.md +239 -0
- package/dist/sui/cryptography/keypairs.md +267 -0
- package/dist/sui/cryptography/multisig.md +194 -0
- package/dist/sui/cryptography/passkey.md +111 -0
- package/dist/sui/cryptography/webcrypto-signer.md +81 -0
- package/dist/sui/executors.md +148 -0
- package/dist/sui/faucet.md +26 -0
- package/dist/sui/hello-sui.md +115 -0
- package/dist/sui/index.md +53 -0
- package/dist/sui/install.md +61 -0
- package/dist/sui/llm-docs.md +32 -0
- package/dist/sui/llms-index.md +44 -0
- package/dist/sui/migrations/0.38.md +58 -0
- package/dist/sui/migrations/sui-1.0.md +455 -0
- package/dist/sui/migrations/sui-2.0/agent-prompt.md +42 -0
- package/dist/sui/migrations/sui-2.0/dapp-kit.md +350 -0
- package/dist/sui/migrations/sui-2.0/deepbook-v3.md +33 -0
- package/dist/sui/migrations/sui-2.0/index.md +158 -0
- package/dist/sui/migrations/sui-2.0/json-rpc-migration.md +386 -0
- package/dist/sui/migrations/sui-2.0/kiosk.md +120 -0
- package/dist/sui/migrations/sui-2.0/sdk-maintainers.md +90 -0
- package/dist/sui/migrations/sui-2.0/seal.md +14 -0
- package/dist/sui/migrations/sui-2.0/sui.md +341 -0
- package/dist/sui/migrations/sui-2.0/suins.md +43 -0
- package/dist/sui/migrations/sui-2.0/wallet-builders.md +66 -0
- package/dist/sui/migrations/sui-2.0/walrus.md +41 -0
- package/dist/sui/migrations/sui-2.0/zksend.md +95 -0
- package/dist/sui/plugins.md +258 -0
- package/dist/sui/sdk-building.md +344 -0
- package/dist/sui/transaction-building/basics.md +299 -0
- package/dist/sui/transaction-building/gas.md +62 -0
- package/dist/sui/transaction-building/intents.md +62 -0
- package/dist/sui/transaction-building/offline.md +73 -0
- package/dist/sui/transaction-building/sponsored-transactions.md +22 -0
- package/dist/sui/utils/derived_objects.md +59 -0
- package/dist/sui/utils/index.md +52 -0
- package/dist/sui/zklogin.md +83 -0
- package/dist/walrus/index.md +527 -0
- package/dist/walrus/llms-index.md +4 -0
- package/dist/zksend/index.md +27 -0
- package/dist/zksend/link-builder.md +192 -0
- package/dist/zksend/llms-index.md +5 -0
- package/package.json +66 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
# Sui Programmable Transaction Basics
|
|
2
|
+
|
|
3
|
+
> Construct programmable transaction blocks with the Transaction API
|
|
4
|
+
|
|
5
|
+
This example starts by constructing a transaction to send SUI. To construct transactions, import the
|
|
6
|
+
`Transaction` class and construct it:
|
|
7
|
+
|
|
8
|
+
```tsx
|
|
9
|
+
|
|
10
|
+
const tx = new Transaction();
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
You can then add commands to the transaction .
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
// create a new coin with balance 100, based on the coins used as gas payment
|
|
17
|
+
// you can define any balance here
|
|
18
|
+
const [coin] = tx.splitCoins(tx.gas, [100]);
|
|
19
|
+
|
|
20
|
+
// transfer the split coin to a specific address
|
|
21
|
+
tx.transferObjects([coin], '0xSomeSuiAddress');
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
You can attach multiple commands of the same type to a transaction, as well. For example, to get a
|
|
25
|
+
list of transfers and iterate over them to transfer coins to each of them:
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
interface Transfer {
|
|
29
|
+
to: string;
|
|
30
|
+
amount: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// procure a list of some Sui transfers to make
|
|
34
|
+
const transfers: Transfer[] = getTransfers();
|
|
35
|
+
|
|
36
|
+
const tx = new Transaction();
|
|
37
|
+
|
|
38
|
+
// first, split the gas coin into multiple coins
|
|
39
|
+
const coins = tx.splitCoins(
|
|
40
|
+
tx.gas,
|
|
41
|
+
transfers.map((transfer) => transfer.amount),
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
// next, create a transfer command for each coin
|
|
45
|
+
transfers.forEach((transfer, index) => {
|
|
46
|
+
tx.transferObjects([coins[index]], transfer.to);
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
After you have the transaction defined, you can directly execute it with a signer using
|
|
51
|
+
`signAndExecuteTransaction`.
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
const result = await client.signAndExecuteTransaction({ signer: keypair, transaction: tx });
|
|
55
|
+
|
|
56
|
+
// IMPORTANT: Always check the transaction status
|
|
57
|
+
// Transactions can execute but still fail (e.g., insufficient gas, move errors)
|
|
58
|
+
if (result.$kind === 'FailedTransaction') {
|
|
59
|
+
throw new Error(`Transaction failed: ${result.FailedTransaction.status.error?.message}`);
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Observing the results of a transaction
|
|
64
|
+
|
|
65
|
+
When you use `client.signAndExecuteTransaction` or `client.executeTransactionBlock`, the transaction
|
|
66
|
+
will be finalized on the blockchain before the function resolves, but the effects of the transaction
|
|
67
|
+
may not be immediately observable.
|
|
68
|
+
|
|
69
|
+
There are 2 ways to observe the results of a transaction. Methods like
|
|
70
|
+
`client.signAndExecuteTransaction` accept an `options` object with options like `showObjectChanges`
|
|
71
|
+
and `showBalanceChanges` (see
|
|
72
|
+
[the SuiJsonRpcClient docs for more details](/sui/clients/json-rpc#arguments)). These options will
|
|
73
|
+
cause the request to contain additional details about the effects of the transaction that can be
|
|
74
|
+
immediately displayed to the user, or used for further processing in your application.
|
|
75
|
+
|
|
76
|
+
The other way effects of transactions can be observed is by querying other RPC methods like
|
|
77
|
+
`client.getBalances` that return objects or balances owned by a specific address. These RPC calls
|
|
78
|
+
depend on the RPC node having indexed the effects of the transaction, which may not have happened
|
|
79
|
+
immediately after a transaction has been executed. To ensure that effects of a transaction are
|
|
80
|
+
represented in future RPC calls, you can use the `waitForTransaction` method on the client:
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
const result = await client.signAndExecuteTransaction({ signer: keypair, transaction: tx });
|
|
84
|
+
|
|
85
|
+
// Check transaction status
|
|
86
|
+
if (result.$kind === 'FailedTransaction') {
|
|
87
|
+
throw new Error(`Transaction failed: ${result.FailedTransaction.status.error?.message}`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
await client.waitForTransaction({ result });
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Once `waitForTransaction` resolves, any future RPC calls will be guaranteed to reflect the effects
|
|
94
|
+
of the transaction.
|
|
95
|
+
|
|
96
|
+
## Transactions
|
|
97
|
+
|
|
98
|
+
Programmable Transactions have two key concepts: inputs and commands.
|
|
99
|
+
|
|
100
|
+
Commands are steps of execution in the transaction. Each command in a Transaction takes a set of
|
|
101
|
+
inputs, and produces results. The inputs for a transaction depend on the kind of command. Sui
|
|
102
|
+
supports following commands:
|
|
103
|
+
|
|
104
|
+
- `tx.splitCoins(coin, amounts)` - Creates new coins with the defined amounts, split from the
|
|
105
|
+
provided coin. Returns the coins so that it can be used in subsequent transactions.
|
|
106
|
+
- Example: `tx.splitCoins(tx.gas, [100, 200])`
|
|
107
|
+
- `tx.mergeCoins(destinationCoin, sourceCoins)` - Merges the sourceCoins into the destinationCoin.
|
|
108
|
+
- Example: `tx.mergeCoins(tx.object(coin1), [tx.object(coin2), tx.object(coin3)])`
|
|
109
|
+
- `tx.transferObjects(objects, address)` - Transfers a list of objects to the specified address.
|
|
110
|
+
- Example: `tx.transferObjects([tx.object(thing1), tx.object(thing2)], myAddress)`
|
|
111
|
+
- `tx.moveCall({ target, arguments, typeArguments })` - Executes a Move call. Returns whatever the
|
|
112
|
+
Sui Move call returns.
|
|
113
|
+
- Example:
|
|
114
|
+
`tx.moveCall({ target: '0x2::devnet_nft::mint', arguments: [tx.pure.string(name), tx.pure.string(description), tx.pure.string(image)] })`
|
|
115
|
+
- `tx.makeMoveVec({ type, elements })` - Constructs a vector of objects that can be passed into a
|
|
116
|
+
`moveCall`. This is required as there’s no way to define a vector as an input.
|
|
117
|
+
- Example: `tx.makeMoveVec({ elements: [tx.object(id1), tx.object(id2)] })`
|
|
118
|
+
- `tx.publish(modules, dependencies)` - Publishes a Move package. Returns the upgrade capability
|
|
119
|
+
object.
|
|
120
|
+
|
|
121
|
+
## Passing inputs to a command
|
|
122
|
+
|
|
123
|
+
Command inputs can be provided in a number of different ways, depending on the command, and the type
|
|
124
|
+
of value being provided.
|
|
125
|
+
|
|
126
|
+
#### JavaScript values
|
|
127
|
+
|
|
128
|
+
For specific command arguments (`amounts` in `splitCoins`, and `address` in `transferObjects`) the
|
|
129
|
+
expected type is known ahead of time, and you can directly pass raw javascript values when calling
|
|
130
|
+
the command method. appropriate Move type automatically.
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
// the amount to split off the gas coin is provided as a pure javascript number
|
|
134
|
+
const [coin] = tx.splitCoins(tx.gas, [100]);
|
|
135
|
+
// the address for the transfer is provided as a pure javascript string
|
|
136
|
+
tx.transferObjects([coin], '0xSomeSuiAddress');
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
#### Pure values
|
|
140
|
+
|
|
141
|
+
When providing inputs that are not on chain objects, the values must be serialized as
|
|
142
|
+
|
|
143
|
+
[BCS](https://sdk.mystenlabs.com/bcs), which can be done using `tx.pure` eg,
|
|
144
|
+
`tx.pure.address(address)` or `tx.pure(bcs.vector(bcs.U8).serialize(bytes))`.
|
|
145
|
+
|
|
146
|
+
`tx.pure` can be called as a function that accepts a SerializedBcs object, or as a namespace that
|
|
147
|
+
contains functions for each of the supported types.
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
const [coin] = tx.splitCoins(tx.gas, [tx.pure.u64(100)]);
|
|
151
|
+
const [coin] = tx.splitCoins(tx.gas, [tx.pure(bcs.U64.serialize(100))]);
|
|
152
|
+
tx.transferObjects([coin], tx.pure.address('0xSomeSuiAddress'));
|
|
153
|
+
tx.transferObjects([coin], tx.pure(bcs.Address.serialize('0xSomeSuiAddress')));
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
To pass `vector` or `option` types, you can pass use the corresponding methods on `tx.pure`, use
|
|
157
|
+
tx.pure as a function with a type argument, or serialize the value before passing it to tx.pure
|
|
158
|
+
using the bcs sdk:
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
|
|
162
|
+
tx.moveCall({
|
|
163
|
+
target: '0x2::foo::bar',
|
|
164
|
+
arguments: [
|
|
165
|
+
// using vector and option methods
|
|
166
|
+
tx.pure.vector('u8', [1, 2, 3]),
|
|
167
|
+
tx.pure.option('u8', 1),
|
|
168
|
+
tx.pure.option('u8', null),
|
|
169
|
+
|
|
170
|
+
// Using pure with type arguments
|
|
171
|
+
tx.pure('vector<u8>', [1, 2, 3]),
|
|
172
|
+
tx.pure('option<u8>', 1),
|
|
173
|
+
tx.pure('option<u8>', null),
|
|
174
|
+
tx.pure('vector<option<u8>>', [1, null, 2]),
|
|
175
|
+
|
|
176
|
+
// Using bcs.serialize
|
|
177
|
+
tx.pure(bcs.vector(bcs.U8).serialize([1, 2, 3])),
|
|
178
|
+
tx.pure(bcs.option(bcs.U8).serialize(1)),
|
|
179
|
+
tx.pure(bcs.option(bcs.U8).serialize(null)),
|
|
180
|
+
tx.pure(bcs.vector(bcs.option(bcs.U8)).serialize([1, null, 2])),
|
|
181
|
+
],
|
|
182
|
+
});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
#### Object references
|
|
186
|
+
|
|
187
|
+
To use an on chain object as a transaction input, you must pass a reference to that object. This can
|
|
188
|
+
be done by calling `tx.object` with the object id. Transaction arguments that only accept objects
|
|
189
|
+
(like `objects` in `transferObjects`) will automatically treat any provided strings as objects ids.
|
|
190
|
+
For methods like `moveCall` that accept both objects and other types, you must explicitly call
|
|
191
|
+
`tx.object` to convert the id to an object reference.
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
// Object IDs can be passed to some methods like (transferObjects) directly
|
|
195
|
+
tx.transferObjects(['0xSomeObject'], 'OxSomeAddress');
|
|
196
|
+
// tx.object can be used anywhere an object is accepted
|
|
197
|
+
tx.transferObjects([tx.object('0xSomeObject')], 'OxSomeAddress');
|
|
198
|
+
|
|
199
|
+
tx.moveCall({
|
|
200
|
+
target: '0x2::nft::mint',
|
|
201
|
+
// object IDs must be wrapped in moveCall arguments
|
|
202
|
+
arguments: [tx.object('0xSomeObject')],
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// tx.object automatically converts the object ID to receiving transaction arguments if the moveCall expects it
|
|
206
|
+
tx.moveCall({
|
|
207
|
+
target: '0xSomeAddress::example::receive_object',
|
|
208
|
+
// 0xSomeAddress::example::receive_object expects a receiving argument and has a Move definition that looks like this:
|
|
209
|
+
// public fun receive_object<T: key>(parent_object: &mut ParentObjectType, receiving_object: Receiving<ChildObjectType>) { ... }
|
|
210
|
+
arguments: [tx.object('0xParentObjectID'), tx.object('0xReceivingObjectID')],
|
|
211
|
+
});
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
When building a transaction, Sui expects all objects to be fully resolved, including the object
|
|
215
|
+
version. The SDK automatically looks up the current version of objects for any provided object
|
|
216
|
+
reference when building a transaction. If the object reference is used as a receiving argument to a
|
|
217
|
+
`moveCall`, the object reference is automatically converted to a receiving transaction argument.
|
|
218
|
+
This greatly simplifies building transactions, but requires additional RPC calls. You can optimize
|
|
219
|
+
this process by providing a fully resolved object reference instead:
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
// for owned or immutable objects
|
|
223
|
+
tx.object(Inputs.ObjectRef({ digest, objectId, version }));
|
|
224
|
+
|
|
225
|
+
// for shared objects
|
|
226
|
+
tx.object(Inputs.SharedObjectRef({ objectId, initialSharedVersion, mutable }));
|
|
227
|
+
|
|
228
|
+
// for receiving objects
|
|
229
|
+
tx.object(Inputs.ReceivingRef({ digest, objectId, version }));
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
##### Object helpers
|
|
233
|
+
|
|
234
|
+
There are a handful of specific object types that can be referenced through helper methods on
|
|
235
|
+
tx.object:
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
tx.object.system(),
|
|
239
|
+
tx.object.clock(),
|
|
240
|
+
tx.object.random(),
|
|
241
|
+
tx.object.denyList(),
|
|
242
|
+
|
|
243
|
+
tx.object.option({
|
|
244
|
+
type: '0x123::example::Thing',
|
|
245
|
+
// value can be an Object ID, or any other object reference, or null for `none`
|
|
246
|
+
value: '0x456',
|
|
247
|
+
}),
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
#### Transaction results
|
|
251
|
+
|
|
252
|
+
You can also use the result of a command as an argument in a subsequent commands. Each method on the
|
|
253
|
+
transaction builder returns a reference to the transaction result.
|
|
254
|
+
|
|
255
|
+
```tsx
|
|
256
|
+
// split a coin object off of the gas object
|
|
257
|
+
const [coin] = tx.splitCoins(tx.gas, [100]);
|
|
258
|
+
// transfer the resulting coin object
|
|
259
|
+
tx.transferObjects([coin], address);
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
When a command returns multiple results, you can access the result at a specific index either using
|
|
263
|
+
destructuring, or array indexes.
|
|
264
|
+
|
|
265
|
+
```tsx
|
|
266
|
+
// destructuring (preferred, as it gives you logical local names)
|
|
267
|
+
const [nft1, nft2] = tx.moveCall({ target: '0x2::nft::mint_many' });
|
|
268
|
+
tx.transferObjects([nft1, nft2], address);
|
|
269
|
+
|
|
270
|
+
// array indexes
|
|
271
|
+
const mintMany = tx.moveCall({ target: '0x2::nft::mint_many' });
|
|
272
|
+
tx.transferObjects([mintMany[0], mintMany[1]], address);
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Get transaction bytes
|
|
276
|
+
|
|
277
|
+
If you need the transaction bytes, instead of signing or executing the transaction, you can use the
|
|
278
|
+
`build` method on the transaction builder itself.
|
|
279
|
+
|
|
280
|
+
**Important:** You might need to explicitly call `setSender()` on the transaction to ensure that the
|
|
281
|
+
`sender` field is populated. This is normally done by the signer before signing the transaction, but
|
|
282
|
+
will not be done automatically if you’re building the transaction bytes yourself.
|
|
283
|
+
|
|
284
|
+
```tsx
|
|
285
|
+
const tx = new Transaction();
|
|
286
|
+
|
|
287
|
+
// ... add some transactions...
|
|
288
|
+
|
|
289
|
+
await tx.build({ client });
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
In most cases, building requires your SuiJsonRpcClient to fully resolve input values.
|
|
293
|
+
|
|
294
|
+
If you have transaction bytes, you can also convert them back into a `Transaction` class:
|
|
295
|
+
|
|
296
|
+
```tsx
|
|
297
|
+
const bytes = getTransactionBytesFromSomewhere();
|
|
298
|
+
const tx = Transaction.from(bytes);
|
|
299
|
+
```
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Paying for Sui Transactions with Gas Coins
|
|
2
|
+
|
|
3
|
+
> Configure gas budget, price, and coin selection for transactions
|
|
4
|
+
|
|
5
|
+
With Programmable Transactions, you can use the gas payment coin to construct coins with a set
|
|
6
|
+
balance using `splitCoin`. This is useful for Sui payments, and avoids the need for up-front coin
|
|
7
|
+
selection. You can use `tx.gas` to access the gas coin in a transaction, and it is valid as input
|
|
8
|
+
for any arguments, as long as it is used
|
|
9
|
+
[by-reference](https://docs.sui.io/guides/developer/sui-101/simulating-refs). Practically speaking,
|
|
10
|
+
this means you can also add to the gas coin with `mergeCoins` and borrow it for Move functions with
|
|
11
|
+
`moveCall`.
|
|
12
|
+
|
|
13
|
+
You can also transfer the gas coin using `transferObjects`, in the event that you want to transfer
|
|
14
|
+
all of your coin balance to another address.
|
|
15
|
+
|
|
16
|
+
## Gas configuration
|
|
17
|
+
|
|
18
|
+
The new transaction builder comes with default behavior for all gas logic, including automatically
|
|
19
|
+
setting the gas price, budget, and selecting coins to be used as gas. This behavior can be
|
|
20
|
+
customized.
|
|
21
|
+
|
|
22
|
+
### Gas price
|
|
23
|
+
|
|
24
|
+
By default, the gas price is set to the reference gas price of the network. You can also explicitly
|
|
25
|
+
set the gas price of the transaction by calling `setGasPrice` on the transaction builder.
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
tx.setGasPrice(gasPrice);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Budget
|
|
32
|
+
|
|
33
|
+
By default, the gas budget is automatically derived by executing a dry-run of the transaction
|
|
34
|
+
beforehand. The dry run gas consumption is then used to determine a balance for the transaction. You
|
|
35
|
+
can override this behavior by explicitly setting a gas budget for the transaction, by calling
|
|
36
|
+
`setGasBudget` on the transaction builder.
|
|
37
|
+
|
|
38
|
+
**Note:** The gas budget is represented in Sui, and should take the gas price of the transaction
|
|
39
|
+
into account.
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
tx.setGasBudget(gasBudgetAmount);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Gas payment
|
|
46
|
+
|
|
47
|
+
By default, the gas payment is automatically determined by the SDK. The SDK selects all of the users
|
|
48
|
+
coins that are not used as inputs in the transaction.
|
|
49
|
+
|
|
50
|
+
The list of coins used as gas payment will be merged down into a single gas coin before executing
|
|
51
|
+
the transaction, and all but one of the gas objects will be deleted. The gas coin at the 0-index
|
|
52
|
+
will be the coin that all others are merged into.
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
// you need to ensure that the coins do not overlap with any
|
|
56
|
+
// of the input objects for the transaction
|
|
57
|
+
tx.setGasPayment([coin1, coin2]);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Gas coins should be objects containing the coins objectId, version, and digest.
|
|
61
|
+
|
|
62
|
+
<auto-type-table type="{ objectId: string, version: string | number, digest: string }" />
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Transaction Intents
|
|
2
|
+
|
|
3
|
+
> Use high-level intents to simplify transaction building
|
|
4
|
+
|
|
5
|
+
Transaction Intents enable 3rd party SDKs and [Transaction Plugins](../plugins) to more easily add
|
|
6
|
+
complex operations to a Transaction. The Typescript SDK currently only includes a single Intent
|
|
7
|
+
(CoinWithBalance), but more will be added in the future.
|
|
8
|
+
|
|
9
|
+
## The CoinWithBalance intent
|
|
10
|
+
|
|
11
|
+
The `CoinWithBalance` intent makes it easy to get a coin with a specific balance. For SUI, this has
|
|
12
|
+
generally been done by splitting the gas coin:
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
const tx = new Transaction();
|
|
16
|
+
|
|
17
|
+
const [coin] = tx.splitCoins(tx.gas, [100]);
|
|
18
|
+
|
|
19
|
+
tx.transferObjects([coin], recipient);
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
This approach works well for SUI, but can't be used for other coin types. The CoinWithBalance intent
|
|
23
|
+
solves this by providing a helper function that automatically adds the correct SplitCoins and
|
|
24
|
+
MergeCoins commands to the transaction:
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
|
|
28
|
+
const tx = new Transaction();
|
|
29
|
+
|
|
30
|
+
// Setting the sender is required for the CoinWithBalance intent to resolve coins when not using the gas coin
|
|
31
|
+
tx.setSender(keypair.toSuiAddress());
|
|
32
|
+
|
|
33
|
+
tx.transferObjects(
|
|
34
|
+
[
|
|
35
|
+
// Create a SUI coin (balance is in MIST)
|
|
36
|
+
coinWithBalance({ balance: 100 }),
|
|
37
|
+
// Create a coin of another type
|
|
38
|
+
coinWithBalance({ balance: 100, type: '0x123::foo:Bar' }),
|
|
39
|
+
],
|
|
40
|
+
recipient,
|
|
41
|
+
);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Splitting the gas coin also causes problems for sponsored transactions. When sponsoring
|
|
45
|
+
transactions, the gas coin comes from the sponsor instead of the transaction sender. Transaction
|
|
46
|
+
sponsors usually do not sponsor transactions that use the gas coin for anything other than gas. To
|
|
47
|
+
transfer SUI that does not use the gas coin, you can set the `useGasCoin` option to `false`:
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
const tx = new Transaction();
|
|
51
|
+
tx.transferObjects([coinWithBalance({ balance: 100, useGasCoin: false })], recipient);
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
It's important to only set `useGasCoin` option to false for sponsored transactions, otherwise the
|
|
55
|
+
coinWithBalance intent may use all the SUI coins, leaving no coins to use for gas.
|
|
56
|
+
|
|
57
|
+
## How it works
|
|
58
|
+
|
|
59
|
+
When the `CoinWithBalance` intent is resolved, it will look up the senders owned coins for each type
|
|
60
|
+
that needs to be created. It will then find a set of coins with sufficient balance to cover the
|
|
61
|
+
desired balance, to combine them into a single coin. This coin is then used in a `SplitCoins`
|
|
62
|
+
command to create the desired coin.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Building Offline
|
|
2
|
+
|
|
3
|
+
> Build transactions without a network connection
|
|
4
|
+
|
|
5
|
+
To build a transaction offline (with no `client` required), you need to fully define all of your
|
|
6
|
+
inputs, gas configuration, and expiration.
|
|
7
|
+
|
|
8
|
+
## Required Configuration
|
|
9
|
+
|
|
10
|
+
When building offline, you must set the following:
|
|
11
|
+
|
|
12
|
+
- **Sender address** - The address that will execute the transaction
|
|
13
|
+
- **Gas price** - The price per gas unit (can be obtained from the network beforehand)
|
|
14
|
+
- **Gas budget** - The maximum gas to spend on this transaction
|
|
15
|
+
- **Gas payment** - One or more coin object references to use for gas, or an empty array for Address
|
|
16
|
+
Balances
|
|
17
|
+
- **Expiration** - Only needed when using address balances for gas
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
|
|
21
|
+
const { referenceGasPrice } = await client.getReferenceGasPrice();
|
|
22
|
+
|
|
23
|
+
const tx = new Transaction();
|
|
24
|
+
|
|
25
|
+
tx.setSender('0x<your-address>');
|
|
26
|
+
tx.setGasPrice(referenceGasPrice);
|
|
27
|
+
tx.setGasBudget(50_000_000);
|
|
28
|
+
tx.setGasPayment([
|
|
29
|
+
{
|
|
30
|
+
objectId: '0x<gas-coin-object-id>',
|
|
31
|
+
version: '<object-version>',
|
|
32
|
+
digest: '<object-digest>',
|
|
33
|
+
},
|
|
34
|
+
]);
|
|
35
|
+
|
|
36
|
+
// Build the transaction without a client
|
|
37
|
+
const bytes = await tx.build();
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Object References
|
|
41
|
+
|
|
42
|
+
For objects used in your transaction, you must provide full object references using the `Inputs`
|
|
43
|
+
helper:
|
|
44
|
+
|
|
45
|
+
```tsx
|
|
46
|
+
|
|
47
|
+
// For owned or immutable objects
|
|
48
|
+
tx.object(
|
|
49
|
+
Inputs.ObjectRef({
|
|
50
|
+
objectId: '0x<object-id>',
|
|
51
|
+
version: '<object-version>',
|
|
52
|
+
digest: '<object-digest>',
|
|
53
|
+
}),
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
// For shared objects
|
|
57
|
+
tx.object(
|
|
58
|
+
Inputs.SharedObjectRef({
|
|
59
|
+
objectId: '0x<object-id>',
|
|
60
|
+
initialSharedVersion: '<initial-shared-version>',
|
|
61
|
+
mutable: true,
|
|
62
|
+
}),
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
// For receiving objects (objects being received by another object)
|
|
66
|
+
tx.object(
|
|
67
|
+
Inputs.ReceivingRef({
|
|
68
|
+
objectId: '0x<object-id>',
|
|
69
|
+
version: '<object-version>',
|
|
70
|
+
digest: '<object-digest>',
|
|
71
|
+
}),
|
|
72
|
+
);
|
|
73
|
+
```
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Sponsored Transactions
|
|
2
|
+
|
|
3
|
+
> Pay gas fees on behalf of other users with sponsored transactions
|
|
4
|
+
|
|
5
|
+
The transaction builder can support sponsored transactions by using the `onlyTransactionKind` flag
|
|
6
|
+
when building the transaction.
|
|
7
|
+
|
|
8
|
+
```tsx
|
|
9
|
+
const tx = new Transaction();
|
|
10
|
+
|
|
11
|
+
// ... add some transactions...
|
|
12
|
+
|
|
13
|
+
const kindBytes = await tx.build({ provider, onlyTransactionKind: true });
|
|
14
|
+
|
|
15
|
+
// construct a sponsored transaction from the kind bytes
|
|
16
|
+
const sponsoredtx = Transaction.fromKind(kindBytes);
|
|
17
|
+
|
|
18
|
+
// you can now set the sponsored transaction data that is required
|
|
19
|
+
sponsoredtx.setSender(sender);
|
|
20
|
+
sponsoredtx.setGasOwner(sponsor);
|
|
21
|
+
sponsoredtx.setGasPayment(sponsorCoins);
|
|
22
|
+
```
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Derived Objects
|
|
2
|
+
|
|
3
|
+
> Compute derived object IDs from parent objects
|
|
4
|
+
|
|
5
|
+
Derived objects enable deterministic IDs for objects, enabling offline derivation of object IDs.
|
|
6
|
+
[Click here to read more.](https://docs.sui.io/concepts/sui-move-concepts/derived-objects)
|
|
7
|
+
|
|
8
|
+
To derive an object ID, you can import `deriveObjectID` function exposed from utils.
|
|
9
|
+
|
|
10
|
+
```typescript
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
To derive any object, you need to have its parent's ID (the object from which it was derived), and
|
|
15
|
+
the key used to generate it.
|
|
16
|
+
|
|
17
|
+
> **Warning:** It is recommended to verify the on-chain `derived_object::derive_address` match your off-chain
|
|
18
|
+
> calculation (at least once when implementing offline calculations), especially for critical cases
|
|
19
|
+
> like transferring assets.
|
|
20
|
+
|
|
21
|
+
## Deriving using primitive keys
|
|
22
|
+
|
|
23
|
+
To derive the IDs using primitive types, you can use the built-in types like this, assuming you have
|
|
24
|
+
a parent object with ID `0xc0ffee`.
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
// Example 1: On-chain derivation for `0xc0ffee + vector<u8>([0,1,2])
|
|
28
|
+
deriveObjectID('0xc0ffee', 'vector<u8>', bcs.vector(bcs.u8()).serialize([0, 1, 2]).toBytes());
|
|
29
|
+
|
|
30
|
+
// Example 2: On-chain derivation for `0xc0ffee + address('0x111')`
|
|
31
|
+
deriveObjectID('0xc0ffee', 'address', bcs.Address.serialize('0x111').toBytes());
|
|
32
|
+
|
|
33
|
+
// Example 3: On-chain derivation for `0xc0ffee + non-ascii string ("foo")`
|
|
34
|
+
deriveObjectID('0xc0ffee', '0x1::string::String', bcs.String.serialize('foo').toBytes());
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Deriving using custom types
|
|
38
|
+
|
|
39
|
+
To derive IDs using your custom objects, you can use BCS & the known type IDs.
|
|
40
|
+
|
|
41
|
+
Assuming a custom struct on-chain (for the key) being:
|
|
42
|
+
|
|
43
|
+
```move
|
|
44
|
+
public struct DemoStruct has copy, store, drop { value: u64 }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
you can derive it by doing:
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
// Assuming we wanted to derive for key `DemoStruct { value: 1 }`.
|
|
51
|
+
const bcsType = bcs.struct('DemoStruct', {
|
|
52
|
+
value: bcs.u64(),
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const key = bcsType.serialize({ value: 1 }).toBytes();
|
|
56
|
+
|
|
57
|
+
// Derive the object ID for the key `DemoStruct { value: 1 }`.
|
|
58
|
+
deriveObjectID('0xc0ffee', `0xc0ffee::demo::DemoStruct`, key);
|
|
59
|
+
```
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# The `@mysten/sui/utils` package
|
|
2
|
+
|
|
3
|
+
> Utility functions for addresses, coins, and common operations
|
|
4
|
+
|
|
5
|
+
This package contains some utilities that simplify common operations when working with the Sui
|
|
6
|
+
TypeScript SDK.
|
|
7
|
+
|
|
8
|
+
## Constants
|
|
9
|
+
|
|
10
|
+
A set of constants exported for common uses cases:
|
|
11
|
+
|
|
12
|
+
- `MIST_PER_SUI`: The conversion rate for MIST to SUI (1,000,000,000)
|
|
13
|
+
- `SUI_DECIMALS`: the number of decimals you must shift a MIST value to convert it to SUI (`9`)
|
|
14
|
+
- `SUI_ADDRESS_LENGTH`: The number of bytes in a Sui address (32)
|
|
15
|
+
- `MOVE_STDLIB_ADDRESS`: The address for the Sui Move standard library
|
|
16
|
+
- `SUI_FRAMEWORK_ADDRESS`: The address for the Sui Framework
|
|
17
|
+
- `SUI_SYSTEM_ADDRESS`: The address for the Sui System module
|
|
18
|
+
- `SUI_CLOCK_OBJECT_ID`: The address for the `sui::clock::Clock` object
|
|
19
|
+
- `SUI_SYSTEM_STATE_OBJECT_ID`: The address for the `SuiSystemState` object
|
|
20
|
+
- `SUI_RANDOM_OBJECT_ID`: The address for the `0x2::random::Random` object
|
|
21
|
+
|
|
22
|
+
## Formatters
|
|
23
|
+
|
|
24
|
+
You can use the following helpers to format various values:
|
|
25
|
+
|
|
26
|
+
- `formatAddress`
|
|
27
|
+
- `formatDigest`
|
|
28
|
+
- `normalizeStructTag`
|
|
29
|
+
- `normalizeSuiAddress`
|
|
30
|
+
- `normalizeSuiObjectId`
|
|
31
|
+
- `normalizeSuiNSName`
|
|
32
|
+
- `normalizeSuiNSName`
|
|
33
|
+
|
|
34
|
+
## Validators
|
|
35
|
+
|
|
36
|
+
You can use the following helpers to validate the format of various values (this only validates that
|
|
37
|
+
the value is in the correct format, but does not validate the value is valid for a specific use
|
|
38
|
+
case, or exists on chain).
|
|
39
|
+
|
|
40
|
+
- `isValidSuiAddress`
|
|
41
|
+
- `isValidSuiObjectId`
|
|
42
|
+
- `isValidTransactionDigest`
|
|
43
|
+
- `isValidSuiNSName`
|
|
44
|
+
|
|
45
|
+
## Encoding
|
|
46
|
+
|
|
47
|
+
The following methods are re-exported to help with converting between commonly used encodings
|
|
48
|
+
|
|
49
|
+
- `fromHex`: Deserializes a hex string to a Uint8Array
|
|
50
|
+
- `toHex`: Serializes a Uint8Array to a hex string
|
|
51
|
+
- `fromBase64`: Deserializes a base64 string to a Uint8Array
|
|
52
|
+
- `toBase64`: Serializes a Uint8Array to a base64 string
|