Skip to content

Commit

Permalink
Accept transfer (#310)
Browse files Browse the repository at this point in the history
* Cleanup

* Refactor approve

* Use nullable

* Cleanup

* Add toast

* Do it
  • Loading branch information
guibescos authored Dec 20, 2023
1 parent 0fe41b6 commit c600e61
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 59 deletions.
135 changes: 95 additions & 40 deletions frontend/pages/approve.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,77 +13,132 @@ import {
STAKING_ADDRESS,
} from '@pythnetwork/staking'
import { useEffect, useState } from 'react'
import { utils, Wallet } from '@coral-xyz/anchor'
import toast from 'react-hot-toast'
import { capitalizeFirstLetter } from '../utils/capitalizeFirstLetter'
import { Wallet } from '@coral-xyz/anchor'
import { PublicKey } from '@solana/web3.js'
import { useRouter } from 'next/router'
import toast from 'react-hot-toast'
import { capitalizeFirstLetter } from 'utils/capitalizeFirstLetter'

const ApproveSplit: NextPage = () => {
const { connection } = useConnection()
const anchorWallet = useAnchorWallet()
const { publicKey, connected } = useWallet()
const [amount, setAmount] = useState<PythBalance>()
const [recipient, setRecipient] = useState<PublicKey>()

const [stakeConnection, setStakeConnection] = useState<StakeConnection>()
const [stakeAccounts, setStakeAccounts] = useState<StakeAccount[]>()
const [selectedStakeAccount, setSelectStakeAccount] = useState<StakeAccount>()

const [stakeAccount, setStakeAccount] = useState<StakeAccount>()
const [amount, setAmount] = useState<PythBalance>()
const [recipient, setRecipient] = useState<PublicKey>()
const router = useRouter()
const { owner } = router.query

const handleSelectStakeAccount = (event: any) => {
for (const stakeAccount of stakeAccounts!) {
if (stakeAccount.address.toString() === event.target.value) {
setSelectStakeAccount(stakeAccount)
break
}
}
}

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))
}
const stakeConnection = await StakeConnection.createStakeConnection(
connection,
anchorWallet as Wallet,
STAKING_ADDRESS
)
setStakeConnection(stakeConnection)
}
if (!connected) {

if (!anchorWallet) {
setStakeConnection(undefined)
} else {
initialize()
}
}, [connected])

const router = useRouter()
const { key } = router.query
}, [anchorWallet])

useEffect(() => {
const helper = async () => {
if (stakeConnection !== undefined) {
const splitAccountOwner: PublicKey = new PublicKey(key!)
const stakeAccount = (await stakeConnection!.getMainAccount(
splitAccountOwner
))!
const loadStakeAccounts = async () => {
if (stakeConnection && anchorWallet) {
const stakeAccounts = await stakeConnection.getStakeAccounts(
new PublicKey(owner!)
)
setStakeAccounts(stakeAccounts)
} else {
setStakeAccounts(undefined)
}
}
loadStakeAccounts()
}, [stakeConnection])

const { balance, recipient } = (await stakeConnection.getSplitRequest(
stakeAccount
))!
useEffect(() => {
const loadCurrentRequest = async () => {
if (stakeConnection && selectedStakeAccount) {
const request = await stakeConnection.getSplitRequest(
selectedStakeAccount
)

setStakeAccount(stakeAccount)
setAmount(balance)
setRecipient(recipient)
if (request) {
setAmount(request.balance)
setRecipient(request.recipient)
} else {
setAmount(undefined)
setRecipient(undefined)
}
}
}
helper()
}, [stakeConnection])
loadCurrentRequest()
}, [selectedStakeAccount])

useEffect(() => {
if (stakeAccounts && stakeAccounts.length > 0)
setSelectStakeAccount(stakeAccounts[0])
}, [stakeAccounts])

const approveSplit = async () => {
await stakeConnection!.acceptSplit(stakeAccount!, amount!, recipient!)
if (stakeConnection && selectedStakeAccount && recipient && amount) {
try {
await stakeConnection.acceptSplit(
selectedStakeAccount,
amount,
recipient
)
toast.success('Successfully created transfer request')
} catch (err) {
toast.error(capitalizeFirstLetter(err.message))
}
}
}

return (
<Layout>
<SEO title={'Approve Split'} />
<p className=" text-sm ">Approve a split request from {key}</p>
<p className=" text-sm ">Approve a split request from {owner}</p>
<p>
{stakeAccount != undefined
? `stake account address: ${stakeAccount.address}`
{stakeConnection &&
stakeAccounts !== undefined &&
stakeAccounts.length > 0 && (
<div>
<p className=" p-2 ">
Request a transfer of locked tokens to a new account
</p>

<select
style={{ color: 'black' }}
value={selectedStakeAccount?.address.toString()}
onChange={handleSelectStakeAccount}
>
{stakeAccounts.map((option, index) => (
<option key={index} value={option.address.toBase58()}>
{option.address.toString()}
</option>
))}
</select>
</div>
)}
{selectedStakeAccount != undefined
? `stake account address: ${selectedStakeAccount.address}`
: 'no owner'}
</p>
<p>{amount != undefined ? `amount: ${amount}` : 'no amount'}</p>
Expand Down
33 changes: 19 additions & 14 deletions frontend/pages/request.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ const RequestSplit: NextPage = () => {
const { connection } = useConnection()
const anchorWallet = useAnchorWallet()

const [owner, setOwner] = useState<PublicKey>()
const [recipient, setRecipient] = useState<PublicKey>()
const [amount, setAmount] = useState<PythBalance>()

const handleSetOwner = (event: any) => {
const handleSetRecipient = (event: any) => {
try {
setOwner(new PublicKey(event.target.value))
setRecipient(new PublicKey(event.target.value))
} catch (e) {
setOwner(undefined)
setRecipient(undefined)
}
}
const handleSetAmount = (event: any) => {
Expand Down Expand Up @@ -88,7 +88,7 @@ const RequestSplit: NextPage = () => {
)
if (request) {
setAmount(request.balance)
setOwner(request.recipient)
setRecipient(request.recipient)
}
}
loadCurrentRequest()
Expand All @@ -101,9 +101,13 @@ const RequestSplit: NextPage = () => {
}, [stakeAccounts])

const requestSplit = async () => {
if (stakeConnection && selectedStakeAccount && owner && amount)
if (stakeConnection && selectedStakeAccount && recipient && amount)
try {
await stakeConnection.requestSplit(selectedStakeAccount, amount, owner)
await stakeConnection.requestSplit(
selectedStakeAccount,
amount,
recipient
)
toast.success('Successfully created transfer request')
} catch (err) {
toast.error(capitalizeFirstLetter(err.message))
Expand Down Expand Up @@ -141,12 +145,12 @@ const RequestSplit: NextPage = () => {
</p>
)}

<p className=" text-sm ">New owner</p>
<p className=" text-sm ">Recipient</p>
<input
type="text"
style={{ color: 'black' }}
value={owner ? owner.toString() : ''}
onChange={handleSetOwner}
value={recipient ? recipient.toString() : ''}
onChange={handleSetRecipient}
/>
<p className=" text-sm ">Amount</p>
<input
Expand All @@ -156,7 +160,8 @@ const RequestSplit: NextPage = () => {
onChange={handleSetAmount}
/>
<p className=" text-sm ">
Owner : {owner ? owner.toString() : 'Invalid new owner'}
Recipient :{' '}
{recipient ? recipient.toString() : 'Invalid recipient'}
</p>
<p className=" text-sm ">
Amount to be transferred:{' '}
Expand All @@ -165,7 +170,7 @@ const RequestSplit: NextPage = () => {
</div>
)}

{stakeConnection && owner && amount ? (
{stakeConnection && recipient && amount ? (
<p>
<button
className="rounded-full p-2 hover:bg-hoverGray"
Expand All @@ -176,8 +181,8 @@ const RequestSplit: NextPage = () => {
</p>
) : !stakeConnection ? (
<p className="p-2 hover:bg-hoverGray"> Please connect wallet</p>
) : !owner ? (
<p className="p-2 hover:bg-hoverGray ">Please insert valid new owner</p>
) : !recipient ? (
<p className="p-2 hover:bg-hoverGray ">Please insert valid recipient</p>
) : (
<p className="p-2 hover:bg-hoverGray ">
Please insert valid amount to be transferred
Expand Down
14 changes: 9 additions & 5 deletions staking/app/StakeConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -898,14 +898,18 @@ export class StakeConnection {
],
this.program.programId
)[0];
const splitRequest = await this.program.account.splitRequest.fetch(
const splitRequest = await this.program.account.splitRequest.fetchNullable(
splitRequestAccount
);

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

public async acceptSplit(
Expand Down

2 comments on commit c600e61

@vercel
Copy link

@vercel vercel bot commented on c600e61 Dec 20, 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 – ./

staking-devnet-git-main-pyth-web.vercel.app
staking-devnet-pyth-web.vercel.app
governance-nu.vercel.app

@vercel
Copy link

@vercel vercel bot commented on c600e61 Dec 20, 2023

Choose a reason for hiding this comment

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

Please sign in to comment.