@subwallet/extension-base 1.3.16-0 → 1.3.18-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 (137) hide show
  1. package/background/KoniTypes.d.ts +12 -2
  2. package/cjs/constants/index.js +6 -3
  3. package/cjs/core/logic-validation/request.js +26 -19
  4. package/cjs/core/logic-validation/transfer.js +18 -17
  5. package/cjs/koni/api/contract-handler/evm/web3.js +3 -3
  6. package/cjs/koni/api/staking/bonding/utils.js +1 -1
  7. package/cjs/koni/background/handlers/Extension.js +289 -124
  8. package/cjs/koni/background/handlers/State.js +1 -8
  9. package/cjs/packageInfo.js +1 -1
  10. package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +14 -2
  11. package/cjs/services/balance-service/index.js +13 -0
  12. package/cjs/services/balance-service/transfer/smart-contract.js +47 -33
  13. package/cjs/services/balance-service/transfer/token.js +5 -4
  14. package/cjs/services/balance-service/transfer/xcm/availBridge.js +14 -18
  15. package/cjs/services/balance-service/transfer/xcm/index.js +30 -61
  16. package/cjs/services/balance-service/transfer/xcm/polygonBridge.js +13 -17
  17. package/cjs/services/balance-service/transfer/xcm/posBridge.js +20 -21
  18. package/cjs/services/balance-service/transfer/xcm/snowBridge.js +7 -7
  19. package/cjs/services/balance-service/transfer/xcm/utils.js +2 -2
  20. package/cjs/services/chain-service/constants.js +3 -3
  21. package/cjs/services/chain-service/index.js +22 -0
  22. package/cjs/services/earning-service/handlers/liquid-staking/stella-swap.js +7 -12
  23. package/cjs/services/earning-service/handlers/native-staking/tao.js +121 -30
  24. package/cjs/services/earning-service/handlers/nomination-pool/index.js +1 -1
  25. package/cjs/services/earning-service/handlers/special.js +34 -14
  26. package/cjs/services/fee-service/interfaces.js +1 -0
  27. package/cjs/services/fee-service/service.js +111 -0
  28. package/cjs/services/fee-service/utils/index.js +99 -113
  29. package/cjs/services/storage-service/db-stores/Balance.js +3 -0
  30. package/cjs/services/swap-service/handler/asset-hub/handler.js +21 -6
  31. package/cjs/services/swap-service/handler/asset-hub/router.js +1 -1
  32. package/cjs/services/swap-service/handler/asset-hub/utils.js +4 -4
  33. package/cjs/services/swap-service/handler/base-handler.js +2 -0
  34. package/cjs/services/swap-service/handler/chainflip-handler.js +25 -4
  35. package/cjs/services/swap-service/handler/hydradx-handler.js +20 -6
  36. package/cjs/services/swap-service/handler/simpleswap-handler.js +23 -3
  37. package/cjs/services/swap-service/index.js +8 -8
  38. package/cjs/services/transaction-service/index.js +23 -3
  39. package/cjs/types/balance/transfer.js +1 -0
  40. package/cjs/types/fee/base.js +1 -0
  41. package/cjs/types/fee/evm.js +16 -1
  42. package/cjs/types/fee/index.js +37 -4
  43. package/cjs/types/fee/option.js +1 -0
  44. package/cjs/types/fee/subscription.js +1 -0
  45. package/cjs/types/fee/substrate.js +1 -0
  46. package/cjs/types/fee/ton.js +1 -0
  47. package/cjs/utils/fee/combine.js +50 -0
  48. package/cjs/utils/fee/index.js +27 -0
  49. package/cjs/utils/fee/transfer.js +374 -0
  50. package/cjs/utils/index.js +12 -0
  51. package/constants/index.d.ts +1 -0
  52. package/constants/index.js +1 -0
  53. package/core/logic-validation/request.js +17 -10
  54. package/core/logic-validation/transfer.d.ts +5 -5
  55. package/core/logic-validation/transfer.js +20 -19
  56. package/core/substrate/xcm-parser.d.ts +1 -1
  57. package/koni/api/contract-handler/evm/web3.js +3 -3
  58. package/koni/api/staking/bonding/utils.js +1 -1
  59. package/koni/background/handlers/Extension.d.ts +4 -3
  60. package/koni/background/handlers/Extension.js +273 -108
  61. package/koni/background/handlers/State.js +1 -8
  62. package/package.json +55 -5
  63. package/packageInfo.js +1 -1
  64. package/services/balance-service/helpers/subscribe/substrate/index.js +14 -2
  65. package/services/balance-service/index.d.ts +1 -0
  66. package/services/balance-service/index.js +13 -0
  67. package/services/balance-service/transfer/smart-contract.d.ts +24 -4
  68. package/services/balance-service/transfer/smart-contract.js +45 -33
  69. package/services/balance-service/transfer/token.js +6 -5
  70. package/services/balance-service/transfer/xcm/availBridge.d.ts +3 -2
  71. package/services/balance-service/transfer/xcm/availBridge.js +11 -15
  72. package/services/balance-service/transfer/xcm/index.d.ts +12 -11
  73. package/services/balance-service/transfer/xcm/index.js +29 -58
  74. package/services/balance-service/transfer/xcm/polygonBridge.d.ts +4 -3
  75. package/services/balance-service/transfer/xcm/polygonBridge.js +13 -17
  76. package/services/balance-service/transfer/xcm/posBridge.d.ts +4 -3
  77. package/services/balance-service/transfer/xcm/posBridge.js +18 -19
  78. package/services/balance-service/transfer/xcm/snowBridge.d.ts +2 -1
  79. package/services/balance-service/transfer/xcm/snowBridge.js +7 -7
  80. package/services/balance-service/transfer/xcm/utils.js +2 -2
  81. package/services/chain-service/constants.js +3 -3
  82. package/services/chain-service/index.d.ts +6 -1
  83. package/services/chain-service/index.js +22 -0
  84. package/services/earning-service/handlers/liquid-staking/stella-swap.js +7 -12
  85. package/services/earning-service/handlers/native-staking/tao.d.ts +7 -2
  86. package/services/earning-service/handlers/native-staking/tao.js +119 -29
  87. package/services/earning-service/handlers/nomination-pool/index.js +1 -1
  88. package/services/earning-service/handlers/special.js +36 -16
  89. package/services/fee-service/interfaces.d.ts +5 -0
  90. package/services/fee-service/interfaces.js +1 -0
  91. package/services/fee-service/service.d.ts +4 -1
  92. package/services/fee-service/service.js +111 -0
  93. package/services/fee-service/utils/index.d.ts +8 -2
  94. package/services/fee-service/utils/index.js +92 -108
  95. package/services/storage-service/db-stores/Balance.d.ts +1 -0
  96. package/services/storage-service/db-stores/Balance.js +3 -0
  97. package/services/swap-service/handler/asset-hub/handler.d.ts +2 -1
  98. package/services/swap-service/handler/asset-hub/handler.js +21 -6
  99. package/services/swap-service/handler/asset-hub/router.js +2 -2
  100. package/services/swap-service/handler/asset-hub/utils.d.ts +1 -1
  101. package/services/swap-service/handler/asset-hub/utils.js +2 -2
  102. package/services/swap-service/handler/base-handler.d.ts +4 -1
  103. package/services/swap-service/handler/base-handler.js +2 -0
  104. package/services/swap-service/handler/chainflip-handler.d.ts +2 -1
  105. package/services/swap-service/handler/chainflip-handler.js +24 -3
  106. package/services/swap-service/handler/hydradx-handler.d.ts +2 -1
  107. package/services/swap-service/handler/hydradx-handler.js +19 -5
  108. package/services/swap-service/handler/simpleswap-handler.d.ts +2 -1
  109. package/services/swap-service/handler/simpleswap-handler.js +23 -3
  110. package/services/swap-service/index.js +8 -8
  111. package/services/transaction-service/index.js +23 -3
  112. package/services/transaction-service/types.d.ts +5 -4
  113. package/types/balance/transfer.d.ts +25 -0
  114. package/types/balance/transfer.js +1 -0
  115. package/types/fee/base.d.ts +8 -0
  116. package/types/fee/base.js +1 -0
  117. package/types/fee/evm.d.ts +46 -16
  118. package/types/fee/evm.js +10 -1
  119. package/types/fee/index.d.ts +4 -1
  120. package/types/fee/index.js +4 -1
  121. package/types/fee/option.d.ts +8 -0
  122. package/types/fee/option.js +1 -0
  123. package/types/fee/subscription.d.ts +12 -0
  124. package/types/fee/subscription.js +1 -0
  125. package/types/fee/substrate.d.ts +15 -0
  126. package/types/fee/substrate.js +1 -0
  127. package/types/fee/ton.d.ts +18 -0
  128. package/types/fee/ton.js +1 -0
  129. package/types/transaction/request.d.ts +13 -3
  130. package/utils/fee/combine.d.ts +12 -0
  131. package/utils/fee/combine.js +42 -0
  132. package/utils/fee/index.d.ts +2 -0
  133. package/utils/fee/index.js +5 -0
  134. package/utils/fee/transfer.d.ts +22 -0
  135. package/utils/fee/transfer.js +363 -0
  136. package/utils/index.d.ts +1 -0
  137. package/utils/index.js +1 -0
@@ -7,6 +7,7 @@ import { getERC20Contract, getERC20SpendingApprovalTx } from '@subwallet/extensi
7
7
  import { _getAssetDecimals, _getContractAddressOfToken } from '@subwallet/extension-base/services/chain-service/utils';
8
8
  import { calculateGasFeeParams } from '@subwallet/extension-base/services/fee-service/utils';
9
9
  import { BasicTxErrorType, EarningStatus, UnstakingStatus, YieldStepType } from '@subwallet/extension-base/types';
10
+ import { combineEthFee } from '@subwallet/extension-base/utils';
10
11
  import { BN, BN_TEN, BN_ZERO } from '@polkadot/util';
11
12
  import { ST_LIQUID_TOKEN_ABI } from "../../constants/index.js";
12
13
  import BaseLiquidStakingPoolHandler from "./base.js";
@@ -271,7 +272,6 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
271
272
  });
272
273
  }
273
274
  async handleSubmitStep(data, path) {
274
- var _priority$maxFeePerGa, _priority$maxPriority;
275
275
  const {
276
276
  address,
277
277
  amount
@@ -291,14 +291,13 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
291
291
  from: address
292
292
  });
293
293
  const priority = await calculateGasFeeParams(evmApi, this.chain);
294
+ const feeCombine = combineEthFee(priority);
294
295
  const transactionObject = {
295
296
  from: address,
296
297
  to: _getContractAddressOfToken(derivativeTokenInfo),
297
298
  data: depositEncodedCall,
298
299
  gas: gasLimit,
299
- gasPrice: priority.gasPrice,
300
- maxFeePerGas: (_priority$maxFeePerGa = priority.maxFeePerGas) === null || _priority$maxFeePerGa === void 0 ? void 0 : _priority$maxFeePerGa.toString(),
301
- maxPriorityFeePerGas: (_priority$maxPriority = priority.maxPriorityFeePerGas) === null || _priority$maxPriority === void 0 ? void 0 : _priority$maxPriority.toString()
300
+ ...feeCombine
302
301
  };
303
302
  return {
304
303
  txChain: this.chain,
@@ -318,7 +317,6 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
318
317
  return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
319
318
  }
320
319
  async handleYieldUnstake(amount, address, selectedTarget) {
321
- var _priority$maxFeePerGa2, _priority$maxPriority2;
322
320
  const evmApi = this.evmApi;
323
321
  const derivativeTokenSlug = this.derivativeAssets[0];
324
322
  const derivativeTokenInfo = this.state.getAssetBySlug(derivativeTokenSlug);
@@ -334,14 +332,13 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
334
332
  from: address
335
333
  });
336
334
  const priority = await calculateGasFeeParams(evmApi, this.chain);
335
+ const feeCombine = combineEthFee(priority);
337
336
  const transaction = {
338
337
  from: address,
339
338
  to: _getContractAddressOfToken(derivativeTokenInfo),
340
339
  data: redeemEncodedCall,
341
340
  gas: gasLimit,
342
- gasPrice: priority.gasPrice,
343
- maxFeePerGas: (_priority$maxFeePerGa2 = priority.maxFeePerGas) === null || _priority$maxFeePerGa2 === void 0 ? void 0 : _priority$maxFeePerGa2.toString(),
344
- maxPriorityFeePerGas: (_priority$maxPriority2 = priority.maxPriorityFeePerGas) === null || _priority$maxPriority2 === void 0 ? void 0 : _priority$maxPriority2.toString()
341
+ ...feeCombine
345
342
  };
346
343
  return [ExtrinsicType.UNSTAKE_STDOT, transaction];
347
344
  }
@@ -351,7 +348,6 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
351
348
  /* Other actions */
352
349
 
353
350
  async handleYieldWithdraw(address, unstakingInfo) {
354
- var _priority$maxFeePerGa3, _priority$maxPriority3;
355
351
  const evmApi = this.evmApi;
356
352
  const derivativeTokenSlug = this.derivativeAssets[0];
357
353
  const derivativeTokenInfo = this.state.getAssetBySlug(derivativeTokenSlug);
@@ -367,14 +363,13 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
367
363
  from: address
368
364
  });
369
365
  const priority = await calculateGasFeeParams(evmApi, this.chain);
366
+ const feeCombine = combineEthFee(priority);
370
367
  return {
371
368
  from: address,
372
369
  to: _getContractAddressOfToken(derivativeTokenInfo),
373
370
  data: withdrawEncodedCall,
374
371
  gas: gasLimit,
375
- gasPrice: priority.gasPrice,
376
- maxFeePerGas: (_priority$maxFeePerGa3 = priority.maxFeePerGas) === null || _priority$maxFeePerGa3 === void 0 ? void 0 : _priority$maxFeePerGa3.toString(),
377
- maxPriorityFeePerGas: (_priority$maxPriority3 = priority.maxPriorityFeePerGas) === null || _priority$maxPriority3 === void 0 ? void 0 : _priority$maxPriority3.toString()
372
+ ...feeCombine
378
373
  }; // TODO: check tx history parsing
379
374
  }
380
375
 
@@ -1,11 +1,16 @@
1
1
  import { _ChainInfo } from '@subwallet/chain-list/types';
2
2
  import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
3
+ import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
3
4
  import BaseParaStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/native-staking/base-para';
4
5
  import { BaseYieldPositionInfo, StakeCancelWithdrawalParams, SubmitJoinNativeStaking, TransactionData, UnstakingInfo, ValidatorInfo, YieldPoolInfo, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
6
+ export interface TaoStakeInfo {
7
+ hotkey: string;
8
+ stake: string;
9
+ netuid: number;
10
+ }
5
11
  interface TaoStakingStakeOption {
6
12
  owner: string;
7
13
  amount: string;
8
- identity: string;
9
14
  }
10
15
  export interface RawDelegateState {
11
16
  data: Array<{
@@ -30,6 +35,7 @@ interface Validator {
30
35
  take: string;
31
36
  apr: string;
32
37
  }
38
+ export declare const getTaoToAlphaMapping: (substrateApi: _SubstrateApi) => Promise<Record<number, string>>;
33
39
  export declare const BITTENSOR_API_KEY_1: string;
34
40
  export declare const BITTENSOR_API_KEY_2: string;
35
41
  export declare const BITTENSOR_API_KEY_3: string;
@@ -42,7 +48,6 @@ export declare const BITTENSOR_API_KEY_9: string;
42
48
  export declare const BITTENSOR_API_KEY_10: string;
43
49
  export declare const bittensorApiKey: () => string;
44
50
  export declare function fetchDelegates(): Promise<ValidatorResponse>;
45
- export declare function fetchTaoDelegateState(address: string): Promise<RawDelegateState>;
46
51
  export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHandler {
47
52
  handleYieldWithdraw(address: string, unstakingInfo: UnstakingInfo): Promise<TransactionData>;
48
53
  handleYieldCancelUnstake(params: StakeCancelWithdrawalParams): Promise<TransactionData>;
@@ -11,6 +11,25 @@ import { reformatAddress } from '@subwallet/extension-base/utils';
11
11
  import BigN from 'bignumber.js';
12
12
  import { BN, BN_TEN, BN_ZERO } from '@polkadot/util';
13
13
  import { calculateReward } from "../../utils/index.js";
14
+ export const getTaoToAlphaMapping = async substrateApi => {
15
+ const allSubnets = (await substrateApi.api.call.subnetInfoRuntimeApi.getAllDynamicInfo()).toJSON();
16
+ if (!allSubnets) {
17
+ return {};
18
+ }
19
+ return allSubnets.reduce((acc, subnet) => {
20
+ const netuid = subnet === null || subnet === void 0 ? void 0 : subnet.netuid;
21
+ const taoIn = subnet !== null && subnet !== void 0 && subnet.taoIn ? new BigN(subnet.taoIn) : new BigN(0);
22
+ const alphaIn = subnet !== null && subnet !== void 0 && subnet.alphaIn ? new BigN(subnet.alphaIn) : new BigN(0);
23
+ if (netuid === 0) {
24
+ acc[netuid] = '1';
25
+ } else if (alphaIn.gt(0)) {
26
+ acc[netuid] = taoIn.dividedBy(alphaIn).toString();
27
+ } else {
28
+ acc[netuid] = '1';
29
+ }
30
+ return acc;
31
+ }, {});
32
+ };
14
33
  export const BITTENSOR_API_KEY_1 = process.env.BITTENSOR_API_KEY_1 || '';
15
34
  export const BITTENSOR_API_KEY_2 = process.env.BITTENSOR_API_KEY_2 || '';
16
35
  export const BITTENSOR_API_KEY_3 = process.env.BITTENSOR_API_KEY_3 || '';
@@ -27,7 +46,7 @@ function random(...keys) {
27
46
  return validKeys[randomIndex];
28
47
  }
29
48
  export const bittensorApiKey = () => {
30
- return random(BITTENSOR_API_KEY_1, BITTENSOR_API_KEY_2, BITTENSOR_API_KEY_3, BITTENSOR_API_KEY_4, BITTENSOR_API_KEY_5, BITTENSOR_API_KEY_6);
49
+ return random(BITTENSOR_API_KEY_1, BITTENSOR_API_KEY_2, BITTENSOR_API_KEY_3, BITTENSOR_API_KEY_4, BITTENSOR_API_KEY_5, BITTENSOR_API_KEY_6, BITTENSOR_API_KEY_7, BITTENSOR_API_KEY_8, BITTENSOR_API_KEY_9, BITTENSOR_API_KEY_10);
31
50
  };
32
51
 
33
52
  /* Fetch data */
@@ -46,20 +65,22 @@ export async function fetchDelegates() {
46
65
  }).catch(console.error);
47
66
  });
48
67
  }
49
- export async function fetchTaoDelegateState(address) {
50
- const apiKey = bittensorApiKey();
51
- return new Promise(function (resolve) {
52
- fetch(`https://api.taostats.io/api/stake_balance/latest/v1?coldkey=${address}`, {
53
- method: 'GET',
54
- headers: {
55
- 'Content-Type': 'application/json',
56
- Authorization: `${apiKey}`
57
- }
58
- }).then(resp => {
59
- resolve(resp.json());
60
- }).catch(console.error);
61
- });
62
- }
68
+
69
+ // export async function fetchTaoDelegateState (address: string): Promise<RawDelegateState> {
70
+ // const apiKey = bittensorApiKey();
71
+
72
+ // return new Promise(function (resolve) {
73
+ // fetch(`https://api.taostats.io/api/stake_balance/latest/v1?coldkey=${address}`, {
74
+ // method: 'GET',
75
+ // headers: {
76
+ // 'Content-Type': 'application/json',
77
+ // Authorization: `${apiKey}`
78
+ // }
79
+ // }).then((resp) => {
80
+ // resolve(resp.json());
81
+ // }).catch(console.error);
82
+ // });
83
+ // }
63
84
 
64
85
  /* Fetch data */
65
86
 
@@ -160,11 +181,12 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
160
181
  chain: chainInfo.slug,
161
182
  validatorAddress: delegate.owner,
162
183
  activeStake: activeStake,
163
- validatorMinStake: minDelegatorStake,
164
- validatorIdentity: delegate.identity
184
+ validatorMinStake: minDelegatorStake
185
+ // validatorIdentity: delegate.identity
165
186
  });
166
187
  }
167
188
  }
189
+
168
190
  const stakingStatus = getEarningStatusByNominations(allActiveStake, nominationList);
169
191
  return {
170
192
  status: stakingStatus,
@@ -192,9 +214,10 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
192
214
  bnTotalBalance = bnTotalBalance.add(bnStakeAmount);
193
215
  delegatorState.push({
194
216
  owner: testnetAddress,
195
- amount: bnStakeAmount.toString(),
196
- identity: testnetAddress
217
+ amount: bnStakeAmount.toString()
218
+ // identity: testnetAddress
197
219
  });
220
+
198
221
  rsCallback({
199
222
  ...defaultInfo,
200
223
  type: this.type,
@@ -217,20 +240,32 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
217
240
  await Promise.all(stakePromises);
218
241
  };
219
242
  const getMainnetPoolPosition = async () => {
220
- const rawDelegateStateInfos = await Promise.all(useAddresses.map(address => fetchTaoDelegateState(address)));
221
- if (rawDelegateStateInfos.length > 0) {
243
+ const rawDelegateStateInfos = await Promise.all(useAddresses.map(async address => (await substrateApi.api.call.stakeInfoRuntimeApi.getStakeInfoForColdkey(address)).toJSON()));
244
+ const price = await getTaoToAlphaMapping(this.substrateApi);
245
+ if (rawDelegateStateInfos && rawDelegateStateInfos.length > 0) {
222
246
  rawDelegateStateInfos.forEach((rawDelegateStateInfo, i) => {
223
247
  const owner = reformatAddress(useAddresses[i], 42);
224
248
  const delegatorState = [];
225
249
  let bnTotalBalance = BN_ZERO;
226
- const delegateStateInfo = rawDelegateStateInfo.data;
250
+ const delegateStateInfo = rawDelegateStateInfo;
251
+ const totalDelegate = {};
227
252
  for (const delegate of delegateStateInfo) {
228
- const name = delegate.hotkey_name || delegate.hotkey.ss58;
229
- bnTotalBalance = bnTotalBalance.add(new BN(delegate.stake));
253
+ const hotkey = delegate.hotkey;
254
+ const netuid = delegate.netuid;
255
+ const stake = new BigN(delegate.stake);
256
+ const taoToAlphaPrice = price[netuid] ? new BigN(price[netuid]) : new BigN(1);
257
+ const taoStake = stake.multipliedBy(taoToAlphaPrice).toFixed(0).toString();
258
+ if (totalDelegate[hotkey]) {
259
+ totalDelegate[hotkey] = new BigN(totalDelegate[hotkey]).plus(taoStake).toString();
260
+ } else {
261
+ totalDelegate[hotkey] = taoStake;
262
+ }
263
+ }
264
+ for (const hotkey in totalDelegate) {
265
+ bnTotalBalance = bnTotalBalance.add(new BN(totalDelegate[hotkey]));
230
266
  delegatorState.push({
231
- owner: delegate.hotkey.ss58,
232
- amount: delegate.stake,
233
- identity: name
267
+ owner: hotkey,
268
+ amount: totalDelegate[hotkey]
234
269
  });
235
270
  }
236
271
  if (delegateStateInfo && delegateStateInfo.length > 0) {
@@ -260,6 +295,61 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
260
295
  });
261
296
  }
262
297
  };
298
+
299
+ // const getMainnetPoolPosition = async () => {
300
+ // const rawDelegateStateInfos = await Promise.all(
301
+ // useAddresses.map((address) => fetchTaoDelegateState(address))
302
+ // );
303
+
304
+ // if (rawDelegateStateInfos.length > 0) {
305
+ // rawDelegateStateInfos.forEach((rawDelegateStateInfo, i) => {
306
+ // const owner = reformatAddress(useAddresses[i], 42);
307
+ // const delegatorState: TaoStakingStakeOption[] = [];
308
+ // let bnTotalBalance = BN_ZERO;
309
+ // const delegateStateInfo = rawDelegateStateInfo.data;
310
+
311
+ // for (const delegate of delegateStateInfo) {
312
+ // const name = delegate.hotkey_name || delegate.hotkey.ss58;
313
+
314
+ // bnTotalBalance = bnTotalBalance.add(new BN(delegate.stake));
315
+
316
+ // delegatorState.push({
317
+ // owner: delegate.hotkey.ss58,
318
+ // amount: delegate.stake,
319
+ // identity: name
320
+ // });
321
+ // }
322
+
323
+ // if (delegateStateInfo && delegateStateInfo.length > 0) {
324
+ // this.parseNominatorMetadata(chainInfo, owner, delegatorState)
325
+ // .then((nominatorMetadata) => {
326
+ // rsCallback({
327
+ // ...defaultInfo,
328
+ // ...nominatorMetadata,
329
+ // address: owner,
330
+ // type: this.type
331
+ // });
332
+ // })
333
+ // .catch(console.error);
334
+ // } else {
335
+ // rsCallback({
336
+ // ...defaultInfo,
337
+ // type: this.type,
338
+ // address: owner,
339
+ // balanceToken: this.nativeToken.slug,
340
+ // totalStake: '0',
341
+ // activeStake: '0',
342
+ // unstakeBalance: '0',
343
+ // status: EarningStatus.NOT_STAKING,
344
+ // isBondedBefore: false,
345
+ // nominations: [],
346
+ // unstakings: []
347
+ // });
348
+ // }
349
+ // });
350
+ // }
351
+ // };
352
+
263
353
  const getStakingPositionInterval = async () => {
264
354
  if (cancel) {
265
355
  return;
@@ -364,7 +454,7 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
364
454
  const binaryAmount = new BN(amount);
365
455
  const selectedValidatorInfo = targetValidators[0];
366
456
  const hotkey = selectedValidatorInfo.address;
367
- const extrinsic = chainApi.api.tx.subtensorModule.addStake(hotkey, binaryAmount);
457
+ const extrinsic = chainApi.api.tx.subtensorModule.addStake(hotkey, 0, binaryAmount);
368
458
  return [extrinsic, {
369
459
  slug: this.nativeToken.slug,
370
460
  amount: '0'
@@ -382,7 +472,7 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
382
472
  if (!selectedTarget || !poolPosition) {
383
473
  return Promise.reject(new TransactionError(BasicTxErrorType.INVALID_PARAMS));
384
474
  }
385
- const extrinsic = apiPromise.api.tx.subtensorModule.removeStake(selectedTarget, binaryAmount);
475
+ const extrinsic = apiPromise.api.tx.subtensorModule.removeStake(selectedTarget, 0, binaryAmount);
386
476
  return [ExtrinsicType.STAKING_UNBOND, extrinsic];
387
477
  }
388
478
 
@@ -83,7 +83,7 @@ export default class NominationPoolHandler extends BasePoolHandler {
83
83
 
84
84
  const supportedDays = getSupportedDaysByHistoryDepth(erasPerDay, parseInt(maxSupportedEras), parseInt(currentEra) / erasPerDay);
85
85
  const startEra = parseInt(currentEra) - supportedDays * erasPerDay;
86
- const [_maxPoolMember, _EraStakeInfo, _totalIssuance, _auctionCounter, _minPoolJoin, ..._eraReward] = await Promise.all([(_substrateApi$api$que2 = substrateApi.api.query.nominationPools) === null || _substrateApi$api$que2 === void 0 ? void 0 : _substrateApi$api$que2.maxPoolMembersPerPool(), substrateApi.api.query.staking.erasTotalStake.multi([parseInt(currentEra), parseInt(currentEra) - 1]), substrateApi.api.query.balances.totalIssuance(), (_substrateApi$api$que3 = substrateApi.api.query.auctions) === null || _substrateApi$api$que3 === void 0 ? void 0 : _substrateApi$api$que3.auctionCounter(), (_substrateApi$api$que4 = substrateApi.api.query.nominationPools) === null || _substrateApi$api$que4 === void 0 ? void 0 : _substrateApi$api$que4.minJoinBond(), substrateApi.api.query.staking.erasValidatorReward.multi([...Array(supportedDays.toString()).keys()].map(i => i + startEra))]);
86
+ const [_maxPoolMember, _EraStakeInfo, _totalIssuance, _auctionCounter, _minPoolJoin, ..._eraReward] = await Promise.all([(_substrateApi$api$que2 = substrateApi.api.query.nominationPools) === null || _substrateApi$api$que2 === void 0 ? void 0 : _substrateApi$api$que2.maxPoolMembersPerPool(), substrateApi.api.query.staking.erasTotalStake.multi([parseInt(currentEra), parseInt(currentEra) - 1]), substrateApi.api.query.balances.totalIssuance(), (_substrateApi$api$que3 = substrateApi.api.query.auctions) === null || _substrateApi$api$que3 === void 0 ? void 0 : _substrateApi$api$que3.auctionCounter(), (_substrateApi$api$que4 = substrateApi.api.query.nominationPools) === null || _substrateApi$api$que4 === void 0 ? void 0 : _substrateApi$api$que4.minJoinBond(), substrateApi.api.query.staking.erasValidatorReward.multi([...Array(supportedDays).keys()].map(i => i + startEra))]);
87
87
  const maxPoolMembers = _maxPoolMember ? parseInt(_maxPoolMember.toString()) : undefined;
88
88
  const [_totalEraStake, _lastTotalStaked] = _EraStakeInfo;
89
89
  const validatorEraReward = getAvgValidatorEraReward(supportedDays, _eraReward[0]);
@@ -3,12 +3,13 @@
3
3
 
4
4
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
5
5
  import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
6
- import { ALL_ACCOUNT_KEY } from '@subwallet/extension-base/constants';
6
+ import { ALL_ACCOUNT_KEY, XCM_FEE_RATIO } from '@subwallet/extension-base/constants';
7
7
  import { YIELD_POOL_STAT_REFRESH_INTERVAL } from '@subwallet/extension-base/koni/api/yield/helper/utils';
8
8
  import { createXcmExtrinsic } from '@subwallet/extension-base/services/balance-service/transfer/xcm';
9
- import { _getChainNativeTokenSlug } from '@subwallet/extension-base/services/chain-service/utils';
9
+ import { _getAssetDecimals, _getAssetExistentialDeposit, _getAssetName, _getAssetSymbol, _getChainNativeTokenSlug } from '@subwallet/extension-base/services/chain-service/utils';
10
10
  import { BasicTxErrorType, YieldStepType, YieldValidationStatus } from '@subwallet/extension-base/types';
11
11
  import { createPromiseHandler, formatNumber } from '@subwallet/extension-base/utils';
12
+ import { getId } from '@subwallet/extension-base/utils/getId';
12
13
  import { t } from 'i18next';
13
14
  import { BN, BN_TEN, BN_ZERO, noop } from '@polkadot/util';
14
15
  import BasePoolHandler from "./base.js";
@@ -73,17 +74,27 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
73
74
  value: '0'
74
75
  }), this.state.balanceService.getTransferableBalance(request.address, feeAssetInfo.originChain, feeAssetInfo.slug)]);
75
76
  const bnInputAssetBalance = new BN(inputAssetBalance.value);
76
- const bnAltInputAssetBalance = new BN(altInputAssetBalance.value);
77
77
  const bnMinJoinPool = new BN(poolInfo.statistic.earningThreshold.join);
78
78
  const inputTokenInfo = this.state.chainService.getAssetBySlug(this.inputAsset);
79
79
  const altInputTokenInfo = this.state.chainService.getAssetBySlug(this.altInputAsset);
80
+ const existentialDeposit = new BN(_getAssetExistentialDeposit(altInputTokenInfo));
81
+ const bnAltInputAssetBalance = new BN(altInputAssetBalance.value);
80
82
  if (bnInputAssetBalance.add(bnAltInputAssetBalance).lt(bnMinJoinPool)) {
83
+ const missingAmount = bnMinJoinPool.sub(bnInputAssetBalance).sub(bnAltInputAssetBalance);
84
+ const isTheSame = missingAmount.toString() === bnMinJoinPool.toString();
81
85
  const originChain = this.state.getChainInfo(inputTokenInfo.originChain);
82
86
  const altChain = this.state.getChainInfo(altInputTokenInfo.originChain);
83
- const parsedMinJoinPool = formatNumber(bnMinJoinPool.toString(), inputAssetInfo.decimals || 0);
87
+ const originSymbol = _getAssetSymbol(inputTokenInfo);
88
+ const altSymbol = _getAssetSymbol(altInputTokenInfo);
89
+ const originName = originChain.name;
90
+ const altName = altChain.name;
91
+ const parsedMinJoinPool = formatNumber(missingAmount.toString(), inputAssetInfo.decimals || 0);
92
+ const formatparsedMinJoinPool = isTheSame ? parsedMinJoinPool : Number(parsedMinJoinPool) + 0.01;
93
+ const parsedMinAltJoinPool = formatNumber(missingAmount.add(existentialDeposit).toString(), inputAssetInfo.decimals || 0);
94
+ const formatParsedMinAltJoinPool = isTheSame ? parsedMinAltJoinPool : Number(parsedMinAltJoinPool) + 0.01;
84
95
  return {
85
96
  passed: false,
86
- errorMessage: `You need at least ${parsedMinJoinPool} ${inputTokenInfo.symbol} (${originChain.name}) or ${altInputTokenInfo.symbol} (${altChain.name}) to start earning`
97
+ errorMessage: `You need to deposit an additional ${formatparsedMinJoinPool} ${originSymbol} (${originName}) or ${formatParsedMinAltJoinPool} ${altSymbol} (${altName}) to start earning`
87
98
  };
88
99
  }
89
100
  if (this.feeAssets.length === 1) {
@@ -215,13 +226,18 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
215
226
  type: YieldStepType.XCM
216
227
  };
217
228
  const xcmOriginSubstrateApi = await this.state.getSubstrateApi(altInputTokenInfo.originChain).isReady;
229
+ const id = getId();
230
+ const feeInfo = await this.state.feeService.subscribeChainFee(id, altChainInfo.slug, 'substrate');
218
231
  const xcmTransfer = await createXcmExtrinsic({
232
+ sender: address,
219
233
  originTokenInfo: altInputTokenInfo,
220
234
  destinationTokenInfo: inputTokenInfo,
221
235
  sendingValue: bnAmount.toString(),
222
236
  recipient: address,
223
- chainInfoMap: this.state.getChainInfoMap(),
224
- substrateApi: xcmOriginSubstrateApi
237
+ destinationChain: this.chainInfo,
238
+ originChain: altChainInfo,
239
+ substrateApi: xcmOriginSubstrateApi,
240
+ feeInfo
225
241
  });
226
242
  const _xcmFeeInfo = await xcmTransfer.paymentInfo(address);
227
243
  const xcmFeeInfo = _xcmFeeInfo.toPrimitive();
@@ -281,16 +297,15 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
281
297
  processValidation.failedStep = path.steps[1];
282
298
  processValidation.ok = false;
283
299
  processValidation.status = YieldValidationStatus.NOT_ENOUGH_BALANCE;
300
+ const bnMaxXCM = new BN(altInputTokenBalance.value).sub(xcmFee.mul(new BN(XCM_FEE_RATIO)));
301
+ const inputTokenDecimal = _getAssetDecimals(inputTokenInfo);
284
302
  const maxBn = bnInputTokenBalance.add(new BN(altInputTokenBalance.value)).sub(xcmFee).sub(xcmFee);
285
303
  const maxValue = formatNumber(maxBn.toString(), inputTokenInfo.decimals || 0);
286
- const altInputTokenInfo = this.state.getAssetBySlug(altInputTokenSlug);
287
- const symbol = altInputTokenInfo.symbol;
288
- const altNetwork = this.state.getChainInfo(altInputTokenInfo.originChain);
304
+ const maxXCMValue = formatNumber(bnMaxXCM.toString(), inputTokenDecimal);
305
+ const symbol = _getAssetSymbol(altInputTokenInfo);
289
306
  const inputNetworkName = this.chainInfo.name;
290
- const altNetworkName = altNetwork.name;
291
- const currentValue = formatNumber(bnInputTokenBalance.toString(), inputTokenInfo.decimals || 0);
292
- const bnMaxXCM = new BN(altInputTokenBalance.value).sub(xcmFee).sub(xcmFee);
293
- const maxXCMValue = formatNumber(bnMaxXCM.toString(), inputTokenInfo.decimals || 0);
307
+ const altNetworkName = _getAssetName(altInputTokenInfo);
308
+ const currentValue = formatNumber(bnInputTokenBalance.toString(), inputTokenDecimal);
294
309
  processValidation.message = t('You can only enter a maximum of {{maxValue}} {{symbol}}, which is {{currentValue}} {{symbol}} ({{inputNetworkName}}) and {{maxXCMValue}} {{symbol}} ({{altNetworkName}}). Lower your amount and try again.', {
295
310
  replace: {
296
311
  symbol,
@@ -419,13 +434,18 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
419
434
  const bnXcmFee = new BN(xcmFee);
420
435
  const bnAmount = new BN(amount);
421
436
  const bnTotalAmount = bnAmount.sub(bnInputTokenBalance).add(bnXcmFee);
437
+ const id = getId();
438
+ const feeInfo = await this.state.feeService.subscribeChainFee(id, originChainInfo.slug, 'substrate');
422
439
  const extrinsic = await createXcmExtrinsic({
423
- chainInfoMap: this.state.getChainInfoMap(),
424
440
  destinationTokenInfo,
425
441
  originTokenInfo,
426
442
  recipient: address,
427
443
  sendingValue: bnTotalAmount.toString(),
428
- substrateApi
444
+ substrateApi,
445
+ sender: address,
446
+ originChain: originChainInfo,
447
+ destinationChain: this.chainInfo,
448
+ feeInfo
429
449
  });
430
450
  const xcmData = {
431
451
  originNetworkKey: originChainInfo.slug,
@@ -0,0 +1,5 @@
1
+ export interface TokenHasBalanceInfo {
2
+ slug: string;
3
+ free: string;
4
+ rate: string;
5
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,12 +1,15 @@
1
1
  import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
2
- import { EvmFeeInfo } from '@subwallet/extension-base/types';
2
+ import { EvmFeeInfo, FeeChainType, FeeInfo } from '@subwallet/extension-base/types';
3
3
  export default class FeeService {
4
4
  protected readonly state: KoniState;
5
5
  private evmFeeSubject;
6
6
  private useInfura;
7
+ private chainFeeSubscriptionMap;
7
8
  constructor(state: KoniState);
8
9
  changeMode(useInfura: boolean): void;
9
10
  private updateFees;
10
11
  private updateChainFee;
11
12
  subscribeFees(callback: (data: Record<string, EvmFeeInfo>) => void): () => void;
13
+ subscribeChainFee(id: string, chain: string, type: FeeChainType, callback?: (data: FeeInfo) => void): Promise<FeeInfo>;
14
+ unsubscribeChainFee(id: string, chain: string, type: FeeChainType): void;
12
15
  }
@@ -6,6 +6,11 @@ import { calculateGasFeeParams } from '@subwallet/extension-base/services/fee-se
6
6
  import { BehaviorSubject } from 'rxjs';
7
7
  export default class FeeService {
8
8
  evmFeeSubject = new BehaviorSubject({});
9
+ chainFeeSubscriptionMap = {
10
+ evm: {},
11
+ substrate: {},
12
+ ton: {}
13
+ };
9
14
  constructor(state) {
10
15
  this.state = state;
11
16
  this.useInfura = true;
@@ -60,4 +65,110 @@ export default class FeeService {
60
65
  clearInterval(interval);
61
66
  };
62
67
  }
68
+ subscribeChainFee(id, chain, type, callback) {
69
+ return new Promise(resolve => {
70
+ const _callback = value => {
71
+ if (value) {
72
+ callback === null || callback === void 0 ? void 0 : callback(value);
73
+ resolve(value);
74
+ }
75
+ };
76
+ const feeSubscription = this.chainFeeSubscriptionMap[type][chain];
77
+ if (feeSubscription) {
78
+ const observer = feeSubscription.observer;
79
+ _callback(observer.getValue());
80
+
81
+ // If have callback, just subscribe
82
+ if (callback) {
83
+ const subscription = observer.subscribe({
84
+ next: _callback
85
+ });
86
+ this.chainFeeSubscriptionMap[type][chain].subscription[id] = () => {
87
+ if (!subscription.closed) {
88
+ subscription.unsubscribe();
89
+ }
90
+ };
91
+ }
92
+ } else {
93
+ const observer = new BehaviorSubject(undefined);
94
+ const subscription = observer.subscribe({
95
+ next: _callback
96
+ });
97
+ let cancel = false;
98
+ let interval;
99
+ const update = () => {
100
+ if (cancel) {
101
+ clearInterval(interval);
102
+ } else {
103
+ const api = this.state.getEvmApi(chain);
104
+ if (api) {
105
+ calculateGasFeeParams(api, chain).then(info => {
106
+ observer.next(info);
107
+ }).catch(e => {
108
+ console.warn(`Cannot get fee param for ${chain}`, e);
109
+ observer.next({
110
+ type: 'evm',
111
+ gasPrice: '0',
112
+ baseGasFee: undefined,
113
+ options: undefined
114
+ });
115
+ });
116
+ } else {
117
+ observer.next({
118
+ type: type,
119
+ busyNetwork: false,
120
+ options: {
121
+ slow: {
122
+ tip: '0'
123
+ },
124
+ average: {
125
+ tip: '0'
126
+ },
127
+ fast: {
128
+ tip: '0'
129
+ },
130
+ default: 'slow'
131
+ }
132
+ });
133
+ clearInterval(interval);
134
+ }
135
+ }
136
+ };
137
+ update();
138
+
139
+ // If have callback, just subscribe
140
+ if (callback) {
141
+ interval = setInterval(update, 15 * 1000);
142
+ const unsub = () => {
143
+ cancel = true;
144
+ observer.complete();
145
+ clearInterval(interval);
146
+ };
147
+ this.chainFeeSubscriptionMap[type][chain] = {
148
+ observer,
149
+ subscription: {
150
+ [id]: () => {
151
+ if (!subscription.closed) {
152
+ subscription.unsubscribe();
153
+ }
154
+ }
155
+ },
156
+ unsubscribe: unsub
157
+ };
158
+ }
159
+ }
160
+ });
161
+ }
162
+ unsubscribeChainFee(id, chain, type) {
163
+ const subscription = this.chainFeeSubscriptionMap[type][chain];
164
+ if (subscription) {
165
+ const unsub = subscription.subscription[id];
166
+ unsub && unsub();
167
+ delete subscription.subscription[id];
168
+ if (Object.keys(subscription.subscription).length === 0) {
169
+ subscription.unsubscribe();
170
+ delete this.chainFeeSubscriptionMap[type][chain];
171
+ }
172
+ }
173
+ }
63
174
  }
@@ -1,8 +1,14 @@
1
+ import { _ChainAsset } from '@subwallet/chain-list/types';
1
2
  import { _EvmApi } from '@subwallet/extension-base/services/chain-service/types';
2
- import { EvmFeeInfo, InfuraFeeInfo } from '@subwallet/extension-base/types';
3
- export declare const parseInfuraFee: (info: InfuraFeeInfo) => EvmFeeInfo;
3
+ import { EvmEIP1559FeeOption, EvmFeeInfo, InfuraFeeInfo, InfuraThresholdInfo } from '@subwallet/extension-base/types';
4
+ import BigN from 'bignumber.js';
5
+ import { ApiPromise } from '@polkadot/api';
6
+ export declare const FEE_COVERAGE_PERCENTAGE_SPECIAL_CASE = 105;
7
+ export declare const parseInfuraFee: (info: InfuraFeeInfo, threshold: InfuraThresholdInfo) => EvmFeeInfo;
4
8
  export declare const fetchInfuraFeeData: (chainId: number, infuraAuth?: string) => Promise<EvmFeeInfo | null>;
5
9
  export declare const fetchSubWalletFeeData: (chainId: number, networkKey: string) => Promise<EvmFeeInfo | null>;
6
10
  export declare const fetchOnlineFeeData: (chainId: number, networkKey: string, useInfura?: boolean) => Promise<EvmFeeInfo | null>;
7
11
  export declare const recalculateGasPrice: (_price: string, chain: string) => string;
12
+ export declare const getEIP1559GasFee: (baseFee: BigN, maxPriorityFee: BigN, blockNumber: number, blockTime: number) => EvmEIP1559FeeOption;
8
13
  export declare const calculateGasFeeParams: (web3: _EvmApi, networkKey: string, useOnline?: boolean, useInfura?: boolean) => Promise<EvmFeeInfo>;
14
+ export declare const calculateToAmountByReservePool: (api: ApiPromise, fromToken: _ChainAsset, toToken: _ChainAsset, fromAmount: string) => Promise<string>;