@mysten/sui 2.23.2 → 2.25.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.
Files changed (86) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/README.md +9 -9
  3. package/dist/bcs/bcs.d.mts +6 -6
  4. package/dist/client/core.d.mts +1 -0
  5. package/dist/client/core.d.mts.map +1 -1
  6. package/dist/client/core.mjs +4 -1
  7. package/dist/client/core.mjs.map +1 -1
  8. package/dist/client/mvr.d.mts.map +1 -1
  9. package/dist/client/mvr.mjs +1 -0
  10. package/dist/client/mvr.mjs.map +1 -1
  11. package/dist/client/types.d.mts +7 -0
  12. package/dist/client/types.d.mts.map +1 -1
  13. package/dist/cryptography/signature.d.mts +6 -6
  14. package/dist/graphql/client.d.mts +6 -1
  15. package/dist/graphql/client.d.mts.map +1 -1
  16. package/dist/graphql/client.mjs +18 -2
  17. package/dist/graphql/client.mjs.map +1 -1
  18. package/dist/graphql/core.d.mts +5 -4
  19. package/dist/graphql/core.d.mts.map +1 -1
  20. package/dist/graphql/core.mjs +60 -14
  21. package/dist/graphql/core.mjs.map +1 -1
  22. package/dist/graphql/generated/queries.d.mts.map +1 -1
  23. package/dist/graphql/generated/queries.mjs +8 -1
  24. package/dist/graphql/generated/queries.mjs.map +1 -1
  25. package/dist/graphql/generated/tada-env.d.mts +16 -0
  26. package/dist/grpc/client.d.mts +6 -1
  27. package/dist/grpc/client.d.mts.map +1 -1
  28. package/dist/grpc/client.mjs +17 -2
  29. package/dist/grpc/client.mjs.map +1 -1
  30. package/dist/grpc/core.d.mts +1 -0
  31. package/dist/grpc/core.d.mts.map +1 -1
  32. package/dist/grpc/core.mjs +20 -0
  33. package/dist/grpc/core.mjs.map +1 -1
  34. package/dist/grpc/proto/sui/rpc/v2/move_package_service.client.d.mts +4 -4
  35. package/dist/grpc/proto/sui/rpc/v2/name_service.client.d.mts +4 -4
  36. package/dist/grpc/proto/sui/rpc/v2/signature_verification_service.client.d.mts +4 -4
  37. package/dist/grpc/proto/sui/rpc/v2/state_service.client.d.mts +4 -4
  38. package/dist/grpc/proto/sui/rpc/v2/subscription_service.client.d.mts +4 -4
  39. package/dist/jsonRpc/client.d.mts.map +1 -1
  40. package/dist/jsonRpc/client.mjs +60 -15
  41. package/dist/jsonRpc/client.mjs.map +1 -1
  42. package/dist/jsonRpc/core.d.mts +6 -1
  43. package/dist/jsonRpc/core.d.mts.map +1 -1
  44. package/dist/jsonRpc/core.mjs +25 -7
  45. package/dist/jsonRpc/core.mjs.map +1 -1
  46. package/dist/version.mjs +1 -1
  47. package/dist/version.mjs.map +1 -1
  48. package/dist/zklogin/bcs.d.mts +14 -14
  49. package/docs/bcs.md +2 -2
  50. package/docs/clients/core.md +151 -690
  51. package/docs/clients/executing.md +113 -0
  52. package/docs/clients/graphql.md +91 -46
  53. package/docs/clients/grpc.md +239 -142
  54. package/docs/clients/index.md +87 -51
  55. package/docs/clients/querying.md +539 -0
  56. package/docs/executors.md +28 -13
  57. package/docs/index.md +1 -1
  58. package/docs/llms-index.md +18 -17
  59. package/docs/migrations/sui-2.0/dapp-kit.md +3 -3
  60. package/docs/migrations/sui-2.0/deepbook-v3.md +2 -2
  61. package/docs/migrations/sui-2.0/index.md +46 -25
  62. package/docs/migrations/sui-2.0/json-rpc-migration.md +462 -284
  63. package/docs/migrations/sui-2.0/kiosk.md +10 -9
  64. package/docs/migrations/sui-2.0/sdk-maintainers.md +17 -11
  65. package/docs/migrations/sui-2.0/sui.md +47 -29
  66. package/docs/migrations/sui-2.0/suins.md +2 -2
  67. package/docs/migrations/sui-2.0/walrus.md +3 -3
  68. package/docs/migrations/sui-2.0/zksend.md +9 -8
  69. package/docs/sdk-building.md +7 -5
  70. package/docs/transactions/signing-and-execution.md +8 -28
  71. package/package.json +1 -1
  72. package/src/client/core.ts +5 -0
  73. package/src/client/mvr.ts +6 -0
  74. package/src/client/types.ts +11 -0
  75. package/src/graphql/client.ts +35 -2
  76. package/src/graphql/core.ts +57 -10
  77. package/src/graphql/generated/queries.ts +14 -0
  78. package/src/graphql/generated/schema.graphql +11 -1
  79. package/src/graphql/generated/tada-env.ts +20 -0
  80. package/src/graphql/queries/nameService.graphql +6 -0
  81. package/src/grpc/client.ts +34 -2
  82. package/src/grpc/core.ts +35 -0
  83. package/src/jsonRpc/client.ts +15 -0
  84. package/src/jsonRpc/core.ts +31 -6
  85. package/src/version.ts +1 -1
  86. package/docs/clients/json-rpc.md +0 -239
@@ -1,737 +1,198 @@
1
1
  # Core API
2
2
 
3
- > Transport-agnostic Core API shared by all Sui clients.
3
+ > The transport-agnostic client contract that SDKs and libraries build against
4
4
 
5
- The Core API is the transport-agnostic interface that all Sui clients implement. It provides a
6
- consistent set of methods for interacting with the Sui blockchain, regardless of whether you're
7
- using gRPC, GraphQL, or JSON-RPC.
5
+ The Core API is the contract every Sui client implements. It exists so that libraries do not have to
6
+ care which transport their caller chose: an SDK written against the Core API works with
7
+ `SuiGrpcClient`, `SuiGraphQLClient`, and the deprecated `SuiJsonRpcClient` alike.
8
8
 
9
- ## `ClientWithCoreApi`
10
-
11
- The `ClientWithCoreApi` type represents any client that implements the Core API. Use this type when
12
- building SDKs or libraries that should work with any transport:
13
-
14
- ```typescript
15
-
16
- // Your SDK works with any client
17
- class MySDK {
18
- constructor(private client: ClientWithCoreApi) {}
19
-
20
- async doSomething() {
21
- // Use client.core for all operations
22
- return this.client.core.getObject({ objectId: '0x...' });
23
- }
24
- }
25
- ```
26
-
27
- ## Object methods
28
-
29
- Object methods accept an optional `include` parameter to control what data is returned. By default,
30
- every object comes with `objectId`, `version`, `digest`, `owner`, and `type`. The following fields
31
- are only populated when requested:
9
+ > **Note:** This page is for SDK and library authors. If you are writing application code, create a client and
10
+ > call its [top-level methods](/sui/clients/querying) directly. You do not need `client.core`.
32
11
 
33
- | Option | Type | Description |
34
- | --------------------- | --------- | ------------------------------------------------------------------------- |
35
- | `content` | `boolean` | BCS-encoded Move struct content (pass this to generated BCS type parsers) |
36
- | `previousTransaction` | `boolean` | Digest of the transaction that last mutated this object |
37
- | `json` | `boolean` | JSON representation of the object's Move struct content |
38
- | `objectBcs` | `boolean` | Full BCS-encoded object envelope (rarely needed; see [below](#objectbcs)) |
39
- | `display` | `boolean` | [Sui Display Standard](https://docs.sui.io/standards/display) metadata |
12
+ For packaging, extension, and code-generation patterns that go with this contract, see
13
+ [Building SDKs](/sui/sdk-building).
40
14
 
41
- ### `getObject`
15
+ ## `ClientWithCoreApi`
42
16
 
43
- Fetch a single object by ID.
17
+ `ClientWithCoreApi` is the type to accept in library code. It says "any Sui client", and gives you
18
+ `client.core` to work through:
44
19
 
45
20
  ```typescript
46
- const { object } = await client.core.getObject({
47
- objectId: '0x123...',
48
- include: {
49
- content: true, // Include BCS-encoded content
50
- previousTransaction: true, // Include creating transaction digest
51
- },
52
- });
53
-
54
- console.log(object.objectId);
55
- console.log(object.version);
56
- console.log(object.digest);
57
- console.log(object.type); // e.g., "0x2::coin::Coin<0x2::sui::SUI>"
58
- ```
59
-
60
- ### `getObjects`
61
21
 
62
- Fetch multiple objects in a single request.
22
+ #client: ClientWithCoreApi;
63
23
 
64
- ```typescript
65
- const { objects } = await client.core.getObjects({
66
- objectIds: ['0x123...', '0x456...'],
67
- include: { content: true },
68
- });
69
-
70
- for (const obj of objects) {
71
- if (obj instanceof Error) {
72
- console.log('Object not found:', obj.message);
73
- } else {
74
- console.log(obj.objectId, obj.type);
24
+ constructor(client: ClientWithCoreApi) {
25
+ this.#client = client;
75
26
  }
76
- }
77
- ```
78
-
79
- ### `listOwnedObjects`
80
-
81
- List objects owned by an address.
82
-
83
- ```typescript
84
- const result = await client.core.listOwnedObjects({
85
- owner: '0xabc...',
86
- filter: {
87
- StructType: '0x2::coin::Coin<0x2::sui::SUI>',
88
- },
89
- limit: 10,
90
- });
91
-
92
- for (const obj of result.objects) {
93
- console.log(obj.objectId, obj.type);
94
- }
95
-
96
- // Paginate
97
- if (result.cursor) {
98
- const nextPage = await client.core.listOwnedObjects({
99
- owner: '0xabc...',
100
- cursor: result.cursor,
101
- });
102
- }
103
- ```
104
-
105
- ### Parsing object content
106
-
107
- Use `include: { content: true }` to get the BCS-encoded Move struct bytes, then parse them with
108
- generated types (from `@mysten/codegen`) or manual BCS definitions:
109
-
110
- ```typescript
111
-
112
- const { object } = await client.core.getObject({
113
- objectId: '0x123...',
114
- include: { content: true },
115
- });
116
-
117
- const parsed = MyStruct.parse(object.content);
118
- ```
119
-
120
- ### `json` include option
121
-
122
- You can also fetch a JSON representation of the object's content with `include: { json: true }`.
123
-
124
- > **Warning:** The `json` field structure might vary between API implementations. For example, JSON-RPC returns
125
- > UID fields as nested objects (`{ "id": { "id": "0x..." } }`), while gRPC and GraphQL flatten
126
- > them (`{ "id": "0x..." }`). For consistent data across all clients, use `content` and parse BCS
127
- > directly.
128
-
129
- ### `objectBcs`
130
-
131
- The `objectBcs` option returns the full BCS-encoded object envelope, which is the struct content
132
- wrapped in metadata (type, `hasPublicTransfer`, version, owner, previous transaction, and storage
133
- rebate). Most of this metadata is already available as fields on the object response, so you
134
- typically only need `content`. If you do need `objectBcs`, parse it with `bcs.Object` from
135
- `@mysten/sui/bcs`:
136
-
137
- ```typescript
138
-
139
- const envelope = bcs.Object.parse(object.objectBcs);
140
- ```
141
-
142
- > **Error:** Do not pass `objectBcs` to a Move struct parser. It contains wrapping metadata that will cause
143
- > parsing to fail or produce incorrect results. Use `content` for parsing Move struct fields.
144
-
145
- ### `display` include option
146
-
147
- The `display` option fetches [Sui Display Standard](https://docs.sui.io/standards/display) metadata
148
- for an object. Display templates define how an object should be presented in wallets and explorers,
149
- including fields like `name`, `description`, and `image_url`.
150
-
151
- ```typescript
152
- const { object } = await client.core.getObject({
153
- objectId: '0x123...',
154
- include: { display: true },
155
- });
156
-
157
- if (object.display) {
158
- // display is null if the object's type has no Display template
159
- console.log(object.display.output?.name);
160
- console.log(object.display.output?.image_url);
161
- }
162
- ```
163
-
164
- The `display` field is `null` when the object's type has no registered Display template, and
165
- `undefined` when `display` was not requested. The `Display` type has two fields:
166
-
167
- | Field | Type | Description |
168
- | -------- | -------------------------------- | --------------------------------------------------------------- |
169
- | `output` | `Record<string, string> \| null` | Interpolated display fields (template variables resolved) |
170
- | `errors` | `Record<string, string> \| null` | Per-field errors if any template variable failed to interpolate |
171
-
172
- `display` works with `getObject`, `getObjects`, and `listOwnedObjects`.
173
-
174
- ## Coin and balance methods
175
-
176
- ### `getBalance`
177
-
178
- Get the balance of a specific coin type for an owner.
179
-
180
- ```typescript
181
- const { balance } = await client.core.getBalance({
182
- owner: '0xabc...',
183
- coinType: '0x2::sui::SUI', // Optional, defaults to SUI
184
- });
185
-
186
- console.log(balance.balance); // Total balance (coin objects + address balance)
187
- console.log(balance.coinBalance); // Balance from coin objects only
188
- console.log(balance.addressBalance); // Balance from address balance only
189
- ```
190
-
191
- ### `listBalances`
192
-
193
- List all coin balances for an owner.
194
-
195
- ```typescript
196
- const { balances } = await client.core.listBalances({
197
- owner: '0xabc...',
198
- });
199
-
200
- for (const balance of balances) {
201
- console.log(balance.coinType, balance.balance);
202
- }
203
- ```
204
-
205
- ### `listCoins`
206
-
207
- List coin objects of a specific type owned by an address.
208
-
209
- ```typescript
210
- const result = await client.core.listCoins({
211
- owner: '0xabc...',
212
- coinType: '0x2::sui::SUI',
213
- limit: 10,
214
- });
215
-
216
- for (const coin of result.objects) {
217
- console.log(coin.objectId, coin.balance);
218
- }
219
- ```
220
-
221
- ### `getCoinMetadata`
222
-
223
- Get metadata for a coin type, including its name, symbol, decimals, and description.
224
-
225
- ```typescript
226
- const { coinMetadata } = await client.core.getCoinMetadata({
227
- coinType: '0x2::sui::SUI',
228
- });
229
-
230
- if (coinMetadata) {
231
- console.log(coinMetadata.name, coinMetadata.symbol, coinMetadata.decimals);
232
- // "Sui" "SUI" 9
233
- }
234
- ```
235
-
236
- ## Dynamic field methods
237
-
238
- ### `listDynamicFields`
239
-
240
- List dynamic fields on an object.
241
-
242
- ```typescript
243
- const result = await client.core.listDynamicFields({
244
- parentId: '0x123...',
245
- limit: 10,
246
- });
247
-
248
- for (const field of result.dynamicFields) {
249
- console.log(field.name, field.type);
250
- }
251
- ```
252
-
253
- ### `getDynamicField`
254
-
255
- Get a specific dynamic field by name.
256
-
257
- ```typescript
258
-
259
- const { dynamicField } = await client.core.getDynamicField({
260
- parentId: '0x123...',
261
- name: {
262
- type: 'u64',
263
- bcs: bcs.u64().serialize(42).toBytes(),
264
- },
265
- });
266
-
267
- console.log(dynamicField.name);
268
- console.log(dynamicField.value.type);
269
- console.log(dynamicField.value.bcs); // BCS-encoded value
270
- ```
271
-
272
- ### `getDynamicObjectField`
273
-
274
- Get a dynamic object field, returning the referenced object. Supports the same
275
- [object include options](#object-methods) as `getObject`.
276
-
277
- ```typescript
278
- const { object } = await client.core.getDynamicObjectField({
279
- parentId: '0x123...',
280
- name: {
281
- type: '0x2::object::ID',
282
- bcs: bcs.Address.serialize('0x456...').toBytes(),
283
- },
284
- include: { content: true },
285
- });
286
- ```
287
-
288
- ## Transaction methods
289
-
290
- Transaction methods accept an optional `include` parameter to control what data is returned. By
291
- default, every transaction result includes `digest`, `signatures`, `epoch`, and `status`. The
292
- following fields are only populated when requested:
293
-
294
- | Option | Type | Description |
295
- | ---------------- | --------- | ------------------------------------------------------------------ |
296
- | `effects` | `boolean` | Parsed transaction effects (gas used, changed objects, and status) |
297
- | `events` | `boolean` | Events emitted during execution |
298
- | `transaction` | `boolean` | Parsed transaction data (sender, gas config, inputs, commands) |
299
- | `balanceChanges` | `boolean` | Balance changes caused by the transaction |
300
- | `objectTypes` | `boolean` | Map of object IDs to their types for all changed objects |
301
- | `bcs` | `boolean` | Raw BCS-encoded transaction bytes |
302
-
303
- `simulateTransaction` also supports:
304
-
305
- | Option | Type | Description |
306
- | ---------------- | --------- | ------------------------------------------------------ |
307
- | `commandResults` | `boolean` | Return values and mutated references from each command |
308
-
309
- ### `executeTransaction`
310
-
311
- Execute a signed transaction.
312
-
313
- ```typescript
314
- const result = await client.core.executeTransaction({
315
- transaction: transactionBytes,
316
- signatures: [signature],
317
- include: {
318
- effects: true,
319
- events: true,
320
- },
321
- });
322
-
323
- if (result.Transaction) {
324
- console.log('Success:', result.Transaction.digest);
325
- console.log('Effects:', result.Transaction.effects);
326
- } else {
327
- console.log('Failed:', result.FailedTransaction?.status.error);
328
- }
329
- ```
330
-
331
- ### `simulateTransaction`
332
27
 
333
- Simulate a transaction without executing it.
28
+ async getResource(objectId: string) {
29
+ const { object } = await this.#client.core.getObject({
30
+ objectId,
31
+ include: { content: true },
32
+ });
334
33
 
335
- ```typescript
336
- const result = await client.core.simulateTransaction({
337
- transaction: transactionBytes,
338
- include: {
339
- effects: true,
340
- balanceChanges: true,
341
- commandResults: true, // simulation-only option
342
- },
343
- });
344
-
345
- // Check simulated effects before signing
346
- console.log(result.effects);
347
- console.log(result.balanceChanges);
348
- ```
349
-
350
- #### Disabling checks
351
-
352
- By default, `simulateTransaction` runs with full transaction validation. For example when inspecting
353
- non-public or non-entry Move functions set `checksEnabled: false`:
354
-
355
- ```typescript
356
- const result = await client.core.simulateTransaction({
357
- transaction: transactionBytes,
358
- checksEnabled: false,
359
- include: {
360
- commandResults: true,
361
- },
362
- });
363
- ```
364
-
365
- ### `signAndExecuteTransaction`
366
-
367
- Sign and execute a transaction in one step.
368
-
369
- ```typescript
370
-
371
- const tx = new Transaction();
372
- tx.transferObjects([tx.object('0x123...')], '0xrecipient...');
373
-
374
- const result = await client.core.signAndExecuteTransaction({
375
- transaction: tx,
376
- signer: keypair,
377
- include: { effects: true },
378
- });
379
-
380
- // Always check the result
381
- if (result.FailedTransaction) {
382
- throw new Error(`Failed: ${result.FailedTransaction.status.error}`);
34
+ return object;
35
+ }
383
36
  }
384
-
385
- console.log('Digest:', result.Transaction.digest);
386
37
  ```
387
38
 
388
- ### `getTransaction`
39
+ Take the client as a parameter rather than constructing one: the caller has already configured a
40
+ network, endpoint, and transport, and a second client would bypass all of it along with the request
41
+ cache the caller's client holds.
389
42
 
390
- Fetch a transaction by digest.
43
+ ### Why go through `client.core`
391
44
 
392
- ```typescript
393
- const result = await client.core.getTransaction({
394
- digest: 'ABC123...',
395
- include: {
396
- effects: true,
397
- events: true,
398
- transaction: true,
399
- },
400
- });
401
-
402
- console.log(result.Transaction?.digest);
403
- console.log(result.Transaction?.effects);
404
- console.log(result.Transaction?.transaction?.sender);
405
- ```
45
+ Top-level methods on `SuiGrpcClient` and `SuiGraphQLClient` are a superset of the Core API: each
46
+ transport can add fields where it has extra native data, such as `include: { protoJson: true }` on
47
+ gRPC. Those additions are not portable. `client.core` is the subset that every transport guarantees,
48
+ so library code that stays inside it keeps working whichever client the caller supplies.
406
49
 
407
- You can also fetch raw BCS-encoded transaction bytes:
50
+ ## The contract
408
51
 
409
- ```typescript
410
- const result = await client.core.getTransaction({
411
- digest: 'ABC123...',
412
- include: { bcs: true },
413
- });
414
-
415
- // Raw BCS bytes for the transaction
416
- console.log(result.Transaction?.bcs); // Uint8Array
417
- ```
52
+ Every client implements these methods on `client.core`. [Querying data](/sui/clients/querying)
53
+ documents them in full, with options, include flags, and response shapes.
418
54
 
419
- ### `waitForTransaction`
55
+ | Category | Methods |
56
+ | -------------- | ------------------------------------------------------------------------------------------ |
57
+ | Objects | `getObject`, `getObjects`, `listOwnedObjects` |
58
+ | Coins | `getBalance`, `listBalances`, `listCoins`, `getCoinMetadata` |
59
+ | Dynamic fields | `listDynamicFields`, `getDynamicField`, `getDynamicObjectField` |
60
+ | Transactions | `getTransaction`, `executeTransaction`, `signAndExecuteTransaction`, `waitForTransaction` |
61
+ | Simulation | `simulateTransaction` |
62
+ | History | `listTransactions`, `listEvents` |
63
+ | Move | `getMoveFunction` |
64
+ | Names | `resolveNameServiceAddress`, `defaultNameServiceName`, `mvr` |
65
+ | Network | `getReferenceGasPrice`, `getCurrentSystemState`, `getProtocolConfig`, `getChainIdentifier` |
66
+ | Verification | `verifyZkLoginSignature` |
67
+ | Building | `resolveTransactionPlugin` |
420
68
 
421
- Wait for a transaction to be available.
69
+ `SuiGrpcClient` and `SuiGraphQLClient` also expose every one of these as a top-level method, so the
70
+ choice between `client.core.getObject()` and `client.getObject()` is about portability rather than
71
+ reach. The deprecated `SuiJsonRpcClient` is the exception: it implements the contract on
72
+ `client.core`, but its own top-level methods keep their legacy JSON-RPC names and shapes.
422
73
 
423
- ```typescript
424
- const result = await client.core.waitForTransaction({
425
- digest: 'ABC123...',
426
- timeout: 60_000, // 60 seconds
427
- include: { effects: true },
428
- });
429
- ```
74
+ ## Typing library code
430
75
 
431
- You can also pass the result directly from `executeTransaction`:
76
+ `SuiClientTypes` holds every option and response type in the contract. Import it to type your own
77
+ signatures rather than re-deriving shapes:
432
78
 
433
79
  ```typescript
434
- const executeResult = await client.core.executeTransaction({ ... });
435
-
436
- const finalResult = await client.core.waitForTransaction({
437
- result: executeResult,
438
- include: { effects: true },
439
- });
440
- ```
441
-
442
- ## Query methods
443
-
444
- Query methods return pages of transactions or events. They expose the same filters, pagination, and
445
- results on every transport, and share a common set of options. A few transport-specific caveats
446
- (page-size caps, gRPC scan-limited pages, generic event types and missing event checkpoints on the
447
- deprecated JSON-RPC transport, and GraphQL's per-transaction event limit) are documented on the
448
- corresponding option and response types in `SuiClientTypes`.
449
-
450
- | Option | Type | Description |
451
- | -------- | ---------------------------------- | ----------------------------------------------------- |
452
- | `filter` | `TransactionFilter \| EventFilter` | Filter to apply (transactions and events) |
453
- | `limit` | `number` | Maximum number of items to return (defaults to 50) |
454
- | `after` | `string \| null` | Return items strictly after this cursor (ascending) |
455
- | `before` | `string \| null` | Return items strictly before this cursor (descending) |
456
- | `order` | `'ascending' \| 'descending'` | Order of results (defaults to `ascending`) |
457
80
 
458
- A filter specifies exactly one predicate. MVR names in `function` and `eventType` predicates are
459
- resolved automatically.
460
-
461
- `after` and `before` are exclusive ledger-position bounds, and each page reports the positions of
462
- its first and last items as `startCursor` and `endCursor`. You can provide at most one bound per
463
- query, and the bound implies the traversal direction (`after` reads ascending, `before` reads
464
- descending), so a feed of recent activity can page in both directions from any point:
465
-
466
- ```typescript
467
- // Fetch the most recent transactions
468
- const latest = await client.core.listTransactions({
469
- filter: { sender: '0xabc...' },
470
- order: 'descending',
471
- limit: 10,
472
- });
473
-
474
- // Load older transactions
475
- const older = await client.core.listTransactions({
476
- filter: { sender: '0xabc...' },
477
- before: latest.endCursor,
478
- limit: 10,
479
- });
480
-
481
- // Poll for transactions executed since
482
- const newer = await client.core.listTransactions({
483
- filter: { sender: '0xabc...' },
484
- after: latest.startCursor,
485
- });
486
- ```
487
-
488
- > **Note:** Richer filtering (combined predicates, additional predicates like affected addresses and objects,
489
- > and checkpoint ranges on transaction and event queries) is available through the [raw gRPC ledger
490
- > service](/sui/clients/grpc#ledger-service) and [raw GraphQL queries](/sui/clients/graphql).
491
-
492
- ### `listTransactions`
493
-
494
- Query transactions matching a filter. Results support the same `include` options as
495
- [`getTransaction`](#gettransaction).
496
-
497
- ```typescript
498
- const result = await client.core.listTransactions({
499
- filter: { function: '0x2::coin::transfer' },
500
- limit: 10,
501
- include: { effects: true },
502
- });
503
-
504
- for (const tx of result.transactions) {
505
- const transaction = tx.Transaction ?? tx.FailedTransaction;
506
- console.log(transaction.digest, tx.$kind);
81
+ // Include generics flow through, so `object.content` is typed as present here
82
+ function parseResource(object: SuiClientTypes.Object<{ content: true }>) {
83
+ return MyStruct.parse(object.content);
507
84
  }
508
85
 
509
- // Paginate
510
- if (result.hasNextPage) {
511
- const nextPage = await client.core.listTransactions({
512
- filter: { function: '0x2::coin::transfer' },
513
- after: result.endCursor,
514
- });
515
- }
516
- ```
517
-
518
- Transaction filters support one of the following predicates:
519
-
520
- | Predicate | Description |
521
- | ---------- | --------------------------------------------------------------------------- |
522
- | `sender` | Transactions sent by an address |
523
- | `function` | Transactions calling a Move function (`pkg`, `pkg::mod`, or `pkg::mod::fn`) |
524
-
525
- ### `listEvents`
526
-
527
- Query events matching a filter. Each event includes its position in the ledger (`transactionDigest`
528
- and `eventIndex`, plus `checkpoint` on transports that can provide it; `checkpoint` is `null` on
529
- JSON-RPC).
530
-
531
- ```typescript
532
- const result = await client.core.listEvents({
533
- filter: { eventType: '0x2::coin::CoinCreated' },
534
- order: 'descending',
535
- limit: 10,
536
- });
537
-
538
- for (const event of result.events) {
539
- console.log(event.eventType, event.transactionDigest, event.json);
86
+ async function fetchBalance(
87
+ client: ClientWithCoreApi,
88
+ owner: string,
89
+ ): Promise<SuiClientTypes.Balance> {
90
+ const { balance } = await client.core.getBalance({ owner });
91
+ return balance;
540
92
  }
541
93
  ```
542
94
 
543
- Event filters support one of the following predicates:
95
+ The `Include` generic is what makes optional data type-safe: a field that was not requested is typed
96
+ `undefined`, so forgetting to ask for `content` is a compile error rather than a runtime one.
544
97
 
545
- | Predicate | Description |
546
- | ------------ | --------------------------------------------------------------------------------- |
547
- | `sender` | Events from transactions sent by an address |
548
- | `emitModule` | Events emitted by a module (`pkg::mod`) |
549
- | `eventType` | Events with types defined in a module (`pkg::mod`) or a fully qualified type name |
98
+ ### Discriminated unions
550
99
 
551
- ## System methods
552
-
553
- ### `getReferenceGasPrice`
554
-
555
- Get the current reference gas price.
100
+ Polymorphic types in the contract use a `$kind` discriminant rather than optional fields. Narrow on
101
+ `$kind` and the matching property is typed for you:
556
102
 
557
103
  ```typescript
558
- const { referenceGasPrice } = await client.core.getReferenceGasPrice();
559
- console.log(referenceGasPrice); // bigint
560
- ```
561
-
562
- ### `getCurrentSystemState`
563
-
564
- Get the current system state including epoch information.
565
-
566
- ```typescript
567
- const { systemState } = await client.core.getCurrentSystemState();
568
- console.log(systemState.epoch);
569
- console.log(systemState.systemStateVersion);
570
- ```
571
-
572
- ### `getChainIdentifier`
573
-
574
- Get the chain identifier for the network.
575
-
576
- ```typescript
577
- const { chainIdentifier } = await client.core.getChainIdentifier();
578
- console.log(chainIdentifier); // e.g., "4c78adac"
579
- ```
580
-
581
- ## Move methods
582
-
583
- ### `getMoveFunction`
584
-
585
- Get information about a Move function.
586
-
587
- ```typescript
588
- const { function: fn } = await client.core.getMoveFunction({
589
- packageId: '0x2',
590
- moduleName: 'coin',
591
- name: 'value',
592
- });
593
-
594
- console.log(fn.name);
595
- console.log(fn.parameters);
596
- console.log(fn.typeParameters);
597
- ```
598
-
599
- ## Name service methods
600
-
601
- ### `defaultNameServiceName`
602
-
603
- Resolve an address to its default SuiNS name.
604
-
605
- ```typescript
606
- const { name } = await client.core.defaultNameServiceName({
607
- address: '0xabc...',
608
- });
609
-
610
- console.log(name); // e.g., "example.sui"
611
- ```
612
-
613
- ## MVR methods
614
-
615
- The client also exposes MVR (Move Registry) methods through `client.core.mvr`:
616
-
617
- ### `resolveType`
618
-
619
- Resolve a type name (including `.move` names) to a fully qualified type.
620
-
621
- ```typescript
622
- const { type } = await client.core.mvr.resolveType({
623
- type: '@mysten/sui::coin::Coin<@mysten/sui::sui::SUI>',
624
- });
625
-
626
- console.log(type); // "0x2::coin::Coin<0x2::sui::SUI>"
627
- ```
628
-
629
- ## Error handling
630
-
631
- Methods that fetch objects might return errors in the result:
632
-
633
- ```typescript
634
- const { objects } = await client.core.getObjects({
635
- objectIds: ['0x123...', '0x456...'],
636
- });
637
-
638
- for (const obj of objects) {
639
- if (obj instanceof Error) {
640
- // Object not found or other error
641
- console.error('Error:', obj.message);
642
- } else {
643
- // Successfully fetched
644
- console.log(obj.objectId);
104
+ function describeOwner(owner: SuiClientTypes.ObjectOwner) {
105
+ switch (owner.$kind) {
106
+ case 'AddressOwner':
107
+ return `owned by ${owner.AddressOwner}`;
108
+ case 'ObjectOwner':
109
+ return `owned by object ${owner.ObjectOwner}`;
110
+ case 'Shared':
111
+ return `shared since ${owner.Shared.initialSharedVersion}`;
112
+ case 'ConsensusAddressOwner':
113
+ return `consensus-owned by ${owner.ConsensusAddressOwner.owner}`;
114
+ case 'Immutable':
115
+ return 'immutable';
116
+ default:
117
+ return 'unknown';
645
118
  }
646
119
  }
647
120
  ```
648
121
 
649
- For transaction execution, always check the result type:
650
-
651
- ```typescript
652
- const result = await client.core.executeTransaction({ ... });
653
-
654
- if (result.Transaction) {
655
- // Success
656
- console.log(result.Transaction.digest);
657
- } else if (result.FailedTransaction) {
658
- // Transaction was executed but failed
659
- throw new Error(result.FailedTransaction.status.error);
660
- }
661
- ```
662
-
663
- ## `SuiClientTypes` Namespace
664
-
665
- The `SuiClientTypes` namespace contains all type definitions for the Core API. Import it when you
666
- need to type function parameters, return values, or variables:
122
+ `TransactionResult`, `SimulateTransactionResult`, `DatatypeResponse`, `ExecutionError`, and
123
+ `OpenSignatureBody` follow the same pattern.
667
124
 
668
- ```typescript
669
-
670
- // Type function parameters
671
- function processObject(obj: SuiClientTypes.Object<{ content: true }>) {
672
- console.log(obj.objectId, obj.content);
673
- }
125
+ ### Common types
674
126
 
675
- // Type return values
676
- async function fetchBalance(
127
+ | Type | Description |
128
+ | ---------------------- | ---------------------------------------------------------------------------------------- |
129
+ | `Object<Include>` | The unified object shape; `Include` controls which optional fields are present and typed |
130
+ | `Coin` | Coin object with balance |
131
+ | `Balance` | Balance summary for a coin type |
132
+ | `CoinMetadata` | Metadata for a coin type |
133
+ | `Transaction<Include>` | An executed transaction; `Include` controls which optional fields are present |
134
+ | `TransactionResult` | Success or failure result from execution |
135
+ | `TransactionEffects` | Detailed effects from transaction execution |
136
+ | `Event` | Emitted event from a transaction |
137
+ | `EventEntry` | Queried event with its ledger position |
138
+ | `TransactionFilter` | Filter for transaction queries |
139
+ | `EventFilter` | Filter for event queries |
140
+ | `ObjectOwner` | Union of all owner types |
141
+ | `ExecutionStatus` | Success/failure status with error details |
142
+ | `DynamicFieldName` | Name identifier for dynamic fields |
143
+ | `FunctionResponse` | Move function metadata |
144
+ | `Network` | Network identifier type |
145
+
146
+ Option types follow a predictable naming scheme (`GetObjectOptions`, `ListCoinsOptions`,
147
+ `SimulateTransactionOptions`, and so on), along with the include shapes `ObjectInclude`,
148
+ `TransactionInclude`, and `SimulateTransactionInclude`.
149
+
150
+ ## Cross-transport differences
151
+
152
+ All transports produce the same shapes, but they read from different backends, and a few differences
153
+ are visible to callers. Library code that runs against any client should account for them.
154
+
155
+ | Behavior | What differs |
156
+ | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
157
+ | `include: { json: true }` | Field shapes vary between implementations. Use `content` and parse BCS when the result must be stable |
158
+ | `include: { events: true }` | GraphQL returns at most the first 50 events of a transaction; gRPC and JSON-RPC return all of them |
159
+ | JSON-RPC query gaps | `EventEntry.checkpoint` is `null`, and a bare generic `eventType` filter matches nothing where gRPC and GraphQL match any instantiation |
160
+ | Page-size caps | Over-large `limit` values are silently truncated on gRPC and rejected with an error on GraphQL and JSON-RPC |
161
+ | Short pages | gRPC bounds how much ledger a filtered query scans, so a page can be short or empty with `hasNextPage: true` |
162
+ | Read-after-write | GraphQL reads an index that trails execution. Use `waitForTransaction` before reading your own writes |
163
+
164
+ Two constraints are enforced by the client itself, so they fail the same way everywhere: a query
165
+ takes at most one of `after` or `before`, and paginating transactions filtered by `function`
166
+ requires a fully qualified `package::module::function`.
167
+
168
+ ## Client services
169
+
170
+ Beyond the methods, `ClientWithCoreApi` carries a few properties worth knowing about when writing
171
+ library code:
172
+
173
+ | Property | Purpose |
174
+ | ----------------- | ---------------------------------------------------------------------------- |
175
+ | `client.network` | The network the client was created for (`'mainnet'`, `'testnet'`, and so on) |
176
+ | `client.cache` | A shared cache; call `cache.scope('my-sdk')` for a namespace of your own |
177
+ | `client.core.mvr` | Move Registry resolution, with its own cache |
178
+
179
+ Every Core API method also accepts a `signal`, so a library method can pass its caller's
180
+ `AbortSignal` straight through:
181
+
182
+ ```typescript
183
+ async function getResource(
677
184
  client: ClientWithCoreApi,
678
- owner: string,
679
- ): Promise<SuiClientTypes.Balance> {
680
- const { balance } = await client.core.getBalance({ owner });
681
- return balance;
185
+ objectId: string,
186
+ options?: { signal?: AbortSignal },
187
+ ) {
188
+ return client.core.getObject({
189
+ objectId,
190
+ include: { content: true },
191
+ signal: options?.signal,
192
+ });
682
193
  }
683
-
684
- // Type options
685
- const options: SuiClientTypes.GetObjectOptions<{ content: true }> = {
686
- objectId: '0x123...',
687
- include: { content: true },
688
- };
689
194
  ```
690
195
 
691
- ### Common types
692
-
693
- | Type | Description |
694
- | ---------------------- | ------------------------------------------- |
695
- | `Object<Include>` | Fetched object with optional included data |
696
- | `Coin` | Coin object with balance |
697
- | `Balance` | Balance summary for a coin type |
698
- | `CoinMetadata` | Metadata for a coin type |
699
- | `Transaction<Include>` | Executed transaction with optional data |
700
- | `TransactionResult` | Success or failure result from execution |
701
- | `TransactionEffects` | Detailed effects from transaction execution |
702
- | `Event` | Emitted event from a transaction |
703
- | `EventEntry` | Queried event with its ledger position |
704
- | `TransactionFilter` | Filter for transaction queries |
705
- | `EventFilter` | Filter for event queries |
706
- | `ObjectOwner` | Union of all owner types |
707
- | `ExecutionStatus` | Success/failure status with error details |
708
- | `DynamicFieldName` | Name identifier for dynamic fields |
709
- | `FunctionResponse` | Move function metadata |
710
- | `Network` | Network identifier type |
711
-
712
- ### Include options types
713
-
714
- | Type | Description |
715
- | ---------------------------- | --------------------------------------- |
716
- | `ObjectInclude` | Options for object data inclusion |
717
- | `TransactionInclude` | Options for transaction data inclusion |
718
- | `SimulateTransactionInclude` | Extended options for simulation results |
719
-
720
- ### Method options types
721
-
722
- | Type | Description |
723
- | ---------------------------------- | --------------------------------------- |
724
- | `GetObjectOptions` | Options for `getObject` |
725
- | `GetObjectsOptions` | Options for `getObjects` |
726
- | `ListOwnedObjectsOptions` | Options for `listOwnedObjects` |
727
- | `ListCoinsOptions` | Options for `listCoins` |
728
- | `GetBalanceOptions` | Options for `getBalance` |
729
- | `ListBalancesOptions` | Options for `listBalances` |
730
- | `GetCoinMetadataOptions` | Options for `getCoinMetadata` |
731
- | `ExecuteTransactionOptions` | Options for `executeTransaction` |
732
- | `SimulateTransactionOptions` | Options for `simulateTransaction` |
733
- | `SignAndExecuteTransactionOptions` | Options for `signAndExecuteTransaction` |
734
- | `GetTransactionOptions` | Options for `getTransaction` |
735
- | `WaitForTransactionOptions` | Options for `waitForTransaction` |
736
- | `ListTransactionsOptions` | Options for `listTransactions` |
737
- | `ListEventsOptions` | Options for `listEvents` |
196
+ SDKs attach themselves to a client with `$extend`, so several SDKs can compose on one client
197
+ instance. See [Building SDKs](/sui/sdk-building) for how to author an extension, choose peer
198
+ dependencies, and structure your SDK's methods.