Skip to content
This repository has been archived by the owner on Jan 13, 2025. It is now read-only.

Commit

Permalink
Voter weight plugin config (#481)
Browse files Browse the repository at this point in the history
* voter weight addin

* vote weight plugin yarn

* playaround wip

* fixes

* fix version

* configuremint

* chore: setup DEFAULT_GOVERNANCE_PROGRAM_ID in .env files

* chore: rename useVoteRegistry to useVoterStakeRegistryClient

* chore:

* feat: Configure voter stake registry with default values

* feat:  crate mint config form

* fix: hide V2 options from V1 program UI

* feat: add voterWeightAddin to realm config proposal

* fix: add voterWeightRecord to sdk api

* feat: setup voter stake configure mint instruction

Co-authored-by: Sebastian.Bor <[email protected]>
  • Loading branch information
abrzezinski94 and SebastianBor authored Jan 18, 2022
1 parent dd8044b commit 281aeb3
Show file tree
Hide file tree
Showing 39 changed files with 888 additions and 84 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,9 @@ yarn-debug.log*
yarn-error.log*
*.css
*.css.map

# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"cSpell.words": [
"Addin",
"Blockhash",
"blockworks",
"Lamport",
"lamports",
"localnet",
Expand Down
78 changes: 43 additions & 35 deletions packages/common/src/contexts/wallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from '@solana/wallet-adapter-base';
import {
useWallet as useWalletBase,
WalletProvider as BaseWalletProvider
WalletProvider as BaseWalletProvider,
} from '@solana/wallet-adapter-react';
import {
getLedgerWallet,
Expand All @@ -22,10 +22,19 @@ import {
Wallet,
WalletName,
} from '@solana/wallet-adapter-wallets';
import { Button, Modal } from "antd";
import React, { createContext, FC, ReactNode, useCallback, useContext, useEffect, useMemo, useState } from 'react';
import { notify } from "../utils";
import { useConnectionConfig } from "./connection";
import { Button, Modal } from 'antd';
import React, {
createContext,
FC,
ReactNode,
useCallback,
useContext,
useEffect,
useMemo,
useState,
} from 'react';
import { notify } from '../utils';
import { useConnectionConfig } from './connection';

export interface WalletContextState extends WalletAdapterProps {
wallets: Wallet[];
Expand All @@ -43,20 +52,25 @@ export interface WalletContextState extends WalletAdapterProps {
signMessage: MessageSignerWalletAdapterProps['signMessage'] | undefined;
}

export function useWallet (): WalletContextState {
export function useWallet(): WalletContextState {
return useWalletBase() as WalletContextState;
}

export { SignerWalletAdapter, WalletNotConnectedError };

export type WalletSigner = Pick<SignerWalletAdapter, 'publicKey' | 'signTransaction' | 'signAllTransactions'>;
export type WalletSigner = Pick<
SignerWalletAdapter,
'publicKey' | 'signTransaction' | 'signAllTransactions'
>;

export interface WalletModalContextState {
visible: boolean;
setVisible: (open: boolean) => void;
}

export const WalletModalContext = createContext<WalletModalContextState>({} as WalletModalContextState);
export const WalletModalContext = createContext<WalletModalContextState>(
{} as WalletModalContextState,
);

export function useWalletModal(): WalletModalContextState {
return useContext(WalletModalContext);
Expand All @@ -76,20 +90,23 @@ export const WalletModal = () => {
onCancel={close}
width={400}
>
{wallets.map((wallet) => {
{wallets.map(wallet => {
return (
<Button
key={wallet.name}
size="large"
type={wallet === selected ? 'primary' : 'ghost'}
onClick={() => { select(wallet.name); close(); }}
onClick={() => {
select(wallet.name);
close();
}}
icon={
<img
alt={`${wallet.name}`}
width={20}
height={20}
src={wallet.icon}
style={{marginRight: 8}}
style={{ marginRight: 8 }}
/>
}
style={{
Expand Down Expand Up @@ -117,13 +134,10 @@ export const WalletModalProvider = ({ children }: { children: ReactNode }) => {
const base58 = publicKey.toBase58();
const keyToDisplay =
base58.length > 20
? `${base58.substring(
0,
7,
)}.....${base58.substring(
base58.length - 7,
base58.length,
)}`
? `${base58.substring(0, 7)}.....${base58.substring(
base58.length - 7,
base58.length,
)}`
: base58;

notify({
Expand Down Expand Up @@ -151,22 +165,22 @@ export const WalletModalProvider = ({ children }: { children: ReactNode }) => {
}}
>
{children}
<WalletModal/>
<WalletModal />
</WalletModalContext.Provider>
);
};

export const WalletProvider = ({ children }: {children: ReactNode }) => {
export const WalletProvider = ({ children }: { children: ReactNode }) => {
const { env } = useConnectionConfig();

const network = useMemo(() => {
switch (env) {
case "mainnet-beta":
case 'mainnet-beta':
return WalletAdapterNetwork.Mainnet;
case "testnet":
case 'testnet':
return WalletAdapterNetwork.Testnet;
case "devnet":
case "localnet":
case 'devnet':
case 'localnet':
default:
return WalletAdapterNetwork.Devnet;
}
Expand All @@ -178,13 +192,13 @@ export const WalletProvider = ({ children }: {children: ReactNode }) => {
getSlopeWallet(),
getSolflareWallet(),
getTorusWallet({
options: { clientId: 'Get a client ID @ https://developer.tor.us' }
options: { clientId: 'Get a client ID @ https://developer.tor.us' },
}),
getLedgerWallet(),
getSolletWallet({ network }),
getSolletExtensionWallet({ network }),
],
[]
[],
);

const onError = useCallback((error: WalletError) => {
Expand All @@ -196,14 +210,8 @@ export const WalletProvider = ({ children }: {children: ReactNode }) => {
}, []);

return (
<BaseWalletProvider
wallets={wallets}
onError={onError}
autoConnect
>
<WalletModalProvider>
{children}
</WalletModalProvider>
<BaseWalletProvider wallets={wallets} onError={onError} autoConnect>
<WalletModalProvider>{children}</WalletModalProvider>
</BaseWalletProvider>
);
}
};
2 changes: 1 addition & 1 deletion packages/governance-sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@solana/spl-governance",
"version": "0.0.13",
"version": "0.0.14",
"description": "SPL Governance Client API",
"author": "Solana Maintainers <[email protected]>",
"homepage": "https://github.com/solana-labs/oyster/blob/main/packages/governance-sdk/README.md",
Expand Down
2 changes: 1 addition & 1 deletion packages/governance-sdk/src/governance/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ export class RealmConfig {
args.communityMintMaxVoteWeightSource;
this.minCommunityTokensToCreateGovernance =
args.minCommunityTokensToCreateGovernance;
this.useCommunityVoterWeightAddin = args.useCommunityVoterWeightAddin;
this.useCommunityVoterWeightAddin = !!args.useCommunityVoterWeightAddin;
this.reserved = args.reserved;
}
}
Expand Down
4 changes: 4 additions & 0 deletions packages/governance-sdk/src/governance/withCastVote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { CastVoteArgs, Vote } from './instructions';
import { getVoteRecordAddress } from './accounts';
import { PROGRAM_VERSION_V1 } from '../registry/constants';
import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime';
import { withVoterWeightAccounts } from './withVoterWeightAccounts';

export const withCastVote = async (
instructions: TransactionInstruction[],
Expand All @@ -24,6 +25,7 @@ export const withCastVote = async (
governingTokenMint: PublicKey,
vote: Vote,
payer: PublicKey,
voterWeightRecord?: PublicKey,
) => {
const args = new CastVoteArgs(
programVersion === PROGRAM_VERSION_V1
Expand Down Expand Up @@ -103,6 +105,8 @@ export const withCastVote = async (
},
];

withVoterWeightAccounts(keys, programId, realm, voterWeightRecord);

instructions.push(
new TransactionInstruction({
keys,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { serialize } from 'borsh';
import { GovernanceConfig } from './accounts';
import { CreateAccountGovernanceArgs } from './instructions';
import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime';
import { withVoterWeightAccounts } from './withVoterWeightAccounts';

export const withCreateAccountGovernance = async (
instructions: TransactionInstruction[],
Expand All @@ -18,6 +19,7 @@ export const withCreateAccountGovernance = async (
tokenOwnerRecord: PublicKey,
payer: PublicKey,
governanceAuthority: PublicKey,
voterWeightRecord?: PublicKey,
): Promise<{ governanceAddress: PublicKey }> => {
const args = new CreateAccountGovernanceArgs({ config });
const data = Buffer.from(serialize(GOVERNANCE_SCHEMA, args));
Expand Down Expand Up @@ -74,6 +76,8 @@ export const withCreateAccountGovernance = async (
},
];

withVoterWeightAccounts(keys, programId, realm, voterWeightRecord);

instructions.push(
new TransactionInstruction({
keys,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { GovernanceConfig } from './accounts';
import { CreateMintGovernanceArgs } from './instructions';
import { TOKEN_PROGRAM_ID } from '../tools/sdk/splToken';
import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime';
import { withVoterWeightAccounts } from './withVoterWeightAccounts';

export const withCreateMintGovernance = async (
instructions: TransactionInstruction[],
Expand All @@ -21,6 +22,7 @@ export const withCreateMintGovernance = async (
tokenOwnerRecord: PublicKey,
payer: PublicKey,
governanceAuthority: PublicKey,
voterWeightRecord?: PublicKey,
): Promise<{ governanceAddress: PublicKey }> => {
const args = new CreateMintGovernanceArgs({
config,
Expand Down Expand Up @@ -86,6 +88,8 @@ export const withCreateMintGovernance = async (
},
];

withVoterWeightAccounts(keys, programId, realm, voterWeightRecord);

instructions.push(
new TransactionInstruction({
keys,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { GovernanceConfig } from './accounts';
import { CreateProgramGovernanceArgs } from './instructions';
import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime';
import { BPF_UPGRADE_LOADER_ID } from '../tools/sdk/bpfUpgradeableLoader';
import { withVoterWeightAccounts } from './withVoterWeightAccounts';

export const withCreateProgramGovernance = async (
instructions: TransactionInstruction[],
Expand All @@ -21,6 +22,7 @@ export const withCreateProgramGovernance = async (
tokenOwnerRecord: PublicKey,
payer: PublicKey,
governanceAuthority: PublicKey,
voterWeightRecord?: PublicKey,
): Promise<{ governanceAddress: PublicKey }> => {
const args = new CreateProgramGovernanceArgs({
config,
Expand Down Expand Up @@ -100,6 +102,8 @@ export const withCreateProgramGovernance = async (
},
];

withVoterWeightAccounts(keys, programId, realm, voterWeightRecord);

instructions.push(
new TransactionInstruction({
keys,
Expand Down
10 changes: 9 additions & 1 deletion packages/governance-sdk/src/governance/withCreateProposal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@ import {
import { getGovernanceSchema } from './serialisation';
import { serialize } from 'borsh';
import { CreateProposalArgs } from './instructions';
import { GOVERNANCE_PROGRAM_SEED, VoteType } from './accounts';
import {
getRealmConfigAddress,
GOVERNANCE_PROGRAM_SEED,
VoteType,
} from './accounts';
import { PROGRAM_VERSION_V1 } from '../registry/constants';
import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime';
import { withVoterWeightAccounts } from './withVoterWeightAccounts';

export const withCreateProposal = async (
instructions: TransactionInstruction[],
Expand All @@ -27,6 +32,7 @@ export const withCreateProposal = async (
options: string[],
useDenyOption: boolean,
payer: PublicKey,
voterWeightRecord?: PublicKey,
) => {
const args = new CreateProposalArgs({
name,
Expand Down Expand Up @@ -110,6 +116,8 @@ export const withCreateProposal = async (
},
];

withVoterWeightAccounts(keys, programId, realm, voterWeightRecord);

instructions.push(
new TransactionInstruction({
keys,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { GovernanceConfig } from './accounts';
import { CreateTokenGovernanceArgs } from './instructions';
import { SYSTEM_PROGRAM_ID } from '../tools/sdk/runtime';
import { TOKEN_PROGRAM_ID } from '../tools/sdk/splToken';
import { withVoterWeightAccounts } from './withVoterWeightAccounts';

export const withCreateTokenGovernance = async (
instructions: TransactionInstruction[],
Expand All @@ -21,6 +22,7 @@ export const withCreateTokenGovernance = async (
tokenOwnerRecord: PublicKey,
payer: PublicKey,
governanceAuthority: PublicKey,
voterWeightRecord?: PublicKey,
): Promise<{ governanceAddress: PublicKey }> => {
const args = new CreateTokenGovernanceArgs({
config,
Expand Down Expand Up @@ -90,6 +92,8 @@ export const withCreateTokenGovernance = async (
},
];

withVoterWeightAccounts(keys, programId, realm, voterWeightRecord);

instructions.push(
new TransactionInstruction({
keys,
Expand Down
25 changes: 25 additions & 0 deletions packages/governance-sdk/src/governance/withVoterWeightAccounts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { AccountMeta, PublicKey } from '@solana/web3.js';
import { getRealmConfigAddress } from './accounts';

export async function withVoterWeightAccounts(
keys: AccountMeta[],
programId: PublicKey,
realm: PublicKey,
voterWeightRecord: PublicKey | undefined,
) {
if (!voterWeightRecord) {
return;
}

const realmConfigAddress = await getRealmConfigAddress(programId, realm);
keys.push({
pubkey: realmConfigAddress,
isWritable: false,
isSigner: false,
});
keys.push({
pubkey: voterWeightRecord,
isWritable: false,
isSigner: false,
});
}
Loading

1 comment on commit 281aeb3

@vercel
Copy link

@vercel vercel bot commented on 281aeb3 Jan 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.