@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
@@ -17,7 +17,7 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
17
17
  protected readonly feeAssets: string[];
18
18
  transactionChainType: ChainType;
19
19
  protected readonly rateDecimals = 10;
20
- protected readonly availableMethod: YieldPoolMethodInfo;
20
+ readonly availableMethod: YieldPoolMethodInfo;
21
21
  constructor(state: KoniState, chain: string);
22
22
  protected getDescription(): string;
23
23
  getPoolStat(): Promise<LiquidYieldPoolInfo>;
@@ -33,7 +33,8 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
33
33
  fastUnstake: false,
34
34
  cancelUnstake: false,
35
35
  withdraw: true,
36
- claimReward: false
36
+ claimReward: false,
37
+ changeValidator: false
37
38
  };
38
39
  constructor(state, chain) {
39
40
  super(state, chain);
@@ -5,7 +5,7 @@ import { BaseYieldPositionInfo, PalletDappsStakingAccountLedger, StakeCancelWith
5
5
  import BaseParaNativeStakingPoolHandler from './base-para';
6
6
  export declare function getAstarWithdrawable(yieldPosition: YieldPositionInfo): UnstakingInfo | undefined;
7
7
  export default class AstarNativeStakingPoolHandler extends BaseParaNativeStakingPoolHandler {
8
- protected readonly availableMethod: YieldPoolMethodInfo;
8
+ readonly availableMethod: YieldPoolMethodInfo;
9
9
  subscribePoolInfo(callback: (data: YieldPoolInfo) => void): Promise<VoidFunction>;
10
10
  parseNominatorMetadata(chainInfo: _ChainInfo, address: string, substrateApi: _SubstrateApi, ledger: PalletDappsStakingAccountLedger): Promise<Omit<YieldPositionInfo, keyof BaseYieldPositionInfo>>;
11
11
  subscribePoolPosition(useAddresses: string[], resultCallback: (rs: YieldPositionInfo) => void): Promise<VoidFunction>;
@@ -39,7 +39,8 @@ export default class AstarNativeStakingPoolHandler extends BaseParaNativeStaking
39
39
  fastUnstake: false,
40
40
  cancelUnstake: false,
41
41
  withdraw: true,
42
- claimReward: true
42
+ claimReward: true,
43
+ changeValidator: false
43
44
  };
44
45
 
45
46
  /* Subscribe pool info */
@@ -1,13 +1,13 @@
1
1
  import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
2
2
  import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
3
- import { EarningRewardHistoryItem, EarningRewardItem, HandleYieldStepData, OptimalYieldPath, OptimalYieldPathParams, SubmitJoinNativeStaking, SubmitYieldJoinData, TransactionData, YieldPoolMethodInfo, YieldPoolType, YieldPositionInfo, YieldStepBaseInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
3
+ import { EarningRewardHistoryItem, EarningRewardItem, HandleYieldStepData, OptimalYieldPath, OptimalYieldPathParams, SubmitChangeValidatorStaking, SubmitJoinNativeStaking, SubmitYieldJoinData, TransactionData, YieldPoolMethodInfo, YieldPoolType, YieldPositionInfo, YieldStepBaseInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
4
4
  import BasePoolHandler from '../base';
5
5
  export default abstract class BaseNativeStakingPoolHandler extends BasePoolHandler {
6
6
  readonly type = YieldPoolType.NATIVE_STAKING;
7
7
  protected readonly name: string;
8
8
  protected readonly shortName: string;
9
9
  slug: string;
10
- protected readonly availableMethod: YieldPoolMethodInfo;
10
+ availableMethod: YieldPoolMethodInfo;
11
11
  static generateSlug(symbol: string, chain: string): string;
12
12
  constructor(state: KoniState, chain: string);
13
13
  protected getDescription(amount?: string): string;
@@ -20,4 +20,5 @@ export default abstract class BaseNativeStakingPoolHandler extends BasePoolHandl
20
20
  handleYieldJoin(_data: SubmitYieldJoinData, path: OptimalYieldPath, currentStep: number): Promise<HandleYieldStepData>;
21
21
  handleYieldRedeem(amount: string, address: string, selectedTarget?: string): Promise<[ExtrinsicType, TransactionData]>;
22
22
  handleYieldClaimReward(address: string, bondReward?: boolean): Promise<TransactionData>;
23
+ handleChangeEarningValidator(_data: SubmitChangeValidatorStaking): Promise<TransactionData>;
23
24
  }
@@ -14,7 +14,8 @@ export default class BaseNativeStakingPoolHandler extends BasePoolHandler {
14
14
  fastUnstake: false,
15
15
  cancelUnstake: true,
16
16
  withdraw: true,
17
- claimReward: false
17
+ claimReward: false,
18
+ changeValidator: false
18
19
  };
19
20
  static generateSlug(symbol, chain) {
20
21
  return `${symbol}___native_staking___${chain}`;
@@ -164,6 +165,9 @@ export default class BaseNativeStakingPoolHandler extends BasePoolHandler {
164
165
  async handleYieldClaimReward(address, bondReward) {
165
166
  return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
166
167
  }
168
+ async handleChangeEarningValidator(_data) {
169
+ return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
170
+ }
167
171
 
168
172
  /* Other actions */
169
173
  }
@@ -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 BaseParaStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/native-staking/base-para';
6
- import { BaseYieldPositionInfo, OptimalYieldPath, RequestEarningSlippage, StakeCancelWithdrawalParams, SubmitJoinNativeStaking, TransactionData, UnstakingInfo, ValidatorInfo, YieldPoolInfo, YieldPoolMethodInfo, YieldPoolType, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
6
+ import { BaseYieldPositionInfo, OptimalYieldPath, RequestEarningSlippage, StakeCancelWithdrawalParams, SubmitBittensorChangeValidatorStaking, SubmitJoinNativeStaking, TransactionData, UnstakingInfo, ValidatorInfo, YieldPoolInfo, YieldPoolMethodInfo, YieldPoolType, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
7
7
  import BigN from 'bignumber.js';
8
8
  export interface SubnetData {
9
9
  netuid: number;
@@ -40,7 +40,7 @@ export interface EarningSlippageResult {
40
40
  slippage: number;
41
41
  rate: number;
42
42
  }
43
- export declare const DEFAULT_DTAO_MINBOND = "600000";
43
+ export declare const DEFAULT_DTAO_MINBOND = "21000000";
44
44
  export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHandler {
45
45
  handleYieldWithdraw(address: string, unstakingInfo: UnstakingInfo): Promise<TransactionData>;
46
46
  handleYieldCancelUnstake(params: StakeCancelWithdrawalParams): Promise<TransactionData>;
@@ -64,10 +64,11 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
64
64
  checkAccountHaveStake(useAddresses: string[]): Promise<string[]>;
65
65
  private getDevnetPoolTargets;
66
66
  private getMainnetPoolTargets;
67
- getPoolTargets(): Promise<ValidatorInfo[]>;
67
+ getPoolTargets(netuid: number): Promise<ValidatorInfo[]>;
68
68
  createJoinExtrinsic(data: SubmitJoinNativeStaking, positionInfo?: YieldPositionInfo, bondDest?: string): Promise<[TransactionData, YieldTokenBaseInfo]>;
69
69
  validateYieldJoin(data: SubmitJoinNativeStaking, path: OptimalYieldPath): Promise<TransactionError[]>;
70
70
  handleYieldUnstake(amount: string, address: string, selectedTarget?: string, netuid?: number, slippage?: number): Promise<[ExtrinsicType, TransactionData]>;
71
71
  validateYieldLeave(amount: string, address: string, fastLeave: boolean, selectedTarget?: string, slug?: string, poolInfo?: YieldPoolInfo): Promise<TransactionError[]>;
72
+ handleChangeEarningValidator(data: SubmitBittensorChangeValidatorStaking): Promise<TransactionData>;
72
73
  }
73
74
  export {};
@@ -7,15 +7,14 @@ 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, YieldPoolType } from '@subwallet/extension-base/types';
10
+ import { BasicTxErrorType, EarningStatus, StakingTxErrorType, YieldPoolType } from '@subwallet/extension-base/types';
11
11
  import { formatNumber, reformatAddress } from '@subwallet/extension-base/utils';
12
12
  import BigN from 'bignumber.js';
13
13
  import { t } from 'i18next';
14
14
  import { BN, BN_ZERO } from '@polkadot/util';
15
- import { calculateReward } from "../../utils/index.js";
16
15
  import { BittensorCache } from "./tao.js";
17
16
  const DEFAULT_BITTENSOR_SLIPPAGE = 0.005;
18
- export const DEFAULT_DTAO_MINBOND = '600000';
17
+ export const DEFAULT_DTAO_MINBOND = '21000000';
19
18
  const getAlphaToTaoMapping = async substrateApi => {
20
19
  const allSubnets = (await substrateApi.api.call.subnetInfoRuntimeApi.getAllDynamicInfo()).toJSON();
21
20
  if (!allSubnets || allSubnets.length === 0) {
@@ -62,7 +61,8 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
62
61
  fastUnstake: false,
63
62
  cancelUnstake: false,
64
63
  withdraw: false,
65
- claimReward: false
64
+ claimReward: false,
65
+ changeValidator: true
66
66
  };
67
67
  constructor(state, chain) {
68
68
  super(state, chain);
@@ -393,32 +393,37 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
393
393
  isCrowded: false
394
394
  }));
395
395
  }
396
- async getMainnetPoolTargets() {
396
+ async getMainnetPoolTargets(netuid) {
397
397
  const _topValidator = await this.bittensorCache.get();
398
398
  const topValidator = _topValidator;
399
399
  const bnMinBond = new BigN(DEFAULT_DTAO_MINBOND);
400
400
  const validatorList = topValidator.data;
401
- const validatorAddresses = Object.keys(validatorList);
402
- const results = await Promise.all(validatorAddresses.map(i => {
403
- const address = validatorList[i].hotkey.ss58;
404
- const bnTotalStake = new BigN(validatorList[i].stake);
405
- const bnOwnStake = new BigN(validatorList[i].validator_stake);
406
- const otherStake = bnTotalStake.minus(bnOwnStake);
407
- const nominatorCount = validatorList[i].nominators;
408
- const commission = validatorList[i].take;
401
+ const aprResponse = await this.bittensorCache.fetchApr(netuid);
402
+ const aprMap = {};
403
+ aprResponse.data.forEach(item => {
404
+ aprMap[item.hotkey.ss58] = item.thirty_day_apy;
405
+ });
406
+ const results = await Promise.all(validatorList.map(validator => {
407
+ const address = validator.hotkey.ss58;
408
+ // With bittensor we use total weight, root weight and alpha staked insted of total stake, own stake and other stake
409
+ const bnTotalWeightStake = new BigN(validator.global_weighted_stake);
410
+ const bnRootWeightStake = new BigN(validator.weighted_root_stake);
411
+ const bnAlphaStake = new BigN(validator.global_alpha_stake_as_tao);
412
+ const nominatorCount = validator.global_nominators;
413
+ const commission = validator.take;
409
414
  const roundedCommission = (parseFloat(commission) * 100).toFixed(0);
410
- const apr = (parseFloat(validatorList[i].apr) / 10 ** 9 * 100).toFixed(2);
411
- const apyCalculate = calculateReward(parseFloat(apr));
412
- const name = validatorList[i].name || address;
415
+ const apr = aprMap[address];
416
+ const expectedReturn = apr ? new BigN(apr).multipliedBy(100).toFixed(2) : '0';
417
+ const name = validator.name || address;
413
418
  return {
414
419
  address: address,
415
- totalStake: bnTotalStake.toString(),
416
- ownStake: bnOwnStake.toString(),
417
- otherStake: otherStake.toString(),
420
+ totalStake: bnTotalWeightStake.toString(),
421
+ ownStake: bnRootWeightStake.toString(),
422
+ otherStake: bnAlphaStake.toString(),
418
423
  minBond: bnMinBond.toString(),
419
424
  nominatorCount: nominatorCount,
420
425
  commission: roundedCommission,
421
- expectedReturn: apyCalculate.apy,
426
+ expectedReturn: expectedReturn,
422
427
  blocked: false,
423
428
  isVerified: false,
424
429
  chain: this.chain,
@@ -428,10 +433,10 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
428
433
  }));
429
434
  return results;
430
435
  }
431
- async getPoolTargets() {
436
+ async getPoolTargets(netuid) {
432
437
  await this.init();
433
438
  if (this.chain === 'bittensor') {
434
- return this.getMainnetPoolTargets();
439
+ return this.getMainnetPoolTargets(netuid);
435
440
  } else {
436
441
  return this.getDevnetPoolTargets();
437
442
  }
@@ -447,6 +452,9 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
447
452
  selectedValidators: targetValidators,
448
453
  subnetData
449
454
  } = data;
455
+ if (!subnetData) {
456
+ throw new Error(BasicTxErrorType.INVALID_PARAMS);
457
+ }
450
458
  const {
451
459
  netuid,
452
460
  slippage
@@ -456,6 +464,8 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
456
464
  const alphaToTaoPrice = new BigN(await getAlphaToTaoRate(this.substrateApi, netuid));
457
465
  const limitPrice = alphaToTaoPrice.multipliedBy(10 ** _getAssetDecimals(this.nativeToken)).multipliedBy(1 + (slippage || DEFAULT_BITTENSOR_SLIPPAGE));
458
466
  const BNlimitPrice = new BigN(limitPrice.integerValue(BigN.ROUND_CEIL).toFixed());
467
+
468
+ // Bittensor only supports changing 1 validator at a time, not multiple
459
469
  const selectedValidatorInfo = targetValidators[0];
460
470
  const hotkey = selectedValidatorInfo.address;
461
471
  const extrinsic = chainApi.api.tx.subtensorModule.addStakeLimit(hotkey, netuid, binaryAmount.toFixed(), BNlimitPrice.toFixed(), false);
@@ -464,6 +474,8 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
464
474
  amount: '0'
465
475
  }];
466
476
  }
477
+
478
+ // Validate for case stake more
467
479
  async validateYieldJoin(data, path) {
468
480
  const baseErrors = await super.validateYieldJoin(data, path);
469
481
  if (baseErrors.length > 0) {
@@ -515,4 +527,45 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
515
527
  }
516
528
 
517
529
  /* Leave pool action */
530
+
531
+ /* Change validator */
532
+ async handleChangeEarningValidator(data) {
533
+ const chainApi = await this.substrateApi.isReady;
534
+ const {
535
+ amount,
536
+ maxAmount,
537
+ metadata,
538
+ originValidator,
539
+ selectedValidators: targetValidators,
540
+ subnetData
541
+ } = data;
542
+ if (!subnetData || !originValidator) {
543
+ return Promise.reject(new TransactionError(BasicTxErrorType.INVALID_PARAMS));
544
+ }
545
+ const {
546
+ netuid
547
+ } = subnetData;
548
+ const selectedValidatorInfo = targetValidators[0];
549
+ const destValidator = selectedValidatorInfo.address;
550
+ if (new BigN(amount).lte(0)) {
551
+ return Promise.reject(new TransactionError(BasicTxErrorType.INVALID_PARAMS, t('Amount must be greater than 0')));
552
+ }
553
+ if (originValidator === destValidator) {
554
+ return Promise.reject(new TransactionError(BasicTxErrorType.INVALID_PARAMS, 'From validator is the same with to validator'));
555
+ }
556
+ const alphaToTaoPrice = new BigN(await getAlphaToTaoRate(this.substrateApi, netuid || 0));
557
+ const minUnstake = new BigN(DEFAULT_DTAO_MINBOND).dividedBy(alphaToTaoPrice);
558
+ const formattedMinUnstake = minUnstake.dividedBy(1000000).integerValue(BigN.ROUND_CEIL).dividedBy(1000);
559
+ const bnMinUnstake = formattedMinUnstake.multipliedBy(10 ** _getAssetDecimals(this.nativeToken));
560
+ if (new BigN(maxAmount).lt(bnMinUnstake)) {
561
+ return Promise.reject(new TransactionError(BasicTxErrorType.INVALID_PARAMS, t(`Amount too low. You need to move at least ${formattedMinUnstake.toString()} ${(metadata === null || metadata === void 0 ? void 0 : metadata.subnetSymbol) || ''}`)));
562
+ }
563
+
564
+ // Avoid remaining amount too low -> can't do anything with that amount
565
+ if (!(maxAmount === amount) && new BigN(maxAmount).minus(new BigN(amount)).lt(bnMinUnstake)) {
566
+ 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))} ${(metadata === null || metadata === void 0 ? void 0 : metadata.subnetSymbol) || ''} to the new validator, or "Cancel" and lower the amount, then try again`)));
567
+ }
568
+ const extrinsic = chainApi.api.tx.subtensorModule.moveStake(originValidator, destValidator, netuid, netuid, amount);
569
+ return extrinsic;
570
+ }
518
571
  }
@@ -11,7 +11,7 @@ interface PalletCollatorStakingUserStakeInfo {
11
11
  maybeLastRewardSession: string;
12
12
  }
13
13
  export default class MythosNativeStakingPoolHandler extends BaseParaStakingPoolHandler {
14
- protected readonly availableMethod: YieldPoolMethodInfo;
14
+ readonly availableMethod: YieldPoolMethodInfo;
15
15
  subscribePoolInfo(callback: (data: YieldPoolInfo) => void): Promise<VoidFunction>;
16
16
  checkAccountHaveStake(useAddresses: string[]): Promise<Array<string>>;
17
17
  subscribePoolPosition(useAddresses: string[], resultCallback: (rs: YieldPositionInfo) => void): Promise<VoidFunction>;
@@ -30,7 +30,8 @@ export default class MythosNativeStakingPoolHandler extends BaseParaStakingPoolH
30
30
  fastUnstake: false,
31
31
  cancelUnstake: false,
32
32
  withdraw: true,
33
- claimReward: true
33
+ claimReward: true,
34
+ changeValidator: false
34
35
  };
35
36
 
36
37
  /* Subscribe pool info */
@@ -2,12 +2,15 @@
2
2
  import { _ChainInfo } from '@subwallet/chain-list/types';
3
3
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
4
4
  import { ExtrinsicType, NominationInfo, UnstakingInfo } from '@subwallet/extension-base/background/KoniTypes';
5
+ import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
5
6
  import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
6
- import { BaseYieldPositionInfo, OptimalYieldPath, PalletStakingNominations, PalletStakingStakingLedger, StakeCancelWithdrawalParams, SubmitJoinNativeStaking, SubmitYieldJoinData, TransactionData, ValidatorInfo, YieldPoolInfo, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
7
+ import { BaseYieldPositionInfo, OptimalYieldPath, PalletStakingNominations, PalletStakingStakingLedger, StakeCancelWithdrawalParams, SubmitChangeValidatorStaking, SubmitJoinNativeStaking, SubmitYieldJoinData, TransactionData, ValidatorInfo, YieldPoolInfo, YieldPoolMethodInfo, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
7
8
  import { DeriveSessionProgress } from '@polkadot/api-derive/types';
8
9
  import { BN } from '@polkadot/util';
9
10
  import BaseNativeStakingPoolHandler from './base';
10
11
  export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPoolHandler {
12
+ availableMethod: YieldPoolMethodInfo;
13
+ constructor(state: KoniState, chain: string);
11
14
  subscribePoolInfo(callback: (data: YieldPoolInfo) => void): Promise<VoidFunction>;
12
15
  parseNominatorMetadata(chainInfo: _ChainInfo, address: string, substrateApi: _SubstrateApi, ledger: PalletStakingStakingLedger, currentEra: string, minStake: BN, _deriveSessionProgress: DeriveSessionProgress): Promise<Omit<YieldPositionInfo, keyof BaseYieldPositionInfo>>;
13
16
  handleNominationsList(substrateApi: _SubstrateApi, chain: string, nominations: PalletStakingNominations, currentEra: string, address: string, maxNominatorRewardedPerValidator: number | undefined): Promise<NominationInfo[]>;
@@ -22,4 +25,5 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
22
25
  handleYieldUnstake(amount: string, address: string, selectedTarget?: string): Promise<[ExtrinsicType, TransactionData]>;
23
26
  handleYieldCancelUnstake(params: StakeCancelWithdrawalParams): Promise<TransactionData>;
24
27
  handleYieldWithdraw(address: string, unstakingInfo: UnstakingInfo): Promise<TransactionData>;
28
+ handleChangeEarningValidator(data: SubmitChangeValidatorStaking): Promise<TransactionData>;
25
29
  }
@@ -6,7 +6,7 @@ import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
6
6
  import { calculateAlephZeroValidatorReturn, calculateChainStakedReturnV2, calculateInflation, calculateTernoaValidatorReturn, calculateValidatorStakedReturn, getAvgValidatorEraReward, getCommission, getMaxValidatorErrorMessage, getMinStakeErrorMessage, getRelayBlockedValidatorList, getRelayEraRewardMap, getRelayMaxNominations, getRelayTopValidatorByPoints, getRelayValidatorPointsMap, getRelayWaitingValidatorList, getSupportedDaysByHistoryDepth } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
7
7
  import { _STAKING_ERA_LENGTH_MAP } from '@subwallet/extension-base/services/chain-service/constants';
8
8
  import { _getChainSubstrateAddressPrefix } from '@subwallet/extension-base/services/chain-service/utils';
9
- import { _STAKING_CHAIN_GROUP, MaxEraRewardPointsEras } from '@subwallet/extension-base/services/earning-service/constants';
9
+ import { _STAKING_CHAIN_GROUP, _SUPPORT_CHANGE_VALIDATOR_CHAIN, MaxEraRewardPointsEras } from '@subwallet/extension-base/services/earning-service/constants';
10
10
  import { applyDecimal, parseIdentity } from '@subwallet/extension-base/services/earning-service/utils';
11
11
  import { BasicTxErrorType, EarningStatus, StakingTxErrorType, UnstakingStatus } from '@subwallet/extension-base/types';
12
12
  import { balanceFormatter, formatNumber, reformatAddress } from '@subwallet/extension-base/utils';
@@ -15,6 +15,24 @@ import { t } from 'i18next';
15
15
  import { BN, BN_ZERO } from '@polkadot/util';
16
16
  import BaseNativeStakingPoolHandler from "./base.js";
17
17
  export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPoolHandler {
18
+ availableMethod = {
19
+ join: true,
20
+ defaultUnstake: true,
21
+ fastUnstake: false,
22
+ cancelUnstake: true,
23
+ withdraw: true,
24
+ claimReward: false,
25
+ changeValidator: false
26
+ };
27
+ constructor(state, chain) {
28
+ super(state, chain);
29
+ if (_SUPPORT_CHANGE_VALIDATOR_CHAIN.includes(chain)) {
30
+ this.availableMethod = {
31
+ ...this.availableMethod,
32
+ changeValidator: true
33
+ };
34
+ }
35
+ }
18
36
  /* Subscribe pool info */
19
37
 
20
38
  async subscribePoolInfo(callback) {
@@ -668,13 +686,11 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
668
686
  const chainApi = await this.substrateApi.isReady;
669
687
  if (chainApi.api.tx.staking.withdrawUnbonded.meta.args.length === 1) {
670
688
  let slashingSpanCount;
671
- if (chainApi.api.query.staking.nominatorSlashInEra) {
672
- const currentEra = await chainApi.api.query.staking.currentEra();
673
- const slashingSpans = (await chainApi.api.query.staking.nominatorSlashInEra(currentEra.toPrimitive(), address)).toPrimitive();
674
- slashingSpanCount = slashingSpans !== null ? slashingSpans.toString() : '0';
675
- } else {
689
+ if (chainApi.api.query.staking.slashingSpans) {
676
690
  const _slashingSpans = (await chainApi.api.query.staking.slashingSpans(address)).toHuman();
677
691
  slashingSpanCount = _slashingSpans !== null ? _slashingSpans.spanIndex : '0';
692
+ } else {
693
+ slashingSpanCount = chainApi.api.consts.staking.historyDepth.toPrimitive();
678
694
  }
679
695
  return chainApi.api.tx.staking.withdrawUnbonded(slashingSpanCount);
680
696
  } else {
@@ -682,6 +698,17 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
682
698
  return chainApi.api.tx.staking.withdrawUnbonded();
683
699
  }
684
700
  }
685
-
701
+ async handleChangeEarningValidator(data) {
702
+ const chainApi = await this.substrateApi.isReady;
703
+ const {
704
+ selectedValidators
705
+ } = data;
706
+ if (!selectedValidators || selectedValidators.length === 0) {
707
+ return Promise.reject(new TransactionError(BasicTxErrorType.INVALID_PARAMS));
708
+ }
709
+ const validatorParamList = selectedValidators.map(validator => validator.address);
710
+ const nominateTx = chainApi.api.tx.staking.nominate(validatorParamList);
711
+ return nominateTx;
712
+ }
686
713
  /* Other actions */
687
714
  }
@@ -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 BaseParaStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/native-staking/base-para';
6
- import { BaseYieldPositionInfo, OptimalYieldPath, StakeCancelWithdrawalParams, SubmitJoinNativeStaking, TransactionData, UnstakingInfo, ValidatorInfo, YieldPoolInfo, YieldPoolMethodInfo, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
6
+ import { BaseYieldPositionInfo, OptimalYieldPath, StakeCancelWithdrawalParams, SubmitBittensorChangeValidatorStaking, SubmitJoinNativeStaking, TransactionData, UnstakingInfo, ValidatorInfo, YieldPoolInfo, YieldPoolMethodInfo, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
7
7
  export interface TaoStakeInfo {
8
8
  hotkey: string;
9
9
  stake: string;
@@ -31,11 +31,27 @@ interface Validator {
31
31
  ss58: string;
32
32
  };
33
33
  name: string;
34
- nominators: number;
34
+ global_nominators: number;
35
+ validator_return_per_day: string;
36
+ nominator_return_per_day: string;
35
37
  stake: string;
36
38
  validator_stake: string;
37
39
  take: string;
38
- apr: string;
40
+ root_stake: string;
41
+ global_weighted_stake: string;
42
+ weighted_root_stake: string;
43
+ global_alpha_stake_as_tao: string;
44
+ }
45
+ interface ValidatorAprResponse {
46
+ data: ValidatorApr[];
47
+ }
48
+ interface ValidatorApr {
49
+ hotkey: {
50
+ ss58: string;
51
+ };
52
+ name: string;
53
+ netuid: number;
54
+ thirty_day_apy: string;
39
55
  }
40
56
  export declare class BittensorCache {
41
57
  private static instance;
@@ -46,9 +62,10 @@ export declare class BittensorCache {
46
62
  static getInstance(): BittensorCache;
47
63
  get(): Promise<ValidatorResponse>;
48
64
  private fetchData;
65
+ fetchApr(netuid: number): Promise<ValidatorAprResponse>;
49
66
  }
50
67
  export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHandler {
51
- protected readonly availableMethod: YieldPoolMethodInfo;
68
+ readonly availableMethod: YieldPoolMethodInfo;
52
69
  private bittensorCache;
53
70
  constructor(state: KoniState, chain: string);
54
71
  handleYieldWithdraw(address: string, unstakingInfo: UnstakingInfo): Promise<TransactionData>;
@@ -65,5 +82,6 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
65
82
  validateYieldJoin(data: SubmitJoinNativeStaking, path: OptimalYieldPath): Promise<TransactionError[]>;
66
83
  handleYieldUnstake(amount: string, address: string, selectedTarget?: string): Promise<[ExtrinsicType, TransactionData]>;
67
84
  validateYieldLeave(amount: string, address: string, fastLeave: boolean, selectedTarget?: string, slug?: string, poolInfo?: YieldPoolInfo): Promise<TransactionError[]>;
85
+ handleChangeEarningValidator(data: SubmitBittensorChangeValidatorStaking): Promise<TransactionData>;
68
86
  }
69
87
  export {};