@subwallet/extension-base 1.3.46-0 → 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.
- package/cjs/koni/api/nft/ordinal_nft/index.js +3 -2
- package/cjs/koni/background/handlers/State.js +3 -0
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +8 -14
- package/cjs/services/buy-service/index.js +2 -0
- package/cjs/services/chain-service/utils/index.js +3 -0
- package/cjs/services/chain-service/utils/patch.js +1 -1
- package/cjs/services/earning-service/handlers/native-staking/amplitude.js +32 -0
- package/cjs/services/earning-service/handlers/native-staking/astar.js +18 -0
- package/cjs/services/earning-service/handlers/native-staking/base.js +37 -29
- package/cjs/services/earning-service/handlers/native-staking/dtao.js +5 -0
- package/cjs/services/earning-service/handlers/native-staking/mythos.js +28 -0
- package/cjs/services/earning-service/handlers/native-staking/para-chain.js +17 -0
- package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +16 -0
- package/cjs/services/earning-service/handlers/native-staking/tao.js +5 -0
- package/cjs/services/earning-service/service.js +26 -5
- package/cjs/services/history-service/index.js +12 -7
- package/cjs/services/subscan-service/index.js +35 -104
- package/cjs/services/transaction-service/utils.js +10 -1
- package/cjs/strategy/api-request-strategy/index.js +1 -0
- package/cjs/strategy/api-request-strategy/utils/index.js +2 -2
- package/cjs/strategy/api-request-strategy-v2/index.js +138 -0
- package/cjs/strategy/api-request-strategy-v2/types.js +1 -0
- package/cjs/utils/gear/combine.js +4 -3
- package/cjs/utils/gear/vft.js +104 -135
- package/koni/api/nft/ordinal_nft/index.js +3 -2
- package/koni/background/handlers/State.js +4 -1
- package/package.json +20 -9
- package/packageInfo.js +1 -1
- package/services/balance-service/helpers/subscribe/substrate/index.js +8 -14
- package/services/buy-service/index.js +2 -0
- package/services/chain-service/utils/index.js +3 -0
- package/services/chain-service/utils/patch.js +1 -1
- package/services/earning-service/handlers/native-staking/amplitude.d.ts +1 -0
- package/services/earning-service/handlers/native-staking/amplitude.js +32 -0
- package/services/earning-service/handlers/native-staking/astar.d.ts +1 -0
- package/services/earning-service/handlers/native-staking/astar.js +18 -0
- package/services/earning-service/handlers/native-staking/base.d.ts +1 -0
- package/services/earning-service/handlers/native-staking/base.js +37 -29
- package/services/earning-service/handlers/native-staking/dtao.d.ts +1 -0
- package/services/earning-service/handlers/native-staking/dtao.js +5 -0
- package/services/earning-service/handlers/native-staking/mythos.d.ts +1 -0
- package/services/earning-service/handlers/native-staking/mythos.js +28 -0
- package/services/earning-service/handlers/native-staking/para-chain.d.ts +1 -0
- package/services/earning-service/handlers/native-staking/para-chain.js +17 -0
- package/services/earning-service/handlers/native-staking/relay-chain.d.ts +1 -0
- package/services/earning-service/handlers/native-staking/relay-chain.js +16 -0
- package/services/earning-service/handlers/native-staking/tao.d.ts +1 -0
- package/services/earning-service/handlers/native-staking/tao.js +5 -0
- package/services/earning-service/service.d.ts +1 -0
- package/services/earning-service/service.js +26 -5
- package/services/history-service/index.js +12 -7
- package/services/subscan-service/index.d.ts +13 -27
- package/services/subscan-service/index.js +26 -95
- package/services/transaction-service/utils.js +11 -2
- package/strategy/api-request-strategy/context/base.d.ts +2 -6
- package/strategy/api-request-strategy/index.js +1 -0
- package/strategy/api-request-strategy/types.d.ts +4 -2
- package/strategy/api-request-strategy/utils/index.js +2 -2
- package/strategy/api-request-strategy-v2/index.d.ts +22 -0
- package/strategy/api-request-strategy-v2/index.js +128 -0
- package/strategy/api-request-strategy-v2/types.d.ts +11 -0
- package/strategy/api-request-strategy-v2/types.js +1 -0
- package/types/buy.d.ts +1 -1
- package/utils/gear/combine.d.ts +2 -1
- package/utils/gear/combine.js +4 -4
- package/utils/gear/vft.d.ts +20 -9
- package/utils/gear/vft.js +104 -135
|
@@ -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
|
-
|
|
59
|
-
const
|
|
60
|
-
return
|
|
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 >
|
|
152
|
-
let blockRange = arguments.length >
|
|
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 >
|
|
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 >
|
|
229
|
-
let direction = arguments.length >
|
|
230
|
-
let blockRange = arguments.length >
|
|
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 >
|
|
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 >
|
|
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 >
|
|
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';
|
|
@@ -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
|
|
25
|
-
const _url = `${url}?${
|
|
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";
|
|
@@ -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(
|
|
26
|
-
|
|
27
|
-
|
|
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
|
}
|