@mysten/sui 2.24.0 → 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.
- package/CHANGELOG.md +60 -0
- package/dist/bcs/bcs.d.mts +6 -6
- package/dist/bcs/index.d.mts +36 -36
- package/dist/client/core.d.mts.map +1 -1
- package/dist/client/core.mjs +4 -1
- package/dist/client/core.mjs.map +1 -1
- package/dist/client/mvr.d.mts.map +1 -1
- package/dist/client/mvr.mjs +1 -0
- package/dist/client/mvr.mjs.map +1 -1
- package/dist/cryptography/signature.d.mts +6 -6
- package/dist/graphql/client.d.mts +5 -1
- package/dist/graphql/client.d.mts.map +1 -1
- package/dist/graphql/client.mjs +15 -2
- package/dist/graphql/client.mjs.map +1 -1
- package/dist/graphql/core.d.mts +4 -4
- package/dist/graphql/core.d.mts.map +1 -1
- package/dist/graphql/core.mjs +50 -13
- package/dist/graphql/core.mjs.map +1 -1
- package/dist/graphql/generated/tada-env.d.mts +16 -0
- package/dist/grpc/client.d.mts +5 -1
- package/dist/grpc/client.d.mts.map +1 -1
- package/dist/grpc/client.mjs +14 -2
- package/dist/grpc/client.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/signature_verification_service.client.d.mts +4 -4
- package/dist/grpc/proto/sui/rpc/v2/state_service.client.d.mts +4 -4
- package/dist/grpc/proto/sui/rpc/v2/subscription_service.client.d.mts +4 -4
- package/dist/grpc/proto/sui/rpc/v2/transaction_execution_service.client.d.mts +4 -4
- package/dist/jsonRpc/client.d.mts.map +1 -1
- package/dist/jsonRpc/client.mjs +60 -15
- package/dist/jsonRpc/client.mjs.map +1 -1
- package/dist/jsonRpc/core.d.mts +1 -1
- package/dist/jsonRpc/core.d.mts.map +1 -1
- package/dist/jsonRpc/core.mjs +18 -7
- package/dist/jsonRpc/core.mjs.map +1 -1
- package/dist/transactions/Transaction.d.mts +3 -3
- package/dist/transactions/data/v1.d.mts +220 -220
- package/dist/transactions/data/v1.d.mts.map +1 -1
- package/dist/transactions/data/v2.d.mts +16 -16
- package/dist/transactions/data/v2.d.mts.map +1 -1
- package/dist/version.mjs +1 -1
- package/dist/version.mjs.map +1 -1
- package/dist/zklogin/bcs.d.mts +14 -14
- package/docs/bcs.md +2 -2
- package/docs/clients/core.md +150 -710
- package/docs/clients/executing.md +113 -0
- package/docs/clients/graphql.md +80 -70
- package/docs/clients/grpc.md +223 -208
- package/docs/clients/index.md +56 -67
- package/docs/clients/querying.md +539 -0
- package/docs/llms-index.md +6 -5
- package/docs/migrations/sui-2.0/json-rpc-migration.md +3 -1
- package/docs/transactions/signing-and-execution.md +8 -28
- package/package.json +1 -1
- package/src/client/core.ts +1 -0
- package/src/client/mvr.ts +6 -0
- package/src/graphql/client.ts +29 -2
- package/src/graphql/core.ts +42 -10
- package/src/graphql/generated/schema.graphql +11 -1
- package/src/graphql/generated/tada-env.ts +20 -0
- package/src/grpc/client.ts +28 -2
- package/src/jsonRpc/client.ts +15 -0
- package/src/jsonRpc/core.ts +19 -6
- package/src/version.ts +1 -1
- package/docs/clients/json-rpc.md +0 -243
|
@@ -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/llms-index.md
CHANGED
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
|
|
4
4
|
- [Sui TypeScript SDK](..md): TypeScript SDK for building on the Sui blockchain
|
|
5
5
|
- [LLM Documentation](./llm-docs.md): Give AI agents access to Sui SDK documentation in your project.
|
|
6
|
-
- [Sui Clients](./clients.md): Choose
|
|
7
|
-
- [
|
|
8
|
-
- [
|
|
9
|
-
- [
|
|
10
|
-
- [
|
|
6
|
+
- [Sui Clients](./clients.md): Choose between SuiGrpcClient and SuiGraphQLClient and understand their shared API
|
|
7
|
+
- [Querying Data](./clients/querying.md): Read objects, coins, balances, dynamic fields, and history with any Sui client
|
|
8
|
+
- [Executing Transactions](./clients/executing.md): Simulate, execute, and wait for transactions with any Sui client
|
|
9
|
+
- [SuiGrpcClient](./clients/grpc.md): Connect to Sui over gRPC, with native service clients and real-time subscriptions
|
|
10
|
+
- [SuiGraphQLClient](./clients/graphql.md): Connect to Sui over GraphQL and write type-safe custom queries
|
|
11
|
+
- [Core API](./clients/core.md): The transport-agnostic client contract that SDKs and libraries build against
|
|
11
12
|
- [Building Transactions](./transactions/basics.md): Construct programmable transaction blocks with the Transaction API
|
|
12
13
|
- [Signing and Execution](./transactions/signing-and-execution.md): Sign transactions and execute them on the Sui network
|
|
13
14
|
- [Coins and Balances](./transactions/coins-and-balances.md): Work with coin objects and address balances in transactions
|
|
@@ -434,7 +434,8 @@ Common event filter mappings:
|
|
|
434
434
|
|
|
435
435
|
The top-level query methods handle pagination and cursor normalization. For richer filters, such as
|
|
436
436
|
combined predicates, affected addresses, affected objects, or checkpoint ranges, use the raw
|
|
437
|
-
[`ledgerService`](/sui/clients/grpc#
|
|
437
|
+
[`ledgerService`](/sui/clients/grpc#using-service-clients) on `SuiGrpcClient` or a custom GraphQL
|
|
438
|
+
query.
|
|
438
439
|
|
|
439
440
|
Use `after: result.endCursor` to continue an ascending query and `before: result.endCursor` to
|
|
440
441
|
continue a descending query. `startCursor` identifies the first item in a page and can be used with
|
|
@@ -626,5 +627,6 @@ await client.suins.getNameRecord('example.sui');
|
|
|
626
627
|
|
|
627
628
|
- [SuiGrpcClient](/sui/clients/grpc)
|
|
628
629
|
- [SuiGraphQLClient](/sui/clients/graphql)
|
|
630
|
+
- [Querying data](/sui/clients/querying)
|
|
629
631
|
- [Core API](/sui/clients/core)
|
|
630
632
|
- [Building SDKs](/sui/sdk-building)
|
|
@@ -36,24 +36,10 @@ if (result.$kind === 'FailedTransaction') {
|
|
|
36
36
|
}
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
| Field | Description |
|
|
45
|
-
| ---------------- | -------------------------------------------------------------------------------------- |
|
|
46
|
-
| `effects` | Execution effects: created, mutated, and deleted objects, gas usage |
|
|
47
|
-
| `events` | Move events emitted during execution |
|
|
48
|
-
| `balanceChanges` | Token balance changes for each affected address and coin type |
|
|
49
|
-
| `objectTypes` | Map of object ID to type string for all changed objects |
|
|
50
|
-
| `transaction` | The full transaction data (sender, commands, gas config) |
|
|
51
|
-
| `bcs` | Raw BCS-encoded transaction bytes |
|
|
52
|
-
| `commandResults` | BCS-encoded return values and mutated references from each command _(simulation only)_ |
|
|
53
|
-
|
|
54
|
-
The `commandResults` field is unique to simulation. It is not available on `executeTransaction`.
|
|
55
|
-
Each entry contains `returnValues` and `mutatedReferences`, both as BCS-encoded `Uint8Array` values
|
|
56
|
-
that you can decode with the [BCS library](/bcs).
|
|
39
|
+
`commandResults` is unique to simulation. Each entry holds a command's `returnValues` and
|
|
40
|
+
`mutatedReferences` as BCS-encoded bytes, which you can decode with the [BCS library](/bcs). For the
|
|
41
|
+
rest of the `include` options, and the two flags that change how the node runs a simulation, see
|
|
42
|
+
[Executing transactions](/sui/clients/executing#simulatetransaction).
|
|
57
43
|
|
|
58
44
|
## With a keypair (backend or scripts)
|
|
59
45
|
|
|
@@ -178,16 +164,10 @@ const result = await grpcClient.executeTransaction({
|
|
|
178
164
|
});
|
|
179
165
|
```
|
|
180
166
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
| `transaction` | The full transaction data (sender, commands, gas) |
|
|
186
|
-
| `effects` | Execution effects (created, mutated, or deleted objects) |
|
|
187
|
-
| `events` | Move events emitted during execution |
|
|
188
|
-
| `balanceChanges` | Token balance changes for each affected address |
|
|
189
|
-
| `objectTypes` | Map of object ID to type for changed objects |
|
|
190
|
-
| `bcs` | Raw BCS bytes of the transaction |
|
|
167
|
+
Clients also expose `signAndExecuteTransaction`, which takes a signer instead of bytes and does both
|
|
168
|
+
steps in one call, which is useful when the signer is not a keypair, or in library code that holds a
|
|
169
|
+
client. See [Executing transactions](/sui/clients/executing) for the full `include` options and the
|
|
170
|
+
rest of the client execution methods.
|
|
191
171
|
|
|
192
172
|
## Observing results
|
|
193
173
|
|
package/package.json
CHANGED
package/src/client/core.ts
CHANGED
|
@@ -209,6 +209,7 @@ export abstract class CoreClient extends BaseClient implements SuiClientTypes.Tr
|
|
|
209
209
|
const resolvedNameType = (
|
|
210
210
|
await this.core.mvr.resolveType({
|
|
211
211
|
type: options.name.type,
|
|
212
|
+
signal: options.signal,
|
|
212
213
|
})
|
|
213
214
|
).type;
|
|
214
215
|
const wrappedType = `0x2::dynamic_object_field::Wrapper<${resolvedNameType}>`;
|
package/src/client/mvr.ts
CHANGED
|
@@ -401,6 +401,12 @@ export function raceSignal<T>(promise: Promise<T>, signal?: AbortSignal): Promis
|
|
|
401
401
|
return promise;
|
|
402
402
|
}
|
|
403
403
|
|
|
404
|
+
// An `abort` event is not replayed for listeners added after the fact, so a signal that was
|
|
405
|
+
// already aborted would otherwise resolve normally.
|
|
406
|
+
if (signal.aborted) {
|
|
407
|
+
return Promise.reject(signal.reason);
|
|
408
|
+
}
|
|
409
|
+
|
|
404
410
|
return new Promise<T>((resolve, reject) => {
|
|
405
411
|
const onAbort = () => reject(signal.reason);
|
|
406
412
|
signal.addEventListener('abort', onAbort, { once: true });
|