@subwallet/extension-base 1.3.47-0 → 1.3.48-1

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 (75) 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/background/handlers/Extension.js +21 -1
  9. package/cjs/packageInfo.js +1 -1
  10. package/cjs/services/chain-service/index.js +7 -2
  11. package/cjs/services/earning-service/constants/chains.js +4 -2
  12. package/cjs/services/earning-service/handlers/lending/interlay.js +2 -1
  13. package/cjs/services/earning-service/handlers/liquid-staking/acala.js +2 -1
  14. package/cjs/services/earning-service/handlers/liquid-staking/bifrost.js +2 -1
  15. package/cjs/services/earning-service/handlers/liquid-staking/parallel.js +2 -1
  16. package/cjs/services/earning-service/handlers/liquid-staking/stella-swap.js +2 -1
  17. package/cjs/services/earning-service/handlers/native-staking/astar.js +2 -1
  18. package/cjs/services/earning-service/handlers/native-staking/base.js +5 -1
  19. package/cjs/services/earning-service/handlers/native-staking/dtao.js +74 -21
  20. package/cjs/services/earning-service/handlers/native-staking/mythos.js +2 -1
  21. package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +33 -6
  22. package/cjs/services/earning-service/handlers/native-staking/tao.js +93 -32
  23. package/cjs/services/earning-service/handlers/nomination-pool/index.js +5 -2
  24. package/cjs/services/earning-service/handlers/special.js +3 -1
  25. package/cjs/services/earning-service/service.js +26 -2
  26. package/cjs/services/transaction-service/helpers/index.js +2 -0
  27. package/cjs/services/transaction-service/index.js +15 -0
  28. package/cjs/types/transaction/error.js +1 -0
  29. package/cjs/utils/account/transform.js +3 -2
  30. package/core/logic-validation/transfer.js +7 -0
  31. package/koni/api/nft/config.d.ts +1 -1
  32. package/koni/api/nft/config.js +1 -1
  33. package/koni/background/handlers/Extension.d.ts +1 -0
  34. package/koni/background/handlers/Extension.js +21 -1
  35. package/package.json +6 -6
  36. package/packageInfo.js +1 -1
  37. package/services/chain-service/index.js +7 -2
  38. package/services/earning-service/constants/chains.d.ts +1 -0
  39. package/services/earning-service/constants/chains.js +2 -1
  40. package/services/earning-service/handlers/base.d.ts +5 -3
  41. package/services/earning-service/handlers/lending/interlay.d.ts +1 -1
  42. package/services/earning-service/handlers/lending/interlay.js +2 -1
  43. package/services/earning-service/handlers/liquid-staking/acala.d.ts +1 -1
  44. package/services/earning-service/handlers/liquid-staking/acala.js +2 -1
  45. package/services/earning-service/handlers/liquid-staking/bifrost.d.ts +1 -1
  46. package/services/earning-service/handlers/liquid-staking/bifrost.js +2 -1
  47. package/services/earning-service/handlers/liquid-staking/parallel.d.ts +1 -1
  48. package/services/earning-service/handlers/liquid-staking/parallel.js +2 -1
  49. package/services/earning-service/handlers/liquid-staking/stella-swap.d.ts +1 -1
  50. package/services/earning-service/handlers/liquid-staking/stella-swap.js +2 -1
  51. package/services/earning-service/handlers/native-staking/astar.d.ts +1 -1
  52. package/services/earning-service/handlers/native-staking/astar.js +2 -1
  53. package/services/earning-service/handlers/native-staking/base.d.ts +3 -2
  54. package/services/earning-service/handlers/native-staking/base.js +5 -1
  55. package/services/earning-service/handlers/native-staking/dtao.d.ts +4 -3
  56. package/services/earning-service/handlers/native-staking/dtao.js +75 -22
  57. package/services/earning-service/handlers/native-staking/mythos.d.ts +1 -1
  58. package/services/earning-service/handlers/native-staking/mythos.js +2 -1
  59. package/services/earning-service/handlers/native-staking/relay-chain.d.ts +5 -1
  60. package/services/earning-service/handlers/native-staking/relay-chain.js +34 -7
  61. package/services/earning-service/handlers/native-staking/tao.d.ts +22 -4
  62. package/services/earning-service/handlers/native-staking/tao.js +94 -33
  63. package/services/earning-service/handlers/nomination-pool/index.d.ts +3 -2
  64. package/services/earning-service/handlers/nomination-pool/index.js +5 -2
  65. package/services/earning-service/handlers/special.d.ts +2 -1
  66. package/services/earning-service/handlers/special.js +3 -1
  67. package/services/earning-service/service.d.ts +2 -1
  68. package/services/earning-service/service.js +26 -2
  69. package/services/transaction-service/helpers/index.js +2 -0
  70. package/services/transaction-service/index.js +15 -0
  71. package/types/transaction/error.d.ts +2 -1
  72. package/types/transaction/error.js +1 -0
  73. package/types/yield/actions/join/submit.d.ts +10 -1
  74. package/types/yield/info/chain/info.d.ts +2 -0
  75. package/utils/account/transform.js +3 -2
@@ -7,14 +7,12 @@ import { BITTENSOR_REFRESH_STAKE_APY, BITTENSOR_REFRESH_STAKE_INFO } from '@subw
7
7
  import { getEarningStatusByNominations } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
8
8
  import { _getAssetDecimals, _getAssetSymbol } from '@subwallet/extension-base/services/chain-service/utils';
9
9
  import BaseParaStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/native-staking/base-para';
10
- import { BasicTxErrorType, EarningStatus } from '@subwallet/extension-base/types';
10
+ import { BasicTxErrorType, EarningStatus, StakingTxErrorType } from '@subwallet/extension-base/types';
11
11
  import { ProxyServiceRoute } from '@subwallet/extension-base/types/environment';
12
12
  import { fetchFromProxyService, formatNumber, reformatAddress } from '@subwallet/extension-base/utils';
13
13
  import BigN from 'bignumber.js';
14
14
  import { t } from 'i18next';
15
15
  import { BN, BN_ZERO } from '@polkadot/util';
16
- import { calculateReward } from "../../utils/index.js";
17
- import { DEFAULT_DTAO_MINBOND } from "./dtao.js";
18
16
  /* Fetch data */
19
17
  export class BittensorCache {
20
18
  static instance = null;
@@ -42,7 +40,7 @@ export class BittensorCache {
42
40
  }
43
41
  async fetchData() {
44
42
  try {
45
- const resp = await fetchFromProxyService(ProxyServiceRoute.BITTENSOR, '/validator/latest/v1?limit=50', {
43
+ const resp = await fetchFromProxyService(ProxyServiceRoute.BITTENSOR, '/dtao/validator/latest/v1?limit=100', {
46
44
  method: 'GET',
47
45
  headers: {
48
46
  'Content-Type': 'application/json'
@@ -56,7 +54,7 @@ export class BittensorCache {
56
54
  }
57
55
  const rawData = await resp.json();
58
56
  const data = {
59
- data: rawData.data.filter(validator => parseFloat(validator.apr) > 0.0001)
57
+ data: rawData.data.filter(validator => parseFloat(validator.root_stake) > 0)
60
58
  };
61
59
  this.cache = data;
62
60
  this.promise = null;
@@ -79,6 +77,27 @@ export class BittensorCache {
79
77
  };
80
78
  }
81
79
  }
80
+ async fetchApr(netuid) {
81
+ try {
82
+ const resp = await fetchFromProxyService(ProxyServiceRoute.BITTENSOR, `/dtao/validator/yield/latest/v1?netuid=${netuid}&limit=100&order=thirty_day_apy_desc`, {
83
+ method: 'GET',
84
+ headers: {
85
+ 'Content-Type': 'application/json'
86
+ }
87
+ });
88
+ const rawData = await resp.json();
89
+
90
+ // Some subnets not return data, ensure the structure is consistent by returning an empty array
91
+ return Array.isArray(rawData.data) ? rawData : {
92
+ data: []
93
+ };
94
+ } catch (error) {
95
+ console.error(error);
96
+ return {
97
+ data: []
98
+ };
99
+ }
100
+ }
82
101
  }
83
102
 
84
103
  // export async function fetchTaoDelegateState (address: string): Promise<RawDelegateState> {
@@ -117,7 +136,8 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
117
136
  fastUnstake: false,
118
137
  cancelUnstake: false,
119
138
  withdraw: false,
120
- claimReward: false
139
+ claimReward: false,
140
+ changeValidator: true
121
141
  };
122
142
  constructor(state, chain) {
123
143
  super(state, chain);
@@ -153,23 +173,18 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
153
173
  const minDelegatorStake = (await substrateApi.api.query.subtensorModule.nominatorMinRequiredStake()).toPrimitive() || 0;
154
174
  const maxValidatorPerNominator = (await substrateApi.api.query.subtensorModule.maxAllowedValidators(0)).toPrimitive();
155
175
  const taoIn = (await substrateApi.api.query.subtensorModule.subnetTAO(0)).toPrimitive();
156
- const _topValidator = await this.bittensorCache.get();
176
+ const _topValidator = await this.bittensorCache.fetchApr(0);
157
177
  const validators = _topValidator.data;
158
- let highestApr = validators[0];
159
- for (let i = 1; i < validators.length; i++) {
160
- if (parseFloat(validators[i].apr) > parseFloat(highestApr.apr)) {
161
- highestApr = validators[i];
162
- }
163
- }
178
+ const highestApr = validators[0];
164
179
  const bnTaoIn = new BigN(taoIn);
165
180
  const BNminDelegatorStake = new BigN(minDelegatorStake.toString());
166
- const apr = this.chain === 'bittensor' ? Number(highestApr.apr) * 100 : 0;
181
+ const apr = this.chain === 'bittensor' ? Number(highestApr.thirty_day_apy) * 100 : 0;
167
182
  const data = {
168
183
  ...this.baseInfo,
169
184
  type: this.type,
170
185
  metadata: {
171
186
  ...this.metadataInfo,
172
- description: this.getDescription()
187
+ description: this.getDescription(formatNumber(BNminDelegatorStake, _getAssetDecimals(this.nativeToken)))
173
188
  },
174
189
  statistic: {
175
190
  assetEarning: [{
@@ -416,27 +431,32 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
416
431
  const nominatorMinRequiredStake = (await getNominatorMinRequiredStake).toString();
417
432
  const bnMinBond = new BigN(nominatorMinRequiredStake);
418
433
  const validatorList = topValidator.data;
419
- const validatorAddresses = Object.keys(validatorList);
420
- const results = await Promise.all(validatorAddresses.map(i => {
421
- const address = validatorList[i].hotkey.ss58;
422
- const bnTotalStake = new BigN(validatorList[i].stake);
423
- const bnOwnStake = new BigN(validatorList[i].validator_stake);
424
- const otherStake = bnTotalStake.minus(bnOwnStake);
425
- const nominatorCount = validatorList[i].nominators;
426
- const commission = validatorList[i].take;
434
+ const aprResponse = await this.bittensorCache.fetchApr(0);
435
+ const aprMap = {};
436
+ aprResponse.data.forEach(item => {
437
+ aprMap[item.hotkey.ss58] = item.thirty_day_apy;
438
+ });
439
+ const results = await Promise.all(validatorList.map(validator => {
440
+ const address = validator.hotkey.ss58;
441
+ // With bittensor we use total weight, root weight and alpha staked insted of total stake, own stake and other stake
442
+ const bnTotalWeightStake = new BigN(validator.global_weighted_stake);
443
+ const bnRootWeightStake = new BigN(validator.weighted_root_stake);
444
+ const bnAlphaStake = new BigN(validator.global_alpha_stake_as_tao);
445
+ const nominatorCount = validator.global_nominators;
446
+ const commission = validator.take;
427
447
  const roundedCommission = (parseFloat(commission) * 100).toFixed(0);
428
- const apr = (parseFloat(validatorList[i].apr) / 10 ** 9 * 100).toFixed(2);
429
- const apyCalculate = calculateReward(parseFloat(apr));
430
- const name = validatorList[i].name || address;
448
+ const apr = aprMap[address];
449
+ const expectedReturn = apr ? new BigN(apr).multipliedBy(100).toFixed(2) : '0';
450
+ const name = validator.name || address;
431
451
  return {
432
452
  address: address,
433
- totalStake: bnTotalStake.toString(),
434
- ownStake: bnOwnStake.toString(),
435
- otherStake: otherStake.toString(),
453
+ totalStake: bnTotalWeightStake.toString(),
454
+ ownStake: bnRootWeightStake.toString(),
455
+ otherStake: bnAlphaStake.toString(),
436
456
  minBond: bnMinBond.toString(),
437
457
  nominatorCount: nominatorCount,
438
458
  commission: roundedCommission,
439
- expectedReturn: apyCalculate.apy,
459
+ expectedReturn: expectedReturn,
440
460
  blocked: false,
441
461
  isVerified: false,
442
462
  chain: this.chain,
@@ -473,6 +493,8 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
473
493
  amount: '0'
474
494
  }];
475
495
  }
496
+
497
+ // Validate for case stake more
476
498
  async validateYieldJoin(data, path) {
477
499
  const baseErrors = await super.validateYieldJoin(data, path);
478
500
  if (baseErrors.length > 0) {
@@ -481,8 +503,10 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
481
503
  const {
482
504
  amount
483
505
  } = data;
484
- if (new BigN(amount).lt(new BigN(DEFAULT_DTAO_MINBOND))) {
485
- return [new TransactionError(BasicTxErrorType.INVALID_PARAMS, t(`Insufficient stake. You need to stake at least ${formatNumber(DEFAULT_DTAO_MINBOND, _getAssetDecimals(this.nativeToken))} ${_getAssetSymbol(this.nativeToken)} to earn rewards`))];
506
+ const minDelegatorStake = (await this.substrateApi.api.query.subtensorModule.nominatorMinRequiredStake()).toPrimitive() || 0;
507
+ const bnMinStake = minDelegatorStake.toString();
508
+ if (new BigN(amount).lt(bnMinStake)) {
509
+ return [new TransactionError(BasicTxErrorType.INVALID_PARAMS, t(`Insufficient stake. You need to stake at least ${formatNumber(bnMinStake, _getAssetDecimals(this.nativeToken))} ${_getAssetSymbol(this.nativeToken)} to earn rewards`))];
486
510
  }
487
511
  return baseErrors;
488
512
  }
@@ -509,7 +533,8 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
509
533
  if (!poolInfo) {
510
534
  return [new TransactionError(BasicTxErrorType.INVALID_PARAMS)];
511
535
  }
512
- const bnMinUnstake = new BigN(DEFAULT_DTAO_MINBOND);
536
+ const minDelegatorStake = (await this.substrateApi.api.query.subtensorModule.nominatorMinRequiredStake()).toPrimitive() || 0;
537
+ const bnMinUnstake = new BigN(minDelegatorStake.toString());
513
538
  if (new BigN(amount).lt(bnMinUnstake)) {
514
539
  return [new TransactionError(BasicTxErrorType.INVALID_PARAMS, t(`Amount too low. You need to unstake at least ${formatNumber(bnMinUnstake, _getAssetDecimals(this.nativeToken))} ${_getAssetSymbol(this.nativeToken)}`))];
515
540
  }
@@ -517,4 +542,40 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
517
542
  }
518
543
 
519
544
  /* Leave pool action */
545
+
546
+ /* Change validator */
547
+ async handleChangeEarningValidator(data) {
548
+ const chainApi = await this.substrateApi.isReady;
549
+ const {
550
+ amount,
551
+ maxAmount,
552
+ originValidator,
553
+ selectedValidators: targetValidators
554
+ } = data;
555
+ if (!originValidator) {
556
+ return Promise.reject(new TransactionError(BasicTxErrorType.INVALID_PARAMS));
557
+ }
558
+
559
+ // Bittensor only supports changing 1 validator at a time, not multiple
560
+ const selectedValidatorInfo = targetValidators[0];
561
+ const destValidator = selectedValidatorInfo.address;
562
+ if (new BigN(amount).lte(0)) {
563
+ return Promise.reject(new TransactionError(BasicTxErrorType.INVALID_PARAMS, t('Amount must be greater than 0')));
564
+ }
565
+ if (originValidator === destValidator) {
566
+ return Promise.reject(new TransactionError(BasicTxErrorType.INVALID_PARAMS, 'From validator is the same with to validator'));
567
+ }
568
+ const minDelegatorStake = (await this.substrateApi.api.query.subtensorModule.nominatorMinRequiredStake()).toPrimitive() || 0;
569
+ const bnMinMoveStake = new BigN(minDelegatorStake.toString());
570
+ if (new BigN(maxAmount).lt(bnMinMoveStake)) {
571
+ return Promise.reject(new TransactionError(BasicTxErrorType.INVALID_PARAMS, t(`Amount too low. You need to move at least ${formatNumber(bnMinMoveStake, _getAssetDecimals(this.nativeToken))} ${_getAssetSymbol(this.nativeToken)}`)));
572
+ }
573
+
574
+ // Avoid remaining amount too low -> can't do anything with that amount
575
+ if (!(maxAmount === amount) && new BigN(maxAmount).minus(new BigN(amount)).lt(bnMinMoveStake)) {
576
+ return Promise.reject(new TransactionError(StakingTxErrorType.REMAINING_AMOUNT_TOO_LOW, t(`Your remaining stake on the initial validator will fall below minimum active stake and cannot be unstaked if you proceed with the chosen amount. Hit "Move all" to move all ${formatNumber(maxAmount, _getAssetDecimals(this.nativeToken))} ${_getAssetSymbol(this.nativeToken)} to the new validator, or "Cancel" and lower the amount, then try again`)));
577
+ }
578
+ const extrinsic = chainApi.api.tx.subtensorModule.moveStake(originValidator, destValidator, 0, 0, amount);
579
+ return extrinsic;
580
+ }
520
581
  }
@@ -3,7 +3,7 @@ import { ExtrinsicType, UnstakingInfo } from '@subwallet/extension-base/backgrou
3
3
  import { PalletNominationPoolsPoolMember } from '@subwallet/extension-base/core/substrate/types';
4
4
  import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
5
5
  import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
6
- import { BaseYieldPositionInfo, EarningRewardHistoryItem, EarningRewardItem, HandleYieldStepData, NominationPoolInfo, OptimalYieldPath, OptimalYieldPathParams, StakeCancelWithdrawalParams, SubmitJoinNominationPool, SubmitYieldJoinData, TransactionData, YieldPoolInfo, YieldPoolMethodInfo, YieldPoolType, YieldPositionInfo, YieldStepBaseInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
6
+ import { BaseYieldPositionInfo, EarningRewardHistoryItem, EarningRewardItem, HandleYieldStepData, NominationPoolInfo, OptimalYieldPath, OptimalYieldPathParams, StakeCancelWithdrawalParams, SubmitChangeValidatorStaking, SubmitJoinNominationPool, SubmitYieldJoinData, TransactionData, YieldPoolInfo, YieldPoolMethodInfo, YieldPoolType, YieldPositionInfo, YieldStepBaseInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
7
7
  import { DeriveSessionProgress } from '@polkadot/api-derive/types';
8
8
  import BasePoolHandler from '../base';
9
9
  export default class NominationPoolHandler extends BasePoolHandler {
@@ -11,7 +11,7 @@ export default class NominationPoolHandler extends BasePoolHandler {
11
11
  protected readonly name: string;
12
12
  protected readonly shortName: string;
13
13
  slug: string;
14
- protected readonly availableMethod: YieldPoolMethodInfo;
14
+ readonly availableMethod: YieldPoolMethodInfo;
15
15
  static generateSlug(symbol: string, chain: string): string;
16
16
  constructor(state: KoniState, chain: string);
17
17
  protected getDescription(amount?: string): string;
@@ -35,4 +35,5 @@ export default class NominationPoolHandler extends BasePoolHandler {
35
35
  handleYieldCancelUnstake(params: StakeCancelWithdrawalParams): Promise<TransactionData>;
36
36
  handleYieldClaimReward(address: string, bondReward?: boolean): Promise<TransactionData>;
37
37
  handleYieldWithdraw(address: string, unstakingInfo: UnstakingInfo): Promise<TransactionData>;
38
+ handleChangeEarningValidator(data: SubmitChangeValidatorStaking): Promise<TransactionData>;
38
39
  }
@@ -20,7 +20,8 @@ export default class NominationPoolHandler extends BasePoolHandler {
20
20
  fastUnstake: false,
21
21
  cancelUnstake: false,
22
22
  withdraw: true,
23
- claimReward: true
23
+ claimReward: true,
24
+ changeValidator: false
24
25
  };
25
26
  static generateSlug(symbol, chain) {
26
27
  return `${symbol}___nomination_pool___${chain}`;
@@ -575,6 +576,8 @@ export default class NominationPoolHandler extends BasePoolHandler {
575
576
  });
576
577
  }
577
578
  }
578
-
579
+ handleChangeEarningValidator(data) {
580
+ return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
581
+ }
579
582
  /* Other actions */
580
583
  }
@@ -2,7 +2,7 @@
2
2
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
3
3
  import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
4
4
  import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
5
- import { BaseYieldStepDetail, HandleYieldStepData, OptimalYieldPath, OptimalYieldPathParams, RequestEarlyValidateYield, ResponseEarlyValidateYield, SpecialYieldPoolInfo, SpecialYieldPoolMetadata, SubmitYieldJoinData, TransactionData, UnstakingInfo, YieldPoolInfo, YieldPoolTarget, YieldPoolType, YieldStepBaseInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
5
+ import { BaseYieldStepDetail, HandleYieldStepData, OptimalYieldPath, OptimalYieldPathParams, RequestEarlyValidateYield, ResponseEarlyValidateYield, SpecialYieldPoolInfo, SpecialYieldPoolMetadata, SubmitChangeValidatorStaking, SubmitYieldJoinData, TransactionData, UnstakingInfo, YieldPoolInfo, YieldPoolTarget, YieldPoolType, YieldStepBaseInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
6
6
  import { BN } from '@polkadot/util';
7
7
  import BasePoolHandler from './base';
8
8
  export default abstract class BaseSpecialStakingPoolHandler extends BasePoolHandler {
@@ -62,4 +62,5 @@ export default abstract class BaseSpecialStakingPoolHandler extends BasePoolHand
62
62
  handleYieldCancelUnstake(): Promise<TransactionData>;
63
63
  handleYieldClaimReward(address: string, bondReward?: boolean): Promise<TransactionData>;
64
64
  handleYieldWithdraw(address: string, unstakingInfo: UnstakingInfo): Promise<TransactionData>;
65
+ handleChangeEarningValidator(data: SubmitChangeValidatorStaking): Promise<TransactionData>;
65
66
  }
@@ -512,6 +512,8 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
512
512
  handleYieldWithdraw(address, unstakingInfo) {
513
513
  return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
514
514
  }
515
-
515
+ handleChangeEarningValidator(data) {
516
+ return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
517
+ }
516
518
  /* Other actions */
517
519
  }
@@ -3,7 +3,7 @@ import { TransactionError } from '@subwallet/extension-base/background/errors/Tr
3
3
  import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
4
4
  import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
5
5
  import { PersistDataServiceInterface, ServiceStatus, StoppableServiceInterface } from '@subwallet/extension-base/services/base/types';
6
- import { EarningRewardHistoryItem, EarningRewardItem, EarningRewardJson, HandleYieldStepData, HandleYieldStepParams, OptimalYieldPath, OptimalYieldPathParams, RequestEarlyValidateYield, RequestEarningSlippage, RequestStakeCancelWithdrawal, RequestStakeClaimReward, RequestYieldLeave, RequestYieldWithdrawal, ResponseEarlyValidateYield, TransactionData, ValidateYieldProcessParams, YieldPoolInfo, YieldPoolTarget, YieldPositionInfo } from '@subwallet/extension-base/types';
6
+ import { EarningRewardHistoryItem, EarningRewardItem, EarningRewardJson, HandleYieldStepData, HandleYieldStepParams, OptimalYieldPath, OptimalYieldPathParams, RequestEarlyValidateYield, RequestEarningSlippage, RequestStakeCancelWithdrawal, RequestStakeClaimReward, RequestYieldLeave, RequestYieldWithdrawal, ResponseEarlyValidateYield, SubmitChangeValidatorStaking, TransactionData, ValidateYieldProcessParams, YieldPoolInfo, YieldPoolTarget, YieldPositionInfo } from '@subwallet/extension-base/types';
7
7
  import { PromiseHandler } from '@subwallet/extension-base/utils';
8
8
  import { BehaviorSubject } from 'rxjs';
9
9
  import { EarningSlippageResult } from './handlers/native-staking/dtao';
@@ -103,5 +103,6 @@ export default class EarningService implements StoppableServiceInterface, Persis
103
103
  handleYieldCancelUnstake(params: RequestStakeCancelWithdrawal): Promise<TransactionData>;
104
104
  handleYieldClaimReward(params: RequestStakeClaimReward): Promise<TransactionData>;
105
105
  yieldGetEarningSlippage(params: RequestEarningSlippage): Promise<EarningSlippageResult>;
106
+ handleYieldChangeValidator(params: SubmitChangeValidatorStaking): Promise<TransactionData>;
106
107
  resetWallet(): Promise<void>;
107
108
  }
@@ -377,7 +377,13 @@ export default class EarningService {
377
377
  delete onlineData[inactiveSlug];
378
378
  }
379
379
  Object.values(onlineData).forEach(item => {
380
- this.updateYieldPoolInfo(item);
380
+ const handler = this.getPoolHandler(item.slug);
381
+ if (!handler) {
382
+ return;
383
+ }
384
+ const updatedItem = structuredClone(item);
385
+ updatedItem.metadata.availableMethod = handler.availableMethod;
386
+ this.updateYieldPoolInfo(updatedItem);
381
387
  });
382
388
  return onlineData;
383
389
  }
@@ -714,7 +720,13 @@ export default class EarningService {
714
720
  const handler = this.getPoolHandler(slug);
715
721
  if (!targets.length && handler) {
716
722
  await this.eventService.waitChainReady;
717
- targets = await handler.getPoolTargets();
723
+ const isSubnet = slug.match(/subnet_(\d+)/);
724
+ if (isSubnet) {
725
+ const subnet = Number(isSubnet[1]);
726
+ targets = await handler.getPoolTargets(subnet);
727
+ } else {
728
+ targets = await handler.getPoolTargets();
729
+ }
718
730
  }
719
731
  return targets;
720
732
  }
@@ -857,6 +869,18 @@ export default class EarningService {
857
869
  return Promise.reject(new TransactionError(BasicTxErrorType.INTERNAL_ERROR));
858
870
  }
859
871
  }
872
+ async handleYieldChangeValidator(params) {
873
+ await this.eventService.waitChainReady;
874
+ const {
875
+ slug
876
+ } = params;
877
+ const handler = this.getPoolHandler(slug);
878
+ if (handler) {
879
+ return handler.handleChangeEarningValidator(params);
880
+ } else {
881
+ return Promise.reject(new TransactionError(BasicTxErrorType.INTERNAL_ERROR));
882
+ }
883
+ }
860
884
 
861
885
  /* Other */
862
886
 
@@ -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
@@ -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 = {};