import { PublicKey, TransactionInstruction } from "@solana/web3.js"; import type { PitProgram } from "../program.js"; import { TOKEN_2022_PROGRAM_ID } from "../constants.js"; import { getMarketAddress, getMintAddress } from "../accounts/pda.js"; import { PoolType } from "../types.js"; /** * Parameters for creating an initialize_metadata instruction */ interface InitializeMetadataParams { /** Week number for this market (must match create_market_mints and initialize_market) */ weekNumber: number; /** Which pool to initialize metadata for */ poolType: PoolType; /** Operator's public key (must match hardcoded OPERATOR) */ operator: PublicKey; } /** * Create an initialize_metadata instruction * * This instruction initializes token metadata for one pool's mints (6 mints). * It must be called AFTER initialize_market for a given week number. * * Due to compute unit limits, metadata initialization is split into two calls: * - One for the High pool (6 mints) * - One for the Low pool (6 mints) * * @param program - Anchor Program instance * @param params - Initialize metadata parameters * @returns Promise resolving to TransactionInstruction * * @example * ```typescript * import { createProgram, createInitializeMetadataInstruction, PoolType } from "@pit-protocol/sdk"; * * const program = createProgram(provider); * * // Initialize High pool metadata * const highMetadataIx = await createInitializeMetadataInstruction(program, { * weekNumber: 2604, * poolType: PoolType.High, * operator: operatorKeypair.publicKey, * }); * const tx1 = new Transaction().add(highMetadataIx); * await sendAndConfirmTransaction(connection, tx1, [operatorKeypair]); * * // Initialize Low pool metadata * const lowMetadataIx = await createInitializeMetadataInstruction(program, { * weekNumber: 2604, * poolType: PoolType.Low, * operator: operatorKeypair.publicKey, * }); * const tx2 = new Transaction().add(lowMetadataIx); * await sendAndConfirmTransaction(connection, tx2, [operatorKeypair]); * ``` */ export async function createInitializeMetadataInstruction( program: PitProgram, params: InitializeMetadataParams ): Promise { const { weekNumber, poolType, operator } = params; // Derive market PDA const marketState = getMarketAddress(weekNumber); const poolTypeByte = poolType === PoolType.High ? 0 : 1; // Derive the 6 mint PDAs for this pool // Order: HIT mints (0, 1, 2), then MISS mints (0, 1, 2) const hitMint0 = getMintAddress(weekNumber, poolTypeByte, 0, true); const hitMint1 = getMintAddress(weekNumber, poolTypeByte, 1, true); const hitMint2 = getMintAddress(weekNumber, poolTypeByte, 2, true); const missMint0 = getMintAddress(weekNumber, poolTypeByte, 0, false); const missMint1 = getMintAddress(weekNumber, poolTypeByte, 1, false); const missMint2 = getMintAddress(weekNumber, poolTypeByte, 2, false); // Convert PoolType to IDL format const poolTypeArg = (poolType === PoolType.High ? { high: {} } : { low: {} }) as | { high: Record } | { low: Record }; return await program.methods .initializeMetadata(weekNumber, poolTypeArg) .accountsPartial({ marketState, operator, token2022Program: TOKEN_2022_PROGRAM_ID, }) .remainingAccounts([ { pubkey: hitMint0, isSigner: false, isWritable: true }, { pubkey: hitMint1, isSigner: false, isWritable: true }, { pubkey: hitMint2, isSigner: false, isWritable: true }, { pubkey: missMint0, isSigner: false, isWritable: true }, { pubkey: missMint1, isSigner: false, isWritable: true }, { pubkey: missMint2, isSigner: false, isWritable: true }, ]) .instruction(); }