@exodus/sui-api 1.2.0 → 1.2.2
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 +18 -0
- package/package.json +4 -4
- package/src/vendors/client/client.js +0 -145
- package/src/vendors/experimental/core.js +0 -12
- package/src/vendors/experimental/transports/jsonRPC.js +2 -2
- package/src/vendors/transactions/Transaction.js +0 -2
- package/src/vendors/transactions/data/internal.js +2 -1
- package/src/vendors/transactions/hash.js +2 -0
- package/src/vendors/experimental/mvr.js +0 -489
- package/src/vendors/transactions/plugins/NamedPackagesPlugin.js +0 -49
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,24 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [1.2.2](https://github.com/ExodusMovement/assets/compare/@exodus/sui-api@1.2.1...@exodus/sui-api@1.2.2) (2026-06-04)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @exodus/sui-api
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [1.2.1](https://github.com/ExodusMovement/assets/compare/@exodus/sui-api@1.2.0...@exodus/sui-api@1.2.1) (2026-04-23)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
* fix(sui-api): use BigInt literal for u64 upper bound check (#7748)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
6
24
|
## [1.2.0](https://github.com/ExodusMovement/assets/compare/@exodus/sui-api@1.1.3...@exodus/sui-api@1.2.0) (2026-01-06)
|
|
7
25
|
|
|
8
26
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/sui-api",
|
|
3
3
|
"packageManager": "yarn@4.3.1",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.2",
|
|
5
5
|
"description": "Transaction monitors, RPC with the blockchain node, and other networking code for Sui",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "src/index.js",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"@exodus/basic-utils": "^3.1.0",
|
|
30
30
|
"@exodus/crypto": "^1.0.0-rc.26",
|
|
31
31
|
"@exodus/currency": "^6.0.1",
|
|
32
|
-
"@exodus/models": "^
|
|
32
|
+
"@exodus/models": "^13.0.0",
|
|
33
33
|
"@exodus/sui-lib": "^1.3.0",
|
|
34
34
|
"@exodus/sui-meta": "^1.2.0",
|
|
35
35
|
"bn.js": "^5.2.1",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"url-join": "^4.0.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@exodus/asset": "^2.
|
|
42
|
+
"@exodus/asset": "^2.3.0",
|
|
43
43
|
"@exodus/assets-testing": "^1.0.0"
|
|
44
44
|
},
|
|
45
45
|
"homepage": "https://github.com/ExodusMovement/assets/tree/master/sui/sui-api",
|
|
@@ -50,5 +50,5 @@
|
|
|
50
50
|
"type": "git",
|
|
51
51
|
"url": "git+https://github.com/ExodusMovement/assets.git"
|
|
52
52
|
},
|
|
53
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "575705152d40034e99f61290312f85e2466ad84f"
|
|
54
54
|
}
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
import { vendorLib } from '@exodus/sui-lib'
|
|
5
5
|
|
|
6
6
|
import { Experimental_BaseClient } from '../experimental/client.js'
|
|
7
|
-
import { hasMvrName } from '../experimental/mvr.js'
|
|
8
7
|
import { JSONRpcTransport } from '../experimental/transports/jsonRPC.js'
|
|
9
8
|
import { isTransaction } from '../transactions/Transaction.js'
|
|
10
9
|
import { SuiHTTPTransport } from './http-transport.js'
|
|
@@ -19,8 +18,6 @@ const {
|
|
|
19
18
|
normalizeSuiObjectId,
|
|
20
19
|
} = vendorLib.utils
|
|
21
20
|
|
|
22
|
-
const { isValidNamedPackage } = vendorLib.utils
|
|
23
|
-
|
|
24
21
|
const SUI_CLIENT_BRAND = Symbol.for('@mysten/SuiClient')
|
|
25
22
|
|
|
26
23
|
class SuiClient extends Experimental_BaseClient {
|
|
@@ -35,7 +32,6 @@ class SuiClient extends Experimental_BaseClient {
|
|
|
35
32
|
this.transport = options.transport ?? new SuiHTTPTransport({ url: options.url })
|
|
36
33
|
this.core = new JSONRpcTransport({
|
|
37
34
|
jsonRpcClient: this,
|
|
38
|
-
mvr: options.mvr,
|
|
39
35
|
})
|
|
40
36
|
}
|
|
41
37
|
|
|
@@ -60,14 +56,6 @@ class SuiClient extends Experimental_BaseClient {
|
|
|
60
56
|
throw new Error('Invalid Sui address')
|
|
61
57
|
}
|
|
62
58
|
|
|
63
|
-
if (coinType && hasMvrName(coinType)) {
|
|
64
|
-
coinType = (
|
|
65
|
-
await this.core.mvr.resolveType({
|
|
66
|
-
type: coinType,
|
|
67
|
-
})
|
|
68
|
-
).type
|
|
69
|
-
}
|
|
70
|
-
|
|
71
59
|
return await this.transport.request({
|
|
72
60
|
method: 'suix_getCoins',
|
|
73
61
|
params: [owner, coinType, cursor, limit],
|
|
@@ -98,14 +86,6 @@ class SuiClient extends Experimental_BaseClient {
|
|
|
98
86
|
throw new Error('Invalid Sui address')
|
|
99
87
|
}
|
|
100
88
|
|
|
101
|
-
if (coinType && hasMvrName(coinType)) {
|
|
102
|
-
coinType = (
|
|
103
|
-
await this.core.mvr.resolveType({
|
|
104
|
-
type: coinType,
|
|
105
|
-
})
|
|
106
|
-
).type
|
|
107
|
-
}
|
|
108
|
-
|
|
109
89
|
return await this.transport.request({
|
|
110
90
|
method: 'suix_getBalance',
|
|
111
91
|
params: [owner, coinType],
|
|
@@ -132,14 +112,6 @@ class SuiClient extends Experimental_BaseClient {
|
|
|
132
112
|
* Fetch CoinMetadata for a given coin type
|
|
133
113
|
*/
|
|
134
114
|
async getCoinMetadata({ coinType, signal }) {
|
|
135
|
-
if (coinType && hasMvrName(coinType)) {
|
|
136
|
-
coinType = (
|
|
137
|
-
await this.core.mvr.resolveType({
|
|
138
|
-
type: coinType,
|
|
139
|
-
})
|
|
140
|
-
).type
|
|
141
|
-
}
|
|
142
|
-
|
|
143
115
|
return await this.transport.request({
|
|
144
116
|
method: 'suix_getCoinMetadata',
|
|
145
117
|
params: [coinType],
|
|
@@ -151,14 +123,6 @@ class SuiClient extends Experimental_BaseClient {
|
|
|
151
123
|
* Fetch total supply for a coin
|
|
152
124
|
*/
|
|
153
125
|
async getTotalSupply({ coinType, signal }) {
|
|
154
|
-
if (coinType && hasMvrName(coinType)) {
|
|
155
|
-
coinType = (
|
|
156
|
-
await this.core.mvr.resolveType({
|
|
157
|
-
type: coinType,
|
|
158
|
-
})
|
|
159
|
-
).type
|
|
160
|
-
}
|
|
161
|
-
|
|
162
126
|
return await this.transport.request({
|
|
163
127
|
method: 'suix_getTotalSupply',
|
|
164
128
|
params: [coinType],
|
|
@@ -179,14 +143,6 @@ class SuiClient extends Experimental_BaseClient {
|
|
|
179
143
|
* Get Move function argument types like read, write and full access
|
|
180
144
|
*/
|
|
181
145
|
async getMoveFunctionArgTypes({ package: pkg, module, function: fn, signal }) {
|
|
182
|
-
if (pkg && isValidNamedPackage(pkg)) {
|
|
183
|
-
pkg = (
|
|
184
|
-
await this.core.mvr.resolvePackage({
|
|
185
|
-
package: pkg,
|
|
186
|
-
})
|
|
187
|
-
).package
|
|
188
|
-
}
|
|
189
|
-
|
|
190
146
|
return await this.transport.request({
|
|
191
147
|
method: 'sui_getMoveFunctionArgTypes',
|
|
192
148
|
params: [pkg, module, fn],
|
|
@@ -199,14 +155,6 @@ class SuiClient extends Experimental_BaseClient {
|
|
|
199
155
|
* structured representations of Move modules
|
|
200
156
|
*/
|
|
201
157
|
async getNormalizedMoveModulesByPackage({ package: pkg, signal }) {
|
|
202
|
-
if (pkg && isValidNamedPackage(pkg)) {
|
|
203
|
-
pkg = (
|
|
204
|
-
await this.core.mvr.resolvePackage({
|
|
205
|
-
package: pkg,
|
|
206
|
-
})
|
|
207
|
-
).package
|
|
208
|
-
}
|
|
209
|
-
|
|
210
158
|
return await this.transport.request({
|
|
211
159
|
method: 'sui_getNormalizedMoveModulesByPackage',
|
|
212
160
|
params: [pkg],
|
|
@@ -218,14 +166,6 @@ class SuiClient extends Experimental_BaseClient {
|
|
|
218
166
|
* Get a structured representation of Move module
|
|
219
167
|
*/
|
|
220
168
|
async getNormalizedMoveModule({ package: pkg, module, signal }) {
|
|
221
|
-
if (pkg && isValidNamedPackage(pkg)) {
|
|
222
|
-
pkg = (
|
|
223
|
-
await this.core.mvr.resolvePackage({
|
|
224
|
-
package: pkg,
|
|
225
|
-
})
|
|
226
|
-
).package
|
|
227
|
-
}
|
|
228
|
-
|
|
229
169
|
return await this.transport.request({
|
|
230
170
|
method: 'sui_getNormalizedMoveModule',
|
|
231
171
|
params: [pkg, module],
|
|
@@ -237,14 +177,6 @@ class SuiClient extends Experimental_BaseClient {
|
|
|
237
177
|
* Get a structured representation of Move function
|
|
238
178
|
*/
|
|
239
179
|
async getNormalizedMoveFunction({ package: pkg, module, function: fn, signal }) {
|
|
240
|
-
if (pkg && isValidNamedPackage(pkg)) {
|
|
241
|
-
pkg = (
|
|
242
|
-
await this.core.mvr.resolvePackage({
|
|
243
|
-
package: pkg,
|
|
244
|
-
})
|
|
245
|
-
).package
|
|
246
|
-
}
|
|
247
|
-
|
|
248
180
|
return await this.transport.request({
|
|
249
181
|
method: 'sui_getNormalizedMoveFunction',
|
|
250
182
|
params: [pkg, module, fn],
|
|
@@ -256,14 +188,6 @@ class SuiClient extends Experimental_BaseClient {
|
|
|
256
188
|
* Get a structured representation of Move struct
|
|
257
189
|
*/
|
|
258
190
|
async getNormalizedMoveStruct({ package: pkg, module, struct, signal }) {
|
|
259
|
-
if (pkg && isValidNamedPackage(pkg)) {
|
|
260
|
-
pkg = (
|
|
261
|
-
await this.core.mvr.resolvePackage({
|
|
262
|
-
package: pkg,
|
|
263
|
-
})
|
|
264
|
-
).package
|
|
265
|
-
}
|
|
266
|
-
|
|
267
191
|
return await this.transport.request({
|
|
268
192
|
method: 'sui_getNormalizedMoveStruct',
|
|
269
193
|
params: [pkg, module, struct],
|
|
@@ -284,23 +208,6 @@ class SuiClient extends Experimental_BaseClient {
|
|
|
284
208
|
...input.filter,
|
|
285
209
|
}
|
|
286
210
|
: void 0
|
|
287
|
-
if (filter && 'MoveModule' in filter && isValidNamedPackage(filter.MoveModule.package)) {
|
|
288
|
-
filter.MoveModule = {
|
|
289
|
-
module: filter.MoveModule.module,
|
|
290
|
-
package: (
|
|
291
|
-
await this.core.mvr.resolvePackage({
|
|
292
|
-
package: filter.MoveModule.package,
|
|
293
|
-
})
|
|
294
|
-
).package,
|
|
295
|
-
}
|
|
296
|
-
} else if (filter && 'StructType' in filter && hasMvrName(filter.StructType)) {
|
|
297
|
-
filter.StructType = (
|
|
298
|
-
await this.core.mvr.resolveType({
|
|
299
|
-
type: filter.StructType,
|
|
300
|
-
})
|
|
301
|
-
).type
|
|
302
|
-
}
|
|
303
|
-
|
|
304
211
|
return await this.transport.request({
|
|
305
212
|
method: 'suix_getOwnedObjects',
|
|
306
213
|
params: [
|
|
@@ -364,19 +271,6 @@ class SuiClient extends Experimental_BaseClient {
|
|
|
364
271
|
* Get transaction blocks for a given query criteria
|
|
365
272
|
*/
|
|
366
273
|
async queryTransactionBlocks({ filter, options, cursor, limit, order, signal }) {
|
|
367
|
-
if (filter && 'MoveFunction' in filter && isValidNamedPackage(filter.MoveFunction.package)) {
|
|
368
|
-
filter = {
|
|
369
|
-
...filter,
|
|
370
|
-
MoveFunction: {
|
|
371
|
-
package: (
|
|
372
|
-
await this.core.mvr.resolvePackage({
|
|
373
|
-
package: filter.MoveFunction.package,
|
|
374
|
-
})
|
|
375
|
-
).package,
|
|
376
|
-
},
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
|
|
380
274
|
return await this.transport.request({
|
|
381
275
|
method: 'suix_queryTransactionBlocks',
|
|
382
276
|
params: [
|
|
@@ -530,45 +424,6 @@ class SuiClient extends Experimental_BaseClient {
|
|
|
530
424
|
* Get events for a given query criteria
|
|
531
425
|
*/
|
|
532
426
|
async queryEvents({ query, cursor, limit, order, signal }) {
|
|
533
|
-
if (query && 'MoveEventType' in query && hasMvrName(query.MoveEventType)) {
|
|
534
|
-
query = {
|
|
535
|
-
...query,
|
|
536
|
-
MoveEventType: (
|
|
537
|
-
await this.core.mvr.resolveType({
|
|
538
|
-
type: query.MoveEventType,
|
|
539
|
-
})
|
|
540
|
-
).type,
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
if (query && 'MoveEventModule' in query && isValidNamedPackage(query.MoveEventModule.package)) {
|
|
545
|
-
query = {
|
|
546
|
-
...query,
|
|
547
|
-
MoveEventModule: {
|
|
548
|
-
module: query.MoveEventModule.module,
|
|
549
|
-
package: (
|
|
550
|
-
await this.core.mvr.resolvePackage({
|
|
551
|
-
package: query.MoveEventModule.package,
|
|
552
|
-
})
|
|
553
|
-
).package,
|
|
554
|
-
},
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
if ('MoveModule' in query && isValidNamedPackage(query.MoveModule.package)) {
|
|
559
|
-
query = {
|
|
560
|
-
...query,
|
|
561
|
-
MoveModule: {
|
|
562
|
-
module: query.MoveModule.module,
|
|
563
|
-
package: (
|
|
564
|
-
await this.core.mvr.resolvePackage({
|
|
565
|
-
package: query.MoveModule.package,
|
|
566
|
-
})
|
|
567
|
-
).package,
|
|
568
|
-
},
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
|
|
572
427
|
return await this.transport.request({
|
|
573
428
|
method: 'suix_queryEvents',
|
|
574
429
|
params: [query, cursor, limit, (order || 'descending') === 'descending'],
|
|
@@ -1,23 +1,11 @@
|
|
|
1
1
|
/* eslint-disable camelcase */
|
|
2
2
|
|
|
3
3
|
import { Experimental_BaseClient } from './client.js'
|
|
4
|
-
import { MvrClient } from './mvr.js'
|
|
5
|
-
|
|
6
|
-
const DEFAULT_MVR_URLS = {
|
|
7
|
-
mainnet: 'https://mainnet.mvr.mystenlabs.com',
|
|
8
|
-
testnet: 'https://testnet.mvr.mystenlabs.com',
|
|
9
|
-
}
|
|
10
4
|
|
|
11
5
|
class Experimental_CoreClient extends Experimental_BaseClient {
|
|
12
6
|
constructor(options) {
|
|
13
7
|
super(options)
|
|
14
8
|
this.core = this
|
|
15
|
-
this.mvr = new MvrClient({
|
|
16
|
-
cache: this.cache.scope('core.mvr'),
|
|
17
|
-
url: options.mvr?.url ?? DEFAULT_MVR_URLS[this.network],
|
|
18
|
-
pageSize: options.mvr?.pageSize,
|
|
19
|
-
overrides: options.mvr?.overrides,
|
|
20
|
-
})
|
|
21
9
|
}
|
|
22
10
|
}
|
|
23
11
|
export { Experimental_CoreClient }
|
|
@@ -10,8 +10,8 @@ const { bcs } = vendorLib
|
|
|
10
10
|
export class JSONRpcTransport extends Experimental_CoreClient {
|
|
11
11
|
#jsonRpcClient
|
|
12
12
|
|
|
13
|
-
constructor({ jsonRpcClient
|
|
14
|
-
super({ network: jsonRpcClient.network, base: jsonRpcClient
|
|
13
|
+
constructor({ jsonRpcClient }) {
|
|
14
|
+
super({ network: jsonRpcClient.network, base: jsonRpcClient })
|
|
15
15
|
this.#jsonRpcClient = jsonRpcClient
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -8,7 +8,6 @@ import { Argument, NormalizedCallArg, ObjectRef, TransactionExpiration } from '.
|
|
|
8
8
|
import { SerializedTransactionDataV2 } from './data/v2.js'
|
|
9
9
|
import { Inputs } from './Inputs.js'
|
|
10
10
|
import { createObjectMethods } from './object.js'
|
|
11
|
-
import { namedPackagesPlugin } from './plugins/NamedPackagesPlugin.js'
|
|
12
11
|
import { createPure } from './pure.js'
|
|
13
12
|
import { needsTransactionResolution, resolveTransactionPlugin } from './resolve.js'
|
|
14
13
|
import { TransactionDataBuilder } from './TransactionData.js'
|
|
@@ -609,7 +608,6 @@ const _Transaction = class _Transaction {
|
|
|
609
608
|
steps.push(__privateGet(this, _intentResolvers).get(intent))
|
|
610
609
|
}
|
|
611
610
|
|
|
612
|
-
steps.push(namedPackagesPlugin())
|
|
613
611
|
await __privateMethod(this, _Transaction_instances, runPlugins_fn).call(this, steps, options)
|
|
614
612
|
}
|
|
615
613
|
}
|
|
@@ -41,12 +41,13 @@ const SuiAddress = pipe(
|
|
|
41
41
|
)
|
|
42
42
|
const ObjectID = SuiAddress
|
|
43
43
|
const BCSBytes = string()
|
|
44
|
+
const U64_UPPER_BOUND = BigInt(2) ** BigInt(64)
|
|
44
45
|
const JsonU64 = pipe(
|
|
45
46
|
union([string(), pipe(number(), integer())]),
|
|
46
47
|
check((val) => {
|
|
47
48
|
try {
|
|
48
49
|
BigInt(val)
|
|
49
|
-
return BigInt(val) >= 0 && BigInt(val)
|
|
50
|
+
return BigInt(val) >= 0 && BigInt(val) < U64_UPPER_BOUND
|
|
50
51
|
} catch {
|
|
51
52
|
return false
|
|
52
53
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// eslint-disable-next-line @exodus/import/no-deprecated
|
|
1
2
|
import { hashSync } from '@exodus/crypto/hash'
|
|
2
3
|
|
|
3
4
|
function hashTypedData(typeTag, data) {
|
|
@@ -6,6 +7,7 @@ function hashTypedData(typeTag, data) {
|
|
|
6
7
|
const dataWithTag = new Uint8Array(typeTagBytes.length + data.length)
|
|
7
8
|
dataWithTag.set(typeTagBytes)
|
|
8
9
|
dataWithTag.set(data, typeTagBytes.length)
|
|
10
|
+
// eslint-disable-next-line @exodus/import/no-deprecated
|
|
9
11
|
return hashSync('blake2b256', dataWithTag)
|
|
10
12
|
}
|
|
11
13
|
|
|
@@ -1,489 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-sequences */
|
|
2
|
-
/* eslint-disable camelcase */
|
|
3
|
-
import { vendorLib } from '@exodus/sui-lib'
|
|
4
|
-
|
|
5
|
-
const { chunk, DataLoader } = vendorLib.utils
|
|
6
|
-
const {
|
|
7
|
-
isValidNamedPackage,
|
|
8
|
-
isValidNamedType,
|
|
9
|
-
isValidSuiAddress,
|
|
10
|
-
normalizeStructTag,
|
|
11
|
-
normalizeSuiAddress,
|
|
12
|
-
parseStructTag,
|
|
13
|
-
} = vendorLib.utils
|
|
14
|
-
|
|
15
|
-
const MOVE_IDENT = /^[A-Z_a-z]\w*$/
|
|
16
|
-
|
|
17
|
-
// Strict .sui domain (labels a-z0-9 and '-', no leading/trailing '-')
|
|
18
|
-
const SUI_DOMAIN_RE = /^(?=.{1,253}$)(?:[\da-z](?:[\da-z-]{0,61}[\da-z])?\.)+sui$/i
|
|
19
|
-
|
|
20
|
-
// Sui address helpers
|
|
21
|
-
function isEvenHexDigits(hex) {
|
|
22
|
-
return /^[\dA-Fa-f]+$/.test(hex) && hex.length > 0 && hex.length % 2 === 0
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Pre-normalization: 1..64 hex digits (<=32 bytes), even length, 0x prefixed
|
|
26
|
-
function isSuiAddressLoose(addr) {
|
|
27
|
-
if (!/^0x[\dA-Fa-f]+$/.test(addr)) return false
|
|
28
|
-
const hex = addr.slice(2)
|
|
29
|
-
return isEvenHexDigits(hex) && hex.length <= 64
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
var __typeError = (msg) => {
|
|
33
|
-
throw new TypeError(msg)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError('Cannot ' + msg)
|
|
37
|
-
var __privateGet = (obj, member, getter) => (
|
|
38
|
-
__accessCheck(obj, member, 'read from private field'), getter ? getter.call(obj) : member.get(obj)
|
|
39
|
-
)
|
|
40
|
-
var __privateAdd = (obj, member, value) =>
|
|
41
|
-
member.has(obj)
|
|
42
|
-
? __typeError('Cannot add the same private member more than once')
|
|
43
|
-
: member instanceof WeakSet
|
|
44
|
-
? member.add(obj)
|
|
45
|
-
: member.set(obj, value)
|
|
46
|
-
var __privateSet = (obj, member, value, setter) => (
|
|
47
|
-
__accessCheck(obj, member, 'write to private field'),
|
|
48
|
-
setter ? setter.call(obj, value) : member.set(obj, value),
|
|
49
|
-
value
|
|
50
|
-
)
|
|
51
|
-
var __privateMethod = (obj, member, method) => (
|
|
52
|
-
__accessCheck(obj, member, 'access private method'), method
|
|
53
|
-
)
|
|
54
|
-
var _cache,
|
|
55
|
-
_url,
|
|
56
|
-
_pageSize,
|
|
57
|
-
_overrides,
|
|
58
|
-
_MvrClient_instances,
|
|
59
|
-
mvrPackageDataLoader_get,
|
|
60
|
-
mvrTypeDataLoader_get,
|
|
61
|
-
resolvePackages_fn,
|
|
62
|
-
resolveTypes_fn,
|
|
63
|
-
fetch_fn
|
|
64
|
-
|
|
65
|
-
export const PACKAGE_VERSION = '1.36.1'
|
|
66
|
-
export const TARGETED_RPC_VERSION = '1.55.0'
|
|
67
|
-
|
|
68
|
-
const NAME_SEPARATOR = '/'
|
|
69
|
-
const MVR_API_HEADER = {
|
|
70
|
-
'Mvr-Source': `@mysten/sui@${PACKAGE_VERSION}`,
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
class MvrClient {
|
|
74
|
-
constructor({ cache, url, pageSize = 50, overrides }) {
|
|
75
|
-
__privateAdd(this, _MvrClient_instances)
|
|
76
|
-
__privateAdd(this, _cache)
|
|
77
|
-
__privateAdd(this, _url)
|
|
78
|
-
__privateAdd(this, _pageSize)
|
|
79
|
-
__privateAdd(this, _overrides)
|
|
80
|
-
__privateSet(this, _cache, cache)
|
|
81
|
-
__privateSet(this, _url, url)
|
|
82
|
-
__privateSet(this, _pageSize, pageSize)
|
|
83
|
-
__privateSet(this, _overrides, {
|
|
84
|
-
packages: overrides?.packages,
|
|
85
|
-
types: overrides?.types,
|
|
86
|
-
})
|
|
87
|
-
validateOverrides(__privateGet(this, _overrides))
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
async resolvePackage({ package: name }) {
|
|
91
|
-
const resolved = await __privateGet(this, _MvrClient_instances, mvrPackageDataLoader_get).load(
|
|
92
|
-
name
|
|
93
|
-
)
|
|
94
|
-
return {
|
|
95
|
-
package: resolved,
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
async resolveType({ type }) {
|
|
100
|
-
const mvrTypes = [...extractMvrTypes(type)]
|
|
101
|
-
const resolvedTypes = await __privateGet(
|
|
102
|
-
this,
|
|
103
|
-
_MvrClient_instances,
|
|
104
|
-
mvrTypeDataLoader_get
|
|
105
|
-
).loadMany(mvrTypes)
|
|
106
|
-
const typeMap = Object.create(null)
|
|
107
|
-
for (const [i, mvrType] of mvrTypes.entries()) {
|
|
108
|
-
const resolvedType = resolvedTypes[i]
|
|
109
|
-
if (resolvedType instanceof Error) {
|
|
110
|
-
throw resolvedType
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
typeMap[mvrType] = resolvedType
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return {
|
|
117
|
-
type: replaceMvrNames(type, typeMap),
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
async resolve({ types = [], packages = [] }) {
|
|
122
|
-
const mvrTypes = /* @__PURE__ */ new Set()
|
|
123
|
-
for (const type of types ?? []) {
|
|
124
|
-
extractMvrTypes(type, mvrTypes)
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const typesArray = [...mvrTypes]
|
|
128
|
-
const [resolvedTypes, resolvedPackages] = await Promise.all([
|
|
129
|
-
typesArray.length > 0
|
|
130
|
-
? __privateGet(this, _MvrClient_instances, mvrTypeDataLoader_get).loadMany(typesArray)
|
|
131
|
-
: [],
|
|
132
|
-
packages.length > 0
|
|
133
|
-
? __privateGet(this, _MvrClient_instances, mvrPackageDataLoader_get).loadMany(packages)
|
|
134
|
-
: [],
|
|
135
|
-
])
|
|
136
|
-
const typeMap = {
|
|
137
|
-
...__privateGet(this, _overrides)?.types,
|
|
138
|
-
}
|
|
139
|
-
for (const [i, type] of typesArray.entries()) {
|
|
140
|
-
const resolvedType = resolvedTypes[i]
|
|
141
|
-
if (resolvedType instanceof Error) {
|
|
142
|
-
throw resolvedType
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
typeMap[type] = resolvedType
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const replacedTypes = Object.create(null)
|
|
149
|
-
for (const type of types ?? []) {
|
|
150
|
-
const resolvedType = replaceMvrNames(type, typeMap)
|
|
151
|
-
replacedTypes[type] = {
|
|
152
|
-
type: resolvedType,
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const replacedPackages = Object.create(null)
|
|
157
|
-
for (const [i, pkg] of (packages ?? []).entries()) {
|
|
158
|
-
const resolvedPkg = __privateGet(this, _overrides)?.packages?.[pkg] ?? resolvedPackages[i]
|
|
159
|
-
if (resolvedPkg instanceof Error) {
|
|
160
|
-
throw resolvedPkg
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
replacedPackages[pkg] = {
|
|
164
|
-
package: resolvedPkg,
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
return {
|
|
169
|
-
types: replacedTypes,
|
|
170
|
-
packages: replacedPackages,
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
_cache = new WeakMap()
|
|
175
|
-
_url = new WeakMap()
|
|
176
|
-
_pageSize = new WeakMap()
|
|
177
|
-
_overrides = new WeakMap()
|
|
178
|
-
_MvrClient_instances = new WeakSet()
|
|
179
|
-
mvrPackageDataLoader_get = function () {
|
|
180
|
-
return __privateGet(this, _cache).readSync(
|
|
181
|
-
['#mvrPackageDataLoader', __privateGet(this, _url) ?? ''],
|
|
182
|
-
() => {
|
|
183
|
-
const loader = new DataLoader(async (packages) => {
|
|
184
|
-
if (!__privateGet(this, _url)) {
|
|
185
|
-
throw new Error(
|
|
186
|
-
`MVR Api URL is not set for the current client (resolving ${packages.join(', ')})`
|
|
187
|
-
)
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
const resolved = await __privateMethod(this, _MvrClient_instances, resolvePackages_fn).call(
|
|
191
|
-
this,
|
|
192
|
-
packages
|
|
193
|
-
)
|
|
194
|
-
return packages.map(
|
|
195
|
-
(pkg) => resolved[pkg] ?? new Error(`Failed to resolve package: ${pkg}`)
|
|
196
|
-
)
|
|
197
|
-
})
|
|
198
|
-
const overrides = __privateGet(this, _overrides)?.packages
|
|
199
|
-
if (overrides) {
|
|
200
|
-
for (const [pkg, id] of Object.entries(overrides)) {
|
|
201
|
-
loader.prime(pkg, id)
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
return loader
|
|
206
|
-
}
|
|
207
|
-
)
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
mvrTypeDataLoader_get = function () {
|
|
211
|
-
return __privateGet(this, _cache).readSync(
|
|
212
|
-
['#mvrTypeDataLoader', __privateGet(this, _url) ?? ''],
|
|
213
|
-
() => {
|
|
214
|
-
const loader = new DataLoader(async (types) => {
|
|
215
|
-
if (!__privateGet(this, _url)) {
|
|
216
|
-
throw new Error(
|
|
217
|
-
`MVR Api URL is not set for the current client (resolving ${types.join(', ')})`
|
|
218
|
-
)
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
const resolved = await __privateMethod(this, _MvrClient_instances, resolveTypes_fn).call(
|
|
222
|
-
this,
|
|
223
|
-
types
|
|
224
|
-
)
|
|
225
|
-
return types.map((type) => resolved[type] ?? new Error(`Failed to resolve type: ${type}`))
|
|
226
|
-
})
|
|
227
|
-
const overrides = __privateGet(this, _overrides)?.types
|
|
228
|
-
if (overrides) {
|
|
229
|
-
for (const [type, id] of Object.entries(overrides)) {
|
|
230
|
-
loader.prime(type, id)
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
return loader
|
|
235
|
-
}
|
|
236
|
-
)
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
resolvePackages_fn = async function (packages) {
|
|
240
|
-
if (packages.length === 0) return Object.create(null)
|
|
241
|
-
const batches = chunk(packages, __privateGet(this, _pageSize))
|
|
242
|
-
const results = Object.create(null)
|
|
243
|
-
await Promise.all(
|
|
244
|
-
batches.map(async (batch) => {
|
|
245
|
-
const data = await __privateMethod(this, _MvrClient_instances, fetch_fn).call(
|
|
246
|
-
this,
|
|
247
|
-
'/v1/resolution/bulk',
|
|
248
|
-
{
|
|
249
|
-
names: batch,
|
|
250
|
-
}
|
|
251
|
-
)
|
|
252
|
-
if (!data?.resolution) return
|
|
253
|
-
for (const pkg of Object.keys(data?.resolution)) {
|
|
254
|
-
const pkgData = data.resolution[pkg]?.package_id
|
|
255
|
-
if (!pkgData) continue
|
|
256
|
-
results[pkg] = pkgData
|
|
257
|
-
}
|
|
258
|
-
})
|
|
259
|
-
)
|
|
260
|
-
return results
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
resolveTypes_fn = async function (types) {
|
|
264
|
-
if (types.length === 0) return Object.create(null)
|
|
265
|
-
const batches = chunk(types, __privateGet(this, _pageSize))
|
|
266
|
-
const results = Object.create(null)
|
|
267
|
-
await Promise.all(
|
|
268
|
-
batches.map(async (batch) => {
|
|
269
|
-
const data = await __privateMethod(this, _MvrClient_instances, fetch_fn).call(
|
|
270
|
-
this,
|
|
271
|
-
'/v1/struct-definition/bulk',
|
|
272
|
-
{
|
|
273
|
-
types: batch,
|
|
274
|
-
}
|
|
275
|
-
)
|
|
276
|
-
if (!data?.resolution) return
|
|
277
|
-
for (const type of Object.keys(data?.resolution)) {
|
|
278
|
-
const typeData = data.resolution[type]?.type_tag
|
|
279
|
-
if (!typeData) continue
|
|
280
|
-
results[type] = typeData
|
|
281
|
-
}
|
|
282
|
-
})
|
|
283
|
-
)
|
|
284
|
-
return results
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
fetch_fn = async function (url, body) {
|
|
288
|
-
if (!__privateGet(this, _url)) {
|
|
289
|
-
throw new Error('MVR Api URL is not set for the current client')
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
const response = await fetch(`${__privateGet(this, _url)}${url}`, {
|
|
293
|
-
method: 'POST',
|
|
294
|
-
headers: {
|
|
295
|
-
'Content-Type': 'application/json',
|
|
296
|
-
...MVR_API_HEADER,
|
|
297
|
-
},
|
|
298
|
-
body: JSON.stringify(body),
|
|
299
|
-
})
|
|
300
|
-
if (!response.ok) {
|
|
301
|
-
const errorBody = await response.json().catch(() => Object.create(null))
|
|
302
|
-
throw new Error(`Failed to resolve types: ${errorBody?.message}`)
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
return response.json()
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
function validateOverrides(overrides) {
|
|
309
|
-
if (overrides?.packages) {
|
|
310
|
-
for (const [pkg, id] of Object.entries(overrides.packages)) {
|
|
311
|
-
if (!isValidNamedPackage(pkg)) {
|
|
312
|
-
throw new Error(`Invalid package name: ${pkg}`)
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
if (!isValidSuiAddress(normalizeSuiAddress(id))) {
|
|
316
|
-
throw new Error(`Invalid package ID: ${id}`)
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
if (overrides?.types) {
|
|
322
|
-
for (const [type, val] of Object.entries(overrides.types)) {
|
|
323
|
-
// NOTE: exodus dev edited on audit
|
|
324
|
-
if (parseStructTag(type).typeParams.length > 0) {
|
|
325
|
-
throw new Error(
|
|
326
|
-
'Type overrides must be first-level only. If you want to supply generic types, just pass each type individually.'
|
|
327
|
-
)
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
const parsedValue = parseStructTag(val)
|
|
331
|
-
if (!isValidSuiAddress(parsedValue.address)) {
|
|
332
|
-
throw new Error(`Invalid type: ${val}`)
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
function extractMvrTypes(type, types = /* @__PURE__ */ new Set()) {
|
|
339
|
-
if (typeof type === 'string' && !hasMvrName(type)) return types
|
|
340
|
-
const tag = isStructTag(type) ? type : parseStructTag(type)
|
|
341
|
-
if (hasMvrName(tag.address)) types.add(`${tag.address}::${tag.module}::${tag.name}`)
|
|
342
|
-
for (const param of tag.typeParams) {
|
|
343
|
-
extractMvrTypes(param, types)
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
return types
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
function replaceMvrNames(tag, typeCache) {
|
|
350
|
-
const type = isStructTag(tag) ? tag : parseStructTag(tag)
|
|
351
|
-
const typeTag = `${type.address}::${type.module}::${type.name}`
|
|
352
|
-
const cacheHit = typeCache[typeTag]
|
|
353
|
-
return normalizeStructTag({
|
|
354
|
-
...type,
|
|
355
|
-
address: cacheHit ? cacheHit.split('::')[0] : type.address,
|
|
356
|
-
typeParams: type.typeParams.map((param) => replaceMvrNames(param, typeCache)),
|
|
357
|
-
})
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
function hasMvrName(nameOrType) {
|
|
361
|
-
// NOTE: exodus dev edited on audit
|
|
362
|
-
if (typeof nameOrType !== 'string') return false
|
|
363
|
-
const s = nameOrType.trim()
|
|
364
|
-
if (!s) return false
|
|
365
|
-
|
|
366
|
-
// 1) foo(.bar).sui
|
|
367
|
-
if (SUI_DOMAIN_RE.test(s)) return true
|
|
368
|
-
|
|
369
|
-
// 2) name@0x<hex>
|
|
370
|
-
const at = s.indexOf('@')
|
|
371
|
-
if (at > 0) {
|
|
372
|
-
const left = s.slice(0, at)
|
|
373
|
-
const right = s.slice(at + 1)
|
|
374
|
-
if (MOVE_IDENT.test(left) && isSuiAddressLoose(right)) return true
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
// 3) namespace/name (exactly one separator, both identifiers)
|
|
378
|
-
if (s.includes(NAME_SEPARATOR)) {
|
|
379
|
-
const parts = s.split(NAME_SEPARATOR)
|
|
380
|
-
if (
|
|
381
|
-
parts.length === 2 &&
|
|
382
|
-
parts[0] &&
|
|
383
|
-
parts[1] &&
|
|
384
|
-
MOVE_IDENT.test(parts[0]) &&
|
|
385
|
-
MOVE_IDENT.test(parts[1])
|
|
386
|
-
) {
|
|
387
|
-
return true
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
return false
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
function isStructTag(type) {
|
|
395
|
-
return (
|
|
396
|
-
typeof type === 'object' &&
|
|
397
|
-
'address' in type &&
|
|
398
|
-
'module' in type &&
|
|
399
|
-
'name' in type &&
|
|
400
|
-
'typeParams' in type
|
|
401
|
-
)
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
function findNamesInTransaction(builder) {
|
|
405
|
-
const packages = /* @__PURE__ */ new Set()
|
|
406
|
-
const types = /* @__PURE__ */ new Set()
|
|
407
|
-
for (const command of builder.commands) {
|
|
408
|
-
switch (command.$kind) {
|
|
409
|
-
case 'MakeMoveVec':
|
|
410
|
-
if (command.MakeMoveVec.type) {
|
|
411
|
-
getNamesFromTypeList([command.MakeMoveVec.type]).forEach((type) => {
|
|
412
|
-
types.add(type)
|
|
413
|
-
})
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
break
|
|
417
|
-
case 'MoveCall':
|
|
418
|
-
const moveCall = command.MoveCall
|
|
419
|
-
const pkg = moveCall.package.split('::')[0]
|
|
420
|
-
if (hasMvrName(pkg)) {
|
|
421
|
-
if (!isValidNamedPackage(pkg)) throw new Error(`Invalid package name: ${pkg}`)
|
|
422
|
-
packages.add(pkg)
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
getNamesFromTypeList(moveCall.typeArguments ?? []).forEach((type) => {
|
|
426
|
-
types.add(type)
|
|
427
|
-
})
|
|
428
|
-
break
|
|
429
|
-
default:
|
|
430
|
-
break
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
return {
|
|
435
|
-
packages: [...packages],
|
|
436
|
-
types: [...types],
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
function replaceNames(builder, resolved) {
|
|
441
|
-
for (const command of builder.commands) {
|
|
442
|
-
if (command.MakeMoveVec?.type) {
|
|
443
|
-
if (!hasMvrName(command.MakeMoveVec.type)) continue
|
|
444
|
-
if (!resolved.types[command.MakeMoveVec.type]) {
|
|
445
|
-
throw new Error(`No resolution found for type: ${command.MakeMoveVec.type}`)
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
command.MakeMoveVec.type = resolved.types[command.MakeMoveVec.type].type
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
const tx = command.MoveCall
|
|
452
|
-
if (!tx) continue
|
|
453
|
-
const nameParts = tx.package.split('::')
|
|
454
|
-
const name = nameParts[0]
|
|
455
|
-
if (hasMvrName(name) && !resolved.packages[name]) {
|
|
456
|
-
throw new Error(`No address found for package: ${name}`)
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
if (hasMvrName(name)) {
|
|
460
|
-
nameParts[0] = resolved.packages[name].package
|
|
461
|
-
tx.package = nameParts.join('::')
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
const types = tx.typeArguments
|
|
465
|
-
if (!types) continue
|
|
466
|
-
for (let i = 0; i < types.length; i++) {
|
|
467
|
-
if (!hasMvrName(types[i])) continue
|
|
468
|
-
if (!resolved.types[types[i]]) throw new Error(`No resolution found for type: ${types[i]}`)
|
|
469
|
-
types[i] = resolved.types[types[i]].type
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
tx.typeArguments = types
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
function getNamesFromTypeList(types) {
|
|
477
|
-
const names = /* @__PURE__ */ new Set()
|
|
478
|
-
for (const type of types) {
|
|
479
|
-
if (hasMvrName(type)) {
|
|
480
|
-
if (!isValidNamedType(type)) throw new Error(`Invalid type with names: ${type}`)
|
|
481
|
-
names.add(type)
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
return names
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
export { MvrClient, findNamesInTransaction, hasMvrName, replaceNames, validateOverrides }
|
|
489
|
-
// # sourceMappingURL=mvr.js.map
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { ClientCache } from '../../experimental/cache.js'
|
|
2
|
-
import { findNamesInTransaction, MvrClient, replaceNames } from '../../experimental/mvr.js'
|
|
3
|
-
|
|
4
|
-
const cacheMap = /* @__PURE__ */ new WeakMap()
|
|
5
|
-
const namedPackagesPlugin = (options) => {
|
|
6
|
-
let mvrClient
|
|
7
|
-
if (options) {
|
|
8
|
-
const overrides = options.overrides ?? {
|
|
9
|
-
packages: Object.create(null),
|
|
10
|
-
types: Object.create(null),
|
|
11
|
-
}
|
|
12
|
-
if (!cacheMap.has(overrides)) {
|
|
13
|
-
cacheMap.set(overrides, new ClientCache())
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
mvrClient = new MvrClient({
|
|
17
|
-
cache: cacheMap.get(overrides),
|
|
18
|
-
url: options.url,
|
|
19
|
-
pageSize: options.pageSize,
|
|
20
|
-
overrides,
|
|
21
|
-
})
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return async (transactionData, buildOptions, next) => {
|
|
25
|
-
const names = findNamesInTransaction(transactionData)
|
|
26
|
-
if (names.types.length === 0 && names.packages.length === 0) {
|
|
27
|
-
return next()
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const resolved = await (mvrClient || getClient(buildOptions).core.mvr).resolve({
|
|
31
|
-
types: names.types,
|
|
32
|
-
packages: names.packages,
|
|
33
|
-
})
|
|
34
|
-
replaceNames(transactionData, resolved)
|
|
35
|
-
await next()
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function getClient(options) {
|
|
40
|
-
if (!options.client) {
|
|
41
|
-
throw new Error(
|
|
42
|
-
`No sui client passed to Transaction#build, but transaction data was not sufficient to build offline.`
|
|
43
|
-
)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return options.client
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export { namedPackagesPlugin }
|