@subwallet/extension-base 1.0.7-0 → 1.0.7-2

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 (64) hide show
  1. package/background/KoniTypes.d.ts +7 -8
  2. package/cjs/constants/index.js +1 -1
  3. package/cjs/koni/api/staking/bonding/amplitude.js +83 -0
  4. package/cjs/koni/api/staking/bonding/astar.js +109 -5
  5. package/cjs/koni/api/staking/bonding/index.js +35 -0
  6. package/cjs/koni/api/staking/bonding/paraChain.js +97 -0
  7. package/cjs/koni/api/staking/bonding/relayChain.js +203 -15
  8. package/cjs/koni/api/staking/bonding/utils.js +7 -0
  9. package/cjs/koni/api/staking/index.js +11 -11
  10. package/cjs/koni/api/staking/paraChain.js +200 -130
  11. package/cjs/koni/api/staking/relayChain.js +66 -68
  12. package/cjs/koni/api/staking/subsquidStaking.js +6 -11
  13. package/cjs/koni/background/cron.js +0 -25
  14. package/cjs/koni/background/handlers/Extension.js +98 -74
  15. package/cjs/koni/background/handlers/State.js +17 -19
  16. package/cjs/koni/background/subscription.js +57 -12
  17. package/cjs/packageInfo.js +1 -1
  18. package/cjs/services/chain-service/constants.js +3 -1
  19. package/cjs/services/chain-service/utils.js +6 -1
  20. package/cjs/services/storage-service/DatabaseService.js +7 -3
  21. package/cjs/services/storage-service/db-stores/ChainStakingMetadata.js +5 -0
  22. package/cjs/services/storage-service/db-stores/NominatorMetadata.js +4 -4
  23. package/cjs/services/transaction-service/index.js +6 -1
  24. package/constants/index.d.ts +1 -1
  25. package/constants/index.js +1 -1
  26. package/koni/api/staking/bonding/amplitude.d.ts +4 -0
  27. package/koni/api/staking/bonding/amplitude.js +81 -0
  28. package/koni/api/staking/bonding/astar.d.ts +4 -0
  29. package/koni/api/staking/bonding/astar.js +107 -5
  30. package/koni/api/staking/bonding/index.d.ts +1 -0
  31. package/koni/api/staking/bonding/index.js +38 -4
  32. package/koni/api/staking/bonding/paraChain.d.ts +4 -0
  33. package/koni/api/staking/bonding/paraChain.js +95 -0
  34. package/koni/api/staking/bonding/relayChain.d.ts +5 -0
  35. package/koni/api/staking/bonding/relayChain.js +198 -14
  36. package/koni/api/staking/bonding/utils.d.ts +5 -0
  37. package/koni/api/staking/bonding/utils.js +6 -0
  38. package/koni/api/staking/index.d.ts +4 -4
  39. package/koni/api/staking/index.js +11 -11
  40. package/koni/api/staking/paraChain.d.ts +5 -5
  41. package/koni/api/staking/paraChain.js +201 -131
  42. package/koni/api/staking/relayChain.d.ts +4 -4
  43. package/koni/api/staking/relayChain.js +66 -67
  44. package/koni/api/staking/subsquidStaking.d.ts +1 -1
  45. package/koni/api/staking/subsquidStaking.js +6 -11
  46. package/koni/background/cron.js +1 -26
  47. package/koni/background/handlers/Extension.js +29 -7
  48. package/koni/background/handlers/State.d.ts +2 -2
  49. package/koni/background/handlers/State.js +17 -19
  50. package/koni/background/subscription.d.ts +2 -1
  51. package/koni/background/subscription.js +58 -13
  52. package/package.json +5 -5
  53. package/packageInfo.js +1 -1
  54. package/services/chain-service/constants.d.ts +1 -0
  55. package/services/chain-service/constants.js +3 -2
  56. package/services/chain-service/types.d.ts +8 -0
  57. package/services/chain-service/utils.js +6 -1
  58. package/services/storage-service/DatabaseService.d.ts +2 -2
  59. package/services/storage-service/DatabaseService.js +7 -3
  60. package/services/storage-service/db-stores/ChainStakingMetadata.d.ts +1 -0
  61. package/services/storage-service/db-stores/ChainStakingMetadata.js +3 -0
  62. package/services/storage-service/db-stores/NominatorMetadata.d.ts +2 -2
  63. package/services/storage-service/db-stores/NominatorMetadata.js +4 -4
  64. package/services/transaction-service/index.js +6 -1
@@ -2,10 +2,10 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { StakingType } from '@subwallet/extension-base/background/KoniTypes';
5
- import { getAmplitudeBondingExtrinsic, getAmplitudeClaimRewardExtrinsic, getAmplitudeCollatorsInfo, getAmplitudeNominatorMetadata, getAmplitudeStakingMetadata, getAmplitudeUnbondingExtrinsic, getAmplitudeWithdrawalExtrinsic } from '@subwallet/extension-base/koni/api/staking/bonding/amplitude';
6
- import { getAstarBondingExtrinsic, getAstarClaimRewardExtrinsic, getAstarDappsInfo, getAstarNominatorMetadata, getAstarStakingMetadata, getAstarUnbondingExtrinsic, getAstarWithdrawalExtrinsic } from '@subwallet/extension-base/koni/api/staking/bonding/astar';
7
- import { getParaBondingExtrinsic, getParaCancelWithdrawalExtrinsic, getParachainCollatorsInfo, getParaChainNominatorMetadata, getParaChainStakingMetadata, getParaUnbondingExtrinsic, getParaWithdrawalExtrinsic, validateParaChainBondingCondition, validateParaChainUnbondingCondition } from '@subwallet/extension-base/koni/api/staking/bonding/paraChain';
8
- import { getPoolingClaimRewardExtrinsic, getPoolingWithdrawalExtrinsic, getRelayBondingExtrinsic, getRelayCancelWithdrawalExtrinsic, getRelayChainNominatorMetadata, getRelayChainStakingMetadata, getRelayPoolsInfo, getRelayUnbondingExtrinsic, getRelayValidatorsInfo, getRelayWithdrawalExtrinsic, validateRelayBondingCondition, validateRelayUnbondingCondition } from '@subwallet/extension-base/koni/api/staking/bonding/relayChain';
5
+ import { getAmplitudeBondingExtrinsic, getAmplitudeClaimRewardExtrinsic, getAmplitudeCollatorsInfo, getAmplitudeNominatorMetadata, getAmplitudeStakingMetadata, getAmplitudeUnbondingExtrinsic, getAmplitudeWithdrawalExtrinsic, subscribeAmplitudeStakingMetadata } from '@subwallet/extension-base/koni/api/staking/bonding/amplitude';
6
+ import { getAstarBondingExtrinsic, getAstarClaimRewardExtrinsic, getAstarDappsInfo, getAstarNominatorMetadata, getAstarStakingMetadata, getAstarUnbondingExtrinsic, getAstarWithdrawalExtrinsic, subscribeAstarStakingMetadata } from '@subwallet/extension-base/koni/api/staking/bonding/astar';
7
+ import { getParaBondingExtrinsic, getParaCancelWithdrawalExtrinsic, getParachainCollatorsInfo, getParaChainNominatorMetadata, getParaChainStakingMetadata, getParaUnbondingExtrinsic, getParaWithdrawalExtrinsic, subscribeParaChainStakingMetadata, validateParaChainBondingCondition, validateParaChainUnbondingCondition } from '@subwallet/extension-base/koni/api/staking/bonding/paraChain';
8
+ import { getPoolingClaimRewardExtrinsic, getPoolingWithdrawalExtrinsic, getRelayBondingExtrinsic, getRelayCancelWithdrawalExtrinsic, getRelayChainNominatorMetadata, getRelayChainStakingMetadata, getRelayPoolsInfo, getRelayUnbondingExtrinsic, getRelayValidatorsInfo, getRelayWithdrawalExtrinsic, subscribeRelayChainStakingMetadata, validateRelayBondingCondition, validateRelayUnbondingCondition } from '@subwallet/extension-base/koni/api/staking/bonding/relayChain';
9
9
  import { _STAKING_CHAIN_GROUP } from '@subwallet/extension-base/services/chain-service/constants';
10
10
  // all addresses must be converted to its chain format
11
11
 
@@ -100,4 +100,38 @@ export async function getCancelWithdrawalExtrinsic(substrateApi, chain, selected
100
100
  return getParaCancelWithdrawalExtrinsic(substrateApi, selectedUnstaking);
101
101
  }
102
102
  return getRelayCancelWithdrawalExtrinsic(substrateApi, selectedUnstaking);
103
+ }
104
+ export function subscribeEssentialChainStakingMetadata(substrateApiMap, chainInfoMap, callback) {
105
+ const unsubList = [];
106
+
107
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
108
+ Object.values(chainInfoMap).forEach(async chainInfo => {
109
+ const substrateApi = await substrateApiMap[chainInfo.slug].isReady;
110
+ if (_STAKING_CHAIN_GROUP.astar.includes(chainInfo.slug)) {
111
+ const unsub = await subscribeAstarStakingMetadata(chainInfo.slug, substrateApi, callback);
112
+
113
+ // @ts-ignore
114
+ unsubList.push(unsub);
115
+ } else if (_STAKING_CHAIN_GROUP.para.includes(chainInfo.slug)) {
116
+ const unsub = await subscribeParaChainStakingMetadata(chainInfo.slug, substrateApi, callback);
117
+
118
+ // @ts-ignore
119
+ unsubList.push(unsub);
120
+ } else if (_STAKING_CHAIN_GROUP.amplitude.includes(chainInfo.slug)) {
121
+ const unsub = await subscribeAmplitudeStakingMetadata(chainInfo.slug, substrateApi, callback);
122
+
123
+ // @ts-ignore
124
+ unsubList.push(unsub);
125
+ } else if (_STAKING_CHAIN_GROUP.relay.includes(chainInfo.slug)) {
126
+ const unsub = await subscribeRelayChainStakingMetadata(chainInfo, substrateApi, callback);
127
+
128
+ // @ts-ignore
129
+ unsubList.push(unsub);
130
+ }
131
+ });
132
+ return () => {
133
+ unsubList.forEach(unsub => {
134
+ unsub && unsub();
135
+ });
136
+ };
103
137
  }
@@ -1,10 +1,14 @@
1
1
  import { _ChainInfo } from '@subwallet/chain-list/types';
2
2
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
3
3
  import { ChainStakingMetadata, NominatorMetadata, UnstakingInfo, ValidatorInfo } from '@subwallet/extension-base/background/KoniTypes';
4
+ import { PalletParachainStakingDelegator } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
4
5
  import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
6
+ import { Codec } from '@polkadot/types/types';
5
7
  export declare function validateParaChainUnbondingCondition(amount: string, nominatorMetadata: NominatorMetadata, chainStakingMetadata: ChainStakingMetadata, selectedCollator: string): TransactionError[];
6
8
  export declare function validateParaChainBondingCondition(chainInfo: _ChainInfo, amount: string, selectedCollators: ValidatorInfo[], address: string, chainStakingMetadata: ChainStakingMetadata, nominatorMetadata?: NominatorMetadata): TransactionError[];
9
+ export declare function subscribeParaChainStakingMetadata(chain: string, substrateApi: _SubstrateApi, callback: (chain: string, rs: ChainStakingMetadata) => void): Promise<Codec>;
7
10
  export declare function getParaChainStakingMetadata(chain: string, substrateApi: _SubstrateApi): Promise<ChainStakingMetadata>;
11
+ export declare function subscribeParaChainNominatorMetadata(chainInfo: _ChainInfo, address: string, substrateApi: _SubstrateApi, delegatorState: PalletParachainStakingDelegator): Promise<NominatorMetadata>;
8
12
  export declare function getParaChainNominatorMetadata(chainInfo: _ChainInfo, address: string, substrateApi: _SubstrateApi): Promise<NominatorMetadata | undefined>;
9
13
  export declare function getParachainCollatorsInfo(chain: string, substrateApi: _SubstrateApi): Promise<ValidatorInfo[]>;
10
14
  export declare function getParaBondingExtrinsic(chainInfo: _ChainInfo, substrateApi: _SubstrateApi, amount: string, selectedCollatorInfo: ValidatorInfo, nominatorMetadata?: NominatorMetadata): Promise<import("@polkadot/api-base/types").SubmittableExtrinsic<"promise", import("@polkadot/types/types").ISubmittableResult>>;
@@ -81,6 +81,26 @@ export function validateParaChainBondingCondition(chainInfo, amount, selectedCol
81
81
  }
82
82
  return errors;
83
83
  }
84
+ export function subscribeParaChainStakingMetadata(chain, substrateApi, callback) {
85
+ return substrateApi.api.query.parachainStaking.round(_round => {
86
+ const roundObj = _round.toHuman();
87
+ const round = parseRawNumber(roundObj.current);
88
+ const maxDelegations = substrateApi.api.consts.parachainStaking.maxDelegationsPerDelegator.toString();
89
+ const unstakingDelay = substrateApi.api.consts.parachainStaking.delegationBondLessDelay.toString();
90
+ const unstakingPeriod = parseInt(unstakingDelay) * (_STAKING_ERA_LENGTH_MAP[chain] || _STAKING_ERA_LENGTH_MAP.default);
91
+ callback(chain, {
92
+ chain,
93
+ type: StakingType.NOMINATED,
94
+ era: round,
95
+ minStake: '0',
96
+ maxValidatorPerNominator: parseInt(maxDelegations),
97
+ maxWithdrawalRequestPerValidator: 1,
98
+ // by default
99
+ allowCancelUnstaking: true,
100
+ unstakingPeriod
101
+ });
102
+ });
103
+ }
84
104
  export async function getParaChainStakingMetadata(chain, substrateApi) {
85
105
  const chainApi = await substrateApi.isReady;
86
106
  const _round = (await chainApi.api.query.parachainStaking.round()).toHuman();
@@ -119,6 +139,81 @@ export async function getParaChainStakingMetadata(chain, substrateApi) {
119
139
  unstakingPeriod
120
140
  };
121
141
  }
142
+ export async function subscribeParaChainNominatorMetadata(chainInfo, address, substrateApi, delegatorState) {
143
+ const nominationList = [];
144
+ const unstakingMap = {};
145
+ let bnTotalActiveStake = BN_ZERO;
146
+ const _roundInfo = await substrateApi.api.query.parachainStaking.round();
147
+ const roundInfo = _roundInfo.toPrimitive();
148
+ const currentRound = roundInfo.current;
149
+ await Promise.all(delegatorState.delegations.map(async delegation => {
150
+ const [_delegationScheduledRequests, _identity, _collatorInfo] = await Promise.all([substrateApi.api.query.parachainStaking.delegationScheduledRequests(delegation.owner), substrateApi.api.query.identity.identityOf(delegation.owner), substrateApi.api.query.parachainStaking.candidateInfo(delegation.owner)]);
151
+ const collatorInfo = _collatorInfo.toPrimitive();
152
+ const minDelegation = collatorInfo === null || collatorInfo === void 0 ? void 0 : collatorInfo.lowestTopDelegationAmount.toString();
153
+ const identityInfo = _identity.toHuman();
154
+ const delegationScheduledRequests = _delegationScheduledRequests.toPrimitive();
155
+ const identity = parseIdentity(identityInfo);
156
+ let hasUnstaking = false;
157
+ let delegationStatus = StakingStatus.NOT_EARNING;
158
+
159
+ // parse unstaking info
160
+ if (delegationScheduledRequests) {
161
+ for (const scheduledRequest of delegationScheduledRequests) {
162
+ if (reformatAddress(scheduledRequest.delegator, 0) === reformatAddress(address, 0)) {
163
+ // add network prefix
164
+ const isClaimable = scheduledRequest.whenExecutable - currentRound <= 0;
165
+ const remainingEra = scheduledRequest.whenExecutable - (currentRound + 1);
166
+ const waitingTime = remainingEra * _STAKING_ERA_LENGTH_MAP[chainInfo.slug];
167
+ const claimable = Object.values(scheduledRequest.action)[0];
168
+ unstakingMap[delegation.owner] = {
169
+ chain: chainInfo.slug,
170
+ status: isClaimable ? UnstakingStatus.CLAIMABLE : UnstakingStatus.UNLOCKING,
171
+ validatorAddress: delegation.owner,
172
+ claimable: claimable.toString(),
173
+ waitingTime: waitingTime > 0 ? waitingTime : 0
174
+ };
175
+ hasUnstaking = true;
176
+ break; // only handle 1 scheduledRequest per collator
177
+ }
178
+ }
179
+ }
180
+
181
+ const bnStake = new BN(delegation.amount);
182
+ const bnUnstakeBalance = unstakingMap[delegation.owner] ? new BN(unstakingMap[delegation.owner].claimable) : BN_ZERO;
183
+ const bnActiveStake = bnStake.sub(bnUnstakeBalance);
184
+ if (bnActiveStake.gt(BN_ZERO) && bnActiveStake.gte(new BN(minDelegation))) {
185
+ delegationStatus = StakingStatus.EARNING_REWARD;
186
+ }
187
+ bnTotalActiveStake = bnTotalActiveStake.add(bnActiveStake);
188
+ nominationList.push({
189
+ chain: chainInfo.slug,
190
+ status: delegationStatus,
191
+ validatorAddress: delegation.owner,
192
+ validatorIdentity: identity,
193
+ activeStake: bnActiveStake.toString(),
194
+ hasUnstaking,
195
+ validatorMinStake: collatorInfo.lowestTopDelegationAmount.toString()
196
+ });
197
+ }));
198
+
199
+ // await Promise.all(nominationList.map(async (nomination) => {
200
+ // const _collatorInfo = await substrateApi.api.query.parachainStaking.candidateInfo(nomination.validatorAddress);
201
+ // const collatorInfo = _collatorInfo.toPrimitive() as unknown as ParachainStakingCandidateMetadata;
202
+ //
203
+ // nomination.validatorMinStake = collatorInfo.lowestTopDelegationAmount.toString();
204
+ // }));
205
+
206
+ const stakingStatus = getStakingStatusByNominations(bnTotalActiveStake, nominationList);
207
+ return {
208
+ chain: chainInfo.slug,
209
+ type: StakingType.NOMINATED,
210
+ status: stakingStatus,
211
+ address: address,
212
+ activeStake: bnTotalActiveStake.toString(),
213
+ nominations: nominationList,
214
+ unstakings: Object.values(unstakingMap)
215
+ };
216
+ }
122
217
  export async function getParaChainNominatorMetadata(chainInfo, address, substrateApi) {
123
218
  if (_isChainEvmCompatible(chainInfo) && !isEthereumAddress(address)) {
124
219
  return;
@@ -1,7 +1,9 @@
1
1
  import { _ChainInfo } from '@subwallet/chain-list/types';
2
2
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
3
3
  import { ChainStakingMetadata, NominationPoolInfo, NominatorMetadata, UnstakingInfo, ValidatorInfo } from '@subwallet/extension-base/background/KoniTypes';
4
+ import { PalletNominationPoolsPoolMember } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
4
5
  import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
6
+ import { Codec } from '@polkadot/types/types';
5
7
  export interface PalletStakingNominations {
6
8
  targets: string[];
7
9
  submittedIn: number;
@@ -21,8 +23,11 @@ export interface PalletStakingStakingLedger {
21
23
  export declare function validateRelayUnbondingCondition(amount: string, chainStakingMetadata: ChainStakingMetadata, nominatorMetadata: NominatorMetadata): TransactionError[];
22
24
  export declare function validatePoolBondingCondition(chainInfo: _ChainInfo, amount: string, selectedPool: NominationPoolInfo, address: string, chainStakingMetadata: ChainStakingMetadata, nominatorMetadata?: NominatorMetadata): TransactionError[];
23
25
  export declare function validateRelayBondingCondition(chainInfo: _ChainInfo, amount: string, selectedValidators: ValidatorInfo[], address: string, chainStakingMetadata: ChainStakingMetadata, nominatorMetadata?: NominatorMetadata): TransactionError[];
26
+ export declare function subscribeRelayChainStakingMetadata(chainInfo: _ChainInfo, substrateApi: _SubstrateApi, callback: (chain: string, rs: ChainStakingMetadata) => void): Promise<Codec>;
24
27
  export declare function getRelayChainStakingMetadata(chainInfo: _ChainInfo, substrateApi: _SubstrateApi): Promise<ChainStakingMetadata>;
28
+ export declare function subscribeRelayChainNominatorMetadata(chainInfo: _ChainInfo, address: string, substrateApi: _SubstrateApi, ledger: PalletStakingStakingLedger): Promise<NominatorMetadata>;
25
29
  export declare function getRelayChainNominatorMetadata(chainInfo: _ChainInfo, address: string, substrateApi: _SubstrateApi): Promise<NominatorMetadata | undefined>;
30
+ export declare function subscribeRelayChainPoolMemberMetadata(chainInfo: _ChainInfo, address: string, substrateApi: _SubstrateApi, poolMemberInfo: PalletNominationPoolsPoolMember): Promise<NominatorMetadata>;
26
31
  export declare function getRelayChainPoolMemberMetadata(chainInfo: _ChainInfo, address: string, substrateApi: _SubstrateApi): Promise<NominatorMetadata | undefined>;
27
32
  export declare function getRelayValidatorsInfo(chain: string, substrateApi: _SubstrateApi, decimals: number, chainStakingMetadata: ChainStakingMetadata): Promise<ValidatorInfo[]>;
28
33
  export declare function getRelayPoolsInfo(chain: string, substrateApi: _SubstrateApi): Promise<NominationPoolInfo[]>;
@@ -3,7 +3,7 @@
3
3
 
4
4
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
5
5
  import { StakingStatus, StakingTxErrorType, StakingType, UnstakingStatus } from '@subwallet/extension-base/background/KoniTypes';
6
- import { calculateAlephZeroValidatorReturn, calculateChainStakedReturn, calculateInflation, calculateValidatorStakedReturn, getCommission, parseIdentity, parsePoolStashAddress, transformPoolName } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
6
+ import { calculateAlephZeroValidatorReturn, calculateChainStakedReturn, calculateInflation, calculateTernoaValidatorReturn, calculateValidatorStakedReturn, getCommission, parseIdentity, parsePoolStashAddress, transformPoolName } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
7
7
  import { _STAKING_CHAIN_GROUP, _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
9
  import { reformatAddress } from '@subwallet/extension-base/utils';
@@ -34,7 +34,7 @@ export function validatePoolBondingCondition(chainInfo, amount, selectedPool, ad
34
34
  if (nominatorMetadata) {
35
35
  const bnCurrentActiveStake = new BN(nominatorMetadata.activeStake);
36
36
  bnTotalStake = bnTotalStake.add(bnCurrentActiveStake);
37
- if (nominatorMetadata.unstakings.length > 0) {
37
+ if (nominatorMetadata.unstakings.length > 0 && bnCurrentActiveStake.isZero()) {
38
38
  errors.push(new TransactionError(StakingTxErrorType.EXIST_UNSTAKING_REQUEST));
39
39
  }
40
40
  }
@@ -66,6 +66,35 @@ export function validateRelayBondingCondition(chainInfo, amount, selectedValidat
66
66
  }
67
67
  return errors;
68
68
  }
69
+ export function subscribeRelayChainStakingMetadata(chainInfo, substrateApi, callback) {
70
+ return substrateApi.api.query.staking.currentEra(async _currentEra => {
71
+ var _substrateApi$api$que, _substrateApi$api$que2, _substrateApi$api$que3, _substrateApi$api$que4, _substrateApi$api$que5, _substrateApi$api$que6;
72
+ const currentEra = _currentEra.toString();
73
+ const maxNominations = substrateApi.api.consts.staking.maxNominations.toString();
74
+ const maxUnlockingChunks = substrateApi.api.consts.staking.maxUnlockingChunks.toString();
75
+ const unlockingEras = substrateApi.api.consts.staking.bondingDuration.toString();
76
+ const [_minNominatorBond, _minPoolJoin, _minimumActiveStake] = await Promise.all([substrateApi.api.query.staking.minNominatorBond(), (_substrateApi$api$que = substrateApi.api.query) === null || _substrateApi$api$que === void 0 ? void 0 : (_substrateApi$api$que2 = _substrateApi$api$que.nominationPools) === null || _substrateApi$api$que2 === void 0 ? void 0 : _substrateApi$api$que2.minJoinBond(), ((_substrateApi$api$que3 = substrateApi.api.query) === null || _substrateApi$api$que3 === void 0 ? void 0 : (_substrateApi$api$que4 = _substrateApi$api$que3.staking) === null || _substrateApi$api$que4 === void 0 ? void 0 : _substrateApi$api$que4.minimumActiveStake) && ((_substrateApi$api$que5 = substrateApi.api.query) === null || _substrateApi$api$que5 === void 0 ? void 0 : (_substrateApi$api$que6 = _substrateApi$api$que5.staking) === null || _substrateApi$api$que6 === void 0 ? void 0 : _substrateApi$api$que6.minimumActiveStake())]);
77
+ const minActiveStake = (_minimumActiveStake === null || _minimumActiveStake === void 0 ? void 0 : _minimumActiveStake.toString()) || '0';
78
+ const minNominatorBond = _minNominatorBond.toString();
79
+ const bnMinActiveStake = new BN(minActiveStake);
80
+ const bnMinNominatorBond = new BN(minNominatorBond);
81
+ const minStake = bnMinActiveStake.gt(bnMinNominatorBond) ? bnMinActiveStake : bnMinNominatorBond;
82
+ const minPoolJoin = (_minPoolJoin === null || _minPoolJoin === void 0 ? void 0 : _minPoolJoin.toString()) || undefined;
83
+ const unlockingPeriod = parseInt(unlockingEras) * (_STAKING_ERA_LENGTH_MAP[chainInfo.slug] || _STAKING_ERA_LENGTH_MAP.default); // in hours
84
+
85
+ callback(chainInfo.slug, {
86
+ chain: chainInfo.slug,
87
+ type: StakingType.NOMINATED,
88
+ era: parseInt(currentEra),
89
+ minStake: minStake.toString(),
90
+ maxValidatorPerNominator: parseInt(maxNominations),
91
+ maxWithdrawalRequestPerValidator: parseInt(maxUnlockingChunks),
92
+ allowCancelUnstaking: true,
93
+ unstakingPeriod: unlockingPeriod,
94
+ minJoinNominationPool: minPoolJoin
95
+ });
96
+ });
97
+ }
69
98
  export async function getRelayChainStakingMetadata(chainInfo, substrateApi) {
70
99
  var _chainApi$api$query$a, _chainApi$api$query, _chainApi$api$query$s, _chainApi$api$query2, _chainApi$api$query2$, _chainApi$api$query3, _chainApi$api$query3$;
71
100
  const chain = chainInfo.slug;
@@ -77,16 +106,17 @@ export async function getRelayChainStakingMetadata(chainInfo, substrateApi) {
77
106
  const unlockingEras = chainApi.api.consts.staking.bondingDuration.toString();
78
107
  const [_totalEraStake, _totalIssuance, _auctionCounter, _minimumActiveStake, _minNominatorBond, _minPoolJoin, _eraStakers] = await Promise.all([chainApi.api.query.staking.erasTotalStake(parseInt(currentEra)), chainApi.api.query.balances.totalIssuance(), (_chainApi$api$query$a = chainApi.api.query.auctions) === null || _chainApi$api$query$a === void 0 ? void 0 : _chainApi$api$query$a.auctionCounter(), ((_chainApi$api$query = chainApi.api.query) === null || _chainApi$api$query === void 0 ? void 0 : (_chainApi$api$query$s = _chainApi$api$query.staking) === null || _chainApi$api$query$s === void 0 ? void 0 : _chainApi$api$query$s.minimumActiveStake) && ((_chainApi$api$query2 = chainApi.api.query) === null || _chainApi$api$query2 === void 0 ? void 0 : (_chainApi$api$query2$ = _chainApi$api$query2.staking) === null || _chainApi$api$query2$ === void 0 ? void 0 : _chainApi$api$query2$.minimumActiveStake()), chainApi.api.query.staking.minNominatorBond(), (_chainApi$api$query3 = chainApi.api.query) === null || _chainApi$api$query3 === void 0 ? void 0 : (_chainApi$api$query3$ = _chainApi$api$query3.nominationPools) === null || _chainApi$api$query3$ === void 0 ? void 0 : _chainApi$api$query3$.minJoinBond(), chainApi.api.query.staking.erasStakers.entries(parseInt(currentEra))]);
79
108
  const eraStakers = _eraStakers;
109
+ let allCurrentNominators = [];
80
110
  const nominatorList = [];
81
111
  for (const item of eraStakers) {
82
112
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
83
113
  const rawValidatorStat = item[1].toHuman();
84
114
  const eraNominators = rawValidatorStat.others;
85
- for (const nominator of eraNominators) {
86
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
87
- if (!nominatorList.includes(nominator.who)) {
88
- nominatorList.push(nominator.who);
89
- }
115
+ allCurrentNominators = allCurrentNominators.concat(eraNominators);
116
+ }
117
+ for (const nominator of allCurrentNominators) {
118
+ if (!nominatorList.includes(nominator.who)) {
119
+ nominatorList.push(nominator.who);
90
120
  }
91
121
  }
92
122
  const minActiveStake = (_minimumActiveStake === null || _minimumActiveStake === void 0 ? void 0 : _minimumActiveStake.toString()) || '0';
@@ -108,7 +138,7 @@ export async function getRelayChainStakingMetadata(chainInfo, substrateApi) {
108
138
  chain,
109
139
  type: StakingType.NOMINATED,
110
140
  era: parseInt(currentEra),
111
- expectedReturn,
141
+ expectedReturn: !_STAKING_CHAIN_GROUP.ternoa.includes(chain) ? expectedReturn : undefined,
112
142
  // in %, annually
113
143
  inflation,
114
144
  minStake: minStake.toString(),
@@ -120,14 +150,98 @@ export async function getRelayChainStakingMetadata(chainInfo, substrateApi) {
120
150
  nominatorCount: nominatorList.length
121
151
  };
122
152
  }
153
+ export async function subscribeRelayChainNominatorMetadata(chainInfo, address, substrateApi, ledger) {
154
+ var _chainApi$api$query4, _chainApi$api$query4$, _chainApi$api$query5, _chainApi$api$query5$, _chainApi$api$query6, _chainApi$api$query6$, _chainApi$api$query7, _chainApi$api$query7$, _chainApi$api$query8, _chainApi$api$query8$, _chainApi$api$query9, _chainApi$api$query9$;
155
+ const chain = chainInfo.slug;
156
+ const chainApi = await substrateApi.isReady;
157
+ const [_nominations, _currentEra, _bonded, _minimumActiveStake, _minNominatorBond] = await Promise.all([(_chainApi$api$query4 = chainApi.api.query) === null || _chainApi$api$query4 === void 0 ? void 0 : (_chainApi$api$query4$ = _chainApi$api$query4.staking) === null || _chainApi$api$query4$ === void 0 ? void 0 : _chainApi$api$query4$.nominators(address), (_chainApi$api$query5 = chainApi.api.query) === null || _chainApi$api$query5 === void 0 ? void 0 : (_chainApi$api$query5$ = _chainApi$api$query5.staking) === null || _chainApi$api$query5$ === void 0 ? void 0 : _chainApi$api$query5$.currentEra(), (_chainApi$api$query6 = chainApi.api.query) === null || _chainApi$api$query6 === void 0 ? void 0 : (_chainApi$api$query6$ = _chainApi$api$query6.staking) === null || _chainApi$api$query6$ === void 0 ? void 0 : _chainApi$api$query6$.bonded(address), ((_chainApi$api$query7 = chainApi.api.query) === null || _chainApi$api$query7 === void 0 ? void 0 : (_chainApi$api$query7$ = _chainApi$api$query7.staking) === null || _chainApi$api$query7$ === void 0 ? void 0 : _chainApi$api$query7$.minimumActiveStake) && ((_chainApi$api$query8 = chainApi.api.query) === null || _chainApi$api$query8 === void 0 ? void 0 : (_chainApi$api$query8$ = _chainApi$api$query8.staking) === null || _chainApi$api$query8$ === void 0 ? void 0 : _chainApi$api$query8$.minimumActiveStake()), (_chainApi$api$query9 = chainApi.api.query) === null || _chainApi$api$query9 === void 0 ? void 0 : (_chainApi$api$query9$ = _chainApi$api$query9.staking) === null || _chainApi$api$query9$ === void 0 ? void 0 : _chainApi$api$query9$.minNominatorBond()]);
158
+ const minActiveStake = (_minimumActiveStake === null || _minimumActiveStake === void 0 ? void 0 : _minimumActiveStake.toString()) || '0';
159
+ const minNominatorBond = _minNominatorBond.toString();
160
+ const bnMinActiveStake = new BN(minActiveStake);
161
+ const bnMinNominatorBond = new BN(minNominatorBond);
162
+ const minStake = bnMinActiveStake.gt(bnMinNominatorBond) ? bnMinActiveStake : bnMinNominatorBond;
163
+ const _maxNominatorRewardedPerValidator = chainApi.api.consts.staking.maxNominatorRewardedPerValidator.toString();
164
+ const maxNominatorRewardedPerValidator = parseInt(_maxNominatorRewardedPerValidator);
165
+ const nominations = _nominations.toPrimitive();
166
+ const currentEra = _currentEra.toString();
167
+ const bonded = _bonded.toHuman();
168
+ const activeStake = ledger.active.toString();
169
+ const nominationList = [];
170
+ const unstakingList = [];
171
+ if (nominations) {
172
+ const validatorList = nominations.targets;
173
+ await Promise.all(validatorList.map(async validatorAddress => {
174
+ let nominationStatus = StakingStatus.NOT_EARNING;
175
+ const [_identityInfo, _eraStaker] = await Promise.all([chainApi.api.query.identity.identityOf(validatorAddress), chainApi.api.query.staking.erasStakers(currentEra, validatorAddress)]);
176
+ const eraStaker = _eraStaker.toPrimitive();
177
+ const identityInfo = _identityInfo.toHuman();
178
+ const identity = parseIdentity(identityInfo);
179
+ const topNominators = eraStaker.others.map(nominator => {
180
+ return nominator.who;
181
+ });
182
+ if (!topNominators.includes(reformatAddress(address, _getChainSubstrateAddressPrefix(chainInfo)))) {
183
+ // if nominator has target but not in nominator list
184
+ nominationStatus = StakingStatus.WAITING;
185
+ } else if (topNominators.slice(0, maxNominatorRewardedPerValidator).includes(reformatAddress(address, _getChainSubstrateAddressPrefix(chainInfo)))) {
186
+ // if address in top nominators
187
+ nominationStatus = StakingStatus.EARNING_REWARD;
188
+ }
189
+ nominationList.push({
190
+ chain,
191
+ validatorAddress,
192
+ status: nominationStatus,
193
+ validatorIdentity: identity,
194
+ activeStake: '0' // relaychain allocates stake accordingly
195
+ });
196
+ }));
197
+ }
198
+
199
+ let stakingStatus = StakingStatus.NOT_EARNING;
200
+ const bnActiveStake = new BN(activeStake);
201
+ let waitingNominationCount = 0;
202
+ if (bnActiveStake.gte(minStake)) {
203
+ for (const nomination of nominationList) {
204
+ if (nomination.status === StakingStatus.EARNING_REWARD) {
205
+ // only need 1 earning nomination to count
206
+ stakingStatus = StakingStatus.EARNING_REWARD;
207
+ } else if (nomination.status === StakingStatus.WAITING) {
208
+ waitingNominationCount += 1;
209
+ }
210
+ }
211
+ if (waitingNominationCount === nominationList.length) {
212
+ stakingStatus = StakingStatus.WAITING;
213
+ }
214
+ }
215
+ ledger.unlocking.forEach(unlockingChunk => {
216
+ const isClaimable = unlockingChunk.era - parseInt(currentEra) <= 0;
217
+ const remainingEra = unlockingChunk.era - (parseInt(currentEra) + 1);
218
+ const waitingTime = remainingEra * _STAKING_ERA_LENGTH_MAP[chain];
219
+ unstakingList.push({
220
+ chain,
221
+ status: isClaimable ? UnstakingStatus.CLAIMABLE : UnstakingStatus.UNLOCKING,
222
+ claimable: unlockingChunk.value.toString(),
223
+ waitingTime: waitingTime > 0 ? waitingTime : 0
224
+ });
225
+ });
226
+ return {
227
+ chain,
228
+ type: StakingType.NOMINATED,
229
+ status: stakingStatus,
230
+ address: address,
231
+ activeStake,
232
+ nominations: nominationList,
233
+ unstakings: unstakingList,
234
+ isBondedBefore: bonded !== null
235
+ };
236
+ }
123
237
  export async function getRelayChainNominatorMetadata(chainInfo, address, substrateApi) {
124
- var _chainApi$api$query4, _chainApi$api$query4$, _chainApi$api$query5, _chainApi$api$query5$, _chainApi$api$query6, _chainApi$api$query6$, _chainApi$api$query7, _chainApi$api$query7$, _chainApi$api$query8, _chainApi$api$query8$, _chainApi$api$query9, _chainApi$api$query9$, _chainApi$api$query10, _chainApi$api$query11;
238
+ var _chainApi$api$query10, _chainApi$api$query11, _chainApi$api$query12, _chainApi$api$query13, _chainApi$api$query14, _chainApi$api$query15, _chainApi$api$query16, _chainApi$api$query17, _chainApi$api$query18, _chainApi$api$query19, _chainApi$api$query20, _chainApi$api$query21, _chainApi$api$query22, _chainApi$api$query23;
125
239
  if (isEthereumAddress(address)) {
126
240
  return;
127
241
  }
128
242
  const chain = chainInfo.slug;
129
243
  const chainApi = await substrateApi.isReady;
130
- const [_ledger, _nominations, _currentEra, _bonded, _minimumActiveStake, _minNominatorBond] = await Promise.all([(_chainApi$api$query4 = chainApi.api.query) === null || _chainApi$api$query4 === void 0 ? void 0 : (_chainApi$api$query4$ = _chainApi$api$query4.staking) === null || _chainApi$api$query4$ === void 0 ? void 0 : _chainApi$api$query4$.ledger(address), (_chainApi$api$query5 = chainApi.api.query) === null || _chainApi$api$query5 === void 0 ? void 0 : (_chainApi$api$query5$ = _chainApi$api$query5.staking) === null || _chainApi$api$query5$ === void 0 ? void 0 : _chainApi$api$query5$.nominators(address), (_chainApi$api$query6 = chainApi.api.query) === null || _chainApi$api$query6 === void 0 ? void 0 : (_chainApi$api$query6$ = _chainApi$api$query6.staking) === null || _chainApi$api$query6$ === void 0 ? void 0 : _chainApi$api$query6$.currentEra(), (_chainApi$api$query7 = chainApi.api.query) === null || _chainApi$api$query7 === void 0 ? void 0 : (_chainApi$api$query7$ = _chainApi$api$query7.staking) === null || _chainApi$api$query7$ === void 0 ? void 0 : _chainApi$api$query7$.bonded(address), ((_chainApi$api$query8 = chainApi.api.query) === null || _chainApi$api$query8 === void 0 ? void 0 : (_chainApi$api$query8$ = _chainApi$api$query8.staking) === null || _chainApi$api$query8$ === void 0 ? void 0 : _chainApi$api$query8$.minimumActiveStake) && ((_chainApi$api$query9 = chainApi.api.query) === null || _chainApi$api$query9 === void 0 ? void 0 : (_chainApi$api$query9$ = _chainApi$api$query9.staking) === null || _chainApi$api$query9$ === void 0 ? void 0 : _chainApi$api$query9$.minimumActiveStake()), (_chainApi$api$query10 = chainApi.api.query) === null || _chainApi$api$query10 === void 0 ? void 0 : (_chainApi$api$query11 = _chainApi$api$query10.staking) === null || _chainApi$api$query11 === void 0 ? void 0 : _chainApi$api$query11.minNominatorBond()]);
244
+ const [_ledger, _nominations, _currentEra, _bonded, _minimumActiveStake, _minNominatorBond] = await Promise.all([(_chainApi$api$query10 = chainApi.api.query) === null || _chainApi$api$query10 === void 0 ? void 0 : (_chainApi$api$query11 = _chainApi$api$query10.staking) === null || _chainApi$api$query11 === void 0 ? void 0 : _chainApi$api$query11.ledger(address), (_chainApi$api$query12 = chainApi.api.query) === null || _chainApi$api$query12 === void 0 ? void 0 : (_chainApi$api$query13 = _chainApi$api$query12.staking) === null || _chainApi$api$query13 === void 0 ? void 0 : _chainApi$api$query13.nominators(address), (_chainApi$api$query14 = chainApi.api.query) === null || _chainApi$api$query14 === void 0 ? void 0 : (_chainApi$api$query15 = _chainApi$api$query14.staking) === null || _chainApi$api$query15 === void 0 ? void 0 : _chainApi$api$query15.currentEra(), (_chainApi$api$query16 = chainApi.api.query) === null || _chainApi$api$query16 === void 0 ? void 0 : (_chainApi$api$query17 = _chainApi$api$query16.staking) === null || _chainApi$api$query17 === void 0 ? void 0 : _chainApi$api$query17.bonded(address), ((_chainApi$api$query18 = chainApi.api.query) === null || _chainApi$api$query18 === void 0 ? void 0 : (_chainApi$api$query19 = _chainApi$api$query18.staking) === null || _chainApi$api$query19 === void 0 ? void 0 : _chainApi$api$query19.minimumActiveStake) && ((_chainApi$api$query20 = chainApi.api.query) === null || _chainApi$api$query20 === void 0 ? void 0 : (_chainApi$api$query21 = _chainApi$api$query20.staking) === null || _chainApi$api$query21 === void 0 ? void 0 : _chainApi$api$query21.minimumActiveStake()), (_chainApi$api$query22 = chainApi.api.query) === null || _chainApi$api$query22 === void 0 ? void 0 : (_chainApi$api$query23 = _chainApi$api$query22.staking) === null || _chainApi$api$query23 === void 0 ? void 0 : _chainApi$api$query23.minNominatorBond()]);
131
245
  const minActiveStake = (_minimumActiveStake === null || _minimumActiveStake === void 0 ? void 0 : _minimumActiveStake.toString()) || '0';
132
246
  const minNominatorBond = _minNominatorBond.toString();
133
247
  const bnMinActiveStake = new BN(minActiveStake);
@@ -219,6 +333,67 @@ export async function getRelayChainNominatorMetadata(chainInfo, address, substra
219
333
  isBondedBefore: bonded !== null
220
334
  };
221
335
  }
336
+ export async function subscribeRelayChainPoolMemberMetadata(chainInfo, address, substrateApi, poolMemberInfo) {
337
+ const _maxNominatorRewardedPerValidator = substrateApi.api.consts.staking.maxNominatorRewardedPerValidator.toString();
338
+ const maxNominatorRewardedPerValidator = parseInt(_maxNominatorRewardedPerValidator);
339
+ const poolsPalletId = substrateApi.api.consts.nominationPools.palletId.toString();
340
+ const poolStashAccount = parsePoolStashAddress(substrateApi.api, 0, poolMemberInfo.poolId, poolsPalletId);
341
+ const [_nominations, _poolMetadata, _currentEra] = await Promise.all([substrateApi.api.query.staking.nominators(poolStashAccount), substrateApi.api.query.nominationPools.metadata(poolMemberInfo.poolId), substrateApi.api.query.staking.currentEra()]);
342
+ const poolMetadata = _poolMetadata.toPrimitive();
343
+ const currentEra = _currentEra.toString();
344
+ const nominations = _nominations.toJSON();
345
+ let stakingStatus = StakingStatus.NOT_EARNING;
346
+ const poolName = transformPoolName(poolMetadata.isUtf8 ? poolMetadata.toUtf8() : poolMetadata.toString());
347
+ if (nominations) {
348
+ const validatorList = nominations.targets;
349
+ await Promise.all(validatorList.map(async validatorAddress => {
350
+ const _eraStaker = await substrateApi.api.query.staking.erasStakers(currentEra, validatorAddress);
351
+ const eraStaker = _eraStaker.toPrimitive();
352
+ const topNominators = eraStaker.others.map(nominator => {
353
+ return nominator.who;
354
+ }).slice(0, maxNominatorRewardedPerValidator);
355
+ if (topNominators.includes(reformatAddress(poolStashAccount, _getChainSubstrateAddressPrefix(chainInfo)))) {
356
+ // if address in top nominators
357
+ stakingStatus = StakingStatus.EARNING_REWARD;
358
+ }
359
+ }));
360
+ }
361
+ const joinedPoolInfo = {
362
+ activeStake: poolMemberInfo.points.toString(),
363
+ chain: chainInfo.slug,
364
+ status: stakingStatus,
365
+ validatorIdentity: poolName,
366
+ validatorAddress: poolMemberInfo.poolId.toString(),
367
+ // use poolId
368
+ hasUnstaking: poolMemberInfo.unbondingEras && Object.keys(poolMemberInfo.unbondingEras).length > 0
369
+ };
370
+ const unstakings = [];
371
+ Object.entries(poolMemberInfo.unbondingEras).forEach(([unlockingEra, amount]) => {
372
+ const isClaimable = parseInt(unlockingEra) - parseInt(currentEra) <= 0;
373
+ const remainingEra = parseInt(unlockingEra) - (parseInt(currentEra) + 1);
374
+ const waitingTime = remainingEra * _STAKING_ERA_LENGTH_MAP[chainInfo.slug];
375
+ unstakings.push({
376
+ chain: chainInfo.slug,
377
+ status: isClaimable ? UnstakingStatus.CLAIMABLE : UnstakingStatus.UNLOCKING,
378
+ claimable: amount.toString(),
379
+ waitingTime: waitingTime > 0 ? waitingTime : 0
380
+ });
381
+ });
382
+ const bnActiveStake = new BN(poolMemberInfo.points.toString());
383
+ if (!bnActiveStake.gt(BN_ZERO)) {
384
+ stakingStatus = StakingStatus.NOT_EARNING;
385
+ }
386
+ return {
387
+ chain: chainInfo.slug,
388
+ type: StakingType.POOLED,
389
+ address,
390
+ status: stakingStatus,
391
+ activeStake: poolMemberInfo.points.toString(),
392
+ nominations: [joinedPoolInfo],
393
+ // can only join 1 pool at a time
394
+ unstakings
395
+ };
396
+ }
222
397
  export async function getRelayChainPoolMemberMetadata(chainInfo, address, substrateApi) {
223
398
  const chainApi = await substrateApi.isReady;
224
399
  const [_poolMemberInfo, _currentEra] = await Promise.all([chainApi.api.query.nominationPools.poolMembers(address), chainApi.api.query.staking.currentEra()]);
@@ -302,7 +477,8 @@ export async function getRelayValidatorsInfo(chain, substrateApi, decimals, chai
302
477
  const currentEra = _era.toString();
303
478
  const allValidators = [];
304
479
  const validatorInfoList = [];
305
- const [_totalEraStake, _eraStakers, _minBond] = await Promise.all([chainApi.api.query.staking.erasTotalStake(parseInt(currentEra)), chainApi.api.query.staking.erasStakers.entries(parseInt(currentEra)), chainApi.api.query.staking.minNominatorBond()]);
480
+ const [_totalEraStake, _eraStakers, _minBond, _stakingRewards] = await Promise.all([chainApi.api.query.staking.erasTotalStake(parseInt(currentEra)), chainApi.api.query.staking.erasStakers.entries(parseInt(currentEra)), chainApi.api.query.staking.minNominatorBond(), chainApi.api.query.stakingRewards && chainApi.api.query.stakingRewards.data()]);
481
+ const stakingRewards = _stakingRewards === null || _stakingRewards === void 0 ? void 0 : _stakingRewards.toPrimitive();
306
482
  const maxNominatorRewarded = chainApi.api.consts.staking.maxNominatorRewardedPerValidator.toString();
307
483
  const bnTotalEraStake = new BN(_totalEraStake.toString());
308
484
  const eraStakers = _eraStakers;
@@ -345,9 +521,9 @@ export async function getRelayValidatorsInfo(chain, substrateApi, decimals, chai
345
521
  }
346
522
  const extraInfoMap = {};
347
523
  await Promise.all(allValidators.map(async address => {
348
- var _chainApi$api$query12, _chainApi$api$query13, _identityInfo$judgeme;
524
+ var _chainApi$api$query24, _chainApi$api$query25, _identityInfo$judgeme;
349
525
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
350
- const [_commissionInfo, _identityInfo] = await Promise.all([chainApi.api.query.staking.validators(address), (_chainApi$api$query12 = chainApi.api.query) === null || _chainApi$api$query12 === void 0 ? void 0 : (_chainApi$api$query13 = _chainApi$api$query12.identity) === null || _chainApi$api$query13 === void 0 ? void 0 : _chainApi$api$query13.identityOf(address)]);
526
+ const [_commissionInfo, _identityInfo] = await Promise.all([chainApi.api.query.staking.validators(address), (_chainApi$api$query24 = chainApi.api.query) === null || _chainApi$api$query24 === void 0 ? void 0 : (_chainApi$api$query25 = _chainApi$api$query24.identity) === null || _chainApi$api$query25 === void 0 ? void 0 : _chainApi$api$query25.identityOf(address)]);
351
527
  const commissionInfo = _commissionInfo.toHuman();
352
528
  const identityInfo = _identityInfo ? _identityInfo.toHuman() : null;
353
529
  let identity;
@@ -365,7 +541,15 @@ export async function getRelayValidatorsInfo(chain, substrateApi, decimals, chai
365
541
  for (const validator of validatorInfoList) {
366
542
  const commission = extraInfoMap[validator.address].commission;
367
543
  const bnValidatorStake = totalStakeMap[validator.address].div(bnDecimals);
368
- validator.expectedReturn = _STAKING_CHAIN_GROUP.aleph.includes(chain) ? calculateAlephZeroValidatorReturn(chainStakingMetadata.expectedReturn, getCommission(commission)) : calculateValidatorStakedReturn(chainStakingMetadata.expectedReturn, bnValidatorStake, bnAvgStake, getCommission(commission));
544
+ if (_STAKING_CHAIN_GROUP.aleph.includes(chain)) {
545
+ validator.expectedReturn = calculateAlephZeroValidatorReturn(chainStakingMetadata.expectedReturn, getCommission(commission));
546
+ } else if (_STAKING_CHAIN_GROUP.ternoa.includes(chain)) {
547
+ const rewardPerValidator = new BN(stakingRewards.sessionExtraRewardPayout).divn(allValidators.length).div(bnDecimals);
548
+ const validatorStake = totalStakeMap[validator.address].div(bnDecimals).toNumber();
549
+ validator.expectedReturn = calculateTernoaValidatorReturn(rewardPerValidator.toNumber(), validatorStake, getCommission(commission));
550
+ } else {
551
+ validator.expectedReturn = calculateValidatorStakedReturn(chainStakingMetadata.expectedReturn, bnValidatorStake, bnAvgStake, getCommission(commission));
552
+ }
369
553
  validator.commission = parseFloat(commission.split('%')[0]);
370
554
  validator.blocked = extraInfoMap[validator.address].blocked;
371
555
  validator.identity = extraInfoMap[validator.address].identity;
@@ -102,6 +102,10 @@ export interface Unlocking {
102
102
  remainingEras: BN;
103
103
  value: BN;
104
104
  }
105
+ export interface TernoaStakingRewardsStakingRewardsData {
106
+ sessionEraPayout: string;
107
+ sessionExtraRewardPayout: string;
108
+ }
105
109
  export declare function parsePoolStashAddress(api: ApiPromise, index: number, poolId: number, poolsPalletId: string): string;
106
110
  export declare function transformPoolName(input: string): string;
107
111
  export declare function parseIdentity(identityInfo: PalletIdentityRegistration | null): string | undefined;
@@ -111,6 +115,7 @@ export declare function calcInflationRewardCurve(minInflation: number, stakedFra
111
115
  export declare function calculateInflation(totalEraStake: BN, totalIssuance: BN, numAuctions: number, networkKey: string): number;
112
116
  export declare function calculateChainStakedReturn(inflation: number, totalEraStake: BN, totalIssuance: BN, networkKey: string): number;
113
117
  export declare function calculateAlephZeroValidatorReturn(chainStakedReturn: number, commission: number): number;
118
+ export declare function calculateTernoaValidatorReturn(rewardPerValidator: number, validatorStake: number, commission: number): number;
114
119
  export declare function calculateValidatorStakedReturn(chainStakedReturn: number, totalValidatorStake: BN, avgStake: BN, commission: number): number;
115
120
  export declare function getCommission(commissionString: string): number;
116
121
  export interface InflationConfig {
@@ -86,6 +86,12 @@ export function calculateChainStakedReturn(inflation, totalEraStake, totalIssuan
86
86
  export function calculateAlephZeroValidatorReturn(chainStakedReturn, commission) {
87
87
  return chainStakedReturn * (100 - commission) / 100;
88
88
  }
89
+ export function calculateTernoaValidatorReturn(rewardPerValidator, validatorStake, commission) {
90
+ const percentRewardForNominators = (100 - commission) / 100;
91
+ const rewardForNominators = rewardPerValidator * percentRewardForNominators;
92
+ const stakeRatio = rewardForNominators / validatorStake;
93
+ return stakeRatio * 365 * 100;
94
+ }
89
95
  export function calculateValidatorStakedReturn(chainStakedReturn, totalValidatorStake, avgStake, commission) {
90
96
  const bnAdjusted = avgStake.mul(BN_HUNDRED).div(totalValidatorStake);
91
97
  const adjusted = bnAdjusted.toNumber() * chainStakedReturn;
@@ -1,6 +1,6 @@
1
1
  import { _ChainInfo } from '@subwallet/chain-list/types';
2
- import { StakingItem, StakingRewardItem } from '@subwallet/extension-base/background/KoniTypes';
2
+ import { NominatorMetadata, StakingItem, StakingRewardItem } from '@subwallet/extension-base/background/KoniTypes';
3
3
  import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
4
- export declare function stakingOnChainApi(addresses: string[], substrateApiMap: Record<string, _SubstrateApi>, callback: (networkKey: string, rs: StakingItem) => void, chainInfoMap: Record<string, _ChainInfo>): () => void;
5
- export declare function getNominationStakingRewardData(addresses: string[], chainInfoMap: Record<string, _ChainInfo>): Promise<StakingRewardItem[]>;
6
- export declare function getPoolingStakingRewardData(addresses: string[], networkMap: Record<string, _ChainInfo>, dotSamaApiMap: Record<string, _SubstrateApi>): Promise<StakingRewardItem[]>;
4
+ export declare function stakingOnChainApi(addresses: string[], substrateApiMap: Record<string, _SubstrateApi>, chainInfoMap: Record<string, _ChainInfo>, stakingCallback: (networkKey: string, rs: StakingItem) => void, nominatorStateCallback: (nominatorMetadata: NominatorMetadata) => void): () => void;
5
+ export declare function getNominationStakingRewardData(addresses: string[], chainInfoMap: Record<string, _ChainInfo>, callback: (rewardItem: StakingRewardItem) => void): Promise<void>;
6
+ export declare function getPoolingStakingRewardData(addresses: string[], networkMap: Record<string, _ChainInfo>, dotSamaApiMap: Record<string, _SubstrateApi>, callback: (rs: StakingRewardItem) => void): Promise<void>;
@@ -7,7 +7,7 @@ import { getAllSubsquidStaking } from '@subwallet/extension-base/koni/api/stakin
7
7
  import { _PURE_EVM_CHAINS, _STAKING_CHAIN_GROUP } from '@subwallet/extension-base/services/chain-service/constants';
8
8
  import { _isChainEvmCompatible, _isChainSupportSubstrateStaking, _isSubstrateRelayChain } from '@subwallet/extension-base/services/chain-service/utils';
9
9
  import { categoryAddresses } from '@subwallet/extension-base/utils';
10
- export function stakingOnChainApi(addresses, substrateApiMap, callback, chainInfoMap) {
10
+ export function stakingOnChainApi(addresses, substrateApiMap, chainInfoMap, stakingCallback, nominatorStateCallback) {
11
11
  const filteredApiMap = [];
12
12
  const [substrateAddresses, evmAddresses] = categoryAddresses(addresses);
13
13
  Object.entries(chainInfoMap).forEach(([networkKey, chainInfo]) => {
@@ -28,20 +28,20 @@ export function stakingOnChainApi(addresses, substrateApiMap, callback, chainInf
28
28
  const parentApi = await apiPromise.isReady;
29
29
  const useAddresses = _isChainEvmCompatible(chainInfoMap[chain]) ? evmAddresses : substrateAddresses;
30
30
  if (_STAKING_CHAIN_GROUP.amplitude.includes(chain)) {
31
- const unsub = await getAmplitudeStakingOnChain(parentApi, useAddresses, chainInfoMap, chain, callback);
31
+ const unsub = await getAmplitudeStakingOnChain(parentApi, useAddresses, chainInfoMap, chain, stakingCallback, nominatorStateCallback);
32
32
  unsubList.push(unsub);
33
33
  } else if (_STAKING_CHAIN_GROUP.astar.includes(chain)) {
34
- const unsub = await getAstarStakingOnChain(parentApi, useAddresses, chainInfoMap, chain, callback);
34
+ const unsub = await getAstarStakingOnChain(parentApi, useAddresses, chainInfoMap, chain, stakingCallback, nominatorStateCallback);
35
35
  unsubList.push(unsub);
36
36
  } else if (_STAKING_CHAIN_GROUP.para.includes(chain)) {
37
- const unsub = await getParaStakingOnChain(parentApi, useAddresses, chainInfoMap, chain, callback);
37
+ const unsub = await getParaStakingOnChain(parentApi, useAddresses, chainInfoMap, chain, stakingCallback, nominatorStateCallback);
38
38
  unsubList.push(unsub);
39
39
  } else if (_STAKING_CHAIN_GROUP.relay.includes(chain)) {
40
- const unsub = await getRelayStakingOnChain(parentApi, useAddresses, chainInfoMap, chain, callback);
40
+ const unsub = await getRelayStakingOnChain(parentApi, useAddresses, chainInfoMap, chain, stakingCallback, nominatorStateCallback);
41
41
  unsubList.push(unsub);
42
42
  }
43
43
  if (_STAKING_CHAIN_GROUP.nominationPool.includes(chain)) {
44
- const unsub = await getRelayPoolingOnChain(parentApi, useAddresses, chainInfoMap, chain, callback);
44
+ const unsub = await getRelayPoolingOnChain(parentApi, useAddresses, chainInfoMap, chain, stakingCallback, nominatorStateCallback);
45
45
  unsubList.push(unsub);
46
46
  }
47
47
  });
@@ -51,11 +51,11 @@ export function stakingOnChainApi(addresses, substrateApiMap, callback, chainInf
51
51
  });
52
52
  };
53
53
  }
54
- export async function getNominationStakingRewardData(addresses, chainInfoMap) {
54
+ export async function getNominationStakingRewardData(addresses, chainInfoMap, callback) {
55
55
  // might retrieve from other sources
56
- return await getAllSubsquidStaking(addresses, chainInfoMap);
56
+ await getAllSubsquidStaking(addresses, chainInfoMap, callback);
57
57
  }
58
- export async function getPoolingStakingRewardData(addresses, networkMap, dotSamaApiMap) {
58
+ export async function getPoolingStakingRewardData(addresses, networkMap, dotSamaApiMap, callback) {
59
59
  const activeNetworks = [];
60
60
  Object.entries(networkMap).forEach(([key, chainInfo]) => {
61
61
  if (_isChainSupportSubstrateStaking(chainInfo) && _isSubstrateRelayChain(chainInfo)) {
@@ -63,7 +63,7 @@ export async function getPoolingStakingRewardData(addresses, networkMap, dotSama
63
63
  }
64
64
  });
65
65
  if (activeNetworks.length === 0) {
66
- return [];
66
+ return;
67
67
  }
68
- return getNominationPoolReward(addresses, networkMap, dotSamaApiMap);
68
+ await getNominationPoolReward(addresses, networkMap, dotSamaApiMap, callback);
69
69
  }