@subwallet/extension-base 1.2.15-0 → 1.2.16-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 (58) hide show
  1. package/background/KoniTypes.d.ts +6 -1
  2. package/cjs/koni/background/handlers/Extension.js +33 -7
  3. package/cjs/koni/background/handlers/State.js +11 -1
  4. package/cjs/packageInfo.js +1 -1
  5. package/cjs/services/balance-service/helpers/subscribe/index.js +1 -1
  6. package/cjs/services/balance-service/helpers/subscribe/substrate/gear.js +135 -0
  7. package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +9 -62
  8. package/cjs/services/balance-service/transfer/token.js +4 -3
  9. package/cjs/services/chain-service/handler/SubstrateApi.js +3 -1
  10. package/cjs/services/chain-service/handler/SubstrateChainHandler.js +21 -26
  11. package/cjs/services/chain-service/index.js +48 -3
  12. package/cjs/services/chain-service/types.js +1 -1
  13. package/cjs/services/chain-service/utils/index.js +18 -12
  14. package/cjs/services/earning-service/service.js +3 -0
  15. package/cjs/services/migration-service/scripts/databases/ClearMetadataDatabase.js +16 -0
  16. package/cjs/services/migration-service/scripts/index.js +7 -7
  17. package/cjs/services/transaction-service/index.js +12 -7
  18. package/cjs/utils/gear/combine.js +28 -0
  19. package/cjs/utils/gear/grc20.js +56 -49
  20. package/cjs/utils/gear/index.js +22 -0
  21. package/cjs/utils/gear/vft.js +173 -0
  22. package/cjs/utils/metadata.js +45 -34
  23. package/koni/background/handlers/Extension.d.ts +2 -0
  24. package/koni/background/handlers/Extension.js +25 -1
  25. package/koni/background/handlers/State.d.ts +2 -0
  26. package/koni/background/handlers/State.js +11 -1
  27. package/package.json +24 -8
  28. package/packageInfo.js +1 -1
  29. package/services/balance-service/helpers/subscribe/index.js +1 -1
  30. package/services/balance-service/helpers/subscribe/substrate/gear.d.ts +4 -0
  31. package/services/balance-service/helpers/subscribe/substrate/gear.js +123 -0
  32. package/services/balance-service/helpers/subscribe/substrate/index.js +10 -61
  33. package/services/balance-service/transfer/token.js +5 -4
  34. package/services/chain-service/handler/SubstrateApi.d.ts +1 -1
  35. package/services/chain-service/handler/SubstrateApi.js +3 -1
  36. package/services/chain-service/handler/SubstrateChainHandler.d.ts +1 -0
  37. package/services/chain-service/handler/SubstrateChainHandler.js +22 -27
  38. package/services/chain-service/index.d.ts +4 -0
  39. package/services/chain-service/index.js +49 -4
  40. package/services/chain-service/types.d.ts +1 -0
  41. package/services/chain-service/types.js +1 -1
  42. package/services/chain-service/utils/index.d.ts +1 -0
  43. package/services/chain-service/utils/index.js +16 -12
  44. package/services/earning-service/service.js +3 -0
  45. package/services/migration-service/scripts/databases/ClearMetadataDatabase.js +16 -0
  46. package/services/migration-service/scripts/index.js +7 -7
  47. package/services/transaction-service/index.js +13 -8
  48. package/types/metadata.d.ts +9 -2
  49. package/utils/gear/combine.d.ts +10 -0
  50. package/utils/gear/combine.js +18 -0
  51. package/utils/gear/grc20.d.ts +18 -20
  52. package/utils/gear/grc20.js +53 -45
  53. package/utils/gear/index.d.ts +2 -0
  54. package/utils/gear/index.js +3 -1
  55. package/utils/gear/vft.d.ts +36 -0
  56. package/utils/gear/vft.js +162 -0
  57. package/utils/metadata.d.ts +7 -2
  58. package/utils/metadata.js +41 -31
@@ -3,46 +3,57 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getShortMetadata = exports.getMetadataHash = exports._isRuntimeUpdated = void 0;
6
+ exports.getShortMetadata = exports.calculateMetadataHash = exports.cacheMetadata = exports._isRuntimeUpdated = void 0;
7
+ var _typesKnown = require("@polkadot/types-known");
8
+ var _util = require("@polkadot/util");
9
+ var _merkleizeMetadata2 = require("@polkadot-api/merkleize-metadata");
7
10
  // Copyright 2019-2022 @subwallet/extension-base
8
11
  // SPDX-License-Identifier: Apache-2.0
9
12
 
10
- const LEDGER_API_URL = 'https://ledger-api.subwallet.app';
11
- const createUrl = path => `${LEDGER_API_URL}/${path}`;
12
13
  const _isRuntimeUpdated = signedExtensions => {
13
14
  return signedExtensions ? signedExtensions.includes('CheckMetadataHash') : false;
14
15
  };
15
16
  exports._isRuntimeUpdated = _isRuntimeUpdated;
16
- const getMetadataHash = async chain => {
17
- const data = {
18
- id: chain
19
- };
20
- const resp = await fetch(createUrl('node/metadata/hash'), {
21
- method: 'POST',
22
- headers: {
23
- 'Content-Type': 'application/json'
24
- },
25
- body: JSON.stringify(data)
26
- });
27
- const rs = await resp.json();
28
- return rs.metadataHash;
17
+ const calculateMetadataHash = (extraInfo, metadataV15) => {
18
+ const _merkleizeMetadata = (0, _merkleizeMetadata2.merkleizeMetadata)(metadataV15, extraInfo);
19
+ return (0, _util.u8aToHex)(_merkleizeMetadata.digest());
29
20
  };
30
- exports.getMetadataHash = getMetadataHash;
31
- const getShortMetadata = async (chain, blob) => {
32
- const data = {
33
- chain: {
34
- id: chain
35
- },
36
- txBlob: blob
37
- };
38
- const resp = await fetch(createUrl('transaction/metadata'), {
39
- method: 'POST',
40
- headers: {
41
- 'Content-Type': 'application/json'
42
- },
43
- body: JSON.stringify(data)
44
- });
45
- const rs = await resp.json();
46
- return rs.txMetadata;
21
+ exports.calculateMetadataHash = calculateMetadataHash;
22
+ const getShortMetadata = (blob, extraInfo, metadata) => {
23
+ const _merkleizeMetadata = (0, _merkleizeMetadata2.merkleizeMetadata)(metadata, extraInfo);
24
+ return (0, _util.u8aToHex)(_merkleizeMetadata.getProofForExtrinsicPayload(blob));
47
25
  };
48
- exports.getShortMetadata = getShortMetadata;
26
+ exports.getShortMetadata = getShortMetadata;
27
+ const cacheMetadata = (chain, substrateApi, chainService) => {
28
+ // Update metadata to database with async methods
29
+ substrateApi.api.isReady.then(async api => {
30
+ const currentSpecVersion = api.runtimeVersion.specVersion.toString();
31
+ const specName = api.runtimeVersion.specName.toString();
32
+ const genesisHash = api.genesisHash.toHex();
33
+ const metadata = await (chainService === null || chainService === void 0 ? void 0 : chainService.getMetadata(chain));
34
+
35
+ // Avoid date existed metadata
36
+ if (metadata && metadata.specVersion === currentSpecVersion && metadata.genesisHash === genesisHash) {
37
+ return;
38
+ }
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();
46
+ }
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);
57
+ }).catch(console.error);
58
+ };
59
+ exports.cacheMetadata = cacheMetadata;
@@ -219,6 +219,8 @@ export default class KoniExtension {
219
219
  private subscribeMantaPayConfig;
220
220
  private subscribeMantaPaySyncState;
221
221
  private findRawMetadata;
222
+ private calculateMetadataHash;
223
+ private shortenMetadata;
222
224
  private resolveDomainByAddress;
223
225
  private resolveAddressByDomain;
224
226
  private addInjects;
@@ -3632,7 +3632,7 @@ export default class KoniExtension {
3632
3632
  };
3633
3633
  }
3634
3634
 
3635
- /// Metadata
3635
+ /* Metadata */
3636
3636
 
3637
3637
  async findRawMetadata({
3638
3638
  genesisHash
@@ -3650,6 +3650,26 @@ export default class KoniExtension {
3650
3650
  userExtensions
3651
3651
  };
3652
3652
  }
3653
+ async calculateMetadataHash({
3654
+ chain
3655
+ }) {
3656
+ const hash = await this.#koniState.calculateMetadataHash(chain);
3657
+ return {
3658
+ metadataHash: hash || ''
3659
+ };
3660
+ }
3661
+ async shortenMetadata({
3662
+ chain,
3663
+ txBlob
3664
+ }) {
3665
+ const shorten = await this.#koniState.shortenMetadata(chain, txBlob);
3666
+ return {
3667
+ txMetadata: shorten || ''
3668
+ };
3669
+ }
3670
+
3671
+ /* Metadata */
3672
+
3653
3673
  async resolveDomainByAddress(request) {
3654
3674
  const chainApi = this.#koniState.getSubstrateApi(request.chain);
3655
3675
  return await resolveAzeroDomainToAddress(request.domain, request.chain, chainApi.api);
@@ -4587,6 +4607,10 @@ export default class KoniExtension {
4587
4607
  // Metadata
4588
4608
  case 'pri(metadata.find)':
4589
4609
  return this.findRawMetadata(request);
4610
+ case 'pri(metadata.hash)':
4611
+ return this.calculateMetadataHash(request);
4612
+ case 'pri(metadata.transaction.shorten)':
4613
+ return this.shortenMetadata(request);
4590
4614
 
4591
4615
  /* Campaign */
4592
4616
  case 'pri(campaign.banner.subscribe)':
@@ -258,6 +258,8 @@ export default class KoniState {
258
258
  types: Record<string, string | Record<string, string>>;
259
259
  userExtensions: import("@polkadot/types/extrinsic/signedExtensions/types").ExtDef | undefined;
260
260
  }>;
261
+ calculateMetadataHash(chain: string): Promise<string | undefined>;
262
+ shortenMetadata(chain: string, txBlob: string): Promise<string | undefined>;
261
263
  getCrowdloanContributions({ address, page, relayChain }: RequestCrowdloanContributions): Promise<import("../../../services/subscan-service/types").CrowdloanContributionsResponse>;
262
264
  }
263
265
  export {};
@@ -1789,7 +1789,8 @@ export default class KoniState {
1789
1789
  return (_this$chainService34 = this.chainService) === null || _this$chainService34 === void 0 ? void 0 : (_this$chainService34$ = _this$chainService34.mantaPay) === null || _this$chainService34$ === void 0 ? void 0 : _this$chainService34$.subscribeSyncState();
1790
1790
  }
1791
1791
 
1792
- // Metadata
1792
+ /* Metadata */
1793
+
1793
1794
  async findMetadata(hash) {
1794
1795
  const metadata = await this.chainService.getMetadataByHash(hash);
1795
1796
  return {
@@ -1799,6 +1800,15 @@ export default class KoniState {
1799
1800
  userExtensions: metadata === null || metadata === void 0 ? void 0 : metadata.userExtensions
1800
1801
  };
1801
1802
  }
1803
+ async calculateMetadataHash(chain) {
1804
+ return this.chainService.calculateMetadataHash(chain);
1805
+ }
1806
+ async shortenMetadata(chain, txBlob) {
1807
+ return this.chainService.shortenMetadata(chain, txBlob);
1808
+ }
1809
+
1810
+ /* Metadata */
1811
+
1802
1812
  getCrowdloanContributions({
1803
1813
  address,
1804
1814
  page,
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.2.15-0",
20
+ "version": "1.2.16-0",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -559,6 +559,11 @@
559
559
  "require": "./cjs/services/balance-service/helpers/subscribe/substrate/equilibrium.js",
560
560
  "default": "./services/balance-service/helpers/subscribe/substrate/equilibrium.js"
561
561
  },
562
+ "./services/balance-service/helpers/subscribe/substrate/gear": {
563
+ "types": "./services/balance-service/helpers/subscribe/substrate/gear.d.ts",
564
+ "require": "./cjs/services/balance-service/helpers/subscribe/substrate/gear.js",
565
+ "default": "./services/balance-service/helpers/subscribe/substrate/gear.js"
566
+ },
562
567
  "./services/balance-service/transfer/smart-contract": {
563
568
  "types": "./services/balance-service/transfer/smart-contract.d.ts",
564
569
  "require": "./cjs/services/balance-service/transfer/smart-contract.js",
@@ -1881,11 +1886,21 @@
1881
1886
  "require": "./cjs/utils/gear/index.js",
1882
1887
  "default": "./utils/gear/index.js"
1883
1888
  },
1889
+ "./utils/gear/combine": {
1890
+ "types": "./utils/gear/combine.d.ts",
1891
+ "require": "./cjs/utils/gear/combine.js",
1892
+ "default": "./utils/gear/combine.js"
1893
+ },
1884
1894
  "./utils/gear/grc20": {
1885
1895
  "types": "./utils/gear/grc20.d.ts",
1886
1896
  "require": "./cjs/utils/gear/grc20.js",
1887
1897
  "default": "./utils/gear/grc20.js"
1888
1898
  },
1899
+ "./utils/gear/vft": {
1900
+ "types": "./utils/gear/vft.d.ts",
1901
+ "require": "./cjs/utils/gear/vft.js",
1902
+ "default": "./utils/gear/vft.js"
1903
+ },
1889
1904
  "./utils/getId": {
1890
1905
  "types": "./utils/getId.d.ts",
1891
1906
  "require": "./cjs/utils/getId.js",
@@ -1969,11 +1984,12 @@
1969
1984
  "@ethereumjs/tx": "^5.1.0",
1970
1985
  "@ethersproject/abi": "^5.7.0",
1971
1986
  "@galacticcouncil/sdk": "^2.1.0",
1972
- "@gear-js/api": "^0.37.2",
1987
+ "@gear-js/api": "^0.38.1",
1973
1988
  "@json-rpc-tools/utils": "^1.7.6",
1974
1989
  "@metamask/safe-event-emitter": "^2.0.0",
1975
1990
  "@metaverse-network-sdk/type-definitions": "^0.0.1-13",
1976
1991
  "@oak-foundation/types": "^0.0.23",
1992
+ "@polkadot-api/merkleize-metadata": "^1.1.0",
1977
1993
  "@polkadot/api": "^11.0.3",
1978
1994
  "@polkadot/api-base": "^10.11.2",
1979
1995
  "@polkadot/api-contract": "^11.0.3",
@@ -1993,11 +2009,11 @@
1993
2009
  "@reduxjs/toolkit": "^1.9.1",
1994
2010
  "@sora-substrate/type-definitions": "^1.17.7",
1995
2011
  "@substrate/connect": "^0.8.9",
1996
- "@subwallet/chain-list": "0.2.74",
1997
- "@subwallet/extension-base": "^1.2.15-0",
1998
- "@subwallet/extension-chains": "^1.2.15-0",
1999
- "@subwallet/extension-dapp": "^1.2.15-0",
2000
- "@subwallet/extension-inject": "^1.2.15-0",
2012
+ "@subwallet/chain-list": "0.2.75",
2013
+ "@subwallet/extension-base": "^1.2.16-0",
2014
+ "@subwallet/extension-chains": "^1.2.16-0",
2015
+ "@subwallet/extension-dapp": "^1.2.16-0",
2016
+ "@subwallet/extension-inject": "^1.2.16-0",
2001
2017
  "@subwallet/keyring": "^0.1.5",
2002
2018
  "@subwallet/ui-keyring": "^0.1.5",
2003
2019
  "@walletconnect/keyvaluestorage": "^1.1.1",
@@ -2026,7 +2042,7 @@
2026
2042
  "moment": "^2.29.4",
2027
2043
  "protobufjs": "^7.2.4",
2028
2044
  "rxjs": "^7.8.1",
2029
- "sails-js": "^0.1.3",
2045
+ "sails-js": "^0.1.6",
2030
2046
  "uuid": "^9.0.0",
2031
2047
  "web3": "^1.10.0",
2032
2048
  "web3-core": "^1.10.0",
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.2.15-0'
10
+ version: '1.2.16-0'
11
11
  };
@@ -82,7 +82,7 @@ export function subscribeBalance(addresses, chains, tokens, _chainAssetMap, _cha
82
82
  const chainSlug = chainInfo.slug;
83
83
  const [useAddresses, notSupportAddresses] = filterAddress(addresses, chainInfo);
84
84
  if (notSupportAddresses.length) {
85
- const tokens = filterAssetsByChainAndType(chainAssetMap, chainSlug, [_AssetType.NATIVE, _AssetType.ERC20, _AssetType.PSP22, _AssetType.LOCAL, _AssetType.GRC20]);
85
+ const tokens = filterAssetsByChainAndType(chainAssetMap, chainSlug, [_AssetType.NATIVE, _AssetType.ERC20, _AssetType.PSP22, _AssetType.LOCAL, _AssetType.GRC20, _AssetType.VFT]);
86
86
  const now = new Date().getTime();
87
87
  Object.values(tokens).forEach(token => {
88
88
  const items = notSupportAddresses.map(address => ({
@@ -0,0 +1,4 @@
1
+ /// <reference types="filesystem" />
2
+ import { SubscribeSubstratePalletBalance } from '@subwallet/extension-base/types';
3
+ export declare const subscribeGRC20Balance: ({ addresses, assetMap, callback, chainInfo, substrateApi }: SubscribeSubstratePalletBalance) => VoidCallback;
4
+ export declare const subscribeVftBalance: ({ addresses, assetMap, callback, chainInfo, substrateApi }: SubscribeSubstratePalletBalance) => VoidCallback;
@@ -0,0 +1,123 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { GearApi } from '@gear-js/api';
5
+ import { _AssetType } from '@subwallet/chain-list/types';
6
+ import { APIItemState } from '@subwallet/extension-base/background/KoniTypes';
7
+ import { SUB_TOKEN_REFRESH_BALANCE_INTERVAL } from '@subwallet/extension-base/constants';
8
+ import { _getContractAddressOfToken } from '@subwallet/extension-base/services/chain-service/utils';
9
+ import { filterAssetsByChainAndType, getGRC20ContractPromise, getVFTContractPromise } from '@subwallet/extension-base/utils';
10
+ import { noop, u8aToHex } from '@polkadot/util';
11
+ import { decodeAddress } from '@polkadot/util-crypto';
12
+ export const subscribeGRC20Balance = ({
13
+ addresses,
14
+ assetMap,
15
+ callback,
16
+ chainInfo,
17
+ substrateApi
18
+ }) => {
19
+ if (!(substrateApi instanceof GearApi)) {
20
+ console.warn('Cannot subscribe GRC20 balance without GearApi instance');
21
+ return noop;
22
+ }
23
+ const chain = chainInfo.slug;
24
+ const grc20ContractMap = {};
25
+ const tokenList = filterAssetsByChainAndType(assetMap, chain, [_AssetType.GRC20]);
26
+ Object.entries(tokenList).forEach(([slug, tokenInfo]) => {
27
+ grc20ContractMap[slug] = getGRC20ContractPromise(substrateApi, _getContractAddressOfToken(tokenInfo));
28
+ });
29
+ const getTokenBalances = () => {
30
+ Object.values(tokenList).map(async tokenInfo => {
31
+ try {
32
+ const contract = grc20ContractMap[tokenInfo.slug];
33
+ const balances = await Promise.all(addresses.map(async address => {
34
+ try {
35
+ const actor = u8aToHex(decodeAddress(address));
36
+ const _balanceOf = await contract.service.balanceOf(actor, address);
37
+ return {
38
+ address: address,
39
+ tokenSlug: tokenInfo.slug,
40
+ free: _balanceOf.toString(10),
41
+ locked: '0',
42
+ state: APIItemState.READY
43
+ };
44
+ } catch (err) {
45
+ console.error(`Error on get balance of account ${address} for token ${tokenInfo.slug}`, err);
46
+ return {
47
+ address: address,
48
+ tokenSlug: tokenInfo.slug,
49
+ free: '0',
50
+ locked: '0',
51
+ state: APIItemState.READY
52
+ };
53
+ }
54
+ }));
55
+ callback(balances);
56
+ } catch (err) {
57
+ console.warn(tokenInfo.slug, err); // TODO: error createType
58
+ }
59
+ });
60
+ };
61
+
62
+ getTokenBalances();
63
+ const interval = setInterval(getTokenBalances, SUB_TOKEN_REFRESH_BALANCE_INTERVAL);
64
+ return () => {
65
+ clearInterval(interval);
66
+ };
67
+ };
68
+ export const subscribeVftBalance = ({
69
+ addresses,
70
+ assetMap,
71
+ callback,
72
+ chainInfo,
73
+ substrateApi
74
+ }) => {
75
+ if (!(substrateApi instanceof GearApi)) {
76
+ console.warn('Cannot subscribe VFT balance without GearApi instance');
77
+ return noop;
78
+ }
79
+ const chain = chainInfo.slug;
80
+ const vftContractMap = {};
81
+ const tokenList = filterAssetsByChainAndType(assetMap, chain, [_AssetType.VFT]);
82
+ Object.entries(tokenList).forEach(([slug, tokenInfo]) => {
83
+ vftContractMap[slug] = getVFTContractPromise(substrateApi, _getContractAddressOfToken(tokenInfo));
84
+ });
85
+ const getTokenBalances = () => {
86
+ Object.values(tokenList).map(async tokenInfo => {
87
+ try {
88
+ const contract = vftContractMap[tokenInfo.slug];
89
+ const balances = await Promise.all(addresses.map(async address => {
90
+ try {
91
+ const actor = u8aToHex(decodeAddress(address));
92
+ const _balanceOf = await contract.service.balanceOf(actor, address);
93
+ return {
94
+ address: address,
95
+ tokenSlug: tokenInfo.slug,
96
+ free: _balanceOf.toString(10),
97
+ locked: '0',
98
+ state: APIItemState.READY
99
+ };
100
+ } catch (err) {
101
+ console.error(`Error on get balance of account ${address} for token ${tokenInfo.slug}`, err);
102
+ return {
103
+ address: address,
104
+ tokenSlug: tokenInfo.slug,
105
+ free: '0',
106
+ locked: '0',
107
+ state: APIItemState.READY
108
+ };
109
+ }
110
+ }));
111
+ callback(balances);
112
+ } catch (err) {
113
+ console.warn(tokenInfo.slug, err); // TODO: error createType
114
+ }
115
+ });
116
+ };
117
+
118
+ getTokenBalances();
119
+ const interval = setInterval(getTokenBalances, SUB_TOKEN_REFRESH_BALANCE_INTERVAL);
120
+ return () => {
121
+ clearInterval(interval);
122
+ };
123
+ };
@@ -1,7 +1,6 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { GearApi } from '@gear-js/api';
5
4
  import { _AssetType } from '@subwallet/chain-list/types';
6
5
  import { APIItemState } from '@subwallet/extension-base/background/KoniTypes';
7
6
  import { SUB_TOKEN_REFRESH_BALANCE_INTERVAL } from '@subwallet/extension-base/constants';
@@ -12,13 +11,13 @@ import { getPSP22ContractPromise } from '@subwallet/extension-base/koni/api/cont
12
11
  import { getDefaultWeightV2 } from '@subwallet/extension-base/koni/api/contract-handler/wasm/utils';
13
12
  import { _BALANCE_CHAIN_GROUP, _MANTA_ZK_CHAIN_GROUP, _ZK_ASSET_PREFIX } from '@subwallet/extension-base/services/chain-service/constants';
14
13
  import { _checkSmartContractSupportByChain, _getChainExistentialDeposit, _getChainNativeTokenSlug, _getContractAddressOfToken, _getTokenOnChainAssetId, _getTokenOnChainInfo, _getTokenTypesSupportedByChain, _getXcmAssetMultilocation, _isBridgedToken, _isChainEvmCompatible, _isSubstrateRelayChain } from '@subwallet/extension-base/services/chain-service/utils';
15
- import { filterAssetsByChainAndType, getGRC20ContractPromise } from '@subwallet/extension-base/utils';
14
+ import { filterAssetsByChainAndType } from '@subwallet/extension-base/utils';
16
15
  import BigN from 'bignumber.js';
17
16
  import { combineLatest, Observable } from 'rxjs';
18
- import { BN, BN_ZERO, noop, u8aToHex } from '@polkadot/util';
19
- import { decodeAddress } from '@polkadot/util-crypto';
17
+ import { BN, BN_ZERO } from '@polkadot/util';
20
18
  import { subscribeERC20Interval } from "../evm.js";
21
19
  import { subscribeEquilibriumTokenBalance } from "./equilibrium.js";
20
+ import { subscribeGRC20Balance, subscribeVftBalance } from "./gear.js";
22
21
  export const subscribeSubstrateBalance = async (addresses, chainInfo, assetMap, substrateApi, evmApi, callback, extrinsicType) => {
23
22
  let unsubNativeToken;
24
23
  let unsubLocalToken;
@@ -26,6 +25,7 @@ export const subscribeSubstrateBalance = async (addresses, chainInfo, assetMap,
26
25
  let unsubWasmContractToken;
27
26
  let unsubBridgedToken;
28
27
  let unsubGrcToken;
28
+ let unsubVftToken;
29
29
  const chain = chainInfo.slug;
30
30
  const baseParams = {
31
31
  addresses,
@@ -82,17 +82,22 @@ export const subscribeSubstrateBalance = async (addresses, chainInfo, assetMap,
82
82
  // Get sub-token for substrate-based chains
83
83
  unsubGrcToken = subscribeGRC20Balance(substrateParams);
84
84
  }
85
+ if (_checkSmartContractSupportByChain(chainInfo, _AssetType.VFT)) {
86
+ // Get sub-token for substrate-based chains
87
+ unsubVftToken = subscribeVftBalance(substrateParams);
88
+ }
85
89
  } catch (err) {
86
90
  console.warn(err);
87
91
  }
88
92
  return () => {
89
- var _unsubGrcToken;
93
+ var _unsubGrcToken, _unsubVftToken;
90
94
  unsubNativeToken && unsubNativeToken();
91
95
  unsubLocalToken && unsubLocalToken();
92
96
  unsubEvmContractToken && unsubEvmContractToken();
93
97
  unsubWasmContractToken && unsubWasmContractToken();
94
98
  unsubBridgedToken && unsubBridgedToken();
95
99
  (_unsubGrcToken = unsubGrcToken) === null || _unsubGrcToken === void 0 ? void 0 : _unsubGrcToken();
100
+ (_unsubVftToken = unsubVftToken) === null || _unsubVftToken === void 0 ? void 0 : _unsubVftToken();
96
101
  };
97
102
  };
98
103
 
@@ -421,60 +426,4 @@ const subscribeOrmlTokensPallet = async ({
421
426
  }).catch(console.error);
422
427
  });
423
428
  };
424
- };
425
- const subscribeGRC20Balance = ({
426
- addresses,
427
- assetMap,
428
- callback,
429
- chainInfo,
430
- substrateApi
431
- }) => {
432
- if (!(substrateApi instanceof GearApi)) {
433
- console.warn('Cannot subscribe VFT balance without GearApi instance');
434
- return noop;
435
- }
436
- const chain = chainInfo.slug;
437
- const psp22ContractMap = {};
438
- const tokenList = filterAssetsByChainAndType(assetMap, chain, [_AssetType.GRC20]);
439
- Object.entries(tokenList).forEach(([slug, tokenInfo]) => {
440
- psp22ContractMap[slug] = getGRC20ContractPromise(substrateApi, _getContractAddressOfToken(tokenInfo));
441
- });
442
- const getTokenBalances = () => {
443
- Object.values(tokenList).map(async tokenInfo => {
444
- try {
445
- const contract = psp22ContractMap[tokenInfo.slug];
446
- const balances = await Promise.all(addresses.map(async address => {
447
- try {
448
- const actor = u8aToHex(decodeAddress(address));
449
- const _balanceOf = await contract.balanceOf(actor, address);
450
- return {
451
- address: address,
452
- tokenSlug: tokenInfo.slug,
453
- free: _balanceOf.toString(10),
454
- locked: '0',
455
- state: APIItemState.READY
456
- };
457
- } catch (err) {
458
- console.error(`Error on get balance of account ${address} for token ${tokenInfo.slug}`, err);
459
- return {
460
- address: address,
461
- tokenSlug: tokenInfo.slug,
462
- free: '0',
463
- locked: '0',
464
- state: APIItemState.READY
465
- };
466
- }
467
- }));
468
- callback(balances);
469
- } catch (err) {
470
- console.warn(tokenInfo.slug, err); // TODO: error createType
471
- }
472
- });
473
- };
474
-
475
- getTokenBalances();
476
- const interval = setInterval(getTokenBalances, SUB_TOKEN_REFRESH_BALANCE_INTERVAL);
477
- return () => {
478
- clearInterval(interval);
479
- };
480
429
  };
@@ -2,12 +2,13 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { GearApi } from '@gear-js/api';
5
+ import { _AssetType } from '@subwallet/chain-list/types';
5
6
  import { getPSP22ContractPromise } from '@subwallet/extension-base/koni/api/contract-handler/wasm';
6
7
  import { getWasmContractGasLimit } from '@subwallet/extension-base/koni/api/contract-handler/wasm/utils';
7
8
  import { _TRANSFER_CHAIN_GROUP } from '@subwallet/extension-base/services/chain-service/constants';
8
9
  import { _getContractAddressOfToken, _getTokenOnChainAssetId, _getTokenOnChainInfo, _getXcmAssetMultilocation, _isBridgedToken, _isChainEvmCompatible, _isNativeToken, _isTokenGearSmartContract, _isTokenTransferredByEvm, _isTokenWasmSmartContract } from '@subwallet/extension-base/services/chain-service/utils';
9
10
  import { calculateGasFeeParams } from '@subwallet/extension-base/services/fee-service/utils';
10
- import { getGRC20ContractPromise } from '@subwallet/extension-base/utils';
11
+ import { getGRC20ContractPromise, getVFTContractPromise } from '@subwallet/extension-base/utils';
11
12
  import BigN from 'bignumber.js';
12
13
  import { BN, u8aToHex } from '@polkadot/util';
13
14
  import { decodeAddress } from '@polkadot/util-crypto';
@@ -53,12 +54,12 @@ export const createTransferExtrinsic = async ({
53
54
  }, to, value, {});
54
55
  transferAmount = value;
55
56
  } else if (_isTokenGearSmartContract(tokenInfo) && api instanceof GearApi) {
56
- const contractPromise = getGRC20ContractPromise(api, _getContractAddressOfToken(tokenInfo));
57
- const transaction = await contractPromise.transfer(u8aToHex(decodeAddress(to)), BigInt(value)) // Create transfer transaction
57
+ const contractPromise = tokenInfo.assetType === _AssetType.GRC20 ? getGRC20ContractPromise(api, _getContractAddressOfToken(tokenInfo)) : getVFTContractPromise(api, _getContractAddressOfToken(tokenInfo));
58
+ const transaction = await contractPromise.service.transfer(u8aToHex(decodeAddress(to)), value) // Create transfer transaction
58
59
  .withAccount(from) // Set sender account
59
60
  .calculateGas(); // Add account arg to extrinsic
60
61
 
61
- transfer = transaction.tx;
62
+ transfer = transaction.extrinsic;
62
63
  transferAmount = value;
63
64
  } else if (_TRANSFER_CHAIN_GROUP.acala.includes(networkKey)) {
64
65
  if (!_isNativeToken(tokenInfo)) {
@@ -39,7 +39,7 @@ export declare class SubstrateApi implements _SubstrateApi {
39
39
  constructor(chainSlug: string, apiUrl: string, { externalApiPromise, metadata, providerName }?: _ApiOptions);
40
40
  get isReady(): Promise<_SubstrateApi>;
41
41
  updateApiUrl(apiUrl: string): Promise<void>;
42
- connect(): void;
42
+ connect(_callbackUpdateMetadata?: (substrateApi: _SubstrateApi) => void): void;
43
43
  disconnect(): Promise<void>;
44
44
  recoverConnect(): Promise<void>;
45
45
  destroy(): Promise<void>;
@@ -159,14 +159,16 @@ export class SubstrateApi {
159
159
  this.provider = this.createProvider(apiUrl);
160
160
  this.api = this.createApi(this.provider);
161
161
  }
162
- connect() {
162
+ connect(_callbackUpdateMetadata) {
163
163
  if (this.api.isConnected) {
164
164
  this.updateConnectionStatus(_ChainConnectionStatus.CONNECTED);
165
+ _callbackUpdateMetadata === null || _callbackUpdateMetadata === void 0 ? void 0 : _callbackUpdateMetadata(this);
165
166
  } else {
166
167
  this.updateConnectionStatus(_ChainConnectionStatus.CONNECTING);
167
168
  this.api.connect().then(() => {
168
169
  this.api.isReady.then(() => {
169
170
  this.updateConnectionStatus(_ChainConnectionStatus.CONNECTED);
171
+ _callbackUpdateMetadata === null || _callbackUpdateMetadata === void 0 ? void 0 : _callbackUpdateMetadata(this);
170
172
  }).catch(console.error);
171
173
  }).catch(console.error);
172
174
  }
@@ -19,6 +19,7 @@ export declare class SubstrateChainHandler extends AbstractChainHandler {
19
19
  private getPsp22TokenInfo;
20
20
  private getPsp34TokenInfo;
21
21
  private getGrc20TokenInfo;
22
+ private getVftTokenInfo;
22
23
  getSubstrateContractTokenInfo(contractAddress: string, tokenType: _AssetType, originChain: string, contractCaller?: string): Promise<_SmartContractTokenInfo>;
23
24
  setSubstrateApi(chainSlug: string, substrateApi: SubstrateApi): void;
24
25
  destroySubstrateApi(chainSlug: string): void;