diff --git a/packages/bridge/src/components/AppBar/index.less b/packages/bridge/src/components/AppBar/index.less index 0d8ac1c..951e1fe 100644 --- a/packages/bridge/src/components/AppBar/index.less +++ b/packages/bridge/src/components/AppBar/index.less @@ -6,7 +6,7 @@ header.ant-layout-header.App-Bar { width: 100%; background: transparent; display: flex; - justify-content: center; + justify-content: center !important; height: 80px; .nav-burger { @@ -30,6 +30,9 @@ header.ant-layout-header.App-Bar { justify-content: center; height: auto; align-items: center; + button.app-bar-item { + padding: 0; + } .app-bar-item { cursor: pointer; padding: 0 30px; diff --git a/packages/bridge/src/components/CurrentUserWalletBadge/index.tsx b/packages/bridge/src/components/CurrentUserWalletBadge/index.tsx new file mode 100644 index 0000000..be4358b --- /dev/null +++ b/packages/bridge/src/components/CurrentUserWalletBadge/index.tsx @@ -0,0 +1,32 @@ +import React from 'react'; + +import { useWallet, WALLET_PROVIDERS } from '@oyster/common'; +import { shortenAddress } from '@oyster/common'; + +export const CurrentUserWalletBadge = (props: { showDisconnect?: boolean }) => { + const { wallet, disconnect } = useWallet(); + + if (!wallet || !wallet.publicKey) { + return null; + } + + return ( +
+
+ {'icon'} p.name === 'Sollet')[0]?.icon} + style={{ marginRight: 8 }} + /> + {shortenAddress(`${wallet.publicKey}`)} + {props.showDisconnect && ( + disconnect()}> + X + + )} +
+
+ ); +}; diff --git a/packages/bridge/src/components/Input/input.tsx b/packages/bridge/src/components/Input/input.tsx index 77bb624..705be75 100644 --- a/packages/bridge/src/components/Input/input.tsx +++ b/packages/bridge/src/components/Input/input.tsx @@ -13,6 +13,7 @@ import { TokenSelectModal } from '../TokenSelectModal'; import { chainToName } from '../../utils/assets'; import { TokenChain } from '../TokenDisplay/tokenChain'; import { EthereumConnect } from '../EthereumConnect'; +import { CurrentUserWalletBadge } from '../CurrentUserWalletBadge'; export function Input(props: { title: string; @@ -106,7 +107,10 @@ export function Input(props: { {props.chain === ASSET_CHAIN.Ethereum ? ( - ) : ( + ) : connected ? ( + + ) : ( + )} ); diff --git a/packages/bridge/src/components/RecentTransactionsTable/index.tsx b/packages/bridge/src/components/RecentTransactionsTable/index.tsx index 20ad0f1..f4067b1 100644 --- a/packages/bridge/src/components/RecentTransactionsTable/index.tsx +++ b/packages/bridge/src/components/RecentTransactionsTable/index.tsx @@ -145,7 +145,11 @@ export const RecentTransactionsTable = () => { render(text: string, record: any) { return { props: { style: {} }, - children: {record.status}, + children: ( + + {record.status} + + ), }; }, }, diff --git a/packages/bridge/src/hooks/useWormholeTransactions.tsx b/packages/bridge/src/hooks/useWormholeTransactions.tsx index 77cadb9..065639a 100644 --- a/packages/bridge/src/hooks/useWormholeTransactions.tsx +++ b/packages/bridge/src/hooks/useWormholeTransactions.tsx @@ -65,10 +65,7 @@ const queryWrappedMetaTransactions = async ( }, ]; - let wh = WormholeFactory.connect( - programIds().wormhole.bridge, - provider, - ); + let wh = WormholeFactory.connect(programIds().wormhole.bridge, provider); const resp = await (connection as any)._rpcRequest('getProgramAccounts', [ WORMHOLE_PROGRAM_ID.toBase58(), { @@ -227,7 +224,6 @@ export const useWormholeTransactions = () => { bridge, ).then(() => setLoading(false)); })(); - }, [connection, setTransfers]); const coingeckoTimer = useRef(0); diff --git a/packages/bridge/src/views/home/index.tsx b/packages/bridge/src/views/home/index.tsx index 4f544c0..175fb0c 100644 --- a/packages/bridge/src/views/home/index.tsx +++ b/packages/bridge/src/views/home/index.tsx @@ -158,9 +158,7 @@ export const HomeView = () => {
Bridge in any direction
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis - nisi at praesent sed sollicitudin ullamcorper malesuada in. - Molestie sed morbi vitae in amet ultrices. +
@@ -169,9 +167,7 @@ export const HomeView = () => {
Staking & Validation
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis - nisi at praesent sed sollicitudin ullamcorper malesuada in. - Molestie sed morbi vitae in amet ultrices. +
@@ -180,9 +176,7 @@ export const HomeView = () => {
Layers and Capabilities
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis - nisi at praesent sed sollicitudin ullamcorper malesuada in. - Molestie sed morbi vitae in amet ultrices. +
diff --git a/packages/common/src/models/account.ts b/packages/common/src/models/account.ts index 6570c81..df0473c 100644 --- a/packages/common/src/models/account.ts +++ b/packages/common/src/models/account.ts @@ -65,27 +65,17 @@ export function approve( const transferAuthority = existingTransferAuthority || new Account(); const delegateKey = delegate ?? transferAuthority.publicKey; - const instruction = Token.createApproveInstruction( - tokenProgram, - account, - delegateKey, - owner, - [], - amount, + instructions.push( + Token.createApproveInstruction( + tokenProgram, + account, + delegate ?? transferAuthority.publicKey, + owner, + [], + amount, + ), ); - // Temp. workaround for a bug in Token.createApproveInstruction which doesn't add the delegate account to signers - instruction.keys = instruction.keys.map(k => - k.pubkey.equals(delegateKey) - ? { - ...k, - isSigner: true, - } - : k, - ); - - instructions.push(instruction); - if (autoRevoke) { cleanupInstructions.push( Token.createRevokeInstruction(tokenProgram, account, owner, []), diff --git a/packages/proposals/src/actions/addCustomSingleSignerTransaction.ts b/packages/proposals/src/actions/addCustomSingleSignerTransaction.ts index 1d5af6a..e51e3bd 100644 --- a/packages/proposals/src/actions/addCustomSingleSignerTransaction.ts +++ b/packages/proposals/src/actions/addCustomSingleSignerTransaction.ts @@ -8,6 +8,7 @@ import { } from '@solana/web3.js'; import { contexts, utils, models, ParsedAccount } from '@oyster/common'; import { + GOVERNANCE_AUTHORITY_SEED, CustomSingleSignerTimelockTransactionLayout, TimelockSet, TimelockState, @@ -50,7 +51,7 @@ export const addCustomSingleSignerTransaction = async ( }); const [authority] = await PublicKey.findProgramAddress( - [proposal.pubkey.toBuffer()], + [Buffer.from(GOVERNANCE_AUTHORITY_SEED), proposal.pubkey.toBuffer()], PROGRAM_IDS.timelock.programId, ); diff --git a/packages/proposals/src/actions/addSigner.ts b/packages/proposals/src/actions/addSigner.ts index 5f5dfc0..f03b39a 100644 --- a/packages/proposals/src/actions/addSigner.ts +++ b/packages/proposals/src/actions/addSigner.ts @@ -12,7 +12,11 @@ import { actions, } from '@oyster/common'; -import { TimelockSet, TimelockState } from '../models/timelock'; +import { + GOVERNANCE_AUTHORITY_SEED, + TimelockSet, + TimelockState, +} from '../models/timelock'; import { AccountLayout } from '@solana/spl-token'; import { addSignerInstruction } from '../models/addSigner'; const { createTokenAccount } = actions; @@ -47,7 +51,7 @@ export const addSigner = async ( ); const [mintAuthority] = await PublicKey.findProgramAddress( - [proposal.pubkey.toBuffer()], + [Buffer.from(GOVERNANCE_AUTHORITY_SEED), proposal.pubkey.toBuffer()], PROGRAM_IDS.timelock.programId, ); diff --git a/packages/proposals/src/actions/createProposal.ts b/packages/proposals/src/actions/createProposal.ts index a87d867..81984a5 100644 --- a/packages/proposals/src/actions/createProposal.ts +++ b/packages/proposals/src/actions/createProposal.ts @@ -10,6 +10,7 @@ import { contexts, utils, actions, ParsedAccount } from '@oyster/common'; import { AccountLayout, MintLayout } from '@solana/spl-token'; import { initTimelockSetInstruction } from '../models/initTimelockSet'; import { + GOVERNANCE_AUTHORITY_SEED, TimelockConfig, TimelockSetLayout, TimelockStateLayout, @@ -45,7 +46,7 @@ export const createProposal = async ( connection, useGovernance ? timelockConfig.info.governanceMint - : timelockConfig.info.councilMint, + : timelockConfig.info.councilMint!, ) ).decimals; @@ -135,7 +136,7 @@ export const createProposal = async ( sourceHoldingAccount, useGovernance ? timelockConfig.info.governanceMint - : timelockConfig.info.councilMint, + : timelockConfig.info.councilMint!, authority, description, name, @@ -205,7 +206,10 @@ async function getAssociatedAccountsAndInstructions( const PROGRAM_IDS = utils.programIds(); const [authority] = await PublicKey.findProgramAddress( - [newProposalKey.publicKey.toBuffer()], + [ + Buffer.from(GOVERNANCE_AUTHORITY_SEED), + newProposalKey.publicKey.toBuffer(), + ], PROGRAM_IDS.timelock.programId, ); @@ -342,7 +346,7 @@ async function getAssociatedAccountsAndInstructions( accountRentExempt, useGovernance ? timelockConfig.info.governanceMint - : timelockConfig.info.councilMint, + : timelockConfig.info.councilMint!, authority, holdingSigners, ); diff --git a/packages/proposals/src/actions/depositSourceTokensAndVote.ts b/packages/proposals/src/actions/depositSourceTokensAndVote.ts index 382d561..89cf29f 100644 --- a/packages/proposals/src/actions/depositSourceTokensAndVote.ts +++ b/packages/proposals/src/actions/depositSourceTokensAndVote.ts @@ -12,7 +12,12 @@ import { actions, } from '@oyster/common'; -import { TimelockConfig, TimelockSet, TimelockState } from '../models/timelock'; +import { + GOVERNANCE_AUTHORITY_SEED, + TimelockConfig, + TimelockSet, + TimelockState, +} from '../models/timelock'; import { AccountLayout } from '@solana/spl-token'; @@ -66,6 +71,7 @@ export const depositSourceTokensAndVote = async ( const [governanceVotingRecord] = await PublicKey.findProgramAddress( [ + Buffer.from(GOVERNANCE_AUTHORITY_SEED), PROGRAM_IDS.timelock.programId.toBuffer(), proposal.pubkey.toBuffer(), existingVoteAccount.toBuffer(), @@ -107,7 +113,7 @@ export const depositSourceTokensAndVote = async ( } const [mintAuthority] = await PublicKey.findProgramAddress( - [proposal.pubkey.toBuffer()], + [Buffer.from(GOVERNANCE_AUTHORITY_SEED), proposal.pubkey.toBuffer()], PROGRAM_IDS.timelock.programId, ); diff --git a/packages/proposals/src/actions/mintSourceTokens.ts b/packages/proposals/src/actions/mintSourceTokens.ts index f14dae4..0ec368b 100644 --- a/packages/proposals/src/actions/mintSourceTokens.ts +++ b/packages/proposals/src/actions/mintSourceTokens.ts @@ -45,7 +45,7 @@ export const mintSourceTokens = async ( accountRentExempt, useGovernance ? timelockConfig.info.governanceMint - : timelockConfig.info.councilMint, + : timelockConfig.info.councilMint!, e.owner, signers, ); @@ -55,7 +55,7 @@ export const mintSourceTokens = async ( PROGRAM_IDS.token, useGovernance ? timelockConfig.info.governanceMint - : timelockConfig.info.councilMint, + : timelockConfig.info.councilMint!, e.sourceAccount, wallet.publicKey, [], diff --git a/packages/proposals/src/actions/registerProgramGovernance.ts b/packages/proposals/src/actions/registerProgramGovernance.ts index cfb0120..a67a5b8 100644 --- a/packages/proposals/src/actions/registerProgramGovernance.ts +++ b/packages/proposals/src/actions/registerProgramGovernance.ts @@ -8,6 +8,7 @@ import { contexts, utils, actions } from '@oyster/common'; import { AccountLayout, MintLayout, Token } from '@solana/spl-token'; import { + GOVERNANCE_AUTHORITY_SEED, ConsensusAlgorithm, ExecutionType, TimelockConfig, @@ -26,6 +27,7 @@ export const registerProgramGovernance = async ( connection: Connection, wallet: any, uninitializedTimelockConfig: Partial, + useCouncil: boolean, ): Promise => { const PROGRAM_IDS = utils.programIds(); let signers: Account[] = []; @@ -43,7 +45,7 @@ export const registerProgramGovernance = async ( if (!uninitializedTimelockConfig.program) uninitializedTimelockConfig.program = new Account().publicKey; // Random generation if none given - if (!uninitializedTimelockConfig.councilMint) { + if (!uninitializedTimelockConfig.councilMint && useCouncil) { // Initialize the mint, an account for the admin, and give them one council token // to start their lives with. uninitializedTimelockConfig.councilMint = createMint( @@ -111,11 +113,16 @@ export const registerProgramGovernance = async ( ); } + const councilMintSeed = uninitializedTimelockConfig.councilMint + ? uninitializedTimelockConfig.councilMint.toBuffer() + : Buffer.from(''); + const [timelockConfigKey] = await PublicKey.findProgramAddress( [ + Buffer.from(GOVERNANCE_AUTHORITY_SEED), PROGRAM_IDS.timelock.programId.toBuffer(), uninitializedTimelockConfig.governanceMint.toBuffer(), - uninitializedTimelockConfig.councilMint.toBuffer(), + councilMintSeed, uninitializedTimelockConfig.program.toBuffer(), ], PROGRAM_IDS.timelock.programId, @@ -126,8 +133,8 @@ export const registerProgramGovernance = async ( timelockConfigKey, uninitializedTimelockConfig.program, uninitializedTimelockConfig.governanceMint, - uninitializedTimelockConfig.councilMint, wallet.publicKey, + uninitializedTimelockConfig.councilMint, ), ); instructions.push( @@ -135,7 +142,7 @@ export const registerProgramGovernance = async ( timelockConfigKey, uninitializedTimelockConfig.program, uninitializedTimelockConfig.governanceMint, - uninitializedTimelockConfig.councilMint, + uninitializedTimelockConfig.consensusAlgorithm || ConsensusAlgorithm.Majority, uninitializedTimelockConfig.executionType || ExecutionType.Independent, @@ -145,6 +152,7 @@ export const registerProgramGovernance = async ( uninitializedTimelockConfig.minimumSlotWaitingPeriod || new BN(0), uninitializedTimelockConfig.timeLimit || new BN(0), uninitializedTimelockConfig.name || '', + uninitializedTimelockConfig.councilMint, ), ); diff --git a/packages/proposals/src/actions/removeSigner.ts b/packages/proposals/src/actions/removeSigner.ts index e2357e2..02ba946 100644 --- a/packages/proposals/src/actions/removeSigner.ts +++ b/packages/proposals/src/actions/removeSigner.ts @@ -6,7 +6,7 @@ import { } from '@solana/web3.js'; import { contexts, utils, models, ParsedAccount } from '@oyster/common'; -import { TimelockSet } from '../models/timelock'; +import { GOVERNANCE_AUTHORITY_SEED, TimelockSet } from '../models/timelock'; import { removeSignerInstruction } from '../models/removeSigner'; const { sendTransaction } = contexts.Connection; const { notify } = utils; @@ -25,7 +25,7 @@ export const removeSigner = async ( let instructions: TransactionInstruction[] = []; const [mintAuthority] = await PublicKey.findProgramAddress( - [proposal.pubkey.toBuffer()], + [Buffer.from(GOVERNANCE_AUTHORITY_SEED), proposal.pubkey.toBuffer()], PROGRAM_IDS.timelock.programId, ); diff --git a/packages/proposals/src/actions/sign.ts b/packages/proposals/src/actions/sign.ts index 30e9709..02d34a3 100644 --- a/packages/proposals/src/actions/sign.ts +++ b/packages/proposals/src/actions/sign.ts @@ -6,7 +6,11 @@ import { } from '@solana/web3.js'; import { contexts, utils, models, ParsedAccount } from '@oyster/common'; -import { TimelockSet, TimelockState } from '../models/timelock'; +import { + GOVERNANCE_AUTHORITY_SEED, + TimelockSet, + TimelockState, +} from '../models/timelock'; import { signInstruction } from '../models/sign'; const { sendTransaction } = contexts.Connection; @@ -26,7 +30,7 @@ export const sign = async ( let instructions: TransactionInstruction[] = []; const [mintAuthority] = await PublicKey.findProgramAddress( - [proposal.pubkey.toBuffer()], + [Buffer.from(GOVERNANCE_AUTHORITY_SEED), proposal.pubkey.toBuffer()], PROGRAM_IDS.timelock.programId, ); diff --git a/packages/proposals/src/actions/withdrawVotingTokens.ts b/packages/proposals/src/actions/withdrawVotingTokens.ts index d11971b..424ba34 100644 --- a/packages/proposals/src/actions/withdrawVotingTokens.ts +++ b/packages/proposals/src/actions/withdrawVotingTokens.ts @@ -13,6 +13,7 @@ import { } from '@oyster/common'; import { + GOVERNANCE_AUTHORITY_SEED, TimelockSet, TimelockState, TimelockStateStatus, @@ -79,7 +80,7 @@ export const withdrawVotingTokens = async ( } const [mintAuthority] = await PublicKey.findProgramAddress( - [proposal.pubkey.toBuffer()], + [Buffer.from(GOVERNANCE_AUTHORITY_SEED), proposal.pubkey.toBuffer()], PROGRAM_IDS.timelock.programId, ); @@ -117,6 +118,7 @@ export const withdrawVotingTokens = async ( const [governanceVotingRecord] = await PublicKey.findProgramAddress( [ + Buffer.from(GOVERNANCE_AUTHORITY_SEED), PROGRAM_IDS.timelock.programId.toBuffer(), proposal.pubkey.toBuffer(), existingVoteAccount.toBuffer(), diff --git a/packages/proposals/src/components/Proposal/MintSourceTokens.tsx b/packages/proposals/src/components/Proposal/MintSourceTokens.tsx index 2ae65fd..6824ec5 100644 --- a/packages/proposals/src/components/Proposal/MintSourceTokens.tsx +++ b/packages/proposals/src/components/Proposal/MintSourceTokens.tsx @@ -33,7 +33,7 @@ export default function MintSourceTokens({ const connection = useConnection(); const mintKey = useGovernance ? timelockConfig.info.governanceMint - : timelockConfig.info.councilMint; + : timelockConfig.info.councilMint!; const mint = useMint(mintKey); const [saving, setSaving] = useState(false); diff --git a/packages/proposals/src/models/createEmptyTimelockConfig.ts b/packages/proposals/src/models/createEmptyTimelockConfig.ts index 73742a1..4e3f56a 100644 --- a/packages/proposals/src/models/createEmptyTimelockConfig.ts +++ b/packages/proposals/src/models/createEmptyTimelockConfig.ts @@ -13,16 +13,16 @@ import * as Layout from '../utils/layout'; /// program account key, governance mint key, council mint key, and timelock program account key. /// 1. `[]` Program account to tie this config to. /// 2. `[]` Governance mint to tie this config to -/// 3. `[]` Council mint [optional] to tie this config to [Pass in 0s otherwise] -/// 4. `[]` Payer -/// 6. `[]` Timelock program pub key. -/// 7. `[]` System account. +/// 3. `[]` Payer +/// 4. `[]` Timelock program pub key. +/// 5. `[]` System account. +/// 6. `[]` Council mint [optional] to tie this config to [Optional] export const createEmptyTimelockConfigInstruction = ( timelockConfigAccount: PublicKey, programAccount: PublicKey, governanceMint: PublicKey, - councilMint: PublicKey, payer: PublicKey, + councilMint?: PublicKey, ): TransactionInstruction => { const PROGRAM_IDS = utils.programIds(); @@ -41,7 +41,6 @@ export const createEmptyTimelockConfigInstruction = ( { pubkey: timelockConfigAccount, isSigner: false, isWritable: false }, { pubkey: programAccount, isSigner: false, isWritable: false }, { pubkey: governanceMint, isSigner: false, isWritable: false }, - { pubkey: councilMint, isSigner: false, isWritable: false }, { pubkey: payer, isSigner: true, isWritable: false }, { @@ -51,6 +50,11 @@ export const createEmptyTimelockConfigInstruction = ( }, { pubkey: PROGRAM_IDS.system, isSigner: false, isWritable: false }, ]; + + if (councilMint) { + keys.push({ pubkey: councilMint, isSigner: false, isWritable: false }); + } + return new TransactionInstruction({ keys, programId: PROGRAM_IDS.timelock.programId, diff --git a/packages/proposals/src/models/depositSourceTokens.ts b/packages/proposals/src/models/depositSourceTokens.ts index 755635b..371d8e6 100644 --- a/packages/proposals/src/models/depositSourceTokens.ts +++ b/packages/proposals/src/models/depositSourceTokens.ts @@ -55,7 +55,7 @@ export const depositSourceTokensInstruction = ( { pubkey: sourceHoldingAccount, isSigner: false, isWritable: true }, { pubkey: votingMint, isSigner: false, isWritable: true }, { pubkey: timelockSetAccount, isSigner: false, isWritable: false }, - { pubkey: transferAuthority, isSigner: false, isWritable: false }, + { pubkey: transferAuthority, isSigner: true, isWritable: false }, { pubkey: mintAuthority, isSigner: false, isWritable: false }, { pubkey: PROGRAM_IDS.token, isSigner: false, isWritable: false }, ]; diff --git a/packages/proposals/src/models/initTimelockConfig.ts b/packages/proposals/src/models/initTimelockConfig.ts index 54be842..2ceac34 100644 --- a/packages/proposals/src/models/initTimelockConfig.ts +++ b/packages/proposals/src/models/initTimelockConfig.ts @@ -13,12 +13,11 @@ import * as Layout from '../utils/layout'; /// program account key, governance mint key, council mint key, timelock program account key. /// 1. `[]` Program account that this config uses /// 2. `[]` Governance mint that this config uses -/// 3. `[]` Council mint that this config uses [Optional] [Pass in 0s otherwise] +/// 3. `[]` Council mint that this config uses [Optional] export const initTimelockConfigInstruction = ( timelockConfigAccount: PublicKey, programAccount: PublicKey, governanceMint: PublicKey, - councilMint: PublicKey, consensusAlgorithm: number, executionType: number, timelockType: number, @@ -26,6 +25,7 @@ export const initTimelockConfigInstruction = ( minimumSlotWaitingPeriod: BN, timeLimit: BN, name: string, + councilMint?: PublicKey, ): TransactionInstruction => { const PROGRAM_IDS = utils.programIds(); @@ -69,8 +69,12 @@ export const initTimelockConfigInstruction = ( { pubkey: timelockConfigAccount, isSigner: false, isWritable: true }, { pubkey: programAccount, isSigner: false, isWritable: false }, { pubkey: governanceMint, isSigner: false, isWritable: false }, - { pubkey: councilMint, isSigner: false, isWritable: false }, ]; + + if (councilMint) { + keys.push({ pubkey: councilMint, isSigner: false, isWritable: false }); + } + return new TransactionInstruction({ keys, programId: PROGRAM_IDS.timelock.programId, diff --git a/packages/proposals/src/models/timelock.ts b/packages/proposals/src/models/timelock.ts index 1904616..20e6c79 100644 --- a/packages/proposals/src/models/timelock.ts +++ b/packages/proposals/src/models/timelock.ts @@ -10,8 +10,9 @@ export const CONFIG_NAME_LENGTH = 32; export const INSTRUCTION_LIMIT = 450; export const TRANSACTION_SLOTS = 5; export const TEMP_FILE_TXN_SIZE = 1000; -// Key chosen to represent an unused key, a dummy empty. Points to system program. -export const ZERO_KEY = '11111111111111111111111111111111'; + +/// Seed for proposal authority +export const GOVERNANCE_AUTHORITY_SEED = 'governance'; export enum TimelockInstruction { InitTimelockSet = 1, @@ -71,7 +72,7 @@ export interface TimelockConfig { /// Governance mint governanceMint: PublicKey; /// Council mint (Optional) - councilMint: PublicKey; + councilMint?: PublicKey; /// Program ID that is tied to this config (optional) program: PublicKey; /// Time limit in slots for proposal to be open to voting @@ -91,12 +92,13 @@ export const TimelockConfigLayout: typeof BufferLayout.Structure = BufferLayout. BufferLayout.u8('votingEntryRule'), Layout.uint64('minimumSlotWaitingPeriod'), Layout.publicKey('governanceMint'), + BufferLayout.u8('councilMintOption'), Layout.publicKey('councilMint'), Layout.publicKey('program'), Layout.uint64('timeLimit'), BufferLayout.seq(BufferLayout.u8(), CONFIG_NAME_LENGTH, 'name'), BufferLayout.u32('count'), - BufferLayout.seq(BufferLayout.u8(), 296, 'padding'), + BufferLayout.seq(BufferLayout.u8(), 295, 'padding'), ], ); @@ -428,7 +430,7 @@ export const TimelockConfigParser = ( votingEntryRule: data.votingEntryRule, minimumSlotWaitingPeriod: data.minimumSlotWaitingPeriod, governanceMint: data.governanceMint, - councilMint: data.councilMint, + councilMint: data.councilMintOption == 1 ? data.councilMint : null, program: data.program, timeLimit: data.timeLimit, name: utils.fromUTF8Array(data.name).replaceAll('\u0000', ''), diff --git a/packages/proposals/src/utils/serialize.ts b/packages/proposals/src/utils/serialize.ts index d1dc853..8017f84 100644 --- a/packages/proposals/src/utils/serialize.ts +++ b/packages/proposals/src/utils/serialize.ts @@ -6,7 +6,7 @@ import { PublicKey, Message, } from '@solana/web3.js'; -import { TimelockSet } from '../models/timelock'; +import { GOVERNANCE_AUTHORITY_SEED, TimelockSet } from '../models/timelock'; export async function serializeInstruction({ connection, instr, @@ -23,7 +23,7 @@ export async function serializeInstruction({ await connection.getRecentBlockhash('max') ).blockhash; const [authority] = await PublicKey.findProgramAddress( - [proposal.pubkey.toBuffer()], + [Buffer.from(GOVERNANCE_AUTHORITY_SEED), proposal.pubkey.toBuffer()], PROGRAM_IDS.timelock.programId, ); instructionTransaction.setSigners(authority); diff --git a/packages/proposals/src/views/governance/index.tsx b/packages/proposals/src/views/governance/index.tsx index aad66ee..39674e2 100644 --- a/packages/proposals/src/views/governance/index.tsx +++ b/packages/proposals/src/views/governance/index.tsx @@ -16,7 +16,6 @@ import { TimelockConfig, TimelockType, VotingEntryRule, - ZERO_KEY, } from '../../models/timelock'; import { PublicKey } from '@solana/web3.js'; import { Table } from 'antd'; @@ -91,7 +90,7 @@ const columns = [ render: (config: ParsedAccount) => ( <> - {config.info.councilMint.toBase58() != ZERO_KEY && ( + {config.info.councilMint && ( )} diff --git a/packages/proposals/src/views/governance/register.tsx b/packages/proposals/src/views/governance/register.tsx index c25fb39..bdf066f 100644 --- a/packages/proposals/src/views/governance/register.tsx +++ b/packages/proposals/src/views/governance/register.tsx @@ -8,7 +8,6 @@ import { ExecutionType, TimelockType, VotingEntryRule, - ZERO_KEY, } from '../../models/timelock'; import { LABELS } from '../../constants'; import { contexts, utils, tryParseKey } from '@oyster/common'; @@ -132,9 +131,8 @@ export function NewForm({ : undefined, councilMint: values.councilMint ? new PublicKey(values.councilMint) - : councilVisible - ? undefined // if visible but empty, set undefined so we instantiate one - : new PublicKey(ZERO_KEY), // default empty case, just make it padding since user doesnt want one. + : undefined, + program: new PublicKey(values.program), name: values.name, timeLimit: new BN(values.timeLimit), @@ -144,6 +142,7 @@ export function NewForm({ connection, wallet.wallet, uninitializedConfig, + councilVisible, ); handleOk(newConfig); }; diff --git a/packages/proposals/src/views/proposal/new.tsx b/packages/proposals/src/views/proposal/new.tsx index 15d6e77..a4d5a2a 100644 --- a/packages/proposals/src/views/proposal/new.tsx +++ b/packages/proposals/src/views/proposal/new.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import { Button, ButtonProps, Modal, Radio } from 'antd'; import { Form, Input, Select } from 'antd'; import { Account } from '@solana/web3.js'; -import { DESC_SIZE, NAME_SIZE, ZERO_KEY } from '../../models/timelock'; +import { DESC_SIZE, NAME_SIZE } from '../../models/timelock'; import { LABELS } from '../../constants'; import { contexts, utils } from '@oyster/common'; import { createProposal } from '../../actions/createProposal'; @@ -80,7 +80,7 @@ export function NewForm({ if ( values.proposalMintType === ProposalMintType.Council && - config.info.councilMint.toBase58() === ZERO_KEY + !config.info.councilMint ) { notify({ message: LABELS.THIS_CONFIG_LACKS_COUNCIL,