@subwallet/extension-base 1.3.12-0 → 1.3.13-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 (29) hide show
  1. package/background/KoniTypes.d.ts +10 -0
  2. package/cjs/koni/background/handlers/Extension.js +8 -56
  3. package/cjs/koni/background/utils.js +72 -0
  4. package/cjs/packageInfo.js +1 -1
  5. package/cjs/services/chain-service/index.js +20 -12
  6. package/cjs/services/migration-service/scripts/index.js +2 -2
  7. package/cjs/services/storage-service/DatabaseService.js +1 -0
  8. package/cjs/services/storage-service/databases/index.js +3 -0
  9. package/cjs/services/storage-service/db-stores/MetadataV15.js +26 -0
  10. package/cjs/services/storage-service/db-stores/index.js +7 -0
  11. package/cjs/utils/metadata.js +70 -23
  12. package/koni/background/handlers/Extension.js +10 -58
  13. package/koni/background/utils.d.ts +13 -0
  14. package/koni/background/utils.js +63 -0
  15. package/package.json +15 -5
  16. package/packageInfo.js +1 -1
  17. package/services/chain-service/index.d.ts +5 -3
  18. package/services/chain-service/index.js +20 -12
  19. package/services/migration-service/scripts/index.js +2 -2
  20. package/services/storage-service/DatabaseService.d.ts +2 -1
  21. package/services/storage-service/DatabaseService.js +2 -1
  22. package/services/storage-service/databases/index.d.ts +4 -1
  23. package/services/storage-service/databases/index.js +3 -0
  24. package/services/storage-service/db-stores/MetadataV15.d.ts +8 -0
  25. package/services/storage-service/db-stores/MetadataV15.js +18 -0
  26. package/services/storage-service/db-stores/index.d.ts +1 -0
  27. package/services/storage-service/db-stores/index.js +1 -0
  28. package/utils/metadata.d.ts +10 -0
  29. package/utils/metadata.js +67 -23
@@ -211,6 +211,16 @@ export interface MetadataItem {
211
211
  types: Record<string, Record<string, string> | string>;
212
212
  userExtensions?: ExtDef;
213
213
  hexV15?: HexString;
214
+ tokenInfo?: {
215
+ ss58Format: number;
216
+ tokenDecimals: number;
217
+ tokenSymbol: string;
218
+ };
219
+ }
220
+ export interface MetadataV15Item {
221
+ genesisHash: string;
222
+ specVersion: string;
223
+ hexV15?: HexString;
214
224
  }
215
225
  export interface CrowdloanItem {
216
226
  state: APIItemState;
@@ -47,7 +47,6 @@ var _stores = require("@subwallet/extension-base/stores");
47
47
  var _types3 = require("@subwallet/extension-base/types");
48
48
  var _utils5 = require("@subwallet/extension-base/utils");
49
49
  var _parseTransaction2 = require("@subwallet/extension-base/utils/eth/parseTransaction");
50
- var _extensionChains = require("@subwallet/extension-chains");
51
50
  var _keyring = require("@subwallet/keyring");
52
51
  var _types4 = require("@subwallet/keyring/types");
53
52
  var _uiKeyring = require("@subwallet/ui-keyring");
@@ -58,6 +57,7 @@ var _rxjs = require("rxjs");
58
57
  var _types5 = require("@polkadot/types");
59
58
  var _util = require("@polkadot/util");
60
59
  var _utilCrypto = require("@polkadot/util-crypto");
60
+ var _utils7 = require("../utils");
61
61
  // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
62
62
  // SPDX-License-Identifier: Apache-2.0
63
63
 
@@ -2320,7 +2320,7 @@ class KoniExtension {
2320
2320
  }
2321
2321
  }
2322
2322
 
2323
- /// Signing substrate request
2323
+ // Signing substrate request
2324
2324
  async signingApprovePasswordV2(_ref43) {
2325
2325
  let {
2326
2326
  id
@@ -2336,7 +2336,7 @@ class KoniExtension {
2336
2336
 
2337
2337
  // unlike queued.account.address the following
2338
2338
  // address is encoded with the default prefix
2339
- // which what is used for password caching mapping
2339
+ // which is used for password caching mapping
2340
2340
  const {
2341
2341
  address
2342
2342
  } = pair;
@@ -2350,63 +2350,15 @@ class KoniExtension {
2350
2350
  const {
2351
2351
  payload
2352
2352
  } = request;
2353
- let registry;
2353
+ let registry = new _types5.TypeRegistry();
2354
2354
  if (isJsonPayload(payload)) {
2355
2355
  const [, chainInfo] = this.#koniState.findNetworkKeyByGenesisHash(payload.genesisHash);
2356
- let metadata;
2357
-
2358
- /**
2359
- * Get the metadata for the genesisHash
2360
- * @todo: need to handle case metadata store in db
2361
- */
2362
- metadata = this.#koniState.knownMetadata.find(meta => meta.genesisHash === payload.genesisHash);
2363
- if (metadata) {
2364
- // we have metadata, expand it and extract the info/registry
2365
- const expanded = (0, _extensionChains.metadataExpand)(metadata, false);
2366
- registry = expanded.registry;
2367
- registry.setSignedExtensions(payload.signedExtensions, expanded.definition.userExtensions);
2356
+ const allRegistry = [(0, _utils7.setupApiRegistry)(chainInfo, this.#koniState), (0, _utils7.setupDatabaseRegistry)(await this.#koniState.chainService.getMetadataByHash(payload.genesisHash), chainInfo, payload), (0, _utils7.setupDappRegistry)(this.#koniState.knownMetadata.find(meta => meta.genesisHash === payload.genesisHash), payload)].filter(item => item !== null && item.registry !== undefined);
2357
+ if (allRegistry.length === 0) {
2358
+ registry.setSignedExtensions(payload.signedExtensions);
2368
2359
  } else {
2369
- metadata = await this.#koniState.chainService.getMetadataByHash(payload.genesisHash);
2370
- if (metadata) {
2371
- var _chainInfo$substrateI, _chainInfo$substrateI2, _chainInfo$substrateI3, _chainInfo$substrateI4;
2372
- registry = new _types5.TypeRegistry();
2373
- const _metadata = new _types5.Metadata(registry, metadata.hexValue);
2374
- registry.register(metadata.types);
2375
- registry.setChainProperties(registry.createType('ChainProperties', {
2376
- ss58Format: (_chainInfo$substrateI = chainInfo === null || chainInfo === void 0 ? void 0 : (_chainInfo$substrateI2 = chainInfo.substrateInfo) === null || _chainInfo$substrateI2 === void 0 ? void 0 : _chainInfo$substrateI2.addressPrefix) !== null && _chainInfo$substrateI !== void 0 ? _chainInfo$substrateI : 42,
2377
- tokenDecimals: chainInfo === null || chainInfo === void 0 ? void 0 : (_chainInfo$substrateI3 = chainInfo.substrateInfo) === null || _chainInfo$substrateI3 === void 0 ? void 0 : _chainInfo$substrateI3.decimals,
2378
- tokenSymbol: chainInfo === null || chainInfo === void 0 ? void 0 : (_chainInfo$substrateI4 = chainInfo.substrateInfo) === null || _chainInfo$substrateI4 === void 0 ? void 0 : _chainInfo$substrateI4.symbol
2379
- }));
2380
- registry.setMetadata(_metadata, payload.signedExtensions, metadata.userExtensions);
2381
- } else {
2382
- // we have no metadata, create a new registry
2383
- registry = new _types5.TypeRegistry();
2384
- registry.setSignedExtensions(payload.signedExtensions);
2385
- }
2360
+ registry = (0, _utils7.getSuitableRegistry)(allRegistry, payload);
2386
2361
  }
2387
- if (!metadata) {
2388
- /*
2389
- * Some networks must have metadata to signing,
2390
- * so if the chain not active (cannot use metadata from api), it must be rejected
2391
- * */
2392
- if (chainInfo && (_constants2._API_OPTIONS_CHAIN_GROUP.avail.includes(chainInfo.slug) || _constants2._API_OPTIONS_CHAIN_GROUP.goldberg.includes(chainInfo.slug)) // The special case for chains that need metadata to signing
2393
- ) {
2394
- // For case the chain does not have any provider
2395
- if (!Object.keys(chainInfo.providers).length) {
2396
- reject(new Error('{{chain}} network does not have any provider to connect, please update metadata from dApp'.replaceAll('{{chain}}', chainInfo.name)));
2397
- return false;
2398
- }
2399
- const isChainActive = this.#koniState.getChainStateByKey(chainInfo.slug).active;
2400
- if (!isChainActive) {
2401
- reject(new Error('Please activate {{chain}} network before signing'.replaceAll('{{chain}}', chainInfo.name)));
2402
- return false;
2403
- }
2404
- registry = this.#koniState.getSubstrateApi(chainInfo.slug).api.registry;
2405
- }
2406
- }
2407
- } else {
2408
- // for non-payload, just create a registry to use
2409
- registry = new _types5.TypeRegistry();
2410
2362
  }
2411
2363
  const result = request.sign(registry, pair);
2412
2364
  resolve({
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getSuitableRegistry = getSuitableRegistry;
7
+ exports.setupApiRegistry = setupApiRegistry;
8
+ exports.setupDappRegistry = setupDappRegistry;
9
+ exports.setupDatabaseRegistry = setupDatabaseRegistry;
10
+ var _bundle = require("@subwallet/extension-chains/bundle");
11
+ var _types = require("@polkadot/types");
12
+ // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
13
+ // SPDX-License-Identifier: Apache-2.0
14
+
15
+ function getSuitableRegistry(registries, payload) {
16
+ const payloadSpecVersion = parseInt(payload.specVersion);
17
+ const sortedRegistries = registries.filter(registrySource => registrySource.registry !== undefined).map(registrySource => {
18
+ const specVersion = Number(registrySource.specVersion);
19
+ const distance = Math.abs(specVersion - payloadSpecVersion);
20
+ const isHigher = specVersion >= payloadSpecVersion;
21
+ return {
22
+ registry: registrySource.registry,
23
+ specVersion,
24
+ distance,
25
+ isHigher
26
+ };
27
+ }).sort((a, b) => {
28
+ if (a.distance !== b.distance) {
29
+ return a.distance - b.distance;
30
+ }
31
+ return b.specVersion - a.specVersion;
32
+ });
33
+ return sortedRegistries[0].registry;
34
+ }
35
+ function setupApiRegistry(chainInfo, koniState) {
36
+ if (!chainInfo) {
37
+ return null;
38
+ }
39
+ const api = koniState.getSubstrateApi(chainInfo.slug).api;
40
+ const apiSpecVersion = api === null || api === void 0 ? void 0 : api.runtimeVersion.specVersion.toString();
41
+ const registry = api === null || api === void 0 ? void 0 : api.registry;
42
+ return {
43
+ registry,
44
+ specVersion: apiSpecVersion
45
+ };
46
+ }
47
+ function setupDatabaseRegistry(metadata, chainInfo, payload) {
48
+ if (!metadata || !metadata.genesisHash || !chainInfo) {
49
+ return null;
50
+ }
51
+ const registry = new _types.TypeRegistry();
52
+ const _metadata = new _types.Metadata(registry, metadata.hexValue);
53
+ registry.register(metadata.types);
54
+ registry.setChainProperties(registry.createType('ChainProperties', metadata.tokenInfo));
55
+ registry.setMetadata(_metadata, payload.signedExtensions, metadata.userExtensions);
56
+ return {
57
+ registry,
58
+ specVersion: metadata.specVersion
59
+ };
60
+ }
61
+ function setupDappRegistry(metadata, payload) {
62
+ if (!metadata || !metadata.genesisHash) {
63
+ return null;
64
+ }
65
+ const expanded = (0, _bundle.metadataExpand)(metadata, false);
66
+ const registry = expanded.registry;
67
+ registry.setSignedExtensions(payload.signedExtensions, expanded.definition.userExtensions);
68
+ return {
69
+ registry,
70
+ specVersion: metadata.specVersion
71
+ };
72
+ }
@@ -13,6 +13,6 @@ const packageInfo = {
13
13
  name: '@subwallet/extension-base',
14
14
  path: typeof __dirname === 'string' ? __dirname : 'auto',
15
15
  type: 'cjs',
16
- version: '1.3.12-0'
16
+ version: '1.3.13-0'
17
17
  };
18
18
  exports.packageInfo = packageInfo;
@@ -1749,27 +1749,34 @@ class ChainService {
1749
1749
  upsertMetadata(chain, metadata) {
1750
1750
  return this.dbService.stores.metadata.upsertMetadata(chain, metadata);
1751
1751
  }
1752
+ getMetadataV15(chain) {
1753
+ return this.dbService.stores.metadataV15.getMetadata(chain);
1754
+ }
1755
+ upsertMetadataV15(chain, metadata) {
1756
+ return this.dbService.stores.metadataV15.upsertMetadata(chain, metadata);
1757
+ }
1752
1758
  getMetadataByHash(hash) {
1753
1759
  return this.dbService.stores.metadata.getMetadataByGenesisHash(hash);
1754
1760
  }
1755
- getExtraInfo(chain) {
1756
- var _chainInfo$substrateI2, _chainInfo$substrateI3, _chainInfo$substrateI4, _chainInfo$substrateI5, _chainInfo$substrateI6, _chainInfo$substrateI7;
1757
- const chainInfo = this.getChainInfoByKey(chain);
1761
+ getExtraInfo(metadata) {
1762
+ var _tokenInfo$tokenDecim, _tokenInfo$tokenSymbo, _tokenInfo$ss58Format;
1763
+ const tokenInfo = metadata.tokenInfo;
1758
1764
  return {
1759
- decimals: (_chainInfo$substrateI2 = (_chainInfo$substrateI3 = chainInfo.substrateInfo) === null || _chainInfo$substrateI3 === void 0 ? void 0 : _chainInfo$substrateI3.decimals) !== null && _chainInfo$substrateI2 !== void 0 ? _chainInfo$substrateI2 : 0,
1760
- tokenSymbol: (_chainInfo$substrateI4 = (_chainInfo$substrateI5 = chainInfo.substrateInfo) === null || _chainInfo$substrateI5 === void 0 ? void 0 : _chainInfo$substrateI5.symbol) !== null && _chainInfo$substrateI4 !== void 0 ? _chainInfo$substrateI4 : 'Unit',
1761
- base58Prefix: (_chainInfo$substrateI6 = (_chainInfo$substrateI7 = chainInfo.substrateInfo) === null || _chainInfo$substrateI7 === void 0 ? void 0 : _chainInfo$substrateI7.addressPrefix) !== null && _chainInfo$substrateI6 !== void 0 ? _chainInfo$substrateI6 : 42
1765
+ decimals: (_tokenInfo$tokenDecim = tokenInfo === null || tokenInfo === void 0 ? void 0 : tokenInfo.tokenDecimals) !== null && _tokenInfo$tokenDecim !== void 0 ? _tokenInfo$tokenDecim : 0,
1766
+ tokenSymbol: (_tokenInfo$tokenSymbo = tokenInfo === null || tokenInfo === void 0 ? void 0 : tokenInfo.tokenSymbol) !== null && _tokenInfo$tokenSymbo !== void 0 ? _tokenInfo$tokenSymbo : 'Unit',
1767
+ base58Prefix: (_tokenInfo$ss58Format = tokenInfo === null || tokenInfo === void 0 ? void 0 : tokenInfo.ss58Format) !== null && _tokenInfo$ss58Format !== void 0 ? _tokenInfo$ss58Format : 42
1762
1768
  };
1763
1769
  }
1764
1770
  async calculateMetadataHash(chain) {
1765
1771
  const metadata = await this.getMetadata(chain);
1766
- if (!metadata || !metadata.hexV15) {
1772
+ const metadataV15 = await this.getMetadataV15(chain);
1773
+ if (!metadata || !metadataV15 || !metadataV15.hexV15) {
1767
1774
  return undefined;
1768
1775
  }
1769
- const extraInfo = this.getExtraInfo(chain);
1776
+ const extraInfo = this.getExtraInfo(metadata);
1770
1777
  const specVersion = parseInt(metadata.specVersion);
1771
1778
  const specName = metadata.specName;
1772
- const hexV15 = metadata.hexV15;
1779
+ const hexV15 = metadataV15.hexV15;
1773
1780
  return (0, _utils2.calculateMetadataHash)({
1774
1781
  ...extraInfo,
1775
1782
  specVersion,
@@ -1778,13 +1785,14 @@ class ChainService {
1778
1785
  }
1779
1786
  async shortenMetadata(chain, txBlob) {
1780
1787
  const metadata = await this.getMetadata(chain);
1781
- if (!metadata || !metadata.hexV15) {
1788
+ const metadataV15 = await this.getMetadataV15(chain);
1789
+ if (!metadata || !metadataV15 || !metadataV15.hexV15) {
1782
1790
  return undefined;
1783
1791
  }
1784
- const extraInfo = this.getExtraInfo(chain);
1792
+ const extraInfo = this.getExtraInfo(metadata);
1785
1793
  const specVersion = parseInt(metadata.specVersion);
1786
1794
  const specName = metadata.specName;
1787
- const hexV15 = metadata.hexV15;
1795
+ const hexV15 = metadataV15.hexV15;
1788
1796
  return (0, _utils2.getShortMetadata)(txBlob, {
1789
1797
  ...extraInfo,
1790
1798
  specVersion,
@@ -67,9 +67,9 @@ var _default = {
67
67
  '1.2.28-02': _MigrateTransactionHistoryBySymbol.default,
68
68
  '1.2.69-01': _MigrateRemoveGenesisHash.default,
69
69
  '1.2.13-01': _ReloadMetadata.default,
70
- '1.2.14-01': _ClearMetadataDatabase.default,
71
70
  '1.2.32-01': _MigratePairData.default,
72
- '1.3.6-01': _MigrateTransactionHistoryBridge.default
71
+ '1.3.6-01': _MigrateTransactionHistoryBridge.default,
72
+ '1.3.10-01': _ClearMetadataDatabase.default
73
73
  // [`${EVERYTIME}-1.1.42-02`]: MigrateTransactionHistoryBySymbol
74
74
  // [`${EVERYTIME}-1`]: AutoEnableChainsTokens
75
75
  };
@@ -45,6 +45,7 @@ class DatabaseService {
45
45
  transaction: new _dbStores.TransactionStore(this._db.transactions),
46
46
  migration: new _dbStores.MigrationStore(this._db.migrations),
47
47
  metadata: new _dbStores.MetadataStore(this._db.metadata),
48
+ metadataV15: new _dbStores.MetadataV15Store(this._db.metadataV15),
48
49
  chain: new _dbStores.ChainStore(this._db.chain),
49
50
  asset: new _dbStores.AssetStore(this._db.asset),
50
51
  // yield
@@ -53,6 +53,9 @@ class KoniDatabase extends _dexie.default {
53
53
  this.conditionalVersion(7, {
54
54
  inappNotification: 'id, address, proxyId, [proxyId+actionType], actionType'
55
55
  });
56
+ this.conditionalVersion(8, {
57
+ metadataV15: 'genesisHash, chain'
58
+ });
56
59
  }
57
60
  conditionalVersion(version, schema, upgrade) {
58
61
  if (this.schemaVersion != null && this.schemaVersion < version) {
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _BaseStoreWithChain = _interopRequireDefault(require("@subwallet/extension-base/services/storage-service/db-stores/BaseStoreWithChain"));
9
+ // Copyright 2019-2022 @subwallet/extension-base authors & contributors
10
+ // SPDX-License-Identifier: Apache-2.0
11
+
12
+ class MetadataV15Store extends _BaseStoreWithChain.default {
13
+ getMetadata(chain) {
14
+ return this.table.where('chain').equals(chain).first();
15
+ }
16
+ upsertMetadata(chain, metadata) {
17
+ return this.table.put(metadata, chain);
18
+ }
19
+ getMetadataByGenesisHash(genesisHash) {
20
+ return this.table.get(genesisHash);
21
+ }
22
+ updateMetadataByGenesisHash(genesisHash, metadata) {
23
+ return this.table.put(metadata, genesisHash);
24
+ }
25
+ }
26
+ exports.default = MetadataV15Store;
@@ -34,6 +34,12 @@ Object.defineProperty(exports, "MetadataStore", {
34
34
  return _Metadata.default;
35
35
  }
36
36
  });
37
+ Object.defineProperty(exports, "MetadataV15Store", {
38
+ enumerable: true,
39
+ get: function () {
40
+ return _MetadataV.default;
41
+ }
42
+ });
37
43
  Object.defineProperty(exports, "MigrationStore", {
38
44
  enumerable: true,
39
45
  get: function () {
@@ -79,5 +85,6 @@ var _Staking = _interopRequireDefault(require("./Staking"));
79
85
  var _Transaction = _interopRequireDefault(require("./Transaction"));
80
86
  var _Migration = _interopRequireDefault(require("./Migration"));
81
87
  var _Metadata = _interopRequireDefault(require("./Metadata"));
88
+ var _MetadataV = _interopRequireDefault(require("./MetadataV15"));
82
89
  var _Chain = _interopRequireDefault(require("./Chain"));
83
90
  var _Asset = _interopRequireDefault(require("./Asset"));
@@ -3,13 +3,24 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getShortMetadata = exports.calculateMetadataHash = exports.cacheMetadata = exports._isRuntimeUpdated = void 0;
6
+ exports.statics = exports.getShortMetadata = exports.calculateMetadataHash = exports.cacheMetadata = exports._isRuntimeUpdated = exports.DEFAULT_SS58 = exports.DEFAULT_DECIMALS = void 0;
7
+ var _types = require("@polkadot/types");
7
8
  var _typesKnown = require("@polkadot/types-known");
8
9
  var _util = require("@polkadot/util");
10
+ var _defaults = require("@polkadot/util-crypto/address/defaults");
9
11
  var _merkleizeMetadata2 = require("@polkadot-api/merkleize-metadata");
10
12
  // Copyright 2019-2022 @subwallet/extension-base
11
13
  // SPDX-License-Identifier: Apache-2.0
12
14
 
15
+ const statics = {
16
+ api: undefined,
17
+ registry: new _types.TypeRegistry()
18
+ };
19
+ exports.statics = statics;
20
+ const DEFAULT_DECIMALS = statics.registry.createType('u32', 12);
21
+ exports.DEFAULT_DECIMALS = DEFAULT_DECIMALS;
22
+ const DEFAULT_SS58 = statics.registry.createType('u32', _defaults.defaults.prefix);
23
+ exports.DEFAULT_SS58 = DEFAULT_SS58;
13
24
  const _isRuntimeUpdated = signedExtensions => {
14
25
  return signedExtensions ? signedExtensions.includes('CheckMetadataHash') : false;
15
26
  };
@@ -24,36 +35,72 @@ const getShortMetadata = (blob, extraInfo, metadata) => {
24
35
  return (0, _util.u8aToHex)(_merkleizeMetadata.getProofForExtrinsicPayload(blob));
25
36
  };
26
37
  exports.getShortMetadata = getShortMetadata;
27
- const cacheMetadata = (chain, substrateApi, chainService) => {
28
- // Update metadata to database with async methods
29
- substrateApi.api.isReady.then(async api => {
38
+ const updateMetadataV15 = async (chain, api, chainService) => {
39
+ try {
30
40
  const currentSpecVersion = api.runtimeVersion.specVersion.toString();
31
- const specName = api.runtimeVersion.specName.toString();
32
41
  const genesisHash = api.genesisHash.toHex();
33
- const metadata = await (chainService === null || chainService === void 0 ? void 0 : chainService.getMetadata(chain));
42
+ const metadata = await (chainService === null || chainService === void 0 ? void 0 : chainService.getMetadataV15(chain));
34
43
 
35
44
  // Avoid date existed metadata
36
45
  if (metadata && metadata.specVersion === currentSpecVersion && metadata.genesisHash === genesisHash) {
37
46
  return;
38
47
  }
39
- const systemChain = await api.rpc.system.chain();
40
- // const _metadata: Option<OpaqueMetadata> = await api.call.metadata.metadataAtVersion(15);
41
- // const metadataHex = _metadata.isSome ? _metadata.unwrap().toHex().slice(2) : ''; // Need unwrap to create metadata object
42
- let hexV15;
43
- const metadataV15 = await api.call.metadata.metadataAtVersion(15);
44
- if (!metadataV15.isEmpty) {
45
- hexV15 = metadataV15.unwrap().toHex();
48
+ if (api.call.metadata.metadataAtVersion) {
49
+ const metadataV15 = await api.call.metadata.metadataAtVersion(15);
50
+ if (!metadataV15.isEmpty) {
51
+ const hexV15 = metadataV15.unwrap().toHex();
52
+ const updateMetadata = {
53
+ chain: chain,
54
+ genesisHash: genesisHash,
55
+ specVersion: currentSpecVersion,
56
+ hexV15
57
+ };
58
+ chainService === null || chainService === void 0 ? void 0 : chainService.upsertMetadataV15(chain, {
59
+ ...updateMetadata
60
+ }).catch(console.error);
61
+ }
46
62
  }
47
- chainService === null || chainService === void 0 ? void 0 : chainService.upsertMetadata(chain, {
48
- chain: chain,
49
- genesisHash: genesisHash,
50
- specName: specName,
51
- specVersion: currentSpecVersion,
52
- hexValue: api.runtimeMetadata.toHex(),
53
- types: (0, _typesKnown.getSpecTypes)(api.registry, systemChain, api.runtimeVersion.specName, api.runtimeVersion.specVersion),
54
- userExtensions: (0, _typesKnown.getSpecExtensions)(api.registry, systemChain, api.runtimeVersion.specName),
55
- hexV15
56
- }).catch(console.error);
63
+ } catch (err) {
64
+ console.error('Error:', err);
65
+ }
66
+ };
67
+ const updateMetadata = async (chain, api, chainService) => {
68
+ const currentSpecVersion = api.runtimeVersion.specVersion.toString();
69
+ const genesisHash = api.genesisHash.toHex();
70
+ const specName = api.runtimeVersion.specName.toString();
71
+ const metadata = await (chainService === null || chainService === void 0 ? void 0 : chainService.getMetadata(chain));
72
+
73
+ // Avoid date existed metadata
74
+ if (metadata && metadata.specVersion === currentSpecVersion && metadata.genesisHash === genesisHash) {
75
+ return;
76
+ }
77
+ const systemChain = api.runtimeChain;
78
+ const metadataHex = api.runtimeMetadata.toHex();
79
+ const registry = api.registry;
80
+ const tokenInfo = {
81
+ ss58Format: (0, _util.isNumber)(registry.chainSS58) ? registry.chainSS58 : DEFAULT_SS58.toNumber(),
82
+ tokenDecimals: (registry.chainDecimals || [DEFAULT_DECIMALS.toNumber()])[0],
83
+ tokenSymbol: (registry.chainTokens || _util.formatBalance.getDefaults().unit)[0]
84
+ };
85
+ const updateMetadata = {
86
+ chain: chain,
87
+ genesisHash: genesisHash,
88
+ specName: specName,
89
+ specVersion: currentSpecVersion,
90
+ hexValue: metadataHex,
91
+ types: (0, _typesKnown.getSpecTypes)(api.registry, systemChain, api.runtimeVersion.specName, api.runtimeVersion.specVersion),
92
+ userExtensions: (0, _typesKnown.getSpecExtensions)(api.registry, systemChain, api.runtimeVersion.specName),
93
+ tokenInfo
94
+ };
95
+ chainService === null || chainService === void 0 ? void 0 : chainService.upsertMetadata(chain, {
96
+ ...updateMetadata
97
+ }).catch(console.error);
98
+ };
99
+ const cacheMetadata = (chain, substrateApi, chainService) => {
100
+ // Update metadata to database with async methods
101
+ substrateApi.api.isReady.then(api => {
102
+ updateMetadata(chain, api, chainService).catch(console.error);
103
+ updateMetadataV15(chain, api, chainService).catch(console.error);
57
104
  }).catch(console.error);
58
105
  };
59
106
  exports.cacheMetadata = cacheMetadata;
@@ -31,7 +31,7 @@ import { createAvailBridgeExtrinsicFromAvail, createAvailBridgeTxFromEth, create
31
31
  import { getClaimTxOnAvail, getClaimTxOnEthereum, isAvailChainBridge } from '@subwallet/extension-base/services/balance-service/transfer/xcm/availBridge';
32
32
  import { _isPolygonChainBridge, getClaimPolygonBridge, isClaimedPolygonBridge } from '@subwallet/extension-base/services/balance-service/transfer/xcm/polygonBridge';
33
33
  import { _isPosChainBridge, getClaimPosBridge } from '@subwallet/extension-base/services/balance-service/transfer/xcm/posBridge';
34
- import { _API_OPTIONS_CHAIN_GROUP, _DEFAULT_MANTA_ZK_CHAIN, _MANTA_ZK_CHAIN_GROUP, _ZK_ASSET_PREFIX, SUFFICIENT_CHAIN } from '@subwallet/extension-base/services/chain-service/constants';
34
+ import { _DEFAULT_MANTA_ZK_CHAIN, _MANTA_ZK_CHAIN_GROUP, _ZK_ASSET_PREFIX, SUFFICIENT_CHAIN } from '@subwallet/extension-base/services/chain-service/constants';
35
35
  import { _ChainConnectionStatus } from '@subwallet/extension-base/services/chain-service/types';
36
36
  import { _getAssetDecimals, _getAssetSymbol, _getChainNativeTokenBasicInfo, _getContractAddressOfToken, _getEvmChainId, _getTokenMinAmount, _getTokenOnChainAssetId, _getXcmAssetMultilocation, _isAssetSmartContractNft, _isBridgedToken, _isChainEvmCompatible, _isChainSubstrateCompatible, _isChainTonCompatible, _isCustomAsset, _isLocalToken, _isMantaZkAsset, _isNativeToken, _isPureEvmChain, _isTokenEvmSmartContract, _isTokenTransferredByEvm, _isTokenTransferredByTon } from '@subwallet/extension-base/services/chain-service/utils';
37
37
  import { EXTENSION_REQUEST_URL } from '@subwallet/extension-base/services/request-service/constants';
@@ -42,7 +42,6 @@ import { AccountsStore } from '@subwallet/extension-base/stores';
42
42
  import { BasicTxErrorType, BasicTxWarningCode, StakingTxErrorType, YieldPoolType } from '@subwallet/extension-base/types';
43
43
  import { _analyzeAddress, BN_ZERO, combineAllAccountProxy, createTransactionFromRLP, isSameAddress, MODULE_SUPPORT, reformatAddress, signatureToHex, toBNString, transformAccounts, transformAddresses, uniqueStringArray } from '@subwallet/extension-base/utils';
44
44
  import { parseContractInput, parseEvmRlp } from '@subwallet/extension-base/utils/eth/parseTransaction';
45
- import { metadataExpand } from '@subwallet/extension-chains';
46
45
  import { getKeypairTypeByAddress, isAddress, isSubstrateAddress, isTonAddress } from '@subwallet/keyring';
47
46
  import { EthereumKeypairTypes, SubstrateKeypairTypes, TonKeypairTypes } from '@subwallet/keyring/types';
48
47
  import { keyring } from '@subwallet/ui-keyring';
@@ -50,9 +49,10 @@ import { getSdkError } from '@walletconnect/utils';
50
49
  import BigN from 'bignumber.js';
51
50
  import { t } from 'i18next';
52
51
  import { combineLatest, Subject } from 'rxjs';
53
- import { Metadata, TypeRegistry } from '@polkadot/types';
52
+ import { TypeRegistry } from '@polkadot/types';
54
53
  import { assert, hexStripPrefix, hexToU8a, isAscii, isHex, u8aToHex } from '@polkadot/util';
55
54
  import { decodeAddress, isEthereumAddress } from '@polkadot/util-crypto';
55
+ import { getSuitableRegistry, setupApiRegistry, setupDappRegistry, setupDatabaseRegistry } from "../utils.js";
56
56
  export function isJsonPayload(value) {
57
57
  return value.genesisHash !== undefined;
58
58
  }
@@ -2264,7 +2264,7 @@ export default class KoniExtension {
2264
2264
  }
2265
2265
  }
2266
2266
 
2267
- /// Signing substrate request
2267
+ // Signing substrate request
2268
2268
  async signingApprovePasswordV2({
2269
2269
  id
2270
2270
  }) {
@@ -2279,7 +2279,7 @@ export default class KoniExtension {
2279
2279
 
2280
2280
  // unlike queued.account.address the following
2281
2281
  // address is encoded with the default prefix
2282
- // which what is used for password caching mapping
2282
+ // which is used for password caching mapping
2283
2283
  const {
2284
2284
  address
2285
2285
  } = pair;
@@ -2293,63 +2293,15 @@ export default class KoniExtension {
2293
2293
  const {
2294
2294
  payload
2295
2295
  } = request;
2296
- let registry;
2296
+ let registry = new TypeRegistry();
2297
2297
  if (isJsonPayload(payload)) {
2298
2298
  const [, chainInfo] = this.#koniState.findNetworkKeyByGenesisHash(payload.genesisHash);
2299
- let metadata;
2300
-
2301
- /**
2302
- * Get the metadata for the genesisHash
2303
- * @todo: need to handle case metadata store in db
2304
- */
2305
- metadata = this.#koniState.knownMetadata.find(meta => meta.genesisHash === payload.genesisHash);
2306
- if (metadata) {
2307
- // we have metadata, expand it and extract the info/registry
2308
- const expanded = metadataExpand(metadata, false);
2309
- registry = expanded.registry;
2310
- registry.setSignedExtensions(payload.signedExtensions, expanded.definition.userExtensions);
2299
+ const allRegistry = [setupApiRegistry(chainInfo, this.#koniState), setupDatabaseRegistry(await this.#koniState.chainService.getMetadataByHash(payload.genesisHash), chainInfo, payload), setupDappRegistry(this.#koniState.knownMetadata.find(meta => meta.genesisHash === payload.genesisHash), payload)].filter(item => item !== null && item.registry !== undefined);
2300
+ if (allRegistry.length === 0) {
2301
+ registry.setSignedExtensions(payload.signedExtensions);
2311
2302
  } else {
2312
- metadata = await this.#koniState.chainService.getMetadataByHash(payload.genesisHash);
2313
- if (metadata) {
2314
- var _chainInfo$substrateI, _chainInfo$substrateI2, _chainInfo$substrateI3, _chainInfo$substrateI4;
2315
- registry = new TypeRegistry();
2316
- const _metadata = new Metadata(registry, metadata.hexValue);
2317
- registry.register(metadata.types);
2318
- registry.setChainProperties(registry.createType('ChainProperties', {
2319
- ss58Format: (_chainInfo$substrateI = chainInfo === null || chainInfo === void 0 ? void 0 : (_chainInfo$substrateI2 = chainInfo.substrateInfo) === null || _chainInfo$substrateI2 === void 0 ? void 0 : _chainInfo$substrateI2.addressPrefix) !== null && _chainInfo$substrateI !== void 0 ? _chainInfo$substrateI : 42,
2320
- tokenDecimals: chainInfo === null || chainInfo === void 0 ? void 0 : (_chainInfo$substrateI3 = chainInfo.substrateInfo) === null || _chainInfo$substrateI3 === void 0 ? void 0 : _chainInfo$substrateI3.decimals,
2321
- tokenSymbol: chainInfo === null || chainInfo === void 0 ? void 0 : (_chainInfo$substrateI4 = chainInfo.substrateInfo) === null || _chainInfo$substrateI4 === void 0 ? void 0 : _chainInfo$substrateI4.symbol
2322
- }));
2323
- registry.setMetadata(_metadata, payload.signedExtensions, metadata.userExtensions);
2324
- } else {
2325
- // we have no metadata, create a new registry
2326
- registry = new TypeRegistry();
2327
- registry.setSignedExtensions(payload.signedExtensions);
2328
- }
2303
+ registry = getSuitableRegistry(allRegistry, payload);
2329
2304
  }
2330
- if (!metadata) {
2331
- /*
2332
- * Some networks must have metadata to signing,
2333
- * so if the chain not active (cannot use metadata from api), it must be rejected
2334
- * */
2335
- if (chainInfo && (_API_OPTIONS_CHAIN_GROUP.avail.includes(chainInfo.slug) || _API_OPTIONS_CHAIN_GROUP.goldberg.includes(chainInfo.slug)) // The special case for chains that need metadata to signing
2336
- ) {
2337
- // For case the chain does not have any provider
2338
- if (!Object.keys(chainInfo.providers).length) {
2339
- reject(new Error('{{chain}} network does not have any provider to connect, please update metadata from dApp'.replaceAll('{{chain}}', chainInfo.name)));
2340
- return false;
2341
- }
2342
- const isChainActive = this.#koniState.getChainStateByKey(chainInfo.slug).active;
2343
- if (!isChainActive) {
2344
- reject(new Error('Please activate {{chain}} network before signing'.replaceAll('{{chain}}', chainInfo.name)));
2345
- return false;
2346
- }
2347
- registry = this.#koniState.getSubstrateApi(chainInfo.slug).api.registry;
2348
- }
2349
- }
2350
- } else {
2351
- // for non-payload, just create a registry to use
2352
- registry = new TypeRegistry();
2353
2305
  }
2354
2306
  const result = request.sign(registry, pair);
2355
2307
  resolve({
@@ -0,0 +1,13 @@
1
+ import { _ChainInfo } from '@subwallet/chain-list/types';
2
+ import { MetadataItem } from '@subwallet/extension-base/background/KoniTypes';
3
+ import { MetadataDef } from '@subwallet/extension-inject/types';
4
+ import { Registry, SignerPayloadJSON } from '@polkadot/types/types';
5
+ import KoniState from './handlers/State';
6
+ export interface RegistrySource {
7
+ registry: Registry;
8
+ specVersion: string | number;
9
+ }
10
+ export declare function getSuitableRegistry(registries: RegistrySource[], payload: SignerPayloadJSON): Registry;
11
+ export declare function setupApiRegistry(chainInfo: _ChainInfo | undefined, koniState: KoniState): RegistrySource | null;
12
+ export declare function setupDatabaseRegistry(metadata: MetadataItem, chainInfo: _ChainInfo | undefined, payload: SignerPayloadJSON): RegistrySource | null;
13
+ export declare function setupDappRegistry(metadata: MetadataDef, payload: SignerPayloadJSON): RegistrySource | null;
@@ -0,0 +1,63 @@
1
+ // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { metadataExpand } from '@subwallet/extension-chains/bundle';
5
+ import { Metadata, TypeRegistry } from '@polkadot/types';
6
+ export function getSuitableRegistry(registries, payload) {
7
+ const payloadSpecVersion = parseInt(payload.specVersion);
8
+ const sortedRegistries = registries.filter(registrySource => registrySource.registry !== undefined).map(registrySource => {
9
+ const specVersion = Number(registrySource.specVersion);
10
+ const distance = Math.abs(specVersion - payloadSpecVersion);
11
+ const isHigher = specVersion >= payloadSpecVersion;
12
+ return {
13
+ registry: registrySource.registry,
14
+ specVersion,
15
+ distance,
16
+ isHigher
17
+ };
18
+ }).sort((a, b) => {
19
+ if (a.distance !== b.distance) {
20
+ return a.distance - b.distance;
21
+ }
22
+ return b.specVersion - a.specVersion;
23
+ });
24
+ return sortedRegistries[0].registry;
25
+ }
26
+ export function setupApiRegistry(chainInfo, koniState) {
27
+ if (!chainInfo) {
28
+ return null;
29
+ }
30
+ const api = koniState.getSubstrateApi(chainInfo.slug).api;
31
+ const apiSpecVersion = api === null || api === void 0 ? void 0 : api.runtimeVersion.specVersion.toString();
32
+ const registry = api === null || api === void 0 ? void 0 : api.registry;
33
+ return {
34
+ registry,
35
+ specVersion: apiSpecVersion
36
+ };
37
+ }
38
+ export function setupDatabaseRegistry(metadata, chainInfo, payload) {
39
+ if (!metadata || !metadata.genesisHash || !chainInfo) {
40
+ return null;
41
+ }
42
+ const registry = new TypeRegistry();
43
+ const _metadata = new Metadata(registry, metadata.hexValue);
44
+ registry.register(metadata.types);
45
+ registry.setChainProperties(registry.createType('ChainProperties', metadata.tokenInfo));
46
+ registry.setMetadata(_metadata, payload.signedExtensions, metadata.userExtensions);
47
+ return {
48
+ registry,
49
+ specVersion: metadata.specVersion
50
+ };
51
+ }
52
+ export function setupDappRegistry(metadata, payload) {
53
+ if (!metadata || !metadata.genesisHash) {
54
+ return null;
55
+ }
56
+ const expanded = metadataExpand(metadata, false);
57
+ const registry = expanded.registry;
58
+ registry.setSignedExtensions(payload.signedExtensions, expanded.definition.userExtensions);
59
+ return {
60
+ registry,
61
+ specVersion: metadata.specVersion
62
+ };
63
+ }
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.3.12-0",
20
+ "version": "1.3.13-0",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -568,6 +568,11 @@
568
568
  "require": "./cjs/koni/background/subscription.js",
569
569
  "default": "./koni/background/subscription.js"
570
570
  },
571
+ "./koni/background/utils": {
572
+ "types": "./koni/background/utils.d.ts",
573
+ "require": "./cjs/koni/background/utils.js",
574
+ "default": "./koni/background/utils.js"
575
+ },
571
576
  "./package.json": "./package.json",
572
577
  "./packageInfo.js": {
573
578
  "types": "./packageInfo.d.ts",
@@ -1681,6 +1686,11 @@
1681
1686
  "require": "./cjs/services/storage-service/db-stores/Metadata.js",
1682
1687
  "default": "./services/storage-service/db-stores/Metadata.js"
1683
1688
  },
1689
+ "./services/storage-service/db-stores/MetadataV15": {
1690
+ "types": "./services/storage-service/db-stores/MetadataV15.d.ts",
1691
+ "require": "./cjs/services/storage-service/db-stores/MetadataV15.js",
1692
+ "default": "./services/storage-service/db-stores/MetadataV15.js"
1693
+ },
1684
1694
  "./services/storage-service/db-stores/Migration": {
1685
1695
  "types": "./services/storage-service/db-stores/Migration.d.ts",
1686
1696
  "require": "./cjs/services/storage-service/db-stores/Migration.js",
@@ -2504,10 +2514,10 @@
2504
2514
  "@sora-substrate/type-definitions": "^1.17.7",
2505
2515
  "@substrate/connect": "^0.8.9",
2506
2516
  "@subwallet/chain-list": "0.2.97",
2507
- "@subwallet/extension-base": "^1.3.12-0",
2508
- "@subwallet/extension-chains": "^1.3.12-0",
2509
- "@subwallet/extension-dapp": "^1.3.12-0",
2510
- "@subwallet/extension-inject": "^1.3.12-0",
2517
+ "@subwallet/extension-base": "^1.3.13-0",
2518
+ "@subwallet/extension-chains": "^1.3.13-0",
2519
+ "@subwallet/extension-dapp": "^1.3.13-0",
2520
+ "@subwallet/extension-inject": "^1.3.13-0",
2511
2521
  "@subwallet/keyring": "^0.1.8-beta.0",
2512
2522
  "@subwallet/ui-keyring": "^0.1.8-beta.0",
2513
2523
  "@ton/core": "^0.56.3",
package/packageInfo.js CHANGED
@@ -7,5 +7,5 @@ export const packageInfo = {
7
7
  name: '@subwallet/extension-base',
8
8
  path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto',
9
9
  type: 'esm',
10
- version: '1.3.12-0'
10
+ version: '1.3.13-0'
11
11
  };
@@ -1,10 +1,10 @@
1
1
  /// <reference types="node" />
2
2
  import { _AssetRef, _AssetType, _ChainAsset, _ChainInfo, _MultiChainAsset } from '@subwallet/chain-list/types';
3
- import { AssetSetting, ValidateNetworkResponse } from '@subwallet/extension-base/background/KoniTypes';
3
+ import { AssetSetting, MetadataItem, ValidateNetworkResponse } from '@subwallet/extension-base/background/KoniTypes';
4
4
  import { MantaPrivateHandler } from '@subwallet/extension-base/services/chain-service/handler/manta/MantaPrivateHandler';
5
5
  import { _ChainApiStatus, _ChainConnectionStatus, _ChainState, _NetworkUpsertParams, _SubstrateApi, _ValidateCustomAssetRequest, _ValidateCustomAssetResponse } from '@subwallet/extension-base/services/chain-service/types';
6
6
  import { EventService } from '@subwallet/extension-base/services/event-service';
7
- import { IMetadataItem } from '@subwallet/extension-base/services/storage-service/databases';
7
+ import { IMetadataItem, IMetadataV15Item } from '@subwallet/extension-base/services/storage-service/databases';
8
8
  import DatabaseService from '@subwallet/extension-base/services/storage-service/DatabaseService';
9
9
  import { BehaviorSubject, Subject } from 'rxjs';
10
10
  import { ExtraInfo } from '@polkadot-api/merkleize-metadata';
@@ -155,8 +155,10 @@ export declare class ChainService {
155
155
  resetWallet(resetAll: boolean): void;
156
156
  getMetadata(chain: string): import("dexie").PromiseExtended<IMetadataItem | undefined>;
157
157
  upsertMetadata(chain: string, metadata: IMetadataItem): import("dexie").PromiseExtended<unknown>;
158
+ getMetadataV15(chain: string): import("dexie").PromiseExtended<IMetadataV15Item | undefined>;
159
+ upsertMetadataV15(chain: string, metadata: IMetadataV15Item): import("dexie").PromiseExtended<unknown>;
158
160
  getMetadataByHash(hash: string): import("dexie").PromiseExtended<IMetadataItem | undefined>;
159
- getExtraInfo(chain: string): Omit<ExtraInfo, 'specVersion' | 'specName'>;
161
+ getExtraInfo(metadata: MetadataItem): Omit<ExtraInfo, 'specVersion' | 'specName'>;
160
162
  calculateMetadataHash(chain: string): Promise<string | undefined>;
161
163
  shortenMetadata(chain: string, txBlob: string): Promise<string | undefined>;
162
164
  getSubscanChainMap(reverse?: boolean): Record<string, string>;
@@ -1720,27 +1720,34 @@ export class ChainService {
1720
1720
  upsertMetadata(chain, metadata) {
1721
1721
  return this.dbService.stores.metadata.upsertMetadata(chain, metadata);
1722
1722
  }
1723
+ getMetadataV15(chain) {
1724
+ return this.dbService.stores.metadataV15.getMetadata(chain);
1725
+ }
1726
+ upsertMetadataV15(chain, metadata) {
1727
+ return this.dbService.stores.metadataV15.upsertMetadata(chain, metadata);
1728
+ }
1723
1729
  getMetadataByHash(hash) {
1724
1730
  return this.dbService.stores.metadata.getMetadataByGenesisHash(hash);
1725
1731
  }
1726
- getExtraInfo(chain) {
1727
- var _chainInfo$substrateI2, _chainInfo$substrateI3, _chainInfo$substrateI4, _chainInfo$substrateI5, _chainInfo$substrateI6, _chainInfo$substrateI7;
1728
- const chainInfo = this.getChainInfoByKey(chain);
1732
+ getExtraInfo(metadata) {
1733
+ var _tokenInfo$tokenDecim, _tokenInfo$tokenSymbo, _tokenInfo$ss58Format;
1734
+ const tokenInfo = metadata.tokenInfo;
1729
1735
  return {
1730
- decimals: (_chainInfo$substrateI2 = (_chainInfo$substrateI3 = chainInfo.substrateInfo) === null || _chainInfo$substrateI3 === void 0 ? void 0 : _chainInfo$substrateI3.decimals) !== null && _chainInfo$substrateI2 !== void 0 ? _chainInfo$substrateI2 : 0,
1731
- tokenSymbol: (_chainInfo$substrateI4 = (_chainInfo$substrateI5 = chainInfo.substrateInfo) === null || _chainInfo$substrateI5 === void 0 ? void 0 : _chainInfo$substrateI5.symbol) !== null && _chainInfo$substrateI4 !== void 0 ? _chainInfo$substrateI4 : 'Unit',
1732
- base58Prefix: (_chainInfo$substrateI6 = (_chainInfo$substrateI7 = chainInfo.substrateInfo) === null || _chainInfo$substrateI7 === void 0 ? void 0 : _chainInfo$substrateI7.addressPrefix) !== null && _chainInfo$substrateI6 !== void 0 ? _chainInfo$substrateI6 : 42
1736
+ decimals: (_tokenInfo$tokenDecim = tokenInfo === null || tokenInfo === void 0 ? void 0 : tokenInfo.tokenDecimals) !== null && _tokenInfo$tokenDecim !== void 0 ? _tokenInfo$tokenDecim : 0,
1737
+ tokenSymbol: (_tokenInfo$tokenSymbo = tokenInfo === null || tokenInfo === void 0 ? void 0 : tokenInfo.tokenSymbol) !== null && _tokenInfo$tokenSymbo !== void 0 ? _tokenInfo$tokenSymbo : 'Unit',
1738
+ base58Prefix: (_tokenInfo$ss58Format = tokenInfo === null || tokenInfo === void 0 ? void 0 : tokenInfo.ss58Format) !== null && _tokenInfo$ss58Format !== void 0 ? _tokenInfo$ss58Format : 42
1733
1739
  };
1734
1740
  }
1735
1741
  async calculateMetadataHash(chain) {
1736
1742
  const metadata = await this.getMetadata(chain);
1737
- if (!metadata || !metadata.hexV15) {
1743
+ const metadataV15 = await this.getMetadataV15(chain);
1744
+ if (!metadata || !metadataV15 || !metadataV15.hexV15) {
1738
1745
  return undefined;
1739
1746
  }
1740
- const extraInfo = this.getExtraInfo(chain);
1747
+ const extraInfo = this.getExtraInfo(metadata);
1741
1748
  const specVersion = parseInt(metadata.specVersion);
1742
1749
  const specName = metadata.specName;
1743
- const hexV15 = metadata.hexV15;
1750
+ const hexV15 = metadataV15.hexV15;
1744
1751
  return calculateMetadataHash({
1745
1752
  ...extraInfo,
1746
1753
  specVersion,
@@ -1749,13 +1756,14 @@ export class ChainService {
1749
1756
  }
1750
1757
  async shortenMetadata(chain, txBlob) {
1751
1758
  const metadata = await this.getMetadata(chain);
1752
- if (!metadata || !metadata.hexV15) {
1759
+ const metadataV15 = await this.getMetadataV15(chain);
1760
+ if (!metadata || !metadataV15 || !metadataV15.hexV15) {
1753
1761
  return undefined;
1754
1762
  }
1755
- const extraInfo = this.getExtraInfo(chain);
1763
+ const extraInfo = this.getExtraInfo(metadata);
1756
1764
  const specVersion = parseInt(metadata.specVersion);
1757
1765
  const specName = metadata.specName;
1758
- const hexV15 = metadata.hexV15;
1766
+ const hexV15 = metadataV15.hexV15;
1759
1767
  return getShortMetadata(txBlob, {
1760
1768
  ...extraInfo,
1761
1769
  specVersion,
@@ -59,9 +59,9 @@ export default {
59
59
  '1.2.28-02': MigrateTransactionHistoryBySymbol,
60
60
  '1.2.69-01': MigrateRemoveGenesisHash,
61
61
  '1.2.13-01': ReloadMetadata,
62
- '1.2.14-01': ClearMetadataDatabase,
63
62
  '1.2.32-01': MigratePairData,
64
- '1.3.6-01': MigrateTransactionHistoryBridge
63
+ '1.3.6-01': MigrateTransactionHistoryBridge,
64
+ '1.3.10-01': ClearMetadataDatabase
65
65
  // [`${EVERYTIME}-1.1.42-02`]: MigrateTransactionHistoryBySymbol
66
66
  // [`${EVERYTIME}-1`]: AutoEnableChainsTokens
67
67
  };
@@ -3,7 +3,7 @@ import { ChainStakingMetadata, CrowdloanItem, MantaPayConfig, NftCollection, Nft
3
3
  import { EventService } from '@subwallet/extension-base/services/event-service';
4
4
  import { _NotificationInfo } from '@subwallet/extension-base/services/inapp-notification-service/interfaces';
5
5
  import { IBalance, ICampaign, IChain, INft } from '@subwallet/extension-base/services/storage-service/databases';
6
- import { AssetStore, BalanceStore, ChainStore, CrowdloanStore, MetadataStore, MigrationStore, NftCollectionStore, NftStore, PriceStore, StakingStore, TransactionStore } from '@subwallet/extension-base/services/storage-service/db-stores';
6
+ import { AssetStore, BalanceStore, ChainStore, CrowdloanStore, MetadataStore, MetadataV15Store, MigrationStore, NftCollectionStore, NftStore, PriceStore, StakingStore, TransactionStore } from '@subwallet/extension-base/services/storage-service/db-stores';
7
7
  import CampaignStore from '@subwallet/extension-base/services/storage-service/db-stores/Campaign';
8
8
  import ChainStakingMetadataStore from '@subwallet/extension-base/services/storage-service/db-stores/ChainStakingMetadata';
9
9
  import InappNotificationStore from '@subwallet/extension-base/services/storage-service/db-stores/InappNotification';
@@ -30,6 +30,7 @@ export default class DatabaseService {
30
30
  transaction: TransactionStore;
31
31
  migration: MigrationStore;
32
32
  metadata: MetadataStore;
33
+ metadataV15: MetadataV15Store;
33
34
  chain: ChainStore;
34
35
  asset: AssetStore;
35
36
  yieldPoolInfo: YieldPoolStore;
@@ -3,7 +3,7 @@
3
3
 
4
4
  import { APIItemState, StakingType } from '@subwallet/extension-base/background/KoniTypes';
5
5
  import KoniDatabase from '@subwallet/extension-base/services/storage-service/databases';
6
- import { AssetStore, BalanceStore, ChainStore, CrowdloanStore, MetadataStore, MigrationStore, NftCollectionStore, NftStore, PriceStore, StakingStore, TransactionStore } from '@subwallet/extension-base/services/storage-service/db-stores';
6
+ import { AssetStore, BalanceStore, ChainStore, CrowdloanStore, MetadataStore, MetadataV15Store, MigrationStore, NftCollectionStore, NftStore, PriceStore, StakingStore, TransactionStore } from '@subwallet/extension-base/services/storage-service/db-stores';
7
7
  import CampaignStore from '@subwallet/extension-base/services/storage-service/db-stores/Campaign';
8
8
  import ChainStakingMetadataStore from '@subwallet/extension-base/services/storage-service/db-stores/ChainStakingMetadata';
9
9
  import InappNotificationStore from '@subwallet/extension-base/services/storage-service/db-stores/InappNotification';
@@ -37,6 +37,7 @@ export default class DatabaseService {
37
37
  transaction: new TransactionStore(this._db.transactions),
38
38
  migration: new MigrationStore(this._db.migrations),
39
39
  metadata: new MetadataStore(this._db.metadata),
40
+ metadataV15: new MetadataV15Store(this._db.metadataV15),
40
41
  chain: new ChainStore(this._db.chain),
41
42
  asset: new AssetStore(this._db.asset),
42
43
  // yield
@@ -1,5 +1,5 @@
1
1
  import { _AssetRef, _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
2
- import { CampaignData, ChainStakingMetadata, CrowdloanItem, MetadataItem, NftCollection, NftItem, NominatorMetadata, PriceJson, StakingItem, TransactionHistoryItem } from '@subwallet/extension-base/background/KoniTypes';
2
+ import { CampaignData, ChainStakingMetadata, CrowdloanItem, MetadataItem, MetadataV15Item, NftCollection, NftItem, NominatorMetadata, PriceJson, StakingItem, TransactionHistoryItem } from '@subwallet/extension-base/background/KoniTypes';
3
3
  import { _NotificationInfo } from '@subwallet/extension-base/services/inapp-notification-service/interfaces';
4
4
  import { BalanceItem, YieldPoolInfo, YieldPositionInfo } from '@subwallet/extension-base/types';
5
5
  import Dexie, { Table } from 'dexie';
@@ -36,6 +36,8 @@ export interface IMigration {
36
36
  }
37
37
  export interface IMetadataItem extends MetadataItem, DefaultChainDoc {
38
38
  }
39
+ export interface IMetadataV15Item extends MetadataV15Item, DefaultChainDoc {
40
+ }
39
41
  export declare type IMantaPayLedger = any;
40
42
  export declare type ICampaign = CampaignData;
41
43
  export interface IAssetRef extends _AssetRef {
@@ -51,6 +53,7 @@ export default class KoniDatabase extends Dexie {
51
53
  transactions: Table<ITransactionHistoryItem, object>;
52
54
  migrations: Table<IMigration, object>;
53
55
  metadata: Table<IMetadataItem, object>;
56
+ metadataV15: Table<IMetadataV15Item, object>;
54
57
  chain: Table<IChain, object>;
55
58
  asset: Table<_ChainAsset, object>;
56
59
  chainStakingMetadata: Table<ChainStakingMetadata, object>;
@@ -43,6 +43,9 @@ export default class KoniDatabase extends Dexie {
43
43
  this.conditionalVersion(7, {
44
44
  inappNotification: 'id, address, proxyId, [proxyId+actionType], actionType'
45
45
  });
46
+ this.conditionalVersion(8, {
47
+ metadataV15: 'genesisHash, chain'
48
+ });
46
49
  }
47
50
  conditionalVersion(version, schema, upgrade) {
48
51
  if (this.schemaVersion != null && this.schemaVersion < version) {
@@ -0,0 +1,8 @@
1
+ import BaseStoreWithChain from '@subwallet/extension-base/services/storage-service/db-stores/BaseStoreWithChain';
2
+ import { IMetadataV15Item } from '../databases';
3
+ export default class MetadataV15Store extends BaseStoreWithChain<IMetadataV15Item> {
4
+ getMetadata(chain: string): import("dexie").PromiseExtended<IMetadataV15Item | undefined>;
5
+ upsertMetadata(chain: string, metadata: IMetadataV15Item): import("dexie").PromiseExtended<unknown>;
6
+ getMetadataByGenesisHash(genesisHash: string): import("dexie").PromiseExtended<IMetadataV15Item | undefined>;
7
+ updateMetadataByGenesisHash(genesisHash: string, metadata: IMetadataV15Item): import("dexie").PromiseExtended<unknown>;
8
+ }
@@ -0,0 +1,18 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import BaseStoreWithChain from '@subwallet/extension-base/services/storage-service/db-stores/BaseStoreWithChain';
5
+ export default class MetadataV15Store extends BaseStoreWithChain {
6
+ getMetadata(chain) {
7
+ return this.table.where('chain').equals(chain).first();
8
+ }
9
+ upsertMetadata(chain, metadata) {
10
+ return this.table.put(metadata, chain);
11
+ }
12
+ getMetadataByGenesisHash(genesisHash) {
13
+ return this.table.get(genesisHash);
14
+ }
15
+ updateMetadataByGenesisHash(genesisHash, metadata) {
16
+ return this.table.put(metadata, genesisHash);
17
+ }
18
+ }
@@ -7,5 +7,6 @@ export { default as StakingStore } from './Staking';
7
7
  export { default as TransactionStore } from './Transaction';
8
8
  export { default as MigrationStore } from './Migration';
9
9
  export { default as MetadataStore } from './Metadata';
10
+ export { default as MetadataV15Store } from './MetadataV15';
10
11
  export { default as ChainStore } from './Chain';
11
12
  export { default as AssetStore } from './Asset';
@@ -10,5 +10,6 @@ export { default as StakingStore } from "./Staking.js";
10
10
  export { default as TransactionStore } from "./Transaction.js";
11
11
  export { default as MigrationStore } from "./Migration.js";
12
12
  export { default as MetadataStore } from "./Metadata.js";
13
+ export { default as MetadataV15Store } from "./MetadataV15.js";
13
14
  export { default as ChainStore } from "./Chain.js";
14
15
  export { default as AssetStore } from "./Asset.js";
@@ -1,8 +1,18 @@
1
1
  import { ChainService } from '@subwallet/extension-base/services/chain-service';
2
2
  import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
3
+ import { ApiPromise } from '@polkadot/api';
4
+ import { TypeRegistry } from '@polkadot/types';
3
5
  import { HexString } from '@polkadot/util/types';
4
6
  import { ExtraInfo } from '@polkadot-api/merkleize-metadata';
7
+ interface Statics {
8
+ api: ApiPromise;
9
+ registry: TypeRegistry;
10
+ }
11
+ export declare const statics: Statics;
12
+ export declare const DEFAULT_DECIMALS: import("@polkadot/types").U32;
13
+ export declare const DEFAULT_SS58: import("@polkadot/types").U32;
5
14
  export declare const _isRuntimeUpdated: (signedExtensions?: string[]) => boolean;
6
15
  export declare const calculateMetadataHash: (extraInfo: ExtraInfo, metadataV15: HexString) => string;
7
16
  export declare const getShortMetadata: (blob: HexString, extraInfo: ExtraInfo, metadata: HexString) => string;
8
17
  export declare const cacheMetadata: (chain: string, substrateApi: _SubstrateApi, chainService?: ChainService) => void;
18
+ export {};
package/utils/metadata.js CHANGED
@@ -1,9 +1,17 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
+ import { TypeRegistry } from '@polkadot/types';
4
5
  import { getSpecExtensions, getSpecTypes } from '@polkadot/types-known';
5
- import { u8aToHex } from '@polkadot/util';
6
+ import { formatBalance, isNumber, u8aToHex } from '@polkadot/util';
7
+ import { defaults as addressDefaults } from '@polkadot/util-crypto/address/defaults';
6
8
  import { merkleizeMetadata } from '@polkadot-api/merkleize-metadata';
9
+ export const statics = {
10
+ api: undefined,
11
+ registry: new TypeRegistry()
12
+ };
13
+ export const DEFAULT_DECIMALS = statics.registry.createType('u32', 12);
14
+ export const DEFAULT_SS58 = statics.registry.createType('u32', addressDefaults.prefix);
7
15
  export const _isRuntimeUpdated = signedExtensions => {
8
16
  return signedExtensions ? signedExtensions.includes('CheckMetadataHash') : false;
9
17
  };
@@ -15,35 +23,71 @@ export const getShortMetadata = (blob, extraInfo, metadata) => {
15
23
  const _merkleizeMetadata = merkleizeMetadata(metadata, extraInfo);
16
24
  return u8aToHex(_merkleizeMetadata.getProofForExtrinsicPayload(blob));
17
25
  };
18
- export const cacheMetadata = (chain, substrateApi, chainService) => {
19
- // Update metadata to database with async methods
20
- substrateApi.api.isReady.then(async api => {
26
+ const updateMetadataV15 = async (chain, api, chainService) => {
27
+ try {
21
28
  const currentSpecVersion = api.runtimeVersion.specVersion.toString();
22
- const specName = api.runtimeVersion.specName.toString();
23
29
  const genesisHash = api.genesisHash.toHex();
24
- const metadata = await (chainService === null || chainService === void 0 ? void 0 : chainService.getMetadata(chain));
30
+ const metadata = await (chainService === null || chainService === void 0 ? void 0 : chainService.getMetadataV15(chain));
25
31
 
26
32
  // Avoid date existed metadata
27
33
  if (metadata && metadata.specVersion === currentSpecVersion && metadata.genesisHash === genesisHash) {
28
34
  return;
29
35
  }
30
- const systemChain = await api.rpc.system.chain();
31
- // const _metadata: Option<OpaqueMetadata> = await api.call.metadata.metadataAtVersion(15);
32
- // const metadataHex = _metadata.isSome ? _metadata.unwrap().toHex().slice(2) : ''; // Need unwrap to create metadata object
33
- let hexV15;
34
- const metadataV15 = await api.call.metadata.metadataAtVersion(15);
35
- if (!metadataV15.isEmpty) {
36
- hexV15 = metadataV15.unwrap().toHex();
36
+ if (api.call.metadata.metadataAtVersion) {
37
+ const metadataV15 = await api.call.metadata.metadataAtVersion(15);
38
+ if (!metadataV15.isEmpty) {
39
+ const hexV15 = metadataV15.unwrap().toHex();
40
+ const updateMetadata = {
41
+ chain: chain,
42
+ genesisHash: genesisHash,
43
+ specVersion: currentSpecVersion,
44
+ hexV15
45
+ };
46
+ chainService === null || chainService === void 0 ? void 0 : chainService.upsertMetadataV15(chain, {
47
+ ...updateMetadata
48
+ }).catch(console.error);
49
+ }
37
50
  }
38
- chainService === null || chainService === void 0 ? void 0 : chainService.upsertMetadata(chain, {
39
- chain: chain,
40
- genesisHash: genesisHash,
41
- specName: specName,
42
- specVersion: currentSpecVersion,
43
- hexValue: api.runtimeMetadata.toHex(),
44
- types: getSpecTypes(api.registry, systemChain, api.runtimeVersion.specName, api.runtimeVersion.specVersion),
45
- userExtensions: getSpecExtensions(api.registry, systemChain, api.runtimeVersion.specName),
46
- hexV15
47
- }).catch(console.error);
51
+ } catch (err) {
52
+ console.error('Error:', err);
53
+ }
54
+ };
55
+ const updateMetadata = async (chain, api, chainService) => {
56
+ const currentSpecVersion = api.runtimeVersion.specVersion.toString();
57
+ const genesisHash = api.genesisHash.toHex();
58
+ const specName = api.runtimeVersion.specName.toString();
59
+ const metadata = await (chainService === null || chainService === void 0 ? void 0 : chainService.getMetadata(chain));
60
+
61
+ // Avoid date existed metadata
62
+ if (metadata && metadata.specVersion === currentSpecVersion && metadata.genesisHash === genesisHash) {
63
+ return;
64
+ }
65
+ const systemChain = api.runtimeChain;
66
+ const metadataHex = api.runtimeMetadata.toHex();
67
+ const registry = api.registry;
68
+ const tokenInfo = {
69
+ ss58Format: isNumber(registry.chainSS58) ? registry.chainSS58 : DEFAULT_SS58.toNumber(),
70
+ tokenDecimals: (registry.chainDecimals || [DEFAULT_DECIMALS.toNumber()])[0],
71
+ tokenSymbol: (registry.chainTokens || formatBalance.getDefaults().unit)[0]
72
+ };
73
+ const updateMetadata = {
74
+ chain: chain,
75
+ genesisHash: genesisHash,
76
+ specName: specName,
77
+ specVersion: currentSpecVersion,
78
+ hexValue: metadataHex,
79
+ types: getSpecTypes(api.registry, systemChain, api.runtimeVersion.specName, api.runtimeVersion.specVersion),
80
+ userExtensions: getSpecExtensions(api.registry, systemChain, api.runtimeVersion.specName),
81
+ tokenInfo
82
+ };
83
+ chainService === null || chainService === void 0 ? void 0 : chainService.upsertMetadata(chain, {
84
+ ...updateMetadata
85
+ }).catch(console.error);
86
+ };
87
+ export const cacheMetadata = (chain, substrateApi, chainService) => {
88
+ // Update metadata to database with async methods
89
+ substrateApi.api.isReady.then(api => {
90
+ updateMetadata(chain, api, chainService).catch(console.error);
91
+ updateMetadataV15(chain, api, chainService).catch(console.error);
48
92
  }).catch(console.error);
49
93
  };