/** * 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, getAddressEncoder, getBytesDecoder, getBytesEncoder, getI16Decoder, getI16Encoder, getI64Decoder, getI64Encoder, getProgramDerivedAddress, getStructDecoder, getStructEncoder, getU16Decoder, getU16Encoder, getU32Decoder, getU32Encoder, getU64Decoder, getU64Encoder, getU8Decoder, getU8Encoder, 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 ReadonlySignerAccount, type ReadonlyUint8Array, type TransactionSigner, type WritableAccount, type WritableSignerAccount, } from '@solana/kit'; import { getAccountMetaFactory, getAddressFromResolvedInstructionAccount, type ResolvedInstructionAccount, } from '@solana/program-client-core'; import { SAGE_PROGRAM_ADDRESS } from '../programs'; import { getCargoIdDecoder, getCargoIdEncoder, type CargoId, type CargoIdArgs, } from '../types'; export const START_MISSION_DISCRIMINATOR = new Uint8Array([ 220, 224, 41, 25, 46, 134, 254, 157, ]); export function getStartMissionDiscriminatorBytes() { return fixEncoderSize(getBytesEncoder(), 8).encode( START_MISSION_DISCRIMINATOR, ); } export type StartMissionInstruction< TProgram extends string = typeof SAGE_PROGRAM_ADDRESS, TAccountProfileValidationSigner extends string | AccountMeta = string, TAccountProfileValidationProfile extends string | AccountMeta = string, TAccountProfileValidationCertificate extends string | AccountMeta = string, TAccountProfileValidationProgram extends string | AccountMeta = 'C4PRoFNroxxzdgeCoM31LJjYRg7kT6ymogSTAT99iD1u', TAccountGame extends string | AccountMeta = string, TAccountSystemAndStarbasePlayerSystem extends string | AccountMeta = string, TAccountSystemAndStarbasePlayerStarbasePlayer extends | string | AccountMeta = string, TAccountMissionProcess extends string | AccountMeta = string, TAccountCharacter extends string | AccountMeta = string, TAccountStarSystem extends string | AccountMeta = string, TAccountMissionVault extends string | AccountMeta = string, TAccountRewardPool extends string | AccountMeta = string, TAccountStakeFleet extends string | AccountMeta = string, TAccountRegionTracker extends string | AccountMeta = string, TAccountOutlawFlag extends string | AccountMeta = string, TAccountSystemProgram extends string | AccountMeta = '11111111111111111111111111111111', TRemainingAccounts extends readonly AccountMeta[] = [], > = Instruction & InstructionWithData & InstructionWithAccounts< [ TAccountProfileValidationSigner extends string ? ReadonlySignerAccount & AccountSignerMeta : TAccountProfileValidationSigner, TAccountProfileValidationProfile extends string ? WritableAccount : TAccountProfileValidationProfile, TAccountProfileValidationCertificate extends string ? ReadonlyAccount : TAccountProfileValidationCertificate, TAccountProfileValidationProgram extends string ? ReadonlyAccount : TAccountProfileValidationProgram, TAccountGame extends string ? ReadonlyAccount : TAccountGame, TAccountSystemAndStarbasePlayerSystem extends string ? ReadonlyAccount : TAccountSystemAndStarbasePlayerSystem, TAccountSystemAndStarbasePlayerStarbasePlayer extends string ? WritableAccount : TAccountSystemAndStarbasePlayerStarbasePlayer, TAccountMissionProcess extends string ? WritableSignerAccount & AccountSignerMeta : TAccountMissionProcess, TAccountCharacter extends string ? WritableAccount : TAccountCharacter, TAccountStarSystem extends string ? ReadonlyAccount : TAccountStarSystem, TAccountMissionVault extends string ? WritableAccount : TAccountMissionVault, TAccountRewardPool extends string ? ReadonlyAccount : TAccountRewardPool, TAccountStakeFleet extends string ? WritableAccount : TAccountStakeFleet, TAccountRegionTracker extends string ? ReadonlyAccount : TAccountRegionTracker, TAccountOutlawFlag extends string ? ReadonlyAccount : TAccountOutlawFlag, TAccountSystemProgram extends string ? ReadonlyAccount : TAccountSystemProgram, ...TRemainingAccounts, ] >; export type StartMissionInstructionData = { discriminator: ReadonlyUint8Array; keyIndex: number; crew: number; duration: bigint; rewardPage: number; /** WIDENED u8 -> u16 vs StartQuest (BUILD BLOCKER #0). */ rewardXp: number; /** the ATLAS (Floyds) paid on win (the catalog's tier-scaled winAtlas); breaker-capped at settle. */ rewardAtlas: bigint; /** THE committed success target (0..=10000), computed off-chain by `formula.js` (parity). */ successBps: number; /** committed sector impacts (off-chain PRE-SCALED; settle folds exactly one into the RegionOrderAnchor). */ sectorWinDelta: number; sectorLossDelta: number; missionTemplateId: number; lootTableId: number; stakeAtlas: bigint; /** 0 = no resource stake. Multi-resource stakes pass extra legs as remaining_accounts (vault map). */ stakeResourceId: CargoId; stakeResourceQty: bigint; /** * Phase-2 faction-stance (doc 180): 0=INCUMBENT intent, 1=CHALLENGER intent, 255=NONE (untagged). * Whether this resolves to support/oppose/treason is DERIVED at settle (stance_side × incumbent × base). */ stanceSide: number; }; export type StartMissionInstructionDataArgs = { keyIndex: number; crew: number; duration: number | bigint; rewardPage: number; /** WIDENED u8 -> u16 vs StartQuest (BUILD BLOCKER #0). */ rewardXp: number; /** the ATLAS (Floyds) paid on win (the catalog's tier-scaled winAtlas); breaker-capped at settle. */ rewardAtlas: number | bigint; /** THE committed success target (0..=10000), computed off-chain by `formula.js` (parity). */ successBps: number; /** committed sector impacts (off-chain PRE-SCALED; settle folds exactly one into the RegionOrderAnchor). */ sectorWinDelta: number; sectorLossDelta: number; missionTemplateId: number; lootTableId: number; stakeAtlas: number | bigint; /** 0 = no resource stake. Multi-resource stakes pass extra legs as remaining_accounts (vault map). */ stakeResourceId: CargoIdArgs; stakeResourceQty: number | bigint; /** * Phase-2 faction-stance (doc 180): 0=INCUMBENT intent, 1=CHALLENGER intent, 255=NONE (untagged). * Whether this resolves to support/oppose/treason is DERIVED at settle (stance_side × incumbent × base). */ stanceSide: number; }; export function getStartMissionInstructionDataEncoder(): FixedSizeEncoder { return transformEncoder( getStructEncoder([ ['discriminator', fixEncoderSize(getBytesEncoder(), 8)], ['keyIndex', getU16Encoder()], ['crew', getU16Encoder()], ['duration', getI64Encoder()], ['rewardPage', getU16Encoder()], ['rewardXp', getU16Encoder()], ['rewardAtlas', getU64Encoder()], ['successBps', getU16Encoder()], ['sectorWinDelta', getI16Encoder()], ['sectorLossDelta', getI16Encoder()], ['missionTemplateId', getU32Encoder()], ['lootTableId', getU32Encoder()], ['stakeAtlas', getU64Encoder()], ['stakeResourceId', getCargoIdEncoder()], ['stakeResourceQty', getU64Encoder()], ['stanceSide', getU8Encoder()], ]), (value) => ({ ...value, discriminator: START_MISSION_DISCRIMINATOR }), ); } export function getStartMissionInstructionDataDecoder(): FixedSizeDecoder { return getStructDecoder([ ['discriminator', fixDecoderSize(getBytesDecoder(), 8)], ['keyIndex', getU16Decoder()], ['crew', getU16Decoder()], ['duration', getI64Decoder()], ['rewardPage', getU16Decoder()], ['rewardXp', getU16Decoder()], ['rewardAtlas', getU64Decoder()], ['successBps', getU16Decoder()], ['sectorWinDelta', getI16Decoder()], ['sectorLossDelta', getI16Decoder()], ['missionTemplateId', getU32Decoder()], ['lootTableId', getU32Decoder()], ['stakeAtlas', getU64Decoder()], ['stakeResourceId', getCargoIdDecoder()], ['stakeResourceQty', getU64Decoder()], ['stanceSide', getU8Decoder()], ]); } export function getStartMissionInstructionDataCodec(): FixedSizeCodec< StartMissionInstructionDataArgs, StartMissionInstructionData > { return combineCodec( getStartMissionInstructionDataEncoder(), getStartMissionInstructionDataDecoder(), ); } export type StartMissionAsyncInput< TAccountProfileValidationSigner extends string = string, TAccountProfileValidationProfile extends string = string, TAccountProfileValidationCertificate extends string = string, TAccountProfileValidationProgram extends string = string, TAccountGame extends string = string, TAccountSystemAndStarbasePlayerSystem extends string = string, TAccountSystemAndStarbasePlayerStarbasePlayer extends string = string, TAccountMissionProcess extends string = string, TAccountCharacter extends string = string, TAccountStarSystem extends string = string, TAccountMissionVault extends string = string, TAccountRewardPool extends string = string, TAccountStakeFleet extends string = string, TAccountRegionTracker extends string = string, TAccountOutlawFlag extends string = string, TAccountSystemProgram extends string = string, > = { profileValidationSigner: TransactionSigner; profileValidationProfile: Address; profileValidationCertificate?: Address; profileValidationProgram?: Address; game: Address; /** The [`StarSystem`] account */ systemAndStarbasePlayerSystem: Address; /** The [`StarbasePlayer`] Account */ systemAndStarbasePlayerStarbasePlayer: Address; /** The NEW mission process (keypair-funded, closed on terminal call) — clone of `quest_process`. */ missionProcess: TransactionSigner; /** * The owner's character — the in-game ATLAS source (`character.atlas`, the `AtlasBalance` ledger, * per `trade.rs`). Validated against `profile_validation.profile` + `game` (PR#732 house type). */ character?: Address; /** * The system the starbase-player is in — asserted `== sbp.system`, read `region: Option` * to PIN `MissionProcess.region_id` (never caller-chosen; 10 §2.1 step 6, option a). */ starSystem: Address; /** The per-mission escrow PDA, seeds `(b"MissionVault", mission_process.key)`. */ missionVault: Address; /** The emissions-fed treasury this mission's WIN draws from — pinned into the process. */ rewardPool: Address; /** * (v1: ATLAS-only) Reserved for a future on-chain RESOURCE stake. StartMission rejects * `stake_resource_qty > 0` in v1, so this trailing optional account is currently always omitted; it is * kept in the set for forward-compatibility once the stake-return path is designed. Validated against * game + owner profile (same arg shape scan.rs uses for its fleet); when None the validate is a no-op. */ stakeFleet?: Address; /** * Phase-2: the region tracker — read-only, to pin the sector's RIGHTFUL incumbent * (`regions[region_id].owner`) TRUSTLESSLY at start (never a caller arg). Same validate arg shape as * scan.rs's region_tracker. */ regionTracker: Address; /** * Phase-2: the actor's OutlawFlag for `base_faction` (APPEND-LAST optional). Omitted (program-id * sentinel) ⇒ not outlaw ⇒ own-faction opposition stays BLOCKED (fail-closed). `AccountValidate` * checks the profile match; the handler re-derives the (profile, base_faction) PDA + key-checks it * (base_faction isn't known at validate). Read-only — `StartMission` only SNAPSHOTS the resolved value. */ outlawFlag?: Address; systemProgram?: Address; keyIndex: StartMissionInstructionDataArgs['keyIndex']; crew: StartMissionInstructionDataArgs['crew']; duration: StartMissionInstructionDataArgs['duration']; rewardPage: StartMissionInstructionDataArgs['rewardPage']; rewardXp: StartMissionInstructionDataArgs['rewardXp']; rewardAtlas: StartMissionInstructionDataArgs['rewardAtlas']; successBps: StartMissionInstructionDataArgs['successBps']; sectorWinDelta: StartMissionInstructionDataArgs['sectorWinDelta']; sectorLossDelta: StartMissionInstructionDataArgs['sectorLossDelta']; missionTemplateId: StartMissionInstructionDataArgs['missionTemplateId']; lootTableId: StartMissionInstructionDataArgs['lootTableId']; stakeAtlas: StartMissionInstructionDataArgs['stakeAtlas']; stakeResourceId: StartMissionInstructionDataArgs['stakeResourceId']; stakeResourceQty: StartMissionInstructionDataArgs['stakeResourceQty']; stanceSide: StartMissionInstructionDataArgs['stanceSide']; }; export async function getStartMissionInstructionAsync< TAccountProfileValidationSigner extends string, TAccountProfileValidationProfile extends string, TAccountProfileValidationCertificate extends string, TAccountProfileValidationProgram extends string, TAccountGame extends string, TAccountSystemAndStarbasePlayerSystem extends string, TAccountSystemAndStarbasePlayerStarbasePlayer extends string, TAccountMissionProcess extends string, TAccountCharacter extends string, TAccountStarSystem extends string, TAccountMissionVault extends string, TAccountRewardPool extends string, TAccountStakeFleet extends string, TAccountRegionTracker extends string, TAccountOutlawFlag extends string, TAccountSystemProgram extends string, TProgramAddress extends Address = typeof SAGE_PROGRAM_ADDRESS, >( input: StartMissionAsyncInput< TAccountProfileValidationSigner, TAccountProfileValidationProfile, TAccountProfileValidationCertificate, TAccountProfileValidationProgram, TAccountGame, TAccountSystemAndStarbasePlayerSystem, TAccountSystemAndStarbasePlayerStarbasePlayer, TAccountMissionProcess, TAccountCharacter, TAccountStarSystem, TAccountMissionVault, TAccountRewardPool, TAccountStakeFleet, TAccountRegionTracker, TAccountOutlawFlag, TAccountSystemProgram >, config?: { programAddress?: TProgramAddress }, ): Promise< StartMissionInstruction< TProgramAddress, TAccountProfileValidationSigner, TAccountProfileValidationProfile, TAccountProfileValidationCertificate, TAccountProfileValidationProgram, TAccountGame, TAccountSystemAndStarbasePlayerSystem, TAccountSystemAndStarbasePlayerStarbasePlayer, TAccountMissionProcess, TAccountCharacter, TAccountStarSystem, TAccountMissionVault, TAccountRewardPool, TAccountStakeFleet, TAccountRegionTracker, TAccountOutlawFlag, TAccountSystemProgram > > { // Program address. const programAddress = config?.programAddress ?? SAGE_PROGRAM_ADDRESS; // Original accounts. const originalAccounts = { profileValidationSigner: { value: input.profileValidationSigner ?? null, isWritable: false, }, profileValidationProfile: { value: input.profileValidationProfile ?? null, isWritable: true, }, profileValidationCertificate: { value: input.profileValidationCertificate ?? null, isWritable: false, }, profileValidationProgram: { value: input.profileValidationProgram ?? null, isWritable: false, }, game: { value: input.game ?? null, isWritable: false }, systemAndStarbasePlayerSystem: { value: input.systemAndStarbasePlayerSystem ?? null, isWritable: false, }, systemAndStarbasePlayerStarbasePlayer: { value: input.systemAndStarbasePlayerStarbasePlayer ?? null, isWritable: true, }, missionProcess: { value: input.missionProcess ?? null, isWritable: true }, character: { value: input.character ?? null, isWritable: true }, starSystem: { value: input.starSystem ?? null, isWritable: false }, missionVault: { value: input.missionVault ?? null, isWritable: true }, rewardPool: { value: input.rewardPool ?? null, isWritable: false }, stakeFleet: { value: input.stakeFleet ?? null, isWritable: true }, regionTracker: { value: input.regionTracker ?? null, isWritable: false }, outlawFlag: { value: input.outlawFlag ?? null, isWritable: false }, systemProgram: { value: input.systemProgram ?? null, isWritable: false }, }; const accounts = originalAccounts as Record< keyof typeof originalAccounts, ResolvedInstructionAccount >; // Original args. const args = { ...input }; // Resolve default values. if (!accounts.profileValidationProgram.value) { accounts.profileValidationProgram.value = 'C4PRoFNroxxzdgeCoM31LJjYRg7kT6ymogSTAT99iD1u' as Address<'C4PRoFNroxxzdgeCoM31LJjYRg7kT6ymogSTAT99iD1u'>; } if (!accounts.character.value) { accounts.character.value = await getProgramDerivedAddress({ programAddress, seeds: [ getBytesEncoder().encode( new Uint8Array([67, 104, 97, 114, 97, 99, 116, 101, 114]), ), getAddressEncoder().encode( getAddressFromResolvedInstructionAccount( 'profileValidationProfile', accounts.profileValidationProfile.value, ), ), getAddressEncoder().encode( getAddressFromResolvedInstructionAccount('game', accounts.game.value), ), ], }); } if (!accounts.systemProgram.value) { accounts.systemProgram.value = '11111111111111111111111111111111' as Address<'11111111111111111111111111111111'>; } const getAccountMeta = getAccountMetaFactory(programAddress, 'programId'); return Object.freeze({ accounts: [ getAccountMeta( 'profileValidationSigner', accounts.profileValidationSigner, ), getAccountMeta( 'profileValidationProfile', accounts.profileValidationProfile, ), getAccountMeta( 'profileValidationCertificate', accounts.profileValidationCertificate, ), getAccountMeta( 'profileValidationProgram', accounts.profileValidationProgram, ), getAccountMeta('game', accounts.game), getAccountMeta( 'systemAndStarbasePlayerSystem', accounts.systemAndStarbasePlayerSystem, ), getAccountMeta( 'systemAndStarbasePlayerStarbasePlayer', accounts.systemAndStarbasePlayerStarbasePlayer, ), getAccountMeta('missionProcess', accounts.missionProcess), getAccountMeta('character', accounts.character), getAccountMeta('starSystem', accounts.starSystem), getAccountMeta('missionVault', accounts.missionVault), getAccountMeta('rewardPool', accounts.rewardPool), getAccountMeta('stakeFleet', accounts.stakeFleet), getAccountMeta('regionTracker', accounts.regionTracker), getAccountMeta('outlawFlag', accounts.outlawFlag), getAccountMeta('systemProgram', accounts.systemProgram), ], data: getStartMissionInstructionDataEncoder().encode( args as StartMissionInstructionDataArgs, ), programAddress, } as StartMissionInstruction< TProgramAddress, TAccountProfileValidationSigner, TAccountProfileValidationProfile, TAccountProfileValidationCertificate, TAccountProfileValidationProgram, TAccountGame, TAccountSystemAndStarbasePlayerSystem, TAccountSystemAndStarbasePlayerStarbasePlayer, TAccountMissionProcess, TAccountCharacter, TAccountStarSystem, TAccountMissionVault, TAccountRewardPool, TAccountStakeFleet, TAccountRegionTracker, TAccountOutlawFlag, TAccountSystemProgram >); } export type StartMissionInput< TAccountProfileValidationSigner extends string = string, TAccountProfileValidationProfile extends string = string, TAccountProfileValidationCertificate extends string = string, TAccountProfileValidationProgram extends string = string, TAccountGame extends string = string, TAccountSystemAndStarbasePlayerSystem extends string = string, TAccountSystemAndStarbasePlayerStarbasePlayer extends string = string, TAccountMissionProcess extends string = string, TAccountCharacter extends string = string, TAccountStarSystem extends string = string, TAccountMissionVault extends string = string, TAccountRewardPool extends string = string, TAccountStakeFleet extends string = string, TAccountRegionTracker extends string = string, TAccountOutlawFlag extends string = string, TAccountSystemProgram extends string = string, > = { profileValidationSigner: TransactionSigner; profileValidationProfile: Address; profileValidationCertificate?: Address; profileValidationProgram?: Address; game: Address; /** The [`StarSystem`] account */ systemAndStarbasePlayerSystem: Address; /** The [`StarbasePlayer`] Account */ systemAndStarbasePlayerStarbasePlayer: Address; /** The NEW mission process (keypair-funded, closed on terminal call) — clone of `quest_process`. */ missionProcess: TransactionSigner; /** * The owner's character — the in-game ATLAS source (`character.atlas`, the `AtlasBalance` ledger, * per `trade.rs`). Validated against `profile_validation.profile` + `game` (PR#732 house type). */ character: Address; /** * The system the starbase-player is in — asserted `== sbp.system`, read `region: Option` * to PIN `MissionProcess.region_id` (never caller-chosen; 10 §2.1 step 6, option a). */ starSystem: Address; /** The per-mission escrow PDA, seeds `(b"MissionVault", mission_process.key)`. */ missionVault: Address; /** The emissions-fed treasury this mission's WIN draws from — pinned into the process. */ rewardPool: Address; /** * (v1: ATLAS-only) Reserved for a future on-chain RESOURCE stake. StartMission rejects * `stake_resource_qty > 0` in v1, so this trailing optional account is currently always omitted; it is * kept in the set for forward-compatibility once the stake-return path is designed. Validated against * game + owner profile (same arg shape scan.rs uses for its fleet); when None the validate is a no-op. */ stakeFleet?: Address; /** * Phase-2: the region tracker — read-only, to pin the sector's RIGHTFUL incumbent * (`regions[region_id].owner`) TRUSTLESSLY at start (never a caller arg). Same validate arg shape as * scan.rs's region_tracker. */ regionTracker: Address; /** * Phase-2: the actor's OutlawFlag for `base_faction` (APPEND-LAST optional). Omitted (program-id * sentinel) ⇒ not outlaw ⇒ own-faction opposition stays BLOCKED (fail-closed). `AccountValidate` * checks the profile match; the handler re-derives the (profile, base_faction) PDA + key-checks it * (base_faction isn't known at validate). Read-only — `StartMission` only SNAPSHOTS the resolved value. */ outlawFlag?: Address; systemProgram?: Address; keyIndex: StartMissionInstructionDataArgs['keyIndex']; crew: StartMissionInstructionDataArgs['crew']; duration: StartMissionInstructionDataArgs['duration']; rewardPage: StartMissionInstructionDataArgs['rewardPage']; rewardXp: StartMissionInstructionDataArgs['rewardXp']; rewardAtlas: StartMissionInstructionDataArgs['rewardAtlas']; successBps: StartMissionInstructionDataArgs['successBps']; sectorWinDelta: StartMissionInstructionDataArgs['sectorWinDelta']; sectorLossDelta: StartMissionInstructionDataArgs['sectorLossDelta']; missionTemplateId: StartMissionInstructionDataArgs['missionTemplateId']; lootTableId: StartMissionInstructionDataArgs['lootTableId']; stakeAtlas: StartMissionInstructionDataArgs['stakeAtlas']; stakeResourceId: StartMissionInstructionDataArgs['stakeResourceId']; stakeResourceQty: StartMissionInstructionDataArgs['stakeResourceQty']; stanceSide: StartMissionInstructionDataArgs['stanceSide']; }; export function getStartMissionInstruction< TAccountProfileValidationSigner extends string, TAccountProfileValidationProfile extends string, TAccountProfileValidationCertificate extends string, TAccountProfileValidationProgram extends string, TAccountGame extends string, TAccountSystemAndStarbasePlayerSystem extends string, TAccountSystemAndStarbasePlayerStarbasePlayer extends string, TAccountMissionProcess extends string, TAccountCharacter extends string, TAccountStarSystem extends string, TAccountMissionVault extends string, TAccountRewardPool extends string, TAccountStakeFleet extends string, TAccountRegionTracker extends string, TAccountOutlawFlag extends string, TAccountSystemProgram extends string, TProgramAddress extends Address = typeof SAGE_PROGRAM_ADDRESS, >( input: StartMissionInput< TAccountProfileValidationSigner, TAccountProfileValidationProfile, TAccountProfileValidationCertificate, TAccountProfileValidationProgram, TAccountGame, TAccountSystemAndStarbasePlayerSystem, TAccountSystemAndStarbasePlayerStarbasePlayer, TAccountMissionProcess, TAccountCharacter, TAccountStarSystem, TAccountMissionVault, TAccountRewardPool, TAccountStakeFleet, TAccountRegionTracker, TAccountOutlawFlag, TAccountSystemProgram >, config?: { programAddress?: TProgramAddress }, ): StartMissionInstruction< TProgramAddress, TAccountProfileValidationSigner, TAccountProfileValidationProfile, TAccountProfileValidationCertificate, TAccountProfileValidationProgram, TAccountGame, TAccountSystemAndStarbasePlayerSystem, TAccountSystemAndStarbasePlayerStarbasePlayer, TAccountMissionProcess, TAccountCharacter, TAccountStarSystem, TAccountMissionVault, TAccountRewardPool, TAccountStakeFleet, TAccountRegionTracker, TAccountOutlawFlag, TAccountSystemProgram > { // Program address. const programAddress = config?.programAddress ?? SAGE_PROGRAM_ADDRESS; // Original accounts. const originalAccounts = { profileValidationSigner: { value: input.profileValidationSigner ?? null, isWritable: false, }, profileValidationProfile: { value: input.profileValidationProfile ?? null, isWritable: true, }, profileValidationCertificate: { value: input.profileValidationCertificate ?? null, isWritable: false, }, profileValidationProgram: { value: input.profileValidationProgram ?? null, isWritable: false, }, game: { value: input.game ?? null, isWritable: false }, systemAndStarbasePlayerSystem: { value: input.systemAndStarbasePlayerSystem ?? null, isWritable: false, }, systemAndStarbasePlayerStarbasePlayer: { value: input.systemAndStarbasePlayerStarbasePlayer ?? null, isWritable: true, }, missionProcess: { value: input.missionProcess ?? null, isWritable: true }, character: { value: input.character ?? null, isWritable: true }, starSystem: { value: input.starSystem ?? null, isWritable: false }, missionVault: { value: input.missionVault ?? null, isWritable: true }, rewardPool: { value: input.rewardPool ?? null, isWritable: false }, stakeFleet: { value: input.stakeFleet ?? null, isWritable: true }, regionTracker: { value: input.regionTracker ?? null, isWritable: false }, outlawFlag: { value: input.outlawFlag ?? null, isWritable: false }, systemProgram: { value: input.systemProgram ?? null, isWritable: false }, }; const accounts = originalAccounts as Record< keyof typeof originalAccounts, ResolvedInstructionAccount >; // Original args. const args = { ...input }; // Resolve default values. if (!accounts.profileValidationProgram.value) { accounts.profileValidationProgram.value = 'C4PRoFNroxxzdgeCoM31LJjYRg7kT6ymogSTAT99iD1u' as Address<'C4PRoFNroxxzdgeCoM31LJjYRg7kT6ymogSTAT99iD1u'>; } if (!accounts.systemProgram.value) { accounts.systemProgram.value = '11111111111111111111111111111111' as Address<'11111111111111111111111111111111'>; } const getAccountMeta = getAccountMetaFactory(programAddress, 'programId'); return Object.freeze({ accounts: [ getAccountMeta( 'profileValidationSigner', accounts.profileValidationSigner, ), getAccountMeta( 'profileValidationProfile', accounts.profileValidationProfile, ), getAccountMeta( 'profileValidationCertificate', accounts.profileValidationCertificate, ), getAccountMeta( 'profileValidationProgram', accounts.profileValidationProgram, ), getAccountMeta('game', accounts.game), getAccountMeta( 'systemAndStarbasePlayerSystem', accounts.systemAndStarbasePlayerSystem, ), getAccountMeta( 'systemAndStarbasePlayerStarbasePlayer', accounts.systemAndStarbasePlayerStarbasePlayer, ), getAccountMeta('missionProcess', accounts.missionProcess), getAccountMeta('character', accounts.character), getAccountMeta('starSystem', accounts.starSystem), getAccountMeta('missionVault', accounts.missionVault), getAccountMeta('rewardPool', accounts.rewardPool), getAccountMeta('stakeFleet', accounts.stakeFleet), getAccountMeta('regionTracker', accounts.regionTracker), getAccountMeta('outlawFlag', accounts.outlawFlag), getAccountMeta('systemProgram', accounts.systemProgram), ], data: getStartMissionInstructionDataEncoder().encode( args as StartMissionInstructionDataArgs, ), programAddress, } as StartMissionInstruction< TProgramAddress, TAccountProfileValidationSigner, TAccountProfileValidationProfile, TAccountProfileValidationCertificate, TAccountProfileValidationProgram, TAccountGame, TAccountSystemAndStarbasePlayerSystem, TAccountSystemAndStarbasePlayerStarbasePlayer, TAccountMissionProcess, TAccountCharacter, TAccountStarSystem, TAccountMissionVault, TAccountRewardPool, TAccountStakeFleet, TAccountRegionTracker, TAccountOutlawFlag, TAccountSystemProgram >); } export type ParsedStartMissionInstruction< TProgram extends string = typeof SAGE_PROGRAM_ADDRESS, TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], > = { programAddress: Address; accounts: { profileValidationSigner: TAccountMetas[0]; profileValidationProfile: TAccountMetas[1]; profileValidationCertificate?: TAccountMetas[2] | undefined; profileValidationProgram: TAccountMetas[3]; game: TAccountMetas[4]; /** The [`StarSystem`] account */ systemAndStarbasePlayerSystem: TAccountMetas[5]; /** The [`StarbasePlayer`] Account */ systemAndStarbasePlayerStarbasePlayer: TAccountMetas[6]; /** The NEW mission process (keypair-funded, closed on terminal call) — clone of `quest_process`. */ missionProcess: TAccountMetas[7]; /** * The owner's character — the in-game ATLAS source (`character.atlas`, the `AtlasBalance` ledger, * per `trade.rs`). Validated against `profile_validation.profile` + `game` (PR#732 house type). */ character: TAccountMetas[8]; /** * The system the starbase-player is in — asserted `== sbp.system`, read `region: Option` * to PIN `MissionProcess.region_id` (never caller-chosen; 10 §2.1 step 6, option a). */ starSystem: TAccountMetas[9]; /** The per-mission escrow PDA, seeds `(b"MissionVault", mission_process.key)`. */ missionVault: TAccountMetas[10]; /** The emissions-fed treasury this mission's WIN draws from — pinned into the process. */ rewardPool: TAccountMetas[11]; /** * (v1: ATLAS-only) Reserved for a future on-chain RESOURCE stake. StartMission rejects * `stake_resource_qty > 0` in v1, so this trailing optional account is currently always omitted; it is * kept in the set for forward-compatibility once the stake-return path is designed. Validated against * game + owner profile (same arg shape scan.rs uses for its fleet); when None the validate is a no-op. */ stakeFleet?: TAccountMetas[12] | undefined; /** * Phase-2: the region tracker — read-only, to pin the sector's RIGHTFUL incumbent * (`regions[region_id].owner`) TRUSTLESSLY at start (never a caller arg). Same validate arg shape as * scan.rs's region_tracker. */ regionTracker: TAccountMetas[13]; /** * Phase-2: the actor's OutlawFlag for `base_faction` (APPEND-LAST optional). Omitted (program-id * sentinel) ⇒ not outlaw ⇒ own-faction opposition stays BLOCKED (fail-closed). `AccountValidate` * checks the profile match; the handler re-derives the (profile, base_faction) PDA + key-checks it * (base_faction isn't known at validate). Read-only — `StartMission` only SNAPSHOTS the resolved value. */ outlawFlag?: TAccountMetas[14] | undefined; systemProgram: TAccountMetas[15]; }; data: StartMissionInstructionData; }; export function parseStartMissionInstruction< TProgram extends string, TAccountMetas extends readonly AccountMeta[], >( instruction: Instruction & InstructionWithAccounts & InstructionWithData, ): ParsedStartMissionInstruction { if (instruction.accounts.length < 16) { throw new SolanaError( SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS, { actualAccountMetas: instruction.accounts.length, expectedAccountMetas: 16, }, ); } 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: { profileValidationSigner: getNextAccount(), profileValidationProfile: getNextAccount(), profileValidationCertificate: getNextOptionalAccount(), profileValidationProgram: getNextAccount(), game: getNextAccount(), systemAndStarbasePlayerSystem: getNextAccount(), systemAndStarbasePlayerStarbasePlayer: getNextAccount(), missionProcess: getNextAccount(), character: getNextAccount(), starSystem: getNextAccount(), missionVault: getNextAccount(), rewardPool: getNextAccount(), stakeFleet: getNextOptionalAccount(), regionTracker: getNextAccount(), outlawFlag: getNextOptionalAccount(), systemProgram: getNextAccount(), }, data: getStartMissionInstructionDataDecoder().decode(instruction.data), }; }