@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.
- package/CHANGELOG.md +18 -0
- package/dist/cjs/client/client.d.ts +13 -12
- package/dist/cjs/client/client.js +189 -48
- package/dist/cjs/client/client.js.map +3 -3
- package/dist/cjs/experimental/cache.d.ts +1 -0
- package/dist/cjs/experimental/cache.js +9 -0
- package/dist/cjs/experimental/cache.js.map +2 -2
- package/dist/cjs/experimental/client.d.ts +2 -1
- package/dist/cjs/experimental/client.js +2 -1
- package/dist/cjs/experimental/client.js.map +2 -2
- package/dist/cjs/experimental/core.d.ts +6 -0
- package/dist/cjs/experimental/core.js +11 -3
- package/dist/cjs/experimental/core.js.map +2 -2
- package/dist/cjs/experimental/index.d.ts +2 -2
- package/dist/cjs/experimental/index.js.map +2 -2
- package/dist/cjs/experimental/mvr.d.ts +42 -0
- package/dist/cjs/experimental/mvr.js +355 -0
- package/dist/cjs/experimental/mvr.js.map +7 -0
- package/dist/cjs/experimental/transports/graphql.d.ts +4 -1
- package/dist/cjs/experimental/transports/graphql.js +17 -8
- package/dist/cjs/experimental/transports/graphql.js.map +2 -2
- package/dist/cjs/experimental/transports/jsonRPC.d.ts +5 -2
- package/dist/cjs/experimental/transports/jsonRPC.js +25 -17
- package/dist/cjs/experimental/transports/jsonRPC.js.map +3 -3
- package/dist/cjs/experimental/transports/utils.js +2 -2
- package/dist/cjs/experimental/transports/utils.js.map +2 -2
- package/dist/cjs/experimental/types.d.ts +43 -1
- package/dist/cjs/experimental/types.js.map +1 -1
- package/dist/cjs/graphql/client.d.ts +2 -1
- package/dist/cjs/graphql/client.js +6 -2
- package/dist/cjs/graphql/client.js.map +2 -2
- package/dist/cjs/transactions/index.d.ts +4 -1
- package/dist/cjs/transactions/index.js +2 -2
- package/dist/cjs/transactions/index.js.map +3 -3
- package/dist/cjs/transactions/plugins/NamedPackagesPlugin.d.ts +4 -3
- package/dist/cjs/transactions/plugins/NamedPackagesPlugin.js +38 -90
- package/dist/cjs/transactions/plugins/NamedPackagesPlugin.js.map +3 -3
- package/dist/cjs/transactions/resolve.js +6 -3
- package/dist/cjs/transactions/resolve.js.map +2 -2
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/version.js.map +1 -1
- package/dist/esm/client/client.d.ts +13 -12
- package/dist/esm/client/client.js +188 -47
- package/dist/esm/client/client.js.map +2 -2
- package/dist/esm/experimental/cache.d.ts +1 -0
- package/dist/esm/experimental/cache.js +9 -0
- package/dist/esm/experimental/cache.js.map +2 -2
- package/dist/esm/experimental/client.d.ts +2 -1
- package/dist/esm/experimental/client.js +2 -1
- package/dist/esm/experimental/client.js.map +2 -2
- package/dist/esm/experimental/core.d.ts +6 -0
- package/dist/esm/experimental/core.js +11 -3
- package/dist/esm/experimental/core.js.map +2 -2
- package/dist/esm/experimental/index.d.ts +2 -2
- package/dist/esm/experimental/index.js.map +2 -2
- package/dist/esm/experimental/mvr.d.ts +42 -0
- package/dist/esm/experimental/mvr.js +340 -0
- package/dist/esm/experimental/mvr.js.map +7 -0
- package/dist/esm/experimental/transports/graphql.d.ts +4 -1
- package/dist/esm/experimental/transports/graphql.js +17 -8
- package/dist/esm/experimental/transports/graphql.js.map +2 -2
- package/dist/esm/experimental/transports/jsonRPC.d.ts +5 -2
- package/dist/esm/experimental/transports/jsonRPC.js +22 -14
- package/dist/esm/experimental/transports/jsonRPC.js.map +3 -3
- package/dist/esm/experimental/transports/utils.js +1 -1
- package/dist/esm/experimental/transports/utils.js.map +1 -1
- package/dist/esm/experimental/types.d.ts +43 -1
- package/dist/esm/graphql/client.d.ts +2 -1
- package/dist/esm/graphql/client.js +6 -2
- package/dist/esm/graphql/client.js.map +2 -2
- package/dist/esm/transactions/index.d.ts +4 -1
- package/dist/esm/transactions/index.js.map +2 -2
- package/dist/esm/transactions/plugins/NamedPackagesPlugin.d.ts +4 -3
- package/dist/esm/transactions/plugins/NamedPackagesPlugin.js +37 -95
- package/dist/esm/transactions/plugins/NamedPackagesPlugin.js.map +3 -3
- package/dist/esm/transactions/resolve.js +6 -3
- package/dist/esm/transactions/resolve.js.map +2 -2
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/client/client.ts +239 -60
- package/src/experimental/cache.ts +14 -0
- package/src/experimental/client.ts +3 -1
- package/src/experimental/core.ts +20 -1
- package/src/experimental/index.ts +2 -1
- package/src/experimental/mvr.ts +477 -0
- package/src/experimental/transports/graphql.ts +22 -10
- package/src/experimental/transports/jsonRPC.ts +21 -11
- package/src/experimental/transports/utils.ts +1 -1
- package/src/experimental/types.ts +59 -1
- package/src/graphql/client.ts +7 -1
- package/src/transactions/index.ts +5 -1
- package/src/transactions/plugins/NamedPackagesPlugin.ts +46 -120
- package/src/transactions/resolve.ts +6 -3
- package/src/version.ts +1 -1
- package/dist/cjs/transactions/plugins/utils.d.ts +0 -31
- package/dist/cjs/transactions/plugins/utils.js +0 -144
- package/dist/cjs/transactions/plugins/utils.js.map +0 -7
- package/dist/esm/transactions/plugins/utils.d.ts +0 -31
- package/dist/esm/transactions/plugins/utils.js +0 -124
- package/dist/esm/transactions/plugins/utils.js.map +0 -7
- 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(
|
|
37
|
-
|
|
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:
|
|
106
|
-
|
|
107
|
-
|
|
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:
|
|
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:
|
|
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(
|
|
28
|
-
|
|
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 =
|
|
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:
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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/
|
|
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 {
|