@subwallet/extension-base 1.3.27-0 → 1.3.28-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 +7 -1
- package/cjs/constants/index.js +1 -1
- package/cjs/koni/background/handlers/Extension.js +13 -0
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +89 -33
- package/cjs/services/chain-service/constants.js +2 -1
- package/cjs/services/chain-service/utils/index.js +11 -2
- package/cjs/services/chain-service/utils/patch.js +1 -1
- package/cjs/services/earning-service/handlers/base.js +3 -0
- package/cjs/services/earning-service/handlers/native-staking/dtao.js +97 -36
- package/cjs/services/earning-service/handlers/native-staking/tao.js +34 -4
- package/cjs/services/earning-service/service.js +13 -1
- package/cjs/services/migration-service/index.js +2 -5
- package/cjs/services/migration-service/scripts/index.js +4 -8
- package/cjs/services/price-service/coingecko.js +49 -0
- package/cjs/services/transaction-service/utils.js +4 -1
- package/cjs/utils/asset.js +17 -2
- package/constants/index.d.ts +1 -1
- package/constants/index.js +1 -1
- package/koni/background/handlers/Extension.d.ts +1 -0
- package/koni/background/handlers/Extension.js +13 -0
- package/package.json +7 -7
- package/packageInfo.js +1 -1
- package/services/balance-service/helpers/subscribe/substrate/index.js +76 -23
- package/services/chain-service/constants.d.ts +1 -0
- package/services/chain-service/constants.js +2 -1
- package/services/chain-service/utils/index.d.ts +1 -0
- package/services/chain-service/utils/index.js +6 -0
- package/services/chain-service/utils/patch.js +1 -1
- package/services/earning-service/handlers/base.d.ts +3 -2
- package/services/earning-service/handlers/base.js +3 -0
- package/services/earning-service/handlers/native-staking/dtao.d.ts +7 -2
- package/services/earning-service/handlers/native-staking/dtao.js +89 -31
- package/services/earning-service/handlers/native-staking/tao.d.ts +4 -1
- package/services/earning-service/handlers/native-staking/tao.js +31 -1
- package/services/earning-service/service.d.ts +2 -1
- package/services/earning-service/service.js +13 -1
- package/services/migration-service/index.js +2 -5
- package/services/migration-service/scripts/index.js +4 -8
- package/services/price-service/coingecko.js +48 -0
- package/services/transaction-service/utils.js +4 -1
- package/types/yield/actions/join/submit.d.ts +3 -0
- package/types/yield/actions/others.d.ts +7 -0
- package/utils/asset.d.ts +1 -0
- package/utils/asset.js +14 -0
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"./cjs/detectPackage.js"
|
|
18
18
|
],
|
|
19
19
|
"type": "module",
|
|
20
|
-
"version": "1.3.
|
|
20
|
+
"version": "1.3.28-0",
|
|
21
21
|
"main": "./cjs/index.js",
|
|
22
22
|
"module": "./index.js",
|
|
23
23
|
"types": "./index.d.ts",
|
|
@@ -2669,13 +2669,13 @@
|
|
|
2669
2669
|
"@reduxjs/toolkit": "^1.9.1",
|
|
2670
2670
|
"@sora-substrate/type-definitions": "^1.17.7",
|
|
2671
2671
|
"@substrate/connect": "^0.8.9",
|
|
2672
|
-
"@subwallet/chain-list": "0.2.102",
|
|
2673
|
-
"@subwallet/extension-base": "^1.3.
|
|
2674
|
-
"@subwallet/extension-chains": "^1.3.
|
|
2675
|
-
"@subwallet/extension-dapp": "^1.3.
|
|
2676
|
-
"@subwallet/extension-inject": "^1.3.
|
|
2672
|
+
"@subwallet/chain-list": "0.2.102-beta.19",
|
|
2673
|
+
"@subwallet/extension-base": "^1.3.28-0",
|
|
2674
|
+
"@subwallet/extension-chains": "^1.3.28-0",
|
|
2675
|
+
"@subwallet/extension-dapp": "^1.3.28-0",
|
|
2676
|
+
"@subwallet/extension-inject": "^1.3.28-0",
|
|
2677
2677
|
"@subwallet/keyring": "^0.1.9",
|
|
2678
|
-
"@subwallet/subwallet-api-sdk": "^1.3.
|
|
2678
|
+
"@subwallet/subwallet-api-sdk": "^1.3.28-0",
|
|
2679
2679
|
"@subwallet/ui-keyring": "^0.1.9",
|
|
2680
2680
|
"@ton/core": "^0.56.3",
|
|
2681
2681
|
"@ton/crypto": "^3.2.0",
|
package/packageInfo.js
CHANGED
|
@@ -7,5 +7,5 @@ export const packageInfo = {
|
|
|
7
7
|
name: '@subwallet/extension-base',
|
|
8
8
|
path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto',
|
|
9
9
|
type: 'esm',
|
|
10
|
-
version: '1.3.
|
|
10
|
+
version: '1.3.28-0'
|
|
11
11
|
};
|
|
@@ -14,9 +14,8 @@ import { _adaptX1Interior } from '@subwallet/extension-base/core/substrate/xcm-p
|
|
|
14
14
|
import { getPSP22ContractPromise } from '@subwallet/extension-base/koni/api/contract-handler/wasm';
|
|
15
15
|
import { getDefaultWeightV2 } from '@subwallet/extension-base/koni/api/contract-handler/wasm/utils';
|
|
16
16
|
import { _BALANCE_CHAIN_GROUP, _MANTA_ZK_CHAIN_GROUP, _ZK_ASSET_PREFIX } from '@subwallet/extension-base/services/chain-service/constants';
|
|
17
|
-
import { _checkSmartContractSupportByChain, _getAssetExistentialDeposit, _getChainExistentialDeposit, _getChainNativeTokenSlug, _getContractAddressOfToken, _getTokenOnChainAssetId, _getTokenOnChainInfo, _getTokenTypesSupportedByChain, _getXcmAssetMultilocation, _isBridgedToken, _isChainEvmCompatible } from '@subwallet/extension-base/services/chain-service/utils';
|
|
18
|
-
import {
|
|
19
|
-
import { filterAssetsByChainAndType } from '@subwallet/extension-base/utils';
|
|
17
|
+
import { _checkSmartContractSupportByChain, _getAssetExistentialDeposit, _getAssetNetuid, _getChainExistentialDeposit, _getChainNativeTokenSlug, _getContractAddressOfToken, _getTokenOnChainAssetId, _getTokenOnChainInfo, _getTokenTypesSupportedByChain, _getXcmAssetMultilocation, _isBridgedToken, _isChainEvmCompatible } from '@subwallet/extension-base/services/chain-service/utils';
|
|
18
|
+
import { filterAlphaAssetsByChain, filterAssetsByChainAndType } from '@subwallet/extension-base/utils';
|
|
20
19
|
import BigN from 'bignumber.js';
|
|
21
20
|
import { subscribeERC20Interval } from "../evm.js";
|
|
22
21
|
import { subscribeEquilibriumTokenBalance } from "./equilibrium.js";
|
|
@@ -29,6 +28,7 @@ export const subscribeSubstrateBalance = async (addresses, chainInfo, assetMap,
|
|
|
29
28
|
let unsubBridgedToken;
|
|
30
29
|
let unsubGrcToken;
|
|
31
30
|
let unsubVftToken;
|
|
31
|
+
let unsubSubnetAlphaToken;
|
|
32
32
|
const chain = chainInfo.slug;
|
|
33
33
|
const baseParams = {
|
|
34
34
|
addresses,
|
|
@@ -65,6 +65,9 @@ export const subscribeSubstrateBalance = async (addresses, chainInfo, assetMap,
|
|
|
65
65
|
if (_BALANCE_CHAIN_GROUP.supportBridged.includes(chain)) {
|
|
66
66
|
unsubBridgedToken = await subscribeForeignAssetBalance(substrateParams);
|
|
67
67
|
}
|
|
68
|
+
if (_BALANCE_CHAIN_GROUP.bittensor.includes(chain)) {
|
|
69
|
+
unsubSubnetAlphaToken = await subscribeSubnetAlphaPallet(substrateParams);
|
|
70
|
+
}
|
|
68
71
|
|
|
69
72
|
/**
|
|
70
73
|
* Some substrate chain use evm account format but not have evm connection and support ERC20 contract,
|
|
@@ -93,7 +96,7 @@ export const subscribeSubstrateBalance = async (addresses, chainInfo, assetMap,
|
|
|
93
96
|
console.warn(err);
|
|
94
97
|
}
|
|
95
98
|
return () => {
|
|
96
|
-
var _unsubGrcToken, _unsubVftToken;
|
|
99
|
+
var _unsubGrcToken, _unsubVftToken, _unsubSubnetAlphaToke;
|
|
97
100
|
unsubNativeToken && unsubNativeToken();
|
|
98
101
|
unsubLocalToken && unsubLocalToken();
|
|
99
102
|
unsubEvmContractToken && unsubEvmContractToken();
|
|
@@ -101,6 +104,7 @@ export const subscribeSubstrateBalance = async (addresses, chainInfo, assetMap,
|
|
|
101
104
|
unsubBridgedToken && unsubBridgedToken();
|
|
102
105
|
(_unsubGrcToken = unsubGrcToken) === null || _unsubGrcToken === void 0 ? void 0 : _unsubGrcToken();
|
|
103
106
|
(_unsubVftToken = unsubVftToken) === null || _unsubVftToken === void 0 ? void 0 : _unsubVftToken();
|
|
107
|
+
(_unsubSubnetAlphaToke = unsubSubnetAlphaToken) === null || _unsubSubnetAlphaToke === void 0 ? void 0 : _unsubSubnetAlphaToke();
|
|
104
108
|
};
|
|
105
109
|
};
|
|
106
110
|
|
|
@@ -130,27 +134,19 @@ const subscribeWithSystemAccountPallet = async ({
|
|
|
130
134
|
args: addresses
|
|
131
135
|
});
|
|
132
136
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const stakeInfo = (await substrateApi.api.call.stakeInfoRuntimeApi.getStakeInfoForColdkey(address)).toJSON();
|
|
137
|
-
const price = await getTaoToAlphaMapping(substrateApi);
|
|
138
|
-
let TaoTotalStake = new BigN(0);
|
|
139
|
-
if (stakeInfo) {
|
|
140
|
-
for (const validator of Object.values(stakeInfo)) {
|
|
141
|
-
const stake = new BigN(validator.stake);
|
|
142
|
-
const netuid = validator.netuid;
|
|
143
|
-
const taoToAlphaPrice = price[netuid] ? new BigN(price[netuid]) : new BigN(1);
|
|
144
|
-
const taoStake = stake.multipliedBy(taoToAlphaPrice).toFixed(0).toString();
|
|
145
|
-
TaoTotalStake = TaoTotalStake.plus(taoStake);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
return new BigN(TaoTotalStake.toString());
|
|
149
|
-
}));
|
|
150
|
-
}
|
|
151
|
-
const subscription = substrateApi.subscribeDataWithMulti(params, rs => {
|
|
137
|
+
|
|
138
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
139
|
+
const subscription = substrateApi.subscribeDataWithMulti(params, async rs => {
|
|
152
140
|
const balances = rs[systemAccountKey];
|
|
153
141
|
const poolMemberInfos = rs[poolMembersKey];
|
|
142
|
+
let bittensorStakingBalances = new Array(addresses.length).fill(new BigN(0));
|
|
143
|
+
if (_BALANCE_CHAIN_GROUP.bittensor.includes(chainInfo.slug)) {
|
|
144
|
+
const rawData = await substrateApi.api.call.stakeInfoRuntimeApi.getStakeInfoForColdkeys(addresses);
|
|
145
|
+
const values = rawData.toPrimitive();
|
|
146
|
+
bittensorStakingBalances = values.map(([, stakes]) => {
|
|
147
|
+
return stakes.filter(i => i.netuid === 0).reduce((previousValue, currentValue) => previousValue.plus(currentValue.stake), BigN(0));
|
|
148
|
+
});
|
|
149
|
+
}
|
|
154
150
|
const items = balances.map((_balance, index) => {
|
|
155
151
|
const balanceInfo = _balance;
|
|
156
152
|
const transferableBalance = _getSystemPalletTransferable(balanceInfo, _getChainExistentialDeposit(chainInfo), extrinsicType);
|
|
@@ -476,4 +472,61 @@ const subscribeOrmlTokensPallet = async ({
|
|
|
476
472
|
unsub && unsub.unsubscribe();
|
|
477
473
|
});
|
|
478
474
|
};
|
|
475
|
+
};
|
|
476
|
+
|
|
477
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
478
|
+
const subscribeSubnetAlphaPallet = async ({
|
|
479
|
+
addresses,
|
|
480
|
+
assetMap,
|
|
481
|
+
callback,
|
|
482
|
+
chainInfo,
|
|
483
|
+
substrateApi
|
|
484
|
+
}) => {
|
|
485
|
+
let cancel = false;
|
|
486
|
+
const tokenMap = filterAlphaAssetsByChain(assetMap, chainInfo.slug);
|
|
487
|
+
const getTokenBalances = async () => {
|
|
488
|
+
if (cancel) {
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
const rawData = await substrateApi.api.call.stakeInfoRuntimeApi.getStakeInfoForColdkeys(addresses);
|
|
492
|
+
const values = rawData.toPrimitive();
|
|
493
|
+
const converted = {};
|
|
494
|
+
for (let i = 0; i < values.length; i++) {
|
|
495
|
+
const [, stakes] = values[i];
|
|
496
|
+
const address = addresses[i];
|
|
497
|
+
converted[address] = {};
|
|
498
|
+
stakes.forEach(stakeInfo => {
|
|
499
|
+
const {
|
|
500
|
+
netuid,
|
|
501
|
+
stake
|
|
502
|
+
} = stakeInfo;
|
|
503
|
+
const currentValue = converted[address][netuid] || BigN(0);
|
|
504
|
+
converted[address][netuid] = currentValue.plus(stake);
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
for (const chainAsset of Object.values(tokenMap)) {
|
|
508
|
+
const netuid = _getAssetNetuid(chainAsset);
|
|
509
|
+
const items = Object.entries(converted).map(([address, stakeMap]) => {
|
|
510
|
+
const value = stakeMap[netuid] || BigN(0);
|
|
511
|
+
return {
|
|
512
|
+
address: address,
|
|
513
|
+
tokenSlug: chainAsset.slug,
|
|
514
|
+
state: APIItemState.READY,
|
|
515
|
+
free: value.toFixed(0),
|
|
516
|
+
locked: '0'
|
|
517
|
+
};
|
|
518
|
+
});
|
|
519
|
+
if (!cancel) {
|
|
520
|
+
callback(items);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
getTokenBalances().catch(console.error);
|
|
525
|
+
const interval = setInterval(() => {
|
|
526
|
+
getTokenBalances().catch(console.error);
|
|
527
|
+
}, SUB_TOKEN_REFRESH_BALANCE_INTERVAL);
|
|
528
|
+
return () => {
|
|
529
|
+
cancel = true;
|
|
530
|
+
clearInterval(interval);
|
|
531
|
+
};
|
|
479
532
|
};
|
|
@@ -34,7 +34,8 @@ export const _BALANCE_CHAIN_GROUP = {
|
|
|
34
34
|
kusama: ['kusama', 'kintsugi', 'kintsugi_test', 'interlay', 'acala', 'statemint', 'karura', 'bifrost'],
|
|
35
35
|
// perhaps there are some runtime updates
|
|
36
36
|
centrifuge: ['centrifuge'],
|
|
37
|
-
supportBridged: ['rococo_assethub', 'statemint', 'statemine', 'polimec']
|
|
37
|
+
supportBridged: ['rococo_assethub', 'statemint', 'statemine', 'polimec'],
|
|
38
|
+
bittensor: ['bittensor', 'bittensor_testnet']
|
|
38
39
|
};
|
|
39
40
|
export const _BALANCE_TOKEN_GROUP = {
|
|
40
41
|
crab: ['CKTON', 'PKTON'],
|
|
@@ -116,4 +116,5 @@ export declare function updateLatestChainInfo(currentDataMap: _DataMap, latestCh
|
|
|
116
116
|
needUpdateChainApiList: _ChainInfo[];
|
|
117
117
|
};
|
|
118
118
|
export declare const _chainInfoToChainType: (chainInfo: _ChainInfo) => AccountChainType;
|
|
119
|
+
export declare const _getAssetNetuid: (assetInfo: _ChainAsset) => number;
|
|
119
120
|
export * from './patch';
|
|
@@ -577,4 +577,10 @@ export const _chainInfoToChainType = chainInfo => {
|
|
|
577
577
|
}
|
|
578
578
|
return AccountChainType.SUBSTRATE;
|
|
579
579
|
};
|
|
580
|
+
export const _getAssetNetuid = assetInfo => {
|
|
581
|
+
var _assetInfo$metadata$n, _assetInfo$metadata;
|
|
582
|
+
// @ts-ignore
|
|
583
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
584
|
+
return (_assetInfo$metadata$n = (_assetInfo$metadata = assetInfo.metadata) === null || _assetInfo$metadata === void 0 ? void 0 : _assetInfo$metadata.netuid) !== null && _assetInfo$metadata$n !== void 0 ? _assetInfo$metadata$n : -1;
|
|
585
|
+
};
|
|
580
586
|
export * from "./patch.js";
|
|
@@ -5,7 +5,7 @@ const PRODUCTION_BRANCHES = ['master', 'webapp', 'webapp-dev'];
|
|
|
5
5
|
const branchName = process.env.BRANCH_NAME || 'subwallet-dev';
|
|
6
6
|
const fetchDomain = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'https://chain-list-assets.subwallet.app' : 'https://dev.sw-chain-list-assets.pages.dev';
|
|
7
7
|
const fetchFile = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'list.json' : 'preview.json';
|
|
8
|
-
const ChainListVersion = '0.2.
|
|
8
|
+
const ChainListVersion = '0.2.102'; // update this when build chainlist
|
|
9
9
|
|
|
10
10
|
// todo: move this interface to chainlist
|
|
11
11
|
|
|
@@ -3,7 +3,7 @@ import { TransactionError } from '@subwallet/extension-base/background/errors/Tr
|
|
|
3
3
|
import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
4
4
|
import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
|
|
5
5
|
import { _EvmApi, _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
|
|
6
|
-
import { BasePoolInfo, BaseYieldPoolMetadata, EarningRewardHistoryItem, EarningRewardItem, HandleYieldStepData, OptimalYieldPath, OptimalYieldPathParams, RequestEarlyValidateYield, ResponseEarlyValidateYield, StakeCancelWithdrawalParams, SubmitYieldJoinData, TransactionData, UnstakingInfo, YieldPoolInfo, YieldPoolMethodInfo, YieldPoolTarget, YieldPoolType, YieldPositionInfo, YieldStepBaseInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
|
|
6
|
+
import { BasePoolInfo, BaseYieldPoolMetadata, EarningRewardHistoryItem, EarningRewardItem, HandleYieldStepData, OptimalYieldPath, OptimalYieldPathParams, RequestEarlyValidateYield, RequestEarningSlippage, ResponseEarlyValidateYield, StakeCancelWithdrawalParams, SubmitYieldJoinData, TransactionData, UnstakingInfo, YieldPoolInfo, YieldPoolMethodInfo, YieldPoolTarget, YieldPoolType, YieldPositionInfo, YieldStepBaseInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
|
|
7
7
|
/**
|
|
8
8
|
* @class BasePoolHandler
|
|
9
9
|
* @description Base pool handler
|
|
@@ -99,7 +99,7 @@ export default abstract class BasePoolHandler {
|
|
|
99
99
|
/** Create `transaction` to join the pool step-by-step */
|
|
100
100
|
abstract handleYieldJoin(data: SubmitYieldJoinData, path: OptimalYieldPath, currentStep: number): Promise<HandleYieldStepData>;
|
|
101
101
|
/** Validate param to leave the pool */
|
|
102
|
-
abstract validateYieldLeave(amount: string, address: string, fastLeave: boolean, selectedTarget?: string, slug?: string): Promise<TransactionError[]>;
|
|
102
|
+
abstract validateYieldLeave(amount: string, address: string, fastLeave: boolean, selectedTarget?: string, slug?: string, poolInfo?: YieldPoolInfo): Promise<TransactionError[]>;
|
|
103
103
|
/** Create `transaction` to leave the pool normal (default unstake) */
|
|
104
104
|
protected abstract handleYieldUnstake(amount: string, address: string, selectedTarget?: string, netuid?: number): Promise<[ExtrinsicType, TransactionData]>;
|
|
105
105
|
/** Create `transaction` to leave the pool fast (swap token) */
|
|
@@ -114,4 +114,5 @@ export default abstract class BasePoolHandler {
|
|
|
114
114
|
abstract handleYieldClaimReward(address: string, bondReward?: boolean): Promise<TransactionData>;
|
|
115
115
|
/** Check handler can handle slug */
|
|
116
116
|
canHandleSlug(slug: string): boolean;
|
|
117
|
+
getEarningSlippage(params: RequestEarningSlippage): Promise<number>;
|
|
117
118
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { _ChainInfo } from '@subwallet/chain-list/types';
|
|
2
|
+
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
2
3
|
import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
3
4
|
import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
|
|
4
5
|
import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
|
|
5
6
|
import BaseParaStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/native-staking/base-para';
|
|
6
|
-
import { BaseYieldPositionInfo, StakeCancelWithdrawalParams, SubmitJoinNativeStaking, TransactionData, UnstakingInfo, ValidatorInfo, YieldPoolInfo, YieldPoolMethodInfo, YieldPoolType, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
|
|
7
|
+
import { BaseYieldPositionInfo, OptimalYieldPath, RequestEarningSlippage, StakeCancelWithdrawalParams, SubmitJoinNativeStaking, TransactionData, UnstakingInfo, ValidatorInfo, YieldPoolInfo, YieldPoolMethodInfo, YieldPoolType, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
|
|
7
8
|
import { BigNumber } from 'bignumber.js';
|
|
8
9
|
export interface SubnetData {
|
|
9
10
|
netuid: number;
|
|
@@ -35,7 +36,8 @@ export interface TestnetBittensorDelegateInfo {
|
|
|
35
36
|
nominators: Nominators;
|
|
36
37
|
returnPer1000: number;
|
|
37
38
|
}
|
|
38
|
-
export declare const
|
|
39
|
+
export declare const DEFAULT_DTAO_MINBOND = "600000";
|
|
40
|
+
export declare const getAlphaToTaoMapping: (substrateApi: _SubstrateApi) => Promise<Record<number, string>>;
|
|
39
41
|
export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHandler {
|
|
40
42
|
handleYieldWithdraw(address: string, unstakingInfo: UnstakingInfo): Promise<TransactionData>;
|
|
41
43
|
handleYieldCancelUnstake(params: StakeCancelWithdrawalParams): Promise<TransactionData>;
|
|
@@ -49,6 +51,7 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
49
51
|
readonly availableMethod: YieldPoolMethodInfo;
|
|
50
52
|
constructor(state: KoniState, chain: string);
|
|
51
53
|
canHandleSlug(slug: string): boolean;
|
|
54
|
+
getEarningSlippage(params: RequestEarningSlippage): Promise<number>;
|
|
52
55
|
get maintainBalance(): string;
|
|
53
56
|
private init;
|
|
54
57
|
protected getDescription(): string;
|
|
@@ -59,6 +62,8 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
59
62
|
private getMainnetPoolTargets;
|
|
60
63
|
getPoolTargets(): Promise<ValidatorInfo[]>;
|
|
61
64
|
createJoinExtrinsic(data: SubmitJoinNativeStaking, positionInfo?: YieldPositionInfo, bondDest?: string): Promise<[TransactionData, YieldTokenBaseInfo]>;
|
|
65
|
+
validateYieldJoin(data: SubmitJoinNativeStaking, path: OptimalYieldPath): Promise<TransactionError[]>;
|
|
62
66
|
handleYieldUnstake(amount: string, address: string, selectedTarget?: string, netuid?: number): Promise<[ExtrinsicType, TransactionData]>;
|
|
67
|
+
validateYieldLeave(amount: string, address: string, fastLeave: boolean, selectedTarget?: string, slug?: string, poolInfo?: YieldPoolInfo): Promise<TransactionError[]>;
|
|
63
68
|
}
|
|
64
69
|
export {};
|
|
@@ -5,14 +5,18 @@ import { TransactionError } from '@subwallet/extension-base/background/errors/Tr
|
|
|
5
5
|
import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
6
6
|
import { BITTENSOR_REFRESH_STAKE_APY, BITTENSOR_REFRESH_STAKE_INFO } from '@subwallet/extension-base/constants';
|
|
7
7
|
import { getEarningStatusByNominations } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
|
|
8
|
+
import { _getAssetDecimals, _getAssetSymbol } from '@subwallet/extension-base/services/chain-service/utils';
|
|
8
9
|
import BaseParaStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/native-staking/base-para';
|
|
9
10
|
import { BasicTxErrorType, EarningStatus, YieldPoolType } from '@subwallet/extension-base/types';
|
|
10
|
-
import { reformatAddress } from '@subwallet/extension-base/utils';
|
|
11
|
-
import BigN from 'bignumber.js';
|
|
11
|
+
import { formatNumber, reformatAddress } from '@subwallet/extension-base/utils';
|
|
12
|
+
import BigN, { BigNumber } from 'bignumber.js';
|
|
13
|
+
import { t } from 'i18next';
|
|
12
14
|
import { BN, BN_TEN, BN_ZERO } from '@polkadot/util';
|
|
13
15
|
import { calculateReward } from "../../utils/index.js";
|
|
14
16
|
import { BittensorCache } from "./tao.js";
|
|
15
|
-
|
|
17
|
+
const DEFAULT_BITTENSOR_SLIPPAGE = 0.005;
|
|
18
|
+
export const DEFAULT_DTAO_MINBOND = '600000';
|
|
19
|
+
export const getAlphaToTaoMapping = async substrateApi => {
|
|
16
20
|
const allSubnets = (await substrateApi.api.call.subnetInfoRuntimeApi.getAllDynamicInfo()).toJSON();
|
|
17
21
|
if (!allSubnets) {
|
|
18
22
|
return {};
|
|
@@ -66,6 +70,30 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
66
70
|
canHandleSlug(slug) {
|
|
67
71
|
return slug.startsWith(`${this.slug}__`);
|
|
68
72
|
}
|
|
73
|
+
async getEarningSlippage(params) {
|
|
74
|
+
const substrateApi = await this.substrateApi.isReady;
|
|
75
|
+
const subnetInfo = (await substrateApi.api.call.subnetInfoRuntimeApi.getDynamicInfo(params.netuid)).toJSON();
|
|
76
|
+
const alphaIn = new BigNumber((subnetInfo === null || subnetInfo === void 0 ? void 0 : subnetInfo.alphaIn) || 0);
|
|
77
|
+
const taoIn = new BigNumber((subnetInfo === null || subnetInfo === void 0 ? void 0 : subnetInfo.taoIn) || 0);
|
|
78
|
+
const k = alphaIn.multipliedBy(taoIn);
|
|
79
|
+
const value = new BigNumber(params.value);
|
|
80
|
+
if (params.type === ExtrinsicType.STAKING_BOND) {
|
|
81
|
+
const newTaoIn = taoIn.plus(value);
|
|
82
|
+
const newAlphaIn = k.dividedBy(newTaoIn);
|
|
83
|
+
const alphaReturned = alphaIn.minus(newAlphaIn);
|
|
84
|
+
const alphaIdeal = value.multipliedBy(alphaIn).dividedBy(taoIn);
|
|
85
|
+
const slippage = alphaIdeal.minus(alphaReturned).dividedBy(alphaIdeal);
|
|
86
|
+
return slippage.toNumber();
|
|
87
|
+
} else if (params.type === ExtrinsicType.STAKING_UNBOND) {
|
|
88
|
+
const newAlphaIn = alphaIn.plus(value);
|
|
89
|
+
const newTaoReserve = k.dividedBy(newAlphaIn);
|
|
90
|
+
const taoReturned = taoIn.minus(newTaoReserve);
|
|
91
|
+
const taoIdeal = value.multipliedBy(taoIn).dividedBy(alphaIn);
|
|
92
|
+
const slippage = taoIdeal.minus(taoReturned).dividedBy(taoIdeal);
|
|
93
|
+
return slippage.toNumber();
|
|
94
|
+
}
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
69
97
|
get maintainBalance() {
|
|
70
98
|
const ed = new BN(this.nativeToken.minAmount || '0');
|
|
71
99
|
const calculateMaintainBalance = new BN(15).mul(ed).div(BN_TEN);
|
|
@@ -74,6 +102,9 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
74
102
|
}
|
|
75
103
|
async init() {
|
|
76
104
|
try {
|
|
105
|
+
if (this.isInit || !this.substrateApi) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
77
108
|
const substrateApi = await this.substrateApi.isReady;
|
|
78
109
|
const dynamicInfo = (await substrateApi.api.call.subnetInfoRuntimeApi.getAllDynamicInfo()).toJSON();
|
|
79
110
|
const subnetsInfo = (await substrateApi.api.call.subnetInfoRuntimeApi.getSubnetsInfoV2()).toJSON();
|
|
@@ -110,18 +141,14 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
110
141
|
/* Subscribe pool info */
|
|
111
142
|
|
|
112
143
|
async subscribePoolInfo(callback) {
|
|
113
|
-
|
|
114
|
-
await this.init();
|
|
115
|
-
}
|
|
144
|
+
await this.init();
|
|
116
145
|
let cancel = false;
|
|
117
|
-
const substrateApi = await this.substrateApi.isReady;
|
|
118
146
|
const updateStakingInfo = async () => {
|
|
147
|
+
await this.substrateApi.isReady;
|
|
119
148
|
try {
|
|
120
149
|
if (cancel) {
|
|
121
150
|
return;
|
|
122
151
|
}
|
|
123
|
-
const minDelegatorStake = (await substrateApi.api.query.subtensorModule.nominatorMinRequiredStake()).toPrimitive() || 0;
|
|
124
|
-
const BNminDelegatorStake = new BigN(minDelegatorStake.toString());
|
|
125
152
|
this.subnetData.forEach(subnet => {
|
|
126
153
|
const netuid = subnet.netuid.toString().padStart(2, '0');
|
|
127
154
|
const subnetSlug = `${this.slug}__subnet_${netuid.padStart(2, '0')}`;
|
|
@@ -148,7 +175,7 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
148
175
|
maxCandidatePerFarmer: subnet.maxAllowedValidators,
|
|
149
176
|
maxWithdrawalRequestPerFarmer: 1,
|
|
150
177
|
earningThreshold: {
|
|
151
|
-
join:
|
|
178
|
+
join: DEFAULT_DTAO_MINBOND,
|
|
152
179
|
defaultUnstake: '0',
|
|
153
180
|
fastUnstake: '0'
|
|
154
181
|
},
|
|
@@ -167,7 +194,6 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
167
194
|
const subscribeStakingMetadataInterval = () => {
|
|
168
195
|
updateStakingInfo().catch(console.error);
|
|
169
196
|
};
|
|
170
|
-
await substrateApi.isReady;
|
|
171
197
|
subscribeStakingMetadataInterval();
|
|
172
198
|
const interval = setInterval(subscribeStakingMetadataInterval, BITTENSOR_REFRESH_STAKE_APY);
|
|
173
199
|
return () => {
|
|
@@ -179,9 +205,8 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
179
205
|
/* Subscribe pool position */
|
|
180
206
|
|
|
181
207
|
async parseNominatorMetadata(chainInfo, address, delegatorState) {
|
|
208
|
+
await this.substrateApi.isReady;
|
|
182
209
|
const nominationList = [];
|
|
183
|
-
const getMinDelegatorStake = this.substrateApi.api.query.subtensorModule.nominatorMinRequiredStake();
|
|
184
|
-
const minDelegatorStake = (await getMinDelegatorStake).toString();
|
|
185
210
|
let allActiveStake = BN_ZERO;
|
|
186
211
|
for (const delegate of delegatorState) {
|
|
187
212
|
const stake = new BigN(delegate.amount);
|
|
@@ -195,7 +220,7 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
195
220
|
chain: chainInfo.slug,
|
|
196
221
|
validatorAddress: delegate.owner,
|
|
197
222
|
activeStake: delegate.amount,
|
|
198
|
-
validatorMinStake:
|
|
223
|
+
validatorMinStake: DEFAULT_DTAO_MINBOND,
|
|
199
224
|
originActiveStake: originActiveStake,
|
|
200
225
|
validatorIdentity: delegate.identity
|
|
201
226
|
});
|
|
@@ -214,9 +239,7 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
214
239
|
};
|
|
215
240
|
}
|
|
216
241
|
async subscribePoolPosition(useAddresses, rsCallback) {
|
|
217
|
-
|
|
218
|
-
await this.init();
|
|
219
|
-
}
|
|
242
|
+
await this.init();
|
|
220
243
|
let cancel = false;
|
|
221
244
|
const substrateApi = await this.substrateApi.isReady;
|
|
222
245
|
const defaultInfo = this.baseInfo;
|
|
@@ -224,7 +247,7 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
224
247
|
const _delegateInfo = await this.bittensorCache.get();
|
|
225
248
|
const getPoolPosition = async () => {
|
|
226
249
|
const rawDelegateStateInfos = await Promise.all(useAddresses.map(async address => (await substrateApi.api.call.stakeInfoRuntimeApi.getStakeInfoForColdkey(address)).toJSON()));
|
|
227
|
-
const price = await
|
|
250
|
+
const price = await getAlphaToTaoMapping(this.substrateApi);
|
|
228
251
|
if (rawDelegateStateInfos && rawDelegateStateInfos.length > 0) {
|
|
229
252
|
rawDelegateStateInfos.forEach((rawDelegateStateInfo, i) => {
|
|
230
253
|
const owner = reformatAddress(useAddresses[i], 42);
|
|
@@ -234,7 +257,7 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
234
257
|
const hotkey = delegate.hotkey;
|
|
235
258
|
const netuid = delegate.netuid;
|
|
236
259
|
const stake = new BigN(delegate.stake);
|
|
237
|
-
const
|
|
260
|
+
const aplhaToTaoPrice = new BigN(price[netuid]);
|
|
238
261
|
if (!subnetPositions[netuid]) {
|
|
239
262
|
subnetPositions[netuid] = {
|
|
240
263
|
delegatorState: [],
|
|
@@ -250,7 +273,7 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
250
273
|
subnetPositions[netuid].delegatorState.push({
|
|
251
274
|
owner: hotkey,
|
|
252
275
|
amount: stake.toString(),
|
|
253
|
-
rate:
|
|
276
|
+
rate: aplhaToTaoPrice,
|
|
254
277
|
identity: identity
|
|
255
278
|
});
|
|
256
279
|
subnetPositions[netuid].totalBalance = subnetPositions[netuid].totalBalance.add(new BN(stake.toString()));
|
|
@@ -327,9 +350,7 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
327
350
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
328
351
|
async getDevnetPoolTargets() {
|
|
329
352
|
const testnetDelegate = (await this.substrateApi.api.call.delegateInfoRuntimeApi.getDelegates()).toJSON();
|
|
330
|
-
const
|
|
331
|
-
const nominatorMinRequiredStake = (await getNominatorMinRequiredStake).toString();
|
|
332
|
-
const bnMinBond = new BN(nominatorMinRequiredStake);
|
|
353
|
+
const bnMinBond = new BN(DEFAULT_DTAO_MINBOND);
|
|
333
354
|
const filteredDelegates = testnetDelegate.filter(delegate => {
|
|
334
355
|
return delegate.returnPer1000 !== 0;
|
|
335
356
|
});
|
|
@@ -350,9 +371,7 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
350
371
|
async getMainnetPoolTargets() {
|
|
351
372
|
const _topValidator = await this.bittensorCache.get();
|
|
352
373
|
const topValidator = _topValidator;
|
|
353
|
-
const
|
|
354
|
-
const nominatorMinRequiredStake = (await getNominatorMinRequiredStake).toString();
|
|
355
|
-
const bnMinBond = new BN(nominatorMinRequiredStake);
|
|
374
|
+
const bnMinBond = new BN(DEFAULT_DTAO_MINBOND);
|
|
356
375
|
const validatorList = topValidator.data;
|
|
357
376
|
const validatorAddresses = Object.keys(validatorList);
|
|
358
377
|
const results = await Promise.all(validatorAddresses.map(i => {
|
|
@@ -385,9 +404,7 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
385
404
|
return results;
|
|
386
405
|
}
|
|
387
406
|
async getPoolTargets() {
|
|
388
|
-
|
|
389
|
-
await this.init();
|
|
390
|
-
}
|
|
407
|
+
await this.init();
|
|
391
408
|
if (this.chain === 'bittensor') {
|
|
392
409
|
return this.getMainnetPoolTargets();
|
|
393
410
|
} else {
|
|
@@ -407,14 +424,31 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
407
424
|
} = data;
|
|
408
425
|
const chainApi = await this.substrateApi.isReady;
|
|
409
426
|
const binaryAmount = new BN(amount);
|
|
427
|
+
const price = await getAlphaToTaoMapping(this.substrateApi);
|
|
428
|
+
const alphaToTaoPrice = new BigN(price[netuid]);
|
|
429
|
+
const limitPrice = alphaToTaoPrice.multipliedBy(10 ** _getAssetDecimals(this.nativeToken)).multipliedBy(1 + DEFAULT_BITTENSOR_SLIPPAGE);
|
|
430
|
+
const BNlimitPrice = new BN(limitPrice.integerValue(BigNumber.ROUND_CEIL).toFixed());
|
|
410
431
|
const selectedValidatorInfo = targetValidators[0];
|
|
411
432
|
const hotkey = selectedValidatorInfo.address;
|
|
412
|
-
const extrinsic = chainApi.api.tx.subtensorModule.
|
|
433
|
+
const extrinsic = chainApi.api.tx.subtensorModule.addStakeLimit(hotkey, netuid, binaryAmount, BNlimitPrice, false);
|
|
413
434
|
return [extrinsic, {
|
|
414
435
|
slug: this.nativeToken.slug,
|
|
415
436
|
amount: '0'
|
|
416
437
|
}];
|
|
417
438
|
}
|
|
439
|
+
async validateYieldJoin(data, path) {
|
|
440
|
+
const baseErrors = await super.validateYieldJoin(data, path);
|
|
441
|
+
if (baseErrors.length > 0) {
|
|
442
|
+
return baseErrors;
|
|
443
|
+
}
|
|
444
|
+
const {
|
|
445
|
+
amount
|
|
446
|
+
} = data;
|
|
447
|
+
if (new BN(amount).lt(new BN(DEFAULT_DTAO_MINBOND))) {
|
|
448
|
+
return [new TransactionError(BasicTxErrorType.INVALID_PARAMS, t(`Insufficient stake. You need to stake at least ${formatNumber(DEFAULT_DTAO_MINBOND, _getAssetDecimals(this.nativeToken))} ${_getAssetSymbol(this.nativeToken)} to earn rewards`))];
|
|
449
|
+
}
|
|
450
|
+
return baseErrors;
|
|
451
|
+
}
|
|
418
452
|
|
|
419
453
|
/* Join pool action */
|
|
420
454
|
|
|
@@ -423,12 +457,36 @@ export default class SubnetTaoStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
423
457
|
async handleYieldUnstake(amount, address, selectedTarget, netuid) {
|
|
424
458
|
const apiPromise = await this.substrateApi.isReady;
|
|
425
459
|
const binaryAmount = new BN(amount);
|
|
460
|
+
const price = await getAlphaToTaoMapping(this.substrateApi);
|
|
461
|
+
const alphaToTaoPrice = new BigN(price[netuid]);
|
|
462
|
+
const limitPrice = alphaToTaoPrice.multipliedBy(10 ** _getAssetDecimals(this.nativeToken)).multipliedBy(1 - DEFAULT_BITTENSOR_SLIPPAGE);
|
|
463
|
+
const BNlimitPrice = new BN(limitPrice.integerValue(BigNumber.ROUND_CEIL).toFixed());
|
|
426
464
|
if (!selectedTarget) {
|
|
427
465
|
return Promise.reject(new TransactionError(BasicTxErrorType.INVALID_PARAMS));
|
|
428
466
|
}
|
|
429
|
-
const extrinsic = apiPromise.api.tx.subtensorModule.
|
|
467
|
+
const extrinsic = apiPromise.api.tx.subtensorModule.removeStakeLimit(selectedTarget, netuid, binaryAmount, BNlimitPrice, false);
|
|
430
468
|
return [ExtrinsicType.STAKING_UNBOND, extrinsic];
|
|
431
469
|
}
|
|
470
|
+
async validateYieldLeave(amount, address, fastLeave, selectedTarget, slug, poolInfo) {
|
|
471
|
+
var _poolInfo$metadata$su;
|
|
472
|
+
const baseErrors = await super.validateYieldLeave(amount, address, fastLeave, selectedTarget, slug);
|
|
473
|
+
if (baseErrors.length > 0) {
|
|
474
|
+
return baseErrors;
|
|
475
|
+
}
|
|
476
|
+
if (!poolInfo) {
|
|
477
|
+
return [new TransactionError(BasicTxErrorType.INVALID_PARAMS)];
|
|
478
|
+
}
|
|
479
|
+
const netuid = (_poolInfo$metadata$su = poolInfo.metadata.subnetData) === null || _poolInfo$metadata$su === void 0 ? void 0 : _poolInfo$metadata$su.netuid;
|
|
480
|
+
const price = await getAlphaToTaoMapping(this.substrateApi);
|
|
481
|
+
const minUnstake = new BigN(DEFAULT_DTAO_MINBOND).dividedBy(new BigN(price[netuid]));
|
|
482
|
+
console.log('minUnstake', minUnstake.dividedBy(10 ** _getAssetDecimals(this.nativeToken)).toString());
|
|
483
|
+
const formattedMinUnstake = minUnstake.dividedBy(1000000).integerValue(BigNumber.ROUND_CEIL).dividedBy(1000);
|
|
484
|
+
if (new BigN(amount).lt(formattedMinUnstake.multipliedBy(10 ** _getAssetDecimals(this.nativeToken)))) {
|
|
485
|
+
var _poolInfo$metadata$su2;
|
|
486
|
+
return [new TransactionError(BasicTxErrorType.INVALID_PARAMS, t(`Amount too low. You need to unstake at least ${formattedMinUnstake.toString()} ${((_poolInfo$metadata$su2 = poolInfo.metadata.subnetData) === null || _poolInfo$metadata$su2 === void 0 ? void 0 : _poolInfo$metadata$su2.subnetSymbol) || ''}`))];
|
|
487
|
+
}
|
|
488
|
+
return baseErrors;
|
|
489
|
+
}
|
|
432
490
|
|
|
433
491
|
/* Leave pool action */
|
|
434
492
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { _ChainInfo } from '@subwallet/chain-list/types';
|
|
2
|
+
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
2
3
|
import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
3
4
|
import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
|
|
4
5
|
import BaseParaStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/native-staking/base-para';
|
|
5
|
-
import { BaseYieldPositionInfo, StakeCancelWithdrawalParams, SubmitJoinNativeStaking, TransactionData, UnstakingInfo, ValidatorInfo, YieldPoolInfo, YieldPoolMethodInfo, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
|
|
6
|
+
import { BaseYieldPositionInfo, OptimalYieldPath, StakeCancelWithdrawalParams, SubmitJoinNativeStaking, TransactionData, UnstakingInfo, ValidatorInfo, YieldPoolInfo, YieldPoolMethodInfo, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
|
|
6
7
|
export interface TaoStakeInfo {
|
|
7
8
|
hotkey: string;
|
|
8
9
|
stake: string;
|
|
@@ -71,6 +72,8 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
71
72
|
private getMainnetPoolTargets;
|
|
72
73
|
getPoolTargets(): Promise<ValidatorInfo[]>;
|
|
73
74
|
createJoinExtrinsic(data: SubmitJoinNativeStaking, positionInfo?: YieldPositionInfo, bondDest?: string): Promise<[TransactionData, YieldTokenBaseInfo]>;
|
|
75
|
+
validateYieldJoin(data: SubmitJoinNativeStaking, path: OptimalYieldPath): Promise<TransactionError[]>;
|
|
74
76
|
handleYieldUnstake(amount: string, address: string, selectedTarget?: string): Promise<[ExtrinsicType, TransactionData]>;
|
|
77
|
+
validateYieldLeave(amount: string, address: string, fastLeave: boolean, selectedTarget?: string, slug?: string, poolInfo?: YieldPoolInfo): Promise<TransactionError[]>;
|
|
75
78
|
}
|
|
76
79
|
export {};
|
|
@@ -5,12 +5,15 @@ import { TransactionError } from '@subwallet/extension-base/background/errors/Tr
|
|
|
5
5
|
import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
6
6
|
import { BITTENSOR_REFRESH_STAKE_APY, BITTENSOR_REFRESH_STAKE_INFO } from '@subwallet/extension-base/constants';
|
|
7
7
|
import { getEarningStatusByNominations } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
|
|
8
|
+
import { _getAssetDecimals, _getAssetSymbol } from '@subwallet/extension-base/services/chain-service/utils';
|
|
8
9
|
import BaseParaStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/native-staking/base-para';
|
|
9
10
|
import { BasicTxErrorType, EarningStatus } from '@subwallet/extension-base/types';
|
|
10
|
-
import { reformatAddress } from '@subwallet/extension-base/utils';
|
|
11
|
+
import { formatNumber, reformatAddress } from '@subwallet/extension-base/utils';
|
|
11
12
|
import BigN from 'bignumber.js';
|
|
13
|
+
import { t } from 'i18next';
|
|
12
14
|
import { BN, BN_TEN, BN_ZERO } from '@polkadot/util';
|
|
13
15
|
import { calculateReward } from "../../utils/index.js";
|
|
16
|
+
import { DEFAULT_DTAO_MINBOND } from "./dtao.js";
|
|
14
17
|
export const BITTENSOR_API_KEY_1 = process.env.BITTENSOR_API_KEY_1 || '';
|
|
15
18
|
export const BITTENSOR_API_KEY_2 = process.env.BITTENSOR_API_KEY_2 || '';
|
|
16
19
|
export const BITTENSOR_API_KEY_3 = process.env.BITTENSOR_API_KEY_3 || '';
|
|
@@ -475,6 +478,19 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
475
478
|
amount: '0'
|
|
476
479
|
}];
|
|
477
480
|
}
|
|
481
|
+
async validateYieldJoin(data, path) {
|
|
482
|
+
const baseErrors = await super.validateYieldJoin(data, path);
|
|
483
|
+
if (baseErrors.length > 0) {
|
|
484
|
+
return baseErrors;
|
|
485
|
+
}
|
|
486
|
+
const {
|
|
487
|
+
amount
|
|
488
|
+
} = data;
|
|
489
|
+
if (new BN(amount).lt(new BN(DEFAULT_DTAO_MINBOND))) {
|
|
490
|
+
return [new TransactionError(BasicTxErrorType.INVALID_PARAMS, t(`Insufficient stake. You need to stake at least ${formatNumber(DEFAULT_DTAO_MINBOND, _getAssetDecimals(this.nativeToken))} ${_getAssetSymbol(this.nativeToken)} to earn rewards`))];
|
|
491
|
+
}
|
|
492
|
+
return baseErrors;
|
|
493
|
+
}
|
|
478
494
|
|
|
479
495
|
/* Join pool action */
|
|
480
496
|
|
|
@@ -490,6 +506,20 @@ export default class TaoNativeStakingPoolHandler extends BaseParaStakingPoolHand
|
|
|
490
506
|
const extrinsic = apiPromise.api.tx.subtensorModule.removeStake(selectedTarget, 0, binaryAmount);
|
|
491
507
|
return [ExtrinsicType.STAKING_UNBOND, extrinsic];
|
|
492
508
|
}
|
|
509
|
+
async validateYieldLeave(amount, address, fastLeave, selectedTarget, slug, poolInfo) {
|
|
510
|
+
const baseErrors = await super.validateYieldLeave(amount, address, fastLeave, selectedTarget, slug);
|
|
511
|
+
if (baseErrors.length > 0) {
|
|
512
|
+
return baseErrors;
|
|
513
|
+
}
|
|
514
|
+
if (!poolInfo) {
|
|
515
|
+
return [new TransactionError(BasicTxErrorType.INVALID_PARAMS)];
|
|
516
|
+
}
|
|
517
|
+
const bnMinUnstake = new BigN(DEFAULT_DTAO_MINBOND);
|
|
518
|
+
if (new BigN(amount).lt(bnMinUnstake)) {
|
|
519
|
+
return [new TransactionError(BasicTxErrorType.INVALID_PARAMS, t(`Amount too low. You need to unstake at least ${formatNumber(bnMinUnstake, _getAssetDecimals(this.nativeToken))} ${_getAssetSymbol(this.nativeToken)}`))];
|
|
520
|
+
}
|
|
521
|
+
return baseErrors;
|
|
522
|
+
}
|
|
493
523
|
|
|
494
524
|
/* Leave pool action */
|
|
495
525
|
}
|