import { AccountRole, address, createNoopSigner } from '@solana/kit'; import { describe, expect, it } from 'vitest'; import { getStopSubwarpInstruction } from '../src/generated/instructions/stopSubwarp'; import { getTheOneFleetStateHandlerInstruction, parseTheOneFleetStateHandlerInstruction, } from '../src/generated/instructions/theOneFleetStateHandler'; import { SAGE_PROGRAM_ADDRESS } from '../src/generated/programs/sage'; const SYSTEM = address('11111111111111111111111111111111'); const GAME = address('Stake11111111111111111111111111111111111111'); const FLEET = address('Config1111111111111111111111111111111111111'); const CHARACTER = address('Vote111111111111111111111111111111111111111'); const BUDGET = address('SysvarC1ock11111111111111111111111111111111'); const CONFIG = address('SysvarRent111111111111111111111111111111111'); const HYE = address('HYEWZXXzMyrnN89ASYPVHHdFdgvrgV8diFLv6P2wEwFN'); describe.each([SAGE_PROGRAM_ADDRESS, HYE])( 'fleet settlement ABI (%s)', (programAddress) => { const base = { funder: createNoopSigner(SYSTEM), fleet: FLEET, game: GAME, }; it('appends writable budget and readonly config after the rent-program slot', () => { const instruction = getTheOneFleetStateHandlerInstruction( { ...base, character: CHARACTER, xpBudget: BUDGET, xpBudgetConfig: CONFIG, }, { programAddress }, ); expect(instruction.accounts).toHaveLength(9); expect(instruction.accounts.map((a) => a.address)).toEqual([ SYSTEM, FLEET, GAME, programAddress, programAddress, CHARACTER, SYSTEM, BUDGET, CONFIG, ]); expect(instruction.accounts[7].role).toBe(AccountRole.WRITABLE); expect(instruction.accounts[8].role).toBe(AccountRole.READONLY); const parsed = parseTheOneFleetStateHandlerInstruction(instruction); expect(parsed.accounts.system).toBeUndefined(); expect(parsed.accounts.asteroid).toBeUndefined(); expect(parsed.accounts.character?.address).toBe(CHARACTER); expect(parsed.accounts.xpBudget?.address).toBe(BUDGET); expect(parsed.accounts.xpBudgetConfig?.address).toBe(CONFIG); }); it.each([6, 7, 9])( 'still decodes legacy/omitted tails (%i metas)', (length) => { const instruction = getTheOneFleetStateHandlerInstruction(base, { programAddress, }); const parsed = parseTheOneFleetStateHandlerInstruction({ ...instruction, accounts: instruction.accounts.slice(0, length), }); expect(parsed.accounts.character).toBeUndefined(); expect(parsed.accounts.xpBudget).toBeUndefined(); expect(parsed.accounts.xpBudgetConfig).toBeUndefined(); expect(parsed.accounts.systemProgram?.address).toBe( length === 6 ? undefined : SYSTEM, ); }, ); it('rejects a truncated historical prefix', () => { const instruction = getTheOneFleetStateHandlerInstruction(base, { programAddress, }); expect(() => parseTheOneFleetStateHandlerInstruction({ ...instruction, accounts: instruction.accounts.slice(0, 5), }), ).toThrow(); }); it('keeps StopSubwarp account positions unchanged', () => { const instruction = getStopSubwarpInstruction( { profileValidationSigner: base.funder, profileValidationProfile: CHARACTER, character: CHARACTER, fleet: FLEET, game: GAME, regionTracker: CONFIG, xpBudget: BUDGET, xpBudgetConfig: CONFIG, keyIndex: 0, }, { programAddress }, ); expect(instruction.accounts).toHaveLength(10); expect(instruction.accounts.slice(8)).toEqual([ { address: BUDGET, role: AccountRole.WRITABLE }, { address: CONFIG, role: AccountRole.READONLY }, ]); }); }, );