@subwallet/extension-base 1.3.45-1 → 1.3.47-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 (128) hide show
  1. package/background/KoniTypes.d.ts +5 -0
  2. package/background/KoniTypes.js +5 -0
  3. package/background/types.d.ts +2 -0
  4. package/cjs/background/KoniTypes.js +7 -1
  5. package/cjs/core/logic-validation/request.js +55 -28
  6. package/cjs/core/utils.js +22 -0
  7. package/cjs/koni/api/nft/ordinal_nft/index.js +3 -2
  8. package/cjs/koni/background/handlers/Extension.js +84 -61
  9. package/cjs/koni/background/handlers/State.js +3 -0
  10. package/cjs/koni/background/handlers/Tabs.js +11 -3
  11. package/cjs/packageInfo.js +1 -1
  12. package/cjs/page/evm/index.js +64 -105
  13. package/cjs/page/index.js +5 -3
  14. package/cjs/page/substrate/Accounts.js +2 -1
  15. package/cjs/services/balance-service/helpers/subscribe/index.js +3 -76
  16. package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +8 -14
  17. package/cjs/services/buy-service/index.js +2 -0
  18. package/cjs/services/chain-service/index.js +3 -0
  19. package/cjs/services/chain-service/utils/index.js +34 -1
  20. package/cjs/services/chain-service/utils/patch.js +1 -1
  21. package/cjs/services/earning-service/constants/chains.js +2 -1
  22. package/cjs/services/earning-service/handlers/native-staking/amplitude.js +32 -0
  23. package/cjs/services/earning-service/handlers/native-staking/astar.js +18 -0
  24. package/cjs/services/earning-service/handlers/native-staking/base.js +40 -29
  25. package/cjs/services/earning-service/handlers/native-staking/dtao.js +5 -0
  26. package/cjs/services/earning-service/handlers/native-staking/mythos.js +28 -0
  27. package/cjs/services/earning-service/handlers/native-staking/para-chain.js +17 -0
  28. package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +25 -2
  29. package/cjs/services/earning-service/handlers/native-staking/tao.js +5 -0
  30. package/cjs/services/earning-service/handlers/nomination-pool/index.js +6 -3
  31. package/cjs/services/earning-service/service.js +65 -22
  32. package/cjs/services/history-service/index.js +12 -7
  33. package/cjs/services/keyring-service/context/handlers/Json.js +2 -1
  34. package/cjs/services/keyring-service/context/handlers/Ledger.js +7 -2
  35. package/cjs/services/request-service/handler/AuthRequestHandler.js +30 -6
  36. package/cjs/services/subscan-service/index.js +35 -104
  37. package/cjs/services/transaction-service/utils.js +10 -1
  38. package/cjs/strategy/api-request-strategy/index.js +1 -0
  39. package/cjs/strategy/api-request-strategy/utils/index.js +2 -2
  40. package/cjs/strategy/api-request-strategy-v2/index.js +138 -0
  41. package/cjs/strategy/api-request-strategy-v2/types.js +1 -0
  42. package/cjs/types/account/info/keyring.js +1 -0
  43. package/cjs/utils/account/analyze.js +5 -2
  44. package/cjs/utils/account/common.js +93 -2
  45. package/cjs/utils/account/transform.js +10 -0
  46. package/cjs/utils/asset.js +9 -2
  47. package/cjs/utils/gear/combine.js +4 -3
  48. package/cjs/utils/gear/vft.js +104 -135
  49. package/cjs/utils/staticData/index.js +7 -2
  50. package/core/logic-validation/request.js +31 -4
  51. package/core/types.d.ts +3 -2
  52. package/core/utils.js +24 -2
  53. package/koni/api/nft/ordinal_nft/index.js +3 -2
  54. package/koni/background/handlers/Extension.js +31 -8
  55. package/koni/background/handlers/State.js +4 -1
  56. package/koni/background/handlers/Tabs.js +11 -4
  57. package/package.json +21 -9
  58. package/packageInfo.js +1 -1
  59. package/page/evm/index.d.ts +9 -18
  60. package/page/evm/index.js +62 -101
  61. package/page/index.js +5 -3
  62. package/page/substrate/Accounts.js +2 -1
  63. package/services/balance-service/helpers/subscribe/index.d.ts +1 -11
  64. package/services/balance-service/helpers/subscribe/index.js +3 -74
  65. package/services/balance-service/helpers/subscribe/substrate/index.js +8 -14
  66. package/services/buy-service/index.js +2 -0
  67. package/services/chain-service/index.d.ts +1 -0
  68. package/services/chain-service/index.js +3 -0
  69. package/services/chain-service/utils/index.d.ts +10 -2
  70. package/services/chain-service/utils/index.js +29 -2
  71. package/services/chain-service/utils/patch.js +1 -1
  72. package/services/earning-service/constants/chains.d.ts +1 -0
  73. package/services/earning-service/constants/chains.js +2 -1
  74. package/services/earning-service/handlers/native-staking/amplitude.d.ts +1 -0
  75. package/services/earning-service/handlers/native-staking/amplitude.js +32 -0
  76. package/services/earning-service/handlers/native-staking/astar.d.ts +1 -0
  77. package/services/earning-service/handlers/native-staking/astar.js +18 -0
  78. package/services/earning-service/handlers/native-staking/base.d.ts +2 -0
  79. package/services/earning-service/handlers/native-staking/base.js +40 -29
  80. package/services/earning-service/handlers/native-staking/dtao.d.ts +1 -0
  81. package/services/earning-service/handlers/native-staking/dtao.js +5 -0
  82. package/services/earning-service/handlers/native-staking/mythos.d.ts +1 -0
  83. package/services/earning-service/handlers/native-staking/mythos.js +28 -0
  84. package/services/earning-service/handlers/native-staking/para-chain.d.ts +1 -0
  85. package/services/earning-service/handlers/native-staking/para-chain.js +17 -0
  86. package/services/earning-service/handlers/native-staking/relay-chain.d.ts +1 -0
  87. package/services/earning-service/handlers/native-staking/relay-chain.js +25 -2
  88. package/services/earning-service/handlers/native-staking/tao.d.ts +1 -0
  89. package/services/earning-service/handlers/native-staking/tao.js +5 -0
  90. package/services/earning-service/handlers/nomination-pool/index.d.ts +1 -0
  91. package/services/earning-service/handlers/nomination-pool/index.js +6 -3
  92. package/services/earning-service/service.d.ts +3 -0
  93. package/services/earning-service/service.js +68 -25
  94. package/services/history-service/index.js +12 -7
  95. package/services/keyring-service/context/handlers/Json.js +2 -1
  96. package/services/keyring-service/context/handlers/Ledger.js +7 -2
  97. package/services/request-service/handler/AuthRequestHandler.d.ts +1 -0
  98. package/services/request-service/handler/AuthRequestHandler.js +30 -6
  99. package/services/request-service/types.d.ts +1 -0
  100. package/services/subscan-service/index.d.ts +13 -27
  101. package/services/subscan-service/index.js +26 -95
  102. package/services/transaction-service/utils.js +11 -2
  103. package/strategy/api-request-strategy/context/base.d.ts +2 -6
  104. package/strategy/api-request-strategy/index.js +1 -0
  105. package/strategy/api-request-strategy/types.d.ts +4 -2
  106. package/strategy/api-request-strategy/utils/index.js +2 -2
  107. package/strategy/api-request-strategy-v2/index.d.ts +22 -0
  108. package/strategy/api-request-strategy-v2/index.js +128 -0
  109. package/strategy/api-request-strategy-v2/types.d.ts +11 -0
  110. package/strategy/api-request-strategy-v2/types.js +1 -0
  111. package/types/account/action/subscribe.d.ts +3 -0
  112. package/types/account/info/keyring.d.ts +3 -0
  113. package/types/account/info/keyring.js +1 -0
  114. package/types/balance/transfer.d.ts +1 -0
  115. package/types/buy.d.ts +1 -1
  116. package/utils/account/analyze.js +5 -2
  117. package/utils/account/common.d.ts +13 -1
  118. package/utils/account/common.js +91 -2
  119. package/utils/account/transform.js +10 -0
  120. package/utils/asset.d.ts +2 -1
  121. package/utils/asset.js +7 -1
  122. package/utils/gear/combine.d.ts +2 -1
  123. package/utils/gear/combine.js +4 -4
  124. package/utils/gear/vft.d.ts +20 -9
  125. package/utils/gear/vft.js +104 -135
  126. package/utils/staticData/assetHubStaking.json +1 -0
  127. package/utils/staticData/index.d.ts +4 -1
  128. package/utils/staticData/index.js +5 -1
@@ -2,15 +2,15 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
5
- import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
5
+ import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
6
6
  import { CRON_REFRESH_CHAIN_STAKING_METADATA, CRON_REFRESH_EARNING_REWARD_HISTORY_INTERVAL, CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL } from '@subwallet/extension-base/constants';
7
7
  import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
8
- import { _isChainEnabled, _isChainEvmCompatible } from '@subwallet/extension-base/services/chain-service/utils';
8
+ import { _getChainSubstrateTokenSymbol, _isChainEnabled } from '@subwallet/extension-base/services/chain-service/utils';
9
9
  import { _STAKING_CHAIN_GROUP } from '@subwallet/extension-base/services/earning-service/constants';
10
10
  import BaseLiquidStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/liquid-staking/base';
11
11
  import MythosNativeStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/native-staking/mythos';
12
12
  import { BasicTxErrorType, YieldPoolType } from '@subwallet/extension-base/types';
13
- import { addLazy, createPromiseHandler, getAddressesByChainType, removeLazy } from '@subwallet/extension-base/utils';
13
+ import { addLazy, createPromiseHandler, filterAddressByChainInfo, removeLazy } from '@subwallet/extension-base/utils';
14
14
  import { fetchStaticCache } from '@subwallet/extension-base/utils/fetchStaticCache';
15
15
  import { BehaviorSubject } from 'rxjs';
16
16
  import { AcalaLiquidStakingPoolHandler, AmplitudeNativeStakingPoolHandler, AstarNativeStakingPoolHandler, BifrostLiquidStakingPoolHandler, BifrostMantaLiquidStakingPoolHandler, InterlayLendingPoolHandler, NominationPoolHandler, ParallelLiquidStakingPoolHandler, ParaNativeStakingPoolHandler, RelayNativeStakingPoolHandler, StellaSwapLiquidStakingPoolHandler, SubnetTaoStakingPoolHandler, TaoNativeStakingPoolHandler } from "./handlers/index.js";
@@ -23,6 +23,7 @@ const fetchPoolsData = async () => {
23
23
  export default class EarningService {
24
24
  handlers = {};
25
25
  handlerCache = new Map();
26
+ inactivePoolSlug = new Set();
26
27
  earningRewardSubject = new BehaviorSubject({
27
28
  ready: false,
28
29
  data: {}
@@ -36,6 +37,7 @@ export default class EarningService {
36
37
  yieldPositionListSubject = new BehaviorSubject([]); // virtual list of yieldPositionSubject with filter values
37
38
 
38
39
  useOnlineCacheOnly = true;
40
+ inactivePoolReady = createPromiseHandler();
39
41
  constructor(state) {
40
42
  this.state = state;
41
43
  this.dbService = state.dbService;
@@ -53,10 +55,23 @@ export default class EarningService {
53
55
  }
54
56
  }
55
57
  const minAmountPercent = {};
58
+ const ahMapChain = await this.state.chainService.fetchAhMapChain();
56
59
  for (const chain of chains) {
57
60
  const handlers = [];
61
+ const chainInfo = this.state.getChainInfo(chain);
62
+ const symbol = _getChainSubstrateTokenSymbol(chainInfo);
58
63
  if (_STAKING_CHAIN_GROUP.relay.includes(chain)) {
59
- handlers.push(new RelayNativeStakingPoolHandler(this.state, chain));
64
+ if (_STAKING_CHAIN_GROUP.assetHub.includes(chain)) {
65
+ continue;
66
+ }
67
+ const ahChain = ahMapChain[chain];
68
+ if (ahChain) {
69
+ handlers.push(new RelayNativeStakingPoolHandler(this.state, ahChain));
70
+ const relaySlug = RelayNativeStakingPoolHandler.generateSlug(symbol, chain);
71
+ this.inactivePoolSlug.add(relaySlug);
72
+ } else {
73
+ handlers.push(new RelayNativeStakingPoolHandler(this.state, chain));
74
+ }
60
75
  }
61
76
  if (_STAKING_CHAIN_GROUP.para.includes(chain)) {
62
77
  handlers.push(new ParaNativeStakingPoolHandler(this.state, chain));
@@ -77,7 +92,14 @@ export default class EarningService {
77
92
  handlers.push(new MythosNativeStakingPoolHandler(this.state, chain));
78
93
  }
79
94
  if (_STAKING_CHAIN_GROUP.nominationPool.includes(chain)) {
80
- handlers.push(new NominationPoolHandler(this.state, chain));
95
+ const ahChain = ahMapChain[chain];
96
+ if (ahChain) {
97
+ handlers.push(new NominationPoolHandler(this.state, ahChain));
98
+ const relaySlug = NominationPoolHandler.generateSlug(symbol, chain);
99
+ this.inactivePoolSlug.add(relaySlug);
100
+ } else {
101
+ handlers.push(new NominationPoolHandler(this.state, chain));
102
+ }
81
103
  }
82
104
  if (_STAKING_CHAIN_GROUP.liquidStaking.includes(chain)) {
83
105
  if (chain === 'bifrost_dot') {
@@ -110,6 +132,7 @@ export default class EarningService {
110
132
  }
111
133
  minAmountPercent.default = BaseLiquidStakingPoolHandler.defaultMinAmountPercent;
112
134
  this.minAmountPercentSubject.next(minAmountPercent);
135
+ this.inactivePoolReady.resolve();
113
136
 
114
137
  // Emit earning ready
115
138
  this.eventService.emit('earning.ready', true);
@@ -129,7 +152,7 @@ export default class EarningService {
129
152
  next: data => {
130
153
  const activeMap = this.state.getActiveChainInfoMap();
131
154
  const activePositions = Object.values(data).filter(item => {
132
- return !!activeMap[item.chain];
155
+ return !!activeMap[item.chain] && !this.inactivePoolSlug.has(item.slug);
133
156
  });
134
157
  this.yieldPositionListSubject.next(Object.values(activePositions));
135
158
  }
@@ -312,7 +335,9 @@ export default class EarningService {
312
335
  const yieldPoolInfo = {};
313
336
  const existedYieldPoolInfo = await this.dbService.getYieldPools();
314
337
  existedYieldPoolInfo.forEach(info => {
315
- yieldPoolInfo[info.slug] = info;
338
+ if (!this.inactivePoolSlug.has(info.slug)) {
339
+ yieldPoolInfo[info.slug] = info;
340
+ }
316
341
  });
317
342
  this.yieldPoolInfoSubject.next(yieldPoolInfo);
318
343
  }
@@ -347,6 +372,10 @@ export default class EarningService {
347
372
  }
348
373
  async fetchingPoolsInfoOnline() {
349
374
  const onlineData = await fetchPoolsData();
375
+ await this.inactivePoolReady.promise;
376
+ for (const inactiveSlug of this.inactivePoolSlug) {
377
+ delete onlineData[inactiveSlug];
378
+ }
350
379
  Object.values(onlineData).forEach(item => {
351
380
  this.updateYieldPoolInfo(item);
352
381
  });
@@ -389,14 +418,11 @@ export default class EarningService {
389
418
  async subscribePoolPositions(addresses, callback) {
390
419
  let cancel = false;
391
420
  await this.eventService.waitChainReady;
392
- const evmAddresses = getAddressesByChainType(addresses, [ChainType.EVM]);
393
- const substrateAddresses = getAddressesByChainType(addresses, [ChainType.SUBSTRATE]);
394
421
  const activeChains = this.state.activeChainSlugs;
395
422
  const unsubList = [];
396
423
  for (const handler of Object.values(this.handlers)) {
397
424
  if (activeChains.includes(handler.chain)) {
398
- const chainInfo = handler.chainInfo;
399
- const useAddresses = _isChainEvmCompatible(chainInfo) ? evmAddresses : substrateAddresses;
425
+ const [useAddresses] = filterAddressByChainInfo(addresses, handler.chainInfo);
400
426
  handler.subscribePoolPosition(useAddresses, callback).then(unsub => {
401
427
  if (cancel) {
402
428
  unsub();
@@ -442,7 +468,9 @@ export default class EarningService {
442
468
  const existedYieldPosition = await this.dbService.getYieldNominationPoolPosition(addresses, this.state.activeChainSlugs);
443
469
  const yieldPositionInfo = this.yieldPositionSubject.getValue();
444
470
  existedYieldPosition.forEach(item => {
445
- yieldPositionInfo[this._getYieldPositionKey(item.slug, item.address)] = item;
471
+ if (!this.inactivePoolSlug.has(item.slug)) {
472
+ yieldPositionInfo[this._getYieldPositionKey(item.slug, item.address)] = item;
473
+ }
446
474
  });
447
475
  this.yieldPositionSubject.next(yieldPositionInfo);
448
476
  }
@@ -533,14 +561,11 @@ export default class EarningService {
533
561
  async getPoolReward(addresses, callback) {
534
562
  let cancel = false;
535
563
  await this.eventService.waitChainReady;
536
- const evmAddresses = getAddressesByChainType(addresses, [ChainType.EVM]);
537
- const substrateAddresses = getAddressesByChainType(addresses, [ChainType.SUBSTRATE]);
538
564
  const activeChains = this.state.activeChainSlugs;
539
565
  const unsubList = [];
540
566
  for (const handler of Object.values(this.handlers)) {
541
567
  if (activeChains.includes(handler.chain)) {
542
- const chainInfo = handler.chainInfo;
543
- const useAddresses = _isChainEvmCompatible(chainInfo) ? evmAddresses : substrateAddresses;
568
+ const [useAddresses] = filterAddressByChainInfo(addresses, handler.chainInfo);
544
569
  handler.getPoolReward(useAddresses, callback).then(unsub => {
545
570
  if (cancel) {
546
571
  unsub();
@@ -589,14 +614,11 @@ export default class EarningService {
589
614
  async fetchPoolRewardHistory(addresses, callback) {
590
615
  let cancel = false;
591
616
  await this.eventService.waitChainReady;
592
- const evmAddresses = getAddressesByChainType(addresses, [ChainType.EVM]);
593
- const substrateAddresses = getAddressesByChainType(addresses, [ChainType.SUBSTRATE]);
594
617
  const activeChains = this.state.activeChainSlugs;
595
618
  const unsubList = [];
596
619
  for (const handler of Object.values(this.handlers)) {
597
620
  if (activeChains.includes(handler.chain)) {
598
- const chainInfo = handler.chainInfo;
599
- const useAddresses = _isChainEvmCompatible(chainInfo) ? evmAddresses : substrateAddresses;
621
+ const [useAddresses] = filterAddressByChainInfo(addresses, handler.chainInfo);
600
622
  handler.getPoolRewardHistory(useAddresses, callback).then(unsub => {
601
623
  if (cancel) {
602
624
  unsub();
@@ -638,18 +660,39 @@ export default class EarningService {
638
660
  if (!addresses.length) {
639
661
  return;
640
662
  }
641
- this.fetchPoolRewardHistory(addresses, result => {
642
- this.updateEarningRewardHistory(result);
643
- }).catch(console.error);
644
- this.earningsRewardHistoryInterval = setInterval(() => {
663
+ let cancel = false;
664
+ let unsub;
665
+ this.unSubFetchEarningRewardHistory = () => {
666
+ if (!cancel) {
667
+ var _unsub2;
668
+ (_unsub2 = unsub) === null || _unsub2 === void 0 ? void 0 : _unsub2();
669
+ cancel = true;
670
+ }
671
+ };
672
+ const fetchData = () => {
645
673
  this.fetchPoolRewardHistory(addresses, result => {
674
+ if (cancel) {
675
+ return;
676
+ }
646
677
  this.updateEarningRewardHistory(result);
678
+ }).then(_unsub => {
679
+ if (!cancel) {
680
+ var _unsub3;
681
+ (_unsub3 = unsub) === null || _unsub3 === void 0 ? void 0 : _unsub3();
682
+ unsub = _unsub;
683
+ }
647
684
  }).catch(console.error);
648
- }, CRON_REFRESH_EARNING_REWARD_HISTORY_INTERVAL);
685
+ };
686
+ if (!cancel) {
687
+ fetchData();
688
+ }
689
+ this.earningsRewardHistoryInterval = setInterval(fetchData, CRON_REFRESH_EARNING_REWARD_HISTORY_INTERVAL);
649
690
  }
650
691
  runUnsubscribeEarningRewardHistoryInterval() {
692
+ var _this$unSubFetchEarni;
651
693
  removeLazy('updateEarningRewardHistory');
652
694
  this.earningRewardHistoryQueue = [];
695
+ (_this$unSubFetchEarni = this.unSubFetchEarningRewardHistory) === null || _this$unSubFetchEarni === void 0 ? void 0 : _this$unSubFetchEarni.call(this);
653
696
  this.earningsRewardHistoryInterval && clearInterval(this.earningsRewardHistoryInterval);
654
697
  }
655
698
 
@@ -74,7 +74,7 @@ export class HistoryService {
74
74
  /**
75
75
  * @todo: Must improve performance of this function
76
76
  * */
77
- fetchSubscanTransactionHistory(chain, addresses) {
77
+ fetchSubscanTransactionHistory(chain, addresses, groupId) {
78
78
  if (!this.subscanService.checkSupportedSubscanChain(chain) || !addresses.length) {
79
79
  return;
80
80
  }
@@ -87,7 +87,7 @@ export class HistoryService {
87
87
  // However, fetchAllPossibleTransferItems-sent must run after fetchAllPossibleExtrinsicItems,
88
88
  // to avoid "duplicate Extrinsic Hash between items" problem
89
89
 
90
- this.subscanService.fetchAllPossibleExtrinsicItems(chain, address, extrinsicItems => {
90
+ this.subscanService.fetchAllPossibleExtrinsicItems(groupId, chain, address, extrinsicItems => {
91
91
  const result = [];
92
92
  extrinsicItems.forEach(x => {
93
93
  const item = parseSubscanExtrinsicData(address, x, chainInfo);
@@ -105,7 +105,7 @@ export class HistoryService {
105
105
  excludeTransferExtrinsicHash.push(x.extrinsic_hash);
106
106
  }
107
107
  });
108
- this.subscanService.fetchAllPossibleTransferItems(chain, address, 'sent').then(rsMap => {
108
+ this.subscanService.fetchAllPossibleTransferItems(groupId, chain, address, 'sent').then(rsMap => {
109
109
  const result = [];
110
110
  Object.keys(rsMap).forEach(hash => {
111
111
  // only push item that does not have same hash with another item
@@ -125,7 +125,7 @@ export class HistoryService {
125
125
  }).catch(e => {
126
126
  console.log('fetchAllPossibleExtrinsicItems error', e);
127
127
  });
128
- this.subscanService.fetchAllPossibleTransferItems(chain, address, 'received').then(rsMap => {
128
+ this.subscanService.fetchAllPossibleTransferItems(groupId, chain, address, 'received').then(rsMap => {
129
129
  const result = [];
130
130
  Object.keys(rsMap).forEach(hash => {
131
131
  // only push item that does not have same hash with another item
@@ -172,14 +172,19 @@ export class HistoryService {
172
172
  const evmAddresses = getAddressesByChainType(addresses, [ChainType.EVM]);
173
173
  const substrateAddresses = getAddressesByChainType(addresses, [ChainType.SUBSTRATE]);
174
174
  const bitcoinAddresses = getAddressesByChainType(addresses, [ChainType.BITCOIN], chainInfo);
175
+ const groupId = this.subscanService.getGroupId();
175
176
  const subscription = this.historySubject.subscribe(items => {
176
177
  cb(items.filter(filterHistoryItemByAddressAndChain(chain, addresses)));
177
178
  });
179
+ const unsubscribe = () => {
180
+ subscription.unsubscribe();
181
+ this.subscanService.cancelGroupRequest(groupId);
182
+ };
178
183
  if (_isChainSubstrateCompatible(chainInfo)) {
179
184
  if (_isChainEvmCompatible(chainInfo)) {
180
- this.fetchSubscanTransactionHistory(chain, evmAddresses);
185
+ this.fetchSubscanTransactionHistory(chain, evmAddresses, groupId);
181
186
  } else {
182
- this.fetchSubscanTransactionHistory(chain, substrateAddresses);
187
+ this.fetchSubscanTransactionHistory(chain, substrateAddresses, groupId);
183
188
  }
184
189
  } else if (_isChainBitcoinCompatible(chainInfo)) {
185
190
  this.fetchBitcoinTransactionHistory(chain, bitcoinAddresses).catch(e => {
@@ -187,7 +192,7 @@ export class HistoryService {
187
192
  });
188
193
  }
189
194
  return {
190
- unsubscribe: subscription.unsubscribe,
195
+ unsubscribe,
191
196
  value: this.historySubject.getValue().filter(filterHistoryItemByAddressAndChain(chain, addresses))
192
197
  };
193
198
  }
@@ -2,6 +2,7 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { ALL_ACCOUNT_KEY } from '@subwallet/extension-base/constants';
5
+ import { AccountProxyType } from '@subwallet/extension-base/types';
5
6
  import { combineAccountsWithKeyPair, convertAccountProxyType, createPromiseHandler, transformAccount } from '@subwallet/extension-base/utils';
6
7
  import { generateRandomString } from '@subwallet/extension-base/utils/getId';
7
8
  import { createPair } from '@subwallet/keyring';
@@ -307,7 +308,7 @@ export class AccountJsonHandler extends AccountBaseHandler {
307
308
  const _proxyIds = proxyIds || Object.keys(_account);
308
309
  const modifyPairs = Object.fromEntries(Object.entries(_modifyPair).filter(([, modifyPair]) => _proxyIds.includes(modifyPair.accountProxyId || '')));
309
310
  const accountProxies = Object.fromEntries(Object.entries(_accountProxy).filter(([, proxy]) => _proxyIds.includes(proxy.id)));
310
- const addresses = Object.values(_account).filter(account => _proxyIds.includes(account.id)).flatMap(proxy => proxy.accounts.map(account => account.address));
311
+ const addresses = Object.values(_account).filter(account => _proxyIds.includes(account.id) && account.accountType !== AccountProxyType.LEDGER).flatMap(proxy => proxy.accounts.map(account => account.address));
311
312
  const rs = await keyring.backupAccounts(password, addresses);
312
313
  if (Object.keys(modifyPairs).length && Object.keys(accountProxies).length) {
313
314
  rs.accountProxies = accountProxies;
@@ -95,6 +95,7 @@ export class AccountLedgerHandler extends AccountBaseHandler {
95
95
  isEthereum,
96
96
  isGeneric,
97
97
  isLedgerRecovery,
98
+ isSubstrateECDSA,
98
99
  name,
99
100
  originGenesisHash
100
101
  } = account;
@@ -106,9 +107,13 @@ export class AccountLedgerHandler extends AccountBaseHandler {
106
107
  genesisHash,
107
108
  originGenesisHash,
108
109
  isGeneric,
109
- isLedgerRecovery
110
+ isLedgerRecovery,
111
+ isSubstrateECDSA
110
112
  };
111
- const type = isEthereum ? 'ethereum' : 'sr25519';
113
+ let type = 'sr25519';
114
+ if (isEthereum || isSubstrateECDSA) {
115
+ type = 'ethereum';
116
+ }
112
117
  const pair = keyring.keyring.createFromAddress(address, {
113
118
  ...baseMeta,
114
119
  isExternal: true,
@@ -18,6 +18,7 @@ export default class AuthRequestHandler {
18
18
  private init;
19
19
  private migrateAuthUrlInfoToUnified;
20
20
  private getAddressList;
21
+ private getEcdsaAddressList;
21
22
  get numAuthRequestsV2(): number;
22
23
  private get allAuthRequestsV2();
23
24
  private updateIconAuthV2;
@@ -47,6 +47,9 @@ export default class AuthRequestHandler {
47
47
  } else if (!value.currentNetworkMap) {
48
48
  value.currentNetworkMap = {};
49
49
  }
50
+ if (existKeyBothConnectAuthType) {
51
+ value.canConnectSubstrateEcdsa = true;
52
+ }
50
53
  acc[key] = {
51
54
  ...value
52
55
  };
@@ -81,6 +84,18 @@ export default class AuthRequestHandler {
81
84
  [v]: value
82
85
  }), {});
83
86
  }
87
+ getEcdsaAddressList() {
88
+ const addressList = Object.keys(this.keyringService.context.pairs);
89
+ const pairs = this.keyringService.context.pairs;
90
+ const ecdsaAddressList = new Set();
91
+ addressList.forEach(address => {
92
+ const pair = pairs[address];
93
+ if (pair && pair.json.meta.isSubstrateECDSA) {
94
+ ecdsaAddressList.add(address);
95
+ }
96
+ });
97
+ return ecdsaAddressList;
98
+ }
84
99
  get numAuthRequestsV2() {
85
100
  return Object.keys(this.#authRequestsV2).length;
86
101
  }
@@ -188,6 +203,7 @@ export default class AuthRequestHandler {
188
203
  }
189
204
  authCompleteV2 = (id, url, resolve, reject) => {
190
205
  const isAllowedMap = this.getAddressList();
206
+ const ecdsaAddressList = this.getEcdsaAddressList();
191
207
  const complete = (result, cb, accounts) => {
192
208
  const isAllowed = result === true;
193
209
  let isCancelled = false;
@@ -208,6 +224,7 @@ export default class AuthRequestHandler {
208
224
  idStr,
209
225
  request: {
210
226
  allowedAccounts,
227
+ canConnectSubstrateEcdsa,
211
228
  origin
212
229
  },
213
230
  url
@@ -215,10 +232,9 @@ export default class AuthRequestHandler {
215
232
 
216
233
  // Note: accountAuthTypes represents the accountAuthType of this request
217
234
  // allowedAccounts is a list of connected accounts that exist for this origin during this request.
218
-
219
235
  if (accountAuthTypes.length !== ALL_ACCOUNT_AUTH_TYPES.length) {
220
236
  const backupAllowed = (allowedAccounts || []).filter(a => {
221
- if (isEthereumAddress(a) && !accountAuthTypes.includes('evm')) {
237
+ if (isEthereumAddress(a) && (canConnectSubstrateEcdsa || !ecdsaAddressList.has(a)) && !accountAuthTypes.includes('evm')) {
222
238
  return true;
223
239
  }
224
240
  if (isSubstrateAddress(a) && !accountAuthTypes.includes('substrate')) {
@@ -281,7 +297,8 @@ export default class AuthRequestHandler {
281
297
  currentNetworkMap: existed ? {
282
298
  ...defaultNetworkMap,
283
299
  ...existed.currentNetworkMap
284
- } : defaultNetworkMap
300
+ } : defaultNetworkMap,
301
+ canConnectSubstrateEcdsa: canConnectSubstrateEcdsa || (existed === null || existed === void 0 ? void 0 : existed.canConnectSubstrateEcdsa)
285
302
  };
286
303
  this.setAuthorize(authorizeList, () => {
287
304
  cb();
@@ -312,6 +329,7 @@ export default class AuthRequestHandler {
312
329
  const idStr = stripUrl(url);
313
330
  const isAllowedDappConnectBothType = !!DAPP_CONNECT_BOTH_TYPE_ACCOUNT_URL.find(url_ => url.includes(url_));
314
331
  let accountAuthTypes = [...new Set(isAllowedDappConnectBothType ? ['evm', 'substrate'] : request.accountAuthTypes || ['substrate'])];
332
+ let canConnectSubstrateEcdsa = !!request.canConnectSubstrateEcdsa || isAllowedDappConnectBothType;
315
333
  if (!authList) {
316
334
  authList = {};
317
335
  }
@@ -344,6 +362,9 @@ export default class AuthRequestHandler {
344
362
  if (accountAuthTypes && _request.accountAuthTypes) {
345
363
  const filteredAccountAuthTypes = new Set([..._request.accountAuthTypes, ...accountAuthTypes]);
346
364
  accountAuthTypes = [...filteredAccountAuthTypes];
365
+ if (_request.request.canConnectSubstrateEcdsa) {
366
+ canConnectSubstrateEcdsa = true;
367
+ }
347
368
  }
348
369
  mergeKeys.push(key);
349
370
  }
@@ -372,9 +393,10 @@ export default class AuthRequestHandler {
372
393
  }
373
394
  request.allowedAccounts = Object.entries(existedAuth.isAllowedMap).map(([address, allowed]) => allowed ? address : '').filter(item => item !== '');
374
395
  let allowedListByRequestType = [...request.allowedAccounts];
396
+ const ecdsaAddressList = this.getEcdsaAddressList();
375
397
  allowedListByRequestType = accountAuthTypes.reduce((list, accountAuthType) => {
376
398
  if (accountAuthType === 'evm') {
377
- list.push(...allowedListByRequestType.filter(a => isEthereumAddress(a)));
399
+ list.push(...allowedListByRequestType.filter(a => isEthereumAddress(a) && (canConnectSubstrateEcdsa || !ecdsaAddressList.has(a))));
378
400
  } else if (accountAuthType === 'substrate') {
379
401
  list.push(...allowedListByRequestType.filter(a => isSubstrateAddress(a)));
380
402
  } else if (accountAuthType === 'ton') {
@@ -405,7 +427,8 @@ export default class AuthRequestHandler {
405
427
  origin,
406
428
  url,
407
429
  accountAuthTypes: ALL_ACCOUNT_AUTH_TYPES,
408
- currentNetworkMap: {}
430
+ currentNetworkMap: {},
431
+ canConnectSubstrateEcdsa
409
432
  };
410
433
  this.setAuthorize(authList);
411
434
  return true;
@@ -417,7 +440,8 @@ export default class AuthRequestHandler {
417
440
  idStr,
418
441
  request: {
419
442
  ...request,
420
- accountAuthTypes
443
+ accountAuthTypes,
444
+ canConnectSubstrateEcdsa
421
445
  },
422
446
  url,
423
447
  accountAuthTypes: accountAuthTypes || ['substrate']
@@ -21,6 +21,7 @@ export interface AuthUrlInfo {
21
21
  isAllowedMap: Record<string, boolean>;
22
22
  currentNetworkMap: Partial<Record<AccountAuthType, string>>;
23
23
  currentAccount?: string;
24
+ canConnectSubstrateEcdsa?: boolean;
24
25
  }
25
26
  export interface AuthUrlInfoNeedMigration extends Omit<AuthUrlInfo, 'accountAuthTypes'> {
26
27
  accountAuthType?: AccountAuthType | 'both';
@@ -1,44 +1,30 @@
1
- import { CrowdloanContributionsResponse, ExtrinsicItem, ExtrinsicsListResponse, IMultiChainBalance, RequestBlockRange, RewardHistoryListResponse, SubscanRequest, TransferItem, TransfersListResponse } from '@subwallet/extension-base/services/subscan-service/types';
1
+ import { CrowdloanContributionsResponse, ExtrinsicItem, ExtrinsicsListResponse, IMultiChainBalance, RequestBlockRange, RewardHistoryListResponse, TransferItem, TransfersListResponse } from '@subwallet/extension-base/services/subscan-service/types';
2
+ import { ApiRequestContextProps } from '@subwallet/extension-base/strategy/api-request-strategy/types';
3
+ import { BaseApiRequestStrategyV2 } from '@subwallet/extension-base/strategy/api-request-strategy-v2';
2
4
  import { SubscanEventBaseItemData, SubscanExtrinsicParam } from '@subwallet/extension-base/types';
3
- export declare class SubscanService {
5
+ export declare class SubscanService extends BaseApiRequestStrategyV2 {
4
6
  private subscanChainMap;
5
- private callRate;
6
- private limitRate;
7
- private intervalCheck;
8
- private maxRetry;
9
- private rollbackRateTime;
10
- private timeoutRollbackRate;
11
- private requestMap;
12
- private nextId;
13
- private isRunning;
14
- private getId;
15
- constructor(subscanChainMap: Record<string, string>, options?: {
16
- limitRate?: number;
17
- intervalCheck?: number;
18
- maxRetry?: number;
19
- });
20
- private reduceLimitRate;
7
+ constructor(subscanChainMap: Record<string, string>, options?: Partial<ApiRequestContextProps>);
21
8
  private getApiUrl;
22
9
  private postRequest;
23
- addRequest<T>(run: SubscanRequest<T>['run'], ordinal: number): Promise<T>;
24
- private process;
10
+ isRateLimited(e: Error): boolean;
25
11
  checkSupportedSubscanChain(chain: string): boolean;
26
12
  setSubscanChainMap(subscanChainMap: Record<string, string>): void;
27
13
  getMultiChainBalance(address: string): Promise<IMultiChainBalance[]>;
28
14
  getCrowdloanContributions(relayChain: string, address: string, page?: number): Promise<CrowdloanContributionsResponse>;
29
- getExtrinsicsList(chain: string, address: string, page?: number, blockRange?: RequestBlockRange): Promise<ExtrinsicsListResponse>;
30
- fetchAllPossibleExtrinsicItems(chain: string, address: string, cbAfterEachRequest?: (items: ExtrinsicItem[]) => void, limit?: {
15
+ getExtrinsicsList(groupId: number, chain: string, address: string, page?: number, blockRange?: RequestBlockRange): Promise<ExtrinsicsListResponse>;
16
+ fetchAllPossibleExtrinsicItems(groupId: number, chain: string, address: string, cbAfterEachRequest?: (items: ExtrinsicItem[]) => void, limit?: {
31
17
  page: number;
32
18
  record: number;
33
19
  }): Promise<ExtrinsicItem[]>;
34
- getTransfersList(chain: string, address: string, page?: number, direction?: 'sent' | 'received', blockRange?: RequestBlockRange): Promise<TransfersListResponse>;
35
- fetchAllPossibleTransferItems(chain: string, address: string, direction?: 'sent' | 'received', cbAfterEachRequest?: (items: TransferItem[]) => void, limit?: {
20
+ getTransfersList(groupId: number, chain: string, address: string, page?: number, direction?: 'sent' | 'received', blockRange?: RequestBlockRange): Promise<TransfersListResponse>;
21
+ fetchAllPossibleTransferItems(groupId: number, chain: string, address: string, direction?: 'sent' | 'received', cbAfterEachRequest?: (items: TransferItem[]) => void, limit?: {
36
22
  page: number;
37
23
  record: number;
38
24
  }): Promise<Record<string, TransferItem[]>>;
39
- getRewardHistoryList(chain: string, address: string, page?: number): Promise<RewardHistoryListResponse>;
40
- getAccountRemarkEvents(chain: string, address: string): Promise<SubscanEventBaseItemData[]>;
41
- getExtrinsicParams(chain: string, extrinsicIndexes: string[], ordinal?: number): Promise<SubscanExtrinsicParam[]>;
25
+ getRewardHistoryList(groupId: number, chain: string, address: string, page?: number): Promise<RewardHistoryListResponse>;
26
+ getAccountRemarkEvents(groupId: number, chain: string, address: string): Promise<SubscanEventBaseItemData[]>;
27
+ getExtrinsicParams(groupId: number, chain: string, extrinsicIndexes: string[], ordinal?: number): Promise<SubscanExtrinsicParam[]>;
42
28
  private static _instance;
43
29
  static getInstance(): SubscanService;
44
30
  }