@subwallet/extension-base 1.1.51-0 → 1.1.51-2

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.
@@ -337,6 +337,7 @@ export declare type RequestChangeLanguage = {
337
337
  export declare type RequestChangeShowBalance = {
338
338
  enable: boolean;
339
339
  };
340
+ export declare type DetectBalanceCache = Record<string, number>;
340
341
  export interface RandomTestRequest {
341
342
  start: number;
342
343
  end: number;
@@ -1535,59 +1535,21 @@ class KoniState {
1535
1535
  createUnsubscriptionHandle(id, unsubscribe) {
1536
1536
  this.unsubscriptionMap[id] = unsubscribe;
1537
1537
  }
1538
- async autoEnableChains(addresses) {
1539
- const assetMap = this.chainService.getAssetRegistry();
1540
- const promiseList = addresses.map(address => {
1541
- return this.subscanService.getMultiChainBalance(address).catch(e => {
1542
- console.error(e);
1543
- return null;
1544
- });
1545
- });
1546
- const needEnableChains = [];
1547
- const needActiveTokens = [];
1548
- const currentAssetSettings = await this.chainService.getAssetSettings();
1549
- const chainMap = this.chainService.getChainInfoMap();
1550
- const balanceDataList = await Promise.all(promiseList);
1551
- balanceDataList.forEach(balanceData => {
1552
- balanceData && balanceData.forEach(_ref10 => {
1553
- var _currentAssetSettings;
1554
- let {
1555
- balance,
1556
- bonded,
1557
- category,
1558
- locked,
1559
- network,
1560
- symbol
1561
- } = _ref10;
1562
- const chain = _subscanChainMap.SUBSCAN_BALANCE_CHAIN_MAP_REVERSE[network];
1563
- const chainInfo = chain ? chainMap[chain] : null;
1564
- const balanceIsEmpty = (!balance || balance === '0') && (!locked || locked === '0') && (!bonded || bonded === '0');
1565
-
1566
- // Cancel if chain is not supported or is testnet or balance is 0
1567
- if (!chainInfo || chainInfo.isTestnet || balanceIsEmpty) {
1568
- return;
1569
- }
1570
- const tokenKey = `${chain}-${category === 'native' ? 'NATIVE' : 'LOCAL'}-${symbol.toUpperCase()}`;
1571
- const existedKey = Object.keys(assetMap).find(v => v.toLowerCase() === tokenKey.toLowerCase());
1572
- if (existedKey && !((_currentAssetSettings = currentAssetSettings[existedKey]) !== null && _currentAssetSettings !== void 0 && _currentAssetSettings.visible)) {
1573
- needEnableChains.push(chain);
1574
- needActiveTokens.push(existedKey);
1575
- currentAssetSettings[existedKey] = {
1576
- visible: true
1577
- };
1578
- }
1579
- });
1580
- });
1581
- if (needActiveTokens.length) {
1582
- await this.chainService.enableChains(needEnableChains);
1583
- this.chainService.setAssetSettings({
1584
- ...currentAssetSettings
1585
- });
1538
+ get detectBalanceChainSlugMap() {
1539
+ const result = {};
1540
+ const chainInfoMap = this.getChainInfoMap();
1541
+ for (const [key, chainInfo] of Object.entries(chainInfoMap)) {
1542
+ var _chainInfo$extraInfo;
1543
+ const chainBalanceSlug = ((_chainInfo$extraInfo = chainInfo.extraInfo) === null || _chainInfo$extraInfo === void 0 ? void 0 : _chainInfo$extraInfo.chainBalanceSlug) || '';
1544
+ if (chainBalanceSlug) {
1545
+ result[chainBalanceSlug] = key;
1546
+ }
1586
1547
  }
1548
+ return result;
1587
1549
  }
1588
1550
  onAccountAdd() {
1589
1551
  this.eventService.on('account.add', address => {
1590
- this.autoEnableChains([address]).catch(this.logger.error);
1552
+ this.balanceService.autoEnableChains([address]).catch(this.logger.error);
1591
1553
  });
1592
1554
  }
1593
1555
  onAccountRemove() {
@@ -1815,12 +1777,12 @@ class KoniState {
1815
1777
  specVersion: parseInt((metadata === null || metadata === void 0 ? void 0 : metadata.specVersion) || '0')
1816
1778
  };
1817
1779
  }
1818
- getCrowdloanContributions(_ref11) {
1780
+ getCrowdloanContributions(_ref10) {
1819
1781
  let {
1820
1782
  address,
1821
1783
  page,
1822
1784
  relayChain
1823
- } = _ref11;
1785
+ } = _ref10;
1824
1786
  return this.subscanService.getCrowdloanContributions(relayChain, address, page);
1825
1787
  }
1826
1788
  }
@@ -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.1.51-0'
16
+ version: '1.1.51-2'
17
17
  };
18
18
  exports.packageInfo = packageInfo;
@@ -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
  });
@@ -11,8 +12,12 @@ var _evm = require("@subwallet/extension-base/services/balance-service/helpers/s
11
12
  var _substrate = require("@subwallet/extension-base/services/balance-service/helpers/subscribe/substrate");
12
13
  var _constants = require("@subwallet/extension-base/services/chain-service/constants");
13
14
  var _utils = require("@subwallet/extension-base/services/chain-service/utils");
15
+ var _DetectAccountBalance = _interopRequireDefault(require("@subwallet/extension-base/stores/DetectAccountBalance"));
14
16
  var _utils2 = require("@subwallet/extension-base/utils");
17
+ var _uiKeyring = _interopRequireDefault(require("@subwallet/ui-keyring"));
15
18
  var _i18next = require("i18next");
19
+ var _rxjs = require("rxjs");
20
+ var _util = require("@polkadot/util");
16
21
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
17
22
  // SPDX-License-Identifier: Apache-2.0
18
23
 
@@ -21,6 +26,10 @@ var _i18next = require("i18next");
21
26
  * @class
22
27
  */
23
28
  class BalanceService {
29
+ detectAccountBalanceStore = new _DetectAccountBalance.default();
30
+ balanceDetectSubject = new _rxjs.BehaviorSubject({});
31
+ intervalTime = 3 * 60 * 1000;
32
+ cacheTime = 15 * 60 * 1000;
24
33
  /**
25
34
  * @constructor
26
35
  * @param {KoniState} state - The state of extension.
@@ -35,6 +44,54 @@ class BalanceService {
35
44
  // Todo: Add new account
36
45
  // Todo: Optimize get balance for single account and chain with cache
37
46
  // Todo: Move everything of fetching balance to this service
47
+
48
+ this.startHandler = (0, _utils2.createPromiseHandler)();
49
+ const updateBalanceDetectCache = value => {
50
+ this.startHandler.resolve();
51
+ this.balanceDetectSubject.next(value || {});
52
+ };
53
+ this.getBalanceDetectCache(updateBalanceDetectCache);
54
+ this.detectAccountBalanceStore.getSubject().subscribe({
55
+ next: updateBalanceDetectCache
56
+ });
57
+ this.startDetectBalance().catch(console.error);
58
+ }
59
+ async startDetectBalance() {
60
+ const scanBalance = () => {
61
+ const addresses = _uiKeyring.default.getPairs().map(account => account.address);
62
+ const cache = this.balanceDetectSubject.value;
63
+ const now = Date.now();
64
+ const needDetectAddresses = [];
65
+ for (const address of addresses) {
66
+ if (!cache[address] || now - cache[address] > this.cacheTime) {
67
+ needDetectAddresses.push(address);
68
+ }
69
+ }
70
+ if (needDetectAddresses.length) {
71
+ this.autoEnableChains(needDetectAddresses).finally(_util.noop);
72
+ }
73
+ };
74
+ await this.state.eventService.waitAccountReady;
75
+ await this.state.eventService.waitChainReady;
76
+ await this.startHandler.promise;
77
+ scanBalance();
78
+ setInterval(scanBalance, this.intervalTime);
79
+ }
80
+ getBalanceDetectCache(update) {
81
+ this.detectAccountBalanceStore.get('DetectBalanceCache', value => {
82
+ update(value);
83
+ });
84
+ }
85
+ setBalanceDetectCache(addresses) {
86
+ this.detectAccountBalanceStore.get('DetectBalanceCache', value => {
87
+ const rs = {
88
+ ...value
89
+ };
90
+ for (const address of addresses) {
91
+ rs[address] = Date.now();
92
+ }
93
+ this.detectAccountBalanceStore.set('DetectBalanceCache', rs);
94
+ });
38
95
  }
39
96
 
40
97
  /* Subscribe token free balance on chain */
@@ -138,5 +195,73 @@ class BalanceService {
138
195
  });
139
196
  };
140
197
  }
198
+ async autoEnableChains(addresses) {
199
+ this.setBalanceDetectCache(addresses);
200
+ const assetMap = this.state.chainService.getAssetRegistry();
201
+ const promiseList = addresses.map(address => {
202
+ return this.state.subscanService.getMultiChainBalance(address).catch(e => {
203
+ console.error(e);
204
+ return null;
205
+ });
206
+ });
207
+ const needEnableChains = [];
208
+ const needActiveTokens = [];
209
+ const balanceDataList = await Promise.all(promiseList);
210
+ const currentAssetSettings = await this.state.chainService.getAssetSettings();
211
+ const chainInfoMap = this.state.chainService.getChainInfoMap();
212
+ const detectBalanceChainSlugMap = this.state.chainService.detectBalanceChainSlugMap;
213
+ for (const balanceData of balanceDataList) {
214
+ if (balanceData) {
215
+ for (const balanceDatum of balanceData) {
216
+ var _currentAssetSettings;
217
+ const {
218
+ balance,
219
+ bonded,
220
+ category,
221
+ locked,
222
+ network,
223
+ symbol
224
+ } = balanceDatum;
225
+ const chain = detectBalanceChainSlugMap[network];
226
+ const chainInfo = chain ? chainInfoMap[chain] : null;
227
+ const chainState = this.state.chainService.getChainStateByKey(chain);
228
+ const balanceIsEmpty = (!balance || balance === '0') && (!locked || locked === '0') && (!bonded || bonded === '0');
229
+ const tokenKey = `${chain}-${category === 'native' ? 'NATIVE' : 'LOCAL'}-${symbol.toUpperCase()}`;
230
+ const existedKey = Object.keys(assetMap).find(v => v.toLowerCase() === tokenKey.toLowerCase());
231
+
232
+ // Cancel if chain is not supported or is testnet
233
+ if (!chainInfo || chainInfo.isTestnet) {
234
+ continue;
235
+ }
236
+
237
+ // Cancel is balance is 0
238
+ if (balanceIsEmpty) {
239
+ continue;
240
+ }
241
+
242
+ // Cancel is chain is turned off by user
243
+ if (chainState && chainState.manualTurnOff) {
244
+ continue;
245
+ }
246
+
247
+ // const a = this.state.chainService.getChainStateByKey(chain);
248
+
249
+ if (existedKey && !((_currentAssetSettings = currentAssetSettings[existedKey]) !== null && _currentAssetSettings !== void 0 && _currentAssetSettings.visible)) {
250
+ needEnableChains.push(chain);
251
+ needActiveTokens.push(existedKey);
252
+ currentAssetSettings[existedKey] = {
253
+ visible: true
254
+ };
255
+ }
256
+ }
257
+ }
258
+ }
259
+ if (needActiveTokens.length) {
260
+ await this.state.chainService.enableChains(needEnableChains);
261
+ this.state.chainService.setAssetSettings({
262
+ ...currentAssetSettings
263
+ });
264
+ }
265
+ }
141
266
  }
142
267
  exports.BalanceService = BalanceService;
@@ -470,7 +470,7 @@ class ChainService {
470
470
  stopCheckLatestChainData() {
471
471
  clearInterval(this.refreshLatestChainDataTimeOut);
472
472
  }
473
- handleLatestProviderData(latestChainInfo) {
473
+ handleLatestChainData(latestChainInfo) {
474
474
  try {
475
475
  if (latestChainInfo && latestChainInfo.length > 0) {
476
476
  const {
@@ -548,6 +548,17 @@ class ChainService {
548
548
  this.assetLogoMapSubject.next(logoMap);
549
549
  }
550
550
  }
551
+ if (latestAssetLogoMap) {
552
+ const latestAssetLogoPatch = JSON.stringify(latestAssetLogoMap);
553
+ if (this.assetLogoPatch !== latestAssetLogoPatch) {
554
+ const logoMap = {
555
+ ..._chainList.AssetLogoMap,
556
+ ...latestAssetLogoMap
557
+ };
558
+ this.assetLogoPatch = latestAssetLogoPatch;
559
+ this.assetLogoMapSubject.next(logoMap);
560
+ }
561
+ }
551
562
  } catch (e) {
552
563
  console.error('Error fetching latest asset data');
553
564
  }
@@ -585,7 +596,7 @@ class ChainService {
585
596
  }).catch(console.error);
586
597
  }).catch(console.error);
587
598
  this.fetchLatestChainData().then(latestChainInfo => {
588
- this.handleLatestProviderData(latestChainInfo);
599
+ this.handleLatestChainData(latestChainInfo);
589
600
  }).catch(console.error);
590
601
  this.fetchLatestAssetRef().then(_ref7 => {
591
602
  let [latestAssetRef, latestAssetRefMap] = _ref7;
@@ -665,7 +676,8 @@ class ChainService {
665
676
  this.dbService.updateChainStore({
666
677
  ...chainInfo,
667
678
  active: true,
668
- currentProvider: chainStateMap[chainSlug].currentProvider
679
+ currentProvider: chainStateMap[chainSlug].currentProvider,
680
+ manualTurnOff: !!chainStateMap[chainSlug].manualTurnOff
669
681
  }).catch(console.error);
670
682
  chainStateMap[chainSlug].active = true;
671
683
  await this.initApiForChain(chainInfo);
@@ -690,7 +702,8 @@ class ChainService {
690
702
  this.dbService.updateChainStore({
691
703
  ...chainInfo,
692
704
  active: true,
693
- currentProvider: chainStateMap[chainSlug].currentProvider
705
+ currentProvider: chainStateMap[chainSlug].currentProvider,
706
+ manualTurnOff: !!chainStateMap[chainSlug].manualTurnOff
694
707
  }).catch(console.error);
695
708
  chainStateMap[chainSlug].active = true;
696
709
  await this.initApiForChain(chainInfo);
@@ -717,13 +730,15 @@ class ChainService {
717
730
  }
718
731
  this.lockChainInfoMap = true;
719
732
  chainStateMap[chainSlug].active = false;
733
+ chainStateMap[chainSlug].manualTurnOff = true;
720
734
  // Set disconnect state for inactive chain
721
735
  this.updateChainConnectionStatus(chainSlug, _types3._ChainConnectionStatus.DISCONNECTED);
722
736
  this.destroyApiForChain(chainInfo);
723
737
  this.dbService.updateChainStore({
724
738
  ...chainInfo,
725
739
  active: false,
726
- currentProvider: chainStateMap[chainSlug].currentProvider
740
+ currentProvider: chainStateMap[chainSlug].currentProvider,
741
+ manualTurnOff: true
727
742
  }).catch(console.error);
728
743
  this.updateChainStateMapSubscription();
729
744
  this.lockChainInfoMap = false;
@@ -815,7 +830,8 @@ class ChainService {
815
830
  this.dataMap.chainStateMap[chainInfo.slug] = {
816
831
  currentProvider: providerKey,
817
832
  slug: chainInfo.slug,
818
- active: _constants._DEFAULT_ACTIVE_CHAINS.includes(chainInfo.slug)
833
+ active: _constants._DEFAULT_ACTIVE_CHAINS.includes(chainInfo.slug),
834
+ manualTurnOff: false
819
835
  };
820
836
  this.updateChainConnectionStatus(chainInfo.slug, _types3._ChainConnectionStatus.DISCONNECTED);
821
837
 
@@ -823,13 +839,15 @@ class ChainService {
823
839
  newStorageData.push({
824
840
  ...chainInfo,
825
841
  active: _constants._DEFAULT_ACTIVE_CHAINS.includes(chainInfo.slug),
826
- currentProvider: providerKey
842
+ currentProvider: providerKey,
843
+ manualTurnOff: false
827
844
  });
828
845
  });
829
846
  } else {
830
847
  const mergedChainInfoMap = defaultChainInfoMap;
831
848
  for (const [storedSlug, storedChainInfo] of Object.entries(storedChainSettingMap)) {
832
849
  const chainInfo = defaultChainInfoMap[storedSlug];
850
+ const manualTurnOff = !!storedChainInfo.manualTurnOff;
833
851
 
834
852
  // Network existed on change list
835
853
  // check predefined chains first, keep setting for providers and currentProvider
@@ -868,13 +886,15 @@ class ChainService {
868
886
  this.dataMap.chainStateMap[storedSlug] = {
869
887
  currentProvider: selectedProvider,
870
888
  slug: storedSlug,
871
- active: canActive && storedChainInfo.active
889
+ active: canActive && storedChainInfo.active,
890
+ manualTurnOff
872
891
  };
873
892
  this.updateChainConnectionStatus(storedSlug, _types3._ChainConnectionStatus.DISCONNECTED);
874
893
  newStorageData.push({
875
894
  ...mergedChainInfoMap[storedSlug],
876
895
  active: canActive && storedChainInfo.active,
877
- currentProvider: selectedProvider
896
+ currentProvider: selectedProvider,
897
+ manualTurnOff
878
898
  });
879
899
  } else if ((0, _utils._isCustomChain)(storedSlug)) {
880
900
  var _storedChainInfo$subs, _storedChainInfo$evmI;
@@ -890,13 +910,15 @@ class ChainService {
890
910
  this.dataMap.chainStateMap[duplicatedDefaultSlug] = {
891
911
  currentProvider: storedChainInfo.currentProvider,
892
912
  slug: duplicatedDefaultSlug,
893
- active: storedChainInfo.active
913
+ active: storedChainInfo.active,
914
+ manualTurnOff
894
915
  };
895
916
  this.updateChainConnectionStatus(duplicatedDefaultSlug, _types3._ChainConnectionStatus.DISCONNECTED);
896
917
  newStorageData.push({
897
918
  ...mergedChainInfoMap[duplicatedDefaultSlug],
898
919
  active: storedChainInfo.active,
899
- currentProvider: storedChainInfo.currentProvider
920
+ currentProvider: storedChainInfo.currentProvider,
921
+ manualTurnOff
900
922
  });
901
923
  deprecatedChainMap[storedSlug] = duplicatedDefaultSlug;
902
924
  deprecatedChains.push(storedSlug);
@@ -917,13 +939,16 @@ class ChainService {
917
939
  currentProvider: storedChainInfo.currentProvider,
918
940
  // TODO: review
919
941
  slug: storedSlug,
920
- active: storedChainInfo.active
942
+ active: storedChainInfo.active,
943
+ manualTurnOff
921
944
  };
922
945
  this.updateChainConnectionStatus(storedSlug, _types3._ChainConnectionStatus.DISCONNECTED);
923
946
  newStorageData.push({
924
947
  ...mergedChainInfoMap[storedSlug],
925
948
  active: storedChainInfo.active,
926
- currentProvider: storedChainInfo.currentProvider // TODO: review
949
+ currentProvider: storedChainInfo.currentProvider,
950
+ // TODO: review
951
+ manualTurnOff
927
952
  });
928
953
  }
929
954
  } else {
@@ -938,13 +963,15 @@ class ChainService {
938
963
  this.dataMap.chainStateMap[slug] = {
939
964
  currentProvider: Object.keys(chainInfo.providers)[0],
940
965
  slug,
941
- active: _constants._DEFAULT_ACTIVE_CHAINS.includes(slug)
966
+ active: _constants._DEFAULT_ACTIVE_CHAINS.includes(slug),
967
+ manualTurnOff: false
942
968
  };
943
969
  this.updateChainConnectionStatus(slug, _types3._ChainConnectionStatus.DISCONNECTED);
944
970
  newStorageData.push({
945
971
  ...mergedChainInfoMap[slug],
946
972
  active: _constants._DEFAULT_ACTIVE_CHAINS.includes(slug),
947
- currentProvider: Object.keys(chainInfo.providers)[0]
973
+ currentProvider: Object.keys(chainInfo.providers)[0],
974
+ manualTurnOff: false
948
975
  });
949
976
  }
950
977
  });
@@ -1061,7 +1088,8 @@ class ChainService {
1061
1088
  this.dbService.updateChainStore({
1062
1089
  ...targetChainInfo,
1063
1090
  active: targetChainState.active,
1064
- currentProvider: targetChainState.currentProvider
1091
+ currentProvider: targetChainState.currentProvider,
1092
+ manualTurnOff: !targetChainState.active || !!targetChainState.manualTurnOff
1065
1093
  }).then(() => {
1066
1094
  this.eventService.emit('chain.updateState', chainSlug);
1067
1095
  }).catch(e => this.logger.error(e));
@@ -1125,7 +1153,8 @@ class ChainService {
1125
1153
  chainStateMap[newChainSlug] = {
1126
1154
  active: true,
1127
1155
  currentProvider: params.chainEditInfo.currentProvider,
1128
- slug: newChainSlug
1156
+ slug: newChainSlug,
1157
+ manualTurnOff: false
1129
1158
  };
1130
1159
 
1131
1160
  // const chainStatusMap = this.getChainStatusMap();
@@ -1160,6 +1189,7 @@ class ChainService {
1160
1189
  this.dbService.updateChainStore({
1161
1190
  active: true,
1162
1191
  currentProvider: params.chainEditInfo.currentProvider,
1192
+ manualTurnOff: false,
1163
1193
  ...chainInfo
1164
1194
  }).then(() => {
1165
1195
  this.eventService.emit('chain.add', newChainSlug);
@@ -1599,5 +1629,17 @@ class ChainService {
1599
1629
  });
1600
1630
  return result;
1601
1631
  }
1632
+ get detectBalanceChainSlugMap() {
1633
+ const result = {};
1634
+ const chainInfoMap = this.getChainInfoMap();
1635
+ for (const [key, chainInfo] of Object.entries(chainInfoMap)) {
1636
+ var _chainInfo$extraInfo;
1637
+ const chainBalanceSlug = ((_chainInfo$extraInfo = chainInfo.extraInfo) === null || _chainInfo$extraInfo === void 0 ? void 0 : _chainInfo$extraInfo.chainBalanceSlug) || '';
1638
+ if (chainBalanceSlug) {
1639
+ result[chainBalanceSlug] = key;
1640
+ }
1641
+ }
1642
+ return result;
1643
+ }
1602
1644
  }
1603
1645
  exports.ChainService = ChainService;
@@ -562,10 +562,11 @@ function updateLatestChainInfo(currentDataMap, latestChainInfoList) {
562
562
  const currentChainStateMap = currentDataMap.chainStateMap;
563
563
  const storedChainInfoList = [];
564
564
  const needUpdateChainApiList = [];
565
- latestChainInfoList.forEach(latestChainInfo => {
565
+ for (const latestChainInfo of latestChainInfoList) {
566
566
  const currentChainInfo = currentChainInfoMap[latestChainInfo.slug];
567
567
  const currentChainState = currentChainStateMap[latestChainInfo.slug];
568
568
  const currentChainProviderValue = currentChainInfo === null || currentChainInfo === void 0 ? void 0 : currentChainInfo.providers[currentChainState === null || currentChainState === void 0 ? void 0 : currentChainState.currentProvider];
569
+ let needUpdate = false;
569
570
  if (currentChainInfo && currentChainState) {
570
571
  const preservedProvider = {};
571
572
  Object.entries(currentChainInfo.providers).forEach(_ref => {
@@ -587,12 +588,19 @@ function updateLatestChainInfo(currentDataMap, latestChainInfoList) {
587
588
  currentChainState.currentProvider = providerKey;
588
589
  needUpdateChainApiList.push(currentChainInfo);
589
590
  }
591
+ needUpdate = true;
592
+ }
593
+ if (currentChainInfo) {
594
+ needUpdate = true;
595
+ currentChainInfo.extraInfo = latestChainInfo.extraInfo;
596
+ }
597
+ if (needUpdate) {
590
598
  storedChainInfoList.push({
591
599
  ...currentChainInfo,
592
600
  ...currentChainState
593
601
  });
594
602
  }
595
- });
603
+ }
596
604
  return {
597
605
  storedChainInfoList,
598
606
  needUpdateChainApiList
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.fetchPatchData = fetchPatchData;
8
- var _packageInfo = require("@subwallet/chain-list/packageInfo");
9
8
  var _crossFetch = _interopRequireDefault(require("cross-fetch"));
10
9
  // Copyright 2019-2022 @subwallet/extension-base
11
10
  // SPDX-License-Identifier: Apache-2.0
@@ -13,9 +12,10 @@ var _crossFetch = _interopRequireDefault(require("cross-fetch"));
13
12
  const PRODUCTION_BRANCHES = ['master', 'webapp', 'webapp-dev'];
14
13
  const branchName = process.env.BRANCH_NAME || 'subwallet-dev';
15
14
  const fetchDomain = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'https://chain-list-assets.subwallet.app' : 'https://dev.sw-chain-list-assets.pages.dev';
15
+ const ChainListVersion = '0.2.53';
16
16
  async function fetchPatchData(slug) {
17
17
  try {
18
- const fetchPromise = (0, _crossFetch.default)(`${fetchDomain}/patch/${_packageInfo.packageInfo.version}/${slug}`);
18
+ const fetchPromise = (0, _crossFetch.default)(`${fetchDomain}/patch/${ChainListVersion}/${slug}`);
19
19
  const timeout = new Promise(resolve => {
20
20
  const id = setTimeout(() => {
21
21
  clearTimeout(id);
@@ -156,7 +156,7 @@ class ParaNativeStakingPoolHandler extends _basePara.default {
156
156
  for (const scheduledRequest of delegationScheduledRequests) {
157
157
  if ((0, _utils3.reformatAddress)(scheduledRequest.delegator, 0) === (0, _utils3.reformatAddress)(address, 0)) {
158
158
  // add network prefix
159
- const isClaimable = scheduledRequest.whenExecutable - currentRound < 0;
159
+ const isClaimable = scheduledRequest.whenExecutable - currentRound <= 0;
160
160
  const remainingEra = scheduledRequest.whenExecutable - currentRound;
161
161
  const waitingTime = remainingEra * _constants._STAKING_ERA_LENGTH_MAP[chainInfo.slug];
162
162
  const claimable = Object.values(scheduledRequest.action)[0];
@@ -13,7 +13,7 @@ var _uiKeyring = require("@subwallet/ui-keyring");
13
13
  class AutoEnableChainsTokens extends _Base.default {
14
14
  async run() {
15
15
  const accounts = _uiKeyring.keyring.getAccounts();
16
- await this.state.autoEnableChains(accounts.map(_ref => {
16
+ await this.state.balanceService.autoEnableChains(accounts.map(_ref => {
17
17
  let {
18
18
  address
19
19
  } = _ref;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _defaults = require("@subwallet/extension-base/defaults");
9
+ var _SubscribableStore = _interopRequireDefault(require("@subwallet/extension-base/stores/SubscribableStore"));
10
+ // Copyright 2019-2022 @subwallet/extension-base authors & contributors
11
+ // SPDX-License-Identifier: Apache-2.0
12
+
13
+ class DetectAccountBalanceStore extends _SubscribableStore.default {
14
+ constructor() {
15
+ super(_defaults.EXTENSION_PREFIX ? `${_defaults.EXTENSION_PREFIX}DetectBalanceCache` : null);
16
+ }
17
+ }
18
+ exports.default = DetectAccountBalanceStore;
@@ -237,7 +237,7 @@ export default class KoniState {
237
237
  wakeup(): Promise<void>;
238
238
  cancelSubscription(id: string): boolean;
239
239
  createUnsubscriptionHandle(id: string, unsubscribe: () => void): void;
240
- autoEnableChains(addresses: string[]): Promise<void>;
240
+ get detectBalanceChainSlugMap(): Record<string, string>;
241
241
  onAccountAdd(): void;
242
242
  onAccountRemove(): void;
243
243
  reloadNft(): Promise<boolean>;
@@ -28,7 +28,7 @@ import RequestService from '@subwallet/extension-base/services/request-service';
28
28
  import SettingService from '@subwallet/extension-base/services/setting-service/SettingService';
29
29
  import DatabaseService from '@subwallet/extension-base/services/storage-service/DatabaseService';
30
30
  import { SubscanService } from '@subwallet/extension-base/services/subscan-service';
31
- import { SUBSCAN_API_CHAIN_MAP, SUBSCAN_BALANCE_CHAIN_MAP_REVERSE } from '@subwallet/extension-base/services/subscan-service/subscan-chain-map';
31
+ import { SUBSCAN_API_CHAIN_MAP } from '@subwallet/extension-base/services/subscan-service/subscan-chain-map';
32
32
  import TransactionService from '@subwallet/extension-base/services/transaction-service';
33
33
  import WalletConnectService from '@subwallet/extension-base/services/wallet-connect-service';
34
34
  import AccountRefStore from '@subwallet/extension-base/stores/AccountRef';
@@ -1511,58 +1511,21 @@ export default class KoniState {
1511
1511
  createUnsubscriptionHandle(id, unsubscribe) {
1512
1512
  this.unsubscriptionMap[id] = unsubscribe;
1513
1513
  }
1514
- async autoEnableChains(addresses) {
1515
- const assetMap = this.chainService.getAssetRegistry();
1516
- const promiseList = addresses.map(address => {
1517
- return this.subscanService.getMultiChainBalance(address).catch(e => {
1518
- console.error(e);
1519
- return null;
1520
- });
1521
- });
1522
- const needEnableChains = [];
1523
- const needActiveTokens = [];
1524
- const currentAssetSettings = await this.chainService.getAssetSettings();
1525
- const chainMap = this.chainService.getChainInfoMap();
1526
- const balanceDataList = await Promise.all(promiseList);
1527
- balanceDataList.forEach(balanceData => {
1528
- balanceData && balanceData.forEach(({
1529
- balance,
1530
- bonded,
1531
- category,
1532
- locked,
1533
- network,
1534
- symbol
1535
- }) => {
1536
- var _currentAssetSettings;
1537
- const chain = SUBSCAN_BALANCE_CHAIN_MAP_REVERSE[network];
1538
- const chainInfo = chain ? chainMap[chain] : null;
1539
- const balanceIsEmpty = (!balance || balance === '0') && (!locked || locked === '0') && (!bonded || bonded === '0');
1540
-
1541
- // Cancel if chain is not supported or is testnet or balance is 0
1542
- if (!chainInfo || chainInfo.isTestnet || balanceIsEmpty) {
1543
- return;
1544
- }
1545
- const tokenKey = `${chain}-${category === 'native' ? 'NATIVE' : 'LOCAL'}-${symbol.toUpperCase()}`;
1546
- const existedKey = Object.keys(assetMap).find(v => v.toLowerCase() === tokenKey.toLowerCase());
1547
- if (existedKey && !((_currentAssetSettings = currentAssetSettings[existedKey]) !== null && _currentAssetSettings !== void 0 && _currentAssetSettings.visible)) {
1548
- needEnableChains.push(chain);
1549
- needActiveTokens.push(existedKey);
1550
- currentAssetSettings[existedKey] = {
1551
- visible: true
1552
- };
1553
- }
1554
- });
1555
- });
1556
- if (needActiveTokens.length) {
1557
- await this.chainService.enableChains(needEnableChains);
1558
- this.chainService.setAssetSettings({
1559
- ...currentAssetSettings
1560
- });
1514
+ get detectBalanceChainSlugMap() {
1515
+ const result = {};
1516
+ const chainInfoMap = this.getChainInfoMap();
1517
+ for (const [key, chainInfo] of Object.entries(chainInfoMap)) {
1518
+ var _chainInfo$extraInfo;
1519
+ const chainBalanceSlug = ((_chainInfo$extraInfo = chainInfo.extraInfo) === null || _chainInfo$extraInfo === void 0 ? void 0 : _chainInfo$extraInfo.chainBalanceSlug) || '';
1520
+ if (chainBalanceSlug) {
1521
+ result[chainBalanceSlug] = key;
1522
+ }
1561
1523
  }
1524
+ return result;
1562
1525
  }
1563
1526
  onAccountAdd() {
1564
1527
  this.eventService.on('account.add', address => {
1565
- this.autoEnableChains([address]).catch(this.logger.error);
1528
+ this.balanceService.autoEnableChains([address]).catch(this.logger.error);
1566
1529
  });
1567
1530
  }
1568
1531
  onAccountRemove() {
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.1.51-0",
20
+ "version": "1.1.51-2",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -1480,6 +1480,11 @@
1480
1480
  "require": "./cjs/stores/CurrentAccountStore.js",
1481
1481
  "default": "./stores/CurrentAccountStore.js"
1482
1482
  },
1483
+ "./stores/DetectAccountBalance": {
1484
+ "types": "./stores/DetectAccountBalance.d.ts",
1485
+ "require": "./cjs/stores/DetectAccountBalance.js",
1486
+ "default": "./stores/DetectAccountBalance.js"
1487
+ },
1483
1488
  "./stores/Keyring": {
1484
1489
  "types": "./stores/Keyring.d.ts",
1485
1490
  "require": "./cjs/stores/Keyring.js",
@@ -1802,10 +1807,10 @@
1802
1807
  "@sora-substrate/type-definitions": "^1.17.7",
1803
1808
  "@substrate/connect": "^0.7.26",
1804
1809
  "@subwallet/chain-list": "0.2.53",
1805
- "@subwallet/extension-base": "^1.1.51-0",
1806
- "@subwallet/extension-chains": "^1.1.51-0",
1807
- "@subwallet/extension-dapp": "^1.1.51-0",
1808
- "@subwallet/extension-inject": "^1.1.51-0",
1810
+ "@subwallet/extension-base": "^1.1.51-2",
1811
+ "@subwallet/extension-chains": "^1.1.51-2",
1812
+ "@subwallet/extension-dapp": "^1.1.51-2",
1813
+ "@subwallet/extension-inject": "^1.1.51-2",
1809
1814
  "@subwallet/keyring": "^0.1.3",
1810
1815
  "@subwallet/ui-keyring": "^0.1.3",
1811
1816
  "@walletconnect/sign-client": "^2.8.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.1.51-0'
10
+ version: '1.1.51-2'
11
11
  };
@@ -1,4 +1,4 @@
1
- import { AmountData } from '@subwallet/extension-base/background/KoniTypes';
1
+ import { AmountData, DetectBalanceCache } from '@subwallet/extension-base/background/KoniTypes';
2
2
  import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
3
3
  import { BalanceItem } from '@subwallet/extension-base/types';
4
4
  /**
@@ -6,12 +6,20 @@ import { BalanceItem } from '@subwallet/extension-base/types';
6
6
  * @class
7
7
  */
8
8
  export declare class BalanceService {
9
- private state;
9
+ private readonly state;
10
+ private readonly detectAccountBalanceStore;
11
+ private readonly balanceDetectSubject;
12
+ private readonly intervalTime;
13
+ private readonly cacheTime;
14
+ private readonly startHandler;
10
15
  /**
11
16
  * @constructor
12
17
  * @param {KoniState} state - The state of extension.
13
18
  */
14
19
  constructor(state: KoniState);
20
+ startDetectBalance(): Promise<void>;
21
+ getBalanceDetectCache(update: (value: DetectBalanceCache) => void): void;
22
+ setBalanceDetectCache(addresses: string[]): void;
15
23
  subscribeTokenFreeBalance(address: string, chain: string, tokenSlug: string | undefined, callback?: (rs: AmountData) => void): Promise<[() => void, AmountData]>;
16
24
  /**
17
25
  * @public
@@ -25,4 +33,5 @@ export declare class BalanceService {
25
33
  */
26
34
  getTokenFreeBalance(address: string, chain: string, tokenSlug?: string): Promise<AmountData>;
27
35
  subscribeBalance(addresses: string[], chains: string[] | null, _callback: (rs: BalanceItem) => void): () => void;
36
+ autoEnableChains(addresses: string[]): Promise<void>;
28
37
  }
@@ -8,14 +8,22 @@ import { subscribeEVMBalance } from '@subwallet/extension-base/services/balance-
8
8
  import { subscribeSubstrateBalance } from '@subwallet/extension-base/services/balance-service/helpers/subscribe/substrate';
9
9
  import { _PURE_EVM_CHAINS } from '@subwallet/extension-base/services/chain-service/constants';
10
10
  import { _getChainNativeTokenSlug, _isChainEvmCompatible, _isPureEvmChain } from '@subwallet/extension-base/services/chain-service/utils';
11
- import { categoryAddresses } from '@subwallet/extension-base/utils';
11
+ import DetectAccountBalanceStore from '@subwallet/extension-base/stores/DetectAccountBalance';
12
+ import { categoryAddresses, createPromiseHandler } from '@subwallet/extension-base/utils';
13
+ import keyring from '@subwallet/ui-keyring';
12
14
  import { t } from 'i18next';
15
+ import { BehaviorSubject } from 'rxjs';
16
+ import { noop } from '@polkadot/util';
13
17
 
14
18
  /**
15
19
  * Balance service
16
20
  * @class
17
21
  */
18
22
  export class BalanceService {
23
+ detectAccountBalanceStore = new DetectAccountBalanceStore();
24
+ balanceDetectSubject = new BehaviorSubject({});
25
+ intervalTime = 3 * 60 * 1000;
26
+ cacheTime = 15 * 60 * 1000;
19
27
  /**
20
28
  * @constructor
21
29
  * @param {KoniState} state - The state of extension.
@@ -30,6 +38,54 @@ export class BalanceService {
30
38
  // Todo: Add new account
31
39
  // Todo: Optimize get balance for single account and chain with cache
32
40
  // Todo: Move everything of fetching balance to this service
41
+
42
+ this.startHandler = createPromiseHandler();
43
+ const updateBalanceDetectCache = value => {
44
+ this.startHandler.resolve();
45
+ this.balanceDetectSubject.next(value || {});
46
+ };
47
+ this.getBalanceDetectCache(updateBalanceDetectCache);
48
+ this.detectAccountBalanceStore.getSubject().subscribe({
49
+ next: updateBalanceDetectCache
50
+ });
51
+ this.startDetectBalance().catch(console.error);
52
+ }
53
+ async startDetectBalance() {
54
+ const scanBalance = () => {
55
+ const addresses = keyring.getPairs().map(account => account.address);
56
+ const cache = this.balanceDetectSubject.value;
57
+ const now = Date.now();
58
+ const needDetectAddresses = [];
59
+ for (const address of addresses) {
60
+ if (!cache[address] || now - cache[address] > this.cacheTime) {
61
+ needDetectAddresses.push(address);
62
+ }
63
+ }
64
+ if (needDetectAddresses.length) {
65
+ this.autoEnableChains(needDetectAddresses).finally(noop);
66
+ }
67
+ };
68
+ await this.state.eventService.waitAccountReady;
69
+ await this.state.eventService.waitChainReady;
70
+ await this.startHandler.promise;
71
+ scanBalance();
72
+ setInterval(scanBalance, this.intervalTime);
73
+ }
74
+ getBalanceDetectCache(update) {
75
+ this.detectAccountBalanceStore.get('DetectBalanceCache', value => {
76
+ update(value);
77
+ });
78
+ }
79
+ setBalanceDetectCache(addresses) {
80
+ this.detectAccountBalanceStore.get('DetectBalanceCache', value => {
81
+ const rs = {
82
+ ...value
83
+ };
84
+ for (const address of addresses) {
85
+ rs[address] = Date.now();
86
+ }
87
+ this.detectAccountBalanceStore.set('DetectBalanceCache', rs);
88
+ });
33
89
  }
34
90
 
35
91
  /* Subscribe token free balance on chain */
@@ -133,4 +189,72 @@ export class BalanceService {
133
189
  });
134
190
  };
135
191
  }
192
+ async autoEnableChains(addresses) {
193
+ this.setBalanceDetectCache(addresses);
194
+ const assetMap = this.state.chainService.getAssetRegistry();
195
+ const promiseList = addresses.map(address => {
196
+ return this.state.subscanService.getMultiChainBalance(address).catch(e => {
197
+ console.error(e);
198
+ return null;
199
+ });
200
+ });
201
+ const needEnableChains = [];
202
+ const needActiveTokens = [];
203
+ const balanceDataList = await Promise.all(promiseList);
204
+ const currentAssetSettings = await this.state.chainService.getAssetSettings();
205
+ const chainInfoMap = this.state.chainService.getChainInfoMap();
206
+ const detectBalanceChainSlugMap = this.state.chainService.detectBalanceChainSlugMap;
207
+ for (const balanceData of balanceDataList) {
208
+ if (balanceData) {
209
+ for (const balanceDatum of balanceData) {
210
+ var _currentAssetSettings;
211
+ const {
212
+ balance,
213
+ bonded,
214
+ category,
215
+ locked,
216
+ network,
217
+ symbol
218
+ } = balanceDatum;
219
+ const chain = detectBalanceChainSlugMap[network];
220
+ const chainInfo = chain ? chainInfoMap[chain] : null;
221
+ const chainState = this.state.chainService.getChainStateByKey(chain);
222
+ const balanceIsEmpty = (!balance || balance === '0') && (!locked || locked === '0') && (!bonded || bonded === '0');
223
+ const tokenKey = `${chain}-${category === 'native' ? 'NATIVE' : 'LOCAL'}-${symbol.toUpperCase()}`;
224
+ const existedKey = Object.keys(assetMap).find(v => v.toLowerCase() === tokenKey.toLowerCase());
225
+
226
+ // Cancel if chain is not supported or is testnet
227
+ if (!chainInfo || chainInfo.isTestnet) {
228
+ continue;
229
+ }
230
+
231
+ // Cancel is balance is 0
232
+ if (balanceIsEmpty) {
233
+ continue;
234
+ }
235
+
236
+ // Cancel is chain is turned off by user
237
+ if (chainState && chainState.manualTurnOff) {
238
+ continue;
239
+ }
240
+
241
+ // const a = this.state.chainService.getChainStateByKey(chain);
242
+
243
+ if (existedKey && !((_currentAssetSettings = currentAssetSettings[existedKey]) !== null && _currentAssetSettings !== void 0 && _currentAssetSettings.visible)) {
244
+ needEnableChains.push(chain);
245
+ needActiveTokens.push(existedKey);
246
+ currentAssetSettings[existedKey] = {
247
+ visible: true
248
+ };
249
+ }
250
+ }
251
+ }
252
+ }
253
+ if (needActiveTokens.length) {
254
+ await this.state.chainService.enableChains(needEnableChains);
255
+ this.state.chainService.setAssetSettings({
256
+ ...currentAssetSettings
257
+ });
258
+ }
259
+ }
136
260
  }
@@ -83,7 +83,7 @@ export declare class ChainService {
83
83
  initAssetRefMap(): void;
84
84
  checkLatestData(): void;
85
85
  stopCheckLatestChainData(): void;
86
- handleLatestProviderData(latestChainInfo: _ChainInfo[]): void;
86
+ handleLatestChainData(latestChainInfo: _ChainInfo[]): void;
87
87
  handleLatestAssetRef(latestBlockedAssetRefList: string[], latestAssetRefMap: Record<string, _AssetRef> | null): void;
88
88
  handleLatestPriceId(latestPriceIds: Record<string, string | null>): void;
89
89
  handleLatestAssetData(latestAssetInfo: Record<string, _ChainAsset> | null, latestAssetLogoMap: Record<string, string> | null): void;
@@ -138,4 +138,5 @@ export declare class ChainService {
138
138
  upsertMetadata(chain: string, metadata: IMetadataItem): import("dexie").PromiseExtended<unknown>;
139
139
  getMetadataByHash(hash: string): import("dexie").PromiseExtended<IMetadataItem | undefined>;
140
140
  getSubscanChainMap(reverse?: boolean): Record<string, string>;
141
+ get detectBalanceChainSlugMap(): Record<string, string>;
141
142
  }
@@ -454,7 +454,7 @@ export class ChainService {
454
454
  stopCheckLatestChainData() {
455
455
  clearInterval(this.refreshLatestChainDataTimeOut);
456
456
  }
457
- handleLatestProviderData(latestChainInfo) {
457
+ handleLatestChainData(latestChainInfo) {
458
458
  try {
459
459
  if (latestChainInfo && latestChainInfo.length > 0) {
460
460
  const {
@@ -531,6 +531,17 @@ export class ChainService {
531
531
  this.assetLogoMapSubject.next(logoMap);
532
532
  }
533
533
  }
534
+ if (latestAssetLogoMap) {
535
+ const latestAssetLogoPatch = JSON.stringify(latestAssetLogoMap);
536
+ if (this.assetLogoPatch !== latestAssetLogoPatch) {
537
+ const logoMap = {
538
+ ...AssetLogoMap,
539
+ ...latestAssetLogoMap
540
+ };
541
+ this.assetLogoPatch = latestAssetLogoPatch;
542
+ this.assetLogoMapSubject.next(logoMap);
543
+ }
544
+ }
534
545
  } catch (e) {
535
546
  console.error('Error fetching latest asset data');
536
547
  }
@@ -567,7 +578,7 @@ export class ChainService {
567
578
  }).catch(console.error);
568
579
  }).catch(console.error);
569
580
  this.fetchLatestChainData().then(latestChainInfo => {
570
- this.handleLatestProviderData(latestChainInfo);
581
+ this.handleLatestChainData(latestChainInfo);
571
582
  }).catch(console.error);
572
583
  this.fetchLatestAssetRef().then(([latestAssetRef, latestAssetRefMap]) => {
573
584
  this.handleLatestAssetRef(latestAssetRef, latestAssetRefMap);
@@ -644,7 +655,8 @@ export class ChainService {
644
655
  this.dbService.updateChainStore({
645
656
  ...chainInfo,
646
657
  active: true,
647
- currentProvider: chainStateMap[chainSlug].currentProvider
658
+ currentProvider: chainStateMap[chainSlug].currentProvider,
659
+ manualTurnOff: !!chainStateMap[chainSlug].manualTurnOff
648
660
  }).catch(console.error);
649
661
  chainStateMap[chainSlug].active = true;
650
662
  await this.initApiForChain(chainInfo);
@@ -669,7 +681,8 @@ export class ChainService {
669
681
  this.dbService.updateChainStore({
670
682
  ...chainInfo,
671
683
  active: true,
672
- currentProvider: chainStateMap[chainSlug].currentProvider
684
+ currentProvider: chainStateMap[chainSlug].currentProvider,
685
+ manualTurnOff: !!chainStateMap[chainSlug].manualTurnOff
673
686
  }).catch(console.error);
674
687
  chainStateMap[chainSlug].active = true;
675
688
  await this.initApiForChain(chainInfo);
@@ -696,13 +709,15 @@ export class ChainService {
696
709
  }
697
710
  this.lockChainInfoMap = true;
698
711
  chainStateMap[chainSlug].active = false;
712
+ chainStateMap[chainSlug].manualTurnOff = true;
699
713
  // Set disconnect state for inactive chain
700
714
  this.updateChainConnectionStatus(chainSlug, _ChainConnectionStatus.DISCONNECTED);
701
715
  this.destroyApiForChain(chainInfo);
702
716
  this.dbService.updateChainStore({
703
717
  ...chainInfo,
704
718
  active: false,
705
- currentProvider: chainStateMap[chainSlug].currentProvider
719
+ currentProvider: chainStateMap[chainSlug].currentProvider,
720
+ manualTurnOff: true
706
721
  }).catch(console.error);
707
722
  this.updateChainStateMapSubscription();
708
723
  this.lockChainInfoMap = false;
@@ -794,7 +809,8 @@ export class ChainService {
794
809
  this.dataMap.chainStateMap[chainInfo.slug] = {
795
810
  currentProvider: providerKey,
796
811
  slug: chainInfo.slug,
797
- active: _DEFAULT_ACTIVE_CHAINS.includes(chainInfo.slug)
812
+ active: _DEFAULT_ACTIVE_CHAINS.includes(chainInfo.slug),
813
+ manualTurnOff: false
798
814
  };
799
815
  this.updateChainConnectionStatus(chainInfo.slug, _ChainConnectionStatus.DISCONNECTED);
800
816
 
@@ -802,13 +818,15 @@ export class ChainService {
802
818
  newStorageData.push({
803
819
  ...chainInfo,
804
820
  active: _DEFAULT_ACTIVE_CHAINS.includes(chainInfo.slug),
805
- currentProvider: providerKey
821
+ currentProvider: providerKey,
822
+ manualTurnOff: false
806
823
  });
807
824
  });
808
825
  } else {
809
826
  const mergedChainInfoMap = defaultChainInfoMap;
810
827
  for (const [storedSlug, storedChainInfo] of Object.entries(storedChainSettingMap)) {
811
828
  const chainInfo = defaultChainInfoMap[storedSlug];
829
+ const manualTurnOff = !!storedChainInfo.manualTurnOff;
812
830
 
813
831
  // Network existed on change list
814
832
  // check predefined chains first, keep setting for providers and currentProvider
@@ -847,13 +865,15 @@ export class ChainService {
847
865
  this.dataMap.chainStateMap[storedSlug] = {
848
866
  currentProvider: selectedProvider,
849
867
  slug: storedSlug,
850
- active: canActive && storedChainInfo.active
868
+ active: canActive && storedChainInfo.active,
869
+ manualTurnOff
851
870
  };
852
871
  this.updateChainConnectionStatus(storedSlug, _ChainConnectionStatus.DISCONNECTED);
853
872
  newStorageData.push({
854
873
  ...mergedChainInfoMap[storedSlug],
855
874
  active: canActive && storedChainInfo.active,
856
- currentProvider: selectedProvider
875
+ currentProvider: selectedProvider,
876
+ manualTurnOff
857
877
  });
858
878
  } else if (_isCustomChain(storedSlug)) {
859
879
  var _storedChainInfo$subs, _storedChainInfo$evmI;
@@ -869,13 +889,15 @@ export class ChainService {
869
889
  this.dataMap.chainStateMap[duplicatedDefaultSlug] = {
870
890
  currentProvider: storedChainInfo.currentProvider,
871
891
  slug: duplicatedDefaultSlug,
872
- active: storedChainInfo.active
892
+ active: storedChainInfo.active,
893
+ manualTurnOff
873
894
  };
874
895
  this.updateChainConnectionStatus(duplicatedDefaultSlug, _ChainConnectionStatus.DISCONNECTED);
875
896
  newStorageData.push({
876
897
  ...mergedChainInfoMap[duplicatedDefaultSlug],
877
898
  active: storedChainInfo.active,
878
- currentProvider: storedChainInfo.currentProvider
899
+ currentProvider: storedChainInfo.currentProvider,
900
+ manualTurnOff
879
901
  });
880
902
  deprecatedChainMap[storedSlug] = duplicatedDefaultSlug;
881
903
  deprecatedChains.push(storedSlug);
@@ -896,13 +918,16 @@ export class ChainService {
896
918
  currentProvider: storedChainInfo.currentProvider,
897
919
  // TODO: review
898
920
  slug: storedSlug,
899
- active: storedChainInfo.active
921
+ active: storedChainInfo.active,
922
+ manualTurnOff
900
923
  };
901
924
  this.updateChainConnectionStatus(storedSlug, _ChainConnectionStatus.DISCONNECTED);
902
925
  newStorageData.push({
903
926
  ...mergedChainInfoMap[storedSlug],
904
927
  active: storedChainInfo.active,
905
- currentProvider: storedChainInfo.currentProvider // TODO: review
928
+ currentProvider: storedChainInfo.currentProvider,
929
+ // TODO: review
930
+ manualTurnOff
906
931
  });
907
932
  }
908
933
  } else {
@@ -916,13 +941,15 @@ export class ChainService {
916
941
  this.dataMap.chainStateMap[slug] = {
917
942
  currentProvider: Object.keys(chainInfo.providers)[0],
918
943
  slug,
919
- active: _DEFAULT_ACTIVE_CHAINS.includes(slug)
944
+ active: _DEFAULT_ACTIVE_CHAINS.includes(slug),
945
+ manualTurnOff: false
920
946
  };
921
947
  this.updateChainConnectionStatus(slug, _ChainConnectionStatus.DISCONNECTED);
922
948
  newStorageData.push({
923
949
  ...mergedChainInfoMap[slug],
924
950
  active: _DEFAULT_ACTIVE_CHAINS.includes(slug),
925
- currentProvider: Object.keys(chainInfo.providers)[0]
951
+ currentProvider: Object.keys(chainInfo.providers)[0],
952
+ manualTurnOff: false
926
953
  });
927
954
  }
928
955
  });
@@ -1039,7 +1066,8 @@ export class ChainService {
1039
1066
  this.dbService.updateChainStore({
1040
1067
  ...targetChainInfo,
1041
1068
  active: targetChainState.active,
1042
- currentProvider: targetChainState.currentProvider
1069
+ currentProvider: targetChainState.currentProvider,
1070
+ manualTurnOff: !targetChainState.active || !!targetChainState.manualTurnOff
1043
1071
  }).then(() => {
1044
1072
  this.eventService.emit('chain.updateState', chainSlug);
1045
1073
  }).catch(e => this.logger.error(e));
@@ -1103,7 +1131,8 @@ export class ChainService {
1103
1131
  chainStateMap[newChainSlug] = {
1104
1132
  active: true,
1105
1133
  currentProvider: params.chainEditInfo.currentProvider,
1106
- slug: newChainSlug
1134
+ slug: newChainSlug,
1135
+ manualTurnOff: false
1107
1136
  };
1108
1137
 
1109
1138
  // const chainStatusMap = this.getChainStatusMap();
@@ -1138,6 +1167,7 @@ export class ChainService {
1138
1167
  this.dbService.updateChainStore({
1139
1168
  active: true,
1140
1169
  currentProvider: params.chainEditInfo.currentProvider,
1170
+ manualTurnOff: false,
1141
1171
  ...chainInfo
1142
1172
  }).then(() => {
1143
1173
  this.eventService.emit('chain.add', newChainSlug);
@@ -1576,4 +1606,16 @@ export class ChainService {
1576
1606
  });
1577
1607
  return result;
1578
1608
  }
1609
+ get detectBalanceChainSlugMap() {
1610
+ const result = {};
1611
+ const chainInfoMap = this.getChainInfoMap();
1612
+ for (const [key, chainInfo] of Object.entries(chainInfoMap)) {
1613
+ var _chainInfo$extraInfo;
1614
+ const chainBalanceSlug = ((_chainInfo$extraInfo = chainInfo.extraInfo) === null || _chainInfo$extraInfo === void 0 ? void 0 : _chainInfo$extraInfo.chainBalanceSlug) || '';
1615
+ if (chainBalanceSlug) {
1616
+ result[chainBalanceSlug] = key;
1617
+ }
1618
+ }
1619
+ return result;
1620
+ }
1579
1621
  }
@@ -22,6 +22,7 @@ export interface _ChainState {
22
22
  slug: string;
23
23
  active: boolean;
24
24
  currentProvider: string;
25
+ manualTurnOff: boolean;
25
26
  }
26
27
  export interface _ChainApiStatus {
27
28
  slug: string;
@@ -400,10 +400,11 @@ export function updateLatestChainInfo(currentDataMap, latestChainInfoList) {
400
400
  const currentChainStateMap = currentDataMap.chainStateMap;
401
401
  const storedChainInfoList = [];
402
402
  const needUpdateChainApiList = [];
403
- latestChainInfoList.forEach(latestChainInfo => {
403
+ for (const latestChainInfo of latestChainInfoList) {
404
404
  const currentChainInfo = currentChainInfoMap[latestChainInfo.slug];
405
405
  const currentChainState = currentChainStateMap[latestChainInfo.slug];
406
406
  const currentChainProviderValue = currentChainInfo === null || currentChainInfo === void 0 ? void 0 : currentChainInfo.providers[currentChainState === null || currentChainState === void 0 ? void 0 : currentChainState.currentProvider];
407
+ let needUpdate = false;
407
408
  if (currentChainInfo && currentChainState) {
408
409
  const preservedProvider = {};
409
410
  Object.entries(currentChainInfo.providers).forEach(([providerKey, providerValue]) => {
@@ -424,12 +425,19 @@ export function updateLatestChainInfo(currentDataMap, latestChainInfoList) {
424
425
  currentChainState.currentProvider = providerKey;
425
426
  needUpdateChainApiList.push(currentChainInfo);
426
427
  }
428
+ needUpdate = true;
429
+ }
430
+ if (currentChainInfo) {
431
+ needUpdate = true;
432
+ currentChainInfo.extraInfo = latestChainInfo.extraInfo;
433
+ }
434
+ if (needUpdate) {
427
435
  storedChainInfoList.push({
428
436
  ...currentChainInfo,
429
437
  ...currentChainState
430
438
  });
431
439
  }
432
- });
440
+ }
433
441
  return {
434
442
  storedChainInfoList,
435
443
  needUpdateChainApiList
@@ -1,14 +1,14 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { packageInfo as chainListInfo } from '@subwallet/chain-list/packageInfo';
5
4
  import fetch from 'cross-fetch';
6
5
  const PRODUCTION_BRANCHES = ['master', 'webapp', 'webapp-dev'];
7
6
  const branchName = process.env.BRANCH_NAME || 'subwallet-dev';
8
7
  const fetchDomain = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'https://chain-list-assets.subwallet.app' : 'https://dev.sw-chain-list-assets.pages.dev';
8
+ const ChainListVersion = '0.2.53';
9
9
  export async function fetchPatchData(slug) {
10
10
  try {
11
- const fetchPromise = fetch(`${fetchDomain}/patch/${chainListInfo.version}/${slug}`);
11
+ const fetchPromise = fetch(`${fetchDomain}/patch/${ChainListVersion}/${slug}`);
12
12
  const timeout = new Promise(resolve => {
13
13
  const id = setTimeout(() => {
14
14
  clearTimeout(id);
@@ -149,7 +149,7 @@ export default class ParaNativeStakingPoolHandler extends BaseParaNativeStakingP
149
149
  for (const scheduledRequest of delegationScheduledRequests) {
150
150
  if (reformatAddress(scheduledRequest.delegator, 0) === reformatAddress(address, 0)) {
151
151
  // add network prefix
152
- const isClaimable = scheduledRequest.whenExecutable - currentRound < 0;
152
+ const isClaimable = scheduledRequest.whenExecutable - currentRound <= 0;
153
153
  const remainingEra = scheduledRequest.whenExecutable - currentRound;
154
154
  const waitingTime = remainingEra * _STAKING_ERA_LENGTH_MAP[chainInfo.slug];
155
155
  const claimable = Object.values(scheduledRequest.action)[0];
@@ -6,7 +6,7 @@ import { keyring } from '@subwallet/ui-keyring';
6
6
  export default class AutoEnableChainsTokens extends BaseMigrationJob {
7
7
  async run() {
8
8
  const accounts = keyring.getAccounts();
9
- await this.state.autoEnableChains(accounts.map(({
9
+ await this.state.balanceService.autoEnableChains(accounts.map(({
10
10
  address
11
11
  }) => address));
12
12
  }
@@ -15,6 +15,7 @@ export interface IBalance extends BalanceItem, DefaultAddressDoc {
15
15
  export interface IChain extends _ChainInfo {
16
16
  active: boolean;
17
17
  currentProvider: string;
18
+ manualTurnOff: boolean;
18
19
  }
19
20
  export interface ICrowdloanItem extends CrowdloanItem, DefaultAddressDoc, DefaultChainDoc {
20
21
  }
@@ -0,0 +1,5 @@
1
+ import { DetectBalanceCache } from '@subwallet/extension-base/background/KoniTypes';
2
+ import SubscribableStore from '@subwallet/extension-base/stores/SubscribableStore';
3
+ export default class DetectAccountBalanceStore extends SubscribableStore<DetectBalanceCache> {
4
+ constructor();
5
+ }
@@ -0,0 +1,10 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { EXTENSION_PREFIX } from '@subwallet/extension-base/defaults';
5
+ import SubscribableStore from '@subwallet/extension-base/stores/SubscribableStore';
6
+ export default class DetectAccountBalanceStore extends SubscribableStore {
7
+ constructor() {
8
+ super(EXTENSION_PREFIX ? `${EXTENSION_PREFIX}DetectBalanceCache` : null);
9
+ }
10
+ }