@talismn/scale 0.0.0-pr997-20231115151657 → 0.0.2

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.
@@ -4,16 +4,63 @@ import * as $ from '@talismn/subshape-fork';
4
4
  import { EncodeBuffer } from '@talismn/subshape-fork';
5
5
  import anylogger from 'anylogger';
6
6
 
7
+ const ignoreModuleMessages = {
8
+ "PORTABLEREGISTRY:": ["Unable to determine runtime Event type, cannot inspect frame_system::EventRecord", "Unable to determine runtime Call type, cannot inspect sp_runtime::generic::unchecked_extrinsic::UncheckedExtrinsic"]
9
+ };
10
+ function suppressPortableRegistryConsoleWarnings() {
11
+ /* eslint-disable-next-line no-console */
12
+ const originalWarn = console.warn;
13
+
14
+ /* eslint-disable-next-line no-console */
15
+ console.warn = (...data) => {
16
+ const [, dataModule, dataMessage] = data;
17
+ const ignoreMessages = typeof dataModule === "string" && ignoreModuleMessages[dataModule];
18
+ if (Array.isArray(ignoreMessages) && ignoreMessages.includes(dataMessage)) return;
19
+ if (data[0] === "Unable to map Bytes to a lookup index") return;
20
+ if (data[0] === "Unable to map [u8; 32] to a lookup index") return;
21
+ if (data[0] === "Unable to map u16 to a lookup index") return;
22
+ if (data[0] === "Unable to map u32 to a lookup index") return;
23
+ if (data[0] === "Unable to map u64 to a lookup index") return;
24
+ if (data[0] === "Unable to map u128 to a lookup index") return;
25
+ originalWarn(...data);
26
+ };
27
+ }
28
+
7
29
  //
8
30
  // The simd variants of these hash fns are faster, but some devices don't support them.
9
31
  //
10
32
  // This file re-exports the faster fns from `./simd` for devices which support them,
11
33
  // and falls back to `./nosimd` re-exports for devices which do not.
12
34
  //
35
+ /**
36
+ * Show a useful error message when someone attempts to use one of the classes
37
+ * from this lib without waiting for them to be initialized.
38
+ */
39
+ class UninitializedHasher {
40
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
41
+ constructor(...args) {
42
+ throw new Error(`This class cannot be used before @talismn/scale has initialized it. Please await 'watCryptoWaitReady' before attempting to construct this class.`);
43
+ }
44
+
45
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
46
+ update(input) {
47
+ throw new Error(`This class cannot be used before @talismn/scale has initialized it. Please await 'watCryptoWaitReady' before attempting to construct this class.`);
48
+ }
49
+ digest() {
50
+ throw new Error(`This class cannot be used before @talismn/scale has initialized it. Please await 'watCryptoWaitReady' before attempting to construct this class.`);
51
+ }
52
+ digestInto(digest) {
53
+ digest.set(this.digest());
54
+ }
55
+ dispose() {
56
+ throw new Error(`This class cannot be used before @talismn/scale has initialized it. Please await 'watCryptoWaitReady' before attempting to construct this class.`);
57
+ }
58
+ }
59
+
13
60
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
- let Blake2b;
61
+ let Blake2b = UninitializedHasher;
15
62
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
- let Xxhash;
63
+ let Xxhash = UninitializedHasher;
17
64
  let readyPromise = null;
18
65
  const watCryptoWaitReady = async () => {
19
66
  // if this is the second/third/etc time we've called watCryptoWaitReady,
@@ -37,7 +84,7 @@ const watCryptoWaitReady = async () => {
37
84
  Xxhash = imported.Xxhash;
38
85
  } else {
39
86
  // system does not support wasm simd
40
- const imported = await import('./nosimd-20b5b0ca.esm.js');
87
+ const imported = await import('./nosimd-8c31fb2d.esm.js');
41
88
  Blake2b = imported.Blake2b;
42
89
  Xxhash = imported.Xxhash;
43
90
  }
@@ -422,6 +469,7 @@ const blake2_128Concat = new Blake2Hasher(128, true);
422
469
  const blake2_256 = new Blake2Hasher(256, false);
423
470
  const blake2_512 = new Blake2Hasher(512, false);
424
471
  const identity = new IdentityHasher();
472
+ const twox64 = new TwoxHasher(64, false);
425
473
  const twox128 = new TwoxHasher(128, false);
426
474
  const twox256 = new TwoxHasher(256, false);
427
475
  const twox64Concat = new TwoxHasher(64, true);
@@ -1135,9 +1183,12 @@ function transformMetadata(metadata) {
1135
1183
  }
1136
1184
  };
1137
1185
  function getExtrinsicParameter(key) {
1186
+ if (!metadata.extrinsic.ty) return $.never;
1138
1187
  const extrinsicTy = metadata.tys[metadata.extrinsic.ty];
1139
1188
  if (!extrinsicTy) return $.never;
1140
- return ids[extrinsicTy.params.find(x => x.name.toLowerCase() === key).ty];
1189
+ const id = extrinsicTy.params.find(x => x.name.toLowerCase() === key)?.ty;
1190
+ if (id === undefined) return $.never;
1191
+ return ids[id];
1141
1192
  }
1142
1193
  function getExtensionsCodec(key) {
1143
1194
  return $.object(...metadata.extrinsic.signedExtensions.flatMap(ext => {
@@ -1283,7 +1334,7 @@ class SignerError extends Error {
1283
1334
 
1284
1335
  var packageJson = {
1285
1336
  name: "@talismn/scale",
1286
- version: "0.0.0-pr997-20231115151657",
1337
+ version: "0.0.2",
1287
1338
  author: "Talisman",
1288
1339
  homepage: "https://talisman.xyz",
1289
1340
  license: "GPL-3.0-or-later",
@@ -1309,14 +1360,14 @@ var packageJson = {
1309
1360
  clean: "rm -rf dist && rm -rf .turbo rm -rf node_modules"
1310
1361
  },
1311
1362
  dependencies: {
1312
- "@talismn/subshape-fork": "^0.0.1",
1363
+ "@talismn/subshape-fork": "^0.0.2",
1313
1364
  "@talismn/util": "workspace:*",
1314
1365
  anylogger: "^1.0.11",
1315
- "wasm-feature-detect": "^1.6.0",
1366
+ "wasm-feature-detect": "^1.6.1",
1316
1367
  "wat-the-crypto": "^0.0.3"
1317
1368
  },
1318
1369
  devDependencies: {
1319
- "@polkadot/util-crypto": "^11.1.1",
1370
+ "@polkadot/util-crypto": "^12.3.2",
1320
1371
  "@talismn/eslint-config": "workspace:*",
1321
1372
  "@talismn/tsconfig": "workspace:*",
1322
1373
  "@types/jest": "^27.5.1",
@@ -1326,7 +1377,7 @@ var packageJson = {
1326
1377
  typescript: "^5.2.2"
1327
1378
  },
1328
1379
  peerDependencies: {
1329
- "@polkadot/util-crypto": "^11.x"
1380
+ "@polkadot/util-crypto": "12.x"
1330
1381
  },
1331
1382
  eslintConfig: {
1332
1383
  root: true,
@@ -1338,6 +1389,14 @@ var packageJson = {
1338
1389
 
1339
1390
  var log = anylogger(packageJson.name);
1340
1391
 
1392
+ const getMetadataVersion = metadataRpc => {
1393
+ // https://docs.substrate.io/build/application-development/#metadata-system
1394
+ const magicNumber = 1635018093;
1395
+ const {
1396
+ version
1397
+ } = $.object($.field("magicNumber", $.constant(magicNumber, $.u32)), $.field("version", $.u8)).decode($.decodeHex(metadataRpc));
1398
+ return version;
1399
+ };
1341
1400
  const filterMetadataPalletsAndItems = (metadata, palletsAndItems, extraKeepTypes) => {
1342
1401
  // remove pallets we don't care about
1343
1402
  metadata.pallets = metadata.pallets.filter(pallet =>
@@ -1353,7 +1412,7 @@ const filterMetadataPalletsAndItems = (metadata, palletsAndItems, extraKeepTypes
1353
1412
  }) => {
1354
1413
  const pallet = metadata.pallets.find(palletFilter);
1355
1414
  if (!pallet || !pallet.storage) {
1356
- log.warn("Failed to find pallet", palletFilter);
1415
+ log.debug("Failed to find pallet", palletFilter);
1357
1416
  return [];
1358
1417
  }
1359
1418
 
@@ -1435,4 +1494,207 @@ addedTypes = new Set()) => {
1435
1494
  }
1436
1495
  };
1437
1496
 
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 };
1497
+ /**
1498
+ * This module is largely copied from https://github.com/0xKheops/substrate-metadata-explorer/blob/4b5a991e5ced45cad3b8675ff9104b8366d20429/packages/sme-codegen/src/types/getConstantVariableName.ts
1499
+ *
1500
+ * The primary difference between this module and `sme-codegen` is in the output.
1501
+ *
1502
+ * The `sme-codegen` module exports typescript code as a string, which can then be interpretted in order to construct subshape objects.
1503
+ *
1504
+ * Whereas this module directly exports the subshape objects described by that code.
1505
+ */
1506
+
1507
+ /** Returns a unique name (relative to all of the types in `metadata`) to identify this type. */
1508
+ const getTypeName = (metadata, type) => {
1509
+ const uniqueName = getUniqueTypeName(metadata, type);
1510
+ return `${uniqueName.charAt(0).toUpperCase()}${uniqueName.substring(1)}`;
1511
+ };
1512
+
1513
+ /**
1514
+ * Tries each of `getSimpleTypeName`, `getSmartTypeName`, `getFullTypeName` in order and
1515
+ * returns the first name which is unique in the collection of types in `metadata`.
1516
+ */
1517
+ const getUniqueTypeName = (metadata, type) => {
1518
+ const rawTypeName = getRawTypeName(type);
1519
+ if (type.path.length < 1) return rawTypeName;
1520
+
1521
+ // use simpleName if it is unique
1522
+ const simpleName = getSimpleTypeName(type);
1523
+ if (!metadata.tys.some(t => t.id !== type.id && getSimpleTypeName(t) === simpleName)) return simpleName;
1524
+
1525
+ // use smartName if it is unique
1526
+ const smartName = getSmartTypeName(type);
1527
+ if (!metadata.tys.some(t => t.id !== type.id && getSmartTypeName(t) === smartName)) return smartName;
1528
+
1529
+ // use fullName if it is unique
1530
+ const fullName = getFullTypeName(type);
1531
+ if (!metadata.tys.some(t => t.id !== type.id && getFullTypeName(t) === fullName))
1532
+ // return if fullName is unique
1533
+ return fullName;
1534
+
1535
+ // use fullName + type number
1536
+ return `${fullName}${type.id}`;
1537
+ };
1538
+
1539
+ /** Gets "Type" + type number */
1540
+ const getRawTypeName = type => `Type${type.id}`;
1541
+
1542
+ /** Gets the last element of `type.path` */
1543
+ const getSimpleTypeName = type => type.path.slice(-1)[0];
1544
+
1545
+ /** Gets the first two elements, and the last element, of `type.path` and joins them together with `::` */
1546
+ const getSmartTypeName = type => type.path.length > 3 ? normalizeTypeName([...type.path.slice(0, 2), ...type.path.slice(-1)].join("::")) : getFullTypeName(type);
1547
+
1548
+ /** Gets all elements of `type.path` and joins them together with `::` */
1549
+ const getFullTypeName = type => normalizeTypeName(type.path.join("::"));
1550
+
1551
+ /**
1552
+ * This module is largely copied from https://github.com/0xKheops/substrate-metadata-explorer/blob/4b5a991e5ced45cad3b8675ff9104b8366d20429/packages/sme-codegen/src/types/getShape.ts
1553
+ *
1554
+ * The primary difference between this module and `sme-codegen` is in the output.
1555
+ *
1556
+ * The `sme-codegen` module exports typescript code as a string, which can then be interpretted in order to construct subshape objects.
1557
+ *
1558
+ * Whereas this module directly exports the subshape objects described by that code.
1559
+ */
1560
+ const getShape = (metadata, typeId, gotShapes = new Map()) => {
1561
+ const type = metadata.tys.find(type => type.id === typeId);
1562
+ if (!type) throw new Error(`Type not found (${typeId})`);
1563
+
1564
+ // Short circuit if we've already encountered this shape
1565
+ const typeName = getTypeName(metadata, type);
1566
+ if (gotShapes.has(typeName)) return gotShapes.get(typeName);
1567
+
1568
+ // TODO: Use `$.deferred(() => Type)` for self-referential types
1569
+
1570
+ // Get shape, add to gotShapes list, return shape
1571
+ const shape = getTypeShape(metadata, type, gotShapes);
1572
+ gotShapes.set(typeName, shape);
1573
+ return shape;
1574
+ };
1575
+ const getTypeShape = (metadata, type, gotShapes) => {
1576
+ const tyType = type.type;
1577
+ switch (tyType) {
1578
+ case "Primitive":
1579
+ return getPrimitiveShape(type);
1580
+ case "SizedArray":
1581
+ return getSizedArrayShape(metadata, type, gotShapes);
1582
+ case "Compact":
1583
+ return getCompactShape(metadata, type, gotShapes);
1584
+ case "Sequence":
1585
+ return getSequenceShape(metadata, type, gotShapes);
1586
+ case "Struct":
1587
+ return getStructShape(metadata, type, gotShapes);
1588
+ case "Tuple":
1589
+ return getTupleShape(metadata, type, gotShapes);
1590
+ case "Union":
1591
+ return getUnionShape(metadata, type, gotShapes);
1592
+ case "BitSequence":
1593
+ return $.bitSequence;
1594
+ default:
1595
+ {
1596
+ // force compilation error if any types don't have a case
1597
+ const exhaustiveCheck = tyType;
1598
+ throw new Error(`Unsupported type shape ${exhaustiveCheck}`);
1599
+ }
1600
+ }
1601
+ };
1602
+ const tyIsU8 = type => type?.type === "Primitive" && type.kind === "u8";
1603
+ const getPrimitiveShape = primitive => {
1604
+ // TODO: Test that `char` and `$.u8` are equivalent (`$.char` does not exist)
1605
+ if (primitive.kind === "char") return $.u8;
1606
+ return $[primitive.kind];
1607
+ };
1608
+ const getSizedArrayShape = (metadata, sizedArray, gotShapes) => {
1609
+ // Get the type definition for the items of this array from the metadata
1610
+ const typeParam = metadata.tys.find(({
1611
+ id
1612
+ }) => id === sizedArray.typeParam);
1613
+ if (!typeParam) {
1614
+ const typeName = getTypeName(metadata, sizedArray);
1615
+ throw new Error(`Could not find typeParam ${sizedArray.typeParam} for sizedArray ${typeName}`);
1616
+ }
1617
+
1618
+ // Shortcut for uint8 arrays
1619
+ if (tyIsU8(typeParam)) return $.sizedUint8Array(sizedArray.len);
1620
+
1621
+ // Get the subshape object for the items of this array
1622
+ const typeParamShape = getShape(metadata, typeParam.id, gotShapes);
1623
+
1624
+ // Return a subshape sizedArray
1625
+ return $.sizedArray(typeParamShape, sizedArray.len);
1626
+ };
1627
+ const getCompactShape = (metadata, compact, gotShapes) => {
1628
+ // Get the type definition for the item of this compact from the metadata
1629
+ const typeParam = metadata.tys.find(({
1630
+ id
1631
+ }) => id === compact.typeParam);
1632
+ if (!typeParam) {
1633
+ const typeName = getTypeName(metadata, compact);
1634
+ throw new Error(`Could not find typeParam ${compact.typeParam} for compact ${typeName}`);
1635
+ }
1636
+
1637
+ // Get the subshape object for the item of this compact
1638
+ const typeParamShape = getShape(metadata, typeParam.id, gotShapes);
1639
+
1640
+ // Return a subshape compact
1641
+ return $.compact(typeParamShape);
1642
+ };
1643
+ const getSequenceShape = (metadata, sequence, gotShapes) => {
1644
+ // Get the type definition for the items of this sequence from the metadata
1645
+ const typeParam = metadata.tys.find(({
1646
+ id
1647
+ }) => id === sequence.typeParam);
1648
+ if (!typeParam) {
1649
+ const typeName = getTypeName(metadata, sequence);
1650
+ throw new Error(`Could not find typeParam ${sequence.typeParam} for sequence ${typeName}`);
1651
+ }
1652
+
1653
+ // Shortcut for uint8 sequences
1654
+ if (tyIsU8(typeParam)) return $.uint8Array;
1655
+
1656
+ // Get the subshape object for the items of this sequence
1657
+ const typeParamShape = getShape(metadata, typeParam.id, gotShapes);
1658
+
1659
+ // Return a subshape sequence
1660
+ return $.array(typeParamShape);
1661
+ };
1662
+ const getStructShape = (metadata, struct, gotShapes) => {
1663
+ // If there's only one field and it has no name, don't wrap it in $.object
1664
+ if (struct.fields.length === 1 && !struct.fields[0].name) return getShape(metadata, struct.fields[0].ty, gotShapes);
1665
+
1666
+ // Check that all fields have a name
1667
+ if (!struct.fields.every(field => field.name)) {
1668
+ const typeName = getTypeName(metadata, struct);
1669
+ throw new Error(`Could not build subshape object for struct ${struct.id} (${typeName})): Not all fields have a name`);
1670
+ }
1671
+
1672
+ // Get the type definition for the fields of this struct from the metadata
1673
+ const fieldsShape = struct.fields.map(field => $.field(normalizeIdent(field.name), getShape(metadata, field.ty, gotShapes)));
1674
+ return $.object(...fieldsShape);
1675
+ };
1676
+ const getTupleShape = (metadata, tuple, gotShapes) =>
1677
+ // Get the type definition for the fields of this tuple from the metadata and wrap them in `$.tuple`
1678
+ $.tuple(...tuple.fields.map(type => getShape(metadata, type, gotShapes)));
1679
+ const getUnionShape = (metadata, union, gotShapes) => {
1680
+ if (union.members.every(member => !member.fields.length)) return $.literalUnion(Object.fromEntries(union.members.map(member => [member.index, normalizeIdent(member.name)])));
1681
+
1682
+ // TODO: Check if invalid
1683
+ if (union.members.length === 2 && union.path[union.path.length - 1] === "Option" && union.members[0]?.name === "None" && union.members[1]?.name === "Some") return $.option(getShape(metadata, union.members[1].fields[0].ty, gotShapes));
1684
+ return $.taggedUnion("type", Object.fromEntries(union.members.map(member => {
1685
+ const args = [];
1686
+
1687
+ // invalid if only some fields (but not all of them) have a name
1688
+ if (member.fields.some(field => field.name) && !member.fields.every(field => field.name)) {
1689
+ const typeName = getTypeName(metadata, union);
1690
+ throw new Error(`Could not build subshape object for union ${union.id} (${typeName}): Not all fields have a name`);
1691
+ }
1692
+ if (member.fields.every(field => field.name)) for (const field of member.fields) args.push($.field(normalizeIdent(field.name), getShape(metadata, field.ty, gotShapes)));else if (member.fields.length > 1) args.push($.field("value", $.tuple(...member.fields.map(field => getShape(metadata, field.ty, gotShapes)))));else args.push($.field("value", getShape(metadata, member.fields[0].ty, gotShapes)));
1693
+ return [member.index, $.variant(normalizeIdent(member.name), ...args)];
1694
+ })));
1695
+ };
1696
+
1697
+ // TODO: Get the DX of this lib as close as possible to the DX of `const jsonResult = '{"someKey":"someValue"}'; JSON.decode(jsonResult)`
1698
+ suppressPortableRegistryConsoleWarnings();
1699
+
1700
+ 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, getFullTypeName, getMetadataVersion, getOrInit, getRawTypeName, getShape, getSimpleTypeName, getSmartTypeName, getTypeName, getTypeShape, getUniqueTypeName, identity, normalizeDocs, normalizeIdent, normalizePackageName, normalizeTypeName, normalizeVariableName, ss58, stringifyKey, stringifyPropertyAccess, transformMetadata as transformMetadataV14, transformTys, twox128, twox256, twox64, twox64Concat, watCryptoWaitReady };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@talismn/scale",
3
- "version": "0.0.0-pr997-20231115151657",
3
+ "version": "0.0.2",
4
4
  "author": "Talisman",
5
5
  "homepage": "https://talisman.xyz",
6
6
  "license": "GPL-3.0-or-later",
@@ -26,15 +26,15 @@
26
26
  "clean": "rm -rf dist && rm -rf .turbo rm -rf node_modules"
27
27
  },
28
28
  "dependencies": {
29
- "@talismn/subshape-fork": "^0.0.1",
30
- "@talismn/util": "0.0.0-pr997-20231115151657",
29
+ "@talismn/subshape-fork": "^0.0.2",
30
+ "@talismn/util": "0.2.1",
31
31
  "anylogger": "^1.0.11",
32
- "wasm-feature-detect": "^1.6.0",
32
+ "wasm-feature-detect": "^1.6.1",
33
33
  "wat-the-crypto": "^0.0.3"
34
34
  },
35
35
  "devDependencies": {
36
- "@polkadot/util-crypto": "^11.1.1",
37
- "@talismn/eslint-config": "0.0.0-pr997-20231115151657",
36
+ "@polkadot/util-crypto": "^12.3.2",
37
+ "@talismn/eslint-config": "0.0.3",
38
38
  "@talismn/tsconfig": "0.0.2",
39
39
  "@types/jest": "^27.5.1",
40
40
  "eslint": "^8.52.0",
@@ -43,7 +43,7 @@
43
43
  "typescript": "^5.2.2"
44
44
  },
45
45
  "peerDependencies": {
46
- "@polkadot/util-crypto": "^11.x"
46
+ "@polkadot/util-crypto": "12.x"
47
47
  },
48
48
  "eslintConfig": {
49
49
  "root": true,