Skip to content

Commit

Permalink
Merge pull request #29 from Access-Labs-Inc/fix/lock-and-claim
Browse files Browse the repository at this point in the history
Add timer after stake 5s and allow claim always with redirect to HUB
  • Loading branch information
martincik authored Sep 11, 2024
2 parents b96398d + af3ed20 commit bc151d7
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 79 deletions.
29 changes: 19 additions & 10 deletions src/components/ProgressModal.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { Fragment, h } from 'preact';

import { RouteLink } from '../layout/Router';

import { useContext } from 'preact/hooks';
import { useContext, useEffect, useState } from 'preact/hooks';
import { ConfigContext } from '../AppContext';
import { clsxp } from '../libs/utils';
import Loading from './Loading';
Expand All @@ -15,35 +13,46 @@ const ProgressModal = ({
doneStepName: string;
}) => {
const { classPrefix } = useContext(ConfigContext);
const [countdown, setCountdown] = useState(5);

useEffect(() => {
if (working === doneStepName && countdown > 0) {
const timer = setTimeout(() => setCountdown(countdown - 1), 1000);
return () => clearTimeout(timer);
}
}, [working, doneStepName, countdown]);

const isButtonDisabled = working !== doneStepName || countdown > 0;

return (
<Fragment>
<div className={clsxp(classPrefix, 'process_modal_title')}>
Sign a transaction
</div>
<div className={clsxp(classPrefix, 'process_modal_subtitle')}>
{ working === doneStepName ?
'Transaction sent successfully.' :
'We need you to sign a transaction to lock your funds.' }
{working === doneStepName
? 'Transaction sent successfully.'
: 'We need you to sign a transaction to lock your funds.'}
</div>
<nav
className={clsxp(classPrefix, 'process_modal_steps')}
aria-label='Progress'
>
<div className={clsxp(classPrefix, 'process_modal_steps_load')}>
{ working !== doneStepName && <Loading />}
{working !== doneStepName && <Loading />}
</div>
<RouteLink
disabled={working !== doneStepName}
disabled={isButtonDisabled}
href='/'
className={clsxp(
classPrefix,
'process_modal_button',
working !== doneStepName
isButtonDisabled
? 'process_modal_button_disabled'
: 'process_modal_button_selected'
)}
>
Close
{isButtonDisabled && countdown > 0 ? `Close (${countdown})` : 'Close'}
</RouteLink>
</nav>
</Fragment>
Expand Down
121 changes: 78 additions & 43 deletions src/routes/Actions.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
import { h } from 'preact';
import { useCallback, useContext, useEffect, useMemo, useState, } from 'preact/hooks';
import {
useCallback,
useContext,
useEffect,
useMemo,
useState,
} from 'preact/hooks';
import { PublicKey } from '@solana/web3.js';
import BN from 'bn.js';

import { calculateRewardForStaker, getBondAccounts, getStakeAccounts, getUserACSBalance, } from '../libs/program';
import {
calculateRewardForStaker,
getBondAccounts,
getStakeAccounts,
getUserACSBalance,
} from '../libs/program';
import { ConfigContext } from '../AppContext';
import { BondAccount, BondV2Account, getBondV2Accounts, StakeAccount, StakePool } from '@accessprotocol/js';
import {
BondAccount,
BondV2Account,
getBondV2Accounts,
StakeAccount,
StakePool,
} from '@accessprotocol/js';
import { clsxp, formatPenyACSCurrency } from '../libs/utils';
import { RouteLink } from '../layout/Router';
import { Header } from '../components/Header';
Expand Down Expand Up @@ -83,8 +100,13 @@ export const Actions = () => {
env.PROGRAM_ID
);
setBondAccounts(
bAccounts.map((bAccount: any) => BondAccount.deserialize(bAccount.account.data))
.filter((bAccount: BondAccount) => bAccount.stakePool.toBase58() === poolId)
bAccounts
.map((bAccount: any) =>
BondAccount.deserialize(bAccount.account.data)
)
.filter(
(bAccount: BondAccount) => bAccount.stakePool.toBase58() === poolId
)
);
})();
}, [publicKey, connection, poolId]);
Expand All @@ -101,8 +123,13 @@ export const Actions = () => {
);

setBondV2Accounts(
bV2Accounts.map((bAccount: any) => BondV2Account.deserialize(bAccount.account.data))
.filter((bAccount: BondV2Account) => bAccount.pool.toBase58() === poolId)
bV2Accounts
.map((bAccount: any) =>
BondV2Account.deserialize(bAccount.account.data)
)
.filter(
(bAccount: BondV2Account) => bAccount.pool.toBase58() === poolId
)
);
})();
}, [publicKey, connection, poolId]);
Expand All @@ -123,29 +150,41 @@ export const Actions = () => {
return null;
}

return bondAccounts.reduce((acc, ba) =>
acc + calculateRewardForStaker(
stakePool.currentDayIdx - ba.lastClaimedOffset.toNumber(),
stakePool,
ba.totalStaked as BN
), 0);
return bondAccounts.reduce(
(acc, ba) =>
acc +
calculateRewardForStaker(
stakePool.currentDayIdx - ba.lastClaimedOffset.toNumber(),
stakePool,
ba.totalStaked as BN
),
0
);
}, [bondAccounts, stakePool]);

const claimableBondV2Amount = useMemo(() => {
if (bondV2Accounts.length === 0 || !stakePool) {
return null;
}

return bondV2Accounts.reduce((acc, ba) =>
acc + calculateRewardForStaker(
stakePool.currentDayIdx - ba.lastClaimedOffset.toNumber(),
stakePool,
ba.amount as BN
), 0);
return bondV2Accounts.reduce(
(acc, ba) =>
acc +
calculateRewardForStaker(
stakePool.currentDayIdx - ba.lastClaimedOffset.toNumber(),
stakePool,
ba.amount as BN
),
0
);
}, [bondV2Accounts, stakePool]);

const claimableAmount = useMemo(() => {
return (claimableBondAmount ?? 0) + (claimableStakeAmount ?? 0) + (claimableBondV2Amount ?? 0);
return (
(claimableBondAmount ?? 0) +
(claimableStakeAmount ?? 0) +
(claimableBondV2Amount ?? 0)
);
}, [claimableBondAmount, claimableStakeAmount, claimableBondV2Amount]);

const disconnectHandler = useCallback(async () => {
Expand Down Expand Up @@ -218,14 +257,20 @@ export const Actions = () => {
classPrefix,
'actions_staked_amount',
(stakedAccount === undefined || bondAccounts === undefined) &&
'actions_blink'
'actions_blink'
)}
>
<div>
{formatPenyACSCurrency(
(stakedAccount?.stakeAmount.toNumber() ?? 0) +
(bondAccounts?.reduce((acc, ba) => acc + ba.totalStaked.toNumber(), 0) ?? 0) +
(bondV2Accounts?.reduce((acc, ba) => acc + ba.amount.toNumber(), 0) ?? 0)
(bondAccounts?.reduce(
(acc, ba) => acc + ba.totalStaked.toNumber(),
0
) ?? 0) +
(bondV2Accounts?.reduce(
(acc, ba) => acc + ba.amount.toNumber(),
0
) ?? 0)
)}{' '}
ACS locked
</div>
Expand All @@ -244,7 +289,7 @@ export const Actions = () => {
classPrefix,
'actions_balance',
(stakedAccount === undefined || bondAccounts === undefined) &&
'actions_blink'
'actions_blink'
)}
>
{formatPenyACSCurrency(claimableAmount ?? 0)} ACS rewards
Expand All @@ -258,7 +303,9 @@ export const Actions = () => {
>
Lock
</RouteLink>
{(stakedAccount && stakedAccount.stakeAmount.toNumber() > 0) || hasUnlockableBonds || hasUnlockableBondsV2 ? (
{(stakedAccount && stakedAccount.stakeAmount.toNumber() > 0) ||
hasUnlockableBonds ||
hasUnlockableBondsV2 ? (
<RouteLink
className={clsxp(classPrefix, 'actions_button')}
href='/unstake'
Expand All @@ -276,24 +323,12 @@ export const Actions = () => {
Unlock ACS
</span>
)}
{claimableAmount && claimableAmount > 0 ? (
<RouteLink
className={clsxp(classPrefix, 'actions_button')}
href='/claim'
>
Claim
</RouteLink>
) : (
<span
className={clsxp(
classPrefix,
'actions_button',
'actions_button_disabled'
)}
>
Claim rewards
</span>
)}
<RouteLink
className={clsxp(classPrefix, 'actions_button')}
href='/claim'
>
Claim
</RouteLink>
</div>
</div>
);
Expand Down
78 changes: 52 additions & 26 deletions src/routes/Claim.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,18 @@ import { useContext, useEffect, useMemo, useState } from 'preact/hooks';
import { ConfigContext } from '../AppContext';
import env from '../libs/env';
import { clsxp, formatPenyACSCurrency } from '../libs/utils';
import { BondAccount, BondV2Account, getBondV2Accounts, StakeAccount, StakePool } from '@accessprotocol/js';
import { calculateRewardForStaker, getBondAccounts, getStakeAccounts } from '../libs/program';
import {
BondAccount,
BondV2Account,
getBondV2Accounts,
StakeAccount,
StakePool,
} from '@accessprotocol/js';
import {
calculateRewardForStaker,
getBondAccounts,
getStakeAccounts,
} from '../libs/program';
import { PublicKey } from '@solana/web3.js';
import BN from 'bn.js';
import { useWallet } from '../components/wallet-adapter/useWallet';
Expand Down Expand Up @@ -72,10 +82,12 @@ export const Claim = () => {
env.PROGRAM_ID
);
if (bAccounts != null && bAccounts.length > 0) {
const bas = bAccounts.filter((st) => {
const ba = BondAccount.deserialize(st.account.data);
return ba.stakePool.toBase58() === poolId;
}).map((bAccount) => BondAccount.deserialize(bAccount.account.data));
const bas = bAccounts
.filter((st) => {
const ba = BondAccount.deserialize(st.account.data);
return ba.stakePool.toBase58() === poolId;
})
.map((bAccount) => BondAccount.deserialize(bAccount.account.data));
setBondAccounts(bas);
} else {
setBondAccounts([]);
Expand All @@ -95,8 +107,13 @@ export const Claim = () => {
);

setBondV2Accounts(
bV2Accounts.map((bAccount: any) => BondV2Account.deserialize(bAccount.account.data))
.filter((bAccount: BondV2Account) => bAccount.pool.toBase58() === poolId)
bV2Accounts
.map((bAccount: any) =>
BondV2Account.deserialize(bAccount.account.data)
)
.filter(
(bAccount: BondV2Account) => bAccount.pool.toBase58() === poolId
)
);
})();
}, [publicKey, connection, poolId]);
Expand All @@ -117,38 +134,47 @@ export const Claim = () => {
return null;
}

return bondAccounts.reduce((acc, ba) =>
acc + calculateRewardForStaker(
stakePool.currentDayIdx - ba.lastClaimedOffset.toNumber(),
stakePool,
ba.totalStaked as BN
), 0);
return bondAccounts.reduce(
(acc, ba) =>
acc +
calculateRewardForStaker(
stakePool.currentDayIdx - ba.lastClaimedOffset.toNumber(),
stakePool,
ba.totalStaked as BN
),
0
);
}, [bondAccounts, stakePool]);

const claimableBondV2Amount = useMemo(() => {
if (bondV2Accounts.length === 0 || !stakePool) {
return null;
}

return bondV2Accounts.reduce((acc, ba) =>
acc + calculateRewardForStaker(
stakePool.currentDayIdx - ba.lastClaimedOffset.toNumber(),
stakePool,
ba.amount as BN
), 0);
return bondV2Accounts.reduce(
(acc, ba) =>
acc +
calculateRewardForStaker(
stakePool.currentDayIdx - ba.lastClaimedOffset.toNumber(),
stakePool,
ba.amount as BN
),
0
);
}, [bondV2Accounts, stakePool]);

const claimableAmount = useMemo(() => {
return (claimableBondAmount ?? 0) + (claimableStakeAmount ?? 0) + (claimableBondV2Amount ?? 0);
return (
(claimableBondAmount ?? 0) +
(claimableStakeAmount ?? 0) +
(claimableBondV2Amount ?? 0)
);
}, [claimableBondAmount, claimableStakeAmount, claimableBondV2Amount]);

return (
<div className={clsxp(classPrefix, 'claim_root')}>
<Header>
<RouteLink
href='/'
className={clsxp(classPrefix, 'claim_cancel_link')}
>
<RouteLink href='/' className={clsxp(classPrefix, 'claim_cancel_link')}>
Cancel
</RouteLink>
</Header>
Expand All @@ -166,7 +192,7 @@ export const Claim = () => {
<div>
<a
className={clsxp(classPrefix, 'claim_button')}
href={`${env.REWARDS_BASE_URL}/${poolId}`}
href={`${env.REWARDS_BASE_URL}`}
target='_blank'
rel='noopener'
>
Expand Down

0 comments on commit bc151d7

Please sign in to comment.