Skip to content

Commit

Permalink
decode add member and revoke member (solana-labs#1400)
Browse files Browse the repository at this point in the history
* decode revoke member

* decode add member
  • Loading branch information
asktree authored Feb 12, 2023
1 parent aef3f42 commit e93e83d
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 1 deletion.
135 changes: 135 additions & 0 deletions components/instructions/programs/governance.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Loading from '@components/Loading'
import { fetchMintInfoByPubkey } from '@hooks/queries/mintInfo'
import {
AccountMetaData,
DepositGoverningTokensArgs,
deserializeBorsh,
getGovernance,
getGovernanceInstructionSchema,
Expand All @@ -10,6 +12,7 @@ import {
InstructionData,
ProgramAccount,
RealmConfigAccount,
RevokeGoverningTokensArgs,
SetRealmAuthorityAction,
SetRealmAuthorityArgs,
tryGetRealmConfig,
Expand All @@ -24,6 +27,7 @@ import { DISABLED_VOTER_WEIGHT, SIMULATION_WALLET } from '@tools/constants'
import { fmtVoterWeightThresholdMintAmount } from '@tools/governance/units'
import {
fmtBNAmount,
fmtBnMintDecimals,
fmtMintAmount,
getDaysFromTimestamp,
getHoursFromTimestamp,
Expand All @@ -36,6 +40,70 @@ const governanceProgramId = 'GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw'

export const GOVERNANCE_INSTRUCTIONS = {
[governanceProgramId]: {
1: {
/// Deposits governing tokens (Community or Council) to Governance Realm and establishes your voter weight to be used for voting within the Realm
/// Note: If subsequent (top up) deposit is made and there are active votes for the Voter then the vote weights won't be updated automatically
/// It can be done by relinquishing votes on active Proposals and voting again with the new weight
///
/// 0. `[]` Realm account
/// 1. `[writable]` Governing Token Holding account. PDA seeds: ['governance',realm, governing_token_mint]
/// 2. `[writable]` Governing Token Source account. It can be either spl-token TokenAccount or MintAccount
/// Tokens will be transferred or minted to the Holding account
/// 3. `[signer]` Governing Token Owner account
/// 4. `[signer]` Governing Token Source account authority
/// It should be owner for TokenAccount and mint_authority for MintAccount
/// 5. `[writable]` TokenOwnerRecord account. PDA seeds: ['governance',realm, governing_token_mint, governing_token_owner]
/// 6. `[signer]` Payer
/// 7. `[]` System
/// 8. `[]` SPL Token program
/// 9. `[]` RealmConfig account. PDA seeds: ['realm-config', realm]
name: 'Deposit Governing Tokens',
accounts: [
{ name: 'Realm' },
{ name: 'Governing Token Holding' },
{ name: 'Mint' },
{ name: 'Governing Token Owner' },
{ name: 'Mint Authority' },
{ name: 'Token Owner Record' },
{ name: 'Payer' },
{ name: 'System' },
{ name: 'SPL Token Program' },
{ name: 'Realm Config' },
],
getDataUI: async (
connection: Connection,
data: Uint8Array,
accounts: AccountMetaData[]
) => {
const realm = await getRealm(connection, accounts[0].pubkey)
const programVersion = await getGovernanceProgramVersion(
connection,
realm.owner
)
const mintInfoQuery = await fetchMintInfoByPubkey(
connection,
accounts[2].pubkey
)

const args = deserializeBorsh(
getGovernanceInstructionSchema(programVersion),
DepositGoverningTokensArgs,
Buffer.from(data)
) as DepositGoverningTokensArgs

return (
<>
<p>
amount:{' '}
{mintInfoQuery.result !== undefined
? fmtBnMintDecimals(args.amount, mintInfoQuery.result.decimals)
: 'loading mint info...'}{' '}
({args.amount.toString()})
</p>
</>
)
},
},
19: {
name: 'Set Governance Config',
accounts: [{ name: 'Governance' }],
Expand Down Expand Up @@ -663,5 +731,72 @@ export const GOVERNANCE_INSTRUCTIONS = {
)
},
},
26: {
name: 'Revoke Governing Tokens',
/// Revokes (burns) membership governing tokens for the given TokenOwnerRecord and hence takes away governance power from the TokenOwner
/// Note: If there are active votes for the TokenOwner then the vote weights won't be updated automatically
///
/// 0. `[]` Realm account
/// 1. `[writable]` Governing Token Holding account. PDA seeds: ['governance',realm, governing_token_mint]
/// 2. `[writable]` TokenOwnerRecord account. PDA seeds: ['governance',realm, governing_token_mint, governing_token_owner]
/// 3. `[writable]` GoverningTokenMint
/// 4. `[signer]` Revoke authority which can be either of:
/// 1) GoverningTokenMint mint_authority to forcefully revoke the membership tokens
/// 2) GoverningTokenOwner who voluntarily revokes their own membership
/// 5. `[]` RealmConfig account. PDA seeds: ['realm-config', realm]
/// 6. `[]` SPL Token program
accounts: [
{
name: 'Realm',
},
{
name: 'Governing Token Holding',
},
{
name: 'Token Owner Record',
},
{
name: 'Governing Token Mint',
},
{
name: 'Governing Token Mint Authority',
},
{ name: 'Realm Config Account' },
{ name: 'SPL Token Program' },
],
getDataUI: async (
connection: Connection,
data: Uint8Array,
accounts: AccountMetaData[]
) => {
const realm = await getRealm(connection, accounts[0].pubkey)
const programVersion = await getGovernanceProgramVersion(
connection,
realm.owner
)
const mintInfoQuery = await fetchMintInfoByPubkey(
connection,
accounts[3].pubkey
)

const args = deserializeBorsh(
getGovernanceInstructionSchema(programVersion),
RevokeGoverningTokensArgs,
Buffer.from(data)
) as RevokeGoverningTokensArgs

return (
<>
<p>
amount:{' '}
{mintInfoQuery.result !== undefined
? fmtBnMintDecimals(args.amount, mintInfoQuery.result.decimals)
: 'loading mint info...'}{' '}
({args.amount.toString()})
</p>
</>
)
},
},
},
} as const
18 changes: 17 additions & 1 deletion hooks/queries/mintInfo.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { EndpointTypes } from '@models/types'
import { PublicKey } from '@solana/web3.js'
import { Connection, PublicKey } from '@solana/web3.js'
import { useQuery } from '@tanstack/react-query'
import { getNetworkFromEndpoint } from '@utils/connection'
import asFindable from '@utils/queries/asFindable'
import { tryGetMint } from '@utils/tokens'
import useWalletStore from 'stores/useWalletStore'
import queryClient from './queryClient'

export const mintInfoQueryKeys = {
all: (cluster: EndpointTypes) => [cluster, 'MintInfo'],
Expand Down Expand Up @@ -32,3 +34,17 @@ export const useMintInfoByPubkeyQuery = (pubkey?: PublicKey) => {

return query
}

export const fetchMintInfoByPubkey = (
connection: Connection,
pubkey: PublicKey
) => {
const cluster = getNetworkFromEndpoint(connection.rpcEndpoint)
return queryClient.fetchQuery({
queryKey: mintInfoQueryKeys.byPubkey(cluster, pubkey),
queryFn: () =>
asFindable((...x: Parameters<typeof tryGetMint>) =>
tryGetMint(...x).then((x) => x?.account)
)(connection, pubkey),
})
}

0 comments on commit e93e83d

Please sign in to comment.