diff --git a/.changeset/proud-dragons-spend.md b/.changeset/proud-dragons-spend.md new file mode 100644 index 00000000..df53d3b2 --- /dev/null +++ b/.changeset/proud-dragons-spend.md @@ -0,0 +1,7 @@ +--- +"@macalinao/clients-voter-stake-registry": patch +"@macalinao/coda-visitors": patch +"@macalinao/coda": patch +--- + +Adds coda-visitors package and clients-voter-stake-registry diff --git a/bun.lock b/bun.lock index f9b6dc67..fb4b38d2 100644 --- a/bun.lock +++ b/bun.lock @@ -113,6 +113,21 @@ "@solana/kit": "*", }, }, + "clients/voter-stake-registry": { + "name": "@macalinao/clients-voter-stake-registry", + "version": "0.1.0", + "devDependencies": { + "@macalinao/coda": "workspace:*", + "@macalinao/eslint-config": "catalog:", + "@macalinao/tsconfig": "catalog:", + "@solana/kit": "catalog:", + "eslint": "catalog:", + "typescript": "catalog:", + }, + "peerDependencies": { + "@solana/kit": "*", + }, + }, "packages/coda": { "name": "@macalinao/coda", "version": "0.4.0", @@ -122,6 +137,7 @@ "dependencies": { "@codama/nodes-from-anchor": "catalog:", "@codama/renderers-rust": "^1.2.7", + "@macalinao/coda-visitors": "workspace:*", "@macalinao/codama-nodes-from-anchor-x": "workspace:*", "@macalinao/codama-rename-visitor": "workspace:*", "@macalinao/codama-renderers-js-esm": "workspace:*", @@ -138,6 +154,19 @@ "typescript": "catalog:", }, }, + "packages/coda-visitors": { + "name": "@macalinao/coda-visitors", + "version": "0.1.0", + "dependencies": { + "codama": "catalog:", + }, + "devDependencies": { + "@macalinao/eslint-config": "catalog:", + "@macalinao/tsconfig": "catalog:", + "eslint": "catalog:", + "typescript": "catalog:", + }, + }, "packages/codama-instruction-accounts-dedupe-visitor": { "name": "@macalinao/codama-instruction-accounts-dedupe-visitor", "version": "0.4.0", @@ -495,8 +524,12 @@ "@macalinao/clients-token-metadata": ["@macalinao/clients-token-metadata@workspace:clients/token-metadata"], + "@macalinao/clients-voter-stake-registry": ["@macalinao/clients-voter-stake-registry@workspace:clients/voter-stake-registry"], + "@macalinao/coda": ["@macalinao/coda@workspace:packages/coda"], + "@macalinao/coda-visitors": ["@macalinao/coda-visitors@workspace:packages/coda-visitors"], + "@macalinao/codama-instruction-accounts-dedupe-visitor": ["@macalinao/codama-instruction-accounts-dedupe-visitor@workspace:packages/codama-instruction-accounts-dedupe-visitor"], "@macalinao/codama-nodes-from-anchor-x": ["@macalinao/codama-nodes-from-anchor-x@workspace:packages/codama-nodes-from-anchor-x"], @@ -1929,12 +1962,20 @@ "@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="], + "@macalinao/clients-voter-stake-registry/typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + + "@macalinao/coda/typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + + "@macalinao/coda-visitors/typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + "@macalinao/codama-instruction-accounts-dedupe-visitor/typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], "@macalinao/codama-nodes-from-anchor-x/typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], "@macalinao/codama-rename-visitor/typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + "@macalinao/codama-renderers-js-esm/typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + "@macalinao/codama-renderers-markdown/typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], "@manypkg/find-root/@types/node": ["@types/node@12.20.55", "", {}, "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ=="], diff --git a/clients/voter-stake-registry/README.md b/clients/voter-stake-registry/README.md new file mode 100644 index 00000000..bc29661a --- /dev/null +++ b/clients/voter-stake-registry/README.md @@ -0,0 +1,65 @@ +# @macalinao/clients-voter-stake-registry + +[![npm version](https://img.shields.io/npm/v/@macalinao/clients-voter-stake-registry.svg)](https://www.npmjs.com/package/@macalinao/clients-voter-stake-registry) + +TypeScript client for the SPL Governance Voter Stake Registry program, generated using Coda with full ESM support. + +## Installation + +```bash +bun add @macalinao/clients-voter-stake-registry +``` + +## Development + +This client is generated from the Voter Stake Registry IDL using Coda CLI: + +```bash +# Generate the client from idls/voter_stake_registry.json +bun run codegen + +# Build the TypeScript +bun run build +``` + +### Configuration + +The `coda.config.mjs` file defines custom PDAs for the Voter Stake Registry program, including: + +- **Registrar**: The voting registrar account - one per governance realm and governing mint +- **Voter**: Individual voter accounts tied to a registrar and voter authority +- **Voter Weight Record**: The account shown to spl-governance to prove vote weight + +## Usage + +```typescript +import { + findRegistrarPda, + findVoterPda, + findVoterWeightRecordPda +} from "@macalinao/clients-voter-stake-registry"; + +// Get the registrar PDA +const registrarPda = await findRegistrarPda({ + realm: realmPublicKey, + realmGoverningTokenMint: mintPublicKey, +}); + +// Get a voter PDA +const voterPda = await findVoterPda({ + registrar: registrarPublicKey, + voterAuthority: authorityPublicKey, +}); + +// Get a voter weight record PDA +const voterWeightRecordPda = await findVoterWeightRecordPda({ + registrar: registrarPublicKey, + voterAuthority: authorityPublicKey, +}); +``` + +## License + +Copyright © 2025 Ian Macalinao + +Licensed under the Apache License, Version 2.0 \ No newline at end of file diff --git a/clients/voter-stake-registry/coda.config.mjs b/clients/voter-stake-registry/coda.config.mjs new file mode 100644 index 00000000..d02602e9 --- /dev/null +++ b/clients/voter-stake-registry/coda.config.mjs @@ -0,0 +1,197 @@ +import { + accountNode, + accountValueNode, + addNodesVisitor, + addPdasVisitor, + bytesTypeNode, + bytesValueNode, + constantPdaSeedNodeFromString, + defineConfig, + fieldDiscriminatorNode, + fixedSizeTypeNode, + numberTypeNode, + optionTypeNode, + payerValueNode, + pdaLinkNode, + pdaSeedValueNode, + pdaValueNode, + publicKeyTypeNode, + publicKeyValueNode, + setInstructionAccountDefaultValuesVisitor, + structFieldTypeNode, + structTypeNode, + updateAccountsVisitor, + variablePdaSeedNode, +} from "@macalinao/coda"; + +const addCustomPDAsVisitor = addPdasVisitor({ + voterStakeRegistry: [ + { + name: "registrar", + docs: [ + "The voting registrar. There can only be a single registrar", + "per governance realm and governing mint.", + ], + seeds: [ + variablePdaSeedNode("realm", publicKeyTypeNode()), + constantPdaSeedNodeFromString("utf8", "registrar"), + variablePdaSeedNode("realmGoverningTokenMint", publicKeyTypeNode()), + ], + }, + { + name: "voter", + docs: [ + "The voter account for a given voter authority.", + "Each voter authority has a unique voter account per registrar.", + ], + seeds: [ + variablePdaSeedNode("registrar", publicKeyTypeNode()), + constantPdaSeedNodeFromString("utf8", "voter"), + variablePdaSeedNode("voterAuthority", publicKeyTypeNode()), + ], + }, + { + name: "voterWeightRecord", + docs: [ + "The voter weight record is the account that will be shown to spl-governance", + "to prove how much vote weight the voter has. See update_voter_weight_record.", + ], + seeds: [ + variablePdaSeedNode("registrar", publicKeyTypeNode()), + constantPdaSeedNodeFromString("utf8", "voter-weight-record"), + variablePdaSeedNode("voterAuthority", publicKeyTypeNode()), + ], + }, + ], +}); + +export default defineConfig({ + outputDir: "./src/generated", + docs: { + npmPackageName: "@macalinao/clients-voter-stake-registry", + }, + visitors: [ + addNodesVisitor({ + voterStakeRegistry: { + accounts: [ + // See: https://github.com/Mythic-Project/oyster/blob/main/packages/governance-sdk/src/addins/serialisation.ts + accountNode({ + name: "voterWeightRecord", + discriminators: [fieldDiscriminatorNode("discriminator", 0)], + data: structTypeNode([ + structFieldTypeNode({ + name: "discriminator", + defaultValueStrategy: "omitted", + type: fixedSizeTypeNode(bytesTypeNode(), 8), + defaultValue: bytesValueNode("base16", "3265663939623462"), + }), + structFieldTypeNode({ + name: "realm", + type: publicKeyTypeNode(), + }), + structFieldTypeNode({ + name: "governingTokenMint", + type: publicKeyTypeNode(), + }), + structFieldTypeNode({ + name: "governingTokenOwner", + type: publicKeyTypeNode(), + }), + structFieldTypeNode({ + name: "voterWeight", + type: numberTypeNode("u64"), + }), + structFieldTypeNode({ + name: "voterWeightExpiry", + type: optionTypeNode(numberTypeNode("u64")), + }), + structFieldTypeNode({ + name: "weightAction", + type: optionTypeNode(numberTypeNode("u8")), + }), + structFieldTypeNode({ + name: "weightActionTarget", + type: optionTypeNode(publicKeyTypeNode()), + }), + // ['realm', 'pubkey'], + // ['governingTokenMint', 'pubkey'], + // ['governingTokenOwner', 'pubkey'], + // ['voterWeight', 'u64'], + // ['voterWeightExpiry', { kind: 'option', type: 'u64' }], + // ['weightAction', { kind: 'option', type: 'u8' }], + // ['weightActionTarget', { kind: 'option', type: 'pubkey' }], + ]), + pda: pdaLinkNode("voterWeightRecord"), + }), + ], + }, + }), + updateAccountsVisitor({ + registrar: { + pda: pdaLinkNode("registrar"), + }, + voter: { + pda: pdaLinkNode("voter"), + }, + }), + + setInstructionAccountDefaultValuesVisitor([ + { + account: "tokenProgram", + defaultValue: publicKeyValueNode( + "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", + ), + }, + { + account: "associatedTokenProgram", + defaultValue: publicKeyValueNode( + "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", + ), + }, + { + account: "systemProgram", + defaultValue: publicKeyValueNode("11111111111111111111111111111111"), + }, + { + account: "rent", + defaultValue: publicKeyValueNode( + "SysvarRent111111111111111111111111111111111", + ), + }, + { + account: "instructions", + defaultValue: publicKeyValueNode( + "Sysvar1nstructions1111111111111111111111111", + ), + }, + { + account: "payer", + defaultValue: payerValueNode(), + }, + + { + account: "voter", + instruction: "createVoter", + defaultValue: pdaValueNode(pdaLinkNode("voter"), [ + pdaSeedValueNode("registrar", accountValueNode("registrar")), + pdaSeedValueNode( + "voterAuthority", + accountValueNode("voterAuthority"), + ), + ]), + }, + { + account: "voterWeightRecord", + instruction: "createVoter", + defaultValue: pdaValueNode(pdaLinkNode("voterWeightRecord"), [ + pdaSeedValueNode("registrar", accountValueNode("registrar")), + pdaSeedValueNode( + "voterAuthority", + accountValueNode("voterAuthority"), + ), + ]), + }, + ]), + addCustomPDAsVisitor, + ], +}); diff --git a/clients/voter-stake-registry/eslint.config.js b/clients/voter-stake-registry/eslint.config.js new file mode 100644 index 00000000..f157753e --- /dev/null +++ b/clients/voter-stake-registry/eslint.config.js @@ -0,0 +1,31 @@ +import { configs } from "@macalinao/eslint-config"; + +export default [ + ...configs.fast, + { + languageOptions: { + parserOptions: { + tsconfigRootDir: import.meta.dirname, + }, + }, + }, + { + files: ["src/generated/**/*.ts"], + rules: { + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/prefer-nullish-coalescing": "off", + }, + }, + { + files: [ + "src/generated/instructions/*.ts", + "src/generated/types/*.ts", + "src/generated/errors/*.ts", + ], + rules: { + "@typescript-eslint/no-unnecessary-condition": "off", + "no-constant-condition": "off", + "@typescript-eslint/no-empty-object-type": "off", + }, + }, +]; diff --git a/clients/voter-stake-registry/idls/voter_stake_registry.json b/clients/voter-stake-registry/idls/voter_stake_registry.json new file mode 100644 index 00000000..8fa3b60e --- /dev/null +++ b/clients/voter-stake-registry/idls/voter_stake_registry.json @@ -0,0 +1,991 @@ +{ + "address": "vsr2nfGVNHmSY8uxoBGqq8AQbwz3JwaEaHqGbsTPXqQ", + "metadata": { + "name": "voter_stake_registry", + "version": "0.1.3", + "spec": "0.1.0" + }, + "instructions": [ + { + "name": "create_registrar", + "discriminator": [132, 235, 36, 49, 139, 66, 202, 69], + "accounts": [ + { + "name": "registrar", + "writable": true + }, + { + "name": "realm" + }, + { + "name": "governance_program_id" + }, + { + "name": "realm_governing_token_mint" + }, + { + "name": "realm_authority", + "signer": true + }, + { + "name": "payer", + "writable": true, + "signer": true + }, + { + "name": "system_program" + }, + { + "name": "rent" + } + ], + "args": [ + { + "name": "registrar_bump", + "type": "u8" + } + ] + }, + { + "name": "configure_voting_mint", + "discriminator": [113, 153, 141, 236, 184, 9, 135, 15], + "accounts": [ + { + "name": "registrar", + "writable": true + }, + { + "name": "realm_authority", + "signer": true + }, + { + "name": "mint" + } + ], + "args": [ + { + "name": "idx", + "type": "u16" + }, + { + "name": "digit_shift", + "type": "i8" + }, + { + "name": "deposit_scaled_factor", + "type": "u64" + }, + { + "name": "lockup_scaled_factor", + "type": "u64" + }, + { + "name": "lockup_saturation_secs", + "type": "u64" + }, + { + "name": "grant_authority", + "type": { + "option": "pubkey" + } + } + ] + }, + { + "name": "create_voter", + "discriminator": [6, 24, 245, 52, 243, 255, 148, 25], + "accounts": [ + { + "name": "registrar" + }, + { + "name": "voter", + "writable": true + }, + { + "name": "voter_authority", + "signer": true + }, + { + "name": "voter_weight_record", + "writable": true + }, + { + "name": "payer", + "writable": true, + "signer": true + }, + { + "name": "system_program" + }, + { + "name": "rent" + }, + { + "name": "instructions" + } + ], + "args": [ + { + "name": "voter_bump", + "type": "u8" + }, + { + "name": "voter_weight_record_bump", + "type": "u8" + } + ] + }, + { + "name": "create_deposit_entry", + "discriminator": [185, 131, 167, 186, 159, 125, 19, 67], + "accounts": [ + { + "name": "registrar" + }, + { + "name": "voter", + "writable": true + }, + { + "name": "vault", + "writable": true + }, + { + "name": "voter_authority", + "signer": true + }, + { + "name": "payer", + "writable": true, + "signer": true + }, + { + "name": "deposit_mint" + }, + { + "name": "system_program" + }, + { + "name": "token_program" + }, + { + "name": "associated_token_program" + }, + { + "name": "rent" + } + ], + "args": [ + { + "name": "deposit_entry_index", + "type": "u8" + }, + { + "name": "kind", + "type": { + "defined": { + "name": "LockupKind" + } + } + }, + { + "name": "start_ts", + "type": { + "option": "u64" + } + }, + { + "name": "periods", + "type": "u32" + }, + { + "name": "allow_clawback", + "type": "bool" + } + ] + }, + { + "name": "deposit", + "discriminator": [242, 35, 198, 137, 82, 225, 242, 182], + "accounts": [ + { + "name": "registrar" + }, + { + "name": "voter", + "writable": true + }, + { + "name": "vault", + "writable": true + }, + { + "name": "deposit_token", + "writable": true + }, + { + "name": "deposit_authority", + "signer": true + }, + { + "name": "token_program" + } + ], + "args": [ + { + "name": "deposit_entry_index", + "type": "u8" + }, + { + "name": "amount", + "type": "u64" + } + ] + }, + { + "name": "withdraw", + "discriminator": [183, 18, 70, 156, 148, 109, 161, 34], + "accounts": [ + { + "name": "registrar" + }, + { + "name": "voter", + "writable": true + }, + { + "name": "voter_authority", + "signer": true + }, + { + "name": "token_owner_record" + }, + { + "name": "voter_weight_record", + "writable": true + }, + { + "name": "vault", + "writable": true + }, + { + "name": "destination", + "writable": true + }, + { + "name": "token_program" + } + ], + "args": [ + { + "name": "deposit_entry_index", + "type": "u8" + }, + { + "name": "amount", + "type": "u64" + } + ] + }, + { + "name": "grant", + "discriminator": [145, 189, 68, 153, 161, 231, 76, 107], + "accounts": [ + { + "name": "registrar" + }, + { + "name": "voter", + "writable": true + }, + { + "name": "voter_authority" + }, + { + "name": "voter_weight_record", + "writable": true + }, + { + "name": "vault", + "writable": true + }, + { + "name": "deposit_token", + "writable": true + }, + { + "name": "authority", + "signer": true + }, + { + "name": "payer", + "writable": true, + "signer": true + }, + { + "name": "deposit_mint" + }, + { + "name": "system_program" + }, + { + "name": "token_program" + }, + { + "name": "associated_token_program" + }, + { + "name": "rent" + } + ], + "args": [ + { + "name": "voter_bump", + "type": "u8" + }, + { + "name": "voter_weight_record_bump", + "type": "u8" + }, + { + "name": "kind", + "type": { + "defined": { + "name": "LockupKind" + } + } + }, + { + "name": "start_ts", + "type": { + "option": "u64" + } + }, + { + "name": "periods", + "type": "u32" + }, + { + "name": "allow_clawback", + "type": "bool" + }, + { + "name": "amount", + "type": "u64" + } + ] + }, + { + "name": "clawback", + "discriminator": [111, 92, 142, 79, 33, 234, 82, 27], + "accounts": [ + { + "name": "registrar" + }, + { + "name": "realm_authority", + "signer": true + }, + { + "name": "voter", + "writable": true + }, + { + "name": "token_owner_record" + }, + { + "name": "vault", + "writable": true + }, + { + "name": "destination", + "writable": true + }, + { + "name": "token_program" + } + ], + "args": [ + { + "name": "deposit_entry_index", + "type": "u8" + } + ] + }, + { + "name": "close_deposit_entry", + "discriminator": [236, 190, 87, 34, 251, 131, 138, 237], + "accounts": [ + { + "name": "voter", + "writable": true + }, + { + "name": "voter_authority", + "signer": true + } + ], + "args": [ + { + "name": "deposit_entry_index", + "type": "u8" + } + ] + }, + { + "name": "reset_lockup", + "discriminator": [243, 20, 24, 247, 238, 148, 94, 62], + "accounts": [ + { + "name": "registrar" + }, + { + "name": "voter", + "writable": true + }, + { + "name": "voter_authority", + "signer": true + } + ], + "args": [ + { + "name": "deposit_entry_index", + "type": "u8" + }, + { + "name": "kind", + "type": { + "defined": { + "name": "LockupKind" + } + } + }, + { + "name": "periods", + "type": "u32" + } + ] + }, + { + "name": "internal_transfer", + "discriminator": [56, 217, 60, 137, 252, 221, 185, 114], + "accounts": [ + { + "name": "registrar" + }, + { + "name": "voter", + "writable": true + }, + { + "name": "voter_authority", + "signer": true + } + ], + "args": [ + { + "name": "source_deposit_entry_index", + "type": "u8" + }, + { + "name": "target_deposit_entry_index", + "type": "u8" + }, + { + "name": "amount", + "type": "u64" + } + ] + }, + { + "name": "update_voter_weight_record", + "discriminator": [45, 185, 3, 36, 109, 190, 115, 169], + "accounts": [ + { + "name": "registrar" + }, + { + "name": "voter" + }, + { + "name": "voter_weight_record", + "writable": true + }, + { + "name": "system_program" + } + ], + "args": [] + }, + { + "name": "update_max_vote_weight", + "discriminator": [78, 221, 185, 255, 240, 128, 244, 162], + "accounts": [ + { + "name": "registrar" + }, + { + "name": "max_vote_weight_record" + } + ], + "args": [] + }, + { + "name": "close_voter", + "discriminator": [117, 35, 234, 247, 206, 131, 182, 149], + "accounts": [ + { + "name": "voter", + "writable": true + }, + { + "name": "voter_authority", + "signer": true + }, + { + "name": "sol_destination" + } + ], + "args": [] + }, + { + "name": "set_time_offset", + "discriminator": [89, 238, 89, 160, 239, 113, 25, 123], + "accounts": [ + { + "name": "registrar", + "writable": true + }, + { + "name": "realm_authority", + "signer": true + } + ], + "args": [ + { + "name": "time_offset", + "type": "i64" + } + ] + } + ], + "accounts": [ + { + "name": "Registrar", + "discriminator": [193, 202, 205, 51, 78, 168, 150, 128] + }, + { + "name": "Voter", + "discriminator": [241, 93, 35, 191, 254, 147, 17, 202] + } + ], + "errors": [ + { + "code": 6000, + "name": "InvalidRate", + "msg": "Exchange rate must be greater than zero" + }, + { + "code": 6001, + "name": "RatesFull", + "msg": "" + }, + { + "code": 6002, + "name": "VotingMintNotFound", + "msg": "" + }, + { + "code": 6003, + "name": "DepositEntryNotFound", + "msg": "" + }, + { + "code": 6004, + "name": "DepositEntryFull", + "msg": "" + }, + { + "code": 6005, + "name": "VotingTokenNonZero", + "msg": "" + }, + { + "code": 6006, + "name": "OutOfBoundsDepositEntryIndex", + "msg": "" + }, + { + "code": 6007, + "name": "UnusedDepositEntryIndex", + "msg": "" + }, + { + "code": 6008, + "name": "InsufficientVestedTokens", + "msg": "" + }, + { + "code": 6009, + "name": "UnableToConvert", + "msg": "" + }, + { + "code": 6010, + "name": "InvalidLockupPeriod", + "msg": "" + }, + { + "code": 6011, + "name": "InvalidEndTs", + "msg": "" + }, + { + "code": 6012, + "name": "InvalidDays", + "msg": "" + }, + { + "code": 6013, + "name": "VotingMintConfigIndexAlreadyInUse", + "msg": "" + }, + { + "code": 6014, + "name": "OutOfBoundsVotingMintConfigIndex", + "msg": "" + }, + { + "code": 6015, + "name": "InvalidDecimals", + "msg": "Exchange rate decimals cannot be larger than registrar decimals" + }, + { + "code": 6016, + "name": "InvalidToDepositAndWithdrawInOneSlot", + "msg": "" + }, + { + "code": 6017, + "name": "ShouldBeTheFirstIxInATx", + "msg": "" + }, + { + "code": 6018, + "name": "ForbiddenCpi", + "msg": "" + }, + { + "code": 6019, + "name": "InvalidMint", + "msg": "" + }, + { + "code": 6020, + "name": "DebugInstruction", + "msg": "" + }, + { + "code": 6021, + "name": "ClawbackNotAllowedOnDeposit", + "msg": "" + }, + { + "code": 6022, + "name": "DepositStillLocked", + "msg": "" + }, + { + "code": 6023, + "name": "InvalidAuthority", + "msg": "" + }, + { + "code": 6024, + "name": "InvalidTokenOwnerRecord", + "msg": "" + }, + { + "code": 6025, + "name": "InvalidRealmAuthority", + "msg": "" + }, + { + "code": 6026, + "name": "VoterWeightOverflow", + "msg": "" + }, + { + "code": 6027, + "name": "LockupSaturationMustBePositive", + "msg": "" + }, + { + "code": 6028, + "name": "VotingMintConfiguredWithDifferentIndex", + "msg": "" + }, + { + "code": 6029, + "name": "InternalProgramError", + "msg": "" + }, + { + "code": 6030, + "name": "InsufficientLockedTokens", + "msg": "" + }, + { + "code": 6031, + "name": "MustKeepTokensLocked", + "msg": "" + }, + { + "code": 6032, + "name": "InvalidLockupKind", + "msg": "" + }, + { + "code": 6033, + "name": "InvalidChangeToClawbackDepositEntry", + "msg": "" + } + ], + "types": [ + { + "name": "DepositEntry", + "type": { + "kind": "struct", + "fields": [ + { + "name": "lockup", + "type": { + "defined": { + "name": "Lockup" + } + } + }, + { + "name": "amount_deposited_native", + "type": "u64" + }, + { + "name": "amount_initially_locked_native", + "type": "u64" + }, + { + "name": "is_used", + "type": "bool" + }, + { + "name": "allow_clawback", + "type": "bool" + }, + { + "name": "voting_mint_config_idx", + "type": "u8" + }, + { + "name": "padding", + "type": { + "array": ["u8", 13] + } + } + ] + } + }, + { + "name": "Lockup", + "type": { + "kind": "struct", + "fields": [ + { + "name": "start_ts", + "type": "i64" + }, + { + "name": "end_ts", + "type": "i64" + }, + { + "name": "kind", + "type": { + "defined": { + "name": "LockupKind" + } + } + }, + { + "name": "padding", + "type": { + "array": ["u8", 15] + } + } + ] + } + }, + { + "name": "VotingMintConfig", + "type": { + "kind": "struct", + "fields": [ + { + "name": "mint", + "type": "pubkey" + }, + { + "name": "grant_authority", + "type": "pubkey" + }, + { + "name": "deposit_scaled_factor", + "type": "u64" + }, + { + "name": "lockup_scaled_factor", + "type": "u64" + }, + { + "name": "lockup_saturation_secs", + "type": "u64" + }, + { + "name": "digit_shift", + "type": "i8" + }, + { + "name": "padding", + "type": { + "array": ["u8", 31] + } + } + ] + } + }, + { + "name": "LockupKind", + "type": { + "kind": "enum", + "variants": [ + { + "name": "None" + }, + { + "name": "Daily" + }, + { + "name": "Monthly" + }, + { + "name": "Cliff" + }, + { + "name": "Constant" + } + ] + } + }, + { + "name": "Registrar", + "type": { + "kind": "struct", + "fields": [ + { + "name": "governance_program_id", + "type": "pubkey" + }, + { + "name": "realm", + "type": "pubkey" + }, + { + "name": "realm_governing_token_mint", + "type": "pubkey" + }, + { + "name": "realm_authority", + "type": "pubkey" + }, + { + "name": "padding1", + "type": { + "array": ["u8", 32] + } + }, + { + "name": "voting_mints", + "type": { + "array": [ + { + "defined": { + "name": "VotingMintConfig" + } + }, + 4 + ] + } + }, + { + "name": "time_offset", + "type": "i64" + }, + { + "name": "bump", + "type": "u8" + }, + { + "name": "padding2", + "type": { + "array": ["u8", 31] + } + } + ] + } + }, + { + "name": "Voter", + "type": { + "kind": "struct", + "fields": [ + { + "name": "voter_authority", + "type": "pubkey" + }, + { + "name": "registrar", + "type": "pubkey" + }, + { + "name": "deposits", + "type": { + "array": [ + { + "defined": { + "name": "DepositEntry" + } + }, + 32 + ] + } + }, + { + "name": "voter_bump", + "type": "u8" + }, + { + "name": "voter_weight_record_bump", + "type": "u8" + }, + { + "name": "padding", + "type": { + "array": ["u8", 30] + } + } + ] + } + } + ] +} diff --git a/clients/voter-stake-registry/package.json b/clients/voter-stake-registry/package.json new file mode 100644 index 00000000..c1f68e33 --- /dev/null +++ b/clients/voter-stake-registry/package.json @@ -0,0 +1,62 @@ +{ + "name": "@macalinao/clients-voter-stake-registry", + "version": "0.1.0", + "description": "TypeScript client for the SPL Governance Voter Stake Registry program", + "type": "module", + "sideEffects": false, + "author": "Ian Macalinao ", + "homepage": "https://coda.ianm.com", + "license": "Apache-2.0", + "keywords": [ + "coda", + "solana", + "spl", + "governance", + "voter-stake-registry", + "dao", + "voting", + "staking", + "realm", + "client", + "esm", + "typescript", + "ian-macalinao" + ], + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/index.js", + "types": "./dist/index.d.ts" + } + }, + "files": [ + "dist/", + "src/" + ], + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/macalinao/coda.git", + "directory": "clients/voter-stake-registry" + }, + "scripts": { + "build": "tsc", + "clean": "rm -fr dist/", + "lint": "eslint . --cache", + "codegen": "coda generate" + }, + "peerDependencies": { + "@solana/kit": "*" + }, + "devDependencies": { + "@macalinao/coda": "workspace:*", + "@macalinao/eslint-config": "catalog:", + "@macalinao/tsconfig": "catalog:", + "@solana/kit": "catalog:", + "eslint": "catalog:", + "typescript": "catalog:" + } +} diff --git a/clients/voter-stake-registry/src/generated/accounts/index.ts b/clients/voter-stake-registry/src/generated/accounts/index.ts new file mode 100644 index 00000000..7040b4e2 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/accounts/index.ts @@ -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. + * + * @see https://github.com/codama-idl/codama + */ + +export * from "./registrar.js"; +export * from "./voter.js"; +export * from "./voterWeightRecord.js"; diff --git a/clients/voter-stake-registry/src/generated/accounts/registrar.ts b/clients/voter-stake-registry/src/generated/accounts/registrar.ts new file mode 100644 index 00000000..2cea3284 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/accounts/registrar.ts @@ -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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + Account, + Address, + EncodedAccount, + FetchAccountConfig, + FetchAccountsConfig, + FixedSizeCodec, + FixedSizeDecoder, + FixedSizeEncoder, + MaybeAccount, + MaybeEncodedAccount, + ReadonlyUint8Array, +} from "@solana/kit"; +import type { RegistrarSeeds } from "../pdas/index.js"; +import type { VotingMintConfig, VotingMintConfigArgs } from "../types/index.js"; +import { + assertAccountExists, + assertAccountsExist, + combineCodec, + decodeAccount, + fetchEncodedAccount, + fetchEncodedAccounts, + fixDecoderSize, + fixEncoderSize, + getAddressDecoder, + getAddressEncoder, + getArrayDecoder, + getArrayEncoder, + getBytesDecoder, + getBytesEncoder, + getI64Decoder, + getI64Encoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + transformEncoder, +} from "@solana/kit"; +import { findRegistrarPda } from "../pdas/index.js"; +import { + getVotingMintConfigDecoder, + getVotingMintConfigEncoder, +} from "../types/index.js"; + +export const REGISTRAR_DISCRIMINATOR: ReadonlyUint8Array = new Uint8Array([ + 193, 202, 205, 51, 78, 168, 150, 128, +]); + +export function getRegistrarDiscriminatorBytes(): ReadonlyUint8Array { + return fixEncoderSize(getBytesEncoder(), 8).encode(REGISTRAR_DISCRIMINATOR); +} + +export interface Registrar { + discriminator: ReadonlyUint8Array; + governanceProgramId: Address; + realm: Address; + realmGoverningTokenMint: Address; + realmAuthority: Address; + padding1: number[]; + votingMints: VotingMintConfig[]; + timeOffset: bigint; + bump: number; + padding2: number[]; +} + +export interface RegistrarArgs { + governanceProgramId: Address; + realm: Address; + realmGoverningTokenMint: Address; + realmAuthority: Address; + padding1: number[]; + votingMints: VotingMintConfigArgs[]; + timeOffset: number | bigint; + bump: number; + padding2: number[]; +} + +export function getRegistrarEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([ + ["discriminator", fixEncoderSize(getBytesEncoder(), 8)], + ["governanceProgramId", getAddressEncoder()], + ["realm", getAddressEncoder()], + ["realmGoverningTokenMint", getAddressEncoder()], + ["realmAuthority", getAddressEncoder()], + ["padding1", getArrayEncoder(getU8Encoder(), { size: 32 })], + [ + "votingMints", + getArrayEncoder(getVotingMintConfigEncoder(), { size: 4 }), + ], + ["timeOffset", getI64Encoder()], + ["bump", getU8Encoder()], + ["padding2", getArrayEncoder(getU8Encoder(), { size: 31 })], + ]), + (value) => ({ ...value, discriminator: REGISTRAR_DISCRIMINATOR }), + ); +} + +export function getRegistrarDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ["discriminator", fixDecoderSize(getBytesDecoder(), 8)], + ["governanceProgramId", getAddressDecoder()], + ["realm", getAddressDecoder()], + ["realmGoverningTokenMint", getAddressDecoder()], + ["realmAuthority", getAddressDecoder()], + ["padding1", getArrayDecoder(getU8Decoder(), { size: 32 })], + ["votingMints", getArrayDecoder(getVotingMintConfigDecoder(), { size: 4 })], + ["timeOffset", getI64Decoder()], + ["bump", getU8Decoder()], + ["padding2", getArrayDecoder(getU8Decoder(), { size: 31 })], + ]); +} + +export function getRegistrarCodec(): FixedSizeCodec { + return combineCodec(getRegistrarEncoder(), getRegistrarDecoder()); +} + +export function decodeRegistrar( + encodedAccount: EncodedAccount, +): Account; +export function decodeRegistrar( + encodedAccount: MaybeEncodedAccount, +): MaybeAccount; +export function decodeRegistrar( + encodedAccount: EncodedAccount | MaybeEncodedAccount, +): Account | MaybeAccount { + return decodeAccount( + encodedAccount as MaybeEncodedAccount, + getRegistrarDecoder(), + ); +} + +export async function fetchRegistrar( + rpc: Parameters[0], + address: Address, + config?: FetchAccountConfig, +): Promise> { + const maybeAccount = await fetchMaybeRegistrar(rpc, address, config); + assertAccountExists(maybeAccount); + return maybeAccount; +} + +export async function fetchMaybeRegistrar( + rpc: Parameters[0], + address: Address, + config?: FetchAccountConfig, +): Promise> { + const maybeAccount = await fetchEncodedAccount(rpc, address, config); + return decodeRegistrar(maybeAccount); +} + +export async function fetchAllRegistrar( + rpc: Parameters[0], + addresses: Address[], + config?: FetchAccountsConfig, +): Promise[]> { + const maybeAccounts = await fetchAllMaybeRegistrar(rpc, addresses, config); + assertAccountsExist(maybeAccounts); + return maybeAccounts; +} + +export async function fetchAllMaybeRegistrar( + rpc: Parameters[0], + addresses: Address[], + config?: FetchAccountsConfig, +): Promise[]> { + const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config); + return maybeAccounts.map((maybeAccount) => decodeRegistrar(maybeAccount)); +} + +export async function fetchRegistrarFromSeeds( + rpc: Parameters[0], + seeds: RegistrarSeeds, + config: FetchAccountConfig & { programAddress?: Address } = {}, +): Promise> { + const maybeAccount = await fetchMaybeRegistrarFromSeeds(rpc, seeds, config); + assertAccountExists(maybeAccount); + return maybeAccount; +} + +export async function fetchMaybeRegistrarFromSeeds( + rpc: Parameters[0], + seeds: RegistrarSeeds, + config: FetchAccountConfig & { programAddress?: Address } = {}, +): Promise> { + const { programAddress, ...fetchConfig } = config; + const [address] = await findRegistrarPda(seeds, { programAddress }); + return await fetchMaybeRegistrar(rpc, address, fetchConfig); +} diff --git a/clients/voter-stake-registry/src/generated/accounts/voter.ts b/clients/voter-stake-registry/src/generated/accounts/voter.ts new file mode 100644 index 00000000..c1d639b4 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/accounts/voter.ts @@ -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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + Account, + Address, + EncodedAccount, + FetchAccountConfig, + FetchAccountsConfig, + FixedSizeCodec, + FixedSizeDecoder, + FixedSizeEncoder, + MaybeAccount, + MaybeEncodedAccount, + ReadonlyUint8Array, +} from "@solana/kit"; +import type { VoterSeeds } from "../pdas/index.js"; +import type { DepositEntry, DepositEntryArgs } from "../types/index.js"; +import { + assertAccountExists, + assertAccountsExist, + combineCodec, + decodeAccount, + fetchEncodedAccount, + fetchEncodedAccounts, + fixDecoderSize, + fixEncoderSize, + getAddressDecoder, + getAddressEncoder, + getArrayDecoder, + getArrayEncoder, + getBytesDecoder, + getBytesEncoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + transformEncoder, +} from "@solana/kit"; +import { findVoterPda } from "../pdas/index.js"; +import { + getDepositEntryDecoder, + getDepositEntryEncoder, +} from "../types/index.js"; + +export const VOTER_DISCRIMINATOR: ReadonlyUint8Array = new Uint8Array([ + 241, 93, 35, 191, 254, 147, 17, 202, +]); + +export function getVoterDiscriminatorBytes(): ReadonlyUint8Array { + return fixEncoderSize(getBytesEncoder(), 8).encode(VOTER_DISCRIMINATOR); +} + +export interface Voter { + discriminator: ReadonlyUint8Array; + voterAuthority: Address; + registrar: Address; + deposits: DepositEntry[]; + voterBump: number; + voterWeightRecordBump: number; + padding: number[]; +} + +export interface VoterArgs { + voterAuthority: Address; + registrar: Address; + deposits: DepositEntryArgs[]; + voterBump: number; + voterWeightRecordBump: number; + padding: number[]; +} + +export function getVoterEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([ + ["discriminator", fixEncoderSize(getBytesEncoder(), 8)], + ["voterAuthority", getAddressEncoder()], + ["registrar", getAddressEncoder()], + ["deposits", getArrayEncoder(getDepositEntryEncoder(), { size: 32 })], + ["voterBump", getU8Encoder()], + ["voterWeightRecordBump", getU8Encoder()], + ["padding", getArrayEncoder(getU8Encoder(), { size: 30 })], + ]), + (value) => ({ ...value, discriminator: VOTER_DISCRIMINATOR }), + ); +} + +export function getVoterDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ["discriminator", fixDecoderSize(getBytesDecoder(), 8)], + ["voterAuthority", getAddressDecoder()], + ["registrar", getAddressDecoder()], + ["deposits", getArrayDecoder(getDepositEntryDecoder(), { size: 32 })], + ["voterBump", getU8Decoder()], + ["voterWeightRecordBump", getU8Decoder()], + ["padding", getArrayDecoder(getU8Decoder(), { size: 30 })], + ]); +} + +export function getVoterCodec(): FixedSizeCodec { + return combineCodec(getVoterEncoder(), getVoterDecoder()); +} + +export function decodeVoter( + encodedAccount: EncodedAccount, +): Account; +export function decodeVoter( + encodedAccount: MaybeEncodedAccount, +): MaybeAccount; +export function decodeVoter( + encodedAccount: EncodedAccount | MaybeEncodedAccount, +): Account | MaybeAccount { + return decodeAccount( + encodedAccount as MaybeEncodedAccount, + getVoterDecoder(), + ); +} + +export async function fetchVoter( + rpc: Parameters[0], + address: Address, + config?: FetchAccountConfig, +): Promise> { + const maybeAccount = await fetchMaybeVoter(rpc, address, config); + assertAccountExists(maybeAccount); + return maybeAccount; +} + +export async function fetchMaybeVoter( + rpc: Parameters[0], + address: Address, + config?: FetchAccountConfig, +): Promise> { + const maybeAccount = await fetchEncodedAccount(rpc, address, config); + return decodeVoter(maybeAccount); +} + +export async function fetchAllVoter( + rpc: Parameters[0], + addresses: Address[], + config?: FetchAccountsConfig, +): Promise[]> { + const maybeAccounts = await fetchAllMaybeVoter(rpc, addresses, config); + assertAccountsExist(maybeAccounts); + return maybeAccounts; +} + +export async function fetchAllMaybeVoter( + rpc: Parameters[0], + addresses: Address[], + config?: FetchAccountsConfig, +): Promise[]> { + const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config); + return maybeAccounts.map((maybeAccount) => decodeVoter(maybeAccount)); +} + +export async function fetchVoterFromSeeds( + rpc: Parameters[0], + seeds: VoterSeeds, + config: FetchAccountConfig & { programAddress?: Address } = {}, +): Promise> { + const maybeAccount = await fetchMaybeVoterFromSeeds(rpc, seeds, config); + assertAccountExists(maybeAccount); + return maybeAccount; +} + +export async function fetchMaybeVoterFromSeeds( + rpc: Parameters[0], + seeds: VoterSeeds, + config: FetchAccountConfig & { programAddress?: Address } = {}, +): Promise> { + const { programAddress, ...fetchConfig } = config; + const [address] = await findVoterPda(seeds, { programAddress }); + return await fetchMaybeVoter(rpc, address, fetchConfig); +} diff --git a/clients/voter-stake-registry/src/generated/accounts/voterWeightRecord.ts b/clients/voter-stake-registry/src/generated/accounts/voterWeightRecord.ts new file mode 100644 index 00000000..92507932 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/accounts/voterWeightRecord.ts @@ -0,0 +1,204 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + Account, + Address, + Codec, + Decoder, + EncodedAccount, + Encoder, + FetchAccountConfig, + FetchAccountsConfig, + MaybeAccount, + MaybeEncodedAccount, + Option, + OptionOrNullable, + ReadonlyUint8Array, +} from "@solana/kit"; +import type { VoterWeightRecordSeeds } from "../pdas/index.js"; +import { + assertAccountExists, + assertAccountsExist, + combineCodec, + decodeAccount, + fetchEncodedAccount, + fetchEncodedAccounts, + fixDecoderSize, + fixEncoderSize, + getAddressDecoder, + getAddressEncoder, + getBytesDecoder, + getBytesEncoder, + getOptionDecoder, + getOptionEncoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + getU64Decoder, + getU64Encoder, + transformEncoder, +} from "@solana/kit"; +import { findVoterWeightRecordPda } from "../pdas/index.js"; + +export const VOTER_WEIGHT_RECORD_DISCRIMINATOR: ReadonlyUint8Array = + new Uint8Array([50, 101, 102, 57, 57, 98, 52, 98]); + +export function getVoterWeightRecordDiscriminatorBytes(): ReadonlyUint8Array { + return fixEncoderSize(getBytesEncoder(), 8).encode( + VOTER_WEIGHT_RECORD_DISCRIMINATOR, + ); +} + +export interface VoterWeightRecord { + discriminator: ReadonlyUint8Array; + realm: Address; + governingTokenMint: Address; + governingTokenOwner: Address; + voterWeight: bigint; + voterWeightExpiry: Option; + weightAction: Option; + weightActionTarget: Option
; +} + +export interface VoterWeightRecordArgs { + realm: Address; + governingTokenMint: Address; + governingTokenOwner: Address; + voterWeight: number | bigint; + voterWeightExpiry: OptionOrNullable; + weightAction: OptionOrNullable; + weightActionTarget: OptionOrNullable
; +} + +export function getVoterWeightRecordEncoder(): Encoder { + return transformEncoder( + getStructEncoder([ + ["discriminator", fixEncoderSize(getBytesEncoder(), 8)], + ["realm", getAddressEncoder()], + ["governingTokenMint", getAddressEncoder()], + ["governingTokenOwner", getAddressEncoder()], + ["voterWeight", getU64Encoder()], + ["voterWeightExpiry", getOptionEncoder(getU64Encoder())], + ["weightAction", getOptionEncoder(getU8Encoder())], + ["weightActionTarget", getOptionEncoder(getAddressEncoder())], + ]), + (value) => ({ ...value, discriminator: VOTER_WEIGHT_RECORD_DISCRIMINATOR }), + ); +} + +export function getVoterWeightRecordDecoder(): Decoder { + return getStructDecoder([ + ["discriminator", fixDecoderSize(getBytesDecoder(), 8)], + ["realm", getAddressDecoder()], + ["governingTokenMint", getAddressDecoder()], + ["governingTokenOwner", getAddressDecoder()], + ["voterWeight", getU64Decoder()], + ["voterWeightExpiry", getOptionDecoder(getU64Decoder())], + ["weightAction", getOptionDecoder(getU8Decoder())], + ["weightActionTarget", getOptionDecoder(getAddressDecoder())], + ]); +} + +export function getVoterWeightRecordCodec(): Codec< + VoterWeightRecordArgs, + VoterWeightRecord +> { + return combineCodec( + getVoterWeightRecordEncoder(), + getVoterWeightRecordDecoder(), + ); +} + +export function decodeVoterWeightRecord( + encodedAccount: EncodedAccount, +): Account; +export function decodeVoterWeightRecord( + encodedAccount: MaybeEncodedAccount, +): MaybeAccount; +export function decodeVoterWeightRecord( + encodedAccount: EncodedAccount | MaybeEncodedAccount, +): + | Account + | MaybeAccount { + return decodeAccount( + encodedAccount as MaybeEncodedAccount, + getVoterWeightRecordDecoder(), + ); +} + +export async function fetchVoterWeightRecord( + rpc: Parameters[0], + address: Address, + config?: FetchAccountConfig, +): Promise> { + const maybeAccount = await fetchMaybeVoterWeightRecord(rpc, address, config); + assertAccountExists(maybeAccount); + return maybeAccount; +} + +export async function fetchMaybeVoterWeightRecord< + TAddress extends string = string, +>( + rpc: Parameters[0], + address: Address, + config?: FetchAccountConfig, +): Promise> { + const maybeAccount = await fetchEncodedAccount(rpc, address, config); + return decodeVoterWeightRecord(maybeAccount); +} + +export async function fetchAllVoterWeightRecord( + rpc: Parameters[0], + addresses: Address[], + config?: FetchAccountsConfig, +): Promise[]> { + const maybeAccounts = await fetchAllMaybeVoterWeightRecord( + rpc, + addresses, + config, + ); + assertAccountsExist(maybeAccounts); + return maybeAccounts; +} + +export async function fetchAllMaybeVoterWeightRecord( + rpc: Parameters[0], + addresses: Address[], + config?: FetchAccountsConfig, +): Promise[]> { + const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config); + return maybeAccounts.map((maybeAccount) => + decodeVoterWeightRecord(maybeAccount), + ); +} + +export async function fetchVoterWeightRecordFromSeeds( + rpc: Parameters[0], + seeds: VoterWeightRecordSeeds, + config: FetchAccountConfig & { programAddress?: Address } = {}, +): Promise> { + const maybeAccount = await fetchMaybeVoterWeightRecordFromSeeds( + rpc, + seeds, + config, + ); + assertAccountExists(maybeAccount); + return maybeAccount; +} + +export async function fetchMaybeVoterWeightRecordFromSeeds( + rpc: Parameters[0], + seeds: VoterWeightRecordSeeds, + config: FetchAccountConfig & { programAddress?: Address } = {}, +): Promise> { + const { programAddress, ...fetchConfig } = config; + const [address] = await findVoterWeightRecordPda(seeds, { programAddress }); + return await fetchMaybeVoterWeightRecord(rpc, address, fetchConfig); +} diff --git a/clients/voter-stake-registry/src/generated/errors/index.ts b/clients/voter-stake-registry/src/generated/errors/index.ts new file mode 100644 index 00000000..93333bb5 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/errors/index.ts @@ -0,0 +1,9 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +export * from "./voterStakeRegistry.js"; diff --git a/clients/voter-stake-registry/src/generated/errors/voterStakeRegistry.ts b/clients/voter-stake-registry/src/generated/errors/voterStakeRegistry.ts new file mode 100644 index 00000000..1e5949ed --- /dev/null +++ b/clients/voter-stake-registry/src/generated/errors/voterStakeRegistry.ts @@ -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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + Address, + SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM, + SolanaError, +} from "@solana/kit"; +import { isProgramError } from "@solana/kit"; +import { VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS } from "../programs/index.js"; + +/** InvalidRate: Exchange rate must be greater than zero */ +export const VOTER_STAKE_REGISTRY_ERROR__INVALID_RATE = 0x1770; // 6000 +/** RatesFull: */ +export const VOTER_STAKE_REGISTRY_ERROR__RATES_FULL = 0x1771; // 6001 +/** VotingMintNotFound: */ +export const VOTER_STAKE_REGISTRY_ERROR__VOTING_MINT_NOT_FOUND = 0x1772; // 6002 +/** DepositEntryNotFound: */ +export const VOTER_STAKE_REGISTRY_ERROR__DEPOSIT_ENTRY_NOT_FOUND = 0x1773; // 6003 +/** DepositEntryFull: */ +export const VOTER_STAKE_REGISTRY_ERROR__DEPOSIT_ENTRY_FULL = 0x1774; // 6004 +/** VotingTokenNonZero: */ +export const VOTER_STAKE_REGISTRY_ERROR__VOTING_TOKEN_NON_ZERO = 0x1775; // 6005 +/** OutOfBoundsDepositEntryIndex: */ +export const VOTER_STAKE_REGISTRY_ERROR__OUT_OF_BOUNDS_DEPOSIT_ENTRY_INDEX = 0x1776; // 6006 +/** UnusedDepositEntryIndex: */ +export const VOTER_STAKE_REGISTRY_ERROR__UNUSED_DEPOSIT_ENTRY_INDEX = 0x1777; // 6007 +/** InsufficientVestedTokens: */ +export const VOTER_STAKE_REGISTRY_ERROR__INSUFFICIENT_VESTED_TOKENS = 0x1778; // 6008 +/** UnableToConvert: */ +export const VOTER_STAKE_REGISTRY_ERROR__UNABLE_TO_CONVERT = 0x1779; // 6009 +/** InvalidLockupPeriod: */ +export const VOTER_STAKE_REGISTRY_ERROR__INVALID_LOCKUP_PERIOD = 0x177a; // 6010 +/** InvalidEndTs: */ +export const VOTER_STAKE_REGISTRY_ERROR__INVALID_END_TS = 0x177b; // 6011 +/** InvalidDays: */ +export const VOTER_STAKE_REGISTRY_ERROR__INVALID_DAYS = 0x177c; // 6012 +/** VotingMintConfigIndexAlreadyInUse: */ +export const VOTER_STAKE_REGISTRY_ERROR__VOTING_MINT_CONFIG_INDEX_ALREADY_IN_USE = 0x177d; // 6013 +/** OutOfBoundsVotingMintConfigIndex: */ +export const VOTER_STAKE_REGISTRY_ERROR__OUT_OF_BOUNDS_VOTING_MINT_CONFIG_INDEX = 0x177e; // 6014 +/** InvalidDecimals: Exchange rate decimals cannot be larger than registrar decimals */ +export const VOTER_STAKE_REGISTRY_ERROR__INVALID_DECIMALS = 0x177f; // 6015 +/** InvalidToDepositAndWithdrawInOneSlot: */ +export const VOTER_STAKE_REGISTRY_ERROR__INVALID_TO_DEPOSIT_AND_WITHDRAW_IN_ONE_SLOT = 0x1780; // 6016 +/** ShouldBeTheFirstIxInATx: */ +export const VOTER_STAKE_REGISTRY_ERROR__SHOULD_BE_THE_FIRST_IX_IN_A_TX = 0x1781; // 6017 +/** ForbiddenCpi: */ +export const VOTER_STAKE_REGISTRY_ERROR__FORBIDDEN_CPI = 0x1782; // 6018 +/** InvalidMint: */ +export const VOTER_STAKE_REGISTRY_ERROR__INVALID_MINT = 0x1783; // 6019 +/** DebugInstruction: */ +export const VOTER_STAKE_REGISTRY_ERROR__DEBUG_INSTRUCTION = 0x1784; // 6020 +/** ClawbackNotAllowedOnDeposit: */ +export const VOTER_STAKE_REGISTRY_ERROR__CLAWBACK_NOT_ALLOWED_ON_DEPOSIT = 0x1785; // 6021 +/** DepositStillLocked: */ +export const VOTER_STAKE_REGISTRY_ERROR__DEPOSIT_STILL_LOCKED = 0x1786; // 6022 +/** InvalidAuthority: */ +export const VOTER_STAKE_REGISTRY_ERROR__INVALID_AUTHORITY = 0x1787; // 6023 +/** InvalidTokenOwnerRecord: */ +export const VOTER_STAKE_REGISTRY_ERROR__INVALID_TOKEN_OWNER_RECORD = 0x1788; // 6024 +/** InvalidRealmAuthority: */ +export const VOTER_STAKE_REGISTRY_ERROR__INVALID_REALM_AUTHORITY = 0x1789; // 6025 +/** VoterWeightOverflow: */ +export const VOTER_STAKE_REGISTRY_ERROR__VOTER_WEIGHT_OVERFLOW = 0x178a; // 6026 +/** LockupSaturationMustBePositive: */ +export const VOTER_STAKE_REGISTRY_ERROR__LOCKUP_SATURATION_MUST_BE_POSITIVE = 0x178b; // 6027 +/** VotingMintConfiguredWithDifferentIndex: */ +export const VOTER_STAKE_REGISTRY_ERROR__VOTING_MINT_CONFIGURED_WITH_DIFFERENT_INDEX = 0x178c; // 6028 +/** InternalProgramError: */ +export const VOTER_STAKE_REGISTRY_ERROR__INTERNAL_PROGRAM_ERROR = 0x178d; // 6029 +/** InsufficientLockedTokens: */ +export const VOTER_STAKE_REGISTRY_ERROR__INSUFFICIENT_LOCKED_TOKENS = 0x178e; // 6030 +/** MustKeepTokensLocked: */ +export const VOTER_STAKE_REGISTRY_ERROR__MUST_KEEP_TOKENS_LOCKED = 0x178f; // 6031 +/** InvalidLockupKind: */ +export const VOTER_STAKE_REGISTRY_ERROR__INVALID_LOCKUP_KIND = 0x1790; // 6032 +/** InvalidChangeToClawbackDepositEntry: */ +export const VOTER_STAKE_REGISTRY_ERROR__INVALID_CHANGE_TO_CLAWBACK_DEPOSIT_ENTRY = 0x1791; // 6033 + +export type VoterStakeRegistryError = + | typeof VOTER_STAKE_REGISTRY_ERROR__CLAWBACK_NOT_ALLOWED_ON_DEPOSIT + | typeof VOTER_STAKE_REGISTRY_ERROR__DEBUG_INSTRUCTION + | typeof VOTER_STAKE_REGISTRY_ERROR__DEPOSIT_ENTRY_FULL + | typeof VOTER_STAKE_REGISTRY_ERROR__DEPOSIT_ENTRY_NOT_FOUND + | typeof VOTER_STAKE_REGISTRY_ERROR__DEPOSIT_STILL_LOCKED + | typeof VOTER_STAKE_REGISTRY_ERROR__FORBIDDEN_CPI + | typeof VOTER_STAKE_REGISTRY_ERROR__INSUFFICIENT_LOCKED_TOKENS + | typeof VOTER_STAKE_REGISTRY_ERROR__INSUFFICIENT_VESTED_TOKENS + | typeof VOTER_STAKE_REGISTRY_ERROR__INTERNAL_PROGRAM_ERROR + | typeof VOTER_STAKE_REGISTRY_ERROR__INVALID_AUTHORITY + | typeof VOTER_STAKE_REGISTRY_ERROR__INVALID_CHANGE_TO_CLAWBACK_DEPOSIT_ENTRY + | typeof VOTER_STAKE_REGISTRY_ERROR__INVALID_DAYS + | typeof VOTER_STAKE_REGISTRY_ERROR__INVALID_DECIMALS + | typeof VOTER_STAKE_REGISTRY_ERROR__INVALID_END_TS + | typeof VOTER_STAKE_REGISTRY_ERROR__INVALID_LOCKUP_KIND + | typeof VOTER_STAKE_REGISTRY_ERROR__INVALID_LOCKUP_PERIOD + | typeof VOTER_STAKE_REGISTRY_ERROR__INVALID_MINT + | typeof VOTER_STAKE_REGISTRY_ERROR__INVALID_RATE + | typeof VOTER_STAKE_REGISTRY_ERROR__INVALID_REALM_AUTHORITY + | typeof VOTER_STAKE_REGISTRY_ERROR__INVALID_TO_DEPOSIT_AND_WITHDRAW_IN_ONE_SLOT + | typeof VOTER_STAKE_REGISTRY_ERROR__INVALID_TOKEN_OWNER_RECORD + | typeof VOTER_STAKE_REGISTRY_ERROR__LOCKUP_SATURATION_MUST_BE_POSITIVE + | typeof VOTER_STAKE_REGISTRY_ERROR__MUST_KEEP_TOKENS_LOCKED + | typeof VOTER_STAKE_REGISTRY_ERROR__OUT_OF_BOUNDS_DEPOSIT_ENTRY_INDEX + | typeof VOTER_STAKE_REGISTRY_ERROR__OUT_OF_BOUNDS_VOTING_MINT_CONFIG_INDEX + | typeof VOTER_STAKE_REGISTRY_ERROR__RATES_FULL + | typeof VOTER_STAKE_REGISTRY_ERROR__SHOULD_BE_THE_FIRST_IX_IN_A_TX + | typeof VOTER_STAKE_REGISTRY_ERROR__UNABLE_TO_CONVERT + | typeof VOTER_STAKE_REGISTRY_ERROR__UNUSED_DEPOSIT_ENTRY_INDEX + | typeof VOTER_STAKE_REGISTRY_ERROR__VOTER_WEIGHT_OVERFLOW + | typeof VOTER_STAKE_REGISTRY_ERROR__VOTING_MINT_CONFIG_INDEX_ALREADY_IN_USE + | typeof VOTER_STAKE_REGISTRY_ERROR__VOTING_MINT_CONFIGURED_WITH_DIFFERENT_INDEX + | typeof VOTER_STAKE_REGISTRY_ERROR__VOTING_MINT_NOT_FOUND + | typeof VOTER_STAKE_REGISTRY_ERROR__VOTING_TOKEN_NON_ZERO; + +let voterStakeRegistryErrorMessages: + | Record + | undefined; +if (true) { + voterStakeRegistryErrorMessages = { + [VOTER_STAKE_REGISTRY_ERROR__CLAWBACK_NOT_ALLOWED_ON_DEPOSIT]: "", + [VOTER_STAKE_REGISTRY_ERROR__DEBUG_INSTRUCTION]: "", + [VOTER_STAKE_REGISTRY_ERROR__DEPOSIT_ENTRY_FULL]: "", + [VOTER_STAKE_REGISTRY_ERROR__DEPOSIT_ENTRY_NOT_FOUND]: "", + [VOTER_STAKE_REGISTRY_ERROR__DEPOSIT_STILL_LOCKED]: "", + [VOTER_STAKE_REGISTRY_ERROR__FORBIDDEN_CPI]: "", + [VOTER_STAKE_REGISTRY_ERROR__INSUFFICIENT_LOCKED_TOKENS]: "", + [VOTER_STAKE_REGISTRY_ERROR__INSUFFICIENT_VESTED_TOKENS]: "", + [VOTER_STAKE_REGISTRY_ERROR__INTERNAL_PROGRAM_ERROR]: "", + [VOTER_STAKE_REGISTRY_ERROR__INVALID_AUTHORITY]: "", + [VOTER_STAKE_REGISTRY_ERROR__INVALID_CHANGE_TO_CLAWBACK_DEPOSIT_ENTRY]: "", + [VOTER_STAKE_REGISTRY_ERROR__INVALID_DAYS]: "", + [VOTER_STAKE_REGISTRY_ERROR__INVALID_DECIMALS]: + "Exchange rate decimals cannot be larger than registrar decimals", + [VOTER_STAKE_REGISTRY_ERROR__INVALID_END_TS]: "", + [VOTER_STAKE_REGISTRY_ERROR__INVALID_LOCKUP_KIND]: "", + [VOTER_STAKE_REGISTRY_ERROR__INVALID_LOCKUP_PERIOD]: "", + [VOTER_STAKE_REGISTRY_ERROR__INVALID_MINT]: "", + [VOTER_STAKE_REGISTRY_ERROR__INVALID_RATE]: + "Exchange rate must be greater than zero", + [VOTER_STAKE_REGISTRY_ERROR__INVALID_REALM_AUTHORITY]: "", + [VOTER_STAKE_REGISTRY_ERROR__INVALID_TO_DEPOSIT_AND_WITHDRAW_IN_ONE_SLOT]: + "", + [VOTER_STAKE_REGISTRY_ERROR__INVALID_TOKEN_OWNER_RECORD]: "", + [VOTER_STAKE_REGISTRY_ERROR__LOCKUP_SATURATION_MUST_BE_POSITIVE]: "", + [VOTER_STAKE_REGISTRY_ERROR__MUST_KEEP_TOKENS_LOCKED]: "", + [VOTER_STAKE_REGISTRY_ERROR__OUT_OF_BOUNDS_DEPOSIT_ENTRY_INDEX]: "", + [VOTER_STAKE_REGISTRY_ERROR__OUT_OF_BOUNDS_VOTING_MINT_CONFIG_INDEX]: "", + [VOTER_STAKE_REGISTRY_ERROR__RATES_FULL]: "", + [VOTER_STAKE_REGISTRY_ERROR__SHOULD_BE_THE_FIRST_IX_IN_A_TX]: "", + [VOTER_STAKE_REGISTRY_ERROR__UNABLE_TO_CONVERT]: "", + [VOTER_STAKE_REGISTRY_ERROR__UNUSED_DEPOSIT_ENTRY_INDEX]: "", + [VOTER_STAKE_REGISTRY_ERROR__VOTER_WEIGHT_OVERFLOW]: "", + [VOTER_STAKE_REGISTRY_ERROR__VOTING_MINT_CONFIG_INDEX_ALREADY_IN_USE]: "", + [VOTER_STAKE_REGISTRY_ERROR__VOTING_MINT_CONFIGURED_WITH_DIFFERENT_INDEX]: + "", + [VOTER_STAKE_REGISTRY_ERROR__VOTING_MINT_NOT_FOUND]: "", + [VOTER_STAKE_REGISTRY_ERROR__VOTING_TOKEN_NON_ZERO]: "", + }; +} + +export function getVoterStakeRegistryErrorMessage( + code: VoterStakeRegistryError, +): string { + if (true) { + return voterStakeRegistryErrorMessages![code]; + } + + return "Error message not available in production bundles."; +} + +export function isVoterStakeRegistryError< + TProgramErrorCode extends VoterStakeRegistryError, +>( + error: unknown, + transactionMessage: { + instructions: Record; + }, + code?: TProgramErrorCode, +): error is SolanaError & + Readonly<{ context: Readonly<{ code: TProgramErrorCode }> }> { + return isProgramError( + error, + transactionMessage, + VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + code, + ); +} diff --git a/clients/voter-stake-registry/src/generated/index.ts b/clients/voter-stake-registry/src/generated/index.ts new file mode 100644 index 00000000..975e985c --- /dev/null +++ b/clients/voter-stake-registry/src/generated/index.ts @@ -0,0 +1,14 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +export * from "./accounts/index.js"; +export * from "./errors/index.js"; +export * from "./instructions/index.js"; +export * from "./pdas/index.js"; +export * from "./programs/index.js"; +export * from "./types/index.js"; diff --git a/clients/voter-stake-registry/src/generated/instructions/clawback.ts b/clients/voter-stake-registry/src/generated/instructions/clawback.ts new file mode 100644 index 00000000..aa3751a4 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/instructions/clawback.ts @@ -0,0 +1,282 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + AccountMeta, + AccountSignerMeta, + Address, + FixedSizeCodec, + FixedSizeDecoder, + FixedSizeEncoder, + Instruction, + InstructionWithAccounts, + InstructionWithData, + ReadonlyAccount, + ReadonlySignerAccount, + ReadonlyUint8Array, + TransactionSigner, + WritableAccount, +} from "@solana/kit"; +import type { ResolvedAccount } from "../shared/index.js"; +import { + combineCodec, + fixDecoderSize, + fixEncoderSize, + getBytesDecoder, + getBytesEncoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + transformEncoder, +} from "@solana/kit"; +import { VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS } from "../programs/index.js"; +import { getAccountMetaFactory } from "../shared/index.js"; + +export const CLAWBACK_DISCRIMINATOR: ReadonlyUint8Array = new Uint8Array([ + 111, 92, 142, 79, 33, 234, 82, 27, +]); + +export function getClawbackDiscriminatorBytes(): ReadonlyUint8Array { + return fixEncoderSize(getBytesEncoder(), 8).encode(CLAWBACK_DISCRIMINATOR); +} + +export type ClawbackInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountRegistrar extends string | AccountMeta = string, + TAccountRealmAuthority extends string | AccountMeta = string, + TAccountVoter extends string | AccountMeta = string, + TAccountTokenOwnerRecord extends string | AccountMeta = string, + TAccountVault extends string | AccountMeta = string, + TAccountDestination extends string | AccountMeta = string, + TAccountTokenProgram extends + | string + | AccountMeta = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountRegistrar extends string + ? ReadonlyAccount + : TAccountRegistrar, + TAccountRealmAuthority extends string + ? ReadonlySignerAccount & + AccountSignerMeta + : TAccountRealmAuthority, + TAccountVoter extends string + ? WritableAccount + : TAccountVoter, + TAccountTokenOwnerRecord extends string + ? ReadonlyAccount + : TAccountTokenOwnerRecord, + TAccountVault extends string + ? WritableAccount + : TAccountVault, + TAccountDestination extends string + ? WritableAccount + : TAccountDestination, + TAccountTokenProgram extends string + ? ReadonlyAccount + : TAccountTokenProgram, + ...TRemainingAccounts, + ] + >; + +export interface ClawbackInstructionData { + discriminator: ReadonlyUint8Array; + depositEntryIndex: number; +} + +export interface ClawbackInstructionDataArgs { + depositEntryIndex: number; +} + +export function getClawbackInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([ + ["discriminator", fixEncoderSize(getBytesEncoder(), 8)], + ["depositEntryIndex", getU8Encoder()], + ]), + (value) => ({ ...value, discriminator: CLAWBACK_DISCRIMINATOR }), + ); +} + +export function getClawbackInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ["discriminator", fixDecoderSize(getBytesDecoder(), 8)], + ["depositEntryIndex", getU8Decoder()], + ]); +} + +export function getClawbackInstructionDataCodec(): FixedSizeCodec< + ClawbackInstructionDataArgs, + ClawbackInstructionData +> { + return combineCodec( + getClawbackInstructionDataEncoder(), + getClawbackInstructionDataDecoder(), + ); +} + +export interface ClawbackInput< + TAccountRegistrar extends string = string, + TAccountRealmAuthority extends string = string, + TAccountVoter extends string = string, + TAccountTokenOwnerRecord extends string = string, + TAccountVault extends string = string, + TAccountDestination extends string = string, + TAccountTokenProgram extends string = string, +> { + registrar: Address; + realmAuthority: TransactionSigner; + voter: Address; + tokenOwnerRecord: Address; + vault: Address; + destination: Address; + tokenProgram?: Address; + depositEntryIndex: ClawbackInstructionDataArgs["depositEntryIndex"]; +} + +export function getClawbackInstruction< + TAccountRegistrar extends string, + TAccountRealmAuthority extends string, + TAccountVoter extends string, + TAccountTokenOwnerRecord extends string, + TAccountVault extends string, + TAccountDestination extends string, + TAccountTokenProgram extends string, + TProgramAddress extends Address = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, +>( + input: ClawbackInput< + TAccountRegistrar, + TAccountRealmAuthority, + TAccountVoter, + TAccountTokenOwnerRecord, + TAccountVault, + TAccountDestination, + TAccountTokenProgram + >, + config?: { programAddress?: TProgramAddress }, +): ClawbackInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountRealmAuthority, + TAccountVoter, + TAccountTokenOwnerRecord, + TAccountVault, + TAccountDestination, + TAccountTokenProgram +> { + // Program address. + const programAddress = + config?.programAddress ?? VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + registrar: { value: input.registrar ?? null, isWritable: false }, + realmAuthority: { value: input.realmAuthority ?? null, isWritable: false }, + voter: { value: input.voter ?? null, isWritable: true }, + tokenOwnerRecord: { + value: input.tokenOwnerRecord ?? null, + isWritable: false, + }, + vault: { value: input.vault ?? null, isWritable: true }, + destination: { value: input.destination ?? null, isWritable: true }, + tokenProgram: { value: input.tokenProgram ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record< + keyof typeof originalAccounts, + ResolvedAccount + >; + + // Original args. + const args = { ...input }; + + // Resolve default values. + if (!accounts.tokenProgram.value) { + accounts.tokenProgram.value = + "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" as Address<"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA">; + } + + const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.registrar), + getAccountMeta(accounts.realmAuthority), + getAccountMeta(accounts.voter), + getAccountMeta(accounts.tokenOwnerRecord), + getAccountMeta(accounts.vault), + getAccountMeta(accounts.destination), + getAccountMeta(accounts.tokenProgram), + ], + data: getClawbackInstructionDataEncoder().encode( + args as ClawbackInstructionDataArgs, + ), + programAddress, + } as ClawbackInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountRealmAuthority, + TAccountVoter, + TAccountTokenOwnerRecord, + TAccountVault, + TAccountDestination, + TAccountTokenProgram + >); +} + +export interface ParsedClawbackInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> { + programAddress: Address; + accounts: { + registrar: TAccountMetas[0]; + realmAuthority: TAccountMetas[1]; + voter: TAccountMetas[2]; + tokenOwnerRecord: TAccountMetas[3]; + vault: TAccountMetas[4]; + destination: TAccountMetas[5]; + tokenProgram: TAccountMetas[6]; + }; + data: ClawbackInstructionData; +} + +export function parseClawbackInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedClawbackInstruction { + if (instruction.accounts.length < 7) { + // TODO: Coded error. + throw new Error("Not enough accounts"); + } + let accountIndex = 0; + const getNextAccount = () => { + const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; + accountIndex += 1; + return accountMeta; + }; + return { + programAddress: instruction.programAddress, + accounts: { + registrar: getNextAccount(), + realmAuthority: getNextAccount(), + voter: getNextAccount(), + tokenOwnerRecord: getNextAccount(), + vault: getNextAccount(), + destination: getNextAccount(), + tokenProgram: getNextAccount(), + }, + data: getClawbackInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/clients/voter-stake-registry/src/generated/instructions/closeDepositEntry.ts b/clients/voter-stake-registry/src/generated/instructions/closeDepositEntry.ts new file mode 100644 index 00000000..ccdcdaf7 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/instructions/closeDepositEntry.ts @@ -0,0 +1,195 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + AccountMeta, + AccountSignerMeta, + Address, + FixedSizeCodec, + FixedSizeDecoder, + FixedSizeEncoder, + Instruction, + InstructionWithAccounts, + InstructionWithData, + ReadonlySignerAccount, + ReadonlyUint8Array, + TransactionSigner, + WritableAccount, +} from "@solana/kit"; +import type { ResolvedAccount } from "../shared/index.js"; +import { + combineCodec, + fixDecoderSize, + fixEncoderSize, + getBytesDecoder, + getBytesEncoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + transformEncoder, +} from "@solana/kit"; +import { VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS } from "../programs/index.js"; +import { getAccountMetaFactory } from "../shared/index.js"; + +export const CLOSE_DEPOSIT_ENTRY_DISCRIMINATOR: ReadonlyUint8Array = + new Uint8Array([236, 190, 87, 34, 251, 131, 138, 237]); + +export function getCloseDepositEntryDiscriminatorBytes(): ReadonlyUint8Array { + return fixEncoderSize(getBytesEncoder(), 8).encode( + CLOSE_DEPOSIT_ENTRY_DISCRIMINATOR, + ); +} + +export type CloseDepositEntryInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountVoter extends string | AccountMeta = string, + TAccountVoterAuthority extends string | AccountMeta = string, + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountVoter extends string + ? WritableAccount + : TAccountVoter, + TAccountVoterAuthority extends string + ? ReadonlySignerAccount & + AccountSignerMeta + : TAccountVoterAuthority, + ...TRemainingAccounts, + ] + >; + +export interface CloseDepositEntryInstructionData { + discriminator: ReadonlyUint8Array; + depositEntryIndex: number; +} + +export interface CloseDepositEntryInstructionDataArgs { + depositEntryIndex: number; +} + +export function getCloseDepositEntryInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([ + ["discriminator", fixEncoderSize(getBytesEncoder(), 8)], + ["depositEntryIndex", getU8Encoder()], + ]), + (value) => ({ ...value, discriminator: CLOSE_DEPOSIT_ENTRY_DISCRIMINATOR }), + ); +} + +export function getCloseDepositEntryInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ["discriminator", fixDecoderSize(getBytesDecoder(), 8)], + ["depositEntryIndex", getU8Decoder()], + ]); +} + +export function getCloseDepositEntryInstructionDataCodec(): FixedSizeCodec< + CloseDepositEntryInstructionDataArgs, + CloseDepositEntryInstructionData +> { + return combineCodec( + getCloseDepositEntryInstructionDataEncoder(), + getCloseDepositEntryInstructionDataDecoder(), + ); +} + +export interface CloseDepositEntryInput< + TAccountVoter extends string = string, + TAccountVoterAuthority extends string = string, +> { + voter: Address; + voterAuthority: TransactionSigner; + depositEntryIndex: CloseDepositEntryInstructionDataArgs["depositEntryIndex"]; +} + +export function getCloseDepositEntryInstruction< + TAccountVoter extends string, + TAccountVoterAuthority extends string, + TProgramAddress extends Address = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, +>( + input: CloseDepositEntryInput, + config?: { programAddress?: TProgramAddress }, +): CloseDepositEntryInstruction< + TProgramAddress, + TAccountVoter, + TAccountVoterAuthority +> { + // Program address. + const programAddress = + config?.programAddress ?? VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + voter: { value: input.voter ?? null, isWritable: true }, + voterAuthority: { value: input.voterAuthority ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record< + keyof typeof originalAccounts, + ResolvedAccount + >; + + // Original args. + const args = { ...input }; + + const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.voter), + getAccountMeta(accounts.voterAuthority), + ], + data: getCloseDepositEntryInstructionDataEncoder().encode( + args as CloseDepositEntryInstructionDataArgs, + ), + programAddress, + } as CloseDepositEntryInstruction< + TProgramAddress, + TAccountVoter, + TAccountVoterAuthority + >); +} + +export interface ParsedCloseDepositEntryInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> { + programAddress: Address; + accounts: { + voter: TAccountMetas[0]; + voterAuthority: TAccountMetas[1]; + }; + data: CloseDepositEntryInstructionData; +} + +export function parseCloseDepositEntryInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedCloseDepositEntryInstruction { + if (instruction.accounts.length < 2) { + // TODO: Coded error. + throw new Error("Not enough accounts"); + } + let accountIndex = 0; + const getNextAccount = () => { + const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; + accountIndex += 1; + return accountMeta; + }; + return { + programAddress: instruction.programAddress, + accounts: { voter: getNextAccount(), voterAuthority: getNextAccount() }, + data: getCloseDepositEntryInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/clients/voter-stake-registry/src/generated/instructions/closeVoter.ts b/clients/voter-stake-registry/src/generated/instructions/closeVoter.ts new file mode 100644 index 00000000..9d97426f --- /dev/null +++ b/clients/voter-stake-registry/src/generated/instructions/closeVoter.ts @@ -0,0 +1,200 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + AccountMeta, + AccountSignerMeta, + Address, + FixedSizeCodec, + FixedSizeDecoder, + FixedSizeEncoder, + Instruction, + InstructionWithAccounts, + InstructionWithData, + ReadonlyAccount, + ReadonlySignerAccount, + ReadonlyUint8Array, + TransactionSigner, + WritableAccount, +} from "@solana/kit"; +import type { ResolvedAccount } from "../shared/index.js"; +import { + combineCodec, + fixDecoderSize, + fixEncoderSize, + getBytesDecoder, + getBytesEncoder, + getStructDecoder, + getStructEncoder, + transformEncoder, +} from "@solana/kit"; +import { VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS } from "../programs/index.js"; +import { getAccountMetaFactory } from "../shared/index.js"; + +export const CLOSE_VOTER_DISCRIMINATOR: ReadonlyUint8Array = new Uint8Array([ + 117, 35, 234, 247, 206, 131, 182, 149, +]); + +export function getCloseVoterDiscriminatorBytes(): ReadonlyUint8Array { + return fixEncoderSize(getBytesEncoder(), 8).encode(CLOSE_VOTER_DISCRIMINATOR); +} + +export type CloseVoterInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountVoter extends string | AccountMeta = string, + TAccountVoterAuthority extends string | AccountMeta = string, + TAccountSolDestination extends string | AccountMeta = string, + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountVoter extends string + ? WritableAccount + : TAccountVoter, + TAccountVoterAuthority extends string + ? ReadonlySignerAccount & + AccountSignerMeta + : TAccountVoterAuthority, + TAccountSolDestination extends string + ? ReadonlyAccount + : TAccountSolDestination, + ...TRemainingAccounts, + ] + >; + +export interface CloseVoterInstructionData { + discriminator: ReadonlyUint8Array; +} + +export interface CloseVoterInstructionDataArgs {} + +export function getCloseVoterInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([["discriminator", fixEncoderSize(getBytesEncoder(), 8)]]), + (value) => ({ ...value, discriminator: CLOSE_VOTER_DISCRIMINATOR }), + ); +} + +export function getCloseVoterInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ["discriminator", fixDecoderSize(getBytesDecoder(), 8)], + ]); +} + +export function getCloseVoterInstructionDataCodec(): FixedSizeCodec< + CloseVoterInstructionDataArgs, + CloseVoterInstructionData +> { + return combineCodec( + getCloseVoterInstructionDataEncoder(), + getCloseVoterInstructionDataDecoder(), + ); +} + +export interface CloseVoterInput< + TAccountVoter extends string = string, + TAccountVoterAuthority extends string = string, + TAccountSolDestination extends string = string, +> { + voter: Address; + voterAuthority: TransactionSigner; + solDestination: Address; +} + +export function getCloseVoterInstruction< + TAccountVoter extends string, + TAccountVoterAuthority extends string, + TAccountSolDestination extends string, + TProgramAddress extends Address = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, +>( + input: CloseVoterInput< + TAccountVoter, + TAccountVoterAuthority, + TAccountSolDestination + >, + config?: { programAddress?: TProgramAddress }, +): CloseVoterInstruction< + TProgramAddress, + TAccountVoter, + TAccountVoterAuthority, + TAccountSolDestination +> { + // Program address. + const programAddress = + config?.programAddress ?? VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + voter: { value: input.voter ?? null, isWritable: true }, + voterAuthority: { value: input.voterAuthority ?? null, isWritable: false }, + solDestination: { value: input.solDestination ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record< + keyof typeof originalAccounts, + ResolvedAccount + >; + + const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.voter), + getAccountMeta(accounts.voterAuthority), + getAccountMeta(accounts.solDestination), + ], + data: getCloseVoterInstructionDataEncoder().encode({}), + programAddress, + } as CloseVoterInstruction< + TProgramAddress, + TAccountVoter, + TAccountVoterAuthority, + TAccountSolDestination + >); +} + +export interface ParsedCloseVoterInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> { + programAddress: Address; + accounts: { + voter: TAccountMetas[0]; + voterAuthority: TAccountMetas[1]; + solDestination: TAccountMetas[2]; + }; + data: CloseVoterInstructionData; +} + +export function parseCloseVoterInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedCloseVoterInstruction { + if (instruction.accounts.length < 3) { + // TODO: Coded error. + throw new Error("Not enough accounts"); + } + let accountIndex = 0; + const getNextAccount = () => { + const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; + accountIndex += 1; + return accountMeta; + }; + return { + programAddress: instruction.programAddress, + accounts: { + voter: getNextAccount(), + voterAuthority: getNextAccount(), + solDestination: getNextAccount(), + }, + data: getCloseVoterInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/clients/voter-stake-registry/src/generated/instructions/configureVotingMint.ts b/clients/voter-stake-registry/src/generated/instructions/configureVotingMint.ts new file mode 100644 index 00000000..c5ecb824 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/instructions/configureVotingMint.ts @@ -0,0 +1,256 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + AccountMeta, + AccountSignerMeta, + Address, + Codec, + Decoder, + Encoder, + Instruction, + InstructionWithAccounts, + InstructionWithData, + Option, + OptionOrNullable, + ReadonlyAccount, + ReadonlySignerAccount, + ReadonlyUint8Array, + TransactionSigner, + WritableAccount, +} from "@solana/kit"; +import type { ResolvedAccount } from "../shared/index.js"; +import { + combineCodec, + fixDecoderSize, + fixEncoderSize, + getAddressDecoder, + getAddressEncoder, + getBytesDecoder, + getBytesEncoder, + getI8Decoder, + getI8Encoder, + getOptionDecoder, + getOptionEncoder, + getStructDecoder, + getStructEncoder, + getU16Decoder, + getU16Encoder, + getU64Decoder, + getU64Encoder, + transformEncoder, +} from "@solana/kit"; +import { VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS } from "../programs/index.js"; +import { getAccountMetaFactory } from "../shared/index.js"; + +export const CONFIGURE_VOTING_MINT_DISCRIMINATOR: ReadonlyUint8Array = + new Uint8Array([113, 153, 141, 236, 184, 9, 135, 15]); + +export function getConfigureVotingMintDiscriminatorBytes(): ReadonlyUint8Array { + return fixEncoderSize(getBytesEncoder(), 8).encode( + CONFIGURE_VOTING_MINT_DISCRIMINATOR, + ); +} + +export type ConfigureVotingMintInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountRegistrar extends string | AccountMeta = string, + TAccountRealmAuthority extends string | AccountMeta = string, + TAccountMint extends string | AccountMeta = string, + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountRegistrar extends string + ? WritableAccount + : TAccountRegistrar, + TAccountRealmAuthority extends string + ? ReadonlySignerAccount & + AccountSignerMeta + : TAccountRealmAuthority, + TAccountMint extends string + ? ReadonlyAccount + : TAccountMint, + ...TRemainingAccounts, + ] + >; + +export interface ConfigureVotingMintInstructionData { + discriminator: ReadonlyUint8Array; + idx: number; + digitShift: number; + depositScaledFactor: bigint; + lockupScaledFactor: bigint; + lockupSaturationSecs: bigint; + grantAuthority: Option
; +} + +export interface ConfigureVotingMintInstructionDataArgs { + idx: number; + digitShift: number; + depositScaledFactor: number | bigint; + lockupScaledFactor: number | bigint; + lockupSaturationSecs: number | bigint; + grantAuthority: OptionOrNullable
; +} + +export function getConfigureVotingMintInstructionDataEncoder(): Encoder { + return transformEncoder( + getStructEncoder([ + ["discriminator", fixEncoderSize(getBytesEncoder(), 8)], + ["idx", getU16Encoder()], + ["digitShift", getI8Encoder()], + ["depositScaledFactor", getU64Encoder()], + ["lockupScaledFactor", getU64Encoder()], + ["lockupSaturationSecs", getU64Encoder()], + ["grantAuthority", getOptionEncoder(getAddressEncoder())], + ]), + (value) => ({ + ...value, + discriminator: CONFIGURE_VOTING_MINT_DISCRIMINATOR, + }), + ); +} + +export function getConfigureVotingMintInstructionDataDecoder(): Decoder { + return getStructDecoder([ + ["discriminator", fixDecoderSize(getBytesDecoder(), 8)], + ["idx", getU16Decoder()], + ["digitShift", getI8Decoder()], + ["depositScaledFactor", getU64Decoder()], + ["lockupScaledFactor", getU64Decoder()], + ["lockupSaturationSecs", getU64Decoder()], + ["grantAuthority", getOptionDecoder(getAddressDecoder())], + ]); +} + +export function getConfigureVotingMintInstructionDataCodec(): Codec< + ConfigureVotingMintInstructionDataArgs, + ConfigureVotingMintInstructionData +> { + return combineCodec( + getConfigureVotingMintInstructionDataEncoder(), + getConfigureVotingMintInstructionDataDecoder(), + ); +} + +export interface ConfigureVotingMintInput< + TAccountRegistrar extends string = string, + TAccountRealmAuthority extends string = string, + TAccountMint extends string = string, +> { + registrar: Address; + realmAuthority: TransactionSigner; + mint: Address; + idx: ConfigureVotingMintInstructionDataArgs["idx"]; + digitShift: ConfigureVotingMintInstructionDataArgs["digitShift"]; + depositScaledFactor: ConfigureVotingMintInstructionDataArgs["depositScaledFactor"]; + lockupScaledFactor: ConfigureVotingMintInstructionDataArgs["lockupScaledFactor"]; + lockupSaturationSecs: ConfigureVotingMintInstructionDataArgs["lockupSaturationSecs"]; + grantAuthority: ConfigureVotingMintInstructionDataArgs["grantAuthority"]; +} + +export function getConfigureVotingMintInstruction< + TAccountRegistrar extends string, + TAccountRealmAuthority extends string, + TAccountMint extends string, + TProgramAddress extends Address = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, +>( + input: ConfigureVotingMintInput< + TAccountRegistrar, + TAccountRealmAuthority, + TAccountMint + >, + config?: { programAddress?: TProgramAddress }, +): ConfigureVotingMintInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountRealmAuthority, + TAccountMint +> { + // Program address. + const programAddress = + config?.programAddress ?? VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + registrar: { value: input.registrar ?? null, isWritable: true }, + realmAuthority: { value: input.realmAuthority ?? null, isWritable: false }, + mint: { value: input.mint ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record< + keyof typeof originalAccounts, + ResolvedAccount + >; + + // Original args. + const args = { ...input }; + + const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.registrar), + getAccountMeta(accounts.realmAuthority), + getAccountMeta(accounts.mint), + ], + data: getConfigureVotingMintInstructionDataEncoder().encode( + args as ConfigureVotingMintInstructionDataArgs, + ), + programAddress, + } as ConfigureVotingMintInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountRealmAuthority, + TAccountMint + >); +} + +export interface ParsedConfigureVotingMintInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> { + programAddress: Address; + accounts: { + registrar: TAccountMetas[0]; + realmAuthority: TAccountMetas[1]; + mint: TAccountMetas[2]; + }; + data: ConfigureVotingMintInstructionData; +} + +export function parseConfigureVotingMintInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedConfigureVotingMintInstruction { + if (instruction.accounts.length < 3) { + // TODO: Coded error. + throw new Error("Not enough accounts"); + } + let accountIndex = 0; + const getNextAccount = () => { + const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; + accountIndex += 1; + return accountMeta; + }; + return { + programAddress: instruction.programAddress, + accounts: { + registrar: getNextAccount(), + realmAuthority: getNextAccount(), + mint: getNextAccount(), + }, + data: getConfigureVotingMintInstructionDataDecoder().decode( + instruction.data, + ), + }; +} diff --git a/clients/voter-stake-registry/src/generated/instructions/createDepositEntry.ts b/clients/voter-stake-registry/src/generated/instructions/createDepositEntry.ts new file mode 100644 index 00000000..14d2d8eb --- /dev/null +++ b/clients/voter-stake-registry/src/generated/instructions/createDepositEntry.ts @@ -0,0 +1,382 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + AccountMeta, + AccountSignerMeta, + Address, + Codec, + Decoder, + Encoder, + Instruction, + InstructionWithAccounts, + InstructionWithData, + Option, + OptionOrNullable, + ReadonlyAccount, + ReadonlySignerAccount, + ReadonlyUint8Array, + TransactionSigner, + WritableAccount, + WritableSignerAccount, +} from "@solana/kit"; +import type { ResolvedAccount } from "../shared/index.js"; +import type { LockupKind, LockupKindArgs } from "../types/index.js"; +import { + combineCodec, + fixDecoderSize, + fixEncoderSize, + getBooleanDecoder, + getBooleanEncoder, + getBytesDecoder, + getBytesEncoder, + getOptionDecoder, + getOptionEncoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + getU32Decoder, + getU32Encoder, + getU64Decoder, + getU64Encoder, + transformEncoder, +} from "@solana/kit"; +import { VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS } from "../programs/index.js"; +import { getAccountMetaFactory } from "../shared/index.js"; +import { getLockupKindDecoder, getLockupKindEncoder } from "../types/index.js"; + +export const CREATE_DEPOSIT_ENTRY_DISCRIMINATOR: ReadonlyUint8Array = + new Uint8Array([185, 131, 167, 186, 159, 125, 19, 67]); + +export function getCreateDepositEntryDiscriminatorBytes(): ReadonlyUint8Array { + return fixEncoderSize(getBytesEncoder(), 8).encode( + CREATE_DEPOSIT_ENTRY_DISCRIMINATOR, + ); +} + +export type CreateDepositEntryInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountRegistrar extends string | AccountMeta = string, + TAccountVoter extends string | AccountMeta = string, + TAccountVault extends string | AccountMeta = string, + TAccountVoterAuthority extends string | AccountMeta = string, + TAccountPayer extends string | AccountMeta = string, + TAccountDepositMint extends string | AccountMeta = string, + TAccountSystemProgram extends + | string + | AccountMeta = "11111111111111111111111111111111", + TAccountTokenProgram extends + | string + | AccountMeta = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", + TAccountAssociatedTokenProgram extends + | string + | AccountMeta = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", + TAccountRent extends + | string + | AccountMeta = "SysvarRent111111111111111111111111111111111", + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountRegistrar extends string + ? ReadonlyAccount + : TAccountRegistrar, + TAccountVoter extends string + ? WritableAccount + : TAccountVoter, + TAccountVault extends string + ? WritableAccount + : TAccountVault, + TAccountVoterAuthority extends string + ? ReadonlySignerAccount & + AccountSignerMeta + : TAccountVoterAuthority, + TAccountPayer extends string + ? WritableSignerAccount & + AccountSignerMeta + : TAccountPayer, + TAccountDepositMint extends string + ? ReadonlyAccount + : TAccountDepositMint, + TAccountSystemProgram extends string + ? ReadonlyAccount + : TAccountSystemProgram, + TAccountTokenProgram extends string + ? ReadonlyAccount + : TAccountTokenProgram, + TAccountAssociatedTokenProgram extends string + ? ReadonlyAccount + : TAccountAssociatedTokenProgram, + TAccountRent extends string + ? ReadonlyAccount + : TAccountRent, + ...TRemainingAccounts, + ] + >; + +export interface CreateDepositEntryInstructionData { + discriminator: ReadonlyUint8Array; + depositEntryIndex: number; + kind: LockupKind; + startTs: Option; + periods: number; + allowClawback: boolean; +} + +export interface CreateDepositEntryInstructionDataArgs { + depositEntryIndex: number; + kind: LockupKindArgs; + startTs: OptionOrNullable; + periods: number; + allowClawback: boolean; +} + +export function getCreateDepositEntryInstructionDataEncoder(): Encoder { + return transformEncoder( + getStructEncoder([ + ["discriminator", fixEncoderSize(getBytesEncoder(), 8)], + ["depositEntryIndex", getU8Encoder()], + ["kind", getLockupKindEncoder()], + ["startTs", getOptionEncoder(getU64Encoder())], + ["periods", getU32Encoder()], + ["allowClawback", getBooleanEncoder()], + ]), + (value) => ({ + ...value, + discriminator: CREATE_DEPOSIT_ENTRY_DISCRIMINATOR, + }), + ); +} + +export function getCreateDepositEntryInstructionDataDecoder(): Decoder { + return getStructDecoder([ + ["discriminator", fixDecoderSize(getBytesDecoder(), 8)], + ["depositEntryIndex", getU8Decoder()], + ["kind", getLockupKindDecoder()], + ["startTs", getOptionDecoder(getU64Decoder())], + ["periods", getU32Decoder()], + ["allowClawback", getBooleanDecoder()], + ]); +} + +export function getCreateDepositEntryInstructionDataCodec(): Codec< + CreateDepositEntryInstructionDataArgs, + CreateDepositEntryInstructionData +> { + return combineCodec( + getCreateDepositEntryInstructionDataEncoder(), + getCreateDepositEntryInstructionDataDecoder(), + ); +} + +export interface CreateDepositEntryInput< + TAccountRegistrar extends string = string, + TAccountVoter extends string = string, + TAccountVault extends string = string, + TAccountVoterAuthority extends string = string, + TAccountPayer extends string = string, + TAccountDepositMint extends string = string, + TAccountSystemProgram extends string = string, + TAccountTokenProgram extends string = string, + TAccountAssociatedTokenProgram extends string = string, + TAccountRent extends string = string, +> { + registrar: Address; + voter: Address; + vault: Address; + voterAuthority: TransactionSigner; + payer: TransactionSigner; + depositMint: Address; + systemProgram?: Address; + tokenProgram?: Address; + associatedTokenProgram?: Address; + rent?: Address; + depositEntryIndex: CreateDepositEntryInstructionDataArgs["depositEntryIndex"]; + kind: CreateDepositEntryInstructionDataArgs["kind"]; + startTs: CreateDepositEntryInstructionDataArgs["startTs"]; + periods: CreateDepositEntryInstructionDataArgs["periods"]; + allowClawback: CreateDepositEntryInstructionDataArgs["allowClawback"]; +} + +export function getCreateDepositEntryInstruction< + TAccountRegistrar extends string, + TAccountVoter extends string, + TAccountVault extends string, + TAccountVoterAuthority extends string, + TAccountPayer extends string, + TAccountDepositMint extends string, + TAccountSystemProgram extends string, + TAccountTokenProgram extends string, + TAccountAssociatedTokenProgram extends string, + TAccountRent extends string, + TProgramAddress extends Address = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, +>( + input: CreateDepositEntryInput< + TAccountRegistrar, + TAccountVoter, + TAccountVault, + TAccountVoterAuthority, + TAccountPayer, + TAccountDepositMint, + TAccountSystemProgram, + TAccountTokenProgram, + TAccountAssociatedTokenProgram, + TAccountRent + >, + config?: { programAddress?: TProgramAddress }, +): CreateDepositEntryInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountVoter, + TAccountVault, + TAccountVoterAuthority, + TAccountPayer, + TAccountDepositMint, + TAccountSystemProgram, + TAccountTokenProgram, + TAccountAssociatedTokenProgram, + TAccountRent +> { + // Program address. + const programAddress = + config?.programAddress ?? VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + registrar: { value: input.registrar ?? null, isWritable: false }, + voter: { value: input.voter ?? null, isWritable: true }, + vault: { value: input.vault ?? null, isWritable: true }, + voterAuthority: { value: input.voterAuthority ?? null, isWritable: false }, + payer: { value: input.payer ?? null, isWritable: true }, + depositMint: { value: input.depositMint ?? null, isWritable: false }, + systemProgram: { value: input.systemProgram ?? null, isWritable: false }, + tokenProgram: { value: input.tokenProgram ?? null, isWritable: false }, + associatedTokenProgram: { + value: input.associatedTokenProgram ?? null, + isWritable: false, + }, + rent: { value: input.rent ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record< + keyof typeof originalAccounts, + ResolvedAccount + >; + + // Original args. + const args = { ...input }; + + // Resolve default values. + if (!accounts.systemProgram.value) { + accounts.systemProgram.value = + "11111111111111111111111111111111" as Address<"11111111111111111111111111111111">; + } + if (!accounts.tokenProgram.value) { + accounts.tokenProgram.value = + "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" as Address<"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA">; + } + if (!accounts.associatedTokenProgram.value) { + accounts.associatedTokenProgram.value = + "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" as Address<"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL">; + } + if (!accounts.rent.value) { + accounts.rent.value = + "SysvarRent111111111111111111111111111111111" as Address<"SysvarRent111111111111111111111111111111111">; + } + + const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.registrar), + getAccountMeta(accounts.voter), + getAccountMeta(accounts.vault), + getAccountMeta(accounts.voterAuthority), + getAccountMeta(accounts.payer), + getAccountMeta(accounts.depositMint), + getAccountMeta(accounts.systemProgram), + getAccountMeta(accounts.tokenProgram), + getAccountMeta(accounts.associatedTokenProgram), + getAccountMeta(accounts.rent), + ], + data: getCreateDepositEntryInstructionDataEncoder().encode( + args as CreateDepositEntryInstructionDataArgs, + ), + programAddress, + } as CreateDepositEntryInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountVoter, + TAccountVault, + TAccountVoterAuthority, + TAccountPayer, + TAccountDepositMint, + TAccountSystemProgram, + TAccountTokenProgram, + TAccountAssociatedTokenProgram, + TAccountRent + >); +} + +export interface ParsedCreateDepositEntryInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> { + programAddress: Address; + accounts: { + registrar: TAccountMetas[0]; + voter: TAccountMetas[1]; + vault: TAccountMetas[2]; + voterAuthority: TAccountMetas[3]; + payer: TAccountMetas[4]; + depositMint: TAccountMetas[5]; + systemProgram: TAccountMetas[6]; + tokenProgram: TAccountMetas[7]; + associatedTokenProgram: TAccountMetas[8]; + rent: TAccountMetas[9]; + }; + data: CreateDepositEntryInstructionData; +} + +export function parseCreateDepositEntryInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedCreateDepositEntryInstruction { + if (instruction.accounts.length < 10) { + // TODO: Coded error. + throw new Error("Not enough accounts"); + } + let accountIndex = 0; + const getNextAccount = () => { + const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; + accountIndex += 1; + return accountMeta; + }; + return { + programAddress: instruction.programAddress, + accounts: { + registrar: getNextAccount(), + voter: getNextAccount(), + vault: getNextAccount(), + voterAuthority: getNextAccount(), + payer: getNextAccount(), + depositMint: getNextAccount(), + systemProgram: getNextAccount(), + tokenProgram: getNextAccount(), + associatedTokenProgram: getNextAccount(), + rent: getNextAccount(), + }, + data: getCreateDepositEntryInstructionDataDecoder().decode( + instruction.data, + ), + }; +} diff --git a/clients/voter-stake-registry/src/generated/instructions/createRegistrar.ts b/clients/voter-stake-registry/src/generated/instructions/createRegistrar.ts new file mode 100644 index 00000000..ba5fc184 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/instructions/createRegistrar.ts @@ -0,0 +1,308 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + AccountMeta, + AccountSignerMeta, + Address, + FixedSizeCodec, + FixedSizeDecoder, + FixedSizeEncoder, + Instruction, + InstructionWithAccounts, + InstructionWithData, + ReadonlyAccount, + ReadonlySignerAccount, + ReadonlyUint8Array, + TransactionSigner, + WritableAccount, + WritableSignerAccount, +} from "@solana/kit"; +import type { ResolvedAccount } from "../shared/index.js"; +import { + combineCodec, + fixDecoderSize, + fixEncoderSize, + getBytesDecoder, + getBytesEncoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + transformEncoder, +} from "@solana/kit"; +import { VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS } from "../programs/index.js"; +import { getAccountMetaFactory } from "../shared/index.js"; + +export const CREATE_REGISTRAR_DISCRIMINATOR: ReadonlyUint8Array = + new Uint8Array([132, 235, 36, 49, 139, 66, 202, 69]); + +export function getCreateRegistrarDiscriminatorBytes(): ReadonlyUint8Array { + return fixEncoderSize(getBytesEncoder(), 8).encode( + CREATE_REGISTRAR_DISCRIMINATOR, + ); +} + +export type CreateRegistrarInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountRegistrar extends string | AccountMeta = string, + TAccountRealm extends string | AccountMeta = string, + TAccountGovernanceProgramId extends string | AccountMeta = string, + TAccountRealmGoverningTokenMint extends string | AccountMeta = string, + TAccountRealmAuthority extends string | AccountMeta = string, + TAccountPayer extends string | AccountMeta = string, + TAccountSystemProgram extends + | string + | AccountMeta = "11111111111111111111111111111111", + TAccountRent extends + | string + | AccountMeta = "SysvarRent111111111111111111111111111111111", + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountRegistrar extends string + ? WritableAccount + : TAccountRegistrar, + TAccountRealm extends string + ? ReadonlyAccount + : TAccountRealm, + TAccountGovernanceProgramId extends string + ? ReadonlyAccount + : TAccountGovernanceProgramId, + TAccountRealmGoverningTokenMint extends string + ? ReadonlyAccount + : TAccountRealmGoverningTokenMint, + TAccountRealmAuthority extends string + ? ReadonlySignerAccount & + AccountSignerMeta + : TAccountRealmAuthority, + TAccountPayer extends string + ? WritableSignerAccount & + AccountSignerMeta + : TAccountPayer, + TAccountSystemProgram extends string + ? ReadonlyAccount + : TAccountSystemProgram, + TAccountRent extends string + ? ReadonlyAccount + : TAccountRent, + ...TRemainingAccounts, + ] + >; + +export interface CreateRegistrarInstructionData { + discriminator: ReadonlyUint8Array; + registrarBump: number; +} + +export interface CreateRegistrarInstructionDataArgs { + registrarBump: number; +} + +export function getCreateRegistrarInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([ + ["discriminator", fixEncoderSize(getBytesEncoder(), 8)], + ["registrarBump", getU8Encoder()], + ]), + (value) => ({ ...value, discriminator: CREATE_REGISTRAR_DISCRIMINATOR }), + ); +} + +export function getCreateRegistrarInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ["discriminator", fixDecoderSize(getBytesDecoder(), 8)], + ["registrarBump", getU8Decoder()], + ]); +} + +export function getCreateRegistrarInstructionDataCodec(): FixedSizeCodec< + CreateRegistrarInstructionDataArgs, + CreateRegistrarInstructionData +> { + return combineCodec( + getCreateRegistrarInstructionDataEncoder(), + getCreateRegistrarInstructionDataDecoder(), + ); +} + +export interface CreateRegistrarInput< + TAccountRegistrar extends string = string, + TAccountRealm extends string = string, + TAccountGovernanceProgramId extends string = string, + TAccountRealmGoverningTokenMint extends string = string, + TAccountRealmAuthority extends string = string, + TAccountPayer extends string = string, + TAccountSystemProgram extends string = string, + TAccountRent extends string = string, +> { + registrar: Address; + realm: Address; + governanceProgramId: Address; + realmGoverningTokenMint: Address; + realmAuthority: TransactionSigner; + payer: TransactionSigner; + systemProgram?: Address; + rent?: Address; + registrarBump: CreateRegistrarInstructionDataArgs["registrarBump"]; +} + +export function getCreateRegistrarInstruction< + TAccountRegistrar extends string, + TAccountRealm extends string, + TAccountGovernanceProgramId extends string, + TAccountRealmGoverningTokenMint extends string, + TAccountRealmAuthority extends string, + TAccountPayer extends string, + TAccountSystemProgram extends string, + TAccountRent extends string, + TProgramAddress extends Address = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, +>( + input: CreateRegistrarInput< + TAccountRegistrar, + TAccountRealm, + TAccountGovernanceProgramId, + TAccountRealmGoverningTokenMint, + TAccountRealmAuthority, + TAccountPayer, + TAccountSystemProgram, + TAccountRent + >, + config?: { programAddress?: TProgramAddress }, +): CreateRegistrarInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountRealm, + TAccountGovernanceProgramId, + TAccountRealmGoverningTokenMint, + TAccountRealmAuthority, + TAccountPayer, + TAccountSystemProgram, + TAccountRent +> { + // Program address. + const programAddress = + config?.programAddress ?? VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + registrar: { value: input.registrar ?? null, isWritable: true }, + realm: { value: input.realm ?? null, isWritable: false }, + governanceProgramId: { + value: input.governanceProgramId ?? null, + isWritable: false, + }, + realmGoverningTokenMint: { + value: input.realmGoverningTokenMint ?? null, + isWritable: false, + }, + realmAuthority: { value: input.realmAuthority ?? null, isWritable: false }, + payer: { value: input.payer ?? null, isWritable: true }, + systemProgram: { value: input.systemProgram ?? null, isWritable: false }, + rent: { value: input.rent ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record< + keyof typeof originalAccounts, + ResolvedAccount + >; + + // Original args. + const args = { ...input }; + + // Resolve default values. + if (!accounts.systemProgram.value) { + accounts.systemProgram.value = + "11111111111111111111111111111111" as Address<"11111111111111111111111111111111">; + } + if (!accounts.rent.value) { + accounts.rent.value = + "SysvarRent111111111111111111111111111111111" as Address<"SysvarRent111111111111111111111111111111111">; + } + + const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.registrar), + getAccountMeta(accounts.realm), + getAccountMeta(accounts.governanceProgramId), + getAccountMeta(accounts.realmGoverningTokenMint), + getAccountMeta(accounts.realmAuthority), + getAccountMeta(accounts.payer), + getAccountMeta(accounts.systemProgram), + getAccountMeta(accounts.rent), + ], + data: getCreateRegistrarInstructionDataEncoder().encode( + args as CreateRegistrarInstructionDataArgs, + ), + programAddress, + } as CreateRegistrarInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountRealm, + TAccountGovernanceProgramId, + TAccountRealmGoverningTokenMint, + TAccountRealmAuthority, + TAccountPayer, + TAccountSystemProgram, + TAccountRent + >); +} + +export interface ParsedCreateRegistrarInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> { + programAddress: Address; + accounts: { + registrar: TAccountMetas[0]; + realm: TAccountMetas[1]; + governanceProgramId: TAccountMetas[2]; + realmGoverningTokenMint: TAccountMetas[3]; + realmAuthority: TAccountMetas[4]; + payer: TAccountMetas[5]; + systemProgram: TAccountMetas[6]; + rent: TAccountMetas[7]; + }; + data: CreateRegistrarInstructionData; +} + +export function parseCreateRegistrarInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedCreateRegistrarInstruction { + if (instruction.accounts.length < 8) { + // TODO: Coded error. + throw new Error("Not enough accounts"); + } + let accountIndex = 0; + const getNextAccount = () => { + const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; + accountIndex += 1; + return accountMeta; + }; + return { + programAddress: instruction.programAddress, + accounts: { + registrar: getNextAccount(), + realm: getNextAccount(), + governanceProgramId: getNextAccount(), + realmGoverningTokenMint: getNextAccount(), + realmAuthority: getNextAccount(), + payer: getNextAccount(), + systemProgram: getNextAccount(), + rent: getNextAccount(), + }, + data: getCreateRegistrarInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/clients/voter-stake-registry/src/generated/instructions/createVoter.ts b/clients/voter-stake-registry/src/generated/instructions/createVoter.ts new file mode 100644 index 00000000..b7b73728 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/instructions/createVoter.ts @@ -0,0 +1,456 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + AccountMeta, + AccountSignerMeta, + Address, + FixedSizeCodec, + FixedSizeDecoder, + FixedSizeEncoder, + Instruction, + InstructionWithAccounts, + InstructionWithData, + ReadonlyAccount, + ReadonlySignerAccount, + ReadonlyUint8Array, + TransactionSigner, + WritableAccount, + WritableSignerAccount, +} from "@solana/kit"; +import type { ResolvedAccount } from "../shared/index.js"; +import { + combineCodec, + fixDecoderSize, + fixEncoderSize, + getBytesDecoder, + getBytesEncoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + transformEncoder, +} from "@solana/kit"; +import { findVoterPda, findVoterWeightRecordPda } from "../pdas/index.js"; +import { VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS } from "../programs/index.js"; +import { expectAddress, getAccountMetaFactory } from "../shared/index.js"; + +export const CREATE_VOTER_DISCRIMINATOR: ReadonlyUint8Array = new Uint8Array([ + 6, 24, 245, 52, 243, 255, 148, 25, +]); + +export function getCreateVoterDiscriminatorBytes(): ReadonlyUint8Array { + return fixEncoderSize(getBytesEncoder(), 8).encode( + CREATE_VOTER_DISCRIMINATOR, + ); +} + +export type CreateVoterInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountRegistrar extends string | AccountMeta = string, + TAccountVoter extends string | AccountMeta = string, + TAccountVoterAuthority extends string | AccountMeta = string, + TAccountVoterWeightRecord extends string | AccountMeta = string, + TAccountPayer extends string | AccountMeta = string, + TAccountSystemProgram extends + | string + | AccountMeta = "11111111111111111111111111111111", + TAccountRent extends + | string + | AccountMeta = "SysvarRent111111111111111111111111111111111", + TAccountInstructions extends + | string + | AccountMeta = "Sysvar1nstructions1111111111111111111111111", + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountRegistrar extends string + ? ReadonlyAccount + : TAccountRegistrar, + TAccountVoter extends string + ? WritableAccount + : TAccountVoter, + TAccountVoterAuthority extends string + ? ReadonlySignerAccount & + AccountSignerMeta + : TAccountVoterAuthority, + TAccountVoterWeightRecord extends string + ? WritableAccount + : TAccountVoterWeightRecord, + TAccountPayer extends string + ? WritableSignerAccount & + AccountSignerMeta + : TAccountPayer, + TAccountSystemProgram extends string + ? ReadonlyAccount + : TAccountSystemProgram, + TAccountRent extends string + ? ReadonlyAccount + : TAccountRent, + TAccountInstructions extends string + ? ReadonlyAccount + : TAccountInstructions, + ...TRemainingAccounts, + ] + >; + +export interface CreateVoterInstructionData { + discriminator: ReadonlyUint8Array; + voterBump: number; + voterWeightRecordBump: number; +} + +export interface CreateVoterInstructionDataArgs { + voterBump: number; + voterWeightRecordBump: number; +} + +export function getCreateVoterInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([ + ["discriminator", fixEncoderSize(getBytesEncoder(), 8)], + ["voterBump", getU8Encoder()], + ["voterWeightRecordBump", getU8Encoder()], + ]), + (value) => ({ ...value, discriminator: CREATE_VOTER_DISCRIMINATOR }), + ); +} + +export function getCreateVoterInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ["discriminator", fixDecoderSize(getBytesDecoder(), 8)], + ["voterBump", getU8Decoder()], + ["voterWeightRecordBump", getU8Decoder()], + ]); +} + +export function getCreateVoterInstructionDataCodec(): FixedSizeCodec< + CreateVoterInstructionDataArgs, + CreateVoterInstructionData +> { + return combineCodec( + getCreateVoterInstructionDataEncoder(), + getCreateVoterInstructionDataDecoder(), + ); +} + +export interface CreateVoterAsyncInput< + TAccountRegistrar extends string = string, + TAccountVoter extends string = string, + TAccountVoterAuthority extends string = string, + TAccountVoterWeightRecord extends string = string, + TAccountPayer extends string = string, + TAccountSystemProgram extends string = string, + TAccountRent extends string = string, + TAccountInstructions extends string = string, +> { + registrar: Address; + voter?: Address; + voterAuthority: TransactionSigner; + voterWeightRecord?: Address; + payer: TransactionSigner; + systemProgram?: Address; + rent?: Address; + instructions?: Address; + voterBump: CreateVoterInstructionDataArgs["voterBump"]; + voterWeightRecordBump: CreateVoterInstructionDataArgs["voterWeightRecordBump"]; +} + +export async function getCreateVoterInstructionAsync< + TAccountRegistrar extends string, + TAccountVoter extends string, + TAccountVoterAuthority extends string, + TAccountVoterWeightRecord extends string, + TAccountPayer extends string, + TAccountSystemProgram extends string, + TAccountRent extends string, + TAccountInstructions extends string, + TProgramAddress extends Address = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, +>( + input: CreateVoterAsyncInput< + TAccountRegistrar, + TAccountVoter, + TAccountVoterAuthority, + TAccountVoterWeightRecord, + TAccountPayer, + TAccountSystemProgram, + TAccountRent, + TAccountInstructions + >, + config?: { programAddress?: TProgramAddress }, +): Promise< + CreateVoterInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountVoter, + TAccountVoterAuthority, + TAccountVoterWeightRecord, + TAccountPayer, + TAccountSystemProgram, + TAccountRent, + TAccountInstructions + > +> { + // Program address. + const programAddress = + config?.programAddress ?? VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + registrar: { value: input.registrar ?? null, isWritable: false }, + voter: { value: input.voter ?? null, isWritable: true }, + voterAuthority: { value: input.voterAuthority ?? null, isWritable: false }, + voterWeightRecord: { + value: input.voterWeightRecord ?? null, + isWritable: true, + }, + payer: { value: input.payer ?? null, isWritable: true }, + systemProgram: { value: input.systemProgram ?? null, isWritable: false }, + rent: { value: input.rent ?? null, isWritable: false }, + instructions: { value: input.instructions ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record< + keyof typeof originalAccounts, + ResolvedAccount + >; + + // Original args. + const args = { ...input }; + + // Resolve default values. + if (!accounts.voter.value) { + accounts.voter.value = await findVoterPda({ + registrar: expectAddress(accounts.registrar.value), + voterAuthority: expectAddress(accounts.voterAuthority.value), + }); + } + if (!accounts.voterWeightRecord.value) { + accounts.voterWeightRecord.value = await findVoterWeightRecordPda({ + registrar: expectAddress(accounts.registrar.value), + voterAuthority: expectAddress(accounts.voterAuthority.value), + }); + } + if (!accounts.systemProgram.value) { + accounts.systemProgram.value = + "11111111111111111111111111111111" as Address<"11111111111111111111111111111111">; + } + if (!accounts.rent.value) { + accounts.rent.value = + "SysvarRent111111111111111111111111111111111" as Address<"SysvarRent111111111111111111111111111111111">; + } + if (!accounts.instructions.value) { + accounts.instructions.value = + "Sysvar1nstructions1111111111111111111111111" as Address<"Sysvar1nstructions1111111111111111111111111">; + } + + const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.registrar), + getAccountMeta(accounts.voter), + getAccountMeta(accounts.voterAuthority), + getAccountMeta(accounts.voterWeightRecord), + getAccountMeta(accounts.payer), + getAccountMeta(accounts.systemProgram), + getAccountMeta(accounts.rent), + getAccountMeta(accounts.instructions), + ], + data: getCreateVoterInstructionDataEncoder().encode( + args as CreateVoterInstructionDataArgs, + ), + programAddress, + } as CreateVoterInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountVoter, + TAccountVoterAuthority, + TAccountVoterWeightRecord, + TAccountPayer, + TAccountSystemProgram, + TAccountRent, + TAccountInstructions + >); +} + +export interface CreateVoterInput< + TAccountRegistrar extends string = string, + TAccountVoter extends string = string, + TAccountVoterAuthority extends string = string, + TAccountVoterWeightRecord extends string = string, + TAccountPayer extends string = string, + TAccountSystemProgram extends string = string, + TAccountRent extends string = string, + TAccountInstructions extends string = string, +> { + registrar: Address; + voter: Address; + voterAuthority: TransactionSigner; + voterWeightRecord: Address; + payer: TransactionSigner; + systemProgram?: Address; + rent?: Address; + instructions?: Address; + voterBump: CreateVoterInstructionDataArgs["voterBump"]; + voterWeightRecordBump: CreateVoterInstructionDataArgs["voterWeightRecordBump"]; +} + +export function getCreateVoterInstruction< + TAccountRegistrar extends string, + TAccountVoter extends string, + TAccountVoterAuthority extends string, + TAccountVoterWeightRecord extends string, + TAccountPayer extends string, + TAccountSystemProgram extends string, + TAccountRent extends string, + TAccountInstructions extends string, + TProgramAddress extends Address = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, +>( + input: CreateVoterInput< + TAccountRegistrar, + TAccountVoter, + TAccountVoterAuthority, + TAccountVoterWeightRecord, + TAccountPayer, + TAccountSystemProgram, + TAccountRent, + TAccountInstructions + >, + config?: { programAddress?: TProgramAddress }, +): CreateVoterInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountVoter, + TAccountVoterAuthority, + TAccountVoterWeightRecord, + TAccountPayer, + TAccountSystemProgram, + TAccountRent, + TAccountInstructions +> { + // Program address. + const programAddress = + config?.programAddress ?? VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + registrar: { value: input.registrar ?? null, isWritable: false }, + voter: { value: input.voter ?? null, isWritable: true }, + voterAuthority: { value: input.voterAuthority ?? null, isWritable: false }, + voterWeightRecord: { + value: input.voterWeightRecord ?? null, + isWritable: true, + }, + payer: { value: input.payer ?? null, isWritable: true }, + systemProgram: { value: input.systemProgram ?? null, isWritable: false }, + rent: { value: input.rent ?? null, isWritable: false }, + instructions: { value: input.instructions ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record< + keyof typeof originalAccounts, + ResolvedAccount + >; + + // Original args. + const args = { ...input }; + + // Resolve default values. + if (!accounts.systemProgram.value) { + accounts.systemProgram.value = + "11111111111111111111111111111111" as Address<"11111111111111111111111111111111">; + } + if (!accounts.rent.value) { + accounts.rent.value = + "SysvarRent111111111111111111111111111111111" as Address<"SysvarRent111111111111111111111111111111111">; + } + if (!accounts.instructions.value) { + accounts.instructions.value = + "Sysvar1nstructions1111111111111111111111111" as Address<"Sysvar1nstructions1111111111111111111111111">; + } + + const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.registrar), + getAccountMeta(accounts.voter), + getAccountMeta(accounts.voterAuthority), + getAccountMeta(accounts.voterWeightRecord), + getAccountMeta(accounts.payer), + getAccountMeta(accounts.systemProgram), + getAccountMeta(accounts.rent), + getAccountMeta(accounts.instructions), + ], + data: getCreateVoterInstructionDataEncoder().encode( + args as CreateVoterInstructionDataArgs, + ), + programAddress, + } as CreateVoterInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountVoter, + TAccountVoterAuthority, + TAccountVoterWeightRecord, + TAccountPayer, + TAccountSystemProgram, + TAccountRent, + TAccountInstructions + >); +} + +export interface ParsedCreateVoterInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> { + programAddress: Address; + accounts: { + registrar: TAccountMetas[0]; + voter: TAccountMetas[1]; + voterAuthority: TAccountMetas[2]; + voterWeightRecord: TAccountMetas[3]; + payer: TAccountMetas[4]; + systemProgram: TAccountMetas[5]; + rent: TAccountMetas[6]; + instructions: TAccountMetas[7]; + }; + data: CreateVoterInstructionData; +} + +export function parseCreateVoterInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedCreateVoterInstruction { + if (instruction.accounts.length < 8) { + // TODO: Coded error. + throw new Error("Not enough accounts"); + } + let accountIndex = 0; + const getNextAccount = () => { + const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; + accountIndex += 1; + return accountMeta; + }; + return { + programAddress: instruction.programAddress, + accounts: { + registrar: getNextAccount(), + voter: getNextAccount(), + voterAuthority: getNextAccount(), + voterWeightRecord: getNextAccount(), + payer: getNextAccount(), + systemProgram: getNextAccount(), + rent: getNextAccount(), + instructions: getNextAccount(), + }, + data: getCreateVoterInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/clients/voter-stake-registry/src/generated/instructions/deposit.ts b/clients/voter-stake-registry/src/generated/instructions/deposit.ts new file mode 100644 index 00000000..1bc9fcd4 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/instructions/deposit.ts @@ -0,0 +1,275 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + AccountMeta, + AccountSignerMeta, + Address, + FixedSizeCodec, + FixedSizeDecoder, + FixedSizeEncoder, + Instruction, + InstructionWithAccounts, + InstructionWithData, + ReadonlyAccount, + ReadonlySignerAccount, + ReadonlyUint8Array, + TransactionSigner, + WritableAccount, +} from "@solana/kit"; +import type { ResolvedAccount } from "../shared/index.js"; +import { + combineCodec, + fixDecoderSize, + fixEncoderSize, + getBytesDecoder, + getBytesEncoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + getU64Decoder, + getU64Encoder, + transformEncoder, +} from "@solana/kit"; +import { VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS } from "../programs/index.js"; +import { getAccountMetaFactory } from "../shared/index.js"; + +export const DEPOSIT_DISCRIMINATOR: ReadonlyUint8Array = new Uint8Array([ + 242, 35, 198, 137, 82, 225, 242, 182, +]); + +export function getDepositDiscriminatorBytes(): ReadonlyUint8Array { + return fixEncoderSize(getBytesEncoder(), 8).encode(DEPOSIT_DISCRIMINATOR); +} + +export type DepositInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountRegistrar extends string | AccountMeta = string, + TAccountVoter extends string | AccountMeta = string, + TAccountVault extends string | AccountMeta = string, + TAccountDepositToken extends string | AccountMeta = string, + TAccountDepositAuthority extends string | AccountMeta = string, + TAccountTokenProgram extends + | string + | AccountMeta = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountRegistrar extends string + ? ReadonlyAccount + : TAccountRegistrar, + TAccountVoter extends string + ? WritableAccount + : TAccountVoter, + TAccountVault extends string + ? WritableAccount + : TAccountVault, + TAccountDepositToken extends string + ? WritableAccount + : TAccountDepositToken, + TAccountDepositAuthority extends string + ? ReadonlySignerAccount & + AccountSignerMeta + : TAccountDepositAuthority, + TAccountTokenProgram extends string + ? ReadonlyAccount + : TAccountTokenProgram, + ...TRemainingAccounts, + ] + >; + +export interface DepositInstructionData { + discriminator: ReadonlyUint8Array; + depositEntryIndex: number; + amount: bigint; +} + +export interface DepositInstructionDataArgs { + depositEntryIndex: number; + amount: number | bigint; +} + +export function getDepositInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([ + ["discriminator", fixEncoderSize(getBytesEncoder(), 8)], + ["depositEntryIndex", getU8Encoder()], + ["amount", getU64Encoder()], + ]), + (value) => ({ ...value, discriminator: DEPOSIT_DISCRIMINATOR }), + ); +} + +export function getDepositInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ["discriminator", fixDecoderSize(getBytesDecoder(), 8)], + ["depositEntryIndex", getU8Decoder()], + ["amount", getU64Decoder()], + ]); +} + +export function getDepositInstructionDataCodec(): FixedSizeCodec< + DepositInstructionDataArgs, + DepositInstructionData +> { + return combineCodec( + getDepositInstructionDataEncoder(), + getDepositInstructionDataDecoder(), + ); +} + +export interface DepositInput< + TAccountRegistrar extends string = string, + TAccountVoter extends string = string, + TAccountVault extends string = string, + TAccountDepositToken extends string = string, + TAccountDepositAuthority extends string = string, + TAccountTokenProgram extends string = string, +> { + registrar: Address; + voter: Address; + vault: Address; + depositToken: Address; + depositAuthority: TransactionSigner; + tokenProgram?: Address; + depositEntryIndex: DepositInstructionDataArgs["depositEntryIndex"]; + amount: DepositInstructionDataArgs["amount"]; +} + +export function getDepositInstruction< + TAccountRegistrar extends string, + TAccountVoter extends string, + TAccountVault extends string, + TAccountDepositToken extends string, + TAccountDepositAuthority extends string, + TAccountTokenProgram extends string, + TProgramAddress extends Address = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, +>( + input: DepositInput< + TAccountRegistrar, + TAccountVoter, + TAccountVault, + TAccountDepositToken, + TAccountDepositAuthority, + TAccountTokenProgram + >, + config?: { programAddress?: TProgramAddress }, +): DepositInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountVoter, + TAccountVault, + TAccountDepositToken, + TAccountDepositAuthority, + TAccountTokenProgram +> { + // Program address. + const programAddress = + config?.programAddress ?? VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + registrar: { value: input.registrar ?? null, isWritable: false }, + voter: { value: input.voter ?? null, isWritable: true }, + vault: { value: input.vault ?? null, isWritable: true }, + depositToken: { value: input.depositToken ?? null, isWritable: true }, + depositAuthority: { + value: input.depositAuthority ?? null, + isWritable: false, + }, + tokenProgram: { value: input.tokenProgram ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record< + keyof typeof originalAccounts, + ResolvedAccount + >; + + // Original args. + const args = { ...input }; + + // Resolve default values. + if (!accounts.tokenProgram.value) { + accounts.tokenProgram.value = + "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" as Address<"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA">; + } + + const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.registrar), + getAccountMeta(accounts.voter), + getAccountMeta(accounts.vault), + getAccountMeta(accounts.depositToken), + getAccountMeta(accounts.depositAuthority), + getAccountMeta(accounts.tokenProgram), + ], + data: getDepositInstructionDataEncoder().encode( + args as DepositInstructionDataArgs, + ), + programAddress, + } as DepositInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountVoter, + TAccountVault, + TAccountDepositToken, + TAccountDepositAuthority, + TAccountTokenProgram + >); +} + +export interface ParsedDepositInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> { + programAddress: Address; + accounts: { + registrar: TAccountMetas[0]; + voter: TAccountMetas[1]; + vault: TAccountMetas[2]; + depositToken: TAccountMetas[3]; + depositAuthority: TAccountMetas[4]; + tokenProgram: TAccountMetas[5]; + }; + data: DepositInstructionData; +} + +export function parseDepositInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedDepositInstruction { + if (instruction.accounts.length < 6) { + // TODO: Coded error. + throw new Error("Not enough accounts"); + } + let accountIndex = 0; + const getNextAccount = () => { + const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; + accountIndex += 1; + return accountMeta; + }; + return { + programAddress: instruction.programAddress, + accounts: { + registrar: getNextAccount(), + voter: getNextAccount(), + vault: getNextAccount(), + depositToken: getNextAccount(), + depositAuthority: getNextAccount(), + tokenProgram: getNextAccount(), + }, + data: getDepositInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/clients/voter-stake-registry/src/generated/instructions/grant.ts b/clients/voter-stake-registry/src/generated/instructions/grant.ts new file mode 100644 index 00000000..7a07d58c --- /dev/null +++ b/clients/voter-stake-registry/src/generated/instructions/grant.ts @@ -0,0 +1,431 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + AccountMeta, + AccountSignerMeta, + Address, + Codec, + Decoder, + Encoder, + Instruction, + InstructionWithAccounts, + InstructionWithData, + Option, + OptionOrNullable, + ReadonlyAccount, + ReadonlySignerAccount, + ReadonlyUint8Array, + TransactionSigner, + WritableAccount, + WritableSignerAccount, +} from "@solana/kit"; +import type { ResolvedAccount } from "../shared/index.js"; +import type { LockupKind, LockupKindArgs } from "../types/index.js"; +import { + combineCodec, + fixDecoderSize, + fixEncoderSize, + getBooleanDecoder, + getBooleanEncoder, + getBytesDecoder, + getBytesEncoder, + getOptionDecoder, + getOptionEncoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + getU32Decoder, + getU32Encoder, + getU64Decoder, + getU64Encoder, + transformEncoder, +} from "@solana/kit"; +import { VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS } from "../programs/index.js"; +import { getAccountMetaFactory } from "../shared/index.js"; +import { getLockupKindDecoder, getLockupKindEncoder } from "../types/index.js"; + +export const GRANT_DISCRIMINATOR: ReadonlyUint8Array = new Uint8Array([ + 145, 189, 68, 153, 161, 231, 76, 107, +]); + +export function getGrantDiscriminatorBytes(): ReadonlyUint8Array { + return fixEncoderSize(getBytesEncoder(), 8).encode(GRANT_DISCRIMINATOR); +} + +export type GrantInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountRegistrar extends string | AccountMeta = string, + TAccountVoter extends string | AccountMeta = string, + TAccountVoterAuthority extends string | AccountMeta = string, + TAccountVoterWeightRecord extends string | AccountMeta = string, + TAccountVault extends string | AccountMeta = string, + TAccountDepositToken extends string | AccountMeta = string, + TAccountAuthority extends string | AccountMeta = string, + TAccountPayer extends string | AccountMeta = string, + TAccountDepositMint extends string | AccountMeta = string, + TAccountSystemProgram extends + | string + | AccountMeta = "11111111111111111111111111111111", + TAccountTokenProgram extends + | string + | AccountMeta = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", + TAccountAssociatedTokenProgram extends + | string + | AccountMeta = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", + TAccountRent extends + | string + | AccountMeta = "SysvarRent111111111111111111111111111111111", + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountRegistrar extends string + ? ReadonlyAccount + : TAccountRegistrar, + TAccountVoter extends string + ? WritableAccount + : TAccountVoter, + TAccountVoterAuthority extends string + ? ReadonlyAccount + : TAccountVoterAuthority, + TAccountVoterWeightRecord extends string + ? WritableAccount + : TAccountVoterWeightRecord, + TAccountVault extends string + ? WritableAccount + : TAccountVault, + TAccountDepositToken extends string + ? WritableAccount + : TAccountDepositToken, + TAccountAuthority extends string + ? ReadonlySignerAccount & + AccountSignerMeta + : TAccountAuthority, + TAccountPayer extends string + ? WritableSignerAccount & + AccountSignerMeta + : TAccountPayer, + TAccountDepositMint extends string + ? ReadonlyAccount + : TAccountDepositMint, + TAccountSystemProgram extends string + ? ReadonlyAccount + : TAccountSystemProgram, + TAccountTokenProgram extends string + ? ReadonlyAccount + : TAccountTokenProgram, + TAccountAssociatedTokenProgram extends string + ? ReadonlyAccount + : TAccountAssociatedTokenProgram, + TAccountRent extends string + ? ReadonlyAccount + : TAccountRent, + ...TRemainingAccounts, + ] + >; + +export interface GrantInstructionData { + discriminator: ReadonlyUint8Array; + voterBump: number; + voterWeightRecordBump: number; + kind: LockupKind; + startTs: Option; + periods: number; + allowClawback: boolean; + amount: bigint; +} + +export interface GrantInstructionDataArgs { + voterBump: number; + voterWeightRecordBump: number; + kind: LockupKindArgs; + startTs: OptionOrNullable; + periods: number; + allowClawback: boolean; + amount: number | bigint; +} + +export function getGrantInstructionDataEncoder(): Encoder { + return transformEncoder( + getStructEncoder([ + ["discriminator", fixEncoderSize(getBytesEncoder(), 8)], + ["voterBump", getU8Encoder()], + ["voterWeightRecordBump", getU8Encoder()], + ["kind", getLockupKindEncoder()], + ["startTs", getOptionEncoder(getU64Encoder())], + ["periods", getU32Encoder()], + ["allowClawback", getBooleanEncoder()], + ["amount", getU64Encoder()], + ]), + (value) => ({ ...value, discriminator: GRANT_DISCRIMINATOR }), + ); +} + +export function getGrantInstructionDataDecoder(): Decoder { + return getStructDecoder([ + ["discriminator", fixDecoderSize(getBytesDecoder(), 8)], + ["voterBump", getU8Decoder()], + ["voterWeightRecordBump", getU8Decoder()], + ["kind", getLockupKindDecoder()], + ["startTs", getOptionDecoder(getU64Decoder())], + ["periods", getU32Decoder()], + ["allowClawback", getBooleanDecoder()], + ["amount", getU64Decoder()], + ]); +} + +export function getGrantInstructionDataCodec(): Codec< + GrantInstructionDataArgs, + GrantInstructionData +> { + return combineCodec( + getGrantInstructionDataEncoder(), + getGrantInstructionDataDecoder(), + ); +} + +export interface GrantInput< + TAccountRegistrar extends string = string, + TAccountVoter extends string = string, + TAccountVoterAuthority extends string = string, + TAccountVoterWeightRecord extends string = string, + TAccountVault extends string = string, + TAccountDepositToken extends string = string, + TAccountAuthority extends string = string, + TAccountPayer extends string = string, + TAccountDepositMint extends string = string, + TAccountSystemProgram extends string = string, + TAccountTokenProgram extends string = string, + TAccountAssociatedTokenProgram extends string = string, + TAccountRent extends string = string, +> { + registrar: Address; + voter: Address; + voterAuthority: Address; + voterWeightRecord: Address; + vault: Address; + depositToken: Address; + authority: TransactionSigner; + payer: TransactionSigner; + depositMint: Address; + systemProgram?: Address; + tokenProgram?: Address; + associatedTokenProgram?: Address; + rent?: Address; + voterBump: GrantInstructionDataArgs["voterBump"]; + voterWeightRecordBump: GrantInstructionDataArgs["voterWeightRecordBump"]; + kind: GrantInstructionDataArgs["kind"]; + startTs: GrantInstructionDataArgs["startTs"]; + periods: GrantInstructionDataArgs["periods"]; + allowClawback: GrantInstructionDataArgs["allowClawback"]; + amount: GrantInstructionDataArgs["amount"]; +} + +export function getGrantInstruction< + TAccountRegistrar extends string, + TAccountVoter extends string, + TAccountVoterAuthority extends string, + TAccountVoterWeightRecord extends string, + TAccountVault extends string, + TAccountDepositToken extends string, + TAccountAuthority extends string, + TAccountPayer extends string, + TAccountDepositMint extends string, + TAccountSystemProgram extends string, + TAccountTokenProgram extends string, + TAccountAssociatedTokenProgram extends string, + TAccountRent extends string, + TProgramAddress extends Address = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, +>( + input: GrantInput< + TAccountRegistrar, + TAccountVoter, + TAccountVoterAuthority, + TAccountVoterWeightRecord, + TAccountVault, + TAccountDepositToken, + TAccountAuthority, + TAccountPayer, + TAccountDepositMint, + TAccountSystemProgram, + TAccountTokenProgram, + TAccountAssociatedTokenProgram, + TAccountRent + >, + config?: { programAddress?: TProgramAddress }, +): GrantInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountVoter, + TAccountVoterAuthority, + TAccountVoterWeightRecord, + TAccountVault, + TAccountDepositToken, + TAccountAuthority, + TAccountPayer, + TAccountDepositMint, + TAccountSystemProgram, + TAccountTokenProgram, + TAccountAssociatedTokenProgram, + TAccountRent +> { + // Program address. + const programAddress = + config?.programAddress ?? VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + registrar: { value: input.registrar ?? null, isWritable: false }, + voter: { value: input.voter ?? null, isWritable: true }, + voterAuthority: { value: input.voterAuthority ?? null, isWritable: false }, + voterWeightRecord: { + value: input.voterWeightRecord ?? null, + isWritable: true, + }, + vault: { value: input.vault ?? null, isWritable: true }, + depositToken: { value: input.depositToken ?? null, isWritable: true }, + authority: { value: input.authority ?? null, isWritable: false }, + payer: { value: input.payer ?? null, isWritable: true }, + depositMint: { value: input.depositMint ?? null, isWritable: false }, + systemProgram: { value: input.systemProgram ?? null, isWritable: false }, + tokenProgram: { value: input.tokenProgram ?? null, isWritable: false }, + associatedTokenProgram: { + value: input.associatedTokenProgram ?? null, + isWritable: false, + }, + rent: { value: input.rent ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record< + keyof typeof originalAccounts, + ResolvedAccount + >; + + // Original args. + const args = { ...input }; + + // Resolve default values. + if (!accounts.systemProgram.value) { + accounts.systemProgram.value = + "11111111111111111111111111111111" as Address<"11111111111111111111111111111111">; + } + if (!accounts.tokenProgram.value) { + accounts.tokenProgram.value = + "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" as Address<"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA">; + } + if (!accounts.associatedTokenProgram.value) { + accounts.associatedTokenProgram.value = + "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" as Address<"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL">; + } + if (!accounts.rent.value) { + accounts.rent.value = + "SysvarRent111111111111111111111111111111111" as Address<"SysvarRent111111111111111111111111111111111">; + } + + const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.registrar), + getAccountMeta(accounts.voter), + getAccountMeta(accounts.voterAuthority), + getAccountMeta(accounts.voterWeightRecord), + getAccountMeta(accounts.vault), + getAccountMeta(accounts.depositToken), + getAccountMeta(accounts.authority), + getAccountMeta(accounts.payer), + getAccountMeta(accounts.depositMint), + getAccountMeta(accounts.systemProgram), + getAccountMeta(accounts.tokenProgram), + getAccountMeta(accounts.associatedTokenProgram), + getAccountMeta(accounts.rent), + ], + data: getGrantInstructionDataEncoder().encode( + args as GrantInstructionDataArgs, + ), + programAddress, + } as GrantInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountVoter, + TAccountVoterAuthority, + TAccountVoterWeightRecord, + TAccountVault, + TAccountDepositToken, + TAccountAuthority, + TAccountPayer, + TAccountDepositMint, + TAccountSystemProgram, + TAccountTokenProgram, + TAccountAssociatedTokenProgram, + TAccountRent + >); +} + +export interface ParsedGrantInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> { + programAddress: Address; + accounts: { + registrar: TAccountMetas[0]; + voter: TAccountMetas[1]; + voterAuthority: TAccountMetas[2]; + voterWeightRecord: TAccountMetas[3]; + vault: TAccountMetas[4]; + depositToken: TAccountMetas[5]; + authority: TAccountMetas[6]; + payer: TAccountMetas[7]; + depositMint: TAccountMetas[8]; + systemProgram: TAccountMetas[9]; + tokenProgram: TAccountMetas[10]; + associatedTokenProgram: TAccountMetas[11]; + rent: TAccountMetas[12]; + }; + data: GrantInstructionData; +} + +export function parseGrantInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedGrantInstruction { + if (instruction.accounts.length < 13) { + // TODO: Coded error. + throw new Error("Not enough accounts"); + } + let accountIndex = 0; + const getNextAccount = () => { + const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; + accountIndex += 1; + return accountMeta; + }; + return { + programAddress: instruction.programAddress, + accounts: { + registrar: getNextAccount(), + voter: getNextAccount(), + voterAuthority: getNextAccount(), + voterWeightRecord: getNextAccount(), + vault: getNextAccount(), + depositToken: getNextAccount(), + authority: getNextAccount(), + payer: getNextAccount(), + depositMint: getNextAccount(), + systemProgram: getNextAccount(), + tokenProgram: getNextAccount(), + associatedTokenProgram: getNextAccount(), + rent: getNextAccount(), + }, + data: getGrantInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/clients/voter-stake-registry/src/generated/instructions/index.ts b/clients/voter-stake-registry/src/generated/instructions/index.ts new file mode 100644 index 00000000..f87b99af --- /dev/null +++ b/clients/voter-stake-registry/src/generated/instructions/index.ts @@ -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. + * + * @see https://github.com/codama-idl/codama + */ + +export * from "./clawback.js"; +export * from "./closeDepositEntry.js"; +export * from "./closeVoter.js"; +export * from "./configureVotingMint.js"; +export * from "./createDepositEntry.js"; +export * from "./createRegistrar.js"; +export * from "./createVoter.js"; +export * from "./deposit.js"; +export * from "./grant.js"; +export * from "./internalTransfer.js"; +export * from "./resetLockup.js"; +export * from "./setTimeOffset.js"; +export * from "./updateMaxVoteWeight.js"; +export * from "./updateVoterWeightRecord.js"; +export * from "./withdraw.js"; diff --git a/clients/voter-stake-registry/src/generated/instructions/internalTransfer.ts b/clients/voter-stake-registry/src/generated/instructions/internalTransfer.ts new file mode 100644 index 00000000..a0327027 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/instructions/internalTransfer.ts @@ -0,0 +1,228 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + AccountMeta, + AccountSignerMeta, + Address, + FixedSizeCodec, + FixedSizeDecoder, + FixedSizeEncoder, + Instruction, + InstructionWithAccounts, + InstructionWithData, + ReadonlyAccount, + ReadonlySignerAccount, + ReadonlyUint8Array, + TransactionSigner, + WritableAccount, +} from "@solana/kit"; +import type { ResolvedAccount } from "../shared/index.js"; +import { + combineCodec, + fixDecoderSize, + fixEncoderSize, + getBytesDecoder, + getBytesEncoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + getU64Decoder, + getU64Encoder, + transformEncoder, +} from "@solana/kit"; +import { VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS } from "../programs/index.js"; +import { getAccountMetaFactory } from "../shared/index.js"; + +export const INTERNAL_TRANSFER_DISCRIMINATOR: ReadonlyUint8Array = + new Uint8Array([56, 217, 60, 137, 252, 221, 185, 114]); + +export function getInternalTransferDiscriminatorBytes(): ReadonlyUint8Array { + return fixEncoderSize(getBytesEncoder(), 8).encode( + INTERNAL_TRANSFER_DISCRIMINATOR, + ); +} + +export type InternalTransferInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountRegistrar extends string | AccountMeta = string, + TAccountVoter extends string | AccountMeta = string, + TAccountVoterAuthority extends string | AccountMeta = string, + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountRegistrar extends string + ? ReadonlyAccount + : TAccountRegistrar, + TAccountVoter extends string + ? WritableAccount + : TAccountVoter, + TAccountVoterAuthority extends string + ? ReadonlySignerAccount & + AccountSignerMeta + : TAccountVoterAuthority, + ...TRemainingAccounts, + ] + >; + +export interface InternalTransferInstructionData { + discriminator: ReadonlyUint8Array; + sourceDepositEntryIndex: number; + targetDepositEntryIndex: number; + amount: bigint; +} + +export interface InternalTransferInstructionDataArgs { + sourceDepositEntryIndex: number; + targetDepositEntryIndex: number; + amount: number | bigint; +} + +export function getInternalTransferInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([ + ["discriminator", fixEncoderSize(getBytesEncoder(), 8)], + ["sourceDepositEntryIndex", getU8Encoder()], + ["targetDepositEntryIndex", getU8Encoder()], + ["amount", getU64Encoder()], + ]), + (value) => ({ ...value, discriminator: INTERNAL_TRANSFER_DISCRIMINATOR }), + ); +} + +export function getInternalTransferInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ["discriminator", fixDecoderSize(getBytesDecoder(), 8)], + ["sourceDepositEntryIndex", getU8Decoder()], + ["targetDepositEntryIndex", getU8Decoder()], + ["amount", getU64Decoder()], + ]); +} + +export function getInternalTransferInstructionDataCodec(): FixedSizeCodec< + InternalTransferInstructionDataArgs, + InternalTransferInstructionData +> { + return combineCodec( + getInternalTransferInstructionDataEncoder(), + getInternalTransferInstructionDataDecoder(), + ); +} + +export interface InternalTransferInput< + TAccountRegistrar extends string = string, + TAccountVoter extends string = string, + TAccountVoterAuthority extends string = string, +> { + registrar: Address; + voter: Address; + voterAuthority: TransactionSigner; + sourceDepositEntryIndex: InternalTransferInstructionDataArgs["sourceDepositEntryIndex"]; + targetDepositEntryIndex: InternalTransferInstructionDataArgs["targetDepositEntryIndex"]; + amount: InternalTransferInstructionDataArgs["amount"]; +} + +export function getInternalTransferInstruction< + TAccountRegistrar extends string, + TAccountVoter extends string, + TAccountVoterAuthority extends string, + TProgramAddress extends Address = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, +>( + input: InternalTransferInput< + TAccountRegistrar, + TAccountVoter, + TAccountVoterAuthority + >, + config?: { programAddress?: TProgramAddress }, +): InternalTransferInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountVoter, + TAccountVoterAuthority +> { + // Program address. + const programAddress = + config?.programAddress ?? VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + registrar: { value: input.registrar ?? null, isWritable: false }, + voter: { value: input.voter ?? null, isWritable: true }, + voterAuthority: { value: input.voterAuthority ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record< + keyof typeof originalAccounts, + ResolvedAccount + >; + + // Original args. + const args = { ...input }; + + const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.registrar), + getAccountMeta(accounts.voter), + getAccountMeta(accounts.voterAuthority), + ], + data: getInternalTransferInstructionDataEncoder().encode( + args as InternalTransferInstructionDataArgs, + ), + programAddress, + } as InternalTransferInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountVoter, + TAccountVoterAuthority + >); +} + +export interface ParsedInternalTransferInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> { + programAddress: Address; + accounts: { + registrar: TAccountMetas[0]; + voter: TAccountMetas[1]; + voterAuthority: TAccountMetas[2]; + }; + data: InternalTransferInstructionData; +} + +export function parseInternalTransferInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedInternalTransferInstruction { + if (instruction.accounts.length < 3) { + // TODO: Coded error. + throw new Error("Not enough accounts"); + } + let accountIndex = 0; + const getNextAccount = () => { + const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; + accountIndex += 1; + return accountMeta; + }; + return { + programAddress: instruction.programAddress, + accounts: { + registrar: getNextAccount(), + voter: getNextAccount(), + voterAuthority: getNextAccount(), + }, + data: getInternalTransferInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/clients/voter-stake-registry/src/generated/instructions/resetLockup.ts b/clients/voter-stake-registry/src/generated/instructions/resetLockup.ts new file mode 100644 index 00000000..e7947670 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/instructions/resetLockup.ts @@ -0,0 +1,231 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + AccountMeta, + AccountSignerMeta, + Address, + FixedSizeCodec, + FixedSizeDecoder, + FixedSizeEncoder, + Instruction, + InstructionWithAccounts, + InstructionWithData, + ReadonlyAccount, + ReadonlySignerAccount, + ReadonlyUint8Array, + TransactionSigner, + WritableAccount, +} from "@solana/kit"; +import type { ResolvedAccount } from "../shared/index.js"; +import type { LockupKind, LockupKindArgs } from "../types/index.js"; +import { + combineCodec, + fixDecoderSize, + fixEncoderSize, + getBytesDecoder, + getBytesEncoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + getU32Decoder, + getU32Encoder, + transformEncoder, +} from "@solana/kit"; +import { VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS } from "../programs/index.js"; +import { getAccountMetaFactory } from "../shared/index.js"; +import { getLockupKindDecoder, getLockupKindEncoder } from "../types/index.js"; + +export const RESET_LOCKUP_DISCRIMINATOR: ReadonlyUint8Array = new Uint8Array([ + 243, 20, 24, 247, 238, 148, 94, 62, +]); + +export function getResetLockupDiscriminatorBytes(): ReadonlyUint8Array { + return fixEncoderSize(getBytesEncoder(), 8).encode( + RESET_LOCKUP_DISCRIMINATOR, + ); +} + +export type ResetLockupInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountRegistrar extends string | AccountMeta = string, + TAccountVoter extends string | AccountMeta = string, + TAccountVoterAuthority extends string | AccountMeta = string, + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountRegistrar extends string + ? ReadonlyAccount + : TAccountRegistrar, + TAccountVoter extends string + ? WritableAccount + : TAccountVoter, + TAccountVoterAuthority extends string + ? ReadonlySignerAccount & + AccountSignerMeta + : TAccountVoterAuthority, + ...TRemainingAccounts, + ] + >; + +export interface ResetLockupInstructionData { + discriminator: ReadonlyUint8Array; + depositEntryIndex: number; + kind: LockupKind; + periods: number; +} + +export interface ResetLockupInstructionDataArgs { + depositEntryIndex: number; + kind: LockupKindArgs; + periods: number; +} + +export function getResetLockupInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([ + ["discriminator", fixEncoderSize(getBytesEncoder(), 8)], + ["depositEntryIndex", getU8Encoder()], + ["kind", getLockupKindEncoder()], + ["periods", getU32Encoder()], + ]), + (value) => ({ ...value, discriminator: RESET_LOCKUP_DISCRIMINATOR }), + ); +} + +export function getResetLockupInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ["discriminator", fixDecoderSize(getBytesDecoder(), 8)], + ["depositEntryIndex", getU8Decoder()], + ["kind", getLockupKindDecoder()], + ["periods", getU32Decoder()], + ]); +} + +export function getResetLockupInstructionDataCodec(): FixedSizeCodec< + ResetLockupInstructionDataArgs, + ResetLockupInstructionData +> { + return combineCodec( + getResetLockupInstructionDataEncoder(), + getResetLockupInstructionDataDecoder(), + ); +} + +export interface ResetLockupInput< + TAccountRegistrar extends string = string, + TAccountVoter extends string = string, + TAccountVoterAuthority extends string = string, +> { + registrar: Address; + voter: Address; + voterAuthority: TransactionSigner; + depositEntryIndex: ResetLockupInstructionDataArgs["depositEntryIndex"]; + kind: ResetLockupInstructionDataArgs["kind"]; + periods: ResetLockupInstructionDataArgs["periods"]; +} + +export function getResetLockupInstruction< + TAccountRegistrar extends string, + TAccountVoter extends string, + TAccountVoterAuthority extends string, + TProgramAddress extends Address = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, +>( + input: ResetLockupInput< + TAccountRegistrar, + TAccountVoter, + TAccountVoterAuthority + >, + config?: { programAddress?: TProgramAddress }, +): ResetLockupInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountVoter, + TAccountVoterAuthority +> { + // Program address. + const programAddress = + config?.programAddress ?? VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + registrar: { value: input.registrar ?? null, isWritable: false }, + voter: { value: input.voter ?? null, isWritable: true }, + voterAuthority: { value: input.voterAuthority ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record< + keyof typeof originalAccounts, + ResolvedAccount + >; + + // Original args. + const args = { ...input }; + + const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.registrar), + getAccountMeta(accounts.voter), + getAccountMeta(accounts.voterAuthority), + ], + data: getResetLockupInstructionDataEncoder().encode( + args as ResetLockupInstructionDataArgs, + ), + programAddress, + } as ResetLockupInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountVoter, + TAccountVoterAuthority + >); +} + +export interface ParsedResetLockupInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> { + programAddress: Address; + accounts: { + registrar: TAccountMetas[0]; + voter: TAccountMetas[1]; + voterAuthority: TAccountMetas[2]; + }; + data: ResetLockupInstructionData; +} + +export function parseResetLockupInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedResetLockupInstruction { + if (instruction.accounts.length < 3) { + // TODO: Coded error. + throw new Error("Not enough accounts"); + } + let accountIndex = 0; + const getNextAccount = () => { + const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; + accountIndex += 1; + return accountMeta; + }; + return { + programAddress: instruction.programAddress, + accounts: { + registrar: getNextAccount(), + voter: getNextAccount(), + voterAuthority: getNextAccount(), + }, + data: getResetLockupInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/clients/voter-stake-registry/src/generated/instructions/setTimeOffset.ts b/clients/voter-stake-registry/src/generated/instructions/setTimeOffset.ts new file mode 100644 index 00000000..05567a8f --- /dev/null +++ b/clients/voter-stake-registry/src/generated/instructions/setTimeOffset.ts @@ -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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + AccountMeta, + AccountSignerMeta, + Address, + FixedSizeCodec, + FixedSizeDecoder, + FixedSizeEncoder, + Instruction, + InstructionWithAccounts, + InstructionWithData, + ReadonlySignerAccount, + ReadonlyUint8Array, + TransactionSigner, + WritableAccount, +} from "@solana/kit"; +import type { ResolvedAccount } from "../shared/index.js"; +import { + combineCodec, + fixDecoderSize, + fixEncoderSize, + getBytesDecoder, + getBytesEncoder, + getI64Decoder, + getI64Encoder, + getStructDecoder, + getStructEncoder, + transformEncoder, +} from "@solana/kit"; +import { VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS } from "../programs/index.js"; +import { getAccountMetaFactory } from "../shared/index.js"; + +export const SET_TIME_OFFSET_DISCRIMINATOR: ReadonlyUint8Array = new Uint8Array( + [89, 238, 89, 160, 239, 113, 25, 123], +); + +export function getSetTimeOffsetDiscriminatorBytes(): ReadonlyUint8Array { + return fixEncoderSize(getBytesEncoder(), 8).encode( + SET_TIME_OFFSET_DISCRIMINATOR, + ); +} + +export type SetTimeOffsetInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountRegistrar extends string | AccountMeta = string, + TAccountRealmAuthority extends string | AccountMeta = string, + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountRegistrar extends string + ? WritableAccount + : TAccountRegistrar, + TAccountRealmAuthority extends string + ? ReadonlySignerAccount & + AccountSignerMeta + : TAccountRealmAuthority, + ...TRemainingAccounts, + ] + >; + +export interface SetTimeOffsetInstructionData { + discriminator: ReadonlyUint8Array; + timeOffset: bigint; +} + +export interface SetTimeOffsetInstructionDataArgs { + timeOffset: number | bigint; +} + +export function getSetTimeOffsetInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([ + ["discriminator", fixEncoderSize(getBytesEncoder(), 8)], + ["timeOffset", getI64Encoder()], + ]), + (value) => ({ ...value, discriminator: SET_TIME_OFFSET_DISCRIMINATOR }), + ); +} + +export function getSetTimeOffsetInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ["discriminator", fixDecoderSize(getBytesDecoder(), 8)], + ["timeOffset", getI64Decoder()], + ]); +} + +export function getSetTimeOffsetInstructionDataCodec(): FixedSizeCodec< + SetTimeOffsetInstructionDataArgs, + SetTimeOffsetInstructionData +> { + return combineCodec( + getSetTimeOffsetInstructionDataEncoder(), + getSetTimeOffsetInstructionDataDecoder(), + ); +} + +export interface SetTimeOffsetInput< + TAccountRegistrar extends string = string, + TAccountRealmAuthority extends string = string, +> { + registrar: Address; + realmAuthority: TransactionSigner; + timeOffset: SetTimeOffsetInstructionDataArgs["timeOffset"]; +} + +export function getSetTimeOffsetInstruction< + TAccountRegistrar extends string, + TAccountRealmAuthority extends string, + TProgramAddress extends Address = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, +>( + input: SetTimeOffsetInput, + config?: { programAddress?: TProgramAddress }, +): SetTimeOffsetInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountRealmAuthority +> { + // Program address. + const programAddress = + config?.programAddress ?? VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + registrar: { value: input.registrar ?? null, isWritable: true }, + realmAuthority: { value: input.realmAuthority ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record< + keyof typeof originalAccounts, + ResolvedAccount + >; + + // Original args. + const args = { ...input }; + + const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.registrar), + getAccountMeta(accounts.realmAuthority), + ], + data: getSetTimeOffsetInstructionDataEncoder().encode( + args as SetTimeOffsetInstructionDataArgs, + ), + programAddress, + } as SetTimeOffsetInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountRealmAuthority + >); +} + +export interface ParsedSetTimeOffsetInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> { + programAddress: Address; + accounts: { + registrar: TAccountMetas[0]; + realmAuthority: TAccountMetas[1]; + }; + data: SetTimeOffsetInstructionData; +} + +export function parseSetTimeOffsetInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedSetTimeOffsetInstruction { + if (instruction.accounts.length < 2) { + // TODO: Coded error. + throw new Error("Not enough accounts"); + } + let accountIndex = 0; + const getNextAccount = () => { + const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; + accountIndex += 1; + return accountMeta; + }; + return { + programAddress: instruction.programAddress, + accounts: { registrar: getNextAccount(), realmAuthority: getNextAccount() }, + data: getSetTimeOffsetInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/clients/voter-stake-registry/src/generated/instructions/updateMaxVoteWeight.ts b/clients/voter-stake-registry/src/generated/instructions/updateMaxVoteWeight.ts new file mode 100644 index 00000000..10201156 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/instructions/updateMaxVoteWeight.ts @@ -0,0 +1,190 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + AccountMeta, + Address, + FixedSizeCodec, + FixedSizeDecoder, + FixedSizeEncoder, + Instruction, + InstructionWithAccounts, + InstructionWithData, + ReadonlyAccount, + ReadonlyUint8Array, +} from "@solana/kit"; +import type { ResolvedAccount } from "../shared/index.js"; +import { + combineCodec, + fixDecoderSize, + fixEncoderSize, + getBytesDecoder, + getBytesEncoder, + getStructDecoder, + getStructEncoder, + transformEncoder, +} from "@solana/kit"; +import { VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS } from "../programs/index.js"; +import { getAccountMetaFactory } from "../shared/index.js"; + +export const UPDATE_MAX_VOTE_WEIGHT_DISCRIMINATOR: ReadonlyUint8Array = + new Uint8Array([78, 221, 185, 255, 240, 128, 244, 162]); + +export function getUpdateMaxVoteWeightDiscriminatorBytes(): ReadonlyUint8Array { + return fixEncoderSize(getBytesEncoder(), 8).encode( + UPDATE_MAX_VOTE_WEIGHT_DISCRIMINATOR, + ); +} + +export type UpdateMaxVoteWeightInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountRegistrar extends string | AccountMeta = string, + TAccountMaxVoteWeightRecord extends string | AccountMeta = string, + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountRegistrar extends string + ? ReadonlyAccount + : TAccountRegistrar, + TAccountMaxVoteWeightRecord extends string + ? ReadonlyAccount + : TAccountMaxVoteWeightRecord, + ...TRemainingAccounts, + ] + >; + +export interface UpdateMaxVoteWeightInstructionData { + discriminator: ReadonlyUint8Array; +} + +export interface UpdateMaxVoteWeightInstructionDataArgs {} + +export function getUpdateMaxVoteWeightInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([["discriminator", fixEncoderSize(getBytesEncoder(), 8)]]), + (value) => ({ + ...value, + discriminator: UPDATE_MAX_VOTE_WEIGHT_DISCRIMINATOR, + }), + ); +} + +export function getUpdateMaxVoteWeightInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ["discriminator", fixDecoderSize(getBytesDecoder(), 8)], + ]); +} + +export function getUpdateMaxVoteWeightInstructionDataCodec(): FixedSizeCodec< + UpdateMaxVoteWeightInstructionDataArgs, + UpdateMaxVoteWeightInstructionData +> { + return combineCodec( + getUpdateMaxVoteWeightInstructionDataEncoder(), + getUpdateMaxVoteWeightInstructionDataDecoder(), + ); +} + +export interface UpdateMaxVoteWeightInput< + TAccountRegistrar extends string = string, + TAccountMaxVoteWeightRecord extends string = string, +> { + registrar: Address; + maxVoteWeightRecord: Address; +} + +export function getUpdateMaxVoteWeightInstruction< + TAccountRegistrar extends string, + TAccountMaxVoteWeightRecord extends string, + TProgramAddress extends Address = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, +>( + input: UpdateMaxVoteWeightInput< + TAccountRegistrar, + TAccountMaxVoteWeightRecord + >, + config?: { programAddress?: TProgramAddress }, +): UpdateMaxVoteWeightInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountMaxVoteWeightRecord +> { + // Program address. + const programAddress = + config?.programAddress ?? VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + registrar: { value: input.registrar ?? null, isWritable: false }, + maxVoteWeightRecord: { + value: input.maxVoteWeightRecord ?? null, + isWritable: false, + }, + }; + const accounts = originalAccounts as Record< + keyof typeof originalAccounts, + ResolvedAccount + >; + + const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.registrar), + getAccountMeta(accounts.maxVoteWeightRecord), + ], + data: getUpdateMaxVoteWeightInstructionDataEncoder().encode({}), + programAddress, + } as UpdateMaxVoteWeightInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountMaxVoteWeightRecord + >); +} + +export interface ParsedUpdateMaxVoteWeightInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> { + programAddress: Address; + accounts: { + registrar: TAccountMetas[0]; + maxVoteWeightRecord: TAccountMetas[1]; + }; + data: UpdateMaxVoteWeightInstructionData; +} + +export function parseUpdateMaxVoteWeightInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedUpdateMaxVoteWeightInstruction { + if (instruction.accounts.length < 2) { + // TODO: Coded error. + throw new Error("Not enough accounts"); + } + let accountIndex = 0; + const getNextAccount = () => { + const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; + accountIndex += 1; + return accountMeta; + }; + return { + programAddress: instruction.programAddress, + accounts: { + registrar: getNextAccount(), + maxVoteWeightRecord: getNextAccount(), + }, + data: getUpdateMaxVoteWeightInstructionDataDecoder().decode( + instruction.data, + ), + }; +} diff --git a/clients/voter-stake-registry/src/generated/instructions/updateVoterWeightRecord.ts b/clients/voter-stake-registry/src/generated/instructions/updateVoterWeightRecord.ts new file mode 100644 index 00000000..d1e4306b --- /dev/null +++ b/clients/voter-stake-registry/src/generated/instructions/updateVoterWeightRecord.ts @@ -0,0 +1,227 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + AccountMeta, + Address, + FixedSizeCodec, + FixedSizeDecoder, + FixedSizeEncoder, + Instruction, + InstructionWithAccounts, + InstructionWithData, + ReadonlyAccount, + ReadonlyUint8Array, + WritableAccount, +} from "@solana/kit"; +import type { ResolvedAccount } from "../shared/index.js"; +import { + combineCodec, + fixDecoderSize, + fixEncoderSize, + getBytesDecoder, + getBytesEncoder, + getStructDecoder, + getStructEncoder, + transformEncoder, +} from "@solana/kit"; +import { VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS } from "../programs/index.js"; +import { getAccountMetaFactory } from "../shared/index.js"; + +export const UPDATE_VOTER_WEIGHT_RECORD_DISCRIMINATOR: ReadonlyUint8Array = + new Uint8Array([45, 185, 3, 36, 109, 190, 115, 169]); + +export function getUpdateVoterWeightRecordDiscriminatorBytes(): ReadonlyUint8Array { + return fixEncoderSize(getBytesEncoder(), 8).encode( + UPDATE_VOTER_WEIGHT_RECORD_DISCRIMINATOR, + ); +} + +export type UpdateVoterWeightRecordInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountRegistrar extends string | AccountMeta = string, + TAccountVoter extends string | AccountMeta = string, + TAccountVoterWeightRecord extends string | AccountMeta = string, + TAccountSystemProgram extends + | string + | AccountMeta = "11111111111111111111111111111111", + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountRegistrar extends string + ? ReadonlyAccount + : TAccountRegistrar, + TAccountVoter extends string + ? ReadonlyAccount + : TAccountVoter, + TAccountVoterWeightRecord extends string + ? WritableAccount + : TAccountVoterWeightRecord, + TAccountSystemProgram extends string + ? ReadonlyAccount + : TAccountSystemProgram, + ...TRemainingAccounts, + ] + >; + +export interface UpdateVoterWeightRecordInstructionData { + discriminator: ReadonlyUint8Array; +} + +export interface UpdateVoterWeightRecordInstructionDataArgs {} + +export function getUpdateVoterWeightRecordInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([["discriminator", fixEncoderSize(getBytesEncoder(), 8)]]), + (value) => ({ + ...value, + discriminator: UPDATE_VOTER_WEIGHT_RECORD_DISCRIMINATOR, + }), + ); +} + +export function getUpdateVoterWeightRecordInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ["discriminator", fixDecoderSize(getBytesDecoder(), 8)], + ]); +} + +export function getUpdateVoterWeightRecordInstructionDataCodec(): FixedSizeCodec< + UpdateVoterWeightRecordInstructionDataArgs, + UpdateVoterWeightRecordInstructionData +> { + return combineCodec( + getUpdateVoterWeightRecordInstructionDataEncoder(), + getUpdateVoterWeightRecordInstructionDataDecoder(), + ); +} + +export interface UpdateVoterWeightRecordInput< + TAccountRegistrar extends string = string, + TAccountVoter extends string = string, + TAccountVoterWeightRecord extends string = string, + TAccountSystemProgram extends string = string, +> { + registrar: Address; + voter: Address; + voterWeightRecord: Address; + systemProgram?: Address; +} + +export function getUpdateVoterWeightRecordInstruction< + TAccountRegistrar extends string, + TAccountVoter extends string, + TAccountVoterWeightRecord extends string, + TAccountSystemProgram extends string, + TProgramAddress extends Address = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, +>( + input: UpdateVoterWeightRecordInput< + TAccountRegistrar, + TAccountVoter, + TAccountVoterWeightRecord, + TAccountSystemProgram + >, + config?: { programAddress?: TProgramAddress }, +): UpdateVoterWeightRecordInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountVoter, + TAccountVoterWeightRecord, + TAccountSystemProgram +> { + // Program address. + const programAddress = + config?.programAddress ?? VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + registrar: { value: input.registrar ?? null, isWritable: false }, + voter: { value: input.voter ?? null, isWritable: false }, + voterWeightRecord: { + value: input.voterWeightRecord ?? null, + isWritable: true, + }, + systemProgram: { value: input.systemProgram ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record< + keyof typeof originalAccounts, + ResolvedAccount + >; + + // Resolve default values. + if (!accounts.systemProgram.value) { + accounts.systemProgram.value = + "11111111111111111111111111111111" as Address<"11111111111111111111111111111111">; + } + + const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.registrar), + getAccountMeta(accounts.voter), + getAccountMeta(accounts.voterWeightRecord), + getAccountMeta(accounts.systemProgram), + ], + data: getUpdateVoterWeightRecordInstructionDataEncoder().encode({}), + programAddress, + } as UpdateVoterWeightRecordInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountVoter, + TAccountVoterWeightRecord, + TAccountSystemProgram + >); +} + +export interface ParsedUpdateVoterWeightRecordInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> { + programAddress: Address; + accounts: { + registrar: TAccountMetas[0]; + voter: TAccountMetas[1]; + voterWeightRecord: TAccountMetas[2]; + systemProgram: TAccountMetas[3]; + }; + data: UpdateVoterWeightRecordInstructionData; +} + +export function parseUpdateVoterWeightRecordInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedUpdateVoterWeightRecordInstruction { + if (instruction.accounts.length < 4) { + // TODO: Coded error. + throw new Error("Not enough accounts"); + } + let accountIndex = 0; + const getNextAccount = () => { + const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; + accountIndex += 1; + return accountMeta; + }; + return { + programAddress: instruction.programAddress, + accounts: { + registrar: getNextAccount(), + voter: getNextAccount(), + voterWeightRecord: getNextAccount(), + systemProgram: getNextAccount(), + }, + data: getUpdateVoterWeightRecordInstructionDataDecoder().decode( + instruction.data, + ), + }; +} diff --git a/clients/voter-stake-registry/src/generated/instructions/withdraw.ts b/clients/voter-stake-registry/src/generated/instructions/withdraw.ts new file mode 100644 index 00000000..baca509f --- /dev/null +++ b/clients/voter-stake-registry/src/generated/instructions/withdraw.ts @@ -0,0 +1,306 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + AccountMeta, + AccountSignerMeta, + Address, + FixedSizeCodec, + FixedSizeDecoder, + FixedSizeEncoder, + Instruction, + InstructionWithAccounts, + InstructionWithData, + ReadonlyAccount, + ReadonlySignerAccount, + ReadonlyUint8Array, + TransactionSigner, + WritableAccount, +} from "@solana/kit"; +import type { ResolvedAccount } from "../shared/index.js"; +import { + combineCodec, + fixDecoderSize, + fixEncoderSize, + getBytesDecoder, + getBytesEncoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + getU64Decoder, + getU64Encoder, + transformEncoder, +} from "@solana/kit"; +import { VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS } from "../programs/index.js"; +import { getAccountMetaFactory } from "../shared/index.js"; + +export const WITHDRAW_DISCRIMINATOR: ReadonlyUint8Array = new Uint8Array([ + 183, 18, 70, 156, 148, 109, 161, 34, +]); + +export function getWithdrawDiscriminatorBytes(): ReadonlyUint8Array { + return fixEncoderSize(getBytesEncoder(), 8).encode(WITHDRAW_DISCRIMINATOR); +} + +export type WithdrawInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountRegistrar extends string | AccountMeta = string, + TAccountVoter extends string | AccountMeta = string, + TAccountVoterAuthority extends string | AccountMeta = string, + TAccountTokenOwnerRecord extends string | AccountMeta = string, + TAccountVoterWeightRecord extends string | AccountMeta = string, + TAccountVault extends string | AccountMeta = string, + TAccountDestination extends string | AccountMeta = string, + TAccountTokenProgram extends + | string + | AccountMeta = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountRegistrar extends string + ? ReadonlyAccount + : TAccountRegistrar, + TAccountVoter extends string + ? WritableAccount + : TAccountVoter, + TAccountVoterAuthority extends string + ? ReadonlySignerAccount & + AccountSignerMeta + : TAccountVoterAuthority, + TAccountTokenOwnerRecord extends string + ? ReadonlyAccount + : TAccountTokenOwnerRecord, + TAccountVoterWeightRecord extends string + ? WritableAccount + : TAccountVoterWeightRecord, + TAccountVault extends string + ? WritableAccount + : TAccountVault, + TAccountDestination extends string + ? WritableAccount + : TAccountDestination, + TAccountTokenProgram extends string + ? ReadonlyAccount + : TAccountTokenProgram, + ...TRemainingAccounts, + ] + >; + +export interface WithdrawInstructionData { + discriminator: ReadonlyUint8Array; + depositEntryIndex: number; + amount: bigint; +} + +export interface WithdrawInstructionDataArgs { + depositEntryIndex: number; + amount: number | bigint; +} + +export function getWithdrawInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([ + ["discriminator", fixEncoderSize(getBytesEncoder(), 8)], + ["depositEntryIndex", getU8Encoder()], + ["amount", getU64Encoder()], + ]), + (value) => ({ ...value, discriminator: WITHDRAW_DISCRIMINATOR }), + ); +} + +export function getWithdrawInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ["discriminator", fixDecoderSize(getBytesDecoder(), 8)], + ["depositEntryIndex", getU8Decoder()], + ["amount", getU64Decoder()], + ]); +} + +export function getWithdrawInstructionDataCodec(): FixedSizeCodec< + WithdrawInstructionDataArgs, + WithdrawInstructionData +> { + return combineCodec( + getWithdrawInstructionDataEncoder(), + getWithdrawInstructionDataDecoder(), + ); +} + +export interface WithdrawInput< + TAccountRegistrar extends string = string, + TAccountVoter extends string = string, + TAccountVoterAuthority extends string = string, + TAccountTokenOwnerRecord extends string = string, + TAccountVoterWeightRecord extends string = string, + TAccountVault extends string = string, + TAccountDestination extends string = string, + TAccountTokenProgram extends string = string, +> { + registrar: Address; + voter: Address; + voterAuthority: TransactionSigner; + tokenOwnerRecord: Address; + voterWeightRecord: Address; + vault: Address; + destination: Address; + tokenProgram?: Address; + depositEntryIndex: WithdrawInstructionDataArgs["depositEntryIndex"]; + amount: WithdrawInstructionDataArgs["amount"]; +} + +export function getWithdrawInstruction< + TAccountRegistrar extends string, + TAccountVoter extends string, + TAccountVoterAuthority extends string, + TAccountTokenOwnerRecord extends string, + TAccountVoterWeightRecord extends string, + TAccountVault extends string, + TAccountDestination extends string, + TAccountTokenProgram extends string, + TProgramAddress extends Address = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, +>( + input: WithdrawInput< + TAccountRegistrar, + TAccountVoter, + TAccountVoterAuthority, + TAccountTokenOwnerRecord, + TAccountVoterWeightRecord, + TAccountVault, + TAccountDestination, + TAccountTokenProgram + >, + config?: { programAddress?: TProgramAddress }, +): WithdrawInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountVoter, + TAccountVoterAuthority, + TAccountTokenOwnerRecord, + TAccountVoterWeightRecord, + TAccountVault, + TAccountDestination, + TAccountTokenProgram +> { + // Program address. + const programAddress = + config?.programAddress ?? VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + registrar: { value: input.registrar ?? null, isWritable: false }, + voter: { value: input.voter ?? null, isWritable: true }, + voterAuthority: { value: input.voterAuthority ?? null, isWritable: false }, + tokenOwnerRecord: { + value: input.tokenOwnerRecord ?? null, + isWritable: false, + }, + voterWeightRecord: { + value: input.voterWeightRecord ?? null, + isWritable: true, + }, + vault: { value: input.vault ?? null, isWritable: true }, + destination: { value: input.destination ?? null, isWritable: true }, + tokenProgram: { value: input.tokenProgram ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record< + keyof typeof originalAccounts, + ResolvedAccount + >; + + // Original args. + const args = { ...input }; + + // Resolve default values. + if (!accounts.tokenProgram.value) { + accounts.tokenProgram.value = + "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" as Address<"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA">; + } + + const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.registrar), + getAccountMeta(accounts.voter), + getAccountMeta(accounts.voterAuthority), + getAccountMeta(accounts.tokenOwnerRecord), + getAccountMeta(accounts.voterWeightRecord), + getAccountMeta(accounts.vault), + getAccountMeta(accounts.destination), + getAccountMeta(accounts.tokenProgram), + ], + data: getWithdrawInstructionDataEncoder().encode( + args as WithdrawInstructionDataArgs, + ), + programAddress, + } as WithdrawInstruction< + TProgramAddress, + TAccountRegistrar, + TAccountVoter, + TAccountVoterAuthority, + TAccountTokenOwnerRecord, + TAccountVoterWeightRecord, + TAccountVault, + TAccountDestination, + TAccountTokenProgram + >); +} + +export interface ParsedWithdrawInstruction< + TProgram extends string = typeof VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> { + programAddress: Address; + accounts: { + registrar: TAccountMetas[0]; + voter: TAccountMetas[1]; + voterAuthority: TAccountMetas[2]; + tokenOwnerRecord: TAccountMetas[3]; + voterWeightRecord: TAccountMetas[4]; + vault: TAccountMetas[5]; + destination: TAccountMetas[6]; + tokenProgram: TAccountMetas[7]; + }; + data: WithdrawInstructionData; +} + +export function parseWithdrawInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedWithdrawInstruction { + if (instruction.accounts.length < 8) { + // TODO: Coded error. + throw new Error("Not enough accounts"); + } + let accountIndex = 0; + const getNextAccount = () => { + const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; + accountIndex += 1; + return accountMeta; + }; + return { + programAddress: instruction.programAddress, + accounts: { + registrar: getNextAccount(), + voter: getNextAccount(), + voterAuthority: getNextAccount(), + tokenOwnerRecord: getNextAccount(), + voterWeightRecord: getNextAccount(), + vault: getNextAccount(), + destination: getNextAccount(), + tokenProgram: getNextAccount(), + }, + data: getWithdrawInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/clients/voter-stake-registry/src/generated/pdas/index.ts b/clients/voter-stake-registry/src/generated/pdas/index.ts new file mode 100644 index 00000000..7040b4e2 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/pdas/index.ts @@ -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. + * + * @see https://github.com/codama-idl/codama + */ + +export * from "./registrar.js"; +export * from "./voter.js"; +export * from "./voterWeightRecord.js"; diff --git a/clients/voter-stake-registry/src/generated/pdas/registrar.ts b/clients/voter-stake-registry/src/generated/pdas/registrar.ts new file mode 100644 index 00000000..17836884 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/pdas/registrar.ts @@ -0,0 +1,40 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { Address, ProgramDerivedAddress } from "@solana/kit"; +import { + getAddressEncoder, + getProgramDerivedAddress, + getUtf8Encoder, +} from "@solana/kit"; + +export interface RegistrarSeeds { + realm: Address; + realmGoverningTokenMint: Address; +} + +/** + * The voting registrar. There can only be a single registrar + * per governance realm and governing mint. + */ +export async function findRegistrarPda( + seeds: RegistrarSeeds, + config: { programAddress?: Address | undefined } = {}, +): Promise { + const { + programAddress = "vsr2nfGVNHmSY8uxoBGqq8AQbwz3JwaEaHqGbsTPXqQ" as Address<"vsr2nfGVNHmSY8uxoBGqq8AQbwz3JwaEaHqGbsTPXqQ">, + } = config; + return await getProgramDerivedAddress({ + programAddress, + seeds: [ + getAddressEncoder().encode(seeds.realm), + getUtf8Encoder().encode("registrar"), + getAddressEncoder().encode(seeds.realmGoverningTokenMint), + ], + }); +} diff --git a/clients/voter-stake-registry/src/generated/pdas/voter.ts b/clients/voter-stake-registry/src/generated/pdas/voter.ts new file mode 100644 index 00000000..41bdbd3b --- /dev/null +++ b/clients/voter-stake-registry/src/generated/pdas/voter.ts @@ -0,0 +1,40 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { Address, ProgramDerivedAddress } from "@solana/kit"; +import { + getAddressEncoder, + getProgramDerivedAddress, + getUtf8Encoder, +} from "@solana/kit"; + +export interface VoterSeeds { + registrar: Address; + voterAuthority: Address; +} + +/** + * The voter account for a given voter authority. + * Each voter authority has a unique voter account per registrar. + */ +export async function findVoterPda( + seeds: VoterSeeds, + config: { programAddress?: Address | undefined } = {}, +): Promise { + const { + programAddress = "vsr2nfGVNHmSY8uxoBGqq8AQbwz3JwaEaHqGbsTPXqQ" as Address<"vsr2nfGVNHmSY8uxoBGqq8AQbwz3JwaEaHqGbsTPXqQ">, + } = config; + return await getProgramDerivedAddress({ + programAddress, + seeds: [ + getAddressEncoder().encode(seeds.registrar), + getUtf8Encoder().encode("voter"), + getAddressEncoder().encode(seeds.voterAuthority), + ], + }); +} diff --git a/clients/voter-stake-registry/src/generated/pdas/voterWeightRecord.ts b/clients/voter-stake-registry/src/generated/pdas/voterWeightRecord.ts new file mode 100644 index 00000000..2b5eba65 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/pdas/voterWeightRecord.ts @@ -0,0 +1,40 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { Address, ProgramDerivedAddress } from "@solana/kit"; +import { + getAddressEncoder, + getProgramDerivedAddress, + getUtf8Encoder, +} from "@solana/kit"; + +export interface VoterWeightRecordSeeds { + registrar: Address; + voterAuthority: Address; +} + +/** + * The voter weight record is the account that will be shown to spl-governance + * to prove how much vote weight the voter has. See update_voter_weight_record. + */ +export async function findVoterWeightRecordPda( + seeds: VoterWeightRecordSeeds, + config: { programAddress?: Address | undefined } = {}, +): Promise { + const { + programAddress = "vsr2nfGVNHmSY8uxoBGqq8AQbwz3JwaEaHqGbsTPXqQ" as Address<"vsr2nfGVNHmSY8uxoBGqq8AQbwz3JwaEaHqGbsTPXqQ">, + } = config; + return await getProgramDerivedAddress({ + programAddress, + seeds: [ + getAddressEncoder().encode(seeds.registrar), + getUtf8Encoder().encode("voter-weight-record"), + getAddressEncoder().encode(seeds.voterAuthority), + ], + }); +} diff --git a/clients/voter-stake-registry/src/generated/programs/index.ts b/clients/voter-stake-registry/src/generated/programs/index.ts new file mode 100644 index 00000000..93333bb5 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/programs/index.ts @@ -0,0 +1,9 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +export * from "./voterStakeRegistry.js"; diff --git a/clients/voter-stake-registry/src/generated/programs/voterStakeRegistry.ts b/clients/voter-stake-registry/src/generated/programs/voterStakeRegistry.ts new file mode 100644 index 00000000..dd89cbbe --- /dev/null +++ b/clients/voter-stake-registry/src/generated/programs/voterStakeRegistry.ts @@ -0,0 +1,319 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { Address, ReadonlyUint8Array } from "@solana/kit"; +import type { + ParsedClawbackInstruction, + ParsedCloseDepositEntryInstruction, + ParsedCloseVoterInstruction, + ParsedConfigureVotingMintInstruction, + ParsedCreateDepositEntryInstruction, + ParsedCreateRegistrarInstruction, + ParsedCreateVoterInstruction, + ParsedDepositInstruction, + ParsedGrantInstruction, + ParsedInternalTransferInstruction, + ParsedResetLockupInstruction, + ParsedSetTimeOffsetInstruction, + ParsedUpdateMaxVoteWeightInstruction, + ParsedUpdateVoterWeightRecordInstruction, + ParsedWithdrawInstruction, +} from "../instructions/index.js"; +import { containsBytes, fixEncoderSize, getBytesEncoder } from "@solana/kit"; + +export const VOTER_STAKE_REGISTRY_PROGRAM_ADDRESS = + "vsr2nfGVNHmSY8uxoBGqq8AQbwz3JwaEaHqGbsTPXqQ" as Address<"vsr2nfGVNHmSY8uxoBGqq8AQbwz3JwaEaHqGbsTPXqQ">; + +export enum VoterStakeRegistryAccount { + Registrar = 0, + Voter = 1, + VoterWeightRecord = 2, +} + +export function identifyVoterStakeRegistryAccount( + account: { data: ReadonlyUint8Array } | ReadonlyUint8Array, +): VoterStakeRegistryAccount { + const data = "data" in account ? account.data : account; + if ( + containsBytes( + data, + fixEncoderSize(getBytesEncoder(), 8).encode( + new Uint8Array([193, 202, 205, 51, 78, 168, 150, 128]), + ), + 0, + ) + ) { + return VoterStakeRegistryAccount.Registrar; + } + if ( + containsBytes( + data, + fixEncoderSize(getBytesEncoder(), 8).encode( + new Uint8Array([241, 93, 35, 191, 254, 147, 17, 202]), + ), + 0, + ) + ) { + return VoterStakeRegistryAccount.Voter; + } + if ( + containsBytes( + data, + fixEncoderSize(getBytesEncoder(), 8).encode( + new Uint8Array([50, 101, 102, 57, 57, 98, 52, 98]), + ), + 0, + ) + ) { + return VoterStakeRegistryAccount.VoterWeightRecord; + } + throw new Error( + "The provided account could not be identified as a voterStakeRegistry account.", + ); +} + +export enum VoterStakeRegistryInstruction { + CreateRegistrar = 0, + ConfigureVotingMint = 1, + CreateVoter = 2, + CreateDepositEntry = 3, + Deposit = 4, + Withdraw = 5, + Grant = 6, + Clawback = 7, + CloseDepositEntry = 8, + ResetLockup = 9, + InternalTransfer = 10, + UpdateVoterWeightRecord = 11, + UpdateMaxVoteWeight = 12, + CloseVoter = 13, + SetTimeOffset = 14, +} + +export function identifyVoterStakeRegistryInstruction( + instruction: { data: ReadonlyUint8Array } | ReadonlyUint8Array, +): VoterStakeRegistryInstruction { + const data = "data" in instruction ? instruction.data : instruction; + if ( + containsBytes( + data, + fixEncoderSize(getBytesEncoder(), 8).encode( + new Uint8Array([132, 235, 36, 49, 139, 66, 202, 69]), + ), + 0, + ) + ) { + return VoterStakeRegistryInstruction.CreateRegistrar; + } + if ( + containsBytes( + data, + fixEncoderSize(getBytesEncoder(), 8).encode( + new Uint8Array([113, 153, 141, 236, 184, 9, 135, 15]), + ), + 0, + ) + ) { + return VoterStakeRegistryInstruction.ConfigureVotingMint; + } + if ( + containsBytes( + data, + fixEncoderSize(getBytesEncoder(), 8).encode( + new Uint8Array([6, 24, 245, 52, 243, 255, 148, 25]), + ), + 0, + ) + ) { + return VoterStakeRegistryInstruction.CreateVoter; + } + if ( + containsBytes( + data, + fixEncoderSize(getBytesEncoder(), 8).encode( + new Uint8Array([185, 131, 167, 186, 159, 125, 19, 67]), + ), + 0, + ) + ) { + return VoterStakeRegistryInstruction.CreateDepositEntry; + } + if ( + containsBytes( + data, + fixEncoderSize(getBytesEncoder(), 8).encode( + new Uint8Array([242, 35, 198, 137, 82, 225, 242, 182]), + ), + 0, + ) + ) { + return VoterStakeRegistryInstruction.Deposit; + } + if ( + containsBytes( + data, + fixEncoderSize(getBytesEncoder(), 8).encode( + new Uint8Array([183, 18, 70, 156, 148, 109, 161, 34]), + ), + 0, + ) + ) { + return VoterStakeRegistryInstruction.Withdraw; + } + if ( + containsBytes( + data, + fixEncoderSize(getBytesEncoder(), 8).encode( + new Uint8Array([145, 189, 68, 153, 161, 231, 76, 107]), + ), + 0, + ) + ) { + return VoterStakeRegistryInstruction.Grant; + } + if ( + containsBytes( + data, + fixEncoderSize(getBytesEncoder(), 8).encode( + new Uint8Array([111, 92, 142, 79, 33, 234, 82, 27]), + ), + 0, + ) + ) { + return VoterStakeRegistryInstruction.Clawback; + } + if ( + containsBytes( + data, + fixEncoderSize(getBytesEncoder(), 8).encode( + new Uint8Array([236, 190, 87, 34, 251, 131, 138, 237]), + ), + 0, + ) + ) { + return VoterStakeRegistryInstruction.CloseDepositEntry; + } + if ( + containsBytes( + data, + fixEncoderSize(getBytesEncoder(), 8).encode( + new Uint8Array([243, 20, 24, 247, 238, 148, 94, 62]), + ), + 0, + ) + ) { + return VoterStakeRegistryInstruction.ResetLockup; + } + if ( + containsBytes( + data, + fixEncoderSize(getBytesEncoder(), 8).encode( + new Uint8Array([56, 217, 60, 137, 252, 221, 185, 114]), + ), + 0, + ) + ) { + return VoterStakeRegistryInstruction.InternalTransfer; + } + if ( + containsBytes( + data, + fixEncoderSize(getBytesEncoder(), 8).encode( + new Uint8Array([45, 185, 3, 36, 109, 190, 115, 169]), + ), + 0, + ) + ) { + return VoterStakeRegistryInstruction.UpdateVoterWeightRecord; + } + if ( + containsBytes( + data, + fixEncoderSize(getBytesEncoder(), 8).encode( + new Uint8Array([78, 221, 185, 255, 240, 128, 244, 162]), + ), + 0, + ) + ) { + return VoterStakeRegistryInstruction.UpdateMaxVoteWeight; + } + if ( + containsBytes( + data, + fixEncoderSize(getBytesEncoder(), 8).encode( + new Uint8Array([117, 35, 234, 247, 206, 131, 182, 149]), + ), + 0, + ) + ) { + return VoterStakeRegistryInstruction.CloseVoter; + } + if ( + containsBytes( + data, + fixEncoderSize(getBytesEncoder(), 8).encode( + new Uint8Array([89, 238, 89, 160, 239, 113, 25, 123]), + ), + 0, + ) + ) { + return VoterStakeRegistryInstruction.SetTimeOffset; + } + throw new Error( + "The provided instruction could not be identified as a voterStakeRegistry instruction.", + ); +} + +export type ParsedVoterStakeRegistryInstruction< + TProgram extends string = "vsr2nfGVNHmSY8uxoBGqq8AQbwz3JwaEaHqGbsTPXqQ", +> = + | ({ + instructionType: VoterStakeRegistryInstruction.CreateRegistrar; + } & ParsedCreateRegistrarInstruction) + | ({ + instructionType: VoterStakeRegistryInstruction.ConfigureVotingMint; + } & ParsedConfigureVotingMintInstruction) + | ({ + instructionType: VoterStakeRegistryInstruction.CreateVoter; + } & ParsedCreateVoterInstruction) + | ({ + instructionType: VoterStakeRegistryInstruction.CreateDepositEntry; + } & ParsedCreateDepositEntryInstruction) + | ({ + instructionType: VoterStakeRegistryInstruction.Deposit; + } & ParsedDepositInstruction) + | ({ + instructionType: VoterStakeRegistryInstruction.Withdraw; + } & ParsedWithdrawInstruction) + | ({ + instructionType: VoterStakeRegistryInstruction.Grant; + } & ParsedGrantInstruction) + | ({ + instructionType: VoterStakeRegistryInstruction.Clawback; + } & ParsedClawbackInstruction) + | ({ + instructionType: VoterStakeRegistryInstruction.CloseDepositEntry; + } & ParsedCloseDepositEntryInstruction) + | ({ + instructionType: VoterStakeRegistryInstruction.ResetLockup; + } & ParsedResetLockupInstruction) + | ({ + instructionType: VoterStakeRegistryInstruction.InternalTransfer; + } & ParsedInternalTransferInstruction) + | ({ + instructionType: VoterStakeRegistryInstruction.UpdateVoterWeightRecord; + } & ParsedUpdateVoterWeightRecordInstruction) + | ({ + instructionType: VoterStakeRegistryInstruction.UpdateMaxVoteWeight; + } & ParsedUpdateMaxVoteWeightInstruction) + | ({ + instructionType: VoterStakeRegistryInstruction.CloseVoter; + } & ParsedCloseVoterInstruction) + | ({ + instructionType: VoterStakeRegistryInstruction.SetTimeOffset; + } & ParsedSetTimeOffsetInstruction); diff --git a/clients/voter-stake-registry/src/generated/shared/index.ts b/clients/voter-stake-registry/src/generated/shared/index.ts new file mode 100644 index 00000000..b79b9c6b --- /dev/null +++ b/clients/voter-stake-registry/src/generated/shared/index.ts @@ -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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + AccountMeta, + AccountSignerMeta, + Address, + ProgramDerivedAddress, + TransactionSigner, +} from "@solana/kit"; +import { + AccountRole, + isProgramDerivedAddress, + isTransactionSigner as kitIsTransactionSigner, + upgradeRoleToSigner, +} from "@solana/kit"; + +/** + * Asserts that the given value is not null or undefined. + * @internal + */ +export function expectSome(value: T | null | undefined): T { + if (value === null || value === undefined) { + throw new Error("Expected a value but received null or undefined."); + } + return value; +} + +/** + * Asserts that the given value is a PublicKey. + * @internal + */ +export function expectAddress( + value: + | Address + | ProgramDerivedAddress + | TransactionSigner + | null + | undefined, +): Address { + if (!value) { + throw new Error("Expected a Address."); + } + if (typeof value === "object" && "address" in value) { + return value.address; + } + if (Array.isArray(value)) { + return value[0] as Address; + } + return value as Address; +} + +/** + * Asserts that the given value is a PDA. + * @internal + */ +export function expectProgramDerivedAddress( + value: + | Address + | ProgramDerivedAddress + | TransactionSigner + | null + | undefined, +): ProgramDerivedAddress { + if (!(value && Array.isArray(value) && isProgramDerivedAddress(value))) { + throw new Error("Expected a ProgramDerivedAddress."); + } + return value; +} + +/** + * Asserts that the given value is a TransactionSigner. + * @internal + */ +export function expectTransactionSigner( + value: + | Address + | ProgramDerivedAddress + | TransactionSigner + | null + | undefined, +): TransactionSigner { + if (!(value && isTransactionSigner(value))) { + throw new Error("Expected a TransactionSigner."); + } + return value; +} + +/** + * Defines an instruction account to resolve. + * @internal + */ +export interface ResolvedAccount< + T extends string = string, + U extends + | Address + | ProgramDerivedAddress + | TransactionSigner + | null = + | Address + | ProgramDerivedAddress + | TransactionSigner + | null, +> { + isWritable: boolean; + value: U; +} + +/** + * Defines an instruction that stores additional bytes on-chain. + * @internal + */ +export interface InstructionWithByteDelta { + byteDelta: number; +} + +/** + * Get account metas and signers from resolved accounts. + * @internal + */ +export function getAccountMetaFactory( + programAddress: Address, + optionalAccountStrategy: "omitted" | "programId", +) { + return ( + account: ResolvedAccount, + ): AccountMeta | AccountSignerMeta | undefined => { + if (!account.value) { + if (optionalAccountStrategy === "omitted") { + return; + } + return Object.freeze({ + address: programAddress, + role: AccountRole.READONLY, + }); + } + + const writableRole = account.isWritable + ? AccountRole.WRITABLE + : AccountRole.READONLY; + return Object.freeze({ + address: expectAddress(account.value), + role: isTransactionSigner(account.value) + ? upgradeRoleToSigner(writableRole) + : writableRole, + ...(isTransactionSigner(account.value) ? { signer: account.value } : {}), + }); + }; +} + +export function isTransactionSigner( + value: + | Address + | ProgramDerivedAddress + | TransactionSigner, +): value is TransactionSigner { + return ( + !!value && + typeof value === "object" && + "address" in value && + kitIsTransactionSigner(value) + ); +} diff --git a/clients/voter-stake-registry/src/generated/types/depositEntry.ts b/clients/voter-stake-registry/src/generated/types/depositEntry.ts new file mode 100644 index 00000000..82c381f6 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/types/depositEntry.ts @@ -0,0 +1,79 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + FixedSizeCodec, + FixedSizeDecoder, + FixedSizeEncoder, +} from "@solana/kit"; +import type { Lockup, LockupArgs } from "./index.js"; +import { + combineCodec, + getArrayDecoder, + getArrayEncoder, + getBooleanDecoder, + getBooleanEncoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + getU64Decoder, + getU64Encoder, +} from "@solana/kit"; +import { getLockupDecoder, getLockupEncoder } from "./index.js"; + +export interface DepositEntry { + lockup: Lockup; + amountDepositedNative: bigint; + amountInitiallyLockedNative: bigint; + isUsed: boolean; + allowClawback: boolean; + votingMintConfigIdx: number; + padding: number[]; +} + +export interface DepositEntryArgs { + lockup: LockupArgs; + amountDepositedNative: number | bigint; + amountInitiallyLockedNative: number | bigint; + isUsed: boolean; + allowClawback: boolean; + votingMintConfigIdx: number; + padding: number[]; +} + +export function getDepositEntryEncoder(): FixedSizeEncoder { + return getStructEncoder([ + ["lockup", getLockupEncoder()], + ["amountDepositedNative", getU64Encoder()], + ["amountInitiallyLockedNative", getU64Encoder()], + ["isUsed", getBooleanEncoder()], + ["allowClawback", getBooleanEncoder()], + ["votingMintConfigIdx", getU8Encoder()], + ["padding", getArrayEncoder(getU8Encoder(), { size: 13 })], + ]); +} + +export function getDepositEntryDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ["lockup", getLockupDecoder()], + ["amountDepositedNative", getU64Decoder()], + ["amountInitiallyLockedNative", getU64Decoder()], + ["isUsed", getBooleanDecoder()], + ["allowClawback", getBooleanDecoder()], + ["votingMintConfigIdx", getU8Decoder()], + ["padding", getArrayDecoder(getU8Decoder(), { size: 13 })], + ]); +} + +export function getDepositEntryCodec(): FixedSizeCodec< + DepositEntryArgs, + DepositEntry +> { + return combineCodec(getDepositEntryEncoder(), getDepositEntryDecoder()); +} diff --git a/clients/voter-stake-registry/src/generated/types/index.ts b/clients/voter-stake-registry/src/generated/types/index.ts new file mode 100644 index 00000000..3633f723 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/types/index.ts @@ -0,0 +1,12 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +export * from "./depositEntry.js"; +export * from "./lockup.js"; +export * from "./lockupKind.js"; +export * from "./votingMintConfig.js"; diff --git a/clients/voter-stake-registry/src/generated/types/lockup.ts b/clients/voter-stake-registry/src/generated/types/lockup.ts new file mode 100644 index 00000000..eb99b886 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/types/lockup.ts @@ -0,0 +1,62 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + FixedSizeCodec, + FixedSizeDecoder, + FixedSizeEncoder, +} from "@solana/kit"; +import type { LockupKind, LockupKindArgs } from "./index.js"; +import { + combineCodec, + getArrayDecoder, + getArrayEncoder, + getI64Decoder, + getI64Encoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, +} from "@solana/kit"; +import { getLockupKindDecoder, getLockupKindEncoder } from "./index.js"; + +export interface Lockup { + startTs: bigint; + endTs: bigint; + kind: LockupKind; + padding: number[]; +} + +export interface LockupArgs { + startTs: number | bigint; + endTs: number | bigint; + kind: LockupKindArgs; + padding: number[]; +} + +export function getLockupEncoder(): FixedSizeEncoder { + return getStructEncoder([ + ["startTs", getI64Encoder()], + ["endTs", getI64Encoder()], + ["kind", getLockupKindEncoder()], + ["padding", getArrayEncoder(getU8Encoder(), { size: 15 })], + ]); +} + +export function getLockupDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ["startTs", getI64Decoder()], + ["endTs", getI64Decoder()], + ["kind", getLockupKindDecoder()], + ["padding", getArrayDecoder(getU8Decoder(), { size: 15 })], + ]); +} + +export function getLockupCodec(): FixedSizeCodec { + return combineCodec(getLockupEncoder(), getLockupDecoder()); +} diff --git a/clients/voter-stake-registry/src/generated/types/lockupKind.ts b/clients/voter-stake-registry/src/generated/types/lockupKind.ts new file mode 100644 index 00000000..22410ab0 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/types/lockupKind.ts @@ -0,0 +1,39 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + FixedSizeCodec, + FixedSizeDecoder, + FixedSizeEncoder, +} from "@solana/kit"; +import { combineCodec, getEnumDecoder, getEnumEncoder } from "@solana/kit"; + +export enum LockupKind { + None = 0, + Daily = 1, + Monthly = 2, + Cliff = 3, + Constant = 4, +} + +export type LockupKindArgs = LockupKind; + +export function getLockupKindEncoder(): FixedSizeEncoder { + return getEnumEncoder(LockupKind); +} + +export function getLockupKindDecoder(): FixedSizeDecoder { + return getEnumDecoder(LockupKind); +} + +export function getLockupKindCodec(): FixedSizeCodec< + LockupKindArgs, + LockupKind +> { + return combineCodec(getLockupKindEncoder(), getLockupKindDecoder()); +} diff --git a/clients/voter-stake-registry/src/generated/types/votingMintConfig.ts b/clients/voter-stake-registry/src/generated/types/votingMintConfig.ts new file mode 100644 index 00000000..9026c845 --- /dev/null +++ b/clients/voter-stake-registry/src/generated/types/votingMintConfig.ts @@ -0,0 +1,83 @@ +/** + * 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. + * + * @see https://github.com/codama-idl/codama + */ + +import type { + Address, + FixedSizeCodec, + FixedSizeDecoder, + FixedSizeEncoder, +} from "@solana/kit"; +import { + combineCodec, + getAddressDecoder, + getAddressEncoder, + getArrayDecoder, + getArrayEncoder, + getI8Decoder, + getI8Encoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + getU64Decoder, + getU64Encoder, +} from "@solana/kit"; + +export interface VotingMintConfig { + mint: Address; + grantAuthority: Address; + depositScaledFactor: bigint; + lockupScaledFactor: bigint; + lockupSaturationSecs: bigint; + digitShift: number; + padding: number[]; +} + +export interface VotingMintConfigArgs { + mint: Address; + grantAuthority: Address; + depositScaledFactor: number | bigint; + lockupScaledFactor: number | bigint; + lockupSaturationSecs: number | bigint; + digitShift: number; + padding: number[]; +} + +export function getVotingMintConfigEncoder(): FixedSizeEncoder { + return getStructEncoder([ + ["mint", getAddressEncoder()], + ["grantAuthority", getAddressEncoder()], + ["depositScaledFactor", getU64Encoder()], + ["lockupScaledFactor", getU64Encoder()], + ["lockupSaturationSecs", getU64Encoder()], + ["digitShift", getI8Encoder()], + ["padding", getArrayEncoder(getU8Encoder(), { size: 31 })], + ]); +} + +export function getVotingMintConfigDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ["mint", getAddressDecoder()], + ["grantAuthority", getAddressDecoder()], + ["depositScaledFactor", getU64Decoder()], + ["lockupScaledFactor", getU64Decoder()], + ["lockupSaturationSecs", getU64Decoder()], + ["digitShift", getI8Decoder()], + ["padding", getArrayDecoder(getU8Decoder(), { size: 31 })], + ]); +} + +export function getVotingMintConfigCodec(): FixedSizeCodec< + VotingMintConfigArgs, + VotingMintConfig +> { + return combineCodec( + getVotingMintConfigEncoder(), + getVotingMintConfigDecoder(), + ); +} diff --git a/clients/voter-stake-registry/src/index.ts b/clients/voter-stake-registry/src/index.ts new file mode 100644 index 00000000..9248f57d --- /dev/null +++ b/clients/voter-stake-registry/src/index.ts @@ -0,0 +1,8 @@ +/** + * @macalinao/clients-spl-governance + * + * TypeScript client for the SPL Governance program. + * Generated using Codama with full ESM support. + */ + +export * from "./generated/index.js"; diff --git a/clients/voter-stake-registry/tsconfig.json b/clients/voter-stake-registry/tsconfig.json new file mode 100644 index 00000000..e528d933 --- /dev/null +++ b/clients/voter-stake-registry/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "@macalinao/tsconfig/tsconfig.base.json" +} diff --git a/packages/coda-visitors/README.md b/packages/coda-visitors/README.md new file mode 100644 index 00000000..6644df40 --- /dev/null +++ b/packages/coda-visitors/README.md @@ -0,0 +1,72 @@ +# @macalinao/coda-visitors + +[![npm version](https://img.shields.io/npm/v/@macalinao/coda-visitors.svg)](https://www.npmjs.com/package/@macalinao/coda-visitors) + +Additional Codama visitors for enhanced code generation with Coda. + +## Installation + +```bash +bun add @macalinao/coda-visitors +``` + +## Visitors + +### addNodesVisitor + +Adds nodes (accounts, instructions, defined types, errors, PDAs) to existing programs in the Codama AST. + +```typescript +import { addNodesVisitor } from "@macalinao/coda-visitors"; +import { accountNode } from "codama"; + +const visitor = addNodesVisitor({ + myProgram: { + accounts: [ + accountNode({ + name: "customAccount", + // ... account configuration + }) + ], + instructions: [ + // Add custom instructions + ], + definedTypes: [ + // Add custom types + ], + errors: [ + // Add custom errors + ], + pdas: [ + // Add custom PDAs + ] + } +}); +``` + +## Usage with Coda + +This visitor is commonly used in `coda.config.mjs` to extend IDL-generated programs: + +```javascript +import { defineConfig } from "@macalinao/coda"; +import { addNodesVisitor } from "@macalinao/coda-visitors"; + +export default defineConfig({ + visitors: [ + addNodesVisitor({ + voterStakeRegistry: { + accounts: [ + // Add custom accounts not in IDL + ] + } + }) + ] +}); +``` + +## License + +Copyright © 2025 Ian Macalinao + +Licensed under the Apache License, Version 2.0 \ No newline at end of file diff --git a/packages/coda-visitors/eslint.config.js b/packages/coda-visitors/eslint.config.js new file mode 100644 index 00000000..f3d4a91f --- /dev/null +++ b/packages/coda-visitors/eslint.config.js @@ -0,0 +1,15 @@ +import { configs } from "@macalinao/eslint-config"; + +export default [ + ...configs.fast, + { + languageOptions: { + parserOptions: { + tsconfigRootDir: import.meta.dirname, + }, + }, + }, + { + ignores: ["**/*.test.ts", "**/*.test.tsx", "dist/**"], + }, +]; diff --git a/packages/coda-visitors/package.json b/packages/coda-visitors/package.json new file mode 100644 index 00000000..d95a8c41 --- /dev/null +++ b/packages/coda-visitors/package.json @@ -0,0 +1,56 @@ +{ + "name": "@macalinao/coda-visitors", + "version": "0.1.0", + "description": "Additional Codama visitors for enhanced code generation with Coda", + "type": "module", + "sideEffects": false, + "author": "Ian Macalinao ", + "homepage": "https://coda.ianm.com", + "license": "Apache-2.0", + "keywords": [ + "codama", + "coda", + "solana", + "anchor", + "idl", + "visitor", + "ast", + "nodes", + "typescript", + "ian-macalinao" + ], + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/index.js", + "types": "./dist/index.d.ts" + } + }, + "files": [ + "dist/", + "src/" + ], + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/macalinao/coda.git", + "directory": "packages/coda-visitors" + }, + "scripts": { + "build": "tsc", + "clean": "rm -fr dist/", + "lint": "eslint . --cache" + }, + "dependencies": { + "codama": "catalog:" + }, + "devDependencies": { + "@macalinao/eslint-config": "catalog:", + "@macalinao/tsconfig": "catalog:", + "eslint": "catalog:", + "typescript": "catalog:" + } +} diff --git a/packages/coda-visitors/src/add-nodes-visitor.ts b/packages/coda-visitors/src/add-nodes-visitor.ts new file mode 100644 index 00000000..c67d64cd --- /dev/null +++ b/packages/coda-visitors/src/add-nodes-visitor.ts @@ -0,0 +1,66 @@ +import type { + BottomUpNodeTransformerWithSelector, + ProgramNodeInput, +} from "codama"; +import { + assertIsNode, + bottomUpTransformerVisitor, + camelCase, + programLinkNode, + programNode, +} from "codama"; + +export type ProgramAdditions = Partial; + +/** + * Adds nodes to programs. + * @param map + * @returns + */ +export function addNodesVisitor(map: Record) { + return bottomUpTransformerVisitor( + Object.entries(map).flatMap( + ([name, updates]): BottomUpNodeTransformerWithSelector[] => { + const newName = + typeof updates === "object" && "name" in updates && updates.name + ? camelCase(updates.name) + : undefined; + + const transformers: BottomUpNodeTransformerWithSelector[] = [ + { + select: `[programNode]${name}`, + transform: (node) => { + assertIsNode(node, "programNode"); + return programNode({ + ...node, + accounts: [...node.accounts, ...(updates.accounts ?? [])], + instructions: [ + ...node.instructions, + ...(updates.instructions ?? []), + ], + definedTypes: [ + ...node.definedTypes, + ...(updates.definedTypes ?? []), + ], + errors: [...node.errors, ...(updates.errors ?? [])], + pdas: [...node.pdas, ...(updates.pdas ?? [])], + }); + }, + }, + ]; + + if (newName) { + transformers.push({ + select: `[programLinkNode]${name}`, + transform: (node) => { + assertIsNode(node, "programLinkNode"); + return programLinkNode(newName); + }, + }); + } + + return transformers; + }, + ), + ); +} diff --git a/packages/coda-visitors/src/index.ts b/packages/coda-visitors/src/index.ts new file mode 100644 index 00000000..5bcb8edc --- /dev/null +++ b/packages/coda-visitors/src/index.ts @@ -0,0 +1 @@ +export * from "./add-nodes-visitor.js"; diff --git a/packages/coda-visitors/tsconfig.json b/packages/coda-visitors/tsconfig.json new file mode 100644 index 00000000..4807bb6e --- /dev/null +++ b/packages/coda-visitors/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "@macalinao/tsconfig/tsconfig.base.json", + "compilerOptions": { + "isolatedDeclarations": false, + "types": ["bun-types"] + }, + "exclude": ["src/**/*.test.ts", "dist/**"] +} diff --git a/packages/coda/package.json b/packages/coda/package.json index d5a534f8..5d7c6ea3 100644 --- a/packages/coda/package.json +++ b/packages/coda/package.json @@ -50,6 +50,7 @@ "dependencies": { "@codama/nodes-from-anchor": "catalog:", "@codama/renderers-rust": "^1.2.7", + "@macalinao/coda-visitors": "workspace:*", "@macalinao/codama-nodes-from-anchor-x": "workspace:*", "@macalinao/codama-rename-visitor": "workspace:*", "@macalinao/codama-renderers-js-esm": "workspace:*", diff --git a/packages/coda/src/bin/cli.ts b/packages/coda/src/bin/cli.ts index cdeeb6e3..6d7f11bb 100644 --- a/packages/coda/src/bin/cli.ts +++ b/packages/coda/src/bin/cli.ts @@ -1,6 +1,6 @@ #!/usr/bin/env node import type { Visitor } from "codama"; -import { writeFile } from "node:fs/promises"; +import { rm, writeFile } from "node:fs/promises"; import { resolve } from "node:path"; import { renderVisitor as renderRustVisitor } from "@codama/renderers-rust"; import { renderESMTypeScriptVisitor } from "@macalinao/codama-renderers-js-esm"; @@ -30,6 +30,12 @@ program const { codama, config } = await processIdls(options); const outputPath = resolve(config.outputDir ?? "./src/generated/"); + // Delete the existing directory if it exists + if (await fileExists(outputPath)) { + console.log(`Removing existing directory: ${outputPath}`); + await rm(outputPath, { recursive: true, force: true }); + } + // Apply the ESM TypeScript visitor console.log(`Generating client to ${outputPath}...`); codama.accept(renderESMTypeScriptVisitor(outputPath)); @@ -88,6 +94,12 @@ program const { codama, config } = await processIdls(options); const outputPath = resolve(config.rustOutputDir ?? "./rust"); + // Delete the existing directory if it exists + if (await fileExists(outputPath)) { + console.log(`Removing existing directory: ${outputPath}`); + await rm(outputPath, { recursive: true, force: true }); + } + // Apply the Rust visitor console.log(`Generating Rust client to ${outputPath}...`); codama.accept( @@ -119,6 +131,12 @@ program const { codama, config } = await processIdls(options); const outputPath = resolve(config.docs?.path ?? "./docs"); + // Delete the existing directory if it exists + if (await fileExists(outputPath)) { + console.log(`Removing existing directory: ${outputPath}`); + await rm(outputPath, { recursive: true, force: true }); + } + // Apply the markdown visitor with options from config console.log(`Generating documentation to ${outputPath}...`); const markdownOptions = { diff --git a/packages/coda/src/index.ts b/packages/coda/src/index.ts index f4638656..7d3a1a46 100644 --- a/packages/coda/src/index.ts +++ b/packages/coda/src/index.ts @@ -1,6 +1,7 @@ // Re-export useful visitors and utilities export type { CodaConfig, VisitorContext } from "./config.js"; +export * from "@macalinao/coda-visitors"; export { renameVisitor } from "@macalinao/codama-rename-visitor"; export { ESM_DEPENDENCY_MAP,