mirror of https://github.com/certusone/oyster.git
Governance: devnet program api update (#101)
* chore: use single create instruction to create governance * chore: remove yes/no dump accounts * chore: remove single value enums * chore: remove token from proposal account * chore: remove governance program account from createEmptyGovernanceVotingRecord * chore: remove number_of_extra_accounts from Execute * chore: update program id
This commit is contained in:
parent
3a9e3854fc
commit
39b1fa63ef
|
@ -88,7 +88,7 @@ export const PROGRAM_IDS = [
|
||||||
{
|
{
|
||||||
name: 'testnet',
|
name: 'testnet',
|
||||||
governance: () => ({
|
governance: () => ({
|
||||||
programId: new PublicKey('DCVPuhaGNMLh73FRWFroH4o3ERUhBKMRWfBgJV94VqRk'),
|
programId: new PublicKey('A9KW1nhwZUr1kMX8C6rgzZvAE9AwEEUi2C77SiVvEiuN'),
|
||||||
}),
|
}),
|
||||||
wormhole: () => ({
|
wormhole: () => ({
|
||||||
pubkey: new PublicKey('5gQf5AUhAgWYgUCt9ouShm9H7dzzXUsLdssYwe5krKhg'),
|
pubkey: new PublicKey('5gQf5AUhAgWYgUCt9ouShm9H7dzzXUsLdssYwe5krKhg'),
|
||||||
|
@ -103,10 +103,11 @@ export const PROGRAM_IDS = [
|
||||||
legacy: [],
|
legacy: [],
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
name: 'devnet',
|
name: 'devnet',
|
||||||
governance: () => ({
|
governance: () => ({
|
||||||
programId: new PublicKey('DCVPuhaGNMLh73FRWFroH4o3ERUhBKMRWfBgJV94VqRk'),
|
programId: new PublicKey('A9KW1nhwZUr1kMX8C6rgzZvAE9AwEEUi2C77SiVvEiuN'),
|
||||||
}),
|
}),
|
||||||
wormhole: () => ({
|
wormhole: () => ({
|
||||||
pubkey: new PublicKey('WormT3McKhFJ2RkiGpdw9GKvNCrB2aB54gb2uV9MfQC'),
|
pubkey: new PublicKey('WormT3McKhFJ2RkiGpdw9GKvNCrB2aB54gb2uV9MfQC'),
|
||||||
|
|
|
@ -69,8 +69,6 @@ export const createProposal = async (
|
||||||
adminValidationAccount,
|
adminValidationAccount,
|
||||||
adminDestinationAccount,
|
adminDestinationAccount,
|
||||||
sigDestinationAccount,
|
sigDestinationAccount,
|
||||||
yesVoteDumpAccount,
|
|
||||||
noVoteDumpAccount,
|
|
||||||
sourceHoldingAccount,
|
sourceHoldingAccount,
|
||||||
authority,
|
authority,
|
||||||
instructions: associatedInstructions,
|
instructions: associatedInstructions,
|
||||||
|
@ -137,8 +135,6 @@ export const createProposal = async (
|
||||||
voteValidationAccount,
|
voteValidationAccount,
|
||||||
adminDestinationAccount,
|
adminDestinationAccount,
|
||||||
sigDestinationAccount,
|
sigDestinationAccount,
|
||||||
yesVoteDumpAccount,
|
|
||||||
noVoteDumpAccount,
|
|
||||||
sourceHoldingAccount,
|
sourceHoldingAccount,
|
||||||
useGovernance
|
useGovernance
|
||||||
? governance.info.governanceMint
|
? governance.info.governanceMint
|
||||||
|
@ -193,8 +189,6 @@ interface ValidationReturn {
|
||||||
adminValidationAccount: PublicKey;
|
adminValidationAccount: PublicKey;
|
||||||
adminDestinationAccount: PublicKey;
|
adminDestinationAccount: PublicKey;
|
||||||
sigDestinationAccount: PublicKey;
|
sigDestinationAccount: PublicKey;
|
||||||
yesVoteDumpAccount: PublicKey;
|
|
||||||
noVoteDumpAccount: PublicKey;
|
|
||||||
sourceHoldingAccount: PublicKey;
|
sourceHoldingAccount: PublicKey;
|
||||||
authority: PublicKey;
|
authority: PublicKey;
|
||||||
signers: Account[][];
|
signers: Account[][];
|
||||||
|
@ -329,24 +323,6 @@ async function getAssociatedAccountsAndInstructions(
|
||||||
let holdingSigners: Account[] = [];
|
let holdingSigners: Account[] = [];
|
||||||
let holdingInstructions: TransactionInstruction[] = [];
|
let holdingInstructions: TransactionInstruction[] = [];
|
||||||
|
|
||||||
const yesVoteDumpAccount = createTokenAccount(
|
|
||||||
holdingInstructions,
|
|
||||||
wallet.publicKey,
|
|
||||||
accountRentExempt,
|
|
||||||
yesVoteMint,
|
|
||||||
authority,
|
|
||||||
holdingSigners,
|
|
||||||
);
|
|
||||||
|
|
||||||
const noVoteDumpAccount = createTokenAccount(
|
|
||||||
holdingInstructions,
|
|
||||||
wallet.publicKey,
|
|
||||||
accountRentExempt,
|
|
||||||
noVoteMint,
|
|
||||||
authority,
|
|
||||||
holdingSigners,
|
|
||||||
);
|
|
||||||
|
|
||||||
const sourceHoldingAccount = createTokenAccount(
|
const sourceHoldingAccount = createTokenAccount(
|
||||||
holdingInstructions,
|
holdingInstructions,
|
||||||
wallet.publicKey,
|
wallet.publicKey,
|
||||||
|
@ -369,8 +345,6 @@ async function getAssociatedAccountsAndInstructions(
|
||||||
adminValidationAccount,
|
adminValidationAccount,
|
||||||
adminDestinationAccount,
|
adminDestinationAccount,
|
||||||
sigDestinationAccount,
|
sigDestinationAccount,
|
||||||
yesVoteDumpAccount,
|
|
||||||
noVoteDumpAccount,
|
|
||||||
sourceHoldingAccount,
|
sourceHoldingAccount,
|
||||||
authority,
|
authority,
|
||||||
signers: [
|
signers: [
|
||||||
|
|
|
@ -7,16 +7,9 @@ import {
|
||||||
import { contexts, utils, actions, SequenceType } from '@oyster/common';
|
import { contexts, utils, actions, SequenceType } from '@oyster/common';
|
||||||
|
|
||||||
import { AccountLayout, MintLayout, Token } from '@solana/spl-token';
|
import { AccountLayout, MintLayout, Token } from '@solana/spl-token';
|
||||||
import {
|
import { GOVERNANCE_AUTHORITY_SEED, Governance } from '../models/governance';
|
||||||
GOVERNANCE_AUTHORITY_SEED,
|
import { createGovernanceInstruction } from '../models/createGovernance';
|
||||||
ExecutionType,
|
|
||||||
Governance,
|
|
||||||
GovernanceType,
|
|
||||||
VotingEntryRule,
|
|
||||||
} from '../models/governance';
|
|
||||||
import { initGovernanceInstruction } from '../models/initGovernance';
|
|
||||||
import BN from 'bn.js';
|
import BN from 'bn.js';
|
||||||
import { createEmptyGovernanceInstruction } from '../models/createEmptyGovernance';
|
|
||||||
|
|
||||||
const { sendTransactions } = contexts.Connection;
|
const { sendTransactions } = contexts.Connection;
|
||||||
const { createMint, createTokenAccount } = actions;
|
const { createMint, createTokenAccount } = actions;
|
||||||
|
@ -126,29 +119,18 @@ export const registerProgramGovernance = async (
|
||||||
);
|
);
|
||||||
|
|
||||||
instructions.push(
|
instructions.push(
|
||||||
createEmptyGovernanceInstruction(
|
createGovernanceInstruction(
|
||||||
governanceKey,
|
governanceKey,
|
||||||
uninitializedGovernance.program,
|
uninitializedGovernance.program,
|
||||||
programDataAccount,
|
programDataAccount,
|
||||||
wallet.publicKey,
|
wallet.publicKey,
|
||||||
uninitializedGovernance.governanceMint,
|
uninitializedGovernance.governanceMint,
|
||||||
wallet.publicKey,
|
|
||||||
uninitializedGovernance.councilMint,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
instructions.push(
|
|
||||||
initGovernanceInstruction(
|
|
||||||
governanceKey,
|
|
||||||
uninitializedGovernance.program,
|
|
||||||
uninitializedGovernance.governanceMint,
|
|
||||||
|
|
||||||
uninitializedGovernance.voteThreshold!,
|
uninitializedGovernance.voteThreshold!,
|
||||||
uninitializedGovernance.executionType || ExecutionType.Independent,
|
|
||||||
uninitializedGovernance.governanceType || GovernanceType.Governance,
|
|
||||||
uninitializedGovernance.votingEntryRule || VotingEntryRule.Anytime,
|
|
||||||
uninitializedGovernance.minimumSlotWaitingPeriod || new BN(0),
|
uninitializedGovernance.minimumSlotWaitingPeriod || new BN(0),
|
||||||
uninitializedGovernance.timeLimit || new BN(0),
|
uninitializedGovernance.timeLimit || new BN(0),
|
||||||
uninitializedGovernance.name || '',
|
uninitializedGovernance.name || '',
|
||||||
|
wallet.publicKey,
|
||||||
uninitializedGovernance.councilMint,
|
uninitializedGovernance.councilMint,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -136,8 +136,6 @@ export const withdrawVotingTokens = async (
|
||||||
existingNoVoteAccount,
|
existingNoVoteAccount,
|
||||||
destinationAccount,
|
destinationAccount,
|
||||||
proposal.info.sourceHolding,
|
proposal.info.sourceHolding,
|
||||||
proposal.info.yesVotingDump,
|
|
||||||
proposal.info.noVotingDump,
|
|
||||||
proposal.info.votingMint,
|
proposal.info.votingMint,
|
||||||
proposal.info.yesVotingMint,
|
proposal.info.yesVotingMint,
|
||||||
proposal.info.noVotingMint,
|
proposal.info.noVotingMint,
|
||||||
|
|
|
@ -108,10 +108,9 @@ export const LABELS = {
|
||||||
GOVERNANCE_MINT: 'Governance Mint ID',
|
GOVERNANCE_MINT: 'Governance Mint ID',
|
||||||
USE_COUNCIL_MINT: 'Allow Council Mint?',
|
USE_COUNCIL_MINT: 'Allow Council Mint?',
|
||||||
COUNCIL_MINT: 'Council Mint ID',
|
COUNCIL_MINT: 'Council Mint ID',
|
||||||
PROPOSAL_TYPE: 'Proposal Type',
|
|
||||||
EXECUTION_TYPE: 'Execution Type',
|
|
||||||
VOTE_PERCENT_THRESHOLD: 'Vote Threshold (%)',
|
VOTE_PERCENT_THRESHOLD: 'Vote Threshold (%)',
|
||||||
VOTING_ENTRY_RULES: 'Voting Entry Rules',
|
|
||||||
SELECT_PROPOSAL_TYPE: 'Select the type of proposals this app will generate',
|
SELECT_PROPOSAL_TYPE: 'Select the type of proposals this app will generate',
|
||||||
SELECT_EXECUTION_TYPE: 'Select how transactions will be executed',
|
SELECT_EXECUTION_TYPE: 'Select how transactions will be executed',
|
||||||
|
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
import { PublicKey, TransactionInstruction } from '@solana/web3.js';
|
|
||||||
import { utils } from '@oyster/common';
|
|
||||||
import * as BufferLayout from 'buffer-layout';
|
|
||||||
import { GovernanceInstruction } from './governance';
|
|
||||||
|
|
||||||
/// 0. `[]` Governance account. The account pubkey needs to be set to PDA with the following seeds:
|
|
||||||
/// 1) 'governance' const prefix, 2) Governed Program account key
|
|
||||||
/// 1. `[]` Account of the Program governed by this Governance account
|
|
||||||
/// 2. `[writable]` Program Data account of the Program governed by this Governance account
|
|
||||||
/// 3. `[signer]` Current Upgrade Authority account of the Program governed by this Governance account
|
|
||||||
/// 4. `[signer]` Payer
|
|
||||||
/// 5. `[]` System account.
|
|
||||||
/// 6. `[]` bpf_upgrade_loader account.
|
|
||||||
export const createEmptyGovernanceInstruction = (
|
|
||||||
governanceAccount: PublicKey,
|
|
||||||
programAccount: PublicKey,
|
|
||||||
programDataAccount: PublicKey,
|
|
||||||
programUpgradeAuthority: PublicKey,
|
|
||||||
governanceMint: PublicKey,
|
|
||||||
payer: PublicKey,
|
|
||||||
councilMint?: PublicKey,
|
|
||||||
): TransactionInstruction => {
|
|
||||||
const PROGRAM_IDS = utils.programIds();
|
|
||||||
|
|
||||||
const dataLayout = BufferLayout.struct([BufferLayout.u8('instruction')]);
|
|
||||||
|
|
||||||
const data = Buffer.alloc(dataLayout.span);
|
|
||||||
|
|
||||||
dataLayout.encode(
|
|
||||||
{
|
|
||||||
instruction: GovernanceInstruction.CreateEmptyGovernance,
|
|
||||||
},
|
|
||||||
data,
|
|
||||||
);
|
|
||||||
|
|
||||||
const keys = [
|
|
||||||
{ pubkey: governanceAccount, isSigner: false, isWritable: false },
|
|
||||||
{ pubkey: programAccount, isSigner: false, isWritable: false },
|
|
||||||
{ pubkey: programDataAccount, isSigner: false, isWritable: true },
|
|
||||||
{ pubkey: programUpgradeAuthority, isSigner: true, isWritable: false },
|
|
||||||
|
|
||||||
{ pubkey: payer, isSigner: true, isWritable: false },
|
|
||||||
{ pubkey: PROGRAM_IDS.system, isSigner: false, isWritable: false },
|
|
||||||
{
|
|
||||||
pubkey: PROGRAM_IDS.bpf_upgrade_loader,
|
|
||||||
isSigner: false,
|
|
||||||
isWritable: false,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return new TransactionInstruction({
|
|
||||||
keys,
|
|
||||||
programId: PROGRAM_IDS.governance.programId,
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -34,11 +34,7 @@ export const createEmptyGovernanceVotingRecordInstruction = (
|
||||||
{ pubkey: proposalAccount, isSigner: false, isWritable: false },
|
{ pubkey: proposalAccount, isSigner: false, isWritable: false },
|
||||||
{ pubkey: votingAccount, isSigner: false, isWritable: false },
|
{ pubkey: votingAccount, isSigner: false, isWritable: false },
|
||||||
{ pubkey: payer, isSigner: true, isWritable: false },
|
{ pubkey: payer, isSigner: true, isWritable: false },
|
||||||
{
|
|
||||||
pubkey: PROGRAM_IDS.governance.programId,
|
|
||||||
isSigner: false,
|
|
||||||
isWritable: false,
|
|
||||||
},
|
|
||||||
{ pubkey: PROGRAM_IDS.system, isSigner: false, isWritable: false },
|
{ pubkey: PROGRAM_IDS.system, isSigner: false, isWritable: false },
|
||||||
];
|
];
|
||||||
return new TransactionInstruction({
|
return new TransactionInstruction({
|
||||||
|
|
|
@ -1,47 +1,49 @@
|
||||||
import { PublicKey, TransactionInstruction } from '@solana/web3.js';
|
import { PublicKey, TransactionInstruction } from '@solana/web3.js';
|
||||||
import { utils } from '@oyster/common';
|
import { utils } from '@oyster/common';
|
||||||
import * as BufferLayout from 'buffer-layout';
|
import * as BufferLayout from 'buffer-layout';
|
||||||
import { CONFIG_NAME_LENGTH, GovernanceInstruction } from './governance';
|
import { GOVERNANCE_NAME_LENGTH, GovernanceInstruction } from './governance';
|
||||||
import BN from 'bn.js';
|
import BN from 'bn.js';
|
||||||
import * as Layout from '../utils/layout';
|
import * as Layout from '../utils/layout';
|
||||||
|
|
||||||
/// 0. `[writable]` Governance account. The account pubkey needs to be set to PDA with the following seeds:
|
/// 0. `[writable]` Governance account. The account pubkey needs to be set to PDA with the following seeds:
|
||||||
/// 1) 'governance' const prefix, 2) Governed Program account key
|
/// 1) 'governance' const prefix, 2) Governed Program account key
|
||||||
/// 1. `[]` Account of the Program governed by this Governance account
|
/// 1. `[]` Account of the Program governed by this Governance account
|
||||||
/// 2. `[]` Governance mint that this Governance uses
|
/// 2. `[writable]` Program Data account of the Program governed by this Governance account
|
||||||
/// 3. `[]` Council mint that this Governance uses [Optional]
|
/// 3. `[signer]` Current Upgrade Authority account of the Program governed by this Governance account
|
||||||
export const initGovernanceInstruction = (
|
/// 4. `[]` Governance mint that this Governance uses
|
||||||
|
/// 5. `[signer]` Payer
|
||||||
|
/// 6. `[]` System account.
|
||||||
|
/// 7. `[]` bpf_upgrade_loader account.
|
||||||
|
/// 8. `[]` Council mint that this Governance uses [Optional]
|
||||||
|
export const createGovernanceInstruction = (
|
||||||
governanceAccount: PublicKey,
|
governanceAccount: PublicKey,
|
||||||
programAccount: PublicKey,
|
governedProgramAccount: PublicKey,
|
||||||
|
governedProgramDataAccount: PublicKey,
|
||||||
|
governedProgramUpgradeAuthority: PublicKey,
|
||||||
governanceMint: PublicKey,
|
governanceMint: PublicKey,
|
||||||
voteThreshold: number,
|
voteThreshold: number,
|
||||||
executionType: number,
|
|
||||||
governanceType: number,
|
|
||||||
votingEntryRule: number,
|
|
||||||
minimumSlotWaitingPeriod: BN,
|
minimumSlotWaitingPeriod: BN,
|
||||||
timeLimit: BN,
|
timeLimit: BN,
|
||||||
name: string,
|
name: string,
|
||||||
|
payer: PublicKey,
|
||||||
councilMint?: PublicKey,
|
councilMint?: PublicKey,
|
||||||
): TransactionInstruction => {
|
): TransactionInstruction => {
|
||||||
const PROGRAM_IDS = utils.programIds();
|
const PROGRAM_IDS = utils.programIds();
|
||||||
|
|
||||||
if (name.length > CONFIG_NAME_LENGTH) {
|
if (name.length > GOVERNANCE_NAME_LENGTH) {
|
||||||
throw new Error('Name is more than ' + CONFIG_NAME_LENGTH);
|
throw new Error('Name is more than ' + GOVERNANCE_NAME_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
const dataLayout = BufferLayout.struct([
|
const dataLayout = BufferLayout.struct([
|
||||||
BufferLayout.u8('instruction'),
|
BufferLayout.u8('instruction'),
|
||||||
BufferLayout.u8('voteThreshold'),
|
BufferLayout.u8('voteThreshold'),
|
||||||
BufferLayout.u8('executionType'),
|
|
||||||
BufferLayout.u8('governanceType'),
|
|
||||||
BufferLayout.u8('votingEntryRule'),
|
|
||||||
Layout.uint64('minimumSlotWaitingPeriod'),
|
Layout.uint64('minimumSlotWaitingPeriod'),
|
||||||
Layout.uint64('timeLimit'),
|
Layout.uint64('timeLimit'),
|
||||||
BufferLayout.seq(BufferLayout.u8(), CONFIG_NAME_LENGTH, 'name'),
|
BufferLayout.seq(BufferLayout.u8(), GOVERNANCE_NAME_LENGTH, 'name'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const nameAsBytes = utils.toUTF8Array(name);
|
const nameAsBytes = utils.toUTF8Array(name);
|
||||||
for (let i = nameAsBytes.length; i <= CONFIG_NAME_LENGTH - 1; i++) {
|
for (let i = nameAsBytes.length; i <= GOVERNANCE_NAME_LENGTH - 1; i++) {
|
||||||
nameAsBytes.push(0);
|
nameAsBytes.push(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,11 +51,8 @@ export const initGovernanceInstruction = (
|
||||||
|
|
||||||
dataLayout.encode(
|
dataLayout.encode(
|
||||||
{
|
{
|
||||||
instruction: GovernanceInstruction.InitGovernance,
|
instruction: GovernanceInstruction.CreateGovernance,
|
||||||
voteThreshold,
|
voteThreshold,
|
||||||
executionType,
|
|
||||||
governanceType,
|
|
||||||
votingEntryRule,
|
|
||||||
minimumSlotWaitingPeriod,
|
minimumSlotWaitingPeriod,
|
||||||
timeLimit,
|
timeLimit,
|
||||||
name: nameAsBytes,
|
name: nameAsBytes,
|
||||||
|
@ -63,8 +62,21 @@ export const initGovernanceInstruction = (
|
||||||
|
|
||||||
const keys = [
|
const keys = [
|
||||||
{ pubkey: governanceAccount, isSigner: false, isWritable: true },
|
{ pubkey: governanceAccount, isSigner: false, isWritable: true },
|
||||||
{ pubkey: programAccount, isSigner: false, isWritable: false },
|
{ pubkey: governedProgramAccount, isSigner: false, isWritable: false },
|
||||||
|
{ pubkey: governedProgramDataAccount, isSigner: false, isWritable: true },
|
||||||
|
{
|
||||||
|
pubkey: governedProgramUpgradeAuthority,
|
||||||
|
isSigner: true,
|
||||||
|
isWritable: false,
|
||||||
|
},
|
||||||
{ pubkey: governanceMint, isSigner: false, isWritable: false },
|
{ pubkey: governanceMint, isSigner: false, isWritable: false },
|
||||||
|
{ pubkey: payer, isSigner: true, isWritable: false },
|
||||||
|
{ pubkey: PROGRAM_IDS.system, isSigner: false, isWritable: false },
|
||||||
|
{
|
||||||
|
pubkey: PROGRAM_IDS.bpf_upgrade_loader,
|
||||||
|
isSigner: false,
|
||||||
|
isWritable: false,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
if (councilMint) {
|
if (councilMint) {
|
|
@ -27,17 +27,15 @@ export const executeInstruction = (
|
||||||
): TransactionInstruction => {
|
): TransactionInstruction => {
|
||||||
const PROGRAM_IDS = utils.programIds();
|
const PROGRAM_IDS = utils.programIds();
|
||||||
|
|
||||||
const dataLayout = BufferLayout.struct([
|
const dataLayout = BufferLayout.struct([BufferLayout.u8('instruction')]);
|
||||||
BufferLayout.u8('instruction'),
|
|
||||||
BufferLayout.u8('numberOfExtraAccounts'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const data = Buffer.alloc(dataLayout.span);
|
const data = Buffer.alloc(dataLayout.span);
|
||||||
|
|
||||||
|
console.log('ACCTS', accountInfos);
|
||||||
|
|
||||||
dataLayout.encode(
|
dataLayout.encode(
|
||||||
{
|
{
|
||||||
instruction: GovernanceInstruction.Execute,
|
instruction: GovernanceInstruction.Execute,
|
||||||
numberOfExtraAccounts: accountInfos.length,
|
|
||||||
},
|
},
|
||||||
data,
|
data,
|
||||||
);
|
);
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { utils } from '@oyster/common';
|
||||||
|
|
||||||
export const DESC_SIZE = 200;
|
export const DESC_SIZE = 200;
|
||||||
export const NAME_SIZE = 32;
|
export const NAME_SIZE = 32;
|
||||||
export const CONFIG_NAME_LENGTH = 32;
|
export const GOVERNANCE_NAME_LENGTH = 32;
|
||||||
export const INSTRUCTION_LIMIT = 450;
|
export const INSTRUCTION_LIMIT = 450;
|
||||||
export const MAX_TRANSACTIONS = 5;
|
export const MAX_TRANSACTIONS = 5;
|
||||||
export const TEMP_FILE_TXN_SIZE = 1000;
|
export const TEMP_FILE_TXN_SIZE = 1000;
|
||||||
|
@ -21,13 +21,12 @@ export enum GovernanceInstruction {
|
||||||
AddCustomSingleSignerTransaction = 4,
|
AddCustomSingleSignerTransaction = 4,
|
||||||
Sign = 8,
|
Sign = 8,
|
||||||
Vote = 9,
|
Vote = 9,
|
||||||
InitGovernance = 10,
|
CreateGovernance = 10,
|
||||||
|
|
||||||
Execute = 11,
|
Execute = 11,
|
||||||
DepositGovernanceTokens = 12,
|
DepositGovernanceTokens = 12,
|
||||||
WithdrawVotingTokens = 13,
|
WithdrawVotingTokens = 13,
|
||||||
CreateEmptyGovernance = 14,
|
CreateGovernanceVotingRecord = 14,
|
||||||
CreateGovernanceVotingRecord = 15,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GovernanceVotingRecord {
|
export interface GovernanceVotingRecord {
|
||||||
|
@ -63,12 +62,7 @@ export interface Governance {
|
||||||
accountType: GovernanceAccountType;
|
accountType: GovernanceAccountType;
|
||||||
/// Vote threshold
|
/// Vote threshold
|
||||||
voteThreshold: number;
|
voteThreshold: number;
|
||||||
/// Execution type
|
|
||||||
executionType: ExecutionType;
|
|
||||||
/// Governance Type
|
|
||||||
governanceType: GovernanceType;
|
|
||||||
/// Voting entry rule
|
|
||||||
votingEntryRule: VotingEntryRule;
|
|
||||||
/// Minimum slot time-distance from creation of proposal for an instruction to be placed
|
/// Minimum slot time-distance from creation of proposal for an instruction to be placed
|
||||||
minimumSlotWaitingPeriod: BN;
|
minimumSlotWaitingPeriod: BN;
|
||||||
/// Governance mint
|
/// Governance mint
|
||||||
|
@ -98,33 +92,18 @@ export const GovernanceLayout: typeof BufferLayout.Structure = BufferLayout.stru
|
||||||
[
|
[
|
||||||
BufferLayout.u8('accountType'),
|
BufferLayout.u8('accountType'),
|
||||||
BufferLayout.u8('voteThreshold'),
|
BufferLayout.u8('voteThreshold'),
|
||||||
BufferLayout.u8('executionType'),
|
|
||||||
BufferLayout.u8('governanceType'),
|
|
||||||
BufferLayout.u8('votingEntryRule'),
|
|
||||||
Layout.uint64('minimumSlotWaitingPeriod'),
|
Layout.uint64('minimumSlotWaitingPeriod'),
|
||||||
Layout.publicKey('governanceMint'),
|
Layout.publicKey('governanceMint'),
|
||||||
BufferLayout.u8('councilMintOption'),
|
BufferLayout.u8('councilMintOption'),
|
||||||
Layout.publicKey('councilMint'),
|
Layout.publicKey('councilMint'),
|
||||||
Layout.publicKey('program'),
|
Layout.publicKey('program'),
|
||||||
Layout.uint64('timeLimit'),
|
Layout.uint64('timeLimit'),
|
||||||
BufferLayout.seq(BufferLayout.u8(), CONFIG_NAME_LENGTH, 'name'),
|
BufferLayout.seq(BufferLayout.u8(), GOVERNANCE_NAME_LENGTH, 'name'),
|
||||||
BufferLayout.u32('count'),
|
BufferLayout.u32('count'),
|
||||||
BufferLayout.seq(BufferLayout.u8(), 295, 'padding'),
|
BufferLayout.seq(BufferLayout.u8(), 295, 'padding'),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
export enum VotingEntryRule {
|
|
||||||
Anytime = 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum ExecutionType {
|
|
||||||
Independent = 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum GovernanceType {
|
|
||||||
Governance = 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum ProposalStateStatus {
|
export enum ProposalStateStatus {
|
||||||
/// Draft
|
/// Draft
|
||||||
Draft = 0,
|
Draft = 0,
|
||||||
|
@ -180,7 +159,6 @@ export const ProposalLayout: typeof BufferLayout.Structure = BufferLayout.struct
|
||||||
[
|
[
|
||||||
BufferLayout.u8('accountType'),
|
BufferLayout.u8('accountType'),
|
||||||
Layout.publicKey('config'),
|
Layout.publicKey('config'),
|
||||||
Layout.publicKey('tokenProgramId'),
|
|
||||||
Layout.publicKey('state'),
|
Layout.publicKey('state'),
|
||||||
Layout.publicKey('signatoryMint'),
|
Layout.publicKey('signatoryMint'),
|
||||||
Layout.publicKey('adminMint'),
|
Layout.publicKey('adminMint'),
|
||||||
|
@ -192,8 +170,7 @@ export const ProposalLayout: typeof BufferLayout.Structure = BufferLayout.struct
|
||||||
Layout.publicKey('adminValidation'),
|
Layout.publicKey('adminValidation'),
|
||||||
Layout.publicKey('votingValidation'),
|
Layout.publicKey('votingValidation'),
|
||||||
Layout.publicKey('sourceHolding'),
|
Layout.publicKey('sourceHolding'),
|
||||||
Layout.publicKey('yesVotingDump'),
|
|
||||||
Layout.publicKey('noVotingDump'),
|
|
||||||
BufferLayout.seq(BufferLayout.u8(), 300, 'padding'),
|
BufferLayout.seq(BufferLayout.u8(), 300, 'padding'),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
@ -225,9 +202,6 @@ export interface Proposal {
|
||||||
/// configuration values
|
/// configuration values
|
||||||
config: PublicKey;
|
config: PublicKey;
|
||||||
|
|
||||||
/// Token Program ID
|
|
||||||
tokenProgramId: PublicKey;
|
|
||||||
|
|
||||||
/// state values
|
/// state values
|
||||||
state: PublicKey;
|
state: PublicKey;
|
||||||
|
|
||||||
|
@ -262,12 +236,6 @@ export interface Proposal {
|
||||||
|
|
||||||
/// Governance holding account
|
/// Governance holding account
|
||||||
sourceHolding: PublicKey;
|
sourceHolding: PublicKey;
|
||||||
|
|
||||||
/// Yes Voting dump account for exchanged vote tokens
|
|
||||||
yesVotingDump: PublicKey;
|
|
||||||
|
|
||||||
/// No Voting dump account for exchanged vote tokens
|
|
||||||
noVotingDump: PublicKey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CustomSingleSignerTransactionLayout: typeof BufferLayout.Structure = BufferLayout.struct(
|
export const CustomSingleSignerTransactionLayout: typeof BufferLayout.Structure = BufferLayout.struct(
|
||||||
|
@ -309,7 +277,6 @@ export const ProposalParser = (
|
||||||
info: {
|
info: {
|
||||||
accountType: data.accountType,
|
accountType: data.accountType,
|
||||||
config: data.config,
|
config: data.config,
|
||||||
tokenProgramId: data.tokenProgramId,
|
|
||||||
state: data.state,
|
state: data.state,
|
||||||
signatoryMint: data.signatoryMint,
|
signatoryMint: data.signatoryMint,
|
||||||
adminMint: data.adminMint,
|
adminMint: data.adminMint,
|
||||||
|
@ -321,8 +288,6 @@ export const ProposalParser = (
|
||||||
adminValidation: data.adminValidation,
|
adminValidation: data.adminValidation,
|
||||||
votingValidation: data.votingValidation,
|
votingValidation: data.votingValidation,
|
||||||
sourceHolding: data.sourceHolding,
|
sourceHolding: data.sourceHolding,
|
||||||
yesVotingDump: data.yesVotingDump,
|
|
||||||
noVotingDump: data.noVotingDump,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -431,9 +396,7 @@ export const GovernanceParser = (
|
||||||
info: {
|
info: {
|
||||||
accountType: data.accountType,
|
accountType: data.accountType,
|
||||||
voteThreshold: data.voteThreshold,
|
voteThreshold: data.voteThreshold,
|
||||||
executionType: data.executionType,
|
|
||||||
governanceType: data.governanceType,
|
|
||||||
votingEntryRule: data.votingEntryRule,
|
|
||||||
minimumSlotWaitingPeriod: data.minimumSlotWaitingPeriod,
|
minimumSlotWaitingPeriod: data.minimumSlotWaitingPeriod,
|
||||||
governanceMint: data.governanceMint,
|
governanceMint: data.governanceMint,
|
||||||
councilMint: data.councilMintOption === 1 ? data.councilMint : null,
|
councilMint: data.councilMintOption === 1 ? data.councilMint : null,
|
||||||
|
|
|
@ -23,8 +23,6 @@ import { DESC_SIZE, NAME_SIZE, GovernanceInstruction } from './governance';
|
||||||
/// 10. `[writable]` Initialized Voting Validation account
|
/// 10. `[writable]` Initialized Voting Validation account
|
||||||
/// 11. `[writable]` Initialized Destination account for first admin token
|
/// 11. `[writable]` Initialized Destination account for first admin token
|
||||||
/// 12. `[writable]` Initialized Destination account for first signatory token
|
/// 12. `[writable]` Initialized Destination account for first signatory token
|
||||||
/// 13. `[writable]` Initialized Yes voting dump account
|
|
||||||
/// 14. `[writable]` Initialized No voting dump account
|
|
||||||
/// 15. `[writable]` Initialized source holding account
|
/// 15. `[writable]` Initialized source holding account
|
||||||
/// 16. `[]` Source mint
|
/// 16. `[]` Source mint
|
||||||
/// 17. `[]` Governance minting authority (pda with seed of Proposal key)
|
/// 17. `[]` Governance minting authority (pda with seed of Proposal key)
|
||||||
|
@ -44,8 +42,6 @@ export const initProposalInstruction = (
|
||||||
votingValidationAccount: PublicKey,
|
votingValidationAccount: PublicKey,
|
||||||
destinationAdminAccount: PublicKey,
|
destinationAdminAccount: PublicKey,
|
||||||
destinationSignatoryAccount: PublicKey,
|
destinationSignatoryAccount: PublicKey,
|
||||||
yesVotingDumpAccount: PublicKey,
|
|
||||||
noVotingDumpAccount: PublicKey,
|
|
||||||
sourceHoldingAccount: PublicKey,
|
sourceHoldingAccount: PublicKey,
|
||||||
sourceMintAccount: PublicKey,
|
sourceMintAccount: PublicKey,
|
||||||
authority: PublicKey,
|
authority: PublicKey,
|
||||||
|
@ -101,8 +97,6 @@ export const initProposalInstruction = (
|
||||||
{ pubkey: votingValidationAccount, isSigner: false, isWritable: true },
|
{ pubkey: votingValidationAccount, isSigner: false, isWritable: true },
|
||||||
{ pubkey: destinationAdminAccount, isSigner: false, isWritable: true },
|
{ pubkey: destinationAdminAccount, isSigner: false, isWritable: true },
|
||||||
{ pubkey: destinationSignatoryAccount, isSigner: false, isWritable: true },
|
{ pubkey: destinationSignatoryAccount, isSigner: false, isWritable: true },
|
||||||
{ pubkey: yesVotingDumpAccount, isSigner: false, isWritable: true },
|
|
||||||
{ pubkey: noVotingDumpAccount, isSigner: false, isWritable: true },
|
|
||||||
{ pubkey: sourceHoldingAccount, isSigner: false, isWritable: true },
|
{ pubkey: sourceHoldingAccount, isSigner: false, isWritable: true },
|
||||||
{
|
{
|
||||||
pubkey: sourceMintAccount,
|
pubkey: sourceMintAccount,
|
||||||
|
|
|
@ -15,8 +15,6 @@ import BN from 'bn.js';
|
||||||
/// 3. `[writable]` Initialized No Voting account from which to remove your voting tokens.
|
/// 3. `[writable]` Initialized No Voting account from which to remove your voting tokens.
|
||||||
/// 4. `[writable]` User token account that you wish your actual tokens to be returned to.
|
/// 4. `[writable]` User token account that you wish your actual tokens to be returned to.
|
||||||
/// 5. `[writable]` Source holding account owned by the Governance that will has the actual tokens in escrow.
|
/// 5. `[writable]` Source holding account owned by the Governance that will has the actual tokens in escrow.
|
||||||
/// 6. `[writable]` Initialized Yes Voting dump account owned by Proposal to which to send your voting tokens.
|
|
||||||
/// 7. `[writable]` Initialized No Voting dump account owned by Proposal to which to send your voting tokens.
|
|
||||||
/// 8. `[writable]` Voting mint account.
|
/// 8. `[writable]` Voting mint account.
|
||||||
/// 9. `[writable]` Yes Voting mint account.
|
/// 9. `[writable]` Yes Voting mint account.
|
||||||
/// 10. `[writable]` No Voting mint account.
|
/// 10. `[writable]` No Voting mint account.
|
||||||
|
@ -32,8 +30,6 @@ export const withdrawVotingTokensInstruction = (
|
||||||
noVotingAccount: PublicKey,
|
noVotingAccount: PublicKey,
|
||||||
destinationAccount: PublicKey,
|
destinationAccount: PublicKey,
|
||||||
sourceHoldingAccount: PublicKey,
|
sourceHoldingAccount: PublicKey,
|
||||||
yesVotingDump: PublicKey,
|
|
||||||
noVotingDump: PublicKey,
|
|
||||||
votingMint: PublicKey,
|
votingMint: PublicKey,
|
||||||
yesVotingMint: PublicKey,
|
yesVotingMint: PublicKey,
|
||||||
noVotingMint: PublicKey,
|
noVotingMint: PublicKey,
|
||||||
|
@ -67,8 +63,6 @@ export const withdrawVotingTokensInstruction = (
|
||||||
{ pubkey: noVotingAccount, isSigner: false, isWritable: true },
|
{ pubkey: noVotingAccount, isSigner: false, isWritable: true },
|
||||||
{ pubkey: destinationAccount, isSigner: false, isWritable: true },
|
{ pubkey: destinationAccount, isSigner: false, isWritable: true },
|
||||||
{ pubkey: sourceHoldingAccount, isSigner: false, isWritable: true },
|
{ pubkey: sourceHoldingAccount, isSigner: false, isWritable: true },
|
||||||
{ pubkey: yesVotingDump, isSigner: false, isWritable: true },
|
|
||||||
{ pubkey: noVotingDump, isSigner: false, isWritable: true },
|
|
||||||
{ pubkey: votingMint, isSigner: false, isWritable: true },
|
{ pubkey: votingMint, isSigner: false, isWritable: true },
|
||||||
{ pubkey: yesVotingMint, isSigner: false, isWritable: true },
|
{ pubkey: yesVotingMint, isSigner: false, isWritable: true },
|
||||||
{ pubkey: noVotingMint, isSigner: false, isWritable: true },
|
{ pubkey: noVotingMint, isSigner: false, isWritable: true },
|
||||||
|
|
|
@ -9,12 +9,7 @@ import {
|
||||||
deserializeMint,
|
deserializeMint,
|
||||||
ParsedAccount,
|
ParsedAccount,
|
||||||
} from '@oyster/common';
|
} from '@oyster/common';
|
||||||
import {
|
import { Governance } from '../../models/governance';
|
||||||
ExecutionType,
|
|
||||||
Governance,
|
|
||||||
GovernanceType,
|
|
||||||
VotingEntryRule,
|
|
||||||
} from '../../models/governance';
|
|
||||||
import { PublicKey } from '@solana/web3.js';
|
import { PublicKey } from '@solana/web3.js';
|
||||||
import { Table } from 'antd';
|
import { Table } from 'antd';
|
||||||
import MintSourceTokens from '../../components/Proposal/MintSourceTokens';
|
import MintSourceTokens from '../../components/Proposal/MintSourceTokens';
|
||||||
|
@ -32,24 +27,7 @@ const columns = [
|
||||||
key: 'voteThreshold',
|
key: 'voteThreshold',
|
||||||
render: (number: number) => <span>{number}</span>,
|
render: (number: number) => <span>{number}</span>,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: LABELS.EXECUTION_TYPE,
|
|
||||||
dataIndex: 'executionType',
|
|
||||||
key: 'executionType',
|
|
||||||
render: (number: number) => <span>{ExecutionType[number]}</span>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: LABELS.PROPOSAL_TYPE,
|
|
||||||
dataIndex: 'governanceType',
|
|
||||||
key: 'governanceType',
|
|
||||||
render: (number: number) => <span>{GovernanceType[number]}</span>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: LABELS.VOTING_ENTRY_RULES,
|
|
||||||
dataIndex: 'votingEntryRule',
|
|
||||||
key: 'votingEntryRule',
|
|
||||||
render: (number: number) => <span>{VotingEntryRule[number]}</span>,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: LABELS.MINIMUM_SLOT_WAITING_PERIOD,
|
title: LABELS.MINIMUM_SLOT_WAITING_PERIOD,
|
||||||
dataIndex: 'minimumSlotWaitingPeriod',
|
dataIndex: 'minimumSlotWaitingPeriod',
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { Button, ButtonProps, InputNumber, Modal, Switch } from 'antd';
|
import { Button, ButtonProps, InputNumber, Modal, Switch } from 'antd';
|
||||||
import { Form, Input, Select } from 'antd';
|
import { Form, Input } from 'antd';
|
||||||
import { PublicKey } from '@solana/web3.js';
|
import { PublicKey } from '@solana/web3.js';
|
||||||
import {
|
import { GOVERNANCE_NAME_LENGTH } from '../../models/governance';
|
||||||
CONFIG_NAME_LENGTH,
|
|
||||||
ExecutionType,
|
|
||||||
GovernanceType,
|
|
||||||
VotingEntryRule,
|
|
||||||
} from '../../models/governance';
|
|
||||||
import { LABELS } from '../../constants';
|
import { LABELS } from '../../constants';
|
||||||
import { contexts, utils, tryParseKey } from '@oyster/common';
|
import { contexts, utils, tryParseKey } from '@oyster/common';
|
||||||
import { registerProgramGovernance } from '../../actions/registerProgramGovernance';
|
import { registerProgramGovernance } from '../../actions/registerProgramGovernance';
|
||||||
|
@ -16,7 +11,6 @@ import BN from 'bn.js';
|
||||||
|
|
||||||
const { useWallet } = contexts.Wallet;
|
const { useWallet } = contexts.Wallet;
|
||||||
const { useConnection } = contexts.Connection;
|
const { useConnection } = contexts.Connection;
|
||||||
const { Option } = Select;
|
|
||||||
const { notify } = utils;
|
const { notify } = utils;
|
||||||
|
|
||||||
const layout = {
|
const layout = {
|
||||||
|
@ -68,10 +62,8 @@ export function NewForm({
|
||||||
const wallet = useWallet();
|
const wallet = useWallet();
|
||||||
const connection = useConnection();
|
const connection = useConnection();
|
||||||
const onFinish = async (values: {
|
const onFinish = async (values: {
|
||||||
governanceType: GovernanceType;
|
|
||||||
executionType: ExecutionType;
|
|
||||||
voteThreshold: number;
|
voteThreshold: number;
|
||||||
votingEntryRule: VotingEntryRule;
|
|
||||||
minimumSlotWaitingPeriod: string;
|
minimumSlotWaitingPeriod: string;
|
||||||
timeLimit: string;
|
timeLimit: string;
|
||||||
governanceMint: string;
|
governanceMint: string;
|
||||||
|
@ -120,10 +112,8 @@ export function NewForm({
|
||||||
}
|
}
|
||||||
|
|
||||||
const uninitializedGovernance = {
|
const uninitializedGovernance = {
|
||||||
governanceType: values.governanceType,
|
|
||||||
executionType: values.executionType,
|
|
||||||
voteThreshold: values.voteThreshold,
|
voteThreshold: values.voteThreshold,
|
||||||
votingEntryRule: values.votingEntryRule,
|
|
||||||
minimumSlotWaitingPeriod: new BN(values.minimumSlotWaitingPeriod),
|
minimumSlotWaitingPeriod: new BN(values.minimumSlotWaitingPeriod),
|
||||||
governanceMint: values.governanceMint
|
governanceMint: values.governanceMint
|
||||||
? new PublicKey(values.governanceMint)
|
? new PublicKey(values.governanceMint)
|
||||||
|
@ -154,7 +144,7 @@ export function NewForm({
|
||||||
>
|
>
|
||||||
<Form {...layout} form={form} name="control-hooks" onFinish={onFinish}>
|
<Form {...layout} form={form} name="control-hooks" onFinish={onFinish}>
|
||||||
<Form.Item name="name" label="Name" rules={[{ required: true }]}>
|
<Form.Item name="name" label="Name" rules={[{ required: true }]}>
|
||||||
<Input maxLength={CONFIG_NAME_LENGTH} />
|
<Input maxLength={GOVERNANCE_NAME_LENGTH} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="program"
|
name="program"
|
||||||
|
@ -204,36 +194,6 @@ export function NewForm({
|
||||||
>
|
>
|
||||||
<InputNumber maxLength={3} min={1} max={100} />
|
<InputNumber maxLength={3} min={1} max={100} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
|
||||||
name="executionType"
|
|
||||||
label={LABELS.EXECUTION_TYPE}
|
|
||||||
rules={[{ required: true }]}
|
|
||||||
initialValue={ExecutionType.Independent}
|
|
||||||
>
|
|
||||||
<Select placeholder={LABELS.SELECT_EXECUTION_TYPE}>
|
|
||||||
<Option value={ExecutionType.Independent}>Independent</Option>
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
|
||||||
name="governanceType"
|
|
||||||
label={LABELS.PROPOSAL_TYPE}
|
|
||||||
rules={[{ required: true }]}
|
|
||||||
initialValue={GovernanceType.Governance}
|
|
||||||
>
|
|
||||||
<Select placeholder={LABELS.SELECT_PROPOSAL_TYPE}>
|
|
||||||
<Option value={GovernanceType.Governance}>Single Signer</Option>
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
|
||||||
name="votingEntryRule"
|
|
||||||
label={LABELS.VOTING_ENTRY_RULES}
|
|
||||||
rules={[{ required: true }]}
|
|
||||||
initialValue={VotingEntryRule.Anytime}
|
|
||||||
>
|
|
||||||
<Select placeholder={LABELS.SELECT_VOTING_ENTRY_RULE}>
|
|
||||||
<Option value={VotingEntryRule.Anytime}>At any time</Option>
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue