@subwallet/extension-base 1.0.6-2 → 1.0.7-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.
- package/background/KoniTypes.d.ts +11 -5
- package/cjs/constants/index.js +1 -1
- package/cjs/koni/api/staking/bonding/amplitude.js +83 -0
- package/cjs/koni/api/staking/bonding/astar.js +104 -1
- package/cjs/koni/api/staking/bonding/index.js +35 -0
- package/cjs/koni/api/staking/bonding/paraChain.js +97 -0
- package/cjs/koni/api/staking/bonding/relayChain.js +191 -12
- package/cjs/koni/api/staking/index.js +11 -11
- package/cjs/koni/api/staking/paraChain.js +200 -130
- package/cjs/koni/api/staking/relayChain.js +66 -68
- package/cjs/koni/api/staking/subsquidStaking.js +6 -11
- package/cjs/koni/background/cron.js +0 -25
- package/cjs/koni/background/handlers/State.js +18 -19
- package/cjs/koni/background/handlers/Tabs.js +68 -19
- package/cjs/koni/background/subscription.js +57 -12
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/chain-service/utils.js +6 -1
- package/cjs/services/migration-service/index.js +2 -2
- package/cjs/services/request-service/handler/EvmRequestHandler.js +23 -0
- package/cjs/services/request-service/index.js +5 -0
- package/cjs/services/storage-service/DatabaseService.js +7 -3
- package/cjs/services/storage-service/db-stores/ChainStakingMetadata.js +5 -0
- package/cjs/services/storage-service/db-stores/NominatorMetadata.js +4 -4
- package/cjs/services/transaction-service/index.js +6 -1
- package/constants/index.d.ts +1 -1
- package/constants/index.js +1 -1
- package/koni/api/staking/bonding/amplitude.d.ts +4 -0
- package/koni/api/staking/bonding/amplitude.js +81 -0
- package/koni/api/staking/bonding/astar.d.ts +4 -0
- package/koni/api/staking/bonding/astar.js +102 -1
- package/koni/api/staking/bonding/index.d.ts +1 -0
- package/koni/api/staking/bonding/index.js +38 -4
- package/koni/api/staking/bonding/paraChain.d.ts +4 -0
- package/koni/api/staking/bonding/paraChain.js +95 -0
- package/koni/api/staking/bonding/relayChain.d.ts +5 -0
- package/koni/api/staking/bonding/relayChain.js +185 -10
- package/koni/api/staking/index.d.ts +4 -4
- package/koni/api/staking/index.js +11 -11
- package/koni/api/staking/paraChain.d.ts +5 -5
- package/koni/api/staking/paraChain.js +201 -131
- package/koni/api/staking/relayChain.d.ts +4 -4
- package/koni/api/staking/relayChain.js +66 -67
- package/koni/api/staking/subsquidStaking.d.ts +1 -1
- package/koni/api/staking/subsquidStaking.js +6 -11
- package/koni/background/cron.js +1 -26
- package/koni/background/handlers/State.d.ts +2 -2
- package/koni/background/handlers/State.js +18 -19
- package/koni/background/handlers/Tabs.js +68 -19
- package/koni/background/subscription.d.ts +2 -1
- package/koni/background/subscription.js +58 -13
- package/package.json +6 -6
- package/packageInfo.js +1 -1
- package/services/chain-service/types.d.ts +3 -0
- package/services/chain-service/utils.js +6 -1
- package/services/migration-service/index.js +2 -2
- package/services/request-service/handler/EvmRequestHandler.d.ts +1 -0
- package/services/request-service/handler/EvmRequestHandler.js +21 -0
- package/services/request-service/index.d.ts +1 -0
- package/services/request-service/index.js +3 -0
- package/services/storage-service/DatabaseService.d.ts +2 -2
- package/services/storage-service/DatabaseService.js +7 -3
- package/services/storage-service/db-stores/ChainStakingMetadata.d.ts +1 -0
- package/services/storage-service/db-stores/ChainStakingMetadata.js +3 -0
- package/services/storage-service/db-stores/NominatorMetadata.d.ts +2 -2
- package/services/storage-service/db-stores/NominatorMetadata.js +4 -4
- package/services/transaction-service/index.js +6 -1
|
@@ -7,6 +7,30 @@ import { _STAKING_ERA_LENGTH_MAP } from '@subwallet/extension-base/services/chai
|
|
|
7
7
|
import { parseRawNumber, reformatAddress } from '@subwallet/extension-base/utils';
|
|
8
8
|
import { BN, BN_ZERO } from '@polkadot/util';
|
|
9
9
|
import { isEthereumAddress } from '@polkadot/util-crypto';
|
|
10
|
+
export function subscribeAmplitudeStakingMetadata(chain, substrateApi, callback) {
|
|
11
|
+
return substrateApi.api.query.parachainStaking.round(_round => {
|
|
12
|
+
const roundObj = _round.toHuman();
|
|
13
|
+
const round = parseRawNumber(roundObj.current);
|
|
14
|
+
const maxDelegations = substrateApi.api.consts.parachainStaking.maxDelegationsPerRound.toString();
|
|
15
|
+
const minDelegatorStake = substrateApi.api.consts.parachainStaking.minDelegatorStake.toString();
|
|
16
|
+
const unstakingDelay = substrateApi.api.consts.parachainStaking.stakeDuration.toString();
|
|
17
|
+
const _blockPerRound = substrateApi.api.consts.parachainStaking.defaultBlocksPerRound.toString();
|
|
18
|
+
const blockPerRound = parseFloat(_blockPerRound);
|
|
19
|
+
const blockDuration = (_STAKING_ERA_LENGTH_MAP[chain] || _STAKING_ERA_LENGTH_MAP.default) / blockPerRound; // in hours
|
|
20
|
+
const unstakingPeriod = blockDuration * parseInt(unstakingDelay);
|
|
21
|
+
callback(chain, {
|
|
22
|
+
chain,
|
|
23
|
+
type: StakingType.NOMINATED,
|
|
24
|
+
era: round,
|
|
25
|
+
minStake: minDelegatorStake,
|
|
26
|
+
maxValidatorPerNominator: parseInt(maxDelegations),
|
|
27
|
+
maxWithdrawalRequestPerValidator: 1,
|
|
28
|
+
// by default
|
|
29
|
+
allowCancelUnstaking: true,
|
|
30
|
+
unstakingPeriod
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
}
|
|
10
34
|
export async function getAmplitudeStakingMetadata(chain, substrateApi) {
|
|
11
35
|
const chainApi = await substrateApi.isReady;
|
|
12
36
|
const _round = (await chainApi.api.query.parachainStaking.round()).toHuman();
|
|
@@ -30,6 +54,63 @@ export async function getAmplitudeStakingMetadata(chain, substrateApi) {
|
|
|
30
54
|
unstakingPeriod
|
|
31
55
|
};
|
|
32
56
|
}
|
|
57
|
+
export async function subscribeAmplitudeNominatorMetadata(chainInfo, address, substrateApi, delegatorState, unstakingInfo) {
|
|
58
|
+
const nominationList = [];
|
|
59
|
+
const unstakingList = [];
|
|
60
|
+
const minDelegatorStake = substrateApi.api.consts.parachainStaking.minDelegatorStake.toString();
|
|
61
|
+
let activeStake = '0';
|
|
62
|
+
if (delegatorState) {
|
|
63
|
+
// delegatorState can be null while unstaking all
|
|
64
|
+
const identityInfo = substrateApi.api.query.identity ? (await substrateApi.api.query.identity.identityOf(delegatorState.owner)).toPrimitive() : undefined;
|
|
65
|
+
const identity = identityInfo ? parseIdentity(identityInfo) : undefined;
|
|
66
|
+
activeStake = delegatorState.amount.toString();
|
|
67
|
+
const bnActiveStake = new BN(activeStake);
|
|
68
|
+
let delegationStatus = StakingStatus.NOT_EARNING;
|
|
69
|
+
if (bnActiveStake.gt(BN_ZERO) && bnActiveStake.gte(new BN(minDelegatorStake))) {
|
|
70
|
+
delegationStatus = StakingStatus.EARNING_REWARD;
|
|
71
|
+
}
|
|
72
|
+
nominationList.push({
|
|
73
|
+
status: delegationStatus,
|
|
74
|
+
chain: chainInfo.slug,
|
|
75
|
+
validatorAddress: delegatorState.owner,
|
|
76
|
+
activeStake: delegatorState.amount.toString(),
|
|
77
|
+
validatorMinStake: '0',
|
|
78
|
+
hasUnstaking: !!unstakingInfo && Object.values(unstakingInfo).length > 0,
|
|
79
|
+
validatorIdentity: identity
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
if (unstakingInfo && Object.values(unstakingInfo).length > 0) {
|
|
83
|
+
const _currentBlockInfo = await substrateApi.api.rpc.chain.getHeader();
|
|
84
|
+
const currentBlockInfo = _currentBlockInfo.toPrimitive();
|
|
85
|
+
const currentBlockNumber = currentBlockInfo.number;
|
|
86
|
+
const _blockPerRound = substrateApi.api.consts.parachainStaking.defaultBlocksPerRound.toString();
|
|
87
|
+
const blockPerRound = parseFloat(_blockPerRound);
|
|
88
|
+
const nearestUnstakingBlock = Object.keys(unstakingInfo)[0];
|
|
89
|
+
const nearestUnstakingAmount = Object.values(unstakingInfo)[0];
|
|
90
|
+
const blockDuration = (_STAKING_ERA_LENGTH_MAP[chainInfo.slug] || _STAKING_ERA_LENGTH_MAP.default) / blockPerRound; // in hours
|
|
91
|
+
|
|
92
|
+
const isClaimable = parseInt(nearestUnstakingBlock) - currentBlockNumber <= 0;
|
|
93
|
+
const remainingBlock = parseInt(nearestUnstakingBlock) - (currentBlockNumber + 1);
|
|
94
|
+
const waitingTime = remainingBlock * blockDuration;
|
|
95
|
+
unstakingList.push({
|
|
96
|
+
chain: chainInfo.slug,
|
|
97
|
+
status: isClaimable ? UnstakingStatus.CLAIMABLE : UnstakingStatus.UNLOCKING,
|
|
98
|
+
claimable: nearestUnstakingAmount.toString(),
|
|
99
|
+
waitingTime: waitingTime > 0 ? waitingTime : 0,
|
|
100
|
+
validatorAddress: (delegatorState === null || delegatorState === void 0 ? void 0 : delegatorState.owner) || undefined
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
const stakingStatus = getStakingStatusByNominations(new BN(activeStake), nominationList);
|
|
104
|
+
return {
|
|
105
|
+
chain: chainInfo.slug,
|
|
106
|
+
type: StakingType.NOMINATED,
|
|
107
|
+
status: stakingStatus,
|
|
108
|
+
address: address,
|
|
109
|
+
activeStake: activeStake,
|
|
110
|
+
nominations: nominationList,
|
|
111
|
+
unstakings: unstakingList
|
|
112
|
+
};
|
|
113
|
+
}
|
|
33
114
|
export async function getAmplitudeNominatorMetadata(chainInfo, address, substrateApi) {
|
|
34
115
|
if (isEthereumAddress(address)) {
|
|
35
116
|
return;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { _ChainInfo } from '@subwallet/chain-list/types';
|
|
2
2
|
import { ChainStakingMetadata, NominatorMetadata, UnstakingInfo, ValidatorInfo } from '@subwallet/extension-base/background/KoniTypes';
|
|
3
|
+
import { PalletDappsStakingAccountLedger } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
|
|
3
4
|
import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
|
|
5
|
+
import { Codec } from '@polkadot/types/types';
|
|
6
|
+
export declare function subscribeAstarStakingMetadata(chain: string, substrateApi: _SubstrateApi, callback: (chain: string, rs: ChainStakingMetadata) => void): Promise<Codec>;
|
|
4
7
|
export declare function getAstarStakingMetadata(chain: string, substrateApi: _SubstrateApi): Promise<ChainStakingMetadata>;
|
|
8
|
+
export declare function subscribeAstarNominatorMetadata(chainInfo: _ChainInfo, address: string, substrateApi: _SubstrateApi, ledger: PalletDappsStakingAccountLedger): Promise<NominatorMetadata>;
|
|
5
9
|
export declare function getAstarNominatorMetadata(chainInfo: _ChainInfo, address: string, substrateApi: _SubstrateApi): Promise<NominatorMetadata | undefined>;
|
|
6
10
|
export declare function getAstarDappsInfo(networkKey: string, substrateApi: _SubstrateApi): Promise<ValidatorInfo[]>;
|
|
7
11
|
export declare function getAstarBondingExtrinsic(substrateApi: _SubstrateApi, amount: string, dappInfo: ValidatorInfo): Promise<import("@polkadot/api-base/types").SubmittableExtrinsic<"promise", import("@polkadot/types/types").ISubmittableResult>>;
|
|
@@ -8,6 +8,26 @@ import { isUrl, parseRawNumber } from '@subwallet/extension-base/utils';
|
|
|
8
8
|
import fetch from 'cross-fetch';
|
|
9
9
|
import { BN, BN_ZERO } from '@polkadot/util';
|
|
10
10
|
import { isEthereumAddress } from '@polkadot/util-crypto';
|
|
11
|
+
export function subscribeAstarStakingMetadata(chain, substrateApi, callback) {
|
|
12
|
+
return substrateApi.api.query.dappsStaking.currentEra(_currentEra => {
|
|
13
|
+
const era = _currentEra.toString();
|
|
14
|
+
const minDelegatorStake = substrateApi.api.consts.dappsStaking.minimumStakingAmount.toString();
|
|
15
|
+
const unstakingDelay = substrateApi.api.consts.dappsStaking.unbondingPeriod.toString();
|
|
16
|
+
const unstakingPeriod = parseInt(unstakingDelay) * _STAKING_ERA_LENGTH_MAP[chain];
|
|
17
|
+
callback(chain, {
|
|
18
|
+
chain,
|
|
19
|
+
type: StakingType.NOMINATED,
|
|
20
|
+
era: parseInt(era),
|
|
21
|
+
minStake: minDelegatorStake,
|
|
22
|
+
maxValidatorPerNominator: 100,
|
|
23
|
+
// temporary fix for Astar, there's no limit for now
|
|
24
|
+
maxWithdrawalRequestPerValidator: 1,
|
|
25
|
+
// by default
|
|
26
|
+
allowCancelUnstaking: true,
|
|
27
|
+
unstakingPeriod
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|
|
11
31
|
export async function getAstarStakingMetadata(chain, substrateApi) {
|
|
12
32
|
const aprPromise = new Promise(function (resolve) {
|
|
13
33
|
fetch(`https://api.astar.network/api/v1/${chain}/dapps-staking/apr`, {
|
|
@@ -43,6 +63,87 @@ export async function getAstarStakingMetadata(chain, substrateApi) {
|
|
|
43
63
|
unstakingPeriod
|
|
44
64
|
};
|
|
45
65
|
}
|
|
66
|
+
export async function subscribeAstarNominatorMetadata(chainInfo, address, substrateApi, ledger) {
|
|
67
|
+
const nominationList = [];
|
|
68
|
+
const unstakingList = [];
|
|
69
|
+
const allDappsReq = new Promise(function (resolve) {
|
|
70
|
+
fetch(`https://api.astar.network/api/v1/${chainInfo.slug}/dapps-staking/dapps`, {
|
|
71
|
+
method: 'GET'
|
|
72
|
+
}).then(resp => {
|
|
73
|
+
resolve(resp.json());
|
|
74
|
+
}).catch(console.error);
|
|
75
|
+
});
|
|
76
|
+
const [_allDapps, _era, _stakerInfo] = await Promise.all([allDappsReq, substrateApi.api.query.dappsStaking.currentEra(), substrateApi.api.query.dappsStaking.generalStakerInfo.entries(address)]);
|
|
77
|
+
const currentEra = _era.toString();
|
|
78
|
+
const minDelegatorStake = substrateApi.api.consts.dappsStaking.minimumStakingAmount.toString();
|
|
79
|
+
const allDapps = _allDapps;
|
|
80
|
+
let bnTotalActiveStake = BN_ZERO;
|
|
81
|
+
if (_stakerInfo.length > 0) {
|
|
82
|
+
const dAppInfoMap = {};
|
|
83
|
+
allDapps.forEach(dappInfo => {
|
|
84
|
+
dAppInfoMap[dappInfo.address.toLowerCase()] = dappInfo;
|
|
85
|
+
});
|
|
86
|
+
for (const item of _stakerInfo) {
|
|
87
|
+
const data = item[0].toHuman();
|
|
88
|
+
const stakedDapp = data[1];
|
|
89
|
+
const stakeData = item[1].toPrimitive();
|
|
90
|
+
const stakeList = stakeData.stakes;
|
|
91
|
+
const dappAddress = stakedDapp.Evm ? stakedDapp.Evm.toLowerCase() : stakedDapp.Wasm;
|
|
92
|
+
const currentStake = stakeList.slice(-1)[0].staked.toString() || '0';
|
|
93
|
+
const bnCurrentStake = new BN(currentStake);
|
|
94
|
+
if (bnCurrentStake.gt(BN_ZERO)) {
|
|
95
|
+
const dappStakingStatus = bnCurrentStake.gt(BN_ZERO) && bnCurrentStake.gte(new BN(minDelegatorStake)) ? StakingStatus.EARNING_REWARD : StakingStatus.NOT_EARNING;
|
|
96
|
+
bnTotalActiveStake = bnTotalActiveStake.add(bnCurrentStake);
|
|
97
|
+
const dappInfo = dAppInfoMap[dappAddress];
|
|
98
|
+
nominationList.push({
|
|
99
|
+
status: dappStakingStatus,
|
|
100
|
+
chain: chainInfo.slug,
|
|
101
|
+
validatorAddress: dappAddress.toLowerCase(),
|
|
102
|
+
activeStake: currentStake,
|
|
103
|
+
validatorMinStake: '0',
|
|
104
|
+
validatorIdentity: dappInfo === null || dappInfo === void 0 ? void 0 : dappInfo.name,
|
|
105
|
+
hasUnstaking: false // cannot get unstaking info by dapp
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const unlockingChunks = ledger.unbondingInfo.unlockingChunks;
|
|
112
|
+
if (unlockingChunks.length > 0) {
|
|
113
|
+
for (const unlockingChunk of unlockingChunks) {
|
|
114
|
+
const isClaimable = unlockingChunk.unlockEra - parseInt(currentEra) <= 0;
|
|
115
|
+
const remainingEra = unlockingChunk.unlockEra - (parseInt(currentEra) + 1);
|
|
116
|
+
const waitingTime = remainingEra * _STAKING_ERA_LENGTH_MAP[chainInfo.slug];
|
|
117
|
+
unstakingList.push({
|
|
118
|
+
chain: chainInfo.slug,
|
|
119
|
+
status: isClaimable ? UnstakingStatus.CLAIMABLE : UnstakingStatus.UNLOCKING,
|
|
120
|
+
claimable: unlockingChunk.amount.toString(),
|
|
121
|
+
waitingTime: waitingTime > 0 ? waitingTime : 0
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (nominationList.length === 0 && unstakingList.length === 0) {
|
|
126
|
+
return {
|
|
127
|
+
chain: chainInfo.slug,
|
|
128
|
+
type: StakingType.NOMINATED,
|
|
129
|
+
address,
|
|
130
|
+
status: StakingStatus.NOT_STAKING,
|
|
131
|
+
activeStake: '0',
|
|
132
|
+
nominations: [],
|
|
133
|
+
unstakings: []
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
const stakingStatus = getStakingStatusByNominations(bnTotalActiveStake, nominationList);
|
|
137
|
+
return {
|
|
138
|
+
chain: chainInfo.slug,
|
|
139
|
+
type: StakingType.NOMINATED,
|
|
140
|
+
address: address,
|
|
141
|
+
activeStake: bnTotalActiveStake.toString(),
|
|
142
|
+
nominations: nominationList,
|
|
143
|
+
unstakings: unstakingList,
|
|
144
|
+
status: stakingStatus
|
|
145
|
+
};
|
|
146
|
+
}
|
|
46
147
|
export async function getAstarNominatorMetadata(chainInfo, address, substrateApi) {
|
|
47
148
|
if (isEthereumAddress(address)) {
|
|
48
149
|
return;
|
|
@@ -167,7 +268,7 @@ export async function getAstarDappsInfo(networkKey, substrateApi) {
|
|
|
167
268
|
allDappsInfo.push({
|
|
168
269
|
commission: 0,
|
|
169
270
|
expectedReturn: 0,
|
|
170
|
-
address: dappAddress.toLowerCase(),
|
|
271
|
+
address: isEthereumAddress(dappAddress) ? dappAddress.toLowerCase() : dappAddress,
|
|
171
272
|
totalStake: totalStake,
|
|
172
273
|
ownStake: '0',
|
|
173
274
|
otherStake: totalStake.toString(),
|
|
@@ -13,3 +13,4 @@ export declare function getUnbondingExtrinsic(nominatorMetadata: NominatorMetada
|
|
|
13
13
|
export declare function getWithdrawalExtrinsic(substrateApi: _SubstrateApi, chain: string, nominatorMetadata: NominatorMetadata, validatorAddress?: string): Promise<import("@polkadot/api-base/types").SubmittableExtrinsic<"promise", import("@polkadot/types/types").ISubmittableResult>>;
|
|
14
14
|
export declare function getClaimRewardExtrinsic(substrateApi: _SubstrateApi, chain: string, address: string, stakingType: StakingType, bondReward?: boolean): Promise<import("@polkadot/api-base/types").SubmittableExtrinsic<"promise", import("@polkadot/types/types").ISubmittableResult>>;
|
|
15
15
|
export declare function getCancelWithdrawalExtrinsic(substrateApi: _SubstrateApi, chain: string, selectedUnstaking: UnstakingInfo): Promise<import("@polkadot/api-base/types").SubmittableExtrinsic<"promise", import("@polkadot/types/types").ISubmittableResult>>;
|
|
16
|
+
export declare function subscribeEssentialChainStakingMetadata(substrateApiMap: Record<string, _SubstrateApi>, chainInfoMap: Record<string, _ChainInfo>, callback: (chain: string, rs: ChainStakingMetadata) => void): () => void;
|
|
@@ -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[]>;
|