@mysten/sui 1.31.0 → 1.33.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.
Files changed (106) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/cjs/client/client.d.ts +13 -12
  3. package/dist/cjs/client/client.js +189 -48
  4. package/dist/cjs/client/client.js.map +3 -3
  5. package/dist/cjs/experimental/cache.d.ts +1 -0
  6. package/dist/cjs/experimental/cache.js +9 -0
  7. package/dist/cjs/experimental/cache.js.map +2 -2
  8. package/dist/cjs/experimental/client.d.ts +2 -1
  9. package/dist/cjs/experimental/client.js +2 -1
  10. package/dist/cjs/experimental/client.js.map +2 -2
  11. package/dist/cjs/experimental/core.d.ts +6 -0
  12. package/dist/cjs/experimental/core.js +11 -3
  13. package/dist/cjs/experimental/core.js.map +2 -2
  14. package/dist/cjs/experimental/index.d.ts +2 -2
  15. package/dist/cjs/experimental/index.js.map +2 -2
  16. package/dist/cjs/experimental/mvr.d.ts +42 -0
  17. package/dist/cjs/experimental/mvr.js +355 -0
  18. package/dist/cjs/experimental/mvr.js.map +7 -0
  19. package/dist/cjs/experimental/transports/graphql.d.ts +4 -1
  20. package/dist/cjs/experimental/transports/graphql.js +17 -8
  21. package/dist/cjs/experimental/transports/graphql.js.map +2 -2
  22. package/dist/cjs/experimental/transports/jsonRPC.d.ts +5 -2
  23. package/dist/cjs/experimental/transports/jsonRPC.js +25 -17
  24. package/dist/cjs/experimental/transports/jsonRPC.js.map +3 -3
  25. package/dist/cjs/experimental/transports/utils.js +2 -2
  26. package/dist/cjs/experimental/transports/utils.js.map +2 -2
  27. package/dist/cjs/experimental/types.d.ts +43 -1
  28. package/dist/cjs/experimental/types.js.map +1 -1
  29. package/dist/cjs/graphql/client.d.ts +2 -1
  30. package/dist/cjs/graphql/client.js +6 -2
  31. package/dist/cjs/graphql/client.js.map +2 -2
  32. package/dist/cjs/transactions/index.d.ts +4 -1
  33. package/dist/cjs/transactions/index.js +2 -2
  34. package/dist/cjs/transactions/index.js.map +3 -3
  35. package/dist/cjs/transactions/plugins/NamedPackagesPlugin.d.ts +4 -3
  36. package/dist/cjs/transactions/plugins/NamedPackagesPlugin.js +38 -90
  37. package/dist/cjs/transactions/plugins/NamedPackagesPlugin.js.map +3 -3
  38. package/dist/cjs/transactions/resolve.js +6 -3
  39. package/dist/cjs/transactions/resolve.js.map +2 -2
  40. package/dist/cjs/version.d.ts +1 -1
  41. package/dist/cjs/version.js +1 -1
  42. package/dist/cjs/version.js.map +1 -1
  43. package/dist/esm/client/client.d.ts +13 -12
  44. package/dist/esm/client/client.js +188 -47
  45. package/dist/esm/client/client.js.map +2 -2
  46. package/dist/esm/experimental/cache.d.ts +1 -0
  47. package/dist/esm/experimental/cache.js +9 -0
  48. package/dist/esm/experimental/cache.js.map +2 -2
  49. package/dist/esm/experimental/client.d.ts +2 -1
  50. package/dist/esm/experimental/client.js +2 -1
  51. package/dist/esm/experimental/client.js.map +2 -2
  52. package/dist/esm/experimental/core.d.ts +6 -0
  53. package/dist/esm/experimental/core.js +11 -3
  54. package/dist/esm/experimental/core.js.map +2 -2
  55. package/dist/esm/experimental/index.d.ts +2 -2
  56. package/dist/esm/experimental/index.js.map +2 -2
  57. package/dist/esm/experimental/mvr.d.ts +42 -0
  58. package/dist/esm/experimental/mvr.js +340 -0
  59. package/dist/esm/experimental/mvr.js.map +7 -0
  60. package/dist/esm/experimental/transports/graphql.d.ts +4 -1
  61. package/dist/esm/experimental/transports/graphql.js +17 -8
  62. package/dist/esm/experimental/transports/graphql.js.map +2 -2
  63. package/dist/esm/experimental/transports/jsonRPC.d.ts +5 -2
  64. package/dist/esm/experimental/transports/jsonRPC.js +22 -14
  65. package/dist/esm/experimental/transports/jsonRPC.js.map +3 -3
  66. package/dist/esm/experimental/transports/utils.js +1 -1
  67. package/dist/esm/experimental/transports/utils.js.map +1 -1
  68. package/dist/esm/experimental/types.d.ts +43 -1
  69. package/dist/esm/graphql/client.d.ts +2 -1
  70. package/dist/esm/graphql/client.js +6 -2
  71. package/dist/esm/graphql/client.js.map +2 -2
  72. package/dist/esm/transactions/index.d.ts +4 -1
  73. package/dist/esm/transactions/index.js.map +2 -2
  74. package/dist/esm/transactions/plugins/NamedPackagesPlugin.d.ts +4 -3
  75. package/dist/esm/transactions/plugins/NamedPackagesPlugin.js +37 -95
  76. package/dist/esm/transactions/plugins/NamedPackagesPlugin.js.map +3 -3
  77. package/dist/esm/transactions/resolve.js +6 -3
  78. package/dist/esm/transactions/resolve.js.map +2 -2
  79. package/dist/esm/version.d.ts +1 -1
  80. package/dist/esm/version.js +1 -1
  81. package/dist/esm/version.js.map +1 -1
  82. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  83. package/dist/tsconfig.tsbuildinfo +1 -1
  84. package/package.json +3 -3
  85. package/src/client/client.ts +239 -60
  86. package/src/experimental/cache.ts +14 -0
  87. package/src/experimental/client.ts +3 -1
  88. package/src/experimental/core.ts +20 -1
  89. package/src/experimental/index.ts +2 -1
  90. package/src/experimental/mvr.ts +477 -0
  91. package/src/experimental/transports/graphql.ts +22 -10
  92. package/src/experimental/transports/jsonRPC.ts +21 -11
  93. package/src/experimental/transports/utils.ts +1 -1
  94. package/src/experimental/types.ts +59 -1
  95. package/src/graphql/client.ts +7 -1
  96. package/src/transactions/index.ts +5 -1
  97. package/src/transactions/plugins/NamedPackagesPlugin.ts +46 -120
  98. package/src/transactions/resolve.ts +6 -3
  99. package/src/version.ts +1 -1
  100. package/dist/cjs/transactions/plugins/utils.d.ts +0 -31
  101. package/dist/cjs/transactions/plugins/utils.js +0 -144
  102. package/dist/cjs/transactions/plugins/utils.js.map +0 -7
  103. package/dist/esm/transactions/plugins/utils.d.ts +0 -31
  104. package/dist/esm/transactions/plugins/utils.js +0 -124
  105. package/dist/esm/transactions/plugins/utils.js.map +0 -7
  106. package/src/transactions/plugins/utils.ts +0 -215
@@ -0,0 +1,477 @@
1
+ // Copyright (c) Mysten Labs, Inc.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { chunk, DataLoader } from '@mysten/utils';
5
+ import { isValidNamedPackage, isValidNamedType } from '../utils/move-registry.js';
6
+ import type { StructTag } from '../utils/sui-types.js';
7
+ import {
8
+ isValidSuiAddress,
9
+ normalizeStructTag,
10
+ normalizeSuiAddress,
11
+ parseStructTag,
12
+ } from '../utils/sui-types.js';
13
+ import type { ClientCache } from './cache.js';
14
+ import type { TransactionDataBuilder } from '../transactions/TransactionData.js';
15
+ import { PACKAGE_VERSION } from '../version.js';
16
+ import type { Experimental_SuiClientTypes } from './types.js';
17
+
18
+ const NAME_SEPARATOR = '/';
19
+ const MVR_API_HEADER = {
20
+ 'Mvr-Source': `@mysten/sui@${PACKAGE_VERSION}`,
21
+ };
22
+
23
+ export interface MvrClientOptions {
24
+ cache: ClientCache;
25
+ url?: string;
26
+ pageSize?: number;
27
+ overrides?: {
28
+ packages?: Record<string, string>;
29
+ types?: Record<string, string>;
30
+ };
31
+ }
32
+
33
+ export class MvrClient implements Experimental_SuiClientTypes.MvrMethods {
34
+ #cache: ClientCache;
35
+ #url?: string;
36
+ #pageSize: number;
37
+ #overrides: {
38
+ packages?: Record<string, string>;
39
+ types?: Record<string, string>;
40
+ };
41
+
42
+ constructor({ cache, url, pageSize = 50, overrides }: MvrClientOptions) {
43
+ this.#cache = cache;
44
+ this.#url = url;
45
+ this.#pageSize = pageSize;
46
+ this.#overrides = {
47
+ packages: overrides?.packages,
48
+ types: overrides?.types,
49
+ };
50
+
51
+ validateOverrides(this.#overrides);
52
+ }
53
+
54
+ get #mvrPackageDataLoader() {
55
+ return this.#cache.readSync(['#mvrPackageDataLoader', this.#url ?? ''], () => {
56
+ const loader = new DataLoader<string, string>(async (packages) => {
57
+ if (!this.#url) {
58
+ throw new Error(
59
+ `MVR Api URL is not set for the current client (resolving ${packages.join(', ')})`,
60
+ );
61
+ }
62
+ const resolved = await this.#resolvePackages(packages);
63
+
64
+ return packages.map(
65
+ (pkg) => resolved[pkg] ?? new Error(`Failed to resolve package: ${pkg}`),
66
+ );
67
+ });
68
+ const overrides = this.#overrides?.packages;
69
+
70
+ if (overrides) {
71
+ for (const [pkg, id] of Object.entries(overrides)) {
72
+ loader.prime(pkg, id);
73
+ }
74
+ }
75
+
76
+ return loader;
77
+ });
78
+ }
79
+
80
+ get #mvrTypeDataLoader() {
81
+ return this.#cache.readSync(['#mvrTypeDataLoader', this.#url ?? ''], () => {
82
+ const loader = new DataLoader<string, string>(async (types) => {
83
+ if (!this.#url) {
84
+ throw new Error(
85
+ `MVR Api URL is not set for the current client (resolving ${types.join(', ')})`,
86
+ );
87
+ }
88
+ const resolved = await this.#resolveTypes(types);
89
+
90
+ return types.map((type) => resolved[type] ?? new Error(`Failed to resolve type: ${type}`));
91
+ });
92
+
93
+ const overrides = this.#overrides?.types;
94
+
95
+ if (overrides) {
96
+ for (const [type, id] of Object.entries(overrides)) {
97
+ loader.prime(type, id);
98
+ }
99
+ }
100
+
101
+ return loader;
102
+ });
103
+ }
104
+
105
+ async #resolvePackages(packages: readonly string[]) {
106
+ if (packages.length === 0) return {};
107
+
108
+ const batches = chunk(packages, this.#pageSize);
109
+ const results: Record<string, string> = {};
110
+
111
+ await Promise.all(
112
+ batches.map(async (batch) => {
113
+ const data = await this.#fetch<{ resolution: Record<string, { package_id: string }> }>(
114
+ '/v1/resolution/bulk',
115
+ {
116
+ names: batch,
117
+ },
118
+ );
119
+
120
+ if (!data?.resolution) return;
121
+
122
+ for (const pkg of Object.keys(data?.resolution)) {
123
+ const pkgData = data.resolution[pkg]?.package_id;
124
+
125
+ if (!pkgData) continue;
126
+
127
+ results[pkg] = pkgData;
128
+ }
129
+ }),
130
+ );
131
+
132
+ return results;
133
+ }
134
+
135
+ async #resolveTypes(types: readonly string[]) {
136
+ if (types.length === 0) return {};
137
+
138
+ const batches = chunk(types, this.#pageSize);
139
+ const results: Record<string, string> = {};
140
+
141
+ await Promise.all(
142
+ batches.map(async (batch) => {
143
+ const data = await this.#fetch<{ resolution: Record<string, { type_tag: string }> }>(
144
+ '/v1/struct-definition/bulk',
145
+ {
146
+ types: batch,
147
+ },
148
+ );
149
+
150
+ if (!data?.resolution) return;
151
+
152
+ for (const type of Object.keys(data?.resolution)) {
153
+ const typeData = data.resolution[type]?.type_tag;
154
+ if (!typeData) continue;
155
+
156
+ results[type] = typeData;
157
+ }
158
+ }),
159
+ );
160
+
161
+ return results;
162
+ }
163
+
164
+ async #fetch<T>(url: string, body: Record<string, unknown>): Promise<T> {
165
+ if (!this.#url) {
166
+ throw new Error('MVR Api URL is not set for the current client');
167
+ }
168
+
169
+ const response = await fetch(`${this.#url}${url}`, {
170
+ method: 'POST',
171
+ headers: {
172
+ 'Content-Type': 'application/json',
173
+ ...MVR_API_HEADER,
174
+ },
175
+ body: JSON.stringify(body),
176
+ });
177
+
178
+ if (!response.ok) {
179
+ const errorBody = await response.json().catch(() => ({}));
180
+ throw new Error(`Failed to resolve types: ${errorBody?.message}`);
181
+ }
182
+
183
+ return response.json();
184
+ }
185
+
186
+ async resolvePackage({
187
+ package: name,
188
+ }: Experimental_SuiClientTypes.MvrResolvePackageOptions): Promise<Experimental_SuiClientTypes.MvrResolvePackageResponse> {
189
+ const resolved = await this.#mvrPackageDataLoader.load(name);
190
+ return {
191
+ package: resolved,
192
+ };
193
+ }
194
+
195
+ async resolveType({
196
+ type,
197
+ }: Experimental_SuiClientTypes.MvrResolveTypeOptions): Promise<Experimental_SuiClientTypes.MvrResolveTypeResponse> {
198
+ const mvrTypes = [...extractMvrTypes(type)];
199
+ const resolvedTypes = await this.#mvrTypeDataLoader.loadMany(mvrTypes);
200
+
201
+ const typeMap: Record<string, string> = {};
202
+
203
+ for (let i = 0; i < mvrTypes.length; i++) {
204
+ const resolvedType = resolvedTypes[i];
205
+ if (resolvedType instanceof Error) {
206
+ throw resolvedType;
207
+ }
208
+ typeMap[mvrTypes[i]] = resolvedType;
209
+ }
210
+
211
+ return {
212
+ type: replaceMvrNames(type, typeMap),
213
+ };
214
+ }
215
+
216
+ async resolve({
217
+ types = [],
218
+ packages = [],
219
+ }: Experimental_SuiClientTypes.MvrResolveOptions): Promise<Experimental_SuiClientTypes.MvrResolveResponse> {
220
+ const mvrTypes = new Set<string>();
221
+
222
+ for (const type of types ?? []) {
223
+ extractMvrTypes(type, mvrTypes);
224
+ }
225
+
226
+ const typesArray = [...mvrTypes];
227
+ const [resolvedTypes, resolvedPackages] = await Promise.all([
228
+ typesArray.length > 0 ? this.#mvrTypeDataLoader.loadMany(typesArray) : [],
229
+ packages.length > 0 ? this.#mvrPackageDataLoader.loadMany(packages) : [],
230
+ ]);
231
+
232
+ const typeMap: Record<string, string> = {
233
+ ...this.#overrides?.types,
234
+ };
235
+
236
+ for (const [i, type] of typesArray.entries()) {
237
+ const resolvedType = resolvedTypes[i];
238
+ if (resolvedType instanceof Error) {
239
+ throw resolvedType;
240
+ }
241
+ typeMap[type] = resolvedType;
242
+ }
243
+
244
+ const replacedTypes: Record<
245
+ string,
246
+ {
247
+ type: string;
248
+ }
249
+ > = {};
250
+
251
+ for (const type of types ?? []) {
252
+ const resolvedType = replaceMvrNames(type, typeMap);
253
+
254
+ replacedTypes[type] = {
255
+ type: resolvedType,
256
+ };
257
+ }
258
+
259
+ const replacedPackages: Record<
260
+ string,
261
+ {
262
+ package: string;
263
+ }
264
+ > = {};
265
+
266
+ for (const [i, pkg] of (packages ?? []).entries()) {
267
+ const resolvedPkg = this.#overrides?.packages?.[pkg] ?? resolvedPackages[i];
268
+
269
+ if (resolvedPkg instanceof Error) {
270
+ throw resolvedPkg;
271
+ }
272
+
273
+ replacedPackages[pkg] = {
274
+ package: resolvedPkg,
275
+ };
276
+ }
277
+
278
+ return {
279
+ types: replacedTypes,
280
+ packages: replacedPackages,
281
+ };
282
+ }
283
+ }
284
+
285
+ function validateOverrides(overrides?: {
286
+ packages?: Record<string, string>;
287
+ types?: Record<string, string>;
288
+ }) {
289
+ if (overrides?.packages) {
290
+ for (const [pkg, id] of Object.entries(overrides.packages)) {
291
+ if (!isValidNamedPackage(pkg)) {
292
+ throw new Error(`Invalid package name: ${pkg}`);
293
+ }
294
+ if (!isValidSuiAddress(normalizeSuiAddress(id))) {
295
+ throw new Error(`Invalid package ID: ${id}`);
296
+ }
297
+ }
298
+ }
299
+
300
+ if (overrides?.types) {
301
+ for (const [type, val] of Object.entries(overrides.types)) {
302
+ // validate that types are first-level only.
303
+ if (parseStructTag(type).typeParams.length > 0) {
304
+ throw new Error(
305
+ 'Type overrides must be first-level only. If you want to supply generic types, just pass each type individually.',
306
+ );
307
+ }
308
+
309
+ const parsedValue = parseStructTag(val);
310
+
311
+ if (!isValidSuiAddress(parsedValue.address)) {
312
+ throw new Error(`Invalid type: ${val}`);
313
+ }
314
+ }
315
+ }
316
+ }
317
+
318
+ /**
319
+ * Extracts all named types from a given type.
320
+ */
321
+ export function extractMvrTypes(type: string | StructTag, types = new Set<string>()) {
322
+ if (typeof type === 'string' && !hasMvrName(type)) return types;
323
+
324
+ const tag = isStructTag(type) ? type : parseStructTag(type);
325
+
326
+ if (hasMvrName(tag.address)) types.add(`${tag.address}::${tag.module}::${tag.name}`);
327
+
328
+ for (const param of tag.typeParams) {
329
+ extractMvrTypes(param, types);
330
+ }
331
+
332
+ return types;
333
+ }
334
+
335
+ /**
336
+ * Traverses a type, and replaces any found names with their resolved equivalents,
337
+ * based on the supplied type cache.
338
+ */
339
+ function replaceMvrNames(tag: string | StructTag, typeCache: Record<string, string>): string {
340
+ const type = isStructTag(tag) ? tag : parseStructTag(tag);
341
+
342
+ const typeTag = `${type.address}::${type.module}::${type.name}`;
343
+ const cacheHit = typeCache[typeTag];
344
+
345
+ return normalizeStructTag({
346
+ ...type,
347
+ address: cacheHit ? cacheHit.split('::')[0] : type.address,
348
+ typeParams: type.typeParams.map((param) => replaceMvrNames(param, typeCache)),
349
+ });
350
+ }
351
+
352
+ export function hasMvrName(nameOrType: string) {
353
+ return (
354
+ nameOrType.includes(NAME_SEPARATOR) || nameOrType.includes('@') || nameOrType.includes('.sui')
355
+ );
356
+ }
357
+
358
+ function isStructTag(type: string | StructTag): type is StructTag {
359
+ return (
360
+ typeof type === 'object' &&
361
+ 'address' in type &&
362
+ 'module' in type &&
363
+ 'name' in type &&
364
+ 'typeParams' in type
365
+ );
366
+ }
367
+
368
+ export type NamedPackagesOverrides = {
369
+ packages: Record<string, string>;
370
+ types: Record<string, string>;
371
+ };
372
+
373
+ /**
374
+ * Looks up all `.move` names in a transaction block.
375
+ * Returns a list of all the names found.
376
+ */
377
+ export function findNamesInTransaction(builder: TransactionDataBuilder): {
378
+ packages: string[];
379
+ types: string[];
380
+ } {
381
+ const packages: Set<string> = new Set();
382
+ const types: Set<string> = new Set();
383
+
384
+ for (const command of builder.commands) {
385
+ switch (command.$kind) {
386
+ case 'MakeMoveVec':
387
+ if (command.MakeMoveVec.type) {
388
+ getNamesFromTypeList([command.MakeMoveVec.type]).forEach((type) => {
389
+ types.add(type);
390
+ });
391
+ }
392
+ break;
393
+ case 'MoveCall':
394
+ const moveCall = command.MoveCall;
395
+
396
+ const pkg = moveCall.package.split('::')[0];
397
+ if (hasMvrName(pkg)) {
398
+ if (!isValidNamedPackage(pkg)) throw new Error(`Invalid package name: ${pkg}`);
399
+ packages.add(pkg);
400
+ }
401
+
402
+ getNamesFromTypeList(moveCall.typeArguments ?? []).forEach((type) => {
403
+ types.add(type);
404
+ });
405
+
406
+ break;
407
+ default:
408
+ break;
409
+ }
410
+ }
411
+
412
+ return {
413
+ packages: [...packages],
414
+ types: [...types],
415
+ };
416
+ }
417
+
418
+ /**
419
+ * Replace all names & types in a transaction block
420
+ * with their resolved names/types.
421
+ */
422
+ export function replaceNames(
423
+ builder: TransactionDataBuilder,
424
+ resolved: Experimental_SuiClientTypes.MvrResolveResponse,
425
+ ) {
426
+ for (const command of builder.commands) {
427
+ // Replacements for `MakeMoveVec` commands (that can include types)
428
+ if (command.MakeMoveVec?.type) {
429
+ if (!hasMvrName(command.MakeMoveVec.type)) continue;
430
+ if (!resolved.types[command.MakeMoveVec.type])
431
+ throw new Error(`No resolution found for type: ${command.MakeMoveVec.type}`);
432
+ command.MakeMoveVec.type = resolved.types[command.MakeMoveVec.type].type;
433
+ }
434
+ // Replacements for `MoveCall` commands (that can include packages & types)
435
+ const tx = command.MoveCall;
436
+ if (!tx) continue;
437
+
438
+ const nameParts = tx.package.split('::');
439
+ const name = nameParts[0];
440
+
441
+ if (hasMvrName(name) && !resolved.packages[name])
442
+ throw new Error(`No address found for package: ${name}`);
443
+
444
+ // Replace package name with address.
445
+ if (hasMvrName(name)) {
446
+ nameParts[0] = resolved.packages[name].package;
447
+ tx.package = nameParts.join('::');
448
+ }
449
+
450
+ const types = tx.typeArguments;
451
+ if (!types) continue;
452
+
453
+ for (let i = 0; i < types.length; i++) {
454
+ if (!hasMvrName(types[i])) continue;
455
+
456
+ if (!resolved.types[types[i]]) throw new Error(`No resolution found for type: ${types[i]}`);
457
+ types[i] = resolved.types[types[i]].type;
458
+ }
459
+
460
+ tx.typeArguments = types;
461
+ }
462
+ }
463
+
464
+ /**
465
+ * Returns a list of unique types that include a name
466
+ * from the given list. This list is retrieved from the Transaction Data.
467
+ */
468
+ function getNamesFromTypeList(types: string[]) {
469
+ const names = new Set<string>();
470
+ for (const type of types) {
471
+ if (hasMvrName(type)) {
472
+ if (!isValidNamedType(type)) throw new Error(`Invalid type with names: ${type}`);
473
+ names.add(type);
474
+ }
475
+ }
476
+ return names;
477
+ }
@@ -33,8 +33,14 @@ import { parseTransactionBcs, parseTransactionEffectsBcs } from './utils.js';
33
33
  export class GraphQLTransport extends Experimental_CoreClient {
34
34
  #graphqlClient: SuiGraphQLClient;
35
35
 
36
- constructor(graphqlClient: SuiGraphQLClient) {
37
- super({ network: graphqlClient.network });
36
+ constructor({
37
+ graphqlClient,
38
+ mvr,
39
+ }: {
40
+ graphqlClient: SuiGraphQLClient;
41
+ mvr?: Experimental_SuiClientTypes.MvrOptions;
42
+ }) {
43
+ super({ network: graphqlClient.network, base: graphqlClient, mvr });
38
44
  this.#graphqlClient = graphqlClient;
39
45
  }
40
46
 
@@ -98,13 +104,15 @@ export class GraphQLTransport extends Experimental_CoreClient {
98
104
  }
99
105
  return {
100
106
  id: obj.address,
101
- version: obj.version,
107
+ version: obj.version.toString(),
102
108
  digest: obj.digest!,
103
109
  owner: mapOwner(obj.owner!),
104
110
  type: obj.asMoveObject?.contents?.type?.repr!,
105
- content: obj.asMoveObject
106
- ? fromBase64(obj.asMoveObject?.contents?.bcs!)
107
- : new Uint8Array(),
111
+ content: Promise.resolve(
112
+ obj.asMoveObject?.contents?.bcs
113
+ ? fromBase64(obj.asMoveObject.contents.bcs)
114
+ : new Uint8Array(),
115
+ ),
108
116
  };
109
117
  }),
110
118
  };
@@ -128,11 +136,13 @@ export class GraphQLTransport extends Experimental_CoreClient {
128
136
  return {
129
137
  objects: objects.nodes.map((obj) => ({
130
138
  id: obj.address,
131
- version: obj.version,
139
+ version: obj.version.toString(),
132
140
  digest: obj.digest!,
133
141
  owner: mapOwner(obj.owner!),
134
142
  type: obj.contents?.type?.repr!,
135
- content: fromBase64(obj.contents?.bcs!),
143
+ content: Promise.resolve(
144
+ obj.contents?.bcs ? fromBase64(obj.contents.bcs) : new Uint8Array(),
145
+ ),
136
146
  })),
137
147
  hasNextPage: objects.pageInfo.hasNextPage,
138
148
  cursor: objects.pageInfo.endCursor ?? null,
@@ -159,12 +169,14 @@ export class GraphQLTransport extends Experimental_CoreClient {
159
169
  hasNextPage: coins.pageInfo.hasNextPage,
160
170
  objects: coins.nodes.map((coin) => ({
161
171
  id: coin.address,
162
- version: coin.version,
172
+ version: coin.version.toString(),
163
173
  digest: coin.digest!,
164
174
  owner: mapOwner(coin.owner!),
165
175
  type: coin.contents?.type?.repr!,
166
176
  balance: coin.coinBalance,
167
- content: fromBase64(coin.contents?.bcs!),
177
+ content: Promise.resolve(
178
+ coin.contents?.bcs ? fromBase64(coin.contents.bcs) : new Uint8Array(),
179
+ ),
168
180
  })),
169
181
  };
170
182
  }
@@ -12,7 +12,6 @@ import type {
12
12
  SuiTransactionBlockResponse,
13
13
  TransactionEffects,
14
14
  } from '../../client/index.js';
15
- import { batch } from '../../transactions/plugins/utils.js';
16
15
  import { Transaction } from '../../transactions/Transaction.js';
17
16
  import { Experimental_CoreClient } from '../core.js';
18
17
  import { ObjectError } from '../errors.js';
@@ -20,17 +19,24 @@ import type { Experimental_SuiClientTypes } from '../types.js';
20
19
  import { parseTransactionBcs, parseTransactionEffectsBcs } from './utils.js';
21
20
  import { resolveTransactionPlugin } from './json-rpc-resolver.js';
22
21
  import { TransactionDataBuilder } from '../../transactions/TransactionData.js';
22
+ import { chunk } from '@mysten/utils';
23
23
 
24
24
  export class JSONRpcTransport extends Experimental_CoreClient {
25
25
  #jsonRpcClient: SuiClient;
26
26
 
27
- constructor(jsonRpcClient: SuiClient) {
28
- super({ network: jsonRpcClient.network });
27
+ constructor({
28
+ jsonRpcClient,
29
+ mvr,
30
+ }: {
31
+ jsonRpcClient: SuiClient;
32
+ mvr?: Experimental_SuiClientTypes.MvrOptions;
33
+ }) {
34
+ super({ network: jsonRpcClient.network, base: jsonRpcClient, mvr });
29
35
  this.#jsonRpcClient = jsonRpcClient;
30
36
  }
31
37
 
32
38
  async getObjects(options: Experimental_SuiClientTypes.GetObjectsOptions) {
33
- const batches = batch(options.objectIds, 50);
39
+ const batches = chunk(options.objectIds, 50);
34
40
  const results: Experimental_SuiClientTypes.GetObjectsResponse['objects'] = [];
35
41
 
36
42
  for (const batch of batches) {
@@ -67,6 +73,7 @@ export class JSONRpcTransport extends Experimental_CoreClient {
67
73
  showType: true,
68
74
  showBcs: true,
69
75
  },
76
+ filter: options.type ? { StructType: options.type } : null,
70
77
  signal: options.signal,
71
78
  });
72
79
 
@@ -100,12 +107,14 @@ export class JSONRpcTransport extends Experimental_CoreClient {
100
107
  digest: coin.digest,
101
108
  balance: coin.balance,
102
109
  type: `0x2::coin::Coin<${coin.coinType}>`,
103
- content: Coin.serialize({
104
- id: coin.coinObjectId,
105
- balance: {
106
- value: coin.balance,
107
- },
108
- }).toBytes(),
110
+ content: Promise.resolve(
111
+ Coin.serialize({
112
+ id: coin.coinObjectId,
113
+ balance: {
114
+ value: coin.balance,
115
+ },
116
+ }).toBytes(),
117
+ ),
109
118
  owner: {
110
119
  $kind: 'ObjectOwner' as const,
111
120
  ObjectOwner: options.address,
@@ -267,8 +276,9 @@ function parseObject(object: SuiObjectData): Experimental_SuiClientTypes.ObjectR
267
276
  version: object.version,
268
277
  digest: object.digest,
269
278
  type: object.type!,
270
- content:
279
+ content: Promise.resolve(
271
280
  object.bcs?.dataType === 'moveObject' ? fromBase64(object.bcs.bcsBytes) : new Uint8Array(),
281
+ ),
272
282
  owner: parseOwner(object.owner!),
273
283
  };
274
284
  }
@@ -2,7 +2,7 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { bcs } from '../../bcs/index.js';
5
- import { TransactionDataBuilder } from '../../transactions/index.js';
5
+ import { TransactionDataBuilder } from '../../transactions/TransactionData.js';
6
6
  import type { Experimental_SuiClientTypes } from '../types.js';
7
7
 
8
8
  export function parseTransactionBcs(
@@ -37,6 +37,16 @@ export namespace Experimental_SuiClientTypes {
37
37
 
38
38
  export interface SuiClientOptions {
39
39
  network: Network;
40
+ base?: Experimental_BaseClient;
41
+ }
42
+
43
+ export interface MvrOptions {
44
+ url?: string;
45
+ pageSize?: number;
46
+ overrides?: {
47
+ packages?: Record<string, string>;
48
+ types?: Record<string, string>;
49
+ };
40
50
  }
41
51
 
42
52
  export interface CoreClientMethodOptions {
@@ -111,7 +121,7 @@ export namespace Experimental_SuiClientTypes {
111
121
  digest: string;
112
122
  owner: ObjectOwner;
113
123
  type: string;
114
- content: Uint8Array;
124
+ content: PromiseLike<Uint8Array>;
115
125
  }
116
126
 
117
127
  export interface CoinResponse extends ObjectResponse {
@@ -279,6 +289,54 @@ export namespace Experimental_SuiClientTypes {
279
289
  ) => Promise<ResolveNameServiceNamesResponse>;
280
290
  }
281
291
 
292
+ /** MVR methods */
293
+
294
+ export interface TransportMethods {
295
+ mvr: MvrMethods;
296
+ }
297
+
298
+ export interface MvrMethods {
299
+ resolvePackage: (options: MvrResolvePackageOptions) => Promise<MvrResolvePackageResponse>;
300
+ resolveType: (options: MvrResolveTypeOptions) => Promise<MvrResolveTypeResponse>;
301
+ resolve: (options: MvrResolveOptions) => Promise<MvrResolveResponse>;
302
+ }
303
+
304
+ export interface MvrResolvePackageOptions extends CoreClientMethodOptions {
305
+ package: string;
306
+ }
307
+
308
+ export interface MvrResolveTypeOptions extends CoreClientMethodOptions {
309
+ type: string;
310
+ }
311
+
312
+ export interface MvrResolveOptions extends CoreClientMethodOptions {
313
+ packages?: string[];
314
+ types?: string[];
315
+ }
316
+
317
+ export interface MvrResolvePackageResponse {
318
+ package: string;
319
+ }
320
+
321
+ export interface MvrResolveTypeResponse {
322
+ type: string;
323
+ }
324
+
325
+ export interface MvrResolveResponse {
326
+ packages: Record<
327
+ string,
328
+ {
329
+ package: string;
330
+ }
331
+ >;
332
+ types: Record<
333
+ string,
334
+ {
335
+ type: string;
336
+ }
337
+ >;
338
+ }
339
+
282
340
  /** ObjectOwner types */
283
341
 
284
342
  export interface AddressOwner {