Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Issue-2581] Fix bug showing withdrawal time on unstaking #2611

Merged
merged 20 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
67e58cb
[Issue-2581] Fix bug showing withdrawal time on unstaking
Feb 16, 2024
621fd8b
[Issue-2581] Update display waiting time, fix bug round waiting
bluezdot Feb 21, 2024
55a3f07
[Issue-2581] Update display content
bluezdot Feb 21, 2024
d85fdd7
[Issue-2581] Update display content
bluezdot Feb 21, 2024
54bb132
[Issue-2581] Update realtime for unstaking in direct staking
bluezdot Feb 22, 2024
074155f
[Issue-2581] Update realtime for unstaking in nomination pool
bluezdot Feb 22, 2024
b430e5d
[Issue-2581] Update realtime for Button withdraw
bluezdot Feb 22, 2024
061eec1
Revert "[Issue-2581] Update realtime for Button withdraw"
bluezdot Feb 22, 2024
640fd8b
[Issue-2581] Update realtime for Button withdraw
bluezdot Feb 22, 2024
26b0ba5
Update earning withdraw logic
Feb 22, 2024
7eb56cb
[Issue-2581] update interface for UnstakingInfo
bluezdot Feb 22, 2024
32f7dc1
[Issue-2581] note to update waiting time for earning
bluezdot Feb 22, 2024
5e79c5d
fix eslint
bluezdot Feb 22, 2024
1dd39fc
[Issue-2581] update timestamp for all staking chains
bluezdot Feb 23, 2024
f5b7e0e
[Issue-2581] Rollback and fix show waiting time on other pool (parac …
S2kael Feb 23, 2024
3fa16c3
Merge branch 'subwallet-dev' into koni/dev/issue-2581
S2kael Feb 23, 2024
d6ecd9a
[Issue-2581] Fix wrong claimable value
S2kael Feb 23, 2024
6c24dc2
Merge branch 'subwallet-dev' into koni/dev/issue-2581
S2kael Feb 29, 2024
82d5914
[Issue-2581] Update text withdraw time for auto withdraw pool
S2kael Feb 29, 2024
df96339
[Issue-2581] Update withdraw condition
S2kael Feb 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/extension-base/src/background/KoniTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,10 @@
externalUrl?: string;
rarity?: string;
description?: string;
properties?: Record<any, any> | null;

Check warning on line 231 in packages/extension-base/src/background/KoniTypes.ts

View workflow job for this annotation

GitHub Actions / Build Development Preview

Unexpected any. Specify a different type

Check warning on line 231 in packages/extension-base/src/background/KoniTypes.ts

View workflow job for this annotation

GitHub Actions / Build Development Preview

Unexpected any. Specify a different type
type?: _AssetType.ERC721 | _AssetType.PSP34 | RMRK_VER; // for sending
rmrk_ver?: RMRK_VER;
onChainOption?: any; // for sending PSP-34 tokens, should be done better

Check warning on line 234 in packages/extension-base/src/background/KoniTypes.ts

View workflow job for this annotation

GitHub Actions / Build Development Preview

Unexpected any. Specify a different type
}

export interface NftCollection {
Expand Down Expand Up @@ -525,7 +525,7 @@
[ExtrinsicType.STAKING_COMPOUNDING]: RequestTuringStakeCompound,
[ExtrinsicType.STAKING_CANCEL_COMPOUNDING]: RequestTuringCancelStakeCompound,
[ExtrinsicType.STAKING_CANCEL_UNSTAKE]: RequestStakeCancelWithdrawal,
[ExtrinsicType.STAKING_POOL_WITHDRAW]: any,

Check warning on line 528 in packages/extension-base/src/background/KoniTypes.ts

View workflow job for this annotation

GitHub Actions / Build Development Preview

Unexpected any. Specify a different type

// Yield
[ExtrinsicType.JOIN_YIELD_POOL]: RequestYieldStepSubmit,
Expand Down Expand Up @@ -554,8 +554,8 @@
[ExtrinsicType.TOKEN_APPROVE]: TokenApproveData,

[ExtrinsicType.EVM_EXECUTE]: TransactionConfig,
[ExtrinsicType.CROWDLOAN]: any,

Check warning on line 557 in packages/extension-base/src/background/KoniTypes.ts

View workflow job for this annotation

GitHub Actions / Build Development Preview

Unexpected any. Specify a different type
[ExtrinsicType.UNKNOWN]: any

Check warning on line 558 in packages/extension-base/src/background/KoniTypes.ts

View workflow job for this annotation

GitHub Actions / Build Development Preview

Unexpected any. Specify a different type
}

export enum ExtrinsicStatus {
Expand Down Expand Up @@ -648,7 +648,7 @@
// : T extends ExtrinsicType.MINT_VDOT
// ? Pick<SubmitBifrostLiquidStaking, 'rewardTokenSlug' | 'estimatedAmountReceived'>
// : undefined;
export interface TransactionHistoryItem<ET extends ExtrinsicType = ExtrinsicType.TRANSFER_BALANCE> {

Check warning on line 651 in packages/extension-base/src/background/KoniTypes.ts

View workflow job for this annotation

GitHub Actions / Build Development Preview

'ET' is defined but never used
origin?: 'app' | 'migration' | 'subsquid' | 'subscan', // 'app' or history source
callhash?: string,
signature?: string,
Expand All @@ -673,7 +673,7 @@
tip?: AmountData,
fee?: AmountData,
explorerUrl?: string,
additionalInfo?: any,

Check warning on line 676 in packages/extension-base/src/background/KoniTypes.ts

View workflow job for this annotation

GitHub Actions / Build Development Preview

Unexpected any. Specify a different type
startBlock?: number,
nonce?: number,
}
Expand Down Expand Up @@ -1116,12 +1116,12 @@
recipientAddress: string,

nftItemName?: string, // Use for confirmation view only
params: Record<string, any>,

Check warning on line 1119 in packages/extension-base/src/background/KoniTypes.ts

View workflow job for this annotation

GitHub Actions / Build Development Preview

Unexpected any. Specify a different type
nftItem: NftItem
}

export interface EvmNftTransaction extends ValidateTransactionResponse {
tx: Record<string, any> | null;

Check warning on line 1124 in packages/extension-base/src/background/KoniTypes.ts

View workflow job for this annotation

GitHub Actions / Build Development Preview

Unexpected any. Specify a different type
}

export interface EvmNftSubmitTransaction extends BaseRequestSign {
Expand Down Expand Up @@ -1607,7 +1607,8 @@
chain: string;
status: UnstakingStatus;
claimable: string; // amount to be withdrawn
waitingTime: number; // in hours
waitingTime?: number;
targetTimestampMs?: number;
validatorAddress?: string; // might unstake from a validator or not
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export const _STAKING_ERA_LENGTH_MAP: Record<string, number> = { // in hours
shibuya: 24,
bifrost_testnet: 0.5,
bifrost: 2,
bifrost_dot: 24,
ternoa: 24,
calamari: 6,
calamari_test: 6,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default class AcalaLiquidStakingPoolHandler extends BaseLiquidStakingPool
defaultUnstake: true,
fastUnstake: true,
cancelUnstake: false,
withdraw: true,
withdraw: false, // TODO: Change after verify unstake info
claimReward: false
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@ export default class BifrostLiquidStakingPoolHandler extends BaseLiquidStakingPo
const exchangeRate = new BigNumber(rate);

const currentRelayEraObj = _currentRelayEra.toPrimitive() as Record<string, number>;
const currentRelayEra = currentRelayEraObj.Era;

const currentRelayEra = currentRelayEraObj.era;

const unlockLedgerList: BifrostUnlockLedger[] = [];

Expand Down Expand Up @@ -277,13 +278,16 @@ export default class BifrostLiquidStakingPoolHandler extends BaseLiquidStakingPo
const isClaimable = unlocking.era - currentRelayEra < 0;
const remainingEra = unlocking.era - currentRelayEra;
const waitingTime = remainingEra * _STAKING_ERA_LENGTH_MAP[this.chain];
// const currentTimestampMs = Date.now();
// const targetTimestampMs = currentTimestampMs + waitingTime * 60 * 60 * 1000;

unlockBalance = unlockBalance.add(new BN(unlocking.balance));
unstakingList.push({
chain: this.chain,
status: isClaimable ? UnstakingStatus.CLAIMABLE : UnstakingStatus.UNLOCKING,
claimable: unlocking.balance,
waitingTime: waitingTime
// targetTimestampMs: targetTimestampMs
} as UnstakingInfo);
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ export default class ParallelLiquidStakingPoolHandler extends BaseLiquidStakingP
const remainingEra = chunk.era - currentEra;
const eraTime = _STAKING_ERA_LENGTH_MAP[this.chain] || _STAKING_ERA_LENGTH_MAP.default;
const waitingTime = remainingEra * eraTime;
// const currentTimestampMs = Date.now();
// const targetTimestampMs = currentTimestampMs + waitingTime * 60 * 60 * 1000;

totalBalance = totalBalance.add(amount);
unlockingBalance = unlockingBalance.add(amount);
Expand All @@ -185,6 +187,7 @@ export default class ParallelLiquidStakingPoolHandler extends BaseLiquidStakingP
status: isClaimable ? UnstakingStatus.CLAIMABLE : UnstakingStatus.UNLOCKING,
claimable: amount.toString(),
waitingTime: waitingTime
// targetTimestampMs: targetTimestampMs
} as UnstakingInfo);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ export default class AmplitudeNativeStakingPoolHandler extends BaseParaNativeSta
const isClaimable = parseInt(unstakingBlock) - currentBlockNumber < 0;
const remainingBlock = parseInt(unstakingBlock) - currentBlockNumber;
const waitingTime = remainingBlock * blockDuration;
// const currentTimestampMs = Date.now();
// const targetTimestampMs = currentTimestampMs + waitingTime * 60 * 60 * 1000;

unstakingBalance = unstakingAmount.toString();

Expand All @@ -208,6 +210,7 @@ export default class AmplitudeNativeStakingPoolHandler extends BaseParaNativeSta
status: isClaimable ? UnstakingStatus.CLAIMABLE : UnstakingStatus.UNLOCKING,
claimable: unstakingAmount.toString(),
waitingTime,
// targetTimestampMs: targetTimestampMs,
validatorAddress: undefined
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ export function getAstarWithdrawable (yieldPosition: YieldPositionInfo): Unstaki
const unstakingInfo: UnstakingInfo = {
chain: yieldPosition.chain,
status: UnstakingStatus.CLAIMABLE,
claimable: '0',
waitingTime: 0
claimable: '0'
};

let bnWithdrawable = BN_ZERO;
Expand Down Expand Up @@ -249,12 +248,15 @@ export default class AstarNativeStakingPoolHandler extends BaseParaNativeStaking
const isClaimable = unlockingChunk.unlockEra - parseInt(currentEra) < 0;
const remainingEra = unlockingChunk.unlockEra - parseInt(currentEra);
const waitingTime = remainingEra * _STAKING_ERA_LENGTH_MAP[chainInfo.slug];
// const currentTimestampMs = Date.now();
// const targetTimestampMs = currentTimestampMs + waitingTime * 60 * 60 * 1000;

unstakingList.push({
chain: chainInfo.slug,
status: isClaimable ? UnstakingStatus.CLAIMABLE : UnstakingStatus.UNLOCKING,
claimable: unlockingChunk.amount.toString(),
waitingTime
// targetTimestampMs: targetTimestampMs
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,16 @@ export default class ParaNativeStakingPoolHandler extends BaseParaNativeStakingP
const remainingEra = scheduledRequest.whenExecutable - currentRound;
const waitingTime = remainingEra * _STAKING_ERA_LENGTH_MAP[chainInfo.slug];
const claimable = Object.values(scheduledRequest.action)[0];
// const currentTimestampMs = Date.now();
// const targetTimestampMs = currentTimestampMs + waitingTime * 60 * 60 * 1000;

unstakingMap[delegation.owner] = {
chain: chainInfo.slug,
status: isClaimable ? UnstakingStatus.CLAIMABLE : UnstakingStatus.UNLOCKING,
validatorAddress: delegation.owner,
claimable: claimable.toString(),
waitingTime
// targetTimestampMs: targetTimestampMs
} as UnstakingInfo;

hasUnstaking = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/
import { _getChainSubstrateAddressPrefix } from '@subwallet/extension-base/services/chain-service/utils';
import { _STAKING_CHAIN_GROUP } from '@subwallet/extension-base/services/earning-service/constants';
import { parseIdentity } from '@subwallet/extension-base/services/earning-service/utils';
import { BaseYieldPositionInfo, EarningStatus, NativeYieldPoolInfo, OptimalYieldPath, PalletStakingExposure, PalletStakingNominations, PalletStakingStakingLedger, PalletStakingValidatorPrefs, StakeCancelWithdrawalParams, SubmitJoinNativeStaking, SubmitYieldJoinData, TernoaStakingRewardsStakingRewardsData, TransactionData, UnstakingStatus, ValidatorExtraInfo, ValidatorInfo, YieldPoolInfo, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
import { BaseYieldPositionInfo, EarningStatus, NativeYieldPoolInfo, OptimalYieldPath, PalletStakingActiveEraInfo, PalletStakingExposure, PalletStakingNominations, PalletStakingStakingLedger, PalletStakingValidatorPrefs, StakeCancelWithdrawalParams, SubmitJoinNativeStaking, SubmitYieldJoinData, TernoaStakingRewardsStakingRewardsData, TransactionData, UnstakingStatus, ValidatorExtraInfo, ValidatorInfo, YieldPoolInfo, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
import { balanceFormatter, formatNumber, reformatAddress } from '@subwallet/extension-base/utils';
import BigN from 'bignumber.js';
import { t } from 'i18next';
Expand Down Expand Up @@ -159,11 +159,11 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
async parseNominatorMetadata (chainInfo: _ChainInfo, address: string, substrateApi: _SubstrateApi, ledger: PalletStakingStakingLedger, currentEra: string, minStake: BN, _deriveSessionProgress: DeriveSessionProgress): Promise<Omit<YieldPositionInfo, keyof BaseYieldPositionInfo>> {
const chain = chainInfo.slug;

const [_nominations, _bonded] = await Promise.all([
const [_nominations, _bonded, _activeEra] = await Promise.all([
substrateApi.api.query?.staking?.nominators(address),
substrateApi.api.query?.staking?.bonded(address)
substrateApi.api.query?.staking?.bonded(address),
substrateApi.api.query?.staking?.activeEra()
]);

const unlimitedNominatorRewarded = substrateApi.api.consts.staking.maxExposurePageSize !== undefined;
const _maxNominatorRewardedPerValidator = (substrateApi.api.consts.staking.maxNominatorRewardedPerValidator || 0).toString();
const maxNominatorRewardedPerValidator = parseInt(_maxNominatorRewardedPerValidator);
Expand Down Expand Up @@ -232,22 +232,21 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
}

ledger.unlocking.forEach((unlockingChunk) => {
// Calculate the remaining time for current era ending
const isClaimable = unlockingChunk.era - parseInt(currentEra) < 0;
const remainingEra = unlockingChunk.era - parseInt(currentEra);
const expectedBlockTime = _EXPECTED_BLOCK_TIME[chain];
const eraLength = _deriveSessionProgress.eraLength.toNumber();
const eraProgress = _deriveSessionProgress.eraProgress.toNumber();
const remainingSlots = eraLength - eraProgress;
const remainingHours = expectedBlockTime * remainingSlots / 60 / 60;
const activeEra = _activeEra.toPrimitive() as unknown as PalletStakingActiveEraInfo;
const era = parseInt(activeEra.index);
const startTimestampMs = parseInt(activeEra.start);

const remainingEra = unlockingChunk.era - era;
const eraTime = _STAKING_ERA_LENGTH_MAP[chainInfo.slug] || _STAKING_ERA_LENGTH_MAP.default; // in hours
const waitingTime = remainingEra * eraTime + remainingHours;
const remaningTimestampMs = remainingEra * eraTime * 60 * 60 * 1000;
const targetTimestampMs = startTimestampMs + remaningTimestampMs;
const isClaimable = targetTimestampMs - Date.now() <= 0;

unstakingList.push({
chain,
status: isClaimable ? UnstakingStatus.CLAIMABLE : UnstakingStatus.UNLOCKING,
claimable: unlockingChunk.value.toString(),
waitingTime: waitingTime
targetTimestampMs: targetTimestampMs
} as UnstakingInfo);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import KoniState from '@subwallet/extension-base/koni/background/handlers/State'
import { _EXPECTED_BLOCK_TIME, _STAKING_ERA_LENGTH_MAP } from '@subwallet/extension-base/services/chain-service/constants';
import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
import { _getChainSubstrateAddressPrefix } from '@subwallet/extension-base/services/chain-service/utils';
import { BaseYieldPositionInfo, EarningRewardHistoryItem, EarningRewardItem, EarningStatus, HandleYieldStepData, NominationPoolInfo, NominationYieldPoolInfo, OptimalYieldPath, OptimalYieldPathParams, PalletNominationPoolsBondedPoolInner, PalletNominationPoolsPoolMember, PalletStakingExposure, PalletStakingNominations, RequestStakePoolingBonding, StakeCancelWithdrawalParams, SubmitJoinNominationPool, SubmitYieldJoinData, TransactionData, UnstakingStatus, YieldPoolInfo, YieldPoolMethodInfo, YieldPoolType, YieldPositionInfo, YieldStepBaseInfo, YieldStepType, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
import { BaseYieldPositionInfo, EarningRewardHistoryItem, EarningRewardItem, EarningStatus, HandleYieldStepData, NominationPoolInfo, NominationYieldPoolInfo, OptimalYieldPath, OptimalYieldPathParams, PalletNominationPoolsBondedPoolInner, PalletNominationPoolsPoolMember, PalletStakingActiveEraInfo, PalletStakingExposure, PalletStakingNominations, RequestStakePoolingBonding, StakeCancelWithdrawalParams, SubmitJoinNominationPool, SubmitYieldJoinData, TransactionData, UnstakingStatus, YieldPoolInfo, YieldPoolMethodInfo, YieldPoolType, YieldPositionInfo, YieldStepBaseInfo, YieldStepType, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
import { balanceFormatter, formatNumber, reformatAddress } from '@subwallet/extension-base/utils';
import BigN from 'bignumber.js';
import { t } from 'i18next';
Expand Down Expand Up @@ -190,9 +190,10 @@ export default class NominationPoolHandler extends BasePoolHandler {
const poolsPalletId = substrateApi.api.consts.nominationPools.palletId.toString();
const poolStashAccount = parsePoolStashAddress(substrateApi.api, 0, poolMemberInfo.poolId, poolsPalletId);

const [_nominations, _poolMetadata] = await Promise.all([
const [_nominations, _poolMetadata, _activeEra] = await Promise.all([
substrateApi.api.query.staking.nominators(poolStashAccount),
substrateApi.api.query.nominationPools.metadata(poolMemberInfo.poolId)
substrateApi.api.query.nominationPools.metadata(poolMemberInfo.poolId),
substrateApi.api.query.staking.activeEra()
]);

const poolMetadata = _poolMetadata.toPrimitive() as unknown as string;
Expand Down Expand Up @@ -240,23 +241,22 @@ export default class NominationPoolHandler extends BasePoolHandler {
let unstakingBalance = BN_ZERO;

Object.entries(poolMemberInfo.unbondingEras).forEach(([unlockingEra, amount]) => {
// Calculate the remaining time for current era ending
const isClaimable = parseInt(unlockingEra) - parseInt(currentEra) < 0;
const remainingEra = parseInt(unlockingEra) - parseInt(currentEra);
const expectedBlockTime = _EXPECTED_BLOCK_TIME[this.chain];
const eraLength = _deriveSessionProgress.eraLength.toNumber();
const eraProgress = _deriveSessionProgress.eraProgress.toNumber();
const remainingSlots = eraLength - eraProgress;
const remainingHours = expectedBlockTime * remainingSlots / 60 / 60;
const activeEra = _activeEra.toPrimitive() as unknown as PalletStakingActiveEraInfo;
const era = parseInt(activeEra.index);
const startTimestampMs = parseInt(activeEra.start);

const remainingEra = parseInt(unlockingEra) - era;
const eraTime = _STAKING_ERA_LENGTH_MAP[chainInfo.slug] || _STAKING_ERA_LENGTH_MAP.default; // in hours
const waitingTime = remainingEra * eraTime + remainingHours;
const remaningTimestampMs = remainingEra * eraTime * 60 * 60 * 1000;
const targetTimestampMs = startTimestampMs + remaningTimestampMs;
const isClaimable = targetTimestampMs - Date.now() <= 0;

unstakingBalance = unstakingBalance.add(new BN(amount));
unstakings.push({
chain: chainInfo.slug,
status: isClaimable ? UnstakingStatus.CLAIMABLE : UnstakingStatus.UNLOCKING,
claimable: amount.toString(),
waitingTime: waitingTime
targetTimestampMs: targetTimestampMs
} as UnstakingInfo);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export interface UnstakingInfo {
claimable: string;
/** Time remains to wait (in hours) */
waitingTime?: number;
/** Timestamp to withdraw */
targetTimestampMs?: number;
/** Address of validator */
validatorAddress?: string;
}
5 changes: 5 additions & 0 deletions packages/extension-base/src/types/yield/info/pallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ export interface PalletStakingStakingLedger {
claimedRewards: number[]
}

export interface PalletStakingActiveEraInfo {
index: string,
start: string
}

export interface RuntimeDispatchInfo {
weight: {
refTime: number,
Expand Down
Loading
Loading