@subwallet/extension-base 1.0.2-3 → 1.0.4-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/background/KoniTypes.d.ts +10 -2
  2. package/background/KoniTypes.js +3 -1
  3. package/cjs/background/KoniTypes.js +3 -1
  4. package/cjs/koni/background/handlers/Extension.js +9 -0
  5. package/cjs/koni/background/handlers/State.js +8 -1
  6. package/cjs/koni/background/subscription.js +24 -2
  7. package/cjs/packageInfo.js +1 -1
  8. package/cjs/services/base/types.js +20 -0
  9. package/cjs/services/chain-service/constants.js +17 -2
  10. package/cjs/services/chain-service/index.js +57 -18
  11. package/cjs/services/history-service/index.js +84 -39
  12. package/cjs/services/migration-service/scripts/MigrateImportedToken.js +2 -1
  13. package/cjs/services/price-service/index.js +71 -23
  14. package/cjs/services/storage-service/DatabaseService.js +10 -0
  15. package/cjs/services/storage-service/db-stores/Transaction.js +6 -10
  16. package/cjs/services/transaction-service/index.js +78 -33
  17. package/cjs/services/transaction-service/utils.js +10 -8
  18. package/cjs/utils/promise.js +26 -0
  19. package/koni/background/handlers/Extension.d.ts +1 -0
  20. package/koni/background/handlers/Extension.js +9 -0
  21. package/koni/background/handlers/State.js +8 -1
  22. package/koni/background/subscription.d.ts +2 -0
  23. package/koni/background/subscription.js +23 -2
  24. package/package.json +22 -12
  25. package/packageInfo.js +1 -1
  26. package/services/base/types.d.ts +34 -0
  27. package/services/base/types.js +15 -0
  28. package/services/chain-service/constants.d.ts +6 -0
  29. package/services/chain-service/constants.js +10 -1
  30. package/services/chain-service/index.d.ts +3 -0
  31. package/services/chain-service/index.js +59 -20
  32. package/services/history-service/index.d.ts +24 -5
  33. package/services/history-service/index.js +84 -39
  34. package/services/migration-service/scripts/MigrateImportedToken.js +2 -1
  35. package/services/price-service/index.d.ts +22 -1
  36. package/services/price-service/index.js +71 -23
  37. package/services/storage-service/DatabaseService.d.ts +1 -0
  38. package/services/storage-service/DatabaseService.js +10 -0
  39. package/services/storage-service/db-stores/Transaction.d.ts +2 -0
  40. package/services/storage-service/db-stores/Transaction.js +6 -10
  41. package/services/transaction-service/index.d.ts +2 -0
  42. package/services/transaction-service/index.js +60 -17
  43. package/services/transaction-service/types.d.ts +2 -0
  44. package/services/transaction-service/utils.js +10 -8
  45. package/utils/promise.d.ts +6 -0
  46. package/utils/promise.js +20 -0
  47. /package/cjs/services/chain-service/{heath-check → health-check}/index.js +0 -0
  48. /package/services/chain-service/{heath-check → health-check}/index.d.ts +0 -0
  49. /package/services/chain-service/{heath-check → health-check}/index.js +0 -0
@@ -342,14 +342,16 @@ export interface ExtrinsicDataTypeMap {
342
342
  [ExtrinsicType.STAKING_CANCEL_COMPOUNDING]: RequestTuringCancelStakeCompound;
343
343
  [ExtrinsicType.STAKING_CANCEL_UNSTAKE]: RequestStakeCancelWithdrawal;
344
344
  [ExtrinsicType.STAKING_POOL_WITHDRAW]: any;
345
- [ExtrinsicType.EVM_EXECUTE]: any;
345
+ [ExtrinsicType.EVM_EXECUTE]: TransactionConfig;
346
346
  [ExtrinsicType.UNKNOWN]: any;
347
347
  }
348
348
  export declare enum ExtrinsicStatus {
349
- PENDING = "pending",
349
+ QUEUED = "queued",
350
+ SUBMITTING = "submitting",
350
351
  PROCESSING = "processing",
351
352
  SUCCESS = "success",
352
353
  FAIL = "fail",
354
+ CANCELLED = "cancelled",
353
355
  UNKNOWN = "unknown"
354
356
  }
355
357
  export interface TxHistoryItem {
@@ -398,6 +400,7 @@ export interface TransactionHistoryItem<ET extends ExtrinsicType = ExtrinsicType
398
400
  toName?: string;
399
401
  address: string;
400
402
  status: ExtrinsicStatus;
403
+ transactionId?: string;
401
404
  extrinsicHash: string;
402
405
  time: number;
403
406
  data?: string;
@@ -1357,6 +1360,10 @@ export declare type NotificationParams = Omit<Notification, 'id'>;
1357
1360
  export interface CronReloadRequest {
1358
1361
  data: 'nft' | 'staking';
1359
1362
  }
1363
+ export interface AllLogoMap {
1364
+ chainLogoMap: Record<string, string>;
1365
+ assetLogoMap: Record<string, string>;
1366
+ }
1360
1367
  export interface KoniRequestSignatures {
1361
1368
  'pri(staking.submitTuringCancelCompound)': [RequestTuringCancelStakeCompound, SWTransactionResponse];
1362
1369
  'pri(staking.submitTuringCompound)': [RequestTuringStakeCompound, SWTransactionResponse];
@@ -1450,6 +1457,7 @@ export interface KoniRequestSignatures {
1450
1457
  'pri(settings.saveTheme)': [ThemeNames, boolean, UiSettings];
1451
1458
  'pri(settings.saveBrowserConfirmationType)': [BrowserConfirmationType, boolean, UiSettings];
1452
1459
  'pri(settings.saveCamera)': [RequestCameraSettings, boolean];
1460
+ 'pri(settings.getLogoMaps)': [null, AllLogoMap];
1453
1461
  'pri(transaction.history.getSubscription)': [null, TransactionHistoryItem[], TransactionHistoryItem[]];
1454
1462
  'pri(transfer.checkReferenceCount)': [RequestTransferCheckReferenceCount, boolean];
1455
1463
  'pri(transfer.checkSupporting)': [RequestTransferCheckSupporting, SupportTransferResponse];
@@ -82,10 +82,12 @@ export let ExtrinsicType;
82
82
  })(ExtrinsicType || (ExtrinsicType = {}));
83
83
  export let ExtrinsicStatus;
84
84
  (function (ExtrinsicStatus) {
85
- ExtrinsicStatus["PENDING"] = "pending";
85
+ ExtrinsicStatus["QUEUED"] = "queued";
86
+ ExtrinsicStatus["SUBMITTING"] = "submitting";
86
87
  ExtrinsicStatus["PROCESSING"] = "processing";
87
88
  ExtrinsicStatus["SUCCESS"] = "success";
88
89
  ExtrinsicStatus["FAIL"] = "fail";
90
+ ExtrinsicStatus["CANCELLED"] = "cancelled";
89
91
  ExtrinsicStatus["UNKNOWN"] = "unknown";
90
92
  })(ExtrinsicStatus || (ExtrinsicStatus = {}));
91
93
  export let BasicTxErrorType;
@@ -86,10 +86,12 @@ exports.ExtrinsicType = ExtrinsicType;
86
86
  let ExtrinsicStatus;
87
87
  exports.ExtrinsicStatus = ExtrinsicStatus;
88
88
  (function (ExtrinsicStatus) {
89
- ExtrinsicStatus["PENDING"] = "pending";
89
+ ExtrinsicStatus["QUEUED"] = "queued";
90
+ ExtrinsicStatus["SUBMITTING"] = "submitting";
90
91
  ExtrinsicStatus["PROCESSING"] = "processing";
91
92
  ExtrinsicStatus["SUCCESS"] = "success";
92
93
  ExtrinsicStatus["FAIL"] = "fail";
94
+ ExtrinsicStatus["CANCELLED"] = "cancelled";
93
95
  ExtrinsicStatus["UNKNOWN"] = "unknown";
94
96
  })(ExtrinsicStatus || (exports.ExtrinsicStatus = ExtrinsicStatus = {}));
95
97
  let BasicTxErrorType;
@@ -2892,6 +2892,13 @@ class KoniExtension {
2892
2892
  }
2893
2893
  return Promise.resolve(false);
2894
2894
  }
2895
+ async getLogoMap() {
2896
+ const [chainLogoMap, assetLogoMap] = await Promise.all([this.#koniState.chainService.getChainLogoMap(), this.#koniState.chainService.getAssetLogoMap()]);
2897
+ return {
2898
+ chainLogoMap,
2899
+ assetLogoMap
2900
+ };
2901
+ }
2895
2902
 
2896
2903
  // --------------------------------------------------------------
2897
2904
  // eslint-disable-next-line @typescript-eslint/require-await
@@ -3251,6 +3258,8 @@ class KoniExtension {
3251
3258
  return this.subscribeNotifications(id, port);
3252
3259
  case 'pri(cron.reload)':
3253
3260
  return await this.reloadCron(request);
3261
+ case 'pri(settings.getLogoMaps)':
3262
+ return await this.getLogoMap();
3254
3263
 
3255
3264
  // Default
3256
3265
  default:
@@ -221,6 +221,8 @@ class KoniState {
221
221
  onReady() {
222
222
  this.subscription.start();
223
223
  this.cron.start();
224
+ this.historyService.start().catch(console.error);
225
+ this.priceService.start().catch(console.error);
224
226
  this.ready = true;
225
227
  this.logger.log('State is ready');
226
228
  }
@@ -572,7 +574,8 @@ class KoniState {
572
574
  assetType: tokenInfo.type,
573
575
  metadata: (0, _utils._parseMetadataForSmartContractAsset)(tokenInfo.contractAddress),
574
576
  multiChainAsset: null,
575
- hasValue: (0, _utils._isChainTestNet)(this.chainService.getChainInfoByKey(tokenInfo.originChain))
577
+ hasValue: (0, _utils._isChainTestNet)(this.chainService.getChainInfoByKey(tokenInfo.originChain)),
578
+ icon: ''
576
579
  });
577
580
  return isApproved;
578
581
  } else {
@@ -1348,11 +1351,15 @@ class KoniState {
1348
1351
  this.cron.stop();
1349
1352
  this.subscription.stop();
1350
1353
  await this.pauseAllNetworks(undefined, 'IDLE mode');
1354
+ await this.historyService.stop();
1355
+ await this.priceService.stop();
1351
1356
  }
1352
1357
  async wakeup() {
1353
1358
  await this.resumeAllNetworks();
1354
1359
  this.cron.start();
1355
1360
  this.subscription.start();
1361
+ await this.historyService.start();
1362
+ await this.priceService.start();
1356
1363
  }
1357
1364
  cancelSubscription(id) {
1358
1365
  if ((0, _subscriptions.isSubscriptionRunning)(id)) {
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
@@ -15,6 +16,7 @@ var _handlers = require("@subwallet/extension-base/koni/background/handlers");
15
16
  var _constants2 = require("@subwallet/extension-base/services/chain-service/constants");
16
17
  var _utils = require("@subwallet/extension-base/services/chain-service/utils");
17
18
  var _types = require("@subwallet/extension-base/services/event-service/types");
19
+ var _axios = _interopRequireDefault(require("axios"));
18
20
  var _util = require("@polkadot/util");
19
21
  var _utilCrypto = require("@polkadot/util-crypto");
20
22
  // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
@@ -238,6 +240,17 @@ class KoniSubscription {
238
240
  const result = [...poolingStakingRewards, ...amplitudeUnclaimedStakingRewards];
239
241
  this.state.updateStakingReward(result, 'fastInterval');
240
242
  }
243
+ async fetchingStakingFromApi() {
244
+ try {
245
+ const response = await _axios.default.get('https://staking-data.subwallet.app/api/staking/get');
246
+ if (response.status === 200) {
247
+ return response.data;
248
+ }
249
+ } catch (e) {
250
+ this.logger.error(e);
251
+ }
252
+ return {};
253
+ }
241
254
  async fetchChainStakingMetadata(chainInfoMap, chainStateMap, substrateApiMap) {
242
255
  const filteredChainInfoMap = {};
243
256
  Object.values(chainInfoMap).forEach(chainInfo => {
@@ -249,9 +262,18 @@ class KoniSubscription {
249
262
  if (Object.values(filteredChainInfoMap).length === 0) {
250
263
  return;
251
264
  }
265
+
266
+ // Fetch data from helper API
267
+ const dataFromApi = await this.fetchingStakingFromApi();
252
268
  await Promise.all(Object.values(filteredChainInfoMap).map(async chainInfo => {
253
- const chainStakingMetadata = await (0, _bonding.getChainStakingMetadata)(chainInfo, substrateApiMap[chainInfo.slug]);
254
- this.state.updateChainStakingMetadata(chainStakingMetadata);
269
+ // Use fetch API data if available
270
+ if (dataFromApi[chainInfo.slug]) {
271
+ this.state.updateChainStakingMetadata(dataFromApi[chainInfo.slug]);
272
+ } else {
273
+ console.warn('Not found staking data from api', chainInfo.slug);
274
+ const chainStakingMetadata = await (0, _bonding.getChainStakingMetadata)(chainInfo, substrateApiMap[chainInfo.slug]);
275
+ this.state.updateChainStakingMetadata(chainStakingMetadata);
276
+ }
255
277
  }));
256
278
  }
257
279
  async fetchNominatorMetadata(currentAddress, chainInfoMap, chainStateMap, substrateApiMap) {
@@ -13,6 +13,6 @@ const packageInfo = {
13
13
  name: '@subwallet/extension-base',
14
14
  path: typeof __dirname === 'string' ? __dirname : 'auto',
15
15
  type: 'cjs',
16
- version: '1.0.2-3'
16
+ version: '1.0.4-0'
17
17
  };
18
18
  exports.packageInfo = packageInfo;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ServiceStatus = void 0;
7
+ // Copyright 2019-2022 @subwallet/extension-base
8
+ // SPDX-License-Identifier: Apache-2.0
9
+ // 'init' | 'started' | 'starting' | 'stopped' | 'stopping'
10
+ let ServiceStatus;
11
+ exports.ServiceStatus = ServiceStatus;
12
+ (function (ServiceStatus) {
13
+ ServiceStatus["NOT_INITIALIZED"] = "not_initialized";
14
+ ServiceStatus["INITIALIZING"] = "initializing";
15
+ ServiceStatus["INITIALIZED"] = "initialized";
16
+ ServiceStatus["STARTED"] = "started";
17
+ ServiceStatus["STARTING"] = "starting";
18
+ ServiceStatus["STOPPED"] = "stopped";
19
+ ServiceStatus["STOPPING"] = "stopping";
20
+ })(ServiceStatus || (exports.ServiceStatus = ServiceStatus = {}));
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports._XCM_TYPE = exports._XCM_CHAIN_GROUP = exports._TRANSFER_NOT_SUPPORTED_CHAINS = exports._TRANSFER_CHAIN_GROUP = exports._SUBSTRATE_DEFAULT_INFLATION_PARAMS = exports._STAKING_ERA_LENGTH_MAP = exports._STAKING_CHAIN_GROUP = exports._PURE_EVM_CHAINS = exports._PREDEFINED_SINGLE_MODES = exports._PARACHAIN_INFLATION_DISTRIBUTION = exports._NFT_CHAIN_GROUP = exports._KNOWN_CHAIN_INFLATION_PARAMS = exports._DEFAULT_ACTIVE_CHAINS = exports._BALANCE_TOKEN_GROUP = exports._BALANCE_PARSING_CHAIN_GROUP = exports._BALANCE_CHAIN_GROUP = exports._API_OPTIONS_CHAIN_GROUP = exports.API_MAX_RETRY = exports.API_AUTO_CONNECT_MS = void 0;
6
+ exports._XCM_TYPE = exports._XCM_CHAIN_GROUP = exports._TRANSFER_NOT_SUPPORTED_CHAINS = exports._TRANSFER_CHAIN_GROUP = exports._SUBSTRATE_DEFAULT_INFLATION_PARAMS = exports._STAKING_ERA_LENGTH_MAP = exports._STAKING_CHAIN_GROUP = exports._PURE_EVM_CHAINS = exports._PREDEFINED_SINGLE_MODES = exports._PARACHAIN_INFLATION_DISTRIBUTION = exports._NFT_CHAIN_GROUP = exports._MULTI_CHAIN_ASSET_SRC = exports._KNOWN_CHAIN_INFLATION_PARAMS = exports._DEFAULT_ACTIVE_CHAINS = exports._CHAIN_LOGO_MAP_SRC = exports._CHAIN_INFO_SRC = exports._CHAIN_ASSET_SRC = exports._BALANCE_TOKEN_GROUP = exports._BALANCE_PARSING_CHAIN_GROUP = exports._BALANCE_CHAIN_GROUP = exports._ASSET_REF_SRC = exports._ASSET_LOGO_MAP_SRC = exports._API_OPTIONS_CHAIN_GROUP = exports.API_MAX_RETRY = exports.API_AUTO_CONNECT_MS = void 0;
7
7
  var _chainList = require("@subwallet/chain-list");
8
8
  var _types = require("@subwallet/chain-list/types");
9
9
  var _KoniTypes = require("@subwallet/extension-base/background/KoniTypes");
@@ -218,4 +218,19 @@ const _XCM_TYPE = {
218
218
  };
219
219
  exports._XCM_TYPE = _XCM_TYPE;
220
220
  const _DEFAULT_ACTIVE_CHAINS = [..._chainList._DEFAULT_CHAINS];
221
- exports._DEFAULT_ACTIVE_CHAINS = _DEFAULT_ACTIVE_CHAINS;
221
+
222
+ // TODO: review
223
+ exports._DEFAULT_ACTIVE_CHAINS = _DEFAULT_ACTIVE_CHAINS;
224
+ const TARGET_BRANCH = process.env.NODE_ENV !== 'production' ? 'koni-dev' : 'master';
225
+ const _CHAIN_INFO_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/ChainInfo.json`;
226
+ exports._CHAIN_INFO_SRC = _CHAIN_INFO_SRC;
227
+ const _CHAIN_ASSET_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/ChainAsset.json`;
228
+ exports._CHAIN_ASSET_SRC = _CHAIN_ASSET_SRC;
229
+ const _ASSET_REF_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/AssetRef.json`;
230
+ exports._ASSET_REF_SRC = _ASSET_REF_SRC;
231
+ const _MULTI_CHAIN_ASSET_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/AssetRef.json`;
232
+ exports._MULTI_CHAIN_ASSET_SRC = _MULTI_CHAIN_ASSET_SRC;
233
+ const _CHAIN_LOGO_MAP_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/ChainLogoMap.json`;
234
+ exports._CHAIN_LOGO_MAP_SRC = _CHAIN_LOGO_MAP_SRC;
235
+ const _ASSET_LOGO_MAP_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/AssetLogoMap.json`;
236
+ exports._ASSET_LOGO_MAP_SRC = _ASSET_LOGO_MAP_SRC;
@@ -47,7 +47,6 @@ class ChainService {
47
47
  this.chainInfoMapSubject.next(this.dataMap.chainInfoMap);
48
48
  this.chainStateMapSubject.next(this.dataMap.chainStateMap);
49
49
  this.assetRegistrySubject.next(this.dataMap.assetRegistry);
50
- this.multiChainAssetMapSubject.next(_chainList.MultiChainAssetMap);
51
50
  this.xcmRefMapSubject.next(this.getXcmRefMap());
52
51
  this.logger = (0, _logger.logger)('chain-service');
53
52
  this.refreshChainStateInterval(3000, 6);
@@ -157,7 +156,8 @@ class ChainService {
157
156
  priceId: '',
158
157
  slug: '',
159
158
  symbol: '',
160
- hasValue: true
159
+ hasValue: true,
160
+ icon: ''
161
161
  };
162
162
  for (const assetInfo of Object.values(this.getAssetRegistry())) {
163
163
  if (assetInfo.assetType === _types._AssetType.NATIVE && assetInfo.originChain === chainSlug) {
@@ -358,7 +358,9 @@ class ChainService {
358
358
  // Business logic
359
359
  async init() {
360
360
  // TODO: reconsider the flow of initiation
361
- this.dataMap.assetRefMap = _chainList.AssetRefMap;
361
+ const [latestAssetRefMap, latestMultiChainAssetMap] = await Promise.all([this.fetchLatestData(_constants._ASSET_REF_SRC, _chainList.AssetRefMap), this.fetchLatestData(_constants._MULTI_CHAIN_ASSET_SRC, _chainList.MultiChainAssetMap)]);
362
+ this.multiChainAssetMapSubject.next(latestMultiChainAssetMap);
363
+ this.dataMap.assetRefMap = latestAssetRefMap;
362
364
  await this.initChains();
363
365
  this.chainInfoMapSubject.next(this.getChainInfoMap());
364
366
  this.chainStateMapSubject.next(this.getChainStateMap());
@@ -463,16 +465,16 @@ class ChainService {
463
465
  this.eventService.emit('chain.updateState', chainSlug);
464
466
  return true;
465
467
  }
466
- checkExistedPredefinedChain(genesisHash, evmChainId) {
468
+ checkExistedPredefinedChain(latestChainInfoMap, genesisHash, evmChainId) {
467
469
  let duplicatedSlug = '';
468
470
  if (genesisHash) {
469
- Object.values(_chainList.ChainInfoMap).forEach(chainInfo => {
471
+ Object.values(latestChainInfoMap).forEach(chainInfo => {
470
472
  if (chainInfo.substrateInfo && chainInfo.substrateInfo.genesisHash === genesisHash) {
471
473
  duplicatedSlug = chainInfo.slug;
472
474
  }
473
475
  });
474
476
  } else if (evmChainId) {
475
- Object.values(_chainList.ChainInfoMap).forEach(chainInfo => {
477
+ Object.values(latestChainInfoMap).forEach(chainInfo => {
476
478
  if (chainInfo.evmInfo && chainInfo.evmInfo.evmChainId === evmChainId) {
477
479
  duplicatedSlug = chainInfo.slug;
478
480
  }
@@ -480,8 +482,35 @@ class ChainService {
480
482
  }
481
483
  return duplicatedSlug;
482
484
  }
485
+ async fetchLatestData(src, defaultValue) {
486
+ try {
487
+ const timeout = await new Promise(resolve => {
488
+ const id = setTimeout(() => {
489
+ clearTimeout(id);
490
+ resolve(null);
491
+ }, 1000);
492
+ });
493
+ let result = defaultValue;
494
+ const resp = (await Promise.race([timeout, fetch(src)])) || null;
495
+ if (!resp) {
496
+ return result;
497
+ }
498
+ if (resp.ok) {
499
+ try {
500
+ result = await resp.json();
501
+ } catch (err) {
502
+ console.warn('Error parsing latest data', src, err);
503
+ }
504
+ }
505
+ return result;
506
+ } catch (e) {
507
+ console.warn('Error fetching latest data', src, e);
508
+ return defaultValue;
509
+ }
510
+ }
483
511
  async initChains() {
484
512
  const storedChainSettings = await this.dbService.getAllChainStore();
513
+ const latestChainInfoMap = await this.fetchLatestData(_constants._CHAIN_INFO_SRC, _chainList.ChainInfoMap);
485
514
  const storedChainSettingMap = {};
486
515
  storedChainSettings.forEach(chainStoredSetting => {
487
516
  storedChainSettingMap[chainStoredSetting.slug] = chainStoredSetting;
@@ -490,8 +519,8 @@ class ChainService {
490
519
  const deprecatedChains = [];
491
520
  const deprecatedChainMap = {};
492
521
  if (storedChainSettings.length === 0) {
493
- this.dataMap.chainInfoMap = _chainList.ChainInfoMap;
494
- Object.values(_chainList.ChainInfoMap).forEach(chainInfo => {
522
+ this.dataMap.chainInfoMap = latestChainInfoMap;
523
+ Object.values(latestChainInfoMap).forEach(chainInfo => {
495
524
  this.dataMap.chainStateMap[chainInfo.slug] = {
496
525
  currentProvider: Object.keys(chainInfo.providers)[0],
497
526
  slug: chainInfo.slug,
@@ -507,10 +536,10 @@ class ChainService {
507
536
  });
508
537
  });
509
538
  } else {
510
- const mergedChainInfoMap = _chainList.ChainInfoMap;
539
+ const mergedChainInfoMap = latestChainInfoMap;
511
540
  for (const [storedSlug, storedChainInfo] of Object.entries(storedChainSettingMap)) {
512
- if (storedSlug in _chainList.ChainInfoMap) {
513
- // check predefined chains first, update providers and currentProvider
541
+ if (storedSlug in latestChainInfoMap) {
542
+ // check predefined chains first, keep setting for providers and currentProvider
514
543
  mergedChainInfoMap[storedSlug].providers = {
515
544
  ...storedChainInfo.providers,
516
545
  ...mergedChainInfoMap[storedSlug].providers
@@ -530,7 +559,7 @@ class ChainService {
530
559
  var _storedChainInfo$subs, _storedChainInfo$evmI;
531
560
  // only custom chains are left
532
561
  // check custom chain duplicated with predefined chain => merge into predefined chain
533
- const duplicatedDefaultSlug = this.checkExistedPredefinedChain((_storedChainInfo$subs = storedChainInfo.substrateInfo) === null || _storedChainInfo$subs === void 0 ? void 0 : _storedChainInfo$subs.genesisHash, (_storedChainInfo$evmI = storedChainInfo.evmInfo) === null || _storedChainInfo$evmI === void 0 ? void 0 : _storedChainInfo$evmI.evmChainId);
562
+ const duplicatedDefaultSlug = this.checkExistedPredefinedChain(latestChainInfoMap, (_storedChainInfo$subs = storedChainInfo.substrateInfo) === null || _storedChainInfo$subs === void 0 ? void 0 : _storedChainInfo$subs.genesisHash, (_storedChainInfo$evmI = storedChainInfo.evmInfo) === null || _storedChainInfo$evmI === void 0 ? void 0 : _storedChainInfo$evmI.evmChainId);
534
563
  if (duplicatedDefaultSlug.length > 0) {
535
564
  // merge custom chain with existed chain
536
565
  mergedChainInfoMap[duplicatedDefaultSlug].providers = {
@@ -558,7 +587,8 @@ class ChainService {
558
587
  evmInfo: storedChainInfo.evmInfo,
559
588
  substrateInfo: storedChainInfo.substrateInfo,
560
589
  isTestnet: storedChainInfo.isTestnet,
561
- chainStatus: storedChainInfo.chainStatus
590
+ chainStatus: storedChainInfo.chainStatus,
591
+ icon: storedChainInfo.icon
562
592
  };
563
593
  this.dataMap.chainStateMap[storedSlug] = {
564
594
  currentProvider: storedChainInfo.currentProvider,
@@ -600,10 +630,11 @@ class ChainService {
600
630
  }
601
631
  async initAssetRegistry(deprecatedCustomChainMap) {
602
632
  const storedAssetRegistry = await this.dbService.getAllAssetStore();
633
+ const latestAssetRegistry = await this.fetchLatestData(_constants._CHAIN_ASSET_SRC, _chainList.ChainAssetMap);
603
634
  if (storedAssetRegistry.length === 0) {
604
- this.dataMap.assetRegistry = _chainList.ChainAssetMap;
635
+ this.dataMap.assetRegistry = latestAssetRegistry;
605
636
  } else {
606
- const mergedAssetRegistry = _chainList.ChainAssetMap;
637
+ const mergedAssetRegistry = latestAssetRegistry;
607
638
  const parsedStoredAssetRegistry = {};
608
639
  const deprecatedAssets = [];
609
640
 
@@ -625,7 +656,7 @@ class ChainService {
625
656
  });
626
657
  for (const assetInfo of Object.values(parsedStoredAssetRegistry)) {
627
658
  let duplicated = false;
628
- for (const defaultChainAsset of Object.values(_chainList.ChainAssetMap)) {
659
+ for (const defaultChainAsset of Object.values(latestAssetRegistry)) {
629
660
  // case merge custom asset with default asset
630
661
  if ((0, _utils._isEqualSmartContractAsset)(assetInfo, defaultChainAsset)) {
631
662
  duplicated = true;
@@ -730,7 +761,8 @@ class ChainService {
730
761
  substrateInfo,
731
762
  evmInfo,
732
763
  isTestnet: false,
733
- chainStatus: _types._ChainStatus.ACTIVE
764
+ chainStatus: _types._ChainStatus.ACTIVE,
765
+ icon: '' // Todo: Allow update with custom chain
734
766
  };
735
767
 
736
768
  // insert new chainInfo
@@ -758,7 +790,8 @@ class ChainService {
758
790
  priceId: params.chainEditInfo.priceId || null,
759
791
  slug: '',
760
792
  symbol: params.chainEditInfo.symbol,
761
- hasValue: true
793
+ hasValue: true,
794
+ icon: ''
762
795
  });
763
796
 
764
797
  // update subscription
@@ -1198,5 +1231,11 @@ class ChainService {
1198
1231
  subscribeAssetSettings() {
1199
1232
  return this.assetSettingSubject;
1200
1233
  }
1234
+ async getChainLogoMap() {
1235
+ return await this.fetchLatestData(_constants._CHAIN_LOGO_MAP_SRC, _chainList.ChainLogoMap);
1236
+ }
1237
+ async getAssetLogoMap() {
1238
+ return await this.fetchLatestData(_constants._ASSET_LOGO_MAP_SRC, _chainList.AssetLogoMap);
1239
+ }
1201
1240
  }
1202
1241
  exports.ChainService = ChainService;
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.HistoryService = void 0;
7
7
  var _constants = require("@subwallet/extension-base/constants");
8
+ var _types = require("@subwallet/extension-base/services/base/types");
9
+ var _promise = require("@subwallet/extension-base/utils/promise");
8
10
  var _uiKeyring = require("@subwallet/ui-keyring");
9
11
  var _rxjs = require("rxjs");
10
12
  var _subsquidMultiChainHistory = require("./subsquid-multi-chain-history");
@@ -18,24 +20,10 @@ class HistoryService {
18
20
  this.chainService = chainService;
19
21
  this.eventService = eventService;
20
22
  this.keyringService = keyringService;
21
- // Load history from database
22
- this.dbService.getHistories().then(histories => {
23
- this.historySubject.next(histories);
24
- }).catch(console.error);
25
-
26
- // Wait for keyring and chain ready and start
27
- Promise.all([this.eventService.waitKeyringReady, this.eventService.waitChainReady]).then(() => {
28
- this.getHistories().catch(console.log);
29
- this.eventService.on('account.add', () => {
30
- this.refreshHistoryInterval();
31
- });
32
- this.eventService.on('account.remove', address => {
33
- this.removeHistoryByAddress(address).catch(console.error);
34
- });
35
- }).catch(console.error);
23
+ this.init().catch(console.error);
36
24
  }
37
25
  fetchPromise = null;
38
- nextFetch = undefined;
26
+ interval = undefined;
39
27
  async fetchAndLoadHistories(addresses) {
40
28
  if (!addresses || addresses.length === 0) {
41
29
  return [];
@@ -59,32 +47,16 @@ class HistoryService {
59
47
  await this.addHistoryItems(historyRecords);
60
48
  return historyRecords;
61
49
  }
62
- async fetchHistories(addresses) {
63
- if (!this.fetchPromise) {
64
- // Fetch another histories data data indexer and merge it with stored in database
65
- this.fetchPromise = this.fetchAndLoadHistories(addresses);
66
- }
67
- return this.fetchPromise;
68
- }
69
- invalidCache() {
70
- this.fetchPromise = null;
71
- }
72
- refreshHistoryInterval() {
73
- clearTimeout(this.nextFetch);
74
- this.invalidCache();
75
- this.getHistories().catch(console.error);
76
- this.nextFetch = setTimeout(() => {
77
- this.refreshHistoryInterval();
78
- }, _constants.CRON_REFRESH_HISTORY_INTERVAL);
79
- }
80
50
  async getHistories() {
81
51
  const addressList = _uiKeyring.keyring.getAccounts().map(a => a.address);
82
- const currentHistories = this.historySubject.value;
83
- if (!this.fetchPromise || currentHistories.length === 0) {
84
- await this.fetchHistories(addressList);
85
- this.historySubject.next(await this.dbService.getHistories());
52
+ if (!this.fetchPromise) {
53
+ this.fetchPromise = (async () => {
54
+ await this.fetchAndLoadHistories(addressList);
55
+ const histories = await this.dbService.getHistories();
56
+ this.historySubject.next(histories);
57
+ })();
86
58
  }
87
- return this.historySubject.getValue();
59
+ return Promise.resolve(this.historySubject.getValue());
88
60
  }
89
61
  async getHistorySubject() {
90
62
  await this.getHistories();
@@ -103,6 +75,10 @@ class HistoryService {
103
75
  });
104
76
  await this.addHistoryItems(updatedRecords);
105
77
  }
78
+ async updateHistoryByExtrinsicHash(extrinsicHash, updateData) {
79
+ await this.dbService.updateHistoryByNewExtrinsicHash(extrinsicHash, updateData);
80
+ this.historySubject.next(await this.dbService.getHistories());
81
+ }
106
82
 
107
83
  // Insert history without check override origin 'app'
108
84
  async insertHistories(historyItems) {
@@ -131,5 +107,74 @@ class HistoryService {
131
107
  await this.dbService.stores.transaction.removeAllByAddress(address);
132
108
  this.historySubject.next(await this.dbService.getHistories());
133
109
  }
110
+ status = _types.ServiceStatus.NOT_INITIALIZED;
111
+ async loadData() {
112
+ const histories = await this.dbService.getHistories();
113
+ this.historySubject.next(histories);
114
+ }
115
+ async persistData() {
116
+ await this.dbService.upsertHistory(this.historySubject.value);
117
+ }
118
+ async startCron() {
119
+ await this.getHistories();
120
+ this.interval = setInterval(() => {
121
+ this.getHistories().catch(console.error);
122
+ }, _constants.CRON_REFRESH_HISTORY_INTERVAL);
123
+ }
124
+ stopCron() {
125
+ clearTimeout(this.interval);
126
+ this.fetchPromise = null;
127
+ return Promise.resolve();
128
+ }
129
+ startPromiseHandler = (0, _promise.createPromiseHandler)();
130
+ async init() {
131
+ this.status = _types.ServiceStatus.INITIALIZING;
132
+ await this.loadData();
133
+ Promise.all([this.eventService.waitKeyringReady, this.eventService.waitChainReady]).then(() => {
134
+ this.getHistories().catch(console.log);
135
+ this.eventService.on('account.add', () => {
136
+ (async () => {
137
+ await this.stopCron();
138
+ await this.startCron();
139
+ })().catch(console.error);
140
+ });
141
+ this.eventService.on('account.remove', address => {
142
+ this.removeHistoryByAddress(address).catch(console.error);
143
+ });
144
+ }).catch(console.error);
145
+ this.status = _types.ServiceStatus.INITIALIZED;
146
+ }
147
+ async start() {
148
+ try {
149
+ console.debug('Start history service');
150
+ this.startPromiseHandler = (0, _promise.createPromiseHandler)();
151
+ this.status = _types.ServiceStatus.STARTING;
152
+ await this.startCron();
153
+ this.status = _types.ServiceStatus.STARTED;
154
+ this.startPromiseHandler.resolve();
155
+ } catch (e) {
156
+ this.startPromiseHandler.reject(e);
157
+ }
158
+ }
159
+ waitForStarted() {
160
+ return this.startPromiseHandler.promise;
161
+ }
162
+ stopPromiseHandler = (0, _promise.createPromiseHandler)();
163
+ async stop() {
164
+ console.debug('Stop history service');
165
+ try {
166
+ this.stopPromiseHandler = (0, _promise.createPromiseHandler)();
167
+ this.status = _types.ServiceStatus.STOPPING;
168
+ await this.persistData();
169
+ await this.stopCron();
170
+ this.stopPromiseHandler.resolve();
171
+ this.status = _types.ServiceStatus.STOPPED;
172
+ } catch (e) {
173
+ this.stopPromiseHandler.reject(e);
174
+ }
175
+ }
176
+ waitForStopped() {
177
+ return this.stopPromiseHandler.promise;
178
+ }
134
179
  }
135
180
  exports.HistoryService = HistoryService;
@@ -33,7 +33,8 @@ class MigrateImportedToken extends _Base.default {
33
33
  originChain: item.chain,
34
34
  priceId: null,
35
35
  slug: '',
36
- symbol: item.symbol || ''
36
+ symbol: item.symbol || '',
37
+ icon: ''
37
38
  });
38
39
  } catch (e) {
39
40
  console.log(e);