/** * 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 { combineCodec, fixDecoderSize, fixEncoderSize, getBytesDecoder, getBytesEncoder, getStructDecoder, getStructEncoder, SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS, SolanaError, transformEncoder, type AccountMeta, type AccountSignerMeta, type Address, type FixedSizeCodec, type FixedSizeDecoder, type FixedSizeEncoder, type Instruction, type InstructionWithAccounts, type InstructionWithData, type ReadonlyAccount, type ReadonlyUint8Array, type TransactionSigner, type WritableAccount, type WritableSignerAccount, } from '@solana/kit'; import { getAccountMetaFactory, type ResolvedInstructionAccount, } from '@solana/program-client-core'; import { SAGE_PROGRAM_ADDRESS } from '../programs'; export const COMPLETE_QUEST_DISCRIMINATOR = new Uint8Array([ 96, 34, 101, 232, 164, 246, 150, 61, ]); export function getCompleteQuestDiscriminatorBytes() { return fixEncoderSize(getBytesEncoder(), 8).encode( COMPLETE_QUEST_DISCRIMINATOR, ); } export type CompleteQuestInstruction< TProgram extends string = typeof SAGE_PROGRAM_ADDRESS, TAccountFunder extends string | AccountMeta = string, TAccountGame extends string | AccountMeta = string, TAccountStarbasePlayer extends string | AccountMeta = string, TAccountQuestProcess extends string | AccountMeta = string, TAccountRoster extends string | AccountMeta = string, TRemainingAccounts extends readonly AccountMeta[] = [], > = Instruction & InstructionWithData & InstructionWithAccounts< [ TAccountFunder extends string ? WritableSignerAccount & AccountSignerMeta : TAccountFunder, TAccountGame extends string ? ReadonlyAccount : TAccountGame, TAccountStarbasePlayer extends string ? WritableAccount : TAccountStarbasePlayer, TAccountQuestProcess extends string ? WritableAccount : TAccountQuestProcess, TAccountRoster extends string ? WritableAccount : TAccountRoster, ...TRemainingAccounts, ] >; export type CompleteQuestInstructionData = { discriminator: ReadonlyUint8Array; }; export type CompleteQuestInstructionDataArgs = {}; export function getCompleteQuestInstructionDataEncoder(): FixedSizeEncoder { return transformEncoder( getStructEncoder([['discriminator', fixEncoderSize(getBytesEncoder(), 8)]]), (value) => ({ ...value, discriminator: COMPLETE_QUEST_DISCRIMINATOR }), ); } export function getCompleteQuestInstructionDataDecoder(): FixedSizeDecoder { return getStructDecoder([ ['discriminator', fixDecoderSize(getBytesDecoder(), 8)], ]); } export function getCompleteQuestInstructionDataCodec(): FixedSizeCodec< CompleteQuestInstructionDataArgs, CompleteQuestInstructionData > { return combineCodec( getCompleteQuestInstructionDataEncoder(), getCompleteQuestInstructionDataDecoder(), ); } export type CompleteQuestInput< TAccountFunder extends string = string, TAccountGame extends string = string, TAccountStarbasePlayer extends string = string, TAccountQuestProcess extends string = string, TAccountRoster extends string = string, > = { /** * The funder for any Solana rent payments AND the rent-refund recipient for the closed * `QuestProcess` (the `CloseAccount` cleanup requires a registered recipient — the * cranker keeps the freed rent, the standard permissionless-crank incentive). The ONLY * signer (generic_fleet_state_handler_rs:22-23). Any cranker may settle an elapsed quest. */ funder: TransactionSigner; /** The game account (flag gate). */ game: Address; /** * The starbase-player whose `busy_crew` the quest reserved — cross-checked against the * process's stored `starbase_player` key. `Mut` for the `reconcile(-N)` release. * ASSUMES (SAGE): a starbase-player account form addressable without the owner's profile * (the crank has no profile); the composite/validated form keyed by the process's stored * key. Modeled as the validated starbase-player; the integrator binds the exact * crank-friendly account. The auth binding is the `quest_process` cross-check below * (`#[validate(arg = (self.starbase_player.key_for(),))]`), NOT a profile — so this is a raw * `Mut>` (no `ValidatedStarbasePlayer`, which needs a profile-derived * validation arg the permissionless crank cannot supply). */ starbasePlayer: Address; /** * The quest process being settled — validated against the starbase-player it stored * (the `KeyForFromAccountSet` cross-check, quest_rs:82-104), and **closed** on success * (the no-leak guarantee — install_rs:69). `Mut` + `CloseAccount` cleanup. */ questProcess: Address; /** * The owner's pinned reward roster page (`QuestProcess.reward_page`). Required when * `reward_xp > 0`; omitted only for reward-less quests. */ roster?: Address; }; export function getCompleteQuestInstruction< TAccountFunder extends string, TAccountGame extends string, TAccountStarbasePlayer extends string, TAccountQuestProcess extends string, TAccountRoster extends string, TProgramAddress extends Address = typeof SAGE_PROGRAM_ADDRESS, >( input: CompleteQuestInput< TAccountFunder, TAccountGame, TAccountStarbasePlayer, TAccountQuestProcess, TAccountRoster >, config?: { programAddress?: TProgramAddress }, ): CompleteQuestInstruction< TProgramAddress, TAccountFunder, TAccountGame, TAccountStarbasePlayer, TAccountQuestProcess, TAccountRoster > { // Program address. const programAddress = config?.programAddress ?? SAGE_PROGRAM_ADDRESS; // Original accounts. const originalAccounts = { funder: { value: input.funder ?? null, isWritable: true }, game: { value: input.game ?? null, isWritable: false }, starbasePlayer: { value: input.starbasePlayer ?? null, isWritable: true }, questProcess: { value: input.questProcess ?? null, isWritable: true }, roster: { value: input.roster ?? null, isWritable: true }, }; const accounts = originalAccounts as Record< keyof typeof originalAccounts, ResolvedInstructionAccount >; const getAccountMeta = getAccountMetaFactory(programAddress, 'programId'); return Object.freeze({ accounts: [ getAccountMeta('funder', accounts.funder), getAccountMeta('game', accounts.game), getAccountMeta('starbasePlayer', accounts.starbasePlayer), getAccountMeta('questProcess', accounts.questProcess), getAccountMeta('roster', accounts.roster), ], data: getCompleteQuestInstructionDataEncoder().encode({}), programAddress, } as CompleteQuestInstruction< TProgramAddress, TAccountFunder, TAccountGame, TAccountStarbasePlayer, TAccountQuestProcess, TAccountRoster >); } export type ParsedCompleteQuestInstruction< TProgram extends string = typeof SAGE_PROGRAM_ADDRESS, TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], > = { programAddress: Address; accounts: { /** * The funder for any Solana rent payments AND the rent-refund recipient for the closed * `QuestProcess` (the `CloseAccount` cleanup requires a registered recipient — the * cranker keeps the freed rent, the standard permissionless-crank incentive). The ONLY * signer (generic_fleet_state_handler_rs:22-23). Any cranker may settle an elapsed quest. */ funder: TAccountMetas[0]; /** The game account (flag gate). */ game: TAccountMetas[1]; /** * The starbase-player whose `busy_crew` the quest reserved — cross-checked against the * process's stored `starbase_player` key. `Mut` for the `reconcile(-N)` release. * ASSUMES (SAGE): a starbase-player account form addressable without the owner's profile * (the crank has no profile); the composite/validated form keyed by the process's stored * key. Modeled as the validated starbase-player; the integrator binds the exact * crank-friendly account. The auth binding is the `quest_process` cross-check below * (`#[validate(arg = (self.starbase_player.key_for(),))]`), NOT a profile — so this is a raw * `Mut>` (no `ValidatedStarbasePlayer`, which needs a profile-derived * validation arg the permissionless crank cannot supply). */ starbasePlayer: TAccountMetas[2]; /** * The quest process being settled — validated against the starbase-player it stored * (the `KeyForFromAccountSet` cross-check, quest_rs:82-104), and **closed** on success * (the no-leak guarantee — install_rs:69). `Mut` + `CloseAccount` cleanup. */ questProcess: TAccountMetas[3]; /** * The owner's pinned reward roster page (`QuestProcess.reward_page`). Required when * `reward_xp > 0`; omitted only for reward-less quests. */ roster?: TAccountMetas[4] | undefined; }; data: CompleteQuestInstructionData; }; export function parseCompleteQuestInstruction< TProgram extends string, TAccountMetas extends readonly AccountMeta[], >( instruction: Instruction & InstructionWithAccounts & InstructionWithData, ): ParsedCompleteQuestInstruction { if (instruction.accounts.length < 5) { throw new SolanaError( SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS, { actualAccountMetas: instruction.accounts.length, expectedAccountMetas: 5, }, ); } let accountIndex = 0; const getNextAccount = () => { const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; accountIndex += 1; return accountMeta; }; const getNextOptionalAccount = () => { const accountMeta = getNextAccount(); return accountMeta.address === SAGE_PROGRAM_ADDRESS ? undefined : accountMeta; }; return { programAddress: instruction.programAddress, accounts: { funder: getNextAccount(), game: getNextAccount(), starbasePlayer: getNextAccount(), questProcess: getNextAccount(), roster: getNextOptionalAccount(), }, data: getCompleteQuestInstructionDataDecoder().decode(instruction.data), }; }