@subwallet/extension-base 1.1.31-beta.0 → 1.1.32-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 +1 -0
- package/cjs/koni/api/staking/bonding/index.js +2 -0
- package/cjs/koni/api/staking/bonding/paraChain.js +6 -3
- package/cjs/koni/background/cron.js +0 -28
- package/cjs/koni/background/handlers/Extension.js +17 -11
- package/cjs/koni/background/handlers/State.js +4 -46
- package/cjs/koni/background/subscription.js +0 -155
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/campaign-service/index.js +19 -0
- package/cjs/services/chain-service/constants.js +3 -2
- package/cjs/services/earning-service/constants/chains.js +1 -1
- package/cjs/services/earning-service/handlers/base.js +9 -6
- package/cjs/services/earning-service/handlers/lending/base.js +61 -0
- package/cjs/services/earning-service/handlers/lending/interlay.js +3 -2
- package/cjs/services/earning-service/handlers/liquid-staking/acala.js +3 -2
- package/cjs/services/earning-service/handlers/liquid-staking/base.js +54 -0
- package/cjs/services/earning-service/handlers/liquid-staking/bifrost.js +3 -2
- package/cjs/services/earning-service/handlers/liquid-staking/parallel.js +3 -2
- package/cjs/services/earning-service/handlers/liquid-staking/stella-swap.js +16 -7
- package/cjs/services/earning-service/handlers/native-staking/amplitude.js +7 -2
- package/cjs/services/earning-service/handlers/native-staking/astar.js +7 -2
- package/cjs/services/earning-service/handlers/native-staking/base.js +4 -2
- package/cjs/services/earning-service/handlers/native-staking/para-chain.js +7 -2
- package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +12 -3
- package/cjs/services/earning-service/handlers/nomination-pool/index.js +9 -3
- package/cjs/services/earning-service/handlers/special.js +57 -67
- package/cjs/services/earning-service/service.js +370 -37
- package/cjs/services/event-service/index.js +1 -0
- package/cjs/services/migration-service/scripts/index.js +1 -2
- package/cjs/services/storage-service/DatabaseService.js +15 -0
- package/cjs/services/storage-service/db-stores/Campaign.js +9 -3
- package/cjs/services/storage-service/db-stores/YieldPositionStore.js +6 -0
- package/cjs/services/transaction-service/index.js +15 -1
- package/cjs/utils/number.js +3 -1
- package/koni/api/staking/bonding/index.d.ts +1 -0
- package/koni/api/staking/bonding/index.js +2 -0
- package/koni/api/staking/bonding/paraChain.js +6 -3
- package/koni/background/cron.d.ts +0 -5
- package/koni/background/cron.js +1 -29
- package/koni/background/handlers/Extension.js +17 -11
- package/koni/background/handlers/State.d.ts +1 -12
- package/koni/background/handlers/State.js +4 -46
- package/koni/background/subscription.d.ts +1 -11
- package/koni/background/subscription.js +2 -157
- package/package.json +6 -6
- package/packageInfo.js +1 -1
- package/services/campaign-service/index.js +19 -0
- package/services/chain-service/constants.js +3 -2
- package/services/earning-service/constants/chains.js +1 -1
- package/services/earning-service/handlers/base.d.ts +1 -0
- package/services/earning-service/handlers/base.js +9 -6
- package/services/earning-service/handlers/lending/base.d.ts +2 -0
- package/services/earning-service/handlers/lending/base.js +61 -0
- package/services/earning-service/handlers/lending/interlay.js +4 -3
- package/services/earning-service/handlers/liquid-staking/acala.js +4 -3
- package/services/earning-service/handlers/liquid-staking/base.d.ts +2 -0
- package/services/earning-service/handlers/liquid-staking/base.js +55 -1
- package/services/earning-service/handlers/liquid-staking/bifrost.js +4 -3
- package/services/earning-service/handlers/liquid-staking/parallel.js +4 -3
- package/services/earning-service/handlers/liquid-staking/stella-swap.js +16 -7
- package/services/earning-service/handlers/native-staking/amplitude.js +7 -2
- package/services/earning-service/handlers/native-staking/astar.js +7 -2
- package/services/earning-service/handlers/native-staking/base.js +5 -3
- package/services/earning-service/handlers/native-staking/para-chain.js +7 -2
- package/services/earning-service/handlers/native-staking/relay-chain.js +12 -3
- package/services/earning-service/handlers/nomination-pool/index.js +10 -4
- package/services/earning-service/handlers/special.d.ts +0 -1
- package/services/earning-service/handlers/special.js +58 -68
- package/services/earning-service/service.d.ts +49 -1
- package/services/earning-service/service.js +358 -28
- package/services/event-service/index.d.ts +1 -0
- package/services/event-service/index.js +1 -0
- package/services/event-service/types.d.ts +1 -0
- package/services/migration-service/scripts/index.js +1 -2
- package/services/storage-service/DatabaseService.d.ts +5 -0
- package/services/storage-service/DatabaseService.js +15 -0
- package/services/storage-service/db-stores/Campaign.js +9 -3
- package/services/storage-service/db-stores/YieldPositionStore.d.ts +2 -0
- package/services/storage-service/db-stores/YieldPositionStore.js +6 -0
- package/services/transaction-service/index.js +15 -1
- package/types/yield/actions/join/submit.d.ts +2 -1
- package/types/yield/info/account/reward.d.ts +2 -0
- package/utils/number.d.ts +1 -0
- package/utils/number.js +1 -0
|
@@ -147,7 +147,8 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
|
|
|
147
147
|
status: UnstakingStatus.UNLOCKING
|
|
148
148
|
});
|
|
149
149
|
}
|
|
150
|
-
const
|
|
150
|
+
const activeBalance = new BN(balance);
|
|
151
|
+
const acviteToTotal = activeBalance.mul(exchangeRate).div(decimals);
|
|
151
152
|
const totalBalance = acviteToTotal.add(unlockBalance);
|
|
152
153
|
const result = {
|
|
153
154
|
...this.baseInfo,
|
|
@@ -159,7 +160,7 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
|
|
|
159
160
|
unstakeBalance: unlockBalance.toString(),
|
|
160
161
|
isBondedBefore: totalBalance.gt(BN_ZERO),
|
|
161
162
|
derivativeToken: derivativeTokenSlug,
|
|
162
|
-
status: EarningStatus.EARNING_REWARD,
|
|
163
|
+
status: activeBalance.gt(BN_ZERO) ? EarningStatus.EARNING_REWARD : EarningStatus.NOT_EARNING,
|
|
163
164
|
nominations: [],
|
|
164
165
|
unstakings
|
|
165
166
|
};
|
|
@@ -222,9 +223,15 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
|
|
|
222
223
|
|
|
223
224
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
|
|
224
225
|
const depositCall = stakingContract.methods.deposit(params.amount);
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
226
|
+
let estimatedDepositGas = 0;
|
|
227
|
+
try {
|
|
228
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
229
|
+
estimatedDepositGas = await depositCall.estimateGas({
|
|
230
|
+
from: params.address
|
|
231
|
+
});
|
|
232
|
+
} catch (e) {
|
|
233
|
+
console.error(e);
|
|
234
|
+
}
|
|
228
235
|
const gasPrice = await evmApi.api.eth.getGasPrice();
|
|
229
236
|
return {
|
|
230
237
|
slug: this.feeAssets[0],
|
|
@@ -277,7 +284,8 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
|
|
|
277
284
|
extrinsicType: ExtrinsicType.TOKEN_APPROVE,
|
|
278
285
|
extrinsic: transactionObject,
|
|
279
286
|
txData: _data,
|
|
280
|
-
transferNativeAmount: '0'
|
|
287
|
+
transferNativeAmount: '0',
|
|
288
|
+
chainType: ChainType.EVM
|
|
281
289
|
});
|
|
282
290
|
}
|
|
283
291
|
async handleSubmitStep(data, path) {
|
|
@@ -313,7 +321,8 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
|
|
|
313
321
|
extrinsicType: ExtrinsicType.MINT_STDOT,
|
|
314
322
|
extrinsic: transactionObject,
|
|
315
323
|
txData: data,
|
|
316
|
-
transferNativeAmount: '0'
|
|
324
|
+
transferNativeAmount: '0',
|
|
325
|
+
chainType: ChainType.EVM
|
|
317
326
|
};
|
|
318
327
|
}
|
|
319
328
|
|
|
@@ -17,7 +17,7 @@ export default class AmplitudeNativeStakingPoolHandler extends BaseParaNativeSta
|
|
|
17
17
|
async subscribePoolInfo(callback) {
|
|
18
18
|
let cancel = false;
|
|
19
19
|
const nativeToken = this.nativeToken;
|
|
20
|
-
|
|
20
|
+
const defaultCallback = async () => {
|
|
21
21
|
const data = {
|
|
22
22
|
...this.baseInfo,
|
|
23
23
|
type: this.type,
|
|
@@ -26,11 +26,16 @@ export default class AmplitudeNativeStakingPoolHandler extends BaseParaNativeSta
|
|
|
26
26
|
description: this.getDescription()
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
|
-
|
|
29
|
+
const poolInfo = await this.getPoolInfo();
|
|
30
|
+
!poolInfo && callback(data);
|
|
31
|
+
};
|
|
32
|
+
if (!this.isActive) {
|
|
33
|
+
await defaultCallback();
|
|
30
34
|
return () => {
|
|
31
35
|
cancel = true;
|
|
32
36
|
};
|
|
33
37
|
}
|
|
38
|
+
await defaultCallback();
|
|
34
39
|
const substrateApi = await this.substrateApi.isReady;
|
|
35
40
|
const unsub = await substrateApi.api.query.parachainStaking.round(async _round => {
|
|
36
41
|
if (cancel) {
|
|
@@ -49,7 +49,7 @@ export default class AstarNativeStakingPoolHandler extends BaseParaNativeStaking
|
|
|
49
49
|
async subscribePoolInfo(callback) {
|
|
50
50
|
let cancel = false;
|
|
51
51
|
const nativeToken = this.nativeToken;
|
|
52
|
-
|
|
52
|
+
const defaultCallback = async () => {
|
|
53
53
|
const data = {
|
|
54
54
|
...this.baseInfo,
|
|
55
55
|
type: this.type,
|
|
@@ -58,11 +58,16 @@ export default class AstarNativeStakingPoolHandler extends BaseParaNativeStaking
|
|
|
58
58
|
description: this.getDescription()
|
|
59
59
|
}
|
|
60
60
|
};
|
|
61
|
-
|
|
61
|
+
const poolInfo = await this.getPoolInfo();
|
|
62
|
+
!poolInfo && callback(data);
|
|
63
|
+
};
|
|
64
|
+
if (!this.isActive) {
|
|
65
|
+
await defaultCallback();
|
|
62
66
|
return () => {
|
|
63
67
|
cancel = true;
|
|
64
68
|
};
|
|
65
69
|
}
|
|
70
|
+
await defaultCallback();
|
|
66
71
|
const apyPromise = new Promise(resolve => {
|
|
67
72
|
fetch(`https://api.astar.network/api/v1/${this.chain}/dapps-staking/apy`, {
|
|
68
73
|
method: 'GET'
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
5
|
-
import { BasicTxErrorType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
5
|
+
import { BasicTxErrorType, ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
6
6
|
import { YieldPoolType, YieldStepType } from '@subwallet/extension-base/types';
|
|
7
7
|
import { noop } from '@polkadot/util';
|
|
8
8
|
import BasePoolHandler from "../base.js";
|
|
@@ -59,7 +59,8 @@ export default class BaseNativeStakingPoolHandler extends BasePoolHandler {
|
|
|
59
59
|
address: address,
|
|
60
60
|
group: this.group,
|
|
61
61
|
blockTimestamp: timeStamp,
|
|
62
|
-
amount: item.amount
|
|
62
|
+
amount: item.amount,
|
|
63
|
+
eventIndex: item.event_index
|
|
63
64
|
};
|
|
64
65
|
callBack(data);
|
|
65
66
|
}
|
|
@@ -126,7 +127,8 @@ export default class BaseNativeStakingPoolHandler extends BasePoolHandler {
|
|
|
126
127
|
extrinsicType: ExtrinsicType.STAKING_BOND,
|
|
127
128
|
extrinsic,
|
|
128
129
|
txData: bondingData,
|
|
129
|
-
transferNativeAmount: amount
|
|
130
|
+
transferNativeAmount: amount,
|
|
131
|
+
chainType: ChainType.SUBSTRATE
|
|
130
132
|
};
|
|
131
133
|
}
|
|
132
134
|
|
|
@@ -17,7 +17,7 @@ export default class ParaNativeStakingPoolHandler extends BaseParaNativeStakingP
|
|
|
17
17
|
let cancel = false;
|
|
18
18
|
const chainApi = this.substrateApi;
|
|
19
19
|
const nativeToken = this.nativeToken;
|
|
20
|
-
|
|
20
|
+
const defaultCallback = async () => {
|
|
21
21
|
const data = {
|
|
22
22
|
...this.baseInfo,
|
|
23
23
|
type: this.type,
|
|
@@ -26,11 +26,16 @@ export default class ParaNativeStakingPoolHandler extends BaseParaNativeStakingP
|
|
|
26
26
|
description: this.getDescription()
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
|
-
|
|
29
|
+
const poolInfo = await this.getPoolInfo();
|
|
30
|
+
!poolInfo && callback(data);
|
|
31
|
+
};
|
|
32
|
+
if (!this.isActive) {
|
|
33
|
+
await defaultCallback();
|
|
30
34
|
return () => {
|
|
31
35
|
cancel = true;
|
|
32
36
|
};
|
|
33
37
|
}
|
|
38
|
+
await defaultCallback();
|
|
34
39
|
await chainApi.isReady;
|
|
35
40
|
const unsub = await chainApi.api.query.parachainStaking.round(async _round => {
|
|
36
41
|
var _chainApi$api$consts, _chainApi$api$consts$, _chainApi$api$consts$2;
|
|
@@ -10,6 +10,7 @@ import { _STAKING_CHAIN_GROUP } from '@subwallet/extension-base/services/earning
|
|
|
10
10
|
import { parseIdentity } from '@subwallet/extension-base/services/earning-service/utils';
|
|
11
11
|
import { EarningStatus, UnstakingStatus } from '@subwallet/extension-base/types';
|
|
12
12
|
import { balanceFormatter, formatNumber, reformatAddress } from '@subwallet/extension-base/utils';
|
|
13
|
+
import BigN from 'bignumber.js';
|
|
13
14
|
import { t } from 'i18next';
|
|
14
15
|
import { BN, BN_ZERO } from '@polkadot/util';
|
|
15
16
|
import BaseNativeStakingPoolHandler from "./base.js";
|
|
@@ -22,7 +23,7 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
|
|
|
22
23
|
const substrateApi = this.substrateApi;
|
|
23
24
|
const chainInfo = this.chainInfo;
|
|
24
25
|
const nativeToken = this.nativeToken;
|
|
25
|
-
|
|
26
|
+
const defaultCallback = async () => {
|
|
26
27
|
const data = {
|
|
27
28
|
...this.baseInfo,
|
|
28
29
|
type: this.type,
|
|
@@ -31,11 +32,16 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
|
|
|
31
32
|
description: this.getDescription()
|
|
32
33
|
}
|
|
33
34
|
};
|
|
34
|
-
|
|
35
|
+
const poolInfo = await this.getPoolInfo();
|
|
36
|
+
!poolInfo && callback(data);
|
|
37
|
+
};
|
|
38
|
+
if (!this.isActive) {
|
|
39
|
+
await defaultCallback();
|
|
35
40
|
return () => {
|
|
36
41
|
cancel = true;
|
|
37
42
|
};
|
|
38
43
|
}
|
|
44
|
+
await defaultCallback();
|
|
39
45
|
await substrateApi.isReady;
|
|
40
46
|
const unsub = await ((_substrateApi$api$que = substrateApi.api.query.staking) === null || _substrateApi$api$que === void 0 ? void 0 : _substrateApi$api$que.currentEra(async _currentEra => {
|
|
41
47
|
var _substrateApi$api$con, _substrateApi$api$con2, _substrateApi$api$que2, _substrateApi$api$que3, _substrateApi$api$que4, _substrateApi$api$que5, _substrateApi$api$que6;
|
|
@@ -127,7 +133,10 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
|
|
|
127
133
|
let nominationStatus = EarningStatus.NOT_EARNING;
|
|
128
134
|
const [[identity], _eraStaker] = await Promise.all([parseIdentity(substrateApi, validatorAddress), substrateApi.api.query.staking.erasStakers(currentEra, validatorAddress)]);
|
|
129
135
|
const eraStaker = _eraStaker.toPrimitive();
|
|
130
|
-
const
|
|
136
|
+
const sortedNominators = eraStaker.others.sort((a, b) => {
|
|
137
|
+
return new BigN(b.value).minus(a.value).toNumber();
|
|
138
|
+
});
|
|
139
|
+
const topNominators = sortedNominators.map(nominator => {
|
|
131
140
|
return nominator.who;
|
|
132
141
|
});
|
|
133
142
|
if (!topNominators.includes(reformatAddress(address, _getChainSubstrateAddressPrefix(chainInfo)))) {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
5
|
-
import { APIItemState, BasicTxErrorType, ExtrinsicType, StakingTxErrorType, StakingType } from '@subwallet/extension-base/background/KoniTypes';
|
|
5
|
+
import { APIItemState, BasicTxErrorType, ChainType, ExtrinsicType, StakingTxErrorType, StakingType } from '@subwallet/extension-base/background/KoniTypes';
|
|
6
6
|
import { calculateChainStakedReturn, calculateInflation, getExistUnstakeErrorMessage, getMinStakeErrorMessage, parsePoolStashAddress } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
|
|
7
7
|
import { _EXPECTED_BLOCK_TIME, _STAKING_ERA_LENGTH_MAP } from '@subwallet/extension-base/services/chain-service/constants';
|
|
8
8
|
import { _getChainSubstrateAddressPrefix } from '@subwallet/extension-base/services/chain-service/utils';
|
|
@@ -46,7 +46,7 @@ export default class NominationPoolHandler extends BasePoolHandler {
|
|
|
46
46
|
const substrateApi = this.substrateApi;
|
|
47
47
|
const chainInfo = this.chainInfo;
|
|
48
48
|
const nativeToken = this.nativeToken;
|
|
49
|
-
|
|
49
|
+
const defaultCallback = async () => {
|
|
50
50
|
const data = {
|
|
51
51
|
...this.baseInfo,
|
|
52
52
|
type: this.type,
|
|
@@ -55,11 +55,16 @@ export default class NominationPoolHandler extends BasePoolHandler {
|
|
|
55
55
|
description: this.getDescription()
|
|
56
56
|
}
|
|
57
57
|
};
|
|
58
|
-
|
|
58
|
+
const poolInfo = await this.getPoolInfo();
|
|
59
|
+
!poolInfo && callback(data);
|
|
60
|
+
};
|
|
61
|
+
if (!this.isActive) {
|
|
62
|
+
await defaultCallback();
|
|
59
63
|
return () => {
|
|
60
64
|
cancel = true;
|
|
61
65
|
};
|
|
62
66
|
}
|
|
67
|
+
await defaultCallback();
|
|
63
68
|
await substrateApi.isReady;
|
|
64
69
|
const unsub = await ((_substrateApi$api$que = substrateApi.api.query.staking) === null || _substrateApi$api$que === void 0 ? void 0 : _substrateApi$api$que.currentEra(async _currentEra => {
|
|
65
70
|
var _substrateApi$api$que2, _substrateApi$api$que3, _substrateApi$api$que4;
|
|
@@ -461,7 +466,8 @@ export default class NominationPoolHandler extends BasePoolHandler {
|
|
|
461
466
|
extrinsicType: ExtrinsicType.STAKING_JOIN_POOL,
|
|
462
467
|
extrinsic,
|
|
463
468
|
txData: joinPoolData,
|
|
464
|
-
transferNativeAmount: amount
|
|
469
|
+
transferNativeAmount: amount,
|
|
470
|
+
chainType: ChainType.SUBSTRATE
|
|
465
471
|
};
|
|
466
472
|
}
|
|
467
473
|
|
|
@@ -57,7 +57,6 @@ export default abstract class BaseSpecialStakingPoolHandler extends BasePoolHand
|
|
|
57
57
|
handleXcmStep(data: SubmitYieldJoinData, path: OptimalYieldPath, xcmFee: string): Promise<HandleYieldStepData>;
|
|
58
58
|
abstract handleSubmitStep(data: SubmitYieldJoinData, path: OptimalYieldPath): Promise<HandleYieldStepData>;
|
|
59
59
|
handleYieldJoin(data: SubmitYieldJoinData, path: OptimalYieldPath, currentStep: number): Promise<HandleYieldStepData>;
|
|
60
|
-
validateYieldLeave(amount: string, address: string, fastLeave: boolean, selectedTarget?: string): Promise<TransactionError[]>;
|
|
61
60
|
handleYieldUnstake(amount: string, address: string, selectedTarget?: string): Promise<[ExtrinsicType, TransactionData]>;
|
|
62
61
|
handleYieldCancelUnstake(): Promise<TransactionData>;
|
|
63
62
|
handleYieldClaimReward(address: string, bondReward?: boolean): Promise<TransactionData>;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import { COMMON_CHAIN_SLUGS } from '@subwallet/chain-list';
|
|
5
5
|
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
6
|
-
import { BasicTxErrorType,
|
|
6
|
+
import { BasicTxErrorType, ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
7
7
|
import { ALL_ACCOUNT_KEY } from '@subwallet/extension-base/constants';
|
|
8
8
|
import { createXcmExtrinsic } from '@subwallet/extension-base/koni/api/xcm';
|
|
9
9
|
import { YIELD_POOL_STAT_REFRESH_INTERVAL } from '@subwallet/extension-base/koni/api/yield/helper/utils';
|
|
@@ -55,7 +55,7 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
55
55
|
if (!poolInfo || !((_poolInfo$statistic = poolInfo.statistic) !== null && _poolInfo$statistic !== void 0 && _poolInfo$statistic.earningThreshold.join)) {
|
|
56
56
|
return {
|
|
57
57
|
passed: false,
|
|
58
|
-
errorMessage: 'There
|
|
58
|
+
errorMessage: 'There is a problem fetching your data. Check your Internet connection or change the network endpoint and try again.'
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
61
|
if (request.address === ALL_ACCOUNT_KEY) {
|
|
@@ -76,14 +76,13 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
76
76
|
const bnMinJoinPool = new BN(poolInfo.statistic.earningThreshold.join);
|
|
77
77
|
const inputTokenInfo = this.state.chainService.getAssetBySlug(this.inputAsset);
|
|
78
78
|
const altInputTokenInfo = this.state.chainService.getAssetBySlug(this.altInputAsset);
|
|
79
|
-
const minJoinDiv = BN_TEN.pow(new BN(inputAssetInfo.decimals || 0));
|
|
80
|
-
const parsedMinJoinPool = bnMinJoinPool.div(minJoinDiv);
|
|
81
79
|
if (bnInputAssetBalance.add(bnAltInputAssetBalance).lt(bnMinJoinPool)) {
|
|
82
80
|
const originChain = this.state.getChainInfo(inputTokenInfo.originChain);
|
|
83
81
|
const altChain = this.state.getChainInfo(altInputTokenInfo.originChain);
|
|
82
|
+
const parsedMinJoinPool = formatNumber(bnMinJoinPool.toString(), inputAssetInfo.decimals || 0);
|
|
84
83
|
return {
|
|
85
84
|
passed: false,
|
|
86
|
-
errorMessage: `You need at least ${parsedMinJoinPool
|
|
85
|
+
errorMessage: `You need at least ${parsedMinJoinPool} ${inputTokenInfo.symbol} (${originChain.name}) or ${altInputTokenInfo.symbol} (${altChain.name}) to start earning`
|
|
87
86
|
};
|
|
88
87
|
}
|
|
89
88
|
if (this.feeAssets.length === 1) {
|
|
@@ -113,24 +112,29 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
113
112
|
|
|
114
113
|
async subscribePoolInfo(callback) {
|
|
115
114
|
let cancel = false;
|
|
115
|
+
const _callback = data => {
|
|
116
|
+
!cancel && callback(data);
|
|
117
|
+
};
|
|
118
|
+
const defaultCallback = async () => {
|
|
119
|
+
const data = {
|
|
120
|
+
...this.baseInfo,
|
|
121
|
+
type: this.type,
|
|
122
|
+
metadata: {
|
|
123
|
+
...this.metadataInfo,
|
|
124
|
+
description: this.getDescription()
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
const poolInfo = await this.getPoolInfo();
|
|
128
|
+
!poolInfo && _callback(data);
|
|
129
|
+
};
|
|
116
130
|
const getStatInterval = () => {
|
|
117
131
|
if (!this.isActive) {
|
|
118
|
-
|
|
119
|
-
const rs = {
|
|
120
|
-
...this.baseInfo,
|
|
121
|
-
type: this.type,
|
|
122
|
-
metadata: {
|
|
123
|
-
...this.metadataInfo,
|
|
124
|
-
description: this.getDescription()
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
callback(rs);
|
|
128
|
-
}
|
|
132
|
+
defaultCallback().catch(console.error);
|
|
129
133
|
} else {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
+
defaultCallback().then(() => {
|
|
135
|
+
return this.getPoolStat();
|
|
136
|
+
}).then(rs => {
|
|
137
|
+
_callback(rs);
|
|
134
138
|
}).catch(console.error);
|
|
135
139
|
}
|
|
136
140
|
};
|
|
@@ -263,6 +267,7 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
263
267
|
const bnAmount = new BN(params.amount);
|
|
264
268
|
const altInputTokenSlug = this.altInputAsset || '';
|
|
265
269
|
const altInputTokenInfo = this.state.getAssetBySlug(altInputTokenSlug);
|
|
270
|
+
const inputTokenInfo = this.state.getAssetBySlug(this.inputAsset);
|
|
266
271
|
const altInputTokenBalance = await this.state.balanceService.getTokenFreeBalance(params.address, altInputTokenInfo.originChain, altInputTokenSlug);
|
|
267
272
|
const missingAmount = bnAmount.sub(bnInputTokenBalance); // TODO: what if input token is not LOCAL ??
|
|
268
273
|
const xcmFee = new BN(path.totalFee[1].amount || '0');
|
|
@@ -273,6 +278,26 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
273
278
|
processValidation.failedStep = path.steps[1];
|
|
274
279
|
processValidation.ok = false;
|
|
275
280
|
processValidation.status = YieldValidationStatus.NOT_ENOUGH_BALANCE;
|
|
281
|
+
const maxBn = bnInputTokenBalance.add(new BN(altInputTokenBalance.value)).sub(xcmFee).sub(altInputTokenMinAmount);
|
|
282
|
+
const maxValue = formatNumber(maxBn.toString(), inputTokenInfo.decimals || 0);
|
|
283
|
+
const altInputTokenInfo = this.state.getAssetBySlug(altInputTokenSlug);
|
|
284
|
+
const symbol = altInputTokenInfo.symbol;
|
|
285
|
+
const altNetwork = this.state.getChainInfo(altInputTokenInfo.originChain);
|
|
286
|
+
const inputNetworkName = this.chainInfo.name;
|
|
287
|
+
const altNetworkName = altNetwork.name;
|
|
288
|
+
const currentValue = formatNumber(bnInputTokenBalance.toString(), inputTokenInfo.decimals || 0);
|
|
289
|
+
const bnMaxXCM = new BN(altInputTokenBalance.value).sub(xcmFee).sub(altInputTokenMinAmount);
|
|
290
|
+
const maxXCMValue = formatNumber(bnMaxXCM.toString(), inputTokenInfo.decimals || 0);
|
|
291
|
+
processValidation.message = t('You can only enter a maximum of {{maxValue}} {{symbol}}, which is {{currentValue}} {{symbol}} ({{inputNetworkName}}) and {{maxXCMValue}} {{symbol}} ({{altNetworkName}}). Lower your amount and try again.', {
|
|
292
|
+
replace: {
|
|
293
|
+
symbol,
|
|
294
|
+
maxValue,
|
|
295
|
+
inputNetworkName,
|
|
296
|
+
altNetworkName,
|
|
297
|
+
currentValue,
|
|
298
|
+
maxXCMValue
|
|
299
|
+
}
|
|
300
|
+
});
|
|
276
301
|
return [new TransactionError(YieldValidationStatus.NOT_ENOUGH_BALANCE, processValidation.message, processValidation)];
|
|
277
302
|
}
|
|
278
303
|
return [];
|
|
@@ -292,6 +317,7 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
292
317
|
};
|
|
293
318
|
const feeTokenSlug = path.totalFee[id].slug;
|
|
294
319
|
const feeTokenInfo = this.state.getAssetBySlug(feeTokenSlug);
|
|
320
|
+
const inputTokenInfo = this.state.getAssetBySlug(this.inputAsset);
|
|
295
321
|
const defaultFeeTokenSlug = this.feeAssets[0];
|
|
296
322
|
const bnAmount = new BN(params.amount);
|
|
297
323
|
if (this.feeAssets.length === 1 && feeTokenSlug === defaultFeeTokenSlug) {
|
|
@@ -317,6 +343,16 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
317
343
|
processValidation.failedStep = path.steps[id];
|
|
318
344
|
processValidation.ok = false;
|
|
319
345
|
processValidation.status = YieldValidationStatus.NOT_ENOUGH_BALANCE;
|
|
346
|
+
const maxString = formatNumber(bnInputTokenBalance.toString(), inputTokenInfo.decimals || 0);
|
|
347
|
+
if (maxString !== '0') {
|
|
348
|
+
processValidation.message = t('Amount must be equal or less than {{number}}', {
|
|
349
|
+
replace: {
|
|
350
|
+
number: maxString
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
} else {
|
|
354
|
+
processValidation.message = t('You need balance greater than 0 to continue');
|
|
355
|
+
}
|
|
320
356
|
return [new TransactionError(YieldValidationStatus.NOT_ENOUGH_BALANCE, processValidation.message, processValidation)];
|
|
321
357
|
}
|
|
322
358
|
return [];
|
|
@@ -400,7 +436,8 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
400
436
|
extrinsicType: ExtrinsicType.TRANSFER_XCM,
|
|
401
437
|
extrinsic,
|
|
402
438
|
txData: xcmData,
|
|
403
|
-
transferNativeAmount: bnTotalAmount.toString()
|
|
439
|
+
transferNativeAmount: bnTotalAmount.toString(),
|
|
440
|
+
chainType: ChainType.SUBSTRATE
|
|
404
441
|
};
|
|
405
442
|
}
|
|
406
443
|
handleYieldJoin(data, path, currentStep) {
|
|
@@ -426,53 +463,6 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
426
463
|
|
|
427
464
|
/* Leave pool action */
|
|
428
465
|
|
|
429
|
-
async validateYieldLeave(amount, address, fastLeave, selectedTarget) {
|
|
430
|
-
const poolInfo = await this.getPoolInfo();
|
|
431
|
-
const poolPosition = await this.getPoolPosition(address);
|
|
432
|
-
if (!poolInfo || !poolInfo.statistic || !poolPosition) {
|
|
433
|
-
return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
|
|
434
|
-
}
|
|
435
|
-
if (!this.availableMethod.defaultUnstake && !fastLeave) {
|
|
436
|
-
return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
|
|
437
|
-
}
|
|
438
|
-
if (!this.availableMethod.fastUnstake && fastLeave) {
|
|
439
|
-
return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
|
|
440
|
-
}
|
|
441
|
-
const errors = [];
|
|
442
|
-
const bnActiveStake = new BN(poolPosition.activeStake);
|
|
443
|
-
const bnAmount = new BN(amount);
|
|
444
|
-
const bnRemainingStake = bnActiveStake.sub(bnAmount);
|
|
445
|
-
const minStake = new BN(poolInfo.statistic.earningThreshold.join || '0');
|
|
446
|
-
const minUnstake = new BN((fastLeave ? poolInfo.statistic.earningThreshold.fastUnstake : poolInfo.statistic.earningThreshold.defaultUnstake) || '0');
|
|
447
|
-
const maxUnstakeRequest = poolInfo.statistic.maxWithdrawalRequestPerFarmer;
|
|
448
|
-
const derivativeTokenInfo = this.state.getAssetBySlug(this.derivativeAssets[0]);
|
|
449
|
-
if (bnAmount.lte(BN_ZERO)) {
|
|
450
|
-
return [new TransactionError(BasicTxErrorType.INVALID_PARAMS, t('Amount must be greater than 0'))];
|
|
451
|
-
}
|
|
452
|
-
if (bnAmount.lt(minUnstake)) {
|
|
453
|
-
const minUnstakeStr = formatNumber(minUnstake.toString(), derivativeTokenInfo.decimals || 0);
|
|
454
|
-
errors.push(new TransactionError(StakingTxErrorType.NOT_ENOUGH_MIN_UNSTAKE, t('You need to unstake at least {{amount}} {{token}}', {
|
|
455
|
-
replace: {
|
|
456
|
-
amount: minUnstakeStr,
|
|
457
|
-
token: derivativeTokenInfo.symbol
|
|
458
|
-
}
|
|
459
|
-
})));
|
|
460
|
-
}
|
|
461
|
-
if (!fastLeave) {
|
|
462
|
-
if (!(bnRemainingStake.isZero() || bnRemainingStake.gte(minStake))) {
|
|
463
|
-
errors.push(new TransactionError(StakingTxErrorType.INVALID_ACTIVE_STAKE)); // TODO
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
if (poolPosition.unstakings.length > maxUnstakeRequest) {
|
|
467
|
-
errors.push(new TransactionError(StakingTxErrorType.EXCEED_MAX_UNSTAKING, t('You cannot unstake more than {{number}} times', {
|
|
468
|
-
replace: {
|
|
469
|
-
number: maxUnstakeRequest
|
|
470
|
-
}
|
|
471
|
-
})));
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
return Promise.resolve(errors);
|
|
475
|
-
}
|
|
476
466
|
handleYieldUnstake(amount, address, selectedTarget) {
|
|
477
467
|
return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
|
|
478
468
|
}
|
|
@@ -1,31 +1,79 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
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';
|
|
5
|
+
import { PersistDataServiceInterface, ServiceStatus, StoppableServiceInterface } from '@subwallet/extension-base/services/base/types';
|
|
4
6
|
import { EarningRewardHistoryItem, EarningRewardItem, EarningRewardJson, HandleYieldStepData, HandleYieldStepParams, OptimalYieldPath, OptimalYieldPathParams, RequestEarlyValidateYield, RequestStakeCancelWithdrawal, RequestStakeClaimReward, RequestYieldLeave, RequestYieldWithdrawal, ResponseEarlyValidateYield, TransactionData, ValidateYieldProcessParams, YieldPoolInfo, YieldPoolTarget, YieldPositionInfo } from '@subwallet/extension-base/types';
|
|
7
|
+
import { PromiseHandler } from '@subwallet/extension-base/utils';
|
|
5
8
|
import { BehaviorSubject } from 'rxjs';
|
|
6
9
|
import { BasePoolHandler } from './handlers';
|
|
7
|
-
export default class EarningService {
|
|
10
|
+
export default class EarningService implements StoppableServiceInterface, PersistDataServiceInterface {
|
|
8
11
|
protected readonly state: KoniState;
|
|
9
12
|
protected handlers: Record<string, BasePoolHandler>;
|
|
10
13
|
private earningRewardSubject;
|
|
11
14
|
private earningRewardHistorySubject;
|
|
12
15
|
private minAmountPercentSubject;
|
|
16
|
+
readonly yieldPoolInfoSubject: BehaviorSubject<Record<string, YieldPoolInfo>>;
|
|
17
|
+
readonly yieldPositionSubject: BehaviorSubject<Record<string, YieldPositionInfo>>;
|
|
18
|
+
readonly yieldPositionListSubject: BehaviorSubject<YieldPositionInfo[]>;
|
|
19
|
+
private dbService;
|
|
20
|
+
private eventService;
|
|
13
21
|
constructor(state: KoniState);
|
|
14
22
|
private initHandlers;
|
|
23
|
+
startPromiseHandler: PromiseHandler<void>;
|
|
24
|
+
stopPromiseHandler: PromiseHandler<void>;
|
|
25
|
+
status: ServiceStatus;
|
|
26
|
+
init(): Promise<void>;
|
|
27
|
+
handleActions(): void;
|
|
28
|
+
loadData(): Promise<void>;
|
|
29
|
+
persistData(): Promise<void>;
|
|
30
|
+
start(): Promise<void>;
|
|
31
|
+
stop(): Promise<void>;
|
|
32
|
+
waitForStarted(): Promise<void>;
|
|
33
|
+
waitForStopped(): Promise<void>;
|
|
15
34
|
getPoolHandler(slug: string): BasePoolHandler | undefined;
|
|
16
35
|
isPoolSupportAlternativeFee(slug: string): boolean;
|
|
17
36
|
subscribeMinAmountPercent(): BehaviorSubject<Record<string, number>>;
|
|
18
37
|
getMinAmountPercent(): Record<string, number>;
|
|
38
|
+
getYieldPool(slug: string): Promise<YieldPoolInfo | undefined>;
|
|
19
39
|
subscribePoolsInfo(callback: (rs: YieldPoolInfo) => void): Promise<VoidFunction>;
|
|
40
|
+
private getYieldPoolInfoFromDBAndOnline;
|
|
41
|
+
subscribeYieldPoolInfo(): BehaviorSubject<Record<string, YieldPoolInfo>>;
|
|
42
|
+
getYieldPoolInfo(): Promise<YieldPoolInfo[]>;
|
|
43
|
+
private yieldPoolPersistQueue;
|
|
44
|
+
updateYieldPoolInfo(data: YieldPoolInfo): void;
|
|
45
|
+
private yieldPoolsInfoUnsub;
|
|
46
|
+
runSubscribePoolsInfo(): Promise<void>;
|
|
47
|
+
runUnsubscribePoolsInfo(): void;
|
|
48
|
+
getYieldPosition(address: string, slug: string): Promise<YieldPositionInfo | undefined>;
|
|
20
49
|
subscribePoolPositions(addresses: string[], callback: (rs: YieldPositionInfo) => void): Promise<VoidFunction>;
|
|
50
|
+
removeYieldPositions(chains?: string[], addresses?: string[]): Promise<void>;
|
|
51
|
+
private getYieldPositionFromDB;
|
|
52
|
+
subscribeYieldPosition(): BehaviorSubject<YieldPositionInfo[]>;
|
|
53
|
+
getYieldPositionInfo(): Promise<YieldPositionInfo[]>;
|
|
54
|
+
yieldPositionPersistQueue: YieldPositionInfo[];
|
|
55
|
+
resetYieldPositionQueue(): void;
|
|
56
|
+
resetYieldPosition(): void;
|
|
57
|
+
private _getYieldPositionKey;
|
|
58
|
+
updateYieldPosition(data: YieldPositionInfo): void;
|
|
59
|
+
reloadEarning(reset?: boolean): Promise<void>;
|
|
60
|
+
private yieldPositionUnsub;
|
|
61
|
+
runSubscribePoolsPosition(): Promise<void>;
|
|
62
|
+
runUnsubscribePoolsPosition(): void;
|
|
21
63
|
updateEarningReward(stakingRewardData: EarningRewardItem): void;
|
|
22
64
|
getPoolReward(addresses: string[], callback: (result: EarningRewardItem) => void): Promise<VoidFunction>;
|
|
23
65
|
subscribeEarningReward(): BehaviorSubject<EarningRewardJson>;
|
|
24
66
|
getEarningRewards(): EarningRewardJson;
|
|
67
|
+
earningsRewardInterval: NodeJS.Timer | undefined;
|
|
68
|
+
runSubscribeStakingRewardInterval(): void;
|
|
69
|
+
runUnsubscribeStakingRewardInterval(): void;
|
|
25
70
|
fetchPoolRewardHistory(addresses: string[], callback: (result: EarningRewardHistoryItem) => void): Promise<VoidFunction>;
|
|
26
71
|
updateEarningRewardHistory(earningRewardHistory: EarningRewardHistoryItem): void;
|
|
27
72
|
subscribeEarningRewardHistory(): BehaviorSubject<Record<string, EarningRewardHistoryItem>>;
|
|
28
73
|
getEarningRewardHistory(): Record<string, EarningRewardHistoryItem>;
|
|
74
|
+
earningsRewardHistoryInterval: NodeJS.Timer | undefined;
|
|
75
|
+
runSubscribeEarningRewardHistoryInterval(): void;
|
|
76
|
+
runUnsubscribeEarningRewardHistoryInterval(): void;
|
|
29
77
|
/**
|
|
30
78
|
* @async
|
|
31
79
|
* @function getPoolTargets
|