@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
@@ -0,0 +1,539 @@
1
+ # Querying Data
2
+
3
+ > Read objects, coins, balances, dynamic fields, and history with any Sui client
4
+
5
+ Every Sui client reads data through the same set of methods. `SuiGrpcClient` and `SuiGraphQLClient`
6
+ expose them as top-level methods, and every client also exposes them on `client.core`, so the
7
+ examples on this page work unchanged whichever client you created.
8
+
9
+ ```typescript
10
+
11
+ const client = new SuiGrpcClient({
12
+ network: 'mainnet',
13
+ baseUrl: 'https://fullnode.mainnet.sui.io:443',
14
+ });
15
+
16
+ const { object } = await client.getObject({
17
+ objectId: '0x123...',
18
+ include: { content: true },
19
+ });
20
+ ```
21
+
22
+ Application code should call the top-level method, as above. Libraries that accept any client should
23
+ call `client.core.getObject(...)` instead. See the [Core API](/sui/clients/core) for that contract.
24
+
25
+ ## Objects
26
+
27
+ ### `getObject`
28
+
29
+ Fetch a single object by ID. Throws if the object does not exist or cannot be read.
30
+
31
+ ```typescript
32
+ const { object } = await client.getObject({
33
+ objectId: '0x123...',
34
+ include: {
35
+ content: true,
36
+ previousTransaction: true,
37
+ },
38
+ });
39
+
40
+ console.log(object.objectId);
41
+ console.log(object.version);
42
+ console.log(object.digest);
43
+ console.log(object.type); // e.g., "0x2::coin::Coin<0x2::sui::SUI>"
44
+ console.log(object.owner.$kind); // "AddressOwner" | "ObjectOwner" | "Shared" | ...
45
+ ```
46
+
47
+ ### `getObjects`
48
+
49
+ Fetch multiple objects in a single request. Unlike `getObject`, per-object failures are returned in
50
+ place rather than thrown, so one missing object does not fail the batch.
51
+
52
+ ```typescript
53
+ const { objects } = await client.getObjects({
54
+ objectIds: ['0x123...', '0x456...'],
55
+ include: { content: true },
56
+ });
57
+
58
+ for (const object of objects) {
59
+ if (object instanceof Error) {
60
+ console.log('Could not read object:', object.message);
61
+ } else {
62
+ console.log(object.objectId, object.type);
63
+ }
64
+ }
65
+ ```
66
+
67
+ ### `listOwnedObjects`
68
+
69
+ List objects owned by an address, optionally filtered by type. The filter can be as broad or as
70
+ narrow as you need: a package, a module, a type name, or a full instantiation. `0x2::coin::Coin`
71
+ matches every `Coin<T>`, while `0x2::coin::Coin<0x2::sui::SUI>` matches only SUI coins. The `type`
72
+ accepts [MVR](#move-registry-names) names as well as fully qualified types.
73
+
74
+ ```typescript
75
+ const page = await client.listOwnedObjects({
76
+ owner: '0xabc...',
77
+ type: '0x2::coin::Coin<0x2::sui::SUI>',
78
+ limit: 10,
79
+ });
80
+
81
+ for (const object of page.objects) {
82
+ console.log(object.objectId, object.type);
83
+ }
84
+ ```
85
+
86
+ See [Pagination](#pagination) for reading the next page.
87
+
88
+ ## Include options
89
+
90
+ Object methods accept an `include` parameter that controls what extra data is fetched. Every object
91
+ always comes back with `objectId`, `version`, `digest`, `owner`, and `type`. Anything else must be
92
+ requested, and is typed as `undefined` when it was not:
93
+
94
+ | Option | Type | Description |
95
+ | --------------------- | --------- | ------------------------------------------------------------------------- |
96
+ | `content` | `boolean` | BCS-encoded Move struct content (pass this to generated BCS type parsers) |
97
+ | `previousTransaction` | `boolean` | Digest of the transaction that last mutated this object |
98
+ | `json` | `boolean` | JSON representation of the object's Move struct content |
99
+ | `objectBcs` | `boolean` | Full BCS-encoded object envelope (rarely needed; see [below](#objectbcs)) |
100
+ | `display` | `boolean` | [Sui Display Standard](https://docs.sui.io/standards/display) metadata |
101
+
102
+ These options work with `getObject`, `getObjects`, `listOwnedObjects`, and `getDynamicObjectField`.
103
+
104
+ ### `content`
105
+
106
+ `include: { content: true }` returns the BCS-encoded Move struct bytes. Parse them with generated
107
+ types (from [@mysten/codegen](/codegen)) or with manual BCS definitions:
108
+
109
+ ```typescript
110
+
111
+ const { object } = await client.getObject({
112
+ objectId: '0x123...',
113
+ include: { content: true },
114
+ });
115
+
116
+ const parsed = MyStruct.parse(object.content);
117
+ ```
118
+
119
+ ### `json`
120
+
121
+ `include: { json: true }` returns a JSON representation of the object's content, or `null` if the
122
+ object has none.
123
+
124
+ > **Warning:** The shape of the `json` field varies between API implementations, and field names and nesting are
125
+ > not guaranteed to match across clients. When the result has to be stable, use `content` and parse
126
+ > the BCS directly.
127
+
128
+ ### `objectBcs`
129
+
130
+ The `objectBcs` option returns the full BCS-encoded object envelope: the struct content wrapped in
131
+ metadata (type, `hasPublicTransfer`, version, owner, previous transaction, and storage rebate). Most
132
+ of that metadata is already available as fields on the object response, so `content` is almost
133
+ always what you want. If you do need the envelope, parse it with `bcs.Object` from
134
+ `@mysten/sui/bcs`:
135
+
136
+ ```typescript
137
+
138
+ const envelope = bcs.Object.parse(object.objectBcs);
139
+ ```
140
+
141
+ > **Error:** Do not pass `objectBcs` to a Move struct parser. It contains wrapping metadata that causes parsing
142
+ > to fail or produce incorrect results. Use `content` for parsing Move struct fields.
143
+
144
+ ### `display`
145
+
146
+ The `display` option fetches [Sui Display Standard](https://docs.sui.io/standards/display) metadata,
147
+ which defines how wallets and explorers should present an object.
148
+
149
+ ```typescript
150
+ const { object } = await client.getObject({
151
+ objectId: '0x123...',
152
+ include: { display: true },
153
+ });
154
+
155
+ if (object.display) {
156
+ // display is null if the object's type has no Display template
157
+ console.log(object.display.output?.name);
158
+ console.log(object.display.output?.image_url);
159
+ }
160
+ ```
161
+
162
+ The field is `null` when the object's type has no registered Display template, and `undefined` when
163
+ `display` was not requested. `Display` has two fields:
164
+
165
+ | Field | Type | Description |
166
+ | -------- | --------------------------------- | --------------------------------------------------------------- |
167
+ | `output` | `Record<string, unknown> \| null` | Rendered display fields, keyed by field name |
168
+ | `errors` | `Record<string, string> \| null` | Per-field errors if any template variable failed to interpolate |
169
+
170
+ Most rendered values are strings, but Display v2 templates can produce structured JSON values for
171
+ fields that use the `:json` transform or reference non-string Move types, so `output` values are
172
+ typed as `unknown`.
173
+
174
+ ## Coins and balances
175
+
176
+ ### `getBalance`
177
+
178
+ Get the balance of one coin type for an owner. `coinType` defaults to `0x2::sui::SUI`.
179
+
180
+ ```typescript
181
+ const { balance } = await client.getBalance({
182
+ owner: '0xabc...',
183
+ coinType: '0x2::sui::SUI',
184
+ });
185
+
186
+ console.log(balance.balance); // Total: coin objects + address balance
187
+ console.log(balance.coinBalance); // From coin objects only
188
+ console.log(balance.addressBalance); // From the address balance only
189
+ ```
190
+
191
+ All three values are decimal strings, not numbers, so use `BigInt` for arithmetic.
192
+
193
+ ### `listBalances`
194
+
195
+ List balances for every coin type an address holds.
196
+
197
+ ```typescript
198
+ const page = await client.listBalances({ owner: '0xabc...' });
199
+
200
+ for (const balance of page.balances) {
201
+ console.log(balance.coinType, balance.balance);
202
+ }
203
+ ```
204
+
205
+ ### `listCoins`
206
+
207
+ List individual coin objects of one type. `coinType` defaults to `0x2::sui::SUI`.
208
+
209
+ ```typescript
210
+ const page = await client.listCoins({
211
+ owner: '0xabc...',
212
+ coinType: '0x2::sui::SUI',
213
+ limit: 10,
214
+ });
215
+
216
+ for (const coin of page.objects) {
217
+ console.log(coin.objectId, coin.balance);
218
+ }
219
+ ```
220
+
221
+ > **Note:** You rarely need to select coins by hand. The transaction builder resolves gas and coin inputs for
222
+ > you. See [Coins and balances](/sui/transactions/coins-and-balances).
223
+
224
+ ### `getCoinMetadata`
225
+
226
+ Get the name, symbol, decimals, description, and icon for a coin type. Returns `null` when the type
227
+ has no registered metadata.
228
+
229
+ ```typescript
230
+ const { coinMetadata } = await client.getCoinMetadata({
231
+ coinType: '0x2::sui::SUI',
232
+ });
233
+
234
+ if (coinMetadata) {
235
+ console.log(coinMetadata.name, coinMetadata.symbol, coinMetadata.decimals);
236
+ // "Sui" "SUI" 9
237
+ }
238
+ ```
239
+
240
+ ## Dynamic fields
241
+
242
+ ### `listDynamicFields`
243
+
244
+ List the dynamic fields attached to an object.
245
+
246
+ ```typescript
247
+ const page = await client.listDynamicFields({
248
+ parentId: '0x123...',
249
+ limit: 10,
250
+ });
251
+
252
+ for (const field of page.dynamicFields) {
253
+ console.log(field.$kind); // "DynamicField" | "DynamicObject"
254
+ console.log(field.fieldId, field.name.type, field.valueType);
255
+ }
256
+ ```
257
+
258
+ On `SuiGrpcClient` and `SuiGraphQLClient` this method also accepts `include: { value: true }` to
259
+ fetch each field's BCS-encoded value in the same request.
260
+
261
+ ### `getDynamicField`
262
+
263
+ Fetch one dynamic field by name. The name is given as its Move type plus BCS-encoded bytes.
264
+
265
+ ```typescript
266
+
267
+ const { dynamicField } = await client.getDynamicField({
268
+ parentId: '0x123...',
269
+ name: {
270
+ type: 'u64',
271
+ bcs: bcs.u64().serialize(42).toBytes(),
272
+ },
273
+ });
274
+
275
+ console.log(dynamicField.value.type);
276
+ console.log(dynamicField.value.bcs); // BCS-encoded value
277
+ ```
278
+
279
+ ### `getDynamicObjectField`
280
+
281
+ Fetch a dynamic _object_ field and return the referenced object itself, with the same
282
+ [include options](#include-options) as `getObject`.
283
+
284
+ ```typescript
285
+ const { object } = await client.getDynamicObjectField({
286
+ parentId: '0x123...',
287
+ name: {
288
+ type: '0x2::object::ID',
289
+ bcs: bcs.Address.serialize('0x456...').toBytes(),
290
+ },
291
+ include: { content: true },
292
+ });
293
+ ```
294
+
295
+ ## Transactions and events
296
+
297
+ Reading transactions back is covered here; running them is covered in
298
+ [Executing transactions](/sui/clients/executing).
299
+
300
+ ### `getTransaction`
301
+
302
+ Fetch one transaction by digest. The result is the same discriminated union that execution returns,
303
+ and it takes the same [include options](/sui/clients/executing#include-options).
304
+
305
+ ```typescript
306
+ const result = await client.getTransaction({
307
+ digest: 'ABC123...',
308
+ include: {
309
+ effects: true,
310
+ events: true,
311
+ transaction: true,
312
+ },
313
+ });
314
+
315
+ const transaction = result.Transaction ?? result.FailedTransaction;
316
+
317
+ console.log(transaction.digest);
318
+ console.log(transaction.status.success);
319
+ console.log(transaction.effects);
320
+ ```
321
+
322
+ A transaction that executed but aborted onchain comes back as `FailedTransaction` rather than
323
+ throwing. See
324
+ [checking success or failure](/sui/transactions/signing-and-execution#checking-success-or-failure).
325
+
326
+ ### `listTransactions`
327
+
328
+ Page through transactions matching a filter. Results use the same include options as
329
+ `getTransaction`.
330
+
331
+ ```typescript
332
+ const page = await client.listTransactions({
333
+ filter: { function: '0x2::coin::mint_and_transfer' },
334
+ limit: 10,
335
+ include: { effects: true },
336
+ });
337
+
338
+ for (const result of page.transactions) {
339
+ const transaction = result.Transaction ?? result.FailedTransaction;
340
+ console.log(transaction.digest, result.$kind);
341
+ }
342
+ ```
343
+
344
+ Transaction filters take exactly one predicate:
345
+
346
+ | Predicate | Description |
347
+ | ---------- | --------------------------------------------------------------------------- |
348
+ | `sender` | Transactions sent by an address |
349
+ | `function` | Transactions calling a Move function (`pkg`, `pkg::mod`, or `pkg::mod::fn`) |
350
+
351
+ ### `listEvents`
352
+
353
+ Page through events matching a filter. Each event carries its ledger position (`checkpoint`,
354
+ `transactionDigest`, and `eventIndex`) alongside the event data.
355
+
356
+ ```typescript
357
+ const page = await client.listEvents({
358
+ filter: { eventType: '0xpkg...::my_module::MyEvent' },
359
+ order: 'descending',
360
+ limit: 10,
361
+ });
362
+
363
+ for (const event of page.events) {
364
+ console.log(event.eventType, event.transactionDigest, event.eventIndex, event.json);
365
+ }
366
+ ```
367
+
368
+ Event filters take exactly one predicate:
369
+
370
+ | Predicate | Description |
371
+ | ------------ | --------------------------------------------------------------------------------- |
372
+ | `sender` | Events from transactions sent by an address |
373
+ | `emitModule` | Events emitted by a module (`pkg::mod`) |
374
+ | `eventType` | Events with types defined in a module (`pkg::mod`) or a fully qualified type name |
375
+
376
+ Both filters resolve [MVR](#move-registry-names) names automatically, and both methods take a
377
+ `limit` and an `order` and page through history with the cursors described under
378
+ [Pagination](#pagination).
379
+
380
+ For filters beyond one predicate (combined or negated predicates, affected addresses and objects, or
381
+ checkpoint ranges), use the [raw gRPC list RPCs](/sui/clients/grpc#using-service-clients) or a
382
+ [custom GraphQL query](/sui/clients/graphql#writing-queries). To follow new activity as it happens,
383
+ see [gRPC subscriptions](/sui/clients/grpc#subscriptions).
384
+
385
+ ## Pagination
386
+
387
+ Collection reads and history queries paginate differently, and both report `hasNextPage`.
388
+
389
+ ### Collection cursors
390
+
391
+ `listOwnedObjects`, `listCoins`, `listBalances`, and `listDynamicFields` take a `limit` and a
392
+ `cursor`, and return the next `cursor` alongside the results:
393
+
394
+ ```typescript
395
+ let page = await client.listOwnedObjects({ owner: '0xabc...', limit: 50 });
396
+
397
+ while (true) {
398
+ for (const object of page.objects) {
399
+ console.log(object.objectId);
400
+ }
401
+
402
+ if (!page.hasNextPage) {
403
+ break;
404
+ }
405
+
406
+ page = await client.listOwnedObjects({
407
+ owner: '0xabc...',
408
+ cursor: page.cursor,
409
+ limit: 50,
410
+ });
411
+ }
412
+ ```
413
+
414
+ > **Note:** Carrying the cursor in a separately annotated variable (`let cursor: string | null = null`) makes
415
+ > these methods fail to infer: because they are generic over `include`, the type of the page depends
416
+ > on the argument that holds the cursor, which depends on the page. Reassigning the page itself, as
417
+ > above, avoids the cycle.
418
+
419
+ ### History cursors
420
+
421
+ `listTransactions` and `listEvents` read an ordered ledger instead of a collection, so they take
422
+ `after` and `before`, which are exclusive ledger-position bounds. A query takes at most one of them,
423
+ and the bound implies the direction: `after` reads ascending, `before` reads descending. Each page
424
+ reports the position of its first and last item as `startCursor` and `endCursor`, so a feed can page
425
+ in both directions from any point:
426
+
427
+ ```typescript
428
+ // The most recent transactions
429
+ const latest = await client.listTransactions({
430
+ filter: { sender: '0xabc...' },
431
+ order: 'descending',
432
+ limit: 10,
433
+ });
434
+
435
+ // Older transactions, continuing backwards
436
+ const older = await client.listTransactions({
437
+ filter: { sender: '0xabc...' },
438
+ before: latest.endCursor,
439
+ limit: 10,
440
+ });
441
+
442
+ // Anything that landed since, continuing forwards
443
+ const newer = await client.listTransactions({
444
+ filter: { sender: '0xabc...' },
445
+ after: latest.startCursor,
446
+ });
447
+ ```
448
+
449
+ > **Note:** Drive pagination off `hasNextPage` rather than page length. On gRPC, a filtered query is bounded
450
+ > in how much ledger it scans per request, so a page can come back shorter than `limit`, even empty,
451
+ > while `hasNextPage` is still `true`; continuing from `endCursor` always makes progress. Servers
452
+ > also cap page sizes (50 by default); over-large `limit` values are truncated on gRPC and rejected
453
+ > on GraphQL.
454
+
455
+ ## Move functions
456
+
457
+ `getMoveFunction` returns a function's normalized signature.
458
+
459
+ ```typescript
460
+ const { function: fn } = await client.getMoveFunction({
461
+ packageId: '0x2',
462
+ moduleName: 'coin',
463
+ name: 'value',
464
+ });
465
+
466
+ console.log(fn.visibility, fn.isEntry);
467
+ console.log(fn.parameters);
468
+ console.log(fn.typeParameters);
469
+ ```
470
+
471
+ ## Name service
472
+
473
+ ### `resolveNameServiceAddress`
474
+
475
+ Resolve a SuiNS name to its target address. The address is `null` when the name does not exist, has
476
+ expired, or has no target address.
477
+
478
+ ```typescript
479
+ const { address } = await client.resolveNameServiceAddress({
480
+ name: 'example.sui',
481
+ });
482
+ ```
483
+
484
+ ### `defaultNameServiceName`
485
+
486
+ Resolve an address to its default SuiNS name, or `null` if it has none.
487
+
488
+ ```typescript
489
+ const {
490
+ data: { name },
491
+ } = await client.defaultNameServiceName({
492
+ address: '0xabc...',
493
+ });
494
+ ```
495
+
496
+ ## Move Registry names
497
+
498
+ Wherever a method takes a Move type or package, it also accepts a Move Registry (MVR) name, a
499
+ human-readable alias such as `@deepbook/core`, which the client resolves for you. You can also
500
+ resolve them directly through `client.mvr`:
501
+
502
+ ```typescript
503
+ const { package: packageId } = await client.mvr.resolvePackage({
504
+ package: '@deepbook/core',
505
+ });
506
+
507
+ const { type } = await client.mvr.resolveType({
508
+ type: '@deepbook/core::pool::Pool<@deepbook/core::deep::DEEP>',
509
+ });
510
+ ```
511
+
512
+ `client.mvr.resolve({ packages, types })` resolves several names in one call. Resolved names are
513
+ cached on the client.
514
+
515
+ > **Note:** MVR has default endpoints for Mainnet and Testnet only. On other networks, pass an `mvr` option
516
+ > when constructing the client. Names that are not registered are rejected rather than passed
517
+ > through, so only packages actually published to the registry resolve.
518
+
519
+ ## Cancelling requests
520
+
521
+ Every method accepts a `signal` to cancel an in-flight request:
522
+
523
+ ```typescript
524
+ const controller = new AbortController();
525
+
526
+ const { object } = await client.getObject({
527
+ objectId: '0x123...',
528
+ signal: controller.signal,
529
+ });
530
+ ```
531
+
532
+ ## Error handling
533
+
534
+ Methods reject when a request fails. The one exception is [`getObjects`](#getobjects), which reports
535
+ per-object failures in its result array so a single bad ID does not fail the batch.
536
+
537
+ Transaction results have their own convention, where a transaction that executed but failed onchain
538
+ is not an error. See
539
+ [checking success or failure](/sui/transactions/signing-and-execution#checking-success-or-failure).
package/docs/executors.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Transaction Executors
2
2
 
3
- > Manage transaction execution with queuing and parallel strategies.
3
+ > Manage transaction execution with queuing and parallel strategies
4
4
 
5
5
  The TypeScript SDK ships two `Transaction` executor classes that simplify the processes of
6
6
  efficiently executing multiple transactions signed by the same address. These executors help manage
@@ -30,8 +30,8 @@ transactions to finish before sending the next one.
30
30
 
31
31
  - `client`: An instance of a Sui client (such as `SuiGrpcClient`) used to execute transactions.
32
32
  - `signer`: The signer/keypair used for signed transactions.
33
- - `defaultBudget`: The default budget for transactions, which will be used if the transaction does
34
- not specify a budget (default `50_000_000n`).
33
+ - `defaultGasBudget`: The default budget for transactions, which will be used if the transaction
34
+ does not specify a budget (default `50_000_000n`).
35
35
  - `gasMode`: Either `'coins'` (default) to use owned coins for gas, or `'addressBalance'` to pay gas
36
36
  from the sender's address balance.
37
37
 
@@ -54,10 +54,18 @@ const tx2 = new Transaction();
54
54
  const [coin2] = tx2.splitCoins(tx2.gas, [1]);
55
55
  tx2.transferObjects([coin2], address2);
56
56
 
57
- const [{ digest: digest1 }, { digest: digest2 }] = await Promise.all([
57
+ const results = await Promise.all([
58
58
  executor.executeTransaction(tx1),
59
59
  executor.executeTransaction(tx2),
60
60
  ]);
61
+
62
+ const [digest1, digest2] = results.map((result) => {
63
+ if (result.$kind === 'FailedTransaction') {
64
+ throw new Error(`Transaction failed: ${result.FailedTransaction.status.error.message}`);
65
+ }
66
+
67
+ return result.Transaction.digest;
68
+ });
61
69
  ```
62
70
 
63
71
  ## `ParallelTransactionExecutor`
@@ -83,7 +91,7 @@ way that avoids conflicts between transactions using the same object ids.
83
91
 
84
92
  `ParallelTransactionExecutor` can be configured with a number of options:
85
93
 
86
- - `client`: An instance of `SuiJsonRpcClient` used to execute transactions.
94
+ - `client`: A client implementing `ClientWithCoreApi`. `SuiGrpcClient` is the recommended default.
87
95
  - `signer`: The signer/keypair used for signed transactions.
88
96
  - `gasMode`: Either `'coins'` (default) to use owned coins for gas, or `'addressBalance'` to pay gas
89
97
  from the sender's address balance. When using `'addressBalance'`, coin-specific options like
@@ -94,20 +102,19 @@ way that avoids conflicts between transactions using the same object ids.
94
102
  `200_000_000n`),
95
103
  - `minimumCoinBalance`: After executing a transaction, the gasCoin will be reused unless it's
96
104
  balance is below this value (default `50_000_000n`),
97
- - `defaultBudget`: The default budget for transactions, which will be used if the transaction does
98
- not specify a budget (default `minimumCoinBalance`),
105
+ - `defaultGasBudget`: The default budget for transactions, which will be used if the transaction
106
+ does not specify a budget (default `minimumCoinBalance`),
99
107
  - `maxPoolSize`: The maximum number of gas coins to keep in the gas pool, which also limits the
100
108
  maximum number of concurrent transactions (default 50),
101
109
  - `sourceCoins`: An array of coins to use to create the gas pool, defaults to using all coins owned
102
110
  by the signer.
103
- - `epochBoundaryWindow`: Time to wait before or after the expected epoch boundary before re-fetching
104
- the gas pool (in milliseconds). Building transactions will be paused for up to 2x this duration
105
- around each epoch boundary to ensure the gas price is up-to-date for the next epoch. (default
106
- `1000`)
107
111
 
108
112
  ```ts
109
113
 
110
- const client = new SuiJsonRpcClient({ url: getJsonRpcFullnodeUrl('devnet'), network: 'devnet' });
114
+ const client = new SuiGrpcClient({
115
+ baseUrl: 'https://fullnode.devnet.sui.io:443',
116
+ network: 'devnet',
117
+ });
111
118
 
112
119
  const executor = new ParallelTransactionExecutor({
113
120
  client,
@@ -121,10 +128,18 @@ const tx2 = new Transaction();
121
128
  const [coin2] = tx2.splitCoins(tx2.gas, [1]);
122
129
  tx2.transferObjects([coin2], address2);
123
130
 
124
- const [{ digest: digest1 }, { digest: digest2 }] = await Promise.all([
131
+ const results = await Promise.all([
125
132
  executor.executeTransaction(tx1),
126
133
  executor.executeTransaction(tx2),
127
134
  ]);
135
+
136
+ const [digest1, digest2] = results.map((result) => {
137
+ if (result.$kind === 'FailedTransaction') {
138
+ throw new Error(`Transaction failed: ${result.FailedTransaction.status.error.message}`);
139
+ }
140
+
141
+ return result.Transaction.digest;
142
+ });
128
143
  ```
129
144
 
130
145
  ## Building and executing transactions with executors
package/docs/index.md CHANGED
@@ -126,7 +126,7 @@ const grpcClient = new SuiGrpcClient({
126
126
  baseUrl: 'https://fullnode.devnet.sui.io:443',
127
127
  });
128
128
 
129
- const { balance } = await grpcClient.core.getBalance({
129
+ const { balance } = await grpcClient.getBalance({
130
130
  owner: keypair.toSuiAddress(),
131
131
  });
132
132