@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.
- package/CHANGELOG.md +67 -0
- package/README.md +9 -9
- package/dist/bcs/bcs.d.mts +6 -6
- package/dist/client/core.d.mts +1 -0
- 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/client/types.d.mts +7 -0
- package/dist/client/types.d.mts.map +1 -1
- package/dist/cryptography/signature.d.mts +6 -6
- package/dist/graphql/client.d.mts +6 -1
- package/dist/graphql/client.d.mts.map +1 -1
- package/dist/graphql/client.mjs +18 -2
- package/dist/graphql/client.mjs.map +1 -1
- package/dist/graphql/core.d.mts +5 -4
- package/dist/graphql/core.d.mts.map +1 -1
- package/dist/graphql/core.mjs +60 -14
- package/dist/graphql/core.mjs.map +1 -1
- package/dist/graphql/generated/queries.d.mts.map +1 -1
- package/dist/graphql/generated/queries.mjs +8 -1
- package/dist/graphql/generated/queries.mjs.map +1 -1
- package/dist/graphql/generated/tada-env.d.mts +16 -0
- package/dist/grpc/client.d.mts +6 -1
- package/dist/grpc/client.d.mts.map +1 -1
- package/dist/grpc/client.mjs +17 -2
- package/dist/grpc/client.mjs.map +1 -1
- package/dist/grpc/core.d.mts +1 -0
- package/dist/grpc/core.d.mts.map +1 -1
- package/dist/grpc/core.mjs +20 -0
- package/dist/grpc/core.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/name_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/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 +6 -1
- package/dist/jsonRpc/core.d.mts.map +1 -1
- package/dist/jsonRpc/core.mjs +25 -7
- package/dist/jsonRpc/core.mjs.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 +151 -690
- package/docs/clients/executing.md +113 -0
- package/docs/clients/graphql.md +91 -46
- package/docs/clients/grpc.md +239 -142
- package/docs/clients/index.md +87 -51
- package/docs/clients/querying.md +539 -0
- package/docs/executors.md +28 -13
- package/docs/index.md +1 -1
- package/docs/llms-index.md +18 -17
- package/docs/migrations/sui-2.0/dapp-kit.md +3 -3
- package/docs/migrations/sui-2.0/deepbook-v3.md +2 -2
- package/docs/migrations/sui-2.0/index.md +46 -25
- package/docs/migrations/sui-2.0/json-rpc-migration.md +462 -284
- package/docs/migrations/sui-2.0/kiosk.md +10 -9
- package/docs/migrations/sui-2.0/sdk-maintainers.md +17 -11
- package/docs/migrations/sui-2.0/sui.md +47 -29
- package/docs/migrations/sui-2.0/suins.md +2 -2
- package/docs/migrations/sui-2.0/walrus.md +3 -3
- package/docs/migrations/sui-2.0/zksend.md +9 -8
- package/docs/sdk-building.md +7 -5
- package/docs/transactions/signing-and-execution.md +8 -28
- package/package.json +1 -1
- package/src/client/core.ts +5 -0
- package/src/client/mvr.ts +6 -0
- package/src/client/types.ts +11 -0
- package/src/graphql/client.ts +35 -2
- package/src/graphql/core.ts +57 -10
- package/src/graphql/generated/queries.ts +14 -0
- package/src/graphql/generated/schema.graphql +11 -1
- package/src/graphql/generated/tada-env.ts +20 -0
- package/src/graphql/queries/nameService.graphql +6 -0
- package/src/grpc/client.ts +34 -2
- package/src/grpc/core.ts +35 -0
- package/src/jsonRpc/client.ts +15 -0
- package/src/jsonRpc/core.ts +31 -6
- package/src/version.ts +1 -1
- 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
|
-
- `
|
|
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
|
|
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`:
|
|
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
|
-
- `
|
|
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
|
|
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
|
|
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.
|
|
129
|
+
const { balance } = await grpcClient.getBalance({
|
|
130
130
|
owner: keypair.toSuiAddress(),
|
|
131
131
|
});
|
|
132
132
|
|