@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 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.0",
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": "^12.0.1",
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.2.0",
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": "f32e29d35f604bd6857bb1d19e2896b34352f122"
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, mvr }) {
14
- super({ network: jsonRpcClient.network, base: jsonRpcClient, mvr })
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) <= BigInt(18_446_744_073_709_551_615)
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 }