@exodus/sui-api 1.3.0 → 1.4.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.
@@ -1,680 +0,0 @@
1
- /* eslint-disable unicorn/no-await-expression-member */
2
- /* eslint-disable no-return-await */
3
- /* eslint-disable camelcase */
4
- import { vendorLib } from '@exodus/sui-lib'
5
-
6
- import { Experimental_BaseClient } from '../experimental/client.js'
7
- import { JSONRpcTransport } from '../experimental/transports/jsonRPC.js'
8
- import { isTransaction } from '../transactions/Transaction.js'
9
- import { SuiHTTPTransport } from './http-transport.js'
10
-
11
- const { fromBase58, toBase64, toHex } = vendorLib.utils
12
-
13
- const {
14
- isValidSuiAddress,
15
- isValidSuiObjectId,
16
- isValidTransactionDigest,
17
- normalizeSuiAddress,
18
- normalizeSuiObjectId,
19
- } = vendorLib.utils
20
-
21
- const SUI_CLIENT_BRAND = Symbol.for('@mysten/SuiClient')
22
-
23
- class SuiClient extends Experimental_BaseClient {
24
- /**
25
- * Establish a connection to a Sui RPC endpoint
26
- *
27
- * @param options configuration options for the API Client
28
- */
29
- constructor(options) {
30
- super({ network: options.network ?? 'unknown' })
31
- this.jsonRpc = this
32
- this.transport = options.transport ?? new SuiHTTPTransport({ url: options.url })
33
- this.core = new JSONRpcTransport({
34
- jsonRpcClient: this,
35
- })
36
- }
37
-
38
- get [SUI_CLIENT_BRAND]() {
39
- return true
40
- }
41
-
42
- async getRpcApiVersion({ signal } = Object.create(null)) {
43
- const resp = await this.transport.request({
44
- method: 'rpc.discover',
45
- params: [],
46
- signal,
47
- })
48
- return resp.info.version
49
- }
50
-
51
- /**
52
- * Get all Coin<`coin_type`> objects owned by an address.
53
- */
54
- async getCoins({ coinType, owner, cursor, limit, signal }) {
55
- if (!owner || !isValidSuiAddress(normalizeSuiAddress(owner))) {
56
- throw new Error('Invalid Sui address')
57
- }
58
-
59
- return await this.transport.request({
60
- method: 'suix_getCoins',
61
- params: [owner, coinType, cursor, limit],
62
- signal,
63
- })
64
- }
65
-
66
- /**
67
- * Get all Coin objects owned by an address.
68
- */
69
- async getAllCoins(input) {
70
- if (!input.owner || !isValidSuiAddress(normalizeSuiAddress(input.owner))) {
71
- throw new Error('Invalid Sui address')
72
- }
73
-
74
- return await this.transport.request({
75
- method: 'suix_getAllCoins',
76
- params: [input.owner, input.cursor, input.limit],
77
- signal: input.signal,
78
- })
79
- }
80
-
81
- /**
82
- * Get the total coin balance for one coin type, owned by the address owner.
83
- */
84
- async getBalance({ owner, coinType, signal }) {
85
- if (!owner || !isValidSuiAddress(normalizeSuiAddress(owner))) {
86
- throw new Error('Invalid Sui address')
87
- }
88
-
89
- return await this.transport.request({
90
- method: 'suix_getBalance',
91
- params: [owner, coinType],
92
- signal,
93
- })
94
- }
95
-
96
- /**
97
- * Get the total coin balance for all coin types, owned by the address owner.
98
- */
99
- async getAllBalances(input) {
100
- if (!input.owner || !isValidSuiAddress(normalizeSuiAddress(input.owner))) {
101
- throw new Error('Invalid Sui address')
102
- }
103
-
104
- return await this.transport.request({
105
- method: 'suix_getAllBalances',
106
- params: [input.owner],
107
- signal: input.signal,
108
- })
109
- }
110
-
111
- /**
112
- * Fetch CoinMetadata for a given coin type
113
- */
114
- async getCoinMetadata({ coinType, signal }) {
115
- return await this.transport.request({
116
- method: 'suix_getCoinMetadata',
117
- params: [coinType],
118
- signal,
119
- })
120
- }
121
-
122
- /**
123
- * Fetch total supply for a coin
124
- */
125
- async getTotalSupply({ coinType, signal }) {
126
- return await this.transport.request({
127
- method: 'suix_getTotalSupply',
128
- params: [coinType],
129
- signal,
130
- })
131
- }
132
-
133
- /**
134
- * Invoke any RPC method
135
- * @param method the method to be invoked
136
- * @param args the arguments to be passed to the RPC request
137
- */
138
- async call(method, params, { signal } = Object.create(null)) {
139
- return await this.transport.request({ method, params, signal })
140
- }
141
-
142
- /**
143
- * Get Move function argument types like read, write and full access
144
- */
145
- async getMoveFunctionArgTypes({ package: pkg, module, function: fn, signal }) {
146
- return await this.transport.request({
147
- method: 'sui_getMoveFunctionArgTypes',
148
- params: [pkg, module, fn],
149
- signal,
150
- })
151
- }
152
-
153
- /**
154
- * Get a map from module name to
155
- * structured representations of Move modules
156
- */
157
- async getNormalizedMoveModulesByPackage({ package: pkg, signal }) {
158
- return await this.transport.request({
159
- method: 'sui_getNormalizedMoveModulesByPackage',
160
- params: [pkg],
161
- signal,
162
- })
163
- }
164
-
165
- /**
166
- * Get a structured representation of Move module
167
- */
168
- async getNormalizedMoveModule({ package: pkg, module, signal }) {
169
- return await this.transport.request({
170
- method: 'sui_getNormalizedMoveModule',
171
- params: [pkg, module],
172
- signal,
173
- })
174
- }
175
-
176
- /**
177
- * Get a structured representation of Move function
178
- */
179
- async getNormalizedMoveFunction({ package: pkg, module, function: fn, signal }) {
180
- return await this.transport.request({
181
- method: 'sui_getNormalizedMoveFunction',
182
- params: [pkg, module, fn],
183
- signal,
184
- })
185
- }
186
-
187
- /**
188
- * Get a structured representation of Move struct
189
- */
190
- async getNormalizedMoveStruct({ package: pkg, module, struct, signal }) {
191
- return await this.transport.request({
192
- method: 'sui_getNormalizedMoveStruct',
193
- params: [pkg, module, struct],
194
- signal,
195
- })
196
- }
197
-
198
- /**
199
- * Get all objects owned by an address
200
- */
201
- async getOwnedObjects(input) {
202
- if (!input.owner || !isValidSuiAddress(normalizeSuiAddress(input.owner))) {
203
- throw new Error('Invalid Sui address')
204
- }
205
-
206
- const filter = input.filter
207
- ? {
208
- ...input.filter,
209
- }
210
- : void 0
211
- return await this.transport.request({
212
- method: 'suix_getOwnedObjects',
213
- params: [
214
- input.owner,
215
- {
216
- filter,
217
- options: input.options,
218
- },
219
- input.cursor,
220
- input.limit,
221
- ],
222
- signal: input.signal,
223
- })
224
- }
225
-
226
- /**
227
- * Get details about an object
228
- */
229
- async getObject(input) {
230
- if (!input.id || !isValidSuiObjectId(normalizeSuiObjectId(input.id))) {
231
- throw new Error('Invalid Sui Object id')
232
- }
233
-
234
- return await this.transport.request({
235
- method: 'sui_getObject',
236
- params: [input.id, input.options],
237
- signal: input.signal,
238
- })
239
- }
240
-
241
- async tryGetPastObject(input) {
242
- return await this.transport.request({
243
- method: 'sui_tryGetPastObject',
244
- params: [input.id, input.version, input.options],
245
- signal: input.signal,
246
- })
247
- }
248
-
249
- /**
250
- * Batch get details about a list of objects. If any of the object ids are duplicates the call will fail
251
- */
252
- async multiGetObjects(input) {
253
- input.ids.forEach((id) => {
254
- if (!id || !isValidSuiObjectId(normalizeSuiObjectId(id))) {
255
- throw new Error(`Invalid Sui Object id ${id}`)
256
- }
257
- })
258
- const hasDuplicates = input.ids.length !== new Set(input.ids).size
259
- if (hasDuplicates) {
260
- throw new Error(`Duplicate object ids in batch call ${input.ids}`)
261
- }
262
-
263
- return await this.transport.request({
264
- method: 'sui_multiGetObjects',
265
- params: [input.ids, input.options],
266
- signal: input.signal,
267
- })
268
- }
269
-
270
- /**
271
- * Get transaction blocks for a given query criteria
272
- */
273
- async queryTransactionBlocks({ filter, options, cursor, limit, order, signal }) {
274
- return await this.transport.request({
275
- method: 'suix_queryTransactionBlocks',
276
- params: [
277
- {
278
- filter,
279
- options,
280
- },
281
- cursor,
282
- limit,
283
- (order || 'descending') === 'descending',
284
- ],
285
- signal,
286
- })
287
- }
288
-
289
- async getTransactionBlock(input) {
290
- if (!isValidTransactionDigest(input.digest)) {
291
- throw new Error('Invalid Transaction digest')
292
- }
293
-
294
- return await this.transport.request({
295
- method: 'sui_getTransactionBlock',
296
- params: [input.digest, input.options],
297
- signal: input.signal,
298
- })
299
- }
300
-
301
- async multiGetTransactionBlocks(input) {
302
- input.digests.forEach((d) => {
303
- if (!isValidTransactionDigest(d)) {
304
- throw new Error(`Invalid Transaction digest ${d}`)
305
- }
306
- })
307
- const hasDuplicates = input.digests.length !== new Set(input.digests).size
308
- if (hasDuplicates) {
309
- throw new Error(`Duplicate digests in batch call ${input.digests}`)
310
- }
311
-
312
- return await this.transport.request({
313
- method: 'sui_multiGetTransactionBlocks',
314
- params: [input.digests, input.options],
315
- signal: input.signal,
316
- })
317
- }
318
-
319
- async executeTransactionBlock({ transactionBlock, signature, options, requestType, signal }) {
320
- const result = await this.transport.request({
321
- method: 'sui_executeTransactionBlock',
322
- params: [
323
- typeof transactionBlock === 'string' ? transactionBlock : toBase64(transactionBlock),
324
- Array.isArray(signature) ? signature : [signature],
325
- options,
326
- ],
327
- signal,
328
- })
329
- if (requestType === 'WaitForLocalExecution') {
330
- try {
331
- await this.waitForTransaction({
332
- digest: result.digest,
333
- })
334
- } catch {}
335
- }
336
-
337
- return result
338
- }
339
-
340
- async signAndExecuteTransaction({ transaction, signer, ...input }) {
341
- let transactionBytes
342
- if (transaction instanceof Uint8Array) {
343
- transactionBytes = transaction
344
- } else {
345
- transaction.setSenderIfNotSet(signer.toSuiAddress())
346
- transactionBytes = await transaction.build({ client: this })
347
- }
348
-
349
- const { signature, bytes } = await signer.signTransaction(transactionBytes)
350
- return this.executeTransactionBlock({
351
- transactionBlock: bytes,
352
- signature,
353
- ...input,
354
- })
355
- }
356
-
357
- /**
358
- * Get total number of transactions
359
- */
360
- async getTotalTransactionBlocks({ signal } = Object.create(null)) {
361
- const resp = await this.transport.request({
362
- method: 'sui_getTotalTransactionBlocks',
363
- params: [],
364
- signal,
365
- })
366
- return BigInt(resp)
367
- }
368
-
369
- /**
370
- * Getting the reference gas price for the network
371
- */
372
- async getReferenceGasPrice({ signal } = Object.create(null)) {
373
- const resp = await this.transport.request({
374
- method: 'suix_getReferenceGasPrice',
375
- params: [],
376
- signal,
377
- })
378
- return BigInt(resp)
379
- }
380
-
381
- /**
382
- * Return the delegated stakes for an address
383
- */
384
- async getStakes(input) {
385
- if (!input.owner || !isValidSuiAddress(normalizeSuiAddress(input.owner))) {
386
- throw new Error('Invalid Sui address')
387
- }
388
-
389
- return await this.transport.request({
390
- method: 'suix_getStakes',
391
- params: [input.owner],
392
- signal: input.signal,
393
- })
394
- }
395
-
396
- /**
397
- * Return the delegated stakes queried by id.
398
- */
399
- async getStakesByIds(input) {
400
- input.stakedSuiIds.forEach((id) => {
401
- if (!id || !isValidSuiObjectId(normalizeSuiObjectId(id))) {
402
- throw new Error(`Invalid Sui Stake id ${id}`)
403
- }
404
- })
405
- return await this.transport.request({
406
- method: 'suix_getStakesByIds',
407
- params: [input.stakedSuiIds],
408
- signal: input.signal,
409
- })
410
- }
411
-
412
- /**
413
- * Return the latest system state content.
414
- */
415
- async getLatestSuiSystemState({ signal } = Object.create(null)) {
416
- return await this.transport.request({
417
- method: 'suix_getLatestSuiSystemState',
418
- params: [],
419
- signal,
420
- })
421
- }
422
-
423
- /**
424
- * Get events for a given query criteria
425
- */
426
- async queryEvents({ query, cursor, limit, order, signal }) {
427
- return await this.transport.request({
428
- method: 'suix_queryEvents',
429
- params: [query, cursor, limit, (order || 'descending') === 'descending'],
430
- signal,
431
- })
432
- }
433
-
434
- /**
435
- * Runs the transaction block in dev-inspect mode. Which allows for nearly any
436
- * transaction (or Move call) with any arguments. Detailed results are
437
- * provided, including both the transaction effects and any return values.
438
- */
439
- async devInspectTransactionBlock(input) {
440
- let devInspectTxBytes
441
- if (isTransaction(input.transactionBlock)) {
442
- input.transactionBlock.setSenderIfNotSet(input.sender)
443
- devInspectTxBytes = toBase64(
444
- await input.transactionBlock.build({
445
- client: this,
446
- onlyTransactionKind: true,
447
- })
448
- )
449
- } else if (typeof input.transactionBlock === 'string') {
450
- devInspectTxBytes = input.transactionBlock
451
- } else if (input.transactionBlock instanceof Uint8Array) {
452
- devInspectTxBytes = toBase64(input.transactionBlock)
453
- } else {
454
- throw new TypeError('Unknown transaction block format.')
455
- }
456
-
457
- input.signal?.throwIfAborted()
458
- return await this.transport.request({
459
- method: 'sui_devInspectTransactionBlock',
460
- params: [input.sender, devInspectTxBytes, input.gasPrice?.toString(), input.epoch],
461
- signal: input.signal,
462
- })
463
- }
464
-
465
- /**
466
- * Dry run a transaction block and return the result.
467
- */
468
- async dryRunTransactionBlock(input) {
469
- return await this.transport.request({
470
- method: 'sui_dryRunTransactionBlock',
471
- params: [
472
- typeof input.transactionBlock === 'string'
473
- ? input.transactionBlock
474
- : toBase64(input.transactionBlock),
475
- ],
476
- })
477
- }
478
-
479
- /**
480
- * Return the list of dynamic field objects owned by an object
481
- */
482
- async getDynamicFields(input) {
483
- if (!input.parentId || !isValidSuiObjectId(normalizeSuiObjectId(input.parentId))) {
484
- throw new Error('Invalid Sui Object id')
485
- }
486
-
487
- return await this.transport.request({
488
- method: 'suix_getDynamicFields',
489
- params: [input.parentId, input.cursor, input.limit],
490
- signal: input.signal,
491
- })
492
- }
493
-
494
- /**
495
- * Return the dynamic field object information for a specified object
496
- */
497
- async getDynamicFieldObject(input) {
498
- return await this.transport.request({
499
- method: 'suix_getDynamicFieldObject',
500
- params: [input.parentId, input.name],
501
- signal: input.signal,
502
- })
503
- }
504
-
505
- /**
506
- * Get the sequence number of the latest checkpoint that has been executed
507
- */
508
- async getLatestCheckpointSequenceNumber({ signal } = Object.create(null)) {
509
- const resp = await this.transport.request({
510
- method: 'sui_getLatestCheckpointSequenceNumber',
511
- params: [],
512
- signal,
513
- })
514
- return String(resp)
515
- }
516
-
517
- /**
518
- * Returns information about a given checkpoint
519
- */
520
- async getCheckpoint(input) {
521
- return await this.transport.request({
522
- method: 'sui_getCheckpoint',
523
- params: [input.id],
524
- signal: input.signal,
525
- })
526
- }
527
-
528
- /**
529
- * Returns historical checkpoints paginated
530
- */
531
- async getCheckpoints(input) {
532
- return await this.transport.request({
533
- method: 'sui_getCheckpoints',
534
- params: [input.cursor, input?.limit, input.descendingOrder],
535
- signal: input.signal,
536
- })
537
- }
538
-
539
- /**
540
- * Return the committee information for the asked epoch
541
- */
542
- async getCommitteeInfo(input) {
543
- return await this.transport.request({
544
- method: 'suix_getCommitteeInfo',
545
- params: [input?.epoch],
546
- signal: input?.signal,
547
- })
548
- }
549
-
550
- async getNetworkMetrics({ signal } = Object.create(null)) {
551
- return await this.transport.request({
552
- method: 'suix_getNetworkMetrics',
553
- params: [],
554
- signal,
555
- })
556
- }
557
-
558
- async getAddressMetrics({ signal } = Object.create(null)) {
559
- return await this.transport.request({
560
- method: 'suix_getLatestAddressMetrics',
561
- params: [],
562
- signal,
563
- })
564
- }
565
-
566
- async getEpochMetrics(input) {
567
- return await this.transport.request({
568
- method: 'suix_getEpochMetrics',
569
- params: [input?.cursor, input?.limit, input?.descendingOrder],
570
- signal: input?.signal,
571
- })
572
- }
573
-
574
- async getAllEpochAddressMetrics(input) {
575
- return await this.transport.request({
576
- method: 'suix_getAllEpochAddressMetrics',
577
- params: [input?.descendingOrder],
578
- signal: input?.signal,
579
- })
580
- }
581
-
582
- /**
583
- * Return the committee information for the asked epoch
584
- */
585
- async getEpochs(input) {
586
- return await this.transport.request({
587
- method: 'suix_getEpochs',
588
- params: [input?.cursor, input?.limit, input?.descendingOrder],
589
- signal: input?.signal,
590
- })
591
- }
592
-
593
- /**
594
- * Returns list of top move calls by usage
595
- */
596
- async getMoveCallMetrics({ signal } = Object.create(null)) {
597
- return await this.transport.request({
598
- method: 'suix_getMoveCallMetrics',
599
- params: [],
600
- signal,
601
- })
602
- }
603
-
604
- /**
605
- * Return the committee information for the asked epoch
606
- */
607
- async getCurrentEpoch({ signal } = Object.create(null)) {
608
- return await this.transport.request({
609
- method: 'suix_getCurrentEpoch',
610
- params: [],
611
- signal,
612
- })
613
- }
614
-
615
- /**
616
- * Return the Validators APYs
617
- */
618
- async getValidatorsApy({ signal } = Object.create(null)) {
619
- return await this.transport.request({
620
- method: 'suix_getValidatorsApy',
621
- params: [],
622
- signal,
623
- })
624
- }
625
-
626
- // TODO: Migrate this to `sui_getChainIdentifier` once it is widely available.
627
- async getChainIdentifier({ signal } = Object.create(null)) {
628
- const checkpoint = await this.getCheckpoint({ id: '0', signal })
629
- const bytes = fromBase58(checkpoint.digest)
630
- return toHex(bytes.slice(0, 4))
631
- }
632
-
633
- async getProtocolConfig(input) {
634
- return await this.transport.request({
635
- method: 'sui_getProtocolConfig',
636
- params: [input?.version],
637
- signal: input?.signal,
638
- })
639
- }
640
-
641
- /**
642
- * Wait for a transaction block result to be available over the API.
643
- * This can be used in conjunction with `executeTransactionBlock` to wait for the transaction to
644
- * be available via the API.
645
- * This currently polls the `getTransactionBlock` API to check for the transaction.
646
- */
647
- async waitForTransaction({ signal, timeout = 60 * 1e3, pollInterval = 2 * 1e3, ...input }) {
648
- const timeoutSignal = AbortSignal.timeout(timeout)
649
- // eslint-disable-next-line promise/param-names
650
- const timeoutPromise = new Promise((_, reject) => {
651
- timeoutSignal.addEventListener('abort', () => reject(timeoutSignal.reason))
652
- })
653
- timeoutPromise.catch(() => {})
654
- while (!timeoutSignal.aborted) {
655
- signal?.throwIfAborted()
656
- try {
657
- return await this.getTransactionBlock(input)
658
- } catch {
659
- await Promise.race([
660
- new Promise((resolve) => setTimeout(resolve, pollInterval)),
661
- timeoutPromise,
662
- ])
663
- }
664
- }
665
-
666
- timeoutSignal.throwIfAborted()
667
- throw new Error('Unexpected error while waiting for transaction block.')
668
- }
669
-
670
- experimental_asClientExtension() {
671
- return {
672
- name: 'jsonRPC',
673
- register: () => {
674
- return this
675
- },
676
- }
677
- }
678
- }
679
- export { SuiClient }
680
- // # sourceMappingURL=client.js.map
@@ -1,38 +0,0 @@
1
- const CODE_TO_ERROR_TYPE = {
2
- '-32700': 'ParseError',
3
- '-32701': 'OversizedRequest',
4
- '-32702': 'OversizedResponse',
5
- '-32600': 'InvalidRequest',
6
- '-32601': 'MethodNotFound',
7
- '-32602': 'InvalidParams',
8
- '-32603': 'InternalError',
9
- '-32604': 'ServerBusy',
10
- '-32000': 'CallExecutionFailed',
11
- '-32001': 'UnknownError',
12
- '-32003': 'SubscriptionClosed',
13
- '-32004': 'SubscriptionClosedWithError',
14
- '-32005': 'BatchesNotSupported',
15
- '-32006': 'TooManySubscriptions',
16
- '-32050': 'TransientError',
17
- '-32002': 'TransactionExecutionClientError',
18
- }
19
-
20
- class SuiHTTPTransportError extends Error {}
21
-
22
- class JsonRpcError extends SuiHTTPTransportError {
23
- constructor(message, code) {
24
- super(message)
25
- this.code = code
26
- this.type = CODE_TO_ERROR_TYPE[code] ?? 'ServerError'
27
- }
28
- }
29
-
30
- class SuiHTTPStatusError extends SuiHTTPTransportError {
31
- constructor(message, status, statusText) {
32
- super(message)
33
- this.status = status
34
- this.statusText = statusText
35
- }
36
- }
37
- export { JsonRpcError, SuiHTTPStatusError }
38
- // # sourceMappingURL=errors.js.map