@talismn/scale 0.0.0-pr997-20231116062730 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/declarations/src/index.d.ts +1 -2
  2. package/dist/declarations/src/papito.d.ts +6 -0
  3. package/dist/declarations/src/util/compactMetadata.d.ts +20 -0
  4. package/dist/declarations/src/util/decodeMetadata.d.ts +13 -0
  5. package/dist/declarations/src/util/decodeScale.d.ts +4 -0
  6. package/dist/declarations/src/util/encodeMetadata.d.ts +8 -0
  7. package/dist/declarations/src/util/encodeStateKey.d.ts +4 -0
  8. package/dist/declarations/src/util/getMetadataVersion.d.ts +6 -0
  9. package/dist/declarations/src/util/index.d.ts +7 -0
  10. package/dist/declarations/src/util/serdePapi.d.ts +29 -0
  11. package/dist/talismn-scale.cjs.dev.js +318 -1395
  12. package/dist/talismn-scale.cjs.prod.js +318 -1395
  13. package/dist/talismn-scale.esm.js +283 -1330
  14. package/package.json +16 -20
  15. package/CHANGELOG.md +0 -13
  16. package/dist/declarations/src/capi/crypto/base58.d.ts +0 -18
  17. package/dist/declarations/src/capi/crypto/hashers.d.ts +0 -66
  18. package/dist/declarations/src/capi/crypto/index.d.ts +0 -3
  19. package/dist/declarations/src/capi/crypto/ss58.d.ts +0 -16
  20. package/dist/declarations/src/capi/crypto/util/index.d.ts +0 -4
  21. package/dist/declarations/src/capi/crypto/util/nosimd.d.ts +0 -19
  22. package/dist/declarations/src/capi/crypto/util/simd.d.ts +0 -1
  23. package/dist/declarations/src/capi/frame_metadata/Extrinsic.d.ts +0 -50
  24. package/dist/declarations/src/capi/frame_metadata/FrameMetadata.d.ts +0 -61
  25. package/dist/declarations/src/capi/frame_metadata/decodeMetadata.d.ts +0 -312
  26. package/dist/declarations/src/capi/frame_metadata/index.d.ts +0 -4
  27. package/dist/declarations/src/capi/frame_metadata/key_codecs.d.ts +0 -27
  28. package/dist/declarations/src/capi/frame_metadata/raw/v14.d.ts +0 -312
  29. package/dist/declarations/src/capi/index.d.ts +0 -4
  30. package/dist/declarations/src/capi/scale_info/index.d.ts +0 -4
  31. package/dist/declarations/src/capi/scale_info/overrides/ChainError.d.ts +0 -26
  32. package/dist/declarations/src/capi/scale_info/overrides/Era.d.ts +0 -33
  33. package/dist/declarations/src/capi/scale_info/overrides/index.d.ts +0 -1
  34. package/dist/declarations/src/capi/scale_info/overrides/overrides.d.ts +0 -23
  35. package/dist/declarations/src/capi/scale_info/raw/Ty.d.ts +0 -313
  36. package/dist/declarations/src/capi/scale_info/transformTys.d.ts +0 -34
  37. package/dist/declarations/src/capi/util/index.d.ts +0 -3
  38. package/dist/declarations/src/capi/util/key.d.ts +0 -22
  39. package/dist/declarations/src/capi/util/normalize.d.ts +0 -25
  40. package/dist/declarations/src/capi/util/state.d.ts +0 -25
  41. package/dist/declarations/src/util.d.ts +0 -9
  42. package/dist/nosimd-20b5b0ca.esm.js +0 -45
  43. package/dist/nosimd-3e5ed5a9.cjs.prod.js +0 -48
  44. package/dist/nosimd-61fc593c.cjs.dev.js +0 -48
  45. package/dist/simd-133b8f48.cjs.prod.js +0 -14
  46. package/dist/simd-2ddb8d7c.cjs.dev.js +0 -14
  47. package/dist/simd-b794dbff.esm.js +0 -1
@@ -1,1289 +1,17 @@
1
- import { Deferred } from '@talismn/util';
2
- import { simd } from 'wasm-feature-detect';
3
- import * as $ from '@talismn/subshape-fork';
4
- import { EncodeBuffer } from '@talismn/subshape-fork';
1
+ export { getDynamicBuilder, getLookupFn } from '@polkadot-api/metadata-builders';
2
+ import { toHex } from '@polkadot-api/utils';
3
+ export { fromHex, toHex } from '@polkadot-api/utils';
4
+ import { metadata, Binary } from '@polkadot-api/substrate-bindings';
5
+ export { metadata, v14, v15 } from '@polkadot-api/substrate-bindings';
5
6
  import anylogger from 'anylogger';
7
+ import { Struct, u32, u8 } from 'scale-ts';
6
8
 
7
- //
8
- // The simd variants of these hash fns are faster, but some devices don't support them.
9
- //
10
- // This file re-exports the faster fns from `./simd` for devices which support them,
11
- // and falls back to `./nosimd` re-exports for devices which do not.
12
- //
13
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
- let Blake2b;
15
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
- let Xxhash;
17
- let readyPromise = null;
18
- const watCryptoWaitReady = async () => {
19
- // if this is the second/third/etc time we've called watCryptoWaitReady,
20
- // then get a reference to the existing promise and wait for it to resolve/reject
21
- if (readyPromise !== null) return await readyPromise;
22
-
23
- // if this is the first time we've called watCryptoWaitReady,
24
- // then create and return a new promise
25
- const deferred = Deferred();
26
- readyPromise = deferred.promise
27
-
28
- // spawn a task to initialize the fns and resolve the readyPromise
29
- ;
30
- (async () => {
31
- try {
32
- // initialize simd or nosimd, based on wasm feature detection
33
- if (await simd()) {
34
- // system supports wasm simd
35
- const imported = await import('./simd-b794dbff.esm.js');
36
- Blake2b = imported.Blake2b;
37
- Xxhash = imported.Xxhash;
38
- } else {
39
- // system does not support wasm simd
40
- const imported = await import('./nosimd-20b5b0ca.esm.js');
41
- Blake2b = imported.Blake2b;
42
- Xxhash = imported.Xxhash;
43
- }
44
-
45
- // feature detection and loading complete
46
- deferred.resolve();
47
- } catch (error) {
48
- // feature detection and loading failed
49
- deferred.reject(error);
50
- }
51
- })();
52
-
53
- // wait for the promise to resolve/reject
54
- return await readyPromise;
55
- };
56
-
57
- // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
58
- // This module is browser compatible.
59
-
60
- /**
61
- * {@linkcode encode} and {@linkcode decode} for
62
- * [base58](https://en.wikipedia.org/wiki/Binary-to-text_encoding#Base58) encoding.
63
- *
64
- * This module is browser compatible.
65
- *
66
- * @module
67
- */
68
-
69
- // deno-fmt-ignore
70
- const mapBase58 = {
71
- "1": 0,
72
- "2": 1,
73
- "3": 2,
74
- "4": 3,
75
- "5": 4,
76
- "6": 5,
77
- "7": 6,
78
- "8": 7,
79
- "9": 8,
80
- "A": 9,
81
- "B": 10,
82
- "C": 11,
83
- "D": 12,
84
- "E": 13,
85
- "F": 14,
86
- "G": 15,
87
- "H": 16,
88
- "J": 17,
89
- "K": 18,
90
- "L": 19,
91
- "M": 20,
92
- "N": 21,
93
- "P": 22,
94
- "Q": 23,
95
- "R": 24,
96
- "S": 25,
97
- "T": 26,
98
- "U": 27,
99
- "V": 28,
100
- "W": 29,
101
- "X": 30,
102
- "Y": 31,
103
- "Z": 32,
104
- "a": 33,
105
- "b": 34,
106
- "c": 35,
107
- "d": 36,
108
- "e": 37,
109
- "f": 38,
110
- "g": 39,
111
- "h": 40,
112
- "i": 41,
113
- "j": 42,
114
- "k": 43,
115
- "m": 44,
116
- "n": 45,
117
- "o": 46,
118
- "p": 47,
119
- "q": 48,
120
- "r": 49,
121
- "s": 50,
122
- "t": 51,
123
- "u": 52,
124
- "v": 53,
125
- "w": 54,
126
- "x": 55,
127
- "y": 56,
128
- "z": 57
129
- };
130
- const base58alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".split("");
131
-
132
- /**
133
- * Encodes a given Uint8Array, ArrayBuffer or string into draft-mspotny-base58-03 RFC base58 representation:
134
- * https://tools.ietf.org/id/draft-msporny-base58-01.html#rfc.section.1
135
- *
136
- * @param data
137
- *
138
- * @returns Encoded value
139
- */
140
- function encode$1(data) {
141
- const uint8tData = typeof data === "string" ? new TextEncoder().encode(data) : data instanceof Uint8Array ? data : new Uint8Array(data);
142
- let length = 0;
143
- let zeroes = 0;
144
-
145
- // Counting leading zeroes
146
- let index = 0;
147
- while (uint8tData[index] === 0) {
148
- zeroes++;
149
- index++;
150
- }
151
- const notZeroUint8Data = uint8tData.slice(index);
152
- const size = Math.round(uint8tData.length * 138 / 100 + 1);
153
- const b58Encoding = [];
154
- notZeroUint8Data.forEach(byte => {
155
- let i = 0;
156
- let carry = byte;
157
- for (let reverse_iterator = size - 1; (carry > 0 || i < length) && reverse_iterator !== -1; reverse_iterator--, i++) {
158
- carry += (b58Encoding[reverse_iterator] || 0) * 256;
159
- b58Encoding[reverse_iterator] = Math.round(carry % 58);
160
- carry = Math.floor(carry / 58);
161
- }
162
- length = i;
163
- });
164
- const strResult = Array.from({
165
- length: b58Encoding.length + zeroes
166
- });
167
- if (zeroes > 0) {
168
- strResult.fill("1", 0, zeroes);
169
- }
170
- b58Encoding.forEach(byteValue => strResult.push(base58alphabet[byteValue]));
171
- return strResult.join("");
172
- }
173
-
174
- /**
175
- * Decodes a given b58 string according to draft-mspotny-base58-03 RFC base58 representation:
176
- * https://tools.ietf.org/id/draft-msporny-base58-01.html#rfc.section.1
177
- *
178
- * @param b58
179
- *
180
- * @returns Decoded value
181
- */
182
- function decode$1(b58) {
183
- const splitInput = b58.trim().split("");
184
- let length = 0;
185
- let ones = 0;
186
-
187
- // Counting leading ones
188
- let index = 0;
189
- while (splitInput[index] === "1") {
190
- ones++;
191
- index++;
192
- }
193
- const notZeroData = splitInput.slice(index);
194
- const size = Math.round(b58.length * 733 / 1000 + 1);
195
- const output = [];
196
- notZeroData.forEach((char, idx) => {
197
- let carry = mapBase58[char];
198
- let i = 0;
199
- if (carry === undefined) {
200
- throw new Error(`Invalid base58 char at index ${idx} with value ${char}`);
201
- }
202
- for (let reverse_iterator = size - 1; (carry > 0 || i < length) && reverse_iterator !== -1; reverse_iterator--, i++) {
203
- carry += 58 * (output[reverse_iterator] || 0);
204
- output[reverse_iterator] = Math.round(carry % 256);
205
- carry = Math.floor(carry / 256);
206
- }
207
- length = i;
208
- });
209
- const validOutput = output.filter(item => item !== undefined);
210
- if (ones > 0) {
211
- const onesResult = Array.from({
212
- length: ones
213
- }).fill(0, 0, ones);
214
- return new Uint8Array([...onesResult, ...validOutput]);
215
- }
216
- return new Uint8Array(validOutput);
217
- }
218
-
219
- /* eslint-disable @typescript-eslint/no-non-null-assertion */
220
- function encode(prefix, payload, checksumLength) {
221
- return encode$1(encodeRaw(prefix, payload, checksumLength));
222
- }
223
- function encodeRaw(prefix, payload, checksumLength) {
224
- checksumLength ??= DEFAULT_PAYLOAD_CHECKSUM_LENGTHS[payload.length];
225
- if (!checksumLength) throw new InvalidPayloadLengthError();
226
- const prefixBytes = prefix < 64 ? Uint8Array.of(prefix) : Uint8Array.of((prefix & 0b0000_0000_1111_1100) >> 2 | 0b0100_0000, prefix >> 8 | (prefix & 0b0000_0000_0000_0011) << 6);
227
- const hasher = new Blake2b();
228
- hasher.update(SS58PRE);
229
- hasher.update(prefixBytes);
230
- hasher.update(payload);
231
- const digest = hasher.digest();
232
- const checksum = digest.subarray(0, checksumLength);
233
- hasher.dispose();
234
- const address = new Uint8Array(prefixBytes.length + payload.length + checksumLength);
235
- address.set(prefixBytes, 0);
236
- address.set(payload, prefixBytes.length);
237
- address.set(checksum, prefixBytes.length + payload.length);
238
- return address;
239
- }
240
- class InvalidPayloadLengthError extends Error {
241
- name = "InvalidPayloadLengthError";
242
- }
243
- function decode(address) {
244
- return decodeRaw(decode$1(address));
245
- }
246
- function decodeRaw(address) {
247
- const checksumLength = VALID_ADDRESS_CHECKSUM_LENGTHS[address.length];
248
- if (!checksumLength) throw new InvalidAddressLengthError();
249
- const prefixLength = address[0] & 0b0100_0000 ? 2 : 1;
250
- const prefix = prefixLength === 1 ? address[0] : (address[0] & 0b0011_1111) << 2 | address[1] >> 6 | (address[1] & 0b0011_1111) << 8;
251
- const hasher = new Blake2b();
252
- hasher.update(SS58PRE);
253
- hasher.update(address.subarray(0, address.length - checksumLength));
254
- const digest = hasher.digest();
255
- const checksum = address.subarray(address.length - checksumLength);
256
- hasher.dispose();
257
- if (!isValidChecksum(digest, checksum, checksumLength)) {
258
- throw new InvalidAddressChecksumError();
259
- }
260
- const pubKey = address.subarray(prefixLength, address.length - checksumLength);
261
- return [prefix, pubKey];
262
- }
263
- class InvalidAddressLengthError extends Error {
264
- name = "InvalidAddressError";
265
- }
266
- class InvalidAddressChecksumError extends Error {
267
- name = "InvalidAddressChecksumError";
268
- }
269
-
270
- // SS58PRE string (0x53533538505245 hex) encoded as Uint8Array
271
- const SS58PRE = Uint8Array.of(83, 83, 53, 56, 80, 82, 69);
272
- const VALID_ADDRESS_CHECKSUM_LENGTHS = {
273
- 3: 1,
274
- 4: 1,
275
- 5: 2,
276
- 6: 1,
277
- 7: 2,
278
- 8: 3,
279
- 9: 4,
280
- 10: 1,
281
- 11: 2,
282
- 12: 3,
283
- 13: 4,
284
- 14: 5,
285
- 15: 6,
286
- 16: 7,
287
- 17: 8,
288
- 35: 2,
289
- 36: 2,
290
- 37: 2
291
- };
292
- const DEFAULT_PAYLOAD_CHECKSUM_LENGTHS = {
293
- 1: 1,
294
- 2: 1,
295
- 4: 1,
296
- 8: 1,
297
- 32: 2,
298
- 33: 2
299
- };
300
- function isValidChecksum(digest, checksum, checksumLength) {
301
- for (let i = 0; i < checksumLength; i++) {
302
- if (digest[i] !== checksum[i]) {
303
- return false;
304
- }
305
- }
306
- return true;
307
- }
308
-
309
- var ss58 = /*#__PURE__*/Object.freeze({
310
- __proto__: null,
311
- encode: encode,
312
- encodeRaw: encodeRaw,
313
- InvalidPayloadLengthError: InvalidPayloadLengthError,
314
- decode: decode,
315
- decodeRaw: decodeRaw,
316
- InvalidAddressLengthError: InvalidAddressLengthError,
317
- InvalidAddressChecksumError: InvalidAddressChecksumError
318
- });
319
-
320
- /**
321
- * Adapted from https://github.com/paritytech/capi-old copyright Parity Technologies (APACHE License 2.0)
322
- * Changes August 19th 2023 :
323
- * - updated to use subshape for scale decoding
324
- * - adapted from deno to typescript
325
- *
326
- Copyright 2023 Parity Technologies
327
-
328
- Licensed under the Apache License, Version 2.0 (the "License");
329
- you may not use this file except in compliance with the License.
330
- You may obtain a copy of the License at
331
-
332
- http://www.apache.org/licenses/LICENSE-2.0
333
-
334
- Unless required by applicable law or agreed to in writing, software
335
- distributed under the License is distributed on an "AS IS" BASIS,
336
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
337
- See the License for the specific language governing permissions and
338
- limitations under the License.
339
- */
340
- class Hasher {
341
- $hash($inner) {
342
- return $hash(this, $inner);
343
- }
344
- hash(data) {
345
- const output = new Uint8Array(this.digestLength + (this.concat ? data.length : 0));
346
- const hashing = this.create();
347
- hashing.update(data);
348
- hashing.digestInto(output);
349
- hashing.dispose?.();
350
- if (this.concat) {
351
- output.set(data, this.digestLength);
352
- }
353
- return output;
354
- }
355
- }
356
- function $hash(hasher, $inner) {
357
- return $.createShape({
358
- metadata: $.metadata("$hash", $hash, hasher, $inner),
359
- staticSize: hasher.digestLength + $inner.staticSize,
360
- subEncode(buffer, value) {
361
- const hashArray = buffer.array.subarray(buffer.index, buffer.index += hasher.digestLength);
362
- const cursor = hasher.concat ? buffer.createCursor($inner.staticSize) : new EncodeBuffer(buffer.stealAlloc($inner.staticSize));
363
- $inner.subEncode(cursor, value);
364
- buffer.waitForBuffer(cursor, () => {
365
- if (hasher.concat) cursor.close();else cursor._commitWritten();
366
- const hashing = hasher.create();
367
- updateHashing(hashing, cursor);
368
- hashing.digestInto(hashArray);
369
- hashing.dispose?.();
370
- });
371
- },
372
- subDecode(buffer) {
373
- if (!hasher.concat) throw new DecodeNonTransparentKeyError();
374
- buffer.index += hasher.digestLength;
375
- return $inner.subDecode(buffer);
376
- },
377
- subAssert(assert) {
378
- $inner.subAssert(assert);
379
- }
380
- });
381
- }
382
- class Blake2Hasher extends Hasher {
383
- constructor(size, concat) {
384
- super();
385
- this.concat = concat;
386
- this.digestLength = size / 8;
387
- }
388
- create() {
389
- return new Blake2b(this.digestLength);
390
- }
391
- }
392
- class IdentityHasher extends Hasher {
393
- digestLength = 0;
394
- concat = true;
395
- create() {
396
- return {
397
- update() {},
398
- digestInto() {}
399
- };
400
- }
401
- $hash($inner) {
402
- return $inner;
403
- }
404
- hash(data) {
405
- return data.slice();
406
- }
407
- }
408
- class TwoxHasher extends Hasher {
409
- constructor(size, concat) {
410
- super();
411
- this.concat = concat;
412
- this.digestLength = size / 8;
413
- this.rounds = size / 64;
414
- }
415
- create() {
416
- return new Xxhash(this.rounds);
417
- }
418
- }
419
- const blake2_64 = new Blake2Hasher(64, false);
420
- const blake2_128 = new Blake2Hasher(128, false);
421
- const blake2_128Concat = new Blake2Hasher(128, true);
422
- const blake2_256 = new Blake2Hasher(256, false);
423
- const blake2_512 = new Blake2Hasher(512, false);
424
- const identity = new IdentityHasher();
425
- const twox128 = new TwoxHasher(128, false);
426
- const twox256 = new TwoxHasher(256, false);
427
- const twox64Concat = new TwoxHasher(64, true);
428
- function updateHashing(hashing, data) {
429
- for (const array of data.finishedArrays) {
430
- if (array instanceof EncodeBuffer) {
431
- updateHashing(hashing, array);
432
- } else {
433
- hashing.update(array);
434
- }
435
- }
436
- }
437
- class DecodeNonTransparentKeyError extends Error {
438
- name = "DecodeNonTransparentKeyError";
439
- }
440
-
441
- /**
442
- * Adapted from https://github.com/paritytech/capi-old copyright Parity Technologies (APACHE License 2.0)
443
- * Changes August 19th 2023 :
444
- * - updated to use subshape for scale decoding
445
- * - adapted from deno to typescript
446
- *
447
- Copyright 2023 Parity Technologies
448
-
449
- Licensed under the Apache License, Version 2.0 (the "License");
450
- you may not use this file except in compliance with the License.
451
- You may obtain a copy of the License at
452
-
453
- http://www.apache.org/licenses/LICENSE-2.0
454
-
455
- Unless required by applicable law or agreed to in writing, software
456
- distributed under the License is distributed on an "AS IS" BASIS,
457
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
458
- See the License for the specific language governing permissions and
459
- limitations under the License.
460
- */
461
- const $tyId = $.compact($.u32);
462
- const $field = $.object($.optionalField("name", $.str), $.field("ty", $tyId), $.optionalField("typeName", $.str), $.field("docs", $.array($.str)));
463
- const $primitiveKind = $.literalUnion(["bool", "char", "str", "u8", "u16", "u32", "u64", "u128", "u256", "i8", "i16", "i32", "i64", "i128", "i256"]);
464
- const $tyDef = $.taggedUnion("type", [$.variant("Struct", $.field("fields", $.array($field))), $.variant("Union", $.field("members", $.array($.object($.field("name", $.str), $.field("fields", $.array($field)), $.field("index", $.u8), $.field("docs", $.array($.str)))))), $.variant("Sequence", $.field("typeParam", $tyId)), $.variant("SizedArray", $.field("len", $.u32), $.field("typeParam", $tyId)), $.variant("Tuple", $.field("fields", $.array($tyId))), $.variant("Primitive", $.field("kind", $primitiveKind)), $.variant("Compact", $.field("typeParam", $tyId)), $.variant("BitSequence", $.field("bitOrderType", $tyId), $.field("bitStoreType", $tyId))]);
465
- const $ty = $.object($.field("id", $.compact($.u32)), $.field("path", $.array($.str)), $.field("params", $.array($.object($.field("name", $.str), $.optionalField("ty", $tyId)))), $tyDef, $.field("docs", $.array($.str)));
466
-
467
- /**
468
- * Adapted from https://github.com/paritytech/capi-old copyright Parity Technologies (APACHE License 2.0)
469
- * Changes August 19th 2023 :
470
- * - updated to use subshape for scale decoding
471
- * - adapted from deno to typescript
472
- *
473
- Copyright 2023 Parity Technologies
474
-
475
- Licensed under the Apache License, Version 2.0 (the "License");
476
- you may not use this file except in compliance with the License.
477
- You may obtain a copy of the License at
478
-
479
- http://www.apache.org/licenses/LICENSE-2.0
480
-
481
- Unless required by applicable law or agreed to in writing, software
482
- distributed under the License is distributed on an "AS IS" BASIS,
483
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
484
- See the License for the specific language governing permissions and
485
- limitations under the License.
486
- */
487
-
488
- const unquotedKey = /^(?!__proto__$)[$_\p{ID_Start}][$\p{ID_Continue}]+$|^\d+$/u;
489
- function stringifyKey(key) {
490
- return unquotedKey.test(key) ? key : JSON.stringify(key);
491
- }
492
- function stringifyPropertyAccess(key) {
493
- return unquotedKey.test(key) ? `.${key}` : `[${JSON.stringify(key)}]`;
494
- }
495
-
496
- /**
497
- * Adapted from https://github.com/paritytech/capi-old copyright Parity Technologies (APACHE License 2.0)
498
- * Changes August 19th 2023 :
499
- * - updated to use subshape for scale decoding
500
- * - adapted from deno to typescript
501
- *
502
- Copyright 2023 Parity Technologies
503
-
504
- Licensed under the Apache License, Version 2.0 (the "License");
505
- you may not use this file except in compliance with the License.
506
- You may obtain a copy of the License at
507
-
508
- http://www.apache.org/licenses/LICENSE-2.0
509
-
510
- Unless required by applicable law or agreed to in writing, software
511
- distributed under the License is distributed on an "AS IS" BASIS,
512
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
513
- See the License for the specific language governing permissions and
514
- limitations under the License.
515
- */
516
-
517
- function normalizeIdent(ident) {
518
- if (ident.startsWith("r#")) ident = ident.slice(2);
519
- return normalizeKeyword(ident.replace(/(?:[^\p{ID_Continue}]|_)+(.)/gu, (_, $1) => $1.toUpperCase()));
520
- }
521
- function normalizeDocs(docs) {
522
- let str = docs?.join("\n") ?? "";
523
- str = str.replace(/[^\S\n]+$/gm, "") // strip trailing whitespace
524
- .replace(/^\n+|\n+$/g, ""); // strip leading and trailing newlines
525
- const match = /^([^\S\n]+).*(?:\n\1.*)*$/.exec(str); // find a common indent
526
- if (match) {
527
- const {
528
- 1: prefix
529
- } = match;
530
- str = str.replace(new RegExp(`^${prefix}`, "gm"), ""); // strip the common indent
531
- // this `new RegExp` is safe because `prefix` must be whitespace
532
- }
533
-
534
- return str;
535
- }
536
- function normalizePackageName(name) {
537
- return name.replace(/[A-Z]/g, x => `-` + x.toLowerCase());
538
- }
539
- function normalizeTypeName(name) {
540
- return normalizeIdent(name).replace(/^./, x => x.toUpperCase());
541
- }
542
- function normalizeVariableName(name) {
543
- return normalizeIdent(name).replace(/^./, x => x.toLowerCase());
544
- }
545
-
546
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#reserved_words
547
- const keywords = ["break", "case", "catch", "class", "const", "continue", "debugger", "delete", "do", "else", "export", "extends", "false", "finally", "for", "function", "if", "import", "in", "instanceof", "new", "null", "return", "super", "switch", "this", "throw", "true", "try", "typeof", "var", "void", "while", "with", "let", "static", "yield", "await", "enum", "implements", "interface", "package", "private", "protected", "public"];
548
- function normalizeKeyword(ident) {
549
- return keywords.includes(ident) ? ident + "_" : ident;
550
- }
551
-
552
- /**
553
- * Adapted from https://github.com/paritytech/capi-old copyright Parity Technologies (APACHE License 2.0)
554
- * Changes August 19th 2023 :
555
- * - updated to use subshape for scale decoding
556
- * - adapted from deno to typescript
557
- *
558
- Copyright 2023 Parity Technologies
559
-
560
- Licensed under the Apache License, Version 2.0 (the "License");
561
- you may not use this file except in compliance with the License.
562
- You may obtain a copy of the License at
563
-
564
- http://www.apache.org/licenses/LICENSE-2.0
565
-
566
- Unless required by applicable law or agreed to in writing, software
567
- distributed under the License is distributed on an "AS IS" BASIS,
568
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
569
- See the License for the specific language governing permissions and
570
- limitations under the License.
571
- */
572
-
573
- function getOrInit(container, key, init) {
574
- let value = container.get(key);
575
- if (value === undefined) {
576
- value = init();
577
- container.set(key, value);
578
- }
579
- return value;
580
- }
581
-
582
- // export class WeakRefMap<K, V extends object> {
583
- // map = new Map<K, WeakRef<V>>()
584
- // finReg = new FinalizationRegistry<K>((key) => this.map.delete(key))
585
- // get(key: K) {
586
- // return this.map.get(key)?.deref()
587
- // }
588
- // set(key: K, value: V) {
589
- // this.map.set(key, new WeakRef(value))
590
- // this.finReg.register(value, key, value)
591
- // }
592
- // delete(key: K) {
593
- // const value = this.get(key)
594
- // if (!value) return false
595
- // this.map.delete(key)
596
- // this.finReg.unregister(value)
597
- // return true
598
- // }
599
- // }
600
-
601
- /**
602
- * Adapted from https://github.com/paritytech/capi-old copyright Parity Technologies (APACHE License 2.0)
603
- * Changes August 19th 2023 :
604
- * - updated to use subshape for scale decoding
605
- * - adapted from deno to typescript
606
- *
607
- Copyright 2023 Parity Technologies
608
-
609
- Licensed under the Apache License, Version 2.0 (the "License");
610
- you may not use this file except in compliance with the License.
611
- You may obtain a copy of the License at
612
-
613
- http://www.apache.org/licenses/LICENSE-2.0
614
-
615
- Unless required by applicable law or agreed to in writing, software
616
- distributed under the License is distributed on an "AS IS" BASIS,
617
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
618
- See the License for the specific language governing permissions and
619
- limitations under the License.
620
- */
621
-
622
- class ChainError extends Error {
623
- name = "ChainError";
624
- constructor(value) {
625
- super();
626
- this.value = value;
627
- this.stack = "ChainError: see error.value\n [error occurred on chain]";
628
- }
629
- static toArgs = x => [x.value];
630
- }
631
-
632
- /**
633
- * Adapted from https://github.com/paritytech/capi-old copyright Parity Technologies (APACHE License 2.0)
634
- * Changes August 19th 2023 :
635
- * - updated to use subshape for scale decoding
636
- * - adapted from deno to typescript
637
- *
638
- Copyright 2023 Parity Technologies
639
-
640
- Licensed under the Apache License, Version 2.0 (the "License");
641
- you may not use this file except in compliance with the License.
642
- You may obtain a copy of the License at
643
-
644
- http://www.apache.org/licenses/LICENSE-2.0
645
-
646
- Unless required by applicable law or agreed to in writing, software
647
- distributed under the License is distributed on an "AS IS" BASIS,
648
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
649
- See the License for the specific language governing permissions and
650
- limitations under the License.
651
- */
652
- // eslint-disable-next-line @typescript-eslint/no-namespace
653
- let Era;
654
- (function (_Era) {
655
- _Era.Immortal = {
656
- type: "Immortal"
657
- };
658
- function Mortal(period, current) {
659
- const adjustedPeriod = minN(maxN(nextPowerOfTwo(period), 4n), 1n << 16n);
660
- const phase = current % adjustedPeriod;
661
- const quantizeFactor = maxN(adjustedPeriod >> 12n, 1n);
662
- const quantizedPhase = phase / quantizeFactor * quantizeFactor;
663
- return {
664
- type: "Mortal",
665
- period: adjustedPeriod,
666
- phase: quantizedPhase
667
- };
668
- }
669
- _Era.Mortal = Mortal;
670
- })(Era || (Era = {}));
671
- const $era = $.createShape({
672
- metadata: $.metadata("$era"),
673
- staticSize: 2,
674
- subEncode(buffer, value) {
675
- if (value.type === "Immortal") {
676
- buffer.array[buffer.index++] = 0;
677
- } else {
678
- const quantizeFactor = maxN(value.period >> 12n, 1n);
679
- const encoded = minN(maxN(trailingZeroes(value.period) - 1n, 1n), 15n) | value.phase / quantizeFactor << 4n;
680
- $.u16.subEncode(buffer, Number(encoded));
681
- }
682
- },
683
- subDecode(buffer) {
684
- if (buffer.array[buffer.index] === 0) {
685
- buffer.index++;
686
- return {
687
- type: "Immortal"
688
- };
689
- } else {
690
- const encoded = BigInt($.u16.subDecode(buffer));
691
- const period = 2n << encoded % (1n << 4n);
692
- const quantizeFactor = maxN(period >> 12n, 1n);
693
- const phase = (encoded >> 4n) * quantizeFactor;
694
- if (period >= 4n && phase <= period) {
695
- return {
696
- type: "Mortal",
697
- period,
698
- phase
699
- };
700
- } else {
701
- throw new Error("Invalid period and phase");
702
- }
703
- }
704
- },
705
- subAssert: $.taggedUnion("type", [$.variant("Immortal"), $.variant("Mortal", $.field("period", $.u64), $.field("phase", $.u64))]).subAssert
706
- });
707
- function maxN(a, b) {
708
- return a > b ? a : b;
709
- }
710
- function minN(a, b) {
711
- return a < b ? a : b;
712
- }
713
- function trailingZeroes(n) {
714
- let i = 0n;
715
- while (!(n & 1n)) {
716
- i++;
717
- n >>= 1n;
718
- }
719
- return i;
720
- }
721
- function nextPowerOfTwo(n) {
722
- n--;
723
- let p = 1n;
724
- while (n > 0n) {
725
- p <<= 1n;
726
- n >>= 1n;
727
- }
728
- return p;
729
- }
730
-
731
- /* eslint-disable @typescript-eslint/no-non-null-assertion */
732
- const isResult = new $.ShapeVisitor().add($.result, () => true).fallback(() => false);
733
- const isOption = new $.ShapeVisitor().add($.option, () => true).fallback(() => false);
734
- const overrides = {
735
- "Option": (ty, visit) => {
736
- let $some = visit(ty.params[0].ty);
737
- if (isOption.visit($some)) {
738
- $some = $.tuple($some);
739
- }
740
- return $.option($some);
741
- },
742
- "Result": (ty, visit) => {
743
- let $ok = visit(ty.params[0].ty);
744
- if (isResult.visit($ok)) {
745
- $ok = $.tuple($ok);
746
- }
747
- return $.result($ok, $.instance(ChainError, $.tuple(visit(ty.params[1].ty)), ChainError.toArgs));
748
- },
749
- "BTreeMap": (ty, visit) => {
750
- return $.map(visit(ty.params[0].ty), visit(ty.params[1].ty));
751
- },
752
- "BTreeSet": (ty, visit) => {
753
- return $.set(visit(ty.params[0].ty));
754
- },
755
- "frame_support::traits::misc::WrapperOpaque": (ty, visit) => {
756
- return $.lenPrefixed(visit(ty.params[0].ty));
757
- },
758
- "frame_support::traits::misc::WrapperKeepOpaque": (ty, visit) => {
759
- return $.lenPrefixed(visit(ty.params[0].ty));
760
- },
761
- "sp_runtime::generic::era::Era": () => {
762
- return $era;
763
- }
764
- };
765
-
766
- /* eslint-disable @typescript-eslint/no-non-null-assertion */
767
- /**
768
- * All derived codecs for ZSTs will use this exact codec,
769
- * so `derivedCodec === $null` is true iff the type is a ZST.
770
- */
771
- const $null = $.withMetadata($.metadata("$null"), $.constant(null));
772
- function transformTys(tys) {
773
- const tysMap = new Map(tys.map(ty => [ty.id, ty]));
774
- const memo = new Map();
775
- const types = {};
776
- const paths = {};
777
- const seenPaths = new Map();
778
- const includePaths = new Set();
779
- const names = new Map();
780
- const nameCounts = new Map();
781
- for (const ty of tys) {
782
- const path = ty.path.join("::");
783
- if (!path) continue;
784
- const last = seenPaths.get(path);
785
- if (last !== undefined) {
786
- if (last === null || !eqTy(tysMap, last.id, ty.id)) {
787
- seenPaths.set(path, null);
788
- includePaths.delete(path);
789
- }
790
- continue;
791
- }
792
- seenPaths.set(path, ty);
793
- includePaths.add(path);
794
- }
795
- for (const path of includePaths) {
796
- const parts = path.split("::");
797
- const name = parts.at(-1);
798
- const map = getOrInit(nameCounts, name, () => new Map());
799
- for (let i = 0; i < parts.length; i++) {
800
- const pathPart = parts.slice(0, i).join("::");
801
- map.set(pathPart, (map.get(pathPart) ?? 0) + 1);
802
- }
803
- }
804
- for (const path of includePaths) {
805
- const parts = path.split("::");
806
- const name = parts.at(-1);
807
- const map = nameCounts.get(name);
808
- const pathLength = parts.findIndex((_, i) => map.get(parts.slice(0, i).join("::")) === 1);
809
- const newPath = [...parts.slice(0, pathLength), name].join("::");
810
- const newName = normalizeTypeName(newPath);
811
- names.set(path, newName);
812
- }
813
- return {
814
- ids: tys.map(ty => visit(ty.id)),
815
- types,
816
- paths
817
- };
818
- function visit(i) {
819
- return getOrInit(memo, i, () => {
820
- memo.set(i, $.deferred(() => memo.get(i)));
821
- const ty = tysMap.get(i);
822
- const path = ty.path.join("::");
823
- const usePath = includePaths.has(path);
824
- const name = names.get(path);
825
- if (usePath && types[name]) return types[name];
826
- const codec = withDocs(ty.docs, _visit(ty));
827
- if (usePath) return types[name] ??= paths[path] = codec;
828
- return codec;
829
- });
830
- }
831
- function _visit(ty) {
832
- const overrideFn = overrides[ty.path.join("::")];
833
- if (overrideFn) return overrideFn(ty, visit);
834
- if (ty.type === "Struct") {
835
- if (ty.fields.length === 0) {
836
- return $null;
837
- } else if (ty.fields[0].name === undefined) {
838
- if (ty.fields.length === 1) {
839
- // wrapper
840
- return visit(ty.fields[0].ty);
841
- } else {
842
- return $.tuple(...ty.fields.map(x => visit(x.ty)));
843
- }
844
- } else {
845
- return $.object(...ty.fields.map(x => withDocs(x.docs, maybeOptionalField(normalizeIdent(x.name), visit(x.ty)))));
846
- }
847
- } else if (ty.type === "Tuple") {
848
- if (ty.fields.length === 0) {
849
- return $null;
850
- } else if (ty.fields.length === 1) {
851
- // wrapper
852
- return visit(ty.fields[0]);
853
- } else {
854
- return $.tuple(...ty.fields.map(x => visit(x)));
855
- }
856
- } else if (ty.type === "Union") {
857
- if (ty.members.length === 0) {
858
- return $.never;
859
- } else if (ty.members.every(x => x.fields.length === 0)) {
860
- const members = {};
861
- for (const {
862
- index,
863
- name
864
- } of ty.members) {
865
- members[index] = normalizeIdent(name);
866
- }
867
- return $.literalUnion(members);
868
- } else {
869
- const members = {};
870
- for (const {
871
- fields,
872
- name,
873
- index
874
- } of ty.members) {
875
- let member;
876
- const type = normalizeIdent(name);
877
- if (fields.length === 0) {
878
- member = $.variant(type);
879
- } else if (fields[0].name === undefined) {
880
- // Tuple variant
881
- const $value = fields.length === 1 ? visit(fields[0].ty) : $.tuple(...fields.map(f => visit(f.ty)));
882
- member = $.variant(type, maybeOptionalField("value", $value));
883
- } else {
884
- // Object variant
885
- const memberFields = fields.map(field => {
886
- return withDocs(field.docs, maybeOptionalField(normalizeIdent(field.name), visit(field.ty)));
887
- });
888
- member = $.variant(type, ...memberFields);
889
- }
890
- members[index] = member;
891
- }
892
- return $.taggedUnion("type", members);
893
- }
894
- } else if (ty.type === "Sequence") {
895
- const $inner = visit(ty.typeParam);
896
- if ($inner === $.u8) {
897
- return $.uint8Array;
898
- } else {
899
- return $.array($inner);
900
- }
901
- } else if (ty.type === "SizedArray") {
902
- const $inner = visit(ty.typeParam);
903
- if ($inner === $.u8) {
904
- return $.sizedUint8Array(ty.len);
905
- } else {
906
- return $.sizedArray($inner, ty.len);
907
- }
908
- } else if (ty.type === "Primitive") {
909
- if (ty.kind === "char") return $.str;
910
- return $[ty.kind];
911
- } else if (ty.type === "Compact") {
912
- return $.compact(visit(ty.typeParam));
913
- } else if (ty.type === "BitSequence") {
914
- return $.bitSequence;
915
- } else {
916
- throw new Error("unreachable");
917
- }
918
- }
919
- }
920
- function withDocs(_docs, codec) {
921
- const docs = normalizeDocs(_docs);
922
- if (docs) return $.documented(docs, codec);
923
- return codec;
924
- }
925
- function eqTy(tysMap, a, b) {
926
- const seen = new Set();
927
- return eqTy(a, b);
928
- function eqTy(ai, bi) {
929
- const key = `${ai}=${bi}`;
930
- if (seen.has(key)) return true;
931
- seen.add(key);
932
- const a = tysMap.get(ai);
933
- const b = tysMap.get(bi);
934
- if (a.id === b.id) return true;
935
- if (a.type !== b.type) return false;
936
- if (a.path.join("::") !== b.path.join("::")) return false;
937
- if (normalizeDocs(a.docs) !== normalizeDocs(b.docs)) return false;
938
- if (!eqArray(a.params, b.params, (a, b) => a.name === b.name && a.ty == null === (b.ty == null) && (a.ty == null || eqTy(a.ty, b.ty)))) {
939
- return false;
940
- }
941
- if (a.type === "BitSequence") {
942
- return true;
943
- }
944
- if (a.type === "Primitive" && b.type === "Primitive") {
945
- return a.kind === b.kind;
946
- }
947
- if (a.type === "Compact" && b.type === "Compact" || a.type === "Sequence" && b.type === "Sequence") {
948
- return eqTy(a.typeParam, b.typeParam);
949
- }
950
- if (a.type === "SizedArray" && b.type === "SizedArray") {
951
- return a.len === b.len && eqTy(a.typeParam, b.typeParam);
952
- }
953
- if (a.type === "Struct" && b.type === "Struct") {
954
- return eqArray(a.fields, b.fields, eqField);
955
- }
956
- if (a.type === "Tuple" && b.type === "Tuple") {
957
- return eqArray(a.fields, b.fields, eqTy);
958
- }
959
- if (a.type === "Union" && b.type === "Union") {
960
- return eqArray(a.members, b.members, (a, b) => a.index === b.index && a.name === b.name && normalizeDocs(a.docs) === normalizeDocs(b.docs) && eqArray(a.fields, b.fields, eqField));
961
- }
962
- return false;
963
- }
964
- function eqField(a, b) {
965
- return a.name === b.name && a.typeName === b.typeName && eqDocs(a.docs, b.docs) && eqTy(a.ty, b.ty);
966
- }
967
- function eqDocs(a, b) {
968
- return normalizeDocs(a) === normalizeDocs(b);
969
- }
970
- function eqArray(a, b, eqVal) {
971
- return a.length === b.length && a.every((x, i) => eqVal(x, b[i]));
972
- }
973
- }
974
- const optionInnerVisitor = new $.ShapeVisitor().add($.option, (_codec, $some) => $some).fallback(() => null);
975
- function maybeOptionalField(key, $value) {
976
- const $inner = optionInnerVisitor.visit($value);
977
- return $inner ? $.optionalField(key, $inner) : $.field(key, $value);
978
- }
979
-
980
- /* eslint-disable @typescript-eslint/no-non-null-assertion */
981
- function $storageKey(palletName, entryName, $key) {
982
- const palletHash = twox128.hash(new TextEncoder().encode(palletName));
983
- const entryHash = twox128.hash(new TextEncoder().encode(entryName));
984
- return $.createShape({
985
- metadata: $.metadata("$storageKey", $storageKey, palletName, entryName, $key),
986
- staticSize: $key.staticSize + 32,
987
- subEncode(buffer, key) {
988
- buffer.insertArray(palletHash);
989
- buffer.insertArray(entryHash);
990
- $key.subEncode(buffer, key);
991
- },
992
- subDecode(buffer) {
993
- // Ignore initial hashes
994
- buffer.index += 32;
995
- return $key.subDecode(buffer);
996
- },
997
- subAssert(assert) {
998
- $key.subAssert(assert);
999
- }
1000
- });
1001
- }
1002
- const $emptyKey = $.withMetadata($.metadata("$emptyKey"), $.constant(undefined));
1003
- const $partialEmptyKey = $.createShape({
1004
- metadata: $.metadata("$partialEmptyKey"),
1005
- staticSize: 0,
1006
- subEncode() {},
1007
- subDecode() {
1008
- throw new Error("Cannot decode partial key");
1009
- },
1010
- subAssert(assert) {
1011
- if (assert.value != null) {
1012
- throw new $.ShapeAssertError(this, assert.value, `${assert.path} != null`);
1013
- }
1014
- }
1015
- });
1016
- function $partialSingleKey($inner) {
1017
- return $.createShape({
1018
- metadata: $.metadata("$partialSingleKey", $partialSingleKey, $inner),
1019
- staticSize: $inner.staticSize,
1020
- subEncode(buffer, key) {
1021
- if (key !== null) $inner.subEncode(buffer, key);
1022
- },
1023
- subDecode() {
1024
- throw new Error("Cannot decode partial key");
1025
- },
1026
- subAssert(assert) {
1027
- if (assert.value === null) return;
1028
- $inner.subAssert(assert);
1029
- }
1030
- });
1031
- }
1032
-
1033
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1034
-
1035
- function $partialMultiKey(...codecs) {
1036
- return $.createShape({
1037
- metadata: $.metadata("$partialMultiKey", $partialMultiKey, ...codecs),
1038
- staticSize: $.tuple(...codecs).staticSize,
1039
- subEncode(buffer, key) {
1040
- if (!key) return;
1041
- for (let i = 0; i < key.length; i++) {
1042
- codecs[i].subEncode(buffer, key[i]);
1043
- }
1044
- },
1045
- subDecode() {
1046
- throw new Error("Cannot decode partial key");
1047
- },
1048
- subAssert(assert) {
1049
- if (assert.value === null) return;
1050
- assert.instanceof(this, Array);
1051
- const assertLength = assert.key(this, "length");
1052
- assertLength.typeof(this, "number");
1053
- const length = assertLength.value;
1054
- $.tuple(...codecs.slice(0, length)).subAssert(assert);
1055
- }
1056
- });
1057
- }
1058
-
1059
- /* eslint-disable @typescript-eslint/no-non-null-assertion */
1060
- const hashers = {
1061
- blake2_128,
1062
- blake2_256,
1063
- blake2_128Concat,
1064
- twox128,
1065
- twox256,
1066
- twox64Concat,
1067
- identity
1068
- };
1069
- const $hasher = $.literalUnion(["blake2_128", "blake2_256", "blake2_128Concat", "twox128", "twox256", "twox64Concat", "identity"]);
1070
- const $storageEntry = $.object($.field("name", $.str), $.field("modifier", $.literalUnion(["Optional", "Default"])), $.taggedUnion("type", [$.variant("Plain", $.field("value", $tyId)), $.variant("Map", $.field("hashers", $.array($hasher)), $.field("key", $tyId), $.field("value", $tyId))]), $.field("default", $.uint8Array), $.field("docs", $.array($.str)));
1071
- const $constant = $.object($.field("name", $.str), $.field("ty", $tyId), $.field("value", $.uint8Array), $.field("docs", $.array($.str)));
1072
- const $pallet = $.object($.field("name", $.str), $.optionalField("storage", $.object($.field("prefix", $.str), $.field("entries", $.array($storageEntry)))), $.optionalField("calls", $tyId), $.optionalField("event", $tyId), $.field("constants", $.array($constant)), $.optionalField("error", $tyId), $.field("id", $.u8));
1073
- const $extrinsicDef = $.object($.field("ty", $tyId), $.field("version", $.u8), $.field("signedExtensions", $.array($.object($.field("ident", $.str), $.field("ty", $tyId), $.field("additionalSigned", $tyId)))));
1074
-
1075
- // https://docs.substrate.io/build/application-development/#metadata-system
9
+ /** Constant: https://docs.substrate.io/build/application-development/#metadata-format */
1076
10
  const magicNumber = 1635018093;
1077
- const $metadata = $.object($.field("magicNumber", $.constant(magicNumber, $.u32)), $.field("version", $.constant(14, $.u8)), $.field("tys", $.array($ty)), $.field("pallets", $.array($pallet)), $.field("extrinsic", $extrinsicDef),
1078
- // TODO: is this useful?
1079
- $.field("runtime", $tyId));
1080
- function transformMetadata(metadata) {
1081
- const {
1082
- ids,
1083
- types,
1084
- paths
1085
- } = transformTys(metadata.tys);
1086
- return {
1087
- types,
1088
- paths,
1089
- pallets: Object.fromEntries(metadata.pallets.map(pallet => [pallet.name, {
1090
- id: pallet.id,
1091
- name: pallet.name,
1092
- storagePrefix: pallet.storage?.prefix ?? pallet.name,
1093
- storage: Object.fromEntries(pallet.storage?.entries.map(storage => {
1094
- let key, partialKey;
1095
- if (storage.type === "Plain") {
1096
- key = $emptyKey;
1097
- partialKey = $partialEmptyKey;
1098
- } else if (storage.hashers.length === 1) {
1099
- key = hashers[storage.hashers[0]].$hash(ids[storage.key]);
1100
- partialKey = $partialSingleKey(key);
1101
- } else {
1102
- const codecs = extractTupleMembersVisitor.visit(ids[storage.key]).map((codec, i) => hashers[storage.hashers[i]].$hash(codec));
1103
- key = $.tuple(...codecs);
1104
- partialKey = $partialMultiKey(...codecs);
1105
- }
1106
- return [storage.name, {
1107
- singular: storage.type === "Plain",
1108
- name: storage.name,
1109
- key: $storageKey(pallet.name, storage.name, key),
1110
- partialKey: $storageKey(pallet.name, storage.name, partialKey),
1111
- value: ids[storage.value],
1112
- docs: normalizeDocs(storage.docs),
1113
- default: storage.modifier === "Default" ? storage.default : undefined
1114
- }];
1115
- }) ?? []),
1116
- constants: Object.fromEntries(pallet.constants.map(constant => [constant.name, {
1117
- name: constant.name,
1118
- codec: ids[constant.ty],
1119
- value: constant.value,
1120
- docs: normalizeDocs(constant.docs)
1121
- }])),
1122
- types: {
1123
- call: ids[pallet.calls],
1124
- error: ids[pallet.error],
1125
- event: ids[pallet.event]
1126
- },
1127
- docs: ""
1128
- }])),
1129
- extrinsic: {
1130
- call: getExtrinsicParameter("call"),
1131
- signature: getExtrinsicParameter("signature"),
1132
- address: getExtrinsicParameter("address"),
1133
- extra: getExtensionsCodec("ty"),
1134
- additional: getExtensionsCodec("additionalSigned")
1135
- }
1136
- };
1137
- function getExtrinsicParameter(key) {
1138
- const extrinsicTy = metadata.tys[metadata.extrinsic.ty];
1139
- if (!extrinsicTy) return $.never;
1140
- return ids[extrinsicTy.params.find(x => x.name.toLowerCase() === key).ty];
1141
- }
1142
- function getExtensionsCodec(key) {
1143
- return $.object(...metadata.extrinsic.signedExtensions.flatMap(ext => {
1144
- const codec = ids[ext[key]];
1145
- if (codec === $null) return [];
1146
- return [$.field(normalizeIdent(ext.ident), codec)];
1147
- }) // eslint-disable-line @typescript-eslint/no-explicit-any
1148
- );
1149
- }
1150
- }
1151
-
1152
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1153
- const extractTupleMembersVisitor = new $.ShapeVisitor().add(
1154
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1155
- $.tuple, (_codec, ...members) => members);
1156
-
1157
- /**
1158
- * Adapted from https://github.com/paritytech/capi-old copyright Parity Technologies (APACHE License 2.0)
1159
- * Changes August 19th 2023 :
1160
- * - updated to use subshape for scale decoding
1161
- * - adapted from deno to typescript
1162
- *
1163
- Copyright 2023 Parity Technologies
1164
-
1165
- Licensed under the Apache License, Version 2.0 (the "License");
1166
- you may not use this file except in compliance with the License.
1167
- You may obtain a copy of the License at
1168
-
1169
- http://www.apache.org/licenses/LICENSE-2.0
1170
-
1171
- Unless required by applicable law or agreed to in writing, software
1172
- distributed under the License is distributed on an "AS IS" BASIS,
1173
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1174
- See the License for the specific language governing permissions and
1175
- limitations under the License.
1176
- */
1177
- function decodeMetadata(encoded) {
1178
- return transformMetadata($metadata.decode(encoded));
1179
- }
1180
- const $metadataV14 = $metadata;
1181
-
1182
- /* eslint-disable @typescript-eslint/no-non-null-assertion */
1183
- function $extrinsic(metadata) {
1184
- const $sig = metadata.extrinsic.signature;
1185
- const $sigPromise = $.promise($sig);
1186
- const $call = metadata.extrinsic.call;
1187
- const $address = metadata.extrinsic.address;
1188
- const $extra = metadata.extrinsic.extra;
1189
- const $additional = metadata.extrinsic.additional;
1190
- const toSignSize = $call.staticSize + $extra.staticSize + $additional.staticSize;
1191
- const totalSize = 1 + $address.staticSize + $sig.staticSize + toSignSize;
1192
- const $baseExtrinsic = $.createShape({
1193
- metadata: [],
1194
- staticSize: totalSize,
1195
- subEncode(buffer, extrinsic) {
1196
- const firstByte = +!!extrinsic.signature << 7 | extrinsic.protocolVersion;
1197
- buffer.array[buffer.index++] = firstByte;
1198
- const {
1199
- signature,
1200
- call
1201
- } = extrinsic;
1202
- if (signature) {
1203
- $address.subEncode(buffer, signature.sender.address);
1204
- if (signature.additional) {
1205
- const toSignBuffer = new $.EncodeBuffer(buffer.stealAlloc(toSignSize));
1206
- $call.subEncode(toSignBuffer, call);
1207
- const callEnd = toSignBuffer.finishedSize + toSignBuffer.index;
1208
- $extra.subEncode(toSignBuffer, signature.extra);
1209
- const extraEnd = toSignBuffer.finishedSize + toSignBuffer.index;
1210
- $additional.subEncode(toSignBuffer, signature.additional);
1211
- const toSignEncoded = toSignBuffer.finish();
1212
- const callEncoded = toSignEncoded.subarray(0, callEnd);
1213
- const extraEncoded = toSignEncoded.subarray(callEnd, extraEnd);
1214
- const toSign = toSignEncoded.length > 256 ? blake2_256.hash(toSignEncoded) : toSignEncoded;
1215
- const sig = signature.sender.sign(toSign, toSignEncoded);
1216
- if (sig instanceof Promise) {
1217
- $sigPromise.subEncode(buffer, sig);
1218
- } else {
1219
- $sig.subEncode(buffer, sig);
1220
- }
1221
- buffer.insertArray(extraEncoded);
1222
- buffer.insertArray(callEncoded);
1223
- } else {
1224
- $sig.subEncode(buffer, signature.sig);
1225
- $extra.subEncode(buffer, signature.extra);
1226
- $call.subEncode(buffer, call);
1227
- }
1228
- } else {
1229
- $call.subEncode(buffer, call);
1230
- }
1231
- },
1232
- subDecode(buffer) {
1233
- const firstByte = buffer.array[buffer.index++];
1234
- const hasSignature = firstByte & 1 << 7;
1235
- const protocolVersion = firstByte & ~(1 << 7);
1236
- let signature;
1237
- if (hasSignature) {
1238
- const address = $address.subDecode(buffer);
1239
- const sig = $sig.subDecode(buffer);
1240
- const extra = $extra.subDecode(buffer);
1241
- signature = {
1242
- sender: {
1243
- address
1244
- },
1245
- sig,
1246
- extra
1247
- };
1248
- }
1249
- const call = $call.subDecode(buffer);
1250
- return {
1251
- protocolVersion,
1252
- signature,
1253
- call
1254
- };
1255
- },
1256
- subAssert(assert) {
1257
- assert.typeof(this, "object");
1258
- assert.key(this, "protocolVersion").equals($.u8, 4);
1259
- const value_ = assert.value;
1260
- $call.subAssert(assert.key(this, "call"));
1261
- if (value_.signature) {
1262
- const signatureAssertState = assert.key(this, "signature");
1263
- $address.subAssert(signatureAssertState.key(this, "sender").key(this, "address"));
1264
- $extra.subAssert(signatureAssertState.key(this, "extra"));
1265
- if ("additional" in value_.signature) {
1266
- $additional.subAssert(signatureAssertState.key(this, "additional"));
1267
- signatureAssertState.key(this, "sender").key(this, "sign").typeof(this, "function");
1268
- } else {
1269
- $sig.subAssert(signatureAssertState.key(this, "sig"));
1270
- }
1271
- }
1272
- }
1273
- });
1274
- return $.withMetadata($.metadata("$extrinsic", $extrinsic, metadata), $.lenPrefixed($baseExtrinsic));
1275
- }
1276
- class SignerError extends Error {
1277
- name = "SignerError";
1278
- constructor(inner) {
1279
- super();
1280
- this.inner = inner;
1281
- }
1282
- }
1283
11
 
1284
12
  var packageJson = {
1285
13
  name: "@talismn/scale",
1286
- version: "0.0.0-pr997-20231116062730",
14
+ version: "0.1.0",
1287
15
  author: "Talisman",
1288
16
  homepage: "https://talisman.xyz",
1289
17
  license: "GPL-3.0-or-later",
@@ -1306,27 +34,23 @@ var packageJson = {
1306
34
  scripts: {
1307
35
  test: "jest",
1308
36
  lint: "eslint src --max-warnings 0",
1309
- clean: "rm -rf dist && rm -rf .turbo rm -rf node_modules"
37
+ clean: "rm -rf dist .turbo node_modules"
1310
38
  },
1311
39
  dependencies: {
1312
- "@talismn/subshape-fork": "^0.0.1",
1313
- "@talismn/util": "workspace:*",
40
+ "@polkadot-api/metadata-builders": "0.9.1",
41
+ "@polkadot-api/substrate-bindings": "0.9.3",
42
+ "@polkadot-api/utils": "0.1.2",
1314
43
  anylogger: "^1.0.11",
1315
- "wasm-feature-detect": "^1.6.0",
1316
- "wat-the-crypto": "^0.0.3"
44
+ "scale-ts": "^1.6.1"
1317
45
  },
1318
46
  devDependencies: {
1319
- "@polkadot/util-crypto": "^11.1.1",
1320
47
  "@talismn/eslint-config": "workspace:*",
1321
48
  "@talismn/tsconfig": "workspace:*",
1322
- "@types/jest": "^27.5.1",
1323
- eslint: "^8.52.0",
49
+ "@types/jest": "^29.5.14",
50
+ eslint: "^8.57.1",
1324
51
  jest: "^29.7",
1325
- "ts-jest": "^29.1.1",
1326
- typescript: "^5.2.2"
1327
- },
1328
- peerDependencies: {
1329
- "@polkadot/util-crypto": "^11.x"
52
+ "ts-jest": "^29.2.5",
53
+ typescript: "^5.6.3"
1330
54
  },
1331
55
  eslintConfig: {
1332
56
  root: true,
@@ -1338,37 +62,49 @@ var packageJson = {
1338
62
 
1339
63
  var log = anylogger(packageJson.name);
1340
64
 
1341
- const filterMetadataPalletsAndItems = (metadata, palletsAndItems, extraKeepTypes) => {
65
+ /**
66
+ * Converts a `Metadata` into a `MiniMetadata`.
67
+ *
68
+ * A `MiniMetadata` only contains the types inside of its `lookup` which are relevant for
69
+ * the storage queries specified in `palletsAndItems`.
70
+ *
71
+ * E.g. if `palletsAndItems` is `{ pallet: "System", items: ["Account"] }`, then only the
72
+ * types used in the `System.Account` storage query will remain inside of metadata.lookups.
73
+ */
74
+ const compactMetadata = (metadata, palletsAndItems, extraKeepTypes) => {
1342
75
  // remove pallets we don't care about
1343
76
  metadata.pallets = metadata.pallets.filter(pallet =>
1344
77
  // keep this pallet if it's listed in `palletsAndItems`
1345
78
  palletsAndItems.some(({
1346
- pallet: palletFilter
1347
- }) => palletFilter(pallet)));
79
+ pallet: palletName
80
+ }) => pallet.name === palletName));
1348
81
 
1349
82
  // remove fields we don't care about from each pallet, and extract types for each storage item we care about
1350
83
  const items = palletsAndItems.flatMap(({
1351
- pallet: palletFilter,
1352
- items
84
+ pallet: palletName,
85
+ items: itemNames
1353
86
  }) => {
1354
- const pallet = metadata.pallets.find(palletFilter);
1355
- if (!pallet || !pallet.storage) {
1356
- log.warn("Failed to find pallet", palletFilter);
87
+ const pallet = metadata.pallets.find(pallet => pallet.name === palletName);
88
+ if (!pallet) {
89
+ log.debug("Failed to find pallet", palletName);
1357
90
  return [];
1358
91
  }
1359
92
 
1360
- // remove fields we don't care about
93
+ // remove pallet fields we don't care about
1361
94
  pallet.calls = undefined;
1362
95
  pallet.constants = [];
1363
- pallet.error = undefined;
1364
- pallet.event = undefined;
96
+ // v15 (NOT v14) has docs
97
+ if ("docs" in pallet) pallet.docs = [];
98
+ pallet.errors = undefined;
99
+ pallet.events = undefined;
100
+ if (!pallet.storage) return [];
1365
101
 
1366
102
  // filter and extract storage items we care about
1367
- pallet.storage.entries = pallet.storage.entries.filter(item => items.some(itemFilter => itemFilter(item)));
1368
- return pallet.storage.entries;
103
+ pallet.storage.items = pallet.storage.items.filter(item => itemNames.some(itemName => item.name === itemName));
104
+ return pallet.storage.items;
1369
105
  });
1370
106
 
1371
- // this is a set of type ids which we plan to keep in our mutated metadata
107
+ // this is a set of type ids which we plan to keep in our compacted metadata
1372
108
  // anything not in this set will be deleted
1373
109
  // we start off with just the types of the state calls we plan to make,
1374
110
  // then we run those types through a function (addDependentTypes) which will also include
@@ -1377,15 +113,45 @@ const filterMetadataPalletsAndItems = (metadata, palletsAndItems, extraKeepTypes
1377
113
  // each type can be either "Plain" or "Map"
1378
114
  // if it's "Plain" we only need to get the value type
1379
115
  // if it's a "Map" we want to keep both the key AND the value types
1380
- item.type === "Map" && item.key, item.value]).filter(type => typeof type === "number"));
116
+ item.type.tag === "plain" && item.type.value, item.type.tag === "map" && item.type.value.key, item.type.tag === "map" && item.type.value.value]).filter(type => typeof type === "number"));
1381
117
  extraKeepTypes?.forEach(type => keepTypes.add(type));
1382
118
 
1383
119
  // recursively find all the types which our keepTypes depend on and add them to the keepTypes set
1384
- const metadataTysMap = new Map(metadata.tys.map(ty => [ty.id, ty]));
120
+ const metadataTysMap = new Map(metadata.lookup.map(ty => [ty.id, ty]));
1385
121
  addDependentTypes(metadataTysMap, keepTypes, [...keepTypes]);
1386
122
 
1387
123
  // ditch the types we aren't keeping
1388
- metadata.tys = metadata.tys.filter(type => keepTypes.has(type.id));
124
+ metadata.lookup = metadata.lookup.filter(type => keepTypes.has(type.id));
125
+
126
+ // update all type ids to be sequential (fill the gaps left by the deleted types)
127
+ const newTypeIds = new Map();
128
+ metadata.lookup.forEach((type, index) => newTypeIds.set(type.id, index));
129
+ const getNewTypeId = oldTypeId => {
130
+ const newTypeId = newTypeIds.get(oldTypeId);
131
+ if (typeof newTypeId !== "number") log.error(`Failed to find newTypeId for type ${oldTypeId}`);
132
+ return newTypeId ?? 0;
133
+ };
134
+ remapTypeIds(metadata, getNewTypeId);
135
+
136
+ // ditch the remaining data we don't need to keep in a miniMetata
137
+ if ("apis" in metadata) {
138
+ // metadata is v15 (NOT v14)
139
+ metadata.apis = [];
140
+ }
141
+ if ("address" in metadata.extrinsic) {
142
+ // metadata is v15 (NOT v14)
143
+ metadata.extrinsic.address = 0;
144
+ metadata.extrinsic.call = 0;
145
+ metadata.extrinsic.extra = 0;
146
+ metadata.extrinsic.signature = 0;
147
+ }
148
+ metadata.extrinsic.signedExtensions = [];
149
+ if ("outerEnums" in metadata) {
150
+ // metadata is v15 (NOT v14)
151
+ metadata.outerEnums.call = 0;
152
+ metadata.outerEnums.error = 0;
153
+ metadata.outerEnums.event = 0;
154
+ }
1389
155
  };
1390
156
  const addDependentTypes = (metadataTysMap, keepTypes, types,
1391
157
  // Prevent stack overflow when a type references itself
@@ -1400,39 +166,226 @@ addedTypes = new Set()) => {
1400
166
  if (addedTypes.has(type.id)) continue;
1401
167
  keepTypes.add(type.id);
1402
168
  addedTypes.add(type.id);
1403
- switch (type.type) {
1404
- case "Struct":
1405
- addDependentSubTypes([...type.params.map(param => param.ty).filter(ty => typeof ty === "number"), ...type.fields.map(field => field.ty).filter(ty => typeof ty === "number")]);
169
+ const paramTypes = type.params.map(param => param.type).filter(type => typeof type === "number");
170
+ addDependentSubTypes(paramTypes);
171
+ switch (type.def.tag) {
172
+ case "array":
173
+ addDependentSubTypes([type.def.value.type]);
174
+ break;
175
+ case "bitSequence":
176
+ addDependentSubTypes([type.def.value.bitOrderType, type.def.value.bitStoreType]);
177
+ break;
178
+ case "compact":
179
+ addDependentSubTypes([type.def.value]);
180
+ break;
181
+ case "composite":
182
+ addDependentSubTypes(type.def.value.map(field => field.type).filter(type => typeof type === "number"));
183
+ break;
184
+ case "primitive":
185
+ break;
186
+ case "sequence":
187
+ addDependentSubTypes([type.def.value]);
188
+ break;
189
+ case "tuple":
190
+ addDependentSubTypes(type.def.value.filter(type => typeof type === "number"));
1406
191
  break;
1407
- case "Union":
1408
- addDependentSubTypes([...type.params.map(param => param.ty).filter(ty => typeof ty === "number"), ...type.members.flatMap(member => member.fields.map(field => field.ty)).filter(ty => typeof ty === "number")]);
192
+ case "variant":
193
+ addDependentSubTypes(type.def.value.flatMap(member => member.fields.map(field => field.type)).filter(type => typeof type === "number"));
1409
194
  break;
1410
- case "Sequence":
1411
- addDependentSubTypes([...type.params.map(param => param.ty).filter(ty => typeof ty === "number"), type.typeParam]);
195
+ default:
196
+ {
197
+ // force compilation error if any types don't have a case
198
+ const exhaustiveCheck = type.def;
199
+ log.error(`Unhandled V15Type type ${exhaustiveCheck}`);
200
+ }
201
+ }
202
+ }
203
+ };
204
+ const remapTypeIds = (metadata, getNewTypeId) => {
205
+ remapLookupTypeIds(metadata, getNewTypeId);
206
+ remapStorageTypeIds(metadata, getNewTypeId);
207
+ };
208
+ const remapLookupTypeIds = (metadata, getNewTypeId) => {
209
+ for (const type of metadata.lookup) {
210
+ type.id = getNewTypeId(type.id);
211
+ for (const param of type.params) {
212
+ if (typeof param.type !== "number") continue;
213
+ param.type = getNewTypeId(param.type);
214
+ }
215
+ switch (type.def.tag) {
216
+ case "array":
217
+ type.def.value.type = getNewTypeId(type.def.value.type);
1412
218
  break;
1413
- case "SizedArray":
1414
- addDependentSubTypes([...type.params.map(param => param.ty).filter(ty => typeof ty === "number"), type.typeParam]);
219
+ case "bitSequence":
220
+ type.def.value.bitOrderType = getNewTypeId(type.def.value.bitOrderType);
221
+ type.def.value.bitStoreType = getNewTypeId(type.def.value.bitStoreType);
1415
222
  break;
1416
- case "Tuple":
1417
- addDependentSubTypes([...type.params.map(param => param.ty).filter(ty => typeof ty === "number"), ...type.fields.filter(ty => typeof ty === "number")]);
223
+ case "compact":
224
+ type.def.value = getNewTypeId(type.def.value);
1418
225
  break;
1419
- case "Primitive":
1420
- addDependentSubTypes([...type.params.map(param => param.ty).filter(ty => typeof ty === "number")]);
226
+ case "composite":
227
+ for (const field of type.def.value) {
228
+ if (typeof field.type !== "number") continue;
229
+ field.type = getNewTypeId(field.type);
230
+ }
1421
231
  break;
1422
- case "Compact":
1423
- addDependentSubTypes([...type.params.map(param => param.ty).filter(ty => typeof ty === "number"), type.typeParam]);
232
+ case "primitive":
1424
233
  break;
1425
- case "BitSequence":
1426
- addDependentSubTypes([type.bitOrderType, type.bitStoreType]);
234
+ case "sequence":
235
+ type.def.value = getNewTypeId(type.def.value);
236
+ break;
237
+ case "tuple":
238
+ type.def.value = type.def.value.map(type => {
239
+ if (typeof type !== "number") return type;
240
+ return getNewTypeId(type);
241
+ });
242
+ break;
243
+ case "variant":
244
+ for (const member of type.def.value) {
245
+ for (const field of member.fields) {
246
+ if (typeof field.type !== "number") continue;
247
+ field.type = getNewTypeId(field.type);
248
+ }
249
+ }
1427
250
  break;
1428
251
  default:
1429
252
  {
1430
253
  // force compilation error if any types don't have a case
1431
- const exhaustiveCheck = type;
1432
- log.error(`Unhandled TyMV14 type ${exhaustiveCheck}`);
254
+ const exhaustiveCheck = type.def;
255
+ log.error(`Unhandled V15Type type ${exhaustiveCheck}`);
1433
256
  }
1434
257
  }
1435
258
  }
1436
259
  };
260
+ const remapStorageTypeIds = (metadata, getNewTypeId) => {
261
+ for (const pallet of metadata.pallets) {
262
+ for (const item of pallet.storage?.items ?? []) {
263
+ if (item.type.tag === "plain") item.type.value = getNewTypeId(item.type.value);
264
+ if (item.type.tag === "map") {
265
+ item.type.value.key = getNewTypeId(item.type.value.key);
266
+ item.type.value.value = getNewTypeId(item.type.value.value);
267
+ }
268
+ }
269
+ }
270
+ };
271
+
272
+ /**
273
+ * Extracts the `version` u8 from a SCALE-encoded metadata blob and returns it as a `number`.
274
+ *
275
+ * Only reads the first 40 bytes of the blob.
276
+ */
277
+ const getMetadataVersion = metadataRpc => {
278
+ try {
279
+ return Struct({
280
+ magicNumber: u32,
281
+ version: u8
282
+ }).dec(metadataRpc).version;
283
+ } catch {
284
+ return 0;
285
+ }
286
+ };
287
+
288
+ const decodeMetadata = metadataRpc => {
289
+ const metadataVersion = getMetadataVersion(metadataRpc);
290
+ if (metadataVersion !== 15 && metadataVersion !== 14) return {
291
+ metadataVersion
292
+ };
293
+ const decoded = metadata.dec(metadataRpc);
294
+ if (decoded.metadata.tag === "v15") return {
295
+ metadataVersion,
296
+ metadata: decoded.metadata.value,
297
+ tag: decoded.metadata.tag
298
+ };
299
+ if (decoded.metadata.tag === "v14") return {
300
+ metadataVersion,
301
+ metadata: decoded.metadata.value,
302
+ tag: decoded.metadata.tag
303
+ };
304
+ return {
305
+ metadataVersion
306
+ };
307
+ };
308
+
309
+ const decodeScale = (scaleCoder, change, error) => {
310
+ if (change === null) return null;
311
+ try {
312
+ return scaleCoder?.dec(change) ?? null;
313
+ } catch (cause) {
314
+ log.warn(error ?? `Failed to decode ${change}`, cause);
315
+ return null;
316
+ }
317
+ };
318
+
319
+ const encodeMetadata = ({
320
+ metadata: metadata$1,
321
+ tag
322
+ }) => toHex(metadata.enc({
323
+ magicNumber,
324
+ metadata: tag === "v15" ? {
325
+ tag,
326
+ value: metadata$1
327
+ } : {
328
+ tag,
329
+ value: metadata$1
330
+ }
331
+ }));
332
+
333
+ const encodeStateKey = (scaleCoder, error, ...args) => {
334
+ try {
335
+ return scaleCoder?.enc(...args);
336
+ } catch (cause) {
337
+ log.warn(error ?? `Failed to encode stateKey ${JSON.stringify(args)}`, cause);
338
+ return;
339
+ }
340
+ };
341
+
342
+ /**
343
+ * For the substrate-tokens (and other) modules, we configure the `onChainId` field in chaindata to tell the module how to query each token.
344
+ * These queries are made to the tokens pallet.
345
+ * E.g. api.query.Tokens.Account(accountAddress, papiParse(onChainId))
346
+ *
347
+ * The `onChainId` field on chaindata must be a JSON-parseable string, but for some SCALE types (especially the Binary type) we must
348
+ * use specific `polkadot-api` classes to handle SCALE-encoding the statekey.
349
+ *
350
+ * Some examples:
351
+ * Input: `5`
352
+ * Output: `5`
353
+ *
354
+ * Input: `{ type: "DexShare", value: [ { type: "Token", value: { type: "ACA" } }, { type: "Token", value: { type: "AUSD" } } ] }`
355
+ * Output: `Enum("DexShare", [Enum("Token", Enum("ACA")), Enum("Token", Enum("AUSD"))])`
356
+ *
357
+ * Input: `{ type: "LiquidCrowdloan", value: 13 }`
358
+ * Output: `Enum("LiquidCrowdloan", 13)`
359
+ *
360
+ * Input: `{ type: "NativeToken", value: "bigint:2" }`
361
+ * Output: `Enum("NativeToken", 2n)`
362
+ *
363
+ * Input: `{ type: "Erc20", value: "hex:0x07df96d1341a7d16ba1ad431e2c847d978bc2bce" }`
364
+ * Output: `Enum("Erc20", Binary.fromHex("0x07df96d1341a7d16ba1ad431e2c847d978bc2bce"))`
365
+ *
366
+ * Input: `{ type: "Stellar", value: { code: "bin:TZS", issuer: "hex:0x34c94b2a4ba9e8b57b22547dcbb30f443c4cb02da3829a89aa1bd4780e4466ba" } }`
367
+ * Output: `Enum("Stellar", { code: Binary.fromText("TZS"), issuer: Binary.fromHex("0x34c94b2a4ba9e8b57b22547dcbb30f443c4cb02da3829a89aa1bd4780e4466ba") })`
368
+ */
369
+ const papiParse = text => {
370
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
371
+ const reviver = (_key, value) => {
372
+ if (typeof value !== "string") return value;
373
+ if (value.startsWith("bigint:")) return BigInt(value.slice("bigint:".length));
374
+ if (value.startsWith("hex:")) return Binary.fromHex(value.slice("hex:".length));
375
+ if (value.startsWith("bin:")) return Binary.fromText(value.slice("bin:".length));
376
+ return value;
377
+ };
378
+ if (typeof text !== "string") return text;
379
+ return JSON.parse(text, reviver);
380
+ };
381
+ const papiStringify = (value, space) => {
382
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
383
+ const replacer = (_key, value) => {
384
+ if (typeof value === "bigint") return `bigint:${String(value)}`;
385
+ if (value instanceof Binary) return `hex:${value.asHex()}`;
386
+ return value;
387
+ };
388
+ return JSON.stringify(value, replacer, space);
389
+ };
1437
390
 
1438
- export { $emptyKey, $era, $extrinsic, $field, $hash, $metadataV14, $null, $partialEmptyKey, $partialMultiKey, $partialSingleKey, $primitiveKind, $storageKey, $ty, $tyDef, $tyId, Blake2Hasher, DecodeNonTransparentKeyError, Era, Hasher, IdentityHasher, SignerError, TwoxHasher, addDependentTypes, blake2_128, blake2_128Concat, blake2_256, blake2_512, blake2_64, decodeMetadata, filterMetadataPalletsAndItems, getOrInit, identity, normalizeDocs, normalizeIdent, normalizePackageName, normalizeTypeName, normalizeVariableName, ss58, stringifyKey, stringifyPropertyAccess, transformMetadata as transformMetadataV14, transformTys, twox128, twox256, twox64Concat, watCryptoWaitReady };
391
+ export { compactMetadata, decodeMetadata, decodeScale, encodeMetadata, encodeStateKey, getMetadataVersion, magicNumber, papiParse, papiStringify };