Skip to content

Commit

Permalink
stake-ui: Upgrade to anchor 0.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
armaniferrante committed Feb 14, 2021
1 parent 7203ca7 commit d443c6a
Show file tree
Hide file tree
Showing 12 changed files with 415 additions and 122 deletions.
2 changes: 1 addition & 1 deletion packages/stake-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"dependencies": {
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@project-serum/anchor": "^0.0.0-alpha.7",
"@project-serum/anchor": "^0.2.1",
"@project-serum/common": "^0.0.1-beta.3",
"@project-serum/sol-wallet-adapter": "^0.1.4",
"@testing-library/jest-dom": "^5.11.4",
Expand Down
2 changes: 1 addition & 1 deletion packages/stake-ui/src/components/common/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export default function Header(props: HeaderProps) {
<div style={{ display: 'flex' }}>
<SerumLogoButton />
<BarButton label="Stake" hrefClient="/stake" />
{/*<BarButton label="Lockup" hrefClient="/lockup" />*/}
<BarButton label="Lockup" hrefClient="/lockup" />
<BarButton label="Trade" href="https://dex.projectserum.com" />
<BarButton label="Swap" href="https://swap.projectserum.com" />
{network.srmFaucet && (
Expand Down
14 changes: 8 additions & 6 deletions packages/stake-ui/src/components/common/MyNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -385,11 +385,12 @@ function DepositDialog(props: DepositDialogProps) {
);
const tx = await (async () => {
if (isLocked) {
const relayData = registryClient.coder.instruction.encode({
depositLocked: {
const relayData = registryClient.coder.instruction.encode(
'deposit_locked',
{
amount,
},
});
);
const vesting = accounts[from.toString()];
const _memberSigner = (
await memberSigner(
Expand Down Expand Up @@ -536,11 +537,12 @@ function WithdrawDialog(props: WithdrawDialogProps) {
member!,
);
if (isLocked) {
const relayData = registryClient.coder.instruction.encode({
withdrawLocked: {
const relayData = registryClient.coder.instruction.encode(
'withdraw_locked',
{
amount,
},
});
);
const vesting = accounts[from.toString()];
const _memberSigner = (
await memberSigner(registryClient.programId, registrar, member!)
Expand Down
40 changes: 38 additions & 2 deletions packages/stake-ui/src/components/lockups/NewVesting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ function NewVestingDialog(props: NewVestingDialogProps) {
};
});

const defaultStartDate = new Date().toString();
const defaultStartTs = new Date(defaultStartDate).getTime() / 1000;
const defaultEndDate = '2027-01-01T12:00';
const defaultEndTs = new Date(defaultEndDate).getTime() / 1000;

Expand All @@ -75,6 +77,7 @@ function NewVestingDialog(props: NewVestingDialogProps) {
const displayBeneficiaryError = !isValidBeneficiary && beneficiary !== '';

const [fromAccount, setFromAccount] = useState<null | PublicKey>(null);
const [startTimestamp, setStartTimestamp] = useState(defaultStartTs);
const [timestamp, setTimestamp] = useState(defaultEndTs);
const [periodCount, setPeriodCount] = useState(7);
const [displayAmount, setDisplayAmount] = useState<null | number>(null);
Expand Down Expand Up @@ -134,10 +137,12 @@ function NewVestingDialog(props: NewVestingDialogProps) {

let tx = await lockupClient.rpc.createVesting(
beneficiaryPublicKey,
new BN(timestamp),
new BN(periodCount),
amount,
_vestingSigner.nonce,
new BN(startTimestamp),
new BN(timestamp),
new BN(periodCount),
null,
{
accounts: {
vesting: vesting.publicKey,
Expand Down Expand Up @@ -292,6 +297,37 @@ function NewVestingDialog(props: NewVestingDialogProps) {
Amount to deposit into the vesting account
</FormHelperText>
</div>
<div
style={{
marginTop: '24px',
display: 'flex',
}}
>
<div style={{ flex: 1, marginRight: '10px' }}>
<TextField
fullWidth
label="Start date"
type="datetime-local"
defaultValue={defaultStartDate}
InputLabelProps={{
shrink: true,
}}
onChange={e => {
const d = new Date(e.target.value);
setStartTimestamp(d.getTime() / 1000);
}}
/>
<FormHelperText>Date when vesting begins</FormHelperText>
</div>
<div>
<TextField
disabled
fullWidth
label="Unix Timestamp"
value={startTimestamp}
/>
</div>
</div>
<div
style={{
marginTop: '24px',
Expand Down
122 changes: 93 additions & 29 deletions packages/stake-ui/src/components/lockups/VestingAccountCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,18 @@ type VestingAccountCardProps = {

export default function VestingAccountCard(props: VestingAccountCardProps) {
const { vesting, network } = props;
const { lockupClient } = useWallet();
const { lockupClient, registryClient } = useWallet();
const { enqueueSnackbar } = useSnackbar();
const dispatch = useDispatch();
const { accounts } = useSelector((state: StoreState) => {
const { accounts, member } = useSelector((state: StoreState) => {
return {
network: state.common.network,
accounts: state.accounts,
member: state.registry.member
? {
publicKey: state.registry.member,
account: state.accounts[state.registry.member.toString()],
}
: undefined,
};
});

Expand Down Expand Up @@ -139,6 +144,34 @@ export default function VestingAccountCard(props: VestingAccountCardProps) {
'Withdrawing locked tokens',
'Tokens unlocked',
async () => {
const remainingAccounts = (() => {
if (vesting.account.realizor) {
if (!member) {
// Should never be thrown.
throw new Error('Member account not found');
}
return [
{
pubkey: registryClient.programId,
isSigner: false,
isWritable: false,
},
{ pubkey: member.publicKey, isSigner: false, isWritable: false },
{
pubkey: member.account.balances.spt,
isSigner: false,
isWritable: false,
},
{
pubkey: member.account.balancesLocked.spt,
isSigner: false,
isWritable: false,
},
];
} else {
return undefined;
}
})();
const tx = await lockupClient.rpc.withdraw(availableForWithdrawal!, {
accounts: {
vesting: vesting.publicKey,
Expand All @@ -151,6 +184,7 @@ export default function VestingAccountCard(props: VestingAccountCardProps) {
tokenProgram: TokenInstructions.TOKEN_PROGRAM_ID,
clock: SYSVAR_CLOCK_PUBKEY,
},
remainingAccounts,
});
const newVesting = await lockupClient.account.vesting(
vesting.publicKey,
Expand All @@ -168,10 +202,9 @@ export default function VestingAccountCard(props: VestingAccountCardProps) {
},
);
};

const rows = [
{
field: 'Available for unlock',
field: 'Projected unlock',
value:
availableForWithdrawal === null
? null
Expand Down Expand Up @@ -199,7 +232,12 @@ export default function VestingAccountCard(props: VestingAccountCardProps) {
value: displayFn(vesting.account.whitelistOwned),
},
{ field: 'Period count', value: vesting.account.periodCount.toString() },
{ field: 'Vault', value: vesting.account.vault.toString() },
{
field: 'Created at timestamp',
value: `${new Date(
vesting.account.createdTs.toNumber() * 1000,
).toLocaleString()} (${vesting.account.createdTs.toString()})`,
},
{
field: 'Start timestamp',
value: `${new Date(
Expand All @@ -212,6 +250,19 @@ export default function VestingAccountCard(props: VestingAccountCardProps) {
vesting.account.endTs.toNumber() * 1000,
).toLocaleString()} (${vesting.account.endTs.toString()})`,
},
{ field: 'Vault', value: vesting.account.vault.toString() },
{
field: 'Realizor program',
value: vesting.account.realizor
? vesting.account.realizor.program.toString()
: 'None',
},
{
field: 'Realizor metadata',
value: vesting.account.realizor
? vesting.account.realizor.metadata.toString()
: 'None',
},
];

return (
Expand Down Expand Up @@ -247,7 +298,7 @@ export default function VestingAccountCard(props: VestingAccountCardProps) {
/>
<div
style={{
maxWidth: '400px',
maxWidth: '155px',
marginTop: '6px',
color: 'rgba(0, 0, 0, 0.54)',
display: 'flex',
Expand All @@ -264,28 +315,33 @@ export default function VestingAccountCard(props: VestingAccountCardProps) {
</div>
</div>
</ListItem>
<ChartistGraph
data={{
labels: vestingDates,
series: [cumulativeVesting],
}}
options={
{
axisY: {
type: FixedScaleAxis,
low: 0,
high: cumulativeVesting[cumulativeVesting.length - 1],
ticks: cumulativeVesting,
},
axisX: {
ticks: vestingDates,
},
lineSmooth: Interpolation.step(),
height: 400,
} as IChartOptions
}
type={'Line'}
/>
<Typography></Typography>
{vestingDates.length <= 15 ? (
<ChartistGraph
data={{
labels: vestingDates,
series: [cumulativeVesting],
}}
options={
{
axisY: {
type: FixedScaleAxis,
low: 0,
high: cumulativeVesting[cumulativeVesting.length - 1],
ticks: cumulativeVesting,
},
lineSmooth: Interpolation.step(),
height: 400,
} as IChartOptions
}
type={'Line'}
/>
) : (
<div style={{ textAlign: 'center', fontWeight: 'bold' }}>
{/* TOOD: graphs for vesting accounts with a lot of periods. */}A
graph isn't available for this account.
</div>
)}
<div>
{isCustomMint && (
<div
Expand Down Expand Up @@ -326,11 +382,19 @@ export default function VestingAccountCard(props: VestingAccountCardProps) {
/>
<div style={{ marginLeft: '20px', width: '191px' }}>
<Button
style={{ fontSize: '12px' }}
color="primary"
disabled={!withdrawEnabled}
variant="contained"
onClick={() =>
withdraw().catch(err => {
let msg = err.toString();
if (
msg &&
msg.split('custom program error: 0x78').length === 2
) {
msg = 'Unrealized rewards. Please unstake';
}
enqueueSnackbar(
`Error withdrawing from vesting account: ${err.toString()}`,
{
Expand Down
16 changes: 14 additions & 2 deletions packages/stake-ui/src/components/lockups/Vestings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,34 @@ export default function Vestings() {
fontWeight: 'bold',
}}
>
My Vesting Accounts
Projected Unlocks
</Typography>
</div>
<div>
<NewVestingButton />
</div>
</div>
)}
<List disablePadding>
<Typography color="textSecondary">
In addition to a vesting schedule, locked token accounts are subject
to an application dependent
<b> realization condition</b>, determining if and when locked tokens
are given to a user. For example, in the case of locked staking
rewards, locked tokens become realized in the event of unstaking. If
one never unstakes, one never receives locked token rewards.
</Typography>
<List
disablePadding
style={{ width: '656px', marginLeft: 'auto', marginRight: 'auto' }}
>
{vestingAccounts.map(v => (
<VestingAccountCard network={network} vesting={v} />
))}
{vestingAccounts.length === 0 && (
<Card
style={{
marginTop: '24px',
width: '656px',
}}
>
<CardContent>
Expand Down
Loading

0 comments on commit d443c6a

Please sign in to comment.