@polkadot-api/metadata-builders 0.2.0 → 0.3.1
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/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +366 -252
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +366 -252
- package/dist/index.mjs.map +1 -1
- package/dist/min/index.d.ts +2 -2
- package/dist/min/index.js +1 -1
- package/dist/min/index.js.map +1 -1
- package/package.json +3 -8
package/dist/index.mjs
CHANGED
|
@@ -6,8 +6,7 @@ var getLookupFn = (lookupData) => {
|
|
|
6
6
|
const withCache2 = (fn) => {
|
|
7
7
|
return (id) => {
|
|
8
8
|
let entry = lookups.get(id);
|
|
9
|
-
if (entry)
|
|
10
|
-
return entry;
|
|
9
|
+
if (entry) return entry;
|
|
11
10
|
if (from.has(id)) {
|
|
12
11
|
const entry2 = {
|
|
13
12
|
id
|
|
@@ -36,8 +35,7 @@ var getLookupFn = (lookupData) => {
|
|
|
36
35
|
const getLookupEntryDef = withCache2((id) => {
|
|
37
36
|
const { def, path, params } = lookupData[id];
|
|
38
37
|
if (def.tag === "composite") {
|
|
39
|
-
if (def.value.length === 0)
|
|
40
|
-
return { type: "void" };
|
|
38
|
+
if (def.value.length === 0) return { type: "void" };
|
|
41
39
|
if (def.value.length === 1) {
|
|
42
40
|
const inner = getLookupEntryDef(def.value[0].type);
|
|
43
41
|
if (isAccountId32SearchOn && path.at(-1) === "AccountId32" && isBytes(inner, 32)) {
|
|
@@ -90,8 +88,7 @@ var getLookupFn = (lookupData) => {
|
|
|
90
88
|
}
|
|
91
89
|
};
|
|
92
90
|
}
|
|
93
|
-
if (def.value.length === 0)
|
|
94
|
-
return { type: "void" };
|
|
91
|
+
if (def.value.length === 0) return { type: "void" };
|
|
95
92
|
const enumValue = {};
|
|
96
93
|
const enumDocs = {};
|
|
97
94
|
def.value.forEach((x) => {
|
|
@@ -118,17 +115,29 @@ var getLookupFn = (lookupData) => {
|
|
|
118
115
|
values[key2] = getLookupEntryDef(x2.type);
|
|
119
116
|
innerDocs[key2] = x2.docs;
|
|
120
117
|
});
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
118
|
+
if (allKey) {
|
|
119
|
+
enumValue[key] = {
|
|
120
|
+
type: "struct",
|
|
121
|
+
value: values,
|
|
122
|
+
innerDocs,
|
|
123
|
+
idx: x.index
|
|
124
|
+
};
|
|
125
|
+
} else {
|
|
126
|
+
const valuesArr = Object.values(values);
|
|
127
|
+
const innerDocsArr = Object.values(innerDocs);
|
|
128
|
+
const areAllSame = valuesArr.every((v) => v.id === valuesArr[0].id);
|
|
129
|
+
enumValue[key] = areAllSame && innerDocsArr.every((doc) => doc.length === 0) ? {
|
|
130
|
+
type: "array",
|
|
131
|
+
value: valuesArr[0],
|
|
132
|
+
len: valuesArr.length,
|
|
133
|
+
idx: x.index
|
|
134
|
+
} : {
|
|
135
|
+
type: "tuple",
|
|
136
|
+
value: valuesArr,
|
|
137
|
+
innerDocs: innerDocsArr,
|
|
138
|
+
idx: x.index
|
|
139
|
+
};
|
|
140
|
+
}
|
|
132
141
|
});
|
|
133
142
|
return {
|
|
134
143
|
type: "enum",
|
|
@@ -146,10 +155,8 @@ var getLookupFn = (lookupData) => {
|
|
|
146
155
|
if (def.tag === "array") {
|
|
147
156
|
const { len } = def.value;
|
|
148
157
|
const value = getLookupEntryDef(def.value.type);
|
|
149
|
-
if (len === 0)
|
|
150
|
-
|
|
151
|
-
if (len === 1)
|
|
152
|
-
return value;
|
|
158
|
+
if (len === 0) return { type: "void" };
|
|
159
|
+
if (len === 1) return value;
|
|
153
160
|
return {
|
|
154
161
|
type: "array",
|
|
155
162
|
value,
|
|
@@ -157,8 +164,7 @@ var getLookupFn = (lookupData) => {
|
|
|
157
164
|
};
|
|
158
165
|
}
|
|
159
166
|
if (def.tag === "tuple") {
|
|
160
|
-
if (def.value.length === 0)
|
|
161
|
-
return { type: "void" };
|
|
167
|
+
if (def.value.length === 0) return { type: "void" };
|
|
162
168
|
if (def.value.length === 1)
|
|
163
169
|
return getLookupEntryDef(def.value[0]);
|
|
164
170
|
const value = def.value.map((x) => getLookupEntryDef(x));
|
|
@@ -185,8 +191,7 @@ var getLookupFn = (lookupData) => {
|
|
|
185
191
|
}
|
|
186
192
|
if (def.tag === "compact") {
|
|
187
193
|
const translated = getLookupEntryDef(def.value);
|
|
188
|
-
if (translated.type === "void")
|
|
189
|
-
return { type: "compact", isBig: null };
|
|
194
|
+
if (translated.type === "void") return { type: "compact", isBig: null };
|
|
190
195
|
const isBig = Number(translated.value.slice(1)) > 32;
|
|
191
196
|
return {
|
|
192
197
|
type: "compact",
|
|
@@ -206,8 +211,7 @@ import * as scale from "@polkadot-api/substrate-bindings";
|
|
|
206
211
|
// src/with-cache.ts
|
|
207
212
|
var withCache = (fn, onEnterCircular, onExitCircular) => (input, cache, stack, ...rest) => {
|
|
208
213
|
const { id } = input;
|
|
209
|
-
if (cache.has(id))
|
|
210
|
-
return cache.get(id);
|
|
214
|
+
if (cache.has(id)) return cache.get(id);
|
|
211
215
|
if (stack.has(id)) {
|
|
212
216
|
const res = onEnterCircular(() => cache.get(id), input, ...rest);
|
|
213
217
|
cache.set(id, res);
|
|
@@ -226,18 +230,12 @@ var withCache = (fn, onEnterCircular, onExitCircular) => (input, cache, stack, .
|
|
|
226
230
|
import { mapObject } from "@polkadot-api/utils";
|
|
227
231
|
var _bytes = scale.Bin();
|
|
228
232
|
var _buildCodec = (input, cache, stack, _accountId) => {
|
|
229
|
-
if (input.type === "primitive")
|
|
230
|
-
|
|
231
|
-
if (input.type === "
|
|
232
|
-
|
|
233
|
-
if (input.type === "
|
|
234
|
-
|
|
235
|
-
if (input.type === "AccountId20")
|
|
236
|
-
return scale.ethAccount;
|
|
237
|
-
if (input.type === "compact")
|
|
238
|
-
return scale.compact;
|
|
239
|
-
if (input.type === "bitSequence")
|
|
240
|
-
return scale.bitSequence;
|
|
233
|
+
if (input.type === "primitive") return scale[input.value];
|
|
234
|
+
if (input.type === "void") return scale._void;
|
|
235
|
+
if (input.type === "AccountId32") return _accountId;
|
|
236
|
+
if (input.type === "AccountId20") return scale.ethAccount;
|
|
237
|
+
if (input.type === "compact") return scale.compact;
|
|
238
|
+
if (input.type === "bitSequence") return scale.bitSequence;
|
|
241
239
|
const buildNextCodec = (nextInput) => buildCodec(nextInput, cache, stack, _accountId);
|
|
242
240
|
const buildVector = (inner2, len) => {
|
|
243
241
|
const innerCodec = buildNextCodec(inner2);
|
|
@@ -258,25 +256,28 @@ var _buildCodec = (input, cache, stack, _accountId) => {
|
|
|
258
256
|
return scale.Bin(input.len);
|
|
259
257
|
return buildVector(input.value, input.len);
|
|
260
258
|
}
|
|
261
|
-
if (input.type === "sequence")
|
|
262
|
-
|
|
263
|
-
if (input.type === "
|
|
264
|
-
|
|
265
|
-
if (input.type === "struct")
|
|
266
|
-
return buildStruct(input.value);
|
|
267
|
-
if (input.type === "option")
|
|
268
|
-
return scale.Option(buildNextCodec(input.value));
|
|
259
|
+
if (input.type === "sequence") return buildVector(input.value);
|
|
260
|
+
if (input.type === "tuple") return buildTuple(input.value);
|
|
261
|
+
if (input.type === "struct") return buildStruct(input.value);
|
|
262
|
+
if (input.type === "option") return scale.Option(buildNextCodec(input.value));
|
|
269
263
|
if (input.type === "result")
|
|
270
264
|
return scale.Result(
|
|
271
265
|
buildNextCodec(input.value.ok),
|
|
272
266
|
buildNextCodec(input.value.ko)
|
|
273
267
|
);
|
|
274
268
|
const dependencies = Object.values(input.value).map((v) => {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
269
|
+
switch (v.type) {
|
|
270
|
+
case "void":
|
|
271
|
+
return scale._void;
|
|
272
|
+
case "lookupEntry":
|
|
273
|
+
return buildNextCodec(v.value);
|
|
274
|
+
case "tuple":
|
|
275
|
+
return buildTuple(v.value);
|
|
276
|
+
case "struct":
|
|
277
|
+
return buildStruct(v.value);
|
|
278
|
+
case "array":
|
|
279
|
+
return buildVector(v.value, v.len);
|
|
280
|
+
}
|
|
280
281
|
});
|
|
281
282
|
const inner = Object.fromEntries(
|
|
282
283
|
Object.keys(input.value).map((key, idx) => {
|
|
@@ -329,24 +330,42 @@ var getDynamicBuilder = (metadata) => {
|
|
|
329
330
|
const { key, value, hashers } = storageEntry.type.value;
|
|
330
331
|
const val = buildDefinition(value);
|
|
331
332
|
const hashes = hashers.map((x) => scale[x.tag]);
|
|
332
|
-
const hashArgs =
|
|
333
|
-
(
|
|
334
|
-
buildDefinition(
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
333
|
+
const hashArgs = (() => {
|
|
334
|
+
if (hashes.length === 1) {
|
|
335
|
+
return [[buildDefinition(key), hashes[0]]];
|
|
336
|
+
}
|
|
337
|
+
const keyDef = getLookupEntryDef(key);
|
|
338
|
+
switch (keyDef.type) {
|
|
339
|
+
case "array":
|
|
340
|
+
return hashes.map((hash) => [buildDefinition(keyDef.value.id), hash]);
|
|
341
|
+
case "tuple":
|
|
342
|
+
return keyDef.value.map((x, idx) => [
|
|
343
|
+
buildDefinition(x.id),
|
|
344
|
+
hashes[idx]
|
|
345
|
+
]);
|
|
346
|
+
default:
|
|
347
|
+
throw new Error("Invalid key type");
|
|
348
|
+
}
|
|
349
|
+
})();
|
|
338
350
|
return storageWithFallback(hashes.length, entry, val.dec, ...hashArgs);
|
|
339
351
|
};
|
|
340
352
|
const buildEnumEntry = (entry) => {
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
353
|
+
switch (entry.type) {
|
|
354
|
+
case "void":
|
|
355
|
+
return scale._void;
|
|
356
|
+
case "lookupEntry":
|
|
357
|
+
return buildDefinition(entry.value.id);
|
|
358
|
+
case "tuple":
|
|
359
|
+
return scale.Tuple(
|
|
360
|
+
...Object.values(entry.value).map((l) => buildDefinition(l.id))
|
|
361
|
+
);
|
|
362
|
+
case "struct":
|
|
363
|
+
return scale.Struct(
|
|
364
|
+
mapObject(entry.value, (x) => buildDefinition(x.id))
|
|
365
|
+
);
|
|
366
|
+
case "array":
|
|
367
|
+
return scale.Vector(buildDefinition(entry.value.id), entry.len);
|
|
368
|
+
}
|
|
350
369
|
};
|
|
351
370
|
const buildConstant = (pallet, constantName) => {
|
|
352
371
|
const storageEntry = metadata.pallets.find((x) => x.name === pallet).constants.find((s) => s.name === constantName);
|
|
@@ -355,8 +374,7 @@ var getDynamicBuilder = (metadata) => {
|
|
|
355
374
|
const buildVariant = (type) => (pallet, name) => {
|
|
356
375
|
const palletEntry = metadata.pallets.find((x) => x.name === pallet);
|
|
357
376
|
const lookup = getLookupEntryDef(palletEntry[type]);
|
|
358
|
-
if (lookup.type !== "enum")
|
|
359
|
-
throw null;
|
|
377
|
+
if (lookup.type !== "enum") throw null;
|
|
360
378
|
const entry = lookup.value[name];
|
|
361
379
|
return {
|
|
362
380
|
location: [palletEntry.index, entry.idx],
|
|
@@ -365,8 +383,7 @@ var getDynamicBuilder = (metadata) => {
|
|
|
365
383
|
};
|
|
366
384
|
const buildRuntimeCall = (api, method) => {
|
|
367
385
|
const entry = metadata.apis.find((x) => x.name === api)?.methods.find((x) => x.name === method);
|
|
368
|
-
if (!entry)
|
|
369
|
-
throw null;
|
|
386
|
+
if (!entry) throw null;
|
|
370
387
|
return {
|
|
371
388
|
args: scale.Tuple(...entry.inputs.map((x) => buildDefinition(x.type))),
|
|
372
389
|
value: buildDefinition(entry.output)
|
|
@@ -386,13 +403,174 @@ var getDynamicBuilder = (metadata) => {
|
|
|
386
403
|
|
|
387
404
|
// src/checksum-builder.ts
|
|
388
405
|
import { h64 } from "@polkadot-api/substrate-bindings";
|
|
406
|
+
|
|
407
|
+
// src/lookup-graph.ts
|
|
408
|
+
function buildLookupGraph(lookupFn, lookupLength) {
|
|
409
|
+
const result = /* @__PURE__ */ new Map();
|
|
410
|
+
const visited = /* @__PURE__ */ new Set();
|
|
411
|
+
const addEdge = (from, to) => {
|
|
412
|
+
if (!result.has(from))
|
|
413
|
+
result.set(from, {
|
|
414
|
+
entry: lookupFn(from),
|
|
415
|
+
backRefs: /* @__PURE__ */ new Set(),
|
|
416
|
+
refs: /* @__PURE__ */ new Set()
|
|
417
|
+
});
|
|
418
|
+
if (!result.has(to))
|
|
419
|
+
result.set(to, {
|
|
420
|
+
entry: lookupFn(to),
|
|
421
|
+
backRefs: /* @__PURE__ */ new Set(),
|
|
422
|
+
refs: /* @__PURE__ */ new Set()
|
|
423
|
+
});
|
|
424
|
+
result.get(from).refs.add(to);
|
|
425
|
+
result.get(to).backRefs.add(from);
|
|
426
|
+
};
|
|
427
|
+
for (let i = 0; i < lookupLength; i++) {
|
|
428
|
+
const entry = lookupFn(i);
|
|
429
|
+
if (i !== entry.id) {
|
|
430
|
+
addEdge(i, entry.id);
|
|
431
|
+
}
|
|
432
|
+
if (visited.has(entry.id)) continue;
|
|
433
|
+
visited.add(entry.id);
|
|
434
|
+
switch (entry.type) {
|
|
435
|
+
case "array":
|
|
436
|
+
case "option":
|
|
437
|
+
case "sequence":
|
|
438
|
+
addEdge(entry.id, entry.value.id);
|
|
439
|
+
break;
|
|
440
|
+
case "enum":
|
|
441
|
+
Object.values(entry.value).forEach((enumEntry) => {
|
|
442
|
+
switch (enumEntry.type) {
|
|
443
|
+
case "array":
|
|
444
|
+
case "lookupEntry":
|
|
445
|
+
addEdge(entry.id, enumEntry.value.id);
|
|
446
|
+
break;
|
|
447
|
+
case "struct":
|
|
448
|
+
case "tuple":
|
|
449
|
+
Object.values(enumEntry.value).forEach(
|
|
450
|
+
(v) => addEdge(entry.id, v.id)
|
|
451
|
+
);
|
|
452
|
+
break;
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
break;
|
|
456
|
+
case "result":
|
|
457
|
+
addEdge(entry.id, entry.value.ok.id);
|
|
458
|
+
addEdge(entry.id, entry.value.ko.id);
|
|
459
|
+
break;
|
|
460
|
+
case "struct":
|
|
461
|
+
case "tuple":
|
|
462
|
+
Object.values(entry.value).forEach((v) => addEdge(entry.id, v.id));
|
|
463
|
+
break;
|
|
464
|
+
}
|
|
465
|
+
if (!result.has(entry.id)) {
|
|
466
|
+
result.set(entry.id, {
|
|
467
|
+
backRefs: /* @__PURE__ */ new Set(),
|
|
468
|
+
refs: /* @__PURE__ */ new Set(),
|
|
469
|
+
entry
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
return result;
|
|
474
|
+
}
|
|
475
|
+
var subgraphCache = /* @__PURE__ */ new WeakMap();
|
|
476
|
+
function _getSubgraph(id, graph, result, cache) {
|
|
477
|
+
if (result.has(id)) return;
|
|
478
|
+
const node = graph.get(id);
|
|
479
|
+
result.set(id, node);
|
|
480
|
+
cache.set(id, result);
|
|
481
|
+
node.refs.forEach((ref) => _getSubgraph(ref, graph, result, cache));
|
|
482
|
+
node.backRefs.forEach((ref) => _getSubgraph(ref, graph, result, cache));
|
|
483
|
+
}
|
|
484
|
+
function getSubgraph(id, graph) {
|
|
485
|
+
if (!subgraphCache.has(graph)) {
|
|
486
|
+
subgraphCache.set(graph, /* @__PURE__ */ new Map());
|
|
487
|
+
}
|
|
488
|
+
const cache = subgraphCache.get(graph);
|
|
489
|
+
if (cache.has(id)) return cache.get(id);
|
|
490
|
+
const result = /* @__PURE__ */ new Map();
|
|
491
|
+
_getSubgraph(id, graph, result, cache);
|
|
492
|
+
return result;
|
|
493
|
+
}
|
|
494
|
+
function getStronglyConnectedComponents(graph) {
|
|
495
|
+
const tarjanState = /* @__PURE__ */ new Map();
|
|
496
|
+
let index = 0;
|
|
497
|
+
const stack = [];
|
|
498
|
+
const result = [];
|
|
499
|
+
function strongConnect(v) {
|
|
500
|
+
const state = {
|
|
501
|
+
index,
|
|
502
|
+
lowLink: index,
|
|
503
|
+
onStack: true
|
|
504
|
+
};
|
|
505
|
+
tarjanState.set(v, state);
|
|
506
|
+
index++;
|
|
507
|
+
stack.push(v);
|
|
508
|
+
const edges = graph.get(v).refs;
|
|
509
|
+
for (let w of edges) {
|
|
510
|
+
const edgeState = tarjanState.get(w);
|
|
511
|
+
if (!edgeState) {
|
|
512
|
+
strongConnect(w);
|
|
513
|
+
state.lowLink = Math.min(state.lowLink, tarjanState.get(w).lowLink);
|
|
514
|
+
} else if (edgeState.onStack) {
|
|
515
|
+
state.lowLink = Math.min(state.lowLink, edgeState.index);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
if (state.lowLink === state.index) {
|
|
519
|
+
const component = /* @__PURE__ */ new Set();
|
|
520
|
+
let poppedNode = -1;
|
|
521
|
+
do {
|
|
522
|
+
poppedNode = stack.pop();
|
|
523
|
+
tarjanState.get(poppedNode).onStack = false;
|
|
524
|
+
component.add(poppedNode);
|
|
525
|
+
} while (poppedNode !== v);
|
|
526
|
+
if (component.size > 1) result.push(component);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
for (const node of graph.keys()) {
|
|
530
|
+
if (!tarjanState.has(node)) {
|
|
531
|
+
strongConnect(node);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
return result;
|
|
535
|
+
}
|
|
536
|
+
function mergeSCCsWithCommonNodes(stronglyConnectedComponents) {
|
|
537
|
+
const scc = stronglyConnectedComponents;
|
|
538
|
+
const ungroupedCycles = new Set(scc.map((_, i) => i));
|
|
539
|
+
const edges = new Map(scc.map((_, i) => [i, /* @__PURE__ */ new Set()]));
|
|
540
|
+
scc.forEach((cycle, i) => {
|
|
541
|
+
scc.slice(i + 1).forEach((otherCycle, _j) => {
|
|
542
|
+
const j = _j + i + 1;
|
|
543
|
+
const combined = /* @__PURE__ */ new Set([...cycle, ...otherCycle]);
|
|
544
|
+
if (combined.size !== cycle.size + otherCycle.size) {
|
|
545
|
+
edges.get(i).add(j);
|
|
546
|
+
edges.get(j).add(i);
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
});
|
|
550
|
+
const groups = [];
|
|
551
|
+
while (ungroupedCycles.size) {
|
|
552
|
+
const group = /* @__PURE__ */ new Set();
|
|
553
|
+
const toVisit = [ungroupedCycles.values().next().value];
|
|
554
|
+
while (toVisit.length) {
|
|
555
|
+
const idx = toVisit.pop();
|
|
556
|
+
if (!ungroupedCycles.has(idx)) continue;
|
|
557
|
+
ungroupedCycles.delete(idx);
|
|
558
|
+
const cycle = scc[idx];
|
|
559
|
+
cycle.forEach((v) => group.add(Number(v)));
|
|
560
|
+
edges.get(idx).forEach((n) => toVisit.push(n));
|
|
561
|
+
}
|
|
562
|
+
groups.push(group);
|
|
563
|
+
}
|
|
564
|
+
return groups;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
// src/checksum-builder.ts
|
|
389
568
|
var textEncoder = new TextEncoder();
|
|
390
569
|
var encodeText = textEncoder.encode.bind(textEncoder);
|
|
391
570
|
var getChecksum = (values) => {
|
|
392
571
|
const res = new Uint8Array(values.length * 8);
|
|
393
572
|
const dv = new DataView(res.buffer);
|
|
394
|
-
for (let i = 0; i < values.length; i++)
|
|
395
|
-
dv.setBigUint64(i * 8, values[i]);
|
|
573
|
+
for (let i = 0; i < values.length; i++) dv.setBigUint64(i * 8, values[i]);
|
|
396
574
|
return h64(res);
|
|
397
575
|
};
|
|
398
576
|
var getStringChecksum = (values) => getChecksum(values.map((v) => h64(encodeText(v))));
|
|
@@ -448,61 +626,10 @@ var structLikeBuilder = (shapeId, input, innerChecksum) => {
|
|
|
448
626
|
);
|
|
449
627
|
return getChecksum([shapeId, keysChecksum, valuesChecksum]);
|
|
450
628
|
};
|
|
451
|
-
var buildGraph = (entry, result = /* @__PURE__ */ new Map()) => {
|
|
452
|
-
if (result.has(entry.id))
|
|
453
|
-
return result;
|
|
454
|
-
switch (entry.type) {
|
|
455
|
-
case "array":
|
|
456
|
-
case "option":
|
|
457
|
-
case "sequence":
|
|
458
|
-
result.set(entry.id, [entry, /* @__PURE__ */ new Set([entry.value.id])]);
|
|
459
|
-
buildGraph(entry.value, result);
|
|
460
|
-
break;
|
|
461
|
-
case "enum": {
|
|
462
|
-
const children = Object.values(entry.value).flatMap((value) => {
|
|
463
|
-
if (value.type === "void")
|
|
464
|
-
return [];
|
|
465
|
-
if (value.type === "lookupEntry")
|
|
466
|
-
return value.value;
|
|
467
|
-
if (value.type === "struct")
|
|
468
|
-
return Object.values(value.value);
|
|
469
|
-
return value.value;
|
|
470
|
-
});
|
|
471
|
-
result.set(entry.id, [entry, new Set(children.map((child) => child.id))]);
|
|
472
|
-
children.forEach((child) => buildGraph(child, result));
|
|
473
|
-
break;
|
|
474
|
-
}
|
|
475
|
-
case "result":
|
|
476
|
-
result.set(entry.id, [
|
|
477
|
-
entry,
|
|
478
|
-
/* @__PURE__ */ new Set([entry.value.ok.id, entry.value.ko.id])
|
|
479
|
-
]);
|
|
480
|
-
buildGraph(entry.value.ok, result);
|
|
481
|
-
buildGraph(entry.value.ko, result);
|
|
482
|
-
break;
|
|
483
|
-
case "struct": {
|
|
484
|
-
const children = Object.values(entry.value);
|
|
485
|
-
result.set(entry.id, [entry, new Set(children.map((child) => child.id))]);
|
|
486
|
-
children.forEach((child) => buildGraph(child, result));
|
|
487
|
-
break;
|
|
488
|
-
}
|
|
489
|
-
case "tuple":
|
|
490
|
-
result.set(entry.id, [
|
|
491
|
-
entry,
|
|
492
|
-
new Set(entry.value.map((child) => child.id))
|
|
493
|
-
]);
|
|
494
|
-
entry.value.forEach((child) => buildGraph(child, result));
|
|
495
|
-
break;
|
|
496
|
-
default:
|
|
497
|
-
result.set(entry.id, [entry, /* @__PURE__ */ new Set()]);
|
|
498
|
-
}
|
|
499
|
-
return result;
|
|
500
|
-
};
|
|
501
629
|
var _buildChecksum = (input, buildNextChecksum) => {
|
|
502
630
|
if (input.type === "primitive")
|
|
503
631
|
return getChecksum([shapeIds.primitive, metadataPrimitiveIds[input.value]]);
|
|
504
|
-
if (input.type === "void")
|
|
505
|
-
return getChecksum([shapeIds.void]);
|
|
632
|
+
if (input.type === "void") return getChecksum([shapeIds.void]);
|
|
506
633
|
if (input.type === "compact")
|
|
507
634
|
return getChecksum([
|
|
508
635
|
shapeIds.primitive,
|
|
@@ -516,6 +643,12 @@ var _buildChecksum = (input, buildNextChecksum) => {
|
|
|
516
643
|
if (input.type === "AccountId20") {
|
|
517
644
|
return getChecksum([shapeIds.primitive, runtimePrimitiveIds.accountId20]);
|
|
518
645
|
}
|
|
646
|
+
const buildVector = (entry, length) => {
|
|
647
|
+
const innerChecksum = buildNextChecksum(entry);
|
|
648
|
+
return getChecksum(
|
|
649
|
+
length !== void 0 ? [shapeIds.vector, innerChecksum, BigInt(length)] : [shapeIds.vector, innerChecksum]
|
|
650
|
+
);
|
|
651
|
+
};
|
|
519
652
|
if (input.type === "array") {
|
|
520
653
|
const innerValue = input.value;
|
|
521
654
|
if (innerValue.type === "primitive" && innerValue.value === "u8") {
|
|
@@ -525,23 +658,19 @@ var _buildChecksum = (input, buildNextChecksum) => {
|
|
|
525
658
|
BigInt(input.len)
|
|
526
659
|
]);
|
|
527
660
|
}
|
|
528
|
-
|
|
529
|
-
return getChecksum([shapeIds.vector, innerChecksum, BigInt(input.len)]);
|
|
661
|
+
return buildVector(innerValue, input.len);
|
|
530
662
|
}
|
|
531
663
|
if (input.type === "sequence") {
|
|
532
664
|
const innerValue = input.value;
|
|
533
665
|
if (innerValue.type === "primitive" && innerValue.value === "u8") {
|
|
534
666
|
return getChecksum([shapeIds.primitive, runtimePrimitiveIds.byteSequence]);
|
|
535
667
|
}
|
|
536
|
-
|
|
537
|
-
return getChecksum([shapeIds.vector, innerChecksum]);
|
|
668
|
+
return buildVector(innerValue);
|
|
538
669
|
}
|
|
539
670
|
const buildTuple = (entries) => getChecksum([shapeIds.tuple, ...entries.map(buildNextChecksum)]);
|
|
540
671
|
const buildStruct = (entries) => structLikeBuilder(shapeIds.struct, entries, buildNextChecksum);
|
|
541
|
-
if (input.type === "tuple")
|
|
542
|
-
|
|
543
|
-
if (input.type === "struct")
|
|
544
|
-
return buildStruct(input.value);
|
|
672
|
+
if (input.type === "tuple") return buildTuple(input.value);
|
|
673
|
+
if (input.type === "struct") return buildStruct(input.value);
|
|
545
674
|
if (input.type === "option")
|
|
546
675
|
return getChecksum([shapeIds.option, buildNextChecksum(input.value)]);
|
|
547
676
|
if (input.type === "result")
|
|
@@ -551,8 +680,7 @@ var _buildChecksum = (input, buildNextChecksum) => {
|
|
|
551
680
|
buildNextChecksum(input.value.ko)
|
|
552
681
|
]);
|
|
553
682
|
return structLikeBuilder(shapeIds.enum, input.value, (entry) => {
|
|
554
|
-
if (entry.type === "lookupEntry")
|
|
555
|
-
return buildNextChecksum(entry.value);
|
|
683
|
+
if (entry.type === "lookupEntry") return buildNextChecksum(entry.value);
|
|
556
684
|
switch (entry.type) {
|
|
557
685
|
case "void":
|
|
558
686
|
return getChecksum([shapeIds.void]);
|
|
@@ -560,147 +688,129 @@ var _buildChecksum = (input, buildNextChecksum) => {
|
|
|
560
688
|
return buildTuple(entry.value);
|
|
561
689
|
case "struct":
|
|
562
690
|
return buildStruct(entry.value);
|
|
691
|
+
case "array":
|
|
692
|
+
return buildVector(entry.value, entry.len);
|
|
563
693
|
}
|
|
564
694
|
});
|
|
565
695
|
};
|
|
566
|
-
var getCycles = (graph) => {
|
|
567
|
-
const tarjanState = /* @__PURE__ */ new Map();
|
|
568
|
-
let index = 0;
|
|
569
|
-
const stack = [];
|
|
570
|
-
const result = [];
|
|
571
|
-
function strongConnect(v) {
|
|
572
|
-
const state = {
|
|
573
|
-
index,
|
|
574
|
-
lowLink: index,
|
|
575
|
-
onStack: true
|
|
576
|
-
};
|
|
577
|
-
tarjanState.set(v, state);
|
|
578
|
-
index++;
|
|
579
|
-
stack.push(v);
|
|
580
|
-
const edges = graph.get(v)[1];
|
|
581
|
-
for (let w of edges) {
|
|
582
|
-
const edgeState = tarjanState.get(w);
|
|
583
|
-
if (!edgeState) {
|
|
584
|
-
strongConnect(w);
|
|
585
|
-
state.lowLink = Math.min(state.lowLink, tarjanState.get(w).lowLink);
|
|
586
|
-
} else if (edgeState.onStack) {
|
|
587
|
-
state.lowLink = Math.min(state.lowLink, edgeState.index);
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
if (state.lowLink === state.index) {
|
|
591
|
-
const component = /* @__PURE__ */ new Set();
|
|
592
|
-
let poppedNode = -1;
|
|
593
|
-
do {
|
|
594
|
-
poppedNode = stack.pop();
|
|
595
|
-
tarjanState.get(poppedNode).onStack = false;
|
|
596
|
-
component.add(poppedNode);
|
|
597
|
-
} while (poppedNode !== v);
|
|
598
|
-
if (component.size > 1)
|
|
599
|
-
result.push(component);
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
for (const node of graph.keys()) {
|
|
603
|
-
if (!tarjanState.has(node)) {
|
|
604
|
-
strongConnect(node);
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
return result;
|
|
608
|
-
};
|
|
609
|
-
var getCyclicGroups = (cycles) => {
|
|
610
|
-
const ungroupedCycles = new Set(cycles.map((_, i) => i));
|
|
611
|
-
const edges = new Map(cycles.map((_, i) => [i, /* @__PURE__ */ new Set()]));
|
|
612
|
-
cycles.forEach((cycle, i) => {
|
|
613
|
-
cycles.slice(i + 1).forEach((otherCycle, _j) => {
|
|
614
|
-
const j = _j + i + 1;
|
|
615
|
-
const combined = /* @__PURE__ */ new Set([...cycle, ...otherCycle]);
|
|
616
|
-
if (combined.size !== cycle.size + otherCycle.size) {
|
|
617
|
-
edges.get(i).add(j);
|
|
618
|
-
edges.get(j).add(i);
|
|
619
|
-
}
|
|
620
|
-
});
|
|
621
|
-
});
|
|
622
|
-
const groups = [];
|
|
623
|
-
while (ungroupedCycles.size) {
|
|
624
|
-
const group = /* @__PURE__ */ new Set();
|
|
625
|
-
const toVisit = [ungroupedCycles.values().next().value];
|
|
626
|
-
while (toVisit.length) {
|
|
627
|
-
const idx = toVisit.pop();
|
|
628
|
-
if (!ungroupedCycles.has(idx))
|
|
629
|
-
continue;
|
|
630
|
-
ungroupedCycles.delete(idx);
|
|
631
|
-
const cycle = cycles[idx];
|
|
632
|
-
cycle.forEach((v) => group.add(Number(v)));
|
|
633
|
-
edges.get(idx).forEach((n) => toVisit.push(n));
|
|
634
|
-
}
|
|
635
|
-
groups.push(group);
|
|
636
|
-
}
|
|
637
|
-
return groups;
|
|
638
|
-
};
|
|
639
696
|
var sortCyclicGroups = (groups, graph) => {
|
|
640
697
|
const getReachableNodes = (group) => {
|
|
641
|
-
const
|
|
642
|
-
const
|
|
643
|
-
|
|
698
|
+
const result2 = /* @__PURE__ */ new Set();
|
|
699
|
+
const toVisit = Array.from(group);
|
|
700
|
+
while (toVisit.length) {
|
|
701
|
+
const id = toVisit.pop();
|
|
702
|
+
if (result2.has(id)) continue;
|
|
703
|
+
result2.add(id);
|
|
704
|
+
graph.get(id)?.refs.forEach((id2) => toVisit.push(id2));
|
|
705
|
+
}
|
|
706
|
+
return Array.from(result2);
|
|
644
707
|
};
|
|
645
708
|
const result = new Array();
|
|
646
709
|
function dependentsFirst(group) {
|
|
647
|
-
if (result.includes(group))
|
|
648
|
-
return;
|
|
710
|
+
if (result.includes(group)) return;
|
|
649
711
|
const dependents = groups.filter(
|
|
650
712
|
(candidate) => candidate !== group && getReachableNodes(group).some((node) => candidate.has(node))
|
|
651
713
|
);
|
|
652
714
|
dependents.forEach((group2) => dependentsFirst(group2));
|
|
653
|
-
if (result.includes(group))
|
|
654
|
-
return;
|
|
715
|
+
if (result.includes(group)) return;
|
|
655
716
|
result.push(group);
|
|
656
717
|
}
|
|
657
718
|
groups.forEach((group) => dependentsFirst(group));
|
|
658
719
|
return result;
|
|
659
720
|
};
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
const
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
const sortedCyclicGroups = sortCyclicGroups(cyclicGroups, graph);
|
|
667
|
-
const recursiveBuildChecksum = (entry2, writeCache, skipCache = false) => {
|
|
668
|
-
if (!skipCache && cache.has(entry2.id)) {
|
|
669
|
-
return cache.get(entry2.id);
|
|
721
|
+
function iterateChecksums(group, iterations, cache, graph) {
|
|
722
|
+
const groupReadCache = new Map([...group].map((id) => [id, 0n]));
|
|
723
|
+
const groupWriteCache = /* @__PURE__ */ new Map();
|
|
724
|
+
const recursiveBuildChecksum = (entry, skipCache = true) => {
|
|
725
|
+
if (!skipCache && (groupReadCache.has(entry.id) || cache.has(entry.id))) {
|
|
726
|
+
return groupReadCache.get(entry.id) ?? cache.get(entry.id);
|
|
670
727
|
}
|
|
671
728
|
const result = _buildChecksum(
|
|
672
|
-
|
|
673
|
-
(nextEntry) => recursiveBuildChecksum(nextEntry,
|
|
729
|
+
entry,
|
|
730
|
+
(nextEntry) => recursiveBuildChecksum(nextEntry, false)
|
|
674
731
|
);
|
|
675
|
-
|
|
732
|
+
if (group.has(entry.id)) {
|
|
733
|
+
groupWriteCache.set(entry.id, result);
|
|
734
|
+
} else {
|
|
735
|
+
cache.set(entry.id, result);
|
|
736
|
+
}
|
|
676
737
|
return result;
|
|
677
738
|
};
|
|
739
|
+
for (let i = 0; i < iterations; i++) {
|
|
740
|
+
group.forEach((id) => recursiveBuildChecksum(graph.get(id).entry));
|
|
741
|
+
group.forEach((id) => groupReadCache.set(id, groupWriteCache.get(id)));
|
|
742
|
+
}
|
|
743
|
+
return groupReadCache;
|
|
744
|
+
}
|
|
745
|
+
function getMirroredNodes(cyclicGroups, graph) {
|
|
746
|
+
const maxSize = cyclicGroups.reduce(
|
|
747
|
+
(acc, group) => Math.max(acc, group.size),
|
|
748
|
+
0
|
|
749
|
+
);
|
|
750
|
+
const allEntries = new Set([...graph.values()].map((v) => v.entry.id));
|
|
751
|
+
const resultingChecksums = iterateChecksums(
|
|
752
|
+
allEntries,
|
|
753
|
+
maxSize,
|
|
754
|
+
// Cache won't be used, since it's using the internal one for every node.
|
|
755
|
+
/* @__PURE__ */ new Map(),
|
|
756
|
+
graph
|
|
757
|
+
);
|
|
758
|
+
const checksumToNodes = /* @__PURE__ */ new Map();
|
|
759
|
+
for (const id of allEntries) {
|
|
760
|
+
const checksum = resultingChecksums.get(id);
|
|
761
|
+
if (checksum == void 0) throw new Error("Unreachable");
|
|
762
|
+
if (!checksumToNodes.has(checksum)) {
|
|
763
|
+
checksumToNodes.set(checksum, []);
|
|
764
|
+
}
|
|
765
|
+
checksumToNodes.get(checksum).push(id);
|
|
766
|
+
}
|
|
767
|
+
const checksumsWithDuplicates = [...checksumToNodes.entries()].filter(
|
|
768
|
+
([, nodes]) => nodes.length > 1
|
|
769
|
+
);
|
|
770
|
+
const duplicatesMap = {};
|
|
771
|
+
checksumsWithDuplicates.forEach(([, nodes]) => {
|
|
772
|
+
nodes.forEach((n) => duplicatesMap[n] = nodes);
|
|
773
|
+
});
|
|
774
|
+
return duplicatesMap;
|
|
775
|
+
}
|
|
776
|
+
var buildChecksum = (entry, cache, graph) => {
|
|
777
|
+
if (cache.has(entry.id)) return cache.get(entry.id);
|
|
778
|
+
const subGraph = getSubgraph(entry.id, graph);
|
|
779
|
+
const cycles = getStronglyConnectedComponents(subGraph);
|
|
780
|
+
const cyclicGroups = mergeSCCsWithCommonNodes(cycles).filter((group) => {
|
|
781
|
+
return !cache.has(group.values().next().value);
|
|
782
|
+
});
|
|
783
|
+
const mirrored = getMirroredNodes(cyclicGroups, subGraph);
|
|
784
|
+
const sortedCyclicGroups = sortCyclicGroups(
|
|
785
|
+
cyclicGroups.filter((group) => group.size > 1),
|
|
786
|
+
subGraph
|
|
787
|
+
);
|
|
678
788
|
sortedCyclicGroups.forEach((group) => {
|
|
679
|
-
group.
|
|
680
|
-
|
|
681
|
-
const results = /* @__PURE__ */ new Map();
|
|
682
|
-
group.forEach(
|
|
683
|
-
(id) => recursiveBuildChecksum(
|
|
684
|
-
graph.get(id)[0],
|
|
685
|
-
(id2, value) => {
|
|
686
|
-
const writeCache = group.has(id2) ? results : cache;
|
|
687
|
-
writeCache.set(id2, value);
|
|
688
|
-
},
|
|
689
|
-
true
|
|
690
|
-
)
|
|
691
|
-
);
|
|
692
|
-
Array.from(results.entries()).forEach(
|
|
693
|
-
([id, checksum]) => cache.set(id, checksum)
|
|
694
|
-
);
|
|
789
|
+
if (cache.has(group.values().next().value)) {
|
|
790
|
+
return;
|
|
695
791
|
}
|
|
792
|
+
const result = iterateChecksums(group, group.size, cache, graph);
|
|
793
|
+
group.forEach((id) => {
|
|
794
|
+
const checksum = result.get(id);
|
|
795
|
+
if (id in mirrored) {
|
|
796
|
+
mirrored[id].forEach((id2) => cache.set(id2, checksum));
|
|
797
|
+
} else {
|
|
798
|
+
cache.set(id, checksum);
|
|
799
|
+
}
|
|
800
|
+
});
|
|
696
801
|
});
|
|
697
|
-
|
|
802
|
+
const getChecksum2 = (entry2) => {
|
|
803
|
+
if (cache.has(entry2.id)) return cache.get(entry2.id);
|
|
804
|
+
return _buildChecksum(entry2, getChecksum2);
|
|
805
|
+
};
|
|
806
|
+
return getChecksum2(entry);
|
|
698
807
|
};
|
|
699
808
|
var getChecksumBuilder = (metadata) => {
|
|
700
809
|
const lookupData = metadata.lookup;
|
|
701
810
|
const getLookupEntryDef = getLookupFn(lookupData);
|
|
811
|
+
const graph = buildLookupGraph(getLookupEntryDef, lookupData.length);
|
|
702
812
|
const cache = /* @__PURE__ */ new Map();
|
|
703
|
-
const buildDefinition = (id) => buildChecksum(getLookupEntryDef(id), cache);
|
|
813
|
+
const buildDefinition = (id) => buildChecksum(getLookupEntryDef(id), cache, graph);
|
|
704
814
|
const buildStorage = (pallet, entry) => {
|
|
705
815
|
try {
|
|
706
816
|
const storageEntry = metadata.pallets.find((x) => x.name === pallet).storage.items.find((s) => s.name === entry);
|
|
@@ -717,8 +827,7 @@ var getChecksumBuilder = (metadata) => {
|
|
|
717
827
|
const buildRuntimeCall = (api, method) => {
|
|
718
828
|
try {
|
|
719
829
|
const entry = metadata.apis.find((x) => x.name === api)?.methods.find((x) => x.name === method);
|
|
720
|
-
if (!entry)
|
|
721
|
-
throw null;
|
|
830
|
+
if (!entry) throw null;
|
|
722
831
|
const argNamesChecksum = getStringChecksum(
|
|
723
832
|
entry.inputs.map((x) => x.name)
|
|
724
833
|
);
|
|
@@ -732,14 +841,20 @@ var getChecksumBuilder = (metadata) => {
|
|
|
732
841
|
}
|
|
733
842
|
};
|
|
734
843
|
const buildComposite = (input) => {
|
|
735
|
-
if (input.type === "void")
|
|
736
|
-
return getChecksum([0n]);
|
|
844
|
+
if (input.type === "void") return getChecksum([0n]);
|
|
737
845
|
if (input.type === "tuple") {
|
|
738
846
|
const values = Object.values(input.value).map(
|
|
739
847
|
(entry) => buildDefinition(entry.id)
|
|
740
848
|
);
|
|
741
849
|
return getChecksum([shapeIds.tuple, ...values]);
|
|
742
850
|
}
|
|
851
|
+
if (input.type === "array") {
|
|
852
|
+
return getChecksum([
|
|
853
|
+
shapeIds.vector,
|
|
854
|
+
buildDefinition(input.value.id),
|
|
855
|
+
BigInt(input.len)
|
|
856
|
+
]);
|
|
857
|
+
}
|
|
743
858
|
return structLikeBuilder(
|
|
744
859
|
shapeIds.struct,
|
|
745
860
|
input.value,
|
|
@@ -760,8 +875,7 @@ var getChecksumBuilder = (metadata) => {
|
|
|
760
875
|
palletEntry[variantType]
|
|
761
876
|
);
|
|
762
877
|
buildDefinition(enumLookup.id);
|
|
763
|
-
if (enumLookup.type !== "enum")
|
|
764
|
-
throw null;
|
|
878
|
+
if (enumLookup.type !== "enum") throw null;
|
|
765
879
|
const entry = enumLookup.value[name];
|
|
766
880
|
return entry.type === "lookupEntry" ? buildDefinition(entry.value.id) : buildComposite(entry);
|
|
767
881
|
} catch (_) {
|