@subwallet/extension-base 1.3.46-0 → 1.3.48-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 (119) hide show
  1. package/background/KoniTypes.d.ts +7 -1
  2. package/background/KoniTypes.js +1 -0
  3. package/background/errors/TransactionError.js +4 -0
  4. package/cjs/background/KoniTypes.js +1 -0
  5. package/cjs/background/errors/TransactionError.js +4 -0
  6. package/cjs/core/logic-validation/transfer.js +7 -0
  7. package/cjs/koni/api/nft/config.js +1 -1
  8. package/cjs/koni/api/nft/ordinal_nft/index.js +3 -2
  9. package/cjs/koni/background/handlers/Extension.js +21 -1
  10. package/cjs/koni/background/handlers/State.js +3 -0
  11. package/cjs/packageInfo.js +1 -1
  12. package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +8 -14
  13. package/cjs/services/buy-service/index.js +2 -0
  14. package/cjs/services/chain-service/index.js +7 -2
  15. package/cjs/services/chain-service/utils/index.js +3 -0
  16. package/cjs/services/chain-service/utils/patch.js +1 -1
  17. package/cjs/services/earning-service/constants/chains.js +4 -2
  18. package/cjs/services/earning-service/handlers/lending/interlay.js +2 -1
  19. package/cjs/services/earning-service/handlers/liquid-staking/acala.js +2 -1
  20. package/cjs/services/earning-service/handlers/liquid-staking/bifrost.js +2 -1
  21. package/cjs/services/earning-service/handlers/liquid-staking/parallel.js +2 -1
  22. package/cjs/services/earning-service/handlers/liquid-staking/stella-swap.js +2 -1
  23. package/cjs/services/earning-service/handlers/native-staking/amplitude.js +32 -0
  24. package/cjs/services/earning-service/handlers/native-staking/astar.js +20 -1
  25. package/cjs/services/earning-service/handlers/native-staking/base.js +42 -30
  26. package/cjs/services/earning-service/handlers/native-staking/dtao.js +79 -21
  27. package/cjs/services/earning-service/handlers/native-staking/mythos.js +30 -1
  28. package/cjs/services/earning-service/handlers/native-staking/para-chain.js +17 -0
  29. package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +49 -6
  30. package/cjs/services/earning-service/handlers/native-staking/tao.js +98 -32
  31. package/cjs/services/earning-service/handlers/nomination-pool/index.js +5 -2
  32. package/cjs/services/earning-service/handlers/special.js +3 -1
  33. package/cjs/services/earning-service/service.js +52 -7
  34. package/cjs/services/history-service/index.js +12 -7
  35. package/cjs/services/subscan-service/index.js +35 -104
  36. package/cjs/services/transaction-service/helpers/index.js +2 -0
  37. package/cjs/services/transaction-service/index.js +15 -0
  38. package/cjs/services/transaction-service/utils.js +10 -1
  39. package/cjs/strategy/api-request-strategy/index.js +1 -0
  40. package/cjs/strategy/api-request-strategy/utils/index.js +2 -2
  41. package/cjs/strategy/api-request-strategy-v2/index.js +138 -0
  42. package/cjs/strategy/api-request-strategy-v2/types.js +1 -0
  43. package/cjs/types/transaction/error.js +1 -0
  44. package/cjs/utils/account/transform.js +3 -2
  45. package/cjs/utils/gear/combine.js +4 -3
  46. package/cjs/utils/gear/vft.js +104 -135
  47. package/core/logic-validation/transfer.js +7 -0
  48. package/koni/api/nft/config.d.ts +1 -1
  49. package/koni/api/nft/config.js +1 -1
  50. package/koni/api/nft/ordinal_nft/index.js +3 -2
  51. package/koni/background/handlers/Extension.d.ts +1 -0
  52. package/koni/background/handlers/Extension.js +21 -1
  53. package/koni/background/handlers/State.js +4 -1
  54. package/package.json +20 -9
  55. package/packageInfo.js +1 -1
  56. package/services/balance-service/helpers/subscribe/substrate/index.js +8 -14
  57. package/services/buy-service/index.js +2 -0
  58. package/services/chain-service/index.js +7 -2
  59. package/services/chain-service/utils/index.js +3 -0
  60. package/services/chain-service/utils/patch.js +1 -1
  61. package/services/earning-service/constants/chains.d.ts +1 -0
  62. package/services/earning-service/constants/chains.js +2 -1
  63. package/services/earning-service/handlers/base.d.ts +5 -3
  64. package/services/earning-service/handlers/lending/interlay.d.ts +1 -1
  65. package/services/earning-service/handlers/lending/interlay.js +2 -1
  66. package/services/earning-service/handlers/liquid-staking/acala.d.ts +1 -1
  67. package/services/earning-service/handlers/liquid-staking/acala.js +2 -1
  68. package/services/earning-service/handlers/liquid-staking/bifrost.d.ts +1 -1
  69. package/services/earning-service/handlers/liquid-staking/bifrost.js +2 -1
  70. package/services/earning-service/handlers/liquid-staking/parallel.d.ts +1 -1
  71. package/services/earning-service/handlers/liquid-staking/parallel.js +2 -1
  72. package/services/earning-service/handlers/liquid-staking/stella-swap.d.ts +1 -1
  73. package/services/earning-service/handlers/liquid-staking/stella-swap.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 +2 -1
  77. package/services/earning-service/handlers/native-staking/astar.js +20 -1
  78. package/services/earning-service/handlers/native-staking/base.d.ts +4 -2
  79. package/services/earning-service/handlers/native-staking/base.js +42 -30
  80. package/services/earning-service/handlers/native-staking/dtao.d.ts +5 -3
  81. package/services/earning-service/handlers/native-staking/dtao.js +80 -22
  82. package/services/earning-service/handlers/native-staking/mythos.d.ts +2 -1
  83. package/services/earning-service/handlers/native-staking/mythos.js +30 -1
  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 +6 -1
  87. package/services/earning-service/handlers/native-staking/relay-chain.js +50 -7
  88. package/services/earning-service/handlers/native-staking/tao.d.ts +23 -4
  89. package/services/earning-service/handlers/native-staking/tao.js +99 -33
  90. package/services/earning-service/handlers/nomination-pool/index.d.ts +3 -2
  91. package/services/earning-service/handlers/nomination-pool/index.js +5 -2
  92. package/services/earning-service/handlers/special.d.ts +2 -1
  93. package/services/earning-service/handlers/special.js +3 -1
  94. package/services/earning-service/service.d.ts +3 -1
  95. package/services/earning-service/service.js +52 -7
  96. package/services/history-service/index.js +12 -7
  97. package/services/subscan-service/index.d.ts +13 -27
  98. package/services/subscan-service/index.js +26 -95
  99. package/services/transaction-service/helpers/index.js +2 -0
  100. package/services/transaction-service/index.js +15 -0
  101. package/services/transaction-service/utils.js +11 -2
  102. package/strategy/api-request-strategy/context/base.d.ts +2 -6
  103. package/strategy/api-request-strategy/index.js +1 -0
  104. package/strategy/api-request-strategy/types.d.ts +4 -2
  105. package/strategy/api-request-strategy/utils/index.js +2 -2
  106. package/strategy/api-request-strategy-v2/index.d.ts +22 -0
  107. package/strategy/api-request-strategy-v2/index.js +128 -0
  108. package/strategy/api-request-strategy-v2/types.d.ts +11 -0
  109. package/strategy/api-request-strategy-v2/types.js +1 -0
  110. package/types/buy.d.ts +1 -1
  111. package/types/transaction/error.d.ts +2 -1
  112. package/types/transaction/error.js +1 -0
  113. package/types/yield/actions/join/submit.d.ts +10 -1
  114. package/types/yield/info/chain/info.d.ts +2 -0
  115. package/utils/account/transform.js +3 -2
  116. package/utils/gear/combine.d.ts +2 -1
  117. package/utils/gear/combine.js +4 -4
  118. package/utils/gear/vft.d.ts +20 -9
  119. package/utils/gear/vft.js +104 -135
@@ -384,7 +384,13 @@ class EarningService {
384
384
  delete onlineData[inactiveSlug];
385
385
  }
386
386
  Object.values(onlineData).forEach(item => {
387
- this.updateYieldPoolInfo(item);
387
+ const handler = this.getPoolHandler(item.slug);
388
+ if (!handler) {
389
+ return;
390
+ }
391
+ const updatedItem = structuredClone(item);
392
+ updatedItem.metadata.availableMethod = handler.availableMethod;
393
+ this.updateYieldPoolInfo(updatedItem);
388
394
  });
389
395
  return onlineData;
390
396
  }
@@ -670,18 +676,39 @@ class EarningService {
670
676
  if (!addresses.length) {
671
677
  return;
672
678
  }
673
- this.fetchPoolRewardHistory(addresses, result => {
674
- this.updateEarningRewardHistory(result);
675
- }).catch(console.error);
676
- this.earningsRewardHistoryInterval = setInterval(() => {
679
+ let cancel = false;
680
+ let unsub;
681
+ this.unSubFetchEarningRewardHistory = () => {
682
+ if (!cancel) {
683
+ var _unsub2;
684
+ (_unsub2 = unsub) === null || _unsub2 === void 0 ? void 0 : _unsub2();
685
+ cancel = true;
686
+ }
687
+ };
688
+ const fetchData = () => {
677
689
  this.fetchPoolRewardHistory(addresses, result => {
690
+ if (cancel) {
691
+ return;
692
+ }
678
693
  this.updateEarningRewardHistory(result);
694
+ }).then(_unsub => {
695
+ if (!cancel) {
696
+ var _unsub3;
697
+ (_unsub3 = unsub) === null || _unsub3 === void 0 ? void 0 : _unsub3();
698
+ unsub = _unsub;
699
+ }
679
700
  }).catch(console.error);
680
- }, _constants.CRON_REFRESH_EARNING_REWARD_HISTORY_INTERVAL);
701
+ };
702
+ if (!cancel) {
703
+ fetchData();
704
+ }
705
+ this.earningsRewardHistoryInterval = setInterval(fetchData, _constants.CRON_REFRESH_EARNING_REWARD_HISTORY_INTERVAL);
681
706
  }
682
707
  runUnsubscribeEarningRewardHistoryInterval() {
708
+ var _this$unSubFetchEarni;
683
709
  (0, _utils2.removeLazy)('updateEarningRewardHistory');
684
710
  this.earningRewardHistoryQueue = [];
711
+ (_this$unSubFetchEarni = this.unSubFetchEarningRewardHistory) === null || _this$unSubFetchEarni === void 0 ? void 0 : _this$unSubFetchEarni.call(this);
685
712
  this.earningsRewardHistoryInterval && clearInterval(this.earningsRewardHistoryInterval);
686
713
  }
687
714
 
@@ -703,7 +730,13 @@ class EarningService {
703
730
  const handler = this.getPoolHandler(slug);
704
731
  if (!targets.length && handler) {
705
732
  await this.eventService.waitChainReady;
706
- targets = await handler.getPoolTargets();
733
+ const isSubnet = slug.match(/subnet_(\d+)/);
734
+ if (isSubnet) {
735
+ const subnet = Number(isSubnet[1]);
736
+ targets = await handler.getPoolTargets(subnet);
737
+ } else {
738
+ targets = await handler.getPoolTargets();
739
+ }
707
740
  }
708
741
  return targets;
709
742
  }
@@ -846,6 +879,18 @@ class EarningService {
846
879
  return Promise.reject(new _TransactionError.TransactionError(_types2.BasicTxErrorType.INTERNAL_ERROR));
847
880
  }
848
881
  }
882
+ async handleYieldChangeValidator(params) {
883
+ await this.eventService.waitChainReady;
884
+ const {
885
+ slug
886
+ } = params;
887
+ const handler = this.getPoolHandler(slug);
888
+ if (handler) {
889
+ return handler.handleChangeEarningValidator(params);
890
+ } else {
891
+ return Promise.reject(new _TransactionError.TransactionError(_types2.BasicTxErrorType.INTERNAL_ERROR));
892
+ }
893
+ }
849
894
 
850
895
  /* Other */
851
896
 
@@ -81,7 +81,7 @@ class HistoryService {
81
81
  /**
82
82
  * @todo: Must improve performance of this function
83
83
  * */
84
- fetchSubscanTransactionHistory(chain, addresses) {
84
+ fetchSubscanTransactionHistory(chain, addresses, groupId) {
85
85
  if (!this.subscanService.checkSupportedSubscanChain(chain) || !addresses.length) {
86
86
  return;
87
87
  }
@@ -94,7 +94,7 @@ class HistoryService {
94
94
  // However, fetchAllPossibleTransferItems-sent must run after fetchAllPossibleExtrinsicItems,
95
95
  // to avoid "duplicate Extrinsic Hash between items" problem
96
96
 
97
- this.subscanService.fetchAllPossibleExtrinsicItems(chain, address, extrinsicItems => {
97
+ this.subscanService.fetchAllPossibleExtrinsicItems(groupId, chain, address, extrinsicItems => {
98
98
  const result = [];
99
99
  extrinsicItems.forEach(x => {
100
100
  const item = (0, _subscanHistory.parseSubscanExtrinsicData)(address, x, chainInfo);
@@ -112,7 +112,7 @@ class HistoryService {
112
112
  excludeTransferExtrinsicHash.push(x.extrinsic_hash);
113
113
  }
114
114
  });
115
- this.subscanService.fetchAllPossibleTransferItems(chain, address, 'sent').then(rsMap => {
115
+ this.subscanService.fetchAllPossibleTransferItems(groupId, chain, address, 'sent').then(rsMap => {
116
116
  const result = [];
117
117
  Object.keys(rsMap).forEach(hash => {
118
118
  // only push item that does not have same hash with another item
@@ -132,7 +132,7 @@ class HistoryService {
132
132
  }).catch(e => {
133
133
  console.log('fetchAllPossibleExtrinsicItems error', e);
134
134
  });
135
- this.subscanService.fetchAllPossibleTransferItems(chain, address, 'received').then(rsMap => {
135
+ this.subscanService.fetchAllPossibleTransferItems(groupId, chain, address, 'received').then(rsMap => {
136
136
  const result = [];
137
137
  Object.keys(rsMap).forEach(hash => {
138
138
  // only push item that does not have same hash with another item
@@ -179,14 +179,19 @@ class HistoryService {
179
179
  const evmAddresses = (0, _utils2.getAddressesByChainType)(addresses, [_KoniTypes.ChainType.EVM]);
180
180
  const substrateAddresses = (0, _utils2.getAddressesByChainType)(addresses, [_KoniTypes.ChainType.SUBSTRATE]);
181
181
  const bitcoinAddresses = (0, _utils2.getAddressesByChainType)(addresses, [_KoniTypes.ChainType.BITCOIN], chainInfo);
182
+ const groupId = this.subscanService.getGroupId();
182
183
  const subscription = this.historySubject.subscribe(items => {
183
184
  cb(items.filter(filterHistoryItemByAddressAndChain(chain, addresses)));
184
185
  });
186
+ const unsubscribe = () => {
187
+ subscription.unsubscribe();
188
+ this.subscanService.cancelGroupRequest(groupId);
189
+ };
185
190
  if ((0, _utils._isChainSubstrateCompatible)(chainInfo)) {
186
191
  if ((0, _utils._isChainEvmCompatible)(chainInfo)) {
187
- this.fetchSubscanTransactionHistory(chain, evmAddresses);
192
+ this.fetchSubscanTransactionHistory(chain, evmAddresses, groupId);
188
193
  } else {
189
- this.fetchSubscanTransactionHistory(chain, substrateAddresses);
194
+ this.fetchSubscanTransactionHistory(chain, substrateAddresses, groupId);
190
195
  }
191
196
  } else if ((0, _utils._isChainBitcoinCompatible)(chainInfo)) {
192
197
  this.fetchBitcoinTransactionHistory(chain, bitcoinAddresses).catch(e => {
@@ -194,7 +199,7 @@ class HistoryService {
194
199
  });
195
200
  }
196
201
  return {
197
- unsubscribe: subscription.unsubscribe,
202
+ unsubscribe,
198
203
  value: this.historySubject.getValue().filter(filterHistoryItemByAddressAndChain(chain, addresses))
199
204
  };
200
205
  }
@@ -7,37 +7,18 @@ exports.SubscanService = void 0;
7
7
  var _SWError = require("@subwallet/extension-base/background/errors/SWError");
8
8
  var _constants = require("@subwallet/extension-base/koni/api/nft/ordinal_nft/constants");
9
9
  var _subscanChainMap = require("@subwallet/extension-base/services/subscan-service/subscan-chain-map");
10
+ var _base = require("@subwallet/extension-base/strategy/api-request-strategy/context/base");
11
+ var _apiRequestStrategyV = require("@subwallet/extension-base/strategy/api-request-strategy-v2");
10
12
  var _utils = require("@subwallet/extension-base/utils");
11
13
  // Copyright 2019-2022 @subwallet/extension-base
12
14
  // SPDX-License-Identifier: Apache-2.0
13
15
 
14
16
  const QUERY_ROW = 100;
15
- class SubscanService {
16
- callRate = 2; // limit per interval check
17
- limitRate = 2; // max rate per interval check
18
- intervalCheck = 1000; // interval check in ms
19
- maxRetry = 9; // interval check in ms
20
- rollbackRateTime = 30 * 1000; // rollback rate time in ms
21
- timeoutRollbackRate = undefined;
22
- requestMap = {};
23
- nextId = 0;
24
- isRunning = false;
25
- getId() {
26
- return this.nextId++;
27
- }
17
+ class SubscanService extends _apiRequestStrategyV.BaseApiRequestStrategyV2 {
28
18
  constructor(subscanChainMap, options) {
19
+ const context = new _base.BaseApiRequestContext(options);
20
+ super(context);
29
21
  this.subscanChainMap = subscanChainMap;
30
- this.callRate = (options === null || options === void 0 ? void 0 : options.limitRate) || this.callRate;
31
- this.limitRate = (options === null || options === void 0 ? void 0 : options.limitRate) || this.limitRate;
32
- this.intervalCheck = (options === null || options === void 0 ? void 0 : options.intervalCheck) || this.intervalCheck;
33
- this.maxRetry = (options === null || options === void 0 ? void 0 : options.maxRetry) || this.maxRetry;
34
- }
35
- reduceLimitRate() {
36
- clearTimeout(this.timeoutRollbackRate);
37
- this.callRate = Math.ceil(this.limitRate / 2);
38
- this.timeoutRollbackRate = setTimeout(() => {
39
- this.callRate = this.limitRate;
40
- }, this.rollbackRateTime);
41
22
  }
42
23
  getApiUrl(chain, path) {
43
24
  const subscanChain = this.subscanChainMap[chain];
@@ -55,61 +36,9 @@ class SubscanService {
55
36
  body: JSON.stringify(body)
56
37
  });
57
38
  }
58
- addRequest(run, ordinal) {
59
- const newId = this.getId();
60
- return new Promise((resolve, reject) => {
61
- this.requestMap[newId] = {
62
- id: newId,
63
- status: 'pending',
64
- retry: -1,
65
- ordinal,
66
- run,
67
- resolve,
68
- reject
69
- };
70
- if (!this.isRunning) {
71
- this.process();
72
- }
73
- });
74
- }
75
- process() {
76
- this.isRunning = true;
77
- const maxRetry = this.maxRetry;
78
- const interval = setInterval(() => {
79
- const remainingRequests = Object.values(this.requestMap);
80
- if (remainingRequests.length === 0) {
81
- this.isRunning = false;
82
- clearInterval(interval);
83
- return;
84
- }
85
-
86
- // Get first this.limit requests base on id
87
- const requests = remainingRequests.filter(request => request.status !== 'running').sort((a, b) => a.id - b.id).sort((a, b) => a.ordinal - b.ordinal).slice(0, this.callRate);
88
-
89
- // Start requests
90
- requests.forEach(request => {
91
- request.status = 'running';
92
- request.run().then(rs => {
93
- request.resolve(rs);
94
- }).catch(e => {
95
- const error = JSON.parse(e.message);
96
-
97
- // Limit rate
98
- if (error.code === 20008) {
99
- if (request.retry < maxRetry) {
100
- request.status = 'pending';
101
- request.retry++;
102
- this.reduceLimitRate();
103
- } else {
104
- // Reject request
105
- request.reject(new _SWError.SWError('MAX_RETRY', String(e)));
106
- }
107
- } else {
108
- request.reject(new _SWError.SWError('UNKNOWN', String(e)));
109
- }
110
- });
111
- });
112
- }, this.intervalCheck);
39
+ isRateLimited(e) {
40
+ const error = JSON.parse(e.message);
41
+ return error.code === 20008;
113
42
  }
114
43
  checkSupportedSubscanChain(chain) {
115
44
  return !!this.subscanChainMap[chain];
@@ -120,6 +49,7 @@ class SubscanService {
120
49
 
121
50
  // Implement Subscan API
122
51
  getMultiChainBalance(address) {
52
+ const hashKey = this.createKeyHash(['multi_chain_balance', address]);
123
53
  return this.addRequest(async () => {
124
54
  const rs = await this.postRequest(this.getApiUrl('polkadot', 'api/scan/multiChain/account'), {
125
55
  address
@@ -129,7 +59,7 @@ class SubscanService {
129
59
  }
130
60
  const jsonData = await rs.json();
131
61
  return jsonData.data;
132
- }, 1);
62
+ }, 1, undefined, hashKey);
133
63
  }
134
64
  getCrowdloanContributions(relayChain, address) {
135
65
  let page = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
@@ -147,9 +77,9 @@ class SubscanService {
147
77
  return jsonData.data;
148
78
  }, 2);
149
79
  }
150
- getExtrinsicsList(chain, address) {
151
- let page = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
152
- let blockRange = arguments.length > 3 ? arguments[3] : undefined;
80
+ getExtrinsicsList(groupId, chain, address) {
81
+ let page = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
82
+ let blockRange = arguments.length > 4 ? arguments[4] : undefined;
153
83
  const _blockRange = (() => {
154
84
  if (!blockRange || !blockRange.to) {
155
85
  return null;
@@ -168,10 +98,10 @@ class SubscanService {
168
98
  }
169
99
  const jsonData = await rs.json();
170
100
  return jsonData.data;
171
- }, 0);
101
+ }, 0, groupId);
172
102
  }
173
- async fetchAllPossibleExtrinsicItems(chain, address, cbAfterEachRequest) {
174
- let limit = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {
103
+ async fetchAllPossibleExtrinsicItems(groupId, chain, address, cbAfterEachRequest) {
104
+ let limit = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {
175
105
  page: 10,
176
106
  record: 1000
177
107
  };
@@ -183,7 +113,7 @@ class SubscanService {
183
113
  };
184
114
  const resultMap = {};
185
115
  const _getExtrinsicItems = async page => {
186
- const res = await this.getExtrinsicsList(chain, address, page, blockRange);
116
+ const res = await this.getExtrinsicsList(groupId, chain, address, page, blockRange);
187
117
  if (!res || !res.count || !res.extrinsics || !res.extrinsics.length) {
188
118
  return;
189
119
  }
@@ -192,7 +122,7 @@ class SubscanService {
192
122
  }
193
123
  const extrinsics = res.extrinsics;
194
124
  const extrinsicIndexes = extrinsics.map(item => item.extrinsic_index);
195
- const extrinsicParams = await this.getExtrinsicParams(chain, extrinsicIndexes, 0);
125
+ const extrinsicParams = await this.getExtrinsicParams(groupId, chain, extrinsicIndexes, 0);
196
126
  for (const data of extrinsicParams) {
197
127
  const {
198
128
  extrinsic_index: extrinsicIndex,
@@ -224,10 +154,10 @@ class SubscanService {
224
154
  await _getExtrinsicItems(0);
225
155
  return Object.values(resultMap);
226
156
  }
227
- getTransfersList(chain, address) {
228
- let page = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
229
- let direction = arguments.length > 3 ? arguments[3] : undefined;
230
- let blockRange = arguments.length > 4 ? arguments[4] : undefined;
157
+ getTransfersList(groupId, chain, address) {
158
+ let page = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
159
+ let direction = arguments.length > 4 ? arguments[4] : undefined;
160
+ let blockRange = arguments.length > 5 ? arguments[5] : undefined;
231
161
  return this.addRequest(async () => {
232
162
  const rs = await this.postRequest(this.getApiUrl(chain, 'api/v2/scan/transfers'), {
233
163
  page,
@@ -242,10 +172,10 @@ class SubscanService {
242
172
  }
243
173
  const jsonData = await rs.json();
244
174
  return jsonData.data;
245
- }, 0);
175
+ }, 0, groupId);
246
176
  }
247
- async fetchAllPossibleTransferItems(chain, address, direction, cbAfterEachRequest) {
248
- let limit = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {
177
+ async fetchAllPossibleTransferItems(groupId, chain, address, direction, cbAfterEachRequest) {
178
+ let limit = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {
249
179
  page: 10,
250
180
  record: 1000
251
181
  };
@@ -257,7 +187,7 @@ class SubscanService {
257
187
  };
258
188
  const resultMap = {};
259
189
  const _getTransferItems = async page => {
260
- const res = await this.getTransfersList(chain, address, page, direction, blockRange);
190
+ const res = await this.getTransfersList(groupId, chain, address, page, direction, blockRange);
261
191
  if (!res || !res.count || !res.transfers || !res.transfers.length) {
262
192
  return;
263
193
  }
@@ -287,8 +217,9 @@ class SubscanService {
287
217
  await _getTransferItems(0);
288
218
  return resultMap;
289
219
  }
290
- getRewardHistoryList(chain, address) {
291
- let page = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
220
+ getRewardHistoryList(groupId, chain, address) {
221
+ let page = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
222
+ const hashKey = this.createKeyHash([chain, 'reward_slash', address, page]);
292
223
  return this.addRequest(async () => {
293
224
  const rs = await this.postRequest(this.getApiUrl(chain, 'api/scan/account/reward_slash'), {
294
225
  page,
@@ -308,9 +239,9 @@ class SubscanService {
308
239
  };
309
240
  }
310
241
  return jsonData.data;
311
- }, 2);
242
+ }, 2, groupId, hashKey);
312
243
  }
313
- getAccountRemarkEvents(chain, address) {
244
+ getAccountRemarkEvents(groupId, chain, address) {
314
245
  return this.addRequest(async () => {
315
246
  const rs = await this.postRequest(this.getApiUrl(chain, 'api/v2/scan/events'), {
316
247
  ..._constants.BASE_FETCH_ORDINAL_EVENT_DATA,
@@ -321,10 +252,10 @@ class SubscanService {
321
252
  }
322
253
  const jsonData = await rs.json();
323
254
  return jsonData.data.events;
324
- }, 3);
255
+ }, 3, groupId);
325
256
  }
326
- getExtrinsicParams(chain, extrinsicIndexes) {
327
- let ordinal = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 3;
257
+ getExtrinsicParams(groupId, chain, extrinsicIndexes) {
258
+ let ordinal = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 3;
328
259
  return this.addRequest(async () => {
329
260
  const rs = await this.postRequest(this.getApiUrl(chain, 'api/scan/extrinsic/params'), {
330
261
  extrinsic_index: extrinsicIndexes
@@ -334,7 +265,7 @@ class SubscanService {
334
265
  }
335
266
  const jsonData = await rs.json();
336
267
  return jsonData.data;
337
- }, ordinal);
268
+ }, ordinal, groupId);
338
269
  }
339
270
 
340
271
  // Singleton
@@ -73,6 +73,8 @@ const typeName = type => {
73
73
  return 'Withdraw pool';
74
74
  case _KoniTypes.ExtrinsicType.JOIN_YIELD_POOL:
75
75
  return 'Start earning';
76
+ case _KoniTypes.ExtrinsicType.CHANGE_EARNING_VALIDATOR:
77
+ return 'Change validator';
76
78
  case _KoniTypes.ExtrinsicType.UNKNOWN:
77
79
  default:
78
80
  return 'unknown';
@@ -916,6 +916,21 @@ class TransactionService {
916
916
  };
917
917
  break;
918
918
  }
919
+ case _KoniTypes.ExtrinsicType.CHANGE_EARNING_VALIDATOR:
920
+ {
921
+ var _data$metadata;
922
+ const data = (0, _utils3.parseTransactionData)(transaction.data);
923
+ historyItem.additionalInfo = {
924
+ symbol: ((_data$metadata = data.metadata) === null || _data$metadata === void 0 ? void 0 : _data$metadata.subnetSymbol) || ''
925
+ };
926
+ if (data.amount !== '0') {
927
+ historyItem.amount = {
928
+ ...baseNativeAmount,
929
+ value: data.amount
930
+ };
931
+ }
932
+ break;
933
+ }
919
934
  case _KoniTypes.ExtrinsicType.EVM_EXECUTE:
920
935
  {
921
936
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
@@ -46,13 +46,19 @@ function getBlockExplorerAccountRoute(explorerLink) {
46
46
  if (explorerLink.includes('taostats.io')) {
47
47
  return 'account';
48
48
  }
49
+ if (explorerLink.includes('tonviewer.com')) {
50
+ return '';
51
+ }
52
+ if (explorerLink.includes('devnet-explorer.mosaicchain.io')) {
53
+ return 'accounts';
54
+ }
49
55
  return 'address';
50
56
  }
51
57
  function getBlockExplorerTxRoute(chainInfo) {
52
58
  if ((0, _utils._isPureEvmChain)(chainInfo) || (0, _utils._isPureBitcoinChain)(chainInfo)) {
53
59
  return 'tx';
54
60
  }
55
- if ((0, _utils._isPureCardanoChain)(chainInfo)) {
61
+ if ((0, _utils._isPureCardanoChain)(chainInfo) || (0, _utils._isPureTonChain)(chainInfo)) {
56
62
  return 'transaction';
57
63
  }
58
64
  if (['aventus', 'deeper_network'].includes(chainInfo.slug)) {
@@ -61,6 +67,9 @@ function getBlockExplorerTxRoute(chainInfo) {
61
67
  if (['gen6_public'].includes(chainInfo.slug)) {
62
68
  return '#/extrinsics';
63
69
  }
70
+ if (['mosaicTest'].includes(chainInfo.slug)) {
71
+ return 'transactions';
72
+ }
64
73
  const explorerLink = (0, _utils._getBlockExplorerFromChain)(chainInfo);
65
74
  if (explorerLink && explorerLink.includes('statescan.io')) {
66
75
  return '#/extrinsics';
@@ -56,6 +56,7 @@ class BaseApiRequestStrategy {
56
56
  request.status = 'running';
57
57
  request.run().then(rs => {
58
58
  request.resolve(rs);
59
+ delete this.requestMap[request.id];
59
60
  }).catch(e => {
60
61
  const isRateLimited = this.isRateLimited(e);
61
62
 
@@ -21,8 +21,8 @@ const postRequest = function (url, body, headers) {
21
21
  };
22
22
  exports.postRequest = postRequest;
23
23
  const getRequest = (url, params, headers) => {
24
- const queryString = params ? Object.keys(params).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`).join('&') : '';
25
- const _url = `${url}?${queryString}`;
24
+ const q = new URLSearchParams(params);
25
+ const _url = `${url}?${q.toString()}`;
26
26
  return (0, _crossFetch.default)(_url, {
27
27
  method: 'GET',
28
28
  headers: headers || {
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.BaseApiRequestStrategyV2 = void 0;
7
+ var _SWError = require("@subwallet/extension-base/background/errors/SWError");
8
+ var _constants = require("@subwallet/extension-base/constants");
9
+ var _tsMd = require("ts-md5");
10
+ // Copyright 2019-2022 @subwallet/extension-base
11
+ // SPDX-License-Identifier: Apache-2.0
12
+
13
+ class BaseApiRequestStrategyV2 {
14
+ nextId = 0;
15
+ groupId = 0;
16
+ isRunning = false;
17
+ requestMap = {};
18
+ processInterval = undefined;
19
+ canceledGroupIds = new Set();
20
+ cacheMap = new Map();
21
+ getId() {
22
+ return this.nextId++;
23
+ }
24
+ constructor(context) {
25
+ this.context = context;
26
+ }
27
+ getGroupId() {
28
+ return this.groupId++;
29
+ }
30
+ createKeyHash(keys) {
31
+ return _tsMd.Md5.hashStr(JSON.stringify([this.constructor.name, ...keys]));
32
+ }
33
+ addRequest(run, ordinal, _groupId, keyHash) {
34
+ const newId = this.getId();
35
+ const groupId = _groupId !== null && _groupId !== void 0 ? _groupId : this.getGroupId();
36
+ if (this.canceledGroupIds.has(groupId)) {
37
+ return Promise.reject(new _SWError.SWError('CANCELED', 'Request has been canceled'));
38
+ }
39
+ return new Promise((resolve, reject) => {
40
+ this.requestMap[newId] = {
41
+ cacheKey: keyHash,
42
+ groupId,
43
+ id: newId,
44
+ ordinal,
45
+ reject,
46
+ resolve,
47
+ retry: -1,
48
+ run,
49
+ status: 'pending'
50
+ };
51
+ if (!this.isRunning) {
52
+ this.process();
53
+ }
54
+ });
55
+ }
56
+ process() {
57
+ this.stop();
58
+ this.isRunning = true;
59
+ const maxRetry = this.context.maxRetry;
60
+ const interval = setInterval(() => {
61
+ const remainingRequests = Object.values(this.requestMap);
62
+ if (remainingRequests.length === 0) {
63
+ this.isRunning = false;
64
+ clearInterval(interval);
65
+ return;
66
+ }
67
+ console.log('[ApiRequestStrategyV2] Processing requests...', remainingRequests.map(r => r.groupId));
68
+
69
+ // Get first this.limit requests base on id
70
+ const requests = remainingRequests.filter(request => request.status !== 'running').sort((a, b) => a.id - b.id).sort((a, b) => a.ordinal - b.ordinal).slice(0, this.context.callRate);
71
+
72
+ // Start requests
73
+ requests.forEach(request => {
74
+ request.status = 'running';
75
+ if (request.cacheKey) {
76
+ if (this.cacheMap.has(request.cacheKey)) {
77
+ const resp = this.cacheMap.get(request.cacheKey);
78
+ request.resolve(resp);
79
+ console.log('[ApiRequestStrategyV2] Cache hit for request', request.id, 'with cache key', request.cacheKey);
80
+ delete this.requestMap[request.id];
81
+ return;
82
+ }
83
+ }
84
+ request.run().then(rs => {
85
+ request.resolve(rs);
86
+ if (request.cacheKey) {
87
+ this.cacheMap.set(request.cacheKey, rs);
88
+ setTimeout(() => {
89
+ if (request.cacheKey) {
90
+ this.cacheMap.delete(request.cacheKey);
91
+ }
92
+ }, _constants.BASE_MINUTE_INTERVAL);
93
+ }
94
+ delete this.requestMap[request.id];
95
+ }).catch(e => {
96
+ const isRateLimited = this.isRateLimited(e);
97
+
98
+ // Limit rate
99
+ if (isRateLimited) {
100
+ if (request.retry < maxRetry) {
101
+ request.status = 'pending';
102
+ request.retry++;
103
+ this.context.reduceLimitRate();
104
+ } else {
105
+ // Reject request
106
+ request.reject(new _SWError.SWError('MAX_RETRY', String(e)));
107
+ }
108
+ } else {
109
+ request.reject(new _SWError.SWError('UNKNOWN', String(e)));
110
+ }
111
+ });
112
+ });
113
+ }, this.context.intervalCheck);
114
+ this.processInterval = interval;
115
+ }
116
+ stop() {
117
+ clearInterval(this.processInterval);
118
+ this.processInterval = undefined;
119
+ }
120
+ cancelGroupRequest(groupId) {
121
+ Object.values(this.requestMap).forEach(request => {
122
+ if (request.groupId === groupId) {
123
+ request.reject(new _SWError.SWError('CANCELED', 'Request has been canceled'));
124
+ }
125
+ this.canceledGroupIds.add(groupId);
126
+ });
127
+ this.requestMap = Object.fromEntries(Object.entries(this.requestMap).filter(_ref => {
128
+ let [_, request] = _ref;
129
+ return request.groupId !== groupId;
130
+ }));
131
+ }
132
+ setContext(context) {
133
+ this.stop();
134
+ this.context = context;
135
+ this.process();
136
+ }
137
+ }
138
+ exports.BaseApiRequestStrategyV2 = BaseApiRequestStrategyV2;
@@ -0,0 +1 @@
1
+ "use strict";
@@ -41,6 +41,7 @@ exports.StakingTxErrorType = StakingTxErrorType;
41
41
  StakingTxErrorType["INACTIVE_NOMINATION_POOL"] = "INACTIVE_NOMINATION_POOL";
42
42
  StakingTxErrorType["CAN_NOT_GET_METADATA"] = "CAN_NOT_GET_METADATA";
43
43
  StakingTxErrorType["NOT_ENOUGH_MIN_UNSTAKE"] = "NOT_ENOUGH_MIN_UNSTAKE";
44
+ StakingTxErrorType["REMAINING_AMOUNT_TOO_LOW"] = "REMAINING_AMOUNT_TOO_LOW";
44
45
  })(StakingTxErrorType || (exports.StakingTxErrorType = StakingTxErrorType = {}));
45
46
  let TransferTxErrorType;
46
47
  exports.TransferTxErrorType = TransferTxErrorType;
@@ -154,7 +154,7 @@ const BASE_TRANSFER_ACTIONS = [_KoniTypes.ExtrinsicType.TRANSFER_BALANCE, _KoniT
154
154
  const NATIVE_STAKE_ACTIONS = [_KoniTypes.ExtrinsicType.STAKING_BOND, _KoniTypes.ExtrinsicType.STAKING_UNBOND, _KoniTypes.ExtrinsicType.STAKING_WITHDRAW,
155
155
  // ExtrinsicType.STAKING_COMPOUNDING,
156
156
  // ExtrinsicType.STAKING_CANCEL_COMPOUNDING,
157
- _KoniTypes.ExtrinsicType.STAKING_CANCEL_UNSTAKE];
157
+ _KoniTypes.ExtrinsicType.STAKING_CANCEL_UNSTAKE, _KoniTypes.ExtrinsicType.CHANGE_EARNING_VALIDATOR];
158
158
  const POOL_STAKE_ACTIONS = [_KoniTypes.ExtrinsicType.STAKING_JOIN_POOL, _KoniTypes.ExtrinsicType.STAKING_LEAVE_POOL, _KoniTypes.ExtrinsicType.STAKING_POOL_WITHDRAW, _KoniTypes.ExtrinsicType.STAKING_CLAIM_REWARD, _KoniTypes.ExtrinsicType.JOIN_YIELD_POOL];
159
159
  const EARN_VDOT_ACTIONS = [_KoniTypes.ExtrinsicType.MINT_VDOT, _KoniTypes.ExtrinsicType.REDEEM_VDOT, _KoniTypes.ExtrinsicType.UNSTAKE_VDOT];
160
160
  const EARN_LDOT_ACTIONS = [_KoniTypes.ExtrinsicType.MINT_LDOT, _KoniTypes.ExtrinsicType.REDEEM_LDOT, _KoniTypes.ExtrinsicType.UNSTAKE_LDOT];
@@ -402,8 +402,9 @@ const convertAccountProxyType = accountSignMode => {
402
402
  return _types2.AccountProxyType.ALL_ACCOUNT;
403
403
  case _types2.AccountSignMode.UNKNOWN:
404
404
  return _types2.AccountProxyType.UNKNOWN;
405
+ default:
406
+ return _types2.AccountProxyType.UNKNOWN;
405
407
  }
406
- return _types2.AccountProxyType.UNKNOWN;
407
408
  };
408
409
  exports.convertAccountProxyType = convertAccountProxyType;
409
410
  const _combineAccounts = (accounts, modifyPairs, accountProxies) => {