@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
@@ -1,44 +1,30 @@
1
- import { CrowdloanContributionsResponse, ExtrinsicItem, ExtrinsicsListResponse, IMultiChainBalance, RequestBlockRange, RewardHistoryListResponse, SubscanRequest, TransferItem, TransfersListResponse } from '@subwallet/extension-base/services/subscan-service/types';
1
+ import { CrowdloanContributionsResponse, ExtrinsicItem, ExtrinsicsListResponse, IMultiChainBalance, RequestBlockRange, RewardHistoryListResponse, TransferItem, TransfersListResponse } from '@subwallet/extension-base/services/subscan-service/types';
2
+ import { ApiRequestContextProps } from '@subwallet/extension-base/strategy/api-request-strategy/types';
3
+ import { BaseApiRequestStrategyV2 } from '@subwallet/extension-base/strategy/api-request-strategy-v2';
2
4
  import { SubscanEventBaseItemData, SubscanExtrinsicParam } from '@subwallet/extension-base/types';
3
- export declare class SubscanService {
5
+ export declare class SubscanService extends BaseApiRequestStrategyV2 {
4
6
  private subscanChainMap;
5
- private callRate;
6
- private limitRate;
7
- private intervalCheck;
8
- private maxRetry;
9
- private rollbackRateTime;
10
- private timeoutRollbackRate;
11
- private requestMap;
12
- private nextId;
13
- private isRunning;
14
- private getId;
15
- constructor(subscanChainMap: Record<string, string>, options?: {
16
- limitRate?: number;
17
- intervalCheck?: number;
18
- maxRetry?: number;
19
- });
20
- private reduceLimitRate;
7
+ constructor(subscanChainMap: Record<string, string>, options?: Partial<ApiRequestContextProps>);
21
8
  private getApiUrl;
22
9
  private postRequest;
23
- addRequest<T>(run: SubscanRequest<T>['run'], ordinal: number): Promise<T>;
24
- private process;
10
+ isRateLimited(e: Error): boolean;
25
11
  checkSupportedSubscanChain(chain: string): boolean;
26
12
  setSubscanChainMap(subscanChainMap: Record<string, string>): void;
27
13
  getMultiChainBalance(address: string): Promise<IMultiChainBalance[]>;
28
14
  getCrowdloanContributions(relayChain: string, address: string, page?: number): Promise<CrowdloanContributionsResponse>;
29
- getExtrinsicsList(chain: string, address: string, page?: number, blockRange?: RequestBlockRange): Promise<ExtrinsicsListResponse>;
30
- fetchAllPossibleExtrinsicItems(chain: string, address: string, cbAfterEachRequest?: (items: ExtrinsicItem[]) => void, limit?: {
15
+ getExtrinsicsList(groupId: number, chain: string, address: string, page?: number, blockRange?: RequestBlockRange): Promise<ExtrinsicsListResponse>;
16
+ fetchAllPossibleExtrinsicItems(groupId: number, chain: string, address: string, cbAfterEachRequest?: (items: ExtrinsicItem[]) => void, limit?: {
31
17
  page: number;
32
18
  record: number;
33
19
  }): Promise<ExtrinsicItem[]>;
34
- getTransfersList(chain: string, address: string, page?: number, direction?: 'sent' | 'received', blockRange?: RequestBlockRange): Promise<TransfersListResponse>;
35
- fetchAllPossibleTransferItems(chain: string, address: string, direction?: 'sent' | 'received', cbAfterEachRequest?: (items: TransferItem[]) => void, limit?: {
20
+ getTransfersList(groupId: number, chain: string, address: string, page?: number, direction?: 'sent' | 'received', blockRange?: RequestBlockRange): Promise<TransfersListResponse>;
21
+ fetchAllPossibleTransferItems(groupId: number, chain: string, address: string, direction?: 'sent' | 'received', cbAfterEachRequest?: (items: TransferItem[]) => void, limit?: {
36
22
  page: number;
37
23
  record: number;
38
24
  }): Promise<Record<string, TransferItem[]>>;
39
- getRewardHistoryList(chain: string, address: string, page?: number): Promise<RewardHistoryListResponse>;
40
- getAccountRemarkEvents(chain: string, address: string): Promise<SubscanEventBaseItemData[]>;
41
- getExtrinsicParams(chain: string, extrinsicIndexes: string[], ordinal?: number): Promise<SubscanExtrinsicParam[]>;
25
+ getRewardHistoryList(groupId: number, chain: string, address: string, page?: number): Promise<RewardHistoryListResponse>;
26
+ getAccountRemarkEvents(groupId: number, chain: string, address: string): Promise<SubscanEventBaseItemData[]>;
27
+ getExtrinsicParams(groupId: number, chain: string, extrinsicIndexes: string[], ordinal?: number): Promise<SubscanExtrinsicParam[]>;
42
28
  private static _instance;
43
29
  static getInstance(): SubscanService;
44
30
  }
@@ -4,34 +4,15 @@
4
4
  import { SWError } from '@subwallet/extension-base/background/errors/SWError';
5
5
  import { BASE_FETCH_ORDINAL_EVENT_DATA } from '@subwallet/extension-base/koni/api/nft/ordinal_nft/constants';
6
6
  import { SUBSCAN_API_CHAIN_MAP } from '@subwallet/extension-base/services/subscan-service/subscan-chain-map';
7
+ import { BaseApiRequestContext } from '@subwallet/extension-base/strategy/api-request-strategy/context/base';
8
+ import { BaseApiRequestStrategyV2 } from '@subwallet/extension-base/strategy/api-request-strategy-v2';
7
9
  import { wait } from '@subwallet/extension-base/utils';
8
10
  const QUERY_ROW = 100;
9
- export class SubscanService {
10
- callRate = 2; // limit per interval check
11
- limitRate = 2; // max rate per interval check
12
- intervalCheck = 1000; // interval check in ms
13
- maxRetry = 9; // interval check in ms
14
- rollbackRateTime = 30 * 1000; // rollback rate time in ms
15
- timeoutRollbackRate = undefined;
16
- requestMap = {};
17
- nextId = 0;
18
- isRunning = false;
19
- getId() {
20
- return this.nextId++;
21
- }
11
+ export class SubscanService extends BaseApiRequestStrategyV2 {
22
12
  constructor(subscanChainMap, options) {
13
+ const context = new BaseApiRequestContext(options);
14
+ super(context);
23
15
  this.subscanChainMap = subscanChainMap;
24
- this.callRate = (options === null || options === void 0 ? void 0 : options.limitRate) || this.callRate;
25
- this.limitRate = (options === null || options === void 0 ? void 0 : options.limitRate) || this.limitRate;
26
- this.intervalCheck = (options === null || options === void 0 ? void 0 : options.intervalCheck) || this.intervalCheck;
27
- this.maxRetry = (options === null || options === void 0 ? void 0 : options.maxRetry) || this.maxRetry;
28
- }
29
- reduceLimitRate() {
30
- clearTimeout(this.timeoutRollbackRate);
31
- this.callRate = Math.ceil(this.limitRate / 2);
32
- this.timeoutRollbackRate = setTimeout(() => {
33
- this.callRate = this.limitRate;
34
- }, this.rollbackRateTime);
35
16
  }
36
17
  getApiUrl(chain, path) {
37
18
  const subscanChain = this.subscanChainMap[chain];
@@ -49,61 +30,9 @@ export class SubscanService {
49
30
  body: JSON.stringify(body)
50
31
  });
51
32
  }
52
- addRequest(run, ordinal) {
53
- const newId = this.getId();
54
- return new Promise((resolve, reject) => {
55
- this.requestMap[newId] = {
56
- id: newId,
57
- status: 'pending',
58
- retry: -1,
59
- ordinal,
60
- run,
61
- resolve,
62
- reject
63
- };
64
- if (!this.isRunning) {
65
- this.process();
66
- }
67
- });
68
- }
69
- process() {
70
- this.isRunning = true;
71
- const maxRetry = this.maxRetry;
72
- const interval = setInterval(() => {
73
- const remainingRequests = Object.values(this.requestMap);
74
- if (remainingRequests.length === 0) {
75
- this.isRunning = false;
76
- clearInterval(interval);
77
- return;
78
- }
79
-
80
- // Get first this.limit requests base on id
81
- 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);
82
-
83
- // Start requests
84
- requests.forEach(request => {
85
- request.status = 'running';
86
- request.run().then(rs => {
87
- request.resolve(rs);
88
- }).catch(e => {
89
- const error = JSON.parse(e.message);
90
-
91
- // Limit rate
92
- if (error.code === 20008) {
93
- if (request.retry < maxRetry) {
94
- request.status = 'pending';
95
- request.retry++;
96
- this.reduceLimitRate();
97
- } else {
98
- // Reject request
99
- request.reject(new SWError('MAX_RETRY', String(e)));
100
- }
101
- } else {
102
- request.reject(new SWError('UNKNOWN', String(e)));
103
- }
104
- });
105
- });
106
- }, this.intervalCheck);
33
+ isRateLimited(e) {
34
+ const error = JSON.parse(e.message);
35
+ return error.code === 20008;
107
36
  }
108
37
  checkSupportedSubscanChain(chain) {
109
38
  return !!this.subscanChainMap[chain];
@@ -114,6 +43,7 @@ export class SubscanService {
114
43
 
115
44
  // Implement Subscan API
116
45
  getMultiChainBalance(address) {
46
+ const hashKey = this.createKeyHash(['multi_chain_balance', address]);
117
47
  return this.addRequest(async () => {
118
48
  const rs = await this.postRequest(this.getApiUrl('polkadot', 'api/scan/multiChain/account'), {
119
49
  address
@@ -123,7 +53,7 @@ export class SubscanService {
123
53
  }
124
54
  const jsonData = await rs.json();
125
55
  return jsonData.data;
126
- }, 1);
56
+ }, 1, undefined, hashKey);
127
57
  }
128
58
  getCrowdloanContributions(relayChain, address, page = 0) {
129
59
  return this.addRequest(async () => {
@@ -140,7 +70,7 @@ export class SubscanService {
140
70
  return jsonData.data;
141
71
  }, 2);
142
72
  }
143
- getExtrinsicsList(chain, address, page = 0, blockRange) {
73
+ getExtrinsicsList(groupId, chain, address, page = 0, blockRange) {
144
74
  const _blockRange = (() => {
145
75
  if (!blockRange || !blockRange.to) {
146
76
  return null;
@@ -159,9 +89,9 @@ export class SubscanService {
159
89
  }
160
90
  const jsonData = await rs.json();
161
91
  return jsonData.data;
162
- }, 0);
92
+ }, 0, groupId);
163
93
  }
164
- async fetchAllPossibleExtrinsicItems(chain, address, cbAfterEachRequest, limit = {
94
+ async fetchAllPossibleExtrinsicItems(groupId, chain, address, cbAfterEachRequest, limit = {
165
95
  page: 10,
166
96
  record: 1000
167
97
  }) {
@@ -173,7 +103,7 @@ export class SubscanService {
173
103
  };
174
104
  const resultMap = {};
175
105
  const _getExtrinsicItems = async page => {
176
- const res = await this.getExtrinsicsList(chain, address, page, blockRange);
106
+ const res = await this.getExtrinsicsList(groupId, chain, address, page, blockRange);
177
107
  if (!res || !res.count || !res.extrinsics || !res.extrinsics.length) {
178
108
  return;
179
109
  }
@@ -182,7 +112,7 @@ export class SubscanService {
182
112
  }
183
113
  const extrinsics = res.extrinsics;
184
114
  const extrinsicIndexes = extrinsics.map(item => item.extrinsic_index);
185
- const extrinsicParams = await this.getExtrinsicParams(chain, extrinsicIndexes, 0);
115
+ const extrinsicParams = await this.getExtrinsicParams(groupId, chain, extrinsicIndexes, 0);
186
116
  for (const data of extrinsicParams) {
187
117
  const {
188
118
  extrinsic_index: extrinsicIndex,
@@ -214,7 +144,7 @@ export class SubscanService {
214
144
  await _getExtrinsicItems(0);
215
145
  return Object.values(resultMap);
216
146
  }
217
- getTransfersList(chain, address, page = 0, direction, blockRange) {
147
+ getTransfersList(groupId, chain, address, page = 0, direction, blockRange) {
218
148
  return this.addRequest(async () => {
219
149
  const rs = await this.postRequest(this.getApiUrl(chain, 'api/v2/scan/transfers'), {
220
150
  page,
@@ -229,9 +159,9 @@ export class SubscanService {
229
159
  }
230
160
  const jsonData = await rs.json();
231
161
  return jsonData.data;
232
- }, 0);
162
+ }, 0, groupId);
233
163
  }
234
- async fetchAllPossibleTransferItems(chain, address, direction, cbAfterEachRequest, limit = {
164
+ async fetchAllPossibleTransferItems(groupId, chain, address, direction, cbAfterEachRequest, limit = {
235
165
  page: 10,
236
166
  record: 1000
237
167
  }) {
@@ -243,7 +173,7 @@ export class SubscanService {
243
173
  };
244
174
  const resultMap = {};
245
175
  const _getTransferItems = async page => {
246
- const res = await this.getTransfersList(chain, address, page, direction, blockRange);
176
+ const res = await this.getTransfersList(groupId, chain, address, page, direction, blockRange);
247
177
  if (!res || !res.count || !res.transfers || !res.transfers.length) {
248
178
  return;
249
179
  }
@@ -273,7 +203,8 @@ export class SubscanService {
273
203
  await _getTransferItems(0);
274
204
  return resultMap;
275
205
  }
276
- getRewardHistoryList(chain, address, page = 0) {
206
+ getRewardHistoryList(groupId, chain, address, page = 0) {
207
+ const hashKey = this.createKeyHash([chain, 'reward_slash', address, page]);
277
208
  return this.addRequest(async () => {
278
209
  const rs = await this.postRequest(this.getApiUrl(chain, 'api/scan/account/reward_slash'), {
279
210
  page,
@@ -293,9 +224,9 @@ export class SubscanService {
293
224
  };
294
225
  }
295
226
  return jsonData.data;
296
- }, 2);
227
+ }, 2, groupId, hashKey);
297
228
  }
298
- getAccountRemarkEvents(chain, address) {
229
+ getAccountRemarkEvents(groupId, chain, address) {
299
230
  return this.addRequest(async () => {
300
231
  const rs = await this.postRequest(this.getApiUrl(chain, 'api/v2/scan/events'), {
301
232
  ...BASE_FETCH_ORDINAL_EVENT_DATA,
@@ -306,9 +237,9 @@ export class SubscanService {
306
237
  }
307
238
  const jsonData = await rs.json();
308
239
  return jsonData.data.events;
309
- }, 3);
240
+ }, 3, groupId);
310
241
  }
311
- getExtrinsicParams(chain, extrinsicIndexes, ordinal = 3) {
242
+ getExtrinsicParams(groupId, chain, extrinsicIndexes, ordinal = 3) {
312
243
  return this.addRequest(async () => {
313
244
  const rs = await this.postRequest(this.getApiUrl(chain, 'api/scan/extrinsic/params'), {
314
245
  extrinsic_index: extrinsicIndexes
@@ -318,7 +249,7 @@ export class SubscanService {
318
249
  }
319
250
  const jsonData = await rs.json();
320
251
  return jsonData.data;
321
- }, ordinal);
252
+ }, ordinal, groupId);
322
253
  }
323
254
 
324
255
  // Singleton
@@ -60,6 +60,8 @@ const typeName = type => {
60
60
  return 'Withdraw pool';
61
61
  case ExtrinsicType.JOIN_YIELD_POOL:
62
62
  return 'Start earning';
63
+ case ExtrinsicType.CHANGE_EARNING_VALIDATOR:
64
+ return 'Change validator';
63
65
  case ExtrinsicType.UNKNOWN:
64
66
  default:
65
67
  return 'unknown';
@@ -909,6 +909,21 @@ export default class TransactionService {
909
909
  };
910
910
  break;
911
911
  }
912
+ case ExtrinsicType.CHANGE_EARNING_VALIDATOR:
913
+ {
914
+ var _data$metadata;
915
+ const data = parseTransactionData(transaction.data);
916
+ historyItem.additionalInfo = {
917
+ symbol: ((_data$metadata = data.metadata) === null || _data$metadata === void 0 ? void 0 : _data$metadata.subnetSymbol) || ''
918
+ };
919
+ if (data.amount !== '0') {
920
+ historyItem.amount = {
921
+ ...baseNativeAmount,
922
+ value: data.amount
923
+ };
924
+ }
925
+ break;
926
+ }
912
927
  case ExtrinsicType.EVM_EXECUTE:
913
928
  {
914
929
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
@@ -1,7 +1,7 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { _getBlockExplorerFromChain, _isChainTestNet, _isPureBitcoinChain, _isPureCardanoChain, _isPureEvmChain } from '@subwallet/extension-base/services/chain-service/utils';
4
+ import { _getBlockExplorerFromChain, _isChainTestNet, _isPureBitcoinChain, _isPureCardanoChain, _isPureEvmChain, _isPureTonChain } from '@subwallet/extension-base/services/chain-service/utils';
5
5
  import { CHAIN_FLIP_MAINNET_EXPLORER, CHAIN_FLIP_TESTNET_EXPLORER, SIMPLE_SWAP_EXPLORER } from '@subwallet/extension-base/services/swap-service/utils';
6
6
  import { hexAddPrefix, isHex, u8aToHex } from '@polkadot/util';
7
7
  import { decodeAddress } from '@polkadot/util-crypto';
@@ -37,13 +37,19 @@ function getBlockExplorerAccountRoute(explorerLink) {
37
37
  if (explorerLink.includes('taostats.io')) {
38
38
  return 'account';
39
39
  }
40
+ if (explorerLink.includes('tonviewer.com')) {
41
+ return '';
42
+ }
43
+ if (explorerLink.includes('devnet-explorer.mosaicchain.io')) {
44
+ return 'accounts';
45
+ }
40
46
  return 'address';
41
47
  }
42
48
  function getBlockExplorerTxRoute(chainInfo) {
43
49
  if (_isPureEvmChain(chainInfo) || _isPureBitcoinChain(chainInfo)) {
44
50
  return 'tx';
45
51
  }
46
- if (_isPureCardanoChain(chainInfo)) {
52
+ if (_isPureCardanoChain(chainInfo) || _isPureTonChain(chainInfo)) {
47
53
  return 'transaction';
48
54
  }
49
55
  if (['aventus', 'deeper_network'].includes(chainInfo.slug)) {
@@ -52,6 +58,9 @@ function getBlockExplorerTxRoute(chainInfo) {
52
58
  if (['gen6_public'].includes(chainInfo.slug)) {
53
59
  return '#/extrinsics';
54
60
  }
61
+ if (['mosaicTest'].includes(chainInfo.slug)) {
62
+ return 'transactions';
63
+ }
55
64
  const explorerLink = _getBlockExplorerFromChain(chainInfo);
56
65
  if (explorerLink && explorerLink.includes('statescan.io')) {
57
66
  return '#/extrinsics';
@@ -1,4 +1,4 @@
1
- import { ApiRequestContext } from '@subwallet/extension-base/strategy/api-request-strategy/types';
1
+ import { ApiRequestContext, ApiRequestContextProps } from '@subwallet/extension-base/strategy/api-request-strategy/types';
2
2
  export declare class BaseApiRequestContext implements ApiRequestContext {
3
3
  callRate: number;
4
4
  limitRate: number;
@@ -6,10 +6,6 @@ export declare class BaseApiRequestContext implements ApiRequestContext {
6
6
  maxRetry: number;
7
7
  private rollbackRateTime;
8
8
  private timeoutRollbackRate;
9
- constructor(options?: {
10
- limitRate?: number;
11
- intervalCheck?: number;
12
- maxRetry?: number;
13
- });
9
+ constructor(options?: Partial<ApiRequestContextProps>);
14
10
  reduceLimitRate(): void;
15
11
  }
@@ -50,6 +50,7 @@ export class BaseApiRequestStrategy {
50
50
  request.status = 'running';
51
51
  request.run().then(rs => {
52
52
  request.resolve(rs);
53
+ delete this.requestMap[request.id];
53
54
  }).catch(e => {
54
55
  const isRateLimited = this.isRateLimited(e);
55
56
 
@@ -1,8 +1,10 @@
1
- export interface ApiRequestContext {
2
- callRate: number;
1
+ export interface ApiRequestContextProps {
3
2
  limitRate: number;
4
3
  intervalCheck: number;
5
4
  maxRetry: number;
5
+ }
6
+ export interface ApiRequestContext extends ApiRequestContextProps {
7
+ callRate: number;
6
8
  reduceLimitRate: () => void;
7
9
  }
8
10
  export interface ApiRequestStrategy {
@@ -12,8 +12,8 @@ export const postRequest = (url, body, headers, jsonBody = true) => {
12
12
  });
13
13
  };
14
14
  export const getRequest = (url, params, headers) => {
15
- const queryString = params ? Object.keys(params).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`).join('&') : '';
16
- const _url = `${url}?${queryString}`;
15
+ const q = new URLSearchParams(params);
16
+ const _url = `${url}?${q.toString()}`;
17
17
  return fetch(_url, {
18
18
  method: 'GET',
19
19
  headers: headers || {
@@ -0,0 +1,22 @@
1
+ import { ApiRequestContext } from '../api-request-strategy/types';
2
+ import { ApiRequestStrategyV2, ApiRequestV2 } from './types';
3
+ export declare abstract class BaseApiRequestStrategyV2 implements ApiRequestStrategyV2 {
4
+ private nextId;
5
+ private groupId;
6
+ private isRunning;
7
+ private requestMap;
8
+ private context;
9
+ private processInterval;
10
+ private canceledGroupIds;
11
+ private cacheMap;
12
+ private getId;
13
+ protected constructor(context: ApiRequestContext);
14
+ getGroupId(): number;
15
+ createKeyHash(keys: Array<string | number>): string;
16
+ addRequest<T>(run: ApiRequestV2<T>['run'], ordinal: number, _groupId?: number, keyHash?: string): Promise<T>;
17
+ abstract isRateLimited(error: Error): boolean;
18
+ private process;
19
+ stop(): void;
20
+ cancelGroupRequest(groupId: number): void;
21
+ setContext(context: ApiRequestContext): void;
22
+ }
@@ -0,0 +1,128 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { SWError } from '@subwallet/extension-base/background/errors/SWError';
5
+ import { BASE_MINUTE_INTERVAL } from '@subwallet/extension-base/constants';
6
+ import { Md5 } from 'ts-md5';
7
+ export class BaseApiRequestStrategyV2 {
8
+ nextId = 0;
9
+ groupId = 0;
10
+ isRunning = false;
11
+ requestMap = {};
12
+ processInterval = undefined;
13
+ canceledGroupIds = new Set();
14
+ cacheMap = new Map();
15
+ getId() {
16
+ return this.nextId++;
17
+ }
18
+ constructor(context) {
19
+ this.context = context;
20
+ }
21
+ getGroupId() {
22
+ return this.groupId++;
23
+ }
24
+ createKeyHash(keys) {
25
+ return Md5.hashStr(JSON.stringify([this.constructor.name, ...keys]));
26
+ }
27
+ addRequest(run, ordinal, _groupId, keyHash) {
28
+ const newId = this.getId();
29
+ const groupId = _groupId !== null && _groupId !== void 0 ? _groupId : this.getGroupId();
30
+ if (this.canceledGroupIds.has(groupId)) {
31
+ return Promise.reject(new SWError('CANCELED', 'Request has been canceled'));
32
+ }
33
+ return new Promise((resolve, reject) => {
34
+ this.requestMap[newId] = {
35
+ cacheKey: keyHash,
36
+ groupId,
37
+ id: newId,
38
+ ordinal,
39
+ reject,
40
+ resolve,
41
+ retry: -1,
42
+ run,
43
+ status: 'pending'
44
+ };
45
+ if (!this.isRunning) {
46
+ this.process();
47
+ }
48
+ });
49
+ }
50
+ process() {
51
+ this.stop();
52
+ this.isRunning = true;
53
+ const maxRetry = this.context.maxRetry;
54
+ const interval = setInterval(() => {
55
+ const remainingRequests = Object.values(this.requestMap);
56
+ if (remainingRequests.length === 0) {
57
+ this.isRunning = false;
58
+ clearInterval(interval);
59
+ return;
60
+ }
61
+ console.log('[ApiRequestStrategyV2] Processing requests...', remainingRequests.map(r => r.groupId));
62
+
63
+ // Get first this.limit requests base on id
64
+ 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);
65
+
66
+ // Start requests
67
+ requests.forEach(request => {
68
+ request.status = 'running';
69
+ if (request.cacheKey) {
70
+ if (this.cacheMap.has(request.cacheKey)) {
71
+ const resp = this.cacheMap.get(request.cacheKey);
72
+ request.resolve(resp);
73
+ console.log('[ApiRequestStrategyV2] Cache hit for request', request.id, 'with cache key', request.cacheKey);
74
+ delete this.requestMap[request.id];
75
+ return;
76
+ }
77
+ }
78
+ request.run().then(rs => {
79
+ request.resolve(rs);
80
+ if (request.cacheKey) {
81
+ this.cacheMap.set(request.cacheKey, rs);
82
+ setTimeout(() => {
83
+ if (request.cacheKey) {
84
+ this.cacheMap.delete(request.cacheKey);
85
+ }
86
+ }, BASE_MINUTE_INTERVAL);
87
+ }
88
+ delete this.requestMap[request.id];
89
+ }).catch(e => {
90
+ const isRateLimited = this.isRateLimited(e);
91
+
92
+ // Limit rate
93
+ if (isRateLimited) {
94
+ if (request.retry < maxRetry) {
95
+ request.status = 'pending';
96
+ request.retry++;
97
+ this.context.reduceLimitRate();
98
+ } else {
99
+ // Reject request
100
+ request.reject(new SWError('MAX_RETRY', String(e)));
101
+ }
102
+ } else {
103
+ request.reject(new SWError('UNKNOWN', String(e)));
104
+ }
105
+ });
106
+ });
107
+ }, this.context.intervalCheck);
108
+ this.processInterval = interval;
109
+ }
110
+ stop() {
111
+ clearInterval(this.processInterval);
112
+ this.processInterval = undefined;
113
+ }
114
+ cancelGroupRequest(groupId) {
115
+ Object.values(this.requestMap).forEach(request => {
116
+ if (request.groupId === groupId) {
117
+ request.reject(new SWError('CANCELED', 'Request has been canceled'));
118
+ }
119
+ this.canceledGroupIds.add(groupId);
120
+ });
121
+ this.requestMap = Object.fromEntries(Object.entries(this.requestMap).filter(([_, request]) => request.groupId !== groupId));
122
+ }
123
+ setContext(context) {
124
+ this.stop();
125
+ this.context = context;
126
+ this.process();
127
+ }
128
+ }
@@ -0,0 +1,11 @@
1
+ import { ApiRequest, ApiRequestContext } from '../api-request-strategy/types';
2
+ export interface ApiRequestStrategyV2 {
3
+ addRequest: <T>(run: ApiRequestV2<T>['run'], groupId: number, ordinal: number) => Promise<T>;
4
+ setContext: (context: ApiRequestContext) => void;
5
+ stop: (groupId?: number) => void;
6
+ cancelGroupRequest: (groupId: number) => void;
7
+ }
8
+ export interface ApiRequestV2<T> extends ApiRequest<T> {
9
+ groupId: number;
10
+ cacheKey?: string;
11
+ }
@@ -0,0 +1 @@
1
+ export {};
package/types/buy.d.ts CHANGED
@@ -4,7 +4,7 @@ export interface BuyService {
4
4
  symbol: string;
5
5
  }
6
6
  export declare type SupportService = 'transak' | 'banxa' | 'coinbase' | 'moonpay' | 'onramper' | 'meld';
7
- export declare type OnrampAccountSupportType = 'ETHEREUM' | 'SUBSTRATE' | 'TON' | 'CARDANO';
7
+ export declare type OnrampAccountSupportType = 'ETHEREUM' | 'SUBSTRATE' | 'TON' | 'CARDANO' | 'BITCOIN';
8
8
  export interface BuyTokenInfo {
9
9
  network: string;
10
10
  symbol: string;
@@ -27,7 +27,8 @@ export declare enum StakingTxErrorType {
27
27
  EXCEED_MAX_UNSTAKING = "EXCEED_MAX_UNSTAKING",
28
28
  INACTIVE_NOMINATION_POOL = "INACTIVE_NOMINATION_POOL",
29
29
  CAN_NOT_GET_METADATA = "CAN_NOT_GET_METADATA",
30
- NOT_ENOUGH_MIN_UNSTAKE = "NOT_ENOUGH_MIN_UNSTAKE"
30
+ NOT_ENOUGH_MIN_UNSTAKE = "NOT_ENOUGH_MIN_UNSTAKE",
31
+ REMAINING_AMOUNT_TOO_LOW = "REMAINING_AMOUNT_TOO_LOW"
31
32
  }
32
33
  export declare enum TransferTxErrorType {
33
34
  NOT_ENOUGH_VALUE = "NOT_ENOUGH_VALUE",
@@ -33,6 +33,7 @@ export let StakingTxErrorType;
33
33
  StakingTxErrorType["INACTIVE_NOMINATION_POOL"] = "INACTIVE_NOMINATION_POOL";
34
34
  StakingTxErrorType["CAN_NOT_GET_METADATA"] = "CAN_NOT_GET_METADATA";
35
35
  StakingTxErrorType["NOT_ENOUGH_MIN_UNSTAKE"] = "NOT_ENOUGH_MIN_UNSTAKE";
36
+ StakingTxErrorType["REMAINING_AMOUNT_TOO_LOW"] = "REMAINING_AMOUNT_TOO_LOW";
36
37
  })(StakingTxErrorType || (StakingTxErrorType = {}));
37
38
  export let TransferTxErrorType;
38
39
  (function (TransferTxErrorType) {
@@ -20,7 +20,7 @@ export interface SubmitJoinNativeStaking extends AbstractSubmitYieldJoinData {
20
20
  mindBond: string;
21
21
  };
22
22
  selectedValidators: ValidatorInfo[];
23
- subnetData: {
23
+ subnetData?: {
24
24
  netuid: number;
25
25
  slippage: number;
26
26
  };
@@ -81,3 +81,12 @@ export interface BondingSubmitParams extends BaseRequestSign {
81
81
  lockPeriod?: number;
82
82
  }
83
83
  export declare type RequestBondingSubmit = InternalRequestSign<BondingSubmitParams>;
84
+ export declare type SubmitChangeValidatorStaking = SubmitBittensorChangeValidatorStaking | SubmitJoinNativeStaking;
85
+ export interface SubmitBittensorChangeValidatorStaking extends SubmitJoinNativeStaking {
86
+ originValidator: string;
87
+ maxAmount: string;
88
+ isMovePartialStake: boolean;
89
+ metadata: {
90
+ subnetSymbol: string;
91
+ };
92
+ }
@@ -41,6 +41,8 @@ export interface YieldPoolMethodInfo {
41
41
  withdraw: boolean;
42
42
  /** Pool can claim reward */
43
43
  claimReward: boolean;
44
+ /** Pool can change validator */
45
+ changeValidator: boolean;
44
46
  }
45
47
  /**
46
48
  * @interface YieldThresholdInfo
@@ -143,7 +143,7 @@ const BASE_TRANSFER_ACTIONS = [ExtrinsicType.TRANSFER_BALANCE, ExtrinsicType.TRA
143
143
  const NATIVE_STAKE_ACTIONS = [ExtrinsicType.STAKING_BOND, ExtrinsicType.STAKING_UNBOND, ExtrinsicType.STAKING_WITHDRAW,
144
144
  // ExtrinsicType.STAKING_COMPOUNDING,
145
145
  // ExtrinsicType.STAKING_CANCEL_COMPOUNDING,
146
- ExtrinsicType.STAKING_CANCEL_UNSTAKE];
146
+ ExtrinsicType.STAKING_CANCEL_UNSTAKE, ExtrinsicType.CHANGE_EARNING_VALIDATOR];
147
147
  const POOL_STAKE_ACTIONS = [ExtrinsicType.STAKING_JOIN_POOL, ExtrinsicType.STAKING_LEAVE_POOL, ExtrinsicType.STAKING_POOL_WITHDRAW, ExtrinsicType.STAKING_CLAIM_REWARD, ExtrinsicType.JOIN_YIELD_POOL];
148
148
  const EARN_VDOT_ACTIONS = [ExtrinsicType.MINT_VDOT, ExtrinsicType.REDEEM_VDOT, ExtrinsicType.UNSTAKE_VDOT];
149
149
  const EARN_LDOT_ACTIONS = [ExtrinsicType.MINT_LDOT, ExtrinsicType.REDEEM_LDOT, ExtrinsicType.UNSTAKE_LDOT];
@@ -374,8 +374,9 @@ export const convertAccountProxyType = accountSignMode => {
374
374
  return AccountProxyType.ALL_ACCOUNT;
375
375
  case AccountSignMode.UNKNOWN:
376
376
  return AccountProxyType.UNKNOWN;
377
+ default:
378
+ return AccountProxyType.UNKNOWN;
377
379
  }
378
- return AccountProxyType.UNKNOWN;
379
380
  };
380
381
  export const _combineAccounts = (accounts, modifyPairs, accountProxies) => {
381
382
  const temp = {};