forked from solana-labs/governance-ui
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Withdraw and Exercise for Dual Staking Options (solana-labs#1284)
* Initial commit for reals + Staking Options * Dual Staking Option (#1) * In progress fix * More instructions * Do TODO for all in one transaction * Validation for instruction * Separate payer * labels, order & tooltips * Add tooltips * More comment for base and quote treasury Co-authored-by: john <[email protected]> * Undo lint errors * Add to tooltips * fix yarn lock * fix proposal enum * alphabetic order of instructions * fix merge * add logo * create helper checking account * fix signers * Update hooks/useGovernanceAssets.ts Co-authored-by: Grégory NEUT <[email protected]> * Apply suggestions from code review Co-authored-by: Grégory NEUT <[email protected]> * Fix version of the sdk * build fix * fix * Withdraw * outline for withdraw and exercise * Initial commit for withdraw and exercise * withdraw code and template for exercise * remove logging * Exercise * Init fee account if needed * Use quote mint from the state obj * fix yarn lock * fix lint errors Co-authored-by: john <[email protected]> Co-authored-by: Adrian Brzeziński <[email protected]> Co-authored-by: Grégory NEUT <[email protected]>
- Loading branch information
1 parent
c4b85df
commit 69e2f90
Showing
10 changed files
with
424 additions
and
9 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
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
140 changes: 140 additions & 0 deletions
140
pages/dao/[symbol]/proposal/components/instructions/Dual/DualExercise.tsx
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,140 @@ | ||
/* eslint-disable @typescript-eslint/no-non-null-assertion */ | ||
import React, { useContext, useEffect, useState } from 'react' | ||
import { ProgramAccount, Governance } from '@solana/spl-governance' | ||
import { | ||
UiInstruction, | ||
DualFinanceExerciseForm, | ||
} from '@utils/uiTypes/proposalCreationTypes' | ||
import { NewProposalContext } from '../../../new' | ||
import GovernedAccountSelect from '../../GovernedAccountSelect' | ||
import useGovernanceAssets from '@hooks/useGovernanceAssets' | ||
import Input from '@components/inputs/Input' | ||
import { getExerciseInstruction } from '@utils/instructions/Dual' | ||
import useWalletStore from 'stores/useWalletStore' | ||
import { getDualFinanceExerciseSchema } from '@utils/validations' | ||
import Tooltip from '@components/Tooltip' | ||
|
||
const DualExercise = ({ | ||
index, | ||
governance, | ||
}: { | ||
index: number | ||
governance: ProgramAccount<Governance> | null | ||
}) => { | ||
const [form, setForm] = useState<DualFinanceExerciseForm>({ | ||
numTokens: 0, | ||
soName: undefined, | ||
baseTreasury: undefined, | ||
quoteTreasury: undefined, | ||
optionAccount: undefined, | ||
}) | ||
const connection = useWalletStore((s) => s.connection) | ||
const wallet = useWalletStore((s) => s.current) | ||
const shouldBeGoverned = !!(index !== 0 && governance) | ||
const { governedTokenAccountsWithoutNfts } = useGovernanceAssets() | ||
const [governedAccount, setGovernedAccount] = useState< | ||
ProgramAccount<Governance> | undefined | ||
>(undefined) | ||
|
||
const [formErrors, setFormErrors] = useState({}) | ||
const { handleSetInstructions } = useContext(NewProposalContext) | ||
const handleSetForm = ({ propertyName, value }) => { | ||
setFormErrors({}) | ||
setForm({ ...form, [propertyName]: value }) | ||
} | ||
function getInstruction(): Promise<UiInstruction> { | ||
return getExerciseInstruction({ | ||
connection, | ||
form, | ||
schema, | ||
setFormErrors, | ||
wallet, | ||
}) | ||
} | ||
useEffect(() => { | ||
handleSetInstructions( | ||
{ governedAccount: governedAccount, getInstruction }, | ||
index | ||
) | ||
}, [form]) | ||
useEffect(() => { | ||
setGovernedAccount(form.baseTreasury?.governance) | ||
}, [form.baseTreasury]) | ||
const schema = getDualFinanceExerciseSchema() | ||
|
||
// TODO: Find the name from metaplex from a token lookup once that is | ||
// connected to the program. | ||
return ( | ||
<> | ||
<Tooltip content="Identifier for the Staking Option"> | ||
<Input | ||
label="Name" | ||
value={form.soName} | ||
type="text" | ||
onChange={(evt) => | ||
handleSetForm({ | ||
value: evt.target.value, | ||
propertyName: 'soName', | ||
}) | ||
} | ||
error={formErrors['soName']} | ||
/> | ||
</Tooltip> | ||
<Tooltip content="Option token that will be exercised."> | ||
<GovernedAccountSelect | ||
label="Option Account" | ||
governedAccounts={governedTokenAccountsWithoutNfts} | ||
onChange={(value) => { | ||
handleSetForm({ value, propertyName: 'optionAccount' }) | ||
}} | ||
value={form.optionAccount} | ||
error={formErrors['optionAccount']} | ||
shouldBeGoverned={shouldBeGoverned} | ||
governance={governance} | ||
></GovernedAccountSelect> | ||
</Tooltip> | ||
<Tooltip content="Treasury owned account providing the payment for the option."> | ||
<GovernedAccountSelect | ||
label="Quote Treasury" | ||
governedAccounts={governedTokenAccountsWithoutNfts} | ||
onChange={(value) => { | ||
handleSetForm({ value, propertyName: 'quoteTreasury' }) | ||
}} | ||
value={form.quoteTreasury} | ||
error={formErrors['quoteTreasury']} | ||
shouldBeGoverned={shouldBeGoverned} | ||
governance={governance} | ||
></GovernedAccountSelect> | ||
</Tooltip> | ||
<Tooltip content="Treasury owned account receiving the option exercise."> | ||
<GovernedAccountSelect | ||
label="Base Treasury" | ||
governedAccounts={governedTokenAccountsWithoutNfts} | ||
onChange={(value) => { | ||
handleSetForm({ value, propertyName: 'baseTreasury' }) | ||
}} | ||
value={form.baseTreasury} | ||
error={formErrors['baseTreasury']} | ||
shouldBeGoverned={shouldBeGoverned} | ||
governance={governance} | ||
></GovernedAccountSelect> | ||
</Tooltip> | ||
<Tooltip content="How many option tokens are exercised staking options."> | ||
<Input | ||
label="Quantity" | ||
value={form.numTokens} | ||
type="number" | ||
onChange={(evt) => | ||
handleSetForm({ | ||
value: evt.target.value, | ||
propertyName: 'numTokens', | ||
}) | ||
} | ||
error={formErrors['numTokens']} | ||
/> | ||
</Tooltip> | ||
</> | ||
) | ||
} | ||
|
||
export default DualExercise |
97 changes: 97 additions & 0 deletions
97
pages/dao/[symbol]/proposal/components/instructions/Dual/DualWithdraw.tsx
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,97 @@ | ||
/* eslint-disable @typescript-eslint/no-non-null-assertion */ | ||
import React, { useContext, useEffect, useState } from 'react' | ||
import { ProgramAccount, Governance } from '@solana/spl-governance' | ||
import { | ||
UiInstruction, | ||
DualFinanceWithdrawForm, | ||
} from '@utils/uiTypes/proposalCreationTypes' | ||
import { NewProposalContext } from '../../../new' | ||
import GovernedAccountSelect from '../../GovernedAccountSelect' | ||
import useGovernanceAssets from '@hooks/useGovernanceAssets' | ||
import Input from '@components/inputs/Input' | ||
import { getWithdrawInstruction } from '@utils/instructions/Dual' | ||
import useWalletStore from 'stores/useWalletStore' | ||
import { getDualFinanceWithdrawSchema } from '@utils/validations' | ||
import Tooltip from '@components/Tooltip' | ||
|
||
const DualWithdraw = ({ | ||
index, | ||
governance, | ||
}: { | ||
index: number | ||
governance: ProgramAccount<Governance> | null | ||
}) => { | ||
const [form, setForm] = useState<DualFinanceWithdrawForm>({ | ||
soName: undefined, | ||
baseTreasury: undefined, | ||
}) | ||
const connection = useWalletStore((s) => s.connection) | ||
const wallet = useWalletStore((s) => s.current) | ||
const shouldBeGoverned = !!(index !== 0 && governance) | ||
const { governedTokenAccountsWithoutNfts } = useGovernanceAssets() | ||
const [governedAccount, setGovernedAccount] = useState< | ||
ProgramAccount<Governance> | undefined | ||
>(undefined) | ||
|
||
const [formErrors, setFormErrors] = useState({}) | ||
const { handleSetInstructions } = useContext(NewProposalContext) | ||
const handleSetForm = ({ propertyName, value }) => { | ||
setFormErrors({}) | ||
setForm({ ...form, [propertyName]: value }) | ||
} | ||
function getInstruction(): Promise<UiInstruction> { | ||
return getWithdrawInstruction({ | ||
connection, | ||
form, | ||
schema, | ||
setFormErrors, | ||
wallet, | ||
}) | ||
} | ||
useEffect(() => { | ||
handleSetInstructions( | ||
{ governedAccount: governedAccount, getInstruction }, | ||
index | ||
) | ||
}, [form]) | ||
useEffect(() => { | ||
setGovernedAccount(form.baseTreasury?.governance) | ||
}, [form.baseTreasury]) | ||
const schema = getDualFinanceWithdrawSchema() | ||
|
||
// TODO: Include this in the config instruction which can optionally be done | ||
// if the project doesnt need to change where the tokens get returned to. | ||
return ( | ||
<> | ||
<Tooltip content="Identifier for the Staking Option"> | ||
<Input | ||
label="Name" | ||
value={form.soName} | ||
type="text" | ||
onChange={(evt) => | ||
handleSetForm({ | ||
value: evt.target.value, | ||
propertyName: 'soName', | ||
}) | ||
} | ||
error={formErrors['soName']} | ||
/> | ||
</Tooltip> | ||
<Tooltip content="Treasury owned account receiving the tokens back."> | ||
<GovernedAccountSelect | ||
label="Base Treasury" | ||
governedAccounts={governedTokenAccountsWithoutNfts} | ||
onChange={(value) => { | ||
handleSetForm({ value, propertyName: 'baseTreasury' }) | ||
}} | ||
value={form.baseTreasury} | ||
error={formErrors['baseTreasury']} | ||
shouldBeGoverned={shouldBeGoverned} | ||
governance={governance} | ||
></GovernedAccountSelect> | ||
</Tooltip> | ||
</> | ||
) | ||
} | ||
|
||
export default DualWithdraw |
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
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
Oops, something went wrong.