@subwallet/extension-base 1.0.4-1 → 1.0.5-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/background/KoniTypes.d.ts +12 -1
- package/background/KoniTypes.js +1 -0
- package/background/errors/TransactionError.js +4 -0
- package/background/handlers/State.d.ts +1 -1
- package/background/handlers/State.js +2 -8
- package/background/handlers/subscriptions.js +0 -1
- package/background/types.d.ts +2 -2
- package/cjs/background/KoniTypes.js +1 -0
- package/cjs/background/errors/TransactionError.js +4 -0
- package/cjs/background/handlers/State.js +1 -7
- package/cjs/background/handlers/subscriptions.js +0 -1
- package/cjs/constants/index.js +6 -6
- package/cjs/koni/api/coingecko.js +1 -4
- package/cjs/koni/api/dotsama/balance.js +7 -5
- package/cjs/koni/api/dotsama/crowdloan.js +0 -4
- package/cjs/koni/api/dotsama/transfer.js +0 -4
- package/cjs/koni/api/nft/acala_nft/index.js +1 -1
- package/cjs/koni/api/nft/bit.country/index.js +1 -1
- package/cjs/koni/api/nft/evm_nft/index.js +2 -3
- package/cjs/koni/api/nft/index.js +1 -2
- package/cjs/koni/api/nft/karura_nft/index.js +1 -1
- package/cjs/koni/api/nft/quartz_nft/index.js +1 -1
- package/cjs/koni/api/nft/rmrk_nft/index.js +2 -3
- package/cjs/koni/api/nft/statemine_nft/index.js +1 -1
- package/cjs/koni/api/nft/transfer.js +5 -5
- package/cjs/koni/api/nft/unique_nft/index.js +1 -1
- package/cjs/koni/api/nft/unique_nft/uniqueNftV2.js +0 -1
- package/cjs/koni/api/nft/wasm_nft/index.js +1 -2
- package/cjs/koni/api/staking/bonding/astar.js +28 -12
- package/cjs/koni/api/staking/bonding/utils.js +4 -0
- package/cjs/koni/api/staking/relayChain.js +0 -1
- package/cjs/koni/api/staking/subsquidStaking.js +0 -2
- package/cjs/koni/api/tokens/wasm/index.js +0 -1
- package/cjs/koni/api/tokens/wasm/utils.js +0 -1
- package/cjs/koni/api/xcm/index.js +0 -1
- package/cjs/koni/background/cron.js +0 -45
- package/cjs/koni/background/handlers/Extension.js +163 -133
- package/cjs/koni/background/handlers/State.js +18 -3
- package/cjs/koni/background/handlers/Tabs.js +34 -2
- package/cjs/koni/background/handlers/index.js +3 -2
- package/cjs/koni/background/subscription.js +0 -26
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/chain-service/handler/EvmChainHandler.js +1 -1
- package/cjs/services/chain-service/handler/SubstrateChainHandler.js +2 -9
- package/cjs/services/chain-service/handler/light-client/index.js +9 -6
- package/cjs/services/chain-service/index.js +0 -2
- package/cjs/services/chain-service/utils.js +3 -0
- package/cjs/services/history-service/helpers/recoverHistoryStatus.js +108 -0
- package/cjs/services/history-service/index.js +60 -5
- package/cjs/services/history-service/subsquid-multi-chain-history.js +3 -2
- package/cjs/services/history-service/testChainMap.js +724 -0
- package/cjs/services/keyring-service/index.js +0 -2
- package/cjs/services/migration-service/index.js +0 -3
- package/cjs/services/migration-service/scripts/MigrateAutoLock.js +30 -0
- package/cjs/services/migration-service/scripts/MigrateChainPatrol.js +30 -0
- package/cjs/services/migration-service/scripts/index.js +5 -1
- package/cjs/services/price-service/coingecko.js +1 -1
- package/cjs/services/price-service/index.js +0 -3
- package/cjs/services/request-service/handler/AuthRequestHandler.js +1 -1
- package/cjs/services/setting-service/constants.js +8 -2
- package/cjs/services/storage-service/DatabaseService.js +2 -44
- package/cjs/services/transaction-service/constants.js +11 -0
- package/cjs/services/transaction-service/index.js +28 -9
- package/cjs/services/transaction-service/utils.js +25 -14
- package/constants/index.d.ts +1 -1
- package/constants/index.js +1 -1
- package/koni/api/coingecko.js +1 -4
- package/koni/api/dotsama/balance.js +7 -5
- package/koni/api/dotsama/crowdloan.js +0 -4
- package/koni/api/dotsama/transfer.js +0 -4
- package/koni/api/nft/acala_nft/index.js +1 -1
- package/koni/api/nft/bit.country/index.js +1 -1
- package/koni/api/nft/evm_nft/index.js +2 -3
- package/koni/api/nft/index.js +1 -2
- package/koni/api/nft/karura_nft/index.js +1 -1
- package/koni/api/nft/quartz_nft/index.js +1 -1
- package/koni/api/nft/rmrk_nft/index.js +2 -3
- package/koni/api/nft/statemine_nft/index.js +1 -1
- package/koni/api/nft/transfer.js +5 -5
- package/koni/api/nft/unique_nft/index.js +1 -1
- package/koni/api/nft/unique_nft/uniqueNftV2.js +0 -1
- package/koni/api/nft/wasm_nft/index.js +1 -2
- package/koni/api/staking/bonding/astar.d.ts +2 -1
- package/koni/api/staking/bonding/astar.js +27 -12
- package/koni/api/staking/bonding/utils.js +4 -0
- package/koni/api/staking/relayChain.js +0 -1
- package/koni/api/staking/subsquidStaking.js +0 -2
- package/koni/api/tokens/wasm/index.js +0 -1
- package/koni/api/tokens/wasm/utils.js +0 -1
- package/koni/api/xcm/index.js +0 -1
- package/koni/background/cron.js +0 -45
- package/koni/background/handlers/Extension.d.ts +2 -0
- package/koni/background/handlers/Extension.js +78 -50
- package/koni/background/handlers/State.d.ts +3 -1
- package/koni/background/handlers/State.js +18 -3
- package/koni/background/handlers/Tabs.d.ts +1 -0
- package/koni/background/handlers/Tabs.js +32 -1
- package/koni/background/handlers/index.js +3 -2
- package/koni/background/subscription.d.ts +0 -1
- package/koni/background/subscription.js +0 -26
- package/package.json +55 -34
- package/packageInfo.js +1 -1
- package/services/chain-service/handler/EvmChainHandler.js +1 -1
- package/services/chain-service/handler/SubstrateChainHandler.js +2 -9
- package/services/chain-service/handler/light-client/index.js +8 -6
- package/services/chain-service/helper/api-helper/spec/acala.d.ts +3 -3
- package/services/chain-service/index.js +0 -2
- package/services/chain-service/utils.js +3 -0
- package/services/history-service/helpers/recoverHistoryStatus.d.ts +11 -0
- package/services/history-service/helpers/recoverHistoryStatus.js +98 -0
- package/services/history-service/index.d.ts +6 -0
- package/services/history-service/index.js +61 -6
- package/services/history-service/subsquid-multi-chain-history.js +3 -2
- package/services/history-service/testChainMap.d.ts +3 -0
- package/services/history-service/testChainMap.js +716 -0
- package/services/keyring-service/index.js +0 -2
- package/services/migration-service/index.js +0 -3
- package/services/migration-service/scripts/MigrateAutoLock.d.ts +4 -0
- package/services/migration-service/scripts/MigrateAutoLock.js +22 -0
- package/services/migration-service/scripts/MigrateChainPatrol.d.ts +4 -0
- package/services/migration-service/scripts/MigrateChainPatrol.js +22 -0
- package/services/migration-service/scripts/index.js +5 -1
- package/services/price-service/coingecko.js +1 -1
- package/services/price-service/index.js +0 -3
- package/services/request-service/handler/AuthRequestHandler.js +1 -1
- package/services/setting-service/constants.d.ts +4 -2
- package/services/setting-service/constants.js +5 -1
- package/services/storage-service/DatabaseService.js +2 -44
- package/services/transaction-service/constants.d.ts +1 -0
- package/services/transaction-service/constants.js +4 -0
- package/services/transaction-service/index.d.ts +1 -0
- package/services/transaction-service/index.js +29 -10
- package/services/transaction-service/utils.d.ts +1 -1
- package/services/transaction-service/utils.js +24 -13
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"./cjs/detectPackage.js"
|
|
18
18
|
],
|
|
19
19
|
"type": "module",
|
|
20
|
-
"version": "1.0.
|
|
20
|
+
"version": "1.0.5-1",
|
|
21
21
|
"main": "./cjs/index.js",
|
|
22
22
|
"module": "./index.js",
|
|
23
23
|
"types": "./index.d.ts",
|
|
@@ -1190,11 +1190,21 @@
|
|
|
1190
1190
|
"require": "./cjs/services/history-service/index.js",
|
|
1191
1191
|
"default": "./services/history-service/index.js"
|
|
1192
1192
|
},
|
|
1193
|
+
"./services/history-service/helpers/recoverHistoryStatus": {
|
|
1194
|
+
"types": "./services/history-service/helpers/recoverHistoryStatus.d.ts",
|
|
1195
|
+
"require": "./cjs/services/history-service/helpers/recoverHistoryStatus.js",
|
|
1196
|
+
"default": "./services/history-service/helpers/recoverHistoryStatus.js"
|
|
1197
|
+
},
|
|
1193
1198
|
"./services/history-service/subsquid-multi-chain-history": {
|
|
1194
1199
|
"types": "./services/history-service/subsquid-multi-chain-history.d.ts",
|
|
1195
1200
|
"require": "./cjs/services/history-service/subsquid-multi-chain-history.js",
|
|
1196
1201
|
"default": "./services/history-service/subsquid-multi-chain-history.js"
|
|
1197
1202
|
},
|
|
1203
|
+
"./services/history-service/testChainMap": {
|
|
1204
|
+
"types": "./services/history-service/testChainMap.d.ts",
|
|
1205
|
+
"require": "./cjs/services/history-service/testChainMap.js",
|
|
1206
|
+
"default": "./services/history-service/testChainMap.js"
|
|
1207
|
+
},
|
|
1198
1208
|
"./services/keyring-service": {
|
|
1199
1209
|
"types": "./services/keyring-service/index.d.ts",
|
|
1200
1210
|
"require": "./cjs/services/keyring-service/index.js",
|
|
@@ -1230,6 +1240,16 @@
|
|
|
1230
1240
|
"require": "./cjs/services/migration-service/scripts/MigrateAuthUrls.js",
|
|
1231
1241
|
"default": "./services/migration-service/scripts/MigrateAuthUrls.js"
|
|
1232
1242
|
},
|
|
1243
|
+
"./services/migration-service/scripts/MigrateAutoLock": {
|
|
1244
|
+
"types": "./services/migration-service/scripts/MigrateAutoLock.d.ts",
|
|
1245
|
+
"require": "./cjs/services/migration-service/scripts/MigrateAutoLock.js",
|
|
1246
|
+
"default": "./services/migration-service/scripts/MigrateAutoLock.js"
|
|
1247
|
+
},
|
|
1248
|
+
"./services/migration-service/scripts/MigrateChainPatrol": {
|
|
1249
|
+
"types": "./services/migration-service/scripts/MigrateChainPatrol.d.ts",
|
|
1250
|
+
"require": "./cjs/services/migration-service/scripts/MigrateChainPatrol.js",
|
|
1251
|
+
"default": "./services/migration-service/scripts/MigrateChainPatrol.js"
|
|
1252
|
+
},
|
|
1233
1253
|
"./services/migration-service/scripts/MigrateImportedToken": {
|
|
1234
1254
|
"types": "./services/migration-service/scripts/MigrateImportedToken.d.ts",
|
|
1235
1255
|
"require": "./cjs/services/migration-service/scripts/MigrateImportedToken.js",
|
|
@@ -1435,6 +1455,11 @@
|
|
|
1435
1455
|
"require": "./cjs/services/transaction-service/index.js",
|
|
1436
1456
|
"default": "./services/transaction-service/index.js"
|
|
1437
1457
|
},
|
|
1458
|
+
"./services/transaction-service/constants": {
|
|
1459
|
+
"types": "./services/transaction-service/constants.d.ts",
|
|
1460
|
+
"require": "./cjs/services/transaction-service/constants.js",
|
|
1461
|
+
"default": "./services/transaction-service/constants.js"
|
|
1462
|
+
},
|
|
1438
1463
|
"./services/transaction-service/event-parser": {
|
|
1439
1464
|
"types": "./services/transaction-service/event-parser/index.d.ts",
|
|
1440
1465
|
"require": "./cjs/services/transaction-service/event-parser/index.js",
|
|
@@ -1617,8 +1642,8 @@
|
|
|
1617
1642
|
}
|
|
1618
1643
|
},
|
|
1619
1644
|
"dependencies": {
|
|
1620
|
-
"@acala-network/api": "^
|
|
1621
|
-
"@acala-network/type-definitions": "^
|
|
1645
|
+
"@acala-network/api": "^5.0.2",
|
|
1646
|
+
"@acala-network/type-definitions": "^5.0.2",
|
|
1622
1647
|
"@apollo/client": "^3.7.14",
|
|
1623
1648
|
"@babel/runtime": "^7.20.6",
|
|
1624
1649
|
"@bifrost-finance/type-definitions": "^1.7.2",
|
|
@@ -1628,7 +1653,7 @@
|
|
|
1628
1653
|
"@digitalnative/type-definitions": "^1.1.27",
|
|
1629
1654
|
"@docknetwork/node-types": "^0.15.0",
|
|
1630
1655
|
"@edgeware/node-types": "^3.6.2-wako",
|
|
1631
|
-
"@equilab/api": "^1.14.
|
|
1656
|
+
"@equilab/api": "^1.14.25",
|
|
1632
1657
|
"@equilab/definitions": "^1.4.18",
|
|
1633
1658
|
"@ethereumjs/common": "^2.6.5",
|
|
1634
1659
|
"@ethereumjs/tx": "^4.0.2",
|
|
@@ -1639,47 +1664,43 @@
|
|
|
1639
1664
|
"@fortawesome/free-solid-svg-icons": "^6.2.1",
|
|
1640
1665
|
"@fortawesome/react-fontawesome": "^0.2.0",
|
|
1641
1666
|
"@google/model-viewer": "^2.0.2",
|
|
1642
|
-
"@interlay/interbtc-types": "^1.
|
|
1643
|
-
"@kiltprotocol/type-definitions": "^0.
|
|
1667
|
+
"@interlay/interbtc-types": "^1.12.0",
|
|
1668
|
+
"@kiltprotocol/type-definitions": "^0.32.0",
|
|
1644
1669
|
"@laminar/type-definitions": "^0.3.1",
|
|
1645
1670
|
"@metamask/safe-event-emitter": "^2.0.0",
|
|
1646
1671
|
"@metaverse-network-sdk/type-definitions": "^0.0.1-13",
|
|
1647
1672
|
"@oak-foundation/api-augment": "^0.0.23",
|
|
1648
1673
|
"@oak-foundation/types": "^0.0.23",
|
|
1649
|
-
"@parallel-finance/type-definitions": "^1.7.
|
|
1650
|
-
"@phala/typedefs": "^0.2.
|
|
1651
|
-
"@polkadot/api": "^
|
|
1652
|
-
"@polkadot/api-contract": "^
|
|
1653
|
-
"@polkadot/api-derive": "^
|
|
1654
|
-
"@polkadot/hw-ledger": "^
|
|
1655
|
-
"@polkadot/
|
|
1656
|
-
"@polkadot/
|
|
1657
|
-
"@polkadot/
|
|
1658
|
-
"@polkadot/
|
|
1659
|
-
"@polkadot/
|
|
1660
|
-
"@polkadot/
|
|
1661
|
-
"@polkadot/
|
|
1662
|
-
"@polkadot/
|
|
1663
|
-
"@polkadot/ui-keyring": "^2.9.14",
|
|
1664
|
-
"@polkadot/ui-settings": "^2.9.14",
|
|
1665
|
-
"@polkadot/util": "^10.2.1",
|
|
1666
|
-
"@polkadot/util-crypto": "^10.2.1",
|
|
1674
|
+
"@parallel-finance/type-definitions": "^1.7.17",
|
|
1675
|
+
"@phala/typedefs": "^0.2.33",
|
|
1676
|
+
"@polkadot/api": "^10.7.1",
|
|
1677
|
+
"@polkadot/api-contract": "^10.7.1",
|
|
1678
|
+
"@polkadot/api-derive": "^10.7.1",
|
|
1679
|
+
"@polkadot/hw-ledger": "^12.2.1",
|
|
1680
|
+
"@polkadot/networks": "^12.2.1",
|
|
1681
|
+
"@polkadot/phishing": "^0.21.3",
|
|
1682
|
+
"@polkadot/rpc-provider": "^10.7.1",
|
|
1683
|
+
"@polkadot/types": "^10.7.1",
|
|
1684
|
+
"@polkadot/types-augment": "^10.7.1",
|
|
1685
|
+
"@polkadot/ui-settings": "^3.4.1",
|
|
1686
|
+
"@polkadot/util": "^12.2.1",
|
|
1687
|
+
"@polkadot/util-crypto": "^12.2.1",
|
|
1667
1688
|
"@polymathnetwork/polymesh-types": "^0.0.2",
|
|
1668
1689
|
"@ramonak/react-progress-bar": "^5.0.3",
|
|
1669
1690
|
"@reduxjs/toolkit": "^1.9.1",
|
|
1670
1691
|
"@snowfork/snowbridge-types": "^0.2.7",
|
|
1671
|
-
"@sora-substrate/type-definitions": "^1.
|
|
1692
|
+
"@sora-substrate/type-definitions": "^1.17.7",
|
|
1672
1693
|
"@subsocial/types": "^0.6.8",
|
|
1673
|
-
"@substrate/connect": "^0.7.
|
|
1694
|
+
"@substrate/connect": "^0.7.26",
|
|
1674
1695
|
"@subwallet/chain-list": "^0.1.2",
|
|
1675
|
-
"@subwallet/extension-base": "^1.0.
|
|
1676
|
-
"@subwallet/extension-chains": "^1.0.
|
|
1677
|
-
"@subwallet/extension-dapp": "^1.0.
|
|
1678
|
-
"@subwallet/extension-inject": "^1.0.
|
|
1679
|
-
"@subwallet/keyring": "^0.0.
|
|
1680
|
-
"@subwallet/ui-keyring": "^0.0.
|
|
1696
|
+
"@subwallet/extension-base": "^1.0.5-1",
|
|
1697
|
+
"@subwallet/extension-chains": "^1.0.5-1",
|
|
1698
|
+
"@subwallet/extension-dapp": "^1.0.5-1",
|
|
1699
|
+
"@subwallet/extension-inject": "^1.0.5-1",
|
|
1700
|
+
"@subwallet/keyring": "^0.0.9",
|
|
1701
|
+
"@subwallet/ui-keyring": "^0.0.9",
|
|
1681
1702
|
"@unique-nft/types": "^0.6.0-4",
|
|
1682
|
-
"@zeitgeistpm/type-defs": "^0.
|
|
1703
|
+
"@zeitgeistpm/type-defs": "^1.0.0",
|
|
1683
1704
|
"@zeroio/type-definitions": "^0.0.14",
|
|
1684
1705
|
"axios": "^1.2.1",
|
|
1685
1706
|
"bignumber.js": "^9.1.1",
|
|
@@ -1701,7 +1722,7 @@
|
|
|
1701
1722
|
"is-buffer": "^2.0.5",
|
|
1702
1723
|
"json-rpc-engine": "^6.1.0",
|
|
1703
1724
|
"moment": "^2.29.4",
|
|
1704
|
-
"moonbeam-types-bundle": "^2.0.
|
|
1725
|
+
"moonbeam-types-bundle": "^2.0.10",
|
|
1705
1726
|
"phosphor-react": "^1.4.1",
|
|
1706
1727
|
"pontem-types-bundle": "^1.0.15",
|
|
1707
1728
|
"protobufjs": "^7.1.2",
|
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.0.
|
|
10
|
+
version: '1.0.5-1'
|
|
11
11
|
};
|
|
@@ -30,7 +30,6 @@ export class SubstrateChainHandler {
|
|
|
30
30
|
resumeAllApis() {
|
|
31
31
|
return Promise.all(Object.values(this.getSubstrateApiMap()).map(async substrateApi => {
|
|
32
32
|
if (!substrateApi.api.isConnected && substrateApi.api.connect) {
|
|
33
|
-
this.logger.log(`[Substrate] Resuming network [${substrateApi.specName}]`);
|
|
34
33
|
await substrateApi.api.connect();
|
|
35
34
|
}
|
|
36
35
|
}));
|
|
@@ -39,7 +38,6 @@ export class SubstrateChainHandler {
|
|
|
39
38
|
return Promise.all(Object.values(this.getSubstrateApiMap()).map(async substrateApi => {
|
|
40
39
|
if (substrateApi.api.isConnected) {
|
|
41
40
|
var _substrateApi$api, _substrateApi$api2;
|
|
42
|
-
this.logger.log(`[Substrate] Stopping network [${substrateApi.chainSlug}]`);
|
|
43
41
|
((_substrateApi$api = substrateApi.api) === null || _substrateApi$api === void 0 ? void 0 : _substrateApi$api.disconnect) && (await ((_substrateApi$api2 = substrateApi.api) === null || _substrateApi$api2 === void 0 ? void 0 : _substrateApi$api2.disconnect()));
|
|
44
42
|
}
|
|
45
43
|
}));
|
|
@@ -97,7 +95,6 @@ export class SubstrateChainHandler {
|
|
|
97
95
|
gasLimit: getDefaultWeightV2(substrateApi.api)
|
|
98
96
|
})]);
|
|
99
97
|
if (!(nameResp.result.isOk && symbolResp.result.isOk && decimalsResp.result.isOk) || !nameResp.output || !decimalsResp.output || !symbolResp.output) {
|
|
100
|
-
this.logger.error('Error response while validating WASM contract');
|
|
101
98
|
return {
|
|
102
99
|
name: '',
|
|
103
100
|
decimals: -1,
|
|
@@ -124,7 +121,6 @@ export class SubstrateChainHandler {
|
|
|
124
121
|
}); // read-only operation so no gas limit
|
|
125
122
|
|
|
126
123
|
if (!collectionIdResp.result.isOk || !collectionIdResp.output) {
|
|
127
|
-
this.logger.error('Error response while validating WASM contract');
|
|
128
124
|
return {
|
|
129
125
|
name: '',
|
|
130
126
|
decimals: -1,
|
|
@@ -149,7 +145,7 @@ export class SubstrateChainHandler {
|
|
|
149
145
|
contractError
|
|
150
146
|
};
|
|
151
147
|
} catch (e) {
|
|
152
|
-
this.logger.error(
|
|
148
|
+
this.logger.error(e);
|
|
153
149
|
return {
|
|
154
150
|
name: '',
|
|
155
151
|
decimals: -1,
|
|
@@ -215,7 +211,6 @@ export class SubstrateChainHandler {
|
|
|
215
211
|
defaultFormatBalance: undefined,
|
|
216
212
|
recoverConnect: () => {
|
|
217
213
|
substrateApi.apiRetry = 0;
|
|
218
|
-
this.logger.log('Recover connect to ', apiUrl);
|
|
219
214
|
provider.connect().then(this.logger.log).catch(this.logger.error);
|
|
220
215
|
},
|
|
221
216
|
get isReady() {
|
|
@@ -237,7 +232,6 @@ export class SubstrateChainHandler {
|
|
|
237
232
|
}
|
|
238
233
|
};
|
|
239
234
|
api.on('connected', () => {
|
|
240
|
-
this.logger.log('Substrate API connected to ', apiUrl);
|
|
241
235
|
substrateApi.apiRetry = 0;
|
|
242
236
|
if (substrateApi.isApiReadyOnce) {
|
|
243
237
|
substrateApi.isApiReady = true;
|
|
@@ -255,7 +249,6 @@ export class SubstrateChainHandler {
|
|
|
255
249
|
}
|
|
256
250
|
});
|
|
257
251
|
api.on('ready', () => {
|
|
258
|
-
this.logger.log('Substrate API ready with', apiUrl);
|
|
259
252
|
this.loadOnReady(registry, api).then(rs => {
|
|
260
253
|
objectSpread(substrateApi, rs);
|
|
261
254
|
}).catch(error => {
|
|
@@ -307,7 +300,7 @@ export class SubstrateChainHandler {
|
|
|
307
300
|
const tokenSymbol = properties.tokenSymbol.unwrapOr([formatBalance.getDefaults().unit, ...DEFAULT_AUX]);
|
|
308
301
|
const tokenDecimals = properties.tokenDecimals.unwrapOr([DEFAULT_DECIMALS]);
|
|
309
302
|
const isDevelopment = systemChainType.isDevelopment || systemChainType.isLocal || isTestChain(systemChain);
|
|
310
|
-
this.logger.log(`
|
|
303
|
+
this.logger.log(`Connected to ${systemChain} (${systemChainType.toString()}), ${stringify(properties)}`);
|
|
311
304
|
|
|
312
305
|
// explicitly override the ss58Format as specified
|
|
313
306
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
import * as Sc from '@substrate/connect';
|
|
5
|
+
import { WellKnownChain } from '@substrate/connect';
|
|
4
6
|
import { ScProvider } from '@polkadot/rpc-provider';
|
|
5
7
|
export const relayChainSpecs = {
|
|
6
|
-
kusama:
|
|
7
|
-
polkadot:
|
|
8
|
-
rococo:
|
|
9
|
-
westend:
|
|
8
|
+
kusama: WellKnownChain.ksmcc3,
|
|
9
|
+
polkadot: WellKnownChain.polkadot,
|
|
10
|
+
rococo: WellKnownChain.rococo_v2_2,
|
|
11
|
+
westend: WellKnownChain.westend2
|
|
10
12
|
};
|
|
11
13
|
|
|
12
14
|
// Direct get spec data from @polkadot/react-api repository
|
|
@@ -97,14 +99,14 @@ class ProviderPlaceholder {
|
|
|
97
99
|
export function getSubstrateConnectProvider(specLink) {
|
|
98
100
|
const [relayName, paraName] = specLink.split('/');
|
|
99
101
|
const relaySpec = relayChainSpecs[relayName];
|
|
100
|
-
const relayProvider = new ScProvider(relaySpec);
|
|
102
|
+
const relayProvider = new ScProvider(Sc, relaySpec);
|
|
101
103
|
if (!paraName) {
|
|
102
104
|
return relayProvider;
|
|
103
105
|
}
|
|
104
106
|
const paraChainData = paraChainSpecs[specLink];
|
|
105
107
|
let scProvider;
|
|
106
108
|
const scPromise = fetch(paraChainData).then(rs => rs.text()).then(spec => {
|
|
107
|
-
scProvider = new ScProvider(
|
|
109
|
+
scProvider = new ScProvider(Sc, spec);
|
|
108
110
|
return scProvider;
|
|
109
111
|
}).catch(console.error);
|
|
110
112
|
return new ProviderPlaceholder(scPromise);
|
|
@@ -5,7 +5,7 @@ declare const _default: {
|
|
|
5
5
|
council: string[];
|
|
6
6
|
};
|
|
7
7
|
types: {
|
|
8
|
-
minmax: [
|
|
8
|
+
minmax: number[] | [(number | undefined)?, (number | undefined)?] | [number, number];
|
|
9
9
|
types: {
|
|
10
10
|
Keys: string;
|
|
11
11
|
};
|
|
@@ -18,7 +18,7 @@ declare const _default: {
|
|
|
18
18
|
council: string[];
|
|
19
19
|
};
|
|
20
20
|
types: {
|
|
21
|
-
minmax: [
|
|
21
|
+
minmax: number[] | [(number | undefined)?, (number | undefined)?] | [number, number];
|
|
22
22
|
types: {
|
|
23
23
|
Keys: string;
|
|
24
24
|
};
|
|
@@ -31,7 +31,7 @@ declare const _default: {
|
|
|
31
31
|
council: string[];
|
|
32
32
|
};
|
|
33
33
|
types: {
|
|
34
|
-
minmax: [
|
|
34
|
+
minmax: number[] | [(number | undefined)?, (number | undefined)?] | [number, number];
|
|
35
35
|
types: {
|
|
36
36
|
Keys: string;
|
|
37
37
|
};
|
|
@@ -358,7 +358,6 @@ export class ChainService {
|
|
|
358
358
|
this.assetRegistrySubject.next(this.getAssetRegistry());
|
|
359
359
|
this.initApis();
|
|
360
360
|
await this.initAssetSettings();
|
|
361
|
-
this.logger.log('Initiated chains, assets and APIs');
|
|
362
361
|
}
|
|
363
362
|
initApis() {
|
|
364
363
|
// TODO: this might be async
|
|
@@ -1140,7 +1139,6 @@ export class ChainService {
|
|
|
1140
1139
|
});
|
|
1141
1140
|
await Promise.all(promiseList);
|
|
1142
1141
|
if (update) {
|
|
1143
|
-
console.log('Update chain connection state');
|
|
1144
1142
|
this.chainStateMapSubject.next(chainStateMap);
|
|
1145
1143
|
}
|
|
1146
1144
|
}
|
|
@@ -285,6 +285,9 @@ export function _getAssetDecimals(assetInfo) {
|
|
|
285
285
|
}
|
|
286
286
|
export function _getBlockExplorerFromChain(chainInfo) {
|
|
287
287
|
let blockExplorer;
|
|
288
|
+
if (!chainInfo) {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
288
291
|
if (_isPureEvmChain(chainInfo)) {
|
|
289
292
|
var _chainInfo$evmInfo4;
|
|
290
293
|
blockExplorer = chainInfo === null || chainInfo === void 0 ? void 0 : (_chainInfo$evmInfo4 = chainInfo.evmInfo) === null || _chainInfo$evmInfo4 === void 0 ? void 0 : _chainInfo$evmInfo4.blockExplorer;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { TransactionHistoryItem } from '@subwallet/extension-base/background/KoniTypes';
|
|
2
|
+
import { ChainService } from '@subwallet/extension-base/services/chain-service';
|
|
3
|
+
export declare enum HistoryRecoverStatus {
|
|
4
|
+
SUCCESS = "SUCCESS",
|
|
5
|
+
FAILED = "FAILED",
|
|
6
|
+
API_INACTIVE = "API_INACTIVE",
|
|
7
|
+
LACK_INFO = "LACK_INFO",
|
|
8
|
+
FAIL_DETECT = "FAIL_DETECT",
|
|
9
|
+
UNKNOWN = "UNKNOWN"
|
|
10
|
+
}
|
|
11
|
+
export declare const historyRecover: (history: TransactionHistoryItem, chainService: ChainService) => Promise<HistoryRecoverStatus>;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-koni authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
export let HistoryRecoverStatus;
|
|
5
|
+
(function (HistoryRecoverStatus) {
|
|
6
|
+
HistoryRecoverStatus["SUCCESS"] = "SUCCESS";
|
|
7
|
+
HistoryRecoverStatus["FAILED"] = "FAILED";
|
|
8
|
+
HistoryRecoverStatus["API_INACTIVE"] = "API_INACTIVE";
|
|
9
|
+
HistoryRecoverStatus["LACK_INFO"] = "LACK_INFO";
|
|
10
|
+
HistoryRecoverStatus["FAIL_DETECT"] = "FAIL_DETECT";
|
|
11
|
+
HistoryRecoverStatus["UNKNOWN"] = "UNKNOWN";
|
|
12
|
+
})(HistoryRecoverStatus || (HistoryRecoverStatus = {}));
|
|
13
|
+
const substrateRecover = async (history, chainService) => {
|
|
14
|
+
const {
|
|
15
|
+
blockHash,
|
|
16
|
+
chain,
|
|
17
|
+
extrinsicHash
|
|
18
|
+
} = history;
|
|
19
|
+
try {
|
|
20
|
+
const substrateApi = chainService.getSubstrateApi(chain);
|
|
21
|
+
if (substrateApi) {
|
|
22
|
+
const _api = await substrateApi.isReady;
|
|
23
|
+
const api = _api.api;
|
|
24
|
+
if (!blockHash) {
|
|
25
|
+
console.log(`Fail to find extrinsic ${extrinsicHash} on ${chain}: No block hash`);
|
|
26
|
+
return HistoryRecoverStatus.LACK_INFO;
|
|
27
|
+
}
|
|
28
|
+
const block = await api.rpc.chain.getBlock(blockHash);
|
|
29
|
+
const allEvents = await api.query.system.events.at(blockHash);
|
|
30
|
+
const extrinsics = block.block.extrinsics;
|
|
31
|
+
let index;
|
|
32
|
+
extrinsics.forEach((extrinsic, _idx) => {
|
|
33
|
+
if (extrinsicHash === extrinsic.hash.toHex()) {
|
|
34
|
+
index = _idx;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
if (index === undefined) {
|
|
38
|
+
console.log(`Fail to find extrinsic ${extrinsicHash} on ${chain}`);
|
|
39
|
+
return HistoryRecoverStatus.FAIL_DETECT;
|
|
40
|
+
}
|
|
41
|
+
const events = allEvents.filter(({
|
|
42
|
+
phase
|
|
43
|
+
}) => phase.isApplyExtrinsic && phase.asApplyExtrinsic.eq(index));
|
|
44
|
+
for (const {
|
|
45
|
+
event
|
|
46
|
+
} of events) {
|
|
47
|
+
if (api.events.system.ExtrinsicSuccess.is(event)) {
|
|
48
|
+
return HistoryRecoverStatus.SUCCESS;
|
|
49
|
+
} else if (api.events.system.ExtrinsicFailed.is(event)) {
|
|
50
|
+
return HistoryRecoverStatus.FAILED;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return HistoryRecoverStatus.FAIL_DETECT;
|
|
54
|
+
} else {
|
|
55
|
+
console.error(`Fail to update history ${chain}-${extrinsicHash}: Api not active`);
|
|
56
|
+
return HistoryRecoverStatus.API_INACTIVE;
|
|
57
|
+
}
|
|
58
|
+
} catch (e) {
|
|
59
|
+
console.error(`Fail to update history ${chain}-${extrinsicHash}:`, e.message);
|
|
60
|
+
return HistoryRecoverStatus.UNKNOWN;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const evmRecover = async (history, chainService) => {
|
|
64
|
+
const {
|
|
65
|
+
chain,
|
|
66
|
+
extrinsicHash
|
|
67
|
+
} = history;
|
|
68
|
+
try {
|
|
69
|
+
const evmApi = chainService.getEvmApi(chain);
|
|
70
|
+
if (evmApi) {
|
|
71
|
+
const _api = await evmApi.isReady;
|
|
72
|
+
const api = _api.api;
|
|
73
|
+
const block = await api.eth.getTransactionReceipt(extrinsicHash);
|
|
74
|
+
return block.status ? HistoryRecoverStatus.SUCCESS : HistoryRecoverStatus.FAILED;
|
|
75
|
+
} else {
|
|
76
|
+
console.error(`Fail to update history ${chain}-${extrinsicHash}: Api not active`);
|
|
77
|
+
return HistoryRecoverStatus.API_INACTIVE;
|
|
78
|
+
}
|
|
79
|
+
} catch (e) {
|
|
80
|
+
console.error(`Fail to update history ${chain}-${extrinsicHash}:`, e.message);
|
|
81
|
+
return HistoryRecoverStatus.UNKNOWN;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// undefined: Cannot check status
|
|
86
|
+
// true: Transaction success
|
|
87
|
+
// false: Transaction failed
|
|
88
|
+
export const historyRecover = async (history, chainService) => {
|
|
89
|
+
const {
|
|
90
|
+
chainType
|
|
91
|
+
} = history;
|
|
92
|
+
if (chainType) {
|
|
93
|
+
const checkFunction = chainType === 'substrate' ? substrateRecover : evmRecover;
|
|
94
|
+
return await checkFunction(history, chainService);
|
|
95
|
+
} else {
|
|
96
|
+
return HistoryRecoverStatus.LACK_INFO;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
@@ -6,6 +6,7 @@ import { KeyringService } from '@subwallet/extension-base/services/keyring-servi
|
|
|
6
6
|
import DatabaseService from '@subwallet/extension-base/services/storage-service/DatabaseService';
|
|
7
7
|
import { BehaviorSubject } from 'rxjs';
|
|
8
8
|
export declare class HistoryService implements StoppableServiceInterface, PersistDataServiceInterface, CronServiceInterface {
|
|
9
|
+
#private;
|
|
9
10
|
private dbService;
|
|
10
11
|
private chainService;
|
|
11
12
|
private eventService;
|
|
@@ -14,6 +15,7 @@ export declare class HistoryService implements StoppableServiceInterface, Persis
|
|
|
14
15
|
constructor(dbService: DatabaseService, chainService: ChainService, eventService: EventService, keyringService: KeyringService);
|
|
15
16
|
private fetchPromise;
|
|
16
17
|
private interval;
|
|
18
|
+
private recoverInterval;
|
|
17
19
|
private fetchAndLoadHistories;
|
|
18
20
|
getHistories(): Promise<TransactionHistoryItem<import("@subwallet/extension-base/background/KoniTypes").ExtrinsicType.TRANSFER_BALANCE>[]>;
|
|
19
21
|
getHistorySubject(): Promise<BehaviorSubject<TransactionHistoryItem<import("@subwallet/extension-base/background/KoniTypes").ExtrinsicType.TRANSFER_BALANCE>[]>>;
|
|
@@ -27,12 +29,16 @@ export declare class HistoryService implements StoppableServiceInterface, Persis
|
|
|
27
29
|
persistData(): Promise<void>;
|
|
28
30
|
startCron(): Promise<void>;
|
|
29
31
|
stopCron(): Promise<void>;
|
|
32
|
+
startRecoverHistories(): Promise<void>;
|
|
33
|
+
stopRecoverHistories(): Promise<void>;
|
|
34
|
+
recoverHistories(): Promise<void>;
|
|
30
35
|
startPromiseHandler: {
|
|
31
36
|
resolve: (value: void) => void;
|
|
32
37
|
reject: (reason?: unknown) => void;
|
|
33
38
|
promise: Promise<void>;
|
|
34
39
|
};
|
|
35
40
|
init(): Promise<void>;
|
|
41
|
+
getProcessingHistory(): Promise<void>;
|
|
36
42
|
start(): Promise<void>;
|
|
37
43
|
waitForStarted(): Promise<void>;
|
|
38
44
|
stopPromiseHandler: {
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-base
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { ExtrinsicStatus } from '@subwallet/extension-base/background/KoniTypes';
|
|
5
|
+
import { CRON_RECOVER_HISTORY_INTERVAL, CRON_REFRESH_HISTORY_INTERVAL } from '@subwallet/extension-base/constants';
|
|
5
6
|
import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
|
|
7
|
+
import { historyRecover, HistoryRecoverStatus } from '@subwallet/extension-base/services/history-service/helpers/recoverHistoryStatus';
|
|
6
8
|
import { createPromiseHandler } from '@subwallet/extension-base/utils/promise';
|
|
7
9
|
import { keyring } from '@subwallet/ui-keyring';
|
|
8
10
|
import { BehaviorSubject } from 'rxjs';
|
|
9
11
|
import { fetchMultiChainHistories } from "./subsquid-multi-chain-history.js";
|
|
10
12
|
export class HistoryService {
|
|
11
13
|
historySubject = new BehaviorSubject([]);
|
|
14
|
+
#processingHistories = {};
|
|
12
15
|
constructor(dbService, chainService, eventService, keyringService) {
|
|
13
16
|
this.dbService = dbService;
|
|
14
17
|
this.chainService = chainService;
|
|
@@ -18,6 +21,7 @@ export class HistoryService {
|
|
|
18
21
|
}
|
|
19
22
|
fetchPromise = null;
|
|
20
23
|
interval = undefined;
|
|
24
|
+
recoverInterval = undefined;
|
|
21
25
|
async fetchAndLoadHistories(addresses) {
|
|
22
26
|
if (!addresses || addresses.length === 0) {
|
|
23
27
|
return [];
|
|
@@ -88,9 +92,6 @@ export class HistoryService {
|
|
|
88
92
|
});
|
|
89
93
|
const updateRecords = historyItems.filter(item => {
|
|
90
94
|
const key = `${item.chain}-${item.extrinsicHash}`;
|
|
91
|
-
|
|
92
|
-
// !excludeKeys.includes(key) && console.log('Cancel update', key);
|
|
93
|
-
|
|
94
95
|
return item.origin === 'app' || !excludeKeys.includes(key);
|
|
95
96
|
});
|
|
96
97
|
await this.dbService.upsertHistory(updateRecords);
|
|
@@ -119,12 +120,56 @@ export class HistoryService {
|
|
|
119
120
|
this.fetchPromise = null;
|
|
120
121
|
return Promise.resolve();
|
|
121
122
|
}
|
|
123
|
+
async startRecoverHistories() {
|
|
124
|
+
await this.recoverHistories();
|
|
125
|
+
this.recoverInterval = setInterval(() => {
|
|
126
|
+
this.recoverHistories().catch(console.error);
|
|
127
|
+
}, CRON_RECOVER_HISTORY_INTERVAL);
|
|
128
|
+
}
|
|
129
|
+
stopRecoverHistories() {
|
|
130
|
+
clearInterval(this.recoverInterval);
|
|
131
|
+
return Promise.resolve();
|
|
132
|
+
}
|
|
133
|
+
async recoverHistories() {
|
|
134
|
+
const list = [];
|
|
135
|
+
for (const processingHistory of Object.values(this.#processingHistories)) {
|
|
136
|
+
const chainState = this.chainService.getChainStateByKey(processingHistory.chain);
|
|
137
|
+
if (chainState.active) {
|
|
138
|
+
list.push(processingHistory);
|
|
139
|
+
}
|
|
140
|
+
if (list.length >= 10) {
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const promises = list.map(history => historyRecover(history, this.chainService));
|
|
145
|
+
const result = await Promise.all(promises);
|
|
146
|
+
result.forEach((status, index) => {
|
|
147
|
+
const extrinsicHash = list[index].extrinsicHash;
|
|
148
|
+
switch (status) {
|
|
149
|
+
case HistoryRecoverStatus.API_INACTIVE:
|
|
150
|
+
break;
|
|
151
|
+
case HistoryRecoverStatus.FAILED:
|
|
152
|
+
case HistoryRecoverStatus.SUCCESS:
|
|
153
|
+
this.updateHistoryByExtrinsicHash(extrinsicHash, {
|
|
154
|
+
status: status === HistoryRecoverStatus.SUCCESS ? ExtrinsicStatus.SUCCESS : ExtrinsicStatus.FAIL
|
|
155
|
+
}).catch(console.error);
|
|
156
|
+
delete this.#processingHistories[extrinsicHash];
|
|
157
|
+
break;
|
|
158
|
+
default:
|
|
159
|
+
delete this.#processingHistories[extrinsicHash];
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
if (!Object.keys(this.#processingHistories).length) {
|
|
163
|
+
await this.stopRecoverHistories();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
122
166
|
startPromiseHandler = createPromiseHandler();
|
|
123
167
|
async init() {
|
|
124
168
|
this.status = ServiceStatus.INITIALIZING;
|
|
125
169
|
await this.loadData();
|
|
126
170
|
Promise.all([this.eventService.waitKeyringReady, this.eventService.waitChainReady]).then(() => {
|
|
127
171
|
this.getHistories().catch(console.log);
|
|
172
|
+
this.getProcessingHistory().catch(console.log);
|
|
128
173
|
this.eventService.on('account.add', () => {
|
|
129
174
|
(async () => {
|
|
130
175
|
await this.stopCron();
|
|
@@ -137,12 +182,22 @@ export class HistoryService {
|
|
|
137
182
|
}).catch(console.error);
|
|
138
183
|
this.status = ServiceStatus.INITIALIZED;
|
|
139
184
|
}
|
|
185
|
+
async getProcessingHistory() {
|
|
186
|
+
const histories = await this.dbService.getHistories();
|
|
187
|
+
this.#processingHistories = {};
|
|
188
|
+
histories.filter(history => {
|
|
189
|
+
return history.status === 'processing';
|
|
190
|
+
}).forEach(history => {
|
|
191
|
+
this.#processingHistories[history.extrinsicHash] = history;
|
|
192
|
+
});
|
|
193
|
+
this.startRecoverHistories().catch(console.error);
|
|
194
|
+
}
|
|
140
195
|
async start() {
|
|
141
196
|
try {
|
|
142
|
-
console.debug('Start history service');
|
|
143
197
|
this.startPromiseHandler = createPromiseHandler();
|
|
144
198
|
this.status = ServiceStatus.STARTING;
|
|
145
199
|
await this.startCron();
|
|
200
|
+
await this.startRecoverHistories();
|
|
146
201
|
this.status = ServiceStatus.STARTED;
|
|
147
202
|
this.startPromiseHandler.resolve();
|
|
148
203
|
} catch (e) {
|
|
@@ -154,12 +209,12 @@ export class HistoryService {
|
|
|
154
209
|
}
|
|
155
210
|
stopPromiseHandler = createPromiseHandler();
|
|
156
211
|
async stop() {
|
|
157
|
-
console.debug('Stop history service');
|
|
158
212
|
try {
|
|
159
213
|
this.stopPromiseHandler = createPromiseHandler();
|
|
160
214
|
this.status = ServiceStatus.STOPPING;
|
|
161
215
|
await this.persistData();
|
|
162
216
|
await this.stopCron();
|
|
217
|
+
await this.stopRecoverHistories();
|
|
163
218
|
this.stopPromiseHandler.resolve();
|
|
164
219
|
this.status = ServiceStatus.STOPPED;
|
|
165
220
|
} catch (e) {
|
|
@@ -110,7 +110,7 @@ export function parseSubsquidTransactionData(address, type, historyItem, chainIn
|
|
|
110
110
|
const parsedArgs = args;
|
|
111
111
|
const transaction = data.call.data.args.transaction.value;
|
|
112
112
|
to = autoFormatAddress(parsedArgs.to);
|
|
113
|
-
from = autoFormatAddress(parsedArgs.from);
|
|
113
|
+
from = autoFormatAddress(parsedArgs.from || address);
|
|
114
114
|
extrinsicHash = parsedArgs.transactionHash || extrinsic.hash;
|
|
115
115
|
amount = transaction.value || '0';
|
|
116
116
|
fee = (parseInt(transaction.gasPrice) * parseInt(transaction.gasLimit)).toString();
|
|
@@ -244,7 +244,8 @@ export async function fetchMultiChainHistories(addresses, chainMap, maxPage = 25
|
|
|
244
244
|
const usedAddresses = relatedAddresses.filter(a => lowerAddresses.includes(a.toLowerCase()));
|
|
245
245
|
const chainInfo = chainMap[chainId];
|
|
246
246
|
if (chainInfo === undefined) {
|
|
247
|
-
console.warn(`Not found chain info for chain id: ${chainId}`);
|
|
247
|
+
console.warn(`Not found chain info for chain id: ${chainId}`); // TODO: resolve conflicting chainId
|
|
248
|
+
|
|
248
249
|
return;
|
|
249
250
|
}
|
|
250
251
|
usedAddresses.forEach(address => {
|