mirror of https://github.com/certusone/oyster.git
commit
3132591862
|
@ -95,9 +95,9 @@ export const PROGRAM_IDS = [
|
||||||
name: 'devnet',
|
name: 'devnet',
|
||||||
timelock: () => ({
|
timelock: () => ({
|
||||||
programAccountId: new PublicKey(
|
programAccountId: new PublicKey(
|
||||||
'Hn2FtiPy4fYu4WgEeuvF8Y6os412a1iQvam2rrT6ibX1',
|
'Gc6ktQPgHDxf9GpN6CdLEnkkqj5NfGYJeLDWFLoN3wNb',
|
||||||
),
|
),
|
||||||
programId: new PublicKey('5naVRdHoPFFQd2vTcWywyHthqqYziKvwu8urSxzV6Qj4'),
|
programId: new PublicKey('FmxAXMEKaj7BvgH9zdRNMZZYdAk4mBeRdSQwUoM3QYYw'),
|
||||||
}),
|
}),
|
||||||
wormhole: () => ({
|
wormhole: () => ({
|
||||||
pubkey: new PublicKey('WormT3McKhFJ2RkiGpdw9GKvNCrB2aB54gb2uV9MfQC'),
|
pubkey: new PublicKey('WormT3McKhFJ2RkiGpdw9GKvNCrB2aB54gb2uV9MfQC'),
|
||||||
|
|
|
@ -272,7 +272,7 @@ async function getAssociatedAccountsAndInstructions(
|
||||||
wallet.publicKey,
|
wallet.publicKey,
|
||||||
accountRentExempt,
|
accountRentExempt,
|
||||||
yesVoteMint,
|
yesVoteMint,
|
||||||
wallet.publicKey,
|
authority,
|
||||||
holdingSigners,
|
holdingSigners,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -281,7 +281,7 @@ async function getAssociatedAccountsAndInstructions(
|
||||||
wallet.publicKey,
|
wallet.publicKey,
|
||||||
accountRentExempt,
|
accountRentExempt,
|
||||||
noVoteMint,
|
noVoteMint,
|
||||||
wallet.publicKey,
|
authority,
|
||||||
holdingSigners,
|
holdingSigners,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -290,7 +290,7 @@ async function getAssociatedAccountsAndInstructions(
|
||||||
wallet.publicKey,
|
wallet.publicKey,
|
||||||
accountRentExempt,
|
accountRentExempt,
|
||||||
timelockConfig.info.governanceMint,
|
timelockConfig.info.governanceMint,
|
||||||
wallet.publicKey,
|
authority,
|
||||||
holdingSigners,
|
holdingSigners,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -23,14 +23,7 @@ export const execute = async (
|
||||||
|
|
||||||
let signers: Account[] = [];
|
let signers: Account[] = [];
|
||||||
let instructions: TransactionInstruction[] = [];
|
let instructions: TransactionInstruction[] = [];
|
||||||
|
|
||||||
const [authority] = await PublicKey.findProgramAddress(
|
|
||||||
[PROGRAM_IDS.timelock.programAccountId.toBuffer()],
|
|
||||||
PROGRAM_IDS.timelock.programId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const actualMessage = decodeBufferIntoMessage(transaction.info.instruction);
|
const actualMessage = decodeBufferIntoMessage(transaction.info.instruction);
|
||||||
console.log('Actual message', actualMessage);
|
|
||||||
const accountInfos = getAccountInfos(actualMessage);
|
const accountInfos = getAccountInfos(actualMessage);
|
||||||
|
|
||||||
instructions.push(
|
instructions.push(
|
||||||
|
@ -38,7 +31,7 @@ export const execute = async (
|
||||||
transaction.pubkey,
|
transaction.pubkey,
|
||||||
proposal.pubkey,
|
proposal.pubkey,
|
||||||
actualMessage.accountKeys[actualMessage.instructions[0].programIdIndex],
|
actualMessage.accountKeys[actualMessage.instructions[0].programIdIndex],
|
||||||
authority,
|
proposal.info.config,
|
||||||
accountInfos,
|
accountInfos,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -119,7 +119,6 @@ export const withdrawVotingTokens = async (
|
||||||
proposal.info.noVotingDump,
|
proposal.info.noVotingDump,
|
||||||
proposal.info.votingMint,
|
proposal.info.votingMint,
|
||||||
proposal.pubkey,
|
proposal.pubkey,
|
||||||
proposal.info.config,
|
|
||||||
transferAuthority.publicKey,
|
transferAuthority.publicKey,
|
||||||
yesTransferAuthority.publicKey,
|
yesTransferAuthority.publicKey,
|
||||||
noTransferAuthority.publicKey,
|
noTransferAuthority.publicKey,
|
||||||
|
|
|
@ -46,7 +46,10 @@ export function RegisterToVote({
|
||||||
const eligibleToView =
|
const eligibleToView =
|
||||||
(timelockConfig.info.votingEntryRule == VotingEntryRule.DraftOnly &&
|
(timelockConfig.info.votingEntryRule == VotingEntryRule.DraftOnly &&
|
||||||
proposal.info.state.status == TimelockStateStatus.Draft) ||
|
proposal.info.state.status == TimelockStateStatus.Draft) ||
|
||||||
timelockConfig.info.votingEntryRule == VotingEntryRule.Anytime;
|
(timelockConfig.info.votingEntryRule == VotingEntryRule.Anytime &&
|
||||||
|
[TimelockStateStatus.Draft, TimelockStateStatus.Voting].includes(
|
||||||
|
proposal.info.state.status,
|
||||||
|
));
|
||||||
const [_, setTokenAmount] = useState(1);
|
const [_, setTokenAmount] = useState(1);
|
||||||
return eligibleToView ? (
|
return eligibleToView ? (
|
||||||
<Button
|
<Button
|
||||||
|
|
|
@ -41,7 +41,6 @@ export function Vote({
|
||||||
return eligibleToView ? (
|
return eligibleToView ? (
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
disabled={!voteAccount}
|
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
confirm({
|
confirm({
|
||||||
title: 'Confirm',
|
title: 'Confirm',
|
||||||
|
@ -72,15 +71,18 @@ export function Vote({
|
||||||
cancelText: LABELS.CANCEL,
|
cancelText: LABELS.CANCEL,
|
||||||
onOk: async () => {
|
onOk: async () => {
|
||||||
if (voteAccount && yesVoteAccount && noVoteAccount) {
|
if (voteAccount && yesVoteAccount && noVoteAccount) {
|
||||||
// tokenAmount is out of date in this scope, so we use a trick to get it here.
|
// tokenAmount and mode is out of date in this scope, so we use a trick to get it here.
|
||||||
const valueHolder = { value: 0 };
|
const valueHolder = { value: 0, mode: true };
|
||||||
await setTokenAmount(amount => {
|
await setTokenAmount(amount => {
|
||||||
valueHolder.value = amount;
|
valueHolder.value = amount;
|
||||||
return amount;
|
return amount;
|
||||||
});
|
});
|
||||||
const yesTokenAmount = mode ? valueHolder.value : 0;
|
await setMode(mode => {
|
||||||
const noTokenAmount = !mode ? valueHolder.value : 0;
|
valueHolder.mode = mode;
|
||||||
|
return mode;
|
||||||
|
});
|
||||||
|
const yesTokenAmount = valueHolder.mode ? valueHolder.value : 0;
|
||||||
|
const noTokenAmount = !valueHolder.mode ? valueHolder.value : 0;
|
||||||
await vote(
|
await vote(
|
||||||
connection,
|
connection,
|
||||||
wallet.wallet,
|
wallet.wallet,
|
||||||
|
|
|
@ -33,16 +33,20 @@ export function WithdrawTokens({
|
||||||
const governanceAccount = useAccountByMint(
|
const governanceAccount = useAccountByMint(
|
||||||
timelockConfig.info.governanceMint,
|
timelockConfig.info.governanceMint,
|
||||||
);
|
);
|
||||||
const totalTokens =
|
const votingTokens = (voteAccount && voteAccount.info.amount.toNumber()) || 0;
|
||||||
((voteAccount && voteAccount.info.amount.toNumber()) || 0) +
|
let totalTokens = votingTokens;
|
||||||
|
const inEscrow =
|
||||||
((yesVoteAccount && yesVoteAccount.info.amount.toNumber()) || 0) +
|
((yesVoteAccount && yesVoteAccount.info.amount.toNumber()) || 0) +
|
||||||
((noVoteAccount && noVoteAccount.info.amount.toNumber()) || 0);
|
((noVoteAccount && noVoteAccount.info.amount.toNumber()) || 0);
|
||||||
|
let additionalMsg = '';
|
||||||
|
if (proposal.info.state.status !== TimelockStateStatus.Voting) {
|
||||||
|
totalTokens += inEscrow;
|
||||||
|
} else additionalMsg = LABELS.ADDITIONAL_VOTING_MSG;
|
||||||
|
|
||||||
const [_, setTokenAmount] = useState(1);
|
const [_, setTokenAmount] = useState(1);
|
||||||
return totalTokens > 0 ? (
|
return votingTokens + inEscrow > 0 ? (
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
disabled={!voteAccount}
|
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
confirm({
|
confirm({
|
||||||
title: 'Confirm',
|
title: 'Confirm',
|
||||||
|
@ -50,8 +54,14 @@ export function WithdrawTokens({
|
||||||
content: (
|
content: (
|
||||||
<Row>
|
<Row>
|
||||||
<Col span={24}>
|
<Col span={24}>
|
||||||
<p>You can withdraw up to {totalTokens} voting tokens.</p>
|
<p>You can withdraw up to {totalTokens} voting tokens. </p>
|
||||||
|
{additionalMsg && <p>{additionalMsg}</p>}
|
||||||
|
{additionalMsg && (
|
||||||
|
<p>
|
||||||
|
You have {inEscrow} tokens in holding until voting
|
||||||
|
completes.
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
<Slider min={1} max={totalTokens} onChange={setTokenAmount} />
|
<Slider min={1} max={totalTokens} onChange={setTokenAmount} />
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
|
@ -90,4 +90,6 @@ export const LABELS = {
|
||||||
PUBLIC_KEY: 'Public Key',
|
PUBLIC_KEY: 'Public Key',
|
||||||
MENU_GOVERNANCE: 'My Governed Programs',
|
MENU_GOVERNANCE: 'My Governed Programs',
|
||||||
LEAVE_BLANK_IF_YOU_WANT_ONE: 'Leave blank if you want one made for you',
|
LEAVE_BLANK_IF_YOU_WANT_ONE: 'Leave blank if you want one made for you',
|
||||||
|
ADDITIONAL_VOTING_MSG:
|
||||||
|
' Please note that during voting, you cannot withdraw tokens you have used to vote. You must wait for the vote to complete.',
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,15 +12,15 @@ import { TimelockInstruction } from './timelock';
|
||||||
/// 0. `[writable]` Transaction account you wish to execute.
|
/// 0. `[writable]` Transaction account you wish to execute.
|
||||||
/// 1. `[]` Timelock set account.
|
/// 1. `[]` Timelock set account.
|
||||||
/// 2. `[]` Program being invoked account
|
/// 2. `[]` Program being invoked account
|
||||||
/// 3. `[]` Timelock program authority
|
/// 4. `[]` Timelock config
|
||||||
/// 4. `[]` Timelock program account pub key.
|
/// 5. `[]` Timelock program account pub key.
|
||||||
/// 5. `[]` Clock sysvar.
|
/// 6. `[]` Clock sysvar.
|
||||||
/// 6+ Any extra accounts that are part of the instruction, in order
|
/// 6+ Any extra accounts that are part of the instruction, in order
|
||||||
export const executeInstruction = (
|
export const executeInstruction = (
|
||||||
transactionAccount: PublicKey,
|
transactionAccount: PublicKey,
|
||||||
timelockSetAccount: PublicKey,
|
timelockSetAccount: PublicKey,
|
||||||
programBeingInvokedAccount: PublicKey,
|
programBeingInvokedAccount: PublicKey,
|
||||||
timelockAuthority: PublicKey,
|
timelockConfig: PublicKey,
|
||||||
accountInfos: { pubkey: PublicKey; isWritable: boolean; isSigner: boolean }[],
|
accountInfos: { pubkey: PublicKey; isWritable: boolean; isSigner: boolean }[],
|
||||||
): TransactionInstruction => {
|
): TransactionInstruction => {
|
||||||
const PROGRAM_IDS = utils.programIds();
|
const PROGRAM_IDS = utils.programIds();
|
||||||
|
@ -39,16 +39,12 @@ export const executeInstruction = (
|
||||||
},
|
},
|
||||||
data,
|
data,
|
||||||
);
|
);
|
||||||
console.log(
|
|
||||||
'Acohjnt',
|
|
||||||
accountInfos.map(a => console.log(a.pubkey.toBase58(), a.isWritable)),
|
|
||||||
);
|
|
||||||
|
|
||||||
const keys = [
|
const keys = [
|
||||||
{ pubkey: transactionAccount, isSigner: false, isWritable: true },
|
{ pubkey: transactionAccount, isSigner: false, isWritable: true },
|
||||||
{ pubkey: timelockSetAccount, isSigner: false, isWritable: true },
|
{ pubkey: timelockSetAccount, isSigner: false, isWritable: true },
|
||||||
{ pubkey: programBeingInvokedAccount, isSigner: false, isWritable: true },
|
{ pubkey: programBeingInvokedAccount, isSigner: false, isWritable: true },
|
||||||
{ pubkey: timelockAuthority, isSigner: false, isWritable: true },
|
{ pubkey: timelockConfig, isSigner: false, isWritable: true },
|
||||||
{
|
{
|
||||||
pubkey: PROGRAM_IDS.timelock.programAccountId,
|
pubkey: PROGRAM_IDS.timelock.programAccountId,
|
||||||
isSigner: false,
|
isSigner: false,
|
||||||
|
|
|
@ -11,17 +11,16 @@ import BN from 'bn.js';
|
||||||
/// 2. `[writable]` Initialized No Voting account from which to remove your voting tokens.
|
/// 2. `[writable]` Initialized No Voting account from which to remove your voting tokens.
|
||||||
/// 3. `[writable]` Governance token account that you wish your actual tokens to be returned to.
|
/// 3. `[writable]` Governance token account that you wish your actual tokens to be returned to.
|
||||||
/// 4. `[writable]` Governance holding account owned by the timelock that will has the actual tokens in escrow.
|
/// 4. `[writable]` Governance holding account owned by the timelock that will has the actual tokens in escrow.
|
||||||
/// 6. `[writable]` Initialized Yes Voting dump account owned by timelock set to which to send your voting tokens.
|
/// 5. `[writable]` Initialized Yes Voting dump account owned by timelock set to which to send your voting tokens.
|
||||||
/// 7. `[writable]` Initialized No Voting dump account owned by timelock set to which to send your voting tokens.
|
/// 6. `[writable]` Initialized No Voting dump account owned by timelock set to which to send your voting tokens.
|
||||||
/// 8. `[]` Voting mint account.
|
/// 7. `[]` Voting mint account.
|
||||||
/// 9. `[]` Timelock set account.
|
/// 8. `[]` Timelock set account.
|
||||||
/// 10. `[]` Timelock config account.
|
/// 9. `[]` Transfer authority
|
||||||
/// 11. `[]` Transfer authority
|
/// 10. `[]` Yes Transfer authority
|
||||||
/// 12. `[]` Yes Transfer authority
|
/// 11. `[]` No Transfer authority
|
||||||
/// 13. `[]` No Transfer authority
|
/// 12. `[]` Timelock program mint authority
|
||||||
/// 14. `[]` Timelock program mint authority
|
/// 13. `[]` Timelock program account pub key.
|
||||||
/// 15. `[]` Timelock program account pub key.
|
/// 14. `[]` Token program account.
|
||||||
/// 16. `[]` Token program account.
|
|
||||||
export const withdrawVotingTokensInstruction = (
|
export const withdrawVotingTokensInstruction = (
|
||||||
votingAccount: PublicKey,
|
votingAccount: PublicKey,
|
||||||
yesVotingAccount: PublicKey,
|
yesVotingAccount: PublicKey,
|
||||||
|
@ -32,7 +31,6 @@ export const withdrawVotingTokensInstruction = (
|
||||||
noVotingDump: PublicKey,
|
noVotingDump: PublicKey,
|
||||||
votingMint: PublicKey,
|
votingMint: PublicKey,
|
||||||
timelockSetAccount: PublicKey,
|
timelockSetAccount: PublicKey,
|
||||||
timelockConfigAccount: PublicKey,
|
|
||||||
transferAuthority: PublicKey,
|
transferAuthority: PublicKey,
|
||||||
yesTransferAuthority: PublicKey,
|
yesTransferAuthority: PublicKey,
|
||||||
noTransferAuthority: PublicKey,
|
noTransferAuthority: PublicKey,
|
||||||
|
@ -66,7 +64,6 @@ export const withdrawVotingTokensInstruction = (
|
||||||
{ pubkey: noVotingDump, isSigner: false, isWritable: true },
|
{ pubkey: noVotingDump, isSigner: false, isWritable: true },
|
||||||
{ pubkey: votingMint, isSigner: false, isWritable: true },
|
{ pubkey: votingMint, isSigner: false, isWritable: true },
|
||||||
{ pubkey: timelockSetAccount, isSigner: false, isWritable: false },
|
{ pubkey: timelockSetAccount, isSigner: false, isWritable: false },
|
||||||
{ pubkey: timelockConfigAccount, isSigner: false, isWritable: false },
|
|
||||||
{ pubkey: transferAuthority, isSigner: false, isWritable: false },
|
{ pubkey: transferAuthority, isSigner: false, isWritable: false },
|
||||||
{ pubkey: yesTransferAuthority, isSigner: false, isWritable: false },
|
{ pubkey: yesTransferAuthority, isSigner: false, isWritable: false },
|
||||||
{ pubkey: noTransferAuthority, isSigner: false, isWritable: false },
|
{ pubkey: noTransferAuthority, isSigner: false, isWritable: false },
|
||||||
|
|
|
@ -41,13 +41,13 @@ export const ProposalView = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flexColumn">
|
<div className="flexColumn">
|
||||||
{proposal && sigMint && votingMint && governanceMint ? (
|
{proposal && sigMint && votingMint && governanceMint && yesVotingMint ? (
|
||||||
<InnerProposalView
|
<InnerProposalView
|
||||||
proposal={proposal}
|
proposal={proposal}
|
||||||
timelockConfig={timelockConfig}
|
timelockConfig={timelockConfig}
|
||||||
governanceMint={governanceMint}
|
governanceMint={governanceMint}
|
||||||
votingMint={votingMint}
|
votingMint={votingMint}
|
||||||
yesVotingMint={votingMint}
|
yesVotingMint={yesVotingMint}
|
||||||
sigMint={sigMint}
|
sigMint={sigMint}
|
||||||
instructions={context.transactions}
|
instructions={context.transactions}
|
||||||
/>
|
/>
|
||||||
|
@ -208,7 +208,6 @@ function InnerProposalView({
|
||||||
: 'vertical'
|
: 'vertical'
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<MintGovernanceTokens timelockConfig={timelockConfig} />
|
|
||||||
<RegisterToVote
|
<RegisterToVote
|
||||||
timelockConfig={timelockConfig}
|
timelockConfig={timelockConfig}
|
||||||
proposal={proposal}
|
proposal={proposal}
|
||||||
|
@ -226,6 +225,16 @@ function InnerProposalView({
|
||||||
title={LABELS.VOTES_REQUIRED}
|
title={LABELS.VOTES_REQUIRED}
|
||||||
value={getVotesRequired(timelockConfig, governanceMint)}
|
value={getVotesRequired(timelockConfig, governanceMint)}
|
||||||
/>
|
/>
|
||||||
|
<Space
|
||||||
|
style={{ marginTop: '10px' }}
|
||||||
|
direction={
|
||||||
|
breakpoint.lg || breakpoint.xl || breakpoint.xxl
|
||||||
|
? 'horizontal'
|
||||||
|
: 'vertical'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<MintGovernanceTokens timelockConfig={timelockConfig} />
|
||||||
|
</Space>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row
|
<Row
|
||||||
|
|
Loading…
Reference in New Issue