@mysten/sui 2.16.3 → 2.18.0
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/CHANGELOG.md +36 -0
- package/dist/bcs/bcs.d.mts +6 -6
- package/dist/bcs/index.d.mts +20 -20
- package/dist/graphql/generated/queries.d.mts.map +1 -1
- package/dist/graphql/generated/queries.mjs.map +1 -1
- package/dist/graphql/generated/tada-env.d.mts +82 -1
- package/dist/grpc/client.d.mts +2 -0
- package/dist/grpc/client.d.mts.map +1 -1
- package/dist/grpc/client.mjs +2 -0
- package/dist/grpc/client.mjs.map +1 -1
- package/dist/grpc/proto/google/protobuf/struct.mjs +1 -1
- package/dist/grpc/proto/google/protobuf/struct.mjs.map +1 -1
- package/dist/grpc/proto/google/rpc/status.mjs +1 -1
- package/dist/grpc/proto/google/rpc/status.mjs.map +1 -1
- package/dist/grpc/proto/sui/forking/v1alpha/forking_service.client.d.mts +66 -0
- package/dist/grpc/proto/sui/forking/v1alpha/forking_service.client.d.mts.map +1 -0
- package/dist/grpc/proto/sui/forking/v1alpha/forking_service.client.mjs +48 -0
- package/dist/grpc/proto/sui/forking/v1alpha/forking_service.client.mjs.map +1 -0
- package/dist/grpc/proto/sui/forking/v1alpha/forking_service.d.mts +135 -0
- package/dist/grpc/proto/sui/forking/v1alpha/forking_service.d.mts.map +1 -0
- package/dist/grpc/proto/sui/forking/v1alpha/forking_service.mjs +144 -0
- package/dist/grpc/proto/sui/forking/v1alpha/forking_service.mjs.map +1 -0
- package/dist/grpc/proto/sui/rpc/v2/checkpoint.mjs +1 -1
- package/dist/grpc/proto/sui/rpc/v2/checkpoint.mjs.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/checkpoint_contents.mjs +3 -3
- package/dist/grpc/proto/sui/rpc/v2/checkpoint_contents.mjs.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/checkpoint_summary.mjs +3 -3
- package/dist/grpc/proto/sui/rpc/v2/checkpoint_summary.mjs.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/effects.d.mts +71 -3
- package/dist/grpc/proto/sui/rpc/v2/effects.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/effects.mjs +71 -5
- package/dist/grpc/proto/sui/rpc/v2/effects.mjs.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/event.mjs +1 -1
- package/dist/grpc/proto/sui/rpc/v2/event.mjs.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/executed_transaction.mjs +2 -2
- package/dist/grpc/proto/sui/rpc/v2/executed_transaction.mjs.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/ledger_service.client.d.mts +4 -4
- package/dist/grpc/proto/sui/rpc/v2/ledger_service.mjs +3 -3
- package/dist/grpc/proto/sui/rpc/v2/ledger_service.mjs.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/move_package.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/move_package.mjs +13 -13
- package/dist/grpc/proto/sui/rpc/v2/move_package.mjs.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/move_package_service.client.d.mts +4 -4
- package/dist/grpc/proto/sui/rpc/v2/move_package_service.mjs +1 -1
- package/dist/grpc/proto/sui/rpc/v2/move_package_service.mjs.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/name_service.client.d.mts +4 -4
- package/dist/grpc/proto/sui/rpc/v2/object.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/object.mjs +1 -1
- package/dist/grpc/proto/sui/rpc/v2/object.mjs.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/signature.mjs +3 -3
- package/dist/grpc/proto/sui/rpc/v2/signature.mjs.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/signature_verification_service.client.d.mts +4 -4
- package/dist/grpc/proto/sui/rpc/v2/signature_verification_service.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/signature_verification_service.mjs +1 -1
- package/dist/grpc/proto/sui/rpc/v2/signature_verification_service.mjs.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/state_service.client.d.mts +4 -4
- package/dist/grpc/proto/sui/rpc/v2/state_service.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/state_service.mjs +3 -3
- package/dist/grpc/proto/sui/rpc/v2/state_service.mjs.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/subscription_service.client.d.mts +4 -4
- package/dist/grpc/proto/sui/rpc/v2/system_state.mjs +2 -2
- package/dist/grpc/proto/sui/rpc/v2/system_state.mjs.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/transaction.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/transaction.mjs +16 -16
- package/dist/grpc/proto/sui/rpc/v2/transaction.mjs.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/transaction_execution_service.mjs +4 -4
- package/dist/grpc/proto/sui/rpc/v2/transaction_execution_service.mjs.map +1 -1
- package/dist/grpc/proto/types.d.mts +3 -2
- package/dist/grpc/proto/types.mjs +11 -1
- package/dist/grpc/proto/types.mjs.map +1 -1
- package/dist/jsonRpc/types/params.d.mts +5 -5
- package/dist/transactions/Transaction.d.mts +25 -11
- package/dist/transactions/Transaction.d.mts.map +1 -1
- package/dist/transactions/Transaction.mjs +8 -3
- package/dist/transactions/Transaction.mjs.map +1 -1
- package/dist/transactions/index.d.mts +2 -2
- package/dist/version.mjs +1 -1
- package/dist/version.mjs.map +1 -1
- package/dist/zklogin/jwt-utils.d.mts.map +1 -1
- package/dist/zklogin/jwt-utils.mjs.map +1 -1
- package/dist/zklogin/utils.d.mts.map +1 -1
- package/dist/zklogin/utils.mjs +9 -0
- package/dist/zklogin/utils.mjs.map +1 -1
- package/docs/bcs.md +11 -6
- package/docs/clients/core.md +10 -9
- package/docs/clients/grpc.md +1 -1
- package/docs/index.md +176 -22
- package/docs/llms-index.md +6 -9
- package/docs/migrations/0.38.md +2 -2
- package/docs/migrations/sui-1.0.md +2 -2
- package/docs/migrations/sui-2.0/json-rpc-migration.md +76 -33
- package/docs/plugins.md +29 -5
- package/docs/transactions/basics.md +279 -0
- package/docs/transactions/coins-and-balances.md +293 -0
- package/docs/transactions/offline.md +192 -0
- package/docs/transactions/reference.md +380 -0
- package/docs/transactions/signing-and-execution.md +401 -0
- package/package.json +27 -27
- package/src/graphql/generated/queries.ts +46 -1
- package/src/graphql/generated/schema.graphql +49 -3
- package/src/graphql/generated/tada-env.ts +97 -1
- package/src/grpc/client.ts +3 -0
- package/src/grpc/proto/google/protobuf/struct.ts +1 -1
- package/src/grpc/proto/google/rpc/error_details.ts +4 -4
- package/src/grpc/proto/google/rpc/status.ts +1 -1
- package/src/grpc/proto/sui/forking/v1alpha/forking_service.client.ts +125 -0
- package/src/grpc/proto/sui/forking/v1alpha/forking_service.ts +230 -0
- package/src/grpc/proto/sui/rpc/v2/checkpoint.ts +1 -1
- package/src/grpc/proto/sui/rpc/v2/checkpoint_contents.ts +3 -3
- package/src/grpc/proto/sui/rpc/v2/checkpoint_summary.ts +3 -3
- package/src/grpc/proto/sui/rpc/v2/effects.ts +112 -6
- package/src/grpc/proto/sui/rpc/v2/event.ts +1 -1
- package/src/grpc/proto/sui/rpc/v2/executed_transaction.ts +2 -2
- package/src/grpc/proto/sui/rpc/v2/ledger_service.ts +3 -3
- package/src/grpc/proto/sui/rpc/v2/move_package.ts +19 -13
- package/src/grpc/proto/sui/rpc/v2/move_package_service.ts +1 -1
- package/src/grpc/proto/sui/rpc/v2/object.ts +7 -1
- package/src/grpc/proto/sui/rpc/v2/signature.ts +3 -3
- package/src/grpc/proto/sui/rpc/v2/signature_verification_service.ts +7 -1
- package/src/grpc/proto/sui/rpc/v2/state_service.ts +9 -3
- package/src/grpc/proto/sui/rpc/v2/system_state.ts +2 -2
- package/src/grpc/proto/sui/rpc/v2/transaction.ts +22 -16
- package/src/grpc/proto/sui/rpc/v2/transaction_execution_service.ts +4 -4
- package/src/grpc/proto/types.ts +1 -0
- package/src/jsonRpc/types/params.ts +5 -5
- package/src/transactions/Transaction.ts +36 -5
- package/src/transactions/index.ts +1 -0
- package/src/version.ts +1 -1
- package/src/zklogin/jwt-utils.ts +3 -0
- package/src/zklogin/utils.ts +17 -0
- package/docs/faucet.md +0 -26
- package/docs/hello-sui.md +0 -115
- package/docs/install.md +0 -61
- package/docs/transaction-building/basics.md +0 -299
- package/docs/transaction-building/gas.md +0 -61
- package/docs/transaction-building/intents.md +0 -62
- package/docs/transaction-building/offline.md +0 -73
- package/docs/transaction-building/sponsored-transactions.md +0 -22
|
@@ -135,8 +135,8 @@ export interface GetObjectParams {
|
|
|
135
135
|
signal?: AbortSignal;
|
|
136
136
|
}
|
|
137
137
|
/**
|
|
138
|
-
* Return the protocol config table for the given version number. If
|
|
139
|
-
*
|
|
138
|
+
* Return the protocol config table for the given version number. If none is specified, the node uses
|
|
139
|
+
* the version of the latest epoch it has processed.
|
|
140
140
|
*/
|
|
141
141
|
export interface GetProtocolConfigParams {
|
|
142
142
|
/**
|
|
@@ -520,7 +520,7 @@ export interface UnsafePayAllSuiParams {
|
|
|
520
520
|
* input_coin to create new coin following the order of amounts and assign it to the corresponding
|
|
521
521
|
* recipient. 2. accumulate all residual SUI from input coins left and deposit all SUI to the first
|
|
522
522
|
* input coin, then use the first input coin as the gas coin object. 3. the balance of the first input
|
|
523
|
-
* coin after tx is sum(input_coins) - sum(amounts) - actual_gas_cost 4. all other input
|
|
523
|
+
* coin after tx is sum(input_coins) - sum(amounts) - actual_gas_cost 4. all other input coins other
|
|
524
524
|
* than the first one are deleted.
|
|
525
525
|
*/
|
|
526
526
|
export interface UnsafePaySuiParams {
|
|
@@ -591,7 +591,7 @@ export interface UnsafeRequestWithdrawStakeParams {
|
|
|
591
591
|
export interface UnsafeSplitCoinParams {
|
|
592
592
|
/** the transaction signer's Sui address */
|
|
593
593
|
signer: string;
|
|
594
|
-
/** the coin object to be
|
|
594
|
+
/** the coin object to be split */
|
|
595
595
|
coinObjectId: string;
|
|
596
596
|
/** the amounts to split out from the coin */
|
|
597
597
|
splitAmounts: string[];
|
|
@@ -608,7 +608,7 @@ export interface UnsafeSplitCoinParams {
|
|
|
608
608
|
export interface UnsafeSplitCoinEqualParams {
|
|
609
609
|
/** the transaction signer's Sui address */
|
|
610
610
|
signer: string;
|
|
611
|
-
/** the coin object to be
|
|
611
|
+
/** the coin object to be split */
|
|
612
612
|
coinObjectId: string;
|
|
613
613
|
/** the number of coins to split into */
|
|
614
614
|
splitCount: string;
|
|
@@ -139,6 +139,17 @@ type TransactionLike = {
|
|
|
139
139
|
getData(): unknown;
|
|
140
140
|
};
|
|
141
141
|
|
|
142
|
+
export interface TransactionCopyOptions {
|
|
143
|
+
/**
|
|
144
|
+
* A map of intent names to resolvers for any custom intents used in the transaction being copied.
|
|
145
|
+
*
|
|
146
|
+
* Built-in intents (such as `CoinWithBalance`) are handled automatically. Providing resolvers for
|
|
147
|
+
* custom intents lets `Transaction.from` copy a transaction synchronously even when it still
|
|
148
|
+
* contains unresolved intents, without first awaiting `prepareForSerialization`.
|
|
149
|
+
*/
|
|
150
|
+
intentResolvers?: Record<string, TransactionPlugin>;
|
|
151
|
+
}
|
|
152
|
+
|
|
142
153
|
/**
|
|
143
154
|
* Transaction Builder
|
|
144
155
|
*/
|
|
@@ -175,8 +186,15 @@ export class Transaction {
|
|
|
175
186
|
* There are two supported serialized formats:
|
|
176
187
|
* - A string returned from `Transaction#serialize`. The serialized format must be compatible, or it will throw an error.
|
|
177
188
|
* - A byte array (or base64-encoded bytes) containing BCS transaction data.
|
|
189
|
+
*
|
|
190
|
+
* When copying an in-memory transaction that uses custom intents, pass resolvers for those intents
|
|
191
|
+
* via `options.intentResolvers` so the copy can be created synchronously without first awaiting
|
|
192
|
+
* `prepareForSerialization`. Built-in intents (such as `CoinWithBalance`) are handled automatically.
|
|
178
193
|
*/
|
|
179
|
-
static from(
|
|
194
|
+
static from(
|
|
195
|
+
transaction: string | Uint8Array | TransactionLike,
|
|
196
|
+
options: TransactionCopyOptions = {},
|
|
197
|
+
) {
|
|
180
198
|
const newTransaction = new Transaction();
|
|
181
199
|
|
|
182
200
|
if (isTransaction(transaction)) {
|
|
@@ -195,14 +213,27 @@ export class Transaction {
|
|
|
195
213
|
newTransaction.#commandSection = newTransaction.#data.commands.slice();
|
|
196
214
|
newTransaction.#availableResults = new Set(newTransaction.#commandSection.map((_, i) => i));
|
|
197
215
|
|
|
198
|
-
|
|
216
|
+
// Built-in intents are resolvable by default. Caller-supplied resolvers cover custom intents,
|
|
217
|
+
// and take precedence so a built-in resolver can be overridden if needed.
|
|
218
|
+
const intentResolvers = new Map<string, TransactionPlugin>([
|
|
219
|
+
[COIN_WITH_BALANCE, resolveCoinBalance],
|
|
220
|
+
...Object.entries(options.intentResolvers ?? {}),
|
|
221
|
+
]);
|
|
222
|
+
|
|
223
|
+
if (
|
|
224
|
+
!newTransaction.isPreparedForSerialization({
|
|
225
|
+
supportedIntents: [...intentResolvers.keys()],
|
|
226
|
+
})
|
|
227
|
+
) {
|
|
199
228
|
throw new Error(
|
|
200
|
-
'Transaction has unresolved intents or async thunks.
|
|
229
|
+
'Transaction has unresolved intents or async thunks. Provide resolvers for any custom intents via the `intentResolvers` option, or call `prepareForSerialization` before copying.',
|
|
201
230
|
);
|
|
202
231
|
}
|
|
203
232
|
|
|
204
|
-
|
|
205
|
-
|
|
233
|
+
// Register every resolver so the copy can resolve its intents on build. Resolvers for intents
|
|
234
|
+
// that aren't present are harmless — a resolver only runs when its intent appears in the data.
|
|
235
|
+
for (const [intent, resolver] of intentResolvers) {
|
|
236
|
+
newTransaction.addIntentResolver(intent, resolver);
|
|
206
237
|
}
|
|
207
238
|
|
|
208
239
|
return newTransaction;
|
package/src/version.ts
CHANGED
package/src/zklogin/jwt-utils.ts
CHANGED
|
@@ -116,6 +116,9 @@ export function extractClaimValue<R>(claim: Claim, claimName: string): R {
|
|
|
116
116
|
return value;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
// TODO: root cause of the claim-escaping bug — jwtDecode resolves JSON escapes, but the
|
|
120
|
+
// circuit derives the address seed from raw JWT bytes, so escaped claim values decode
|
|
121
|
+
// differently here than the circuit hashes. Real fix: parse claims over raw bytes.
|
|
119
122
|
export function decodeJwt(jwt: string): Omit<JwtPayload, 'iss' | 'aud' | 'sub'> & {
|
|
120
123
|
iss: string;
|
|
121
124
|
aud: string;
|
package/src/zklogin/utils.ts
CHANGED
|
@@ -87,6 +87,20 @@ export function hashASCIIStrToField(str: string, maxSize: number) {
|
|
|
87
87
|
return poseidonHash(packed);
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
// Reject claim inputs whose decoded form reveals a JSON escape ('"', '\', control char):
|
|
91
|
+
// the circuit hashes raw JWT bytes, so an escaped value would derive a different address.
|
|
92
|
+
function assertNoJsonEscape(value: string, label: string) {
|
|
93
|
+
for (let i = 0; i < value.length; i++) {
|
|
94
|
+
const c = value.charCodeAt(i);
|
|
95
|
+
if (c < 0x20 || c === 0x22 || c === 0x5c) {
|
|
96
|
+
throw new Error(
|
|
97
|
+
`zkLogin ${label} contains a JSON-escaped character (code ${c}); the circuit ` +
|
|
98
|
+
`hashes raw JWT bytes, so claim values with escapes are not supported`,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
90
104
|
export function genAddressSeed(
|
|
91
105
|
salt: string | bigint,
|
|
92
106
|
name: string,
|
|
@@ -96,6 +110,9 @@ export function genAddressSeed(
|
|
|
96
110
|
max_value_length = MAX_KEY_CLAIM_VALUE_LENGTH,
|
|
97
111
|
max_aud_length = MAX_AUD_VALUE_LENGTH,
|
|
98
112
|
): bigint {
|
|
113
|
+
assertNoJsonEscape(name, 'key claim name');
|
|
114
|
+
assertNoJsonEscape(value, 'key claim value');
|
|
115
|
+
assertNoJsonEscape(aud, 'aud');
|
|
99
116
|
return poseidonHash([
|
|
100
117
|
hashASCIIStrToField(name, max_name_length),
|
|
101
118
|
hashASCIIStrToField(value, max_value_length),
|
package/docs/faucet.md
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# Faucet
|
|
2
|
-
|
|
3
|
-
> Request test SUI tokens from the faucet on Devnet, Testnet, or local networks.
|
|
4
|
-
|
|
5
|
-
Devnet, Testnet, and local networks include faucets that mint SUI. You can use the Sui TypeScript
|
|
6
|
-
SDK to call a network's faucet and provide SUI to the address you provide.
|
|
7
|
-
|
|
8
|
-
To request SUI from a faucet, import the `requestSuiFromFaucetV2` function from the
|
|
9
|
-
`@mysten/sui/faucet` package to your project.
|
|
10
|
-
|
|
11
|
-
```typescript
|
|
12
|
-
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
Use `requestSuiFromFaucetV2` in your TypeScript code to request SUI from the network's faucet.
|
|
16
|
-
|
|
17
|
-
```typescript
|
|
18
|
-
await requestSuiFromFaucetV2({
|
|
19
|
-
host: getFaucetHost('testnet'),
|
|
20
|
-
recipient: <RECIPIENT_ADDRESS>,
|
|
21
|
-
});
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
> **Note:** Faucets on Devnet and Testnet are rate limited. If you run the script too many times, you surpass
|
|
25
|
-
> the limit and must wait to successfully run it again. For Testnet, the best way to get SUI is
|
|
26
|
-
> through the Web UI: `faucet.sui.io`.
|
package/docs/hello-sui.md
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
# Hello Sui
|
|
2
|
-
|
|
3
|
-
> Build your first Sui application with the TypeScript SDK.
|
|
4
|
-
|
|
5
|
-
This basic example introduces you to the Sui TypeScript SDK. The Node.js example mints SUI on a Sui
|
|
6
|
-
network and then queries the address to get a sum for the owned SUI. You don't need to use an IDE to
|
|
7
|
-
complete the example, but one like Microsoft Visual Studio Code helps centralize more advanced
|
|
8
|
-
projects.
|
|
9
|
-
|
|
10
|
-
## Before you begin
|
|
11
|
-
|
|
12
|
-
You need an address on a Sui development network (Devnet, Testnet, or local). If you don't already
|
|
13
|
-
have an address, use the [Sui Client CLI](https://docs.sui.io/references/cli/client) or the
|
|
14
|
-
[Sui Wallet browser extension](https://docs.mystenlabs.com) to create one.
|
|
15
|
-
|
|
16
|
-
You also need [Node.js](https://nodejs.org/en/download/current) and a package manager like
|
|
17
|
-
[pnpm](https://pnpm.io/installation) to follow this example, so install them on your system if you
|
|
18
|
-
haven't already.
|
|
19
|
-
|
|
20
|
-
## Start a project
|
|
21
|
-
|
|
22
|
-
Using a Terminal or Console, create a folder on your system (`hello-sui` in this example) and make
|
|
23
|
-
it the working directory.
|
|
24
|
-
|
|
25
|
-
```sh
|
|
26
|
-
mkdir hello-sui
|
|
27
|
-
cd hello-sui
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
When you use a package manager to install the necessary packages, it downloads the modules to your
|
|
31
|
-
`node_modules` folder and adds the references to your `package.json` file, creating the file if it
|
|
32
|
-
doesn't already exist. For this example, you need only the Sui TypeScript SDK:
|
|
33
|
-
|
|
34
|
-
```sh npm2yarn
|
|
35
|
-
npm i -D @mysten/sui
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
The SDK is published as an ESM only package, so you also need to set `"type": "module"` in your
|
|
39
|
-
`package.json`. Your `package.json` file should look like this:
|
|
40
|
-
|
|
41
|
-
```json
|
|
42
|
-
{
|
|
43
|
-
"type": "module",
|
|
44
|
-
"dependencies": {
|
|
45
|
-
"@mysten/sui": "^<VERSION_NUMBER>"
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
## Get some SUI for your account
|
|
51
|
-
|
|
52
|
-
Instead of a 'Hello World' output to your console, this example introduces some SUI to your wallet
|
|
53
|
-
address. You must be on Devnet, Testnet, or a local network to use a faucet for minting SUI.
|
|
54
|
-
|
|
55
|
-
Create a new `index.js` file in the root of your project with the following code.
|
|
56
|
-
|
|
57
|
-
```js
|
|
58
|
-
|
|
59
|
-
// replace <YOUR_SUI_ADDRESS> with your actual address, which is in the form 0x123...
|
|
60
|
-
const MY_ADDRESS = '<YOUR_SUI_ADDRESS>';
|
|
61
|
-
|
|
62
|
-
// create a new SuiGrpcClient object pointing to the network you want to use
|
|
63
|
-
const suiClient = new SuiGrpcClient({
|
|
64
|
-
network: 'devnet',
|
|
65
|
-
baseUrl: 'https://fullnode.devnet.sui.io:443',
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
// Convert MIST to Sui
|
|
69
|
-
const balance = (balance) => {
|
|
70
|
-
return Number.parseInt(balance.totalBalance) / Number(MIST_PER_SUI);
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
// store the JSON representation for the SUI the address owns before using faucet
|
|
74
|
-
const suiBefore = await suiClient.getBalance({
|
|
75
|
-
owner: MY_ADDRESS,
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
await requestSuiFromFaucetV2({
|
|
79
|
-
// use getFaucetHost to make sure you're using correct faucet address
|
|
80
|
-
// you can also just use the address (see Sui TypeScript SDK Quick Start for values)
|
|
81
|
-
host: getFaucetHost('devnet'),
|
|
82
|
-
recipient: MY_ADDRESS,
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
// store the JSON representation for the SUI the address owns after using faucet
|
|
86
|
-
const suiAfter = await suiClient.getBalance({
|
|
87
|
-
owner: MY_ADDRESS,
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// Output result to console.
|
|
91
|
-
console.log(
|
|
92
|
-
`Balance before faucet: ${balance(suiBefore)} SUI. Balance after: ${balance(
|
|
93
|
-
suiAfter,
|
|
94
|
-
)} SUI. Hello, SUI!`,
|
|
95
|
-
);
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
Save the file, then use Node.js to run it in your Console or Terminal:
|
|
99
|
-
|
|
100
|
-
```sh
|
|
101
|
-
node index.js
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
The code imports the `requestSuiFromFaucetV2` function from the SDK and calls it to mint SUI for the
|
|
105
|
-
provided address. The code also imports `SuiGrpcClient` to create a new client on the Sui network
|
|
106
|
-
that it uses to query the address and output the amount of SUI the address owns before and after
|
|
107
|
-
using the faucet. You can check the total SUI for your address using the Sui Wallet or Sui Client
|
|
108
|
-
CLI.
|
|
109
|
-
|
|
110
|
-
> **Note:** Faucets on Devnet and Testnet are rate limited. If you run the script too many times, you surpass
|
|
111
|
-
> the limit and must wait to successfully run it again. For Testnet, the best way to get SUI is
|
|
112
|
-
> through the Web UI: `faucet.sui.io`.
|
|
113
|
-
|
|
114
|
-
You can also use the [Sui Client CLI](https://docs.sui.io/references/cli/client) to perform client
|
|
115
|
-
calls on a Sui network.
|
package/docs/install.md
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
# Install Sui TypeScript SDK
|
|
2
|
-
|
|
3
|
-
> Install the @mysten/sui package and configure your project.
|
|
4
|
-
|
|
5
|
-
The Sui TypeScript SDK is available in the
|
|
6
|
-
[Sui TS SDK monorepo](https://github.com/MystenLabs/ts-sdks) and NPM.
|
|
7
|
-
|
|
8
|
-
## Install from NPM
|
|
9
|
-
|
|
10
|
-
To use the Sui TypeScript SDK in your project, run the following command in your project root:
|
|
11
|
-
|
|
12
|
-
```sh npm2yarn
|
|
13
|
-
npm i @mysten/sui
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
The SDK is published as an ESM only package. Make sure your `package.json` includes
|
|
17
|
-
`"type": "module"`:
|
|
18
|
-
|
|
19
|
-
```json
|
|
20
|
-
{
|
|
21
|
-
"type": "module"
|
|
22
|
-
}
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
If you are using TypeScript, your `tsconfig.json` should use a compatible `moduleResolution` setting
|
|
26
|
-
such as `"NodeNext"`, `"Node16"`, or `"Bundler"`. See the
|
|
27
|
-
[2.0 migration guide](/sui/migrations/sui-2.0#esm-migration) for more details.
|
|
28
|
-
|
|
29
|
-
## Experimental tag for use with a local Sui network
|
|
30
|
-
|
|
31
|
-
Projects developing against one of the onchain Sui networks (Devnet, Testnet, Mainnet) should use
|
|
32
|
-
the base SDK published in the NPM registry (previous section) because the code aligns with the
|
|
33
|
-
relevant JSON-RPC. If you are developing against a
|
|
34
|
-
[local network](https://docs.sui.io/guides/developer/getting-started/local-network) built from the
|
|
35
|
-
`main` branch of the Sui monorepo, however, you should use the `experimental`-tagged SDK package as
|
|
36
|
-
it contains the latest features (or a local build detailed in the section that follows).
|
|
37
|
-
|
|
38
|
-
```sh npm2yarn
|
|
39
|
-
npm i @mysten/sui@experimental
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Install from local build
|
|
43
|
-
|
|
44
|
-
To build the SDK from the Sui monorepo, you must use [pnpm](https://pnpm.io/). With pnpm installed,
|
|
45
|
-
run the following command from the `sui` root directory:
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
# Install all dependencies
|
|
49
|
-
pnpm install
|
|
50
|
-
# Run the build for the TypeScript SDK
|
|
51
|
-
pnpm sdk build
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
With the SDK built, you can import the library from your `sui` project. To do so, use a path to the
|
|
55
|
-
`ts-sdks/packages/sui` directory that is relative to your project. For example, if you created a
|
|
56
|
-
folder `my-sui-project` at the same level as `sui`, use the following to import the locally built
|
|
57
|
-
Sui TypeScript package:
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
pnpm add ../ts-sdks/packages/sui
|
|
61
|
-
```
|
|
@@ -1,299 +0,0 @@
|
|
|
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
|
-
might 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 might 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`, for example
|
|
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
|
-
You might need to explicitly call `setSender()` on the transaction to ensure that the `sender` field
|
|
281
|
-
is populated. This is normally done by the signer before signing the transaction, but will not be
|
|
282
|
-
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
|
-
```
|