-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* correct panels * rename * update desc * enable * rename props
- Loading branch information
Dev Kalra
authored
Nov 18, 2023
1 parent
49926c2
commit 4dba065
Showing
9 changed files
with
422 additions
and
423 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,302 @@ | ||
import { PythBalance } from '@pythnetwork/staking' | ||
import { | ||
PythBalance, | ||
StakeAccount, | ||
VestingAccountState, | ||
} from '@pythnetwork/staking' | ||
import { BaseModal } from './BaseModal' | ||
import Tooltip from '@components/Tooltip' | ||
import { useUnvestedLockAllMutation } from 'hooks/useUnvestedLockAllMutation' | ||
import { useUnvestedPreUnlockAllMutation } from 'hooks/useUnvestedPreUnlockAllMutation' | ||
import { useUnvestedUnlockAllMutation } from 'hooks/useUnvestedUnlockAllMutation' | ||
import { useBalance } from 'hooks/useBalance' | ||
import { useNextVestingEvent } from 'hooks/useNextVestingEvent' | ||
import { useStakeConnection } from 'hooks/useStakeConnection' | ||
|
||
type LockedModalProps = { | ||
export type LockedModalProps = { | ||
isLockedModalOpen: boolean | ||
setIsLockedModalOpen: (open: boolean) => void | ||
lockedPythBalance?: PythBalance | ||
lockingPythBalance?: PythBalance | ||
currentVestingAccountState: VestingAccountState | undefined | ||
mainStakeAccount: StakeAccount | undefined | ||
} | ||
export function LockedModal({ | ||
isLockedModalOpen, | ||
setIsLockedModalOpen, | ||
lockedPythBalance, | ||
lockingPythBalance, | ||
currentVestingAccountState, | ||
mainStakeAccount, | ||
}: LockedModalProps) { | ||
const { data: balanceData, isLoading: _isBalanceLoading } = | ||
useBalance(mainStakeAccount) | ||
|
||
const { | ||
unvestedTotalPythBalance, | ||
unvestedLockingPythBalance, | ||
unvestedLockedPythBalance, | ||
unvestedPreUnlockingPythBalance, | ||
unvestedUnlockingPythBalance, | ||
unvestedUnlockedPythBalance, | ||
} = balanceData ?? {} | ||
|
||
const { data: nextVestingEvent } = useNextVestingEvent(mainStakeAccount) | ||
const { nextVestingDate, nextVestingAmount } = nextVestingEvent ?? {} | ||
|
||
return ( | ||
<> | ||
<BaseModal | ||
isModalOpen={isLockedModalOpen} | ||
setIsModalOpen={setIsLockedModalOpen} | ||
title={'Locked tokens'} | ||
> | ||
<p className="mb-8 leading-6 "> | ||
Locked tokens enables you to participate in Pyth Network governance. | ||
Newly-locked tokens become eligible to vote in governance at the | ||
beginning of the next epoch. | ||
</p> | ||
<p className="leading-6 "> | ||
You currently have {lockedPythBalance?.toString()} locked tokens. | ||
</p> | ||
{lockingPythBalance && !lockingPythBalance.isZero() ? ( | ||
<p className="mt-4 leading-6 "> | ||
{lockingPythBalance.toString()} tokens will be locked from the | ||
beginning of the next epoch. | ||
</p> | ||
) : null} | ||
</BaseModal> | ||
</> | ||
<BaseModal | ||
title="Locked tokens" | ||
isModalOpen={isLockedModalOpen} | ||
setIsModalOpen={setIsLockedModalOpen} | ||
> | ||
<p className="mb-4"> | ||
You currently have {unvestedTotalPythBalance?.toString()} locked tokens.{' '} | ||
{nextVestingDate && !unvestedTotalPythBalance?.isZero() | ||
? `${nextVestingAmount?.toString()} tokens | ||
will unlock on ${nextVestingDate?.toLocaleString()}.` | ||
: null} | ||
<br /> | ||
<br /> | ||
<LockedModalCurrentState | ||
currentVestingAccountState={currentVestingAccountState} | ||
unvestedLockedPythBalance={ | ||
unvestedLockedPythBalance ?? PythBalance.zero() | ||
} | ||
unvestedLockingPythBalance={ | ||
unvestedLockingPythBalance ?? PythBalance.zero() | ||
} | ||
unvestedUnlockedPythBalance={ | ||
unvestedUnlockedPythBalance ?? PythBalance.zero() | ||
} | ||
unvestedPreUnlockingPythBalance={ | ||
unvestedPreUnlockingPythBalance ?? PythBalance.zero() | ||
} | ||
unvestedUnlockingPythBalance={ | ||
unvestedUnlockingPythBalance ?? PythBalance.zero() | ||
} | ||
nextVestingAmount={nextVestingAmount ?? PythBalance.zero()} | ||
nextVestingDate={nextVestingDate} | ||
/> | ||
</p> | ||
<div className="flex flex-col items-center space-y-4 text-center md:block md:space-x-10"> | ||
<LockedModalButton | ||
currentVestingAccountState={currentVestingAccountState} | ||
mainStakeAccount={mainStakeAccount} | ||
/> | ||
</div> | ||
</BaseModal> | ||
) | ||
} | ||
|
||
type LockedModalCurrentStateProps = { | ||
currentVestingAccountState: VestingAccountState | undefined | ||
unvestedLockedPythBalance: PythBalance | ||
unvestedLockingPythBalance: PythBalance | ||
unvestedUnlockedPythBalance: PythBalance | ||
unvestedPreUnlockingPythBalance: PythBalance | ||
unvestedUnlockingPythBalance: PythBalance | ||
nextVestingAmount: PythBalance | ||
nextVestingDate: Date | undefined | ||
} | ||
function LockedModalCurrentState({ | ||
currentVestingAccountState, | ||
unvestedLockedPythBalance, | ||
unvestedLockingPythBalance, | ||
unvestedUnlockedPythBalance, | ||
unvestedPreUnlockingPythBalance, | ||
unvestedUnlockingPythBalance, | ||
nextVestingAmount, | ||
nextVestingDate, | ||
}: LockedModalCurrentStateProps) { | ||
switch (currentVestingAccountState) { | ||
case VestingAccountState.UnvestedTokensPartiallyLocked: | ||
return ( | ||
<> | ||
{unvestedLockedPythBalance.add(unvestedLockingPythBalance).toString()}{' '} | ||
locked tokens are staked in governance. <br /> | ||
{unvestedUnlockedPythBalance.toString()} locked tokens are unstaked.{' '} | ||
<br /> | ||
{unvestedPreUnlockingPythBalance | ||
.add(unvestedUnlockingPythBalance) | ||
.toString()}{' '} | ||
locked tokens are in cooldown period. | ||
<br /> | ||
<br /> | ||
Your {nextVestingAmount.toString()} tokens scheduled to unlock on{' '} | ||
{nextVestingDate?.toLocaleString()} will be withdrawable. | ||
<br /> | ||
<br /> | ||
The rest of your locked tokens are participating in governance. | ||
</> | ||
) | ||
case VestingAccountState.UnvestedTokensFullyLockedExceptCooldown: | ||
return ( | ||
<> | ||
{unvestedLockedPythBalance.add(unvestedLockingPythBalance).toString()}{' '} | ||
tokens are staked in governance. <br /> | ||
{unvestedPreUnlockingPythBalance | ||
.add(unvestedUnlockingPythBalance) | ||
.toString()}{' '} | ||
tokens are in cooldown period. | ||
</> | ||
) | ||
case VestingAccountState.UnvestedTokensFullyLocked: | ||
return ( | ||
<> | ||
Your locked tokens are staked in the contract to participate in | ||
governance. On vest, they will become staked tokens, which require a 2 | ||
epoch cooldown to withdraw. | ||
<br /> | ||
<br /> | ||
If you would like to withdraw them immediately on unlock, you may | ||
choose to preliminary unstake them now. This action will cause your{' '} | ||
{nextVestingAmount.toString()} tokens scheduled to unstake on{' '} | ||
{nextVestingDate?.toLocaleString()} to become withdrawable on unlock. | ||
<br /> | ||
<br /> | ||
You may also choose to unstake all of your locked tokens, immediately | ||
reducing your governance power. | ||
</> | ||
) | ||
case VestingAccountState.UnvestedTokensFullyUnlocked: | ||
return ( | ||
<> | ||
Your locked tokens are not participating in governance. On unlock, | ||
they will become withdrawable tokens. | ||
<br /> | ||
<br /> | ||
Participating in governance requires you to stake your locked tokens. | ||
This means that when your tokens unlock, you will have to manually | ||
unstake them by interacting with the UI and wait for a one epoch | ||
cooldown before being able to withdraw them. | ||
</> | ||
) | ||
case VestingAccountState.UnvestedTokensFullyUnlockedExceptCooldown: | ||
return <>All of your locked tokens are currently in cooldown period.</> | ||
} | ||
} | ||
|
||
type LockedModalButtonProps = { | ||
currentVestingAccountState: VestingAccountState | undefined | ||
mainStakeAccount?: StakeAccount | ||
} | ||
function LockedModalButton({ | ||
currentVestingAccountState, | ||
mainStakeAccount, | ||
}: LockedModalButtonProps) { | ||
const { data: stakeConnection } = useStakeConnection() | ||
|
||
const unvestedLockAll = useUnvestedLockAllMutation() | ||
const unvestedPreUnlockAll = useUnvestedPreUnlockAllMutation() | ||
const unvestedUnlockAll = useUnvestedUnlockAllMutation() | ||
|
||
switch (currentVestingAccountState) { | ||
case VestingAccountState.UnvestedTokensFullyLocked: | ||
return ( | ||
<> | ||
<button | ||
type="button" | ||
className="primary-btn px-8 py-3 text-base font-semibold hover:bg-blueGemHover" | ||
onClick={() => | ||
unvestedPreUnlockAll.mutate({ | ||
mainStakeAccount: mainStakeAccount!, | ||
stakeConnection: stakeConnection!, | ||
}) | ||
} | ||
disabled={ | ||
mainStakeAccount === undefined || stakeConnection === undefined | ||
} | ||
> | ||
Preliminary unstake | ||
</button> | ||
<button | ||
type="button" | ||
className="primary-btn px-8 py-3 text-base font-semibold hover:bg-blueGemHover" | ||
onClick={() => | ||
unvestedUnlockAll.mutate({ | ||
mainStakeAccount: mainStakeAccount!, | ||
stakeConnection: stakeConnection!, | ||
}) | ||
} | ||
disabled={ | ||
mainStakeAccount === undefined || stakeConnection === undefined | ||
} | ||
> | ||
Unstake all | ||
</button> | ||
</> | ||
) | ||
case VestingAccountState.FullyVested: | ||
return null | ||
default: | ||
return ( | ||
<> | ||
<button | ||
type="button" | ||
className="primary-btn min-w-[145px] px-8 py-3 text-base font-semibold hover:bg-blueGemHover disabled:bg-valhalla" | ||
onClick={() => | ||
unvestedLockAll.mutate({ | ||
mainStakeAccount: mainStakeAccount!, | ||
stakeConnection: stakeConnection!, | ||
}) | ||
} | ||
disabled={ | ||
currentVestingAccountState == | ||
VestingAccountState.UnvestedTokensFullyLockedExceptCooldown || | ||
currentVestingAccountState == | ||
VestingAccountState.UnvestedTokensFullyUnlockedExceptCooldown || | ||
mainStakeAccount === undefined || | ||
stakeConnection === undefined | ||
} | ||
> | ||
{currentVestingAccountState == | ||
VestingAccountState.UnvestedTokensFullyLockedExceptCooldown || | ||
currentVestingAccountState == | ||
VestingAccountState.UnvestedTokensFullyUnlockedExceptCooldown ? ( | ||
<Tooltip | ||
content="Your tokens are in the process of being unlocked." | ||
className="m-4" | ||
> | ||
Stake all | ||
</Tooltip> | ||
) : ( | ||
'Stake all' | ||
)} | ||
</button> | ||
<button | ||
type="button" | ||
className="primary-btn min-w-[145px] px-8 py-3 text-base font-semibold hover:bg-blueGemHover disabled:bg-valhalla" | ||
onClick={() => | ||
unvestedUnlockAll.mutate({ | ||
mainStakeAccount: mainStakeAccount!, | ||
stakeConnection: stakeConnection!, | ||
}) | ||
} | ||
disabled={ | ||
currentVestingAccountState == | ||
VestingAccountState.UnvestedTokensFullyUnlocked || | ||
currentVestingAccountState == | ||
VestingAccountState.UnvestedTokensFullyUnlockedExceptCooldown || | ||
mainStakeAccount === undefined || | ||
stakeConnection === undefined | ||
} | ||
> | ||
{currentVestingAccountState == | ||
VestingAccountState.UnvestedTokensFullyUnlocked || | ||
currentVestingAccountState == | ||
VestingAccountState.UnvestedTokensFullyUnlockedExceptCooldown ? ( | ||
<Tooltip | ||
content={ | ||
currentVestingAccountState == | ||
VestingAccountState.UnvestedTokensFullyUnlocked | ||
? "You don't have any locked tokens to unlock." | ||
: 'Your tokens are in the process of being unlocked.' | ||
} | ||
className="m-4" | ||
> | ||
Unstake all | ||
</Tooltip> | ||
) : ( | ||
'Unstake all' | ||
)} | ||
</button> | ||
</> | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { PythBalance } from '@pythnetwork/staking' | ||
import { BaseModal } from './BaseModal' | ||
|
||
type StakedModalProps = { | ||
isStakedModalOpen: boolean | ||
setIsStakedModalOpen: (open: boolean) => void | ||
stakedPythBalance?: PythBalance | ||
stakingPythBalance?: PythBalance | ||
} | ||
export function StakedModal({ | ||
isStakedModalOpen, | ||
setIsStakedModalOpen, | ||
stakedPythBalance, | ||
stakingPythBalance, | ||
}: StakedModalProps) { | ||
return ( | ||
<> | ||
<BaseModal | ||
isModalOpen={isStakedModalOpen} | ||
setIsModalOpen={setIsStakedModalOpen} | ||
title={'Staked tokens'} | ||
> | ||
<p className="mb-8 leading-6 "> | ||
Staked tokens enable you to participate in Pyth Network governance. | ||
Newly-staked tokens become eligible to vote in governance at the | ||
beginning of the next epoch. | ||
</p> | ||
<p className="leading-6 "> | ||
You currently have {stakedPythBalance?.toString()} staked tokens. | ||
</p> | ||
{stakingPythBalance && !stakingPythBalance.isZero() ? ( | ||
<p className="mt-4 leading-6 "> | ||
{stakingPythBalance.toString()} tokens will be staked from the | ||
beginning of the next epoch. | ||
</p> | ||
) : null} | ||
</BaseModal> | ||
</> | ||
) | ||
} |
Oops, something went wrong.
4dba065
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
staking-devnet – ./
governance-nu.vercel.app
staking-devnet-git-main-pyth-web.vercel.app
staking-devnet-pyth-web.vercel.app
4dba065
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
staking – ./
staking-rho-nine.vercel.app
staking-pyth-web.vercel.app
staking-git-main-pyth-web.vercel.app
staking.pyth.network