@subwallet/extension-base 1.0.2-2 → 1.0.3-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.
- package/background/KoniTypes.d.ts +56 -40
- package/background/KoniTypes.js +11 -9
- package/background/errors/TransactionError.js +25 -1
- package/background/types.d.ts +10 -5
- package/cjs/background/KoniTypes.js +11 -9
- package/cjs/background/errors/TransactionError.js +24 -0
- package/cjs/constants/index.js +8 -26
- package/cjs/koni/api/dotsama/balance.js +49 -224
- package/cjs/koni/api/dotsama/transfer.js +34 -39
- package/cjs/koni/api/nft/acala_nft/index.js +7 -7
- package/cjs/koni/api/nft/bit.country/index.js +7 -6
- package/cjs/koni/api/nft/evm_nft/index.js +8 -3
- package/cjs/koni/api/nft/index.js +3 -6
- package/cjs/koni/api/nft/karura_nft/index.js +7 -6
- package/cjs/koni/api/nft/rmrk_nft/index.js +11 -1
- package/cjs/koni/api/nft/statemine_nft/index.js +7 -6
- package/cjs/koni/api/nft/unique_nft/index.js +5 -1
- package/cjs/koni/api/nft/wasm_nft/index.js +170 -111
- package/cjs/koni/api/nft/wasm_nft/utils.js +11 -7
- package/cjs/koni/api/staking/bonding/amplitude.js +13 -9
- package/cjs/koni/api/staking/bonding/astar.js +15 -13
- package/cjs/koni/api/staking/bonding/index.js +22 -10
- package/cjs/koni/api/staking/bonding/paraChain.js +85 -2
- package/cjs/koni/api/staking/bonding/relayChain.js +122 -16
- package/cjs/koni/api/staking/bonding/utils.js +27 -8
- package/cjs/koni/api/tokens/wasm/index.js +5 -4
- package/cjs/koni/api/tokens/wasm/utils.js +63 -0
- package/cjs/koni/api/xcm/polkadotXcm.js +1 -1
- package/cjs/koni/api/xcm/utils.js +18 -13
- package/cjs/koni/api/xcm/xTokens.js +1 -1
- package/cjs/koni/api/xcm/xcmPallet.js +9 -6
- package/cjs/koni/background/cron.js +171 -61
- package/cjs/koni/background/handlers/Extension.js +391 -207
- package/cjs/koni/background/handlers/State.js +49 -34
- package/cjs/koni/background/handlers/Tabs.js +50 -17
- package/cjs/koni/background/subscription.js +53 -28
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/base/types.js +20 -0
- package/cjs/services/chain-service/handler/SubstrateChainHandler.js +13 -8
- package/cjs/services/chain-service/index.js +73 -49
- package/cjs/services/event-service/index.js +5 -1
- package/cjs/services/event-service/types.js +11 -1
- package/cjs/services/history-service/index.js +101 -50
- package/cjs/services/history-service/subsquid-multi-chain-history.js +13 -10
- package/cjs/services/keyring-service/index.js +11 -13
- package/cjs/services/migration-service/scripts/MigrateImportedToken.js +2 -1
- package/cjs/services/price-service/coingecko.js +0 -1
- package/cjs/services/price-service/index.js +71 -24
- package/cjs/services/request-service/handler/AuthRequestHandler.js +13 -7
- package/cjs/services/request-service/handler/EvmRequestHandler.js +8 -12
- package/cjs/services/request-service/index.js +14 -5
- package/cjs/services/storage-service/DatabaseService.js +66 -34
- package/cjs/services/storage-service/db-stores/Nft.js +7 -15
- package/cjs/services/storage-service/db-stores/Transaction.js +6 -10
- package/cjs/services/transaction-service/event-parser/index.js +20 -48
- package/cjs/services/transaction-service/index.js +104 -48
- package/cjs/services/transaction-service/utils.js +10 -8
- package/cjs/utils/address.js +10 -1
- package/cjs/utils/index.js +9 -15
- package/cjs/utils/promise.js +26 -0
- package/constants/index.d.ts +7 -13
- package/constants/index.js +7 -13
- package/koni/api/dotsama/balance.d.ts +0 -1
- package/koni/api/dotsama/balance.js +22 -197
- package/koni/api/dotsama/transfer.js +11 -16
- package/koni/api/nft/acala_nft/index.js +7 -7
- package/koni/api/nft/bit.country/index.js +7 -6
- package/koni/api/nft/evm_nft/index.js +7 -3
- package/koni/api/nft/index.d.ts +1 -2
- package/koni/api/nft/index.js +3 -6
- package/koni/api/nft/karura_nft/index.js +7 -6
- package/koni/api/nft/nft.d.ts +1 -0
- package/koni/api/nft/rmrk_nft/index.js +11 -1
- package/koni/api/nft/statemine_nft/index.js +7 -6
- package/koni/api/nft/unique_nft/index.js +5 -1
- package/koni/api/nft/wasm_nft/index.d.ts +0 -2
- package/koni/api/nft/wasm_nft/index.js +168 -109
- package/koni/api/nft/wasm_nft/utils.d.ts +7 -5
- package/koni/api/nft/wasm_nft/utils.js +7 -5
- package/koni/api/staking/bonding/amplitude.d.ts +0 -1
- package/koni/api/staking/bonding/amplitude.js +15 -10
- package/koni/api/staking/bonding/astar.js +8 -6
- package/koni/api/staking/bonding/index.d.ts +4 -1
- package/koni/api/staking/bonding/index.js +23 -13
- package/koni/api/staking/bonding/paraChain.d.ts +3 -0
- package/koni/api/staking/bonding/paraChain.js +86 -5
- package/koni/api/staking/bonding/relayChain.d.ts +5 -1
- package/koni/api/staking/bonding/relayChain.js +121 -18
- package/koni/api/staking/bonding/utils.d.ts +3 -2
- package/koni/api/staking/bonding/utils.js +27 -9
- package/koni/api/tokens/wasm/index.js +5 -4
- package/koni/api/tokens/wasm/utils.d.ts +6 -0
- package/koni/api/tokens/wasm/utils.js +54 -0
- package/koni/api/xcm/polkadotXcm.js +2 -2
- package/koni/api/xcm/utils.d.ts +5 -6
- package/koni/api/xcm/utils.js +15 -10
- package/koni/api/xcm/xTokens.js +2 -2
- package/koni/api/xcm/xcmPallet.js +10 -9
- package/koni/background/cron.d.ts +6 -1
- package/koni/background/cron.js +172 -62
- package/koni/background/handlers/Extension.d.ts +9 -3
- package/koni/background/handlers/Extension.js +306 -126
- package/koni/background/handlers/State.d.ts +5 -6
- package/koni/background/handlers/State.js +51 -34
- package/koni/background/handlers/Tabs.js +50 -17
- package/koni/background/subscription.d.ts +2 -0
- package/koni/background/subscription.js +51 -29
- package/package.json +29 -14
- package/packageInfo.js +1 -1
- package/services/base/types.d.ts +34 -0
- package/services/base/types.js +15 -0
- package/services/chain-service/handler/SubstrateChainHandler.js +14 -9
- package/services/chain-service/helper/psp22_abi.json +1041 -881
- package/services/chain-service/helper/psp34_abi.json +2963 -1807
- package/services/chain-service/index.d.ts +5 -2
- package/services/chain-service/index.js +68 -45
- package/services/chain-service/types.d.ts +1 -0
- package/services/event-service/index.js +5 -1
- package/services/event-service/types.d.ts +5 -9
- package/services/event-service/types.js +4 -1
- package/services/history-service/index.d.ts +28 -7
- package/services/history-service/index.js +101 -50
- package/services/history-service/subsquid-multi-chain-history.js +16 -12
- package/services/keyring-service/index.d.ts +4 -2
- package/services/keyring-service/index.js +11 -13
- package/services/migration-service/scripts/MigrateImportedToken.js +2 -1
- package/services/price-service/coingecko.js +0 -1
- package/services/price-service/index.d.ts +22 -1
- package/services/price-service/index.js +71 -24
- package/services/request-service/handler/AuthRequestHandler.d.ts +3 -1
- package/services/request-service/handler/AuthRequestHandler.js +13 -7
- package/services/request-service/handler/EvmRequestHandler.js +8 -12
- package/services/request-service/index.d.ts +3 -1
- package/services/request-service/index.js +14 -5
- package/services/storage-service/DatabaseService.d.ts +2 -0
- package/services/storage-service/DatabaseService.js +66 -34
- package/services/storage-service/db-stores/Nft.d.ts +2 -2
- package/services/storage-service/db-stores/Nft.js +7 -14
- package/services/storage-service/db-stores/Transaction.d.ts +2 -0
- package/services/storage-service/db-stores/Transaction.js +6 -10
- package/services/transaction-service/event-parser/index.js +21 -49
- package/services/transaction-service/index.d.ts +2 -0
- package/services/transaction-service/index.js +86 -32
- package/services/transaction-service/types.d.ts +2 -0
- package/services/transaction-service/utils.js +10 -8
- package/utils/address.d.ts +3 -0
- package/utils/address.js +8 -1
- package/utils/index.d.ts +2 -2
- package/utils/index.js +7 -13
- package/utils/promise.d.ts +6 -0
- package/utils/promise.js +20 -0
|
@@ -19,7 +19,6 @@ export declare class ChainService {
|
|
|
19
19
|
private store;
|
|
20
20
|
private assetSettingSubject;
|
|
21
21
|
private logger;
|
|
22
|
-
private refreshChainStateTimeout;
|
|
23
22
|
constructor(dbService: DatabaseService, eventService: EventService);
|
|
24
23
|
getXcmRefMap(): Record<string, _AssetRef>;
|
|
25
24
|
getEvmApi(slug: string): _EvmApi;
|
|
@@ -92,8 +91,10 @@ export declare class ChainService {
|
|
|
92
91
|
refreshEvmApi(slug: string): void;
|
|
93
92
|
stopAllChainApis(): Promise<void[]>;
|
|
94
93
|
resumeAllChainApis(): Promise<void[]>;
|
|
94
|
+
private refreshChainStateTimeout;
|
|
95
|
+
private refreshChainStateTimes;
|
|
95
96
|
private refreshChainStateInterval;
|
|
96
|
-
|
|
97
|
+
updateApiMapStatus(): Promise<void>;
|
|
97
98
|
initAssetSettings(): Promise<void>;
|
|
98
99
|
setAssetSettings(assetSettings: Record<string, AssetSetting>, emitEvent?: boolean): void;
|
|
99
100
|
getStoreAssetSettings(): Promise<Record<string, AssetSetting>>;
|
|
@@ -101,4 +102,6 @@ export declare class ChainService {
|
|
|
101
102
|
updateAssetSetting(assetSlug: string, assetSetting: AssetSetting): Promise<boolean | undefined>;
|
|
102
103
|
updateAssetSettingByChain(chainSlug: string, visible: boolean): Promise<void>;
|
|
103
104
|
subscribeAssetSettings(): BehaviorSubject<Record<string, AssetSetting>>;
|
|
105
|
+
getChainLogoMap(): Promise<Record<string, string>>;
|
|
106
|
+
getAssetLogoMap(): Promise<Record<string, string>>;
|
|
104
107
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import { AssetRefMap, ChainAssetMap, ChainInfoMap, MultiChainAssetMap } from '@subwallet/chain-list';
|
|
4
|
+
import { AssetLogoMap, AssetRefMap, ChainAssetMap, ChainInfoMap, ChainLogoMap, MultiChainAssetMap } from '@subwallet/chain-list';
|
|
5
5
|
import { _AssetRefPath, _AssetType, _ChainStatus, _SubstrateChainType } from '@subwallet/chain-list/types';
|
|
6
|
-
import { CRON_GET_API_MAP_STATUS } from '@subwallet/extension-base/constants';
|
|
7
6
|
import { _DEFAULT_ACTIVE_CHAINS } from '@subwallet/extension-base/services/chain-service/constants';
|
|
8
7
|
import { EvmChainHandler } from '@subwallet/extension-base/services/chain-service/handler/EvmChainHandler';
|
|
9
8
|
import { SubstrateChainHandler } from '@subwallet/extension-base/services/chain-service/handler/SubstrateChainHandler';
|
|
@@ -44,7 +43,7 @@ export class ChainService {
|
|
|
44
43
|
this.multiChainAssetMapSubject.next(MultiChainAssetMap);
|
|
45
44
|
this.xcmRefMapSubject.next(this.getXcmRefMap());
|
|
46
45
|
this.logger = createLogger('chain-service');
|
|
47
|
-
this.refreshChainStateInterval(3000);
|
|
46
|
+
this.refreshChainStateInterval(3000, 6);
|
|
48
47
|
}
|
|
49
48
|
|
|
50
49
|
// Getter
|
|
@@ -150,7 +149,8 @@ export class ChainService {
|
|
|
150
149
|
priceId: '',
|
|
151
150
|
slug: '',
|
|
152
151
|
symbol: '',
|
|
153
|
-
hasValue: true
|
|
152
|
+
hasValue: true,
|
|
153
|
+
icon: ''
|
|
154
154
|
};
|
|
155
155
|
for (const assetInfo of Object.values(this.getAssetRegistry())) {
|
|
156
156
|
if (assetInfo.assetType === _AssetType.NATIVE && assetInfo.originChain === chainSlug) {
|
|
@@ -277,7 +277,7 @@ export class ChainService {
|
|
|
277
277
|
this.dbService.removeFromChainStore([slug]).catch(console.error);
|
|
278
278
|
this.updateChainSubscription();
|
|
279
279
|
this.lockChainInfoMap = false;
|
|
280
|
-
this.eventService.emit('chain.
|
|
280
|
+
this.eventService.emit('chain.updateState', slug);
|
|
281
281
|
return true;
|
|
282
282
|
}
|
|
283
283
|
resetChainInfoMap(excludedChains) {
|
|
@@ -343,7 +343,7 @@ export class ChainService {
|
|
|
343
343
|
this.dbService.removeFromAssetStore(targetAssets).catch(e => this.logger.error(e));
|
|
344
344
|
this.assetRegistrySubject.next(assetRegistry);
|
|
345
345
|
targetAssets.forEach(assetSlug => {
|
|
346
|
-
this.eventService.emit('asset.
|
|
346
|
+
this.eventService.emit('asset.updateState', assetSlug);
|
|
347
347
|
});
|
|
348
348
|
}
|
|
349
349
|
|
|
@@ -407,14 +407,14 @@ export class ChainService {
|
|
|
407
407
|
this.lockChainInfoMap = true;
|
|
408
408
|
chainStateMap[chainSlug].active = true;
|
|
409
409
|
this.initApiForChain(chainInfo);
|
|
410
|
-
this.refreshChainStateInterval(
|
|
410
|
+
this.refreshChainStateInterval(3000, 6);
|
|
411
411
|
this.dbService.updateChainStore({
|
|
412
412
|
...chainInfo,
|
|
413
413
|
active: true,
|
|
414
414
|
currentProvider: chainStateMap[chainSlug].currentProvider
|
|
415
415
|
}).catch(console.error);
|
|
416
416
|
this.lockChainInfoMap = false;
|
|
417
|
-
this.eventService.emit('chain.
|
|
417
|
+
this.eventService.emit('chain.updateState', chainSlug);
|
|
418
418
|
return true;
|
|
419
419
|
}
|
|
420
420
|
enableChain(chainSlug) {
|
|
@@ -449,7 +449,7 @@ export class ChainService {
|
|
|
449
449
|
}).catch(console.error);
|
|
450
450
|
this.updateChainStateMapSubscription();
|
|
451
451
|
this.lockChainInfoMap = false;
|
|
452
|
-
this.eventService.emit('chain.
|
|
452
|
+
this.eventService.emit('chain.updateState', chainSlug);
|
|
453
453
|
return true;
|
|
454
454
|
}
|
|
455
455
|
checkExistedPredefinedChain(genesisHash, evmChainId) {
|
|
@@ -547,7 +547,8 @@ export class ChainService {
|
|
|
547
547
|
evmInfo: storedChainInfo.evmInfo,
|
|
548
548
|
substrateInfo: storedChainInfo.substrateInfo,
|
|
549
549
|
isTestnet: storedChainInfo.isTestnet,
|
|
550
|
-
chainStatus: storedChainInfo.chainStatus
|
|
550
|
+
chainStatus: storedChainInfo.chainStatus,
|
|
551
|
+
icon: storedChainInfo.icon
|
|
551
552
|
};
|
|
552
553
|
this.dataMap.chainStateMap[storedSlug] = {
|
|
553
554
|
currentProvider: storedChainInfo.currentProvider,
|
|
@@ -672,7 +673,7 @@ export class ChainService {
|
|
|
672
673
|
active: targetChainState.active,
|
|
673
674
|
currentProvider: targetChainState.currentProvider
|
|
674
675
|
}).then(() => {
|
|
675
|
-
this.eventService.emit('chain.
|
|
676
|
+
this.eventService.emit('chain.updateState', chainSlug);
|
|
676
677
|
}).catch(e => this.logger.error(e));
|
|
677
678
|
}
|
|
678
679
|
insertChain(params) {
|
|
@@ -718,7 +719,8 @@ export class ChainService {
|
|
|
718
719
|
substrateInfo,
|
|
719
720
|
evmInfo,
|
|
720
721
|
isTestnet: false,
|
|
721
|
-
chainStatus: _ChainStatus.ACTIVE
|
|
722
|
+
chainStatus: _ChainStatus.ACTIVE,
|
|
723
|
+
icon: '' // Todo: Allow update with custom chain
|
|
722
724
|
};
|
|
723
725
|
|
|
724
726
|
// insert new chainInfo
|
|
@@ -746,7 +748,8 @@ export class ChainService {
|
|
|
746
748
|
priceId: params.chainEditInfo.priceId || null,
|
|
747
749
|
slug: '',
|
|
748
750
|
symbol: params.chainEditInfo.symbol,
|
|
749
|
-
hasValue: true
|
|
751
|
+
hasValue: true,
|
|
752
|
+
icon: ''
|
|
750
753
|
});
|
|
751
754
|
|
|
752
755
|
// update subscription
|
|
@@ -961,21 +964,23 @@ export class ChainService {
|
|
|
961
964
|
}
|
|
962
965
|
async validateCustomToken(data) {
|
|
963
966
|
const assetRegistry = this.getSmartContractTokens();
|
|
964
|
-
let
|
|
967
|
+
let existedToken;
|
|
965
968
|
for (const token of Object.values(assetRegistry)) {
|
|
966
969
|
var _token$metadata2;
|
|
967
970
|
const contractAddress = token === null || token === void 0 ? void 0 : (_token$metadata2 = token.metadata) === null || _token$metadata2 === void 0 ? void 0 : _token$metadata2.contractAddress;
|
|
968
971
|
if (_isEqualContractAddress(contractAddress, data.contractAddress) && token.assetType === data.type && token.originChain === data.originChain) {
|
|
969
|
-
|
|
972
|
+
existedToken = token;
|
|
970
973
|
break;
|
|
971
974
|
}
|
|
972
975
|
}
|
|
973
|
-
if (
|
|
976
|
+
if (existedToken) {
|
|
977
|
+
var _existedToken;
|
|
974
978
|
return {
|
|
975
|
-
decimals:
|
|
976
|
-
name:
|
|
977
|
-
symbol:
|
|
978
|
-
isExist,
|
|
979
|
+
decimals: existedToken.decimals || 0,
|
|
980
|
+
name: existedToken.name,
|
|
981
|
+
symbol: existedToken.symbol,
|
|
982
|
+
isExist: !!existedToken,
|
|
983
|
+
existedSlug: (_existedToken = existedToken) === null || _existedToken === void 0 ? void 0 : _existedToken.slug,
|
|
979
984
|
contractError: false
|
|
980
985
|
};
|
|
981
986
|
}
|
|
@@ -989,7 +994,7 @@ export class ChainService {
|
|
|
989
994
|
name,
|
|
990
995
|
decimals,
|
|
991
996
|
symbol,
|
|
992
|
-
isExist,
|
|
997
|
+
isExist: !!existedToken,
|
|
993
998
|
contractError
|
|
994
999
|
};
|
|
995
1000
|
}
|
|
@@ -1039,19 +1044,26 @@ export class ChainService {
|
|
|
1039
1044
|
|
|
1040
1045
|
return this.substrateChainHandler.resumeAllApis();
|
|
1041
1046
|
}
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
refreshChainStateInterval(delay = 0) {
|
|
1047
|
+
refreshChainStateTimeout = undefined;
|
|
1048
|
+
refreshChainStateTimes = 0;
|
|
1049
|
+
refreshChainStateInterval(delay = 0, times) {
|
|
1045
1050
|
clearTimeout(this.refreshChainStateTimeout);
|
|
1046
1051
|
setTimeout(() => {
|
|
1047
|
-
|
|
1052
|
+
if (times) {
|
|
1053
|
+
this.refreshChainStateTimes = times;
|
|
1054
|
+
}
|
|
1055
|
+
this.refreshChainStateTimes -= 1;
|
|
1056
|
+
if (this.refreshChainStateTimes < 0) {
|
|
1057
|
+
return;
|
|
1058
|
+
}
|
|
1059
|
+
this.updateApiMapStatus().catch(console.error);
|
|
1048
1060
|
this.refreshChainStateTimeout = setTimeout(() => {
|
|
1049
|
-
this.updateApiMapStatus();
|
|
1050
|
-
this.refreshChainStateInterval();
|
|
1051
|
-
},
|
|
1061
|
+
this.updateApiMapStatus().catch(console.error);
|
|
1062
|
+
this.refreshChainStateInterval(0);
|
|
1063
|
+
}, 3000);
|
|
1052
1064
|
}, delay);
|
|
1053
1065
|
}
|
|
1054
|
-
updateApiMapStatus() {
|
|
1066
|
+
async updateApiMapStatus() {
|
|
1055
1067
|
const substrateApiMap = this.getSubstrateApiMap();
|
|
1056
1068
|
const evmApiMap = this.getEvmApiMap();
|
|
1057
1069
|
const chainStateMap = this.getChainStateMap();
|
|
@@ -1062,24 +1074,30 @@ export class ChainService {
|
|
|
1062
1074
|
update = true;
|
|
1063
1075
|
}
|
|
1064
1076
|
}
|
|
1065
|
-
Object.entries(chainStateMap).
|
|
1066
|
-
|
|
1067
|
-
if (
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1077
|
+
const promiseList = Object.entries(chainStateMap).map(async ([chain, chainState]) => {
|
|
1078
|
+
try {
|
|
1079
|
+
if (chainState.active) {
|
|
1080
|
+
if (substrateApiMap[chain]) {
|
|
1081
|
+
const api = substrateApiMap[chain];
|
|
1082
|
+
if (api.isApiConnected) {
|
|
1083
|
+
updateState(chainState, _ChainConnectionStatus.CONNECTED);
|
|
1084
|
+
return;
|
|
1085
|
+
}
|
|
1086
|
+
} else if (evmApiMap[chain]) {
|
|
1087
|
+
var _api$api;
|
|
1088
|
+
const api = evmApiMap[chain];
|
|
1089
|
+
if (await (api === null || api === void 0 ? void 0 : (_api$api = api.api) === null || _api$api === void 0 ? void 0 : _api$api.eth.net.isListening())) {
|
|
1090
|
+
updateState(chainState, _ChainConnectionStatus.CONNECTED);
|
|
1091
|
+
return;
|
|
1092
|
+
}
|
|
1078
1093
|
}
|
|
1079
1094
|
}
|
|
1095
|
+
updateState(chainState, _ChainConnectionStatus.DISCONNECTED);
|
|
1096
|
+
} catch (e) {
|
|
1097
|
+
updateState(chainState, _ChainConnectionStatus.DISCONNECTED);
|
|
1080
1098
|
}
|
|
1081
|
-
updateState(chainState, _ChainConnectionStatus.DISCONNECTED);
|
|
1082
1099
|
});
|
|
1100
|
+
await Promise.all(promiseList);
|
|
1083
1101
|
if (update) {
|
|
1084
1102
|
console.log('Update chain connection state');
|
|
1085
1103
|
this.chainStateMapSubject.next(chainStateMap);
|
|
@@ -1105,7 +1123,6 @@ export class ChainService {
|
|
|
1105
1123
|
this.setAssetSettings(assetSettings, false);
|
|
1106
1124
|
}
|
|
1107
1125
|
this.eventService.emit('asset.ready', true);
|
|
1108
|
-
console.log('Done init asset settings');
|
|
1109
1126
|
}
|
|
1110
1127
|
setAssetSettings(assetSettings, emitEvent = true) {
|
|
1111
1128
|
const updateAssets = [];
|
|
@@ -1119,7 +1136,7 @@ export class ChainService {
|
|
|
1119
1136
|
}
|
|
1120
1137
|
this.assetSettingSubject.next(assetSettings);
|
|
1121
1138
|
updateAssets.forEach(slug => {
|
|
1122
|
-
this.eventService.emit(
|
|
1139
|
+
this.eventService.emit('asset.updateState', slug);
|
|
1123
1140
|
});
|
|
1124
1141
|
this.store.set('AssetSetting', assetSettings);
|
|
1125
1142
|
}
|
|
@@ -1168,4 +1185,10 @@ export class ChainService {
|
|
|
1168
1185
|
subscribeAssetSettings() {
|
|
1169
1186
|
return this.assetSettingSubject;
|
|
1170
1187
|
}
|
|
1188
|
+
async getChainLogoMap() {
|
|
1189
|
+
return Promise.resolve(ChainLogoMap);
|
|
1190
|
+
}
|
|
1191
|
+
async getAssetLogoMap() {
|
|
1192
|
+
return Promise.resolve(AssetLogoMap);
|
|
1193
|
+
}
|
|
1171
1194
|
}
|
|
@@ -104,6 +104,7 @@ export interface _SmartContractTokenInfo {
|
|
|
104
104
|
}
|
|
105
105
|
export interface _ValidateCustomAssetResponse extends _SmartContractTokenInfo {
|
|
106
106
|
isExist: boolean;
|
|
107
|
+
existedSlug?: string;
|
|
107
108
|
}
|
|
108
109
|
export declare const _FUNGIBLE_CONTRACT_STANDARDS: _AssetType[];
|
|
109
110
|
export declare const _NFT_CONTRACT_STANDARDS: _AssetType[];
|
|
@@ -34,7 +34,11 @@ export class EventService extends EventEmitter {
|
|
|
34
34
|
}, this.lazyTime);
|
|
35
35
|
}
|
|
36
36
|
emitLazy() {
|
|
37
|
-
|
|
37
|
+
try {
|
|
38
|
+
this.lazyEmitter.emit('lazy', this.pendingEvents, this.pendingEvents.map(e => e.type));
|
|
39
|
+
} catch (e) {
|
|
40
|
+
console.error('Get error in some listener of lazy event', e);
|
|
41
|
+
}
|
|
38
42
|
this.pendingEvents = [];
|
|
39
43
|
this.timeoutId = null;
|
|
40
44
|
}
|
|
@@ -9,20 +9,16 @@ export interface EventRegistry {
|
|
|
9
9
|
'account.remove': [string];
|
|
10
10
|
'chain.ready': [boolean];
|
|
11
11
|
'chain.add': [string];
|
|
12
|
-
'chain.
|
|
13
|
-
'chain.disable': [string];
|
|
14
|
-
'chain.enable': [string];
|
|
15
|
-
'chain.remove': [string];
|
|
12
|
+
'chain.updateState': [string];
|
|
16
13
|
'asset.ready': [boolean];
|
|
17
|
-
'asset.
|
|
18
|
-
'asset.update': [string];
|
|
19
|
-
'asset.enable': [string];
|
|
20
|
-
'asset.disable': [string];
|
|
21
|
-
'asset.remove': [string];
|
|
14
|
+
'asset.updateState': [string];
|
|
22
15
|
'transaction.done': [SWTransaction];
|
|
23
16
|
'transaction.failed': [SWTransaction | undefined];
|
|
17
|
+
'transaction.submitStaking': [string];
|
|
18
|
+
'transaction.transferNft': [SWTransaction | undefined];
|
|
24
19
|
}
|
|
25
20
|
export declare type EventType = keyof EventRegistry;
|
|
21
|
+
export declare const COMMON_RELOAD_EVENTS: EventType[];
|
|
26
22
|
export interface EventItem<T extends EventType> {
|
|
27
23
|
type: T;
|
|
28
24
|
data: EventRegistry[T];
|
|
@@ -1,24 +1,45 @@
|
|
|
1
1
|
import { TransactionHistoryItem } from '@subwallet/extension-base/background/KoniTypes';
|
|
2
|
+
import { CronServiceInterface, PersistDataServiceInterface, ServiceStatus, StoppableServiceInterface } from '@subwallet/extension-base/services/base/types';
|
|
2
3
|
import { ChainService } from '@subwallet/extension-base/services/chain-service';
|
|
3
4
|
import { EventService } from '@subwallet/extension-base/services/event-service';
|
|
5
|
+
import { KeyringService } from '@subwallet/extension-base/services/keyring-service';
|
|
4
6
|
import DatabaseService from '@subwallet/extension-base/services/storage-service/DatabaseService';
|
|
5
7
|
import { BehaviorSubject } from 'rxjs';
|
|
6
|
-
export declare class HistoryService {
|
|
8
|
+
export declare class HistoryService implements StoppableServiceInterface, PersistDataServiceInterface, CronServiceInterface {
|
|
7
9
|
private dbService;
|
|
8
10
|
private chainService;
|
|
9
11
|
private eventService;
|
|
12
|
+
private keyringService;
|
|
10
13
|
private historySubject;
|
|
11
|
-
constructor(dbService: DatabaseService, chainService: ChainService, eventService: EventService);
|
|
14
|
+
constructor(dbService: DatabaseService, chainService: ChainService, eventService: EventService, keyringService: KeyringService);
|
|
12
15
|
private fetchPromise;
|
|
13
|
-
private
|
|
16
|
+
private interval;
|
|
14
17
|
private fetchAndLoadHistories;
|
|
15
|
-
fetchHistories(addresses: string[]): Promise<TransactionHistoryItem<import("@subwallet/extension-base/background/KoniTypes").ExtrinsicType.TRANSFER_BALANCE>[]>;
|
|
16
|
-
invalidCache(): void;
|
|
17
|
-
refreshHistoryInterval(): void;
|
|
18
18
|
getHistories(): Promise<TransactionHistoryItem<import("@subwallet/extension-base/background/KoniTypes").ExtrinsicType.TRANSFER_BALANCE>[]>;
|
|
19
19
|
getHistorySubject(): Promise<BehaviorSubject<TransactionHistoryItem<import("@subwallet/extension-base/background/KoniTypes").ExtrinsicType.TRANSFER_BALANCE>[]>>;
|
|
20
|
-
insertHistories(historyItems: TransactionHistoryItem[]): Promise<void>;
|
|
21
20
|
updateHistories(chain: string, extrinsicHash: string, updateData: Partial<TransactionHistoryItem>): Promise<void>;
|
|
21
|
+
updateHistoryByExtrinsicHash(extrinsicHash: string, updateData: Partial<TransactionHistoryItem>): Promise<void>;
|
|
22
|
+
insertHistories(historyItems: TransactionHistoryItem[]): Promise<void>;
|
|
22
23
|
addHistoryItems(historyItems: TransactionHistoryItem[]): Promise<void>;
|
|
23
24
|
removeHistoryByAddress(address: string): Promise<void>;
|
|
25
|
+
status: ServiceStatus;
|
|
26
|
+
loadData(): Promise<void>;
|
|
27
|
+
persistData(): Promise<void>;
|
|
28
|
+
startCron(): Promise<void>;
|
|
29
|
+
stopCron(): Promise<void>;
|
|
30
|
+
startPromiseHandler: {
|
|
31
|
+
resolve: (value: void) => void;
|
|
32
|
+
reject: (reason?: unknown) => void;
|
|
33
|
+
promise: Promise<void>;
|
|
34
|
+
};
|
|
35
|
+
init(): Promise<void>;
|
|
36
|
+
start(): Promise<void>;
|
|
37
|
+
waitForStarted(): Promise<void>;
|
|
38
|
+
stopPromiseHandler: {
|
|
39
|
+
resolve: (value: void) => void;
|
|
40
|
+
reject: (reason?: unknown) => void;
|
|
41
|
+
promise: Promise<void>;
|
|
42
|
+
};
|
|
43
|
+
stop(): Promise<void>;
|
|
44
|
+
waitForStopped(): Promise<void>;
|
|
24
45
|
}
|
|
@@ -2,35 +2,22 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import { CRON_REFRESH_HISTORY_INTERVAL } from '@subwallet/extension-base/constants';
|
|
5
|
-
import {
|
|
5
|
+
import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
|
|
6
|
+
import { createPromiseHandler } from '@subwallet/extension-base/utils/promise';
|
|
6
7
|
import { keyring } from '@subwallet/ui-keyring';
|
|
7
|
-
import { accounts } from '@subwallet/ui-keyring/observable/accounts';
|
|
8
8
|
import { BehaviorSubject } from 'rxjs';
|
|
9
9
|
import { fetchMultiChainHistories } from "./subsquid-multi-chain-history.js";
|
|
10
10
|
export class HistoryService {
|
|
11
11
|
historySubject = new BehaviorSubject([]);
|
|
12
|
-
constructor(dbService, chainService, eventService) {
|
|
12
|
+
constructor(dbService, chainService, eventService, keyringService) {
|
|
13
13
|
this.dbService = dbService;
|
|
14
14
|
this.chainService = chainService;
|
|
15
15
|
this.eventService = eventService;
|
|
16
|
-
|
|
17
|
-
this.
|
|
18
|
-
this.historySubject.next(histories);
|
|
19
|
-
}).catch(console.error);
|
|
20
|
-
|
|
21
|
-
// Wait for keyring and chain ready and start
|
|
22
|
-
Promise.all([this.eventService.waitKeyringReady, this.eventService.waitChainReady]).then(() => {
|
|
23
|
-
this.getHistories().catch(console.log);
|
|
24
|
-
this.eventService.on('account.add', () => {
|
|
25
|
-
this.refreshHistoryInterval();
|
|
26
|
-
});
|
|
27
|
-
this.eventService.on('account.remove', address => {
|
|
28
|
-
this.removeHistoryByAddress(address).catch(console.error);
|
|
29
|
-
});
|
|
30
|
-
}).catch(console.error);
|
|
16
|
+
this.keyringService = keyringService;
|
|
17
|
+
this.init().catch(console.error);
|
|
31
18
|
}
|
|
32
19
|
fetchPromise = null;
|
|
33
|
-
|
|
20
|
+
interval = undefined;
|
|
34
21
|
async fetchAndLoadHistories(addresses) {
|
|
35
22
|
if (!addresses || addresses.length === 0) {
|
|
36
23
|
return [];
|
|
@@ -41,7 +28,7 @@ export class HistoryService {
|
|
|
41
28
|
const historyRecords = await fetchMultiChainHistories(addresses, chainMap);
|
|
42
29
|
|
|
43
30
|
// Fill additional info
|
|
44
|
-
const accountMap = Object.entries(
|
|
31
|
+
const accountMap = Object.entries(this.keyringService.accounts).reduce((map, [address, account]) => {
|
|
45
32
|
map[address.toLowerCase()] = account.json.meta.name || address;
|
|
46
33
|
return map;
|
|
47
34
|
}, {});
|
|
@@ -50,44 +37,24 @@ export class HistoryService {
|
|
|
50
37
|
record.fromName = accountMap[(_record$from = record.from) === null || _record$from === void 0 ? void 0 : _record$from.toLowerCase()];
|
|
51
38
|
record.toName = accountMap[(_record$to = record.to) === null || _record$to === void 0 ? void 0 : _record$to.toLowerCase()];
|
|
52
39
|
});
|
|
53
|
-
this.
|
|
40
|
+
await this.addHistoryItems(historyRecords);
|
|
54
41
|
return historyRecords;
|
|
55
42
|
}
|
|
56
|
-
async fetchHistories(addresses) {
|
|
57
|
-
if (!this.fetchPromise) {
|
|
58
|
-
// Fetch another histories data data indexer and merge it with stored in database
|
|
59
|
-
this.fetchPromise = this.fetchAndLoadHistories(addresses);
|
|
60
|
-
}
|
|
61
|
-
return this.fetchPromise;
|
|
62
|
-
}
|
|
63
|
-
invalidCache() {
|
|
64
|
-
this.fetchPromise = null;
|
|
65
|
-
}
|
|
66
|
-
refreshHistoryInterval() {
|
|
67
|
-
clearTimeout(this.nextFetch);
|
|
68
|
-
this.invalidCache();
|
|
69
|
-
this.getHistories().catch(console.error);
|
|
70
|
-
this.nextFetch = setTimeout(() => {
|
|
71
|
-
this.refreshHistoryInterval();
|
|
72
|
-
}, CRON_REFRESH_HISTORY_INTERVAL);
|
|
73
|
-
}
|
|
74
43
|
async getHistories() {
|
|
75
44
|
const addressList = keyring.getAccounts().map(a => a.address);
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
45
|
+
if (!this.fetchPromise) {
|
|
46
|
+
this.fetchPromise = (async () => {
|
|
47
|
+
await this.fetchAndLoadHistories(addressList);
|
|
48
|
+
const histories = await this.dbService.getHistories();
|
|
49
|
+
this.historySubject.next(histories);
|
|
50
|
+
})();
|
|
80
51
|
}
|
|
81
|
-
return this.historySubject.getValue();
|
|
52
|
+
return Promise.resolve(this.historySubject.getValue());
|
|
82
53
|
}
|
|
83
54
|
async getHistorySubject() {
|
|
84
55
|
await this.getHistories();
|
|
85
56
|
return this.historySubject;
|
|
86
57
|
}
|
|
87
|
-
async insertHistories(historyItems) {
|
|
88
|
-
await this.dbService.upsertHistory(historyItems);
|
|
89
|
-
this.historySubject.next(await this.dbService.getHistories());
|
|
90
|
-
}
|
|
91
58
|
async updateHistories(chain, extrinsicHash, updateData) {
|
|
92
59
|
const existedRecords = await this.dbService.getHistories({
|
|
93
60
|
chain,
|
|
@@ -101,14 +68,29 @@ export class HistoryService {
|
|
|
101
68
|
});
|
|
102
69
|
await this.addHistoryItems(updatedRecords);
|
|
103
70
|
}
|
|
71
|
+
async updateHistoryByExtrinsicHash(extrinsicHash, updateData) {
|
|
72
|
+
await this.dbService.updateHistoryByNewExtrinsicHash(extrinsicHash, updateData);
|
|
73
|
+
this.historySubject.next(await this.dbService.getHistories());
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Insert history without check override origin 'app'
|
|
77
|
+
async insertHistories(historyItems) {
|
|
78
|
+
await this.dbService.upsertHistory(historyItems);
|
|
79
|
+
this.historySubject.next(await this.dbService.getHistories());
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Insert history with check override origin 'app'
|
|
104
83
|
async addHistoryItems(historyItems) {
|
|
105
84
|
// Prevent override record with original is 'app'
|
|
106
85
|
const appRecords = this.historySubject.value.filter(item => item.origin === 'app');
|
|
107
86
|
const excludeKeys = appRecords.map(item => {
|
|
108
|
-
return `${item.chain}-${
|
|
87
|
+
return `${item.chain}-${item.extrinsicHash}`;
|
|
109
88
|
});
|
|
110
89
|
const updateRecords = historyItems.filter(item => {
|
|
111
|
-
const key = `${item.chain}-${
|
|
90
|
+
const key = `${item.chain}-${item.extrinsicHash}`;
|
|
91
|
+
|
|
92
|
+
// !excludeKeys.includes(key) && console.log('Cancel update', key);
|
|
93
|
+
|
|
112
94
|
return item.origin === 'app' || !excludeKeys.includes(key);
|
|
113
95
|
});
|
|
114
96
|
await this.dbService.upsertHistory(updateRecords);
|
|
@@ -118,4 +100,73 @@ export class HistoryService {
|
|
|
118
100
|
await this.dbService.stores.transaction.removeAllByAddress(address);
|
|
119
101
|
this.historySubject.next(await this.dbService.getHistories());
|
|
120
102
|
}
|
|
103
|
+
status = ServiceStatus.NOT_INITIALIZED;
|
|
104
|
+
async loadData() {
|
|
105
|
+
const histories = await this.dbService.getHistories();
|
|
106
|
+
this.historySubject.next(histories);
|
|
107
|
+
}
|
|
108
|
+
async persistData() {
|
|
109
|
+
await this.dbService.upsertHistory(this.historySubject.value);
|
|
110
|
+
}
|
|
111
|
+
async startCron() {
|
|
112
|
+
await this.getHistories();
|
|
113
|
+
this.interval = setInterval(() => {
|
|
114
|
+
this.getHistories().catch(console.error);
|
|
115
|
+
}, CRON_REFRESH_HISTORY_INTERVAL);
|
|
116
|
+
}
|
|
117
|
+
stopCron() {
|
|
118
|
+
clearTimeout(this.interval);
|
|
119
|
+
this.fetchPromise = null;
|
|
120
|
+
return Promise.resolve();
|
|
121
|
+
}
|
|
122
|
+
startPromiseHandler = createPromiseHandler();
|
|
123
|
+
async init() {
|
|
124
|
+
this.status = ServiceStatus.INITIALIZING;
|
|
125
|
+
await this.loadData();
|
|
126
|
+
Promise.all([this.eventService.waitKeyringReady, this.eventService.waitChainReady]).then(() => {
|
|
127
|
+
this.getHistories().catch(console.log);
|
|
128
|
+
this.eventService.on('account.add', () => {
|
|
129
|
+
(async () => {
|
|
130
|
+
await this.stopCron();
|
|
131
|
+
await this.startCron();
|
|
132
|
+
})().catch(console.error);
|
|
133
|
+
});
|
|
134
|
+
this.eventService.on('account.remove', address => {
|
|
135
|
+
this.removeHistoryByAddress(address).catch(console.error);
|
|
136
|
+
});
|
|
137
|
+
}).catch(console.error);
|
|
138
|
+
this.status = ServiceStatus.INITIALIZED;
|
|
139
|
+
}
|
|
140
|
+
async start() {
|
|
141
|
+
try {
|
|
142
|
+
console.debug('Start history service');
|
|
143
|
+
this.startPromiseHandler = createPromiseHandler();
|
|
144
|
+
this.status = ServiceStatus.STARTING;
|
|
145
|
+
await this.startCron();
|
|
146
|
+
this.status = ServiceStatus.STARTED;
|
|
147
|
+
this.startPromiseHandler.resolve();
|
|
148
|
+
} catch (e) {
|
|
149
|
+
this.startPromiseHandler.reject(e);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
waitForStarted() {
|
|
153
|
+
return this.startPromiseHandler.promise;
|
|
154
|
+
}
|
|
155
|
+
stopPromiseHandler = createPromiseHandler();
|
|
156
|
+
async stop() {
|
|
157
|
+
console.debug('Stop history service');
|
|
158
|
+
try {
|
|
159
|
+
this.stopPromiseHandler = createPromiseHandler();
|
|
160
|
+
this.status = ServiceStatus.STOPPING;
|
|
161
|
+
await this.persistData();
|
|
162
|
+
await this.stopCron();
|
|
163
|
+
this.stopPromiseHandler.resolve();
|
|
164
|
+
this.status = ServiceStatus.STOPPED;
|
|
165
|
+
} catch (e) {
|
|
166
|
+
this.stopPromiseHandler.reject(e);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
waitForStopped() {
|
|
170
|
+
return this.stopPromiseHandler.promise;
|
|
171
|
+
}
|
|
121
172
|
}
|
|
@@ -57,11 +57,15 @@ function autoFormatAddress(address) {
|
|
|
57
57
|
return '';
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
-
function generateSignature({
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
function generateSignature(input) {
|
|
61
|
+
if (!input) {
|
|
62
|
+
return '';
|
|
63
|
+
}
|
|
64
|
+
const {
|
|
65
|
+
r,
|
|
66
|
+
s,
|
|
67
|
+
v
|
|
68
|
+
} = input;
|
|
65
69
|
const rHex = r.startsWith('0x') ? r.slice(2) : r;
|
|
66
70
|
const sHex = s.startsWith('0x') ? s.slice(2) : s;
|
|
67
71
|
const vHex = parseInt(v).toString(16);
|
|
@@ -107,7 +111,7 @@ export function parseSubsquidTransactionData(address, type, historyItem, chainIn
|
|
|
107
111
|
const transaction = data.call.data.args.transaction.value;
|
|
108
112
|
to = autoFormatAddress(parsedArgs.to);
|
|
109
113
|
from = autoFormatAddress(parsedArgs.from);
|
|
110
|
-
extrinsicHash = parsedArgs.transactionHash;
|
|
114
|
+
extrinsicHash = parsedArgs.transactionHash || extrinsic.hash;
|
|
111
115
|
amount = transaction.value || '0';
|
|
112
116
|
fee = (parseInt(transaction.gasPrice) * parseInt(transaction.gasLimit)).toString();
|
|
113
117
|
signature = generateSignature(transaction.signature);
|
|
@@ -243,14 +247,14 @@ export async function fetchMultiChainHistories(addresses, chainMap, maxPage = 25
|
|
|
243
247
|
console.warn(`Not found chain info for chain id: ${chainId}`);
|
|
244
248
|
return;
|
|
245
249
|
}
|
|
246
|
-
|
|
247
|
-
|
|
250
|
+
usedAddresses.forEach(address => {
|
|
251
|
+
try {
|
|
248
252
|
const transactionData = parseSubsquidTransactionData(address, name, historyItem, chainInfo, parseData(args), parseData(_data));
|
|
249
253
|
histories.push(transactionData);
|
|
250
|
-
})
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
}
|
|
254
|
+
} catch (e) {
|
|
255
|
+
console.warn('Parse transaction data failed', address, e);
|
|
256
|
+
}
|
|
257
|
+
});
|
|
254
258
|
});
|
|
255
259
|
return histories;
|
|
256
260
|
}
|