@polkadot-api/metadata-builders 0.3.1 → 0.4.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/dist/index.mjs DELETED
@@ -1,912 +0,0 @@
1
- // src/lookups.ts
2
- var isBytes = (value, nBytes) => value.type === "array" && value.len === nBytes && value.value.type === "primitive" && value.value.value === "u8";
3
- var getLookupFn = (lookupData) => {
4
- const lookups = /* @__PURE__ */ new Map();
5
- const from = /* @__PURE__ */ new Set();
6
- const withCache2 = (fn) => {
7
- return (id) => {
8
- let entry = lookups.get(id);
9
- if (entry) return entry;
10
- if (from.has(id)) {
11
- const entry2 = {
12
- id
13
- };
14
- lookups.set(id, entry2);
15
- return entry2;
16
- }
17
- from.add(id);
18
- const value = fn(id);
19
- entry = lookups.get(id);
20
- if (entry) {
21
- Object.assign(entry, value);
22
- } else {
23
- entry = {
24
- id,
25
- ...value
26
- };
27
- lookups.set(id, entry);
28
- }
29
- from.delete(id);
30
- return entry;
31
- };
32
- };
33
- let isAccountId32SearchOn = true;
34
- let isAccountId20SearchOn = true;
35
- const getLookupEntryDef = withCache2((id) => {
36
- const { def, path, params } = lookupData[id];
37
- if (def.tag === "composite") {
38
- if (def.value.length === 0) return { type: "void" };
39
- if (def.value.length === 1) {
40
- const inner = getLookupEntryDef(def.value[0].type);
41
- if (isAccountId32SearchOn && path.at(-1) === "AccountId32" && isBytes(inner, 32)) {
42
- isAccountId32SearchOn = false;
43
- return { type: "AccountId32" };
44
- }
45
- if (isAccountId20SearchOn && path.at(-1) === "AccountId20" && isBytes(inner, 20)) {
46
- isAccountId20SearchOn = false;
47
- return { type: "AccountId20" };
48
- }
49
- return inner;
50
- }
51
- let allKey = true;
52
- const values = {};
53
- const innerDocs = {};
54
- def.value.forEach((x, idx) => {
55
- allKey = allKey && !!x.name;
56
- const key = x.name || idx;
57
- values[key] = getLookupEntryDef(x.type);
58
- innerDocs[key] = x.docs;
59
- });
60
- return allKey ? {
61
- type: "struct",
62
- value: values,
63
- innerDocs
64
- } : {
65
- type: "tuple",
66
- value: Object.values(values),
67
- innerDocs: Object.values(innerDocs)
68
- };
69
- }
70
- if (def.tag === "variant") {
71
- if (path.length === 1 && path[0] === "Option" && params.length === 1 && params[0].name === "T") {
72
- const value = getLookupEntryDef(params[0].type);
73
- return value.type === "void" ? (
74
- // Option<void> would return a Codec<undefined> which makes no sense
75
- // Therefore, we better treat it as a bool
76
- { type: "primitive", value: "bool" }
77
- ) : {
78
- type: "option",
79
- value
80
- };
81
- }
82
- if (path.length === 1 && path[0] === "Result" && params.length === 2 && params[0].name === "T" && params[1].name === "E") {
83
- return {
84
- type: "result",
85
- value: {
86
- ok: getLookupEntryDef(params[0].type),
87
- ko: getLookupEntryDef(params[1].type)
88
- }
89
- };
90
- }
91
- if (def.value.length === 0) return { type: "void" };
92
- const enumValue = {};
93
- const enumDocs = {};
94
- def.value.forEach((x) => {
95
- const key = x.name;
96
- enumDocs[key] = x.docs;
97
- if (x.fields.length === 0) {
98
- enumValue[key] = { type: "void", idx: x.index };
99
- return;
100
- }
101
- if (x.fields.length === 1 && !x.fields[0].name) {
102
- enumValue[key] = {
103
- type: "lookupEntry",
104
- value: getLookupEntryDef(x.fields[0].type),
105
- idx: x.index
106
- };
107
- return;
108
- }
109
- let allKey = true;
110
- const values = {};
111
- const innerDocs = {};
112
- x.fields.forEach((x2, idx) => {
113
- allKey = allKey && !!x2.name;
114
- const key2 = x2.name || idx;
115
- values[key2] = getLookupEntryDef(x2.type);
116
- innerDocs[key2] = x2.docs;
117
- });
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
- }
141
- });
142
- return {
143
- type: "enum",
144
- value: enumValue,
145
- innerDocs: enumDocs
146
- };
147
- }
148
- if (def.tag === "sequence") {
149
- const value = getLookupEntryDef(def.value);
150
- return {
151
- type: "sequence",
152
- value
153
- };
154
- }
155
- if (def.tag === "array") {
156
- const { len } = def.value;
157
- const value = getLookupEntryDef(def.value.type);
158
- if (len === 0) return { type: "void" };
159
- if (len === 1) return value;
160
- return {
161
- type: "array",
162
- value,
163
- len: def.value.len
164
- };
165
- }
166
- if (def.tag === "tuple") {
167
- if (def.value.length === 0) return { type: "void" };
168
- if (def.value.length === 1)
169
- return getLookupEntryDef(def.value[0]);
170
- const value = def.value.map((x) => getLookupEntryDef(x));
171
- const innerDocs = def.value.map((x) => lookupData[x].docs);
172
- const areAllSame = value.every((v) => v.id === value[0].id);
173
- if (areAllSame && innerDocs.every((doc) => doc.length === 0)) {
174
- return {
175
- type: "array",
176
- value: value[0],
177
- len: value.length
178
- };
179
- }
180
- return {
181
- type: "tuple",
182
- value,
183
- innerDocs
184
- };
185
- }
186
- if (def.tag === "primitive") {
187
- return {
188
- type: "primitive",
189
- value: def.value.tag
190
- };
191
- }
192
- if (def.tag === "compact") {
193
- const translated = getLookupEntryDef(def.value);
194
- if (translated.type === "void") return { type: "compact", isBig: null };
195
- const isBig = Number(translated.value.slice(1)) > 32;
196
- return {
197
- type: "compact",
198
- isBig
199
- };
200
- }
201
- return {
202
- type: def.tag
203
- };
204
- });
205
- return getLookupEntryDef;
206
- };
207
-
208
- // src/dynamic-builder.ts
209
- import * as scale from "@polkadot-api/substrate-bindings";
210
-
211
- // src/with-cache.ts
212
- var withCache = (fn, onEnterCircular, onExitCircular) => (input, cache, stack, ...rest) => {
213
- const { id } = input;
214
- if (cache.has(id)) return cache.get(id);
215
- if (stack.has(id)) {
216
- const res = onEnterCircular(() => cache.get(id), input, ...rest);
217
- cache.set(id, res);
218
- return res;
219
- }
220
- stack.add(id);
221
- let result = fn(input, cache, stack, ...rest);
222
- stack.delete(id);
223
- if (cache.has(id))
224
- result = onExitCircular(result, cache.get(id), input, ...rest);
225
- cache.set(id, result);
226
- return result;
227
- };
228
-
229
- // src/dynamic-builder.ts
230
- import { mapObject } from "@polkadot-api/utils";
231
- var _bytes = scale.Bin();
232
- var _buildCodec = (input, cache, stack, _accountId) => {
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;
239
- const buildNextCodec = (nextInput) => buildCodec(nextInput, cache, stack, _accountId);
240
- const buildVector = (inner2, len) => {
241
- const innerCodec = buildNextCodec(inner2);
242
- return len ? scale.Vector(innerCodec, len) : scale.Vector(innerCodec);
243
- };
244
- const buildTuple = (value) => scale.Tuple(...value.map(buildNextCodec));
245
- const buildStruct = (value) => {
246
- const inner2 = Object.fromEntries(
247
- Object.entries(value).map(([key, value2]) => [key, buildNextCodec(value2)])
248
- );
249
- return scale.Struct(inner2);
250
- };
251
- if (input.type === "sequence" && input.value.type === "primitive" && input.value.value === "u8") {
252
- return _bytes;
253
- }
254
- if (input.type === "array") {
255
- if (input.value.type === "primitive" && input.value.value === "u8")
256
- return scale.Bin(input.len);
257
- return buildVector(input.value, input.len);
258
- }
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));
263
- if (input.type === "result")
264
- return scale.Result(
265
- buildNextCodec(input.value.ok),
266
- buildNextCodec(input.value.ko)
267
- );
268
- const dependencies = Object.values(input.value).map((v) => {
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
- }
281
- });
282
- const inner = Object.fromEntries(
283
- Object.keys(input.value).map((key, idx) => {
284
- return [key, dependencies[idx]];
285
- })
286
- );
287
- const indexes = Object.values(input.value).map((x) => x.idx);
288
- const areIndexesSorted = indexes.every((idx, i) => idx === i);
289
- return areIndexesSorted ? scale.Variant(inner) : scale.Variant(inner, indexes);
290
- };
291
- var buildCodec = withCache(_buildCodec, scale.Self, (res) => res);
292
- var getDynamicBuilder = (metadata) => {
293
- const lookupData = metadata.lookup;
294
- const getLookupEntryDef = getLookupFn(lookupData);
295
- let _accountId = scale.AccountId();
296
- const cache = /* @__PURE__ */ new Map();
297
- const buildDefinition = (id) => buildCodec(getLookupEntryDef(id), cache, /* @__PURE__ */ new Set(), _accountId);
298
- const prefix = metadata.pallets.find((x) => x.name === "System")?.constants.find((x) => x.name === "SS58Prefix");
299
- let ss58Prefix;
300
- if (prefix) {
301
- try {
302
- const prefixVal = buildDefinition(prefix.type).dec(prefix.value);
303
- if (typeof prefixVal === "number") {
304
- ss58Prefix = prefixVal;
305
- _accountId = scale.AccountId(prefixVal);
306
- }
307
- } catch (_) {
308
- }
309
- }
310
- const storagePallets = /* @__PURE__ */ new Map();
311
- const buildStorage = (pallet, entry) => {
312
- let storagePallet = storagePallets.get(pallet);
313
- if (!storagePallet)
314
- storagePallets.set(pallet, storagePallet = scale.Storage(pallet));
315
- const storageEntry = metadata.pallets.find((x) => x.name === pallet).storage.items.find((s) => s.name === entry);
316
- const storageWithFallback = (len, ...args) => {
317
- const result = storagePallet(...args);
318
- return {
319
- ...result,
320
- len,
321
- fallback: storageEntry.modifier === 1 ? result.dec(storageEntry.fallback) : void 0
322
- };
323
- };
324
- if (storageEntry.type.tag === "plain")
325
- return storageWithFallback(
326
- 0,
327
- entry,
328
- buildDefinition(storageEntry.type.value).dec
329
- );
330
- const { key, value, hashers } = storageEntry.type.value;
331
- const val = buildDefinition(value);
332
- const hashes = hashers.map((x) => scale[x.tag]);
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
- })();
350
- return storageWithFallback(hashes.length, entry, val.dec, ...hashArgs);
351
- };
352
- const buildEnumEntry = (entry) => {
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
- }
369
- };
370
- const buildConstant = (pallet, constantName) => {
371
- const storageEntry = metadata.pallets.find((x) => x.name === pallet).constants.find((s) => s.name === constantName);
372
- return buildDefinition(storageEntry.type);
373
- };
374
- const buildVariant = (type) => (pallet, name) => {
375
- const palletEntry = metadata.pallets.find((x) => x.name === pallet);
376
- const lookup = getLookupEntryDef(palletEntry[type]);
377
- if (lookup.type !== "enum") throw null;
378
- const entry = lookup.value[name];
379
- return {
380
- location: [palletEntry.index, entry.idx],
381
- codec: buildEnumEntry(lookup.value[name])
382
- };
383
- };
384
- const buildRuntimeCall = (api, method) => {
385
- const entry = metadata.apis.find((x) => x.name === api)?.methods.find((x) => x.name === method);
386
- if (!entry) throw null;
387
- return {
388
- args: scale.Tuple(...entry.inputs.map((x) => buildDefinition(x.type))),
389
- value: buildDefinition(entry.output)
390
- };
391
- };
392
- return {
393
- buildDefinition,
394
- buildStorage,
395
- buildEvent: buildVariant("events"),
396
- buildError: buildVariant("errors"),
397
- buildRuntimeCall,
398
- buildCall: buildVariant("calls"),
399
- buildConstant,
400
- ss58Prefix
401
- };
402
- };
403
-
404
- // src/checksum-builder.ts
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
568
- var textEncoder = new TextEncoder();
569
- var encodeText = textEncoder.encode.bind(textEncoder);
570
- var getChecksum = (values) => {
571
- const res = new Uint8Array(values.length * 8);
572
- const dv = new DataView(res.buffer);
573
- for (let i = 0; i < values.length; i++) dv.setBigUint64(i * 8, values[i]);
574
- return h64(res);
575
- };
576
- var getStringChecksum = (values) => getChecksum(values.map((v) => h64(encodeText(v))));
577
- var shapeIds = {
578
- primitive: 0n,
579
- vector: 1n,
580
- tuple: 2n,
581
- struct: 3n,
582
- option: 4n,
583
- result: 5n,
584
- enum: 6n,
585
- void: 7n
586
- };
587
- var runtimePrimitiveIds = {
588
- undefined: 0n,
589
- number: 1n,
590
- string: 2n,
591
- bigint: 3n,
592
- boolean: 4n,
593
- bitSequence: 5n,
594
- // {bitsLen: number, bytes: Uint8Array}
595
- byteSequence: 6n,
596
- // Binary
597
- accountId32: 7n,
598
- // SS58String
599
- accountId20: 8n
600
- // EthAccount
601
- };
602
- var metadataPrimitiveIds = {
603
- bool: runtimePrimitiveIds.boolean,
604
- char: runtimePrimitiveIds.string,
605
- str: runtimePrimitiveIds.string,
606
- u8: runtimePrimitiveIds.number,
607
- u16: runtimePrimitiveIds.number,
608
- u32: runtimePrimitiveIds.number,
609
- u64: runtimePrimitiveIds.bigint,
610
- u128: runtimePrimitiveIds.bigint,
611
- u256: runtimePrimitiveIds.bigint,
612
- i8: runtimePrimitiveIds.number,
613
- i16: runtimePrimitiveIds.number,
614
- i32: runtimePrimitiveIds.number,
615
- i64: runtimePrimitiveIds.bigint,
616
- i128: runtimePrimitiveIds.bigint,
617
- i256: runtimePrimitiveIds.bigint
618
- };
619
- var structLikeBuilder = (shapeId, input, innerChecksum) => {
620
- const sortedEntries = Object.entries(input).sort(
621
- ([a], [b]) => a.localeCompare(b)
622
- );
623
- const keysChecksum = getStringChecksum(sortedEntries.map(([key]) => key));
624
- const valuesChecksum = getChecksum(
625
- sortedEntries.map(([, entry]) => innerChecksum(entry))
626
- );
627
- return getChecksum([shapeId, keysChecksum, valuesChecksum]);
628
- };
629
- var _buildChecksum = (input, buildNextChecksum) => {
630
- if (input.type === "primitive")
631
- return getChecksum([shapeIds.primitive, metadataPrimitiveIds[input.value]]);
632
- if (input.type === "void") return getChecksum([shapeIds.void]);
633
- if (input.type === "compact")
634
- return getChecksum([
635
- shapeIds.primitive,
636
- runtimePrimitiveIds[input.isBig || input.isBig === null ? "bigint" : "number"]
637
- ]);
638
- if (input.type === "bitSequence")
639
- return getChecksum([shapeIds.primitive, runtimePrimitiveIds.bitSequence]);
640
- if (input.type === "AccountId32") {
641
- return getChecksum([shapeIds.primitive, runtimePrimitiveIds.accountId32]);
642
- }
643
- if (input.type === "AccountId20") {
644
- return getChecksum([shapeIds.primitive, runtimePrimitiveIds.accountId20]);
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
- };
652
- if (input.type === "array") {
653
- const innerValue = input.value;
654
- if (innerValue.type === "primitive" && innerValue.value === "u8") {
655
- return getChecksum([
656
- shapeIds.primitive,
657
- runtimePrimitiveIds.byteSequence,
658
- BigInt(input.len)
659
- ]);
660
- }
661
- return buildVector(innerValue, input.len);
662
- }
663
- if (input.type === "sequence") {
664
- const innerValue = input.value;
665
- if (innerValue.type === "primitive" && innerValue.value === "u8") {
666
- return getChecksum([shapeIds.primitive, runtimePrimitiveIds.byteSequence]);
667
- }
668
- return buildVector(innerValue);
669
- }
670
- const buildTuple = (entries) => getChecksum([shapeIds.tuple, ...entries.map(buildNextChecksum)]);
671
- const buildStruct = (entries) => structLikeBuilder(shapeIds.struct, entries, buildNextChecksum);
672
- if (input.type === "tuple") return buildTuple(input.value);
673
- if (input.type === "struct") return buildStruct(input.value);
674
- if (input.type === "option")
675
- return getChecksum([shapeIds.option, buildNextChecksum(input.value)]);
676
- if (input.type === "result")
677
- return getChecksum([
678
- shapeIds.result,
679
- buildNextChecksum(input.value.ok),
680
- buildNextChecksum(input.value.ko)
681
- ]);
682
- return structLikeBuilder(shapeIds.enum, input.value, (entry) => {
683
- if (entry.type === "lookupEntry") return buildNextChecksum(entry.value);
684
- switch (entry.type) {
685
- case "void":
686
- return getChecksum([shapeIds.void]);
687
- case "tuple":
688
- return buildTuple(entry.value);
689
- case "struct":
690
- return buildStruct(entry.value);
691
- case "array":
692
- return buildVector(entry.value, entry.len);
693
- }
694
- });
695
- };
696
- var sortCyclicGroups = (groups, graph) => {
697
- const getReachableNodes = (group) => {
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);
707
- };
708
- const result = new Array();
709
- function dependentsFirst(group) {
710
- if (result.includes(group)) return;
711
- const dependents = groups.filter(
712
- (candidate) => candidate !== group && getReachableNodes(group).some((node) => candidate.has(node))
713
- );
714
- dependents.forEach((group2) => dependentsFirst(group2));
715
- if (result.includes(group)) return;
716
- result.push(group);
717
- }
718
- groups.forEach((group) => dependentsFirst(group));
719
- return result;
720
- };
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);
727
- }
728
- const result = _buildChecksum(
729
- entry,
730
- (nextEntry) => recursiveBuildChecksum(nextEntry, false)
731
- );
732
- if (group.has(entry.id)) {
733
- groupWriteCache.set(entry.id, result);
734
- } else {
735
- cache.set(entry.id, result);
736
- }
737
- return result;
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
- );
788
- sortedCyclicGroups.forEach((group) => {
789
- if (cache.has(group.values().next().value)) {
790
- return;
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
- });
801
- });
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);
807
- };
808
- var getChecksumBuilder = (metadata) => {
809
- const lookupData = metadata.lookup;
810
- const getLookupEntryDef = getLookupFn(lookupData);
811
- const graph = buildLookupGraph(getLookupEntryDef, lookupData.length);
812
- const cache = /* @__PURE__ */ new Map();
813
- const buildDefinition = (id) => buildChecksum(getLookupEntryDef(id), cache, graph);
814
- const buildStorage = (pallet, entry) => {
815
- try {
816
- const storageEntry = metadata.pallets.find((x) => x.name === pallet).storage.items.find((s) => s.name === entry);
817
- if (storageEntry.type.tag === "plain")
818
- return buildDefinition(storageEntry.type.value);
819
- const { key, value } = storageEntry.type.value;
820
- const val = buildDefinition(value);
821
- const returnKey = buildDefinition(key);
822
- return getChecksum([val, returnKey]);
823
- } catch (_) {
824
- return null;
825
- }
826
- };
827
- const buildRuntimeCall = (api, method) => {
828
- try {
829
- const entry = metadata.apis.find((x) => x.name === api)?.methods.find((x) => x.name === method);
830
- if (!entry) throw null;
831
- const argNamesChecksum = getStringChecksum(
832
- entry.inputs.map((x) => x.name)
833
- );
834
- const argValuesChecksum = getChecksum(
835
- entry.inputs.map((x) => buildDefinition(x.type))
836
- );
837
- const outputChecksum = buildDefinition(entry.output);
838
- return getChecksum([argNamesChecksum, argValuesChecksum, outputChecksum]);
839
- } catch (_) {
840
- return null;
841
- }
842
- };
843
- const buildComposite = (input) => {
844
- if (input.type === "void") return getChecksum([0n]);
845
- if (input.type === "tuple") {
846
- const values = Object.values(input.value).map(
847
- (entry) => buildDefinition(entry.id)
848
- );
849
- return getChecksum([shapeIds.tuple, ...values]);
850
- }
851
- if (input.type === "array") {
852
- return getChecksum([
853
- shapeIds.vector,
854
- buildDefinition(input.value.id),
855
- BigInt(input.len)
856
- ]);
857
- }
858
- return structLikeBuilder(
859
- shapeIds.struct,
860
- input.value,
861
- (entry) => buildDefinition(entry.id)
862
- );
863
- };
864
- const buildNamedTuple = (input) => {
865
- return structLikeBuilder(
866
- shapeIds.tuple,
867
- input.value,
868
- (entry) => buildDefinition(entry.id)
869
- );
870
- };
871
- const buildVariant = (variantType) => (pallet, name) => {
872
- try {
873
- const palletEntry = metadata.pallets.find((x) => x.name === pallet);
874
- const enumLookup = getLookupEntryDef(
875
- palletEntry[variantType]
876
- );
877
- buildDefinition(enumLookup.id);
878
- if (enumLookup.type !== "enum") throw null;
879
- const entry = enumLookup.value[name];
880
- return entry.type === "lookupEntry" ? buildDefinition(entry.value.id) : buildComposite(entry);
881
- } catch (_) {
882
- return null;
883
- }
884
- };
885
- const buildConstant = (pallet, constantName) => {
886
- try {
887
- const storageEntry = metadata.pallets.find((x) => x.name === pallet).constants.find((s) => s.name === constantName);
888
- return buildDefinition(storageEntry.type);
889
- } catch (_) {
890
- return null;
891
- }
892
- };
893
- const toStringEnhancer = (fn) => (...args) => fn(...args)?.toString(32) ?? null;
894
- return {
895
- buildDefinition: toStringEnhancer(buildDefinition),
896
- buildRuntimeCall: toStringEnhancer(buildRuntimeCall),
897
- buildStorage: toStringEnhancer(buildStorage),
898
- buildCall: toStringEnhancer(buildVariant("calls")),
899
- buildEvent: toStringEnhancer(buildVariant("events")),
900
- buildError: toStringEnhancer(buildVariant("errors")),
901
- buildConstant: toStringEnhancer(buildConstant),
902
- buildComposite: toStringEnhancer(buildComposite),
903
- buildNamedTuple: toStringEnhancer(buildNamedTuple),
904
- getAllGeneratedChecksums: () => Array.from(cache.values()).map((v) => v.toString(32))
905
- };
906
- };
907
- export {
908
- getChecksumBuilder,
909
- getDynamicBuilder,
910
- getLookupFn
911
- };
912
- //# sourceMappingURL=index.mjs.map