From 8789d427aea80cae08c78e8f22dcc1192873aa93 Mon Sep 17 00:00:00 2001 From: Ian Macalinao Date: Thu, 9 Oct 2025 11:51:50 +0800 Subject: [PATCH 1/5] pdas mod/page template --- public/templates/pdasMod.njk | 7 +++ public/templates/pdasPage.njk | 103 ++++++++++++++++++++++++++++++++++ public/templates/rootMod.njk | 3 + 3 files changed, 113 insertions(+) create mode 100644 public/templates/pdasMod.njk create mode 100644 public/templates/pdasPage.njk diff --git a/public/templates/pdasMod.njk b/public/templates/pdasMod.njk new file mode 100644 index 0000000..1bfe479 --- /dev/null +++ b/public/templates/pdasMod.njk @@ -0,0 +1,7 @@ +{% for pda in pdasToExport %} +pub mod {{ pda.name | snakeCase }}; +{% endfor %} + +{% for pda in pdasToExport %} +pub use self::{{ pda.name | snakeCase }}::*; +{% endfor %} \ No newline at end of file diff --git a/public/templates/pdasPage.njk b/public/templates/pdasPage.njk new file mode 100644 index 0000000..aaf1ba3 --- /dev/null +++ b/public/templates/pdasPage.njk @@ -0,0 +1,103 @@ +{% extends "layout.njk" %} +{% import "macros.njk" as macros %} + +{% block main %} + +{% if program %} +use crate::{{ program.name | snakeCase | upper }}_ID; +{% endif %} + +{# Generate SEED constants for constant seeds #} +{% set constantIndex = 0 %} +{% for seed in seeds %} + {% if seed.kind === 'constantPdaSeedNode' and seed.value.kind !== 'programIdValueNode' %} +pub const {{ pda.name | snakeCase | upper }}_SEED{% if constantSeeds.length > 1 %}_{{ constantIndex }}{% endif %}: &'static [u8] = b{{ seed.valueManifest.render }}; + {% set constantIndex = constantIndex + 1 %} + {% endif %} +{% endfor %} + +pub fn create_{{ pda.name | snakeCase }}_pda( + {% if hasVariableSeeds %} + {% for seed in seeds %} + {% if seed.kind === 'variablePdaSeedNode' %} + {% if seed.resolvedType.kind == 'publicKeyTypeNode' %} + {{ seed.name | snakeCase }}: solana_pubkey::Pubkey, + {% else %} + {{ seed.name | snakeCase }}: {{ seed.typeManifest.type }}, + {% endif %} + {% endif %} + {% endfor %} + {% endif %} + bump: u8, +) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + {% set constantUsageIndex = 0 %} + {% for seed in seeds %} + {% if seed.kind === 'constantPdaSeedNode' and seed.value.kind === 'programIdValueNode' %} + {% if program %} + crate::{{ program.name | snakeCase | upper }}_ID.as_ref(), + {% endif %} + {% elif seed.kind === 'constantPdaSeedNode' %} + {{ pda.name | snakeCase | upper }}_SEED{% if constantSeeds.length > 1 %}_{{ constantUsageIndex }}{% endif %}, + {% set constantUsageIndex = constantUsageIndex + 1 %} + {% elif seed.kind == 'variablePdaSeedNode' and seed.resolvedType.kind == 'publicKeyTypeNode' %} + {{ seed.name | snakeCase }}.as_ref(), + {% elif seed.kind == 'variablePdaSeedNode' and seed.resolvedType.kind == 'bytesTypeNode' %} + &{{ seed.name | snakeCase }}, + {% else %} + {{ seed.name | snakeCase }}.to_string().as_ref(), + {% endif %} + {% endfor %} + &[bump], + ], + {% if program %} + &{{ program.name | snakeCase | upper }}_ID, + {% else %} + // Program ID not available + {% endif %} + ) +} + +pub fn find_{{ pda.name | snakeCase }}_pda( +{% if hasVariableSeeds %} + {% for seed in seeds %} + {% if seed.kind == 'variablePdaSeedNode' %} + {% if seed.resolvedType.kind == 'publicKeyTypeNode' %} + {{ seed.name | snakeCase }}: &solana_pubkey::Pubkey, + {% else %} + {{ seed.name | snakeCase }}: {{ seed.typeManifest.type }}, + {% endif %} + {% endif %} + {% endfor %} +{% endif %} +) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + {% set constantUsageIndex2 = 0 %} + {% for seed in seeds %} + {% if seed.kind === 'constantPdaSeedNode' and seed.value.kind === 'programIdValueNode' %} + {% if program %} + crate::{{ program.name | snakeCase | upper }}_ID.as_ref(), + {% endif %} + {% elif seed.kind === 'constantPdaSeedNode' %} + {{ pda.name | snakeCase | upper }}_SEED{% if constantSeeds.length > 1 %}_{{ constantUsageIndex2 }}{% endif %}, + {% set constantUsageIndex2 = constantUsageIndex2 + 1 %} + {% elif seed.kind == 'variablePdaSeedNode' and seed.resolvedType.kind == 'publicKeyTypeNode' %} + {{ seed.name | snakeCase }}.as_ref(), + {% elif seed.kind == 'variablePdaSeedNode' and seed.resolvedType.kind == 'bytesTypeNode' %} + &{{ seed.name | snakeCase }}, + {% else %} + {{ seed.name | snakeCase }}.to_string().as_ref(), + {% endif %} + {% endfor %} + ], + {% if program %} + &{{ program.name | snakeCase | upper }}_ID, + {% else %} + // Program ID not available + {% endif %} + ) +} + +{% endblock %} \ No newline at end of file diff --git a/public/templates/rootMod.njk b/public/templates/rootMod.njk index d792bcb..6c9f256 100644 --- a/public/templates/rootMod.njk +++ b/public/templates/rootMod.njk @@ -12,6 +12,9 @@ {% if instructionsToExport.length > 0 %} pub mod instructions; {% endif %} + {% if pdasToExport.length > 0 %} + pub mod pdas; + {% endif %} {% if programsToExport.length > 0 %} pub mod programs; {% endif %} From 9813465677555ca1618bb19d891b0363ef9295f9 Mon Sep 17 00:00:00 2001 From: Ian Macalinao Date: Thu, 9 Oct 2025 12:33:30 +0800 Subject: [PATCH 2/5] add example for pda generation --- Cargo.lock | 25 + e2e/governance/Cargo.toml | 33 + e2e/governance/idl.json | 8758 +++++++++++++++++ .../src/generated/accounts/governance_v1.rs | 178 + .../src/generated/accounts/governance_v2.rs | 182 + .../accounts/legacy_token_owner_record.rs | 197 + e2e/governance/src/generated/accounts/mod.rs | 46 + .../generated/accounts/program_metadata.rs | 133 + .../generated/accounts/proposal_deposit.rs | 177 + .../accounts/proposal_instruction_v1.rs | 187 + .../accounts/proposal_transaction_v2.rs | 189 + .../src/generated/accounts/proposal_v1.rs | 213 + .../src/generated/accounts/proposal_v2.rs | 220 + .../accounts/realm_config_account.rs | 164 + .../src/generated/accounts/realm_v1.rs | 166 + .../src/generated/accounts/realm_v2.rs | 168 + .../generated/accounts/required_signatory.rs | 176 + .../generated/accounts/signatory_record_v1.rs | 176 + .../generated/accounts/signatory_record_v2.rs | 177 + .../accounts/token_owner_record_v1.rs | 194 + .../accounts/token_owner_record_v2.rs | 196 + .../src/generated/accounts/vote_record_v1.rs | 178 + .../src/generated/accounts/vote_record_v2.rs | 180 + e2e/governance/src/generated/errors/mod.rs | 10 + .../src/generated/errors/spl_governance.rs | 394 + .../instructions/add_required_signatory.rs | 454 + .../generated/instructions/add_signatory.rs | 541 + .../generated/instructions/cancel_proposal.rs | 447 + .../src/generated/instructions/cast_vote.rs | 896 ++ .../instructions/complete_proposal.rs | 365 + .../instructions/create_governance.rs | 689 ++ .../instructions/create_mint_governance.rs | 794 ++ .../instructions/create_native_treasury.rs | 407 + .../instructions/create_program_governance.rs | 845 ++ .../generated/instructions/create_proposal.rs | 905 ++ .../generated/instructions/create_realm.rs | 1051 ++ .../instructions/create_token_governance.rs | 805 ++ .../instructions/create_token_owner_record.rs | 488 + .../instructions/deposit_governing_tokens.rs | 716 ++ .../instructions/execute_transaction.rs | 365 + .../generated/instructions/finalize_vote.rs | 547 + .../instructions/flag_transaction_error.rs | 416 + .../instructions/insert_transaction.rs | 675 ++ .../src/generated/instructions/legacy1.rs | 225 + .../src/generated/instructions/mod.rs | 70 + .../instructions/refund_proposal_deposit.rs | 372 + .../generated/instructions/relinquish_vote.rs | 617 ++ .../instructions/remove_required_signatory.rs | 369 + .../instructions/remove_transaction.rs | 458 + .../instructions/revoke_governing_tokens.rs | 599 ++ .../instructions/set_governance_config.rs | 329 + .../instructions/set_governance_delegate.rs | 376 + .../instructions/set_realm_authority.rs | 423 + .../instructions/set_realm_config.rs | 919 ++ .../instructions/sign_off_proposal.rs | 454 + .../instructions/update_program_metadata.rs | 363 + .../instructions/withdraw_governing_tokens.rs | 552 ++ e2e/governance/src/generated/mod.rs | 15 + .../generated/pdas/community_token_holding.rs | 42 + .../generated/pdas/council_token_holding.rs | 42 + .../src/generated/pdas/governance.rs | 42 + .../generated/pdas/governing_token_holding.rs | 42 + e2e/governance/src/generated/pdas/mod.rs | 1 + .../src/generated/pdas/native_treasury.rs | 38 + e2e/governance/src/generated/pdas/proposal.rs | 46 + .../src/generated/pdas/proposal_deposit.rs | 42 + .../generated/pdas/proposal_transaction.rs | 46 + e2e/governance/src/generated/pdas/realm.rs | 38 + .../src/generated/pdas/realm_config.rs | 38 + .../src/generated/pdas/required_signatory.rs | 42 + .../src/generated/pdas/signatory_record.rs | 42 + .../src/generated/pdas/token_owner_record.rs | 46 + .../src/generated/pdas/vote_record.rs | 42 + e2e/governance/src/generated/programs.rs | 11 + e2e/governance/src/generated/shared.rs | 21 + .../src/generated/types/account_meta_data.rs | 22 + .../types/governance_account_type.rs | 51 + .../src/generated/types/governance_config.rs | 28 + .../types/governance_instruction_v1.rs | 22 + .../generated/types/governing_token_config.rs | 20 + .../governing_token_config_account_args.rs | 19 + .../types/governing_token_config_params.rs | 18 + .../generated/types/governing_token_type.rs | 29 + .../src/generated/types/instruction_data.rs | 23 + .../types/instruction_execution_flags.rs | 29 + .../types/mint_max_voter_weight_source.rs | 16 + e2e/governance/src/generated/types/mod.rs | 72 + .../src/generated/types/multi_choice_type.rs | 28 + .../src/generated/types/native_treasury.rs | 13 + .../src/generated/types/option_vote_result.rs | 29 + .../src/generated/types/proposal_option.rs | 21 + .../src/generated/types/proposal_state.rs | 36 + .../src/generated/types/realm_config.rs | 22 + .../generated/types/realm_config_params.rs | 21 + .../generated/types/realm_config_params_v1.rs | 18 + .../src/generated/types/reserved110.rs | 18 + .../src/generated/types/reserved119.rs | 18 + .../types/set_realm_authority_action.rs | 29 + e2e/governance/src/generated/types/slot.rs | 8 + .../types/transaction_execution_status.rs | 29 + .../src/generated/types/unix_timestamp.rs | 8 + e2e/governance/src/generated/types/vote.rs | 19 + .../src/generated/types/vote_choice.rs | 16 + .../src/generated/types/vote_kind.rs | 28 + .../src/generated/types/vote_threshold.rs | 17 + .../src/generated/types/vote_tipping.rs | 29 + .../src/generated/types/vote_type.rs | 22 + .../src/generated/types/vote_weight_v1.rs | 16 + e2e/governance/src/lib.rs | 4 + src/getRenderMapVisitor.ts | 70 +- src/utils/render.ts | 2 +- test/pdasPage.test.ts | 163 + 112 files changed, 31911 insertions(+), 7 deletions(-) create mode 100644 e2e/governance/Cargo.toml create mode 100644 e2e/governance/idl.json create mode 100644 e2e/governance/src/generated/accounts/governance_v1.rs create mode 100644 e2e/governance/src/generated/accounts/governance_v2.rs create mode 100644 e2e/governance/src/generated/accounts/legacy_token_owner_record.rs create mode 100644 e2e/governance/src/generated/accounts/mod.rs create mode 100644 e2e/governance/src/generated/accounts/program_metadata.rs create mode 100644 e2e/governance/src/generated/accounts/proposal_deposit.rs create mode 100644 e2e/governance/src/generated/accounts/proposal_instruction_v1.rs create mode 100644 e2e/governance/src/generated/accounts/proposal_transaction_v2.rs create mode 100644 e2e/governance/src/generated/accounts/proposal_v1.rs create mode 100644 e2e/governance/src/generated/accounts/proposal_v2.rs create mode 100644 e2e/governance/src/generated/accounts/realm_config_account.rs create mode 100644 e2e/governance/src/generated/accounts/realm_v1.rs create mode 100644 e2e/governance/src/generated/accounts/realm_v2.rs create mode 100644 e2e/governance/src/generated/accounts/required_signatory.rs create mode 100644 e2e/governance/src/generated/accounts/signatory_record_v1.rs create mode 100644 e2e/governance/src/generated/accounts/signatory_record_v2.rs create mode 100644 e2e/governance/src/generated/accounts/token_owner_record_v1.rs create mode 100644 e2e/governance/src/generated/accounts/token_owner_record_v2.rs create mode 100644 e2e/governance/src/generated/accounts/vote_record_v1.rs create mode 100644 e2e/governance/src/generated/accounts/vote_record_v2.rs create mode 100644 e2e/governance/src/generated/errors/mod.rs create mode 100644 e2e/governance/src/generated/errors/spl_governance.rs create mode 100644 e2e/governance/src/generated/instructions/add_required_signatory.rs create mode 100644 e2e/governance/src/generated/instructions/add_signatory.rs create mode 100644 e2e/governance/src/generated/instructions/cancel_proposal.rs create mode 100644 e2e/governance/src/generated/instructions/cast_vote.rs create mode 100644 e2e/governance/src/generated/instructions/complete_proposal.rs create mode 100644 e2e/governance/src/generated/instructions/create_governance.rs create mode 100644 e2e/governance/src/generated/instructions/create_mint_governance.rs create mode 100644 e2e/governance/src/generated/instructions/create_native_treasury.rs create mode 100644 e2e/governance/src/generated/instructions/create_program_governance.rs create mode 100644 e2e/governance/src/generated/instructions/create_proposal.rs create mode 100644 e2e/governance/src/generated/instructions/create_realm.rs create mode 100644 e2e/governance/src/generated/instructions/create_token_governance.rs create mode 100644 e2e/governance/src/generated/instructions/create_token_owner_record.rs create mode 100644 e2e/governance/src/generated/instructions/deposit_governing_tokens.rs create mode 100644 e2e/governance/src/generated/instructions/execute_transaction.rs create mode 100644 e2e/governance/src/generated/instructions/finalize_vote.rs create mode 100644 e2e/governance/src/generated/instructions/flag_transaction_error.rs create mode 100644 e2e/governance/src/generated/instructions/insert_transaction.rs create mode 100644 e2e/governance/src/generated/instructions/legacy1.rs create mode 100644 e2e/governance/src/generated/instructions/mod.rs create mode 100644 e2e/governance/src/generated/instructions/refund_proposal_deposit.rs create mode 100644 e2e/governance/src/generated/instructions/relinquish_vote.rs create mode 100644 e2e/governance/src/generated/instructions/remove_required_signatory.rs create mode 100644 e2e/governance/src/generated/instructions/remove_transaction.rs create mode 100644 e2e/governance/src/generated/instructions/revoke_governing_tokens.rs create mode 100644 e2e/governance/src/generated/instructions/set_governance_config.rs create mode 100644 e2e/governance/src/generated/instructions/set_governance_delegate.rs create mode 100644 e2e/governance/src/generated/instructions/set_realm_authority.rs create mode 100644 e2e/governance/src/generated/instructions/set_realm_config.rs create mode 100644 e2e/governance/src/generated/instructions/sign_off_proposal.rs create mode 100644 e2e/governance/src/generated/instructions/update_program_metadata.rs create mode 100644 e2e/governance/src/generated/instructions/withdraw_governing_tokens.rs create mode 100644 e2e/governance/src/generated/mod.rs create mode 100644 e2e/governance/src/generated/pdas/community_token_holding.rs create mode 100644 e2e/governance/src/generated/pdas/council_token_holding.rs create mode 100644 e2e/governance/src/generated/pdas/governance.rs create mode 100644 e2e/governance/src/generated/pdas/governing_token_holding.rs create mode 100644 e2e/governance/src/generated/pdas/mod.rs create mode 100644 e2e/governance/src/generated/pdas/native_treasury.rs create mode 100644 e2e/governance/src/generated/pdas/proposal.rs create mode 100644 e2e/governance/src/generated/pdas/proposal_deposit.rs create mode 100644 e2e/governance/src/generated/pdas/proposal_transaction.rs create mode 100644 e2e/governance/src/generated/pdas/realm.rs create mode 100644 e2e/governance/src/generated/pdas/realm_config.rs create mode 100644 e2e/governance/src/generated/pdas/required_signatory.rs create mode 100644 e2e/governance/src/generated/pdas/signatory_record.rs create mode 100644 e2e/governance/src/generated/pdas/token_owner_record.rs create mode 100644 e2e/governance/src/generated/pdas/vote_record.rs create mode 100644 e2e/governance/src/generated/programs.rs create mode 100644 e2e/governance/src/generated/shared.rs create mode 100644 e2e/governance/src/generated/types/account_meta_data.rs create mode 100644 e2e/governance/src/generated/types/governance_account_type.rs create mode 100644 e2e/governance/src/generated/types/governance_config.rs create mode 100644 e2e/governance/src/generated/types/governance_instruction_v1.rs create mode 100644 e2e/governance/src/generated/types/governing_token_config.rs create mode 100644 e2e/governance/src/generated/types/governing_token_config_account_args.rs create mode 100644 e2e/governance/src/generated/types/governing_token_config_params.rs create mode 100644 e2e/governance/src/generated/types/governing_token_type.rs create mode 100644 e2e/governance/src/generated/types/instruction_data.rs create mode 100644 e2e/governance/src/generated/types/instruction_execution_flags.rs create mode 100644 e2e/governance/src/generated/types/mint_max_voter_weight_source.rs create mode 100644 e2e/governance/src/generated/types/mod.rs create mode 100644 e2e/governance/src/generated/types/multi_choice_type.rs create mode 100644 e2e/governance/src/generated/types/native_treasury.rs create mode 100644 e2e/governance/src/generated/types/option_vote_result.rs create mode 100644 e2e/governance/src/generated/types/proposal_option.rs create mode 100644 e2e/governance/src/generated/types/proposal_state.rs create mode 100644 e2e/governance/src/generated/types/realm_config.rs create mode 100644 e2e/governance/src/generated/types/realm_config_params.rs create mode 100644 e2e/governance/src/generated/types/realm_config_params_v1.rs create mode 100644 e2e/governance/src/generated/types/reserved110.rs create mode 100644 e2e/governance/src/generated/types/reserved119.rs create mode 100644 e2e/governance/src/generated/types/set_realm_authority_action.rs create mode 100644 e2e/governance/src/generated/types/slot.rs create mode 100644 e2e/governance/src/generated/types/transaction_execution_status.rs create mode 100644 e2e/governance/src/generated/types/unix_timestamp.rs create mode 100644 e2e/governance/src/generated/types/vote.rs create mode 100644 e2e/governance/src/generated/types/vote_choice.rs create mode 100644 e2e/governance/src/generated/types/vote_kind.rs create mode 100644 e2e/governance/src/generated/types/vote_threshold.rs create mode 100644 e2e/governance/src/generated/types/vote_tipping.rs create mode 100644 e2e/governance/src/generated/types/vote_type.rs create mode 100644 e2e/governance/src/generated/types/vote_weight_v1.rs create mode 100644 e2e/governance/src/lib.rs create mode 100644 test/pdasPage.test.ts diff --git a/Cargo.lock b/Cargo.lock index 20d95ee..ab96c58 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -862,6 +862,31 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "codama-renderers-rust-e2e-governance" +version = "0.0.0" +dependencies = [ + "anchor-lang", + "assert_matches", + "borsh 0.10.4", + "kaigan", + "num-derive", + "num-traits", + "serde", + "serde-big-array", + "serde_with", + "solana-account", + "solana-account-info", + "solana-client", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-sdk", + "thiserror 1.0.69", +] + [[package]] name = "codama-renderers-rust-e2e-memo" version = "0.0.0" diff --git a/e2e/governance/Cargo.toml b/e2e/governance/Cargo.toml new file mode 100644 index 0000000..5a04d0e --- /dev/null +++ b/e2e/governance/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "codama-renderers-rust-e2e-governance" +version = "0.0.0" +edition = "2021" + +[features] +anchor = ["dep:anchor-lang"] +anchor-idl-build = ["anchor", "anchor-lang?/idl-build"] +serde = ["dep:serde", "dep:serde_with", "dep:serde-big-array"] +test-sbf = [] + +[dependencies] +anchor-lang = { workspace = true, optional = true } +borsh = { workspace = true } +kaigan = { workspace = true } +num-derive = { workspace = true } +num-traits = { workspace = true } +serde = { workspace = true, features = ["derive"], optional = true } +serde-big-array = { workspace = true, optional = true } +serde_with = { workspace = true, optional = true } +solana-account = { workspace = true } +solana-account-info = { workspace = true } +solana-client = { workspace = true, optional = true } +solana-cpi = { workspace = true } +solana-decode-error = { workspace = true } +solana-instruction = { workspace = true } +solana-program-error = { workspace = true } +solana-pubkey = { workspace = true, features = ["curve25519", "borsh"] } +thiserror = { workspace = true } + +[dev-dependencies] +assert_matches = { workspace = true } +solana-sdk = { workspace = true } diff --git a/e2e/governance/idl.json b/e2e/governance/idl.json new file mode 100644 index 0000000..ca7f9df --- /dev/null +++ b/e2e/governance/idl.json @@ -0,0 +1,8758 @@ +{ + "kind": "rootNode", + "standard": "codama", + "version": "1.3.7", + "program": { + "kind": "programNode", + "name": "splGovernance", + "publicKey": "GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw", + "version": "3.1.1", + "origin": "shank", + "docs": [], + "accounts": [ + { + "kind": "accountNode", + "name": "governanceV2", + "docs": [], + "data": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "accountType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceAccountType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "realm", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "governedAccount", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "reserved1", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "config", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceConfig" + } + }, + { + "kind": "structFieldTypeNode", + "name": "reservedV2", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "reserved119" + } + }, + { + "kind": "structFieldTypeNode", + "name": "requiredSignatoriesCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "activeProposalCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + } + ] + }, + "pda": { + "kind": "pdaLinkNode", + "name": "governance" + } + }, + { + "kind": "accountNode", + "name": "realmV1", + "docs": [], + "data": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "accountType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceAccountType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "communityMint", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "config", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "realmConfig" + } + }, + { + "kind": "structFieldTypeNode", + "name": "reserved", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 6 + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "votingProposalCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u16", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "authority", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "publicKeyTypeNode" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "name", + "docs": [], + "type": { + "kind": "sizePrefixTypeNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + } + } + ] + }, + "pda": { + "kind": "pdaLinkNode", + "name": "realm" + } + }, + { + "kind": "accountNode", + "name": "tokenOwnerRecordV1", + "docs": [], + "data": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "accountType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceAccountType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "realm", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "governingTokenMint", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "governingTokenOwner", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "governingTokenDepositAmount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "unrelinquishedVotesCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "outstandingProposalCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "version", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "reserved", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 6 + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "governanceDelegate", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "publicKeyTypeNode" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + } + ] + }, + "pda": { + "kind": "pdaLinkNode", + "name": "tokenOwnerRecord" + } + }, + { + "kind": "accountNode", + "name": "governanceV1", + "docs": [], + "data": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "accountType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceAccountType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "realm", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "governedAccount", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "proposalsCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "config", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceConfig" + } + } + ] + }, + "pda": { + "kind": "pdaLinkNode", + "name": "governance" + } + }, + { + "kind": "accountNode", + "name": "proposalV1", + "docs": [], + "data": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "accountType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceAccountType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "governance", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "governingTokenMint", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "state", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "proposalState" + } + }, + { + "kind": "structFieldTypeNode", + "name": "tokenOwnerRecord", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "signatoriesCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "signatoriesSignedOffCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "yesVotesCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "noVotesCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "instructionsExecutedCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u16", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "instructionsCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u16", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "instructionsNextIndex", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u16", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "draftAt", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "unixTimestamp" + } + }, + { + "kind": "structFieldTypeNode", + "name": "signingOffAt", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "definedTypeLinkNode", + "name": "unixTimestamp" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "votingAt", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "definedTypeLinkNode", + "name": "unixTimestamp" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "votingAtSlot", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "definedTypeLinkNode", + "name": "slot" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "votingCompletedAt", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "definedTypeLinkNode", + "name": "unixTimestamp" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "executingAt", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "definedTypeLinkNode", + "name": "unixTimestamp" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "closedAt", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "definedTypeLinkNode", + "name": "unixTimestamp" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "executionFlags", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "instructionExecutionFlags" + } + }, + { + "kind": "structFieldTypeNode", + "name": "maxVoteWeight", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "voteThreshold", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "definedTypeLinkNode", + "name": "voteThreshold" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "name", + "docs": [], + "type": { + "kind": "sizePrefixTypeNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "descriptionLink", + "docs": [], + "type": { + "kind": "sizePrefixTypeNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + } + } + ] + }, + "pda": { + "kind": "pdaLinkNode", + "name": "proposal" + } + }, + { + "kind": "accountNode", + "name": "signatoryRecordV1", + "docs": [], + "data": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "accountType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceAccountType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "proposal", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "signatory", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "signedOff", + "docs": [], + "type": { + "kind": "booleanTypeNode", + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + } + ] + }, + "pda": { + "kind": "pdaLinkNode", + "name": "signatoryRecord" + } + }, + { + "kind": "accountNode", + "name": "proposalInstructionV1", + "docs": [], + "data": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "accountType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceAccountType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "proposal", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "instructionIndex", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u16", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "holdUpTime", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "instruction", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "instructionData" + } + }, + { + "kind": "structFieldTypeNode", + "name": "executedAt", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "definedTypeLinkNode", + "name": "unixTimestamp" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "executionStatus", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "transactionExecutionStatus" + } + } + ] + }, + "pda": { + "kind": "pdaLinkNode", + "name": "proposalTransaction" + } + }, + { + "kind": "accountNode", + "name": "voteRecordV1", + "docs": [], + "data": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "accountType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceAccountType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "proposal", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "governingTokenOwner", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "isRelinquished", + "docs": [], + "type": { + "kind": "booleanTypeNode", + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "voteWeight", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "voteWeightV1" + } + } + ] + }, + "pda": { + "kind": "pdaLinkNode", + "name": "voteRecord" + } + }, + { + "kind": "accountNode", + "name": "programMetadata", + "docs": [], + "data": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "accountType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceAccountType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "updatedAt", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "slot" + } + }, + { + "kind": "structFieldTypeNode", + "name": "version", + "docs": [], + "type": { + "kind": "sizePrefixTypeNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "reserved", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 64 + } + } + } + ] + } + }, + { + "kind": "accountNode", + "name": "proposalV2", + "docs": [], + "data": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "accountType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceAccountType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "governance", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "governingTokenMint", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "state", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "proposalState" + } + }, + { + "kind": "structFieldTypeNode", + "name": "tokenOwnerRecord", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "signatoriesCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "signatoriesSignedOffCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "voteType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "voteType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "options", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "definedTypeLinkNode", + "name": "proposalOption" + }, + "count": { + "kind": "prefixedCountNode", + "prefix": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "denyVoteWeight", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "reserved1", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "abstainVoteWeight", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "startVotingAt", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "definedTypeLinkNode", + "name": "unixTimestamp" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "draftAt", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "unixTimestamp" + } + }, + { + "kind": "structFieldTypeNode", + "name": "signingOffAt", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "definedTypeLinkNode", + "name": "unixTimestamp" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "votingAt", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "definedTypeLinkNode", + "name": "unixTimestamp" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "votingAtSlot", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "definedTypeLinkNode", + "name": "slot" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "votingCompletedAt", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "definedTypeLinkNode", + "name": "unixTimestamp" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "executingAt", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "definedTypeLinkNode", + "name": "unixTimestamp" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "closedAt", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "definedTypeLinkNode", + "name": "unixTimestamp" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "executionFlags", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "instructionExecutionFlags" + } + }, + { + "kind": "structFieldTypeNode", + "name": "maxVoteWeight", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "maxVotingTime", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "voteThreshold", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "definedTypeLinkNode", + "name": "voteThreshold" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "reserved", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 64 + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "name", + "docs": [], + "type": { + "kind": "sizePrefixTypeNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "descriptionLink", + "docs": [], + "type": { + "kind": "sizePrefixTypeNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "vetoVoteWeight", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + } + ] + }, + "pda": { + "kind": "pdaLinkNode", + "name": "proposal" + } + }, + { + "kind": "accountNode", + "name": "proposalDeposit", + "docs": [], + "data": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "accountType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceAccountType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "proposal", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "depositPayer", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "reserved", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 64 + } + } + } + ] + }, + "pda": { + "kind": "pdaLinkNode", + "name": "proposalDeposit" + } + }, + { + "kind": "accountNode", + "name": "proposalTransactionV2", + "docs": [], + "data": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "accountType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceAccountType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "proposal", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "optionIndex", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "transactionIndex", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u16", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "holdUpTime", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "instructions", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "definedTypeLinkNode", + "name": "instructionData" + }, + "count": { + "kind": "prefixedCountNode", + "prefix": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "executedAt", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "definedTypeLinkNode", + "name": "unixTimestamp" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "executionStatus", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "transactionExecutionStatus" + } + }, + { + "kind": "structFieldTypeNode", + "name": "reservedV2", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 8 + } + } + } + ] + }, + "pda": { + "kind": "pdaLinkNode", + "name": "proposalTransaction" + } + }, + { + "kind": "accountNode", + "name": "realmV2", + "docs": [], + "data": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "accountType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceAccountType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "communityMint", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "config", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "realmConfig" + } + }, + { + "kind": "structFieldTypeNode", + "name": "reserved", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 6 + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "legacy1", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u16", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "authority", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "publicKeyTypeNode" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "name", + "docs": [], + "type": { + "kind": "sizePrefixTypeNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "reservedV2", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 128 + } + } + } + ] + }, + "pda": { + "kind": "pdaLinkNode", + "name": "realm" + } + }, + { + "kind": "accountNode", + "name": "realmConfigAccount", + "docs": [], + "data": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "accountType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceAccountType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "realm", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "communityTokenConfig", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governingTokenConfig" + } + }, + { + "kind": "structFieldTypeNode", + "name": "councilTokenConfig", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governingTokenConfig" + } + }, + { + "kind": "structFieldTypeNode", + "name": "reserved", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "reserved110" + } + } + ] + }, + "pda": { + "kind": "pdaLinkNode", + "name": "realmConfig" + } + }, + { + "kind": "accountNode", + "name": "requiredSignatory", + "docs": [], + "data": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "accountType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceAccountType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "accountVersion", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "governance", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "signatory", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + } + ] + }, + "pda": { + "kind": "pdaLinkNode", + "name": "requiredSignatory" + } + }, + { + "kind": "accountNode", + "name": "signatoryRecordV2", + "docs": [], + "data": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "accountType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceAccountType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "proposal", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "signatory", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "signedOff", + "docs": [], + "type": { + "kind": "booleanTypeNode", + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "reservedV2", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 8 + } + } + } + ] + }, + "pda": { + "kind": "pdaLinkNode", + "name": "signatoryRecord" + } + }, + { + "kind": "accountNode", + "name": "tokenOwnerRecordV2", + "docs": [], + "data": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "accountType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceAccountType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "realm", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "governingTokenMint", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "governingTokenOwner", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "governingTokenDepositAmount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "unrelinquishedVotesCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "outstandingProposalCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "version", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "reserved", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 6 + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "governanceDelegate", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "publicKeyTypeNode" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "reservedV2", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 128 + } + } + } + ] + }, + "pda": { + "kind": "pdaLinkNode", + "name": "tokenOwnerRecord" + } + }, + { + "kind": "accountNode", + "name": "legacyTokenOwnerRecord", + "docs": [], + "data": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "accountType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceAccountType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "realm", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "governingTokenMint", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "governingTokenOwner", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "governingTokenDepositAmount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "unrelinquishedVotesCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "totalVotesCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "outstandingProposalCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "reserved", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 7 + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "governanceDelegate", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "publicKeyTypeNode" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "reservedV2", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 128 + } + } + } + ] + }, + "pda": { + "kind": "pdaLinkNode", + "name": "tokenOwnerRecord" + } + }, + { + "kind": "accountNode", + "name": "voteRecordV2", + "docs": [], + "data": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "accountType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceAccountType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "proposal", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "governingTokenOwner", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "isRelinquished", + "docs": [], + "type": { + "kind": "booleanTypeNode", + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "voterWeight", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "vote", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "vote" + } + }, + { + "kind": "structFieldTypeNode", + "name": "reservedV2", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 8 + } + } + } + ] + }, + "pda": { + "kind": "pdaLinkNode", + "name": "voteRecord" + } + } + ], + "instructions": [ + { + "kind": "instructionNode", + "name": "createRealm", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "realmAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "Governance Realm account" + ] + }, + { + "kind": "instructionAccountNode", + "name": "realmAuthority", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "The authority of the Realm" + ] + }, + { + "kind": "instructionAccountNode", + "name": "communityTokenMint", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "The mint address of the token to be used as the community mint" + ] + }, + { + "kind": "instructionAccountNode", + "name": "communityTokenHoldingAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "The account to hold the community tokens.", + " PDA seeds=['governance', realm, community_mint]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "payer", + "isWritable": true, + "isSigner": true, + "isOptional": false, + "docs": [ + "the payer of this transaction" + ], + "defaultValue": { + "kind": "payerValueNode" + } + }, + { + "kind": "instructionAccountNode", + "name": "systemProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "System Program" + ], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "11111111111111111111111111111111", + "identifier": "systemProgram" + } + }, + { + "kind": "instructionAccountNode", + "name": "tokenProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "SPL Token Program" + ], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", + "identifier": "splToken" + } + }, + { + "kind": "instructionAccountNode", + "name": "rent", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "SysVar Rent" + ], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "SysvarRent111111111111111111111111111111111" + } + }, + { + "kind": "instructionAccountNode", + "name": "councilTokenMint", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "The mint address of the token to be used as the council mint" + ] + }, + { + "kind": "instructionAccountNode", + "name": "councilTokenHoldingAccount", + "isWritable": true, + "isSigner": false, + "isOptional": true, + "docs": [ + "The account to hold the council tokens.", + " PDA seeds: ['governance',realm,council_mint]", + " " + ] + }, + { + "kind": "instructionAccountNode", + "name": "realmConfig", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "Realm Config account" + ] + }, + { + "kind": "instructionAccountNode", + "name": "communityVoterWeightAddin", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "Optional Community Voter Weight Addin Program Id" + ] + }, + { + "kind": "instructionAccountNode", + "name": "maxCommunityVoterWeightAddin", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "Optional Max Community Voter Weight Addin Program Id" + ] + }, + { + "kind": "instructionAccountNode", + "name": "councilVoterWeightAddin", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "Optional Council Voter Weight Addin Program Id" + ] + }, + { + "kind": "instructionAccountNode", + "name": "maxCouncilVoterWeightAddin", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "Optional Max Council Voter Weight Addin Program Id" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 0 + } + }, + { + "kind": "instructionArgumentNode", + "name": "name", + "docs": [], + "type": { + "kind": "sizePrefixTypeNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + } + }, + { + "kind": "instructionArgumentNode", + "name": "configArgs", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "realmConfigParams" + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "depositGoverningTokens", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "realmAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "governingTokenHoldingAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "seeds=['governance', realm, governing_token_mint]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governingTokenSourceAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "It can either be spl-token TokenAccount or MintAccount. Tokens will be transferred or minted to the holding account" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governingTokenOwnerAccount", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "governingTokenSourceAccountAuthority", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [ + "It should be owner for TokenAccount and mint_authority for MintAccount" + ] + }, + { + "kind": "instructionAccountNode", + "name": "tokenOwnerRecord", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "seeds=['governance', realm, governing_token_mint, governing_token_owner]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "payer", + "isWritable": true, + "isSigner": true, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "payerValueNode" + } + }, + { + "kind": "instructionAccountNode", + "name": "systemProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "11111111111111111111111111111111", + "identifier": "systemProgram" + } + }, + { + "kind": "instructionAccountNode", + "name": "tokenProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", + "identifier": "splToken" + } + }, + { + "kind": "instructionAccountNode", + "name": "realmConfigAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "seeds=['realm-config', realm]" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 1 + } + }, + { + "kind": "instructionArgumentNode", + "name": "amount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "withdrawGoverningTokens", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "realmAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "governingTokenHoldingAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "seeds=['governance', realm, governing_token_mint]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governingTokenDestinationAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "All tokens will be transferred to this account" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governingTokenOwnerAccount", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "tokenOwnerRecord", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "seeds=['governance',realm, governing_token_mint, governing_token_owner]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "tokenProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", + "identifier": "splToken" + } + }, + { + "kind": "instructionAccountNode", + "name": "realmConfigAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "seeds=['realm-config', realm]" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 2 + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "setGovernanceDelegate", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "currentDelegateOrOwner", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [ + "Current governance delegate or governing token owner" + ] + }, + { + "kind": "instructionAccountNode", + "name": "tokenOwnerRecord", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 3 + } + }, + { + "kind": "instructionArgumentNode", + "name": "newGovernanceDelegate", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "publicKeyTypeNode" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "createGovernance", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "realmAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "Realm account the created governance belongs to" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governanceAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "seeds=['account-governance', realm, governed_account]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governedAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "Account governed by this Governance (governing_account). ", + " Note: the account doesn't have to exist and can be used only as a unique identified for the Governance account" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governingTokenOwnerRecord", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "Used only if not signed by RealmAuthority" + ] + }, + { + "kind": "instructionAccountNode", + "name": "payer", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "payerValueNode" + } + }, + { + "kind": "instructionAccountNode", + "name": "systemProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "11111111111111111111111111111111", + "identifier": "systemProgram" + } + }, + { + "kind": "instructionAccountNode", + "name": "governanceAuthority", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "realmConfigAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "seeds=['realm-config', realm]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "voterWeightRecord", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "Optional Voter Weight Record" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 4 + } + }, + { + "kind": "instructionArgumentNode", + "name": "config", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceConfig" + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "createProgramGovernance", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "realmAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "Realm account the created Governance belongs to" + ] + }, + { + "kind": "instructionAccountNode", + "name": "programGovernanceAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "Program Governance account. seeds: ['program-governance', realm, governed_program]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governedProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "Program governed by this Governance account" + ] + }, + { + "kind": "instructionAccountNode", + "name": "programData", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "Program Data account of the Program governed by this Governance account" + ] + }, + { + "kind": "instructionAccountNode", + "name": "currentUpgradeAuthority", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [ + "Current Upgrade Authority account of the Program governed by this Governance account" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governingTokenOwnerRecord", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "Governing TokenOwnerRecord account (Used only if not signed by RealmAuthority)" + ] + }, + { + "kind": "instructionAccountNode", + "name": "payer", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "payerValueNode" + } + }, + { + "kind": "instructionAccountNode", + "name": "bpfUpgradeableLoaderProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "bpf_upgradeable_loader_program program" + ] + }, + { + "kind": "instructionAccountNode", + "name": "systemProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "11111111111111111111111111111111", + "identifier": "systemProgram" + } + }, + { + "kind": "instructionAccountNode", + "name": "governanceAuthority", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "realmConfig", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "RealmConfig account. seeds=['realm-config', realm]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "voterWeightRecord", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "Optional Voter Weight Record" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 5 + } + }, + { + "kind": "instructionArgumentNode", + "name": "config", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceConfig" + } + }, + { + "kind": "instructionArgumentNode", + "name": "transferUpgradeAuthority", + "docs": [], + "type": { + "kind": "booleanTypeNode", + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "createProposal", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "realmAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "Realm account the created Proposal belongs to" + ] + }, + { + "kind": "instructionAccountNode", + "name": "proposalAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "Proposal account. PDA seeds ['governance',governance, governing_token_mint, proposal_index]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governanceAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "Governance account" + ] + }, + { + "kind": "instructionAccountNode", + "name": "tokenOwnerRecord", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "TokenOwnerRecord account of the Proposal owner" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governingTokenMint", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "Token Mint the Proposal is created for" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governanceAuthority", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [ + "Governance Authority (Token Owner or Governance Delegate)" + ] + }, + { + "kind": "instructionAccountNode", + "name": "payer", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "payerValueNode" + } + }, + { + "kind": "instructionAccountNode", + "name": "systemProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "11111111111111111111111111111111", + "identifier": "systemProgram" + } + }, + { + "kind": "instructionAccountNode", + "name": "realmConfig", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "RealmConfig account. PDA seeds: ['realm-config', realm]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "voterWeightRecord", + "isWritable": true, + "isSigner": false, + "isOptional": true, + "docs": [ + "Optional Voter Weight Record" + ] + }, + { + "kind": "instructionAccountNode", + "name": "proposalDepositAccount", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "Optional Proposal deposit is required when there are more active ", + " proposals than the configured deposit exempt amount. ", + " PDA seeds: ['proposal-deposit', proposal, deposit payer]" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 6 + } + }, + { + "kind": "instructionArgumentNode", + "name": "name", + "docs": [], + "type": { + "kind": "sizePrefixTypeNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + } + }, + { + "kind": "instructionArgumentNode", + "name": "descriptionLink", + "docs": [], + "type": { + "kind": "sizePrefixTypeNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + } + }, + { + "kind": "instructionArgumentNode", + "name": "voteType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "voteType" + } + }, + { + "kind": "instructionArgumentNode", + "name": "options", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "sizePrefixTypeNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + }, + "count": { + "kind": "prefixedCountNode", + "prefix": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + } + } + }, + { + "kind": "instructionArgumentNode", + "name": "useDenyOption", + "docs": [], + "type": { + "kind": "booleanTypeNode", + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "instructionArgumentNode", + "name": "proposalSeed", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "addSignatory", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "proposalAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "Proposal Account associated with the governance" + ] + }, + { + "kind": "instructionAccountNode", + "name": "tokenOwnerRecord", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "TokenOwnerRecord account of the Proposal owner" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governanceAuthority", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [ + "Governance Authority (Token Owner or Governance Delegate)" + ] + }, + { + "kind": "instructionAccountNode", + "name": "signatoryRecordAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "Signatory Record Account" + ] + }, + { + "kind": "instructionAccountNode", + "name": "payer", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "payerValueNode" + } + }, + { + "kind": "instructionAccountNode", + "name": "systemProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "11111111111111111111111111111111", + "identifier": "systemProgram" + } + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 7 + } + }, + { + "kind": "instructionArgumentNode", + "name": "signatory", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "legacy1", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 8 + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "insertTransaction", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "governanceAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "proposalAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "tokenOwnerRecord", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "TokenOwnerRecord account of the Proposal owner" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governanceAuthority", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [ + "Governance Authority (Token Owner or Governance Delegate)" + ] + }, + { + "kind": "instructionAccountNode", + "name": "proposalTransactionAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "ProposalTransaction, account. PDA seeds: ['governance', proposal, option_index, index]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "payer", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "payerValueNode" + } + }, + { + "kind": "instructionAccountNode", + "name": "systemProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "11111111111111111111111111111111", + "identifier": "systemProgram" + } + }, + { + "kind": "instructionAccountNode", + "name": "rent", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "SysvarRent111111111111111111111111111111111" + } + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 9 + } + }, + { + "kind": "instructionArgumentNode", + "name": "optionIndex", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "instructionArgumentNode", + "name": "index", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u16", + "endian": "le" + } + }, + { + "kind": "instructionArgumentNode", + "name": "holdUpTime", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + }, + { + "kind": "instructionArgumentNode", + "name": "instructions", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "definedTypeLinkNode", + "name": "instructionData" + }, + "count": { + "kind": "prefixedCountNode", + "prefix": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + } + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "removeTransaction", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "proposalAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "tokenOwnerRecord", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "TokenOwnerRecord account of the Proposal owner" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governanceAuthority", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [ + "Governance Authority (Token Owner or Governance Delegate)" + ] + }, + { + "kind": "instructionAccountNode", + "name": "proposalTransactionAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "beneficiaryAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "Beneficiary Account which would receive lamports from the disposed ProposalTransaction account" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 10 + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "cancelProposal", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "realmAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "governanceAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "proposalAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "tokenOwnerRecord", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "TokenOwnerRecord account of the Proposal owner" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governanceAuthority", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [ + "Governance authority (Token Owner or Governance Delegate)" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 11 + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "signOffProposal", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "realmAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "governanceAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "proposalAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "signatoryAccount", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [ + "Signatory account signing off the Proposal.", + " Or Proposal owner if the owner hasn't appointed any signatories" + ] + }, + { + "kind": "instructionAccountNode", + "name": "tokenOwnerRecord", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "TokenOwnerRecord for the Proposal owner, required when the owner signs off the Proposal.", + " Or `[writable]` SignatoryRecord account, required when non owner signs off the Proposal" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 12 + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "castVote", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "realmAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "governanceAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "proposalAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "proposalTokenOwnerRecord", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "TokenOwnerRecord of the Proposal owner" + ] + }, + { + "kind": "instructionAccountNode", + "name": "voterTokenOwnerRecord", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "TokenOwnerRecord of the voter. PDA seeds: ['governance',realm, vote_governing_token_mint, governing_token_owner]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governanceAuthority", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [ + "Governance Authority (Token Owner or Governance Delegate)" + ] + }, + { + "kind": "instructionAccountNode", + "name": "proposalVoteRecord", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "Proposal VoteRecord account. PDA seeds: ['governance',proposal,token_owner_record]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governingTokenMint", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "The Governing Token Mint which is used to cast the vote (vote_governing_token_mint).", + " The voting token mint is the governing_token_mint of the Proposal for Approve, Deny and Abstain votes.", + " For Veto vote the voting token mint is the mint of the opposite voting population.", + " Council mint to veto Community proposals and Community mint to veto Council proposals", + " Note: In the current version only Council veto is supported" + ] + }, + { + "kind": "instructionAccountNode", + "name": "payer", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "payerValueNode" + } + }, + { + "kind": "instructionAccountNode", + "name": "systemProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "11111111111111111111111111111111", + "identifier": "systemProgram" + } + }, + { + "kind": "instructionAccountNode", + "name": "realmConfigAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "RealmConfig account. PDA seeds: ['realm-config', realm]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "voterWeightRecord", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "Optional Voter Weight Record" + ] + }, + { + "kind": "instructionAccountNode", + "name": "maxVoterWeightRecord", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "Optional Max Voter Weight Record" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 13 + } + }, + { + "kind": "instructionArgumentNode", + "name": "vote", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "vote" + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "finalizeVote", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "realmAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "governanceAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "proposalAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "tokenOwnerRecord", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "TokenOwnerRecord of the Proposal owner" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governingTokenMint", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "realmConfig", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "RealmConfig account. PDA seeds: ['realm-config', realm]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "maxVoterWeightRecord", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "Optional Max Voter Weight Record" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 14 + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "relinquishVote", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "realmAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "governanceAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "proposalAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "tokenOwnerRecord", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "TokenOwnerRecord account. PDA seeds: ['governance',realm, vote_governing_token_mint, governing_token_owner]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "proposalVoteRecord", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "Proposal VoteRecord account. PDA seeds: ['governance',proposal, token_owner_record]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governingTokenMint", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "The Governing Token Mint which was used to cast the vote (vote_governing_token_mint)" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governanceAuthority", + "isWritable": false, + "isSigner": true, + "isOptional": true, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "beneficiaryAccount", + "isWritable": true, + "isSigner": false, + "isOptional": true, + "docs": [ + "Optional Beneficiary account which would receive lamports when VoteRecord Account is disposed.", + " It's required only when Proposal is still being voted on" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 15 + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "executeTransaction", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "governanceAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "proposalAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "proposalTransactionAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 16 + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "createMintGovernance", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "realmAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "Realm account the created Governance belongs to" + ] + }, + { + "kind": "instructionAccountNode", + "name": "mintGovernanceAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "Mint Governance account. seeds=['mint-governance', realm, governed_mint]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governedMint", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "Mint governed by this Governance account" + ] + }, + { + "kind": "instructionAccountNode", + "name": "mintAuthority", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [ + "Current Mint authority (MintTokens and optionally FreezeAccount)" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governingTokenOwnerRecord", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "Governing TokenOwnerRecord account (Used only if not signed by RealmAuthority)" + ] + }, + { + "kind": "instructionAccountNode", + "name": "payer", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "payerValueNode" + } + }, + { + "kind": "instructionAccountNode", + "name": "tokenProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", + "identifier": "splToken" + } + }, + { + "kind": "instructionAccountNode", + "name": "systemProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "11111111111111111111111111111111", + "identifier": "systemProgram" + } + }, + { + "kind": "instructionAccountNode", + "name": "governanceAuthority", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "realmConfig", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "RealmConfig account. seeds=['realm-config', realm]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "voterWeightRecord", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "Optional Voter Weight Record" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 17 + } + }, + { + "kind": "instructionArgumentNode", + "name": "config", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceConfig" + } + }, + { + "kind": "instructionArgumentNode", + "name": "transferMintAuthorities", + "docs": [], + "type": { + "kind": "booleanTypeNode", + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "createTokenGovernance", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "realmAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "Realm account the created Governance belongs to" + ] + }, + { + "kind": "instructionAccountNode", + "name": "tokenGovernanceAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "Token Governance account. seeds=['token-governance', realm, governed_token]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "tokenAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "Token account governed by this Governance account" + ] + }, + { + "kind": "instructionAccountNode", + "name": "tokenAccountAuthority", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [ + "Current token account authority (AccountOwner and optionally CloseAccount" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governingTokenOwnerRecord", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "Governing TokenOwnerRecord account (Used only if not signed by RealmAuthority" + ] + }, + { + "kind": "instructionAccountNode", + "name": "payer", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "payerValueNode" + } + }, + { + "kind": "instructionAccountNode", + "name": "tokenProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", + "identifier": "splToken" + } + }, + { + "kind": "instructionAccountNode", + "name": "systemProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "11111111111111111111111111111111", + "identifier": "systemProgram" + } + }, + { + "kind": "instructionAccountNode", + "name": "governanceAuthority", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "realmConfig", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "seeds=['realm-config', realm]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "voterWeightRecord", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "Optional Voter Weight Record" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 18 + } + }, + { + "kind": "instructionArgumentNode", + "name": "config", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceConfig" + } + }, + { + "kind": "instructionArgumentNode", + "name": "transferAccountAuthorities", + "docs": [], + "type": { + "kind": "booleanTypeNode", + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "setGovernanceConfig", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "governanceAccount", + "isWritable": true, + "isSigner": true, + "isOptional": false, + "docs": [ + "The governance account the config is for" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 19 + } + }, + { + "kind": "instructionArgumentNode", + "name": "config", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governanceConfig" + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "flagTransactionError", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "proposalAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "tokenOwnerRecord", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "TokenOwnerRecord account of the Proposal owner" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governanceAuthority", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [ + "Governance Authority (Token Owner or Governance Delegate)" + ] + }, + { + "kind": "instructionAccountNode", + "name": "proposalTransactionAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "ProposalTransaction account to flag" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 20 + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "setRealmAuthority", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "realmAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "realmAuthority", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "newRealmAuthority", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "Must be one of the realm governances when set" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 21 + } + }, + { + "kind": "instructionArgumentNode", + "name": "action", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "setRealmAuthorityAction" + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "setRealmConfig", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "realmAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "realmAuthority", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "councilTokenMint", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "Council Token Mint - optional. ", + " Note: In the current version it's only possible to remove council mint (set it to None)", + " After setting council to None it won't be possible to withdraw the tokens from the Realm any longer. ", + " If that's required then it must be done before executing this instruction" + ] + }, + { + "kind": "instructionAccountNode", + "name": "councilTokenHoldingAccount", + "isWritable": true, + "isSigner": false, + "isOptional": true, + "docs": [ + "Optional unless council is used. seeds=['governance', realm, council_mint]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "systemProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "11111111111111111111111111111111", + "identifier": "systemProgram" + } + }, + { + "kind": "instructionAccountNode", + "name": "realmConfig", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "RealmConfig account. seeds=['realm-config', realm]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "communityVoterWeightAddinProgramId", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "Optional Community Voter Weight Addin Program Id" + ] + }, + { + "kind": "instructionAccountNode", + "name": "maxCommunityVoterWeightAddinProgramId", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "Optional Max Community Voter Weight Addin Program Id" + ] + }, + { + "kind": "instructionAccountNode", + "name": "councilVoterWeightAddinProgramId", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "Optional Council Voter Weight Adding Program Id" + ] + }, + { + "kind": "instructionAccountNode", + "name": "maxCouncilVoterWeightAddinProgramId", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "Optional Max Council Voter Weight Addin Program Id" + ] + }, + { + "kind": "instructionAccountNode", + "name": "payer", + "isWritable": false, + "isSigner": true, + "isOptional": true, + "docs": [ + "Optional Payer. Required if RealmConfig doesn't exist and needs to be created" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 22 + } + }, + { + "kind": "instructionArgumentNode", + "name": "configArgs", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "realmConfigParams" + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "createTokenOwnerRecord", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "realmAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "governingTokenOwnerAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "tokenOwnerRecord", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "seeds=['governance', realm, governing_token_mint, governing_token_owner]" + ], + "defaultValue": { + "kind": "pdaValueNode", + "pda": { + "kind": "pdaLinkNode", + "name": "tokenOwnerRecord" + }, + "seeds": [ + { + "kind": "pdaSeedValueNode", + "name": "realm", + "value": { + "kind": "accountValueNode", + "name": "realmAccount" + } + }, + { + "kind": "pdaSeedValueNode", + "name": "governingTokenMint", + "value": { + "kind": "accountValueNode", + "name": "governingTokenMint" + } + }, + { + "kind": "pdaSeedValueNode", + "name": "governingTokenOwner", + "value": { + "kind": "accountValueNode", + "name": "governingTokenOwnerAccount" + } + } + ] + } + }, + { + "kind": "instructionAccountNode", + "name": "governingTokenMint", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "payer", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "payerValueNode" + } + }, + { + "kind": "instructionAccountNode", + "name": "systemProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "11111111111111111111111111111111", + "identifier": "systemProgram" + } + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 23 + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "updateProgramMetadata", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "programMetadataAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "seeds=['metadata']" + ] + }, + { + "kind": "instructionAccountNode", + "name": "payer", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "payerValueNode" + } + }, + { + "kind": "instructionAccountNode", + "name": "systemProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "11111111111111111111111111111111", + "identifier": "systemProgram" + } + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 24 + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "createNativeTreasury", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "governanceAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "Governance account the treasury account is for" + ] + }, + { + "kind": "instructionAccountNode", + "name": "nativeTreasuryAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "seeds=['native-treasury', governance]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "payer", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "payerValueNode" + } + }, + { + "kind": "instructionAccountNode", + "name": "systemProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "11111111111111111111111111111111", + "identifier": "systemProgram" + } + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 25 + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "revokeGoverningTokens", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "realmAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "governingTokenHoldingAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "seeds=['governance', realm, governing_token_mint]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "tokenOwnerRecord", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "seeds=['governance', realm, governing_token_mint, governing_token_owner]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "governingTokenMint", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "governingTokenMintAuthorityOrTokenOwner", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [ + "GoverningTokenMint mint_authority" + ] + }, + { + "kind": "instructionAccountNode", + "name": "realmConfigAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "seeds=['realm-config', realm]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "tokenProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", + "identifier": "splToken" + } + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 26 + } + }, + { + "kind": "instructionArgumentNode", + "name": "amount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "refundProposalDeposit", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "proposalAccount", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "proposalDepositAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "PDA Seeds: ['proposal-deposit', proposal, deposit payer]" + ] + }, + { + "kind": "instructionAccountNode", + "name": "proposalDepositPayer", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "Proposal Deposit Payer (beneficiary) account" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 27 + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "completeProposal", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "proposalAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "tokenOwnerRecord", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "TokenOwnerRecord account of the Proposal owner" + ] + }, + { + "kind": "instructionAccountNode", + "name": "completeProposalAuthority", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [ + "Token Owner or Delegate" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 28 + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "addRequiredSignatory", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "governanceAccount", + "isWritable": true, + "isSigner": true, + "isOptional": false, + "docs": [ + "The Governance account the config is for" + ] + }, + { + "kind": "instructionAccountNode", + "name": "requiredSignatoryAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "payer", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "payerValueNode" + } + }, + { + "kind": "instructionAccountNode", + "name": "systemProgram", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "11111111111111111111111111111111", + "identifier": "systemProgram" + } + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 29 + } + }, + { + "kind": "instructionArgumentNode", + "name": "signatory", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + }, + { + "kind": "instructionNode", + "name": "removeRequiredSignatory", + "docs": [], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "governanceAccount", + "isWritable": true, + "isSigner": true, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "requiredSignatoryAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [] + }, + { + "kind": "instructionAccountNode", + "name": "beneficiaryAccount", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": [ + "Beneficiary Account which would receive lamports from the disposed RequiredSignatory Account" + ] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 30 + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] + } + ], + "definedTypes": [ + { + "kind": "definedTypeNode", + "name": "governanceConfig", + "docs": [], + "type": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "communityVoteThreshold", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "voteThreshold" + } + }, + { + "kind": "structFieldTypeNode", + "name": "minCommunityWeightToCreateProposal", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "minTransactionHoldUpTime", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "votingBaseTime", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "communityVoteTipping", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "voteTipping" + } + }, + { + "kind": "structFieldTypeNode", + "name": "councilVoteThreshold", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "voteThreshold" + } + }, + { + "kind": "structFieldTypeNode", + "name": "councilVetoVoteThreshold", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "voteThreshold" + } + }, + { + "kind": "structFieldTypeNode", + "name": "minCouncilWeightToCreateProposal", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "councilVoteTipping", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "voteTipping" + } + }, + { + "kind": "structFieldTypeNode", + "name": "communityVetoVoteThreshold", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "voteThreshold" + } + }, + { + "kind": "structFieldTypeNode", + "name": "votingCoolOffTime", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "depositExemptProposalCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + ] + } + }, + { + "kind": "definedTypeNode", + "name": "nativeTreasury", + "docs": [], + "type": { + "kind": "structTypeNode", + "fields": [] + } + }, + { + "kind": "definedTypeNode", + "name": "proposalOption", + "docs": [], + "type": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "label", + "docs": [], + "type": { + "kind": "sizePrefixTypeNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "voteWeight", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "voteResult", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "optionVoteResult" + } + }, + { + "kind": "structFieldTypeNode", + "name": "transactionsExecutedCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u16", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "transactionsCount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u16", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "transactionsNextIndex", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u16", + "endian": "le" + } + } + ] + } + }, + { + "kind": "definedTypeNode", + "name": "instructionData", + "docs": [], + "type": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "programId", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "accounts", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "definedTypeLinkNode", + "name": "accountMetaData" + }, + "count": { + "kind": "prefixedCountNode", + "prefix": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "data", + "docs": [], + "type": { + "kind": "sizePrefixTypeNode", + "type": { + "kind": "bytesTypeNode" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + } + } + ] + } + }, + { + "kind": "definedTypeNode", + "name": "accountMetaData", + "docs": [], + "type": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "pubkey", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "isSigner", + "docs": [], + "type": { + "kind": "booleanTypeNode", + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "isWritable", + "docs": [], + "type": { + "kind": "booleanTypeNode", + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + } + ] + } + }, + { + "kind": "definedTypeNode", + "name": "realmConfigParams", + "docs": [], + "type": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "useCouncilMint", + "docs": [], + "type": { + "kind": "booleanTypeNode", + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "minCommunityWeightToCreateGovernance", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "communityMintMaxVoterWeightSource", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "mintMaxVoterWeightSource" + } + }, + { + "kind": "structFieldTypeNode", + "name": "communityTokenConfigArgs", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governingTokenConfigParams" + } + }, + { + "kind": "structFieldTypeNode", + "name": "councilTokenConfigArgs", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governingTokenConfigParams" + } + } + ] + } + }, + { + "kind": "definedTypeNode", + "name": "governingTokenConfigParams", + "docs": [], + "type": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "useVoterWeightAddin", + "docs": [], + "type": { + "kind": "booleanTypeNode", + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "useMaxVoterWeightAddin", + "docs": [], + "type": { + "kind": "booleanTypeNode", + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "tokenType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governingTokenType" + } + } + ] + } + }, + { + "kind": "definedTypeNode", + "name": "governingTokenConfigAccountArgs", + "docs": [], + "type": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "voterWeightAddin", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "publicKeyTypeNode" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "maxVoterWeightAddin", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "publicKeyTypeNode" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "tokenType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governingTokenType" + } + } + ] + } + }, + { + "kind": "definedTypeNode", + "name": "realmConfig", + "docs": [], + "type": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "legacy1", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "legacy2", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "reserved", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 6 + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "minCommunityWeightToCreateGovernance", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "communityMintMaxVoterWeightSource", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "mintMaxVoterWeightSource" + } + }, + { + "kind": "structFieldTypeNode", + "name": "councilMint", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "publicKeyTypeNode" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + } + ] + } + }, + { + "kind": "definedTypeNode", + "name": "realmConfigParamsV1", + "docs": [], + "type": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "useCouncilMint", + "docs": [], + "type": { + "kind": "booleanTypeNode", + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "minCommunityWeightToCreateGovernance", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "communityMintMaxVoterWeightSource", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "mintMaxVoterWeightSource" + } + } + ] + } + }, + { + "kind": "definedTypeNode", + "name": "governingTokenConfig", + "docs": [], + "type": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "voterWeightAddin", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "publicKeyTypeNode" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "maxVoterWeightAddin", + "docs": [], + "type": { + "kind": "optionTypeNode", + "fixed": false, + "item": { + "kind": "publicKeyTypeNode" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "tokenType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "governingTokenType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "reserved", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 8 + } + } + } + ] + } + }, + { + "kind": "definedTypeNode", + "name": "voteChoice", + "docs": [], + "type": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "rank", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "weightPercentage", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + ] + } + }, + { + "kind": "definedTypeNode", + "name": "reserved110", + "docs": [], + "type": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "reserved64", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 64 + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "reserved32", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 32 + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "reserved14", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 14 + } + } + } + ] + } + }, + { + "kind": "definedTypeNode", + "name": "reserved119", + "docs": [], + "type": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "reserved64", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 64 + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "reserved32", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 32 + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "reserved23", + "docs": [], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "count": { + "kind": "fixedCountNode", + "value": 23 + } + } + } + ] + } + }, + { + "kind": "definedTypeNode", + "name": "governanceAccountType", + "docs": [], + "type": { + "kind": "enumTypeNode", + "variants": [ + { + "kind": "enumEmptyVariantTypeNode", + "name": "uninitialized" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "realmV1" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "tokenOwnerRecordV1" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "governanceV1" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "programGovernanceV1" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "proposalV1" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "signatoryRecordV1" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "voteRecordV1" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "proposalInstructionV1" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "mintGovernanceV1" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "tokenGovernanceV1" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "realmConfig" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "voteRecordV2" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "proposalTransactionV2" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "proposalV2" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "programMetadata" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "realmV2" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "tokenOwnerRecordV2" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "governanceV2" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "programGovernanceV2" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "mintGovernanceV2" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "tokenGovernanceV2" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "signatoryRecordV2" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "proposalDeposit" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "requiredSignatory" + } + ], + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "definedTypeNode", + "name": "proposalState", + "docs": [], + "type": { + "kind": "enumTypeNode", + "variants": [ + { + "kind": "enumEmptyVariantTypeNode", + "name": "draft" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "signingOff" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "voting" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "succeeded" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "executing" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "completed" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "cancelled" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "defeated" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "executingWithErrors" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "vetoed" + } + ], + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "definedTypeNode", + "name": "voteThreshold", + "docs": [], + "type": { + "kind": "enumTypeNode", + "variants": [ + { + "kind": "enumTupleVariantTypeNode", + "name": "yesVotePercentage", + "tuple": { + "kind": "tupleTypeNode", + "items": [ + { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + ] + } + }, + { + "kind": "enumTupleVariantTypeNode", + "name": "quorumPercentage", + "tuple": { + "kind": "tupleTypeNode", + "items": [ + { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + ] + } + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "disabled" + } + ], + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "definedTypeNode", + "name": "voteTipping", + "docs": [], + "type": { + "kind": "enumTypeNode", + "variants": [ + { + "kind": "enumEmptyVariantTypeNode", + "name": "strict" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "early" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "disabled" + } + ], + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "definedTypeNode", + "name": "transactionExecutionStatus", + "docs": [], + "type": { + "kind": "enumTypeNode", + "variants": [ + { + "kind": "enumEmptyVariantTypeNode", + "name": "none" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "success" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "error" + } + ], + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "definedTypeNode", + "name": "instructionExecutionFlags", + "docs": [], + "type": { + "kind": "enumTypeNode", + "variants": [ + { + "kind": "enumEmptyVariantTypeNode", + "name": "none" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "ordered" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "useTransaction" + } + ], + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "definedTypeNode", + "name": "mintMaxVoterWeightSource", + "docs": [], + "type": { + "kind": "enumTypeNode", + "variants": [ + { + "kind": "enumTupleVariantTypeNode", + "name": "supplyFraction", + "tuple": { + "kind": "tupleTypeNode", + "items": [ + { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + ] + } + }, + { + "kind": "enumTupleVariantTypeNode", + "name": "absolute", + "tuple": { + "kind": "tupleTypeNode", + "items": [ + { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + ] + } + } + ], + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "definedTypeNode", + "name": "voteWeightV1", + "docs": [], + "type": { + "kind": "enumTypeNode", + "variants": [ + { + "kind": "enumTupleVariantTypeNode", + "name": "yes", + "tuple": { + "kind": "tupleTypeNode", + "items": [ + { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + ] + } + }, + { + "kind": "enumTupleVariantTypeNode", + "name": "no", + "tuple": { + "kind": "tupleTypeNode", + "items": [ + { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + ] + } + } + ], + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "definedTypeNode", + "name": "optionVoteResult", + "docs": [], + "type": { + "kind": "enumTypeNode", + "variants": [ + { + "kind": "enumEmptyVariantTypeNode", + "name": "none" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "succeeded" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "defeated" + } + ], + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "definedTypeNode", + "name": "voteType", + "docs": [], + "type": { + "kind": "enumTypeNode", + "variants": [ + { + "kind": "enumEmptyVariantTypeNode", + "name": "singleChoice" + }, + { + "kind": "enumStructVariantTypeNode", + "name": "multiChoice", + "struct": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "choiceType", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "multiChoiceType" + } + }, + { + "kind": "structFieldTypeNode", + "name": "minVoterOptions", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "maxVoterOptions", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "maxWinningOptions", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + ] + } + } + ], + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "definedTypeNode", + "name": "multiChoiceType", + "docs": [], + "type": { + "kind": "enumTypeNode", + "variants": [ + { + "kind": "enumEmptyVariantTypeNode", + "name": "fullWeight" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "weighted" + } + ], + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "definedTypeNode", + "name": "setRealmAuthorityAction", + "docs": [], + "type": { + "kind": "enumTypeNode", + "variants": [ + { + "kind": "enumEmptyVariantTypeNode", + "name": "setUnchecked" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "setChecked" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "remove" + } + ], + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "definedTypeNode", + "name": "governanceInstructionV1", + "docs": [], + "type": { + "kind": "enumTypeNode", + "variants": [ + { + "kind": "enumStructVariantTypeNode", + "name": "createRealm", + "struct": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "name", + "docs": [], + "type": { + "kind": "sizePrefixTypeNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "prefix": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + } + }, + { + "kind": "structFieldTypeNode", + "name": "configArgs", + "docs": [], + "type": { + "kind": "definedTypeLinkNode", + "name": "realmConfigParamsV1" + } + } + ] + } + }, + { + "kind": "enumStructVariantTypeNode", + "name": "depositGoverningTokens", + "struct": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "amount", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + } + ] + } + } + ], + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "definedTypeNode", + "name": "governingTokenType", + "docs": [], + "type": { + "kind": "enumTypeNode", + "variants": [ + { + "kind": "enumEmptyVariantTypeNode", + "name": "liquid" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "membership" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "dormant" + } + ], + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "definedTypeNode", + "name": "vote", + "docs": [], + "type": { + "kind": "enumTypeNode", + "variants": [ + { + "kind": "enumTupleVariantTypeNode", + "name": "approve", + "tuple": { + "kind": "tupleTypeNode", + "items": [ + { + "kind": "arrayTypeNode", + "item": { + "kind": "definedTypeLinkNode", + "name": "voteChoice" + }, + "count": { + "kind": "prefixedCountNode", + "prefix": { + "kind": "numberTypeNode", + "format": "u32", + "endian": "le" + } + } + } + ] + } + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "deny" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "abstain" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "veto" + } + ], + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "definedTypeNode", + "name": "voteKind", + "docs": [], + "type": { + "kind": "enumTypeNode", + "variants": [ + { + "kind": "enumEmptyVariantTypeNode", + "name": "electorate" + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "veto" + } + ], + "size": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + } + }, + { + "kind": "definedTypeNode", + "name": "unixTimestamp", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "i64", + "endian": "le" + } + }, + { + "kind": "definedTypeNode", + "name": "slot", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + } + ], + "pdas": [ + { + "kind": "pdaNode", + "name": "realm", + "docs": [ + "Realm account identified by its name" + ], + "seeds": [ + { + "kind": "constantPdaSeedNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "value": { + "kind": "stringValueNode", + "string": "governance" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "name", + "docs": [], + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + } + } + ] + }, + { + "kind": "pdaNode", + "name": "communityTokenHolding", + "docs": [ + "Community token holding account of a realm" + ], + "seeds": [ + { + "kind": "constantPdaSeedNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "value": { + "kind": "stringValueNode", + "string": "governance" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "realm", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "communityMint", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + } + ] + }, + { + "kind": "pdaNode", + "name": "councilTokenHolding", + "docs": [ + "Council token holding account of a realm" + ], + "seeds": [ + { + "kind": "constantPdaSeedNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "value": { + "kind": "stringValueNode", + "string": "governance" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "realm", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "councilMint", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + } + ] + }, + { + "kind": "pdaNode", + "name": "realmConfig", + "docs": [ + "Configuration of a realm" + ], + "seeds": [ + { + "kind": "constantPdaSeedNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "value": { + "kind": "stringValueNode", + "string": "realm-config" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "realm", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + } + ] + }, + { + "kind": "pdaNode", + "name": "tokenOwnerRecord", + "docs": [ + "Token owner's record within a realm" + ], + "seeds": [ + { + "kind": "constantPdaSeedNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "value": { + "kind": "stringValueNode", + "string": "governance" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "realm", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "governingTokenMint", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "governingTokenOwner", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + } + ] + }, + { + "kind": "pdaNode", + "name": "governingTokenHolding", + "docs": [ + "Governing token holding account" + ], + "seeds": [ + { + "kind": "constantPdaSeedNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "value": { + "kind": "stringValueNode", + "string": "governance" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "realm", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "governingTokenMint", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + } + ] + }, + { + "kind": "pdaNode", + "name": "governance", + "docs": [ + "Governance account within a realm" + ], + "seeds": [ + { + "kind": "constantPdaSeedNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "value": { + "kind": "stringValueNode", + "string": "account-governance" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "realm", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "seed", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + } + ] + }, + { + "kind": "pdaNode", + "name": "nativeTreasury", + "docs": [ + "Governance's native SOL treasury account" + ], + "seeds": [ + { + "kind": "constantPdaSeedNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "value": { + "kind": "stringValueNode", + "string": "native-treasury" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "governance", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + } + ] + }, + { + "kind": "pdaNode", + "name": "proposal", + "docs": [ + "Governance proposal" + ], + "seeds": [ + { + "kind": "constantPdaSeedNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "value": { + "kind": "stringValueNode", + "string": "governance" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "governance", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "governingTokenMint", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "proposalSeed", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + } + ] + }, + { + "kind": "pdaNode", + "name": "proposalDeposit", + "docs": [ + "Proposal deposit made by a specific payer" + ], + "seeds": [ + { + "kind": "constantPdaSeedNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "value": { + "kind": "stringValueNode", + "string": "proposal-deposit" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "proposal", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "depositPayer", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + } + ] + }, + { + "kind": "pdaNode", + "name": "signatoryRecord", + "docs": [ + "Signatory's record on a proposal" + ], + "seeds": [ + { + "kind": "constantPdaSeedNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "value": { + "kind": "stringValueNode", + "string": "governance" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "proposal", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "signatory", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + } + ] + }, + { + "kind": "pdaNode", + "name": "proposalTransaction", + "docs": [ + "Transaction within a proposal option" + ], + "seeds": [ + { + "kind": "constantPdaSeedNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "value": { + "kind": "stringValueNode", + "string": "governance" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "proposal", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "optionIndex", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "index", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u16", + "endian": "le" + } + } + ] + }, + { + "kind": "pdaNode", + "name": "voteRecord", + "docs": [ + "Vote record on a proposal" + ], + "seeds": [ + { + "kind": "constantPdaSeedNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "value": { + "kind": "stringValueNode", + "string": "governance" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "proposal", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "tokenOwnerRecord", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + } + ] + }, + { + "kind": "pdaNode", + "name": "requiredSignatory", + "docs": [ + "Required signatory on a governance" + ], + "seeds": [ + { + "kind": "constantPdaSeedNode", + "type": { + "kind": "stringTypeNode", + "encoding": "utf8" + }, + "value": { + "kind": "stringValueNode", + "string": "required-signatory" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "governance", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "variablePdaSeedNode", + "name": "signatory", + "docs": [], + "type": { + "kind": "publicKeyTypeNode" + } + } + ] + } + ], + "errors": [ + { + "kind": "errorNode", + "name": "invalidInstruction", + "code": 500, + "message": "Invalid instruction passed to program", + "docs": [ + "InvalidInstruction: Invalid instruction passed to program" + ] + }, + { + "kind": "errorNode", + "name": "realmAlreadyExists", + "code": 501, + "message": "Realm with the given name and governing mints already exists", + "docs": [ + "RealmAlreadyExists: Realm with the given name and governing mints already exists" + ] + }, + { + "kind": "errorNode", + "name": "invalidRealm", + "code": 502, + "message": "Invalid realm", + "docs": [ + "InvalidRealm: Invalid realm" + ] + }, + { + "kind": "errorNode", + "name": "invalidGoverningTokenMint", + "code": 503, + "message": "Invalid Governing Token Mint", + "docs": [ + "InvalidGoverningTokenMint: Invalid Governing Token Mint" + ] + }, + { + "kind": "errorNode", + "name": "governingTokenOwnerMustSign", + "code": 504, + "message": "Governing Token Owner must sign transaction", + "docs": [ + "GoverningTokenOwnerMustSign: Governing Token Owner must sign transaction" + ] + }, + { + "kind": "errorNode", + "name": "governingTokenOwnerOrDelegateMustSign", + "code": 505, + "message": "Governing Token Owner or Delegate must sign transaction", + "docs": [ + "GoverningTokenOwnerOrDelegateMustSign: Governing Token Owner or Delegate must sign transaction" + ] + }, + { + "kind": "errorNode", + "name": "allVotesMustBeRelinquishedToWithdrawGoverningTokens", + "code": 506, + "message": "All votes must be relinquished to withdraw governing tokens", + "docs": [ + "AllVotesMustBeRelinquishedToWithdrawGoverningTokens: All votes must be relinquished to withdraw governing tokens" + ] + }, + { + "kind": "errorNode", + "name": "invalidTokenOwnerRecordAccountAddress", + "code": 507, + "message": "Invalid Token Owner Record account address", + "docs": [ + "InvalidTokenOwnerRecordAccountAddress: Invalid Token Owner Record account address" + ] + }, + { + "kind": "errorNode", + "name": "invalidGoverningMintForTokenOwnerRecord", + "code": 508, + "message": "Invalid GoverningMint for TokenOwnerRecord", + "docs": [ + "InvalidGoverningMintForTokenOwnerRecord: Invalid GoverningMint for TokenOwnerRecord" + ] + }, + { + "kind": "errorNode", + "name": "invalidRealmForTokenOwnerRecord", + "code": 509, + "message": "Invalid Realm for TokenOwnerRecord", + "docs": [ + "InvalidRealmForTokenOwnerRecord: Invalid Realm for TokenOwnerRecord" + ] + }, + { + "kind": "errorNode", + "name": "invalidProposalForProposalTransaction", + "code": 510, + "message": "Invalid Proposal for ProposalTransaction,", + "docs": [ + "InvalidProposalForProposalTransaction: Invalid Proposal for ProposalTransaction," + ] + }, + { + "kind": "errorNode", + "name": "invalidSignatoryAddress", + "code": 511, + "message": "Invalid Signatory account address", + "docs": [ + "InvalidSignatoryAddress: Invalid Signatory account address" + ] + }, + { + "kind": "errorNode", + "name": "signatoryAlreadySignedOff", + "code": 512, + "message": "Signatory already signed off", + "docs": [ + "SignatoryAlreadySignedOff: Signatory already signed off" + ] + }, + { + "kind": "errorNode", + "name": "signatoryMustSign", + "code": 513, + "message": "Signatory must sign", + "docs": [ + "SignatoryMustSign: Signatory must sign" + ] + }, + { + "kind": "errorNode", + "name": "invalidProposalOwnerAccount", + "code": 514, + "message": "Invalid Proposal Owner", + "docs": [ + "InvalidProposalOwnerAccount: Invalid Proposal Owner" + ] + }, + { + "kind": "errorNode", + "name": "invalidProposalForVoterRecord", + "code": 515, + "message": "Invalid Proposal for VoterRecord", + "docs": [ + "InvalidProposalForVoterRecord: Invalid Proposal for VoterRecord" + ] + }, + { + "kind": "errorNode", + "name": "invalidGoverningTokenOwnerForVoteRecord", + "code": 516, + "message": "Invalid GoverningTokenOwner for VoteRecord", + "docs": [ + "InvalidGoverningTokenOwnerForVoteRecord: Invalid GoverningTokenOwner for VoteRecord" + ] + }, + { + "kind": "errorNode", + "name": "invalidVoteThresholdPercentage", + "code": 517, + "message": "Invalid Governance config: Vote threshold percentage out of range", + "docs": [ + "InvalidVoteThresholdPercentage: Invalid Governance config: Vote threshold percentage out of range" + ] + }, + { + "kind": "errorNode", + "name": "proposalAlreadyExists", + "code": 518, + "message": "Proposal for the given Governance, Governing Token Mint and index already exists", + "docs": [ + "ProposalAlreadyExists: Proposal for the given Governance, Governing Token Mint and index already exists" + ] + }, + { + "kind": "errorNode", + "name": "voteAlreadyExists", + "code": 519, + "message": "Token Owner already voted on the Proposal", + "docs": [ + "VoteAlreadyExists: Token Owner already voted on the Proposal" + ] + }, + { + "kind": "errorNode", + "name": "notEnoughTokensToCreateProposal", + "code": 520, + "message": "Owner doesn't have enough governing tokens to create Proposal", + "docs": [ + "NotEnoughTokensToCreateProposal: Owner doesn't have enough governing tokens to create Proposal" + ] + }, + { + "kind": "errorNode", + "name": "invalidStateCannotEditSignatories", + "code": 521, + "message": "Invalid State: Can't edit Signatories", + "docs": [ + "InvalidStateCannotEditSignatories: Invalid State: Can't edit Signatories" + ] + }, + { + "kind": "errorNode", + "name": "invalidProposalState", + "code": 522, + "message": "Invalid Proposal state", + "docs": [ + "InvalidProposalState: Invalid Proposal state" + ] + }, + { + "kind": "errorNode", + "name": "invalidStateCannotEditTransactions", + "code": 523, + "message": "Invalid State: Can't edit transactions", + "docs": [ + "InvalidStateCannotEditTransactions: Invalid State: Can't edit transactions" + ] + }, + { + "kind": "errorNode", + "name": "invalidStateCannotExecuteTransaction", + "code": 524, + "message": "Invalid State: Can't execute transaction", + "docs": [ + "InvalidStateCannotExecuteTransaction: Invalid State: Can't execute transaction" + ] + }, + { + "kind": "errorNode", + "name": "cannotExecuteTransactionWithinHoldUpTime", + "code": 525, + "message": "Can't execute transaction within its hold up time", + "docs": [ + "CannotExecuteTransactionWithinHoldUpTime: Can't execute transaction within its hold up time" + ] + }, + { + "kind": "errorNode", + "name": "transactionAlreadyExecuted", + "code": 526, + "message": "Transaction already executed", + "docs": [ + "TransactionAlreadyExecuted: Transaction already executed" + ] + }, + { + "kind": "errorNode", + "name": "invalidTransactionIndex", + "code": 527, + "message": "Invalid Transaction index", + "docs": [ + "InvalidTransactionIndex: Invalid Transaction index" + ] + }, + { + "kind": "errorNode", + "name": "transactionHoldUpTimeBelowRequiredMin", + "code": 528, + "message": "Transaction hold up time is below the min specified by Governance", + "docs": [ + "TransactionHoldUpTimeBelowRequiredMin: Transaction hold up time is below the min specified by Governance" + ] + }, + { + "kind": "errorNode", + "name": "transactionAlreadyExists", + "code": 529, + "message": "Transaction at the given index for the Proposal already exists", + "docs": [ + "TransactionAlreadyExists: Transaction at the given index for the Proposal already exists" + ] + }, + { + "kind": "errorNode", + "name": "invalidStateCannotSignOff", + "code": 530, + "message": "Invalid State: Can't sign off", + "docs": [ + "InvalidStateCannotSignOff: Invalid State: Can't sign off" + ] + }, + { + "kind": "errorNode", + "name": "invalidStateCannotVote", + "code": 531, + "message": "Invalid State: Can't vote", + "docs": [ + "InvalidStateCannotVote: Invalid State: Can't vote" + ] + }, + { + "kind": "errorNode", + "name": "invalidStateCannotFinalize", + "code": 532, + "message": "Invalid State: Can't finalize vote", + "docs": [ + "InvalidStateCannotFinalize: Invalid State: Can't finalize vote" + ] + }, + { + "kind": "errorNode", + "name": "invalidStateCannotCancelProposal", + "code": 533, + "message": "Invalid State: Can't cancel Proposal", + "docs": [ + "InvalidStateCannotCancelProposal: Invalid State: Can't cancel Proposal" + ] + }, + { + "kind": "errorNode", + "name": "voteAlreadyRelinquished", + "code": 534, + "message": "Vote already relinquished", + "docs": [ + "VoteAlreadyRelinquished: Vote already relinquished" + ] + }, + { + "kind": "errorNode", + "name": "cannotFinalizeVotingInProgress", + "code": 535, + "message": "Can't finalize vote. Voting still in progress", + "docs": [ + "CannotFinalizeVotingInProgress: Can't finalize vote. Voting still in progress" + ] + }, + { + "kind": "errorNode", + "name": "proposalVotingTimeExpired", + "code": 536, + "message": "Proposal voting time expired", + "docs": [ + "ProposalVotingTimeExpired: Proposal voting time expired" + ] + }, + { + "kind": "errorNode", + "name": "invalidSignatoryMint", + "code": 537, + "message": "Invalid Signatory Mint", + "docs": [ + "InvalidSignatoryMint: Invalid Signatory Mint" + ] + }, + { + "kind": "errorNode", + "name": "invalidGovernanceForProposal", + "code": 538, + "message": "Proposal does not belong to the given Governance", + "docs": [ + "InvalidGovernanceForProposal: Proposal does not belong to the given Governance" + ] + }, + { + "kind": "errorNode", + "name": "invalidGoverningMintForProposal", + "code": 539, + "message": "Proposal does not belong to given Governing Mint", + "docs": [ + "InvalidGoverningMintForProposal: Proposal does not belong to given Governing Mint" + ] + }, + { + "kind": "errorNode", + "name": "mintAuthorityMustSign", + "code": 540, + "message": "Current mint authority must sign transaction", + "docs": [ + "MintAuthorityMustSign: Current mint authority must sign transaction" + ] + }, + { + "kind": "errorNode", + "name": "invalidMintAuthority", + "code": 541, + "message": "Invalid mint authority", + "docs": [ + "InvalidMintAuthority: Invalid mint authority" + ] + }, + { + "kind": "errorNode", + "name": "mintHasNoAuthority", + "code": 542, + "message": "Mint has no authority", + "docs": [ + "MintHasNoAuthority: Mint has no authority" + ] + }, + { + "kind": "errorNode", + "name": "splTokenAccountWithInvalidOwner", + "code": 543, + "message": "Invalid Token account owner", + "docs": [ + "SplTokenAccountWithInvalidOwner: Invalid Token account owner" + ] + }, + { + "kind": "errorNode", + "name": "splTokenMintWithInvalidOwner", + "code": 544, + "message": "Invalid Mint account owner", + "docs": [ + "SplTokenMintWithInvalidOwner: Invalid Mint account owner" + ] + }, + { + "kind": "errorNode", + "name": "splTokenAccountNotInitialized", + "code": 545, + "message": "Token Account is not initialized", + "docs": [ + "SplTokenAccountNotInitialized: Token Account is not initialized" + ] + }, + { + "kind": "errorNode", + "name": "splTokenAccountDoesNotExist", + "code": 546, + "message": "Token Account doesn't exist", + "docs": [ + "SplTokenAccountDoesNotExist: Token Account doesn't exist" + ] + }, + { + "kind": "errorNode", + "name": "splTokenInvalidTokenAccountData", + "code": 547, + "message": "Token account data is invalid", + "docs": [ + "SplTokenInvalidTokenAccountData: Token account data is invalid" + ] + }, + { + "kind": "errorNode", + "name": "splTokenInvalidMintAccountData", + "code": 548, + "message": "Token mint account data is invalid", + "docs": [ + "SplTokenInvalidMintAccountData: Token mint account data is invalid" + ] + }, + { + "kind": "errorNode", + "name": "splTokenMintNotInitialized", + "code": 549, + "message": "Token Mint account is not initialized", + "docs": [ + "SplTokenMintNotInitialized: Token Mint account is not initialized" + ] + }, + { + "kind": "errorNode", + "name": "splTokenMintDoesNotExist", + "code": 550, + "message": "Token Mint account doesn't exist", + "docs": [ + "SplTokenMintDoesNotExist: Token Mint account doesn't exist" + ] + }, + { + "kind": "errorNode", + "name": "invalidProgramDataAccountAddress", + "code": 551, + "message": "Invalid ProgramData account address", + "docs": [ + "InvalidProgramDataAccountAddress: Invalid ProgramData account address" + ] + }, + { + "kind": "errorNode", + "name": "invalidProgramDataAccountData", + "code": 552, + "message": "Invalid ProgramData account Data", + "docs": [ + "InvalidProgramDataAccountData: Invalid ProgramData account Data" + ] + }, + { + "kind": "errorNode", + "name": "invalidUpgradeAuthority", + "code": 553, + "message": "Provided upgrade authority doesn't match current program upgrade authority", + "docs": [ + "InvalidUpgradeAuthority: Provided upgrade authority doesn't match current program upgrade authority" + ] + }, + { + "kind": "errorNode", + "name": "upgradeAuthorityMustSign", + "code": 554, + "message": "Current program upgrade authority must sign transaction", + "docs": [ + "UpgradeAuthorityMustSign: Current program upgrade authority must sign transaction" + ] + }, + { + "kind": "errorNode", + "name": "programNotUpgradable", + "code": 555, + "message": "Given program is not upgradable", + "docs": [ + "ProgramNotUpgradable: Given program is not upgradable" + ] + }, + { + "kind": "errorNode", + "name": "invalidTokenOwner", + "code": 556, + "message": "Invalid token owner", + "docs": [ + "InvalidTokenOwner: Invalid token owner" + ] + }, + { + "kind": "errorNode", + "name": "tokenOwnerMustSign", + "code": 557, + "message": "Current token owner must sign transaction", + "docs": [ + "TokenOwnerMustSign: Current token owner must sign transaction" + ] + }, + { + "kind": "errorNode", + "name": "voteThresholdTypeNotSupported", + "code": 558, + "message": "Given VoteThresholdType is not supported", + "docs": [ + "VoteThresholdTypeNotSupported: Given VoteThresholdType is not supported" + ] + }, + { + "kind": "errorNode", + "name": "voteWeightSourceNotSupported", + "code": 559, + "message": "Given VoteWeightSource is not supported", + "docs": [ + "VoteWeightSourceNotSupported: Given VoteWeightSource is not supported" + ] + }, + { + "kind": "errorNode", + "name": "legacy1", + "code": 560, + "message": "Legacy1", + "docs": [ + "Legacy1: Legacy1" + ] + }, + { + "kind": "errorNode", + "name": "governancePdaMustSign", + "code": 561, + "message": "Governance PDA must sign", + "docs": [ + "GovernancePdaMustSign: Governance PDA must sign" + ] + }, + { + "kind": "errorNode", + "name": "transactionAlreadyFlaggedWithError", + "code": 562, + "message": "Transaction already flagged with error", + "docs": [ + "TransactionAlreadyFlaggedWithError: Transaction already flagged with error" + ] + }, + { + "kind": "errorNode", + "name": "invalidRealmForGovernance", + "code": 563, + "message": "Invalid Realm for Governance", + "docs": [ + "InvalidRealmForGovernance: Invalid Realm for Governance" + ] + }, + { + "kind": "errorNode", + "name": "invalidAuthorityForRealm", + "code": 564, + "message": "Invalid Authority for Realm", + "docs": [ + "InvalidAuthorityForRealm: Invalid Authority for Realm" + ] + }, + { + "kind": "errorNode", + "name": "realmHasNoAuthority", + "code": 565, + "message": "Realm has no authority", + "docs": [ + "RealmHasNoAuthority: Realm has no authority" + ] + }, + { + "kind": "errorNode", + "name": "realmAuthorityMustSign", + "code": 566, + "message": "Realm authority must sign", + "docs": [ + "RealmAuthorityMustSign: Realm authority must sign" + ] + }, + { + "kind": "errorNode", + "name": "invalidGoverningTokenHoldingAccount", + "code": 567, + "message": "Invalid governing token holding account", + "docs": [ + "InvalidGoverningTokenHoldingAccount: Invalid governing token holding account" + ] + }, + { + "kind": "errorNode", + "name": "realmCouncilMintChangeIsNotSupported", + "code": 568, + "message": "Realm council mint change is not supported", + "docs": [ + "RealmCouncilMintChangeIsNotSupported: Realm council mint change is not supported" + ] + }, + { + "kind": "errorNode", + "name": "invalidMaxVoterWeightAbsoluteValue", + "code": 569, + "message": "Invalid max voter weight absolute value", + "docs": [ + "InvalidMaxVoterWeightAbsoluteValue: Invalid max voter weight absolute value" + ] + }, + { + "kind": "errorNode", + "name": "invalidMaxVoterWeightSupplyFraction", + "code": 570, + "message": "Invalid max voter weight supply fraction", + "docs": [ + "InvalidMaxVoterWeightSupplyFraction: Invalid max voter weight supply fraction" + ] + }, + { + "kind": "errorNode", + "name": "notEnoughTokensToCreateGovernance", + "code": 571, + "message": "Owner doesn't have enough governing tokens to create Governance", + "docs": [ + "NotEnoughTokensToCreateGovernance: Owner doesn't have enough governing tokens to create Governance" + ] + }, + { + "kind": "errorNode", + "name": "tooManyOutstandingProposals", + "code": 572, + "message": "Too many outstanding proposals", + "docs": [ + "TooManyOutstandingProposals: Too many outstanding proposals" + ] + }, + { + "kind": "errorNode", + "name": "allProposalsMustBeFinalisedToWithdrawGoverningTokens", + "code": 573, + "message": "All proposals must be finalized to withdraw governing tokens", + "docs": [ + "AllProposalsMustBeFinalisedToWithdrawGoverningTokens: All proposals must be finalized to withdraw governing tokens" + ] + }, + { + "kind": "errorNode", + "name": "invalidVoterWeightRecordForRealm", + "code": 574, + "message": "Invalid VoterWeightRecord for Realm", + "docs": [ + "InvalidVoterWeightRecordForRealm: Invalid VoterWeightRecord for Realm" + ] + }, + { + "kind": "errorNode", + "name": "invalidVoterWeightRecordForGoverningTokenMint", + "code": 575, + "message": "Invalid VoterWeightRecord for GoverningTokenMint", + "docs": [ + "InvalidVoterWeightRecordForGoverningTokenMint: Invalid VoterWeightRecord for GoverningTokenMint" + ] + }, + { + "kind": "errorNode", + "name": "invalidVoterWeightRecordForTokenOwner", + "code": 576, + "message": "Invalid VoterWeightRecord for TokenOwner", + "docs": [ + "InvalidVoterWeightRecordForTokenOwner: Invalid VoterWeightRecord for TokenOwner" + ] + }, + { + "kind": "errorNode", + "name": "voterWeightRecordExpired", + "code": 577, + "message": "VoterWeightRecord expired", + "docs": [ + "VoterWeightRecordExpired: VoterWeightRecord expired" + ] + }, + { + "kind": "errorNode", + "name": "invalidRealmConfigForRealm", + "code": 578, + "message": "Invalid RealmConfig for Realm", + "docs": [ + "InvalidRealmConfigForRealm: Invalid RealmConfig for Realm" + ] + }, + { + "kind": "errorNode", + "name": "tokenOwnerRecordAlreadyExists", + "code": 579, + "message": "TokenOwnerRecord already exists", + "docs": [ + "TokenOwnerRecordAlreadyExists: TokenOwnerRecord already exists" + ] + }, + { + "kind": "errorNode", + "name": "governingTokenDepositsNotAllowed", + "code": 580, + "message": "Governing token deposits not allowed", + "docs": [ + "GoverningTokenDepositsNotAllowed: Governing token deposits not allowed" + ] + }, + { + "kind": "errorNode", + "name": "invalidVoteChoiceWeightPercentage", + "code": 581, + "message": "Invalid vote choice weight percentage", + "docs": [ + "InvalidVoteChoiceWeightPercentage: Invalid vote choice weight percentage" + ] + }, + { + "kind": "errorNode", + "name": "voteTypeNotSupported", + "code": 582, + "message": "Vote type not supported", + "docs": [ + "VoteTypeNotSupported: Vote type not supported" + ] + }, + { + "kind": "errorNode", + "name": "invalidProposalOptions", + "code": 583, + "message": "Invalid proposal options", + "docs": [ + "InvalidProposalOptions: Invalid proposal options" + ] + }, + { + "kind": "errorNode", + "name": "proposalIsNotExecutable", + "code": 584, + "message": "Proposal is not not executable", + "docs": [ + "ProposalIsNotExecutable: Proposal is not not executable" + ] + }, + { + "kind": "errorNode", + "name": "denyVoteIsNotAllowed", + "code": 585, + "message": "Deny vote is not allowed", + "docs": [ + "DenyVoteIsNotAllowed: Deny vote is not allowed" + ] + }, + { + "kind": "errorNode", + "name": "cannotExecuteDefeatedOption", + "code": 586, + "message": "Cannot execute defeated option", + "docs": [ + "CannotExecuteDefeatedOption: Cannot execute defeated option" + ] + }, + { + "kind": "errorNode", + "name": "voterWeightRecordInvalidAction", + "code": 587, + "message": "VoterWeightRecord invalid action", + "docs": [ + "VoterWeightRecordInvalidAction: VoterWeightRecord invalid action" + ] + }, + { + "kind": "errorNode", + "name": "voterWeightRecordInvalidActionTarget", + "code": 588, + "message": "VoterWeightRecord invalid action target", + "docs": [ + "VoterWeightRecordInvalidActionTarget: VoterWeightRecord invalid action target" + ] + }, + { + "kind": "errorNode", + "name": "invalidMaxVoterWeightRecordForRealm", + "code": 589, + "message": "Invalid MaxVoterWeightRecord for Realm", + "docs": [ + "InvalidMaxVoterWeightRecordForRealm: Invalid MaxVoterWeightRecord for Realm" + ] + }, + { + "kind": "errorNode", + "name": "invalidMaxVoterWeightRecordForGoverningTokenMint", + "code": 590, + "message": "Invalid MaxVoterWeightRecord for GoverningTokenMint", + "docs": [ + "InvalidMaxVoterWeightRecordForGoverningTokenMint: Invalid MaxVoterWeightRecord for GoverningTokenMint" + ] + }, + { + "kind": "errorNode", + "name": "maxVoterWeightRecordExpired", + "code": 591, + "message": "MaxVoterWeightRecord expired", + "docs": [ + "MaxVoterWeightRecordExpired: MaxVoterWeightRecord expired" + ] + }, + { + "kind": "errorNode", + "name": "notSupportedVoteType", + "code": 592, + "message": "Not supported VoteType", + "docs": [ + "NotSupportedVoteType: Not supported VoteType" + ] + }, + { + "kind": "errorNode", + "name": "realmConfigChangeNotAllowed", + "code": 593, + "message": "RealmConfig change not allowed", + "docs": [ + "RealmConfigChangeNotAllowed: RealmConfig change not allowed" + ] + }, + { + "kind": "errorNode", + "name": "governanceConfigChangeNotAllowed", + "code": 594, + "message": "GovernanceConfig change not allowed", + "docs": [ + "GovernanceConfigChangeNotAllowed: GovernanceConfig change not allowed" + ] + }, + { + "kind": "errorNode", + "name": "atLeastOneVoteThresholdRequired", + "code": 595, + "message": "At least one VoteThreshold is required", + "docs": [ + "AtLeastOneVoteThresholdRequired: At least one VoteThreshold is required" + ] + }, + { + "kind": "errorNode", + "name": "reservedBufferMustBeEmpty", + "code": 596, + "message": "Reserved buffer must be empty", + "docs": [ + "ReservedBufferMustBeEmpty: Reserved buffer must be empty" + ] + }, + { + "kind": "errorNode", + "name": "cannotRelinquishInFinalizingState", + "code": 597, + "message": "Cannot Relinquish in Finalizing state", + "docs": [ + "CannotRelinquishInFinalizingState: Cannot Relinquish in Finalizing state" + ] + }, + { + "kind": "errorNode", + "name": "invalidRealmConfigAddress", + "code": 598, + "message": "Invalid RealmConfig account address", + "docs": [ + "InvalidRealmConfigAddress: Invalid RealmConfig account address" + ] + }, + { + "kind": "errorNode", + "name": "cannotDepositDormantTokens", + "code": 599, + "message": "Cannot deposit dormant tokens", + "docs": [ + "CannotDepositDormantTokens: Cannot deposit dormant tokens" + ] + }, + { + "kind": "errorNode", + "name": "cannotWithdrawMembershipTokens", + "code": 600, + "message": "Cannot withdraw membership tokens", + "docs": [ + "CannotWithdrawMembershipTokens: Cannot withdraw membership tokens" + ] + }, + { + "kind": "errorNode", + "name": "cannotRevokeGoverningTokens", + "code": 601, + "message": "Cannot revoke GoverningTokens", + "docs": [ + "CannotRevokeGoverningTokens: Cannot revoke GoverningTokens" + ] + }, + { + "kind": "errorNode", + "name": "invalidRevokeAmount", + "code": 602, + "message": "Invalid Revoke amount", + "docs": [ + "InvalidRevokeAmount: Invalid Revoke amount" + ] + }, + { + "kind": "errorNode", + "name": "invalidGoverningTokenSource", + "code": 603, + "message": "Invalid GoverningToken source", + "docs": [ + "InvalidGoverningTokenSource: Invalid GoverningToken source" + ] + }, + { + "kind": "errorNode", + "name": "cannotChangeCommunityTokenTypeToMembership", + "code": 604, + "message": "Cannot change community TokenType to Membership", + "docs": [ + "CannotChangeCommunityTokenTypeToMembership: Cannot change community TokenType to Membership" + ] + }, + { + "kind": "errorNode", + "name": "voterWeightThresholdDisabled", + "code": 605, + "message": "Voter weight threshold disabled", + "docs": [ + "VoterWeightThresholdDisabled: Voter weight threshold disabled" + ] + }, + { + "kind": "errorNode", + "name": "voteNotAllowedInCoolOffTime", + "code": 606, + "message": "Vote not allowed in cool off time", + "docs": [ + "VoteNotAllowedInCoolOffTime: Vote not allowed in cool off time" + ] + }, + { + "kind": "errorNode", + "name": "cannotRefundProposalDeposit", + "code": 607, + "message": "Cannot refund ProposalDeposit", + "docs": [ + "CannotRefundProposalDeposit: Cannot refund ProposalDeposit" + ] + }, + { + "kind": "errorNode", + "name": "invalidProposalForProposalDeposit", + "code": 608, + "message": "Invalid Proposal for ProposalDeposit", + "docs": [ + "InvalidProposalForProposalDeposit: Invalid Proposal for ProposalDeposit" + ] + }, + { + "kind": "errorNode", + "name": "invalidDepositExemptProposalCount", + "code": 609, + "message": "Invalid deposit_exempt_proposal_count", + "docs": [ + "InvalidDepositExemptProposalCount: Invalid deposit_exempt_proposal_count" + ] + }, + { + "kind": "errorNode", + "name": "governingTokenMintNotAllowedToVote", + "code": 610, + "message": "GoverningTokenMint not allowed to vote", + "docs": [ + "GoverningTokenMintNotAllowedToVote: GoverningTokenMint not allowed to vote" + ] + }, + { + "kind": "errorNode", + "name": "invalidDepositPayerForProposalDeposit", + "code": 611, + "message": "Invalid deposit Payer for ProposalDeposit", + "docs": [ + "InvalidDepositPayerForProposalDeposit: Invalid deposit Payer for ProposalDeposit" + ] + }, + { + "kind": "errorNode", + "name": "invalidStateNotFinal", + "code": 612, + "message": "Invalid State: Proposal is not in final state", + "docs": [ + "InvalidStateNotFinal: Invalid State: Proposal is not in final state" + ] + }, + { + "kind": "errorNode", + "name": "invalidStateToCompleteProposal", + "code": 613, + "message": "Invalid state for proposal state transition to Completed", + "docs": [ + "InvalidStateToCompleteProposal: Invalid state for proposal state transition to Completed" + ] + }, + { + "kind": "errorNode", + "name": "invalidNumberOfVoteChoices", + "code": 614, + "message": "Invalid number of vote choices", + "docs": [ + "InvalidNumberOfVoteChoices: Invalid number of vote choices" + ] + }, + { + "kind": "errorNode", + "name": "rankedVoteIsNotSupported", + "code": 615, + "message": "Ranked vote is not supported", + "docs": [ + "RankedVoteIsNotSupported: Ranked vote is not supported" + ] + }, + { + "kind": "errorNode", + "name": "choiceWeightMustBe100Percent", + "code": 616, + "message": "Choice weight must be 100%", + "docs": [ + "ChoiceWeightMustBe100Percent: Choice weight must be 100%" + ] + }, + { + "kind": "errorNode", + "name": "singleChoiceOnlyIsAllowed", + "code": 617, + "message": "Single choice only is allowed", + "docs": [ + "SingleChoiceOnlyIsAllowed: Single choice only is allowed" + ] + }, + { + "kind": "errorNode", + "name": "atLeastSingleChoiceIsRequired", + "code": 618, + "message": "At least single choice is required", + "docs": [ + "AtLeastSingleChoiceIsRequired: At least single choice is required" + ] + }, + { + "kind": "errorNode", + "name": "totalVoteWeightMustBe100Percent", + "code": 619, + "message": "Total vote weight must be 100%", + "docs": [ + "TotalVoteWeightMustBe100Percent: Total vote weight must be 100%" + ] + }, + { + "kind": "errorNode", + "name": "invalidMultiChoiceProposalParameters", + "code": 620, + "message": "Invalid multi choice proposal parameters", + "docs": [ + "InvalidMultiChoiceProposalParameters: Invalid multi choice proposal parameters" + ] + }, + { + "kind": "errorNode", + "name": "invalidGovernanceForRequiredSignatory", + "code": 621, + "message": "Invalid Governance for RequiredSignatory", + "docs": [ + "InvalidGovernanceForRequiredSignatory: Invalid Governance for RequiredSignatory" + ] + }, + { + "kind": "errorNode", + "name": "signatoryRecordAlreadyExists", + "code": 622, + "message": "Signatory Record has already been created", + "docs": [ + "SignatoryRecordAlreadyExists: Signatory Record has already been created" + ] + }, + { + "kind": "errorNode", + "name": "instructionDeprecated", + "code": 623, + "message": "Instruction has been removed", + "docs": [ + "InstructionDeprecated: Instruction has been removed" + ] + }, + { + "kind": "errorNode", + "name": "missingRequiredSignatories", + "code": 624, + "message": "Proposal is missing required signatories", + "docs": [ + "MissingRequiredSignatories: Proposal is missing required signatories" + ] + } + ] + }, + "additionalPrograms": [] +} diff --git a/e2e/governance/src/generated/accounts/governance_v1.rs b/e2e/governance/src/generated/accounts/governance_v1.rs new file mode 100644 index 0000000..c7fb13e --- /dev/null +++ b/e2e/governance/src/generated/accounts/governance_v1.rs @@ -0,0 +1,178 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceAccountType; +use crate::generated::types::GovernanceConfig; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct GovernanceV1 { + pub account_type: GovernanceAccountType, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub realm: Pubkey, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub governed_account: Pubkey, + pub proposals_count: u32, + pub config: GovernanceConfig, +} + +impl GovernanceV1 { + /// Prefix values used to generate a PDA for this account. + /// + /// Values are positional and appear in the following order: + /// + /// 0. `GovernanceV1::PREFIX` + /// 1. realm (`Pubkey`) + /// 2. seed (`Pubkey`) + pub const PREFIX: &'static [u8] = "account-governance".as_bytes(); + + pub fn create_pda( + realm: Pubkey, + seed: Pubkey, + bump: u8, + ) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + "account-governance".as_bytes(), + realm.as_ref(), + seed.as_ref(), + &[bump], + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + pub fn find_pda(realm: &Pubkey, seed: &Pubkey) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + "account-governance".as_bytes(), + realm.as_ref(), + seed.as_ref(), + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + #[inline(always)] + pub fn from_bytes(data: &[u8]) -> Result { + let mut data = data; + Self::deserialize(&mut data) + } +} + +impl<'a> TryFrom<&solana_account_info::AccountInfo<'a>> for GovernanceV1 { + type Error = std::io::Error; + + fn try_from(account_info: &solana_account_info::AccountInfo<'a>) -> Result { + let mut data: &[u8] = &(*account_info.data).borrow(); + Self::deserialize(&mut data) + } +} + +#[cfg(feature = "fetch")] +pub fn fetch_governance_v1( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_governance_v1(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_governance_v1( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + let account = accounts[i].as_ref().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Account not found: {}", address), + ))?; + let data = GovernanceV1::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }); + } + Ok(decoded_accounts) +} + +#[cfg(feature = "fetch")] +pub fn fetch_maybe_governance_v1( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_maybe_governance_v1(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_maybe_governance_v1( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + if let Some(account) = accounts[i].as_ref() { + let data = GovernanceV1::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::MaybeAccount::Exists( + crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }, + )); + } else { + decoded_accounts.push(crate::shared::MaybeAccount::NotFound(address)); + } + } + Ok(decoded_accounts) +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountDeserialize for GovernanceV1 { + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + Ok(Self::deserialize(buf)?) + } +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountSerialize for GovernanceV1 {} + +#[cfg(feature = "anchor")] +impl anchor_lang::Owner for GovernanceV1 { + fn owner() -> Pubkey { + crate::SPL_GOVERNANCE_ID + } +} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::IdlBuild for GovernanceV1 {} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::Discriminator for GovernanceV1 { + const DISCRIMINATOR: &[u8] = &[0; 8]; +} diff --git a/e2e/governance/src/generated/accounts/governance_v2.rs b/e2e/governance/src/generated/accounts/governance_v2.rs new file mode 100644 index 0000000..85e117f --- /dev/null +++ b/e2e/governance/src/generated/accounts/governance_v2.rs @@ -0,0 +1,182 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceAccountType; +use crate::generated::types::GovernanceConfig; +use crate::generated::types::Reserved119; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct GovernanceV2 { + pub account_type: GovernanceAccountType, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub realm: Pubkey, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub governed_account: Pubkey, + pub reserved1: u32, + pub config: GovernanceConfig, + pub reserved_v2: Reserved119, + pub required_signatories_count: u8, + pub active_proposal_count: u64, +} + +impl GovernanceV2 { + /// Prefix values used to generate a PDA for this account. + /// + /// Values are positional and appear in the following order: + /// + /// 0. `GovernanceV2::PREFIX` + /// 1. realm (`Pubkey`) + /// 2. seed (`Pubkey`) + pub const PREFIX: &'static [u8] = "account-governance".as_bytes(); + + pub fn create_pda( + realm: Pubkey, + seed: Pubkey, + bump: u8, + ) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + "account-governance".as_bytes(), + realm.as_ref(), + seed.as_ref(), + &[bump], + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + pub fn find_pda(realm: &Pubkey, seed: &Pubkey) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + "account-governance".as_bytes(), + realm.as_ref(), + seed.as_ref(), + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + #[inline(always)] + pub fn from_bytes(data: &[u8]) -> Result { + let mut data = data; + Self::deserialize(&mut data) + } +} + +impl<'a> TryFrom<&solana_account_info::AccountInfo<'a>> for GovernanceV2 { + type Error = std::io::Error; + + fn try_from(account_info: &solana_account_info::AccountInfo<'a>) -> Result { + let mut data: &[u8] = &(*account_info.data).borrow(); + Self::deserialize(&mut data) + } +} + +#[cfg(feature = "fetch")] +pub fn fetch_governance_v2( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_governance_v2(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_governance_v2( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + let account = accounts[i].as_ref().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Account not found: {}", address), + ))?; + let data = GovernanceV2::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }); + } + Ok(decoded_accounts) +} + +#[cfg(feature = "fetch")] +pub fn fetch_maybe_governance_v2( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_maybe_governance_v2(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_maybe_governance_v2( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + if let Some(account) = accounts[i].as_ref() { + let data = GovernanceV2::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::MaybeAccount::Exists( + crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }, + )); + } else { + decoded_accounts.push(crate::shared::MaybeAccount::NotFound(address)); + } + } + Ok(decoded_accounts) +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountDeserialize for GovernanceV2 { + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + Ok(Self::deserialize(buf)?) + } +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountSerialize for GovernanceV2 {} + +#[cfg(feature = "anchor")] +impl anchor_lang::Owner for GovernanceV2 { + fn owner() -> Pubkey { + crate::SPL_GOVERNANCE_ID + } +} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::IdlBuild for GovernanceV2 {} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::Discriminator for GovernanceV2 { + const DISCRIMINATOR: &[u8] = &[0; 8]; +} diff --git a/e2e/governance/src/generated/accounts/legacy_token_owner_record.rs b/e2e/governance/src/generated/accounts/legacy_token_owner_record.rs new file mode 100644 index 0000000..0547d43 --- /dev/null +++ b/e2e/governance/src/generated/accounts/legacy_token_owner_record.rs @@ -0,0 +1,197 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceAccountType; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct LegacyTokenOwnerRecord { + pub account_type: GovernanceAccountType, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub realm: Pubkey, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub governing_token_mint: Pubkey, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub governing_token_owner: Pubkey, + pub governing_token_deposit_amount: u64, + pub unrelinquished_votes_count: u32, + pub total_votes_count: u32, + pub outstanding_proposal_count: u8, + pub reserved: [u8; 7], + pub governance_delegate: Option, + #[cfg_attr(feature = "serde", serde(with = "serde_big_array::BigArray"))] + pub reserved_v2: [u8; 128], +} + +impl LegacyTokenOwnerRecord { + /// Prefix values used to generate a PDA for this account. + /// + /// Values are positional and appear in the following order: + /// + /// 0. `LegacyTokenOwnerRecord::PREFIX` + /// 1. realm (`Pubkey`) + /// 2. governing_token_mint (`Pubkey`) + /// 3. governing_token_owner (`Pubkey`) + pub const PREFIX: &'static [u8] = "governance".as_bytes(); + + pub fn create_pda( + realm: Pubkey, + governing_token_mint: Pubkey, + governing_token_owner: Pubkey, + bump: u8, + ) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + "governance".as_bytes(), + realm.as_ref(), + governing_token_mint.as_ref(), + governing_token_owner.as_ref(), + &[bump], + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + pub fn find_pda( + realm: &Pubkey, + governing_token_mint: &Pubkey, + governing_token_owner: &Pubkey, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + "governance".as_bytes(), + realm.as_ref(), + governing_token_mint.as_ref(), + governing_token_owner.as_ref(), + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + #[inline(always)] + pub fn from_bytes(data: &[u8]) -> Result { + let mut data = data; + Self::deserialize(&mut data) + } +} + +impl<'a> TryFrom<&solana_account_info::AccountInfo<'a>> for LegacyTokenOwnerRecord { + type Error = std::io::Error; + + fn try_from(account_info: &solana_account_info::AccountInfo<'a>) -> Result { + let mut data: &[u8] = &(*account_info.data).borrow(); + Self::deserialize(&mut data) + } +} + +#[cfg(feature = "fetch")] +pub fn fetch_legacy_token_owner_record( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_legacy_token_owner_record(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_legacy_token_owner_record( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = + Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + let account = accounts[i].as_ref().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Account not found: {}", address), + ))?; + let data = LegacyTokenOwnerRecord::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }); + } + Ok(decoded_accounts) +} + +#[cfg(feature = "fetch")] +pub fn fetch_maybe_legacy_token_owner_record( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_maybe_legacy_token_owner_record(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_maybe_legacy_token_owner_record( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + if let Some(account) = accounts[i].as_ref() { + let data = LegacyTokenOwnerRecord::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::MaybeAccount::Exists( + crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }, + )); + } else { + decoded_accounts.push(crate::shared::MaybeAccount::NotFound(address)); + } + } + Ok(decoded_accounts) +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountDeserialize for LegacyTokenOwnerRecord { + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + Ok(Self::deserialize(buf)?) + } +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountSerialize for LegacyTokenOwnerRecord {} + +#[cfg(feature = "anchor")] +impl anchor_lang::Owner for LegacyTokenOwnerRecord { + fn owner() -> Pubkey { + crate::SPL_GOVERNANCE_ID + } +} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::IdlBuild for LegacyTokenOwnerRecord {} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::Discriminator for LegacyTokenOwnerRecord { + const DISCRIMINATOR: &[u8] = &[0; 8]; +} diff --git a/e2e/governance/src/generated/accounts/mod.rs b/e2e/governance/src/generated/accounts/mod.rs new file mode 100644 index 0000000..4160ab4 --- /dev/null +++ b/e2e/governance/src/generated/accounts/mod.rs @@ -0,0 +1,46 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +pub(crate) mod r#governance_v1; +pub(crate) mod r#governance_v2; +pub(crate) mod r#legacy_token_owner_record; +pub(crate) mod r#program_metadata; +pub(crate) mod r#proposal_deposit; +pub(crate) mod r#proposal_instruction_v1; +pub(crate) mod r#proposal_transaction_v2; +pub(crate) mod r#proposal_v1; +pub(crate) mod r#proposal_v2; +pub(crate) mod r#realm_config_account; +pub(crate) mod r#realm_v1; +pub(crate) mod r#realm_v2; +pub(crate) mod r#required_signatory; +pub(crate) mod r#signatory_record_v1; +pub(crate) mod r#signatory_record_v2; +pub(crate) mod r#token_owner_record_v1; +pub(crate) mod r#token_owner_record_v2; +pub(crate) mod r#vote_record_v1; +pub(crate) mod r#vote_record_v2; + +pub use self::r#governance_v1::*; +pub use self::r#governance_v2::*; +pub use self::r#legacy_token_owner_record::*; +pub use self::r#program_metadata::*; +pub use self::r#proposal_deposit::*; +pub use self::r#proposal_instruction_v1::*; +pub use self::r#proposal_transaction_v2::*; +pub use self::r#proposal_v1::*; +pub use self::r#proposal_v2::*; +pub use self::r#realm_config_account::*; +pub use self::r#realm_v1::*; +pub use self::r#realm_v2::*; +pub use self::r#required_signatory::*; +pub use self::r#signatory_record_v1::*; +pub use self::r#signatory_record_v2::*; +pub use self::r#token_owner_record_v1::*; +pub use self::r#token_owner_record_v2::*; +pub use self::r#vote_record_v1::*; +pub use self::r#vote_record_v2::*; diff --git a/e2e/governance/src/generated/accounts/program_metadata.rs b/e2e/governance/src/generated/accounts/program_metadata.rs new file mode 100644 index 0000000..5e2b867 --- /dev/null +++ b/e2e/governance/src/generated/accounts/program_metadata.rs @@ -0,0 +1,133 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceAccountType; +use crate::generated::types::Slot; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ProgramMetadata { + pub account_type: GovernanceAccountType, + pub updated_at: Slot, + pub version: String, + #[cfg_attr(feature = "serde", serde(with = "serde_big_array::BigArray"))] + pub reserved: [u8; 64], +} + +impl ProgramMetadata { + #[inline(always)] + pub fn from_bytes(data: &[u8]) -> Result { + let mut data = data; + Self::deserialize(&mut data) + } +} + +impl<'a> TryFrom<&solana_account_info::AccountInfo<'a>> for ProgramMetadata { + type Error = std::io::Error; + + fn try_from(account_info: &solana_account_info::AccountInfo<'a>) -> Result { + let mut data: &[u8] = &(*account_info.data).borrow(); + Self::deserialize(&mut data) + } +} + +#[cfg(feature = "fetch")] +pub fn fetch_program_metadata( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_program_metadata(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_program_metadata( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + let account = accounts[i].as_ref().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Account not found: {}", address), + ))?; + let data = ProgramMetadata::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }); + } + Ok(decoded_accounts) +} + +#[cfg(feature = "fetch")] +pub fn fetch_maybe_program_metadata( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_maybe_program_metadata(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_maybe_program_metadata( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + if let Some(account) = accounts[i].as_ref() { + let data = ProgramMetadata::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::MaybeAccount::Exists( + crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }, + )); + } else { + decoded_accounts.push(crate::shared::MaybeAccount::NotFound(address)); + } + } + Ok(decoded_accounts) +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountDeserialize for ProgramMetadata { + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + Ok(Self::deserialize(buf)?) + } +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountSerialize for ProgramMetadata {} + +#[cfg(feature = "anchor")] +impl anchor_lang::Owner for ProgramMetadata { + fn owner() -> Pubkey { + crate::SPL_GOVERNANCE_ID + } +} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::IdlBuild for ProgramMetadata {} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::Discriminator for ProgramMetadata { + const DISCRIMINATOR: &[u8] = &[0; 8]; +} diff --git a/e2e/governance/src/generated/accounts/proposal_deposit.rs b/e2e/governance/src/generated/accounts/proposal_deposit.rs new file mode 100644 index 0000000..695552b --- /dev/null +++ b/e2e/governance/src/generated/accounts/proposal_deposit.rs @@ -0,0 +1,177 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceAccountType; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ProposalDeposit { + pub account_type: GovernanceAccountType, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub proposal: Pubkey, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub deposit_payer: Pubkey, + #[cfg_attr(feature = "serde", serde(with = "serde_big_array::BigArray"))] + pub reserved: [u8; 64], +} + +impl ProposalDeposit { + /// Prefix values used to generate a PDA for this account. + /// + /// Values are positional and appear in the following order: + /// + /// 0. `ProposalDeposit::PREFIX` + /// 1. proposal (`Pubkey`) + /// 2. deposit_payer (`Pubkey`) + pub const PREFIX: &'static [u8] = "proposal-deposit".as_bytes(); + + pub fn create_pda( + proposal: Pubkey, + deposit_payer: Pubkey, + bump: u8, + ) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + "proposal-deposit".as_bytes(), + proposal.as_ref(), + deposit_payer.as_ref(), + &[bump], + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + pub fn find_pda(proposal: &Pubkey, deposit_payer: &Pubkey) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + "proposal-deposit".as_bytes(), + proposal.as_ref(), + deposit_payer.as_ref(), + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + #[inline(always)] + pub fn from_bytes(data: &[u8]) -> Result { + let mut data = data; + Self::deserialize(&mut data) + } +} + +impl<'a> TryFrom<&solana_account_info::AccountInfo<'a>> for ProposalDeposit { + type Error = std::io::Error; + + fn try_from(account_info: &solana_account_info::AccountInfo<'a>) -> Result { + let mut data: &[u8] = &(*account_info.data).borrow(); + Self::deserialize(&mut data) + } +} + +#[cfg(feature = "fetch")] +pub fn fetch_proposal_deposit( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_proposal_deposit(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_proposal_deposit( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + let account = accounts[i].as_ref().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Account not found: {}", address), + ))?; + let data = ProposalDeposit::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }); + } + Ok(decoded_accounts) +} + +#[cfg(feature = "fetch")] +pub fn fetch_maybe_proposal_deposit( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_maybe_proposal_deposit(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_maybe_proposal_deposit( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + if let Some(account) = accounts[i].as_ref() { + let data = ProposalDeposit::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::MaybeAccount::Exists( + crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }, + )); + } else { + decoded_accounts.push(crate::shared::MaybeAccount::NotFound(address)); + } + } + Ok(decoded_accounts) +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountDeserialize for ProposalDeposit { + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + Ok(Self::deserialize(buf)?) + } +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountSerialize for ProposalDeposit {} + +#[cfg(feature = "anchor")] +impl anchor_lang::Owner for ProposalDeposit { + fn owner() -> Pubkey { + crate::SPL_GOVERNANCE_ID + } +} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::IdlBuild for ProposalDeposit {} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::Discriminator for ProposalDeposit { + const DISCRIMINATOR: &[u8] = &[0; 8]; +} diff --git a/e2e/governance/src/generated/accounts/proposal_instruction_v1.rs b/e2e/governance/src/generated/accounts/proposal_instruction_v1.rs new file mode 100644 index 0000000..28df3ab --- /dev/null +++ b/e2e/governance/src/generated/accounts/proposal_instruction_v1.rs @@ -0,0 +1,187 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceAccountType; +use crate::generated::types::InstructionData; +use crate::generated::types::TransactionExecutionStatus; +use crate::generated::types::UnixTimestamp; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ProposalInstructionV1 { + pub account_type: GovernanceAccountType, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub proposal: Pubkey, + pub instruction_index: u16, + pub hold_up_time: u32, + pub instruction: InstructionData, + pub executed_at: Option, + pub execution_status: TransactionExecutionStatus, +} + +impl ProposalInstructionV1 { + /// Prefix values used to generate a PDA for this account. + /// + /// Values are positional and appear in the following order: + /// + /// 0. `ProposalInstructionV1::PREFIX` + /// 1. proposal (`Pubkey`) + /// 2. option_index (`u8`) + /// 3. index (`u16`) + pub const PREFIX: &'static [u8] = "governance".as_bytes(); + + pub fn create_pda( + proposal: Pubkey, + option_index: u8, + index: u16, + bump: u8, + ) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + "governance".as_bytes(), + proposal.as_ref(), + option_index.to_string().as_ref(), + index.to_string().as_ref(), + &[bump], + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + pub fn find_pda( + proposal: &Pubkey, + option_index: u8, + index: u16, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + "governance".as_bytes(), + proposal.as_ref(), + option_index.to_string().as_ref(), + index.to_string().as_ref(), + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + #[inline(always)] + pub fn from_bytes(data: &[u8]) -> Result { + let mut data = data; + Self::deserialize(&mut data) + } +} + +impl<'a> TryFrom<&solana_account_info::AccountInfo<'a>> for ProposalInstructionV1 { + type Error = std::io::Error; + + fn try_from(account_info: &solana_account_info::AccountInfo<'a>) -> Result { + let mut data: &[u8] = &(*account_info.data).borrow(); + Self::deserialize(&mut data) + } +} + +#[cfg(feature = "fetch")] +pub fn fetch_proposal_instruction_v1( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_proposal_instruction_v1(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_proposal_instruction_v1( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = + Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + let account = accounts[i].as_ref().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Account not found: {}", address), + ))?; + let data = ProposalInstructionV1::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }); + } + Ok(decoded_accounts) +} + +#[cfg(feature = "fetch")] +pub fn fetch_maybe_proposal_instruction_v1( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_maybe_proposal_instruction_v1(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_maybe_proposal_instruction_v1( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + if let Some(account) = accounts[i].as_ref() { + let data = ProposalInstructionV1::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::MaybeAccount::Exists( + crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }, + )); + } else { + decoded_accounts.push(crate::shared::MaybeAccount::NotFound(address)); + } + } + Ok(decoded_accounts) +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountDeserialize for ProposalInstructionV1 { + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + Ok(Self::deserialize(buf)?) + } +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountSerialize for ProposalInstructionV1 {} + +#[cfg(feature = "anchor")] +impl anchor_lang::Owner for ProposalInstructionV1 { + fn owner() -> Pubkey { + crate::SPL_GOVERNANCE_ID + } +} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::IdlBuild for ProposalInstructionV1 {} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::Discriminator for ProposalInstructionV1 { + const DISCRIMINATOR: &[u8] = &[0; 8]; +} diff --git a/e2e/governance/src/generated/accounts/proposal_transaction_v2.rs b/e2e/governance/src/generated/accounts/proposal_transaction_v2.rs new file mode 100644 index 0000000..9fa1d2e --- /dev/null +++ b/e2e/governance/src/generated/accounts/proposal_transaction_v2.rs @@ -0,0 +1,189 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceAccountType; +use crate::generated::types::InstructionData; +use crate::generated::types::TransactionExecutionStatus; +use crate::generated::types::UnixTimestamp; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ProposalTransactionV2 { + pub account_type: GovernanceAccountType, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub proposal: Pubkey, + pub option_index: u8, + pub transaction_index: u16, + pub hold_up_time: u32, + pub instructions: Vec, + pub executed_at: Option, + pub execution_status: TransactionExecutionStatus, + pub reserved_v2: [u8; 8], +} + +impl ProposalTransactionV2 { + /// Prefix values used to generate a PDA for this account. + /// + /// Values are positional and appear in the following order: + /// + /// 0. `ProposalTransactionV2::PREFIX` + /// 1. proposal (`Pubkey`) + /// 2. option_index (`u8`) + /// 3. index (`u16`) + pub const PREFIX: &'static [u8] = "governance".as_bytes(); + + pub fn create_pda( + proposal: Pubkey, + option_index: u8, + index: u16, + bump: u8, + ) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + "governance".as_bytes(), + proposal.as_ref(), + option_index.to_string().as_ref(), + index.to_string().as_ref(), + &[bump], + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + pub fn find_pda( + proposal: &Pubkey, + option_index: u8, + index: u16, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + "governance".as_bytes(), + proposal.as_ref(), + option_index.to_string().as_ref(), + index.to_string().as_ref(), + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + #[inline(always)] + pub fn from_bytes(data: &[u8]) -> Result { + let mut data = data; + Self::deserialize(&mut data) + } +} + +impl<'a> TryFrom<&solana_account_info::AccountInfo<'a>> for ProposalTransactionV2 { + type Error = std::io::Error; + + fn try_from(account_info: &solana_account_info::AccountInfo<'a>) -> Result { + let mut data: &[u8] = &(*account_info.data).borrow(); + Self::deserialize(&mut data) + } +} + +#[cfg(feature = "fetch")] +pub fn fetch_proposal_transaction_v2( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_proposal_transaction_v2(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_proposal_transaction_v2( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = + Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + let account = accounts[i].as_ref().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Account not found: {}", address), + ))?; + let data = ProposalTransactionV2::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }); + } + Ok(decoded_accounts) +} + +#[cfg(feature = "fetch")] +pub fn fetch_maybe_proposal_transaction_v2( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_maybe_proposal_transaction_v2(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_maybe_proposal_transaction_v2( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + if let Some(account) = accounts[i].as_ref() { + let data = ProposalTransactionV2::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::MaybeAccount::Exists( + crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }, + )); + } else { + decoded_accounts.push(crate::shared::MaybeAccount::NotFound(address)); + } + } + Ok(decoded_accounts) +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountDeserialize for ProposalTransactionV2 { + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + Ok(Self::deserialize(buf)?) + } +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountSerialize for ProposalTransactionV2 {} + +#[cfg(feature = "anchor")] +impl anchor_lang::Owner for ProposalTransactionV2 { + fn owner() -> Pubkey { + crate::SPL_GOVERNANCE_ID + } +} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::IdlBuild for ProposalTransactionV2 {} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::Discriminator for ProposalTransactionV2 { + const DISCRIMINATOR: &[u8] = &[0; 8]; +} diff --git a/e2e/governance/src/generated/accounts/proposal_v1.rs b/e2e/governance/src/generated/accounts/proposal_v1.rs new file mode 100644 index 0000000..7c68cb4 --- /dev/null +++ b/e2e/governance/src/generated/accounts/proposal_v1.rs @@ -0,0 +1,213 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceAccountType; +use crate::generated::types::InstructionExecutionFlags; +use crate::generated::types::ProposalState; +use crate::generated::types::Slot; +use crate::generated::types::UnixTimestamp; +use crate::generated::types::VoteThreshold; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ProposalV1 { + pub account_type: GovernanceAccountType, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub governance: Pubkey, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub governing_token_mint: Pubkey, + pub state: ProposalState, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub token_owner_record: Pubkey, + pub signatories_count: u8, + pub signatories_signed_off_count: u8, + pub yes_votes_count: u64, + pub no_votes_count: u64, + pub instructions_executed_count: u16, + pub instructions_count: u16, + pub instructions_next_index: u16, + pub draft_at: UnixTimestamp, + pub signing_off_at: Option, + pub voting_at: Option, + pub voting_at_slot: Option, + pub voting_completed_at: Option, + pub executing_at: Option, + pub closed_at: Option, + pub execution_flags: InstructionExecutionFlags, + pub max_vote_weight: Option, + pub vote_threshold: Option, + pub name: String, + pub description_link: String, +} + +impl ProposalV1 { + /// Prefix values used to generate a PDA for this account. + /// + /// Values are positional and appear in the following order: + /// + /// 0. `ProposalV1::PREFIX` + /// 1. governance (`Pubkey`) + /// 2. governing_token_mint (`Pubkey`) + /// 3. proposal_seed (`Pubkey`) + pub const PREFIX: &'static [u8] = "governance".as_bytes(); + + pub fn create_pda( + governance: Pubkey, + governing_token_mint: Pubkey, + proposal_seed: Pubkey, + bump: u8, + ) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + "governance".as_bytes(), + governance.as_ref(), + governing_token_mint.as_ref(), + proposal_seed.as_ref(), + &[bump], + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + pub fn find_pda( + governance: &Pubkey, + governing_token_mint: &Pubkey, + proposal_seed: &Pubkey, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + "governance".as_bytes(), + governance.as_ref(), + governing_token_mint.as_ref(), + proposal_seed.as_ref(), + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + #[inline(always)] + pub fn from_bytes(data: &[u8]) -> Result { + let mut data = data; + Self::deserialize(&mut data) + } +} + +impl<'a> TryFrom<&solana_account_info::AccountInfo<'a>> for ProposalV1 { + type Error = std::io::Error; + + fn try_from(account_info: &solana_account_info::AccountInfo<'a>) -> Result { + let mut data: &[u8] = &(*account_info.data).borrow(); + Self::deserialize(&mut data) + } +} + +#[cfg(feature = "fetch")] +pub fn fetch_proposal_v1( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_proposal_v1(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_proposal_v1( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + let account = accounts[i].as_ref().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Account not found: {}", address), + ))?; + let data = ProposalV1::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }); + } + Ok(decoded_accounts) +} + +#[cfg(feature = "fetch")] +pub fn fetch_maybe_proposal_v1( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_maybe_proposal_v1(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_maybe_proposal_v1( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + if let Some(account) = accounts[i].as_ref() { + let data = ProposalV1::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::MaybeAccount::Exists( + crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }, + )); + } else { + decoded_accounts.push(crate::shared::MaybeAccount::NotFound(address)); + } + } + Ok(decoded_accounts) +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountDeserialize for ProposalV1 { + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + Ok(Self::deserialize(buf)?) + } +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountSerialize for ProposalV1 {} + +#[cfg(feature = "anchor")] +impl anchor_lang::Owner for ProposalV1 { + fn owner() -> Pubkey { + crate::SPL_GOVERNANCE_ID + } +} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::IdlBuild for ProposalV1 {} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::Discriminator for ProposalV1 { + const DISCRIMINATOR: &[u8] = &[0; 8]; +} diff --git a/e2e/governance/src/generated/accounts/proposal_v2.rs b/e2e/governance/src/generated/accounts/proposal_v2.rs new file mode 100644 index 0000000..772d940 --- /dev/null +++ b/e2e/governance/src/generated/accounts/proposal_v2.rs @@ -0,0 +1,220 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceAccountType; +use crate::generated::types::InstructionExecutionFlags; +use crate::generated::types::ProposalOption; +use crate::generated::types::ProposalState; +use crate::generated::types::Slot; +use crate::generated::types::UnixTimestamp; +use crate::generated::types::VoteThreshold; +use crate::generated::types::VoteType; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ProposalV2 { + pub account_type: GovernanceAccountType, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub governance: Pubkey, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub governing_token_mint: Pubkey, + pub state: ProposalState, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub token_owner_record: Pubkey, + pub signatories_count: u8, + pub signatories_signed_off_count: u8, + pub vote_type: VoteType, + pub options: Vec, + pub deny_vote_weight: Option, + pub reserved1: u8, + pub abstain_vote_weight: Option, + pub start_voting_at: Option, + pub draft_at: UnixTimestamp, + pub signing_off_at: Option, + pub voting_at: Option, + pub voting_at_slot: Option, + pub voting_completed_at: Option, + pub executing_at: Option, + pub closed_at: Option, + pub execution_flags: InstructionExecutionFlags, + pub max_vote_weight: Option, + pub max_voting_time: Option, + pub vote_threshold: Option, + #[cfg_attr(feature = "serde", serde(with = "serde_big_array::BigArray"))] + pub reserved: [u8; 64], + pub name: String, + pub description_link: String, + pub veto_vote_weight: u64, +} + +impl ProposalV2 { + /// Prefix values used to generate a PDA for this account. + /// + /// Values are positional and appear in the following order: + /// + /// 0. `ProposalV2::PREFIX` + /// 1. governance (`Pubkey`) + /// 2. governing_token_mint (`Pubkey`) + /// 3. proposal_seed (`Pubkey`) + pub const PREFIX: &'static [u8] = "governance".as_bytes(); + + pub fn create_pda( + governance: Pubkey, + governing_token_mint: Pubkey, + proposal_seed: Pubkey, + bump: u8, + ) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + "governance".as_bytes(), + governance.as_ref(), + governing_token_mint.as_ref(), + proposal_seed.as_ref(), + &[bump], + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + pub fn find_pda( + governance: &Pubkey, + governing_token_mint: &Pubkey, + proposal_seed: &Pubkey, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + "governance".as_bytes(), + governance.as_ref(), + governing_token_mint.as_ref(), + proposal_seed.as_ref(), + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + #[inline(always)] + pub fn from_bytes(data: &[u8]) -> Result { + let mut data = data; + Self::deserialize(&mut data) + } +} + +impl<'a> TryFrom<&solana_account_info::AccountInfo<'a>> for ProposalV2 { + type Error = std::io::Error; + + fn try_from(account_info: &solana_account_info::AccountInfo<'a>) -> Result { + let mut data: &[u8] = &(*account_info.data).borrow(); + Self::deserialize(&mut data) + } +} + +#[cfg(feature = "fetch")] +pub fn fetch_proposal_v2( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_proposal_v2(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_proposal_v2( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + let account = accounts[i].as_ref().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Account not found: {}", address), + ))?; + let data = ProposalV2::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }); + } + Ok(decoded_accounts) +} + +#[cfg(feature = "fetch")] +pub fn fetch_maybe_proposal_v2( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_maybe_proposal_v2(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_maybe_proposal_v2( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + if let Some(account) = accounts[i].as_ref() { + let data = ProposalV2::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::MaybeAccount::Exists( + crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }, + )); + } else { + decoded_accounts.push(crate::shared::MaybeAccount::NotFound(address)); + } + } + Ok(decoded_accounts) +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountDeserialize for ProposalV2 { + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + Ok(Self::deserialize(buf)?) + } +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountSerialize for ProposalV2 {} + +#[cfg(feature = "anchor")] +impl anchor_lang::Owner for ProposalV2 { + fn owner() -> Pubkey { + crate::SPL_GOVERNANCE_ID + } +} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::IdlBuild for ProposalV2 {} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::Discriminator for ProposalV2 { + const DISCRIMINATOR: &[u8] = &[0; 8]; +} diff --git a/e2e/governance/src/generated/accounts/realm_config_account.rs b/e2e/governance/src/generated/accounts/realm_config_account.rs new file mode 100644 index 0000000..2892b1b --- /dev/null +++ b/e2e/governance/src/generated/accounts/realm_config_account.rs @@ -0,0 +1,164 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceAccountType; +use crate::generated::types::GoverningTokenConfig; +use crate::generated::types::Reserved110; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct RealmConfigAccount { + pub account_type: GovernanceAccountType, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub realm: Pubkey, + pub community_token_config: GoverningTokenConfig, + pub council_token_config: GoverningTokenConfig, + pub reserved: Reserved110, +} + +impl RealmConfigAccount { + /// Prefix values used to generate a PDA for this account. + /// + /// Values are positional and appear in the following order: + /// + /// 0. `RealmConfigAccount::PREFIX` + /// 1. realm (`Pubkey`) + pub const PREFIX: &'static [u8] = "realm-config".as_bytes(); + + pub fn create_pda( + realm: Pubkey, + bump: u8, + ) -> Result { + solana_pubkey::Pubkey::create_program_address( + &["realm-config".as_bytes(), realm.as_ref(), &[bump]], + &crate::SPL_GOVERNANCE_ID, + ) + } + + pub fn find_pda(realm: &Pubkey) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &["realm-config".as_bytes(), realm.as_ref()], + &crate::SPL_GOVERNANCE_ID, + ) + } + + #[inline(always)] + pub fn from_bytes(data: &[u8]) -> Result { + let mut data = data; + Self::deserialize(&mut data) + } +} + +impl<'a> TryFrom<&solana_account_info::AccountInfo<'a>> for RealmConfigAccount { + type Error = std::io::Error; + + fn try_from(account_info: &solana_account_info::AccountInfo<'a>) -> Result { + let mut data: &[u8] = &(*account_info.data).borrow(); + Self::deserialize(&mut data) + } +} + +#[cfg(feature = "fetch")] +pub fn fetch_realm_config_account( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_realm_config_account(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_realm_config_account( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + let account = accounts[i].as_ref().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Account not found: {}", address), + ))?; + let data = RealmConfigAccount::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }); + } + Ok(decoded_accounts) +} + +#[cfg(feature = "fetch")] +pub fn fetch_maybe_realm_config_account( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_maybe_realm_config_account(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_maybe_realm_config_account( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + if let Some(account) = accounts[i].as_ref() { + let data = RealmConfigAccount::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::MaybeAccount::Exists( + crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }, + )); + } else { + decoded_accounts.push(crate::shared::MaybeAccount::NotFound(address)); + } + } + Ok(decoded_accounts) +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountDeserialize for RealmConfigAccount { + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + Ok(Self::deserialize(buf)?) + } +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountSerialize for RealmConfigAccount {} + +#[cfg(feature = "anchor")] +impl anchor_lang::Owner for RealmConfigAccount { + fn owner() -> Pubkey { + crate::SPL_GOVERNANCE_ID + } +} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::IdlBuild for RealmConfigAccount {} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::Discriminator for RealmConfigAccount { + const DISCRIMINATOR: &[u8] = &[0; 8]; +} diff --git a/e2e/governance/src/generated/accounts/realm_v1.rs b/e2e/governance/src/generated/accounts/realm_v1.rs new file mode 100644 index 0000000..d9d5dad --- /dev/null +++ b/e2e/governance/src/generated/accounts/realm_v1.rs @@ -0,0 +1,166 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceAccountType; +use crate::generated::types::RealmConfig; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use kaigan::types::RemainderStr; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct RealmV1 { + pub account_type: GovernanceAccountType, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub community_mint: Pubkey, + pub config: RealmConfig, + pub reserved: [u8; 6], + pub voting_proposal_count: u16, + pub authority: Option, + pub name: String, +} + +impl RealmV1 { + /// Prefix values used to generate a PDA for this account. + /// + /// Values are positional and appear in the following order: + /// + /// 0. `RealmV1::PREFIX` + /// 1. name (`RemainderStr`) + pub const PREFIX: &'static [u8] = "governance".as_bytes(); + + pub fn create_pda( + name: RemainderStr, + bump: u8, + ) -> Result { + solana_pubkey::Pubkey::create_program_address( + &["governance".as_bytes(), name.to_string().as_ref(), &[bump]], + &crate::SPL_GOVERNANCE_ID, + ) + } + + pub fn find_pda(name: RemainderStr) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &["governance".as_bytes(), name.to_string().as_ref()], + &crate::SPL_GOVERNANCE_ID, + ) + } + + #[inline(always)] + pub fn from_bytes(data: &[u8]) -> Result { + let mut data = data; + Self::deserialize(&mut data) + } +} + +impl<'a> TryFrom<&solana_account_info::AccountInfo<'a>> for RealmV1 { + type Error = std::io::Error; + + fn try_from(account_info: &solana_account_info::AccountInfo<'a>) -> Result { + let mut data: &[u8] = &(*account_info.data).borrow(); + Self::deserialize(&mut data) + } +} + +#[cfg(feature = "fetch")] +pub fn fetch_realm_v1( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_realm_v1(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_realm_v1( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + let account = accounts[i].as_ref().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Account not found: {}", address), + ))?; + let data = RealmV1::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }); + } + Ok(decoded_accounts) +} + +#[cfg(feature = "fetch")] +pub fn fetch_maybe_realm_v1( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_maybe_realm_v1(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_maybe_realm_v1( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + if let Some(account) = accounts[i].as_ref() { + let data = RealmV1::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::MaybeAccount::Exists( + crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }, + )); + } else { + decoded_accounts.push(crate::shared::MaybeAccount::NotFound(address)); + } + } + Ok(decoded_accounts) +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountDeserialize for RealmV1 { + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + Ok(Self::deserialize(buf)?) + } +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountSerialize for RealmV1 {} + +#[cfg(feature = "anchor")] +impl anchor_lang::Owner for RealmV1 { + fn owner() -> Pubkey { + crate::SPL_GOVERNANCE_ID + } +} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::IdlBuild for RealmV1 {} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::Discriminator for RealmV1 { + const DISCRIMINATOR: &[u8] = &[0; 8]; +} diff --git a/e2e/governance/src/generated/accounts/realm_v2.rs b/e2e/governance/src/generated/accounts/realm_v2.rs new file mode 100644 index 0000000..04551d8 --- /dev/null +++ b/e2e/governance/src/generated/accounts/realm_v2.rs @@ -0,0 +1,168 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceAccountType; +use crate::generated::types::RealmConfig; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use kaigan::types::RemainderStr; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct RealmV2 { + pub account_type: GovernanceAccountType, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub community_mint: Pubkey, + pub config: RealmConfig, + pub reserved: [u8; 6], + pub legacy1: u16, + pub authority: Option, + pub name: String, + #[cfg_attr(feature = "serde", serde(with = "serde_big_array::BigArray"))] + pub reserved_v2: [u8; 128], +} + +impl RealmV2 { + /// Prefix values used to generate a PDA for this account. + /// + /// Values are positional and appear in the following order: + /// + /// 0. `RealmV2::PREFIX` + /// 1. name (`RemainderStr`) + pub const PREFIX: &'static [u8] = "governance".as_bytes(); + + pub fn create_pda( + name: RemainderStr, + bump: u8, + ) -> Result { + solana_pubkey::Pubkey::create_program_address( + &["governance".as_bytes(), name.to_string().as_ref(), &[bump]], + &crate::SPL_GOVERNANCE_ID, + ) + } + + pub fn find_pda(name: RemainderStr) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &["governance".as_bytes(), name.to_string().as_ref()], + &crate::SPL_GOVERNANCE_ID, + ) + } + + #[inline(always)] + pub fn from_bytes(data: &[u8]) -> Result { + let mut data = data; + Self::deserialize(&mut data) + } +} + +impl<'a> TryFrom<&solana_account_info::AccountInfo<'a>> for RealmV2 { + type Error = std::io::Error; + + fn try_from(account_info: &solana_account_info::AccountInfo<'a>) -> Result { + let mut data: &[u8] = &(*account_info.data).borrow(); + Self::deserialize(&mut data) + } +} + +#[cfg(feature = "fetch")] +pub fn fetch_realm_v2( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_realm_v2(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_realm_v2( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + let account = accounts[i].as_ref().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Account not found: {}", address), + ))?; + let data = RealmV2::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }); + } + Ok(decoded_accounts) +} + +#[cfg(feature = "fetch")] +pub fn fetch_maybe_realm_v2( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_maybe_realm_v2(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_maybe_realm_v2( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + if let Some(account) = accounts[i].as_ref() { + let data = RealmV2::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::MaybeAccount::Exists( + crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }, + )); + } else { + decoded_accounts.push(crate::shared::MaybeAccount::NotFound(address)); + } + } + Ok(decoded_accounts) +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountDeserialize for RealmV2 { + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + Ok(Self::deserialize(buf)?) + } +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountSerialize for RealmV2 {} + +#[cfg(feature = "anchor")] +impl anchor_lang::Owner for RealmV2 { + fn owner() -> Pubkey { + crate::SPL_GOVERNANCE_ID + } +} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::IdlBuild for RealmV2 {} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::Discriminator for RealmV2 { + const DISCRIMINATOR: &[u8] = &[0; 8]; +} diff --git a/e2e/governance/src/generated/accounts/required_signatory.rs b/e2e/governance/src/generated/accounts/required_signatory.rs new file mode 100644 index 0000000..3fbfc3e --- /dev/null +++ b/e2e/governance/src/generated/accounts/required_signatory.rs @@ -0,0 +1,176 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceAccountType; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct RequiredSignatory { + pub account_type: GovernanceAccountType, + pub account_version: u8, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub governance: Pubkey, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub signatory: Pubkey, +} + +impl RequiredSignatory { + /// Prefix values used to generate a PDA for this account. + /// + /// Values are positional and appear in the following order: + /// + /// 0. `RequiredSignatory::PREFIX` + /// 1. governance (`Pubkey`) + /// 2. signatory (`Pubkey`) + pub const PREFIX: &'static [u8] = "required-signatory".as_bytes(); + + pub fn create_pda( + governance: Pubkey, + signatory: Pubkey, + bump: u8, + ) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + "required-signatory".as_bytes(), + governance.as_ref(), + signatory.as_ref(), + &[bump], + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + pub fn find_pda(governance: &Pubkey, signatory: &Pubkey) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + "required-signatory".as_bytes(), + governance.as_ref(), + signatory.as_ref(), + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + #[inline(always)] + pub fn from_bytes(data: &[u8]) -> Result { + let mut data = data; + Self::deserialize(&mut data) + } +} + +impl<'a> TryFrom<&solana_account_info::AccountInfo<'a>> for RequiredSignatory { + type Error = std::io::Error; + + fn try_from(account_info: &solana_account_info::AccountInfo<'a>) -> Result { + let mut data: &[u8] = &(*account_info.data).borrow(); + Self::deserialize(&mut data) + } +} + +#[cfg(feature = "fetch")] +pub fn fetch_required_signatory( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_required_signatory(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_required_signatory( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + let account = accounts[i].as_ref().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Account not found: {}", address), + ))?; + let data = RequiredSignatory::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }); + } + Ok(decoded_accounts) +} + +#[cfg(feature = "fetch")] +pub fn fetch_maybe_required_signatory( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_maybe_required_signatory(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_maybe_required_signatory( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + if let Some(account) = accounts[i].as_ref() { + let data = RequiredSignatory::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::MaybeAccount::Exists( + crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }, + )); + } else { + decoded_accounts.push(crate::shared::MaybeAccount::NotFound(address)); + } + } + Ok(decoded_accounts) +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountDeserialize for RequiredSignatory { + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + Ok(Self::deserialize(buf)?) + } +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountSerialize for RequiredSignatory {} + +#[cfg(feature = "anchor")] +impl anchor_lang::Owner for RequiredSignatory { + fn owner() -> Pubkey { + crate::SPL_GOVERNANCE_ID + } +} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::IdlBuild for RequiredSignatory {} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::Discriminator for RequiredSignatory { + const DISCRIMINATOR: &[u8] = &[0; 8]; +} diff --git a/e2e/governance/src/generated/accounts/signatory_record_v1.rs b/e2e/governance/src/generated/accounts/signatory_record_v1.rs new file mode 100644 index 0000000..76fbe79 --- /dev/null +++ b/e2e/governance/src/generated/accounts/signatory_record_v1.rs @@ -0,0 +1,176 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceAccountType; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct SignatoryRecordV1 { + pub account_type: GovernanceAccountType, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub proposal: Pubkey, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub signatory: Pubkey, + pub signed_off: bool, +} + +impl SignatoryRecordV1 { + /// Prefix values used to generate a PDA for this account. + /// + /// Values are positional and appear in the following order: + /// + /// 0. `SignatoryRecordV1::PREFIX` + /// 1. proposal (`Pubkey`) + /// 2. signatory (`Pubkey`) + pub const PREFIX: &'static [u8] = "governance".as_bytes(); + + pub fn create_pda( + proposal: Pubkey, + signatory: Pubkey, + bump: u8, + ) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + "governance".as_bytes(), + proposal.as_ref(), + signatory.as_ref(), + &[bump], + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + pub fn find_pda(proposal: &Pubkey, signatory: &Pubkey) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + "governance".as_bytes(), + proposal.as_ref(), + signatory.as_ref(), + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + #[inline(always)] + pub fn from_bytes(data: &[u8]) -> Result { + let mut data = data; + Self::deserialize(&mut data) + } +} + +impl<'a> TryFrom<&solana_account_info::AccountInfo<'a>> for SignatoryRecordV1 { + type Error = std::io::Error; + + fn try_from(account_info: &solana_account_info::AccountInfo<'a>) -> Result { + let mut data: &[u8] = &(*account_info.data).borrow(); + Self::deserialize(&mut data) + } +} + +#[cfg(feature = "fetch")] +pub fn fetch_signatory_record_v1( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_signatory_record_v1(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_signatory_record_v1( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + let account = accounts[i].as_ref().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Account not found: {}", address), + ))?; + let data = SignatoryRecordV1::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }); + } + Ok(decoded_accounts) +} + +#[cfg(feature = "fetch")] +pub fn fetch_maybe_signatory_record_v1( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_maybe_signatory_record_v1(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_maybe_signatory_record_v1( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + if let Some(account) = accounts[i].as_ref() { + let data = SignatoryRecordV1::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::MaybeAccount::Exists( + crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }, + )); + } else { + decoded_accounts.push(crate::shared::MaybeAccount::NotFound(address)); + } + } + Ok(decoded_accounts) +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountDeserialize for SignatoryRecordV1 { + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + Ok(Self::deserialize(buf)?) + } +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountSerialize for SignatoryRecordV1 {} + +#[cfg(feature = "anchor")] +impl anchor_lang::Owner for SignatoryRecordV1 { + fn owner() -> Pubkey { + crate::SPL_GOVERNANCE_ID + } +} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::IdlBuild for SignatoryRecordV1 {} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::Discriminator for SignatoryRecordV1 { + const DISCRIMINATOR: &[u8] = &[0; 8]; +} diff --git a/e2e/governance/src/generated/accounts/signatory_record_v2.rs b/e2e/governance/src/generated/accounts/signatory_record_v2.rs new file mode 100644 index 0000000..40f57ea --- /dev/null +++ b/e2e/governance/src/generated/accounts/signatory_record_v2.rs @@ -0,0 +1,177 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceAccountType; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct SignatoryRecordV2 { + pub account_type: GovernanceAccountType, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub proposal: Pubkey, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub signatory: Pubkey, + pub signed_off: bool, + pub reserved_v2: [u8; 8], +} + +impl SignatoryRecordV2 { + /// Prefix values used to generate a PDA for this account. + /// + /// Values are positional and appear in the following order: + /// + /// 0. `SignatoryRecordV2::PREFIX` + /// 1. proposal (`Pubkey`) + /// 2. signatory (`Pubkey`) + pub const PREFIX: &'static [u8] = "governance".as_bytes(); + + pub fn create_pda( + proposal: Pubkey, + signatory: Pubkey, + bump: u8, + ) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + "governance".as_bytes(), + proposal.as_ref(), + signatory.as_ref(), + &[bump], + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + pub fn find_pda(proposal: &Pubkey, signatory: &Pubkey) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + "governance".as_bytes(), + proposal.as_ref(), + signatory.as_ref(), + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + #[inline(always)] + pub fn from_bytes(data: &[u8]) -> Result { + let mut data = data; + Self::deserialize(&mut data) + } +} + +impl<'a> TryFrom<&solana_account_info::AccountInfo<'a>> for SignatoryRecordV2 { + type Error = std::io::Error; + + fn try_from(account_info: &solana_account_info::AccountInfo<'a>) -> Result { + let mut data: &[u8] = &(*account_info.data).borrow(); + Self::deserialize(&mut data) + } +} + +#[cfg(feature = "fetch")] +pub fn fetch_signatory_record_v2( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_signatory_record_v2(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_signatory_record_v2( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + let account = accounts[i].as_ref().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Account not found: {}", address), + ))?; + let data = SignatoryRecordV2::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }); + } + Ok(decoded_accounts) +} + +#[cfg(feature = "fetch")] +pub fn fetch_maybe_signatory_record_v2( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_maybe_signatory_record_v2(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_maybe_signatory_record_v2( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + if let Some(account) = accounts[i].as_ref() { + let data = SignatoryRecordV2::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::MaybeAccount::Exists( + crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }, + )); + } else { + decoded_accounts.push(crate::shared::MaybeAccount::NotFound(address)); + } + } + Ok(decoded_accounts) +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountDeserialize for SignatoryRecordV2 { + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + Ok(Self::deserialize(buf)?) + } +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountSerialize for SignatoryRecordV2 {} + +#[cfg(feature = "anchor")] +impl anchor_lang::Owner for SignatoryRecordV2 { + fn owner() -> Pubkey { + crate::SPL_GOVERNANCE_ID + } +} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::IdlBuild for SignatoryRecordV2 {} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::Discriminator for SignatoryRecordV2 { + const DISCRIMINATOR: &[u8] = &[0; 8]; +} diff --git a/e2e/governance/src/generated/accounts/token_owner_record_v1.rs b/e2e/governance/src/generated/accounts/token_owner_record_v1.rs new file mode 100644 index 0000000..fd4abc8 --- /dev/null +++ b/e2e/governance/src/generated/accounts/token_owner_record_v1.rs @@ -0,0 +1,194 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceAccountType; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct TokenOwnerRecordV1 { + pub account_type: GovernanceAccountType, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub realm: Pubkey, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub governing_token_mint: Pubkey, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub governing_token_owner: Pubkey, + pub governing_token_deposit_amount: u64, + pub unrelinquished_votes_count: u64, + pub outstanding_proposal_count: u8, + pub version: u8, + pub reserved: [u8; 6], + pub governance_delegate: Option, +} + +impl TokenOwnerRecordV1 { + /// Prefix values used to generate a PDA for this account. + /// + /// Values are positional and appear in the following order: + /// + /// 0. `TokenOwnerRecordV1::PREFIX` + /// 1. realm (`Pubkey`) + /// 2. governing_token_mint (`Pubkey`) + /// 3. governing_token_owner (`Pubkey`) + pub const PREFIX: &'static [u8] = "governance".as_bytes(); + + pub fn create_pda( + realm: Pubkey, + governing_token_mint: Pubkey, + governing_token_owner: Pubkey, + bump: u8, + ) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + "governance".as_bytes(), + realm.as_ref(), + governing_token_mint.as_ref(), + governing_token_owner.as_ref(), + &[bump], + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + pub fn find_pda( + realm: &Pubkey, + governing_token_mint: &Pubkey, + governing_token_owner: &Pubkey, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + "governance".as_bytes(), + realm.as_ref(), + governing_token_mint.as_ref(), + governing_token_owner.as_ref(), + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + #[inline(always)] + pub fn from_bytes(data: &[u8]) -> Result { + let mut data = data; + Self::deserialize(&mut data) + } +} + +impl<'a> TryFrom<&solana_account_info::AccountInfo<'a>> for TokenOwnerRecordV1 { + type Error = std::io::Error; + + fn try_from(account_info: &solana_account_info::AccountInfo<'a>) -> Result { + let mut data: &[u8] = &(*account_info.data).borrow(); + Self::deserialize(&mut data) + } +} + +#[cfg(feature = "fetch")] +pub fn fetch_token_owner_record_v1( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_token_owner_record_v1(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_token_owner_record_v1( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + let account = accounts[i].as_ref().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Account not found: {}", address), + ))?; + let data = TokenOwnerRecordV1::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }); + } + Ok(decoded_accounts) +} + +#[cfg(feature = "fetch")] +pub fn fetch_maybe_token_owner_record_v1( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_maybe_token_owner_record_v1(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_maybe_token_owner_record_v1( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + if let Some(account) = accounts[i].as_ref() { + let data = TokenOwnerRecordV1::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::MaybeAccount::Exists( + crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }, + )); + } else { + decoded_accounts.push(crate::shared::MaybeAccount::NotFound(address)); + } + } + Ok(decoded_accounts) +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountDeserialize for TokenOwnerRecordV1 { + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + Ok(Self::deserialize(buf)?) + } +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountSerialize for TokenOwnerRecordV1 {} + +#[cfg(feature = "anchor")] +impl anchor_lang::Owner for TokenOwnerRecordV1 { + fn owner() -> Pubkey { + crate::SPL_GOVERNANCE_ID + } +} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::IdlBuild for TokenOwnerRecordV1 {} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::Discriminator for TokenOwnerRecordV1 { + const DISCRIMINATOR: &[u8] = &[0; 8]; +} diff --git a/e2e/governance/src/generated/accounts/token_owner_record_v2.rs b/e2e/governance/src/generated/accounts/token_owner_record_v2.rs new file mode 100644 index 0000000..319bc3c --- /dev/null +++ b/e2e/governance/src/generated/accounts/token_owner_record_v2.rs @@ -0,0 +1,196 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceAccountType; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct TokenOwnerRecordV2 { + pub account_type: GovernanceAccountType, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub realm: Pubkey, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub governing_token_mint: Pubkey, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub governing_token_owner: Pubkey, + pub governing_token_deposit_amount: u64, + pub unrelinquished_votes_count: u64, + pub outstanding_proposal_count: u8, + pub version: u8, + pub reserved: [u8; 6], + pub governance_delegate: Option, + #[cfg_attr(feature = "serde", serde(with = "serde_big_array::BigArray"))] + pub reserved_v2: [u8; 128], +} + +impl TokenOwnerRecordV2 { + /// Prefix values used to generate a PDA for this account. + /// + /// Values are positional and appear in the following order: + /// + /// 0. `TokenOwnerRecordV2::PREFIX` + /// 1. realm (`Pubkey`) + /// 2. governing_token_mint (`Pubkey`) + /// 3. governing_token_owner (`Pubkey`) + pub const PREFIX: &'static [u8] = "governance".as_bytes(); + + pub fn create_pda( + realm: Pubkey, + governing_token_mint: Pubkey, + governing_token_owner: Pubkey, + bump: u8, + ) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + "governance".as_bytes(), + realm.as_ref(), + governing_token_mint.as_ref(), + governing_token_owner.as_ref(), + &[bump], + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + pub fn find_pda( + realm: &Pubkey, + governing_token_mint: &Pubkey, + governing_token_owner: &Pubkey, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + "governance".as_bytes(), + realm.as_ref(), + governing_token_mint.as_ref(), + governing_token_owner.as_ref(), + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + #[inline(always)] + pub fn from_bytes(data: &[u8]) -> Result { + let mut data = data; + Self::deserialize(&mut data) + } +} + +impl<'a> TryFrom<&solana_account_info::AccountInfo<'a>> for TokenOwnerRecordV2 { + type Error = std::io::Error; + + fn try_from(account_info: &solana_account_info::AccountInfo<'a>) -> Result { + let mut data: &[u8] = &(*account_info.data).borrow(); + Self::deserialize(&mut data) + } +} + +#[cfg(feature = "fetch")] +pub fn fetch_token_owner_record_v2( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_token_owner_record_v2(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_token_owner_record_v2( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + let account = accounts[i].as_ref().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Account not found: {}", address), + ))?; + let data = TokenOwnerRecordV2::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }); + } + Ok(decoded_accounts) +} + +#[cfg(feature = "fetch")] +pub fn fetch_maybe_token_owner_record_v2( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_maybe_token_owner_record_v2(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_maybe_token_owner_record_v2( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + if let Some(account) = accounts[i].as_ref() { + let data = TokenOwnerRecordV2::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::MaybeAccount::Exists( + crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }, + )); + } else { + decoded_accounts.push(crate::shared::MaybeAccount::NotFound(address)); + } + } + Ok(decoded_accounts) +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountDeserialize for TokenOwnerRecordV2 { + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + Ok(Self::deserialize(buf)?) + } +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountSerialize for TokenOwnerRecordV2 {} + +#[cfg(feature = "anchor")] +impl anchor_lang::Owner for TokenOwnerRecordV2 { + fn owner() -> Pubkey { + crate::SPL_GOVERNANCE_ID + } +} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::IdlBuild for TokenOwnerRecordV2 {} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::Discriminator for TokenOwnerRecordV2 { + const DISCRIMINATOR: &[u8] = &[0; 8]; +} diff --git a/e2e/governance/src/generated/accounts/vote_record_v1.rs b/e2e/governance/src/generated/accounts/vote_record_v1.rs new file mode 100644 index 0000000..477d07b --- /dev/null +++ b/e2e/governance/src/generated/accounts/vote_record_v1.rs @@ -0,0 +1,178 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceAccountType; +use crate::generated::types::VoteWeightV1; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct VoteRecordV1 { + pub account_type: GovernanceAccountType, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub proposal: Pubkey, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub governing_token_owner: Pubkey, + pub is_relinquished: bool, + pub vote_weight: VoteWeightV1, +} + +impl VoteRecordV1 { + /// Prefix values used to generate a PDA for this account. + /// + /// Values are positional and appear in the following order: + /// + /// 0. `VoteRecordV1::PREFIX` + /// 1. proposal (`Pubkey`) + /// 2. token_owner_record (`Pubkey`) + pub const PREFIX: &'static [u8] = "governance".as_bytes(); + + pub fn create_pda( + proposal: Pubkey, + token_owner_record: Pubkey, + bump: u8, + ) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + "governance".as_bytes(), + proposal.as_ref(), + token_owner_record.as_ref(), + &[bump], + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + pub fn find_pda(proposal: &Pubkey, token_owner_record: &Pubkey) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + "governance".as_bytes(), + proposal.as_ref(), + token_owner_record.as_ref(), + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + #[inline(always)] + pub fn from_bytes(data: &[u8]) -> Result { + let mut data = data; + Self::deserialize(&mut data) + } +} + +impl<'a> TryFrom<&solana_account_info::AccountInfo<'a>> for VoteRecordV1 { + type Error = std::io::Error; + + fn try_from(account_info: &solana_account_info::AccountInfo<'a>) -> Result { + let mut data: &[u8] = &(*account_info.data).borrow(); + Self::deserialize(&mut data) + } +} + +#[cfg(feature = "fetch")] +pub fn fetch_vote_record_v1( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_vote_record_v1(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_vote_record_v1( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + let account = accounts[i].as_ref().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Account not found: {}", address), + ))?; + let data = VoteRecordV1::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }); + } + Ok(decoded_accounts) +} + +#[cfg(feature = "fetch")] +pub fn fetch_maybe_vote_record_v1( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_maybe_vote_record_v1(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_maybe_vote_record_v1( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + if let Some(account) = accounts[i].as_ref() { + let data = VoteRecordV1::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::MaybeAccount::Exists( + crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }, + )); + } else { + decoded_accounts.push(crate::shared::MaybeAccount::NotFound(address)); + } + } + Ok(decoded_accounts) +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountDeserialize for VoteRecordV1 { + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + Ok(Self::deserialize(buf)?) + } +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountSerialize for VoteRecordV1 {} + +#[cfg(feature = "anchor")] +impl anchor_lang::Owner for VoteRecordV1 { + fn owner() -> Pubkey { + crate::SPL_GOVERNANCE_ID + } +} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::IdlBuild for VoteRecordV1 {} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::Discriminator for VoteRecordV1 { + const DISCRIMINATOR: &[u8] = &[0; 8]; +} diff --git a/e2e/governance/src/generated/accounts/vote_record_v2.rs b/e2e/governance/src/generated/accounts/vote_record_v2.rs new file mode 100644 index 0000000..de784cb --- /dev/null +++ b/e2e/governance/src/generated/accounts/vote_record_v2.rs @@ -0,0 +1,180 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceAccountType; +use crate::generated::types::Vote; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct VoteRecordV2 { + pub account_type: GovernanceAccountType, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub proposal: Pubkey, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub governing_token_owner: Pubkey, + pub is_relinquished: bool, + pub voter_weight: u64, + pub vote: Vote, + pub reserved_v2: [u8; 8], +} + +impl VoteRecordV2 { + /// Prefix values used to generate a PDA for this account. + /// + /// Values are positional and appear in the following order: + /// + /// 0. `VoteRecordV2::PREFIX` + /// 1. proposal (`Pubkey`) + /// 2. token_owner_record (`Pubkey`) + pub const PREFIX: &'static [u8] = "governance".as_bytes(); + + pub fn create_pda( + proposal: Pubkey, + token_owner_record: Pubkey, + bump: u8, + ) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + "governance".as_bytes(), + proposal.as_ref(), + token_owner_record.as_ref(), + &[bump], + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + pub fn find_pda(proposal: &Pubkey, token_owner_record: &Pubkey) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + "governance".as_bytes(), + proposal.as_ref(), + token_owner_record.as_ref(), + ], + &crate::SPL_GOVERNANCE_ID, + ) + } + + #[inline(always)] + pub fn from_bytes(data: &[u8]) -> Result { + let mut data = data; + Self::deserialize(&mut data) + } +} + +impl<'a> TryFrom<&solana_account_info::AccountInfo<'a>> for VoteRecordV2 { + type Error = std::io::Error; + + fn try_from(account_info: &solana_account_info::AccountInfo<'a>) -> Result { + let mut data: &[u8] = &(*account_info.data).borrow(); + Self::deserialize(&mut data) + } +} + +#[cfg(feature = "fetch")] +pub fn fetch_vote_record_v2( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_vote_record_v2(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_vote_record_v2( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + let account = accounts[i].as_ref().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Account not found: {}", address), + ))?; + let data = VoteRecordV2::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }); + } + Ok(decoded_accounts) +} + +#[cfg(feature = "fetch")] +pub fn fetch_maybe_vote_record_v2( + rpc: &solana_client::rpc_client::RpcClient, + address: &solana_pubkey::Pubkey, +) -> Result, std::io::Error> { + let accounts = fetch_all_maybe_vote_record_v2(rpc, &[*address])?; + Ok(accounts[0].clone()) +} + +#[cfg(feature = "fetch")] +pub fn fetch_all_maybe_vote_record_v2( + rpc: &solana_client::rpc_client::RpcClient, + addresses: &[solana_pubkey::Pubkey], +) -> Result>, std::io::Error> { + let accounts = rpc + .get_multiple_accounts(addresses) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let mut decoded_accounts: Vec> = Vec::new(); + for i in 0..addresses.len() { + let address = addresses[i]; + if let Some(account) = accounts[i].as_ref() { + let data = VoteRecordV2::from_bytes(&account.data)?; + decoded_accounts.push(crate::shared::MaybeAccount::Exists( + crate::shared::DecodedAccount { + address, + account: account.clone(), + data, + }, + )); + } else { + decoded_accounts.push(crate::shared::MaybeAccount::NotFound(address)); + } + } + Ok(decoded_accounts) +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountDeserialize for VoteRecordV2 { + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + Ok(Self::deserialize(buf)?) + } +} + +#[cfg(feature = "anchor")] +impl anchor_lang::AccountSerialize for VoteRecordV2 {} + +#[cfg(feature = "anchor")] +impl anchor_lang::Owner for VoteRecordV2 { + fn owner() -> Pubkey { + crate::SPL_GOVERNANCE_ID + } +} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::IdlBuild for VoteRecordV2 {} + +#[cfg(feature = "anchor-idl-build")] +impl anchor_lang::Discriminator for VoteRecordV2 { + const DISCRIMINATOR: &[u8] = &[0; 8]; +} diff --git a/e2e/governance/src/generated/errors/mod.rs b/e2e/governance/src/generated/errors/mod.rs new file mode 100644 index 0000000..b84bbdc --- /dev/null +++ b/e2e/governance/src/generated/errors/mod.rs @@ -0,0 +1,10 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +pub(crate) mod spl_governance; + +pub use self::spl_governance::SplGovernanceError; diff --git a/e2e/governance/src/generated/errors/spl_governance.rs b/e2e/governance/src/generated/errors/spl_governance.rs new file mode 100644 index 0000000..6e19600 --- /dev/null +++ b/e2e/governance/src/generated/errors/spl_governance.rs @@ -0,0 +1,394 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use num_derive::FromPrimitive; +use thiserror::Error; + +#[derive(Clone, Debug, Eq, Error, FromPrimitive, PartialEq)] +pub enum SplGovernanceError { + /// 500 - Invalid instruction passed to program + #[error("Invalid instruction passed to program")] + InvalidInstruction = 0x1F4, + /// 501 - Realm with the given name and governing mints already exists + #[error("Realm with the given name and governing mints already exists")] + RealmAlreadyExists = 0x1F5, + /// 502 - Invalid realm + #[error("Invalid realm")] + InvalidRealm = 0x1F6, + /// 503 - Invalid Governing Token Mint + #[error("Invalid Governing Token Mint")] + InvalidGoverningTokenMint = 0x1F7, + /// 504 - Governing Token Owner must sign transaction + #[error("Governing Token Owner must sign transaction")] + GoverningTokenOwnerMustSign = 0x1F8, + /// 505 - Governing Token Owner or Delegate must sign transaction + #[error("Governing Token Owner or Delegate must sign transaction")] + GoverningTokenOwnerOrDelegateMustSign = 0x1F9, + /// 506 - All votes must be relinquished to withdraw governing tokens + #[error("All votes must be relinquished to withdraw governing tokens")] + AllVotesMustBeRelinquishedToWithdrawGoverningTokens = 0x1FA, + /// 507 - Invalid Token Owner Record account address + #[error("Invalid Token Owner Record account address")] + InvalidTokenOwnerRecordAccountAddress = 0x1FB, + /// 508 - Invalid GoverningMint for TokenOwnerRecord + #[error("Invalid GoverningMint for TokenOwnerRecord")] + InvalidGoverningMintForTokenOwnerRecord = 0x1FC, + /// 509 - Invalid Realm for TokenOwnerRecord + #[error("Invalid Realm for TokenOwnerRecord")] + InvalidRealmForTokenOwnerRecord = 0x1FD, + /// 510 - Invalid Proposal for ProposalTransaction, + #[error("Invalid Proposal for ProposalTransaction,")] + InvalidProposalForProposalTransaction = 0x1FE, + /// 511 - Invalid Signatory account address + #[error("Invalid Signatory account address")] + InvalidSignatoryAddress = 0x1FF, + /// 512 - Signatory already signed off + #[error("Signatory already signed off")] + SignatoryAlreadySignedOff = 0x200, + /// 513 - Signatory must sign + #[error("Signatory must sign")] + SignatoryMustSign = 0x201, + /// 514 - Invalid Proposal Owner + #[error("Invalid Proposal Owner")] + InvalidProposalOwnerAccount = 0x202, + /// 515 - Invalid Proposal for VoterRecord + #[error("Invalid Proposal for VoterRecord")] + InvalidProposalForVoterRecord = 0x203, + /// 516 - Invalid GoverningTokenOwner for VoteRecord + #[error("Invalid GoverningTokenOwner for VoteRecord")] + InvalidGoverningTokenOwnerForVoteRecord = 0x204, + /// 517 - Invalid Governance config: Vote threshold percentage out of range + #[error("Invalid Governance config: Vote threshold percentage out of range")] + InvalidVoteThresholdPercentage = 0x205, + /// 518 - Proposal for the given Governance, Governing Token Mint and index already exists + #[error("Proposal for the given Governance, Governing Token Mint and index already exists")] + ProposalAlreadyExists = 0x206, + /// 519 - Token Owner already voted on the Proposal + #[error("Token Owner already voted on the Proposal")] + VoteAlreadyExists = 0x207, + /// 520 - Owner doesn't have enough governing tokens to create Proposal + #[error("Owner doesn't have enough governing tokens to create Proposal")] + NotEnoughTokensToCreateProposal = 0x208, + /// 521 - Invalid State: Can't edit Signatories + #[error("Invalid State: Can't edit Signatories")] + InvalidStateCannotEditSignatories = 0x209, + /// 522 - Invalid Proposal state + #[error("Invalid Proposal state")] + InvalidProposalState = 0x20A, + /// 523 - Invalid State: Can't edit transactions + #[error("Invalid State: Can't edit transactions")] + InvalidStateCannotEditTransactions = 0x20B, + /// 524 - Invalid State: Can't execute transaction + #[error("Invalid State: Can't execute transaction")] + InvalidStateCannotExecuteTransaction = 0x20C, + /// 525 - Can't execute transaction within its hold up time + #[error("Can't execute transaction within its hold up time")] + CannotExecuteTransactionWithinHoldUpTime = 0x20D, + /// 526 - Transaction already executed + #[error("Transaction already executed")] + TransactionAlreadyExecuted = 0x20E, + /// 527 - Invalid Transaction index + #[error("Invalid Transaction index")] + InvalidTransactionIndex = 0x20F, + /// 528 - Transaction hold up time is below the min specified by Governance + #[error("Transaction hold up time is below the min specified by Governance")] + TransactionHoldUpTimeBelowRequiredMin = 0x210, + /// 529 - Transaction at the given index for the Proposal already exists + #[error("Transaction at the given index for the Proposal already exists")] + TransactionAlreadyExists = 0x211, + /// 530 - Invalid State: Can't sign off + #[error("Invalid State: Can't sign off")] + InvalidStateCannotSignOff = 0x212, + /// 531 - Invalid State: Can't vote + #[error("Invalid State: Can't vote")] + InvalidStateCannotVote = 0x213, + /// 532 - Invalid State: Can't finalize vote + #[error("Invalid State: Can't finalize vote")] + InvalidStateCannotFinalize = 0x214, + /// 533 - Invalid State: Can't cancel Proposal + #[error("Invalid State: Can't cancel Proposal")] + InvalidStateCannotCancelProposal = 0x215, + /// 534 - Vote already relinquished + #[error("Vote already relinquished")] + VoteAlreadyRelinquished = 0x216, + /// 535 - Can't finalize vote. Voting still in progress + #[error("Can't finalize vote. Voting still in progress")] + CannotFinalizeVotingInProgress = 0x217, + /// 536 - Proposal voting time expired + #[error("Proposal voting time expired")] + ProposalVotingTimeExpired = 0x218, + /// 537 - Invalid Signatory Mint + #[error("Invalid Signatory Mint")] + InvalidSignatoryMint = 0x219, + /// 538 - Proposal does not belong to the given Governance + #[error("Proposal does not belong to the given Governance")] + InvalidGovernanceForProposal = 0x21A, + /// 539 - Proposal does not belong to given Governing Mint + #[error("Proposal does not belong to given Governing Mint")] + InvalidGoverningMintForProposal = 0x21B, + /// 540 - Current mint authority must sign transaction + #[error("Current mint authority must sign transaction")] + MintAuthorityMustSign = 0x21C, + /// 541 - Invalid mint authority + #[error("Invalid mint authority")] + InvalidMintAuthority = 0x21D, + /// 542 - Mint has no authority + #[error("Mint has no authority")] + MintHasNoAuthority = 0x21E, + /// 543 - Invalid Token account owner + #[error("Invalid Token account owner")] + SplTokenAccountWithInvalidOwner = 0x21F, + /// 544 - Invalid Mint account owner + #[error("Invalid Mint account owner")] + SplTokenMintWithInvalidOwner = 0x220, + /// 545 - Token Account is not initialized + #[error("Token Account is not initialized")] + SplTokenAccountNotInitialized = 0x221, + /// 546 - Token Account doesn't exist + #[error("Token Account doesn't exist")] + SplTokenAccountDoesNotExist = 0x222, + /// 547 - Token account data is invalid + #[error("Token account data is invalid")] + SplTokenInvalidTokenAccountData = 0x223, + /// 548 - Token mint account data is invalid + #[error("Token mint account data is invalid")] + SplTokenInvalidMintAccountData = 0x224, + /// 549 - Token Mint account is not initialized + #[error("Token Mint account is not initialized")] + SplTokenMintNotInitialized = 0x225, + /// 550 - Token Mint account doesn't exist + #[error("Token Mint account doesn't exist")] + SplTokenMintDoesNotExist = 0x226, + /// 551 - Invalid ProgramData account address + #[error("Invalid ProgramData account address")] + InvalidProgramDataAccountAddress = 0x227, + /// 552 - Invalid ProgramData account Data + #[error("Invalid ProgramData account Data")] + InvalidProgramDataAccountData = 0x228, + /// 553 - Provided upgrade authority doesn't match current program upgrade authority + #[error("Provided upgrade authority doesn't match current program upgrade authority")] + InvalidUpgradeAuthority = 0x229, + /// 554 - Current program upgrade authority must sign transaction + #[error("Current program upgrade authority must sign transaction")] + UpgradeAuthorityMustSign = 0x22A, + /// 555 - Given program is not upgradable + #[error("Given program is not upgradable")] + ProgramNotUpgradable = 0x22B, + /// 556 - Invalid token owner + #[error("Invalid token owner")] + InvalidTokenOwner = 0x22C, + /// 557 - Current token owner must sign transaction + #[error("Current token owner must sign transaction")] + TokenOwnerMustSign = 0x22D, + /// 558 - Given VoteThresholdType is not supported + #[error("Given VoteThresholdType is not supported")] + VoteThresholdTypeNotSupported = 0x22E, + /// 559 - Given VoteWeightSource is not supported + #[error("Given VoteWeightSource is not supported")] + VoteWeightSourceNotSupported = 0x22F, + /// 560 - Legacy1 + #[error("Legacy1")] + Legacy1 = 0x230, + /// 561 - Governance PDA must sign + #[error("Governance PDA must sign")] + GovernancePdaMustSign = 0x231, + /// 562 - Transaction already flagged with error + #[error("Transaction already flagged with error")] + TransactionAlreadyFlaggedWithError = 0x232, + /// 563 - Invalid Realm for Governance + #[error("Invalid Realm for Governance")] + InvalidRealmForGovernance = 0x233, + /// 564 - Invalid Authority for Realm + #[error("Invalid Authority for Realm")] + InvalidAuthorityForRealm = 0x234, + /// 565 - Realm has no authority + #[error("Realm has no authority")] + RealmHasNoAuthority = 0x235, + /// 566 - Realm authority must sign + #[error("Realm authority must sign")] + RealmAuthorityMustSign = 0x236, + /// 567 - Invalid governing token holding account + #[error("Invalid governing token holding account")] + InvalidGoverningTokenHoldingAccount = 0x237, + /// 568 - Realm council mint change is not supported + #[error("Realm council mint change is not supported")] + RealmCouncilMintChangeIsNotSupported = 0x238, + /// 569 - Invalid max voter weight absolute value + #[error("Invalid max voter weight absolute value")] + InvalidMaxVoterWeightAbsoluteValue = 0x239, + /// 570 - Invalid max voter weight supply fraction + #[error("Invalid max voter weight supply fraction")] + InvalidMaxVoterWeightSupplyFraction = 0x23A, + /// 571 - Owner doesn't have enough governing tokens to create Governance + #[error("Owner doesn't have enough governing tokens to create Governance")] + NotEnoughTokensToCreateGovernance = 0x23B, + /// 572 - Too many outstanding proposals + #[error("Too many outstanding proposals")] + TooManyOutstandingProposals = 0x23C, + /// 573 - All proposals must be finalized to withdraw governing tokens + #[error("All proposals must be finalized to withdraw governing tokens")] + AllProposalsMustBeFinalisedToWithdrawGoverningTokens = 0x23D, + /// 574 - Invalid VoterWeightRecord for Realm + #[error("Invalid VoterWeightRecord for Realm")] + InvalidVoterWeightRecordForRealm = 0x23E, + /// 575 - Invalid VoterWeightRecord for GoverningTokenMint + #[error("Invalid VoterWeightRecord for GoverningTokenMint")] + InvalidVoterWeightRecordForGoverningTokenMint = 0x23F, + /// 576 - Invalid VoterWeightRecord for TokenOwner + #[error("Invalid VoterWeightRecord for TokenOwner")] + InvalidVoterWeightRecordForTokenOwner = 0x240, + /// 577 - VoterWeightRecord expired + #[error("VoterWeightRecord expired")] + VoterWeightRecordExpired = 0x241, + /// 578 - Invalid RealmConfig for Realm + #[error("Invalid RealmConfig for Realm")] + InvalidRealmConfigForRealm = 0x242, + /// 579 - TokenOwnerRecord already exists + #[error("TokenOwnerRecord already exists")] + TokenOwnerRecordAlreadyExists = 0x243, + /// 580 - Governing token deposits not allowed + #[error("Governing token deposits not allowed")] + GoverningTokenDepositsNotAllowed = 0x244, + /// 581 - Invalid vote choice weight percentage + #[error("Invalid vote choice weight percentage")] + InvalidVoteChoiceWeightPercentage = 0x245, + /// 582 - Vote type not supported + #[error("Vote type not supported")] + VoteTypeNotSupported = 0x246, + /// 583 - Invalid proposal options + #[error("Invalid proposal options")] + InvalidProposalOptions = 0x247, + /// 584 - Proposal is not not executable + #[error("Proposal is not not executable")] + ProposalIsNotExecutable = 0x248, + /// 585 - Deny vote is not allowed + #[error("Deny vote is not allowed")] + DenyVoteIsNotAllowed = 0x249, + /// 586 - Cannot execute defeated option + #[error("Cannot execute defeated option")] + CannotExecuteDefeatedOption = 0x24A, + /// 587 - VoterWeightRecord invalid action + #[error("VoterWeightRecord invalid action")] + VoterWeightRecordInvalidAction = 0x24B, + /// 588 - VoterWeightRecord invalid action target + #[error("VoterWeightRecord invalid action target")] + VoterWeightRecordInvalidActionTarget = 0x24C, + /// 589 - Invalid MaxVoterWeightRecord for Realm + #[error("Invalid MaxVoterWeightRecord for Realm")] + InvalidMaxVoterWeightRecordForRealm = 0x24D, + /// 590 - Invalid MaxVoterWeightRecord for GoverningTokenMint + #[error("Invalid MaxVoterWeightRecord for GoverningTokenMint")] + InvalidMaxVoterWeightRecordForGoverningTokenMint = 0x24E, + /// 591 - MaxVoterWeightRecord expired + #[error("MaxVoterWeightRecord expired")] + MaxVoterWeightRecordExpired = 0x24F, + /// 592 - Not supported VoteType + #[error("Not supported VoteType")] + NotSupportedVoteType = 0x250, + /// 593 - RealmConfig change not allowed + #[error("RealmConfig change not allowed")] + RealmConfigChangeNotAllowed = 0x251, + /// 594 - GovernanceConfig change not allowed + #[error("GovernanceConfig change not allowed")] + GovernanceConfigChangeNotAllowed = 0x252, + /// 595 - At least one VoteThreshold is required + #[error("At least one VoteThreshold is required")] + AtLeastOneVoteThresholdRequired = 0x253, + /// 596 - Reserved buffer must be empty + #[error("Reserved buffer must be empty")] + ReservedBufferMustBeEmpty = 0x254, + /// 597 - Cannot Relinquish in Finalizing state + #[error("Cannot Relinquish in Finalizing state")] + CannotRelinquishInFinalizingState = 0x255, + /// 598 - Invalid RealmConfig account address + #[error("Invalid RealmConfig account address")] + InvalidRealmConfigAddress = 0x256, + /// 599 - Cannot deposit dormant tokens + #[error("Cannot deposit dormant tokens")] + CannotDepositDormantTokens = 0x257, + /// 600 - Cannot withdraw membership tokens + #[error("Cannot withdraw membership tokens")] + CannotWithdrawMembershipTokens = 0x258, + /// 601 - Cannot revoke GoverningTokens + #[error("Cannot revoke GoverningTokens")] + CannotRevokeGoverningTokens = 0x259, + /// 602 - Invalid Revoke amount + #[error("Invalid Revoke amount")] + InvalidRevokeAmount = 0x25A, + /// 603 - Invalid GoverningToken source + #[error("Invalid GoverningToken source")] + InvalidGoverningTokenSource = 0x25B, + /// 604 - Cannot change community TokenType to Membership + #[error("Cannot change community TokenType to Membership")] + CannotChangeCommunityTokenTypeToMembership = 0x25C, + /// 605 - Voter weight threshold disabled + #[error("Voter weight threshold disabled")] + VoterWeightThresholdDisabled = 0x25D, + /// 606 - Vote not allowed in cool off time + #[error("Vote not allowed in cool off time")] + VoteNotAllowedInCoolOffTime = 0x25E, + /// 607 - Cannot refund ProposalDeposit + #[error("Cannot refund ProposalDeposit")] + CannotRefundProposalDeposit = 0x25F, + /// 608 - Invalid Proposal for ProposalDeposit + #[error("Invalid Proposal for ProposalDeposit")] + InvalidProposalForProposalDeposit = 0x260, + /// 609 - Invalid deposit_exempt_proposal_count + #[error("Invalid deposit_exempt_proposal_count")] + InvalidDepositExemptProposalCount = 0x261, + /// 610 - GoverningTokenMint not allowed to vote + #[error("GoverningTokenMint not allowed to vote")] + GoverningTokenMintNotAllowedToVote = 0x262, + /// 611 - Invalid deposit Payer for ProposalDeposit + #[error("Invalid deposit Payer for ProposalDeposit")] + InvalidDepositPayerForProposalDeposit = 0x263, + /// 612 - Invalid State: Proposal is not in final state + #[error("Invalid State: Proposal is not in final state")] + InvalidStateNotFinal = 0x264, + /// 613 - Invalid state for proposal state transition to Completed + #[error("Invalid state for proposal state transition to Completed")] + InvalidStateToCompleteProposal = 0x265, + /// 614 - Invalid number of vote choices + #[error("Invalid number of vote choices")] + InvalidNumberOfVoteChoices = 0x266, + /// 615 - Ranked vote is not supported + #[error("Ranked vote is not supported")] + RankedVoteIsNotSupported = 0x267, + /// 616 - Choice weight must be 100% + #[error("Choice weight must be 100%")] + ChoiceWeightMustBe100Percent = 0x268, + /// 617 - Single choice only is allowed + #[error("Single choice only is allowed")] + SingleChoiceOnlyIsAllowed = 0x269, + /// 618 - At least single choice is required + #[error("At least single choice is required")] + AtLeastSingleChoiceIsRequired = 0x26A, + /// 619 - Total vote weight must be 100% + #[error("Total vote weight must be 100%")] + TotalVoteWeightMustBe100Percent = 0x26B, + /// 620 - Invalid multi choice proposal parameters + #[error("Invalid multi choice proposal parameters")] + InvalidMultiChoiceProposalParameters = 0x26C, + /// 621 - Invalid Governance for RequiredSignatory + #[error("Invalid Governance for RequiredSignatory")] + InvalidGovernanceForRequiredSignatory = 0x26D, + /// 622 - Signatory Record has already been created + #[error("Signatory Record has already been created")] + SignatoryRecordAlreadyExists = 0x26E, + /// 623 - Instruction has been removed + #[error("Instruction has been removed")] + InstructionDeprecated = 0x26F, + /// 624 - Proposal is missing required signatories + #[error("Proposal is missing required signatories")] + MissingRequiredSignatories = 0x270, +} + +impl From for solana_program_error::ProgramError { + fn from(e: SplGovernanceError) -> Self { + solana_program_error::ProgramError::Custom(e as u32) + } +} diff --git a/e2e/governance/src/generated/instructions/add_required_signatory.rs b/e2e/governance/src/generated/instructions/add_required_signatory.rs new file mode 100644 index 0000000..0e78413 --- /dev/null +++ b/e2e/governance/src/generated/instructions/add_required_signatory.rs @@ -0,0 +1,454 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +pub const ADD_REQUIRED_SIGNATORY_DISCRIMINATOR: u8 = 29; + +/// Accounts. +#[derive(Debug)] +pub struct AddRequiredSignatory { + /// The Governance account the config is for + pub governance_account: solana_pubkey::Pubkey, + + pub required_signatory_account: solana_pubkey::Pubkey, + + pub payer: solana_pubkey::Pubkey, + + pub system_program: solana_pubkey::Pubkey, +} + +impl AddRequiredSignatory { + pub fn instruction( + &self, + args: AddRequiredSignatoryInstructionArgs, + ) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(args, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + args: AddRequiredSignatoryInstructionArgs, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(4 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + self.governance_account, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.required_signatory_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.payer, true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.system_program, + false, + )); + accounts.extend_from_slice(remaining_accounts); + let mut data = AddRequiredSignatoryInstructionData::new() + .try_to_vec() + .unwrap(); + let mut args = args.try_to_vec().unwrap(); + data.append(&mut args); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct AddRequiredSignatoryInstructionData { + discriminator: u8, +} + +impl AddRequiredSignatoryInstructionData { + pub fn new() -> Self { + Self { discriminator: 29 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for AddRequiredSignatoryInstructionData { + fn default() -> Self { + Self::new() + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct AddRequiredSignatoryInstructionArgs { + pub signatory: Pubkey, +} + +impl AddRequiredSignatoryInstructionArgs { + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +/// Instruction builder for `AddRequiredSignatory`. +/// +/// ### Accounts: +/// +/// 0. `[writable, signer]` governance_account +/// 1. `[writable]` required_signatory_account +/// 2. `[signer]` payer +/// 3. `[optional]` system_program (default to `11111111111111111111111111111111`) +#[derive(Clone, Debug, Default)] +pub struct AddRequiredSignatoryBuilder { + governance_account: Option, + required_signatory_account: Option, + payer: Option, + system_program: Option, + signatory: Option, + __remaining_accounts: Vec, +} + +impl AddRequiredSignatoryBuilder { + pub fn new() -> Self { + Self::default() + } + /// The Governance account the config is for + #[inline(always)] + pub fn governance_account(&mut self, governance_account: solana_pubkey::Pubkey) -> &mut Self { + self.governance_account = Some(governance_account); + self + } + #[inline(always)] + pub fn required_signatory_account( + &mut self, + required_signatory_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.required_signatory_account = Some(required_signatory_account); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: solana_pubkey::Pubkey) -> &mut Self { + self.payer = Some(payer); + self + } + /// `[optional account, default to '11111111111111111111111111111111']` + #[inline(always)] + pub fn system_program(&mut self, system_program: solana_pubkey::Pubkey) -> &mut Self { + self.system_program = Some(system_program); + self + } + #[inline(always)] + pub fn signatory(&mut self, signatory: Pubkey) -> &mut Self { + self.signatory = Some(signatory); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = AddRequiredSignatory { + governance_account: self + .governance_account + .expect("governance_account is not set"), + required_signatory_account: self + .required_signatory_account + .expect("required_signatory_account is not set"), + payer: self.payer.expect("payer is not set"), + system_program: self + .system_program + .unwrap_or(solana_pubkey::pubkey!("11111111111111111111111111111111")), + }; + let args = AddRequiredSignatoryInstructionArgs { + signatory: self.signatory.clone().expect("signatory is not set"), + }; + + accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) + } +} + +/// `add_required_signatory` CPI accounts. +pub struct AddRequiredSignatoryCpiAccounts<'a, 'b> { + /// The Governance account the config is for + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + + pub required_signatory_account: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, +} + +/// `add_required_signatory` CPI instruction. +pub struct AddRequiredSignatoryCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + /// The Governance account the config is for + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + + pub required_signatory_account: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, + /// The arguments for the instruction. + pub __args: AddRequiredSignatoryInstructionArgs, +} + +impl<'a, 'b> AddRequiredSignatoryCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: AddRequiredSignatoryCpiAccounts<'a, 'b>, + args: AddRequiredSignatoryInstructionArgs, + ) -> Self { + Self { + __program: program, + governance_account: accounts.governance_account, + required_signatory_account: accounts.required_signatory_account, + payer: accounts.payer, + system_program: accounts.system_program, + __args: args, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(4 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + *self.governance_account.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.required_signatory_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.payer.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.system_program.key, + false, + )); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let mut data = AddRequiredSignatoryInstructionData::new() + .try_to_vec() + .unwrap(); + let mut args = self.__args.try_to_vec().unwrap(); + data.append(&mut args); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(5 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.governance_account.clone()); + account_infos.push(self.required_signatory_account.clone()); + account_infos.push(self.payer.clone()); + account_infos.push(self.system_program.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `AddRequiredSignatory` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[writable, signer]` governance_account +/// 1. `[writable]` required_signatory_account +/// 2. `[signer]` payer +/// 3. `[]` system_program +#[derive(Clone, Debug)] +pub struct AddRequiredSignatoryCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> AddRequiredSignatoryCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(AddRequiredSignatoryCpiBuilderInstruction { + __program: program, + governance_account: None, + required_signatory_account: None, + payer: None, + system_program: None, + signatory: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + /// The Governance account the config is for + #[inline(always)] + pub fn governance_account( + &mut self, + governance_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_account = Some(governance_account); + self + } + #[inline(always)] + pub fn required_signatory_account( + &mut self, + required_signatory_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.required_signatory_account = Some(required_signatory_account); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: &'b solana_account_info::AccountInfo<'a>) -> &mut Self { + self.instruction.payer = Some(payer); + self + } + #[inline(always)] + pub fn system_program( + &mut self, + system_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.system_program = Some(system_program); + self + } + #[inline(always)] + pub fn signatory(&mut self, signatory: Pubkey) -> &mut Self { + self.instruction.signatory = Some(signatory); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let args = AddRequiredSignatoryInstructionArgs { + signatory: self + .instruction + .signatory + .clone() + .expect("signatory is not set"), + }; + let instruction = AddRequiredSignatoryCpi { + __program: self.instruction.__program, + + governance_account: self + .instruction + .governance_account + .expect("governance_account is not set"), + + required_signatory_account: self + .instruction + .required_signatory_account + .expect("required_signatory_account is not set"), + + payer: self.instruction.payer.expect("payer is not set"), + + system_program: self + .instruction + .system_program + .expect("system_program is not set"), + __args: args, + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct AddRequiredSignatoryCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + governance_account: Option<&'b solana_account_info::AccountInfo<'a>>, + required_signatory_account: Option<&'b solana_account_info::AccountInfo<'a>>, + payer: Option<&'b solana_account_info::AccountInfo<'a>>, + system_program: Option<&'b solana_account_info::AccountInfo<'a>>, + signatory: Option, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/add_signatory.rs b/e2e/governance/src/generated/instructions/add_signatory.rs new file mode 100644 index 0000000..b6616ef --- /dev/null +++ b/e2e/governance/src/generated/instructions/add_signatory.rs @@ -0,0 +1,541 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +pub const ADD_SIGNATORY_DISCRIMINATOR: u8 = 7; + +/// Accounts. +#[derive(Debug)] +pub struct AddSignatory { + /// Proposal Account associated with the governance + pub proposal_account: solana_pubkey::Pubkey, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: solana_pubkey::Pubkey, + /// Governance Authority (Token Owner or Governance Delegate) + pub governance_authority: solana_pubkey::Pubkey, + /// Signatory Record Account + pub signatory_record_account: solana_pubkey::Pubkey, + + pub payer: solana_pubkey::Pubkey, + + pub system_program: solana_pubkey::Pubkey, +} + +impl AddSignatory { + pub fn instruction( + &self, + args: AddSignatoryInstructionArgs, + ) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(args, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + args: AddSignatoryInstructionArgs, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(6 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.token_owner_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governance_authority, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.signatory_record_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.payer, true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.system_program, + false, + )); + accounts.extend_from_slice(remaining_accounts); + let mut data = AddSignatoryInstructionData::new().try_to_vec().unwrap(); + let mut args = args.try_to_vec().unwrap(); + data.append(&mut args); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct AddSignatoryInstructionData { + discriminator: u8, +} + +impl AddSignatoryInstructionData { + pub fn new() -> Self { + Self { discriminator: 7 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for AddSignatoryInstructionData { + fn default() -> Self { + Self::new() + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct AddSignatoryInstructionArgs { + pub signatory: Pubkey, +} + +impl AddSignatoryInstructionArgs { + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +/// Instruction builder for `AddSignatory`. +/// +/// ### Accounts: +/// +/// 0. `[writable]` proposal_account +/// 1. `[]` token_owner_record +/// 2. `[signer]` governance_authority +/// 3. `[writable]` signatory_record_account +/// 4. `[signer]` payer +/// 5. `[optional]` system_program (default to `11111111111111111111111111111111`) +#[derive(Clone, Debug, Default)] +pub struct AddSignatoryBuilder { + proposal_account: Option, + token_owner_record: Option, + governance_authority: Option, + signatory_record_account: Option, + payer: Option, + system_program: Option, + signatory: Option, + __remaining_accounts: Vec, +} + +impl AddSignatoryBuilder { + pub fn new() -> Self { + Self::default() + } + /// Proposal Account associated with the governance + #[inline(always)] + pub fn proposal_account(&mut self, proposal_account: solana_pubkey::Pubkey) -> &mut Self { + self.proposal_account = Some(proposal_account); + self + } + /// TokenOwnerRecord account of the Proposal owner + #[inline(always)] + pub fn token_owner_record(&mut self, token_owner_record: solana_pubkey::Pubkey) -> &mut Self { + self.token_owner_record = Some(token_owner_record); + self + } + /// Governance Authority (Token Owner or Governance Delegate) + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governance_authority = Some(governance_authority); + self + } + /// Signatory Record Account + #[inline(always)] + pub fn signatory_record_account( + &mut self, + signatory_record_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.signatory_record_account = Some(signatory_record_account); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: solana_pubkey::Pubkey) -> &mut Self { + self.payer = Some(payer); + self + } + /// `[optional account, default to '11111111111111111111111111111111']` + #[inline(always)] + pub fn system_program(&mut self, system_program: solana_pubkey::Pubkey) -> &mut Self { + self.system_program = Some(system_program); + self + } + #[inline(always)] + pub fn signatory(&mut self, signatory: Pubkey) -> &mut Self { + self.signatory = Some(signatory); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = AddSignatory { + proposal_account: self.proposal_account.expect("proposal_account is not set"), + token_owner_record: self + .token_owner_record + .expect("token_owner_record is not set"), + governance_authority: self + .governance_authority + .expect("governance_authority is not set"), + signatory_record_account: self + .signatory_record_account + .expect("signatory_record_account is not set"), + payer: self.payer.expect("payer is not set"), + system_program: self + .system_program + .unwrap_or(solana_pubkey::pubkey!("11111111111111111111111111111111")), + }; + let args = AddSignatoryInstructionArgs { + signatory: self.signatory.clone().expect("signatory is not set"), + }; + + accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) + } +} + +/// `add_signatory` CPI accounts. +pub struct AddSignatoryCpiAccounts<'a, 'b> { + /// Proposal Account associated with the governance + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// Governance Authority (Token Owner or Governance Delegate) + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, + /// Signatory Record Account + pub signatory_record_account: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, +} + +/// `add_signatory` CPI instruction. +pub struct AddSignatoryCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + /// Proposal Account associated with the governance + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// Governance Authority (Token Owner or Governance Delegate) + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, + /// Signatory Record Account + pub signatory_record_account: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, + /// The arguments for the instruction. + pub __args: AddSignatoryInstructionArgs, +} + +impl<'a, 'b> AddSignatoryCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: AddSignatoryCpiAccounts<'a, 'b>, + args: AddSignatoryInstructionArgs, + ) -> Self { + Self { + __program: program, + proposal_account: accounts.proposal_account, + token_owner_record: accounts.token_owner_record, + governance_authority: accounts.governance_authority, + signatory_record_account: accounts.signatory_record_account, + payer: accounts.payer, + system_program: accounts.system_program, + __args: args, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(6 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.token_owner_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governance_authority.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.signatory_record_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.payer.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.system_program.key, + false, + )); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let mut data = AddSignatoryInstructionData::new().try_to_vec().unwrap(); + let mut args = self.__args.try_to_vec().unwrap(); + data.append(&mut args); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(7 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.proposal_account.clone()); + account_infos.push(self.token_owner_record.clone()); + account_infos.push(self.governance_authority.clone()); + account_infos.push(self.signatory_record_account.clone()); + account_infos.push(self.payer.clone()); + account_infos.push(self.system_program.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `AddSignatory` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[writable]` proposal_account +/// 1. `[]` token_owner_record +/// 2. `[signer]` governance_authority +/// 3. `[writable]` signatory_record_account +/// 4. `[signer]` payer +/// 5. `[]` system_program +#[derive(Clone, Debug)] +pub struct AddSignatoryCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> AddSignatoryCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(AddSignatoryCpiBuilderInstruction { + __program: program, + proposal_account: None, + token_owner_record: None, + governance_authority: None, + signatory_record_account: None, + payer: None, + system_program: None, + signatory: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + /// Proposal Account associated with the governance + #[inline(always)] + pub fn proposal_account( + &mut self, + proposal_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_account = Some(proposal_account); + self + } + /// TokenOwnerRecord account of the Proposal owner + #[inline(always)] + pub fn token_owner_record( + &mut self, + token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_owner_record = Some(token_owner_record); + self + } + /// Governance Authority (Token Owner or Governance Delegate) + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_authority = Some(governance_authority); + self + } + /// Signatory Record Account + #[inline(always)] + pub fn signatory_record_account( + &mut self, + signatory_record_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.signatory_record_account = Some(signatory_record_account); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: &'b solana_account_info::AccountInfo<'a>) -> &mut Self { + self.instruction.payer = Some(payer); + self + } + #[inline(always)] + pub fn system_program( + &mut self, + system_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.system_program = Some(system_program); + self + } + #[inline(always)] + pub fn signatory(&mut self, signatory: Pubkey) -> &mut Self { + self.instruction.signatory = Some(signatory); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let args = AddSignatoryInstructionArgs { + signatory: self + .instruction + .signatory + .clone() + .expect("signatory is not set"), + }; + let instruction = AddSignatoryCpi { + __program: self.instruction.__program, + + proposal_account: self + .instruction + .proposal_account + .expect("proposal_account is not set"), + + token_owner_record: self + .instruction + .token_owner_record + .expect("token_owner_record is not set"), + + governance_authority: self + .instruction + .governance_authority + .expect("governance_authority is not set"), + + signatory_record_account: self + .instruction + .signatory_record_account + .expect("signatory_record_account is not set"), + + payer: self.instruction.payer.expect("payer is not set"), + + system_program: self + .instruction + .system_program + .expect("system_program is not set"), + __args: args, + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct AddSignatoryCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + proposal_account: Option<&'b solana_account_info::AccountInfo<'a>>, + token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + governance_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + signatory_record_account: Option<&'b solana_account_info::AccountInfo<'a>>, + payer: Option<&'b solana_account_info::AccountInfo<'a>>, + system_program: Option<&'b solana_account_info::AccountInfo<'a>>, + signatory: Option, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/cancel_proposal.rs b/e2e/governance/src/generated/instructions/cancel_proposal.rs new file mode 100644 index 0000000..ad46ea8 --- /dev/null +++ b/e2e/governance/src/generated/instructions/cancel_proposal.rs @@ -0,0 +1,447 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const CANCEL_PROPOSAL_DISCRIMINATOR: u8 = 11; + +/// Accounts. +#[derive(Debug)] +pub struct CancelProposal { + pub realm_account: solana_pubkey::Pubkey, + + pub governance_account: solana_pubkey::Pubkey, + + pub proposal_account: solana_pubkey::Pubkey, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: solana_pubkey::Pubkey, + /// Governance authority (Token Owner or Governance Delegate) + pub governance_authority: solana_pubkey::Pubkey, +} + +impl CancelProposal { + pub fn instruction(&self) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(&[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(5 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + self.realm_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.governance_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.token_owner_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governance_authority, + true, + )); + accounts.extend_from_slice(remaining_accounts); + let data = CancelProposalInstructionData::new().try_to_vec().unwrap(); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CancelProposalInstructionData { + discriminator: u8, +} + +impl CancelProposalInstructionData { + pub fn new() -> Self { + Self { discriminator: 11 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for CancelProposalInstructionData { + fn default() -> Self { + Self::new() + } +} + +/// Instruction builder for `CancelProposal`. +/// +/// ### Accounts: +/// +/// 0. `[writable]` realm_account +/// 1. `[writable]` governance_account +/// 2. `[writable]` proposal_account +/// 3. `[writable]` token_owner_record +/// 4. `[signer]` governance_authority +#[derive(Clone, Debug, Default)] +pub struct CancelProposalBuilder { + realm_account: Option, + governance_account: Option, + proposal_account: Option, + token_owner_record: Option, + governance_authority: Option, + __remaining_accounts: Vec, +} + +impl CancelProposalBuilder { + pub fn new() -> Self { + Self::default() + } + #[inline(always)] + pub fn realm_account(&mut self, realm_account: solana_pubkey::Pubkey) -> &mut Self { + self.realm_account = Some(realm_account); + self + } + #[inline(always)] + pub fn governance_account(&mut self, governance_account: solana_pubkey::Pubkey) -> &mut Self { + self.governance_account = Some(governance_account); + self + } + #[inline(always)] + pub fn proposal_account(&mut self, proposal_account: solana_pubkey::Pubkey) -> &mut Self { + self.proposal_account = Some(proposal_account); + self + } + /// TokenOwnerRecord account of the Proposal owner + #[inline(always)] + pub fn token_owner_record(&mut self, token_owner_record: solana_pubkey::Pubkey) -> &mut Self { + self.token_owner_record = Some(token_owner_record); + self + } + /// Governance authority (Token Owner or Governance Delegate) + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governance_authority = Some(governance_authority); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = CancelProposal { + realm_account: self.realm_account.expect("realm_account is not set"), + governance_account: self + .governance_account + .expect("governance_account is not set"), + proposal_account: self.proposal_account.expect("proposal_account is not set"), + token_owner_record: self + .token_owner_record + .expect("token_owner_record is not set"), + governance_authority: self + .governance_authority + .expect("governance_authority is not set"), + }; + + accounts.instruction_with_remaining_accounts(&self.__remaining_accounts) + } +} + +/// `cancel_proposal` CPI accounts. +pub struct CancelProposalCpiAccounts<'a, 'b> { + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// Governance authority (Token Owner or Governance Delegate) + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, +} + +/// `cancel_proposal` CPI instruction. +pub struct CancelProposalCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// Governance authority (Token Owner or Governance Delegate) + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, +} + +impl<'a, 'b> CancelProposalCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: CancelProposalCpiAccounts<'a, 'b>, + ) -> Self { + Self { + __program: program, + realm_account: accounts.realm_account, + governance_account: accounts.governance_account, + proposal_account: accounts.proposal_account, + token_owner_record: accounts.token_owner_record, + governance_authority: accounts.governance_authority, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(5 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + *self.realm_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.governance_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.token_owner_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governance_authority.key, + true, + )); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let data = CancelProposalInstructionData::new().try_to_vec().unwrap(); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(6 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.realm_account.clone()); + account_infos.push(self.governance_account.clone()); + account_infos.push(self.proposal_account.clone()); + account_infos.push(self.token_owner_record.clone()); + account_infos.push(self.governance_authority.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `CancelProposal` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[writable]` realm_account +/// 1. `[writable]` governance_account +/// 2. `[writable]` proposal_account +/// 3. `[writable]` token_owner_record +/// 4. `[signer]` governance_authority +#[derive(Clone, Debug)] +pub struct CancelProposalCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> CancelProposalCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(CancelProposalCpiBuilderInstruction { + __program: program, + realm_account: None, + governance_account: None, + proposal_account: None, + token_owner_record: None, + governance_authority: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + #[inline(always)] + pub fn realm_account( + &mut self, + realm_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_account = Some(realm_account); + self + } + #[inline(always)] + pub fn governance_account( + &mut self, + governance_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_account = Some(governance_account); + self + } + #[inline(always)] + pub fn proposal_account( + &mut self, + proposal_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_account = Some(proposal_account); + self + } + /// TokenOwnerRecord account of the Proposal owner + #[inline(always)] + pub fn token_owner_record( + &mut self, + token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_owner_record = Some(token_owner_record); + self + } + /// Governance authority (Token Owner or Governance Delegate) + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_authority = Some(governance_authority); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let instruction = CancelProposalCpi { + __program: self.instruction.__program, + + realm_account: self + .instruction + .realm_account + .expect("realm_account is not set"), + + governance_account: self + .instruction + .governance_account + .expect("governance_account is not set"), + + proposal_account: self + .instruction + .proposal_account + .expect("proposal_account is not set"), + + token_owner_record: self + .instruction + .token_owner_record + .expect("token_owner_record is not set"), + + governance_authority: self + .instruction + .governance_authority + .expect("governance_authority is not set"), + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct CancelProposalCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + realm_account: Option<&'b solana_account_info::AccountInfo<'a>>, + governance_account: Option<&'b solana_account_info::AccountInfo<'a>>, + proposal_account: Option<&'b solana_account_info::AccountInfo<'a>>, + token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + governance_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/cast_vote.rs b/e2e/governance/src/generated/instructions/cast_vote.rs new file mode 100644 index 0000000..79388f7 --- /dev/null +++ b/e2e/governance/src/generated/instructions/cast_vote.rs @@ -0,0 +1,896 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::Vote; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const CAST_VOTE_DISCRIMINATOR: u8 = 13; + +/// Accounts. +#[derive(Debug)] +pub struct CastVote { + pub realm_account: solana_pubkey::Pubkey, + + pub governance_account: solana_pubkey::Pubkey, + + pub proposal_account: solana_pubkey::Pubkey, + /// TokenOwnerRecord of the Proposal owner + pub proposal_token_owner_record: solana_pubkey::Pubkey, + /// TokenOwnerRecord of the voter. PDA seeds: ['governance',realm, vote_governing_token_mint, governing_token_owner] + pub voter_token_owner_record: solana_pubkey::Pubkey, + /// Governance Authority (Token Owner or Governance Delegate) + pub governance_authority: solana_pubkey::Pubkey, + /// Proposal VoteRecord account. PDA seeds: ['governance',proposal,token_owner_record] + pub proposal_vote_record: solana_pubkey::Pubkey, + /// The Governing Token Mint which is used to cast the vote (vote_governing_token_mint). + /// The voting token mint is the governing_token_mint of the Proposal for Approve, Deny and Abstain votes. + /// For Veto vote the voting token mint is the mint of the opposite voting population. + /// Council mint to veto Community proposals and Community mint to veto Council proposals + /// Note: In the current version only Council veto is supported + pub governing_token_mint: solana_pubkey::Pubkey, + + pub payer: solana_pubkey::Pubkey, + + pub system_program: solana_pubkey::Pubkey, + /// RealmConfig account. PDA seeds: ['realm-config', realm] + pub realm_config_account: solana_pubkey::Pubkey, + /// Optional Voter Weight Record + pub voter_weight_record: Option, + /// Optional Max Voter Weight Record + pub max_voter_weight_record: Option, +} + +impl CastVote { + pub fn instruction(&self, args: CastVoteInstructionArgs) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(args, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + args: CastVoteInstructionArgs, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(13 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.governance_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_token_owner_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.voter_token_owner_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governance_authority, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_vote_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governing_token_mint, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.payer, true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.system_program, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_config_account, + false, + )); + if let Some(voter_weight_record) = self.voter_weight_record { + accounts.push(solana_instruction::AccountMeta::new_readonly( + voter_weight_record, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(max_voter_weight_record) = self.max_voter_weight_record { + accounts.push(solana_instruction::AccountMeta::new_readonly( + max_voter_weight_record, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + accounts.extend_from_slice(remaining_accounts); + let mut data = CastVoteInstructionData::new().try_to_vec().unwrap(); + let mut args = args.try_to_vec().unwrap(); + data.append(&mut args); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CastVoteInstructionData { + discriminator: u8, +} + +impl CastVoteInstructionData { + pub fn new() -> Self { + Self { discriminator: 13 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for CastVoteInstructionData { + fn default() -> Self { + Self::new() + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CastVoteInstructionArgs { + pub vote: Vote, +} + +impl CastVoteInstructionArgs { + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +/// Instruction builder for `CastVote`. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[writable]` governance_account +/// 2. `[writable]` proposal_account +/// 3. `[writable]` proposal_token_owner_record +/// 4. `[writable]` voter_token_owner_record +/// 5. `[signer]` governance_authority +/// 6. `[writable]` proposal_vote_record +/// 7. `[]` governing_token_mint +/// 8. `[signer]` payer +/// 9. `[optional]` system_program (default to `11111111111111111111111111111111`) +/// 10. `[]` realm_config_account +/// 11. `[optional]` voter_weight_record +/// 12. `[optional]` max_voter_weight_record +#[derive(Clone, Debug, Default)] +pub struct CastVoteBuilder { + realm_account: Option, + governance_account: Option, + proposal_account: Option, + proposal_token_owner_record: Option, + voter_token_owner_record: Option, + governance_authority: Option, + proposal_vote_record: Option, + governing_token_mint: Option, + payer: Option, + system_program: Option, + realm_config_account: Option, + voter_weight_record: Option, + max_voter_weight_record: Option, + vote: Option, + __remaining_accounts: Vec, +} + +impl CastVoteBuilder { + pub fn new() -> Self { + Self::default() + } + #[inline(always)] + pub fn realm_account(&mut self, realm_account: solana_pubkey::Pubkey) -> &mut Self { + self.realm_account = Some(realm_account); + self + } + #[inline(always)] + pub fn governance_account(&mut self, governance_account: solana_pubkey::Pubkey) -> &mut Self { + self.governance_account = Some(governance_account); + self + } + #[inline(always)] + pub fn proposal_account(&mut self, proposal_account: solana_pubkey::Pubkey) -> &mut Self { + self.proposal_account = Some(proposal_account); + self + } + /// TokenOwnerRecord of the Proposal owner + #[inline(always)] + pub fn proposal_token_owner_record( + &mut self, + proposal_token_owner_record: solana_pubkey::Pubkey, + ) -> &mut Self { + self.proposal_token_owner_record = Some(proposal_token_owner_record); + self + } + /// TokenOwnerRecord of the voter. PDA seeds: ['governance',realm, vote_governing_token_mint, governing_token_owner] + #[inline(always)] + pub fn voter_token_owner_record( + &mut self, + voter_token_owner_record: solana_pubkey::Pubkey, + ) -> &mut Self { + self.voter_token_owner_record = Some(voter_token_owner_record); + self + } + /// Governance Authority (Token Owner or Governance Delegate) + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governance_authority = Some(governance_authority); + self + } + /// Proposal VoteRecord account. PDA seeds: ['governance',proposal,token_owner_record] + #[inline(always)] + pub fn proposal_vote_record( + &mut self, + proposal_vote_record: solana_pubkey::Pubkey, + ) -> &mut Self { + self.proposal_vote_record = Some(proposal_vote_record); + self + } + /// The Governing Token Mint which is used to cast the vote (vote_governing_token_mint). + /// The voting token mint is the governing_token_mint of the Proposal for Approve, Deny and Abstain votes. + /// For Veto vote the voting token mint is the mint of the opposite voting population. + /// Council mint to veto Community proposals and Community mint to veto Council proposals + /// Note: In the current version only Council veto is supported + #[inline(always)] + pub fn governing_token_mint( + &mut self, + governing_token_mint: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governing_token_mint = Some(governing_token_mint); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: solana_pubkey::Pubkey) -> &mut Self { + self.payer = Some(payer); + self + } + /// `[optional account, default to '11111111111111111111111111111111']` + #[inline(always)] + pub fn system_program(&mut self, system_program: solana_pubkey::Pubkey) -> &mut Self { + self.system_program = Some(system_program); + self + } + /// RealmConfig account. PDA seeds: ['realm-config', realm] + #[inline(always)] + pub fn realm_config_account( + &mut self, + realm_config_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.realm_config_account = Some(realm_config_account); + self + } + /// `[optional account]` + /// Optional Voter Weight Record + #[inline(always)] + pub fn voter_weight_record( + &mut self, + voter_weight_record: Option, + ) -> &mut Self { + self.voter_weight_record = voter_weight_record; + self + } + /// `[optional account]` + /// Optional Max Voter Weight Record + #[inline(always)] + pub fn max_voter_weight_record( + &mut self, + max_voter_weight_record: Option, + ) -> &mut Self { + self.max_voter_weight_record = max_voter_weight_record; + self + } + #[inline(always)] + pub fn vote(&mut self, vote: Vote) -> &mut Self { + self.vote = Some(vote); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = CastVote { + realm_account: self.realm_account.expect("realm_account is not set"), + governance_account: self + .governance_account + .expect("governance_account is not set"), + proposal_account: self.proposal_account.expect("proposal_account is not set"), + proposal_token_owner_record: self + .proposal_token_owner_record + .expect("proposal_token_owner_record is not set"), + voter_token_owner_record: self + .voter_token_owner_record + .expect("voter_token_owner_record is not set"), + governance_authority: self + .governance_authority + .expect("governance_authority is not set"), + proposal_vote_record: self + .proposal_vote_record + .expect("proposal_vote_record is not set"), + governing_token_mint: self + .governing_token_mint + .expect("governing_token_mint is not set"), + payer: self.payer.expect("payer is not set"), + system_program: self + .system_program + .unwrap_or(solana_pubkey::pubkey!("11111111111111111111111111111111")), + realm_config_account: self + .realm_config_account + .expect("realm_config_account is not set"), + voter_weight_record: self.voter_weight_record, + max_voter_weight_record: self.max_voter_weight_record, + }; + let args = CastVoteInstructionArgs { + vote: self.vote.clone().expect("vote is not set"), + }; + + accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) + } +} + +/// `cast_vote` CPI accounts. +pub struct CastVoteCpiAccounts<'a, 'b> { + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord of the Proposal owner + pub proposal_token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord of the voter. PDA seeds: ['governance',realm, vote_governing_token_mint, governing_token_owner] + pub voter_token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// Governance Authority (Token Owner or Governance Delegate) + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, + /// Proposal VoteRecord account. PDA seeds: ['governance',proposal,token_owner_record] + pub proposal_vote_record: &'b solana_account_info::AccountInfo<'a>, + /// The Governing Token Mint which is used to cast the vote (vote_governing_token_mint). + /// The voting token mint is the governing_token_mint of the Proposal for Approve, Deny and Abstain votes. + /// For Veto vote the voting token mint is the mint of the opposite voting population. + /// Council mint to veto Community proposals and Community mint to veto Council proposals + /// Note: In the current version only Council veto is supported + pub governing_token_mint: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, + /// RealmConfig account. PDA seeds: ['realm-config', realm] + pub realm_config_account: &'b solana_account_info::AccountInfo<'a>, + /// Optional Voter Weight Record + pub voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional Max Voter Weight Record + pub max_voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, +} + +/// `cast_vote` CPI instruction. +pub struct CastVoteCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord of the Proposal owner + pub proposal_token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord of the voter. PDA seeds: ['governance',realm, vote_governing_token_mint, governing_token_owner] + pub voter_token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// Governance Authority (Token Owner or Governance Delegate) + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, + /// Proposal VoteRecord account. PDA seeds: ['governance',proposal,token_owner_record] + pub proposal_vote_record: &'b solana_account_info::AccountInfo<'a>, + /// The Governing Token Mint which is used to cast the vote (vote_governing_token_mint). + /// The voting token mint is the governing_token_mint of the Proposal for Approve, Deny and Abstain votes. + /// For Veto vote the voting token mint is the mint of the opposite voting population. + /// Council mint to veto Community proposals and Community mint to veto Council proposals + /// Note: In the current version only Council veto is supported + pub governing_token_mint: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, + /// RealmConfig account. PDA seeds: ['realm-config', realm] + pub realm_config_account: &'b solana_account_info::AccountInfo<'a>, + /// Optional Voter Weight Record + pub voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional Max Voter Weight Record + pub max_voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + /// The arguments for the instruction. + pub __args: CastVoteInstructionArgs, +} + +impl<'a, 'b> CastVoteCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: CastVoteCpiAccounts<'a, 'b>, + args: CastVoteInstructionArgs, + ) -> Self { + Self { + __program: program, + realm_account: accounts.realm_account, + governance_account: accounts.governance_account, + proposal_account: accounts.proposal_account, + proposal_token_owner_record: accounts.proposal_token_owner_record, + voter_token_owner_record: accounts.voter_token_owner_record, + governance_authority: accounts.governance_authority, + proposal_vote_record: accounts.proposal_vote_record, + governing_token_mint: accounts.governing_token_mint, + payer: accounts.payer, + system_program: accounts.system_program, + realm_config_account: accounts.realm_config_account, + voter_weight_record: accounts.voter_weight_record, + max_voter_weight_record: accounts.max_voter_weight_record, + __args: args, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(13 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.governance_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_token_owner_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.voter_token_owner_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governance_authority.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_vote_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governing_token_mint.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.payer.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.system_program.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_config_account.key, + false, + )); + if let Some(voter_weight_record) = self.voter_weight_record { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *voter_weight_record.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(max_voter_weight_record) = self.max_voter_weight_record { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *max_voter_weight_record.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let mut data = CastVoteInstructionData::new().try_to_vec().unwrap(); + let mut args = self.__args.try_to_vec().unwrap(); + data.append(&mut args); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(14 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.realm_account.clone()); + account_infos.push(self.governance_account.clone()); + account_infos.push(self.proposal_account.clone()); + account_infos.push(self.proposal_token_owner_record.clone()); + account_infos.push(self.voter_token_owner_record.clone()); + account_infos.push(self.governance_authority.clone()); + account_infos.push(self.proposal_vote_record.clone()); + account_infos.push(self.governing_token_mint.clone()); + account_infos.push(self.payer.clone()); + account_infos.push(self.system_program.clone()); + account_infos.push(self.realm_config_account.clone()); + if let Some(voter_weight_record) = self.voter_weight_record { + account_infos.push(voter_weight_record.clone()); + } + if let Some(max_voter_weight_record) = self.max_voter_weight_record { + account_infos.push(max_voter_weight_record.clone()); + } + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `CastVote` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[writable]` governance_account +/// 2. `[writable]` proposal_account +/// 3. `[writable]` proposal_token_owner_record +/// 4. `[writable]` voter_token_owner_record +/// 5. `[signer]` governance_authority +/// 6. `[writable]` proposal_vote_record +/// 7. `[]` governing_token_mint +/// 8. `[signer]` payer +/// 9. `[]` system_program +/// 10. `[]` realm_config_account +/// 11. `[optional]` voter_weight_record +/// 12. `[optional]` max_voter_weight_record +#[derive(Clone, Debug)] +pub struct CastVoteCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> CastVoteCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(CastVoteCpiBuilderInstruction { + __program: program, + realm_account: None, + governance_account: None, + proposal_account: None, + proposal_token_owner_record: None, + voter_token_owner_record: None, + governance_authority: None, + proposal_vote_record: None, + governing_token_mint: None, + payer: None, + system_program: None, + realm_config_account: None, + voter_weight_record: None, + max_voter_weight_record: None, + vote: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + #[inline(always)] + pub fn realm_account( + &mut self, + realm_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_account = Some(realm_account); + self + } + #[inline(always)] + pub fn governance_account( + &mut self, + governance_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_account = Some(governance_account); + self + } + #[inline(always)] + pub fn proposal_account( + &mut self, + proposal_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_account = Some(proposal_account); + self + } + /// TokenOwnerRecord of the Proposal owner + #[inline(always)] + pub fn proposal_token_owner_record( + &mut self, + proposal_token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_token_owner_record = Some(proposal_token_owner_record); + self + } + /// TokenOwnerRecord of the voter. PDA seeds: ['governance',realm, vote_governing_token_mint, governing_token_owner] + #[inline(always)] + pub fn voter_token_owner_record( + &mut self, + voter_token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.voter_token_owner_record = Some(voter_token_owner_record); + self + } + /// Governance Authority (Token Owner or Governance Delegate) + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_authority = Some(governance_authority); + self + } + /// Proposal VoteRecord account. PDA seeds: ['governance',proposal,token_owner_record] + #[inline(always)] + pub fn proposal_vote_record( + &mut self, + proposal_vote_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_vote_record = Some(proposal_vote_record); + self + } + /// The Governing Token Mint which is used to cast the vote (vote_governing_token_mint). + /// The voting token mint is the governing_token_mint of the Proposal for Approve, Deny and Abstain votes. + /// For Veto vote the voting token mint is the mint of the opposite voting population. + /// Council mint to veto Community proposals and Community mint to veto Council proposals + /// Note: In the current version only Council veto is supported + #[inline(always)] + pub fn governing_token_mint( + &mut self, + governing_token_mint: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governing_token_mint = Some(governing_token_mint); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: &'b solana_account_info::AccountInfo<'a>) -> &mut Self { + self.instruction.payer = Some(payer); + self + } + #[inline(always)] + pub fn system_program( + &mut self, + system_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.system_program = Some(system_program); + self + } + /// RealmConfig account. PDA seeds: ['realm-config', realm] + #[inline(always)] + pub fn realm_config_account( + &mut self, + realm_config_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_config_account = Some(realm_config_account); + self + } + /// `[optional account]` + /// Optional Voter Weight Record + #[inline(always)] + pub fn voter_weight_record( + &mut self, + voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.voter_weight_record = voter_weight_record; + self + } + /// `[optional account]` + /// Optional Max Voter Weight Record + #[inline(always)] + pub fn max_voter_weight_record( + &mut self, + max_voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.max_voter_weight_record = max_voter_weight_record; + self + } + #[inline(always)] + pub fn vote(&mut self, vote: Vote) -> &mut Self { + self.instruction.vote = Some(vote); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let args = CastVoteInstructionArgs { + vote: self.instruction.vote.clone().expect("vote is not set"), + }; + let instruction = CastVoteCpi { + __program: self.instruction.__program, + + realm_account: self + .instruction + .realm_account + .expect("realm_account is not set"), + + governance_account: self + .instruction + .governance_account + .expect("governance_account is not set"), + + proposal_account: self + .instruction + .proposal_account + .expect("proposal_account is not set"), + + proposal_token_owner_record: self + .instruction + .proposal_token_owner_record + .expect("proposal_token_owner_record is not set"), + + voter_token_owner_record: self + .instruction + .voter_token_owner_record + .expect("voter_token_owner_record is not set"), + + governance_authority: self + .instruction + .governance_authority + .expect("governance_authority is not set"), + + proposal_vote_record: self + .instruction + .proposal_vote_record + .expect("proposal_vote_record is not set"), + + governing_token_mint: self + .instruction + .governing_token_mint + .expect("governing_token_mint is not set"), + + payer: self.instruction.payer.expect("payer is not set"), + + system_program: self + .instruction + .system_program + .expect("system_program is not set"), + + realm_config_account: self + .instruction + .realm_config_account + .expect("realm_config_account is not set"), + + voter_weight_record: self.instruction.voter_weight_record, + + max_voter_weight_record: self.instruction.max_voter_weight_record, + __args: args, + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct CastVoteCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + realm_account: Option<&'b solana_account_info::AccountInfo<'a>>, + governance_account: Option<&'b solana_account_info::AccountInfo<'a>>, + proposal_account: Option<&'b solana_account_info::AccountInfo<'a>>, + proposal_token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + voter_token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + governance_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + proposal_vote_record: Option<&'b solana_account_info::AccountInfo<'a>>, + governing_token_mint: Option<&'b solana_account_info::AccountInfo<'a>>, + payer: Option<&'b solana_account_info::AccountInfo<'a>>, + system_program: Option<&'b solana_account_info::AccountInfo<'a>>, + realm_config_account: Option<&'b solana_account_info::AccountInfo<'a>>, + voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + max_voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + vote: Option, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/complete_proposal.rs b/e2e/governance/src/generated/instructions/complete_proposal.rs new file mode 100644 index 0000000..2410dc2 --- /dev/null +++ b/e2e/governance/src/generated/instructions/complete_proposal.rs @@ -0,0 +1,365 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const COMPLETE_PROPOSAL_DISCRIMINATOR: u8 = 28; + +/// Accounts. +#[derive(Debug)] +pub struct CompleteProposal { + pub proposal_account: solana_pubkey::Pubkey, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: solana_pubkey::Pubkey, + /// Token Owner or Delegate + pub complete_proposal_authority: solana_pubkey::Pubkey, +} + +impl CompleteProposal { + pub fn instruction(&self) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(&[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(3 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.token_owner_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.complete_proposal_authority, + true, + )); + accounts.extend_from_slice(remaining_accounts); + let data = CompleteProposalInstructionData::new().try_to_vec().unwrap(); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CompleteProposalInstructionData { + discriminator: u8, +} + +impl CompleteProposalInstructionData { + pub fn new() -> Self { + Self { discriminator: 28 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for CompleteProposalInstructionData { + fn default() -> Self { + Self::new() + } +} + +/// Instruction builder for `CompleteProposal`. +/// +/// ### Accounts: +/// +/// 0. `[writable]` proposal_account +/// 1. `[]` token_owner_record +/// 2. `[signer]` complete_proposal_authority +#[derive(Clone, Debug, Default)] +pub struct CompleteProposalBuilder { + proposal_account: Option, + token_owner_record: Option, + complete_proposal_authority: Option, + __remaining_accounts: Vec, +} + +impl CompleteProposalBuilder { + pub fn new() -> Self { + Self::default() + } + #[inline(always)] + pub fn proposal_account(&mut self, proposal_account: solana_pubkey::Pubkey) -> &mut Self { + self.proposal_account = Some(proposal_account); + self + } + /// TokenOwnerRecord account of the Proposal owner + #[inline(always)] + pub fn token_owner_record(&mut self, token_owner_record: solana_pubkey::Pubkey) -> &mut Self { + self.token_owner_record = Some(token_owner_record); + self + } + /// Token Owner or Delegate + #[inline(always)] + pub fn complete_proposal_authority( + &mut self, + complete_proposal_authority: solana_pubkey::Pubkey, + ) -> &mut Self { + self.complete_proposal_authority = Some(complete_proposal_authority); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = CompleteProposal { + proposal_account: self.proposal_account.expect("proposal_account is not set"), + token_owner_record: self + .token_owner_record + .expect("token_owner_record is not set"), + complete_proposal_authority: self + .complete_proposal_authority + .expect("complete_proposal_authority is not set"), + }; + + accounts.instruction_with_remaining_accounts(&self.__remaining_accounts) + } +} + +/// `complete_proposal` CPI accounts. +pub struct CompleteProposalCpiAccounts<'a, 'b> { + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// Token Owner or Delegate + pub complete_proposal_authority: &'b solana_account_info::AccountInfo<'a>, +} + +/// `complete_proposal` CPI instruction. +pub struct CompleteProposalCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// Token Owner or Delegate + pub complete_proposal_authority: &'b solana_account_info::AccountInfo<'a>, +} + +impl<'a, 'b> CompleteProposalCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: CompleteProposalCpiAccounts<'a, 'b>, + ) -> Self { + Self { + __program: program, + proposal_account: accounts.proposal_account, + token_owner_record: accounts.token_owner_record, + complete_proposal_authority: accounts.complete_proposal_authority, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(3 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.token_owner_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.complete_proposal_authority.key, + true, + )); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let data = CompleteProposalInstructionData::new().try_to_vec().unwrap(); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(4 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.proposal_account.clone()); + account_infos.push(self.token_owner_record.clone()); + account_infos.push(self.complete_proposal_authority.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `CompleteProposal` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[writable]` proposal_account +/// 1. `[]` token_owner_record +/// 2. `[signer]` complete_proposal_authority +#[derive(Clone, Debug)] +pub struct CompleteProposalCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> CompleteProposalCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(CompleteProposalCpiBuilderInstruction { + __program: program, + proposal_account: None, + token_owner_record: None, + complete_proposal_authority: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + #[inline(always)] + pub fn proposal_account( + &mut self, + proposal_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_account = Some(proposal_account); + self + } + /// TokenOwnerRecord account of the Proposal owner + #[inline(always)] + pub fn token_owner_record( + &mut self, + token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_owner_record = Some(token_owner_record); + self + } + /// Token Owner or Delegate + #[inline(always)] + pub fn complete_proposal_authority( + &mut self, + complete_proposal_authority: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.complete_proposal_authority = Some(complete_proposal_authority); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let instruction = CompleteProposalCpi { + __program: self.instruction.__program, + + proposal_account: self + .instruction + .proposal_account + .expect("proposal_account is not set"), + + token_owner_record: self + .instruction + .token_owner_record + .expect("token_owner_record is not set"), + + complete_proposal_authority: self + .instruction + .complete_proposal_authority + .expect("complete_proposal_authority is not set"), + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct CompleteProposalCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + proposal_account: Option<&'b solana_account_info::AccountInfo<'a>>, + token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + complete_proposal_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/create_governance.rs b/e2e/governance/src/generated/instructions/create_governance.rs new file mode 100644 index 0000000..b9c2767 --- /dev/null +++ b/e2e/governance/src/generated/instructions/create_governance.rs @@ -0,0 +1,689 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceConfig; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const CREATE_GOVERNANCE_DISCRIMINATOR: u8 = 4; + +/// Accounts. +#[derive(Debug)] +pub struct CreateGovernance { + /// Realm account the created governance belongs to + pub realm_account: solana_pubkey::Pubkey, + /// seeds=['account-governance', realm, governed_account] + pub governance_account: solana_pubkey::Pubkey, + /// Account governed by this Governance (governing_account). + /// Note: the account doesn't have to exist and can be used only as a unique identified for the Governance account + pub governed_account: solana_pubkey::Pubkey, + /// Used only if not signed by RealmAuthority + pub governing_token_owner_record: solana_pubkey::Pubkey, + + pub payer: solana_pubkey::Pubkey, + + pub system_program: solana_pubkey::Pubkey, + + pub governance_authority: solana_pubkey::Pubkey, + /// seeds=['realm-config', realm] + pub realm_config_account: solana_pubkey::Pubkey, + /// Optional Voter Weight Record + pub voter_weight_record: Option, +} + +impl CreateGovernance { + pub fn instruction( + &self, + args: CreateGovernanceInstructionArgs, + ) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(args, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + args: CreateGovernanceInstructionArgs, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(9 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.governance_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governed_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governing_token_owner_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.payer, true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.system_program, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governance_authority, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_config_account, + false, + )); + if let Some(voter_weight_record) = self.voter_weight_record { + accounts.push(solana_instruction::AccountMeta::new_readonly( + voter_weight_record, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + accounts.extend_from_slice(remaining_accounts); + let mut data = CreateGovernanceInstructionData::new().try_to_vec().unwrap(); + let mut args = args.try_to_vec().unwrap(); + data.append(&mut args); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CreateGovernanceInstructionData { + discriminator: u8, +} + +impl CreateGovernanceInstructionData { + pub fn new() -> Self { + Self { discriminator: 4 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for CreateGovernanceInstructionData { + fn default() -> Self { + Self::new() + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CreateGovernanceInstructionArgs { + pub config: GovernanceConfig, +} + +impl CreateGovernanceInstructionArgs { + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +/// Instruction builder for `CreateGovernance`. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[writable]` governance_account +/// 2. `[]` governed_account +/// 3. `[]` governing_token_owner_record +/// 4. `[signer]` payer +/// 5. `[optional]` system_program (default to `11111111111111111111111111111111`) +/// 6. `[signer]` governance_authority +/// 7. `[]` realm_config_account +/// 8. `[optional]` voter_weight_record +#[derive(Clone, Debug, Default)] +pub struct CreateGovernanceBuilder { + realm_account: Option, + governance_account: Option, + governed_account: Option, + governing_token_owner_record: Option, + payer: Option, + system_program: Option, + governance_authority: Option, + realm_config_account: Option, + voter_weight_record: Option, + config: Option, + __remaining_accounts: Vec, +} + +impl CreateGovernanceBuilder { + pub fn new() -> Self { + Self::default() + } + /// Realm account the created governance belongs to + #[inline(always)] + pub fn realm_account(&mut self, realm_account: solana_pubkey::Pubkey) -> &mut Self { + self.realm_account = Some(realm_account); + self + } + /// seeds=['account-governance', realm, governed_account] + #[inline(always)] + pub fn governance_account(&mut self, governance_account: solana_pubkey::Pubkey) -> &mut Self { + self.governance_account = Some(governance_account); + self + } + /// Account governed by this Governance (governing_account). + /// Note: the account doesn't have to exist and can be used only as a unique identified for the Governance account + #[inline(always)] + pub fn governed_account(&mut self, governed_account: solana_pubkey::Pubkey) -> &mut Self { + self.governed_account = Some(governed_account); + self + } + /// Used only if not signed by RealmAuthority + #[inline(always)] + pub fn governing_token_owner_record( + &mut self, + governing_token_owner_record: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governing_token_owner_record = Some(governing_token_owner_record); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: solana_pubkey::Pubkey) -> &mut Self { + self.payer = Some(payer); + self + } + /// `[optional account, default to '11111111111111111111111111111111']` + #[inline(always)] + pub fn system_program(&mut self, system_program: solana_pubkey::Pubkey) -> &mut Self { + self.system_program = Some(system_program); + self + } + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governance_authority = Some(governance_authority); + self + } + /// seeds=['realm-config', realm] + #[inline(always)] + pub fn realm_config_account( + &mut self, + realm_config_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.realm_config_account = Some(realm_config_account); + self + } + /// `[optional account]` + /// Optional Voter Weight Record + #[inline(always)] + pub fn voter_weight_record( + &mut self, + voter_weight_record: Option, + ) -> &mut Self { + self.voter_weight_record = voter_weight_record; + self + } + #[inline(always)] + pub fn config(&mut self, config: GovernanceConfig) -> &mut Self { + self.config = Some(config); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = CreateGovernance { + realm_account: self.realm_account.expect("realm_account is not set"), + governance_account: self + .governance_account + .expect("governance_account is not set"), + governed_account: self.governed_account.expect("governed_account is not set"), + governing_token_owner_record: self + .governing_token_owner_record + .expect("governing_token_owner_record is not set"), + payer: self.payer.expect("payer is not set"), + system_program: self + .system_program + .unwrap_or(solana_pubkey::pubkey!("11111111111111111111111111111111")), + governance_authority: self + .governance_authority + .expect("governance_authority is not set"), + realm_config_account: self + .realm_config_account + .expect("realm_config_account is not set"), + voter_weight_record: self.voter_weight_record, + }; + let args = CreateGovernanceInstructionArgs { + config: self.config.clone().expect("config is not set"), + }; + + accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) + } +} + +/// `create_governance` CPI accounts. +pub struct CreateGovernanceCpiAccounts<'a, 'b> { + /// Realm account the created governance belongs to + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['account-governance', realm, governed_account] + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + /// Account governed by this Governance (governing_account). + /// Note: the account doesn't have to exist and can be used only as a unique identified for the Governance account + pub governed_account: &'b solana_account_info::AccountInfo<'a>, + /// Used only if not signed by RealmAuthority + pub governing_token_owner_record: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, + + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['realm-config', realm] + pub realm_config_account: &'b solana_account_info::AccountInfo<'a>, + /// Optional Voter Weight Record + pub voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, +} + +/// `create_governance` CPI instruction. +pub struct CreateGovernanceCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + /// Realm account the created governance belongs to + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['account-governance', realm, governed_account] + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + /// Account governed by this Governance (governing_account). + /// Note: the account doesn't have to exist and can be used only as a unique identified for the Governance account + pub governed_account: &'b solana_account_info::AccountInfo<'a>, + /// Used only if not signed by RealmAuthority + pub governing_token_owner_record: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, + + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['realm-config', realm] + pub realm_config_account: &'b solana_account_info::AccountInfo<'a>, + /// Optional Voter Weight Record + pub voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + /// The arguments for the instruction. + pub __args: CreateGovernanceInstructionArgs, +} + +impl<'a, 'b> CreateGovernanceCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: CreateGovernanceCpiAccounts<'a, 'b>, + args: CreateGovernanceInstructionArgs, + ) -> Self { + Self { + __program: program, + realm_account: accounts.realm_account, + governance_account: accounts.governance_account, + governed_account: accounts.governed_account, + governing_token_owner_record: accounts.governing_token_owner_record, + payer: accounts.payer, + system_program: accounts.system_program, + governance_authority: accounts.governance_authority, + realm_config_account: accounts.realm_config_account, + voter_weight_record: accounts.voter_weight_record, + __args: args, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(9 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.governance_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governed_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governing_token_owner_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.payer.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.system_program.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governance_authority.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_config_account.key, + false, + )); + if let Some(voter_weight_record) = self.voter_weight_record { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *voter_weight_record.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let mut data = CreateGovernanceInstructionData::new().try_to_vec().unwrap(); + let mut args = self.__args.try_to_vec().unwrap(); + data.append(&mut args); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(10 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.realm_account.clone()); + account_infos.push(self.governance_account.clone()); + account_infos.push(self.governed_account.clone()); + account_infos.push(self.governing_token_owner_record.clone()); + account_infos.push(self.payer.clone()); + account_infos.push(self.system_program.clone()); + account_infos.push(self.governance_authority.clone()); + account_infos.push(self.realm_config_account.clone()); + if let Some(voter_weight_record) = self.voter_weight_record { + account_infos.push(voter_weight_record.clone()); + } + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `CreateGovernance` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[writable]` governance_account +/// 2. `[]` governed_account +/// 3. `[]` governing_token_owner_record +/// 4. `[signer]` payer +/// 5. `[]` system_program +/// 6. `[signer]` governance_authority +/// 7. `[]` realm_config_account +/// 8. `[optional]` voter_weight_record +#[derive(Clone, Debug)] +pub struct CreateGovernanceCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> CreateGovernanceCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(CreateGovernanceCpiBuilderInstruction { + __program: program, + realm_account: None, + governance_account: None, + governed_account: None, + governing_token_owner_record: None, + payer: None, + system_program: None, + governance_authority: None, + realm_config_account: None, + voter_weight_record: None, + config: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + /// Realm account the created governance belongs to + #[inline(always)] + pub fn realm_account( + &mut self, + realm_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_account = Some(realm_account); + self + } + /// seeds=['account-governance', realm, governed_account] + #[inline(always)] + pub fn governance_account( + &mut self, + governance_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_account = Some(governance_account); + self + } + /// Account governed by this Governance (governing_account). + /// Note: the account doesn't have to exist and can be used only as a unique identified for the Governance account + #[inline(always)] + pub fn governed_account( + &mut self, + governed_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governed_account = Some(governed_account); + self + } + /// Used only if not signed by RealmAuthority + #[inline(always)] + pub fn governing_token_owner_record( + &mut self, + governing_token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governing_token_owner_record = Some(governing_token_owner_record); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: &'b solana_account_info::AccountInfo<'a>) -> &mut Self { + self.instruction.payer = Some(payer); + self + } + #[inline(always)] + pub fn system_program( + &mut self, + system_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.system_program = Some(system_program); + self + } + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_authority = Some(governance_authority); + self + } + /// seeds=['realm-config', realm] + #[inline(always)] + pub fn realm_config_account( + &mut self, + realm_config_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_config_account = Some(realm_config_account); + self + } + /// `[optional account]` + /// Optional Voter Weight Record + #[inline(always)] + pub fn voter_weight_record( + &mut self, + voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.voter_weight_record = voter_weight_record; + self + } + #[inline(always)] + pub fn config(&mut self, config: GovernanceConfig) -> &mut Self { + self.instruction.config = Some(config); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let args = CreateGovernanceInstructionArgs { + config: self.instruction.config.clone().expect("config is not set"), + }; + let instruction = CreateGovernanceCpi { + __program: self.instruction.__program, + + realm_account: self + .instruction + .realm_account + .expect("realm_account is not set"), + + governance_account: self + .instruction + .governance_account + .expect("governance_account is not set"), + + governed_account: self + .instruction + .governed_account + .expect("governed_account is not set"), + + governing_token_owner_record: self + .instruction + .governing_token_owner_record + .expect("governing_token_owner_record is not set"), + + payer: self.instruction.payer.expect("payer is not set"), + + system_program: self + .instruction + .system_program + .expect("system_program is not set"), + + governance_authority: self + .instruction + .governance_authority + .expect("governance_authority is not set"), + + realm_config_account: self + .instruction + .realm_config_account + .expect("realm_config_account is not set"), + + voter_weight_record: self.instruction.voter_weight_record, + __args: args, + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct CreateGovernanceCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + realm_account: Option<&'b solana_account_info::AccountInfo<'a>>, + governance_account: Option<&'b solana_account_info::AccountInfo<'a>>, + governed_account: Option<&'b solana_account_info::AccountInfo<'a>>, + governing_token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + payer: Option<&'b solana_account_info::AccountInfo<'a>>, + system_program: Option<&'b solana_account_info::AccountInfo<'a>>, + governance_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + realm_config_account: Option<&'b solana_account_info::AccountInfo<'a>>, + voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + config: Option, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/create_mint_governance.rs b/e2e/governance/src/generated/instructions/create_mint_governance.rs new file mode 100644 index 0000000..221ea76 --- /dev/null +++ b/e2e/governance/src/generated/instructions/create_mint_governance.rs @@ -0,0 +1,794 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceConfig; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const CREATE_MINT_GOVERNANCE_DISCRIMINATOR: u8 = 17; + +/// Accounts. +#[derive(Debug)] +pub struct CreateMintGovernance { + /// Realm account the created Governance belongs to + pub realm_account: solana_pubkey::Pubkey, + /// Mint Governance account. seeds=['mint-governance', realm, governed_mint] + pub mint_governance_account: solana_pubkey::Pubkey, + /// Mint governed by this Governance account + pub governed_mint: solana_pubkey::Pubkey, + /// Current Mint authority (MintTokens and optionally FreezeAccount) + pub mint_authority: solana_pubkey::Pubkey, + /// Governing TokenOwnerRecord account (Used only if not signed by RealmAuthority) + pub governing_token_owner_record: solana_pubkey::Pubkey, + + pub payer: solana_pubkey::Pubkey, + + pub token_program: solana_pubkey::Pubkey, + + pub system_program: solana_pubkey::Pubkey, + + pub governance_authority: solana_pubkey::Pubkey, + /// RealmConfig account. seeds=['realm-config', realm] + pub realm_config: solana_pubkey::Pubkey, + /// Optional Voter Weight Record + pub voter_weight_record: Option, +} + +impl CreateMintGovernance { + pub fn instruction( + &self, + args: CreateMintGovernanceInstructionArgs, + ) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(args, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + args: CreateMintGovernanceInstructionArgs, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(11 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.mint_governance_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.governed_mint, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.mint_authority, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governing_token_owner_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.payer, true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.token_program, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.system_program, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governance_authority, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_config, + false, + )); + if let Some(voter_weight_record) = self.voter_weight_record { + accounts.push(solana_instruction::AccountMeta::new_readonly( + voter_weight_record, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + accounts.extend_from_slice(remaining_accounts); + let mut data = CreateMintGovernanceInstructionData::new() + .try_to_vec() + .unwrap(); + let mut args = args.try_to_vec().unwrap(); + data.append(&mut args); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CreateMintGovernanceInstructionData { + discriminator: u8, +} + +impl CreateMintGovernanceInstructionData { + pub fn new() -> Self { + Self { discriminator: 17 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for CreateMintGovernanceInstructionData { + fn default() -> Self { + Self::new() + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CreateMintGovernanceInstructionArgs { + pub config: GovernanceConfig, + pub transfer_mint_authorities: bool, +} + +impl CreateMintGovernanceInstructionArgs { + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +/// Instruction builder for `CreateMintGovernance`. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[writable]` mint_governance_account +/// 2. `[writable]` governed_mint +/// 3. `[signer]` mint_authority +/// 4. `[]` governing_token_owner_record +/// 5. `[signer]` payer +/// 6. `[optional]` token_program (default to `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`) +/// 7. `[optional]` system_program (default to `11111111111111111111111111111111`) +/// 8. `[signer]` governance_authority +/// 9. `[]` realm_config +/// 10. `[optional]` voter_weight_record +#[derive(Clone, Debug, Default)] +pub struct CreateMintGovernanceBuilder { + realm_account: Option, + mint_governance_account: Option, + governed_mint: Option, + mint_authority: Option, + governing_token_owner_record: Option, + payer: Option, + token_program: Option, + system_program: Option, + governance_authority: Option, + realm_config: Option, + voter_weight_record: Option, + config: Option, + transfer_mint_authorities: Option, + __remaining_accounts: Vec, +} + +impl CreateMintGovernanceBuilder { + pub fn new() -> Self { + Self::default() + } + /// Realm account the created Governance belongs to + #[inline(always)] + pub fn realm_account(&mut self, realm_account: solana_pubkey::Pubkey) -> &mut Self { + self.realm_account = Some(realm_account); + self + } + /// Mint Governance account. seeds=['mint-governance', realm, governed_mint] + #[inline(always)] + pub fn mint_governance_account( + &mut self, + mint_governance_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.mint_governance_account = Some(mint_governance_account); + self + } + /// Mint governed by this Governance account + #[inline(always)] + pub fn governed_mint(&mut self, governed_mint: solana_pubkey::Pubkey) -> &mut Self { + self.governed_mint = Some(governed_mint); + self + } + /// Current Mint authority (MintTokens and optionally FreezeAccount) + #[inline(always)] + pub fn mint_authority(&mut self, mint_authority: solana_pubkey::Pubkey) -> &mut Self { + self.mint_authority = Some(mint_authority); + self + } + /// Governing TokenOwnerRecord account (Used only if not signed by RealmAuthority) + #[inline(always)] + pub fn governing_token_owner_record( + &mut self, + governing_token_owner_record: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governing_token_owner_record = Some(governing_token_owner_record); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: solana_pubkey::Pubkey) -> &mut Self { + self.payer = Some(payer); + self + } + /// `[optional account, default to 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA']` + #[inline(always)] + pub fn token_program(&mut self, token_program: solana_pubkey::Pubkey) -> &mut Self { + self.token_program = Some(token_program); + self + } + /// `[optional account, default to '11111111111111111111111111111111']` + #[inline(always)] + pub fn system_program(&mut self, system_program: solana_pubkey::Pubkey) -> &mut Self { + self.system_program = Some(system_program); + self + } + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governance_authority = Some(governance_authority); + self + } + /// RealmConfig account. seeds=['realm-config', realm] + #[inline(always)] + pub fn realm_config(&mut self, realm_config: solana_pubkey::Pubkey) -> &mut Self { + self.realm_config = Some(realm_config); + self + } + /// `[optional account]` + /// Optional Voter Weight Record + #[inline(always)] + pub fn voter_weight_record( + &mut self, + voter_weight_record: Option, + ) -> &mut Self { + self.voter_weight_record = voter_weight_record; + self + } + #[inline(always)] + pub fn config(&mut self, config: GovernanceConfig) -> &mut Self { + self.config = Some(config); + self + } + #[inline(always)] + pub fn transfer_mint_authorities(&mut self, transfer_mint_authorities: bool) -> &mut Self { + self.transfer_mint_authorities = Some(transfer_mint_authorities); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = CreateMintGovernance { + realm_account: self.realm_account.expect("realm_account is not set"), + mint_governance_account: self + .mint_governance_account + .expect("mint_governance_account is not set"), + governed_mint: self.governed_mint.expect("governed_mint is not set"), + mint_authority: self.mint_authority.expect("mint_authority is not set"), + governing_token_owner_record: self + .governing_token_owner_record + .expect("governing_token_owner_record is not set"), + payer: self.payer.expect("payer is not set"), + token_program: self.token_program.unwrap_or(solana_pubkey::pubkey!( + "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + )), + system_program: self + .system_program + .unwrap_or(solana_pubkey::pubkey!("11111111111111111111111111111111")), + governance_authority: self + .governance_authority + .expect("governance_authority is not set"), + realm_config: self.realm_config.expect("realm_config is not set"), + voter_weight_record: self.voter_weight_record, + }; + let args = CreateMintGovernanceInstructionArgs { + config: self.config.clone().expect("config is not set"), + transfer_mint_authorities: self + .transfer_mint_authorities + .clone() + .expect("transfer_mint_authorities is not set"), + }; + + accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) + } +} + +/// `create_mint_governance` CPI accounts. +pub struct CreateMintGovernanceCpiAccounts<'a, 'b> { + /// Realm account the created Governance belongs to + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + /// Mint Governance account. seeds=['mint-governance', realm, governed_mint] + pub mint_governance_account: &'b solana_account_info::AccountInfo<'a>, + /// Mint governed by this Governance account + pub governed_mint: &'b solana_account_info::AccountInfo<'a>, + /// Current Mint authority (MintTokens and optionally FreezeAccount) + pub mint_authority: &'b solana_account_info::AccountInfo<'a>, + /// Governing TokenOwnerRecord account (Used only if not signed by RealmAuthority) + pub governing_token_owner_record: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub token_program: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, + + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, + /// RealmConfig account. seeds=['realm-config', realm] + pub realm_config: &'b solana_account_info::AccountInfo<'a>, + /// Optional Voter Weight Record + pub voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, +} + +/// `create_mint_governance` CPI instruction. +pub struct CreateMintGovernanceCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + /// Realm account the created Governance belongs to + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + /// Mint Governance account. seeds=['mint-governance', realm, governed_mint] + pub mint_governance_account: &'b solana_account_info::AccountInfo<'a>, + /// Mint governed by this Governance account + pub governed_mint: &'b solana_account_info::AccountInfo<'a>, + /// Current Mint authority (MintTokens and optionally FreezeAccount) + pub mint_authority: &'b solana_account_info::AccountInfo<'a>, + /// Governing TokenOwnerRecord account (Used only if not signed by RealmAuthority) + pub governing_token_owner_record: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub token_program: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, + + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, + /// RealmConfig account. seeds=['realm-config', realm] + pub realm_config: &'b solana_account_info::AccountInfo<'a>, + /// Optional Voter Weight Record + pub voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + /// The arguments for the instruction. + pub __args: CreateMintGovernanceInstructionArgs, +} + +impl<'a, 'b> CreateMintGovernanceCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: CreateMintGovernanceCpiAccounts<'a, 'b>, + args: CreateMintGovernanceInstructionArgs, + ) -> Self { + Self { + __program: program, + realm_account: accounts.realm_account, + mint_governance_account: accounts.mint_governance_account, + governed_mint: accounts.governed_mint, + mint_authority: accounts.mint_authority, + governing_token_owner_record: accounts.governing_token_owner_record, + payer: accounts.payer, + token_program: accounts.token_program, + system_program: accounts.system_program, + governance_authority: accounts.governance_authority, + realm_config: accounts.realm_config, + voter_weight_record: accounts.voter_weight_record, + __args: args, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(11 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.mint_governance_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.governed_mint.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.mint_authority.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governing_token_owner_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.payer.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.token_program.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.system_program.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governance_authority.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_config.key, + false, + )); + if let Some(voter_weight_record) = self.voter_weight_record { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *voter_weight_record.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let mut data = CreateMintGovernanceInstructionData::new() + .try_to_vec() + .unwrap(); + let mut args = self.__args.try_to_vec().unwrap(); + data.append(&mut args); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(12 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.realm_account.clone()); + account_infos.push(self.mint_governance_account.clone()); + account_infos.push(self.governed_mint.clone()); + account_infos.push(self.mint_authority.clone()); + account_infos.push(self.governing_token_owner_record.clone()); + account_infos.push(self.payer.clone()); + account_infos.push(self.token_program.clone()); + account_infos.push(self.system_program.clone()); + account_infos.push(self.governance_authority.clone()); + account_infos.push(self.realm_config.clone()); + if let Some(voter_weight_record) = self.voter_weight_record { + account_infos.push(voter_weight_record.clone()); + } + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `CreateMintGovernance` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[writable]` mint_governance_account +/// 2. `[writable]` governed_mint +/// 3. `[signer]` mint_authority +/// 4. `[]` governing_token_owner_record +/// 5. `[signer]` payer +/// 6. `[]` token_program +/// 7. `[]` system_program +/// 8. `[signer]` governance_authority +/// 9. `[]` realm_config +/// 10. `[optional]` voter_weight_record +#[derive(Clone, Debug)] +pub struct CreateMintGovernanceCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> CreateMintGovernanceCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(CreateMintGovernanceCpiBuilderInstruction { + __program: program, + realm_account: None, + mint_governance_account: None, + governed_mint: None, + mint_authority: None, + governing_token_owner_record: None, + payer: None, + token_program: None, + system_program: None, + governance_authority: None, + realm_config: None, + voter_weight_record: None, + config: None, + transfer_mint_authorities: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + /// Realm account the created Governance belongs to + #[inline(always)] + pub fn realm_account( + &mut self, + realm_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_account = Some(realm_account); + self + } + /// Mint Governance account. seeds=['mint-governance', realm, governed_mint] + #[inline(always)] + pub fn mint_governance_account( + &mut self, + mint_governance_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.mint_governance_account = Some(mint_governance_account); + self + } + /// Mint governed by this Governance account + #[inline(always)] + pub fn governed_mint( + &mut self, + governed_mint: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governed_mint = Some(governed_mint); + self + } + /// Current Mint authority (MintTokens and optionally FreezeAccount) + #[inline(always)] + pub fn mint_authority( + &mut self, + mint_authority: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.mint_authority = Some(mint_authority); + self + } + /// Governing TokenOwnerRecord account (Used only if not signed by RealmAuthority) + #[inline(always)] + pub fn governing_token_owner_record( + &mut self, + governing_token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governing_token_owner_record = Some(governing_token_owner_record); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: &'b solana_account_info::AccountInfo<'a>) -> &mut Self { + self.instruction.payer = Some(payer); + self + } + #[inline(always)] + pub fn token_program( + &mut self, + token_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_program = Some(token_program); + self + } + #[inline(always)] + pub fn system_program( + &mut self, + system_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.system_program = Some(system_program); + self + } + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_authority = Some(governance_authority); + self + } + /// RealmConfig account. seeds=['realm-config', realm] + #[inline(always)] + pub fn realm_config( + &mut self, + realm_config: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_config = Some(realm_config); + self + } + /// `[optional account]` + /// Optional Voter Weight Record + #[inline(always)] + pub fn voter_weight_record( + &mut self, + voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.voter_weight_record = voter_weight_record; + self + } + #[inline(always)] + pub fn config(&mut self, config: GovernanceConfig) -> &mut Self { + self.instruction.config = Some(config); + self + } + #[inline(always)] + pub fn transfer_mint_authorities(&mut self, transfer_mint_authorities: bool) -> &mut Self { + self.instruction.transfer_mint_authorities = Some(transfer_mint_authorities); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let args = CreateMintGovernanceInstructionArgs { + config: self.instruction.config.clone().expect("config is not set"), + transfer_mint_authorities: self + .instruction + .transfer_mint_authorities + .clone() + .expect("transfer_mint_authorities is not set"), + }; + let instruction = CreateMintGovernanceCpi { + __program: self.instruction.__program, + + realm_account: self + .instruction + .realm_account + .expect("realm_account is not set"), + + mint_governance_account: self + .instruction + .mint_governance_account + .expect("mint_governance_account is not set"), + + governed_mint: self + .instruction + .governed_mint + .expect("governed_mint is not set"), + + mint_authority: self + .instruction + .mint_authority + .expect("mint_authority is not set"), + + governing_token_owner_record: self + .instruction + .governing_token_owner_record + .expect("governing_token_owner_record is not set"), + + payer: self.instruction.payer.expect("payer is not set"), + + token_program: self + .instruction + .token_program + .expect("token_program is not set"), + + system_program: self + .instruction + .system_program + .expect("system_program is not set"), + + governance_authority: self + .instruction + .governance_authority + .expect("governance_authority is not set"), + + realm_config: self + .instruction + .realm_config + .expect("realm_config is not set"), + + voter_weight_record: self.instruction.voter_weight_record, + __args: args, + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct CreateMintGovernanceCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + realm_account: Option<&'b solana_account_info::AccountInfo<'a>>, + mint_governance_account: Option<&'b solana_account_info::AccountInfo<'a>>, + governed_mint: Option<&'b solana_account_info::AccountInfo<'a>>, + mint_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + governing_token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + payer: Option<&'b solana_account_info::AccountInfo<'a>>, + token_program: Option<&'b solana_account_info::AccountInfo<'a>>, + system_program: Option<&'b solana_account_info::AccountInfo<'a>>, + governance_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + realm_config: Option<&'b solana_account_info::AccountInfo<'a>>, + voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + config: Option, + transfer_mint_authorities: Option, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/create_native_treasury.rs b/e2e/governance/src/generated/instructions/create_native_treasury.rs new file mode 100644 index 0000000..35036e8 --- /dev/null +++ b/e2e/governance/src/generated/instructions/create_native_treasury.rs @@ -0,0 +1,407 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const CREATE_NATIVE_TREASURY_DISCRIMINATOR: u8 = 25; + +/// Accounts. +#[derive(Debug)] +pub struct CreateNativeTreasury { + /// Governance account the treasury account is for + pub governance_account: solana_pubkey::Pubkey, + /// seeds=['native-treasury', governance] + pub native_treasury_account: solana_pubkey::Pubkey, + + pub payer: solana_pubkey::Pubkey, + + pub system_program: solana_pubkey::Pubkey, +} + +impl CreateNativeTreasury { + pub fn instruction(&self) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(&[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(4 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governance_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.native_treasury_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.payer, true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.system_program, + false, + )); + accounts.extend_from_slice(remaining_accounts); + let data = CreateNativeTreasuryInstructionData::new() + .try_to_vec() + .unwrap(); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CreateNativeTreasuryInstructionData { + discriminator: u8, +} + +impl CreateNativeTreasuryInstructionData { + pub fn new() -> Self { + Self { discriminator: 25 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for CreateNativeTreasuryInstructionData { + fn default() -> Self { + Self::new() + } +} + +/// Instruction builder for `CreateNativeTreasury`. +/// +/// ### Accounts: +/// +/// 0. `[]` governance_account +/// 1. `[writable]` native_treasury_account +/// 2. `[signer]` payer +/// 3. `[optional]` system_program (default to `11111111111111111111111111111111`) +#[derive(Clone, Debug, Default)] +pub struct CreateNativeTreasuryBuilder { + governance_account: Option, + native_treasury_account: Option, + payer: Option, + system_program: Option, + __remaining_accounts: Vec, +} + +impl CreateNativeTreasuryBuilder { + pub fn new() -> Self { + Self::default() + } + /// Governance account the treasury account is for + #[inline(always)] + pub fn governance_account(&mut self, governance_account: solana_pubkey::Pubkey) -> &mut Self { + self.governance_account = Some(governance_account); + self + } + /// seeds=['native-treasury', governance] + #[inline(always)] + pub fn native_treasury_account( + &mut self, + native_treasury_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.native_treasury_account = Some(native_treasury_account); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: solana_pubkey::Pubkey) -> &mut Self { + self.payer = Some(payer); + self + } + /// `[optional account, default to '11111111111111111111111111111111']` + #[inline(always)] + pub fn system_program(&mut self, system_program: solana_pubkey::Pubkey) -> &mut Self { + self.system_program = Some(system_program); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = CreateNativeTreasury { + governance_account: self + .governance_account + .expect("governance_account is not set"), + native_treasury_account: self + .native_treasury_account + .expect("native_treasury_account is not set"), + payer: self.payer.expect("payer is not set"), + system_program: self + .system_program + .unwrap_or(solana_pubkey::pubkey!("11111111111111111111111111111111")), + }; + + accounts.instruction_with_remaining_accounts(&self.__remaining_accounts) + } +} + +/// `create_native_treasury` CPI accounts. +pub struct CreateNativeTreasuryCpiAccounts<'a, 'b> { + /// Governance account the treasury account is for + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['native-treasury', governance] + pub native_treasury_account: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, +} + +/// `create_native_treasury` CPI instruction. +pub struct CreateNativeTreasuryCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + /// Governance account the treasury account is for + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['native-treasury', governance] + pub native_treasury_account: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, +} + +impl<'a, 'b> CreateNativeTreasuryCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: CreateNativeTreasuryCpiAccounts<'a, 'b>, + ) -> Self { + Self { + __program: program, + governance_account: accounts.governance_account, + native_treasury_account: accounts.native_treasury_account, + payer: accounts.payer, + system_program: accounts.system_program, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(4 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governance_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.native_treasury_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.payer.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.system_program.key, + false, + )); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let data = CreateNativeTreasuryInstructionData::new() + .try_to_vec() + .unwrap(); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(5 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.governance_account.clone()); + account_infos.push(self.native_treasury_account.clone()); + account_infos.push(self.payer.clone()); + account_infos.push(self.system_program.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `CreateNativeTreasury` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[]` governance_account +/// 1. `[writable]` native_treasury_account +/// 2. `[signer]` payer +/// 3. `[]` system_program +#[derive(Clone, Debug)] +pub struct CreateNativeTreasuryCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> CreateNativeTreasuryCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(CreateNativeTreasuryCpiBuilderInstruction { + __program: program, + governance_account: None, + native_treasury_account: None, + payer: None, + system_program: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + /// Governance account the treasury account is for + #[inline(always)] + pub fn governance_account( + &mut self, + governance_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_account = Some(governance_account); + self + } + /// seeds=['native-treasury', governance] + #[inline(always)] + pub fn native_treasury_account( + &mut self, + native_treasury_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.native_treasury_account = Some(native_treasury_account); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: &'b solana_account_info::AccountInfo<'a>) -> &mut Self { + self.instruction.payer = Some(payer); + self + } + #[inline(always)] + pub fn system_program( + &mut self, + system_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.system_program = Some(system_program); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let instruction = CreateNativeTreasuryCpi { + __program: self.instruction.__program, + + governance_account: self + .instruction + .governance_account + .expect("governance_account is not set"), + + native_treasury_account: self + .instruction + .native_treasury_account + .expect("native_treasury_account is not set"), + + payer: self.instruction.payer.expect("payer is not set"), + + system_program: self + .instruction + .system_program + .expect("system_program is not set"), + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct CreateNativeTreasuryCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + governance_account: Option<&'b solana_account_info::AccountInfo<'a>>, + native_treasury_account: Option<&'b solana_account_info::AccountInfo<'a>>, + payer: Option<&'b solana_account_info::AccountInfo<'a>>, + system_program: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/create_program_governance.rs b/e2e/governance/src/generated/instructions/create_program_governance.rs new file mode 100644 index 0000000..545e74e --- /dev/null +++ b/e2e/governance/src/generated/instructions/create_program_governance.rs @@ -0,0 +1,845 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceConfig; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const CREATE_PROGRAM_GOVERNANCE_DISCRIMINATOR: u8 = 5; + +/// Accounts. +#[derive(Debug)] +pub struct CreateProgramGovernance { + /// Realm account the created Governance belongs to + pub realm_account: solana_pubkey::Pubkey, + /// Program Governance account. seeds: ['program-governance', realm, governed_program] + pub program_governance_account: solana_pubkey::Pubkey, + /// Program governed by this Governance account + pub governed_program: solana_pubkey::Pubkey, + /// Program Data account of the Program governed by this Governance account + pub program_data: solana_pubkey::Pubkey, + /// Current Upgrade Authority account of the Program governed by this Governance account + pub current_upgrade_authority: solana_pubkey::Pubkey, + /// Governing TokenOwnerRecord account (Used only if not signed by RealmAuthority) + pub governing_token_owner_record: solana_pubkey::Pubkey, + + pub payer: solana_pubkey::Pubkey, + /// bpf_upgradeable_loader_program program + pub bpf_upgradeable_loader_program: solana_pubkey::Pubkey, + + pub system_program: solana_pubkey::Pubkey, + + pub governance_authority: solana_pubkey::Pubkey, + /// RealmConfig account. seeds=['realm-config', realm] + pub realm_config: solana_pubkey::Pubkey, + /// Optional Voter Weight Record + pub voter_weight_record: Option, +} + +impl CreateProgramGovernance { + pub fn instruction( + &self, + args: CreateProgramGovernanceInstructionArgs, + ) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(args, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + args: CreateProgramGovernanceInstructionArgs, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(12 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.program_governance_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governed_program, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.program_data, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.current_upgrade_authority, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governing_token_owner_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.payer, true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.bpf_upgradeable_loader_program, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.system_program, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governance_authority, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_config, + false, + )); + if let Some(voter_weight_record) = self.voter_weight_record { + accounts.push(solana_instruction::AccountMeta::new_readonly( + voter_weight_record, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + accounts.extend_from_slice(remaining_accounts); + let mut data = CreateProgramGovernanceInstructionData::new() + .try_to_vec() + .unwrap(); + let mut args = args.try_to_vec().unwrap(); + data.append(&mut args); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CreateProgramGovernanceInstructionData { + discriminator: u8, +} + +impl CreateProgramGovernanceInstructionData { + pub fn new() -> Self { + Self { discriminator: 5 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for CreateProgramGovernanceInstructionData { + fn default() -> Self { + Self::new() + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CreateProgramGovernanceInstructionArgs { + pub config: GovernanceConfig, + pub transfer_upgrade_authority: bool, +} + +impl CreateProgramGovernanceInstructionArgs { + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +/// Instruction builder for `CreateProgramGovernance`. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[writable]` program_governance_account +/// 2. `[]` governed_program +/// 3. `[writable]` program_data +/// 4. `[signer]` current_upgrade_authority +/// 5. `[]` governing_token_owner_record +/// 6. `[signer]` payer +/// 7. `[]` bpf_upgradeable_loader_program +/// 8. `[optional]` system_program (default to `11111111111111111111111111111111`) +/// 9. `[signer]` governance_authority +/// 10. `[]` realm_config +/// 11. `[optional]` voter_weight_record +#[derive(Clone, Debug, Default)] +pub struct CreateProgramGovernanceBuilder { + realm_account: Option, + program_governance_account: Option, + governed_program: Option, + program_data: Option, + current_upgrade_authority: Option, + governing_token_owner_record: Option, + payer: Option, + bpf_upgradeable_loader_program: Option, + system_program: Option, + governance_authority: Option, + realm_config: Option, + voter_weight_record: Option, + config: Option, + transfer_upgrade_authority: Option, + __remaining_accounts: Vec, +} + +impl CreateProgramGovernanceBuilder { + pub fn new() -> Self { + Self::default() + } + /// Realm account the created Governance belongs to + #[inline(always)] + pub fn realm_account(&mut self, realm_account: solana_pubkey::Pubkey) -> &mut Self { + self.realm_account = Some(realm_account); + self + } + /// Program Governance account. seeds: ['program-governance', realm, governed_program] + #[inline(always)] + pub fn program_governance_account( + &mut self, + program_governance_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.program_governance_account = Some(program_governance_account); + self + } + /// Program governed by this Governance account + #[inline(always)] + pub fn governed_program(&mut self, governed_program: solana_pubkey::Pubkey) -> &mut Self { + self.governed_program = Some(governed_program); + self + } + /// Program Data account of the Program governed by this Governance account + #[inline(always)] + pub fn program_data(&mut self, program_data: solana_pubkey::Pubkey) -> &mut Self { + self.program_data = Some(program_data); + self + } + /// Current Upgrade Authority account of the Program governed by this Governance account + #[inline(always)] + pub fn current_upgrade_authority( + &mut self, + current_upgrade_authority: solana_pubkey::Pubkey, + ) -> &mut Self { + self.current_upgrade_authority = Some(current_upgrade_authority); + self + } + /// Governing TokenOwnerRecord account (Used only if not signed by RealmAuthority) + #[inline(always)] + pub fn governing_token_owner_record( + &mut self, + governing_token_owner_record: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governing_token_owner_record = Some(governing_token_owner_record); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: solana_pubkey::Pubkey) -> &mut Self { + self.payer = Some(payer); + self + } + /// bpf_upgradeable_loader_program program + #[inline(always)] + pub fn bpf_upgradeable_loader_program( + &mut self, + bpf_upgradeable_loader_program: solana_pubkey::Pubkey, + ) -> &mut Self { + self.bpf_upgradeable_loader_program = Some(bpf_upgradeable_loader_program); + self + } + /// `[optional account, default to '11111111111111111111111111111111']` + #[inline(always)] + pub fn system_program(&mut self, system_program: solana_pubkey::Pubkey) -> &mut Self { + self.system_program = Some(system_program); + self + } + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governance_authority = Some(governance_authority); + self + } + /// RealmConfig account. seeds=['realm-config', realm] + #[inline(always)] + pub fn realm_config(&mut self, realm_config: solana_pubkey::Pubkey) -> &mut Self { + self.realm_config = Some(realm_config); + self + } + /// `[optional account]` + /// Optional Voter Weight Record + #[inline(always)] + pub fn voter_weight_record( + &mut self, + voter_weight_record: Option, + ) -> &mut Self { + self.voter_weight_record = voter_weight_record; + self + } + #[inline(always)] + pub fn config(&mut self, config: GovernanceConfig) -> &mut Self { + self.config = Some(config); + self + } + #[inline(always)] + pub fn transfer_upgrade_authority(&mut self, transfer_upgrade_authority: bool) -> &mut Self { + self.transfer_upgrade_authority = Some(transfer_upgrade_authority); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = CreateProgramGovernance { + realm_account: self.realm_account.expect("realm_account is not set"), + program_governance_account: self + .program_governance_account + .expect("program_governance_account is not set"), + governed_program: self.governed_program.expect("governed_program is not set"), + program_data: self.program_data.expect("program_data is not set"), + current_upgrade_authority: self + .current_upgrade_authority + .expect("current_upgrade_authority is not set"), + governing_token_owner_record: self + .governing_token_owner_record + .expect("governing_token_owner_record is not set"), + payer: self.payer.expect("payer is not set"), + bpf_upgradeable_loader_program: self + .bpf_upgradeable_loader_program + .expect("bpf_upgradeable_loader_program is not set"), + system_program: self + .system_program + .unwrap_or(solana_pubkey::pubkey!("11111111111111111111111111111111")), + governance_authority: self + .governance_authority + .expect("governance_authority is not set"), + realm_config: self.realm_config.expect("realm_config is not set"), + voter_weight_record: self.voter_weight_record, + }; + let args = CreateProgramGovernanceInstructionArgs { + config: self.config.clone().expect("config is not set"), + transfer_upgrade_authority: self + .transfer_upgrade_authority + .clone() + .expect("transfer_upgrade_authority is not set"), + }; + + accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) + } +} + +/// `create_program_governance` CPI accounts. +pub struct CreateProgramGovernanceCpiAccounts<'a, 'b> { + /// Realm account the created Governance belongs to + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + /// Program Governance account. seeds: ['program-governance', realm, governed_program] + pub program_governance_account: &'b solana_account_info::AccountInfo<'a>, + /// Program governed by this Governance account + pub governed_program: &'b solana_account_info::AccountInfo<'a>, + /// Program Data account of the Program governed by this Governance account + pub program_data: &'b solana_account_info::AccountInfo<'a>, + /// Current Upgrade Authority account of the Program governed by this Governance account + pub current_upgrade_authority: &'b solana_account_info::AccountInfo<'a>, + /// Governing TokenOwnerRecord account (Used only if not signed by RealmAuthority) + pub governing_token_owner_record: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + /// bpf_upgradeable_loader_program program + pub bpf_upgradeable_loader_program: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, + + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, + /// RealmConfig account. seeds=['realm-config', realm] + pub realm_config: &'b solana_account_info::AccountInfo<'a>, + /// Optional Voter Weight Record + pub voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, +} + +/// `create_program_governance` CPI instruction. +pub struct CreateProgramGovernanceCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + /// Realm account the created Governance belongs to + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + /// Program Governance account. seeds: ['program-governance', realm, governed_program] + pub program_governance_account: &'b solana_account_info::AccountInfo<'a>, + /// Program governed by this Governance account + pub governed_program: &'b solana_account_info::AccountInfo<'a>, + /// Program Data account of the Program governed by this Governance account + pub program_data: &'b solana_account_info::AccountInfo<'a>, + /// Current Upgrade Authority account of the Program governed by this Governance account + pub current_upgrade_authority: &'b solana_account_info::AccountInfo<'a>, + /// Governing TokenOwnerRecord account (Used only if not signed by RealmAuthority) + pub governing_token_owner_record: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + /// bpf_upgradeable_loader_program program + pub bpf_upgradeable_loader_program: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, + + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, + /// RealmConfig account. seeds=['realm-config', realm] + pub realm_config: &'b solana_account_info::AccountInfo<'a>, + /// Optional Voter Weight Record + pub voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + /// The arguments for the instruction. + pub __args: CreateProgramGovernanceInstructionArgs, +} + +impl<'a, 'b> CreateProgramGovernanceCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: CreateProgramGovernanceCpiAccounts<'a, 'b>, + args: CreateProgramGovernanceInstructionArgs, + ) -> Self { + Self { + __program: program, + realm_account: accounts.realm_account, + program_governance_account: accounts.program_governance_account, + governed_program: accounts.governed_program, + program_data: accounts.program_data, + current_upgrade_authority: accounts.current_upgrade_authority, + governing_token_owner_record: accounts.governing_token_owner_record, + payer: accounts.payer, + bpf_upgradeable_loader_program: accounts.bpf_upgradeable_loader_program, + system_program: accounts.system_program, + governance_authority: accounts.governance_authority, + realm_config: accounts.realm_config, + voter_weight_record: accounts.voter_weight_record, + __args: args, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(12 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.program_governance_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governed_program.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.program_data.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.current_upgrade_authority.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governing_token_owner_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.payer.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.bpf_upgradeable_loader_program.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.system_program.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governance_authority.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_config.key, + false, + )); + if let Some(voter_weight_record) = self.voter_weight_record { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *voter_weight_record.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let mut data = CreateProgramGovernanceInstructionData::new() + .try_to_vec() + .unwrap(); + let mut args = self.__args.try_to_vec().unwrap(); + data.append(&mut args); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(13 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.realm_account.clone()); + account_infos.push(self.program_governance_account.clone()); + account_infos.push(self.governed_program.clone()); + account_infos.push(self.program_data.clone()); + account_infos.push(self.current_upgrade_authority.clone()); + account_infos.push(self.governing_token_owner_record.clone()); + account_infos.push(self.payer.clone()); + account_infos.push(self.bpf_upgradeable_loader_program.clone()); + account_infos.push(self.system_program.clone()); + account_infos.push(self.governance_authority.clone()); + account_infos.push(self.realm_config.clone()); + if let Some(voter_weight_record) = self.voter_weight_record { + account_infos.push(voter_weight_record.clone()); + } + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `CreateProgramGovernance` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[writable]` program_governance_account +/// 2. `[]` governed_program +/// 3. `[writable]` program_data +/// 4. `[signer]` current_upgrade_authority +/// 5. `[]` governing_token_owner_record +/// 6. `[signer]` payer +/// 7. `[]` bpf_upgradeable_loader_program +/// 8. `[]` system_program +/// 9. `[signer]` governance_authority +/// 10. `[]` realm_config +/// 11. `[optional]` voter_weight_record +#[derive(Clone, Debug)] +pub struct CreateProgramGovernanceCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> CreateProgramGovernanceCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(CreateProgramGovernanceCpiBuilderInstruction { + __program: program, + realm_account: None, + program_governance_account: None, + governed_program: None, + program_data: None, + current_upgrade_authority: None, + governing_token_owner_record: None, + payer: None, + bpf_upgradeable_loader_program: None, + system_program: None, + governance_authority: None, + realm_config: None, + voter_weight_record: None, + config: None, + transfer_upgrade_authority: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + /// Realm account the created Governance belongs to + #[inline(always)] + pub fn realm_account( + &mut self, + realm_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_account = Some(realm_account); + self + } + /// Program Governance account. seeds: ['program-governance', realm, governed_program] + #[inline(always)] + pub fn program_governance_account( + &mut self, + program_governance_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.program_governance_account = Some(program_governance_account); + self + } + /// Program governed by this Governance account + #[inline(always)] + pub fn governed_program( + &mut self, + governed_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governed_program = Some(governed_program); + self + } + /// Program Data account of the Program governed by this Governance account + #[inline(always)] + pub fn program_data( + &mut self, + program_data: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.program_data = Some(program_data); + self + } + /// Current Upgrade Authority account of the Program governed by this Governance account + #[inline(always)] + pub fn current_upgrade_authority( + &mut self, + current_upgrade_authority: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.current_upgrade_authority = Some(current_upgrade_authority); + self + } + /// Governing TokenOwnerRecord account (Used only if not signed by RealmAuthority) + #[inline(always)] + pub fn governing_token_owner_record( + &mut self, + governing_token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governing_token_owner_record = Some(governing_token_owner_record); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: &'b solana_account_info::AccountInfo<'a>) -> &mut Self { + self.instruction.payer = Some(payer); + self + } + /// bpf_upgradeable_loader_program program + #[inline(always)] + pub fn bpf_upgradeable_loader_program( + &mut self, + bpf_upgradeable_loader_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.bpf_upgradeable_loader_program = Some(bpf_upgradeable_loader_program); + self + } + #[inline(always)] + pub fn system_program( + &mut self, + system_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.system_program = Some(system_program); + self + } + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_authority = Some(governance_authority); + self + } + /// RealmConfig account. seeds=['realm-config', realm] + #[inline(always)] + pub fn realm_config( + &mut self, + realm_config: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_config = Some(realm_config); + self + } + /// `[optional account]` + /// Optional Voter Weight Record + #[inline(always)] + pub fn voter_weight_record( + &mut self, + voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.voter_weight_record = voter_weight_record; + self + } + #[inline(always)] + pub fn config(&mut self, config: GovernanceConfig) -> &mut Self { + self.instruction.config = Some(config); + self + } + #[inline(always)] + pub fn transfer_upgrade_authority(&mut self, transfer_upgrade_authority: bool) -> &mut Self { + self.instruction.transfer_upgrade_authority = Some(transfer_upgrade_authority); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let args = CreateProgramGovernanceInstructionArgs { + config: self.instruction.config.clone().expect("config is not set"), + transfer_upgrade_authority: self + .instruction + .transfer_upgrade_authority + .clone() + .expect("transfer_upgrade_authority is not set"), + }; + let instruction = CreateProgramGovernanceCpi { + __program: self.instruction.__program, + + realm_account: self + .instruction + .realm_account + .expect("realm_account is not set"), + + program_governance_account: self + .instruction + .program_governance_account + .expect("program_governance_account is not set"), + + governed_program: self + .instruction + .governed_program + .expect("governed_program is not set"), + + program_data: self + .instruction + .program_data + .expect("program_data is not set"), + + current_upgrade_authority: self + .instruction + .current_upgrade_authority + .expect("current_upgrade_authority is not set"), + + governing_token_owner_record: self + .instruction + .governing_token_owner_record + .expect("governing_token_owner_record is not set"), + + payer: self.instruction.payer.expect("payer is not set"), + + bpf_upgradeable_loader_program: self + .instruction + .bpf_upgradeable_loader_program + .expect("bpf_upgradeable_loader_program is not set"), + + system_program: self + .instruction + .system_program + .expect("system_program is not set"), + + governance_authority: self + .instruction + .governance_authority + .expect("governance_authority is not set"), + + realm_config: self + .instruction + .realm_config + .expect("realm_config is not set"), + + voter_weight_record: self.instruction.voter_weight_record, + __args: args, + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct CreateProgramGovernanceCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + realm_account: Option<&'b solana_account_info::AccountInfo<'a>>, + program_governance_account: Option<&'b solana_account_info::AccountInfo<'a>>, + governed_program: Option<&'b solana_account_info::AccountInfo<'a>>, + program_data: Option<&'b solana_account_info::AccountInfo<'a>>, + current_upgrade_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + governing_token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + payer: Option<&'b solana_account_info::AccountInfo<'a>>, + bpf_upgradeable_loader_program: Option<&'b solana_account_info::AccountInfo<'a>>, + system_program: Option<&'b solana_account_info::AccountInfo<'a>>, + governance_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + realm_config: Option<&'b solana_account_info::AccountInfo<'a>>, + voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + config: Option, + transfer_upgrade_authority: Option, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/create_proposal.rs b/e2e/governance/src/generated/instructions/create_proposal.rs new file mode 100644 index 0000000..02d16d8 --- /dev/null +++ b/e2e/governance/src/generated/instructions/create_proposal.rs @@ -0,0 +1,905 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::VoteType; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +pub const CREATE_PROPOSAL_DISCRIMINATOR: u8 = 6; + +/// Accounts. +#[derive(Debug)] +pub struct CreateProposal { + /// Realm account the created Proposal belongs to + pub realm_account: solana_pubkey::Pubkey, + /// Proposal account. PDA seeds ['governance',governance, governing_token_mint, proposal_index] + pub proposal_account: solana_pubkey::Pubkey, + /// Governance account + pub governance_account: solana_pubkey::Pubkey, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: solana_pubkey::Pubkey, + /// Token Mint the Proposal is created for + pub governing_token_mint: solana_pubkey::Pubkey, + /// Governance Authority (Token Owner or Governance Delegate) + pub governance_authority: solana_pubkey::Pubkey, + + pub payer: solana_pubkey::Pubkey, + + pub system_program: solana_pubkey::Pubkey, + /// RealmConfig account. PDA seeds: ['realm-config', realm] + pub realm_config: solana_pubkey::Pubkey, + /// Optional Voter Weight Record + pub voter_weight_record: Option, + /// Optional Proposal deposit is required when there are more active + /// proposals than the configured deposit exempt amount. + /// PDA seeds: ['proposal-deposit', proposal, deposit payer] + pub proposal_deposit_account: Option, +} + +impl CreateProposal { + pub fn instruction( + &self, + args: CreateProposalInstructionArgs, + ) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(args, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + args: CreateProposalInstructionArgs, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(11 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.governance_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.token_owner_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governing_token_mint, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governance_authority, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.payer, true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.system_program, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_config, + false, + )); + if let Some(voter_weight_record) = self.voter_weight_record { + accounts.push(solana_instruction::AccountMeta::new( + voter_weight_record, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(proposal_deposit_account) = self.proposal_deposit_account { + accounts.push(solana_instruction::AccountMeta::new_readonly( + proposal_deposit_account, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + accounts.extend_from_slice(remaining_accounts); + let mut data = CreateProposalInstructionData::new().try_to_vec().unwrap(); + let mut args = args.try_to_vec().unwrap(); + data.append(&mut args); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CreateProposalInstructionData { + discriminator: u8, +} + +impl CreateProposalInstructionData { + pub fn new() -> Self { + Self { discriminator: 6 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for CreateProposalInstructionData { + fn default() -> Self { + Self::new() + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CreateProposalInstructionArgs { + pub name: String, + pub description_link: String, + pub vote_type: VoteType, + pub options: Vec, + pub use_deny_option: bool, + pub proposal_seed: Pubkey, +} + +impl CreateProposalInstructionArgs { + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +/// Instruction builder for `CreateProposal`. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[writable]` proposal_account +/// 2. `[writable]` governance_account +/// 3. `[writable]` token_owner_record +/// 4. `[]` governing_token_mint +/// 5. `[signer]` governance_authority +/// 6. `[signer]` payer +/// 7. `[optional]` system_program (default to `11111111111111111111111111111111`) +/// 8. `[]` realm_config +/// 9. `[writable, optional]` voter_weight_record +/// 10. `[optional]` proposal_deposit_account +#[derive(Clone, Debug, Default)] +pub struct CreateProposalBuilder { + realm_account: Option, + proposal_account: Option, + governance_account: Option, + token_owner_record: Option, + governing_token_mint: Option, + governance_authority: Option, + payer: Option, + system_program: Option, + realm_config: Option, + voter_weight_record: Option, + proposal_deposit_account: Option, + name: Option, + description_link: Option, + vote_type: Option, + options: Option>, + use_deny_option: Option, + proposal_seed: Option, + __remaining_accounts: Vec, +} + +impl CreateProposalBuilder { + pub fn new() -> Self { + Self::default() + } + /// Realm account the created Proposal belongs to + #[inline(always)] + pub fn realm_account(&mut self, realm_account: solana_pubkey::Pubkey) -> &mut Self { + self.realm_account = Some(realm_account); + self + } + /// Proposal account. PDA seeds ['governance',governance, governing_token_mint, proposal_index] + #[inline(always)] + pub fn proposal_account(&mut self, proposal_account: solana_pubkey::Pubkey) -> &mut Self { + self.proposal_account = Some(proposal_account); + self + } + /// Governance account + #[inline(always)] + pub fn governance_account(&mut self, governance_account: solana_pubkey::Pubkey) -> &mut Self { + self.governance_account = Some(governance_account); + self + } + /// TokenOwnerRecord account of the Proposal owner + #[inline(always)] + pub fn token_owner_record(&mut self, token_owner_record: solana_pubkey::Pubkey) -> &mut Self { + self.token_owner_record = Some(token_owner_record); + self + } + /// Token Mint the Proposal is created for + #[inline(always)] + pub fn governing_token_mint( + &mut self, + governing_token_mint: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governing_token_mint = Some(governing_token_mint); + self + } + /// Governance Authority (Token Owner or Governance Delegate) + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governance_authority = Some(governance_authority); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: solana_pubkey::Pubkey) -> &mut Self { + self.payer = Some(payer); + self + } + /// `[optional account, default to '11111111111111111111111111111111']` + #[inline(always)] + pub fn system_program(&mut self, system_program: solana_pubkey::Pubkey) -> &mut Self { + self.system_program = Some(system_program); + self + } + /// RealmConfig account. PDA seeds: ['realm-config', realm] + #[inline(always)] + pub fn realm_config(&mut self, realm_config: solana_pubkey::Pubkey) -> &mut Self { + self.realm_config = Some(realm_config); + self + } + /// `[optional account]` + /// Optional Voter Weight Record + #[inline(always)] + pub fn voter_weight_record( + &mut self, + voter_weight_record: Option, + ) -> &mut Self { + self.voter_weight_record = voter_weight_record; + self + } + /// `[optional account]` + /// Optional Proposal deposit is required when there are more active + /// proposals than the configured deposit exempt amount. + /// PDA seeds: ['proposal-deposit', proposal, deposit payer] + #[inline(always)] + pub fn proposal_deposit_account( + &mut self, + proposal_deposit_account: Option, + ) -> &mut Self { + self.proposal_deposit_account = proposal_deposit_account; + self + } + #[inline(always)] + pub fn name(&mut self, name: String) -> &mut Self { + self.name = Some(name); + self + } + #[inline(always)] + pub fn description_link(&mut self, description_link: String) -> &mut Self { + self.description_link = Some(description_link); + self + } + #[inline(always)] + pub fn vote_type(&mut self, vote_type: VoteType) -> &mut Self { + self.vote_type = Some(vote_type); + self + } + #[inline(always)] + pub fn options(&mut self, options: Vec) -> &mut Self { + self.options = Some(options); + self + } + #[inline(always)] + pub fn use_deny_option(&mut self, use_deny_option: bool) -> &mut Self { + self.use_deny_option = Some(use_deny_option); + self + } + #[inline(always)] + pub fn proposal_seed(&mut self, proposal_seed: Pubkey) -> &mut Self { + self.proposal_seed = Some(proposal_seed); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = CreateProposal { + realm_account: self.realm_account.expect("realm_account is not set"), + proposal_account: self.proposal_account.expect("proposal_account is not set"), + governance_account: self + .governance_account + .expect("governance_account is not set"), + token_owner_record: self + .token_owner_record + .expect("token_owner_record is not set"), + governing_token_mint: self + .governing_token_mint + .expect("governing_token_mint is not set"), + governance_authority: self + .governance_authority + .expect("governance_authority is not set"), + payer: self.payer.expect("payer is not set"), + system_program: self + .system_program + .unwrap_or(solana_pubkey::pubkey!("11111111111111111111111111111111")), + realm_config: self.realm_config.expect("realm_config is not set"), + voter_weight_record: self.voter_weight_record, + proposal_deposit_account: self.proposal_deposit_account, + }; + let args = CreateProposalInstructionArgs { + name: self.name.clone().expect("name is not set"), + description_link: self + .description_link + .clone() + .expect("description_link is not set"), + vote_type: self.vote_type.clone().expect("vote_type is not set"), + options: self.options.clone().expect("options is not set"), + use_deny_option: self + .use_deny_option + .clone() + .expect("use_deny_option is not set"), + proposal_seed: self + .proposal_seed + .clone() + .expect("proposal_seed is not set"), + }; + + accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) + } +} + +/// `create_proposal` CPI accounts. +pub struct CreateProposalCpiAccounts<'a, 'b> { + /// Realm account the created Proposal belongs to + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + /// Proposal account. PDA seeds ['governance',governance, governing_token_mint, proposal_index] + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// Governance account + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// Token Mint the Proposal is created for + pub governing_token_mint: &'b solana_account_info::AccountInfo<'a>, + /// Governance Authority (Token Owner or Governance Delegate) + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, + /// RealmConfig account. PDA seeds: ['realm-config', realm] + pub realm_config: &'b solana_account_info::AccountInfo<'a>, + /// Optional Voter Weight Record + pub voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional Proposal deposit is required when there are more active + /// proposals than the configured deposit exempt amount. + /// PDA seeds: ['proposal-deposit', proposal, deposit payer] + pub proposal_deposit_account: Option<&'b solana_account_info::AccountInfo<'a>>, +} + +/// `create_proposal` CPI instruction. +pub struct CreateProposalCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + /// Realm account the created Proposal belongs to + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + /// Proposal account. PDA seeds ['governance',governance, governing_token_mint, proposal_index] + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// Governance account + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// Token Mint the Proposal is created for + pub governing_token_mint: &'b solana_account_info::AccountInfo<'a>, + /// Governance Authority (Token Owner or Governance Delegate) + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, + /// RealmConfig account. PDA seeds: ['realm-config', realm] + pub realm_config: &'b solana_account_info::AccountInfo<'a>, + /// Optional Voter Weight Record + pub voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional Proposal deposit is required when there are more active + /// proposals than the configured deposit exempt amount. + /// PDA seeds: ['proposal-deposit', proposal, deposit payer] + pub proposal_deposit_account: Option<&'b solana_account_info::AccountInfo<'a>>, + /// The arguments for the instruction. + pub __args: CreateProposalInstructionArgs, +} + +impl<'a, 'b> CreateProposalCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: CreateProposalCpiAccounts<'a, 'b>, + args: CreateProposalInstructionArgs, + ) -> Self { + Self { + __program: program, + realm_account: accounts.realm_account, + proposal_account: accounts.proposal_account, + governance_account: accounts.governance_account, + token_owner_record: accounts.token_owner_record, + governing_token_mint: accounts.governing_token_mint, + governance_authority: accounts.governance_authority, + payer: accounts.payer, + system_program: accounts.system_program, + realm_config: accounts.realm_config, + voter_weight_record: accounts.voter_weight_record, + proposal_deposit_account: accounts.proposal_deposit_account, + __args: args, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(11 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.governance_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.token_owner_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governing_token_mint.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governance_authority.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.payer.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.system_program.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_config.key, + false, + )); + if let Some(voter_weight_record) = self.voter_weight_record { + accounts.push(solana_instruction::AccountMeta::new( + *voter_weight_record.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(proposal_deposit_account) = self.proposal_deposit_account { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *proposal_deposit_account.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let mut data = CreateProposalInstructionData::new().try_to_vec().unwrap(); + let mut args = self.__args.try_to_vec().unwrap(); + data.append(&mut args); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(12 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.realm_account.clone()); + account_infos.push(self.proposal_account.clone()); + account_infos.push(self.governance_account.clone()); + account_infos.push(self.token_owner_record.clone()); + account_infos.push(self.governing_token_mint.clone()); + account_infos.push(self.governance_authority.clone()); + account_infos.push(self.payer.clone()); + account_infos.push(self.system_program.clone()); + account_infos.push(self.realm_config.clone()); + if let Some(voter_weight_record) = self.voter_weight_record { + account_infos.push(voter_weight_record.clone()); + } + if let Some(proposal_deposit_account) = self.proposal_deposit_account { + account_infos.push(proposal_deposit_account.clone()); + } + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `CreateProposal` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[writable]` proposal_account +/// 2. `[writable]` governance_account +/// 3. `[writable]` token_owner_record +/// 4. `[]` governing_token_mint +/// 5. `[signer]` governance_authority +/// 6. `[signer]` payer +/// 7. `[]` system_program +/// 8. `[]` realm_config +/// 9. `[writable, optional]` voter_weight_record +/// 10. `[optional]` proposal_deposit_account +#[derive(Clone, Debug)] +pub struct CreateProposalCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> CreateProposalCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(CreateProposalCpiBuilderInstruction { + __program: program, + realm_account: None, + proposal_account: None, + governance_account: None, + token_owner_record: None, + governing_token_mint: None, + governance_authority: None, + payer: None, + system_program: None, + realm_config: None, + voter_weight_record: None, + proposal_deposit_account: None, + name: None, + description_link: None, + vote_type: None, + options: None, + use_deny_option: None, + proposal_seed: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + /// Realm account the created Proposal belongs to + #[inline(always)] + pub fn realm_account( + &mut self, + realm_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_account = Some(realm_account); + self + } + /// Proposal account. PDA seeds ['governance',governance, governing_token_mint, proposal_index] + #[inline(always)] + pub fn proposal_account( + &mut self, + proposal_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_account = Some(proposal_account); + self + } + /// Governance account + #[inline(always)] + pub fn governance_account( + &mut self, + governance_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_account = Some(governance_account); + self + } + /// TokenOwnerRecord account of the Proposal owner + #[inline(always)] + pub fn token_owner_record( + &mut self, + token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_owner_record = Some(token_owner_record); + self + } + /// Token Mint the Proposal is created for + #[inline(always)] + pub fn governing_token_mint( + &mut self, + governing_token_mint: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governing_token_mint = Some(governing_token_mint); + self + } + /// Governance Authority (Token Owner or Governance Delegate) + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_authority = Some(governance_authority); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: &'b solana_account_info::AccountInfo<'a>) -> &mut Self { + self.instruction.payer = Some(payer); + self + } + #[inline(always)] + pub fn system_program( + &mut self, + system_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.system_program = Some(system_program); + self + } + /// RealmConfig account. PDA seeds: ['realm-config', realm] + #[inline(always)] + pub fn realm_config( + &mut self, + realm_config: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_config = Some(realm_config); + self + } + /// `[optional account]` + /// Optional Voter Weight Record + #[inline(always)] + pub fn voter_weight_record( + &mut self, + voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.voter_weight_record = voter_weight_record; + self + } + /// `[optional account]` + /// Optional Proposal deposit is required when there are more active + /// proposals than the configured deposit exempt amount. + /// PDA seeds: ['proposal-deposit', proposal, deposit payer] + #[inline(always)] + pub fn proposal_deposit_account( + &mut self, + proposal_deposit_account: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.proposal_deposit_account = proposal_deposit_account; + self + } + #[inline(always)] + pub fn name(&mut self, name: String) -> &mut Self { + self.instruction.name = Some(name); + self + } + #[inline(always)] + pub fn description_link(&mut self, description_link: String) -> &mut Self { + self.instruction.description_link = Some(description_link); + self + } + #[inline(always)] + pub fn vote_type(&mut self, vote_type: VoteType) -> &mut Self { + self.instruction.vote_type = Some(vote_type); + self + } + #[inline(always)] + pub fn options(&mut self, options: Vec) -> &mut Self { + self.instruction.options = Some(options); + self + } + #[inline(always)] + pub fn use_deny_option(&mut self, use_deny_option: bool) -> &mut Self { + self.instruction.use_deny_option = Some(use_deny_option); + self + } + #[inline(always)] + pub fn proposal_seed(&mut self, proposal_seed: Pubkey) -> &mut Self { + self.instruction.proposal_seed = Some(proposal_seed); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let args = CreateProposalInstructionArgs { + name: self.instruction.name.clone().expect("name is not set"), + description_link: self + .instruction + .description_link + .clone() + .expect("description_link is not set"), + vote_type: self + .instruction + .vote_type + .clone() + .expect("vote_type is not set"), + options: self + .instruction + .options + .clone() + .expect("options is not set"), + use_deny_option: self + .instruction + .use_deny_option + .clone() + .expect("use_deny_option is not set"), + proposal_seed: self + .instruction + .proposal_seed + .clone() + .expect("proposal_seed is not set"), + }; + let instruction = CreateProposalCpi { + __program: self.instruction.__program, + + realm_account: self + .instruction + .realm_account + .expect("realm_account is not set"), + + proposal_account: self + .instruction + .proposal_account + .expect("proposal_account is not set"), + + governance_account: self + .instruction + .governance_account + .expect("governance_account is not set"), + + token_owner_record: self + .instruction + .token_owner_record + .expect("token_owner_record is not set"), + + governing_token_mint: self + .instruction + .governing_token_mint + .expect("governing_token_mint is not set"), + + governance_authority: self + .instruction + .governance_authority + .expect("governance_authority is not set"), + + payer: self.instruction.payer.expect("payer is not set"), + + system_program: self + .instruction + .system_program + .expect("system_program is not set"), + + realm_config: self + .instruction + .realm_config + .expect("realm_config is not set"), + + voter_weight_record: self.instruction.voter_weight_record, + + proposal_deposit_account: self.instruction.proposal_deposit_account, + __args: args, + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct CreateProposalCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + realm_account: Option<&'b solana_account_info::AccountInfo<'a>>, + proposal_account: Option<&'b solana_account_info::AccountInfo<'a>>, + governance_account: Option<&'b solana_account_info::AccountInfo<'a>>, + token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + governing_token_mint: Option<&'b solana_account_info::AccountInfo<'a>>, + governance_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + payer: Option<&'b solana_account_info::AccountInfo<'a>>, + system_program: Option<&'b solana_account_info::AccountInfo<'a>>, + realm_config: Option<&'b solana_account_info::AccountInfo<'a>>, + voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + proposal_deposit_account: Option<&'b solana_account_info::AccountInfo<'a>>, + name: Option, + description_link: Option, + vote_type: Option, + options: Option>, + use_deny_option: Option, + proposal_seed: Option, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/create_realm.rs b/e2e/governance/src/generated/instructions/create_realm.rs new file mode 100644 index 0000000..6b8e8cc --- /dev/null +++ b/e2e/governance/src/generated/instructions/create_realm.rs @@ -0,0 +1,1051 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::RealmConfigParams; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const CREATE_REALM_DISCRIMINATOR: u8 = 0; + +/// Accounts. +#[derive(Debug)] +pub struct CreateRealm { + /// Governance Realm account + pub realm_account: solana_pubkey::Pubkey, + /// The authority of the Realm + pub realm_authority: solana_pubkey::Pubkey, + /// The mint address of the token to be used as the community mint + pub community_token_mint: solana_pubkey::Pubkey, + /// The account to hold the community tokens. + /// PDA seeds=['governance', realm, community_mint] + pub community_token_holding_account: solana_pubkey::Pubkey, + /// the payer of this transaction + pub payer: solana_pubkey::Pubkey, + /// System Program + pub system_program: solana_pubkey::Pubkey, + /// SPL Token Program + pub token_program: solana_pubkey::Pubkey, + /// SysVar Rent + pub rent: solana_pubkey::Pubkey, + /// The mint address of the token to be used as the council mint + pub council_token_mint: Option, + /// The account to hold the council tokens. + /// PDA seeds: ['governance',realm,council_mint] + /// + pub council_token_holding_account: Option, + /// Realm Config account + pub realm_config: solana_pubkey::Pubkey, + /// Optional Community Voter Weight Addin Program Id + pub community_voter_weight_addin: Option, + /// Optional Max Community Voter Weight Addin Program Id + pub max_community_voter_weight_addin: Option, + /// Optional Council Voter Weight Addin Program Id + pub council_voter_weight_addin: Option, + /// Optional Max Council Voter Weight Addin Program Id + pub max_council_voter_weight_addin: Option, +} + +impl CreateRealm { + pub fn instruction(&self, args: CreateRealmInstructionArgs) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(args, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + args: CreateRealmInstructionArgs, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(15 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + self.realm_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_authority, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.community_token_mint, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.community_token_holding_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new(self.payer, true)); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.system_program, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.token_program, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.rent, false, + )); + if let Some(council_token_mint) = self.council_token_mint { + accounts.push(solana_instruction::AccountMeta::new_readonly( + council_token_mint, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(council_token_holding_account) = self.council_token_holding_account { + accounts.push(solana_instruction::AccountMeta::new( + council_token_holding_account, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + accounts.push(solana_instruction::AccountMeta::new( + self.realm_config, + false, + )); + if let Some(community_voter_weight_addin) = self.community_voter_weight_addin { + accounts.push(solana_instruction::AccountMeta::new_readonly( + community_voter_weight_addin, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(max_community_voter_weight_addin) = self.max_community_voter_weight_addin { + accounts.push(solana_instruction::AccountMeta::new_readonly( + max_community_voter_weight_addin, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(council_voter_weight_addin) = self.council_voter_weight_addin { + accounts.push(solana_instruction::AccountMeta::new_readonly( + council_voter_weight_addin, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(max_council_voter_weight_addin) = self.max_council_voter_weight_addin { + accounts.push(solana_instruction::AccountMeta::new_readonly( + max_council_voter_weight_addin, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + accounts.extend_from_slice(remaining_accounts); + let mut data = CreateRealmInstructionData::new().try_to_vec().unwrap(); + let mut args = args.try_to_vec().unwrap(); + data.append(&mut args); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CreateRealmInstructionData { + discriminator: u8, +} + +impl CreateRealmInstructionData { + pub fn new() -> Self { + Self { discriminator: 0 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for CreateRealmInstructionData { + fn default() -> Self { + Self::new() + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CreateRealmInstructionArgs { + pub name: String, + pub config_args: RealmConfigParams, +} + +impl CreateRealmInstructionArgs { + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +/// Instruction builder for `CreateRealm`. +/// +/// ### Accounts: +/// +/// 0. `[writable]` realm_account +/// 1. `[]` realm_authority +/// 2. `[]` community_token_mint +/// 3. `[writable]` community_token_holding_account +/// 4. `[writable, signer]` payer +/// 5. `[optional]` system_program (default to `11111111111111111111111111111111`) +/// 6. `[optional]` token_program (default to `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`) +/// 7. `[optional]` rent (default to `SysvarRent111111111111111111111111111111111`) +/// 8. `[optional]` council_token_mint +/// 9. `[writable, optional]` council_token_holding_account +/// 10. `[writable]` realm_config +/// 11. `[optional]` community_voter_weight_addin +/// 12. `[optional]` max_community_voter_weight_addin +/// 13. `[optional]` council_voter_weight_addin +/// 14. `[optional]` max_council_voter_weight_addin +#[derive(Clone, Debug, Default)] +pub struct CreateRealmBuilder { + realm_account: Option, + realm_authority: Option, + community_token_mint: Option, + community_token_holding_account: Option, + payer: Option, + system_program: Option, + token_program: Option, + rent: Option, + council_token_mint: Option, + council_token_holding_account: Option, + realm_config: Option, + community_voter_weight_addin: Option, + max_community_voter_weight_addin: Option, + council_voter_weight_addin: Option, + max_council_voter_weight_addin: Option, + name: Option, + config_args: Option, + __remaining_accounts: Vec, +} + +impl CreateRealmBuilder { + pub fn new() -> Self { + Self::default() + } + /// Governance Realm account + #[inline(always)] + pub fn realm_account(&mut self, realm_account: solana_pubkey::Pubkey) -> &mut Self { + self.realm_account = Some(realm_account); + self + } + /// The authority of the Realm + #[inline(always)] + pub fn realm_authority(&mut self, realm_authority: solana_pubkey::Pubkey) -> &mut Self { + self.realm_authority = Some(realm_authority); + self + } + /// The mint address of the token to be used as the community mint + #[inline(always)] + pub fn community_token_mint( + &mut self, + community_token_mint: solana_pubkey::Pubkey, + ) -> &mut Self { + self.community_token_mint = Some(community_token_mint); + self + } + /// The account to hold the community tokens. + /// PDA seeds=['governance', realm, community_mint] + #[inline(always)] + pub fn community_token_holding_account( + &mut self, + community_token_holding_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.community_token_holding_account = Some(community_token_holding_account); + self + } + /// the payer of this transaction + #[inline(always)] + pub fn payer(&mut self, payer: solana_pubkey::Pubkey) -> &mut Self { + self.payer = Some(payer); + self + } + /// `[optional account, default to '11111111111111111111111111111111']` + /// System Program + #[inline(always)] + pub fn system_program(&mut self, system_program: solana_pubkey::Pubkey) -> &mut Self { + self.system_program = Some(system_program); + self + } + /// `[optional account, default to 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA']` + /// SPL Token Program + #[inline(always)] + pub fn token_program(&mut self, token_program: solana_pubkey::Pubkey) -> &mut Self { + self.token_program = Some(token_program); + self + } + /// `[optional account, default to 'SysvarRent111111111111111111111111111111111']` + /// SysVar Rent + #[inline(always)] + pub fn rent(&mut self, rent: solana_pubkey::Pubkey) -> &mut Self { + self.rent = Some(rent); + self + } + /// `[optional account]` + /// The mint address of the token to be used as the council mint + #[inline(always)] + pub fn council_token_mint( + &mut self, + council_token_mint: Option, + ) -> &mut Self { + self.council_token_mint = council_token_mint; + self + } + /// `[optional account]` + /// The account to hold the council tokens. + /// PDA seeds: ['governance',realm,council_mint] + /// + #[inline(always)] + pub fn council_token_holding_account( + &mut self, + council_token_holding_account: Option, + ) -> &mut Self { + self.council_token_holding_account = council_token_holding_account; + self + } + /// Realm Config account + #[inline(always)] + pub fn realm_config(&mut self, realm_config: solana_pubkey::Pubkey) -> &mut Self { + self.realm_config = Some(realm_config); + self + } + /// `[optional account]` + /// Optional Community Voter Weight Addin Program Id + #[inline(always)] + pub fn community_voter_weight_addin( + &mut self, + community_voter_weight_addin: Option, + ) -> &mut Self { + self.community_voter_weight_addin = community_voter_weight_addin; + self + } + /// `[optional account]` + /// Optional Max Community Voter Weight Addin Program Id + #[inline(always)] + pub fn max_community_voter_weight_addin( + &mut self, + max_community_voter_weight_addin: Option, + ) -> &mut Self { + self.max_community_voter_weight_addin = max_community_voter_weight_addin; + self + } + /// `[optional account]` + /// Optional Council Voter Weight Addin Program Id + #[inline(always)] + pub fn council_voter_weight_addin( + &mut self, + council_voter_weight_addin: Option, + ) -> &mut Self { + self.council_voter_weight_addin = council_voter_weight_addin; + self + } + /// `[optional account]` + /// Optional Max Council Voter Weight Addin Program Id + #[inline(always)] + pub fn max_council_voter_weight_addin( + &mut self, + max_council_voter_weight_addin: Option, + ) -> &mut Self { + self.max_council_voter_weight_addin = max_council_voter_weight_addin; + self + } + #[inline(always)] + pub fn name(&mut self, name: String) -> &mut Self { + self.name = Some(name); + self + } + #[inline(always)] + pub fn config_args(&mut self, config_args: RealmConfigParams) -> &mut Self { + self.config_args = Some(config_args); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = CreateRealm { + realm_account: self.realm_account.expect("realm_account is not set"), + realm_authority: self.realm_authority.expect("realm_authority is not set"), + community_token_mint: self + .community_token_mint + .expect("community_token_mint is not set"), + community_token_holding_account: self + .community_token_holding_account + .expect("community_token_holding_account is not set"), + payer: self.payer.expect("payer is not set"), + system_program: self + .system_program + .unwrap_or(solana_pubkey::pubkey!("11111111111111111111111111111111")), + token_program: self.token_program.unwrap_or(solana_pubkey::pubkey!( + "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + )), + rent: self.rent.unwrap_or(solana_pubkey::pubkey!( + "SysvarRent111111111111111111111111111111111" + )), + council_token_mint: self.council_token_mint, + council_token_holding_account: self.council_token_holding_account, + realm_config: self.realm_config.expect("realm_config is not set"), + community_voter_weight_addin: self.community_voter_weight_addin, + max_community_voter_weight_addin: self.max_community_voter_weight_addin, + council_voter_weight_addin: self.council_voter_weight_addin, + max_council_voter_weight_addin: self.max_council_voter_weight_addin, + }; + let args = CreateRealmInstructionArgs { + name: self.name.clone().expect("name is not set"), + config_args: self.config_args.clone().expect("config_args is not set"), + }; + + accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) + } +} + +/// `create_realm` CPI accounts. +pub struct CreateRealmCpiAccounts<'a, 'b> { + /// Governance Realm account + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + /// The authority of the Realm + pub realm_authority: &'b solana_account_info::AccountInfo<'a>, + /// The mint address of the token to be used as the community mint + pub community_token_mint: &'b solana_account_info::AccountInfo<'a>, + /// The account to hold the community tokens. + /// PDA seeds=['governance', realm, community_mint] + pub community_token_holding_account: &'b solana_account_info::AccountInfo<'a>, + /// the payer of this transaction + pub payer: &'b solana_account_info::AccountInfo<'a>, + /// System Program + pub system_program: &'b solana_account_info::AccountInfo<'a>, + /// SPL Token Program + pub token_program: &'b solana_account_info::AccountInfo<'a>, + /// SysVar Rent + pub rent: &'b solana_account_info::AccountInfo<'a>, + /// The mint address of the token to be used as the council mint + pub council_token_mint: Option<&'b solana_account_info::AccountInfo<'a>>, + /// The account to hold the council tokens. + /// PDA seeds: ['governance',realm,council_mint] + /// + pub council_token_holding_account: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Realm Config account + pub realm_config: &'b solana_account_info::AccountInfo<'a>, + /// Optional Community Voter Weight Addin Program Id + pub community_voter_weight_addin: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional Max Community Voter Weight Addin Program Id + pub max_community_voter_weight_addin: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional Council Voter Weight Addin Program Id + pub council_voter_weight_addin: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional Max Council Voter Weight Addin Program Id + pub max_council_voter_weight_addin: Option<&'b solana_account_info::AccountInfo<'a>>, +} + +/// `create_realm` CPI instruction. +pub struct CreateRealmCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + /// Governance Realm account + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + /// The authority of the Realm + pub realm_authority: &'b solana_account_info::AccountInfo<'a>, + /// The mint address of the token to be used as the community mint + pub community_token_mint: &'b solana_account_info::AccountInfo<'a>, + /// The account to hold the community tokens. + /// PDA seeds=['governance', realm, community_mint] + pub community_token_holding_account: &'b solana_account_info::AccountInfo<'a>, + /// the payer of this transaction + pub payer: &'b solana_account_info::AccountInfo<'a>, + /// System Program + pub system_program: &'b solana_account_info::AccountInfo<'a>, + /// SPL Token Program + pub token_program: &'b solana_account_info::AccountInfo<'a>, + /// SysVar Rent + pub rent: &'b solana_account_info::AccountInfo<'a>, + /// The mint address of the token to be used as the council mint + pub council_token_mint: Option<&'b solana_account_info::AccountInfo<'a>>, + /// The account to hold the council tokens. + /// PDA seeds: ['governance',realm,council_mint] + /// + pub council_token_holding_account: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Realm Config account + pub realm_config: &'b solana_account_info::AccountInfo<'a>, + /// Optional Community Voter Weight Addin Program Id + pub community_voter_weight_addin: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional Max Community Voter Weight Addin Program Id + pub max_community_voter_weight_addin: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional Council Voter Weight Addin Program Id + pub council_voter_weight_addin: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional Max Council Voter Weight Addin Program Id + pub max_council_voter_weight_addin: Option<&'b solana_account_info::AccountInfo<'a>>, + /// The arguments for the instruction. + pub __args: CreateRealmInstructionArgs, +} + +impl<'a, 'b> CreateRealmCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: CreateRealmCpiAccounts<'a, 'b>, + args: CreateRealmInstructionArgs, + ) -> Self { + Self { + __program: program, + realm_account: accounts.realm_account, + realm_authority: accounts.realm_authority, + community_token_mint: accounts.community_token_mint, + community_token_holding_account: accounts.community_token_holding_account, + payer: accounts.payer, + system_program: accounts.system_program, + token_program: accounts.token_program, + rent: accounts.rent, + council_token_mint: accounts.council_token_mint, + council_token_holding_account: accounts.council_token_holding_account, + realm_config: accounts.realm_config, + community_voter_weight_addin: accounts.community_voter_weight_addin, + max_community_voter_weight_addin: accounts.max_community_voter_weight_addin, + council_voter_weight_addin: accounts.council_voter_weight_addin, + max_council_voter_weight_addin: accounts.max_council_voter_weight_addin, + __args: args, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(15 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + *self.realm_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_authority.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.community_token_mint.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.community_token_holding_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new(*self.payer.key, true)); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.system_program.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.token_program.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.rent.key, + false, + )); + if let Some(council_token_mint) = self.council_token_mint { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *council_token_mint.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(council_token_holding_account) = self.council_token_holding_account { + accounts.push(solana_instruction::AccountMeta::new( + *council_token_holding_account.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + accounts.push(solana_instruction::AccountMeta::new( + *self.realm_config.key, + false, + )); + if let Some(community_voter_weight_addin) = self.community_voter_weight_addin { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *community_voter_weight_addin.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(max_community_voter_weight_addin) = self.max_community_voter_weight_addin { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *max_community_voter_weight_addin.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(council_voter_weight_addin) = self.council_voter_weight_addin { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *council_voter_weight_addin.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(max_council_voter_weight_addin) = self.max_council_voter_weight_addin { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *max_council_voter_weight_addin.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let mut data = CreateRealmInstructionData::new().try_to_vec().unwrap(); + let mut args = self.__args.try_to_vec().unwrap(); + data.append(&mut args); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(16 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.realm_account.clone()); + account_infos.push(self.realm_authority.clone()); + account_infos.push(self.community_token_mint.clone()); + account_infos.push(self.community_token_holding_account.clone()); + account_infos.push(self.payer.clone()); + account_infos.push(self.system_program.clone()); + account_infos.push(self.token_program.clone()); + account_infos.push(self.rent.clone()); + if let Some(council_token_mint) = self.council_token_mint { + account_infos.push(council_token_mint.clone()); + } + if let Some(council_token_holding_account) = self.council_token_holding_account { + account_infos.push(council_token_holding_account.clone()); + } + account_infos.push(self.realm_config.clone()); + if let Some(community_voter_weight_addin) = self.community_voter_weight_addin { + account_infos.push(community_voter_weight_addin.clone()); + } + if let Some(max_community_voter_weight_addin) = self.max_community_voter_weight_addin { + account_infos.push(max_community_voter_weight_addin.clone()); + } + if let Some(council_voter_weight_addin) = self.council_voter_weight_addin { + account_infos.push(council_voter_weight_addin.clone()); + } + if let Some(max_council_voter_weight_addin) = self.max_council_voter_weight_addin { + account_infos.push(max_council_voter_weight_addin.clone()); + } + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `CreateRealm` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[writable]` realm_account +/// 1. `[]` realm_authority +/// 2. `[]` community_token_mint +/// 3. `[writable]` community_token_holding_account +/// 4. `[writable, signer]` payer +/// 5. `[]` system_program +/// 6. `[]` token_program +/// 7. `[]` rent +/// 8. `[optional]` council_token_mint +/// 9. `[writable, optional]` council_token_holding_account +/// 10. `[writable]` realm_config +/// 11. `[optional]` community_voter_weight_addin +/// 12. `[optional]` max_community_voter_weight_addin +/// 13. `[optional]` council_voter_weight_addin +/// 14. `[optional]` max_council_voter_weight_addin +#[derive(Clone, Debug)] +pub struct CreateRealmCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> CreateRealmCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(CreateRealmCpiBuilderInstruction { + __program: program, + realm_account: None, + realm_authority: None, + community_token_mint: None, + community_token_holding_account: None, + payer: None, + system_program: None, + token_program: None, + rent: None, + council_token_mint: None, + council_token_holding_account: None, + realm_config: None, + community_voter_weight_addin: None, + max_community_voter_weight_addin: None, + council_voter_weight_addin: None, + max_council_voter_weight_addin: None, + name: None, + config_args: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + /// Governance Realm account + #[inline(always)] + pub fn realm_account( + &mut self, + realm_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_account = Some(realm_account); + self + } + /// The authority of the Realm + #[inline(always)] + pub fn realm_authority( + &mut self, + realm_authority: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_authority = Some(realm_authority); + self + } + /// The mint address of the token to be used as the community mint + #[inline(always)] + pub fn community_token_mint( + &mut self, + community_token_mint: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.community_token_mint = Some(community_token_mint); + self + } + /// The account to hold the community tokens. + /// PDA seeds=['governance', realm, community_mint] + #[inline(always)] + pub fn community_token_holding_account( + &mut self, + community_token_holding_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.community_token_holding_account = Some(community_token_holding_account); + self + } + /// the payer of this transaction + #[inline(always)] + pub fn payer(&mut self, payer: &'b solana_account_info::AccountInfo<'a>) -> &mut Self { + self.instruction.payer = Some(payer); + self + } + /// System Program + #[inline(always)] + pub fn system_program( + &mut self, + system_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.system_program = Some(system_program); + self + } + /// SPL Token Program + #[inline(always)] + pub fn token_program( + &mut self, + token_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_program = Some(token_program); + self + } + /// SysVar Rent + #[inline(always)] + pub fn rent(&mut self, rent: &'b solana_account_info::AccountInfo<'a>) -> &mut Self { + self.instruction.rent = Some(rent); + self + } + /// `[optional account]` + /// The mint address of the token to be used as the council mint + #[inline(always)] + pub fn council_token_mint( + &mut self, + council_token_mint: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.council_token_mint = council_token_mint; + self + } + /// `[optional account]` + /// The account to hold the council tokens. + /// PDA seeds: ['governance',realm,council_mint] + /// + #[inline(always)] + pub fn council_token_holding_account( + &mut self, + council_token_holding_account: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.council_token_holding_account = council_token_holding_account; + self + } + /// Realm Config account + #[inline(always)] + pub fn realm_config( + &mut self, + realm_config: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_config = Some(realm_config); + self + } + /// `[optional account]` + /// Optional Community Voter Weight Addin Program Id + #[inline(always)] + pub fn community_voter_weight_addin( + &mut self, + community_voter_weight_addin: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.community_voter_weight_addin = community_voter_weight_addin; + self + } + /// `[optional account]` + /// Optional Max Community Voter Weight Addin Program Id + #[inline(always)] + pub fn max_community_voter_weight_addin( + &mut self, + max_community_voter_weight_addin: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.max_community_voter_weight_addin = max_community_voter_weight_addin; + self + } + /// `[optional account]` + /// Optional Council Voter Weight Addin Program Id + #[inline(always)] + pub fn council_voter_weight_addin( + &mut self, + council_voter_weight_addin: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.council_voter_weight_addin = council_voter_weight_addin; + self + } + /// `[optional account]` + /// Optional Max Council Voter Weight Addin Program Id + #[inline(always)] + pub fn max_council_voter_weight_addin( + &mut self, + max_council_voter_weight_addin: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.max_council_voter_weight_addin = max_council_voter_weight_addin; + self + } + #[inline(always)] + pub fn name(&mut self, name: String) -> &mut Self { + self.instruction.name = Some(name); + self + } + #[inline(always)] + pub fn config_args(&mut self, config_args: RealmConfigParams) -> &mut Self { + self.instruction.config_args = Some(config_args); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let args = CreateRealmInstructionArgs { + name: self.instruction.name.clone().expect("name is not set"), + config_args: self + .instruction + .config_args + .clone() + .expect("config_args is not set"), + }; + let instruction = CreateRealmCpi { + __program: self.instruction.__program, + + realm_account: self + .instruction + .realm_account + .expect("realm_account is not set"), + + realm_authority: self + .instruction + .realm_authority + .expect("realm_authority is not set"), + + community_token_mint: self + .instruction + .community_token_mint + .expect("community_token_mint is not set"), + + community_token_holding_account: self + .instruction + .community_token_holding_account + .expect("community_token_holding_account is not set"), + + payer: self.instruction.payer.expect("payer is not set"), + + system_program: self + .instruction + .system_program + .expect("system_program is not set"), + + token_program: self + .instruction + .token_program + .expect("token_program is not set"), + + rent: self.instruction.rent.expect("rent is not set"), + + council_token_mint: self.instruction.council_token_mint, + + council_token_holding_account: self.instruction.council_token_holding_account, + + realm_config: self + .instruction + .realm_config + .expect("realm_config is not set"), + + community_voter_weight_addin: self.instruction.community_voter_weight_addin, + + max_community_voter_weight_addin: self.instruction.max_community_voter_weight_addin, + + council_voter_weight_addin: self.instruction.council_voter_weight_addin, + + max_council_voter_weight_addin: self.instruction.max_council_voter_weight_addin, + __args: args, + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct CreateRealmCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + realm_account: Option<&'b solana_account_info::AccountInfo<'a>>, + realm_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + community_token_mint: Option<&'b solana_account_info::AccountInfo<'a>>, + community_token_holding_account: Option<&'b solana_account_info::AccountInfo<'a>>, + payer: Option<&'b solana_account_info::AccountInfo<'a>>, + system_program: Option<&'b solana_account_info::AccountInfo<'a>>, + token_program: Option<&'b solana_account_info::AccountInfo<'a>>, + rent: Option<&'b solana_account_info::AccountInfo<'a>>, + council_token_mint: Option<&'b solana_account_info::AccountInfo<'a>>, + council_token_holding_account: Option<&'b solana_account_info::AccountInfo<'a>>, + realm_config: Option<&'b solana_account_info::AccountInfo<'a>>, + community_voter_weight_addin: Option<&'b solana_account_info::AccountInfo<'a>>, + max_community_voter_weight_addin: Option<&'b solana_account_info::AccountInfo<'a>>, + council_voter_weight_addin: Option<&'b solana_account_info::AccountInfo<'a>>, + max_council_voter_weight_addin: Option<&'b solana_account_info::AccountInfo<'a>>, + name: Option, + config_args: Option, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/create_token_governance.rs b/e2e/governance/src/generated/instructions/create_token_governance.rs new file mode 100644 index 0000000..50425d3 --- /dev/null +++ b/e2e/governance/src/generated/instructions/create_token_governance.rs @@ -0,0 +1,805 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceConfig; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const CREATE_TOKEN_GOVERNANCE_DISCRIMINATOR: u8 = 18; + +/// Accounts. +#[derive(Debug)] +pub struct CreateTokenGovernance { + /// Realm account the created Governance belongs to + pub realm_account: solana_pubkey::Pubkey, + /// Token Governance account. seeds=['token-governance', realm, governed_token] + pub token_governance_account: solana_pubkey::Pubkey, + /// Token account governed by this Governance account + pub token_account: solana_pubkey::Pubkey, + /// Current token account authority (AccountOwner and optionally CloseAccount + pub token_account_authority: solana_pubkey::Pubkey, + /// Governing TokenOwnerRecord account (Used only if not signed by RealmAuthority + pub governing_token_owner_record: solana_pubkey::Pubkey, + + pub payer: solana_pubkey::Pubkey, + + pub token_program: solana_pubkey::Pubkey, + + pub system_program: solana_pubkey::Pubkey, + + pub governance_authority: solana_pubkey::Pubkey, + /// seeds=['realm-config', realm] + pub realm_config: solana_pubkey::Pubkey, + /// Optional Voter Weight Record + pub voter_weight_record: Option, +} + +impl CreateTokenGovernance { + pub fn instruction( + &self, + args: CreateTokenGovernanceInstructionArgs, + ) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(args, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + args: CreateTokenGovernanceInstructionArgs, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(11 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.token_governance_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.token_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.token_account_authority, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governing_token_owner_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.payer, true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.token_program, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.system_program, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governance_authority, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_config, + false, + )); + if let Some(voter_weight_record) = self.voter_weight_record { + accounts.push(solana_instruction::AccountMeta::new_readonly( + voter_weight_record, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + accounts.extend_from_slice(remaining_accounts); + let mut data = CreateTokenGovernanceInstructionData::new() + .try_to_vec() + .unwrap(); + let mut args = args.try_to_vec().unwrap(); + data.append(&mut args); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CreateTokenGovernanceInstructionData { + discriminator: u8, +} + +impl CreateTokenGovernanceInstructionData { + pub fn new() -> Self { + Self { discriminator: 18 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for CreateTokenGovernanceInstructionData { + fn default() -> Self { + Self::new() + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CreateTokenGovernanceInstructionArgs { + pub config: GovernanceConfig, + pub transfer_account_authorities: bool, +} + +impl CreateTokenGovernanceInstructionArgs { + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +/// Instruction builder for `CreateTokenGovernance`. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[writable]` token_governance_account +/// 2. `[writable]` token_account +/// 3. `[signer]` token_account_authority +/// 4. `[]` governing_token_owner_record +/// 5. `[signer]` payer +/// 6. `[optional]` token_program (default to `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`) +/// 7. `[optional]` system_program (default to `11111111111111111111111111111111`) +/// 8. `[signer]` governance_authority +/// 9. `[]` realm_config +/// 10. `[optional]` voter_weight_record +#[derive(Clone, Debug, Default)] +pub struct CreateTokenGovernanceBuilder { + realm_account: Option, + token_governance_account: Option, + token_account: Option, + token_account_authority: Option, + governing_token_owner_record: Option, + payer: Option, + token_program: Option, + system_program: Option, + governance_authority: Option, + realm_config: Option, + voter_weight_record: Option, + config: Option, + transfer_account_authorities: Option, + __remaining_accounts: Vec, +} + +impl CreateTokenGovernanceBuilder { + pub fn new() -> Self { + Self::default() + } + /// Realm account the created Governance belongs to + #[inline(always)] + pub fn realm_account(&mut self, realm_account: solana_pubkey::Pubkey) -> &mut Self { + self.realm_account = Some(realm_account); + self + } + /// Token Governance account. seeds=['token-governance', realm, governed_token] + #[inline(always)] + pub fn token_governance_account( + &mut self, + token_governance_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.token_governance_account = Some(token_governance_account); + self + } + /// Token account governed by this Governance account + #[inline(always)] + pub fn token_account(&mut self, token_account: solana_pubkey::Pubkey) -> &mut Self { + self.token_account = Some(token_account); + self + } + /// Current token account authority (AccountOwner and optionally CloseAccount + #[inline(always)] + pub fn token_account_authority( + &mut self, + token_account_authority: solana_pubkey::Pubkey, + ) -> &mut Self { + self.token_account_authority = Some(token_account_authority); + self + } + /// Governing TokenOwnerRecord account (Used only if not signed by RealmAuthority + #[inline(always)] + pub fn governing_token_owner_record( + &mut self, + governing_token_owner_record: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governing_token_owner_record = Some(governing_token_owner_record); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: solana_pubkey::Pubkey) -> &mut Self { + self.payer = Some(payer); + self + } + /// `[optional account, default to 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA']` + #[inline(always)] + pub fn token_program(&mut self, token_program: solana_pubkey::Pubkey) -> &mut Self { + self.token_program = Some(token_program); + self + } + /// `[optional account, default to '11111111111111111111111111111111']` + #[inline(always)] + pub fn system_program(&mut self, system_program: solana_pubkey::Pubkey) -> &mut Self { + self.system_program = Some(system_program); + self + } + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governance_authority = Some(governance_authority); + self + } + /// seeds=['realm-config', realm] + #[inline(always)] + pub fn realm_config(&mut self, realm_config: solana_pubkey::Pubkey) -> &mut Self { + self.realm_config = Some(realm_config); + self + } + /// `[optional account]` + /// Optional Voter Weight Record + #[inline(always)] + pub fn voter_weight_record( + &mut self, + voter_weight_record: Option, + ) -> &mut Self { + self.voter_weight_record = voter_weight_record; + self + } + #[inline(always)] + pub fn config(&mut self, config: GovernanceConfig) -> &mut Self { + self.config = Some(config); + self + } + #[inline(always)] + pub fn transfer_account_authorities( + &mut self, + transfer_account_authorities: bool, + ) -> &mut Self { + self.transfer_account_authorities = Some(transfer_account_authorities); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = CreateTokenGovernance { + realm_account: self.realm_account.expect("realm_account is not set"), + token_governance_account: self + .token_governance_account + .expect("token_governance_account is not set"), + token_account: self.token_account.expect("token_account is not set"), + token_account_authority: self + .token_account_authority + .expect("token_account_authority is not set"), + governing_token_owner_record: self + .governing_token_owner_record + .expect("governing_token_owner_record is not set"), + payer: self.payer.expect("payer is not set"), + token_program: self.token_program.unwrap_or(solana_pubkey::pubkey!( + "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + )), + system_program: self + .system_program + .unwrap_or(solana_pubkey::pubkey!("11111111111111111111111111111111")), + governance_authority: self + .governance_authority + .expect("governance_authority is not set"), + realm_config: self.realm_config.expect("realm_config is not set"), + voter_weight_record: self.voter_weight_record, + }; + let args = CreateTokenGovernanceInstructionArgs { + config: self.config.clone().expect("config is not set"), + transfer_account_authorities: self + .transfer_account_authorities + .clone() + .expect("transfer_account_authorities is not set"), + }; + + accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) + } +} + +/// `create_token_governance` CPI accounts. +pub struct CreateTokenGovernanceCpiAccounts<'a, 'b> { + /// Realm account the created Governance belongs to + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + /// Token Governance account. seeds=['token-governance', realm, governed_token] + pub token_governance_account: &'b solana_account_info::AccountInfo<'a>, + /// Token account governed by this Governance account + pub token_account: &'b solana_account_info::AccountInfo<'a>, + /// Current token account authority (AccountOwner and optionally CloseAccount + pub token_account_authority: &'b solana_account_info::AccountInfo<'a>, + /// Governing TokenOwnerRecord account (Used only if not signed by RealmAuthority + pub governing_token_owner_record: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub token_program: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, + + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['realm-config', realm] + pub realm_config: &'b solana_account_info::AccountInfo<'a>, + /// Optional Voter Weight Record + pub voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, +} + +/// `create_token_governance` CPI instruction. +pub struct CreateTokenGovernanceCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + /// Realm account the created Governance belongs to + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + /// Token Governance account. seeds=['token-governance', realm, governed_token] + pub token_governance_account: &'b solana_account_info::AccountInfo<'a>, + /// Token account governed by this Governance account + pub token_account: &'b solana_account_info::AccountInfo<'a>, + /// Current token account authority (AccountOwner and optionally CloseAccount + pub token_account_authority: &'b solana_account_info::AccountInfo<'a>, + /// Governing TokenOwnerRecord account (Used only if not signed by RealmAuthority + pub governing_token_owner_record: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub token_program: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, + + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['realm-config', realm] + pub realm_config: &'b solana_account_info::AccountInfo<'a>, + /// Optional Voter Weight Record + pub voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + /// The arguments for the instruction. + pub __args: CreateTokenGovernanceInstructionArgs, +} + +impl<'a, 'b> CreateTokenGovernanceCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: CreateTokenGovernanceCpiAccounts<'a, 'b>, + args: CreateTokenGovernanceInstructionArgs, + ) -> Self { + Self { + __program: program, + realm_account: accounts.realm_account, + token_governance_account: accounts.token_governance_account, + token_account: accounts.token_account, + token_account_authority: accounts.token_account_authority, + governing_token_owner_record: accounts.governing_token_owner_record, + payer: accounts.payer, + token_program: accounts.token_program, + system_program: accounts.system_program, + governance_authority: accounts.governance_authority, + realm_config: accounts.realm_config, + voter_weight_record: accounts.voter_weight_record, + __args: args, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(11 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.token_governance_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.token_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.token_account_authority.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governing_token_owner_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.payer.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.token_program.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.system_program.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governance_authority.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_config.key, + false, + )); + if let Some(voter_weight_record) = self.voter_weight_record { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *voter_weight_record.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let mut data = CreateTokenGovernanceInstructionData::new() + .try_to_vec() + .unwrap(); + let mut args = self.__args.try_to_vec().unwrap(); + data.append(&mut args); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(12 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.realm_account.clone()); + account_infos.push(self.token_governance_account.clone()); + account_infos.push(self.token_account.clone()); + account_infos.push(self.token_account_authority.clone()); + account_infos.push(self.governing_token_owner_record.clone()); + account_infos.push(self.payer.clone()); + account_infos.push(self.token_program.clone()); + account_infos.push(self.system_program.clone()); + account_infos.push(self.governance_authority.clone()); + account_infos.push(self.realm_config.clone()); + if let Some(voter_weight_record) = self.voter_weight_record { + account_infos.push(voter_weight_record.clone()); + } + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `CreateTokenGovernance` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[writable]` token_governance_account +/// 2. `[writable]` token_account +/// 3. `[signer]` token_account_authority +/// 4. `[]` governing_token_owner_record +/// 5. `[signer]` payer +/// 6. `[]` token_program +/// 7. `[]` system_program +/// 8. `[signer]` governance_authority +/// 9. `[]` realm_config +/// 10. `[optional]` voter_weight_record +#[derive(Clone, Debug)] +pub struct CreateTokenGovernanceCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> CreateTokenGovernanceCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(CreateTokenGovernanceCpiBuilderInstruction { + __program: program, + realm_account: None, + token_governance_account: None, + token_account: None, + token_account_authority: None, + governing_token_owner_record: None, + payer: None, + token_program: None, + system_program: None, + governance_authority: None, + realm_config: None, + voter_weight_record: None, + config: None, + transfer_account_authorities: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + /// Realm account the created Governance belongs to + #[inline(always)] + pub fn realm_account( + &mut self, + realm_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_account = Some(realm_account); + self + } + /// Token Governance account. seeds=['token-governance', realm, governed_token] + #[inline(always)] + pub fn token_governance_account( + &mut self, + token_governance_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_governance_account = Some(token_governance_account); + self + } + /// Token account governed by this Governance account + #[inline(always)] + pub fn token_account( + &mut self, + token_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_account = Some(token_account); + self + } + /// Current token account authority (AccountOwner and optionally CloseAccount + #[inline(always)] + pub fn token_account_authority( + &mut self, + token_account_authority: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_account_authority = Some(token_account_authority); + self + } + /// Governing TokenOwnerRecord account (Used only if not signed by RealmAuthority + #[inline(always)] + pub fn governing_token_owner_record( + &mut self, + governing_token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governing_token_owner_record = Some(governing_token_owner_record); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: &'b solana_account_info::AccountInfo<'a>) -> &mut Self { + self.instruction.payer = Some(payer); + self + } + #[inline(always)] + pub fn token_program( + &mut self, + token_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_program = Some(token_program); + self + } + #[inline(always)] + pub fn system_program( + &mut self, + system_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.system_program = Some(system_program); + self + } + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_authority = Some(governance_authority); + self + } + /// seeds=['realm-config', realm] + #[inline(always)] + pub fn realm_config( + &mut self, + realm_config: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_config = Some(realm_config); + self + } + /// `[optional account]` + /// Optional Voter Weight Record + #[inline(always)] + pub fn voter_weight_record( + &mut self, + voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.voter_weight_record = voter_weight_record; + self + } + #[inline(always)] + pub fn config(&mut self, config: GovernanceConfig) -> &mut Self { + self.instruction.config = Some(config); + self + } + #[inline(always)] + pub fn transfer_account_authorities( + &mut self, + transfer_account_authorities: bool, + ) -> &mut Self { + self.instruction.transfer_account_authorities = Some(transfer_account_authorities); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let args = CreateTokenGovernanceInstructionArgs { + config: self.instruction.config.clone().expect("config is not set"), + transfer_account_authorities: self + .instruction + .transfer_account_authorities + .clone() + .expect("transfer_account_authorities is not set"), + }; + let instruction = CreateTokenGovernanceCpi { + __program: self.instruction.__program, + + realm_account: self + .instruction + .realm_account + .expect("realm_account is not set"), + + token_governance_account: self + .instruction + .token_governance_account + .expect("token_governance_account is not set"), + + token_account: self + .instruction + .token_account + .expect("token_account is not set"), + + token_account_authority: self + .instruction + .token_account_authority + .expect("token_account_authority is not set"), + + governing_token_owner_record: self + .instruction + .governing_token_owner_record + .expect("governing_token_owner_record is not set"), + + payer: self.instruction.payer.expect("payer is not set"), + + token_program: self + .instruction + .token_program + .expect("token_program is not set"), + + system_program: self + .instruction + .system_program + .expect("system_program is not set"), + + governance_authority: self + .instruction + .governance_authority + .expect("governance_authority is not set"), + + realm_config: self + .instruction + .realm_config + .expect("realm_config is not set"), + + voter_weight_record: self.instruction.voter_weight_record, + __args: args, + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct CreateTokenGovernanceCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + realm_account: Option<&'b solana_account_info::AccountInfo<'a>>, + token_governance_account: Option<&'b solana_account_info::AccountInfo<'a>>, + token_account: Option<&'b solana_account_info::AccountInfo<'a>>, + token_account_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + governing_token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + payer: Option<&'b solana_account_info::AccountInfo<'a>>, + token_program: Option<&'b solana_account_info::AccountInfo<'a>>, + system_program: Option<&'b solana_account_info::AccountInfo<'a>>, + governance_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + realm_config: Option<&'b solana_account_info::AccountInfo<'a>>, + voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + config: Option, + transfer_account_authorities: Option, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/create_token_owner_record.rs b/e2e/governance/src/generated/instructions/create_token_owner_record.rs new file mode 100644 index 0000000..25b7c74 --- /dev/null +++ b/e2e/governance/src/generated/instructions/create_token_owner_record.rs @@ -0,0 +1,488 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const CREATE_TOKEN_OWNER_RECORD_DISCRIMINATOR: u8 = 23; + +/// Accounts. +#[derive(Debug)] +pub struct CreateTokenOwnerRecord { + pub realm_account: solana_pubkey::Pubkey, + + pub governing_token_owner_account: solana_pubkey::Pubkey, + /// seeds=['governance', realm, governing_token_mint, governing_token_owner] + pub token_owner_record: solana_pubkey::Pubkey, + + pub governing_token_mint: solana_pubkey::Pubkey, + + pub payer: solana_pubkey::Pubkey, + + pub system_program: solana_pubkey::Pubkey, +} + +impl CreateTokenOwnerRecord { + pub fn instruction(&self) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(&[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(6 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governing_token_owner_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.token_owner_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governing_token_mint, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.payer, true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.system_program, + false, + )); + accounts.extend_from_slice(remaining_accounts); + let data = CreateTokenOwnerRecordInstructionData::new() + .try_to_vec() + .unwrap(); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CreateTokenOwnerRecordInstructionData { + discriminator: u8, +} + +impl CreateTokenOwnerRecordInstructionData { + pub fn new() -> Self { + Self { discriminator: 23 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for CreateTokenOwnerRecordInstructionData { + fn default() -> Self { + Self::new() + } +} + +/// Instruction builder for `CreateTokenOwnerRecord`. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[]` governing_token_owner_account +/// 2. `[writable]` token_owner_record +/// 3. `[]` governing_token_mint +/// 4. `[signer]` payer +/// 5. `[optional]` system_program (default to `11111111111111111111111111111111`) +#[derive(Clone, Debug, Default)] +pub struct CreateTokenOwnerRecordBuilder { + realm_account: Option, + governing_token_owner_account: Option, + token_owner_record: Option, + governing_token_mint: Option, + payer: Option, + system_program: Option, + __remaining_accounts: Vec, +} + +impl CreateTokenOwnerRecordBuilder { + pub fn new() -> Self { + Self::default() + } + #[inline(always)] + pub fn realm_account(&mut self, realm_account: solana_pubkey::Pubkey) -> &mut Self { + self.realm_account = Some(realm_account); + self + } + #[inline(always)] + pub fn governing_token_owner_account( + &mut self, + governing_token_owner_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governing_token_owner_account = Some(governing_token_owner_account); + self + } + /// seeds=['governance', realm, governing_token_mint, governing_token_owner] + #[inline(always)] + pub fn token_owner_record(&mut self, token_owner_record: solana_pubkey::Pubkey) -> &mut Self { + self.token_owner_record = Some(token_owner_record); + self + } + #[inline(always)] + pub fn governing_token_mint( + &mut self, + governing_token_mint: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governing_token_mint = Some(governing_token_mint); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: solana_pubkey::Pubkey) -> &mut Self { + self.payer = Some(payer); + self + } + /// `[optional account, default to '11111111111111111111111111111111']` + #[inline(always)] + pub fn system_program(&mut self, system_program: solana_pubkey::Pubkey) -> &mut Self { + self.system_program = Some(system_program); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = CreateTokenOwnerRecord { + realm_account: self.realm_account.expect("realm_account is not set"), + governing_token_owner_account: self + .governing_token_owner_account + .expect("governing_token_owner_account is not set"), + token_owner_record: self + .token_owner_record + .expect("token_owner_record is not set"), + governing_token_mint: self + .governing_token_mint + .expect("governing_token_mint is not set"), + payer: self.payer.expect("payer is not set"), + system_program: self + .system_program + .unwrap_or(solana_pubkey::pubkey!("11111111111111111111111111111111")), + }; + + accounts.instruction_with_remaining_accounts(&self.__remaining_accounts) + } +} + +/// `create_token_owner_record` CPI accounts. +pub struct CreateTokenOwnerRecordCpiAccounts<'a, 'b> { + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + + pub governing_token_owner_account: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['governance', realm, governing_token_mint, governing_token_owner] + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + + pub governing_token_mint: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, +} + +/// `create_token_owner_record` CPI instruction. +pub struct CreateTokenOwnerRecordCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + + pub governing_token_owner_account: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['governance', realm, governing_token_mint, governing_token_owner] + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + + pub governing_token_mint: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, +} + +impl<'a, 'b> CreateTokenOwnerRecordCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: CreateTokenOwnerRecordCpiAccounts<'a, 'b>, + ) -> Self { + Self { + __program: program, + realm_account: accounts.realm_account, + governing_token_owner_account: accounts.governing_token_owner_account, + token_owner_record: accounts.token_owner_record, + governing_token_mint: accounts.governing_token_mint, + payer: accounts.payer, + system_program: accounts.system_program, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(6 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governing_token_owner_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.token_owner_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governing_token_mint.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.payer.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.system_program.key, + false, + )); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let data = CreateTokenOwnerRecordInstructionData::new() + .try_to_vec() + .unwrap(); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(7 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.realm_account.clone()); + account_infos.push(self.governing_token_owner_account.clone()); + account_infos.push(self.token_owner_record.clone()); + account_infos.push(self.governing_token_mint.clone()); + account_infos.push(self.payer.clone()); + account_infos.push(self.system_program.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `CreateTokenOwnerRecord` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[]` governing_token_owner_account +/// 2. `[writable]` token_owner_record +/// 3. `[]` governing_token_mint +/// 4. `[signer]` payer +/// 5. `[]` system_program +#[derive(Clone, Debug)] +pub struct CreateTokenOwnerRecordCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> CreateTokenOwnerRecordCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(CreateTokenOwnerRecordCpiBuilderInstruction { + __program: program, + realm_account: None, + governing_token_owner_account: None, + token_owner_record: None, + governing_token_mint: None, + payer: None, + system_program: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + #[inline(always)] + pub fn realm_account( + &mut self, + realm_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_account = Some(realm_account); + self + } + #[inline(always)] + pub fn governing_token_owner_account( + &mut self, + governing_token_owner_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governing_token_owner_account = Some(governing_token_owner_account); + self + } + /// seeds=['governance', realm, governing_token_mint, governing_token_owner] + #[inline(always)] + pub fn token_owner_record( + &mut self, + token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_owner_record = Some(token_owner_record); + self + } + #[inline(always)] + pub fn governing_token_mint( + &mut self, + governing_token_mint: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governing_token_mint = Some(governing_token_mint); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: &'b solana_account_info::AccountInfo<'a>) -> &mut Self { + self.instruction.payer = Some(payer); + self + } + #[inline(always)] + pub fn system_program( + &mut self, + system_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.system_program = Some(system_program); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let instruction = CreateTokenOwnerRecordCpi { + __program: self.instruction.__program, + + realm_account: self + .instruction + .realm_account + .expect("realm_account is not set"), + + governing_token_owner_account: self + .instruction + .governing_token_owner_account + .expect("governing_token_owner_account is not set"), + + token_owner_record: self + .instruction + .token_owner_record + .expect("token_owner_record is not set"), + + governing_token_mint: self + .instruction + .governing_token_mint + .expect("governing_token_mint is not set"), + + payer: self.instruction.payer.expect("payer is not set"), + + system_program: self + .instruction + .system_program + .expect("system_program is not set"), + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct CreateTokenOwnerRecordCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + realm_account: Option<&'b solana_account_info::AccountInfo<'a>>, + governing_token_owner_account: Option<&'b solana_account_info::AccountInfo<'a>>, + token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + governing_token_mint: Option<&'b solana_account_info::AccountInfo<'a>>, + payer: Option<&'b solana_account_info::AccountInfo<'a>>, + system_program: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/deposit_governing_tokens.rs b/e2e/governance/src/generated/instructions/deposit_governing_tokens.rs new file mode 100644 index 0000000..a4390ae --- /dev/null +++ b/e2e/governance/src/generated/instructions/deposit_governing_tokens.rs @@ -0,0 +1,716 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const DEPOSIT_GOVERNING_TOKENS_DISCRIMINATOR: u8 = 1; + +/// Accounts. +#[derive(Debug)] +pub struct DepositGoverningTokens { + pub realm_account: solana_pubkey::Pubkey, + /// seeds=['governance', realm, governing_token_mint] + pub governing_token_holding_account: solana_pubkey::Pubkey, + /// It can either be spl-token TokenAccount or MintAccount. Tokens will be transferred or minted to the holding account + pub governing_token_source_account: solana_pubkey::Pubkey, + + pub governing_token_owner_account: solana_pubkey::Pubkey, + /// It should be owner for TokenAccount and mint_authority for MintAccount + pub governing_token_source_account_authority: solana_pubkey::Pubkey, + /// seeds=['governance', realm, governing_token_mint, governing_token_owner] + pub token_owner_record: solana_pubkey::Pubkey, + + pub payer: solana_pubkey::Pubkey, + + pub system_program: solana_pubkey::Pubkey, + + pub token_program: solana_pubkey::Pubkey, + /// seeds=['realm-config', realm] + pub realm_config_account: solana_pubkey::Pubkey, +} + +impl DepositGoverningTokens { + pub fn instruction( + &self, + args: DepositGoverningTokensInstructionArgs, + ) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(args, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + args: DepositGoverningTokensInstructionArgs, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(10 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.governing_token_holding_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.governing_token_source_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governing_token_owner_account, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governing_token_source_account_authority, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.token_owner_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new(self.payer, true)); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.system_program, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.token_program, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_config_account, + false, + )); + accounts.extend_from_slice(remaining_accounts); + let mut data = DepositGoverningTokensInstructionData::new() + .try_to_vec() + .unwrap(); + let mut args = args.try_to_vec().unwrap(); + data.append(&mut args); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct DepositGoverningTokensInstructionData { + discriminator: u8, +} + +impl DepositGoverningTokensInstructionData { + pub fn new() -> Self { + Self { discriminator: 1 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for DepositGoverningTokensInstructionData { + fn default() -> Self { + Self::new() + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct DepositGoverningTokensInstructionArgs { + pub amount: u64, +} + +impl DepositGoverningTokensInstructionArgs { + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +/// Instruction builder for `DepositGoverningTokens`. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[writable]` governing_token_holding_account +/// 2. `[writable]` governing_token_source_account +/// 3. `[signer]` governing_token_owner_account +/// 4. `[signer]` governing_token_source_account_authority +/// 5. `[writable]` token_owner_record +/// 6. `[writable, signer]` payer +/// 7. `[optional]` system_program (default to `11111111111111111111111111111111`) +/// 8. `[optional]` token_program (default to `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`) +/// 9. `[]` realm_config_account +#[derive(Clone, Debug, Default)] +pub struct DepositGoverningTokensBuilder { + realm_account: Option, + governing_token_holding_account: Option, + governing_token_source_account: Option, + governing_token_owner_account: Option, + governing_token_source_account_authority: Option, + token_owner_record: Option, + payer: Option, + system_program: Option, + token_program: Option, + realm_config_account: Option, + amount: Option, + __remaining_accounts: Vec, +} + +impl DepositGoverningTokensBuilder { + pub fn new() -> Self { + Self::default() + } + #[inline(always)] + pub fn realm_account(&mut self, realm_account: solana_pubkey::Pubkey) -> &mut Self { + self.realm_account = Some(realm_account); + self + } + /// seeds=['governance', realm, governing_token_mint] + #[inline(always)] + pub fn governing_token_holding_account( + &mut self, + governing_token_holding_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governing_token_holding_account = Some(governing_token_holding_account); + self + } + /// It can either be spl-token TokenAccount or MintAccount. Tokens will be transferred or minted to the holding account + #[inline(always)] + pub fn governing_token_source_account( + &mut self, + governing_token_source_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governing_token_source_account = Some(governing_token_source_account); + self + } + #[inline(always)] + pub fn governing_token_owner_account( + &mut self, + governing_token_owner_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governing_token_owner_account = Some(governing_token_owner_account); + self + } + /// It should be owner for TokenAccount and mint_authority for MintAccount + #[inline(always)] + pub fn governing_token_source_account_authority( + &mut self, + governing_token_source_account_authority: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governing_token_source_account_authority = + Some(governing_token_source_account_authority); + self + } + /// seeds=['governance', realm, governing_token_mint, governing_token_owner] + #[inline(always)] + pub fn token_owner_record(&mut self, token_owner_record: solana_pubkey::Pubkey) -> &mut Self { + self.token_owner_record = Some(token_owner_record); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: solana_pubkey::Pubkey) -> &mut Self { + self.payer = Some(payer); + self + } + /// `[optional account, default to '11111111111111111111111111111111']` + #[inline(always)] + pub fn system_program(&mut self, system_program: solana_pubkey::Pubkey) -> &mut Self { + self.system_program = Some(system_program); + self + } + /// `[optional account, default to 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA']` + #[inline(always)] + pub fn token_program(&mut self, token_program: solana_pubkey::Pubkey) -> &mut Self { + self.token_program = Some(token_program); + self + } + /// seeds=['realm-config', realm] + #[inline(always)] + pub fn realm_config_account( + &mut self, + realm_config_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.realm_config_account = Some(realm_config_account); + self + } + #[inline(always)] + pub fn amount(&mut self, amount: u64) -> &mut Self { + self.amount = Some(amount); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = DepositGoverningTokens { + realm_account: self.realm_account.expect("realm_account is not set"), + governing_token_holding_account: self + .governing_token_holding_account + .expect("governing_token_holding_account is not set"), + governing_token_source_account: self + .governing_token_source_account + .expect("governing_token_source_account is not set"), + governing_token_owner_account: self + .governing_token_owner_account + .expect("governing_token_owner_account is not set"), + governing_token_source_account_authority: self + .governing_token_source_account_authority + .expect("governing_token_source_account_authority is not set"), + token_owner_record: self + .token_owner_record + .expect("token_owner_record is not set"), + payer: self.payer.expect("payer is not set"), + system_program: self + .system_program + .unwrap_or(solana_pubkey::pubkey!("11111111111111111111111111111111")), + token_program: self.token_program.unwrap_or(solana_pubkey::pubkey!( + "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + )), + realm_config_account: self + .realm_config_account + .expect("realm_config_account is not set"), + }; + let args = DepositGoverningTokensInstructionArgs { + amount: self.amount.clone().expect("amount is not set"), + }; + + accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) + } +} + +/// `deposit_governing_tokens` CPI accounts. +pub struct DepositGoverningTokensCpiAccounts<'a, 'b> { + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['governance', realm, governing_token_mint] + pub governing_token_holding_account: &'b solana_account_info::AccountInfo<'a>, + /// It can either be spl-token TokenAccount or MintAccount. Tokens will be transferred or minted to the holding account + pub governing_token_source_account: &'b solana_account_info::AccountInfo<'a>, + + pub governing_token_owner_account: &'b solana_account_info::AccountInfo<'a>, + /// It should be owner for TokenAccount and mint_authority for MintAccount + pub governing_token_source_account_authority: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['governance', realm, governing_token_mint, governing_token_owner] + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, + + pub token_program: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['realm-config', realm] + pub realm_config_account: &'b solana_account_info::AccountInfo<'a>, +} + +/// `deposit_governing_tokens` CPI instruction. +pub struct DepositGoverningTokensCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['governance', realm, governing_token_mint] + pub governing_token_holding_account: &'b solana_account_info::AccountInfo<'a>, + /// It can either be spl-token TokenAccount or MintAccount. Tokens will be transferred or minted to the holding account + pub governing_token_source_account: &'b solana_account_info::AccountInfo<'a>, + + pub governing_token_owner_account: &'b solana_account_info::AccountInfo<'a>, + /// It should be owner for TokenAccount and mint_authority for MintAccount + pub governing_token_source_account_authority: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['governance', realm, governing_token_mint, governing_token_owner] + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, + + pub token_program: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['realm-config', realm] + pub realm_config_account: &'b solana_account_info::AccountInfo<'a>, + /// The arguments for the instruction. + pub __args: DepositGoverningTokensInstructionArgs, +} + +impl<'a, 'b> DepositGoverningTokensCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: DepositGoverningTokensCpiAccounts<'a, 'b>, + args: DepositGoverningTokensInstructionArgs, + ) -> Self { + Self { + __program: program, + realm_account: accounts.realm_account, + governing_token_holding_account: accounts.governing_token_holding_account, + governing_token_source_account: accounts.governing_token_source_account, + governing_token_owner_account: accounts.governing_token_owner_account, + governing_token_source_account_authority: accounts + .governing_token_source_account_authority, + token_owner_record: accounts.token_owner_record, + payer: accounts.payer, + system_program: accounts.system_program, + token_program: accounts.token_program, + realm_config_account: accounts.realm_config_account, + __args: args, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(10 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.governing_token_holding_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.governing_token_source_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governing_token_owner_account.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governing_token_source_account_authority.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.token_owner_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new(*self.payer.key, true)); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.system_program.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.token_program.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_config_account.key, + false, + )); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let mut data = DepositGoverningTokensInstructionData::new() + .try_to_vec() + .unwrap(); + let mut args = self.__args.try_to_vec().unwrap(); + data.append(&mut args); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(11 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.realm_account.clone()); + account_infos.push(self.governing_token_holding_account.clone()); + account_infos.push(self.governing_token_source_account.clone()); + account_infos.push(self.governing_token_owner_account.clone()); + account_infos.push(self.governing_token_source_account_authority.clone()); + account_infos.push(self.token_owner_record.clone()); + account_infos.push(self.payer.clone()); + account_infos.push(self.system_program.clone()); + account_infos.push(self.token_program.clone()); + account_infos.push(self.realm_config_account.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `DepositGoverningTokens` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[writable]` governing_token_holding_account +/// 2. `[writable]` governing_token_source_account +/// 3. `[signer]` governing_token_owner_account +/// 4. `[signer]` governing_token_source_account_authority +/// 5. `[writable]` token_owner_record +/// 6. `[writable, signer]` payer +/// 7. `[]` system_program +/// 8. `[]` token_program +/// 9. `[]` realm_config_account +#[derive(Clone, Debug)] +pub struct DepositGoverningTokensCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> DepositGoverningTokensCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(DepositGoverningTokensCpiBuilderInstruction { + __program: program, + realm_account: None, + governing_token_holding_account: None, + governing_token_source_account: None, + governing_token_owner_account: None, + governing_token_source_account_authority: None, + token_owner_record: None, + payer: None, + system_program: None, + token_program: None, + realm_config_account: None, + amount: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + #[inline(always)] + pub fn realm_account( + &mut self, + realm_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_account = Some(realm_account); + self + } + /// seeds=['governance', realm, governing_token_mint] + #[inline(always)] + pub fn governing_token_holding_account( + &mut self, + governing_token_holding_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governing_token_holding_account = Some(governing_token_holding_account); + self + } + /// It can either be spl-token TokenAccount or MintAccount. Tokens will be transferred or minted to the holding account + #[inline(always)] + pub fn governing_token_source_account( + &mut self, + governing_token_source_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governing_token_source_account = Some(governing_token_source_account); + self + } + #[inline(always)] + pub fn governing_token_owner_account( + &mut self, + governing_token_owner_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governing_token_owner_account = Some(governing_token_owner_account); + self + } + /// It should be owner for TokenAccount and mint_authority for MintAccount + #[inline(always)] + pub fn governing_token_source_account_authority( + &mut self, + governing_token_source_account_authority: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governing_token_source_account_authority = + Some(governing_token_source_account_authority); + self + } + /// seeds=['governance', realm, governing_token_mint, governing_token_owner] + #[inline(always)] + pub fn token_owner_record( + &mut self, + token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_owner_record = Some(token_owner_record); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: &'b solana_account_info::AccountInfo<'a>) -> &mut Self { + self.instruction.payer = Some(payer); + self + } + #[inline(always)] + pub fn system_program( + &mut self, + system_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.system_program = Some(system_program); + self + } + #[inline(always)] + pub fn token_program( + &mut self, + token_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_program = Some(token_program); + self + } + /// seeds=['realm-config', realm] + #[inline(always)] + pub fn realm_config_account( + &mut self, + realm_config_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_config_account = Some(realm_config_account); + self + } + #[inline(always)] + pub fn amount(&mut self, amount: u64) -> &mut Self { + self.instruction.amount = Some(amount); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let args = DepositGoverningTokensInstructionArgs { + amount: self.instruction.amount.clone().expect("amount is not set"), + }; + let instruction = DepositGoverningTokensCpi { + __program: self.instruction.__program, + + realm_account: self + .instruction + .realm_account + .expect("realm_account is not set"), + + governing_token_holding_account: self + .instruction + .governing_token_holding_account + .expect("governing_token_holding_account is not set"), + + governing_token_source_account: self + .instruction + .governing_token_source_account + .expect("governing_token_source_account is not set"), + + governing_token_owner_account: self + .instruction + .governing_token_owner_account + .expect("governing_token_owner_account is not set"), + + governing_token_source_account_authority: self + .instruction + .governing_token_source_account_authority + .expect("governing_token_source_account_authority is not set"), + + token_owner_record: self + .instruction + .token_owner_record + .expect("token_owner_record is not set"), + + payer: self.instruction.payer.expect("payer is not set"), + + system_program: self + .instruction + .system_program + .expect("system_program is not set"), + + token_program: self + .instruction + .token_program + .expect("token_program is not set"), + + realm_config_account: self + .instruction + .realm_config_account + .expect("realm_config_account is not set"), + __args: args, + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct DepositGoverningTokensCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + realm_account: Option<&'b solana_account_info::AccountInfo<'a>>, + governing_token_holding_account: Option<&'b solana_account_info::AccountInfo<'a>>, + governing_token_source_account: Option<&'b solana_account_info::AccountInfo<'a>>, + governing_token_owner_account: Option<&'b solana_account_info::AccountInfo<'a>>, + governing_token_source_account_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + payer: Option<&'b solana_account_info::AccountInfo<'a>>, + system_program: Option<&'b solana_account_info::AccountInfo<'a>>, + token_program: Option<&'b solana_account_info::AccountInfo<'a>>, + realm_config_account: Option<&'b solana_account_info::AccountInfo<'a>>, + amount: Option, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/execute_transaction.rs b/e2e/governance/src/generated/instructions/execute_transaction.rs new file mode 100644 index 0000000..a26c75c --- /dev/null +++ b/e2e/governance/src/generated/instructions/execute_transaction.rs @@ -0,0 +1,365 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const EXECUTE_TRANSACTION_DISCRIMINATOR: u8 = 16; + +/// Accounts. +#[derive(Debug)] +pub struct ExecuteTransaction { + pub governance_account: solana_pubkey::Pubkey, + + pub proposal_account: solana_pubkey::Pubkey, + + pub proposal_transaction_account: solana_pubkey::Pubkey, +} + +impl ExecuteTransaction { + pub fn instruction(&self) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(&[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(3 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governance_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_transaction_account, + false, + )); + accounts.extend_from_slice(remaining_accounts); + let data = ExecuteTransactionInstructionData::new() + .try_to_vec() + .unwrap(); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ExecuteTransactionInstructionData { + discriminator: u8, +} + +impl ExecuteTransactionInstructionData { + pub fn new() -> Self { + Self { discriminator: 16 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for ExecuteTransactionInstructionData { + fn default() -> Self { + Self::new() + } +} + +/// Instruction builder for `ExecuteTransaction`. +/// +/// ### Accounts: +/// +/// 0. `[]` governance_account +/// 1. `[writable]` proposal_account +/// 2. `[writable]` proposal_transaction_account +#[derive(Clone, Debug, Default)] +pub struct ExecuteTransactionBuilder { + governance_account: Option, + proposal_account: Option, + proposal_transaction_account: Option, + __remaining_accounts: Vec, +} + +impl ExecuteTransactionBuilder { + pub fn new() -> Self { + Self::default() + } + #[inline(always)] + pub fn governance_account(&mut self, governance_account: solana_pubkey::Pubkey) -> &mut Self { + self.governance_account = Some(governance_account); + self + } + #[inline(always)] + pub fn proposal_account(&mut self, proposal_account: solana_pubkey::Pubkey) -> &mut Self { + self.proposal_account = Some(proposal_account); + self + } + #[inline(always)] + pub fn proposal_transaction_account( + &mut self, + proposal_transaction_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.proposal_transaction_account = Some(proposal_transaction_account); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = ExecuteTransaction { + governance_account: self + .governance_account + .expect("governance_account is not set"), + proposal_account: self.proposal_account.expect("proposal_account is not set"), + proposal_transaction_account: self + .proposal_transaction_account + .expect("proposal_transaction_account is not set"), + }; + + accounts.instruction_with_remaining_accounts(&self.__remaining_accounts) + } +} + +/// `execute_transaction` CPI accounts. +pub struct ExecuteTransactionCpiAccounts<'a, 'b> { + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_transaction_account: &'b solana_account_info::AccountInfo<'a>, +} + +/// `execute_transaction` CPI instruction. +pub struct ExecuteTransactionCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_transaction_account: &'b solana_account_info::AccountInfo<'a>, +} + +impl<'a, 'b> ExecuteTransactionCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: ExecuteTransactionCpiAccounts<'a, 'b>, + ) -> Self { + Self { + __program: program, + governance_account: accounts.governance_account, + proposal_account: accounts.proposal_account, + proposal_transaction_account: accounts.proposal_transaction_account, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(3 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governance_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_transaction_account.key, + false, + )); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let data = ExecuteTransactionInstructionData::new() + .try_to_vec() + .unwrap(); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(4 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.governance_account.clone()); + account_infos.push(self.proposal_account.clone()); + account_infos.push(self.proposal_transaction_account.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `ExecuteTransaction` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[]` governance_account +/// 1. `[writable]` proposal_account +/// 2. `[writable]` proposal_transaction_account +#[derive(Clone, Debug)] +pub struct ExecuteTransactionCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> ExecuteTransactionCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(ExecuteTransactionCpiBuilderInstruction { + __program: program, + governance_account: None, + proposal_account: None, + proposal_transaction_account: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + #[inline(always)] + pub fn governance_account( + &mut self, + governance_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_account = Some(governance_account); + self + } + #[inline(always)] + pub fn proposal_account( + &mut self, + proposal_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_account = Some(proposal_account); + self + } + #[inline(always)] + pub fn proposal_transaction_account( + &mut self, + proposal_transaction_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_transaction_account = Some(proposal_transaction_account); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let instruction = ExecuteTransactionCpi { + __program: self.instruction.__program, + + governance_account: self + .instruction + .governance_account + .expect("governance_account is not set"), + + proposal_account: self + .instruction + .proposal_account + .expect("proposal_account is not set"), + + proposal_transaction_account: self + .instruction + .proposal_transaction_account + .expect("proposal_transaction_account is not set"), + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct ExecuteTransactionCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + governance_account: Option<&'b solana_account_info::AccountInfo<'a>>, + proposal_account: Option<&'b solana_account_info::AccountInfo<'a>>, + proposal_transaction_account: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/finalize_vote.rs b/e2e/governance/src/generated/instructions/finalize_vote.rs new file mode 100644 index 0000000..cb800b2 --- /dev/null +++ b/e2e/governance/src/generated/instructions/finalize_vote.rs @@ -0,0 +1,547 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const FINALIZE_VOTE_DISCRIMINATOR: u8 = 14; + +/// Accounts. +#[derive(Debug)] +pub struct FinalizeVote { + pub realm_account: solana_pubkey::Pubkey, + + pub governance_account: solana_pubkey::Pubkey, + + pub proposal_account: solana_pubkey::Pubkey, + /// TokenOwnerRecord of the Proposal owner + pub token_owner_record: solana_pubkey::Pubkey, + + pub governing_token_mint: solana_pubkey::Pubkey, + /// RealmConfig account. PDA seeds: ['realm-config', realm] + pub realm_config: solana_pubkey::Pubkey, + /// Optional Max Voter Weight Record + pub max_voter_weight_record: Option, +} + +impl FinalizeVote { + pub fn instruction(&self) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(&[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(7 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.governance_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.token_owner_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governing_token_mint, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_config, + false, + )); + if let Some(max_voter_weight_record) = self.max_voter_weight_record { + accounts.push(solana_instruction::AccountMeta::new_readonly( + max_voter_weight_record, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + accounts.extend_from_slice(remaining_accounts); + let data = FinalizeVoteInstructionData::new().try_to_vec().unwrap(); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct FinalizeVoteInstructionData { + discriminator: u8, +} + +impl FinalizeVoteInstructionData { + pub fn new() -> Self { + Self { discriminator: 14 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for FinalizeVoteInstructionData { + fn default() -> Self { + Self::new() + } +} + +/// Instruction builder for `FinalizeVote`. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[writable]` governance_account +/// 2. `[writable]` proposal_account +/// 3. `[writable]` token_owner_record +/// 4. `[]` governing_token_mint +/// 5. `[]` realm_config +/// 6. `[optional]` max_voter_weight_record +#[derive(Clone, Debug, Default)] +pub struct FinalizeVoteBuilder { + realm_account: Option, + governance_account: Option, + proposal_account: Option, + token_owner_record: Option, + governing_token_mint: Option, + realm_config: Option, + max_voter_weight_record: Option, + __remaining_accounts: Vec, +} + +impl FinalizeVoteBuilder { + pub fn new() -> Self { + Self::default() + } + #[inline(always)] + pub fn realm_account(&mut self, realm_account: solana_pubkey::Pubkey) -> &mut Self { + self.realm_account = Some(realm_account); + self + } + #[inline(always)] + pub fn governance_account(&mut self, governance_account: solana_pubkey::Pubkey) -> &mut Self { + self.governance_account = Some(governance_account); + self + } + #[inline(always)] + pub fn proposal_account(&mut self, proposal_account: solana_pubkey::Pubkey) -> &mut Self { + self.proposal_account = Some(proposal_account); + self + } + /// TokenOwnerRecord of the Proposal owner + #[inline(always)] + pub fn token_owner_record(&mut self, token_owner_record: solana_pubkey::Pubkey) -> &mut Self { + self.token_owner_record = Some(token_owner_record); + self + } + #[inline(always)] + pub fn governing_token_mint( + &mut self, + governing_token_mint: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governing_token_mint = Some(governing_token_mint); + self + } + /// RealmConfig account. PDA seeds: ['realm-config', realm] + #[inline(always)] + pub fn realm_config(&mut self, realm_config: solana_pubkey::Pubkey) -> &mut Self { + self.realm_config = Some(realm_config); + self + } + /// `[optional account]` + /// Optional Max Voter Weight Record + #[inline(always)] + pub fn max_voter_weight_record( + &mut self, + max_voter_weight_record: Option, + ) -> &mut Self { + self.max_voter_weight_record = max_voter_weight_record; + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = FinalizeVote { + realm_account: self.realm_account.expect("realm_account is not set"), + governance_account: self + .governance_account + .expect("governance_account is not set"), + proposal_account: self.proposal_account.expect("proposal_account is not set"), + token_owner_record: self + .token_owner_record + .expect("token_owner_record is not set"), + governing_token_mint: self + .governing_token_mint + .expect("governing_token_mint is not set"), + realm_config: self.realm_config.expect("realm_config is not set"), + max_voter_weight_record: self.max_voter_weight_record, + }; + + accounts.instruction_with_remaining_accounts(&self.__remaining_accounts) + } +} + +/// `finalize_vote` CPI accounts. +pub struct FinalizeVoteCpiAccounts<'a, 'b> { + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord of the Proposal owner + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + + pub governing_token_mint: &'b solana_account_info::AccountInfo<'a>, + /// RealmConfig account. PDA seeds: ['realm-config', realm] + pub realm_config: &'b solana_account_info::AccountInfo<'a>, + /// Optional Max Voter Weight Record + pub max_voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, +} + +/// `finalize_vote` CPI instruction. +pub struct FinalizeVoteCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord of the Proposal owner + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + + pub governing_token_mint: &'b solana_account_info::AccountInfo<'a>, + /// RealmConfig account. PDA seeds: ['realm-config', realm] + pub realm_config: &'b solana_account_info::AccountInfo<'a>, + /// Optional Max Voter Weight Record + pub max_voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, +} + +impl<'a, 'b> FinalizeVoteCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: FinalizeVoteCpiAccounts<'a, 'b>, + ) -> Self { + Self { + __program: program, + realm_account: accounts.realm_account, + governance_account: accounts.governance_account, + proposal_account: accounts.proposal_account, + token_owner_record: accounts.token_owner_record, + governing_token_mint: accounts.governing_token_mint, + realm_config: accounts.realm_config, + max_voter_weight_record: accounts.max_voter_weight_record, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(7 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.governance_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.token_owner_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governing_token_mint.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_config.key, + false, + )); + if let Some(max_voter_weight_record) = self.max_voter_weight_record { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *max_voter_weight_record.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let data = FinalizeVoteInstructionData::new().try_to_vec().unwrap(); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(8 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.realm_account.clone()); + account_infos.push(self.governance_account.clone()); + account_infos.push(self.proposal_account.clone()); + account_infos.push(self.token_owner_record.clone()); + account_infos.push(self.governing_token_mint.clone()); + account_infos.push(self.realm_config.clone()); + if let Some(max_voter_weight_record) = self.max_voter_weight_record { + account_infos.push(max_voter_weight_record.clone()); + } + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `FinalizeVote` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[writable]` governance_account +/// 2. `[writable]` proposal_account +/// 3. `[writable]` token_owner_record +/// 4. `[]` governing_token_mint +/// 5. `[]` realm_config +/// 6. `[optional]` max_voter_weight_record +#[derive(Clone, Debug)] +pub struct FinalizeVoteCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> FinalizeVoteCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(FinalizeVoteCpiBuilderInstruction { + __program: program, + realm_account: None, + governance_account: None, + proposal_account: None, + token_owner_record: None, + governing_token_mint: None, + realm_config: None, + max_voter_weight_record: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + #[inline(always)] + pub fn realm_account( + &mut self, + realm_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_account = Some(realm_account); + self + } + #[inline(always)] + pub fn governance_account( + &mut self, + governance_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_account = Some(governance_account); + self + } + #[inline(always)] + pub fn proposal_account( + &mut self, + proposal_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_account = Some(proposal_account); + self + } + /// TokenOwnerRecord of the Proposal owner + #[inline(always)] + pub fn token_owner_record( + &mut self, + token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_owner_record = Some(token_owner_record); + self + } + #[inline(always)] + pub fn governing_token_mint( + &mut self, + governing_token_mint: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governing_token_mint = Some(governing_token_mint); + self + } + /// RealmConfig account. PDA seeds: ['realm-config', realm] + #[inline(always)] + pub fn realm_config( + &mut self, + realm_config: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_config = Some(realm_config); + self + } + /// `[optional account]` + /// Optional Max Voter Weight Record + #[inline(always)] + pub fn max_voter_weight_record( + &mut self, + max_voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.max_voter_weight_record = max_voter_weight_record; + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let instruction = FinalizeVoteCpi { + __program: self.instruction.__program, + + realm_account: self + .instruction + .realm_account + .expect("realm_account is not set"), + + governance_account: self + .instruction + .governance_account + .expect("governance_account is not set"), + + proposal_account: self + .instruction + .proposal_account + .expect("proposal_account is not set"), + + token_owner_record: self + .instruction + .token_owner_record + .expect("token_owner_record is not set"), + + governing_token_mint: self + .instruction + .governing_token_mint + .expect("governing_token_mint is not set"), + + realm_config: self + .instruction + .realm_config + .expect("realm_config is not set"), + + max_voter_weight_record: self.instruction.max_voter_weight_record, + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct FinalizeVoteCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + realm_account: Option<&'b solana_account_info::AccountInfo<'a>>, + governance_account: Option<&'b solana_account_info::AccountInfo<'a>>, + proposal_account: Option<&'b solana_account_info::AccountInfo<'a>>, + token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + governing_token_mint: Option<&'b solana_account_info::AccountInfo<'a>>, + realm_config: Option<&'b solana_account_info::AccountInfo<'a>>, + max_voter_weight_record: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/flag_transaction_error.rs b/e2e/governance/src/generated/instructions/flag_transaction_error.rs new file mode 100644 index 0000000..3549368 --- /dev/null +++ b/e2e/governance/src/generated/instructions/flag_transaction_error.rs @@ -0,0 +1,416 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const FLAG_TRANSACTION_ERROR_DISCRIMINATOR: u8 = 20; + +/// Accounts. +#[derive(Debug)] +pub struct FlagTransactionError { + pub proposal_account: solana_pubkey::Pubkey, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: solana_pubkey::Pubkey, + /// Governance Authority (Token Owner or Governance Delegate) + pub governance_authority: solana_pubkey::Pubkey, + /// ProposalTransaction account to flag + pub proposal_transaction_account: solana_pubkey::Pubkey, +} + +impl FlagTransactionError { + pub fn instruction(&self) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(&[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(4 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.token_owner_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governance_authority, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_transaction_account, + false, + )); + accounts.extend_from_slice(remaining_accounts); + let data = FlagTransactionErrorInstructionData::new() + .try_to_vec() + .unwrap(); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct FlagTransactionErrorInstructionData { + discriminator: u8, +} + +impl FlagTransactionErrorInstructionData { + pub fn new() -> Self { + Self { discriminator: 20 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for FlagTransactionErrorInstructionData { + fn default() -> Self { + Self::new() + } +} + +/// Instruction builder for `FlagTransactionError`. +/// +/// ### Accounts: +/// +/// 0. `[writable]` proposal_account +/// 1. `[]` token_owner_record +/// 2. `[signer]` governance_authority +/// 3. `[writable]` proposal_transaction_account +#[derive(Clone, Debug, Default)] +pub struct FlagTransactionErrorBuilder { + proposal_account: Option, + token_owner_record: Option, + governance_authority: Option, + proposal_transaction_account: Option, + __remaining_accounts: Vec, +} + +impl FlagTransactionErrorBuilder { + pub fn new() -> Self { + Self::default() + } + #[inline(always)] + pub fn proposal_account(&mut self, proposal_account: solana_pubkey::Pubkey) -> &mut Self { + self.proposal_account = Some(proposal_account); + self + } + /// TokenOwnerRecord account of the Proposal owner + #[inline(always)] + pub fn token_owner_record(&mut self, token_owner_record: solana_pubkey::Pubkey) -> &mut Self { + self.token_owner_record = Some(token_owner_record); + self + } + /// Governance Authority (Token Owner or Governance Delegate) + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governance_authority = Some(governance_authority); + self + } + /// ProposalTransaction account to flag + #[inline(always)] + pub fn proposal_transaction_account( + &mut self, + proposal_transaction_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.proposal_transaction_account = Some(proposal_transaction_account); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = FlagTransactionError { + proposal_account: self.proposal_account.expect("proposal_account is not set"), + token_owner_record: self + .token_owner_record + .expect("token_owner_record is not set"), + governance_authority: self + .governance_authority + .expect("governance_authority is not set"), + proposal_transaction_account: self + .proposal_transaction_account + .expect("proposal_transaction_account is not set"), + }; + + accounts.instruction_with_remaining_accounts(&self.__remaining_accounts) + } +} + +/// `flag_transaction_error` CPI accounts. +pub struct FlagTransactionErrorCpiAccounts<'a, 'b> { + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// Governance Authority (Token Owner or Governance Delegate) + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, + /// ProposalTransaction account to flag + pub proposal_transaction_account: &'b solana_account_info::AccountInfo<'a>, +} + +/// `flag_transaction_error` CPI instruction. +pub struct FlagTransactionErrorCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// Governance Authority (Token Owner or Governance Delegate) + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, + /// ProposalTransaction account to flag + pub proposal_transaction_account: &'b solana_account_info::AccountInfo<'a>, +} + +impl<'a, 'b> FlagTransactionErrorCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: FlagTransactionErrorCpiAccounts<'a, 'b>, + ) -> Self { + Self { + __program: program, + proposal_account: accounts.proposal_account, + token_owner_record: accounts.token_owner_record, + governance_authority: accounts.governance_authority, + proposal_transaction_account: accounts.proposal_transaction_account, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(4 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.token_owner_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governance_authority.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_transaction_account.key, + false, + )); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let data = FlagTransactionErrorInstructionData::new() + .try_to_vec() + .unwrap(); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(5 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.proposal_account.clone()); + account_infos.push(self.token_owner_record.clone()); + account_infos.push(self.governance_authority.clone()); + account_infos.push(self.proposal_transaction_account.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `FlagTransactionError` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[writable]` proposal_account +/// 1. `[]` token_owner_record +/// 2. `[signer]` governance_authority +/// 3. `[writable]` proposal_transaction_account +#[derive(Clone, Debug)] +pub struct FlagTransactionErrorCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> FlagTransactionErrorCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(FlagTransactionErrorCpiBuilderInstruction { + __program: program, + proposal_account: None, + token_owner_record: None, + governance_authority: None, + proposal_transaction_account: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + #[inline(always)] + pub fn proposal_account( + &mut self, + proposal_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_account = Some(proposal_account); + self + } + /// TokenOwnerRecord account of the Proposal owner + #[inline(always)] + pub fn token_owner_record( + &mut self, + token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_owner_record = Some(token_owner_record); + self + } + /// Governance Authority (Token Owner or Governance Delegate) + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_authority = Some(governance_authority); + self + } + /// ProposalTransaction account to flag + #[inline(always)] + pub fn proposal_transaction_account( + &mut self, + proposal_transaction_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_transaction_account = Some(proposal_transaction_account); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let instruction = FlagTransactionErrorCpi { + __program: self.instruction.__program, + + proposal_account: self + .instruction + .proposal_account + .expect("proposal_account is not set"), + + token_owner_record: self + .instruction + .token_owner_record + .expect("token_owner_record is not set"), + + governance_authority: self + .instruction + .governance_authority + .expect("governance_authority is not set"), + + proposal_transaction_account: self + .instruction + .proposal_transaction_account + .expect("proposal_transaction_account is not set"), + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct FlagTransactionErrorCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + proposal_account: Option<&'b solana_account_info::AccountInfo<'a>>, + token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + governance_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + proposal_transaction_account: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/insert_transaction.rs b/e2e/governance/src/generated/instructions/insert_transaction.rs new file mode 100644 index 0000000..e670906 --- /dev/null +++ b/e2e/governance/src/generated/instructions/insert_transaction.rs @@ -0,0 +1,675 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::InstructionData; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const INSERT_TRANSACTION_DISCRIMINATOR: u8 = 9; + +/// Accounts. +#[derive(Debug)] +pub struct InsertTransaction { + pub governance_account: solana_pubkey::Pubkey, + + pub proposal_account: solana_pubkey::Pubkey, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: solana_pubkey::Pubkey, + /// Governance Authority (Token Owner or Governance Delegate) + pub governance_authority: solana_pubkey::Pubkey, + /// ProposalTransaction, account. PDA seeds: ['governance', proposal, option_index, index] + pub proposal_transaction_account: solana_pubkey::Pubkey, + + pub payer: solana_pubkey::Pubkey, + + pub system_program: solana_pubkey::Pubkey, + + pub rent: solana_pubkey::Pubkey, +} + +impl InsertTransaction { + pub fn instruction( + &self, + args: InsertTransactionInstructionArgs, + ) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(args, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + args: InsertTransactionInstructionArgs, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(8 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governance_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.token_owner_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governance_authority, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_transaction_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.payer, true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.system_program, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.rent, false, + )); + accounts.extend_from_slice(remaining_accounts); + let mut data = InsertTransactionInstructionData::new() + .try_to_vec() + .unwrap(); + let mut args = args.try_to_vec().unwrap(); + data.append(&mut args); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct InsertTransactionInstructionData { + discriminator: u8, +} + +impl InsertTransactionInstructionData { + pub fn new() -> Self { + Self { discriminator: 9 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for InsertTransactionInstructionData { + fn default() -> Self { + Self::new() + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct InsertTransactionInstructionArgs { + pub option_index: u8, + pub index: u16, + pub hold_up_time: u32, + pub instructions: Vec, +} + +impl InsertTransactionInstructionArgs { + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +/// Instruction builder for `InsertTransaction`. +/// +/// ### Accounts: +/// +/// 0. `[]` governance_account +/// 1. `[writable]` proposal_account +/// 2. `[]` token_owner_record +/// 3. `[signer]` governance_authority +/// 4. `[writable]` proposal_transaction_account +/// 5. `[signer]` payer +/// 6. `[optional]` system_program (default to `11111111111111111111111111111111`) +/// 7. `[optional]` rent (default to `SysvarRent111111111111111111111111111111111`) +#[derive(Clone, Debug, Default)] +pub struct InsertTransactionBuilder { + governance_account: Option, + proposal_account: Option, + token_owner_record: Option, + governance_authority: Option, + proposal_transaction_account: Option, + payer: Option, + system_program: Option, + rent: Option, + option_index: Option, + index: Option, + hold_up_time: Option, + instructions: Option>, + __remaining_accounts: Vec, +} + +impl InsertTransactionBuilder { + pub fn new() -> Self { + Self::default() + } + #[inline(always)] + pub fn governance_account(&mut self, governance_account: solana_pubkey::Pubkey) -> &mut Self { + self.governance_account = Some(governance_account); + self + } + #[inline(always)] + pub fn proposal_account(&mut self, proposal_account: solana_pubkey::Pubkey) -> &mut Self { + self.proposal_account = Some(proposal_account); + self + } + /// TokenOwnerRecord account of the Proposal owner + #[inline(always)] + pub fn token_owner_record(&mut self, token_owner_record: solana_pubkey::Pubkey) -> &mut Self { + self.token_owner_record = Some(token_owner_record); + self + } + /// Governance Authority (Token Owner or Governance Delegate) + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governance_authority = Some(governance_authority); + self + } + /// ProposalTransaction, account. PDA seeds: ['governance', proposal, option_index, index] + #[inline(always)] + pub fn proposal_transaction_account( + &mut self, + proposal_transaction_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.proposal_transaction_account = Some(proposal_transaction_account); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: solana_pubkey::Pubkey) -> &mut Self { + self.payer = Some(payer); + self + } + /// `[optional account, default to '11111111111111111111111111111111']` + #[inline(always)] + pub fn system_program(&mut self, system_program: solana_pubkey::Pubkey) -> &mut Self { + self.system_program = Some(system_program); + self + } + /// `[optional account, default to 'SysvarRent111111111111111111111111111111111']` + #[inline(always)] + pub fn rent(&mut self, rent: solana_pubkey::Pubkey) -> &mut Self { + self.rent = Some(rent); + self + } + #[inline(always)] + pub fn option_index(&mut self, option_index: u8) -> &mut Self { + self.option_index = Some(option_index); + self + } + #[inline(always)] + pub fn index(&mut self, index: u16) -> &mut Self { + self.index = Some(index); + self + } + #[inline(always)] + pub fn hold_up_time(&mut self, hold_up_time: u32) -> &mut Self { + self.hold_up_time = Some(hold_up_time); + self + } + #[inline(always)] + pub fn instructions(&mut self, instructions: Vec) -> &mut Self { + self.instructions = Some(instructions); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = InsertTransaction { + governance_account: self + .governance_account + .expect("governance_account is not set"), + proposal_account: self.proposal_account.expect("proposal_account is not set"), + token_owner_record: self + .token_owner_record + .expect("token_owner_record is not set"), + governance_authority: self + .governance_authority + .expect("governance_authority is not set"), + proposal_transaction_account: self + .proposal_transaction_account + .expect("proposal_transaction_account is not set"), + payer: self.payer.expect("payer is not set"), + system_program: self + .system_program + .unwrap_or(solana_pubkey::pubkey!("11111111111111111111111111111111")), + rent: self.rent.unwrap_or(solana_pubkey::pubkey!( + "SysvarRent111111111111111111111111111111111" + )), + }; + let args = InsertTransactionInstructionArgs { + option_index: self.option_index.clone().expect("option_index is not set"), + index: self.index.clone().expect("index is not set"), + hold_up_time: self.hold_up_time.clone().expect("hold_up_time is not set"), + instructions: self.instructions.clone().expect("instructions is not set"), + }; + + accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) + } +} + +/// `insert_transaction` CPI accounts. +pub struct InsertTransactionCpiAccounts<'a, 'b> { + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// Governance Authority (Token Owner or Governance Delegate) + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, + /// ProposalTransaction, account. PDA seeds: ['governance', proposal, option_index, index] + pub proposal_transaction_account: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, + + pub rent: &'b solana_account_info::AccountInfo<'a>, +} + +/// `insert_transaction` CPI instruction. +pub struct InsertTransactionCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// Governance Authority (Token Owner or Governance Delegate) + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, + /// ProposalTransaction, account. PDA seeds: ['governance', proposal, option_index, index] + pub proposal_transaction_account: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, + + pub rent: &'b solana_account_info::AccountInfo<'a>, + /// The arguments for the instruction. + pub __args: InsertTransactionInstructionArgs, +} + +impl<'a, 'b> InsertTransactionCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: InsertTransactionCpiAccounts<'a, 'b>, + args: InsertTransactionInstructionArgs, + ) -> Self { + Self { + __program: program, + governance_account: accounts.governance_account, + proposal_account: accounts.proposal_account, + token_owner_record: accounts.token_owner_record, + governance_authority: accounts.governance_authority, + proposal_transaction_account: accounts.proposal_transaction_account, + payer: accounts.payer, + system_program: accounts.system_program, + rent: accounts.rent, + __args: args, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(8 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governance_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.token_owner_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governance_authority.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_transaction_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.payer.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.system_program.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.rent.key, + false, + )); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let mut data = InsertTransactionInstructionData::new() + .try_to_vec() + .unwrap(); + let mut args = self.__args.try_to_vec().unwrap(); + data.append(&mut args); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(9 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.governance_account.clone()); + account_infos.push(self.proposal_account.clone()); + account_infos.push(self.token_owner_record.clone()); + account_infos.push(self.governance_authority.clone()); + account_infos.push(self.proposal_transaction_account.clone()); + account_infos.push(self.payer.clone()); + account_infos.push(self.system_program.clone()); + account_infos.push(self.rent.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `InsertTransaction` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[]` governance_account +/// 1. `[writable]` proposal_account +/// 2. `[]` token_owner_record +/// 3. `[signer]` governance_authority +/// 4. `[writable]` proposal_transaction_account +/// 5. `[signer]` payer +/// 6. `[]` system_program +/// 7. `[]` rent +#[derive(Clone, Debug)] +pub struct InsertTransactionCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> InsertTransactionCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(InsertTransactionCpiBuilderInstruction { + __program: program, + governance_account: None, + proposal_account: None, + token_owner_record: None, + governance_authority: None, + proposal_transaction_account: None, + payer: None, + system_program: None, + rent: None, + option_index: None, + index: None, + hold_up_time: None, + instructions: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + #[inline(always)] + pub fn governance_account( + &mut self, + governance_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_account = Some(governance_account); + self + } + #[inline(always)] + pub fn proposal_account( + &mut self, + proposal_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_account = Some(proposal_account); + self + } + /// TokenOwnerRecord account of the Proposal owner + #[inline(always)] + pub fn token_owner_record( + &mut self, + token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_owner_record = Some(token_owner_record); + self + } + /// Governance Authority (Token Owner or Governance Delegate) + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_authority = Some(governance_authority); + self + } + /// ProposalTransaction, account. PDA seeds: ['governance', proposal, option_index, index] + #[inline(always)] + pub fn proposal_transaction_account( + &mut self, + proposal_transaction_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_transaction_account = Some(proposal_transaction_account); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: &'b solana_account_info::AccountInfo<'a>) -> &mut Self { + self.instruction.payer = Some(payer); + self + } + #[inline(always)] + pub fn system_program( + &mut self, + system_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.system_program = Some(system_program); + self + } + #[inline(always)] + pub fn rent(&mut self, rent: &'b solana_account_info::AccountInfo<'a>) -> &mut Self { + self.instruction.rent = Some(rent); + self + } + #[inline(always)] + pub fn option_index(&mut self, option_index: u8) -> &mut Self { + self.instruction.option_index = Some(option_index); + self + } + #[inline(always)] + pub fn index(&mut self, index: u16) -> &mut Self { + self.instruction.index = Some(index); + self + } + #[inline(always)] + pub fn hold_up_time(&mut self, hold_up_time: u32) -> &mut Self { + self.instruction.hold_up_time = Some(hold_up_time); + self + } + #[inline(always)] + pub fn instructions(&mut self, instructions: Vec) -> &mut Self { + self.instruction.instructions = Some(instructions); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let args = InsertTransactionInstructionArgs { + option_index: self + .instruction + .option_index + .clone() + .expect("option_index is not set"), + index: self.instruction.index.clone().expect("index is not set"), + hold_up_time: self + .instruction + .hold_up_time + .clone() + .expect("hold_up_time is not set"), + instructions: self + .instruction + .instructions + .clone() + .expect("instructions is not set"), + }; + let instruction = InsertTransactionCpi { + __program: self.instruction.__program, + + governance_account: self + .instruction + .governance_account + .expect("governance_account is not set"), + + proposal_account: self + .instruction + .proposal_account + .expect("proposal_account is not set"), + + token_owner_record: self + .instruction + .token_owner_record + .expect("token_owner_record is not set"), + + governance_authority: self + .instruction + .governance_authority + .expect("governance_authority is not set"), + + proposal_transaction_account: self + .instruction + .proposal_transaction_account + .expect("proposal_transaction_account is not set"), + + payer: self.instruction.payer.expect("payer is not set"), + + system_program: self + .instruction + .system_program + .expect("system_program is not set"), + + rent: self.instruction.rent.expect("rent is not set"), + __args: args, + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct InsertTransactionCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + governance_account: Option<&'b solana_account_info::AccountInfo<'a>>, + proposal_account: Option<&'b solana_account_info::AccountInfo<'a>>, + token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + governance_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + proposal_transaction_account: Option<&'b solana_account_info::AccountInfo<'a>>, + payer: Option<&'b solana_account_info::AccountInfo<'a>>, + system_program: Option<&'b solana_account_info::AccountInfo<'a>>, + rent: Option<&'b solana_account_info::AccountInfo<'a>>, + option_index: Option, + index: Option, + hold_up_time: Option, + instructions: Option>, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/legacy1.rs b/e2e/governance/src/generated/instructions/legacy1.rs new file mode 100644 index 0000000..9e155f0 --- /dev/null +++ b/e2e/governance/src/generated/instructions/legacy1.rs @@ -0,0 +1,225 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const LEGACY1_DISCRIMINATOR: u8 = 8; + +/// Accounts. +#[derive(Debug)] +pub struct Legacy1 {} + +impl Legacy1 { + pub fn instruction(&self) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(&[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(remaining_accounts.len()); + accounts.extend_from_slice(remaining_accounts); + let data = Legacy1InstructionData::new().try_to_vec().unwrap(); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Legacy1InstructionData { + discriminator: u8, +} + +impl Legacy1InstructionData { + pub fn new() -> Self { + Self { discriminator: 8 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for Legacy1InstructionData { + fn default() -> Self { + Self::new() + } +} + +/// Instruction builder for `Legacy1`. +/// +/// ### Accounts: +/// +#[derive(Clone, Debug, Default)] +pub struct Legacy1Builder { + __remaining_accounts: Vec, +} + +impl Legacy1Builder { + pub fn new() -> Self { + Self::default() + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = Legacy1 {}; + + accounts.instruction_with_remaining_accounts(&self.__remaining_accounts) + } +} + +/// `legacy1` CPI instruction. +pub struct Legacy1Cpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, +} + +impl<'a, 'b> Legacy1Cpi<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + Self { __program: program } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(remaining_accounts.len()); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let data = Legacy1InstructionData::new().try_to_vec().unwrap(); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(1 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `Legacy1` via CPI. +/// +/// ### Accounts: +/// +#[derive(Clone, Debug)] +pub struct Legacy1CpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> Legacy1CpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(Legacy1CpiBuilderInstruction { + __program: program, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let instruction = Legacy1Cpi { + __program: self.instruction.__program, + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct Legacy1CpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/mod.rs b/e2e/governance/src/generated/instructions/mod.rs new file mode 100644 index 0000000..6531b79 --- /dev/null +++ b/e2e/governance/src/generated/instructions/mod.rs @@ -0,0 +1,70 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +pub(crate) mod r#add_required_signatory; +pub(crate) mod r#add_signatory; +pub(crate) mod r#cancel_proposal; +pub(crate) mod r#cast_vote; +pub(crate) mod r#complete_proposal; +pub(crate) mod r#create_governance; +pub(crate) mod r#create_mint_governance; +pub(crate) mod r#create_native_treasury; +pub(crate) mod r#create_program_governance; +pub(crate) mod r#create_proposal; +pub(crate) mod r#create_realm; +pub(crate) mod r#create_token_governance; +pub(crate) mod r#create_token_owner_record; +pub(crate) mod r#deposit_governing_tokens; +pub(crate) mod r#execute_transaction; +pub(crate) mod r#finalize_vote; +pub(crate) mod r#flag_transaction_error; +pub(crate) mod r#insert_transaction; +pub(crate) mod r#legacy1; +pub(crate) mod r#refund_proposal_deposit; +pub(crate) mod r#relinquish_vote; +pub(crate) mod r#remove_required_signatory; +pub(crate) mod r#remove_transaction; +pub(crate) mod r#revoke_governing_tokens; +pub(crate) mod r#set_governance_config; +pub(crate) mod r#set_governance_delegate; +pub(crate) mod r#set_realm_authority; +pub(crate) mod r#set_realm_config; +pub(crate) mod r#sign_off_proposal; +pub(crate) mod r#update_program_metadata; +pub(crate) mod r#withdraw_governing_tokens; + +pub use self::r#add_required_signatory::*; +pub use self::r#add_signatory::*; +pub use self::r#cancel_proposal::*; +pub use self::r#cast_vote::*; +pub use self::r#complete_proposal::*; +pub use self::r#create_governance::*; +pub use self::r#create_mint_governance::*; +pub use self::r#create_native_treasury::*; +pub use self::r#create_program_governance::*; +pub use self::r#create_proposal::*; +pub use self::r#create_realm::*; +pub use self::r#create_token_governance::*; +pub use self::r#create_token_owner_record::*; +pub use self::r#deposit_governing_tokens::*; +pub use self::r#execute_transaction::*; +pub use self::r#finalize_vote::*; +pub use self::r#flag_transaction_error::*; +pub use self::r#insert_transaction::*; +pub use self::r#legacy1::*; +pub use self::r#refund_proposal_deposit::*; +pub use self::r#relinquish_vote::*; +pub use self::r#remove_required_signatory::*; +pub use self::r#remove_transaction::*; +pub use self::r#revoke_governing_tokens::*; +pub use self::r#set_governance_config::*; +pub use self::r#set_governance_delegate::*; +pub use self::r#set_realm_authority::*; +pub use self::r#set_realm_config::*; +pub use self::r#sign_off_proposal::*; +pub use self::r#update_program_metadata::*; +pub use self::r#withdraw_governing_tokens::*; diff --git a/e2e/governance/src/generated/instructions/refund_proposal_deposit.rs b/e2e/governance/src/generated/instructions/refund_proposal_deposit.rs new file mode 100644 index 0000000..9c672c1 --- /dev/null +++ b/e2e/governance/src/generated/instructions/refund_proposal_deposit.rs @@ -0,0 +1,372 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const REFUND_PROPOSAL_DEPOSIT_DISCRIMINATOR: u8 = 27; + +/// Accounts. +#[derive(Debug)] +pub struct RefundProposalDeposit { + pub proposal_account: solana_pubkey::Pubkey, + /// PDA Seeds: ['proposal-deposit', proposal, deposit payer] + pub proposal_deposit_account: solana_pubkey::Pubkey, + /// Proposal Deposit Payer (beneficiary) account + pub proposal_deposit_payer: solana_pubkey::Pubkey, +} + +impl RefundProposalDeposit { + pub fn instruction(&self) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(&[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(3 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.proposal_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_deposit_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_deposit_payer, + false, + )); + accounts.extend_from_slice(remaining_accounts); + let data = RefundProposalDepositInstructionData::new() + .try_to_vec() + .unwrap(); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct RefundProposalDepositInstructionData { + discriminator: u8, +} + +impl RefundProposalDepositInstructionData { + pub fn new() -> Self { + Self { discriminator: 27 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for RefundProposalDepositInstructionData { + fn default() -> Self { + Self::new() + } +} + +/// Instruction builder for `RefundProposalDeposit`. +/// +/// ### Accounts: +/// +/// 0. `[]` proposal_account +/// 1. `[writable]` proposal_deposit_account +/// 2. `[writable]` proposal_deposit_payer +#[derive(Clone, Debug, Default)] +pub struct RefundProposalDepositBuilder { + proposal_account: Option, + proposal_deposit_account: Option, + proposal_deposit_payer: Option, + __remaining_accounts: Vec, +} + +impl RefundProposalDepositBuilder { + pub fn new() -> Self { + Self::default() + } + #[inline(always)] + pub fn proposal_account(&mut self, proposal_account: solana_pubkey::Pubkey) -> &mut Self { + self.proposal_account = Some(proposal_account); + self + } + /// PDA Seeds: ['proposal-deposit', proposal, deposit payer] + #[inline(always)] + pub fn proposal_deposit_account( + &mut self, + proposal_deposit_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.proposal_deposit_account = Some(proposal_deposit_account); + self + } + /// Proposal Deposit Payer (beneficiary) account + #[inline(always)] + pub fn proposal_deposit_payer( + &mut self, + proposal_deposit_payer: solana_pubkey::Pubkey, + ) -> &mut Self { + self.proposal_deposit_payer = Some(proposal_deposit_payer); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = RefundProposalDeposit { + proposal_account: self.proposal_account.expect("proposal_account is not set"), + proposal_deposit_account: self + .proposal_deposit_account + .expect("proposal_deposit_account is not set"), + proposal_deposit_payer: self + .proposal_deposit_payer + .expect("proposal_deposit_payer is not set"), + }; + + accounts.instruction_with_remaining_accounts(&self.__remaining_accounts) + } +} + +/// `refund_proposal_deposit` CPI accounts. +pub struct RefundProposalDepositCpiAccounts<'a, 'b> { + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// PDA Seeds: ['proposal-deposit', proposal, deposit payer] + pub proposal_deposit_account: &'b solana_account_info::AccountInfo<'a>, + /// Proposal Deposit Payer (beneficiary) account + pub proposal_deposit_payer: &'b solana_account_info::AccountInfo<'a>, +} + +/// `refund_proposal_deposit` CPI instruction. +pub struct RefundProposalDepositCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// PDA Seeds: ['proposal-deposit', proposal, deposit payer] + pub proposal_deposit_account: &'b solana_account_info::AccountInfo<'a>, + /// Proposal Deposit Payer (beneficiary) account + pub proposal_deposit_payer: &'b solana_account_info::AccountInfo<'a>, +} + +impl<'a, 'b> RefundProposalDepositCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: RefundProposalDepositCpiAccounts<'a, 'b>, + ) -> Self { + Self { + __program: program, + proposal_account: accounts.proposal_account, + proposal_deposit_account: accounts.proposal_deposit_account, + proposal_deposit_payer: accounts.proposal_deposit_payer, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(3 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.proposal_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_deposit_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_deposit_payer.key, + false, + )); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let data = RefundProposalDepositInstructionData::new() + .try_to_vec() + .unwrap(); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(4 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.proposal_account.clone()); + account_infos.push(self.proposal_deposit_account.clone()); + account_infos.push(self.proposal_deposit_payer.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `RefundProposalDeposit` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[]` proposal_account +/// 1. `[writable]` proposal_deposit_account +/// 2. `[writable]` proposal_deposit_payer +#[derive(Clone, Debug)] +pub struct RefundProposalDepositCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> RefundProposalDepositCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(RefundProposalDepositCpiBuilderInstruction { + __program: program, + proposal_account: None, + proposal_deposit_account: None, + proposal_deposit_payer: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + #[inline(always)] + pub fn proposal_account( + &mut self, + proposal_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_account = Some(proposal_account); + self + } + /// PDA Seeds: ['proposal-deposit', proposal, deposit payer] + #[inline(always)] + pub fn proposal_deposit_account( + &mut self, + proposal_deposit_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_deposit_account = Some(proposal_deposit_account); + self + } + /// Proposal Deposit Payer (beneficiary) account + #[inline(always)] + pub fn proposal_deposit_payer( + &mut self, + proposal_deposit_payer: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_deposit_payer = Some(proposal_deposit_payer); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let instruction = RefundProposalDepositCpi { + __program: self.instruction.__program, + + proposal_account: self + .instruction + .proposal_account + .expect("proposal_account is not set"), + + proposal_deposit_account: self + .instruction + .proposal_deposit_account + .expect("proposal_deposit_account is not set"), + + proposal_deposit_payer: self + .instruction + .proposal_deposit_payer + .expect("proposal_deposit_payer is not set"), + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct RefundProposalDepositCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + proposal_account: Option<&'b solana_account_info::AccountInfo<'a>>, + proposal_deposit_account: Option<&'b solana_account_info::AccountInfo<'a>>, + proposal_deposit_payer: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/relinquish_vote.rs b/e2e/governance/src/generated/instructions/relinquish_vote.rs new file mode 100644 index 0000000..8721fc5 --- /dev/null +++ b/e2e/governance/src/generated/instructions/relinquish_vote.rs @@ -0,0 +1,617 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const RELINQUISH_VOTE_DISCRIMINATOR: u8 = 15; + +/// Accounts. +#[derive(Debug)] +pub struct RelinquishVote { + pub realm_account: solana_pubkey::Pubkey, + + pub governance_account: solana_pubkey::Pubkey, + + pub proposal_account: solana_pubkey::Pubkey, + /// TokenOwnerRecord account. PDA seeds: ['governance',realm, vote_governing_token_mint, governing_token_owner] + pub token_owner_record: solana_pubkey::Pubkey, + /// Proposal VoteRecord account. PDA seeds: ['governance',proposal, token_owner_record] + pub proposal_vote_record: solana_pubkey::Pubkey, + /// The Governing Token Mint which was used to cast the vote (vote_governing_token_mint) + pub governing_token_mint: solana_pubkey::Pubkey, + + pub governance_authority: Option, + /// Optional Beneficiary account which would receive lamports when VoteRecord Account is disposed. + /// It's required only when Proposal is still being voted on + pub beneficiary_account: Option, +} + +impl RelinquishVote { + pub fn instruction(&self) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(&[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(8 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governance_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.token_owner_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_vote_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governing_token_mint, + false, + )); + if let Some(governance_authority) = self.governance_authority { + accounts.push(solana_instruction::AccountMeta::new_readonly( + governance_authority, + true, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(beneficiary_account) = self.beneficiary_account { + accounts.push(solana_instruction::AccountMeta::new( + beneficiary_account, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + accounts.extend_from_slice(remaining_accounts); + let data = RelinquishVoteInstructionData::new().try_to_vec().unwrap(); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct RelinquishVoteInstructionData { + discriminator: u8, +} + +impl RelinquishVoteInstructionData { + pub fn new() -> Self { + Self { discriminator: 15 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for RelinquishVoteInstructionData { + fn default() -> Self { + Self::new() + } +} + +/// Instruction builder for `RelinquishVote`. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[]` governance_account +/// 2. `[writable]` proposal_account +/// 3. `[writable]` token_owner_record +/// 4. `[writable]` proposal_vote_record +/// 5. `[]` governing_token_mint +/// 6. `[signer, optional]` governance_authority +/// 7. `[writable, optional]` beneficiary_account +#[derive(Clone, Debug, Default)] +pub struct RelinquishVoteBuilder { + realm_account: Option, + governance_account: Option, + proposal_account: Option, + token_owner_record: Option, + proposal_vote_record: Option, + governing_token_mint: Option, + governance_authority: Option, + beneficiary_account: Option, + __remaining_accounts: Vec, +} + +impl RelinquishVoteBuilder { + pub fn new() -> Self { + Self::default() + } + #[inline(always)] + pub fn realm_account(&mut self, realm_account: solana_pubkey::Pubkey) -> &mut Self { + self.realm_account = Some(realm_account); + self + } + #[inline(always)] + pub fn governance_account(&mut self, governance_account: solana_pubkey::Pubkey) -> &mut Self { + self.governance_account = Some(governance_account); + self + } + #[inline(always)] + pub fn proposal_account(&mut self, proposal_account: solana_pubkey::Pubkey) -> &mut Self { + self.proposal_account = Some(proposal_account); + self + } + /// TokenOwnerRecord account. PDA seeds: ['governance',realm, vote_governing_token_mint, governing_token_owner] + #[inline(always)] + pub fn token_owner_record(&mut self, token_owner_record: solana_pubkey::Pubkey) -> &mut Self { + self.token_owner_record = Some(token_owner_record); + self + } + /// Proposal VoteRecord account. PDA seeds: ['governance',proposal, token_owner_record] + #[inline(always)] + pub fn proposal_vote_record( + &mut self, + proposal_vote_record: solana_pubkey::Pubkey, + ) -> &mut Self { + self.proposal_vote_record = Some(proposal_vote_record); + self + } + /// The Governing Token Mint which was used to cast the vote (vote_governing_token_mint) + #[inline(always)] + pub fn governing_token_mint( + &mut self, + governing_token_mint: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governing_token_mint = Some(governing_token_mint); + self + } + /// `[optional account]` + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: Option, + ) -> &mut Self { + self.governance_authority = governance_authority; + self + } + /// `[optional account]` + /// Optional Beneficiary account which would receive lamports when VoteRecord Account is disposed. + /// It's required only when Proposal is still being voted on + #[inline(always)] + pub fn beneficiary_account( + &mut self, + beneficiary_account: Option, + ) -> &mut Self { + self.beneficiary_account = beneficiary_account; + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = RelinquishVote { + realm_account: self.realm_account.expect("realm_account is not set"), + governance_account: self + .governance_account + .expect("governance_account is not set"), + proposal_account: self.proposal_account.expect("proposal_account is not set"), + token_owner_record: self + .token_owner_record + .expect("token_owner_record is not set"), + proposal_vote_record: self + .proposal_vote_record + .expect("proposal_vote_record is not set"), + governing_token_mint: self + .governing_token_mint + .expect("governing_token_mint is not set"), + governance_authority: self.governance_authority, + beneficiary_account: self.beneficiary_account, + }; + + accounts.instruction_with_remaining_accounts(&self.__remaining_accounts) + } +} + +/// `relinquish_vote` CPI accounts. +pub struct RelinquishVoteCpiAccounts<'a, 'b> { + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord account. PDA seeds: ['governance',realm, vote_governing_token_mint, governing_token_owner] + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// Proposal VoteRecord account. PDA seeds: ['governance',proposal, token_owner_record] + pub proposal_vote_record: &'b solana_account_info::AccountInfo<'a>, + /// The Governing Token Mint which was used to cast the vote (vote_governing_token_mint) + pub governing_token_mint: &'b solana_account_info::AccountInfo<'a>, + + pub governance_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional Beneficiary account which would receive lamports when VoteRecord Account is disposed. + /// It's required only when Proposal is still being voted on + pub beneficiary_account: Option<&'b solana_account_info::AccountInfo<'a>>, +} + +/// `relinquish_vote` CPI instruction. +pub struct RelinquishVoteCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord account. PDA seeds: ['governance',realm, vote_governing_token_mint, governing_token_owner] + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// Proposal VoteRecord account. PDA seeds: ['governance',proposal, token_owner_record] + pub proposal_vote_record: &'b solana_account_info::AccountInfo<'a>, + /// The Governing Token Mint which was used to cast the vote (vote_governing_token_mint) + pub governing_token_mint: &'b solana_account_info::AccountInfo<'a>, + + pub governance_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional Beneficiary account which would receive lamports when VoteRecord Account is disposed. + /// It's required only when Proposal is still being voted on + pub beneficiary_account: Option<&'b solana_account_info::AccountInfo<'a>>, +} + +impl<'a, 'b> RelinquishVoteCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: RelinquishVoteCpiAccounts<'a, 'b>, + ) -> Self { + Self { + __program: program, + realm_account: accounts.realm_account, + governance_account: accounts.governance_account, + proposal_account: accounts.proposal_account, + token_owner_record: accounts.token_owner_record, + proposal_vote_record: accounts.proposal_vote_record, + governing_token_mint: accounts.governing_token_mint, + governance_authority: accounts.governance_authority, + beneficiary_account: accounts.beneficiary_account, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(8 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governance_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.token_owner_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_vote_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governing_token_mint.key, + false, + )); + if let Some(governance_authority) = self.governance_authority { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *governance_authority.key, + true, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(beneficiary_account) = self.beneficiary_account { + accounts.push(solana_instruction::AccountMeta::new( + *beneficiary_account.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let data = RelinquishVoteInstructionData::new().try_to_vec().unwrap(); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(9 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.realm_account.clone()); + account_infos.push(self.governance_account.clone()); + account_infos.push(self.proposal_account.clone()); + account_infos.push(self.token_owner_record.clone()); + account_infos.push(self.proposal_vote_record.clone()); + account_infos.push(self.governing_token_mint.clone()); + if let Some(governance_authority) = self.governance_authority { + account_infos.push(governance_authority.clone()); + } + if let Some(beneficiary_account) = self.beneficiary_account { + account_infos.push(beneficiary_account.clone()); + } + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `RelinquishVote` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[]` governance_account +/// 2. `[writable]` proposal_account +/// 3. `[writable]` token_owner_record +/// 4. `[writable]` proposal_vote_record +/// 5. `[]` governing_token_mint +/// 6. `[signer, optional]` governance_authority +/// 7. `[writable, optional]` beneficiary_account +#[derive(Clone, Debug)] +pub struct RelinquishVoteCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> RelinquishVoteCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(RelinquishVoteCpiBuilderInstruction { + __program: program, + realm_account: None, + governance_account: None, + proposal_account: None, + token_owner_record: None, + proposal_vote_record: None, + governing_token_mint: None, + governance_authority: None, + beneficiary_account: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + #[inline(always)] + pub fn realm_account( + &mut self, + realm_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_account = Some(realm_account); + self + } + #[inline(always)] + pub fn governance_account( + &mut self, + governance_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_account = Some(governance_account); + self + } + #[inline(always)] + pub fn proposal_account( + &mut self, + proposal_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_account = Some(proposal_account); + self + } + /// TokenOwnerRecord account. PDA seeds: ['governance',realm, vote_governing_token_mint, governing_token_owner] + #[inline(always)] + pub fn token_owner_record( + &mut self, + token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_owner_record = Some(token_owner_record); + self + } + /// Proposal VoteRecord account. PDA seeds: ['governance',proposal, token_owner_record] + #[inline(always)] + pub fn proposal_vote_record( + &mut self, + proposal_vote_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_vote_record = Some(proposal_vote_record); + self + } + /// The Governing Token Mint which was used to cast the vote (vote_governing_token_mint) + #[inline(always)] + pub fn governing_token_mint( + &mut self, + governing_token_mint: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governing_token_mint = Some(governing_token_mint); + self + } + /// `[optional account]` + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.governance_authority = governance_authority; + self + } + /// `[optional account]` + /// Optional Beneficiary account which would receive lamports when VoteRecord Account is disposed. + /// It's required only when Proposal is still being voted on + #[inline(always)] + pub fn beneficiary_account( + &mut self, + beneficiary_account: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.beneficiary_account = beneficiary_account; + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let instruction = RelinquishVoteCpi { + __program: self.instruction.__program, + + realm_account: self + .instruction + .realm_account + .expect("realm_account is not set"), + + governance_account: self + .instruction + .governance_account + .expect("governance_account is not set"), + + proposal_account: self + .instruction + .proposal_account + .expect("proposal_account is not set"), + + token_owner_record: self + .instruction + .token_owner_record + .expect("token_owner_record is not set"), + + proposal_vote_record: self + .instruction + .proposal_vote_record + .expect("proposal_vote_record is not set"), + + governing_token_mint: self + .instruction + .governing_token_mint + .expect("governing_token_mint is not set"), + + governance_authority: self.instruction.governance_authority, + + beneficiary_account: self.instruction.beneficiary_account, + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct RelinquishVoteCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + realm_account: Option<&'b solana_account_info::AccountInfo<'a>>, + governance_account: Option<&'b solana_account_info::AccountInfo<'a>>, + proposal_account: Option<&'b solana_account_info::AccountInfo<'a>>, + token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + proposal_vote_record: Option<&'b solana_account_info::AccountInfo<'a>>, + governing_token_mint: Option<&'b solana_account_info::AccountInfo<'a>>, + governance_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + beneficiary_account: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/remove_required_signatory.rs b/e2e/governance/src/generated/instructions/remove_required_signatory.rs new file mode 100644 index 0000000..8b8367d --- /dev/null +++ b/e2e/governance/src/generated/instructions/remove_required_signatory.rs @@ -0,0 +1,369 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const REMOVE_REQUIRED_SIGNATORY_DISCRIMINATOR: u8 = 30; + +/// Accounts. +#[derive(Debug)] +pub struct RemoveRequiredSignatory { + pub governance_account: solana_pubkey::Pubkey, + + pub required_signatory_account: solana_pubkey::Pubkey, + /// Beneficiary Account which would receive lamports from the disposed RequiredSignatory Account + pub beneficiary_account: solana_pubkey::Pubkey, +} + +impl RemoveRequiredSignatory { + pub fn instruction(&self) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(&[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(3 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + self.governance_account, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.required_signatory_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.beneficiary_account, + false, + )); + accounts.extend_from_slice(remaining_accounts); + let data = RemoveRequiredSignatoryInstructionData::new() + .try_to_vec() + .unwrap(); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct RemoveRequiredSignatoryInstructionData { + discriminator: u8, +} + +impl RemoveRequiredSignatoryInstructionData { + pub fn new() -> Self { + Self { discriminator: 30 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for RemoveRequiredSignatoryInstructionData { + fn default() -> Self { + Self::new() + } +} + +/// Instruction builder for `RemoveRequiredSignatory`. +/// +/// ### Accounts: +/// +/// 0. `[writable, signer]` governance_account +/// 1. `[writable]` required_signatory_account +/// 2. `[writable]` beneficiary_account +#[derive(Clone, Debug, Default)] +pub struct RemoveRequiredSignatoryBuilder { + governance_account: Option, + required_signatory_account: Option, + beneficiary_account: Option, + __remaining_accounts: Vec, +} + +impl RemoveRequiredSignatoryBuilder { + pub fn new() -> Self { + Self::default() + } + #[inline(always)] + pub fn governance_account(&mut self, governance_account: solana_pubkey::Pubkey) -> &mut Self { + self.governance_account = Some(governance_account); + self + } + #[inline(always)] + pub fn required_signatory_account( + &mut self, + required_signatory_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.required_signatory_account = Some(required_signatory_account); + self + } + /// Beneficiary Account which would receive lamports from the disposed RequiredSignatory Account + #[inline(always)] + pub fn beneficiary_account(&mut self, beneficiary_account: solana_pubkey::Pubkey) -> &mut Self { + self.beneficiary_account = Some(beneficiary_account); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = RemoveRequiredSignatory { + governance_account: self + .governance_account + .expect("governance_account is not set"), + required_signatory_account: self + .required_signatory_account + .expect("required_signatory_account is not set"), + beneficiary_account: self + .beneficiary_account + .expect("beneficiary_account is not set"), + }; + + accounts.instruction_with_remaining_accounts(&self.__remaining_accounts) + } +} + +/// `remove_required_signatory` CPI accounts. +pub struct RemoveRequiredSignatoryCpiAccounts<'a, 'b> { + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + + pub required_signatory_account: &'b solana_account_info::AccountInfo<'a>, + /// Beneficiary Account which would receive lamports from the disposed RequiredSignatory Account + pub beneficiary_account: &'b solana_account_info::AccountInfo<'a>, +} + +/// `remove_required_signatory` CPI instruction. +pub struct RemoveRequiredSignatoryCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + + pub required_signatory_account: &'b solana_account_info::AccountInfo<'a>, + /// Beneficiary Account which would receive lamports from the disposed RequiredSignatory Account + pub beneficiary_account: &'b solana_account_info::AccountInfo<'a>, +} + +impl<'a, 'b> RemoveRequiredSignatoryCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: RemoveRequiredSignatoryCpiAccounts<'a, 'b>, + ) -> Self { + Self { + __program: program, + governance_account: accounts.governance_account, + required_signatory_account: accounts.required_signatory_account, + beneficiary_account: accounts.beneficiary_account, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(3 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + *self.governance_account.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.required_signatory_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.beneficiary_account.key, + false, + )); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let data = RemoveRequiredSignatoryInstructionData::new() + .try_to_vec() + .unwrap(); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(4 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.governance_account.clone()); + account_infos.push(self.required_signatory_account.clone()); + account_infos.push(self.beneficiary_account.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `RemoveRequiredSignatory` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[writable, signer]` governance_account +/// 1. `[writable]` required_signatory_account +/// 2. `[writable]` beneficiary_account +#[derive(Clone, Debug)] +pub struct RemoveRequiredSignatoryCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> RemoveRequiredSignatoryCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(RemoveRequiredSignatoryCpiBuilderInstruction { + __program: program, + governance_account: None, + required_signatory_account: None, + beneficiary_account: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + #[inline(always)] + pub fn governance_account( + &mut self, + governance_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_account = Some(governance_account); + self + } + #[inline(always)] + pub fn required_signatory_account( + &mut self, + required_signatory_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.required_signatory_account = Some(required_signatory_account); + self + } + /// Beneficiary Account which would receive lamports from the disposed RequiredSignatory Account + #[inline(always)] + pub fn beneficiary_account( + &mut self, + beneficiary_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.beneficiary_account = Some(beneficiary_account); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let instruction = RemoveRequiredSignatoryCpi { + __program: self.instruction.__program, + + governance_account: self + .instruction + .governance_account + .expect("governance_account is not set"), + + required_signatory_account: self + .instruction + .required_signatory_account + .expect("required_signatory_account is not set"), + + beneficiary_account: self + .instruction + .beneficiary_account + .expect("beneficiary_account is not set"), + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct RemoveRequiredSignatoryCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + governance_account: Option<&'b solana_account_info::AccountInfo<'a>>, + required_signatory_account: Option<&'b solana_account_info::AccountInfo<'a>>, + beneficiary_account: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/remove_transaction.rs b/e2e/governance/src/generated/instructions/remove_transaction.rs new file mode 100644 index 0000000..7188295 --- /dev/null +++ b/e2e/governance/src/generated/instructions/remove_transaction.rs @@ -0,0 +1,458 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const REMOVE_TRANSACTION_DISCRIMINATOR: u8 = 10; + +/// Accounts. +#[derive(Debug)] +pub struct RemoveTransaction { + pub proposal_account: solana_pubkey::Pubkey, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: solana_pubkey::Pubkey, + /// Governance Authority (Token Owner or Governance Delegate) + pub governance_authority: solana_pubkey::Pubkey, + + pub proposal_transaction_account: solana_pubkey::Pubkey, + /// Beneficiary Account which would receive lamports from the disposed ProposalTransaction account + pub beneficiary_account: solana_pubkey::Pubkey, +} + +impl RemoveTransaction { + pub fn instruction(&self) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(&[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(5 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.token_owner_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governance_authority, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_transaction_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.beneficiary_account, + false, + )); + accounts.extend_from_slice(remaining_accounts); + let data = RemoveTransactionInstructionData::new() + .try_to_vec() + .unwrap(); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct RemoveTransactionInstructionData { + discriminator: u8, +} + +impl RemoveTransactionInstructionData { + pub fn new() -> Self { + Self { discriminator: 10 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for RemoveTransactionInstructionData { + fn default() -> Self { + Self::new() + } +} + +/// Instruction builder for `RemoveTransaction`. +/// +/// ### Accounts: +/// +/// 0. `[writable]` proposal_account +/// 1. `[]` token_owner_record +/// 2. `[signer]` governance_authority +/// 3. `[writable]` proposal_transaction_account +/// 4. `[writable]` beneficiary_account +#[derive(Clone, Debug, Default)] +pub struct RemoveTransactionBuilder { + proposal_account: Option, + token_owner_record: Option, + governance_authority: Option, + proposal_transaction_account: Option, + beneficiary_account: Option, + __remaining_accounts: Vec, +} + +impl RemoveTransactionBuilder { + pub fn new() -> Self { + Self::default() + } + #[inline(always)] + pub fn proposal_account(&mut self, proposal_account: solana_pubkey::Pubkey) -> &mut Self { + self.proposal_account = Some(proposal_account); + self + } + /// TokenOwnerRecord account of the Proposal owner + #[inline(always)] + pub fn token_owner_record(&mut self, token_owner_record: solana_pubkey::Pubkey) -> &mut Self { + self.token_owner_record = Some(token_owner_record); + self + } + /// Governance Authority (Token Owner or Governance Delegate) + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governance_authority = Some(governance_authority); + self + } + #[inline(always)] + pub fn proposal_transaction_account( + &mut self, + proposal_transaction_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.proposal_transaction_account = Some(proposal_transaction_account); + self + } + /// Beneficiary Account which would receive lamports from the disposed ProposalTransaction account + #[inline(always)] + pub fn beneficiary_account(&mut self, beneficiary_account: solana_pubkey::Pubkey) -> &mut Self { + self.beneficiary_account = Some(beneficiary_account); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = RemoveTransaction { + proposal_account: self.proposal_account.expect("proposal_account is not set"), + token_owner_record: self + .token_owner_record + .expect("token_owner_record is not set"), + governance_authority: self + .governance_authority + .expect("governance_authority is not set"), + proposal_transaction_account: self + .proposal_transaction_account + .expect("proposal_transaction_account is not set"), + beneficiary_account: self + .beneficiary_account + .expect("beneficiary_account is not set"), + }; + + accounts.instruction_with_remaining_accounts(&self.__remaining_accounts) + } +} + +/// `remove_transaction` CPI accounts. +pub struct RemoveTransactionCpiAccounts<'a, 'b> { + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// Governance Authority (Token Owner or Governance Delegate) + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_transaction_account: &'b solana_account_info::AccountInfo<'a>, + /// Beneficiary Account which would receive lamports from the disposed ProposalTransaction account + pub beneficiary_account: &'b solana_account_info::AccountInfo<'a>, +} + +/// `remove_transaction` CPI instruction. +pub struct RemoveTransactionCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord account of the Proposal owner + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// Governance Authority (Token Owner or Governance Delegate) + pub governance_authority: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_transaction_account: &'b solana_account_info::AccountInfo<'a>, + /// Beneficiary Account which would receive lamports from the disposed ProposalTransaction account + pub beneficiary_account: &'b solana_account_info::AccountInfo<'a>, +} + +impl<'a, 'b> RemoveTransactionCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: RemoveTransactionCpiAccounts<'a, 'b>, + ) -> Self { + Self { + __program: program, + proposal_account: accounts.proposal_account, + token_owner_record: accounts.token_owner_record, + governance_authority: accounts.governance_authority, + proposal_transaction_account: accounts.proposal_transaction_account, + beneficiary_account: accounts.beneficiary_account, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(5 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.token_owner_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governance_authority.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_transaction_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.beneficiary_account.key, + false, + )); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let data = RemoveTransactionInstructionData::new() + .try_to_vec() + .unwrap(); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(6 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.proposal_account.clone()); + account_infos.push(self.token_owner_record.clone()); + account_infos.push(self.governance_authority.clone()); + account_infos.push(self.proposal_transaction_account.clone()); + account_infos.push(self.beneficiary_account.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `RemoveTransaction` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[writable]` proposal_account +/// 1. `[]` token_owner_record +/// 2. `[signer]` governance_authority +/// 3. `[writable]` proposal_transaction_account +/// 4. `[writable]` beneficiary_account +#[derive(Clone, Debug)] +pub struct RemoveTransactionCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> RemoveTransactionCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(RemoveTransactionCpiBuilderInstruction { + __program: program, + proposal_account: None, + token_owner_record: None, + governance_authority: None, + proposal_transaction_account: None, + beneficiary_account: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + #[inline(always)] + pub fn proposal_account( + &mut self, + proposal_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_account = Some(proposal_account); + self + } + /// TokenOwnerRecord account of the Proposal owner + #[inline(always)] + pub fn token_owner_record( + &mut self, + token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_owner_record = Some(token_owner_record); + self + } + /// Governance Authority (Token Owner or Governance Delegate) + #[inline(always)] + pub fn governance_authority( + &mut self, + governance_authority: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_authority = Some(governance_authority); + self + } + #[inline(always)] + pub fn proposal_transaction_account( + &mut self, + proposal_transaction_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_transaction_account = Some(proposal_transaction_account); + self + } + /// Beneficiary Account which would receive lamports from the disposed ProposalTransaction account + #[inline(always)] + pub fn beneficiary_account( + &mut self, + beneficiary_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.beneficiary_account = Some(beneficiary_account); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let instruction = RemoveTransactionCpi { + __program: self.instruction.__program, + + proposal_account: self + .instruction + .proposal_account + .expect("proposal_account is not set"), + + token_owner_record: self + .instruction + .token_owner_record + .expect("token_owner_record is not set"), + + governance_authority: self + .instruction + .governance_authority + .expect("governance_authority is not set"), + + proposal_transaction_account: self + .instruction + .proposal_transaction_account + .expect("proposal_transaction_account is not set"), + + beneficiary_account: self + .instruction + .beneficiary_account + .expect("beneficiary_account is not set"), + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct RemoveTransactionCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + proposal_account: Option<&'b solana_account_info::AccountInfo<'a>>, + token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + governance_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + proposal_transaction_account: Option<&'b solana_account_info::AccountInfo<'a>>, + beneficiary_account: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/revoke_governing_tokens.rs b/e2e/governance/src/generated/instructions/revoke_governing_tokens.rs new file mode 100644 index 0000000..2f09cb0 --- /dev/null +++ b/e2e/governance/src/generated/instructions/revoke_governing_tokens.rs @@ -0,0 +1,599 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const REVOKE_GOVERNING_TOKENS_DISCRIMINATOR: u8 = 26; + +/// Accounts. +#[derive(Debug)] +pub struct RevokeGoverningTokens { + pub realm_account: solana_pubkey::Pubkey, + /// seeds=['governance', realm, governing_token_mint] + pub governing_token_holding_account: solana_pubkey::Pubkey, + /// seeds=['governance', realm, governing_token_mint, governing_token_owner] + pub token_owner_record: solana_pubkey::Pubkey, + + pub governing_token_mint: solana_pubkey::Pubkey, + /// GoverningTokenMint mint_authority + pub governing_token_mint_authority_or_token_owner: solana_pubkey::Pubkey, + /// seeds=['realm-config', realm] + pub realm_config_account: solana_pubkey::Pubkey, + + pub token_program: solana_pubkey::Pubkey, +} + +impl RevokeGoverningTokens { + pub fn instruction( + &self, + args: RevokeGoverningTokensInstructionArgs, + ) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(args, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + args: RevokeGoverningTokensInstructionArgs, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(7 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.governing_token_holding_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.token_owner_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.governing_token_mint, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governing_token_mint_authority_or_token_owner, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_config_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.token_program, + false, + )); + accounts.extend_from_slice(remaining_accounts); + let mut data = RevokeGoverningTokensInstructionData::new() + .try_to_vec() + .unwrap(); + let mut args = args.try_to_vec().unwrap(); + data.append(&mut args); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct RevokeGoverningTokensInstructionData { + discriminator: u8, +} + +impl RevokeGoverningTokensInstructionData { + pub fn new() -> Self { + Self { discriminator: 26 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for RevokeGoverningTokensInstructionData { + fn default() -> Self { + Self::new() + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct RevokeGoverningTokensInstructionArgs { + pub amount: u64, +} + +impl RevokeGoverningTokensInstructionArgs { + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +/// Instruction builder for `RevokeGoverningTokens`. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[writable]` governing_token_holding_account +/// 2. `[writable]` token_owner_record +/// 3. `[writable]` governing_token_mint +/// 4. `[signer]` governing_token_mint_authority_or_token_owner +/// 5. `[]` realm_config_account +/// 6. `[optional]` token_program (default to `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`) +#[derive(Clone, Debug, Default)] +pub struct RevokeGoverningTokensBuilder { + realm_account: Option, + governing_token_holding_account: Option, + token_owner_record: Option, + governing_token_mint: Option, + governing_token_mint_authority_or_token_owner: Option, + realm_config_account: Option, + token_program: Option, + amount: Option, + __remaining_accounts: Vec, +} + +impl RevokeGoverningTokensBuilder { + pub fn new() -> Self { + Self::default() + } + #[inline(always)] + pub fn realm_account(&mut self, realm_account: solana_pubkey::Pubkey) -> &mut Self { + self.realm_account = Some(realm_account); + self + } + /// seeds=['governance', realm, governing_token_mint] + #[inline(always)] + pub fn governing_token_holding_account( + &mut self, + governing_token_holding_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governing_token_holding_account = Some(governing_token_holding_account); + self + } + /// seeds=['governance', realm, governing_token_mint, governing_token_owner] + #[inline(always)] + pub fn token_owner_record(&mut self, token_owner_record: solana_pubkey::Pubkey) -> &mut Self { + self.token_owner_record = Some(token_owner_record); + self + } + #[inline(always)] + pub fn governing_token_mint( + &mut self, + governing_token_mint: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governing_token_mint = Some(governing_token_mint); + self + } + /// GoverningTokenMint mint_authority + #[inline(always)] + pub fn governing_token_mint_authority_or_token_owner( + &mut self, + governing_token_mint_authority_or_token_owner: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governing_token_mint_authority_or_token_owner = + Some(governing_token_mint_authority_or_token_owner); + self + } + /// seeds=['realm-config', realm] + #[inline(always)] + pub fn realm_config_account( + &mut self, + realm_config_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.realm_config_account = Some(realm_config_account); + self + } + /// `[optional account, default to 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA']` + #[inline(always)] + pub fn token_program(&mut self, token_program: solana_pubkey::Pubkey) -> &mut Self { + self.token_program = Some(token_program); + self + } + #[inline(always)] + pub fn amount(&mut self, amount: u64) -> &mut Self { + self.amount = Some(amount); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = RevokeGoverningTokens { + realm_account: self.realm_account.expect("realm_account is not set"), + governing_token_holding_account: self + .governing_token_holding_account + .expect("governing_token_holding_account is not set"), + token_owner_record: self + .token_owner_record + .expect("token_owner_record is not set"), + governing_token_mint: self + .governing_token_mint + .expect("governing_token_mint is not set"), + governing_token_mint_authority_or_token_owner: self + .governing_token_mint_authority_or_token_owner + .expect("governing_token_mint_authority_or_token_owner is not set"), + realm_config_account: self + .realm_config_account + .expect("realm_config_account is not set"), + token_program: self.token_program.unwrap_or(solana_pubkey::pubkey!( + "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + )), + }; + let args = RevokeGoverningTokensInstructionArgs { + amount: self.amount.clone().expect("amount is not set"), + }; + + accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) + } +} + +/// `revoke_governing_tokens` CPI accounts. +pub struct RevokeGoverningTokensCpiAccounts<'a, 'b> { + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['governance', realm, governing_token_mint] + pub governing_token_holding_account: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['governance', realm, governing_token_mint, governing_token_owner] + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + + pub governing_token_mint: &'b solana_account_info::AccountInfo<'a>, + /// GoverningTokenMint mint_authority + pub governing_token_mint_authority_or_token_owner: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['realm-config', realm] + pub realm_config_account: &'b solana_account_info::AccountInfo<'a>, + + pub token_program: &'b solana_account_info::AccountInfo<'a>, +} + +/// `revoke_governing_tokens` CPI instruction. +pub struct RevokeGoverningTokensCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['governance', realm, governing_token_mint] + pub governing_token_holding_account: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['governance', realm, governing_token_mint, governing_token_owner] + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + + pub governing_token_mint: &'b solana_account_info::AccountInfo<'a>, + /// GoverningTokenMint mint_authority + pub governing_token_mint_authority_or_token_owner: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['realm-config', realm] + pub realm_config_account: &'b solana_account_info::AccountInfo<'a>, + + pub token_program: &'b solana_account_info::AccountInfo<'a>, + /// The arguments for the instruction. + pub __args: RevokeGoverningTokensInstructionArgs, +} + +impl<'a, 'b> RevokeGoverningTokensCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: RevokeGoverningTokensCpiAccounts<'a, 'b>, + args: RevokeGoverningTokensInstructionArgs, + ) -> Self { + Self { + __program: program, + realm_account: accounts.realm_account, + governing_token_holding_account: accounts.governing_token_holding_account, + token_owner_record: accounts.token_owner_record, + governing_token_mint: accounts.governing_token_mint, + governing_token_mint_authority_or_token_owner: accounts + .governing_token_mint_authority_or_token_owner, + realm_config_account: accounts.realm_config_account, + token_program: accounts.token_program, + __args: args, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(7 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.governing_token_holding_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.token_owner_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.governing_token_mint.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governing_token_mint_authority_or_token_owner.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_config_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.token_program.key, + false, + )); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let mut data = RevokeGoverningTokensInstructionData::new() + .try_to_vec() + .unwrap(); + let mut args = self.__args.try_to_vec().unwrap(); + data.append(&mut args); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(8 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.realm_account.clone()); + account_infos.push(self.governing_token_holding_account.clone()); + account_infos.push(self.token_owner_record.clone()); + account_infos.push(self.governing_token_mint.clone()); + account_infos.push(self.governing_token_mint_authority_or_token_owner.clone()); + account_infos.push(self.realm_config_account.clone()); + account_infos.push(self.token_program.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `RevokeGoverningTokens` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[writable]` governing_token_holding_account +/// 2. `[writable]` token_owner_record +/// 3. `[writable]` governing_token_mint +/// 4. `[signer]` governing_token_mint_authority_or_token_owner +/// 5. `[]` realm_config_account +/// 6. `[]` token_program +#[derive(Clone, Debug)] +pub struct RevokeGoverningTokensCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> RevokeGoverningTokensCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(RevokeGoverningTokensCpiBuilderInstruction { + __program: program, + realm_account: None, + governing_token_holding_account: None, + token_owner_record: None, + governing_token_mint: None, + governing_token_mint_authority_or_token_owner: None, + realm_config_account: None, + token_program: None, + amount: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + #[inline(always)] + pub fn realm_account( + &mut self, + realm_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_account = Some(realm_account); + self + } + /// seeds=['governance', realm, governing_token_mint] + #[inline(always)] + pub fn governing_token_holding_account( + &mut self, + governing_token_holding_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governing_token_holding_account = Some(governing_token_holding_account); + self + } + /// seeds=['governance', realm, governing_token_mint, governing_token_owner] + #[inline(always)] + pub fn token_owner_record( + &mut self, + token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_owner_record = Some(token_owner_record); + self + } + #[inline(always)] + pub fn governing_token_mint( + &mut self, + governing_token_mint: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governing_token_mint = Some(governing_token_mint); + self + } + /// GoverningTokenMint mint_authority + #[inline(always)] + pub fn governing_token_mint_authority_or_token_owner( + &mut self, + governing_token_mint_authority_or_token_owner: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction + .governing_token_mint_authority_or_token_owner = + Some(governing_token_mint_authority_or_token_owner); + self + } + /// seeds=['realm-config', realm] + #[inline(always)] + pub fn realm_config_account( + &mut self, + realm_config_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_config_account = Some(realm_config_account); + self + } + #[inline(always)] + pub fn token_program( + &mut self, + token_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_program = Some(token_program); + self + } + #[inline(always)] + pub fn amount(&mut self, amount: u64) -> &mut Self { + self.instruction.amount = Some(amount); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let args = RevokeGoverningTokensInstructionArgs { + amount: self.instruction.amount.clone().expect("amount is not set"), + }; + let instruction = RevokeGoverningTokensCpi { + __program: self.instruction.__program, + + realm_account: self + .instruction + .realm_account + .expect("realm_account is not set"), + + governing_token_holding_account: self + .instruction + .governing_token_holding_account + .expect("governing_token_holding_account is not set"), + + token_owner_record: self + .instruction + .token_owner_record + .expect("token_owner_record is not set"), + + governing_token_mint: self + .instruction + .governing_token_mint + .expect("governing_token_mint is not set"), + + governing_token_mint_authority_or_token_owner: self + .instruction + .governing_token_mint_authority_or_token_owner + .expect("governing_token_mint_authority_or_token_owner is not set"), + + realm_config_account: self + .instruction + .realm_config_account + .expect("realm_config_account is not set"), + + token_program: self + .instruction + .token_program + .expect("token_program is not set"), + __args: args, + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct RevokeGoverningTokensCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + realm_account: Option<&'b solana_account_info::AccountInfo<'a>>, + governing_token_holding_account: Option<&'b solana_account_info::AccountInfo<'a>>, + token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + governing_token_mint: Option<&'b solana_account_info::AccountInfo<'a>>, + governing_token_mint_authority_or_token_owner: Option<&'b solana_account_info::AccountInfo<'a>>, + realm_config_account: Option<&'b solana_account_info::AccountInfo<'a>>, + token_program: Option<&'b solana_account_info::AccountInfo<'a>>, + amount: Option, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/set_governance_config.rs b/e2e/governance/src/generated/instructions/set_governance_config.rs new file mode 100644 index 0000000..99ec8f7 --- /dev/null +++ b/e2e/governance/src/generated/instructions/set_governance_config.rs @@ -0,0 +1,329 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GovernanceConfig; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const SET_GOVERNANCE_CONFIG_DISCRIMINATOR: u8 = 19; + +/// Accounts. +#[derive(Debug)] +pub struct SetGovernanceConfig { + /// The governance account the config is for + pub governance_account: solana_pubkey::Pubkey, +} + +impl SetGovernanceConfig { + pub fn instruction( + &self, + args: SetGovernanceConfigInstructionArgs, + ) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(args, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + args: SetGovernanceConfigInstructionArgs, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(1 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + self.governance_account, + true, + )); + accounts.extend_from_slice(remaining_accounts); + let mut data = SetGovernanceConfigInstructionData::new() + .try_to_vec() + .unwrap(); + let mut args = args.try_to_vec().unwrap(); + data.append(&mut args); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct SetGovernanceConfigInstructionData { + discriminator: u8, +} + +impl SetGovernanceConfigInstructionData { + pub fn new() -> Self { + Self { discriminator: 19 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for SetGovernanceConfigInstructionData { + fn default() -> Self { + Self::new() + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct SetGovernanceConfigInstructionArgs { + pub config: GovernanceConfig, +} + +impl SetGovernanceConfigInstructionArgs { + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +/// Instruction builder for `SetGovernanceConfig`. +/// +/// ### Accounts: +/// +/// 0. `[writable, signer]` governance_account +#[derive(Clone, Debug, Default)] +pub struct SetGovernanceConfigBuilder { + governance_account: Option, + config: Option, + __remaining_accounts: Vec, +} + +impl SetGovernanceConfigBuilder { + pub fn new() -> Self { + Self::default() + } + /// The governance account the config is for + #[inline(always)] + pub fn governance_account(&mut self, governance_account: solana_pubkey::Pubkey) -> &mut Self { + self.governance_account = Some(governance_account); + self + } + #[inline(always)] + pub fn config(&mut self, config: GovernanceConfig) -> &mut Self { + self.config = Some(config); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = SetGovernanceConfig { + governance_account: self + .governance_account + .expect("governance_account is not set"), + }; + let args = SetGovernanceConfigInstructionArgs { + config: self.config.clone().expect("config is not set"), + }; + + accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) + } +} + +/// `set_governance_config` CPI accounts. +pub struct SetGovernanceConfigCpiAccounts<'a, 'b> { + /// The governance account the config is for + pub governance_account: &'b solana_account_info::AccountInfo<'a>, +} + +/// `set_governance_config` CPI instruction. +pub struct SetGovernanceConfigCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + /// The governance account the config is for + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + /// The arguments for the instruction. + pub __args: SetGovernanceConfigInstructionArgs, +} + +impl<'a, 'b> SetGovernanceConfigCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: SetGovernanceConfigCpiAccounts<'a, 'b>, + args: SetGovernanceConfigInstructionArgs, + ) -> Self { + Self { + __program: program, + governance_account: accounts.governance_account, + __args: args, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(1 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + *self.governance_account.key, + true, + )); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let mut data = SetGovernanceConfigInstructionData::new() + .try_to_vec() + .unwrap(); + let mut args = self.__args.try_to_vec().unwrap(); + data.append(&mut args); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(2 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.governance_account.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `SetGovernanceConfig` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[writable, signer]` governance_account +#[derive(Clone, Debug)] +pub struct SetGovernanceConfigCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> SetGovernanceConfigCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(SetGovernanceConfigCpiBuilderInstruction { + __program: program, + governance_account: None, + config: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + /// The governance account the config is for + #[inline(always)] + pub fn governance_account( + &mut self, + governance_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_account = Some(governance_account); + self + } + #[inline(always)] + pub fn config(&mut self, config: GovernanceConfig) -> &mut Self { + self.instruction.config = Some(config); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let args = SetGovernanceConfigInstructionArgs { + config: self.instruction.config.clone().expect("config is not set"), + }; + let instruction = SetGovernanceConfigCpi { + __program: self.instruction.__program, + + governance_account: self + .instruction + .governance_account + .expect("governance_account is not set"), + __args: args, + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct SetGovernanceConfigCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + governance_account: Option<&'b solana_account_info::AccountInfo<'a>>, + config: Option, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/set_governance_delegate.rs b/e2e/governance/src/generated/instructions/set_governance_delegate.rs new file mode 100644 index 0000000..d542369 --- /dev/null +++ b/e2e/governance/src/generated/instructions/set_governance_delegate.rs @@ -0,0 +1,376 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +pub const SET_GOVERNANCE_DELEGATE_DISCRIMINATOR: u8 = 3; + +/// Accounts. +#[derive(Debug)] +pub struct SetGovernanceDelegate { + /// Current governance delegate or governing token owner + pub current_delegate_or_owner: solana_pubkey::Pubkey, + + pub token_owner_record: solana_pubkey::Pubkey, +} + +impl SetGovernanceDelegate { + pub fn instruction( + &self, + args: SetGovernanceDelegateInstructionArgs, + ) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(args, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + args: SetGovernanceDelegateInstructionArgs, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(2 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.current_delegate_or_owner, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.token_owner_record, + false, + )); + accounts.extend_from_slice(remaining_accounts); + let mut data = SetGovernanceDelegateInstructionData::new() + .try_to_vec() + .unwrap(); + let mut args = args.try_to_vec().unwrap(); + data.append(&mut args); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct SetGovernanceDelegateInstructionData { + discriminator: u8, +} + +impl SetGovernanceDelegateInstructionData { + pub fn new() -> Self { + Self { discriminator: 3 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for SetGovernanceDelegateInstructionData { + fn default() -> Self { + Self::new() + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct SetGovernanceDelegateInstructionArgs { + pub new_governance_delegate: Option, +} + +impl SetGovernanceDelegateInstructionArgs { + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +/// Instruction builder for `SetGovernanceDelegate`. +/// +/// ### Accounts: +/// +/// 0. `[signer]` current_delegate_or_owner +/// 1. `[writable]` token_owner_record +#[derive(Clone, Debug, Default)] +pub struct SetGovernanceDelegateBuilder { + current_delegate_or_owner: Option, + token_owner_record: Option, + new_governance_delegate: Option, + __remaining_accounts: Vec, +} + +impl SetGovernanceDelegateBuilder { + pub fn new() -> Self { + Self::default() + } + /// Current governance delegate or governing token owner + #[inline(always)] + pub fn current_delegate_or_owner( + &mut self, + current_delegate_or_owner: solana_pubkey::Pubkey, + ) -> &mut Self { + self.current_delegate_or_owner = Some(current_delegate_or_owner); + self + } + #[inline(always)] + pub fn token_owner_record(&mut self, token_owner_record: solana_pubkey::Pubkey) -> &mut Self { + self.token_owner_record = Some(token_owner_record); + self + } + /// `[optional argument]` + #[inline(always)] + pub fn new_governance_delegate(&mut self, new_governance_delegate: Pubkey) -> &mut Self { + self.new_governance_delegate = Some(new_governance_delegate); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = SetGovernanceDelegate { + current_delegate_or_owner: self + .current_delegate_or_owner + .expect("current_delegate_or_owner is not set"), + token_owner_record: self + .token_owner_record + .expect("token_owner_record is not set"), + }; + let args = SetGovernanceDelegateInstructionArgs { + new_governance_delegate: self.new_governance_delegate.clone(), + }; + + accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) + } +} + +/// `set_governance_delegate` CPI accounts. +pub struct SetGovernanceDelegateCpiAccounts<'a, 'b> { + /// Current governance delegate or governing token owner + pub current_delegate_or_owner: &'b solana_account_info::AccountInfo<'a>, + + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, +} + +/// `set_governance_delegate` CPI instruction. +pub struct SetGovernanceDelegateCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + /// Current governance delegate or governing token owner + pub current_delegate_or_owner: &'b solana_account_info::AccountInfo<'a>, + + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + /// The arguments for the instruction. + pub __args: SetGovernanceDelegateInstructionArgs, +} + +impl<'a, 'b> SetGovernanceDelegateCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: SetGovernanceDelegateCpiAccounts<'a, 'b>, + args: SetGovernanceDelegateInstructionArgs, + ) -> Self { + Self { + __program: program, + current_delegate_or_owner: accounts.current_delegate_or_owner, + token_owner_record: accounts.token_owner_record, + __args: args, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(2 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.current_delegate_or_owner.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.token_owner_record.key, + false, + )); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let mut data = SetGovernanceDelegateInstructionData::new() + .try_to_vec() + .unwrap(); + let mut args = self.__args.try_to_vec().unwrap(); + data.append(&mut args); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(3 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.current_delegate_or_owner.clone()); + account_infos.push(self.token_owner_record.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `SetGovernanceDelegate` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[signer]` current_delegate_or_owner +/// 1. `[writable]` token_owner_record +#[derive(Clone, Debug)] +pub struct SetGovernanceDelegateCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> SetGovernanceDelegateCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(SetGovernanceDelegateCpiBuilderInstruction { + __program: program, + current_delegate_or_owner: None, + token_owner_record: None, + new_governance_delegate: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + /// Current governance delegate or governing token owner + #[inline(always)] + pub fn current_delegate_or_owner( + &mut self, + current_delegate_or_owner: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.current_delegate_or_owner = Some(current_delegate_or_owner); + self + } + #[inline(always)] + pub fn token_owner_record( + &mut self, + token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_owner_record = Some(token_owner_record); + self + } + /// `[optional argument]` + #[inline(always)] + pub fn new_governance_delegate(&mut self, new_governance_delegate: Pubkey) -> &mut Self { + self.instruction.new_governance_delegate = Some(new_governance_delegate); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let args = SetGovernanceDelegateInstructionArgs { + new_governance_delegate: self.instruction.new_governance_delegate.clone(), + }; + let instruction = SetGovernanceDelegateCpi { + __program: self.instruction.__program, + + current_delegate_or_owner: self + .instruction + .current_delegate_or_owner + .expect("current_delegate_or_owner is not set"), + + token_owner_record: self + .instruction + .token_owner_record + .expect("token_owner_record is not set"), + __args: args, + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct SetGovernanceDelegateCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + current_delegate_or_owner: Option<&'b solana_account_info::AccountInfo<'a>>, + token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + new_governance_delegate: Option, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/set_realm_authority.rs b/e2e/governance/src/generated/instructions/set_realm_authority.rs new file mode 100644 index 0000000..eeb20a8 --- /dev/null +++ b/e2e/governance/src/generated/instructions/set_realm_authority.rs @@ -0,0 +1,423 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::SetRealmAuthorityAction; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const SET_REALM_AUTHORITY_DISCRIMINATOR: u8 = 21; + +/// Accounts. +#[derive(Debug)] +pub struct SetRealmAuthority { + pub realm_account: solana_pubkey::Pubkey, + + pub realm_authority: solana_pubkey::Pubkey, + /// Must be one of the realm governances when set + pub new_realm_authority: Option, +} + +impl SetRealmAuthority { + pub fn instruction( + &self, + args: SetRealmAuthorityInstructionArgs, + ) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(args, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + args: SetRealmAuthorityInstructionArgs, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(3 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + self.realm_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_authority, + true, + )); + if let Some(new_realm_authority) = self.new_realm_authority { + accounts.push(solana_instruction::AccountMeta::new_readonly( + new_realm_authority, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + accounts.extend_from_slice(remaining_accounts); + let mut data = SetRealmAuthorityInstructionData::new() + .try_to_vec() + .unwrap(); + let mut args = args.try_to_vec().unwrap(); + data.append(&mut args); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct SetRealmAuthorityInstructionData { + discriminator: u8, +} + +impl SetRealmAuthorityInstructionData { + pub fn new() -> Self { + Self { discriminator: 21 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for SetRealmAuthorityInstructionData { + fn default() -> Self { + Self::new() + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct SetRealmAuthorityInstructionArgs { + pub action: SetRealmAuthorityAction, +} + +impl SetRealmAuthorityInstructionArgs { + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +/// Instruction builder for `SetRealmAuthority`. +/// +/// ### Accounts: +/// +/// 0. `[writable]` realm_account +/// 1. `[signer]` realm_authority +/// 2. `[optional]` new_realm_authority +#[derive(Clone, Debug, Default)] +pub struct SetRealmAuthorityBuilder { + realm_account: Option, + realm_authority: Option, + new_realm_authority: Option, + action: Option, + __remaining_accounts: Vec, +} + +impl SetRealmAuthorityBuilder { + pub fn new() -> Self { + Self::default() + } + #[inline(always)] + pub fn realm_account(&mut self, realm_account: solana_pubkey::Pubkey) -> &mut Self { + self.realm_account = Some(realm_account); + self + } + #[inline(always)] + pub fn realm_authority(&mut self, realm_authority: solana_pubkey::Pubkey) -> &mut Self { + self.realm_authority = Some(realm_authority); + self + } + /// `[optional account]` + /// Must be one of the realm governances when set + #[inline(always)] + pub fn new_realm_authority( + &mut self, + new_realm_authority: Option, + ) -> &mut Self { + self.new_realm_authority = new_realm_authority; + self + } + #[inline(always)] + pub fn action(&mut self, action: SetRealmAuthorityAction) -> &mut Self { + self.action = Some(action); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = SetRealmAuthority { + realm_account: self.realm_account.expect("realm_account is not set"), + realm_authority: self.realm_authority.expect("realm_authority is not set"), + new_realm_authority: self.new_realm_authority, + }; + let args = SetRealmAuthorityInstructionArgs { + action: self.action.clone().expect("action is not set"), + }; + + accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) + } +} + +/// `set_realm_authority` CPI accounts. +pub struct SetRealmAuthorityCpiAccounts<'a, 'b> { + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + + pub realm_authority: &'b solana_account_info::AccountInfo<'a>, + /// Must be one of the realm governances when set + pub new_realm_authority: Option<&'b solana_account_info::AccountInfo<'a>>, +} + +/// `set_realm_authority` CPI instruction. +pub struct SetRealmAuthorityCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + + pub realm_authority: &'b solana_account_info::AccountInfo<'a>, + /// Must be one of the realm governances when set + pub new_realm_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + /// The arguments for the instruction. + pub __args: SetRealmAuthorityInstructionArgs, +} + +impl<'a, 'b> SetRealmAuthorityCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: SetRealmAuthorityCpiAccounts<'a, 'b>, + args: SetRealmAuthorityInstructionArgs, + ) -> Self { + Self { + __program: program, + realm_account: accounts.realm_account, + realm_authority: accounts.realm_authority, + new_realm_authority: accounts.new_realm_authority, + __args: args, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(3 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + *self.realm_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_authority.key, + true, + )); + if let Some(new_realm_authority) = self.new_realm_authority { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *new_realm_authority.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let mut data = SetRealmAuthorityInstructionData::new() + .try_to_vec() + .unwrap(); + let mut args = self.__args.try_to_vec().unwrap(); + data.append(&mut args); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(4 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.realm_account.clone()); + account_infos.push(self.realm_authority.clone()); + if let Some(new_realm_authority) = self.new_realm_authority { + account_infos.push(new_realm_authority.clone()); + } + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `SetRealmAuthority` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[writable]` realm_account +/// 1. `[signer]` realm_authority +/// 2. `[optional]` new_realm_authority +#[derive(Clone, Debug)] +pub struct SetRealmAuthorityCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> SetRealmAuthorityCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(SetRealmAuthorityCpiBuilderInstruction { + __program: program, + realm_account: None, + realm_authority: None, + new_realm_authority: None, + action: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + #[inline(always)] + pub fn realm_account( + &mut self, + realm_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_account = Some(realm_account); + self + } + #[inline(always)] + pub fn realm_authority( + &mut self, + realm_authority: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_authority = Some(realm_authority); + self + } + /// `[optional account]` + /// Must be one of the realm governances when set + #[inline(always)] + pub fn new_realm_authority( + &mut self, + new_realm_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.new_realm_authority = new_realm_authority; + self + } + #[inline(always)] + pub fn action(&mut self, action: SetRealmAuthorityAction) -> &mut Self { + self.instruction.action = Some(action); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let args = SetRealmAuthorityInstructionArgs { + action: self.instruction.action.clone().expect("action is not set"), + }; + let instruction = SetRealmAuthorityCpi { + __program: self.instruction.__program, + + realm_account: self + .instruction + .realm_account + .expect("realm_account is not set"), + + realm_authority: self + .instruction + .realm_authority + .expect("realm_authority is not set"), + + new_realm_authority: self.instruction.new_realm_authority, + __args: args, + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct SetRealmAuthorityCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + realm_account: Option<&'b solana_account_info::AccountInfo<'a>>, + realm_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + new_realm_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + action: Option, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/set_realm_config.rs b/e2e/governance/src/generated/instructions/set_realm_config.rs new file mode 100644 index 0000000..ab27076 --- /dev/null +++ b/e2e/governance/src/generated/instructions/set_realm_config.rs @@ -0,0 +1,919 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::RealmConfigParams; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const SET_REALM_CONFIG_DISCRIMINATOR: u8 = 22; + +/// Accounts. +#[derive(Debug)] +pub struct SetRealmConfig { + pub realm_account: solana_pubkey::Pubkey, + + pub realm_authority: solana_pubkey::Pubkey, + /// Council Token Mint - optional. + /// Note: In the current version it's only possible to remove council mint (set it to None) + /// After setting council to None it won't be possible to withdraw the tokens from the Realm any longer. + /// If that's required then it must be done before executing this instruction + pub council_token_mint: Option, + /// Optional unless council is used. seeds=['governance', realm, council_mint] + pub council_token_holding_account: Option, + + pub system_program: solana_pubkey::Pubkey, + /// RealmConfig account. seeds=['realm-config', realm] + pub realm_config: solana_pubkey::Pubkey, + /// Optional Community Voter Weight Addin Program Id + pub community_voter_weight_addin_program_id: Option, + /// Optional Max Community Voter Weight Addin Program Id + pub max_community_voter_weight_addin_program_id: Option, + /// Optional Council Voter Weight Adding Program Id + pub council_voter_weight_addin_program_id: Option, + /// Optional Max Council Voter Weight Addin Program Id + pub max_council_voter_weight_addin_program_id: Option, + /// Optional Payer. Required if RealmConfig doesn't exist and needs to be created + pub payer: Option, +} + +impl SetRealmConfig { + pub fn instruction( + &self, + args: SetRealmConfigInstructionArgs, + ) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(args, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + args: SetRealmConfigInstructionArgs, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(11 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + self.realm_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_authority, + true, + )); + if let Some(council_token_mint) = self.council_token_mint { + accounts.push(solana_instruction::AccountMeta::new_readonly( + council_token_mint, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(council_token_holding_account) = self.council_token_holding_account { + accounts.push(solana_instruction::AccountMeta::new( + council_token_holding_account, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.system_program, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.realm_config, + false, + )); + if let Some(community_voter_weight_addin_program_id) = + self.community_voter_weight_addin_program_id + { + accounts.push(solana_instruction::AccountMeta::new_readonly( + community_voter_weight_addin_program_id, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(max_community_voter_weight_addin_program_id) = + self.max_community_voter_weight_addin_program_id + { + accounts.push(solana_instruction::AccountMeta::new_readonly( + max_community_voter_weight_addin_program_id, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(council_voter_weight_addin_program_id) = + self.council_voter_weight_addin_program_id + { + accounts.push(solana_instruction::AccountMeta::new_readonly( + council_voter_weight_addin_program_id, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(max_council_voter_weight_addin_program_id) = + self.max_council_voter_weight_addin_program_id + { + accounts.push(solana_instruction::AccountMeta::new_readonly( + max_council_voter_weight_addin_program_id, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(payer) = self.payer { + accounts.push(solana_instruction::AccountMeta::new_readonly(payer, true)); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + accounts.extend_from_slice(remaining_accounts); + let mut data = SetRealmConfigInstructionData::new().try_to_vec().unwrap(); + let mut args = args.try_to_vec().unwrap(); + data.append(&mut args); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct SetRealmConfigInstructionData { + discriminator: u8, +} + +impl SetRealmConfigInstructionData { + pub fn new() -> Self { + Self { discriminator: 22 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for SetRealmConfigInstructionData { + fn default() -> Self { + Self::new() + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct SetRealmConfigInstructionArgs { + pub config_args: RealmConfigParams, +} + +impl SetRealmConfigInstructionArgs { + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +/// Instruction builder for `SetRealmConfig`. +/// +/// ### Accounts: +/// +/// 0. `[writable]` realm_account +/// 1. `[signer]` realm_authority +/// 2. `[optional]` council_token_mint +/// 3. `[writable, optional]` council_token_holding_account +/// 4. `[optional]` system_program (default to `11111111111111111111111111111111`) +/// 5. `[writable]` realm_config +/// 6. `[optional]` community_voter_weight_addin_program_id +/// 7. `[optional]` max_community_voter_weight_addin_program_id +/// 8. `[optional]` council_voter_weight_addin_program_id +/// 9. `[optional]` max_council_voter_weight_addin_program_id +/// 10. `[signer, optional]` payer +#[derive(Clone, Debug, Default)] +pub struct SetRealmConfigBuilder { + realm_account: Option, + realm_authority: Option, + council_token_mint: Option, + council_token_holding_account: Option, + system_program: Option, + realm_config: Option, + community_voter_weight_addin_program_id: Option, + max_community_voter_weight_addin_program_id: Option, + council_voter_weight_addin_program_id: Option, + max_council_voter_weight_addin_program_id: Option, + payer: Option, + config_args: Option, + __remaining_accounts: Vec, +} + +impl SetRealmConfigBuilder { + pub fn new() -> Self { + Self::default() + } + #[inline(always)] + pub fn realm_account(&mut self, realm_account: solana_pubkey::Pubkey) -> &mut Self { + self.realm_account = Some(realm_account); + self + } + #[inline(always)] + pub fn realm_authority(&mut self, realm_authority: solana_pubkey::Pubkey) -> &mut Self { + self.realm_authority = Some(realm_authority); + self + } + /// `[optional account]` + /// Council Token Mint - optional. + /// Note: In the current version it's only possible to remove council mint (set it to None) + /// After setting council to None it won't be possible to withdraw the tokens from the Realm any longer. + /// If that's required then it must be done before executing this instruction + #[inline(always)] + pub fn council_token_mint( + &mut self, + council_token_mint: Option, + ) -> &mut Self { + self.council_token_mint = council_token_mint; + self + } + /// `[optional account]` + /// Optional unless council is used. seeds=['governance', realm, council_mint] + #[inline(always)] + pub fn council_token_holding_account( + &mut self, + council_token_holding_account: Option, + ) -> &mut Self { + self.council_token_holding_account = council_token_holding_account; + self + } + /// `[optional account, default to '11111111111111111111111111111111']` + #[inline(always)] + pub fn system_program(&mut self, system_program: solana_pubkey::Pubkey) -> &mut Self { + self.system_program = Some(system_program); + self + } + /// RealmConfig account. seeds=['realm-config', realm] + #[inline(always)] + pub fn realm_config(&mut self, realm_config: solana_pubkey::Pubkey) -> &mut Self { + self.realm_config = Some(realm_config); + self + } + /// `[optional account]` + /// Optional Community Voter Weight Addin Program Id + #[inline(always)] + pub fn community_voter_weight_addin_program_id( + &mut self, + community_voter_weight_addin_program_id: Option, + ) -> &mut Self { + self.community_voter_weight_addin_program_id = community_voter_weight_addin_program_id; + self + } + /// `[optional account]` + /// Optional Max Community Voter Weight Addin Program Id + #[inline(always)] + pub fn max_community_voter_weight_addin_program_id( + &mut self, + max_community_voter_weight_addin_program_id: Option, + ) -> &mut Self { + self.max_community_voter_weight_addin_program_id = + max_community_voter_weight_addin_program_id; + self + } + /// `[optional account]` + /// Optional Council Voter Weight Adding Program Id + #[inline(always)] + pub fn council_voter_weight_addin_program_id( + &mut self, + council_voter_weight_addin_program_id: Option, + ) -> &mut Self { + self.council_voter_weight_addin_program_id = council_voter_weight_addin_program_id; + self + } + /// `[optional account]` + /// Optional Max Council Voter Weight Addin Program Id + #[inline(always)] + pub fn max_council_voter_weight_addin_program_id( + &mut self, + max_council_voter_weight_addin_program_id: Option, + ) -> &mut Self { + self.max_council_voter_weight_addin_program_id = max_council_voter_weight_addin_program_id; + self + } + /// `[optional account]` + /// Optional Payer. Required if RealmConfig doesn't exist and needs to be created + #[inline(always)] + pub fn payer(&mut self, payer: Option) -> &mut Self { + self.payer = payer; + self + } + #[inline(always)] + pub fn config_args(&mut self, config_args: RealmConfigParams) -> &mut Self { + self.config_args = Some(config_args); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = SetRealmConfig { + realm_account: self.realm_account.expect("realm_account is not set"), + realm_authority: self.realm_authority.expect("realm_authority is not set"), + council_token_mint: self.council_token_mint, + council_token_holding_account: self.council_token_holding_account, + system_program: self + .system_program + .unwrap_or(solana_pubkey::pubkey!("11111111111111111111111111111111")), + realm_config: self.realm_config.expect("realm_config is not set"), + community_voter_weight_addin_program_id: self.community_voter_weight_addin_program_id, + max_community_voter_weight_addin_program_id: self + .max_community_voter_weight_addin_program_id, + council_voter_weight_addin_program_id: self.council_voter_weight_addin_program_id, + max_council_voter_weight_addin_program_id: self + .max_council_voter_weight_addin_program_id, + payer: self.payer, + }; + let args = SetRealmConfigInstructionArgs { + config_args: self.config_args.clone().expect("config_args is not set"), + }; + + accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) + } +} + +/// `set_realm_config` CPI accounts. +pub struct SetRealmConfigCpiAccounts<'a, 'b> { + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + + pub realm_authority: &'b solana_account_info::AccountInfo<'a>, + /// Council Token Mint - optional. + /// Note: In the current version it's only possible to remove council mint (set it to None) + /// After setting council to None it won't be possible to withdraw the tokens from the Realm any longer. + /// If that's required then it must be done before executing this instruction + pub council_token_mint: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional unless council is used. seeds=['governance', realm, council_mint] + pub council_token_holding_account: Option<&'b solana_account_info::AccountInfo<'a>>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, + /// RealmConfig account. seeds=['realm-config', realm] + pub realm_config: &'b solana_account_info::AccountInfo<'a>, + /// Optional Community Voter Weight Addin Program Id + pub community_voter_weight_addin_program_id: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional Max Community Voter Weight Addin Program Id + pub max_community_voter_weight_addin_program_id: + Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional Council Voter Weight Adding Program Id + pub council_voter_weight_addin_program_id: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional Max Council Voter Weight Addin Program Id + pub max_council_voter_weight_addin_program_id: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional Payer. Required if RealmConfig doesn't exist and needs to be created + pub payer: Option<&'b solana_account_info::AccountInfo<'a>>, +} + +/// `set_realm_config` CPI instruction. +pub struct SetRealmConfigCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + + pub realm_authority: &'b solana_account_info::AccountInfo<'a>, + /// Council Token Mint - optional. + /// Note: In the current version it's only possible to remove council mint (set it to None) + /// After setting council to None it won't be possible to withdraw the tokens from the Realm any longer. + /// If that's required then it must be done before executing this instruction + pub council_token_mint: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional unless council is used. seeds=['governance', realm, council_mint] + pub council_token_holding_account: Option<&'b solana_account_info::AccountInfo<'a>>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, + /// RealmConfig account. seeds=['realm-config', realm] + pub realm_config: &'b solana_account_info::AccountInfo<'a>, + /// Optional Community Voter Weight Addin Program Id + pub community_voter_weight_addin_program_id: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional Max Community Voter Weight Addin Program Id + pub max_community_voter_weight_addin_program_id: + Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional Council Voter Weight Adding Program Id + pub council_voter_weight_addin_program_id: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional Max Council Voter Weight Addin Program Id + pub max_council_voter_weight_addin_program_id: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Optional Payer. Required if RealmConfig doesn't exist and needs to be created + pub payer: Option<&'b solana_account_info::AccountInfo<'a>>, + /// The arguments for the instruction. + pub __args: SetRealmConfigInstructionArgs, +} + +impl<'a, 'b> SetRealmConfigCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: SetRealmConfigCpiAccounts<'a, 'b>, + args: SetRealmConfigInstructionArgs, + ) -> Self { + Self { + __program: program, + realm_account: accounts.realm_account, + realm_authority: accounts.realm_authority, + council_token_mint: accounts.council_token_mint, + council_token_holding_account: accounts.council_token_holding_account, + system_program: accounts.system_program, + realm_config: accounts.realm_config, + community_voter_weight_addin_program_id: accounts + .community_voter_weight_addin_program_id, + max_community_voter_weight_addin_program_id: accounts + .max_community_voter_weight_addin_program_id, + council_voter_weight_addin_program_id: accounts.council_voter_weight_addin_program_id, + max_council_voter_weight_addin_program_id: accounts + .max_council_voter_weight_addin_program_id, + payer: accounts.payer, + __args: args, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(11 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + *self.realm_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_authority.key, + true, + )); + if let Some(council_token_mint) = self.council_token_mint { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *council_token_mint.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(council_token_holding_account) = self.council_token_holding_account { + accounts.push(solana_instruction::AccountMeta::new( + *council_token_holding_account.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.system_program.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.realm_config.key, + false, + )); + if let Some(community_voter_weight_addin_program_id) = + self.community_voter_weight_addin_program_id + { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *community_voter_weight_addin_program_id.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(max_community_voter_weight_addin_program_id) = + self.max_community_voter_weight_addin_program_id + { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *max_community_voter_weight_addin_program_id.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(council_voter_weight_addin_program_id) = + self.council_voter_weight_addin_program_id + { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *council_voter_weight_addin_program_id.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(max_council_voter_weight_addin_program_id) = + self.max_council_voter_weight_addin_program_id + { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *max_council_voter_weight_addin_program_id.key, + false, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + if let Some(payer) = self.payer { + accounts.push(solana_instruction::AccountMeta::new_readonly( + *payer.key, true, + )); + } else { + accounts.push(solana_instruction::AccountMeta::new_readonly( + crate::SPL_GOVERNANCE_ID, + false, + )); + } + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let mut data = SetRealmConfigInstructionData::new().try_to_vec().unwrap(); + let mut args = self.__args.try_to_vec().unwrap(); + data.append(&mut args); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(12 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.realm_account.clone()); + account_infos.push(self.realm_authority.clone()); + if let Some(council_token_mint) = self.council_token_mint { + account_infos.push(council_token_mint.clone()); + } + if let Some(council_token_holding_account) = self.council_token_holding_account { + account_infos.push(council_token_holding_account.clone()); + } + account_infos.push(self.system_program.clone()); + account_infos.push(self.realm_config.clone()); + if let Some(community_voter_weight_addin_program_id) = + self.community_voter_weight_addin_program_id + { + account_infos.push(community_voter_weight_addin_program_id.clone()); + } + if let Some(max_community_voter_weight_addin_program_id) = + self.max_community_voter_weight_addin_program_id + { + account_infos.push(max_community_voter_weight_addin_program_id.clone()); + } + if let Some(council_voter_weight_addin_program_id) = + self.council_voter_weight_addin_program_id + { + account_infos.push(council_voter_weight_addin_program_id.clone()); + } + if let Some(max_council_voter_weight_addin_program_id) = + self.max_council_voter_weight_addin_program_id + { + account_infos.push(max_council_voter_weight_addin_program_id.clone()); + } + if let Some(payer) = self.payer { + account_infos.push(payer.clone()); + } + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `SetRealmConfig` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[writable]` realm_account +/// 1. `[signer]` realm_authority +/// 2. `[optional]` council_token_mint +/// 3. `[writable, optional]` council_token_holding_account +/// 4. `[]` system_program +/// 5. `[writable]` realm_config +/// 6. `[optional]` community_voter_weight_addin_program_id +/// 7. `[optional]` max_community_voter_weight_addin_program_id +/// 8. `[optional]` council_voter_weight_addin_program_id +/// 9. `[optional]` max_council_voter_weight_addin_program_id +/// 10. `[signer, optional]` payer +#[derive(Clone, Debug)] +pub struct SetRealmConfigCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> SetRealmConfigCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(SetRealmConfigCpiBuilderInstruction { + __program: program, + realm_account: None, + realm_authority: None, + council_token_mint: None, + council_token_holding_account: None, + system_program: None, + realm_config: None, + community_voter_weight_addin_program_id: None, + max_community_voter_weight_addin_program_id: None, + council_voter_weight_addin_program_id: None, + max_council_voter_weight_addin_program_id: None, + payer: None, + config_args: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + #[inline(always)] + pub fn realm_account( + &mut self, + realm_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_account = Some(realm_account); + self + } + #[inline(always)] + pub fn realm_authority( + &mut self, + realm_authority: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_authority = Some(realm_authority); + self + } + /// `[optional account]` + /// Council Token Mint - optional. + /// Note: In the current version it's only possible to remove council mint (set it to None) + /// After setting council to None it won't be possible to withdraw the tokens from the Realm any longer. + /// If that's required then it must be done before executing this instruction + #[inline(always)] + pub fn council_token_mint( + &mut self, + council_token_mint: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.council_token_mint = council_token_mint; + self + } + /// `[optional account]` + /// Optional unless council is used. seeds=['governance', realm, council_mint] + #[inline(always)] + pub fn council_token_holding_account( + &mut self, + council_token_holding_account: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.council_token_holding_account = council_token_holding_account; + self + } + #[inline(always)] + pub fn system_program( + &mut self, + system_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.system_program = Some(system_program); + self + } + /// RealmConfig account. seeds=['realm-config', realm] + #[inline(always)] + pub fn realm_config( + &mut self, + realm_config: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_config = Some(realm_config); + self + } + /// `[optional account]` + /// Optional Community Voter Weight Addin Program Id + #[inline(always)] + pub fn community_voter_weight_addin_program_id( + &mut self, + community_voter_weight_addin_program_id: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.community_voter_weight_addin_program_id = + community_voter_weight_addin_program_id; + self + } + /// `[optional account]` + /// Optional Max Community Voter Weight Addin Program Id + #[inline(always)] + pub fn max_community_voter_weight_addin_program_id( + &mut self, + max_community_voter_weight_addin_program_id: Option< + &'b solana_account_info::AccountInfo<'a>, + >, + ) -> &mut Self { + self.instruction.max_community_voter_weight_addin_program_id = + max_community_voter_weight_addin_program_id; + self + } + /// `[optional account]` + /// Optional Council Voter Weight Adding Program Id + #[inline(always)] + pub fn council_voter_weight_addin_program_id( + &mut self, + council_voter_weight_addin_program_id: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.council_voter_weight_addin_program_id = + council_voter_weight_addin_program_id; + self + } + /// `[optional account]` + /// Optional Max Council Voter Weight Addin Program Id + #[inline(always)] + pub fn max_council_voter_weight_addin_program_id( + &mut self, + max_council_voter_weight_addin_program_id: Option<&'b solana_account_info::AccountInfo<'a>>, + ) -> &mut Self { + self.instruction.max_council_voter_weight_addin_program_id = + max_council_voter_weight_addin_program_id; + self + } + /// `[optional account]` + /// Optional Payer. Required if RealmConfig doesn't exist and needs to be created + #[inline(always)] + pub fn payer(&mut self, payer: Option<&'b solana_account_info::AccountInfo<'a>>) -> &mut Self { + self.instruction.payer = payer; + self + } + #[inline(always)] + pub fn config_args(&mut self, config_args: RealmConfigParams) -> &mut Self { + self.instruction.config_args = Some(config_args); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let args = SetRealmConfigInstructionArgs { + config_args: self + .instruction + .config_args + .clone() + .expect("config_args is not set"), + }; + let instruction = SetRealmConfigCpi { + __program: self.instruction.__program, + + realm_account: self + .instruction + .realm_account + .expect("realm_account is not set"), + + realm_authority: self + .instruction + .realm_authority + .expect("realm_authority is not set"), + + council_token_mint: self.instruction.council_token_mint, + + council_token_holding_account: self.instruction.council_token_holding_account, + + system_program: self + .instruction + .system_program + .expect("system_program is not set"), + + realm_config: self + .instruction + .realm_config + .expect("realm_config is not set"), + + community_voter_weight_addin_program_id: self + .instruction + .community_voter_weight_addin_program_id, + + max_community_voter_weight_addin_program_id: self + .instruction + .max_community_voter_weight_addin_program_id, + + council_voter_weight_addin_program_id: self + .instruction + .council_voter_weight_addin_program_id, + + max_council_voter_weight_addin_program_id: self + .instruction + .max_council_voter_weight_addin_program_id, + + payer: self.instruction.payer, + __args: args, + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct SetRealmConfigCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + realm_account: Option<&'b solana_account_info::AccountInfo<'a>>, + realm_authority: Option<&'b solana_account_info::AccountInfo<'a>>, + council_token_mint: Option<&'b solana_account_info::AccountInfo<'a>>, + council_token_holding_account: Option<&'b solana_account_info::AccountInfo<'a>>, + system_program: Option<&'b solana_account_info::AccountInfo<'a>>, + realm_config: Option<&'b solana_account_info::AccountInfo<'a>>, + community_voter_weight_addin_program_id: Option<&'b solana_account_info::AccountInfo<'a>>, + max_community_voter_weight_addin_program_id: Option<&'b solana_account_info::AccountInfo<'a>>, + council_voter_weight_addin_program_id: Option<&'b solana_account_info::AccountInfo<'a>>, + max_council_voter_weight_addin_program_id: Option<&'b solana_account_info::AccountInfo<'a>>, + payer: Option<&'b solana_account_info::AccountInfo<'a>>, + config_args: Option, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/sign_off_proposal.rs b/e2e/governance/src/generated/instructions/sign_off_proposal.rs new file mode 100644 index 0000000..436fa66 --- /dev/null +++ b/e2e/governance/src/generated/instructions/sign_off_proposal.rs @@ -0,0 +1,454 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const SIGN_OFF_PROPOSAL_DISCRIMINATOR: u8 = 12; + +/// Accounts. +#[derive(Debug)] +pub struct SignOffProposal { + pub realm_account: solana_pubkey::Pubkey, + + pub governance_account: solana_pubkey::Pubkey, + + pub proposal_account: solana_pubkey::Pubkey, + /// Signatory account signing off the Proposal. + /// Or Proposal owner if the owner hasn't appointed any signatories + pub signatory_account: solana_pubkey::Pubkey, + /// TokenOwnerRecord for the Proposal owner, required when the owner signs off the Proposal. + /// Or `[writable]` SignatoryRecord account, required when non owner signs off the Proposal + pub token_owner_record: solana_pubkey::Pubkey, +} + +impl SignOffProposal { + pub fn instruction(&self) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(&[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(5 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governance_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.proposal_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.signatory_account, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.token_owner_record, + false, + )); + accounts.extend_from_slice(remaining_accounts); + let data = SignOffProposalInstructionData::new().try_to_vec().unwrap(); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct SignOffProposalInstructionData { + discriminator: u8, +} + +impl SignOffProposalInstructionData { + pub fn new() -> Self { + Self { discriminator: 12 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for SignOffProposalInstructionData { + fn default() -> Self { + Self::new() + } +} + +/// Instruction builder for `SignOffProposal`. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[]` governance_account +/// 2. `[writable]` proposal_account +/// 3. `[signer]` signatory_account +/// 4. `[writable]` token_owner_record +#[derive(Clone, Debug, Default)] +pub struct SignOffProposalBuilder { + realm_account: Option, + governance_account: Option, + proposal_account: Option, + signatory_account: Option, + token_owner_record: Option, + __remaining_accounts: Vec, +} + +impl SignOffProposalBuilder { + pub fn new() -> Self { + Self::default() + } + #[inline(always)] + pub fn realm_account(&mut self, realm_account: solana_pubkey::Pubkey) -> &mut Self { + self.realm_account = Some(realm_account); + self + } + #[inline(always)] + pub fn governance_account(&mut self, governance_account: solana_pubkey::Pubkey) -> &mut Self { + self.governance_account = Some(governance_account); + self + } + #[inline(always)] + pub fn proposal_account(&mut self, proposal_account: solana_pubkey::Pubkey) -> &mut Self { + self.proposal_account = Some(proposal_account); + self + } + /// Signatory account signing off the Proposal. + /// Or Proposal owner if the owner hasn't appointed any signatories + #[inline(always)] + pub fn signatory_account(&mut self, signatory_account: solana_pubkey::Pubkey) -> &mut Self { + self.signatory_account = Some(signatory_account); + self + } + /// TokenOwnerRecord for the Proposal owner, required when the owner signs off the Proposal. + /// Or `[writable]` SignatoryRecord account, required when non owner signs off the Proposal + #[inline(always)] + pub fn token_owner_record(&mut self, token_owner_record: solana_pubkey::Pubkey) -> &mut Self { + self.token_owner_record = Some(token_owner_record); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = SignOffProposal { + realm_account: self.realm_account.expect("realm_account is not set"), + governance_account: self + .governance_account + .expect("governance_account is not set"), + proposal_account: self.proposal_account.expect("proposal_account is not set"), + signatory_account: self + .signatory_account + .expect("signatory_account is not set"), + token_owner_record: self + .token_owner_record + .expect("token_owner_record is not set"), + }; + + accounts.instruction_with_remaining_accounts(&self.__remaining_accounts) + } +} + +/// `sign_off_proposal` CPI accounts. +pub struct SignOffProposalCpiAccounts<'a, 'b> { + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// Signatory account signing off the Proposal. + /// Or Proposal owner if the owner hasn't appointed any signatories + pub signatory_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord for the Proposal owner, required when the owner signs off the Proposal. + /// Or `[writable]` SignatoryRecord account, required when non owner signs off the Proposal + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, +} + +/// `sign_off_proposal` CPI instruction. +pub struct SignOffProposalCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + + pub governance_account: &'b solana_account_info::AccountInfo<'a>, + + pub proposal_account: &'b solana_account_info::AccountInfo<'a>, + /// Signatory account signing off the Proposal. + /// Or Proposal owner if the owner hasn't appointed any signatories + pub signatory_account: &'b solana_account_info::AccountInfo<'a>, + /// TokenOwnerRecord for the Proposal owner, required when the owner signs off the Proposal. + /// Or `[writable]` SignatoryRecord account, required when non owner signs off the Proposal + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, +} + +impl<'a, 'b> SignOffProposalCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: SignOffProposalCpiAccounts<'a, 'b>, + ) -> Self { + Self { + __program: program, + realm_account: accounts.realm_account, + governance_account: accounts.governance_account, + proposal_account: accounts.proposal_account, + signatory_account: accounts.signatory_account, + token_owner_record: accounts.token_owner_record, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(5 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governance_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.proposal_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.signatory_account.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.token_owner_record.key, + false, + )); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let data = SignOffProposalInstructionData::new().try_to_vec().unwrap(); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(6 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.realm_account.clone()); + account_infos.push(self.governance_account.clone()); + account_infos.push(self.proposal_account.clone()); + account_infos.push(self.signatory_account.clone()); + account_infos.push(self.token_owner_record.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `SignOffProposal` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[]` governance_account +/// 2. `[writable]` proposal_account +/// 3. `[signer]` signatory_account +/// 4. `[writable]` token_owner_record +#[derive(Clone, Debug)] +pub struct SignOffProposalCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> SignOffProposalCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(SignOffProposalCpiBuilderInstruction { + __program: program, + realm_account: None, + governance_account: None, + proposal_account: None, + signatory_account: None, + token_owner_record: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + #[inline(always)] + pub fn realm_account( + &mut self, + realm_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_account = Some(realm_account); + self + } + #[inline(always)] + pub fn governance_account( + &mut self, + governance_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governance_account = Some(governance_account); + self + } + #[inline(always)] + pub fn proposal_account( + &mut self, + proposal_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.proposal_account = Some(proposal_account); + self + } + /// Signatory account signing off the Proposal. + /// Or Proposal owner if the owner hasn't appointed any signatories + #[inline(always)] + pub fn signatory_account( + &mut self, + signatory_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.signatory_account = Some(signatory_account); + self + } + /// TokenOwnerRecord for the Proposal owner, required when the owner signs off the Proposal. + /// Or `[writable]` SignatoryRecord account, required when non owner signs off the Proposal + #[inline(always)] + pub fn token_owner_record( + &mut self, + token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_owner_record = Some(token_owner_record); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let instruction = SignOffProposalCpi { + __program: self.instruction.__program, + + realm_account: self + .instruction + .realm_account + .expect("realm_account is not set"), + + governance_account: self + .instruction + .governance_account + .expect("governance_account is not set"), + + proposal_account: self + .instruction + .proposal_account + .expect("proposal_account is not set"), + + signatory_account: self + .instruction + .signatory_account + .expect("signatory_account is not set"), + + token_owner_record: self + .instruction + .token_owner_record + .expect("token_owner_record is not set"), + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct SignOffProposalCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + realm_account: Option<&'b solana_account_info::AccountInfo<'a>>, + governance_account: Option<&'b solana_account_info::AccountInfo<'a>>, + proposal_account: Option<&'b solana_account_info::AccountInfo<'a>>, + signatory_account: Option<&'b solana_account_info::AccountInfo<'a>>, + token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/update_program_metadata.rs b/e2e/governance/src/generated/instructions/update_program_metadata.rs new file mode 100644 index 0000000..fbb3cfa --- /dev/null +++ b/e2e/governance/src/generated/instructions/update_program_metadata.rs @@ -0,0 +1,363 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const UPDATE_PROGRAM_METADATA_DISCRIMINATOR: u8 = 24; + +/// Accounts. +#[derive(Debug)] +pub struct UpdateProgramMetadata { + /// seeds=['metadata'] + pub program_metadata_account: solana_pubkey::Pubkey, + + pub payer: solana_pubkey::Pubkey, + + pub system_program: solana_pubkey::Pubkey, +} + +impl UpdateProgramMetadata { + pub fn instruction(&self) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(&[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(3 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + self.program_metadata_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.payer, true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.system_program, + false, + )); + accounts.extend_from_slice(remaining_accounts); + let data = UpdateProgramMetadataInstructionData::new() + .try_to_vec() + .unwrap(); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct UpdateProgramMetadataInstructionData { + discriminator: u8, +} + +impl UpdateProgramMetadataInstructionData { + pub fn new() -> Self { + Self { discriminator: 24 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for UpdateProgramMetadataInstructionData { + fn default() -> Self { + Self::new() + } +} + +/// Instruction builder for `UpdateProgramMetadata`. +/// +/// ### Accounts: +/// +/// 0. `[writable]` program_metadata_account +/// 1. `[signer]` payer +/// 2. `[optional]` system_program (default to `11111111111111111111111111111111`) +#[derive(Clone, Debug, Default)] +pub struct UpdateProgramMetadataBuilder { + program_metadata_account: Option, + payer: Option, + system_program: Option, + __remaining_accounts: Vec, +} + +impl UpdateProgramMetadataBuilder { + pub fn new() -> Self { + Self::default() + } + /// seeds=['metadata'] + #[inline(always)] + pub fn program_metadata_account( + &mut self, + program_metadata_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.program_metadata_account = Some(program_metadata_account); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: solana_pubkey::Pubkey) -> &mut Self { + self.payer = Some(payer); + self + } + /// `[optional account, default to '11111111111111111111111111111111']` + #[inline(always)] + pub fn system_program(&mut self, system_program: solana_pubkey::Pubkey) -> &mut Self { + self.system_program = Some(system_program); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = UpdateProgramMetadata { + program_metadata_account: self + .program_metadata_account + .expect("program_metadata_account is not set"), + payer: self.payer.expect("payer is not set"), + system_program: self + .system_program + .unwrap_or(solana_pubkey::pubkey!("11111111111111111111111111111111")), + }; + + accounts.instruction_with_remaining_accounts(&self.__remaining_accounts) + } +} + +/// `update_program_metadata` CPI accounts. +pub struct UpdateProgramMetadataCpiAccounts<'a, 'b> { + /// seeds=['metadata'] + pub program_metadata_account: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, +} + +/// `update_program_metadata` CPI instruction. +pub struct UpdateProgramMetadataCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['metadata'] + pub program_metadata_account: &'b solana_account_info::AccountInfo<'a>, + + pub payer: &'b solana_account_info::AccountInfo<'a>, + + pub system_program: &'b solana_account_info::AccountInfo<'a>, +} + +impl<'a, 'b> UpdateProgramMetadataCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: UpdateProgramMetadataCpiAccounts<'a, 'b>, + ) -> Self { + Self { + __program: program, + program_metadata_account: accounts.program_metadata_account, + payer: accounts.payer, + system_program: accounts.system_program, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(3 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new( + *self.program_metadata_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.payer.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.system_program.key, + false, + )); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let data = UpdateProgramMetadataInstructionData::new() + .try_to_vec() + .unwrap(); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(4 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.program_metadata_account.clone()); + account_infos.push(self.payer.clone()); + account_infos.push(self.system_program.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `UpdateProgramMetadata` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[writable]` program_metadata_account +/// 1. `[signer]` payer +/// 2. `[]` system_program +#[derive(Clone, Debug)] +pub struct UpdateProgramMetadataCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> UpdateProgramMetadataCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(UpdateProgramMetadataCpiBuilderInstruction { + __program: program, + program_metadata_account: None, + payer: None, + system_program: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + /// seeds=['metadata'] + #[inline(always)] + pub fn program_metadata_account( + &mut self, + program_metadata_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.program_metadata_account = Some(program_metadata_account); + self + } + #[inline(always)] + pub fn payer(&mut self, payer: &'b solana_account_info::AccountInfo<'a>) -> &mut Self { + self.instruction.payer = Some(payer); + self + } + #[inline(always)] + pub fn system_program( + &mut self, + system_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.system_program = Some(system_program); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let instruction = UpdateProgramMetadataCpi { + __program: self.instruction.__program, + + program_metadata_account: self + .instruction + .program_metadata_account + .expect("program_metadata_account is not set"), + + payer: self.instruction.payer.expect("payer is not set"), + + system_program: self + .instruction + .system_program + .expect("system_program is not set"), + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct UpdateProgramMetadataCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + program_metadata_account: Option<&'b solana_account_info::AccountInfo<'a>>, + payer: Option<&'b solana_account_info::AccountInfo<'a>>, + system_program: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/instructions/withdraw_governing_tokens.rs b/e2e/governance/src/generated/instructions/withdraw_governing_tokens.rs new file mode 100644 index 0000000..434989f --- /dev/null +++ b/e2e/governance/src/generated/instructions/withdraw_governing_tokens.rs @@ -0,0 +1,552 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +pub const WITHDRAW_GOVERNING_TOKENS_DISCRIMINATOR: u8 = 2; + +/// Accounts. +#[derive(Debug)] +pub struct WithdrawGoverningTokens { + pub realm_account: solana_pubkey::Pubkey, + /// seeds=['governance', realm, governing_token_mint] + pub governing_token_holding_account: solana_pubkey::Pubkey, + /// All tokens will be transferred to this account + pub governing_token_destination_account: solana_pubkey::Pubkey, + + pub governing_token_owner_account: solana_pubkey::Pubkey, + /// seeds=['governance',realm, governing_token_mint, governing_token_owner] + pub token_owner_record: solana_pubkey::Pubkey, + + pub token_program: solana_pubkey::Pubkey, + /// seeds=['realm-config', realm] + pub realm_config_account: solana_pubkey::Pubkey, +} + +impl WithdrawGoverningTokens { + pub fn instruction(&self) -> solana_instruction::Instruction { + self.instruction_with_remaining_accounts(&[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + remaining_accounts: &[solana_instruction::AccountMeta], + ) -> solana_instruction::Instruction { + let mut accounts = Vec::with_capacity(7 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.governing_token_holding_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.governing_token_destination_account, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.governing_token_owner_account, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + self.token_owner_record, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.token_program, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + self.realm_config_account, + false, + )); + accounts.extend_from_slice(remaining_accounts); + let data = WithdrawGoverningTokensInstructionData::new() + .try_to_vec() + .unwrap(); + + solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct WithdrawGoverningTokensInstructionData { + discriminator: u8, +} + +impl WithdrawGoverningTokensInstructionData { + pub fn new() -> Self { + Self { discriminator: 2 } + } + + pub(crate) fn try_to_vec(&self) -> Result, std::io::Error> { + borsh::to_vec(self) + } +} + +impl Default for WithdrawGoverningTokensInstructionData { + fn default() -> Self { + Self::new() + } +} + +/// Instruction builder for `WithdrawGoverningTokens`. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[writable]` governing_token_holding_account +/// 2. `[writable]` governing_token_destination_account +/// 3. `[signer]` governing_token_owner_account +/// 4. `[writable]` token_owner_record +/// 5. `[optional]` token_program (default to `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`) +/// 6. `[]` realm_config_account +#[derive(Clone, Debug, Default)] +pub struct WithdrawGoverningTokensBuilder { + realm_account: Option, + governing_token_holding_account: Option, + governing_token_destination_account: Option, + governing_token_owner_account: Option, + token_owner_record: Option, + token_program: Option, + realm_config_account: Option, + __remaining_accounts: Vec, +} + +impl WithdrawGoverningTokensBuilder { + pub fn new() -> Self { + Self::default() + } + #[inline(always)] + pub fn realm_account(&mut self, realm_account: solana_pubkey::Pubkey) -> &mut Self { + self.realm_account = Some(realm_account); + self + } + /// seeds=['governance', realm, governing_token_mint] + #[inline(always)] + pub fn governing_token_holding_account( + &mut self, + governing_token_holding_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governing_token_holding_account = Some(governing_token_holding_account); + self + } + /// All tokens will be transferred to this account + #[inline(always)] + pub fn governing_token_destination_account( + &mut self, + governing_token_destination_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governing_token_destination_account = Some(governing_token_destination_account); + self + } + #[inline(always)] + pub fn governing_token_owner_account( + &mut self, + governing_token_owner_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.governing_token_owner_account = Some(governing_token_owner_account); + self + } + /// seeds=['governance',realm, governing_token_mint, governing_token_owner] + #[inline(always)] + pub fn token_owner_record(&mut self, token_owner_record: solana_pubkey::Pubkey) -> &mut Self { + self.token_owner_record = Some(token_owner_record); + self + } + /// `[optional account, default to 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA']` + #[inline(always)] + pub fn token_program(&mut self, token_program: solana_pubkey::Pubkey) -> &mut Self { + self.token_program = Some(token_program); + self + } + /// seeds=['realm-config', realm] + #[inline(always)] + pub fn realm_config_account( + &mut self, + realm_config_account: solana_pubkey::Pubkey, + ) -> &mut Self { + self.realm_config_account = Some(realm_config_account); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_instruction::Instruction { + let accounts = WithdrawGoverningTokens { + realm_account: self.realm_account.expect("realm_account is not set"), + governing_token_holding_account: self + .governing_token_holding_account + .expect("governing_token_holding_account is not set"), + governing_token_destination_account: self + .governing_token_destination_account + .expect("governing_token_destination_account is not set"), + governing_token_owner_account: self + .governing_token_owner_account + .expect("governing_token_owner_account is not set"), + token_owner_record: self + .token_owner_record + .expect("token_owner_record is not set"), + token_program: self.token_program.unwrap_or(solana_pubkey::pubkey!( + "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + )), + realm_config_account: self + .realm_config_account + .expect("realm_config_account is not set"), + }; + + accounts.instruction_with_remaining_accounts(&self.__remaining_accounts) + } +} + +/// `withdraw_governing_tokens` CPI accounts. +pub struct WithdrawGoverningTokensCpiAccounts<'a, 'b> { + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['governance', realm, governing_token_mint] + pub governing_token_holding_account: &'b solana_account_info::AccountInfo<'a>, + /// All tokens will be transferred to this account + pub governing_token_destination_account: &'b solana_account_info::AccountInfo<'a>, + + pub governing_token_owner_account: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['governance',realm, governing_token_mint, governing_token_owner] + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + + pub token_program: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['realm-config', realm] + pub realm_config_account: &'b solana_account_info::AccountInfo<'a>, +} + +/// `withdraw_governing_tokens` CPI instruction. +pub struct WithdrawGoverningTokensCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_account_info::AccountInfo<'a>, + + pub realm_account: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['governance', realm, governing_token_mint] + pub governing_token_holding_account: &'b solana_account_info::AccountInfo<'a>, + /// All tokens will be transferred to this account + pub governing_token_destination_account: &'b solana_account_info::AccountInfo<'a>, + + pub governing_token_owner_account: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['governance',realm, governing_token_mint, governing_token_owner] + pub token_owner_record: &'b solana_account_info::AccountInfo<'a>, + + pub token_program: &'b solana_account_info::AccountInfo<'a>, + /// seeds=['realm-config', realm] + pub realm_config_account: &'b solana_account_info::AccountInfo<'a>, +} + +impl<'a, 'b> WithdrawGoverningTokensCpi<'a, 'b> { + pub fn new( + program: &'b solana_account_info::AccountInfo<'a>, + accounts: WithdrawGoverningTokensCpiAccounts<'a, 'b>, + ) -> Self { + Self { + __program: program, + realm_account: accounts.realm_account, + governing_token_holding_account: accounts.governing_token_holding_account, + governing_token_destination_account: accounts.governing_token_destination_account, + governing_token_owner_account: accounts.governing_token_owner_account, + token_owner_record: accounts.token_owner_record, + token_program: accounts.token_program, + realm_config_account: accounts.realm_config_account, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> solana_program_error::ProgramResult { + let mut accounts = Vec::with_capacity(7 + remaining_accounts.len()); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.governing_token_holding_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.governing_token_destination_account.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.governing_token_owner_account.key, + true, + )); + accounts.push(solana_instruction::AccountMeta::new( + *self.token_owner_record.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.token_program.key, + false, + )); + accounts.push(solana_instruction::AccountMeta::new_readonly( + *self.realm_config_account.key, + false, + )); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let data = WithdrawGoverningTokensInstructionData::new() + .try_to_vec() + .unwrap(); + + let instruction = solana_instruction::Instruction { + program_id: crate::SPL_GOVERNANCE_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(8 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.realm_account.clone()); + account_infos.push(self.governing_token_holding_account.clone()); + account_infos.push(self.governing_token_destination_account.clone()); + account_infos.push(self.governing_token_owner_account.clone()); + account_infos.push(self.token_owner_record.clone()); + account_infos.push(self.token_program.clone()); + account_infos.push(self.realm_config_account.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_cpi::invoke(&instruction, &account_infos) + } else { + solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// Instruction builder for `WithdrawGoverningTokens` via CPI. +/// +/// ### Accounts: +/// +/// 0. `[]` realm_account +/// 1. `[writable]` governing_token_holding_account +/// 2. `[writable]` governing_token_destination_account +/// 3. `[signer]` governing_token_owner_account +/// 4. `[writable]` token_owner_record +/// 5. `[]` token_program +/// 6. `[]` realm_config_account +#[derive(Clone, Debug)] +pub struct WithdrawGoverningTokensCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> WithdrawGoverningTokensCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(WithdrawGoverningTokensCpiBuilderInstruction { + __program: program, + realm_account: None, + governing_token_holding_account: None, + governing_token_destination_account: None, + governing_token_owner_account: None, + token_owner_record: None, + token_program: None, + realm_config_account: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + #[inline(always)] + pub fn realm_account( + &mut self, + realm_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_account = Some(realm_account); + self + } + /// seeds=['governance', realm, governing_token_mint] + #[inline(always)] + pub fn governing_token_holding_account( + &mut self, + governing_token_holding_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governing_token_holding_account = Some(governing_token_holding_account); + self + } + /// All tokens will be transferred to this account + #[inline(always)] + pub fn governing_token_destination_account( + &mut self, + governing_token_destination_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governing_token_destination_account = + Some(governing_token_destination_account); + self + } + #[inline(always)] + pub fn governing_token_owner_account( + &mut self, + governing_token_owner_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.governing_token_owner_account = Some(governing_token_owner_account); + self + } + /// seeds=['governance',realm, governing_token_mint, governing_token_owner] + #[inline(always)] + pub fn token_owner_record( + &mut self, + token_owner_record: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_owner_record = Some(token_owner_record); + self + } + #[inline(always)] + pub fn token_program( + &mut self, + token_program: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.token_program = Some(token_program); + self + } + /// seeds=['realm-config', realm] + #[inline(always)] + pub fn realm_config_account( + &mut self, + realm_config_account: &'b solana_account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.realm_config_account = Some(realm_config_account); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program_error::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult { + let instruction = WithdrawGoverningTokensCpi { + __program: self.instruction.__program, + + realm_account: self + .instruction + .realm_account + .expect("realm_account is not set"), + + governing_token_holding_account: self + .instruction + .governing_token_holding_account + .expect("governing_token_holding_account is not set"), + + governing_token_destination_account: self + .instruction + .governing_token_destination_account + .expect("governing_token_destination_account is not set"), + + governing_token_owner_account: self + .instruction + .governing_token_owner_account + .expect("governing_token_owner_account is not set"), + + token_owner_record: self + .instruction + .token_owner_record + .expect("token_owner_record is not set"), + + token_program: self + .instruction + .token_program + .expect("token_program is not set"), + + realm_config_account: self + .instruction + .realm_config_account + .expect("realm_config_account is not set"), + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +#[derive(Clone, Debug)] +struct WithdrawGoverningTokensCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_account_info::AccountInfo<'a>, + realm_account: Option<&'b solana_account_info::AccountInfo<'a>>, + governing_token_holding_account: Option<&'b solana_account_info::AccountInfo<'a>>, + governing_token_destination_account: Option<&'b solana_account_info::AccountInfo<'a>>, + governing_token_owner_account: Option<&'b solana_account_info::AccountInfo<'a>>, + token_owner_record: Option<&'b solana_account_info::AccountInfo<'a>>, + token_program: Option<&'b solana_account_info::AccountInfo<'a>>, + realm_config_account: Option<&'b solana_account_info::AccountInfo<'a>>, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>, +} diff --git a/e2e/governance/src/generated/mod.rs b/e2e/governance/src/generated/mod.rs new file mode 100644 index 0000000..e0d740a --- /dev/null +++ b/e2e/governance/src/generated/mod.rs @@ -0,0 +1,15 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +pub mod accounts; +pub mod errors; +pub mod instructions; +pub mod programs; +pub mod shared; +pub mod types; + +pub(crate) use programs::*; diff --git a/e2e/governance/src/generated/pdas/community_token_holding.rs b/e2e/governance/src/generated/pdas/community_token_holding.rs new file mode 100644 index 0000000..889d1b9 --- /dev/null +++ b/e2e/governance/src/generated/pdas/community_token_holding.rs @@ -0,0 +1,42 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::SPL_GOVERNANCE_ID; + + + pub const COMMUNITY_TOKEN_HOLDING_SEED: &'static [u8] = b"governance"; + +pub fn create_community_token_holding_pda( + realm: solana_pubkey::Pubkey, + community_mint: solana_pubkey::Pubkey, + bump: u8, +) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + COMMUNITY_TOKEN_HOLDING_SEED, + realm.as_ref(), + community_mint.as_ref(), + &[bump], + ], + &SPL_GOVERNANCE_ID, + ) +} + +pub fn find_community_token_holding_pda( + realm: &solana_pubkey::Pubkey, + community_mint: &solana_pubkey::Pubkey, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + COMMUNITY_TOKEN_HOLDING_SEED, + realm.as_ref(), + community_mint.as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) +} + diff --git a/e2e/governance/src/generated/pdas/council_token_holding.rs b/e2e/governance/src/generated/pdas/council_token_holding.rs new file mode 100644 index 0000000..85e0a52 --- /dev/null +++ b/e2e/governance/src/generated/pdas/council_token_holding.rs @@ -0,0 +1,42 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::SPL_GOVERNANCE_ID; + + + pub const COUNCIL_TOKEN_HOLDING_SEED: &'static [u8] = b"governance"; + +pub fn create_council_token_holding_pda( + realm: solana_pubkey::Pubkey, + council_mint: solana_pubkey::Pubkey, + bump: u8, +) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + COUNCIL_TOKEN_HOLDING_SEED, + realm.as_ref(), + council_mint.as_ref(), + &[bump], + ], + &SPL_GOVERNANCE_ID, + ) +} + +pub fn find_council_token_holding_pda( + realm: &solana_pubkey::Pubkey, + council_mint: &solana_pubkey::Pubkey, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + COUNCIL_TOKEN_HOLDING_SEED, + realm.as_ref(), + council_mint.as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) +} + diff --git a/e2e/governance/src/generated/pdas/governance.rs b/e2e/governance/src/generated/pdas/governance.rs new file mode 100644 index 0000000..f075a20 --- /dev/null +++ b/e2e/governance/src/generated/pdas/governance.rs @@ -0,0 +1,42 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::SPL_GOVERNANCE_ID; + + + pub const GOVERNANCE_SEED: &'static [u8] = b"account-governance"; + +pub fn create_governance_pda( + realm: solana_pubkey::Pubkey, + seed: solana_pubkey::Pubkey, + bump: u8, +) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + GOVERNANCE_SEED, + realm.as_ref(), + seed.as_ref(), + &[bump], + ], + &SPL_GOVERNANCE_ID, + ) +} + +pub fn find_governance_pda( + realm: &solana_pubkey::Pubkey, + seed: &solana_pubkey::Pubkey, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + GOVERNANCE_SEED, + realm.as_ref(), + seed.as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) +} + diff --git a/e2e/governance/src/generated/pdas/governing_token_holding.rs b/e2e/governance/src/generated/pdas/governing_token_holding.rs new file mode 100644 index 0000000..4a89c93 --- /dev/null +++ b/e2e/governance/src/generated/pdas/governing_token_holding.rs @@ -0,0 +1,42 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::SPL_GOVERNANCE_ID; + + + pub const GOVERNING_TOKEN_HOLDING_SEED: &'static [u8] = b"governance"; + +pub fn create_governing_token_holding_pda( + realm: solana_pubkey::Pubkey, + governing_token_mint: solana_pubkey::Pubkey, + bump: u8, +) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + GOVERNING_TOKEN_HOLDING_SEED, + realm.as_ref(), + governing_token_mint.as_ref(), + &[bump], + ], + &SPL_GOVERNANCE_ID, + ) +} + +pub fn find_governing_token_holding_pda( + realm: &solana_pubkey::Pubkey, + governing_token_mint: &solana_pubkey::Pubkey, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + GOVERNING_TOKEN_HOLDING_SEED, + realm.as_ref(), + governing_token_mint.as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) +} + diff --git a/e2e/governance/src/generated/pdas/mod.rs b/e2e/governance/src/generated/pdas/mod.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/e2e/governance/src/generated/pdas/mod.rs @@ -0,0 +1 @@ + diff --git a/e2e/governance/src/generated/pdas/native_treasury.rs b/e2e/governance/src/generated/pdas/native_treasury.rs new file mode 100644 index 0000000..54e36f6 --- /dev/null +++ b/e2e/governance/src/generated/pdas/native_treasury.rs @@ -0,0 +1,38 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::SPL_GOVERNANCE_ID; + + + pub const NATIVE_TREASURY_SEED: &'static [u8] = b"native-treasury"; + +pub fn create_native_treasury_pda( + governance: solana_pubkey::Pubkey, + bump: u8, +) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + NATIVE_TREASURY_SEED, + governance.as_ref(), + &[bump], + ], + &SPL_GOVERNANCE_ID, + ) +} + +pub fn find_native_treasury_pda( + governance: &solana_pubkey::Pubkey, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + NATIVE_TREASURY_SEED, + governance.as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) +} + diff --git a/e2e/governance/src/generated/pdas/proposal.rs b/e2e/governance/src/generated/pdas/proposal.rs new file mode 100644 index 0000000..109bc99 --- /dev/null +++ b/e2e/governance/src/generated/pdas/proposal.rs @@ -0,0 +1,46 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::SPL_GOVERNANCE_ID; + + + pub const PROPOSAL_SEED: &'static [u8] = b"governance"; + +pub fn create_proposal_pda( + governance: solana_pubkey::Pubkey, + governing_token_mint: solana_pubkey::Pubkey, + proposal_seed: solana_pubkey::Pubkey, + bump: u8, +) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + PROPOSAL_SEED, + governance.as_ref(), + governing_token_mint.as_ref(), + proposal_seed.as_ref(), + &[bump], + ], + &SPL_GOVERNANCE_ID, + ) +} + +pub fn find_proposal_pda( + governance: &solana_pubkey::Pubkey, + governing_token_mint: &solana_pubkey::Pubkey, + proposal_seed: &solana_pubkey::Pubkey, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + PROPOSAL_SEED, + governance.as_ref(), + governing_token_mint.as_ref(), + proposal_seed.as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) +} + diff --git a/e2e/governance/src/generated/pdas/proposal_deposit.rs b/e2e/governance/src/generated/pdas/proposal_deposit.rs new file mode 100644 index 0000000..207b043 --- /dev/null +++ b/e2e/governance/src/generated/pdas/proposal_deposit.rs @@ -0,0 +1,42 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::SPL_GOVERNANCE_ID; + + + pub const PROPOSAL_DEPOSIT_SEED: &'static [u8] = b"proposal-deposit"; + +pub fn create_proposal_deposit_pda( + proposal: solana_pubkey::Pubkey, + deposit_payer: solana_pubkey::Pubkey, + bump: u8, +) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + PROPOSAL_DEPOSIT_SEED, + proposal.as_ref(), + deposit_payer.as_ref(), + &[bump], + ], + &SPL_GOVERNANCE_ID, + ) +} + +pub fn find_proposal_deposit_pda( + proposal: &solana_pubkey::Pubkey, + deposit_payer: &solana_pubkey::Pubkey, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + PROPOSAL_DEPOSIT_SEED, + proposal.as_ref(), + deposit_payer.as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) +} + diff --git a/e2e/governance/src/generated/pdas/proposal_transaction.rs b/e2e/governance/src/generated/pdas/proposal_transaction.rs new file mode 100644 index 0000000..a107021 --- /dev/null +++ b/e2e/governance/src/generated/pdas/proposal_transaction.rs @@ -0,0 +1,46 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::SPL_GOVERNANCE_ID; + + + pub const PROPOSAL_TRANSACTION_SEED: &'static [u8] = b"governance"; + +pub fn create_proposal_transaction_pda( + proposal: solana_pubkey::Pubkey, + option_index: u8, + index: u16, + bump: u8, +) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + PROPOSAL_TRANSACTION_SEED, + proposal.as_ref(), + option_index.to_string().as_ref(), + index.to_string().as_ref(), + &[bump], + ], + &SPL_GOVERNANCE_ID, + ) +} + +pub fn find_proposal_transaction_pda( + proposal: &solana_pubkey::Pubkey, + option_index: u8, + index: u16, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + PROPOSAL_TRANSACTION_SEED, + proposal.as_ref(), + option_index.to_string().as_ref(), + index.to_string().as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) +} + diff --git a/e2e/governance/src/generated/pdas/realm.rs b/e2e/governance/src/generated/pdas/realm.rs new file mode 100644 index 0000000..1d72486 --- /dev/null +++ b/e2e/governance/src/generated/pdas/realm.rs @@ -0,0 +1,38 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::SPL_GOVERNANCE_ID; + + + pub const REALM_SEED: &'static [u8] = b"governance"; + +pub fn create_realm_pda( + name: RemainderStr, + bump: u8, +) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + REALM_SEED, + name.to_string().as_ref(), + &[bump], + ], + &SPL_GOVERNANCE_ID, + ) +} + +pub fn find_realm_pda( + name: RemainderStr, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + REALM_SEED, + name.to_string().as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) +} + diff --git a/e2e/governance/src/generated/pdas/realm_config.rs b/e2e/governance/src/generated/pdas/realm_config.rs new file mode 100644 index 0000000..ee86683 --- /dev/null +++ b/e2e/governance/src/generated/pdas/realm_config.rs @@ -0,0 +1,38 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::SPL_GOVERNANCE_ID; + + + pub const REALM_CONFIG_SEED: &'static [u8] = b"realm-config"; + +pub fn create_realm_config_pda( + realm: solana_pubkey::Pubkey, + bump: u8, +) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + REALM_CONFIG_SEED, + realm.as_ref(), + &[bump], + ], + &SPL_GOVERNANCE_ID, + ) +} + +pub fn find_realm_config_pda( + realm: &solana_pubkey::Pubkey, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + REALM_CONFIG_SEED, + realm.as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) +} + diff --git a/e2e/governance/src/generated/pdas/required_signatory.rs b/e2e/governance/src/generated/pdas/required_signatory.rs new file mode 100644 index 0000000..f53afd5 --- /dev/null +++ b/e2e/governance/src/generated/pdas/required_signatory.rs @@ -0,0 +1,42 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::SPL_GOVERNANCE_ID; + + + pub const REQUIRED_SIGNATORY_SEED: &'static [u8] = b"required-signatory"; + +pub fn create_required_signatory_pda( + governance: solana_pubkey::Pubkey, + signatory: solana_pubkey::Pubkey, + bump: u8, +) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + REQUIRED_SIGNATORY_SEED, + governance.as_ref(), + signatory.as_ref(), + &[bump], + ], + &SPL_GOVERNANCE_ID, + ) +} + +pub fn find_required_signatory_pda( + governance: &solana_pubkey::Pubkey, + signatory: &solana_pubkey::Pubkey, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + REQUIRED_SIGNATORY_SEED, + governance.as_ref(), + signatory.as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) +} + diff --git a/e2e/governance/src/generated/pdas/signatory_record.rs b/e2e/governance/src/generated/pdas/signatory_record.rs new file mode 100644 index 0000000..295b3e3 --- /dev/null +++ b/e2e/governance/src/generated/pdas/signatory_record.rs @@ -0,0 +1,42 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::SPL_GOVERNANCE_ID; + + + pub const SIGNATORY_RECORD_SEED: &'static [u8] = b"governance"; + +pub fn create_signatory_record_pda( + proposal: solana_pubkey::Pubkey, + signatory: solana_pubkey::Pubkey, + bump: u8, +) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + SIGNATORY_RECORD_SEED, + proposal.as_ref(), + signatory.as_ref(), + &[bump], + ], + &SPL_GOVERNANCE_ID, + ) +} + +pub fn find_signatory_record_pda( + proposal: &solana_pubkey::Pubkey, + signatory: &solana_pubkey::Pubkey, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + SIGNATORY_RECORD_SEED, + proposal.as_ref(), + signatory.as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) +} + diff --git a/e2e/governance/src/generated/pdas/token_owner_record.rs b/e2e/governance/src/generated/pdas/token_owner_record.rs new file mode 100644 index 0000000..a7672e5 --- /dev/null +++ b/e2e/governance/src/generated/pdas/token_owner_record.rs @@ -0,0 +1,46 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::SPL_GOVERNANCE_ID; + + + pub const TOKEN_OWNER_RECORD_SEED: &'static [u8] = b"governance"; + +pub fn create_token_owner_record_pda( + realm: solana_pubkey::Pubkey, + governing_token_mint: solana_pubkey::Pubkey, + governing_token_owner: solana_pubkey::Pubkey, + bump: u8, +) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + TOKEN_OWNER_RECORD_SEED, + realm.as_ref(), + governing_token_mint.as_ref(), + governing_token_owner.as_ref(), + &[bump], + ], + &SPL_GOVERNANCE_ID, + ) +} + +pub fn find_token_owner_record_pda( + realm: &solana_pubkey::Pubkey, + governing_token_mint: &solana_pubkey::Pubkey, + governing_token_owner: &solana_pubkey::Pubkey, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + TOKEN_OWNER_RECORD_SEED, + realm.as_ref(), + governing_token_mint.as_ref(), + governing_token_owner.as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) +} + diff --git a/e2e/governance/src/generated/pdas/vote_record.rs b/e2e/governance/src/generated/pdas/vote_record.rs new file mode 100644 index 0000000..4443f88 --- /dev/null +++ b/e2e/governance/src/generated/pdas/vote_record.rs @@ -0,0 +1,42 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::SPL_GOVERNANCE_ID; + + + pub const VOTE_RECORD_SEED: &'static [u8] = b"governance"; + +pub fn create_vote_record_pda( + proposal: solana_pubkey::Pubkey, + token_owner_record: solana_pubkey::Pubkey, + bump: u8, +) -> Result { + solana_pubkey::Pubkey::create_program_address( + &[ + VOTE_RECORD_SEED, + proposal.as_ref(), + token_owner_record.as_ref(), + &[bump], + ], + &SPL_GOVERNANCE_ID, + ) +} + +pub fn find_vote_record_pda( + proposal: &solana_pubkey::Pubkey, + token_owner_record: &solana_pubkey::Pubkey, + ) -> (solana_pubkey::Pubkey, u8) { + solana_pubkey::Pubkey::find_program_address( + &[ + VOTE_RECORD_SEED, + proposal.as_ref(), + token_owner_record.as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) +} + diff --git a/e2e/governance/src/generated/programs.rs b/e2e/governance/src/generated/programs.rs new file mode 100644 index 0000000..1a3d43e --- /dev/null +++ b/e2e/governance/src/generated/programs.rs @@ -0,0 +1,11 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use solana_pubkey::{pubkey, Pubkey}; + +/// `spl_governance` program ID. +pub const SPL_GOVERNANCE_ID: Pubkey = pubkey!("GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw"); diff --git a/e2e/governance/src/generated/shared.rs b/e2e/governance/src/generated/shared.rs new file mode 100644 index 0000000..71b906d --- /dev/null +++ b/e2e/governance/src/generated/shared.rs @@ -0,0 +1,21 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +#[cfg(feature = "fetch")] +#[derive(Debug, Clone)] +pub struct DecodedAccount { + pub address: solana_pubkey::Pubkey, + pub account: solana_account::Account, + pub data: T, +} + +#[cfg(feature = "fetch")] +#[derive(Debug, Clone)] +pub enum MaybeAccount { + Exists(DecodedAccount), + NotFound(solana_pubkey::Pubkey), +} diff --git a/e2e/governance/src/generated/types/account_meta_data.rs b/e2e/governance/src/generated/types/account_meta_data.rs new file mode 100644 index 0000000..c15ed18 --- /dev/null +++ b/e2e/governance/src/generated/types/account_meta_data.rs @@ -0,0 +1,22 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct AccountMetaData { + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub pubkey: Pubkey, + pub is_signer: bool, + pub is_writable: bool, +} diff --git a/e2e/governance/src/generated/types/governance_account_type.rs b/e2e/governance/src/generated/types/governance_account_type.rs new file mode 100644 index 0000000..5554407 --- /dev/null +++ b/e2e/governance/src/generated/types/governance_account_type.rs @@ -0,0 +1,51 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use num_derive::FromPrimitive; + +#[derive( + BorshSerialize, + BorshDeserialize, + Clone, + Debug, + Eq, + PartialEq, + Copy, + PartialOrd, + Hash, + FromPrimitive, +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum GovernanceAccountType { + Uninitialized, + RealmV1, + TokenOwnerRecordV1, + GovernanceV1, + ProgramGovernanceV1, + ProposalV1, + SignatoryRecordV1, + VoteRecordV1, + ProposalInstructionV1, + MintGovernanceV1, + TokenGovernanceV1, + RealmConfig, + VoteRecordV2, + ProposalTransactionV2, + ProposalV2, + ProgramMetadata, + RealmV2, + TokenOwnerRecordV2, + GovernanceV2, + ProgramGovernanceV2, + MintGovernanceV2, + TokenGovernanceV2, + SignatoryRecordV2, + ProposalDeposit, + RequiredSignatory, +} diff --git a/e2e/governance/src/generated/types/governance_config.rs b/e2e/governance/src/generated/types/governance_config.rs new file mode 100644 index 0000000..d84716c --- /dev/null +++ b/e2e/governance/src/generated/types/governance_config.rs @@ -0,0 +1,28 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::VoteThreshold; +use crate::generated::types::VoteTipping; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct GovernanceConfig { + pub community_vote_threshold: VoteThreshold, + pub min_community_weight_to_create_proposal: u64, + pub min_transaction_hold_up_time: u32, + pub voting_base_time: u32, + pub community_vote_tipping: VoteTipping, + pub council_vote_threshold: VoteThreshold, + pub council_veto_vote_threshold: VoteThreshold, + pub min_council_weight_to_create_proposal: u64, + pub council_vote_tipping: VoteTipping, + pub community_veto_vote_threshold: VoteThreshold, + pub voting_cool_off_time: u32, + pub deposit_exempt_proposal_count: u8, +} diff --git a/e2e/governance/src/generated/types/governance_instruction_v1.rs b/e2e/governance/src/generated/types/governance_instruction_v1.rs new file mode 100644 index 0000000..fbef779 --- /dev/null +++ b/e2e/governance/src/generated/types/governance_instruction_v1.rs @@ -0,0 +1,22 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::RealmConfigParamsV1; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum GovernanceInstructionV1 { + CreateRealm { + name: String, + config_args: RealmConfigParamsV1, + }, + DepositGoverningTokens { + amount: u64, + }, +} diff --git a/e2e/governance/src/generated/types/governing_token_config.rs b/e2e/governance/src/generated/types/governing_token_config.rs new file mode 100644 index 0000000..55bf0fe --- /dev/null +++ b/e2e/governance/src/generated/types/governing_token_config.rs @@ -0,0 +1,20 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GoverningTokenType; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct GoverningTokenConfig { + pub voter_weight_addin: Option, + pub max_voter_weight_addin: Option, + pub token_type: GoverningTokenType, + pub reserved: [u8; 8], +} diff --git a/e2e/governance/src/generated/types/governing_token_config_account_args.rs b/e2e/governance/src/generated/types/governing_token_config_account_args.rs new file mode 100644 index 0000000..a536aba --- /dev/null +++ b/e2e/governance/src/generated/types/governing_token_config_account_args.rs @@ -0,0 +1,19 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GoverningTokenType; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct GoverningTokenConfigAccountArgs { + pub voter_weight_addin: Option, + pub max_voter_weight_addin: Option, + pub token_type: GoverningTokenType, +} diff --git a/e2e/governance/src/generated/types/governing_token_config_params.rs b/e2e/governance/src/generated/types/governing_token_config_params.rs new file mode 100644 index 0000000..997da2a --- /dev/null +++ b/e2e/governance/src/generated/types/governing_token_config_params.rs @@ -0,0 +1,18 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GoverningTokenType; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct GoverningTokenConfigParams { + pub use_voter_weight_addin: bool, + pub use_max_voter_weight_addin: bool, + pub token_type: GoverningTokenType, +} diff --git a/e2e/governance/src/generated/types/governing_token_type.rs b/e2e/governance/src/generated/types/governing_token_type.rs new file mode 100644 index 0000000..38414f2 --- /dev/null +++ b/e2e/governance/src/generated/types/governing_token_type.rs @@ -0,0 +1,29 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use num_derive::FromPrimitive; + +#[derive( + BorshSerialize, + BorshDeserialize, + Clone, + Debug, + Eq, + PartialEq, + Copy, + PartialOrd, + Hash, + FromPrimitive, +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum GoverningTokenType { + Liquid, + Membership, + Dormant, +} diff --git a/e2e/governance/src/generated/types/instruction_data.rs b/e2e/governance/src/generated/types/instruction_data.rs new file mode 100644 index 0000000..c4d309b --- /dev/null +++ b/e2e/governance/src/generated/types/instruction_data.rs @@ -0,0 +1,23 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::AccountMetaData; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct InstructionData { + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub program_id: Pubkey, + pub accounts: Vec, + pub data: Vec, +} diff --git a/e2e/governance/src/generated/types/instruction_execution_flags.rs b/e2e/governance/src/generated/types/instruction_execution_flags.rs new file mode 100644 index 0000000..e7d6fbf --- /dev/null +++ b/e2e/governance/src/generated/types/instruction_execution_flags.rs @@ -0,0 +1,29 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use num_derive::FromPrimitive; + +#[derive( + BorshSerialize, + BorshDeserialize, + Clone, + Debug, + Eq, + PartialEq, + Copy, + PartialOrd, + Hash, + FromPrimitive, +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum InstructionExecutionFlags { + None, + Ordered, + UseTransaction, +} diff --git a/e2e/governance/src/generated/types/mint_max_voter_weight_source.rs b/e2e/governance/src/generated/types/mint_max_voter_weight_source.rs new file mode 100644 index 0000000..b37c7a7 --- /dev/null +++ b/e2e/governance/src/generated/types/mint_max_voter_weight_source.rs @@ -0,0 +1,16 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum MintMaxVoterWeightSource { + SupplyFraction(u64), + Absolute(u64), +} diff --git a/e2e/governance/src/generated/types/mod.rs b/e2e/governance/src/generated/types/mod.rs new file mode 100644 index 0000000..b5b6bae --- /dev/null +++ b/e2e/governance/src/generated/types/mod.rs @@ -0,0 +1,72 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +pub(crate) mod r#account_meta_data; +pub(crate) mod r#governance_account_type; +pub(crate) mod r#governance_config; +pub(crate) mod r#governance_instruction_v1; +pub(crate) mod r#governing_token_config; +pub(crate) mod r#governing_token_config_account_args; +pub(crate) mod r#governing_token_config_params; +pub(crate) mod r#governing_token_type; +pub(crate) mod r#instruction_data; +pub(crate) mod r#instruction_execution_flags; +pub(crate) mod r#mint_max_voter_weight_source; +pub(crate) mod r#multi_choice_type; +pub(crate) mod r#native_treasury; +pub(crate) mod r#option_vote_result; +pub(crate) mod r#proposal_option; +pub(crate) mod r#proposal_state; +pub(crate) mod r#realm_config; +pub(crate) mod r#realm_config_params; +pub(crate) mod r#realm_config_params_v1; +pub(crate) mod r#reserved110; +pub(crate) mod r#reserved119; +pub(crate) mod r#set_realm_authority_action; +pub(crate) mod r#slot; +pub(crate) mod r#transaction_execution_status; +pub(crate) mod r#unix_timestamp; +pub(crate) mod r#vote; +pub(crate) mod r#vote_choice; +pub(crate) mod r#vote_kind; +pub(crate) mod r#vote_threshold; +pub(crate) mod r#vote_tipping; +pub(crate) mod r#vote_type; +pub(crate) mod r#vote_weight_v1; + +pub use self::r#account_meta_data::*; +pub use self::r#governance_account_type::*; +pub use self::r#governance_config::*; +pub use self::r#governance_instruction_v1::*; +pub use self::r#governing_token_config::*; +pub use self::r#governing_token_config_account_args::*; +pub use self::r#governing_token_config_params::*; +pub use self::r#governing_token_type::*; +pub use self::r#instruction_data::*; +pub use self::r#instruction_execution_flags::*; +pub use self::r#mint_max_voter_weight_source::*; +pub use self::r#multi_choice_type::*; +pub use self::r#native_treasury::*; +pub use self::r#option_vote_result::*; +pub use self::r#proposal_option::*; +pub use self::r#proposal_state::*; +pub use self::r#realm_config::*; +pub use self::r#realm_config_params::*; +pub use self::r#realm_config_params_v1::*; +pub use self::r#reserved110::*; +pub use self::r#reserved119::*; +pub use self::r#set_realm_authority_action::*; +pub use self::r#slot::*; +pub use self::r#transaction_execution_status::*; +pub use self::r#unix_timestamp::*; +pub use self::r#vote::*; +pub use self::r#vote_choice::*; +pub use self::r#vote_kind::*; +pub use self::r#vote_threshold::*; +pub use self::r#vote_tipping::*; +pub use self::r#vote_type::*; +pub use self::r#vote_weight_v1::*; diff --git a/e2e/governance/src/generated/types/multi_choice_type.rs b/e2e/governance/src/generated/types/multi_choice_type.rs new file mode 100644 index 0000000..711e515 --- /dev/null +++ b/e2e/governance/src/generated/types/multi_choice_type.rs @@ -0,0 +1,28 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use num_derive::FromPrimitive; + +#[derive( + BorshSerialize, + BorshDeserialize, + Clone, + Debug, + Eq, + PartialEq, + Copy, + PartialOrd, + Hash, + FromPrimitive, +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum MultiChoiceType { + FullWeight, + Weighted, +} diff --git a/e2e/governance/src/generated/types/native_treasury.rs b/e2e/governance/src/generated/types/native_treasury.rs new file mode 100644 index 0000000..5fa3f7c --- /dev/null +++ b/e2e/governance/src/generated/types/native_treasury.rs @@ -0,0 +1,13 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct NativeTreasury {} diff --git a/e2e/governance/src/generated/types/option_vote_result.rs b/e2e/governance/src/generated/types/option_vote_result.rs new file mode 100644 index 0000000..395fc8d --- /dev/null +++ b/e2e/governance/src/generated/types/option_vote_result.rs @@ -0,0 +1,29 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use num_derive::FromPrimitive; + +#[derive( + BorshSerialize, + BorshDeserialize, + Clone, + Debug, + Eq, + PartialEq, + Copy, + PartialOrd, + Hash, + FromPrimitive, +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum OptionVoteResult { + None, + Succeeded, + Defeated, +} diff --git a/e2e/governance/src/generated/types/proposal_option.rs b/e2e/governance/src/generated/types/proposal_option.rs new file mode 100644 index 0000000..e594325 --- /dev/null +++ b/e2e/governance/src/generated/types/proposal_option.rs @@ -0,0 +1,21 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::OptionVoteResult; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ProposalOption { + pub label: String, + pub vote_weight: u64, + pub vote_result: OptionVoteResult, + pub transactions_executed_count: u16, + pub transactions_count: u16, + pub transactions_next_index: u16, +} diff --git a/e2e/governance/src/generated/types/proposal_state.rs b/e2e/governance/src/generated/types/proposal_state.rs new file mode 100644 index 0000000..21ca864 --- /dev/null +++ b/e2e/governance/src/generated/types/proposal_state.rs @@ -0,0 +1,36 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use num_derive::FromPrimitive; + +#[derive( + BorshSerialize, + BorshDeserialize, + Clone, + Debug, + Eq, + PartialEq, + Copy, + PartialOrd, + Hash, + FromPrimitive, +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum ProposalState { + Draft, + SigningOff, + Voting, + Succeeded, + Executing, + Completed, + Cancelled, + Defeated, + ExecutingWithErrors, + Vetoed, +} diff --git a/e2e/governance/src/generated/types/realm_config.rs b/e2e/governance/src/generated/types/realm_config.rs new file mode 100644 index 0000000..c102325 --- /dev/null +++ b/e2e/governance/src/generated/types/realm_config.rs @@ -0,0 +1,22 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::MintMaxVoterWeightSource; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct RealmConfig { + pub legacy1: u8, + pub legacy2: u8, + pub reserved: [u8; 6], + pub min_community_weight_to_create_governance: u64, + pub community_mint_max_voter_weight_source: MintMaxVoterWeightSource, + pub council_mint: Option, +} diff --git a/e2e/governance/src/generated/types/realm_config_params.rs b/e2e/governance/src/generated/types/realm_config_params.rs new file mode 100644 index 0000000..7675c7d --- /dev/null +++ b/e2e/governance/src/generated/types/realm_config_params.rs @@ -0,0 +1,21 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::GoverningTokenConfigParams; +use crate::generated::types::MintMaxVoterWeightSource; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct RealmConfigParams { + pub use_council_mint: bool, + pub min_community_weight_to_create_governance: u64, + pub community_mint_max_voter_weight_source: MintMaxVoterWeightSource, + pub community_token_config_args: GoverningTokenConfigParams, + pub council_token_config_args: GoverningTokenConfigParams, +} diff --git a/e2e/governance/src/generated/types/realm_config_params_v1.rs b/e2e/governance/src/generated/types/realm_config_params_v1.rs new file mode 100644 index 0000000..3c5ad52 --- /dev/null +++ b/e2e/governance/src/generated/types/realm_config_params_v1.rs @@ -0,0 +1,18 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::MintMaxVoterWeightSource; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct RealmConfigParamsV1 { + pub use_council_mint: bool, + pub min_community_weight_to_create_governance: u64, + pub community_mint_max_voter_weight_source: MintMaxVoterWeightSource, +} diff --git a/e2e/governance/src/generated/types/reserved110.rs b/e2e/governance/src/generated/types/reserved110.rs new file mode 100644 index 0000000..3f64489 --- /dev/null +++ b/e2e/governance/src/generated/types/reserved110.rs @@ -0,0 +1,18 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Reserved110 { + #[cfg_attr(feature = "serde", serde(with = "serde_big_array::BigArray"))] + pub reserved64: [u8; 64], + pub reserved32: [u8; 32], + pub reserved14: [u8; 14], +} diff --git a/e2e/governance/src/generated/types/reserved119.rs b/e2e/governance/src/generated/types/reserved119.rs new file mode 100644 index 0000000..e669cd9 --- /dev/null +++ b/e2e/governance/src/generated/types/reserved119.rs @@ -0,0 +1,18 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Reserved119 { + #[cfg_attr(feature = "serde", serde(with = "serde_big_array::BigArray"))] + pub reserved64: [u8; 64], + pub reserved32: [u8; 32], + pub reserved23: [u8; 23], +} diff --git a/e2e/governance/src/generated/types/set_realm_authority_action.rs b/e2e/governance/src/generated/types/set_realm_authority_action.rs new file mode 100644 index 0000000..10f16ab --- /dev/null +++ b/e2e/governance/src/generated/types/set_realm_authority_action.rs @@ -0,0 +1,29 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use num_derive::FromPrimitive; + +#[derive( + BorshSerialize, + BorshDeserialize, + Clone, + Debug, + Eq, + PartialEq, + Copy, + PartialOrd, + Hash, + FromPrimitive, +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum SetRealmAuthorityAction { + SetUnchecked, + SetChecked, + Remove, +} diff --git a/e2e/governance/src/generated/types/slot.rs b/e2e/governance/src/generated/types/slot.rs new file mode 100644 index 0000000..f804032 --- /dev/null +++ b/e2e/governance/src/generated/types/slot.rs @@ -0,0 +1,8 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +pub type Slot = u64; diff --git a/e2e/governance/src/generated/types/transaction_execution_status.rs b/e2e/governance/src/generated/types/transaction_execution_status.rs new file mode 100644 index 0000000..af34c69 --- /dev/null +++ b/e2e/governance/src/generated/types/transaction_execution_status.rs @@ -0,0 +1,29 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use num_derive::FromPrimitive; + +#[derive( + BorshSerialize, + BorshDeserialize, + Clone, + Debug, + Eq, + PartialEq, + Copy, + PartialOrd, + Hash, + FromPrimitive, +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum TransactionExecutionStatus { + None, + Success, + Error, +} diff --git a/e2e/governance/src/generated/types/unix_timestamp.rs b/e2e/governance/src/generated/types/unix_timestamp.rs new file mode 100644 index 0000000..62d0860 --- /dev/null +++ b/e2e/governance/src/generated/types/unix_timestamp.rs @@ -0,0 +1,8 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +pub type UnixTimestamp = i64; diff --git a/e2e/governance/src/generated/types/vote.rs b/e2e/governance/src/generated/types/vote.rs new file mode 100644 index 0000000..6f1aa4f --- /dev/null +++ b/e2e/governance/src/generated/types/vote.rs @@ -0,0 +1,19 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::VoteChoice; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum Vote { + Approve(Vec), + Deny, + Abstain, + Veto, +} diff --git a/e2e/governance/src/generated/types/vote_choice.rs b/e2e/governance/src/generated/types/vote_choice.rs new file mode 100644 index 0000000..e6459ce --- /dev/null +++ b/e2e/governance/src/generated/types/vote_choice.rs @@ -0,0 +1,16 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct VoteChoice { + pub rank: u8, + pub weight_percentage: u8, +} diff --git a/e2e/governance/src/generated/types/vote_kind.rs b/e2e/governance/src/generated/types/vote_kind.rs new file mode 100644 index 0000000..51d6ef8 --- /dev/null +++ b/e2e/governance/src/generated/types/vote_kind.rs @@ -0,0 +1,28 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use num_derive::FromPrimitive; + +#[derive( + BorshSerialize, + BorshDeserialize, + Clone, + Debug, + Eq, + PartialEq, + Copy, + PartialOrd, + Hash, + FromPrimitive, +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum VoteKind { + Electorate, + Veto, +} diff --git a/e2e/governance/src/generated/types/vote_threshold.rs b/e2e/governance/src/generated/types/vote_threshold.rs new file mode 100644 index 0000000..e608373 --- /dev/null +++ b/e2e/governance/src/generated/types/vote_threshold.rs @@ -0,0 +1,17 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum VoteThreshold { + YesVotePercentage(u8), + QuorumPercentage(u8), + Disabled, +} diff --git a/e2e/governance/src/generated/types/vote_tipping.rs b/e2e/governance/src/generated/types/vote_tipping.rs new file mode 100644 index 0000000..5c5a149 --- /dev/null +++ b/e2e/governance/src/generated/types/vote_tipping.rs @@ -0,0 +1,29 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use num_derive::FromPrimitive; + +#[derive( + BorshSerialize, + BorshDeserialize, + Clone, + Debug, + Eq, + PartialEq, + Copy, + PartialOrd, + Hash, + FromPrimitive, +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum VoteTipping { + Strict, + Early, + Disabled, +} diff --git a/e2e/governance/src/generated/types/vote_type.rs b/e2e/governance/src/generated/types/vote_type.rs new file mode 100644 index 0000000..16266c2 --- /dev/null +++ b/e2e/governance/src/generated/types/vote_type.rs @@ -0,0 +1,22 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use crate::generated::types::MultiChoiceType; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum VoteType { + SingleChoice, + MultiChoice { + choice_type: MultiChoiceType, + min_voter_options: u8, + max_voter_options: u8, + max_winning_options: u8, + }, +} diff --git a/e2e/governance/src/generated/types/vote_weight_v1.rs b/e2e/governance/src/generated/types/vote_weight_v1.rs new file mode 100644 index 0000000..bb13f94 --- /dev/null +++ b/e2e/governance/src/generated/types/vote_weight_v1.rs @@ -0,0 +1,16 @@ +//! This code was AUTOGENERATED using the codama library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun codama to update it. +//! +//! +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum VoteWeightV1 { + Yes(u64), + No(u64), +} diff --git a/e2e/governance/src/lib.rs b/e2e/governance/src/lib.rs new file mode 100644 index 0000000..19f9287 --- /dev/null +++ b/e2e/governance/src/lib.rs @@ -0,0 +1,4 @@ +mod generated; + +pub use generated::programs::SPL_GOVERNANCE_ID as ID; +pub use generated::*; diff --git a/src/getRenderMapVisitor.ts b/src/getRenderMapVisitor.ts index 5423e21..9479a3a 100644 --- a/src/getRenderMapVisitor.ts +++ b/src/getRenderMapVisitor.ts @@ -3,12 +3,12 @@ import { getAllAccounts, getAllDefinedTypes, getAllInstructionsWithSubs, + getAllPdas, getAllPrograms, InstructionNode, isNode, isNodeFilter, pascalCase, - ProgramNode, resolveNestedTypeNode, snakeCase, structTypeNodeFromInstructionArgumentNodes, @@ -17,6 +17,7 @@ import { import { addToRenderMap, createRenderMap, mergeRenderMaps } from '@codama/renderers-core'; import { extendVisitor, + findProgramNodeFromPath, LinkableDictionary, NodeStack, pipe, @@ -50,7 +51,6 @@ export type GetRenderMapOptions = { export function getRenderMapVisitor(options: GetRenderMapOptions = {}) { const linkables = new LinkableDictionary(); const stack = new NodeStack(); - let program: ProgramNode | null = null; const renderParentInstructions = options.renderParentInstructions ?? false; const dependencyMap = options.dependencyMap ?? {}; @@ -65,11 +65,16 @@ export function getRenderMapVisitor(options: GetRenderMapOptions = {}) { return pipe( staticVisitor(() => createRenderMap(), { - keys: ['rootNode', 'programNode', 'instructionNode', 'accountNode', 'definedTypeNode'], + keys: ['rootNode', 'programNode', 'instructionNode', 'accountNode', 'definedTypeNode', 'pdaNode'], }), v => extendVisitor(v, { visitAccount(node) { + const accountPath = stack.getPath('accountNode'); + const program = findProgramNodeFromPath(accountPath); + if (!program) { + throw new Error('Account must be visited inside a program.'); + } const typeManifest = visit(node, typeManifestVisitor); // Discriminator constants. @@ -148,6 +153,11 @@ export function getRenderMapVisitor(options: GetRenderMapOptions = {}) { }, visitInstruction(node) { + const instructionPath = stack.getPath('instructionNode'); + const program = findProgramNodeFromPath(instructionPath); + if (!program) { + throw new Error('Instruction must be visited inside a program.'); + } // Imports. const imports = new ImportMap(); @@ -249,19 +259,66 @@ export function getRenderMapVisitor(options: GetRenderMapOptions = {}) { instruction: node, instructionArgs, program, - typeManifest, + typeManifest + }), + ); + }, + + visitPda(node) { + const pdaPath = stack.getPath('pdaNode'); + const program = findProgramNodeFromPath(pdaPath); + if (!program) { + throw new Error('PDA must be visited inside a program.'); + } + const imports = new ImportMap(); + + // Process seeds + const seeds = node.seeds.map(seed => { + if (isNode(seed, 'variablePdaSeedNode')) { + const seedManifest = visit(seed.type, typeManifestVisitor); + imports.mergeWith(seedManifest.imports); + const resolvedType = resolveNestedTypeNode(seed.type); + return { ...seed, resolvedType, typeManifest: seedManifest }; + } + if (isNode(seed.value, 'programIdValueNode')) { + return seed; + } + const seedManifest = visit(seed.type, typeManifestVisitor); + const valueManifest = renderValueNode(seed.value, getImportFrom, true); + imports.mergeWith(valueManifest.imports); + const resolvedType = resolveNestedTypeNode(seed.type); + return { ...seed, resolvedType, typeManifest: seedManifest, valueManifest }; + }); + + const hasVariableSeeds = node.seeds.filter(isNodeFilter('variablePdaSeedNode')).length > 0; + const constantSeeds = seeds + .filter(isNodeFilter('constantPdaSeedNode')) + .filter(seed => !isNode(seed.value, 'programIdValueNode')); + + const programAddress = node.programId ?? program?.publicKey; + + return createRenderMap( + `pdas/${snakeCase(node.name)}.rs`, + render('pdasPage.njk', { + constantSeeds, + hasVariableSeeds, + imports: imports.toString(dependencyMap), + pda: node, + program, + programAddress, + seeds, }), ); }, visitProgram(node, { self }) { - program = node; let renders = mergeRenderMaps([ ...node.accounts.map(account => visit(account, self)), ...node.definedTypes.map(type => visit(type, self)), ...getAllInstructionsWithSubs(node, { leavesOnly: !renderParentInstructions, }).map(ix => visit(ix, self)), + ...node.pdas.map(pda => visit(pda, self)), ]); // Errors. @@ -277,7 +334,6 @@ export function getRenderMapVisitor(options: GetRenderMapOptions = {}) { ); } - program = null; return renders; }, @@ -287,6 +343,7 @@ export function getRenderMapVisitor(options: GetRenderMapOptions = {}) { const instructionsToExport = getAllInstructionsWithSubs(node, { leavesOnly: !renderParentInstructions, }); + const pdasToExport = getAllPdas(node); const definedTypesToExport = getAllDefinedTypes(node); const hasAnythingToExport = programsToExport.length > 0 || @@ -311,6 +368,7 @@ export function getRenderMapVisitor(options: GetRenderMapOptions = {}) { ['instructions/mod.rs']: instructionsToExport.length > 0 ? render('instructionsMod.njk', ctx) : undefined, ['mod.rs']: render('rootMod.njk', ctx), + ['pdas/mod.rs']: pdasToExport.length > 0 ? render('pdasMod.njk', ctx) : undefined, ['programs.rs']: programsToExport.length > 0 ? render('programsMod.njk', ctx) : undefined, ['shared.rs']: accountsToExport.length > 0 ? render('sharedPage.njk', ctx) : undefined, ['types/mod.rs']: diff --git a/src/utils/render.ts b/src/utils/render.ts index 0dcff19..df8a24a 100644 --- a/src/utils/render.ts +++ b/src/utils/render.ts @@ -6,7 +6,7 @@ import nunjucks, { ConfigureOptions as NunJucksOptions } from 'nunjucks'; export function rustDocblock(docs: string[]): string { if (docs.length <= 0) return ''; - const lines = docs.map(doc => `/// ${doc}`); + const lines = docs.flatMap(doc => doc.split('\n')).map(doc => `/// ${doc}`); return `${lines.join('\n')}\n`; } diff --git a/test/pdasPage.test.ts b/test/pdasPage.test.ts new file mode 100644 index 0000000..99cfd37 --- /dev/null +++ b/test/pdasPage.test.ts @@ -0,0 +1,163 @@ +import { + constantPdaSeedNodeFromString, + constantPdaSeedNode, + pdaNode, + programNode, + publicKeyTypeNode, + variablePdaSeedNode, + numberTypeNode, + numberValueNode, + bytesTypeNode, + fixedSizeTypeNode, + rootNode, +} from '@codama/nodes'; +import { getFromRenderMap } from '@codama/renderers-core'; +import { visit } from '@codama/visitors-core'; +import { test } from 'vitest'; + +import { getRenderMapVisitor } from '../src'; +import { codeContains } from './_setup'; + +test('it renders a standalone PDA with variable seeds', () => { + // Given a program with a PDA that has variable seeds. + const node = programNode({ + name: 'myProgram', + publicKey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', + pdas: [ + pdaNode({ + name: 'myPda', + seeds: [ + constantPdaSeedNodeFromString('utf8', 'metadata'), + variablePdaSeedNode('mint', publicKeyTypeNode()), + ], + }), + ], + }); + + // When we render it. + const renderMap = visit(node, getRenderMapVisitor()); + + // Then we expect a standalone PDA file to be created. + codeContains(getFromRenderMap(renderMap, 'pdas/my_pda.rs'), [ + 'pub const MY_PDA_SEED: &\'static [u8] = b"metadata";', + 'pub fn create_my_pda_pda(', + 'mint: solana_pubkey::Pubkey,', + 'bump: u8,', + 'pub fn find_my_pda_pda(', + 'mint: &solana_pubkey::Pubkey,', + '-> (solana_pubkey::Pubkey, u8)', + ]); +}); + +test('it renders a PDA with only constant seeds', () => { + // Given a program with a PDA that has only constant seeds. + const node = programNode({ + name: 'myProgram', + publicKey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', + pdas: [ + pdaNode({ + name: 'configPda', + seeds: [ + constantPdaSeedNodeFromString('utf8', 'config'), + constantPdaSeedNode(numberTypeNode('u64'), numberValueNode(1)), + ], + }), + ], + }); + + // When we render it. + const renderMap = visit(node, getRenderMapVisitor()); + + // Then we expect the PDA functions without variable parameters. + codeContains(getFromRenderMap(renderMap, 'pdas/config_pda.rs'), [ + 'pub const CONFIG_PDA_SEED_0: &\'static [u8] = b"config";', + 'pub const CONFIG_PDA_SEED_1: &\'static [u8] = b1;', + 'pub fn create_config_pda_pda(', + 'bump: u8,', + 'pub fn find_config_pda_pda(', + ') -> (solana_pubkey::Pubkey, u8)', + ]); +}); + +test('it renders a PDA with byte array seeds', () => { + // Given a program with a PDA that has byte array seeds. + const node = programNode({ + name: 'myProgram', + publicKey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', + pdas: [ + pdaNode({ + name: 'hashPda', + seeds: [ + constantPdaSeedNodeFromString('utf8', 'hash'), + variablePdaSeedNode('dataHash', fixedSizeTypeNode(bytesTypeNode(), 32)), + ], + }), + ], + }); + + // When we render it. + const renderMap = visit(node, getRenderMapVisitor()); + + // Then we expect the byte array to be handled correctly. + codeContains(getFromRenderMap(renderMap, 'pdas/hash_pda.rs'), [ + 'pub const HASH_PDA_SEED: &\'static [u8] = b"hash";', + 'pub fn create_hash_pda_pda(', + 'data_hash: [u8; 32],', + '&data_hash,', + 'pub fn find_hash_pda_pda(', + 'data_hash: [u8; 32],', + ]); +}); + +test('it renders a PDA module file', () => { + // Given a root node with a program containing multiple PDAs. + const program = programNode({ + name: 'myProgram', + publicKey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', + pdas: [ + pdaNode({ + name: 'firstPda', + seeds: [constantPdaSeedNodeFromString('utf8', 'first')], + }), + pdaNode({ + name: 'secondPda', + seeds: [constantPdaSeedNodeFromString('utf8', 'second')], + }), + ], + }); + const node = rootNode(program); + + // When we render it. + const renderMap = visit(node, getRenderMapVisitor()); + + // Then we expect a module file to be created. + codeContains(getFromRenderMap(renderMap, 'pdas/mod.rs'), [ + 'pub mod first_pda;', + 'pub mod second_pda;', + 'pub use self::first_pda::*;', + 'pub use self::second_pda::*;', + ]); +}); + +test('it includes PDAs module in the root mod file', () => { + // Given a root node with a program containing PDAs. + const program = programNode({ + name: 'myProgram', + publicKey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', + pdas: [ + pdaNode({ + name: 'myPda', + seeds: [constantPdaSeedNodeFromString('utf8', 'test')], + }), + ], + }); + const node = rootNode(program); + + // When we render it. + const renderMap = visit(node, getRenderMapVisitor()); + + // Then we expect the pdas module to be included in the root mod. + codeContains(getFromRenderMap(renderMap, 'mod.rs'), [ + 'pub mod pdas;', + ]); +}); \ No newline at end of file From ca45484c0479336adb551b9a3c98ae630773b28f Mon Sep 17 00:00:00 2001 From: Ian Macalinao Date: Thu, 9 Oct 2025 12:34:12 +0800 Subject: [PATCH 3/5] add governance to test projects --- e2e/test.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/e2e/test.sh b/e2e/test.sh index 498b7a4..8274c91 100755 --- a/e2e/test.sh +++ b/e2e/test.sh @@ -18,5 +18,6 @@ function test_anchor_project() { test_project dummy test_project system test_project memo +test_project governance # test_project meteora # TODO: uncomment after some internal fixes test_anchor_project anchor \ No newline at end of file From 77b25ea578709bd49950905239259d85f01d9ea8 Mon Sep 17 00:00:00 2001 From: Ian Macalinao Date: Thu, 9 Oct 2025 12:41:05 +0800 Subject: [PATCH 4/5] fix generation again --- .changeset/tired-rules-rule.md | 5 ++ e2e/governance/src/generated/mod.rs | 1 + .../generated/pdas/community_token_holding.rs | 40 ++++++++-------- .../generated/pdas/council_token_holding.rs | 40 ++++++++-------- .../src/generated/pdas/governance.rs | 37 +++++--------- .../generated/pdas/governing_token_holding.rs | 40 ++++++++-------- e2e/governance/src/generated/pdas/mod.rs | 28 +++++++++++ .../src/generated/pdas/native_treasury.rs | 31 ++++-------- e2e/governance/src/generated/pdas/proposal.rs | 48 +++++++++---------- .../src/generated/pdas/proposal_deposit.rs | 40 ++++++++-------- .../generated/pdas/proposal_transaction.rs | 48 +++++++++---------- e2e/governance/src/generated/pdas/realm.rs | 31 ++++-------- .../src/generated/pdas/realm_config.rs | 31 ++++-------- .../src/generated/pdas/required_signatory.rs | 40 ++++++++-------- .../src/generated/pdas/signatory_record.rs | 38 +++++++-------- .../src/generated/pdas/token_owner_record.rs | 48 +++++++++---------- .../src/generated/pdas/vote_record.rs | 40 ++++++++-------- src/getRenderMapVisitor.ts | 1 + test/pdasPage.test.ts | 25 +++++----- 19 files changed, 291 insertions(+), 321 deletions(-) create mode 100644 .changeset/tired-rules-rule.md diff --git a/.changeset/tired-rules-rule.md b/.changeset/tired-rules-rule.md new file mode 100644 index 0000000..6574b56 --- /dev/null +++ b/.changeset/tired-rules-rule.md @@ -0,0 +1,5 @@ +--- +'@codama/renderers-rust': patch +--- + +Add support for PDA generation diff --git a/e2e/governance/src/generated/mod.rs b/e2e/governance/src/generated/mod.rs index e0d740a..d37d822 100644 --- a/e2e/governance/src/generated/mod.rs +++ b/e2e/governance/src/generated/mod.rs @@ -8,6 +8,7 @@ pub mod accounts; pub mod errors; pub mod instructions; +pub mod pdas; pub mod programs; pub mod shared; pub mod types; diff --git a/e2e/governance/src/generated/pdas/community_token_holding.rs b/e2e/governance/src/generated/pdas/community_token_holding.rs index 889d1b9..ebc98bb 100644 --- a/e2e/governance/src/generated/pdas/community_token_holding.rs +++ b/e2e/governance/src/generated/pdas/community_token_holding.rs @@ -7,36 +7,34 @@ use crate::SPL_GOVERNANCE_ID; +pub const COMMUNITY_TOKEN_HOLDING_SEED: &'static [u8] = b"governance"; - pub const COMMUNITY_TOKEN_HOLDING_SEED: &'static [u8] = b"governance"; - pub fn create_community_token_holding_pda( - realm: solana_pubkey::Pubkey, - community_mint: solana_pubkey::Pubkey, - bump: u8, + realm: solana_pubkey::Pubkey, + community_mint: solana_pubkey::Pubkey, + bump: u8, ) -> Result { solana_pubkey::Pubkey::create_program_address( &[ - COMMUNITY_TOKEN_HOLDING_SEED, - realm.as_ref(), - community_mint.as_ref(), - &[bump], + COMMUNITY_TOKEN_HOLDING_SEED, + realm.as_ref(), + community_mint.as_ref(), + &[bump], ], - &SPL_GOVERNANCE_ID, - ) + &SPL_GOVERNANCE_ID, + ) } pub fn find_community_token_holding_pda( - realm: &solana_pubkey::Pubkey, - community_mint: &solana_pubkey::Pubkey, - ) -> (solana_pubkey::Pubkey, u8) { + realm: &solana_pubkey::Pubkey, + community_mint: &solana_pubkey::Pubkey, +) -> (solana_pubkey::Pubkey, u8) { solana_pubkey::Pubkey::find_program_address( &[ - COMMUNITY_TOKEN_HOLDING_SEED, - realm.as_ref(), - community_mint.as_ref(), - ], - &SPL_GOVERNANCE_ID, - ) + COMMUNITY_TOKEN_HOLDING_SEED, + realm.as_ref(), + community_mint.as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) } - diff --git a/e2e/governance/src/generated/pdas/council_token_holding.rs b/e2e/governance/src/generated/pdas/council_token_holding.rs index 85e0a52..b5da294 100644 --- a/e2e/governance/src/generated/pdas/council_token_holding.rs +++ b/e2e/governance/src/generated/pdas/council_token_holding.rs @@ -7,36 +7,34 @@ use crate::SPL_GOVERNANCE_ID; +pub const COUNCIL_TOKEN_HOLDING_SEED: &'static [u8] = b"governance"; - pub const COUNCIL_TOKEN_HOLDING_SEED: &'static [u8] = b"governance"; - pub fn create_council_token_holding_pda( - realm: solana_pubkey::Pubkey, - council_mint: solana_pubkey::Pubkey, - bump: u8, + realm: solana_pubkey::Pubkey, + council_mint: solana_pubkey::Pubkey, + bump: u8, ) -> Result { solana_pubkey::Pubkey::create_program_address( &[ - COUNCIL_TOKEN_HOLDING_SEED, - realm.as_ref(), - council_mint.as_ref(), - &[bump], + COUNCIL_TOKEN_HOLDING_SEED, + realm.as_ref(), + council_mint.as_ref(), + &[bump], ], - &SPL_GOVERNANCE_ID, - ) + &SPL_GOVERNANCE_ID, + ) } pub fn find_council_token_holding_pda( - realm: &solana_pubkey::Pubkey, - council_mint: &solana_pubkey::Pubkey, - ) -> (solana_pubkey::Pubkey, u8) { + realm: &solana_pubkey::Pubkey, + council_mint: &solana_pubkey::Pubkey, +) -> (solana_pubkey::Pubkey, u8) { solana_pubkey::Pubkey::find_program_address( &[ - COUNCIL_TOKEN_HOLDING_SEED, - realm.as_ref(), - council_mint.as_ref(), - ], - &SPL_GOVERNANCE_ID, - ) + COUNCIL_TOKEN_HOLDING_SEED, + realm.as_ref(), + council_mint.as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) } - diff --git a/e2e/governance/src/generated/pdas/governance.rs b/e2e/governance/src/generated/pdas/governance.rs index f075a20..bf3bd2b 100644 --- a/e2e/governance/src/generated/pdas/governance.rs +++ b/e2e/governance/src/generated/pdas/governance.rs @@ -7,36 +7,25 @@ use crate::SPL_GOVERNANCE_ID; +pub const GOVERNANCE_SEED: &'static [u8] = b"account-governance"; - pub const GOVERNANCE_SEED: &'static [u8] = b"account-governance"; - pub fn create_governance_pda( - realm: solana_pubkey::Pubkey, - seed: solana_pubkey::Pubkey, - bump: u8, + realm: solana_pubkey::Pubkey, + seed: solana_pubkey::Pubkey, + bump: u8, ) -> Result { solana_pubkey::Pubkey::create_program_address( - &[ - GOVERNANCE_SEED, - realm.as_ref(), - seed.as_ref(), - &[bump], - ], - &SPL_GOVERNANCE_ID, - ) + &[GOVERNANCE_SEED, realm.as_ref(), seed.as_ref(), &[bump]], + &SPL_GOVERNANCE_ID, + ) } pub fn find_governance_pda( - realm: &solana_pubkey::Pubkey, - seed: &solana_pubkey::Pubkey, - ) -> (solana_pubkey::Pubkey, u8) { + realm: &solana_pubkey::Pubkey, + seed: &solana_pubkey::Pubkey, +) -> (solana_pubkey::Pubkey, u8) { solana_pubkey::Pubkey::find_program_address( - &[ - GOVERNANCE_SEED, - realm.as_ref(), - seed.as_ref(), - ], - &SPL_GOVERNANCE_ID, - ) + &[GOVERNANCE_SEED, realm.as_ref(), seed.as_ref()], + &SPL_GOVERNANCE_ID, + ) } - diff --git a/e2e/governance/src/generated/pdas/governing_token_holding.rs b/e2e/governance/src/generated/pdas/governing_token_holding.rs index 4a89c93..dfbe67f 100644 --- a/e2e/governance/src/generated/pdas/governing_token_holding.rs +++ b/e2e/governance/src/generated/pdas/governing_token_holding.rs @@ -7,36 +7,34 @@ use crate::SPL_GOVERNANCE_ID; +pub const GOVERNING_TOKEN_HOLDING_SEED: &'static [u8] = b"governance"; - pub const GOVERNING_TOKEN_HOLDING_SEED: &'static [u8] = b"governance"; - pub fn create_governing_token_holding_pda( - realm: solana_pubkey::Pubkey, - governing_token_mint: solana_pubkey::Pubkey, - bump: u8, + realm: solana_pubkey::Pubkey, + governing_token_mint: solana_pubkey::Pubkey, + bump: u8, ) -> Result { solana_pubkey::Pubkey::create_program_address( &[ - GOVERNING_TOKEN_HOLDING_SEED, - realm.as_ref(), - governing_token_mint.as_ref(), - &[bump], + GOVERNING_TOKEN_HOLDING_SEED, + realm.as_ref(), + governing_token_mint.as_ref(), + &[bump], ], - &SPL_GOVERNANCE_ID, - ) + &SPL_GOVERNANCE_ID, + ) } pub fn find_governing_token_holding_pda( - realm: &solana_pubkey::Pubkey, - governing_token_mint: &solana_pubkey::Pubkey, - ) -> (solana_pubkey::Pubkey, u8) { + realm: &solana_pubkey::Pubkey, + governing_token_mint: &solana_pubkey::Pubkey, +) -> (solana_pubkey::Pubkey, u8) { solana_pubkey::Pubkey::find_program_address( &[ - GOVERNING_TOKEN_HOLDING_SEED, - realm.as_ref(), - governing_token_mint.as_ref(), - ], - &SPL_GOVERNANCE_ID, - ) + GOVERNING_TOKEN_HOLDING_SEED, + realm.as_ref(), + governing_token_mint.as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) } - diff --git a/e2e/governance/src/generated/pdas/mod.rs b/e2e/governance/src/generated/pdas/mod.rs index 8b13789..2fb9d5c 100644 --- a/e2e/governance/src/generated/pdas/mod.rs +++ b/e2e/governance/src/generated/pdas/mod.rs @@ -1 +1,29 @@ +pub mod community_token_holding; +pub mod council_token_holding; +pub mod governance; +pub mod governing_token_holding; +pub mod native_treasury; +pub mod proposal; +pub mod proposal_deposit; +pub mod proposal_transaction; +pub mod realm; +pub mod realm_config; +pub mod required_signatory; +pub mod signatory_record; +pub mod token_owner_record; +pub mod vote_record; +pub use self::community_token_holding::*; +pub use self::council_token_holding::*; +pub use self::governance::*; +pub use self::governing_token_holding::*; +pub use self::native_treasury::*; +pub use self::proposal::*; +pub use self::proposal_deposit::*; +pub use self::proposal_transaction::*; +pub use self::realm::*; +pub use self::realm_config::*; +pub use self::required_signatory::*; +pub use self::signatory_record::*; +pub use self::token_owner_record::*; +pub use self::vote_record::*; diff --git a/e2e/governance/src/generated/pdas/native_treasury.rs b/e2e/governance/src/generated/pdas/native_treasury.rs index 54e36f6..d9b7217 100644 --- a/e2e/governance/src/generated/pdas/native_treasury.rs +++ b/e2e/governance/src/generated/pdas/native_treasury.rs @@ -7,32 +7,21 @@ use crate::SPL_GOVERNANCE_ID; +pub const NATIVE_TREASURY_SEED: &'static [u8] = b"native-treasury"; - pub const NATIVE_TREASURY_SEED: &'static [u8] = b"native-treasury"; - pub fn create_native_treasury_pda( - governance: solana_pubkey::Pubkey, - bump: u8, + governance: solana_pubkey::Pubkey, + bump: u8, ) -> Result { solana_pubkey::Pubkey::create_program_address( - &[ - NATIVE_TREASURY_SEED, - governance.as_ref(), - &[bump], - ], - &SPL_GOVERNANCE_ID, - ) + &[NATIVE_TREASURY_SEED, governance.as_ref(), &[bump]], + &SPL_GOVERNANCE_ID, + ) } -pub fn find_native_treasury_pda( - governance: &solana_pubkey::Pubkey, - ) -> (solana_pubkey::Pubkey, u8) { +pub fn find_native_treasury_pda(governance: &solana_pubkey::Pubkey) -> (solana_pubkey::Pubkey, u8) { solana_pubkey::Pubkey::find_program_address( - &[ - NATIVE_TREASURY_SEED, - governance.as_ref(), - ], - &SPL_GOVERNANCE_ID, - ) + &[NATIVE_TREASURY_SEED, governance.as_ref()], + &SPL_GOVERNANCE_ID, + ) } - diff --git a/e2e/governance/src/generated/pdas/proposal.rs b/e2e/governance/src/generated/pdas/proposal.rs index 109bc99..2726eb4 100644 --- a/e2e/governance/src/generated/pdas/proposal.rs +++ b/e2e/governance/src/generated/pdas/proposal.rs @@ -7,40 +7,38 @@ use crate::SPL_GOVERNANCE_ID; +pub const PROPOSAL_SEED: &'static [u8] = b"governance"; - pub const PROPOSAL_SEED: &'static [u8] = b"governance"; - pub fn create_proposal_pda( - governance: solana_pubkey::Pubkey, - governing_token_mint: solana_pubkey::Pubkey, - proposal_seed: solana_pubkey::Pubkey, - bump: u8, + governance: solana_pubkey::Pubkey, + governing_token_mint: solana_pubkey::Pubkey, + proposal_seed: solana_pubkey::Pubkey, + bump: u8, ) -> Result { solana_pubkey::Pubkey::create_program_address( &[ - PROPOSAL_SEED, - governance.as_ref(), - governing_token_mint.as_ref(), - proposal_seed.as_ref(), - &[bump], + PROPOSAL_SEED, + governance.as_ref(), + governing_token_mint.as_ref(), + proposal_seed.as_ref(), + &[bump], ], - &SPL_GOVERNANCE_ID, - ) + &SPL_GOVERNANCE_ID, + ) } pub fn find_proposal_pda( - governance: &solana_pubkey::Pubkey, - governing_token_mint: &solana_pubkey::Pubkey, - proposal_seed: &solana_pubkey::Pubkey, - ) -> (solana_pubkey::Pubkey, u8) { + governance: &solana_pubkey::Pubkey, + governing_token_mint: &solana_pubkey::Pubkey, + proposal_seed: &solana_pubkey::Pubkey, +) -> (solana_pubkey::Pubkey, u8) { solana_pubkey::Pubkey::find_program_address( &[ - PROPOSAL_SEED, - governance.as_ref(), - governing_token_mint.as_ref(), - proposal_seed.as_ref(), - ], - &SPL_GOVERNANCE_ID, - ) + PROPOSAL_SEED, + governance.as_ref(), + governing_token_mint.as_ref(), + proposal_seed.as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) } - diff --git a/e2e/governance/src/generated/pdas/proposal_deposit.rs b/e2e/governance/src/generated/pdas/proposal_deposit.rs index 207b043..83a1a1a 100644 --- a/e2e/governance/src/generated/pdas/proposal_deposit.rs +++ b/e2e/governance/src/generated/pdas/proposal_deposit.rs @@ -7,36 +7,34 @@ use crate::SPL_GOVERNANCE_ID; +pub const PROPOSAL_DEPOSIT_SEED: &'static [u8] = b"proposal-deposit"; - pub const PROPOSAL_DEPOSIT_SEED: &'static [u8] = b"proposal-deposit"; - pub fn create_proposal_deposit_pda( - proposal: solana_pubkey::Pubkey, - deposit_payer: solana_pubkey::Pubkey, - bump: u8, + proposal: solana_pubkey::Pubkey, + deposit_payer: solana_pubkey::Pubkey, + bump: u8, ) -> Result { solana_pubkey::Pubkey::create_program_address( &[ - PROPOSAL_DEPOSIT_SEED, - proposal.as_ref(), - deposit_payer.as_ref(), - &[bump], + PROPOSAL_DEPOSIT_SEED, + proposal.as_ref(), + deposit_payer.as_ref(), + &[bump], ], - &SPL_GOVERNANCE_ID, - ) + &SPL_GOVERNANCE_ID, + ) } pub fn find_proposal_deposit_pda( - proposal: &solana_pubkey::Pubkey, - deposit_payer: &solana_pubkey::Pubkey, - ) -> (solana_pubkey::Pubkey, u8) { + proposal: &solana_pubkey::Pubkey, + deposit_payer: &solana_pubkey::Pubkey, +) -> (solana_pubkey::Pubkey, u8) { solana_pubkey::Pubkey::find_program_address( &[ - PROPOSAL_DEPOSIT_SEED, - proposal.as_ref(), - deposit_payer.as_ref(), - ], - &SPL_GOVERNANCE_ID, - ) + PROPOSAL_DEPOSIT_SEED, + proposal.as_ref(), + deposit_payer.as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) } - diff --git a/e2e/governance/src/generated/pdas/proposal_transaction.rs b/e2e/governance/src/generated/pdas/proposal_transaction.rs index a107021..7aee3c9 100644 --- a/e2e/governance/src/generated/pdas/proposal_transaction.rs +++ b/e2e/governance/src/generated/pdas/proposal_transaction.rs @@ -7,40 +7,38 @@ use crate::SPL_GOVERNANCE_ID; +pub const PROPOSAL_TRANSACTION_SEED: &'static [u8] = b"governance"; - pub const PROPOSAL_TRANSACTION_SEED: &'static [u8] = b"governance"; - pub fn create_proposal_transaction_pda( - proposal: solana_pubkey::Pubkey, - option_index: u8, - index: u16, - bump: u8, + proposal: solana_pubkey::Pubkey, + option_index: u8, + index: u16, + bump: u8, ) -> Result { solana_pubkey::Pubkey::create_program_address( &[ - PROPOSAL_TRANSACTION_SEED, - proposal.as_ref(), - option_index.to_string().as_ref(), - index.to_string().as_ref(), - &[bump], + PROPOSAL_TRANSACTION_SEED, + proposal.as_ref(), + option_index.to_string().as_ref(), + index.to_string().as_ref(), + &[bump], ], - &SPL_GOVERNANCE_ID, - ) + &SPL_GOVERNANCE_ID, + ) } pub fn find_proposal_transaction_pda( - proposal: &solana_pubkey::Pubkey, - option_index: u8, - index: u16, - ) -> (solana_pubkey::Pubkey, u8) { + proposal: &solana_pubkey::Pubkey, + option_index: u8, + index: u16, +) -> (solana_pubkey::Pubkey, u8) { solana_pubkey::Pubkey::find_program_address( &[ - PROPOSAL_TRANSACTION_SEED, - proposal.as_ref(), - option_index.to_string().as_ref(), - index.to_string().as_ref(), - ], - &SPL_GOVERNANCE_ID, - ) + PROPOSAL_TRANSACTION_SEED, + proposal.as_ref(), + option_index.to_string().as_ref(), + index.to_string().as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) } - diff --git a/e2e/governance/src/generated/pdas/realm.rs b/e2e/governance/src/generated/pdas/realm.rs index 1d72486..de693bc 100644 --- a/e2e/governance/src/generated/pdas/realm.rs +++ b/e2e/governance/src/generated/pdas/realm.rs @@ -7,32 +7,21 @@ use crate::SPL_GOVERNANCE_ID; +pub const REALM_SEED: &'static [u8] = b"governance"; - pub const REALM_SEED: &'static [u8] = b"governance"; - pub fn create_realm_pda( - name: RemainderStr, - bump: u8, + name: RemainderStr, + bump: u8, ) -> Result { solana_pubkey::Pubkey::create_program_address( - &[ - REALM_SEED, - name.to_string().as_ref(), - &[bump], - ], - &SPL_GOVERNANCE_ID, - ) + &[REALM_SEED, name.to_string().as_ref(), &[bump]], + &SPL_GOVERNANCE_ID, + ) } -pub fn find_realm_pda( - name: RemainderStr, - ) -> (solana_pubkey::Pubkey, u8) { +pub fn find_realm_pda(name: RemainderStr) -> (solana_pubkey::Pubkey, u8) { solana_pubkey::Pubkey::find_program_address( - &[ - REALM_SEED, - name.to_string().as_ref(), - ], - &SPL_GOVERNANCE_ID, - ) + &[REALM_SEED, name.to_string().as_ref()], + &SPL_GOVERNANCE_ID, + ) } - diff --git a/e2e/governance/src/generated/pdas/realm_config.rs b/e2e/governance/src/generated/pdas/realm_config.rs index ee86683..ee7990c 100644 --- a/e2e/governance/src/generated/pdas/realm_config.rs +++ b/e2e/governance/src/generated/pdas/realm_config.rs @@ -7,32 +7,21 @@ use crate::SPL_GOVERNANCE_ID; +pub const REALM_CONFIG_SEED: &'static [u8] = b"realm-config"; - pub const REALM_CONFIG_SEED: &'static [u8] = b"realm-config"; - pub fn create_realm_config_pda( - realm: solana_pubkey::Pubkey, - bump: u8, + realm: solana_pubkey::Pubkey, + bump: u8, ) -> Result { solana_pubkey::Pubkey::create_program_address( - &[ - REALM_CONFIG_SEED, - realm.as_ref(), - &[bump], - ], - &SPL_GOVERNANCE_ID, - ) + &[REALM_CONFIG_SEED, realm.as_ref(), &[bump]], + &SPL_GOVERNANCE_ID, + ) } -pub fn find_realm_config_pda( - realm: &solana_pubkey::Pubkey, - ) -> (solana_pubkey::Pubkey, u8) { +pub fn find_realm_config_pda(realm: &solana_pubkey::Pubkey) -> (solana_pubkey::Pubkey, u8) { solana_pubkey::Pubkey::find_program_address( - &[ - REALM_CONFIG_SEED, - realm.as_ref(), - ], - &SPL_GOVERNANCE_ID, - ) + &[REALM_CONFIG_SEED, realm.as_ref()], + &SPL_GOVERNANCE_ID, + ) } - diff --git a/e2e/governance/src/generated/pdas/required_signatory.rs b/e2e/governance/src/generated/pdas/required_signatory.rs index f53afd5..2d906ad 100644 --- a/e2e/governance/src/generated/pdas/required_signatory.rs +++ b/e2e/governance/src/generated/pdas/required_signatory.rs @@ -7,36 +7,34 @@ use crate::SPL_GOVERNANCE_ID; +pub const REQUIRED_SIGNATORY_SEED: &'static [u8] = b"required-signatory"; - pub const REQUIRED_SIGNATORY_SEED: &'static [u8] = b"required-signatory"; - pub fn create_required_signatory_pda( - governance: solana_pubkey::Pubkey, - signatory: solana_pubkey::Pubkey, - bump: u8, + governance: solana_pubkey::Pubkey, + signatory: solana_pubkey::Pubkey, + bump: u8, ) -> Result { solana_pubkey::Pubkey::create_program_address( &[ - REQUIRED_SIGNATORY_SEED, - governance.as_ref(), - signatory.as_ref(), - &[bump], + REQUIRED_SIGNATORY_SEED, + governance.as_ref(), + signatory.as_ref(), + &[bump], ], - &SPL_GOVERNANCE_ID, - ) + &SPL_GOVERNANCE_ID, + ) } pub fn find_required_signatory_pda( - governance: &solana_pubkey::Pubkey, - signatory: &solana_pubkey::Pubkey, - ) -> (solana_pubkey::Pubkey, u8) { + governance: &solana_pubkey::Pubkey, + signatory: &solana_pubkey::Pubkey, +) -> (solana_pubkey::Pubkey, u8) { solana_pubkey::Pubkey::find_program_address( &[ - REQUIRED_SIGNATORY_SEED, - governance.as_ref(), - signatory.as_ref(), - ], - &SPL_GOVERNANCE_ID, - ) + REQUIRED_SIGNATORY_SEED, + governance.as_ref(), + signatory.as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) } - diff --git a/e2e/governance/src/generated/pdas/signatory_record.rs b/e2e/governance/src/generated/pdas/signatory_record.rs index 295b3e3..1099693 100644 --- a/e2e/governance/src/generated/pdas/signatory_record.rs +++ b/e2e/governance/src/generated/pdas/signatory_record.rs @@ -7,36 +7,30 @@ use crate::SPL_GOVERNANCE_ID; +pub const SIGNATORY_RECORD_SEED: &'static [u8] = b"governance"; - pub const SIGNATORY_RECORD_SEED: &'static [u8] = b"governance"; - pub fn create_signatory_record_pda( - proposal: solana_pubkey::Pubkey, - signatory: solana_pubkey::Pubkey, - bump: u8, + proposal: solana_pubkey::Pubkey, + signatory: solana_pubkey::Pubkey, + bump: u8, ) -> Result { solana_pubkey::Pubkey::create_program_address( &[ - SIGNATORY_RECORD_SEED, - proposal.as_ref(), - signatory.as_ref(), - &[bump], + SIGNATORY_RECORD_SEED, + proposal.as_ref(), + signatory.as_ref(), + &[bump], ], - &SPL_GOVERNANCE_ID, - ) + &SPL_GOVERNANCE_ID, + ) } pub fn find_signatory_record_pda( - proposal: &solana_pubkey::Pubkey, - signatory: &solana_pubkey::Pubkey, - ) -> (solana_pubkey::Pubkey, u8) { + proposal: &solana_pubkey::Pubkey, + signatory: &solana_pubkey::Pubkey, +) -> (solana_pubkey::Pubkey, u8) { solana_pubkey::Pubkey::find_program_address( - &[ - SIGNATORY_RECORD_SEED, - proposal.as_ref(), - signatory.as_ref(), - ], - &SPL_GOVERNANCE_ID, - ) + &[SIGNATORY_RECORD_SEED, proposal.as_ref(), signatory.as_ref()], + &SPL_GOVERNANCE_ID, + ) } - diff --git a/e2e/governance/src/generated/pdas/token_owner_record.rs b/e2e/governance/src/generated/pdas/token_owner_record.rs index a7672e5..3786066 100644 --- a/e2e/governance/src/generated/pdas/token_owner_record.rs +++ b/e2e/governance/src/generated/pdas/token_owner_record.rs @@ -7,40 +7,38 @@ use crate::SPL_GOVERNANCE_ID; +pub const TOKEN_OWNER_RECORD_SEED: &'static [u8] = b"governance"; - pub const TOKEN_OWNER_RECORD_SEED: &'static [u8] = b"governance"; - pub fn create_token_owner_record_pda( - realm: solana_pubkey::Pubkey, - governing_token_mint: solana_pubkey::Pubkey, - governing_token_owner: solana_pubkey::Pubkey, - bump: u8, + realm: solana_pubkey::Pubkey, + governing_token_mint: solana_pubkey::Pubkey, + governing_token_owner: solana_pubkey::Pubkey, + bump: u8, ) -> Result { solana_pubkey::Pubkey::create_program_address( &[ - TOKEN_OWNER_RECORD_SEED, - realm.as_ref(), - governing_token_mint.as_ref(), - governing_token_owner.as_ref(), - &[bump], + TOKEN_OWNER_RECORD_SEED, + realm.as_ref(), + governing_token_mint.as_ref(), + governing_token_owner.as_ref(), + &[bump], ], - &SPL_GOVERNANCE_ID, - ) + &SPL_GOVERNANCE_ID, + ) } pub fn find_token_owner_record_pda( - realm: &solana_pubkey::Pubkey, - governing_token_mint: &solana_pubkey::Pubkey, - governing_token_owner: &solana_pubkey::Pubkey, - ) -> (solana_pubkey::Pubkey, u8) { + realm: &solana_pubkey::Pubkey, + governing_token_mint: &solana_pubkey::Pubkey, + governing_token_owner: &solana_pubkey::Pubkey, +) -> (solana_pubkey::Pubkey, u8) { solana_pubkey::Pubkey::find_program_address( &[ - TOKEN_OWNER_RECORD_SEED, - realm.as_ref(), - governing_token_mint.as_ref(), - governing_token_owner.as_ref(), - ], - &SPL_GOVERNANCE_ID, - ) + TOKEN_OWNER_RECORD_SEED, + realm.as_ref(), + governing_token_mint.as_ref(), + governing_token_owner.as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) } - diff --git a/e2e/governance/src/generated/pdas/vote_record.rs b/e2e/governance/src/generated/pdas/vote_record.rs index 4443f88..7789e57 100644 --- a/e2e/governance/src/generated/pdas/vote_record.rs +++ b/e2e/governance/src/generated/pdas/vote_record.rs @@ -7,36 +7,34 @@ use crate::SPL_GOVERNANCE_ID; +pub const VOTE_RECORD_SEED: &'static [u8] = b"governance"; - pub const VOTE_RECORD_SEED: &'static [u8] = b"governance"; - pub fn create_vote_record_pda( - proposal: solana_pubkey::Pubkey, - token_owner_record: solana_pubkey::Pubkey, - bump: u8, + proposal: solana_pubkey::Pubkey, + token_owner_record: solana_pubkey::Pubkey, + bump: u8, ) -> Result { solana_pubkey::Pubkey::create_program_address( &[ - VOTE_RECORD_SEED, - proposal.as_ref(), - token_owner_record.as_ref(), - &[bump], + VOTE_RECORD_SEED, + proposal.as_ref(), + token_owner_record.as_ref(), + &[bump], ], - &SPL_GOVERNANCE_ID, - ) + &SPL_GOVERNANCE_ID, + ) } pub fn find_vote_record_pda( - proposal: &solana_pubkey::Pubkey, - token_owner_record: &solana_pubkey::Pubkey, - ) -> (solana_pubkey::Pubkey, u8) { + proposal: &solana_pubkey::Pubkey, + token_owner_record: &solana_pubkey::Pubkey, +) -> (solana_pubkey::Pubkey, u8) { solana_pubkey::Pubkey::find_program_address( &[ - VOTE_RECORD_SEED, - proposal.as_ref(), - token_owner_record.as_ref(), - ], - &SPL_GOVERNANCE_ID, - ) + VOTE_RECORD_SEED, + proposal.as_ref(), + token_owner_record.as_ref(), + ], + &SPL_GOVERNANCE_ID, + ) } - diff --git a/src/getRenderMapVisitor.ts b/src/getRenderMapVisitor.ts index 9479a3a..114bf2e 100644 --- a/src/getRenderMapVisitor.ts +++ b/src/getRenderMapVisitor.ts @@ -356,6 +356,7 @@ export function getRenderMapVisitor(options: GetRenderMapOptions = {}) { definedTypesToExport, hasAnythingToExport, instructionsToExport, + pdasToExport, programsToExport, root: node, }; diff --git a/test/pdasPage.test.ts b/test/pdasPage.test.ts index 99cfd37..1448961 100644 --- a/test/pdasPage.test.ts +++ b/test/pdasPage.test.ts @@ -1,15 +1,16 @@ import { - constantPdaSeedNodeFromString, + bytesTypeNode, constantPdaSeedNode, + constantPdaSeedNodeFromString, + fixedSizeTypeNode, + getAllPdas, + numberTypeNode, + numberValueNode, pdaNode, programNode, publicKeyTypeNode, - variablePdaSeedNode, - numberTypeNode, - numberValueNode, - bytesTypeNode, - fixedSizeTypeNode, rootNode, + variablePdaSeedNode, } from '@codama/nodes'; import { getFromRenderMap } from '@codama/renderers-core'; import { visit } from '@codama/visitors-core'; @@ -22,7 +23,6 @@ test('it renders a standalone PDA with variable seeds', () => { // Given a program with a PDA that has variable seeds. const node = programNode({ name: 'myProgram', - publicKey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', pdas: [ pdaNode({ name: 'myPda', @@ -32,6 +32,7 @@ test('it renders a standalone PDA with variable seeds', () => { ], }), ], + publicKey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', }); // When we render it. @@ -53,7 +54,6 @@ test('it renders a PDA with only constant seeds', () => { // Given a program with a PDA that has only constant seeds. const node = programNode({ name: 'myProgram', - publicKey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', pdas: [ pdaNode({ name: 'configPda', @@ -63,6 +63,7 @@ test('it renders a PDA with only constant seeds', () => { ], }), ], + publicKey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', }); // When we render it. @@ -83,7 +84,6 @@ test('it renders a PDA with byte array seeds', () => { // Given a program with a PDA that has byte array seeds. const node = programNode({ name: 'myProgram', - publicKey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', pdas: [ pdaNode({ name: 'hashPda', @@ -93,6 +93,7 @@ test('it renders a PDA with byte array seeds', () => { ], }), ], + publicKey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', }); // When we render it. @@ -113,7 +114,6 @@ test('it renders a PDA module file', () => { // Given a root node with a program containing multiple PDAs. const program = programNode({ name: 'myProgram', - publicKey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', pdas: [ pdaNode({ name: 'firstPda', @@ -124,6 +124,7 @@ test('it renders a PDA module file', () => { seeds: [constantPdaSeedNodeFromString('utf8', 'second')], }), ], + publicKey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', }); const node = rootNode(program); @@ -143,16 +144,18 @@ test('it includes PDAs module in the root mod file', () => { // Given a root node with a program containing PDAs. const program = programNode({ name: 'myProgram', - publicKey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', pdas: [ pdaNode({ name: 'myPda', seeds: [constantPdaSeedNodeFromString('utf8', 'test')], }), ], + publicKey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', }); const node = rootNode(program); + console.log("PDAs", getAllPdas(node)) + // When we render it. const renderMap = visit(node, getRenderMapVisitor()); From c5c6fcb8806c6bcc912254644d74083c63dc7032 Mon Sep 17 00:00:00 2001 From: Ian Macalinao Date: Thu, 9 Oct 2025 12:43:31 +0800 Subject: [PATCH 5/5] rustdocs for pda generators --- e2e/governance/src/generated/pdas/community_token_holding.rs | 4 ++-- e2e/governance/src/generated/pdas/council_token_holding.rs | 4 ++-- e2e/governance/src/generated/pdas/governance.rs | 4 ++-- e2e/governance/src/generated/pdas/governing_token_holding.rs | 4 ++-- e2e/governance/src/generated/pdas/native_treasury.rs | 4 ++-- e2e/governance/src/generated/pdas/proposal.rs | 4 ++-- e2e/governance/src/generated/pdas/proposal_deposit.rs | 4 ++-- e2e/governance/src/generated/pdas/proposal_transaction.rs | 4 ++-- e2e/governance/src/generated/pdas/realm.rs | 4 ++-- e2e/governance/src/generated/pdas/realm_config.rs | 4 ++-- e2e/governance/src/generated/pdas/required_signatory.rs | 4 ++-- e2e/governance/src/generated/pdas/signatory_record.rs | 4 ++-- e2e/governance/src/generated/pdas/token_owner_record.rs | 4 ++-- e2e/governance/src/generated/pdas/vote_record.rs | 4 ++-- public/templates/pdasPage.njk | 2 ++ 15 files changed, 30 insertions(+), 28 deletions(-) diff --git a/e2e/governance/src/generated/pdas/community_token_holding.rs b/e2e/governance/src/generated/pdas/community_token_holding.rs index ebc98bb..c014544 100644 --- a/e2e/governance/src/generated/pdas/community_token_holding.rs +++ b/e2e/governance/src/generated/pdas/community_token_holding.rs @@ -8,7 +8,7 @@ use crate::SPL_GOVERNANCE_ID; pub const COMMUNITY_TOKEN_HOLDING_SEED: &'static [u8] = b"governance"; - +/// Community token holding account of a realm pub fn create_community_token_holding_pda( realm: solana_pubkey::Pubkey, community_mint: solana_pubkey::Pubkey, @@ -24,7 +24,7 @@ pub fn create_community_token_holding_pda( &SPL_GOVERNANCE_ID, ) } - +/// Community token holding account of a realm pub fn find_community_token_holding_pda( realm: &solana_pubkey::Pubkey, community_mint: &solana_pubkey::Pubkey, diff --git a/e2e/governance/src/generated/pdas/council_token_holding.rs b/e2e/governance/src/generated/pdas/council_token_holding.rs index b5da294..6403a68 100644 --- a/e2e/governance/src/generated/pdas/council_token_holding.rs +++ b/e2e/governance/src/generated/pdas/council_token_holding.rs @@ -8,7 +8,7 @@ use crate::SPL_GOVERNANCE_ID; pub const COUNCIL_TOKEN_HOLDING_SEED: &'static [u8] = b"governance"; - +/// Council token holding account of a realm pub fn create_council_token_holding_pda( realm: solana_pubkey::Pubkey, council_mint: solana_pubkey::Pubkey, @@ -24,7 +24,7 @@ pub fn create_council_token_holding_pda( &SPL_GOVERNANCE_ID, ) } - +/// Council token holding account of a realm pub fn find_council_token_holding_pda( realm: &solana_pubkey::Pubkey, council_mint: &solana_pubkey::Pubkey, diff --git a/e2e/governance/src/generated/pdas/governance.rs b/e2e/governance/src/generated/pdas/governance.rs index bf3bd2b..fda84c7 100644 --- a/e2e/governance/src/generated/pdas/governance.rs +++ b/e2e/governance/src/generated/pdas/governance.rs @@ -8,7 +8,7 @@ use crate::SPL_GOVERNANCE_ID; pub const GOVERNANCE_SEED: &'static [u8] = b"account-governance"; - +/// Governance account within a realm pub fn create_governance_pda( realm: solana_pubkey::Pubkey, seed: solana_pubkey::Pubkey, @@ -19,7 +19,7 @@ pub fn create_governance_pda( &SPL_GOVERNANCE_ID, ) } - +/// Governance account within a realm pub fn find_governance_pda( realm: &solana_pubkey::Pubkey, seed: &solana_pubkey::Pubkey, diff --git a/e2e/governance/src/generated/pdas/governing_token_holding.rs b/e2e/governance/src/generated/pdas/governing_token_holding.rs index dfbe67f..301bd8c 100644 --- a/e2e/governance/src/generated/pdas/governing_token_holding.rs +++ b/e2e/governance/src/generated/pdas/governing_token_holding.rs @@ -8,7 +8,7 @@ use crate::SPL_GOVERNANCE_ID; pub const GOVERNING_TOKEN_HOLDING_SEED: &'static [u8] = b"governance"; - +/// Governing token holding account pub fn create_governing_token_holding_pda( realm: solana_pubkey::Pubkey, governing_token_mint: solana_pubkey::Pubkey, @@ -24,7 +24,7 @@ pub fn create_governing_token_holding_pda( &SPL_GOVERNANCE_ID, ) } - +/// Governing token holding account pub fn find_governing_token_holding_pda( realm: &solana_pubkey::Pubkey, governing_token_mint: &solana_pubkey::Pubkey, diff --git a/e2e/governance/src/generated/pdas/native_treasury.rs b/e2e/governance/src/generated/pdas/native_treasury.rs index d9b7217..1dc03e3 100644 --- a/e2e/governance/src/generated/pdas/native_treasury.rs +++ b/e2e/governance/src/generated/pdas/native_treasury.rs @@ -8,7 +8,7 @@ use crate::SPL_GOVERNANCE_ID; pub const NATIVE_TREASURY_SEED: &'static [u8] = b"native-treasury"; - +/// Governance's native SOL treasury account pub fn create_native_treasury_pda( governance: solana_pubkey::Pubkey, bump: u8, @@ -18,7 +18,7 @@ pub fn create_native_treasury_pda( &SPL_GOVERNANCE_ID, ) } - +/// Governance's native SOL treasury account pub fn find_native_treasury_pda(governance: &solana_pubkey::Pubkey) -> (solana_pubkey::Pubkey, u8) { solana_pubkey::Pubkey::find_program_address( &[NATIVE_TREASURY_SEED, governance.as_ref()], diff --git a/e2e/governance/src/generated/pdas/proposal.rs b/e2e/governance/src/generated/pdas/proposal.rs index 2726eb4..6c27861 100644 --- a/e2e/governance/src/generated/pdas/proposal.rs +++ b/e2e/governance/src/generated/pdas/proposal.rs @@ -8,7 +8,7 @@ use crate::SPL_GOVERNANCE_ID; pub const PROPOSAL_SEED: &'static [u8] = b"governance"; - +/// Governance proposal pub fn create_proposal_pda( governance: solana_pubkey::Pubkey, governing_token_mint: solana_pubkey::Pubkey, @@ -26,7 +26,7 @@ pub fn create_proposal_pda( &SPL_GOVERNANCE_ID, ) } - +/// Governance proposal pub fn find_proposal_pda( governance: &solana_pubkey::Pubkey, governing_token_mint: &solana_pubkey::Pubkey, diff --git a/e2e/governance/src/generated/pdas/proposal_deposit.rs b/e2e/governance/src/generated/pdas/proposal_deposit.rs index 83a1a1a..4953042 100644 --- a/e2e/governance/src/generated/pdas/proposal_deposit.rs +++ b/e2e/governance/src/generated/pdas/proposal_deposit.rs @@ -8,7 +8,7 @@ use crate::SPL_GOVERNANCE_ID; pub const PROPOSAL_DEPOSIT_SEED: &'static [u8] = b"proposal-deposit"; - +/// Proposal deposit made by a specific payer pub fn create_proposal_deposit_pda( proposal: solana_pubkey::Pubkey, deposit_payer: solana_pubkey::Pubkey, @@ -24,7 +24,7 @@ pub fn create_proposal_deposit_pda( &SPL_GOVERNANCE_ID, ) } - +/// Proposal deposit made by a specific payer pub fn find_proposal_deposit_pda( proposal: &solana_pubkey::Pubkey, deposit_payer: &solana_pubkey::Pubkey, diff --git a/e2e/governance/src/generated/pdas/proposal_transaction.rs b/e2e/governance/src/generated/pdas/proposal_transaction.rs index 7aee3c9..952345e 100644 --- a/e2e/governance/src/generated/pdas/proposal_transaction.rs +++ b/e2e/governance/src/generated/pdas/proposal_transaction.rs @@ -8,7 +8,7 @@ use crate::SPL_GOVERNANCE_ID; pub const PROPOSAL_TRANSACTION_SEED: &'static [u8] = b"governance"; - +/// Transaction within a proposal option pub fn create_proposal_transaction_pda( proposal: solana_pubkey::Pubkey, option_index: u8, @@ -26,7 +26,7 @@ pub fn create_proposal_transaction_pda( &SPL_GOVERNANCE_ID, ) } - +/// Transaction within a proposal option pub fn find_proposal_transaction_pda( proposal: &solana_pubkey::Pubkey, option_index: u8, diff --git a/e2e/governance/src/generated/pdas/realm.rs b/e2e/governance/src/generated/pdas/realm.rs index de693bc..84f5c58 100644 --- a/e2e/governance/src/generated/pdas/realm.rs +++ b/e2e/governance/src/generated/pdas/realm.rs @@ -8,7 +8,7 @@ use crate::SPL_GOVERNANCE_ID; pub const REALM_SEED: &'static [u8] = b"governance"; - +/// Realm account identified by its name pub fn create_realm_pda( name: RemainderStr, bump: u8, @@ -18,7 +18,7 @@ pub fn create_realm_pda( &SPL_GOVERNANCE_ID, ) } - +/// Realm account identified by its name pub fn find_realm_pda(name: RemainderStr) -> (solana_pubkey::Pubkey, u8) { solana_pubkey::Pubkey::find_program_address( &[REALM_SEED, name.to_string().as_ref()], diff --git a/e2e/governance/src/generated/pdas/realm_config.rs b/e2e/governance/src/generated/pdas/realm_config.rs index ee7990c..d285ea4 100644 --- a/e2e/governance/src/generated/pdas/realm_config.rs +++ b/e2e/governance/src/generated/pdas/realm_config.rs @@ -8,7 +8,7 @@ use crate::SPL_GOVERNANCE_ID; pub const REALM_CONFIG_SEED: &'static [u8] = b"realm-config"; - +/// Configuration of a realm pub fn create_realm_config_pda( realm: solana_pubkey::Pubkey, bump: u8, @@ -18,7 +18,7 @@ pub fn create_realm_config_pda( &SPL_GOVERNANCE_ID, ) } - +/// Configuration of a realm pub fn find_realm_config_pda(realm: &solana_pubkey::Pubkey) -> (solana_pubkey::Pubkey, u8) { solana_pubkey::Pubkey::find_program_address( &[REALM_CONFIG_SEED, realm.as_ref()], diff --git a/e2e/governance/src/generated/pdas/required_signatory.rs b/e2e/governance/src/generated/pdas/required_signatory.rs index 2d906ad..0d43371 100644 --- a/e2e/governance/src/generated/pdas/required_signatory.rs +++ b/e2e/governance/src/generated/pdas/required_signatory.rs @@ -8,7 +8,7 @@ use crate::SPL_GOVERNANCE_ID; pub const REQUIRED_SIGNATORY_SEED: &'static [u8] = b"required-signatory"; - +/// Required signatory on a governance pub fn create_required_signatory_pda( governance: solana_pubkey::Pubkey, signatory: solana_pubkey::Pubkey, @@ -24,7 +24,7 @@ pub fn create_required_signatory_pda( &SPL_GOVERNANCE_ID, ) } - +/// Required signatory on a governance pub fn find_required_signatory_pda( governance: &solana_pubkey::Pubkey, signatory: &solana_pubkey::Pubkey, diff --git a/e2e/governance/src/generated/pdas/signatory_record.rs b/e2e/governance/src/generated/pdas/signatory_record.rs index 1099693..b029efe 100644 --- a/e2e/governance/src/generated/pdas/signatory_record.rs +++ b/e2e/governance/src/generated/pdas/signatory_record.rs @@ -8,7 +8,7 @@ use crate::SPL_GOVERNANCE_ID; pub const SIGNATORY_RECORD_SEED: &'static [u8] = b"governance"; - +/// Signatory's record on a proposal pub fn create_signatory_record_pda( proposal: solana_pubkey::Pubkey, signatory: solana_pubkey::Pubkey, @@ -24,7 +24,7 @@ pub fn create_signatory_record_pda( &SPL_GOVERNANCE_ID, ) } - +/// Signatory's record on a proposal pub fn find_signatory_record_pda( proposal: &solana_pubkey::Pubkey, signatory: &solana_pubkey::Pubkey, diff --git a/e2e/governance/src/generated/pdas/token_owner_record.rs b/e2e/governance/src/generated/pdas/token_owner_record.rs index 3786066..8199ea6 100644 --- a/e2e/governance/src/generated/pdas/token_owner_record.rs +++ b/e2e/governance/src/generated/pdas/token_owner_record.rs @@ -8,7 +8,7 @@ use crate::SPL_GOVERNANCE_ID; pub const TOKEN_OWNER_RECORD_SEED: &'static [u8] = b"governance"; - +/// Token owner's record within a realm pub fn create_token_owner_record_pda( realm: solana_pubkey::Pubkey, governing_token_mint: solana_pubkey::Pubkey, @@ -26,7 +26,7 @@ pub fn create_token_owner_record_pda( &SPL_GOVERNANCE_ID, ) } - +/// Token owner's record within a realm pub fn find_token_owner_record_pda( realm: &solana_pubkey::Pubkey, governing_token_mint: &solana_pubkey::Pubkey, diff --git a/e2e/governance/src/generated/pdas/vote_record.rs b/e2e/governance/src/generated/pdas/vote_record.rs index 7789e57..366cc74 100644 --- a/e2e/governance/src/generated/pdas/vote_record.rs +++ b/e2e/governance/src/generated/pdas/vote_record.rs @@ -8,7 +8,7 @@ use crate::SPL_GOVERNANCE_ID; pub const VOTE_RECORD_SEED: &'static [u8] = b"governance"; - +/// Vote record on a proposal pub fn create_vote_record_pda( proposal: solana_pubkey::Pubkey, token_owner_record: solana_pubkey::Pubkey, @@ -24,7 +24,7 @@ pub fn create_vote_record_pda( &SPL_GOVERNANCE_ID, ) } - +/// Vote record on a proposal pub fn find_vote_record_pda( proposal: &solana_pubkey::Pubkey, token_owner_record: &solana_pubkey::Pubkey, diff --git a/public/templates/pdasPage.njk b/public/templates/pdasPage.njk index aaf1ba3..9d27784 100644 --- a/public/templates/pdasPage.njk +++ b/public/templates/pdasPage.njk @@ -16,6 +16,7 @@ pub const {{ pda.name | snakeCase | upper }}_SEED{% if constantSeeds.length > 1 {% endif %} {% endfor %} +{{- macros.docblock(pda.docs) -}} pub fn create_{{ pda.name | snakeCase }}_pda( {% if hasVariableSeeds %} {% for seed in seeds %} @@ -59,6 +60,7 @@ pub fn create_{{ pda.name | snakeCase }}_pda( ) } +{{- macros.docblock(pda.docs) -}} pub fn find_{{ pda.name | snakeCase }}_pda( {% if hasVariableSeeds %} {% for seed in seeds %}