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 (
+
+
+
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,