@subwallet/extension-base 1.1.29-beta.0 → 1.1.29-beta.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 (60) hide show
  1. package/background/KoniTypes.d.ts +2 -1
  2. package/cjs/constants/index.js +11 -2
  3. package/cjs/koni/background/cron.js +10 -2
  4. package/cjs/koni/background/handlers/Extension.js +15 -0
  5. package/cjs/koni/background/subscription.js +12 -24
  6. package/cjs/services/earning-service/handlers/base.js +5 -3
  7. package/cjs/services/earning-service/handlers/lending/interlay.js +8 -0
  8. package/cjs/services/earning-service/handlers/liquid-staking/acala.js +16 -5
  9. package/cjs/services/earning-service/handlers/liquid-staking/bifrost.js +17 -1
  10. package/cjs/services/earning-service/handlers/liquid-staking/parallel.js +9 -3
  11. package/cjs/services/earning-service/handlers/liquid-staking/stella-swap.js +38 -11
  12. package/cjs/services/earning-service/handlers/native-staking/amplitude.js +4 -2
  13. package/cjs/services/earning-service/handlers/native-staking/astar.js +11 -6
  14. package/cjs/services/earning-service/handlers/native-staking/base.js +45 -5
  15. package/cjs/services/earning-service/handlers/native-staking/para-chain.js +3 -1
  16. package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +3 -1
  17. package/cjs/services/earning-service/handlers/nomination-pool/index.js +14 -1
  18. package/cjs/services/earning-service/handlers/special.js +7 -8
  19. package/cjs/services/earning-service/service.js +41 -5
  20. package/cjs/services/subscan-service/index.js +16 -0
  21. package/constants/index.d.ts +4 -1
  22. package/constants/index.js +4 -1
  23. package/koni/background/cron.d.ts +1 -0
  24. package/koni/background/cron.js +11 -3
  25. package/koni/background/handlers/Extension.d.ts +1 -0
  26. package/koni/background/handlers/Extension.js +15 -0
  27. package/koni/background/subscription.d.ts +1 -0
  28. package/koni/background/subscription.js +12 -23
  29. package/package.json +1 -1
  30. package/services/earning-service/handlers/base.d.ts +5 -1
  31. package/services/earning-service/handlers/base.js +5 -3
  32. package/services/earning-service/handlers/lending/interlay.d.ts +3 -2
  33. package/services/earning-service/handlers/lending/interlay.js +8 -0
  34. package/services/earning-service/handlers/liquid-staking/acala.d.ts +3 -4
  35. package/services/earning-service/handlers/liquid-staking/acala.js +16 -5
  36. package/services/earning-service/handlers/liquid-staking/bifrost.d.ts +4 -3
  37. package/services/earning-service/handlers/liquid-staking/bifrost.js +17 -1
  38. package/services/earning-service/handlers/liquid-staking/parallel.d.ts +3 -5
  39. package/services/earning-service/handlers/liquid-staking/parallel.js +9 -3
  40. package/services/earning-service/handlers/liquid-staking/stella-swap.d.ts +4 -6
  41. package/services/earning-service/handlers/liquid-staking/stella-swap.js +38 -11
  42. package/services/earning-service/handlers/native-staking/amplitude.js +4 -2
  43. package/services/earning-service/handlers/native-staking/astar.d.ts +2 -2
  44. package/services/earning-service/handlers/native-staking/astar.js +11 -6
  45. package/services/earning-service/handlers/native-staking/base.d.ts +3 -2
  46. package/services/earning-service/handlers/native-staking/base.js +45 -5
  47. package/services/earning-service/handlers/native-staking/para-chain.js +3 -1
  48. package/services/earning-service/handlers/native-staking/relay-chain.js +3 -1
  49. package/services/earning-service/handlers/nomination-pool/index.d.ts +3 -1
  50. package/services/earning-service/handlers/nomination-pool/index.js +15 -2
  51. package/services/earning-service/handlers/special.d.ts +1 -4
  52. package/services/earning-service/handlers/special.js +7 -8
  53. package/services/earning-service/service.d.ts +7 -2
  54. package/services/earning-service/service.js +41 -5
  55. package/services/subscan-service/index.d.ts +2 -1
  56. package/services/subscan-service/index.js +15 -0
  57. package/services/subscan-service/types.d.ts +20 -0
  58. package/types/yield/info/account/info.d.ts +2 -11
  59. package/types/yield/info/account/reward.d.ts +15 -0
  60. package/types/yield/info/chain/info.d.ts +29 -3
@@ -1,8 +1,9 @@
1
1
  import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
2
2
  import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
3
- import { BaseYieldStepDetail, HandleYieldStepData, LiquidYieldPoolInfo, OptimalYieldPath, OptimalYieldPathParams, SubmitYieldJoinData, TransactionData, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
3
+ import { BaseYieldStepDetail, HandleYieldStepData, LiquidYieldPoolInfo, OptimalYieldPath, OptimalYieldPathParams, SubmitYieldJoinData, TransactionData, YieldPoolMethodInfo, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
4
4
  import BaseLiquidStakingPoolHandler from './base';
5
5
  export default class ParallelLiquidStakingPoolHandler extends BaseLiquidStakingPoolHandler {
6
+ slug: string;
6
7
  protected readonly name: string;
7
8
  protected readonly shortName: string;
8
9
  protected readonly altInputAsset: string;
@@ -10,11 +11,8 @@ export default class ParallelLiquidStakingPoolHandler extends BaseLiquidStakingP
10
11
  protected readonly inputAsset: string;
11
12
  protected readonly rewardAssets: string[];
12
13
  protected readonly feeAssets: string[];
13
- /** @inner */
14
14
  readonly minAmountPercent = 0.97;
15
- /** @inner */
16
- protected readonly allowDefaultUnstake = true;
17
- slug: string;
15
+ protected readonly availableMethod: YieldPoolMethodInfo;
18
16
  constructor(state: KoniState, chain: string);
19
17
  protected getDescription(): string;
20
18
  getPoolStat(): Promise<LiquidYieldPoolInfo>;
@@ -13,10 +13,15 @@ export default class ParallelLiquidStakingPoolHandler extends BaseLiquidStakingP
13
13
  inputAsset = 'parallel-LOCAL-DOT';
14
14
  rewardAssets = ['parallel-LOCAL-DOT'];
15
15
  feeAssets = ['parallel-NATIVE-PARA'];
16
- /** @inner */
17
16
  minAmountPercent = 0.97;
18
- /** @inner */
19
- allowDefaultUnstake = true;
17
+ availableMethod = {
18
+ join: true,
19
+ defaultUnstake: true,
20
+ fastUnstake: true,
21
+ cancelUnstake: false,
22
+ withdraw: false,
23
+ claimReward: false
24
+ };
20
25
  constructor(state, chain) {
21
26
  super(state, chain);
22
27
  const chainInfo = this.chainInfo;
@@ -112,6 +117,7 @@ export default class ParallelLiquidStakingPoolHandler extends BaseLiquidStakingP
112
117
  derivativeToken: derivativeTokenSlug,
113
118
  isBondedBefore: bnTotalBalance.gt(BN_ZERO),
114
119
  nominations: [],
120
+ // TODO: add unstaking info from liquidStaking.unlockings
115
121
  unstakings: []
116
122
  };
117
123
  resultCallback(result);
@@ -2,11 +2,12 @@ import { TransactionError } from '@subwallet/extension-base/background/errors/Tr
2
2
  import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
3
3
  import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
4
4
  import { _EvmApi } from '@subwallet/extension-base/services/chain-service/types';
5
- import { BaseYieldStepDetail, HandleYieldStepData, LiquidYieldPoolInfo, OptimalYieldPath, OptimalYieldPathParams, SubmitYieldJoinData, TransactionData, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
5
+ import { BaseYieldStepDetail, HandleYieldStepData, LiquidYieldPoolInfo, OptimalYieldPath, OptimalYieldPathParams, SubmitYieldJoinData, TransactionData, UnstakingInfo, YieldPoolMethodInfo, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
6
6
  import { Contract } from 'web3-eth-contract';
7
7
  import BaseLiquidStakingPoolHandler from './base';
8
8
  export declare const getStellaswapLiquidStakingContract: (networkKey: string, assetAddress: string, evmApi: _EvmApi, options?: {}) => Contract;
9
9
  export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakingPoolHandler {
10
+ slug: string;
10
11
  protected readonly name: string;
11
12
  protected readonly shortName: string;
12
13
  protected readonly inputAsset: string;
@@ -14,12 +15,8 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
14
15
  protected readonly derivativeAssets: string[];
15
16
  protected readonly rewardAssets: string[];
16
17
  protected readonly feeAssets: string[];
17
- /** @inner */
18
- protected readonly allowDefaultUnstake = true;
19
- /** @inner */
20
- protected readonly allowFastUnstake = false;
21
- slug: string;
22
18
  transactionChainType: ChainType;
19
+ protected readonly availableMethod: YieldPoolMethodInfo;
23
20
  constructor(state: KoniState, chain: string);
24
21
  protected getDescription(): string;
25
22
  getPoolStat(): Promise<LiquidYieldPoolInfo>;
@@ -33,4 +30,5 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
33
30
  handleSubmitStep(data: SubmitYieldJoinData, path: OptimalYieldPath): Promise<HandleYieldStepData>;
34
31
  handleYieldRedeem(amount: string, address: string, selectedTarget?: string): Promise<[ExtrinsicType, TransactionData]>;
35
32
  handleYieldUnstake(amount: string, address: string, selectedTarget?: string): Promise<[ExtrinsicType, TransactionData]>;
33
+ handleYieldWithdraw(address: string, unstakingInfo: UnstakingInfo): Promise<TransactionData>;
36
34
  }
@@ -16,6 +16,7 @@ export const getStellaswapLiquidStakingContract = (networkKey, assetAddress, evm
16
16
  return new evmApi.api.eth.Contract(ST_LIQUID_TOKEN_ABI, assetAddress, options);
17
17
  };
18
18
  const APR_STATS_URL = 'https://apr-api.stellaswap.com/api/v1/stdot';
19
+ const SUBWALLET_REFERRAL = '0x7e6815f45E624768548d085231f2d453f16FD7DD';
19
20
  const MAX_INT = '115792089237316195423570985008687907853269984665640564039457584007913129639935';
20
21
  export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakingPoolHandler {
21
22
  inputAsset = 'moonbeam-LOCAL-xcDOT';
@@ -23,11 +24,15 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
23
24
  derivativeAssets = ['moonbeam-ERC20-stDOT-0xbc7E02c4178a7dF7d3E564323a5c359dc96C4db4'];
24
25
  rewardAssets = ['moonbeam-LOCAL-xcDOT'];
25
26
  feeAssets = ['moonbeam-NATIVE-GLMR'];
26
- /** @inner */
27
- allowDefaultUnstake = true;
28
- /** @inner */
29
- allowFastUnstake = false;
30
27
  transactionChainType = ChainType.EVM;
28
+ availableMethod = {
29
+ join: true,
30
+ defaultUnstake: true,
31
+ fastUnstake: true,
32
+ cancelUnstake: false,
33
+ withdraw: true,
34
+ claimReward: false
35
+ };
31
36
  constructor(state, chain) {
32
37
  super(state, chain);
33
38
  this.slug = 'xcDOT___liquid_staking___stellaswap';
@@ -130,11 +135,9 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
130
135
  unstakings.push({
131
136
  chain: this.chain,
132
137
  claimable: unbondedObject.waiting,
133
- status: UnstakingStatus.UNLOCKING,
134
- waitingTime: 20 // TODO: Recheck
138
+ status: UnstakingStatus.UNLOCKING
135
139
  });
136
140
  }
137
-
138
141
  const totalBalance = new BN(balance).add(unlockBalance);
139
142
  const result = {
140
143
  ...this.baseInfo,
@@ -180,8 +183,7 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
180
183
  const inputTokenInfo = this.state.getAssetBySlug(inputTokenSlug);
181
184
  const inputTokenContract = getERC20Contract(this.chain, _getContractAddressOfToken(inputTokenInfo), this.state.getEvmApiMap());
182
185
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
183
- const allowanceCall = inputTokenContract.methods.allowance(params.address, _getContractAddressOfToken(derivativeTokenInfo)); // TODO
184
-
186
+ const allowanceCall = inputTokenContract.methods.allowance(params.address, _getContractAddressOfToken(derivativeTokenInfo));
185
187
  const [allowance, gasPrice] = await Promise.all([
186
188
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
187
189
  await allowanceCall.call(), evmApi.api.eth.getGasPrice()]);
@@ -290,10 +292,12 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
290
292
  } = data;
291
293
  const inputTokenSlug = this.inputAsset;
292
294
  const inputTokenInfo = this.state.getAssetBySlug(inputTokenSlug);
295
+ const derivativeTokenInfo = this.state.getAssetBySlug(this.derivativeAssets[0]);
296
+ const derivativeTokenContractAddress = _getContractAddressOfToken(derivativeTokenInfo);
293
297
  const inputTokenContract = getERC20Contract(this.chain, _getContractAddressOfToken(inputTokenInfo), this.state.getEvmApiMap());
294
298
 
295
299
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
296
- const approveCall = inputTokenContract.methods.approve(address, MAX_INT);
300
+ const approveCall = inputTokenContract.methods.approve(derivativeTokenContractAddress, MAX_INT); // TODO: need test
297
301
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
298
302
  const approveEncodedCall = approveCall.encodeABI();
299
303
  const transactionObject = {
@@ -322,7 +326,7 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
322
326
  const stakingContract = getStellaswapLiquidStakingContract(this.chain, _getContractAddressOfToken(derivativeTokenInfo), evmApi);
323
327
 
324
328
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
325
- const depositCall = stakingContract.methods.deposit(amount); // TODO: referral
329
+ const depositCall = stakingContract.methods.deposit(amount, SUBWALLET_REFERRAL); // TODO: need test
326
330
 
327
331
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
328
332
  const depositEncodedCall = depositCall.encodeABI();
@@ -369,4 +373,27 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
369
373
  }
370
374
 
371
375
  /* Leave pool action */
376
+
377
+ /* Other actions */
378
+
379
+ // eslint-disable-next-line @typescript-eslint/require-await
380
+ async handleYieldWithdraw(address, unstakingInfo) {
381
+ const evmApi = this.evmApi;
382
+ const derivativeTokenSlug = this.derivativeAssets[0];
383
+ const derivativeTokenInfo = this.state.getAssetBySlug(derivativeTokenSlug);
384
+ const stakingContract = getStellaswapLiquidStakingContract(this.chain, _getContractAddressOfToken(derivativeTokenInfo), evmApi);
385
+
386
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
387
+ const withdrawCall = stakingContract.methods.claimUnbonded();
388
+
389
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
390
+ const withdrawEncodedCall = withdrawCall.encodeABI();
391
+ return {
392
+ from: address,
393
+ to: _getContractAddressOfToken(derivativeTokenInfo),
394
+ data: withdrawEncodedCall
395
+ }; // TODO: check tx history parsing
396
+ }
397
+
398
+ /* Other actions */
372
399
  }
@@ -42,10 +42,11 @@ export default class AmplitudeNativeStakingPoolHandler extends BaseParaNativeSta
42
42
  const round = parseRawNumber(roundObj.current);
43
43
  const maxDelegations = substrateApi.api.consts.parachainStaking.maxDelegationsPerRound.toString();
44
44
  const minDelegatorStake = substrateApi.api.consts.parachainStaking.minDelegatorStake.toString();
45
- const unstakingDelay = substrateApi.api.consts.parachainStaking.stakeDuration.toString();
45
+ const unstakingDelay = substrateApi.api.consts.parachainStaking.stakeDuration.toString(); // in blocks
46
46
  const _blockPerRound = substrateApi.api.consts.parachainStaking.defaultBlocksPerRound.toString();
47
47
  const blockPerRound = parseFloat(_blockPerRound);
48
- const blockDuration = (_STAKING_ERA_LENGTH_MAP[this.chain] || _STAKING_ERA_LENGTH_MAP.default) / blockPerRound; // in hours
48
+ const roundTime = _STAKING_ERA_LENGTH_MAP[this.chain] || _STAKING_ERA_LENGTH_MAP.default; // in hours
49
+ const blockDuration = roundTime / blockPerRound; // in hours
49
50
  const unstakingPeriod = blockDuration * parseInt(unstakingDelay);
50
51
  const minToHuman = formatNumber(minDelegatorStake, nativeToken.decimals || 0, balanceFormatter);
51
52
  const delegatorStorages = await substrateApi.api.query.parachainStaking.delegatorState.keys();
@@ -70,6 +71,7 @@ export default class AmplitudeNativeStakingPoolHandler extends BaseParaNativeSta
70
71
  farmerCount: delegatorStorages.length,
71
72
  // One delegator (farmer) - One collator (candidate) - on storage
72
73
  era: round,
74
+ eraTime: roundTime,
73
75
  tvl: stakeInfo.delegators,
74
76
  // TODO recheck
75
77
  totalApy: undefined,
@@ -1,11 +1,11 @@
1
1
  import { _ChainInfo } from '@subwallet/chain-list/types';
2
2
  import { ExtrinsicType, UnstakingInfo } from '@subwallet/extension-base/background/KoniTypes';
3
3
  import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
4
- import { BaseYieldPoolMetadata, BaseYieldPositionInfo, PalletDappsStakingAccountLedger, StakeCancelWithdrawalParams, SubmitJoinNativeStaking, TransactionData, ValidatorInfo, YieldPoolInfo, YieldPositionInfo, YieldStepBaseInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
4
+ import { BaseYieldPositionInfo, PalletDappsStakingAccountLedger, StakeCancelWithdrawalParams, SubmitJoinNativeStaking, TransactionData, ValidatorInfo, YieldPoolInfo, YieldPoolMethodInfo, YieldPositionInfo, YieldStepBaseInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
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 get metadataInfo(): Omit<BaseYieldPoolMetadata, 'description'>;
8
+ protected 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>;
@@ -35,11 +35,14 @@ export function getAstarWithdrawable(yieldPosition) {
35
35
  }
36
36
  }
37
37
  export default class AstarNativeStakingPoolHandler extends BaseParaNativeStakingPoolHandler {
38
- get metadataInfo() {
39
- const result = super.metadataInfo;
40
- result.allowCancelUnstaking = false;
41
- return result;
42
- }
38
+ availableMethod = {
39
+ join: true,
40
+ defaultUnstake: true,
41
+ fastUnstake: false,
42
+ cancelUnstake: false,
43
+ withdraw: true,
44
+ claimReward: true
45
+ };
43
46
 
44
47
  /* Subscribe pool info */
45
48
 
@@ -94,7 +97,8 @@ export default class AstarNativeStakingPoolHandler extends BaseParaNativeStaking
94
97
  const era = _currentEra.toString();
95
98
  const minDelegatorStake = substrateApi.api.consts.dappsStaking.minimumStakingAmount.toString();
96
99
  const unstakingDelay = substrateApi.api.consts.dappsStaking.unbondingPeriod.toString();
97
- const unstakingPeriod = parseInt(unstakingDelay) * _STAKING_ERA_LENGTH_MAP[this.chain];
100
+ const eraTime = _STAKING_ERA_LENGTH_MAP[this.chain] || _STAKING_ERA_LENGTH_MAP.default; // in hours
101
+ const unstakingPeriod = parseInt(unstakingDelay) * eraTime;
98
102
  const minToHuman = formatNumber(minDelegatorStake, nativeToken.decimals || 0, balanceFormatter);
99
103
  const data = {
100
104
  // TODO
@@ -117,6 +121,7 @@ export default class AstarNativeStakingPoolHandler extends BaseParaNativeStaking
117
121
  farmerCount: 0,
118
122
  // TODO recheck
119
123
  era: parseInt(era),
124
+ eraTime,
120
125
  tvl: undefined,
121
126
  // TODO recheck
122
127
  totalApy: apyInfo !== null ? apyInfo : undefined,
@@ -1,16 +1,17 @@
1
1
  import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
2
2
  import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
3
- import { BaseYieldPoolMetadata, EarningRewardItem, HandleYieldStepData, OptimalYieldPath, OptimalYieldPathParams, SubmitJoinNativeStaking, SubmitYieldJoinData, TransactionData, YieldPoolType, YieldPositionInfo, YieldStepBaseInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
3
+ import { EarningRewardHistoryItem, EarningRewardItem, HandleYieldStepData, OptimalYieldPath, OptimalYieldPathParams, 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
11
  constructor(state: KoniState, chain: string);
11
12
  protected getDescription(amount?: string): string;
12
- protected get metadataInfo(): Omit<BaseYieldPoolMetadata, 'description'>;
13
13
  getPoolReward(useAddresses: string[], callBack: (rs: EarningRewardItem) => void): Promise<VoidFunction>;
14
+ getPoolRewardHistory(useAddresses: string[], callBack: (rs: EarningRewardHistoryItem) => void): Promise<VoidFunction>;
14
15
  get defaultSubmitStep(): YieldStepBaseInfo;
15
16
  abstract createJoinExtrinsic(data: SubmitJoinNativeStaking, positionInfo?: YieldPositionInfo, bondDest?: string): Promise<[TransactionData, YieldTokenBaseInfo]>;
16
17
  protected getSubmitStep(params: OptimalYieldPathParams): Promise<YieldStepBaseInfo>;
@@ -8,6 +8,14 @@ import { noop } from '@polkadot/util';
8
8
  import BasePoolHandler from "../base.js";
9
9
  export default class BaseNativeStakingPoolHandler extends BasePoolHandler {
10
10
  type = YieldPoolType.NATIVE_STAKING;
11
+ availableMethod = {
12
+ join: true,
13
+ defaultUnstake: true,
14
+ fastUnstake: false,
15
+ cancelUnstake: true,
16
+ withdraw: true,
17
+ claimReward: false
18
+ };
11
19
  constructor(state, chain) {
12
20
  super(state, chain);
13
21
  const _chainAsset = this.nativeToken;
@@ -22,17 +30,49 @@ export default class BaseNativeStakingPoolHandler extends BasePoolHandler {
22
30
  const symbol = _chainAsset.symbol;
23
31
  return `Start staking with just {{amount}} ${symbol}`.replace('{{amount}}', amount);
24
32
  }
25
- get metadataInfo() {
26
- const result = super.metadataInfo;
27
- result.allowCancelUnstaking = true;
28
- return result;
29
- }
30
33
 
31
34
  /* Get pool reward */
32
35
 
33
36
  async getPoolReward(useAddresses, callBack) {
34
37
  return new Promise(resolve => resolve(noop));
35
38
  }
39
+ async getPoolRewardHistory(useAddresses, callBack) {
40
+ let cancel = false;
41
+ const haveSubscanService = this.state.subscanService.checkSupportedSubscanChain(this.chain);
42
+ if (haveSubscanService) {
43
+ for (const address of useAddresses) {
44
+ if (cancel) {
45
+ break;
46
+ }
47
+ try {
48
+ const rs = await this.state.subscanService.getRewardHistoryList(this.chain, address);
49
+ const items = rs.list;
50
+ if (items) {
51
+ for (const item of items) {
52
+ const now = new Date();
53
+ const isMillisecond = now.getTime().toString().length === item.block_timestamp.toString().length;
54
+ const timeStamp = isMillisecond ? item.block_timestamp : item.block_timestamp * 1000;
55
+ const data = {
56
+ slug: this.slug,
57
+ type: this.type,
58
+ chain: this.chain,
59
+ address: address,
60
+ group: this.group,
61
+ blockTimestamp: timeStamp,
62
+ amount: item.amount
63
+ };
64
+ callBack(data);
65
+ }
66
+ }
67
+ } catch (e) {
68
+ console.error(e);
69
+ }
70
+ }
71
+ }
72
+ return () => {
73
+ cancel = false;
74
+ };
75
+ }
36
76
 
37
77
  /* Get pool reward */
38
78
 
@@ -61,7 +61,8 @@ export default class ParaNativeStakingPoolHandler extends BaseParaNativeStakingP
61
61
 
62
62
  const inflationConfig = _inflation.toHuman();
63
63
  const inflation = getParaCurrentInflation(parseRawNumber(totalStake.toString()), inflationConfig);
64
- const unstakingPeriod = parseInt(unstakingDelay) * (_STAKING_ERA_LENGTH_MAP[this.chain] || _STAKING_ERA_LENGTH_MAP.default);
64
+ const eraTime = _STAKING_ERA_LENGTH_MAP[this.chain] || _STAKING_ERA_LENGTH_MAP.default; // in hours
65
+ const unstakingPeriod = parseInt(unstakingDelay) * eraTime;
65
66
  const minStake = '0';
66
67
  const minToHuman = formatNumber(minStake.toString(), nativeToken.decimals || 0, balanceFormatter);
67
68
  const data = {
@@ -83,6 +84,7 @@ export default class ParaNativeStakingPoolHandler extends BaseParaNativeStakingP
83
84
  farmerCount: 0,
84
85
  // TODO recheck
85
86
  era: round,
87
+ eraTime,
86
88
  totalApy: undefined,
87
89
  // not have
88
90
  tvl: totalStake.toString(),
@@ -61,7 +61,8 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
61
61
  const bnTotalIssuance = new BN(rawTotalIssuance);
62
62
  const inflation = calculateInflation(bnTotalEraStake, bnTotalIssuance, numAuctions, chainInfo.slug);
63
63
  const expectedReturn = calculateChainStakedReturn(inflation, bnTotalEraStake, bnTotalIssuance, chainInfo.slug);
64
- const unlockingPeriod = parseInt(unlockingEras) * (_STAKING_ERA_LENGTH_MAP[chainInfo.slug] || _STAKING_ERA_LENGTH_MAP.default); // in hours
64
+ const eraTime = _STAKING_ERA_LENGTH_MAP[chainInfo.slug] || _STAKING_ERA_LENGTH_MAP.default; // in hours
65
+ const unlockingPeriod = parseInt(unlockingEras) * eraTime; // in hours
65
66
  const farmerCount = _counterForNominators.toPrimitive();
66
67
  const minToHuman = formatNumber(minStake.toString(), nativeToken.decimals || 0, balanceFormatter);
67
68
  const data = {
@@ -83,6 +84,7 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
83
84
  minJoinPool: minStake.toString(),
84
85
  farmerCount: farmerCount,
85
86
  era: parseInt(currentEra),
87
+ eraTime,
86
88
  tvl: bnTotalEraStake.toString(),
87
89
  // TODO recheck
88
90
  totalApy: expectedReturn,
@@ -2,19 +2,21 @@ import { TransactionError } from '@subwallet/extension-base/background/errors/Tr
2
2
  import { ExtrinsicType, UnstakingInfo } from '@subwallet/extension-base/background/KoniTypes';
3
3
  import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
4
4
  import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
5
- import { BaseYieldPositionInfo, EarningRewardItem, HandleYieldStepData, NominationPoolInfo, OptimalYieldPath, OptimalYieldPathParams, PalletNominationPoolsPoolMember, StakeCancelWithdrawalParams, SubmitJoinNominationPool, SubmitYieldJoinData, TransactionData, YieldPoolInfo, YieldPoolType, YieldPositionInfo, YieldStepBaseInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
5
+ import { BaseYieldPositionInfo, EarningRewardHistoryItem, EarningRewardItem, HandleYieldStepData, NominationPoolInfo, OptimalYieldPath, OptimalYieldPathParams, PalletNominationPoolsPoolMember, StakeCancelWithdrawalParams, SubmitJoinNominationPool, SubmitYieldJoinData, TransactionData, YieldPoolInfo, YieldPoolMethodInfo, YieldPoolType, YieldPositionInfo, YieldStepBaseInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
6
6
  import BasePoolHandler from '../base';
7
7
  export default class NominationPoolHandler extends BasePoolHandler {
8
8
  readonly type = YieldPoolType.NOMINATION_POOL;
9
9
  protected readonly name: string;
10
10
  protected readonly shortName: string;
11
11
  slug: string;
12
+ protected readonly availableMethod: YieldPoolMethodInfo;
12
13
  constructor(state: KoniState, chain: string);
13
14
  protected getDescription(amount?: string): string;
14
15
  subscribePoolInfo(callback: (data: YieldPoolInfo) => void): Promise<VoidFunction>;
15
16
  parsePoolMemberMetadata(substrateApi: _SubstrateApi, poolMemberInfo: PalletNominationPoolsPoolMember): Promise<Omit<YieldPositionInfo, keyof BaseYieldPositionInfo>>;
16
17
  subscribePoolPosition(useAddresses: string[], resultCallback: (rs: YieldPositionInfo) => void): Promise<VoidFunction>;
17
18
  getPoolReward(useAddresses: string[], callBack: (rs: EarningRewardItem) => void): Promise<VoidFunction>;
19
+ getPoolRewardHistory(useAddresses: string[], callBack: (rs: EarningRewardHistoryItem) => void): Promise<VoidFunction>;
18
20
  getPoolTargets(): Promise<NominationPoolInfo[]>;
19
21
  get defaultSubmitStep(): YieldStepBaseInfo;
20
22
  protected getSubmitStep(params: OptimalYieldPathParams): Promise<YieldStepBaseInfo>;
@@ -10,10 +10,18 @@ import { EarningStatus, UnstakingStatus, YieldPoolType, YieldStepType } from '@s
10
10
  import { balanceFormatter, formatNumber, reformatAddress } from '@subwallet/extension-base/utils';
11
11
  import BigN from 'bignumber.js';
12
12
  import { t } from 'i18next';
13
- import { BN, BN_ZERO, hexToString, isHex } from '@polkadot/util';
13
+ import { BN, BN_ZERO, hexToString, isHex, noop } from '@polkadot/util';
14
14
  import BasePoolHandler from "../base.js";
15
15
  export default class NominationPoolHandler extends BasePoolHandler {
16
16
  type = YieldPoolType.NOMINATION_POOL;
17
+ availableMethod = {
18
+ join: true,
19
+ defaultUnstake: true,
20
+ fastUnstake: false,
21
+ cancelUnstake: false,
22
+ withdraw: true,
23
+ claimReward: true
24
+ };
17
25
  constructor(state, chain) {
18
26
  super(state, chain);
19
27
  const _chainAsset = this.nativeToken;
@@ -75,7 +83,8 @@ export default class NominationPoolHandler extends BasePoolHandler {
75
83
  const inflation = calculateInflation(bnTotalEraStake, bnTotalIssuance, numAuctions, chainInfo.slug);
76
84
  const minPoolJoin = (_minPoolJoin === null || _minPoolJoin === void 0 ? void 0 : _minPoolJoin.toString()) || undefined;
77
85
  const expectedReturn = calculateChainStakedReturn(inflation, bnTotalEraStake, bnTotalIssuance, chainInfo.slug);
78
- const unlockingPeriod = parseInt(unlockingEras) * (_STAKING_ERA_LENGTH_MAP[chainInfo.slug] || _STAKING_ERA_LENGTH_MAP.default); // in hours
86
+ const eraTime = _STAKING_ERA_LENGTH_MAP[this.chain] || _STAKING_ERA_LENGTH_MAP.default; // in hours
87
+ const unlockingPeriod = parseInt(unlockingEras) * eraTime; // in hours
79
88
 
80
89
  const minToHuman = formatNumber(minPoolJoin || '0', nativeToken.decimals || 0, balanceFormatter);
81
90
  const data = {
@@ -98,6 +107,7 @@ export default class NominationPoolHandler extends BasePoolHandler {
98
107
  farmerCount: 0,
99
108
  // TODO recheck
100
109
  era: parseInt(currentEra),
110
+ eraTime,
101
111
  tvl: bnTotalEraStake.toString(),
102
112
  // TODO recheck
103
113
  totalApy: expectedReturn,
@@ -265,6 +275,9 @@ export default class NominationPoolHandler extends BasePoolHandler {
265
275
  cancel = false;
266
276
  };
267
277
  }
278
+ async getPoolRewardHistory(useAddresses, callBack) {
279
+ return new Promise(resolve => resolve(noop));
280
+ }
268
281
 
269
282
  /* Get pool reward */
270
283
 
@@ -12,16 +12,13 @@ export default abstract class BaseSpecialStakingPoolHandler extends BasePoolHand
12
12
  protected abstract feeAssets: string[];
13
13
  /** Pool's type */
14
14
  abstract type: YieldPoolType.LIQUID_STAKING | YieldPoolType.LENDING;
15
- /** Allow to create default unstake transaction */
16
- protected readonly allowDefaultUnstake: boolean;
17
- /** Allow to create fast unstake transaction */
18
- protected readonly allowFastUnstake: boolean;
19
15
  protected get metadataInfo(): Omit<SpecialYieldPoolMetadata, 'description'>;
20
16
  get isPoolSupportAlternativeFee(): boolean;
21
17
  get group(): string;
22
18
  abstract getPoolStat(): Promise<SpecialYieldPoolInfo>;
23
19
  subscribePoolInfo(callback: (data: YieldPoolInfo) => void): Promise<VoidFunction>;
24
20
  getPoolReward(): Promise<VoidFunction>;
21
+ getPoolRewardHistory(): Promise<VoidFunction>;
25
22
  getPoolTargets(): Promise<YieldPoolTarget[]>;
26
23
  /**
27
24
  * @async
@@ -14,10 +14,6 @@ import BasePoolHandler from "./base.js";
14
14
  export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
15
15
  /** Pool's type */
16
16
 
17
- /** Allow to create default unstake transaction */
18
- allowDefaultUnstake = false;
19
- /** Allow to create fast unstake transaction */
20
- allowFastUnstake = true;
21
17
  get metadataInfo() {
22
18
  return {
23
19
  altInputAssets: this.altInputAsset,
@@ -29,9 +25,9 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
29
25
  shortName: this.shortName,
30
26
  name: this.name,
31
27
  isAvailable: true,
32
- allowCancelUnstaking: false,
33
28
  maintainAsset: this.nativeToken.slug,
34
- maintainBalance: this.maintainBalance
29
+ maintainBalance: this.maintainBalance,
30
+ availableMethod: this.availableMethod
35
31
  };
36
32
  }
37
33
  get isPoolSupportAlternativeFee() {
@@ -92,6 +88,9 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
92
88
  async getPoolReward() {
93
89
  return new Promise(resolve => resolve(noop));
94
90
  }
91
+ async getPoolRewardHistory() {
92
+ return new Promise(resolve => resolve(noop));
93
+ }
95
94
 
96
95
  /* Get pool reward */
97
96
 
@@ -359,10 +358,10 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
359
358
  if (!poolInfo || !poolInfo.statistic || !poolPosition) {
360
359
  return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
361
360
  }
362
- if (!this.allowDefaultUnstake && !fastLeave) {
361
+ if (!this.availableMethod.defaultUnstake && !fastLeave) {
363
362
  return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
364
363
  }
365
- if (!this.allowFastUnstake && fastLeave) {
364
+ if (!this.availableMethod.fastUnstake && fastLeave) {
366
365
  return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
367
366
  }
368
367
  const errors = [];
@@ -1,13 +1,14 @@
1
1
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
2
2
  import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
3
3
  import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
4
- import { EarningRewardItem, EarningRewardJson, HandleYieldStepData, HandleYieldStepParams, OptimalYieldPath, OptimalYieldPathParams, RequestEarlyValidateYield, RequestStakeCancelWithdrawal, RequestStakeClaimReward, RequestYieldLeave, RequestYieldWithdrawal, ResponseEarlyValidateYield, TransactionData, ValidateYieldProcessParams, YieldPoolInfo, YieldPoolTarget, YieldPositionInfo } from '@subwallet/extension-base/types';
4
+ import { EarningRewardHistoryItem, EarningRewardItem, EarningRewardJson, HandleYieldStepData, HandleYieldStepParams, OptimalYieldPath, OptimalYieldPathParams, RequestEarlyValidateYield, RequestStakeCancelWithdrawal, RequestStakeClaimReward, RequestYieldLeave, RequestYieldWithdrawal, ResponseEarlyValidateYield, TransactionData, ValidateYieldProcessParams, YieldPoolInfo, YieldPoolTarget, YieldPositionInfo } from '@subwallet/extension-base/types';
5
5
  import { BehaviorSubject } from 'rxjs';
6
6
  import { BasePoolHandler } from './handlers';
7
7
  export default class EarningService {
8
8
  protected readonly state: KoniState;
9
9
  protected handlers: Record<string, BasePoolHandler>;
10
10
  private earningRewardSubject;
11
+ private earningRewardHistorySubject;
11
12
  private minAmountPercentSubject;
12
13
  constructor(state: KoniState);
13
14
  private initHandlers;
@@ -17,10 +18,14 @@ export default class EarningService {
17
18
  getMinAmountPercent(): Record<string, number>;
18
19
  subscribePoolsInfo(callback: (rs: YieldPoolInfo) => void): Promise<VoidFunction>;
19
20
  subscribePoolPositions(addresses: string[], callback: (rs: YieldPositionInfo) => void): Promise<VoidFunction>;
20
- updateEarningReward(stakingRewardData: EarningRewardItem, callback?: (earningRewardData: EarningRewardJson) => void): void;
21
+ updateEarningReward(stakingRewardData: EarningRewardItem): void;
21
22
  getPoolReward(addresses: string[], callback: (result: EarningRewardItem) => void): Promise<VoidFunction>;
22
23
  subscribeEarningReward(): BehaviorSubject<EarningRewardJson>;
23
24
  getEarningRewards(): EarningRewardJson;
25
+ fetchPoolRewardHistory(addresses: string[], callback: (result: EarningRewardHistoryItem) => void): Promise<VoidFunction>;
26
+ updateEarningRewardHistory(earningRewardHistory: EarningRewardHistoryItem): void;
27
+ subscribeEarningRewardHistory(): BehaviorSubject<Record<string, EarningRewardHistoryItem>>;
28
+ getEarningRewardHistory(): Record<string, EarningRewardHistoryItem>;
24
29
  /**
25
30
  * @async
26
31
  * @function getPoolTargets
@@ -16,6 +16,7 @@ export default class EarningService {
16
16
  ready: false,
17
17
  data: {}
18
18
  });
19
+ earningRewardHistorySubject = new BehaviorSubject({});
19
20
  minAmountPercentSubject = new BehaviorSubject({});
20
21
  constructor(state) {
21
22
  this.state = state;
@@ -149,14 +150,11 @@ export default class EarningService {
149
150
 
150
151
  /* Get pools' reward */
151
152
 
152
- updateEarningReward(stakingRewardData, callback) {
153
+ updateEarningReward(stakingRewardData) {
153
154
  const stakingRewardState = this.earningRewardSubject.getValue();
154
155
  stakingRewardState.ready = true;
155
- const key = `${stakingRewardData.slug}___${stakingRewardData.address}`;
156
+ const key = `${stakingRewardData.slug}---${stakingRewardData.address}`;
156
157
  stakingRewardState.data[key] = stakingRewardData;
157
- if (callback) {
158
- callback(stakingRewardState);
159
- }
160
158
  this.earningRewardSubject.next(stakingRewardState);
161
159
  }
162
160
  async getPoolReward(addresses, callback) {
@@ -191,6 +189,44 @@ export default class EarningService {
191
189
  getEarningRewards() {
192
190
  return this.earningRewardSubject.getValue();
193
191
  }
192
+ async fetchPoolRewardHistory(addresses, callback) {
193
+ let cancel = false;
194
+ await this.state.eventService.waitChainReady;
195
+ const [substrateAddresses, evmAddresses] = categoryAddresses(addresses);
196
+ const activeChains = this.state.activeChainSlugs;
197
+ const unsubList = [];
198
+ for (const handler of Object.values(this.handlers)) {
199
+ if (activeChains.includes(handler.chain)) {
200
+ const chainInfo = handler.chainInfo;
201
+ const useAddresses = _isChainEvmCompatible(chainInfo) ? evmAddresses : substrateAddresses;
202
+ handler.getPoolRewardHistory(useAddresses, callback).then(unsub => {
203
+ if (cancel) {
204
+ unsub();
205
+ } else {
206
+ unsubList.push(unsub);
207
+ }
208
+ }).catch(console.error);
209
+ }
210
+ }
211
+ return () => {
212
+ cancel = true;
213
+ unsubList.forEach(unsub => {
214
+ unsub === null || unsub === void 0 ? void 0 : unsub();
215
+ });
216
+ };
217
+ }
218
+ updateEarningRewardHistory(earningRewardHistory) {
219
+ const earningRewardHistoryState = this.earningRewardHistorySubject.getValue();
220
+ const key = `${earningRewardHistory.slug}---${earningRewardHistory.address}---${earningRewardHistory.blockTimestamp}`;
221
+ earningRewardHistoryState[key] = earningRewardHistory;
222
+ this.earningRewardHistorySubject.next(earningRewardHistoryState);
223
+ }
224
+ subscribeEarningRewardHistory() {
225
+ return this.earningRewardHistorySubject;
226
+ }
227
+ getEarningRewardHistory() {
228
+ return this.earningRewardHistorySubject.getValue();
229
+ }
194
230
 
195
231
  /* Get pools' reward */
196
232
 
@@ -1,4 +1,4 @@
1
- import { CrowdloanContributionsResponse, ExtrinsicItem, ExtrinsicsListResponse, IMultiChainBalance, RequestBlockRange, SubscanRequest, TransferItem, TransfersListResponse } from '@subwallet/extension-base/services/subscan-service/types';
1
+ import { CrowdloanContributionsResponse, ExtrinsicItem, ExtrinsicsListResponse, IMultiChainBalance, RequestBlockRange, RewardHistoryListResponse, SubscanRequest, TransferItem, TransfersListResponse } from '@subwallet/extension-base/services/subscan-service/types';
2
2
  export declare class SubscanService {
3
3
  private subscanChainMap;
4
4
  private limitRate;
@@ -31,4 +31,5 @@ export declare class SubscanService {
31
31
  page: number;
32
32
  record: number;
33
33
  }): Promise<Record<string, TransferItem[]>>;
34
+ getRewardHistoryList(chain: string, address: string, page?: number): Promise<RewardHistoryListResponse>;
34
35
  }