Skip to content

Commit

Permalink
feat: continue
Browse files Browse the repository at this point in the history
  • Loading branch information
danielsimao committed Aug 29, 2023
1 parent 17e4132 commit 6845b47
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 72 deletions.
8 changes: 6 additions & 2 deletions src/hooks/api/escrow/use-get-account-staking-data.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type AccountStakingData = {
amount: MonetaryAmount<CurrencyExt>;
apy: Big;
};
limit: MonetaryAmount<CurrencyExt>;
};

const getUnlockData = (stakeEndBlock: number, currentBlockNumber: number): AccountUnlockStakingData => {
Expand All @@ -48,12 +49,14 @@ const getAccountStakingData = async (accountId: AccountId): Promise<AccountStaki
return null;
}

const limitPromise = window.bridge.api.rpc.escrow.freeStakable(accountId);
const currentBlockNumberPromise = window.bridge.system.getCurrentBlockNumber();
const claimableRewardsPromise = window.bridge.escrow.getRewards(accountId);
const projectedPromise = window.bridge.escrow.getRewardEstimate(accountId);
const votingBalancePromise = window.bridge.escrow.votingBalance(accountId);

const [currentBlockNumber, claimableRewards, projected, votingBalance] = await Promise.all([
const [limit, currentBlockNumber, claimableRewards, projected, votingBalance] = await Promise.all([
limitPromise,
currentBlockNumberPromise,
claimableRewardsPromise,
projectedPromise,
Expand All @@ -68,7 +71,8 @@ const getAccountStakingData = async (accountId: AccountId): Promise<AccountStaki
endBlock: stakedBalance.endBlock,
votingBalance,
claimableRewards,
projected
projected,
limit
};
};

Expand Down
60 changes: 29 additions & 31 deletions src/lib/form/schemas/staking.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// import i18n from 'i18next';
import i18n from 'i18next';

import yup, { MaxAmountValidationParams, MinAmountValidationParams } from '../yup.custom';

Expand All @@ -8,7 +8,7 @@ const STAKING_FEE_TOKEN_FIELD = 'staking-fee-token';

type StakingFormData = {
[STAKING_AMOUNT_FIELD]?: string;
[STAKING_LOCK_TIME_AMOUNT_FIELD]?: number;
[STAKING_LOCK_TIME_AMOUNT_FIELD]?: string;
[STAKING_FEE_TOKEN_FIELD]?: string;
};

Expand All @@ -20,37 +20,35 @@ type StakingValidationParams = {
};
};

// TODO: lock time could be 0 if only adding into staking amount
const stakingSchema = (params: StakingValidationParams): yup.ObjectSchema<any> =>
yup.object().shape({
[STAKING_AMOUNT_FIELD]: yup
.string()
// .when([STAKING_LOCK_TIME_AMOUNT_FIELD], {
// is: !hasStaked,
// then: yup.number().required(i18n.t('forms.please_enter_your_field', { field: 'stake' }))
// })
// .requiredAmount('stake')
.maxAmount(params[STAKING_AMOUNT_FIELD] as MaxAmountValidationParams)
.minAmount(params[STAKING_AMOUNT_FIELD] as MinAmountValidationParams, 'transfer'),
[STAKING_LOCK_TIME_AMOUNT_FIELD]: yup
.number()
// .test('is-required', i18n.t('forms.please_enter_your_field', { field: 'lock time' }), (value) =>
// hasStaked ? true : value !== undefined
// )
// .when([], {
// is: !hasStaked,
// then: yup.number().required(i18n.t('forms.please_enter_your_field', { field: 'lock time' }))
// })
.min(
params[STAKING_LOCK_TIME_AMOUNT_FIELD].min,
`Lock time must be greater than or equal to ${params[STAKING_LOCK_TIME_AMOUNT_FIELD].min}`
)
.max(
params[STAKING_LOCK_TIME_AMOUNT_FIELD].max,
`Lock time must be less than or equal to ${params[STAKING_LOCK_TIME_AMOUNT_FIELD].max}`
),
const stakingSchema = (params: StakingValidationParams, hasStaked: boolean): yup.ObjectSchema<any> => {
let baseAmountSchema = yup
.string()
.maxAmount(params[STAKING_AMOUNT_FIELD] as MaxAmountValidationParams)
.minAmount(params[STAKING_AMOUNT_FIELD] as MinAmountValidationParams, 'transfer');

let baseLockTimeSchema = yup
.string()
.min(
params[STAKING_LOCK_TIME_AMOUNT_FIELD].min,
`Lock time must be greater than or equal to ${params[STAKING_LOCK_TIME_AMOUNT_FIELD].min}`
)
.max(
params[STAKING_LOCK_TIME_AMOUNT_FIELD].max,
`Lock time must be less than or equal to ${params[STAKING_LOCK_TIME_AMOUNT_FIELD].max}`
);

if (!hasStaked) {
baseAmountSchema = baseAmountSchema.requiredAmount('stake');

baseLockTimeSchema = baseLockTimeSchema.required(i18n.t('forms.please_enter_your_field', { field: 'lock time' }));
}

return yup.object().shape({
[STAKING_AMOUNT_FIELD]: baseAmountSchema,
[STAKING_LOCK_TIME_AMOUNT_FIELD]: baseLockTimeSchema,
[STAKING_FEE_TOKEN_FIELD]: yup.string().required()
});
};

export { STAKING_AMOUNT_FIELD, STAKING_FEE_TOKEN_FIELD, STAKING_LOCK_TIME_AMOUNT_FIELD, stakingSchema };
export type { StakingFormData, StakingValidationParams };
2 changes: 0 additions & 2 deletions src/pages/Staking copy/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,6 @@ const Staking = (): JSX.Element => {
const extensionTime =
(stakedAmountAndEndBlock?.endBlock || currentBlockNumber) + convertWeeksToBlockNumbers(lockTimeValue);

console.log(stakedAmountAndEndBlock?.endBlock, currentBlockNumber, convertWeeksToBlockNumbers(lockTimeValue));

setBlockLockTimeExtension(extensionTime);
}, [currentBlockNumber, lockTime, stakedAmountAndEndBlock]);

Expand Down
48 changes: 35 additions & 13 deletions src/pages/Staking/components/StakingForm/StakingForm.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { newMonetaryAmount } from '@interlay/interbtc-api';
import { mergeProps } from '@react-aria/utils';
import { isPast } from 'date-fns';
import { ChangeEvent, useCallback, useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';

import { convertMonetaryAmountToValueInUSD, newSafeMonetaryAmount } from '@/common/utils/utils';
import { Card, CardProps, Divider, Flex, H1, TokenInput } from '@/component-library';
import { Alert, Card, CardProps, Divider, Flex, H1, TokenInput } from '@/component-library';
import {
AuthCTA,
TransactionDetails,
Expand All @@ -29,6 +30,7 @@ import {
stakingSchema,
useForm
} from '@/lib/form';
import { pickSmallerAmount } from '@/utils/helpers/currencies';
import { getTokenInputProps } from '@/utils/helpers/input';
import { getTokenPrice } from '@/utils/helpers/prices';
import { convertBlockNumbersToWeeks, convertWeeksToBlockNumbers } from '@/utils/helpers/staking';
Expand Down Expand Up @@ -60,8 +62,11 @@ const StakingForm = ({ accountData, networkData, onStaking, ...props }: StakingF
}
});

const inputBalance = getAvailableBalance(GOVERNANCE_TOKEN.ticker);
const isWithdrawReady = useMemo(() => !!accountData && isPast(accountData?.unlock.date), [accountData]);

const governanceBalance = getAvailableBalance(GOVERNANCE_TOKEN.ticker);
const inputBalance =
accountData?.limit && governanceBalance && pickSmallerAmount(governanceBalance, accountData.limit);
const minAmount = newMonetaryAmount(1, GOVERNANCE_TOKEN);

const inputSchemaParams = {
Expand All @@ -72,7 +77,7 @@ const StakingForm = ({ accountData, networkData, onStaking, ...props }: StakingF
const getTransactionArgs = useCallback(
async (values: StakingFormData) => {
const amount = newMonetaryAmount(values[STAKING_AMOUNT_FIELD] || 0, GOVERNANCE_TOKEN, true);
const lockTime = values[STAKING_LOCK_TIME_AMOUNT_FIELD];
const lockTime = Number(values[STAKING_LOCK_TIME_AMOUNT_FIELD] || 0);

const hasAmount = !amount.isZero();
const hasLockTime = lockTime && lockTime > 0;
Expand All @@ -82,7 +87,7 @@ const StakingForm = ({ accountData, networkData, onStaking, ...props }: StakingF

const unlockHeight = accountData.endBlock + newLockBlockNumber;

if (hasAmount && lockTime && lockTime > 0) {
if (hasAmount && hasLockTime) {
return { transactionType: Transaction.ESCROW_INCREASE_LOOKED_TIME_AND_AMOUNT as const, amount, unlockHeight };
} else if (hasAmount && !hasLockTime) {
// transactionType = Transaction.ESCROW_INCREASE_LOCKED_AMOUNT;
Expand Down Expand Up @@ -131,15 +136,20 @@ const StakingForm = ({ accountData, networkData, onStaking, ...props }: StakingF
const form = useForm<StakingFormData>({
initialValues: {
[STAKING_AMOUNT_FIELD]: '',
[STAKING_LOCK_TIME_AMOUNT_FIELD]: 1,
[STAKING_LOCK_TIME_AMOUNT_FIELD]: '',
[STAKING_FEE_TOKEN_FIELD]: transaction.fee.defaultCurrency.ticker
},
validationSchema: stakingSchema({
[STAKING_AMOUNT_FIELD]: inputSchemaParams,
[STAKING_LOCK_TIME_AMOUNT_FIELD]: { min: STAKE_LOCK_TIME.MIN, max: maxLockTime }
}),
validationSchema: stakingSchema(
{
[STAKING_AMOUNT_FIELD]: inputSchemaParams,
[STAKING_LOCK_TIME_AMOUNT_FIELD]: { min: accountData ? 0 : STAKE_LOCK_TIME.MIN, max: maxLockTime }
},
!!accountData
),
onSubmit: handleSubmit,
onComplete: async (values) => {
if (isWithdrawReady) return;

const data = await getTransactionArgs(values);

if (!data) return;
Expand All @@ -166,22 +176,30 @@ const StakingForm = ({ accountData, networkData, onStaking, ...props }: StakingF
const handleListSelectionChange = (value: number) => {
form.setFieldValue(STAKING_LOCK_TIME_AMOUNT_FIELD, value, true);

if (isWithdrawReady) return;

const monetaryAmount = newSafeMonetaryAmount(form.values[STAKING_AMOUNT_FIELD] || 0, GOVERNANCE_TOKEN, true);

mutateEstimation({ amount: monetaryAmount, lockTime: value });
};

const handleChangeAmount = (e: ChangeEvent<HTMLInputElement>) => {
if (isWithdrawReady) return;

const amount = e.target.value;

if (!amount) return;

const lockTime = form.values[STAKING_LOCK_TIME_AMOUNT_FIELD];

const monetaryAmount = newSafeMonetaryAmount(amount, GOVERNANCE_TOKEN, true);

mutateEstimation({ amount: monetaryAmount, lockTime: form.values[STAKING_LOCK_TIME_AMOUNT_FIELD] });
mutateEstimation({ amount: monetaryAmount, lockTime: lockTime ? Number(lockTime) : undefined });
};

const handleChangeLockTime = (e: ChangeEvent<HTMLInputElement>) => {
if (isWithdrawReady) return;

const lockTime = e.target.value;

if (!lockTime) return;
Expand All @@ -196,11 +214,10 @@ const StakingForm = ({ accountData, networkData, onStaking, ...props }: StakingF
? convertMonetaryAmountToValueInUSD(monetaryAmount, getTokenPrice(prices, monetaryAmount.currency.ticker)?.usd) || 0
: 0;

console.log(form.errors);
const isBtnDisabled = isWithdrawReady && isTransactionFormDisabled(form, transaction.fee);

const isBtnDisabled = isTransactionFormDisabled(form, transaction.fee);
const shouldDisplayWithdrawAlert = isWithdrawReady && form.dirty;

// TODO: lock form when user needs to withdraw staked INTR
return (
<Card {...props} gap='spacing2'>
<H1 size='base' color='secondary' weight='bold' align='center'>
Expand Down Expand Up @@ -239,6 +256,11 @@ const StakingForm = ({ accountData, networkData, onStaking, ...props }: StakingF
})}
onListSelectionChange={handleListSelectionChange}
/>
{shouldDisplayWithdrawAlert && (
<Alert status='warning'>
Your staked {GOVERNANCE_TOKEN.ticker} needs to be withdrawn before any further actions
</Alert>
)}
<Flex direction='column' gap='spacing2'>
<StakingTransactionDetails
accountData={accountData}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type Props = {
accountData: AccountStakingData | null;
estimation?: AccountStakingEstimationData;
amount: MonetaryAmount<CurrencyExt>;
lockTime?: number;
lockTime?: string;
};

type InheritAttrs = Omit<TransactionDetailsProps, keyof Props>;
Expand All @@ -37,7 +37,7 @@ const StakingTransactionDetails = ({
const unlockDateTerm = accountData ? 'New unlock date' : 'Unlock date';

const newDate = add(accountData?.unlock.date || new Date(), {
weeks: lockTime
weeks: lockTime ? Number(lockTime) : undefined
});

const unlockDateLabel = format(newDate, YEAR_MONTH_DAY_PATTERN);
Expand All @@ -50,28 +50,6 @@ const StakingTransactionDetails = ({

const votingBalanceGained = accountData ? newTotalStaked.sub(accountData?.votingBalance) : newTotalStaked;

// const extendingLockTime = parseInt(lockTime); // Weeks

// let newLockTime: number;
// let newLockingAmount: GovernanceTokenMonetaryAmount;
// if (remainingBlockNumbersToUnstake === null) {
// // If the user has not staked
// newLockTime = extendingLockTime;
// newLockingAmount = monetaryLockingAmount;
// } else {
// // If the user has staked
// const currentLockTime = convertBlockNumbersToWeeks(remainingBlockNumbersToUnstake); // Weeks

// // New lock-time that is applied to the entire staked governance token
// newLockTime = currentLockTime + extendingLockTime; // Weeks

// // New total staked governance token
// newLockingAmount = monetaryLockingAmount.add(stakedAmount);
// }

// // Multiplying the new total staked governance token with the staking time divided by the maximum lock time
// return newLockingAmount.mul(newLockTime).div(STAKE_LOCK_TIME.MAX);

return (
<TransactionDetails {...props}>
<TransactionDetailsGroup>
Expand Down

0 comments on commit 6845b47

Please sign in to comment.