@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
@@ -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
@@ -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";
@@ -55,6 +55,7 @@ exports.AccountSignMode = AccountSignMode;
55
55
  AccountSignMode["QR"] = "qr";
56
56
  AccountSignMode["LEGACY_LEDGER"] = "legacy-ledger";
57
57
  AccountSignMode["GENERIC_LEDGER"] = "generic-ledger";
58
+ AccountSignMode["ECDSA_SUBSTRATE_LEDGER"] = "ecdsa-substrate-ledger";
58
59
  AccountSignMode["READ_ONLY"] = "readonly";
59
60
  AccountSignMode["ALL_ACCOUNT"] = "all";
60
61
  AccountSignMode["INJECTED"] = "injected";
@@ -64,7 +64,7 @@ const _analyzeAddress = async (data, accountProxies, contacts, chainInfo, substr
64
64
  for (const accountProxy of accountProxies) {
65
65
  const _name = accountProxy.name.trim().toLowerCase();
66
66
  const nameCondition = isNameValid(_data, _name);
67
- const filterAccounts = accountProxy.accounts.filter(account => (0, _utils._isChainInfoCompatibleWithAccountInfo)(chainInfo, account.chainType, account.type));
67
+ const filterAccounts = accountProxy.accounts.filter(account => (0, _utils._isChainInfoCompatibleWithAccountInfo)(chainInfo, account));
68
68
  for (const account of filterAccounts) {
69
69
  const addressCondition = isStrValidWithAddress(_data, account, chainInfo);
70
70
  const condition = nameCondition !== 'invalid' ? nameCondition : addressCondition;
@@ -92,7 +92,10 @@ const _analyzeAddress = async (data, accountProxies, contacts, chainInfo, substr
92
92
  }
93
93
  }
94
94
  }
95
- const filterContacts = contacts.filter(contact => (0, _utils._isChainInfoCompatibleWithAccountInfo)(chainInfo, contact.chainType, (0, _keyring.getKeypairTypeByAddress)(contact.address)));
95
+ const filterContacts = contacts.filter(contact => (0, _utils._isChainInfoCompatibleWithAccountInfo)(chainInfo, {
96
+ chainType: contact.chainType,
97
+ type: (0, _keyring.getKeypairTypeByAddress)(contact.address)
98
+ }));
96
99
 
97
100
  // Filter address book addresses
98
101
  for (const contact of filterContacts) {
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getAccountChainTypeForAddress = exports._reformatAddressWithChain = void 0;
6
+ exports.getAccountJsonByAddress = exports.getAccountChainTypeForAddress = exports.filterAddressByChainInfo = exports._reformatAddressWithChain = void 0;
7
7
  exports.getAddressesByChainType = getAddressesByChainType;
8
8
  exports.getAddressesByChainTypeMap = getAddressesByChainTypeMap;
9
9
  exports.isAccountAll = isAccountAll;
@@ -16,6 +16,7 @@ var _types = require("@subwallet/extension-base/types");
16
16
  var _utils2 = require("@subwallet/extension-base/utils");
17
17
  var _keyring = require("@subwallet/keyring");
18
18
  var _validate = require("@subwallet/keyring/utils/address/validate");
19
+ var _uiKeyring = require("@subwallet/ui-keyring");
19
20
  var _utilCrypto = require("@polkadot/util-crypto");
20
21
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
21
22
  // SPDX-License-Identifier: Apache-2.0
@@ -141,4 +142,94 @@ const modifyAccountName = (type, name, modify) => {
141
142
  }
142
143
  return network ? [name, network].join(' - ') : name;
143
144
  };
144
- exports.modifyAccountName = modifyAccountName;
145
+
146
+ /**
147
+ * @function getAccountJsonByAddress
148
+ * @desc Get account info by address
149
+ * <p>
150
+ * Note: Use on the background only
151
+ * </p>
152
+ * @param {string} address - Address
153
+ * @returns {AccountJson|null} - Account info or null if not found
154
+ */
155
+ exports.modifyAccountName = modifyAccountName;
156
+ const getAccountJsonByAddress = address => {
157
+ try {
158
+ const pair = _uiKeyring.keyring.getPair(address);
159
+ if (pair) {
160
+ return (0, _utils2.pairToAccount)(pair);
161
+ } else {
162
+ return null;
163
+ }
164
+ } catch (e) {
165
+ console.warn(e);
166
+ return null;
167
+ }
168
+ };
169
+
170
+ /** Filter addresses to subscribe by chain info */
171
+ exports.getAccountJsonByAddress = getAccountJsonByAddress;
172
+ const filterAddressByChainInfo = (addresses, chainInfo) => {
173
+ const {
174
+ _bitcoin,
175
+ bitcoin,
176
+ cardano,
177
+ evm,
178
+ substrate,
179
+ ton
180
+ } = getAddressesByChainTypeMap(addresses, chainInfo);
181
+ if ((0, _utils._isChainEvmCompatible)(chainInfo)) {
182
+ const [fetchList, unFetchList] = processEvmAndSubstrateAddresses(evm, chainInfo);
183
+ return [fetchList, [...unFetchList, ...bitcoin, ...ton, ...substrate, ...cardano, ..._bitcoin].flat()];
184
+ } else if ((0, _utils._isChainBitcoinCompatible)(chainInfo)) {
185
+ return [bitcoin, [...evm, ...substrate, ...ton, ...cardano, ..._bitcoin].flat()];
186
+ } else if ((0, _utils._isChainTonCompatible)(chainInfo)) {
187
+ return [ton, [...bitcoin, ...evm, ...substrate, ...cardano, ..._bitcoin].flat()];
188
+ } else if ((0, _utils._isChainCardanoCompatible)(chainInfo)) {
189
+ return [cardano, [...bitcoin, ...evm, ...substrate, ...ton, ..._bitcoin].flat()];
190
+ } else {
191
+ const [fetchList, unFetchList] = processEvmAndSubstrateAddresses(substrate, chainInfo);
192
+ return [fetchList, [...unFetchList, ...bitcoin, ...evm, ...ton, ...cardano, ..._bitcoin].flat()];
193
+ }
194
+ };
195
+ exports.filterAddressByChainInfo = filterAddressByChainInfo;
196
+ const processEvmAndSubstrateAddresses = (addressList, chainInfo) => {
197
+ const fetchList = [];
198
+ const unFetchList = [];
199
+ const isEvm = (0, _utilCrypto.isEthereumAddress)(addressList[0]);
200
+ addressList.forEach(address => {
201
+ const account = getAccountJsonByAddress(address);
202
+ if (account) {
203
+ if (account.isHardware) {
204
+ if (isEvm) {
205
+ if (account.isGeneric && account.isSubstrateECDSA) {
206
+ if ((0, _utils._isSubstrateEvmCompatibleChain)(chainInfo)) {
207
+ fetchList.push(address);
208
+ } else {
209
+ unFetchList.push(address);
210
+ }
211
+ } else {
212
+ fetchList.push(address);
213
+ }
214
+ } else {
215
+ if (account.isGeneric) {
216
+ fetchList.push(address);
217
+ } else {
218
+ const availGen = account.availableGenesisHashes || [];
219
+ const gen = (0, _utils._getSubstrateGenesisHash)(chainInfo);
220
+ if (availGen.includes(gen)) {
221
+ fetchList.push(address);
222
+ } else {
223
+ unFetchList.push(address);
224
+ }
225
+ }
226
+ }
227
+ } else {
228
+ fetchList.push(address);
229
+ }
230
+ } else {
231
+ fetchList.push(address);
232
+ }
233
+ });
234
+ return [fetchList, unFetchList];
235
+ };
@@ -71,6 +71,9 @@ const getAccountSignMode = (address, _meta) => {
71
71
  if (meta.isExternal) {
72
72
  if (meta.isHardware) {
73
73
  if (meta.isGeneric) {
74
+ if (meta.isSubstrateECDSA) {
75
+ return _types2.AccountSignMode.ECDSA_SUBSTRATE_LEDGER;
76
+ }
74
77
  return _types2.AccountSignMode.GENERIC_LEDGER;
75
78
  } else {
76
79
  return _types2.AccountSignMode.LEGACY_LEDGER;
@@ -244,6 +247,11 @@ const getAccountTransactionActions = (signMode, networkType, type, _meta, _speci
244
247
  result.push(...CLAIM_AVAIL_BRIDGE);
245
248
  }
246
249
  return result;
250
+ } else if (signMode === _types2.AccountSignMode.ECDSA_SUBSTRATE_LEDGER) {
251
+ // Only for account substrate with ECDSA scheme format
252
+ const result = [];
253
+ result.push(...BASE_TRANSFER_ACTIONS, ...NATIVE_STAKE_ACTIONS, ...POOL_STAKE_ACTIONS, _KoniTypes.ExtrinsicType.TRANSFER_XCM, _KoniTypes.ExtrinsicType.SWAP, _KoniTypes.ExtrinsicType.CROWDLOAN);
254
+ return result;
247
255
  }
248
256
  return [];
249
257
  };
@@ -380,6 +388,7 @@ const convertAccountProxyType = accountSignMode => {
380
388
  switch (accountSignMode) {
381
389
  case _types2.AccountSignMode.GENERIC_LEDGER:
382
390
  case _types2.AccountSignMode.LEGACY_LEDGER:
391
+ case _types2.AccountSignMode.ECDSA_SUBSTRATE_LEDGER:
383
392
  return _types2.AccountProxyType.LEDGER;
384
393
  case _types2.AccountSignMode.QR:
385
394
  return _types2.AccountProxyType.QR;
@@ -490,6 +499,7 @@ const _combineAccounts = (accounts, modifyPairs, accountProxies) => {
490
499
  switch (account.signMode) {
491
500
  case _types2.AccountSignMode.GENERIC_LEDGER:
492
501
  case _types2.AccountSignMode.LEGACY_LEDGER:
502
+ case _types2.AccountSignMode.ECDSA_SUBSTRATE_LEDGER:
493
503
  specialChain = account.specialChain;
494
504
  break;
495
505
  }
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.filterAssetsByChainAndType = exports.filterAlphaAssetsByChain = void 0;
6
+ exports.isSubstrateEcdsaLedgerAssetSupported = exports.filterAssetsByChainAndType = exports.filterAlphaAssetsByChain = void 0;
7
7
  var _types = require("@subwallet/chain-list/types");
8
8
  var _utils = require("@subwallet/extension-base/services/chain-service/utils");
9
9
  // Copyright 2019-2022 @subwallet/extension-base
@@ -31,4 +31,11 @@ const filterAlphaAssetsByChain = (chainAssetMap, chain) => {
31
31
  });
32
32
  return result;
33
33
  };
34
- exports.filterAlphaAssetsByChain = filterAlphaAssetsByChain;
34
+ exports.filterAlphaAssetsByChain = filterAlphaAssetsByChain;
35
+ const isSubstrateEcdsaLedgerAssetSupported = (chainsAsset, chainInfo) => {
36
+ if (!(0, _utils._isSubstrateEvmCompatibleChain)(chainInfo)) {
37
+ return false;
38
+ }
39
+ return (0, _utils._isNativeToken)(chainsAsset) || !(0, _utils._getContractAddressOfToken)(chainsAsset);
40
+ };
41
+ exports.isSubstrateEcdsaLedgerAssetSupported = isSubstrateEcdsaLedgerAssetSupported;
@@ -22,7 +22,8 @@ function getGRC20ContractPromise(apiPromise, contractAddress) {
22
22
  const gearApi = apiPromise;
23
23
  return new _grc.GRC20(gearApi, contractAddress);
24
24
  }
25
- function getVFTContractPromise(apiPromise, contractAddress) {
26
- const gearApi = apiPromise;
27
- return new _vft.VFT(gearApi, contractAddress);
25
+ function getVFTContractPromise(api) {
26
+ let contractAddress = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '0x';
27
+ const sails = _vft.sailsCache.get();
28
+ return new _vft.VFT(api, contractAddress, sails);
28
29
  }