@subwallet/extension-base 1.0.4-0 → 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 +37 -16
- package/background/KoniTypes.js +2 -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 +2 -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/amplitude.js +9 -2
- package/cjs/koni/api/staking/bonding/astar.js +37 -13
- package/cjs/koni/api/staking/bonding/paraChain.js +10 -2
- package/cjs/koni/api/staking/bonding/relayChain.js +21 -4
- 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 +204 -132
- package/cjs/koni/background/handlers/State.js +30 -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/constants.js +1 -1
- package/cjs/services/chain-service/handler/EvmChainHandler.js +1 -1
- package/cjs/services/chain-service/handler/SubstrateChainHandler.js +3 -10
- package/cjs/services/chain-service/handler/light-client/index.js +9 -6
- package/cjs/services/chain-service/index.js +75 -28
- 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 +9 -2
- package/cjs/services/migration-service/index.js +7 -7
- package/cjs/services/migration-service/scripts/MigrateAuthUrls.js +39 -0
- 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 +7 -1
- package/cjs/services/price-service/coingecko.js +1 -1
- package/cjs/services/price-service/index.js +0 -4
- package/cjs/services/request-service/handler/AuthRequestHandler.js +8 -1
- package/cjs/services/request-service/handler/EvmRequestHandler.js +21 -0
- package/cjs/services/request-service/handler/MetadataRequestHandler.js +6 -0
- package/cjs/services/request-service/handler/SubstrateRequestHandler.js +6 -0
- package/cjs/services/request-service/index.js +6 -0
- package/cjs/services/setting-service/SettingService.js +4 -9
- package/cjs/services/setting-service/constants.js +18 -2
- package/cjs/services/storage-service/DatabaseService.js +16 -44
- package/cjs/services/storage-service/databases/index.js +1 -1
- package/cjs/services/storage-service/db-stores/BaseStore.js +3 -0
- package/cjs/services/transaction-service/constants.js +11 -0
- package/cjs/services/transaction-service/index.js +31 -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/amplitude.js +9 -2
- package/koni/api/staking/bonding/astar.d.ts +2 -1
- package/koni/api/staking/bonding/astar.js +36 -13
- package/koni/api/staking/bonding/paraChain.js +10 -2
- package/koni/api/staking/bonding/relayChain.js +21 -4
- 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 +3 -0
- package/koni/background/handlers/Extension.js +120 -51
- package/koni/background/handlers/State.d.ts +4 -1
- package/koni/background/handlers/State.js +30 -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 +65 -39
- package/packageInfo.js +1 -1
- package/services/chain-service/constants.js +1 -1
- package/services/chain-service/handler/EvmChainHandler.js +1 -1
- package/services/chain-service/handler/SubstrateChainHandler.js +3 -10
- 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.d.ts +2 -1
- package/services/chain-service/index.js +75 -28
- 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.d.ts +1 -0
- package/services/keyring-service/index.js +9 -2
- package/services/migration-service/index.js +7 -7
- package/services/migration-service/scripts/MigrateAuthUrls.d.ts +4 -0
- package/services/migration-service/scripts/MigrateAuthUrls.js +31 -0
- 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 +7 -1
- package/services/price-service/coingecko.js +1 -1
- package/services/price-service/index.js +0 -4
- package/services/request-service/handler/AuthRequestHandler.d.ts +1 -0
- package/services/request-service/handler/AuthRequestHandler.js +8 -1
- package/services/request-service/handler/EvmRequestHandler.d.ts +1 -0
- package/services/request-service/handler/EvmRequestHandler.js +21 -0
- package/services/request-service/handler/MetadataRequestHandler.d.ts +1 -0
- package/services/request-service/handler/MetadataRequestHandler.js +6 -0
- package/services/request-service/handler/SubstrateRequestHandler.d.ts +1 -0
- package/services/request-service/handler/SubstrateRequestHandler.js +6 -0
- package/services/request-service/index.d.ts +1 -0
- package/services/request-service/index.js +6 -0
- package/services/setting-service/SettingService.d.ts +1 -0
- package/services/setting-service/SettingService.js +5 -10
- package/services/setting-service/constants.d.ts +4 -1
- package/services/setting-service/constants.js +14 -1
- package/services/storage-service/DatabaseService.d.ts +1 -0
- package/services/storage-service/DatabaseService.js +16 -44
- package/services/storage-service/databases/index.js +1 -1
- package/services/storage-service/db-stores/BaseStore.d.ts +1 -0
- package/services/storage-service/db-stores/BaseStore.js +3 -0
- package/services/transaction-service/constants.d.ts +1 -0
- package/services/transaction-service/constants.js +4 -0
- package/services/transaction-service/index.d.ts +2 -0
- package/services/transaction-service/index.js +32 -10
- package/services/transaction-service/utils.d.ts +1 -1
- package/services/transaction-service/utils.js +24 -13
|
@@ -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
|
|
@@ -471,31 +470,43 @@ export class ChainService {
|
|
|
471
470
|
return duplicatedSlug;
|
|
472
471
|
}
|
|
473
472
|
async fetchLatestData(src, defaultValue) {
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
473
|
+
return Promise.resolve(defaultValue);
|
|
474
|
+
// try {
|
|
475
|
+
// const timeout = new Promise((resolve) => {
|
|
476
|
+
// const id = setTimeout(() => {
|
|
477
|
+
// clearTimeout(id);
|
|
478
|
+
// resolve(null);
|
|
479
|
+
// }, 1500);
|
|
480
|
+
// });
|
|
481
|
+
// let result = defaultValue;
|
|
482
|
+
// const resp = await Promise.race([
|
|
483
|
+
// timeout,
|
|
484
|
+
// fetch(src)
|
|
485
|
+
// ]) as Response || null;
|
|
486
|
+
//
|
|
487
|
+
// if (!resp) {
|
|
488
|
+
// console.warn('Error fetching latest data', src);
|
|
489
|
+
//
|
|
490
|
+
// return result;
|
|
491
|
+
// }
|
|
492
|
+
//
|
|
493
|
+
// if (resp.ok) {
|
|
494
|
+
// try {
|
|
495
|
+
// result = await resp.json();
|
|
496
|
+
// console.log('Fetched latest data', src);
|
|
497
|
+
// } catch (err) {
|
|
498
|
+
// console.warn('Error parsing latest data', src, err);
|
|
499
|
+
// }
|
|
500
|
+
// }
|
|
501
|
+
//
|
|
502
|
+
// return result;
|
|
503
|
+
// } catch (e) {
|
|
504
|
+
// console.warn('Error fetching latest data', src, e);
|
|
505
|
+
//
|
|
506
|
+
// return defaultValue;
|
|
507
|
+
// }
|
|
498
508
|
}
|
|
509
|
+
|
|
499
510
|
async initChains() {
|
|
500
511
|
const storedChainSettings = await this.dbService.getAllChainStore();
|
|
501
512
|
const latestChainInfoMap = await this.fetchLatestData(_CHAIN_INFO_SRC, ChainInfoMap);
|
|
@@ -1128,7 +1139,6 @@ export class ChainService {
|
|
|
1128
1139
|
});
|
|
1129
1140
|
await Promise.all(promiseList);
|
|
1130
1141
|
if (update) {
|
|
1131
|
-
console.log('Update chain connection state');
|
|
1132
1142
|
this.chainStateMapSubject.next(chainStateMap);
|
|
1133
1143
|
}
|
|
1134
1144
|
}
|
|
@@ -1181,13 +1191,12 @@ export class ChainService {
|
|
|
1181
1191
|
}
|
|
1182
1192
|
return this.assetSettingSubject.value;
|
|
1183
1193
|
}
|
|
1184
|
-
async updateAssetSetting(assetSlug, assetSetting) {
|
|
1194
|
+
async updateAssetSetting(assetSlug, assetSetting, autoEnableNativeToken) {
|
|
1185
1195
|
const currentAssetSettings = await this.getAssetSettings();
|
|
1186
1196
|
let needUpdateSubject;
|
|
1187
1197
|
|
|
1188
1198
|
// Update settings
|
|
1189
1199
|
currentAssetSettings[assetSlug] = assetSetting;
|
|
1190
|
-
this.setAssetSettings(currentAssetSettings);
|
|
1191
1200
|
if (assetSetting.visible) {
|
|
1192
1201
|
const assetInfo = this.getAssetBySlug(assetSlug);
|
|
1193
1202
|
const chainState = this.getChainStateByKey(assetInfo.originChain);
|
|
@@ -1196,8 +1205,15 @@ export class ChainService {
|
|
|
1196
1205
|
if (chainState && !chainState.active) {
|
|
1197
1206
|
this.enableChain(chainState.slug);
|
|
1198
1207
|
needUpdateSubject = true;
|
|
1208
|
+
if (autoEnableNativeToken) {
|
|
1209
|
+
const nativeAsset = this.getNativeTokenInfo(assetInfo.originChain);
|
|
1210
|
+
currentAssetSettings[nativeAsset.slug] = {
|
|
1211
|
+
visible: true
|
|
1212
|
+
};
|
|
1213
|
+
}
|
|
1199
1214
|
}
|
|
1200
1215
|
}
|
|
1216
|
+
this.setAssetSettings(currentAssetSettings);
|
|
1201
1217
|
return needUpdateSubject;
|
|
1202
1218
|
}
|
|
1203
1219
|
async updateAssetSettingByChain(chainSlug, visible) {
|
|
@@ -1220,4 +1236,35 @@ export class ChainService {
|
|
|
1220
1236
|
async getAssetLogoMap() {
|
|
1221
1237
|
return await this.fetchLatestData(_ASSET_LOGO_MAP_SRC, AssetLogoMap);
|
|
1222
1238
|
}
|
|
1239
|
+
resetWallet(resetAll) {
|
|
1240
|
+
if (resetAll) {
|
|
1241
|
+
this.setAssetSettings({});
|
|
1242
|
+
|
|
1243
|
+
// Disconnect chain
|
|
1244
|
+
const activeChains = this.getActiveChainInfos();
|
|
1245
|
+
for (const chain of Object.keys(activeChains)) {
|
|
1246
|
+
if (!_DEFAULT_ACTIVE_CHAINS.includes(chain)) {
|
|
1247
|
+
this.disableChain(chain);
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
// Remove custom chain
|
|
1252
|
+
const allChains = this.getChainInfoMap();
|
|
1253
|
+
for (const chain of Object.keys(allChains)) {
|
|
1254
|
+
if (_isCustomChain(chain)) {
|
|
1255
|
+
this.removeCustomChain(chain);
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
// Remove custom asset
|
|
1260
|
+
const assetSettings = this.getAssetSettings();
|
|
1261
|
+
const customToken = [];
|
|
1262
|
+
for (const asset of Object.keys(assetSettings)) {
|
|
1263
|
+
if (_isCustomAsset(asset)) {
|
|
1264
|
+
customToken.push(asset);
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
this.deleteCustomAssets(customToken);
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1223
1270
|
}
|
|
@@ -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 => {
|