Skip to content

Commit

Permalink
Add approval page & fix split request accept thing (#267)
Browse files Browse the repository at this point in the history
* add approval page

* cleanup

* fix
  • Loading branch information
jayantk authored Nov 14, 2023
1 parent 2ba5304 commit b59be91
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 4 deletions.
103 changes: 103 additions & 0 deletions frontend/pages/approve.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import type { NextPage } from 'next'
import Layout from '../components/Layout'
import SEO from '../components/SEO'
import {
useAnchorWallet,
useConnection,
useWallet,
} from '@solana/wallet-adapter-react'
import {
PythBalance,
StakeAccount,
StakeConnection,
STAKING_ADDRESS,
} from '@pythnetwork/staking'
import { useEffect, useState } from 'react'
import { utils, Wallet } from '@project-serum/anchor'
import toast from 'react-hot-toast'
import { capitalizeFirstLetter } from '../utils/capitalizeFirstLetter'
import { PublicKey } from '@solana/web3.js'
import { useRouter } from 'next/router'

const ApproveSplit: NextPage = () => {
const { connection } = useConnection()
const anchorWallet = useAnchorWallet()
const { publicKey, connected } = useWallet()

const [stakeConnection, setStakeConnection] = useState<StakeConnection>()

const [stakeAccount, setStakeAccount] = useState<StakeAccount>()
const [amount, setAmount] = useState<PythBalance>()
const [recipient, setRecipient] = useState<PublicKey>()

useEffect(() => {
const initialize = async () => {
try {
const stakeConnection = await StakeConnection.createStakeConnection(
connection,
anchorWallet as Wallet,
STAKING_ADDRESS
)
setStakeConnection(stakeConnection)
} catch (e) {
toast.error(capitalizeFirstLetter(e.message))
}
}
if (!connected) {
setStakeConnection(undefined)
} else {
initialize()
}
}, [connected])

const router = useRouter()
const { key } = router.query

useEffect(() => {
const helper = async () => {
if (stakeConnection !== undefined) {
const splitAccountOwner: PublicKey = new PublicKey(key!)
const stakeAccount = (await stakeConnection!.getMainAccount(
splitAccountOwner
))!

const { balance, recipient } = (await stakeConnection.getSplitRequest(
stakeAccount
))!

setStakeAccount(stakeAccount)
setAmount(balance)
setRecipient(recipient)
}
}
helper()
}, [stakeConnection])

const approveSplit = async () => {
await stakeConnection!.acceptSplit(stakeAccount!, amount!, recipient!)
}

return (
<Layout>
<SEO title={'Approve Split'} />
<p className=" text-sm ">Approve a split request from {key}</p>
<p>
{stakeAccount != undefined
? `stake account address: ${stakeAccount.address}`
: 'no owner'}
</p>
<p>{amount != undefined ? `amount: ${amount}` : 'no amount'}</p>
<p>
{recipient != undefined ? `recipient: ${recipient}` : 'no recipient'}
</p>
<button
className="rounded-full p-2 hover:bg-hoverGray"
onClick={() => approveSplit()}
>
Click to approve
</button>
</Layout>
)
}

export default ApproveSplit
20 changes: 20 additions & 0 deletions staking/app/StakeConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,26 @@ export class StakeConnection {
.rpc();
}

public async getSplitRequest(
stakeAccount: StakeAccount
): Promise<{ balance: PythBalance; recipient: PublicKey } | undefined> {
const splitRequestAccount = PublicKey.findProgramAddressSync(
[
utils.bytes.utf8.encode(wasm.Constants.SPLIT_REQUEST()),
stakeAccount.address.toBuffer(),
],
this.program.programId
)[0];
const splitRequest = await this.program.account.splitRequest.fetch(
splitRequestAccount
);

return {
balance: new PythBalance(splitRequest.amount),
recipient: splitRequest.recipient,
};
}

public async acceptSplit(
stakeAccount: StakeAccount,
amount: PythBalance,
Expand Down
2 changes: 1 addition & 1 deletion staking/programs/staking/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ pub struct AcceptSplit<'info> {
pub source_stake_account_positions: AccountLoader<'info, positions::PositionData>,
#[account(mut, seeds = [STAKE_ACCOUNT_METADATA_SEED.as_bytes(), source_stake_account_positions.key().as_ref()], bump = source_stake_account_metadata.metadata_bump)]
pub source_stake_account_metadata: Box<Account<'info, stake_account::StakeAccountMetadataV2>>,
#[account(seeds = [SPLIT_REQUEST.as_bytes(), source_stake_account_positions.key().as_ref()], bump)]
#[account(mut, seeds = [SPLIT_REQUEST.as_bytes(), source_stake_account_positions.key().as_ref()], bump)]
pub source_stake_account_split_request: Box<Account<'info, split_request::SplitRequest>>,
#[account(
mut,
Expand Down
1 change: 1 addition & 0 deletions staking/programs/staking/src/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ reexport_seed_const!(TARGET_SEED);
reexport_seed_const!(MAX_VOTER_RECORD_SEED);
reexport_seed_const!(VOTING_TARGET_SEED);
reexport_seed_const!(DATA_TARGET_SEED);
reexport_seed_const!(SPLIT_REQUEST);

#[wasm_bindgen]
impl Constants {
Expand Down
2 changes: 1 addition & 1 deletion staking/target/idl/staking.json
Original file line number Diff line number Diff line change
Expand Up @@ -949,7 +949,7 @@
},
{
"name": "sourceStakeAccountSplitRequest",
"isMut": false,
"isMut": true,
"isSigner": false,
"pda": {
"seeds": [
Expand Down
4 changes: 2 additions & 2 deletions staking/target/types/staking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -949,7 +949,7 @@ export type Staking = {
},
{
"name": "sourceStakeAccountSplitRequest",
"isMut": false,
"isMut": true,
"isSigner": false,
"pda": {
"seeds": [
Expand Down Expand Up @@ -2920,7 +2920,7 @@ export const IDL: Staking = {
},
{
"name": "sourceStakeAccountSplitRequest",
"isMut": false,
"isMut": true,
"isSigner": false,
"pda": {
"seeds": [
Expand Down
18 changes: 18 additions & 0 deletions staking/tests/split_vesting_account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,30 @@ describe("split vesting account", async () => {
aliceConnection.userPublicKey()
);

let request = await samConnection.getSplitRequest(stakeAccount);
assert.equal(
JSON.stringify(request),
JSON.stringify({
balance: PythBalance.fromString("33"),
recipient: aliceConnection.userPublicKey(),
})
);

await pdaConnection.acceptSplit(
stakeAccount,
PythBalance.fromString("33"),
aliceConnection.userPublicKey()
);

request = await samConnection.getSplitRequest(stakeAccount);
assert.equal(
JSON.stringify(request),
JSON.stringify({
balance: PythBalance.fromString("0"),
recipient: aliceConnection.userPublicKey(),
})
);

await assertMainAccountBalance(
samConnection,
VestingAccountState.UnvestedTokensFullyUnlocked,
Expand Down

2 comments on commit b59be91

@vercel
Copy link

@vercel vercel bot commented on b59be91 Nov 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on b59be91 Nov 14, 2023

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-pyth-web.vercel.app
staking-devnet-git-main-pyth-web.vercel.app

Please sign in to comment.