@percolatorct/sdk 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/abi/encode.ts","../src/abi/instructions.ts","../src/abi/accounts.ts","../src/abi/errors.ts","../src/solana/slab.ts","../src/solana/pda.ts","../src/solana/ata.ts","../src/solana/discovery.ts","../src/solana/dex-oracle.ts","../src/solana/oracle.ts","../src/solana/token-program.ts","../src/solana/stake.ts","../src/config/program-ids.ts","../src/solana/adl.ts","../src/runtime/tx.ts","../src/math/trading.ts","../src/math/warmup.ts","../src/validation.ts","../src/oracle/price-router.ts"],"sourcesContent":["import { PublicKey } from \"@solana/web3.js\";\n\nconst U8_MAX = 255;\nconst U16_MAX = 65_535;\nconst U32_MAX = 4_294_967_295;\n\n/**\n * Encode u8 (1 byte)\n */\nexport function encU8(val: number): Uint8Array {\n if (!Number.isInteger(val) || val < 0 || val > 0xFF) {\n throw new Error(`encU8: value out of range (0..255), got ${val}`);\n }\n return new Uint8Array([val]);\n}\n\n/**\n * Encode u16 little-endian (2 bytes)\n */\nexport function encU16(val: number): Uint8Array {\n if (!Number.isInteger(val) || val < 0 || val > 0xFFFF) {\n throw new Error(`encU16: value out of range (0..65535), got ${val}`);\n }\n const buf = new Uint8Array(2);\n new DataView(buf.buffer).setUint16(0, val, true);\n return buf;\n}\n\n/**\n * Encode u32 little-endian (4 bytes)\n */\nexport function encU32(val: number): Uint8Array {\n if (!Number.isInteger(val) || val < 0 || val > 0xFFFFFFFF) {\n throw new Error(`encU32: value out of range (0..4294967295), got ${val}`);\n }\n const buf = new Uint8Array(4);\n new DataView(buf.buffer).setUint32(0, val, true);\n return buf;\n}\n\n/**\n * Encode u64 little-endian (8 bytes)\n * Input: bigint or string (decimal)\n */\nexport function encU64(val: bigint | string): Uint8Array {\n const n = typeof val === \"string\" ? BigInt(val) : val;\n if (n < 0n) throw new Error(\"encU64: value must be non-negative\");\n if (n > 0xffff_ffff_ffff_ffffn) throw new Error(\"encU64: value exceeds u64 max\");\n const buf = new Uint8Array(8);\n new DataView(buf.buffer).setBigUint64(0, n, true);\n return buf;\n}\n\n/**\n * Encode i64 little-endian (8 bytes), two's complement\n * Input: bigint or string (decimal, may be negative)\n */\nexport function encI64(val: bigint | string): Uint8Array {\n const n = typeof val === \"string\" ? BigInt(val) : val;\n const min = -(1n << 63n);\n const max = (1n << 63n) - 1n;\n if (n < min || n > max) throw new Error(\"encI64: value out of range\");\n const buf = new Uint8Array(8);\n new DataView(buf.buffer).setBigInt64(0, n, true);\n return buf;\n}\n\n/**\n * Encode u128 little-endian (16 bytes)\n * Input: bigint or string (decimal)\n */\nexport function encU128(val: bigint | string): Uint8Array {\n const n = typeof val === \"string\" ? BigInt(val) : val;\n if (n < 0n) throw new Error(\"encU128: value must be non-negative\");\n const max = (1n << 128n) - 1n;\n if (n > max) throw new Error(\"encU128: value exceeds u128 max\");\n const buf = new Uint8Array(16);\n const view = new DataView(buf.buffer);\n const lo = n & 0xffff_ffff_ffff_ffffn;\n const hi = n >> 64n;\n view.setBigUint64(0, lo, true);\n view.setBigUint64(8, hi, true);\n return buf;\n}\n\n/**\n * Encode i128 little-endian (16 bytes), two's complement\n * Input: bigint or string (decimal, may be negative)\n */\nexport function encI128(val: bigint | string): Uint8Array {\n const n = typeof val === \"string\" ? BigInt(val) : val;\n const min = -(1n << 127n);\n const max = (1n << 127n) - 1n;\n if (n < min || n > max) throw new Error(\"encI128: value out of range\");\n\n // Convert to unsigned representation (two's complement)\n let unsigned = n;\n if (n < 0n) {\n unsigned = (1n << 128n) + n;\n }\n\n const buf = new Uint8Array(16);\n const view = new DataView(buf.buffer);\n const lo = unsigned & 0xffff_ffff_ffff_ffffn;\n const hi = unsigned >> 64n;\n view.setBigUint64(0, lo, true);\n view.setBigUint64(8, hi, true);\n return buf;\n}\n\n/**\n * Encode a PublicKey (32 bytes)\n * Input: PublicKey or base58 string\n */\nexport function encPubkey(val: PublicKey | string): Uint8Array {\n try {\n const pk = typeof val === \"string\" ? new PublicKey(val) : val;\n return pk.toBytes();\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n throw new Error(`encPubkey: invalid public key \"${String(val)}\" — ${msg}`);\n }\n}\n\n/**\n * Encode a boolean as u8 (0 = false, 1 = true)\n */\nexport function encBool(val: boolean): Uint8Array {\n return encU8(val ? 1 : 0);\n}\n\n/**\n * Concatenate multiple Uint8Arrays (replaces Buffer.concat)\n */\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n const totalLen = arrays.reduce((sum, a) => sum + a.length, 0);\n const result = new Uint8Array(totalLen);\n let offset = 0;\n for (const arr of arrays) {\n result.set(arr, offset);\n offset += arr.length;\n }\n return result;\n}\n","import { PublicKey } from \"@solana/web3.js\";\nimport {\n encU8,\n encU16,\n encU32,\n encU64,\n encI64,\n encU128,\n encI128,\n encPubkey,\n concatBytes,\n} from \"./encode.js\";\n\n/**\n * Instruction tags - exact match to Rust ix::Instruction::decode\n */\nexport const IX_TAG = {\n InitMarket: 0,\n InitUser: 1,\n InitLP: 2,\n DepositCollateral: 3,\n WithdrawCollateral: 4,\n KeeperCrank: 5,\n TradeNoCpi: 6,\n LiquidateAtOracle: 7,\n CloseAccount: 8,\n TopUpInsurance: 9,\n TradeCpi: 10,\n SetRiskThreshold: 11,\n UpdateAdmin: 12,\n CloseSlab: 13,\n UpdateConfig: 14,\n SetMaintenanceFee: 15,\n SetOracleAuthority: 16,\n PushOraclePrice: 17,\n SetOraclePriceCap: 18,\n ResolveMarket: 19,\n WithdrawInsurance: 20,\n AdminForceClose: 21,\n UpdateRiskParams: 22,\n RenounceAdmin: 23,\n CreateInsuranceMint: 24,\n DepositInsuranceLP: 25,\n WithdrawInsuranceLP: 26,\n PauseMarket: 27,\n UnpauseMarket: 28,\n AcceptAdmin: 29,\n SetInsuranceWithdrawPolicy: 30,\n WithdrawInsuranceLimited: 31,\n SetPythOracle: 32,\n UpdateMarkPrice: 33,\n UpdateHyperpMark: 34,\n TradeCpiV2: 35,\n UnresolveMarket: 36,\n CreateLpVault: 37,\n LpVaultDeposit: 38,\n LpVaultWithdraw: 39,\n LpVaultCrankFees: 40,\n /** PERC-306: Fund per-market isolated insurance balance */\n FundMarketInsurance: 41,\n /** PERC-306: Set insurance isolation BPS for a market */\n SetInsuranceIsolation: 42,\n // Tag 43 is ChallengeSettlement on-chain (PERC-314).\n // PERC-305 (ExecuteAdl) is NOT implemented on-chain — do NOT assign tag 43 here.\n // When PERC-305 is implemented, assign a new unused tag (≥47).\n /** PERC-314: Challenge settlement price during dispute window */\n ChallengeSettlement: 43,\n /** PERC-314: Resolve dispute (admin adjudication) */\n ResolveDispute: 44,\n /** PERC-315: Deposit LP vault tokens as perp collateral */\n DepositLpCollateral: 45,\n /** PERC-315: Withdraw LP collateral (position must be closed) */\n WithdrawLpCollateral: 46,\n /** PERC-309: Queue a large LP withdrawal (user; creates withdraw_queue PDA). */\n QueueWithdrawal: 47,\n /** PERC-309: Claim one epoch tranche from a queued LP withdrawal (user). */\n ClaimQueuedWithdrawal: 48,\n /** PERC-309: Cancel a queued withdrawal, refund remaining LP tokens (user). */\n CancelQueuedWithdrawal: 49,\n /** PERC-305: Auto-deleverage — surgically close profitable positions when PnL cap is exceeded (permissionless). */\n ExecuteAdl: 50,\n /** Close a stale slab of an invalid/old layout and recover rent SOL (admin only). */\n CloseStaleSlabs: 51,\n /** Reclaim rent from an uninitialised slab whose market creation failed mid-flow. Slab must sign. */\n ReclaimSlabRent: 52,\n /** Permissionless on-chain audit crank: verifies conservation invariants and pauses market on violation. */\n AuditCrank: 53,\n /** Cross-Market Portfolio Margining: SetOffsetPair */\n SetOffsetPair: 54,\n /** Cross-Market Portfolio Margining: AttestCrossMargin */\n AttestCrossMargin: 55,\n /** PERC-622: Advance oracle phase (permissionless crank) */\n AdvanceOraclePhase: 56,\n /** PERC-623: Top up a market's keeper fund (permissionless) */\n TopUpKeeperFund: 57,\n /** PERC-629: Slash a market creator's deposit (permissionless) */\n SlashCreationDeposit: 58,\n /** PERC-628: Initialize the global shared vault (admin) */\n InitSharedVault: 59,\n /** PERC-628: Allocate virtual liquidity to a market (admin) */\n AllocateMarket: 60,\n /** PERC-628: Queue a withdrawal for the current epoch */\n QueueWithdrawalSV: 61,\n /** PERC-628: Claim a queued withdrawal after epoch elapses */\n ClaimEpochWithdrawal: 62,\n /** PERC-628: Advance the shared vault epoch (permissionless crank) */\n AdvanceEpoch: 63,\n /** PERC-608: Mint a Position NFT for a user's open position. */\n MintPositionNft: 64,\n /** PERC-608: Transfer position ownership via the NFT (keeper-gated). */\n TransferPositionOwnership: 65,\n /** PERC-608: Burn the Position NFT when a position is closed. */\n BurnPositionNft: 66,\n /** PERC-608: Keeper sets pending_settlement flag before a funding transfer. */\n SetPendingSettlement: 67,\n /** PERC-608: Keeper clears pending_settlement flag after KeeperCrank. */\n ClearPendingSettlement: 68,\n /** PERC-608: Internal CPI call from percolator-nft TransferHook to update on-chain owner. */\n TransferOwnershipCpi: 69,\n /** PERC-8111: Set per-wallet position cap (admin only, cap_e6=0 disables). */\n SetWalletCap: 70,\n /** PERC-8110: Set OI imbalance hard-block threshold (admin only). */\n SetOiImbalanceHardBlock: 71,\n} as const;\n\n/**\n * InitMarket instruction data (256 bytes total)\n * Layout: tag(1) + admin(32) + mint(32) + indexFeedId(32) +\n * maxStaleSecs(8) + confFilter(2) + invert(1) + unitScale(4) +\n * RiskParams(144)\n *\n * Note: indexFeedId is the Pyth Pull feed ID (32 bytes hex), NOT an oracle pubkey.\n * The program validates PriceUpdateV2 accounts against this feed ID at runtime.\n */\nexport interface InitMarketArgs {\n admin: PublicKey | string;\n collateralMint: PublicKey | string;\n indexFeedId: string; // Pyth feed ID (hex string, 64 chars without 0x prefix). All zeros = Hyperp mode.\n maxStalenessSecs: bigint | string; // Max staleness in SECONDS (Pyth Pull uses unix timestamps)\n confFilterBps: number;\n invert: number; // 0 = no inversion, 1 = invert oracle price (USD/SOL -> SOL/USD)\n unitScale: number; // Lamports per unit (0 = no scaling, e.g. 1000 = 1 SOL = 1,000,000 units)\n initialMarkPriceE6: bigint | string; // Initial mark price (required non-zero for Hyperp mode)\n warmupPeriodSlots: bigint | string;\n maintenanceMarginBps: bigint | string;\n initialMarginBps: bigint | string;\n tradingFeeBps: bigint | string;\n maxAccounts: bigint | string;\n newAccountFee: bigint | string;\n riskReductionThreshold: bigint | string;\n maintenanceFeePerSlot: bigint | string;\n maxCrankStalenessSlots: bigint | string;\n liquidationFeeBps: bigint | string;\n liquidationFeeCap: bigint | string;\n liquidationBufferBps: bigint | string;\n minLiquidationAbs: bigint | string;\n}\n\n/**\n * Encode a Pyth feed ID (hex string) to 32-byte Uint8Array.\n */\nconst HEX_RE = /^[0-9a-fA-F]{64}$/;\n\nfunction encodeFeedId(feedId: string): Uint8Array {\n const hex = feedId.startsWith(\"0x\") ? feedId.slice(2) : feedId;\n if (!HEX_RE.test(hex)) {\n throw new Error(\n `Invalid feed ID: expected 64 hex chars, got \"${hex.length === 64 ? \"non-hex characters\" : hex.length + \" chars\"}\"`,\n );\n }\n const bytes = new Uint8Array(32);\n for (let i = 0; i < 64; i += 2) {\n bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);\n }\n return bytes;\n}\n\nconst INIT_MARKET_DATA_LEN = 264;\n\nexport function encodeInitMarket(args: InitMarketArgs): Uint8Array {\n const data = concatBytes(\n encU8(IX_TAG.InitMarket),\n encPubkey(args.admin),\n encPubkey(args.collateralMint),\n encodeFeedId(args.indexFeedId),\n encU64(args.maxStalenessSecs),\n encU16(args.confFilterBps),\n encU8(args.invert),\n encU32(args.unitScale),\n encU64(args.initialMarkPriceE6),\n encU64(args.warmupPeriodSlots),\n encU64(args.maintenanceMarginBps),\n encU64(args.initialMarginBps),\n encU64(args.tradingFeeBps),\n encU64(args.maxAccounts),\n encU128(args.newAccountFee),\n encU128(args.riskReductionThreshold),\n encU128(args.maintenanceFeePerSlot),\n encU64(args.maxCrankStalenessSlots),\n encU64(args.liquidationFeeBps),\n encU128(args.liquidationFeeCap),\n encU64(args.liquidationBufferBps),\n encU128(args.minLiquidationAbs),\n );\n if (data.length !== INIT_MARKET_DATA_LEN) {\n throw new Error(\n `encodeInitMarket: expected ${INIT_MARKET_DATA_LEN} bytes, got ${data.length}`,\n );\n }\n return data;\n}\n\n/**\n * InitUser instruction data (9 bytes)\n */\nexport interface InitUserArgs {\n feePayment: bigint | string;\n}\n\nexport function encodeInitUser(args: InitUserArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.InitUser), encU64(args.feePayment));\n}\n\n/**\n * InitLP instruction data (73 bytes)\n */\nexport interface InitLPArgs {\n matcherProgram: PublicKey | string;\n matcherContext: PublicKey | string;\n feePayment: bigint | string;\n}\n\nexport function encodeInitLP(args: InitLPArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.InitLP),\n encPubkey(args.matcherProgram),\n encPubkey(args.matcherContext),\n encU64(args.feePayment),\n );\n}\n\n/**\n * DepositCollateral instruction data (11 bytes)\n */\nexport interface DepositCollateralArgs {\n userIdx: number;\n amount: bigint | string;\n}\n\nexport function encodeDepositCollateral(args: DepositCollateralArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.DepositCollateral),\n encU16(args.userIdx),\n encU64(args.amount),\n );\n}\n\n/**\n * WithdrawCollateral instruction data (11 bytes)\n */\nexport interface WithdrawCollateralArgs {\n userIdx: number;\n amount: bigint | string;\n}\n\nexport function encodeWithdrawCollateral(args: WithdrawCollateralArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.WithdrawCollateral),\n encU16(args.userIdx),\n encU64(args.amount),\n );\n}\n\n/**\n * KeeperCrank instruction data (4 bytes)\n * Funding rate is computed on-chain from LP inventory.\n */\nexport interface KeeperCrankArgs {\n callerIdx: number;\n allowPanic: boolean;\n}\n\nexport function encodeKeeperCrank(args: KeeperCrankArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.KeeperCrank),\n encU16(args.callerIdx),\n encU8(args.allowPanic ? 1 : 0),\n );\n}\n\n/**\n * TradeNoCpi instruction data (21 bytes)\n */\nexport interface TradeNoCpiArgs {\n lpIdx: number;\n userIdx: number;\n size: bigint | string;\n}\n\nexport function encodeTradeNoCpi(args: TradeNoCpiArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.TradeNoCpi),\n encU16(args.lpIdx),\n encU16(args.userIdx),\n encI128(args.size),\n );\n}\n\n/**\n * LiquidateAtOracle instruction data (3 bytes)\n */\nexport interface LiquidateAtOracleArgs {\n targetIdx: number;\n}\n\nexport function encodeLiquidateAtOracle(args: LiquidateAtOracleArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.LiquidateAtOracle),\n encU16(args.targetIdx),\n );\n}\n\n/**\n * CloseAccount instruction data (3 bytes)\n */\nexport interface CloseAccountArgs {\n userIdx: number;\n}\n\nexport function encodeCloseAccount(args: CloseAccountArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.CloseAccount), encU16(args.userIdx));\n}\n\n/**\n * TopUpInsurance instruction data (9 bytes)\n */\nexport interface TopUpInsuranceArgs {\n amount: bigint | string;\n}\n\nexport function encodeTopUpInsurance(args: TopUpInsuranceArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.TopUpInsurance), encU64(args.amount));\n}\n\n/**\n * TradeCpi instruction data (21 bytes)\n */\nexport interface TradeCpiArgs {\n lpIdx: number;\n userIdx: number;\n size: bigint | string;\n}\n\nexport function encodeTradeCpi(args: TradeCpiArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.TradeCpi),\n encU16(args.lpIdx),\n encU16(args.userIdx),\n encI128(args.size),\n );\n}\n\n/**\n * TradeCpiV2 instruction data (22 bytes) — PERC-154 optimized trade CPI.\n *\n * Same as TradeCpi but includes a caller-provided PDA bump byte.\n * Uses create_program_address instead of find_program_address,\n * saving ~1500 CU per trade. The bump should be obtained once via\n * deriveLpPda() and cached for the lifetime of the market.\n */\nexport interface TradeCpiV2Args {\n lpIdx: number;\n userIdx: number;\n size: bigint | string;\n bump: number;\n}\n\nexport function encodeTradeCpiV2(args: TradeCpiV2Args): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.TradeCpiV2),\n encU16(args.lpIdx),\n encU16(args.userIdx),\n encI128(args.size),\n encU8(args.bump),\n );\n}\n\n/**\n * SetRiskThreshold instruction data (17 bytes)\n */\nexport interface SetRiskThresholdArgs {\n newThreshold: bigint | string;\n}\n\nexport function encodeSetRiskThreshold(args: SetRiskThresholdArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.SetRiskThreshold),\n encU128(args.newThreshold),\n );\n}\n\n/**\n * UpdateAdmin instruction data (33 bytes)\n */\nexport interface UpdateAdminArgs {\n newAdmin: PublicKey | string;\n}\n\nexport function encodeUpdateAdmin(args: UpdateAdminArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.UpdateAdmin), encPubkey(args.newAdmin));\n}\n\n/**\n * CloseSlab instruction data (1 byte)\n */\nexport function encodeCloseSlab(): Uint8Array {\n return encU8(IX_TAG.CloseSlab);\n}\n\n/**\n * UpdateConfig instruction data\n * Updates funding and threshold parameters at runtime (admin only)\n */\nexport interface UpdateConfigArgs {\n // Funding parameters\n fundingHorizonSlots: bigint | string;\n fundingKBps: bigint | string;\n fundingInvScaleNotionalE6: bigint | string;\n fundingMaxPremiumBps: bigint | string;\n fundingMaxBpsPerSlot: bigint | string;\n // Threshold parameters\n threshFloor: bigint | string;\n threshRiskBps: bigint | string;\n threshUpdateIntervalSlots: bigint | string;\n threshStepBps: bigint | string;\n threshAlphaBps: bigint | string;\n threshMin: bigint | string;\n threshMax: bigint | string;\n threshMinStep: bigint | string;\n}\n\nexport function encodeUpdateConfig(args: UpdateConfigArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.UpdateConfig),\n encU64(args.fundingHorizonSlots),\n encU64(args.fundingKBps),\n encU128(args.fundingInvScaleNotionalE6),\n encI64(args.fundingMaxPremiumBps), // Rust: i64 (can be negative)\n encI64(args.fundingMaxBpsPerSlot), // Rust: i64 (can be negative)\n encU128(args.threshFloor),\n encU64(args.threshRiskBps),\n encU64(args.threshUpdateIntervalSlots),\n encU64(args.threshStepBps),\n encU64(args.threshAlphaBps),\n encU128(args.threshMin),\n encU128(args.threshMax),\n encU128(args.threshMinStep),\n );\n}\n\n/**\n * SetMaintenanceFee instruction data (17 bytes)\n */\nexport interface SetMaintenanceFeeArgs {\n newFee: bigint | string;\n}\n\nexport function encodeSetMaintenanceFee(args: SetMaintenanceFeeArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.SetMaintenanceFee),\n encU128(args.newFee),\n );\n}\n\n/**\n * SetOracleAuthority instruction data (33 bytes)\n * Sets the oracle price authority. Pass zero pubkey to disable and require Pyth/Chainlink.\n */\nexport interface SetOracleAuthorityArgs {\n newAuthority: PublicKey | string;\n}\n\nexport function encodeSetOracleAuthority(args: SetOracleAuthorityArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.SetOracleAuthority),\n encPubkey(args.newAuthority),\n );\n}\n\n/**\n * PushOraclePrice instruction data (17 bytes)\n * Push a new oracle price (oracle authority only).\n * The price should be in e6 format and already include any inversion/scaling.\n */\nexport interface PushOraclePriceArgs {\n priceE6: bigint | string;\n timestamp: bigint | string;\n}\n\nexport function encodePushOraclePrice(args: PushOraclePriceArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.PushOraclePrice),\n encU64(args.priceE6),\n encI64(args.timestamp),\n );\n}\n\n/**\n * SetOraclePriceCap instruction data (9 bytes)\n * Set oracle price circuit breaker cap (admin only).\n *\n * max_change_e2bps: maximum oracle price movement per slot in 0.01 bps units.\n * 1_000_000 = 100% max move per slot.\n *\n * ⚠️ PERC-8191 (PR#150): cap=0 is NO LONGER accepted for admin-oracle markets.\n * - Hyperp markets: rejected if cap < DEFAULT_HYPERP_PRICE_CAP_E2BPS (1000).\n * - Admin-oracle markets: rejected if cap == 0 (circuit breaker bypass prevention).\n * - Pyth-pinned markets: immune (oracle_authority zeroed), any value accepted.\n *\n * Use a non-zero cap for all admin-oracle and Hyperp markets.\n */\nexport interface SetOraclePriceCapArgs {\n maxChangeE2bps: bigint | string;\n}\n\nexport function encodeSetOraclePriceCap(args: SetOraclePriceCapArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.SetOraclePriceCap),\n encU64(args.maxChangeE2bps),\n );\n}\n\n/**\n * ResolveMarket instruction data (1 byte)\n * Resolves a binary/premarket - sets RESOLVED flag, positions force-closed via crank.\n * Requires admin oracle price (authority_price_e6) to be set first.\n */\nexport function encodeResolveMarket(): Uint8Array {\n return encU8(IX_TAG.ResolveMarket);\n}\n\n/**\n * WithdrawInsurance instruction data (1 byte)\n * Withdraw insurance fund to admin (requires RESOLVED and all positions closed).\n */\nexport function encodeWithdrawInsurance(): Uint8Array {\n return encU8(IX_TAG.WithdrawInsurance);\n}\n\n/**\n * AdminForceClose instruction data (3 bytes)\n * Force-close any position at oracle price (admin only, skips margin checks).\n */\nexport interface AdminForceCloseArgs {\n targetIdx: number;\n}\n\nexport function encodeAdminForceClose(args: AdminForceCloseArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.AdminForceClose),\n encU16(args.targetIdx),\n );\n}\n\n/**\n * UpdateRiskParams instruction data (17 or 25 bytes)\n * Update initial and maintenance margin BPS (admin only).\n *\n * R2-S13: The Rust program uses `data.len() >= 25` to detect the optional\n * tradingFeeBps field, so variable-length encoding is safe. When tradingFeeBps\n * is omitted, the data is 17 bytes (tag + 2×u64). When included, 25 bytes.\n */\nexport interface UpdateRiskParamsArgs {\n initialMarginBps: bigint | string;\n maintenanceMarginBps: bigint | string;\n tradingFeeBps?: bigint | string;\n}\n\nexport function encodeUpdateRiskParams(args: UpdateRiskParamsArgs): Uint8Array {\n const parts = [\n encU8(IX_TAG.UpdateRiskParams),\n encU64(args.initialMarginBps),\n encU64(args.maintenanceMarginBps),\n ];\n if (args.tradingFeeBps !== undefined) {\n parts.push(encU64(args.tradingFeeBps));\n }\n return concatBytes(...parts);\n}\n\n/**\n * On-chain confirmation code for RenounceAdmin (must match program constant).\n * ASCII \"RENOUNCE\" as u64 LE = 0x52454E4F554E4345.\n */\nexport const RENOUNCE_ADMIN_CONFIRMATION = 0x52454E4F554E4345n;\n\n/**\n * On-chain confirmation code for UnresolveMarket (must match program constant).\n */\nexport const UNRESOLVE_CONFIRMATION = 0xDEAD_BEEF_CAFE_1234n;\n\n/**\n * RenounceAdmin instruction data (9 bytes)\n * Irreversibly set admin to all zeros. After this, all admin-only instructions fail.\n *\n * Requires the confirmation code 0x52454E4F554E4345 (\"RENOUNCE\" as u64 LE)\n * to prevent accidental invocation.\n */\nexport function encodeRenounceAdmin(): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.RenounceAdmin),\n encU64(RENOUNCE_ADMIN_CONFIRMATION),\n );\n}\n\n/**\n * CreateInsuranceMint instruction data (1 byte)\n * Creates the SPL mint PDA for insurance LP tokens. Admin only, once per market.\n */\nexport function encodeCreateInsuranceMint(): Uint8Array {\n return encU8(IX_TAG.CreateInsuranceMint);\n}\n\n/**\n * DepositInsuranceLP instruction data (9 bytes)\n * Deposit collateral into insurance fund, receive LP tokens proportional to share.\n */\nexport interface DepositInsuranceLPArgs {\n amount: bigint | string;\n}\n\nexport function encodeDepositInsuranceLP(args: DepositInsuranceLPArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.DepositInsuranceLP), encU64(args.amount));\n}\n\n/**\n * WithdrawInsuranceLP instruction data (9 bytes)\n * Burn LP tokens and withdraw proportional share of insurance fund.\n */\nexport interface WithdrawInsuranceLPArgs {\n lpAmount: bigint | string;\n}\n\nexport function encodeWithdrawInsuranceLP(args: WithdrawInsuranceLPArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.WithdrawInsuranceLP), encU64(args.lpAmount));\n}\n\n// ============================================================================\n// PERC-627 / GH#1926: LpVaultWithdraw (tag 39)\n// ============================================================================\n\n/**\n * LpVaultWithdraw (Tag 39, PERC-627 / GH#1926 / PERC-8287) — burn LP vault tokens and\n * withdraw proportional collateral.\n *\n * **BREAKING (PR#170):** accounts[9] = creatorLockPda is now REQUIRED.\n * Always include `deriveCreatorLockPda(programId, slab)` at position 9.\n * Non-creator withdrawers pass the derived PDA; if no lock exists on-chain\n * the check is a no-op. Omitting this account causes `ExpectLenFailed` on-chain.\n *\n * Instruction data: tag(1) + lp_amount(8) = 9 bytes\n *\n * Accounts (use ACCOUNTS_LP_VAULT_WITHDRAW):\n * [0] withdrawer signer\n * [1] slab writable\n * [2] withdrawerAta writable\n * [3] vault writable\n * [4] tokenProgram\n * [5] lpVaultMint writable\n * [6] withdrawerLpAta writable\n * [7] vaultAuthority\n * [8] lpVaultState writable\n * [9] creatorLockPda writable ← derive with deriveCreatorLockPda(programId, slab)\n *\n * @param lpAmount - Amount of LP vault tokens to burn.\n *\n * @example\n * ```ts\n * import { encodeLpVaultWithdraw, ACCOUNTS_LP_VAULT_WITHDRAW, buildAccountMetas } from \"@percolator/sdk\";\n * import { deriveCreatorLockPda, deriveVaultAuthority } from \"@percolator/sdk\";\n *\n * const [creatorLockPda] = deriveCreatorLockPda(PROGRAM_ID, slabKey);\n * const [vaultAuthority] = deriveVaultAuthority(PROGRAM_ID, slabKey);\n *\n * const data = encodeLpVaultWithdraw({ lpAmount: 1_000_000_000n });\n * const keys = buildAccountMetas(ACCOUNTS_LP_VAULT_WITHDRAW, {\n * withdrawer, slab: slabKey, withdrawerAta, vault, tokenProgram: TOKEN_PROGRAM_ID,\n * lpVaultMint, withdrawerLpAta, vaultAuthority, lpVaultState, creatorLockPda,\n * });\n * ```\n */\nexport interface LpVaultWithdrawArgs {\n /** Amount of LP vault tokens to burn. */\n lpAmount: bigint | string;\n}\n\nexport function encodeLpVaultWithdraw(args: LpVaultWithdrawArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.LpVaultWithdraw), encU64(args.lpAmount));\n}\n\n/**\n * PauseMarket instruction data (1 byte)\n * Pauses the market — disables trading, deposits, and withdrawals.\n */\nexport function encodePauseMarket(): Uint8Array {\n return encU8(IX_TAG.PauseMarket);\n}\n\n/**\n * UnpauseMarket instruction data (1 byte)\n * Unpauses the market — re-enables trading, deposits, and withdrawals.\n */\nexport function encodeUnpauseMarket(): Uint8Array {\n return encU8(IX_TAG.UnpauseMarket);\n}\n\n// ============================================================================\n// PERC-117: Pyth Oracle CPI Instructions\n// ============================================================================\n\n/**\n * SetPythOracle (Tag 32) — switch a market to Pyth-pinned mode.\n *\n * After this instruction:\n * - oracle_authority is cleared → PushOraclePrice is disabled\n * - index_feed_id is set to feed_id → validated on every price read\n * - max_staleness_secs and conf_filter_bps are updated\n * - All price reads go directly to read_pyth_price_e6() with on-chain\n * staleness + confidence + feed-ID validation (no silent fallback)\n *\n * Instruction data: tag(1) + feed_id(32) + max_staleness_secs(8) + conf_filter_bps(2) = 43 bytes\n *\n * Accounts:\n * 0. [signer, writable] Admin\n * 1. [writable] Slab\n */\nexport interface SetPythOracleArgs {\n /** 32-byte Pyth feed ID. All zeros is invalid (reserved for Hyperp mode). */\n feedId: Uint8Array;\n /** Maximum age of Pyth price in seconds before OracleStale is returned. Must be > 0. */\n maxStalenessSecs: bigint;\n /** Max confidence/price ratio in bps (0 = no confidence check). */\n confFilterBps: number;\n}\n\nexport function encodeSetPythOracle(args: SetPythOracleArgs): Uint8Array {\n if (args.feedId.length !== 32) throw new Error('feedId must be 32 bytes');\n if (args.maxStalenessSecs <= 0n) throw new Error('maxStalenessSecs must be > 0');\n\n const buf = new Uint8Array(43);\n const dv = new DataView(buf.buffer);\n\n // Tag 32 (SetPythOracle)\n buf[0] = 32;\n buf.set(args.feedId, 1);\n dv.setBigUint64(33, args.maxStalenessSecs, /* little-endian */ true);\n dv.setUint16(41, args.confFilterBps, true);\n\n return buf;\n}\n\n/**\n * Derive the expected Pyth PriceUpdateV2 account address for a given feed ID.\n * Uses PDA seeds: [shard_id(2), feed_id(32)] under the Pyth Receiver program.\n *\n * @param feedId 32-byte Pyth feed ID\n * @param shardId Shard index (default 0 for mainnet/devnet)\n */\nexport const PYTH_RECEIVER_PROGRAM_ID = 'rec5EKMGg6MxZYaMdyBfgwp4d5rB9T1VQH5pJv5LtFJ';\n\nexport async function derivePythPriceUpdateAccount(\n feedId: Uint8Array,\n shardId = 0,\n): Promise<string> {\n const { PublicKey } = await import('@solana/web3.js');\n const shardBuf = new Uint8Array(2);\n new DataView(shardBuf.buffer).setUint16(0, shardId, true);\n const [pda] = PublicKey.findProgramAddressSync(\n [shardBuf, feedId],\n new PublicKey(PYTH_RECEIVER_PROGRAM_ID),\n );\n return pda.toBase58();\n}\n\n// Add SetPythOracle to the tag registry\n(IX_TAG as Record<string, number>)['SetPythOracle'] = 32;\n\n// PERC-118: Mark Price EMA Instructions\n// ============================================================================\n\n// Tag 33 — permissionless mark price EMA crank\n(IX_TAG as Record<string, number>)['UpdateMarkPrice'] = 33;\n\n/**\n * UpdateMarkPrice (Tag 33) — permissionless EMA mark price crank.\n *\n * Reads the current oracle price on-chain, applies 8-hour EMA smoothing\n * with circuit breaker, and writes result to authority_price_e6.\n *\n * Instruction data: 1 byte (tag only — all params read from on-chain state)\n *\n * Accounts:\n * 0. [writable] Slab\n * 1. [] Oracle account (Pyth PriceUpdateV2 / Chainlink / DEX AMM)\n * 2. [] Clock sysvar (SysvarC1ock11111111111111111111111111111111)\n * 3..N [] Remaining accounts (PumpSwap vaults, etc. if needed)\n */\nexport function encodeUpdateMarkPrice(): Uint8Array {\n return new Uint8Array([33]);\n}\n\n/**\n * Mark price EMA parameters (must match program/src/percolator.rs constants).\n */\nexport const MARK_PRICE_EMA_WINDOW_SLOTS = 72_000n;\nexport const MARK_PRICE_EMA_ALPHA_E6 = 2_000_000n / (MARK_PRICE_EMA_WINDOW_SLOTS + 1n);\n\n/**\n * Compute the next EMA mark price step (TypeScript mirror of the on-chain function).\n */\nexport function computeEmaMarkPrice(\n markPrevE6: bigint,\n oracleE6: bigint,\n dtSlots: bigint,\n alphaE6 = MARK_PRICE_EMA_ALPHA_E6,\n capE2bps = 0n,\n): bigint {\n if (oracleE6 === 0n) return markPrevE6;\n if (markPrevE6 === 0n || dtSlots === 0n) return oracleE6;\n\n let oracleClamped = oracleE6;\n if (capE2bps > 0n) {\n const maxDelta = (markPrevE6 * capE2bps * dtSlots) / 1_000_000n;\n const lo = markPrevE6 > maxDelta ? markPrevE6 - maxDelta : 0n;\n const hi = markPrevE6 + maxDelta;\n if (oracleClamped < lo) oracleClamped = lo;\n if (oracleClamped > hi) oracleClamped = hi;\n }\n\n const effectiveAlpha = alphaE6 * dtSlots > 1_000_000n ? 1_000_000n : alphaE6 * dtSlots;\n const oneMinusAlpha = 1_000_000n - effectiveAlpha;\n\n return (oracleClamped * effectiveAlpha + markPrevE6 * oneMinusAlpha) / 1_000_000n;\n}\n\n// PERC-119: Hyperp EMA Oracle for Permissionless Tokens\n// ============================================================================\n\n// Tag 34 — permissionless Hyperp mark price oracle (reads DEX AMM pool)\n(IX_TAG as Record<string, number>)['UpdateHyperpMark'] = 34;\n\n/**\n * UpdateHyperpMark (Tag 34) — permissionless Hyperp EMA oracle crank.\n *\n * Reads the spot price from a PumpSwap, Raydium CLMM, or Meteora DLMM pool,\n * applies 8-hour EMA smoothing with circuit breaker, and writes the new mark\n * to authority_price_e6 on the slab.\n *\n * This is the core mechanism for permissionless token markets — no Pyth or\n * Chainlink feed is needed. The DEX AMM IS the oracle.\n *\n * Instruction data: 1 byte (tag only)\n *\n * Accounts:\n * 0. [writable] Slab\n * 1. [] DEX pool account (PumpSwap / Raydium CLMM / Meteora DLMM)\n * 2. [] Clock sysvar (SysvarC1ock11111111111111111111111111111111)\n * 3..N [] Remaining accounts (e.g. PumpSwap vault0 + vault1)\n */\nexport function encodeUpdateHyperpMark(): Uint8Array {\n return new Uint8Array([34]);\n}\n\n// ============================================================================\n// PERC-306: Per-Market Insurance Isolation\n// ============================================================================\n\n/**\n * Fund per-market isolated insurance balance.\n * Accounts: [admin(signer,writable), slab(writable), admin_ata(writable), vault(writable), token_program]\n */\nexport function encodeFundMarketInsurance(args: { amount: bigint }): Uint8Array {\n return concatBytes(encU8(IX_TAG.FundMarketInsurance), encU64(args.amount));\n}\n\n/**\n * Set insurance isolation BPS for a market.\n * Accounts: [admin(signer), slab(writable)]\n */\nexport function encodeSetInsuranceIsolation(args: { bps: number }): Uint8Array {\n return concatBytes(encU8(IX_TAG.SetInsuranceIsolation), encU16(args.bps));\n}\n\n// ============================================================================\n// NOTE: encodeExecuteAdl() was historically removed when it was discovered\n// that PERC-305 was NOT implemented on-chain and tag 43 was ChallengeSettlement.\n// PERC-305 (ExecuteAdl) is now live at tag 50. Encoder added below.\n// ============================================================================\n\n// ============================================================================\n// PERC-309: QueueWithdrawal / ClaimQueuedWithdrawal / CancelQueuedWithdrawal\n// ============================================================================\n\n/**\n * QueueWithdrawal (Tag 47, PERC-309) — queue a large LP withdrawal.\n *\n * Creates a withdraw_queue PDA. The LP tokens are claimed in epoch tranches\n * via ClaimQueuedWithdrawal. Call CancelQueuedWithdrawal to abort.\n *\n * Accounts: [user(signer,writable), slab(writable), lpVaultState, withdrawQueue(writable), systemProgram]\n *\n * @param lpAmount - Amount of LP tokens to queue for withdrawal.\n *\n * @example\n * ```ts\n * const data = encodeQueueWithdrawal({ lpAmount: 1_000_000_000n });\n * ```\n */\nexport function encodeQueueWithdrawal(args: { lpAmount: bigint | string }): Uint8Array {\n return concatBytes(encU8(IX_TAG.QueueWithdrawal), encU64(args.lpAmount));\n}\n\n/**\n * ClaimQueuedWithdrawal (Tag 48, PERC-309) — claim one epoch tranche from a queued withdrawal.\n *\n * Burns LP tokens and releases one tranche of SOL to the user.\n * Call once per epoch until epochs_remaining == 0.\n *\n * Accounts: [user(signer,writable), slab(writable), withdrawQueue(writable),\n * lpVaultMint(writable), userLpAta(writable), vault(writable),\n * userAta(writable), vaultAuthority, tokenProgram, lpVaultState(writable)]\n */\nexport function encodeClaimQueuedWithdrawal(): Uint8Array {\n return encU8(IX_TAG.ClaimQueuedWithdrawal);\n}\n\n/**\n * CancelQueuedWithdrawal (Tag 49, PERC-309) — cancel a queued withdrawal, refund remaining LP.\n *\n * Closes the withdraw_queue PDA and returns its rent lamports to the user.\n * The queued LP amount that was not yet claimed is NOT refunded — it is burned.\n * Use only to abandon a partial withdrawal.\n *\n * Accounts: [user(signer,writable), slab, withdrawQueue(writable)]\n */\nexport function encodeCancelQueuedWithdrawal(): Uint8Array {\n return encU8(IX_TAG.CancelQueuedWithdrawal);\n}\n\n// ============================================================================\n// PERC-305: ExecuteAdl (Tag 50) — Auto-Deleverage\n// ============================================================================\n\n/**\n * ExecuteAdl (Tag 50, PERC-305) — auto-deleverage the most profitable position.\n *\n * Permissionless. Surgically closes or reduces `targetIdx` position when\n * `pnl_pos_tot > max_pnl_cap` on the market. The caller receives no reward —\n * the incentive is unblocking the market for normal trading.\n *\n * Requires `UpdateRiskParams.max_pnl_cap > 0` on the market.\n *\n * Accounts: [caller(signer), slab(writable), clock, oracle, ...backupOracles?]\n *\n * @param targetIdx - Account index of the position to deleverage.\n *\n * @example\n * ```ts\n * const data = encodeExecuteAdl({ targetIdx: 5 });\n * ```\n */\nexport interface ExecuteAdlArgs {\n targetIdx: number;\n}\n\nexport function encodeExecuteAdl(args: ExecuteAdlArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.ExecuteAdl), encU16(args.targetIdx));\n}\n\n// ============================================================================\n// CloseStaleSlabs (Tag 51) / ReclaimSlabRent (Tag 52) — Slab recovery\n// ============================================================================\n\n/**\n * CloseStaleSlabs (Tag 51) — close a slab of an invalid/old layout and recover rent SOL.\n *\n * Admin only. Skips slab_guard; validates header magic + admin authority instead.\n * Use for slabs created by old program layouts (e.g. pre-PERC-120 devnet deploys)\n * whose size does not match any current valid tier.\n *\n * Accounts: [dest(signer,writable), slab(writable)]\n */\nexport function encodeCloseStaleSlabs(): Uint8Array {\n return encU8(IX_TAG.CloseStaleSlabs);\n}\n\n/**\n * ReclaimSlabRent (Tag 52) — reclaim rent from an uninitialised slab.\n *\n * For use when market creation failed mid-flow (slab funded but InitMarket not called).\n * The slab account must sign (proves the caller holds the slab keypair).\n * Cannot close an initialised slab (magic == PERCOLAT) — use CloseSlab (tag 13).\n *\n * Accounts: [dest(signer,writable), slab(signer,writable)]\n */\nexport function encodeReclaimSlabRent(): Uint8Array {\n return encU8(IX_TAG.ReclaimSlabRent);\n}\n\n// ============================================================================\n// AuditCrank (Tag 53) — Permissionless on-chain invariant check\n// ============================================================================\n\n/**\n * AuditCrank (Tag 53) — verify conservation invariants on-chain (permissionless).\n *\n * Walks all accounts and verifies: capital sum, pnl_pos_tot, total_oi, LP consistency,\n * and solvency. Sets FLAG_PAUSED on violation (with a 150-slot cooldown guard to\n * prevent DoS from transient failures).\n *\n * Accounts: [slab(writable)]\n *\n * @example\n * ```ts\n * const data = encodeAuditCrank();\n * ```\n */\nexport function encodeAuditCrank(): Uint8Array {\n return encU8(IX_TAG.AuditCrank);\n}\n\n// ============================================================================\n// SMART PRICE ROUTER — quote computation for LP selection\n// ============================================================================\n\n/**\n * Parsed vAMM matcher parameters (from on-chain matcher context account)\n */\nexport interface VammMatcherParams {\n mode: number; // 0 = Passive, 1 = vAMM\n tradingFeeBps: number;\n baseSpreadBps: number;\n maxTotalBps: number;\n impactKBps: number;\n liquidityNotionalE6: bigint;\n}\n\n/** Magic bytes identifying a vAMM matcher context: \"PERCMATC\" as u64 LE */\nexport const VAMM_MAGIC = 0x5045_5243_4d41_5443n;\n\n/** Offset into matcher context where vAMM params start */\nexport const CTX_VAMM_OFFSET = 64;\n\nconst BPS_DENOM = 10_000n;\n\n/**\n * Compute execution price for a given LP quote.\n * For buys (isLong=true): price above oracle.\n * For sells (isLong=false): price below oracle.\n */\nexport function computeVammQuote(\n params: VammMatcherParams,\n oraclePriceE6: bigint,\n tradeSize: bigint,\n isLong: boolean,\n): bigint {\n const absSize = tradeSize < 0n ? -tradeSize : tradeSize;\n const absNotionalE6 = (absSize * oraclePriceE6) / 1_000_000n;\n\n // Impact for vAMM mode\n let impactBps = 0n;\n if (params.mode === 1 && params.liquidityNotionalE6 > 0n) {\n impactBps = (absNotionalE6 * BigInt(params.impactKBps)) / params.liquidityNotionalE6;\n }\n\n // Total = base_spread + trading_fee + impact, capped at max_total\n const maxTotal = BigInt(params.maxTotalBps);\n const baseFee = BigInt(params.baseSpreadBps) + BigInt(params.tradingFeeBps);\n const maxImpact = maxTotal > baseFee ? maxTotal - baseFee : 0n;\n const clampedImpact = impactBps < maxImpact ? impactBps : maxImpact;\n let totalBps = baseFee + clampedImpact;\n if (totalBps > maxTotal) totalBps = maxTotal;\n\n if (isLong) {\n return (oraclePriceE6 * (BPS_DENOM + totalBps)) / BPS_DENOM;\n } else {\n // Prevent underflow: if totalBps >= BPS_DENOM, price would go negative\n if (totalBps >= BPS_DENOM) return 1n; // minimum 1 micro-dollar\n return (oraclePriceE6 * (BPS_DENOM - totalBps)) / BPS_DENOM;\n }\n}\n\n// ============================================================================\n// PERC-622: AdvanceOraclePhase (permissionless crank)\n// ============================================================================\n\n/**\n * AdvanceOraclePhase (Tag 56) — permissionless oracle phase advancement.\n *\n * Checks if a market should transition from Phase 0→1→2 based on\n * time elapsed and cumulative volume. Anyone can call this.\n *\n * Instruction data: 1 byte (tag only)\n *\n * Accounts:\n * 0. [writable] Slab\n */\nexport function encodeAdvanceOraclePhase(): Uint8Array {\n return encU8(IX_TAG.AdvanceOraclePhase);\n}\n\n/** Oracle phase constants matching on-chain values */\nexport const ORACLE_PHASE_NASCENT = 0;\nexport const ORACLE_PHASE_GROWING = 1;\nexport const ORACLE_PHASE_MATURE = 2;\n\n/** Phase transition thresholds (must match program constants) */\nexport const PHASE1_MIN_SLOTS = 648_000n; // ~72h at 400ms\nexport const PHASE1_VOLUME_MIN_SLOTS = 36_000n; // ~4h at 400ms\nexport const PHASE2_VOLUME_THRESHOLD = 100_000_000_000n; // $100K in e6\nexport const PHASE2_MATURITY_SLOTS = 3_024_000n; // ~14 days at 400ms\n\n/**\n * Check if an oracle phase transition is due (TypeScript mirror of on-chain logic).\n *\n * @returns [newPhase, shouldTransition]\n */\nexport function checkPhaseTransition(\n currentSlot: bigint,\n marketCreatedSlot: bigint,\n oraclePhase: number,\n cumulativeVolumeE6: bigint,\n phase2DeltaSlots: number,\n hasMatureOracle: boolean,\n): [number, boolean] {\n switch (oraclePhase) {\n case 0: {\n const elapsed = currentSlot - (marketCreatedSlot > 0n ? marketCreatedSlot : currentSlot);\n const timeReady = elapsed >= PHASE1_MIN_SLOTS;\n const volumeReady = elapsed >= PHASE1_VOLUME_MIN_SLOTS\n && cumulativeVolumeE6 >= PHASE2_VOLUME_THRESHOLD;\n if (timeReady || volumeReady) {\n return [ORACLE_PHASE_GROWING, true];\n }\n return [ORACLE_PHASE_NASCENT, false];\n }\n case 1: {\n if (hasMatureOracle) return [ORACLE_PHASE_MATURE, true];\n const phase2Start = marketCreatedSlot + BigInt(phase2DeltaSlots);\n const elapsedSincePhase2 = currentSlot - phase2Start;\n if (elapsedSincePhase2 >= PHASE2_MATURITY_SLOTS) {\n return [ORACLE_PHASE_MATURE, true];\n }\n return [ORACLE_PHASE_GROWING, false];\n }\n default:\n return [ORACLE_PHASE_MATURE, false];\n }\n}\n\n// ============================================================================\n// PERC-623: Keeper Fund Instructions\n// ============================================================================\n\n/**\n * TopUpKeeperFund (Tag 57) — permissionless keeper fund top-up.\n *\n * Instruction data: tag(1) + amount(8) = 9 bytes\n *\n * Accounts:\n * 0. [signer, writable] Funder\n * 1. [writable] Slab\n * 2. [writable] Keeper fund PDA\n * 3. [] System program\n */\nexport interface TopUpKeeperFundArgs {\n amount: bigint | string;\n}\n\nexport function encodeTopUpKeeperFund(args: TopUpKeeperFundArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.TopUpKeeperFund), encU64(args.amount));\n}\n\n// Note: WithdrawKeeperReward does NOT exist as a separate instruction.\n// Keeper rewards are paid automatically during KeeperCrank (tag 5).\n// The keeper fund PDA is debited in-place when a successful crank is executed.\n\n// ============================================================================\n// PERC-629: Dynamic Creation Deposit\n// ============================================================================\n\n/**\n * SlashCreationDeposit (Tag 58) — permissionless: slash a market creator's deposit\n * after the spam grace period has elapsed (PERC-629).\n *\n * **WARNING**: Tag 58 is reserved in tags.rs but has NO instruction decoder or\n * handler in the on-chain program. Sending this instruction will fail with\n * `InvalidInstructionData`. Do not use until the on-chain handler is deployed.\n *\n * Instruction data: 1 byte (tag only)\n *\n * Accounts:\n * 0. [signer] Caller (anyone)\n * 1. [] Slab\n * 2. [writable] Creator history PDA\n * 3. [writable] Insurance vault\n * 4. [writable] Treasury\n * 5. [] System program\n *\n * @deprecated Not yet implemented on-chain — will fail with InvalidInstructionData.\n */\nexport function encodeSlashCreationDeposit(): Uint8Array {\n return encU8(IX_TAG.SlashCreationDeposit);\n}\n\n// ============================================================================\n// PERC-628: Elastic Shared Vault + Epoch Withdrawals\n// ============================================================================\n\n/**\n * InitSharedVault (Tag 59) — admin: create the global shared vault PDA (PERC-628).\n *\n * Instruction data: tag(1) + epochDurationSlots(8) + maxMarketExposureBps(2) = 11 bytes\n *\n * Accounts:\n * 0. [signer] Admin\n * 1. [writable] Shared vault PDA\n * 2. [] System program\n */\nexport interface InitSharedVaultArgs {\n epochDurationSlots: bigint | string;\n maxMarketExposureBps: number;\n}\n\nexport function encodeInitSharedVault(args: InitSharedVaultArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.InitSharedVault),\n encU64(args.epochDurationSlots),\n encU16(args.maxMarketExposureBps),\n );\n}\n\n/**\n * AllocateMarket (Tag 60) — admin: allocate virtual liquidity from the shared vault\n * to a market (PERC-628).\n *\n * Instruction data: tag(1) + amount(16) = 17 bytes\n *\n * Accounts:\n * 0. [signer] Admin\n * 1. [] Slab\n * 2. [writable] Shared vault PDA\n * 3. [writable] Market alloc PDA\n * 4. [] System program\n */\nexport interface AllocateMarketArgs {\n amount: bigint | string;\n}\n\nexport function encodeAllocateMarket(args: AllocateMarketArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.AllocateMarket), encU128(args.amount));\n}\n\n/**\n * QueueWithdrawalSV (Tag 61) — user: queue a withdrawal request for the current\n * epoch (PERC-628). Tokens are locked until the epoch elapses.\n *\n * Instruction data: tag(1) + lpAmount(8) = 9 bytes\n *\n * Accounts:\n * 0. [signer] User\n * 1. [writable] Shared vault PDA\n * 2. [writable] Withdraw request PDA\n * 3. [] System program\n */\nexport interface QueueWithdrawalSVArgs {\n lpAmount: bigint | string;\n}\n\nexport function encodeQueueWithdrawalSV(args: QueueWithdrawalSVArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.QueueWithdrawalSV), encU64(args.lpAmount));\n}\n\n/**\n * ClaimEpochWithdrawal (Tag 62) — user: claim a queued withdrawal after the epoch\n * has elapsed (PERC-628). Receives pro-rata collateral from the vault.\n *\n * Instruction data: 1 byte (tag only)\n *\n * Accounts:\n * 0. [signer] User\n * 1. [writable] Shared vault PDA\n * 2. [writable] Withdraw request PDA\n * 3. [] Slab\n * 4. [writable] Vault\n * 5. [writable] User ATA\n * 6. [] Vault authority\n * 7. [] Token program\n */\nexport function encodeClaimEpochWithdrawal(): Uint8Array {\n return encU8(IX_TAG.ClaimEpochWithdrawal);\n}\n\n/**\n * AdvanceEpoch (Tag 63) — permissionless crank: move the shared vault to the next\n * epoch once `epoch_duration_slots` have elapsed (PERC-628).\n *\n * Instruction data: 1 byte (tag only)\n *\n * Accounts:\n * 0. [signer] Caller (anyone)\n * 1. [writable] Shared vault PDA\n */\nexport function encodeAdvanceEpoch(): Uint8Array {\n return encU8(IX_TAG.AdvanceEpoch);\n}\n\n// PERC-628: Tag 63 ─────────────────────────────────────────────────────────\n\n// PERC-8110 ────────────────────────────────────────────────────────────────\n\n/**\n * SetOiImbalanceHardBlock (Tag 71, PERC-8110) — set OI imbalance hard-block threshold (admin only).\n *\n * When `|long_oi − short_oi| / total_oi * 10_000 >= threshold_bps`, any new trade that would\n * *increase* the imbalance is rejected with `OiImbalanceHardBlock` (error code 59).\n *\n * - `threshold_bps = 0`: hard block disabled.\n * - `threshold_bps = 8_000`: block trades that push skew above 80%.\n * - `threshold_bps = 10_000`: never allow >100% skew (always blocks one side when oi > 0).\n *\n * Instruction data layout: tag(1) + threshold_bps(2) = 3 bytes\n *\n * Accounts:\n * 0. [signer] admin\n * 1. [writable] slab\n *\n * @example\n * ```ts\n * const ix = new TransactionInstruction({\n * programId: PROGRAM_ID,\n * keys: buildAccountMetas(ACCOUNTS_SET_OI_IMBALANCE_HARD_BLOCK, { admin, slab }),\n * data: Buffer.from(encodeSetOiImbalanceHardBlock({ thresholdBps: 8_000 })),\n * });\n * ```\n */\nexport function encodeSetOiImbalanceHardBlock(args: { thresholdBps: number }): Uint8Array {\n if (args.thresholdBps < 0 || args.thresholdBps > 10_000) {\n throw new Error(`encodeSetOiImbalanceHardBlock: thresholdBps must be 0–10_000, got ${args.thresholdBps}`);\n }\n return concatBytes(encU8(IX_TAG.SetOiImbalanceHardBlock), encU16(args.thresholdBps));\n}\n\n// ============================================================================\n// PERC-608 — Position NFT instructions (tags 64–69)\n// ============================================================================\n\n/**\n * MintPositionNft (Tag 64, PERC-608) — mint a Token-2022 NFT representing a position.\n *\n * Creates a PositionNft PDA + Token-2022 mint with metadata, then mints 1 NFT to the\n * position owner's ATA. The NFT represents ownership of `user_idx` in the slab.\n *\n * Instruction data layout: tag(1) + user_idx(2) = 3 bytes\n *\n * Accounts:\n * 0. [signer, writable] payer\n * 1. [writable] slab\n * 2. [writable] position_nft PDA (created — seeds: [\"position_nft\", slab, user_idx])\n * 3. [writable] nft_mint PDA (created)\n * 4. [writable] owner_ata (Token-2022 ATA for owner)\n * 5. [signer] owner (must match engine account owner)\n * 6. [] vault_authority PDA\n * 7. [] token_2022_program\n * 8. [] system_program\n * 9. [] rent sysvar\n *\n * @example\n * ```ts\n * const ix = new TransactionInstruction({\n * programId: PROGRAM_ID,\n * keys: buildAccountMetas(ACCOUNTS_MINT_POSITION_NFT, [payer, slab, nftPda, nftMint, ownerAta, owner, vaultAuth, TOKEN_2022_PROGRAM_ID, SystemProgram.programId, SYSVAR_RENT_PUBKEY]),\n * data: Buffer.from(encodeMintPositionNft({ userIdx: 5 })),\n * });\n * ```\n */\nexport interface MintPositionNftArgs {\n userIdx: number;\n}\n\nexport function encodeMintPositionNft(args: MintPositionNftArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.MintPositionNft), encU16(args.userIdx));\n}\n\n/**\n * TransferPositionOwnership (Tag 65, PERC-608) — transfer an open position to a new owner.\n *\n * Transfers the Token-2022 NFT from current owner to new owner and updates the on-chain\n * engine account's owner field. Requires `pending_settlement == 0`.\n *\n * Instruction data layout: tag(1) + user_idx(2) = 3 bytes\n *\n * Accounts:\n * 0. [signer, writable] current_owner\n * 1. [writable] slab\n * 2. [writable] position_nft PDA\n * 3. [writable] nft_mint PDA\n * 4. [writable] current_owner_ata (source Token-2022 ATA)\n * 5. [writable] new_owner_ata (destination Token-2022 ATA)\n * 6. [] new_owner\n * 7. [] token_2022_program\n */\nexport interface TransferPositionOwnershipArgs {\n userIdx: number;\n}\n\nexport function encodeTransferPositionOwnership(args: TransferPositionOwnershipArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.TransferPositionOwnership), encU16(args.userIdx));\n}\n\n/**\n * BurnPositionNft (Tag 66, PERC-608) — burn the Position NFT when a position is closed.\n *\n * Burns the NFT, closes the PositionNft PDA and the mint PDA, returning rent to the owner.\n * Can only be called after the position is fully closed (size == 0).\n *\n * Instruction data layout: tag(1) + user_idx(2) = 3 bytes\n *\n * Accounts:\n * 0. [signer, writable] owner\n * 1. [writable] slab\n * 2. [writable] position_nft PDA (closed — rent to owner)\n * 3. [writable] nft_mint PDA (closed via Token-2022 close_account)\n * 4. [writable] owner_ata (Token-2022 ATA, balance burned)\n * 5. [] vault_authority PDA\n * 6. [] token_2022_program\n */\nexport interface BurnPositionNftArgs {\n userIdx: number;\n}\n\nexport function encodeBurnPositionNft(args: BurnPositionNftArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.BurnPositionNft), encU16(args.userIdx));\n}\n\n/**\n * SetPendingSettlement (Tag 67, PERC-608) — keeper sets the pending_settlement flag.\n *\n * Called by the keeper/admin before performing a funding settlement transfer.\n * Blocks NFT transfers until ClearPendingSettlement is called.\n * Admin-only (protected by GH#1475 keeper allowlist guard).\n *\n * Instruction data layout: tag(1) + user_idx(2) = 3 bytes\n *\n * Accounts:\n * 0. [signer] keeper / admin\n * 1. [] slab (read — for PDA verification + admin check)\n * 2. [writable] position_nft PDA\n */\nexport interface SetPendingSettlementArgs {\n userIdx: number;\n}\n\nexport function encodeSetPendingSettlement(args: SetPendingSettlementArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.SetPendingSettlement), encU16(args.userIdx));\n}\n\n/**\n * ClearPendingSettlement (Tag 68, PERC-608) — keeper clears the pending_settlement flag.\n *\n * Called by the keeper/admin after KeeperCrank has run and funding is settled.\n * Admin-only (protected by GH#1475 keeper allowlist guard).\n *\n * Instruction data layout: tag(1) + user_idx(2) = 3 bytes\n *\n * Accounts:\n * 0. [signer] keeper / admin\n * 1. [] slab (read — for PDA verification + admin check)\n * 2. [writable] position_nft PDA\n */\nexport interface ClearPendingSettlementArgs {\n userIdx: number;\n}\n\nexport function encodeClearPendingSettlement(args: ClearPendingSettlementArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.ClearPendingSettlement), encU16(args.userIdx));\n}\n\n/**\n * TransferOwnershipCpi (Tag 69, PERC-608) — internal CPI target for percolator-nft TransferHook.\n *\n * Called by the Token-2022 TransferHook on the percolator-nft program during an NFT transfer.\n * Updates the engine account's owner field to the new_owner public key.\n * NOT intended for direct external use — always called via Token-2022 CPI.\n *\n * Instruction data layout: tag(1) + user_idx(2) + new_owner(32) = 35 bytes\n *\n * Accounts:\n * 0. [signer] nft TransferHook program (CPI caller)\n * 1. [writable] slab\n * (remaining accounts per Token-2022 ExtraAccountMeta spec)\n */\nexport interface TransferOwnershipCpiArgs {\n userIdx: number;\n newOwner: PublicKey | string;\n}\n\nexport function encodeTransferOwnershipCpi(args: TransferOwnershipCpiArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.TransferOwnershipCpi),\n encU16(args.userIdx),\n encPubkey(args.newOwner),\n );\n}\n\n// ============================================================================\n// PERC-8111 — SetWalletCap (tag 70)\n// ============================================================================\n\n/**\n * SetWalletCap (Tag 70, PERC-8111) — set the per-wallet position cap (admin only).\n *\n * Limits the maximum absolute position size any single wallet may hold on this market.\n * Enforced on every trade (TradeNoCpi + TradeCpi) after execute_trade.\n *\n * - `capE6 = 0`: disable per-wallet cap (no limit, default).\n * - `capE6 > 0`: max |position_size| in e6 units ($1 = 1_000_000).\n * Phase 1 launch value: 1_000_000_000n ($1,000).\n *\n * When a trade would breach the cap, the on-chain error `WalletPositionCapExceeded`\n * (error code 58) is returned.\n *\n * Instruction data layout: tag(1) + cap_e6(8) = 9 bytes\n *\n * Accounts:\n * 0. [signer] admin\n * 1. [writable] slab\n *\n * @example\n * ```ts\n * // Set $1K per-wallet cap\n * const ix = new TransactionInstruction({\n * programId: PROGRAM_ID,\n * keys: buildAccountMetas(ACCOUNTS_SET_WALLET_CAP, [admin, slab]),\n * data: Buffer.from(encodeSetWalletCap({ capE6: 1_000_000_000n })),\n * });\n *\n * // Disable cap\n * const disableIx = new TransactionInstruction({\n * programId: PROGRAM_ID,\n * keys: buildAccountMetas(ACCOUNTS_SET_WALLET_CAP, [admin, slab]),\n * data: Buffer.from(encodeSetWalletCap({ capE6: 0n })),\n * });\n * ```\n */\nexport interface SetWalletCapArgs {\n /** Max position size in e6 units. 0 = disabled. $1 = 1_000_000n, $1K = 1_000_000_000n. */\n capE6: bigint | string;\n}\n\nexport function encodeSetWalletCap(args: SetWalletCapArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.SetWalletCap), encU64(args.capE6));\n}\n","import {\n PublicKey,\n AccountMeta,\n SYSVAR_CLOCK_PUBKEY,\n SYSVAR_RENT_PUBKEY,\n SystemProgram,\n} from \"@solana/web3.js\";\nimport { TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\n\n/**\n * Account spec for building instruction account metas.\n * Each instruction has a fixed ordering that matches the Rust processor.\n */\nexport interface AccountSpec {\n name: string;\n signer: boolean;\n writable: boolean;\n}\n\n// ============================================================================\n// ACCOUNT ORDERINGS - Single source of truth\n// ============================================================================\n\n/**\n * InitMarket: 9 accounts (Pyth Pull - feed_id is in instruction data, not as accounts)\n */\nexport const ACCOUNTS_INIT_MARKET: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"mint\", signer: false, writable: false },\n { name: \"vault\", signer: false, writable: false },\n { name: \"tokenProgram\", signer: false, writable: false },\n { name: \"clock\", signer: false, writable: false },\n { name: \"rent\", signer: false, writable: false },\n { name: \"dummyAta\", signer: false, writable: false },\n { name: \"systemProgram\", signer: false, writable: false },\n] as const;\n\n/**\n * InitUser: 5 accounts (clock/oracle removed in commit 410f947)\n */\nexport const ACCOUNTS_INIT_USER: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"userAta\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"tokenProgram\", signer: false, writable: false },\n] as const;\n\n/**\n * InitLP: 5 accounts (clock/oracle removed in commit 410f947)\n */\nexport const ACCOUNTS_INIT_LP: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"userAta\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"tokenProgram\", signer: false, writable: false },\n] as const;\n\n/**\n * DepositCollateral: 6 accounts\n */\nexport const ACCOUNTS_DEPOSIT_COLLATERAL: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"userAta\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"tokenProgram\", signer: false, writable: false },\n { name: \"clock\", signer: false, writable: false },\n] as const;\n\n/**\n * WithdrawCollateral: 8 accounts\n */\nexport const ACCOUNTS_WITHDRAW_COLLATERAL: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"userAta\", signer: false, writable: true },\n { name: \"vaultPda\", signer: false, writable: false },\n { name: \"tokenProgram\", signer: false, writable: false },\n { name: \"clock\", signer: false, writable: false },\n { name: \"oracleIdx\", signer: false, writable: false },\n] as const;\n\n/**\n * KeeperCrank: 4 accounts\n */\nexport const ACCOUNTS_KEEPER_CRANK: readonly AccountSpec[] = [\n { name: \"caller\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"clock\", signer: false, writable: false },\n { name: \"oracle\", signer: false, writable: false },\n] as const;\n\n/**\n * TradeNoCpi: 4 accounts (PERC-199: clock sysvar removed — uses Clock::get() syscall)\n */\nexport const ACCOUNTS_TRADE_NOCPI: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"lp\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"oracle\", signer: false, writable: false },\n] as const;\n\n/**\n * LiquidateAtOracle: 4 accounts\n * Note: account[0] is unused but must be present\n */\nexport const ACCOUNTS_LIQUIDATE_AT_ORACLE: readonly AccountSpec[] = [\n { name: \"unused\", signer: false, writable: false },\n { name: \"slab\", signer: false, writable: true },\n { name: \"clock\", signer: false, writable: false },\n { name: \"oracle\", signer: false, writable: false },\n] as const;\n\n/**\n * CloseAccount: 8 accounts\n */\nexport const ACCOUNTS_CLOSE_ACCOUNT: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"userAta\", signer: false, writable: true },\n { name: \"vaultPda\", signer: false, writable: false },\n { name: \"tokenProgram\", signer: false, writable: false },\n { name: \"clock\", signer: false, writable: false },\n { name: \"oracle\", signer: false, writable: false },\n] as const;\n\n/**\n * TopUpInsurance: 5 accounts\n */\nexport const ACCOUNTS_TOPUP_INSURANCE: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"userAta\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"tokenProgram\", signer: false, writable: false },\n] as const;\n\n/**\n * TradeCpi: 7 accounts (PERC-199: clock sysvar removed — uses Clock::get() syscall)\n */\nexport const ACCOUNTS_TRADE_CPI: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"lpOwner\", signer: false, writable: false }, // LP delegated to matcher - no signature needed\n { name: \"slab\", signer: false, writable: true },\n { name: \"oracle\", signer: false, writable: false },\n { name: \"matcherProg\", signer: false, writable: false },\n { name: \"matcherCtx\", signer: false, writable: true },\n { name: \"lpPda\", signer: false, writable: false },\n] as const;\n\n/**\n * SetRiskThreshold: 2 accounts\n */\nexport const ACCOUNTS_SET_RISK_THRESHOLD: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * UpdateAdmin: 2 accounts\n */\nexport const ACCOUNTS_UPDATE_ADMIN: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * CloseSlab: 2 accounts\n */\nexport const ACCOUNTS_CLOSE_SLAB: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * UpdateConfig: 2 accounts\n */\nexport const ACCOUNTS_UPDATE_CONFIG: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * SetMaintenanceFee: 2 accounts\n */\nexport const ACCOUNTS_SET_MAINTENANCE_FEE: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * SetOracleAuthority: 2 accounts\n * Sets the oracle price authority (admin only)\n */\nexport const ACCOUNTS_SET_ORACLE_AUTHORITY: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * SetOraclePriceCap: 2 accounts\n * Set oracle price circuit breaker cap (admin only)\n */\nexport const ACCOUNTS_SET_ORACLE_PRICE_CAP: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * PushOraclePrice: 2 accounts\n * Push oracle price (oracle authority only)\n */\nexport const ACCOUNTS_PUSH_ORACLE_PRICE: readonly AccountSpec[] = [\n { name: \"authority\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * ResolveMarket: 2 accounts\n * Resolves a binary/premarket (admin only)\n */\nexport const ACCOUNTS_RESOLVE_MARKET: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * WithdrawInsurance: 6 accounts\n * Withdraw insurance fund after market resolution (admin only)\n */\nexport const ACCOUNTS_WITHDRAW_INSURANCE: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"adminAta\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"tokenProgram\", signer: false, writable: false },\n { name: \"vaultPda\", signer: false, writable: false },\n] as const;\n\n/**\n * PauseMarket: 2 accounts\n */\nexport const ACCOUNTS_PAUSE_MARKET: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * UnpauseMarket: 2 accounts\n */\nexport const ACCOUNTS_UNPAUSE_MARKET: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n// ============================================================================\n// ACCOUNT META BUILDERS\n// ============================================================================\n\n/**\n * Build AccountMeta array from spec and provided pubkeys.\n *\n * Accepts either:\n * - `PublicKey[]` — ordered array, one entry per spec account (legacy form)\n * - `Record<string, PublicKey>` — named map keyed by account `name` (preferred form)\n *\n * Named-map form resolves accounts by spec name so callers don't have to\n * remember the positional order, and errors clearly on missing names.\n */\nexport function buildAccountMetas(\n spec: readonly AccountSpec[],\n keys: PublicKey[] | Record<string, PublicKey>\n): AccountMeta[] {\n let keysArray: PublicKey[];\n\n if (Array.isArray(keys)) {\n keysArray = keys;\n } else {\n // Named map: resolve by spec name\n keysArray = spec.map((s) => {\n const key = (keys as Record<string, PublicKey>)[s.name];\n if (!key) {\n throw new Error(\n `buildAccountMetas: missing key for account \"${s.name}\". ` +\n `Provided keys: [${Object.keys(keys).join(\", \")}]`\n );\n }\n return key;\n });\n }\n\n if (keysArray.length !== spec.length) {\n throw new Error(\n `Account count mismatch: expected ${spec.length}, got ${keysArray.length}`\n );\n }\n return spec.map((s, i) => ({\n pubkey: keysArray[i],\n isSigner: s.signer,\n isWritable: s.writable,\n }));\n}\n\n/**\n * CreateInsuranceMint: 9 accounts\n * Creates SPL mint PDA for insurance LP tokens. Admin only, once per market.\n */\nexport const ACCOUNTS_CREATE_INSURANCE_MINT: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: false },\n { name: \"slab\", signer: false, writable: false },\n { name: \"insLpMint\", signer: false, writable: true },\n { name: \"vaultAuthority\", signer: false, writable: false },\n { name: \"collateralMint\", signer: false, writable: false },\n { name: \"systemProgram\", signer: false, writable: false },\n { name: \"tokenProgram\", signer: false, writable: false },\n { name: \"rent\", signer: false, writable: false },\n { name: \"payer\", signer: true, writable: true },\n] as const;\n\n/**\n * DepositInsuranceLP: 8 accounts\n * Deposit collateral into insurance fund, receive LP tokens.\n */\nexport const ACCOUNTS_DEPOSIT_INSURANCE_LP: readonly AccountSpec[] = [\n { name: \"depositor\", signer: true, writable: false },\n { name: \"slab\", signer: false, writable: true },\n { name: \"depositorAta\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"tokenProgram\", signer: false, writable: false },\n { name: \"insLpMint\", signer: false, writable: true },\n { name: \"depositorLpAta\", signer: false, writable: true },\n { name: \"vaultAuthority\", signer: false, writable: false },\n] as const;\n\n/**\n * WithdrawInsuranceLP: 8 accounts\n * Burn LP tokens and withdraw proportional share of insurance fund.\n */\nexport const ACCOUNTS_WITHDRAW_INSURANCE_LP: readonly AccountSpec[] = [\n { name: \"withdrawer\", signer: true, writable: false },\n { name: \"slab\", signer: false, writable: true },\n { name: \"withdrawerAta\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"tokenProgram\", signer: false, writable: false },\n { name: \"insLpMint\", signer: false, writable: true },\n { name: \"withdrawerLpAta\", signer: false, writable: true },\n { name: \"vaultAuthority\", signer: false, writable: false },\n] as const;\n\n// ============================================================================\n// PERC-627 / GH#1926: LpVaultWithdraw (tag 39)\n// ============================================================================\n\n/**\n * LpVaultWithdraw: 10 accounts (tag 39, PERC-627 / GH#1926 / PERC-8287)\n *\n * Burn LP vault tokens and withdraw proportional collateral from the LP vault.\n *\n * accounts[9] = creatorLockPda is REQUIRED since percolator-prog PR#170.\n * Non-creator withdrawers must pass the derived PDA key; if no lock exists\n * on-chain the enforcement is a no-op. Omitting it was the bypass vector\n * fixed in GH#1926. Use `deriveCreatorLockPda(programId, slab)` to compute.\n *\n * Accounts:\n * [0] withdrawer signer, read-only\n * [1] slab writable\n * [2] withdrawerAta writable (collateral destination)\n * [3] vault writable (collateral source)\n * [4] tokenProgram read-only\n * [5] lpVaultMint writable (LP tokens burned from here)\n * [6] withdrawerLpAta writable (LP tokens source)\n * [7] vaultAuthority read-only (PDA that signs token transfers)\n * [8] lpVaultState writable\n * [9] creatorLockPda writable (REQUIRED — derived from [\"creator_lock\", slab])\n */\nexport const ACCOUNTS_LP_VAULT_WITHDRAW: readonly AccountSpec[] = [\n { name: \"withdrawer\", signer: true, writable: false },\n { name: \"slab\", signer: false, writable: true },\n { name: \"withdrawerAta\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"tokenProgram\", signer: false, writable: false },\n { name: \"lpVaultMint\", signer: false, writable: true },\n { name: \"withdrawerLpAta\", signer: false, writable: true },\n { name: \"vaultAuthority\", signer: false, writable: false },\n { name: \"lpVaultState\", signer: false, writable: true },\n { name: \"creatorLockPda\", signer: false, writable: true },\n] as const;\n\n/**\n * FundMarketInsurance: 5 accounts (PERC-306)\n * Fund per-market isolated insurance balance.\n */\nexport const ACCOUNTS_FUND_MARKET_INSURANCE: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"adminAta\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"tokenProgram\", signer: false, writable: false },\n] as const;\n\n/**\n * SetInsuranceIsolation: 2 accounts (PERC-306)\n * Set max % of global fund this market can access.\n */\nexport const ACCOUNTS_SET_INSURANCE_ISOLATION: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: false },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n// ============================================================================\n// PERC-309: QueueWithdrawal / ClaimQueuedWithdrawal / CancelQueuedWithdrawal\n// ============================================================================\n\n/**\n * QueueWithdrawal: 5 accounts (PERC-309)\n * User queues a large LP withdrawal. Creates withdraw_queue PDA.\n */\nexport const ACCOUNTS_QUEUE_WITHDRAWAL: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"lpVaultState\", signer: false, writable: false },\n { name: \"withdrawQueue\", signer: false, writable: true },\n { name: \"systemProgram\", signer: false, writable: false },\n] as const;\n\n/**\n * ClaimQueuedWithdrawal: 10 accounts (PERC-309)\n * Burns LP tokens and releases one epoch tranche of SOL.\n */\nexport const ACCOUNTS_CLAIM_QUEUED_WITHDRAWAL: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"withdrawQueue\", signer: false, writable: true },\n { name: \"lpVaultMint\", signer: false, writable: true },\n { name: \"userLpAta\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"userAta\", signer: false, writable: true },\n { name: \"vaultAuthority\", signer: false, writable: false },\n { name: \"tokenProgram\", signer: false, writable: false },\n { name: \"lpVaultState\", signer: false, writable: true },\n] as const;\n\n/**\n * CancelQueuedWithdrawal: 3 accounts (PERC-309)\n * Cancels queue, closes withdraw_queue PDA, returns rent to user.\n */\nexport const ACCOUNTS_CANCEL_QUEUED_WITHDRAWAL: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: false },\n { name: \"withdrawQueue\", signer: false, writable: true },\n] as const;\n\n// ============================================================================\n// PERC-305: ExecuteAdl (tag 50) — Auto-Deleverage\n// ============================================================================\n\n/**\n * ExecuteAdl: 4+ accounts (PERC-305, tag 50)\n * Permissionless — surgically close/reduce the most profitable position\n * when pnl_pos_tot > max_pnl_cap. For non-Hyperp markets with backup oracles,\n * pass additional oracle accounts at accounts[4..].\n */\nexport const ACCOUNTS_EXECUTE_ADL: readonly AccountSpec[] = [\n { name: \"caller\", signer: true, writable: false },\n { name: \"slab\", signer: false, writable: true },\n { name: \"clock\", signer: false, writable: false },\n { name: \"oracle\", signer: false, writable: false },\n] as const;\n\n// ============================================================================\n// CloseStaleSlabs (tag 51) / ReclaimSlabRent (tag 52)\n// ============================================================================\n\n/**\n * CloseStaleSlabs: 2 accounts (tag 51)\n * Admin closes a slab of an invalid/old layout and recovers rent SOL.\n */\nexport const ACCOUNTS_CLOSE_STALE_SLABS: readonly AccountSpec[] = [\n { name: \"dest\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * ReclaimSlabRent: 2 accounts (tag 52)\n * Reclaim rent from an uninitialised slab. Both dest and slab must sign.\n */\nexport const ACCOUNTS_RECLAIM_SLAB_RENT: readonly AccountSpec[] = [\n { name: \"dest\", signer: true, writable: true },\n { name: \"slab\", signer: true, writable: true },\n] as const;\n\n// ============================================================================\n// AuditCrank (tag 53) — Permissionless invariant check\n// ============================================================================\n\n/**\n * AuditCrank: 1 account (tag 53)\n * Permissionless. Verifies conservation invariants; pauses market on violation.\n */\nexport const ACCOUNTS_AUDIT_CRANK: readonly AccountSpec[] = [\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n// ============================================================================\n// PERC-622: AdvanceOraclePhase (permissionless)\n// ============================================================================\n\n/**\n * AdvanceOraclePhase: 1 account\n * Permissionless — no signer required beyond fee payer.\n */\nexport const ACCOUNTS_ADVANCE_ORACLE_PHASE: readonly AccountSpec[] = [\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n// ============================================================================\n// PERC-623: Keeper Fund Instructions\n// ============================================================================\n\n/**\n * TopUpKeeperFund: 3 accounts\n * Permissionless — anyone can fund. Transfers lamports directly (no system program).\n */\nexport const ACCOUNTS_TOPUP_KEEPER_FUND: readonly AccountSpec[] = [\n { name: \"funder\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"keeperFund\", signer: false, writable: true },\n] as const;\n\n// Note: WithdrawKeeperReward has no separate instruction.\n// Rewards are paid automatically during KeeperCrank (tag 5).\n\n// ============================================================================\n// PERC-8110: SetOiImbalanceHardBlock\n// ============================================================================\n\n/**\n * SetOiImbalanceHardBlock: 2 accounts\n * Sets the OI imbalance hard-block threshold (admin only)\n */\nexport const ACCOUNTS_SET_OI_IMBALANCE_HARD_BLOCK: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: false },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n// ============================================================================\n// PERC-608: Position NFT Instructions (tags 64–69)\n// ============================================================================\n\n/**\n * MintPositionNft: 10 accounts\n * Creates a Token-2022 position NFT for an open position.\n */\nexport const ACCOUNTS_MINT_POSITION_NFT: readonly AccountSpec[] = [\n { name: \"payer\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"positionNftPda\", signer: false, writable: true },\n { name: \"nftMint\", signer: false, writable: true },\n { name: \"ownerAta\", signer: false, writable: true },\n { name: \"owner\", signer: true, writable: false },\n { name: \"vaultAuthority\", signer: false, writable: false },\n { name: \"token2022Program\", signer: false, writable: false },\n { name: \"systemProgram\", signer: false, writable: false },\n { name: \"rent\", signer: false, writable: false },\n] as const;\n\n/**\n * TransferPositionOwnership: 8 accounts\n * Transfer position NFT and update on-chain owner. Requires pending_settlement == 0.\n */\nexport const ACCOUNTS_TRANSFER_POSITION_OWNERSHIP: readonly AccountSpec[] = [\n { name: \"currentOwner\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"positionNftPda\", signer: false, writable: true },\n { name: \"nftMint\", signer: false, writable: true },\n { name: \"currentOwnerAta\", signer: false, writable: true },\n { name: \"newOwnerAta\", signer: false, writable: true },\n { name: \"newOwner\", signer: false, writable: false },\n { name: \"token2022Program\", signer: false, writable: false },\n] as const;\n\n/**\n * BurnPositionNft: 7 accounts\n * Burns NFT and closes PositionNft + mint PDAs after position is closed.\n */\nexport const ACCOUNTS_BURN_POSITION_NFT: readonly AccountSpec[] = [\n { name: \"owner\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"positionNftPda\", signer: false, writable: true },\n { name: \"nftMint\", signer: false, writable: true },\n { name: \"ownerAta\", signer: false, writable: true },\n { name: \"vaultAuthority\", signer: false, writable: false },\n { name: \"token2022Program\", signer: false, writable: false },\n] as const;\n\n/**\n * SetPendingSettlement: 3 accounts\n * Keeper/admin sets pending_settlement flag before funding transfer.\n * Protected by admin allowlist (GH#1475).\n */\nexport const ACCOUNTS_SET_PENDING_SETTLEMENT: readonly AccountSpec[] = [\n { name: \"keeper\", signer: true, writable: false },\n { name: \"slab\", signer: false, writable: false },\n { name: \"positionNftPda\", signer: false, writable: true },\n] as const;\n\n/**\n * ClearPendingSettlement: 3 accounts\n * Keeper/admin clears pending_settlement flag after KeeperCrank.\n * Protected by admin allowlist (GH#1475).\n */\nexport const ACCOUNTS_CLEAR_PENDING_SETTLEMENT: readonly AccountSpec[] = [\n { name: \"keeper\", signer: true, writable: false },\n { name: \"slab\", signer: false, writable: false },\n { name: \"positionNftPda\", signer: false, writable: true },\n] as const;\n\n// ============================================================================\n// PERC-8111: SetWalletCap\n// ============================================================================\n\n/**\n * SetWalletCap: 2 accounts\n * Sets the per-wallet position cap (admin only). capE6=0 disables.\n */\nexport const ACCOUNTS_SET_WALLET_CAP: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: false },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n// ============================================================================\n// WELL-KNOWN PROGRAM/SYSVAR KEYS\n// ============================================================================\n\nexport const WELL_KNOWN = {\n tokenProgram: TOKEN_PROGRAM_ID,\n clock: SYSVAR_CLOCK_PUBKEY,\n rent: SYSVAR_RENT_PUBKEY,\n systemProgram: SystemProgram.programId,\n} as const;\n","/**\n * Percolator program error definitions.\n * Each error includes a name and actionable guidance.\n */\ninterface ErrorInfo {\n name: string;\n hint: string;\n}\n\nexport const PERCOLATOR_ERRORS: Record<number, ErrorInfo> = {\n 0: {\n name: \"InvalidMagic\",\n hint: \"The slab account has invalid data. Ensure you're using the correct slab address.\",\n },\n 1: {\n name: \"InvalidVersion\",\n hint: \"Slab version mismatch. The program may have been upgraded. Check for CLI updates.\",\n },\n 2: {\n name: \"AlreadyInitialized\",\n hint: \"This account is already initialized. Use a different account or skip initialization.\",\n },\n 3: {\n name: \"NotInitialized\",\n hint: \"The slab is not initialized. Run 'init-market' first.\",\n },\n 4: {\n name: \"InvalidSlabLen\",\n hint: \"Slab account has wrong size. Create a new slab account with correct size.\",\n },\n 5: {\n name: \"InvalidOracleKey\",\n hint: \"Oracle account doesn't match config. Check the --oracle parameter matches the market's oracle.\",\n },\n 6: {\n name: \"OracleStale\",\n hint: \"Oracle price is too old. Wait for oracle to update or check if oracle is paused.\",\n },\n 7: {\n name: \"OracleConfTooWide\",\n hint: \"Oracle confidence interval is too wide. Wait for more stable market conditions.\",\n },\n 8: {\n name: \"InvalidVaultAta\",\n hint: \"Vault token account is invalid. Check the vault account is correctly configured.\",\n },\n 9: {\n name: \"InvalidMint\",\n hint: \"Token mint doesn't match. Ensure you're using the correct collateral token.\",\n },\n 10: {\n name: \"ExpectedSigner\",\n hint: \"Missing required signature. Ensure the correct wallet is specified with --wallet.\",\n },\n 11: {\n name: \"ExpectedWritable\",\n hint: \"Account must be writable. This is likely a CLI bug - please report it.\",\n },\n 12: {\n name: \"OracleInvalid\",\n hint: \"Oracle data is invalid. Check the oracle account is a valid Pyth price feed.\",\n },\n 13: {\n name: \"EngineInsufficientBalance\",\n hint: \"Not enough collateral. Deposit more with 'deposit' before this operation.\",\n },\n 14: {\n name: \"EngineUndercollateralized\",\n hint: \"Account is undercollateralized. Deposit more collateral or reduce position size.\",\n },\n 15: {\n name: \"EngineUnauthorized\",\n hint: \"Not authorized. You must be the account owner or admin for this operation.\",\n },\n 16: {\n name: \"EngineInvalidMatchingEngine\",\n hint: \"Matcher program/context doesn't match LP config. Check --matcher-program and --matcher-context.\",\n },\n 17: {\n name: \"EnginePnlNotWarmedUp\",\n hint: \"PnL not warmed up yet. Wait for the warmup period to complete before trading.\",\n },\n 18: {\n name: \"EngineOverflow\",\n hint: \"Numeric overflow in calculation. Try a smaller amount or position size.\",\n },\n 19: {\n name: \"EngineAccountNotFound\",\n hint: \"Account not found at this index. Run 'init-user' or 'init-lp' first, or check the index.\",\n },\n 20: {\n name: \"EngineNotAnLPAccount\",\n hint: \"Expected an LP account but got a user account. Check the --lp-idx parameter.\",\n },\n 21: {\n name: \"EnginePositionSizeMismatch\",\n hint: \"Position size mismatch between user and LP. This shouldn't happen - please report it.\",\n },\n 22: {\n name: \"EngineRiskReductionOnlyMode\",\n hint: \"Market is in risk-reduction mode. Only position-reducing trades are allowed.\",\n },\n 23: {\n name: \"EngineAccountKindMismatch\",\n hint: \"Wrong account type. User operations require user accounts, LP operations require LP accounts.\",\n },\n 24: {\n name: \"InvalidTokenAccount\",\n hint: \"Token account is invalid. Ensure you have an ATA for the collateral mint.\",\n },\n 25: {\n name: \"InvalidTokenProgram\",\n hint: \"Invalid token program. Ensure SPL Token program is accessible.\",\n },\n 26: {\n name: \"InvalidConfigParam\",\n hint: \"Invalid configuration parameter. Check that leverage, fees, and risk thresholds are within allowed ranges.\",\n },\n 27: {\n name: \"HyperpTradeNoCpiDisabled\",\n hint: \"TradeNoCpi is disabled for this market. Use TradeCpi with LP matching instead.\",\n },\n 28: {\n name: \"InsuranceMintAlreadyExists\",\n hint: \"Insurance LP mint already exists for this market. Cannot recreate.\",\n },\n 29: {\n name: \"InsuranceMintNotCreated\",\n hint: \"Insurance LP mint has not been created yet. Run CreateInsuranceMint first.\",\n },\n 30: {\n name: \"InsuranceBelowThreshold\",\n hint: \"Insurance fund balance is below the required threshold. Deposit more to insurance fund.\",\n },\n 31: {\n name: \"InsuranceZeroAmount\",\n hint: \"Insurance deposit/withdrawal amount must be greater than zero.\",\n },\n 32: {\n name: \"InsuranceSupplyMismatch\",\n hint: \"Insurance LP token supply doesn't match vault balance. This is an internal error - please report it.\",\n },\n 33: {\n name: \"MarketPaused\",\n hint: \"This market is currently paused by the admin. Trading, deposits, and withdrawals are disabled.\",\n },\n 34: {\n name: \"AdminRenounceNotAllowed\",\n hint: \"Cannot renounce admin — the market must be RESOLVED first before renouncing admin control.\",\n },\n 35: {\n name: \"InvalidConfirmation\",\n hint: \"Invalid confirmation code for RenounceAdmin. This is a safety check — please verify the code.\",\n },\n 36: {\n name: \"InsufficientSeed\",\n hint: \"Vault seed balance is below the required minimum (500,000,000 raw tokens). Deposit more tokens to the vault before InitMarket.\",\n },\n 37: {\n name: \"InsufficientDexLiquidity\",\n hint: \"DEX pool has insufficient liquidity for safe Hyperp oracle bootstrapping. The quote-side reserves must meet the minimum threshold.\",\n },\n 38: {\n name: \"LpVaultAlreadyExists\",\n hint: \"LP vault already created for this market. Each market can only have one LP vault.\",\n },\n 39: {\n name: \"LpVaultNotCreated\",\n hint: \"LP vault not yet created. Call CreateLpVault first before depositing or withdrawing.\",\n },\n 40: {\n name: \"LpVaultZeroAmount\",\n hint: \"LP vault deposit or withdrawal amount must be greater than zero.\",\n },\n 41: {\n name: \"LpVaultSupplyMismatch\",\n hint: \"LP vault supply/capital mismatch — LP share supply > 0 but vault capital is 0. This is an internal error — please report it.\",\n },\n 42: {\n name: \"LpVaultWithdrawExceedsAvailable\",\n hint: \"LP vault withdrawal exceeds available capital. Some capital is reserved for open interest coverage.\",\n },\n 43: {\n name: \"LpVaultInvalidFeeShare\",\n hint: \"LP vault fee share basis points out of range. Must be 0–10,000 (0%–100%).\",\n },\n 44: {\n name: \"LpVaultNoNewFees\",\n hint: \"No new fees to distribute to LP vault. Wait for more trading activity to accrue fees.\",\n },\n // ── PERC-312 / PERC-314 / PERC-315 / PERC-309 / PERC-8111 / PERC-8110 (codes 45–60) ─────────\n 45: {\n name: \"SafetyValveDominantSideBlocked\",\n hint: \"New position on the dominant side is blocked while the market is rebalancing (safety valve).\",\n },\n 46: {\n name: \"DisputeWindowClosed\",\n hint: \"The dispute window for this resolved market has closed.\",\n },\n 47: {\n name: \"DisputeAlreadyExists\",\n hint: \"A dispute already exists for this market — cannot open another.\",\n },\n 48: {\n name: \"MarketNotResolved\",\n hint: \"Market is not resolved — cannot dispute an active market.\",\n },\n 49: {\n name: \"NoActiveDispute\",\n hint: \"No active dispute found for this market.\",\n },\n 50: {\n name: \"LpCollateralDisabled\",\n hint: \"LP collateral is not enabled for this market.\",\n },\n 51: {\n name: \"LpCollateralPositionOpen\",\n hint: \"Cannot withdraw LP collateral while a position is still open.\",\n },\n 52: {\n name: \"WithdrawQueueAlreadyExists\",\n hint: \"A withdrawal queue entry already exists for this user/market.\",\n },\n 53: {\n name: \"WithdrawQueueNotFound\",\n hint: \"No queued withdrawal found for this user/market.\",\n },\n 54: {\n name: \"WithdrawQueueNothingClaimable\",\n hint: \"Nothing is claimable from the withdrawal queue this epoch — wait for the next epoch.\",\n },\n 55: {\n name: \"AuditViolation\",\n hint: \"Audit crank detected a conservation invariant violation — this is a critical internal error, please report it.\",\n },\n 56: {\n name: \"CrossMarginPairNotFound\",\n hint: \"Cross-margin offset pair is not configured for these two slabs.\",\n },\n 57: {\n name: \"CrossMarginAttestationStale\",\n hint: \"Cross-margin attestation is stale — too many slots have elapsed since the last attestation.\",\n },\n 58: {\n name: \"WalletPositionCapExceeded\",\n hint: \"Trade rejected: the resulting position would exceed the per-wallet position cap (max_wallet_pos_e6) for this market.\",\n },\n 59: {\n name: \"OiImbalanceHardBlock\",\n hint: \"Trade rejected: it would increase the OI imbalance (|long_oi − short_oi| / total_oi) beyond the configured hard-block threshold (oi_imbalance_hard_block_bps). Try the opposite side.\",\n },\n 60: {\n name: \"EngineInvalidEntryPrice\",\n hint: \"Entry price must be positive when opening a position.\",\n },\n 61: {\n name: \"EngineSideBlocked\",\n hint: \"New position blocked — this side is in DrainOnly or ResetPending mode. Wait for the market to stabilise.\",\n },\n 62: {\n name: \"EngineCorruptState\",\n hint: \"Engine detected a corrupt state invariant violation — this is a critical internal error, please report it.\",\n },\n 63: {\n name: \"InsuranceFundNotDepleted\",\n hint: \"ADL rejected — insurance fund is not fully depleted (balance > 0). ADL is only permitted once insurance is exhausted.\",\n },\n 64: {\n name: \"NoAdlCandidates\",\n hint: \"ADL rejected — no eligible candidate positions found for deleveraging.\",\n },\n 65: {\n name: \"BankruptPositionAlreadyClosed\",\n hint: \"ADL rejected — the target position is already closed (size == 0). Re-rank and pick a different target.\",\n },\n};\n\n/**\n * Decode a custom program error code to its info.\n */\nexport function decodeError(code: number): ErrorInfo | undefined {\n return PERCOLATOR_ERRORS[code];\n}\n\n/**\n * Get error name from code.\n */\nexport function getErrorName(code: number): string {\n return PERCOLATOR_ERRORS[code]?.name ?? `Unknown(${code})`;\n}\n\n/**\n * Get actionable hint for error code.\n */\nexport function getErrorHint(code: number): string | undefined {\n return PERCOLATOR_ERRORS[code]?.hint;\n}\n\n/** Max hex digits for `custom program error: 0x...` — Solana custom errors are u32. */\nconst CUSTOM_ERROR_HEX_MAX_LEN = 8;\n\n/**\n * Parse error from transaction logs.\n * Looks for \"Program ... failed: custom program error: 0x...\"\n *\n * Hex capture is bounded (1–8 digits) so pathological logs cannot feed unbounded\n * strings into `parseInt` or produce precision-loss codes above u32.\n */\nexport function parseErrorFromLogs(logs: string[]): {\n code: number;\n name: string;\n hint?: string;\n} | null {\n if (!Array.isArray(logs)) {\n return null;\n }\n const re = new RegExp(\n `custom program error: 0x([0-9a-fA-F]{1,${CUSTOM_ERROR_HEX_MAX_LEN}})(?![0-9a-fA-F])`,\n \"i\",\n );\n for (const log of logs) {\n if (typeof log !== \"string\") {\n continue;\n }\n const match = log.match(re);\n if (match) {\n const code = parseInt(match[1], 16);\n if (!Number.isFinite(code) || code < 0 || code > 0xffff_ffff) {\n continue;\n }\n const info = decodeError(code);\n return {\n code,\n name: info?.name ?? `Unknown(${code})`,\n hint: info?.hint,\n };\n }\n }\n return null;\n}\n","import { Connection, PublicKey } from \"@solana/web3.js\";\n\n// =============================================================================\n// Browser-compatible read helpers using DataView\n// (the npm 'buffer' polyfill lacks readBigUInt64LE / readBigInt64LE)\n// =============================================================================\n\n/** Wrap a Uint8Array in a DataView sharing the same underlying buffer. */\nfunction dv(data: Uint8Array): DataView {\n return new DataView(data.buffer, data.byteOffset, data.byteLength);\n}\n/** Read a single unsigned byte at `off`. */\nfunction readU8(data: Uint8Array, off: number): number {\n return data[off];\n}\n/** Read a little-endian u16 at `off`. */\nfunction readU16LE(data: Uint8Array, off: number): number {\n return dv(data).getUint16(off, true);\n}\n/** Read a little-endian u32 at `off`. */\nfunction readU32LE(data: Uint8Array, off: number): number {\n return dv(data).getUint32(off, true);\n}\n/** Read a little-endian u64 at `off` as a BigInt. */\nfunction readU64LE(data: Uint8Array, off: number): bigint {\n return dv(data).getBigUint64(off, true);\n}\n/** Read a little-endian signed i64 at `off` as a BigInt. */\nfunction readI64LE(data: Uint8Array, off: number): bigint {\n return dv(data).getBigInt64(off, true);\n}\n\n// =============================================================================\n// Helper: read signed/unsigned i128 from buffer\n// =============================================================================\n\n/**\n * Read a little-endian signed i128 at `offset`.\n * Composed from two u64 halves; sign-extends if the high bit is set.\n */\nfunction readI128LE(buf: Uint8Array, offset: number): bigint {\n const lo = readU64LE(buf, offset);\n const hi = readU64LE(buf, offset + 8);\n const unsigned = (hi << 64n) | lo;\n const SIGN_BIT = 1n << 127n;\n if (unsigned >= SIGN_BIT) {\n return unsigned - (1n << 128n);\n }\n return unsigned;\n}\n\n/** Read a little-endian unsigned u128 at `offset` as a BigInt. */\nfunction readU128LE(buf: Uint8Array, offset: number): bigint {\n const lo = readU64LE(buf, offset);\n const hi = readU64LE(buf, offset + 8);\n return (hi << 64n) | lo;\n}\n\n// =============================================================================\n// Slab Layout Version Detection\n// =============================================================================\n// The deployed devnet program uses a different struct layout (V0) than the SDK\n// was updated for (V1). V1 includes PERC-120/121/122/298/299/300/301/306/328\n// struct changes that have NOT been deployed to devnet yet.\n//\n// V0 (deployed devnet): HEADER=72, CONFIG=408, ENGINE_OFF=480, ACCOUNT_SIZE=240\n// - InsuranceFund: {balance: U128, fee_revenue: U128} (32 bytes)\n// - RiskParams: 56 bytes (basic fields only)\n// - No mark_price, no long_oi/short_oi, no emergency OI cap fields\n// - No partial liquidation field in Account (240 bytes)\n//\n// V1 (future upgrade): HEADER=104, CONFIG=536, ENGINE_OFF=640, ACCOUNT_SIZE=248\n// - InsuranceFund: expanded with isolation fields (72 bytes)\n// - RiskParams: 288 bytes (premium funding, partial liq, dynamic fees)\n// - Has mark_price, long_oi/short_oi, emergency fields\n// - Account has last_partial_liquidation_slot (248 bytes)\n// =============================================================================\n\nconst MAGIC: bigint = 0x504552434f4c4154n; // \"PERCOLAT\"\n\n// Flag bits in header._padding[0] at offset 13\nconst FLAG_RESOLVED = 1 << 0;\n\n/**\n * Full slab layout descriptor. Returned by detectSlabLayout().\n * All engine field offsets are relative to engineOff.\n */\nexport interface SlabLayout {\n version: 0 | 1 | 2;\n headerLen: number;\n configOffset: number;\n configLen: number;\n reservedOff: number; // offset of _reserved in header\n engineOff: number;\n accountSize: number;\n maxAccounts: number;\n bitmapWords: number;\n accountsOff: number; // absolute offset of accounts array in slab\n\n // Engine field offsets (relative to engineOff)\n engineInsuranceOff: number;\n engineParamsOff: number;\n paramsSize: number;\n engineCurrentSlotOff: number;\n engineFundingIndexOff: number;\n engineLastFundingSlotOff: number;\n engineFundingRateBpsOff: number;\n engineMarkPriceOff: number; // -1 if not present (V0)\n engineLastCrankSlotOff: number;\n engineMaxCrankStalenessOff: number;\n engineTotalOiOff: number;\n engineLongOiOff: number; // -1 if not present (V0)\n engineShortOiOff: number; // -1 if not present (V0)\n engineCTotOff: number;\n enginePnlPosTotOff: number;\n engineLiqCursorOff: number;\n engineGcCursorOff: number;\n engineLastSweepStartOff: number;\n engineLastSweepCompleteOff: number;\n engineCrankCursorOff: number;\n engineSweepStartIdxOff: number;\n engineLifetimeLiquidationsOff: number;\n engineLifetimeForceClosesOff: number;\n engineNetLpPosOff: number;\n engineLpSumAbsOff: number;\n engineLpMaxAbsOff: number;\n engineLpMaxAbsSweepOff: number;\n engineEmergencyOiModeOff: number; // -1 if not present (V0)\n engineEmergencyStartSlotOff: number; // -1 if not present (V0)\n engineLastBreakerSlotOff: number; // -1 if not present (V0)\n engineBitmapOff: number; // relative to engineOff\n postBitmap: number; // 2 = free_head only (V1D), 18 = num_used + pad + next_account_id + free_head\n acctOwnerOff: number; // byte offset of owner pubkey within an account slot\n\n // Insurance fund layout\n hasInsuranceIsolation: boolean;\n engineInsuranceIsolatedOff: number; // -1 if not present (V0)\n engineInsuranceIsolationBpsOff: number; // -1 if not present (V0)\n}\n\n// ---- V0 layout constants (deployed devnet program) ----\nconst V0_HEADER_LEN = 72;\nconst V0_CONFIG_LEN = 408;\nconst V0_ENGINE_OFF = 480; // align_up(72 + 408, 8) = 480\nconst V0_ACCOUNT_SIZE = 240;\nconst V0_RESERVED_OFF = 48; // magic(8)+version(4)+bump(1)+pad(3)+admin(32) = 48\n\n// V0 engine: vault(16) + insurance{balance(16),fee_revenue(16)}=32 → params at 48\n// V0 RiskParams: 56 bytes → runtime state at 104\nconst V0_ENGINE_PARAMS_OFF = 48;\nconst V0_PARAMS_SIZE = 56;\nconst V0_ENGINE_CURRENT_SLOT_OFF = 104;\nconst V0_ENGINE_FUNDING_INDEX_OFF = 112;\nconst V0_ENGINE_LAST_FUNDING_SLOT_OFF = 128;\nconst V0_ENGINE_FUNDING_RATE_BPS_OFF = 136;\nconst V0_ENGINE_LAST_CRANK_SLOT_OFF = 144;\nconst V0_ENGINE_MAX_CRANK_STALENESS_OFF = 152;\nconst V0_ENGINE_TOTAL_OI_OFF = 160;\nconst V0_ENGINE_C_TOT_OFF = 176;\nconst V0_ENGINE_PNL_POS_TOT_OFF = 192;\nconst V0_ENGINE_LIQ_CURSOR_OFF = 208;\nconst V0_ENGINE_GC_CURSOR_OFF = 210;\nconst V0_ENGINE_LAST_SWEEP_START_OFF = 216;\nconst V0_ENGINE_LAST_SWEEP_COMPLETE_OFF = 224;\nconst V0_ENGINE_CRANK_CURSOR_OFF = 232;\nconst V0_ENGINE_SWEEP_START_IDX_OFF = 234;\nconst V0_ENGINE_LIFETIME_LIQUIDATIONS_OFF = 240;\nconst V0_ENGINE_LIFETIME_FORCE_CLOSES_OFF = 248;\nconst V0_ENGINE_NET_LP_POS_OFF = 256;\nconst V0_ENGINE_LP_SUM_ABS_OFF = 272;\nconst V0_ENGINE_LP_MAX_ABS_OFF = 288;\nconst V0_ENGINE_LP_MAX_ABS_SWEEP_OFF = 304;\nconst V0_ENGINE_BITMAP_OFF = 320;\n\n// ---- V1 layout constants (deployed devnet program, PERC-1094 corrected) ----\n// BPF (SBF) target: u128 alignment = 8, so CONFIG_LEN = 496 on-chain.\n// ENGINE_OFF = align_up(HEADER=104 + CONFIG=496, 8) = 600.\n// Previous value (640) was wrong — it assumed CONFIG_LEN=536 from the native build assertion.\nconst V1_HEADER_LEN = 104;\nconst V1_CONFIG_LEN = 496; // BPF (SBF) on-chain value; native test build would be 512\nconst V1_ENGINE_OFF = 600; // align_up(104 + 496, 8) = 600 (was 640 — corrected in PERC-1094)\n// Legacy: CONFIG_LEN=536 was used in pre-PERC-1094 SDK. Some orphaned slabs on devnet may use\n// ENGINE_OFF=640 (65352 bytes for small). We add them to V1_SIZES_LEGACY for read-only parsing.\nconst V1_ENGINE_OFF_LEGACY = 640;\nconst V1_ACCOUNT_SIZE = 248;\nconst V1_RESERVED_OFF = 80;\n\n// V1 engine: vault(16) + insurance expanded(56) → params at 72\n// V1 RiskParams: 288 bytes → runtime state at 360\nconst V1_ENGINE_PARAMS_OFF = 72;\nconst V1_PARAMS_SIZE = 288;\nconst V1_ENGINE_CURRENT_SLOT_OFF = 360;\nconst V1_ENGINE_FUNDING_INDEX_OFF = 368;\nconst V1_ENGINE_LAST_FUNDING_SLOT_OFF = 384;\nconst V1_ENGINE_FUNDING_RATE_BPS_OFF = 392;\nconst V1_ENGINE_MARK_PRICE_OFF = 400;\nconst V1_ENGINE_LAST_CRANK_SLOT_OFF = 424;\nconst V1_ENGINE_MAX_CRANK_STALENESS_OFF = 432;\nconst V1_ENGINE_TOTAL_OI_OFF = 440;\nconst V1_ENGINE_LONG_OI_OFF = 456;\nconst V1_ENGINE_SHORT_OI_OFF = 472;\nconst V1_ENGINE_C_TOT_OFF = 488;\nconst V1_ENGINE_PNL_POS_TOT_OFF = 504;\nconst V1_ENGINE_LIQ_CURSOR_OFF = 520;\nconst V1_ENGINE_GC_CURSOR_OFF = 522;\nconst V1_ENGINE_LAST_SWEEP_START_OFF = 528;\nconst V1_ENGINE_LAST_SWEEP_COMPLETE_OFF = 536;\nconst V1_ENGINE_CRANK_CURSOR_OFF = 544;\nconst V1_ENGINE_SWEEP_START_IDX_OFF = 546;\nconst V1_ENGINE_LIFETIME_LIQUIDATIONS_OFF = 552;\nconst V1_ENGINE_LIFETIME_FORCE_CLOSES_OFF = 560;\nconst V1_ENGINE_NET_LP_POS_OFF = 568;\nconst V1_ENGINE_LP_SUM_ABS_OFF = 584;\nconst V1_ENGINE_LP_MAX_ABS_OFF = 600;\nconst V1_ENGINE_LP_MAX_ABS_SWEEP_OFF = 616;\nconst V1_ENGINE_EMERGENCY_OI_MODE_OFF = 632;\nconst V1_ENGINE_EMERGENCY_START_SLOT_OFF = 640;\nconst V1_ENGINE_LAST_BREAKER_SLOT_OFF = 648;\nconst V1_ENGINE_BITMAP_OFF = 656;\n// On-chain V1_LEGACY slabs (65352 bytes) place the bitmap 16 bytes later than\n// computeSlabSize predicts (formula bitmapOff=656 gives size=65352 correctly, but\n// the deployed program stores the bitmap at rel=672 and the owner field at +200).\n// These corrected values must be used for actual byte-level parsing.\nconst V1_LEGACY_ENGINE_BITMAP_OFF_ACTUAL = 672; // relative to engineOff (abs = 640+672 = 1312)\nconst V1_LEGACY_ACCT_OWNER_OFF = 200; // vs the usual ACCT_OWNER_OFF=184\n\n// ---- V1D layout constants (actually deployed devnet V1 program, rev ac18a0e) ----\n// The deployed V1 program has a DIFFERENT struct layout than the V1 constants above.\n// Key differences:\n// - MarketConfig is smaller (BPF CONFIG_LEN=320 vs V1's 496) — older revision\n// - InsuranceFund is 80 bytes (V1 assumed 56), so params starts at engine+96 (not 72)\n// - Engine lacks lp_max_abs, lp_max_abs_sweep, emergency_oi, trade_twap fields\n// - Bitmap at engine+624 (not 656)\n// Confirmed by on-chain probing of slab 6ZytbpV4 (the only active V1 market).\nconst V1D_CONFIG_LEN = 320;\nconst V1D_ENGINE_OFF = 424; // align_up(104 + 320, 8) = 424\nconst V1D_ACCOUNT_SIZE = 248;\n\n// V1D engine field offsets (relative to engineOff):\n// vault(16) + InsuranceFund(80) → params at 96; RiskParams(288) → runtime at 384\nconst V1D_ENGINE_INSURANCE_OFF = 16;\nconst V1D_ENGINE_PARAMS_OFF = 96;\nconst V1D_PARAMS_SIZE = 288;\nconst V1D_ENGINE_CURRENT_SLOT_OFF = 384;\nconst V1D_ENGINE_FUNDING_INDEX_OFF = 392;\nconst V1D_ENGINE_LAST_FUNDING_SLOT_OFF = 408;\nconst V1D_ENGINE_FUNDING_RATE_BPS_OFF = 416;\nconst V1D_ENGINE_MARK_PRICE_OFF = 424;\n// funding_frozen(1+7pad) at 432, funding_frozen_rate(8) at 440\nconst V1D_ENGINE_LAST_CRANK_SLOT_OFF = 448;\nconst V1D_ENGINE_MAX_CRANK_STALENESS_OFF = 456;\nconst V1D_ENGINE_TOTAL_OI_OFF = 464;\nconst V1D_ENGINE_LONG_OI_OFF = 480;\nconst V1D_ENGINE_SHORT_OI_OFF = 496;\nconst V1D_ENGINE_C_TOT_OFF = 512;\nconst V1D_ENGINE_PNL_POS_TOT_OFF = 528;\nconst V1D_ENGINE_LIQ_CURSOR_OFF = 544;\nconst V1D_ENGINE_GC_CURSOR_OFF = 546;\nconst V1D_ENGINE_LAST_SWEEP_START_OFF = 552;\nconst V1D_ENGINE_LAST_SWEEP_COMPLETE_OFF = 560;\nconst V1D_ENGINE_CRANK_CURSOR_OFF = 568;\nconst V1D_ENGINE_SWEEP_START_IDX_OFF = 570;\nconst V1D_ENGINE_LIFETIME_LIQUIDATIONS_OFF = 576;\nconst V1D_ENGINE_LIFETIME_FORCE_CLOSES_OFF = 584;\nconst V1D_ENGINE_NET_LP_POS_OFF = 592;\nconst V1D_ENGINE_LP_SUM_ABS_OFF = 608;\n// lp_max_abs, lp_max_abs_sweep, emergency_*, trade_twap_* do NOT exist in this version\nconst V1D_ENGINE_BITMAP_OFF = 624;\n\n// ---- V2 layout constants (BPF intermediate layout, ENGINE_OFF=600, BITMAP_OFF=432) ----\n// V2 shares ENGINE_OFF=600 with V1, but has a completely different engine struct layout:\n// - CONFIG_LEN=496 (same as V1 on-chain), HEADER_LEN=104, ACCOUNT_SIZE=248\n// - Engine lacks mark_price, long_oi, short_oi, emergency OI fields\n// - Different field offsets than V1D (which has ENGINE_OFF=424)\n// V2 is identified by reading the version field at slab header offset 8 (u32 LE) == 2.\n// Without data, V2 cannot be distinguished from V1D by size alone (postBitmap=18 produces\n// identical sizes to V1D postBitmap=2 — both 65088 for 256 accounts).\nconst V2_HEADER_LEN = 104;\nconst V2_CONFIG_LEN = 496;\nconst V2_ENGINE_OFF = 600; // align_up(104 + 496, 8) = 600\nconst V2_ACCOUNT_SIZE = 248;\nconst V2_ENGINE_BITMAP_OFF = 432;\n\n// V2 engine field offsets (relative to engineOff)\nconst V2_ENGINE_CURRENT_SLOT_OFF = 352;\nconst V2_ENGINE_FUNDING_INDEX_OFF = 360;\nconst V2_ENGINE_LAST_FUNDING_SLOT_OFF = 376;\nconst V2_ENGINE_FUNDING_RATE_BPS_OFF = 384;\nconst V2_ENGINE_LAST_CRANK_SLOT_OFF = 392;\nconst V2_ENGINE_MAX_CRANK_STALENESS_OFF = 400;\nconst V2_ENGINE_TOTAL_OI_OFF = 408;\nconst V2_ENGINE_C_TOT_OFF = 424;\nconst V2_ENGINE_PNL_POS_TOT_OFF = 440;\nconst V2_ENGINE_LIQ_CURSOR_OFF = 456;\nconst V2_ENGINE_GC_CURSOR_OFF = 458;\nconst V2_ENGINE_LAST_SWEEP_START_OFF = 464;\nconst V2_ENGINE_LAST_SWEEP_COMPLETE_OFF = 472;\nconst V2_ENGINE_CRANK_CURSOR_OFF = 480;\nconst V2_ENGINE_SWEEP_START_IDX_OFF = 482;\nconst V2_ENGINE_LIFETIME_LIQUIDATIONS_OFF = 488;\nconst V2_ENGINE_LIFETIME_FORCE_CLOSES_OFF = 496;\nconst V2_ENGINE_NET_LP_POS_OFF = 504;\nconst V2_ENGINE_LP_SUM_ABS_OFF = 520;\nconst V2_ENGINE_LP_MAX_ABS_OFF = 536;\nconst V2_ENGINE_LP_MAX_ABS_SWEEP_OFF = 552;\n\n// ---- V_ADL layout constants (ADL-upgraded program, PERC-8270/8271) ----\n// This layout corresponds to the percolator lib at commit ed01137 (PERC-8270) which adds:\n// - Account: position_basis_q(i128,16)+adl_a_basis(u128,16)+adl_k_snap(i128,16)+adl_epoch_snap(u64,8) = +56 bytes\n// Plus 8-byte padding before position_basis_q (i128 requires 16-byte align on BPF) → +64 bytes/account\n// - RiskEngine: last_market_slot(u64)+funding_price_sample_last(u64)+materialized_account_count(u64)+last_oracle_price(u64) = +32 bytes\n// - Also adds: InsuranceFund expanded to 80 bytes (balance_incentive_reserve + _rebate_pad + _isolation_padding),\n// RiskParams expanded to 336 bytes (min_nonzero_mm_req, min_nonzero_im_req, insurance_floor, etc.),\n// pnl_matured_pos_tot(u128,16) field in RiskEngine (PERC-8267),\n// ADL side state fields (PERC-8268, +224 bytes engine before bitmap)\n//\n// BPF SLAB_LEN: 1288304 (large/4096-account tier) — verified by cargo build-sbf (PERC-8271)\n// ENGINE_OFF = 624 (HEADER=104 + CONFIG=520 native, aligned to 8 = 624)\n// ACCOUNT_SIZE = 312 (248 old + 8 pad for i128 alignment + 16+16+16+8 new ADL fields)\n// ENGINE_BITMAP_OFF = 1006 (sum of all fixed RiskEngine scalar fields before [u64; BITMAP_WORDS])\n// Derivation: SLAB_LEN=1288304 = 624 + accountsOff + 4096*312, accountsOff=9728,\n// bitmapOff=1006 → preAccountsLen=1006+512+18+8192=9728 (4096 accounts)\nconst V_ADL_ENGINE_OFF = 624; // align_up(HEADER=104 + CONFIG=520, 8) = 624\nconst V_ADL_CONFIG_LEN = 520; // BPF/native MarketConfig with current fields\nconst V_ADL_ACCOUNT_SIZE = 312; // 248 + 8(pad) + 56(new ADL fields) = 312 bytes\nconst V_ADL_ENGINE_PARAMS_OFF = 96; // vault(16) + InsuranceFund(80) = 96\n\n// V_ADL RiskParams: 336 bytes (same as V1M, includes all dynamic fee params)\nconst V_ADL_PARAMS_SIZE = 336;\n\n// V_ADL engine field offsets (relative to engineOff=624):\n// vault(16) + InsuranceFund(80) + RiskParams(336) = 432 bytes before current_slot\nconst V_ADL_ENGINE_CURRENT_SLOT_OFF = 432; // 96 + 336 = 432\nconst V_ADL_ENGINE_FUNDING_INDEX_OFF = 440; // 432 + 8\nconst V_ADL_ENGINE_LAST_FUNDING_SLOT_OFF = 456; // 440 + 16\nconst V_ADL_ENGINE_FUNDING_RATE_BPS_OFF = 464; // 456 + 8\n// PERC-8270 new fields at 472-504:\n// last_market_slot(8)@472, funding_price_sample_last(8)@480, materialized_account_count(8)@488, last_oracle_price(8)@496\nconst V_ADL_ENGINE_MARK_PRICE_OFF = 504; // 464+8+32 = 504 (shifted +104 from V1's 400)\n// funding_frozen(1+7pad=8)@512, funding_frozen_rate_snapshot(i64,8)@520\nconst V_ADL_ENGINE_LAST_CRANK_SLOT_OFF = 528; // was 424 in V1, +104\nconst V_ADL_ENGINE_MAX_CRANK_STALENESS_OFF = 536;\nconst V_ADL_ENGINE_TOTAL_OI_OFF = 544; // was 440 in V1, +104\nconst V_ADL_ENGINE_LONG_OI_OFF = 560; // was 456 in V1, +104\nconst V_ADL_ENGINE_SHORT_OI_OFF = 576; // was 472 in V1, +104\nconst V_ADL_ENGINE_C_TOT_OFF = 592; // was 488 in V1, +104\nconst V_ADL_ENGINE_PNL_POS_TOT_OFF = 608; // was 504 in V1, +104\n// pnl_matured_pos_tot(u128,16)@624 — NEW in PERC-8267\nconst V_ADL_ENGINE_LIQ_CURSOR_OFF = 640; // was 520 in V1, +120 (extra 16 for pnl_matured)\nconst V_ADL_ENGINE_GC_CURSOR_OFF = 642;\n// last_sweep_start(u64)@648, last_sweep_complete(u64)@656, crank_cursor(u16)@664, sweep_idx(u16)@666\nconst V_ADL_ENGINE_LAST_SWEEP_START_OFF = 648;\nconst V_ADL_ENGINE_LAST_SWEEP_COMPLETE_OFF = 656;\nconst V_ADL_ENGINE_CRANK_CURSOR_OFF = 664;\nconst V_ADL_ENGINE_SWEEP_START_IDX_OFF = 666;\n// lifetime_liquidations(u64)@672, lifetime_force_closes(u64)@680\nconst V_ADL_ENGINE_LIFETIME_LIQUIDATIONS_OFF = 672;\nconst V_ADL_ENGINE_LIFETIME_FORCE_CLOSES_OFF = 680;\n// ADL side state (PERC-8268, 224 bytes):\n// adl_mult_long/short(16ea), adl_coeff_long/short(16ea), adl_epoch_long/short(8ea),\n// adl_epoch_start_k_long/short(16ea), oi_eff_long/short_q(16ea),\n// side_mode_long(u8)+side_mode_short(u8)+pad(6), stored_pos_count×2, stale_count×2(all u64,8),\n// phantom_dust_bound_long/short_q(16ea) = 224 bytes at offsets 688–911\n// Then LP aggregates:\nconst V_ADL_ENGINE_NET_LP_POS_OFF = 904; // after ADL side state\nconst V_ADL_ENGINE_LP_SUM_ABS_OFF = 920;\nconst V_ADL_ENGINE_LP_MAX_ABS_OFF = 936;\nconst V_ADL_ENGINE_LP_MAX_ABS_SWEEP_OFF = 952;\n// emergency fields:\nconst V_ADL_ENGINE_EMERGENCY_OI_MODE_OFF = 968;\nconst V_ADL_ENGINE_EMERGENCY_START_SLOT_OFF = 976;\nconst V_ADL_ENGINE_LAST_BREAKER_SLOT_OFF = 984;\n// trade_twap_e6(8)@992, twap_last_slot(8)@1000\nconst V_ADL_ENGINE_BITMAP_OFF = 1006; // Verified: 1006+512+18+8192=9728 ✓ for 4096 accts\n\n// V_ADL account field offsets (relative to account slot start):\n// account_id(8)+capital(U128,16)+kind(u8+pad7=8)+pnl(I128,16)+reserved_pnl(u128,16)=64\nconst V_ADL_ACCT_WARMUP_STARTED_OFF = 64; // was 56\nconst V_ADL_ACCT_WARMUP_SLOPE_OFF = 72; // was 64\nconst V_ADL_ACCT_POSITION_SIZE_OFF = 88; // was 80\nconst V_ADL_ACCT_ENTRY_PRICE_OFF = 104; // was 96\nconst V_ADL_ACCT_FUNDING_INDEX_OFF = 112; // was 104\nconst V_ADL_ACCT_MATCHER_PROGRAM_OFF = 128; // was 120\nconst V_ADL_ACCT_MATCHER_CONTEXT_OFF = 160; // was 152\nconst V_ADL_ACCT_OWNER_OFF = 192; // was 184 (shifted +8 from reserved_pnl u64→u128)\nconst V_ADL_ACCT_FEE_CREDITS_OFF = 224; // was 216\nconst V_ADL_ACCT_LAST_FEE_SLOT_OFF = 240; // was 232\n\n// ---- V1M layout constants (mainnet-deployed V1 program, ESa89R5) ----\n// The mainnet program has a LARGER RiskParams (336 bytes vs V1's 288) and 22 extra\n// bytes in the runtime state (trade_twap_e6 + twap_last_slot + alignment padding).\n// ENGINE_OFF=640 (same as V1_LEGACY), CONFIG_LEN=536, ACCOUNT_SIZE=248.\n// Confirmed by byte-level probing of mainnet slab 8NY7rvQ (SOL/USDC Perpetual).\nconst V1M_ENGINE_OFF = 640; // align_up(104 + 536, 8) = 640 (same as V1_LEGACY)\nconst V1M_CONFIG_LEN = 536; // MarketConfig size in native/mainnet build\nconst V1M_ACCOUNT_SIZE = 248;\n// V1M2: rebuilt from main@4861c56, CONFIG_LEN=512 on SBF → ENGINE_OFF=616\nconst V1M2_ENGINE_OFF = 616; // align_up(104 + 512, 8) = 616\nconst V1M2_CONFIG_LEN = 512; // MarketConfig with u128 native alignment on SBF\nconst V1M_ENGINE_PARAMS_OFF = 72; // vault(16) + InsuranceFund(56) = 72 (same as V1)\n\n// V1M RiskParams: 336 bytes (+48 over V1's 288)\n// Extra fields: fee_utilization_surge_bps(8) [in SDK V1 already? no → +8],\n// balance_incentive_reserve configs (+8?), min_nonzero_mm_req(u128=16),\n// min_nonzero_im_req(u128=16) = +48 total\nconst V1M_PARAMS_SIZE = 336;\n\n// V1M runtime state starts at engine+408 (72 + 336) instead of V1's +360\nconst V1M_ENGINE_CURRENT_SLOT_OFF = 408;\nconst V1M_ENGINE_FUNDING_INDEX_OFF = 416;\nconst V1M_ENGINE_LAST_FUNDING_SLOT_OFF = 432;\nconst V1M_ENGINE_FUNDING_RATE_BPS_OFF = 440;\nconst V1M_ENGINE_MARK_PRICE_OFF = 448;\n// funding_frozen(1+7pad) at 456, funding_frozen_rate(8) at 464\nconst V1M_ENGINE_LAST_CRANK_SLOT_OFF = 472;\nconst V1M_ENGINE_MAX_CRANK_STALENESS_OFF = 480;\nconst V1M_ENGINE_TOTAL_OI_OFF = 488;\nconst V1M_ENGINE_LONG_OI_OFF = 504;\nconst V1M_ENGINE_SHORT_OI_OFF = 520;\nconst V1M_ENGINE_C_TOT_OFF = 536;\nconst V1M_ENGINE_PNL_POS_TOT_OFF = 552;\nconst V1M_ENGINE_LIQ_CURSOR_OFF = 568;\nconst V1M_ENGINE_GC_CURSOR_OFF = 570;\nconst V1M_ENGINE_LAST_SWEEP_START_OFF = 576;\nconst V1M_ENGINE_LAST_SWEEP_COMPLETE_OFF = 584;\nconst V1M_ENGINE_CRANK_CURSOR_OFF = 592;\nconst V1M_ENGINE_SWEEP_START_IDX_OFF = 594;\nconst V1M_ENGINE_LIFETIME_LIQUIDATIONS_OFF = 600;\nconst V1M_ENGINE_LIFETIME_FORCE_CLOSES_OFF = 608;\nconst V1M_ENGINE_NET_LP_POS_OFF = 616;\nconst V1M_ENGINE_LP_SUM_ABS_OFF = 632;\nconst V1M_ENGINE_LP_MAX_ABS_OFF = 648;\nconst V1M_ENGINE_LP_MAX_ABS_SWEEP_OFF = 664;\nconst V1M_ENGINE_EMERGENCY_OI_MODE_OFF = 680;\nconst V1M_ENGINE_EMERGENCY_START_SLOT_OFF = 688;\nconst V1M_ENGINE_LAST_BREAKER_SLOT_OFF = 696;\n// trade_twap_e6(8) at 704, twap_last_slot(8) at 712 → bitmap at 720\n// No padding between twap_last_slot and used bitmap (u64 array is 8-byte\n// aligned and 720 % 8 == 0). Previous value of 726 was wrong — 726 % 8 = 6\n// which is invalid for a [u64; N] array under #[repr(C)].\nconst V1M_ENGINE_BITMAP_OFF = 720;\n\n// V1M2: mainnet program rebuilt from main@4861c56 with --features medium.\n// ENGINE_OFF=616 (not 640): CONFIG_LEN=512 on SBF because cfg(target_arch=\"bpf\")\n// doesn't match the SBF toolchain (target_arch=\"sbf\"), so u128 align=16 (native) applies.\n// align_up(HEADER=104 + CONFIG=512, 8) = 616.\n// Slab sizes match V_ADL exactly — disambiguation required via data inspection.\n// Confirmed by on-chain probing of slab 7T1Efij9 (SOL-PERP, 323312 bytes, medium tier).\n// Engine struct is larger than V1M (990 vs 720 bitmap offset = +270 runtime bytes).\n// New runtime fields inserted between fundingRateBps and markPrice:\n// +408: currentSlot, +416: fundingIndex(i128), +432: lastFundingSlot, +440: fundingRateBps\n// +448: NEW lastOracleUpdateSlot(?), +456: authorityPriceE6(?), +464-471: reserved\n// +472: lastEffectivePriceE6(?), +480: markPriceE6, +488-503: reserved\n// +504: lastCrankSlot, +512: maxCrankStaleness\nconst V1M2_ACCOUNT_SIZE = 312; // 248 + 64 bytes of new fields per account\nconst V1M2_ENGINE_BITMAP_OFF = 990; // expanded engine struct shifts bitmap forward\n// V1M2 runtime offsets (confirmed by on-chain probing of 7T1Efij9):\nconst V1M2_ENGINE_CURRENT_SLOT_OFF = 408; // same as V1M\nconst V1M2_ENGINE_FUNDING_INDEX_OFF = 416; // same as V1M\nconst V1M2_ENGINE_LAST_FUNDING_SLOT_OFF = 432; // same as V1M\nconst V1M2_ENGINE_FUNDING_RATE_BPS_OFF = 440; // same as V1M\nconst V1M2_ENGINE_MARK_PRICE_OFF = 480; // shifted +32 from V1M's 448\nconst V1M2_ENGINE_LAST_CRANK_SLOT_OFF = 504; // shifted +32 from V1M's 472\nconst V1M2_ENGINE_MAX_CRANK_STALENESS_OFF = 512; // shifted +32 from V1M's 480\n// OI and remaining fields: shifted proportionally. Use conservative offsets based on\n// V1M base + 32 byte shift for fields after fundingRateBps.\nconst V1M2_RUNTIME_SHIFT = 32; // bytes inserted between fundingRateBps and markPrice\n\n// For backward compatibility, export ENGINE_OFF and ENGINE_MARK_PRICE_OFF\n// (used by reinit-slab and other scripts). These refer to V1 layout.\nexport const ENGINE_OFF = V1_ENGINE_OFF;\nexport const ENGINE_MARK_PRICE_OFF = V1_ENGINE_MARK_PRICE_OFF;\n\n// ---- Known slab sizes per version and tier ----\n\n/**\n * Compute the total byte size of a slab given its layout parameters.\n * Used to pre-populate the known-size lookup maps at module load time.\n */\nfunction computeSlabSize(\n engineOff: number,\n bitmapOff: number,\n accountSize: number,\n maxAccounts: number,\n // postBitmap bytes immediately after the free-slot bitmap:\n // SDK default (V0/V1/V1-legacy): 18 = num_used(u16,2) + pad(6) + next_account_id(u64,8) + free_head(u16,2)\n // V1D deployed program: 2 = free_head(u16,2) only — no num_used, pad, or next_account_id\n postBitmap = 18,\n): number {\n const bitmapWords = Math.ceil(maxAccounts / 64);\n const bitmapBytes = bitmapWords * 8;\n const nextFreeBytes = maxAccounts * 2;\n const preAccountsLen = bitmapOff + bitmapBytes + postBitmap + nextFreeBytes;\n const accountsOff = Math.ceil(preAccountsLen / 8) * 8;\n return engineOff + accountsOff + maxAccounts * accountSize;\n}\n\nconst TIERS = [64, 256, 1024, 4096] as const;\n\n// Pre-compute known slab sizes for fast lookup\nconst V0_SIZES = new Map<number, number>();\nconst V1_SIZES = new Map<number, number>();\n// Legacy V1 sizes using incorrect ENGINE_OFF=640 (pre-PERC-1094). Orphaned on devnet; read-only.\nconst V1_SIZES_LEGACY = new Map<number, number>();\n// V1D: actually deployed V1 program (ENGINE_OFF=424, BITMAP_OFF=624)\nconst V1D_SIZES = new Map<number, number>();\n// V1D_SIZES_LEGACY: on-chain slabs created before GH#1234 when SDK assumed postBitmap=18.\n// These are 16 bytes larger per tier (micro=17080, small=65104, medium=257200, large=1025584).\n// The top active market (6ZytbpV4, $14k 24h vol) was created with postBitmap=18 and uses 65104.\n// PR #1236 fixed postBitmap for new slabs (→2) but broke recognition of these legacy 65104 slabs.\n// GH#1237: add both size variants so detectSlabLayout handles both old and new V1D on-chain data.\n// V2: ENGINE_OFF=600, BITMAP_OFF=432, ACCOUNT_SIZE=248, postBitmap=18\nconst V2_SIZES = new Map<number, number>();\n// V1M: mainnet-deployed V1 program (ENGINE_OFF=640, BITMAP_OFF=726, expanded RiskParams)\nconst V1M_SIZES = new Map<number, number>();\n// V_ADL: PERC-8270/8271 ADL-upgraded program (ENGINE_OFF=624, BITMAP_OFF=1006, ACCOUNT_SIZE=312)\nconst V_ADL_SIZES = new Map<number, number>();\nconst V1D_SIZES_LEGACY = new Map<number, number>();\nfor (const n of TIERS) {\n V0_SIZES.set(computeSlabSize(V0_ENGINE_OFF, V0_ENGINE_BITMAP_OFF, V0_ACCOUNT_SIZE, n), n);\n V1_SIZES.set(computeSlabSize(V1_ENGINE_OFF, V1_ENGINE_BITMAP_OFF, V1_ACCOUNT_SIZE, n), n);\n V1_SIZES_LEGACY.set(computeSlabSize(V1_ENGINE_OFF_LEGACY, V1_ENGINE_BITMAP_OFF, V1_ACCOUNT_SIZE, n), n);\n // GH#1234: V1D deployed program omits num_used/pad/next_account_id → postBitmap=2 (free_head only).\n // This yields 65088 (n=256) and 1025568 (n=4096) matching actual devnet account sizes.\n V1D_SIZES.set(computeSlabSize(V1D_ENGINE_OFF, V1D_ENGINE_BITMAP_OFF, V1D_ACCOUNT_SIZE, n, 2), n);\n // GH#1237: also register the legacy postBitmap=18 sizes for slabs created before GH#1234 fix.\n V1D_SIZES_LEGACY.set(computeSlabSize(V1D_ENGINE_OFF, V1D_ENGINE_BITMAP_OFF, V1D_ACCOUNT_SIZE, n, 18), n);\n // V2: postBitmap=18 — produces same sizes as V1D postBitmap=2 (e.g. 65088 for n=256).\n // Disambiguation requires peeking at the version field in the slab header.\n V2_SIZES.set(computeSlabSize(V2_ENGINE_OFF, V2_ENGINE_BITMAP_OFF, V2_ACCOUNT_SIZE, n, 18), n);\n // V1M: mainnet program with expanded RiskParams (336 bytes) and trade_twap fields.\n // e.g. n=1024 → 257512 bytes (confirmed on-chain for slab 8NY7rvQ).\n V1M_SIZES.set(computeSlabSize(V1M_ENGINE_OFF, V1M_ENGINE_BITMAP_OFF, V1M_ACCOUNT_SIZE, n, 18), n);\n // V_ADL: PERC-8270 ADL-upgraded program — new account size (312) and expanded engine layout.\n // e.g. n=4096 → 1288304 bytes (verified by cargo build-sbf in PERC-8271).\n V_ADL_SIZES.set(computeSlabSize(V_ADL_ENGINE_OFF, V_ADL_ENGINE_BITMAP_OFF, V_ADL_ACCOUNT_SIZE, n, 18), n);\n}\n\n/**\n * V2 slab tier sizes (small and large) for discovery.\n * V2 uses ENGINE_OFF=600, BITMAP_OFF=432, ACCOUNT_SIZE=248, postBitmap=18.\n * Sizes overlap with V1D (postBitmap=2) — disambiguation requires reading the version field.\n */\nexport const SLAB_TIERS_V2 = {\n small: { maxAccounts: 256, dataSize: 65_088, label: \"Small\", description: \"256 slots (V2 BPF intermediate)\" },\n large: { maxAccounts: 4096, dataSize: 1_025_568, label: \"Large\", description: \"4,096 slots (V2 BPF intermediate)\" },\n} as const;\n\n/**\n * V1M slab tier sizes — mainnet-deployed V1 program (ESa89R5).\n * ENGINE_OFF=640, BITMAP_OFF=726, ACCOUNT_SIZE=248, postBitmap=18.\n * Expanded RiskParams (336 bytes) and trade_twap runtime fields.\n * Confirmed by on-chain probing of slab 8NY7rvQ (SOL/USDC Perpetual, 257512 bytes).\n */\nexport const SLAB_TIERS_V1M: Record<string, { maxAccounts: number; dataSize: number; label: string; description: string }> = {};\nfor (const [label, n] of [[\"Micro\", 64], [\"Small\", 256], [\"Medium\", 1024], [\"Large\", 4096]] as const) {\n const size = computeSlabSize(V1M_ENGINE_OFF, V1M_ENGINE_BITMAP_OFF, V1M_ACCOUNT_SIZE, n, 18);\n SLAB_TIERS_V1M[label.toLowerCase()] = { maxAccounts: n, dataSize: size, label, description: `${n} slots (V1M mainnet)` };\n}\n\n/**\n * V1M2 slab tier sizes — mainnet program with 312-byte accounts.\n * Same engine layout as V1M but larger accounts. Sizes match V_ADL exactly.\n */\nexport const SLAB_TIERS_V1M2: Record<string, { maxAccounts: number; dataSize: number; label: string; description: string }> = {};\nfor (const [label, n] of [[\"Micro\", 64], [\"Small\", 256], [\"Medium\", 1024], [\"Large\", 4096]] as const) {\n const size = computeSlabSize(V1M2_ENGINE_OFF, V1M2_ENGINE_BITMAP_OFF, V1M2_ACCOUNT_SIZE, n, 18);\n SLAB_TIERS_V1M2[label.toLowerCase()] = { maxAccounts: n, dataSize: size, label, description: `${n} slots (V1M2 mainnet upgraded)` };\n}\n\n/**\n * V_ADL slab tier sizes — PERC-8270/8271 ADL-upgraded program.\n * ENGINE_OFF=624, BITMAP_OFF=1006, ACCOUNT_SIZE=312, postBitmap=18.\n * New account layout adds ADL tracking fields (+64 bytes/account including alignment padding).\n * BPF SLAB_LEN verified by cargo build-sbf in PERC-8271: large (4096) = 1288304 bytes.\n */\nexport const SLAB_TIERS_V_ADL: Record<string, { maxAccounts: number; dataSize: number; label: string; description: string }> = {};\nfor (const [label, n] of [[\"Micro\", 64], [\"Small\", 256], [\"Medium\", 1024], [\"Large\", 4096]] as const) {\n const size = computeSlabSize(V_ADL_ENGINE_OFF, V_ADL_ENGINE_BITMAP_OFF, V_ADL_ACCOUNT_SIZE, n, 18);\n SLAB_TIERS_V_ADL[label.toLowerCase()] = { maxAccounts: n, dataSize: size, label, description: `${n} slots (V_ADL PERC-8270)` };\n}\n\n/**\n * Build a complete SlabLayout descriptor for V0 or V1 (including V1-legacy) slabs.\n * Pass `engineOffOverride` to handle orphaned pre-PERC-1094 slabs that used ENGINE_OFF=640.\n */\nfunction buildLayout(version: 0 | 1, maxAccounts: number, engineOffOverride?: number): SlabLayout {\n const isV0 = version === 0;\n const engineOff = engineOffOverride ?? (isV0 ? V0_ENGINE_OFF : V1_ENGINE_OFF);\n const isV1Legacy = !isV0 && engineOffOverride === V1_ENGINE_OFF_LEGACY;\n // For accountsOff calculation, V1_LEGACY must use its actual bitmap offset (672, not 656).\n // Using the formula bitmapOff (656) produces accountsOff=1864, but accounts actually\n // start at 1880 — a 16-byte gap caused by the extra fields in the V1_LEGACY engine.\n // Non-V1_LEGACY slabs: actualBitmapOff === bitmapOff, so no change.\n const bitmapOff = isV0 ? V0_ENGINE_BITMAP_OFF : V1_ENGINE_BITMAP_OFF;\n const actualBitmapOff = isV1Legacy ? V1_LEGACY_ENGINE_BITMAP_OFF_ACTUAL\n : (isV0 ? V0_ENGINE_BITMAP_OFF : V1_ENGINE_BITMAP_OFF);\n const accountSize = isV0 ? V0_ACCOUNT_SIZE : V1_ACCOUNT_SIZE;\n const bitmapWords = Math.ceil(maxAccounts / 64);\n const bitmapBytes = bitmapWords * 8;\n const postBitmap = 18;\n const nextFreeBytes = maxAccounts * 2;\n // Use actualBitmapOff so V1_LEGACY gets accountsOff=1880 (not 1864).\n const preAccountsLen = actualBitmapOff + bitmapBytes + postBitmap + nextFreeBytes;\n const accountsOffRel = Math.ceil(preAccountsLen / 8) * 8;\n\n return {\n version,\n headerLen: isV0 ? V0_HEADER_LEN : V1_HEADER_LEN,\n configOffset: isV0 ? V0_HEADER_LEN : V1_HEADER_LEN,\n configLen: isV0 ? V0_CONFIG_LEN : V1_CONFIG_LEN,\n reservedOff: isV0 ? V0_RESERVED_OFF : V1_RESERVED_OFF,\n engineOff,\n accountSize,\n maxAccounts,\n bitmapWords,\n accountsOff: engineOff + accountsOffRel,\n\n engineInsuranceOff: 16,\n engineParamsOff: isV0 ? V0_ENGINE_PARAMS_OFF : V1_ENGINE_PARAMS_OFF,\n paramsSize: isV0 ? V0_PARAMS_SIZE : V1_PARAMS_SIZE,\n engineCurrentSlotOff: isV0 ? V0_ENGINE_CURRENT_SLOT_OFF : V1_ENGINE_CURRENT_SLOT_OFF,\n engineFundingIndexOff: isV0 ? V0_ENGINE_FUNDING_INDEX_OFF : V1_ENGINE_FUNDING_INDEX_OFF,\n engineLastFundingSlotOff: isV0 ? V0_ENGINE_LAST_FUNDING_SLOT_OFF : V1_ENGINE_LAST_FUNDING_SLOT_OFF,\n engineFundingRateBpsOff: isV0 ? V0_ENGINE_FUNDING_RATE_BPS_OFF : V1_ENGINE_FUNDING_RATE_BPS_OFF,\n engineMarkPriceOff: isV0 ? -1 : V1_ENGINE_MARK_PRICE_OFF,\n engineLastCrankSlotOff: isV0 ? V0_ENGINE_LAST_CRANK_SLOT_OFF : V1_ENGINE_LAST_CRANK_SLOT_OFF,\n engineMaxCrankStalenessOff: isV0 ? V0_ENGINE_MAX_CRANK_STALENESS_OFF : V1_ENGINE_MAX_CRANK_STALENESS_OFF,\n engineTotalOiOff: isV0 ? V0_ENGINE_TOTAL_OI_OFF : V1_ENGINE_TOTAL_OI_OFF,\n engineLongOiOff: isV0 ? -1 : V1_ENGINE_LONG_OI_OFF,\n engineShortOiOff: isV0 ? -1 : V1_ENGINE_SHORT_OI_OFF,\n engineCTotOff: isV0 ? V0_ENGINE_C_TOT_OFF : V1_ENGINE_C_TOT_OFF,\n enginePnlPosTotOff: isV0 ? V0_ENGINE_PNL_POS_TOT_OFF : V1_ENGINE_PNL_POS_TOT_OFF,\n engineLiqCursorOff: isV0 ? V0_ENGINE_LIQ_CURSOR_OFF : V1_ENGINE_LIQ_CURSOR_OFF,\n engineGcCursorOff: isV0 ? V0_ENGINE_GC_CURSOR_OFF : V1_ENGINE_GC_CURSOR_OFF,\n engineLastSweepStartOff: isV0 ? V0_ENGINE_LAST_SWEEP_START_OFF : V1_ENGINE_LAST_SWEEP_START_OFF,\n engineLastSweepCompleteOff: isV0 ? V0_ENGINE_LAST_SWEEP_COMPLETE_OFF : V1_ENGINE_LAST_SWEEP_COMPLETE_OFF,\n engineCrankCursorOff: isV0 ? V0_ENGINE_CRANK_CURSOR_OFF : V1_ENGINE_CRANK_CURSOR_OFF,\n engineSweepStartIdxOff: isV0 ? V0_ENGINE_SWEEP_START_IDX_OFF : V1_ENGINE_SWEEP_START_IDX_OFF,\n engineLifetimeLiquidationsOff: isV0 ? V0_ENGINE_LIFETIME_LIQUIDATIONS_OFF : V1_ENGINE_LIFETIME_LIQUIDATIONS_OFF,\n engineLifetimeForceClosesOff: isV0 ? V0_ENGINE_LIFETIME_FORCE_CLOSES_OFF : V1_ENGINE_LIFETIME_FORCE_CLOSES_OFF,\n engineNetLpPosOff: isV0 ? V0_ENGINE_NET_LP_POS_OFF : V1_ENGINE_NET_LP_POS_OFF,\n engineLpSumAbsOff: isV0 ? V0_ENGINE_LP_SUM_ABS_OFF : V1_ENGINE_LP_SUM_ABS_OFF,\n engineLpMaxAbsOff: isV0 ? V0_ENGINE_LP_MAX_ABS_OFF : V1_ENGINE_LP_MAX_ABS_OFF,\n engineLpMaxAbsSweepOff: isV0 ? V0_ENGINE_LP_MAX_ABS_SWEEP_OFF : V1_ENGINE_LP_MAX_ABS_SWEEP_OFF,\n engineEmergencyOiModeOff: isV0 ? -1 : V1_ENGINE_EMERGENCY_OI_MODE_OFF,\n engineEmergencyStartSlotOff: isV0 ? -1 : V1_ENGINE_EMERGENCY_START_SLOT_OFF,\n engineLastBreakerSlotOff: isV0 ? -1 : V1_ENGINE_LAST_BREAKER_SLOT_OFF,\n engineBitmapOff: actualBitmapOff,\n postBitmap: 18,\n acctOwnerOff: ACCT_OWNER_OFF,\n\n hasInsuranceIsolation: !isV0,\n engineInsuranceIsolatedOff: isV0 ? -1 : 48,\n engineInsuranceIsolationBpsOff: isV0 ? -1 : 64,\n };\n}\n\n/**\n * Build layout for V1D (actually deployed V1 program, rev ac18a0e).\n * Uses correct field offsets derived from on-chain probing.\n *\n * @param maxAccounts - Number of account slots in the slab\n * @param postBitmap - Bytes after the bitmap before next_free array.\n * 2 = free_head(u16) only — deployed program (GH#1234, default for new slabs)\n * 18 = num_used(u16)+pad(6)+next_account_id(u64)+free_head(u16) — legacy on-chain slabs (GH#1237)\n */\n/**\n * Build a SlabLayout for the actually-deployed V1D program (ENGINE_OFF=424).\n * `postBitmap` is 2 for new slabs (free_head only) and 18 for legacy on-chain slabs\n * created before the GH#1234 fix that removed num_used/pad/next_account_id.\n */\nfunction buildLayoutV1D(maxAccounts: number, postBitmap = 2): SlabLayout {\n const engineOff = V1D_ENGINE_OFF;\n const bitmapOff = V1D_ENGINE_BITMAP_OFF;\n const accountSize = V1D_ACCOUNT_SIZE;\n const bitmapWords = Math.ceil(maxAccounts / 64);\n const bitmapBytes = bitmapWords * 8;\n const nextFreeBytes = maxAccounts * 2;\n const preAccountsLen = bitmapOff + bitmapBytes + postBitmap + nextFreeBytes;\n const accountsOffRel = Math.ceil(preAccountsLen / 8) * 8;\n\n return {\n version: 1,\n headerLen: V1_HEADER_LEN,\n configOffset: V1_HEADER_LEN,\n configLen: V1D_CONFIG_LEN,\n reservedOff: V1_RESERVED_OFF,\n engineOff,\n accountSize,\n maxAccounts,\n bitmapWords,\n accountsOff: engineOff + accountsOffRel,\n\n engineInsuranceOff: V1D_ENGINE_INSURANCE_OFF,\n engineParamsOff: V1D_ENGINE_PARAMS_OFF,\n paramsSize: V1D_PARAMS_SIZE,\n engineCurrentSlotOff: V1D_ENGINE_CURRENT_SLOT_OFF,\n engineFundingIndexOff: V1D_ENGINE_FUNDING_INDEX_OFF,\n engineLastFundingSlotOff: V1D_ENGINE_LAST_FUNDING_SLOT_OFF,\n engineFundingRateBpsOff: V1D_ENGINE_FUNDING_RATE_BPS_OFF,\n engineMarkPriceOff: V1D_ENGINE_MARK_PRICE_OFF,\n engineLastCrankSlotOff: V1D_ENGINE_LAST_CRANK_SLOT_OFF,\n engineMaxCrankStalenessOff: V1D_ENGINE_MAX_CRANK_STALENESS_OFF,\n engineTotalOiOff: V1D_ENGINE_TOTAL_OI_OFF,\n engineLongOiOff: V1D_ENGINE_LONG_OI_OFF,\n engineShortOiOff: V1D_ENGINE_SHORT_OI_OFF,\n engineCTotOff: V1D_ENGINE_C_TOT_OFF,\n enginePnlPosTotOff: V1D_ENGINE_PNL_POS_TOT_OFF,\n engineLiqCursorOff: V1D_ENGINE_LIQ_CURSOR_OFF,\n engineGcCursorOff: V1D_ENGINE_GC_CURSOR_OFF,\n engineLastSweepStartOff: V1D_ENGINE_LAST_SWEEP_START_OFF,\n engineLastSweepCompleteOff: V1D_ENGINE_LAST_SWEEP_COMPLETE_OFF,\n engineCrankCursorOff: V1D_ENGINE_CRANK_CURSOR_OFF,\n engineSweepStartIdxOff: V1D_ENGINE_SWEEP_START_IDX_OFF,\n engineLifetimeLiquidationsOff: V1D_ENGINE_LIFETIME_LIQUIDATIONS_OFF,\n engineLifetimeForceClosesOff: V1D_ENGINE_LIFETIME_FORCE_CLOSES_OFF,\n engineNetLpPosOff: V1D_ENGINE_NET_LP_POS_OFF,\n engineLpSumAbsOff: V1D_ENGINE_LP_SUM_ABS_OFF,\n engineLpMaxAbsOff: -1, // not present in deployed V1\n engineLpMaxAbsSweepOff: -1, // not present in deployed V1\n engineEmergencyOiModeOff: -1, // not present in deployed V1\n engineEmergencyStartSlotOff: -1, // not present in deployed V1\n engineLastBreakerSlotOff: -1, // not present in deployed V1\n engineBitmapOff: V1D_ENGINE_BITMAP_OFF,\n postBitmap,\n acctOwnerOff: ACCT_OWNER_OFF,\n\n hasInsuranceIsolation: true,\n engineInsuranceIsolatedOff: 48, // same within InsuranceFund\n engineInsuranceIsolationBpsOff: 64, // same within InsuranceFund\n };\n}\n\n/**\n * Build a SlabLayout for V2 (BPF intermediate layout).\n * ENGINE_OFF=600, BITMAP_OFF=432, ACCOUNT_SIZE=248, postBitmap=18.\n * V2 lacks mark_price, long_oi, short_oi, emergency OI fields.\n */\nfunction buildLayoutV2(maxAccounts: number): SlabLayout {\n const engineOff = V2_ENGINE_OFF;\n const bitmapOff = V2_ENGINE_BITMAP_OFF;\n const accountSize = V2_ACCOUNT_SIZE;\n const bitmapWords = Math.ceil(maxAccounts / 64);\n const bitmapBytes = bitmapWords * 8;\n const postBitmap = 18;\n const nextFreeBytes = maxAccounts * 2;\n const preAccountsLen = bitmapOff + bitmapBytes + postBitmap + nextFreeBytes;\n const accountsOffRel = Math.ceil(preAccountsLen / 8) * 8;\n\n return {\n version: 2,\n headerLen: V2_HEADER_LEN,\n configOffset: V2_HEADER_LEN,\n configLen: V2_CONFIG_LEN,\n reservedOff: V1_RESERVED_OFF, // V2 shares V1's header layout (reserved at 80)\n engineOff,\n accountSize,\n maxAccounts,\n bitmapWords,\n accountsOff: engineOff + accountsOffRel,\n\n engineInsuranceOff: 16,\n engineParamsOff: V1_ENGINE_PARAMS_OFF, // same as V1: 72\n paramsSize: V1_PARAMS_SIZE, // same as V1: 288\n engineCurrentSlotOff: V2_ENGINE_CURRENT_SLOT_OFF,\n engineFundingIndexOff: V2_ENGINE_FUNDING_INDEX_OFF,\n engineLastFundingSlotOff: V2_ENGINE_LAST_FUNDING_SLOT_OFF,\n engineFundingRateBpsOff: V2_ENGINE_FUNDING_RATE_BPS_OFF,\n engineMarkPriceOff: -1, // V2 has no mark_price\n engineLastCrankSlotOff: V2_ENGINE_LAST_CRANK_SLOT_OFF,\n engineMaxCrankStalenessOff: V2_ENGINE_MAX_CRANK_STALENESS_OFF,\n engineTotalOiOff: V2_ENGINE_TOTAL_OI_OFF,\n engineLongOiOff: -1, // V2 has no long_oi\n engineShortOiOff: -1, // V2 has no short_oi\n engineCTotOff: V2_ENGINE_C_TOT_OFF,\n enginePnlPosTotOff: V2_ENGINE_PNL_POS_TOT_OFF,\n engineLiqCursorOff: V2_ENGINE_LIQ_CURSOR_OFF,\n engineGcCursorOff: V2_ENGINE_GC_CURSOR_OFF,\n engineLastSweepStartOff: V2_ENGINE_LAST_SWEEP_START_OFF,\n engineLastSweepCompleteOff: V2_ENGINE_LAST_SWEEP_COMPLETE_OFF,\n engineCrankCursorOff: V2_ENGINE_CRANK_CURSOR_OFF,\n engineSweepStartIdxOff: V2_ENGINE_SWEEP_START_IDX_OFF,\n engineLifetimeLiquidationsOff: V2_ENGINE_LIFETIME_LIQUIDATIONS_OFF,\n engineLifetimeForceClosesOff: V2_ENGINE_LIFETIME_FORCE_CLOSES_OFF,\n engineNetLpPosOff: V2_ENGINE_NET_LP_POS_OFF,\n engineLpSumAbsOff: V2_ENGINE_LP_SUM_ABS_OFF,\n engineLpMaxAbsOff: V2_ENGINE_LP_MAX_ABS_OFF,\n engineLpMaxAbsSweepOff: V2_ENGINE_LP_MAX_ABS_SWEEP_OFF,\n engineEmergencyOiModeOff: -1, // V2 has no emergency OI fields\n engineEmergencyStartSlotOff: -1,\n engineLastBreakerSlotOff: -1,\n engineBitmapOff: V2_ENGINE_BITMAP_OFF,\n postBitmap: 18,\n acctOwnerOff: ACCT_OWNER_OFF,\n\n hasInsuranceIsolation: true,\n engineInsuranceIsolatedOff: 48,\n engineInsuranceIsolationBpsOff: 64,\n };\n}\n\n/**\n * Build a SlabLayout for the V1M mainnet program (ESa89R5).\n * ENGINE_OFF=640 (same as V1_LEGACY), but expanded RiskParams (336 bytes)\n * and trade_twap runtime fields push the bitmap to offset 726.\n * Confirmed by on-chain probing of slab 8NY7rvQ (257512 bytes, medium tier).\n */\nfunction buildLayoutV1M(maxAccounts: number): SlabLayout {\n const engineOff = V1M_ENGINE_OFF;\n const bitmapOff = V1M_ENGINE_BITMAP_OFF;\n const accountSize = V1M_ACCOUNT_SIZE;\n const bitmapWords = Math.ceil(maxAccounts / 64);\n const bitmapBytes = bitmapWords * 8;\n const postBitmap = 18;\n const nextFreeBytes = maxAccounts * 2;\n const preAccountsLen = bitmapOff + bitmapBytes + postBitmap + nextFreeBytes;\n const accountsOffRel = Math.ceil(preAccountsLen / 8) * 8;\n\n return {\n version: 1,\n headerLen: V1_HEADER_LEN,\n configOffset: V1_HEADER_LEN,\n configLen: V1M_CONFIG_LEN,\n reservedOff: V1_RESERVED_OFF,\n engineOff,\n accountSize,\n maxAccounts,\n bitmapWords,\n accountsOff: engineOff + accountsOffRel,\n\n engineInsuranceOff: 16,\n engineParamsOff: V1M_ENGINE_PARAMS_OFF,\n paramsSize: V1M_PARAMS_SIZE,\n engineCurrentSlotOff: V1M_ENGINE_CURRENT_SLOT_OFF,\n engineFundingIndexOff: V1M_ENGINE_FUNDING_INDEX_OFF,\n engineLastFundingSlotOff: V1M_ENGINE_LAST_FUNDING_SLOT_OFF,\n engineFundingRateBpsOff: V1M_ENGINE_FUNDING_RATE_BPS_OFF,\n engineMarkPriceOff: V1M_ENGINE_MARK_PRICE_OFF,\n engineLastCrankSlotOff: V1M_ENGINE_LAST_CRANK_SLOT_OFF,\n engineMaxCrankStalenessOff: V1M_ENGINE_MAX_CRANK_STALENESS_OFF,\n engineTotalOiOff: V1M_ENGINE_TOTAL_OI_OFF,\n engineLongOiOff: V1M_ENGINE_LONG_OI_OFF,\n engineShortOiOff: V1M_ENGINE_SHORT_OI_OFF,\n engineCTotOff: V1M_ENGINE_C_TOT_OFF,\n enginePnlPosTotOff: V1M_ENGINE_PNL_POS_TOT_OFF,\n engineLiqCursorOff: V1M_ENGINE_LIQ_CURSOR_OFF,\n engineGcCursorOff: V1M_ENGINE_GC_CURSOR_OFF,\n engineLastSweepStartOff: V1M_ENGINE_LAST_SWEEP_START_OFF,\n engineLastSweepCompleteOff: V1M_ENGINE_LAST_SWEEP_COMPLETE_OFF,\n engineCrankCursorOff: V1M_ENGINE_CRANK_CURSOR_OFF,\n engineSweepStartIdxOff: V1M_ENGINE_SWEEP_START_IDX_OFF,\n engineLifetimeLiquidationsOff: V1M_ENGINE_LIFETIME_LIQUIDATIONS_OFF,\n engineLifetimeForceClosesOff: V1M_ENGINE_LIFETIME_FORCE_CLOSES_OFF,\n engineNetLpPosOff: V1M_ENGINE_NET_LP_POS_OFF,\n engineLpSumAbsOff: V1M_ENGINE_LP_SUM_ABS_OFF,\n engineLpMaxAbsOff: V1M_ENGINE_LP_MAX_ABS_OFF,\n engineLpMaxAbsSweepOff: V1M_ENGINE_LP_MAX_ABS_SWEEP_OFF,\n engineEmergencyOiModeOff: V1M_ENGINE_EMERGENCY_OI_MODE_OFF,\n engineEmergencyStartSlotOff: V1M_ENGINE_EMERGENCY_START_SLOT_OFF,\n engineLastBreakerSlotOff: V1M_ENGINE_LAST_BREAKER_SLOT_OFF,\n engineBitmapOff: V1M_ENGINE_BITMAP_OFF,\n postBitmap: 18,\n acctOwnerOff: ACCT_OWNER_OFF,\n\n hasInsuranceIsolation: true,\n engineInsuranceIsolatedOff: 48,\n engineInsuranceIsolationBpsOff: 64,\n };\n}\n\n/**\n * Build a SlabLayout for V1M2 — mainnet program with 312-byte accounts.\n * Same engine layout as V1M (ENGINE_OFF=640, same field offsets) but larger\n * accounts (312 bytes) and shifted bitmap (990).\n * Confirmed by on-chain probing of slab 7T1Efij9 (SOL-PERP, 323312 bytes).\n */\nfunction buildLayoutV1M2(maxAccounts: number): SlabLayout {\n const engineOff = V1M2_ENGINE_OFF;\n const bitmapOff = V1M2_ENGINE_BITMAP_OFF;\n const accountSize = V1M2_ACCOUNT_SIZE;\n const bitmapWords = Math.ceil(maxAccounts / 64);\n const bitmapBytes = bitmapWords * 8;\n const postBitmap = 18;\n const nextFreeBytes = maxAccounts * 2;\n const preAccountsLen = bitmapOff + bitmapBytes + postBitmap + nextFreeBytes;\n const accountsOffRel = Math.ceil(preAccountsLen / 8) * 8;\n\n return {\n version: 1,\n headerLen: V1_HEADER_LEN,\n configOffset: V1_HEADER_LEN,\n configLen: V1M2_CONFIG_LEN,\n reservedOff: V1_RESERVED_OFF,\n engineOff,\n accountSize,\n maxAccounts,\n bitmapWords,\n accountsOff: engineOff + accountsOffRel,\n\n engineInsuranceOff: 16,\n engineParamsOff: V1M_ENGINE_PARAMS_OFF, // 72 — same as V1M\n paramsSize: V1M_PARAMS_SIZE, // 336 — same as V1M\n // Runtime fields: same as V1M up to fundingRateBps, then +32 shift\n engineCurrentSlotOff: V1M2_ENGINE_CURRENT_SLOT_OFF,\n engineFundingIndexOff: V1M2_ENGINE_FUNDING_INDEX_OFF,\n engineLastFundingSlotOff: V1M2_ENGINE_LAST_FUNDING_SLOT_OFF,\n engineFundingRateBpsOff: V1M2_ENGINE_FUNDING_RATE_BPS_OFF,\n engineMarkPriceOff: V1M2_ENGINE_MARK_PRICE_OFF,\n engineLastCrankSlotOff: V1M2_ENGINE_LAST_CRANK_SLOT_OFF,\n engineMaxCrankStalenessOff: V1M2_ENGINE_MAX_CRANK_STALENESS_OFF,\n // Fields after maxCrankStaleness: apply same +32 shift from V1M\n engineTotalOiOff: V1M_ENGINE_TOTAL_OI_OFF + V1M2_RUNTIME_SHIFT,\n engineLongOiOff: V1M_ENGINE_LONG_OI_OFF + V1M2_RUNTIME_SHIFT,\n engineShortOiOff: V1M_ENGINE_SHORT_OI_OFF + V1M2_RUNTIME_SHIFT,\n engineCTotOff: V1M_ENGINE_C_TOT_OFF + V1M2_RUNTIME_SHIFT,\n enginePnlPosTotOff: V1M_ENGINE_PNL_POS_TOT_OFF + V1M2_RUNTIME_SHIFT,\n engineLiqCursorOff: V1M_ENGINE_LIQ_CURSOR_OFF + V1M2_RUNTIME_SHIFT,\n engineGcCursorOff: V1M_ENGINE_GC_CURSOR_OFF + V1M2_RUNTIME_SHIFT,\n engineLastSweepStartOff: V1M_ENGINE_LAST_SWEEP_START_OFF + V1M2_RUNTIME_SHIFT,\n engineLastSweepCompleteOff: V1M_ENGINE_LAST_SWEEP_COMPLETE_OFF + V1M2_RUNTIME_SHIFT,\n engineCrankCursorOff: V1M_ENGINE_CRANK_CURSOR_OFF + V1M2_RUNTIME_SHIFT,\n engineSweepStartIdxOff: V1M_ENGINE_SWEEP_START_IDX_OFF + V1M2_RUNTIME_SHIFT,\n engineLifetimeLiquidationsOff: V1M_ENGINE_LIFETIME_LIQUIDATIONS_OFF + V1M2_RUNTIME_SHIFT,\n engineLifetimeForceClosesOff: V1M_ENGINE_LIFETIME_FORCE_CLOSES_OFF + V1M2_RUNTIME_SHIFT,\n engineNetLpPosOff: V1M_ENGINE_NET_LP_POS_OFF + V1M2_RUNTIME_SHIFT,\n engineLpSumAbsOff: V1M_ENGINE_LP_SUM_ABS_OFF + V1M2_RUNTIME_SHIFT,\n engineLpMaxAbsOff: V1M_ENGINE_LP_MAX_ABS_OFF + V1M2_RUNTIME_SHIFT,\n engineLpMaxAbsSweepOff: V1M_ENGINE_LP_MAX_ABS_SWEEP_OFF + V1M2_RUNTIME_SHIFT,\n engineEmergencyOiModeOff: V1M_ENGINE_EMERGENCY_OI_MODE_OFF + V1M2_RUNTIME_SHIFT,\n engineEmergencyStartSlotOff: V1M_ENGINE_EMERGENCY_START_SLOT_OFF + V1M2_RUNTIME_SHIFT,\n engineLastBreakerSlotOff: V1M_ENGINE_LAST_BREAKER_SLOT_OFF + V1M2_RUNTIME_SHIFT,\n engineBitmapOff: V1M2_ENGINE_BITMAP_OFF,\n postBitmap: 18,\n acctOwnerOff: ACCT_OWNER_OFF,\n\n hasInsuranceIsolation: true,\n engineInsuranceIsolatedOff: 48,\n engineInsuranceIsolationBpsOff: 64,\n };\n}\n\n/**\n * Build a SlabLayout for the ADL-upgraded program (PERC-8270/8271).\n * ENGINE_OFF=624, BITMAP_OFF=1006, ACCOUNT_SIZE=312.\n *\n * Verified slab sizes (BPF, cargo build-sbf):\n * large (4096 accounts): 1288304 bytes ← PERC-8271 confirmed\n * medium (1024 accounts): 323312 bytes\n * small (256 accounts): 82064 bytes\n */\nfunction buildLayoutVADL(maxAccounts: number): SlabLayout {\n const engineOff = V_ADL_ENGINE_OFF;\n const bitmapOff = V_ADL_ENGINE_BITMAP_OFF;\n const accountSize = V_ADL_ACCOUNT_SIZE;\n const bitmapWords = Math.ceil(maxAccounts / 64);\n const bitmapBytes = bitmapWords * 8;\n const postBitmap = 18;\n const nextFreeBytes = maxAccounts * 2;\n const preAccountsLen = bitmapOff + bitmapBytes + postBitmap + nextFreeBytes;\n const accountsOffRel = Math.ceil(preAccountsLen / 8) * 8;\n\n return {\n version: 1,\n headerLen: V1_HEADER_LEN, // 104 (unchanged)\n configOffset: V1_HEADER_LEN,\n configLen: V_ADL_CONFIG_LEN, // 520\n reservedOff: V1_RESERVED_OFF, // 80\n engineOff,\n accountSize,\n maxAccounts,\n bitmapWords,\n accountsOff: engineOff + accountsOffRel,\n\n engineInsuranceOff: 16,\n engineParamsOff: V_ADL_ENGINE_PARAMS_OFF, // 96 (vault=16 + InsuranceFund=80)\n paramsSize: V_ADL_PARAMS_SIZE, // 336\n engineCurrentSlotOff: V_ADL_ENGINE_CURRENT_SLOT_OFF, // 432\n engineFundingIndexOff: V_ADL_ENGINE_FUNDING_INDEX_OFF, // 440\n engineLastFundingSlotOff: V_ADL_ENGINE_LAST_FUNDING_SLOT_OFF, // 456\n engineFundingRateBpsOff: V_ADL_ENGINE_FUNDING_RATE_BPS_OFF, // 464\n engineMarkPriceOff: V_ADL_ENGINE_MARK_PRICE_OFF, // 504\n engineLastCrankSlotOff: V_ADL_ENGINE_LAST_CRANK_SLOT_OFF, // 528\n engineMaxCrankStalenessOff: V_ADL_ENGINE_MAX_CRANK_STALENESS_OFF, // 536\n engineTotalOiOff: V_ADL_ENGINE_TOTAL_OI_OFF, // 544\n engineLongOiOff: V_ADL_ENGINE_LONG_OI_OFF, // 560\n engineShortOiOff: V_ADL_ENGINE_SHORT_OI_OFF, // 576\n engineCTotOff: V_ADL_ENGINE_C_TOT_OFF, // 592\n enginePnlPosTotOff: V_ADL_ENGINE_PNL_POS_TOT_OFF, // 608\n engineLiqCursorOff: V_ADL_ENGINE_LIQ_CURSOR_OFF, // 640\n engineGcCursorOff: V_ADL_ENGINE_GC_CURSOR_OFF, // 642\n engineLastSweepStartOff: V_ADL_ENGINE_LAST_SWEEP_START_OFF, // 648\n engineLastSweepCompleteOff: V_ADL_ENGINE_LAST_SWEEP_COMPLETE_OFF, // 656\n engineCrankCursorOff: V_ADL_ENGINE_CRANK_CURSOR_OFF, // 664\n engineSweepStartIdxOff: V_ADL_ENGINE_SWEEP_START_IDX_OFF, // 666\n engineLifetimeLiquidationsOff: V_ADL_ENGINE_LIFETIME_LIQUIDATIONS_OFF, // 672\n engineLifetimeForceClosesOff: V_ADL_ENGINE_LIFETIME_FORCE_CLOSES_OFF, // 680\n engineNetLpPosOff: V_ADL_ENGINE_NET_LP_POS_OFF, // 904\n engineLpSumAbsOff: V_ADL_ENGINE_LP_SUM_ABS_OFF, // 920\n engineLpMaxAbsOff: V_ADL_ENGINE_LP_MAX_ABS_OFF, // 936\n engineLpMaxAbsSweepOff: V_ADL_ENGINE_LP_MAX_ABS_SWEEP_OFF, // 952\n engineEmergencyOiModeOff: V_ADL_ENGINE_EMERGENCY_OI_MODE_OFF, // 968\n engineEmergencyStartSlotOff: V_ADL_ENGINE_EMERGENCY_START_SLOT_OFF, // 976\n engineLastBreakerSlotOff: V_ADL_ENGINE_LAST_BREAKER_SLOT_OFF, // 984\n engineBitmapOff: V_ADL_ENGINE_BITMAP_OFF, // 1006\n postBitmap: 18,\n acctOwnerOff: V_ADL_ACCT_OWNER_OFF, // 192\n\n hasInsuranceIsolation: true,\n engineInsuranceIsolatedOff: 48,\n engineInsuranceIsolationBpsOff: 64,\n };\n}\n\n/**\n * Detect the slab layout version from the raw account data length.\n * Returns the full SlabLayout descriptor, or null if the size is unrecognised.\n * Checks V_ADL, V1M, V0, V1D, V1D-legacy, V1, and V1-legacy sizes in priority order.\n *\n * When `data` is provided and the size matches V1D, the version field at offset 8 is read\n * to disambiguate V2 slabs (which produce identical sizes to V1D with postBitmap=2).\n * V2 slabs have version===2 at offset 8 (u32 LE).\n *\n * @param dataLen - The slab account data length in bytes\n * @param data - Optional raw slab data for version-field disambiguation\n */\nexport function detectSlabLayout(dataLen: number, data?: Uint8Array): SlabLayout | null {\n // Check V_ADL / V1M2 sizes — these two layouts produce IDENTICAL slab sizes because\n // V_ADL (ENGINE_OFF=624, BITMAP_OFF=1006, ACCOUNT_SIZE=312) and V1M2 (ENGINE_OFF=640,\n // BITMAP_OFF=990, ACCOUNT_SIZE=312) compute to the same totals for all tiers.\n // Disambiguate by reading max_accounts at each layout's params offset:\n // V1M2: engine(640) + params(72) + max_accounts_field(32) = offset 744\n // V_ADL: engine(624) + params(96) + max_accounts_field(32) = offset 752\n const vadln = V_ADL_SIZES.get(dataLen);\n if (vadln !== undefined) {\n if (data && data.length >= 752) {\n const maxAcctsV1M2 = readU64LE(data, V1M2_ENGINE_OFF + V1M_ENGINE_PARAMS_OFF + 32);\n if (maxAcctsV1M2 === BigInt(vadln)) {\n // V1M engine layout with 312-byte accounts (mainnet program upgrade)\n return buildLayoutV1M2(vadln);\n }\n }\n return buildLayoutVADL(vadln);\n }\n\n // Check V1M sizes (mainnet-deployed V1 program, ESa89R5).\n // Must be checked before V1_LEGACY because V1M sizes are unique and don't overlap.\n const v1mn = V1M_SIZES.get(dataLen);\n if (v1mn !== undefined) return buildLayoutV1M(v1mn);\n\n // Check V0 sizes (deployed devnet V0 program)\n const v0n = V0_SIZES.get(dataLen);\n if (v0n !== undefined) return buildLayout(0, v0n);\n\n // Check V1D sizes (actually deployed V1 program — ENGINE_OFF=424, correct struct layout).\n // V2 slabs produce identical sizes (postBitmap=18 for V2 == postBitmap=2 for V1D).\n // When data is available, peek at the version field to disambiguate.\n const v1dn = V1D_SIZES.get(dataLen);\n if (v1dn !== undefined) {\n if (data && data.length >= 12) {\n const version = readU32LE(data, 8);\n if (version === 2) return buildLayoutV2(v1dn);\n }\n return buildLayoutV1D(v1dn, 2);\n }\n\n // Check V1D legacy sizes (postBitmap=18 on-chain slabs created before GH#1234 fix).\n // e.g. slab 6ZytbpV4 (TEST/USD, top active market) = 65104 bytes, uses postBitmap=18.\n // PR #1236 broke these by only registering the postBitmap=2 size; GH#1237 restores support.\n const v1dln = V1D_SIZES_LEGACY.get(dataLen);\n if (v1dln !== undefined) return buildLayoutV1D(v1dln, 18);\n\n // Check V1 sizes (future V1 program — ENGINE_OFF=600, PERC-1094 corrected)\n const v1n = V1_SIZES.get(dataLen);\n if (v1n !== undefined) return buildLayout(1, v1n);\n\n // Check legacy V1 sizes (pre-PERC-1094 SDK used ENGINE_OFF=640; orphaned on devnet)\n const v1ln = V1_SIZES_LEGACY.get(dataLen);\n // PERC-1095 follow-up: must pass V1_ENGINE_OFF_LEGACY (640) so the returned SlabLayout\n // has .engineOff=640 — without the override buildLayout would use V1_ENGINE_OFF=600,\n // causing all engine reads on legacy slabs to land at the wrong byte offset.\n if (v1ln !== undefined) return buildLayout(1, v1ln, V1_ENGINE_OFF_LEGACY);\n\n return null;\n}\n\n/**\n * Legacy detectLayout for backward compat.\n * Returns { bitmapWords, accountsOff, maxAccounts } or null.\n *\n * GH#1238: previously recomputed accountsOff with hardcoded postBitmap=18, which gave a value\n * 16 bytes too large for V1D slabs (which use postBitmap=2). Now delegates directly to the\n * SlabLayout descriptor so each variant uses its own correct accountsOff.\n */\nexport function detectLayout(dataLen: number) {\n const layout = detectSlabLayout(dataLen);\n if (!layout) return null;\n return { bitmapWords: layout.bitmapWords, accountsOff: layout.accountsOff, maxAccounts: layout.maxAccounts };\n}\n\n// =============================================================================\n// RiskParams Layout (field offsets within params, same for V0 and V1 basic fields)\n// =============================================================================\nconst PARAMS_WARMUP_PERIOD_OFF = 0;\nconst PARAMS_MAINTENANCE_MARGIN_OFF = 8;\nconst PARAMS_INITIAL_MARGIN_OFF = 16;\nconst PARAMS_TRADING_FEE_OFF = 24;\nconst PARAMS_MAX_ACCOUNTS_OFF = 32;\nconst PARAMS_NEW_ACCOUNT_FEE_OFF = 40;\n// V1-only extended params (offset 56+)\nconst PARAMS_RISK_THRESHOLD_OFF = 56;\nconst PARAMS_MAINTENANCE_FEE_OFF = 72;\nconst PARAMS_MAX_CRANK_STALENESS_OFF = 88;\nconst PARAMS_LIQUIDATION_FEE_BPS_OFF = 96;\nconst PARAMS_LIQUIDATION_FEE_CAP_OFF = 104;\nconst PARAMS_LIQUIDATION_BUFFER_OFF = 120;\nconst PARAMS_MIN_LIQUIDATION_OFF = 128;\n\n// =============================================================================\n// Account Layout (240/248 bytes)\n// The first 240 bytes are identical in V0 and V1.\n// V1 adds last_partial_liquidation_slot (u64, 8 bytes) at offset 240.\n// =============================================================================\nconst ACCT_ACCOUNT_ID_OFF = 0;\nconst ACCT_CAPITAL_OFF = 8;\nconst ACCT_KIND_OFF = 24;\nconst ACCT_PNL_OFF = 32;\nconst ACCT_RESERVED_PNL_OFF = 48;\nconst ACCT_WARMUP_STARTED_OFF = 56;\nconst ACCT_WARMUP_SLOPE_OFF = 64;\nconst ACCT_POSITION_SIZE_OFF = 80;\nconst ACCT_ENTRY_PRICE_OFF = 96;\nconst ACCT_FUNDING_INDEX_OFF = 104;\nconst ACCT_MATCHER_PROGRAM_OFF = 120;\nconst ACCT_MATCHER_CONTEXT_OFF = 152;\nconst ACCT_OWNER_OFF = 184;\nconst ACCT_FEE_CREDITS_OFF = 216;\nconst ACCT_LAST_FEE_SLOT_OFF = 232;\n\n// =============================================================================\n// Interfaces\n// =============================================================================\n\nexport interface SlabHeader {\n magic: bigint;\n version: number;\n bump: number;\n flags: number;\n resolved: boolean;\n paused: boolean;\n admin: PublicKey;\n nonce: bigint;\n lastThrUpdateSlot: bigint;\n}\n\nexport interface MarketConfig {\n collateralMint: PublicKey;\n vaultPubkey: PublicKey;\n indexFeedId: PublicKey;\n maxStalenessSlots: bigint;\n confFilterBps: number;\n vaultAuthorityBump: number;\n invert: number;\n unitScale: number;\n fundingHorizonSlots: bigint;\n fundingKBps: bigint;\n fundingInvScaleNotionalE6: bigint;\n fundingMaxPremiumBps: bigint;\n fundingMaxBpsPerSlot: bigint;\n fundingPremiumWeightBps: bigint;\n fundingSettlementIntervalSlots: bigint;\n fundingPremiumDampeningE6: bigint;\n fundingPremiumMaxBpsPerSlot: bigint;\n threshFloor: bigint;\n threshRiskBps: bigint;\n threshUpdateIntervalSlots: bigint;\n threshStepBps: bigint;\n threshAlphaBps: bigint;\n threshMin: bigint;\n threshMax: bigint;\n threshMinStep: bigint;\n oracleAuthority: PublicKey;\n authorityPriceE6: bigint;\n authorityTimestamp: bigint;\n oraclePriceCapE2bps: bigint;\n lastEffectivePriceE6: bigint;\n oiCapMultiplierBps: bigint;\n maxPnlCap: bigint;\n adaptiveFundingEnabled: boolean;\n adaptiveScaleBps: number;\n adaptiveMaxFundingBps: bigint;\n marketCreatedSlot: bigint;\n oiRampSlots: bigint;\n resolvedSlot: bigint;\n insuranceIsolationBps: number;\n /** PERC-622: Oracle phase (0=Nascent, 1=Growing, 2=Mature) */\n oraclePhase: number;\n /** PERC-622: Cumulative trade volume in e6 format */\n cumulativeVolumeE6: bigint;\n /** PERC-622: Slots elapsed from market creation to Phase 2 entry (u24) */\n phase2DeltaSlots: number;\n}\n\nexport interface InsuranceFund {\n balance: bigint;\n feeRevenue: bigint;\n isolatedBalance: bigint;\n isolationBps: number;\n}\n\nexport interface RiskParams {\n warmupPeriodSlots: bigint;\n maintenanceMarginBps: bigint;\n initialMarginBps: bigint;\n tradingFeeBps: bigint;\n maxAccounts: bigint;\n newAccountFee: bigint;\n riskReductionThreshold: bigint;\n maintenanceFeePerSlot: bigint;\n maxCrankStalenessSlots: bigint;\n liquidationFeeBps: bigint;\n liquidationFeeCap: bigint;\n liquidationBufferBps: bigint;\n minLiquidationAbs: bigint;\n}\n\nexport interface EngineState {\n vault: bigint;\n insuranceFund: InsuranceFund;\n currentSlot: bigint;\n fundingIndexQpbE6: bigint;\n lastFundingSlot: bigint;\n fundingRateBpsPerSlotLast: bigint;\n lastCrankSlot: bigint;\n maxCrankStalenessSlots: bigint;\n totalOpenInterest: bigint;\n longOi: bigint;\n shortOi: bigint;\n cTot: bigint;\n pnlPosTot: bigint;\n liqCursor: number;\n gcCursor: number;\n lastSweepStartSlot: bigint;\n lastSweepCompleteSlot: bigint;\n crankCursor: number;\n sweepStartIdx: number;\n lifetimeLiquidations: bigint;\n lifetimeForceCloses: bigint;\n netLpPos: bigint;\n lpSumAbs: bigint;\n lpMaxAbs: bigint;\n lpMaxAbsSweep: bigint;\n emergencyOiMode: boolean;\n emergencyStartSlot: bigint;\n lastBreakerSlot: bigint;\n numUsedAccounts: number;\n nextAccountId: bigint;\n markPriceE6: bigint;\n}\n\nexport enum AccountKind {\n User = 0,\n LP = 1,\n}\n\nexport interface Account {\n kind: AccountKind;\n accountId: bigint;\n capital: bigint;\n pnl: bigint;\n reservedPnl: bigint;\n warmupStartedAtSlot: bigint;\n warmupSlopePerStep: bigint;\n positionSize: bigint;\n entryPrice: bigint;\n fundingIndex: bigint;\n matcherProgram: PublicKey;\n matcherContext: PublicKey;\n owner: PublicKey;\n feeCredits: bigint;\n lastFeeSlot: bigint;\n}\n\n// =============================================================================\n// Fetch\n// =============================================================================\n\nexport async function fetchSlab(\n connection: Connection,\n slabPubkey: PublicKey\n): Promise<Uint8Array> {\n const info = await connection.getAccountInfo(slabPubkey);\n if (!info) {\n throw new Error(`Slab account not found: ${slabPubkey.toBase58()}`);\n }\n return new Uint8Array(info.data);\n}\n\n// =============================================================================\n// PERC-302: Market Maturity OI Ramp\n// =============================================================================\n\nexport const RAMP_START_BPS = 1000n;\nexport const DEFAULT_OI_RAMP_SLOTS = 432_000n;\n\nexport function computeEffectiveOiCapBps(config: MarketConfig, currentSlot: bigint): bigint {\n const target = config.oiCapMultiplierBps;\n if (target === 0n) return 0n;\n if (config.oiRampSlots === 0n) return target;\n if (target <= RAMP_START_BPS) return target;\n const elapsed = currentSlot > config.marketCreatedSlot\n ? currentSlot - config.marketCreatedSlot\n : 0n;\n if (elapsed >= config.oiRampSlots) return target;\n const range = target - RAMP_START_BPS;\n const rampAdd = (range * elapsed) / config.oiRampSlots;\n const result = RAMP_START_BPS + rampAdd;\n return result < target ? result : target;\n}\n\n// =============================================================================\n// Header helpers\n// =============================================================================\n\nexport function readNonce(data: Uint8Array): bigint {\n const layout = detectSlabLayout(data.length, data);\n if (!layout) {\n throw new Error(`readNonce: unrecognized slab data length ${data.length}`);\n }\n const roff = layout.reservedOff;\n if (data.length < roff + 8) throw new Error(\"Slab data too short for nonce\");\n return readU64LE(data, roff);\n}\n\nexport function readLastThrUpdateSlot(data: Uint8Array): bigint {\n const layout = detectSlabLayout(data.length, data);\n if (!layout) {\n throw new Error(`readLastThrUpdateSlot: unrecognized slab data length ${data.length}`);\n }\n const roff = layout.reservedOff;\n if (data.length < roff + 16) throw new Error(\"Slab data too short for lastThrUpdateSlot\");\n return readU64LE(data, roff + 8);\n}\n\n// =============================================================================\n// Parsing Functions\n// =============================================================================\n\n/**\n * Parse slab header (first 72 bytes — layout-independent).\n */\nexport function parseHeader(data: Uint8Array): SlabHeader {\n if (data.length < V0_HEADER_LEN) {\n throw new Error(`Slab data too short for header: ${data.length} < ${V0_HEADER_LEN}`);\n }\n\n const magic = readU64LE(data, 0);\n if (magic !== MAGIC) {\n throw new Error(`Invalid slab magic: expected ${MAGIC.toString(16)}, got ${magic.toString(16)}`);\n }\n\n const version = readU32LE(data, 8);\n const bump = readU8(data, 12);\n const flags = readU8(data, 13);\n const admin = new PublicKey(data.subarray(16, 48));\n\n // Reserved field location depends on layout\n const layout = detectSlabLayout(data.length, data);\n const roff = layout ? layout.reservedOff : V0_RESERVED_OFF;\n const nonce = readU64LE(data, roff);\n const lastThrUpdateSlot = readU64LE(data, roff + 8);\n\n return {\n magic,\n version,\n bump,\n flags,\n resolved: (flags & FLAG_RESOLVED) !== 0,\n paused: (flags & 0x02) !== 0,\n admin,\n nonce,\n lastThrUpdateSlot,\n };\n}\n\n/**\n * Parse market config. Layout-version aware.\n * For V0 slabs, fields beyond the basic config are read if present in the data,\n * otherwise defaults are returned.\n *\n * @param data - Slab data (may be a partial slice for discovery; pass layoutHint in that case)\n * @param layoutHint - Pre-detected layout to use; if omitted, detected from data.length.\n */\nexport function parseConfig(data: Uint8Array, layoutHint?: SlabLayout | null): MarketConfig {\n const layout = layoutHint !== undefined ? layoutHint : detectSlabLayout(data.length, data);\n const configOff = layout ? layout.configOffset : V0_HEADER_LEN;\n const configLen = layout ? layout.configLen : V0_CONFIG_LEN;\n\n const minLen = configOff + Math.min(configLen, 120); // need at least basic fields\n if (data.length < minLen) {\n throw new Error(`Slab data too short for config: ${data.length} < ${minLen}`);\n }\n\n let off = configOff;\n\n const collateralMint = new PublicKey(data.subarray(off, off + 32));\n off += 32;\n\n const vaultPubkey = new PublicKey(data.subarray(off, off + 32));\n off += 32;\n\n const indexFeedId = new PublicKey(data.subarray(off, off + 32));\n off += 32;\n\n const maxStalenessSlots = readU64LE(data, off);\n off += 8;\n\n const confFilterBps = readU16LE(data, off);\n off += 2;\n\n const vaultAuthorityBump = readU8(data, off);\n off += 1;\n\n const invert = readU8(data, off);\n off += 1;\n\n const unitScale = readU32LE(data, off);\n off += 4;\n\n // Funding rate parameters\n const fundingHorizonSlots = readU64LE(data, off);\n off += 8;\n\n const fundingKBps = readU64LE(data, off);\n off += 8;\n\n const fundingInvScaleNotionalE6 = readU128LE(data, off);\n off += 16;\n\n const fundingMaxPremiumBps = readI64LE(data, off);\n off += 8;\n\n const fundingMaxBpsPerSlot = readI64LE(data, off);\n off += 8;\n\n // Extended funding fields\n const fundingPremiumWeightBps = readU64LE(data, off);\n off += 8;\n\n const fundingSettlementIntervalSlots = readU64LE(data, off);\n off += 8;\n\n const fundingPremiumDampeningE6 = readU64LE(data, off);\n off += 8;\n\n const fundingPremiumMaxBpsPerSlot = readU64LE(data, off);\n off += 8;\n\n // Threshold parameters\n const threshFloor = readU128LE(data, off);\n off += 16;\n\n const threshRiskBps = readU64LE(data, off);\n off += 8;\n\n const threshUpdateIntervalSlots = readU64LE(data, off);\n off += 8;\n\n const threshStepBps = readU64LE(data, off);\n off += 8;\n\n const threshAlphaBps = readU64LE(data, off);\n off += 8;\n\n const threshMin = readU128LE(data, off);\n off += 16;\n\n const threshMax = readU128LE(data, off);\n off += 16;\n\n const threshMinStep = readU128LE(data, off);\n off += 16;\n\n // Oracle authority fields\n const oracleAuthority = new PublicKey(data.subarray(off, off + 32));\n off += 32;\n\n const authorityPriceE6 = readU64LE(data, off);\n off += 8;\n\n const authorityTimestamp = readI64LE(data, off);\n off += 8;\n\n // Oracle price circuit breaker\n const oraclePriceCapE2bps = readU64LE(data, off);\n off += 8;\n\n const lastEffectivePriceE6 = readU64LE(data, off);\n off += 8;\n\n // OI cap\n const oiCapMultiplierBps = readU64LE(data, off);\n off += 8;\n\n const maxPnlCap = readU64LE(data, off);\n off += 8;\n\n // Check if we have enough data for V1-only fields\n const remaining = configOff + configLen - off;\n\n let adaptiveFundingEnabled = false;\n let adaptiveScaleBps = 0;\n let adaptiveMaxFundingBps = 0n;\n let marketCreatedSlot = 0n;\n let oiRampSlots = 0n;\n let resolvedSlot = 0n;\n let insuranceIsolationBps = 0;\n let oraclePhase = 0;\n let cumulativeVolumeE6 = 0n;\n let phase2DeltaSlots = 0;\n\n if (remaining >= 40) {\n // V1 extended fields — on-chain order (percolator.rs:3617-3639):\n // market_created_slot(u64), oi_ramp_slots(u64),\n // adaptive_funding_enabled(u8), _pad(u8), adaptive_scale_bps(u16),\n // _pad2(u32), adaptive_max_funding_bps(u64),\n // insurance_isolation_bps(u16), _insurance_isolation_padding([u8;14])\n marketCreatedSlot = readU64LE(data, off);\n off += 8;\n\n oiRampSlots = readU64LE(data, off);\n off += 8;\n\n adaptiveFundingEnabled = readU8(data, off) !== 0;\n off += 1;\n off += 1; // _adaptive_pad\n adaptiveScaleBps = readU16LE(data, off);\n off += 2;\n off += 4; // _adaptive_pad2\n adaptiveMaxFundingBps = readU64LE(data, off);\n off += 8;\n\n if (remaining >= 42) {\n insuranceIsolationBps = readU16LE(data, off);\n // PERC-622: Read oracle phase fields from _insurance_isolation_padding\n // padding starts at off + 2 (after u16 insuranceIsolationBps)\n // [0..2] = mark_oracle_weight (PERC-118), [2] = oracle_phase, [3..11] = cumulative_volume, [11..14] = phase2_delta\n if (remaining >= 56) { // 42 + 14 bytes padding\n const padOff = off + 2;\n oraclePhase = Math.min(readU8(data, padOff + 2), 2);\n cumulativeVolumeE6 = readU64LE(data, padOff + 3);\n // phase2_delta_slots is u24 LE (3 bytes)\n phase2DeltaSlots = data[padOff + 11] | (data[padOff + 12] << 8) | (data[padOff + 13] << 16);\n }\n }\n }\n\n return {\n collateralMint,\n vaultPubkey,\n indexFeedId,\n maxStalenessSlots,\n confFilterBps,\n vaultAuthorityBump,\n invert,\n unitScale,\n fundingHorizonSlots,\n fundingKBps,\n fundingInvScaleNotionalE6,\n fundingMaxPremiumBps,\n fundingMaxBpsPerSlot,\n fundingPremiumWeightBps,\n fundingSettlementIntervalSlots,\n fundingPremiumDampeningE6,\n fundingPremiumMaxBpsPerSlot,\n threshFloor,\n threshRiskBps,\n threshUpdateIntervalSlots,\n threshStepBps,\n threshAlphaBps,\n threshMin,\n threshMax,\n threshMinStep,\n oracleAuthority,\n authorityPriceE6,\n authorityTimestamp,\n oraclePriceCapE2bps,\n lastEffectivePriceE6,\n oiCapMultiplierBps,\n maxPnlCap,\n adaptiveFundingEnabled,\n adaptiveScaleBps,\n adaptiveMaxFundingBps,\n marketCreatedSlot,\n oiRampSlots,\n resolvedSlot,\n insuranceIsolationBps,\n oraclePhase,\n cumulativeVolumeE6,\n phase2DeltaSlots,\n };\n}\n\n/**\n * Parse RiskParams from engine data. Layout-version aware.\n * For V0 slabs, extended params (risk_threshold, maintenance_fee, etc.) are\n * not present on-chain, so defaults (0) are returned.\n *\n * @param data - Slab data (may be a partial slice; pass layoutHint in that case)\n * @param layoutHint - Pre-detected layout to use; if omitted, detected from data.length.\n */\nexport function parseParams(data: Uint8Array, layoutHint?: SlabLayout | null): RiskParams {\n const layout = layoutHint !== undefined ? layoutHint : detectSlabLayout(data.length, data);\n const engineOff = layout ? layout.engineOff : V0_ENGINE_OFF;\n const paramsOff = layout ? layout.engineParamsOff : V0_ENGINE_PARAMS_OFF;\n const paramsSize = layout ? layout.paramsSize : V0_PARAMS_SIZE;\n const base = engineOff + paramsOff;\n\n if (data.length < base + Math.min(paramsSize, 56)) {\n throw new Error(\"Slab data too short for RiskParams\");\n }\n\n // Basic params present in both V0 and V1\n const result: RiskParams = {\n warmupPeriodSlots: readU64LE(data, base + PARAMS_WARMUP_PERIOD_OFF),\n maintenanceMarginBps: readU64LE(data, base + PARAMS_MAINTENANCE_MARGIN_OFF),\n initialMarginBps: readU64LE(data, base + PARAMS_INITIAL_MARGIN_OFF),\n tradingFeeBps: readU64LE(data, base + PARAMS_TRADING_FEE_OFF),\n maxAccounts: readU64LE(data, base + PARAMS_MAX_ACCOUNTS_OFF),\n newAccountFee: readU128LE(data, base + PARAMS_NEW_ACCOUNT_FEE_OFF),\n // Extended params: only read if V1 (paramsSize >= 144)\n riskReductionThreshold: 0n,\n maintenanceFeePerSlot: 0n,\n maxCrankStalenessSlots: 0n,\n liquidationFeeBps: 0n,\n liquidationFeeCap: 0n,\n liquidationBufferBps: 0n,\n minLiquidationAbs: 0n,\n };\n\n if (paramsSize >= 144) {\n result.riskReductionThreshold = readU128LE(data, base + PARAMS_RISK_THRESHOLD_OFF);\n result.maintenanceFeePerSlot = readU128LE(data, base + PARAMS_MAINTENANCE_FEE_OFF);\n result.maxCrankStalenessSlots = readU64LE(data, base + PARAMS_MAX_CRANK_STALENESS_OFF);\n result.liquidationFeeBps = readU64LE(data, base + PARAMS_LIQUIDATION_FEE_BPS_OFF);\n result.liquidationFeeCap = readU128LE(data, base + PARAMS_LIQUIDATION_FEE_CAP_OFF);\n result.liquidationBufferBps = readU64LE(data, base + PARAMS_LIQUIDATION_BUFFER_OFF);\n result.minLiquidationAbs = readU128LE(data, base + PARAMS_MIN_LIQUIDATION_OFF);\n }\n\n return result;\n}\n\n/**\n * Parse RiskEngine state (excluding accounts array). Layout-version aware.\n */\nexport function parseEngine(data: Uint8Array): EngineState {\n const layout = detectSlabLayout(data.length, data);\n if (!layout) {\n throw new Error(`Unrecognized slab data length: ${data.length}. Cannot determine layout version.`);\n }\n\n const base = layout.engineOff;\n\n return {\n vault: readU128LE(data, base),\n insuranceFund: {\n balance: readU128LE(data, base + layout.engineInsuranceOff),\n feeRevenue: readU128LE(data, base + layout.engineInsuranceOff + 16),\n isolatedBalance: layout.hasInsuranceIsolation\n ? readU128LE(data, base + layout.engineInsuranceIsolatedOff)\n : 0n,\n isolationBps: layout.hasInsuranceIsolation\n ? readU16LE(data, base + layout.engineInsuranceIsolationBpsOff)\n : 0,\n },\n currentSlot: readU64LE(data, base + layout.engineCurrentSlotOff),\n fundingIndexQpbE6: readI128LE(data, base + layout.engineFundingIndexOff),\n lastFundingSlot: readU64LE(data, base + layout.engineLastFundingSlotOff),\n fundingRateBpsPerSlotLast: readI64LE(data, base + layout.engineFundingRateBpsOff),\n lastCrankSlot: readU64LE(data, base + layout.engineLastCrankSlotOff),\n maxCrankStalenessSlots: readU64LE(data, base + layout.engineMaxCrankStalenessOff),\n totalOpenInterest: readU128LE(data, base + layout.engineTotalOiOff),\n longOi: layout.engineLongOiOff >= 0\n ? readU128LE(data, base + layout.engineLongOiOff)\n : 0n,\n shortOi: layout.engineShortOiOff >= 0\n ? readU128LE(data, base + layout.engineShortOiOff)\n : 0n,\n cTot: readU128LE(data, base + layout.engineCTotOff),\n pnlPosTot: readU128LE(data, base + layout.enginePnlPosTotOff),\n liqCursor: readU16LE(data, base + layout.engineLiqCursorOff),\n gcCursor: readU16LE(data, base + layout.engineGcCursorOff),\n lastSweepStartSlot: readU64LE(data, base + layout.engineLastSweepStartOff),\n lastSweepCompleteSlot: readU64LE(data, base + layout.engineLastSweepCompleteOff),\n crankCursor: readU16LE(data, base + layout.engineCrankCursorOff),\n sweepStartIdx: readU16LE(data, base + layout.engineSweepStartIdxOff),\n lifetimeLiquidations: readU64LE(data, base + layout.engineLifetimeLiquidationsOff),\n lifetimeForceCloses: readU64LE(data, base + layout.engineLifetimeForceClosesOff),\n netLpPos: readI128LE(data, base + layout.engineNetLpPosOff),\n lpSumAbs: readU128LE(data, base + layout.engineLpSumAbsOff),\n lpMaxAbs: layout.engineLpMaxAbsOff >= 0 ? readU128LE(data, base + layout.engineLpMaxAbsOff) : 0n,\n lpMaxAbsSweep: layout.engineLpMaxAbsSweepOff >= 0 ? readU128LE(data, base + layout.engineLpMaxAbsSweepOff) : 0n,\n emergencyOiMode: layout.engineEmergencyOiModeOff >= 0\n ? data[base + layout.engineEmergencyOiModeOff] !== 0\n : false,\n emergencyStartSlot: layout.engineEmergencyStartSlotOff >= 0\n ? readU64LE(data, base + layout.engineEmergencyStartSlotOff)\n : 0n,\n lastBreakerSlot: layout.engineLastBreakerSlotOff >= 0\n ? readU64LE(data, base + layout.engineLastBreakerSlotOff)\n : 0n,\n markPriceE6: layout.engineMarkPriceOff >= 0\n ? readU64LE(data, base + layout.engineMarkPriceOff)\n : 0n,\n numUsedAccounts: (() => {\n if (layout.postBitmap < 18) return 0;\n const bw = layout.bitmapWords;\n return readU16LE(data, base + layout.engineBitmapOff + bw * 8);\n })(),\n nextAccountId: (() => {\n if (layout.postBitmap < 18) return 0n;\n const bw = layout.bitmapWords;\n const numUsedOff = layout.engineBitmapOff + bw * 8;\n return readU64LE(data, base + Math.ceil((numUsedOff + 2) / 8) * 8);\n })(),\n };\n}\n\n/**\n * Read bitmap to get list of used account indices.\n */\n/**\n * Return all account indices whose bitmap bit is set (i.e. slot is in use).\n * Uses the layout-aware bitmap offset so V1_LEGACY slabs (bitmap at rel+672) are handled correctly.\n */\nexport function parseUsedIndices(data: Uint8Array): number[] {\n const layout = detectSlabLayout(data.length, data);\n if (!layout) throw new Error(`Unrecognized slab data length: ${data.length}`);\n\n const base = layout.engineOff + layout.engineBitmapOff;\n if (data.length < base + layout.bitmapWords * 8) {\n throw new Error(\"Slab data too short for bitmap\");\n }\n\n const used: number[] = [];\n for (let word = 0; word < layout.bitmapWords; word++) {\n const bits = readU64LE(data, base + word * 8);\n if (bits === 0n) continue;\n for (let bit = 0; bit < 64; bit++) {\n if ((bits >> BigInt(bit)) & 1n) {\n used.push(word * 64 + bit);\n }\n }\n }\n return used;\n}\n\n/**\n * Check if a specific account index is used.\n */\nexport function isAccountUsed(data: Uint8Array, idx: number): boolean {\n const layout = detectSlabLayout(data.length, data);\n if (!layout) return false;\n if (!Number.isInteger(idx) || idx < 0 || idx >= layout.maxAccounts) return false;\n const base = layout.engineOff + layout.engineBitmapOff;\n const word = Math.floor(idx / 64);\n const bit = idx % 64;\n const bits = readU64LE(data, base + word * 8);\n return ((bits >> BigInt(bit)) & 1n) !== 0n;\n}\n\n/**\n * Calculate the maximum valid account index for a given slab size.\n */\nexport function maxAccountIndex(dataLen: number): number {\n const layout = detectSlabLayout(dataLen);\n if (!layout) return 0;\n const accountsEnd = dataLen - layout.accountsOff;\n if (accountsEnd <= 0) return 0;\n return Math.floor(accountsEnd / layout.accountSize);\n}\n\n/**\n * Parse a single account by index.\n */\nexport function parseAccount(data: Uint8Array, idx: number): Account {\n const layout = detectSlabLayout(data.length, data);\n if (!layout) throw new Error(`Unrecognized slab data length: ${data.length}`);\n\n const maxIdx = maxAccountIndex(data.length);\n if (!Number.isInteger(idx) || idx < 0 || idx >= maxIdx) {\n throw new Error(`Account index out of range: ${idx} (max: ${maxIdx - 1})`);\n }\n\n const base = layout.accountsOff + idx * layout.accountSize;\n if (data.length < base + layout.accountSize) {\n throw new Error(\"Slab data too short for account\");\n }\n\n // Select layout-dependent account field offsets.\n // V_ADL slabs (account_size=312) have shifted offsets from reserved_pnl growing u64→u128 (PERC-8267).\n const isAdl = layout.accountSize >= 312;\n const warmupStartedOff = isAdl ? V_ADL_ACCT_WARMUP_STARTED_OFF : ACCT_WARMUP_STARTED_OFF;\n const warmupSlopeOff = isAdl ? V_ADL_ACCT_WARMUP_SLOPE_OFF : ACCT_WARMUP_SLOPE_OFF;\n const positionSizeOff = isAdl ? V_ADL_ACCT_POSITION_SIZE_OFF : ACCT_POSITION_SIZE_OFF;\n const entryPriceOff = isAdl ? V_ADL_ACCT_ENTRY_PRICE_OFF : ACCT_ENTRY_PRICE_OFF;\n const fundingIndexOff = isAdl ? V_ADL_ACCT_FUNDING_INDEX_OFF : ACCT_FUNDING_INDEX_OFF;\n const matcherProgOff = isAdl ? V_ADL_ACCT_MATCHER_PROGRAM_OFF: ACCT_MATCHER_PROGRAM_OFF;\n const matcherCtxOff = isAdl ? V_ADL_ACCT_MATCHER_CONTEXT_OFF: ACCT_MATCHER_CONTEXT_OFF;\n const feeCreditsOff = isAdl ? V_ADL_ACCT_FEE_CREDITS_OFF : ACCT_FEE_CREDITS_OFF;\n const lastFeeSlotOff = isAdl ? V_ADL_ACCT_LAST_FEE_SLOT_OFF : ACCT_LAST_FEE_SLOT_OFF;\n\n const kindByte = readU8(data, base + ACCT_KIND_OFF);\n const kind = kindByte === 1 ? AccountKind.LP : AccountKind.User;\n\n return {\n kind,\n accountId: readU64LE(data, base + ACCT_ACCOUNT_ID_OFF),\n capital: readU128LE(data, base + ACCT_CAPITAL_OFF),\n pnl: readI128LE(data, base + ACCT_PNL_OFF),\n reservedPnl: isAdl ? readU128LE(data, base + ACCT_RESERVED_PNL_OFF) : readU64LE(data, base + ACCT_RESERVED_PNL_OFF),\n warmupStartedAtSlot: readU64LE(data, base + warmupStartedOff),\n warmupSlopePerStep: readU128LE(data, base + warmupSlopeOff),\n positionSize: readI128LE(data, base + positionSizeOff),\n entryPrice: readU64LE(data, base + entryPriceOff),\n fundingIndex: readI128LE(data, base + fundingIndexOff),\n matcherProgram: new PublicKey(data.subarray(base + matcherProgOff, base + matcherProgOff + 32)),\n matcherContext: new PublicKey(data.subarray(base + matcherCtxOff, base + matcherCtxOff + 32)),\n owner: new PublicKey(data.subarray(base + layout.acctOwnerOff, base + layout.acctOwnerOff + 32)),\n feeCredits: readI128LE(data, base + feeCreditsOff),\n lastFeeSlot: readU64LE(data, base + lastFeeSlotOff),\n };\n}\n\n/**\n * Parse all used accounts.\n */\nexport function parseAllAccounts(data: Uint8Array): { idx: number; account: Account }[] {\n const indices = parseUsedIndices(data);\n const maxIdx = maxAccountIndex(data.length);\n const validIndices = indices.filter(idx => idx < maxIdx);\n const droppedCount = indices.length - validIndices.length;\n if (droppedCount > 0) {\n console.warn(\n `[parseAllAccounts] bitmap claims ${indices.length} used accounts but only ${maxIdx} fit ` +\n `in the slab — ${droppedCount} out-of-bounds indices dropped (possible bitmap corruption)`,\n );\n }\n return validIndices.map(idx => ({\n idx,\n account: parseAccount(data, idx),\n }));\n}\n\n","import { PublicKey } from \"@solana/web3.js\";\n\nconst textEncoder = new TextEncoder();\n\n/**\n * Derive vault authority PDA.\n * Seeds: [\"vault\", slab_key]\n */\nexport function deriveVaultAuthority(\n programId: PublicKey,\n slab: PublicKey\n): [PublicKey, number] {\n return PublicKey.findProgramAddressSync(\n [textEncoder.encode(\"vault\"), slab.toBytes()],\n programId\n );\n}\n\n/**\n * Derive insurance LP mint PDA.\n * Seeds: [\"ins_lp\", slab_key]\n */\nexport function deriveInsuranceLpMint(\n programId: PublicKey,\n slab: PublicKey\n): [PublicKey, number] {\n return PublicKey.findProgramAddressSync(\n [textEncoder.encode(\"ins_lp\"), slab.toBytes()],\n programId\n );\n}\n\nconst LP_INDEX_U16_MAX = 0xffff;\n\n/**\n * Derive LP PDA for TradeCpi.\n * Seeds: [\"lp\", slab_key, lp_idx as u16 LE]\n */\nexport function deriveLpPda(\n programId: PublicKey,\n slab: PublicKey,\n lpIdx: number\n): [PublicKey, number] {\n if (\n typeof lpIdx !== \"number\" ||\n !Number.isInteger(lpIdx) ||\n lpIdx < 0 ||\n lpIdx > LP_INDEX_U16_MAX\n ) {\n throw new Error(\n `deriveLpPda: lpIdx must be an integer in [0, ${LP_INDEX_U16_MAX}], got ${lpIdx}`,\n );\n }\n const idxBuf = new Uint8Array(2);\n new DataView(idxBuf.buffer).setUint16(0, lpIdx, true);\n return PublicKey.findProgramAddressSync(\n [textEncoder.encode(\"lp\"), slab.toBytes(), idxBuf],\n programId\n );\n}\n\n/**\n * Derive keeper fund PDA.\n * Seeds: [\"keeper_fund\", slab_key]\n */\nexport function deriveKeeperFund(\n programId: PublicKey,\n slab: PublicKey\n): [PublicKey, number] {\n return PublicKey.findProgramAddressSync(\n [textEncoder.encode(\"keeper_fund\"), slab.toBytes()],\n programId\n );\n}\n\n// ---------------------------------------------------------------------------\n// DEX Program IDs\n// ---------------------------------------------------------------------------\n\n/** PumpSwap AMM program ID. */\nexport const PUMPSWAP_PROGRAM_ID = new PublicKey(\n \"pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA\"\n);\n\n/** Raydium CLMM (Concentrated Liquidity) program ID. */\nexport const RAYDIUM_CLMM_PROGRAM_ID = new PublicKey(\n \"CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK\"\n);\n\n/** Meteora DLMM (Dynamic Liquidity Market Maker) program ID. */\nexport const METEORA_DLMM_PROGRAM_ID = new PublicKey(\n \"LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo\"\n);\n\n// ---------------------------------------------------------------------------\n// Pyth Push Oracle\n// ---------------------------------------------------------------------------\n\n/** Pyth Push Oracle program on mainnet. */\nexport const PYTH_PUSH_ORACLE_PROGRAM_ID = new PublicKey(\n \"pythWSnswVUd12oZpeFP8e9CVaEqJg25g1Vtc2biRsT\"\n);\n\n// ---------------------------------------------------------------------------\n// Creator Lock PDA (PERC-627)\n// ---------------------------------------------------------------------------\n\n/**\n * Seed used to derive the creator lock PDA.\n * Matches `creator_lock::CREATOR_LOCK_SEED` in percolator-prog.\n */\nexport const CREATOR_LOCK_SEED = \"creator_lock\";\n\n/**\n * Derive the creator lock PDA for a given slab.\n * Seeds: [\"creator_lock\", slab_key]\n *\n * This PDA is required as accounts[9] in every LpVaultWithdraw instruction\n * since percolator-prog PR#170 (GH#1926 / PERC-8287).\n * Non-creator withdrawers must pass this key; if no lock exists on-chain the\n * enforcement is a no-op. The SDK must ALWAYS include it — passing it is mandatory.\n *\n * @param programId - The percolator program ID.\n * @param slab - The slab (market) public key.\n * @returns [pda, bump]\n *\n * @example\n * ```ts\n * const [creatorLockPda] = deriveCreatorLockPda(PROGRAM_ID, slabKey);\n * ```\n */\nexport function deriveCreatorLockPda(\n programId: PublicKey,\n slab: PublicKey\n): [PublicKey, number] {\n return PublicKey.findProgramAddressSync(\n [textEncoder.encode(CREATOR_LOCK_SEED), slab.toBytes()],\n programId\n );\n}\n/** 32-byte feed id as 64 hex digits (optional `0x` prefix after trim). */\nconst PYTH_FEED_ID_HEX_LEN = 64;\n\nfunction normalizePythFeedIdHex(feedIdHex: string): string {\n let s = feedIdHex.trim();\n if (s.startsWith(\"0x\") || s.startsWith(\"0X\")) {\n s = s.slice(2);\n }\n return s;\n}\n\n/**\n * Derive the Pyth Push Oracle PDA for a given feed ID.\n * Seeds: [shard_id(u16 LE, always 0), feed_id(32 bytes)]\n * Program: pythWSnswVUd12oZpeFP8e9CVaEqJg25g1Vtc2biRsT\n */\nconst FEED_HEX_RE = /^[0-9a-fA-F]{64}$/;\n\nexport function derivePythPushOraclePDA(feedIdHex: string): [PublicKey, number] {\n const normalized = normalizePythFeedIdHex(feedIdHex);\n if (!FEED_HEX_RE.test(normalized)) {\n throw new Error(\n `derivePythPushOraclePDA: feedIdHex must be 64 hex digits (32 bytes); got ${normalized.length === 64 ? \"non-hexadecimal characters\" : normalized.length + \" chars\"}`, );\n }\n const feedId = new Uint8Array(32);\n for (let i = 0; i < 32; i++) {\n feedId[i] = parseInt(normalized.substring(i * 2, i * 2 + 2), 16);\n }\n const shardBuf = new Uint8Array(2); // shard_id = 0 (u16 LE)\n return PublicKey.findProgramAddressSync(\n [shardBuf, feedId],\n PYTH_PUSH_ORACLE_PROGRAM_ID,\n );\n}\n","import { Connection, PublicKey } from \"@solana/web3.js\";\nimport {\n getAssociatedTokenAddress,\n getAssociatedTokenAddressSync,\n getAccount,\n Account,\n TOKEN_PROGRAM_ID,\n} from \"@solana/spl-token\";\nimport { TOKEN_2022_PROGRAM_ID } from \"./token-program.js\";\n\n/**\n * Get the associated token address for an owner and mint.\n * Supports both standard SPL Token and Token2022 via optional tokenProgramId.\n */\nexport async function getAta(\n owner: PublicKey,\n mint: PublicKey,\n allowOwnerOffCurve = false,\n tokenProgramId: PublicKey = TOKEN_PROGRAM_ID,\n): Promise<PublicKey> {\n return getAssociatedTokenAddress(mint, owner, allowOwnerOffCurve, tokenProgramId);\n}\n\n/**\n * Synchronous version of getAta.\n * Supports both standard SPL Token and Token2022 via optional tokenProgramId.\n */\nexport function getAtaSync(\n owner: PublicKey,\n mint: PublicKey,\n allowOwnerOffCurve = false,\n tokenProgramId: PublicKey = TOKEN_PROGRAM_ID,\n): PublicKey {\n return getAssociatedTokenAddressSync(mint, owner, allowOwnerOffCurve, tokenProgramId);\n}\n\n/**\n * Fetch token account info.\n * Supports both standard SPL Token and Token2022 via optional tokenProgramId.\n * Throws if account doesn't exist.\n */\nexport async function fetchTokenAccount(\n connection: Connection,\n address: PublicKey,\n tokenProgramId: PublicKey = TOKEN_PROGRAM_ID,\n): Promise<Account> {\n return getAccount(connection, address, undefined, tokenProgramId);\n}\n","import { Connection, PublicKey } from \"@solana/web3.js\";\nimport {\n parseHeader,\n parseConfig,\n parseParams,\n detectSlabLayout,\n SLAB_TIERS_V1M,\n SLAB_TIERS_V2,\n SLAB_TIERS_V_ADL,\n type SlabHeader,\n type MarketConfig,\n type EngineState,\n type RiskParams,\n type SlabLayout,\n} from \"./slab.js\";\n\n/** V1 bitmap offset within engine struct (updated for PERC-120/121/122 struct changes) */\nconst ENGINE_BITMAP_OFF = 656; // Updated for PERC-299 (608 + 24 emergency OI fields)\n/** V0 bitmap offset within engine struct (deployed devnet program) */\nconst ENGINE_BITMAP_OFF_V0 = 320;\n\n/**\n * A discovered Percolator market from on-chain program accounts.\n */\nexport interface DiscoveredMarket {\n slabAddress: PublicKey;\n /** The program that owns this slab account */\n programId: PublicKey;\n header: SlabHeader;\n config: MarketConfig;\n engine: EngineState;\n params: RiskParams;\n}\n\n/** PERCOLAT magic bytes — stored little-endian on-chain as TALOCREP */\nconst MAGIC_BYTES = new Uint8Array([0x54, 0x41, 0x4c, 0x4f, 0x43, 0x52, 0x45, 0x50]);\n\n/**\n * Slab tier definitions — V1 layout (all tiers upgraded as of 2026-03-13).\n * IMPORTANT: dataSize must match the compiled program's SLAB_LEN for that MAX_ACCOUNTS.\n * The on-chain program has a hardcoded SLAB_LEN — slab account data.len() must equal it exactly.\n *\n * Layout: HEADER(104) + CONFIG(536) + RiskEngine(variable by tier)\n * ENGINE_OFF = 640 (HEADER=104 + CONFIG=536, padded to 8-byte align on SBF)\n * RiskEngine = fixed(656) + bitmap(BW*8) + post_bitmap(18) + next_free(N*2) + pad + accounts(N*248)\n *\n * Values are empirically verified against on-chain initialized accounts (GH #1109):\n * small = 65,352 (256-acct program, verified on-chain post-V1 upgrade)\n * medium = 257,448 (1024-acct program g9msRSV3, verified on-chain)\n * large = 1,025,832 (4096-acct program FxfD37s1, pre-PERC-118, matches slabDataSizeV1(4096) formula)\n *\n * NOTE: small program (FwfBKZXb) redeployed with --features small,devnet (2026-03-13).\n * Large program FxfD37s1 is pre-PERC-118 — SLAB_LEN=1,025,832, matching formula.\n * See GH #1109, GH #1112.\n *\n * History: Small was V0 (62_808) until 2026-03-13 program upgrade. V0 values preserved\n * in SLAB_TIERS_V0 for discovery of legacy on-chain accounts.\n */\nexport const SLAB_TIERS = {\n small: { maxAccounts: 256, dataSize: 65_352, label: \"Small\", description: \"256 slots · ~0.45 SOL\" },\n medium: { maxAccounts: 1024, dataSize: 257_448, label: \"Medium\", description: \"1,024 slots · ~1.79 SOL\" },\n large: { maxAccounts: 4096, dataSize: 1_025_832, label: \"Large\", description: \"4,096 slots · ~7.14 SOL\" },\n} as const;\n\n/** @deprecated V0 slab sizes — kept for backward compatibility with old on-chain slabs */\nexport const SLAB_TIERS_V0 = {\n small: { maxAccounts: 256, dataSize: 62_808, label: \"Small\", description: \"256 slots · ~0.44 SOL\" },\n medium: { maxAccounts: 1024, dataSize: 248_760, label: \"Medium\", description: \"1,024 slots · ~1.73 SOL\" },\n large: { maxAccounts: 4096, dataSize: 992_568, label: \"Large\", description: \"4,096 slots · ~6.90 SOL\" },\n} as const;\n\n/**\n * V1D slab sizes — actually-deployed devnet V1 program (ENGINE_OFF=424, BITMAP_OFF=624).\n * PR #1200 added V1D layout detection in slab.ts but discovery.ts ALL_TIERS was missing\n * these sizes, causing V1D slabs to fall through to the memcmp fallback with wrong dataSize\n * hints → detectSlabLayout returning null → parse failure (GH#1205).\n *\n * Sizes computed via computeSlabSize(ENGINE_OFF=424, BITMAP_OFF=624, ACCOUNT_SIZE=248, N, postBitmap=2):\n * The V1D deployed program uses postBitmap=2 (free_head u16 only — no num_used/pad/next_account_id).\n * This is 16 bytes smaller per tier than the SDK default (postBitmap=18). GH#1234.\n * micro = 17,064 (64 slots)\n * small = 65,088 (256 slots)\n * medium = 257,184 (1,024 slots)\n * large = 1,025,568 (4,096 slots)\n */\nexport const SLAB_TIERS_V1D = {\n micro: { maxAccounts: 64, dataSize: 17_064, label: \"Micro\", description: \"64 slots (V1D devnet)\" },\n small: { maxAccounts: 256, dataSize: 65_088, label: \"Small\", description: \"256 slots (V1D devnet)\" },\n medium: { maxAccounts: 1024, dataSize: 257_184, label: \"Medium\", description: \"1,024 slots (V1D devnet)\" },\n large: { maxAccounts: 4096, dataSize: 1_025_568, label: \"Large\", description: \"4,096 slots (V1D devnet)\" },\n} as const;\n\n/**\n * V1D legacy slab sizes — on-chain V1D slabs created before GH#1234 when the SDK assumed\n * postBitmap=18. These are 16 bytes larger per tier than SLAB_TIERS_V1D.\n * PR #1236 fixed postBitmap for new slabs (→2) but caused slab 6ZytbpV4 (65104 bytes,\n * top active market ~$15k 24h vol) to be unrecognized → \"Failed to load market\". GH#1237.\n *\n * Sizes computed via computeSlabSize(ENGINE_OFF=424, BITMAP_OFF=624, ACCOUNT_SIZE=248, N, postBitmap=18):\n * micro = 17,080 (64 slots)\n * small = 65,104 (256 slots) ← slab 6ZytbpV4 TEST/USD\n * medium = 257,200 (1,024 slots)\n * large = 1,025,584 (4,096 slots)\n */\nexport const SLAB_TIERS_V1D_LEGACY = {\n micro: { maxAccounts: 64, dataSize: 17_080, label: \"Micro\", description: \"64 slots (V1D legacy, postBitmap=18)\" },\n small: { maxAccounts: 256, dataSize: 65_104, label: \"Small\", description: \"256 slots (V1D legacy, postBitmap=18)\" },\n medium: { maxAccounts: 1024, dataSize: 257_200, label: \"Medium\", description: \"1,024 slots (V1D legacy, postBitmap=18)\" },\n large: { maxAccounts: 4096, dataSize: 1_025_584, label: \"Large\", description: \"4,096 slots (V1D legacy, postBitmap=18)\" },\n} as const;\n\n/** @deprecated Alias — use SLAB_TIERS (already V1) */\nexport const SLAB_TIERS_V1 = SLAB_TIERS;\n\n/**\n * V_ADL slab tier sizes — PERC-8270/8271 ADL-upgraded program.\n * ENGINE_OFF=624, BITMAP_OFF=1006, ACCOUNT_SIZE=312, postBitmap=18.\n * New account layout adds ADL tracking fields (+64 bytes/account).\n * BPF SLAB_LEN verified by cargo build-sbf in PERC-8271: large (4096) = 1288304 bytes.\n */\n// Single source of truth lives in slab.ts (SLAB_TIERS_V_ADL).\nexport const SLAB_TIERS_V_ADL_DISCOVERY = SLAB_TIERS_V_ADL;\n\nexport type SlabTierKey = keyof typeof SLAB_TIERS;\n\n/** Calculate slab data size for arbitrary account count.\n *\n * Layout (SBF, u128 align = 8):\n * HEADER(104) + CONFIG(536) → ENGINE_OFF = 640\n * RiskEngine fixed scalars: 656 bytes (PERC-299: +24 emergency OI, +32 long/short OI)\n * + bitmap: ceil(N/64)*8\n * + num_used_accounts(u16) + pad(6) + next_account_id(u64) + free_head(u16) = 18\n * + next_free: N*2\n * + pad to 8-byte alignment for Account array\n * + accounts: N*248\n *\n * Must match the on-chain program's SLAB_LEN exactly.\n */\nexport function slabDataSize(maxAccounts: number): number {\n // V0 layout (deployed devnet): ENGINE_OFF=480, ENGINE_BITMAP_OFF=320, ACCOUNT_SIZE=240\n const ENGINE_OFF_V0 = 480;\n const ENGINE_BITMAP_OFF_V0 = 320;\n const ACCOUNT_SIZE_V0 = 240;\n const bitmapBytes = Math.ceil(maxAccounts / 64) * 8;\n const postBitmap = 18;\n const nextFreeBytes = maxAccounts * 2;\n const preAccountsLen = ENGINE_BITMAP_OFF_V0 + bitmapBytes + postBitmap + nextFreeBytes;\n const accountsOff = Math.ceil(preAccountsLen / 8) * 8;\n return ENGINE_OFF_V0 + accountsOff + maxAccounts * ACCOUNT_SIZE_V0;\n}\n\n/**\n * Calculate slab data size for V1 layout (ENGINE_OFF=640).\n *\n * NOTE: This formula is accurate for small (256) and medium (1024) tiers but\n * underestimates large (4096) by 16 bytes — likely due to a padding/alignment\n * difference at high account counts or a post-PERC-118 struct addition in the\n * deployed binary. Always prefer the hardcoded SLAB_TIERS values (empirically\n * verified on-chain) over this formula for production use.\n */\nexport function slabDataSizeV1(maxAccounts: number): number {\n const ENGINE_OFF_V1 = 640; // HEADER(104) + CONFIG(536) aligned to 8 on SBF = 640\n const ENGINE_BITMAP_OFF_V1 = 656;\n const ACCOUNT_SIZE_V1 = 248;\n const bitmapBytes = Math.ceil(maxAccounts / 64) * 8;\n const postBitmap = 18;\n const nextFreeBytes = maxAccounts * 2;\n const preAccountsLen = ENGINE_BITMAP_OFF_V1 + bitmapBytes + postBitmap + nextFreeBytes;\n const accountsOff = Math.ceil(preAccountsLen / 8) * 8;\n return ENGINE_OFF_V1 + accountsOff + maxAccounts * ACCOUNT_SIZE_V1;\n}\n\n/**\n * Validate that a slab data size matches one of the known tier sizes.\n * Use this to catch tier↔program mismatches early (PERC-277).\n *\n * @param dataSize - The expected slab data size (from SLAB_TIERS[tier].dataSize)\n * @param programSlabLen - The program's compiled SLAB_LEN (from on-chain error logs or program introspection)\n * @returns true if sizes match, false if there's a mismatch\n */\nexport function validateSlabTierMatch(dataSize: number, programSlabLen: number): boolean {\n return dataSize === programSlabLen;\n}\n\n/** All known slab data sizes for discovery (V0 + V1 + V1D + V1D legacy + V1M + V_ADL tiers) */\nconst ALL_SLAB_SIZES = [\n ...Object.values(SLAB_TIERS).map(t => t.dataSize),\n ...Object.values(SLAB_TIERS_V0).map(t => t.dataSize),\n ...Object.values(SLAB_TIERS_V1D).map(t => t.dataSize),\n ...Object.values(SLAB_TIERS_V1D_LEGACY).map(t => t.dataSize),\n ...Object.values(SLAB_TIERS_V1M).map(t => t.dataSize),\n ...Object.values(SLAB_TIERS_V_ADL).map(t => t.dataSize),\n];\n\n/** Legacy constant for backward compat */\nconst SLAB_DATA_SIZE = SLAB_TIERS.large.dataSize;\n\n/** We need header(104) + config(536) + engine up to nextAccountId (~1200). Total ~1840. Use 1940 for margin. */\nconst HEADER_SLICE_LENGTH = 1940;\n\nfunction dv(data: Uint8Array): DataView {\n return new DataView(data.buffer, data.byteOffset, data.byteLength);\n}\nfunction readU16LE(data: Uint8Array, off: number): number {\n return dv(data).getUint16(off, true);\n}\nfunction readU64LE(data: Uint8Array, off: number): bigint {\n return dv(data).getBigUint64(off, true);\n}\nfunction readI64LE(data: Uint8Array, off: number): bigint {\n return dv(data).getBigInt64(off, true);\n}\nfunction readU128LE(buf: Uint8Array, offset: number): bigint {\n const lo = readU64LE(buf, offset);\n const hi = readU64LE(buf, offset + 8);\n return (hi << 64n) | lo;\n}\nfunction readI128LE(buf: Uint8Array, offset: number): bigint {\n const lo = readU64LE(buf, offset);\n const hi = readU64LE(buf, offset + 8);\n const unsigned = (hi << 64n) | lo;\n const SIGN_BIT = 1n << 127n;\n if (unsigned >= SIGN_BIT) return unsigned - (1n << 128n);\n return unsigned;\n}\n\n/**\n * Light engine parser that works with partial slab data (dataSlice, no accounts array).\n * Requires a layout hint (from detectSlabLayout on the actual slab size) to use correct offsets.\n *\n * @param data — partial slab slice (HEADER_SLICE_LENGTH bytes)\n * @param layout — SlabLayout from detectSlabLayout(actualDataSize). If null, falls back to V0.\n * @param maxAccounts — tier's max accounts for bitmap offset calculation\n */\nfunction parseEngineLight(\n data: Uint8Array,\n layout: SlabLayout | null,\n maxAccounts: number = 4096,\n): EngineState {\n const isV0 = !layout || layout.version === 0;\n const base = layout ? layout.engineOff : 480; // V0=480, V1=640\n const bitmapOff = layout ? layout.engineBitmapOff : ENGINE_BITMAP_OFF_V0;\n\n const minLen = base + bitmapOff;\n if (data.length < minLen) {\n throw new Error(`Slab data too short for engine light parse: ${data.length} < ${minLen}`);\n }\n\n // Compute tier-dependent offsets for numUsedAccounts and nextAccountId\n const bitmapWords = Math.ceil(maxAccounts / 64);\n const numUsedOff = bitmapOff + bitmapWords * 8; // u16 right after bitmap\n const nextAccountIdOff = Math.ceil((numUsedOff + 2) / 8) * 8; // u64, 8-byte aligned\n\n const canReadNumUsed = data.length >= base + numUsedOff + 2;\n const canReadNextId = data.length >= base + nextAccountIdOff + 8;\n\n if (isV0) {\n // V0 engine struct (deployed devnet): ENGINE_OFF=480\n // vault(0,16) + insurance(16,32) + params(48,56) + currentSlot(104,8)\n // + fundingIndex(112,16) + lastFundingSlot(128,8) + fundingRateBps(136,8)\n // + lastCrankSlot(144,8) + maxCrankStaleness(152,8) + totalOI(160,16)\n // + cTot(176,16) + pnlPosTot(192,16) + liqCursor(208,2) + gcCursor(210,2)\n // + lastSweepStart(216,8) + lastSweepComplete(224,8) + crankCursor(232,2) + sweepStartIdx(234,2)\n // + lifetimeLiquidations(240,8) + lifetimeForceCloses(248,8)\n // + netLpPos(256,16) + lpSumAbs(272,16) + lpMaxAbs(288,16) + bitmap(320)\n return {\n vault: readU128LE(data, base + 0),\n insuranceFund: {\n balance: readU128LE(data, base + 16),\n feeRevenue: readU128LE(data, base + 32),\n isolatedBalance: 0n,\n isolationBps: 0,\n },\n currentSlot: readU64LE(data, base + 104),\n fundingIndexQpbE6: readI128LE(data, base + 112),\n lastFundingSlot: readU64LE(data, base + 128),\n fundingRateBpsPerSlotLast: readI64LE(data, base + 136),\n lastCrankSlot: readU64LE(data, base + 144),\n maxCrankStalenessSlots: readU64LE(data, base + 152),\n totalOpenInterest: readU128LE(data, base + 160),\n longOi: 0n,\n shortOi: 0n,\n cTot: readU128LE(data, base + 176),\n pnlPosTot: readU128LE(data, base + 192),\n liqCursor: readU16LE(data, base + 208),\n gcCursor: readU16LE(data, base + 210),\n lastSweepStartSlot: readU64LE(data, base + 216),\n lastSweepCompleteSlot: readU64LE(data, base + 224),\n crankCursor: readU16LE(data, base + 232),\n sweepStartIdx: readU16LE(data, base + 234),\n lifetimeLiquidations: readU64LE(data, base + 240),\n lifetimeForceCloses: readU64LE(data, base + 248),\n netLpPos: readI128LE(data, base + 256),\n lpSumAbs: readU128LE(data, base + 272),\n lpMaxAbs: readU128LE(data, base + 288),\n lpMaxAbsSweep: 0n,\n emergencyOiMode: false,\n emergencyStartSlot: 0n,\n lastBreakerSlot: 0n,\n markPriceE6: 0n, // V0 engine has no mark_price field\n numUsedAccounts: canReadNumUsed ? readU16LE(data, base + numUsedOff) : 0,\n nextAccountId: canReadNextId ? readU64LE(data, base + nextAccountIdOff) : 0n,\n };\n }\n\n // V2 engine struct (BPF intermediate): ENGINE_OFF=600, BITMAP_OFF=432\n // No mark_price, long_oi, short_oi, emergency OI fields.\n // Field offsets relative to engineOff are different from V1.\n const isV2 = layout?.version === 2;\n if (isV2) {\n return {\n vault: readU128LE(data, base + 0),\n insuranceFund: {\n balance: readU128LE(data, base + 16),\n feeRevenue: readU128LE(data, base + 32),\n isolatedBalance: readU128LE(data, base + 48),\n isolationBps: readU16LE(data, base + 64),\n },\n currentSlot: readU64LE(data, base + 352),\n fundingIndexQpbE6: readI128LE(data, base + 360),\n lastFundingSlot: readU64LE(data, base + 376),\n fundingRateBpsPerSlotLast: readI64LE(data, base + 384),\n lastCrankSlot: readU64LE(data, base + 392),\n maxCrankStalenessSlots: readU64LE(data, base + 400),\n totalOpenInterest: readU128LE(data, base + 408),\n longOi: 0n, // V2 has no long_oi\n shortOi: 0n, // V2 has no short_oi\n cTot: readU128LE(data, base + 424),\n pnlPosTot: readU128LE(data, base + 440),\n liqCursor: readU16LE(data, base + 456),\n gcCursor: readU16LE(data, base + 458),\n lastSweepStartSlot: readU64LE(data, base + 464),\n lastSweepCompleteSlot: readU64LE(data, base + 472),\n crankCursor: readU16LE(data, base + 480),\n sweepStartIdx: readU16LE(data, base + 482),\n lifetimeLiquidations: readU64LE(data, base + 488),\n lifetimeForceCloses: readU64LE(data, base + 496),\n netLpPos: readI128LE(data, base + 504),\n lpSumAbs: readU128LE(data, base + 520),\n lpMaxAbs: readU128LE(data, base + 536),\n lpMaxAbsSweep: readU128LE(data, base + 552),\n emergencyOiMode: false, // V2 has no emergency OI fields\n emergencyStartSlot: 0n,\n lastBreakerSlot: 0n,\n markPriceE6: 0n, // V2 has no mark_price\n numUsedAccounts: canReadNumUsed ? readU16LE(data, base + numUsedOff) : 0,\n nextAccountId: canReadNextId ? readU64LE(data, base + nextAccountIdOff) : 0n,\n };\n }\n\n // V_ADL engine struct (PERC-8270/8271): ENGINE_OFF=624, layout-driven offsets.\n // Must branch here because V_ADL has version===1 same as V1/V1M — differentiate by engineOff.\n // All offsets from SlabLayout descriptor, which is computed by buildLayoutVADL().\n const isVAdl = layout !== null && layout.engineOff === 624 && layout.accountSize === 312;\n if (isVAdl) {\n const l = layout!;\n return {\n vault: readU128LE(data, base + 0),\n insuranceFund: {\n balance: readU128LE(data, base + l.engineInsuranceOff),\n feeRevenue: readU128LE(data, base + l.engineInsuranceOff + 16),\n isolatedBalance: readU128LE(data, base + l.engineInsuranceIsolatedOff),\n isolationBps: readU16LE(data, base + l.engineInsuranceIsolationBpsOff),\n },\n currentSlot: readU64LE(data, base + l.engineCurrentSlotOff),\n fundingIndexQpbE6: readI128LE(data, base + l.engineFundingIndexOff),\n lastFundingSlot: readU64LE(data, base + l.engineLastFundingSlotOff),\n fundingRateBpsPerSlotLast: readI64LE(data, base + l.engineFundingRateBpsOff),\n lastCrankSlot: readU64LE(data, base + l.engineLastCrankSlotOff),\n maxCrankStalenessSlots: readU64LE(data, base + l.engineMaxCrankStalenessOff),\n totalOpenInterest: readU128LE(data, base + l.engineTotalOiOff),\n longOi: l.engineLongOiOff >= 0 ? readU128LE(data, base + l.engineLongOiOff) : 0n,\n shortOi: l.engineShortOiOff >= 0 ? readU128LE(data, base + l.engineShortOiOff) : 0n,\n cTot: readU128LE(data, base + l.engineCTotOff),\n pnlPosTot: readU128LE(data, base + l.enginePnlPosTotOff),\n liqCursor: readU16LE(data, base + l.engineLiqCursorOff),\n gcCursor: readU16LE(data, base + l.engineGcCursorOff),\n lastSweepStartSlot: readU64LE(data, base + l.engineLastSweepStartOff),\n lastSweepCompleteSlot: readU64LE(data, base + l.engineLastSweepCompleteOff),\n crankCursor: readU16LE(data, base + l.engineCrankCursorOff),\n sweepStartIdx: readU16LE(data, base + l.engineSweepStartIdxOff),\n lifetimeLiquidations: readU64LE(data, base + l.engineLifetimeLiquidationsOff),\n lifetimeForceCloses: readU64LE(data, base + l.engineLifetimeForceClosesOff),\n netLpPos: readI128LE(data, base + l.engineNetLpPosOff),\n lpSumAbs: readU128LE(data, base + l.engineLpSumAbsOff),\n lpMaxAbs: readU128LE(data, base + l.engineLpMaxAbsOff),\n lpMaxAbsSweep: readU128LE(data, base + l.engineLpMaxAbsSweepOff),\n emergencyOiMode: l.engineEmergencyOiModeOff >= 0 ? data[base + l.engineEmergencyOiModeOff] !== 0 : false,\n emergencyStartSlot: l.engineEmergencyStartSlotOff >= 0 ? readU64LE(data, base + l.engineEmergencyStartSlotOff) : 0n,\n lastBreakerSlot: l.engineLastBreakerSlotOff >= 0 ? readU64LE(data, base + l.engineLastBreakerSlotOff) : 0n,\n markPriceE6: l.engineMarkPriceOff >= 0 ? readU64LE(data, base + l.engineMarkPriceOff) : 0n,\n numUsedAccounts: canReadNumUsed ? readU16LE(data, base + numUsedOff) : 0,\n nextAccountId: canReadNextId ? readU64LE(data, base + nextAccountIdOff) : 0n,\n };\n }\n\n // V1 engine struct (PERC-1094 corrected): ENGINE_OFF=600 (BPF/SBF, CONFIG_LEN=496)\n // vault(0,16) + insurance(16,56) + params(72,288) + currentSlot(360) + fundingIndex(368,16)\n // + lastFundingSlot(384) + fundingRateBps(392) + markPrice(400) + lastCrankSlot(424)\n // + maxCrankStaleness(432) + totalOI(440,16) + longOi(456,16) + shortOi(472,16)\n // + cTot(488,16) + pnlPosTot(504,16) + liqCursor(520,2) + gcCursor(522,2)\n // + lastSweepStart(528) + lastSweepComplete(536) + crankCursor(544,2) + sweepStartIdx(546,2)\n // + lifetimeLiquidations(552) + lifetimeForceCloses(560)\n // + netLpPos(568,16) + lpSumAbs(584,16) + lpMaxAbs(600,16) + lpMaxAbsSweep(616,16)\n // + emergencyOiMode(632,1+7pad) + emergencyStartSlot(640) + lastBreakerSlot(648) + bitmap(656)\n return {\n vault: readU128LE(data, base + 0),\n insuranceFund: {\n balance: readU128LE(data, base + 16),\n feeRevenue: readU128LE(data, base + 32),\n isolatedBalance: readU128LE(data, base + 48),\n isolationBps: readU16LE(data, base + 64),\n },\n currentSlot: readU64LE(data, base + 360), // PERC-1094: params end at 72+288=360 (was 352)\n fundingIndexQpbE6: readI128LE(data, base + 368),\n lastFundingSlot: readU64LE(data, base + 384),\n fundingRateBpsPerSlotLast: readI64LE(data, base + 392),\n lastCrankSlot: readU64LE(data, base + 424),\n maxCrankStalenessSlots: readU64LE(data, base + 408),\n totalOpenInterest: readU128LE(data, base + 416),\n longOi: readU128LE(data, base + 432),\n shortOi: readU128LE(data, base + 448),\n cTot: readU128LE(data, base + 464),\n pnlPosTot: readU128LE(data, base + 480),\n liqCursor: readU16LE(data, base + 496),\n gcCursor: readU16LE(data, base + 498),\n lastSweepStartSlot: readU64LE(data, base + 504),\n lastSweepCompleteSlot: readU64LE(data, base + 512),\n crankCursor: readU16LE(data, base + 520),\n sweepStartIdx: readU16LE(data, base + 522),\n lifetimeLiquidations: readU64LE(data, base + 528),\n lifetimeForceCloses: readU64LE(data, base + 536),\n netLpPos: readI128LE(data, base + 544),\n lpSumAbs: readU128LE(data, base + 560),\n lpMaxAbs: readU128LE(data, base + 576),\n lpMaxAbsSweep: readU128LE(data, base + 592),\n emergencyOiMode: data[base + 608] !== 0,\n emergencyStartSlot: readU64LE(data, base + 616),\n lastBreakerSlot: readU64LE(data, base + 624),\n markPriceE6: readU64LE(data, base + 400), // PERC-1094: was 392\n numUsedAccounts: canReadNumUsed ? readU16LE(data, base + numUsedOff) : 0,\n nextAccountId: canReadNextId ? readU64LE(data, base + nextAccountIdOff) : 0n,\n };\n}\n\n/** Options for `discoverMarkets`. */\nexport interface DiscoverMarketsOptions {\n /**\n * Run tier queries sequentially with per-tier retry on HTTP 429 instead of\n * firing all in parallel. Reduces RPC rate-limit pressure at the cost of\n * slightly slower discovery (~14 round-trips instead of 1 concurrent batch).\n * Default: false (preserves original parallel behaviour).\n *\n * PERC-1650: keeper uses this flag to avoid 429 storms on its fallback RPC\n * (Helius starter tier). Pass `sequential: true` from CrankService.discover().\n */\n sequential?: boolean;\n /**\n * Delay in ms between sequential tier queries (only used when sequential=true).\n * Default: 200 ms.\n */\n interTierDelayMs?: number;\n /**\n * Per-tier retry backoff delays on 429 (ms). Jitter of up to +25% is applied.\n * Only used when sequential=true. Default: [1_000, 3_000, 9_000, 27_000].\n */\n rateLimitBackoffMs?: number[];\n\n /**\n * In parallel mode (the default), cap how many tier RPC requests are in-flight\n * at once to avoid accidental RPC storms from client code.\n *\n * Default: 6\n */\n maxParallelTiers?: number;\n\n /**\n * Hard cap on how many tier dataSize queries are attempted.\n * Default: all known tiers.\n */\n maxTierQueries?: number;\n}\n\n/** Return true if the error looks like an HTTP 429 / rate-limit response. */\nfunction isRateLimitError(err: unknown): boolean {\n if (!err) return false;\n const msg = err instanceof Error ? err.message : String(err);\n return (\n msg.includes(\"429\") ||\n msg.toLowerCase().includes(\"rate limit\") ||\n msg.toLowerCase().includes(\"too many requests\")\n );\n}\n\n/** Add up to 25% random jitter to avoid thundering-herd on retry. */\nfunction withJitter(delayMs: number): number {\n return delayMs + Math.floor(Math.random() * delayMs * 0.25);\n}\n\n/**\n * Discover all Percolator markets owned by the given program.\n * Uses getProgramAccounts with dataSize filter + dataSlice to download only ~1400 bytes per slab.\n *\n * @param options.sequential - Run tier queries sequentially with 429 retry (PERC-1650).\n */\nexport async function discoverMarkets(\n connection: Connection,\n programId: PublicKey,\n options: DiscoverMarketsOptions = {},\n): Promise<DiscoveredMarket[]> {\n const {\n sequential = false,\n interTierDelayMs = 200,\n rateLimitBackoffMs = [1_000, 3_000, 9_000, 27_000],\n maxParallelTiers = 6,\n } = options;\n\n // Query all known slab sizes in parallel — V0, V1D (deployed devnet), V1D legacy, and V1 (upgraded) tiers.\n // We track the actual dataSize per entry so detectSlabLayout can determine the correct layout,\n // and pass that layout to all parse functions (avoids wrong-version offsets on partial slices).\n // GH#1205: V1D tiers were missing here — V1D slabs fell through to memcmp fallback with wrong\n // dataSize hints → detectSlabLayout returned null → parse failure in discoverMarkets.\n // GH#1237/GH#1238: SLAB_TIERS_V1D_LEGACY (postBitmap=18, e.g. 65,104-byte slabs created before\n // GH#1234) must also be included; omitting them causes legacy on-chain slabs to be missed by\n // dataSize filter queries and fall through to memcmp with wrong maxAccounts hint.\n const ALL_TIERS = [\n ...Object.values(SLAB_TIERS),\n ...Object.values(SLAB_TIERS_V0),\n ...Object.values(SLAB_TIERS_V1D),\n ...Object.values(SLAB_TIERS_V1D_LEGACY),\n ...Object.values(SLAB_TIERS_V2),\n ...Object.values(SLAB_TIERS_V1M),\n ...Object.values(SLAB_TIERS_V_ADL),\n ];\n type RawEntry = { pubkey: PublicKey; account: { data: Buffer | Uint8Array }; maxAccounts: number; dataSize: number };\n let rawAccounts: RawEntry[] = [];\n\n /**\n * Fetch one tier with per-attempt 429 retry (sequential mode only).\n * Returns an array of RawEntry on success, or an empty array after exhausting retries.\n */\n async function fetchTierWithRetry(\n tier: { dataSize: number; maxAccounts: number },\n ): Promise<RawEntry[]> {\n for (let attempt = 0; attempt <= rateLimitBackoffMs.length; attempt++) {\n try {\n const results = await connection.getProgramAccounts(programId, {\n filters: [{ dataSize: tier.dataSize }],\n dataSlice: { offset: 0, length: HEADER_SLICE_LENGTH },\n });\n return results.map(entry => ({ ...entry, maxAccounts: tier.maxAccounts, dataSize: tier.dataSize }));\n } catch (err) {\n if (isRateLimitError(err) && attempt < rateLimitBackoffMs.length) {\n const delay = withJitter(rateLimitBackoffMs[attempt]);\n console.warn(\n `[discoverMarkets] 429 on tier dataSize=${tier.dataSize} attempt=${attempt + 1}, backing off ${delay}ms`,\n );\n await new Promise(r => setTimeout(r, delay));\n continue;\n }\n // Non-429 or exhausted retries\n console.warn(\n `[discoverMarkets] Tier query failed (dataSize=${tier.dataSize}, attempt=${attempt + 1}):`,\n err instanceof Error ? err.message : err,\n );\n return [];\n }\n }\n return [];\n }\n\n const maxTierQueries = options.maxTierQueries ?? ALL_TIERS.length;\n const tiersToQuery = ALL_TIERS.slice(0, maxTierQueries);\n\n // Avoid accidental `0`/negative or NaN causing infinite loops.\n const effectiveMaxParallelTiers = Math.max(1, Number.isFinite(maxParallelTiers) ? maxParallelTiers : 6);\n\n try {\n if (sequential) {\n // PERC-1650: sequential mode — one tier at a time with inter-tier spacing + per-tier 429 retry.\n for (let i = 0; i < tiersToQuery.length; i++) {\n const tier = tiersToQuery[i];\n const entries = await fetchTierWithRetry(tier);\n rawAccounts.push(...entries);\n if (i < tiersToQuery.length - 1) {\n await new Promise(r => setTimeout(r, interTierDelayMs));\n }\n }\n } else {\n // Parallel mode: cap tier concurrency so we don't fire 20+ large\n // getProgramAccounts calls at once from a single client call.\n for (let offset = 0; offset < tiersToQuery.length; offset += effectiveMaxParallelTiers) {\n const chunk = tiersToQuery.slice(offset, offset + effectiveMaxParallelTiers);\n const queries = chunk.map(tier =>\n connection.getProgramAccounts(programId, {\n filters: [{ dataSize: tier.dataSize }],\n dataSlice: { offset: 0, length: HEADER_SLICE_LENGTH },\n }).then(results =>\n results.map(entry => ({\n ...entry,\n maxAccounts: tier.maxAccounts,\n dataSize: tier.dataSize,\n })),\n ),\n );\n\n const results = await Promise.allSettled(queries);\n for (const result of results) {\n if (result.status === \"fulfilled\") {\n for (const entry of result.value) {\n rawAccounts.push(entry as RawEntry);\n }\n } else {\n console.warn(\n \"[discoverMarkets] Tier query rejected:\",\n result.reason instanceof Error ? result.reason.message : result.reason,\n );\n }\n }\n }\n }\n\n // NOTE: hadRejection guard removed — dataSize filters silently return 0 when on-chain\n // account size changed; RPC returns no error, so we must fallback on empty results too.\n if (rawAccounts.length === 0) {\n console.warn(\"[discoverMarkets] dataSize filters returned 0 markets, falling back to memcmp\");\n const fallback = await connection.getProgramAccounts(programId, {\n filters: [\n {\n memcmp: {\n offset: 0,\n bytes: \"F6P2QNqpQV5\", // base58 of TALOCREP (u64 LE magic)\n },\n },\n ],\n dataSlice: { offset: 0, length: HEADER_SLICE_LENGTH },\n });\n // Unknown actual size — use large V0 as safe default (maxAccounts=4096)\n rawAccounts = [...fallback].map(e => ({ ...e, maxAccounts: 4096, dataSize: SLAB_TIERS.large.dataSize })) as RawEntry[];\n }\n } catch (err) {\n console.warn(\n \"[discoverMarkets] dataSize filters failed, falling back to memcmp:\",\n err instanceof Error ? err.message : err,\n );\n const fallback = await connection.getProgramAccounts(programId, {\n filters: [\n {\n memcmp: {\n offset: 0,\n bytes: \"F6P2QNqpQV5\", // base58 of TALOCREP (u64 LE magic)\n },\n },\n ],\n dataSlice: { offset: 0, length: HEADER_SLICE_LENGTH },\n });\n rawAccounts = [...fallback].map(e => ({ ...e, maxAccounts: 4096, dataSize: SLAB_TIERS.large.dataSize })) as RawEntry[];\n }\n const accounts = rawAccounts;\n\n const markets: DiscoveredMarket[] = [];\n // GH#1115: deduplicate raw accounts by pubkey — the same slab can appear in multiple\n // tier queries if both V0 and V1 sizes match or if the RPC returns duplicate entries.\n const seenPubkeys = new Set<string>();\n\n for (const { pubkey, account, maxAccounts, dataSize } of accounts) {\n const pkStr = pubkey.toBase58();\n if (seenPubkeys.has(pkStr)) continue;\n seenPubkeys.add(pkStr);\n const data = new Uint8Array(account.data);\n\n let valid = true;\n for (let i = 0; i < MAGIC_BYTES.length; i++) {\n if (data[i] !== MAGIC_BYTES[i]) {\n valid = false;\n break;\n }\n }\n if (!valid) continue;\n\n // Detect layout from actual slab size — not slice length — so parse functions\n // get correct V0/V1 offsets even when working on the partial HEADER_SLICE_LENGTH slice.\n // Pass the data buffer so V2 slabs (same size as V1D) can be disambiguated via version field.\n const layout = detectSlabLayout(dataSize, data);\n\n if (!layout) {\n console.warn(\n `[discoverMarkets] Skipping account ${pkStr}: unrecognized layout for dataSize=${dataSize}`,\n );\n continue;\n }\n\n try {\n const header = parseHeader(data);\n const config = parseConfig(data, layout);\n const engine = parseEngineLight(data, layout, maxAccounts);\n const params = parseParams(data, layout);\n\n markets.push({ slabAddress: pubkey, programId, header, config, engine, params });\n } catch (err) {\n console.warn(\n `[discoverMarkets] Failed to parse account ${pubkey.toBase58()}:`,\n err instanceof Error ? err.message : err,\n );\n }\n }\n\n return markets;\n}\n","import { PublicKey } from \"@solana/web3.js\";\nimport {\n PUMPSWAP_PROGRAM_ID,\n RAYDIUM_CLMM_PROGRAM_ID,\n METEORA_DLMM_PROGRAM_ID,\n} from \"./pda.js\";\n\nexport type DexType = \"pumpswap\" | \"raydium-clmm\" | \"meteora-dlmm\";\n\nexport interface DexPoolInfo {\n dexType: DexType;\n poolAddress: PublicKey;\n baseMint: PublicKey;\n quoteMint: PublicKey;\n baseVault?: PublicKey; // PumpSwap only\n quoteVault?: PublicKey; // PumpSwap only\n}\n\n/**\n * Detect DEX type from the program that owns the pool account.\n *\n * @param ownerProgramId - The program ID that owns the pool account\n * @returns The detected DEX type, or `null` if the owner is not a supported DEX program\n *\n * Supported DEX programs:\n * - PumpSwap (constant-product AMM)\n * - Raydium CLMM (concentrated liquidity)\n * - Meteora DLMM (discretized liquidity)\n */\nexport function detectDexType(ownerProgramId: PublicKey): DexType | null {\n if (ownerProgramId.equals(PUMPSWAP_PROGRAM_ID)) return \"pumpswap\";\n if (ownerProgramId.equals(RAYDIUM_CLMM_PROGRAM_ID)) return \"raydium-clmm\";\n if (ownerProgramId.equals(METEORA_DLMM_PROGRAM_ID)) return \"meteora-dlmm\";\n return null;\n}\n\n/**\n * Parse a DEX pool account into a {@link DexPoolInfo} struct.\n *\n * @param dexType - The type of DEX (pumpswap, raydium-clmm, or meteora-dlmm)\n * @param poolAddress - The on-chain address of the pool account\n * @param data - Raw account data bytes\n * @returns Parsed pool info including mints and (for PumpSwap) vault addresses\n * @throws Error if data is too short for the given DEX type\n */\nexport function parseDexPool(\n dexType: DexType,\n poolAddress: PublicKey,\n data: Uint8Array,\n): DexPoolInfo {\n switch (dexType) {\n case \"pumpswap\":\n return parsePumpSwapPool(poolAddress, data);\n case \"raydium-clmm\":\n return parseRaydiumClmmPool(poolAddress, data);\n case \"meteora-dlmm\":\n return parseMeteoraPool(poolAddress, data);\n }\n}\n\n/**\n * Compute the spot price from a DEX pool in e6 format (i.e., 1.0 = 1_000_000).\n *\n * **SECURITY NOTE:** DEX spot prices have no staleness or confidence checks and are\n * vulnerable to flash-loan manipulation within a single transaction. For high-value\n * markets, prefer Pyth or Chainlink oracles.\n *\n * @param dexType - The type of DEX\n * @param data - Raw pool account data\n * @param vaultData - For PumpSwap only: base and quote vault account data\n * @returns Price in e6 format (quote per base token)\n * @throws Error if data is too short or computation fails\n */\nexport function computeDexSpotPriceE6(\n dexType: DexType,\n data: Uint8Array,\n vaultData?: { base: Uint8Array; quote: Uint8Array },\n): bigint {\n switch (dexType) {\n case \"pumpswap\":\n if (!vaultData) throw new Error(\"PumpSwap requires vaultData (base and quote vault accounts)\");\n return computePumpSwapPriceE6(data, vaultData);\n case \"raydium-clmm\":\n return computeRaydiumClmmPriceE6(data);\n case \"meteora-dlmm\":\n return computeMeteoraDlmmPriceE6(data);\n }\n}\n\n// ============================================================================\n// PumpSwap\n// ============================================================================\n\nconst PUMPSWAP_MIN_LEN = 195;\n\n/**\n * Parse a PumpSwap constant-product AMM pool account.\n * @internal\n */\nfunction parsePumpSwapPool(poolAddress: PublicKey, data: Uint8Array): DexPoolInfo {\n if (data.length < PUMPSWAP_MIN_LEN) {\n throw new Error(`PumpSwap pool data too short: ${data.length} < ${PUMPSWAP_MIN_LEN}`);\n }\n return {\n dexType: \"pumpswap\",\n poolAddress,\n baseMint: new PublicKey(data.slice(35, 67)),\n quoteMint: new PublicKey(data.slice(67, 99)),\n baseVault: new PublicKey(data.slice(131, 163)),\n quoteVault: new PublicKey(data.slice(163, 195)),\n };\n}\n\nconst SPL_TOKEN_AMOUNT_MIN_LEN = 72;\n\n/**\n * Compute PumpSwap price: quote_amount * 1e6 / base_amount.\n * @internal\n */\nfunction computePumpSwapPriceE6(\n _poolData: Uint8Array,\n vaultData: { base: Uint8Array; quote: Uint8Array },\n): bigint {\n if (vaultData.base.length < SPL_TOKEN_AMOUNT_MIN_LEN) {\n throw new Error(`PumpSwap base vault data too short: ${vaultData.base.length} < ${SPL_TOKEN_AMOUNT_MIN_LEN}`);\n }\n if (vaultData.quote.length < SPL_TOKEN_AMOUNT_MIN_LEN) {\n throw new Error(`PumpSwap quote vault data too short: ${vaultData.quote.length} < ${SPL_TOKEN_AMOUNT_MIN_LEN}`);\n }\n\n const baseDv = new DataView(vaultData.base.buffer, vaultData.base.byteOffset, vaultData.base.byteLength);\n const quoteDv = new DataView(vaultData.quote.buffer, vaultData.quote.byteOffset, vaultData.quote.byteLength);\n\n const baseAmount = readU64LE(baseDv, 64);\n const quoteAmount = readU64LE(quoteDv, 64);\n\n if (baseAmount === 0n) return 0n;\n return (quoteAmount * 1_000_000n) / baseAmount;\n}\n\n// ============================================================================\n// Raydium CLMM\n// ============================================================================\n\nconst RAYDIUM_CLMM_MIN_LEN = 269; // need at least through sqrt_price_x64 (253 + 16)\n\n/**\n * Parse a Raydium CLMM (concentrated liquidity) pool account.\n * @internal\n */\nfunction parseRaydiumClmmPool(poolAddress: PublicKey, data: Uint8Array): DexPoolInfo {\n if (data.length < RAYDIUM_CLMM_MIN_LEN) {\n throw new Error(`Raydium CLMM pool data too short: ${data.length} < ${RAYDIUM_CLMM_MIN_LEN}`);\n }\n return {\n dexType: \"raydium-clmm\",\n poolAddress,\n baseMint: new PublicKey(data.slice(73, 105)),\n quoteMint: new PublicKey(data.slice(105, 137)),\n };\n}\n\n/**\n * Compute Raydium CLMM spot price from sqrt_price_x64 (Q64.64 fixed-point).\n *\n * Formula: `price_e6 = (sqrt^2 / 2^128) * 10^(6 + decimals0 - decimals1)`\n *\n * Uses a precision-preserving approach: scales sqrt by 1e6 before shifting,\n * preventing zero results for micro-priced tokens (memecoins where sqrt < 2^64).\n *\n * @internal\n */\nconst MAX_TOKEN_DECIMALS = 24;\n\nfunction computeRaydiumClmmPriceE6(data: Uint8Array): bigint {\n if (data.length < RAYDIUM_CLMM_MIN_LEN) {\n throw new Error(`Raydium CLMM data too short: ${data.length} < ${RAYDIUM_CLMM_MIN_LEN}`);\n }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n const decimals0 = data[233];\n const decimals1 = data[234];\n\n if (decimals0 > MAX_TOKEN_DECIMALS || decimals1 > MAX_TOKEN_DECIMALS) {\n throw new Error(\n `Raydium CLMM: decimals out of range (${decimals0}, ${decimals1}); max ${MAX_TOKEN_DECIMALS}`,\n );\n }\n\n const sqrtPriceX64 = readU128LE(dv, 253);\n\n if (sqrtPriceX64 === 0n) return 0n;\n\n const scaledSqrt = sqrtPriceX64 * 1_000_000n;\n const term = scaledSqrt >> 64n;\n const priceE6Raw = (term * sqrtPriceX64) >> 64n;\n\n const decimalDiff = 6 + decimals0 - decimals1;\n const adjustedDiff = decimalDiff - 6;\n\n if (adjustedDiff >= 0) {\n const scale = 10n ** BigInt(adjustedDiff);\n return priceE6Raw * scale;\n } else {\n const scale = 10n ** BigInt(-adjustedDiff);\n return priceE6Raw / scale;\n }\n}\n\n// ============================================================================\n// Meteora DLMM\n// ============================================================================\n\nconst METEORA_DLMM_MIN_LEN = 145;\n\n/**\n * Parse a Meteora DLMM (discretized liquidity) pool account.\n * @internal\n */\nfunction parseMeteoraPool(poolAddress: PublicKey, data: Uint8Array): DexPoolInfo {\n if (data.length < METEORA_DLMM_MIN_LEN) {\n throw new Error(`Meteora DLMM pool data too short: ${data.length} < ${METEORA_DLMM_MIN_LEN}`);\n }\n return {\n dexType: \"meteora-dlmm\",\n poolAddress,\n baseMint: new PublicKey(data.slice(81, 113)),\n quoteMint: new PublicKey(data.slice(113, 145)),\n };\n}\n\n/**\n * Compute Meteora DLMM spot price from active_id and bin_step.\n *\n * Formula: `price = (1 + bin_step/10000) ^ active_id`\n *\n * Uses binary exponentiation with 1e18 fixed-point precision, then converts to e6.\n * For negative active_id, computes the inverse.\n *\n * @internal\n */\nconst MAX_BIN_STEP = 10_000;\nconst MAX_ACTIVE_ID_ABS = 500_000;\n\nfunction computeMeteoraDlmmPriceE6(data: Uint8Array): bigint {\n if (data.length < METEORA_DLMM_MIN_LEN) {\n throw new Error(`Meteora DLMM data too short: ${data.length} < ${METEORA_DLMM_MIN_LEN}`);\n }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n const binStep = dv.getUint16(73, true);\n const activeId = dv.getInt32(76, true);\n\n if (binStep === 0) return 0n;\n if (binStep > MAX_BIN_STEP) {\n throw new Error(`Meteora DLMM: binStep ${binStep} exceeds max ${MAX_BIN_STEP}`);\n }\n if (Math.abs(activeId) > MAX_ACTIVE_ID_ABS) {\n throw new Error(\n `Meteora DLMM: |activeId| ${Math.abs(activeId)} exceeds max ${MAX_ACTIVE_ID_ABS}`,\n );\n }\n\n const MAX_ABS_BIN_ID = 500_000;\n if (activeId > MAX_ABS_BIN_ID || activeId < -MAX_ABS_BIN_ID) {\n throw new Error(\n `Meteora DLMM: activeId ${activeId} exceeds safe range (±${MAX_ABS_BIN_ID})`,\n );\n }\n\n const SCALE = 1_000_000_000_000_000_000n; // 1e18\n const base = SCALE + (BigInt(binStep) * SCALE) / 10_000n;\n\n const isNeg = activeId < 0;\n let exp = isNeg ? BigInt(-activeId) : BigInt(activeId);\n\n let result = SCALE;\n let b = base;\n\n while (exp > 0n) {\n if (exp & 1n) {\n result = (result * b) / SCALE;\n }\n exp >>= 1n;\n if (exp > 0n) {\n b = (b * b) / SCALE;\n }\n }\n\n if (isNeg) {\n if (result === 0n) return 0n;\n return (SCALE * 1_000_000n) / result;\n } else {\n return result / 1_000_000_000_000n; // 1e18 → 1e6\n }\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/** Read a little-endian u64 from a DataView. */\nfunction readU64LE(dv: DataView, offset: number): bigint {\n const lo = BigInt(dv.getUint32(offset, true));\n const hi = BigInt(dv.getUint32(offset + 4, true));\n return lo | (hi << 32n);\n}\n\n/** Read a little-endian u128 from a DataView. */\nfunction readU128LE(dv: DataView, offset: number): bigint {\n const lo = readU64LE(dv, offset);\n const hi = readU64LE(dv, offset + 8);\n return lo | (hi << 64n);\n}\n","/**\n * Oracle account parsing utilities.\n *\n * Chainlink aggregator layout on Solana (from Toly's percolator-cli):\n * offset 138: decimals (u8)\n * offset 216: latest answer (i64 LE)\n *\n * Minimum account size: 224 bytes (offset 216 + 8 bytes for i64).\n *\n * These utilities validate oracle data BEFORE parsing to prevent silent\n * propagation of stale or malformed Chainlink data as price.\n */\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Minimum buffer size to read Chainlink price data */\nconst CHAINLINK_MIN_SIZE = 224; // 216 + 8\n\n/** Maximum reasonable decimals for a price feed */\nconst MAX_DECIMALS = 18;\n\n/** Offset of decimals field in Chainlink aggregator account */\nconst CHAINLINK_DECIMALS_OFFSET = 138;\n\n/** Offset of latest answer in Chainlink aggregator account */\nconst CHAINLINK_ANSWER_OFFSET = 216;\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface OraclePrice {\n price: bigint;\n decimals: number;\n}\n\n// ---------------------------------------------------------------------------\n// Browser-compatible read helpers using DataView\n// ---------------------------------------------------------------------------\n\nfunction readU8(data: Uint8Array, off: number): number {\n return data[off];\n}\n\nfunction readBigInt64LE(data: Uint8Array, off: number): bigint {\n return new DataView(data.buffer, data.byteOffset, data.byteLength).getBigInt64(off, true);\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Parse price data from a Chainlink aggregator account buffer.\n *\n * Validates:\n * - Buffer is large enough to contain the required fields (≥ 224 bytes)\n * - Decimals are in a reasonable range (0-18)\n * - Price is positive (non-zero)\n *\n * @param data - Raw account data from Chainlink aggregator\n * @returns Parsed oracle price with decimals\n * @throws if the buffer is invalid or contains unreasonable data\n */\nexport function parseChainlinkPrice(data: Uint8Array): OraclePrice {\n if (data.length < CHAINLINK_MIN_SIZE) {\n throw new Error(\n `Oracle account data too small: ${data.length} bytes (need at least ${CHAINLINK_MIN_SIZE})`\n );\n }\n\n const decimals = readU8(data, CHAINLINK_DECIMALS_OFFSET);\n if (decimals > MAX_DECIMALS) {\n throw new Error(\n `Oracle decimals out of range: ${decimals} (max ${MAX_DECIMALS})`\n );\n }\n\n const price = readBigInt64LE(data, CHAINLINK_ANSWER_OFFSET);\n if (price <= 0n) {\n throw new Error(\n `Oracle price is non-positive: ${price}`\n );\n }\n\n return { price, decimals };\n}\n\n/**\n * Validate that a buffer looks like a valid Chainlink aggregator account.\n * Returns true if the buffer passes all validation checks, false otherwise.\n * Use this for non-throwing validation.\n */\nexport function isValidChainlinkOracle(data: Uint8Array): boolean {\n try {\n parseChainlinkPrice(data);\n return true;\n } catch {\n return false;\n }\n}\n\n// Re-export constants for consumers\nexport { CHAINLINK_MIN_SIZE, CHAINLINK_DECIMALS_OFFSET, CHAINLINK_ANSWER_OFFSET, MAX_DECIMALS };\n","import { Connection, PublicKey } from \"@solana/web3.js\";\nimport { TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\n\n/**\n * Token2022 (Token Extensions) program ID.\n */\nexport const TOKEN_2022_PROGRAM_ID = new PublicKey(\n \"TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb\",\n);\n\n/**\n * Detect which token program owns a given mint account.\n * Returns the owner program ID (TOKEN_PROGRAM_ID or TOKEN_2022_PROGRAM_ID).\n * Throws if the mint account doesn't exist.\n */\nexport async function detectTokenProgram(\n connection: Connection,\n mint: PublicKey,\n): Promise<PublicKey> {\n const info = await connection.getAccountInfo(mint);\n if (!info) throw new Error(`Mint account not found: ${mint.toBase58()}`);\n return info.owner;\n}\n\n/**\n * Check if a given token program ID is Token2022.\n */\nexport function isToken2022(tokenProgramId: PublicKey): boolean {\n return tokenProgramId.equals(TOKEN_2022_PROGRAM_ID);\n}\n\n/**\n * Check if a given token program ID is the standard SPL Token program.\n */\nexport function isStandardToken(tokenProgramId: PublicKey): boolean {\n return tokenProgramId.equals(TOKEN_PROGRAM_ID);\n}\n","/**\n * @module stake\n * Percolator Insurance LP Staking program — instruction encoders, PDA derivation, and account specs.\n *\n * Program: percolator-stake (dcccrypto/percolator-stake)\n * Deployed devnet: 6aJb1F9CDCVWCNYFwj8aQsVb696YnW6J1FznteHq4Q6k\n * Deployed mainnet: (pending deployment — DevOps must set STAKE_PROGRAM_ID env var or deploy and update STAKE_PROGRAM_IDS.mainnet)\n */\n\nimport { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY, SYSVAR_CLOCK_PUBKEY } from '@solana/web3.js';\nimport { TOKEN_PROGRAM_ID } from '@solana/spl-token';\nimport { safeEnv } from '../config/program-ids.js';\nimport { concatBytes } from '../abi/encode.js';// ═══════════════════════════════════════════════════════════════\n// Program ID — network-conditional (mirrors program-ids.ts pattern)\n// ═══════════════════════════════════════════════════════════════\n\n/** Known stake program addresses per network. Mainnet is empty until deployed. */\nexport const STAKE_PROGRAM_IDS = {\n devnet: '6aJb1F9CDCVWCNYFwj8aQsVb696YnW6J1FznteHq4Q6k',\n mainnet: '', // TODO: populate once DevOps deploys percolator-stake to mainnet\n} as const;\n\n/**\n * Resolve the stake program ID for the given network.\n *\n * Priority:\n * 1. STAKE_PROGRAM_ID env var (explicit override — DevOps sets this for mainnet until constant is filled)\n * 2. Network-specific constant from STAKE_PROGRAM_IDS\n *\n * Throws a clear error on mainnet when no address is available so callers\n * surface the gap instead of silently hitting the devnet program.\n */\nexport function getStakeProgramId(network?: 'devnet' | 'mainnet'): PublicKey {\n const override = safeEnv('STAKE_PROGRAM_ID');\n if (override) {\n console.warn(\n `[percolator-sdk] STAKE_PROGRAM_ID env override active: ${override} — ensure this points to a trusted program`,\n );\n return new PublicKey(override);\n }\n\n const detectedNetwork =\n network ??\n (() => {\n const n = safeEnv('NEXT_PUBLIC_DEFAULT_NETWORK')?.toLowerCase() ??\n safeEnv('NETWORK')?.toLowerCase() ?? '';\n return n === 'mainnet' || n === 'mainnet-beta' ? 'mainnet' : 'devnet';\n })();\n\n const id = STAKE_PROGRAM_IDS[detectedNetwork];\n if (!id) {\n throw new Error(\n `Stake program not deployed on ${detectedNetwork}. ` +\n `Set STAKE_PROGRAM_ID env var or wait for DevOps to deploy and update STAKE_PROGRAM_IDS.mainnet.`,\n );\n }\n return new PublicKey(id);\n}\n\n/**\n * Default export — resolves for the current runtime network.\n * Use getStakeProgramId() with an explicit network argument where possible.\n *\n * @deprecated Direct use of STAKE_PROGRAM_ID is being phased out in favour of\n * getStakeProgramId() so mainnet callers get a clear error rather than silently\n * resolving to the devnet address.\n */\nexport const STAKE_PROGRAM_ID = new PublicKey(STAKE_PROGRAM_IDS.devnet);\n\n// ═══════════════════════════════════════════════════════════════\n// Instruction Tags (match src/instruction.rs)\n// ═══════════════════════════════════════════════════════════════\n\nexport const STAKE_IX = {\n InitPool: 0,\n Deposit: 1,\n Withdraw: 2,\n FlushToInsurance: 3,\n UpdateConfig: 4,\n TransferAdmin: 5,\n AdminSetOracleAuthority: 6,\n AdminSetRiskThreshold: 7,\n AdminSetMaintenanceFee: 8,\n AdminResolveMarket: 9,\n AdminWithdrawInsurance: 10,\n AdminSetInsurancePolicy: 11,\n /** PERC-272: Accrue trading fees to LP vault */\n AccrueFees: 12,\n /** PERC-272: Init pool in trading LP mode */\n InitTradingPool: 13,\n /** PERC-313: Set HWM config (enable + floor bps) */\n AdminSetHwmConfig: 14,\n /** PERC-303: Enable/configure senior-junior LP tranches */\n AdminSetTrancheConfig: 15,\n /** PERC-303: Deposit into junior (first-loss) tranche */\n DepositJunior: 16,\n} as const;\n\n// ═══════════════════════════════════════════════════════════════\n// PDA Derivation\n// ═══════════════════════════════════════════════════════════════\n\nconst TEXT = new TextEncoder();\n\n/** Derive the stake pool PDA for a given slab (market). */\nexport function deriveStakePool(slab: PublicKey, programId?: PublicKey) {\n return PublicKey.findProgramAddressSync(\n [TEXT.encode('stake_pool'), slab.toBytes()], programId ?? getStakeProgramId(), );\n}\n\n/** Derive the vault authority PDA (signs CPI, owns LP mint + vault). */\nexport function deriveStakeVaultAuth(pool: PublicKey, programId?: PublicKey) {\n return PublicKey.findProgramAddressSync(\n [TEXT.encode('vault_auth'), pool.toBytes()], programId ?? getStakeProgramId(), );\n}\n\n/** Derive the per-user deposit PDA (tracks cooldown, deposit time). */\nexport function deriveDepositPda(pool: PublicKey, user: PublicKey, programId?: PublicKey) {\n return PublicKey.findProgramAddressSync(\n [TEXT.encode('deposit'), pool.toBytes(), user.toBytes()], programId ?? getStakeProgramId(), );\n}\n\n// ═══════════════════════════════════════════════════════════════\n// Browser-safe binary helpers (DataView, no Node.js Buffer dependency)// ═══════════════════════════════════════════════════════════════\n\n/** Read a u64 little-endian from a Uint8Array at the given offset. */\nfunction readU64LE(data: Uint8Array, off: number): bigint {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n return view.getBigUint64(off, /* littleEndian= */ true);\n}\n\n/** Read a u16 little-endian from a Uint8Array at the given offset. */\nfunction readU16LE(data: Uint8Array, off: number): number {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n return view.getUint16(off, /* littleEndian= */ true);\n}\n\n// ═══════════════════════════════════════════════════════════════\n// Instruction Encoders\n// ═══════════════════════════════════════════════════════════════\n\nfunction u64Le(v: bigint | number): Uint8Array {\n const big = BigInt(v);\n if (big < 0n) throw new Error(`u64Le: value must be non-negative, got ${big}`);\n if (big > 0xFFFF_FFFF_FFFF_FFFFn) throw new Error(`u64Le: value exceeds u64 max`);\n const arr = new Uint8Array(8);\n new DataView(arr.buffer).setBigUint64(0, big, true); return arr;\n}\n\nfunction u128Le(v: bigint | number): Uint8Array {\n const big = BigInt(v);\n if (big < 0n) throw new Error(`u128Le: value must be non-negative, got ${big}`);\n if (big > (1n << 128n) - 1n) throw new Error(`u128Le: value exceeds u128 max`);\n const arr = new Uint8Array(16);\n const view = new DataView(arr.buffer); view.setBigUint64(0, big & 0xFFFFFFFFFFFFFFFFn, true);\n view.setBigUint64(8, big >> 64n, true);\n return arr;\n}\n\nfunction u16Le(v: number): Uint8Array {\n if (v < 0 || v > 0xFFFF) throw new Error(`u16Le: value out of u16 range (0..65535), got ${v}`); const arr = new Uint8Array(2); new DataView(arr.buffer).setUint16(0, v, true);\n return arr;\n}\n\n/** Tag 0: InitPool — create stake pool for a slab. */\nexport function encodeStakeInitPool(cooldownSlots: bigint | number, depositCap: bigint | number): Uint8Array {\n return concatBytes(\n new Uint8Array([STAKE_IX.InitPool]),\n u64Le(cooldownSlots),\n u64Le(depositCap),\n );\n}\n\n/** Tag 1: Deposit — deposit collateral, receive LP tokens. */\nexport function encodeStakeDeposit(amount: bigint | number): Uint8Array {\n return concatBytes(new Uint8Array([STAKE_IX.Deposit]), u64Le(amount));\n}\n\n/** Tag 2: Withdraw — burn LP tokens, receive collateral (subject to cooldown). */\nexport function encodeStakeWithdraw(lpAmount: bigint | number): Uint8Array {\n return concatBytes(new Uint8Array([STAKE_IX.Withdraw]), u64Le(lpAmount));\n}\n\n/** Tag 3: FlushToInsurance — move collateral from stake vault to wrapper insurance. */\nexport function encodeStakeFlushToInsurance(amount: bigint | number): Uint8Array {\n return concatBytes(new Uint8Array([STAKE_IX.FlushToInsurance]), u64Le(amount));\n}\n\n/** Tag 4: UpdateConfig — update cooldown and/or deposit cap. */\nexport function encodeStakeUpdateConfig(\n newCooldownSlots?: bigint | number,\n newDepositCap?: bigint | number,\n): Uint8Array {\n return concatBytes(\n new Uint8Array([STAKE_IX.UpdateConfig]),\n new Uint8Array([newCooldownSlots != null ? 1 : 0]),\n u64Le(newCooldownSlots ?? 0n),\n new Uint8Array([newDepositCap != null ? 1 : 0]),\n u64Le(newDepositCap ?? 0n),\n );\n}\n\n/** Tag 5: TransferAdmin — transfer wrapper admin to pool PDA. */\nexport function encodeStakeTransferAdmin(): Uint8Array {\n return new Uint8Array([STAKE_IX.TransferAdmin]);\n}\n\n/** Tag 6: AdminSetOracleAuthority — forward to wrapper via CPI. */\nexport function encodeStakeAdminSetOracleAuthority(newAuthority: PublicKey): Uint8Array {\n return concatBytes(\n new Uint8Array([STAKE_IX.AdminSetOracleAuthority]),\n newAuthority.toBytes(),\n );\n}\n\n/** Tag 7: AdminSetRiskThreshold — forward to wrapper via CPI. */\nexport function encodeStakeAdminSetRiskThreshold(newThreshold: bigint | number): Uint8Array {\n return concatBytes(\n new Uint8Array([STAKE_IX.AdminSetRiskThreshold]),\n u128Le(newThreshold),\n );\n}\n\n/** Tag 8: AdminSetMaintenanceFee — forward to wrapper via CPI. */\nexport function encodeStakeAdminSetMaintenanceFee(newFee: bigint | number): Uint8Array {\n return concatBytes(\n new Uint8Array([STAKE_IX.AdminSetMaintenanceFee]),\n u128Le(newFee),\n );\n}\n\n/** Tag 9: AdminResolveMarket — forward to wrapper via CPI. */\nexport function encodeStakeAdminResolveMarket(): Uint8Array {\n return new Uint8Array([STAKE_IX.AdminResolveMarket]);\n}\n\n/** Tag 10: AdminWithdrawInsurance — withdraw insurance after market resolution. */\nexport function encodeStakeAdminWithdrawInsurance(amount: bigint | number): Uint8Array {\n return concatBytes(\n new Uint8Array([STAKE_IX.AdminWithdrawInsurance]),\n u64Le(amount),\n );\n}\n\n/** Tag 12: AccrueFees — permissionless: accrue trading fees to LP vault. */\nexport function encodeStakeAccrueFees(): Uint8Array {\n return new Uint8Array([STAKE_IX.AccrueFees]);\n}\n\n/** Tag 13: InitTradingPool — create pool in trading LP mode (pool_mode = 1). */\nexport function encodeStakeInitTradingPool(cooldownSlots: bigint | number, depositCap: bigint | number): Uint8Array {\n return concatBytes(\n new Uint8Array([STAKE_IX.InitTradingPool]),\n u64Le(cooldownSlots),\n u64Le(depositCap),\n );\n}\n\n/** Tag 14 (PERC-313): AdminSetHwmConfig — enable HWM protection and set floor BPS. */\nexport function encodeStakeAdminSetHwmConfig(\n enabled: boolean,\n hwmFloorBps: number,\n): Uint8Array {\n return concatBytes(\n new Uint8Array([STAKE_IX.AdminSetHwmConfig]),\n new Uint8Array([enabled ? 1 : 0]),\n u16Le(hwmFloorBps),\n );\n}\n\n/** Tag 15 (PERC-303): AdminSetTrancheConfig — enable senior/junior LP tranches. */\nexport function encodeStakeAdminSetTrancheConfig(juniorFeeMultBps: number): Uint8Array {\n return concatBytes(\n new Uint8Array([STAKE_IX.AdminSetTrancheConfig]),\n u16Le(juniorFeeMultBps),\n );\n}\n\n/** Tag 16 (PERC-303): DepositJunior — deposit into first-loss junior tranche. */\nexport function encodeStakeDepositJunior(amount: bigint | number): Uint8Array {\n return concatBytes(new Uint8Array([STAKE_IX.DepositJunior]), u64Le(amount));\n}\n\n/** Tag 11: AdminSetInsurancePolicy — set withdrawal policy on wrapper. */\nexport function encodeStakeAdminSetInsurancePolicy(\n authority: PublicKey,\n minWithdrawBase: bigint | number,\n maxWithdrawBps: number,\n cooldownSlots: bigint | number,\n): Uint8Array {\n return concatBytes(\n new Uint8Array([STAKE_IX.AdminSetInsurancePolicy]),\n authority.toBytes(),\n u64Le(minWithdrawBase),\n u16Le(maxWithdrawBps),\n u64Le(cooldownSlots),\n );\n}\n\n// ═══════════════════════════════════════════════════════════════\n// On-Chain State Layout — StakePool decoded fields\n// ═══════════════════════════════════════════════════════════════\n\n/**\n * Decoded StakePool state (352 bytes on-chain).\n * Includes PERC-272 (fee yield), PERC-313 (HWM), and PERC-303 (tranches).\n */\nexport interface StakePoolState {\n isInitialized: boolean;\n bump: number;\n vaultAuthorityBump: number;\n adminTransferred: boolean;\n\n slab: PublicKey;\n admin: PublicKey;\n collateralMint: PublicKey;\n lpMint: PublicKey;\n vault: PublicKey;\n\n totalDeposited: bigint;\n totalLpSupply: bigint;\n cooldownSlots: bigint;\n depositCap: bigint;\n totalFlushed: bigint;\n totalReturned: bigint;\n totalWithdrawn: bigint;\n\n percolatorProgram: PublicKey;\n\n // PERC-272: Fee yield fields\n totalFeesEarned: bigint;\n lastFeeAccrualSlot: bigint;\n lastVaultSnapshot: bigint;\n poolMode: number;\n\n // _reserved layout (64 bytes):\n // [0..8] discriminator\n // [8] version\n // [9..32] PERC-313 HWM\n // [32..51] PERC-303 tranches\n // [51..64] free\n\n // PERC-313: HWM fields (from _reserved[9..32])\n hwmEnabled: boolean;\n epochHighWaterTvl: bigint;\n hwmFloorBps: number;\n\n // PERC-303: Tranche fields (from _reserved[32..51])\n trancheEnabled: boolean;\n juniorBalance: bigint;\n juniorTotalLp: bigint;\n juniorFeeMultBps: number;\n}\n\n/** Size of StakePool on-chain (bytes). */\nexport const STAKE_POOL_SIZE = 352;\n\n/**\n * Decode a StakePool account from raw data buffer. * Uses DataView for all u64/u16 reads — browser-safe.\n */\nexport function decodeStakePool(data: Uint8Array): StakePoolState {\n if (data.length < STAKE_POOL_SIZE) {\n throw new Error(`StakePool data too short: ${data.length} < ${STAKE_POOL_SIZE}`);\n }\n const bytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength); let off = 0;\n const isInitialized = bytes[off] === 1; off += 1;\n const bump = bytes[off]; off += 1;\n const vaultAuthorityBump = bytes[off]; off += 1;\n const adminTransferred = bytes[off] === 1; off += 1;\n off += 4; // _padding\n\n const slab = new PublicKey(bytes.subarray(off, off + 32)); off += 32;\n const admin = new PublicKey(bytes.subarray(off, off + 32)); off += 32;\n const collateralMint = new PublicKey(bytes.subarray(off, off + 32)); off += 32;\n const lpMint = new PublicKey(bytes.subarray(off, off + 32)); off += 32;\n const vault = new PublicKey(bytes.subarray(off, off + 32)); off += 32;\n\n const totalDeposited = readU64LE(bytes, off); off += 8;\n const totalLpSupply = readU64LE(bytes, off); off += 8;\n const cooldownSlots = readU64LE(bytes, off); off += 8;\n const depositCap = readU64LE(bytes, off); off += 8;\n const totalFlushed = readU64LE(bytes, off); off += 8;\n const totalReturned = readU64LE(bytes, off); off += 8;\n const totalWithdrawn = readU64LE(bytes, off); off += 8;\n\n const percolatorProgram = new PublicKey(bytes.subarray(off, off + 32)); off += 32;\n\n // PERC-272 fields\n const totalFeesEarned = readU64LE(bytes, off); off += 8;\n const lastFeeAccrualSlot = readU64LE(bytes, off); off += 8;\n const lastVaultSnapshot = readU64LE(bytes, off); off += 8;\n const poolMode = bytes[off]; off += 1;\n off += 7; // _mode_padding\n\n // _reserved (64 bytes) starts at off\n const reservedStart = off;\n // _reserved[8] = version (skipped)\n // PERC-313: _reserved[9] = hwm_enabled, [10..26] = epoch_high_water_tvl (u128), [26..28] = hwm_floor_bps (u16)\n const hwmEnabled = bytes[reservedStart + 9] === 1;\n // Read u128 as two u64 parts\n const hwmTvlLow = readU64LE(bytes, reservedStart + 10);\n const hwmTvlHigh = readU64LE(bytes, reservedStart + 18);\n const epochHighWaterTvl = hwmTvlLow | (hwmTvlHigh << 64n);\n const hwmFloorBps = readU16LE(bytes, reservedStart + 26);\n\n // PERC-303: _reserved[32] = tranche_enabled, [33..41] = junior_balance, [41..49] = junior_total_lp, [49..51] = junior_fee_mult_bps\n const trancheEnabled = bytes[reservedStart + 32] === 1;\n const juniorBalance = readU64LE(bytes, reservedStart + 33);\n const juniorTotalLp = readU64LE(bytes, reservedStart + 41);\n const juniorFeeMultBps = readU16LE(bytes, reservedStart + 49);\n\n return {\n isInitialized,\n bump,\n vaultAuthorityBump,\n adminTransferred,\n slab,\n admin,\n collateralMint,\n lpMint,\n vault,\n totalDeposited,\n totalLpSupply,\n cooldownSlots,\n depositCap,\n totalFlushed,\n totalReturned,\n totalWithdrawn,\n percolatorProgram,\n totalFeesEarned,\n lastFeeAccrualSlot,\n lastVaultSnapshot,\n poolMode,\n hwmEnabled,\n epochHighWaterTvl,\n hwmFloorBps,\n trancheEnabled,\n juniorBalance,\n juniorTotalLp,\n juniorFeeMultBps,\n };\n}\n\n// ═══════════════════════════════════════════════════════════════\n// Account Specs (for building TransactionInstructions)\n// ═══════════════════════════════════════════════════════════════\n\nexport interface StakeAccounts {\n /** InitPool accounts */\n initPool: {\n admin: PublicKey;\n slab: PublicKey;\n pool: PublicKey;\n lpMint: PublicKey;\n vault: PublicKey;\n vaultAuth: PublicKey;\n collateralMint: PublicKey;\n percolatorProgram: PublicKey;\n };\n /** Deposit accounts */\n deposit: {\n user: PublicKey;\n pool: PublicKey;\n userCollateralAta: PublicKey;\n vault: PublicKey;\n lpMint: PublicKey;\n userLpAta: PublicKey;\n vaultAuth: PublicKey;\n depositPda: PublicKey;\n };\n /** Withdraw accounts */\n withdraw: {\n user: PublicKey;\n pool: PublicKey;\n userLpAta: PublicKey;\n lpMint: PublicKey;\n vault: PublicKey;\n userCollateralAta: PublicKey;\n vaultAuth: PublicKey;\n depositPda: PublicKey;\n };\n /** FlushToInsurance accounts (CPI from stake → percolator) */\n flushToInsurance: {\n caller: PublicKey;\n pool: PublicKey;\n vault: PublicKey;\n vaultAuth: PublicKey;\n slab: PublicKey;\n wrapperVault: PublicKey;\n percolatorProgram: PublicKey;\n };\n}\n\n/**\n * Build account keys for InitPool instruction.\n * Returns array of {pubkey, isSigner, isWritable} in the order the program expects.\n */\nexport function initPoolAccounts(a: StakeAccounts['initPool']) {\n return [\n { pubkey: a.admin, isSigner: true, isWritable: true },\n { pubkey: a.slab, isSigner: false, isWritable: false },\n { pubkey: a.pool, isSigner: false, isWritable: true },\n { pubkey: a.lpMint, isSigner: false, isWritable: true },\n { pubkey: a.vault, isSigner: false, isWritable: true },\n { pubkey: a.vaultAuth, isSigner: false, isWritable: false },\n { pubkey: a.collateralMint, isSigner: false, isWritable: false },\n { pubkey: a.percolatorProgram, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },\n ];\n}\n\n/**\n * Build account keys for Deposit instruction.\n */\nexport function depositAccounts(a: StakeAccounts['deposit']) {\n return [\n { pubkey: a.user, isSigner: true, isWritable: false },\n { pubkey: a.pool, isSigner: false, isWritable: true },\n { pubkey: a.userCollateralAta, isSigner: false, isWritable: true },\n { pubkey: a.vault, isSigner: false, isWritable: true },\n { pubkey: a.lpMint, isSigner: false, isWritable: true },\n { pubkey: a.userLpAta, isSigner: false, isWritable: true },\n { pubkey: a.vaultAuth, isSigner: false, isWritable: false },\n { pubkey: a.depositPda, isSigner: false, isWritable: true },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n ];\n}\n\n/**\n * Build account keys for Withdraw instruction.\n */\nexport function withdrawAccounts(a: StakeAccounts['withdraw']) {\n return [\n { pubkey: a.user, isSigner: true, isWritable: false },\n { pubkey: a.pool, isSigner: false, isWritable: true },\n { pubkey: a.userLpAta, isSigner: false, isWritable: true },\n { pubkey: a.lpMint, isSigner: false, isWritable: true },\n { pubkey: a.vault, isSigner: false, isWritable: true },\n { pubkey: a.userCollateralAta, isSigner: false, isWritable: true },\n { pubkey: a.vaultAuth, isSigner: false, isWritable: false },\n { pubkey: a.depositPda, isSigner: false, isWritable: true },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },\n ];\n}\n\n/**\n * Build account keys for FlushToInsurance instruction.\n */\nexport function flushToInsuranceAccounts(a: StakeAccounts['flushToInsurance']) {\n return [\n { pubkey: a.caller, isSigner: true, isWritable: false },\n { pubkey: a.pool, isSigner: false, isWritable: true },\n { pubkey: a.vault, isSigner: false, isWritable: true },\n { pubkey: a.vaultAuth, isSigner: false, isWritable: false },\n { pubkey: a.slab, isSigner: false, isWritable: true },\n { pubkey: a.wrapperVault, isSigner: false, isWritable: true },\n { pubkey: a.percolatorProgram, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n ];\n}\n","import { PublicKey } from \"@solana/web3.js\";\n\n/**\n * Read an environment variable safely. Returns `undefined` in browser\n * environments where `process` is not defined, avoiding a\n * `ReferenceError` crash at import time.\n */\nexport function safeEnv(key: string): string | undefined {\n try {\n return typeof process !== \"undefined\" && process?.env\n ? process.env[key]\n : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Centralized PROGRAM_ID configuration\n * \n * Default to environment variable, then fall back to network-specific defaults.\n * This prevents hard-coded program IDs scattered across the codebase.\n */\n\nexport const PROGRAM_IDS = {\n devnet: {\n percolator: \"FxfD37s1AZTeWfFQps9Zpebi2dNQ9QSSDtfMKdbsfKrD\",\n matcher: \"GTRgyTDfrMvBubALAqtHuQwT8tbGyXid7svXZKtWfC9k\",\n },\n mainnet: {\n percolator: \"GM8zjJ8LTBMv9xEsverh6H6wLyevgMHEJXcEzyY3rY24\",\n matcher: \"DHP6DtwXP1yJsz8YzfoeigRFPB979gzmumkmCxDLSkUX\",\n },\n} as const;\n\nexport type Network = \"devnet\" | \"mainnet\";\n\n/**\n * Get the Percolator program ID for the current network\n * \n * Priority:\n * 1. PROGRAM_ID env var (explicit override)\n * 2. Network-specific default (NETWORK env var)\n * 3. Devnet default (safest fallback — bug bounty PERC-697)\n */\nexport function getProgramId(network?: Network): PublicKey {\n const override = safeEnv(\"PROGRAM_ID\");\n if (override) {\n console.warn(\n `[percolator-sdk] PROGRAM_ID env override active: ${override} — ensure this points to a trusted program`,\n );\n return new PublicKey(override);\n }\n\n // Use provided network or detect from env — default to devnet (never mainnet silently)\n const detectedNetwork = getCurrentNetwork();\n const targetNetwork = network ?? detectedNetwork;\n const programId = PROGRAM_IDS[targetNetwork].percolator;\n\n return new PublicKey(programId);\n}\n\n/**\n * Get the Matcher program ID for the current network\n */\nexport function getMatcherProgramId(network?: Network): PublicKey {\n const override = safeEnv(\"MATCHER_PROGRAM_ID\");\n if (override) {\n console.warn(\n `[percolator-sdk] MATCHER_PROGRAM_ID env override active: ${override} — ensure this points to a trusted program`,\n );\n return new PublicKey(override);\n }\n\n // Use provided network or detect from env — default to devnet (never mainnet silently)\n const detectedNetwork = getCurrentNetwork();\n const targetNetwork = network ?? detectedNetwork;\n const programId = PROGRAM_IDS[targetNetwork].matcher;\n\n if (!programId) {\n throw new Error(`Matcher program not deployed on ${targetNetwork}`);\n }\n\n return new PublicKey(programId);\n}\n\n/**\n * Get the current network from environment.\n *\n * SECURITY (PERC-697): Removed silent mainnet default.\n * Previously defaulted to \"mainnet\" when NETWORK was unset, which could cause\n * crank/keeper scripts run without env vars to silently target mainnet program IDs.\n *\n * Now defaults to \"devnet\" — the safer fallback for a devnet-first protocol.\n * Production deployments always set NETWORK explicitly via Railway/env.\n * For mainnet operations use networkValidation.ts (ensureNetworkConfigValid) which\n * enforces FORCE_MAINNET=1.\n */\nexport function getCurrentNetwork(): Network {\n const network = safeEnv(\"NETWORK\")?.toLowerCase();\n if (network === \"mainnet\" || network === \"mainnet-beta\") {\n return \"mainnet\";\n }\n // devnet, testnet, or unset → devnet (fail-open to devnet, not mainnet)\n return \"devnet\";\n}\n","/**\n * @module adl\n * Percolator ADL (Auto-Deleveraging) client utilities.\n *\n * PERC-8278 / PERC-8312 / PERC-305: ADL is triggered when `pnl_pos_tot > max_pnl_cap`\n * on a market (PnL cap exceeded) AND the insurance fund is fully depleted (balance == 0).\n * The most profitable positions on the dominant side are deleveraged first.\n *\n * **Note on caller permissions:** `ExecuteAdl` (tag 50) requires the caller to be the\n * market admin/keeper key (`header.admin`). It is NOT permissionless despite the\n * instruction being structurally available to any signer.\n *\n * API surface:\n * - fetchAdlRankedPositions() — fetch slab + rank all open positions by PnL%\n * - rankAdlPositions() — pure (no-RPC) variant for already-fetched slab bytes\n * - isAdlTriggered() — check if slab's pnl_pos_tot exceeds max_pnl_cap\n * - buildAdlInstruction() — build a single ExecuteAdl TransactionInstruction\n * - buildAdlTransaction() — fetch + rank + pick top target + return instruction\n * - parseAdlEvent() — decode AdlEvent from transaction log lines\n * - fetchAdlRankings() — call /api/adl/rankings HTTP endpoint\n * - AdlRankedPosition — position record with adl_rank and computed pnlPct\n * - AdlRankingResult — full ranking with trigger status\n * - AdlEvent — decoded on-chain AdlEvent log entry (tag 0xAD1E_0001)\n * - AdlApiRanking — single ranked position from /api/adl/rankings\n * - AdlApiResult — full result from /api/adl/rankings\n * - AdlSide — \"long\" | \"short\"\n */\n\nimport {\n Connection,\n PublicKey,\n TransactionInstruction,\n AccountMeta,\n SYSVAR_CLOCK_PUBKEY,\n} from \"@solana/web3.js\";\nimport {\n fetchSlab,\n parseAllAccounts,\n parseEngine,\n parseConfig,\n detectSlabLayout,\n AccountKind,\n Account,\n SlabLayout,\n} from \"./slab.js\";\nimport { encodeExecuteAdl } from \"../abi/instructions.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Position side derived from positionSize sign. */\nexport type AdlSide = \"long\" | \"short\";\n\n/**\n * A ranked open position for ADL purposes.\n * Positions are ranked descending by `pnlPct` — rank 0 is the most profitable\n * and will be deleveraged first.\n */\nexport interface AdlRankedPosition {\n /** Account index in the slab (used as `targetIdx` in ExecuteAdl). */\n idx: number;\n /** Owner public key. */\n owner: PublicKey;\n /** Raw position size (i128 — negative = short, positive = long). */\n positionSize: bigint;\n /** Realised + mark-to-market PnL in lamports (i128 from slab). */\n pnl: bigint;\n /** Capital at entry in lamports (u128). */\n capital: bigint;\n /**\n * PnL as a fraction of capital, expressed as basis points (scaled × 10_000).\n * pnlPct = pnl * 10_000 / capital.\n * Higher = more profitable = deleveraged first.\n */\n pnlPct: bigint;\n /** Long or short. */\n side: AdlSide;\n /**\n * ADL rank among positions on the same side (0 = highest PnL%, deleveraged first).\n * `-1` if position size is zero (inactive).\n */\n adlRank: number;\n}\n\n/**\n * Result of `fetchAdlRankedPositions`.\n */\nexport interface AdlRankingResult {\n /** All open (non-zero) user positions, sorted descending by PnLPct, ranked. */\n ranked: AdlRankedPosition[];\n /**\n * Longs ranked separately (adlRank within this subset).\n * Rank 0 = most profitable long = first to be deleveraged on a net-long market.\n */\n longs: AdlRankedPosition[];\n /**\n * Shorts ranked separately (adlRank within this subset).\n * Rank 0 = most profitable short (most negative pnlPct magnitude — i.e., highest\n * unrealised gain for the short-side holder).\n */\n shorts: AdlRankedPosition[];\n /** Whether ADL is currently triggered (pnlPosTot > maxPnlCap). */\n isTriggered: boolean;\n /** pnl_pos_tot from engine state. */\n pnlPosTot: bigint;\n /** max_pnl_cap from market config. */\n maxPnlCap: bigint;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Compute PnL% in basis points for a position.\n * Returns 0n when capital is 0 to avoid division by zero.\n */\nfunction computePnlPct(pnl: bigint, capital: bigint): bigint {\n if (capital === 0n) return 0n;\n return (pnl * 10_000n) / capital;\n}\n\n// ---------------------------------------------------------------------------\n// Core API\n// ---------------------------------------------------------------------------\n\n/**\n * Check whether ADL is currently triggered on a slab.\n *\n * ADL triggers when pnl_pos_tot > max_pnl_cap (max_pnl_cap must be > 0).\n *\n * @param slabData - Raw slab account bytes.\n * @returns true if ADL is triggered.\n *\n * @example\n * ```ts\n * const data = await fetchSlab(connection, slabKey);\n * if (isAdlTriggered(data)) {\n * const ranking = await fetchAdlRankedPositions(connection, slabKey);\n * }\n * ```\n */\nexport function isAdlTriggered(slabData: Uint8Array): boolean {\n const layout = detectSlabLayout(slabData.length);\n if (!layout) return false;\n try {\n const engine = parseEngine(slabData);\n if (engine.pnlPosTot === 0n) return false;\n const config = parseConfig(slabData, layout);\n if (config.maxPnlCap === 0n) return false;\n return engine.pnlPosTot > config.maxPnlCap;\n } catch {\n return false;\n }\n}\n\n/**\n * Fetch a slab and rank all open user positions by PnL% for ADL targeting.\n *\n * Positions are ranked separately per side:\n * - Longs: rank 0 = highest positive PnL% (most profitable long)\n * - Shorts: rank 0 = highest negative PnL% by abs value (most profitable short)\n *\n * Rank ordering matches the on-chain ADL engine in percolator-prog (PERC-8273):\n * the position at rank 0 of the dominant side is deleveraged first.\n *\n * @param connection - Solana connection.\n * @param slab - Slab (market) public key.\n * @returns AdlRankingResult with ranked longs, ranked shorts, and trigger status.\n *\n * @example\n * ```ts\n * const { ranked, longs, isTriggered } = await fetchAdlRankedPositions(connection, slabKey);\n * if (isTriggered && longs.length > 0) {\n * const target = longs[0]; // highest PnL long\n * const ix = buildAdlInstruction(caller, slabKey, oracleKey, programId, target.idx);\n * }\n * ```\n */\nexport async function fetchAdlRankedPositions(\n connection: Connection,\n slab: PublicKey\n): Promise<AdlRankingResult> {\n const data = await fetchSlab(connection, slab);\n return rankAdlPositions(data);\n}\n\n/**\n * Pure (no-RPC) variant — rank positions from already-fetched slab bytes.\n * Useful when you already have the slab data (e.g., from a subscription).\n */\nexport function rankAdlPositions(slabData: Uint8Array): AdlRankingResult {\n const layout = detectSlabLayout(slabData.length);\n\n let pnlPosTot = 0n;\n try {\n const engine = parseEngine(slabData);\n pnlPosTot = engine.pnlPosTot;\n } catch (err) {\n console.warn(\n `[rankAdlPositions] parseEngine failed:`,\n err instanceof Error ? err.message : err,\n );\n }\n\n let maxPnlCap = 0n;\n let isTriggered = false;\n if (layout) {\n try {\n const config = parseConfig(slabData, layout);\n maxPnlCap = config.maxPnlCap;\n isTriggered = maxPnlCap > 0n && pnlPosTot > maxPnlCap;\n } catch {\n // If config parse fails, leave isTriggered=false; ranking still useful.\n }\n }\n\n // Parse all used accounts.\n const accounts = parseAllAccounts(slabData);\n\n // Build ranked position list (user accounts with non-zero position only).\n const positions: AdlRankedPosition[] = [];\n for (const { idx, account } of accounts) {\n if (account.kind !== AccountKind.User) continue;\n if (account.positionSize === 0n) continue;\n\n const side: AdlSide = account.positionSize > 0n ? \"long\" : \"short\";\n // For shorts, positionSize is negative — PnL computation is symmetric:\n // a short profits when price falls, so pnl stored in the slab already\n // reflects mark-to-market gain/loss for both sides.\n const pnlPct = computePnlPct(account.pnl, account.capital);\n\n positions.push({\n idx,\n owner: account.owner,\n positionSize: account.positionSize,\n pnl: account.pnl,\n capital: account.capital,\n pnlPct,\n side,\n adlRank: -1, // assigned below\n });\n }\n\n // Rank longs: descending pnlPct (most profitable first).\n const longs = positions\n .filter(p => p.side === \"long\")\n .sort((a, b) => (b.pnlPct > a.pnlPct ? 1 : b.pnlPct < a.pnlPct ? -1 : 0));\n longs.forEach((p, i) => { p.adlRank = i; });\n\n // Rank shorts: descending pnlPct (most profitable short = highest pnlPct\n // magnitude, but pnlPct can be negative; sort descending still puts\n // the \"least negative\" aka \"most profitable\" short first).\n const shorts = positions\n .filter(p => p.side === \"short\")\n .sort((a, b) => (b.pnlPct > a.pnlPct ? 1 : b.pnlPct < a.pnlPct ? -1 : 0));\n shorts.forEach((p, i) => { p.adlRank = i; });\n\n // Overall ranked list = longs + shorts merged, still sorted by pnlPct desc.\n const ranked = [...longs, ...shorts].sort(\n (a, b) => (b.pnlPct > a.pnlPct ? 1 : b.pnlPct < a.pnlPct ? -1 : 0)\n );\n\n return { ranked, longs, shorts, isTriggered, pnlPosTot, maxPnlCap };\n}\n\n/**\n * Build a single `ExecuteAdl` TransactionInstruction (tag 50, PERC-305).\n *\n * Does NOT fetch the slab or check trigger status — use `fetchAdlRankedPositions`\n * first to determine the correct `targetIdx`.\n *\n * **Caller requirement:** The on-chain handler requires the caller to be the market\n * admin/keeper authority (`header.admin`). Passing any other signer will result in\n * `EngineUnauthorized`.\n *\n * @param caller - Signer — must be the market keeper/admin authority.\n * @param slab - Slab (market) public key.\n * @param oracle - Primary oracle public key for this market.\n * @param programId - Percolator program ID.\n * @param targetIdx - Account index to deleverage (from `AdlRankedPosition.idx`).\n * @param backupOracles - Optional additional oracle accounts (non-Hyperp markets).\n *\n * @example\n * ```ts\n * import { fetchAdlRankedPositions, buildAdlInstruction } from \"@percolator/sdk\";\n *\n * const { longs, isTriggered } = await fetchAdlRankedPositions(connection, slabKey);\n * if (isTriggered && longs.length > 0) {\n * const ix = buildAdlInstruction(\n * caller.publicKey, slabKey, oracleKey, PROGRAM_ID, longs[0].idx\n * );\n * await sendAndConfirmTransaction(connection, new Transaction().add(ix), [caller]);\n * }\n * ```\n */\nexport function buildAdlInstruction(\n caller: PublicKey,\n slab: PublicKey,\n oracle: PublicKey,\n programId: PublicKey,\n targetIdx: number,\n backupOracles: PublicKey[] = []\n): TransactionInstruction {\n if (!Number.isInteger(targetIdx) || targetIdx < 0) {\n throw new Error(\n `buildAdlInstruction: targetIdx must be a non-negative integer, got ${targetIdx}`,\n );\n }\n const dataBytes = encodeExecuteAdl({ targetIdx });\n const data = Buffer.from(dataBytes);\n\n const keys: AccountMeta[] = [\n { pubkey: caller, isSigner: true, isWritable: false },\n { pubkey: slab, isSigner: false, isWritable: true },\n { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },\n { pubkey: oracle, isSigner: false, isWritable: false },\n ...backupOracles.map(k => ({ pubkey: k, isSigner: false, isWritable: false })),\n ];\n\n return new TransactionInstruction({ keys, programId, data });\n}\n\n/**\n * Convenience builder: fetch slab, rank positions, pick the highest-ranked\n * target on the given side, and return a ready-to-send `TransactionInstruction`.\n *\n * Returns `null` when ADL is not triggered or no eligible positions exist.\n *\n * @param connection - Solana connection.\n * @param caller - Signer — must be the market keeper/admin authority.\n * @param slab - Slab (market) public key.\n * @param oracle - Primary oracle public key.\n * @param programId - Percolator program ID.\n * @param preferSide - Optional: target \"long\" or \"short\" side only.\n * If omitted, picks the overall top-ranked position.\n * @param backupOracles - Optional extra oracle accounts.\n *\n * @example\n * ```ts\n * const ix = await buildAdlTransaction(\n * connection, caller.publicKey, slabKey, oracleKey, PROGRAM_ID\n * );\n * if (ix) {\n * await sendAndConfirmTransaction(connection, new Transaction().add(ix), [caller]);\n * }\n * ```\n */\nexport async function buildAdlTransaction(\n connection: Connection,\n caller: PublicKey,\n slab: PublicKey,\n oracle: PublicKey,\n programId: PublicKey,\n preferSide?: AdlSide,\n backupOracles: PublicKey[] = []\n): Promise<TransactionInstruction | null> {\n const ranking = await fetchAdlRankedPositions(connection, slab);\n\n if (!ranking.isTriggered) return null;\n\n let target: AdlRankedPosition | undefined;\n if (preferSide === \"long\") {\n target = ranking.longs[0];\n } else if (preferSide === \"short\") {\n target = ranking.shorts[0];\n } else {\n target = ranking.ranked[0];\n }\n\n if (!target) return null;\n\n return buildAdlInstruction(caller, slab, oracle, programId, target.idx, backupOracles);\n}\n\n// ---------------------------------------------------------------------------\n// AdlEvent — on-chain log decoder (PERC-8312)\n// ---------------------------------------------------------------------------\n\n/**\n * Decoded on-chain AdlEvent emitted by the `ExecuteAdl` instruction handler.\n *\n * The on-chain handler emits via `sol_log_64(0xAD1E_0001, target_idx, price, closed_lo, closed_hi)`.\n * `sol_log_64` prints 5 decimal u64 values separated by spaces on a single \"Program log:\" line.\n *\n * Fields:\n * - `tag` — always `0xAD1E_0001` (2970353665n)\n * - `targetIdx` — slab account index that was deleveraged\n * - `price` — oracle price used (in market price units, e.g. e6)\n * - `closedAbs` — absolute size of the position closed (i128, reassembled from lo+hi u64 parts)\n *\n * @example\n * ```ts\n * const logs = tx.meta?.logMessages ?? [];\n * const event = parseAdlEvent(logs);\n * if (event) {\n * console.log(\"ADL closed position\", event.targetIdx, \"size\", event.closedAbs);\n * }\n * ```\n */\nexport interface AdlEvent {\n /** Tag discriminator — always 0xAD1E_0001n (2970353665). */\n tag: bigint;\n /** Slab account index that was deleveraged. */\n targetIdx: number;\n /** Oracle price used for the deleverage (market-native units, e.g. lamports/e6). */\n price: bigint;\n /**\n * Absolute position size closed (reassembled from lo+hi u64).\n * This is the i128 absolute value — always non-negative.\n */\n closedAbs: bigint;\n}\n\n/** Magic discriminator for the ADL event log line. */\nconst ADL_EVENT_TAG = 0xAD1E_0001n;\n\n/**\n * Parse the AdlEvent from a transaction's log messages.\n *\n * Searches for a \"Program log: <a> <b> <c> <d> <e>\" line where the first\n * decimal value equals `0xAD1E_0001` (2970353665). Returns `null` if not found.\n *\n * @param logs - Array of log message strings (from `tx.meta.logMessages`).\n * @returns Decoded `AdlEvent` or `null` if the log is not present.\n *\n * @example\n * ```ts\n * const event = parseAdlEvent(tx.meta?.logMessages ?? []);\n * if (event) {\n * console.log(`ADL: idx=${event.targetIdx} price=${event.price} closed=${event.closedAbs}`);\n * }\n * ```\n */\nexport function parseAdlEvent(logs: string[]): AdlEvent | null {\n for (const line of logs) {\n if (typeof line !== \"string\") continue;\n // sol_log_64 emits: \"Program log: a b c d e\" (5 space-separated decimals)\n const match = line.match(\n /^Program log: (\\d+) (\\d+) (\\d+) (\\d+) (\\d+)$/,\n );\n if (!match) continue;\n\n let tag: bigint;\n try {\n tag = BigInt(match[1]);\n } catch {\n continue;\n }\n\n if (tag !== ADL_EVENT_TAG) continue;\n\n try {\n const targetIdx = Number(BigInt(match[2]));\n const price = BigInt(match[3]);\n const closedLo = BigInt(match[4]);\n const closedHi = BigInt(match[5]);\n // Reassemble i128 from lo/hi u64 parts (little-endian split).\n const closedAbs = (closedHi << 64n) | closedLo;\n return { tag, targetIdx, price, closedAbs };\n } catch {\n continue;\n }\n }\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// fetchAdlRankings — HTTP client for /api/adl/rankings (PERC-8312)\n// ---------------------------------------------------------------------------\n\n/**\n * A single ranked position as returned by the /api/adl/rankings endpoint.\n */\nexport interface AdlApiRanking {\n /** 1-based rank (1 = highest PnL%, first to be deleveraged). */\n rank: number;\n /** Slab account index. Pass as `targetIdx` to `buildAdlInstruction`. */\n idx: number;\n /** Absolute PnL (lamports) as a decimal string. */\n pnlAbs: string;\n /** Capital at entry (lamports) as a decimal string. */\n capital: string;\n /** PnL as millionths of capital (pnl * 1_000_000 / capital). */\n pnlPctMillionths: string;\n}\n\n/**\n * Full result from the /api/adl/rankings endpoint.\n */\nexport interface AdlApiResult {\n slabAddress: string;\n /** pnl_pos_tot from slab engine state (decimal string). */\n pnlPosTot: string;\n /** max_pnl_cap from market config (decimal string, \"0\" if unconfigured). */\n maxPnlCap: string;\n /** Insurance fund balance (decimal string). */\n insuranceFundBalance: string;\n /** Insurance fund lifetime fee revenue (decimal string). */\n insuranceFundFeeRevenue: string;\n /** Insurance utilization in basis points (0–10000). */\n insuranceUtilizationBps: number;\n /** true if pnlPosTot > maxPnlCap. */\n capExceeded: boolean;\n /** true if insurance fund is fully depleted (balance == 0). */\n insuranceDepleted: boolean;\n /** true if utilization BPS exceeds the configured ADL threshold. */\n utilizationTriggered: boolean;\n /** true if ADL is needed (capExceeded or utilizationTriggered). */\n adlNeeded: boolean;\n /** Excess PnL above cap (decimal string). */\n excess: string;\n /** Ranked positions (empty if adlNeeded=false). */\n rankings: AdlApiRanking[];\n}\n\n/**\n * Fetch ADL rankings from the Percolator API.\n *\n * Calls `GET <apiBase>/api/adl/rankings?slab=<address>` and returns the\n * parsed result. Use this from the frontend or keeper to determine ADL\n * trigger status and pick the target index.\n *\n * @param apiBase - Base URL of the Percolator API (e.g. `https://api.percolator.io`).\n * @param slab - Slab (market) public key or base58 address string.\n * @param fetchFn - Optional custom fetch implementation (defaults to global `fetch`).\n * @returns Parsed `AdlApiResult`.\n * @throws On HTTP error or JSON parse failure.\n *\n * @example\n * ```ts\n * const result = await fetchAdlRankings(\"https://api.percolator.io\", slabKey);\n * if (result.adlNeeded && result.rankings.length > 0) {\n * const target = result.rankings[0]; // rank 1 = highest PnL%\n * const ix = buildAdlInstruction(caller, slabKey, oracleKey, PROGRAM_ID, target.idx);\n * }\n * ```\n */\nexport async function fetchAdlRankings(\n apiBase: string,\n slab: PublicKey | string,\n fetchFn: typeof fetch = fetch,\n): Promise<AdlApiResult> {\n const slabStr = typeof slab === \"string\" ? slab : slab.toBase58();\n const base = apiBase.replace(/\\/$/, \"\");\n const url = `${base}/api/adl/rankings?slab=${encodeURIComponent(slabStr)}`;\n\n const res = await fetchFn(url);\n if (!res.ok) {\n let body = \"\";\n try { body = await res.text(); } catch { /* ignore */ }\n throw new Error(\n `fetchAdlRankings: HTTP ${res.status} from ${url}${body ? ` — ${body}` : \"\"}`,\n );\n }\n\n const json = await res.json() as AdlApiResult;\n return json;\n}\n","import {\n Connection,\n PublicKey,\n TransactionInstruction,\n Transaction,\n Keypair,\n SendOptions,\n Commitment,\n AccountMeta,\n ComputeBudgetProgram,\n} from \"@solana/web3.js\";\nimport { parseErrorFromLogs } from \"../abi/errors.js\";\n\nexport interface BuildIxParams {\n programId: PublicKey;\n keys: AccountMeta[];\n data: Uint8Array | Buffer;\n}\n\n/**\n * Build a transaction instruction.\n */\nexport function buildIx(params: BuildIxParams): TransactionInstruction {\n return new TransactionInstruction({\n programId: params.programId,\n keys: params.keys,\n // TransactionInstruction types expect Buffer, but Uint8Array works at runtime.\n // Cast to avoid Buffer polyfill issues in the browser.\n data: params.data as Buffer,\n });\n}\n\nexport interface TxResult {\n signature: string;\n slot: number;\n err: string | null;\n hint?: string;\n logs: string[];\n unitsConsumed?: number;\n}\n\nexport interface SimulateOrSendParams {\n connection: Connection;\n ix: TransactionInstruction;\n signers: Keypair[];\n simulate: boolean;\n commitment?: Commitment;\n computeUnitLimit?: number; // Custom compute unit limit (default: 200,000, max: 1,400,000)\n}\n\n/**\n * Simulate or send a transaction.\n * Returns consistent output for both modes.\n */\n/** Solana per-transaction compute unit ceiling (Compute Budget program). */\nconst MAX_COMPUTE_UNIT_LIMIT = 1_400_000;\n\nexport async function simulateOrSend(\n params: SimulateOrSendParams\n): Promise<TxResult> {\n const { connection, ix, signers, simulate, commitment = \"confirmed\", computeUnitLimit } = params;\n\n if (!signers.length) {\n throw new Error(\"simulateOrSend: at least one signer is required\");\n }\n\n if (computeUnitLimit !== undefined) {\n if (\n typeof computeUnitLimit !== \"number\" ||\n !Number.isInteger(computeUnitLimit) ||\n computeUnitLimit < 1 ||\n computeUnitLimit > MAX_COMPUTE_UNIT_LIMIT\n ) {\n throw new Error(\n `computeUnitLimit must be an integer in [1, ${MAX_COMPUTE_UNIT_LIMIT}]`,\n );\n }\n }\n\n const tx = new Transaction();\n\n // Add compute budget instruction if custom limit is specified\n if (computeUnitLimit !== undefined) {\n tx.add(\n ComputeBudgetProgram.setComputeUnitLimit({\n units: computeUnitLimit,\n })\n );\n }\n\n tx.add(ix);\n const latestBlockhash = await connection.getLatestBlockhash(commitment);\n tx.recentBlockhash = latestBlockhash.blockhash;\n tx.feePayer = signers[0].publicKey;\n\n if (simulate) {\n try {\n tx.sign(...signers);\n const result = await connection.simulateTransaction(tx, signers);\n const logs = result.value.logs ?? [];\n let err: string | null = null;\n let hint: string | undefined;\n\n if (result.value.err) {\n const parsed = parseErrorFromLogs(logs);\n if (parsed) {\n err = `${parsed.name} (0x${parsed.code.toString(16)})`;\n hint = parsed.hint;\n } else {\n err = JSON.stringify(result.value.err);\n }\n }\n\n return {\n signature: \"(simulated)\",\n slot: result.context.slot,\n err,\n hint,\n logs,\n unitsConsumed: result.value.unitsConsumed ?? undefined,\n };\n } catch (e: unknown) {\n const message = e instanceof Error ? e.message : String(e);\n return {\n signature: \"(simulated)\",\n slot: 0,\n err: message,\n logs: [],\n };\n }\n }\n\n // Send\n const options: SendOptions = {\n skipPreflight: false,\n preflightCommitment: commitment,\n };\n\n try {\n const signature = await connection.sendTransaction(tx, signers, options);\n\n const confirmation = await connection.confirmTransaction(\n {\n signature,\n blockhash: latestBlockhash.blockhash,\n lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,\n },\n commitment\n );\n\n // Fetch logs\n const txInfo = await connection.getTransaction(signature, {\n commitment: \"confirmed\",\n maxSupportedTransactionVersion: 0,\n });\n\n const logs = txInfo?.meta?.logMessages ?? [];\n let err: string | null = null;\n let hint: string | undefined;\n\n if (confirmation.value.err) {\n const parsed = parseErrorFromLogs(logs);\n if (parsed) {\n err = `${parsed.name} (0x${parsed.code.toString(16)})`;\n hint = parsed.hint;\n } else {\n err = JSON.stringify(confirmation.value.err);\n }\n }\n\n return {\n signature,\n slot: txInfo?.slot ?? 0,\n err,\n hint,\n logs,\n };\n } catch (e: unknown) {\n const message = e instanceof Error ? e.message : String(e);\n return {\n signature: \"\",\n slot: 0,\n err: message,\n logs: [],\n };\n }\n}\n\n/**\n * Format transaction result for output.\n */\nexport function formatResult(result: TxResult, jsonMode: boolean): string {\n if (jsonMode) {\n return JSON.stringify(result, null, 2);\n }\n\n const lines: string[] = [];\n\n if (result.err) {\n lines.push(`Error: ${result.err}`);\n if (result.hint) {\n lines.push(`Hint: ${result.hint}`);\n }\n if (result.unitsConsumed !== undefined) {\n lines.push(`Compute Units: ${result.unitsConsumed.toLocaleString()}`);\n }\n if (result.logs.length > 0) {\n lines.push(\"Logs:\");\n result.logs.forEach((log) => lines.push(` ${log}`));\n }\n } else {\n lines.push(`Signature: ${result.signature}`);\n lines.push(`Slot: ${result.slot}`);\n if (result.unitsConsumed !== undefined) {\n lines.push(`Compute Units: ${result.unitsConsumed.toLocaleString()}`);\n }\n if (result.signature !== \"(simulated)\") {\n lines.push(`Explorer: https://explorer.solana.com/tx/${result.signature}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n","/**\n * Coin-margined perpetual trade math utilities.\n *\n * On-chain PnL formula:\n * mark_pnl = (oracle - entry) * abs_pos / oracle (longs)\n * mark_pnl = (entry - oracle) * abs_pos / oracle (shorts)\n *\n * All prices are in e6 format (1 USD = 1_000_000).\n * All token amounts are in native units (e.g. lamports).\n */\n\n/**\n * Compute mark-to-market PnL for an open position.\n */\nexport function computeMarkPnl(\n positionSize: bigint,\n entryPrice: bigint,\n oraclePrice: bigint,\n): bigint {\n if (positionSize === 0n || oraclePrice === 0n) return 0n;\n const absPos = positionSize < 0n ? -positionSize : positionSize;\n const diff =\n positionSize > 0n\n ? oraclePrice - entryPrice\n : entryPrice - oraclePrice;\n return (diff * absPos) / oraclePrice;\n}\n\n/**\n * Compute liquidation price given entry, capital, position and maintenance margin.\n * Uses pure BigInt arithmetic for precision (no Number() truncation).\n */\nexport function computeLiqPrice(\n entryPrice: bigint,\n capital: bigint,\n positionSize: bigint,\n maintenanceMarginBps: bigint,\n): bigint {\n if (positionSize === 0n || entryPrice === 0n) return 0n;\n const absPos = positionSize < 0n ? -positionSize : positionSize;\n // capitalPerUnit scaled by 1e6 for precision\n const capitalPerUnitE6 = (capital * 1_000_000n) / absPos;\n\n if (positionSize > 0n) {\n const adjusted = (capitalPerUnitE6 * 10000n) / (10000n + maintenanceMarginBps);\n const liq = entryPrice - adjusted;\n return liq > 0n ? liq : 0n;\n } else {\n // Guard: short positions liquidate when price rises above liq price.\n // With >= 100% maintenance margin the denominator (10000 - maint) would be <= 0,\n // meaning the position can never be liquidated. Return max u64 to signal this.\n if (maintenanceMarginBps >= 10000n) return 18446744073709551615n; // max u64 — unliquidatable\n const adjusted = (capitalPerUnitE6 * 10000n) / (10000n - maintenanceMarginBps);\n return entryPrice + adjusted;\n }\n}\n\n/**\n * Compute estimated liquidation price BEFORE opening a trade.\n * Accounts for trading fees reducing effective capital.\n */\nexport function computePreTradeLiqPrice(\n oracleE6: bigint,\n margin: bigint,\n posSize: bigint,\n maintBps: bigint,\n feeBps: bigint,\n direction: \"long\" | \"short\",\n): bigint {\n if (oracleE6 === 0n || margin === 0n || posSize === 0n) return 0n;\n const absPos = posSize < 0n ? -posSize : posSize;\n const fee = (absPos * feeBps) / 10000n;\n const effectiveCapital = margin > fee ? margin - fee : 0n;\n const signedPos = direction === \"long\" ? absPos : -absPos;\n return computeLiqPrice(oracleE6, effectiveCapital, signedPos, maintBps);\n}\n\n/**\n * Compute trading fee from notional value and fee rate in bps.\n */\nexport function computeTradingFee(\n notional: bigint,\n tradingFeeBps: bigint,\n): bigint {\n return (notional * tradingFeeBps) / 10000n;\n}\n\n/**\n * Dynamic fee tier configuration.\n */\nexport interface FeeTierConfig {\n /** Base trading fee (Tier 1) in bps */\n baseBps: bigint;\n /** Tier 2 fee in bps (0 = disabled) */\n tier2Bps: bigint;\n /** Tier 3 fee in bps (0 = disabled) */\n tier3Bps: bigint;\n /** Notional threshold to enter Tier 2 (0 = tiered fees disabled) */\n tier2Threshold: bigint;\n /** Notional threshold to enter Tier 3 */\n tier3Threshold: bigint;\n}\n\n/**\n * Compute the effective fee rate in bps using the tiered fee schedule.\n *\n * Mirrors on-chain `compute_dynamic_fee_bps` logic:\n * - notional < tier2Threshold → baseBps (Tier 1)\n * - notional < tier3Threshold → tier2Bps (Tier 2)\n * - notional >= tier3Threshold → tier3Bps (Tier 3)\n *\n * If tier2Threshold == 0, tiered fees are disabled (flat baseBps).\n */\nexport function computeDynamicFeeBps(\n notional: bigint,\n config: FeeTierConfig,\n): bigint {\n if (config.tier2Threshold === 0n) return config.baseBps;\n if (config.tier3Threshold > 0n && notional >= config.tier3Threshold) return config.tier3Bps;\n if (notional >= config.tier2Threshold) return config.tier2Bps;\n return config.baseBps;\n}\n\n/**\n * Compute the dynamic trading fee for a given notional and tier config.\n *\n * Uses ceiling division to match on-chain behavior (prevents fee evasion\n * via micro-trades).\n */\nexport function computeDynamicTradingFee(\n notional: bigint,\n config: FeeTierConfig,\n): bigint {\n const feeBps = computeDynamicFeeBps(notional, config);\n if (notional <= 0n || feeBps <= 0n) return 0n;\n return (notional * feeBps + 9999n) / 10000n;\n}\n\n/**\n * Fee split configuration.\n */\nexport interface FeeSplitConfig {\n /** LP vault share in bps (0–10_000) */\n lpBps: bigint;\n /** Protocol treasury share in bps */\n protocolBps: bigint;\n /** Market creator share in bps */\n creatorBps: bigint;\n}\n\n/**\n * Compute fee split for a total fee amount.\n *\n * Returns [lpShare, protocolShare, creatorShare].\n * If all split params are 0, 100% goes to LP (legacy behavior).\n * Creator gets the rounding remainder to ensure total is preserved.\n */\nexport function computeFeeSplit(\n totalFee: bigint,\n config: FeeSplitConfig,\n): [bigint, bigint, bigint] {\n if (config.lpBps === 0n && config.protocolBps === 0n && config.creatorBps === 0n) {\n return [totalFee, 0n, 0n];\n }\n const lp = (totalFee * config.lpBps) / 10000n;\n const protocol = (totalFee * config.protocolBps) / 10000n;\n const creator = totalFee - lp - protocol;\n return [lp, protocol, creator];\n}\n\n/**\n * Compute PnL as a percentage of capital.\n *\n * Uses BigInt scaling to avoid precision loss from Number(bigint) conversion.\n * Number(bigint) silently truncates values above 2^53, which can produce\n * incorrect percentages for large positions (e.g., tokens with 9 decimals\n * where capital > ~9M tokens in native units exceeds MAX_SAFE_INTEGER).\n */\nexport function computePnlPercent(\n pnlTokens: bigint,\n capital: bigint,\n): number {\n if (capital === 0n) return 0;\n const scaledPct = (pnlTokens * 10_000n) / capital;\n if (scaledPct > BigInt(Number.MAX_SAFE_INTEGER) || scaledPct < BigInt(-Number.MAX_SAFE_INTEGER)) {\n throw new Error(\n `computePnlPercent: scaled result ${scaledPct} exceeds Number.MAX_SAFE_INTEGER — precision loss`,\n );\n }\n return Number(scaledPct) / 100;\n}\n\n/**\n * Estimate entry price including fee impact (slippage approximation).\n */\nexport function computeEstimatedEntryPrice(\n oracleE6: bigint,\n tradingFeeBps: bigint,\n direction: \"long\" | \"short\",\n): bigint {\n if (oracleE6 === 0n) return 0n;\n const feeImpact = (oracleE6 * tradingFeeBps) / 10000n;\n return direction === \"long\" ? oracleE6 + feeImpact : oracleE6 - feeImpact;\n}\n\nconst MAX_SAFE_BIGINT = BigInt(Number.MAX_SAFE_INTEGER);\nconst MIN_SAFE_BIGINT = BigInt(-Number.MAX_SAFE_INTEGER);\n\n/**\n * Convert per-slot funding rate (bps) to annualized percentage.\n */\nexport function computeFundingRateAnnualized(\n fundingRateBpsPerSlot: bigint,\n): number {\n if (fundingRateBpsPerSlot > MAX_SAFE_BIGINT || fundingRateBpsPerSlot < MIN_SAFE_BIGINT) {\n throw new Error(\n `computeFundingRateAnnualized: value ${fundingRateBpsPerSlot} exceeds safe integer range`,\n );\n }\n const bpsPerSlot = Number(fundingRateBpsPerSlot);\n const slotsPerYear = 2.5 * 60 * 60 * 24 * 365; // ~400ms slots\n return (bpsPerSlot * slotsPerYear) / 100;\n}\n\n/**\n * Compute margin required for a given notional and initial margin bps.\n */\nexport function computeRequiredMargin(\n notional: bigint,\n initialMarginBps: bigint,\n): bigint {\n return (notional * initialMarginBps) / 10000n;\n}\n\n/**\n * Compute maximum leverage from initial margin bps.\n *\n * @throws Error if initialMarginBps is zero (infinite leverage is undefined)\n */\nexport function computeMaxLeverage(initialMarginBps: bigint): number {\n if (initialMarginBps <= 0n) {\n throw new Error(\"computeMaxLeverage: initialMarginBps must be positive\");\n }\n return Number(10000n / initialMarginBps);\n}\n","/**\n * Warmup leverage cap utilities.\n *\n * During the market warmup period, capital is released linearly over\n * `warmupPeriodSlots` slots, which constrains the effective leverage\n * and maximum position size available to traders.\n */\n\nimport { computeMaxLeverage } from \"./trading.js\";\n\n// =============================================================================\n// Warmup leverage cap utilities\n// =============================================================================\n\n/**\n * Compute unlocked capital during the warmup period.\n *\n * Capital is released linearly over `warmupPeriodSlots` slots starting from\n * `warmupStartedAtSlot`. Before warmup starts (startSlot === 0) or if the\n * warmup period is 0, all capital is considered unlocked.\n *\n * @param totalCapital - Total deposited capital (native units).\n * @param currentSlot - The current on-chain slot.\n * @param warmupStartSlot - Slot at which warmup started (0 = not started).\n * @param warmupPeriodSlots - Total slots in the warmup period.\n * @returns The amount of capital currently unlocked.\n */\nexport function computeWarmupUnlockedCapital(\n totalCapital: bigint,\n currentSlot: bigint,\n warmupStartSlot: bigint,\n warmupPeriodSlots: bigint,\n): bigint {\n // No warmup configured or not started → all capital available\n if (warmupPeriodSlots === 0n || warmupStartSlot === 0n) return totalCapital;\n if (totalCapital <= 0n) return 0n;\n\n const elapsed = currentSlot > warmupStartSlot\n ? currentSlot - warmupStartSlot\n : 0n;\n\n // Warmup complete\n if (elapsed >= warmupPeriodSlots) return totalCapital;\n\n // Linear unlock: totalCapital * elapsed / warmupPeriodSlots\n return (totalCapital * elapsed) / warmupPeriodSlots;\n}\n\n/**\n * Compute the effective maximum leverage during the warmup period.\n *\n * During warmup, only unlocked capital can be used as margin. The effective\n * leverage relative to *total* capital is therefore capped at:\n *\n * effectiveMaxLeverage = maxLeverage × (unlockedCapital / totalCapital)\n *\n * This returns a floored integer value (leverage is always a whole number\n * in the UI), with a minimum of 1x if any capital is unlocked.\n *\n * @param initialMarginBps - Initial margin requirement in basis points.\n * @param totalCapital - Total deposited capital (native units).\n * @param currentSlot - The current on-chain slot.\n * @param warmupStartSlot - Slot at which warmup started (0 = not started).\n * @param warmupPeriodSlots - Total slots in the warmup period.\n * @returns The effective maximum leverage (integer, ≥ 1).\n */\nexport function computeWarmupLeverageCap(\n initialMarginBps: bigint,\n totalCapital: bigint,\n currentSlot: bigint,\n warmupStartSlot: bigint,\n warmupPeriodSlots: bigint,\n): number {\n const maxLev = computeMaxLeverage(initialMarginBps);\n\n // No warmup or warmup not started → full leverage\n if (warmupPeriodSlots === 0n || warmupStartSlot === 0n) return maxLev;\n if (totalCapital <= 0n) return 1;\n\n const unlocked = computeWarmupUnlockedCapital(\n totalCapital,\n currentSlot,\n warmupStartSlot,\n warmupPeriodSlots,\n );\n\n if (unlocked <= 0n) return 1; // At least 1x if nothing unlocked yet (slot 0 edge)\n\n // Effective leverage = maxLev * (unlocked / total), floored, min 1\n const effectiveLev = Number((BigInt(maxLev) * unlocked) / totalCapital);\n return Math.max(1, effectiveLev);\n}\n\n/**\n * Compute the maximum position size allowed during warmup.\n *\n * This is the unlocked capital multiplied by the base max leverage.\n * Unlike `computeWarmupLeverageCap` (which gives effective leverage\n * relative to total capital), this gives the absolute notional cap.\n *\n * @param initialMarginBps - Initial margin requirement in basis points.\n * @param totalCapital - Total deposited capital (native units).\n * @param currentSlot - The current on-chain slot.\n * @param warmupStartSlot - Slot at which warmup started (0 = not started).\n * @param warmupPeriodSlots - Total slots in the warmup period.\n * @returns Maximum position size in native units.\n */\nexport function computeWarmupMaxPositionSize(\n initialMarginBps: bigint,\n totalCapital: bigint,\n currentSlot: bigint,\n warmupStartSlot: bigint,\n warmupPeriodSlots: bigint,\n): bigint {\n const maxLev = computeMaxLeverage(initialMarginBps);\n const unlocked = computeWarmupUnlockedCapital(\n totalCapital,\n currentSlot,\n warmupStartSlot,\n warmupPeriodSlots,\n );\n return unlocked * BigInt(maxLev);\n}\n","/**\n * Input validation utilities for CLI commands.\n * Provides descriptive error messages for invalid input.\n */\n\nimport { PublicKey } from \"@solana/web3.js\";\n\n// Constants for numeric limits\nconst U16_MAX = 65535;\nconst U64_MAX = BigInt(\"18446744073709551615\");\nconst I64_MIN = BigInt(\"-9223372036854775808\");\nconst I64_MAX = BigInt(\"9223372036854775807\");\nconst U128_MAX = (1n << 128n) - 1n;\nconst I128_MIN = -(1n << 127n);\nconst I128_MAX = (1n << 127n) - 1n;\n\n/**\n * Non-empty trimmed string of decimal digits only: `\"0\"` or `[1-9]\\\\d*` (no leading zeros\n * except a single zero). Rejects fractions, scientific notation, hex prefixes, and trailing junk.\n */\nfunction requireDecimalUIntString(value: string, field: string): string {\n const t = value.trim();\n if (t === \"\") {\n throw new ValidationError(field, `\"${value}\" is not a valid number`);\n }\n if (!/^(0|[1-9]\\d*)$/.test(t)) {\n throw new ValidationError(\n field,\n `\"${value}\" is not a valid non-negative integer (use decimal digits only, e.g. 123).`\n );\n }\n return t;\n}\n\nexport class ValidationError extends Error {\n constructor(\n public readonly field: string,\n message: string\n ) {\n super(`Invalid ${field}: ${message}`);\n this.name = \"ValidationError\";\n }\n}\n\n/**\n * Validate a public key string.\n */\nexport function validatePublicKey(value: string, field: string): PublicKey {\n try {\n return new PublicKey(value);\n } catch {\n throw new ValidationError(\n field,\n `\"${value}\" is not a valid base58 public key. ` +\n `Example: \"11111111111111111111111111111111\"`\n );\n }\n}\n\n/**\n * Validate a non-negative integer index (u16 range for accounts).\n */\nexport function validateIndex(value: string, field: string): number {\n const t = requireDecimalUIntString(value, field);\n const bi = BigInt(t);\n if (bi > BigInt(U16_MAX)) {\n throw new ValidationError(\n field,\n `must be <= ${U16_MAX} (u16 max), got ${t}`\n );\n }\n return Number(bi);\n}\n\n/**\n * Validate a non-negative amount (u64 range).\n */\nexport function validateAmount(value: string, field: string): bigint {\n let num: bigint;\n try {\n num = BigInt(value);\n } catch {\n throw new ValidationError(\n field,\n `\"${value}\" is not a valid number. Use decimal digits only.`\n );\n }\n if (num < 0n) {\n throw new ValidationError(field, `must be non-negative, got ${num}`);\n }\n if (num > U64_MAX) {\n throw new ValidationError(\n field,\n `must be <= ${U64_MAX} (u64 max), got ${num}`\n );\n }\n return num;\n}\n\n/**\n * Validate a u128 value.\n */\nexport function validateU128(value: string, field: string): bigint {\n let num: bigint;\n try {\n num = BigInt(value);\n } catch {\n throw new ValidationError(\n field,\n `\"${value}\" is not a valid number. Use decimal digits only.`\n );\n }\n if (num < 0n) {\n throw new ValidationError(field, `must be non-negative, got ${num}`);\n }\n if (num > U128_MAX) {\n throw new ValidationError(\n field,\n `must be <= ${U128_MAX} (u128 max), got ${num}`\n );\n }\n return num;\n}\n\n/**\n * Validate an i64 value.\n */\nexport function validateI64(value: string, field: string): bigint {\n let num: bigint;\n try {\n num = BigInt(value);\n } catch {\n throw new ValidationError(\n field,\n `\"${value}\" is not a valid number. Use decimal digits only, with optional leading minus.`\n );\n }\n if (num < I64_MIN) {\n throw new ValidationError(\n field,\n `must be >= ${I64_MIN} (i64 min), got ${num}`\n );\n }\n if (num > I64_MAX) {\n throw new ValidationError(\n field,\n `must be <= ${I64_MAX} (i64 max), got ${num}`\n );\n }\n return num;\n}\n\n/**\n * Validate an i128 value (trade sizes).\n */\nexport function validateI128(value: string, field: string): bigint {\n let num: bigint;\n try {\n num = BigInt(value);\n } catch {\n throw new ValidationError(\n field,\n `\"${value}\" is not a valid number. Use decimal digits only, with optional leading minus.`\n );\n }\n if (num < I128_MIN) {\n throw new ValidationError(\n field,\n `must be >= ${I128_MIN} (i128 min), got ${num}`\n );\n }\n if (num > I128_MAX) {\n throw new ValidationError(\n field,\n `must be <= ${I128_MAX} (i128 max), got ${num}`\n );\n }\n return num;\n}\n\n/**\n * Validate a basis points value (0-10000).\n */\nexport function validateBps(value: string, field: string): number {\n const t = requireDecimalUIntString(value, field);\n const bi = BigInt(t);\n if (bi > 10000n) {\n throw new ValidationError(\n field,\n `must be <= 10000 (100%), got ${t}`\n );\n }\n return Number(bi);\n}\n\n/**\n * Validate a u64 value.\n */\nexport function validateU64(value: string, field: string): bigint {\n return validateAmount(value, field);\n}\n\n/**\n * Validate a u16 value.\n */\nexport function validateU16(value: string, field: string): number {\n const t = requireDecimalUIntString(value, field);\n const bi = BigInt(t);\n if (bi > BigInt(U16_MAX)) {\n throw new ValidationError(\n field,\n `must be <= ${U16_MAX} (u16 max), got ${t}`\n );\n }\n return Number(bi);\n}\n","/**\n * Smart Price Router — automatic oracle selection for any token.\n *\n * Given a token mint, discovers all available price sources (DexScreener, Pyth, Jupiter),\n * ranks them by liquidity/reliability, and returns the best oracle config.\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type PriceSourceType = \"pyth\" | \"dex\" | \"jupiter\";\n\nexport interface PriceSource {\n type: PriceSourceType;\n /** Pool address (dex), Pyth feed ID (pyth), or mint (jupiter) */\n address: string;\n /** DEX id for dex sources */\n dexId?: string;\n /** Pair label e.g. \"SOL / USDC\" */\n pairLabel?: string;\n /** USD liquidity depth — higher is better */\n liquidity: number;\n /** Latest spot price in USD */\n price: number;\n /** Confidence score 0-100 (composite of liquidity, staleness, reliability) */\n confidence: number;\n}\n\nexport interface PriceRouterResult {\n mint: string;\n bestSource: PriceSource | null;\n allSources: PriceSource[];\n /** ISO timestamp of resolution */\n resolvedAt: string;\n}\n\n/** Options for {@link resolvePrice}. */\nexport interface ResolvePriceOptions {\n timeoutMs?: number;\n}\n\nconst DEFAULT_RESOLVE_TIMEOUT_MS = 15_000;\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction combineAbortSignals(signals: AbortSignal[]): AbortSignal {\n const already = signals.find((s) => s.aborted);\n if (already) {\n const c = new AbortController();\n c.abort(already.reason);\n return c.signal;\n }\n const active = signals.filter((s) => !s.aborted);\n if (active.length === 0) {\n const c = new AbortController();\n c.abort();\n return c.signal;\n }\n if (active.length === 1) return active[0];\n const ctrl = new AbortController();\n for (const s of active) {\n s.addEventListener(\"abort\", () => ctrl.abort(s.reason), { once: true });\n }\n return ctrl.signal;\n}\n\nconst SUPPORTED_DEX_IDS = new Set([\"pumpswap\", \"raydium\", \"meteora\"]);\n\nfunction parseDexScreenerPairs(json: unknown): PriceSource[] {\n if (!isRecord(json)) return [];\n const rawPairs = json.pairs;\n if (!Array.isArray(rawPairs)) return [];\n const sources: PriceSource[] = [];\n\n for (const pair of rawPairs) {\n if (!isRecord(pair)) continue;\n if (pair.chainId !== \"solana\") continue;\n const dexId = String(pair.dexId || \"\").toLowerCase();\n if (!SUPPORTED_DEX_IDS.has(dexId)) continue;\n\n let liquidity = 0;\n if (isRecord(pair.liquidity) && typeof pair.liquidity.usd === \"number\") {\n liquidity = pair.liquidity.usd;\n }\n if (liquidity < 100) continue;\n\n let confidence = 30;\n if (liquidity > 1_000_000) confidence = 90;\n else if (liquidity > 100_000) confidence = 75;\n else if (liquidity > 10_000) confidence = 60;\n else if (liquidity > 1_000) confidence = 45;\n\n const priceUsd = pair.priceUsd;\n const price =\n typeof priceUsd === \"string\" || typeof priceUsd === \"number\"\n ? parseFloat(String(priceUsd)) || 0\n : 0;\n\n let baseSym = \"?\";\n let quoteSym = \"?\";\n if (isRecord(pair.baseToken) && typeof pair.baseToken.symbol === \"string\") {\n baseSym = pair.baseToken.symbol;\n }\n if (isRecord(pair.quoteToken) && typeof pair.quoteToken.symbol === \"string\") {\n quoteSym = pair.quoteToken.symbol;\n }\n\n const addr = pair.pairAddress;\n sources.push({\n type: \"dex\",\n address: typeof addr === \"string\" ? addr : \"\",\n dexId,\n pairLabel: `${baseSym} / ${quoteSym}`,\n liquidity,\n price,\n confidence,\n });\n }\n\n sources.sort((a, b) => b.liquidity - a.liquidity);\n return sources.slice(0, 10);\n}\n\nfunction parseJupiterMintEntry(\n json: unknown,\n mint: string,\n): { price: number; mintSymbol: string } | null {\n if (!isRecord(json)) return null;\n const data = json.data;\n if (!isRecord(data)) return null;\n const row = data[mint];\n if (!isRecord(row)) return null;\n const rawPrice = row.price;\n if (rawPrice === undefined || rawPrice === null) return null;\n const price = parseFloat(String(rawPrice)) || 0;\n if (price <= 0) return null;\n let mintSymbol = \"?\";\n if (typeof row.mintSymbol === \"string\") mintSymbol = row.mintSymbol;\n return { price, mintSymbol };}\n\n// ---------------------------------------------------------------------------\n// Top Solana tokens with known Pyth feeds (feed ID → symbol)\n// ---------------------------------------------------------------------------\n\nexport const PYTH_SOLANA_FEEDS: Record<string, { symbol: string; mint: string }> = {\n // SOL\n \"ef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d\": { symbol: \"SOL\", mint: \"So11111111111111111111111111111111111111112\" },\n // BTC\n \"e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43\": { symbol: \"BTC\", mint: \"9n4nbM75f5Ui33ZbPYXn59EwSgE8CGsHtAeTH5YFeJ9E\" },\n // ETH\n \"ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace\": { symbol: \"ETH\", mint: \"7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs\" },\n // USDC\n \"eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a\": { symbol: \"USDC\", mint: \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\" },\n // USDT\n \"2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b\": { symbol: \"USDT\", mint: \"Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB\" },\n // BONK\n \"72b021217ca3fe68922a19aaf990109cb9d84e9ad004b4d2025ad6f529314419\": { symbol: \"BONK\", mint: \"DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263\" },\n // JTO\n \"b43660a5f790c69354b0729a5ef9d50d68f1df92107540210b9cccba1f947cc2\": { symbol: \"JTO\", mint: \"jtojtomepa8beP8AuQc6eXt5FriJwfFMwQx2v2f9mCL\" },\n // JUP\n \"0a0408d619e9380abad35060f9192039ed5042fa6f82301d0e48bb52be830996\": { symbol: \"JUP\", mint: \"JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN\" },\n // PYTH\n \"0bbf28e9a841a1cc788f6a361b17ca072d0ea3098a1e5df1c3922d06719579ff\": { symbol: \"PYTH\", mint: \"HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3\" },\n // RAY\n \"91568bae053f70f0c3fbf32eb55df25ec609fb8a21cfb1a0e3b34fc3caa1eab0\": { symbol: \"RAY\", mint: \"4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R\" },\n // ORCA\n \"37505261e557e251f40c2c721e52c4c8bfb2e54a12f450d0e24078276ad51b95\": { symbol: \"ORCA\", mint: \"orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE\" },\n // MNGO\n \"f9abf5eb70a2e68e21b72b68cc6e0a4d25e1d77e1ec16eae5b93068a2cb81f90\": { symbol: \"MNGO\", mint: \"MangoCzJ36AjZyKwVj3VnYU4GTonjfVEnJmvvWaxLac\" },\n // MSOL\n \"c2289a6a43d2ce91c6f55caec370f4acc38a2ed477f58813334c6d03749ff2a4\": { symbol: \"MSOL\", mint: \"mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So\" },\n // JITOSOL\n \"67be9f519b95cf24338801051f9a808eff0a578ccb388db73b7f6fe1de019ffb\": { symbol: \"JITOSOL\", mint: \"J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn\" },\n // WIF\n \"4ca4beeca86f0d164160323817a4e42b10010a724c2217c6ee41b54e6c5c4b03\": { symbol: \"WIF\", mint: \"EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm\" },\n // RENDER\n \"3573eb14b04aa0e4f7cf1e7ae1c2a0e3bc6100b2e476876ca079e10e2c42d7c6\": { symbol: \"RENDER\", mint: \"rndrizKT3MK1iimdxRdWabcF7Zg7AR5T4nud4EkHBof\" },\n // W\n \"eff7446475e218517566ea99e72a4abec2e1bd8498b43b7d8331e29dcb059389\": { symbol: \"W\", mint: \"85VBFQZC9TZkfaptBWjvUw7YbZjy52A6mjtPGjstQAmQ\" },\n // TNSR\n \"05ecd4597cd48fe13d6cc3596c62af4f9675aee06e2e0ca164a73be4b0813f3b\": { symbol: \"TNSR\", mint: \"TNSRxcUxoT9xBG3de7PiJyTDYu7kskLqcpddxnEJAS6\" },\n // HNT\n \"649fdd7ec08e8e2a20f425729854e90293dcbe2376abc47197a14da6ff339756\": { symbol: \"HNT\", mint: \"hntyVP6YFm1Hg25TN9WGLqM12b8TQmcknKrdu1oxWux\" },\n // MOBILE\n \"ff4c53361e36a9b1caa490f1e46e07e3c472d54d2a4856a1e4609bd4db36bff0\": { symbol: \"MOBILE\", mint: \"mb1eu7TzEc71KxDpsmsKoucSSuuoGLv1drys1oP2jh6\" },\n // IOT\n \"8bdd20f0c68bf7370a19389bbb3d17c1db7956c38efa08b2f3dd0e5db9b8c1ef\": { symbol: \"IOT\", mint: \"iotEVVZLEywoTn1QdwNPddxPWszn3zFhEot3MfL9fns\" },\n};\n\n// Reverse lookup: mint → feed ID\nconst MINT_TO_PYTH_FEED = new Map<string, { feedId: string; symbol: string }>();\nfor (const [feedId, info] of Object.entries(PYTH_SOLANA_FEEDS)) {\n MINT_TO_PYTH_FEED.set(info.mint, { feedId, symbol: info.symbol });\n}\n\n// ---------------------------------------------------------------------------\n// DexScreener fetcher\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_FETCH_TIMEOUT_MS = 10_000;\n\nfunction effectiveSignal(signal?: AbortSignal): AbortSignal {\n return signal ?? AbortSignal.timeout(DEFAULT_FETCH_TIMEOUT_MS);\n}\n\nasync function fetchDexSources(mint: string, signal?: AbortSignal): Promise<PriceSource[]> {\n try {\n const resp = await fetch(\n `https://api.dexscreener.com/latest/dex/tokens/${encodeURIComponent(mint)}`,\n {\n signal: effectiveSignal(signal),\n headers: { \"User-Agent\": \"percolator/1.0\" },\n },\n );\n if (!resp.ok) return [];\n const json: unknown = await resp.json();\n return parseDexScreenerPairs(json);\n } catch {\n return [];\n }\n}\n\n// ---------------------------------------------------------------------------\n// Pyth lookup\n// ---------------------------------------------------------------------------\n\nfunction lookupPythSource(mint: string): PriceSource | null {\n const entry = MINT_TO_PYTH_FEED.get(mint);\n if (!entry) return null;\n return {\n type: \"pyth\",\n address: entry.feedId,\n pairLabel: `${entry.symbol} / USD (Pyth)`,\n liquidity: Infinity, // Pyth is considered deep liquidity\n price: 0, // We don't fetch live price here; caller can enrich\n confidence: 95, // Pyth is highest reliability for supported tokens\n };\n}\n\n// ---------------------------------------------------------------------------\n// Jupiter price fallback\n// ---------------------------------------------------------------------------\n\nasync function fetchJupiterSource(mint: string, signal?: AbortSignal): Promise<PriceSource | null> {\n try {\n const resp = await fetch(\n `https://api.jup.ag/price/v2?ids=${encodeURIComponent(mint)}`,\n {\n signal: effectiveSignal(signal),\n headers: { \"User-Agent\": \"percolator/1.0\" },\n },\n );\n if (!resp.ok) return null;\n const json: unknown = await resp.json();\n const row = parseJupiterMintEntry(json, mint);\n if (!row) return null;\n return {\n type: \"jupiter\",\n address: mint,\n pairLabel: `${row.mintSymbol} / USD (Jupiter)`,\n liquidity: 0, // Jupiter aggregator — no single pool liquidity\n price: row.price,\n confidence: 40, // Fallback — lower confidence\n };\n } catch {\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Main resolver\n// ---------------------------------------------------------------------------\n\nexport async function resolvePrice(\n mint: string,\n signal?: AbortSignal,\n options?: ResolvePriceOptions,\n): Promise<PriceRouterResult> {\n const timeoutMs = options?.timeoutMs ?? DEFAULT_RESOLVE_TIMEOUT_MS;\n const timeoutSignal = AbortSignal.timeout(timeoutMs);\n const effectiveSignal = signal\n ? combineAbortSignals([signal, timeoutSignal])\n : timeoutSignal;\n\n const [dexSources, jupiterSource] = await Promise.all([\n fetchDexSources(mint, effectiveSignal),\n fetchJupiterSource(mint, effectiveSignal),\n ]);\n\n const pythSource = lookupPythSource(mint);\n\n const allSources: PriceSource[] = [];\n\n // Add Pyth if available (highest priority for supported tokens)\n if (pythSource) {\n // Enrich Pyth price from Jupiter or DEX if available\n const refPrice = dexSources[0]?.price || jupiterSource?.price || 0;\n pythSource.price = refPrice;\n allSources.push(pythSource);\n }\n\n // Add DEX sources\n allSources.push(...dexSources);\n\n // Add Jupiter as fallback\n if (jupiterSource) {\n allSources.push(jupiterSource);\n }\n\n // Sort by confidence descending (already accounts for liquidity/reliability)\n allSources.sort((a, b) => b.confidence - a.confidence);\n\n return {\n mint,\n bestSource: allSources[0] || null,\n allSources,\n resolvedAt: new Date().toISOString(),\n };\n}\n"],"mappings":"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AAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA;AAAA,EAEA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;A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","names":["dv","PublicKey","PublicKey","AccountKind","PublicKey","PublicKey","PublicKey","TOKEN_PROGRAM_ID","ENGINE_BITMAP_OFF_V0","dv","readU16LE","readU64LE","readI64LE","readU128LE","readI128LE","results","PublicKey","PublicKey","readU64LE","dv","readU128LE","readU8","PublicKey","TOKEN_PROGRAM_ID","PublicKey","SystemProgram","SYSVAR_RENT_PUBKEY","SYSVAR_CLOCK_PUBKEY","TOKEN_PROGRAM_ID","PublicKey","PublicKey","readU64LE","readU16LE","TOKEN_PROGRAM_ID","SystemProgram","SYSVAR_RENT_PUBKEY","SYSVAR_CLOCK_PUBKEY","SYSVAR_CLOCK_PUBKEY","SYSVAR_CLOCK_PUBKEY","TransactionInstruction","TransactionInstruction","PublicKey","effectiveSignal"]}
1
+ {"version":3,"sources":["../src/abi/encode.ts","../src/abi/instructions.ts","../src/abi/accounts.ts","../src/abi/errors.ts","../src/solana/slab.ts","../src/solana/pda.ts","../src/solana/ata.ts","../src/solana/discovery.ts","../src/solana/dex-oracle.ts","../src/solana/oracle.ts","../src/solana/token-program.ts","../src/solana/stake.ts","../src/config/program-ids.ts","../src/solana/adl.ts","../src/runtime/tx.ts","../src/math/trading.ts","../src/math/warmup.ts","../src/validation.ts","../src/oracle/price-router.ts"],"sourcesContent":["import { PublicKey } from \"@solana/web3.js\";\n\nconst U8_MAX = 255;\nconst U16_MAX = 65_535;\nconst U32_MAX = 4_294_967_295;\n\n/**\n * Encode u8 (1 byte)\n */\nexport function encU8(val: number): Uint8Array {\n if (!Number.isInteger(val) || val < 0 || val > 0xFF) {\n throw new Error(`encU8: value out of range (0..255), got ${val}`);\n }\n return new Uint8Array([val]);\n}\n\n/**\n * Encode u16 little-endian (2 bytes)\n */\nexport function encU16(val: number): Uint8Array {\n if (!Number.isInteger(val) || val < 0 || val > 0xFFFF) {\n throw new Error(`encU16: value out of range (0..65535), got ${val}`);\n }\n const buf = new Uint8Array(2);\n new DataView(buf.buffer).setUint16(0, val, true);\n return buf;\n}\n\n/**\n * Encode u32 little-endian (4 bytes)\n */\nexport function encU32(val: number): Uint8Array {\n if (!Number.isInteger(val) || val < 0 || val > 0xFFFFFFFF) {\n throw new Error(`encU32: value out of range (0..4294967295), got ${val}`);\n }\n const buf = new Uint8Array(4);\n new DataView(buf.buffer).setUint32(0, val, true);\n return buf;\n}\n\n/**\n * Encode u64 little-endian (8 bytes)\n * Input: bigint or string (decimal)\n */\nexport function encU64(val: bigint | string): Uint8Array {\n const n = typeof val === \"string\" ? BigInt(val) : val;\n if (n < 0n) throw new Error(\"encU64: value must be non-negative\");\n if (n > 0xffff_ffff_ffff_ffffn) throw new Error(\"encU64: value exceeds u64 max\");\n const buf = new Uint8Array(8);\n new DataView(buf.buffer).setBigUint64(0, n, true);\n return buf;\n}\n\n/**\n * Encode i64 little-endian (8 bytes), two's complement\n * Input: bigint or string (decimal, may be negative)\n */\nexport function encI64(val: bigint | string): Uint8Array {\n const n = typeof val === \"string\" ? BigInt(val) : val;\n const min = -(1n << 63n);\n const max = (1n << 63n) - 1n;\n if (n < min || n > max) throw new Error(\"encI64: value out of range\");\n const buf = new Uint8Array(8);\n new DataView(buf.buffer).setBigInt64(0, n, true);\n return buf;\n}\n\n/**\n * Encode u128 little-endian (16 bytes)\n * Input: bigint or string (decimal)\n */\nexport function encU128(val: bigint | string): Uint8Array {\n const n = typeof val === \"string\" ? BigInt(val) : val;\n if (n < 0n) throw new Error(\"encU128: value must be non-negative\");\n const max = (1n << 128n) - 1n;\n if (n > max) throw new Error(\"encU128: value exceeds u128 max\");\n const buf = new Uint8Array(16);\n const view = new DataView(buf.buffer);\n const lo = n & 0xffff_ffff_ffff_ffffn;\n const hi = n >> 64n;\n view.setBigUint64(0, lo, true);\n view.setBigUint64(8, hi, true);\n return buf;\n}\n\n/**\n * Encode i128 little-endian (16 bytes), two's complement\n * Input: bigint or string (decimal, may be negative)\n */\nexport function encI128(val: bigint | string): Uint8Array {\n const n = typeof val === \"string\" ? BigInt(val) : val;\n const min = -(1n << 127n);\n const max = (1n << 127n) - 1n;\n if (n < min || n > max) throw new Error(\"encI128: value out of range\");\n\n // Convert to unsigned representation (two's complement)\n let unsigned = n;\n if (n < 0n) {\n unsigned = (1n << 128n) + n;\n }\n\n const buf = new Uint8Array(16);\n const view = new DataView(buf.buffer);\n const lo = unsigned & 0xffff_ffff_ffff_ffffn;\n const hi = unsigned >> 64n;\n view.setBigUint64(0, lo, true);\n view.setBigUint64(8, hi, true);\n return buf;\n}\n\n/**\n * Encode a PublicKey (32 bytes)\n * Input: PublicKey or base58 string\n */\nexport function encPubkey(val: PublicKey | string): Uint8Array {\n try {\n const pk = typeof val === \"string\" ? new PublicKey(val) : val;\n return pk.toBytes();\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n throw new Error(`encPubkey: invalid public key \"${String(val)}\" — ${msg}`);\n }\n}\n\n/**\n * Encode a boolean as u8 (0 = false, 1 = true)\n */\nexport function encBool(val: boolean): Uint8Array {\n return encU8(val ? 1 : 0);\n}\n\n/**\n * Concatenate multiple Uint8Arrays (replaces Buffer.concat)\n */\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n const totalLen = arrays.reduce((sum, a) => sum + a.length, 0);\n const result = new Uint8Array(totalLen);\n let offset = 0;\n for (const arr of arrays) {\n result.set(arr, offset);\n offset += arr.length;\n }\n return result;\n}\n","import { PublicKey } from \"@solana/web3.js\";\nimport {\n encU8,\n encU16,\n encU32,\n encU64,\n encI64,\n encU128,\n encI128,\n encPubkey,\n concatBytes,\n} from \"./encode.js\";\n\n/**\n * Instruction tags - exact match to Rust ix::Instruction::decode\n */\nexport const IX_TAG = {\n InitMarket: 0,\n InitUser: 1,\n InitLP: 2,\n DepositCollateral: 3,\n WithdrawCollateral: 4,\n KeeperCrank: 5,\n TradeNoCpi: 6,\n LiquidateAtOracle: 7,\n CloseAccount: 8,\n TopUpInsurance: 9,\n TradeCpi: 10,\n SetRiskThreshold: 11,\n UpdateAdmin: 12,\n CloseSlab: 13,\n UpdateConfig: 14,\n SetMaintenanceFee: 15,\n SetOracleAuthority: 16,\n PushOraclePrice: 17,\n SetOraclePriceCap: 18,\n ResolveMarket: 19,\n WithdrawInsurance: 20,\n AdminForceClose: 21,\n UpdateRiskParams: 22,\n RenounceAdmin: 23,\n CreateInsuranceMint: 24,\n DepositInsuranceLP: 25,\n WithdrawInsuranceLP: 26,\n PauseMarket: 27,\n UnpauseMarket: 28,\n AcceptAdmin: 29,\n SetInsuranceWithdrawPolicy: 30,\n WithdrawInsuranceLimited: 31,\n SetPythOracle: 32,\n UpdateMarkPrice: 33,\n UpdateHyperpMark: 34,\n TradeCpiV2: 35,\n UnresolveMarket: 36,\n CreateLpVault: 37,\n LpVaultDeposit: 38,\n LpVaultWithdraw: 39,\n LpVaultCrankFees: 40,\n /** PERC-306: Fund per-market isolated insurance balance */\n FundMarketInsurance: 41,\n /** PERC-306: Set insurance isolation BPS for a market */\n SetInsuranceIsolation: 42,\n // Tag 43 is ChallengeSettlement on-chain (PERC-314).\n // PERC-305 (ExecuteAdl) is NOT implemented on-chain — do NOT assign tag 43 here.\n // When PERC-305 is implemented, assign a new unused tag (≥47).\n /** PERC-314: Challenge settlement price during dispute window */\n ChallengeSettlement: 43,\n /** PERC-314: Resolve dispute (admin adjudication) */\n ResolveDispute: 44,\n /** PERC-315: Deposit LP vault tokens as perp collateral */\n DepositLpCollateral: 45,\n /** PERC-315: Withdraw LP collateral (position must be closed) */\n WithdrawLpCollateral: 46,\n /** PERC-309: Queue a large LP withdrawal (user; creates withdraw_queue PDA). */\n QueueWithdrawal: 47,\n /** PERC-309: Claim one epoch tranche from a queued LP withdrawal (user). */\n ClaimQueuedWithdrawal: 48,\n /** PERC-309: Cancel a queued withdrawal, refund remaining LP tokens (user). */\n CancelQueuedWithdrawal: 49,\n /** PERC-305: Auto-deleverage — surgically close profitable positions when PnL cap is exceeded (permissionless). */\n ExecuteAdl: 50,\n /** Close a stale slab of an invalid/old layout and recover rent SOL (admin only). */\n CloseStaleSlabs: 51,\n /** Reclaim rent from an uninitialised slab whose market creation failed mid-flow. Slab must sign. */\n ReclaimSlabRent: 52,\n /** Permissionless on-chain audit crank: verifies conservation invariants and pauses market on violation. */\n AuditCrank: 53,\n /** Cross-Market Portfolio Margining: SetOffsetPair */\n SetOffsetPair: 54,\n /** Cross-Market Portfolio Margining: AttestCrossMargin */\n AttestCrossMargin: 55,\n /** PERC-622: Advance oracle phase (permissionless crank) */\n AdvanceOraclePhase: 56,\n /** PERC-623: Top up a market's keeper fund (permissionless) */\n TopUpKeeperFund: 57,\n /** PERC-629: Slash a market creator's deposit (permissionless) */\n SlashCreationDeposit: 58,\n /** PERC-628: Initialize the global shared vault (admin) */\n InitSharedVault: 59,\n /** PERC-628: Allocate virtual liquidity to a market (admin) */\n AllocateMarket: 60,\n /** PERC-628: Queue a withdrawal for the current epoch */\n QueueWithdrawalSV: 61,\n /** PERC-628: Claim a queued withdrawal after epoch elapses */\n ClaimEpochWithdrawal: 62,\n /** PERC-628: Advance the shared vault epoch (permissionless crank) */\n AdvanceEpoch: 63,\n /** PERC-608: Mint a Position NFT for a user's open position. */\n MintPositionNft: 64,\n /** PERC-608: Transfer position ownership via the NFT (keeper-gated). */\n TransferPositionOwnership: 65,\n /** PERC-608: Burn the Position NFT when a position is closed. */\n BurnPositionNft: 66,\n /** PERC-608: Keeper sets pending_settlement flag before a funding transfer. */\n SetPendingSettlement: 67,\n /** PERC-608: Keeper clears pending_settlement flag after KeeperCrank. */\n ClearPendingSettlement: 68,\n /** PERC-608: Internal CPI call from percolator-nft TransferHook to update on-chain owner. */\n TransferOwnershipCpi: 69,\n /** PERC-8111: Set per-wallet position cap (admin only, cap_e6=0 disables). */\n SetWalletCap: 70,\n /** PERC-8110: Set OI imbalance hard-block threshold (admin only). */\n SetOiImbalanceHardBlock: 71,\n} as const;\n\n/**\n * InitMarket instruction data (256 bytes total)\n * Layout: tag(1) + admin(32) + mint(32) + indexFeedId(32) +\n * maxStaleSecs(8) + confFilter(2) + invert(1) + unitScale(4) +\n * RiskParams(144)\n *\n * Note: indexFeedId is the Pyth Pull feed ID (32 bytes hex), NOT an oracle pubkey.\n * The program validates PriceUpdateV2 accounts against this feed ID at runtime.\n */\nexport interface InitMarketArgs {\n admin: PublicKey | string;\n collateralMint: PublicKey | string;\n indexFeedId: string; // Pyth feed ID (hex string, 64 chars without 0x prefix). All zeros = Hyperp mode.\n maxStalenessSecs: bigint | string; // Max staleness in SECONDS (Pyth Pull uses unix timestamps)\n confFilterBps: number;\n invert: number; // 0 = no inversion, 1 = invert oracle price (USD/SOL -> SOL/USD)\n unitScale: number; // Lamports per unit (0 = no scaling, e.g. 1000 = 1 SOL = 1,000,000 units)\n initialMarkPriceE6: bigint | string; // Initial mark price (required non-zero for Hyperp mode)\n warmupPeriodSlots: bigint | string;\n maintenanceMarginBps: bigint | string;\n initialMarginBps: bigint | string;\n tradingFeeBps: bigint | string;\n maxAccounts: bigint | string;\n newAccountFee: bigint | string;\n riskReductionThreshold: bigint | string;\n maintenanceFeePerSlot: bigint | string;\n maxCrankStalenessSlots: bigint | string;\n liquidationFeeBps: bigint | string;\n liquidationFeeCap: bigint | string;\n liquidationBufferBps: bigint | string;\n minLiquidationAbs: bigint | string;\n}\n\n/**\n * Encode a Pyth feed ID (hex string) to 32-byte Uint8Array.\n */\nconst HEX_RE = /^[0-9a-fA-F]{64}$/;\n\nfunction encodeFeedId(feedId: string): Uint8Array {\n const hex = feedId.startsWith(\"0x\") ? feedId.slice(2) : feedId;\n if (!HEX_RE.test(hex)) {\n throw new Error(\n `Invalid feed ID: expected 64 hex chars, got \"${hex.length === 64 ? \"non-hex characters\" : hex.length + \" chars\"}\"`,\n );\n }\n const bytes = new Uint8Array(32);\n for (let i = 0; i < 64; i += 2) {\n bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);\n }\n return bytes;\n}\n\nconst INIT_MARKET_DATA_LEN = 264;\n\nexport function encodeInitMarket(args: InitMarketArgs): Uint8Array {\n const data = concatBytes(\n encU8(IX_TAG.InitMarket),\n encPubkey(args.admin),\n encPubkey(args.collateralMint),\n encodeFeedId(args.indexFeedId),\n encU64(args.maxStalenessSecs),\n encU16(args.confFilterBps),\n encU8(args.invert),\n encU32(args.unitScale),\n encU64(args.initialMarkPriceE6),\n encU64(args.warmupPeriodSlots),\n encU64(args.maintenanceMarginBps),\n encU64(args.initialMarginBps),\n encU64(args.tradingFeeBps),\n encU64(args.maxAccounts),\n encU128(args.newAccountFee),\n encU128(args.riskReductionThreshold),\n encU128(args.maintenanceFeePerSlot),\n encU64(args.maxCrankStalenessSlots),\n encU64(args.liquidationFeeBps),\n encU128(args.liquidationFeeCap),\n encU64(args.liquidationBufferBps),\n encU128(args.minLiquidationAbs),\n );\n if (data.length !== INIT_MARKET_DATA_LEN) {\n throw new Error(\n `encodeInitMarket: expected ${INIT_MARKET_DATA_LEN} bytes, got ${data.length}`,\n );\n }\n return data;\n}\n\n/**\n * InitUser instruction data (9 bytes)\n */\nexport interface InitUserArgs {\n feePayment: bigint | string;\n}\n\nexport function encodeInitUser(args: InitUserArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.InitUser), encU64(args.feePayment));\n}\n\n/**\n * InitLP instruction data (73 bytes)\n */\nexport interface InitLPArgs {\n matcherProgram: PublicKey | string;\n matcherContext: PublicKey | string;\n feePayment: bigint | string;\n}\n\nexport function encodeInitLP(args: InitLPArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.InitLP),\n encPubkey(args.matcherProgram),\n encPubkey(args.matcherContext),\n encU64(args.feePayment),\n );\n}\n\n/**\n * DepositCollateral instruction data (11 bytes)\n */\nexport interface DepositCollateralArgs {\n userIdx: number;\n amount: bigint | string;\n}\n\nexport function encodeDepositCollateral(args: DepositCollateralArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.DepositCollateral),\n encU16(args.userIdx),\n encU64(args.amount),\n );\n}\n\n/**\n * WithdrawCollateral instruction data (11 bytes)\n */\nexport interface WithdrawCollateralArgs {\n userIdx: number;\n amount: bigint | string;\n}\n\nexport function encodeWithdrawCollateral(args: WithdrawCollateralArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.WithdrawCollateral),\n encU16(args.userIdx),\n encU64(args.amount),\n );\n}\n\n/**\n * KeeperCrank instruction data (4 bytes)\n * Funding rate is computed on-chain from LP inventory.\n */\nexport interface KeeperCrankArgs {\n callerIdx: number;\n allowPanic: boolean;\n}\n\nexport function encodeKeeperCrank(args: KeeperCrankArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.KeeperCrank),\n encU16(args.callerIdx),\n encU8(args.allowPanic ? 1 : 0),\n );\n}\n\n/**\n * TradeNoCpi instruction data (21 bytes)\n */\nexport interface TradeNoCpiArgs {\n lpIdx: number;\n userIdx: number;\n size: bigint | string;\n}\n\nexport function encodeTradeNoCpi(args: TradeNoCpiArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.TradeNoCpi),\n encU16(args.lpIdx),\n encU16(args.userIdx),\n encI128(args.size),\n );\n}\n\n/**\n * LiquidateAtOracle instruction data (3 bytes)\n */\nexport interface LiquidateAtOracleArgs {\n targetIdx: number;\n}\n\nexport function encodeLiquidateAtOracle(args: LiquidateAtOracleArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.LiquidateAtOracle),\n encU16(args.targetIdx),\n );\n}\n\n/**\n * CloseAccount instruction data (3 bytes)\n */\nexport interface CloseAccountArgs {\n userIdx: number;\n}\n\nexport function encodeCloseAccount(args: CloseAccountArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.CloseAccount), encU16(args.userIdx));\n}\n\n/**\n * TopUpInsurance instruction data (9 bytes)\n */\nexport interface TopUpInsuranceArgs {\n amount: bigint | string;\n}\n\nexport function encodeTopUpInsurance(args: TopUpInsuranceArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.TopUpInsurance), encU64(args.amount));\n}\n\n/**\n * TradeCpi instruction data (21 bytes)\n */\nexport interface TradeCpiArgs {\n lpIdx: number;\n userIdx: number;\n size: bigint | string;\n}\n\nexport function encodeTradeCpi(args: TradeCpiArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.TradeCpi),\n encU16(args.lpIdx),\n encU16(args.userIdx),\n encI128(args.size),\n );\n}\n\n/**\n * TradeCpiV2 instruction data (22 bytes) — PERC-154 optimized trade CPI.\n *\n * Same as TradeCpi but includes a caller-provided PDA bump byte.\n * Uses create_program_address instead of find_program_address,\n * saving ~1500 CU per trade. The bump should be obtained once via\n * deriveLpPda() and cached for the lifetime of the market.\n */\nexport interface TradeCpiV2Args {\n lpIdx: number;\n userIdx: number;\n size: bigint | string;\n bump: number;\n}\n\nexport function encodeTradeCpiV2(args: TradeCpiV2Args): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.TradeCpiV2),\n encU16(args.lpIdx),\n encU16(args.userIdx),\n encI128(args.size),\n encU8(args.bump),\n );\n}\n\n/**\n * SetRiskThreshold instruction data (17 bytes)\n */\nexport interface SetRiskThresholdArgs {\n newThreshold: bigint | string;\n}\n\nexport function encodeSetRiskThreshold(args: SetRiskThresholdArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.SetRiskThreshold),\n encU128(args.newThreshold),\n );\n}\n\n/**\n * UpdateAdmin instruction data (33 bytes)\n */\nexport interface UpdateAdminArgs {\n newAdmin: PublicKey | string;\n}\n\nexport function encodeUpdateAdmin(args: UpdateAdminArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.UpdateAdmin), encPubkey(args.newAdmin));\n}\n\n/**\n * CloseSlab instruction data (1 byte)\n */\nexport function encodeCloseSlab(): Uint8Array {\n return encU8(IX_TAG.CloseSlab);\n}\n\n/**\n * UpdateConfig instruction data\n * Updates funding and threshold parameters at runtime (admin only)\n */\nexport interface UpdateConfigArgs {\n // Funding parameters\n fundingHorizonSlots: bigint | string;\n fundingKBps: bigint | string;\n fundingInvScaleNotionalE6: bigint | string;\n fundingMaxPremiumBps: bigint | string;\n fundingMaxBpsPerSlot: bigint | string;\n // Threshold parameters\n threshFloor: bigint | string;\n threshRiskBps: bigint | string;\n threshUpdateIntervalSlots: bigint | string;\n threshStepBps: bigint | string;\n threshAlphaBps: bigint | string;\n threshMin: bigint | string;\n threshMax: bigint | string;\n threshMinStep: bigint | string;\n}\n\nexport function encodeUpdateConfig(args: UpdateConfigArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.UpdateConfig),\n encU64(args.fundingHorizonSlots),\n encU64(args.fundingKBps),\n encU128(args.fundingInvScaleNotionalE6),\n encI64(args.fundingMaxPremiumBps), // Rust: i64 (can be negative)\n encI64(args.fundingMaxBpsPerSlot), // Rust: i64 (can be negative)\n encU128(args.threshFloor),\n encU64(args.threshRiskBps),\n encU64(args.threshUpdateIntervalSlots),\n encU64(args.threshStepBps),\n encU64(args.threshAlphaBps),\n encU128(args.threshMin),\n encU128(args.threshMax),\n encU128(args.threshMinStep),\n );\n}\n\n/**\n * SetMaintenanceFee instruction data (17 bytes)\n */\nexport interface SetMaintenanceFeeArgs {\n newFee: bigint | string;\n}\n\nexport function encodeSetMaintenanceFee(args: SetMaintenanceFeeArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.SetMaintenanceFee),\n encU128(args.newFee),\n );\n}\n\n/**\n * SetOracleAuthority instruction data (33 bytes)\n * Sets the oracle price authority. Pass zero pubkey to disable and require Pyth/Chainlink.\n */\nexport interface SetOracleAuthorityArgs {\n newAuthority: PublicKey | string;\n}\n\nexport function encodeSetOracleAuthority(args: SetOracleAuthorityArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.SetOracleAuthority),\n encPubkey(args.newAuthority),\n );\n}\n\n/**\n * PushOraclePrice instruction data (17 bytes)\n * Push a new oracle price (oracle authority only).\n * The price should be in e6 format and already include any inversion/scaling.\n */\nexport interface PushOraclePriceArgs {\n priceE6: bigint | string;\n timestamp: bigint | string;\n}\n\nexport function encodePushOraclePrice(args: PushOraclePriceArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.PushOraclePrice),\n encU64(args.priceE6),\n encI64(args.timestamp),\n );\n}\n\n/**\n * SetOraclePriceCap instruction data (9 bytes)\n * Set oracle price circuit breaker cap (admin only).\n *\n * max_change_e2bps: maximum oracle price movement per slot in 0.01 bps units.\n * 1_000_000 = 100% max move per slot.\n *\n * ⚠️ PERC-8191 (PR#150): cap=0 is NO LONGER accepted for admin-oracle markets.\n * - Hyperp markets: rejected if cap < DEFAULT_HYPERP_PRICE_CAP_E2BPS (1000).\n * - Admin-oracle markets: rejected if cap == 0 (circuit breaker bypass prevention).\n * - Pyth-pinned markets: immune (oracle_authority zeroed), any value accepted.\n *\n * Use a non-zero cap for all admin-oracle and Hyperp markets.\n */\nexport interface SetOraclePriceCapArgs {\n maxChangeE2bps: bigint | string;\n}\n\nexport function encodeSetOraclePriceCap(args: SetOraclePriceCapArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.SetOraclePriceCap),\n encU64(args.maxChangeE2bps),\n );\n}\n\n/**\n * ResolveMarket instruction data (1 byte)\n * Resolves a binary/premarket - sets RESOLVED flag, positions force-closed via crank.\n * Requires admin oracle price (authority_price_e6) to be set first.\n */\nexport function encodeResolveMarket(): Uint8Array {\n return encU8(IX_TAG.ResolveMarket);\n}\n\n/**\n * WithdrawInsurance instruction data (1 byte)\n * Withdraw insurance fund to admin (requires RESOLVED and all positions closed).\n */\nexport function encodeWithdrawInsurance(): Uint8Array {\n return encU8(IX_TAG.WithdrawInsurance);\n}\n\n/**\n * AdminForceClose instruction data (3 bytes)\n * Force-close any position at oracle price (admin only, skips margin checks).\n */\nexport interface AdminForceCloseArgs {\n targetIdx: number;\n}\n\nexport function encodeAdminForceClose(args: AdminForceCloseArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.AdminForceClose),\n encU16(args.targetIdx),\n );\n}\n\n/**\n * UpdateRiskParams instruction data (17 or 25 bytes)\n * Update initial and maintenance margin BPS (admin only).\n *\n * R2-S13: The Rust program uses `data.len() >= 25` to detect the optional\n * tradingFeeBps field, so variable-length encoding is safe. When tradingFeeBps\n * is omitted, the data is 17 bytes (tag + 2×u64). When included, 25 bytes.\n */\nexport interface UpdateRiskParamsArgs {\n initialMarginBps: bigint | string;\n maintenanceMarginBps: bigint | string;\n tradingFeeBps?: bigint | string;\n}\n\nexport function encodeUpdateRiskParams(args: UpdateRiskParamsArgs): Uint8Array {\n const parts = [\n encU8(IX_TAG.UpdateRiskParams),\n encU64(args.initialMarginBps),\n encU64(args.maintenanceMarginBps),\n ];\n if (args.tradingFeeBps !== undefined) {\n parts.push(encU64(args.tradingFeeBps));\n }\n return concatBytes(...parts);\n}\n\n/**\n * On-chain confirmation code for RenounceAdmin (must match program constant).\n * ASCII \"RENOUNCE\" as u64 LE = 0x52454E4F554E4345.\n */\nexport const RENOUNCE_ADMIN_CONFIRMATION = 0x52454E4F554E4345n;\n\n/**\n * On-chain confirmation code for UnresolveMarket (must match program constant).\n */\nexport const UNRESOLVE_CONFIRMATION = 0xDEAD_BEEF_CAFE_1234n;\n\n/**\n * RenounceAdmin instruction data (9 bytes)\n * Irreversibly set admin to all zeros. After this, all admin-only instructions fail.\n *\n * Requires the confirmation code 0x52454E4F554E4345 (\"RENOUNCE\" as u64 LE)\n * to prevent accidental invocation.\n */\nexport function encodeRenounceAdmin(): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.RenounceAdmin),\n encU64(RENOUNCE_ADMIN_CONFIRMATION),\n );\n}\n\n/**\n * CreateInsuranceMint instruction data (1 byte)\n * Creates the SPL mint PDA for insurance LP tokens. Admin only, once per market.\n */\nexport function encodeCreateInsuranceMint(): Uint8Array {\n return encU8(IX_TAG.CreateInsuranceMint);\n}\n\n/**\n * DepositInsuranceLP instruction data (9 bytes)\n * Deposit collateral into insurance fund, receive LP tokens proportional to share.\n */\nexport interface DepositInsuranceLPArgs {\n amount: bigint | string;\n}\n\nexport function encodeDepositInsuranceLP(args: DepositInsuranceLPArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.DepositInsuranceLP), encU64(args.amount));\n}\n\n/**\n * WithdrawInsuranceLP instruction data (9 bytes)\n * Burn LP tokens and withdraw proportional share of insurance fund.\n */\nexport interface WithdrawInsuranceLPArgs {\n lpAmount: bigint | string;\n}\n\nexport function encodeWithdrawInsuranceLP(args: WithdrawInsuranceLPArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.WithdrawInsuranceLP), encU64(args.lpAmount));\n}\n\n// ============================================================================\n// PERC-627 / GH#1926: LpVaultWithdraw (tag 39)\n// ============================================================================\n\n/**\n * LpVaultWithdraw (Tag 39, PERC-627 / GH#1926 / PERC-8287) — burn LP vault tokens and\n * withdraw proportional collateral.\n *\n * **BREAKING (PR#170):** accounts[9] = creatorLockPda is now REQUIRED.\n * Always include `deriveCreatorLockPda(programId, slab)` at position 9.\n * Non-creator withdrawers pass the derived PDA; if no lock exists on-chain\n * the check is a no-op. Omitting this account causes `ExpectLenFailed` on-chain.\n *\n * Instruction data: tag(1) + lp_amount(8) = 9 bytes\n *\n * Accounts (use ACCOUNTS_LP_VAULT_WITHDRAW):\n * [0] withdrawer signer\n * [1] slab writable\n * [2] withdrawerAta writable\n * [3] vault writable\n * [4] tokenProgram\n * [5] lpVaultMint writable\n * [6] withdrawerLpAta writable\n * [7] vaultAuthority\n * [8] lpVaultState writable\n * [9] creatorLockPda writable ← derive with deriveCreatorLockPda(programId, slab)\n *\n * @param lpAmount - Amount of LP vault tokens to burn.\n *\n * @example\n * ```ts\n * import { encodeLpVaultWithdraw, ACCOUNTS_LP_VAULT_WITHDRAW, buildAccountMetas } from \"@percolator/sdk\";\n * import { deriveCreatorLockPda, deriveVaultAuthority } from \"@percolator/sdk\";\n *\n * const [creatorLockPda] = deriveCreatorLockPda(PROGRAM_ID, slabKey);\n * const [vaultAuthority] = deriveVaultAuthority(PROGRAM_ID, slabKey);\n *\n * const data = encodeLpVaultWithdraw({ lpAmount: 1_000_000_000n });\n * const keys = buildAccountMetas(ACCOUNTS_LP_VAULT_WITHDRAW, {\n * withdrawer, slab: slabKey, withdrawerAta, vault, tokenProgram: TOKEN_PROGRAM_ID,\n * lpVaultMint, withdrawerLpAta, vaultAuthority, lpVaultState, creatorLockPda,\n * });\n * ```\n */\nexport interface LpVaultWithdrawArgs {\n /** Amount of LP vault tokens to burn. */\n lpAmount: bigint | string;\n}\n\nexport function encodeLpVaultWithdraw(args: LpVaultWithdrawArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.LpVaultWithdraw), encU64(args.lpAmount));\n}\n\n/**\n * PauseMarket instruction data (1 byte)\n * Pauses the market — disables trading, deposits, and withdrawals.\n */\nexport function encodePauseMarket(): Uint8Array {\n return encU8(IX_TAG.PauseMarket);\n}\n\n/**\n * UnpauseMarket instruction data (1 byte)\n * Unpauses the market — re-enables trading, deposits, and withdrawals.\n */\nexport function encodeUnpauseMarket(): Uint8Array {\n return encU8(IX_TAG.UnpauseMarket);\n}\n\n// ============================================================================\n// PERC-117: Pyth Oracle CPI Instructions\n// ============================================================================\n\n/**\n * SetPythOracle (Tag 32) — switch a market to Pyth-pinned mode.\n *\n * After this instruction:\n * - oracle_authority is cleared → PushOraclePrice is disabled\n * - index_feed_id is set to feed_id → validated on every price read\n * - max_staleness_secs and conf_filter_bps are updated\n * - All price reads go directly to read_pyth_price_e6() with on-chain\n * staleness + confidence + feed-ID validation (no silent fallback)\n *\n * Instruction data: tag(1) + feed_id(32) + max_staleness_secs(8) + conf_filter_bps(2) = 43 bytes\n *\n * Accounts:\n * 0. [signer, writable] Admin\n * 1. [writable] Slab\n */\nexport interface SetPythOracleArgs {\n /** 32-byte Pyth feed ID. All zeros is invalid (reserved for Hyperp mode). */\n feedId: Uint8Array;\n /** Maximum age of Pyth price in seconds before OracleStale is returned. Must be > 0. */\n maxStalenessSecs: bigint;\n /** Max confidence/price ratio in bps (0 = no confidence check). */\n confFilterBps: number;\n}\n\nexport function encodeSetPythOracle(args: SetPythOracleArgs): Uint8Array {\n if (args.feedId.length !== 32) throw new Error('feedId must be 32 bytes');\n if (args.maxStalenessSecs <= 0n) throw new Error('maxStalenessSecs must be > 0');\n\n const buf = new Uint8Array(43);\n const dv = new DataView(buf.buffer);\n\n // Tag 32 (SetPythOracle)\n buf[0] = 32;\n buf.set(args.feedId, 1);\n dv.setBigUint64(33, args.maxStalenessSecs, /* little-endian */ true);\n dv.setUint16(41, args.confFilterBps, true);\n\n return buf;\n}\n\n/**\n * Derive the expected Pyth PriceUpdateV2 account address for a given feed ID.\n * Uses PDA seeds: [shard_id(2), feed_id(32)] under the Pyth Receiver program.\n *\n * @param feedId 32-byte Pyth feed ID\n * @param shardId Shard index (default 0 for mainnet/devnet)\n */\nexport const PYTH_RECEIVER_PROGRAM_ID = 'rec5EKMGg6MxZYaMdyBfgwp4d5rB9T1VQH5pJv5LtFJ';\n\nexport async function derivePythPriceUpdateAccount(\n feedId: Uint8Array,\n shardId = 0,\n): Promise<string> {\n const { PublicKey } = await import('@solana/web3.js');\n const shardBuf = new Uint8Array(2);\n new DataView(shardBuf.buffer).setUint16(0, shardId, true);\n const [pda] = PublicKey.findProgramAddressSync(\n [shardBuf, feedId],\n new PublicKey(PYTH_RECEIVER_PROGRAM_ID),\n );\n return pda.toBase58();\n}\n\n// Add SetPythOracle to the tag registry\n(IX_TAG as Record<string, number>)['SetPythOracle'] = 32;\n\n// PERC-118: Mark Price EMA Instructions\n// ============================================================================\n\n// Tag 33 — permissionless mark price EMA crank\n(IX_TAG as Record<string, number>)['UpdateMarkPrice'] = 33;\n\n/**\n * UpdateMarkPrice (Tag 33) — permissionless EMA mark price crank.\n *\n * Reads the current oracle price on-chain, applies 8-hour EMA smoothing\n * with circuit breaker, and writes result to authority_price_e6.\n *\n * Instruction data: 1 byte (tag only — all params read from on-chain state)\n *\n * Accounts:\n * 0. [writable] Slab\n * 1. [] Oracle account (Pyth PriceUpdateV2 / Chainlink / DEX AMM)\n * 2. [] Clock sysvar (SysvarC1ock11111111111111111111111111111111)\n * 3..N [] Remaining accounts (PumpSwap vaults, etc. if needed)\n */\nexport function encodeUpdateMarkPrice(): Uint8Array {\n return new Uint8Array([33]);\n}\n\n/**\n * Mark price EMA parameters (must match program/src/percolator.rs constants).\n */\nexport const MARK_PRICE_EMA_WINDOW_SLOTS = 72_000n;\nexport const MARK_PRICE_EMA_ALPHA_E6 = 2_000_000n / (MARK_PRICE_EMA_WINDOW_SLOTS + 1n);\n\n/**\n * Compute the next EMA mark price step (TypeScript mirror of the on-chain function).\n */\nexport function computeEmaMarkPrice(\n markPrevE6: bigint,\n oracleE6: bigint,\n dtSlots: bigint,\n alphaE6 = MARK_PRICE_EMA_ALPHA_E6,\n capE2bps = 0n,\n): bigint {\n if (oracleE6 === 0n) return markPrevE6;\n if (markPrevE6 === 0n || dtSlots === 0n) return oracleE6;\n\n let oracleClamped = oracleE6;\n if (capE2bps > 0n) {\n const maxDelta = (markPrevE6 * capE2bps * dtSlots) / 1_000_000n;\n const lo = markPrevE6 > maxDelta ? markPrevE6 - maxDelta : 0n;\n const hi = markPrevE6 + maxDelta;\n if (oracleClamped < lo) oracleClamped = lo;\n if (oracleClamped > hi) oracleClamped = hi;\n }\n\n const effectiveAlpha = alphaE6 * dtSlots > 1_000_000n ? 1_000_000n : alphaE6 * dtSlots;\n const oneMinusAlpha = 1_000_000n - effectiveAlpha;\n\n return (oracleClamped * effectiveAlpha + markPrevE6 * oneMinusAlpha) / 1_000_000n;\n}\n\n// PERC-119: Hyperp EMA Oracle for Permissionless Tokens\n// ============================================================================\n\n// Tag 34 — permissionless Hyperp mark price oracle (reads DEX AMM pool)\n(IX_TAG as Record<string, number>)['UpdateHyperpMark'] = 34;\n\n/**\n * UpdateHyperpMark (Tag 34) — permissionless Hyperp EMA oracle crank.\n *\n * Reads the spot price from a PumpSwap, Raydium CLMM, or Meteora DLMM pool,\n * applies 8-hour EMA smoothing with circuit breaker, and writes the new mark\n * to authority_price_e6 on the slab.\n *\n * This is the core mechanism for permissionless token markets — no Pyth or\n * Chainlink feed is needed. The DEX AMM IS the oracle.\n *\n * Instruction data: 1 byte (tag only)\n *\n * Accounts:\n * 0. [writable] Slab\n * 1. [] DEX pool account (PumpSwap / Raydium CLMM / Meteora DLMM)\n * 2. [] Clock sysvar (SysvarC1ock11111111111111111111111111111111)\n * 3..N [] Remaining accounts (e.g. PumpSwap vault0 + vault1)\n */\nexport function encodeUpdateHyperpMark(): Uint8Array {\n return new Uint8Array([34]);\n}\n\n// ============================================================================\n// PERC-306: Per-Market Insurance Isolation\n// ============================================================================\n\n/**\n * Fund per-market isolated insurance balance.\n * Accounts: [admin(signer,writable), slab(writable), admin_ata(writable), vault(writable), token_program]\n */\nexport function encodeFundMarketInsurance(args: { amount: bigint }): Uint8Array {\n return concatBytes(encU8(IX_TAG.FundMarketInsurance), encU64(args.amount));\n}\n\n/**\n * Set insurance isolation BPS for a market.\n * Accounts: [admin(signer), slab(writable)]\n */\nexport function encodeSetInsuranceIsolation(args: { bps: number }): Uint8Array {\n return concatBytes(encU8(IX_TAG.SetInsuranceIsolation), encU16(args.bps));\n}\n\n// ============================================================================\n// NOTE: encodeExecuteAdl() was historically removed when it was discovered\n// that PERC-305 was NOT implemented on-chain and tag 43 was ChallengeSettlement.\n// PERC-305 (ExecuteAdl) is now live at tag 50. Encoder added below.\n// ============================================================================\n\n// ============================================================================\n// PERC-309: QueueWithdrawal / ClaimQueuedWithdrawal / CancelQueuedWithdrawal\n// ============================================================================\n\n/**\n * QueueWithdrawal (Tag 47, PERC-309) — queue a large LP withdrawal.\n *\n * Creates a withdraw_queue PDA. The LP tokens are claimed in epoch tranches\n * via ClaimQueuedWithdrawal. Call CancelQueuedWithdrawal to abort.\n *\n * Accounts: [user(signer,writable), slab(writable), lpVaultState, withdrawQueue(writable), systemProgram]\n *\n * @param lpAmount - Amount of LP tokens to queue for withdrawal.\n *\n * @example\n * ```ts\n * const data = encodeQueueWithdrawal({ lpAmount: 1_000_000_000n });\n * ```\n */\nexport function encodeQueueWithdrawal(args: { lpAmount: bigint | string }): Uint8Array {\n return concatBytes(encU8(IX_TAG.QueueWithdrawal), encU64(args.lpAmount));\n}\n\n/**\n * ClaimQueuedWithdrawal (Tag 48, PERC-309) — claim one epoch tranche from a queued withdrawal.\n *\n * Burns LP tokens and releases one tranche of SOL to the user.\n * Call once per epoch until epochs_remaining == 0.\n *\n * Accounts: [user(signer,writable), slab(writable), withdrawQueue(writable),\n * lpVaultMint(writable), userLpAta(writable), vault(writable),\n * userAta(writable), vaultAuthority, tokenProgram, lpVaultState(writable)]\n */\nexport function encodeClaimQueuedWithdrawal(): Uint8Array {\n return encU8(IX_TAG.ClaimQueuedWithdrawal);\n}\n\n/**\n * CancelQueuedWithdrawal (Tag 49, PERC-309) — cancel a queued withdrawal, refund remaining LP.\n *\n * Closes the withdraw_queue PDA and returns its rent lamports to the user.\n * The queued LP amount that was not yet claimed is NOT refunded — it is burned.\n * Use only to abandon a partial withdrawal.\n *\n * Accounts: [user(signer,writable), slab, withdrawQueue(writable)]\n */\nexport function encodeCancelQueuedWithdrawal(): Uint8Array {\n return encU8(IX_TAG.CancelQueuedWithdrawal);\n}\n\n// ============================================================================\n// PERC-305: ExecuteAdl (Tag 50) — Auto-Deleverage\n// ============================================================================\n\n/**\n * ExecuteAdl (Tag 50, PERC-305) — auto-deleverage the most profitable position.\n *\n * Permissionless. Surgically closes or reduces `targetIdx` position when\n * `pnl_pos_tot > max_pnl_cap` on the market. The caller receives no reward —\n * the incentive is unblocking the market for normal trading.\n *\n * Requires `UpdateRiskParams.max_pnl_cap > 0` on the market.\n *\n * Accounts: [caller(signer), slab(writable), clock, oracle, ...backupOracles?]\n *\n * @param targetIdx - Account index of the position to deleverage.\n *\n * @example\n * ```ts\n * const data = encodeExecuteAdl({ targetIdx: 5 });\n * ```\n */\nexport interface ExecuteAdlArgs {\n targetIdx: number;\n}\n\nexport function encodeExecuteAdl(args: ExecuteAdlArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.ExecuteAdl), encU16(args.targetIdx));\n}\n\n// ============================================================================\n// CloseStaleSlabs (Tag 51) / ReclaimSlabRent (Tag 52) — Slab recovery\n// ============================================================================\n\n/**\n * CloseStaleSlabs (Tag 51) — close a slab of an invalid/old layout and recover rent SOL.\n *\n * Admin only. Skips slab_guard; validates header magic + admin authority instead.\n * Use for slabs created by old program layouts (e.g. pre-PERC-120 devnet deploys)\n * whose size does not match any current valid tier.\n *\n * Accounts: [dest(signer,writable), slab(writable)]\n */\nexport function encodeCloseStaleSlabs(): Uint8Array {\n return encU8(IX_TAG.CloseStaleSlabs);\n}\n\n/**\n * ReclaimSlabRent (Tag 52) — reclaim rent from an uninitialised slab.\n *\n * For use when market creation failed mid-flow (slab funded but InitMarket not called).\n * The slab account must sign (proves the caller holds the slab keypair).\n * Cannot close an initialised slab (magic == PERCOLAT) — use CloseSlab (tag 13).\n *\n * Accounts: [dest(signer,writable), slab(signer,writable)]\n */\nexport function encodeReclaimSlabRent(): Uint8Array {\n return encU8(IX_TAG.ReclaimSlabRent);\n}\n\n// ============================================================================\n// AuditCrank (Tag 53) — Permissionless on-chain invariant check\n// ============================================================================\n\n/**\n * AuditCrank (Tag 53) — verify conservation invariants on-chain (permissionless).\n *\n * Walks all accounts and verifies: capital sum, pnl_pos_tot, total_oi, LP consistency,\n * and solvency. Sets FLAG_PAUSED on violation (with a 150-slot cooldown guard to\n * prevent DoS from transient failures).\n *\n * Accounts: [slab(writable)]\n *\n * @example\n * ```ts\n * const data = encodeAuditCrank();\n * ```\n */\nexport function encodeAuditCrank(): Uint8Array {\n return encU8(IX_TAG.AuditCrank);\n}\n\n// ============================================================================\n// SMART PRICE ROUTER — quote computation for LP selection\n// ============================================================================\n\n/**\n * Parsed vAMM matcher parameters (from on-chain matcher context account)\n */\nexport interface VammMatcherParams {\n mode: number; // 0 = Passive, 1 = vAMM\n tradingFeeBps: number;\n baseSpreadBps: number;\n maxTotalBps: number;\n impactKBps: number;\n liquidityNotionalE6: bigint;\n}\n\n/** Magic bytes identifying a vAMM matcher context: \"PERCMATC\" as u64 LE */\nexport const VAMM_MAGIC = 0x5045_5243_4d41_5443n;\n\n/** Offset into matcher context where vAMM params start */\nexport const CTX_VAMM_OFFSET = 64;\n\nconst BPS_DENOM = 10_000n;\n\n/**\n * Compute execution price for a given LP quote.\n * For buys (isLong=true): price above oracle.\n * For sells (isLong=false): price below oracle.\n */\nexport function computeVammQuote(\n params: VammMatcherParams,\n oraclePriceE6: bigint,\n tradeSize: bigint,\n isLong: boolean,\n): bigint {\n const absSize = tradeSize < 0n ? -tradeSize : tradeSize;\n const absNotionalE6 = (absSize * oraclePriceE6) / 1_000_000n;\n\n // Impact for vAMM mode\n let impactBps = 0n;\n if (params.mode === 1 && params.liquidityNotionalE6 > 0n) {\n impactBps = (absNotionalE6 * BigInt(params.impactKBps)) / params.liquidityNotionalE6;\n }\n\n // Total = base_spread + trading_fee + impact, capped at max_total\n const maxTotal = BigInt(params.maxTotalBps);\n const baseFee = BigInt(params.baseSpreadBps) + BigInt(params.tradingFeeBps);\n const maxImpact = maxTotal > baseFee ? maxTotal - baseFee : 0n;\n const clampedImpact = impactBps < maxImpact ? impactBps : maxImpact;\n let totalBps = baseFee + clampedImpact;\n if (totalBps > maxTotal) totalBps = maxTotal;\n\n if (isLong) {\n return (oraclePriceE6 * (BPS_DENOM + totalBps)) / BPS_DENOM;\n } else {\n // Prevent underflow: if totalBps >= BPS_DENOM, price would go negative\n if (totalBps >= BPS_DENOM) return 1n; // minimum 1 micro-dollar\n return (oraclePriceE6 * (BPS_DENOM - totalBps)) / BPS_DENOM;\n }\n}\n\n// ============================================================================\n// PERC-622: AdvanceOraclePhase (permissionless crank)\n// ============================================================================\n\n/**\n * AdvanceOraclePhase (Tag 56) — permissionless oracle phase advancement.\n *\n * Checks if a market should transition from Phase 0→1→2 based on\n * time elapsed and cumulative volume. Anyone can call this.\n *\n * Instruction data: 1 byte (tag only)\n *\n * Accounts:\n * 0. [writable] Slab\n */\nexport function encodeAdvanceOraclePhase(): Uint8Array {\n return encU8(IX_TAG.AdvanceOraclePhase);\n}\n\n/** Oracle phase constants matching on-chain values */\nexport const ORACLE_PHASE_NASCENT = 0;\nexport const ORACLE_PHASE_GROWING = 1;\nexport const ORACLE_PHASE_MATURE = 2;\n\n/** Phase transition thresholds (must match program constants) */\nexport const PHASE1_MIN_SLOTS = 648_000n; // ~72h at 400ms\nexport const PHASE1_VOLUME_MIN_SLOTS = 36_000n; // ~4h at 400ms\nexport const PHASE2_VOLUME_THRESHOLD = 100_000_000_000n; // $100K in e6\nexport const PHASE2_MATURITY_SLOTS = 3_024_000n; // ~14 days at 400ms\n\n/**\n * Check if an oracle phase transition is due (TypeScript mirror of on-chain logic).\n *\n * @returns [newPhase, shouldTransition]\n */\nexport function checkPhaseTransition(\n currentSlot: bigint,\n marketCreatedSlot: bigint,\n oraclePhase: number,\n cumulativeVolumeE6: bigint,\n phase2DeltaSlots: number,\n hasMatureOracle: boolean,\n): [number, boolean] {\n switch (oraclePhase) {\n case 0: {\n const elapsed = currentSlot - (marketCreatedSlot > 0n ? marketCreatedSlot : currentSlot);\n const timeReady = elapsed >= PHASE1_MIN_SLOTS;\n const volumeReady = elapsed >= PHASE1_VOLUME_MIN_SLOTS\n && cumulativeVolumeE6 >= PHASE2_VOLUME_THRESHOLD;\n if (timeReady || volumeReady) {\n return [ORACLE_PHASE_GROWING, true];\n }\n return [ORACLE_PHASE_NASCENT, false];\n }\n case 1: {\n if (hasMatureOracle) return [ORACLE_PHASE_MATURE, true];\n const phase2Start = marketCreatedSlot + BigInt(phase2DeltaSlots);\n const elapsedSincePhase2 = currentSlot - phase2Start;\n if (elapsedSincePhase2 >= PHASE2_MATURITY_SLOTS) {\n return [ORACLE_PHASE_MATURE, true];\n }\n return [ORACLE_PHASE_GROWING, false];\n }\n default:\n return [ORACLE_PHASE_MATURE, false];\n }\n}\n\n// ============================================================================\n// PERC-623: Keeper Fund Instructions\n// ============================================================================\n\n/**\n * TopUpKeeperFund (Tag 57) — permissionless keeper fund top-up.\n *\n * Instruction data: tag(1) + amount(8) = 9 bytes\n *\n * Accounts:\n * 0. [signer, writable] Funder\n * 1. [writable] Slab\n * 2. [writable] Keeper fund PDA\n * 3. [] System program\n */\nexport interface TopUpKeeperFundArgs {\n amount: bigint | string;\n}\n\nexport function encodeTopUpKeeperFund(args: TopUpKeeperFundArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.TopUpKeeperFund), encU64(args.amount));\n}\n\n// Note: WithdrawKeeperReward does NOT exist as a separate instruction.\n// Keeper rewards are paid automatically during KeeperCrank (tag 5).\n// The keeper fund PDA is debited in-place when a successful crank is executed.\n\n// ============================================================================\n// PERC-629: Dynamic Creation Deposit\n// ============================================================================\n\n/**\n * SlashCreationDeposit (Tag 58) — permissionless: slash a market creator's deposit\n * after the spam grace period has elapsed (PERC-629).\n *\n * **WARNING**: Tag 58 is reserved in tags.rs but has NO instruction decoder or\n * handler in the on-chain program. Sending this instruction will fail with\n * `InvalidInstructionData`. Do not use until the on-chain handler is deployed.\n *\n * Instruction data: 1 byte (tag only)\n *\n * Accounts:\n * 0. [signer] Caller (anyone)\n * 1. [] Slab\n * 2. [writable] Creator history PDA\n * 3. [writable] Insurance vault\n * 4. [writable] Treasury\n * 5. [] System program\n *\n * @deprecated Not yet implemented on-chain — will fail with InvalidInstructionData.\n */\nexport function encodeSlashCreationDeposit(): Uint8Array {\n return encU8(IX_TAG.SlashCreationDeposit);\n}\n\n// ============================================================================\n// PERC-628: Elastic Shared Vault + Epoch Withdrawals\n// ============================================================================\n\n/**\n * InitSharedVault (Tag 59) — admin: create the global shared vault PDA (PERC-628).\n *\n * Instruction data: tag(1) + epochDurationSlots(8) + maxMarketExposureBps(2) = 11 bytes\n *\n * Accounts:\n * 0. [signer] Admin\n * 1. [writable] Shared vault PDA\n * 2. [] System program\n */\nexport interface InitSharedVaultArgs {\n epochDurationSlots: bigint | string;\n maxMarketExposureBps: number;\n}\n\nexport function encodeInitSharedVault(args: InitSharedVaultArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.InitSharedVault),\n encU64(args.epochDurationSlots),\n encU16(args.maxMarketExposureBps),\n );\n}\n\n/**\n * AllocateMarket (Tag 60) — admin: allocate virtual liquidity from the shared vault\n * to a market (PERC-628).\n *\n * Instruction data: tag(1) + amount(16) = 17 bytes\n *\n * Accounts:\n * 0. [signer] Admin\n * 1. [] Slab\n * 2. [writable] Shared vault PDA\n * 3. [writable] Market alloc PDA\n * 4. [] System program\n */\nexport interface AllocateMarketArgs {\n amount: bigint | string;\n}\n\nexport function encodeAllocateMarket(args: AllocateMarketArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.AllocateMarket), encU128(args.amount));\n}\n\n/**\n * QueueWithdrawalSV (Tag 61) — user: queue a withdrawal request for the current\n * epoch (PERC-628). Tokens are locked until the epoch elapses.\n *\n * Instruction data: tag(1) + lpAmount(8) = 9 bytes\n *\n * Accounts:\n * 0. [signer] User\n * 1. [writable] Shared vault PDA\n * 2. [writable] Withdraw request PDA\n * 3. [] System program\n */\nexport interface QueueWithdrawalSVArgs {\n lpAmount: bigint | string;\n}\n\nexport function encodeQueueWithdrawalSV(args: QueueWithdrawalSVArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.QueueWithdrawalSV), encU64(args.lpAmount));\n}\n\n/**\n * ClaimEpochWithdrawal (Tag 62) — user: claim a queued withdrawal after the epoch\n * has elapsed (PERC-628). Receives pro-rata collateral from the vault.\n *\n * Instruction data: 1 byte (tag only)\n *\n * Accounts:\n * 0. [signer] User\n * 1. [writable] Shared vault PDA\n * 2. [writable] Withdraw request PDA\n * 3. [] Slab\n * 4. [writable] Vault\n * 5. [writable] User ATA\n * 6. [] Vault authority\n * 7. [] Token program\n */\nexport function encodeClaimEpochWithdrawal(): Uint8Array {\n return encU8(IX_TAG.ClaimEpochWithdrawal);\n}\n\n/**\n * AdvanceEpoch (Tag 63) — permissionless crank: move the shared vault to the next\n * epoch once `epoch_duration_slots` have elapsed (PERC-628).\n *\n * Instruction data: 1 byte (tag only)\n *\n * Accounts:\n * 0. [signer] Caller (anyone)\n * 1. [writable] Shared vault PDA\n */\nexport function encodeAdvanceEpoch(): Uint8Array {\n return encU8(IX_TAG.AdvanceEpoch);\n}\n\n// PERC-628: Tag 63 ─────────────────────────────────────────────────────────\n\n// PERC-8110 ────────────────────────────────────────────────────────────────\n\n/**\n * SetOiImbalanceHardBlock (Tag 71, PERC-8110) — set OI imbalance hard-block threshold (admin only).\n *\n * When `|long_oi − short_oi| / total_oi * 10_000 >= threshold_bps`, any new trade that would\n * *increase* the imbalance is rejected with `OiImbalanceHardBlock` (error code 59).\n *\n * - `threshold_bps = 0`: hard block disabled.\n * - `threshold_bps = 8_000`: block trades that push skew above 80%.\n * - `threshold_bps = 10_000`: never allow >100% skew (always blocks one side when oi > 0).\n *\n * Instruction data layout: tag(1) + threshold_bps(2) = 3 bytes\n *\n * Accounts:\n * 0. [signer] admin\n * 1. [writable] slab\n *\n * @example\n * ```ts\n * const ix = new TransactionInstruction({\n * programId: PROGRAM_ID,\n * keys: buildAccountMetas(ACCOUNTS_SET_OI_IMBALANCE_HARD_BLOCK, { admin, slab }),\n * data: Buffer.from(encodeSetOiImbalanceHardBlock({ thresholdBps: 8_000 })),\n * });\n * ```\n */\nexport function encodeSetOiImbalanceHardBlock(args: { thresholdBps: number }): Uint8Array {\n if (args.thresholdBps < 0 || args.thresholdBps > 10_000) {\n throw new Error(`encodeSetOiImbalanceHardBlock: thresholdBps must be 0–10_000, got ${args.thresholdBps}`);\n }\n return concatBytes(encU8(IX_TAG.SetOiImbalanceHardBlock), encU16(args.thresholdBps));\n}\n\n// ============================================================================\n// PERC-608 — Position NFT instructions (tags 64–69)\n// ============================================================================\n\n/**\n * MintPositionNft (Tag 64, PERC-608) — mint a Token-2022 NFT representing a position.\n *\n * Creates a PositionNft PDA + Token-2022 mint with metadata, then mints 1 NFT to the\n * position owner's ATA. The NFT represents ownership of `user_idx` in the slab.\n *\n * Instruction data layout: tag(1) + user_idx(2) = 3 bytes\n *\n * Accounts:\n * 0. [signer, writable] payer\n * 1. [writable] slab\n * 2. [writable] position_nft PDA (created — seeds: [\"position_nft\", slab, user_idx])\n * 3. [writable] nft_mint PDA (created)\n * 4. [writable] owner_ata (Token-2022 ATA for owner)\n * 5. [signer] owner (must match engine account owner)\n * 6. [] vault_authority PDA\n * 7. [] token_2022_program\n * 8. [] system_program\n * 9. [] rent sysvar\n *\n * @example\n * ```ts\n * const ix = new TransactionInstruction({\n * programId: PROGRAM_ID,\n * keys: buildAccountMetas(ACCOUNTS_MINT_POSITION_NFT, [payer, slab, nftPda, nftMint, ownerAta, owner, vaultAuth, TOKEN_2022_PROGRAM_ID, SystemProgram.programId, SYSVAR_RENT_PUBKEY]),\n * data: Buffer.from(encodeMintPositionNft({ userIdx: 5 })),\n * });\n * ```\n */\nexport interface MintPositionNftArgs {\n userIdx: number;\n}\n\nexport function encodeMintPositionNft(args: MintPositionNftArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.MintPositionNft), encU16(args.userIdx));\n}\n\n/**\n * TransferPositionOwnership (Tag 65, PERC-608) — transfer an open position to a new owner.\n *\n * Transfers the Token-2022 NFT from current owner to new owner and updates the on-chain\n * engine account's owner field. Requires `pending_settlement == 0`.\n *\n * Instruction data layout: tag(1) + user_idx(2) = 3 bytes\n *\n * Accounts:\n * 0. [signer, writable] current_owner\n * 1. [writable] slab\n * 2. [writable] position_nft PDA\n * 3. [writable] nft_mint PDA\n * 4. [writable] current_owner_ata (source Token-2022 ATA)\n * 5. [writable] new_owner_ata (destination Token-2022 ATA)\n * 6. [] new_owner\n * 7. [] token_2022_program\n */\nexport interface TransferPositionOwnershipArgs {\n userIdx: number;\n}\n\nexport function encodeTransferPositionOwnership(args: TransferPositionOwnershipArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.TransferPositionOwnership), encU16(args.userIdx));\n}\n\n/**\n * BurnPositionNft (Tag 66, PERC-608) — burn the Position NFT when a position is closed.\n *\n * Burns the NFT, closes the PositionNft PDA and the mint PDA, returning rent to the owner.\n * Can only be called after the position is fully closed (size == 0).\n *\n * Instruction data layout: tag(1) + user_idx(2) = 3 bytes\n *\n * Accounts:\n * 0. [signer, writable] owner\n * 1. [writable] slab\n * 2. [writable] position_nft PDA (closed — rent to owner)\n * 3. [writable] nft_mint PDA (closed via Token-2022 close_account)\n * 4. [writable] owner_ata (Token-2022 ATA, balance burned)\n * 5. [] vault_authority PDA\n * 6. [] token_2022_program\n */\nexport interface BurnPositionNftArgs {\n userIdx: number;\n}\n\nexport function encodeBurnPositionNft(args: BurnPositionNftArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.BurnPositionNft), encU16(args.userIdx));\n}\n\n/**\n * SetPendingSettlement (Tag 67, PERC-608) — keeper sets the pending_settlement flag.\n *\n * Called by the keeper/admin before performing a funding settlement transfer.\n * Blocks NFT transfers until ClearPendingSettlement is called.\n * Admin-only (protected by GH#1475 keeper allowlist guard).\n *\n * Instruction data layout: tag(1) + user_idx(2) = 3 bytes\n *\n * Accounts:\n * 0. [signer] keeper / admin\n * 1. [] slab (read — for PDA verification + admin check)\n * 2. [writable] position_nft PDA\n */\nexport interface SetPendingSettlementArgs {\n userIdx: number;\n}\n\nexport function encodeSetPendingSettlement(args: SetPendingSettlementArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.SetPendingSettlement), encU16(args.userIdx));\n}\n\n/**\n * ClearPendingSettlement (Tag 68, PERC-608) — keeper clears the pending_settlement flag.\n *\n * Called by the keeper/admin after KeeperCrank has run and funding is settled.\n * Admin-only (protected by GH#1475 keeper allowlist guard).\n *\n * Instruction data layout: tag(1) + user_idx(2) = 3 bytes\n *\n * Accounts:\n * 0. [signer] keeper / admin\n * 1. [] slab (read — for PDA verification + admin check)\n * 2. [writable] position_nft PDA\n */\nexport interface ClearPendingSettlementArgs {\n userIdx: number;\n}\n\nexport function encodeClearPendingSettlement(args: ClearPendingSettlementArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.ClearPendingSettlement), encU16(args.userIdx));\n}\n\n/**\n * TransferOwnershipCpi (Tag 69, PERC-608) — internal CPI target for percolator-nft TransferHook.\n *\n * Called by the Token-2022 TransferHook on the percolator-nft program during an NFT transfer.\n * Updates the engine account's owner field to the new_owner public key.\n * NOT intended for direct external use — always called via Token-2022 CPI.\n *\n * Instruction data layout: tag(1) + user_idx(2) + new_owner(32) = 35 bytes\n *\n * Accounts:\n * 0. [signer] nft TransferHook program (CPI caller)\n * 1. [writable] slab\n * (remaining accounts per Token-2022 ExtraAccountMeta spec)\n */\nexport interface TransferOwnershipCpiArgs {\n userIdx: number;\n newOwner: PublicKey | string;\n}\n\nexport function encodeTransferOwnershipCpi(args: TransferOwnershipCpiArgs): Uint8Array {\n return concatBytes(\n encU8(IX_TAG.TransferOwnershipCpi),\n encU16(args.userIdx),\n encPubkey(args.newOwner),\n );\n}\n\n// ============================================================================\n// PERC-8111 — SetWalletCap (tag 70)\n// ============================================================================\n\n/**\n * SetWalletCap (Tag 70, PERC-8111) — set the per-wallet position cap (admin only).\n *\n * Limits the maximum absolute position size any single wallet may hold on this market.\n * Enforced on every trade (TradeNoCpi + TradeCpi) after execute_trade.\n *\n * - `capE6 = 0`: disable per-wallet cap (no limit, default).\n * - `capE6 > 0`: max |position_size| in e6 units ($1 = 1_000_000).\n * Phase 1 launch value: 1_000_000_000n ($1,000).\n *\n * When a trade would breach the cap, the on-chain error `WalletPositionCapExceeded`\n * (error code 58) is returned.\n *\n * Instruction data layout: tag(1) + cap_e6(8) = 9 bytes\n *\n * Accounts:\n * 0. [signer] admin\n * 1. [writable] slab\n *\n * @example\n * ```ts\n * // Set $1K per-wallet cap\n * const ix = new TransactionInstruction({\n * programId: PROGRAM_ID,\n * keys: buildAccountMetas(ACCOUNTS_SET_WALLET_CAP, [admin, slab]),\n * data: Buffer.from(encodeSetWalletCap({ capE6: 1_000_000_000n })),\n * });\n *\n * // Disable cap\n * const disableIx = new TransactionInstruction({\n * programId: PROGRAM_ID,\n * keys: buildAccountMetas(ACCOUNTS_SET_WALLET_CAP, [admin, slab]),\n * data: Buffer.from(encodeSetWalletCap({ capE6: 0n })),\n * });\n * ```\n */\nexport interface SetWalletCapArgs {\n /** Max position size in e6 units. 0 = disabled. $1 = 1_000_000n, $1K = 1_000_000_000n. */\n capE6: bigint | string;\n}\n\nexport function encodeSetWalletCap(args: SetWalletCapArgs): Uint8Array {\n return concatBytes(encU8(IX_TAG.SetWalletCap), encU64(args.capE6));\n}\n","import {\n PublicKey,\n AccountMeta,\n SYSVAR_CLOCK_PUBKEY,\n SYSVAR_RENT_PUBKEY,\n SystemProgram,\n} from \"@solana/web3.js\";\nimport { TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\n\n/**\n * Account spec for building instruction account metas.\n * Each instruction has a fixed ordering that matches the Rust processor.\n */\nexport interface AccountSpec {\n name: string;\n signer: boolean;\n writable: boolean;\n}\n\n// ============================================================================\n// ACCOUNT ORDERINGS - Single source of truth\n// ============================================================================\n\n/**\n * InitMarket: 9 accounts (Pyth Pull - feed_id is in instruction data, not as accounts)\n */\nexport const ACCOUNTS_INIT_MARKET: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"mint\", signer: false, writable: false },\n { name: \"vault\", signer: false, writable: false },\n { name: \"tokenProgram\", signer: false, writable: false },\n { name: \"clock\", signer: false, writable: false },\n { name: \"rent\", signer: false, writable: false },\n { name: \"dummyAta\", signer: false, writable: false },\n { name: \"systemProgram\", signer: false, writable: false },\n] as const;\n\n/**\n * InitUser: 5 accounts (clock/oracle removed in commit 410f947)\n */\nexport const ACCOUNTS_INIT_USER: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"userAta\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"tokenProgram\", signer: false, writable: false },\n] as const;\n\n/**\n * InitLP: 5 accounts (clock/oracle removed in commit 410f947)\n */\nexport const ACCOUNTS_INIT_LP: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"userAta\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"tokenProgram\", signer: false, writable: false },\n] as const;\n\n/**\n * DepositCollateral: 6 accounts\n */\nexport const ACCOUNTS_DEPOSIT_COLLATERAL: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"userAta\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"tokenProgram\", signer: false, writable: false },\n { name: \"clock\", signer: false, writable: false },\n] as const;\n\n/**\n * WithdrawCollateral: 8 accounts\n */\nexport const ACCOUNTS_WITHDRAW_COLLATERAL: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"userAta\", signer: false, writable: true },\n { name: \"vaultPda\", signer: false, writable: false },\n { name: \"tokenProgram\", signer: false, writable: false },\n { name: \"clock\", signer: false, writable: false },\n { name: \"oracleIdx\", signer: false, writable: false },\n] as const;\n\n/**\n * KeeperCrank: 4 accounts\n */\nexport const ACCOUNTS_KEEPER_CRANK: readonly AccountSpec[] = [\n { name: \"caller\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"clock\", signer: false, writable: false },\n { name: \"oracle\", signer: false, writable: false },\n] as const;\n\n/**\n * TradeNoCpi: 4 accounts (PERC-199: clock sysvar removed — uses Clock::get() syscall)\n */\nexport const ACCOUNTS_TRADE_NOCPI: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"lp\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"oracle\", signer: false, writable: false },\n] as const;\n\n/**\n * LiquidateAtOracle: 4 accounts\n * Note: account[0] is unused but must be present\n */\nexport const ACCOUNTS_LIQUIDATE_AT_ORACLE: readonly AccountSpec[] = [\n { name: \"unused\", signer: false, writable: false },\n { name: \"slab\", signer: false, writable: true },\n { name: \"clock\", signer: false, writable: false },\n { name: \"oracle\", signer: false, writable: false },\n] as const;\n\n/**\n * CloseAccount: 8 accounts\n */\nexport const ACCOUNTS_CLOSE_ACCOUNT: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"userAta\", signer: false, writable: true },\n { name: \"vaultPda\", signer: false, writable: false },\n { name: \"tokenProgram\", signer: false, writable: false },\n { name: \"clock\", signer: false, writable: false },\n { name: \"oracle\", signer: false, writable: false },\n] as const;\n\n/**\n * TopUpInsurance: 5 accounts\n */\nexport const ACCOUNTS_TOPUP_INSURANCE: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"userAta\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"tokenProgram\", signer: false, writable: false },\n] as const;\n\n/**\n * TradeCpi: 7 accounts (PERC-199: clock sysvar removed — uses Clock::get() syscall)\n */\nexport const ACCOUNTS_TRADE_CPI: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"lpOwner\", signer: false, writable: false }, // LP delegated to matcher - no signature needed\n { name: \"slab\", signer: false, writable: true },\n { name: \"oracle\", signer: false, writable: false },\n { name: \"matcherProg\", signer: false, writable: false },\n { name: \"matcherCtx\", signer: false, writable: true },\n { name: \"lpPda\", signer: false, writable: false },\n] as const;\n\n/**\n * SetRiskThreshold: 2 accounts\n */\nexport const ACCOUNTS_SET_RISK_THRESHOLD: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * UpdateAdmin: 2 accounts\n */\nexport const ACCOUNTS_UPDATE_ADMIN: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * CloseSlab: 2 accounts\n */\nexport const ACCOUNTS_CLOSE_SLAB: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * UpdateConfig: 2 accounts\n */\nexport const ACCOUNTS_UPDATE_CONFIG: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * SetMaintenanceFee: 2 accounts\n */\nexport const ACCOUNTS_SET_MAINTENANCE_FEE: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * SetOracleAuthority: 2 accounts\n * Sets the oracle price authority (admin only)\n */\nexport const ACCOUNTS_SET_ORACLE_AUTHORITY: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * SetOraclePriceCap: 2 accounts\n * Set oracle price circuit breaker cap (admin only)\n */\nexport const ACCOUNTS_SET_ORACLE_PRICE_CAP: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * PushOraclePrice: 2 accounts\n * Push oracle price (oracle authority only)\n */\nexport const ACCOUNTS_PUSH_ORACLE_PRICE: readonly AccountSpec[] = [\n { name: \"authority\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * ResolveMarket: 2 accounts\n * Resolves a binary/premarket (admin only)\n */\nexport const ACCOUNTS_RESOLVE_MARKET: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * WithdrawInsurance: 6 accounts\n * Withdraw insurance fund after market resolution (admin only)\n */\nexport const ACCOUNTS_WITHDRAW_INSURANCE: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"adminAta\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"tokenProgram\", signer: false, writable: false },\n { name: \"vaultPda\", signer: false, writable: false },\n] as const;\n\n/**\n * PauseMarket: 2 accounts\n */\nexport const ACCOUNTS_PAUSE_MARKET: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * UnpauseMarket: 2 accounts\n */\nexport const ACCOUNTS_UNPAUSE_MARKET: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n// ============================================================================\n// ACCOUNT META BUILDERS\n// ============================================================================\n\n/**\n * Build AccountMeta array from spec and provided pubkeys.\n *\n * Accepts either:\n * - `PublicKey[]` — ordered array, one entry per spec account (legacy form)\n * - `Record<string, PublicKey>` — named map keyed by account `name` (preferred form)\n *\n * Named-map form resolves accounts by spec name so callers don't have to\n * remember the positional order, and errors clearly on missing names.\n */\nexport function buildAccountMetas(\n spec: readonly AccountSpec[],\n keys: PublicKey[] | Record<string, PublicKey>\n): AccountMeta[] {\n let keysArray: PublicKey[];\n\n if (Array.isArray(keys)) {\n keysArray = keys;\n } else {\n // Named map: resolve by spec name\n keysArray = spec.map((s) => {\n const key = (keys as Record<string, PublicKey>)[s.name];\n if (!key) {\n throw new Error(\n `buildAccountMetas: missing key for account \"${s.name}\". ` +\n `Provided keys: [${Object.keys(keys).join(\", \")}]`\n );\n }\n return key;\n });\n }\n\n if (keysArray.length !== spec.length) {\n throw new Error(\n `Account count mismatch: expected ${spec.length}, got ${keysArray.length}`\n );\n }\n return spec.map((s, i) => ({\n pubkey: keysArray[i],\n isSigner: s.signer,\n isWritable: s.writable,\n }));\n}\n\n/**\n * CreateInsuranceMint: 9 accounts\n * Creates SPL mint PDA for insurance LP tokens. Admin only, once per market.\n */\nexport const ACCOUNTS_CREATE_INSURANCE_MINT: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: false },\n { name: \"slab\", signer: false, writable: false },\n { name: \"insLpMint\", signer: false, writable: true },\n { name: \"vaultAuthority\", signer: false, writable: false },\n { name: \"collateralMint\", signer: false, writable: false },\n { name: \"systemProgram\", signer: false, writable: false },\n { name: \"tokenProgram\", signer: false, writable: false },\n { name: \"rent\", signer: false, writable: false },\n { name: \"payer\", signer: true, writable: true },\n] as const;\n\n/**\n * DepositInsuranceLP: 8 accounts\n * Deposit collateral into insurance fund, receive LP tokens.\n */\nexport const ACCOUNTS_DEPOSIT_INSURANCE_LP: readonly AccountSpec[] = [\n { name: \"depositor\", signer: true, writable: false },\n { name: \"slab\", signer: false, writable: true },\n { name: \"depositorAta\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"tokenProgram\", signer: false, writable: false },\n { name: \"insLpMint\", signer: false, writable: true },\n { name: \"depositorLpAta\", signer: false, writable: true },\n { name: \"vaultAuthority\", signer: false, writable: false },\n] as const;\n\n/**\n * WithdrawInsuranceLP: 8 accounts\n * Burn LP tokens and withdraw proportional share of insurance fund.\n */\nexport const ACCOUNTS_WITHDRAW_INSURANCE_LP: readonly AccountSpec[] = [\n { name: \"withdrawer\", signer: true, writable: false },\n { name: \"slab\", signer: false, writable: true },\n { name: \"withdrawerAta\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"tokenProgram\", signer: false, writable: false },\n { name: \"insLpMint\", signer: false, writable: true },\n { name: \"withdrawerLpAta\", signer: false, writable: true },\n { name: \"vaultAuthority\", signer: false, writable: false },\n] as const;\n\n// ============================================================================\n// PERC-627 / GH#1926: LpVaultWithdraw (tag 39)\n// ============================================================================\n\n/**\n * LpVaultWithdraw: 10 accounts (tag 39, PERC-627 / GH#1926 / PERC-8287)\n *\n * Burn LP vault tokens and withdraw proportional collateral from the LP vault.\n *\n * accounts[9] = creatorLockPda is REQUIRED since percolator-prog PR#170.\n * Non-creator withdrawers must pass the derived PDA key; if no lock exists\n * on-chain the enforcement is a no-op. Omitting it was the bypass vector\n * fixed in GH#1926. Use `deriveCreatorLockPda(programId, slab)` to compute.\n *\n * Accounts:\n * [0] withdrawer signer, read-only\n * [1] slab writable\n * [2] withdrawerAta writable (collateral destination)\n * [3] vault writable (collateral source)\n * [4] tokenProgram read-only\n * [5] lpVaultMint writable (LP tokens burned from here)\n * [6] withdrawerLpAta writable (LP tokens source)\n * [7] vaultAuthority read-only (PDA that signs token transfers)\n * [8] lpVaultState writable\n * [9] creatorLockPda writable (REQUIRED — derived from [\"creator_lock\", slab])\n */\nexport const ACCOUNTS_LP_VAULT_WITHDRAW: readonly AccountSpec[] = [\n { name: \"withdrawer\", signer: true, writable: false },\n { name: \"slab\", signer: false, writable: true },\n { name: \"withdrawerAta\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"tokenProgram\", signer: false, writable: false },\n { name: \"lpVaultMint\", signer: false, writable: true },\n { name: \"withdrawerLpAta\", signer: false, writable: true },\n { name: \"vaultAuthority\", signer: false, writable: false },\n { name: \"lpVaultState\", signer: false, writable: true },\n { name: \"creatorLockPda\", signer: false, writable: true },\n] as const;\n\n/**\n * FundMarketInsurance: 5 accounts (PERC-306)\n * Fund per-market isolated insurance balance.\n */\nexport const ACCOUNTS_FUND_MARKET_INSURANCE: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"adminAta\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"tokenProgram\", signer: false, writable: false },\n] as const;\n\n/**\n * SetInsuranceIsolation: 2 accounts (PERC-306)\n * Set max % of global fund this market can access.\n */\nexport const ACCOUNTS_SET_INSURANCE_ISOLATION: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: false },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n// ============================================================================\n// PERC-309: QueueWithdrawal / ClaimQueuedWithdrawal / CancelQueuedWithdrawal\n// ============================================================================\n\n/**\n * QueueWithdrawal: 5 accounts (PERC-309)\n * User queues a large LP withdrawal. Creates withdraw_queue PDA.\n */\nexport const ACCOUNTS_QUEUE_WITHDRAWAL: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"lpVaultState\", signer: false, writable: false },\n { name: \"withdrawQueue\", signer: false, writable: true },\n { name: \"systemProgram\", signer: false, writable: false },\n] as const;\n\n/**\n * ClaimQueuedWithdrawal: 10 accounts (PERC-309)\n * Burns LP tokens and releases one epoch tranche of SOL.\n */\nexport const ACCOUNTS_CLAIM_QUEUED_WITHDRAWAL: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"withdrawQueue\", signer: false, writable: true },\n { name: \"lpVaultMint\", signer: false, writable: true },\n { name: \"userLpAta\", signer: false, writable: true },\n { name: \"vault\", signer: false, writable: true },\n { name: \"userAta\", signer: false, writable: true },\n { name: \"vaultAuthority\", signer: false, writable: false },\n { name: \"tokenProgram\", signer: false, writable: false },\n { name: \"lpVaultState\", signer: false, writable: true },\n] as const;\n\n/**\n * CancelQueuedWithdrawal: 3 accounts (PERC-309)\n * Cancels queue, closes withdraw_queue PDA, returns rent to user.\n */\nexport const ACCOUNTS_CANCEL_QUEUED_WITHDRAWAL: readonly AccountSpec[] = [\n { name: \"user\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: false },\n { name: \"withdrawQueue\", signer: false, writable: true },\n] as const;\n\n// ============================================================================\n// PERC-305: ExecuteAdl (tag 50) — Auto-Deleverage\n// ============================================================================\n\n/**\n * ExecuteAdl: 4+ accounts (PERC-305, tag 50)\n * Permissionless — surgically close/reduce the most profitable position\n * when pnl_pos_tot > max_pnl_cap. For non-Hyperp markets with backup oracles,\n * pass additional oracle accounts at accounts[4..].\n */\nexport const ACCOUNTS_EXECUTE_ADL: readonly AccountSpec[] = [\n { name: \"caller\", signer: true, writable: false },\n { name: \"slab\", signer: false, writable: true },\n { name: \"clock\", signer: false, writable: false },\n { name: \"oracle\", signer: false, writable: false },\n] as const;\n\n// ============================================================================\n// CloseStaleSlabs (tag 51) / ReclaimSlabRent (tag 52)\n// ============================================================================\n\n/**\n * CloseStaleSlabs: 2 accounts (tag 51)\n * Admin closes a slab of an invalid/old layout and recovers rent SOL.\n */\nexport const ACCOUNTS_CLOSE_STALE_SLABS: readonly AccountSpec[] = [\n { name: \"dest\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n/**\n * ReclaimSlabRent: 2 accounts (tag 52)\n * Reclaim rent from an uninitialised slab. Both dest and slab must sign.\n */\nexport const ACCOUNTS_RECLAIM_SLAB_RENT: readonly AccountSpec[] = [\n { name: \"dest\", signer: true, writable: true },\n { name: \"slab\", signer: true, writable: true },\n] as const;\n\n// ============================================================================\n// AuditCrank (tag 53) — Permissionless invariant check\n// ============================================================================\n\n/**\n * AuditCrank: 1 account (tag 53)\n * Permissionless. Verifies conservation invariants; pauses market on violation.\n */\nexport const ACCOUNTS_AUDIT_CRANK: readonly AccountSpec[] = [\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n// ============================================================================\n// PERC-622: AdvanceOraclePhase (permissionless)\n// ============================================================================\n\n/**\n * AdvanceOraclePhase: 1 account\n * Permissionless — no signer required beyond fee payer.\n */\nexport const ACCOUNTS_ADVANCE_ORACLE_PHASE: readonly AccountSpec[] = [\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n// ============================================================================\n// PERC-623: Keeper Fund Instructions\n// ============================================================================\n\n/**\n * TopUpKeeperFund: 3 accounts\n * Permissionless — anyone can fund. Transfers lamports directly (no system program).\n */\nexport const ACCOUNTS_TOPUP_KEEPER_FUND: readonly AccountSpec[] = [\n { name: \"funder\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"keeperFund\", signer: false, writable: true },\n] as const;\n\n// Note: WithdrawKeeperReward has no separate instruction.\n// Rewards are paid automatically during KeeperCrank (tag 5).\n\n// ============================================================================\n// PERC-8110: SetOiImbalanceHardBlock\n// ============================================================================\n\n/**\n * SetOiImbalanceHardBlock: 2 accounts\n * Sets the OI imbalance hard-block threshold (admin only)\n */\nexport const ACCOUNTS_SET_OI_IMBALANCE_HARD_BLOCK: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: false },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n// ============================================================================\n// PERC-608: Position NFT Instructions (tags 64–69)\n// ============================================================================\n\n/**\n * MintPositionNft: 10 accounts\n * Creates a Token-2022 position NFT for an open position.\n */\nexport const ACCOUNTS_MINT_POSITION_NFT: readonly AccountSpec[] = [\n { name: \"payer\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"positionNftPda\", signer: false, writable: true },\n { name: \"nftMint\", signer: false, writable: true },\n { name: \"ownerAta\", signer: false, writable: true },\n { name: \"owner\", signer: true, writable: false },\n { name: \"vaultAuthority\", signer: false, writable: false },\n { name: \"token2022Program\", signer: false, writable: false },\n { name: \"systemProgram\", signer: false, writable: false },\n { name: \"rent\", signer: false, writable: false },\n] as const;\n\n/**\n * TransferPositionOwnership: 8 accounts\n * Transfer position NFT and update on-chain owner. Requires pending_settlement == 0.\n */\nexport const ACCOUNTS_TRANSFER_POSITION_OWNERSHIP: readonly AccountSpec[] = [\n { name: \"currentOwner\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"positionNftPda\", signer: false, writable: true },\n { name: \"nftMint\", signer: false, writable: true },\n { name: \"currentOwnerAta\", signer: false, writable: true },\n { name: \"newOwnerAta\", signer: false, writable: true },\n { name: \"newOwner\", signer: false, writable: false },\n { name: \"token2022Program\", signer: false, writable: false },\n] as const;\n\n/**\n * BurnPositionNft: 7 accounts\n * Burns NFT and closes PositionNft + mint PDAs after position is closed.\n */\nexport const ACCOUNTS_BURN_POSITION_NFT: readonly AccountSpec[] = [\n { name: \"owner\", signer: true, writable: true },\n { name: \"slab\", signer: false, writable: true },\n { name: \"positionNftPda\", signer: false, writable: true },\n { name: \"nftMint\", signer: false, writable: true },\n { name: \"ownerAta\", signer: false, writable: true },\n { name: \"vaultAuthority\", signer: false, writable: false },\n { name: \"token2022Program\", signer: false, writable: false },\n] as const;\n\n/**\n * SetPendingSettlement: 3 accounts\n * Keeper/admin sets pending_settlement flag before funding transfer.\n * Protected by admin allowlist (GH#1475).\n */\nexport const ACCOUNTS_SET_PENDING_SETTLEMENT: readonly AccountSpec[] = [\n { name: \"keeper\", signer: true, writable: false },\n { name: \"slab\", signer: false, writable: false },\n { name: \"positionNftPda\", signer: false, writable: true },\n] as const;\n\n/**\n * ClearPendingSettlement: 3 accounts\n * Keeper/admin clears pending_settlement flag after KeeperCrank.\n * Protected by admin allowlist (GH#1475).\n */\nexport const ACCOUNTS_CLEAR_PENDING_SETTLEMENT: readonly AccountSpec[] = [\n { name: \"keeper\", signer: true, writable: false },\n { name: \"slab\", signer: false, writable: false },\n { name: \"positionNftPda\", signer: false, writable: true },\n] as const;\n\n// ============================================================================\n// PERC-8111: SetWalletCap\n// ============================================================================\n\n/**\n * SetWalletCap: 2 accounts\n * Sets the per-wallet position cap (admin only). capE6=0 disables.\n */\nexport const ACCOUNTS_SET_WALLET_CAP: readonly AccountSpec[] = [\n { name: \"admin\", signer: true, writable: false },\n { name: \"slab\", signer: false, writable: true },\n] as const;\n\n// ============================================================================\n// WELL-KNOWN PROGRAM/SYSVAR KEYS\n// ============================================================================\n\nexport const WELL_KNOWN = {\n tokenProgram: TOKEN_PROGRAM_ID,\n clock: SYSVAR_CLOCK_PUBKEY,\n rent: SYSVAR_RENT_PUBKEY,\n systemProgram: SystemProgram.programId,\n} as const;\n","/**\n * Percolator program error definitions.\n * Each error includes a name and actionable guidance.\n */\ninterface ErrorInfo {\n name: string;\n hint: string;\n}\n\nexport const PERCOLATOR_ERRORS: Record<number, ErrorInfo> = {\n 0: {\n name: \"InvalidMagic\",\n hint: \"The slab account has invalid data. Ensure you're using the correct slab address.\",\n },\n 1: {\n name: \"InvalidVersion\",\n hint: \"Slab version mismatch. The program may have been upgraded. Check for CLI updates.\",\n },\n 2: {\n name: \"AlreadyInitialized\",\n hint: \"This account is already initialized. Use a different account or skip initialization.\",\n },\n 3: {\n name: \"NotInitialized\",\n hint: \"The slab is not initialized. Run 'init-market' first.\",\n },\n 4: {\n name: \"InvalidSlabLen\",\n hint: \"Slab account has wrong size. Create a new slab account with correct size.\",\n },\n 5: {\n name: \"InvalidOracleKey\",\n hint: \"Oracle account doesn't match config. Check the --oracle parameter matches the market's oracle.\",\n },\n 6: {\n name: \"OracleStale\",\n hint: \"Oracle price is too old. Wait for oracle to update or check if oracle is paused.\",\n },\n 7: {\n name: \"OracleConfTooWide\",\n hint: \"Oracle confidence interval is too wide. Wait for more stable market conditions.\",\n },\n 8: {\n name: \"InvalidVaultAta\",\n hint: \"Vault token account is invalid. Check the vault account is correctly configured.\",\n },\n 9: {\n name: \"InvalidMint\",\n hint: \"Token mint doesn't match. Ensure you're using the correct collateral token.\",\n },\n 10: {\n name: \"ExpectedSigner\",\n hint: \"Missing required signature. Ensure the correct wallet is specified with --wallet.\",\n },\n 11: {\n name: \"ExpectedWritable\",\n hint: \"Account must be writable. This is likely a CLI bug - please report it.\",\n },\n 12: {\n name: \"OracleInvalid\",\n hint: \"Oracle data is invalid. Check the oracle account is a valid Pyth price feed.\",\n },\n 13: {\n name: \"EngineInsufficientBalance\",\n hint: \"Not enough collateral. Deposit more with 'deposit' before this operation.\",\n },\n 14: {\n name: \"EngineUndercollateralized\",\n hint: \"Account is undercollateralized. Deposit more collateral or reduce position size.\",\n },\n 15: {\n name: \"EngineUnauthorized\",\n hint: \"Not authorized. You must be the account owner or admin for this operation.\",\n },\n 16: {\n name: \"EngineInvalidMatchingEngine\",\n hint: \"Matcher program/context doesn't match LP config. Check --matcher-program and --matcher-context.\",\n },\n 17: {\n name: \"EnginePnlNotWarmedUp\",\n hint: \"PnL not warmed up yet. Wait for the warmup period to complete before trading.\",\n },\n 18: {\n name: \"EngineOverflow\",\n hint: \"Numeric overflow in calculation. Try a smaller amount or position size.\",\n },\n 19: {\n name: \"EngineAccountNotFound\",\n hint: \"Account not found at this index. Run 'init-user' or 'init-lp' first, or check the index.\",\n },\n 20: {\n name: \"EngineNotAnLPAccount\",\n hint: \"Expected an LP account but got a user account. Check the --lp-idx parameter.\",\n },\n 21: {\n name: \"EnginePositionSizeMismatch\",\n hint: \"Position size mismatch between user and LP. This shouldn't happen - please report it.\",\n },\n 22: {\n name: \"EngineRiskReductionOnlyMode\",\n hint: \"Market is in risk-reduction mode. Only position-reducing trades are allowed.\",\n },\n 23: {\n name: \"EngineAccountKindMismatch\",\n hint: \"Wrong account type. User operations require user accounts, LP operations require LP accounts.\",\n },\n 24: {\n name: \"InvalidTokenAccount\",\n hint: \"Token account is invalid. Ensure you have an ATA for the collateral mint.\",\n },\n 25: {\n name: \"InvalidTokenProgram\",\n hint: \"Invalid token program. Ensure SPL Token program is accessible.\",\n },\n 26: {\n name: \"InvalidConfigParam\",\n hint: \"Invalid configuration parameter. Check that leverage, fees, and risk thresholds are within allowed ranges.\",\n },\n 27: {\n name: \"HyperpTradeNoCpiDisabled\",\n hint: \"TradeNoCpi is disabled for this market. Use TradeCpi with LP matching instead.\",\n },\n 28: {\n name: \"InsuranceMintAlreadyExists\",\n hint: \"Insurance LP mint already exists for this market. Cannot recreate.\",\n },\n 29: {\n name: \"InsuranceMintNotCreated\",\n hint: \"Insurance LP mint has not been created yet. Run CreateInsuranceMint first.\",\n },\n 30: {\n name: \"InsuranceBelowThreshold\",\n hint: \"Insurance fund balance is below the required threshold. Deposit more to insurance fund.\",\n },\n 31: {\n name: \"InsuranceZeroAmount\",\n hint: \"Insurance deposit/withdrawal amount must be greater than zero.\",\n },\n 32: {\n name: \"InsuranceSupplyMismatch\",\n hint: \"Insurance LP token supply doesn't match vault balance. This is an internal error - please report it.\",\n },\n 33: {\n name: \"MarketPaused\",\n hint: \"This market is currently paused by the admin. Trading, deposits, and withdrawals are disabled.\",\n },\n 34: {\n name: \"AdminRenounceNotAllowed\",\n hint: \"Cannot renounce admin — the market must be RESOLVED first before renouncing admin control.\",\n },\n 35: {\n name: \"InvalidConfirmation\",\n hint: \"Invalid confirmation code for RenounceAdmin. This is a safety check — please verify the code.\",\n },\n 36: {\n name: \"InsufficientSeed\",\n hint: \"Vault seed balance is below the required minimum (500,000,000 raw tokens). Deposit more tokens to the vault before InitMarket.\",\n },\n 37: {\n name: \"InsufficientDexLiquidity\",\n hint: \"DEX pool has insufficient liquidity for safe Hyperp oracle bootstrapping. The quote-side reserves must meet the minimum threshold.\",\n },\n 38: {\n name: \"LpVaultAlreadyExists\",\n hint: \"LP vault already created for this market. Each market can only have one LP vault.\",\n },\n 39: {\n name: \"LpVaultNotCreated\",\n hint: \"LP vault not yet created. Call CreateLpVault first before depositing or withdrawing.\",\n },\n 40: {\n name: \"LpVaultZeroAmount\",\n hint: \"LP vault deposit or withdrawal amount must be greater than zero.\",\n },\n 41: {\n name: \"LpVaultSupplyMismatch\",\n hint: \"LP vault supply/capital mismatch — LP share supply > 0 but vault capital is 0. This is an internal error — please report it.\",\n },\n 42: {\n name: \"LpVaultWithdrawExceedsAvailable\",\n hint: \"LP vault withdrawal exceeds available capital. Some capital is reserved for open interest coverage.\",\n },\n 43: {\n name: \"LpVaultInvalidFeeShare\",\n hint: \"LP vault fee share basis points out of range. Must be 0–10,000 (0%–100%).\",\n },\n 44: {\n name: \"LpVaultNoNewFees\",\n hint: \"No new fees to distribute to LP vault. Wait for more trading activity to accrue fees.\",\n },\n // ── PERC-312 / PERC-314 / PERC-315 / PERC-309 / PERC-8111 / PERC-8110 (codes 45–60) ─────────\n 45: {\n name: \"SafetyValveDominantSideBlocked\",\n hint: \"New position on the dominant side is blocked while the market is rebalancing (safety valve).\",\n },\n 46: {\n name: \"DisputeWindowClosed\",\n hint: \"The dispute window for this resolved market has closed.\",\n },\n 47: {\n name: \"DisputeAlreadyExists\",\n hint: \"A dispute already exists for this market — cannot open another.\",\n },\n 48: {\n name: \"MarketNotResolved\",\n hint: \"Market is not resolved — cannot dispute an active market.\",\n },\n 49: {\n name: \"NoActiveDispute\",\n hint: \"No active dispute found for this market.\",\n },\n 50: {\n name: \"LpCollateralDisabled\",\n hint: \"LP collateral is not enabled for this market.\",\n },\n 51: {\n name: \"LpCollateralPositionOpen\",\n hint: \"Cannot withdraw LP collateral while a position is still open.\",\n },\n 52: {\n name: \"WithdrawQueueAlreadyExists\",\n hint: \"A withdrawal queue entry already exists for this user/market.\",\n },\n 53: {\n name: \"WithdrawQueueNotFound\",\n hint: \"No queued withdrawal found for this user/market.\",\n },\n 54: {\n name: \"WithdrawQueueNothingClaimable\",\n hint: \"Nothing is claimable from the withdrawal queue this epoch — wait for the next epoch.\",\n },\n 55: {\n name: \"AuditViolation\",\n hint: \"Audit crank detected a conservation invariant violation — this is a critical internal error, please report it.\",\n },\n 56: {\n name: \"CrossMarginPairNotFound\",\n hint: \"Cross-margin offset pair is not configured for these two slabs.\",\n },\n 57: {\n name: \"CrossMarginAttestationStale\",\n hint: \"Cross-margin attestation is stale — too many slots have elapsed since the last attestation.\",\n },\n 58: {\n name: \"WalletPositionCapExceeded\",\n hint: \"Trade rejected: the resulting position would exceed the per-wallet position cap (max_wallet_pos_e6) for this market.\",\n },\n 59: {\n name: \"OiImbalanceHardBlock\",\n hint: \"Trade rejected: it would increase the OI imbalance (|long_oi − short_oi| / total_oi) beyond the configured hard-block threshold (oi_imbalance_hard_block_bps). Try the opposite side.\",\n },\n 60: {\n name: \"EngineInvalidEntryPrice\",\n hint: \"Entry price must be positive when opening a position.\",\n },\n 61: {\n name: \"EngineSideBlocked\",\n hint: \"New position blocked — this side is in DrainOnly or ResetPending mode. Wait for the market to stabilise.\",\n },\n 62: {\n name: \"EngineCorruptState\",\n hint: \"Engine detected a corrupt state invariant violation — this is a critical internal error, please report it.\",\n },\n 63: {\n name: \"InsuranceFundNotDepleted\",\n hint: \"ADL rejected — insurance fund is not fully depleted (balance > 0). ADL is only permitted once insurance is exhausted.\",\n },\n 64: {\n name: \"NoAdlCandidates\",\n hint: \"ADL rejected — no eligible candidate positions found for deleveraging.\",\n },\n 65: {\n name: \"BankruptPositionAlreadyClosed\",\n hint: \"ADL rejected — the target position is already closed (size == 0). Re-rank and pick a different target.\",\n },\n};\n\n/**\n * Decode a custom program error code to its info.\n */\nexport function decodeError(code: number): ErrorInfo | undefined {\n return PERCOLATOR_ERRORS[code];\n}\n\n/**\n * Get error name from code.\n */\nexport function getErrorName(code: number): string {\n return PERCOLATOR_ERRORS[code]?.name ?? `Unknown(${code})`;\n}\n\n/**\n * Get actionable hint for error code.\n */\nexport function getErrorHint(code: number): string | undefined {\n return PERCOLATOR_ERRORS[code]?.hint;\n}\n\n/** Max hex digits for `custom program error: 0x...` — Solana custom errors are u32. */\nconst CUSTOM_ERROR_HEX_MAX_LEN = 8;\n\n/**\n * Parse error from transaction logs.\n * Looks for \"Program ... failed: custom program error: 0x...\"\n *\n * Hex capture is bounded (1–8 digits) so pathological logs cannot feed unbounded\n * strings into `parseInt` or produce precision-loss codes above u32.\n */\nexport function parseErrorFromLogs(logs: string[]): {\n code: number;\n name: string;\n hint?: string;\n} | null {\n if (!Array.isArray(logs)) {\n return null;\n }\n const re = new RegExp(\n `custom program error: 0x([0-9a-fA-F]{1,${CUSTOM_ERROR_HEX_MAX_LEN}})(?![0-9a-fA-F])`,\n \"i\",\n );\n for (const log of logs) {\n if (typeof log !== \"string\") {\n continue;\n }\n const match = log.match(re);\n if (match) {\n const code = parseInt(match[1], 16);\n if (!Number.isFinite(code) || code < 0 || code > 0xffff_ffff) {\n continue;\n }\n const info = decodeError(code);\n return {\n code,\n name: info?.name ?? `Unknown(${code})`,\n hint: info?.hint,\n };\n }\n }\n return null;\n}\n","import { Connection, PublicKey } from \"@solana/web3.js\";\n\n// =============================================================================\n// Browser-compatible read helpers using DataView\n// (the npm 'buffer' polyfill lacks readBigUInt64LE / readBigInt64LE)\n// =============================================================================\n\n/** Wrap a Uint8Array in a DataView sharing the same underlying buffer. */\nfunction dv(data: Uint8Array): DataView {\n return new DataView(data.buffer, data.byteOffset, data.byteLength);\n}\n/** Read a single unsigned byte at `off`. */\nfunction readU8(data: Uint8Array, off: number): number {\n return data[off];\n}\n/** Read a little-endian u16 at `off`. */\nfunction readU16LE(data: Uint8Array, off: number): number {\n return dv(data).getUint16(off, true);\n}\n/** Read a little-endian u32 at `off`. */\nfunction readU32LE(data: Uint8Array, off: number): number {\n return dv(data).getUint32(off, true);\n}\n/** Read a little-endian u64 at `off` as a BigInt. */\nfunction readU64LE(data: Uint8Array, off: number): bigint {\n return dv(data).getBigUint64(off, true);\n}\n/** Read a little-endian signed i64 at `off` as a BigInt. */\nfunction readI64LE(data: Uint8Array, off: number): bigint {\n return dv(data).getBigInt64(off, true);\n}\n\n// =============================================================================\n// Helper: read signed/unsigned i128 from buffer\n// =============================================================================\n\n/**\n * Read a little-endian signed i128 at `offset`.\n * Composed from two u64 halves; sign-extends if the high bit is set.\n */\nfunction readI128LE(buf: Uint8Array, offset: number): bigint {\n const lo = readU64LE(buf, offset);\n const hi = readU64LE(buf, offset + 8);\n const unsigned = (hi << 64n) | lo;\n const SIGN_BIT = 1n << 127n;\n if (unsigned >= SIGN_BIT) {\n return unsigned - (1n << 128n);\n }\n return unsigned;\n}\n\n/** Read a little-endian unsigned u128 at `offset` as a BigInt. */\nfunction readU128LE(buf: Uint8Array, offset: number): bigint {\n const lo = readU64LE(buf, offset);\n const hi = readU64LE(buf, offset + 8);\n return (hi << 64n) | lo;\n}\n\n// =============================================================================\n// Slab Layout Version Detection\n// =============================================================================\n// The deployed devnet program uses a different struct layout (V0) than the SDK\n// was updated for (V1). V1 includes PERC-120/121/122/298/299/300/301/306/328\n// struct changes that have NOT been deployed to devnet yet.\n//\n// V0 (deployed devnet): HEADER=72, CONFIG=408, ENGINE_OFF=480, ACCOUNT_SIZE=240\n// - InsuranceFund: {balance: U128, fee_revenue: U128} (32 bytes)\n// - RiskParams: 56 bytes (basic fields only)\n// - No mark_price, no long_oi/short_oi, no emergency OI cap fields\n// - No partial liquidation field in Account (240 bytes)\n//\n// V1 (future upgrade): HEADER=104, CONFIG=536, ENGINE_OFF=640, ACCOUNT_SIZE=248\n// - InsuranceFund: expanded with isolation fields (72 bytes)\n// - RiskParams: 288 bytes (premium funding, partial liq, dynamic fees)\n// - Has mark_price, long_oi/short_oi, emergency fields\n// - Account has last_partial_liquidation_slot (248 bytes)\n// =============================================================================\n\nconst MAGIC: bigint = 0x504552434f4c4154n; // \"PERCOLAT\"\n\n// Flag bits in header._padding[0] at offset 13\nconst FLAG_RESOLVED = 1 << 0;\n\n/**\n * Full slab layout descriptor. Returned by detectSlabLayout().\n * All engine field offsets are relative to engineOff.\n */\nexport interface SlabLayout {\n version: 0 | 1 | 2;\n headerLen: number;\n configOffset: number;\n configLen: number;\n reservedOff: number; // offset of _reserved in header\n engineOff: number;\n accountSize: number;\n maxAccounts: number;\n bitmapWords: number;\n accountsOff: number; // absolute offset of accounts array in slab\n\n // Engine field offsets (relative to engineOff)\n engineInsuranceOff: number;\n engineParamsOff: number;\n paramsSize: number;\n engineCurrentSlotOff: number;\n engineFundingIndexOff: number;\n engineLastFundingSlotOff: number;\n engineFundingRateBpsOff: number;\n engineMarkPriceOff: number; // -1 if not present (V0)\n engineLastCrankSlotOff: number;\n engineMaxCrankStalenessOff: number;\n engineTotalOiOff: number;\n engineLongOiOff: number; // -1 if not present (V0)\n engineShortOiOff: number; // -1 if not present (V0)\n engineCTotOff: number;\n enginePnlPosTotOff: number;\n engineLiqCursorOff: number;\n engineGcCursorOff: number;\n engineLastSweepStartOff: number;\n engineLastSweepCompleteOff: number;\n engineCrankCursorOff: number;\n engineSweepStartIdxOff: number;\n engineLifetimeLiquidationsOff: number;\n engineLifetimeForceClosesOff: number;\n engineNetLpPosOff: number;\n engineLpSumAbsOff: number;\n engineLpMaxAbsOff: number;\n engineLpMaxAbsSweepOff: number;\n engineEmergencyOiModeOff: number; // -1 if not present (V0)\n engineEmergencyStartSlotOff: number; // -1 if not present (V0)\n engineLastBreakerSlotOff: number; // -1 if not present (V0)\n engineBitmapOff: number; // relative to engineOff\n postBitmap: number; // 2 = free_head only (V1D), 18 = num_used + pad + next_account_id + free_head\n acctOwnerOff: number; // byte offset of owner pubkey within an account slot\n\n // Insurance fund layout\n hasInsuranceIsolation: boolean;\n engineInsuranceIsolatedOff: number; // -1 if not present (V0)\n engineInsuranceIsolationBpsOff: number; // -1 if not present (V0)\n}\n\n// ---- V0 layout constants (deployed devnet program) ----\nconst V0_HEADER_LEN = 72;\nconst V0_CONFIG_LEN = 408;\nconst V0_ENGINE_OFF = 480; // align_up(72 + 408, 8) = 480\nconst V0_ACCOUNT_SIZE = 240;\nconst V0_RESERVED_OFF = 48; // magic(8)+version(4)+bump(1)+pad(3)+admin(32) = 48\n\n// V0 engine: vault(16) + insurance{balance(16),fee_revenue(16)}=32 → params at 48\n// V0 RiskParams: 56 bytes → runtime state at 104\nconst V0_ENGINE_PARAMS_OFF = 48;\nconst V0_PARAMS_SIZE = 56;\nconst V0_ENGINE_CURRENT_SLOT_OFF = 104;\nconst V0_ENGINE_FUNDING_INDEX_OFF = 112;\nconst V0_ENGINE_LAST_FUNDING_SLOT_OFF = 128;\nconst V0_ENGINE_FUNDING_RATE_BPS_OFF = 136;\nconst V0_ENGINE_LAST_CRANK_SLOT_OFF = 144;\nconst V0_ENGINE_MAX_CRANK_STALENESS_OFF = 152;\nconst V0_ENGINE_TOTAL_OI_OFF = 160;\nconst V0_ENGINE_C_TOT_OFF = 176;\nconst V0_ENGINE_PNL_POS_TOT_OFF = 192;\nconst V0_ENGINE_LIQ_CURSOR_OFF = 208;\nconst V0_ENGINE_GC_CURSOR_OFF = 210;\nconst V0_ENGINE_LAST_SWEEP_START_OFF = 216;\nconst V0_ENGINE_LAST_SWEEP_COMPLETE_OFF = 224;\nconst V0_ENGINE_CRANK_CURSOR_OFF = 232;\nconst V0_ENGINE_SWEEP_START_IDX_OFF = 234;\nconst V0_ENGINE_LIFETIME_LIQUIDATIONS_OFF = 240;\nconst V0_ENGINE_LIFETIME_FORCE_CLOSES_OFF = 248;\nconst V0_ENGINE_NET_LP_POS_OFF = 256;\nconst V0_ENGINE_LP_SUM_ABS_OFF = 272;\nconst V0_ENGINE_LP_MAX_ABS_OFF = 288;\nconst V0_ENGINE_LP_MAX_ABS_SWEEP_OFF = 304;\nconst V0_ENGINE_BITMAP_OFF = 320;\n\n// ---- V1 layout constants (deployed devnet program, PERC-1094 corrected) ----\n// BPF (SBF) target: u128 alignment = 8, so CONFIG_LEN = 496 on-chain.\n// ENGINE_OFF = align_up(HEADER=104 + CONFIG=496, 8) = 600.\n// Previous value (640) was wrong — it assumed CONFIG_LEN=536 from the native build assertion.\nconst V1_HEADER_LEN = 104;\nconst V1_CONFIG_LEN = 496; // BPF (SBF) on-chain value; native test build would be 512\nconst V1_ENGINE_OFF = 600; // align_up(104 + 496, 8) = 600 (was 640 — corrected in PERC-1094)\n// Legacy: CONFIG_LEN=536 was used in pre-PERC-1094 SDK. Some orphaned slabs on devnet may use\n// ENGINE_OFF=640 (65352 bytes for small). We add them to V1_SIZES_LEGACY for read-only parsing.\nconst V1_ENGINE_OFF_LEGACY = 640;\nconst V1_ACCOUNT_SIZE = 248;\nconst V1_RESERVED_OFF = 80;\n\n// V1 engine: vault(16) + insurance expanded(56) → params at 72\n// V1 RiskParams: 288 bytes → runtime state at 360\nconst V1_ENGINE_PARAMS_OFF = 72;\nconst V1_PARAMS_SIZE = 288;\nconst V1_ENGINE_CURRENT_SLOT_OFF = 360;\nconst V1_ENGINE_FUNDING_INDEX_OFF = 368;\nconst V1_ENGINE_LAST_FUNDING_SLOT_OFF = 384;\nconst V1_ENGINE_FUNDING_RATE_BPS_OFF = 392;\nconst V1_ENGINE_MARK_PRICE_OFF = 400;\nconst V1_ENGINE_LAST_CRANK_SLOT_OFF = 424;\nconst V1_ENGINE_MAX_CRANK_STALENESS_OFF = 432;\nconst V1_ENGINE_TOTAL_OI_OFF = 440;\nconst V1_ENGINE_LONG_OI_OFF = 456;\nconst V1_ENGINE_SHORT_OI_OFF = 472;\nconst V1_ENGINE_C_TOT_OFF = 488;\nconst V1_ENGINE_PNL_POS_TOT_OFF = 504;\nconst V1_ENGINE_LIQ_CURSOR_OFF = 520;\nconst V1_ENGINE_GC_CURSOR_OFF = 522;\nconst V1_ENGINE_LAST_SWEEP_START_OFF = 528;\nconst V1_ENGINE_LAST_SWEEP_COMPLETE_OFF = 536;\nconst V1_ENGINE_CRANK_CURSOR_OFF = 544;\nconst V1_ENGINE_SWEEP_START_IDX_OFF = 546;\nconst V1_ENGINE_LIFETIME_LIQUIDATIONS_OFF = 552;\nconst V1_ENGINE_LIFETIME_FORCE_CLOSES_OFF = 560;\nconst V1_ENGINE_NET_LP_POS_OFF = 568;\nconst V1_ENGINE_LP_SUM_ABS_OFF = 584;\nconst V1_ENGINE_LP_MAX_ABS_OFF = 600;\nconst V1_ENGINE_LP_MAX_ABS_SWEEP_OFF = 616;\nconst V1_ENGINE_EMERGENCY_OI_MODE_OFF = 632;\nconst V1_ENGINE_EMERGENCY_START_SLOT_OFF = 640;\nconst V1_ENGINE_LAST_BREAKER_SLOT_OFF = 648;\nconst V1_ENGINE_BITMAP_OFF = 656;\n// On-chain V1_LEGACY slabs (65352 bytes) place the bitmap 16 bytes later than\n// computeSlabSize predicts (formula bitmapOff=656 gives size=65352 correctly, but\n// the deployed program stores the bitmap at rel=672 and the owner field at +200).\n// These corrected values must be used for actual byte-level parsing.\nconst V1_LEGACY_ENGINE_BITMAP_OFF_ACTUAL = 672; // relative to engineOff (abs = 640+672 = 1312)\nconst V1_LEGACY_ACCT_OWNER_OFF = 200; // vs the usual ACCT_OWNER_OFF=184\n\n// ---- V1D layout constants (actually deployed devnet V1 program, rev ac18a0e) ----\n// The deployed V1 program has a DIFFERENT struct layout than the V1 constants above.\n// Key differences:\n// - MarketConfig is smaller (BPF CONFIG_LEN=320 vs V1's 496) — older revision\n// - InsuranceFund is 80 bytes (V1 assumed 56), so params starts at engine+96 (not 72)\n// - Engine lacks lp_max_abs, lp_max_abs_sweep, emergency_oi, trade_twap fields\n// - Bitmap at engine+624 (not 656)\n// Confirmed by on-chain probing of slab 6ZytbpV4 (the only active V1 market).\nconst V1D_CONFIG_LEN = 320;\nconst V1D_ENGINE_OFF = 424; // align_up(104 + 320, 8) = 424\nconst V1D_ACCOUNT_SIZE = 248;\n\n// V1D engine field offsets (relative to engineOff):\n// vault(16) + InsuranceFund(80) → params at 96; RiskParams(288) → runtime at 384\nconst V1D_ENGINE_INSURANCE_OFF = 16;\nconst V1D_ENGINE_PARAMS_OFF = 96;\nconst V1D_PARAMS_SIZE = 288;\nconst V1D_ENGINE_CURRENT_SLOT_OFF = 384;\nconst V1D_ENGINE_FUNDING_INDEX_OFF = 392;\nconst V1D_ENGINE_LAST_FUNDING_SLOT_OFF = 408;\nconst V1D_ENGINE_FUNDING_RATE_BPS_OFF = 416;\nconst V1D_ENGINE_MARK_PRICE_OFF = 424;\n// funding_frozen(1+7pad) at 432, funding_frozen_rate(8) at 440\nconst V1D_ENGINE_LAST_CRANK_SLOT_OFF = 448;\nconst V1D_ENGINE_MAX_CRANK_STALENESS_OFF = 456;\nconst V1D_ENGINE_TOTAL_OI_OFF = 464;\nconst V1D_ENGINE_LONG_OI_OFF = 480;\nconst V1D_ENGINE_SHORT_OI_OFF = 496;\nconst V1D_ENGINE_C_TOT_OFF = 512;\nconst V1D_ENGINE_PNL_POS_TOT_OFF = 528;\nconst V1D_ENGINE_LIQ_CURSOR_OFF = 544;\nconst V1D_ENGINE_GC_CURSOR_OFF = 546;\nconst V1D_ENGINE_LAST_SWEEP_START_OFF = 552;\nconst V1D_ENGINE_LAST_SWEEP_COMPLETE_OFF = 560;\nconst V1D_ENGINE_CRANK_CURSOR_OFF = 568;\nconst V1D_ENGINE_SWEEP_START_IDX_OFF = 570;\nconst V1D_ENGINE_LIFETIME_LIQUIDATIONS_OFF = 576;\nconst V1D_ENGINE_LIFETIME_FORCE_CLOSES_OFF = 584;\nconst V1D_ENGINE_NET_LP_POS_OFF = 592;\nconst V1D_ENGINE_LP_SUM_ABS_OFF = 608;\n// lp_max_abs, lp_max_abs_sweep, emergency_*, trade_twap_* do NOT exist in this version\nconst V1D_ENGINE_BITMAP_OFF = 624;\n\n// ---- V2 layout constants (BPF intermediate layout, ENGINE_OFF=600, BITMAP_OFF=432) ----\n// V2 shares ENGINE_OFF=600 with V1, but has a completely different engine struct layout:\n// - CONFIG_LEN=496 (same as V1 on-chain), HEADER_LEN=104, ACCOUNT_SIZE=248\n// - Engine lacks mark_price, long_oi, short_oi, emergency OI fields\n// - Different field offsets than V1D (which has ENGINE_OFF=424)\n// V2 is identified by reading the version field at slab header offset 8 (u32 LE) == 2.\n// Without data, V2 cannot be distinguished from V1D by size alone (postBitmap=18 produces\n// identical sizes to V1D postBitmap=2 — both 65088 for 256 accounts).\nconst V2_HEADER_LEN = 104;\nconst V2_CONFIG_LEN = 496;\nconst V2_ENGINE_OFF = 600; // align_up(104 + 496, 8) = 600\nconst V2_ACCOUNT_SIZE = 248;\nconst V2_ENGINE_BITMAP_OFF = 432;\n\n// V2 engine field offsets (relative to engineOff)\nconst V2_ENGINE_CURRENT_SLOT_OFF = 352;\nconst V2_ENGINE_FUNDING_INDEX_OFF = 360;\nconst V2_ENGINE_LAST_FUNDING_SLOT_OFF = 376;\nconst V2_ENGINE_FUNDING_RATE_BPS_OFF = 384;\nconst V2_ENGINE_LAST_CRANK_SLOT_OFF = 392;\nconst V2_ENGINE_MAX_CRANK_STALENESS_OFF = 400;\nconst V2_ENGINE_TOTAL_OI_OFF = 408;\nconst V2_ENGINE_C_TOT_OFF = 424;\nconst V2_ENGINE_PNL_POS_TOT_OFF = 440;\nconst V2_ENGINE_LIQ_CURSOR_OFF = 456;\nconst V2_ENGINE_GC_CURSOR_OFF = 458;\nconst V2_ENGINE_LAST_SWEEP_START_OFF = 464;\nconst V2_ENGINE_LAST_SWEEP_COMPLETE_OFF = 472;\nconst V2_ENGINE_CRANK_CURSOR_OFF = 480;\nconst V2_ENGINE_SWEEP_START_IDX_OFF = 482;\nconst V2_ENGINE_LIFETIME_LIQUIDATIONS_OFF = 488;\nconst V2_ENGINE_LIFETIME_FORCE_CLOSES_OFF = 496;\nconst V2_ENGINE_NET_LP_POS_OFF = 504;\nconst V2_ENGINE_LP_SUM_ABS_OFF = 520;\nconst V2_ENGINE_LP_MAX_ABS_OFF = 536;\nconst V2_ENGINE_LP_MAX_ABS_SWEEP_OFF = 552;\n\n// ---- V_ADL layout constants (ADL-upgraded program, PERC-8270/8271) ----\n// This layout corresponds to the percolator lib at commit ed01137 (PERC-8270) which adds:\n// - Account: position_basis_q(i128,16)+adl_a_basis(u128,16)+adl_k_snap(i128,16)+adl_epoch_snap(u64,8) = +56 bytes\n// Plus 8-byte padding before position_basis_q (i128 requires 16-byte align on BPF) → +64 bytes/account\n// - RiskEngine: last_market_slot(u64)+funding_price_sample_last(u64)+materialized_account_count(u64)+last_oracle_price(u64) = +32 bytes\n// - Also adds: InsuranceFund expanded to 80 bytes (balance_incentive_reserve + _rebate_pad + _isolation_padding),\n// RiskParams expanded to 336 bytes (min_nonzero_mm_req, min_nonzero_im_req, insurance_floor, etc.),\n// pnl_matured_pos_tot(u128,16) field in RiskEngine (PERC-8267),\n// ADL side state fields (PERC-8268, +224 bytes engine before bitmap)\n//\n// BPF SLAB_LEN: 1288304 (large/4096-account tier) — verified by cargo build-sbf (PERC-8271)\n// ENGINE_OFF = 624 (HEADER=104 + CONFIG=520 native, aligned to 8 = 624)\n// ACCOUNT_SIZE = 312 (248 old + 8 pad for i128 alignment + 16+16+16+8 new ADL fields)\n// ENGINE_BITMAP_OFF = 1006 (sum of all fixed RiskEngine scalar fields before [u64; BITMAP_WORDS])\n// Derivation: SLAB_LEN=1288304 = 624 + accountsOff + 4096*312, accountsOff=9728,\n// bitmapOff=1006 → preAccountsLen=1006+512+18+8192=9728 (4096 accounts)\nconst V_ADL_ENGINE_OFF = 624; // align_up(HEADER=104 + CONFIG=520, 8) = 624\nconst V_ADL_CONFIG_LEN = 520; // BPF/native MarketConfig with current fields\nconst V_ADL_ACCOUNT_SIZE = 312; // 248 + 8(pad) + 56(new ADL fields) = 312 bytes\nconst V_ADL_ENGINE_PARAMS_OFF = 96; // vault(16) + InsuranceFund(80) = 96\n\n// V_ADL RiskParams: 336 bytes (same as V1M, includes all dynamic fee params)\nconst V_ADL_PARAMS_SIZE = 336;\n\n// V_ADL engine field offsets (relative to engineOff=624):\n// vault(16) + InsuranceFund(80) + RiskParams(336) = 432 bytes before current_slot\nconst V_ADL_ENGINE_CURRENT_SLOT_OFF = 432; // 96 + 336 = 432\nconst V_ADL_ENGINE_FUNDING_INDEX_OFF = 440; // 432 + 8\nconst V_ADL_ENGINE_LAST_FUNDING_SLOT_OFF = 456; // 440 + 16\nconst V_ADL_ENGINE_FUNDING_RATE_BPS_OFF = 464; // 456 + 8\n// PERC-8270 new fields at 472-504:\n// last_market_slot(8)@472, funding_price_sample_last(8)@480, materialized_account_count(8)@488, last_oracle_price(8)@496\nconst V_ADL_ENGINE_MARK_PRICE_OFF = 504; // 464+8+32 = 504 (shifted +104 from V1's 400)\n// funding_frozen(1+7pad=8)@512, funding_frozen_rate_snapshot(i64,8)@520\nconst V_ADL_ENGINE_LAST_CRANK_SLOT_OFF = 528; // was 424 in V1, +104\nconst V_ADL_ENGINE_MAX_CRANK_STALENESS_OFF = 536;\nconst V_ADL_ENGINE_TOTAL_OI_OFF = 544; // was 440 in V1, +104\nconst V_ADL_ENGINE_LONG_OI_OFF = 560; // was 456 in V1, +104\nconst V_ADL_ENGINE_SHORT_OI_OFF = 576; // was 472 in V1, +104\nconst V_ADL_ENGINE_C_TOT_OFF = 592; // was 488 in V1, +104\nconst V_ADL_ENGINE_PNL_POS_TOT_OFF = 608; // was 504 in V1, +104\n// pnl_matured_pos_tot(u128,16)@624 — NEW in PERC-8267\nconst V_ADL_ENGINE_LIQ_CURSOR_OFF = 640; // was 520 in V1, +120 (extra 16 for pnl_matured)\nconst V_ADL_ENGINE_GC_CURSOR_OFF = 642;\n// last_sweep_start(u64)@648, last_sweep_complete(u64)@656, crank_cursor(u16)@664, sweep_idx(u16)@666\nconst V_ADL_ENGINE_LAST_SWEEP_START_OFF = 648;\nconst V_ADL_ENGINE_LAST_SWEEP_COMPLETE_OFF = 656;\nconst V_ADL_ENGINE_CRANK_CURSOR_OFF = 664;\nconst V_ADL_ENGINE_SWEEP_START_IDX_OFF = 666;\n// lifetime_liquidations(u64)@672, lifetime_force_closes(u64)@680\nconst V_ADL_ENGINE_LIFETIME_LIQUIDATIONS_OFF = 672;\nconst V_ADL_ENGINE_LIFETIME_FORCE_CLOSES_OFF = 680;\n// ADL side state (PERC-8268, 224 bytes):\n// adl_mult_long/short(16ea), adl_coeff_long/short(16ea), adl_epoch_long/short(8ea),\n// adl_epoch_start_k_long/short(16ea), oi_eff_long/short_q(16ea),\n// side_mode_long(u8)+side_mode_short(u8)+pad(6), stored_pos_count×2, stale_count×2(all u64,8),\n// phantom_dust_bound_long/short_q(16ea) = 224 bytes at offsets 688–911\n// Then LP aggregates:\nconst V_ADL_ENGINE_NET_LP_POS_OFF = 904; // after ADL side state\nconst V_ADL_ENGINE_LP_SUM_ABS_OFF = 920;\nconst V_ADL_ENGINE_LP_MAX_ABS_OFF = 936;\nconst V_ADL_ENGINE_LP_MAX_ABS_SWEEP_OFF = 952;\n// emergency fields:\nconst V_ADL_ENGINE_EMERGENCY_OI_MODE_OFF = 968;\nconst V_ADL_ENGINE_EMERGENCY_START_SLOT_OFF = 976;\nconst V_ADL_ENGINE_LAST_BREAKER_SLOT_OFF = 984;\n// trade_twap_e6(8)@992, twap_last_slot(8)@1000\nconst V_ADL_ENGINE_BITMAP_OFF = 1006; // Verified: 1006+512+18+8192=9728 ✓ for 4096 accts\n\n// V_ADL account field offsets (relative to account slot start):\n// account_id(8)+capital(U128,16)+kind(u8+pad7=8)+pnl(I128,16)+reserved_pnl(u128,16)=64\nconst V_ADL_ACCT_WARMUP_STARTED_OFF = 64; // was 56\nconst V_ADL_ACCT_WARMUP_SLOPE_OFF = 72; // was 64\nconst V_ADL_ACCT_POSITION_SIZE_OFF = 88; // was 80\nconst V_ADL_ACCT_ENTRY_PRICE_OFF = 104; // was 96\nconst V_ADL_ACCT_FUNDING_INDEX_OFF = 112; // was 104\nconst V_ADL_ACCT_MATCHER_PROGRAM_OFF = 128; // was 120\nconst V_ADL_ACCT_MATCHER_CONTEXT_OFF = 160; // was 152\nconst V_ADL_ACCT_OWNER_OFF = 192; // was 184 (shifted +8 from reserved_pnl u64→u128)\nconst V_ADL_ACCT_FEE_CREDITS_OFF = 224; // was 216\nconst V_ADL_ACCT_LAST_FEE_SLOT_OFF = 240; // was 232\n\n// ---- V1M layout constants (mainnet-deployed V1 program, ESa89R5) ----\n// The mainnet program has a LARGER RiskParams (336 bytes vs V1's 288) and 22 extra\n// bytes in the runtime state (trade_twap_e6 + twap_last_slot + alignment padding).\n// ENGINE_OFF=640 (same as V1_LEGACY), CONFIG_LEN=536, ACCOUNT_SIZE=248.\n// Confirmed by byte-level probing of mainnet slab 8NY7rvQ (SOL/USDC Perpetual).\nconst V1M_ENGINE_OFF = 640; // align_up(104 + 536, 8) = 640 (same as V1_LEGACY)\nconst V1M_CONFIG_LEN = 536; // MarketConfig size in native/mainnet build\nconst V1M_ACCOUNT_SIZE = 248;\n// V1M2: rebuilt from main@4861c56, CONFIG_LEN=512 on SBF → ENGINE_OFF=616\nconst V1M2_ENGINE_OFF = 616; // align_up(104 + 512, 8) = 616\nconst V1M2_CONFIG_LEN = 512; // MarketConfig with u128 native alignment on SBF\nconst V1M_ENGINE_PARAMS_OFF = 72; // vault(16) + InsuranceFund(56) = 72 (same as V1)\nconst V1M2_ENGINE_PARAMS_OFF = 96; // vault(16) + InsuranceFund(80) = 96 (expanded in main@4861c56)\n\n// V1M RiskParams: 336 bytes (+48 over V1's 288)\n// Extra fields: fee_utilization_surge_bps(8) [in SDK V1 already? no → +8],\n// balance_incentive_reserve configs (+8?), min_nonzero_mm_req(u128=16),\n// min_nonzero_im_req(u128=16) = +48 total\nconst V1M_PARAMS_SIZE = 336;\n\n// V1M runtime state starts at engine+408 (72 + 336) instead of V1's +360\nconst V1M_ENGINE_CURRENT_SLOT_OFF = 408;\nconst V1M_ENGINE_FUNDING_INDEX_OFF = 416;\nconst V1M_ENGINE_LAST_FUNDING_SLOT_OFF = 432;\nconst V1M_ENGINE_FUNDING_RATE_BPS_OFF = 440;\nconst V1M_ENGINE_MARK_PRICE_OFF = 448;\n// funding_frozen(1+7pad) at 456, funding_frozen_rate(8) at 464\nconst V1M_ENGINE_LAST_CRANK_SLOT_OFF = 472;\nconst V1M_ENGINE_MAX_CRANK_STALENESS_OFF = 480;\nconst V1M_ENGINE_TOTAL_OI_OFF = 488;\nconst V1M_ENGINE_LONG_OI_OFF = 504;\nconst V1M_ENGINE_SHORT_OI_OFF = 520;\nconst V1M_ENGINE_C_TOT_OFF = 536;\nconst V1M_ENGINE_PNL_POS_TOT_OFF = 552;\nconst V1M_ENGINE_LIQ_CURSOR_OFF = 568;\nconst V1M_ENGINE_GC_CURSOR_OFF = 570;\nconst V1M_ENGINE_LAST_SWEEP_START_OFF = 576;\nconst V1M_ENGINE_LAST_SWEEP_COMPLETE_OFF = 584;\nconst V1M_ENGINE_CRANK_CURSOR_OFF = 592;\nconst V1M_ENGINE_SWEEP_START_IDX_OFF = 594;\nconst V1M_ENGINE_LIFETIME_LIQUIDATIONS_OFF = 600;\nconst V1M_ENGINE_LIFETIME_FORCE_CLOSES_OFF = 608;\nconst V1M_ENGINE_NET_LP_POS_OFF = 616;\nconst V1M_ENGINE_LP_SUM_ABS_OFF = 632;\nconst V1M_ENGINE_LP_MAX_ABS_OFF = 648;\nconst V1M_ENGINE_LP_MAX_ABS_SWEEP_OFF = 664;\nconst V1M_ENGINE_EMERGENCY_OI_MODE_OFF = 680;\nconst V1M_ENGINE_EMERGENCY_START_SLOT_OFF = 688;\nconst V1M_ENGINE_LAST_BREAKER_SLOT_OFF = 696;\n// trade_twap_e6(8) at 704, twap_last_slot(8) at 712 → bitmap at 720\n// No padding between twap_last_slot and used bitmap (u64 array is 8-byte\n// aligned and 720 % 8 == 0). Previous value of 726 was wrong — 726 % 8 = 6\n// which is invalid for a [u64; N] array under #[repr(C)].\nconst V1M_ENGINE_BITMAP_OFF = 720;\n\n// V1M2: mainnet program rebuilt from main@4861c56 with --features medium.\n// ENGINE_OFF=616 (not 640): CONFIG_LEN=512 on SBF because cfg(target_arch=\"bpf\")\n// doesn't match the SBF toolchain (target_arch=\"sbf\"), so u128 align=16 (native) applies.\n// align_up(HEADER=104 + CONFIG=512, 8) = 616.\n// Slab sizes match V_ADL exactly — disambiguation required via data inspection.\n// Confirmed by on-chain probing of slab 7T1Efij9 (SOL-PERP, 323312 bytes, medium tier).\n// Engine struct is larger than V1M (990 vs 720 bitmap offset = +270 runtime bytes).\n// New runtime fields inserted between fundingRateBps and markPrice:\n// +408: currentSlot, +416: fundingIndex(i128), +432: lastFundingSlot, +440: fundingRateBps\n// +448: NEW lastOracleUpdateSlot(?), +456: authorityPriceE6(?), +464-471: reserved\n// +472: lastEffectivePriceE6(?), +480: markPriceE6, +488-503: reserved\n// +504: lastCrankSlot, +512: maxCrankStaleness\nconst V1M2_ACCOUNT_SIZE = 312; // 248 + 64 bytes of new fields per account\nconst V1M2_ENGINE_BITMAP_OFF = 990; // expanded engine struct shifts bitmap forward\n// V1M2 runtime offsets (confirmed by on-chain probing of 7T1Efij9):\nconst V1M2_ENGINE_CURRENT_SLOT_OFF = 408; // same as V1M\nconst V1M2_ENGINE_FUNDING_INDEX_OFF = 416; // same as V1M\nconst V1M2_ENGINE_LAST_FUNDING_SLOT_OFF = 432; // same as V1M\nconst V1M2_ENGINE_FUNDING_RATE_BPS_OFF = 440; // same as V1M\nconst V1M2_ENGINE_MARK_PRICE_OFF = 480; // shifted +32 from V1M's 448\nconst V1M2_ENGINE_LAST_CRANK_SLOT_OFF = 504; // shifted +32 from V1M's 472\nconst V1M2_ENGINE_MAX_CRANK_STALENESS_OFF = 512; // shifted +32 from V1M's 480\n// OI and remaining fields: shifted proportionally. Use conservative offsets based on\n// V1M base + 32 byte shift for fields after fundingRateBps.\nconst V1M2_RUNTIME_SHIFT = 32; // bytes inserted between fundingRateBps and markPrice\n\n// For backward compatibility, export ENGINE_OFF and ENGINE_MARK_PRICE_OFF\n// (used by reinit-slab and other scripts). These refer to V1 layout.\nexport const ENGINE_OFF = V1_ENGINE_OFF;\nexport const ENGINE_MARK_PRICE_OFF = V1_ENGINE_MARK_PRICE_OFF;\n\n// ---- Known slab sizes per version and tier ----\n\n/**\n * Compute the total byte size of a slab given its layout parameters.\n * Used to pre-populate the known-size lookup maps at module load time.\n */\nfunction computeSlabSize(\n engineOff: number,\n bitmapOff: number,\n accountSize: number,\n maxAccounts: number,\n // postBitmap bytes immediately after the free-slot bitmap:\n // SDK default (V0/V1/V1-legacy): 18 = num_used(u16,2) + pad(6) + next_account_id(u64,8) + free_head(u16,2)\n // V1D deployed program: 2 = free_head(u16,2) only — no num_used, pad, or next_account_id\n postBitmap = 18,\n): number {\n const bitmapWords = Math.ceil(maxAccounts / 64);\n const bitmapBytes = bitmapWords * 8;\n const nextFreeBytes = maxAccounts * 2;\n const preAccountsLen = bitmapOff + bitmapBytes + postBitmap + nextFreeBytes;\n const accountsOff = Math.ceil(preAccountsLen / 8) * 8;\n return engineOff + accountsOff + maxAccounts * accountSize;\n}\n\nconst TIERS = [64, 256, 1024, 4096] as const;\n\n// Pre-compute known slab sizes for fast lookup\nconst V0_SIZES = new Map<number, number>();\nconst V1_SIZES = new Map<number, number>();\n// Legacy V1 sizes using incorrect ENGINE_OFF=640 (pre-PERC-1094). Orphaned on devnet; read-only.\nconst V1_SIZES_LEGACY = new Map<number, number>();\n// V1D: actually deployed V1 program (ENGINE_OFF=424, BITMAP_OFF=624)\nconst V1D_SIZES = new Map<number, number>();\n// V1D_SIZES_LEGACY: on-chain slabs created before GH#1234 when SDK assumed postBitmap=18.\n// These are 16 bytes larger per tier (micro=17080, small=65104, medium=257200, large=1025584).\n// The top active market (6ZytbpV4, $14k 24h vol) was created with postBitmap=18 and uses 65104.\n// PR #1236 fixed postBitmap for new slabs (→2) but broke recognition of these legacy 65104 slabs.\n// GH#1237: add both size variants so detectSlabLayout handles both old and new V1D on-chain data.\n// V2: ENGINE_OFF=600, BITMAP_OFF=432, ACCOUNT_SIZE=248, postBitmap=18\nconst V2_SIZES = new Map<number, number>();\n// V1M: mainnet-deployed V1 program (ENGINE_OFF=640, BITMAP_OFF=726, expanded RiskParams)\nconst V1M_SIZES = new Map<number, number>();\n// V_ADL: PERC-8270/8271 ADL-upgraded program (ENGINE_OFF=624, BITMAP_OFF=1006, ACCOUNT_SIZE=312)\nconst V_ADL_SIZES = new Map<number, number>();\nconst V1D_SIZES_LEGACY = new Map<number, number>();\nfor (const n of TIERS) {\n V0_SIZES.set(computeSlabSize(V0_ENGINE_OFF, V0_ENGINE_BITMAP_OFF, V0_ACCOUNT_SIZE, n), n);\n V1_SIZES.set(computeSlabSize(V1_ENGINE_OFF, V1_ENGINE_BITMAP_OFF, V1_ACCOUNT_SIZE, n), n);\n V1_SIZES_LEGACY.set(computeSlabSize(V1_ENGINE_OFF_LEGACY, V1_ENGINE_BITMAP_OFF, V1_ACCOUNT_SIZE, n), n);\n // GH#1234: V1D deployed program omits num_used/pad/next_account_id → postBitmap=2 (free_head only).\n // This yields 65088 (n=256) and 1025568 (n=4096) matching actual devnet account sizes.\n V1D_SIZES.set(computeSlabSize(V1D_ENGINE_OFF, V1D_ENGINE_BITMAP_OFF, V1D_ACCOUNT_SIZE, n, 2), n);\n // GH#1237: also register the legacy postBitmap=18 sizes for slabs created before GH#1234 fix.\n V1D_SIZES_LEGACY.set(computeSlabSize(V1D_ENGINE_OFF, V1D_ENGINE_BITMAP_OFF, V1D_ACCOUNT_SIZE, n, 18), n);\n // V2: postBitmap=18 — produces same sizes as V1D postBitmap=2 (e.g. 65088 for n=256).\n // Disambiguation requires peeking at the version field in the slab header.\n V2_SIZES.set(computeSlabSize(V2_ENGINE_OFF, V2_ENGINE_BITMAP_OFF, V2_ACCOUNT_SIZE, n, 18), n);\n // V1M: mainnet program with expanded RiskParams (336 bytes) and trade_twap fields.\n // e.g. n=1024 → 257512 bytes (confirmed on-chain for slab 8NY7rvQ).\n V1M_SIZES.set(computeSlabSize(V1M_ENGINE_OFF, V1M_ENGINE_BITMAP_OFF, V1M_ACCOUNT_SIZE, n, 18), n);\n // V_ADL: PERC-8270 ADL-upgraded program — new account size (312) and expanded engine layout.\n // e.g. n=4096 → 1288304 bytes (verified by cargo build-sbf in PERC-8271).\n V_ADL_SIZES.set(computeSlabSize(V_ADL_ENGINE_OFF, V_ADL_ENGINE_BITMAP_OFF, V_ADL_ACCOUNT_SIZE, n, 18), n);\n}\n\n/**\n * V2 slab tier sizes (small and large) for discovery.\n * V2 uses ENGINE_OFF=600, BITMAP_OFF=432, ACCOUNT_SIZE=248, postBitmap=18.\n * Sizes overlap with V1D (postBitmap=2) — disambiguation requires reading the version field.\n */\nexport const SLAB_TIERS_V2 = {\n small: { maxAccounts: 256, dataSize: 65_088, label: \"Small\", description: \"256 slots (V2 BPF intermediate)\" },\n large: { maxAccounts: 4096, dataSize: 1_025_568, label: \"Large\", description: \"4,096 slots (V2 BPF intermediate)\" },\n} as const;\n\n/**\n * V1M slab tier sizes — mainnet-deployed V1 program (ESa89R5).\n * ENGINE_OFF=640, BITMAP_OFF=726, ACCOUNT_SIZE=248, postBitmap=18.\n * Expanded RiskParams (336 bytes) and trade_twap runtime fields.\n * Confirmed by on-chain probing of slab 8NY7rvQ (SOL/USDC Perpetual, 257512 bytes).\n */\nexport const SLAB_TIERS_V1M: Record<string, { maxAccounts: number; dataSize: number; label: string; description: string }> = {};\nfor (const [label, n] of [[\"Micro\", 64], [\"Small\", 256], [\"Medium\", 1024], [\"Large\", 4096]] as const) {\n const size = computeSlabSize(V1M_ENGINE_OFF, V1M_ENGINE_BITMAP_OFF, V1M_ACCOUNT_SIZE, n, 18);\n SLAB_TIERS_V1M[label.toLowerCase()] = { maxAccounts: n, dataSize: size, label, description: `${n} slots (V1M mainnet)` };\n}\n\n/**\n * V1M2 slab tier sizes — mainnet program with 312-byte accounts.\n * Same engine layout as V1M but larger accounts. Sizes match V_ADL exactly.\n */\nexport const SLAB_TIERS_V1M2: Record<string, { maxAccounts: number; dataSize: number; label: string; description: string }> = {};\nfor (const [label, n] of [[\"Micro\", 64], [\"Small\", 256], [\"Medium\", 1024], [\"Large\", 4096]] as const) {\n const size = computeSlabSize(V1M2_ENGINE_OFF, V1M2_ENGINE_BITMAP_OFF, V1M2_ACCOUNT_SIZE, n, 18);\n SLAB_TIERS_V1M2[label.toLowerCase()] = { maxAccounts: n, dataSize: size, label, description: `${n} slots (V1M2 mainnet upgraded)` };\n}\n\n/**\n * V_ADL slab tier sizes — PERC-8270/8271 ADL-upgraded program.\n * ENGINE_OFF=624, BITMAP_OFF=1006, ACCOUNT_SIZE=312, postBitmap=18.\n * New account layout adds ADL tracking fields (+64 bytes/account including alignment padding).\n * BPF SLAB_LEN verified by cargo build-sbf in PERC-8271: large (4096) = 1288304 bytes.\n */\nexport const SLAB_TIERS_V_ADL: Record<string, { maxAccounts: number; dataSize: number; label: string; description: string }> = {};\nfor (const [label, n] of [[\"Micro\", 64], [\"Small\", 256], [\"Medium\", 1024], [\"Large\", 4096]] as const) {\n const size = computeSlabSize(V_ADL_ENGINE_OFF, V_ADL_ENGINE_BITMAP_OFF, V_ADL_ACCOUNT_SIZE, n, 18);\n SLAB_TIERS_V_ADL[label.toLowerCase()] = { maxAccounts: n, dataSize: size, label, description: `${n} slots (V_ADL PERC-8270)` };\n}\n\n/**\n * Build a complete SlabLayout descriptor for V0 or V1 (including V1-legacy) slabs.\n * Pass `engineOffOverride` to handle orphaned pre-PERC-1094 slabs that used ENGINE_OFF=640.\n */\nfunction buildLayout(version: 0 | 1, maxAccounts: number, engineOffOverride?: number): SlabLayout {\n const isV0 = version === 0;\n const engineOff = engineOffOverride ?? (isV0 ? V0_ENGINE_OFF : V1_ENGINE_OFF);\n const isV1Legacy = !isV0 && engineOffOverride === V1_ENGINE_OFF_LEGACY;\n // For accountsOff calculation, V1_LEGACY must use its actual bitmap offset (672, not 656).\n // Using the formula bitmapOff (656) produces accountsOff=1864, but accounts actually\n // start at 1880 — a 16-byte gap caused by the extra fields in the V1_LEGACY engine.\n // Non-V1_LEGACY slabs: actualBitmapOff === bitmapOff, so no change.\n const bitmapOff = isV0 ? V0_ENGINE_BITMAP_OFF : V1_ENGINE_BITMAP_OFF;\n const actualBitmapOff = isV1Legacy ? V1_LEGACY_ENGINE_BITMAP_OFF_ACTUAL\n : (isV0 ? V0_ENGINE_BITMAP_OFF : V1_ENGINE_BITMAP_OFF);\n const accountSize = isV0 ? V0_ACCOUNT_SIZE : V1_ACCOUNT_SIZE;\n const bitmapWords = Math.ceil(maxAccounts / 64);\n const bitmapBytes = bitmapWords * 8;\n const postBitmap = 18;\n const nextFreeBytes = maxAccounts * 2;\n // Use actualBitmapOff so V1_LEGACY gets accountsOff=1880 (not 1864).\n const preAccountsLen = actualBitmapOff + bitmapBytes + postBitmap + nextFreeBytes;\n const accountsOffRel = Math.ceil(preAccountsLen / 8) * 8;\n\n return {\n version,\n headerLen: isV0 ? V0_HEADER_LEN : V1_HEADER_LEN,\n configOffset: isV0 ? V0_HEADER_LEN : V1_HEADER_LEN,\n configLen: isV0 ? V0_CONFIG_LEN : V1_CONFIG_LEN,\n reservedOff: isV0 ? V0_RESERVED_OFF : V1_RESERVED_OFF,\n engineOff,\n accountSize,\n maxAccounts,\n bitmapWords,\n accountsOff: engineOff + accountsOffRel,\n\n engineInsuranceOff: 16,\n engineParamsOff: isV0 ? V0_ENGINE_PARAMS_OFF : V1_ENGINE_PARAMS_OFF,\n paramsSize: isV0 ? V0_PARAMS_SIZE : V1_PARAMS_SIZE,\n engineCurrentSlotOff: isV0 ? V0_ENGINE_CURRENT_SLOT_OFF : V1_ENGINE_CURRENT_SLOT_OFF,\n engineFundingIndexOff: isV0 ? V0_ENGINE_FUNDING_INDEX_OFF : V1_ENGINE_FUNDING_INDEX_OFF,\n engineLastFundingSlotOff: isV0 ? V0_ENGINE_LAST_FUNDING_SLOT_OFF : V1_ENGINE_LAST_FUNDING_SLOT_OFF,\n engineFundingRateBpsOff: isV0 ? V0_ENGINE_FUNDING_RATE_BPS_OFF : V1_ENGINE_FUNDING_RATE_BPS_OFF,\n engineMarkPriceOff: isV0 ? -1 : V1_ENGINE_MARK_PRICE_OFF,\n engineLastCrankSlotOff: isV0 ? V0_ENGINE_LAST_CRANK_SLOT_OFF : V1_ENGINE_LAST_CRANK_SLOT_OFF,\n engineMaxCrankStalenessOff: isV0 ? V0_ENGINE_MAX_CRANK_STALENESS_OFF : V1_ENGINE_MAX_CRANK_STALENESS_OFF,\n engineTotalOiOff: isV0 ? V0_ENGINE_TOTAL_OI_OFF : V1_ENGINE_TOTAL_OI_OFF,\n engineLongOiOff: isV0 ? -1 : V1_ENGINE_LONG_OI_OFF,\n engineShortOiOff: isV0 ? -1 : V1_ENGINE_SHORT_OI_OFF,\n engineCTotOff: isV0 ? V0_ENGINE_C_TOT_OFF : V1_ENGINE_C_TOT_OFF,\n enginePnlPosTotOff: isV0 ? V0_ENGINE_PNL_POS_TOT_OFF : V1_ENGINE_PNL_POS_TOT_OFF,\n engineLiqCursorOff: isV0 ? V0_ENGINE_LIQ_CURSOR_OFF : V1_ENGINE_LIQ_CURSOR_OFF,\n engineGcCursorOff: isV0 ? V0_ENGINE_GC_CURSOR_OFF : V1_ENGINE_GC_CURSOR_OFF,\n engineLastSweepStartOff: isV0 ? V0_ENGINE_LAST_SWEEP_START_OFF : V1_ENGINE_LAST_SWEEP_START_OFF,\n engineLastSweepCompleteOff: isV0 ? V0_ENGINE_LAST_SWEEP_COMPLETE_OFF : V1_ENGINE_LAST_SWEEP_COMPLETE_OFF,\n engineCrankCursorOff: isV0 ? V0_ENGINE_CRANK_CURSOR_OFF : V1_ENGINE_CRANK_CURSOR_OFF,\n engineSweepStartIdxOff: isV0 ? V0_ENGINE_SWEEP_START_IDX_OFF : V1_ENGINE_SWEEP_START_IDX_OFF,\n engineLifetimeLiquidationsOff: isV0 ? V0_ENGINE_LIFETIME_LIQUIDATIONS_OFF : V1_ENGINE_LIFETIME_LIQUIDATIONS_OFF,\n engineLifetimeForceClosesOff: isV0 ? V0_ENGINE_LIFETIME_FORCE_CLOSES_OFF : V1_ENGINE_LIFETIME_FORCE_CLOSES_OFF,\n engineNetLpPosOff: isV0 ? V0_ENGINE_NET_LP_POS_OFF : V1_ENGINE_NET_LP_POS_OFF,\n engineLpSumAbsOff: isV0 ? V0_ENGINE_LP_SUM_ABS_OFF : V1_ENGINE_LP_SUM_ABS_OFF,\n engineLpMaxAbsOff: isV0 ? V0_ENGINE_LP_MAX_ABS_OFF : V1_ENGINE_LP_MAX_ABS_OFF,\n engineLpMaxAbsSweepOff: isV0 ? V0_ENGINE_LP_MAX_ABS_SWEEP_OFF : V1_ENGINE_LP_MAX_ABS_SWEEP_OFF,\n engineEmergencyOiModeOff: isV0 ? -1 : V1_ENGINE_EMERGENCY_OI_MODE_OFF,\n engineEmergencyStartSlotOff: isV0 ? -1 : V1_ENGINE_EMERGENCY_START_SLOT_OFF,\n engineLastBreakerSlotOff: isV0 ? -1 : V1_ENGINE_LAST_BREAKER_SLOT_OFF,\n engineBitmapOff: actualBitmapOff,\n postBitmap: 18,\n acctOwnerOff: ACCT_OWNER_OFF,\n\n hasInsuranceIsolation: !isV0,\n engineInsuranceIsolatedOff: isV0 ? -1 : 48,\n engineInsuranceIsolationBpsOff: isV0 ? -1 : 64,\n };\n}\n\n/**\n * Build layout for V1D (actually deployed V1 program, rev ac18a0e).\n * Uses correct field offsets derived from on-chain probing.\n *\n * @param maxAccounts - Number of account slots in the slab\n * @param postBitmap - Bytes after the bitmap before next_free array.\n * 2 = free_head(u16) only — deployed program (GH#1234, default for new slabs)\n * 18 = num_used(u16)+pad(6)+next_account_id(u64)+free_head(u16) — legacy on-chain slabs (GH#1237)\n */\n/**\n * Build a SlabLayout for the actually-deployed V1D program (ENGINE_OFF=424).\n * `postBitmap` is 2 for new slabs (free_head only) and 18 for legacy on-chain slabs\n * created before the GH#1234 fix that removed num_used/pad/next_account_id.\n */\nfunction buildLayoutV1D(maxAccounts: number, postBitmap = 2): SlabLayout {\n const engineOff = V1D_ENGINE_OFF;\n const bitmapOff = V1D_ENGINE_BITMAP_OFF;\n const accountSize = V1D_ACCOUNT_SIZE;\n const bitmapWords = Math.ceil(maxAccounts / 64);\n const bitmapBytes = bitmapWords * 8;\n const nextFreeBytes = maxAccounts * 2;\n const preAccountsLen = bitmapOff + bitmapBytes + postBitmap + nextFreeBytes;\n const accountsOffRel = Math.ceil(preAccountsLen / 8) * 8;\n\n return {\n version: 1,\n headerLen: V1_HEADER_LEN,\n configOffset: V1_HEADER_LEN,\n configLen: V1D_CONFIG_LEN,\n reservedOff: V1_RESERVED_OFF,\n engineOff,\n accountSize,\n maxAccounts,\n bitmapWords,\n accountsOff: engineOff + accountsOffRel,\n\n engineInsuranceOff: V1D_ENGINE_INSURANCE_OFF,\n engineParamsOff: V1D_ENGINE_PARAMS_OFF,\n paramsSize: V1D_PARAMS_SIZE,\n engineCurrentSlotOff: V1D_ENGINE_CURRENT_SLOT_OFF,\n engineFundingIndexOff: V1D_ENGINE_FUNDING_INDEX_OFF,\n engineLastFundingSlotOff: V1D_ENGINE_LAST_FUNDING_SLOT_OFF,\n engineFundingRateBpsOff: V1D_ENGINE_FUNDING_RATE_BPS_OFF,\n engineMarkPriceOff: V1D_ENGINE_MARK_PRICE_OFF,\n engineLastCrankSlotOff: V1D_ENGINE_LAST_CRANK_SLOT_OFF,\n engineMaxCrankStalenessOff: V1D_ENGINE_MAX_CRANK_STALENESS_OFF,\n engineTotalOiOff: V1D_ENGINE_TOTAL_OI_OFF,\n engineLongOiOff: V1D_ENGINE_LONG_OI_OFF,\n engineShortOiOff: V1D_ENGINE_SHORT_OI_OFF,\n engineCTotOff: V1D_ENGINE_C_TOT_OFF,\n enginePnlPosTotOff: V1D_ENGINE_PNL_POS_TOT_OFF,\n engineLiqCursorOff: V1D_ENGINE_LIQ_CURSOR_OFF,\n engineGcCursorOff: V1D_ENGINE_GC_CURSOR_OFF,\n engineLastSweepStartOff: V1D_ENGINE_LAST_SWEEP_START_OFF,\n engineLastSweepCompleteOff: V1D_ENGINE_LAST_SWEEP_COMPLETE_OFF,\n engineCrankCursorOff: V1D_ENGINE_CRANK_CURSOR_OFF,\n engineSweepStartIdxOff: V1D_ENGINE_SWEEP_START_IDX_OFF,\n engineLifetimeLiquidationsOff: V1D_ENGINE_LIFETIME_LIQUIDATIONS_OFF,\n engineLifetimeForceClosesOff: V1D_ENGINE_LIFETIME_FORCE_CLOSES_OFF,\n engineNetLpPosOff: V1D_ENGINE_NET_LP_POS_OFF,\n engineLpSumAbsOff: V1D_ENGINE_LP_SUM_ABS_OFF,\n engineLpMaxAbsOff: -1, // not present in deployed V1\n engineLpMaxAbsSweepOff: -1, // not present in deployed V1\n engineEmergencyOiModeOff: -1, // not present in deployed V1\n engineEmergencyStartSlotOff: -1, // not present in deployed V1\n engineLastBreakerSlotOff: -1, // not present in deployed V1\n engineBitmapOff: V1D_ENGINE_BITMAP_OFF,\n postBitmap,\n acctOwnerOff: ACCT_OWNER_OFF,\n\n hasInsuranceIsolation: true,\n engineInsuranceIsolatedOff: 48, // same within InsuranceFund\n engineInsuranceIsolationBpsOff: 64, // same within InsuranceFund\n };\n}\n\n/**\n * Build a SlabLayout for V2 (BPF intermediate layout).\n * ENGINE_OFF=600, BITMAP_OFF=432, ACCOUNT_SIZE=248, postBitmap=18.\n * V2 lacks mark_price, long_oi, short_oi, emergency OI fields.\n */\nfunction buildLayoutV2(maxAccounts: number): SlabLayout {\n const engineOff = V2_ENGINE_OFF;\n const bitmapOff = V2_ENGINE_BITMAP_OFF;\n const accountSize = V2_ACCOUNT_SIZE;\n const bitmapWords = Math.ceil(maxAccounts / 64);\n const bitmapBytes = bitmapWords * 8;\n const postBitmap = 18;\n const nextFreeBytes = maxAccounts * 2;\n const preAccountsLen = bitmapOff + bitmapBytes + postBitmap + nextFreeBytes;\n const accountsOffRel = Math.ceil(preAccountsLen / 8) * 8;\n\n return {\n version: 2,\n headerLen: V2_HEADER_LEN,\n configOffset: V2_HEADER_LEN,\n configLen: V2_CONFIG_LEN,\n reservedOff: V1_RESERVED_OFF, // V2 shares V1's header layout (reserved at 80)\n engineOff,\n accountSize,\n maxAccounts,\n bitmapWords,\n accountsOff: engineOff + accountsOffRel,\n\n engineInsuranceOff: 16,\n engineParamsOff: V1_ENGINE_PARAMS_OFF, // same as V1: 72\n paramsSize: V1_PARAMS_SIZE, // same as V1: 288\n engineCurrentSlotOff: V2_ENGINE_CURRENT_SLOT_OFF,\n engineFundingIndexOff: V2_ENGINE_FUNDING_INDEX_OFF,\n engineLastFundingSlotOff: V2_ENGINE_LAST_FUNDING_SLOT_OFF,\n engineFundingRateBpsOff: V2_ENGINE_FUNDING_RATE_BPS_OFF,\n engineMarkPriceOff: -1, // V2 has no mark_price\n engineLastCrankSlotOff: V2_ENGINE_LAST_CRANK_SLOT_OFF,\n engineMaxCrankStalenessOff: V2_ENGINE_MAX_CRANK_STALENESS_OFF,\n engineTotalOiOff: V2_ENGINE_TOTAL_OI_OFF,\n engineLongOiOff: -1, // V2 has no long_oi\n engineShortOiOff: -1, // V2 has no short_oi\n engineCTotOff: V2_ENGINE_C_TOT_OFF,\n enginePnlPosTotOff: V2_ENGINE_PNL_POS_TOT_OFF,\n engineLiqCursorOff: V2_ENGINE_LIQ_CURSOR_OFF,\n engineGcCursorOff: V2_ENGINE_GC_CURSOR_OFF,\n engineLastSweepStartOff: V2_ENGINE_LAST_SWEEP_START_OFF,\n engineLastSweepCompleteOff: V2_ENGINE_LAST_SWEEP_COMPLETE_OFF,\n engineCrankCursorOff: V2_ENGINE_CRANK_CURSOR_OFF,\n engineSweepStartIdxOff: V2_ENGINE_SWEEP_START_IDX_OFF,\n engineLifetimeLiquidationsOff: V2_ENGINE_LIFETIME_LIQUIDATIONS_OFF,\n engineLifetimeForceClosesOff: V2_ENGINE_LIFETIME_FORCE_CLOSES_OFF,\n engineNetLpPosOff: V2_ENGINE_NET_LP_POS_OFF,\n engineLpSumAbsOff: V2_ENGINE_LP_SUM_ABS_OFF,\n engineLpMaxAbsOff: V2_ENGINE_LP_MAX_ABS_OFF,\n engineLpMaxAbsSweepOff: V2_ENGINE_LP_MAX_ABS_SWEEP_OFF,\n engineEmergencyOiModeOff: -1, // V2 has no emergency OI fields\n engineEmergencyStartSlotOff: -1,\n engineLastBreakerSlotOff: -1,\n engineBitmapOff: V2_ENGINE_BITMAP_OFF,\n postBitmap: 18,\n acctOwnerOff: ACCT_OWNER_OFF,\n\n hasInsuranceIsolation: true,\n engineInsuranceIsolatedOff: 48,\n engineInsuranceIsolationBpsOff: 64,\n };\n}\n\n/**\n * Build a SlabLayout for the V1M mainnet program (ESa89R5).\n * ENGINE_OFF=640 (same as V1_LEGACY), but expanded RiskParams (336 bytes)\n * and trade_twap runtime fields push the bitmap to offset 726.\n * Confirmed by on-chain probing of slab 8NY7rvQ (257512 bytes, medium tier).\n */\nfunction buildLayoutV1M(maxAccounts: number): SlabLayout {\n const engineOff = V1M_ENGINE_OFF;\n const bitmapOff = V1M_ENGINE_BITMAP_OFF;\n const accountSize = V1M_ACCOUNT_SIZE;\n const bitmapWords = Math.ceil(maxAccounts / 64);\n const bitmapBytes = bitmapWords * 8;\n const postBitmap = 18;\n const nextFreeBytes = maxAccounts * 2;\n const preAccountsLen = bitmapOff + bitmapBytes + postBitmap + nextFreeBytes;\n const accountsOffRel = Math.ceil(preAccountsLen / 8) * 8;\n\n return {\n version: 1,\n headerLen: V1_HEADER_LEN,\n configOffset: V1_HEADER_LEN,\n configLen: V1M_CONFIG_LEN,\n reservedOff: V1_RESERVED_OFF,\n engineOff,\n accountSize,\n maxAccounts,\n bitmapWords,\n accountsOff: engineOff + accountsOffRel,\n\n engineInsuranceOff: 16,\n engineParamsOff: V1M_ENGINE_PARAMS_OFF,\n paramsSize: V1M_PARAMS_SIZE,\n engineCurrentSlotOff: V1M_ENGINE_CURRENT_SLOT_OFF,\n engineFundingIndexOff: V1M_ENGINE_FUNDING_INDEX_OFF,\n engineLastFundingSlotOff: V1M_ENGINE_LAST_FUNDING_SLOT_OFF,\n engineFundingRateBpsOff: V1M_ENGINE_FUNDING_RATE_BPS_OFF,\n engineMarkPriceOff: V1M_ENGINE_MARK_PRICE_OFF,\n engineLastCrankSlotOff: V1M_ENGINE_LAST_CRANK_SLOT_OFF,\n engineMaxCrankStalenessOff: V1M_ENGINE_MAX_CRANK_STALENESS_OFF,\n engineTotalOiOff: V1M_ENGINE_TOTAL_OI_OFF,\n engineLongOiOff: V1M_ENGINE_LONG_OI_OFF,\n engineShortOiOff: V1M_ENGINE_SHORT_OI_OFF,\n engineCTotOff: V1M_ENGINE_C_TOT_OFF,\n enginePnlPosTotOff: V1M_ENGINE_PNL_POS_TOT_OFF,\n engineLiqCursorOff: V1M_ENGINE_LIQ_CURSOR_OFF,\n engineGcCursorOff: V1M_ENGINE_GC_CURSOR_OFF,\n engineLastSweepStartOff: V1M_ENGINE_LAST_SWEEP_START_OFF,\n engineLastSweepCompleteOff: V1M_ENGINE_LAST_SWEEP_COMPLETE_OFF,\n engineCrankCursorOff: V1M_ENGINE_CRANK_CURSOR_OFF,\n engineSweepStartIdxOff: V1M_ENGINE_SWEEP_START_IDX_OFF,\n engineLifetimeLiquidationsOff: V1M_ENGINE_LIFETIME_LIQUIDATIONS_OFF,\n engineLifetimeForceClosesOff: V1M_ENGINE_LIFETIME_FORCE_CLOSES_OFF,\n engineNetLpPosOff: V1M_ENGINE_NET_LP_POS_OFF,\n engineLpSumAbsOff: V1M_ENGINE_LP_SUM_ABS_OFF,\n engineLpMaxAbsOff: V1M_ENGINE_LP_MAX_ABS_OFF,\n engineLpMaxAbsSweepOff: V1M_ENGINE_LP_MAX_ABS_SWEEP_OFF,\n engineEmergencyOiModeOff: V1M_ENGINE_EMERGENCY_OI_MODE_OFF,\n engineEmergencyStartSlotOff: V1M_ENGINE_EMERGENCY_START_SLOT_OFF,\n engineLastBreakerSlotOff: V1M_ENGINE_LAST_BREAKER_SLOT_OFF,\n engineBitmapOff: V1M_ENGINE_BITMAP_OFF,\n postBitmap: 18,\n acctOwnerOff: ACCT_OWNER_OFF,\n\n hasInsuranceIsolation: true,\n engineInsuranceIsolatedOff: 48,\n engineInsuranceIsolationBpsOff: 64,\n };\n}\n\n/**\n * Build a SlabLayout for V1M2 — mainnet program with 312-byte accounts.\n * Same engine layout as V1M (ENGINE_OFF=640, same field offsets) but larger\n * accounts (312 bytes) and shifted bitmap (990).\n * Confirmed by on-chain probing of slab 7T1Efij9 (SOL-PERP, 323312 bytes).\n */\nfunction buildLayoutV1M2(maxAccounts: number): SlabLayout {\n const engineOff = V1M2_ENGINE_OFF;\n const bitmapOff = V1M2_ENGINE_BITMAP_OFF;\n const accountSize = V1M2_ACCOUNT_SIZE;\n const bitmapWords = Math.ceil(maxAccounts / 64);\n const bitmapBytes = bitmapWords * 8;\n const postBitmap = 18;\n const nextFreeBytes = maxAccounts * 2;\n const preAccountsLen = bitmapOff + bitmapBytes + postBitmap + nextFreeBytes;\n const accountsOffRel = Math.ceil(preAccountsLen / 8) * 8;\n\n return {\n version: 1,\n headerLen: V1_HEADER_LEN,\n configOffset: V1_HEADER_LEN,\n configLen: V1M2_CONFIG_LEN,\n reservedOff: V1_RESERVED_OFF,\n engineOff,\n accountSize,\n maxAccounts,\n bitmapWords,\n accountsOff: engineOff + accountsOffRel,\n\n engineInsuranceOff: 16,\n engineParamsOff: V1M2_ENGINE_PARAMS_OFF, // 96 — expanded InsuranceFund\n paramsSize: V1M_PARAMS_SIZE, // 336 — same as V1M\n // Runtime fields: same as V1M up to fundingRateBps, then +32 shift\n engineCurrentSlotOff: V1M2_ENGINE_CURRENT_SLOT_OFF,\n engineFundingIndexOff: V1M2_ENGINE_FUNDING_INDEX_OFF,\n engineLastFundingSlotOff: V1M2_ENGINE_LAST_FUNDING_SLOT_OFF,\n engineFundingRateBpsOff: V1M2_ENGINE_FUNDING_RATE_BPS_OFF,\n engineMarkPriceOff: V1M2_ENGINE_MARK_PRICE_OFF,\n engineLastCrankSlotOff: V1M2_ENGINE_LAST_CRANK_SLOT_OFF,\n engineMaxCrankStalenessOff: V1M2_ENGINE_MAX_CRANK_STALENESS_OFF,\n // Fields after maxCrankStaleness: apply same +32 shift from V1M\n engineTotalOiOff: V1M_ENGINE_TOTAL_OI_OFF + V1M2_RUNTIME_SHIFT,\n engineLongOiOff: V1M_ENGINE_LONG_OI_OFF + V1M2_RUNTIME_SHIFT,\n engineShortOiOff: V1M_ENGINE_SHORT_OI_OFF + V1M2_RUNTIME_SHIFT,\n engineCTotOff: V1M_ENGINE_C_TOT_OFF + V1M2_RUNTIME_SHIFT,\n enginePnlPosTotOff: V1M_ENGINE_PNL_POS_TOT_OFF + V1M2_RUNTIME_SHIFT,\n engineLiqCursorOff: V1M_ENGINE_LIQ_CURSOR_OFF + V1M2_RUNTIME_SHIFT,\n engineGcCursorOff: V1M_ENGINE_GC_CURSOR_OFF + V1M2_RUNTIME_SHIFT,\n engineLastSweepStartOff: V1M_ENGINE_LAST_SWEEP_START_OFF + V1M2_RUNTIME_SHIFT,\n engineLastSweepCompleteOff: V1M_ENGINE_LAST_SWEEP_COMPLETE_OFF + V1M2_RUNTIME_SHIFT,\n engineCrankCursorOff: V1M_ENGINE_CRANK_CURSOR_OFF + V1M2_RUNTIME_SHIFT,\n engineSweepStartIdxOff: V1M_ENGINE_SWEEP_START_IDX_OFF + V1M2_RUNTIME_SHIFT,\n engineLifetimeLiquidationsOff: V1M_ENGINE_LIFETIME_LIQUIDATIONS_OFF + V1M2_RUNTIME_SHIFT,\n engineLifetimeForceClosesOff: V1M_ENGINE_LIFETIME_FORCE_CLOSES_OFF + V1M2_RUNTIME_SHIFT,\n engineNetLpPosOff: V1M_ENGINE_NET_LP_POS_OFF + V1M2_RUNTIME_SHIFT,\n engineLpSumAbsOff: V1M_ENGINE_LP_SUM_ABS_OFF + V1M2_RUNTIME_SHIFT,\n engineLpMaxAbsOff: V1M_ENGINE_LP_MAX_ABS_OFF + V1M2_RUNTIME_SHIFT,\n engineLpMaxAbsSweepOff: V1M_ENGINE_LP_MAX_ABS_SWEEP_OFF + V1M2_RUNTIME_SHIFT,\n engineEmergencyOiModeOff: V1M_ENGINE_EMERGENCY_OI_MODE_OFF + V1M2_RUNTIME_SHIFT,\n engineEmergencyStartSlotOff: V1M_ENGINE_EMERGENCY_START_SLOT_OFF + V1M2_RUNTIME_SHIFT,\n engineLastBreakerSlotOff: V1M_ENGINE_LAST_BREAKER_SLOT_OFF + V1M2_RUNTIME_SHIFT,\n engineBitmapOff: V1M2_ENGINE_BITMAP_OFF,\n postBitmap: 18,\n acctOwnerOff: ACCT_OWNER_OFF,\n\n hasInsuranceIsolation: true,\n engineInsuranceIsolatedOff: 48,\n engineInsuranceIsolationBpsOff: 64,\n };\n}\n\n/**\n * Build a SlabLayout for the ADL-upgraded program (PERC-8270/8271).\n * ENGINE_OFF=624, BITMAP_OFF=1006, ACCOUNT_SIZE=312.\n *\n * Verified slab sizes (BPF, cargo build-sbf):\n * large (4096 accounts): 1288304 bytes ← PERC-8271 confirmed\n * medium (1024 accounts): 323312 bytes\n * small (256 accounts): 82064 bytes\n */\nfunction buildLayoutVADL(maxAccounts: number): SlabLayout {\n const engineOff = V_ADL_ENGINE_OFF;\n const bitmapOff = V_ADL_ENGINE_BITMAP_OFF;\n const accountSize = V_ADL_ACCOUNT_SIZE;\n const bitmapWords = Math.ceil(maxAccounts / 64);\n const bitmapBytes = bitmapWords * 8;\n const postBitmap = 18;\n const nextFreeBytes = maxAccounts * 2;\n const preAccountsLen = bitmapOff + bitmapBytes + postBitmap + nextFreeBytes;\n const accountsOffRel = Math.ceil(preAccountsLen / 8) * 8;\n\n return {\n version: 1,\n headerLen: V1_HEADER_LEN, // 104 (unchanged)\n configOffset: V1_HEADER_LEN,\n configLen: V_ADL_CONFIG_LEN, // 520\n reservedOff: V1_RESERVED_OFF, // 80\n engineOff,\n accountSize,\n maxAccounts,\n bitmapWords,\n accountsOff: engineOff + accountsOffRel,\n\n engineInsuranceOff: 16,\n engineParamsOff: V_ADL_ENGINE_PARAMS_OFF, // 96 (vault=16 + InsuranceFund=80)\n paramsSize: V_ADL_PARAMS_SIZE, // 336\n engineCurrentSlotOff: V_ADL_ENGINE_CURRENT_SLOT_OFF, // 432\n engineFundingIndexOff: V_ADL_ENGINE_FUNDING_INDEX_OFF, // 440\n engineLastFundingSlotOff: V_ADL_ENGINE_LAST_FUNDING_SLOT_OFF, // 456\n engineFundingRateBpsOff: V_ADL_ENGINE_FUNDING_RATE_BPS_OFF, // 464\n engineMarkPriceOff: V_ADL_ENGINE_MARK_PRICE_OFF, // 504\n engineLastCrankSlotOff: V_ADL_ENGINE_LAST_CRANK_SLOT_OFF, // 528\n engineMaxCrankStalenessOff: V_ADL_ENGINE_MAX_CRANK_STALENESS_OFF, // 536\n engineTotalOiOff: V_ADL_ENGINE_TOTAL_OI_OFF, // 544\n engineLongOiOff: V_ADL_ENGINE_LONG_OI_OFF, // 560\n engineShortOiOff: V_ADL_ENGINE_SHORT_OI_OFF, // 576\n engineCTotOff: V_ADL_ENGINE_C_TOT_OFF, // 592\n enginePnlPosTotOff: V_ADL_ENGINE_PNL_POS_TOT_OFF, // 608\n engineLiqCursorOff: V_ADL_ENGINE_LIQ_CURSOR_OFF, // 640\n engineGcCursorOff: V_ADL_ENGINE_GC_CURSOR_OFF, // 642\n engineLastSweepStartOff: V_ADL_ENGINE_LAST_SWEEP_START_OFF, // 648\n engineLastSweepCompleteOff: V_ADL_ENGINE_LAST_SWEEP_COMPLETE_OFF, // 656\n engineCrankCursorOff: V_ADL_ENGINE_CRANK_CURSOR_OFF, // 664\n engineSweepStartIdxOff: V_ADL_ENGINE_SWEEP_START_IDX_OFF, // 666\n engineLifetimeLiquidationsOff: V_ADL_ENGINE_LIFETIME_LIQUIDATIONS_OFF, // 672\n engineLifetimeForceClosesOff: V_ADL_ENGINE_LIFETIME_FORCE_CLOSES_OFF, // 680\n engineNetLpPosOff: V_ADL_ENGINE_NET_LP_POS_OFF, // 904\n engineLpSumAbsOff: V_ADL_ENGINE_LP_SUM_ABS_OFF, // 920\n engineLpMaxAbsOff: V_ADL_ENGINE_LP_MAX_ABS_OFF, // 936\n engineLpMaxAbsSweepOff: V_ADL_ENGINE_LP_MAX_ABS_SWEEP_OFF, // 952\n engineEmergencyOiModeOff: V_ADL_ENGINE_EMERGENCY_OI_MODE_OFF, // 968\n engineEmergencyStartSlotOff: V_ADL_ENGINE_EMERGENCY_START_SLOT_OFF, // 976\n engineLastBreakerSlotOff: V_ADL_ENGINE_LAST_BREAKER_SLOT_OFF, // 984\n engineBitmapOff: V_ADL_ENGINE_BITMAP_OFF, // 1006\n postBitmap: 18,\n acctOwnerOff: V_ADL_ACCT_OWNER_OFF, // 192\n\n hasInsuranceIsolation: true,\n engineInsuranceIsolatedOff: 48,\n engineInsuranceIsolationBpsOff: 64,\n };\n}\n\n/**\n * Detect the slab layout version from the raw account data length.\n * Returns the full SlabLayout descriptor, or null if the size is unrecognised.\n * Checks V_ADL, V1M, V0, V1D, V1D-legacy, V1, and V1-legacy sizes in priority order.\n *\n * When `data` is provided and the size matches V1D, the version field at offset 8 is read\n * to disambiguate V2 slabs (which produce identical sizes to V1D with postBitmap=2).\n * V2 slabs have version===2 at offset 8 (u32 LE).\n *\n * @param dataLen - The slab account data length in bytes\n * @param data - Optional raw slab data for version-field disambiguation\n */\nexport function detectSlabLayout(dataLen: number, data?: Uint8Array): SlabLayout | null {\n // Check V_ADL / V1M2 sizes — these two layouts produce IDENTICAL slab sizes because\n // V_ADL (ENGINE_OFF=624, BITMAP_OFF=1006, ACCOUNT_SIZE=312) and V1M2 (ENGINE_OFF=640,\n // BITMAP_OFF=990, ACCOUNT_SIZE=312) compute to the same totals for all tiers.\n // Disambiguate by reading max_accounts at each layout's params offset:\n // V1M2: engine(640) + params(72) + max_accounts_field(32) = offset 744\n // V_ADL: engine(624) + params(96) + max_accounts_field(32) = offset 752\n const vadln = V_ADL_SIZES.get(dataLen);\n if (vadln !== undefined) {\n if (data && data.length >= 752) {\n const maxAcctsV1M2 = readU64LE(data, V1M2_ENGINE_OFF + V1M2_ENGINE_PARAMS_OFF + 32);\n if (maxAcctsV1M2 === BigInt(vadln)) {\n // V1M engine layout with 312-byte accounts (mainnet program upgrade)\n return buildLayoutV1M2(vadln);\n }\n }\n return buildLayoutVADL(vadln);\n }\n\n // Check V1M sizes (mainnet-deployed V1 program, ESa89R5).\n // Must be checked before V1_LEGACY because V1M sizes are unique and don't overlap.\n const v1mn = V1M_SIZES.get(dataLen);\n if (v1mn !== undefined) return buildLayoutV1M(v1mn);\n\n // Check V0 sizes (deployed devnet V0 program)\n const v0n = V0_SIZES.get(dataLen);\n if (v0n !== undefined) return buildLayout(0, v0n);\n\n // Check V1D sizes (actually deployed V1 program — ENGINE_OFF=424, correct struct layout).\n // V2 slabs produce identical sizes (postBitmap=18 for V2 == postBitmap=2 for V1D).\n // When data is available, peek at the version field to disambiguate.\n const v1dn = V1D_SIZES.get(dataLen);\n if (v1dn !== undefined) {\n if (data && data.length >= 12) {\n const version = readU32LE(data, 8);\n if (version === 2) return buildLayoutV2(v1dn);\n }\n return buildLayoutV1D(v1dn, 2);\n }\n\n // Check V1D legacy sizes (postBitmap=18 on-chain slabs created before GH#1234 fix).\n // e.g. slab 6ZytbpV4 (TEST/USD, top active market) = 65104 bytes, uses postBitmap=18.\n // PR #1236 broke these by only registering the postBitmap=2 size; GH#1237 restores support.\n const v1dln = V1D_SIZES_LEGACY.get(dataLen);\n if (v1dln !== undefined) return buildLayoutV1D(v1dln, 18);\n\n // Check V1 sizes (future V1 program — ENGINE_OFF=600, PERC-1094 corrected)\n const v1n = V1_SIZES.get(dataLen);\n if (v1n !== undefined) return buildLayout(1, v1n);\n\n // Check legacy V1 sizes (pre-PERC-1094 SDK used ENGINE_OFF=640; orphaned on devnet)\n const v1ln = V1_SIZES_LEGACY.get(dataLen);\n // PERC-1095 follow-up: must pass V1_ENGINE_OFF_LEGACY (640) so the returned SlabLayout\n // has .engineOff=640 — without the override buildLayout would use V1_ENGINE_OFF=600,\n // causing all engine reads on legacy slabs to land at the wrong byte offset.\n if (v1ln !== undefined) return buildLayout(1, v1ln, V1_ENGINE_OFF_LEGACY);\n\n return null;\n}\n\n/**\n * Legacy detectLayout for backward compat.\n * Returns { bitmapWords, accountsOff, maxAccounts } or null.\n *\n * GH#1238: previously recomputed accountsOff with hardcoded postBitmap=18, which gave a value\n * 16 bytes too large for V1D slabs (which use postBitmap=2). Now delegates directly to the\n * SlabLayout descriptor so each variant uses its own correct accountsOff.\n */\nexport function detectLayout(dataLen: number) {\n const layout = detectSlabLayout(dataLen);\n if (!layout) return null;\n return { bitmapWords: layout.bitmapWords, accountsOff: layout.accountsOff, maxAccounts: layout.maxAccounts };\n}\n\n// =============================================================================\n// RiskParams Layout (field offsets within params, same for V0 and V1 basic fields)\n// =============================================================================\nconst PARAMS_WARMUP_PERIOD_OFF = 0;\nconst PARAMS_MAINTENANCE_MARGIN_OFF = 8;\nconst PARAMS_INITIAL_MARGIN_OFF = 16;\nconst PARAMS_TRADING_FEE_OFF = 24;\nconst PARAMS_MAX_ACCOUNTS_OFF = 32;\nconst PARAMS_NEW_ACCOUNT_FEE_OFF = 40;\n// V1-only extended params (offset 56+)\nconst PARAMS_RISK_THRESHOLD_OFF = 56;\nconst PARAMS_MAINTENANCE_FEE_OFF = 72;\nconst PARAMS_MAX_CRANK_STALENESS_OFF = 88;\nconst PARAMS_LIQUIDATION_FEE_BPS_OFF = 96;\nconst PARAMS_LIQUIDATION_FEE_CAP_OFF = 104;\nconst PARAMS_LIQUIDATION_BUFFER_OFF = 120;\nconst PARAMS_MIN_LIQUIDATION_OFF = 128;\n\n// =============================================================================\n// Account Layout (240/248 bytes)\n// The first 240 bytes are identical in V0 and V1.\n// V1 adds last_partial_liquidation_slot (u64, 8 bytes) at offset 240.\n// =============================================================================\nconst ACCT_ACCOUNT_ID_OFF = 0;\nconst ACCT_CAPITAL_OFF = 8;\nconst ACCT_KIND_OFF = 24;\nconst ACCT_PNL_OFF = 32;\nconst ACCT_RESERVED_PNL_OFF = 48;\nconst ACCT_WARMUP_STARTED_OFF = 56;\nconst ACCT_WARMUP_SLOPE_OFF = 64;\nconst ACCT_POSITION_SIZE_OFF = 80;\nconst ACCT_ENTRY_PRICE_OFF = 96;\nconst ACCT_FUNDING_INDEX_OFF = 104;\nconst ACCT_MATCHER_PROGRAM_OFF = 120;\nconst ACCT_MATCHER_CONTEXT_OFF = 152;\nconst ACCT_OWNER_OFF = 184;\nconst ACCT_FEE_CREDITS_OFF = 216;\nconst ACCT_LAST_FEE_SLOT_OFF = 232;\n\n// =============================================================================\n// Interfaces\n// =============================================================================\n\nexport interface SlabHeader {\n magic: bigint;\n version: number;\n bump: number;\n flags: number;\n resolved: boolean;\n paused: boolean;\n admin: PublicKey;\n nonce: bigint;\n lastThrUpdateSlot: bigint;\n}\n\nexport interface MarketConfig {\n collateralMint: PublicKey;\n vaultPubkey: PublicKey;\n indexFeedId: PublicKey;\n maxStalenessSlots: bigint;\n confFilterBps: number;\n vaultAuthorityBump: number;\n invert: number;\n unitScale: number;\n fundingHorizonSlots: bigint;\n fundingKBps: bigint;\n fundingInvScaleNotionalE6: bigint;\n fundingMaxPremiumBps: bigint;\n fundingMaxBpsPerSlot: bigint;\n fundingPremiumWeightBps: bigint;\n fundingSettlementIntervalSlots: bigint;\n fundingPremiumDampeningE6: bigint;\n fundingPremiumMaxBpsPerSlot: bigint;\n threshFloor: bigint;\n threshRiskBps: bigint;\n threshUpdateIntervalSlots: bigint;\n threshStepBps: bigint;\n threshAlphaBps: bigint;\n threshMin: bigint;\n threshMax: bigint;\n threshMinStep: bigint;\n oracleAuthority: PublicKey;\n authorityPriceE6: bigint;\n authorityTimestamp: bigint;\n oraclePriceCapE2bps: bigint;\n lastEffectivePriceE6: bigint;\n oiCapMultiplierBps: bigint;\n maxPnlCap: bigint;\n adaptiveFundingEnabled: boolean;\n adaptiveScaleBps: number;\n adaptiveMaxFundingBps: bigint;\n marketCreatedSlot: bigint;\n oiRampSlots: bigint;\n resolvedSlot: bigint;\n insuranceIsolationBps: number;\n /** PERC-622: Oracle phase (0=Nascent, 1=Growing, 2=Mature) */\n oraclePhase: number;\n /** PERC-622: Cumulative trade volume in e6 format */\n cumulativeVolumeE6: bigint;\n /** PERC-622: Slots elapsed from market creation to Phase 2 entry (u24) */\n phase2DeltaSlots: number;\n}\n\nexport interface InsuranceFund {\n balance: bigint;\n feeRevenue: bigint;\n isolatedBalance: bigint;\n isolationBps: number;\n}\n\nexport interface RiskParams {\n warmupPeriodSlots: bigint;\n maintenanceMarginBps: bigint;\n initialMarginBps: bigint;\n tradingFeeBps: bigint;\n maxAccounts: bigint;\n newAccountFee: bigint;\n riskReductionThreshold: bigint;\n maintenanceFeePerSlot: bigint;\n maxCrankStalenessSlots: bigint;\n liquidationFeeBps: bigint;\n liquidationFeeCap: bigint;\n liquidationBufferBps: bigint;\n minLiquidationAbs: bigint;\n}\n\nexport interface EngineState {\n vault: bigint;\n insuranceFund: InsuranceFund;\n currentSlot: bigint;\n fundingIndexQpbE6: bigint;\n lastFundingSlot: bigint;\n fundingRateBpsPerSlotLast: bigint;\n lastCrankSlot: bigint;\n maxCrankStalenessSlots: bigint;\n totalOpenInterest: bigint;\n longOi: bigint;\n shortOi: bigint;\n cTot: bigint;\n pnlPosTot: bigint;\n liqCursor: number;\n gcCursor: number;\n lastSweepStartSlot: bigint;\n lastSweepCompleteSlot: bigint;\n crankCursor: number;\n sweepStartIdx: number;\n lifetimeLiquidations: bigint;\n lifetimeForceCloses: bigint;\n netLpPos: bigint;\n lpSumAbs: bigint;\n lpMaxAbs: bigint;\n lpMaxAbsSweep: bigint;\n emergencyOiMode: boolean;\n emergencyStartSlot: bigint;\n lastBreakerSlot: bigint;\n numUsedAccounts: number;\n nextAccountId: bigint;\n markPriceE6: bigint;\n}\n\nexport enum AccountKind {\n User = 0,\n LP = 1,\n}\n\nexport interface Account {\n kind: AccountKind;\n accountId: bigint;\n capital: bigint;\n pnl: bigint;\n reservedPnl: bigint;\n warmupStartedAtSlot: bigint;\n warmupSlopePerStep: bigint;\n positionSize: bigint;\n entryPrice: bigint;\n fundingIndex: bigint;\n matcherProgram: PublicKey;\n matcherContext: PublicKey;\n owner: PublicKey;\n feeCredits: bigint;\n lastFeeSlot: bigint;\n}\n\n// =============================================================================\n// Fetch\n// =============================================================================\n\nexport async function fetchSlab(\n connection: Connection,\n slabPubkey: PublicKey\n): Promise<Uint8Array> {\n const info = await connection.getAccountInfo(slabPubkey);\n if (!info) {\n throw new Error(`Slab account not found: ${slabPubkey.toBase58()}`);\n }\n return new Uint8Array(info.data);\n}\n\n// =============================================================================\n// PERC-302: Market Maturity OI Ramp\n// =============================================================================\n\nexport const RAMP_START_BPS = 1000n;\nexport const DEFAULT_OI_RAMP_SLOTS = 432_000n;\n\nexport function computeEffectiveOiCapBps(config: MarketConfig, currentSlot: bigint): bigint {\n const target = config.oiCapMultiplierBps;\n if (target === 0n) return 0n;\n if (config.oiRampSlots === 0n) return target;\n if (target <= RAMP_START_BPS) return target;\n const elapsed = currentSlot > config.marketCreatedSlot\n ? currentSlot - config.marketCreatedSlot\n : 0n;\n if (elapsed >= config.oiRampSlots) return target;\n const range = target - RAMP_START_BPS;\n const rampAdd = (range * elapsed) / config.oiRampSlots;\n const result = RAMP_START_BPS + rampAdd;\n return result < target ? result : target;\n}\n\n// =============================================================================\n// Header helpers\n// =============================================================================\n\nexport function readNonce(data: Uint8Array): bigint {\n const layout = detectSlabLayout(data.length, data);\n if (!layout) {\n throw new Error(`readNonce: unrecognized slab data length ${data.length}`);\n }\n const roff = layout.reservedOff;\n if (data.length < roff + 8) throw new Error(\"Slab data too short for nonce\");\n return readU64LE(data, roff);\n}\n\nexport function readLastThrUpdateSlot(data: Uint8Array): bigint {\n const layout = detectSlabLayout(data.length, data);\n if (!layout) {\n throw new Error(`readLastThrUpdateSlot: unrecognized slab data length ${data.length}`);\n }\n const roff = layout.reservedOff;\n if (data.length < roff + 16) throw new Error(\"Slab data too short for lastThrUpdateSlot\");\n return readU64LE(data, roff + 8);\n}\n\n// =============================================================================\n// Parsing Functions\n// =============================================================================\n\n/**\n * Parse slab header (first 72 bytes — layout-independent).\n */\nexport function parseHeader(data: Uint8Array): SlabHeader {\n if (data.length < V0_HEADER_LEN) {\n throw new Error(`Slab data too short for header: ${data.length} < ${V0_HEADER_LEN}`);\n }\n\n const magic = readU64LE(data, 0);\n if (magic !== MAGIC) {\n throw new Error(`Invalid slab magic: expected ${MAGIC.toString(16)}, got ${magic.toString(16)}`);\n }\n\n const version = readU32LE(data, 8);\n const bump = readU8(data, 12);\n const flags = readU8(data, 13);\n const admin = new PublicKey(data.subarray(16, 48));\n\n // Reserved field location depends on layout\n const layout = detectSlabLayout(data.length, data);\n const roff = layout ? layout.reservedOff : V0_RESERVED_OFF;\n const nonce = readU64LE(data, roff);\n const lastThrUpdateSlot = readU64LE(data, roff + 8);\n\n return {\n magic,\n version,\n bump,\n flags,\n resolved: (flags & FLAG_RESOLVED) !== 0,\n paused: (flags & 0x02) !== 0,\n admin,\n nonce,\n lastThrUpdateSlot,\n };\n}\n\n/**\n * Parse market config. Layout-version aware.\n * For V0 slabs, fields beyond the basic config are read if present in the data,\n * otherwise defaults are returned.\n *\n * @param data - Slab data (may be a partial slice for discovery; pass layoutHint in that case)\n * @param layoutHint - Pre-detected layout to use; if omitted, detected from data.length.\n */\nexport function parseConfig(data: Uint8Array, layoutHint?: SlabLayout | null): MarketConfig {\n const layout = layoutHint !== undefined ? layoutHint : detectSlabLayout(data.length, data);\n const configOff = layout ? layout.configOffset : V0_HEADER_LEN;\n const configLen = layout ? layout.configLen : V0_CONFIG_LEN;\n\n const minLen = configOff + Math.min(configLen, 120); // need at least basic fields\n if (data.length < minLen) {\n throw new Error(`Slab data too short for config: ${data.length} < ${minLen}`);\n }\n\n let off = configOff;\n\n const collateralMint = new PublicKey(data.subarray(off, off + 32));\n off += 32;\n\n const vaultPubkey = new PublicKey(data.subarray(off, off + 32));\n off += 32;\n\n const indexFeedId = new PublicKey(data.subarray(off, off + 32));\n off += 32;\n\n const maxStalenessSlots = readU64LE(data, off);\n off += 8;\n\n const confFilterBps = readU16LE(data, off);\n off += 2;\n\n const vaultAuthorityBump = readU8(data, off);\n off += 1;\n\n const invert = readU8(data, off);\n off += 1;\n\n const unitScale = readU32LE(data, off);\n off += 4;\n\n // Funding rate parameters\n const fundingHorizonSlots = readU64LE(data, off);\n off += 8;\n\n const fundingKBps = readU64LE(data, off);\n off += 8;\n\n const fundingInvScaleNotionalE6 = readU128LE(data, off);\n off += 16;\n\n const fundingMaxPremiumBps = readI64LE(data, off);\n off += 8;\n\n const fundingMaxBpsPerSlot = readI64LE(data, off);\n off += 8;\n\n // Extended funding fields\n const fundingPremiumWeightBps = readU64LE(data, off);\n off += 8;\n\n const fundingSettlementIntervalSlots = readU64LE(data, off);\n off += 8;\n\n const fundingPremiumDampeningE6 = readU64LE(data, off);\n off += 8;\n\n const fundingPremiumMaxBpsPerSlot = readU64LE(data, off);\n off += 8;\n\n // Threshold parameters\n const threshFloor = readU128LE(data, off);\n off += 16;\n\n const threshRiskBps = readU64LE(data, off);\n off += 8;\n\n const threshUpdateIntervalSlots = readU64LE(data, off);\n off += 8;\n\n const threshStepBps = readU64LE(data, off);\n off += 8;\n\n const threshAlphaBps = readU64LE(data, off);\n off += 8;\n\n const threshMin = readU128LE(data, off);\n off += 16;\n\n const threshMax = readU128LE(data, off);\n off += 16;\n\n const threshMinStep = readU128LE(data, off);\n off += 16;\n\n // Oracle authority fields\n const oracleAuthority = new PublicKey(data.subarray(off, off + 32));\n off += 32;\n\n const authorityPriceE6 = readU64LE(data, off);\n off += 8;\n\n const authorityTimestamp = readI64LE(data, off);\n off += 8;\n\n // Oracle price circuit breaker\n const oraclePriceCapE2bps = readU64LE(data, off);\n off += 8;\n\n const lastEffectivePriceE6 = readU64LE(data, off);\n off += 8;\n\n // OI cap\n const oiCapMultiplierBps = readU64LE(data, off);\n off += 8;\n\n const maxPnlCap = readU64LE(data, off);\n off += 8;\n\n // Check if we have enough data for V1-only fields\n const remaining = configOff + configLen - off;\n\n let adaptiveFundingEnabled = false;\n let adaptiveScaleBps = 0;\n let adaptiveMaxFundingBps = 0n;\n let marketCreatedSlot = 0n;\n let oiRampSlots = 0n;\n let resolvedSlot = 0n;\n let insuranceIsolationBps = 0;\n let oraclePhase = 0;\n let cumulativeVolumeE6 = 0n;\n let phase2DeltaSlots = 0;\n\n if (remaining >= 40) {\n // V1 extended fields — on-chain order (percolator.rs:3617-3639):\n // market_created_slot(u64), oi_ramp_slots(u64),\n // adaptive_funding_enabled(u8), _pad(u8), adaptive_scale_bps(u16),\n // _pad2(u32), adaptive_max_funding_bps(u64),\n // insurance_isolation_bps(u16), _insurance_isolation_padding([u8;14])\n marketCreatedSlot = readU64LE(data, off);\n off += 8;\n\n oiRampSlots = readU64LE(data, off);\n off += 8;\n\n adaptiveFundingEnabled = readU8(data, off) !== 0;\n off += 1;\n off += 1; // _adaptive_pad\n adaptiveScaleBps = readU16LE(data, off);\n off += 2;\n off += 4; // _adaptive_pad2\n adaptiveMaxFundingBps = readU64LE(data, off);\n off += 8;\n\n if (remaining >= 42) {\n insuranceIsolationBps = readU16LE(data, off);\n // PERC-622: Read oracle phase fields from _insurance_isolation_padding\n // padding starts at off + 2 (after u16 insuranceIsolationBps)\n // [0..2] = mark_oracle_weight (PERC-118), [2] = oracle_phase, [3..11] = cumulative_volume, [11..14] = phase2_delta\n if (remaining >= 56) { // 42 + 14 bytes padding\n const padOff = off + 2;\n oraclePhase = Math.min(readU8(data, padOff + 2), 2);\n cumulativeVolumeE6 = readU64LE(data, padOff + 3);\n // phase2_delta_slots is u24 LE (3 bytes)\n phase2DeltaSlots = data[padOff + 11] | (data[padOff + 12] << 8) | (data[padOff + 13] << 16);\n }\n }\n }\n\n return {\n collateralMint,\n vaultPubkey,\n indexFeedId,\n maxStalenessSlots,\n confFilterBps,\n vaultAuthorityBump,\n invert,\n unitScale,\n fundingHorizonSlots,\n fundingKBps,\n fundingInvScaleNotionalE6,\n fundingMaxPremiumBps,\n fundingMaxBpsPerSlot,\n fundingPremiumWeightBps,\n fundingSettlementIntervalSlots,\n fundingPremiumDampeningE6,\n fundingPremiumMaxBpsPerSlot,\n threshFloor,\n threshRiskBps,\n threshUpdateIntervalSlots,\n threshStepBps,\n threshAlphaBps,\n threshMin,\n threshMax,\n threshMinStep,\n oracleAuthority,\n authorityPriceE6,\n authorityTimestamp,\n oraclePriceCapE2bps,\n lastEffectivePriceE6,\n oiCapMultiplierBps,\n maxPnlCap,\n adaptiveFundingEnabled,\n adaptiveScaleBps,\n adaptiveMaxFundingBps,\n marketCreatedSlot,\n oiRampSlots,\n resolvedSlot,\n insuranceIsolationBps,\n oraclePhase,\n cumulativeVolumeE6,\n phase2DeltaSlots,\n };\n}\n\n/**\n * Parse RiskParams from engine data. Layout-version aware.\n * For V0 slabs, extended params (risk_threshold, maintenance_fee, etc.) are\n * not present on-chain, so defaults (0) are returned.\n *\n * @param data - Slab data (may be a partial slice; pass layoutHint in that case)\n * @param layoutHint - Pre-detected layout to use; if omitted, detected from data.length.\n */\nexport function parseParams(data: Uint8Array, layoutHint?: SlabLayout | null): RiskParams {\n const layout = layoutHint !== undefined ? layoutHint : detectSlabLayout(data.length, data);\n const engineOff = layout ? layout.engineOff : V0_ENGINE_OFF;\n const paramsOff = layout ? layout.engineParamsOff : V0_ENGINE_PARAMS_OFF;\n const paramsSize = layout ? layout.paramsSize : V0_PARAMS_SIZE;\n const base = engineOff + paramsOff;\n\n if (data.length < base + Math.min(paramsSize, 56)) {\n throw new Error(\"Slab data too short for RiskParams\");\n }\n\n // Basic params present in both V0 and V1\n const result: RiskParams = {\n warmupPeriodSlots: readU64LE(data, base + PARAMS_WARMUP_PERIOD_OFF),\n maintenanceMarginBps: readU64LE(data, base + PARAMS_MAINTENANCE_MARGIN_OFF),\n initialMarginBps: readU64LE(data, base + PARAMS_INITIAL_MARGIN_OFF),\n tradingFeeBps: readU64LE(data, base + PARAMS_TRADING_FEE_OFF),\n maxAccounts: readU64LE(data, base + PARAMS_MAX_ACCOUNTS_OFF),\n newAccountFee: readU128LE(data, base + PARAMS_NEW_ACCOUNT_FEE_OFF),\n // Extended params: only read if V1 (paramsSize >= 144)\n riskReductionThreshold: 0n,\n maintenanceFeePerSlot: 0n,\n maxCrankStalenessSlots: 0n,\n liquidationFeeBps: 0n,\n liquidationFeeCap: 0n,\n liquidationBufferBps: 0n,\n minLiquidationAbs: 0n,\n };\n\n if (paramsSize >= 144) {\n result.riskReductionThreshold = readU128LE(data, base + PARAMS_RISK_THRESHOLD_OFF);\n result.maintenanceFeePerSlot = readU128LE(data, base + PARAMS_MAINTENANCE_FEE_OFF);\n result.maxCrankStalenessSlots = readU64LE(data, base + PARAMS_MAX_CRANK_STALENESS_OFF);\n result.liquidationFeeBps = readU64LE(data, base + PARAMS_LIQUIDATION_FEE_BPS_OFF);\n result.liquidationFeeCap = readU128LE(data, base + PARAMS_LIQUIDATION_FEE_CAP_OFF);\n result.liquidationBufferBps = readU64LE(data, base + PARAMS_LIQUIDATION_BUFFER_OFF);\n result.minLiquidationAbs = readU128LE(data, base + PARAMS_MIN_LIQUIDATION_OFF);\n }\n\n return result;\n}\n\n/**\n * Parse RiskEngine state (excluding accounts array). Layout-version aware.\n */\nexport function parseEngine(data: Uint8Array): EngineState {\n const layout = detectSlabLayout(data.length, data);\n if (!layout) {\n throw new Error(`Unrecognized slab data length: ${data.length}. Cannot determine layout version.`);\n }\n\n const base = layout.engineOff;\n\n return {\n vault: readU128LE(data, base),\n insuranceFund: {\n balance: readU128LE(data, base + layout.engineInsuranceOff),\n feeRevenue: readU128LE(data, base + layout.engineInsuranceOff + 16),\n isolatedBalance: layout.hasInsuranceIsolation\n ? readU128LE(data, base + layout.engineInsuranceIsolatedOff)\n : 0n,\n isolationBps: layout.hasInsuranceIsolation\n ? readU16LE(data, base + layout.engineInsuranceIsolationBpsOff)\n : 0,\n },\n currentSlot: readU64LE(data, base + layout.engineCurrentSlotOff),\n fundingIndexQpbE6: readI128LE(data, base + layout.engineFundingIndexOff),\n lastFundingSlot: readU64LE(data, base + layout.engineLastFundingSlotOff),\n fundingRateBpsPerSlotLast: readI64LE(data, base + layout.engineFundingRateBpsOff),\n lastCrankSlot: readU64LE(data, base + layout.engineLastCrankSlotOff),\n maxCrankStalenessSlots: readU64LE(data, base + layout.engineMaxCrankStalenessOff),\n totalOpenInterest: readU128LE(data, base + layout.engineTotalOiOff),\n longOi: layout.engineLongOiOff >= 0\n ? readU128LE(data, base + layout.engineLongOiOff)\n : 0n,\n shortOi: layout.engineShortOiOff >= 0\n ? readU128LE(data, base + layout.engineShortOiOff)\n : 0n,\n cTot: readU128LE(data, base + layout.engineCTotOff),\n pnlPosTot: readU128LE(data, base + layout.enginePnlPosTotOff),\n liqCursor: readU16LE(data, base + layout.engineLiqCursorOff),\n gcCursor: readU16LE(data, base + layout.engineGcCursorOff),\n lastSweepStartSlot: readU64LE(data, base + layout.engineLastSweepStartOff),\n lastSweepCompleteSlot: readU64LE(data, base + layout.engineLastSweepCompleteOff),\n crankCursor: readU16LE(data, base + layout.engineCrankCursorOff),\n sweepStartIdx: readU16LE(data, base + layout.engineSweepStartIdxOff),\n lifetimeLiquidations: readU64LE(data, base + layout.engineLifetimeLiquidationsOff),\n lifetimeForceCloses: readU64LE(data, base + layout.engineLifetimeForceClosesOff),\n netLpPos: readI128LE(data, base + layout.engineNetLpPosOff),\n lpSumAbs: readU128LE(data, base + layout.engineLpSumAbsOff),\n lpMaxAbs: layout.engineLpMaxAbsOff >= 0 ? readU128LE(data, base + layout.engineLpMaxAbsOff) : 0n,\n lpMaxAbsSweep: layout.engineLpMaxAbsSweepOff >= 0 ? readU128LE(data, base + layout.engineLpMaxAbsSweepOff) : 0n,\n emergencyOiMode: layout.engineEmergencyOiModeOff >= 0\n ? data[base + layout.engineEmergencyOiModeOff] !== 0\n : false,\n emergencyStartSlot: layout.engineEmergencyStartSlotOff >= 0\n ? readU64LE(data, base + layout.engineEmergencyStartSlotOff)\n : 0n,\n lastBreakerSlot: layout.engineLastBreakerSlotOff >= 0\n ? readU64LE(data, base + layout.engineLastBreakerSlotOff)\n : 0n,\n markPriceE6: layout.engineMarkPriceOff >= 0\n ? readU64LE(data, base + layout.engineMarkPriceOff)\n : 0n,\n numUsedAccounts: (() => {\n if (layout.postBitmap < 18) return 0;\n const bw = layout.bitmapWords;\n return readU16LE(data, base + layout.engineBitmapOff + bw * 8);\n })(),\n nextAccountId: (() => {\n if (layout.postBitmap < 18) return 0n;\n const bw = layout.bitmapWords;\n const numUsedOff = layout.engineBitmapOff + bw * 8;\n return readU64LE(data, base + Math.ceil((numUsedOff + 2) / 8) * 8);\n })(),\n };\n}\n\n/**\n * Read bitmap to get list of used account indices.\n */\n/**\n * Return all account indices whose bitmap bit is set (i.e. slot is in use).\n * Uses the layout-aware bitmap offset so V1_LEGACY slabs (bitmap at rel+672) are handled correctly.\n */\nexport function parseUsedIndices(data: Uint8Array): number[] {\n const layout = detectSlabLayout(data.length, data);\n if (!layout) throw new Error(`Unrecognized slab data length: ${data.length}`);\n\n const base = layout.engineOff + layout.engineBitmapOff;\n if (data.length < base + layout.bitmapWords * 8) {\n throw new Error(\"Slab data too short for bitmap\");\n }\n\n const used: number[] = [];\n for (let word = 0; word < layout.bitmapWords; word++) {\n const bits = readU64LE(data, base + word * 8);\n if (bits === 0n) continue;\n for (let bit = 0; bit < 64; bit++) {\n if ((bits >> BigInt(bit)) & 1n) {\n used.push(word * 64 + bit);\n }\n }\n }\n return used;\n}\n\n/**\n * Check if a specific account index is used.\n */\nexport function isAccountUsed(data: Uint8Array, idx: number): boolean {\n const layout = detectSlabLayout(data.length, data);\n if (!layout) return false;\n if (!Number.isInteger(idx) || idx < 0 || idx >= layout.maxAccounts) return false;\n const base = layout.engineOff + layout.engineBitmapOff;\n const word = Math.floor(idx / 64);\n const bit = idx % 64;\n const bits = readU64LE(data, base + word * 8);\n return ((bits >> BigInt(bit)) & 1n) !== 0n;\n}\n\n/**\n * Calculate the maximum valid account index for a given slab size.\n */\nexport function maxAccountIndex(dataLen: number): number {\n const layout = detectSlabLayout(dataLen);\n if (!layout) return 0;\n const accountsEnd = dataLen - layout.accountsOff;\n if (accountsEnd <= 0) return 0;\n return Math.floor(accountsEnd / layout.accountSize);\n}\n\n/**\n * Parse a single account by index.\n */\nexport function parseAccount(data: Uint8Array, idx: number): Account {\n const layout = detectSlabLayout(data.length, data);\n if (!layout) throw new Error(`Unrecognized slab data length: ${data.length}`);\n\n const maxIdx = maxAccountIndex(data.length);\n if (!Number.isInteger(idx) || idx < 0 || idx >= maxIdx) {\n throw new Error(`Account index out of range: ${idx} (max: ${maxIdx - 1})`);\n }\n\n const base = layout.accountsOff + idx * layout.accountSize;\n if (data.length < base + layout.accountSize) {\n throw new Error(\"Slab data too short for account\");\n }\n\n // Select layout-dependent account field offsets.\n // V_ADL slabs (account_size=312) have shifted offsets from reserved_pnl growing u64→u128 (PERC-8267).\n const isAdl = layout.accountSize >= 312;\n const warmupStartedOff = isAdl ? V_ADL_ACCT_WARMUP_STARTED_OFF : ACCT_WARMUP_STARTED_OFF;\n const warmupSlopeOff = isAdl ? V_ADL_ACCT_WARMUP_SLOPE_OFF : ACCT_WARMUP_SLOPE_OFF;\n const positionSizeOff = isAdl ? V_ADL_ACCT_POSITION_SIZE_OFF : ACCT_POSITION_SIZE_OFF;\n const entryPriceOff = isAdl ? V_ADL_ACCT_ENTRY_PRICE_OFF : ACCT_ENTRY_PRICE_OFF;\n const fundingIndexOff = isAdl ? V_ADL_ACCT_FUNDING_INDEX_OFF : ACCT_FUNDING_INDEX_OFF;\n const matcherProgOff = isAdl ? V_ADL_ACCT_MATCHER_PROGRAM_OFF: ACCT_MATCHER_PROGRAM_OFF;\n const matcherCtxOff = isAdl ? V_ADL_ACCT_MATCHER_CONTEXT_OFF: ACCT_MATCHER_CONTEXT_OFF;\n const feeCreditsOff = isAdl ? V_ADL_ACCT_FEE_CREDITS_OFF : ACCT_FEE_CREDITS_OFF;\n const lastFeeSlotOff = isAdl ? V_ADL_ACCT_LAST_FEE_SLOT_OFF : ACCT_LAST_FEE_SLOT_OFF;\n\n const kindByte = readU8(data, base + ACCT_KIND_OFF);\n const kind = kindByte === 1 ? AccountKind.LP : AccountKind.User;\n\n return {\n kind,\n accountId: readU64LE(data, base + ACCT_ACCOUNT_ID_OFF),\n capital: readU128LE(data, base + ACCT_CAPITAL_OFF),\n pnl: readI128LE(data, base + ACCT_PNL_OFF),\n reservedPnl: isAdl ? readU128LE(data, base + ACCT_RESERVED_PNL_OFF) : readU64LE(data, base + ACCT_RESERVED_PNL_OFF),\n warmupStartedAtSlot: readU64LE(data, base + warmupStartedOff),\n warmupSlopePerStep: readU128LE(data, base + warmupSlopeOff),\n positionSize: readI128LE(data, base + positionSizeOff),\n entryPrice: readU64LE(data, base + entryPriceOff),\n fundingIndex: readI128LE(data, base + fundingIndexOff),\n matcherProgram: new PublicKey(data.subarray(base + matcherProgOff, base + matcherProgOff + 32)),\n matcherContext: new PublicKey(data.subarray(base + matcherCtxOff, base + matcherCtxOff + 32)),\n owner: new PublicKey(data.subarray(base + layout.acctOwnerOff, base + layout.acctOwnerOff + 32)),\n feeCredits: readI128LE(data, base + feeCreditsOff),\n lastFeeSlot: readU64LE(data, base + lastFeeSlotOff),\n };\n}\n\n/**\n * Parse all used accounts.\n */\nexport function parseAllAccounts(data: Uint8Array): { idx: number; account: Account }[] {\n const indices = parseUsedIndices(data);\n const maxIdx = maxAccountIndex(data.length);\n const validIndices = indices.filter(idx => idx < maxIdx);\n const droppedCount = indices.length - validIndices.length;\n if (droppedCount > 0) {\n console.warn(\n `[parseAllAccounts] bitmap claims ${indices.length} used accounts but only ${maxIdx} fit ` +\n `in the slab — ${droppedCount} out-of-bounds indices dropped (possible bitmap corruption)`,\n );\n }\n return validIndices.map(idx => ({\n idx,\n account: parseAccount(data, idx),\n }));\n}\n\n","import { PublicKey } from \"@solana/web3.js\";\n\nconst textEncoder = new TextEncoder();\n\n/**\n * Derive vault authority PDA.\n * Seeds: [\"vault\", slab_key]\n */\nexport function deriveVaultAuthority(\n programId: PublicKey,\n slab: PublicKey\n): [PublicKey, number] {\n return PublicKey.findProgramAddressSync(\n [textEncoder.encode(\"vault\"), slab.toBytes()],\n programId\n );\n}\n\n/**\n * Derive insurance LP mint PDA.\n * Seeds: [\"ins_lp\", slab_key]\n */\nexport function deriveInsuranceLpMint(\n programId: PublicKey,\n slab: PublicKey\n): [PublicKey, number] {\n return PublicKey.findProgramAddressSync(\n [textEncoder.encode(\"ins_lp\"), slab.toBytes()],\n programId\n );\n}\n\nconst LP_INDEX_U16_MAX = 0xffff;\n\n/**\n * Derive LP PDA for TradeCpi.\n * Seeds: [\"lp\", slab_key, lp_idx as u16 LE]\n */\nexport function deriveLpPda(\n programId: PublicKey,\n slab: PublicKey,\n lpIdx: number\n): [PublicKey, number] {\n if (\n typeof lpIdx !== \"number\" ||\n !Number.isInteger(lpIdx) ||\n lpIdx < 0 ||\n lpIdx > LP_INDEX_U16_MAX\n ) {\n throw new Error(\n `deriveLpPda: lpIdx must be an integer in [0, ${LP_INDEX_U16_MAX}], got ${lpIdx}`,\n );\n }\n const idxBuf = new Uint8Array(2);\n new DataView(idxBuf.buffer).setUint16(0, lpIdx, true);\n return PublicKey.findProgramAddressSync(\n [textEncoder.encode(\"lp\"), slab.toBytes(), idxBuf],\n programId\n );\n}\n\n/**\n * Derive keeper fund PDA.\n * Seeds: [\"keeper_fund\", slab_key]\n */\nexport function deriveKeeperFund(\n programId: PublicKey,\n slab: PublicKey\n): [PublicKey, number] {\n return PublicKey.findProgramAddressSync(\n [textEncoder.encode(\"keeper_fund\"), slab.toBytes()],\n programId\n );\n}\n\n// ---------------------------------------------------------------------------\n// DEX Program IDs\n// ---------------------------------------------------------------------------\n\n/** PumpSwap AMM program ID. */\nexport const PUMPSWAP_PROGRAM_ID = new PublicKey(\n \"pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA\"\n);\n\n/** Raydium CLMM (Concentrated Liquidity) program ID. */\nexport const RAYDIUM_CLMM_PROGRAM_ID = new PublicKey(\n \"CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK\"\n);\n\n/** Meteora DLMM (Dynamic Liquidity Market Maker) program ID. */\nexport const METEORA_DLMM_PROGRAM_ID = new PublicKey(\n \"LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo\"\n);\n\n// ---------------------------------------------------------------------------\n// Pyth Push Oracle\n// ---------------------------------------------------------------------------\n\n/** Pyth Push Oracle program on mainnet. */\nexport const PYTH_PUSH_ORACLE_PROGRAM_ID = new PublicKey(\n \"pythWSnswVUd12oZpeFP8e9CVaEqJg25g1Vtc2biRsT\"\n);\n\n// ---------------------------------------------------------------------------\n// Creator Lock PDA (PERC-627)\n// ---------------------------------------------------------------------------\n\n/**\n * Seed used to derive the creator lock PDA.\n * Matches `creator_lock::CREATOR_LOCK_SEED` in percolator-prog.\n */\nexport const CREATOR_LOCK_SEED = \"creator_lock\";\n\n/**\n * Derive the creator lock PDA for a given slab.\n * Seeds: [\"creator_lock\", slab_key]\n *\n * This PDA is required as accounts[9] in every LpVaultWithdraw instruction\n * since percolator-prog PR#170 (GH#1926 / PERC-8287).\n * Non-creator withdrawers must pass this key; if no lock exists on-chain the\n * enforcement is a no-op. The SDK must ALWAYS include it — passing it is mandatory.\n *\n * @param programId - The percolator program ID.\n * @param slab - The slab (market) public key.\n * @returns [pda, bump]\n *\n * @example\n * ```ts\n * const [creatorLockPda] = deriveCreatorLockPda(PROGRAM_ID, slabKey);\n * ```\n */\nexport function deriveCreatorLockPda(\n programId: PublicKey,\n slab: PublicKey\n): [PublicKey, number] {\n return PublicKey.findProgramAddressSync(\n [textEncoder.encode(CREATOR_LOCK_SEED), slab.toBytes()],\n programId\n );\n}\n/** 32-byte feed id as 64 hex digits (optional `0x` prefix after trim). */\nconst PYTH_FEED_ID_HEX_LEN = 64;\n\nfunction normalizePythFeedIdHex(feedIdHex: string): string {\n let s = feedIdHex.trim();\n if (s.startsWith(\"0x\") || s.startsWith(\"0X\")) {\n s = s.slice(2);\n }\n return s;\n}\n\n/**\n * Derive the Pyth Push Oracle PDA for a given feed ID.\n * Seeds: [shard_id(u16 LE, always 0), feed_id(32 bytes)]\n * Program: pythWSnswVUd12oZpeFP8e9CVaEqJg25g1Vtc2biRsT\n */\nconst FEED_HEX_RE = /^[0-9a-fA-F]{64}$/;\n\nexport function derivePythPushOraclePDA(feedIdHex: string): [PublicKey, number] {\n const normalized = normalizePythFeedIdHex(feedIdHex);\n if (!FEED_HEX_RE.test(normalized)) {\n throw new Error(\n `derivePythPushOraclePDA: feedIdHex must be 64 hex digits (32 bytes); got ${normalized.length === 64 ? \"non-hexadecimal characters\" : normalized.length + \" chars\"}`, );\n }\n const feedId = new Uint8Array(32);\n for (let i = 0; i < 32; i++) {\n feedId[i] = parseInt(normalized.substring(i * 2, i * 2 + 2), 16);\n }\n const shardBuf = new Uint8Array(2); // shard_id = 0 (u16 LE)\n return PublicKey.findProgramAddressSync(\n [shardBuf, feedId],\n PYTH_PUSH_ORACLE_PROGRAM_ID,\n );\n}\n","import { Connection, PublicKey } from \"@solana/web3.js\";\nimport {\n getAssociatedTokenAddress,\n getAssociatedTokenAddressSync,\n getAccount,\n Account,\n TOKEN_PROGRAM_ID,\n} from \"@solana/spl-token\";\nimport { TOKEN_2022_PROGRAM_ID } from \"./token-program.js\";\n\n/**\n * Get the associated token address for an owner and mint.\n * Supports both standard SPL Token and Token2022 via optional tokenProgramId.\n */\nexport async function getAta(\n owner: PublicKey,\n mint: PublicKey,\n allowOwnerOffCurve = false,\n tokenProgramId: PublicKey = TOKEN_PROGRAM_ID,\n): Promise<PublicKey> {\n return getAssociatedTokenAddress(mint, owner, allowOwnerOffCurve, tokenProgramId);\n}\n\n/**\n * Synchronous version of getAta.\n * Supports both standard SPL Token and Token2022 via optional tokenProgramId.\n */\nexport function getAtaSync(\n owner: PublicKey,\n mint: PublicKey,\n allowOwnerOffCurve = false,\n tokenProgramId: PublicKey = TOKEN_PROGRAM_ID,\n): PublicKey {\n return getAssociatedTokenAddressSync(mint, owner, allowOwnerOffCurve, tokenProgramId);\n}\n\n/**\n * Fetch token account info.\n * Supports both standard SPL Token and Token2022 via optional tokenProgramId.\n * Throws if account doesn't exist.\n */\nexport async function fetchTokenAccount(\n connection: Connection,\n address: PublicKey,\n tokenProgramId: PublicKey = TOKEN_PROGRAM_ID,\n): Promise<Account> {\n return getAccount(connection, address, undefined, tokenProgramId);\n}\n","import { Connection, PublicKey } from \"@solana/web3.js\";\nimport {\n parseHeader,\n parseConfig,\n parseParams,\n detectSlabLayout,\n SLAB_TIERS_V1M,\n SLAB_TIERS_V2,\n SLAB_TIERS_V_ADL,\n type SlabHeader,\n type MarketConfig,\n type EngineState,\n type RiskParams,\n type SlabLayout,\n} from \"./slab.js\";\n\n/** V1 bitmap offset within engine struct (updated for PERC-120/121/122 struct changes) */\nconst ENGINE_BITMAP_OFF = 656; // Updated for PERC-299 (608 + 24 emergency OI fields)\n/** V0 bitmap offset within engine struct (deployed devnet program) */\nconst ENGINE_BITMAP_OFF_V0 = 320;\n\n/**\n * A discovered Percolator market from on-chain program accounts.\n */\nexport interface DiscoveredMarket {\n slabAddress: PublicKey;\n /** The program that owns this slab account */\n programId: PublicKey;\n header: SlabHeader;\n config: MarketConfig;\n engine: EngineState;\n params: RiskParams;\n}\n\n/** PERCOLAT magic bytes — stored little-endian on-chain as TALOCREP */\nconst MAGIC_BYTES = new Uint8Array([0x54, 0x41, 0x4c, 0x4f, 0x43, 0x52, 0x45, 0x50]);\n\n/**\n * Slab tier definitions — V1 layout (all tiers upgraded as of 2026-03-13).\n * IMPORTANT: dataSize must match the compiled program's SLAB_LEN for that MAX_ACCOUNTS.\n * The on-chain program has a hardcoded SLAB_LEN — slab account data.len() must equal it exactly.\n *\n * Layout: HEADER(104) + CONFIG(536) + RiskEngine(variable by tier)\n * ENGINE_OFF = 640 (HEADER=104 + CONFIG=536, padded to 8-byte align on SBF)\n * RiskEngine = fixed(656) + bitmap(BW*8) + post_bitmap(18) + next_free(N*2) + pad + accounts(N*248)\n *\n * Values are empirically verified against on-chain initialized accounts (GH #1109):\n * small = 65,352 (256-acct program, verified on-chain post-V1 upgrade)\n * medium = 257,448 (1024-acct program g9msRSV3, verified on-chain)\n * large = 1,025,832 (4096-acct program FxfD37s1, pre-PERC-118, matches slabDataSizeV1(4096) formula)\n *\n * NOTE: small program (FwfBKZXb) redeployed with --features small,devnet (2026-03-13).\n * Large program FxfD37s1 is pre-PERC-118 — SLAB_LEN=1,025,832, matching formula.\n * See GH #1109, GH #1112.\n *\n * History: Small was V0 (62_808) until 2026-03-13 program upgrade. V0 values preserved\n * in SLAB_TIERS_V0 for discovery of legacy on-chain accounts.\n */\nexport const SLAB_TIERS = {\n small: { maxAccounts: 256, dataSize: 65_352, label: \"Small\", description: \"256 slots · ~0.45 SOL\" },\n medium: { maxAccounts: 1024, dataSize: 257_448, label: \"Medium\", description: \"1,024 slots · ~1.79 SOL\" },\n large: { maxAccounts: 4096, dataSize: 1_025_832, label: \"Large\", description: \"4,096 slots · ~7.14 SOL\" },\n} as const;\n\n/** @deprecated V0 slab sizes — kept for backward compatibility with old on-chain slabs */\nexport const SLAB_TIERS_V0 = {\n small: { maxAccounts: 256, dataSize: 62_808, label: \"Small\", description: \"256 slots · ~0.44 SOL\" },\n medium: { maxAccounts: 1024, dataSize: 248_760, label: \"Medium\", description: \"1,024 slots · ~1.73 SOL\" },\n large: { maxAccounts: 4096, dataSize: 992_568, label: \"Large\", description: \"4,096 slots · ~6.90 SOL\" },\n} as const;\n\n/**\n * V1D slab sizes — actually-deployed devnet V1 program (ENGINE_OFF=424, BITMAP_OFF=624).\n * PR #1200 added V1D layout detection in slab.ts but discovery.ts ALL_TIERS was missing\n * these sizes, causing V1D slabs to fall through to the memcmp fallback with wrong dataSize\n * hints → detectSlabLayout returning null → parse failure (GH#1205).\n *\n * Sizes computed via computeSlabSize(ENGINE_OFF=424, BITMAP_OFF=624, ACCOUNT_SIZE=248, N, postBitmap=2):\n * The V1D deployed program uses postBitmap=2 (free_head u16 only — no num_used/pad/next_account_id).\n * This is 16 bytes smaller per tier than the SDK default (postBitmap=18). GH#1234.\n * micro = 17,064 (64 slots)\n * small = 65,088 (256 slots)\n * medium = 257,184 (1,024 slots)\n * large = 1,025,568 (4,096 slots)\n */\nexport const SLAB_TIERS_V1D = {\n micro: { maxAccounts: 64, dataSize: 17_064, label: \"Micro\", description: \"64 slots (V1D devnet)\" },\n small: { maxAccounts: 256, dataSize: 65_088, label: \"Small\", description: \"256 slots (V1D devnet)\" },\n medium: { maxAccounts: 1024, dataSize: 257_184, label: \"Medium\", description: \"1,024 slots (V1D devnet)\" },\n large: { maxAccounts: 4096, dataSize: 1_025_568, label: \"Large\", description: \"4,096 slots (V1D devnet)\" },\n} as const;\n\n/**\n * V1D legacy slab sizes — on-chain V1D slabs created before GH#1234 when the SDK assumed\n * postBitmap=18. These are 16 bytes larger per tier than SLAB_TIERS_V1D.\n * PR #1236 fixed postBitmap for new slabs (→2) but caused slab 6ZytbpV4 (65104 bytes,\n * top active market ~$15k 24h vol) to be unrecognized → \"Failed to load market\". GH#1237.\n *\n * Sizes computed via computeSlabSize(ENGINE_OFF=424, BITMAP_OFF=624, ACCOUNT_SIZE=248, N, postBitmap=18):\n * micro = 17,080 (64 slots)\n * small = 65,104 (256 slots) ← slab 6ZytbpV4 TEST/USD\n * medium = 257,200 (1,024 slots)\n * large = 1,025,584 (4,096 slots)\n */\nexport const SLAB_TIERS_V1D_LEGACY = {\n micro: { maxAccounts: 64, dataSize: 17_080, label: \"Micro\", description: \"64 slots (V1D legacy, postBitmap=18)\" },\n small: { maxAccounts: 256, dataSize: 65_104, label: \"Small\", description: \"256 slots (V1D legacy, postBitmap=18)\" },\n medium: { maxAccounts: 1024, dataSize: 257_200, label: \"Medium\", description: \"1,024 slots (V1D legacy, postBitmap=18)\" },\n large: { maxAccounts: 4096, dataSize: 1_025_584, label: \"Large\", description: \"4,096 slots (V1D legacy, postBitmap=18)\" },\n} as const;\n\n/** @deprecated Alias — use SLAB_TIERS (already V1) */\nexport const SLAB_TIERS_V1 = SLAB_TIERS;\n\n/**\n * V_ADL slab tier sizes — PERC-8270/8271 ADL-upgraded program.\n * ENGINE_OFF=624, BITMAP_OFF=1006, ACCOUNT_SIZE=312, postBitmap=18.\n * New account layout adds ADL tracking fields (+64 bytes/account).\n * BPF SLAB_LEN verified by cargo build-sbf in PERC-8271: large (4096) = 1288304 bytes.\n */\n// Single source of truth lives in slab.ts (SLAB_TIERS_V_ADL).\nexport const SLAB_TIERS_V_ADL_DISCOVERY = SLAB_TIERS_V_ADL;\n\nexport type SlabTierKey = keyof typeof SLAB_TIERS;\n\n/** Calculate slab data size for arbitrary account count.\n *\n * Layout (SBF, u128 align = 8):\n * HEADER(104) + CONFIG(536) → ENGINE_OFF = 640\n * RiskEngine fixed scalars: 656 bytes (PERC-299: +24 emergency OI, +32 long/short OI)\n * + bitmap: ceil(N/64)*8\n * + num_used_accounts(u16) + pad(6) + next_account_id(u64) + free_head(u16) = 18\n * + next_free: N*2\n * + pad to 8-byte alignment for Account array\n * + accounts: N*248\n *\n * Must match the on-chain program's SLAB_LEN exactly.\n */\nexport function slabDataSize(maxAccounts: number): number {\n // V0 layout (deployed devnet): ENGINE_OFF=480, ENGINE_BITMAP_OFF=320, ACCOUNT_SIZE=240\n const ENGINE_OFF_V0 = 480;\n const ENGINE_BITMAP_OFF_V0 = 320;\n const ACCOUNT_SIZE_V0 = 240;\n const bitmapBytes = Math.ceil(maxAccounts / 64) * 8;\n const postBitmap = 18;\n const nextFreeBytes = maxAccounts * 2;\n const preAccountsLen = ENGINE_BITMAP_OFF_V0 + bitmapBytes + postBitmap + nextFreeBytes;\n const accountsOff = Math.ceil(preAccountsLen / 8) * 8;\n return ENGINE_OFF_V0 + accountsOff + maxAccounts * ACCOUNT_SIZE_V0;\n}\n\n/**\n * Calculate slab data size for V1 layout (ENGINE_OFF=640).\n *\n * NOTE: This formula is accurate for small (256) and medium (1024) tiers but\n * underestimates large (4096) by 16 bytes — likely due to a padding/alignment\n * difference at high account counts or a post-PERC-118 struct addition in the\n * deployed binary. Always prefer the hardcoded SLAB_TIERS values (empirically\n * verified on-chain) over this formula for production use.\n */\nexport function slabDataSizeV1(maxAccounts: number): number {\n const ENGINE_OFF_V1 = 640; // HEADER(104) + CONFIG(536) aligned to 8 on SBF = 640\n const ENGINE_BITMAP_OFF_V1 = 656;\n const ACCOUNT_SIZE_V1 = 248;\n const bitmapBytes = Math.ceil(maxAccounts / 64) * 8;\n const postBitmap = 18;\n const nextFreeBytes = maxAccounts * 2;\n const preAccountsLen = ENGINE_BITMAP_OFF_V1 + bitmapBytes + postBitmap + nextFreeBytes;\n const accountsOff = Math.ceil(preAccountsLen / 8) * 8;\n return ENGINE_OFF_V1 + accountsOff + maxAccounts * ACCOUNT_SIZE_V1;\n}\n\n/**\n * Validate that a slab data size matches one of the known tier sizes.\n * Use this to catch tier↔program mismatches early (PERC-277).\n *\n * @param dataSize - The expected slab data size (from SLAB_TIERS[tier].dataSize)\n * @param programSlabLen - The program's compiled SLAB_LEN (from on-chain error logs or program introspection)\n * @returns true if sizes match, false if there's a mismatch\n */\nexport function validateSlabTierMatch(dataSize: number, programSlabLen: number): boolean {\n return dataSize === programSlabLen;\n}\n\n/** All known slab data sizes for discovery (V0 + V1 + V1D + V1D legacy + V1M + V_ADL tiers) */\nconst ALL_SLAB_SIZES = [\n ...Object.values(SLAB_TIERS).map(t => t.dataSize),\n ...Object.values(SLAB_TIERS_V0).map(t => t.dataSize),\n ...Object.values(SLAB_TIERS_V1D).map(t => t.dataSize),\n ...Object.values(SLAB_TIERS_V1D_LEGACY).map(t => t.dataSize),\n ...Object.values(SLAB_TIERS_V1M).map(t => t.dataSize),\n ...Object.values(SLAB_TIERS_V_ADL).map(t => t.dataSize),\n];\n\n/** Legacy constant for backward compat */\nconst SLAB_DATA_SIZE = SLAB_TIERS.large.dataSize;\n\n/** We need header(104) + config(536) + engine up to nextAccountId (~1200). Total ~1840. Use 1940 for margin. */\nconst HEADER_SLICE_LENGTH = 1940;\n\nfunction dv(data: Uint8Array): DataView {\n return new DataView(data.buffer, data.byteOffset, data.byteLength);\n}\nfunction readU16LE(data: Uint8Array, off: number): number {\n return dv(data).getUint16(off, true);\n}\nfunction readU64LE(data: Uint8Array, off: number): bigint {\n return dv(data).getBigUint64(off, true);\n}\nfunction readI64LE(data: Uint8Array, off: number): bigint {\n return dv(data).getBigInt64(off, true);\n}\nfunction readU128LE(buf: Uint8Array, offset: number): bigint {\n const lo = readU64LE(buf, offset);\n const hi = readU64LE(buf, offset + 8);\n return (hi << 64n) | lo;\n}\nfunction readI128LE(buf: Uint8Array, offset: number): bigint {\n const lo = readU64LE(buf, offset);\n const hi = readU64LE(buf, offset + 8);\n const unsigned = (hi << 64n) | lo;\n const SIGN_BIT = 1n << 127n;\n if (unsigned >= SIGN_BIT) return unsigned - (1n << 128n);\n return unsigned;\n}\n\n/**\n * Light engine parser that works with partial slab data (dataSlice, no accounts array).\n * Requires a layout hint (from detectSlabLayout on the actual slab size) to use correct offsets.\n *\n * @param data — partial slab slice (HEADER_SLICE_LENGTH bytes)\n * @param layout — SlabLayout from detectSlabLayout(actualDataSize). If null, falls back to V0.\n * @param maxAccounts — tier's max accounts for bitmap offset calculation\n */\nfunction parseEngineLight(\n data: Uint8Array,\n layout: SlabLayout | null,\n maxAccounts: number = 4096,\n): EngineState {\n const isV0 = !layout || layout.version === 0;\n const base = layout ? layout.engineOff : 480; // V0=480, V1=640\n const bitmapOff = layout ? layout.engineBitmapOff : ENGINE_BITMAP_OFF_V0;\n\n const minLen = base + bitmapOff;\n if (data.length < minLen) {\n throw new Error(`Slab data too short for engine light parse: ${data.length} < ${minLen}`);\n }\n\n // Compute tier-dependent offsets for numUsedAccounts and nextAccountId\n const bitmapWords = Math.ceil(maxAccounts / 64);\n const numUsedOff = bitmapOff + bitmapWords * 8; // u16 right after bitmap\n const nextAccountIdOff = Math.ceil((numUsedOff + 2) / 8) * 8; // u64, 8-byte aligned\n\n const canReadNumUsed = data.length >= base + numUsedOff + 2;\n const canReadNextId = data.length >= base + nextAccountIdOff + 8;\n\n if (isV0) {\n // V0 engine struct (deployed devnet): ENGINE_OFF=480\n // vault(0,16) + insurance(16,32) + params(48,56) + currentSlot(104,8)\n // + fundingIndex(112,16) + lastFundingSlot(128,8) + fundingRateBps(136,8)\n // + lastCrankSlot(144,8) + maxCrankStaleness(152,8) + totalOI(160,16)\n // + cTot(176,16) + pnlPosTot(192,16) + liqCursor(208,2) + gcCursor(210,2)\n // + lastSweepStart(216,8) + lastSweepComplete(224,8) + crankCursor(232,2) + sweepStartIdx(234,2)\n // + lifetimeLiquidations(240,8) + lifetimeForceCloses(248,8)\n // + netLpPos(256,16) + lpSumAbs(272,16) + lpMaxAbs(288,16) + bitmap(320)\n return {\n vault: readU128LE(data, base + 0),\n insuranceFund: {\n balance: readU128LE(data, base + 16),\n feeRevenue: readU128LE(data, base + 32),\n isolatedBalance: 0n,\n isolationBps: 0,\n },\n currentSlot: readU64LE(data, base + 104),\n fundingIndexQpbE6: readI128LE(data, base + 112),\n lastFundingSlot: readU64LE(data, base + 128),\n fundingRateBpsPerSlotLast: readI64LE(data, base + 136),\n lastCrankSlot: readU64LE(data, base + 144),\n maxCrankStalenessSlots: readU64LE(data, base + 152),\n totalOpenInterest: readU128LE(data, base + 160),\n longOi: 0n,\n shortOi: 0n,\n cTot: readU128LE(data, base + 176),\n pnlPosTot: readU128LE(data, base + 192),\n liqCursor: readU16LE(data, base + 208),\n gcCursor: readU16LE(data, base + 210),\n lastSweepStartSlot: readU64LE(data, base + 216),\n lastSweepCompleteSlot: readU64LE(data, base + 224),\n crankCursor: readU16LE(data, base + 232),\n sweepStartIdx: readU16LE(data, base + 234),\n lifetimeLiquidations: readU64LE(data, base + 240),\n lifetimeForceCloses: readU64LE(data, base + 248),\n netLpPos: readI128LE(data, base + 256),\n lpSumAbs: readU128LE(data, base + 272),\n lpMaxAbs: readU128LE(data, base + 288),\n lpMaxAbsSweep: 0n,\n emergencyOiMode: false,\n emergencyStartSlot: 0n,\n lastBreakerSlot: 0n,\n markPriceE6: 0n, // V0 engine has no mark_price field\n numUsedAccounts: canReadNumUsed ? readU16LE(data, base + numUsedOff) : 0,\n nextAccountId: canReadNextId ? readU64LE(data, base + nextAccountIdOff) : 0n,\n };\n }\n\n // V2 engine struct (BPF intermediate): ENGINE_OFF=600, BITMAP_OFF=432\n // No mark_price, long_oi, short_oi, emergency OI fields.\n // Field offsets relative to engineOff are different from V1.\n const isV2 = layout?.version === 2;\n if (isV2) {\n return {\n vault: readU128LE(data, base + 0),\n insuranceFund: {\n balance: readU128LE(data, base + 16),\n feeRevenue: readU128LE(data, base + 32),\n isolatedBalance: readU128LE(data, base + 48),\n isolationBps: readU16LE(data, base + 64),\n },\n currentSlot: readU64LE(data, base + 352),\n fundingIndexQpbE6: readI128LE(data, base + 360),\n lastFundingSlot: readU64LE(data, base + 376),\n fundingRateBpsPerSlotLast: readI64LE(data, base + 384),\n lastCrankSlot: readU64LE(data, base + 392),\n maxCrankStalenessSlots: readU64LE(data, base + 400),\n totalOpenInterest: readU128LE(data, base + 408),\n longOi: 0n, // V2 has no long_oi\n shortOi: 0n, // V2 has no short_oi\n cTot: readU128LE(data, base + 424),\n pnlPosTot: readU128LE(data, base + 440),\n liqCursor: readU16LE(data, base + 456),\n gcCursor: readU16LE(data, base + 458),\n lastSweepStartSlot: readU64LE(data, base + 464),\n lastSweepCompleteSlot: readU64LE(data, base + 472),\n crankCursor: readU16LE(data, base + 480),\n sweepStartIdx: readU16LE(data, base + 482),\n lifetimeLiquidations: readU64LE(data, base + 488),\n lifetimeForceCloses: readU64LE(data, base + 496),\n netLpPos: readI128LE(data, base + 504),\n lpSumAbs: readU128LE(data, base + 520),\n lpMaxAbs: readU128LE(data, base + 536),\n lpMaxAbsSweep: readU128LE(data, base + 552),\n emergencyOiMode: false, // V2 has no emergency OI fields\n emergencyStartSlot: 0n,\n lastBreakerSlot: 0n,\n markPriceE6: 0n, // V2 has no mark_price\n numUsedAccounts: canReadNumUsed ? readU16LE(data, base + numUsedOff) : 0,\n nextAccountId: canReadNextId ? readU64LE(data, base + nextAccountIdOff) : 0n,\n };\n }\n\n // V_ADL engine struct (PERC-8270/8271): ENGINE_OFF=624, layout-driven offsets.\n // Must branch here because V_ADL has version===1 same as V1/V1M — differentiate by engineOff.\n // All offsets from SlabLayout descriptor, which is computed by buildLayoutVADL().\n const isVAdl = layout !== null && layout.engineOff === 624 && layout.accountSize === 312;\n if (isVAdl) {\n const l = layout!;\n return {\n vault: readU128LE(data, base + 0),\n insuranceFund: {\n balance: readU128LE(data, base + l.engineInsuranceOff),\n feeRevenue: readU128LE(data, base + l.engineInsuranceOff + 16),\n isolatedBalance: readU128LE(data, base + l.engineInsuranceIsolatedOff),\n isolationBps: readU16LE(data, base + l.engineInsuranceIsolationBpsOff),\n },\n currentSlot: readU64LE(data, base + l.engineCurrentSlotOff),\n fundingIndexQpbE6: readI128LE(data, base + l.engineFundingIndexOff),\n lastFundingSlot: readU64LE(data, base + l.engineLastFundingSlotOff),\n fundingRateBpsPerSlotLast: readI64LE(data, base + l.engineFundingRateBpsOff),\n lastCrankSlot: readU64LE(data, base + l.engineLastCrankSlotOff),\n maxCrankStalenessSlots: readU64LE(data, base + l.engineMaxCrankStalenessOff),\n totalOpenInterest: readU128LE(data, base + l.engineTotalOiOff),\n longOi: l.engineLongOiOff >= 0 ? readU128LE(data, base + l.engineLongOiOff) : 0n,\n shortOi: l.engineShortOiOff >= 0 ? readU128LE(data, base + l.engineShortOiOff) : 0n,\n cTot: readU128LE(data, base + l.engineCTotOff),\n pnlPosTot: readU128LE(data, base + l.enginePnlPosTotOff),\n liqCursor: readU16LE(data, base + l.engineLiqCursorOff),\n gcCursor: readU16LE(data, base + l.engineGcCursorOff),\n lastSweepStartSlot: readU64LE(data, base + l.engineLastSweepStartOff),\n lastSweepCompleteSlot: readU64LE(data, base + l.engineLastSweepCompleteOff),\n crankCursor: readU16LE(data, base + l.engineCrankCursorOff),\n sweepStartIdx: readU16LE(data, base + l.engineSweepStartIdxOff),\n lifetimeLiquidations: readU64LE(data, base + l.engineLifetimeLiquidationsOff),\n lifetimeForceCloses: readU64LE(data, base + l.engineLifetimeForceClosesOff),\n netLpPos: readI128LE(data, base + l.engineNetLpPosOff),\n lpSumAbs: readU128LE(data, base + l.engineLpSumAbsOff),\n lpMaxAbs: readU128LE(data, base + l.engineLpMaxAbsOff),\n lpMaxAbsSweep: readU128LE(data, base + l.engineLpMaxAbsSweepOff),\n emergencyOiMode: l.engineEmergencyOiModeOff >= 0 ? data[base + l.engineEmergencyOiModeOff] !== 0 : false,\n emergencyStartSlot: l.engineEmergencyStartSlotOff >= 0 ? readU64LE(data, base + l.engineEmergencyStartSlotOff) : 0n,\n lastBreakerSlot: l.engineLastBreakerSlotOff >= 0 ? readU64LE(data, base + l.engineLastBreakerSlotOff) : 0n,\n markPriceE6: l.engineMarkPriceOff >= 0 ? readU64LE(data, base + l.engineMarkPriceOff) : 0n,\n numUsedAccounts: canReadNumUsed ? readU16LE(data, base + numUsedOff) : 0,\n nextAccountId: canReadNextId ? readU64LE(data, base + nextAccountIdOff) : 0n,\n };\n }\n\n // V1 engine struct (PERC-1094 corrected): ENGINE_OFF=600 (BPF/SBF, CONFIG_LEN=496)\n // vault(0,16) + insurance(16,56) + params(72,288) + currentSlot(360) + fundingIndex(368,16)\n // + lastFundingSlot(384) + fundingRateBps(392) + markPrice(400) + lastCrankSlot(424)\n // + maxCrankStaleness(432) + totalOI(440,16) + longOi(456,16) + shortOi(472,16)\n // + cTot(488,16) + pnlPosTot(504,16) + liqCursor(520,2) + gcCursor(522,2)\n // + lastSweepStart(528) + lastSweepComplete(536) + crankCursor(544,2) + sweepStartIdx(546,2)\n // + lifetimeLiquidations(552) + lifetimeForceCloses(560)\n // + netLpPos(568,16) + lpSumAbs(584,16) + lpMaxAbs(600,16) + lpMaxAbsSweep(616,16)\n // + emergencyOiMode(632,1+7pad) + emergencyStartSlot(640) + lastBreakerSlot(648) + bitmap(656)\n return {\n vault: readU128LE(data, base + 0),\n insuranceFund: {\n balance: readU128LE(data, base + 16),\n feeRevenue: readU128LE(data, base + 32),\n isolatedBalance: readU128LE(data, base + 48),\n isolationBps: readU16LE(data, base + 64),\n },\n currentSlot: readU64LE(data, base + 360), // PERC-1094: params end at 72+288=360 (was 352)\n fundingIndexQpbE6: readI128LE(data, base + 368),\n lastFundingSlot: readU64LE(data, base + 384),\n fundingRateBpsPerSlotLast: readI64LE(data, base + 392),\n lastCrankSlot: readU64LE(data, base + 424),\n maxCrankStalenessSlots: readU64LE(data, base + 408),\n totalOpenInterest: readU128LE(data, base + 416),\n longOi: readU128LE(data, base + 432),\n shortOi: readU128LE(data, base + 448),\n cTot: readU128LE(data, base + 464),\n pnlPosTot: readU128LE(data, base + 480),\n liqCursor: readU16LE(data, base + 496),\n gcCursor: readU16LE(data, base + 498),\n lastSweepStartSlot: readU64LE(data, base + 504),\n lastSweepCompleteSlot: readU64LE(data, base + 512),\n crankCursor: readU16LE(data, base + 520),\n sweepStartIdx: readU16LE(data, base + 522),\n lifetimeLiquidations: readU64LE(data, base + 528),\n lifetimeForceCloses: readU64LE(data, base + 536),\n netLpPos: readI128LE(data, base + 544),\n lpSumAbs: readU128LE(data, base + 560),\n lpMaxAbs: readU128LE(data, base + 576),\n lpMaxAbsSweep: readU128LE(data, base + 592),\n emergencyOiMode: data[base + 608] !== 0,\n emergencyStartSlot: readU64LE(data, base + 616),\n lastBreakerSlot: readU64LE(data, base + 624),\n markPriceE6: readU64LE(data, base + 400), // PERC-1094: was 392\n numUsedAccounts: canReadNumUsed ? readU16LE(data, base + numUsedOff) : 0,\n nextAccountId: canReadNextId ? readU64LE(data, base + nextAccountIdOff) : 0n,\n };\n}\n\n/** Options for `discoverMarkets`. */\nexport interface DiscoverMarketsOptions {\n /**\n * Run tier queries sequentially with per-tier retry on HTTP 429 instead of\n * firing all in parallel. Reduces RPC rate-limit pressure at the cost of\n * slightly slower discovery (~14 round-trips instead of 1 concurrent batch).\n * Default: false (preserves original parallel behaviour).\n *\n * PERC-1650: keeper uses this flag to avoid 429 storms on its fallback RPC\n * (Helius starter tier). Pass `sequential: true` from CrankService.discover().\n */\n sequential?: boolean;\n /**\n * Delay in ms between sequential tier queries (only used when sequential=true).\n * Default: 200 ms.\n */\n interTierDelayMs?: number;\n /**\n * Per-tier retry backoff delays on 429 (ms). Jitter of up to +25% is applied.\n * Only used when sequential=true. Default: [1_000, 3_000, 9_000, 27_000].\n */\n rateLimitBackoffMs?: number[];\n\n /**\n * In parallel mode (the default), cap how many tier RPC requests are in-flight\n * at once to avoid accidental RPC storms from client code.\n *\n * Default: 6\n */\n maxParallelTiers?: number;\n\n /**\n * Hard cap on how many tier dataSize queries are attempted.\n * Default: all known tiers.\n */\n maxTierQueries?: number;\n}\n\n/** Return true if the error looks like an HTTP 429 / rate-limit response. */\nfunction isRateLimitError(err: unknown): boolean {\n if (!err) return false;\n const msg = err instanceof Error ? err.message : String(err);\n return (\n msg.includes(\"429\") ||\n msg.toLowerCase().includes(\"rate limit\") ||\n msg.toLowerCase().includes(\"too many requests\")\n );\n}\n\n/** Add up to 25% random jitter to avoid thundering-herd on retry. */\nfunction withJitter(delayMs: number): number {\n return delayMs + Math.floor(Math.random() * delayMs * 0.25);\n}\n\n/**\n * Discover all Percolator markets owned by the given program.\n * Uses getProgramAccounts with dataSize filter + dataSlice to download only ~1400 bytes per slab.\n *\n * @param options.sequential - Run tier queries sequentially with 429 retry (PERC-1650).\n */\nexport async function discoverMarkets(\n connection: Connection,\n programId: PublicKey,\n options: DiscoverMarketsOptions = {},\n): Promise<DiscoveredMarket[]> {\n const {\n sequential = false,\n interTierDelayMs = 200,\n rateLimitBackoffMs = [1_000, 3_000, 9_000, 27_000],\n maxParallelTiers = 6,\n } = options;\n\n // Query all known slab sizes in parallel — V0, V1D (deployed devnet), V1D legacy, and V1 (upgraded) tiers.\n // We track the actual dataSize per entry so detectSlabLayout can determine the correct layout,\n // and pass that layout to all parse functions (avoids wrong-version offsets on partial slices).\n // GH#1205: V1D tiers were missing here — V1D slabs fell through to memcmp fallback with wrong\n // dataSize hints → detectSlabLayout returned null → parse failure in discoverMarkets.\n // GH#1237/GH#1238: SLAB_TIERS_V1D_LEGACY (postBitmap=18, e.g. 65,104-byte slabs created before\n // GH#1234) must also be included; omitting them causes legacy on-chain slabs to be missed by\n // dataSize filter queries and fall through to memcmp with wrong maxAccounts hint.\n const ALL_TIERS = [\n ...Object.values(SLAB_TIERS),\n ...Object.values(SLAB_TIERS_V0),\n ...Object.values(SLAB_TIERS_V1D),\n ...Object.values(SLAB_TIERS_V1D_LEGACY),\n ...Object.values(SLAB_TIERS_V2),\n ...Object.values(SLAB_TIERS_V1M),\n ...Object.values(SLAB_TIERS_V_ADL),\n ];\n type RawEntry = { pubkey: PublicKey; account: { data: Buffer | Uint8Array }; maxAccounts: number; dataSize: number };\n let rawAccounts: RawEntry[] = [];\n\n /**\n * Fetch one tier with per-attempt 429 retry (sequential mode only).\n * Returns an array of RawEntry on success, or an empty array after exhausting retries.\n */\n async function fetchTierWithRetry(\n tier: { dataSize: number; maxAccounts: number },\n ): Promise<RawEntry[]> {\n for (let attempt = 0; attempt <= rateLimitBackoffMs.length; attempt++) {\n try {\n const results = await connection.getProgramAccounts(programId, {\n filters: [{ dataSize: tier.dataSize }],\n dataSlice: { offset: 0, length: HEADER_SLICE_LENGTH },\n });\n return results.map(entry => ({ ...entry, maxAccounts: tier.maxAccounts, dataSize: tier.dataSize }));\n } catch (err) {\n if (isRateLimitError(err) && attempt < rateLimitBackoffMs.length) {\n const delay = withJitter(rateLimitBackoffMs[attempt]);\n console.warn(\n `[discoverMarkets] 429 on tier dataSize=${tier.dataSize} attempt=${attempt + 1}, backing off ${delay}ms`,\n );\n await new Promise(r => setTimeout(r, delay));\n continue;\n }\n // Non-429 or exhausted retries\n console.warn(\n `[discoverMarkets] Tier query failed (dataSize=${tier.dataSize}, attempt=${attempt + 1}):`,\n err instanceof Error ? err.message : err,\n );\n return [];\n }\n }\n return [];\n }\n\n const maxTierQueries = options.maxTierQueries ?? ALL_TIERS.length;\n const tiersToQuery = ALL_TIERS.slice(0, maxTierQueries);\n\n // Avoid accidental `0`/negative or NaN causing infinite loops.\n const effectiveMaxParallelTiers = Math.max(1, Number.isFinite(maxParallelTiers) ? maxParallelTiers : 6);\n\n try {\n if (sequential) {\n // PERC-1650: sequential mode — one tier at a time with inter-tier spacing + per-tier 429 retry.\n for (let i = 0; i < tiersToQuery.length; i++) {\n const tier = tiersToQuery[i];\n const entries = await fetchTierWithRetry(tier);\n rawAccounts.push(...entries);\n if (i < tiersToQuery.length - 1) {\n await new Promise(r => setTimeout(r, interTierDelayMs));\n }\n }\n } else {\n // Parallel mode: cap tier concurrency so we don't fire 20+ large\n // getProgramAccounts calls at once from a single client call.\n for (let offset = 0; offset < tiersToQuery.length; offset += effectiveMaxParallelTiers) {\n const chunk = tiersToQuery.slice(offset, offset + effectiveMaxParallelTiers);\n const queries = chunk.map(tier =>\n connection.getProgramAccounts(programId, {\n filters: [{ dataSize: tier.dataSize }],\n dataSlice: { offset: 0, length: HEADER_SLICE_LENGTH },\n }).then(results =>\n results.map(entry => ({\n ...entry,\n maxAccounts: tier.maxAccounts,\n dataSize: tier.dataSize,\n })),\n ),\n );\n\n const results = await Promise.allSettled(queries);\n for (const result of results) {\n if (result.status === \"fulfilled\") {\n for (const entry of result.value) {\n rawAccounts.push(entry as RawEntry);\n }\n } else {\n console.warn(\n \"[discoverMarkets] Tier query rejected:\",\n result.reason instanceof Error ? result.reason.message : result.reason,\n );\n }\n }\n }\n }\n\n // NOTE: hadRejection guard removed — dataSize filters silently return 0 when on-chain\n // account size changed; RPC returns no error, so we must fallback on empty results too.\n if (rawAccounts.length === 0) {\n console.warn(\"[discoverMarkets] dataSize filters returned 0 markets, falling back to memcmp\");\n const fallback = await connection.getProgramAccounts(programId, {\n filters: [\n {\n memcmp: {\n offset: 0,\n bytes: \"F6P2QNqpQV5\", // base58 of TALOCREP (u64 LE magic)\n },\n },\n ],\n dataSlice: { offset: 0, length: HEADER_SLICE_LENGTH },\n });\n // Unknown actual size — use large V0 as safe default (maxAccounts=4096)\n rawAccounts = [...fallback].map(e => ({ ...e, maxAccounts: 4096, dataSize: SLAB_TIERS.large.dataSize })) as RawEntry[];\n }\n } catch (err) {\n console.warn(\n \"[discoverMarkets] dataSize filters failed, falling back to memcmp:\",\n err instanceof Error ? err.message : err,\n );\n const fallback = await connection.getProgramAccounts(programId, {\n filters: [\n {\n memcmp: {\n offset: 0,\n bytes: \"F6P2QNqpQV5\", // base58 of TALOCREP (u64 LE magic)\n },\n },\n ],\n dataSlice: { offset: 0, length: HEADER_SLICE_LENGTH },\n });\n rawAccounts = [...fallback].map(e => ({ ...e, maxAccounts: 4096, dataSize: SLAB_TIERS.large.dataSize })) as RawEntry[];\n }\n const accounts = rawAccounts;\n\n const markets: DiscoveredMarket[] = [];\n // GH#1115: deduplicate raw accounts by pubkey — the same slab can appear in multiple\n // tier queries if both V0 and V1 sizes match or if the RPC returns duplicate entries.\n const seenPubkeys = new Set<string>();\n\n for (const { pubkey, account, maxAccounts, dataSize } of accounts) {\n const pkStr = pubkey.toBase58();\n if (seenPubkeys.has(pkStr)) continue;\n seenPubkeys.add(pkStr);\n const data = new Uint8Array(account.data);\n\n let valid = true;\n for (let i = 0; i < MAGIC_BYTES.length; i++) {\n if (data[i] !== MAGIC_BYTES[i]) {\n valid = false;\n break;\n }\n }\n if (!valid) continue;\n\n // Detect layout from actual slab size — not slice length — so parse functions\n // get correct V0/V1 offsets even when working on the partial HEADER_SLICE_LENGTH slice.\n // Pass the data buffer so V2 slabs (same size as V1D) can be disambiguated via version field.\n const layout = detectSlabLayout(dataSize, data);\n\n if (!layout) {\n console.warn(\n `[discoverMarkets] Skipping account ${pkStr}: unrecognized layout for dataSize=${dataSize}`,\n );\n continue;\n }\n\n try {\n const header = parseHeader(data);\n const config = parseConfig(data, layout);\n const engine = parseEngineLight(data, layout, maxAccounts);\n const params = parseParams(data, layout);\n\n markets.push({ slabAddress: pubkey, programId, header, config, engine, params });\n } catch (err) {\n console.warn(\n `[discoverMarkets] Failed to parse account ${pubkey.toBase58()}:`,\n err instanceof Error ? err.message : err,\n );\n }\n }\n\n return markets;\n}\n","import { PublicKey } from \"@solana/web3.js\";\nimport {\n PUMPSWAP_PROGRAM_ID,\n RAYDIUM_CLMM_PROGRAM_ID,\n METEORA_DLMM_PROGRAM_ID,\n} from \"./pda.js\";\n\nexport type DexType = \"pumpswap\" | \"raydium-clmm\" | \"meteora-dlmm\";\n\nexport interface DexPoolInfo {\n dexType: DexType;\n poolAddress: PublicKey;\n baseMint: PublicKey;\n quoteMint: PublicKey;\n baseVault?: PublicKey; // PumpSwap only\n quoteVault?: PublicKey; // PumpSwap only\n}\n\n/**\n * Detect DEX type from the program that owns the pool account.\n *\n * @param ownerProgramId - The program ID that owns the pool account\n * @returns The detected DEX type, or `null` if the owner is not a supported DEX program\n *\n * Supported DEX programs:\n * - PumpSwap (constant-product AMM)\n * - Raydium CLMM (concentrated liquidity)\n * - Meteora DLMM (discretized liquidity)\n */\nexport function detectDexType(ownerProgramId: PublicKey): DexType | null {\n if (ownerProgramId.equals(PUMPSWAP_PROGRAM_ID)) return \"pumpswap\";\n if (ownerProgramId.equals(RAYDIUM_CLMM_PROGRAM_ID)) return \"raydium-clmm\";\n if (ownerProgramId.equals(METEORA_DLMM_PROGRAM_ID)) return \"meteora-dlmm\";\n return null;\n}\n\n/**\n * Parse a DEX pool account into a {@link DexPoolInfo} struct.\n *\n * @param dexType - The type of DEX (pumpswap, raydium-clmm, or meteora-dlmm)\n * @param poolAddress - The on-chain address of the pool account\n * @param data - Raw account data bytes\n * @returns Parsed pool info including mints and (for PumpSwap) vault addresses\n * @throws Error if data is too short for the given DEX type\n */\nexport function parseDexPool(\n dexType: DexType,\n poolAddress: PublicKey,\n data: Uint8Array,\n): DexPoolInfo {\n switch (dexType) {\n case \"pumpswap\":\n return parsePumpSwapPool(poolAddress, data);\n case \"raydium-clmm\":\n return parseRaydiumClmmPool(poolAddress, data);\n case \"meteora-dlmm\":\n return parseMeteoraPool(poolAddress, data);\n }\n}\n\n/**\n * Compute the spot price from a DEX pool in e6 format (i.e., 1.0 = 1_000_000).\n *\n * **SECURITY NOTE:** DEX spot prices have no staleness or confidence checks and are\n * vulnerable to flash-loan manipulation within a single transaction. For high-value\n * markets, prefer Pyth or Chainlink oracles.\n *\n * @param dexType - The type of DEX\n * @param data - Raw pool account data\n * @param vaultData - For PumpSwap only: base and quote vault account data\n * @returns Price in e6 format (quote per base token)\n * @throws Error if data is too short or computation fails\n */\nexport function computeDexSpotPriceE6(\n dexType: DexType,\n data: Uint8Array,\n vaultData?: { base: Uint8Array; quote: Uint8Array },\n): bigint {\n switch (dexType) {\n case \"pumpswap\":\n if (!vaultData) throw new Error(\"PumpSwap requires vaultData (base and quote vault accounts)\");\n return computePumpSwapPriceE6(data, vaultData);\n case \"raydium-clmm\":\n return computeRaydiumClmmPriceE6(data);\n case \"meteora-dlmm\":\n return computeMeteoraDlmmPriceE6(data);\n }\n}\n\n// ============================================================================\n// PumpSwap\n// ============================================================================\n\nconst PUMPSWAP_MIN_LEN = 195;\n\n/**\n * Parse a PumpSwap constant-product AMM pool account.\n * @internal\n */\nfunction parsePumpSwapPool(poolAddress: PublicKey, data: Uint8Array): DexPoolInfo {\n if (data.length < PUMPSWAP_MIN_LEN) {\n throw new Error(`PumpSwap pool data too short: ${data.length} < ${PUMPSWAP_MIN_LEN}`);\n }\n return {\n dexType: \"pumpswap\",\n poolAddress,\n baseMint: new PublicKey(data.slice(35, 67)),\n quoteMint: new PublicKey(data.slice(67, 99)),\n baseVault: new PublicKey(data.slice(131, 163)),\n quoteVault: new PublicKey(data.slice(163, 195)),\n };\n}\n\nconst SPL_TOKEN_AMOUNT_MIN_LEN = 72;\n\n/**\n * Compute PumpSwap price: quote_amount * 1e6 / base_amount.\n * @internal\n */\nfunction computePumpSwapPriceE6(\n _poolData: Uint8Array,\n vaultData: { base: Uint8Array; quote: Uint8Array },\n): bigint {\n if (vaultData.base.length < SPL_TOKEN_AMOUNT_MIN_LEN) {\n throw new Error(`PumpSwap base vault data too short: ${vaultData.base.length} < ${SPL_TOKEN_AMOUNT_MIN_LEN}`);\n }\n if (vaultData.quote.length < SPL_TOKEN_AMOUNT_MIN_LEN) {\n throw new Error(`PumpSwap quote vault data too short: ${vaultData.quote.length} < ${SPL_TOKEN_AMOUNT_MIN_LEN}`);\n }\n\n const baseDv = new DataView(vaultData.base.buffer, vaultData.base.byteOffset, vaultData.base.byteLength);\n const quoteDv = new DataView(vaultData.quote.buffer, vaultData.quote.byteOffset, vaultData.quote.byteLength);\n\n const baseAmount = readU64LE(baseDv, 64);\n const quoteAmount = readU64LE(quoteDv, 64);\n\n if (baseAmount === 0n) return 0n;\n return (quoteAmount * 1_000_000n) / baseAmount;\n}\n\n// ============================================================================\n// Raydium CLMM\n// ============================================================================\n\nconst RAYDIUM_CLMM_MIN_LEN = 269; // need at least through sqrt_price_x64 (253 + 16)\n\n/**\n * Parse a Raydium CLMM (concentrated liquidity) pool account.\n * @internal\n */\nfunction parseRaydiumClmmPool(poolAddress: PublicKey, data: Uint8Array): DexPoolInfo {\n if (data.length < RAYDIUM_CLMM_MIN_LEN) {\n throw new Error(`Raydium CLMM pool data too short: ${data.length} < ${RAYDIUM_CLMM_MIN_LEN}`);\n }\n return {\n dexType: \"raydium-clmm\",\n poolAddress,\n baseMint: new PublicKey(data.slice(73, 105)),\n quoteMint: new PublicKey(data.slice(105, 137)),\n };\n}\n\n/**\n * Compute Raydium CLMM spot price from sqrt_price_x64 (Q64.64 fixed-point).\n *\n * Formula: `price_e6 = (sqrt^2 / 2^128) * 10^(6 + decimals0 - decimals1)`\n *\n * Uses a precision-preserving approach: scales sqrt by 1e6 before shifting,\n * preventing zero results for micro-priced tokens (memecoins where sqrt < 2^64).\n *\n * @internal\n */\nconst MAX_TOKEN_DECIMALS = 24;\n\nfunction computeRaydiumClmmPriceE6(data: Uint8Array): bigint {\n if (data.length < RAYDIUM_CLMM_MIN_LEN) {\n throw new Error(`Raydium CLMM data too short: ${data.length} < ${RAYDIUM_CLMM_MIN_LEN}`);\n }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n const decimals0 = data[233];\n const decimals1 = data[234];\n\n if (decimals0 > MAX_TOKEN_DECIMALS || decimals1 > MAX_TOKEN_DECIMALS) {\n throw new Error(\n `Raydium CLMM: decimals out of range (${decimals0}, ${decimals1}); max ${MAX_TOKEN_DECIMALS}`,\n );\n }\n\n const sqrtPriceX64 = readU128LE(dv, 253);\n\n if (sqrtPriceX64 === 0n) return 0n;\n\n const scaledSqrt = sqrtPriceX64 * 1_000_000n;\n const term = scaledSqrt >> 64n;\n const priceE6Raw = (term * sqrtPriceX64) >> 64n;\n\n const decimalDiff = 6 + decimals0 - decimals1;\n const adjustedDiff = decimalDiff - 6;\n\n if (adjustedDiff >= 0) {\n const scale = 10n ** BigInt(adjustedDiff);\n return priceE6Raw * scale;\n } else {\n const scale = 10n ** BigInt(-adjustedDiff);\n return priceE6Raw / scale;\n }\n}\n\n// ============================================================================\n// Meteora DLMM\n// ============================================================================\n\nconst METEORA_DLMM_MIN_LEN = 145;\n\n/**\n * Parse a Meteora DLMM (discretized liquidity) pool account.\n * @internal\n */\nfunction parseMeteoraPool(poolAddress: PublicKey, data: Uint8Array): DexPoolInfo {\n if (data.length < METEORA_DLMM_MIN_LEN) {\n throw new Error(`Meteora DLMM pool data too short: ${data.length} < ${METEORA_DLMM_MIN_LEN}`);\n }\n return {\n dexType: \"meteora-dlmm\",\n poolAddress,\n baseMint: new PublicKey(data.slice(81, 113)),\n quoteMint: new PublicKey(data.slice(113, 145)),\n };\n}\n\n/**\n * Compute Meteora DLMM spot price from active_id and bin_step.\n *\n * Formula: `price = (1 + bin_step/10000) ^ active_id`\n *\n * Uses binary exponentiation with 1e18 fixed-point precision, then converts to e6.\n * For negative active_id, computes the inverse.\n *\n * @internal\n */\nconst MAX_BIN_STEP = 10_000;\nconst MAX_ACTIVE_ID_ABS = 500_000;\n\nfunction computeMeteoraDlmmPriceE6(data: Uint8Array): bigint {\n if (data.length < METEORA_DLMM_MIN_LEN) {\n throw new Error(`Meteora DLMM data too short: ${data.length} < ${METEORA_DLMM_MIN_LEN}`);\n }\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n const binStep = dv.getUint16(73, true);\n const activeId = dv.getInt32(76, true);\n\n if (binStep === 0) return 0n;\n if (binStep > MAX_BIN_STEP) {\n throw new Error(`Meteora DLMM: binStep ${binStep} exceeds max ${MAX_BIN_STEP}`);\n }\n if (Math.abs(activeId) > MAX_ACTIVE_ID_ABS) {\n throw new Error(\n `Meteora DLMM: |activeId| ${Math.abs(activeId)} exceeds max ${MAX_ACTIVE_ID_ABS}`,\n );\n }\n\n const MAX_ABS_BIN_ID = 500_000;\n if (activeId > MAX_ABS_BIN_ID || activeId < -MAX_ABS_BIN_ID) {\n throw new Error(\n `Meteora DLMM: activeId ${activeId} exceeds safe range (±${MAX_ABS_BIN_ID})`,\n );\n }\n\n const SCALE = 1_000_000_000_000_000_000n; // 1e18\n const base = SCALE + (BigInt(binStep) * SCALE) / 10_000n;\n\n const isNeg = activeId < 0;\n let exp = isNeg ? BigInt(-activeId) : BigInt(activeId);\n\n let result = SCALE;\n let b = base;\n\n while (exp > 0n) {\n if (exp & 1n) {\n result = (result * b) / SCALE;\n }\n exp >>= 1n;\n if (exp > 0n) {\n b = (b * b) / SCALE;\n }\n }\n\n if (isNeg) {\n if (result === 0n) return 0n;\n return (SCALE * 1_000_000n) / result;\n } else {\n return result / 1_000_000_000_000n; // 1e18 → 1e6\n }\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/** Read a little-endian u64 from a DataView. */\nfunction readU64LE(dv: DataView, offset: number): bigint {\n const lo = BigInt(dv.getUint32(offset, true));\n const hi = BigInt(dv.getUint32(offset + 4, true));\n return lo | (hi << 32n);\n}\n\n/** Read a little-endian u128 from a DataView. */\nfunction readU128LE(dv: DataView, offset: number): bigint {\n const lo = readU64LE(dv, offset);\n const hi = readU64LE(dv, offset + 8);\n return lo | (hi << 64n);\n}\n","/**\n * Oracle account parsing utilities.\n *\n * Chainlink aggregator layout on Solana (from Toly's percolator-cli):\n * offset 138: decimals (u8)\n * offset 216: latest answer (i64 LE)\n *\n * Minimum account size: 224 bytes (offset 216 + 8 bytes for i64).\n *\n * These utilities validate oracle data BEFORE parsing to prevent silent\n * propagation of stale or malformed Chainlink data as price.\n */\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Minimum buffer size to read Chainlink price data */\nconst CHAINLINK_MIN_SIZE = 224; // 216 + 8\n\n/** Maximum reasonable decimals for a price feed */\nconst MAX_DECIMALS = 18;\n\n/** Offset of decimals field in Chainlink aggregator account */\nconst CHAINLINK_DECIMALS_OFFSET = 138;\n\n/** Offset of latest answer in Chainlink aggregator account */\nconst CHAINLINK_ANSWER_OFFSET = 216;\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface OraclePrice {\n price: bigint;\n decimals: number;\n}\n\n// ---------------------------------------------------------------------------\n// Browser-compatible read helpers using DataView\n// ---------------------------------------------------------------------------\n\nfunction readU8(data: Uint8Array, off: number): number {\n return data[off];\n}\n\nfunction readBigInt64LE(data: Uint8Array, off: number): bigint {\n return new DataView(data.buffer, data.byteOffset, data.byteLength).getBigInt64(off, true);\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Parse price data from a Chainlink aggregator account buffer.\n *\n * Validates:\n * - Buffer is large enough to contain the required fields (≥ 224 bytes)\n * - Decimals are in a reasonable range (0-18)\n * - Price is positive (non-zero)\n *\n * @param data - Raw account data from Chainlink aggregator\n * @returns Parsed oracle price with decimals\n * @throws if the buffer is invalid or contains unreasonable data\n */\nexport function parseChainlinkPrice(data: Uint8Array): OraclePrice {\n if (data.length < CHAINLINK_MIN_SIZE) {\n throw new Error(\n `Oracle account data too small: ${data.length} bytes (need at least ${CHAINLINK_MIN_SIZE})`\n );\n }\n\n const decimals = readU8(data, CHAINLINK_DECIMALS_OFFSET);\n if (decimals > MAX_DECIMALS) {\n throw new Error(\n `Oracle decimals out of range: ${decimals} (max ${MAX_DECIMALS})`\n );\n }\n\n const price = readBigInt64LE(data, CHAINLINK_ANSWER_OFFSET);\n if (price <= 0n) {\n throw new Error(\n `Oracle price is non-positive: ${price}`\n );\n }\n\n return { price, decimals };\n}\n\n/**\n * Validate that a buffer looks like a valid Chainlink aggregator account.\n * Returns true if the buffer passes all validation checks, false otherwise.\n * Use this for non-throwing validation.\n */\nexport function isValidChainlinkOracle(data: Uint8Array): boolean {\n try {\n parseChainlinkPrice(data);\n return true;\n } catch {\n return false;\n }\n}\n\n// Re-export constants for consumers\nexport { CHAINLINK_MIN_SIZE, CHAINLINK_DECIMALS_OFFSET, CHAINLINK_ANSWER_OFFSET, MAX_DECIMALS };\n","import { Connection, PublicKey } from \"@solana/web3.js\";\nimport { TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\n\n/**\n * Token2022 (Token Extensions) program ID.\n */\nexport const TOKEN_2022_PROGRAM_ID = new PublicKey(\n \"TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb\",\n);\n\n/**\n * Detect which token program owns a given mint account.\n * Returns the owner program ID (TOKEN_PROGRAM_ID or TOKEN_2022_PROGRAM_ID).\n * Throws if the mint account doesn't exist.\n */\nexport async function detectTokenProgram(\n connection: Connection,\n mint: PublicKey,\n): Promise<PublicKey> {\n const info = await connection.getAccountInfo(mint);\n if (!info) throw new Error(`Mint account not found: ${mint.toBase58()}`);\n return info.owner;\n}\n\n/**\n * Check if a given token program ID is Token2022.\n */\nexport function isToken2022(tokenProgramId: PublicKey): boolean {\n return tokenProgramId.equals(TOKEN_2022_PROGRAM_ID);\n}\n\n/**\n * Check if a given token program ID is the standard SPL Token program.\n */\nexport function isStandardToken(tokenProgramId: PublicKey): boolean {\n return tokenProgramId.equals(TOKEN_PROGRAM_ID);\n}\n","/**\n * @module stake\n * Percolator Insurance LP Staking program — instruction encoders, PDA derivation, and account specs.\n *\n * Program: percolator-stake (dcccrypto/percolator-stake)\n * Deployed devnet: 6aJb1F9CDCVWCNYFwj8aQsVb696YnW6J1FznteHq4Q6k\n * Deployed mainnet: (pending deployment — DevOps must set STAKE_PROGRAM_ID env var or deploy and update STAKE_PROGRAM_IDS.mainnet)\n */\n\nimport { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY, SYSVAR_CLOCK_PUBKEY } from '@solana/web3.js';\nimport { TOKEN_PROGRAM_ID } from '@solana/spl-token';\nimport { safeEnv } from '../config/program-ids.js';\nimport { concatBytes } from '../abi/encode.js';// ═══════════════════════════════════════════════════════════════\n// Program ID — network-conditional (mirrors program-ids.ts pattern)\n// ═══════════════════════════════════════════════════════════════\n\n/** Known stake program addresses per network. Mainnet is empty until deployed. */\nexport const STAKE_PROGRAM_IDS = {\n devnet: '6aJb1F9CDCVWCNYFwj8aQsVb696YnW6J1FznteHq4Q6k',\n mainnet: '', // TODO: populate once DevOps deploys percolator-stake to mainnet\n} as const;\n\n/**\n * Resolve the stake program ID for the given network.\n *\n * Priority:\n * 1. STAKE_PROGRAM_ID env var (explicit override — DevOps sets this for mainnet until constant is filled)\n * 2. Network-specific constant from STAKE_PROGRAM_IDS\n *\n * Throws a clear error on mainnet when no address is available so callers\n * surface the gap instead of silently hitting the devnet program.\n */\nexport function getStakeProgramId(network?: 'devnet' | 'mainnet'): PublicKey {\n const override = safeEnv('STAKE_PROGRAM_ID');\n if (override) {\n console.warn(\n `[percolator-sdk] STAKE_PROGRAM_ID env override active: ${override} — ensure this points to a trusted program`,\n );\n return new PublicKey(override);\n }\n\n const detectedNetwork =\n network ??\n (() => {\n const n = safeEnv('NEXT_PUBLIC_DEFAULT_NETWORK')?.toLowerCase() ??\n safeEnv('NETWORK')?.toLowerCase() ?? '';\n return n === 'mainnet' || n === 'mainnet-beta' ? 'mainnet' : 'devnet';\n })();\n\n const id = STAKE_PROGRAM_IDS[detectedNetwork];\n if (!id) {\n throw new Error(\n `Stake program not deployed on ${detectedNetwork}. ` +\n `Set STAKE_PROGRAM_ID env var or wait for DevOps to deploy and update STAKE_PROGRAM_IDS.mainnet.`,\n );\n }\n return new PublicKey(id);\n}\n\n/**\n * Default export — resolves for the current runtime network.\n * Use getStakeProgramId() with an explicit network argument where possible.\n *\n * @deprecated Direct use of STAKE_PROGRAM_ID is being phased out in favour of\n * getStakeProgramId() so mainnet callers get a clear error rather than silently\n * resolving to the devnet address.\n */\nexport const STAKE_PROGRAM_ID = new PublicKey(STAKE_PROGRAM_IDS.devnet);\n\n// ═══════════════════════════════════════════════════════════════\n// Instruction Tags (match src/instruction.rs)\n// ═══════════════════════════════════════════════════════════════\n\nexport const STAKE_IX = {\n InitPool: 0,\n Deposit: 1,\n Withdraw: 2,\n FlushToInsurance: 3,\n UpdateConfig: 4,\n TransferAdmin: 5,\n AdminSetOracleAuthority: 6,\n AdminSetRiskThreshold: 7,\n AdminSetMaintenanceFee: 8,\n AdminResolveMarket: 9,\n AdminWithdrawInsurance: 10,\n AdminSetInsurancePolicy: 11,\n /** PERC-272: Accrue trading fees to LP vault */\n AccrueFees: 12,\n /** PERC-272: Init pool in trading LP mode */\n InitTradingPool: 13,\n /** PERC-313: Set HWM config (enable + floor bps) */\n AdminSetHwmConfig: 14,\n /** PERC-303: Enable/configure senior-junior LP tranches */\n AdminSetTrancheConfig: 15,\n /** PERC-303: Deposit into junior (first-loss) tranche */\n DepositJunior: 16,\n} as const;\n\n// ═══════════════════════════════════════════════════════════════\n// PDA Derivation\n// ═══════════════════════════════════════════════════════════════\n\nconst TEXT = new TextEncoder();\n\n/** Derive the stake pool PDA for a given slab (market). */\nexport function deriveStakePool(slab: PublicKey, programId?: PublicKey) {\n return PublicKey.findProgramAddressSync(\n [TEXT.encode('stake_pool'), slab.toBytes()], programId ?? getStakeProgramId(), );\n}\n\n/** Derive the vault authority PDA (signs CPI, owns LP mint + vault). */\nexport function deriveStakeVaultAuth(pool: PublicKey, programId?: PublicKey) {\n return PublicKey.findProgramAddressSync(\n [TEXT.encode('vault_auth'), pool.toBytes()], programId ?? getStakeProgramId(), );\n}\n\n/** Derive the per-user deposit PDA (tracks cooldown, deposit time). */\nexport function deriveDepositPda(pool: PublicKey, user: PublicKey, programId?: PublicKey) {\n return PublicKey.findProgramAddressSync(\n [TEXT.encode('deposit'), pool.toBytes(), user.toBytes()], programId ?? getStakeProgramId(), );\n}\n\n// ═══════════════════════════════════════════════════════════════\n// Browser-safe binary helpers (DataView, no Node.js Buffer dependency)// ═══════════════════════════════════════════════════════════════\n\n/** Read a u64 little-endian from a Uint8Array at the given offset. */\nfunction readU64LE(data: Uint8Array, off: number): bigint {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n return view.getBigUint64(off, /* littleEndian= */ true);\n}\n\n/** Read a u16 little-endian from a Uint8Array at the given offset. */\nfunction readU16LE(data: Uint8Array, off: number): number {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n return view.getUint16(off, /* littleEndian= */ true);\n}\n\n// ═══════════════════════════════════════════════════════════════\n// Instruction Encoders\n// ═══════════════════════════════════════════════════════════════\n\nfunction u64Le(v: bigint | number): Uint8Array {\n const big = BigInt(v);\n if (big < 0n) throw new Error(`u64Le: value must be non-negative, got ${big}`);\n if (big > 0xFFFF_FFFF_FFFF_FFFFn) throw new Error(`u64Le: value exceeds u64 max`);\n const arr = new Uint8Array(8);\n new DataView(arr.buffer).setBigUint64(0, big, true); return arr;\n}\n\nfunction u128Le(v: bigint | number): Uint8Array {\n const big = BigInt(v);\n if (big < 0n) throw new Error(`u128Le: value must be non-negative, got ${big}`);\n if (big > (1n << 128n) - 1n) throw new Error(`u128Le: value exceeds u128 max`);\n const arr = new Uint8Array(16);\n const view = new DataView(arr.buffer); view.setBigUint64(0, big & 0xFFFFFFFFFFFFFFFFn, true);\n view.setBigUint64(8, big >> 64n, true);\n return arr;\n}\n\nfunction u16Le(v: number): Uint8Array {\n if (v < 0 || v > 0xFFFF) throw new Error(`u16Le: value out of u16 range (0..65535), got ${v}`); const arr = new Uint8Array(2); new DataView(arr.buffer).setUint16(0, v, true);\n return arr;\n}\n\n/** Tag 0: InitPool — create stake pool for a slab. */\nexport function encodeStakeInitPool(cooldownSlots: bigint | number, depositCap: bigint | number): Uint8Array {\n return concatBytes(\n new Uint8Array([STAKE_IX.InitPool]),\n u64Le(cooldownSlots),\n u64Le(depositCap),\n );\n}\n\n/** Tag 1: Deposit — deposit collateral, receive LP tokens. */\nexport function encodeStakeDeposit(amount: bigint | number): Uint8Array {\n return concatBytes(new Uint8Array([STAKE_IX.Deposit]), u64Le(amount));\n}\n\n/** Tag 2: Withdraw — burn LP tokens, receive collateral (subject to cooldown). */\nexport function encodeStakeWithdraw(lpAmount: bigint | number): Uint8Array {\n return concatBytes(new Uint8Array([STAKE_IX.Withdraw]), u64Le(lpAmount));\n}\n\n/** Tag 3: FlushToInsurance — move collateral from stake vault to wrapper insurance. */\nexport function encodeStakeFlushToInsurance(amount: bigint | number): Uint8Array {\n return concatBytes(new Uint8Array([STAKE_IX.FlushToInsurance]), u64Le(amount));\n}\n\n/** Tag 4: UpdateConfig — update cooldown and/or deposit cap. */\nexport function encodeStakeUpdateConfig(\n newCooldownSlots?: bigint | number,\n newDepositCap?: bigint | number,\n): Uint8Array {\n return concatBytes(\n new Uint8Array([STAKE_IX.UpdateConfig]),\n new Uint8Array([newCooldownSlots != null ? 1 : 0]),\n u64Le(newCooldownSlots ?? 0n),\n new Uint8Array([newDepositCap != null ? 1 : 0]),\n u64Le(newDepositCap ?? 0n),\n );\n}\n\n/** Tag 5: TransferAdmin — transfer wrapper admin to pool PDA. */\nexport function encodeStakeTransferAdmin(): Uint8Array {\n return new Uint8Array([STAKE_IX.TransferAdmin]);\n}\n\n/** Tag 6: AdminSetOracleAuthority — forward to wrapper via CPI. */\nexport function encodeStakeAdminSetOracleAuthority(newAuthority: PublicKey): Uint8Array {\n return concatBytes(\n new Uint8Array([STAKE_IX.AdminSetOracleAuthority]),\n newAuthority.toBytes(),\n );\n}\n\n/** Tag 7: AdminSetRiskThreshold — forward to wrapper via CPI. */\nexport function encodeStakeAdminSetRiskThreshold(newThreshold: bigint | number): Uint8Array {\n return concatBytes(\n new Uint8Array([STAKE_IX.AdminSetRiskThreshold]),\n u128Le(newThreshold),\n );\n}\n\n/** Tag 8: AdminSetMaintenanceFee — forward to wrapper via CPI. */\nexport function encodeStakeAdminSetMaintenanceFee(newFee: bigint | number): Uint8Array {\n return concatBytes(\n new Uint8Array([STAKE_IX.AdminSetMaintenanceFee]),\n u128Le(newFee),\n );\n}\n\n/** Tag 9: AdminResolveMarket — forward to wrapper via CPI. */\nexport function encodeStakeAdminResolveMarket(): Uint8Array {\n return new Uint8Array([STAKE_IX.AdminResolveMarket]);\n}\n\n/** Tag 10: AdminWithdrawInsurance — withdraw insurance after market resolution. */\nexport function encodeStakeAdminWithdrawInsurance(amount: bigint | number): Uint8Array {\n return concatBytes(\n new Uint8Array([STAKE_IX.AdminWithdrawInsurance]),\n u64Le(amount),\n );\n}\n\n/** Tag 12: AccrueFees — permissionless: accrue trading fees to LP vault. */\nexport function encodeStakeAccrueFees(): Uint8Array {\n return new Uint8Array([STAKE_IX.AccrueFees]);\n}\n\n/** Tag 13: InitTradingPool — create pool in trading LP mode (pool_mode = 1). */\nexport function encodeStakeInitTradingPool(cooldownSlots: bigint | number, depositCap: bigint | number): Uint8Array {\n return concatBytes(\n new Uint8Array([STAKE_IX.InitTradingPool]),\n u64Le(cooldownSlots),\n u64Le(depositCap),\n );\n}\n\n/** Tag 14 (PERC-313): AdminSetHwmConfig — enable HWM protection and set floor BPS. */\nexport function encodeStakeAdminSetHwmConfig(\n enabled: boolean,\n hwmFloorBps: number,\n): Uint8Array {\n return concatBytes(\n new Uint8Array([STAKE_IX.AdminSetHwmConfig]),\n new Uint8Array([enabled ? 1 : 0]),\n u16Le(hwmFloorBps),\n );\n}\n\n/** Tag 15 (PERC-303): AdminSetTrancheConfig — enable senior/junior LP tranches. */\nexport function encodeStakeAdminSetTrancheConfig(juniorFeeMultBps: number): Uint8Array {\n return concatBytes(\n new Uint8Array([STAKE_IX.AdminSetTrancheConfig]),\n u16Le(juniorFeeMultBps),\n );\n}\n\n/** Tag 16 (PERC-303): DepositJunior — deposit into first-loss junior tranche. */\nexport function encodeStakeDepositJunior(amount: bigint | number): Uint8Array {\n return concatBytes(new Uint8Array([STAKE_IX.DepositJunior]), u64Le(amount));\n}\n\n/** Tag 11: AdminSetInsurancePolicy — set withdrawal policy on wrapper. */\nexport function encodeStakeAdminSetInsurancePolicy(\n authority: PublicKey,\n minWithdrawBase: bigint | number,\n maxWithdrawBps: number,\n cooldownSlots: bigint | number,\n): Uint8Array {\n return concatBytes(\n new Uint8Array([STAKE_IX.AdminSetInsurancePolicy]),\n authority.toBytes(),\n u64Le(minWithdrawBase),\n u16Le(maxWithdrawBps),\n u64Le(cooldownSlots),\n );\n}\n\n// ═══════════════════════════════════════════════════════════════\n// On-Chain State Layout — StakePool decoded fields\n// ═══════════════════════════════════════════════════════════════\n\n/**\n * Decoded StakePool state (352 bytes on-chain).\n * Includes PERC-272 (fee yield), PERC-313 (HWM), and PERC-303 (tranches).\n */\nexport interface StakePoolState {\n isInitialized: boolean;\n bump: number;\n vaultAuthorityBump: number;\n adminTransferred: boolean;\n\n slab: PublicKey;\n admin: PublicKey;\n collateralMint: PublicKey;\n lpMint: PublicKey;\n vault: PublicKey;\n\n totalDeposited: bigint;\n totalLpSupply: bigint;\n cooldownSlots: bigint;\n depositCap: bigint;\n totalFlushed: bigint;\n totalReturned: bigint;\n totalWithdrawn: bigint;\n\n percolatorProgram: PublicKey;\n\n // PERC-272: Fee yield fields\n totalFeesEarned: bigint;\n lastFeeAccrualSlot: bigint;\n lastVaultSnapshot: bigint;\n poolMode: number;\n\n // _reserved layout (64 bytes):\n // [0..8] discriminator\n // [8] version\n // [9..32] PERC-313 HWM\n // [32..51] PERC-303 tranches\n // [51..64] free\n\n // PERC-313: HWM fields (from _reserved[9..32])\n hwmEnabled: boolean;\n epochHighWaterTvl: bigint;\n hwmFloorBps: number;\n\n // PERC-303: Tranche fields (from _reserved[32..51])\n trancheEnabled: boolean;\n juniorBalance: bigint;\n juniorTotalLp: bigint;\n juniorFeeMultBps: number;\n}\n\n/** Size of StakePool on-chain (bytes). */\nexport const STAKE_POOL_SIZE = 352;\n\n/**\n * Decode a StakePool account from raw data buffer. * Uses DataView for all u64/u16 reads — browser-safe.\n */\nexport function decodeStakePool(data: Uint8Array): StakePoolState {\n if (data.length < STAKE_POOL_SIZE) {\n throw new Error(`StakePool data too short: ${data.length} < ${STAKE_POOL_SIZE}`);\n }\n const bytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength); let off = 0;\n const isInitialized = bytes[off] === 1; off += 1;\n const bump = bytes[off]; off += 1;\n const vaultAuthorityBump = bytes[off]; off += 1;\n const adminTransferred = bytes[off] === 1; off += 1;\n off += 4; // _padding\n\n const slab = new PublicKey(bytes.subarray(off, off + 32)); off += 32;\n const admin = new PublicKey(bytes.subarray(off, off + 32)); off += 32;\n const collateralMint = new PublicKey(bytes.subarray(off, off + 32)); off += 32;\n const lpMint = new PublicKey(bytes.subarray(off, off + 32)); off += 32;\n const vault = new PublicKey(bytes.subarray(off, off + 32)); off += 32;\n\n const totalDeposited = readU64LE(bytes, off); off += 8;\n const totalLpSupply = readU64LE(bytes, off); off += 8;\n const cooldownSlots = readU64LE(bytes, off); off += 8;\n const depositCap = readU64LE(bytes, off); off += 8;\n const totalFlushed = readU64LE(bytes, off); off += 8;\n const totalReturned = readU64LE(bytes, off); off += 8;\n const totalWithdrawn = readU64LE(bytes, off); off += 8;\n\n const percolatorProgram = new PublicKey(bytes.subarray(off, off + 32)); off += 32;\n\n // PERC-272 fields\n const totalFeesEarned = readU64LE(bytes, off); off += 8;\n const lastFeeAccrualSlot = readU64LE(bytes, off); off += 8;\n const lastVaultSnapshot = readU64LE(bytes, off); off += 8;\n const poolMode = bytes[off]; off += 1;\n off += 7; // _mode_padding\n\n // _reserved (64 bytes) starts at off\n const reservedStart = off;\n // _reserved[8] = version (skipped)\n // PERC-313: _reserved[9] = hwm_enabled, [10..26] = epoch_high_water_tvl (u128), [26..28] = hwm_floor_bps (u16)\n const hwmEnabled = bytes[reservedStart + 9] === 1;\n // Read u128 as two u64 parts\n const hwmTvlLow = readU64LE(bytes, reservedStart + 10);\n const hwmTvlHigh = readU64LE(bytes, reservedStart + 18);\n const epochHighWaterTvl = hwmTvlLow | (hwmTvlHigh << 64n);\n const hwmFloorBps = readU16LE(bytes, reservedStart + 26);\n\n // PERC-303: _reserved[32] = tranche_enabled, [33..41] = junior_balance, [41..49] = junior_total_lp, [49..51] = junior_fee_mult_bps\n const trancheEnabled = bytes[reservedStart + 32] === 1;\n const juniorBalance = readU64LE(bytes, reservedStart + 33);\n const juniorTotalLp = readU64LE(bytes, reservedStart + 41);\n const juniorFeeMultBps = readU16LE(bytes, reservedStart + 49);\n\n return {\n isInitialized,\n bump,\n vaultAuthorityBump,\n adminTransferred,\n slab,\n admin,\n collateralMint,\n lpMint,\n vault,\n totalDeposited,\n totalLpSupply,\n cooldownSlots,\n depositCap,\n totalFlushed,\n totalReturned,\n totalWithdrawn,\n percolatorProgram,\n totalFeesEarned,\n lastFeeAccrualSlot,\n lastVaultSnapshot,\n poolMode,\n hwmEnabled,\n epochHighWaterTvl,\n hwmFloorBps,\n trancheEnabled,\n juniorBalance,\n juniorTotalLp,\n juniorFeeMultBps,\n };\n}\n\n// ═══════════════════════════════════════════════════════════════\n// Account Specs (for building TransactionInstructions)\n// ═══════════════════════════════════════════════════════════════\n\nexport interface StakeAccounts {\n /** InitPool accounts */\n initPool: {\n admin: PublicKey;\n slab: PublicKey;\n pool: PublicKey;\n lpMint: PublicKey;\n vault: PublicKey;\n vaultAuth: PublicKey;\n collateralMint: PublicKey;\n percolatorProgram: PublicKey;\n };\n /** Deposit accounts */\n deposit: {\n user: PublicKey;\n pool: PublicKey;\n userCollateralAta: PublicKey;\n vault: PublicKey;\n lpMint: PublicKey;\n userLpAta: PublicKey;\n vaultAuth: PublicKey;\n depositPda: PublicKey;\n };\n /** Withdraw accounts */\n withdraw: {\n user: PublicKey;\n pool: PublicKey;\n userLpAta: PublicKey;\n lpMint: PublicKey;\n vault: PublicKey;\n userCollateralAta: PublicKey;\n vaultAuth: PublicKey;\n depositPda: PublicKey;\n };\n /** FlushToInsurance accounts (CPI from stake → percolator) */\n flushToInsurance: {\n caller: PublicKey;\n pool: PublicKey;\n vault: PublicKey;\n vaultAuth: PublicKey;\n slab: PublicKey;\n wrapperVault: PublicKey;\n percolatorProgram: PublicKey;\n };\n}\n\n/**\n * Build account keys for InitPool instruction.\n * Returns array of {pubkey, isSigner, isWritable} in the order the program expects.\n */\nexport function initPoolAccounts(a: StakeAccounts['initPool']) {\n return [\n { pubkey: a.admin, isSigner: true, isWritable: true },\n { pubkey: a.slab, isSigner: false, isWritable: false },\n { pubkey: a.pool, isSigner: false, isWritable: true },\n { pubkey: a.lpMint, isSigner: false, isWritable: true },\n { pubkey: a.vault, isSigner: false, isWritable: true },\n { pubkey: a.vaultAuth, isSigner: false, isWritable: false },\n { pubkey: a.collateralMint, isSigner: false, isWritable: false },\n { pubkey: a.percolatorProgram, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },\n ];\n}\n\n/**\n * Build account keys for Deposit instruction.\n */\nexport function depositAccounts(a: StakeAccounts['deposit']) {\n return [\n { pubkey: a.user, isSigner: true, isWritable: false },\n { pubkey: a.pool, isSigner: false, isWritable: true },\n { pubkey: a.userCollateralAta, isSigner: false, isWritable: true },\n { pubkey: a.vault, isSigner: false, isWritable: true },\n { pubkey: a.lpMint, isSigner: false, isWritable: true },\n { pubkey: a.userLpAta, isSigner: false, isWritable: true },\n { pubkey: a.vaultAuth, isSigner: false, isWritable: false },\n { pubkey: a.depositPda, isSigner: false, isWritable: true },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n ];\n}\n\n/**\n * Build account keys for Withdraw instruction.\n */\nexport function withdrawAccounts(a: StakeAccounts['withdraw']) {\n return [\n { pubkey: a.user, isSigner: true, isWritable: false },\n { pubkey: a.pool, isSigner: false, isWritable: true },\n { pubkey: a.userLpAta, isSigner: false, isWritable: true },\n { pubkey: a.lpMint, isSigner: false, isWritable: true },\n { pubkey: a.vault, isSigner: false, isWritable: true },\n { pubkey: a.userCollateralAta, isSigner: false, isWritable: true },\n { pubkey: a.vaultAuth, isSigner: false, isWritable: false },\n { pubkey: a.depositPda, isSigner: false, isWritable: true },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },\n ];\n}\n\n/**\n * Build account keys for FlushToInsurance instruction.\n */\nexport function flushToInsuranceAccounts(a: StakeAccounts['flushToInsurance']) {\n return [\n { pubkey: a.caller, isSigner: true, isWritable: false },\n { pubkey: a.pool, isSigner: false, isWritable: true },\n { pubkey: a.vault, isSigner: false, isWritable: true },\n { pubkey: a.vaultAuth, isSigner: false, isWritable: false },\n { pubkey: a.slab, isSigner: false, isWritable: true },\n { pubkey: a.wrapperVault, isSigner: false, isWritable: true },\n { pubkey: a.percolatorProgram, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n ];\n}\n","import { PublicKey } from \"@solana/web3.js\";\n\n/**\n * Read an environment variable safely. Returns `undefined` in browser\n * environments where `process` is not defined, avoiding a\n * `ReferenceError` crash at import time.\n */\nexport function safeEnv(key: string): string | undefined {\n try {\n return typeof process !== \"undefined\" && process?.env\n ? process.env[key]\n : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Centralized PROGRAM_ID configuration\n * \n * Default to environment variable, then fall back to network-specific defaults.\n * This prevents hard-coded program IDs scattered across the codebase.\n */\n\nexport const PROGRAM_IDS = {\n devnet: {\n percolator: \"FxfD37s1AZTeWfFQps9Zpebi2dNQ9QSSDtfMKdbsfKrD\",\n matcher: \"GTRgyTDfrMvBubALAqtHuQwT8tbGyXid7svXZKtWfC9k\",\n },\n mainnet: {\n percolator: \"GM8zjJ8LTBMv9xEsverh6H6wLyevgMHEJXcEzyY3rY24\",\n matcher: \"DHP6DtwXP1yJsz8YzfoeigRFPB979gzmumkmCxDLSkUX\",\n },\n} as const;\n\nexport type Network = \"devnet\" | \"mainnet\";\n\n/**\n * Get the Percolator program ID for the current network\n * \n * Priority:\n * 1. PROGRAM_ID env var (explicit override)\n * 2. Network-specific default (NETWORK env var)\n * 3. Devnet default (safest fallback — bug bounty PERC-697)\n */\nexport function getProgramId(network?: Network): PublicKey {\n const override = safeEnv(\"PROGRAM_ID\");\n if (override) {\n console.warn(\n `[percolator-sdk] PROGRAM_ID env override active: ${override} — ensure this points to a trusted program`,\n );\n return new PublicKey(override);\n }\n\n // Use provided network or detect from env — default to devnet (never mainnet silently)\n const detectedNetwork = getCurrentNetwork();\n const targetNetwork = network ?? detectedNetwork;\n const programId = PROGRAM_IDS[targetNetwork].percolator;\n\n return new PublicKey(programId);\n}\n\n/**\n * Get the Matcher program ID for the current network\n */\nexport function getMatcherProgramId(network?: Network): PublicKey {\n const override = safeEnv(\"MATCHER_PROGRAM_ID\");\n if (override) {\n console.warn(\n `[percolator-sdk] MATCHER_PROGRAM_ID env override active: ${override} — ensure this points to a trusted program`,\n );\n return new PublicKey(override);\n }\n\n // Use provided network or detect from env — default to devnet (never mainnet silently)\n const detectedNetwork = getCurrentNetwork();\n const targetNetwork = network ?? detectedNetwork;\n const programId = PROGRAM_IDS[targetNetwork].matcher;\n\n if (!programId) {\n throw new Error(`Matcher program not deployed on ${targetNetwork}`);\n }\n\n return new PublicKey(programId);\n}\n\n/**\n * Get the current network from environment.\n *\n * SECURITY (PERC-697): Removed silent mainnet default.\n * Previously defaulted to \"mainnet\" when NETWORK was unset, which could cause\n * crank/keeper scripts run without env vars to silently target mainnet program IDs.\n *\n * Now defaults to \"devnet\" — the safer fallback for a devnet-first protocol.\n * Production deployments always set NETWORK explicitly via Railway/env.\n * For mainnet operations use networkValidation.ts (ensureNetworkConfigValid) which\n * enforces FORCE_MAINNET=1.\n */\nexport function getCurrentNetwork(): Network {\n const network = safeEnv(\"NETWORK\")?.toLowerCase();\n if (network === \"mainnet\" || network === \"mainnet-beta\") {\n return \"mainnet\";\n }\n // devnet, testnet, or unset → devnet (fail-open to devnet, not mainnet)\n return \"devnet\";\n}\n","/**\n * @module adl\n * Percolator ADL (Auto-Deleveraging) client utilities.\n *\n * PERC-8278 / PERC-8312 / PERC-305: ADL is triggered when `pnl_pos_tot > max_pnl_cap`\n * on a market (PnL cap exceeded) AND the insurance fund is fully depleted (balance == 0).\n * The most profitable positions on the dominant side are deleveraged first.\n *\n * **Note on caller permissions:** `ExecuteAdl` (tag 50) requires the caller to be the\n * market admin/keeper key (`header.admin`). It is NOT permissionless despite the\n * instruction being structurally available to any signer.\n *\n * API surface:\n * - fetchAdlRankedPositions() — fetch slab + rank all open positions by PnL%\n * - rankAdlPositions() — pure (no-RPC) variant for already-fetched slab bytes\n * - isAdlTriggered() — check if slab's pnl_pos_tot exceeds max_pnl_cap\n * - buildAdlInstruction() — build a single ExecuteAdl TransactionInstruction\n * - buildAdlTransaction() — fetch + rank + pick top target + return instruction\n * - parseAdlEvent() — decode AdlEvent from transaction log lines\n * - fetchAdlRankings() — call /api/adl/rankings HTTP endpoint\n * - AdlRankedPosition — position record with adl_rank and computed pnlPct\n * - AdlRankingResult — full ranking with trigger status\n * - AdlEvent — decoded on-chain AdlEvent log entry (tag 0xAD1E_0001)\n * - AdlApiRanking — single ranked position from /api/adl/rankings\n * - AdlApiResult — full result from /api/adl/rankings\n * - AdlSide — \"long\" | \"short\"\n */\n\nimport {\n Connection,\n PublicKey,\n TransactionInstruction,\n AccountMeta,\n SYSVAR_CLOCK_PUBKEY,\n} from \"@solana/web3.js\";\nimport {\n fetchSlab,\n parseAllAccounts,\n parseEngine,\n parseConfig,\n detectSlabLayout,\n AccountKind,\n Account,\n SlabLayout,\n} from \"./slab.js\";\nimport { encodeExecuteAdl } from \"../abi/instructions.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Position side derived from positionSize sign. */\nexport type AdlSide = \"long\" | \"short\";\n\n/**\n * A ranked open position for ADL purposes.\n * Positions are ranked descending by `pnlPct` — rank 0 is the most profitable\n * and will be deleveraged first.\n */\nexport interface AdlRankedPosition {\n /** Account index in the slab (used as `targetIdx` in ExecuteAdl). */\n idx: number;\n /** Owner public key. */\n owner: PublicKey;\n /** Raw position size (i128 — negative = short, positive = long). */\n positionSize: bigint;\n /** Realised + mark-to-market PnL in lamports (i128 from slab). */\n pnl: bigint;\n /** Capital at entry in lamports (u128). */\n capital: bigint;\n /**\n * PnL as a fraction of capital, expressed as basis points (scaled × 10_000).\n * pnlPct = pnl * 10_000 / capital.\n * Higher = more profitable = deleveraged first.\n */\n pnlPct: bigint;\n /** Long or short. */\n side: AdlSide;\n /**\n * ADL rank among positions on the same side (0 = highest PnL%, deleveraged first).\n * `-1` if position size is zero (inactive).\n */\n adlRank: number;\n}\n\n/**\n * Result of `fetchAdlRankedPositions`.\n */\nexport interface AdlRankingResult {\n /** All open (non-zero) user positions, sorted descending by PnLPct, ranked. */\n ranked: AdlRankedPosition[];\n /**\n * Longs ranked separately (adlRank within this subset).\n * Rank 0 = most profitable long = first to be deleveraged on a net-long market.\n */\n longs: AdlRankedPosition[];\n /**\n * Shorts ranked separately (adlRank within this subset).\n * Rank 0 = most profitable short (most negative pnlPct magnitude — i.e., highest\n * unrealised gain for the short-side holder).\n */\n shorts: AdlRankedPosition[];\n /** Whether ADL is currently triggered (pnlPosTot > maxPnlCap). */\n isTriggered: boolean;\n /** pnl_pos_tot from engine state. */\n pnlPosTot: bigint;\n /** max_pnl_cap from market config. */\n maxPnlCap: bigint;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Compute PnL% in basis points for a position.\n * Returns 0n when capital is 0 to avoid division by zero.\n */\nfunction computePnlPct(pnl: bigint, capital: bigint): bigint {\n if (capital === 0n) return 0n;\n return (pnl * 10_000n) / capital;\n}\n\n// ---------------------------------------------------------------------------\n// Core API\n// ---------------------------------------------------------------------------\n\n/**\n * Check whether ADL is currently triggered on a slab.\n *\n * ADL triggers when pnl_pos_tot > max_pnl_cap (max_pnl_cap must be > 0).\n *\n * @param slabData - Raw slab account bytes.\n * @returns true if ADL is triggered.\n *\n * @example\n * ```ts\n * const data = await fetchSlab(connection, slabKey);\n * if (isAdlTriggered(data)) {\n * const ranking = await fetchAdlRankedPositions(connection, slabKey);\n * }\n * ```\n */\nexport function isAdlTriggered(slabData: Uint8Array): boolean {\n const layout = detectSlabLayout(slabData.length);\n if (!layout) return false;\n try {\n const engine = parseEngine(slabData);\n if (engine.pnlPosTot === 0n) return false;\n const config = parseConfig(slabData, layout);\n if (config.maxPnlCap === 0n) return false;\n return engine.pnlPosTot > config.maxPnlCap;\n } catch {\n return false;\n }\n}\n\n/**\n * Fetch a slab and rank all open user positions by PnL% for ADL targeting.\n *\n * Positions are ranked separately per side:\n * - Longs: rank 0 = highest positive PnL% (most profitable long)\n * - Shorts: rank 0 = highest negative PnL% by abs value (most profitable short)\n *\n * Rank ordering matches the on-chain ADL engine in percolator-prog (PERC-8273):\n * the position at rank 0 of the dominant side is deleveraged first.\n *\n * @param connection - Solana connection.\n * @param slab - Slab (market) public key.\n * @returns AdlRankingResult with ranked longs, ranked shorts, and trigger status.\n *\n * @example\n * ```ts\n * const { ranked, longs, isTriggered } = await fetchAdlRankedPositions(connection, slabKey);\n * if (isTriggered && longs.length > 0) {\n * const target = longs[0]; // highest PnL long\n * const ix = buildAdlInstruction(caller, slabKey, oracleKey, programId, target.idx);\n * }\n * ```\n */\nexport async function fetchAdlRankedPositions(\n connection: Connection,\n slab: PublicKey\n): Promise<AdlRankingResult> {\n const data = await fetchSlab(connection, slab);\n return rankAdlPositions(data);\n}\n\n/**\n * Pure (no-RPC) variant — rank positions from already-fetched slab bytes.\n * Useful when you already have the slab data (e.g., from a subscription).\n */\nexport function rankAdlPositions(slabData: Uint8Array): AdlRankingResult {\n const layout = detectSlabLayout(slabData.length);\n\n let pnlPosTot = 0n;\n try {\n const engine = parseEngine(slabData);\n pnlPosTot = engine.pnlPosTot;\n } catch (err) {\n console.warn(\n `[rankAdlPositions] parseEngine failed:`,\n err instanceof Error ? err.message : err,\n );\n }\n\n let maxPnlCap = 0n;\n let isTriggered = false;\n if (layout) {\n try {\n const config = parseConfig(slabData, layout);\n maxPnlCap = config.maxPnlCap;\n isTriggered = maxPnlCap > 0n && pnlPosTot > maxPnlCap;\n } catch {\n // If config parse fails, leave isTriggered=false; ranking still useful.\n }\n }\n\n // Parse all used accounts.\n const accounts = parseAllAccounts(slabData);\n\n // Build ranked position list (user accounts with non-zero position only).\n const positions: AdlRankedPosition[] = [];\n for (const { idx, account } of accounts) {\n if (account.kind !== AccountKind.User) continue;\n if (account.positionSize === 0n) continue;\n\n const side: AdlSide = account.positionSize > 0n ? \"long\" : \"short\";\n // For shorts, positionSize is negative — PnL computation is symmetric:\n // a short profits when price falls, so pnl stored in the slab already\n // reflects mark-to-market gain/loss for both sides.\n const pnlPct = computePnlPct(account.pnl, account.capital);\n\n positions.push({\n idx,\n owner: account.owner,\n positionSize: account.positionSize,\n pnl: account.pnl,\n capital: account.capital,\n pnlPct,\n side,\n adlRank: -1, // assigned below\n });\n }\n\n // Rank longs: descending pnlPct (most profitable first).\n const longs = positions\n .filter(p => p.side === \"long\")\n .sort((a, b) => (b.pnlPct > a.pnlPct ? 1 : b.pnlPct < a.pnlPct ? -1 : 0));\n longs.forEach((p, i) => { p.adlRank = i; });\n\n // Rank shorts: descending pnlPct (most profitable short = highest pnlPct\n // magnitude, but pnlPct can be negative; sort descending still puts\n // the \"least negative\" aka \"most profitable\" short first).\n const shorts = positions\n .filter(p => p.side === \"short\")\n .sort((a, b) => (b.pnlPct > a.pnlPct ? 1 : b.pnlPct < a.pnlPct ? -1 : 0));\n shorts.forEach((p, i) => { p.adlRank = i; });\n\n // Overall ranked list = longs + shorts merged, still sorted by pnlPct desc.\n const ranked = [...longs, ...shorts].sort(\n (a, b) => (b.pnlPct > a.pnlPct ? 1 : b.pnlPct < a.pnlPct ? -1 : 0)\n );\n\n return { ranked, longs, shorts, isTriggered, pnlPosTot, maxPnlCap };\n}\n\n/**\n * Build a single `ExecuteAdl` TransactionInstruction (tag 50, PERC-305).\n *\n * Does NOT fetch the slab or check trigger status — use `fetchAdlRankedPositions`\n * first to determine the correct `targetIdx`.\n *\n * **Caller requirement:** The on-chain handler requires the caller to be the market\n * admin/keeper authority (`header.admin`). Passing any other signer will result in\n * `EngineUnauthorized`.\n *\n * @param caller - Signer — must be the market keeper/admin authority.\n * @param slab - Slab (market) public key.\n * @param oracle - Primary oracle public key for this market.\n * @param programId - Percolator program ID.\n * @param targetIdx - Account index to deleverage (from `AdlRankedPosition.idx`).\n * @param backupOracles - Optional additional oracle accounts (non-Hyperp markets).\n *\n * @example\n * ```ts\n * import { fetchAdlRankedPositions, buildAdlInstruction } from \"@percolator/sdk\";\n *\n * const { longs, isTriggered } = await fetchAdlRankedPositions(connection, slabKey);\n * if (isTriggered && longs.length > 0) {\n * const ix = buildAdlInstruction(\n * caller.publicKey, slabKey, oracleKey, PROGRAM_ID, longs[0].idx\n * );\n * await sendAndConfirmTransaction(connection, new Transaction().add(ix), [caller]);\n * }\n * ```\n */\nexport function buildAdlInstruction(\n caller: PublicKey,\n slab: PublicKey,\n oracle: PublicKey,\n programId: PublicKey,\n targetIdx: number,\n backupOracles: PublicKey[] = []\n): TransactionInstruction {\n if (!Number.isInteger(targetIdx) || targetIdx < 0) {\n throw new Error(\n `buildAdlInstruction: targetIdx must be a non-negative integer, got ${targetIdx}`,\n );\n }\n const dataBytes = encodeExecuteAdl({ targetIdx });\n const data = Buffer.from(dataBytes);\n\n const keys: AccountMeta[] = [\n { pubkey: caller, isSigner: true, isWritable: false },\n { pubkey: slab, isSigner: false, isWritable: true },\n { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },\n { pubkey: oracle, isSigner: false, isWritable: false },\n ...backupOracles.map(k => ({ pubkey: k, isSigner: false, isWritable: false })),\n ];\n\n return new TransactionInstruction({ keys, programId, data });\n}\n\n/**\n * Convenience builder: fetch slab, rank positions, pick the highest-ranked\n * target on the given side, and return a ready-to-send `TransactionInstruction`.\n *\n * Returns `null` when ADL is not triggered or no eligible positions exist.\n *\n * @param connection - Solana connection.\n * @param caller - Signer — must be the market keeper/admin authority.\n * @param slab - Slab (market) public key.\n * @param oracle - Primary oracle public key.\n * @param programId - Percolator program ID.\n * @param preferSide - Optional: target \"long\" or \"short\" side only.\n * If omitted, picks the overall top-ranked position.\n * @param backupOracles - Optional extra oracle accounts.\n *\n * @example\n * ```ts\n * const ix = await buildAdlTransaction(\n * connection, caller.publicKey, slabKey, oracleKey, PROGRAM_ID\n * );\n * if (ix) {\n * await sendAndConfirmTransaction(connection, new Transaction().add(ix), [caller]);\n * }\n * ```\n */\nexport async function buildAdlTransaction(\n connection: Connection,\n caller: PublicKey,\n slab: PublicKey,\n oracle: PublicKey,\n programId: PublicKey,\n preferSide?: AdlSide,\n backupOracles: PublicKey[] = []\n): Promise<TransactionInstruction | null> {\n const ranking = await fetchAdlRankedPositions(connection, slab);\n\n if (!ranking.isTriggered) return null;\n\n let target: AdlRankedPosition | undefined;\n if (preferSide === \"long\") {\n target = ranking.longs[0];\n } else if (preferSide === \"short\") {\n target = ranking.shorts[0];\n } else {\n target = ranking.ranked[0];\n }\n\n if (!target) return null;\n\n return buildAdlInstruction(caller, slab, oracle, programId, target.idx, backupOracles);\n}\n\n// ---------------------------------------------------------------------------\n// AdlEvent — on-chain log decoder (PERC-8312)\n// ---------------------------------------------------------------------------\n\n/**\n * Decoded on-chain AdlEvent emitted by the `ExecuteAdl` instruction handler.\n *\n * The on-chain handler emits via `sol_log_64(0xAD1E_0001, target_idx, price, closed_lo, closed_hi)`.\n * `sol_log_64` prints 5 decimal u64 values separated by spaces on a single \"Program log:\" line.\n *\n * Fields:\n * - `tag` — always `0xAD1E_0001` (2970353665n)\n * - `targetIdx` — slab account index that was deleveraged\n * - `price` — oracle price used (in market price units, e.g. e6)\n * - `closedAbs` — absolute size of the position closed (i128, reassembled from lo+hi u64 parts)\n *\n * @example\n * ```ts\n * const logs = tx.meta?.logMessages ?? [];\n * const event = parseAdlEvent(logs);\n * if (event) {\n * console.log(\"ADL closed position\", event.targetIdx, \"size\", event.closedAbs);\n * }\n * ```\n */\nexport interface AdlEvent {\n /** Tag discriminator — always 0xAD1E_0001n (2970353665). */\n tag: bigint;\n /** Slab account index that was deleveraged. */\n targetIdx: number;\n /** Oracle price used for the deleverage (market-native units, e.g. lamports/e6). */\n price: bigint;\n /**\n * Absolute position size closed (reassembled from lo+hi u64).\n * This is the i128 absolute value — always non-negative.\n */\n closedAbs: bigint;\n}\n\n/** Magic discriminator for the ADL event log line. */\nconst ADL_EVENT_TAG = 0xAD1E_0001n;\n\n/**\n * Parse the AdlEvent from a transaction's log messages.\n *\n * Searches for a \"Program log: <a> <b> <c> <d> <e>\" line where the first\n * decimal value equals `0xAD1E_0001` (2970353665). Returns `null` if not found.\n *\n * @param logs - Array of log message strings (from `tx.meta.logMessages`).\n * @returns Decoded `AdlEvent` or `null` if the log is not present.\n *\n * @example\n * ```ts\n * const event = parseAdlEvent(tx.meta?.logMessages ?? []);\n * if (event) {\n * console.log(`ADL: idx=${event.targetIdx} price=${event.price} closed=${event.closedAbs}`);\n * }\n * ```\n */\nexport function parseAdlEvent(logs: string[]): AdlEvent | null {\n for (const line of logs) {\n if (typeof line !== \"string\") continue;\n // sol_log_64 emits: \"Program log: a b c d e\" (5 space-separated decimals)\n const match = line.match(\n /^Program log: (\\d+) (\\d+) (\\d+) (\\d+) (\\d+)$/,\n );\n if (!match) continue;\n\n let tag: bigint;\n try {\n tag = BigInt(match[1]);\n } catch {\n continue;\n }\n\n if (tag !== ADL_EVENT_TAG) continue;\n\n try {\n const targetIdx = Number(BigInt(match[2]));\n const price = BigInt(match[3]);\n const closedLo = BigInt(match[4]);\n const closedHi = BigInt(match[5]);\n // Reassemble i128 from lo/hi u64 parts (little-endian split).\n const closedAbs = (closedHi << 64n) | closedLo;\n return { tag, targetIdx, price, closedAbs };\n } catch {\n continue;\n }\n }\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// fetchAdlRankings — HTTP client for /api/adl/rankings (PERC-8312)\n// ---------------------------------------------------------------------------\n\n/**\n * A single ranked position as returned by the /api/adl/rankings endpoint.\n */\nexport interface AdlApiRanking {\n /** 1-based rank (1 = highest PnL%, first to be deleveraged). */\n rank: number;\n /** Slab account index. Pass as `targetIdx` to `buildAdlInstruction`. */\n idx: number;\n /** Absolute PnL (lamports) as a decimal string. */\n pnlAbs: string;\n /** Capital at entry (lamports) as a decimal string. */\n capital: string;\n /** PnL as millionths of capital (pnl * 1_000_000 / capital). */\n pnlPctMillionths: string;\n}\n\n/**\n * Full result from the /api/adl/rankings endpoint.\n */\nexport interface AdlApiResult {\n slabAddress: string;\n /** pnl_pos_tot from slab engine state (decimal string). */\n pnlPosTot: string;\n /** max_pnl_cap from market config (decimal string, \"0\" if unconfigured). */\n maxPnlCap: string;\n /** Insurance fund balance (decimal string). */\n insuranceFundBalance: string;\n /** Insurance fund lifetime fee revenue (decimal string). */\n insuranceFundFeeRevenue: string;\n /** Insurance utilization in basis points (0–10000). */\n insuranceUtilizationBps: number;\n /** true if pnlPosTot > maxPnlCap. */\n capExceeded: boolean;\n /** true if insurance fund is fully depleted (balance == 0). */\n insuranceDepleted: boolean;\n /** true if utilization BPS exceeds the configured ADL threshold. */\n utilizationTriggered: boolean;\n /** true if ADL is needed (capExceeded or utilizationTriggered). */\n adlNeeded: boolean;\n /** Excess PnL above cap (decimal string). */\n excess: string;\n /** Ranked positions (empty if adlNeeded=false). */\n rankings: AdlApiRanking[];\n}\n\n/**\n * Fetch ADL rankings from the Percolator API.\n *\n * Calls `GET <apiBase>/api/adl/rankings?slab=<address>` and returns the\n * parsed result. Use this from the frontend or keeper to determine ADL\n * trigger status and pick the target index.\n *\n * @param apiBase - Base URL of the Percolator API (e.g. `https://api.percolator.io`).\n * @param slab - Slab (market) public key or base58 address string.\n * @param fetchFn - Optional custom fetch implementation (defaults to global `fetch`).\n * @returns Parsed `AdlApiResult`.\n * @throws On HTTP error or JSON parse failure.\n *\n * @example\n * ```ts\n * const result = await fetchAdlRankings(\"https://api.percolator.io\", slabKey);\n * if (result.adlNeeded && result.rankings.length > 0) {\n * const target = result.rankings[0]; // rank 1 = highest PnL%\n * const ix = buildAdlInstruction(caller, slabKey, oracleKey, PROGRAM_ID, target.idx);\n * }\n * ```\n */\nexport async function fetchAdlRankings(\n apiBase: string,\n slab: PublicKey | string,\n fetchFn: typeof fetch = fetch,\n): Promise<AdlApiResult> {\n const slabStr = typeof slab === \"string\" ? slab : slab.toBase58();\n const base = apiBase.replace(/\\/$/, \"\");\n const url = `${base}/api/adl/rankings?slab=${encodeURIComponent(slabStr)}`;\n\n const res = await fetchFn(url);\n if (!res.ok) {\n let body = \"\";\n try { body = await res.text(); } catch { /* ignore */ }\n throw new Error(\n `fetchAdlRankings: HTTP ${res.status} from ${url}${body ? ` — ${body}` : \"\"}`,\n );\n }\n\n const json = await res.json() as AdlApiResult;\n return json;\n}\n","import {\n Connection,\n PublicKey,\n TransactionInstruction,\n Transaction,\n Keypair,\n SendOptions,\n Commitment,\n AccountMeta,\n ComputeBudgetProgram,\n} from \"@solana/web3.js\";\nimport { parseErrorFromLogs } from \"../abi/errors.js\";\n\nexport interface BuildIxParams {\n programId: PublicKey;\n keys: AccountMeta[];\n data: Uint8Array | Buffer;\n}\n\n/**\n * Build a transaction instruction.\n */\nexport function buildIx(params: BuildIxParams): TransactionInstruction {\n return new TransactionInstruction({\n programId: params.programId,\n keys: params.keys,\n // TransactionInstruction types expect Buffer, but Uint8Array works at runtime.\n // Cast to avoid Buffer polyfill issues in the browser.\n data: params.data as Buffer,\n });\n}\n\nexport interface TxResult {\n signature: string;\n slot: number;\n err: string | null;\n hint?: string;\n logs: string[];\n unitsConsumed?: number;\n}\n\nexport interface SimulateOrSendParams {\n connection: Connection;\n ix: TransactionInstruction;\n signers: Keypair[];\n simulate: boolean;\n commitment?: Commitment;\n computeUnitLimit?: number; // Custom compute unit limit (default: 200,000, max: 1,400,000)\n}\n\n/**\n * Simulate or send a transaction.\n * Returns consistent output for both modes.\n */\n/** Solana per-transaction compute unit ceiling (Compute Budget program). */\nconst MAX_COMPUTE_UNIT_LIMIT = 1_400_000;\n\nexport async function simulateOrSend(\n params: SimulateOrSendParams\n): Promise<TxResult> {\n const { connection, ix, signers, simulate, commitment = \"confirmed\", computeUnitLimit } = params;\n\n if (!signers.length) {\n throw new Error(\"simulateOrSend: at least one signer is required\");\n }\n\n if (computeUnitLimit !== undefined) {\n if (\n typeof computeUnitLimit !== \"number\" ||\n !Number.isInteger(computeUnitLimit) ||\n computeUnitLimit < 1 ||\n computeUnitLimit > MAX_COMPUTE_UNIT_LIMIT\n ) {\n throw new Error(\n `computeUnitLimit must be an integer in [1, ${MAX_COMPUTE_UNIT_LIMIT}]`,\n );\n }\n }\n\n const tx = new Transaction();\n\n // Add compute budget instruction if custom limit is specified\n if (computeUnitLimit !== undefined) {\n tx.add(\n ComputeBudgetProgram.setComputeUnitLimit({\n units: computeUnitLimit,\n })\n );\n }\n\n tx.add(ix);\n const latestBlockhash = await connection.getLatestBlockhash(commitment);\n tx.recentBlockhash = latestBlockhash.blockhash;\n tx.feePayer = signers[0].publicKey;\n\n if (simulate) {\n try {\n tx.sign(...signers);\n const result = await connection.simulateTransaction(tx, signers);\n const logs = result.value.logs ?? [];\n let err: string | null = null;\n let hint: string | undefined;\n\n if (result.value.err) {\n const parsed = parseErrorFromLogs(logs);\n if (parsed) {\n err = `${parsed.name} (0x${parsed.code.toString(16)})`;\n hint = parsed.hint;\n } else {\n err = JSON.stringify(result.value.err);\n }\n }\n\n return {\n signature: \"(simulated)\",\n slot: result.context.slot,\n err,\n hint,\n logs,\n unitsConsumed: result.value.unitsConsumed ?? undefined,\n };\n } catch (e: unknown) {\n const message = e instanceof Error ? e.message : String(e);\n return {\n signature: \"(simulated)\",\n slot: 0,\n err: message,\n logs: [],\n };\n }\n }\n\n // Send\n const options: SendOptions = {\n skipPreflight: false,\n preflightCommitment: commitment,\n };\n\n try {\n const signature = await connection.sendTransaction(tx, signers, options);\n\n const confirmation = await connection.confirmTransaction(\n {\n signature,\n blockhash: latestBlockhash.blockhash,\n lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,\n },\n commitment\n );\n\n // Fetch logs\n const txInfo = await connection.getTransaction(signature, {\n commitment: \"confirmed\",\n maxSupportedTransactionVersion: 0,\n });\n\n const logs = txInfo?.meta?.logMessages ?? [];\n let err: string | null = null;\n let hint: string | undefined;\n\n if (confirmation.value.err) {\n const parsed = parseErrorFromLogs(logs);\n if (parsed) {\n err = `${parsed.name} (0x${parsed.code.toString(16)})`;\n hint = parsed.hint;\n } else {\n err = JSON.stringify(confirmation.value.err);\n }\n }\n\n return {\n signature,\n slot: txInfo?.slot ?? 0,\n err,\n hint,\n logs,\n };\n } catch (e: unknown) {\n const message = e instanceof Error ? e.message : String(e);\n return {\n signature: \"\",\n slot: 0,\n err: message,\n logs: [],\n };\n }\n}\n\n/**\n * Format transaction result for output.\n */\nexport function formatResult(result: TxResult, jsonMode: boolean): string {\n if (jsonMode) {\n return JSON.stringify(result, null, 2);\n }\n\n const lines: string[] = [];\n\n if (result.err) {\n lines.push(`Error: ${result.err}`);\n if (result.hint) {\n lines.push(`Hint: ${result.hint}`);\n }\n if (result.unitsConsumed !== undefined) {\n lines.push(`Compute Units: ${result.unitsConsumed.toLocaleString()}`);\n }\n if (result.logs.length > 0) {\n lines.push(\"Logs:\");\n result.logs.forEach((log) => lines.push(` ${log}`));\n }\n } else {\n lines.push(`Signature: ${result.signature}`);\n lines.push(`Slot: ${result.slot}`);\n if (result.unitsConsumed !== undefined) {\n lines.push(`Compute Units: ${result.unitsConsumed.toLocaleString()}`);\n }\n if (result.signature !== \"(simulated)\") {\n lines.push(`Explorer: https://explorer.solana.com/tx/${result.signature}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n","/**\n * Coin-margined perpetual trade math utilities.\n *\n * On-chain PnL formula:\n * mark_pnl = (oracle - entry) * abs_pos / oracle (longs)\n * mark_pnl = (entry - oracle) * abs_pos / oracle (shorts)\n *\n * All prices are in e6 format (1 USD = 1_000_000).\n * All token amounts are in native units (e.g. lamports).\n */\n\n/**\n * Compute mark-to-market PnL for an open position.\n */\nexport function computeMarkPnl(\n positionSize: bigint,\n entryPrice: bigint,\n oraclePrice: bigint,\n): bigint {\n if (positionSize === 0n || oraclePrice === 0n) return 0n;\n const absPos = positionSize < 0n ? -positionSize : positionSize;\n const diff =\n positionSize > 0n\n ? oraclePrice - entryPrice\n : entryPrice - oraclePrice;\n return (diff * absPos) / oraclePrice;\n}\n\n/**\n * Compute liquidation price given entry, capital, position and maintenance margin.\n * Uses pure BigInt arithmetic for precision (no Number() truncation).\n */\nexport function computeLiqPrice(\n entryPrice: bigint,\n capital: bigint,\n positionSize: bigint,\n maintenanceMarginBps: bigint,\n): bigint {\n if (positionSize === 0n || entryPrice === 0n) return 0n;\n const absPos = positionSize < 0n ? -positionSize : positionSize;\n // capitalPerUnit scaled by 1e6 for precision\n const capitalPerUnitE6 = (capital * 1_000_000n) / absPos;\n\n if (positionSize > 0n) {\n const adjusted = (capitalPerUnitE6 * 10000n) / (10000n + maintenanceMarginBps);\n const liq = entryPrice - adjusted;\n return liq > 0n ? liq : 0n;\n } else {\n // Guard: short positions liquidate when price rises above liq price.\n // With >= 100% maintenance margin the denominator (10000 - maint) would be <= 0,\n // meaning the position can never be liquidated. Return max u64 to signal this.\n if (maintenanceMarginBps >= 10000n) return 18446744073709551615n; // max u64 — unliquidatable\n const adjusted = (capitalPerUnitE6 * 10000n) / (10000n - maintenanceMarginBps);\n return entryPrice + adjusted;\n }\n}\n\n/**\n * Compute estimated liquidation price BEFORE opening a trade.\n * Accounts for trading fees reducing effective capital.\n */\nexport function computePreTradeLiqPrice(\n oracleE6: bigint,\n margin: bigint,\n posSize: bigint,\n maintBps: bigint,\n feeBps: bigint,\n direction: \"long\" | \"short\",\n): bigint {\n if (oracleE6 === 0n || margin === 0n || posSize === 0n) return 0n;\n const absPos = posSize < 0n ? -posSize : posSize;\n const fee = (absPos * feeBps) / 10000n;\n const effectiveCapital = margin > fee ? margin - fee : 0n;\n const signedPos = direction === \"long\" ? absPos : -absPos;\n return computeLiqPrice(oracleE6, effectiveCapital, signedPos, maintBps);\n}\n\n/**\n * Compute trading fee from notional value and fee rate in bps.\n */\nexport function computeTradingFee(\n notional: bigint,\n tradingFeeBps: bigint,\n): bigint {\n return (notional * tradingFeeBps) / 10000n;\n}\n\n/**\n * Dynamic fee tier configuration.\n */\nexport interface FeeTierConfig {\n /** Base trading fee (Tier 1) in bps */\n baseBps: bigint;\n /** Tier 2 fee in bps (0 = disabled) */\n tier2Bps: bigint;\n /** Tier 3 fee in bps (0 = disabled) */\n tier3Bps: bigint;\n /** Notional threshold to enter Tier 2 (0 = tiered fees disabled) */\n tier2Threshold: bigint;\n /** Notional threshold to enter Tier 3 */\n tier3Threshold: bigint;\n}\n\n/**\n * Compute the effective fee rate in bps using the tiered fee schedule.\n *\n * Mirrors on-chain `compute_dynamic_fee_bps` logic:\n * - notional < tier2Threshold → baseBps (Tier 1)\n * - notional < tier3Threshold → tier2Bps (Tier 2)\n * - notional >= tier3Threshold → tier3Bps (Tier 3)\n *\n * If tier2Threshold == 0, tiered fees are disabled (flat baseBps).\n */\nexport function computeDynamicFeeBps(\n notional: bigint,\n config: FeeTierConfig,\n): bigint {\n if (config.tier2Threshold === 0n) return config.baseBps;\n if (config.tier3Threshold > 0n && notional >= config.tier3Threshold) return config.tier3Bps;\n if (notional >= config.tier2Threshold) return config.tier2Bps;\n return config.baseBps;\n}\n\n/**\n * Compute the dynamic trading fee for a given notional and tier config.\n *\n * Uses ceiling division to match on-chain behavior (prevents fee evasion\n * via micro-trades).\n */\nexport function computeDynamicTradingFee(\n notional: bigint,\n config: FeeTierConfig,\n): bigint {\n const feeBps = computeDynamicFeeBps(notional, config);\n if (notional <= 0n || feeBps <= 0n) return 0n;\n return (notional * feeBps + 9999n) / 10000n;\n}\n\n/**\n * Fee split configuration.\n */\nexport interface FeeSplitConfig {\n /** LP vault share in bps (0–10_000) */\n lpBps: bigint;\n /** Protocol treasury share in bps */\n protocolBps: bigint;\n /** Market creator share in bps */\n creatorBps: bigint;\n}\n\n/**\n * Compute fee split for a total fee amount.\n *\n * Returns [lpShare, protocolShare, creatorShare].\n * If all split params are 0, 100% goes to LP (legacy behavior).\n * Creator gets the rounding remainder to ensure total is preserved.\n */\nexport function computeFeeSplit(\n totalFee: bigint,\n config: FeeSplitConfig,\n): [bigint, bigint, bigint] {\n if (config.lpBps === 0n && config.protocolBps === 0n && config.creatorBps === 0n) {\n return [totalFee, 0n, 0n];\n }\n const lp = (totalFee * config.lpBps) / 10000n;\n const protocol = (totalFee * config.protocolBps) / 10000n;\n const creator = totalFee - lp - protocol;\n return [lp, protocol, creator];\n}\n\n/**\n * Compute PnL as a percentage of capital.\n *\n * Uses BigInt scaling to avoid precision loss from Number(bigint) conversion.\n * Number(bigint) silently truncates values above 2^53, which can produce\n * incorrect percentages for large positions (e.g., tokens with 9 decimals\n * where capital > ~9M tokens in native units exceeds MAX_SAFE_INTEGER).\n */\nexport function computePnlPercent(\n pnlTokens: bigint,\n capital: bigint,\n): number {\n if (capital === 0n) return 0;\n const scaledPct = (pnlTokens * 10_000n) / capital;\n if (scaledPct > BigInt(Number.MAX_SAFE_INTEGER) || scaledPct < BigInt(-Number.MAX_SAFE_INTEGER)) {\n throw new Error(\n `computePnlPercent: scaled result ${scaledPct} exceeds Number.MAX_SAFE_INTEGER — precision loss`,\n );\n }\n return Number(scaledPct) / 100;\n}\n\n/**\n * Estimate entry price including fee impact (slippage approximation).\n */\nexport function computeEstimatedEntryPrice(\n oracleE6: bigint,\n tradingFeeBps: bigint,\n direction: \"long\" | \"short\",\n): bigint {\n if (oracleE6 === 0n) return 0n;\n const feeImpact = (oracleE6 * tradingFeeBps) / 10000n;\n return direction === \"long\" ? oracleE6 + feeImpact : oracleE6 - feeImpact;\n}\n\nconst MAX_SAFE_BIGINT = BigInt(Number.MAX_SAFE_INTEGER);\nconst MIN_SAFE_BIGINT = BigInt(-Number.MAX_SAFE_INTEGER);\n\n/**\n * Convert per-slot funding rate (bps) to annualized percentage.\n */\nexport function computeFundingRateAnnualized(\n fundingRateBpsPerSlot: bigint,\n): number {\n if (fundingRateBpsPerSlot > MAX_SAFE_BIGINT || fundingRateBpsPerSlot < MIN_SAFE_BIGINT) {\n throw new Error(\n `computeFundingRateAnnualized: value ${fundingRateBpsPerSlot} exceeds safe integer range`,\n );\n }\n const bpsPerSlot = Number(fundingRateBpsPerSlot);\n const slotsPerYear = 2.5 * 60 * 60 * 24 * 365; // ~400ms slots\n return (bpsPerSlot * slotsPerYear) / 100;\n}\n\n/**\n * Compute margin required for a given notional and initial margin bps.\n */\nexport function computeRequiredMargin(\n notional: bigint,\n initialMarginBps: bigint,\n): bigint {\n return (notional * initialMarginBps) / 10000n;\n}\n\n/**\n * Compute maximum leverage from initial margin bps.\n *\n * @throws Error if initialMarginBps is zero (infinite leverage is undefined)\n */\nexport function computeMaxLeverage(initialMarginBps: bigint): number {\n if (initialMarginBps <= 0n) {\n throw new Error(\"computeMaxLeverage: initialMarginBps must be positive\");\n }\n return Number(10000n / initialMarginBps);\n}\n","/**\n * Warmup leverage cap utilities.\n *\n * During the market warmup period, capital is released linearly over\n * `warmupPeriodSlots` slots, which constrains the effective leverage\n * and maximum position size available to traders.\n */\n\nimport { computeMaxLeverage } from \"./trading.js\";\n\n// =============================================================================\n// Warmup leverage cap utilities\n// =============================================================================\n\n/**\n * Compute unlocked capital during the warmup period.\n *\n * Capital is released linearly over `warmupPeriodSlots` slots starting from\n * `warmupStartedAtSlot`. Before warmup starts (startSlot === 0) or if the\n * warmup period is 0, all capital is considered unlocked.\n *\n * @param totalCapital - Total deposited capital (native units).\n * @param currentSlot - The current on-chain slot.\n * @param warmupStartSlot - Slot at which warmup started (0 = not started).\n * @param warmupPeriodSlots - Total slots in the warmup period.\n * @returns The amount of capital currently unlocked.\n */\nexport function computeWarmupUnlockedCapital(\n totalCapital: bigint,\n currentSlot: bigint,\n warmupStartSlot: bigint,\n warmupPeriodSlots: bigint,\n): bigint {\n // No warmup configured or not started → all capital available\n if (warmupPeriodSlots === 0n || warmupStartSlot === 0n) return totalCapital;\n if (totalCapital <= 0n) return 0n;\n\n const elapsed = currentSlot > warmupStartSlot\n ? currentSlot - warmupStartSlot\n : 0n;\n\n // Warmup complete\n if (elapsed >= warmupPeriodSlots) return totalCapital;\n\n // Linear unlock: totalCapital * elapsed / warmupPeriodSlots\n return (totalCapital * elapsed) / warmupPeriodSlots;\n}\n\n/**\n * Compute the effective maximum leverage during the warmup period.\n *\n * During warmup, only unlocked capital can be used as margin. The effective\n * leverage relative to *total* capital is therefore capped at:\n *\n * effectiveMaxLeverage = maxLeverage × (unlockedCapital / totalCapital)\n *\n * This returns a floored integer value (leverage is always a whole number\n * in the UI), with a minimum of 1x if any capital is unlocked.\n *\n * @param initialMarginBps - Initial margin requirement in basis points.\n * @param totalCapital - Total deposited capital (native units).\n * @param currentSlot - The current on-chain slot.\n * @param warmupStartSlot - Slot at which warmup started (0 = not started).\n * @param warmupPeriodSlots - Total slots in the warmup period.\n * @returns The effective maximum leverage (integer, ≥ 1).\n */\nexport function computeWarmupLeverageCap(\n initialMarginBps: bigint,\n totalCapital: bigint,\n currentSlot: bigint,\n warmupStartSlot: bigint,\n warmupPeriodSlots: bigint,\n): number {\n const maxLev = computeMaxLeverage(initialMarginBps);\n\n // No warmup or warmup not started → full leverage\n if (warmupPeriodSlots === 0n || warmupStartSlot === 0n) return maxLev;\n if (totalCapital <= 0n) return 1;\n\n const unlocked = computeWarmupUnlockedCapital(\n totalCapital,\n currentSlot,\n warmupStartSlot,\n warmupPeriodSlots,\n );\n\n if (unlocked <= 0n) return 1; // At least 1x if nothing unlocked yet (slot 0 edge)\n\n // Effective leverage = maxLev * (unlocked / total), floored, min 1\n const effectiveLev = Number((BigInt(maxLev) * unlocked) / totalCapital);\n return Math.max(1, effectiveLev);\n}\n\n/**\n * Compute the maximum position size allowed during warmup.\n *\n * This is the unlocked capital multiplied by the base max leverage.\n * Unlike `computeWarmupLeverageCap` (which gives effective leverage\n * relative to total capital), this gives the absolute notional cap.\n *\n * @param initialMarginBps - Initial margin requirement in basis points.\n * @param totalCapital - Total deposited capital (native units).\n * @param currentSlot - The current on-chain slot.\n * @param warmupStartSlot - Slot at which warmup started (0 = not started).\n * @param warmupPeriodSlots - Total slots in the warmup period.\n * @returns Maximum position size in native units.\n */\nexport function computeWarmupMaxPositionSize(\n initialMarginBps: bigint,\n totalCapital: bigint,\n currentSlot: bigint,\n warmupStartSlot: bigint,\n warmupPeriodSlots: bigint,\n): bigint {\n const maxLev = computeMaxLeverage(initialMarginBps);\n const unlocked = computeWarmupUnlockedCapital(\n totalCapital,\n currentSlot,\n warmupStartSlot,\n warmupPeriodSlots,\n );\n return unlocked * BigInt(maxLev);\n}\n","/**\n * Input validation utilities for CLI commands.\n * Provides descriptive error messages for invalid input.\n */\n\nimport { PublicKey } from \"@solana/web3.js\";\n\n// Constants for numeric limits\nconst U16_MAX = 65535;\nconst U64_MAX = BigInt(\"18446744073709551615\");\nconst I64_MIN = BigInt(\"-9223372036854775808\");\nconst I64_MAX = BigInt(\"9223372036854775807\");\nconst U128_MAX = (1n << 128n) - 1n;\nconst I128_MIN = -(1n << 127n);\nconst I128_MAX = (1n << 127n) - 1n;\n\n/**\n * Non-empty trimmed string of decimal digits only: `\"0\"` or `[1-9]\\\\d*` (no leading zeros\n * except a single zero). Rejects fractions, scientific notation, hex prefixes, and trailing junk.\n */\nfunction requireDecimalUIntString(value: string, field: string): string {\n const t = value.trim();\n if (t === \"\") {\n throw new ValidationError(field, `\"${value}\" is not a valid number`);\n }\n if (!/^(0|[1-9]\\d*)$/.test(t)) {\n throw new ValidationError(\n field,\n `\"${value}\" is not a valid non-negative integer (use decimal digits only, e.g. 123).`\n );\n }\n return t;\n}\n\nexport class ValidationError extends Error {\n constructor(\n public readonly field: string,\n message: string\n ) {\n super(`Invalid ${field}: ${message}`);\n this.name = \"ValidationError\";\n }\n}\n\n/**\n * Validate a public key string.\n */\nexport function validatePublicKey(value: string, field: string): PublicKey {\n try {\n return new PublicKey(value);\n } catch {\n throw new ValidationError(\n field,\n `\"${value}\" is not a valid base58 public key. ` +\n `Example: \"11111111111111111111111111111111\"`\n );\n }\n}\n\n/**\n * Validate a non-negative integer index (u16 range for accounts).\n */\nexport function validateIndex(value: string, field: string): number {\n const t = requireDecimalUIntString(value, field);\n const bi = BigInt(t);\n if (bi > BigInt(U16_MAX)) {\n throw new ValidationError(\n field,\n `must be <= ${U16_MAX} (u16 max), got ${t}`\n );\n }\n return Number(bi);\n}\n\n/**\n * Validate a non-negative amount (u64 range).\n */\nexport function validateAmount(value: string, field: string): bigint {\n let num: bigint;\n try {\n num = BigInt(value);\n } catch {\n throw new ValidationError(\n field,\n `\"${value}\" is not a valid number. Use decimal digits only.`\n );\n }\n if (num < 0n) {\n throw new ValidationError(field, `must be non-negative, got ${num}`);\n }\n if (num > U64_MAX) {\n throw new ValidationError(\n field,\n `must be <= ${U64_MAX} (u64 max), got ${num}`\n );\n }\n return num;\n}\n\n/**\n * Validate a u128 value.\n */\nexport function validateU128(value: string, field: string): bigint {\n let num: bigint;\n try {\n num = BigInt(value);\n } catch {\n throw new ValidationError(\n field,\n `\"${value}\" is not a valid number. Use decimal digits only.`\n );\n }\n if (num < 0n) {\n throw new ValidationError(field, `must be non-negative, got ${num}`);\n }\n if (num > U128_MAX) {\n throw new ValidationError(\n field,\n `must be <= ${U128_MAX} (u128 max), got ${num}`\n );\n }\n return num;\n}\n\n/**\n * Validate an i64 value.\n */\nexport function validateI64(value: string, field: string): bigint {\n let num: bigint;\n try {\n num = BigInt(value);\n } catch {\n throw new ValidationError(\n field,\n `\"${value}\" is not a valid number. Use decimal digits only, with optional leading minus.`\n );\n }\n if (num < I64_MIN) {\n throw new ValidationError(\n field,\n `must be >= ${I64_MIN} (i64 min), got ${num}`\n );\n }\n if (num > I64_MAX) {\n throw new ValidationError(\n field,\n `must be <= ${I64_MAX} (i64 max), got ${num}`\n );\n }\n return num;\n}\n\n/**\n * Validate an i128 value (trade sizes).\n */\nexport function validateI128(value: string, field: string): bigint {\n let num: bigint;\n try {\n num = BigInt(value);\n } catch {\n throw new ValidationError(\n field,\n `\"${value}\" is not a valid number. Use decimal digits only, with optional leading minus.`\n );\n }\n if (num < I128_MIN) {\n throw new ValidationError(\n field,\n `must be >= ${I128_MIN} (i128 min), got ${num}`\n );\n }\n if (num > I128_MAX) {\n throw new ValidationError(\n field,\n `must be <= ${I128_MAX} (i128 max), got ${num}`\n );\n }\n return num;\n}\n\n/**\n * Validate a basis points value (0-10000).\n */\nexport function validateBps(value: string, field: string): number {\n const t = requireDecimalUIntString(value, field);\n const bi = BigInt(t);\n if (bi > 10000n) {\n throw new ValidationError(\n field,\n `must be <= 10000 (100%), got ${t}`\n );\n }\n return Number(bi);\n}\n\n/**\n * Validate a u64 value.\n */\nexport function validateU64(value: string, field: string): bigint {\n return validateAmount(value, field);\n}\n\n/**\n * Validate a u16 value.\n */\nexport function validateU16(value: string, field: string): number {\n const t = requireDecimalUIntString(value, field);\n const bi = BigInt(t);\n if (bi > BigInt(U16_MAX)) {\n throw new ValidationError(\n field,\n `must be <= ${U16_MAX} (u16 max), got ${t}`\n );\n }\n return Number(bi);\n}\n","/**\n * Smart Price Router — automatic oracle selection for any token.\n *\n * Given a token mint, discovers all available price sources (DexScreener, Pyth, Jupiter),\n * ranks them by liquidity/reliability, and returns the best oracle config.\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type PriceSourceType = \"pyth\" | \"dex\" | \"jupiter\";\n\nexport interface PriceSource {\n type: PriceSourceType;\n /** Pool address (dex), Pyth feed ID (pyth), or mint (jupiter) */\n address: string;\n /** DEX id for dex sources */\n dexId?: string;\n /** Pair label e.g. \"SOL / USDC\" */\n pairLabel?: string;\n /** USD liquidity depth — higher is better */\n liquidity: number;\n /** Latest spot price in USD */\n price: number;\n /** Confidence score 0-100 (composite of liquidity, staleness, reliability) */\n confidence: number;\n}\n\nexport interface PriceRouterResult {\n mint: string;\n bestSource: PriceSource | null;\n allSources: PriceSource[];\n /** ISO timestamp of resolution */\n resolvedAt: string;\n}\n\n/** Options for {@link resolvePrice}. */\nexport interface ResolvePriceOptions {\n timeoutMs?: number;\n}\n\nconst DEFAULT_RESOLVE_TIMEOUT_MS = 15_000;\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction combineAbortSignals(signals: AbortSignal[]): AbortSignal {\n const already = signals.find((s) => s.aborted);\n if (already) {\n const c = new AbortController();\n c.abort(already.reason);\n return c.signal;\n }\n const active = signals.filter((s) => !s.aborted);\n if (active.length === 0) {\n const c = new AbortController();\n c.abort();\n return c.signal;\n }\n if (active.length === 1) return active[0];\n const ctrl = new AbortController();\n for (const s of active) {\n s.addEventListener(\"abort\", () => ctrl.abort(s.reason), { once: true });\n }\n return ctrl.signal;\n}\n\nconst SUPPORTED_DEX_IDS = new Set([\"pumpswap\", \"raydium\", \"meteora\"]);\n\nfunction parseDexScreenerPairs(json: unknown): PriceSource[] {\n if (!isRecord(json)) return [];\n const rawPairs = json.pairs;\n if (!Array.isArray(rawPairs)) return [];\n const sources: PriceSource[] = [];\n\n for (const pair of rawPairs) {\n if (!isRecord(pair)) continue;\n if (pair.chainId !== \"solana\") continue;\n const dexId = String(pair.dexId || \"\").toLowerCase();\n if (!SUPPORTED_DEX_IDS.has(dexId)) continue;\n\n let liquidity = 0;\n if (isRecord(pair.liquidity) && typeof pair.liquidity.usd === \"number\") {\n liquidity = pair.liquidity.usd;\n }\n if (liquidity < 100) continue;\n\n let confidence = 30;\n if (liquidity > 1_000_000) confidence = 90;\n else if (liquidity > 100_000) confidence = 75;\n else if (liquidity > 10_000) confidence = 60;\n else if (liquidity > 1_000) confidence = 45;\n\n const priceUsd = pair.priceUsd;\n const price =\n typeof priceUsd === \"string\" || typeof priceUsd === \"number\"\n ? parseFloat(String(priceUsd)) || 0\n : 0;\n\n let baseSym = \"?\";\n let quoteSym = \"?\";\n if (isRecord(pair.baseToken) && typeof pair.baseToken.symbol === \"string\") {\n baseSym = pair.baseToken.symbol;\n }\n if (isRecord(pair.quoteToken) && typeof pair.quoteToken.symbol === \"string\") {\n quoteSym = pair.quoteToken.symbol;\n }\n\n const addr = pair.pairAddress;\n sources.push({\n type: \"dex\",\n address: typeof addr === \"string\" ? addr : \"\",\n dexId,\n pairLabel: `${baseSym} / ${quoteSym}`,\n liquidity,\n price,\n confidence,\n });\n }\n\n sources.sort((a, b) => b.liquidity - a.liquidity);\n return sources.slice(0, 10);\n}\n\nfunction parseJupiterMintEntry(\n json: unknown,\n mint: string,\n): { price: number; mintSymbol: string } | null {\n if (!isRecord(json)) return null;\n const data = json.data;\n if (!isRecord(data)) return null;\n const row = data[mint];\n if (!isRecord(row)) return null;\n const rawPrice = row.price;\n if (rawPrice === undefined || rawPrice === null) return null;\n const price = parseFloat(String(rawPrice)) || 0;\n if (price <= 0) return null;\n let mintSymbol = \"?\";\n if (typeof row.mintSymbol === \"string\") mintSymbol = row.mintSymbol;\n return { price, mintSymbol };}\n\n// ---------------------------------------------------------------------------\n// Top Solana tokens with known Pyth feeds (feed ID → symbol)\n// ---------------------------------------------------------------------------\n\nexport const PYTH_SOLANA_FEEDS: Record<string, { symbol: string; mint: string }> = {\n // SOL\n \"ef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d\": { symbol: \"SOL\", mint: \"So11111111111111111111111111111111111111112\" },\n // BTC\n \"e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43\": { symbol: \"BTC\", mint: \"9n4nbM75f5Ui33ZbPYXn59EwSgE8CGsHtAeTH5YFeJ9E\" },\n // ETH\n \"ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace\": { symbol: \"ETH\", mint: \"7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs\" },\n // USDC\n \"eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a\": { symbol: \"USDC\", mint: \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\" },\n // USDT\n \"2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b\": { symbol: \"USDT\", mint: \"Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB\" },\n // BONK\n \"72b021217ca3fe68922a19aaf990109cb9d84e9ad004b4d2025ad6f529314419\": { symbol: \"BONK\", mint: \"DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263\" },\n // JTO\n \"b43660a5f790c69354b0729a5ef9d50d68f1df92107540210b9cccba1f947cc2\": { symbol: \"JTO\", mint: \"jtojtomepa8beP8AuQc6eXt5FriJwfFMwQx2v2f9mCL\" },\n // JUP\n \"0a0408d619e9380abad35060f9192039ed5042fa6f82301d0e48bb52be830996\": { symbol: \"JUP\", mint: \"JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN\" },\n // PYTH\n \"0bbf28e9a841a1cc788f6a361b17ca072d0ea3098a1e5df1c3922d06719579ff\": { symbol: \"PYTH\", mint: \"HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3\" },\n // RAY\n \"91568bae053f70f0c3fbf32eb55df25ec609fb8a21cfb1a0e3b34fc3caa1eab0\": { symbol: \"RAY\", mint: \"4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R\" },\n // ORCA\n \"37505261e557e251f40c2c721e52c4c8bfb2e54a12f450d0e24078276ad51b95\": { symbol: \"ORCA\", mint: \"orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE\" },\n // MNGO\n \"f9abf5eb70a2e68e21b72b68cc6e0a4d25e1d77e1ec16eae5b93068a2cb81f90\": { symbol: \"MNGO\", mint: \"MangoCzJ36AjZyKwVj3VnYU4GTonjfVEnJmvvWaxLac\" },\n // MSOL\n \"c2289a6a43d2ce91c6f55caec370f4acc38a2ed477f58813334c6d03749ff2a4\": { symbol: \"MSOL\", mint: \"mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So\" },\n // JITOSOL\n \"67be9f519b95cf24338801051f9a808eff0a578ccb388db73b7f6fe1de019ffb\": { symbol: \"JITOSOL\", mint: \"J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn\" },\n // WIF\n \"4ca4beeca86f0d164160323817a4e42b10010a724c2217c6ee41b54e6c5c4b03\": { symbol: \"WIF\", mint: \"EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm\" },\n // RENDER\n \"3573eb14b04aa0e4f7cf1e7ae1c2a0e3bc6100b2e476876ca079e10e2c42d7c6\": { symbol: \"RENDER\", mint: \"rndrizKT3MK1iimdxRdWabcF7Zg7AR5T4nud4EkHBof\" },\n // W\n \"eff7446475e218517566ea99e72a4abec2e1bd8498b43b7d8331e29dcb059389\": { symbol: \"W\", mint: \"85VBFQZC9TZkfaptBWjvUw7YbZjy52A6mjtPGjstQAmQ\" },\n // TNSR\n \"05ecd4597cd48fe13d6cc3596c62af4f9675aee06e2e0ca164a73be4b0813f3b\": { symbol: \"TNSR\", mint: \"TNSRxcUxoT9xBG3de7PiJyTDYu7kskLqcpddxnEJAS6\" },\n // HNT\n \"649fdd7ec08e8e2a20f425729854e90293dcbe2376abc47197a14da6ff339756\": { symbol: \"HNT\", mint: \"hntyVP6YFm1Hg25TN9WGLqM12b8TQmcknKrdu1oxWux\" },\n // MOBILE\n \"ff4c53361e36a9b1caa490f1e46e07e3c472d54d2a4856a1e4609bd4db36bff0\": { symbol: \"MOBILE\", mint: \"mb1eu7TzEc71KxDpsmsKoucSSuuoGLv1drys1oP2jh6\" },\n // IOT\n \"8bdd20f0c68bf7370a19389bbb3d17c1db7956c38efa08b2f3dd0e5db9b8c1ef\": { symbol: \"IOT\", mint: \"iotEVVZLEywoTn1QdwNPddxPWszn3zFhEot3MfL9fns\" },\n};\n\n// Reverse lookup: mint → feed ID\nconst MINT_TO_PYTH_FEED = new Map<string, { feedId: string; symbol: string }>();\nfor (const [feedId, info] of Object.entries(PYTH_SOLANA_FEEDS)) {\n MINT_TO_PYTH_FEED.set(info.mint, { feedId, symbol: info.symbol });\n}\n\n// ---------------------------------------------------------------------------\n// DexScreener fetcher\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_FETCH_TIMEOUT_MS = 10_000;\n\nfunction effectiveSignal(signal?: AbortSignal): AbortSignal {\n return signal ?? AbortSignal.timeout(DEFAULT_FETCH_TIMEOUT_MS);\n}\n\nasync function fetchDexSources(mint: string, signal?: AbortSignal): Promise<PriceSource[]> {\n try {\n const resp = await fetch(\n `https://api.dexscreener.com/latest/dex/tokens/${encodeURIComponent(mint)}`,\n {\n signal: effectiveSignal(signal),\n headers: { \"User-Agent\": \"percolator/1.0\" },\n },\n );\n if (!resp.ok) return [];\n const json: unknown = await resp.json();\n return parseDexScreenerPairs(json);\n } catch {\n return [];\n }\n}\n\n// ---------------------------------------------------------------------------\n// Pyth lookup\n// ---------------------------------------------------------------------------\n\nfunction lookupPythSource(mint: string): PriceSource | null {\n const entry = MINT_TO_PYTH_FEED.get(mint);\n if (!entry) return null;\n return {\n type: \"pyth\",\n address: entry.feedId,\n pairLabel: `${entry.symbol} / USD (Pyth)`,\n liquidity: Infinity, // Pyth is considered deep liquidity\n price: 0, // We don't fetch live price here; caller can enrich\n confidence: 95, // Pyth is highest reliability for supported tokens\n };\n}\n\n// ---------------------------------------------------------------------------\n// Jupiter price fallback\n// ---------------------------------------------------------------------------\n\nasync function fetchJupiterSource(mint: string, signal?: AbortSignal): Promise<PriceSource | null> {\n try {\n const resp = await fetch(\n `https://api.jup.ag/price/v2?ids=${encodeURIComponent(mint)}`,\n {\n signal: effectiveSignal(signal),\n headers: { \"User-Agent\": \"percolator/1.0\" },\n },\n );\n if (!resp.ok) return null;\n const json: unknown = await resp.json();\n const row = parseJupiterMintEntry(json, mint);\n if (!row) return null;\n return {\n type: \"jupiter\",\n address: mint,\n pairLabel: `${row.mintSymbol} / USD (Jupiter)`,\n liquidity: 0, // Jupiter aggregator — no single pool liquidity\n price: row.price,\n confidence: 40, // Fallback — lower confidence\n };\n } catch {\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Main resolver\n// ---------------------------------------------------------------------------\n\nexport async function resolvePrice(\n mint: string,\n signal?: AbortSignal,\n options?: ResolvePriceOptions,\n): Promise<PriceRouterResult> {\n const timeoutMs = options?.timeoutMs ?? DEFAULT_RESOLVE_TIMEOUT_MS;\n const timeoutSignal = AbortSignal.timeout(timeoutMs);\n const effectiveSignal = signal\n ? combineAbortSignals([signal, timeoutSignal])\n : timeoutSignal;\n\n const [dexSources, jupiterSource] = await Promise.all([\n fetchDexSources(mint, effectiveSignal),\n fetchJupiterSource(mint, effectiveSignal),\n ]);\n\n const pythSource = lookupPythSource(mint);\n\n const allSources: PriceSource[] = [];\n\n // Add Pyth if available (highest priority for supported tokens)\n if (pythSource) {\n // Enrich Pyth price from Jupiter or DEX if available\n const refPrice = dexSources[0]?.price || jupiterSource?.price || 0;\n pythSource.price = refPrice;\n allSources.push(pythSource);\n }\n\n // Add DEX sources\n allSources.push(...dexSources);\n\n // Add Jupiter as fallback\n if (jupiterSource) {\n allSources.push(jupiterSource);\n }\n\n // Sort by confidence descending (already accounts for liquidity/reliability)\n allSources.sort((a, b) => b.confidence - a.confidence);\n\n return {\n mint,\n bestSource: allSources[0] || null,\n allSources,\n resolvedAt: new Date().toISOString(),\n };\n}\n"],"mappings":"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AAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA;AAAA,EAEA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,IAAI;AAAA,IACF,MAAM;A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","names":["dv","PublicKey","PublicKey","AccountKind","PublicKey","PublicKey","PublicKey","TOKEN_PROGRAM_ID","ENGINE_BITMAP_OFF_V0","dv","readU16LE","readU64LE","readI64LE","readU128LE","readI128LE","results","PublicKey","PublicKey","readU64LE","dv","readU128LE","readU8","PublicKey","TOKEN_PROGRAM_ID","PublicKey","SystemProgram","SYSVAR_RENT_PUBKEY","SYSVAR_CLOCK_PUBKEY","TOKEN_PROGRAM_ID","PublicKey","PublicKey","readU64LE","readU16LE","TOKEN_PROGRAM_ID","SystemProgram","SYSVAR_RENT_PUBKEY","SYSVAR_CLOCK_PUBKEY","SYSVAR_CLOCK_PUBKEY","SYSVAR_CLOCK_PUBKEY","TransactionInstruction","TransactionInstruction","PublicKey","effectiveSignal"]}