@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
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.0.2-3",
20
+ "version": "1.0.4-0",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -495,6 +495,11 @@
495
495
  "require": "./cjs/services/balance-service/index.js",
496
496
  "default": "./services/balance-service/index.js"
497
497
  },
498
+ "./services/base/types": {
499
+ "types": "./services/base/types.d.ts",
500
+ "require": "./cjs/services/base/types.js",
501
+ "default": "./services/base/types.js"
502
+ },
498
503
  "./services/chain-service": {
499
504
  "types": "./services/chain-service/index.d.ts",
500
505
  "require": "./cjs/services/chain-service/index.js",
@@ -525,10 +530,10 @@
525
530
  "require": "./cjs/services/chain-service/handler/types.js",
526
531
  "default": "./services/chain-service/handler/types.js"
527
532
  },
528
- "./services/chain-service/heath-check": {
529
- "types": "./services/chain-service/heath-check/index.d.ts",
530
- "require": "./cjs/services/chain-service/heath-check/index.js",
531
- "default": "./services/chain-service/heath-check/index.js"
533
+ "./services/chain-service/health-check": {
534
+ "types": "./services/chain-service/health-check/index.d.ts",
535
+ "require": "./cjs/services/chain-service/health-check/index.js",
536
+ "default": "./services/chain-service/health-check/index.js"
532
537
  },
533
538
  "./services/chain-service/helper": {
534
539
  "types": "./services/chain-service/helper/index.d.ts",
@@ -1595,6 +1600,11 @@
1595
1600
  "require": "./cjs/utils/keyring.js",
1596
1601
  "default": "./utils/keyring.js"
1597
1602
  },
1603
+ "./utils/promise": {
1604
+ "types": "./utils/promise.d.ts",
1605
+ "require": "./cjs/utils/promise.js",
1606
+ "default": "./utils/promise.js"
1607
+ },
1598
1608
  "./utils/request": {
1599
1609
  "types": "./utils/request.d.ts",
1600
1610
  "require": "./cjs/utils/request.js",
@@ -1604,7 +1614,7 @@
1604
1614
  "dependencies": {
1605
1615
  "@acala-network/api": "^4.1.8-2.3",
1606
1616
  "@acala-network/type-definitions": "^4.1.5",
1607
- "@apollo/client": "^3.7.3",
1617
+ "@apollo/client": "^3.7.14",
1608
1618
  "@babel/runtime": "^7.20.6",
1609
1619
  "@bifrost-finance/type-definitions": "^1.7.2",
1610
1620
  "@crustio/type-definitions": "^1.3.0",
@@ -1639,7 +1649,7 @@
1639
1649
  "@polkadot/hw-ledger": "^10.1.9",
1640
1650
  "@polkadot/keyring": "^10.2.1",
1641
1651
  "@polkadot/networks": "^10.2.1",
1642
- "@polkadot/phishing": "^0.21.1",
1652
+ "@polkadot/phishing": "^0.21.2",
1643
1653
  "@polkadot/react-identicon": "^2.9.14",
1644
1654
  "@polkadot/react-qr": "^2.9.14",
1645
1655
  "@polkadot/rpc-provider": "^9.10.3",
@@ -1656,11 +1666,11 @@
1656
1666
  "@sora-substrate/type-definitions": "^1.12.4",
1657
1667
  "@subsocial/types": "^0.6.8",
1658
1668
  "@substrate/connect": "^0.7.18",
1659
- "@subwallet/chain-list": "^0.0.32",
1660
- "@subwallet/extension-base": "^1.0.2-3",
1661
- "@subwallet/extension-chains": "^1.0.2-3",
1662
- "@subwallet/extension-dapp": "^1.0.2-3",
1663
- "@subwallet/extension-inject": "^1.0.2-3",
1669
+ "@subwallet/chain-list": "^0.1.2",
1670
+ "@subwallet/extension-base": "^1.0.4-0",
1671
+ "@subwallet/extension-chains": "^1.0.4-0",
1672
+ "@subwallet/extension-dapp": "^1.0.4-0",
1673
+ "@subwallet/extension-inject": "^1.0.4-0",
1664
1674
  "@subwallet/keyring": "^0.0.5",
1665
1675
  "@subwallet/ui-keyring": "^0.0.3",
1666
1676
  "@unique-nft/types": "^0.6.0-4",
package/packageInfo.js CHANGED
@@ -7,5 +7,5 @@ export const packageInfo = {
7
7
  name: '@subwallet/extension-base',
8
8
  path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto',
9
9
  type: 'esm',
10
- version: '1.0.2-3'
10
+ version: '1.0.4-0'
11
11
  };
@@ -0,0 +1,34 @@
1
+ import { PromiseHandler } from '@subwallet/extension-base/utils/promise';
2
+ export declare enum ServiceStatus {
3
+ NOT_INITIALIZED = "not_initialized",
4
+ INITIALIZING = "initializing",
5
+ INITIALIZED = "initialized",
6
+ STARTED = "started",
7
+ STARTING = "starting",
8
+ STOPPED = "stopped",
9
+ STOPPING = "stopping"
10
+ }
11
+ export interface CoreServiceInterface {
12
+ status: ServiceStatus;
13
+ init: () => Promise<void>;
14
+ startPromiseHandler: PromiseHandler<void>;
15
+ start: () => Promise<void>;
16
+ waitForStarted: () => Promise<void>;
17
+ }
18
+ export interface StoppableServiceInterface extends CoreServiceInterface {
19
+ stopPromiseHandler: PromiseHandler<void>;
20
+ stop: () => Promise<void>;
21
+ waitForStopped: () => Promise<void>;
22
+ }
23
+ export interface PersistDataServiceInterface {
24
+ loadData: () => Promise<void>;
25
+ persistData: () => Promise<void>;
26
+ }
27
+ export interface SubscribeServiceInterface {
28
+ subscribe: () => Promise<void>;
29
+ unsubscribe: () => Promise<void>;
30
+ }
31
+ export interface CronServiceInterface {
32
+ startCron: () => Promise<void>;
33
+ stopCron: () => Promise<void>;
34
+ }
@@ -0,0 +1,15 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ // 'init' | 'started' | 'starting' | 'stopped' | 'stopping'
5
+
6
+ export let ServiceStatus;
7
+ (function (ServiceStatus) {
8
+ ServiceStatus["NOT_INITIALIZED"] = "not_initialized";
9
+ ServiceStatus["INITIALIZING"] = "initializing";
10
+ ServiceStatus["INITIALIZED"] = "initialized";
11
+ ServiceStatus["STARTED"] = "started";
12
+ ServiceStatus["STARTING"] = "starting";
13
+ ServiceStatus["STOPPED"] = "stopped";
14
+ ServiceStatus["STOPPING"] = "stopping";
15
+ })(ServiceStatus || (ServiceStatus = {}));
@@ -75,3 +75,9 @@ export declare const _XCM_TYPE: {
75
75
  PR: string;
76
76
  };
77
77
  export declare const _DEFAULT_ACTIVE_CHAINS: string[];
78
+ export declare const _CHAIN_INFO_SRC: string;
79
+ export declare const _CHAIN_ASSET_SRC: string;
80
+ export declare const _ASSET_REF_SRC: string;
81
+ export declare const _MULTI_CHAIN_ASSET_SRC: string;
82
+ export declare const _CHAIN_LOGO_MAP_SRC: string;
83
+ export declare const _ASSET_LOGO_MAP_SRC: string;
@@ -201,4 +201,13 @@ export const _XCM_TYPE = {
201
201
  PR: `${_SubstrateChainType.PARACHAIN}-${_SubstrateChainType.RELAYCHAIN}` // UMP
202
202
  };
203
203
 
204
- export const _DEFAULT_ACTIVE_CHAINS = [..._DEFAULT_CHAINS];
204
+ export const _DEFAULT_ACTIVE_CHAINS = [..._DEFAULT_CHAINS];
205
+
206
+ // TODO: review
207
+ const TARGET_BRANCH = process.env.NODE_ENV !== 'production' ? 'koni-dev' : 'master';
208
+ export const _CHAIN_INFO_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/ChainInfo.json`;
209
+ export const _CHAIN_ASSET_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/ChainAsset.json`;
210
+ export const _ASSET_REF_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/AssetRef.json`;
211
+ export const _MULTI_CHAIN_ASSET_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/AssetRef.json`;
212
+ export const _CHAIN_LOGO_MAP_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/ChainLogoMap.json`;
213
+ export const _ASSET_LOGO_MAP_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/AssetLogoMap.json`;
@@ -71,6 +71,7 @@ export declare class ChainService {
71
71
  enableChains(chainSlugs: string[]): boolean;
72
72
  disableChain(chainSlug: string): boolean;
73
73
  private checkExistedPredefinedChain;
74
+ private fetchLatestData;
74
75
  private initChains;
75
76
  private initAssetRegistry;
76
77
  private updateChainStateMapSubscription;
@@ -102,4 +103,6 @@ export declare class ChainService {
102
103
  updateAssetSetting(assetSlug: string, assetSetting: AssetSetting): Promise<boolean | undefined>;
103
104
  updateAssetSettingByChain(chainSlug: string, visible: boolean): Promise<void>;
104
105
  subscribeAssetSettings(): BehaviorSubject<Record<string, AssetSetting>>;
106
+ getChainLogoMap(): Promise<Record<string, string>>;
107
+ getAssetLogoMap(): Promise<Record<string, string>>;
105
108
  }
@@ -1,9 +1,9 @@
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 { _DEFAULT_ACTIVE_CHAINS } from '@subwallet/extension-base/services/chain-service/constants';
6
+ import { _ASSET_LOGO_MAP_SRC, _ASSET_REF_SRC, _CHAIN_ASSET_SRC, _CHAIN_INFO_SRC, _CHAIN_LOGO_MAP_SRC, _DEFAULT_ACTIVE_CHAINS, _MULTI_CHAIN_ASSET_SRC } from '@subwallet/extension-base/services/chain-service/constants';
7
7
  import { EvmChainHandler } from '@subwallet/extension-base/services/chain-service/handler/EvmChainHandler';
8
8
  import { SubstrateChainHandler } from '@subwallet/extension-base/services/chain-service/handler/SubstrateChainHandler';
9
9
  import { _CHAIN_VALIDATION_ERROR } from '@subwallet/extension-base/services/chain-service/handler/types';
@@ -40,7 +40,6 @@ export class ChainService {
40
40
  this.chainInfoMapSubject.next(this.dataMap.chainInfoMap);
41
41
  this.chainStateMapSubject.next(this.dataMap.chainStateMap);
42
42
  this.assetRegistrySubject.next(this.dataMap.assetRegistry);
43
- this.multiChainAssetMapSubject.next(MultiChainAssetMap);
44
43
  this.xcmRefMapSubject.next(this.getXcmRefMap());
45
44
  this.logger = createLogger('chain-service');
46
45
  this.refreshChainStateInterval(3000, 6);
@@ -149,7 +148,8 @@ export class ChainService {
149
148
  priceId: '',
150
149
  slug: '',
151
150
  symbol: '',
152
- hasValue: true
151
+ hasValue: true,
152
+ icon: ''
153
153
  };
154
154
  for (const assetInfo of Object.values(this.getAssetRegistry())) {
155
155
  if (assetInfo.assetType === _AssetType.NATIVE && assetInfo.originChain === chainSlug) {
@@ -349,7 +349,9 @@ export class ChainService {
349
349
  // Business logic
350
350
  async init() {
351
351
  // TODO: reconsider the flow of initiation
352
- this.dataMap.assetRefMap = AssetRefMap;
352
+ const [latestAssetRefMap, latestMultiChainAssetMap] = await Promise.all([this.fetchLatestData(_ASSET_REF_SRC, AssetRefMap), this.fetchLatestData(_MULTI_CHAIN_ASSET_SRC, MultiChainAssetMap)]);
353
+ this.multiChainAssetMapSubject.next(latestMultiChainAssetMap);
354
+ this.dataMap.assetRefMap = latestAssetRefMap;
353
355
  await this.initChains();
354
356
  this.chainInfoMapSubject.next(this.getChainInfoMap());
355
357
  this.chainStateMapSubject.next(this.getChainStateMap());
@@ -451,16 +453,16 @@ export class ChainService {
451
453
  this.eventService.emit('chain.updateState', chainSlug);
452
454
  return true;
453
455
  }
454
- checkExistedPredefinedChain(genesisHash, evmChainId) {
456
+ checkExistedPredefinedChain(latestChainInfoMap, genesisHash, evmChainId) {
455
457
  let duplicatedSlug = '';
456
458
  if (genesisHash) {
457
- Object.values(ChainInfoMap).forEach(chainInfo => {
459
+ Object.values(latestChainInfoMap).forEach(chainInfo => {
458
460
  if (chainInfo.substrateInfo && chainInfo.substrateInfo.genesisHash === genesisHash) {
459
461
  duplicatedSlug = chainInfo.slug;
460
462
  }
461
463
  });
462
464
  } else if (evmChainId) {
463
- Object.values(ChainInfoMap).forEach(chainInfo => {
465
+ Object.values(latestChainInfoMap).forEach(chainInfo => {
464
466
  if (chainInfo.evmInfo && chainInfo.evmInfo.evmChainId === evmChainId) {
465
467
  duplicatedSlug = chainInfo.slug;
466
468
  }
@@ -468,8 +470,35 @@ export class ChainService {
468
470
  }
469
471
  return duplicatedSlug;
470
472
  }
473
+ async fetchLatestData(src, defaultValue) {
474
+ try {
475
+ const timeout = await new Promise(resolve => {
476
+ const id = setTimeout(() => {
477
+ clearTimeout(id);
478
+ resolve(null);
479
+ }, 1000);
480
+ });
481
+ let result = defaultValue;
482
+ const resp = (await Promise.race([timeout, fetch(src)])) || null;
483
+ if (!resp) {
484
+ return result;
485
+ }
486
+ if (resp.ok) {
487
+ try {
488
+ result = await resp.json();
489
+ } catch (err) {
490
+ console.warn('Error parsing latest data', src, err);
491
+ }
492
+ }
493
+ return result;
494
+ } catch (e) {
495
+ console.warn('Error fetching latest data', src, e);
496
+ return defaultValue;
497
+ }
498
+ }
471
499
  async initChains() {
472
500
  const storedChainSettings = await this.dbService.getAllChainStore();
501
+ const latestChainInfoMap = await this.fetchLatestData(_CHAIN_INFO_SRC, ChainInfoMap);
473
502
  const storedChainSettingMap = {};
474
503
  storedChainSettings.forEach(chainStoredSetting => {
475
504
  storedChainSettingMap[chainStoredSetting.slug] = chainStoredSetting;
@@ -478,8 +507,8 @@ export class ChainService {
478
507
  const deprecatedChains = [];
479
508
  const deprecatedChainMap = {};
480
509
  if (storedChainSettings.length === 0) {
481
- this.dataMap.chainInfoMap = ChainInfoMap;
482
- Object.values(ChainInfoMap).forEach(chainInfo => {
510
+ this.dataMap.chainInfoMap = latestChainInfoMap;
511
+ Object.values(latestChainInfoMap).forEach(chainInfo => {
483
512
  this.dataMap.chainStateMap[chainInfo.slug] = {
484
513
  currentProvider: Object.keys(chainInfo.providers)[0],
485
514
  slug: chainInfo.slug,
@@ -495,10 +524,10 @@ export class ChainService {
495
524
  });
496
525
  });
497
526
  } else {
498
- const mergedChainInfoMap = ChainInfoMap;
527
+ const mergedChainInfoMap = latestChainInfoMap;
499
528
  for (const [storedSlug, storedChainInfo] of Object.entries(storedChainSettingMap)) {
500
- if (storedSlug in ChainInfoMap) {
501
- // check predefined chains first, update providers and currentProvider
529
+ if (storedSlug in latestChainInfoMap) {
530
+ // check predefined chains first, keep setting for providers and currentProvider
502
531
  mergedChainInfoMap[storedSlug].providers = {
503
532
  ...storedChainInfo.providers,
504
533
  ...mergedChainInfoMap[storedSlug].providers
@@ -518,7 +547,7 @@ export class ChainService {
518
547
  var _storedChainInfo$subs, _storedChainInfo$evmI;
519
548
  // only custom chains are left
520
549
  // check custom chain duplicated with predefined chain => merge into predefined chain
521
- 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);
550
+ 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);
522
551
  if (duplicatedDefaultSlug.length > 0) {
523
552
  // merge custom chain with existed chain
524
553
  mergedChainInfoMap[duplicatedDefaultSlug].providers = {
@@ -546,7 +575,8 @@ export class ChainService {
546
575
  evmInfo: storedChainInfo.evmInfo,
547
576
  substrateInfo: storedChainInfo.substrateInfo,
548
577
  isTestnet: storedChainInfo.isTestnet,
549
- chainStatus: storedChainInfo.chainStatus
578
+ chainStatus: storedChainInfo.chainStatus,
579
+ icon: storedChainInfo.icon
550
580
  };
551
581
  this.dataMap.chainStateMap[storedSlug] = {
552
582
  currentProvider: storedChainInfo.currentProvider,
@@ -587,10 +617,11 @@ export class ChainService {
587
617
  }
588
618
  async initAssetRegistry(deprecatedCustomChainMap) {
589
619
  const storedAssetRegistry = await this.dbService.getAllAssetStore();
620
+ const latestAssetRegistry = await this.fetchLatestData(_CHAIN_ASSET_SRC, ChainAssetMap);
590
621
  if (storedAssetRegistry.length === 0) {
591
- this.dataMap.assetRegistry = ChainAssetMap;
622
+ this.dataMap.assetRegistry = latestAssetRegistry;
592
623
  } else {
593
- const mergedAssetRegistry = ChainAssetMap;
624
+ const mergedAssetRegistry = latestAssetRegistry;
594
625
  const parsedStoredAssetRegistry = {};
595
626
  const deprecatedAssets = [];
596
627
 
@@ -612,7 +643,7 @@ export class ChainService {
612
643
  });
613
644
  for (const assetInfo of Object.values(parsedStoredAssetRegistry)) {
614
645
  let duplicated = false;
615
- for (const defaultChainAsset of Object.values(ChainAssetMap)) {
646
+ for (const defaultChainAsset of Object.values(latestAssetRegistry)) {
616
647
  // case merge custom asset with default asset
617
648
  if (_isEqualSmartContractAsset(assetInfo, defaultChainAsset)) {
618
649
  duplicated = true;
@@ -717,7 +748,8 @@ export class ChainService {
717
748
  substrateInfo,
718
749
  evmInfo,
719
750
  isTestnet: false,
720
- chainStatus: _ChainStatus.ACTIVE
751
+ chainStatus: _ChainStatus.ACTIVE,
752
+ icon: '' // Todo: Allow update with custom chain
721
753
  };
722
754
 
723
755
  // insert new chainInfo
@@ -745,7 +777,8 @@ export class ChainService {
745
777
  priceId: params.chainEditInfo.priceId || null,
746
778
  slug: '',
747
779
  symbol: params.chainEditInfo.symbol,
748
- hasValue: true
780
+ hasValue: true,
781
+ icon: ''
749
782
  });
750
783
 
751
784
  // update subscription
@@ -1181,4 +1214,10 @@ export class ChainService {
1181
1214
  subscribeAssetSettings() {
1182
1215
  return this.assetSettingSubject;
1183
1216
  }
1217
+ async getChainLogoMap() {
1218
+ return await this.fetchLatestData(_CHAIN_LOGO_MAP_SRC, ChainLogoMap);
1219
+ }
1220
+ async getAssetLogoMap() {
1221
+ return await this.fetchLatestData(_ASSET_LOGO_MAP_SRC, AssetLogoMap);
1222
+ }
1184
1223
  }
@@ -1,10 +1,11 @@
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';
4
5
  import { KeyringService } from '@subwallet/extension-base/services/keyring-service';
5
6
  import DatabaseService from '@subwallet/extension-base/services/storage-service/DatabaseService';
6
7
  import { BehaviorSubject } from 'rxjs';
7
- export declare class HistoryService {
8
+ export declare class HistoryService implements StoppableServiceInterface, PersistDataServiceInterface, CronServiceInterface {
8
9
  private dbService;
9
10
  private chainService;
10
11
  private eventService;
@@ -12,15 +13,33 @@ export declare class HistoryService {
12
13
  private historySubject;
13
14
  constructor(dbService: DatabaseService, chainService: ChainService, eventService: EventService, keyringService: KeyringService);
14
15
  private fetchPromise;
15
- private nextFetch;
16
+ private interval;
16
17
  private fetchAndLoadHistories;
17
- fetchHistories(addresses: string[]): Promise<TransactionHistoryItem<import("@subwallet/extension-base/background/KoniTypes").ExtrinsicType.TRANSFER_BALANCE>[]>;
18
- invalidCache(): void;
19
- refreshHistoryInterval(): void;
20
18
  getHistories(): Promise<TransactionHistoryItem<import("@subwallet/extension-base/background/KoniTypes").ExtrinsicType.TRANSFER_BALANCE>[]>;
21
19
  getHistorySubject(): Promise<BehaviorSubject<TransactionHistoryItem<import("@subwallet/extension-base/background/KoniTypes").ExtrinsicType.TRANSFER_BALANCE>[]>>;
22
20
  updateHistories(chain: string, extrinsicHash: string, updateData: Partial<TransactionHistoryItem>): Promise<void>;
21
+ updateHistoryByExtrinsicHash(extrinsicHash: string, updateData: Partial<TransactionHistoryItem>): Promise<void>;
23
22
  insertHistories(historyItems: TransactionHistoryItem[]): Promise<void>;
24
23
  addHistoryItems(historyItems: TransactionHistoryItem[]): Promise<void>;
25
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>;
26
45
  }
@@ -2,6 +2,8 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { CRON_REFRESH_HISTORY_INTERVAL } from '@subwallet/extension-base/constants';
5
+ import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
6
+ import { createPromiseHandler } from '@subwallet/extension-base/utils/promise';
5
7
  import { keyring } from '@subwallet/ui-keyring';
6
8
  import { BehaviorSubject } from 'rxjs';
7
9
  import { fetchMultiChainHistories } from "./subsquid-multi-chain-history.js";
@@ -12,24 +14,10 @@ export class HistoryService {
12
14
  this.chainService = chainService;
13
15
  this.eventService = eventService;
14
16
  this.keyringService = keyringService;
15
- // Load history from database
16
- this.dbService.getHistories().then(histories => {
17
- this.historySubject.next(histories);
18
- }).catch(console.error);
19
-
20
- // Wait for keyring and chain ready and start
21
- Promise.all([this.eventService.waitKeyringReady, this.eventService.waitChainReady]).then(() => {
22
- this.getHistories().catch(console.log);
23
- this.eventService.on('account.add', () => {
24
- this.refreshHistoryInterval();
25
- });
26
- this.eventService.on('account.remove', address => {
27
- this.removeHistoryByAddress(address).catch(console.error);
28
- });
29
- }).catch(console.error);
17
+ this.init().catch(console.error);
30
18
  }
31
19
  fetchPromise = null;
32
- nextFetch = undefined;
20
+ interval = undefined;
33
21
  async fetchAndLoadHistories(addresses) {
34
22
  if (!addresses || addresses.length === 0) {
35
23
  return [];
@@ -52,32 +40,16 @@ export class HistoryService {
52
40
  await this.addHistoryItems(historyRecords);
53
41
  return historyRecords;
54
42
  }
55
- async fetchHistories(addresses) {
56
- if (!this.fetchPromise) {
57
- // Fetch another histories data data indexer and merge it with stored in database
58
- this.fetchPromise = this.fetchAndLoadHistories(addresses);
59
- }
60
- return this.fetchPromise;
61
- }
62
- invalidCache() {
63
- this.fetchPromise = null;
64
- }
65
- refreshHistoryInterval() {
66
- clearTimeout(this.nextFetch);
67
- this.invalidCache();
68
- this.getHistories().catch(console.error);
69
- this.nextFetch = setTimeout(() => {
70
- this.refreshHistoryInterval();
71
- }, CRON_REFRESH_HISTORY_INTERVAL);
72
- }
73
43
  async getHistories() {
74
44
  const addressList = keyring.getAccounts().map(a => a.address);
75
- const currentHistories = this.historySubject.value;
76
- if (!this.fetchPromise || currentHistories.length === 0) {
77
- await this.fetchHistories(addressList);
78
- this.historySubject.next(await this.dbService.getHistories());
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
+ })();
79
51
  }
80
- return this.historySubject.getValue();
52
+ return Promise.resolve(this.historySubject.getValue());
81
53
  }
82
54
  async getHistorySubject() {
83
55
  await this.getHistories();
@@ -96,6 +68,10 @@ export class HistoryService {
96
68
  });
97
69
  await this.addHistoryItems(updatedRecords);
98
70
  }
71
+ async updateHistoryByExtrinsicHash(extrinsicHash, updateData) {
72
+ await this.dbService.updateHistoryByNewExtrinsicHash(extrinsicHash, updateData);
73
+ this.historySubject.next(await this.dbService.getHistories());
74
+ }
99
75
 
100
76
  // Insert history without check override origin 'app'
101
77
  async insertHistories(historyItems) {
@@ -124,4 +100,73 @@ export class HistoryService {
124
100
  await this.dbService.stores.transaction.removeAllByAddress(address);
125
101
  this.historySubject.next(await this.dbService.getHistories());
126
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
+ }
127
172
  }
@@ -25,7 +25,8 @@ export default class MigrateImportedToken extends BaseMigrationJob {
25
25
  originChain: item.chain,
26
26
  priceId: null,
27
27
  slug: '',
28
- symbol: item.symbol || ''
28
+ symbol: item.symbol || '',
29
+ icon: ''
29
30
  });
30
31
  } catch (e) {
31
32
  console.log(e);
@@ -1,9 +1,11 @@
1
1
  import { PriceJson } 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';
4
5
  import DatabaseService from '@subwallet/extension-base/services/storage-service/DatabaseService';
5
6
  import { BehaviorSubject } from 'rxjs';
6
- export declare class PriceService {
7
+ export declare class PriceService implements StoppableServiceInterface, PersistDataServiceInterface, CronServiceInterface {
8
+ status: ServiceStatus;
7
9
  private dbService;
8
10
  private eventService;
9
11
  private chainService;
@@ -15,4 +17,23 @@ export declare class PriceService {
15
17
  getPriceSubject(): BehaviorSubject<PriceJson>;
16
18
  getPriceIds(): Set<string>;
17
19
  refreshPriceData(priceIds?: Set<string>): void;
20
+ init(): Promise<void>;
21
+ loadData(): Promise<void>;
22
+ persistData(): Promise<void>;
23
+ startPromiseHandler: {
24
+ resolve: (value: void) => void;
25
+ reject: (reason?: unknown) => void;
26
+ promise: Promise<void>;
27
+ };
28
+ start(): Promise<void>;
29
+ startCron(): Promise<void>;
30
+ stopPromiseHandler: {
31
+ resolve: (value: void) => void;
32
+ reject: (reason?: unknown) => void;
33
+ promise: Promise<void>;
34
+ };
35
+ stop(): Promise<void>;
36
+ stopCron(): Promise<void>;
37
+ waitForStarted(): Promise<void>;
38
+ waitForStopped(): Promise<void>;
18
39
  }