@subwallet/extension-base 1.1.34-0 → 1.1.35-beta.0
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 +111 -69
- package/background/KoniTypes.js +19 -13
- package/background/errors/TransactionError.js +9 -0
- package/cjs/background/KoniTypes.js +20 -16
- package/cjs/background/errors/TransactionError.js +9 -0
- package/cjs/constants/index.js +19 -4
- package/cjs/constants/staking.js +1 -1
- package/cjs/koni/api/dotsama/balance.js +464 -0
- package/cjs/koni/api/nft/config.js +33 -23
- package/cjs/koni/api/nft/index.js +14 -0
- package/cjs/koni/api/nft/nft.js +1 -22
- package/cjs/koni/api/nft/ordinal_nft/constants.js +21 -0
- package/cjs/koni/api/nft/ordinal_nft/index.js +121 -0
- package/cjs/koni/api/nft/ordinal_nft/utils.js +41 -0
- package/cjs/koni/api/staking/bonding/amplitude.js +19 -16
- package/cjs/koni/api/staking/bonding/astar.js +11 -10
- package/cjs/koni/api/staking/bonding/index.js +4 -1
- package/cjs/koni/api/staking/bonding/paraChain.js +25 -23
- package/cjs/koni/api/staking/bonding/relayChain.js +48 -45
- package/cjs/koni/api/staking/bonding/utils.js +104 -86
- package/cjs/koni/api/staking/index.js +6 -5
- package/cjs/koni/api/staking/paraChain.js +6 -5
- package/cjs/koni/api/staking/relayChain.js +3 -2
- package/cjs/koni/api/yield/helper/utils.js +46 -0
- package/cjs/koni/background/cron.js +3 -21
- package/cjs/koni/background/handlers/Extension.js +368 -69
- package/cjs/koni/background/handlers/State.js +18 -12
- package/cjs/koni/background/handlers/index.js +4 -2
- package/cjs/koni/background/subscription.js +7 -104
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/campaign-service/index.js +9 -6
- package/cjs/services/chain-service/constants.js +2 -17
- package/cjs/services/chain-service/index.js +50 -3
- package/cjs/services/chain-service/utils.js +7 -1
- package/cjs/services/earning-service/constants/chains.js +30 -0
- package/cjs/services/earning-service/constants/index.js +27 -0
- package/cjs/services/earning-service/constants/step.js +18 -0
- package/cjs/services/earning-service/handlers/base.js +262 -0
- package/cjs/services/earning-service/handlers/index.js +60 -0
- package/cjs/services/earning-service/handlers/lending/base.js +81 -0
- package/cjs/services/earning-service/handlers/lending/index.js +13 -0
- package/cjs/services/earning-service/handlers/lending/interlay.js +192 -0
- package/cjs/services/earning-service/handlers/liquid-staking/acala.js +240 -0
- package/cjs/services/earning-service/handlers/liquid-staking/base.js +97 -0
- package/cjs/services/earning-service/handlers/liquid-staking/bifrost-manta.js +140 -0
- package/cjs/services/earning-service/handlers/liquid-staking/bifrost.js +298 -0
- package/cjs/services/earning-service/handlers/liquid-staking/index.js +34 -0
- package/cjs/services/earning-service/handlers/liquid-staking/parallel.js +227 -0
- package/cjs/services/earning-service/handlers/liquid-staking/stella-swap.js +404 -0
- package/cjs/services/earning-service/handlers/native-staking/amplitude.js +434 -0
- package/cjs/services/earning-service/handlers/native-staking/astar.js +466 -0
- package/cjs/services/earning-service/handlers/native-staking/base-para.js +146 -0
- package/cjs/services/earning-service/handlers/native-staking/base.js +161 -0
- package/cjs/services/earning-service/handlers/native-staking/index.js +34 -0
- package/cjs/services/earning-service/handlers/native-staking/para-chain.js +390 -0
- package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +567 -0
- package/cjs/services/earning-service/handlers/nomination-pool/index.js +566 -0
- package/cjs/services/earning-service/handlers/special.js +493 -0
- package/cjs/services/earning-service/service.js +733 -0
- package/cjs/services/earning-service/utils/index.js +128 -0
- package/cjs/services/event-service/index.js +5 -0
- package/cjs/services/keyring-service/index.js +14 -2
- package/cjs/services/migration-service/scripts/DeleteEarningData.js +21 -0
- package/cjs/services/migration-service/scripts/EnableEarningChains.js +21 -0
- package/cjs/services/migration-service/scripts/MigrateEthProvider.js +17 -0
- package/cjs/services/migration-service/scripts/MigrateLedgerAccount.js +1 -1
- package/cjs/services/migration-service/scripts/MigratePioneerProvider.js +17 -0
- package/cjs/services/migration-service/scripts/MigrateProvider.js +29 -0
- package/cjs/services/migration-service/scripts/MigrateTransactionHistory.js +1 -1
- package/cjs/services/migration-service/scripts/databases/MigrateEarningHistory.js +21 -0
- package/cjs/services/migration-service/scripts/databases/MigrateEarningVersion.js +21 -0
- package/cjs/services/migration-service/scripts/index.js +6 -1
- package/cjs/services/mint-campaign-service/campaigns/UnlockDotCampaign.js +149 -0
- package/cjs/services/mint-campaign-service/campaigns/index.js +13 -0
- package/cjs/services/mint-campaign-service/constants.js +11 -0
- package/cjs/services/mint-campaign-service/index.js +18 -0
- package/cjs/services/notification-service/NotificationService.js +3 -2
- package/cjs/services/request-service/handler/PopupHandler.js +2 -3
- package/cjs/services/storage-service/DatabaseService.js +97 -0
- package/cjs/services/storage-service/databases/index.js +4 -0
- package/cjs/services/storage-service/db-stores/AssetRef.js +24 -0
- package/cjs/services/storage-service/db-stores/NominatorMetadata.js +3 -3
- package/cjs/services/storage-service/db-stores/YieldPoolStore.js +36 -0
- package/cjs/services/storage-service/db-stores/YieldPositionStore.js +71 -0
- package/cjs/services/storage-service/index.js +241 -0
- package/cjs/services/subscan-service/index.js +16 -0
- package/cjs/services/transaction-service/event-parser/index.js +58 -0
- package/cjs/services/transaction-service/helpers/index.js +3 -1
- package/cjs/services/transaction-service/index.js +249 -75
- package/cjs/services/transaction-service/utils.js +1 -0
- package/cjs/types/campaigns/index.js +16 -0
- package/cjs/types/campaigns/unlock-dot.js +1 -0
- package/cjs/types/index.js +44 -0
- package/cjs/types/ordinal.js +1 -0
- package/cjs/types/transaction.js +1 -0
- package/cjs/types/yield/actions/index.js +27 -0
- package/cjs/types/yield/actions/join/index.js +38 -0
- package/cjs/types/yield/actions/join/step.js +47 -0
- package/cjs/types/yield/actions/join/submit.js +1 -0
- package/cjs/types/yield/actions/join/validate.js +16 -0
- package/cjs/types/yield/actions/others.js +1 -0
- package/cjs/types/yield/index.js +27 -0
- package/cjs/types/yield/info/account/index.js +49 -0
- package/cjs/types/yield/info/account/info.js +1 -0
- package/cjs/types/yield/info/account/reward.js +1 -0
- package/cjs/types/yield/info/account/target.js +32 -0
- package/cjs/types/yield/info/account/unstake.js +27 -0
- package/cjs/types/yield/info/base.js +41 -0
- package/cjs/types/yield/info/chain/index.js +27 -0
- package/cjs/types/yield/info/chain/info.js +1 -0
- package/cjs/types/yield/info/chain/target.js +1 -0
- package/cjs/types/yield/info/index.js +49 -0
- package/cjs/types/yield/info/pallet.js +15 -0
- package/cjs/types.js +1 -0
- package/cjs/utils/address.js +34 -0
- package/cjs/utils/environment.js +23 -28
- package/cjs/utils/fetchStaticCache.js +22 -0
- package/cjs/utils/fetchStaticData.js +2 -1
- package/cjs/utils/index.js +94 -10
- package/cjs/utils/keyring.js +57 -0
- package/cjs/utils/mv3.js +14 -0
- package/cjs/utils/number.js +6 -2
- package/cjs/utils/object.js +12 -0
- package/constants/index.d.ts +6 -1
- package/constants/index.js +6 -1
- package/constants/staking.js +1 -1
- package/koni/api/nft/config.js +33 -23
- package/koni/api/nft/index.js +15 -1
- package/koni/api/nft/nft.js +2 -23
- package/koni/api/nft/ordinal_nft/constants.d.ts +9 -0
- package/koni/api/nft/ordinal_nft/constants.js +12 -0
- package/koni/api/nft/ordinal_nft/index.d.ts +8 -0
- package/koni/api/nft/ordinal_nft/index.js +114 -0
- package/koni/api/nft/ordinal_nft/utils.d.ts +2 -0
- package/koni/api/nft/ordinal_nft/utils.js +33 -0
- package/koni/api/staking/bonding/amplitude.js +13 -10
- package/koni/api/staking/bonding/astar.js +9 -8
- package/koni/api/staking/bonding/index.d.ts +1 -1
- package/koni/api/staking/bonding/index.js +5 -1
- package/koni/api/staking/bonding/paraChain.js +12 -10
- package/koni/api/staking/bonding/relayChain.d.ts +2 -2
- package/koni/api/staking/bonding/relayChain.js +33 -30
- package/koni/api/staking/bonding/utils.d.ts +15 -38
- package/koni/api/staking/bonding/utils.js +85 -69
- package/koni/api/staking/index.js +2 -1
- package/koni/api/staking/paraChain.js +7 -6
- package/koni/api/staking/relayChain.js +4 -3
- package/koni/api/yield/helper/utils.d.ts +10 -0
- package/koni/api/yield/helper/utils.js +32 -0
- package/koni/background/cron.d.ts +0 -4
- package/koni/background/cron.js +4 -22
- package/koni/background/handlers/Extension.d.ts +17 -1
- package/koni/background/handlers/Extension.js +327 -30
- package/koni/background/handlers/State.d.ts +6 -1
- package/koni/background/handlers/State.js +17 -12
- package/koni/background/handlers/index.js +4 -2
- package/koni/background/subscription.d.ts +1 -6
- package/koni/background/subscription.js +8 -104
- package/package.json +335 -7
- package/packageInfo.js +1 -1
- package/services/campaign-service/index.js +9 -6
- package/services/chain-service/constants.d.ts +1 -13
- package/services/chain-service/constants.js +1 -15
- package/services/chain-service/index.d.ts +3 -0
- package/services/chain-service/index.js +50 -3
- package/services/chain-service/utils.d.ts +1 -0
- package/services/chain-service/utils.js +5 -1
- package/services/earning-service/constants/abis/compound_finance_v2_abi.json +1235 -0
- package/services/earning-service/constants/abis/st_liquid_token_abi.json +1355 -0
- package/services/earning-service/constants/chains.d.ts +15 -0
- package/services/earning-service/constants/chains.js +22 -0
- package/services/earning-service/constants/index.d.ts +2 -0
- package/services/earning-service/constants/index.js +5 -0
- package/services/earning-service/constants/step.d.ts +3 -0
- package/services/earning-service/constants/step.js +10 -0
- package/services/earning-service/handlers/base.d.ts +113 -0
- package/services/earning-service/handlers/base.js +256 -0
- package/services/earning-service/handlers/index.d.ts +5 -0
- package/services/earning-service/handlers/index.js +8 -0
- package/services/earning-service/handlers/lending/base.d.ts +8 -0
- package/services/earning-service/handlers/lending/base.js +73 -0
- package/services/earning-service/handlers/lending/index.d.ts +1 -0
- package/services/earning-service/handlers/lending/index.js +4 -0
- package/services/earning-service/handlers/lending/interlay.d.ts +24 -0
- package/services/earning-service/handlers/lending/interlay.js +184 -0
- package/services/earning-service/handlers/liquid-staking/acala.d.ts +27 -0
- package/services/earning-service/handlers/liquid-staking/acala.js +232 -0
- package/services/earning-service/handlers/liquid-staking/base.d.ts +11 -0
- package/services/earning-service/handlers/liquid-staking/base.js +89 -0
- package/services/earning-service/handlers/liquid-staking/bifrost.d.ts +46 -0
- package/services/earning-service/handlers/liquid-staking/bifrost.js +287 -0
- package/services/earning-service/handlers/liquid-staking/index.d.ts +4 -0
- package/services/earning-service/handlers/liquid-staking/index.js +7 -0
- package/services/earning-service/handlers/liquid-staking/parallel.d.ts +26 -0
- package/services/earning-service/handlers/liquid-staking/parallel.js +219 -0
- package/services/earning-service/handlers/liquid-staking/stella-swap.d.ts +34 -0
- package/services/earning-service/handlers/liquid-staking/stella-swap.js +394 -0
- package/services/earning-service/handlers/native-staking/amplitude.d.ts +22 -0
- package/services/earning-service/handlers/native-staking/amplitude.js +425 -0
- package/services/earning-service/handlers/native-staking/astar.d.ts +19 -0
- package/services/earning-service/handlers/native-staking/astar.js +456 -0
- package/services/earning-service/handlers/native-staking/base-para.d.ts +11 -0
- package/services/earning-service/handlers/native-staking/base-para.js +138 -0
- package/services/earning-service/handlers/native-staking/base.d.ts +21 -0
- package/services/earning-service/handlers/native-staking/base.js +152 -0
- package/services/earning-service/handlers/native-staking/index.d.ts +4 -0
- package/services/earning-service/handlers/native-staking/index.js +7 -0
- package/services/earning-service/handlers/native-staking/para-chain.d.ts +15 -0
- package/services/earning-service/handlers/native-staking/para-chain.js +382 -0
- package/services/earning-service/handlers/native-staking/relay-chain.d.ts +21 -0
- package/services/earning-service/handlers/native-staking/relay-chain.js +558 -0
- package/services/earning-service/handlers/nomination-pool/index.d.ts +36 -0
- package/services/earning-service/handlers/nomination-pool/index.js +556 -0
- package/services/earning-service/handlers/special.d.ts +64 -0
- package/services/earning-service/handlers/special.js +485 -0
- package/services/earning-service/service.d.ts +94 -0
- package/services/earning-service/service.js +722 -0
- package/services/earning-service/utils/index.d.ts +18 -0
- package/services/earning-service/utils/index.js +112 -0
- package/services/event-service/index.d.ts +2 -0
- package/services/event-service/index.js +5 -0
- package/services/event-service/types.d.ts +9 -0
- package/services/keyring-service/index.d.ts +2 -1
- package/services/keyring-service/index.js +14 -2
- package/services/migration-service/scripts/DeleteEarningData.d.ts +4 -0
- package/services/migration-service/scripts/DeleteEarningData.js +13 -0
- package/services/migration-service/scripts/EnableEarningChains.d.ts +4 -0
- package/services/migration-service/scripts/EnableEarningChains.js +13 -0
- package/services/migration-service/scripts/MigrateLedgerAccount.js +1 -1
- package/services/migration-service/scripts/MigrateTransactionHistory.js +1 -1
- package/services/migration-service/scripts/databases/MigrateEarningHistory.d.ts +4 -0
- package/services/migration-service/scripts/databases/MigrateEarningHistory.js +13 -0
- package/services/migration-service/scripts/databases/MigrateEarningVersion.d.ts +4 -0
- package/services/migration-service/scripts/databases/MigrateEarningVersion.js +13 -0
- package/services/migration-service/scripts/index.js +6 -1
- package/services/mint-campaign-service/campaigns/UnlockDotCampaign.d.ts +13 -0
- package/services/mint-campaign-service/campaigns/UnlockDotCampaign.js +139 -0
- package/services/mint-campaign-service/campaigns/index.d.ts +1 -0
- package/services/mint-campaign-service/campaigns/index.js +4 -0
- package/services/mint-campaign-service/constants.d.ts +1 -0
- package/services/mint-campaign-service/constants.js +4 -0
- package/services/mint-campaign-service/index.d.ts +7 -0
- package/services/mint-campaign-service/index.js +11 -0
- package/services/notification-service/NotificationService.js +3 -2
- package/services/request-service/handler/PopupHandler.js +3 -4
- package/services/storage-service/DatabaseService.d.ts +22 -1
- package/services/storage-service/DatabaseService.js +97 -0
- package/services/storage-service/databases/index.d.ts +7 -2
- package/services/storage-service/databases/index.js +4 -0
- package/services/storage-service/db-stores/AssetRef.d.ts +7 -0
- package/services/storage-service/db-stores/AssetRef.js +16 -0
- package/services/storage-service/db-stores/NominatorMetadata.js +3 -3
- package/services/storage-service/db-stores/YieldPoolStore.d.ts +10 -0
- package/services/storage-service/db-stores/YieldPoolStore.js +28 -0
- package/services/storage-service/db-stores/YieldPositionStore.d.ts +11 -0
- package/services/storage-service/db-stores/YieldPositionStore.js +63 -0
- package/services/subscan-service/index.d.ts +3 -2
- package/services/subscan-service/index.js +15 -0
- package/services/subscan-service/types.d.ts +20 -0
- package/services/transaction-service/event-parser/index.d.ts +3 -1
- package/services/transaction-service/event-parser/index.js +57 -1
- package/services/transaction-service/helpers/index.js +3 -1
- package/services/transaction-service/index.d.ts +6 -13
- package/services/transaction-service/index.js +247 -73
- package/services/transaction-service/types.d.ts +2 -0
- package/services/transaction-service/utils.js +1 -0
- package/types/campaigns/index.d.ts +1 -0
- package/types/campaigns/index.js +4 -0
- package/types/campaigns/unlock-dot.d.ts +71 -0
- package/types/campaigns/unlock-dot.js +1 -0
- package/types/index.d.ts +5 -0
- package/types/index.js +5 -1
- package/types/ordinal.d.ts +69 -0
- package/types/ordinal.js +1 -0
- package/types/transaction.d.ts +3 -0
- package/types/transaction.js +1 -0
- package/types/yield/actions/index.d.ts +2 -0
- package/types/yield/actions/index.js +5 -0
- package/types/yield/actions/join/index.d.ts +3 -0
- package/types/yield/actions/join/index.js +6 -0
- package/types/yield/actions/join/step.d.ts +95 -0
- package/types/yield/actions/join/step.js +46 -0
- package/types/yield/actions/join/submit.d.ts +58 -0
- package/types/yield/actions/join/submit.js +1 -0
- package/types/yield/actions/join/validate.d.ts +18 -0
- package/types/yield/actions/join/validate.js +10 -0
- package/types/yield/actions/others.d.ts +85 -0
- package/types/yield/actions/others.js +1 -0
- package/types/yield/index.d.ts +2 -0
- package/types/yield/index.js +5 -0
- package/types/yield/info/account/index.d.ts +4 -0
- package/types/yield/info/account/index.js +7 -0
- package/types/yield/info/account/info.d.ts +92 -0
- package/types/yield/info/account/info.js +1 -0
- package/types/yield/info/account/reward.d.ts +47 -0
- package/types/yield/info/account/reward.js +1 -0
- package/types/yield/info/account/target.d.ts +43 -0
- package/types/yield/info/account/target.js +27 -0
- package/types/yield/info/account/unstake.d.ts +31 -0
- package/types/yield/info/account/unstake.js +22 -0
- package/types/yield/info/base.d.ts +45 -0
- package/types/yield/info/base.js +36 -0
- package/types/yield/info/chain/index.d.ts +2 -0
- package/types/yield/info/chain/index.js +5 -0
- package/types/yield/info/chain/info.d.ts +252 -0
- package/types/yield/info/chain/info.js +1 -0
- package/types/yield/info/chain/target.d.ts +37 -0
- package/types/yield/info/chain/target.js +1 -0
- package/types/yield/info/index.d.ts +4 -0
- package/types/yield/info/index.js +7 -0
- package/types/yield/info/pallet.d.ts +143 -0
- package/types/yield/info/pallet.js +9 -0
- package/utils/environment.d.ts +9 -2
- package/utils/environment.js +14 -26
- package/utils/fetchStaticCache.d.ts +1 -0
- package/utils/fetchStaticCache.js +14 -0
- package/utils/fetchStaticData.js +2 -1
- package/utils/index.d.ts +5 -1
- package/utils/index.js +53 -3
- package/utils/mv3.d.ts +2 -0
- package/utils/mv3.js +6 -0
- package/utils/number.d.ts +2 -1
- package/utils/number.js +2 -1
- package/utils/object.d.ts +1 -0
- package/utils/object.js +6 -0
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-base
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
5
|
+
import { BasicTxErrorType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
6
|
+
import { getEarningStatusByNominations } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
|
|
7
|
+
import { _STAKING_ERA_LENGTH_MAP } from '@subwallet/extension-base/services/chain-service/constants';
|
|
8
|
+
import { EarningStatus, UnstakingStatus, YieldStepType } from '@subwallet/extension-base/types';
|
|
9
|
+
import { balanceFormatter, formatNumber, isUrl, parseRawNumber, reformatAddress } from '@subwallet/extension-base/utils';
|
|
10
|
+
import fetch from 'cross-fetch';
|
|
11
|
+
import { BN, BN_ZERO } from '@polkadot/util';
|
|
12
|
+
import { isEthereumAddress } from '@polkadot/util-crypto';
|
|
13
|
+
import BaseParaNativeStakingPoolHandler from "./base-para.js";
|
|
14
|
+
const convertAddress = address => {
|
|
15
|
+
return isEthereumAddress(address) ? address.toLowerCase() : address;
|
|
16
|
+
};
|
|
17
|
+
export function getAstarWithdrawable(yieldPosition) {
|
|
18
|
+
const unstakingInfo = {
|
|
19
|
+
chain: yieldPosition.chain,
|
|
20
|
+
status: UnstakingStatus.CLAIMABLE,
|
|
21
|
+
claimable: '0',
|
|
22
|
+
waitingTime: 0
|
|
23
|
+
};
|
|
24
|
+
let bnWithdrawable = BN_ZERO;
|
|
25
|
+
for (const unstaking of yieldPosition.unstakings) {
|
|
26
|
+
if (unstaking.status === UnstakingStatus.CLAIMABLE) {
|
|
27
|
+
bnWithdrawable = bnWithdrawable.add(new BN(unstaking.claimable));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (bnWithdrawable.gt(BN_ZERO)) {
|
|
31
|
+
unstakingInfo.claimable = bnWithdrawable.toString();
|
|
32
|
+
return unstakingInfo;
|
|
33
|
+
} else {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export default class AstarNativeStakingPoolHandler extends BaseParaNativeStakingPoolHandler {
|
|
38
|
+
availableMethod = {
|
|
39
|
+
join: true,
|
|
40
|
+
defaultUnstake: true,
|
|
41
|
+
fastUnstake: false,
|
|
42
|
+
cancelUnstake: false,
|
|
43
|
+
withdraw: true,
|
|
44
|
+
claimReward: true
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/* Subscribe pool info */
|
|
48
|
+
|
|
49
|
+
async subscribePoolInfo(callback) {
|
|
50
|
+
let cancel = false;
|
|
51
|
+
const nativeToken = this.nativeToken;
|
|
52
|
+
const defaultCallback = async () => {
|
|
53
|
+
const data = {
|
|
54
|
+
...this.baseInfo,
|
|
55
|
+
type: this.type,
|
|
56
|
+
metadata: {
|
|
57
|
+
...this.metadataInfo,
|
|
58
|
+
description: this.getDescription()
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const poolInfo = await this.getPoolInfo();
|
|
62
|
+
!poolInfo && callback(data);
|
|
63
|
+
};
|
|
64
|
+
if (!this.isActive) {
|
|
65
|
+
await defaultCallback();
|
|
66
|
+
return () => {
|
|
67
|
+
cancel = true;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
await defaultCallback();
|
|
71
|
+
const apyPromise = new Promise(resolve => {
|
|
72
|
+
fetch(`https://api.astar.network/api/v1/${this.chain}/dapps-staking/apy`, {
|
|
73
|
+
method: 'GET'
|
|
74
|
+
}).then(resp => {
|
|
75
|
+
resolve(resp.json());
|
|
76
|
+
}).catch(e => {
|
|
77
|
+
console.error(e);
|
|
78
|
+
resolve(null);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
const timeout = new Promise(resolve => {
|
|
82
|
+
const id = setTimeout(() => {
|
|
83
|
+
clearTimeout(id);
|
|
84
|
+
resolve(null);
|
|
85
|
+
}, 8000);
|
|
86
|
+
});
|
|
87
|
+
const apyRacePromise = Promise.race([timeout, apyPromise]); // need race because API often timeout
|
|
88
|
+
|
|
89
|
+
const substrateApi = await this.substrateApi.isReady;
|
|
90
|
+
let apyInfo;
|
|
91
|
+
try {
|
|
92
|
+
apyInfo = await apyRacePromise;
|
|
93
|
+
} catch (e) {
|
|
94
|
+
apyInfo = null;
|
|
95
|
+
}
|
|
96
|
+
const unsub = await substrateApi.api.query.dappsStaking.currentEra(_currentEra => {
|
|
97
|
+
if (cancel) {
|
|
98
|
+
unsub();
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const era = _currentEra.toString();
|
|
102
|
+
const minDelegatorStake = substrateApi.api.consts.dappsStaking.minimumStakingAmount.toString();
|
|
103
|
+
const unstakingDelay = substrateApi.api.consts.dappsStaking.unbondingPeriod.toString();
|
|
104
|
+
const eraTime = _STAKING_ERA_LENGTH_MAP[this.chain] || _STAKING_ERA_LENGTH_MAP.default; // in hours
|
|
105
|
+
const unstakingPeriod = parseInt(unstakingDelay) * eraTime;
|
|
106
|
+
const minToHuman = formatNumber(minDelegatorStake, nativeToken.decimals || 0, balanceFormatter);
|
|
107
|
+
const data = {
|
|
108
|
+
...this.baseInfo,
|
|
109
|
+
type: this.type,
|
|
110
|
+
metadata: {
|
|
111
|
+
...this.metadataInfo,
|
|
112
|
+
description: this.getDescription(minToHuman)
|
|
113
|
+
},
|
|
114
|
+
statistic: {
|
|
115
|
+
assetEarning: [{
|
|
116
|
+
slug: this.nativeToken.slug,
|
|
117
|
+
apy: apyInfo !== null ? apyInfo : undefined
|
|
118
|
+
}],
|
|
119
|
+
maxCandidatePerFarmer: 100,
|
|
120
|
+
// temporary fix for Astar, there's no limit for now
|
|
121
|
+
maxWithdrawalRequestPerFarmer: 1,
|
|
122
|
+
// by default
|
|
123
|
+
earningThreshold: {
|
|
124
|
+
join: minDelegatorStake,
|
|
125
|
+
defaultUnstake: '0',
|
|
126
|
+
fastUnstake: '0'
|
|
127
|
+
},
|
|
128
|
+
farmerCount: 0,
|
|
129
|
+
// TODO recheck
|
|
130
|
+
era: parseInt(era),
|
|
131
|
+
eraTime,
|
|
132
|
+
tvl: undefined,
|
|
133
|
+
// TODO recheck
|
|
134
|
+
totalApy: apyInfo !== null ? apyInfo : undefined,
|
|
135
|
+
// TODO recheck
|
|
136
|
+
unstakingPeriod
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
callback(data);
|
|
140
|
+
});
|
|
141
|
+
return () => {
|
|
142
|
+
cancel = true;
|
|
143
|
+
unsub();
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/* Subscribe pool info */
|
|
148
|
+
|
|
149
|
+
/* Subscribe pool position */
|
|
150
|
+
|
|
151
|
+
async parseNominatorMetadata(chainInfo, address, substrateApi, ledger) {
|
|
152
|
+
const nominationList = [];
|
|
153
|
+
const unstakingList = [];
|
|
154
|
+
const allDappsReq = new Promise(resolve => {
|
|
155
|
+
fetch(`https://api.astar.network/api/v1/${chainInfo.slug}/dapps-staking/dapps`, {
|
|
156
|
+
method: 'GET'
|
|
157
|
+
}).then(resp => {
|
|
158
|
+
resolve(resp.json());
|
|
159
|
+
}).catch(console.error);
|
|
160
|
+
});
|
|
161
|
+
const [_allDapps, _era, _stakerInfo] = await Promise.all([allDappsReq, substrateApi.api.query.dappsStaking.currentEra(), substrateApi.api.query.dappsStaking.generalStakerInfo.entries(address)]);
|
|
162
|
+
const currentEra = _era.toString();
|
|
163
|
+
const minDelegatorStake = substrateApi.api.consts.dappsStaking.minimumStakingAmount.toString();
|
|
164
|
+
const allDapps = _allDapps;
|
|
165
|
+
let bnTotalActiveStake = BN_ZERO;
|
|
166
|
+
if (_stakerInfo.length > 0) {
|
|
167
|
+
const dAppInfoMap = {};
|
|
168
|
+
allDapps.forEach(dappInfo => {
|
|
169
|
+
dAppInfoMap[convertAddress(dappInfo.address)] = dappInfo;
|
|
170
|
+
});
|
|
171
|
+
for (const item of _stakerInfo) {
|
|
172
|
+
const data = item[0].toHuman();
|
|
173
|
+
const stakedDapp = data[1];
|
|
174
|
+
const stakeData = item[1].toPrimitive();
|
|
175
|
+
const stakeList = stakeData.stakes;
|
|
176
|
+
const _dappAddress = stakedDapp.Evm ? stakedDapp.Evm.toLowerCase() : stakedDapp.Wasm;
|
|
177
|
+
const dappAddress = convertAddress(_dappAddress);
|
|
178
|
+
const currentStake = stakeList.slice(-1)[0].staked.toString() || '0';
|
|
179
|
+
const bnCurrentStake = new BN(currentStake);
|
|
180
|
+
if (bnCurrentStake.gt(BN_ZERO)) {
|
|
181
|
+
const dappEarningStatus = bnCurrentStake.gt(BN_ZERO) && bnCurrentStake.gte(new BN(minDelegatorStake)) ? EarningStatus.EARNING_REWARD : EarningStatus.NOT_EARNING;
|
|
182
|
+
bnTotalActiveStake = bnTotalActiveStake.add(bnCurrentStake);
|
|
183
|
+
const dappInfo = dAppInfoMap[dappAddress];
|
|
184
|
+
nominationList.push({
|
|
185
|
+
status: dappEarningStatus,
|
|
186
|
+
chain: chainInfo.slug,
|
|
187
|
+
validatorAddress: dappAddress,
|
|
188
|
+
activeStake: currentStake,
|
|
189
|
+
validatorMinStake: '0',
|
|
190
|
+
validatorIdentity: dappInfo === null || dappInfo === void 0 ? void 0 : dappInfo.name,
|
|
191
|
+
hasUnstaking: false // cannot get unstaking info by dapp
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const unlockingChunks = ledger.unbondingInfo.unlockingChunks;
|
|
198
|
+
if (unlockingChunks.length > 0) {
|
|
199
|
+
for (const unlockingChunk of unlockingChunks) {
|
|
200
|
+
const isClaimable = unlockingChunk.unlockEra - parseInt(currentEra) < 0;
|
|
201
|
+
const remainingEra = unlockingChunk.unlockEra - parseInt(currentEra);
|
|
202
|
+
const waitingTime = remainingEra * _STAKING_ERA_LENGTH_MAP[chainInfo.slug];
|
|
203
|
+
unstakingList.push({
|
|
204
|
+
chain: chainInfo.slug,
|
|
205
|
+
status: isClaimable ? UnstakingStatus.CLAIMABLE : UnstakingStatus.UNLOCKING,
|
|
206
|
+
claimable: unlockingChunk.amount.toString(),
|
|
207
|
+
waitingTime
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (nominationList.length === 0 && unstakingList.length === 0) {
|
|
212
|
+
return {
|
|
213
|
+
balanceToken: this.nativeToken.slug,
|
|
214
|
+
totalStake: '0',
|
|
215
|
+
unstakeBalance: '0',
|
|
216
|
+
status: EarningStatus.NOT_STAKING,
|
|
217
|
+
isBondedBefore: false,
|
|
218
|
+
activeStake: '0',
|
|
219
|
+
nominations: [],
|
|
220
|
+
unstakings: []
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
const stakingStatus = getEarningStatusByNominations(bnTotalActiveStake, nominationList);
|
|
224
|
+
const activeStake = bnTotalActiveStake.toString();
|
|
225
|
+
const unstakeBalance = unstakingList.reduce((old, currentValue) => {
|
|
226
|
+
return old.add(new BN(currentValue.claimable));
|
|
227
|
+
}, BN_ZERO);
|
|
228
|
+
const totalStake = unstakeBalance.add(bnTotalActiveStake);
|
|
229
|
+
return {
|
|
230
|
+
status: stakingStatus,
|
|
231
|
+
balanceToken: this.nativeToken.slug,
|
|
232
|
+
totalStake: totalStake.toString(),
|
|
233
|
+
activeStake: activeStake,
|
|
234
|
+
unstakeBalance: unstakeBalance.toString(),
|
|
235
|
+
isBondedBefore: totalStake.gt(BN_ZERO),
|
|
236
|
+
nominations: nominationList,
|
|
237
|
+
unstakings: unstakingList
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
async subscribePoolPosition(useAddresses, resultCallback) {
|
|
241
|
+
let cancel = false;
|
|
242
|
+
const substrateApi = await this.substrateApi.isReady;
|
|
243
|
+
const defaultInfo = this.baseInfo;
|
|
244
|
+
const chainInfo = this.chainInfo;
|
|
245
|
+
const unsub = await substrateApi.api.query.dappsStaking.ledger.multi(useAddresses, async ledgers => {
|
|
246
|
+
if (cancel) {
|
|
247
|
+
unsub();
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
if (ledgers) {
|
|
251
|
+
await Promise.all(ledgers.map(async (_ledger, i) => {
|
|
252
|
+
const owner = reformatAddress(useAddresses[i], 42);
|
|
253
|
+
const ledger = _ledger.toPrimitive();
|
|
254
|
+
if (ledger && ledger.locked > 0) {
|
|
255
|
+
const nominatorMetadata = await this.parseNominatorMetadata(chainInfo, owner, substrateApi, ledger);
|
|
256
|
+
resultCallback({
|
|
257
|
+
...defaultInfo,
|
|
258
|
+
...nominatorMetadata,
|
|
259
|
+
address: owner,
|
|
260
|
+
type: this.type
|
|
261
|
+
});
|
|
262
|
+
} else {
|
|
263
|
+
resultCallback({
|
|
264
|
+
...defaultInfo,
|
|
265
|
+
type: this.type,
|
|
266
|
+
address: owner,
|
|
267
|
+
balanceToken: this.nativeToken.slug,
|
|
268
|
+
totalStake: '0',
|
|
269
|
+
activeStake: '0',
|
|
270
|
+
unstakeBalance: '0',
|
|
271
|
+
isBondedBefore: false,
|
|
272
|
+
status: EarningStatus.NOT_STAKING,
|
|
273
|
+
nominations: [],
|
|
274
|
+
unstakings: []
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
}));
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
return () => {
|
|
281
|
+
cancel = true;
|
|
282
|
+
unsub();
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/* Subscribe pool position */
|
|
287
|
+
|
|
288
|
+
/* Get pool targets */
|
|
289
|
+
|
|
290
|
+
async getPoolTargets() {
|
|
291
|
+
const chainApi = await this.substrateApi.isReady;
|
|
292
|
+
const rawMaxStakerPerContract = chainApi.api.consts.dappsStaking.maxNumberOfStakersPerContract.toHuman();
|
|
293
|
+
const allDappsInfo = [];
|
|
294
|
+
const maxStakerPerContract = parseRawNumber(rawMaxStakerPerContract);
|
|
295
|
+
const allDappsReq = new Promise(resolve => {
|
|
296
|
+
fetch(`https://api.astar.network/api/v1/${this.chain}/dapps-staking/dapps`, {
|
|
297
|
+
method: 'GET'
|
|
298
|
+
}).then(resp => {
|
|
299
|
+
resolve(resp.json());
|
|
300
|
+
}).catch(console.error);
|
|
301
|
+
});
|
|
302
|
+
const [_era, _allDapps] = await Promise.all([chainApi.api.query.dappsStaking.currentEra(), allDappsReq]);
|
|
303
|
+
const era = parseRawNumber(_era.toHuman());
|
|
304
|
+
const allDapps = _allDapps;
|
|
305
|
+
await Promise.all(allDapps.map(async dapp => {
|
|
306
|
+
const dappName = dapp.name;
|
|
307
|
+
const dappAddress = dapp.address;
|
|
308
|
+
const dappIcon = isUrl(dapp.iconUrl) ? dapp.iconUrl : undefined;
|
|
309
|
+
const contractParam = isEthereumAddress(dappAddress) ? {
|
|
310
|
+
Evm: dappAddress
|
|
311
|
+
} : {
|
|
312
|
+
Wasm: dappAddress
|
|
313
|
+
};
|
|
314
|
+
const _contractInfo = await chainApi.api.query.dappsStaking.contractEraStake(contractParam, era);
|
|
315
|
+
const contractInfo = _contractInfo.toPrimitive();
|
|
316
|
+
let totalStake = '0';
|
|
317
|
+
let stakerCount = 0;
|
|
318
|
+
if (contractInfo !== null) {
|
|
319
|
+
var _contractInfo$total;
|
|
320
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
|
|
321
|
+
totalStake = contractInfo === null || contractInfo === void 0 ? void 0 : (_contractInfo$total = contractInfo.total) === null || _contractInfo$total === void 0 ? void 0 : _contractInfo$total.toString();
|
|
322
|
+
stakerCount = contractInfo.numberOfStakers;
|
|
323
|
+
}
|
|
324
|
+
allDappsInfo.push({
|
|
325
|
+
commission: 0,
|
|
326
|
+
expectedReturn: 0,
|
|
327
|
+
address: convertAddress(dappAddress),
|
|
328
|
+
totalStake: totalStake,
|
|
329
|
+
ownStake: '0',
|
|
330
|
+
otherStake: totalStake.toString(),
|
|
331
|
+
nominatorCount: stakerCount,
|
|
332
|
+
blocked: false,
|
|
333
|
+
isVerified: false,
|
|
334
|
+
minBond: '0',
|
|
335
|
+
icon: dappIcon,
|
|
336
|
+
identity: dappName,
|
|
337
|
+
chain: this.chain,
|
|
338
|
+
isCrowded: stakerCount >= maxStakerPerContract
|
|
339
|
+
});
|
|
340
|
+
}));
|
|
341
|
+
return allDappsInfo;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/* Get pool targets */
|
|
345
|
+
|
|
346
|
+
/* Join pool action */
|
|
347
|
+
|
|
348
|
+
get defaultSubmitStep() {
|
|
349
|
+
return [{
|
|
350
|
+
name: 'Nominate dApps',
|
|
351
|
+
type: YieldStepType.NOMINATE
|
|
352
|
+
}, {
|
|
353
|
+
slug: this.nativeToken.slug,
|
|
354
|
+
amount: '0'
|
|
355
|
+
}];
|
|
356
|
+
}
|
|
357
|
+
async createJoinExtrinsic(data, positionInfo, bondDest = 'Staked') {
|
|
358
|
+
const {
|
|
359
|
+
amount,
|
|
360
|
+
selectedValidators: targetValidators
|
|
361
|
+
} = data;
|
|
362
|
+
const chainApi = await this.substrateApi.isReady;
|
|
363
|
+
const binaryAmount = new BN(amount);
|
|
364
|
+
const dappInfo = targetValidators[0];
|
|
365
|
+
const dappParam = isEthereumAddress(dappInfo.address) ? {
|
|
366
|
+
Evm: dappInfo.address
|
|
367
|
+
} : {
|
|
368
|
+
Wasm: dappInfo.address
|
|
369
|
+
};
|
|
370
|
+
const extrinsic = chainApi.api.tx.dappsStaking.bondAndStake(dappParam, binaryAmount);
|
|
371
|
+
const tokenSlug = this.nativeToken.slug;
|
|
372
|
+
// const feeInfo = await extrinsic.paymentInfo(address);
|
|
373
|
+
// const fee = feeInfo.toPrimitive() as unknown as RuntimeDispatchInfo;
|
|
374
|
+
|
|
375
|
+
// Not use the fee to validate and to display on UI
|
|
376
|
+
return [extrinsic, {
|
|
377
|
+
slug: tokenSlug,
|
|
378
|
+
amount: '0'
|
|
379
|
+
}];
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/* Join pool action */
|
|
383
|
+
|
|
384
|
+
/* Leave pool action */
|
|
385
|
+
|
|
386
|
+
async handleYieldUnstake(amount, address, selectedTarget) {
|
|
387
|
+
const chainApi = await this.substrateApi.isReady;
|
|
388
|
+
const binaryAmount = new BN(amount);
|
|
389
|
+
if (!selectedTarget) {
|
|
390
|
+
return Promise.reject(new TransactionError(BasicTxErrorType.INVALID_PARAMS));
|
|
391
|
+
}
|
|
392
|
+
const dappParam = isEthereumAddress(selectedTarget) ? {
|
|
393
|
+
Evm: selectedTarget
|
|
394
|
+
} : {
|
|
395
|
+
Wasm: selectedTarget
|
|
396
|
+
};
|
|
397
|
+
const extrinsic = chainApi.api.tx.dappsStaking.unbondAndUnstake(dappParam, binaryAmount);
|
|
398
|
+
return [ExtrinsicType.STAKING_LEAVE_POOL, extrinsic];
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/* Leave pool action */
|
|
402
|
+
|
|
403
|
+
/* Other action */
|
|
404
|
+
|
|
405
|
+
async handleYieldCancelUnstake(params) {
|
|
406
|
+
return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
|
|
407
|
+
}
|
|
408
|
+
async handleYieldWithdraw(address, unstakingInfo) {
|
|
409
|
+
const chainApi = await this.substrateApi.isReady;
|
|
410
|
+
return chainApi.api.tx.dappsStaking.withdrawUnbonded();
|
|
411
|
+
}
|
|
412
|
+
async handleYieldClaimReward(address, bondReward) {
|
|
413
|
+
const apiPromise = await this.substrateApi.isReady;
|
|
414
|
+
const [_stakedDapps, _currentEra] = await Promise.all([apiPromise.api.query.dappsStaking.generalStakerInfo.entries(address), apiPromise.api.query.dappsStaking.currentEra()]);
|
|
415
|
+
const currentEra = parseRawNumber(_currentEra.toHuman());
|
|
416
|
+
const transactions = [];
|
|
417
|
+
for (const item of _stakedDapps) {
|
|
418
|
+
const data = item[0].toHuman();
|
|
419
|
+
const stakedDapp = data[1];
|
|
420
|
+
const stakeData = item[1].toHuman();
|
|
421
|
+
const stakes = stakeData.stakes;
|
|
422
|
+
const dappAddress = isEthereumAddress(stakedDapp.Evm) ? stakedDapp.Evm.toLowerCase() : stakedDapp.Evm;
|
|
423
|
+
let numberOfUnclaimedEra = 0;
|
|
424
|
+
const maxTx = 50;
|
|
425
|
+
for (let i = 0; i < stakes.length; i++) {
|
|
426
|
+
var _stakes;
|
|
427
|
+
const {
|
|
428
|
+
era,
|
|
429
|
+
staked
|
|
430
|
+
} = stakes[i];
|
|
431
|
+
const bnStaked = new BN(staked.replaceAll(',', ''));
|
|
432
|
+
const parsedEra = parseRawNumber(era);
|
|
433
|
+
if (bnStaked.eq(new BN(0))) {
|
|
434
|
+
continue;
|
|
435
|
+
}
|
|
436
|
+
const nextEraData = (_stakes = stakes[i + 1]) !== null && _stakes !== void 0 ? _stakes : null;
|
|
437
|
+
const nextEra = nextEraData && parseRawNumber(nextEraData.era);
|
|
438
|
+
const isLastEra = i === stakes.length - 1;
|
|
439
|
+
const eraToClaim = isLastEra ? currentEra - parsedEra : nextEra - parsedEra;
|
|
440
|
+
numberOfUnclaimedEra += eraToClaim;
|
|
441
|
+
}
|
|
442
|
+
const dappParam = isEthereumAddress(dappAddress) ? {
|
|
443
|
+
Evm: dappAddress
|
|
444
|
+
} : {
|
|
445
|
+
Wasm: dappAddress
|
|
446
|
+
};
|
|
447
|
+
for (let i = 0; i < Math.min(numberOfUnclaimedEra, maxTx); i++) {
|
|
448
|
+
const tx = apiPromise.api.tx.dappsStaking.claimStaker(dappParam);
|
|
449
|
+
transactions.push(tx);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
return apiPromise.api.tx.utility.batch(transactions);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/* Other actions */
|
|
456
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
2
|
+
import BaseNativeStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/native-staking/base';
|
|
3
|
+
import { OptimalYieldPath, SubmitYieldJoinData, YieldStepBaseInfo } from '@subwallet/extension-base/types';
|
|
4
|
+
export default abstract class BaseParaNativeStakingPoolHandler extends BaseNativeStakingPoolHandler {
|
|
5
|
+
get defaultSubmitStep(): YieldStepBaseInfo;
|
|
6
|
+
validateYieldJoin(data: SubmitYieldJoinData, path: OptimalYieldPath): Promise<TransactionError[]>;
|
|
7
|
+
/**
|
|
8
|
+
* @todo Recheck
|
|
9
|
+
* */
|
|
10
|
+
validateYieldLeave(amount: string, address: string, fastLeave: boolean, selectedTarget?: string): Promise<TransactionError[]>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-base
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
5
|
+
import { BasicTxErrorType, StakingTxErrorType, StakingType } from '@subwallet/extension-base/background/KoniTypes';
|
|
6
|
+
import { getBondedValidators, getExistUnstakeErrorMessage, getMaxValidatorErrorMessage, getMinStakeErrorMessage } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
|
|
7
|
+
import BaseNativeStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/native-staking/base';
|
|
8
|
+
import { EarningStatus, YieldStepType } from '@subwallet/extension-base/types';
|
|
9
|
+
import { isSameAddress, reformatAddress } from '@subwallet/extension-base/utils';
|
|
10
|
+
import { t } from 'i18next';
|
|
11
|
+
import { BN, BN_ZERO } from '@polkadot/util';
|
|
12
|
+
export default class BaseParaNativeStakingPoolHandler extends BaseNativeStakingPoolHandler {
|
|
13
|
+
/* Join pool action */
|
|
14
|
+
|
|
15
|
+
get defaultSubmitStep() {
|
|
16
|
+
return [{
|
|
17
|
+
name: 'Nominate collators',
|
|
18
|
+
type: YieldStepType.NOMINATE
|
|
19
|
+
}, {
|
|
20
|
+
slug: this.nativeToken.slug,
|
|
21
|
+
amount: '0'
|
|
22
|
+
}];
|
|
23
|
+
}
|
|
24
|
+
async validateYieldJoin(data, path) {
|
|
25
|
+
const {
|
|
26
|
+
address,
|
|
27
|
+
amount,
|
|
28
|
+
selectedValidators
|
|
29
|
+
} = data;
|
|
30
|
+
const poolInfo = await this.getPoolInfo();
|
|
31
|
+
const poolPosition = await this.getPoolPosition(address);
|
|
32
|
+
const chainInfo = this.chainInfo;
|
|
33
|
+
const bnAmount = new BN(amount);
|
|
34
|
+
if (bnAmount.lte(BN_ZERO)) {
|
|
35
|
+
return [new TransactionError(BasicTxErrorType.INVALID_PARAMS, 'Amount must be greater than 0')];
|
|
36
|
+
}
|
|
37
|
+
if (!poolInfo || !poolInfo.statistic) {
|
|
38
|
+
return Promise.resolve([new TransactionError(BasicTxErrorType.INTERNAL_ERROR)]);
|
|
39
|
+
}
|
|
40
|
+
const errors = [];
|
|
41
|
+
const selectedCollator = selectedValidators[0];
|
|
42
|
+
let bnTotalStake = new BN(amount);
|
|
43
|
+
const bnChainMinStake = new BN(poolInfo.statistic.earningThreshold.join || '0');
|
|
44
|
+
const bnCollatorMinStake = new BN(selectedCollator.minBond || '0');
|
|
45
|
+
const bnMinStake = bnCollatorMinStake > bnChainMinStake ? bnCollatorMinStake : bnChainMinStake;
|
|
46
|
+
const minStakeErrorMessage = getMinStakeErrorMessage(chainInfo, bnMinStake);
|
|
47
|
+
const maxValidator = poolInfo.statistic.maxCandidatePerFarmer;
|
|
48
|
+
const maxValidatorErrorMessage = getMaxValidatorErrorMessage(chainInfo, maxValidator);
|
|
49
|
+
const existUnstakeErrorMessage = getExistUnstakeErrorMessage(chainInfo.slug, StakingType.NOMINATED, true);
|
|
50
|
+
if (!poolPosition || poolPosition.status === EarningStatus.NOT_STAKING) {
|
|
51
|
+
if (!bnTotalStake.gte(bnMinStake)) {
|
|
52
|
+
errors.push(new TransactionError(StakingTxErrorType.NOT_ENOUGH_MIN_STAKE, minStakeErrorMessage));
|
|
53
|
+
}
|
|
54
|
+
return errors;
|
|
55
|
+
}
|
|
56
|
+
const {
|
|
57
|
+
bondedValidators
|
|
58
|
+
} = getBondedValidators(poolPosition.nominations);
|
|
59
|
+
const parsedSelectedCollatorAddress = reformatAddress(selectedCollator.address, 0);
|
|
60
|
+
if (!bondedValidators.includes(parsedSelectedCollatorAddress)) {
|
|
61
|
+
// new delegation
|
|
62
|
+
if (!bnTotalStake.gte(bnMinStake)) {
|
|
63
|
+
errors.push(new TransactionError(StakingTxErrorType.NOT_ENOUGH_MIN_STAKE, minStakeErrorMessage));
|
|
64
|
+
}
|
|
65
|
+
const delegationCount = poolPosition.nominations.length + 1;
|
|
66
|
+
if (delegationCount > maxValidator) {
|
|
67
|
+
errors.push(new TransactionError(StakingTxErrorType.EXCEED_MAX_NOMINATIONS, maxValidatorErrorMessage));
|
|
68
|
+
}
|
|
69
|
+
} else {
|
|
70
|
+
let currentDelegationAmount = '0';
|
|
71
|
+
let hasUnstaking = false;
|
|
72
|
+
for (const delegation of poolPosition.nominations) {
|
|
73
|
+
if (reformatAddress(delegation.validatorAddress, 0) === parsedSelectedCollatorAddress) {
|
|
74
|
+
currentDelegationAmount = delegation.activeStake;
|
|
75
|
+
hasUnstaking = !!delegation.hasUnstaking && delegation.hasUnstaking;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
bnTotalStake = bnTotalStake.add(new BN(currentDelegationAmount));
|
|
80
|
+
if (!bnTotalStake.gte(bnMinStake)) {
|
|
81
|
+
errors.push(new TransactionError(StakingTxErrorType.NOT_ENOUGH_MIN_STAKE, minStakeErrorMessage));
|
|
82
|
+
}
|
|
83
|
+
if (hasUnstaking) {
|
|
84
|
+
errors.push(new TransactionError(StakingTxErrorType.EXIST_UNSTAKING_REQUEST, existUnstakeErrorMessage));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return errors;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* Join pool action */
|
|
91
|
+
|
|
92
|
+
/* Leave pool action */
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @todo Recheck
|
|
96
|
+
* */
|
|
97
|
+
async validateYieldLeave(amount, address, fastLeave, selectedTarget) {
|
|
98
|
+
const errors = [];
|
|
99
|
+
const poolInfo = await this.getPoolInfo();
|
|
100
|
+
const poolPosition = await this.getPoolPosition(address);
|
|
101
|
+
if (!poolInfo || !poolInfo.statistic || !poolPosition || fastLeave || !selectedTarget) {
|
|
102
|
+
return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
|
|
103
|
+
}
|
|
104
|
+
if (fastLeave) {
|
|
105
|
+
return [new TransactionError(BasicTxErrorType.INVALID_PARAMS)];
|
|
106
|
+
}
|
|
107
|
+
const bnAmount = new BN(amount);
|
|
108
|
+
if (bnAmount.lte(BN_ZERO)) {
|
|
109
|
+
errors.push(new TransactionError(BasicTxErrorType.INVALID_PARAMS, t('Amount must be greater than 0')));
|
|
110
|
+
}
|
|
111
|
+
let targetNomination;
|
|
112
|
+
for (const nomination of poolPosition.nominations) {
|
|
113
|
+
if (isSameAddress(nomination.validatorAddress, selectedTarget)) {
|
|
114
|
+
targetNomination = nomination;
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (!targetNomination) {
|
|
119
|
+
errors.push(new TransactionError(BasicTxErrorType.INTERNAL_ERROR));
|
|
120
|
+
return errors;
|
|
121
|
+
}
|
|
122
|
+
const bnActiveStake = new BN(targetNomination.activeStake);
|
|
123
|
+
const bnRemainingStake = bnActiveStake.sub(new BN(amount));
|
|
124
|
+
const bnChainMinStake = new BN(poolInfo.statistic.earningThreshold.join || '0');
|
|
125
|
+
const bnCollatorMinStake = new BN(targetNomination.validatorMinStake || '0');
|
|
126
|
+
const bnMinStake = BN.max(bnCollatorMinStake, bnChainMinStake);
|
|
127
|
+
const existUnstakeErrorMessage = getExistUnstakeErrorMessage(this.chain, StakingType.NOMINATED);
|
|
128
|
+
if (targetNomination.hasUnstaking) {
|
|
129
|
+
errors.push(new TransactionError(StakingTxErrorType.EXIST_UNSTAKING_REQUEST, existUnstakeErrorMessage));
|
|
130
|
+
}
|
|
131
|
+
if (!(bnRemainingStake.isZero() || bnRemainingStake.gte(bnMinStake))) {
|
|
132
|
+
errors.push(new TransactionError(StakingTxErrorType.INVALID_ACTIVE_STAKE));
|
|
133
|
+
}
|
|
134
|
+
return errors;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* Leave pool action */
|
|
138
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
2
|
+
import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
|
|
3
|
+
import { EarningRewardHistoryItem, EarningRewardItem, HandleYieldStepData, OptimalYieldPath, OptimalYieldPathParams, SubmitJoinNativeStaking, SubmitYieldJoinData, TransactionData, YieldPoolMethodInfo, YieldPoolType, YieldPositionInfo, YieldStepBaseInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
|
|
4
|
+
import BasePoolHandler from '../base';
|
|
5
|
+
export default abstract class BaseNativeStakingPoolHandler extends BasePoolHandler {
|
|
6
|
+
readonly type = YieldPoolType.NATIVE_STAKING;
|
|
7
|
+
protected readonly name: string;
|
|
8
|
+
protected readonly shortName: string;
|
|
9
|
+
slug: string;
|
|
10
|
+
protected readonly availableMethod: YieldPoolMethodInfo;
|
|
11
|
+
constructor(state: KoniState, chain: string);
|
|
12
|
+
protected getDescription(amount?: string): string;
|
|
13
|
+
getPoolReward(useAddresses: string[], callBack: (rs: EarningRewardItem) => void): Promise<VoidFunction>;
|
|
14
|
+
getPoolRewardHistory(useAddresses: string[], callBack: (rs: EarningRewardHistoryItem) => void): Promise<VoidFunction>;
|
|
15
|
+
get defaultSubmitStep(): YieldStepBaseInfo;
|
|
16
|
+
abstract createJoinExtrinsic(data: SubmitJoinNativeStaking, positionInfo?: YieldPositionInfo, bondDest?: string): Promise<[TransactionData, YieldTokenBaseInfo]>;
|
|
17
|
+
protected getSubmitStep(params: OptimalYieldPathParams): Promise<YieldStepBaseInfo>;
|
|
18
|
+
handleYieldJoin(_data: SubmitYieldJoinData, path: OptimalYieldPath, currentStep: number): Promise<HandleYieldStepData>;
|
|
19
|
+
handleYieldRedeem(amount: string, address: string, selectedTarget?: string): Promise<[ExtrinsicType, TransactionData]>;
|
|
20
|
+
handleYieldClaimReward(address: string, bondReward?: boolean): Promise<TransactionData>;
|
|
21
|
+
}
|