@panoptic-eng/sdk 1.0.38 → 1.0.40

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.
Files changed (81) hide show
  1. package/dist/cow/index.d.ts +804 -5
  2. package/dist/cow/index.d.ts.map +1 -0
  3. package/dist/cow/index.js +5268 -5
  4. package/dist/cow/index.js.map +1 -0
  5. package/dist/{cow-DB8siv6M.js → cow-tRUtAUZy.js} +2 -3
  6. package/dist/{getTrackedPositionIds-zYPIs5dt.js → getTrackedPositionIds-ms3W9dYB.js} +1 -2
  7. package/dist/greeks-GysWXct-.js +1 -2
  8. package/dist/index.d.ts +5752 -4
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +11952 -2130
  11. package/dist/index.js.map +1 -1
  12. package/dist/{irm-ChkvYphK.js → irm-SPC2KxLA.js} +321 -3
  13. package/dist/panoptic/v2/greeks/index.d.ts +277 -4
  14. package/dist/panoptic/v2/greeks/index.d.ts.map +1 -0
  15. package/dist/panoptic/v2/greeks/index.js +620 -2
  16. package/dist/panoptic/v2/greeks/index.js.map +1 -0
  17. package/dist/panoptic/v2/index.d.ts +14633 -7
  18. package/dist/panoptic/v2/index.d.ts.map +1 -0
  19. package/dist/panoptic/v2/index.js +27875 -9
  20. package/dist/panoptic/v2/index.js.map +1 -0
  21. package/dist/panoptic/v2/react-public.d.ts +14779 -15
  22. package/dist/panoptic/v2/react-public.d.ts.map +1 -1
  23. package/dist/panoptic/v2/react-public.js +29463 -89
  24. package/dist/panoptic/v2/react-public.js.map +1 -1
  25. package/dist/{router-tCRa0ekE.js → router-BTfbaRfg.js} +2 -3
  26. package/dist/{router-BCUJkY8j.js → router-mLWy0MD9.js} +3 -4
  27. package/dist/test/index.d.ts +3 -3
  28. package/dist/test/index.d.ts.map +1 -1
  29. package/dist/test/index.js +2 -2
  30. package/dist/{transactionFees-CVi2TrJh.js → transactionFees-C_Qx07mx.js} +1 -2
  31. package/dist/uniswap/index.d.ts +813 -78
  32. package/dist/uniswap/index.d.ts.map +1 -1
  33. package/dist/uniswap/index.js +5884 -13
  34. package/dist/uniswap/index.js.map +1 -1
  35. package/dist/{v2-BxtzpUnV.js → v2-DG7qG6di.js} +4 -5
  36. package/dist/vault-transaction-fees.d.ts +63 -2
  37. package/dist/vault-transaction-fees.d.ts.map +1 -0
  38. package/dist/vault-transaction-fees.js +174 -2
  39. package/dist/vault-transaction-fees.js.map +1 -0
  40. package/dist/{writes-D3bj1wth.js → writes-Xp9Wa8GQ.js} +2 -3
  41. package/dist/zodiac/index.d.ts.map +1 -1
  42. package/package.json +4 -3
  43. package/dist/cow/types.d.ts +0 -4
  44. package/dist/cow/types.js +0 -0
  45. package/dist/cow-DB8siv6M.js.map +0 -1
  46. package/dist/getTrackedPositionIds-zYPIs5dt.js.map +0 -1
  47. package/dist/greeks-GysWXct-.js.map +0 -1
  48. package/dist/hypoVault/vaultDisplayNames.d.ts +0 -2
  49. package/dist/hypoVault/vaultDisplayNames.js +0 -4
  50. package/dist/index-BhEBx83X.d.ts +0 -9760
  51. package/dist/index-BhEBx83X.d.ts.map +0 -1
  52. package/dist/index-Bo9tHtD7.d.ts +0 -1901
  53. package/dist/index-Bo9tHtD7.d.ts.map +0 -1
  54. package/dist/index-CttjEZ-S.d.ts +0 -275
  55. package/dist/index-CttjEZ-S.d.ts.map +0 -1
  56. package/dist/index-DktZq9Kb.d.ts +0 -261
  57. package/dist/index-DktZq9Kb.d.ts.map +0 -1
  58. package/dist/irm-ChkvYphK.js.map +0 -1
  59. package/dist/irm-D2WTHtuo.d.ts +0 -5667
  60. package/dist/irm-D2WTHtuo.d.ts.map +0 -1
  61. package/dist/irm-D5plRhpB.d.ts +0 -32
  62. package/dist/irm-D5plRhpB.d.ts.map +0 -1
  63. package/dist/panoptic/v2/types/index.d.ts +0 -3
  64. package/dist/panoptic/v2/types/index.js +0 -0
  65. package/dist/quote-DeHNUR0Z.d.ts +0 -52
  66. package/dist/quote-DeHNUR0Z.d.ts.map +0 -1
  67. package/dist/router-BCUJkY8j.js.map +0 -1
  68. package/dist/router-tCRa0ekE.js.map +0 -1
  69. package/dist/src-CRAtPwWk.js +0 -321
  70. package/dist/src-CRAtPwWk.js.map +0 -1
  71. package/dist/transactionFees-CVi2TrJh.js.map +0 -1
  72. package/dist/transactionFees-DzDyt50k.d.ts +0 -63
  73. package/dist/transactionFees-DzDyt50k.d.ts.map +0 -1
  74. package/dist/types-Cad5m4Td.d.ts +0 -246
  75. package/dist/types-Cad5m4Td.d.ts.map +0 -1
  76. package/dist/types-DM0nxlZr.d.ts +0 -128
  77. package/dist/types-DM0nxlZr.d.ts.map +0 -1
  78. package/dist/v2-BxtzpUnV.js.map +0 -1
  79. package/dist/vaultDisplayNames-CKpz51Hu.js +0 -0
  80. package/dist/vaultDisplayNames-Q6htUcch.d.ts +0 -2
  81. package/dist/writes-D3bj1wth.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["tokenURI: string","message: string","cause?: Error","walletChainId: bigint","expectedChainId: bigint","cause?: Error","requestedPool: Address","configuredPool: Address","elapsedMs: bigint","blocksProcessed: bigint","blocksRemaining: bigint","providerBlock: bigint","expectedBlock: bigint","label: string","index: number","functionName: string","currentCount: bigint","attemptedAdd: bigint","level: SafeMode","reason: string","blockTimestamp: bigint","currentTimestamp: bigint","stalenessSeconds: bigint","healthStatus: PoolHealthStatus","lastUpdate: bigint","currentTime: bigint","method: string","retriesAttempted: bigint","code: bigint","rpcMessage: string","dataType: 'poolMeta' | 'positions' | 'positionMeta'","key: string","tickLimitLow: bigint","tickLimitHigh: bigint","token: Address","operation: string","diagnostics: BatchDiagnostic[]","tokenAddress: Address","token0: Address","token1: Address","startBlock: bigint","endBlock: bigint","points: number","value: bigint","oraclePack: bigint","blockTimestamp: bigint","timestamp: bigint","solvent: bigint","numberOfTicks: bigint","cause?: Error","tokenAddress: Address","assetsRequested: bigint","assetBalance: bigint","parameterType: bigint","currentTick: bigint","token: Address","from: Address","amount: bigint","balance: bigint","panopticQueryAbi","errorConstructors: Record<\n string,\n (args: readonly unknown[], cause?: Error) => PanopticError\n>","error: unknown","found: { errorName: string; args: readonly unknown[] } | null","current: Record<string, unknown> | null","errorName: string","args: readonly unknown[]","originalError: unknown","selector: `0x${string}`","i: { type: string }","foundData: `0x${string}` | null","error: PanopticError","errorClass: new (...args: unknown[]) => T","left: bigint","right: bigint","period: bigint","emaPeriods: bigint","maxTicksDelta: bigint","maxClampDelta: bigint","state: DiagnosticOracleState","parameters: OracleRiskParameters","onchainLevel: bigint","causes: OracleSafeModeCause[]","candidateEpochs: bigint[]","decodePositionBalance","balanceData: bigint","value: bigint","logs: Log[]","events: PanopticEvent[]","client: PublicClient","hash: Hash","confirmations?: bigint","params: SubmitWriteParams","hash","gasOverrides: Record<string, unknown>","params: ValidateBatchParams","diagnostics: BatchDiagnostic[]","params: BuildBatchDispatchArgsParams","tickAndSpreadLimits: TickAndSpreadLimits[]","directory: string","fsPromises: typeof FsPromises | null","pathModule: typeof Path | null","key: string","value: string","prefix: string","result: string[]","chainId: bigint","poolAddress: Address","account: Address","tokenId: bigint","key: string","value: string","prefix: string","result: string[]","keysToDelete: string[]","value: unknown","_key: string","space?: string | number","text: string","params: GetBlockMetaParams","params: ResolveBlockNumbersParams","blockNumber: bigint","targetTimestamp: number","low: bigint","high: bigint","params: EstimateBlockNumbersParams","params: MulticallReadParams<TContracts>","results: MulticallResult<unknown>[]","strike: bigint","encodedStrike: bigint","legIndex: bigint","address: Address","tickSpacing: bigint","vegoid: bigint","bytes: number[]","vegoid","poolIdHex: Hex","tokenId: bigint","value: bigint","bitPosition: bigint","leg: EncodeLegParams","legs: DecodedLeg[]","poolId: bigint","config: LegConfig","legIndex: bigint","builder: TokenIdBuilder","leg: EncodeLegParams","config: Omit<LegConfig, 'tokenType' | 'asset'> & { asset?: bigint }","config: LoanCreditConfig","leg: DecodedLeg","tickSpacing: bigint","tokenId: bigint","vegoid","expectedPoolId: bigint","plan: SfpmSwapPlan","sfpmV3Abi","params: FetchSfpmV3PoolIdParams","vegoid","sfpmV3Abi","params: EnsureSfpmV3PoolInitializedParams","WIDE_LIMITS: [number, number]","slippageBps: bigint","params: SfpmSwapPlanParams","invertedLimits: [number, number]","swapOn: 'mint' | 'burn'","packed: bigint","half: bigint","err: unknown","params: QuoteSfpmSwapParams","sfpmV3Abi","chainId: bigint","cause?: Error","UINT128_MAX","UNISWAP_V3_ADDRESSES: Record<number, UniswapV3Addresses>","chainId: number | bigint","overrides?: Partial<UniswapV3Addresses>","BPS_DENOMINATOR","params: QuoteV3ExactInParams","err: unknown","params: GetUniswapV3PoolFromIdParams","params: GetUniswapV4PoolKeyFromIdParams","params: GetEnforcedTickLimitsParams","params: GetChunkLiquiditiesParams","params: GetFactoryTokenURIParams","params: GetFactoryOwnerOfParams","params: GetFactoryConstructMetadataParams","params: GetPanopticPoolAddressParams","params: MinePoolAddressParams","result: readonly [bigint, bigint]","params: SimulateDeployNewPoolParams","result","params: GetPanopticPoolFromPoolIdParams","params: ResolvePanopticPoolFromPoolIdParams","err: unknown","Q192","exponent: bigint","value: bigint","value: string","formatRatio","numerator: bigint","denominator: bigint","precision: bigint","leftNumerator: bigint","leftDenominator: bigint","rightNumerator: bigint","rightDenominator: bigint","tick: bigint","sqrtPriceX96: bigint","decimals0: bigint","decimals1: bigint","price: string","tickLower: bigint","tickUpper: bigint","feeBps: bigint","tickSpacing: bigint","currentTick: bigint","toleranceBps: bigint","DEFAULT_MINT_BUFFER: MintBufferRatio","required: bigint","buffer: MintBufferRatio","required0: bigint","required1: bigint","balance: bigint","erc20Abi","params: GetPoolMetadataParams","underlyingPoolId: string","fee: bigint","tickSpacing: bigint","params: GetPoolParams","vegoid","SECONDS_PER_YEAR","collateralTracker0: CollateralTracker","collateralTracker1: CollateralTracker","riskEngine: RiskEngine","params: GetUtilizationParams","collateralToken0: Address","collateralToken1: Address","poolData: readonly [bigint, bigint, bigint, bigint]","totalSupply: bigint","params: GetOracleStateParams","params: GetOracleRiskParametersParams","params: GetRiskParametersParams","params: {\n client: PublicClient\n poolAddress: Address\n builderCode: bigint\n}","poolId: bigint","poolKeyBytes: `0x${string}`","params: FetchPoolIdParams","Q192","tick: bigint","isAssetToken0: boolean","numerator: bigint","denominator: bigint","leg: Pick<TokenIdLeg, 'asset'>","assetIndex?: bigint","leg: TokenIdLeg","m: bigint","qCurrentTick: bigint","qStrikeTick: bigint","qMintTick: bigint","_definedRisk: boolean","swapAtMint: boolean","itmOffsetNotional: bigint","halfWidthTick: bigint","isPut: boolean","sqrtK","sqrtPm","sqrtR","rX192","diff","diffSqX192","tokenType: bigint","legs: Pick<TokenIdLeg, 'tokenType' | 'isLong'>[]","currentTick: bigint","mintTick: bigint","positionSize: bigint","poolTickSpacing: bigint","definedRisk: boolean","swapAtMint?: boolean","v: bigint","mintTick: bigint | undefined","vDelta","isPut","debtDelta","itmDelta","vDelta: bigint","delta: bigint","fromAsset: bigint","vaultAssetIndex: 0n | 1n","input: PositionGreeksInput","sum","input: Omit<PositionGreeksInput, 'assetIndex' | 'swapAtMint'> & {\n assetIndex: 0n | 1n\n }","positions: PositionGreeksInput[]","input: PositionGreeksInput & { swapAtMint: boolean }","encodedStrike: bigint","index: bigint","leg: bigint","decodeTickSpacing","tokenId: bigint","encodedPosition: bigint","legs: LegParams[]","hex: string","length: number","balance: bigint","params: GetPositionParams","legs: TokenIdLeg[]","params: GetPositionsParams","_meta","ids: bigint[]","positionBalances: readonly bigint[]","meta: BlockMeta","positions: Position[]","candidates: bigint[][]","candidate: bigint[]","validTokenIds: bigint[]","validBalances: bigint[]","params: GetPositionGreeksParams","params: GetAccountPremiaParams","_meta","params: GetPositionsWithPremiaParams","positions: PositionWithPremia[]","legs: TokenIdLeg[]","client: Client","results: readonly MulticallBlockResult[]","index: number","label: string","FP96","Q128","convert0to1","amount: bigint","sqrtPriceX96: bigint","convert1to0","params: IsLiquidatableParams","collateralToken0: Address","collateralToken1: Address","calls: MulticallBlockCall[]","denominatedInToken: bigint","pool: {\n collateralTracker0: { address: Address }\n collateralTracker1: { address: Address }\n}","params: GetAccountCollateralParams","collateralToken0: Address","collateralToken1: Address","token0: TokenCollateral","token1: TokenCollateral","params: GetAccountSummaryBasicParams","params: GetAccountSummaryRiskParams","params: GetNetLiquidationValueParams","params: GetNetLiquidationValuesParams","params: GetLiquidationPricesParams","MIN_TICK","MAX_TICK","SECONDS_PER_YEAR","erc20Abi","params: GetCollateralDataParams","_meta","poolData","totalShares","interestRate","depositedAssets","insideAMM","creditedShares","utilization","totalAssets","borrowRate","supplyRate","params: GetCurrentRatesParams","collateralToken0: Address","collateralToken1: Address","params: GetInterestStateParams","WAD","utilizationBps: bigint","bits: bigint","value: bigint","fieldName: string","inputs: IrmMarketStateInputs","utilizationPct: number","ratePerSecWad: bigint","borrowRatePerSecWad: bigint","utilizationWad: bigint","params: {\n client: PublicClient\n collateralTrackerAddress: Address\n blockNumber?: bigint\n}","params: {\n client: PublicClient\n collateralTrackerAddress: Address\n points?: number\n blockNumber?: bigint\n}","curvePoints: IrmPoint[]","multicallAbi","params: SimulateWithTokenFlowParams","multicallData: Hex[]","data: Hex","params: GetPoolTokensParams","Q128","sqrtPriceX96: bigint","convert0to1","amount: bigint","convert1to0","fromTokenIndex: bigint","toTokenIndex: bigint","params: RecoverSnapshotParams","isRangeLimitError","error: unknown","parts: string[]","current: unknown","params: {\n client: PublicClient\n poolAddress: Address\n account: Address\n fromBlock: bigint\n toBlock: bigint\n}","params: {\n client: PublicClient\n account: Address\n events: SnapshotEventLog[]\n}","event: SnapshotEventLog","params: {\n input: Hex\n from: Address\n to: Address | null\n account?: Address\n pool?: Address\n rolesContext?: RolesSnapshotContext\n}","params: RecoverSnapshotFromTxParams","input: `0x${string}`","candidates: DispatchCalldata[]","account: Address","txFrom: Address","match: DispatchCalldata | null","results: DispatchCalldata[]","params: {\n client: PublicClient\n poolAddress: Address\n account: Address\n positionIds: bigint[]\n blockNumber?: bigint\n}","params: GetTrackedPositionIdsParams","tokenId: bigint","params: GetOpenPositionIdsParams","snapshot: SnapshotRecoveryResult | null","tokenAddress: Address","token0: Address","token1: Address","resolvePositionIds","explicit: bigint[] | undefined","storage: StorageAdapter | undefined","chainId: bigint","poolAddress: Address","account: Address","error: unknown","kind: WidthZeroLegKind","poolId: bigint","asset: bigint","tokenType: bigint","currentTick: bigint","tickSpacing: bigint","existingPositionIds: bigint[]","positionSize: bigint","strike: bigint","optionRatio?: bigint","params: BuildCreditWrappedDispatchParams","swapping: TickAndSpreadLimits","notSwapping: TickAndSpreadLimits","dispatch","wrapped: DispatchIntent","params: SimulateDispatchParams","tokenFlow: TokenFlow","data: Hex | undefined","data","data: DispatchSimulation","BPS_DENOMINATOR","params: BuildTokenShortfallRecoveryDispatchParams","error: unknown","current: unknown","args: Partial<\n Pick<NotEnoughTokensError, 'tokenAddress' | 'assetsRequested' | 'assetBalance'>\n >","estimatedAmountIn: bigint","slippageBps: bigint","numerator: bigint","denominator: bigint","tokenFlow: TokenFlow","tokenInIndex: 0n | 1n","tokenIndex: 0n | 1n","tokenOutIndex: 0n | 1n","params: TokenShortfallRecoveryQuoteParams","error: NotEnoughTokensError","initialRequiredOutput: bigint","MAX_UINT64","params: EstimateCollateralRequiredParams","effectiveTick: bigint","params: GetMaxPositionSizeParams","positionIds: bigint[]","params: {\n client: PublicClient\n poolAddress: Address\n account: Address\n tokenId: bigint\n existingPositionIds: bigint[]\n low: bigint\n high: bigint\n precisionDivisor: bigint\n swapAtMint: boolean\n usePremiaAsCollateral: boolean\n}","positionSize: bigint","params: {\n client: PublicClient\n poolAddress: Address\n account: Address\n tokenId: bigint\n existingPositionIds: bigint[]\n positionSize: bigint\n swapAtMint: boolean\n usePremiaAsCollateral: boolean\n}","tickLimits: readonly [number, number, number]","tickLimits","params: GetRequiredCreditForITMParams","tickTriplet: readonly [number, number, number]","params: GetItmAmountsParams","Q192","POOL_ID_MASK","value: bigint","tokenIndex: 0n | 1n","signedAmount: bigint","signedTick: bigint","poolId: bigint","baseTokenId: bigint","neutralLegs: NeutralLeg[]","prepend: boolean","params: CreateFlowNeutralTokenIdParams","credit: RequiredCreditForITM","pinnedBlock","shortfall: ReturnType<typeof getNotEnoughTokensError>","targets: [bigint, bigint]","best:\n | {\n tokenId: bigint\n neutralLegs: NeutralLeg[]\n residual: RequiredCreditForITM\n residualScore: bigint\n }\n | undefined","previousTokenId: bigint | undefined","indices","neutralLegs","combined","residual: RequiredCreditForITM","residual","index: 0n | 1n","amount: bigint","abs","indices: (0n | 1n)[]","params: GetMaxWithdrawableParams","params: GetMaxRedeemParams","params: {\n client: PublicClient\n collateralTrackerAddress: Address\n account: Address\n assets: bigint\n positionIdList: bigint[]\n usePremiaAsCollateral: boolean\n}","SHARED_RULE: Partial<Record<CollateralStrategyKind, CollateralStrategyKind>>","kind: CollateralStrategyKind","a: DecodedLeg","b: DecodedLeg","tokenId: bigint","groups: StrategyGroup[]","leg: DecodedLeg","unrecognized: StrategyGroup","legIndices: bigint[]","params: EstimateCollateralBreakdownParams","isolated: (bigint | null)[]","total: bigint | null","client: PublicClient","poolAddress: Address","tokenIndex: 0 | 1","providedAddress?: Address","params: ERC4626PreviewParams","params: GetGuardianUnlockStateParams","params: GetSafeModeParams","params: GetPortfolioValueParams","params: CheckCollateralAcrossTicksParams","MIN_TICK","MAX_TICK","dataPoints: CollateralDataPoint[]","params: OptimizeTokenIdRiskPartnersParams","effectiveTick: bigint","params: GetPoolLiquiditiesParams","amount: bigint","decimals: bigint","precision: bigint","amount: string","flow: TokenFlow","decimals0: bigint","decimals1: bigint","precision0: bigint","precision1: bigint","TEN","formatRatio","numerator: bigint","denominator: bigint","precision: bigint","bps: bigint","util: bigint","percent: string","wad: bigint","precision: bigint","rateWad: bigint","value: string","SECONDS_PER_YEAR","ratePerSecondWad: bigint","precision: bigint","config: PoolFormatterConfig","tick: bigint","precision: bigint","price: string","amount: bigint","amount: string","TEN","formatRatio","numerator: bigint","denominator: bigint","precision: bigint","chainId: bigint","address: Address","tokenListId: string","token0Symbol: string","token1Symbol: string","feeBps: bigint","numerator: bigint","denominator: bigint","precision: bigint","address: string","timestamp: bigint","locale?: string","options?: Intl.DateTimeFormatOptions","ms: bigint","minutes","seconds: bigint","blockNumber: bigint","gas: bigint","hash: string","value: bigint","tokenId: bigint","poolId: bigint","formatted: string","wei: bigint","params: GetAccountGreeksParams","targetBlock","_meta","positions: AccountGreeksResult['positions']","params: CalculateAccountGreeksPureParams","totalValue: bigint[]","totalDelta: bigint[]","positionResults: AccountGreeksCurveResult['positions']","posValues: bigint[]","posDeltas: bigint[]","posGammas: bigint[]","MIN_TICK","MAX_TICK","Q128","a: bigint","b: bigint","convert0to1","amount: bigint","sqrtPriceX96: bigint","convert1to0","params: GetMarginBufferParams","collateralToken0: Address","collateralToken1: Address","calls: MulticallBlockCall[]","usageBps0: bigint | null","usageBps1: bigint | null","crossMarginUsageBps: bigint | null","mintableMarginBinding: bigint | null","required: bigint | undefined","balance: bigint | undefined","denominatedInToken: 0 | 1","lowerLiquidationTick: bigint | null","upperLiquidationTick: bigint | null","liquidationDistance: bigint | null","params: GetDeltaHedgeParamsInput","currentTick: bigint","tickSpacing: bigint","poolMeta: BlockMeta","primaryAsset: bigint","currentDelta: bigint","hedgeLeg: LegConfig","simulatedTickAfter: bigint | undefined","collateralAddresses: [Address, Address]","blockNumber: bigint","client: Client","e: unknown","client: Client","collateralTrackerAddresses: Address[]","chainId: number","blockNumber?: bigint","Q128","amount: bigint","sqrtPriceX96: bigint","params: GetAccountBuyingPowerParams","collateralToken0: Address","collateralToken1: Address","calls: MulticallBlockCall[]","params: SimulateOpenPositionParams","tickLimits: readonly [number, number, number]","tickLimits","perPositionCollateralReqs: { token0: bigint; token1: bigint }[]","decoded","data: OpenPositionSimulation","params: GetOpenPositionPreviewParams","tokenShortfall: NotEnoughTokensError | null","params: GetNativeTokenPriceParams","params: GetAccountHistoryParams","trades: AccountTrade[]","params: GetUniswapFeeHistoryParams","_meta","initialFees0: bigint | null","initialFees1: bigint | null","snapshots: UniswapFeeSnapshot[]","client: PublicClient","blockNumbers: (bigint | undefined)[]","legs: StreamiaLeg[]","poolConfig: PoolVersionConfig","blockData: UniswapBlockData","blockNumber: bigint | undefined","uniqueTicks: number[]","poolAddress: Address","stateViewAddress: Address","poolId: `0x${string}`","params: GetStreamiaHistoryParams","_meta","initialUniswapFees0: bigint | null","initialUniswapFees1: bigint | null","snapshots: StreamiaSnapshot[]","params: GetUniswapV3PoolInfoParams","startTick: number","tickSpacing: number","nTicks: bigint","params: GetUniswapV3PoolLiquiditiesParams","poolKey: UniswapV4PoolKey","_params: ResolveUniswapV4PoolKeyParams","params: GetUniswapV4PoolBasicStateParams","client: Pick<PublicClient, 'multicall'>","address: Address","blockNumber?: bigint","params: GetUniswapV4PoolInfoParams","params: GetUniswapV4PoolLiquiditiesParams","error: unknown","params: GetUniswapV3LpPositionStateParams","feeGrowthInsideCurrentX128: bigint","feeGrowthInsideLastX128: bigint","liquidity: bigint","params: GetUniswapV4LpPositionStateParams","params: GetPriceHistoryParams","_meta","snapshots: PriceSnapshot[]","client: PublicClient","blockNumber: bigint | undefined","poolConfig: PoolVersionConfig","tokenId: bigint","callName: string","cause?: unknown","params: GetPositionEnrichmentDataParams","client: PublicClient","queryAddress: Address","positions: PositionInput[]","currentTick: number","blockNumber: bigint | undefined","_meta: BlockMeta","panopticQueryAbi","entries: [string, PositionEnrichmentResult][]","params: DetectReorgParams","reorgBlock: bigint","reorgDepth: bigint","params: SaveCheckpointParams","checkpoint: SyncCheckpoint","storage: StorageAdapter","chainId: bigint","poolAddress: Address","account: Address","client: PublicClient","fromBlock: bigint","toBlock: bigint","previousHash: Hash | null","params: GetSyncStatusParams","params: EventReconstructionParams","mintEvents: MintEvent[]","burnEvents: BurnEvent[]","rangeFromBlock: bigint","rangeToBlock: bigint","mint","openPositions: bigint[]","closedPositions: bigint[]","error: unknown","messages: string[]","current: unknown","client: PublicClient","poolAddress: Address","foundBlock: bigint | null","params: SyncPositionsParams","positionIds: bigint[]","positionsKey","storedData: StoredPositionData","lastBlock: bigint","lastBlockHash: Hash","client: PublicClient","poolAddress: Address","poolMetaKey: string","storage: StorageAdapter","poolMeta: StoredPoolMeta","params: SaveClosedPositionParams","history: ClosedPosition[]","params: GetTradeHistoryParams","params: GetRealizedPnLParams","params: Omit<\n GetTradeHistoryParams,\n 'limit' | 'offset' | 'closureReason' | 'fromBlock' | 'toBlock'\n >","chunk: LiquidityChunkKey","key: string","params: AddTrackedChunksParams","trackedKeys: Set<string>","params: RemoveTrackedChunksParams","params: GetTrackedChunksParams","params: GetChunkSpreadsParams","netLiquidity: bigint","removedLiquidity: bigint","vegoid: bigint","vegoid","params: ScanChunksParams","chunks: ScannedChunk[]","params: GetPositionChunkDataParams","_meta","positions: PositionChunkData[]","legs: LegChunkData[]","params: AddPendingPositionParams","pending: PendingPosition[]","params: GetPendingPositionsParams","params: ConfirmPendingPositionParams","params: FailPendingPositionParams","currentBlock: bigint","maxAgeBlocks: bigint","publicBroadcaster: TxBroadcaster","signedTx: `0x${string}`","client: PublicClient","account: Address","params: ApproveParams","params: ApprovePoolParams","params: CheckApprovalParams","params: DepositParams","params: WithdrawParams","params: WithdrawWithPositionsParams","params: MintParams","params: RedeemParams","explicit: bigint[] | undefined","storage: StorageAdapter | undefined","chainId: bigint | undefined","poolAddress: Address","account: Address","savePositionIds","storage: StorageAdapter","chainId: bigint","positionIds: bigint[]","params: OpenPositionParams","tickLimits: readonly [number, number, number]","tickLimits","params: {\n poolAddress: Address\n existingPositionIds: bigint[]\n tokenId: bigint\n positionSize: bigint\n tickLimitLow: bigint\n tickLimitHigh: bigint\n spreadLimit?: bigint\n swapAtMint?: boolean\n usePremiaAsCollateral?: boolean\n builderCode?: bigint\n}","params: ClosePositionParams","params: RollPositionParams","closeLimits: readonly [number, number, number]","openLimits: readonly [number, number, number]","params: DispatchParams","params: ExecuteBatchDispatchParams","params: LiquidateParams","params: ForceExerciseParams","params: SettleParams","positionSizes: bigint[]","tickAndSpreadLimits: TickAndSpreadLimits[]","params: PokeOracleParams","params: DeployNewPoolParams","value: bigint","multiplier: number","originalMaxFeePerGas: bigint | undefined","originalMaxPriorityFeePerGas: bigint | undefined","explicitMaxFeePerGas: bigint | undefined","explicitMaxPriorityFeePerGas: bigint | undefined","params: SpeedUpParams","replacementHash","params: CancelParams","cancelHash","params: CreditSwapCallParams","params: SwapExactOutParams","call","params: SwapExactInParams","params: WrapXstockParams","params: UnwrapXstockParams","params: PreviewWrapParams","params: WrapEthParams","params: UnwrapWethParams","client: PublicClient","poolAddress: Address","chainId: bigint","token: Address","storage: StorageAdapter","account: Address","positionIds: bigint[]","params: SupplyParams","params: UnsupplyParams","params: BorrowParams","mintTickLimits: readonly [number, number, number]","params: PreviewBorrowParams","collateralReqToken0: bigint | null","collateralReqToken1: bigint | null","params: RepayParams","ascendingLimits: readonly [number, number, number]","existingPositionIds: bigint[]","tokenIndex: bigint","params: SmartRepayParams","opsPositionIds: bigint[]","opsSizes: bigint[]","finalPositionIdList: bigint[]","params: SimulateBatchDispatchParams","params: SimulateClosePositionParams","tickLimits: readonly [number, number, number]","tickLimits","data: ClosePositionSimulation","params: SimulateForceExerciseParams","emptyTokenFlow: TokenFlow","_meta","data: ForceExerciseSimulation","tokenFlow: TokenFlow","params: SimulateLiquidateParams","emptyTokenFlow: TokenFlow","_meta","data: LiquidateSimulation","tokenFlow: TokenFlow","params: SimulateSettleParams","tokenFlow: TokenFlow","forfeitAmounts: [bigint, bigint] | undefined","data: SettleSimulation","params: {\n client: PublicClient\n poolAddress: Address\n account: Address\n positionIdList: bigint[]\n tokenId: bigint\n dispatchCallData: Hex\n blockNumber: bigint\n}","data: Hex","params: SimulateDepositParams","data: DepositSimulation","params: SimulateWithdrawParams","data: WithdrawSimulation","poolKey: PoolKey","v3PoolAddress: Address","params: SimulateSFPMParams","creditTokenId: bigint","existingPositionIds: bigint[]","amount: bigint","mintTickLimits: readonly [number, number, number]","burnTickLimits: readonly [number, number, number]","builderCode: bigint","tokenFlow: TokenFlow","tokenOutIndex: bigint","params: SimulateSwapExactOutParams","params: SimulateSwapExactInParams","BPS_DENOMINATOR","tokenFlow: TokenFlow","index: bigint","value: bigint","amount: bigint","slippageBps: bigint","params: OneTokenFlowQuoteParams","swapAmount: bigint","direction: CreditWrapDirection","baseTargetDelta: bigint | null","maximumAmountIn","POOL_EVENT_NAMES: Record<string, PanopticEventType>","COLLATERAL_EVENT_NAMES: Record<string, PanopticEventType>","RISK_ENGINE_EVENT_NAMES: Record<string, PanopticEventType>","SFPM_EVENT_NAMES: Record<string, PanopticEventType>","POOL_MANAGER_EVENT_NAMES: Record<string, PanopticEventType>","log: DecodedLog","eventName: string","params: WatchEventsParams","unwatchFns: (() => void)[]","events: PanopticEvent[]","DEFAULT_RECONNECT_CONFIG: ReconnectConfig","params: CreateEventSubscriptionParams","config: ReconnectConfig","unwatchFns: (() => void)[]","reconnectTimeout: ReturnType<typeof setTimeout> | null","a: PanopticEvent","b: PanopticEvent","event: PanopticEvent","poolEventTypes: PanopticEventType[]","collateralEventTypes: PanopticEventType[]","riskEngineEventTypes: PanopticEventType[]","sfpmEventTypes: PanopticEventType[]","poolManagerEventTypes: PanopticEventType[]","fromBlock: bigint","toBlock: bigint","allEvents: PanopticEvent[]","parseLog: (log: DecodedLog) => PanopticEvent | null","events: PanopticEvent[]","eventType: PanopticEventType","error: Error","params: CreateEventPollerParams","pollTimeout: ReturnType<typeof setTimeout> | null","poolEventTypes: PanopticEventType[]","collateralEventTypes: PanopticEventType[]","riskEngineEventTypes: PanopticEventType[]","sfpmEventTypes: PanopticEventType[]","poolManagerEventTypes: PanopticEventType[]","from: bigint","to: bigint","allEvents: PanopticEvent[]","data: DataWithMeta","maxAgeSeconds: bigint | number","currentTimestamp?: bigint | number","pool: Pool","safeMode?: SafeModeState","safeMode: SafeModeState","error: unknown","chainDeploymentsData"],"sources":["../../../src/panoptic/v2/utils/constants.ts","../../../src/panoptic/v2/utils/factory.ts","../../../src/panoptic/v2/errors/base.ts","../../../src/panoptic/v2/errors/sdk.ts","../../../src/panoptic/v2/utils/interpolateBlocks.ts","../../../src/panoptic/v2/utils/oraclePack.ts","../../../src/panoptic/v2/errors/contract.ts","../../../src/generated.ts","../../../src/panoptic/v2/errors/errorsAbi.ts","../../../src/panoptic/v2/errors/parser.ts","../../../src/panoptic/v2/utils/oracleSafeMode.ts","../../../src/panoptic/v2/writes/utils.ts","../../../src/panoptic/v2/batch/validate.ts","../../../src/panoptic/v2/batch/build.ts","../../../src/panoptic/v2/storage/fileStorage.ts","../../../src/panoptic/v2/storage/keys.ts","../../../src/panoptic/v2/storage/memoryStorage.ts","../../../src/panoptic/v2/storage/serializer.ts","../../../src/panoptic/v2/clients/blockMeta.ts","../../../src/panoptic/v2/clients/blocksByTimestamp.ts","../../../src/panoptic/v2/clients/multicall.ts","../../../src/panoptic/v2/tokenId/constants.ts","../../../src/panoptic/v2/tokenId/encoding.ts","../../../src/panoptic/v2/tokenId/builder.ts","../../../src/panoptic/v2/tokenId/decode.ts","../../../src/panoptic/v2/sfpmSwap/calldata.ts","../../../src/panoptic/v2/sfpmSwap/init.ts","../../../src/panoptic/v2/sfpmSwap/plan.ts","../../../src/panoptic/v2/sfpmSwap/quote.ts","../../../src/uniswap/v4/router/errors.ts","../../../src/uniswap/v3/router/encodeSwap.ts","../../../src/uniswap/v3/abis/quoterV2.ts","../../../src/uniswap/v3/addresses.ts","../../../src/uniswap/v3/router/quote.ts","../../../src/panoptic/v2/reads/sfpm.ts","../../../src/panoptic/v2/reads/factory.ts","../../../src/panoptic/v2/reads/minePoolAddressLocal.ts","../../../src/panoptic/v2/abis/stateView.ts","../../../src/panoptic/v2/abis/uniswapV3Pool.ts","../../../src/panoptic/v2/formatters/tick.ts","../../../src/panoptic/v2/reads/mintBuffer.ts","../../../src/panoptic/v2/reads/pool.ts","../../../src/panoptic/v2/greeks/index.ts","../../../src/panoptic/v2/utils/option-encoding-v2.ts","../../../src/panoptic/v2/reads/position.ts","../../../src/panoptic/v2/reads/premia.ts","../../../src/panoptic/v2/abis/panopticQuery.ts","../../../src/abis/multicall3.ts","../../../src/panoptic/v2/reads/multicallBlock.ts","../../../src/panoptic/v2/reads/checks.ts","../../../src/panoptic/v2/reads/account.ts","../../../src/panoptic/v2/reads/collateral.ts","../../../src/panoptic/v2/reads/irm.ts","../../../src/panoptic/v2/simulations/tokenFlow.ts","../../../src/panoptic/v2/utils/priceConvert.ts","../../../src/panoptic/v2/sync/snapshotRecovery.ts","../../../src/panoptic/v2/sync/getTrackedPositionIds.ts","../../../src/panoptic/v2/writes/loanUtils.ts","../../../src/panoptic/v2/simulations/creditWrap.ts","../../../src/panoptic/v2/simulations/simulateDispatch.ts","../../../src/panoptic/v2/simulations/tokenShortfallRecovery.ts","../../../src/panoptic/v2/reads/collateralEstimate.ts","../../../src/panoptic/v2/reads/collateralBreakdown.ts","../../../src/panoptic/v2/reads/erc4626.ts","../../../src/panoptic/v2/reads/guardian.ts","../../../src/panoptic/v2/reads/safeMode.ts","../../../src/panoptic/v2/reads/queryUtils.ts","../../../src/panoptic/v2/reads/liquidity.ts","../../../src/panoptic/v2/formatters/amount.ts","../../../src/panoptic/v2/formatters/percentage.ts","../../../src/panoptic/v2/formatters/wad.ts","../../../src/panoptic/v2/formatters/rates.ts","../../../src/panoptic/v2/formatters/poolFormatters.ts","../../../src/panoptic/v2/formatters/tokenList.ts","../../../src/panoptic/v2/formatters/display.ts","../../../src/panoptic/v2/reads/accountGreeks.ts","../../../src/panoptic/v2/reads/margin.ts","../../../src/panoptic/v2/reads/hedge.ts","../../../src/panoptic/v2/reads/collateralSharePrice.ts","../../../src/panoptic/v2/reads/collateralTotalAssets.ts","../../../src/panoptic/v2/reads/buyingPower.ts","../../../src/panoptic/v2/simulations/simulateOpenPosition.ts","../../../src/panoptic/v2/reads/openPositionPreview.ts","../../../src/panoptic/v2/reads/nativeTokenPrice.ts","../../../src/panoptic/v2/reads/history.ts","../../../src/panoptic/v2/reads/uniswapFeeHistory.ts","../../../src/panoptic/v2/reads/streamiaHistory.ts","../../../src/panoptic/v2/reads/uniswapPool.ts","../../../src/abis/StateView.ts","../../../src/panoptic/v2/reads/uniswapLpPosition.ts","../../../src/panoptic/v2/reads/priceHistory.ts","../../../src/panoptic/v2/reads/enrichment.ts","../../../src/panoptic/v2/sync/reorgHandling.ts","../../../src/panoptic/v2/sync/getSyncStatus.ts","../../../src/panoptic/v2/sync/eventReconstruction.ts","../../../src/panoptic/v2/sync/syncPositions.ts","../../../src/panoptic/v2/sync/tradeHistory.ts","../../../src/panoptic/v2/sync/chunkTracking.ts","../../../src/panoptic/v2/sync/pendingPositions.ts","../../../src/panoptic/v2/writes/broadcaster.ts","../../../src/panoptic/v2/writes/approve.ts","../../../src/panoptic/v2/writes/vault.ts","../../../src/panoptic/v2/writes/position.ts","../../../src/panoptic/v2/writes/dispatch.ts","../../../src/panoptic/v2/writes/executeBatchDispatch.ts","../../../src/panoptic/v2/writes/liquidate.ts","../../../src/panoptic/v2/writes/forceExercise.ts","../../../src/panoptic/v2/writes/settle.ts","../../../src/panoptic/v2/writes/pokeOracle.ts","../../../src/panoptic/v2/writes/factory.ts","../../../src/panoptic/v2/writes/txManagement.ts","../../../src/panoptic/v2/writes/swap.ts","../../../src/panoptic/v2/writes/wrap.ts","../../../src/panoptic/v2/writes/lending.ts","../../../src/panoptic/v2/simulations/simulateBatchDispatch.ts","../../../src/panoptic/v2/simulations/simulateClosePosition.ts","../../../src/panoptic/v2/simulations/simulateForceExercise.ts","../../../src/panoptic/v2/simulations/simulateLiquidate.ts","../../../src/panoptic/v2/simulations/simulateSettle.ts","../../../src/panoptic/v2/simulations/simulateVault.ts","../../../src/panoptic/v2/simulations/sfpm.ts","../../../src/panoptic/v2/simulations/simulateSwap.ts","../../../src/panoptic/v2/simulations/oneTokenFlow.ts","../../../src/panoptic/v2/abis/poolManager.ts","../../../src/panoptic/v2/events/watchEvents.ts","../../../src/panoptic/v2/events/subscription.ts","../../../src/panoptic/v2/events/poller.ts","../../../src/panoptic/v2/bot/index.ts","../../../../deployments/src/chainDeployments.data.json","../../../../deployments/src/chainDeployments.js","../../../../deployments/src/vaultDisplayNames.js"],"sourcesContent":["/**\n * Constants for the Panoptic v2 SDK.\n * @module v2/utils/constants\n */\n\n/**\n * WAD constant (10^18) used for fixed-point arithmetic.\n * Commonly used for spread calculations and other WAD-scaled values.\n */\nexport const WAD = 10n ** 18n\n\n/**\n * Zero collateral object for guest mode.\n * Returns safe defaults when no wallet is connected.\n */\nexport const ZERO_COLLATERAL = {\n token0: {\n assets: 0n,\n shares: 0n,\n availableAssets: 0n,\n lockedAssets: 0n,\n },\n token1: {\n assets: 0n,\n shares: 0n,\n availableAssets: 0n,\n lockedAssets: 0n,\n },\n} as const\n\n/**\n * Zero valuation object for guest mode.\n * Returns safe defaults when no wallet is connected.\n */\nexport const ZERO_VALUATION = {\n netLiquidationValue0: 0n,\n netLiquidationValue1: 0n,\n maintenanceMargin0: 0n,\n maintenanceMargin1: 0n,\n marginExcess0: 0n,\n marginExcess1: 0n,\n} as const\n\n/**\n * Storage schema version for the SDK.\n * Increment when storage format changes (triggers migration or clear).\n */\nexport const SCHEMA_VERSION = 1\n\n/**\n * Storage key prefix for all SDK data.\n */\nexport const STORAGE_PREFIX = 'panoptic-v2-sdk'\n\n/**\n * Maximum number of chunks that can be tracked per pool.\n * Exceeding this limit throws ChunkLimitError.\n */\nexport const MAX_TRACKED_CHUNKS = 1000\n\n/**\n * Default reorg depth for chain reorganization handling.\n * On reorg detection, rollback this many blocks and re-sync.\n */\nexport const REORG_DEPTH = 128n\n\n/**\n * Oracle epoch duration in seconds (64 seconds per epoch).\n */\nexport const ORACLE_EPOCH_SECONDS = 64n\n\n/**\n * Minimum tick value for Uniswap v3/v4 pools.\n */\nexport const MIN_TICK = -887272n\n\n/**\n * Maximum tick value for Uniswap v3/v4 pools.\n */\nexport const MAX_TICK = 887272n\n\n/**\n * Basis points denominator (100% = 10000 bps).\n */\nexport const BPS_DENOMINATOR = 10000n\n\n/**\n * Utilization denominator (100% = 10000).\n */\nexport const UTILIZATION_DENOMINATOR = 10000n\n","/**\n * Factory utility functions for the Panoptic v2 SDK.\n * @module v2/utils/factory\n */\n\n/**\n * Decoded Panoptic NFT metadata from a base64-encoded token URI.\n */\nexport type PanopticNFTMetadata = {\n name: string\n description: string\n attributes: [\n {\n trait_type: 'Rarity'\n value: string\n },\n {\n trait_type: 'Strategy'\n value: string\n },\n {\n trait_type: 'ChainId'\n value: string\n },\n ]\n image: string\n}\n\n/**\n * Decode a base64-encoded Panoptic NFT token URI into metadata.\n *\n * @param tokenURI - The base64-encoded data URI string\n * @returns Parsed NFT metadata object, or undefined if input is invalid\n */\nexport function decodePanopticTokenURI(tokenURI: string): PanopticNFTMetadata | undefined {\n if (tokenURI === undefined || tokenURI === '') {\n return undefined\n }\n const parts = tokenURI.split('data:application/json;base64,')\n if (parts.length < 2 || parts[1] === '') {\n return undefined\n }\n try {\n const decoded = atob(parts[1])\n return JSON.parse(decoded) as PanopticNFTMetadata\n } catch {\n return undefined\n }\n}\n","/**\n * Base error class for the Panoptic v2 SDK.\n * @module v2/errors/base\n */\n\n/**\n * Base error class for all Panoptic SDK errors.\n * All errors thrown by the SDK extend this class.\n *\n * @example\n * ```typescript\n * try {\n * await openPosition(config, params)\n * } catch (error) {\n * if (error instanceof PanopticError) {\n * console.log('Panoptic error:', error.name, error.message)\n * console.log('Original cause:', error.cause)\n * }\n * }\n * ```\n */\nexport class PanopticError extends Error {\n override readonly name: string = 'PanopticError'\n\n /** The Solidity error name (e.g. 'PriceBoundFail', 'InputListFail'). Set by the parser. */\n errorName?: string\n\n /**\n * Creates a new PanopticError.\n *\n * @param message - Human-readable error message\n * @param cause - Optional underlying error that caused this error\n */\n constructor(\n message: string,\n public readonly cause?: Error,\n ) {\n super(message)\n\n // Maintains proper stack trace for where error was thrown (V8 only)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor)\n }\n\n // Ensure prototype chain is correctly set up\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n","/**\n * SDK-specific errors not derived from contract Errors.sol.\n * @module v2/errors/sdk\n */\n\nimport type { Address } from 'viem'\n\nimport type { BatchDiagnostic } from '../batch/types'\nimport type { SafeMode } from '../types/oracle'\nimport type { PoolHealthStatus } from '../types/pool'\nimport { PanopticError } from './base'\n\n// ─────────────────────────────────────────────────────────────\n// Configuration & Network Errors\n// ─────────────────────────────────────────────────────────────\n\n/**\n * Wallet is connected to a different network than the config expects.\n * Thrown on write operations when wallet chain !== config chain.\n */\nexport class NetworkMismatchError extends PanopticError {\n override readonly name = 'NetworkMismatchError'\n\n constructor(\n public readonly walletChainId: bigint,\n public readonly expectedChainId: bigint,\n cause?: Error,\n ) {\n super(\n `Network mismatch: wallet on chain ${walletChainId}, expected chain ${expectedChainId}`,\n cause,\n )\n }\n}\n\n/**\n * Cross-pool operation attempted (query for different pool than configured).\n */\nexport class CrossPoolError extends PanopticError {\n override readonly name = 'CrossPoolError'\n\n constructor(\n public readonly requestedPool: Address,\n public readonly configuredPool: Address,\n cause?: Error,\n ) {\n super(`Cross-pool error: requested ${requestedPool}, configured ${configuredPool}`, cause)\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// Sync & Position Tracking Errors\n// ─────────────────────────────────────────────────────────────\n\n/**\n * Position sync timed out.\n */\nexport class SyncTimeoutError extends PanopticError {\n override readonly name = 'SyncTimeoutError'\n\n constructor(\n public readonly elapsedMs: bigint,\n public readonly blocksProcessed: bigint,\n public readonly blocksRemaining: bigint,\n cause?: Error,\n ) {\n super(\n `Sync timeout after ${elapsedMs}ms: processed ${blocksProcessed} blocks, ${blocksRemaining} remaining`,\n cause,\n )\n }\n}\n\n/**\n * Snapshot recovery from dispatch() calldata failed.\n */\nexport class PositionSnapshotNotFoundError extends PanopticError {\n override readonly name = 'PositionSnapshotNotFoundError'\n\n constructor(cause?: Error) {\n super('Position snapshot not found in dispatch() calldata history', cause)\n }\n}\n\n/**\n * Provider is behind the expected block number.\n * Thrown when minBlockNumber option is specified and provider is lagging.\n */\nexport class ProviderLagError extends PanopticError {\n override readonly name = 'ProviderLagError'\n\n constructor(\n public readonly providerBlock: bigint,\n public readonly expectedBlock: bigint,\n cause?: Error,\n ) {\n super(`Provider behind: at block ${providerBlock}, expected at least ${expectedBlock}`, cause)\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// Multicall Errors\n// ─────────────────────────────────────────────────────────────\n\n/**\n * Multicall3 returned fewer results than the number of calls submitted.\n */\nexport class MulticallResultMissingError extends PanopticError {\n override readonly name = 'MulticallResultMissingError'\n\n constructor(\n public readonly label: string,\n public readonly index: number,\n cause?: Error,\n ) {\n super(`Missing Multicall3 result for ${label} (index ${index})`, cause)\n }\n}\n\n/**\n * Multicall3 sub-call reverted (success=false in the result tuple).\n */\nexport class MulticallResultFailedError extends PanopticError {\n override readonly name = 'MulticallResultFailedError'\n\n constructor(\n public readonly label: string,\n public readonly index: number,\n cause?: Error,\n ) {\n super(`Multicall3 result failed for ${label} (index ${index})`, cause)\n }\n}\n\n/**\n * eth_call to Multicall3 returned no data (provider-level failure).\n */\nexport class MulticallNoDataError extends PanopticError {\n override readonly name = 'MulticallNoDataError'\n\n constructor(\n public readonly functionName: string,\n cause?: Error,\n ) {\n super(`Multicall3.${functionName} returned no data`, cause)\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// Chunk Tracking Errors\n// ─────────────────────────────────────────────────────────────\n\n/**\n * Exceeded the maximum number of tracked chunks (1000 per pool).\n */\nexport class ChunkLimitError extends PanopticError {\n override readonly name = 'ChunkLimitError'\n\n constructor(\n public readonly currentCount: bigint,\n public readonly attemptedAdd: bigint,\n cause?: Error,\n ) {\n super(\n `Chunk limit exceeded: ${currentCount} tracked, attempted to add ${attemptedAdd} (max 1000)`,\n cause,\n )\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// Pool Health Errors\n// ─────────────────────────────────────────────────────────────\n\n/**\n * Pool is in safe mode and trading is restricted.\n */\nexport class SafeModeError extends PanopticError {\n override readonly name = 'SafeModeError'\n\n constructor(\n public readonly level: SafeMode,\n public readonly reason: string,\n cause?: Error,\n ) {\n super(`Pool in safe mode (${level}): ${reason}`, cause)\n }\n}\n\n/**\n * Data is stale (too old based on block timestamp).\n */\nexport class StaleDataError extends PanopticError {\n override readonly name = 'StaleDataError'\n\n constructor(\n public readonly blockTimestamp: bigint,\n public readonly currentTimestamp: bigint,\n public readonly stalenessSeconds: bigint,\n cause?: Error,\n ) {\n super(\n `Data stale: block timestamp ${blockTimestamp}, current ${currentTimestamp}, stale by ${stalenessSeconds}s`,\n cause,\n )\n }\n}\n\n/**\n * Pool is in an unhealthy state (low liquidity or paused).\n */\nexport class UnhealthyPoolError extends PanopticError {\n override readonly name = 'UnhealthyPoolError'\n\n constructor(\n public readonly healthStatus: PoolHealthStatus,\n cause?: Error,\n ) {\n super(`Pool unhealthy: ${healthStatus}`, cause)\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// Oracle Errors\n// ─────────────────────────────────────────────────────────────\n\n/**\n * Cannot poke oracle because less than 64 seconds since last update.\n */\nexport class OracleRateLimitedError extends PanopticError {\n override readonly name = 'OracleRateLimitedError'\n\n constructor(\n public readonly lastUpdate: bigint,\n public readonly currentTime: bigint,\n cause?: Error,\n ) {\n const elapsed = currentTime - lastUpdate\n super(`Oracle rate limited: last update ${elapsed}s ago, must wait 64s between updates`, cause)\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// Helper Contract Errors\n// ─────────────────────────────────────────────────────────────\n\n/**\n * PanopticHelper contract is not deployed.\n * Functions requiring the helper will throw this error.\n */\nexport class PanopticHelperNotDeployedError extends PanopticError {\n override readonly name = 'PanopticHelperNotDeployedError'\n\n constructor(cause?: Error) {\n super(\n 'PanopticHelper contract not deployed. This function requires the helper contract.',\n cause,\n )\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// RPC Errors\n// ─────────────────────────────────────────────────────────────\n\n/**\n * RPC request failed after all retries.\n */\nexport class RpcError extends PanopticError {\n override readonly name = 'RpcError'\n\n constructor(\n public readonly method: string,\n public readonly retriesAttempted: bigint,\n cause?: Error,\n ) {\n super(`RPC ${method} failed after ${retriesAttempted} retries`, cause)\n }\n}\n\n/**\n * RPC returned an error response.\n */\nexport class RpcResponseError extends PanopticError {\n override readonly name = 'RpcResponseError'\n\n constructor(\n public readonly code: bigint,\n public readonly rpcMessage: string,\n cause?: Error,\n ) {\n super(`RPC error ${code}: ${rpcMessage}`, cause)\n }\n}\n\n/**\n * Thrown when required data is not found in storage.\n * This usually means syncPositions() needs to be called first.\n */\nexport class StorageDataNotFoundError extends PanopticError {\n override readonly name = 'StorageDataNotFoundError'\n\n constructor(\n public readonly dataType: 'poolMeta' | 'positions' | 'positionMeta',\n public readonly key: string,\n ) {\n super(\n `${dataType} not found in storage (key: ${key}). ` +\n 'Call syncPositions() first to populate storage.',\n )\n }\n}\n\n/**\n * Position ID list was not provided and could not be resolved from storage.\n *\n * Either pass `existingPositionIds` / `positionIdList` explicitly, or provide\n * `storage` + `chainId` so the SDK can read tracked positions automatically.\n */\nexport class MissingPositionIdsError extends PanopticError {\n override readonly name = 'MissingPositionIdsError'\n\n constructor() {\n super(\n 'Either existingPositionIds/positionIdList must be provided, or storage + chainId for auto-resolution.',\n )\n }\n}\n\n/**\n * History range parameters are invalid (e.g. startBlock > endBlock, points < 0).\n */\nexport class InvalidHistoryRangeError extends PanopticError {\n override readonly name = 'InvalidHistoryRangeError'\n}\n\n/**\n * Tick limits are invalid for the given operation.\n *\n * tickLimitLow must be <= tickLimitHigh regardless of swapAtMint.\n * The SDK handles reordering internally based on the swapAtMint flag.\n */\n/**\n * Generic validation error for public SDK functions.\n * Thrown when input parameters fail validation checks.\n */\nexport class PanopticValidationError extends PanopticError {\n override readonly name = 'PanopticValidationError'\n}\n\nexport class InvalidTickLimitsError extends PanopticError {\n override readonly name = 'InvalidTickLimitsError'\n\n constructor(\n public readonly tickLimitLow: bigint,\n public readonly tickLimitHigh: bigint,\n ) {\n super(\n `Invalid tick limits: tickLimitLow (${tickLimitLow}) must be <= tickLimitHigh (${tickLimitHigh}). ` +\n 'The SDK reorders limits based on swapAtMint — always pass them in ascending order.',\n )\n }\n}\n\n/**\n * No loan positions found for the given token.\n */\nexport class NoLoanPositionsError extends PanopticError {\n override readonly name = 'NoLoanPositionsError'\n\n constructor(public readonly token: Address) {\n super(`No loan positions found for token ${token}`)\n }\n}\n\n/**\n * All loan tokenId slots are in use — no unique tokenId could be generated.\n */\nexport class LoanSlotExhaustedError extends PanopticError {\n override readonly name = 'LoanSlotExhaustedError'\n\n constructor() {\n super('Could not build unique loan tokenId — all slots in use')\n }\n}\n\n/**\n * Maximum retry attempts exceeded for the given operation.\n */\nexport class MaxRetriesExceededError extends PanopticError {\n override readonly name = 'MaxRetriesExceededError'\n\n constructor(public readonly operation: string) {\n super(`${operation}: max retries exceeded`)\n }\n}\n\n/**\n * Batch dispatch validation failed.\n *\n * Thrown by `executeBatchDispatch` when the batch contains invalid items\n * (mint of an existing tokenId, burn of a position not held, duplicate tokenIds,\n * cross-pool ops, etc.). The `diagnostics` array carries one entry per failure.\n */\nexport class BatchValidationError extends PanopticError {\n override readonly name = 'BatchValidationError'\n\n constructor(public readonly diagnostics: BatchDiagnostic[]) {\n super(\n `Batch dispatch validation failed (${diagnostics.length} issue${diagnostics.length === 1 ? '' : 's'}): ` +\n diagnostics.map((d) => `[${d.code}] ${d.message}`).join('; '),\n )\n }\n}\n\n/**\n * Thrown when a swap token address doesn't match either token in the pool.\n */\nexport class SwapTokenMismatchError extends PanopticError {\n override readonly name = 'SwapTokenMismatchError'\n\n constructor(\n public readonly tokenAddress: Address,\n public readonly token0: Address,\n public readonly token1: Address,\n ) {\n super(\n `Token ${tokenAddress} does not match either pool token: token0=${token0}, token1=${token1}`,\n )\n }\n}\n","/**\n * Evenly-spaced block number interpolation utility.\n * @module v2/utils/interpolateBlocks\n */\n\nimport { InvalidHistoryRangeError } from '../errors/sdk'\n\n/**\n * Generate evenly-spaced block numbers between start and end (pure math, no RPC).\n *\n * @param startBlock - First block in the range\n * @param endBlock - Last block in the range\n * @param points - Number of evenly-spaced data points to generate\n * @returns Array of interpolated block numbers\n *\n * @throws {InvalidHistoryRangeError} if startBlock > endBlock or points < 0\n */\nexport function interpolateBlocks(startBlock: bigint, endBlock: bigint, points: number): bigint[] {\n if (!Number.isFinite(points) || !Number.isSafeInteger(points)) {\n throw new InvalidHistoryRangeError(`points must be a finite safe integer, got ${points}`)\n }\n if (points < 0) {\n throw new InvalidHistoryRangeError(`points must be >= 0, got ${points}`)\n }\n if (startBlock > endBlock) {\n throw new InvalidHistoryRangeError(\n `startBlock (${startBlock}) must be <= endBlock (${endBlock})`,\n )\n }\n if (points === 0) return []\n if (points === 1) return [endBlock]\n const range = endBlock - startBlock\n return Array.from(\n { length: points },\n (_, i) => startBlock + (range * BigInt(i)) / BigInt(points - 1),\n )\n}\n","import { ORACLE_EPOCH_SECONDS } from './constants'\n\nconst ORACLE_EPOCH_SHIFT = 232n\nconst ORACLE_EPOCH_MASK = (1n << 24n) - 1n\nconst ORACLE_TICK_MASK = (1n << 22n) - 1n\n\nfunction decodeSigned22(value: bigint): bigint {\n const signBit = 1n << 21n\n const truncated = value & ORACLE_TICK_MASK\n return (truncated & signBit) === 0n ? truncated : truncated - (1n << 22n)\n}\n\n/** Timing decoded from an OraclePack and resolved against a specific block. */\nexport interface OracleTiming {\n /** Modulo-2^24 oracle epoch stored on-chain. */\n epoch: bigint\n /** Absolute epoch-boundary timestamp reconstructed at or before the supplied block. */\n timestamp: bigint\n}\n\n/** Fixed-width oracle state decoded from an OraclePack. */\nexport interface DecodedOraclePack {\n referenceTick: bigint\n lockMode: bigint\n spotEMA: bigint\n fastEMA: bigint\n slowEMA: bigint\n eonsEMA: bigint\n epoch: bigint\n timestamp: bigint\n}\n\n/**\n * Decode the 24-bit epoch stored at bits 232..255 of OraclePack.\n *\n * The packed timestamp is modulo 2^30 seconds and only identifies an absolute\n * Unix timestamp within the wrap window containing `blockTimestamp`. Supplying\n * the relevant block timestamp resolves it to the latest matching epoch at or\n * before that block, including across the epoch counter wraparound.\n */\nexport function decodeOracleTiming(oraclePack: bigint, blockTimestamp: bigint): OracleTiming {\n const epoch = (oraclePack >> ORACLE_EPOCH_SHIFT) & ORACLE_EPOCH_MASK\n const currentEpoch = oracleEpochAt(blockTimestamp)\n const elapsedEpochs = (currentEpoch - epoch) & ORACLE_EPOCH_MASK\n const currentEpochTimestamp = blockTimestamp - (blockTimestamp % ORACLE_EPOCH_SECONDS)\n return { epoch, timestamp: currentEpochTimestamp - elapsedEpochs * ORACLE_EPOCH_SECONDS }\n}\n\n/** Decode the fixed-width ticks and guardian state stored in OraclePack. */\nexport function decodeOraclePack(oraclePack: bigint, blockTimestamp: bigint): DecodedOraclePack {\n const timing = decodeOracleTiming(oraclePack, blockTimestamp)\n return {\n referenceTick: decodeSigned22(oraclePack >> 96n),\n lockMode: (oraclePack >> 118n) & 3n,\n spotEMA: decodeSigned22(oraclePack >> 120n),\n fastEMA: decodeSigned22(oraclePack >> 142n),\n slowEMA: decodeSigned22(oraclePack >> 164n),\n eonsEMA: decodeSigned22(oraclePack >> 186n),\n ...timing,\n }\n}\n\n/** Return the contract's modulo-2^24 64-second epoch for a block timestamp. */\nexport function oracleEpochAt(timestamp: bigint): bigint {\n return (timestamp / ORACLE_EPOCH_SECONDS) & ORACLE_EPOCH_MASK\n}\n","/**\n * Contract errors from Errors.sol mapped to TypeScript classes.\n * @module v2/errors/contract\n */\n\nimport type { Address } from 'viem'\n\nimport { PanopticError } from './base'\n\n// ─────────────────────────────────────────────────────────────\n// Solvency & Margin Errors\n// ─────────────────────────────────────────────────────────────\n\n/**\n * The account is not solvent enough to perform the desired action.\n * @see Errors.sol:9\n */\nexport class AccountInsolventError extends PanopticError {\n override readonly name = 'AccountInsolventError'\n\n constructor(\n public readonly solvent: bigint,\n public readonly numberOfTicks: bigint,\n cause?: Error,\n ) {\n super(`Account insolvent: solvent=${solvent}, numberOfTicks=${numberOfTicks}`, cause)\n }\n}\n\n/**\n * Position is still solvent and cannot be liquidated.\n * @see Errors.sol:84\n */\nexport class NotMarginCalledError extends PanopticError {\n override readonly name = 'NotMarginCalledError'\n\n constructor(cause?: Error) {\n super('Position is still solvent and cannot be liquidated', cause)\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// Token & Collateral Errors\n// ─────────────────────────────────────────────────────────────\n\n/**\n * The user does not own enough assets to open/close a position.\n * @see Errors.sol:78\n */\nexport class NotEnoughTokensError extends PanopticError {\n override readonly name = 'NotEnoughTokensError'\n\n constructor(\n public readonly tokenAddress: Address,\n public readonly assetsRequested: bigint,\n public readonly assetBalance: bigint,\n cause?: Error,\n ) {\n super(\n `Not enough tokens: requested=${assetsRequested}, balance=${assetBalance}, token=${tokenAddress}`,\n cause,\n )\n }\n}\n\n/**\n * There is not enough available liquidity in the chunk for a long leg.\n * @see Errors.sol:75\n */\nexport class NotEnoughLiquidityInChunkError extends PanopticError {\n override readonly name = 'NotEnoughLiquidityInChunkError'\n\n constructor(cause?: Error) {\n super('Not enough liquidity in chunk for long leg creation or short leg closure', cause)\n }\n}\n\n/**\n * There is not enough available liquidity to fulfill a credit.\n * @see Errors.sol:47\n */\nexport class InsufficientCreditLiquidityError extends PanopticError {\n override readonly name = 'InsufficientCreditLiquidityError'\n\n constructor(cause?: Error) {\n super('Insufficient credit liquidity available in the PanopticPool', cause)\n }\n}\n\n/**\n * The amount deposited is larger than the maximum permitted.\n * @see Errors.sol:25\n */\nexport class DepositTooLargeError extends PanopticError {\n override readonly name = 'DepositTooLargeError'\n\n constructor(cause?: Error) {\n super('Deposit amount exceeds maximum permitted', cause)\n }\n}\n\n/**\n * Attempted to withdraw/redeem less than a single asset.\n * @see Errors.sol:16\n */\nexport class BelowMinimumRedemptionError extends PanopticError {\n override readonly name = 'BelowMinimumRedemptionError'\n\n constructor(cause?: Error) {\n super('Redemption amount below minimum threshold', cause)\n }\n}\n\n/**\n * Attempted to withdraw/redeem more than available.\n * @see Errors.sol:35\n */\nexport class ExceedsMaximumRedemptionError extends PanopticError {\n override readonly name = 'ExceedsMaximumRedemptionError'\n\n constructor(cause?: Error) {\n super('Redemption exceeds maximum available (liquidity, shares, or open positions)', cause)\n }\n}\n\n/**\n * Mints/burns of a position returns no collateral requirement.\n * @see Errors.sol:141\n */\nexport class ZeroCollateralRequirementError extends PanopticError {\n override readonly name = 'ZeroCollateralRequirementError'\n\n constructor(cause?: Error) {\n super('Position mint/burn returned zero collateral requirement', cause)\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// Position & TokenId Errors\n// ─────────────────────────────────────────────────────────────\n\n/**\n * The TokenId provided is malformed or invalid.\n * @see Errors.sol:54\n */\nexport class InvalidTokenIdParameterError extends PanopticError {\n override readonly name = 'InvalidTokenIdParameterError'\n\n /**\n * Parameter type meanings:\n * 0=poolId, 1=ratio, 2=tokenType, 3=riskPartner, 4=strike, 5=width, 6=duplicateChunk\n */\n constructor(\n public readonly parameterType: bigint,\n cause?: Error,\n ) {\n const paramNames = [\n 'poolId',\n 'ratio',\n 'tokenType',\n 'riskPartner',\n 'strike',\n 'width',\n 'duplicateChunk',\n ]\n const paramName = paramNames[Number(parameterType)] ?? `unknown(${parameterType})`\n super(`Invalid TokenId parameter: ${paramName}`, cause)\n }\n}\n\n/**\n * Position is not owned by the user and has positionSize=0.\n * @see Errors.sol:96\n */\nexport class PositionNotOwnedError extends PanopticError {\n override readonly name = 'PositionNotOwnedError'\n\n constructor(cause?: Error) {\n super('Position is not owned by the user', cause)\n }\n}\n\n/**\n * The maximum token deltas for a position exceed limits.\n * @see Errors.sol:99\n */\nexport class PositionTooLargeError extends PanopticError {\n override readonly name = 'PositionTooLargeError'\n\n constructor(cause?: Error) {\n super('Position size exceeds maximum allowed token deltas', cause)\n }\n}\n\n/**\n * User has open positions, so they cannot transfer collateral shares.\n * @see Errors.sol:93\n */\nexport class PositionCountNotZeroError extends PanopticError {\n override readonly name = 'PositionCountNotZeroError'\n\n constructor(cause?: Error) {\n super('Cannot transfer collateral shares while positions are open', cause)\n }\n}\n\n/**\n * The list of provided TokenIds has a duplicate entry.\n * @see Errors.sol:28\n */\nexport class DuplicateTokenIdError extends PanopticError {\n override readonly name = 'DuplicateTokenIdError'\n\n constructor(cause?: Error) {\n super('Duplicate TokenId in provided list', cause)\n }\n}\n\n/**\n * The supplied tokenId has no valid legs.\n * @see Errors.sol:144\n */\nexport class TokenIdHasZeroLegsError extends PanopticError {\n override readonly name = 'TokenIdHasZeroLegsError'\n\n constructor(cause?: Error) {\n super('TokenId has no valid legs', cause)\n }\n}\n\n/**\n * Position would exceed maximum legs open for account.\n * @see Errors.sol:112\n */\nexport class TooManyLegsOpenError extends PanopticError {\n override readonly name = 'TooManyLegsOpenError'\n\n constructor(cause?: Error) {\n super('Position would exceed maximum allowed legs open', cause)\n }\n}\n\n/**\n * The provided list of option positions is incorrect or invalid.\n * @see Errors.sol:38\n */\nexport class InputListFailError extends PanopticError {\n override readonly name = 'InputListFailError'\n\n constructor(cause?: Error) {\n super('Invalid position list provided', cause)\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// Tick & Price Errors\n// ─────────────────────────────────────────────────────────────\n\n/**\n * Tick is not between MIN_TICK and MAX_TICK.\n * @see Errors.sol:41\n */\nexport class InvalidTickError extends PanopticError {\n override readonly name = 'InvalidTickError'\n\n constructor(cause?: Error) {\n super('Tick is outside valid range (MIN_TICK to MAX_TICK)', cause)\n }\n}\n\n/**\n * The tick range is invalid (not initializable or exceeds bounds).\n * @see Errors.sol:120\n */\nexport class InvalidTickBoundError extends PanopticError {\n override readonly name = 'InvalidTickBoundError'\n\n constructor(cause?: Error) {\n super(\n 'Tick range is invalid (not initializable multiples of tickSpacing or exceeds bounds)',\n cause,\n )\n }\n}\n\n/**\n * The current tick has fallen outside the slippage range.\n * @see Errors.sol:102\n */\nexport class PriceBoundFailError extends PanopticError {\n override readonly name = 'PriceBoundFailError'\n\n constructor(\n public readonly currentTick: bigint,\n cause?: Error,\n ) {\n super(`Price moved outside slippage bounds (currentTick=${currentTick})`, cause)\n }\n}\n\n/**\n * The price impact of the trade is too large.\n * @see Errors.sol:105\n */\nexport class PriceImpactTooLargeError extends PanopticError {\n override readonly name = 'PriceImpactTooLargeError'\n\n constructor(cause?: Error) {\n super('Price impact of trade exceeds maximum allowed', cause)\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// Liquidity Errors\n// ─────────────────────────────────────────────────────────────\n\n/**\n * Mints/burns of zero-liquidity chunks are not supported.\n * @see Errors.sol:19\n */\nexport class ChunkHasZeroLiquidityError extends PanopticError {\n override readonly name = 'ChunkHasZeroLiquidityError'\n\n constructor(cause?: Error) {\n super('Cannot mint/burn chunk with zero liquidity', cause)\n }\n}\n\n/**\n * Liquidity in a chunk is above 2^128.\n * @see Errors.sol:44\n */\nexport class LiquidityTooHighError extends PanopticError {\n override readonly name = 'LiquidityTooHighError'\n\n constructor(cause?: Error) {\n super('Liquidity exceeds maximum (2^128)', cause)\n }\n}\n\n/**\n * Net liquidity is zero due to small positions.\n * @see Errors.sol:63\n */\nexport class NetLiquidityZeroError extends PanopticError {\n override readonly name = 'NetLiquidityZeroError'\n\n constructor(cause?: Error) {\n super('Net liquidity is zero, cannot compute liquidity spread', cause)\n }\n}\n\n/**\n * Effective liquidity above threshold during long mint or short burn.\n * @see Errors.sol:32\n */\nexport class EffectiveLiquidityAboveThresholdError extends PanopticError {\n override readonly name = 'EffectiveLiquidityAboveThresholdError'\n\n constructor(cause?: Error) {\n super('Effective liquidity above spread threshold', cause)\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// Oracle & Safe Mode Errors\n// ─────────────────────────────────────────────────────────────\n\n/**\n * An oracle price is too far from another or the current tick.\n * @see Errors.sol:109\n */\nexport class StaleOracleError extends PanopticError {\n override readonly name = 'StaleOracleError'\n\n constructor(cause?: Error) {\n super('Oracle price deviation too high (potential manipulation safeguard)', cause)\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// Exercise Errors\n// ─────────────────────────────────────────────────────────────\n\n/**\n * None of the legs in a position are force-exercisable.\n * @see Errors.sol:66\n */\nexport class NoLegsExercisableError extends PanopticError {\n override readonly name = 'NoLegsExercisableError'\n\n constructor(cause?: Error) {\n super('No legs are force-exercisable (all are short or ATM long)', cause)\n }\n}\n\n/**\n * The leg is not long, so premium cannot be settled.\n * @see Errors.sol:69\n */\nexport class NotALongLegError extends PanopticError {\n override readonly name = 'NotALongLegError'\n\n constructor(cause?: Error) {\n super('Cannot settle premium for non-long leg', cause)\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// Pool & Initialization Errors\n// ─────────────────────────────────────────────────────────────\n\n/**\n * The Uniswap Pool has not been created.\n * @see Errors.sol:90\n */\nexport class PoolNotInitializedError extends PanopticError {\n override readonly name = 'PoolNotInitializedError'\n\n constructor(cause?: Error) {\n super('Uniswap pool not initialized', cause)\n }\n}\n\n/**\n * Smart contract has already been initialized.\n * @see Errors.sol:22\n */\nexport class AlreadyInitializedError extends PanopticError {\n override readonly name = 'AlreadyInitializedError'\n\n constructor(cause?: Error) {\n super('Contract already initialized', cause)\n }\n}\n\n/**\n * The supplied poolId does not match the poolId for that Uniswap Pool.\n * @see Errors.sol:132\n */\nexport class WrongPoolIdError extends PanopticError {\n override readonly name = 'WrongPoolIdError'\n\n constructor(cause?: Error) {\n super('Pool ID mismatch', cause)\n }\n}\n\n/**\n * The poolId's don't match (SFPM).\n * @see Errors.sol:135\n */\nexport class WrongUniswapPoolError extends PanopticError {\n override readonly name = 'WrongUniswapPoolError'\n\n constructor(cause?: Error) {\n super('Uniswap pool mismatch', cause)\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// Authorization Errors\n// ─────────────────────────────────────────────────────────────\n\n/**\n * The caller is not the Panoptic Pool.\n * @see Errors.sol:87\n */\nexport class NotPanopticPoolError extends PanopticError {\n override readonly name = 'NotPanopticPoolError'\n\n constructor(cause?: Error) {\n super('Caller is not the Panoptic Pool', cause)\n }\n}\n\n/**\n * Can only be called by the guardian.\n * @see Errors.sol:81\n */\nexport class NotGuardianError extends PanopticError {\n override readonly name = 'NotGuardianError'\n\n constructor(cause?: Error) {\n super('Caller is not the guardian', cause)\n }\n}\n\n/**\n * Can only be called by the Builder.\n * @see Errors.sol:72\n */\nexport class NotBuilderError extends PanopticError {\n override readonly name = 'NotBuilderError'\n\n constructor(cause?: Error) {\n super('Caller is not the builder', cause)\n }\n}\n\n/**\n * Invalid builder code.\n * @see Errors.sol:50\n */\nexport class InvalidBuilderCodeError extends PanopticError {\n override readonly name = 'InvalidBuilderCodeError'\n\n constructor(cause?: Error) {\n super('Invalid builder code', cause)\n }\n}\n\n/**\n * Mint or swap callback from invalid address.\n * @see Errors.sol:57\n */\nexport class InvalidUniswapCallbackError extends PanopticError {\n override readonly name = 'InvalidUniswapCallbackError'\n\n constructor(cause?: Error) {\n super('Invalid Uniswap callback (address mismatch)', cause)\n }\n}\n\n/**\n * Unlock callback from non-canonical pool manager.\n * @see Errors.sol:123\n */\nexport class UnauthorizedUniswapCallbackError extends PanopticError {\n override readonly name = 'UnauthorizedUniswapCallbackError'\n\n constructor(cause?: Error) {\n super('Unauthorized Uniswap V4 callback', cause)\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// Transfer & Casting Errors\n// ─────────────────────────────────────────────────────────────\n\n/**\n * ERC20 or SFPM (ERC1155) token transfer did not complete successfully.\n * @see Errors.sol:115\n */\nexport class TransferFailedError extends PanopticError {\n override readonly name = 'TransferFailedError'\n\n constructor(\n public readonly token: Address,\n public readonly from: Address,\n public readonly amount: bigint,\n public readonly balance: bigint,\n cause?: Error,\n ) {\n super(\n `Transfer failed: token=${token}, from=${from}, amount=${amount}, balance=${balance}`,\n cause,\n )\n }\n}\n\n/**\n * Casting error (e.g., uint128(uint256(a)) fails).\n * @see Errors.sol:13\n */\nexport class CastingError extends PanopticError {\n override readonly name = 'CastingError'\n\n constructor(cause?: Error) {\n super('Numeric casting overflow', cause)\n }\n}\n\n/**\n * Underflow or overflow in library operation.\n * @see Errors.sol:126\n */\nexport class UnderOverFlowError extends PanopticError {\n override readonly name = 'UnderOverFlowError'\n\n constructor(cause?: Error) {\n super('Arithmetic underflow or overflow', cause)\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// Reentrancy Error\n// ─────────────────────────────────────────────────────────────\n\n/**\n * Reentrancy check triggered.\n * @see Errors.sol:129\n */\nexport class ReentrancyError extends PanopticError {\n override readonly name = 'ReentrancyError'\n\n constructor(cause?: Error) {\n super('Reentrancy detected', cause)\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// Factory Errors\n// ─────────────────────────────────────────────────────────────\n\n/**\n * Pool deployment via CREATE2 failed.\n */\nexport class CreateFailError extends PanopticError {\n override readonly name = 'CreateFailError'\n\n constructor(cause?: Error) {\n super('Pool deployment failed (CREATE2)', cause)\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// Other Errors\n// ─────────────────────────────────────────────────────────────\n\n/**\n * Zero address was supplied as a parameter.\n * @see Errors.sol:138\n */\nexport class ZeroAddressError extends PanopticError {\n override readonly name = 'ZeroAddressError'\n\n constructor(cause?: Error) {\n super('Zero address supplied', cause)\n }\n}\n\n/**\n * Length mismatch between positionIdList and positionBalanceArray.\n * @see Errors.sol:60\n */\nexport class LengthMismatchError extends PanopticError {\n override readonly name = 'LengthMismatchError'\n\n constructor(cause?: Error) {\n super('Array length mismatch', cause)\n }\n}\n","//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n// CollateralTrackerV2\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n\nexport const collateralTrackerV2Abi = [\n { type: 'constructor', inputs: [], stateMutability: 'nonpayable' },\n {\n type: 'function',\n inputs: [],\n name: 'accrueInterest',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'owner', internalType: 'address', type: 'address' },\n { name: 'spender', internalType: 'address', type: 'address' },\n ],\n name: 'allowance',\n outputs: [{ name: 'allowance', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'spender', internalType: 'address', type: 'address' },\n { name: 'amount', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'approve',\n outputs: [{ name: '', internalType: 'bool', type: 'bool' }],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [],\n name: 'asset',\n outputs: [{ name: 'assetTokenAddress', internalType: 'address', type: 'address' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [{ name: 'owner', internalType: 'address', type: 'address' }],\n name: 'assetsAndInterest',\n outputs: [\n { name: '', internalType: 'uint256', type: 'uint256' },\n { name: '', internalType: 'uint256', type: 'uint256' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'owner', internalType: 'address', type: 'address' }],\n name: 'assetsOf',\n outputs: [{ name: 'assets', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'account', internalType: 'address', type: 'address' }],\n name: 'balanceOf',\n outputs: [{ name: 'balance', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'borrowIndex',\n outputs: [{ name: '', internalType: 'uint80', type: 'uint80' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'shares', internalType: 'uint256', type: 'uint256' }],\n name: 'convertToAssets',\n outputs: [{ name: 'assets', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'assets', internalType: 'uint256', type: 'uint256' }],\n name: 'convertToShares',\n outputs: [{ name: 'shares', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'decimals',\n outputs: [{ name: '', internalType: 'uint8', type: 'uint8' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'delegatee', internalType: 'address', type: 'address' }],\n name: 'delegate',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'assets', internalType: 'uint256', type: 'uint256' },\n { name: 'receiver', internalType: 'address', type: 'address' },\n ],\n name: 'deposit',\n outputs: [{ name: 'shares', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'payable',\n },\n {\n type: 'function',\n inputs: [],\n name: 'getPoolData',\n outputs: [\n { name: 'depositedAssets', internalType: 'uint256', type: 'uint256' },\n { name: 'insideAMM', internalType: 'uint256', type: 'uint256' },\n { name: 'creditedShares', internalType: 'uint256', type: 'uint256' },\n {\n name: 'currentPoolUtilization',\n internalType: 'uint256',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'initialize',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [],\n name: 'interestRate',\n outputs: [{ name: '', internalType: 'uint128', type: 'uint128' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'user', internalType: 'address', type: 'address' }],\n name: 'interestState',\n outputs: [\n { name: 'userBorrowIndex', internalType: 'int128', type: 'int128' },\n { name: 'netBorrows', internalType: 'int128', type: 'int128' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'lastInteractionTimestamp',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: '', internalType: 'address', type: 'address' }],\n name: 'maxDeposit',\n outputs: [{ name: 'maxAssets', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [{ name: '', internalType: 'address', type: 'address' }],\n name: 'maxMint',\n outputs: [{ name: 'maxShares', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'owner', internalType: 'address', type: 'address' }],\n name: 'maxRedeem',\n outputs: [{ name: 'maxShares', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'owner', internalType: 'address', type: 'address' }],\n name: 'maxWithdraw',\n outputs: [{ name: 'maxAssets', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'shares', internalType: 'uint256', type: 'uint256' },\n { name: 'receiver', internalType: 'address', type: 'address' },\n ],\n name: 'mint',\n outputs: [{ name: 'assets', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'payable',\n },\n {\n type: 'function',\n inputs: [{ name: 'data', internalType: 'bytes[]', type: 'bytes[]' }],\n name: 'multicall',\n outputs: [{ name: 'results', internalType: 'bytes[]', type: 'bytes[]' }],\n stateMutability: 'payable',\n },\n {\n type: 'function',\n inputs: [],\n name: 'name',\n outputs: [{ name: '', internalType: 'string', type: 'string' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'owner', internalType: 'address', type: 'address' }],\n name: 'owedInterest',\n outputs: [{ name: '', internalType: 'uint128', type: 'uint128' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'panopticPool',\n outputs: [{ name: '', internalType: 'contract PanopticPoolV2', type: 'address' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [],\n name: 'poolFee',\n outputs: [{ name: '_poolFee', internalType: 'uint24', type: 'uint24' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [],\n name: 'poolManager',\n outputs: [{ name: '', internalType: 'contract IPoolManager', type: 'address' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [{ name: 'assets', internalType: 'uint256', type: 'uint256' }],\n name: 'previewDeposit',\n outputs: [{ name: 'shares', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'shares', internalType: 'uint256', type: 'uint256' }],\n name: 'previewMint',\n outputs: [{ name: 'assets', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'owner', internalType: 'address', type: 'address' }],\n name: 'previewOwedInterest',\n outputs: [{ name: '', internalType: 'uint128', type: 'uint128' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'shares', internalType: 'uint256', type: 'uint256' }],\n name: 'previewRedeem',\n outputs: [{ name: 'assets', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'assets', internalType: 'uint256', type: 'uint256' }],\n name: 'previewWithdraw',\n outputs: [{ name: 'shares', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'rateAtTarget',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'shares', internalType: 'uint256', type: 'uint256' },\n { name: 'receiver', internalType: 'address', type: 'address' },\n { name: 'owner', internalType: 'address', type: 'address' },\n ],\n name: 'redeem',\n outputs: [{ name: 'assets', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [],\n name: 'reentrancyGuardEntered',\n outputs: [{ name: 'entered', internalType: 'bool', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'refunder', internalType: 'address', type: 'address' },\n { name: 'refundee', internalType: 'address', type: 'address' },\n { name: 'assets', internalType: 'int256', type: 'int256' },\n ],\n name: 'refund',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [{ name: 'delegatee', internalType: 'address', type: 'address' }],\n name: 'revoke',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [],\n name: 'riskEngine',\n outputs: [{ name: '', internalType: 'contract IRiskEngine', type: 'address' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [\n { name: 'optionOwner', internalType: 'address', type: 'address' },\n { name: 'longAmount', internalType: 'int128', type: 'int128' },\n { name: 'shortAmount', internalType: 'int128', type: 'int128' },\n { name: 'ammDeltaAmount', internalType: 'int128', type: 'int128' },\n { name: 'realizedPremium', internalType: 'int128', type: 'int128' },\n {\n name: 'riskParameters',\n internalType: 'RiskParameters',\n type: 'uint256',\n },\n ],\n name: 'settleBurn',\n outputs: [{ name: '', internalType: 'int128', type: 'int128' }],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'liquidator', internalType: 'address', type: 'address' },\n { name: 'liquidatee', internalType: 'address', type: 'address' },\n { name: 'bonus', internalType: 'int256', type: 'int256' },\n ],\n name: 'settleLiquidation',\n outputs: [],\n stateMutability: 'payable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'optionOwner', internalType: 'address', type: 'address' },\n { name: 'longAmount', internalType: 'int128', type: 'int128' },\n { name: 'shortAmount', internalType: 'int128', type: 'int128' },\n { name: 'ammDeltaAmount', internalType: 'int128', type: 'int128' },\n {\n name: 'riskParameters',\n internalType: 'RiskParameters',\n type: 'uint256',\n },\n ],\n name: 'settleMint',\n outputs: [\n { name: '', internalType: 'uint32', type: 'uint32' },\n { name: '', internalType: 'int128', type: 'int128' },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [],\n name: 'symbol',\n outputs: [{ name: '', internalType: 'string', type: 'string' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'token0',\n outputs: [{ name: '', internalType: 'address', type: 'address' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [],\n name: 'token1',\n outputs: [{ name: '', internalType: 'address', type: 'address' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [],\n name: 'totalAssets',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'totalSupply',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'recipient', internalType: 'address', type: 'address' },\n { name: 'amount', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'transfer',\n outputs: [{ name: '', internalType: 'bool', type: 'bool' }],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'from', internalType: 'address', type: 'address' },\n { name: 'to', internalType: 'address', type: 'address' },\n { name: 'amount', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'transferFrom',\n outputs: [{ name: '', internalType: 'bool', type: 'bool' }],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [],\n name: 'underlyingIsToken0',\n outputs: [{ name: '_underlyingIsToken0', internalType: 'bool', type: 'bool' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [],\n name: 'underlyingToken',\n outputs: [{ name: '', internalType: 'address', type: 'address' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [{ name: 'data', internalType: 'bytes', type: 'bytes' }],\n name: 'unlockCallback',\n outputs: [{ name: '', internalType: 'bytes', type: 'bytes' }],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [],\n name: 'unrealizedGlobalInterest',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'assets', internalType: 'uint256', type: 'uint256' },\n { name: 'receiver', internalType: 'address', type: 'address' },\n { name: 'owner', internalType: 'address', type: 'address' },\n ],\n name: 'withdraw',\n outputs: [{ name: 'shares', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'assets', internalType: 'uint256', type: 'uint256' },\n { name: 'receiver', internalType: 'address', type: 'address' },\n { name: 'owner', internalType: 'address', type: 'address' },\n { name: 'positionIdList', internalType: 'TokenId[]', type: 'uint256[]' },\n { name: 'usePremiaAsCollateral', internalType: 'bool', type: 'bool' },\n ],\n name: 'withdraw',\n outputs: [{ name: 'shares', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'nonpayable',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'owner',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'spender',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'amount',\n internalType: 'uint256',\n type: 'uint256',\n indexed: false,\n },\n ],\n name: 'Approval',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'owner',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'builder',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'commissionPaidProtocol',\n internalType: 'uint128',\n type: 'uint128',\n indexed: false,\n },\n {\n name: 'commissionPaidBuilder',\n internalType: 'uint128',\n type: 'uint128',\n indexed: false,\n },\n ],\n name: 'CommissionPaid',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'sender',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'owner',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'assets',\n internalType: 'uint256',\n type: 'uint256',\n indexed: false,\n },\n {\n name: 'shares',\n internalType: 'uint256',\n type: 'uint256',\n indexed: false,\n },\n ],\n name: 'Deposit',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'owner',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'interestOwed',\n internalType: 'uint256',\n type: 'uint256',\n indexed: false,\n },\n {\n name: 'interestPaid',\n internalType: 'uint256',\n type: 'uint256',\n indexed: false,\n },\n {\n name: 'sharesBurned',\n internalType: 'uint256',\n type: 'uint256',\n indexed: false,\n },\n ],\n name: 'InsolvencyPenaltyApplied',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'liquidatee',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'liquidator',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'protocolLossAssets',\n internalType: 'uint256',\n type: 'uint256',\n indexed: false,\n },\n {\n name: 'protocolLossShares',\n internalType: 'uint256',\n type: 'uint256',\n indexed: false,\n },\n ],\n name: 'ProtocolLossRealized',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n { name: 'from', internalType: 'address', type: 'address', indexed: true },\n { name: 'to', internalType: 'address', type: 'address', indexed: true },\n {\n name: 'amount',\n internalType: 'uint256',\n type: 'uint256',\n indexed: false,\n },\n ],\n name: 'Transfer',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'sender',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'receiver',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'owner',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'assets',\n internalType: 'uint256',\n type: 'uint256',\n indexed: false,\n },\n {\n name: 'shares',\n internalType: 'uint256',\n type: 'uint256',\n indexed: false,\n },\n ],\n name: 'Withdraw',\n },\n { type: 'error', inputs: [], name: 'AlreadyInitialized' },\n { type: 'error', inputs: [], name: 'BelowMinimumRedemption' },\n { type: 'error', inputs: [], name: 'CastingError' },\n { type: 'error', inputs: [], name: 'DepositTooLarge' },\n { type: 'error', inputs: [], name: 'ExceedsMaximumRedemption' },\n {\n type: 'error',\n inputs: [\n { name: 'tokenAddress', internalType: 'address', type: 'address' },\n { name: 'assetsRequested', internalType: 'uint256', type: 'uint256' },\n { name: 'assetBalance', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'NotEnoughTokens',\n },\n { type: 'error', inputs: [], name: 'NotPanopticPool' },\n { type: 'error', inputs: [], name: 'PositionCountNotZero' },\n { type: 'error', inputs: [], name: 'Reentrancy' },\n {\n type: 'error',\n inputs: [\n { name: 'token', internalType: 'address', type: 'address' },\n { name: 'from', internalType: 'address', type: 'address' },\n { name: 'amount', internalType: 'uint256', type: 'uint256' },\n { name: 'balance', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'TransferFailed',\n },\n { type: 'error', inputs: [], name: 'UnauthorizedUniswapCallback' },\n] as const\n\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n// PanopticFactoryV3\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n\nexport const panopticFactoryV3Abi = [\n {\n type: 'constructor',\n inputs: [\n {\n name: '_SFPM',\n internalType: 'contract SemiFungiblePositionManagerV3',\n type: 'address',\n },\n {\n name: '_univ3Factory',\n internalType: 'contract IUniswapV3Factory',\n type: 'address',\n },\n { name: '_poolReference', internalType: 'address', type: 'address' },\n {\n name: '_collateralReference',\n internalType: 'address',\n type: 'address',\n },\n { name: 'properties', internalType: 'bytes32[]', type: 'bytes32[]' },\n { name: 'indices', internalType: 'uint256[][]', type: 'uint256[][]' },\n { name: 'pointers', internalType: 'Pointer[][]', type: 'uint256[][]' },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'spender', internalType: 'address', type: 'address' },\n { name: 'id', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'approve',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [{ name: 'owner', internalType: 'address', type: 'address' }],\n name: 'balanceOf',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'panopticPool', internalType: 'address', type: 'address' },\n { name: 'symbol0', internalType: 'string', type: 'string' },\n { name: 'symbol1', internalType: 'string', type: 'string' },\n { name: 'fee', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'constructMetadata',\n outputs: [{ name: '', internalType: 'string', type: 'string' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'token0', internalType: 'address', type: 'address' },\n { name: 'token1', internalType: 'address', type: 'address' },\n { name: 'fee', internalType: 'uint24', type: 'uint24' },\n {\n name: 'riskEngine',\n internalType: 'contract IRiskEngine',\n type: 'address',\n },\n { name: 'salt', internalType: 'uint96', type: 'uint96' },\n ],\n name: 'deployNewPool',\n outputs: [\n {\n name: 'newPoolContract',\n internalType: 'contract PanopticPoolV2',\n type: 'address',\n },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n name: 'getApproved',\n outputs: [{ name: '', internalType: 'address', type: 'address' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n {\n name: 'univ3pool',\n internalType: 'contract IUniswapV3Pool',\n type: 'address',\n },\n {\n name: 'riskEngine',\n internalType: 'contract IRiskEngine',\n type: 'address',\n },\n ],\n name: 'getPanopticPool',\n outputs: [{ name: '', internalType: 'contract PanopticPoolV2', type: 'address' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: '', internalType: 'address', type: 'address' },\n { name: '', internalType: 'address', type: 'address' },\n ],\n name: 'isApprovedForAll',\n outputs: [{ name: '', internalType: 'bool', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'deployerAddress', internalType: 'address', type: 'address' },\n { name: 'v3Pool', internalType: 'address', type: 'address' },\n { name: 'riskEngine', internalType: 'address', type: 'address' },\n { name: 'salt', internalType: 'uint96', type: 'uint96' },\n { name: 'loops', internalType: 'uint256', type: 'uint256' },\n { name: 'minTargetRarity', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'minePoolAddress',\n outputs: [\n { name: 'bestSalt', internalType: 'uint96', type: 'uint96' },\n { name: 'highestRarity', internalType: 'uint256', type: 'uint256' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'data', internalType: 'bytes[]', type: 'bytes[]' }],\n name: 'multicall',\n outputs: [{ name: 'results', internalType: 'bytes[]', type: 'bytes[]' }],\n stateMutability: 'payable',\n },\n {\n type: 'function',\n inputs: [],\n name: 'name',\n outputs: [{ name: '', internalType: 'string', type: 'string' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'id', internalType: 'uint256', type: 'uint256' }],\n name: 'ownerOf',\n outputs: [{ name: 'owner', internalType: 'address', type: 'address' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'from', internalType: 'address', type: 'address' },\n { name: 'to', internalType: 'address', type: 'address' },\n { name: 'id', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'safeTransferFrom',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'from', internalType: 'address', type: 'address' },\n { name: 'to', internalType: 'address', type: 'address' },\n { name: 'id', internalType: 'uint256', type: 'uint256' },\n { name: 'data', internalType: 'bytes', type: 'bytes' },\n ],\n name: 'safeTransferFrom',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'operator', internalType: 'address', type: 'address' },\n { name: 'approved', internalType: 'bool', type: 'bool' },\n ],\n name: 'setApprovalForAll',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }],\n name: 'supportsInterface',\n outputs: [{ name: '', internalType: 'bool', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'symbol',\n outputs: [{ name: '', internalType: 'string', type: 'string' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }],\n name: 'tokenURI',\n outputs: [{ name: '', internalType: 'string', type: 'string' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'from', internalType: 'address', type: 'address' },\n { name: 'to', internalType: 'address', type: 'address' },\n { name: 'id', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'transferFrom',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'owner',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'spender',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n { name: 'id', internalType: 'uint256', type: 'uint256', indexed: true },\n ],\n name: 'Approval',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'owner',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'operator',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n { name: 'approved', internalType: 'bool', type: 'bool', indexed: false },\n ],\n name: 'ApprovalForAll',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'poolAddress',\n internalType: 'contract PanopticPoolV2',\n type: 'address',\n indexed: true,\n },\n {\n name: 'uniswapPool',\n internalType: 'contract IUniswapV3Pool',\n type: 'address',\n indexed: true,\n },\n {\n name: 'collateralTracker0',\n internalType: 'contract CollateralTrackerV2',\n type: 'address',\n indexed: false,\n },\n {\n name: 'collateralTracker1',\n internalType: 'contract CollateralTrackerV2',\n type: 'address',\n indexed: false,\n },\n {\n name: 'riskEngine',\n internalType: 'contract IRiskEngine',\n type: 'address',\n indexed: false,\n },\n ],\n name: 'PoolDeployed',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n { name: 'from', internalType: 'address', type: 'address', indexed: true },\n { name: 'to', internalType: 'address', type: 'address', indexed: true },\n { name: 'id', internalType: 'uint256', type: 'uint256', indexed: true },\n ],\n name: 'Transfer',\n },\n { type: 'error', inputs: [], name: 'AlreadyInitialized' },\n { type: 'error', inputs: [], name: 'CreateFail' },\n { type: 'error', inputs: [], name: 'PoolNotInitialized' },\n { type: 'error', inputs: [], name: 'ZeroAddress' },\n] as const\n\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n// PanopticFactoryV4\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n\nexport const panopticFactoryV4Abi = [\n {\n type: 'constructor',\n inputs: [\n {\n name: '_SFPM',\n internalType: 'contract SemiFungiblePositionManagerV4',\n type: 'address',\n },\n {\n name: '_manager',\n internalType: 'contract IPoolManager',\n type: 'address',\n },\n { name: '_poolReference', internalType: 'address', type: 'address' },\n {\n name: '_collateralReference',\n internalType: 'address',\n type: 'address',\n },\n { name: 'properties', internalType: 'bytes32[]', type: 'bytes32[]' },\n { name: 'indices', internalType: 'uint256[][]', type: 'uint256[][]' },\n { name: 'pointers', internalType: 'Pointer[][]', type: 'uint256[][]' },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'spender', internalType: 'address', type: 'address' },\n { name: 'id', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'approve',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [{ name: 'owner', internalType: 'address', type: 'address' }],\n name: 'balanceOf',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'panopticPool', internalType: 'address', type: 'address' },\n { name: 'symbol0', internalType: 'string', type: 'string' },\n { name: 'symbol1', internalType: 'string', type: 'string' },\n { name: 'fee', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'constructMetadata',\n outputs: [{ name: '', internalType: 'string', type: 'string' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n {\n name: 'key',\n internalType: 'struct PoolKey',\n type: 'tuple',\n components: [\n { name: 'currency0', internalType: 'Currency', type: 'address' },\n { name: 'currency1', internalType: 'Currency', type: 'address' },\n { name: 'fee', internalType: 'uint24', type: 'uint24' },\n { name: 'tickSpacing', internalType: 'int24', type: 'int24' },\n { name: 'hooks', internalType: 'contract IHooks', type: 'address' },\n ],\n },\n {\n name: 'riskEngine',\n internalType: 'contract IRiskEngine',\n type: 'address',\n },\n { name: 'salt', internalType: 'uint96', type: 'uint96' },\n ],\n name: 'deployNewPool',\n outputs: [\n {\n name: 'newPoolContract',\n internalType: 'contract PanopticPoolV2',\n type: 'address',\n },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n name: 'getApproved',\n outputs: [{ name: '', internalType: 'address', type: 'address' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n {\n name: 'keyV4',\n internalType: 'struct PoolKey',\n type: 'tuple',\n components: [\n { name: 'currency0', internalType: 'Currency', type: 'address' },\n { name: 'currency1', internalType: 'Currency', type: 'address' },\n { name: 'fee', internalType: 'uint24', type: 'uint24' },\n { name: 'tickSpacing', internalType: 'int24', type: 'int24' },\n { name: 'hooks', internalType: 'contract IHooks', type: 'address' },\n ],\n },\n {\n name: 'riskEngine',\n internalType: 'contract IRiskEngine',\n type: 'address',\n },\n ],\n name: 'getPanopticPool',\n outputs: [{ name: '', internalType: 'contract PanopticPoolV2', type: 'address' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: '', internalType: 'address', type: 'address' },\n { name: '', internalType: 'address', type: 'address' },\n ],\n name: 'isApprovedForAll',\n outputs: [{ name: '', internalType: 'bool', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'deployerAddress', internalType: 'address', type: 'address' },\n {\n name: 'key',\n internalType: 'struct PoolKey',\n type: 'tuple',\n components: [\n { name: 'currency0', internalType: 'Currency', type: 'address' },\n { name: 'currency1', internalType: 'Currency', type: 'address' },\n { name: 'fee', internalType: 'uint24', type: 'uint24' },\n { name: 'tickSpacing', internalType: 'int24', type: 'int24' },\n { name: 'hooks', internalType: 'contract IHooks', type: 'address' },\n ],\n },\n { name: 'riskEngine', internalType: 'address', type: 'address' },\n { name: 'salt', internalType: 'uint96', type: 'uint96' },\n { name: 'loops', internalType: 'uint256', type: 'uint256' },\n { name: 'minTargetRarity', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'minePoolAddress',\n outputs: [\n { name: 'bestSalt', internalType: 'uint96', type: 'uint96' },\n { name: 'highestRarity', internalType: 'uint256', type: 'uint256' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'data', internalType: 'bytes[]', type: 'bytes[]' }],\n name: 'multicall',\n outputs: [{ name: 'results', internalType: 'bytes[]', type: 'bytes[]' }],\n stateMutability: 'payable',\n },\n {\n type: 'function',\n inputs: [],\n name: 'name',\n outputs: [{ name: '', internalType: 'string', type: 'string' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'id', internalType: 'uint256', type: 'uint256' }],\n name: 'ownerOf',\n outputs: [{ name: 'owner', internalType: 'address', type: 'address' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'from', internalType: 'address', type: 'address' },\n { name: 'to', internalType: 'address', type: 'address' },\n { name: 'id', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'safeTransferFrom',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'from', internalType: 'address', type: 'address' },\n { name: 'to', internalType: 'address', type: 'address' },\n { name: 'id', internalType: 'uint256', type: 'uint256' },\n { name: 'data', internalType: 'bytes', type: 'bytes' },\n ],\n name: 'safeTransferFrom',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'operator', internalType: 'address', type: 'address' },\n { name: 'approved', internalType: 'bool', type: 'bool' },\n ],\n name: 'setApprovalForAll',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }],\n name: 'supportsInterface',\n outputs: [{ name: '', internalType: 'bool', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'symbol',\n outputs: [{ name: '', internalType: 'string', type: 'string' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }],\n name: 'tokenURI',\n outputs: [{ name: '', internalType: 'string', type: 'string' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'from', internalType: 'address', type: 'address' },\n { name: 'to', internalType: 'address', type: 'address' },\n { name: 'id', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'transferFrom',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'owner',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'spender',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n { name: 'id', internalType: 'uint256', type: 'uint256', indexed: true },\n ],\n name: 'Approval',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'owner',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'operator',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n { name: 'approved', internalType: 'bool', type: 'bool', indexed: false },\n ],\n name: 'ApprovalForAll',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'poolAddress',\n internalType: 'contract PanopticPoolV2',\n type: 'address',\n indexed: true,\n },\n { name: 'idV4', internalType: 'PoolId', type: 'bytes32', indexed: true },\n {\n name: 'collateralTracker0',\n internalType: 'contract CollateralTrackerV2',\n type: 'address',\n indexed: false,\n },\n {\n name: 'collateralTracker1',\n internalType: 'contract CollateralTrackerV2',\n type: 'address',\n indexed: false,\n },\n {\n name: 'riskEngine',\n internalType: 'contract IRiskEngine',\n type: 'address',\n indexed: false,\n },\n ],\n name: 'PoolDeployed',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n { name: 'from', internalType: 'address', type: 'address', indexed: true },\n { name: 'to', internalType: 'address', type: 'address', indexed: true },\n { name: 'id', internalType: 'uint256', type: 'uint256', indexed: true },\n ],\n name: 'Transfer',\n },\n { type: 'error', inputs: [], name: 'AlreadyInitialized' },\n { type: 'error', inputs: [], name: 'CreateFail' },\n { type: 'error', inputs: [], name: 'PoolNotInitialized' },\n { type: 'error', inputs: [], name: 'ZeroAddress' },\n] as const\n\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n// PanopticGuardian\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n\nexport const panopticGuardianAbi = [\n {\n type: 'constructor',\n inputs: [\n { name: 'guardianAdmin', internalType: 'address', type: 'address' },\n { name: 'treasurer', internalType: 'address', type: 'address' },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [],\n name: 'GUARDIAN_ADMIN',\n outputs: [{ name: '', internalType: 'address', type: 'address' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'TREASURER',\n outputs: [{ name: '', internalType: 'address', type: 'address' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'UNLOCK_DELAY',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: '', internalType: 'address', type: 'address' }],\n name: 'builderAdminRevoked',\n outputs: [{ name: '', internalType: 'bool', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n {\n name: 'pool',\n internalType: 'contract PanopticPoolV2',\n type: 'address',\n },\n ],\n name: 'cancelUnlock',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n {\n name: 'riskEngine',\n internalType: 'contract IRiskEngine',\n type: 'address',\n },\n { name: 'token', internalType: 'address', type: 'address' },\n { name: 'recipient', internalType: 'address', type: 'address' },\n { name: 'amount', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'collect',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'builderCode', internalType: 'uint256', type: 'uint256' },\n { name: 'builderAdmin', internalType: 'address', type: 'address' },\n {\n name: 'builderFactory',\n internalType: 'contract BuilderFactory',\n type: 'address',\n },\n ],\n name: 'deployBuilder',\n outputs: [{ name: 'wallet', internalType: 'address', type: 'address' }],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n {\n name: 'pool',\n internalType: 'contract PanopticPoolV2',\n type: 'address',\n },\n ],\n name: 'executeUnlock',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'account', internalType: 'address', type: 'address' },\n {\n name: 'pool',\n internalType: 'contract PanopticPoolV2',\n type: 'address',\n },\n { name: 'builderCode', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'isBuilderAdmin',\n outputs: [{ name: '', internalType: 'bool', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n {\n name: 'pool',\n internalType: 'contract PanopticPoolV2',\n type: 'address',\n },\n ],\n name: 'isPoolUnlockReady',\n outputs: [{ name: '', internalType: 'bool', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n {\n name: 'pool',\n internalType: 'contract PanopticPoolV2',\n type: 'address',\n },\n ],\n name: 'lockPool',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n {\n name: 'pool',\n internalType: 'contract PanopticPoolV2',\n type: 'address',\n },\n { name: 'builderCode', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'lockPoolAsBuilder',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n {\n name: 'pool',\n internalType: 'contract PanopticPoolV2',\n type: 'address',\n },\n ],\n name: 'requestUnlock',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'admin', internalType: 'address', type: 'address' },\n { name: 'revoked', internalType: 'bool', type: 'bool' },\n ],\n name: 'setBuilderAdminRevoked',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [{ name: '', internalType: 'contract PanopticPoolV2', type: 'address' }],\n name: 'unlockEta',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'admin',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n ],\n name: 'BuilderAdminRestored',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'admin',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n ],\n name: 'BuilderAdminRevoked',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'builderCode',\n internalType: 'uint256',\n type: 'uint256',\n indexed: true,\n },\n {\n name: 'wallet',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n ],\n name: 'BuilderDeployed',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'pool',\n internalType: 'contract PanopticPoolV2',\n type: 'address',\n indexed: true,\n },\n {\n name: 'locker',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n ],\n name: 'PoolLocked',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'pool',\n internalType: 'contract PanopticPoolV2',\n type: 'address',\n indexed: true,\n },\n ],\n name: 'PoolUnlocked',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'token',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'recipient',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'amount',\n internalType: 'uint256',\n type: 'uint256',\n indexed: false,\n },\n ],\n name: 'TokensCollected',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'pool',\n internalType: 'contract PanopticPoolV2',\n type: 'address',\n indexed: true,\n },\n ],\n name: 'UnlockCancelled',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'pool',\n internalType: 'contract PanopticPoolV2',\n type: 'address',\n indexed: true,\n },\n { name: 'eta', internalType: 'uint256', type: 'uint256', indexed: false },\n ],\n name: 'UnlockRequested',\n },\n { type: 'error', inputs: [], name: 'InvalidBuilderCode' },\n { type: 'error', inputs: [], name: 'NoPendingUnlock' },\n { type: 'error', inputs: [], name: 'NotAuthorizedBuilder' },\n { type: 'error', inputs: [], name: 'NotFactoryAdmin' },\n { type: 'error', inputs: [], name: 'NotGuardianAdmin' },\n { type: 'error', inputs: [], name: 'NotTreasurer' },\n { type: 'error', inputs: [], name: 'UnlockAlreadyPending' },\n {\n type: 'error',\n inputs: [{ name: 'eta', internalType: 'uint256', type: 'uint256' }],\n name: 'UnlockNotReady',\n },\n { type: 'error', inputs: [], name: 'ZeroAddress' },\n] as const\n\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n// PanopticPoolV2\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n\nexport const panopticPoolV2Abi = [\n {\n type: 'constructor',\n inputs: [\n {\n name: '_sfpm',\n internalType: 'contract ISemiFungiblePositionManager',\n type: 'address',\n },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [],\n name: 'SFPM',\n outputs: [\n {\n name: '',\n internalType: 'contract ISemiFungiblePositionManager',\n type: 'address',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'minValue0', internalType: 'uint256', type: 'uint256' },\n { name: 'minValue1', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'assertMinCollateralValues',\n outputs: [],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'collateralToken0',\n outputs: [\n {\n name: '',\n internalType: 'contract CollateralTrackerV2',\n type: 'address',\n },\n ],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [],\n name: 'collateralToken1',\n outputs: [\n {\n name: '',\n internalType: 'contract CollateralTrackerV2',\n type: 'address',\n },\n ],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [\n { name: 'positionIdList', internalType: 'TokenId[]', type: 'uint256[]' },\n {\n name: 'finalPositionIdList',\n internalType: 'TokenId[]',\n type: 'uint256[]',\n },\n { name: 'positionSizes', internalType: 'uint128[]', type: 'uint128[]' },\n {\n name: 'tickAndSpreadLimits',\n internalType: 'int24[3][]',\n type: 'int24[3][]',\n },\n { name: 'usePremiaAsCollateral', internalType: 'bool', type: 'bool' },\n { name: 'builderCode', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'dispatch',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n {\n name: 'positionIdListFrom',\n internalType: 'TokenId[]',\n type: 'uint256[]',\n },\n { name: 'account', internalType: 'address', type: 'address' },\n {\n name: 'positionIdListTo',\n internalType: 'TokenId[]',\n type: 'uint256[]',\n },\n {\n name: 'positionIdListToFinal',\n internalType: 'TokenId[]',\n type: 'uint256[]',\n },\n {\n name: 'usePremiaAsCollateral',\n internalType: 'LeftRightUnsigned',\n type: 'uint256',\n },\n ],\n name: 'dispatchFrom',\n outputs: [],\n stateMutability: 'payable',\n },\n {\n type: 'function',\n inputs: [{ name: 'account', internalType: 'address', type: 'address' }],\n name: 'getAssetsOf',\n outputs: [\n { name: 'assets0', internalType: 'uint256', type: 'uint256' },\n { name: 'assets1', internalType: 'uint256', type: 'uint256' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'tickLower', internalType: 'int24', type: 'int24' },\n { name: 'tickUpper', internalType: 'int24', type: 'int24' },\n ],\n name: 'getChunkData',\n outputs: [\n {\n name: 'liquidities0',\n internalType: 'LeftRightUnsigned',\n type: 'uint256',\n },\n {\n name: 'liquidities1',\n internalType: 'LeftRightUnsigned',\n type: 'uint256',\n },\n { name: 'settled0', internalType: 'LeftRightUnsigned', type: 'uint256' },\n { name: 'settled1', internalType: 'LeftRightUnsigned', type: 'uint256' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'getCurrentTick',\n outputs: [{ name: 'currentTick', internalType: 'int24', type: 'int24' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'user', internalType: 'address', type: 'address' },\n { name: 'includePendingPremium', internalType: 'bool', type: 'bool' },\n { name: 'positionIdList', internalType: 'TokenId[]', type: 'uint256[]' },\n ],\n name: 'getFullPositionsData',\n outputs: [\n {\n name: 'shortPremium',\n internalType: 'LeftRightUnsigned',\n type: 'uint256',\n },\n {\n name: 'longPremium',\n internalType: 'LeftRightUnsigned',\n type: 'uint256',\n },\n {\n name: 'positionBalances',\n internalType: 'PositionBalance[]',\n type: 'uint256[]',\n },\n {\n name: 'collateralRequirements',\n internalType: 'LeftRightUnsigned[]',\n type: 'uint256[]',\n },\n {\n name: 'netPremiaPerPosition',\n internalType: 'LeftRightSigned[]',\n type: 'int256[]',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'getOracleTicks',\n outputs: [\n { name: 'currentTick', internalType: 'int24', type: 'int24' },\n { name: 'spotTick', internalType: 'int24', type: 'int24' },\n { name: 'medianTick', internalType: 'int24', type: 'int24' },\n { name: 'latestTick', internalType: 'int24', type: 'int24' },\n { name: 'oraclePack', internalType: 'OraclePack', type: 'uint256' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'builderCode', internalType: 'uint256', type: 'uint256' }],\n name: 'getRiskParameters',\n outputs: [\n {\n name: 'riskParameters',\n internalType: 'RiskParameters',\n type: 'uint256',\n },\n { name: 'currentTick', internalType: 'int24', type: 'int24' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'getTWAP',\n outputs: [{ name: 'twapTick', internalType: 'int24', type: 'int24' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'initialize',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [],\n name: 'isSafeMode',\n outputs: [{ name: '', internalType: 'uint8', type: 'uint8' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'lockSafeMode',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [{ name: 'data', internalType: 'bytes[]', type: 'bytes[]' }],\n name: 'multicall',\n outputs: [{ name: 'results', internalType: 'bytes[]', type: 'bytes[]' }],\n stateMutability: 'payable',\n },\n {\n type: 'function',\n inputs: [{ name: 'user', internalType: 'address', type: 'address' }],\n name: 'numberOfLegs',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: '', internalType: 'address', type: 'address' },\n { name: '', internalType: 'address', type: 'address' },\n { name: '', internalType: 'uint256', type: 'uint256' },\n { name: '', internalType: 'uint256', type: 'uint256' },\n { name: '', internalType: 'bytes', type: 'bytes' },\n ],\n name: 'onERC1155Received',\n outputs: [{ name: '', internalType: 'bytes4', type: 'bytes4' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [],\n name: 'pokeOracle',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [],\n name: 'poolId',\n outputs: [{ name: '', internalType: 'uint64', type: 'uint64' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [],\n name: 'poolKey',\n outputs: [{ name: 'key', internalType: 'bytes', type: 'bytes' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [],\n name: 'poolManager',\n outputs: [{ name: '', internalType: 'address', type: 'address' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [],\n name: 'reentrancyGuardEntered',\n outputs: [{ name: 'entered', internalType: 'bool', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'riskEngine',\n outputs: [{ name: '', internalType: 'contract IRiskEngine', type: 'address' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [],\n name: 'tickSpacing',\n outputs: [{ name: '', internalType: 'int24', type: 'int24' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [],\n name: 'unlockSafeMode',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'user', internalType: 'address', type: 'address' },\n { name: 'positionIdList', internalType: 'TokenId[]', type: 'uint256[]' },\n { name: 'usePremiaAsCollateral', internalType: 'bool', type: 'bool' },\n ],\n name: 'validateCollateralWithdrawable',\n outputs: [],\n stateMutability: 'view',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'liquidator',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'liquidatee',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'bonusAmounts',\n internalType: 'LeftRightSigned',\n type: 'int256',\n indexed: false,\n },\n ],\n name: 'AccountLiquidated',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'exercisor',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n { name: 'user', internalType: 'address', type: 'address', indexed: true },\n {\n name: 'tokenId',\n internalType: 'TokenId',\n type: 'uint256',\n indexed: true,\n },\n {\n name: 'exerciseFee',\n internalType: 'LeftRightSigned',\n type: 'int256',\n indexed: false,\n },\n ],\n name: 'ForcedExercised',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'recipient',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'positionSize',\n internalType: 'uint128',\n type: 'uint128',\n indexed: false,\n },\n {\n name: 'tokenId',\n internalType: 'TokenId',\n type: 'uint256',\n indexed: true,\n },\n {\n name: 'premiaByLeg',\n internalType: 'LeftRightSigned[4]',\n type: 'int256[4]',\n indexed: false,\n },\n ],\n name: 'OptionBurnt',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'recipient',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'tokenId',\n internalType: 'TokenId',\n type: 'uint256',\n indexed: true,\n },\n {\n name: 'balanceData',\n internalType: 'PositionBalance',\n type: 'uint256',\n indexed: false,\n },\n ],\n name: 'OptionMinted',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n { name: 'user', internalType: 'address', type: 'address', indexed: true },\n {\n name: 'tokenId',\n internalType: 'TokenId',\n type: 'uint256',\n indexed: true,\n },\n {\n name: 'legIndex',\n internalType: 'uint256',\n type: 'uint256',\n indexed: false,\n },\n {\n name: 'settledAmounts',\n internalType: 'LeftRightSigned',\n type: 'int256',\n indexed: false,\n },\n ],\n name: 'PremiumSettled',\n },\n {\n type: 'error',\n inputs: [\n { name: 'solvent', internalType: 'uint256', type: 'uint256' },\n { name: 'numberOfTicks', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'AccountInsolvent',\n },\n { type: 'error', inputs: [], name: 'AlreadyInitialized' },\n { type: 'error', inputs: [], name: 'CastingError' },\n { type: 'error', inputs: [], name: 'DuplicateTokenId' },\n { type: 'error', inputs: [], name: 'EffectiveLiquidityAboveThreshold' },\n { type: 'error', inputs: [], name: 'InputListFail' },\n { type: 'error', inputs: [], name: 'InvalidTick' },\n { type: 'error', inputs: [], name: 'InvalidTickBound' },\n { type: 'error', inputs: [], name: 'LiquidityTooHigh' },\n { type: 'error', inputs: [], name: 'NetLiquidityZero' },\n { type: 'error', inputs: [], name: 'NoLegsExercisable' },\n { type: 'error', inputs: [], name: 'NotGuardian' },\n { type: 'error', inputs: [], name: 'NotMarginCalled' },\n { type: 'error', inputs: [], name: 'PositionNotOwned' },\n { type: 'error', inputs: [], name: 'PriceImpactTooLarge' },\n { type: 'error', inputs: [], name: 'Reentrancy' },\n { type: 'error', inputs: [], name: 'StaleOracle' },\n { type: 'error', inputs: [], name: 'TokenIdHasZeroLegs' },\n { type: 'error', inputs: [], name: 'TooManyLegsOpen' },\n { type: 'error', inputs: [], name: 'UnderOverFlow' },\n { type: 'error', inputs: [], name: 'WrongPoolId' },\n] as const\n\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n// PanopticQuery\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n\nexport const panopticQueryAbi = [\n {\n type: 'function',\n inputs: [\n { name: 'pool', internalType: 'contract PanopticPool', type: 'address' },\n { name: 'account', internalType: 'address', type: 'address' },\n { name: 'positionIdList', internalType: 'TokenId[]', type: 'uint256[]' },\n ],\n name: 'checkCollateral',\n outputs: [\n {\n name: 'collateralBalances0',\n internalType: 'uint256[4]',\n type: 'uint256[4]',\n },\n {\n name: 'requiredCollaterals0',\n internalType: 'uint256[4]',\n type: 'uint256[4]',\n },\n {\n name: 'collateralBalances1',\n internalType: 'uint256[4]',\n type: 'uint256[4]',\n },\n {\n name: 'requiredCollaterals1',\n internalType: 'uint256[4]',\n type: 'uint256[4]',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'pool', internalType: 'contract PanopticPool', type: 'address' },\n { name: 'account', internalType: 'address', type: 'address' },\n { name: 'positionIdList', internalType: 'TokenId[]', type: 'uint256[]' },\n { name: 'atTick', internalType: 'int24', type: 'int24' },\n ],\n name: 'checkCollateral',\n outputs: [\n {\n name: 'balancesAndRequired',\n internalType: 'uint256[4]',\n type: 'uint256[4]',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'pool', internalType: 'contract PanopticPool', type: 'address' },\n { name: 'account', internalType: 'address', type: 'address' },\n { name: 'positionIdList', internalType: 'TokenId[]', type: 'uint256[]' },\n ],\n name: 'checkCollateralListOutput',\n outputs: [\n { name: '', internalType: 'uint256[4][]', type: 'uint256[4][]' },\n { name: '', internalType: 'int256[]', type: 'int256[]' },\n { name: '', internalType: 'int24[]', type: 'int24[]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'pool', internalType: 'contract PanopticPool', type: 'address' },\n { name: 'positionIdList', internalType: 'TokenId[]', type: 'uint256[]' },\n ],\n name: 'getChunkData',\n outputs: [{ name: '', internalType: 'uint256[2][4][]', type: 'uint256[2][4][]' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'pool', internalType: 'contract PanopticPool', type: 'address' },\n { name: 'account', internalType: 'address', type: 'address' },\n { name: 'positionIdList', internalType: 'TokenId[]', type: 'uint256[]' },\n ],\n name: 'getLiquidationPrices',\n outputs: [\n { name: 'liquidationPriceDown', internalType: 'int24', type: 'int24' },\n { name: 'liquidationPriceUp', internalType: 'int24', type: 'int24' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n {\n name: 'pool',\n internalType: 'contract PanopticPoolV2',\n type: 'address',\n },\n { name: 'tokenId', internalType: 'TokenId', type: 'uint256' },\n { name: 'positionSize', internalType: 'uint128', type: 'uint128' },\n ],\n name: 'getItmAmounts',\n outputs: [\n { name: 'itm0', internalType: 'int256', type: 'int256' },\n { name: 'itm1', internalType: 'int256', type: 'int256' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'pool', internalType: 'contract PanopticPool', type: 'address' },\n {\n name: 'existingPositionIds',\n internalType: 'TokenId[]',\n type: 'uint256[]',\n },\n { name: 'account', internalType: 'address', type: 'address' },\n { name: 'tokenId', internalType: 'TokenId', type: 'uint256' },\n ],\n name: 'getMaxPositionSizeBounds',\n outputs: [\n { name: 'maxSizeAtMinUtil', internalType: 'uint128', type: 'uint128' },\n { name: 'maxSizeAtMaxUtil', internalType: 'uint128', type: 'uint128' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'pool', internalType: 'contract PanopticPool', type: 'address' },\n { name: 'account', internalType: 'address', type: 'address' },\n { name: 'includePendingPremium', internalType: 'bool', type: 'bool' },\n { name: 'positionIdList', internalType: 'TokenId[]', type: 'uint256[]' },\n { name: 'atTick', internalType: 'int24', type: 'int24' },\n ],\n name: 'getNetLiquidationValue',\n outputs: [\n { name: 'value0', internalType: 'int256', type: 'int256' },\n { name: 'value1', internalType: 'int256', type: 'int256' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'pool', internalType: 'contract PanopticPool', type: 'address' },\n { name: 'account', internalType: 'address', type: 'address' },\n { name: 'atTick', internalType: 'int24', type: 'int24' },\n { name: 'positionIdList', internalType: 'TokenId[]', type: 'uint256[]' },\n ],\n name: 'getPortfolioValue',\n outputs: [\n { name: 'value0', internalType: 'int256', type: 'int256' },\n { name: 'value1', internalType: 'int256', type: 'int256' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'pool', internalType: 'contract PanopticPool', type: 'address' },\n { name: 'account', internalType: 'address', type: 'address' },\n { name: 'atTicks', internalType: 'int24[]', type: 'int24[]' },\n { name: 'positionIdList', internalType: 'TokenId[]', type: 'uint256[]' },\n ],\n name: 'getPortfolioValueAtTicks',\n outputs: [\n { name: 'value0', internalType: 'int256[]', type: 'int256[]' },\n { name: 'value1', internalType: 'int256[]', type: 'int256[]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'pool', internalType: 'contract PanopticPool', type: 'address' },\n { name: 'tokenId', internalType: 'TokenId', type: 'uint256' },\n { name: 'atTick', internalType: 'int24', type: 'int24' },\n ],\n name: 'getRequiredBase',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'pool', internalType: 'contract PanopticPool', type: 'address' },\n { name: 'startTick', internalType: 'int24', type: 'int24' },\n { name: 'nTicks', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'getTickNets',\n outputs: [\n { name: 'tickData', internalType: 'int256[]', type: 'int256[]' },\n { name: 'liquidityNets', internalType: 'int256[]', type: 'int256[]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'pool', internalType: 'contract PanopticPool', type: 'address' },\n { name: 'account', internalType: 'address', type: 'address' },\n { name: 'positionIdList', internalType: 'TokenId[]', type: 'uint256[]' },\n { name: 'atTick', internalType: 'int24', type: 'int24' },\n ],\n name: 'isAccountSolvent',\n outputs: [{ name: '', internalType: 'bool', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'pool', internalType: 'contract PanopticPool', type: 'address' },\n { name: 'atTick', internalType: 'int24', type: 'int24' },\n { name: 'tokenId', internalType: 'TokenId', type: 'uint256' },\n ],\n name: 'optimizeRiskPartners',\n outputs: [{ name: '', internalType: 'TokenId', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'pool', internalType: 'contract PanopticPool', type: 'address' },\n { name: 'tickLower', internalType: 'int24', type: 'int24' },\n { name: 'tickUpper', internalType: 'int24', type: 'int24' },\n { name: 'width', internalType: 'int24', type: 'int24' },\n ],\n name: 'scanChunks',\n outputs: [\n { name: '', internalType: 'int24[]', type: 'int24[]' },\n { name: '', internalType: 'uint128[2][]', type: 'uint128[2][]' },\n { name: '', internalType: 'uint128[2][]', type: 'uint128[2][]' },\n {\n name: '',\n internalType: 'LeftRightUnsigned[2][]',\n type: 'uint256[2][]',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'self', internalType: 'TokenId', type: 'uint256' }],\n name: 'validateTokenId',\n outputs: [],\n stateMutability: 'pure',\n },\n { type: 'error', inputs: [], name: 'CastingError' },\n { type: 'error', inputs: [], name: 'InvalidTick' },\n {\n type: 'error',\n inputs: [{ name: 'parameterType', internalType: 'uint256', type: 'uint256' }],\n name: 'InvalidTokenIdParameter',\n },\n { type: 'error', inputs: [], name: 'LiquidityTooHigh' },\n { type: 'error', inputs: [], name: 'UnderOverFlow' },\n] as const\n\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n// RiskEngine\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n\nexport const riskEngineAbi = [\n {\n type: 'constructor',\n inputs: [\n { name: '_crossBuffer0', internalType: 'uint256', type: 'uint256' },\n { name: '_crossBuffer1', internalType: 'uint256', type: 'uint256' },\n { name: '_guardian', internalType: 'address', type: 'address' },\n { name: '_builderFactory', internalType: 'address', type: 'address' },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [],\n name: 'ADJUSTMENT_SPEED',\n outputs: [{ name: '', internalType: 'int256', type: 'int256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'BP_DECREASE_BUFFER',\n outputs: [{ name: '', internalType: 'uint32', type: 'uint32' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'BUILDER_FACTORY',\n outputs: [{ name: '', internalType: 'address', type: 'address' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'BUILDER_SPLIT',\n outputs: [{ name: '', internalType: 'uint16', type: 'uint16' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'BUYER_COLLATERAL_RATIO',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'CROSS_BUFFER_0',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'CROSS_BUFFER_1',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'CURVE_STEEPNESS',\n outputs: [{ name: '', internalType: 'int256', type: 'int256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'DECIMALS',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'EMA_PERIODS',\n outputs: [{ name: '', internalType: 'uint96', type: 'uint96' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'FORCE_EXERCISE_COST',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'GUARDIAN',\n outputs: [{ name: '', internalType: 'address', type: 'address' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'INITIAL_RATE_AT_TARGET',\n outputs: [{ name: '', internalType: 'int256', type: 'int256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'IRM_MAX_ELAPSED_TIME',\n outputs: [{ name: '', internalType: 'int256', type: 'int256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'MAINT_MARGIN_RATE',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'MAX_BONUS',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'MAX_CLAMP_DELTA',\n outputs: [{ name: '', internalType: 'int24', type: 'int24' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'MAX_OPEN_LEGS',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'MAX_RATE_AT_TARGET',\n outputs: [{ name: '', internalType: 'int256', type: 'int256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'MAX_SPREAD',\n outputs: [{ name: '', internalType: 'uint24', type: 'uint24' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'MAX_TICKS_DELTA',\n outputs: [{ name: '', internalType: 'int256', type: 'int256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'MAX_TWAP_DELTA_DISPATCH',\n outputs: [{ name: '', internalType: 'uint16', type: 'uint16' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'MIN_RATE_AT_TARGET',\n outputs: [{ name: '', internalType: 'int256', type: 'int256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'NOTIONAL_FEE',\n outputs: [{ name: '', internalType: 'uint16', type: 'uint16' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'PREMIUM_FEE',\n outputs: [{ name: '', internalType: 'uint16', type: 'uint16' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'PROTOCOL_SPLIT',\n outputs: [{ name: '', internalType: 'uint16', type: 'uint16' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'SATURATED_POOL_UTIL',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'SELLER_COLLATERAL_RATIO',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'TARGET_POOL_UTIL',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'TARGET_UTILIZATION',\n outputs: [{ name: '', internalType: 'int256', type: 'int256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'VEGOID',\n outputs: [{ name: '', internalType: 'uint8', type: 'uint8' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'token', internalType: 'address', type: 'address' },\n { name: 'recipient', internalType: 'address', type: 'address' },\n ],\n name: 'collect',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'token', internalType: 'address', type: 'address' },\n { name: 'recipient', internalType: 'address', type: 'address' },\n { name: 'amount', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'collect',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'oraclePack', internalType: 'OraclePack', type: 'uint256' },\n { name: 'currentTick', internalType: 'int24', type: 'int24' },\n ],\n name: 'computeInternalMedian',\n outputs: [\n { name: 'medianTick', internalType: 'int24', type: 'int24' },\n {\n name: 'updatedOraclePack',\n internalType: 'OraclePack',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'utilization', internalType: 'int256', type: 'int256' },\n { name: 'crossBuffer', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'crossBufferRatio',\n outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [\n { name: 'currentTick', internalType: 'int24', type: 'int24' },\n { name: 'oracleTick', internalType: 'int24', type: 'int24' },\n { name: 'tokenId', internalType: 'TokenId', type: 'uint256' },\n {\n name: 'positionBalance',\n internalType: 'PositionBalance',\n type: 'uint256',\n },\n ],\n name: 'exerciseCost',\n outputs: [{ name: 'exerciseFees', internalType: 'LeftRightSigned', type: 'int256' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [{ name: 'builderCode', internalType: 'uint256', type: 'uint256' }],\n name: 'getFeeRecipient',\n outputs: [{ name: 'feeRecipient', internalType: 'address', type: 'address' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n {\n name: 'tokenData0',\n internalType: 'LeftRightUnsigned',\n type: 'uint256',\n },\n {\n name: 'tokenData1',\n internalType: 'LeftRightUnsigned',\n type: 'uint256',\n },\n { name: 'atSqrtPriceX96', internalType: 'uint160', type: 'uint160' },\n { name: 'netPaid', internalType: 'LeftRightSigned', type: 'int256' },\n {\n name: 'shortPremium',\n internalType: 'LeftRightUnsigned',\n type: 'uint256',\n },\n {\n name: 'loanAmounts',\n internalType: 'LeftRightUnsigned',\n type: 'uint256',\n },\n ],\n name: 'getLiquidationBonus',\n outputs: [\n { name: '', internalType: 'LeftRightSigned', type: 'int256' },\n { name: '', internalType: 'LeftRightSigned', type: 'int256' },\n ],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [\n {\n name: 'positionBalanceArray',\n internalType: 'PositionBalance[]',\n type: 'uint256[]',\n },\n { name: 'atTick', internalType: 'int24', type: 'int24' },\n { name: 'user', internalType: 'address', type: 'address' },\n { name: 'positionIdList', internalType: 'TokenId[]', type: 'uint256[]' },\n {\n name: 'shortPremia',\n internalType: 'LeftRightUnsigned',\n type: 'uint256',\n },\n {\n name: 'longPremia',\n internalType: 'LeftRightUnsigned',\n type: 'uint256',\n },\n {\n name: 'ct0',\n internalType: 'contract CollateralTrackerV2',\n type: 'address',\n },\n {\n name: 'ct1',\n internalType: 'contract CollateralTrackerV2',\n type: 'address',\n },\n ],\n name: 'getMargin',\n outputs: [\n {\n name: 'tokenData0',\n internalType: 'LeftRightUnsigned',\n type: 'uint256',\n },\n {\n name: 'tokenData1',\n internalType: 'LeftRightUnsigned',\n type: 'uint256',\n },\n {\n name: 'globalUtilizations',\n internalType: 'PositionBalance',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'currentTick', internalType: 'int24', type: 'int24' },\n { name: '_oraclePack', internalType: 'OraclePack', type: 'uint256' },\n ],\n name: 'getOracleTicks',\n outputs: [\n { name: 'spotTick', internalType: 'int24', type: 'int24' },\n { name: 'medianTick', internalType: 'int24', type: 'int24' },\n { name: 'latestTick', internalType: 'int24', type: 'int24' },\n { name: 'oraclePack', internalType: 'OraclePack', type: 'uint256' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n {\n name: 'positionBalanceArray',\n internalType: 'PositionBalance[]',\n type: 'uint256[]',\n },\n { name: 'positionIdList', internalType: 'TokenId[]', type: 'uint256[]' },\n { name: 'atTick', internalType: 'int24', type: 'int24' },\n ],\n name: 'getPerPositionCollateralRequirements',\n outputs: [\n {\n name: 'collateralRequirements',\n internalType: 'LeftRightUnsigned[]',\n type: 'uint256[]',\n },\n ],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [\n { name: 'payor', internalType: 'address', type: 'address' },\n { name: 'fees', internalType: 'LeftRightSigned', type: 'int256' },\n { name: 'atTick', internalType: 'int24', type: 'int24' },\n {\n name: 'ct0',\n internalType: 'contract CollateralTrackerV2',\n type: 'address',\n },\n {\n name: 'ct1',\n internalType: 'contract CollateralTrackerV2',\n type: 'address',\n },\n ],\n name: 'getRefundAmounts',\n outputs: [{ name: '', internalType: 'LeftRightSigned', type: 'int256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'currentTick', internalType: 'int24', type: 'int24' },\n { name: 'oraclePack', internalType: 'OraclePack', type: 'uint256' },\n { name: 'builderCode', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'getRiskParameters',\n outputs: [{ name: '', internalType: 'RiskParameters', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'currentTick', internalType: 'int24', type: 'int24' },\n { name: '_oraclePack', internalType: 'OraclePack', type: 'uint256' },\n { name: 'safeMode', internalType: 'uint8', type: 'uint8' },\n ],\n name: 'getSolvencyTicks',\n outputs: [\n { name: '', internalType: 'int24[]', type: 'int24[]' },\n { name: '', internalType: 'OraclePack', type: 'uint256' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'positionIdList', internalType: 'TokenId[]', type: 'uint256[]' },\n {\n name: 'premiasByLeg',\n internalType: 'LeftRightSigned[4][]',\n type: 'int256[4][]',\n },\n {\n name: 'collateralRemaining',\n internalType: 'LeftRightSigned',\n type: 'int256',\n },\n { name: 'atSqrtPriceX96', internalType: 'uint160', type: 'uint160' },\n ],\n name: 'haircutPremia',\n outputs: [\n { name: 'bonusDeltas', internalType: 'LeftRightSigned', type: 'int256' },\n {\n name: 'haircutTotal',\n internalType: 'LeftRightUnsigned',\n type: 'uint256',\n },\n {\n name: 'haircutPerLeg',\n internalType: 'LeftRightSigned[4][]',\n type: 'int256[4][]',\n },\n ],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [\n { name: 'utilization', internalType: 'uint256', type: 'uint256' },\n {\n name: 'interestRateAccumulator',\n internalType: 'MarketState',\n type: 'uint256',\n },\n ],\n name: 'interestRate',\n outputs: [{ name: '', internalType: 'uint128', type: 'uint128' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n {\n name: 'positionBalanceArray',\n internalType: 'PositionBalance[]',\n type: 'uint256[]',\n },\n { name: 'positionIdList', internalType: 'TokenId[]', type: 'uint256[]' },\n { name: 'atTick', internalType: 'int24', type: 'int24' },\n { name: 'user', internalType: 'address', type: 'address' },\n {\n name: 'shortPremia',\n internalType: 'LeftRightUnsigned',\n type: 'uint256',\n },\n {\n name: 'longPremia',\n internalType: 'LeftRightUnsigned',\n type: 'uint256',\n },\n {\n name: 'ct0',\n internalType: 'contract CollateralTrackerV2',\n type: 'address',\n },\n {\n name: 'ct1',\n internalType: 'contract CollateralTrackerV2',\n type: 'address',\n },\n { name: 'buffer', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'isAccountSolvent',\n outputs: [{ name: '', internalType: 'bool', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'currentTick', internalType: 'int24', type: 'int24' },\n { name: 'oraclePack', internalType: 'OraclePack', type: 'uint256' },\n ],\n name: 'isSafeMode',\n outputs: [{ name: 'safeMode', internalType: 'uint8', type: 'uint8' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [\n {\n name: 'pool',\n internalType: 'contract PanopticPoolV2',\n type: 'address',\n },\n ],\n name: 'lockPool',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [{ name: 'oraclePack', internalType: 'OraclePack', type: 'uint256' }],\n name: 'twapEMA',\n outputs: [{ name: '', internalType: 'int24', type: 'int24' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [\n {\n name: 'pool',\n internalType: 'contract PanopticPoolV2',\n type: 'address',\n },\n ],\n name: 'unlockPool',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'utilization', internalType: 'uint256', type: 'uint256' },\n {\n name: 'interestRateAccumulator',\n internalType: 'MarketState',\n type: 'uint256',\n },\n ],\n name: 'updateInterestRate',\n outputs: [\n { name: '', internalType: 'uint128', type: 'uint128' },\n { name: '', internalType: 'uint256', type: 'uint256' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [],\n name: 'vegoid',\n outputs: [{ name: '', internalType: 'uint8', type: 'uint8' }],\n stateMutability: 'pure',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'collateralToken',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'avgBorrowRate',\n internalType: 'uint256',\n type: 'uint256',\n indexed: false,\n },\n {\n name: 'rateAtTarget',\n internalType: 'uint256',\n type: 'uint256',\n indexed: false,\n },\n ],\n name: 'BorrowRateUpdated',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [{ name: 'lockMode', internalType: 'bool', type: 'bool', indexed: false }],\n name: 'GuardianSafeModeUpdated',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'token',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'recipient',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'amount',\n internalType: 'uint256',\n type: 'uint256',\n indexed: false,\n },\n ],\n name: 'TokensCollected',\n },\n { type: 'error', inputs: [], name: 'BelowMinimumRedemption' },\n { type: 'error', inputs: [], name: 'CastingError' },\n { type: 'error', inputs: [], name: 'InvalidBuilderCode' },\n { type: 'error', inputs: [], name: 'InvalidTick' },\n { type: 'error', inputs: [], name: 'LengthMismatch' },\n { type: 'error', inputs: [], name: 'LiquidityTooHigh' },\n { type: 'error', inputs: [], name: 'NotGuardian' },\n {\n type: 'error',\n inputs: [\n { name: 'token', internalType: 'address', type: 'address' },\n { name: 'from', internalType: 'address', type: 'address' },\n { name: 'amount', internalType: 'uint256', type: 'uint256' },\n { name: 'balance', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'TransferFailed',\n },\n { type: 'error', inputs: [], name: 'UnderOverFlow' },\n] as const\n\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n// SemiFungiblePositionManagerV3\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n\nexport const semiFungiblePositionManagerV3Abi = [\n {\n type: 'constructor',\n inputs: [\n {\n name: '_factory',\n internalType: 'contract IUniswapV3Factory',\n type: 'address',\n },\n {\n name: '_minEnforcedTickFillCost',\n internalType: 'uint256',\n type: 'uint256',\n },\n {\n name: '_supplyMultiplierTickFill',\n internalType: 'uint256',\n type: 'uint256',\n },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'account', internalType: 'address', type: 'address' },\n { name: 'tokenId', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'balanceOf',\n outputs: [{ name: 'balance', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'owners', internalType: 'address[]', type: 'address[]' },\n { name: 'ids', internalType: 'uint256[]', type: 'uint256[]' },\n ],\n name: 'balanceOfBatch',\n outputs: [{ name: 'balances', internalType: 'uint256[]', type: 'uint256[]' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'poolKey', internalType: 'bytes', type: 'bytes' },\n { name: 'tokenId', internalType: 'TokenId', type: 'uint256' },\n { name: 'positionSize', internalType: 'uint128', type: 'uint128' },\n { name: 'tickLimitLow', internalType: 'int24', type: 'int24' },\n { name: 'tickLimitHigh', internalType: 'int24', type: 'int24' },\n ],\n name: 'burnTokenizedPosition',\n outputs: [\n { name: '', internalType: 'LeftRightUnsigned[4]', type: 'uint256[4]' },\n { name: '', internalType: 'LeftRightSigned', type: 'int256' },\n { name: '', internalType: 'int24', type: 'int24' },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [{ name: 'poolId', internalType: 'uint64', type: 'uint64' }],\n name: 'expandEnforcedTickRange',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'poolKey', internalType: 'bytes', type: 'bytes' },\n { name: 'owner', internalType: 'address', type: 'address' },\n { name: 'tokenType', internalType: 'uint256', type: 'uint256' },\n { name: 'tickLower', internalType: 'int24', type: 'int24' },\n { name: 'tickUpper', internalType: 'int24', type: 'int24' },\n ],\n name: 'getAccountFeesBase',\n outputs: [\n { name: 'feesBase0', internalType: 'int128', type: 'int128' },\n { name: 'feesBase1', internalType: 'int128', type: 'int128' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'poolKey', internalType: 'bytes', type: 'bytes' },\n { name: 'owner', internalType: 'address', type: 'address' },\n { name: 'tokenType', internalType: 'uint256', type: 'uint256' },\n { name: 'tickLower', internalType: 'int24', type: 'int24' },\n { name: 'tickUpper', internalType: 'int24', type: 'int24' },\n ],\n name: 'getAccountLiquidity',\n outputs: [\n {\n name: 'accountLiquidities',\n internalType: 'LeftRightUnsigned',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'poolKey', internalType: 'bytes', type: 'bytes' },\n { name: 'owner', internalType: 'address', type: 'address' },\n { name: 'tokenType', internalType: 'uint256', type: 'uint256' },\n { name: 'tickLower', internalType: 'int24', type: 'int24' },\n { name: 'tickUpper', internalType: 'int24', type: 'int24' },\n { name: 'atTick', internalType: 'int24', type: 'int24' },\n { name: 'isLong', internalType: 'uint256', type: 'uint256' },\n { name: 'vegoid', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'getAccountPremium',\n outputs: [\n { name: '', internalType: 'uint128', type: 'uint128' },\n { name: '', internalType: 'uint128', type: 'uint128' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'poolKey', internalType: 'bytes', type: 'bytes' }],\n name: 'getCurrentTick',\n outputs: [{ name: 'currentTick', internalType: 'int24', type: 'int24' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'poolId', internalType: 'uint64', type: 'uint64' }],\n name: 'getEnforcedTickLimits',\n outputs: [\n { name: '', internalType: 'int24', type: 'int24' },\n { name: '', internalType: 'int24', type: 'int24' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'id', internalType: 'bytes', type: 'bytes' },\n { name: 'vegoid', internalType: 'uint8', type: 'uint8' },\n ],\n name: 'getPoolId',\n outputs: [{ name: 'poolId', internalType: 'uint64', type: 'uint64' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'poolId', internalType: 'uint64', type: 'uint64' }],\n name: 'getUniswapV3PoolFromId',\n outputs: [\n {\n name: 'uniswapV3Pool',\n internalType: 'contract IUniswapV3Pool',\n type: 'address',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'token0', internalType: 'address', type: 'address' },\n { name: 'token1', internalType: 'address', type: 'address' },\n { name: 'fee', internalType: 'uint24', type: 'uint24' },\n { name: 'vegoid', internalType: 'uint8', type: 'uint8' },\n ],\n name: 'initializeAMMPool',\n outputs: [{ name: 'poolId', internalType: 'uint64', type: 'uint64' }],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'owner', internalType: 'address', type: 'address' },\n { name: 'operator', internalType: 'address', type: 'address' },\n ],\n name: 'isApprovedForAll',\n outputs: [{ name: 'approvedForAll', internalType: 'bool', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'poolKey', internalType: 'bytes', type: 'bytes' },\n { name: 'tokenId', internalType: 'TokenId', type: 'uint256' },\n { name: 'positionSize', internalType: 'uint128', type: 'uint128' },\n { name: 'tickLimitLow', internalType: 'int24', type: 'int24' },\n { name: 'tickLimitHigh', internalType: 'int24', type: 'int24' },\n ],\n name: 'mintTokenizedPosition',\n outputs: [\n { name: '', internalType: 'LeftRightUnsigned[4]', type: 'uint256[4]' },\n { name: '', internalType: 'LeftRightSigned', type: 'int256' },\n { name: '', internalType: 'int24', type: 'int24' },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [{ name: 'data', internalType: 'bytes[]', type: 'bytes[]' }],\n name: 'multicall',\n outputs: [{ name: 'results', internalType: 'bytes[]', type: 'bytes[]' }],\n stateMutability: 'payable',\n },\n {\n type: 'function',\n inputs: [],\n name: 'reentrancyGuardEntered',\n outputs: [{ name: 'entered', internalType: 'bool', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: '', internalType: 'address', type: 'address' },\n { name: '', internalType: 'address', type: 'address' },\n { name: '', internalType: 'uint256[]', type: 'uint256[]' },\n { name: '', internalType: 'uint256[]', type: 'uint256[]' },\n { name: '', internalType: 'bytes', type: 'bytes' },\n ],\n name: 'safeBatchTransferFrom',\n outputs: [],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [\n { name: '', internalType: 'address', type: 'address' },\n { name: '', internalType: 'address', type: 'address' },\n { name: '', internalType: 'uint256', type: 'uint256' },\n { name: '', internalType: 'uint256', type: 'uint256' },\n { name: '', internalType: 'bytes', type: 'bytes' },\n ],\n name: 'safeTransferFrom',\n outputs: [],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [\n { name: 'operator', internalType: 'address', type: 'address' },\n { name: 'approved', internalType: 'bool', type: 'bool' },\n ],\n name: 'setApprovalForAll',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }],\n name: 'supportsInterface',\n outputs: [{ name: '', internalType: 'bool', type: 'bool' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [\n { name: 'amount0Owed', internalType: 'uint256', type: 'uint256' },\n { name: 'amount1Owed', internalType: 'uint256', type: 'uint256' },\n { name: 'data', internalType: 'bytes', type: 'bytes' },\n ],\n name: 'uniswapV3MintCallback',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'amount0Delta', internalType: 'int256', type: 'int256' },\n { name: 'amount1Delta', internalType: 'int256', type: 'int256' },\n { name: 'data', internalType: 'bytes', type: 'bytes' },\n ],\n name: 'uniswapV3SwapCallback',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'owner',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'operator',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n { name: 'approved', internalType: 'bool', type: 'bool', indexed: false },\n ],\n name: 'ApprovalForAll',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'uniswapPool',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'minEnforcedTick',\n internalType: 'int24',\n type: 'int24',\n indexed: false,\n },\n {\n name: 'maxEnforcedTick',\n internalType: 'int24',\n type: 'int24',\n indexed: false,\n },\n ],\n name: 'EnforcedTicksUpdated',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'univ3pool',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'owner',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'tokenType',\n internalType: 'uint256',\n type: 'uint256',\n indexed: true,\n },\n {\n name: 'tickLower',\n internalType: 'int24',\n type: 'int24',\n indexed: false,\n },\n {\n name: 'tickUpper',\n internalType: 'int24',\n type: 'int24',\n indexed: false,\n },\n {\n name: 'liquidityDelta',\n internalType: 'int128',\n type: 'int128',\n indexed: false,\n },\n ],\n name: 'LiquidityChunkUpdated',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'uniswapPool',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'poolId',\n internalType: 'uint64',\n type: 'uint64',\n indexed: false,\n },\n {\n name: 'minEnforcedTick',\n internalType: 'int24',\n type: 'int24',\n indexed: false,\n },\n {\n name: 'maxEnforcedTick',\n internalType: 'int24',\n type: 'int24',\n indexed: false,\n },\n ],\n name: 'PoolInitialized',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'recipient',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'tokenId',\n internalType: 'TokenId',\n type: 'uint256',\n indexed: true,\n },\n {\n name: 'positionSize',\n internalType: 'uint128',\n type: 'uint128',\n indexed: false,\n },\n ],\n name: 'TokenizedPositionBurnt',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'caller',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'tokenId',\n internalType: 'TokenId',\n type: 'uint256',\n indexed: true,\n },\n {\n name: 'positionSize',\n internalType: 'uint128',\n type: 'uint128',\n indexed: false,\n },\n ],\n name: 'TokenizedPositionMinted',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'operator',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n { name: 'from', internalType: 'address', type: 'address', indexed: true },\n { name: 'to', internalType: 'address', type: 'address', indexed: true },\n {\n name: 'ids',\n internalType: 'uint256[]',\n type: 'uint256[]',\n indexed: false,\n },\n {\n name: 'amounts',\n internalType: 'uint256[]',\n type: 'uint256[]',\n indexed: false,\n },\n ],\n name: 'TransferBatch',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'operator',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n { name: 'from', internalType: 'address', type: 'address', indexed: true },\n { name: 'to', internalType: 'address', type: 'address', indexed: true },\n { name: 'id', internalType: 'uint256', type: 'uint256', indexed: false },\n {\n name: 'amount',\n internalType: 'uint256',\n type: 'uint256',\n indexed: false,\n },\n ],\n name: 'TransferSingle',\n },\n { type: 'error', inputs: [], name: 'CastingError' },\n { type: 'error', inputs: [], name: 'ChunkHasZeroLiquidity' },\n { type: 'error', inputs: [], name: 'InvalidTick' },\n { type: 'error', inputs: [], name: 'InvalidTickBound' },\n {\n type: 'error',\n inputs: [{ name: 'parameterType', internalType: 'uint256', type: 'uint256' }],\n name: 'InvalidTokenIdParameter',\n },\n { type: 'error', inputs: [], name: 'InvalidUniswapCallback' },\n { type: 'error', inputs: [], name: 'LiquidityTooHigh' },\n { type: 'error', inputs: [], name: 'NotAuthorized' },\n { type: 'error', inputs: [], name: 'NotEnoughLiquidityInChunk' },\n { type: 'error', inputs: [], name: 'PoolNotInitialized' },\n { type: 'error', inputs: [], name: 'PositionTooLarge' },\n {\n type: 'error',\n inputs: [{ name: 'currentTick', internalType: 'int24', type: 'int24' }],\n name: 'PriceBoundFail',\n },\n { type: 'error', inputs: [], name: 'Reentrancy' },\n {\n type: 'error',\n inputs: [\n { name: 'token', internalType: 'address', type: 'address' },\n { name: 'from', internalType: 'address', type: 'address' },\n { name: 'amount', internalType: 'uint256', type: 'uint256' },\n { name: 'balance', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'TransferFailed',\n },\n { type: 'error', inputs: [], name: 'UnderOverFlow' },\n { type: 'error', inputs: [], name: 'UnsafeRecipient' },\n { type: 'error', inputs: [], name: 'WrongUniswapPool' },\n] as const\n\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n// SemiFungiblePositionManagerV4\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n\nexport const semiFungiblePositionManagerV4Abi = [\n {\n type: 'constructor',\n inputs: [\n {\n name: 'poolManager',\n internalType: 'contract IPoolManager',\n type: 'address',\n },\n {\n name: '_minEnforcedTickFillCost',\n internalType: 'uint256',\n type: 'uint256',\n },\n {\n name: '_nativeEnforcedTickFillCost',\n internalType: 'uint256',\n type: 'uint256',\n },\n {\n name: '_supplyMultiplierTickFill',\n internalType: 'uint256',\n type: 'uint256',\n },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'account', internalType: 'address', type: 'address' },\n { name: 'tokenId', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'balanceOf',\n outputs: [{ name: 'balance', internalType: 'uint256', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'owners', internalType: 'address[]', type: 'address[]' },\n { name: 'ids', internalType: 'uint256[]', type: 'uint256[]' },\n ],\n name: 'balanceOfBatch',\n outputs: [{ name: 'balances', internalType: 'uint256[]', type: 'uint256[]' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'poolKey', internalType: 'bytes', type: 'bytes' },\n { name: 'tokenId', internalType: 'TokenId', type: 'uint256' },\n { name: 'positionSize', internalType: 'uint128', type: 'uint128' },\n { name: 'tickLimitLow', internalType: 'int24', type: 'int24' },\n { name: 'tickLimitHigh', internalType: 'int24', type: 'int24' },\n ],\n name: 'burnTokenizedPosition',\n outputs: [\n { name: '', internalType: 'LeftRightUnsigned[4]', type: 'uint256[4]' },\n { name: '', internalType: 'LeftRightSigned', type: 'int256' },\n { name: '', internalType: 'int24', type: 'int24' },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [{ name: 'poolId', internalType: 'uint64', type: 'uint64' }],\n name: 'expandEnforcedTickRange',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'poolKey', internalType: 'bytes', type: 'bytes' },\n { name: 'owner', internalType: 'address', type: 'address' },\n { name: 'tokenType', internalType: 'uint256', type: 'uint256' },\n { name: 'tickLower', internalType: 'int24', type: 'int24' },\n { name: 'tickUpper', internalType: 'int24', type: 'int24' },\n ],\n name: 'getAccountLiquidity',\n outputs: [\n {\n name: 'accountLiquidities',\n internalType: 'LeftRightUnsigned',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'poolKey', internalType: 'bytes', type: 'bytes' },\n { name: 'owner', internalType: 'address', type: 'address' },\n { name: 'tokenType', internalType: 'uint256', type: 'uint256' },\n { name: 'tickLower', internalType: 'int24', type: 'int24' },\n { name: 'tickUpper', internalType: 'int24', type: 'int24' },\n { name: 'atTick', internalType: 'int24', type: 'int24' },\n { name: 'isLong', internalType: 'uint256', type: 'uint256' },\n { name: 'vegoid', internalType: 'uint256', type: 'uint256' },\n ],\n name: 'getAccountPremium',\n outputs: [\n { name: '', internalType: 'uint128', type: 'uint128' },\n { name: '', internalType: 'uint128', type: 'uint128' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'poolKey', internalType: 'bytes', type: 'bytes' }],\n name: 'getCurrentTick',\n outputs: [{ name: 'currentTick', internalType: 'int24', type: 'int24' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'poolId', internalType: 'uint64', type: 'uint64' }],\n name: 'getEnforcedTickLimits',\n outputs: [\n { name: '', internalType: 'int24', type: 'int24' },\n { name: '', internalType: 'int24', type: 'int24' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'id', internalType: 'bytes', type: 'bytes' },\n { name: 'vegoid', internalType: 'uint8', type: 'uint8' },\n ],\n name: 'getPoolId',\n outputs: [{ name: '', internalType: 'uint64', type: 'uint64' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [{ name: 'poolId', internalType: 'uint64', type: 'uint64' }],\n name: 'getUniswapV4PoolKeyFromId',\n outputs: [\n {\n name: '',\n internalType: 'struct PoolKey',\n type: 'tuple',\n components: [\n { name: 'currency0', internalType: 'Currency', type: 'address' },\n { name: 'currency1', internalType: 'Currency', type: 'address' },\n { name: 'fee', internalType: 'uint24', type: 'uint24' },\n { name: 'tickSpacing', internalType: 'int24', type: 'int24' },\n { name: 'hooks', internalType: 'contract IHooks', type: 'address' },\n ],\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n {\n name: 'key',\n internalType: 'struct PoolKey',\n type: 'tuple',\n components: [\n { name: 'currency0', internalType: 'Currency', type: 'address' },\n { name: 'currency1', internalType: 'Currency', type: 'address' },\n { name: 'fee', internalType: 'uint24', type: 'uint24' },\n { name: 'tickSpacing', internalType: 'int24', type: 'int24' },\n { name: 'hooks', internalType: 'contract IHooks', type: 'address' },\n ],\n },\n { name: 'vegoid', internalType: 'uint8', type: 'uint8' },\n ],\n name: 'initializeAMMPool',\n outputs: [{ name: 'poolId', internalType: 'uint64', type: 'uint64' }],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [\n { name: 'owner', internalType: 'address', type: 'address' },\n { name: 'operator', internalType: 'address', type: 'address' },\n ],\n name: 'isApprovedForAll',\n outputs: [{ name: 'approvedForAll', internalType: 'bool', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: 'poolKey', internalType: 'bytes', type: 'bytes' },\n { name: 'tokenId', internalType: 'TokenId', type: 'uint256' },\n { name: 'positionSize', internalType: 'uint128', type: 'uint128' },\n { name: 'tickLimitLow', internalType: 'int24', type: 'int24' },\n { name: 'tickLimitHigh', internalType: 'int24', type: 'int24' },\n ],\n name: 'mintTokenizedPosition',\n outputs: [\n { name: '', internalType: 'LeftRightUnsigned[4]', type: 'uint256[4]' },\n { name: '', internalType: 'LeftRightSigned', type: 'int256' },\n { name: '', internalType: 'int24', type: 'int24' },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [{ name: 'data', internalType: 'bytes[]', type: 'bytes[]' }],\n name: 'multicall',\n outputs: [{ name: 'results', internalType: 'bytes[]', type: 'bytes[]' }],\n stateMutability: 'payable',\n },\n {\n type: 'function',\n inputs: [],\n name: 'reentrancyGuardEntered',\n outputs: [{ name: 'entered', internalType: 'bool', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n inputs: [\n { name: '', internalType: 'address', type: 'address' },\n { name: '', internalType: 'address', type: 'address' },\n { name: '', internalType: 'uint256[]', type: 'uint256[]' },\n { name: '', internalType: 'uint256[]', type: 'uint256[]' },\n { name: '', internalType: 'bytes', type: 'bytes' },\n ],\n name: 'safeBatchTransferFrom',\n outputs: [],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [\n { name: '', internalType: 'address', type: 'address' },\n { name: '', internalType: 'address', type: 'address' },\n { name: '', internalType: 'uint256', type: 'uint256' },\n { name: '', internalType: 'uint256', type: 'uint256' },\n { name: '', internalType: 'bytes', type: 'bytes' },\n ],\n name: 'safeTransferFrom',\n outputs: [],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [\n { name: 'operator', internalType: 'address', type: 'address' },\n { name: 'approved', internalType: 'bool', type: 'bool' },\n ],\n name: 'setApprovalForAll',\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }],\n name: 'supportsInterface',\n outputs: [{ name: '', internalType: 'bool', type: 'bool' }],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n inputs: [{ name: 'data', internalType: 'bytes', type: 'bytes' }],\n name: 'unlockCallback',\n outputs: [{ name: '', internalType: 'bytes', type: 'bytes' }],\n stateMutability: 'nonpayable',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'owner',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'operator',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n { name: 'approved', internalType: 'bool', type: 'bool', indexed: false },\n ],\n name: 'ApprovalForAll',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n { name: 'idV4', internalType: 'PoolId', type: 'bytes32', indexed: true },\n {\n name: 'minEnforcedTick',\n internalType: 'int24',\n type: 'int24',\n indexed: false,\n },\n {\n name: 'maxEnforcedTick',\n internalType: 'int24',\n type: 'int24',\n indexed: false,\n },\n ],\n name: 'EnforcedTicksUpdated',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'poolId',\n internalType: 'PoolId',\n type: 'bytes32',\n indexed: true,\n },\n {\n name: 'owner',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'tokenType',\n internalType: 'uint256',\n type: 'uint256',\n indexed: true,\n },\n {\n name: 'tickLower',\n internalType: 'int24',\n type: 'int24',\n indexed: false,\n },\n {\n name: 'tickUpper',\n internalType: 'int24',\n type: 'int24',\n indexed: false,\n },\n {\n name: 'liquidityDelta',\n internalType: 'int128',\n type: 'int128',\n indexed: false,\n },\n ],\n name: 'LiquidityChunkUpdated',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n { name: 'idV4', internalType: 'PoolId', type: 'bytes32', indexed: true },\n {\n name: 'poolId',\n internalType: 'uint64',\n type: 'uint64',\n indexed: false,\n },\n {\n name: 'minEnforcedTick',\n internalType: 'int24',\n type: 'int24',\n indexed: false,\n },\n {\n name: 'maxEnforcedTick',\n internalType: 'int24',\n type: 'int24',\n indexed: false,\n },\n ],\n name: 'PoolInitialized',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'recipient',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'tokenId',\n internalType: 'TokenId',\n type: 'uint256',\n indexed: true,\n },\n {\n name: 'positionSize',\n internalType: 'uint128',\n type: 'uint128',\n indexed: false,\n },\n ],\n name: 'TokenizedPositionBurnt',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'caller',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n {\n name: 'tokenId',\n internalType: 'TokenId',\n type: 'uint256',\n indexed: true,\n },\n {\n name: 'positionSize',\n internalType: 'uint128',\n type: 'uint128',\n indexed: false,\n },\n ],\n name: 'TokenizedPositionMinted',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'operator',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n { name: 'from', internalType: 'address', type: 'address', indexed: true },\n { name: 'to', internalType: 'address', type: 'address', indexed: true },\n {\n name: 'ids',\n internalType: 'uint256[]',\n type: 'uint256[]',\n indexed: false,\n },\n {\n name: 'amounts',\n internalType: 'uint256[]',\n type: 'uint256[]',\n indexed: false,\n },\n ],\n name: 'TransferBatch',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n {\n name: 'operator',\n internalType: 'address',\n type: 'address',\n indexed: true,\n },\n { name: 'from', internalType: 'address', type: 'address', indexed: true },\n { name: 'to', internalType: 'address', type: 'address', indexed: true },\n { name: 'id', internalType: 'uint256', type: 'uint256', indexed: false },\n {\n name: 'amount',\n internalType: 'uint256',\n type: 'uint256',\n indexed: false,\n },\n ],\n name: 'TransferSingle',\n },\n { type: 'error', inputs: [], name: 'ChunkHasZeroLiquidity' },\n { type: 'error', inputs: [], name: 'InvalidTick' },\n { type: 'error', inputs: [], name: 'InvalidTickBound' },\n {\n type: 'error',\n inputs: [{ name: 'parameterType', internalType: 'uint256', type: 'uint256' }],\n name: 'InvalidTokenIdParameter',\n },\n { type: 'error', inputs: [], name: 'LiquidityTooHigh' },\n { type: 'error', inputs: [], name: 'NotAuthorized' },\n { type: 'error', inputs: [], name: 'NotEnoughLiquidityInChunk' },\n { type: 'error', inputs: [], name: 'PoolNotInitialized' },\n { type: 'error', inputs: [], name: 'PositionTooLarge' },\n {\n type: 'error',\n inputs: [{ name: 'currentTick', internalType: 'int24', type: 'int24' }],\n name: 'PriceBoundFail',\n },\n { type: 'error', inputs: [], name: 'Reentrancy' },\n { type: 'error', inputs: [], name: 'UnauthorizedUniswapCallback' },\n { type: 'error', inputs: [], name: 'UnderOverFlow' },\n { type: 'error', inputs: [], name: 'UnsafeRecipient' },\n { type: 'error', inputs: [], name: 'WrongUniswapPool' },\n] as const\n","/**\n * Custom error ABI definitions for Panoptic v2 contracts.\n *\n * Contains all custom errors from Errors.sol with their signatures.\n * Used for decoding contract revert data.\n *\n * Selectors sourced from `forge selectors list` output.\n *\n * @module v2/errors/errorsAbi\n */\n\n/**\n * All custom errors from Panoptic Errors.sol\n *\n * Selector computation: keccak256(errorSignature)[:4]\n */\nexport const panopticErrorsAbi = [\n // AccountInsolvent(uint256 solvent, uint256 numberOfTicks) - 0xcdef092d\n {\n type: 'error',\n name: 'AccountInsolvent',\n inputs: [\n { name: 'solvent', type: 'uint256' },\n { name: 'numberOfTicks', type: 'uint256' },\n ],\n },\n\n // AlreadyInitialized() - 0x0dc149f0\n {\n type: 'error',\n name: 'AlreadyInitialized',\n inputs: [],\n },\n\n // BelowMinimumRedemption() - 0x13185bd7\n {\n type: 'error',\n name: 'BelowMinimumRedemption',\n inputs: [],\n },\n\n // CastingError() - 0xb6680045\n {\n type: 'error',\n name: 'CastingError',\n inputs: [],\n },\n\n // ChunkHasZeroLiquidity() - 0x126ae3af\n {\n type: 'error',\n name: 'ChunkHasZeroLiquidity',\n inputs: [],\n },\n\n // CreateFail() - 0xebfef188\n {\n type: 'error',\n name: 'CreateFail',\n inputs: [],\n },\n\n // DepositTooLarge() - 0xc56d46d3\n {\n type: 'error',\n name: 'DepositTooLarge',\n inputs: [],\n },\n\n // DuplicateTokenId() - 0x2bd1a05a\n {\n type: 'error',\n name: 'DuplicateTokenId',\n inputs: [],\n },\n\n // EffectiveLiquidityAboveThreshold() - 0x3a8795c2\n {\n type: 'error',\n name: 'EffectiveLiquidityAboveThreshold',\n inputs: [],\n },\n\n // ExceedsMaximumRedemption() - 0x20adf2ea\n {\n type: 'error',\n name: 'ExceedsMaximumRedemption',\n inputs: [],\n },\n\n // InputListFail() - 0x99e877ce\n {\n type: 'error',\n name: 'InputListFail',\n inputs: [],\n },\n\n // InsufficientCreditLiquidity() - 0x7a70c281\n {\n type: 'error',\n name: 'InsufficientCreditLiquidity',\n inputs: [],\n },\n\n // InvalidBuilderCode() - 0x15b3fb46\n {\n type: 'error',\n name: 'InvalidBuilderCode',\n inputs: [],\n },\n\n // InvalidTick() - 0xce8ef7fc\n {\n type: 'error',\n name: 'InvalidTick',\n inputs: [],\n },\n\n // InvalidTickBound() - 0x1577d966\n {\n type: 'error',\n name: 'InvalidTickBound',\n inputs: [],\n },\n\n // InvalidTokenIdParameter(uint256 parameterType) - 0x93db0263\n {\n type: 'error',\n name: 'InvalidTokenIdParameter',\n inputs: [{ name: 'parameterType', type: 'uint256' }],\n },\n\n // InvalidUniswapCallback() - 0x3a94c705\n {\n type: 'error',\n name: 'InvalidUniswapCallback',\n inputs: [],\n },\n\n // LengthMismatch() - 0xff633a38\n {\n type: 'error',\n name: 'LengthMismatch',\n inputs: [],\n },\n\n // LiquidityTooHigh() - 0xa500e7ea\n {\n type: 'error',\n name: 'LiquidityTooHigh',\n inputs: [],\n },\n\n // NetLiquidityZero() - 0x73582ea0\n {\n type: 'error',\n name: 'NetLiquidityZero',\n inputs: [],\n },\n\n // NoLegsExercisable() - 0x7721f7da\n {\n type: 'error',\n name: 'NoLegsExercisable',\n inputs: [],\n },\n\n // NotALongLeg() - 0xb7d44f76\n {\n type: 'error',\n name: 'NotALongLeg',\n inputs: [],\n },\n\n // NotBuilder() - 0x0404714e\n {\n type: 'error',\n name: 'NotBuilder',\n inputs: [],\n },\n\n // NotEnoughLiquidityInChunk() - 0xc56d518e\n {\n type: 'error',\n name: 'NotEnoughLiquidityInChunk',\n inputs: [],\n },\n\n // NotEnoughTokens(address tokenAddress, uint256 assetsRequested, uint256 assetBalance) - 0x71c3730b\n {\n type: 'error',\n name: 'NotEnoughTokens',\n inputs: [\n { name: 'tokenAddress', type: 'address' },\n { name: 'assetsRequested', type: 'uint256' },\n { name: 'assetBalance', type: 'uint256' },\n ],\n },\n\n // NotGuardian() - 0xef6d0f02\n {\n type: 'error',\n name: 'NotGuardian',\n inputs: [],\n },\n\n // NotMarginCalled() - 0x2a23f1ad\n {\n type: 'error',\n name: 'NotMarginCalled',\n inputs: [],\n },\n\n // NotPanopticPool() - 0x2dd1912a\n {\n type: 'error',\n name: 'NotPanopticPool',\n inputs: [],\n },\n\n // PoolNotInitialized() - 0x486aa307\n {\n type: 'error',\n name: 'PoolNotInitialized',\n inputs: [],\n },\n\n // PositionCountNotZero() - 0x2501f81e\n {\n type: 'error',\n name: 'PositionCountNotZero',\n inputs: [],\n },\n\n // PositionNotOwned() - 0x00bd51c8\n {\n type: 'error',\n name: 'PositionNotOwned',\n inputs: [],\n },\n\n // PositionTooLarge() - 0x543a6e10\n {\n type: 'error',\n name: 'PositionTooLarge',\n inputs: [],\n },\n\n // PriceBoundFail(int24 currentTick) - 0x618ea40c\n {\n type: 'error',\n name: 'PriceBoundFail',\n inputs: [{ name: 'currentTick', type: 'int24' }],\n },\n\n // PriceImpactTooLarge() - 0xcbe5b9a6\n {\n type: 'error',\n name: 'PriceImpactTooLarge',\n inputs: [],\n },\n\n // Reentrancy() - 0xab143c06\n {\n type: 'error',\n name: 'Reentrancy',\n inputs: [],\n },\n\n // StaleOracle() - 0x88cce429\n {\n type: 'error',\n name: 'StaleOracle',\n inputs: [],\n },\n\n // TokenIdHasZeroLegs() - 0x9cd92fb2\n {\n type: 'error',\n name: 'TokenIdHasZeroLegs',\n inputs: [],\n },\n\n // TooManyLegsOpen() - 0x0ed7e777\n {\n type: 'error',\n name: 'TooManyLegsOpen',\n inputs: [],\n },\n\n // TransferFailed(address token, address from, uint256 amount, uint256 balance) - 0x81f20f86\n {\n type: 'error',\n name: 'TransferFailed',\n inputs: [\n { name: 'token', type: 'address' },\n { name: 'from', type: 'address' },\n { name: 'amount', type: 'uint256' },\n { name: 'balance', type: 'uint256' },\n ],\n },\n\n // UnauthorizedUniswapCallback() - 0x3e30718a\n {\n type: 'error',\n name: 'UnauthorizedUniswapCallback',\n inputs: [],\n },\n\n // UnderOverFlow() - 0xd2190174\n {\n type: 'error',\n name: 'UnderOverFlow',\n inputs: [],\n },\n\n // WrongPoolId() - 0xcfa4bfa2\n {\n type: 'error',\n name: 'WrongPoolId',\n inputs: [],\n },\n\n // WrongUniswapPool() - 0x768778de\n {\n type: 'error',\n name: 'WrongUniswapPool',\n inputs: [],\n },\n\n // ZeroAddress() - 0xd92e233d\n {\n type: 'error',\n name: 'ZeroAddress',\n inputs: [],\n },\n\n // ZeroCollateralRequirement() - 0x5b8edb4a\n {\n type: 'error',\n name: 'ZeroCollateralRequirement',\n inputs: [],\n },\n] as const\n","/**\n * Error parsing utilities for the Panoptic v2 SDK.\n *\n * Converts raw contract errors into typed SDK error classes.\n *\n * @module v2/errors/parser\n */\n\nimport { type Abi, BaseError, decodeErrorResult, toFunctionSelector } from 'viem'\n\nimport { collateralTrackerV2Abi, panopticPoolV2Abi, riskEngineAbi } from '../../../generated'\nimport { PanopticError } from './base'\nimport {\n // Solvency & Margin\n AccountInsolventError,\n AlreadyInitializedError,\n BelowMinimumRedemptionError,\n CastingError,\n // Liquidity\n ChunkHasZeroLiquidityError,\n CreateFailError,\n DepositTooLargeError,\n DuplicateTokenIdError,\n EffectiveLiquidityAboveThresholdError,\n ExceedsMaximumRedemptionError,\n InputListFailError,\n InsufficientCreditLiquidityError,\n InvalidBuilderCodeError,\n InvalidTickBoundError,\n // Tick & Price\n InvalidTickError,\n // Position & TokenId\n InvalidTokenIdParameterError,\n InvalidUniswapCallbackError,\n LengthMismatchError,\n LiquidityTooHighError,\n NetLiquidityZeroError,\n // Exercise\n NoLegsExercisableError,\n NotALongLegError,\n NotBuilderError,\n NotEnoughLiquidityInChunkError,\n // Token & Collateral\n NotEnoughTokensError,\n NotGuardianError,\n NotMarginCalledError,\n // Authorization\n NotPanopticPoolError,\n // Pool & Initialization\n PoolNotInitializedError,\n PositionCountNotZeroError,\n PositionNotOwnedError,\n PositionTooLargeError,\n PriceBoundFailError,\n PriceImpactTooLargeError,\n // Reentrancy\n ReentrancyError,\n // Oracle & Safe Mode\n StaleOracleError,\n TokenIdHasZeroLegsError,\n TooManyLegsOpenError,\n // Transfer & Casting\n TransferFailedError,\n UnauthorizedUniswapCallbackError,\n UnderOverFlowError,\n WrongPoolIdError,\n WrongUniswapPoolError,\n // Other\n ZeroAddressError,\n ZeroCollateralRequirementError,\n} from './contract'\nimport { panopticErrorsAbi } from './errorsAbi'\n\n/**\n * Result of parsing a Panoptic error.\n */\nexport interface ParsedError {\n /** The parsed error instance */\n error: PanopticError\n /** The original error name from the contract */\n errorName: string\n /** The decoded error arguments */\n args: readonly unknown[]\n}\n\n/**\n * Combined ABI for error decoding.\n * Includes the dedicated errors ABI for complete coverage.\n */\nconst combinedAbi = [\n ...panopticPoolV2Abi,\n ...collateralTrackerV2Abi,\n ...riskEngineAbi,\n ...panopticErrorsAbi,\n] as Abi\n\n/**\n * Map of error names to error constructors.\n */\nconst errorConstructors: Record<\n string,\n (args: readonly unknown[], cause?: Error) => PanopticError\n> = {\n // Solvency & Margin\n AccountInsolvent: (args, cause) =>\n new AccountInsolventError(args[0] as bigint, args[1] as bigint, cause),\n NotMarginCalled: (_args, cause) => new NotMarginCalledError(cause),\n\n // Factory\n CreateFail: (_args, cause) => new CreateFailError(cause),\n\n // Token & Collateral\n NotEnoughTokens: (args, cause) =>\n new NotEnoughTokensError(args[0] as `0x${string}`, args[1] as bigint, args[2] as bigint, cause),\n NotEnoughLiquidityInChunk: (_args, cause) => new NotEnoughLiquidityInChunkError(cause),\n InsufficientCreditLiquidity: (_args, cause) => new InsufficientCreditLiquidityError(cause),\n DepositTooLarge: (_args, cause) => new DepositTooLargeError(cause),\n BelowMinimumRedemption: (_args, cause) => new BelowMinimumRedemptionError(cause),\n ExceedsMaximumRedemption: (_args, cause) => new ExceedsMaximumRedemptionError(cause),\n ZeroCollateralRequirement: (_args, cause) => new ZeroCollateralRequirementError(cause),\n\n // Position & TokenId\n InvalidTokenIdParameter: (args, cause) =>\n new InvalidTokenIdParameterError(args[0] as bigint, cause),\n PositionNotOwned: (_args, cause) => new PositionNotOwnedError(cause),\n PositionTooLarge: (_args, cause) => new PositionTooLargeError(cause),\n PositionCountNotZero: (_args, cause) => new PositionCountNotZeroError(cause),\n DuplicateTokenId: (_args, cause) => new DuplicateTokenIdError(cause),\n TokenIdHasZeroLegs: (_args, cause) => new TokenIdHasZeroLegsError(cause),\n TooManyLegsOpen: (_args, cause) => new TooManyLegsOpenError(cause),\n InputListFail: (_args, cause) => new InputListFailError(cause),\n\n // Tick & Price\n InvalidTick: (_args, cause) => new InvalidTickError(cause),\n InvalidTickBound: (_args, cause) => new InvalidTickBoundError(cause),\n PriceBoundFail: (args, cause) => new PriceBoundFailError(args[0] as bigint, cause),\n PriceImpactTooLarge: (_args, cause) => new PriceImpactTooLargeError(cause),\n\n // Liquidity\n ChunkHasZeroLiquidity: (_args, cause) => new ChunkHasZeroLiquidityError(cause),\n LiquidityTooHigh: (_args, cause) => new LiquidityTooHighError(cause),\n NetLiquidityZero: (_args, cause) => new NetLiquidityZeroError(cause),\n EffectiveLiquidityAboveThreshold: (_args, cause) =>\n new EffectiveLiquidityAboveThresholdError(cause),\n\n // Oracle & Safe Mode\n StaleOracle: (_args, cause) => new StaleOracleError(cause),\n\n // Exercise\n NoLegsExercisable: (_args, cause) => new NoLegsExercisableError(cause),\n NotALongLeg: (_args, cause) => new NotALongLegError(cause),\n\n // Pool & Initialization\n PoolNotInitialized: (_args, cause) => new PoolNotInitializedError(cause),\n AlreadyInitialized: (_args, cause) => new AlreadyInitializedError(cause),\n WrongPoolId: (_args, cause) => new WrongPoolIdError(cause),\n WrongUniswapPool: (_args, cause) => new WrongUniswapPoolError(cause),\n\n // Authorization\n NotPanopticPool: (_args, cause) => new NotPanopticPoolError(cause),\n NotGuardian: (_args, cause) => new NotGuardianError(cause),\n NotBuilder: (_args, cause) => new NotBuilderError(cause),\n InvalidBuilderCode: (_args, cause) => new InvalidBuilderCodeError(cause),\n InvalidUniswapCallback: (_args, cause) => new InvalidUniswapCallbackError(cause),\n UnauthorizedUniswapCallback: (_args, cause) => new UnauthorizedUniswapCallbackError(cause),\n\n // Transfer & Casting\n TransferFailed: (args, cause) =>\n new TransferFailedError(\n args[0] as `0x${string}`,\n args[1] as `0x${string}`,\n args[2] as bigint,\n args[3] as bigint,\n cause,\n ),\n CastingError: (_args, cause) => new CastingError(cause),\n UnderOverFlow: (_args, cause) => new UnderOverFlowError(cause),\n\n // Reentrancy\n Reentrancy: (_args, cause) => new ReentrancyError(cause),\n\n // Other\n ZeroAddress: (_args, cause) => new ZeroAddressError(cause),\n LengthMismatch: (_args, cause) => new LengthMismatchError(cause),\n}\n\n/**\n * Parse a raw contract error into a typed SDK error.\n *\n * This function attempts to decode the error data from a failed contract call\n * and return a typed error instance with extracted parameters.\n *\n * @param error - The raw error from a failed contract call\n * @returns Parsed error with typed error instance, or null if parsing fails\n *\n * @example\n * ```typescript\n * try {\n * await contract.openPosition(...)\n * } catch (rawError) {\n * const parsed = parsePanopticError(rawError)\n * if (parsed) {\n * console.log('Error:', parsed.errorName)\n * if (parsed.error instanceof AccountInsolventError) {\n * console.log('Solvent value:', parsed.error.solvent)\n * }\n * }\n * }\n * ```\n */\nexport function parsePanopticError(error: unknown): ParsedError | null {\n // Strategy 1: Check if viem already decoded the error (ContractFunctionRevertedError.data)\n const viemDecoded = extractViemDecodedError(error)\n if (viemDecoded) {\n return buildParsedError(viemDecoded.errorName, viemDecoded.args, error)\n }\n\n // Strategy 2: Extract raw hex data and decode ourselves\n const errorData = extractErrorData(error)\n if (!errorData) return null\n\n try {\n const decoded = decodeErrorResult({\n abi: combinedAbi,\n data: errorData,\n })\n\n return buildParsedError(decoded.errorName, decoded.args ?? [], error)\n } catch {\n // decodeErrorResult failed — possibly we only have the 4-byte selector\n // (e.g. from a multicall error message). Try matching the selector manually.\n if (errorData.length >= 10) {\n const selector = errorData.slice(0, 10) as `0x${string}`\n const match = matchSelectorToErrorName(selector)\n if (match) {\n return buildParsedError(match, [], error)\n }\n }\n return null\n }\n}\n\n/**\n * Walk the cause chain looking for a viem ContractFunctionRevertedError\n * that already has decoded `.data` (an object with `errorName` and `args`).\n * This happens when the ABI passed to simulateContract includes the error definitions.\n */\nfunction extractViemDecodedError(\n error: unknown,\n): { errorName: string; args: readonly unknown[] } | null {\n if (!error || typeof error !== 'object') return null\n\n // Use BaseError.walk if available\n if (error instanceof BaseError) {\n let found: { errorName: string; args: readonly unknown[] } | null = null\n error.walk((e) => {\n if (found) return false\n const node = e as Record<string, unknown>\n if (\n node.data &&\n typeof node.data === 'object' &&\n 'errorName' in (node.data as object) &&\n typeof (node.data as Record<string, unknown>).errorName === 'string'\n ) {\n const data = node.data as { errorName: string; args?: readonly unknown[] }\n found = { errorName: data.errorName, args: data.args ?? [] }\n return true\n }\n return false\n })\n return found\n }\n\n // Manual walk for non-viem errors\n let current: Record<string, unknown> | null = error as Record<string, unknown>\n for (let i = 0; i < 10 && current; i++) {\n if (\n current.data &&\n typeof current.data === 'object' &&\n 'errorName' in (current.data as object) &&\n typeof (current.data as Record<string, unknown>).errorName === 'string'\n ) {\n const data = current.data as { errorName: string; args?: readonly unknown[] }\n return { errorName: data.errorName, args: data.args ?? [] }\n }\n current =\n current.cause && typeof current.cause === 'object'\n ? (current.cause as Record<string, unknown>)\n : null\n }\n\n return null\n}\n\n/**\n * Build a ParsedError from a decoded error name and args.\n */\nfunction buildParsedError(\n errorName: string,\n args: readonly unknown[],\n originalError: unknown,\n): ParsedError {\n const constructor = errorConstructors[errorName]\n const cause = originalError instanceof Error ? originalError : undefined\n\n if (!constructor) {\n const unknownError = new PanopticError(`Unknown contract error: ${errorName}`)\n unknownError.errorName = errorName\n return { error: unknownError, errorName, args }\n }\n\n const typedError = constructor(args, cause)\n typedError.errorName = errorName\n return { error: typedError, errorName, args }\n}\n\n/**\n * Match a 4-byte selector against the panoptic errors ABI.\n * Used as fallback when we only have the selector (no encoded args).\n */\nfunction matchSelectorToErrorName(selector: `0x${string}`): string | null {\n for (const item of panopticErrorsAbi) {\n if (item.type !== 'error') continue\n const computed = toFunctionSelector(\n `${item.name}(${item.inputs.map((i: { type: string }) => i.type).join(',')})`,\n )\n if (computed === selector) {\n return item.name\n }\n }\n return null\n}\n\n/**\n * Extract error data from various error formats.\n *\n * Strategy:\n * 1. Use viem's BaseError.walk() to traverse the full cause chain and find\n * hex data on any node (handles arbitrary nesting depth for multicall etc.)\n * 2. Fall back to manual cause-chain walk for non-viem errors\n * 3. Last resort: extract selector from error message (loses args)\n */\nfunction extractErrorData(error: unknown): `0x${string}` | null {\n if (!error) return null\n\n // Direct hex data\n if (typeof error === 'string' && error.startsWith('0x')) {\n return error as `0x${string}`\n }\n\n if (typeof error !== 'object') return null\n\n // Strategy 1: Use viem's BaseError.walk() — traverses the full cause chain\n if (error instanceof BaseError) {\n let foundData: `0x${string}` | null = null\n\n error.walk((e) => {\n if (foundData) return false\n const node = e as Record<string, unknown>\n\n // Check .data as hex string (full revert bytes on RPC errors)\n if (node.data && typeof node.data === 'string' && node.data.startsWith('0x')) {\n foundData = node.data as `0x${string}`\n return true\n }\n\n // Check .data.data (some RPC providers nest: { data: { data: '0x...' } })\n if (node.data && typeof node.data === 'object') {\n const nested = node.data as Record<string, unknown>\n if (nested.data && typeof nested.data === 'string' && nested.data.startsWith('0x')) {\n foundData = nested.data as `0x${string}`\n return true\n }\n }\n\n return false\n })\n\n if (foundData) return foundData\n\n // Also check .signature on walked nodes (viem stores raw selector here\n // when it can't decode against the provided ABI)\n error.walk((e) => {\n if (foundData) return false\n const node = e as Record<string, unknown>\n if (node.signature && typeof node.signature === 'string' && node.signature.startsWith('0x')) {\n foundData = node.signature as `0x${string}`\n return true\n }\n return false\n })\n\n if (foundData) return foundData\n }\n\n // Strategy 2: Manual cause-chain walk for non-viem errors\n let current: Record<string, unknown> | null = error as Record<string, unknown>\n const maxDepth = 10\n for (let i = 0; i < maxDepth && current; i++) {\n if (current.data && typeof current.data === 'string' && current.data.startsWith('0x')) {\n return current.data as `0x${string}`\n }\n\n if (current.data && typeof current.data === 'object') {\n const nested = current.data as Record<string, unknown>\n if (nested.data && typeof nested.data === 'string' && nested.data.startsWith('0x')) {\n return nested.data as `0x${string}`\n }\n }\n\n if (current.error && typeof current.error === 'object') {\n const rpcError = current.error as Record<string, unknown>\n if (rpcError.data && typeof rpcError.data === 'string' && rpcError.data.startsWith('0x')) {\n return rpcError.data as `0x${string}`\n }\n }\n\n current =\n current.cause && typeof current.cause === 'object'\n ? (current.cause as Record<string, unknown>)\n : null\n }\n\n // Strategy 3: Extract from error message (last resort — may only have 4-byte selector)\n const obj = error as Record<string, unknown>\n if (obj.message && typeof obj.message === 'string') {\n const signatureMatch = obj.message.match(/signature:\\s*(0x[a-fA-F0-9]{8,})/i)\n if (signatureMatch) {\n return signatureMatch[1] as `0x${string}`\n }\n }\n\n return null\n}\n\n/**\n * Check if an error is a specific Panoptic error type.\n *\n * @param error - The error to check\n * @param errorClass - The error class to check against\n * @returns True if the error is an instance of the specified class\n *\n * @example\n * ```typescript\n * const parsed = parsePanopticError(error)\n * if (parsed && isPanopticErrorType(parsed.error, AccountInsolventError)) {\n * console.log('Account is insolvent!')\n * }\n * ```\n */\nexport function isPanopticErrorType<T extends PanopticError>(\n error: PanopticError,\n errorClass: new (...args: unknown[]) => T,\n): error is T {\n return error instanceof errorClass\n}\n","import { PanopticValidationError } from '../errors'\nimport type { OracleState } from '../types'\nimport { ORACLE_EPOCH_SECONDS } from './constants'\n\nconst UINT24_MASK = (1n << 24n) - 1n\n\nexport interface OracleEmaPeriods {\n spot: bigint\n fast: bigint\n slow: bigint\n eons: bigint\n}\n\nexport interface OracleRiskParameters {\n emaPeriods: OracleEmaPeriods\n maxTicksDelta: bigint\n /** Informational observation clamp; not used by SafeMode diagnosis. May be zero. */\n maxClampDelta: bigint\n}\n\nexport type OracleSafeModeCause =\n | 'externalShock'\n | 'internalDisagreement'\n | 'highDivergence'\n | 'guardianLock'\n | 'unknown'\n\nexport interface OracleSafeModeDiagnosis {\n /** Authoritative value returned by PanopticPool.isSafeMode(). */\n level: bigint\n /** Value reproduced using the known RiskEngine formula and live constants. */\n reproducedLevel: bigint\n matchesOnchain: boolean\n causes: readonly OracleSafeModeCause[]\n externalShockDelta: bigint\n internalDisagreementDelta: bigint\n highDivergenceDelta: bigint\n guardianLocked: boolean\n /** Minimum whole 64-second oracle epochs to wait after the last observation. */\n minimumPokeEpochs: bigint\n shouldPoke: boolean\n}\n\ntype DiagnosticOracleState = Pick<\n OracleState,\n 'currentTick' | 'spotEMA' | 'fastEMA' | 'slowEMA' | 'medianTick' | 'lockMode'\n>\n\nfunction absoluteDelta(left: bigint, right: bigint): bigint {\n return left >= right ? left - right : right - left\n}\n\nfunction epochsForPeriod(period: bigint): bigint {\n return (period + ORACLE_EPOCH_SECONDS - 1n) / ORACLE_EPOCH_SECONDS\n}\n\n/** Decode the four uint24 periods packed by RiskEngine.EMA_PERIODS(). */\nexport function decodeOracleRiskParameters(\n emaPeriods: bigint,\n maxTicksDelta: bigint,\n maxClampDelta: bigint,\n): OracleRiskParameters {\n const decodedPeriods = {\n spot: emaPeriods & UINT24_MASK,\n fast: (emaPeriods >> 24n) & UINT24_MASK,\n slow: (emaPeriods >> 48n) & UINT24_MASK,\n eons: (emaPeriods >> 72n) & UINT24_MASK,\n }\n if (\n decodedPeriods.spot === 0n ||\n decodedPeriods.fast === 0n ||\n decodedPeriods.slow === 0n ||\n decodedPeriods.eons === 0n ||\n maxTicksDelta <= 0n ||\n maxClampDelta < 0n\n ) {\n throw new PanopticValidationError(\n `RiskEngine returned invalid oracle parameters: EMA_PERIODS=${emaPeriods}, ` +\n `MAX_TICKS_DELTA=${maxTicksDelta}, MAX_CLAMP_DELTA=${maxClampDelta}`,\n )\n }\n return { emaPeriods: decodedPeriods, maxTicksDelta, maxClampDelta }\n}\n\n/** Explain the on-chain SafeMode level using this deployment's RiskEngine constants. */\nexport function diagnoseOracleSafeMode(\n state: DiagnosticOracleState,\n parameters: OracleRiskParameters,\n onchainLevel: bigint,\n): OracleSafeModeDiagnosis {\n const externalShockDelta = absoluteDelta(state.currentTick, state.spotEMA)\n const internalDisagreementDelta = absoluteDelta(state.spotEMA, state.fastEMA)\n const highDivergenceDelta = absoluteDelta(state.medianTick, state.slowEMA)\n const internalThreshold = parameters.maxTicksDelta / 2n\n const externalShock = externalShockDelta > parameters.maxTicksDelta\n const internalDisagreement = internalDisagreementDelta > internalThreshold\n const highDivergence = highDivergenceDelta > internalThreshold\n const guardianLocked = state.lockMode !== 0n\n\n const algorithmicLevel =\n (externalShock ? 1n : 0n) + (internalDisagreement ? 1n : 0n) + (highDivergence ? 1n : 0n)\n const reproducedLevel = algorithmicLevel + state.lockMode\n const matchesOnchain = reproducedLevel === onchainLevel\n const causes: OracleSafeModeCause[] = []\n if (matchesOnchain) {\n if (externalShock) causes.push('externalShock')\n if (internalDisagreement) causes.push('internalDisagreement')\n if (highDivergence) causes.push('highDivergence')\n } else {\n causes.push('unknown')\n }\n if (guardianLocked) causes.push('guardianLock')\n\n const candidateEpochs: bigint[] = []\n if (!matchesOnchain) candidateEpochs.push(1n)\n if (highDivergence) candidateEpochs.push(1n)\n if (externalShock) candidateEpochs.push(epochsForPeriod(parameters.emaPeriods.spot))\n if (internalDisagreement) candidateEpochs.push(epochsForPeriod(parameters.emaPeriods.fast))\n const minimumPokeEpochs = candidateEpochs.reduce(\n (minimum, epochs) => (minimum === 0n || epochs < minimum ? epochs : minimum),\n 0n,\n )\n\n return {\n level: onchainLevel,\n reproducedLevel,\n matchesOnchain,\n causes,\n externalShockDelta,\n internalDisagreementDelta,\n highDivergenceDelta,\n guardianLocked,\n minimumPokeEpochs,\n shouldPoke: onchainLevel > 0n && !guardianLocked,\n }\n}\n","/**\n * Write utilities for the Panoptic v2 SDK.\n * @module v2/writes/utils\n */\n\nimport type { Abi, Address, Hash, Log, PublicClient, WalletClient } from 'viem'\nimport { decodeEventLog, encodeFunctionData } from 'viem'\n\nimport { collateralTrackerV2Abi, panopticPoolV2Abi } from '../../../generated'\nimport type { PanopticEvent, TxOverrides, TxReceipt, TxResult } from '../types'\n\n/**\n * Decode PositionBalance packed data.\n *\n * Layout (from LSB to MSB):\n * - positionSize: bits 0-127 (uint128)\n * - poolUtilization0: bits 128-143 (uint16)\n * - poolUtilization1: bits 144-159 (uint16)\n * - tickAtMint: bits 160-183 (int24)\n * - timestampAtMint: bits 184-215 (uint32)\n * - blockAtMint: bits 216-254 (uint39)\n * - swapAtMint: bit 255 (bool)\n */\nexport function decodePositionBalance(balanceData: bigint): {\n positionSize: bigint\n poolUtilization0: bigint\n poolUtilization1: bigint\n tickAtMint: bigint\n timestampAtMint: bigint\n blockAtMint: bigint\n swapAtMint: boolean\n} {\n const positionSize = balanceData & ((1n << 128n) - 1n)\n const poolUtilization0 = (balanceData >> 128n) & 0xffffn\n const poolUtilization1 = (balanceData >> 144n) & 0xffffn\n\n // tickAtMint is int24 at bits 160-183\n let tickAtMint = (balanceData >> 160n) & 0xffffffn\n // Sign extend if negative (int24)\n if (tickAtMint > 0x7fffffn) {\n tickAtMint = tickAtMint - 0x1000000n\n }\n\n // timestampAtMint is uint32 at bits 184-215\n const timestampAtMint = (balanceData >> 184n) & 0xffffffffn\n\n // blockAtMint is uint39 at bits 216-254\n const blockAtMint = (balanceData >> 216n) & ((1n << 39n) - 1n)\n\n // swapAtMint is bool at bit 255\n const swapAtMint = balanceData >> 255n === 1n\n\n return {\n positionSize,\n poolUtilization0,\n poolUtilization1,\n tickAtMint,\n timestampAtMint,\n blockAtMint,\n swapAtMint,\n }\n}\n\n/**\n * Decode LeftRightSigned packed value.\n */\nexport function decodeLeftRightSigned(value: bigint): { right: bigint; left: bigint } {\n // Right is bits 0-127 (token0), Left is bits 128-255 (token1)\n // Both are signed int128\n let right = value & ((1n << 128n) - 1n)\n let left = value >> 128n\n\n // Sign extend right if needed\n if (right >= 1n << 127n) {\n right = right - (1n << 128n)\n }\n // Sign extend left if needed\n if (left >= 1n << 127n) {\n left = left - (1n << 128n)\n }\n\n return { right, left }\n}\n\n/**\n * Decode LeftRightUnsigned packed value.\n */\nexport function decodeLeftRightUnsigned(value: bigint): { right: bigint; left: bigint } {\n // Right is bits 0-127 (token0), Left is bits 128-255 (token1)\n // Both are unsigned uint128\n const right = value & ((1n << 128n) - 1n)\n const left = value >> 128n\n\n return { right, left }\n}\n\n/**\n * Parse Panoptic events from transaction logs.\n *\n * @param logs - The transaction logs\n * @returns Parsed Panoptic events\n */\nexport function parsePanopticEvents(logs: Log[]): PanopticEvent[] {\n const events: PanopticEvent[] = []\n\n // Try to decode each log with known ABIs\n for (const log of logs) {\n const baseEvent = {\n blockNumber: log.blockNumber ?? 0n,\n blockHash: (log.blockHash ??\n '0x0000000000000000000000000000000000000000000000000000000000000000') as Hash,\n transactionHash: log.transactionHash ?? ('0x' as Hash),\n logIndex: BigInt(log.logIndex ?? 0),\n }\n\n try {\n // Try PanopticPool events\n const poolEvent = decodeEventLog({\n abi: panopticPoolV2Abi,\n data: log.data,\n topics: log.topics,\n })\n\n if (poolEvent.eventName === 'OptionMinted') {\n const args = poolEvent.args as {\n recipient: `0x${string}`\n tokenId: bigint\n balanceData: bigint\n }\n const balance = decodePositionBalance(args.balanceData)\n events.push({\n type: 'OptionMinted',\n ...baseEvent,\n recipient: args.recipient,\n tokenId: args.tokenId,\n positionSize: balance.positionSize,\n poolUtilization0: balance.poolUtilization0,\n poolUtilization1: balance.poolUtilization1,\n tickAtMint: balance.tickAtMint,\n timestampAtMint: balance.timestampAtMint,\n blockAtMint: balance.blockAtMint,\n swapAtMint: balance.swapAtMint,\n })\n } else if (poolEvent.eventName === 'OptionBurnt') {\n const args = poolEvent.args as {\n recipient: `0x${string}`\n tokenId: bigint\n positionSize: bigint\n premiaByLeg: readonly bigint[]\n }\n events.push({\n type: 'OptionBurnt',\n ...baseEvent,\n recipient: args.recipient,\n tokenId: args.tokenId,\n positionSize: args.positionSize,\n premiaByLeg: [\n args.premiaByLeg[0] ?? 0n,\n args.premiaByLeg[1] ?? 0n,\n args.premiaByLeg[2] ?? 0n,\n args.premiaByLeg[3] ?? 0n,\n ] as const,\n })\n } else if (poolEvent.eventName === 'AccountLiquidated') {\n const args = poolEvent.args as {\n liquidator: `0x${string}`\n liquidatee: `0x${string}`\n bonusAmounts: bigint\n }\n const { right, left } = decodeLeftRightSigned(args.bonusAmounts)\n events.push({\n type: 'AccountLiquidated',\n ...baseEvent,\n liquidator: args.liquidator,\n liquidatee: args.liquidatee,\n bonusAmount0: right,\n bonusAmount1: left,\n })\n } else if (poolEvent.eventName === 'ForcedExercised') {\n const args = poolEvent.args as {\n exercisor: `0x${string}`\n user: `0x${string}`\n tokenId: bigint\n exerciseFee: bigint\n }\n const { right, left } = decodeLeftRightSigned(args.exerciseFee)\n events.push({\n type: 'ForcedExercised',\n ...baseEvent,\n exercisor: args.exercisor,\n user: args.user,\n tokenId: args.tokenId,\n exerciseFee0: right,\n exerciseFee1: left,\n })\n } else if (poolEvent.eventName === 'PremiumSettled') {\n const args = poolEvent.args as {\n user: `0x${string}`\n tokenId: bigint\n legIndex: bigint\n settledAmounts: bigint\n }\n const { right, left } = decodeLeftRightSigned(args.settledAmounts)\n events.push({\n type: 'PremiumSettled',\n ...baseEvent,\n user: args.user,\n tokenId: args.tokenId,\n legIndex: args.legIndex,\n settledAmount0: right,\n settledAmount1: left,\n })\n }\n } catch {\n // Not a PanopticPool event, try CollateralTracker\n try {\n const collateralEvent = decodeEventLog({\n abi: collateralTrackerV2Abi,\n data: log.data,\n topics: log.topics,\n })\n\n if (collateralEvent.eventName === 'Deposit') {\n const args = collateralEvent.args as {\n sender: `0x${string}`\n owner: `0x${string}`\n assets: bigint\n shares: bigint\n }\n events.push({\n type: 'Deposit',\n ...baseEvent,\n sender: args.sender,\n owner: args.owner,\n assets: args.assets,\n shares: args.shares,\n })\n } else if (collateralEvent.eventName === 'Withdraw') {\n const args = collateralEvent.args as {\n sender: `0x${string}`\n receiver: `0x${string}`\n owner: `0x${string}`\n assets: bigint\n shares: bigint\n }\n events.push({\n type: 'Withdraw',\n ...baseEvent,\n sender: args.sender,\n receiver: args.receiver,\n owner: args.owner,\n assets: args.assets,\n shares: args.shares,\n })\n }\n } catch {\n // Unknown event, skip\n }\n }\n }\n\n return events\n}\n\n/**\n * Create a TxResult from a transaction hash.\n *\n * @param client - The public client\n * @param hash - The transaction hash\n * @returns TxResult with wait function\n */\nexport function createTxResult(client: PublicClient, hash: Hash): TxResult {\n return {\n hash,\n wait: async (confirmations?: bigint): Promise<TxReceipt> => {\n const receipt = await client.waitForTransactionReceipt({\n hash,\n confirmations: confirmations !== undefined ? Number(confirmations) : undefined,\n })\n\n const events = parsePanopticEvents(receipt.logs)\n\n return {\n hash: receipt.transactionHash,\n blockNumber: receipt.blockNumber,\n blockHash: receipt.blockHash,\n gasUsed: receipt.gasUsed,\n status: receipt.status === 'success' ? 'success' : 'reverted',\n events,\n }\n },\n }\n}\n\n/**\n * Execute a write operation and return TxResult.\n *\n * @param client - The public client\n * @param hashPromise - Promise that resolves to transaction hash\n * @returns TxResult\n */\nexport async function executeWrite(\n client: PublicClient,\n hashPromise: Promise<Hash>,\n): Promise<TxResult> {\n const hash = await hashPromise\n return createTxResult(client, hash)\n}\n\n/**\n * Execute a write operation and wait for receipt.\n *\n * @param client - The public client\n * @param hashPromise - Promise that resolves to transaction hash\n * @param confirmations - Number of confirmations to wait for\n * @returns TxReceipt\n */\nexport async function executeWriteAndWait(\n client: PublicClient,\n hashPromise: Promise<Hash>,\n confirmations?: bigint,\n): Promise<TxReceipt> {\n const result = await executeWrite(client, hashPromise)\n return result.wait(confirmations)\n}\n\n/**\n * Parameters for the submitWrite helper.\n */\nexport interface SubmitWriteParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** Contract address */\n address: Address\n /** Contract ABI */\n abi: Abi\n /** Function name to call */\n functionName: string\n /** Function arguments */\n args: readonly unknown[]\n /** ETH value to send with the transaction (for native ETH deposits) */\n value?: bigint\n /** Optional gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Submit a write operation, supporting both direct wallet submission\n * and custom broadcaster paths with gas overrides.\n *\n * Normal path (no broadcaster): calls walletClient.writeContract() with gas overrides.\n * Broadcaster path: prepareTransactionRequest → apply overrides → signTransaction → broadcast.\n *\n * @param params - Submit write parameters\n * @returns TxResult\n */\nexport async function submitWrite(params: SubmitWriteParams): Promise<TxResult> {\n const { client, walletClient, account, address, abi, functionName, args, value, txOverrides } =\n params\n\n const broadcaster = txOverrides?.broadcaster\n\n if (broadcaster) {\n // Encode contract calldata before request preparation so gas/tx params\n // are derived from the exact call being signed and broadcast.\n const data = encodeFunctionData({ abi, functionName, args })\n\n // Broadcaster path: prepare → sign → broadcast\n const broadcastAccount = walletClient.account ?? account\n const request = await walletClient.prepareTransactionRequest({\n account: broadcastAccount,\n to: address,\n chain: walletClient.chain,\n data,\n ...(value !== undefined && { value }),\n ...(txOverrides?.maxFeePerGas !== undefined && { maxFeePerGas: txOverrides.maxFeePerGas }),\n ...(txOverrides?.maxPriorityFeePerGas !== undefined && {\n maxPriorityFeePerGas: txOverrides.maxPriorityFeePerGas,\n }),\n ...(txOverrides?.gas !== undefined && { gas: txOverrides.gas }),\n ...(txOverrides?.nonce !== undefined && { nonce: Number(txOverrides.nonce) }),\n })\n\n const signedTx = await walletClient.signTransaction({\n ...request,\n account: broadcastAccount,\n } as unknown as Parameters<WalletClient['signTransaction']>[0])\n\n const hash = await broadcaster.broadcast(signedTx)\n return createTxResult(client, hash)\n }\n\n // Normal path: direct writeContract with gas overrides\n const gasOverrides: Record<string, unknown> = {}\n if (txOverrides?.maxFeePerGas !== undefined) {\n gasOverrides.maxFeePerGas = txOverrides.maxFeePerGas\n }\n if (txOverrides?.maxPriorityFeePerGas !== undefined) {\n gasOverrides.maxPriorityFeePerGas = txOverrides.maxPriorityFeePerGas\n }\n if (txOverrides?.nonce !== undefined) {\n gasOverrides.nonce = Number(txOverrides.nonce)\n }\n\n // Use the walletClient's local account (if available) for local signing.\n // Passing a string address triggers eth_sendTransaction (remote signing),\n // which fails with hosted RPC providers like Alchemy/Infura.\n const resolvedAccount = walletClient.account ?? account\n\n // If no explicit gas override, estimate with a 20% buffer.\n // Panoptic dispatch calls are gas-heavy and viem's default estimate can be tight.\n if (txOverrides?.gas !== undefined) {\n gasOverrides.gas = txOverrides.gas\n } else {\n const estimated = await client.estimateContractGas({\n address,\n abi,\n functionName,\n args,\n account: resolvedAccount,\n ...(value !== undefined && { value }),\n } as Parameters<typeof client.estimateContractGas>[0])\n gasOverrides.gas = (estimated * 120n) / 100n\n }\n\n const hash = await walletClient.writeContract({\n address,\n abi,\n functionName,\n args,\n account: resolvedAccount,\n chain: walletClient.chain,\n ...(value !== undefined && { value }),\n ...gasOverrides,\n })\n\n return createTxResult(client, hash)\n}\n\n/**\n * Parameters required for all write operations.\n */\nexport interface BaseWriteParams {\n /** Public client for reading state */\n client: PublicClient\n}\n","/**\n * Pure validator for batched mint/burn dispatch operations.\n * @module v2/batch/validate\n */\n\nimport type { BatchDiagnostic, BatchOp } from './types'\n\nexport interface ValidateBatchParams {\n items: BatchOp[]\n /** Current on-chain positionIdList for the account. */\n existingPositionIds: bigint[]\n}\n\n/**\n * Run all batch-level and item-level validations.\n * Pure function; never throws. Empty array means \"ready to build\".\n */\nexport function validateBatch(params: ValidateBatchParams): BatchDiagnostic[] {\n const { items, existingPositionIds } = params\n const diagnostics: BatchDiagnostic[] = []\n\n if (items.length === 0) {\n diagnostics.push({\n itemIndex: -1n,\n tokenId: 0n,\n code: 'empty-batch',\n message: 'Batch is empty.',\n })\n return diagnostics\n }\n\n const head = items[0]\n if (!head) return diagnostics\n const firstPool = head.poolAddress.toLowerCase()\n const existing = new Set(existingPositionIds)\n const seen = new Map<bigint, bigint>()\n\n items.forEach((item, idx) => {\n const itemIndex = BigInt(idx)\n if (item.poolAddress.toLowerCase() !== firstPool) {\n diagnostics.push({\n itemIndex,\n tokenId: item.tokenId,\n code: 'cross-pool',\n message: `Item ${idx} targets pool ${item.poolAddress}, expected ${head.poolAddress}.`,\n })\n }\n\n if (item.tickLimitLow > item.tickLimitHigh) {\n diagnostics.push({\n itemIndex,\n tokenId: item.tokenId,\n code: 'invalid-tick-limits',\n message: `Item ${idx} tickLimitLow (${item.tickLimitLow}) > tickLimitHigh (${item.tickLimitHigh}).`,\n })\n }\n\n if (item.kind === 'mint') {\n if (item.positionSize <= 0n) {\n diagnostics.push({\n itemIndex,\n tokenId: item.tokenId,\n code: 'invalid-position-size',\n message: `Mint at index ${idx} must have positionSize > 0.`,\n })\n }\n if (existing.has(item.tokenId)) {\n diagnostics.push({\n itemIndex,\n tokenId: item.tokenId,\n code: 'mint-already-onchain',\n message: `Mint at index ${idx} targets tokenId ${item.tokenId} which is already open on-chain.`,\n })\n }\n } else if (!existing.has(item.tokenId)) {\n diagnostics.push({\n itemIndex,\n tokenId: item.tokenId,\n code: 'burn-not-found',\n message: `Burn at index ${idx} targets tokenId ${item.tokenId} which is not in the account's positions.`,\n })\n }\n\n const prior = seen.get(item.tokenId)\n if (prior !== undefined) {\n diagnostics.push({\n itemIndex,\n tokenId: item.tokenId,\n code: 'duplicate-tokenid-in-batch',\n message: `Item ${idx} duplicates tokenId ${item.tokenId} also at index ${prior}.`,\n })\n } else {\n seen.set(item.tokenId, itemIndex)\n }\n })\n\n return diagnostics\n}\n","/**\n * Pure builder converting batched mint/burn ops into PanopticPool.dispatch() args.\n * @module v2/batch/build\n */\n\nimport type { TickAndSpreadLimits } from '../writes/position'\nimport type { BatchDiagnostic, BatchDispatchArgs, BatchOp } from './types'\nimport { validateBatch } from './validate'\n\nexport interface BuildBatchDispatchArgsParams {\n items: BatchOp[]\n /** Current on-chain positionIdList for the account. */\n existingPositionIds: bigint[]\n /** Apply across the whole dispatch. Defaults to false. */\n usePremiaAsCollateral?: boolean\n /** Apply across the whole dispatch. Defaults to 0n. */\n builderCode?: bigint\n}\n\nexport interface BuildBatchDispatchArgsResult {\n /** Null when diagnostics are non-empty. */\n args: BatchDispatchArgs | null\n diagnostics: BatchDiagnostic[]\n}\n\n/**\n * Build dispatch() args from a list of batch ops + the account's current\n * on-chain positionIdList. Returns diagnostics instead of throwing so callers\n * (UIs, bots) can render conflicts before deciding what to do.\n *\n * The order in `items` is preserved as the operation order in `positionIdList`,\n * `positionSizes`, and `tickAndSpreadLimits`. `finalPositionIdList` is the\n * post-execution state: existing minus burns, plus mints.\n */\nexport function buildBatchDispatchArgs(\n params: BuildBatchDispatchArgsParams,\n): BuildBatchDispatchArgsResult {\n const { items, existingPositionIds, usePremiaAsCollateral = false, builderCode = 0n } = params\n\n const diagnostics = validateBatch({ items, existingPositionIds })\n if (diagnostics.length > 0) {\n return { args: null, diagnostics }\n }\n\n const positionIdList = items.map((i) => i.tokenId)\n const positionSizes = items.map((i) => (i.kind === 'mint' ? i.positionSize : 0n))\n\n const tickAndSpreadLimits: TickAndSpreadLimits[] = items.map((i) => {\n const low = i.tickLimitLow <= i.tickLimitHigh ? i.tickLimitLow : i.tickLimitHigh\n const high = i.tickLimitLow <= i.tickLimitHigh ? i.tickLimitHigh : i.tickLimitLow\n const spread = i.kind === 'mint' ? i.spreadLimit : 0n\n return i.swapAtMint ? ([high, low, spread] as const) : ([low, high, spread] as const)\n })\n\n const mintIds = items.filter((i) => i.kind === 'mint').map((i) => i.tokenId)\n const burnIds = new Set(items.filter((i) => i.kind === 'burn').map((i) => i.tokenId))\n const mintIdSet = new Set(mintIds)\n const finalPositionIdList = [\n ...existingPositionIds.filter((id) => !burnIds.has(id) && !mintIdSet.has(id)),\n ...mintIds,\n ]\n\n return {\n args: {\n positionIdList,\n finalPositionIdList,\n positionSizes,\n tickAndSpreadLimits,\n usePremiaAsCollateral,\n builderCode,\n },\n diagnostics: [],\n }\n}\n","/**\n * File-based storage adapter for Node.js.\n * @module v2/storage/fileStorage\n */\n\nimport type FsPromises from 'node:fs/promises'\nimport type Path from 'node:path'\n\nimport type { StorageAdapter } from './adapter'\n\n/**\n * Creates a file-based storage adapter for Node.js environments.\n * Stores data as JSON files in the specified directory.\n *\n * The directory will be created if it doesn't exist.\n *\n * @param directory - Path to the storage directory\n *\n * @example\n * ```typescript\n * import { createFileStorage, createConfig } from 'panoptic-v2-sdk'\n *\n * // Node.js only\n * const config = createConfig({\n * chainId: 1n,\n * transport: http('...'),\n * poolAddress: '0x...',\n * storage: createFileStorage('./panoptic-cache'),\n * })\n * ```\n */\nexport function createFileStorage(directory: string): StorageAdapter {\n // Lazy import fs/promises to avoid issues in browser environments\n // This function should only be called in Node.js\n let fsPromises: typeof FsPromises | null = null\n let pathModule: typeof Path | null = null\n let initialized = false\n\n const ensureInitialized = async () => {\n if (initialized) return\n\n // Dynamic import for Node.js modules\n fsPromises = await import('node:fs/promises')\n pathModule = await import('node:path')\n\n // Ensure directory exists\n await fsPromises.mkdir(directory, { recursive: true })\n initialized = true\n }\n\n const getFilePath = (key: string): string => {\n if (!pathModule) throw new Error('File storage not initialized')\n // Encode the key to be filesystem-safe\n const safeKey = Buffer.from(key).toString('base64url')\n return pathModule.join(directory, `${safeKey}.json`)\n }\n\n return {\n async get(key: string): Promise<string | null> {\n await ensureInitialized()\n if (!fsPromises) throw new Error('File storage not initialized')\n\n try {\n const filePath = getFilePath(key)\n const content = await fsPromises.readFile(filePath, 'utf-8')\n return content\n } catch (error) {\n // File doesn't exist\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null\n }\n throw error\n }\n },\n\n async set(key: string, value: string): Promise<void> {\n await ensureInitialized()\n if (!fsPromises) throw new Error('File storage not initialized')\n\n const filePath = getFilePath(key)\n await fsPromises.writeFile(filePath, value, 'utf-8')\n },\n\n async delete(key: string): Promise<void> {\n await ensureInitialized()\n if (!fsPromises) throw new Error('File storage not initialized')\n\n try {\n const filePath = getFilePath(key)\n await fsPromises.unlink(filePath)\n } catch (error) {\n // Ignore if file doesn't exist\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw error\n }\n }\n },\n\n async has(key: string): Promise<boolean> {\n await ensureInitialized()\n if (!fsPromises) throw new Error('File storage not initialized')\n\n try {\n const filePath = getFilePath(key)\n await fsPromises.access(filePath)\n return true\n } catch {\n return false\n }\n },\n\n async keys(prefix: string): Promise<string[]> {\n await ensureInitialized()\n if (!fsPromises || !pathModule) throw new Error('File storage not initialized')\n\n const result: string[] = []\n\n try {\n const files = await fsPromises.readdir(directory)\n for (const file of files) {\n if (file.endsWith('.json')) {\n const safeKey = file.slice(0, -5) // Remove .json\n try {\n const key = Buffer.from(safeKey, 'base64url').toString()\n if (key.startsWith(prefix)) {\n result.push(key)\n }\n } catch {\n // Invalid base64, skip\n }\n }\n }\n } catch (error) {\n // Directory doesn't exist yet\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw error\n }\n }\n\n return result\n },\n\n async clear(prefix: string): Promise<void> {\n await ensureInitialized()\n if (!fsPromises) throw new Error('File storage not initialized')\n\n const keysToDelete = await this.keys(prefix)\n for (const key of keysToDelete) {\n await this.delete(key)\n }\n },\n }\n}\n","/**\n * Storage key generation for the Panoptic v2 SDK.\n * @module v2/storage/keys\n */\n\nimport type { Address } from 'viem'\n\nimport { SCHEMA_VERSION, STORAGE_PREFIX } from '../utils/constants'\n\n/**\n * Get the schema version key.\n */\nexport function getSchemaVersionKey(): string {\n return `${STORAGE_PREFIX}:schemaVersion`\n}\n\n/**\n * Get the base prefix for a specific pool.\n */\nexport function getPoolPrefix(chainId: bigint, poolAddress: Address): string {\n return `${STORAGE_PREFIX}:v${SCHEMA_VERSION}:chain${chainId}:pool${poolAddress.toLowerCase()}`\n}\n\n/**\n * Get the key for tracked position IDs.\n */\nexport function getPositionsKey(chainId: bigint, poolAddress: Address, account: Address): string {\n return `${getPoolPrefix(chainId, poolAddress)}:positions:${account.toLowerCase()}`\n}\n\n/**\n * Get the key for position mint metadata.\n */\nexport function getPositionMetaKey(chainId: bigint, poolAddress: Address, tokenId: bigint): string {\n return `${getPoolPrefix(chainId, poolAddress)}:positionMeta:${tokenId.toString()}`\n}\n\n/**\n * Get the key for sync checkpoint.\n */\nexport function getSyncCheckpointKey(\n chainId: bigint,\n poolAddress: Address,\n account: Address,\n): string {\n return `${getPoolPrefix(chainId, poolAddress)}:sync:${account.toLowerCase()}`\n}\n\n/**\n * Get the key for closed positions.\n */\nexport function getClosedPositionsKey(\n chainId: bigint,\n poolAddress: Address,\n account: Address,\n): string {\n return `${getPoolPrefix(chainId, poolAddress)}:closed:${account.toLowerCase()}`\n}\n\n/**\n * Get the key for tracked chunks.\n */\nexport function getTrackedChunksKey(chainId: bigint, poolAddress: Address): string {\n return `${getPoolPrefix(chainId, poolAddress)}:chunks`\n}\n\n/**\n * Get the key for pending positions.\n */\nexport function getPendingPositionsKey(\n chainId: bigint,\n poolAddress: Address,\n account: Address,\n): string {\n return `${getPoolPrefix(chainId, poolAddress)}:pending:${account.toLowerCase()}`\n}\n\n/**\n * Get the key for pool metadata (tickSpacing, etc.).\n */\nexport function getPoolMetaKey(chainId: bigint, poolAddress: Address): string {\n return `${getPoolPrefix(chainId, poolAddress)}:poolMeta`\n}\n","/**\n * In-memory storage adapter for testing.\n * @module v2/storage/memoryStorage\n */\n\nimport type { StorageAdapter } from './adapter'\n\n/**\n * Creates an in-memory storage adapter.\n * Useful for testing and development.\n *\n * Data is lost when the process exits.\n *\n * @example\n * ```typescript\n * import { createMemoryStorage, createConfig } from 'panoptic-v2-sdk'\n *\n * const config = createConfig({\n * chainId: 1n,\n * transport: http('...'),\n * poolAddress: '0x...',\n * storage: createMemoryStorage(),\n * })\n * ```\n */\nexport function createMemoryStorage(): StorageAdapter {\n const store = new Map<string, string>()\n\n return {\n async get(key: string): Promise<string | null> {\n return store.get(key) ?? null\n },\n\n async set(key: string, value: string): Promise<void> {\n store.set(key, value)\n },\n\n async delete(key: string): Promise<void> {\n store.delete(key)\n },\n\n async has(key: string): Promise<boolean> {\n return store.has(key)\n },\n\n async keys(prefix: string): Promise<string[]> {\n const result: string[] = []\n for (const key of store.keys()) {\n if (key.startsWith(prefix)) {\n result.push(key)\n }\n }\n return result\n },\n\n async clear(prefix: string): Promise<void> {\n const keysToDelete: string[] = []\n for (const key of store.keys()) {\n if (key.startsWith(prefix)) {\n keysToDelete.push(key)\n }\n }\n for (const key of keysToDelete) {\n store.delete(key)\n }\n },\n }\n}\n","/**\n * BigInt-safe JSON serialization for the Panoptic v2 SDK.\n * Compatible with superjson patterns for SSR hydration.\n * @module v2/storage/serializer\n */\n\n/**\n * Tagged value for BigInt serialization.\n * Format compatible with superjson for Next.js/Remix SSR.\n */\ninterface BigIntTagged {\n __type: 'bigint'\n value: string\n}\n\n/**\n * Type guard to check if a value is a tagged BigInt.\n */\nfunction isBigIntTagged(value: unknown): value is BigIntTagged {\n return (\n value !== null &&\n typeof value === 'object' &&\n '__type' in value &&\n (value as BigIntTagged).__type === 'bigint' &&\n 'value' in value &&\n typeof (value as BigIntTagged).value === 'string'\n )\n}\n\n/**\n * Replacer function for JSON.stringify that tags BigInt values.\n */\nfunction replacer(_key: string, value: unknown): unknown {\n if (typeof value === 'bigint') {\n return {\n __type: 'bigint',\n value: value.toString(),\n } satisfies BigIntTagged\n }\n return value\n}\n\n/**\n * Reviver function for JSON.parse that restores tagged BigInt values.\n */\nfunction reviver(_key: string, value: unknown): unknown {\n if (isBigIntTagged(value)) {\n return BigInt(value.value)\n }\n return value\n}\n\n/**\n * BigInt-safe JSON serializer for the Panoptic v2 SDK.\n *\n * This serializer handles BigInt values by tagging them with a special format\n * that can be restored on parse. The format is compatible with superjson\n * patterns used in Next.js and Remix for SSR hydration.\n *\n * @example\n * ```typescript\n * import { jsonSerializer } from 'panoptic-v2-sdk'\n *\n * const data = { amount: 1000000000000000000n, nested: { value: 42n } }\n *\n * // Serialize to JSON string\n * const json = jsonSerializer.stringify(data)\n * // '{\"amount\":{\"__type\":\"bigint\",\"value\":\"1000000000000000000\"},\"nested\":{\"value\":{\"__type\":\"bigint\",\"value\":\"42\"}}}'\n *\n * // Parse back to original types\n * const parsed = jsonSerializer.parse(json)\n * // { amount: 1000000000000000000n, nested: { value: 42n } }\n * ```\n */\nexport const jsonSerializer = {\n /**\n * Serialize a value to a JSON string, handling BigInt values.\n *\n * @param value - The value to serialize\n * @param space - Optional indentation (same as JSON.stringify)\n * @returns JSON string with BigInt values tagged\n */\n stringify(value: unknown, space?: string | number): string {\n return JSON.stringify(value, replacer, space)\n },\n\n /**\n * Parse a JSON string, restoring tagged BigInt values.\n *\n * @param text - The JSON string to parse\n * @returns The parsed value with BigInt values restored\n */\n parse(text: string): unknown {\n return JSON.parse(text, reviver)\n },\n} as const\n","/**\n * Block metadata utilities for the Panoptic v2 SDK.\n * @module v2/clients/blockMeta\n */\n\nimport type { PublicClient } from 'viem'\n\nimport type { BlockMeta } from '../types'\n\n/**\n * Parameters for getBlockMeta.\n */\nexport interface GetBlockMetaParams {\n /** viem PublicClient */\n client: Pick<PublicClient, 'getBlock'>\n /** Optional block number (defaults to latest) */\n blockNumber?: bigint\n}\n\n/**\n * Get block metadata for a given block.\n * Used to tag all read results with same-block consistency proof.\n *\n * @param params - The parameters\n * @returns Block metadata\n */\nexport async function getBlockMeta(params: GetBlockMetaParams): Promise<BlockMeta> {\n const { client, blockNumber } = params\n\n const block = await client.getBlock({\n blockNumber,\n includeTransactions: false,\n })\n\n return {\n blockNumber: block.number,\n blockHash: block.hash,\n blockTimestamp: block.timestamp,\n }\n}\n","/**\n * Timestamp-to-block resolution via RPC binary search.\n * No subgraph dependency — uses only eth_getBlockByNumber.\n * @module v2/clients/blocksByTimestamp\n */\n\nimport type { PublicClient } from 'viem'\n\n/**\n * Parameters for resolveBlockNumbers.\n */\nexport interface ResolveBlockNumbersParams {\n /** viem PublicClient */\n client: PublicClient\n /** Array of Unix timestamps (seconds) to resolve to block numbers */\n timestamps: number[]\n}\n\n/**\n * Resolve an array of Unix timestamps to the closest block numbers via RPC binary search.\n *\n * All binary searches run in parallel, sharing an in-flight-deduped block cache\n * so concurrent searches for nearby timestamps avoid redundant RPC calls.\n *\n * @param params - The parameters\n * @returns Array of block numbers in the same order as the input timestamps\n *\n * @example\n * ```typescript\n * const blocks = await resolveBlockNumbers({\n * client,\n * timestamps: [1700000000, 1700003600, 1700007200],\n * })\n * // blocks: [18500000n, 18500300n, 18500600n]\n * ```\n */\nexport async function resolveBlockNumbers(params: ResolveBlockNumbersParams): Promise<bigint[]> {\n const { client, timestamps } = params\n\n if (timestamps.length === 0) return []\n\n const latestBlock = await client.getBlock({ blockTag: 'latest', includeTransactions: false })\n const latestNumber = latestBlock.number\n const latestTimestamp = Number(latestBlock.timestamp)\n\n // Cache + in-flight dedup: avoids redundant RPC calls across parallel searches\n const cache = new Map<bigint, number>()\n cache.set(latestNumber, latestTimestamp)\n cache.set(0n, 0) // genesis is always timestamp 0 (close enough)\n\n const inflight = new Map<bigint, Promise<number>>()\n\n function getTimestamp(blockNumber: bigint): Promise<number> {\n const cached = cache.get(blockNumber)\n if (cached !== undefined) return Promise.resolve(cached)\n\n const existing = inflight.get(blockNumber)\n if (existing) return existing\n\n const promise = client.getBlock({ blockNumber, includeTransactions: false }).then((block) => {\n const ts = Number(block.timestamp)\n cache.set(blockNumber, ts)\n inflight.delete(blockNumber)\n return ts\n })\n inflight.set(blockNumber, promise)\n return promise\n }\n\n /**\n * Binary search for the last block whose timestamp <= targetTimestamp.\n */\n async function searchBlock(targetTimestamp: number, low: bigint, high: bigint): Promise<bigint> {\n // Clamp: if target is beyond latest, return latest\n if (targetTimestamp >= latestTimestamp) return latestNumber\n\n while (high - low > 1n) {\n const mid = (low + high) / 2n\n const midTs = await getTimestamp(mid)\n\n if (midTs <= targetTimestamp) {\n low = mid\n } else {\n high = mid\n }\n }\n\n return low\n }\n\n // Run all binary searches in parallel — shared cache deduplicates common midpoints\n const results = await Promise.all(timestamps.map((ts) => searchBlock(ts, 0n, latestNumber)))\n\n return results\n}\n\n/**\n * Parameters for estimateBlockNumbers.\n */\nexport interface EstimateBlockNumbersParams {\n /** viem PublicClient */\n client: PublicClient\n /** Array of Unix timestamps (seconds) to resolve to block numbers */\n timestamps: number[]\n /**\n * Bootstrap block-time used only to pick the anchor block (seconds).\n * The final estimate uses the *measured* rate between latest and anchor,\n * so this only affects which sample point we draw — not accuracy on the\n * sampled window. Default 12 (Ethereum L1).\n */\n fallbackBlockTimeSec?: number\n}\n\n/**\n * Estimate block numbers for the given Unix timestamps using a 2-RPC linear\n * extrapolation. Trades binary-search accuracy (~25 RPCs) for ~2 RPCs.\n *\n * Suitable for chart-style use cases where the consumer plots tens-to-hundreds\n * of evenly-spaced points and a ±N-block error is invisible. Not suitable when\n * exact block correspondence is required (e.g. event log ranges).\n *\n * Algorithm:\n * 1. Fetch `latest` block.\n * 2. Use `fallbackBlockTimeSec` to estimate an anchor block roughly co-temporal\n * with the *earliest* requested timestamp.\n * 3. Fetch the anchor block.\n * 4. Compute the measured average block time over [anchor, latest].\n * 5. Linearly extrapolate every requested timestamp from `latest`.\n *\n * If the sampled window is degenerate (e.g. anchor too close to latest, or\n * timestamps near genesis), falls back to {@link resolveBlockNumbers}.\n */\nexport async function estimateBlockNumbers(params: EstimateBlockNumbersParams): Promise<bigint[]> {\n const { client, timestamps, fallbackBlockTimeSec = 12 } = params\n\n if (timestamps.length === 0) return []\n\n const latest = await client.getBlock({ blockTag: 'latest', includeTransactions: false })\n const latestNum = latest.number\n const latestTs = Number(latest.timestamp)\n\n const earliest = Math.min(...timestamps)\n const secAgoMax = Math.max(0, latestTs - earliest)\n\n // All requested timestamps are now-or-future\n if (secAgoMax === 0) return timestamps.map(() => latestNum)\n\n const blocksBackEst = BigInt(Math.floor(secAgoMax / fallbackBlockTimeSec))\n const anchorNum = blocksBackEst >= latestNum ? 1n : latestNum - blocksBackEst\n const anchor = await client.getBlock({\n blockNumber: anchorNum,\n includeTransactions: false,\n })\n\n const numDelta = latestNum - anchor.number\n const tsDelta = latestTs - Number(anchor.timestamp)\n\n // Degenerate sample window — fall back to exact resolution.\n if (numDelta <= 0n || tsDelta <= 0) {\n return resolveBlockNumbers({ client, timestamps })\n }\n\n const avgBlockTimeSec = tsDelta / Number(numDelta)\n\n return timestamps.map((ts) => {\n const secAgo = latestTs - ts\n if (secAgo <= 0) return latestNum\n const blocksAgo = BigInt(Math.round(secAgo / avgBlockTimeSec))\n return blocksAgo >= latestNum ? 1n : latestNum - blocksAgo\n })\n}\n","/**\n * Multicall utilities for the Panoptic v2 SDK.\n * Uses viem's built-in multicall for same-block consistency.\n * @module v2/clients/multicall\n */\n\nimport type { Abi, Address, ContractFunctionArgs, ContractFunctionName, PublicClient } from 'viem'\n\nimport type { BlockMeta } from '../types'\nimport { getBlockMeta } from './blockMeta'\n\n/**\n * A contract call to include in a multicall batch.\n */\nexport interface MulticallContract<\n TAbi extends Abi = Abi,\n TFunctionName extends ContractFunctionName<TAbi, 'pure' | 'view'> = ContractFunctionName<\n TAbi,\n 'pure' | 'view'\n >,\n> {\n /** Contract address */\n address: Address\n /** Contract ABI */\n abi: TAbi\n /** Function name to call */\n functionName: TFunctionName\n /** Function arguments */\n args?: ContractFunctionArgs<TAbi, 'pure' | 'view', TFunctionName>\n}\n\n/**\n * Parameters for multicallRead.\n */\nexport interface MulticallReadParams<TContracts extends readonly MulticallContract[]> {\n /** viem PublicClient */\n client: PublicClient\n /** Array of contract calls to batch */\n contracts: TContracts\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Whether to allow failures (default: false) */\n allowFailure?: boolean\n}\n\n/**\n * Result type for a single multicall contract result.\n */\nexport type MulticallResult<T> =\n | { status: 'success'; result: T }\n | { status: 'failure'; error: Error }\n\n/**\n * Perform a batched multicall read with block metadata.\n * All calls are executed at the same block for consistency.\n *\n * @param params - The multicall parameters\n * @returns Results array with block metadata\n */\nexport async function multicallRead<TContracts extends readonly MulticallContract[]>(\n params: MulticallReadParams<TContracts>,\n): Promise<{\n results: MulticallResult<unknown>[]\n _meta: BlockMeta\n}> {\n const { client, contracts, blockNumber, allowFailure = false } = params\n\n // Get the block number to use (latest if not specified)\n const targetBlockNumber = blockNumber ?? (await client.getBlockNumber())\n\n // Execute multicall and get block meta in parallel\n const [multicallResults, _meta] = await Promise.all([\n client.multicall({\n contracts: contracts as unknown as Parameters<typeof client.multicall>['0']['contracts'],\n blockNumber: targetBlockNumber,\n allowFailure: true, // Always allow failure internally to handle gracefully\n }),\n getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n // Map results to our format\n const results: MulticallResult<unknown>[] = multicallResults.map((result) => {\n if (result.status === 'success') {\n return { status: 'success' as const, result: result.result }\n } else {\n // If allowFailure is false and we have a failure, throw\n if (!allowFailure) {\n throw result.error\n }\n return { status: 'failure' as const, error: result.error }\n }\n })\n\n return { results, _meta }\n}\n","/**\n * TokenId constants for the Panoptic v2 SDK.\n * @module v2/tokenId/constants\n */\n\n/**\n * Default vegoid value used in pool ID encoding.\n */\nexport const DEFAULT_VEGOID = 8n\n\n/**\n * Default MAX_SPREAD value (90_000 = 9 * 10_000).\n * On-chain: removed/net ratio cap, in units of 1/10_000.\n */\nexport const DEFAULT_MAX_SPREAD = 90_000n\n\n/**\n * Standard tick widths matching DTE gamma profiles.\n *\n * These represent the position width in ticks for each timescale.\n * Width = tickUpper - tickLower.\n */\nexport const STANDARD_TICK_WIDTHS = {\n /** 1-hour expiry profile (240 ticks) */\n '1H': 240n,\n /** 1-day expiry profile (720 ticks) */\n '1D': 720n,\n /** 1-week expiry profile (2400 ticks) */\n '1W': 2400n,\n /** 1-month expiry profile (4800 ticks) */\n '1M': 4800n,\n /** 1-year expiry profile (15000 ticks) */\n '1Y': 15000n,\n} as const\n\n/**\n * Timescale key type for STANDARD_TICK_WIDTHS.\n */\nexport type Timescale = keyof typeof STANDARD_TICK_WIDTHS\n\n/**\n * Bit positions and sizes for TokenId encoding.\n */\nexport const TOKEN_ID_BITS = {\n /** Pool ID occupies bits 0-63 */\n POOL_ID_SIZE: 64n,\n /** Vegoid starts at bit 40 within pool ID */\n VEGOID_STARTING_BIT: 40n,\n /** Vegoid is 8 bits */\n VEGOID_SIZE: 8n,\n /** Tick spacing starts at bit 48 within pool ID */\n TICK_SPACING_STARTING_BIT: 48n,\n /** Tick spacing is 16 bits */\n TICK_SPACING_SIZE: 16n,\n /** Each leg is 48 bits */\n LEG_SIZE: 48n,\n /** Maximum number of legs per TokenId */\n MAX_LEGS: 4n,\n} as const\n\n/**\n * Bit positions within a leg (relative to leg start).\n */\nexport const LEG_BITS = {\n /** Asset bit position */\n ASSET_BIT: 0n,\n /** Asset size in bits */\n ASSET_SIZE: 1n,\n /** Option ratio starting bit */\n RATIO_BIT: 1n,\n /** Option ratio size in bits */\n RATIO_SIZE: 7n,\n /** Is long starting bit */\n IS_LONG_BIT: 8n,\n /** Is long size in bits */\n IS_LONG_SIZE: 1n,\n /** Token type starting bit */\n TOKEN_TYPE_BIT: 9n,\n /** Token type size in bits */\n TOKEN_TYPE_SIZE: 1n,\n /** Risk partner starting bit */\n RISK_PARTNER_BIT: 10n,\n /** Risk partner size in bits */\n RISK_PARTNER_SIZE: 2n,\n /** Strike starting bit */\n STRIKE_BIT: 12n,\n /** Strike size in bits (24 bits, signed int24) */\n STRIKE_SIZE: 24n,\n /** Width starting bit */\n WIDTH_BIT: 36n,\n /** Width size in bits */\n WIDTH_SIZE: 12n,\n} as const\n\n/**\n * Masks for extracting/encoding leg fields.\n */\nexport const LEG_MASKS = {\n /** Mask for asset (1 bit) */\n ASSET: (1n << LEG_BITS.ASSET_SIZE) - 1n,\n /** Mask for option ratio (7 bits) */\n RATIO: (1n << LEG_BITS.RATIO_SIZE) - 1n,\n /** Mask for is long (1 bit) */\n IS_LONG: (1n << LEG_BITS.IS_LONG_SIZE) - 1n,\n /** Mask for token type (1 bit) */\n TOKEN_TYPE: (1n << LEG_BITS.TOKEN_TYPE_SIZE) - 1n,\n /** Mask for risk partner (2 bits) */\n RISK_PARTNER: (1n << LEG_BITS.RISK_PARTNER_SIZE) - 1n,\n /** Mask for strike (24 bits) */\n STRIKE: (1n << LEG_BITS.STRIKE_SIZE) - 1n,\n /** Mask for width (12 bits) */\n WIDTH: (1n << LEG_BITS.WIDTH_SIZE) - 1n,\n /** Mask for entire leg (48 bits) */\n LEG: (1n << TOKEN_ID_BITS.LEG_SIZE) - 1n,\n} as const\n\n/**\n * Maximum and minimum values for leg fields.\n */\nexport const LEG_LIMITS = {\n /** Maximum option ratio (127) */\n MAX_RATIO: 127n,\n /** Maximum width (4095) */\n MAX_WIDTH: 4095n,\n /** Maximum strike (8388607, max int24 positive) */\n MAX_STRIKE: 8388607n,\n /** Minimum strike (-8388608, min int24) */\n MIN_STRIKE: -8388608n,\n} as const\n\n/**\n * Value used to convert negative strike to unsigned representation.\n * Strike is stored as int24, so we use 2^24 for conversion.\n */\nexport const STRIKE_CONVERSION_FACTOR = 16777216n\n","/**\n * Low-level TokenId encoding utilities for the Panoptic v2 SDK.\n * @module v2/tokenId/encoding\n */\n\nimport type { Address, Hex } from 'viem'\n\nimport {\n DEFAULT_VEGOID,\n LEG_BITS,\n LEG_MASKS,\n STRIKE_CONVERSION_FACTOR,\n TOKEN_ID_BITS,\n} from './constants'\n\n/**\n * Leg parameters for encoding.\n */\nexport interface EncodeLegParams {\n /** Leg index (0-3) */\n index: bigint\n /** Asset index (0 or 1) */\n asset: bigint\n /** Option ratio (1-127) */\n optionRatio: bigint\n /** Whether this is a long position (1n = long, 0n = short) */\n isLong: bigint\n /** Token type (0 or 1) */\n tokenType: bigint\n /** Risk partner leg index (0-3) */\n riskPartner: bigint\n /** Strike tick */\n strike: bigint\n /** Width in tick spacing units */\n width: bigint\n}\n\n/**\n * Convert a signed strike tick to unsigned representation for encoding.\n *\n * @param strike - The signed strike tick\n * @returns The unsigned representation\n */\nexport function convertStrikeToUnsigned(strike: bigint): bigint {\n if (strike < 0n) {\n return STRIKE_CONVERSION_FACTOR + strike\n }\n return strike\n}\n\n/**\n * Convert an unsigned encoded strike back to signed representation.\n *\n * @param encodedStrike - The unsigned encoded strike\n * @returns The signed strike tick\n */\nexport function convertStrikeToSigned(encodedStrike: bigint): bigint {\n // If the value is greater than max positive int24, it's negative\n if (encodedStrike > 2n ** 23n - 1n) {\n return encodedStrike - STRIKE_CONVERSION_FACTOR\n }\n return encodedStrike\n}\n\n/**\n * Get the bit offset for a leg at the given index.\n *\n * @param legIndex - The leg index (0-3)\n * @returns The bit offset from the start of the legs section\n */\nexport function getLegOffset(legIndex: bigint): bigint {\n return legIndex * TOKEN_ID_BITS.LEG_SIZE\n}\n\n/**\n * Encode a pool ID from a Uniswap V3 pool address.\n *\n * The encoded PoolId structure: [16-bit tickSpacing][8-bit vegoid][40-bit pool address]\n *\n * @param address - The Uniswap V3 pool address\n * @param tickSpacing - The tick spacing of the pool\n * @param vegoid - The vegoid value (defaults to 4)\n * @returns The encoded pool ID\n */\nexport function encodePoolId(\n address: Address,\n tickSpacing: bigint,\n vegoid: bigint = DEFAULT_VEGOID,\n): bigint {\n // Remove 0x prefix and get first 10 hex chars (5 bytes = 40 bits)\n const addressHex = address.slice(2, 12).toLowerCase()\n\n // Convert to bytes array (big-endian), then reverse to little-endian\n const bytes: number[] = []\n for (let i = 0; i < 10; i += 2) {\n bytes.push(parseInt(addressHex.slice(i, i + 2), 16))\n }\n bytes.reverse()\n\n // Build poolId: pool address (5 bytes) + vegoid (1 byte) + tickSpacing (2 bytes)\n let poolId = 0n\n for (let i = 0; i < bytes.length; i++) {\n poolId |= BigInt(bytes[i]) << BigInt(i * 8)\n }\n\n // Add vegoid at bit 40\n poolId |= (vegoid & 0xffn) << TOKEN_ID_BITS.VEGOID_STARTING_BIT\n\n // Add tickSpacing at bit 48\n poolId |= (tickSpacing & 0xffffn) << TOKEN_ID_BITS.TICK_SPACING_STARTING_BIT\n\n return poolId\n}\n\n/**\n * Encode a pool ID from a Uniswap V4 pool ID (bytes32).\n *\n * @param poolIdHex - The V4 pool ID (bytes32 hex string)\n * @param tickSpacing - The tick spacing of the pool\n * @param vegoid - The vegoid value (defaults to 4)\n * @returns The encoded pool ID\n */\nexport function encodeV4PoolId(\n poolIdHex: Hex,\n tickSpacing: bigint,\n vegoid: bigint = DEFAULT_VEGOID,\n): bigint {\n // Remove 0x prefix and get last 10 hex chars (5 bytes = 40 bits)\n const hex = poolIdHex.slice(2)\n const last5BytesHex = hex.slice(-10).toLowerCase()\n\n // Convert to bytes array (big-endian), then reverse to little-endian\n const bytes: number[] = []\n for (let i = 0; i < 10; i += 2) {\n bytes.push(parseInt(last5BytesHex.slice(i, i + 2), 16))\n }\n bytes.reverse()\n\n // Build encoded poolId\n let encodedPoolId = 0n\n for (let i = 0; i < bytes.length; i++) {\n encodedPoolId |= BigInt(bytes[i]) << BigInt(i * 8)\n }\n\n // Add vegoid at bit 40\n encodedPoolId |= (vegoid & 0xffn) << TOKEN_ID_BITS.VEGOID_STARTING_BIT\n\n // Add tickSpacing at bit 48\n encodedPoolId |= (tickSpacing & 0xffffn) << TOKEN_ID_BITS.TICK_SPACING_STARTING_BIT\n\n return encodedPoolId\n}\n\n/**\n * Decode the vegoid from a TokenId.\n *\n * @param tokenId - The TokenId to decode\n * @returns The vegoid value\n */\nexport function decodeVegoid(tokenId: bigint): bigint {\n const poolId = tokenId & ((1n << TOKEN_ID_BITS.POOL_ID_SIZE) - 1n)\n return (poolId >> TOKEN_ID_BITS.VEGOID_STARTING_BIT) & ((1n << TOKEN_ID_BITS.VEGOID_SIZE) - 1n)\n}\n\n/**\n * Decode the tick spacing from a TokenId.\n *\n * @param tokenId - The TokenId to decode\n * @returns The tick spacing\n */\nexport function decodeTickSpacing(tokenId: bigint): bigint {\n const poolId = tokenId & ((1n << TOKEN_ID_BITS.POOL_ID_SIZE) - 1n)\n return poolId >> TOKEN_ID_BITS.TICK_SPACING_STARTING_BIT\n}\n\n/**\n * Decode the pool ID portion from a TokenId.\n *\n * @param tokenId - The TokenId to decode\n * @returns The pool ID as a hex string\n */\nexport function decodePoolId(tokenId: bigint): Hex {\n const poolId = tokenId & ((1n << TOKEN_ID_BITS.POOL_ID_SIZE) - 1n)\n let hex = poolId.toString(16)\n // Pad to 16 characters (64 bits)\n while (hex.length < 16) {\n hex = '0' + hex\n }\n return `0x${hex}` as Hex\n}\n\n/**\n * Encode a single leg field.\n *\n * @param value - The value to encode\n * @param bitPosition - The bit position within the leg\n * @param legIndex - The leg index\n * @returns The encoded value shifted to the correct position\n */\nfunction encodeLegField(value: bigint, bitPosition: bigint, legIndex: bigint): bigint {\n return value << (getLegOffset(legIndex) + bitPosition + TOKEN_ID_BITS.POOL_ID_SIZE)\n}\n\n/**\n * Encode a single leg into a TokenId.\n *\n * @param leg - The leg parameters\n * @returns The encoded leg value (to be ORed with existing TokenId)\n */\nexport function encodeLeg(leg: EncodeLegParams): bigint {\n const { index, asset, optionRatio, isLong, tokenType, riskPartner, strike, width } = leg\n\n return (\n encodeLegField(asset & LEG_MASKS.ASSET, LEG_BITS.ASSET_BIT, index) |\n encodeLegField(optionRatio & LEG_MASKS.RATIO, LEG_BITS.RATIO_BIT, index) |\n encodeLegField(isLong & LEG_MASKS.IS_LONG, LEG_BITS.IS_LONG_BIT, index) |\n encodeLegField(tokenType & LEG_MASKS.TOKEN_TYPE, LEG_BITS.TOKEN_TYPE_BIT, index) |\n encodeLegField(riskPartner & LEG_MASKS.RISK_PARTNER, LEG_BITS.RISK_PARTNER_BIT, index) |\n encodeLegField(convertStrikeToUnsigned(strike) & LEG_MASKS.STRIKE, LEG_BITS.STRIKE_BIT, index) |\n encodeLegField(width & LEG_MASKS.WIDTH, LEG_BITS.WIDTH_BIT, index)\n )\n}\n\n/**\n * Add a leg to an existing TokenId.\n *\n * @param tokenId - The existing TokenId (can be just poolId or partial TokenId)\n * @param leg - The leg parameters to add\n * @returns The TokenId with the leg added\n */\nexport function addLegToTokenId(tokenId: bigint, leg: EncodeLegParams): bigint {\n return tokenId | encodeLeg(leg)\n}\n\n/**\n * Decoded leg data.\n */\nexport interface DecodedLeg {\n /** Leg index (0-3) */\n index: bigint\n /** Asset index (0 or 1) */\n asset: bigint\n /** Option ratio (1-127) */\n optionRatio: bigint\n /** Whether this is a long position */\n isLong: boolean\n /** Token type (0 or 1) */\n tokenType: bigint\n /** Risk partner leg index */\n riskPartner: bigint\n /** Strike tick (signed) */\n strike: bigint\n /** Width in tick spacing units */\n width: bigint\n}\n\n/**\n * Decode a single leg from a TokenId.\n *\n * @param tokenId - The TokenId to decode\n * @param legIndex - The leg index (0-3)\n * @returns The decoded leg data\n */\nexport function decodeLeg(tokenId: bigint, legIndex: bigint): DecodedLeg {\n const offset = getLegOffset(legIndex) + TOKEN_ID_BITS.POOL_ID_SIZE\n const leg = (tokenId >> offset) & LEG_MASKS.LEG\n\n const asset = leg & LEG_MASKS.ASSET\n const optionRatio = (leg >> LEG_BITS.RATIO_BIT) & LEG_MASKS.RATIO\n const isLong = ((leg >> LEG_BITS.IS_LONG_BIT) & LEG_MASKS.IS_LONG) === 1n\n const tokenType = (leg >> LEG_BITS.TOKEN_TYPE_BIT) & LEG_MASKS.TOKEN_TYPE\n const riskPartner = (leg >> LEG_BITS.RISK_PARTNER_BIT) & LEG_MASKS.RISK_PARTNER\n const encodedStrike = (leg >> LEG_BITS.STRIKE_BIT) & LEG_MASKS.STRIKE\n const strike = convertStrikeToSigned(encodedStrike)\n const width = (leg >> LEG_BITS.WIDTH_BIT) & LEG_MASKS.WIDTH\n\n return {\n index: legIndex,\n asset,\n optionRatio,\n isLong,\n tokenType,\n riskPartner,\n strike,\n width,\n }\n}\n\n/**\n * Count the number of active legs in a TokenId.\n * A leg is active if its optionRatio > 0.\n *\n * @param tokenId - The TokenId to check\n * @returns The number of active legs\n */\nexport function countLegs(tokenId: bigint): bigint {\n let count = 0n\n for (let i = 0n; i < TOKEN_ID_BITS.MAX_LEGS; i++) {\n const leg = decodeLeg(tokenId, i)\n if (leg.optionRatio > 0n) {\n count++\n }\n }\n return count\n}\n\n/**\n * Decode all active legs from a TokenId.\n *\n * @param tokenId - The TokenId to decode\n * @returns Array of decoded legs (only active legs with optionRatio > 0)\n */\nexport function decodeAllLegs(tokenId: bigint): DecodedLeg[] {\n const legs: DecodedLeg[] = []\n for (let i = 0n; i < TOKEN_ID_BITS.MAX_LEGS; i++) {\n const leg = decodeLeg(tokenId, i)\n if (leg.optionRatio > 0n) {\n legs.push(leg)\n }\n }\n return legs\n}\n","/**\n * TokenId builder for the Panoptic v2 SDK.\n * @module v2/tokenId/builder\n */\n\nimport { InvalidTokenIdParameterError } from '../errors'\nimport { LEG_LIMITS, TOKEN_ID_BITS } from './constants'\nimport { type EncodeLegParams, addLegToTokenId } from './encoding'\n\n/**\n * Leg configuration for the builder.\n */\nexport interface LegConfig {\n /** Asset index (0 or 1) */\n asset: bigint\n /** Option ratio (1-127) */\n optionRatio: bigint\n /** Whether this is a long position */\n isLong: boolean\n /** Token type (0 or 1) */\n tokenType: bigint\n /** Risk partner leg index (defaults to self) */\n riskPartner?: bigint\n /** Strike tick (center of the range) */\n strike: bigint\n /** Width in tick spacing units (0 for loans/credits) */\n width: bigint\n}\n\n/**\n * Loan/credit leg configuration.\n * Uses width=0 encoding to signal the loan/credit branch.\n */\nexport interface LoanCreditConfig {\n /** Asset index (0 or 1) */\n asset: bigint\n /** Token type (0 or 1) - which token to borrow/lend */\n tokenType: bigint\n /** Strike tick (price point for the loan/credit) */\n strike: bigint\n /** Option ratio (1-127, defaults to 1) */\n optionRatio?: bigint\n /** Risk partner leg index (defaults to self) */\n riskPartner?: bigint\n}\n\n/**\n * TokenId builder interface.\n * Provides a fluent API for constructing TokenIds.\n */\nexport interface TokenIdBuilder {\n /**\n * Add a leg to the TokenId.\n * @param config - The leg configuration\n * @returns The builder for chaining\n * @throws InvalidTokenIdParameterError if leg parameters are invalid\n */\n addLeg: (config: LegConfig) => TokenIdBuilder\n\n /**\n * Add a call leg. A call is when tokenType === asset.\n * @param config - Partial leg config (tokenType set automatically based on asset, asset defaults to 0)\n * @returns The builder for chaining\n */\n addCall: (config: Omit<LegConfig, 'tokenType' | 'asset'> & { asset?: bigint }) => TokenIdBuilder\n\n /**\n * Add a put leg. A put is when tokenType !== asset.\n * @param config - Partial leg config (tokenType set automatically based on asset, asset defaults to 0)\n * @returns The builder for chaining\n */\n addPut: (config: Omit<LegConfig, 'tokenType' | 'asset'> & { asset?: bigint }) => TokenIdBuilder\n\n /**\n * Add a loan leg (borrow liquidity). Uses width=0 with isLong=false.\n *\n * A loan borrows liquidity from the pool at a specific strike price.\n * The borrower receives the token and owes interest (streaming premium).\n *\n * @param config - Loan configuration (tokenType, strike, optionRatio)\n * @returns The builder for chaining\n */\n addLoan: (config: LoanCreditConfig) => TokenIdBuilder\n\n /**\n * Add a credit leg (lend liquidity). Uses width=0 with isLong=true.\n *\n * A credit lends liquidity to the pool at a specific strike price.\n * The lender deposits the token and earns interest (streaming premium).\n *\n * @param config - Credit configuration (tokenType, strike, optionRatio)\n * @returns The builder for chaining\n */\n addCredit: (config: LoanCreditConfig) => TokenIdBuilder\n\n /**\n * Build the final TokenId.\n * @returns The constructed TokenId\n * @throws InvalidTokenIdParameterError if the TokenId has no legs\n */\n build: () => bigint\n\n /**\n * Get the current number of legs.\n * @returns The leg count\n */\n legCount: () => bigint\n\n /**\n * Reset the builder to start fresh with just the pool ID.\n * @returns The builder for chaining\n */\n reset: () => TokenIdBuilder\n}\n\n/**\n * Create a TokenId builder from an encoded pool ID.\n *\n * Use the 64-bit poolId from `getPool().poolId` or `fetchPoolId()`.\n * For offline encoding, use `encodePoolId()` or `encodeV4PoolId()` first.\n *\n * @param poolId - The encoded 64-bit pool ID\n * @returns A TokenId builder instance\n *\n * @example\n * ```typescript\n * const pool = await getPool({ client, poolAddress, chainId })\n * const tokenId = createTokenIdBuilder(pool.poolId)\n * .addCall({ strike: 100n, width: 10n, optionRatio: 1n, isLong: false })\n * .addPut({ strike: -100n, width: 10n, optionRatio: 1n, isLong: false })\n * .build()\n * ```\n */\nexport function createTokenIdBuilder(poolId: bigint): TokenIdBuilder {\n let tokenId = poolId\n let currentLegIndex = 0n\n\n const validateLegConfig = (config: LegConfig, legIndex: bigint): void => {\n if (legIndex >= TOKEN_ID_BITS.MAX_LEGS) {\n throw new InvalidTokenIdParameterError(0n) // Too many legs\n }\n\n if (config.optionRatio < 1n || config.optionRatio > LEG_LIMITS.MAX_RATIO) {\n throw new InvalidTokenIdParameterError(1n) // Invalid option ratio\n }\n\n // width == 0 is valid for loans/credits, otherwise must be 1-4095\n if (config.width < 0n || config.width > LEG_LIMITS.MAX_WIDTH) {\n throw new InvalidTokenIdParameterError(2n) // Invalid width\n }\n\n if (config.strike < LEG_LIMITS.MIN_STRIKE || config.strike > LEG_LIMITS.MAX_STRIKE) {\n throw new InvalidTokenIdParameterError(3n) // Invalid strike\n }\n\n if (config.asset !== 0n && config.asset !== 1n) {\n throw new InvalidTokenIdParameterError(4n) // Invalid asset\n }\n\n if (config.tokenType !== 0n && config.tokenType !== 1n) {\n throw new InvalidTokenIdParameterError(5n) // Invalid tokenType\n }\n\n const riskPartner = config.riskPartner ?? legIndex\n if (riskPartner < 0n || riskPartner > 3n) {\n throw new InvalidTokenIdParameterError(6n) // Invalid risk partner\n }\n }\n\n const builder: TokenIdBuilder = {\n addLeg(config: LegConfig): TokenIdBuilder {\n validateLegConfig(config, currentLegIndex)\n\n const leg: EncodeLegParams = {\n index: currentLegIndex,\n asset: config.asset,\n optionRatio: config.optionRatio,\n isLong: config.isLong ? 1n : 0n,\n tokenType: config.tokenType,\n riskPartner: config.riskPartner ?? currentLegIndex,\n strike: config.strike,\n width: config.width,\n }\n\n tokenId = addLegToTokenId(tokenId, leg)\n currentLegIndex++\n\n return builder\n },\n\n addCall(config: Omit<LegConfig, 'tokenType' | 'asset'> & { asset?: bigint }): TokenIdBuilder {\n const asset = config.asset ?? 0n\n return builder.addLeg({\n ...config,\n tokenType: asset, // Call: tokenType === asset\n asset,\n })\n },\n\n addPut(config: Omit<LegConfig, 'tokenType' | 'asset'> & { asset?: bigint }): TokenIdBuilder {\n const asset = config.asset ?? 0n\n return builder.addLeg({\n ...config,\n tokenType: asset === 0n ? 1n : 0n, // Put: tokenType !== asset\n asset,\n })\n },\n\n addLoan(config: LoanCreditConfig): TokenIdBuilder {\n // Loan: width=0, isLong=false (borrowing liquidity)\n // asset is set to same as tokenType for loans\n return builder.addLeg({\n asset: config.asset,\n optionRatio: config.optionRatio ?? 1n,\n isLong: false,\n tokenType: config.tokenType,\n riskPartner: config.riskPartner,\n strike: config.strike,\n width: 0n, // width=0 signals loan/credit branch\n })\n },\n\n addCredit(config: LoanCreditConfig): TokenIdBuilder {\n // Credit: width=0, isLong=true (lending liquidity)\n // asset is set to same as tokenType for credits\n return builder.addLeg({\n asset: config.asset,\n optionRatio: config.optionRatio ?? 1n,\n isLong: true,\n tokenType: config.tokenType,\n riskPartner: config.riskPartner,\n strike: config.strike,\n width: 0n, // width=0 signals loan/credit branch\n })\n },\n\n build(): bigint {\n if (currentLegIndex === 0n) {\n throw new InvalidTokenIdParameterError(7n) // No legs\n }\n return tokenId\n },\n\n legCount(): bigint {\n return currentLegIndex\n },\n\n reset(): TokenIdBuilder {\n tokenId = poolId\n currentLegIndex = 0n\n return builder\n },\n }\n\n return builder\n}\n","/**\n * TokenId decoding for the Panoptic v2 SDK.\n * @module v2/tokenId/decode\n */\n\nimport type { TokenIdLeg } from '../types'\nimport {\n type DecodedLeg,\n countLegs,\n decodeAllLegs,\n decodePoolId,\n decodeTickSpacing,\n decodeVegoid,\n} from './encoding'\n\n/**\n * Decoded TokenId data.\n */\nexport interface DecodedTokenId {\n /** The original TokenId */\n tokenId: bigint\n /** The pool ID portion as hex */\n poolId: `0x${string}`\n /** The vegoid value */\n vegoid: bigint\n /** The tick spacing */\n tickSpacing: bigint\n /** The decoded legs */\n legs: TokenIdLeg[]\n /** Number of active legs */\n legCount: bigint\n}\n\n/**\n * Convert a DecodedLeg to TokenIdLeg format.\n *\n * @param leg - The decoded leg from encoding utils\n * @param tickSpacing - The tick spacing for calculating tick bounds\n * @returns The TokenIdLeg format\n */\nfunction convertToTokenIdLeg(leg: DecodedLeg, tickSpacing: bigint): TokenIdLeg {\n // Calculate tick bounds from strike and width\n // width is in tick spacing units, so actual width = width * tickSpacing\n const halfWidth = (leg.width * tickSpacing) / 2n\n const tickLower = leg.strike - halfWidth\n const tickUpper = leg.strike + halfWidth\n\n return {\n index: leg.index,\n asset: leg.asset,\n optionRatio: leg.optionRatio,\n isLong: leg.isLong,\n tokenType: leg.tokenType,\n riskPartner: leg.riskPartner,\n strike: leg.strike,\n width: leg.width,\n tickLower,\n tickUpper,\n }\n}\n\n/**\n * Decode a TokenId into its component parts.\n *\n * @param tokenId - The TokenId to decode\n * @returns The decoded TokenId data\n *\n * @example\n * ```typescript\n * const decoded = decodeTokenId(tokenId)\n * console.log(decoded.legs) // Array of legs\n * console.log(decoded.tickSpacing) // Tick spacing\n * ```\n */\nexport function decodeTokenId(tokenId: bigint): DecodedTokenId {\n const poolId = decodePoolId(tokenId)\n const vegoid = decodeVegoid(tokenId)\n const tickSpacing = decodeTickSpacing(tokenId)\n const rawLegs = decodeAllLegs(tokenId)\n const numLegs = countLegs(tokenId)\n\n const legs = rawLegs.map((leg) => convertToTokenIdLeg(leg, tickSpacing))\n\n return {\n tokenId,\n poolId,\n vegoid,\n tickSpacing,\n legs,\n legCount: numLegs,\n }\n}\n\n/**\n * Validate that a TokenId has the expected pool ID.\n *\n * @param tokenId - The TokenId to validate\n * @param expectedPoolId - The expected pool ID\n * @returns True if the pool IDs match\n */\nexport function validatePoolId(tokenId: bigint, expectedPoolId: bigint): boolean {\n const actualPoolId = tokenId & ((1n << 64n) - 1n)\n return actualPoolId === expectedPoolId\n}\n\n/**\n * Check if a TokenId represents a long position (any leg is long).\n *\n * @param tokenId - The TokenId to check\n * @returns True if any leg is long\n */\nexport function hasLongLeg(tokenId: bigint): boolean {\n const legs = decodeAllLegs(tokenId)\n return legs.some((leg) => leg.isLong)\n}\n\n/**\n * Check if a TokenId represents a short-only position.\n *\n * @param tokenId - The TokenId to check\n * @returns True if all legs are short\n */\nexport function isShortOnly(tokenId: bigint): boolean {\n const legs = decodeAllLegs(tokenId)\n return legs.length > 0 && legs.every((leg) => !leg.isLong)\n}\n\n/**\n * Check if a TokenId represents a spread (legs with different risk partners).\n *\n * @param tokenId - The TokenId to check\n * @returns True if any leg has a different risk partner\n */\nexport function isSpread(tokenId: bigint): boolean {\n const legs = decodeAllLegs(tokenId)\n return legs.some((leg) => leg.riskPartner !== leg.index)\n}\n\n/**\n * Get the asset index for a TokenId (from the first leg).\n *\n * @param tokenId - The TokenId\n * @returns The asset index (0 or 1), or undefined if no legs\n */\nexport function getAssetIndex(tokenId: bigint): bigint | undefined {\n const legs = decodeAllLegs(tokenId)\n if (legs.length === 0) {\n return undefined\n }\n return legs[0].asset\n}\n\n/**\n * Check if a leg is a loan (width=0 and isLong=false).\n *\n * Loans borrow liquidity from the pool at a specific strike price.\n *\n * @param leg - The decoded leg to check\n * @returns True if the leg is a loan\n */\nexport function isLoanLeg(leg: DecodedLeg): boolean {\n return leg.width === 0n && !leg.isLong\n}\n\n/**\n * Check if a leg is a credit (width=0 and isLong=true).\n *\n * Credits lend liquidity to the pool at a specific strike price.\n *\n * @param leg - The decoded leg to check\n * @returns True if the leg is a credit\n */\nexport function isCreditLeg(leg: DecodedLeg): boolean {\n return leg.width === 0n && leg.isLong\n}\n\n/**\n * Check if a TokenId has any loan legs.\n *\n * @param tokenId - The TokenId to check\n * @returns True if any leg is a loan (width=0, isLong=false)\n */\nexport function hasLoanLeg(tokenId: bigint): boolean {\n const legs = decodeAllLegs(tokenId)\n return legs.some(isLoanLeg)\n}\n\n/**\n * Check if a TokenId has any credit legs.\n *\n * @param tokenId - The TokenId to check\n * @returns True if any leg is a credit (width=0, isLong=true)\n */\nexport function hasCreditLeg(tokenId: bigint): boolean {\n const legs = decodeAllLegs(tokenId)\n return legs.some(isCreditLeg)\n}\n\n/**\n * Check if a TokenId is a pure loan (all legs are loans).\n *\n * @param tokenId - The TokenId to check\n * @returns True if all legs are loans\n */\nexport function isLoan(tokenId: bigint): boolean {\n const legs = decodeAllLegs(tokenId)\n return legs.length > 0 && legs.every(isLoanLeg)\n}\n\n/**\n * Check if a TokenId is a pure credit (all legs are credits).\n *\n * @param tokenId - The TokenId to check\n * @returns True if all legs are credits\n */\nexport function isCredit(tokenId: bigint): boolean {\n const legs = decodeAllLegs(tokenId)\n return legs.length > 0 && legs.every(isCreditLeg)\n}\n\n/**\n * Check if a TokenId contains loan or credit legs (width=0).\n *\n * @param tokenId - The TokenId to check\n * @returns True if any leg has width=0 (loan or credit)\n */\nexport function hasLoanOrCredit(tokenId: bigint): boolean {\n const legs = decodeAllLegs(tokenId)\n return legs.some((leg) => leg.width === 0n)\n}\n","/**\n * Encode SFPM swap calldata (mint + burn wrapped in a single multicall).\n * @module v2/sfpmSwap/calldata\n */\nimport { type Hex, encodeFunctionData } from 'viem'\n\nimport { semiFungiblePositionManagerV3Abi as sfpmV3Abi } from '../../../generated'\nimport type { SfpmSwapPlan } from './types'\n\n/** Encoded calldata for an SFPM swap. */\nexport interface SfpmSwapCalldata {\n /** The `SFPM.multicall(bytes[])` calldata to send to {@link SfpmSwapPlan.sfpmAddress}. */\n multicallData: Hex\n /** The inner `mintTokenizedPosition` calldata (index 0 of the multicall). */\n mintData: Hex\n /** The inner `burnTokenizedPosition` calldata (index 1 of the multicall). */\n burnData: Hex\n}\n\n/**\n * Encode the `multicall([mint, burn])` for a swap plan.\n *\n * The order is always `[mint, burn]` — the ERC1155 must be minted before it is\n * burned. Which call carries the inverted (swap) limits is decided in the plan.\n */\nexport function buildSfpmSwapCalldata(plan: SfpmSwapPlan): SfpmSwapCalldata {\n const mintData = encodeFunctionData({\n abi: sfpmV3Abi,\n functionName: 'mintTokenizedPosition',\n args: [\n plan.poolKey,\n plan.tokenId,\n plan.positionSize,\n plan.mintTickLimits[0],\n plan.mintTickLimits[1],\n ],\n })\n const burnData = encodeFunctionData({\n abi: sfpmV3Abi,\n functionName: 'burnTokenizedPosition',\n args: [\n plan.poolKey,\n plan.tokenId,\n plan.positionSize,\n plan.burnTickLimits[0],\n plan.burnTickLimits[1],\n ],\n })\n const multicallData = encodeFunctionData({\n abi: sfpmV3Abi,\n functionName: 'multicall',\n args: [[mintData, burnData]],\n })\n return { multicallData, mintData, burnData }\n}\n","/**\n * Resolve / ensure a Uniswap v3 pool is registered on the SFPM.\n * @module v2/sfpmSwap/init\n */\nimport type { Address, PublicClient, WalletClient } from 'viem'\nimport { getAddress, zeroAddress } from 'viem'\n\nimport { semiFungiblePositionManagerV3Abi as sfpmV3Abi } from '../../../generated'\nimport { PanopticError, WrongUniswapPoolError } from '../errors'\nimport { DEFAULT_VEGOID } from '../tokenId'\n\nexport interface FetchSfpmV3PoolIdParams {\n client: PublicClient\n sfpmAddress: Address\n token0: Address\n token1: Address\n /** Uniswap fee tier (e.g. 500 for 0.05%). */\n fee: number\n /** Vegoid; defaults to the SDK {@link DEFAULT_VEGOID}. Must match the market's other pools. */\n vegoid?: number\n}\n\n/**\n * Resolve the `uint64` SFPM poolId for a Uniswap v3 pool, initializing it if needed.\n *\n * `initializeAMMPool` is permissionless and idempotent and **returns the poolId**\n * whether or not the pool was already registered, so a `simulateContract` call is\n * enough to learn the id without sending a transaction. Always resolve the id this\n * way rather than encoding it offline — the SFPM can collision-increment ids.\n */\nexport async function fetchSfpmV3PoolId(params: FetchSfpmV3PoolIdParams): Promise<bigint> {\n const { client, sfpmAddress, token0, token1, fee } = params\n const vegoid = params.vegoid ?? Number(DEFAULT_VEGOID)\n const { result } = await client.simulateContract({\n address: sfpmAddress,\n abi: sfpmV3Abi,\n functionName: 'initializeAMMPool',\n args: [token0, token1, fee, vegoid],\n })\n return BigInt(result)\n}\n\nexport interface EnsureSfpmV3PoolInitializedParams extends FetchSfpmV3PoolIdParams {\n wallet: WalletClient\n /** Expected underlying Uniswap v3 pool; if provided, the resolved id is verified against it. */\n expectedPool?: Address\n}\n\nexport interface EnsureSfpmV3PoolInitializedResult {\n poolId: bigint\n /** True if an `initializeAMMPool` transaction was sent (pool was not yet registered). */\n initialized: boolean\n}\n\n/**\n * Ensure a Uniswap v3 pool is registered on the SFPM, sending `initializeAMMPool`\n * only if it is not already registered. Returns the resolved poolId.\n *\n * When `expectedPool` is given, the resolved id is checked to map back to it via\n * `getUniswapV3PoolFromId` — guards against a wrong token/fee triple.\n */\nexport async function ensureSfpmV3PoolInitialized(\n params: EnsureSfpmV3PoolInitializedParams,\n): Promise<EnsureSfpmV3PoolInitializedResult> {\n const { client, wallet, sfpmAddress, token0, token1, fee, expectedPool } = params\n const vegoid = params.vegoid ?? Number(DEFAULT_VEGOID)\n\n const poolId = await fetchSfpmV3PoolId({ client, sfpmAddress, token0, token1, fee, vegoid })\n\n const registered = await client.readContract({\n address: sfpmAddress,\n abi: sfpmV3Abi,\n functionName: 'getUniswapV3PoolFromId',\n args: [poolId],\n })\n\n let initialized = false\n let resolved = registered\n if (getAddress(registered) === zeroAddress) {\n const account = wallet.account\n if (account === undefined) throw new PanopticError('wallet client has no account')\n const hash = await wallet.writeContract({\n account,\n chain: wallet.chain ?? null,\n address: sfpmAddress,\n abi: sfpmV3Abi,\n functionName: 'initializeAMMPool',\n args: [token0, token1, fee, vegoid],\n })\n await client.waitForTransactionReceipt({ hash })\n initialized = true\n // Re-read only after we sent initializeAMMPool; an already-registered pool\n // reuses the first read.\n resolved = await client.readContract({\n address: sfpmAddress,\n abi: sfpmV3Abi,\n functionName: 'getUniswapV3PoolFromId',\n args: [poolId],\n })\n }\n\n if (expectedPool !== undefined && getAddress(resolved) !== getAddress(expectedPool)) {\n throw new WrongUniswapPoolError(\n new PanopticError(`SFPM poolId ${poolId} resolves to ${resolved}, expected ${expectedPool}`),\n )\n }\n\n return { poolId, initialized }\n}\n","/**\n * Build an SFPM off-venue swap plan (tokenId + per-call tick limits).\n * @module v2/sfpmSwap/plan\n */\nimport { encodeAbiParameters } from 'viem'\n\nimport { PanopticError } from '../errors'\nimport { createTokenIdBuilder } from '../tokenId'\nimport { MAX_TICK, MIN_TICK } from '../utils/constants'\nimport type { SfpmSwapPlan, SfpmSwapPlanParams } from './types'\n\n/** Wide, non-inverted band for the paired (non-swapping) call — never triggers a swap. */\nconst WIDE_LIMITS: [number, number] = [Number(MIN_TICK) + 1, Number(MAX_TICK) - 1]\n\n/**\n * Convert a slippage tolerance in bps to a conservative Uniswap tick distance.\n *\n * Ticks are 1.0001^tick, so each tick ≈ 1 bps. This walks up powers of 1.0001\n * until the cumulative price move covers `slippageBps`, matching the hedger-bot's\n * dispatch-path helper so both swap paths agree on band width.\n */\nexport function slippageBpsToTickDistance(slippageBps: bigint): bigint {\n if (slippageBps < 0n || slippageBps > 1000n) {\n throw new PanopticError(`slippage bps ${slippageBps} out of bounds (0..1000)`)\n }\n if (slippageBps === 0n) return 0n\n let numerator = 1n\n let denominator = 1n\n let ticks = 0n\n while (numerator * 10_000n < denominator * (10_000n + slippageBps)) {\n numerator *= 10_001n\n denominator *= 10_000n\n ticks += 1n\n }\n return ticks\n}\n\n/**\n * Build the swap plan.\n *\n * Mechanism (verified in the Phase 0 fork test):\n * - A single-leg **loan** tokenId (width=0, isLong=false, `asset == tokenType`) moves\n * exactly `positionSize` of the `tokenType` token when its call carries inverted\n * tick limits (`low > high`); the paired call uses a wide band and moves nothing.\n * - `exactIn`: swap on the **mint**; `tokenType` = the **input** token index.\n * - `exactOut`: swap on the **burn** (isLong flips → exact-output); `tokenType` = the\n * **output** token index.\n *\n * The inverted band is centered on `currentTick` at ±`slippageBpsToTickDistance`,\n * which the SFPM re-sorts and enforces as an open interval on the post-swap tick.\n */\nexport function buildSfpmSwapPlan(params: SfpmSwapPlanParams): SfpmSwapPlan {\n const { sfpmAddress, poolAddress, poolId, kind, zeroForOne, amount, currentTick, slippageBps } =\n params\n\n if (amount <= 0n) throw new PanopticError(`swap amount must be positive (got ${amount})`)\n\n const distance = slippageBpsToTickDistance(slippageBps)\n if (distance < 1n) {\n // low > high must hold strictly to trigger the swap, and the post-swap tick\n // check is an open interval — a zero-width band can never pass.\n throw new PanopticError(\n `slippageBps ${slippageBps} yields a zero-width tick band; use a larger tolerance`,\n )\n }\n\n // exactIn → tokenType = input token; exactOut → tokenType = output token.\n const tokenType = kind === 'exactIn' ? (zeroForOne ? 0n : 1n) : zeroForOne ? 1n : 0n\n\n const tokenId = createTokenIdBuilder(poolId)\n .addLoan({ asset: tokenType, tokenType, strike: 0n })\n .build()\n\n const d = Number(distance)\n // Inverted (swap-triggering) band: low > high, clamped to the valid tick range\n // so an extreme tolerance near a range extreme can't produce an unrepresentable\n // limit.\n const low = Math.min(Number(MAX_TICK), currentTick + d)\n const high = Math.max(Number(MIN_TICK), currentTick - d)\n if (low <= high) {\n throw new PanopticError(\n `slippageBps ${slippageBps} at tick ${currentTick} yields a non-inverted band after clamping`,\n )\n }\n const invertedLimits: [number, number] = [low, high]\n const swapOn: 'mint' | 'burn' = kind === 'exactIn' ? 'mint' : 'burn'\n\n return {\n sfpmAddress,\n poolAddress,\n poolKey: encodeAbiParameters([{ type: 'address' }], [poolAddress]),\n tokenId,\n positionSize: amount,\n mintTickLimits: swapOn === 'mint' ? invertedLimits : WIDE_LIMITS,\n burnTickLimits: swapOn === 'burn' ? invertedLimits : WIDE_LIMITS,\n swapOn,\n kind,\n }\n}\n","/**\n * Quote an SFPM off-venue swap by simulating the actual multicall.\n * @module v2/sfpmSwap/quote\n */\nimport { type Address, type PublicClient, type StateOverride, decodeFunctionResult } from 'viem'\n\nimport { semiFungiblePositionManagerV3Abi as sfpmV3Abi } from '../../../generated'\nimport { getBlockMeta } from '../clients'\nimport { PanopticError, parsePanopticError } from '../errors'\nimport type { SimulationResult } from '../types'\nimport { buildSfpmSwapCalldata } from './calldata'\nimport type { SfpmSwapPlan, SfpmSwapQuote } from './types'\n\nconst UINT128 = 1n << 128n\nconst INT128_MAX = (1n << 127n) - 1n\n\n/** Extract the two signed 128-bit slots from a packed `LeftRightSigned` int256. */\nfunction unpackLeftRightSigned(packed: bigint): { right: bigint; left: bigint } {\n const u = packed < 0n ? packed + (1n << 256n) : packed\n const toInt128 = (half: bigint): bigint => (half > INT128_MAX ? half - UINT128 : half)\n return {\n right: toInt128(u & (UINT128 - 1n)), // token0\n left: toInt128((u >> 128n) & (UINT128 - 1n)), // token1\n }\n}\n\n/** Wrap an unknown thrown value as a PanopticError, decoding Panoptic reverts when possible. */\nfunction toPanopticError(err: unknown): PanopticError {\n if (err instanceof PanopticError) return err\n const parsed = parsePanopticError(err)\n if (parsed) return parsed.error\n return new PanopticError(\n err instanceof Error ? err.message : 'SFPM swap simulation failed',\n err instanceof Error ? err : undefined,\n )\n}\n\nexport interface QuoteSfpmSwapParams {\n client: PublicClient\n /** Plan from {@link buildSfpmSwapPlan}. */\n plan: SfpmSwapPlan\n /** Caller executing the swap (the Safe in production); must hold the input token. */\n account: Address\n /**\n * Optional viem state overrides — e.g. to grant the input-token allowance to the\n * SFPM and/or fund the account so the quote works before approvals exist. In\n * production (Safe already approved + funded) this can be omitted.\n */\n stateOverride?: StateOverride\n blockNumber?: bigint\n}\n\n/**\n * Quote a swap by simulating `SFPM.multicall([mint, burn])` and decoding the swap\n * call's `totalMoved` return. Authoritative — captures the width-0 loan-leg wei\n * rounding a raw QuoterV2 quote would miss.\n */\nexport async function quoteSfpmSwap(\n params: QuoteSfpmSwapParams,\n): Promise<SimulationResult<SfpmSwapQuote>> {\n const { client, plan, account, stateOverride, blockNumber } = params\n const { mintData, burnData } = buildSfpmSwapCalldata(plan)\n const _meta = await getBlockMeta({ client, blockNumber })\n\n try {\n const { result } = await client.simulateContract({\n account,\n address: plan.sfpmAddress,\n abi: sfpmV3Abi,\n functionName: 'multicall',\n args: [[mintData, burnData]],\n blockNumber,\n stateOverride,\n })\n\n const swapIndex = plan.swapOn === 'mint' ? 0 : 1\n const decoded = decodeFunctionResult({\n abi: sfpmV3Abi,\n functionName: plan.swapOn === 'mint' ? 'mintTokenizedPosition' : 'burnTokenizedPosition',\n data: (result as readonly `0x${string}`[])[swapIndex],\n }) as readonly [readonly bigint[], bigint, number]\n\n const finalTick = Number(decoded[2])\n const { right, left } = unpackLeftRightSigned(decoded[1])\n const inSlot = [right, left].find((s) => s > 0n)\n const outSlot = [right, left].find((s) => s < 0n)\n if (inSlot === undefined || outSlot === undefined) {\n return {\n success: false,\n error: new PanopticError(`SFPM swap simulation moved no tokens (totalMoved=${decoded[1]})`),\n _meta,\n }\n }\n\n return {\n success: true,\n data: { amountIn: inSlot, amountOut: -outSlot, finalTick },\n gasEstimate: 0n,\n _meta,\n }\n } catch (err) {\n return { success: false, error: toPanopticError(err), _meta }\n }\n}\n","/**\n * Errors for the Uniswap v4 Universal Router swap module.\n *\n * All extend {@link PanopticError} so callers can keep a single\n * `instanceof PanopticError` check and so they satisfy `SimulationResult`'s\n * error type.\n *\n * @module uniswap/v4/router/errors\n */\n\nimport type { Address } from 'viem'\n\nimport { PanopticError } from '../../../panoptic/v2/errors'\n\n/**\n * The chain has no configured Uniswap v4 addresses and none were supplied via\n * overrides.\n */\nexport class UnsupportedChainError extends PanopticError {\n override readonly name = 'UnsupportedChainError'\n\n constructor(\n public readonly chainId: bigint,\n cause?: Error,\n ) {\n super(`Uniswap v4 router not configured for chain ${chainId}`, cause)\n }\n}\n\n/**\n * `tokenIn` is neither `currency0` nor `currency1` of the resolved pool.\n */\nexport class InvalidSwapTokenError extends PanopticError {\n override readonly name = 'InvalidSwapTokenError'\n\n constructor(\n public readonly token: Address,\n public readonly currency0: Address,\n public readonly currency1: Address,\n cause?: Error,\n ) {\n super(\n `Token ${token} is not part of the pool (currency0=${currency0}, currency1=${currency1})`,\n cause,\n )\n }\n}\n\n/**\n * An amount exceeds the uint128 range required by the v4 swap encoding.\n */\nexport class AmountExceedsUint128Error extends PanopticError {\n override readonly name = 'AmountExceedsUint128Error'\n\n constructor(\n public readonly amount: bigint,\n cause?: Error,\n ) {\n super(`Amount ${amount} exceeds uint128 maximum`, cause)\n }\n}\n\n/**\n * A native-ETH swap needs a trailing Universal Router SWEEP to deliver the ETH\n * output (or refund the input overpay), but no `recipient` was supplied.\n */\nexport class MissingSweepRecipientError extends PanopticError {\n override readonly name = 'MissingSweepRecipientError'\n\n constructor(cause?: Error) {\n super('A recipient is required to sweep native ETH back to the user', cause)\n }\n}\n\n/**\n * The V4Quoter is not available for the chain (no fallback in v1).\n */\nexport class QuoterUnavailableError extends PanopticError {\n override readonly name = 'QuoterUnavailableError'\n\n constructor(\n public readonly chainId: bigint,\n cause?: Error,\n ) {\n super(`V4Quoter unavailable for chain ${chainId}`, cause)\n }\n}\n","/**\n * Pure calldata builder for an exact-in single-hop swap through a Uniswap **v3**\n * pool via the Universal Router.\n *\n * Opcodes verified against `@uniswap/universal-router` `Commands.sol`:\n * - Universal Router command `V3_SWAP_EXACT_IN = 0x00`.\n *\n * The v3 command input is (unlike the v4 action list) a single flat tuple:\n * `(address recipient, uint256 amountIn, uint256 amountOutMinimum,\n * bytes path, bool payerIsUser)`\n * where:\n * - `recipient` is an EXPLICIT field. We encode the Universal Router sentinel\n * `MSG_SENDER = address(1)`, which the router maps to the `execute` caller —\n * so the output is delivered to the caller (e.g. a Safe) with no literal\n * address in the calldata to redirect.\n * - `path` is `abi.encodePacked(tokenIn, fee (uint24), tokenOut)` for a single\n * hop (43 bytes). The direction lives in the path ordering, not a bool.\n * - `payerIsUser = true`: the router pulls `tokenIn` from the caller via Permit2.\n *\n * ERC20-only: native ETH is intentionally unsupported here (the native paths\n * need WRAP/UNWRAP/SWEEP commands with explicit recipients).\n *\n * @module uniswap/v3/router/encodeSwap\n */\n\nimport type { Address, Hex } from 'viem'\nimport { encodeAbiParameters, encodeFunctionData, encodePacked, zeroAddress } from 'viem'\n\nimport { PanopticError } from '../../../panoptic/v2/errors'\nimport { universalRouterAbi } from '../../v4/abis/universalRouter'\nimport { AmountExceedsUint128Error } from '../../v4/router/errors'\n\n/** Universal Router command byte for a v3 exact-in swap. */\nexport const V3_SWAP_EXACT_IN = 0x00\n\n/**\n * Universal Router recipient sentinel: the router maps `address(1)` to\n * `msg.sender` (the `execute` caller). Uniswap `Constants.MSG_SENDER`.\n */\nexport const MSG_SENDER: Address = '0x0000000000000000000000000000000000000001'\n\nconst UINT128_MAX = (1n << 128n) - 1n\n\nconst v3ExactInInputAbi = [\n { name: 'recipient', type: 'address' },\n { name: 'amountIn', type: 'uint256' },\n { name: 'amountOutMinimum', type: 'uint256' },\n { name: 'path', type: 'bytes' },\n { name: 'payerIsUser', type: 'bool' },\n] as const\n\nfunction assertUint128(amount: bigint): void {\n if (amount < 0n || amount > UINT128_MAX) {\n throw new AmountExceedsUint128Error(amount)\n }\n}\n\n/** Arguments for {@link buildV3SwapExecuteCalldata}. */\nexport interface BuildV3SwapCalldataArgs {\n /** Input token (funds pulled from the caller via Permit2). */\n tokenIn: Address\n /** Output token. */\n tokenOut: Address\n /** v3 pool fee tier (e.g. 500, 3000). */\n fee: bigint\n /** Exact input amount (uint128). */\n amountIn: bigint\n /** Minimum acceptable output (uint128). */\n amountOutMinimum: bigint\n /**\n * Absolute deadline (unix seconds) — the `execute(commands, inputs, deadline)`\n * argument, enforced by the Universal Router.\n */\n deadline: bigint\n}\n\n/**\n * Encode the packed v3 single-hop path `tokenIn ++ fee(uint24) ++ tokenOut`.\n */\nexport function encodeV3Path(tokenIn: Address, fee: bigint, tokenOut: Address): Hex {\n if (fee < 0n || fee > 0xffffffn) {\n throw new PanopticError(`v3 fee ${fee} exceeds uint24`)\n }\n return encodePacked(['address', 'uint24', 'address'], [tokenIn, Number(fee), tokenOut])\n}\n\n/**\n * Build the typed `execute(...)` args for an exact-in single-hop v3 swap whose\n * output is delivered to the `execute` caller (recipient = MSG_SENDER).\n */\nexport function buildV3SwapExecuteArgs(args: BuildV3SwapCalldataArgs): {\n args: readonly [Hex, readonly Hex[], bigint]\n value: bigint\n} {\n const { tokenIn, tokenOut, fee, amountIn, amountOutMinimum, deadline } = args\n\n if (tokenIn === zeroAddress || tokenOut === zeroAddress) {\n throw new PanopticError('native ETH is not supported by the v3 exact-in router builder')\n }\n assertUint128(amountIn)\n assertUint128(amountOutMinimum)\n\n const path = encodeV3Path(tokenIn, fee, tokenOut)\n const input = encodeAbiParameters(v3ExactInInputAbi, [\n MSG_SENDER,\n amountIn,\n amountOutMinimum,\n path,\n true, // payerIsUser: pull tokenIn from the caller via Permit2\n ])\n\n const commands = encodePacked(['uint8'], [V3_SWAP_EXACT_IN])\n return { args: [commands, [input], deadline] as const, value: 0n }\n}\n\n/**\n * Build the `execute(commands, inputs, deadline)` calldata for an exact-in\n * single-hop v3 swap.\n */\nexport function buildV3SwapExecuteCalldata(args: BuildV3SwapCalldataArgs): {\n data: Hex\n value: bigint\n} {\n const { args: executeArgs, value } = buildV3SwapExecuteArgs(args)\n const data = encodeFunctionData({\n abi: universalRouterAbi,\n functionName: 'execute',\n args: executeArgs,\n })\n return { data, value }\n}\n","/**\n * Minimal Uniswap v3 QuoterV2 ABI (`quoteExactInputSingle`).\n *\n * QuoterV2 is revert/staticcall-based (nonpayable but intended for `eth_call` /\n * `simulateContract`), so it must be simulated, not read.\n * @module uniswap/v3/abis/quoterV2\n */\n\nexport const quoterV2Abi = [\n {\n type: 'function',\n name: 'quoteExactInputSingle',\n stateMutability: 'nonpayable',\n inputs: [\n {\n name: 'params',\n type: 'tuple',\n components: [\n { name: 'tokenIn', type: 'address' },\n { name: 'tokenOut', type: 'address' },\n { name: 'amountIn', type: 'uint256' },\n { name: 'fee', type: 'uint24' },\n { name: 'sqrtPriceLimitX96', type: 'uint160' },\n ],\n },\n ],\n outputs: [\n { name: 'amountOut', type: 'uint256' },\n { name: 'sqrtPriceX96After', type: 'uint160' },\n { name: 'initializedTicksCrossed', type: 'uint32' },\n { name: 'gasEstimate', type: 'uint256' },\n ],\n },\n] as const\n","/**\n * Per-chain Uniswap v3 addresses needed for spot quoting via the Universal\n * Router. The Universal Router itself is shared with v4 (see\n * `uniswap/v4/addresses`); only the v3 QuoterV2 is specific to v3.\n *\n * v1 supports mainnet only; other chains throw {@link UnsupportedChainError}\n * unless the address is supplied via overrides (fork tests / new chains).\n *\n * @module uniswap/v3/addresses\n */\n\nimport type { Address } from 'viem'\n\nimport { UnsupportedChainError } from '../v4/router/errors'\n\nexport interface UniswapV3Addresses {\n /** Uniswap v3 QuoterV2 — `quoteExactInputSingle` (revert/staticcall-based). */\n quoterV2: Address\n /** Uniswap v3 NonfungiblePositionManager — ERC721 LP position NFTs. */\n nonfungiblePositionManager: Address\n}\n\n/**\n * Verified Uniswap v3 QuoterV2 addresses keyed by chainId. Add a chain only\n * after verifying against the canonical Uniswap v3 deployment listing.\n */\nexport const UNISWAP_V3_ADDRESSES: Record<number, UniswapV3Addresses> = {\n // Ethereum mainnet\n 1: {\n quoterV2: '0x61fFE014bA17989E743c5F6cB21bF9697530B21e',\n nonfungiblePositionManager: '0xC36442b4a4522E871399CD717aBDD847Ab11FE88',\n },\n}\n\n/**\n * Resolve Uniswap v3 addresses for a chain, applying optional overrides.\n *\n * @throws {UnsupportedChainError} when the chain is not listed and overrides do\n * not supply every required address.\n */\nexport function getUniswapV3Addresses(\n chainId: number | bigint,\n overrides?: Partial<UniswapV3Addresses>,\n): UniswapV3Addresses {\n const id = Number(chainId)\n const base = UNISWAP_V3_ADDRESSES[id]\n const merged = { ...base, ...overrides }\n if (!merged.quoterV2 || !merged.nonfungiblePositionManager) {\n throw new UnsupportedChainError(BigInt(id))\n }\n return merged as UniswapV3Addresses\n}\n","/**\n * Quote an exact-in single-hop swap against a Uniswap v3 pool via QuoterV2.\n * @module uniswap/v3/router/quote\n */\n\nimport type { Address, PublicClient } from 'viem'\nimport { BaseError, ContractFunctionRevertedError } from 'viem'\n\nimport { PanopticError } from '../../../panoptic/v2/errors'\nimport { quoterV2Abi } from '../abis/quoterV2'\nimport { type UniswapV3Addresses, getUniswapV3Addresses } from '../addresses'\n\nconst BPS_DENOMINATOR = 10_000n\nconst UINT128_MAX = (1n << 128n) - 1n\n\nexport interface QuoteV3ExactInParams {\n client: PublicClient\n chainId: bigint\n tokenIn: Address\n tokenOut: Address\n fee: bigint\n amountIn: bigint\n /** Slippage tolerance in bps, used to compute `amountOutMinimum`. */\n slippageBps: bigint\n blockNumber?: bigint\n addresses?: Partial<UniswapV3Addresses>\n}\n\nexport interface V3ExactInQuote {\n amountOut: bigint\n amountOutMinimum: bigint\n gasEstimate: bigint\n}\n\n/**\n * Quote an exact-in v3 swap. Returns `null` when the quote reverts (e.g. the\n * pool does not exist / has no liquidity) so callers can skip that pool when\n * ranking venues, rather than aborting the whole cycle.\n */\nexport async function quoteV3ExactIn(params: QuoteV3ExactInParams): Promise<V3ExactInQuote | null> {\n const { client, chainId, tokenIn, tokenOut, fee, amountIn, slippageBps, blockNumber } = params\n if (amountIn < 0n || amountIn > UINT128_MAX) {\n throw new PanopticError(`amountIn ${amountIn} exceeds uint128 maximum`)\n }\n if (slippageBps < 0n || slippageBps > BPS_DENOMINATOR) {\n throw new PanopticError(`invalid slippageBps ${slippageBps}, must be 0..10000`)\n }\n\n const { quoterV2 } = getUniswapV3Addresses(chainId, params.addresses)\n\n try {\n const { result } = await client.simulateContract({\n address: quoterV2,\n abi: quoterV2Abi,\n functionName: 'quoteExactInputSingle',\n blockNumber,\n args: [{ tokenIn, tokenOut, amountIn, fee: Number(fee), sqrtPriceLimitX96: 0n }],\n })\n const [amountOut, , , gasEstimate] = result\n const amountOutMinimum = (amountOut * (BPS_DENOMINATOR - slippageBps)) / BPS_DENOMINATOR\n return { amountOut, amountOutMinimum, gasEstimate }\n } catch (err) {\n if (isRevert(err)) return null\n // Transport/RPC/timeout errors are NOT \"no liquidity\" — rethrow so routing\n // doesn't silently treat an unreachable node as an empty pool.\n throw err\n }\n}\n\n/** True only for genuine contract reverts (missing pool / no liquidity). */\nfunction isRevert(err: unknown): boolean {\n return (\n err instanceof BaseError &&\n err.walk((e) => e instanceof ContractFunctionRevertedError) instanceof\n ContractFunctionRevertedError\n )\n}\n","/**\n * SFPM read functions — poolId resolution, enforced tick limits, chunk liquidity.\n *\n * @module v2/reads/sfpm\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport {\n semiFungiblePositionManagerV3Abi,\n semiFungiblePositionManagerV4Abi,\n} from '../../../generated'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport { ChunkLimitError } from '../errors'\nimport type { BlockMeta, PoolKey } from '../types'\nimport { MAX_TRACKED_CHUNKS } from '../utils/constants'\n\n// ---------------------------------------------------------------------------\n// getUniswapV3PoolFromId\n// ---------------------------------------------------------------------------\n\n/**\n * Parameters for {@link getUniswapV3PoolFromId}.\n */\nexport interface GetUniswapV3PoolFromIdParams {\n /** Public client */\n client: PublicClient\n /** SemiFungiblePositionManagerV3 address */\n sfpmAddress: Address\n /** The SFPM pool identifier (uint64) */\n poolId: bigint\n}\n\n/**\n * Resolve an SFPM poolId to its corresponding Uniswap V3 pool address.\n *\n * Calls `SemiFungiblePositionManagerV3.getUniswapV3PoolFromId(poolId)`.\n */\nexport async function getUniswapV3PoolFromId(\n params: GetUniswapV3PoolFromIdParams,\n): Promise<Address> {\n const { client, sfpmAddress, poolId } = params\n return client.readContract({\n address: sfpmAddress,\n abi: semiFungiblePositionManagerV3Abi,\n functionName: 'getUniswapV3PoolFromId',\n args: [poolId],\n })\n}\n\n// ---------------------------------------------------------------------------\n// getUniswapV4PoolKeyFromId\n// ---------------------------------------------------------------------------\n\n/**\n * Parameters for {@link getUniswapV4PoolKeyFromId}.\n */\nexport interface GetUniswapV4PoolKeyFromIdParams {\n /** Public client */\n client: PublicClient\n /** SemiFungiblePositionManagerV4 address */\n sfpmAddress: Address\n /** The SFPM pool identifier (uint64) */\n poolId: bigint\n}\n\n/**\n * Resolve an SFPM poolId to its corresponding Uniswap V4 pool key.\n *\n * Calls `SemiFungiblePositionManagerV4.getUniswapV4PoolKeyFromId(poolId)`.\n */\nexport async function getUniswapV4PoolKeyFromId(\n params: GetUniswapV4PoolKeyFromIdParams,\n): Promise<PoolKey> {\n const { client, sfpmAddress, poolId } = params\n const raw = await client.readContract({\n address: sfpmAddress,\n abi: semiFungiblePositionManagerV4Abi,\n functionName: 'getUniswapV4PoolKeyFromId',\n args: [poolId],\n })\n return {\n currency0: raw.currency0,\n currency1: raw.currency1,\n fee: BigInt(raw.fee),\n tickSpacing: BigInt(raw.tickSpacing),\n hooks: raw.hooks,\n }\n}\n\n// ---------------------------------------------------------------------------\n// getEnforcedTickLimits\n// ---------------------------------------------------------------------------\n\n/**\n * Parameters for getEnforcedTickLimits.\n */\nexport interface GetEnforcedTickLimitsParams {\n /** viem PublicClient */\n client: PublicClient\n /** SFPM address (from getPool().metadata.sfpmAddress) */\n sfpmAddress: Address\n /** Encoded pool ID (from getPool().poolId) */\n poolId: bigint\n}\n\n/**\n * Result from getEnforcedTickLimits.\n */\nexport interface EnforcedTickLimits {\n minEnforcedTick: number\n maxEnforcedTick: number\n}\n\n/**\n * Get the enforced tick limits for a pool from the SFPM.\n *\n * @param params - The parameters\n * @returns The min and max enforced ticks\n */\nexport async function getEnforcedTickLimits(\n params: GetEnforcedTickLimitsParams,\n): Promise<EnforcedTickLimits> {\n const { client, sfpmAddress, poolId } = params\n\n const [minTick, maxTick] = await client.readContract({\n address: sfpmAddress,\n abi: semiFungiblePositionManagerV4Abi,\n functionName: 'getEnforcedTickLimits',\n args: [poolId],\n })\n\n return {\n minEnforcedTick: minTick,\n maxEnforcedTick: maxTick,\n }\n}\n\n// ---------------------------------------------------------------------------\n// getChunkLiquidities\n// ---------------------------------------------------------------------------\n\nexport interface ChunkInput {\n /** Owner address (panopticPool address for Panoptic chunks) */\n owner: Address\n /** 0 or 1 */\n tokenType: bigint\n tickLower: bigint\n tickUpper: bigint\n}\n\nexport interface ChunkLiquidityResult {\n /** Liquidity currently deployed in Uniswap */\n netLiquidity: bigint\n /** Liquidity removed by long holders */\n removedLiquidity: bigint\n /** Total liquidity deposited by shorts (net + removed) */\n totalLiquidity: bigint\n /** Alias for totalLiquidity (shorts deposited all of it) */\n shortLiquidity: bigint\n /** Alias for removedLiquidity (longs removed this much) */\n longLiquidity: bigint\n}\n\nexport interface GetChunkLiquiditiesParams {\n client: PublicClient\n /** SFPM address */\n sfpmAddress: Address\n /** Pool key bytes (from getPool().metadata.poolKeyBytes) */\n poolKeyBytes: `0x${string}`\n /** Chunks to query */\n chunks: ChunkInput[]\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\nexport interface GetChunkLiquiditiesResult {\n /** One result per input chunk */\n results: ChunkLiquidityResult[]\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Fetch liquidity breakdown for a batch of chunks via SFPM.getAccountLiquidity().\n *\n * Uses multicall for efficiency. Returns one result per input chunk,\n * along with block metadata for freshness tracking.\n */\nexport async function getChunkLiquidities(\n params: GetChunkLiquiditiesParams,\n): Promise<GetChunkLiquiditiesResult> {\n const { client, sfpmAddress, poolKeyBytes, chunks } = params\n\n if (chunks.length > MAX_TRACKED_CHUNKS) {\n throw new ChunkLimitError(BigInt(chunks.length), 0n)\n }\n\n const _meta = params._meta ?? (await getBlockMeta({ client }))\n\n if (chunks.length === 0) return { results: [], _meta }\n\n // Batch all getAccountLiquidity calls\n const multicallResults = await client.multicall({\n contracts: chunks.map((chunk) => ({\n address: sfpmAddress,\n abi: semiFungiblePositionManagerV4Abi,\n functionName: 'getAccountLiquidity' as const,\n args: [\n poolKeyBytes,\n chunk.owner,\n chunk.tokenType,\n Number(chunk.tickLower),\n Number(chunk.tickUpper),\n ],\n })),\n allowFailure: true,\n })\n\n const results = multicallResults.map((result) => {\n if (result.status === 'failure') {\n return {\n netLiquidity: 0n,\n removedLiquidity: 0n,\n totalLiquidity: 0n,\n shortLiquidity: 0n,\n longLiquidity: 0n,\n }\n }\n\n const packed = result.result as bigint\n // LeftRightUnsigned: right 128 bits = netLiquidity, left 128 bits = removedLiquidity\n const netLiquidity = packed & ((1n << 128n) - 1n)\n const removedLiquidity = packed >> 128n\n const totalLiquidity = netLiquidity + removedLiquidity\n\n return {\n netLiquidity,\n removedLiquidity,\n totalLiquidity,\n shortLiquidity: totalLiquidity,\n longLiquidity: removedLiquidity,\n }\n })\n\n return { results, _meta }\n}\n","/**\n * Factory read functions for the Panoptic v2 SDK.\n *\n * Supports both PanopticFactoryV3 (Uniswap V3) and PanopticFactoryV4 (Uniswap V4).\n *\n * @module v2/reads/factory\n */\n\nimport type { Address, PublicClient } from 'viem'\nimport { zeroAddress } from 'viem'\n\nimport { panopticFactoryV3Abi, panopticFactoryV4Abi } from '../../../generated'\nimport type { PoolKey } from '../types'\nimport { getUniswapV3PoolFromId, getUniswapV4PoolKeyFromId } from './sfpm'\n\n// ---------------------------------------------------------------------------\n// Shared reads (identical signature on both V3 and V4)\n// ---------------------------------------------------------------------------\n\n/**\n * Parameters for getFactoryTokenURI.\n */\nexport interface GetFactoryTokenURIParams {\n /** Public client */\n client: PublicClient\n /** PanopticFactory address */\n factoryAddress: Address\n /** Factory version */\n version: 'v3' | 'v4'\n /** Token ID (encoded pool address) */\n tokenId: bigint\n}\n\n/**\n * Get the token URI from a PanopticFactory NFT.\n */\nexport async function getFactoryTokenURI(params: GetFactoryTokenURIParams): Promise<string> {\n const { client, factoryAddress, version, tokenId } = params\n const abi = version === 'v3' ? panopticFactoryV3Abi : panopticFactoryV4Abi\n\n return client.readContract({\n address: factoryAddress,\n abi,\n functionName: 'tokenURI',\n args: [tokenId],\n })\n}\n\n/**\n * Parameters for getFactoryOwnerOf.\n */\nexport interface GetFactoryOwnerOfParams {\n /** Public client */\n client: PublicClient\n /** PanopticFactory address */\n factoryAddress: Address\n /** Factory version */\n version: 'v3' | 'v4'\n /** Token ID (encoded pool address) */\n tokenId: bigint\n}\n\n/**\n * Get the owner of a PanopticFactory NFT.\n */\nexport async function getFactoryOwnerOf(params: GetFactoryOwnerOfParams): Promise<Address> {\n const { client, factoryAddress, version, tokenId } = params\n const abi = version === 'v3' ? panopticFactoryV3Abi : panopticFactoryV4Abi\n\n return client.readContract({\n address: factoryAddress,\n abi,\n functionName: 'ownerOf',\n args: [tokenId],\n })\n}\n\n/**\n * Parameters for getFactoryConstructMetadata.\n */\nexport interface GetFactoryConstructMetadataParams {\n /** Public client */\n client: PublicClient\n /** PanopticFactory address */\n factoryAddress: Address\n /** Factory version */\n version: 'v3' | 'v4'\n /** PanopticPool address (or predicted address) */\n panopticPoolAddress: Address\n /** Token 0 symbol */\n symbol0: string\n /** Token 1 symbol */\n symbol1: string\n /** Fee tier */\n fee: bigint\n}\n\n/**\n * Construct NFT metadata for a pool via the factory contract.\n */\nexport async function getFactoryConstructMetadata(\n params: GetFactoryConstructMetadataParams,\n): Promise<string> {\n const { client, factoryAddress, version, panopticPoolAddress, symbol0, symbol1, fee } = params\n const abi = version === 'v3' ? panopticFactoryV3Abi : panopticFactoryV4Abi\n\n return client.readContract({\n address: factoryAddress,\n abi,\n functionName: 'constructMetadata',\n args: [panopticPoolAddress, symbol0, symbol1, fee],\n })\n}\n\n// ---------------------------------------------------------------------------\n// V3-specific reads\n// ---------------------------------------------------------------------------\n\n/**\n * Parameters for getPanopticPoolAddress on a V3 factory.\n */\nexport interface GetPanopticPoolAddressV3Params {\n /** Public client */\n client: PublicClient\n /** PanopticFactoryV3 address */\n factoryAddress: Address\n /** Uniswap V3 pool address */\n univ3pool: Address\n /** Risk engine address */\n riskEngine: Address\n}\n\n/**\n * Parameters for getPanopticPoolAddress on a V4 factory.\n */\nexport interface GetPanopticPoolAddressV4Params {\n /** Public client */\n client: PublicClient\n /** PanopticFactoryV4 address */\n factoryAddress: Address\n /** V4 pool key */\n poolKey: PoolKey\n /** Risk engine address */\n riskEngine: Address\n}\n\n/** Versioned params for {@link getPanopticPoolAddress}. Use `version` to select V3 or V4. */\nexport type GetPanopticPoolAddressParams =\n | ({ version: 'v3' } & GetPanopticPoolAddressV3Params)\n | ({ version: 'v4' } & GetPanopticPoolAddressV4Params)\n\n/**\n * Get the PanopticPool address for a given pool and risk engine.\n */\nexport async function getPanopticPoolAddress(\n params: GetPanopticPoolAddressParams,\n): Promise<Address> {\n const { client, factoryAddress, riskEngine } = params\n\n if (params.version === 'v3') {\n return client.readContract({\n address: factoryAddress,\n abi: panopticFactoryV3Abi,\n functionName: 'getPanopticPool',\n args: [params.univ3pool, riskEngine],\n })\n }\n\n return client.readContract({\n address: factoryAddress,\n abi: panopticFactoryV4Abi,\n functionName: 'getPanopticPool',\n args: [\n {\n currency0: params.poolKey.currency0,\n currency1: params.poolKey.currency1,\n fee: Number(params.poolKey.fee),\n tickSpacing: Number(params.poolKey.tickSpacing),\n hooks: params.poolKey.hooks,\n },\n riskEngine,\n ],\n })\n}\n\n// ---------------------------------------------------------------------------\n// minePoolAddress\n// ---------------------------------------------------------------------------\n\n/**\n * Common mining parameters shared between V3 and V4.\n */\ninterface MinePoolAddressCommon {\n /** Public client */\n client: PublicClient\n /** PanopticFactory address */\n factoryAddress: Address\n /** Deployer address (msg.sender for deployment) */\n deployerAddress: Address\n /** Risk engine address */\n riskEngine: Address\n /** Starting salt (uint96) */\n salt: bigint\n /** Number of mining iterations */\n loops: bigint\n /** Minimum rarity target */\n minTargetRarity: bigint\n}\n\nexport interface MinePoolAddressV3Params extends MinePoolAddressCommon {\n /** Uniswap V3 pool address */\n v3Pool: Address\n}\n\nexport interface MinePoolAddressV4Params extends MinePoolAddressCommon {\n /** V4 pool key */\n poolKey: PoolKey\n}\n\n/** Versioned params for {@link minePoolAddress}. Use `version` to select V3 or V4. */\nexport type MinePoolAddressParams =\n | ({ version: 'v3' } & MinePoolAddressV3Params)\n | ({ version: 'v4' } & MinePoolAddressV4Params)\n\n/**\n * Result of pool address mining.\n */\nexport interface MinePoolAddressResult {\n /** Best salt found */\n bestSalt: bigint\n /** Highest rarity achieved */\n highestRarity: bigint\n}\n\n/**\n * Mine for an optimal pool address salt with high rarity.\n */\nexport async function minePoolAddress(\n params: MinePoolAddressParams,\n): Promise<MinePoolAddressResult> {\n const { client, factoryAddress, deployerAddress, riskEngine, salt, loops, minTargetRarity } =\n params\n\n let result: readonly [bigint, bigint]\n\n if (params.version === 'v3') {\n result = await client.readContract({\n address: factoryAddress,\n abi: panopticFactoryV3Abi,\n functionName: 'minePoolAddress',\n args: [deployerAddress, params.v3Pool, riskEngine, salt, loops, minTargetRarity],\n })\n } else {\n result = await client.readContract({\n address: factoryAddress,\n abi: panopticFactoryV4Abi,\n functionName: 'minePoolAddress',\n args: [\n deployerAddress,\n {\n currency0: params.poolKey.currency0,\n currency1: params.poolKey.currency1,\n fee: Number(params.poolKey.fee),\n tickSpacing: Number(params.poolKey.tickSpacing),\n hooks: params.poolKey.hooks,\n },\n riskEngine,\n salt,\n loops,\n minTargetRarity,\n ],\n })\n }\n\n return { bestSalt: BigInt(result[0]), highestRarity: result[1] }\n}\n\n// ---------------------------------------------------------------------------\n// simulateDeployNewPool\n// ---------------------------------------------------------------------------\n\ninterface SimulateDeployNewPoolCommon {\n /** Public client */\n client: PublicClient\n /** PanopticFactory address */\n factoryAddress: Address\n /** Account address (deployer) */\n account: Address\n /** Risk engine address */\n riskEngine: Address\n /** Salt (uint96) */\n salt: bigint\n}\n\nexport interface SimulateDeployNewPoolV3Params extends SimulateDeployNewPoolCommon {\n /** Token 0 address */\n token0: Address\n /** Token 1 address */\n token1: Address\n /** Fee tier (uint24) */\n fee: bigint\n}\n\nexport interface SimulateDeployNewPoolV4Params extends SimulateDeployNewPoolCommon {\n /** V4 pool key */\n poolKey: PoolKey\n}\n\nexport type SimulateDeployNewPoolParams =\n | ({ version: 'v3' } & SimulateDeployNewPoolV3Params)\n | ({ version: 'v4' } & SimulateDeployNewPoolV4Params)\n\n/**\n * Simulate a pool deployment to get the predicted pool address.\n *\n * Uses `simulateContract` on `deployNewPool` — the return value is the new pool address\n * without actually executing the transaction.\n */\nexport async function simulateDeployNewPool(params: SimulateDeployNewPoolParams): Promise<Address> {\n const { client, factoryAddress, account, riskEngine, salt } = params\n\n if (params.version === 'v3') {\n const { result } = await client.simulateContract({\n address: factoryAddress,\n abi: panopticFactoryV3Abi,\n functionName: 'deployNewPool',\n args: [params.token0, params.token1, Number(params.fee), riskEngine, salt],\n account,\n })\n return result\n }\n\n const { result } = await client.simulateContract({\n address: factoryAddress,\n abi: panopticFactoryV4Abi,\n functionName: 'deployNewPool',\n args: [\n {\n currency0: params.poolKey.currency0,\n currency1: params.poolKey.currency1,\n fee: Number(params.poolKey.fee),\n tickSpacing: Number(params.poolKey.tickSpacing),\n hooks: params.poolKey.hooks,\n },\n riskEngine,\n salt,\n ],\n account,\n })\n return result\n}\n\n// ---------------------------------------------------------------------------\n// getPanopticPoolFromPoolId\n// ---------------------------------------------------------------------------\n\n/**\n * Common parameters for {@link getPanopticPoolFromPoolId}.\n */\ninterface GetPanopticPoolFromPoolIdCommon {\n /** Public client */\n client: PublicClient\n /** SFPM address */\n sfpmAddress: Address\n /** PanopticFactory address */\n factoryAddress: Address\n /** Risk engine address */\n riskEngine: Address\n /** The SFPM pool identifier (uint64) */\n poolId: bigint\n}\n\n/** Versioned params for {@link getPanopticPoolFromPoolId}. */\nexport type GetPanopticPoolFromPoolIdParams =\n | ({ version: 'v3' } & GetPanopticPoolFromPoolIdCommon)\n | ({ version: 'v4' } & GetPanopticPoolFromPoolIdCommon)\n\n/**\n * Resolve an SFPM poolId to its PanopticPool address.\n *\n * Chains two on-chain lookups:\n * 1. SFPM: poolId → Uniswap pool address (V3) or pool key (V4)\n * 2. Factory: Uniswap pool + riskEngine → PanopticPool address\n */\nexport async function getPanopticPoolFromPoolId(\n params: GetPanopticPoolFromPoolIdParams,\n): Promise<Address> {\n const { client, sfpmAddress, factoryAddress, riskEngine, poolId, version } = params\n\n if (version === 'v3') {\n const univ3pool = await getUniswapV3PoolFromId({ client, sfpmAddress, poolId })\n return getPanopticPoolAddress({\n version: 'v3',\n client,\n factoryAddress,\n univ3pool,\n riskEngine,\n })\n }\n\n const poolKey = await getUniswapV4PoolKeyFromId({ client, sfpmAddress, poolId })\n return getPanopticPoolAddress({\n version: 'v4',\n client,\n factoryAddress,\n poolKey,\n riskEngine,\n })\n}\n\n// ---------------------------------------------------------------------------\n// resolvePanopticPoolFromPoolId (version-agnostic)\n// ---------------------------------------------------------------------------\n\n/**\n * Parameters for {@link resolvePanopticPoolFromPoolId}.\n */\nexport interface ResolvePanopticPoolFromPoolIdParams {\n /** Public client */\n client: PublicClient\n /** The SFPM pool identifier (uint64) */\n poolId: bigint\n /** Risk engine address */\n riskEngine: Address\n /** V3 SFPM + Factory addresses (omit if V3 is not deployed) */\n v3?: {\n sfpmAddress: Address\n factoryAddress: Address\n }\n /** V4 SFPM + Factory addresses (omit if V4 is not deployed) */\n v4?: {\n sfpmAddress: Address\n factoryAddress: Address\n }\n}\n\n/**\n * Result of {@link resolvePanopticPoolFromPoolId}.\n */\nexport interface ResolvePanopticPoolFromPoolIdResult {\n /** The resolved PanopticPool address */\n panopticPoolAddress: Address\n /** Which version matched */\n version: 'v3' | 'v4'\n}\n\n/**\n * Resolve an SFPM poolId to its PanopticPool address without knowing the version.\n *\n * Tries both V3 and V4 lookups in parallel. The factory returns `address(0)` for\n * non-existent pools, so the non-zero result identifies the correct version.\n *\n * At least one of `v3` or `v4` must be provided.\n *\n * @throws {PanopticValidationError} If no version config is provided or neither resolves.\n */\nexport async function resolvePanopticPoolFromPoolId(\n params: ResolvePanopticPoolFromPoolIdParams,\n): Promise<ResolvePanopticPoolFromPoolIdResult> {\n const { client, poolId, riskEngine, v3, v4 } = params\n\n if (!v3 && !v4) {\n throw new Error('At least one of v3 or v4 must be provided')\n }\n\n const isNotFoundError = (err: unknown): boolean => {\n // Contract reverts (e.g. pool not registered) are \"not found\".\n // RPC / ABI / network errors should propagate.\n if (typeof err === 'object' && err !== null && 'name' in err) {\n const name = (err as { name: string }).name\n return name === 'ContractFunctionExecutionError' || name === 'ContractFunctionRevertedError'\n }\n return false\n }\n\n const results = await Promise.all([\n v3\n ? getPanopticPoolFromPoolId({\n version: 'v3',\n client,\n sfpmAddress: v3.sfpmAddress,\n factoryAddress: v3.factoryAddress,\n riskEngine,\n poolId,\n }).catch((err) => {\n if (isNotFoundError(err)) return zeroAddress\n throw err\n })\n : Promise.resolve(zeroAddress),\n v4\n ? getPanopticPoolFromPoolId({\n version: 'v4',\n client,\n sfpmAddress: v4.sfpmAddress,\n factoryAddress: v4.factoryAddress,\n riskEngine,\n poolId,\n }).catch((err) => {\n if (isNotFoundError(err)) return zeroAddress\n throw err\n })\n : Promise.resolve(zeroAddress),\n ])\n\n const [v3Result, v4Result] = results\n\n if (v3Result !== zeroAddress) {\n return { panopticPoolAddress: v3Result, version: 'v3' }\n }\n if (v4Result !== zeroAddress) {\n return { panopticPoolAddress: v4Result, version: 'v4' }\n }\n\n throw new Error(`No PanopticPool found for poolId ${poolId}`)\n}\n","/**\n * Client-side (off-chain) implementation of minePoolAddress.\n *\n * Replicates the on-chain PanopticFactory mining loop entirely in TypeScript,\n * eliminating RPC round-trips. The result is identical to the on-chain computation.\n *\n * Algorithm:\n * For each candidate salt (uint96):\n * 1. Pack a bytes32 salt from deployer, pool identifier, riskEngine, and iteration salt\n * 2. Predict the CREATE3 deployed address (via proxy)\n * 3. Score by leading hex zeros (\"rarity\")\n * 4. Track the best salt; stop early if minTargetRarity is reached\n *\n * @module v2/reads/minePoolAddressLocal\n */\n\nimport type { Address, Hex } from 'viem'\nimport { encodeAbiParameters, keccak256 } from 'viem'\n\nimport { PanopticValidationError } from '../errors'\nimport type { PoolKey } from '../types'\nimport type {\n MinePoolAddressResult,\n MinePoolAddressV3Params,\n MinePoolAddressV4Params,\n} from './factory'\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Mining params for PanopticFactoryV3 — no RPC client needed. */\nexport type MinePoolAddressLocalV3Params = Omit<MinePoolAddressV3Params, 'client'>\n\n/** Mining params for PanopticFactoryV4 — no RPC client needed. */\nexport type MinePoolAddressLocalV4Params = Omit<MinePoolAddressV4Params, 'client'>\n\nexport type MinePoolAddressLocalParams =\n | ({ version: 'v3' } & MinePoolAddressLocalV3Params)\n | ({ version: 'v4' } & MinePoolAddressLocalV4Params)\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/**\n * keccak256 of the CREATE3 proxy initcode used by ClonesWithImmutableArgs.\n * Source: packages/panoptic-v2-core/lib/clones-with-immutable-args/src/ClonesWithImmutableArgs.sol\n */\nconst CREATE3_PROXY_BYTECODE_HASH =\n '0x21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f' as Hex\n\nconst MASK_80 = (1n << 80n) - 1n\nconst MASK_40 = (1n << 40n) - 1n\nconst MASK_96 = (1n << 96n) - 1n\n\n// ---------------------------------------------------------------------------\n// Private helpers\n// ---------------------------------------------------------------------------\n\n/** Encode a BigInt as a big-endian fixed-length byte array. */\nfunction bigintToBytes(value: bigint, byteLength: number): Uint8Array {\n const bytes = new Uint8Array(byteLength)\n let v = value\n for (let i = byteLength - 1; i >= 0; i--) {\n bytes[i] = Number(v & 0xffn)\n v >>= 8n\n }\n return bytes\n}\n\n/** Parse a 0x-prefixed address into 20 bytes. */\nfunction addressToBytes(addr: Address): Uint8Array {\n const hex = addr.slice(2).padStart(40, '0')\n const bytes = new Uint8Array(20)\n for (let i = 0; i < 20; i++) {\n bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16)\n }\n return bytes\n}\n\n/** Parse a 0x-prefixed 32-byte hex string into bytes. */\nfunction hex32ToBytes(hex: Hex): Uint8Array {\n const h = hex.slice(2).padStart(64, '0')\n const bytes = new Uint8Array(32)\n for (let i = 0; i < 32; i++) {\n bytes[i] = parseInt(h.slice(i * 2, i * 2 + 2), 16)\n }\n return bytes\n}\n\n/**\n * Compute the CREATE3 deployed address for a given factory and packed salt.\n *\n * Mirrors `ClonesWithImmutableArgs.addressOfClone3(salt)` (with `address(this)` = factory):\n * proxy = CREATE2(factory, salt, PROXY_BYTECODE_HASH)\n * deployed = CREATE1(proxy, nonce=1)\n *\n * Returns the deployed address as a uint160 BigInt.\n */\nfunction addressOfClone3(factory: Address, salt: bigint): bigint {\n const saltBytes = bigintToBytes(salt, 32)\n\n // CREATE2: keccak256(0xff ++ factory ++ salt ++ proxyBytecodeHash) — 85 bytes total\n const create2Input = new Uint8Array(85)\n create2Input[0] = 0xff\n create2Input.set(addressToBytes(factory), 1) // bytes 1–20\n create2Input.set(saltBytes, 21) // bytes 21–52\n create2Input.set(hex32ToBytes(CREATE3_PROXY_BYTECODE_HASH), 53) // bytes 53–84\n\n const proxyHash = keccak256(create2Input, 'bytes')\n const proxyAddress = proxyHash.slice(12) // rightmost 20 bytes\n\n // CREATE1 nonce=1: keccak256(0xd694 ++ proxy ++ 0x01) — 23 bytes total\n const create1Input = new Uint8Array(23)\n create1Input[0] = 0xd6\n create1Input[1] = 0x94\n create1Input.set(proxyAddress, 2) // bytes 2–21\n create1Input[22] = 0x01\n\n const deployedHash = keccak256(create1Input, 'bytes')\n\n // Convert rightmost 20 bytes to uint160 BigInt\n let addr = 0n\n for (let i = 12; i < 32; i++) {\n addr = (addr << 8n) | BigInt(deployedHash[i])\n }\n return addr\n}\n\n/**\n * Count leading hex-zero characters in a 160-bit address value.\n *\n * Mirrors `PanopticMath.numberOfLeadingHexZeros(addr)`.\n * Returns 40 for the zero address.\n */\nexport function numberOfLeadingHexZeros(addrInt: bigint): number {\n if (addrInt === 0n) return 40\n let x = addrInt\n let r = 0\n if (x >= 0x100000000000000000000000000000000n) {\n x >>= 128n\n r += 32\n }\n if (x >= 0x10000000000000000n) {\n x >>= 64n\n r += 16\n }\n if (x >= 0x100000000n) {\n x >>= 32n\n r += 8\n }\n if (x >= 0x10000n) {\n x >>= 16n\n r += 4\n }\n if (x >= 0x100n) {\n x >>= 8n\n r += 2\n }\n if (x >= 0x10n) {\n r += 1\n }\n return 39 - r\n}\n\n/**\n * Construct the bytes32 CREATE3 salt for PanopticFactoryV3.\n *\n * Mirrors:\n * bytes32(abi.encodePacked(\n * uint80(uint160(deployerAddress) >> 80), // bits [159:80] of deployer → 10 bytes\n * uint40(uint160(v3Pool) >> 120), // bits [159:120] of v3Pool → 5 bytes\n * uint40(uint160(riskEngine) >> 120), // bits [159:120] of riskEngine→ 5 bytes\n * salt // uint96 → 12 bytes\n * ))\n */\nfunction computeSaltPrefixV3(\n deployerAddress: Address,\n v3Pool: Address,\n riskEngine: Address,\n): bigint {\n const deployer80 = (BigInt(deployerAddress) >> 80n) & MASK_80\n const pool40 = (BigInt(v3Pool) >> 120n) & MASK_40\n const risk40 = (BigInt(riskEngine) >> 120n) & MASK_40\n return (deployer80 << 176n) | (pool40 << 136n) | (risk40 << 96n)\n}\n\n/**\n * Compute the Uniswap V4 PoolId for a PoolKey.\n *\n * Mirrors `PoolId.toId(key)` = keccak256 of the ABI-encoded PoolKey struct\n * (5 fields × 32 bytes = 160 bytes).\n */\nexport function computePoolIdV4(poolKey: PoolKey): bigint {\n const fee = Number(poolKey.fee)\n if (!Number.isInteger(fee) || fee < 0 || fee >= 2 ** 24) {\n throw new PanopticValidationError(`fee out of uint24 range: ${fee}`)\n }\n const tickSpacing = Number(poolKey.tickSpacing)\n if (!Number.isInteger(tickSpacing) || tickSpacing < -(2 ** 23) || tickSpacing > 2 ** 23 - 1) {\n throw new PanopticValidationError(`tickSpacing out of int24 range: ${tickSpacing}`)\n }\n const encoded = encodeAbiParameters(\n [\n { type: 'address' },\n { type: 'address' },\n { type: 'uint24' },\n { type: 'int24' },\n { type: 'address' },\n ],\n [\n poolKey.currency0,\n poolKey.currency1,\n Number(poolKey.fee),\n Number(poolKey.tickSpacing),\n poolKey.hooks,\n ],\n )\n return BigInt(keccak256(encoded))\n}\n\n/**\n * Construct the bytes32 CREATE3 salt for PanopticFactoryV4.\n *\n * Mirrors:\n * bytes32(abi.encodePacked(\n * uint80(uint160(deployerAddress) >> 80),\n * uint40(uint256(PoolId.unwrap(key.toId())) >> 120), // bits [159:120] of poolId\n * uint40(uint160(riskEngine) >> 120),\n * salt\n * ))\n */\nfunction computeSaltPrefixV4(\n deployerAddress: Address,\n poolKey: PoolKey,\n riskEngine: Address,\n): bigint {\n const deployer80 = (BigInt(deployerAddress) >> 80n) & MASK_80\n const poolId40 = (computePoolIdV4(poolKey) >> 120n) & MASK_40\n const risk40 = (BigInt(riskEngine) >> 120n) & MASK_40\n return (deployer80 << 176n) | (poolId40 << 136n) | (risk40 << 96n)\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Mine for an optimal Panoptic pool address salt, running entirely off-chain.\n *\n * Equivalent to calling `minePoolAddress` on the factory contract but with zero\n * RPC round-trips. The result is identical to the on-chain computation.\n *\n * Iterates `loops` times starting from `salt`, tracking the highest-rarity address\n * found. Stops early when `minTargetRarity` is reached.\n *\n * @param params - Mining parameters (versioned: 'v3' or 'v4'). No `client` required.\n * @returns The best salt found and its rarity (number of leading hex zeros).\n */\nexport function minePoolAddressLocal(params: MinePoolAddressLocalParams): MinePoolAddressResult {\n const { factoryAddress, deployerAddress, riskEngine, salt, loops, minTargetRarity } = params\n\n if (salt < 0n || loops < 0n || minTargetRarity < 0n) {\n throw new PanopticValidationError('salt, loops, and minTargetRarity must be non-negative')\n }\n if (salt + loops > (1n << 96n) - 1n) {\n throw new PanopticValidationError('salt + loops exceeds uint96 range')\n }\n\n let bestSalt = salt\n let highestRarity = 0n\n const maxSalt = salt + loops\n\n // Precompute the invariant high-bit prefix once outside the loop\n const saltPrefix =\n params.version === 'v3'\n ? computeSaltPrefixV3(deployerAddress, params.v3Pool, riskEngine)\n : computeSaltPrefixV4(deployerAddress, params.poolKey, riskEngine)\n\n for (let currentSalt = salt; currentSalt < maxSalt; currentSalt++) {\n const newSalt = saltPrefix | (currentSalt & MASK_96)\n\n const addrInt = addressOfClone3(factoryAddress, newSalt)\n const rarity = BigInt(numberOfLeadingHexZeros(addrInt))\n\n if (rarity > highestRarity) {\n highestRarity = rarity\n bestSalt = currentSalt\n }\n\n if (rarity >= minTargetRarity) {\n highestRarity = rarity\n bestSalt = currentSalt\n break\n }\n }\n\n return { bestSalt, highestRarity }\n}\n\n// ---------------------------------------------------------------------------\n// Async variant (yields to the event loop between chunks)\n// ---------------------------------------------------------------------------\n\n/** Number of iterations per chunk before yielding back to the event loop. */\nconst CHUNK_SIZE = 5000n\n\n/**\n * Async version of {@link minePoolAddressLocal} that yields to the event loop\n * between chunks of iterations, preventing the browser UI from freezing.\n *\n * @param params - Mining parameters (versioned: 'v3' or 'v4'). No `client` required.\n * @returns The best salt found and its rarity (number of leading hex zeros).\n */\nexport async function minePoolAddressLocalAsync(\n params: MinePoolAddressLocalParams,\n): Promise<MinePoolAddressResult> {\n const { factoryAddress, deployerAddress, riskEngine, salt, loops, minTargetRarity } = params\n\n let bestSalt = salt\n let highestRarity = 0n\n const maxSalt = salt + loops\n\n const saltPrefix =\n params.version === 'v3'\n ? computeSaltPrefixV3(deployerAddress, params.v3Pool, riskEngine)\n : computeSaltPrefixV4(deployerAddress, params.poolKey, riskEngine)\n\n let currentSalt = salt\n while (currentSalt < maxSalt) {\n const chunkEnd = currentSalt + CHUNK_SIZE < maxSalt ? currentSalt + CHUNK_SIZE : maxSalt\n let done = false\n\n for (; currentSalt < chunkEnd; currentSalt++) {\n const newSalt = saltPrefix | (currentSalt & MASK_96)\n const addrInt = addressOfClone3(factoryAddress, newSalt)\n const rarity = BigInt(numberOfLeadingHexZeros(addrInt))\n\n if (rarity > highestRarity) {\n highestRarity = rarity\n bestSalt = currentSalt\n }\n\n if (rarity >= minTargetRarity) {\n highestRarity = rarity\n bestSalt = currentSalt\n done = true\n break\n }\n }\n\n if (done) break\n\n // Yield to the event loop so the UI stays responsive\n await new Promise<void>((resolve) => setTimeout(resolve, 0))\n }\n\n return { bestSalt, highestRarity }\n}\n","/**\n * Minimal Uniswap V4 StateView ABI for fee growth reads.\n * Only includes functions needed by streamia history.\n */\nexport const stateViewAbi = [\n {\n inputs: [{ internalType: 'PoolId', name: 'poolId', type: 'bytes32' }],\n name: 'getSlot0',\n outputs: [\n { internalType: 'uint160', name: 'sqrtPriceX96', type: 'uint160' },\n { internalType: 'int24', name: 'tick', type: 'int24' },\n { internalType: 'uint24', name: 'protocolFee', type: 'uint24' },\n { internalType: 'uint24', name: 'lpFee', type: 'uint24' },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [{ internalType: 'PoolId', name: 'poolId', type: 'bytes32' }],\n name: 'getFeeGrowthGlobals',\n outputs: [\n { internalType: 'uint256', name: 'feeGrowthGlobal0', type: 'uint256' },\n { internalType: 'uint256', name: 'feeGrowthGlobal1', type: 'uint256' },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n { internalType: 'PoolId', name: 'poolId', type: 'bytes32' },\n { internalType: 'int24', name: 'tick', type: 'int24' },\n ],\n name: 'getTickInfo',\n outputs: [\n { internalType: 'uint128', name: 'liquidityGross', type: 'uint128' },\n { internalType: 'int128', name: 'liquidityNet', type: 'int128' },\n { internalType: 'uint256', name: 'feeGrowthOutside0X128', type: 'uint256' },\n { internalType: 'uint256', name: 'feeGrowthOutside1X128', type: 'uint256' },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [{ internalType: 'PoolId', name: 'poolId', type: 'bytes32' }],\n name: 'getLiquidity',\n outputs: [{ internalType: 'uint128', name: 'liquidity', type: 'uint128' }],\n stateMutability: 'view',\n type: 'function',\n },\n] as const\n","/**\n * Minimal Uniswap V3 Pool ABI for fee growth reads.\n * Only includes functions needed by streamia history.\n */\nexport const uniswapV3PoolAbi = [\n {\n inputs: [],\n name: 'slot0',\n outputs: [\n { internalType: 'uint160', name: 'sqrtPriceX96', type: 'uint160' },\n { internalType: 'int24', name: 'tick', type: 'int24' },\n { internalType: 'uint16', name: 'observationIndex', type: 'uint16' },\n { internalType: 'uint16', name: 'observationCardinality', type: 'uint16' },\n { internalType: 'uint16', name: 'observationCardinalityNext', type: 'uint16' },\n { internalType: 'uint8', name: 'feeProtocol', type: 'uint8' },\n { internalType: 'bool', name: 'unlocked', type: 'bool' },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'feeGrowthGlobal0X128',\n outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'feeGrowthGlobal1X128',\n outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [{ internalType: 'int24', name: '', type: 'int24' }],\n name: 'ticks',\n outputs: [\n { internalType: 'uint128', name: 'liquidityGross', type: 'uint128' },\n { internalType: 'int128', name: 'liquidityNet', type: 'int128' },\n { internalType: 'uint256', name: 'feeGrowthOutside0X128', type: 'uint256' },\n { internalType: 'uint256', name: 'feeGrowthOutside1X128', type: 'uint256' },\n { internalType: 'int56', name: 'tickCumulativeOutside', type: 'int56' },\n { internalType: 'uint160', name: 'secondsPerLiquidityOutsideX128', type: 'uint160' },\n { internalType: 'uint32', name: 'secondsOutside', type: 'uint32' },\n { internalType: 'bool', name: 'initialized', type: 'bool' },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'liquidity',\n outputs: [{ internalType: 'uint128', name: '', type: 'uint128' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'fee',\n outputs: [{ internalType: 'uint24', name: '', type: 'uint24' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'token0',\n outputs: [{ internalType: 'address', name: '', type: 'address' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'token1',\n outputs: [{ internalType: 'address', name: '', type: 'address' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'tickSpacing',\n outputs: [{ internalType: 'int24', name: '', type: 'int24' }],\n stateMutability: 'view',\n type: 'function',\n },\n] as const\n","/**\n * Tick and price formatters for Uniswap V3/V4 pools.\n *\n * Ticks represent logarithmic prices where: price = 1.0001^tick\n *\n * @module v2/formatters/tick\n */\n\nimport { MAX_TICK, MIN_TICK } from '../utils/constants'\n\nconst Q192 = 1n << 192n\nconst RAW_PRICE_PRECISION = 40n\n\nfunction pow10(exponent: bigint): bigint {\n if (exponent < 0n) {\n throw new RangeError('Exponent must be non-negative')\n }\n return 10n ** exponent\n}\n\nfunction absBigint(value: bigint): bigint {\n return value < 0n ? -value : value\n}\n\nfunction trimTrailingZeros(value: string): string {\n const dotIndex = value.indexOf('.')\n if (dotIndex === -1) return value\n\n let end = value.length\n while (end > dotIndex && value[end - 1] === '0') {\n end -= 1\n }\n\n if (end === dotIndex + 1) {\n end = dotIndex\n }\n\n return value.slice(0, end)\n}\n\nfunction formatRatio(numerator: bigint, denominator: bigint, precision: bigint): string {\n if (precision < 0n) {\n throw new RangeError('Precision must be non-negative')\n }\n\n const sign = numerator < 0n ? '-' : ''\n const absNumerator = numerator < 0n ? -numerator : numerator\n\n const scale = pow10(precision)\n const scaled = (absNumerator * scale + denominator / 2n) / denominator\n const integerPart = scaled / scale\n const fractionalPart = scaled % scale\n\n if (precision === 0n) {\n return `${sign}${integerPart}`\n }\n\n return `${sign}${integerPart}.${fractionalPart.toString().padStart(Number(precision), '0')}`\n}\n\nfunction parseDecimalToFraction(value: string): { numerator: bigint; denominator: bigint } {\n const trimmed = value.trim()\n if (trimmed.length === 0) {\n throw new Error('Price must be a number')\n }\n\n const isNegative = trimmed.startsWith('-')\n const unsigned = isNegative || trimmed.startsWith('+') ? trimmed.slice(1) : trimmed\n\n const [basePart, exponentPart] = unsigned.toLowerCase().split('e')\n const [integerStr, fractionalStr = ''] = basePart.split('.')\n\n if (integerStr === '' && fractionalStr === '') {\n throw new Error('Price must be a number')\n }\n\n const integerDigits = integerStr === '' ? '0' : integerStr\n const digits = `${integerDigits}${fractionalStr}`\n\n let numerator = BigInt(digits === '' ? '0' : digits)\n let denominator = pow10(BigInt(fractionalStr.length))\n\n if (exponentPart !== undefined && exponentPart !== '') {\n const exponent = BigInt(exponentPart)\n if (exponent > 0n) {\n numerator *= pow10(exponent)\n } else if (exponent < 0n) {\n denominator *= pow10(-exponent)\n }\n }\n\n if (isNegative) {\n numerator = -numerator\n }\n\n return { numerator, denominator }\n}\n\nfunction compareRatios(\n leftNumerator: bigint,\n leftDenominator: bigint,\n rightNumerator: bigint,\n rightDenominator: bigint,\n): -1 | 0 | 1 {\n const left = leftNumerator * rightDenominator\n const right = rightNumerator * leftDenominator\n\n if (left === right) return 0\n return left < right ? -1 : 1\n}\n\nexport function tickToSqrtPriceX96(tick: bigint): bigint {\n if (tick < MIN_TICK || tick > MAX_TICK) {\n throw new RangeError('Tick out of bounds')\n }\n\n const absTick = tick < 0n ? -tick : tick\n\n let ratio =\n (absTick & 0x1n) !== 0n\n ? 0xfffcb933bd6fad37aa2d162d1a594001n\n : 0x100000000000000000000000000000000n\n if ((absTick & 0x2n) !== 0n) ratio = (ratio * 0xfff97272373d413259a46990580e213an) >> 128n\n if ((absTick & 0x4n) !== 0n) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdccn) >> 128n\n if ((absTick & 0x8n) !== 0n) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0n) >> 128n\n if ((absTick & 0x10n) !== 0n) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644n) >> 128n\n if ((absTick & 0x20n) !== 0n) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0n) >> 128n\n if ((absTick & 0x40n) !== 0n) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861n) >> 128n\n if ((absTick & 0x80n) !== 0n) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053n) >> 128n\n if ((absTick & 0x100n) !== 0n) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4n) >> 128n\n if ((absTick & 0x200n) !== 0n) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54n) >> 128n\n if ((absTick & 0x400n) !== 0n) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3n) >> 128n\n if ((absTick & 0x800n) !== 0n) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9n) >> 128n\n if ((absTick & 0x1000n) !== 0n) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825n) >> 128n\n if ((absTick & 0x2000n) !== 0n) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5n) >> 128n\n if ((absTick & 0x4000n) !== 0n) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7n) >> 128n\n if ((absTick & 0x8000n) !== 0n) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6n) >> 128n\n if ((absTick & 0x10000n) !== 0n) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9n) >> 128n\n if ((absTick & 0x20000n) !== 0n) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604n) >> 128n\n if ((absTick & 0x40000n) !== 0n) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98n) >> 128n\n if ((absTick & 0x80000n) !== 0n) ratio = (ratio * 0x48a170391f7dc42444e8fa2n) >> 128n\n\n if (tick > 0n) {\n ratio = ((1n << 256n) - 1n) / ratio\n }\n\n const remainderMask = (1n << 32n) - 1n\n const sqrtPriceX96 = (ratio >> 32n) + ((ratio & remainderMask) === 0n ? 0n : 1n)\n\n return sqrtPriceX96\n}\n\nconst MIN_SQRT_PRICE_X96 = tickToSqrtPriceX96(MIN_TICK)\nconst MAX_SQRT_PRICE_X96 = tickToSqrtPriceX96(MAX_TICK)\n\nfunction getPriceRatioFromSqrtPriceX96(sqrtPriceX96: bigint): {\n numerator: bigint\n denominator: bigint\n} {\n return {\n numerator: sqrtPriceX96 * sqrtPriceX96,\n denominator: Q192,\n }\n}\n\nfunction getRawPriceRatio(tick: bigint): { numerator: bigint; denominator: bigint } {\n return getPriceRatioFromSqrtPriceX96(tickToSqrtPriceX96(tick))\n}\n\nfunction adjustRatioForDecimals(\n numerator: bigint,\n denominator: bigint,\n decimals0: bigint,\n decimals1: bigint,\n): { numerator: bigint; denominator: bigint } {\n const diff = decimals0 - decimals1\n if (diff === 0n) {\n return { numerator, denominator }\n }\n\n if (diff > 0n) {\n return { numerator: numerator * pow10(diff), denominator }\n }\n\n return { numerator, denominator: denominator * pow10(-diff) }\n}\n\n/**\n * Convert a tick to a raw price string (no decimal adjustment).\n * Uses the formula: price = 1.0001^tick\n *\n * This returns the raw price ratio, not adjusted for token decimals.\n * A fixed internal precision is used and trailing zeros are trimmed.\n *\n * @param tick - The tick value\n * @returns Price string\n *\n * @example\n * ```typescript\n * tickToPrice(0n) // \"1\"\n * tickToPrice(1000n) // \"1.105...\" (approximately)\n * tickToPrice(-1000n) // \"0.904...\" (approximately)\n * tickToPrice(200000n) // Very large number\n * ```\n */\nexport function tickToPrice(tick: bigint): string {\n const { numerator, denominator } = getRawPriceRatio(tick)\n const price = formatRatio(numerator, denominator, RAW_PRICE_PRECISION)\n return trimTrailingZeros(price)\n}\n\n/**\n * Convert a tick to a human-readable price with decimal scaling.\n * Uses the formula: price = 1.0001^tick * 10^(decimals0-decimals1)\n *\n * This adjusts for the different decimals of the two tokens in the pair.\n *\n * @param tick - The tick value\n * @param decimals0 - Decimals of token0\n * @param decimals1 - Decimals of token1\n * @param precision - Number of decimal places to display\n * @returns Formatted price string\n *\n * @example\n * ```typescript\n * // WETH/USDC pool (18 decimals / 6 decimals)\n * // At tick ~200000, price is roughly $2000 per ETH\n * tickToPriceDecimalScaled(200000n, 18n, 6n, 2n) // \"2000.00\" (approximately)\n *\n * // For token1/token0 price, swap the decimals\n * tickToPriceDecimalScaled(200000n, 6n, 18n, 6n) // \"0.000500\" (approximately)\n * ```\n */\nexport function tickToPriceDecimalScaled(\n tick: bigint,\n decimals0: bigint,\n decimals1: bigint,\n precision: bigint,\n): string {\n const rawRatio = getRawPriceRatio(tick)\n const { numerator, denominator } = adjustRatioForDecimals(\n rawRatio.numerator,\n rawRatio.denominator,\n decimals0,\n decimals1,\n )\n\n return formatRatio(numerator, denominator, precision)\n}\n\n/**\n * Convert a sqrtPriceX96 to a human-readable price with decimal scaling.\n *\n * Uses the formula: price = (sqrtPriceX96^2 / 2^192) * 10^(decimals0-decimals1)\n *\n * @param sqrtPriceX96 - The sqrt price in Q64.96 format\n * @param decimals0 - Decimals of token0\n * @param decimals1 - Decimals of token1\n * @param precision - Number of decimal places to display\n * @returns Formatted price string\n *\n * @example\n * ```typescript\n * sqrtPriceX96ToPriceDecimalScaled(2n ** 96n, 18n, 18n, 2n) // \"1.00\"\n * ```\n */\nexport function sqrtPriceX96ToPriceDecimalScaled(\n sqrtPriceX96: bigint,\n decimals0: bigint,\n decimals1: bigint,\n precision: bigint,\n): string {\n const rawRatio = getPriceRatioFromSqrtPriceX96(sqrtPriceX96)\n const { numerator, denominator } = adjustRatioForDecimals(\n rawRatio.numerator,\n rawRatio.denominator,\n decimals0,\n decimals1,\n )\n\n return formatRatio(numerator, denominator, precision)\n}\n\n/**\n * Convert a price to a tick value.\n *\n * @param price - The price string\n * @param decimals0 - Decimals of token0\n * @param decimals1 - Decimals of token1\n * @returns The tick value (rounded to nearest integer)\n *\n * @example\n * ```typescript\n * // WETH/USDC: What tick for $2000 per ETH?\n * priceToTick(\"2000\", 18n, 6n) // ~200000n\n *\n * // Inverse: What tick for 0.0005 ETH per USDC?\n * priceToTick(\"0.0005\", 6n, 18n) // ~200000n\n * ```\n */\nexport function priceToTick(price: string, decimals0: bigint, decimals1: bigint): bigint {\n const parsed = parseDecimalToFraction(price)\n if (parsed.numerator <= 0n) {\n throw new Error('Price must be positive')\n }\n\n let targetNumerator = parsed.numerator\n let targetDenominator = parsed.denominator\n\n const diff = decimals0 - decimals1\n if (diff > 0n) {\n targetDenominator *= pow10(diff)\n } else if (diff < 0n) {\n targetNumerator *= pow10(-diff)\n }\n\n let low = MIN_TICK\n let high = MAX_TICK\n\n while (low <= high) {\n const mid = (low + high) / 2n\n const { numerator, denominator } = getRawPriceRatio(mid)\n const cmp = compareRatios(numerator, denominator, targetNumerator, targetDenominator)\n\n if (cmp === 0) {\n return mid\n }\n\n if (cmp < 0) {\n low = mid + 1n\n } else {\n high = mid - 1n\n }\n }\n\n const floorTick = high\n const ceilTick = low\n\n if (floorTick < MIN_TICK) return MIN_TICK\n if (ceilTick > MAX_TICK) return MAX_TICK\n\n const floorRatio = getRawPriceRatio(floorTick)\n const ceilRatio = getRawPriceRatio(ceilTick)\n\n const floorDiffNumerator = absBigint(\n targetNumerator * floorRatio.denominator - floorRatio.numerator * targetDenominator,\n )\n const ceilDiffNumerator = absBigint(\n targetNumerator * ceilRatio.denominator - ceilRatio.numerator * targetDenominator,\n )\n const floorDiffDenominator = targetDenominator * floorRatio.denominator\n const ceilDiffDenominator = targetDenominator * ceilRatio.denominator\n\n return floorDiffNumerator * ceilDiffDenominator <= ceilDiffNumerator * floorDiffDenominator\n ? floorTick\n : ceilTick\n}\n\n/**\n * Convert a sqrtPriceX96 value to the nearest tick.\n *\n * @param sqrtPriceX96 - The sqrt price in Q64.96 format\n * @returns The tick value (rounded to nearest integer)\n *\n * @example\n * ```typescript\n * const tick = sqrtPriceX96ToTick(2n ** 96n) // 0n\n * ```\n */\nexport function sqrtPriceX96ToTick(sqrtPriceX96: bigint): bigint {\n if (sqrtPriceX96 <= 0n) {\n throw new Error('Sqrt price must be positive')\n }\n\n if (sqrtPriceX96 < MIN_SQRT_PRICE_X96 || sqrtPriceX96 > MAX_SQRT_PRICE_X96) {\n throw new RangeError('Sqrt price out of bounds')\n }\n\n let low = MIN_TICK\n let high = MAX_TICK\n\n while (low <= high) {\n const mid = (low + high) / 2n\n const midSqrt = tickToSqrtPriceX96(mid)\n\n if (midSqrt === sqrtPriceX96) {\n return mid\n }\n\n if (midSqrt < sqrtPriceX96) {\n low = mid + 1n\n } else {\n high = mid - 1n\n }\n }\n\n const floorTick = high\n const ceilTick = low\n\n if (floorTick < MIN_TICK) return MIN_TICK\n if (ceilTick > MAX_TICK) return MAX_TICK\n\n const floorSqrt = tickToSqrtPriceX96(floorTick)\n const ceilSqrt = tickToSqrtPriceX96(ceilTick)\n\n const floorDiff = absBigint(sqrtPriceX96 - floorSqrt)\n const ceilDiff = absBigint(ceilSqrt - sqrtPriceX96)\n\n return floorDiff <= ceilDiff ? floorTick : ceilTick\n}\n\n/**\n * Format a tick value for display.\n *\n * @param tick - The tick value\n * @returns Formatted tick string\n *\n * @example\n * ```typescript\n * formatTick(200000n) // \"200000\"\n * formatTick(-50000n) // \"-50000\"\n * ```\n */\nexport function formatTick(tick: bigint): string {\n return tick.toString()\n}\n\n/**\n * Get the price at a specific tick, returning both token0/token1 and token1/token0 prices.\n *\n * @param tick - The tick value\n * @param decimals0 - Decimals of token0\n * @param decimals1 - Decimals of token1\n * @param precision - Number of decimal places to display\n * @returns Object with both price directions\n *\n * @example\n * ```typescript\n * const prices = getPricesAtTick(200000n, 18n, 6n, 2n)\n * // prices.token0PerToken1 = \"0.00\" (very small)\n * // prices.token1PerToken0 = \"2000.00\" (USDC per ETH)\n * ```\n */\nexport function getPricesAtTick(\n tick: bigint,\n decimals0: bigint,\n decimals1: bigint,\n precision: bigint,\n): { token0PerToken1: string; token1PerToken0: string } {\n const rawRatio = getRawPriceRatio(tick)\n const adjustedRatio = adjustRatioForDecimals(\n rawRatio.numerator,\n rawRatio.denominator,\n decimals0,\n decimals1,\n )\n\n return {\n token0PerToken1: formatRatio(adjustedRatio.denominator, adjustedRatio.numerator, precision),\n token1PerToken0: formatRatio(adjustedRatio.numerator, adjustedRatio.denominator, precision),\n }\n}\n\n/**\n * Format a tick range for display.\n *\n * @param tickLower - Lower tick\n * @param tickUpper - Upper tick\n * @returns Formatted tick range string\n *\n * @example\n * ```typescript\n * formatTickRange(-50000n, 200000n) // \"-50000 - 200000\"\n * ```\n */\nexport function formatTickRange(tickLower: bigint, tickUpper: bigint): string {\n return `${tickLower} - ${tickUpper}`\n}\n\n/**\n * Format a price range for display.\n *\n * @param tickLower - Lower tick\n * @param tickUpper - Upper tick\n * @param decimals0 - Decimals of token0\n * @param decimals1 - Decimals of token1\n * @param precision - Number of decimal places to display\n * @returns Formatted price range string\n *\n * @example\n * ```typescript\n * formatPriceRange(0n, 0n, 18n, 18n, 2n) // \"1.00 - 1.00\"\n * ```\n */\nexport function formatPriceRange(\n tickLower: bigint,\n tickUpper: bigint,\n decimals0: bigint,\n decimals1: bigint,\n precision: bigint,\n): string {\n const lower = tickToPriceDecimalScaled(tickLower, decimals0, decimals1, precision)\n const upper = tickToPriceDecimalScaled(tickUpper, decimals0, decimals1, precision)\n return `${lower} - ${upper}`\n}\n\n/**\n * Calculate the tick spacing for a given fee tier.\n *\n * @param feeBps - Fee in basis points (e.g., 500n for 0.05%)\n * @returns Tick spacing\n *\n * @example\n * ```typescript\n * getTickSpacing(100n) // 1n (0.01% fee tier)\n * getTickSpacing(500n) // 10n (0.05% fee tier)\n * getTickSpacing(3000n) // 60n (0.30% fee tier)\n * getTickSpacing(10000n) // 200n (1.00% fee tier)\n * ```\n */\nexport function getTickSpacing(feeBps: bigint): bigint {\n // Standard Uniswap V3 tick spacings\n switch (feeBps) {\n case 100n:\n return 1n\n case 500n:\n return 10n\n case 3000n:\n return 60n\n case 10000n:\n return 200n\n default: {\n const spacing = feeBps / 50n\n return spacing > 1n ? spacing : 1n\n }\n }\n}\n\n/**\n * Round a tick to the nearest valid tick for a given tick spacing.\n *\n * @param tick - The tick to round\n * @param tickSpacing - The tick spacing\n * @returns Rounded tick\n *\n * @example\n * ```typescript\n * roundToTickSpacing(12345n, 10n) // 12340n\n * roundToTickSpacing(12345n, 60n) // 12360n\n * roundToTickSpacing(-12345n, 10n) // -12350n\n * ```\n */\nexport function roundToTickSpacing(tick: bigint, tickSpacing: bigint): bigint {\n const remainder = tick % tickSpacing\n if (remainder === 0n) {\n return tick\n }\n // Round to nearest\n if (tick >= 0n) {\n return remainder >= tickSpacing / 2n ? tick + (tickSpacing - remainder) : tick - remainder\n }\n\n const absRemainder = -remainder\n return absRemainder >= tickSpacing / 2n\n ? tick - (tickSpacing - absRemainder)\n : tick + absRemainder\n}\n\n/**\n * Result of {@link tickLimits}.\n */\nexport interface TickLimitsResult {\n /** Lower tick limit (clamped to MIN_TICK). */\n low: bigint\n /** Upper tick limit (clamped to MAX_TICK). */\n high: bigint\n}\n\n/**\n * Compute slippage-bounded tick limits around the current tick.\n *\n * 1 tick ≈ 1 basis point (0.01 %) of price change, so a `toleranceBps`\n * of 500 allows roughly 5 % price movement. The result is clamped to\n * the protocol's `[MIN_TICK, MAX_TICK]` range.\n *\n * Useful for setting `tickLimitLow` / `tickLimitHigh` on `openPosition`\n * and `closePosition` to protect against MEV sandwiches and volatile\n * tick moves.\n *\n * @param currentTick - The current pool tick (must be within [MIN_TICK, MAX_TICK]).\n * @param toleranceBps - Slippage tolerance in basis points (≈ ticks). Must be non-negative.\n * @returns Clamped `{ low, high }` tick limits.\n * @throws {RangeError} If `toleranceBps` is negative or `currentTick` is out of bounds.\n *\n * @example\n * ```typescript\n * const { low, high } = tickLimits(200_000n, 500n)\n * // low = 199_500n\n * // high = 200_500n\n *\n * await openPosition({ ..., tickLimitLow: low, tickLimitHigh: high })\n * ```\n */\nexport function tickLimits(currentTick: bigint, toleranceBps: bigint): TickLimitsResult {\n if (toleranceBps < 0n) {\n throw new RangeError(`toleranceBps must be non-negative, got ${toleranceBps}`)\n }\n if (currentTick < MIN_TICK || currentTick > MAX_TICK) {\n throw new RangeError(`currentTick ${currentTick} is out of bounds [${MIN_TICK}, ${MAX_TICK}]`)\n }\n\n const rawLow = currentTick - toleranceBps\n const rawHigh = currentTick + toleranceBps\n const low = rawLow < MIN_TICK ? MIN_TICK : rawLow\n const high = rawHigh > MAX_TICK ? MAX_TICK : rawHigh\n\n if (low > high) {\n throw new RangeError(\n `Computed tick limits are inverted: low ${low} > high ${high} (currentTick=${currentTick}, toleranceBps=${toleranceBps})`,\n )\n }\n\n return { low, high }\n}\n","/**\n * The mint-time margin buffer — the single place the SDK and every UI surface\n * turn a maintenance requirement into the figure the contract actually enforces\n * at mint.\n *\n * `RiskEngine._checkSolvencyAtTick` applies `BP_DECREASE_BUFFER / DECIMALS` to\n * the NATIVE token0 and token1 requirements, with `Math.mulDivRoundingUp`, and\n * only then compares each side against that side's balance. Three properties of\n * that sentence are load-bearing and were each wrong somewhere in the UI:\n *\n * 1. **Scale.** The ratio is `10_666_667 / 10_000_000`, not `10_666 / 10_000`.\n * The truncated form understates the requirement by ~6.3 ppm of notional.\n * 2. **Rounding.** The contract rounds UP. Flooring lets a position read as\n * affordable at exactly the boundary and then revert at mint.\n * 3. **Order.** The buffer is applied per token BEFORE any price conversion.\n * Buffering an already-quote-converted total re-rounds the conversion dust\n * through the buffer, so the two disagree by more than the ratio implies.\n *\n * @module v2/reads/mintBuffer\n */\n\nimport { PanopticValidationError } from '../errors'\nimport type { MintBufferRatio } from '../types/mintBuffer'\n\nexport type { MintBufferRatio } from '../types/mintBuffer'\n\n/**\n * `RiskEngine.BP_DECREASE_BUFFER` — the numerator of the mint-time buffer.\n *\n * Exported so callers can display the constant; prefer {@link applyMintBuffer}\n * over multiplying by it directly, which is how the rounding bug reappears.\n */\nexport const MINT_BUFFER = 10_666_667n\n\n/** `RiskEngine.DECIMALS` — the denominator {@link MINT_BUFFER} is taken over. */\nexport const MINT_BUFFER_DENOMINATOR = 10_000_000n\n\n/** The compiled-in default, matching the deployed RiskEngine. */\nexport const DEFAULT_MINT_BUFFER: MintBufferRatio = {\n numerator: MINT_BUFFER,\n denominator: MINT_BUFFER_DENOMINATOR,\n}\n\n/**\n * Apply the mint buffer to ONE token's NATIVE requirement, rounding up exactly\n * as `Math.mulDivRoundingUp` does on-chain.\n *\n * Call this on the native token0/token1 requirement, never on a quote-converted\n * total — see the module docstring for why the order matters.\n *\n * @param required - Maintenance requirement in that token's own units\n * @param buffer - Optional live on-chain ratio; defaults to {@link DEFAULT_MINT_BUFFER}\n * @returns The mint-time requirement the solvency check enforces\n */\nexport function applyMintBuffer(\n required: bigint,\n buffer: MintBufferRatio = DEFAULT_MINT_BUFFER,\n): bigint {\n const { numerator, denominator } = buffer\n if (denominator <= 0n) {\n throw new PanopticValidationError('applyMintBuffer: buffer denominator must be positive')\n }\n if (required <= 0n) return 0n\n return (required * numerator + denominator - 1n) / denominator\n}\n\n/**\n * Apply the mint buffer to both tokens' NATIVE requirements, independently.\n *\n * This is the shape the solvency check itself uses: two separate per-side\n * comparisons, never a pooled total.\n *\n * @param required0 - Maintenance requirement in token0 units\n * @param required1 - Maintenance requirement in token1 units\n * @param buffer - Optional live on-chain ratio\n * @returns `[buffered0, buffered1]`\n */\nexport function applyMintBufferPerToken(\n required0: bigint,\n required1: bigint,\n buffer: MintBufferRatio = DEFAULT_MINT_BUFFER,\n): [bigint, bigint] {\n return [applyMintBuffer(required0, buffer), applyMintBuffer(required1, buffer)]\n}\n\n/**\n * Collateral still deployable on one side before the mint solvency check fails:\n * `balance - bufferedRequired`, floored at zero.\n *\n * Both arguments must be in the SAME token's units.\n *\n * @param balance - That side's collateral balance\n * @param required - That side's maintenance requirement (unbuffered)\n * @param buffer - Optional live on-chain ratio\n * @returns Mintable headroom, never negative\n */\nexport function mintableAfterBuffer(\n balance: bigint,\n required: bigint,\n buffer: MintBufferRatio = DEFAULT_MINT_BUFFER,\n): bigint {\n const requiredAtMint = applyMintBuffer(required, buffer)\n return balance > requiredAtMint ? balance - requiredAtMint : 0n\n}\n","/**\n * Pool read functions for the Panoptic v2 SDK.\n *\n * ## Same-Block Guarantee\n *\n * All dynamic data is fetched in a SINGLE multicall to ensure block consistency.\n * Per PLAN.md §6, immutable \"static prefetch\" data (addresses, decimals, symbols)\n * can be fetched separately and cached - it's not subject to same-block consistency.\n *\n * Functions accept an optional `poolMetadata` parameter containing pre-fetched\n * immutable addresses. If not provided, it will be fetched first (static prefetch).\n * Then ONE multicall fetches all dynamic data at the target block.\n *\n * @module v2/reads/pool\n */\n\nimport type { Address, PublicClient } from 'viem'\nimport { decodeAbiParameters, keccak256, zeroAddress } from 'viem'\n\nimport { collateralTrackerV2Abi, panopticPoolV2Abi, riskEngineAbi } from '../../../generated'\nimport { stateViewAbi } from '../abis/stateView'\nimport { uniswapV3PoolAbi } from '../abis/uniswapV3Pool'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport { tickToSqrtPriceX96 } from '../formatters/tick'\nimport type {\n BlockMeta,\n CollateralTracker,\n OracleState,\n Pool,\n PoolKey,\n RiskEngine,\n RiskParameters,\n Utilization,\n} from '../types'\nimport { decodeOraclePack } from '../utils/oraclePack'\nimport { type OracleRiskParameters, decodeOracleRiskParameters } from '../utils/oracleSafeMode'\nimport { DEFAULT_MINT_BUFFER } from './mintBuffer'\n\n// ERC20 minimal ABI for token metadata\nconst erc20Abi = [\n {\n type: 'function',\n name: 'symbol',\n inputs: [],\n outputs: [{ type: 'string' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'decimals',\n inputs: [],\n outputs: [{ type: 'uint8' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'name',\n inputs: [],\n outputs: [{ type: 'string' }],\n stateMutability: 'view',\n },\n] as const\n\n/**\n * Immutable pool metadata that can be cached.\n * These values never change for a given pool, so they're exempt from\n * same-block consistency requirements (per PLAN.md \"Static Prefetches\" exception).\n */\nexport interface PoolMetadata {\n /** Pool key bytes */\n poolKeyBytes: `0x${string}`\n /** Pool ID */\n poolId: bigint\n /** Collateral tracker 0 address */\n collateralToken0Address: Address\n /** Collateral tracker 1 address */\n collateralToken1Address: Address\n /** Risk engine address */\n riskEngineAddress: Address\n /** Token 0 underlying asset address */\n token0Asset: Address\n /** Token 1 underlying asset address */\n token1Asset: Address\n /** Token 0 symbol */\n token0Symbol: string\n /** Token 1 symbol */\n token1Symbol: string\n /** Token 0 decimals */\n token0Decimals: bigint\n /** Token 1 decimals */\n token1Decimals: bigint\n /** Token 0 name */\n token0Name: string\n /** Token 1 name */\n token1Name: string\n /** Underlying pool ID (V3: pool address, V4: keccak256(poolKeyBytes)) */\n underlyingPoolId: string\n /** Whether this is a V4 pool (poolManager is non-zero) */\n isV4: boolean\n /** Tick spacing */\n tickSpacing: bigint\n /** Fee tier (V4: from poolKey, V3: from Uniswap pool fee()) */\n fee: bigint\n /** SemiFungiblePositionManager address */\n sfpmAddress: Address\n}\n\n/**\n * Parameters for getPoolMetadata.\n */\nexport interface GetPoolMetadataParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n}\n\n/**\n * Fetch immutable pool metadata (addresses, symbols, decimals).\n * This data never changes for a given pool and can be cached indefinitely.\n *\n * This is the \"static prefetch\" per PLAN.md §6 - exempt from same-block consistency.\n *\n * @param params - The parameters\n * @returns Immutable pool metadata\n */\nexport async function getPoolMetadata(params: GetPoolMetadataParams): Promise<PoolMetadata> {\n const { client, poolAddress } = params\n\n // First call: get basic immutable pool data\n const basicResults = await client.multicall({\n contracts: [\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'poolKey',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'poolId',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken0',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken1',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'riskEngine',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'poolManager',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'SFPM',\n },\n ],\n allowFailure: false,\n })\n\n const [\n poolKeyBytes,\n poolId,\n collateralToken0Address,\n collateralToken1Address,\n riskEngineAddress,\n poolManager,\n sfpmAddress,\n ] = basicResults\n\n // Second call: get underlying asset addresses from collateral trackers\n const assetResults = await client.multicall({\n contracts: [\n {\n address: collateralToken0Address,\n abi: collateralTrackerV2Abi,\n functionName: 'asset',\n },\n {\n address: collateralToken1Address,\n abi: collateralTrackerV2Abi,\n functionName: 'asset',\n },\n ],\n allowFailure: false,\n })\n\n const [token0Asset, token1Asset] = assetResults\n\n // Native ETH (address zero) has no ERC20 contract — use hardcoded metadata\n const NATIVE_ETH_ADDRESS = '0x0000000000000000000000000000000000000000'\n const isToken0Native = token0Asset.toLowerCase() === NATIVE_ETH_ADDRESS\n const isToken1Native = token1Asset.toLowerCase() === NATIVE_ETH_ADDRESS\n\n // Third call: get token metadata (symbols, decimals, names) — skip native ETH tokens\n const erc20Contracts = [\n ...(isToken0Native\n ? []\n : [\n { address: token0Asset, abi: erc20Abi, functionName: 'symbol' as const },\n { address: token0Asset, abi: erc20Abi, functionName: 'decimals' as const },\n { address: token0Asset, abi: erc20Abi, functionName: 'name' as const },\n ]),\n ...(isToken1Native\n ? []\n : [\n { address: token1Asset, abi: erc20Abi, functionName: 'symbol' as const },\n { address: token1Asset, abi: erc20Abi, functionName: 'decimals' as const },\n { address: token1Asset, abi: erc20Abi, functionName: 'name' as const },\n ]),\n ]\n\n const erc20Results =\n erc20Contracts.length > 0\n ? await client.multicall({ contracts: erc20Contracts, allowFailure: false })\n : []\n\n // Reconstruct metadata, inserting native ETH defaults where needed\n let resultIdx = 0\n const token0Symbol = isToken0Native ? 'ETH' : (erc20Results[resultIdx++] as string)\n const token0Decimals = isToken0Native ? 18 : (erc20Results[resultIdx++] as number)\n const token0Name = isToken0Native ? 'Ether' : (erc20Results[resultIdx++] as string)\n const token1Symbol = isToken1Native ? 'ETH' : (erc20Results[resultIdx++] as string)\n const token1Decimals = isToken1Native ? 18 : (erc20Results[resultIdx++] as number)\n const token1Name = isToken1Native ? 'Ether' : (erc20Results[resultIdx++] as string)\n\n // Derive underlyingPoolId, tickSpacing, and fee\n const isV4 = poolManager !== zeroAddress\n const parsedPoolKey = parsePoolKey(poolKeyBytes)\n let underlyingPoolId: string\n let fee: bigint\n let tickSpacing: bigint\n\n if (isV4) {\n underlyingPoolId = keccak256(poolKeyBytes)\n fee = parsedPoolKey.fee\n tickSpacing = tickSpacingFromPoolId(poolId)\n } else {\n const v3PoolAddress = decodeAbiParameters([{ type: 'address' }], poolKeyBytes)[0]\n underlyingPoolId = v3PoolAddress\n const [v3Fee, v3TickSpacing] = await client.multicall({\n contracts: [\n { address: v3PoolAddress, abi: uniswapV3PoolAbi, functionName: 'fee' },\n { address: v3PoolAddress, abi: uniswapV3PoolAbi, functionName: 'tickSpacing' },\n ],\n allowFailure: false,\n })\n fee = BigInt(v3Fee)\n tickSpacing = BigInt(v3TickSpacing)\n }\n\n return {\n poolKeyBytes,\n poolId,\n collateralToken0Address,\n collateralToken1Address,\n isV4,\n riskEngineAddress,\n token0Asset,\n token1Asset,\n token0Symbol,\n token1Symbol,\n token0Decimals: BigInt(token0Decimals),\n token1Decimals: BigInt(token1Decimals),\n token0Name,\n token1Name,\n underlyingPoolId,\n tickSpacing,\n fee,\n sfpmAddress,\n }\n}\n\n/**\n * Parameters for getPool.\n */\nexport interface GetPoolParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Chain ID */\n chainId: bigint\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched pool metadata (for caching/optimization) */\n poolMetadata?: PoolMetadata\n /** Optional StateView address for V4 pools (needed to read Uniswap pool liquidity) */\n stateViewAddress?: Address\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get full pool data including both collateral trackers and oracle state.\n *\n * ## Same-Block Guarantee\n * All dynamic data is fetched in ONE multicall at the target block.\n * Static metadata (addresses, symbols, decimals) is either provided via\n * poolMetadata or fetched separately (static prefetch exception).\n *\n * @param params - The parameters\n * @returns Pool data with block metadata\n */\nexport async function getPool(params: GetPoolParams): Promise<Pool> {\n const { client, poolAddress, chainId, blockNumber, poolMetadata } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Get static metadata (either from cache or fetch it)\n const metadata = poolMetadata ?? (await getPoolMetadata({ client, poolAddress }))\n\n // Build Uniswap pool liquidity read (V3 vs V4)\n const liquidityContract =\n metadata.isV4 && params.stateViewAddress\n ? {\n address: params.stateViewAddress,\n abi: stateViewAbi,\n functionName: 'getLiquidity' as const,\n args: [metadata.underlyingPoolId as `0x${string}`] as const,\n }\n : !metadata.isV4\n ? {\n address: metadata.underlyingPoolId as Address,\n abi: uniswapV3PoolAbi,\n functionName: 'liquidity' as const,\n }\n : null // V4 without stateViewAddress — skip\n\n // SINGLE multicall for ALL dynamic data - ensures same-block consistency\n const [dynamicResults, _meta] = await Promise.all([\n client.multicall({\n contracts: [\n // Pool dynamic state\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'isSafeMode',\n },\n // Token 0 collateral tracker dynamic data\n {\n address: metadata.collateralToken0Address,\n abi: collateralTrackerV2Abi,\n functionName: 'getPoolData',\n },\n {\n address: metadata.collateralToken0Address,\n abi: collateralTrackerV2Abi,\n functionName: 'totalSupply',\n },\n {\n address: metadata.collateralToken0Address,\n abi: collateralTrackerV2Abi,\n functionName: 'interestRate',\n },\n // Token 1 collateral tracker dynamic data\n {\n address: metadata.collateralToken1Address,\n abi: collateralTrackerV2Abi,\n functionName: 'getPoolData',\n },\n {\n address: metadata.collateralToken1Address,\n abi: collateralTrackerV2Abi,\n functionName: 'totalSupply',\n },\n {\n address: metadata.collateralToken1Address,\n abi: collateralTrackerV2Abi,\n functionName: 'interestRate',\n },\n // Risk engine parameters (technically immutable but included for completeness)\n {\n address: metadata.riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'SELLER_COLLATERAL_RATIO',\n },\n {\n address: metadata.riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'MAINT_MARGIN_RATE',\n },\n {\n address: metadata.riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'NOTIONAL_FEE',\n },\n {\n address: metadata.riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'PREMIUM_FEE',\n },\n {\n address: metadata.riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'VEGOID',\n },\n {\n address: metadata.riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'MAX_SPREAD',\n },\n // Uniswap pool in-range liquidity (V3 or V4 via StateView)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ...(liquidityContract ? [liquidityContract as any] : []),\n ],\n blockNumber: targetBlockNumber,\n allowFailure: true,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n // Extract results — first 14 are core (must succeed), last is liquidity (may fail)\n const coreResults = dynamicResults.slice(0, 14)\n if (coreResults.some((r) => r.status !== 'success')) {\n const failed = coreResults.find((r) => r.status !== 'success')\n throw new Error(`Core pool read failed: ${JSON.stringify(failed)}`)\n }\n const [\n currentTick,\n safeModeRaw,\n token0PoolData,\n token0TotalSupply,\n token0InterestRate,\n token1PoolData,\n token1TotalSupply,\n token1InterestRate,\n sellerCollateralRatio,\n maintMarginRate,\n notionalFee,\n premiumFee,\n vegoid,\n maxSpread,\n ] = coreResults.map((r) => r.result) as [\n bigint, // currentTick\n number, // safeModeRaw\n readonly [bigint, bigint, bigint, bigint], // token0PoolData (getPoolData)\n bigint, // token0TotalSupply\n bigint, // token0InterestRate\n readonly [bigint, bigint, bigint, bigint], // token1PoolData (getPoolData)\n bigint, // token1TotalSupply\n bigint, // token1InterestRate\n bigint, // sellerCollateralRatio\n bigint, // maintMarginRate\n bigint, // notionalFee\n bigint, // premiumFee\n bigint, // vegoid\n bigint, // maxSpread\n ]\n const liquidityResult = dynamicResults[14]\n const uniswapPoolLiquidity =\n liquidityResult?.status === 'success' ? BigInt(liquidityResult.result as bigint) : 0n\n\n // V3 poolKey() only contains the Uniswap pool address, so enrich the parsed\n // key with the immutable fee and tick spacing resolved by getPoolMetadata.\n const tickSpacing = metadata.tickSpacing\n const poolKey = {\n ...parsePoolKey(metadata.poolKeyBytes),\n fee: metadata.fee,\n tickSpacing,\n }\n\n // Annualize rates: interestRate() returns WAD/s, multiply by seconds/year\n const SECONDS_PER_YEAR = 31_536_000n\n const borrowRate0 = BigInt(token0InterestRate) * SECONDS_PER_YEAR\n const borrowRate1 = BigInt(token1InterestRate) * SECONDS_PER_YEAR\n const utilization0 = token0PoolData[3]\n const utilization1 = token1PoolData[3]\n // Supply rate = borrow rate * utilization (utilization is in bps, so /10000)\n const supplyRate0 = (borrowRate0 * utilization0) / 10000n\n const supplyRate1 = (borrowRate1 * utilization1) / 10000n\n const totalAssets0 = token0PoolData[0] + token0PoolData[1]\n const totalAssets1 = token1PoolData[0] + token1PoolData[1]\n\n // Build collateral trackers\n const collateralTracker0: CollateralTracker = {\n address: metadata.collateralToken0Address,\n token: metadata.token0Asset,\n symbol: metadata.token0Symbol,\n decimals: metadata.token0Decimals,\n totalAssets: totalAssets0,\n insideAMM: token0PoolData[1],\n creditedShares: token0PoolData[2],\n totalShares: token0TotalSupply,\n utilization: utilization0,\n borrowRate: borrowRate0,\n supplyRate: supplyRate0,\n }\n\n const collateralTracker1: CollateralTracker = {\n address: metadata.collateralToken1Address,\n token: metadata.token1Asset,\n symbol: metadata.token1Symbol,\n decimals: metadata.token1Decimals,\n totalAssets: totalAssets1,\n insideAMM: token1PoolData[1],\n creditedShares: token1PoolData[2],\n totalShares: token1TotalSupply,\n utilization: utilization1,\n borrowRate: borrowRate1,\n supplyRate: supplyRate1,\n }\n\n // Build risk engine\n const riskEngine: RiskEngine = {\n address: metadata.riskEngineAddress,\n collateralRequirement: sellerCollateralRatio,\n maintenanceMargin: maintMarginRate,\n commissionRate: BigInt(notionalFee),\n premiumFeeRate: BigInt(premiumFee),\n vegoid: BigInt(vegoid),\n maxSpread: BigInt(maxSpread),\n }\n\n // Determine health status based on safe mode\n const healthStatus = safeModeRaw === 0 ? 'active' : safeModeRaw === 1 ? 'low_liquidity' : 'paused'\n\n // sqrtPriceX96 from tick\n const sqrtPriceX96 = tickToSqrtPriceX96(BigInt(currentTick))\n\n return {\n address: poolAddress,\n chainId,\n poolId: metadata.poolId,\n poolKey,\n tickSpacing,\n collateralTracker0,\n collateralTracker1,\n riskEngine,\n currentTick: BigInt(currentTick),\n sqrtPriceX96,\n uniswapPoolLiquidity,\n healthStatus,\n metadata,\n _meta,\n }\n}\n\n/**\n * Parameters for getUtilization.\n */\nexport interface GetUtilizationParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched collateral tracker addresses (for caching/optimization) */\n collateralAddresses?: {\n collateralToken0: Address\n collateralToken1: Address\n }\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get current pool utilization for both tokens.\n *\n * ## Same-Block Guarantee\n * All dynamic data is fetched in ONE multicall at the target block.\n * Collateral tracker addresses are either provided or fetched separately (static prefetch).\n *\n * @param params - The parameters\n * @returns Utilization data with block metadata\n */\nexport async function getUtilization(params: GetUtilizationParams): Promise<Utilization> {\n const { client, poolAddress, blockNumber, collateralAddresses } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Get collateral tracker addresses (static prefetch if not provided)\n let collateralToken0: Address\n let collateralToken1: Address\n\n if (collateralAddresses) {\n collateralToken0 = collateralAddresses.collateralToken0\n collateralToken1 = collateralAddresses.collateralToken1\n } else {\n // Static prefetch - addresses are immutable\n const addressResults = await client.multicall({\n contracts: [\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken0',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken1',\n },\n ],\n allowFailure: false,\n })\n collateralToken0 = addressResults[0]\n collateralToken1 = addressResults[1]\n }\n\n // SINGLE multicall for ALL dynamic data - ensures same-block consistency\n const [poolDataResults, _meta] = await Promise.all([\n client.multicall({\n contracts: [\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'getPoolData',\n },\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'getPoolData',\n },\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'totalSupply',\n },\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'totalSupply',\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [poolData0, poolData1, totalSupply0, totalSupply1] = poolDataResults\n\n return {\n utilization0: poolData0[3], // currentPoolUtilization\n utilization1: poolData1[3],\n availableToBorrow0: availableToBorrow(poolData0, totalSupply0),\n availableToBorrow1: availableToBorrow(poolData1, totalSupply1),\n _meta,\n }\n}\n\n/**\n * Assets available to borrow from a collateral tracker.\n *\n * Mirrors `CollateralTracker._maxWithdrawWithPositions`: deposited assets less\n * one wei, less the assets backing credited shares.\n *\n * @param poolData - `getPoolData()` tuple: [depositedAssets, insideAMM, creditedShares, utilization]\n * @param totalSupply - Collateral tracker share supply, for the share→asset conversion\n */\nfunction availableToBorrow(\n poolData: readonly [bigint, bigint, bigint, bigint],\n totalSupply: bigint,\n): bigint {\n const [depositedAssets, insideAMM, creditedShares] = poolData\n const available = depositedAssets > 0n ? depositedAssets - 1n : 0n\n if (creditedShares === 0n || totalSupply === 0n) return available\n\n const totalAssets = depositedAssets + insideAMM\n const creditedAssets = (creditedShares * totalAssets) / totalSupply\n return available > creditedAssets ? available - creditedAssets : 0n\n}\n\n/**\n * Parameters for getOracleState.\n */\nexport interface GetOracleStateParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get current oracle state from the pool.\n *\n * ## Same-Block Guarantee\n * Single contract call + block meta fetch at the same block.\n *\n * @param params - The parameters\n * @returns Oracle state with block metadata\n */\nexport async function getOracleState(params: GetOracleStateParams): Promise<OracleState> {\n const { client, poolAddress, blockNumber } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Read the detailed oracle state and the canonical TWAP used by downstream\n // safety checks at the same block.\n const [[oracleTicks, twapTick], _meta] = await Promise.all([\n client.multicall({\n contracts: [\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getOracleTicks',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getTWAP',\n },\n ],\n allowFailure: false,\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n // oracleTicks returns: currentTick, spotTick, medianTick, latestTick, oraclePack\n const [currentTick, spotTick, medianTick, latestTick, oraclePack] = oracleTicks\n\n const decoded = decodeOraclePack(oraclePack, _meta.blockTimestamp)\n\n return {\n epoch: decoded.epoch,\n lastUpdateTimestamp: decoded.timestamp,\n // Deprecated OracleState alias; use currentTick or oracleReferenceTick.\n referenceTick: BigInt(currentTick),\n currentTick: BigInt(currentTick),\n oracleReferenceTick: decoded.referenceTick,\n latestTick: BigInt(latestTick),\n twapTick: BigInt(twapTick),\n spotEMA: BigInt(spotTick),\n fastEMA: decoded.fastEMA,\n slowEMA: decoded.slowEMA,\n eonsEMA: decoded.eonsEMA,\n lockMode: decoded.lockMode,\n medianTick: BigInt(medianTick),\n _meta,\n }\n}\n\nexport interface GetOracleRiskParametersParams {\n client: PublicClient\n riskEngineAddress: Address\n blockNumber?: bigint\n}\n\nexport interface OracleRiskParametersState extends OracleRiskParameters {\n _meta: BlockMeta\n}\n\n/** Read the oracle constants from a specific deployed RiskEngine. */\nexport async function getOracleRiskParameters(\n params: GetOracleRiskParametersParams,\n): Promise<OracleRiskParametersState> {\n const targetBlockNumber = params.blockNumber ?? (await params.client.getBlockNumber())\n const [[emaPeriods, maxTicksDelta, maxClampDelta], _meta] = await Promise.all([\n params.client.multicall({\n contracts: [\n {\n address: params.riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'EMA_PERIODS',\n },\n {\n address: params.riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'MAX_TICKS_DELTA',\n },\n {\n address: params.riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'MAX_CLAMP_DELTA',\n },\n ],\n allowFailure: false,\n blockNumber: targetBlockNumber,\n }),\n getBlockMeta({ client: params.client, blockNumber: targetBlockNumber }),\n ])\n return {\n ...decodeOracleRiskParameters(BigInt(emaPeriods), BigInt(maxTicksDelta), BigInt(maxClampDelta)),\n _meta,\n }\n}\n\n/**\n * Parameters for getRiskParameters.\n */\nexport interface GetRiskParametersParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Builder code (default: 0) */\n builderCode?: bigint\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched risk engine address (for caching/optimization) */\n riskEngineAddress?: Address\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get risk parameters from the pool.\n *\n * ## Same-Block Guarantee\n * All dynamic data is fetched in ONE multicall at the target block.\n * Risk engine address is either provided or fetched separately (static prefetch).\n *\n * @param params - The parameters\n * @returns Risk parameters with block metadata\n */\nexport async function getRiskParameters(params: GetRiskParametersParams): Promise<RiskParameters> {\n const {\n client,\n poolAddress,\n builderCode = 0n,\n blockNumber,\n riskEngineAddress: providedAddress,\n } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Get risk engine address (static prefetch if not provided)\n const riskEngineAddress =\n providedAddress ??\n (await client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'riskEngine',\n }))\n\n // SINGLE multicall for ALL risk parameters - ensures same-block consistency\n const [riskEngineResults, _meta] = await Promise.all([\n client.multicall({\n contracts: [\n {\n address: riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'SELLER_COLLATERAL_RATIO',\n },\n {\n address: riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'BUYER_COLLATERAL_RATIO',\n },\n {\n address: riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'MAINT_MARGIN_RATE',\n },\n {\n address: riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'NOTIONAL_FEE',\n },\n {\n address: riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'TARGET_POOL_UTIL',\n },\n {\n address: riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'SATURATED_POOL_UTIL',\n },\n // The mint-time margin buffer, read live rather than compiled in, so a\n // redeployed RiskEngine cannot silently desync the displayed \"required\n // at mint\" from what the solvency check actually enforces.\n {\n address: riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'BP_DECREASE_BUFFER',\n },\n {\n address: riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'DECIMALS',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getRiskParameters',\n args: [builderCode],\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [\n sellerCollateralRatio,\n buyerCollateralRatio,\n maintMarginRate,\n notionalFee,\n targetPoolUtil,\n saturatedPoolUtil,\n bpDecreaseBuffer,\n riskEngineDecimals,\n ,\n ] = riskEngineResults\n\n return {\n collateralRequirement: sellerCollateralRatio,\n maintenanceMargin: maintMarginRate,\n commissionRate: BigInt(notionalFee),\n targetUtilization: targetPoolUtil,\n saturatedUtilization: saturatedPoolUtil,\n itmSpreadMultiplier: buyerCollateralRatio, // Using buyer ratio as ITM multiplier\n // A live numerator is meaningful only with its live scale. If the scale is\n // invalid, fall back to the complete compiled-in ratio.\n mintBuffer:\n BigInt(riskEngineDecimals) > 0n\n ? { numerator: BigInt(bpDecreaseBuffer), denominator: BigInt(riskEngineDecimals) }\n : DEFAULT_MINT_BUFFER,\n _meta,\n }\n}\n\n// ---------------------------------------------------------------------------\n// Builder code validation\n// ---------------------------------------------------------------------------\n\n/**\n * Validate whether a builder code maps to a deployed builder wallet.\n *\n * Calls `PanopticPool.getRiskParameters(builderCode)` — the contract reverts\n * with `InvalidBuilderCode` when the computed CREATE2 address has no bytecode.\n *\n * @returns `true` when valid, `false` when the contract reverts.\n */\nexport async function validateBuilderCode(params: {\n client: PublicClient\n poolAddress: Address\n builderCode: bigint\n}): Promise<boolean> {\n const { client, poolAddress, builderCode } = params\n if (builderCode === 0n) return true\n try {\n await client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getRiskParameters',\n args: [builderCode],\n })\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Extract tickSpacing from the encoded 64-bit poolId.\n * Layout: poolAddress (5 bytes) + vegoid (1 byte) + tickSpacing (2 bytes).\n * tickSpacing occupies bits 48–63.\n */\nfunction tickSpacingFromPoolId(poolId: bigint): bigint {\n return (poolId >> 48n) & 0xffffn\n}\n\n/**\n * Parse pool key from ABI-encoded bytes.\n *\n * V4 pools: PoolKey struct is ABI-encoded as 5 consecutive 32-byte slots\n * (currency0, currency1, fee, tickSpacing, hooks).\n *\n * V3 pools: poolKey() returns abi.encode(uniswapV3PoolAddress) — a single\n * 32-byte slot. The struct fields are not available, so currency0/currency1\n * are zeroed and tickSpacing/fee are set to 0 (callers should use\n * getV3PoolTickSpacing and getV3PoolFee respectively).\n */\nfunction parsePoolKey(poolKeyBytes: `0x${string}`): PoolKey {\n const hex = poolKeyBytes.slice(2)\n\n // V3: single ABI-encoded address (64 hex chars = 32 bytes)\n if (hex.length <= 64) {\n return {\n currency0: zeroAddress,\n currency1: zeroAddress,\n fee: 0n,\n tickSpacing: 0n,\n hooks: zeroAddress,\n }\n }\n\n if (hex.length < 320) {\n throw new Error(`Malformed V4 pool key: expected 320 hex chars (160 bytes), got ${hex.length}`)\n }\n\n // Each slot is 64 hex chars (32 bytes)\n // Addresses are in the last 40 hex chars (20 bytes) of their slot\n // Numeric values can be parsed from the full 64 hex chars of their slot\n const currency0 = `0x${hex.slice(24, 64)}` as Address // Slot 0: chars 0-64, address at 24-64\n const currency1 = `0x${hex.slice(88, 128)}` as Address // Slot 1: chars 64-128, address at 88-128\n const fee = BigInt(`0x${hex.slice(128, 192)}`) // Slot 2: chars 128-192 (full slot)\n const tickSpacing = BigInt(`0x${hex.slice(192, 256)}`) // Slot 3: chars 192-256 (full slot)\n const hooks = `0x${hex.slice(280, 320)}` as Address // Slot 4: chars 256-320, address at 280-320\n\n return {\n currency0,\n currency1,\n fee,\n tickSpacing,\n hooks,\n }\n}\n\n/**\n * Parameters for fetchPoolId.\n */\nexport interface FetchPoolIdParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n}\n\n/**\n * Result of fetchPoolId, including block metadata for same-block consistency.\n */\nexport interface FetchPoolIdResult {\n /** The encoded 64-bit pool ID */\n poolId: bigint\n /** Block metadata from the pinned read */\n _meta: BlockMeta\n}\n\n/**\n * Fetch the encoded 64-bit pool ID from a PanopticPool contract.\n *\n * Use this when you need the poolId without fetching the full pool state.\n * The returned poolId can be passed directly to `createTokenIdBuilder()`.\n * The read is pinned to the latest block at call time.\n *\n * @param params - The parameters\n * @returns The pool ID and block metadata\n */\nexport async function fetchPoolId(params: FetchPoolIdParams): Promise<FetchPoolIdResult> {\n const { client, poolAddress } = params\n\n const block = await client.getBlock({ blockTag: 'latest' })\n\n const poolId = await client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'poolId',\n blockNumber: block.number,\n })\n\n return {\n poolId,\n _meta: {\n blockNumber: block.number,\n blockTimestamp: block.timestamp,\n blockHash: block.hash,\n },\n }\n}\n\nexport { tickToSqrtPriceX96 }\n","/**\n * Client-side greeks for the Panoptic v2 SDK.\n *\n * All functions accept bigint inputs (ticks, sizes) and return bigint values\n * in the natural token units — no artificial WAD scaling. The tick-based price\n * (1.0001^tick) naturally encodes the decimal conversion between tokens.\n *\n * Uses pure sqrtPriceX96 arithmetic for exact on-chain fidelity with PanopticQuery.\n * All intermediate calculations keep X96/X192 precision until final scaling.\n *\n * - Value: in numeraire token smallest units (e.g., USDC wei if numeraire is USDC)\n * - Delta: in asset token smallest units (e.g., WETH wei if asset is WETH)\n * - Gamma (dollar-gamma): in numeraire token smallest units\n *\n * @module v2/greeks\n */\n\nimport { tickToSqrtPriceX96 } from '../formatters/tick'\nimport type { TokenIdLeg } from '../types'\n\n// --- Internal Helpers ---\n\n/** Fixed-point scale constants for sqrtPriceX96 arithmetic */\nconst Q96 = 1n << 96n\nconst Q192 = 1n << 192n\n\n/**\n * Convert tick to quote-denominated tick based on asset direction.\n *\n * When isAssetToken0 = true (asset is token0, numeraire is token1):\n * - Tick already encodes price as token1/token0 (numeraire per asset)\n * - Return tick unchanged\n *\n * When isAssetToken0 = false (asset is token1, numeraire is token0):\n * - Tick encodes price as token1/token0, but we need token0/token1 (numeraire per asset)\n * - Invert by negating: 1/price = 1.0001^(-tick)\n */\nfunction quoteTick(tick: bigint, isAssetToken0: boolean): bigint {\n return isAssetToken0 ? tick : -tick\n}\n\n/**\n * Divide with truncation toward zero (matches Solidity division behavior).\n *\n * JavaScript bigint division uses floor (toward negative infinity), but Solidity\n * truncates toward zero. For on-chain fidelity, we must match Solidity.\n *\n * Example:\n * - Solidity: -7 / 2 = -3 (truncate toward zero)\n * - JS bigint: -7n / 2n = -4n (floor toward -∞)\n * - This function: divTrunc(-7n, 2n) = -3n ✓\n */\nfunction divTrunc(numerator: bigint, denominator: bigint): bigint {\n if (denominator === 0n) return 0n\n\n const quotient = numerator / denominator\n const remainder = numerator % denominator\n\n // If signs differ and there's a remainder, JS floored when we need to truncate\n // Add 1 to move toward zero\n if (numerator < 0n !== denominator < 0n && remainder !== 0n) {\n return quotient + 1n\n }\n\n return quotient\n}\n\n/** Resolve isAssetToken0: optional assetIndex overrides leg.asset */\nfunction resolveAssetDirection(leg: Pick<TokenIdLeg, 'asset'>, assetIndex?: bigint): boolean {\n return assetIndex !== undefined ? assetIndex === 0n : leg.asset === 0n\n}\n\n/**\n * Compute the tokenType-denominated notional of a width=0 (loan/credit) leg.\n *\n * When leg.asset !== leg.tokenType, positionSize is in leg.asset units and\n * the borrowed notional is encoded via leg.strike: notional_tokenType_raw =\n * positionSize_raw × 1.0001^strike (a raw-to-raw ratio, unquoted by pool direction).\n * When leg.asset === leg.tokenType, m is already the notional (old convention).\n *\n * `m > 0` for loans (isLong=false), `m < 0` for credits (isLong=true), so the\n * returned notional is signed the same way.\n */\nfunction computeWidth0Notional(leg: TokenIdLeg, m: bigint): bigint {\n const scaleByStrike = leg.asset !== leg.tokenType\n if (!scaleByStrike) return m\n // The UI stores strike with a sign that depends on leg.asset:\n // priceTokenTypePerAsset = 1.0001^(leg.asset === 0 ? strike : -strike)\n // Mirror that here so K_raw matches the intended notional scaling.\n const signedStrike = leg.asset === 0n ? leg.strike : -leg.strike\n const sqrtKraw = tickToSqrtPriceX96(signedStrike)\n const KrawX192 = sqrtKraw * sqrtKraw\n return divTrunc(m * KrawX192, Q192)\n}\n\n/**\n * Calculate value for a width=0 (loan/credit) leg.\n * Width=0 means the range is a single tick (the strike), so there's no meaningful\n * \"in range\" — we use the below/above formulas which avoid division by (r-1)=0.\n *\n * This is the DEBT-ONLY value (the borrowed/lent obligation), used by delta/greeks\n * aggregation where the held-collateral side lives in a separate wallet/CT term. For\n * a standalone payoff chart that must reflect the net user-experienced payoff (which\n * depends on Zap vs Cover-at-mint), use `getLegNetValueWidth0`.\n */\nfunction getLegValueWidth0(\n leg: TokenIdLeg,\n m: bigint,\n qCurrentTick: bigint,\n qStrikeTick: bigint,\n qMintTick: bigint,\n isAssetToken0: boolean,\n _definedRisk: boolean,\n): bigint {\n // For loan/credit legs (width=0), value depends on the borrowed token.\n // m > 0 for loans (isLong=false), m < 0 for credits (isLong=true).\n const borrowsAsset = isCall(leg.tokenType, isAssetToken0)\n\n const notional = computeWidth0Notional(leg, m)\n\n if (borrowsAsset) {\n // Asset loan/credit: debt PnL = -notional*(P - Pm); crosses y=0 at mint price, delta=-notional.\n const sqrtP = tickToSqrtPriceX96(qCurrentTick)\n const sqrtPm = tickToSqrtPriceX96(qMintTick)\n const PX192 = sqrtP * sqrtP\n const PmX192 = sqrtPm * sqrtPm\n return divTrunc(-notional * (PX192 - PmX192), Q192)\n } else {\n // Numeraire loan/credit: the obligation is a constant amount of the numeraire token,\n // so its value doesn't change with price. getLegValue is mint-relative PnL (option\n // legs cancel the mint baseline via `itm`; the asset branch above returns\n // -notional*(P - Pm), which is 0 at mint), so the numeraire branch's mint-relative PnL\n // is value(P) - value(Pm) = const - const = 0. Returning a nonzero constant here would\n // shift the whole PnL curve/baseline by the notional (double-counting the credit).\n return 0n\n }\n}\n\n/**\n * Calculate the NET (user-experienced) payoff value for a width=0 (loan/credit) leg.\n *\n * Unlike `getLegValueWidth0` (debt-only), this includes the collateral/holding side and\n * therefore depends on how the position was opened:\n *\n * - **Cover at mint** (`swapAtMint = false`): the collateral is sourced in the SAME token as\n * the debt/credit, so the holding side exactly offsets it → net PnL is FLAT (0 everywhere,\n * mint-relative), regardless of which token the leg is denominated in.\n * - **Zap** (`swapAtMint = true`): the collateral is sourced in the OTHER token, leaving a\n * ±1-delta line in the asset (ETH), anchored to 0 at the mint price:\n * - USDC loan → zap to ETH: +1 (long ETH)\n * - ETH loan → zap to USDC: −1 (short ETH)\n * - USDC credit ← zap from ETH: −1 (short ETH)\n * - ETH credit ← zap from USDC: +1 (long ETH)\n *\n * @returns Net leg value in numeraire token smallest units (mint-relative PnL).\n */\nexport function getLegNetValueWidth0(\n leg: TokenIdLeg,\n m: bigint,\n qCurrentTick: bigint,\n qMintTick: bigint,\n isAssetToken0: boolean,\n swapAtMint: boolean,\n itmOffsetNotional: bigint = 0n,\n): bigint {\n // Cover at mint: collateral in the same token as the debt/credit cancels it → flat.\n if (!swapAtMint) return 0n\n\n const borrowsAsset = isCall(leg.tokenType, isAssetToken0)\n\n // ITM-neutralizing credits/loans are sized to offset an option leg's mint-time ITM,\n // which was zapped into the other token under swapAtMint and therefore carries the same\n // ±delta line this leg would otherwise add. Net the leg's notional against that ITM\n // (`itmOffsetNotional`, same token side, opposite sign) so a correctly-sized credit\n // cancels to flat and only the residual (over/under-sizing) contributes a swap line.\n const notional = computeWidth0Notional(leg, m) + itmOffsetNotional\n\n const sqrtP = tickToSqrtPriceX96(qCurrentTick)\n const sqrtPm = tickToSqrtPriceX96(qMintTick)\n const PX192 = sqrtP * sqrtP\n const PmX192 = sqrtPm * sqrtPm\n\n if (borrowsAsset) {\n // Debt/credit is in the asset (ETH); zapping the collateral into the numeraire leaves the\n // debt-only asset exposure -notional*(P - Pm). (Loan → short ETH; credit → long ETH.)\n return divTrunc(-notional * (PX192 - PmX192), Q192)\n }\n\n // Debt/credit is in the numeraire (USDC); zapping sources/spends the asset (ETH). We hold\n // notional/Pm units of ETH, worth (notional/Pm)*(P - Pm) = notional*(P/Pm) - notional in\n // numeraire. (Loan → long ETH; credit → short ETH.) Zero at mint by construction.\n return divTrunc(notional * PX192, PmX192) - notional\n}\n\n/**\n * Compute the mint-time ITM (in-the-money) adjustment for an option leg.\n *\n * This is the `itm` baseline used by {@link getLegValue}: the amount by which the\n * position was already ITM at mint, expressed in the leg's natural units:\n * - Puts: numeraire units (added directly to the put's `debt*K + v` value).\n * - Calls: asset-ratio units (the call value multiplies it by price: `itm*P`/`itm*Pm`).\n *\n * Extracted so callers (e.g. {@link calculatePositionValue}) can build a per-side ITM\n * notional pool to net width=0 credit/loan legs against — an ITM-neutralizing credit\n * was sized to offset exactly this amount, so it should not add a spurious swap line.\n */\nfunction computeOptionItm(\n m: bigint,\n qStrikeTick: bigint,\n qMintTick: bigint,\n halfWidthTick: bigint,\n isPut: boolean,\n): bigint {\n if (isPut) {\n // Put ITM adjustment\n if (qMintTick < qStrikeTick - halfWidthTick) {\n // Below range: itm = (K - Pm) * m\n const sqrtK = tickToSqrtPriceX96(qStrikeTick)\n const sqrtPm = tickToSqrtPriceX96(qMintTick)\n const KX192 = sqrtK * sqrtK\n const PmX192 = sqrtPm * sqrtPm\n return divTrunc(m * (KX192 - PmX192), Q192)\n } else if (qMintTick > qStrikeTick + halfWidthTick) {\n // Above range: itm = 0\n return 0n\n }\n // In range: itm = m * (sqrt(K*r) - sqrt(Pm))^2 / (r - 1)\n const sqrtKR = tickToSqrtPriceX96(qStrikeTick + halfWidthTick)\n const sqrtPm = tickToSqrtPriceX96(qMintTick)\n const sqrtR = tickToSqrtPriceX96(halfWidthTick)\n const rX192 = sqrtR * sqrtR\n const diff = sqrtKR - sqrtPm // X96\n const diffSqX192 = diff * diff // X192\n return divTrunc(m * diffSqX192, rX192 - Q192)\n }\n\n // Call ITM adjustment\n if (qMintTick < qStrikeTick - halfWidthTick) {\n // Below range: itm = 0\n return 0n\n } else if (qMintTick > qStrikeTick + halfWidthTick) {\n // Above range: itm = (1 - K/Pm) * m\n const sqrtK = tickToSqrtPriceX96(qStrikeTick)\n const sqrtPm = tickToSqrtPriceX96(qMintTick)\n const KX192 = sqrtK * sqrtK\n const PmX192 = sqrtPm * sqrtPm\n return divTrunc(m * (PmX192 - KX192), PmX192)\n }\n // In range: itm = m * (sqrt(r) - sqrt(K/Pm))^2 / (r - 1)\n const sqrtR = tickToSqrtPriceX96(halfWidthTick)\n const sqrtK = tickToSqrtPriceX96(qStrikeTick)\n const sqrtPm = tickToSqrtPriceX96(qMintTick)\n const rX192 = sqrtR * sqrtR\n // sqrt(K/Pm) in X96 = sqrtK * 2^96 / sqrtPm\n const sqrtKPmX96 = divTrunc(sqrtK * Q96, sqrtPm)\n const diff = sqrtR - sqrtKPmX96 // X96\n const diffSqX192 = diff * diff // X192\n return divTrunc(m * diffSqX192, rX192 - Q192)\n}\n\n// --- Public Helpers ---\n\n/**\n * Check if leg is a call option (vs put).\n *\n * A call is when the leg moves the asset token:\n * - If asset is token0: call when tokenType=0\n * - If asset is token1: call when tokenType=1\n */\nexport function isCall(tokenType: bigint, isAssetToken0: boolean): boolean {\n return isAssetToken0 ? tokenType === 0n : tokenType === 1n\n}\n\n/**\n * Check if position has defined risk (is a spread).\n *\n * A position is defined risk if it has 2+ legs of the same tokenType\n * with both long and short exposure.\n */\nexport function isDefinedRisk(legs: Pick<TokenIdLeg, 'tokenType' | 'isLong'>[]): boolean {\n if (legs.length < 2) return false\n\n for (const tt of [0n, 1n]) {\n const group = legs.filter((l) => l.tokenType === tt)\n if (group.length >= 2 && group.some((l) => l.isLong) && group.some((l) => !l.isLong)) {\n return true\n }\n }\n return false\n}\n\n// --- Per-Leg Greeks ---\n\n/**\n * Calculate the value of a single leg.\n *\n * Value represents the current P&L of the position in numeraire token units.\n * Combines base value (from Panoptic's piecewise formula), debt, and ITM adjustment.\n *\n * Uses sqrtPriceX96 for all calculations to maintain precision and on-chain fidelity.\n *\n * @param leg - The leg to calculate\n * @param currentTick - Current pool tick\n * @param mintTick - Tick at position mint\n * @param positionSize - Position size in asset token smallest units\n * @param poolTickSpacing - Pool tick spacing\n * @param definedRisk - Whether position is defined risk\n * @param assetIndex - Optional override for leg.asset (0n = token0 is asset, 1n = token1)\n * @returns Leg value in numeraire token smallest units\n */\nexport function getLegValue(\n leg: TokenIdLeg,\n currentTick: bigint,\n mintTick: bigint,\n positionSize: bigint,\n poolTickSpacing: bigint,\n definedRisk: boolean,\n assetIndex?: bigint,\n swapAtMint?: boolean,\n): bigint {\n const isAssetToken0 = resolveAssetDirection(leg, assetIndex)\n const qCurrentTick = quoteTick(currentTick, isAssetToken0)\n const qMintTick = quoteTick(mintTick, isAssetToken0)\n const qStrikeTick = quoteTick(leg.strike, isAssetToken0)\n const halfWidthTick = (leg.width * poolTickSpacing) / 2n\n\n const m = leg.isLong ? -(positionSize * leg.optionRatio) : positionSize * leg.optionRatio\n\n // True loan/credit (leg.width === 0n): when the caller specifies how the position was\n // opened (swapAtMint), return the NET user-experienced payoff (Zap vs Cover) instead of\n // the debt-only value. Narrow options whose halfWidth rounds to 0 are excluded.\n if (leg.width === 0n && swapAtMint !== undefined) {\n return getLegNetValueWidth0(leg, m, qCurrentTick, qMintTick, isAssetToken0, swapAtMint)\n }\n\n // Width=0 (loans/credits): single-tick position, no range to integrate over.\n if (halfWidthTick === 0n) {\n return getLegValueWidth0(\n leg,\n m,\n qCurrentTick,\n qStrikeTick,\n qMintTick,\n isAssetToken0,\n definedRisk,\n )\n }\n\n // Compute base value: v = f(P, K, r) from Panoptic's piecewise formula\n let v: bigint\n\n if (qCurrentTick < qStrikeTick - halfWidthTick) {\n // Below range: v = m * P\n const sqrtP = tickToSqrtPriceX96(qCurrentTick)\n const PX192 = sqrtP * sqrtP\n v = divTrunc(m * PX192, Q192)\n } else if (qCurrentTick > qStrikeTick + halfWidthTick) {\n // Above range: v = m * K\n const sqrtK = tickToSqrtPriceX96(qStrikeTick)\n const KX192 = sqrtK * sqrtK\n v = divTrunc(m * KX192, Q192)\n } else {\n // In range: v = m * (2*sqrt(P*K*r) - P - K) / (r - 1)\n const sqrtP = tickToSqrtPriceX96(qCurrentTick)\n const sqrtK = tickToSqrtPriceX96(qStrikeTick)\n const sqrtPKR = tickToSqrtPriceX96(qCurrentTick + qStrikeTick + halfWidthTick)\n const sqrtR = tickToSqrtPriceX96(halfWidthTick)\n\n const PX192 = sqrtP * sqrtP\n const KX192 = sqrtK * sqrtK\n const rX192 = sqrtR * sqrtR\n\n // v = m * (2*sqrtPKR/2^96 - PX192/2^192 - KX192/2^192) / ((rX192 - 2^192)/2^192)\n // = m * (2*sqrtPKR*2^96 - PX192 - KX192) / (rX192 - 2^192)\n const numerator = m * (2n * sqrtPKR * Q96 - PX192 - KX192)\n const denominator = rX192 - Q192\n v = divTrunc(numerator, denominator)\n }\n\n const debt = -m\n const isPut = !isCall(leg.tokenType, isAssetToken0)\n\n // Compute ITM adjustment (differs for puts vs calls)\n const itm = computeOptionItm(m, qStrikeTick, qMintTick, halfWidthTick, isPut)\n\n // Compute final result based on option type\n if (isPut) {\n // Put: result = debt * K + v + itm\n const sqrtK = tickToSqrtPriceX96(qStrikeTick)\n const KX192 = sqrtK * sqrtK\n const debtK = divTrunc(debt * KX192, Q192)\n return debtK + v + itm\n } else {\n // Call: result = debt*P + v + itm*Pm (if defined risk) or debt*P + v + itm*P (if not)\n const sqrtP = tickToSqrtPriceX96(qCurrentTick)\n const PX192 = sqrtP * sqrtP\n const debtP = divTrunc(debt * PX192, Q192)\n\n if (definedRisk) {\n const sqrtPm = tickToSqrtPriceX96(qMintTick)\n const PmX192 = sqrtPm * sqrtPm\n const itmPm = divTrunc(itm * PmX192, Q192)\n return debtP + v + itmPm\n } else {\n const itmP = divTrunc(itm * PX192, Q192)\n return debtP + v + itmP\n }\n }\n}\n\n/**\n * Calculate the delta of a single leg.\n *\n * Delta is the rate of change of position value with respect to price.\n * For puts: delta = vDelta\n * For calls: delta = debtDelta + vDelta + itmDelta (if not defined risk)\n *\n * Uses sqrtPriceX96 for all price calculations to maintain precision.\n *\n * @param leg - The leg to calculate\n * @param currentTick - Current pool tick\n * @param positionSize - Position size in asset token smallest units\n * @param poolTickSpacing - Pool tick spacing\n * @param mintTick - Tick at mint (optional, for ITM adjustment)\n * @param definedRisk - Whether position is defined risk\n * @param assetIndex - Optional override for leg.asset (0n = token0 is asset, 1n = token1)\n * @returns Leg delta in asset token smallest units\n */\nexport function getLegDelta(\n leg: TokenIdLeg,\n currentTick: bigint,\n positionSize: bigint,\n poolTickSpacing: bigint,\n mintTick: bigint | undefined,\n definedRisk: boolean,\n assetIndex?: bigint,\n): bigint {\n const isAssetToken0 = resolveAssetDirection(leg, assetIndex)\n const qCurrentTick = quoteTick(currentTick, isAssetToken0)\n const qStrikeTick = quoteTick(leg.strike, isAssetToken0)\n const halfWidthTick = (leg.width * poolTickSpacing) / 2n\n\n const m = leg.isLong ? -(positionSize * leg.optionRatio) : positionSize * leg.optionRatio\n\n // True loan/credit: leg.width === 0n (not just halfWidth rounding to 0).\n // Debt-side exposure only — no option-like piecewise formula.\n if (leg.width === 0n) {\n const borrowsAsset = isAssetToken0 ? leg.tokenType === 0n : leg.tokenType === 1n\n if (!borrowsAsset) return 0n\n // See getLegValueWidth0 for the notional-scaling rationale.\n if (leg.asset === leg.tokenType) return -m\n const signedStrike = leg.asset === 0n ? leg.strike : -leg.strike\n const sqrtKraw = tickToSqrtPriceX96(signedStrike)\n const KrawX192 = sqrtKraw * sqrtKraw\n const notional = divTrunc(m * KrawX192, Q192)\n return -notional\n }\n\n // Narrow option whose halfWidth rounds to 0: use option-like width=0 branch\n if (halfWidthTick === 0n) {\n const vDelta = qCurrentTick <= qStrikeTick ? m : 0n\n const isPut = !isCall(leg.tokenType, isAssetToken0)\n if (isPut) return vDelta\n\n // Call: add debt delta and ITM delta (same as normal path but no in-range branch)\n const debtDelta = -m\n let itmDelta = 0n\n if (mintTick !== undefined && !definedRisk) {\n const qMintTick = quoteTick(mintTick, isAssetToken0)\n if (qMintTick > qStrikeTick) {\n const sqrtPm = tickToSqrtPriceX96(qMintTick)\n const sqrtK = tickToSqrtPriceX96(qStrikeTick)\n const PmX192 = sqrtPm * sqrtPm\n const KX192 = sqrtK * sqrtK\n itmDelta = divTrunc((PmX192 - KX192) * m, PmX192)\n }\n }\n return definedRisk ? debtDelta + vDelta : debtDelta + vDelta + itmDelta\n }\n\n // Compute vDelta: derivative of value with respect to price\n // vDelta = P < lo ? m : P > hi ? 0 : (m * (sqrt(K*r)/sqrt(P) - 1)) / (r - 1)\n let vDelta: bigint\n\n if (qCurrentTick < qStrikeTick - halfWidthTick) {\n // Below range: vDelta = m\n vDelta = m\n } else if (qCurrentTick > qStrikeTick + halfWidthTick) {\n // Above range: vDelta = 0\n vDelta = 0n\n } else {\n // In range: vDelta = m * (sqrt(K*r) - sqrt(P)) / (sqrt(P) * (r - 1))\n const sqrtP = tickToSqrtPriceX96(qCurrentTick) // X96\n const sqrtKR = tickToSqrtPriceX96(qStrikeTick + halfWidthTick) // sqrt(K*r) in X96\n const sqrtR = tickToSqrtPriceX96(halfWidthTick) // X96\n const rX192 = sqrtR * sqrtR // X192\n\n // vDelta = m * (sqrtKR - sqrtP)/2^96 / (sqrtP/2^96 * (rX192 - 2^192)/2^192)\n // = m * (sqrtKR - sqrtP) * 2^192 / (sqrtP * (rX192 - 2^192))\n const numerator = m * (sqrtKR - sqrtP) * Q192\n const denominator = sqrtP * (rX192 - Q192)\n vDelta = divTrunc(numerator, denominator)\n }\n\n const isPut = !isCall(leg.tokenType, isAssetToken0)\n\n if (isPut) {\n return vDelta\n }\n\n // Call: add debt delta and ITM delta\n const debtDelta = -m\n\n const itmDelta =\n mintTick === undefined\n ? 0n\n : (() => {\n const qMintTick = quoteTick(mintTick, isAssetToken0)\n\n if (qMintTick < qStrikeTick - halfWidthTick) {\n // Below range: itmDelta = 0\n return 0n\n } else if (qMintTick > qStrikeTick + halfWidthTick) {\n // Above range: itmDelta = (1 - K/Pm) * m = (Pm - K) * m / Pm\n const sqrtPm = tickToSqrtPriceX96(qMintTick) // X96\n const sqrtK = tickToSqrtPriceX96(qStrikeTick) // X96\n const PmX192 = sqrtPm * sqrtPm // X192\n const KX192 = sqrtK * sqrtK // X192\n\n // itmDelta = (1 - K/Pm) * m = (PmX192 - KX192) * m / PmX192\n return divTrunc((PmX192 - KX192) * m, PmX192)\n } else {\n // In range: itmDelta = m * (sqrt(r) - sqrt(K/Pm))^2 / (r - 1)\n const sqrtR = tickToSqrtPriceX96(halfWidthTick) // X96\n const sqrtK = tickToSqrtPriceX96(qStrikeTick) // X96\n const sqrtPm = tickToSqrtPriceX96(qMintTick) // X96\n const rX192 = sqrtR * sqrtR // X192\n\n // sqrt(K/Pm) = sqrtK / sqrtPm (both X96, so scale cancels)\n // But we need (sqrt(r) - sqrt(K/Pm))^2, so work in X96:\n // sqrtKPm = sqrt(K/Pm) in X96 = sqrtK * 2^96 / sqrtPm\n const sqrtKPmX96 = (sqrtK * Q96) / sqrtPm // X96\n\n // (sqrt(r) - sqrt(K/Pm))^2 = (sqrtR - sqrtKPmX96)^2 / 2^192\n const diff = sqrtR - sqrtKPmX96 // X96\n const diffSqX192 = diff * diff // X192\n\n // itmDelta = m * diffSqX192 / 2^192 / (rX192 / 2^192 - 1)\n // = m * diffSqX192 / (rX192 - 2^192)\n return divTrunc(m * diffSqX192, rX192 - Q192)\n }\n })()\n\n return definedRisk ? debtDelta + vDelta : debtDelta + vDelta + itmDelta\n}\n\n/** Convert a delta between token frames at the current pool tick. */\nexport function toVaultFrameAtTick(\n delta: bigint,\n fromAsset: bigint,\n vaultAssetIndex: 0n | 1n,\n currentTick: bigint,\n flipSignOnAssetInversion = false,\n): bigint {\n if (fromAsset === vaultAssetIndex) return delta\n const sqrtPriceX96 = tickToSqrtPriceX96(currentTick)\n const converted =\n vaultAssetIndex === 0n\n ? (delta * Q192) / (sqrtPriceX96 * sqrtPriceX96)\n : (delta * sqrtPriceX96 * sqrtPriceX96) / Q192\n return flipSignOnAssetInversion ? -converted : converted\n}\n\n/**\n * Calculate one leg's wallet-aware delta in the vault asset frame.\n *\n * Width-zero loans and credits must be evaluated directly in the vault frame.\n * Option legs remain in their natural leg frame until converted at the mark tick.\n */\nexport function getLegDeltaInVaultFrame(\n leg: TokenIdLeg,\n currentTick: bigint,\n positionSize: bigint,\n poolTickSpacing: bigint,\n mintTick: bigint | undefined,\n definedRisk: boolean,\n vaultAssetIndex: 0n | 1n,\n): bigint {\n if (leg.width === 0n) {\n return getLegDelta(\n leg,\n currentTick,\n positionSize,\n poolTickSpacing,\n mintTick,\n definedRisk,\n vaultAssetIndex,\n )\n }\n\n const legDelta = getLegDelta(\n leg,\n currentTick,\n positionSize,\n poolTickSpacing,\n mintTick,\n definedRisk,\n )\n return toVaultFrameAtTick(legDelta, leg.asset, vaultAssetIndex, currentTick, true)\n}\n\n/**\n * Calculate the gamma (dollar gamma) of a single leg.\n *\n * Formula: gamma = (m * sqrt(K * P * r)) / (2 * (r - 1))\n * where:\n * - m = positionSize * optionRatio (with sign based on long/short)\n * - K = strike price (numeraire/asset)\n * - P = current price (numeraire/asset)\n * - r = 1.0001^(width*tickSpacing/2) ≈ 1 (dimensionless ratio)\n *\n * Uses sqrtPriceX96 arithmetic:\n * - sqrt(K*P*r) = tickToSqrtPriceX96(strikeₜ + currentₜ + widthₜ/2)\n * - Keeps X96/X192 precision until final division\n *\n * @param leg - The leg to calculate\n * @param currentTick - Current pool tick\n * @param positionSize - Position size in asset token smallest units\n * @param poolTickSpacing - Pool tick spacing\n * @param assetIndex - Optional override for leg.asset (0n = token0 is asset, 1n = token1)\n * @returns Leg gamma in numeraire token smallest units\n */\nexport function getLegGamma(\n leg: TokenIdLeg,\n currentTick: bigint,\n positionSize: bigint,\n poolTickSpacing: bigint,\n assetIndex?: bigint,\n): bigint {\n const isAssetToken0 = resolveAssetDirection(leg, assetIndex)\n\n // Convert to quote-denominated ticks (negate if asset is token0)\n const qCurrentTick = quoteTick(currentTick, isAssetToken0)\n const qStrikeTick = quoteTick(leg.strike, isAssetToken0)\n const halfWidthTick = (leg.width * poolTickSpacing) / 2n\n\n // True loan: no gamma\n if (leg.width === 0n) return 0n\n\n // Narrow option whose halfWidth rounds to 0: no curvature (denominator 2*(r-1)=0)\n if (halfWidthTick === 0n) return 0n\n\n // Range check: gamma is zero outside [strike - halfWidth, strike + halfWidth]\n // This works in both normal and inverted tick space\n if (qCurrentTick < qStrikeTick - halfWidthTick || qCurrentTick > qStrikeTick + halfWidthTick) {\n return 0n\n }\n\n // Position size with sign: gamma uses inverted multiplier (long = positive, short = negative)\n const m = leg.isLong ? positionSize * leg.optionRatio : -(positionSize * leg.optionRatio)\n\n // sqrt(K * P * r) using tick addition: sqrt(K*P*r) = sqrt(1.0001^(K_tick + P_tick + r_tick))\n const sqrtKPR = tickToSqrtPriceX96(qStrikeTick + qCurrentTick + halfWidthTick) // X96 scale\n\n // r = 1.0001^(halfWidthTick), compute as (sqrtR)^2 to maintain precision\n const sqrtR = tickToSqrtPriceX96(halfWidthTick) // X96 scale\n const rX192 = sqrtR * sqrtR // X192 scale: r * 2^192\n\n // gamma = m * sqrt(K*P*r) / (2 * (r - 1))\n // = m * (sqrtKPR / 2^96) / (2 * (rX192/2^192 - 1))\n // = m * sqrtKPR * 2^192 / (2^96 * 2 * (rX192 - 2^192))\n // = m * sqrtKPR * 2^96 / (2 * (rX192 - 2^192))\n const numerator = m * sqrtKPR * Q96 // [asset] * [numeraire/asset * 2^96] * 2^96 = [numeraire * 2^192]\n const denominator = 2n * (rX192 - Q192) // 2 * (r - 1) in X192 scale\n\n return divTrunc(numerator, denominator) // [numeraire]\n}\n\n// --- Position-Level Aggregates ---\n\n/**\n * Parameters for position-level greek calculations.\n */\nexport interface PositionGreeksInput {\n /** Position legs */\n legs: TokenIdLeg[]\n /** Current pool tick */\n currentTick: bigint\n /** Tick at position mint */\n mintTick: bigint\n /** Position size in asset token smallest units */\n positionSize: bigint\n /** Pool tick spacing */\n poolTickSpacing: bigint\n /** Optional override for leg.asset on all legs (0n = token0 is asset, 1n = token1) */\n assetIndex?: bigint\n /**\n * How width=0 (loan/credit) legs were opened. When provided, `calculatePositionValue`\n * returns the NET user-experienced payoff for those legs (Zap = ±1 line, Cover = flat)\n * instead of the debt-only value. Leave undefined for delta/greeks aggregation, which\n * accounts for the held collateral separately.\n */\n swapAtMint?: boolean\n}\n\n/**\n * Calculate total value across all legs.\n */\nexport function calculatePositionValue(input: PositionGreeksInput): bigint {\n const { legs, currentTick, mintTick, positionSize, poolTickSpacing, assetIndex, swapAtMint } =\n input\n const definedRisk = isDefinedRisk(legs)\n\n // Fast path: without swapAtMint there is no width=0 net-payoff (delta/greeks aggregation),\n // so no ITM netting is needed — value each leg independently.\n if (swapAtMint === undefined) {\n return legs.reduce(\n (sum, leg) =>\n sum +\n getLegValue(\n leg,\n currentTick,\n mintTick,\n positionSize,\n poolTickSpacing,\n definedRisk,\n assetIndex,\n swapAtMint,\n ),\n 0n,\n )\n }\n\n // Pass 1: accumulate each option leg's mint-time ITM into a per-side notional pool. Under\n // swapAtMint the ITM was zapped into the other token, so a width=0 credit/loan that was\n // created to neutralize it (see getLegNetValueWidth0) should net against this pool instead\n // of adding a duplicate swap line. Puts contribute numeraire ITM; calls contribute asset ITM.\n let numeraireItmPool = 0n\n let assetItmPool = 0n\n for (const leg of legs) {\n const halfWidthTick = (leg.width * poolTickSpacing) / 2n\n if (leg.width === 0n || halfWidthTick === 0n) continue // not a valued option leg\n const isAssetToken0 = resolveAssetDirection(leg, assetIndex)\n const qStrikeTick = quoteTick(leg.strike, isAssetToken0)\n const qMintTick = quoteTick(mintTick, isAssetToken0)\n const m = leg.isLong ? -(positionSize * leg.optionRatio) : positionSize * leg.optionRatio\n const isPut = !isCall(leg.tokenType, isAssetToken0)\n const itm = computeOptionItm(m, qStrikeTick, qMintTick, halfWidthTick, isPut)\n if (isPut) numeraireItmPool += itm\n else assetItmPool += itm\n }\n\n // Pass 2: sum leg values, netting width=0 legs against the matching ITM pool (consumed once).\n let sum = 0n\n for (const leg of legs) {\n if (leg.width === 0n) {\n const isAssetToken0 = resolveAssetDirection(leg, assetIndex)\n const borrowsAsset = isCall(leg.tokenType, isAssetToken0)\n const offset = borrowsAsset ? assetItmPool : numeraireItmPool\n if (borrowsAsset) assetItmPool = 0n\n else numeraireItmPool = 0n\n const qCurrentTick = quoteTick(currentTick, isAssetToken0)\n const qMintTick = quoteTick(mintTick, isAssetToken0)\n const m = leg.isLong ? -(positionSize * leg.optionRatio) : positionSize * leg.optionRatio\n sum += getLegNetValueWidth0(\n leg,\n m,\n qCurrentTick,\n qMintTick,\n isAssetToken0,\n swapAtMint,\n offset,\n )\n } else {\n sum += getLegValue(\n leg,\n currentTick,\n mintTick,\n positionSize,\n poolTickSpacing,\n definedRisk,\n assetIndex,\n swapAtMint,\n )\n }\n }\n return sum\n}\n\n/**\n * Calculate total delta across all legs.\n */\nexport function calculatePositionDelta(input: PositionGreeksInput): bigint {\n const { legs, currentTick, mintTick, positionSize, poolTickSpacing, assetIndex } = input\n const definedRisk = isDefinedRisk(legs)\n\n return legs.reduce(\n (sum, leg) =>\n sum +\n getLegDelta(\n leg,\n currentTick,\n positionSize,\n poolTickSpacing,\n mintTick,\n definedRisk,\n assetIndex,\n ),\n 0n,\n )\n}\n\n/**\n * Calculate debt-only position delta in a single target asset frame.\n *\n * Option legs are first valued in their natural `leg.asset` frame, then\n * converted into `assetIndex` using the current pool price. Width-zero legs\n * are evaluated directly in the target frame.\n *\n * Width=0 loan/credit legs include only their debt obligation. The held-token\n * side must be added separately from account collateral balances, preventing a\n * zap from being counted once in the position and again in collateral.\n */\nexport function calculatePositionDeltaDebtOnly(\n input: Omit<PositionGreeksInput, 'assetIndex' | 'swapAtMint'> & {\n assetIndex: 0n | 1n\n },\n): bigint {\n const { legs, currentTick, mintTick, positionSize, poolTickSpacing, assetIndex } = input\n const definedRisk = isDefinedRisk(legs)\n\n return legs.reduce(\n (sum, leg) =>\n sum +\n getLegDeltaInVaultFrame(\n leg,\n currentTick,\n positionSize,\n poolTickSpacing,\n mintTick,\n definedRisk,\n assetIndex,\n ),\n 0n,\n )\n}\n\n/**\n * Calculate total gamma across all legs.\n */\nexport function calculatePositionGamma(input: PositionGreeksInput): bigint {\n const { legs, currentTick, positionSize, poolTickSpacing, assetIndex } = input\n\n return legs.reduce(\n (sum, leg) => sum + getLegGamma(leg, currentTick, positionSize, poolTickSpacing, assetIndex),\n 0n,\n )\n}\n\n/**\n * Position greeks result.\n */\nexport interface PositionGreeksResult {\n /** Position value in numeraire token smallest units */\n value: bigint\n /** Position delta in asset token smallest units */\n delta: bigint\n /** Position gamma in numeraire token smallest units */\n gamma: bigint\n}\n\n/**\n * Calculate all greeks for a position.\n */\nexport function calculatePositionGreeks(input: PositionGreeksInput): PositionGreeksResult {\n return {\n value: calculatePositionValue(input),\n delta: calculatePositionDelta(input),\n gamma: calculatePositionGamma(input),\n }\n}\n\n// --- Portfolio (Multi-Position) Aggregates ---\n\n/**\n * Aggregate value across multiple independent positions.\n *\n * Each entry is valued with its OWN `positionSize`, `mintTick`, and legs, then\n * summed. Do NOT collapse multiple positions into one synthetic `PositionGreeksInput`\n * with a shared `positionSize` — `m = positionSize * optionRatio` is per-position, so a\n * shared size double-counts (and integer `optionRatio` cannot encode fractional shares).\n *\n * @param positions - One `PositionGreeksInput` per open position\n * @returns Total value in numeraire token smallest units\n */\nexport function calculatePortfolioValue(positions: PositionGreeksInput[]): bigint {\n return positions.reduce((sum, input) => sum + calculatePositionValue(input), 0n)\n}\n\n/**\n * Aggregate delta across multiple independent positions.\n *\n * See {@link calculatePortfolioValue} for why each position must keep its own\n * `positionSize` rather than being merged into one synthetic position.\n *\n * @param positions - One `PositionGreeksInput` per open position\n * @returns Total delta in asset token smallest units\n */\nexport function calculatePortfolioDelta(positions: PositionGreeksInput[]): bigint {\n return positions.reduce((sum, input) => sum + calculatePositionDelta(input), 0n)\n}\n\n/**\n * Aggregate gamma across multiple independent positions.\n *\n * See {@link calculatePortfolioValue} for why each position must keep its own\n * `positionSize` rather than being merged into one synthetic position.\n *\n * @param positions - One `PositionGreeksInput` per open position\n * @returns Total gamma in numeraire token smallest units\n */\nexport function calculatePortfolioGamma(positions: PositionGreeksInput[]): bigint {\n return positions.reduce((sum, input) => sum + calculatePositionGamma(input), 0n)\n}\n\n/**\n * Calculate all greeks aggregated across multiple independent positions.\n */\nexport function calculatePortfolioGreeks(positions: PositionGreeksInput[]): PositionGreeksResult {\n return {\n value: calculatePortfolioValue(positions),\n delta: calculatePortfolioDelta(positions),\n gamma: calculatePortfolioGamma(positions),\n }\n}\n\n// --- Loan/Credit Swap-Aware Delta ---\n\n/**\n * Calculate the effective delta of a loan leg accounting for swapAtMint.\n *\n * A loan borrows one token and (optionally) swaps it for the other at mint.\n * The net delta depends on whether the swap occurred:\n *\n * | Scenario | Result |\n * |-----------------------|-------------------------------------------------|\n * | No swap | 0n (hold what you owe, net zero) |\n * | Swap + borrows asset | -m (hold numeraire, owe asset → short exposure) |\n * | Swap + borrows numer. | +m (hold asset, owe numeraire → long exposure) |\n *\n * Only meaningful for legs with `width === 0n`. For options, use `getLegDelta`.\n *\n * @param leg - The loan leg\n * @param positionSize - Position size in asset token smallest units\n * @param swapAtMint - Whether the borrowed tokens were swapped at mint\n * @param assetIndex - Optional override for leg.asset (0n = token0 is asset)\n * @returns Effective delta in asset token smallest units\n */\nexport function getLoanEffectiveDelta(\n leg: TokenIdLeg,\n positionSize: bigint,\n swapAtMint: boolean,\n assetIndex?: bigint,\n): bigint {\n if (!swapAtMint) return 0n\n\n const isAssetToken0 = resolveAssetDirection(leg, assetIndex)\n const m = leg.isLong ? -(positionSize * leg.optionRatio) : positionSize * leg.optionRatio\n const borrowsAsset = isAssetToken0 ? leg.tokenType === 0n : leg.tokenType === 1n\n\n return borrowsAsset ? -m : m\n}\n\n/**\n * Calculate total delta for a position, using swap-aware delta for loan legs.\n *\n * For legs with `width === 0n` (loans/credits), uses `getLoanEffectiveDelta`\n * which accounts for the swapAtMint flag. For option legs (`width > 0n`),\n * uses the standard `getLegDelta`.\n *\n * @param input - Position greeks input plus swapAtMint flag\n * @returns Total delta in asset token smallest units\n */\nexport function calculatePositionDeltaWithSwap(\n input: PositionGreeksInput & { swapAtMint: boolean },\n): bigint {\n const { legs, currentTick, mintTick, positionSize, poolTickSpacing, assetIndex, swapAtMint } =\n input\n const optionLegs = legs.filter((l) => l.width !== 0n)\n const definedRisk = isDefinedRisk(optionLegs)\n\n return legs.reduce((sum, leg) => {\n if (leg.width === 0n) {\n return sum + getLoanEffectiveDelta(leg, positionSize, swapAtMint, assetIndex)\n }\n return (\n sum +\n getLegDelta(\n leg,\n currentTick,\n positionSize,\n poolTickSpacing,\n mintTick,\n definedRisk,\n assetIndex,\n )\n )\n }, 0n)\n}\n","import type { Address, Hex } from 'viem'\n\nimport { DEFAULT_VEGOID } from '../tokenId/constants'\n\nexport const vegoid = Number(DEFAULT_VEGOID)\n\nexport interface LegParams {\n index: number\n width: bigint\n optionRatio: bigint\n asset: bigint\n strike: bigint\n isLong: bigint // 0 if short, 1 if long\n tokenType: bigint // Which token (0|1 in underlying pool) is being moved\n riskPartner: bigint\n}\n\nexport const areLegsEqual = (leg1: LegParams, leg2: LegParams): boolean => {\n return (\n leg1.width === leg2.width &&\n leg1.optionRatio === leg2.optionRatio &&\n leg1.asset === leg2.asset &&\n leg1.strike === leg2.strike &&\n leg1.isLong === leg2.isLong &&\n leg1.tokenType === leg2.tokenType &&\n leg1.riskPartner === leg2.riskPartner\n )\n}\n\nexport const stringifyLeg = (leg: LegParams): string => {\n return `Index: ${leg.index} | Width: ${leg.width.toString()} | OptionRatio: ${leg.optionRatio.toString()} | Asset: ${leg.asset.toString()} | Strike: ${leg.strike.toString()} | IsLong?: ${leg.isLong.toString()} | Token Type: ${leg.tokenType.toString()} | Risk Partner: ${leg.riskPartner.toString()}`\n}\n\n// Synthetic TokenIds padding constant\nexport const SYNTH_TOKENID_PADDING = BigInt(\n '115792089237316195423570985007226406215939081747436879206741300988257197096960',\n)\n\nconst POOL_ID_SIZE = 64n\nconst VEGOID_STARTING_BIT = 40n\nconst VEGOID_SIZE = 8n\nconst TICK_SPACING_STARTING_BIT = 48n\nconst ASSET_STARTING_BIT = 0n\nconst ASSET_SIZE = 1n\nconst RATIO_STARTING_BIT = ASSET_STARTING_BIT + ASSET_SIZE // 0 + 1\nconst RATIO_SIZE = 7n\nconst IS_LONG_STARTING_BIT = RATIO_STARTING_BIT + RATIO_SIZE // 1 + 7\nconst IS_LONG_SIZE = 1n\nconst TOKEN_TYPE_STARTING_BIT = IS_LONG_STARTING_BIT + IS_LONG_SIZE // 8 + 1\nconst TOKEN_TYPE_SIZE = 1n\nconst RISK_PARTNER_STARTING_BIT = TOKEN_TYPE_STARTING_BIT + TOKEN_TYPE_SIZE // 9 + 1\nconst RISK_PARTNER_SIZE = 2n\nconst STRIKE_STARTING_BIT = RISK_PARTNER_STARTING_BIT + RISK_PARTNER_SIZE // 10 + 2\nconst STRIKE_SIZE = 24n\nconst WIDTH_STARTING_BIT = STRIKE_STARTING_BIT + STRIKE_SIZE // 12 + 24\nconst WIDTH_SIZE = 12n\nconst LEG_SIZE = WIDTH_STARTING_BIT + WIDTH_SIZE // 36 + 12 = 48\n\n// converts unsigned strike to signed for encoding\nexport const convertStrike = (n: bigint): bigint => {\n if (n < 0n) {\n // 3 bytes because strike is int24\n return 16777216n + n\n } else {\n return n\n }\n}\n\n// converts encoded (unsigned) strike back to signed\nexport const signStrike = (encodedStrike: bigint): bigint => {\n if (encodedStrike > 2n ** 23n) {\n return encodedStrike - 16777216n\n }\n return encodedStrike\n}\n\nconst getLegOffsetByIndex = (index: bigint): bigint => index * LEG_SIZE\n\nconst encodeAsset = (asset: bigint, legIndex: bigint): bigint =>\n asset << (getLegOffsetByIndex(legIndex) + ASSET_STARTING_BIT + POOL_ID_SIZE)\n\nconst encodeRatio = (optionRatio: bigint, legIndex: bigint): bigint =>\n optionRatio << (getLegOffsetByIndex(legIndex) + RATIO_STARTING_BIT + POOL_ID_SIZE)\n\nconst encodeIsLong = (isLong: bigint, legIndex: bigint): bigint =>\n isLong << (getLegOffsetByIndex(legIndex) + IS_LONG_STARTING_BIT + POOL_ID_SIZE)\n\nconst encodeTokenType = (tokenType: bigint, legIndex: bigint): bigint =>\n tokenType << (getLegOffsetByIndex(legIndex) + TOKEN_TYPE_STARTING_BIT + POOL_ID_SIZE)\n\nconst encodeRiskPartner = (riskPartner: bigint, legIndex: bigint): bigint =>\n riskPartner << (getLegOffsetByIndex(legIndex) + RISK_PARTNER_STARTING_BIT + POOL_ID_SIZE)\n\nconst encodeStrike = (strike: bigint, legIndex: bigint): bigint =>\n convertStrike(strike) << (getLegOffsetByIndex(legIndex) + STRIKE_STARTING_BIT + POOL_ID_SIZE)\n\nconst encodeWidth = (width: bigint, legIndex: bigint): bigint =>\n width << (getLegOffsetByIndex(legIndex) + WIDTH_STARTING_BIT + POOL_ID_SIZE)\n\nconst decodeAsset = (leg: bigint): bigint => leg % (1n << ASSET_SIZE)\n\nconst decodeRatio = (leg: bigint): bigint => (leg >> RATIO_STARTING_BIT) % (1n << RATIO_SIZE)\n\nconst decodeIsLong = (leg: bigint): bigint => (leg >> IS_LONG_STARTING_BIT) % (1n << IS_LONG_SIZE)\n\nconst decodeTokenType = (leg: bigint): bigint =>\n (leg >> TOKEN_TYPE_STARTING_BIT) % (1n << TOKEN_TYPE_SIZE)\n\nconst decodeRiskPartner = (leg: bigint): bigint =>\n (leg >> RISK_PARTNER_STARTING_BIT) % (1n << RISK_PARTNER_SIZE)\n\nconst decodeStrike = (leg: bigint): bigint =>\n signStrike((leg >> STRIKE_STARTING_BIT) % (1n << STRIKE_SIZE))\n\nconst decodeWidth = (leg: bigint): bigint => (leg >> WIDTH_STARTING_BIT) % (1n << WIDTH_SIZE)\n\n/**\n * Extract vegoid from a TokenId\n * Vegoid is stored in bits 40-47 (8 bits) of the poolId\n */\nexport const decodeVegoid = (tokenId: bigint): bigint => {\n return ((tokenId % (1n << POOL_ID_SIZE)) >> VEGOID_STARTING_BIT) % (1n << VEGOID_SIZE)\n}\n\n/**\n * Extract vegoid from a poolId\n * Vegoid is stored in bits 40-47 (8 bits) of the poolId\n */\nexport const decodeVegoidFromPoolId = (poolId: bigint): bigint => {\n return (poolId >> VEGOID_STARTING_BIT) % (1n << VEGOID_SIZE)\n}\n\n/**\n * Extract tickSpacing from a TokenId\n * TickSpacing is stored in bits 48-63 (16 bits) of the poolId\n */\nexport const decodeTickSpacing = (tokenId: bigint): bigint => {\n return (tokenId % (1n << POOL_ID_SIZE)) >> TICK_SPACING_STARTING_BIT\n}\n\n/**\n * Encode poolId with vegoid support\n * The encoded PoolId structure: [16-bit tickSpacing][8-bit vegoid][40-bit pool address]\n * @param address The Uniswap V3 pool address (hex string)\n * @param tickSpacing The tick spacing of the pool\n * @param vegoidValue The vegoid value (defaults to 4 if not provided)\n * @return The encoded poolId as bigint\n */\nexport const encodePoolId = (\n address: Address,\n tickSpacing: bigint,\n vegoidValue: bigint = BigInt(vegoid),\n): bigint => {\n // Remove 0x prefix and get first 10 hex chars (5 bytes = 40 bits)\n const addressHex = address.slice(2, 12).toLowerCase()\n\n // Convert to bytes array (big-endian), then reverse to little-endian\n const bytes: number[] = []\n for (let i = 0; i < 10; i += 2) {\n bytes.push(parseInt(addressHex.slice(i, i + 2), 16))\n }\n bytes.reverse()\n\n // Build poolId: pool address (5 bytes) + vegoid (1 byte) + tickSpacing (2 bytes) = 8 bytes\n // All in little-endian format\n let poolId = 0n\n for (let i = 0; i < bytes.length; i++) {\n poolId |= BigInt(bytes[i]) << BigInt(i * 8)\n }\n\n // Add vegoid at bit 40\n poolId |= (vegoidValue % 256n) << 40n\n\n // Add tickSpacing at bit 48\n poolId |= (tickSpacing % 65536n) << 48n\n\n return poolId\n}\n\n/**\n * Encode V4 poolId with vegoid support\n * The encoded PoolId structure: [16-bit tickSpacing][8-bit vegoid][40-bit pool pattern]\n * @param poolId The V4 pool ID (bytes32 hex string)\n * @param tickSpacing The tick spacing of the pool\n * @param vegoidValue The vegoid value (defaults to 4 if not provided)\n * @return The encoded poolId as bigint\n */\nexport const encodeV4PoolId = (\n poolId: Hex,\n tickSpacing: bigint,\n vegoidValue: bigint = BigInt(vegoid),\n): bigint => {\n // Remove 0x prefix and get last 10 hex chars (5 bytes = 40 bits)\n const poolIdHex = poolId.slice(2)\n const last5BytesHex = poolIdHex.slice(-10).toLowerCase()\n\n // Convert to bytes array (big-endian), then reverse to little-endian\n const bytes: number[] = []\n for (let i = 0; i < 10; i += 2) {\n bytes.push(parseInt(last5BytesHex.slice(i, i + 2), 16))\n }\n bytes.reverse()\n\n // Build encoded poolId: pool pattern (5 bytes) + vegoid (1 byte) + tickSpacing (2 bytes) = 8 bytes\n let encodedPoolId = 0n\n for (let i = 0; i < bytes.length; i++) {\n encodedPoolId |= BigInt(bytes[i]) << BigInt(i * 8)\n }\n\n // Add vegoid at bit 40\n encodedPoolId |= (vegoidValue % 256n) << 40n\n\n // Add tickSpacing at bit 48\n encodedPoolId |= (tickSpacing % 65536n) << 48n\n\n return encodedPoolId\n}\n\n// Can be (ab)used to create a leg id by passing in a tokenId of 0\nexport const addLeg = (tokenId: bigint, leg: LegParams): bigint => {\n const legIndex = BigInt(leg.index)\n const width = leg.width\n const strike = leg.strike\n const riskPartner = leg.riskPartner\n const tokenType = leg.tokenType\n const isLong = leg.isLong\n const optionRatio = leg.optionRatio\n const asset = leg.asset\n\n return (\n tokenId +\n encodeWidth(width, legIndex) +\n encodeStrike(strike, legIndex) +\n (encodeRiskPartner(riskPartner, legIndex) |\n encodeTokenType(tokenType, legIndex) |\n encodeIsLong(isLong, legIndex) |\n encodeRatio(optionRatio, legIndex) |\n encodeAsset(asset, legIndex))\n )\n}\n\nexport const encodePosition = (poolId: bigint, legs: LegParams[]): bigint => {\n return legs.reduce((acc, leg) => addLeg(acc, leg), poolId)\n}\n\nexport interface Position {\n poolId: string\n legs: LegParams[]\n}\n\nexport const decodePosition = (encodedPosition: bigint): Position => {\n const leg4 = (encodedPosition >> (POOL_ID_SIZE + getLegOffsetByIndex(3n))) % (1n << LEG_SIZE)\n\n const leg3 = (encodedPosition >> (POOL_ID_SIZE + getLegOffsetByIndex(2n))) % (1n << LEG_SIZE)\n\n const leg2 = (encodedPosition >> (POOL_ID_SIZE + getLegOffsetByIndex(1n))) % (1n << LEG_SIZE)\n\n const leg1 = (encodedPosition >> (POOL_ID_SIZE + getLegOffsetByIndex(0n))) % (1n << LEG_SIZE)\n\n let poolId = (encodedPosition % (1n << POOL_ID_SIZE)).toString(16)\n\n const poolIdLength = 16 // poolId is 64 bits => 16 hex characters\n if (poolId.length < poolIdLength) {\n poolId = padHexWithZeros('0x' + poolId, poolIdLength + 2) // +2 for 0x prefix\n } else {\n poolId = '0x' + poolId\n }\n\n const encodedLegs = [leg1, leg2, leg3, leg4].filter((leg) => decodeRatio(leg) > 0n)\n\n const legs: LegParams[] = encodedLegs.map((leg, index) => ({\n index: index,\n width: decodeWidth(leg),\n strike: decodeStrike(leg),\n riskPartner: decodeRiskPartner(leg),\n tokenType: decodeTokenType(leg),\n isLong: decodeIsLong(leg),\n optionRatio: decodeRatio(leg),\n asset: decodeAsset(leg),\n }))\n\n return {\n poolId,\n legs,\n }\n}\n\nexport function padHexWithZeros(hex: string, length: number): string {\n // Check if the hex starts with \"0x\"\n if (hex.startsWith('0x')) {\n // Remove the \"0x\" prefix\n hex = hex.substring(2)\n } else {\n throw new Error('do not use padHexWithZeros on non-hex strings')\n }\n\n // Subtract 2 from length to account for the substring(2) call to remove the leading 0x\n while (hex.length < length - 2) {\n hex = '0' + hex\n }\n\n // Add back the \"0x\" prefix\n return '0x' + hex\n}\n","/**\n * Position read functions for the Panoptic v2 SDK.\n * @module v2/reads/position\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport { calculatePositionGreeks } from '../greeks'\nimport type { BlockMeta, Position, PositionGreeks, TokenIdLeg } from '../types'\nimport { decodePosition, decodeTickSpacing } from '../utils/option-encoding-v2'\n\n/**\n * Decode a packed PositionBalance (uint256) into its component fields.\n */\nfunction decodePositionBalance(balance: bigint) {\n const positionSize = balance & ((1n << 128n) - 1n)\n const poolUtilization0 = (balance >> 128n) & 0xffffn\n const poolUtilization1 = (balance >> 144n) & 0xffffn\n let tickAtMint = (balance >> 160n) & 0xffffffn\n if (tickAtMint > 0x7fffffn) {\n tickAtMint = tickAtMint - 0x1000000n\n }\n const timestampAtMint = (balance >> 184n) & 0xffffffffn\n const blockAtMint = (balance >> 216n) & ((1n << 39n) - 1n)\n const swapAtMint = balance >> 255n === 1n\n\n return {\n positionSize,\n poolUtilization0,\n poolUtilization1,\n tickAtMint,\n timestampAtMint,\n blockAtMint,\n swapAtMint,\n }\n}\n\n/**\n * Parameters for getPosition.\n */\nexport interface GetPositionParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Owner address */\n owner: Address\n /** TokenId to query */\n tokenId: bigint\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get a single position by tokenId.\n *\n * @param params - The parameters\n * @returns Position data with block metadata\n */\nexport async function getPosition(params: GetPositionParams): Promise<Position> {\n const { client, poolAddress, owner, tokenId, blockNumber } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n const [fullData, _meta] = await Promise.all([\n client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [owner, false, [tokenId]],\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const balanceRaw = fullData[2][0] // positionBalances[0]\n const {\n positionSize,\n poolUtilization0: utilization0AtMint,\n poolUtilization1: utilization1AtMint,\n tickAtMint,\n timestampAtMint,\n blockAtMint,\n swapAtMint,\n } = decodePositionBalance(balanceRaw)\n\n // Decode the tokenId to get legs\n const decoded = decodePosition(tokenId)\n const tickSpacing = decodeTickSpacing(tokenId)\n\n // Convert decoded legs to TokenIdLeg format\n const legs: TokenIdLeg[] = decoded.legs.map((leg) => {\n const width = leg.width\n const strike = leg.strike\n // Calculate tick bounds based on strike and width\n const tickLower = strike - (width * tickSpacing) / 2n\n const tickUpper = strike + (width * tickSpacing) / 2n\n\n return {\n index: BigInt(leg.index),\n asset: leg.asset,\n optionRatio: leg.optionRatio,\n isLong: leg.isLong === 1n,\n tokenType: leg.tokenType,\n riskPartner: leg.riskPartner,\n strike,\n width,\n tickLower,\n tickUpper,\n }\n })\n\n return {\n tokenId,\n positionSize,\n owner,\n poolAddress,\n legs,\n poolUtilization0AtMint: utilization0AtMint,\n poolUtilization1AtMint: utilization1AtMint,\n tickAtMint: BigInt(tickAtMint),\n timestampAtMint,\n blockNumberAtMint: blockAtMint,\n swapAtMint,\n premiaOwed0: 0n, // Premia now tracked separately, not returned from positionData\n premiaOwed1: 0n,\n assetIndex: legs.length > 0 ? legs[0].asset : 0n,\n _meta,\n }\n}\n\n/**\n * Parameters for getPositions.\n */\nexport interface GetPositionsParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Owner address */\n owner: Address\n /** TokenIds to query */\n tokenIds: bigint[]\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get multiple positions for an account.\n *\n * @param params - The parameters\n * @returns Array of positions with block metadata\n */\nexport async function getPositions(\n params: GetPositionsParams,\n): Promise<{ positions: Position[]; _meta: BlockMeta }> {\n const { client, poolAddress, owner, tokenIds, blockNumber } = params\n\n if (tokenIds.length === 0) {\n const _meta =\n params._meta ??\n (await getBlockMeta({\n client,\n blockNumber: blockNumber ?? (await client.getBlockNumber()),\n }))\n return { positions: [], _meta }\n }\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n const _meta = params._meta ?? (await getBlockMeta({ client, blockNumber: targetBlockNumber }))\n\n const decodePositions = (\n ids: bigint[],\n positionBalances: readonly bigint[],\n meta: BlockMeta,\n ): Position[] => {\n const positions: Position[] = []\n for (let i = 0; i < ids.length; i += 1) {\n const tokenId = ids[i]\n if (tokenId === undefined) continue\n const balanceRaw = positionBalances[i]\n if (balanceRaw === undefined) continue\n\n const {\n positionSize,\n poolUtilization0: utilization0AtMint,\n poolUtilization1: utilization1AtMint,\n tickAtMint,\n timestampAtMint,\n blockAtMint,\n swapAtMint,\n } = decodePositionBalance(balanceRaw)\n\n // Skip positions with zero size\n if (positionSize === 0n) {\n continue\n }\n\n // Decode the tokenId to get legs\n const decoded = decodePosition(tokenId)\n const tickSpacing = decodeTickSpacing(tokenId)\n\n // Convert decoded legs to TokenIdLeg format\n const legs: TokenIdLeg[] = decoded.legs.map((leg) => {\n const width = leg.width\n const strike = leg.strike\n const tickLower = strike - (width * tickSpacing) / 2n\n const tickUpper = strike + (width * tickSpacing) / 2n\n\n return {\n index: BigInt(leg.index),\n asset: leg.asset,\n optionRatio: leg.optionRatio,\n isLong: leg.isLong === 1n,\n tokenType: leg.tokenType,\n riskPartner: leg.riskPartner,\n strike,\n width,\n tickLower,\n tickUpper,\n }\n })\n\n positions.push({\n tokenId,\n positionSize,\n owner,\n poolAddress,\n legs,\n poolUtilization0AtMint: utilization0AtMint,\n poolUtilization1AtMint: utilization1AtMint,\n tickAtMint: BigInt(tickAtMint),\n timestampAtMint,\n blockNumberAtMint: blockAtMint,\n swapAtMint,\n premiaOwed0: 0n, // Premia now tracked separately\n premiaOwed1: 0n,\n assetIndex: legs.length > 0 ? legs[0].asset : 0n,\n _meta: meta,\n })\n }\n return positions\n }\n\n const getOrderingCandidates = (ids: bigint[]): bigint[][] => {\n if (ids.length <= 1) return [Array.from(ids)]\n const candidates: bigint[][] = []\n const seen = new Set<string>()\n const push = (candidate: bigint[]) => {\n const key = candidate.map((value) => value.toString()).join(',')\n if (seen.has(key)) return\n seen.add(key)\n candidates.push(candidate)\n }\n push(Array.from(ids))\n push(Array.from(ids).sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)))\n push(Array.from(ids).sort((a, b) => (a < b ? 1 : a > b ? -1 : 0)))\n return candidates\n }\n\n const fetchBalances = async (ids: bigint[]) => {\n const fullData = await client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [owner, false, ids],\n blockNumber: targetBlockNumber,\n })\n const balances = fullData[2]\n return Array.isArray(balances) ? balances : []\n }\n\n // Try full-batch read first.\n for (const candidate of getOrderingCandidates(tokenIds)) {\n try {\n const balances = await fetchBalances(candidate)\n return { positions: decodePositions(candidate, balances, _meta), _meta }\n } catch {\n // fall through to next ordering candidate\n }\n }\n\n // Last-resort fallback: probe each token independently and keep only successful reads.\n const perTokenResults = await Promise.all(\n tokenIds.map(async (tokenId) => {\n try {\n const balances = await fetchBalances([tokenId])\n return { tokenId, balance: balances[0] }\n } catch {\n return { tokenId, balance: undefined }\n }\n }),\n )\n const validTokenIds: bigint[] = []\n const validBalances: bigint[] = []\n for (const result of perTokenResults) {\n if (result.balance === undefined) continue\n validTokenIds.push(result.tokenId)\n validBalances.push(result.balance)\n }\n\n return { positions: decodePositions(validTokenIds, validBalances, _meta), _meta }\n}\n\n/**\n * Parameters for getPositionGreeks.\n */\nexport interface GetPositionGreeksParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Owner address */\n owner: Address\n /** TokenId to calculate greeks for */\n tokenId: bigint\n /** Optional: Current tick override (defaults to pool's current tick) */\n atTick?: bigint\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get Greeks for a position.\n *\n * Uses client-side calculation based on the position's legs, current tick,\n * and mint tick. Returns WAD-scaled (1e18) bigint values.\n *\n * @param params - The parameters\n * @returns Position greeks with block metadata\n */\nexport async function getPositionGreeks(\n params: GetPositionGreeksParams,\n): Promise<PositionGreeks & { _meta: BlockMeta }> {\n const { client, poolAddress, owner, tokenId, atTick, blockNumber } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Get position data and current tick in parallel\n const [fullData, currentTickResult, _meta] = await Promise.all([\n client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [owner, false, [tokenId]],\n blockNumber: targetBlockNumber,\n }),\n atTick === undefined\n ? client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n blockNumber: targetBlockNumber,\n })\n : Promise.resolve(atTick),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const { tickAtMint, positionSize } = decodePositionBalance(fullData[2][0])\n\n // Decode the tokenId to get legs\n const decoded = decodePosition(tokenId)\n const tickSpacing = decodeTickSpacing(tokenId)\n\n // Convert decoded legs to TokenIdLeg format\n const legs: TokenIdLeg[] = decoded.legs.map((leg) => {\n const width = leg.width\n const strike = leg.strike\n const tickLower = strike - (width * tickSpacing) / 2n\n const tickUpper = strike + (width * tickSpacing) / 2n\n\n return {\n index: BigInt(leg.index),\n asset: leg.asset,\n optionRatio: leg.optionRatio,\n isLong: leg.isLong === 1n,\n tokenType: leg.tokenType,\n riskPartner: leg.riskPartner,\n strike,\n width,\n tickLower,\n tickUpper,\n }\n })\n\n const currentTick =\n typeof currentTickResult === 'bigint' ? currentTickResult : BigInt(currentTickResult)\n\n // Calculate greeks using client-side implementation\n const greeks = calculatePositionGreeks({\n legs,\n currentTick,\n mintTick: BigInt(tickAtMint),\n positionSize,\n poolTickSpacing: tickSpacing,\n })\n\n return {\n ...greeks,\n _meta,\n }\n}\n","/**\n * Premia read functions for the Panoptic v2 SDK.\n * @module v2/reads/premia\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport type { BlockMeta, Position, TokenIdLeg } from '../types'\nimport { decodePosition, decodeTickSpacing } from '../utils/option-encoding-v2'\nimport { decodeLeftRightUnsigned } from '../writes/utils'\n\n/**\n * Premia data for an account.\n */\nexport interface AccountPremia {\n /** Total short premium owed to the account for token 0 */\n shortPremium0: bigint\n /** Total short premium owed to the account for token 1 */\n shortPremium1: bigint\n /** Total long premium owed by the account for token 0 */\n longPremium0: bigint\n /** Total long premium owed by the account for token 1 */\n longPremium1: bigint\n /** Whether pending (unsettled) premium was included */\n includePendingPremium: boolean\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Parameters for getAccountPremia.\n */\nexport interface GetAccountPremiaParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** TokenIds held by the account */\n tokenIds: bigint[]\n /** Whether to include pending (unsettled) premium (default: true) */\n includePendingPremium?: boolean\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get premia totals for an account.\n *\n * Returns the total short and long premium across all positions.\n * Short premium is owed TO the account (earned from selling options).\n * Long premium is owed BY the account (paid for buying options).\n *\n * @param params - The parameters\n * @returns Premia totals with block metadata\n *\n * @example\n * ```typescript\n * const premia = await getAccountPremia({\n * client,\n * poolAddress,\n * account,\n * tokenIds: [tokenId1, tokenId2],\n * includePendingPremium: true,\n * })\n *\n * console.log('Short premium earned:', premia.shortPremium0, premia.shortPremium1)\n * console.log('Long premium owed:', premia.longPremium0, premia.longPremium1)\n * ```\n */\nexport async function getAccountPremia(params: GetAccountPremiaParams): Promise<AccountPremia> {\n const {\n client,\n poolAddress,\n account,\n tokenIds,\n includePendingPremium = true,\n blockNumber,\n } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Handle empty position list\n if (tokenIds.length === 0) {\n const _meta = params._meta ?? (await getBlockMeta({ client, blockNumber: targetBlockNumber }))\n return {\n shortPremium0: 0n,\n shortPremium1: 0n,\n longPremium0: 0n,\n longPremium1: 0n,\n includePendingPremium,\n _meta,\n }\n }\n\n const [[shortPremiumPacked, longPremiumPacked], _meta] = await Promise.all([\n client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [account, includePendingPremium, tokenIds],\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n // Decode LeftRightUnsigned values (right = token0, left = token1)\n const shortPremium = decodeLeftRightUnsigned(shortPremiumPacked)\n const longPremium = decodeLeftRightUnsigned(longPremiumPacked)\n\n return {\n shortPremium0: shortPremium.right,\n shortPremium1: shortPremium.left,\n longPremium0: longPremium.right,\n longPremium1: longPremium.left,\n includePendingPremium,\n _meta,\n }\n}\n\n/**\n * Position with premia data.\n */\nexport interface PositionWithPremia extends Position {\n // Position already has all fields from the base Position interface\n}\n\n/**\n * Result from getPositionsWithPremia.\n */\nexport interface PositionsWithPremiaResult {\n /** Positions with full data */\n positions: PositionWithPremia[]\n /** Total short premium owed to the account for token 0 */\n shortPremium0: bigint\n /** Total short premium owed to the account for token 1 */\n shortPremium1: bigint\n /** Total long premium owed by the account for token 0 */\n longPremium0: bigint\n /** Total long premium owed by the account for token 1 */\n longPremium1: bigint\n /** Whether pending (unsettled) premium was included */\n includePendingPremium: boolean\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Parameters for getPositionsWithPremia.\n */\nexport interface GetPositionsWithPremiaParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** TokenIds held by the account */\n tokenIds: bigint[]\n /** Whether to include pending (unsettled) premium (default: true) */\n includePendingPremium?: boolean\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get positions with per-position premia data.\n *\n * Uses multicall to batch individual getFullPositionsData calls\n * for each position, giving us per-position premia in a single RPC request.\n *\n * @param params - The parameters\n * @returns Positions with premia and totals with block metadata\n *\n * @example\n * ```typescript\n * const result = await getPositionsWithPremia({\n * client,\n * poolAddress,\n * account,\n * tokenIds: [tokenId1, tokenId2],\n * })\n *\n * for (const position of result.positions) {\n * console.log('Position:', position.tokenId)\n * console.log('Premia:', position.premiaOwed0, position.premiaOwed1)\n * }\n * console.log('Total short premium:', result.shortPremium0, result.shortPremium1)\n * ```\n */\nexport async function getPositionsWithPremia(\n params: GetPositionsWithPremiaParams,\n): Promise<PositionsWithPremiaResult> {\n const {\n client,\n poolAddress,\n account,\n tokenIds,\n includePendingPremium = true,\n blockNumber,\n } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Handle empty position list\n if (tokenIds.length === 0) {\n const _meta = params._meta ?? (await getBlockMeta({ client, blockNumber: targetBlockNumber }))\n return {\n positions: [],\n shortPremium0: 0n,\n shortPremium1: 0n,\n longPremium0: 0n,\n longPremium1: 0n,\n includePendingPremium,\n _meta,\n }\n }\n\n // Build multicall contracts - one getFullPositionsData call per tokenId\n // This gives us per-position premia\n const contracts = tokenIds.map((tokenId) => ({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData' as const,\n args: [account, includePendingPremium, [tokenId]] as const,\n }))\n\n // Execute multicall and get block metadata\n const [multicallResults, _meta] = await Promise.all([\n client.multicall({\n contracts,\n blockNumber: targetBlockNumber,\n allowFailure: true,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n // Build positions and accumulate totals\n const positions: PositionWithPremia[] = []\n let totalShortPremium0 = 0n\n let totalShortPremium1 = 0n\n let totalLongPremium0 = 0n\n let totalLongPremium1 = 0n\n\n for (let i = 0; i < tokenIds.length; i++) {\n const tokenId = tokenIds[i]\n const result = multicallResults[i]\n\n // Skip failed calls\n if (result.status !== 'success') {\n continue\n }\n\n const [shortPremiumPacked, longPremiumPacked, balances] = result.result\n\n // Decode per-position premia\n const shortPremium = decodeLeftRightUnsigned(shortPremiumPacked)\n const longPremium = decodeLeftRightUnsigned(longPremiumPacked)\n\n // Accumulate totals\n totalShortPremium0 += shortPremium.right\n totalShortPremium1 += shortPremium.left\n totalLongPremium0 += longPremium.right\n totalLongPremium1 += longPremium.left\n\n // Get balance data (should be single element array)\n const balanceData = balances[0]\n if (balanceData === undefined) {\n continue\n }\n\n // Decode the PositionBalance\n const positionSize = balanceData & ((1n << 128n) - 1n)\n\n // Skip positions with zero size\n if (positionSize === 0n) {\n continue\n }\n\n const poolUtilization0 = (balanceData >> 128n) & 0xffffn\n const poolUtilization1 = (balanceData >> 144n) & 0xffffn\n\n // tickAtMint is int24 at bits 160-183\n let tickAtMint = (balanceData >> 160n) & 0xffffffn\n if (tickAtMint > 0x7fffffn) {\n tickAtMint = tickAtMint - 0x1000000n\n }\n\n const timestampAtMint = (balanceData >> 184n) & 0xffffffffn\n const blockAtMint = (balanceData >> 216n) & ((1n << 39n) - 1n)\n const swapAtMint = balanceData >> 255n === 1n\n\n // Decode the tokenId to get legs\n const decoded = decodePosition(tokenId)\n const tickSpacing = decodeTickSpacing(tokenId)\n\n // Convert decoded legs to TokenIdLeg format\n const legs: TokenIdLeg[] = decoded.legs.map((leg) => {\n const width = leg.width\n const strike = leg.strike\n const tickLower = strike - (width * tickSpacing) / 2n\n const tickUpper = strike + (width * tickSpacing) / 2n\n\n return {\n index: BigInt(leg.index),\n asset: leg.asset,\n optionRatio: leg.optionRatio,\n isLong: leg.isLong === 1n,\n tokenType: leg.tokenType,\n riskPartner: leg.riskPartner,\n strike,\n width,\n tickLower,\n tickUpper,\n }\n })\n\n // Calculate net premia for this position\n // Positive = position has earned premium (short), Negative = position owes premium (long)\n const premiaOwed0 = shortPremium.right - longPremium.right\n const premiaOwed1 = shortPremium.left - longPremium.left\n\n positions.push({\n tokenId,\n positionSize,\n owner: account,\n poolAddress,\n legs,\n poolUtilization0AtMint: poolUtilization0,\n poolUtilization1AtMint: poolUtilization1,\n tickAtMint,\n timestampAtMint,\n blockNumberAtMint: blockAtMint,\n swapAtMint,\n premiaOwed0,\n premiaOwed1,\n assetIndex: legs.length > 0 ? legs[0].asset : 0n,\n _meta,\n })\n }\n\n return {\n positions,\n shortPremium0: totalShortPremium0,\n shortPremium1: totalShortPremium1,\n longPremium0: totalLongPremium0,\n longPremium1: totalLongPremium1,\n includePendingPremium,\n _meta,\n }\n}\n","/**\n * PanopticQuery contract ABI\n * Auto-generated from PanopticQuery.json\n * @module abis/panopticQuery\n */\n\nexport const panopticQueryAbi = [\n {\n type: 'constructor',\n inputs: [\n {\n name: 'SFPM_',\n type: 'address',\n internalType: 'contract ISemiFungiblePositionManager',\n },\n ],\n stateMutability: 'payable',\n },\n {\n type: 'function',\n name: 'checkCollateral',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n ],\n outputs: [\n { name: 'collateralBalances0', type: 'uint256[4]', internalType: 'uint256[4]' },\n { name: 'requiredCollaterals0', type: 'uint256[4]', internalType: 'uint256[4]' },\n { name: 'collateralBalances1', type: 'uint256[4]', internalType: 'uint256[4]' },\n { name: 'requiredCollaterals1', type: 'uint256[4]', internalType: 'uint256[4]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'checkCollateral',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n { name: 'atTick', type: 'int24', internalType: 'int24' },\n ],\n outputs: [{ name: 'balancesAndRequired', type: 'uint256[4]', internalType: 'uint256[4]' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'checkCollateralListOutput',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n ],\n outputs: [\n { name: '', type: 'uint256[2][]', internalType: 'uint256[2][]' },\n { name: '', type: 'int256[]', internalType: 'int256[]' },\n { name: '', type: 'int24[]', internalType: 'int24[]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'computeMedianObservedPrice',\n inputs: [\n { name: 'univ3pool', type: 'address', internalType: 'contract IUniswapV3Pool' },\n { name: 'cardinality', type: 'uint256', internalType: 'uint256' },\n { name: 'period', type: 'uint256', internalType: 'uint256' },\n ],\n outputs: [{ name: 'medianTick', type: 'int24', internalType: 'int24' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getChunkData',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n ],\n outputs: [{ name: '', type: 'uint256[2][4][]', internalType: 'uint256[2][4][]' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'scanChunks',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'tickLower', type: 'int24', internalType: 'int24' },\n { name: 'tickUpper', type: 'int24', internalType: 'int24' },\n { name: 'width', type: 'int24', internalType: 'int24' },\n ],\n outputs: [\n { name: 'strikes', type: 'int24[]', internalType: 'int24[]' },\n { name: 'netLiquidities', type: 'uint128[2][]', internalType: 'uint128[2][]' },\n { name: 'removedLiquidities', type: 'uint128[2][]', internalType: 'uint128[2][]' },\n { name: 'settledTokens', type: 'uint256[2][]', internalType: 'LeftRightUnsigned[2][]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getLiquidationPrices',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n ],\n outputs: [\n { name: 'liquidationPriceDown', type: 'int24', internalType: 'int24' },\n { name: 'liquidationPriceUp', type: 'int24', internalType: 'int24' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getItmAmounts',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPoolV2' },\n { name: 'tokenId', type: 'uint256', internalType: 'TokenId' },\n { name: 'positionSize', type: 'uint128', internalType: 'uint128' },\n ],\n outputs: [\n { name: 'itm0', type: 'int256', internalType: 'int256' },\n { name: 'itm1', type: 'int256', internalType: 'int256' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getMaxPositionSizeBounds',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'existingPositionIds', type: 'uint256[]', internalType: 'TokenId[]' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'tokenId', type: 'uint256', internalType: 'TokenId' },\n ],\n outputs: [\n { name: 'maxSizeAtMinUtil', type: 'uint128', internalType: 'uint128' },\n { name: 'maxSizeAtMaxUtil', type: 'uint128', internalType: 'uint128' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getNetLiquidationValue',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'includePendingPremium', type: 'bool', internalType: 'bool' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n { name: 'atTicks', type: 'int24[]', internalType: 'int24[]' },\n ],\n outputs: [\n { name: 'value0', type: 'int256[]', internalType: 'int256[]' },\n { name: 'value1', type: 'int256[]', internalType: 'int256[]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getPortfolioValue',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'atTick', type: 'int24', internalType: 'int24' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n ],\n outputs: [\n { name: 'value0', type: 'int256', internalType: 'int256' },\n { name: 'value1', type: 'int256', internalType: 'int256' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getRequiredBase',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'tokenId', type: 'uint256', internalType: 'TokenId' },\n { name: 'atTick', type: 'int24', internalType: 'int24' },\n ],\n outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getTickNets',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'startTick', type: 'int24', internalType: 'int24' },\n { name: 'nTicks', type: 'uint256', internalType: 'uint256' },\n ],\n outputs: [\n { name: 'tickData', type: 'int256[]', internalType: 'int256[]' },\n { name: 'liquidityNets', type: 'int256[]', internalType: 'int256[]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getTickNetsV3',\n inputs: [\n { name: 'univ3pool', type: 'address', internalType: 'contract IUniswapV3Pool' },\n { name: 'startTick', type: 'int24', internalType: 'int24' },\n { name: 'nTicks', type: 'uint256', internalType: 'uint256' },\n ],\n outputs: [\n { name: 'tickData', type: 'int256[]', internalType: 'int256[]' },\n { name: 'liquidityNets', type: 'int256[]', internalType: 'int256[]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getTickNetsV4',\n inputs: [\n { name: 'manager', type: 'address', internalType: 'contract IPoolManager' },\n { name: 'poolId', type: 'bytes32', internalType: 'PoolId' },\n { name: 'tickSpacing', type: 'int24', internalType: 'int24' },\n { name: 'startTick', type: 'int24', internalType: 'int24' },\n { name: 'nTicks', type: 'uint256', internalType: 'uint256' },\n ],\n outputs: [\n { name: 'tickData', type: 'int256[]', internalType: 'int256[]' },\n { name: 'liquidityNets', type: 'int256[]', internalType: 'int256[]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'isAccountSolvent',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n { name: 'atTick', type: 'int24', internalType: 'int24' },\n ],\n outputs: [{ name: '', type: 'bool', internalType: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'optimizeRiskPartners',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'atTick', type: 'int24', internalType: 'int24' },\n { name: 'tokenId', type: 'uint256', internalType: 'TokenId' },\n ],\n outputs: [{ name: '', type: 'uint256', internalType: 'TokenId' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'twapFilter',\n inputs: [\n { name: 'univ3pool', type: 'address', internalType: 'contract IUniswapV3Pool' },\n { name: 'twapWindow', type: 'uint32', internalType: 'uint32' },\n ],\n outputs: [{ name: '', type: 'int24', internalType: 'int24' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'validateTokenId',\n inputs: [{ name: 'self', type: 'uint256', internalType: 'TokenId' }],\n outputs: [],\n stateMutability: 'pure',\n },\n {\n type: 'error',\n name: 'CastingError',\n inputs: [],\n },\n {\n type: 'error',\n name: 'InvalidTick',\n inputs: [],\n },\n {\n type: 'error',\n name: 'InvalidTokenIdParameter',\n inputs: [{ name: 'parameterType', type: 'uint256', internalType: 'uint256' }],\n },\n {\n type: 'error',\n name: 'LiquidityTooHigh',\n inputs: [],\n },\n {\n type: 'error',\n name: 'UnderOverFlow',\n inputs: [],\n },\n] as const\n","export const Multicall3Abi = [\n {\n inputs: [\n {\n components: [\n {\n internalType: 'address',\n name: 'target',\n type: 'address',\n },\n {\n internalType: 'bytes',\n name: 'callData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Call[]',\n name: 'calls',\n type: 'tuple[]',\n },\n ],\n name: 'aggregate',\n outputs: [\n {\n internalType: 'uint256',\n name: 'blockNumber',\n type: 'uint256',\n },\n {\n internalType: 'bytes[]',\n name: 'returnData',\n type: 'bytes[]',\n },\n ],\n stateMutability: 'payable',\n type: 'function',\n },\n {\n inputs: [\n {\n components: [\n {\n internalType: 'address',\n name: 'target',\n type: 'address',\n },\n {\n internalType: 'bool',\n name: 'allowFailure',\n type: 'bool',\n },\n {\n internalType: 'bytes',\n name: 'callData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Call3[]',\n name: 'calls',\n type: 'tuple[]',\n },\n ],\n name: 'aggregate3',\n outputs: [\n {\n components: [\n {\n internalType: 'bool',\n name: 'success',\n type: 'bool',\n },\n {\n internalType: 'bytes',\n name: 'returnData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Result[]',\n name: 'returnData',\n type: 'tuple[]',\n },\n ],\n stateMutability: 'payable',\n type: 'function',\n },\n {\n inputs: [\n {\n components: [\n {\n internalType: 'address',\n name: 'target',\n type: 'address',\n },\n {\n internalType: 'bool',\n name: 'allowFailure',\n type: 'bool',\n },\n {\n internalType: 'uint256',\n name: 'value',\n type: 'uint256',\n },\n {\n internalType: 'bytes',\n name: 'callData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Call3Value[]',\n name: 'calls',\n type: 'tuple[]',\n },\n ],\n name: 'aggregate3Value',\n outputs: [\n {\n components: [\n {\n internalType: 'bool',\n name: 'success',\n type: 'bool',\n },\n {\n internalType: 'bytes',\n name: 'returnData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Result[]',\n name: 'returnData',\n type: 'tuple[]',\n },\n ],\n stateMutability: 'payable',\n type: 'function',\n },\n {\n inputs: [\n {\n components: [\n {\n internalType: 'address',\n name: 'target',\n type: 'address',\n },\n {\n internalType: 'bytes',\n name: 'callData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Call[]',\n name: 'calls',\n type: 'tuple[]',\n },\n ],\n name: 'blockAndAggregate',\n outputs: [\n {\n internalType: 'uint256',\n name: 'blockNumber',\n type: 'uint256',\n },\n {\n internalType: 'bytes32',\n name: 'blockHash',\n type: 'bytes32',\n },\n {\n components: [\n {\n internalType: 'bool',\n name: 'success',\n type: 'bool',\n },\n {\n internalType: 'bytes',\n name: 'returnData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Result[]',\n name: 'returnData',\n type: 'tuple[]',\n },\n ],\n stateMutability: 'payable',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getBasefee',\n outputs: [\n {\n internalType: 'uint256',\n name: 'basefee',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint256',\n name: 'blockNumber',\n type: 'uint256',\n },\n ],\n name: 'getBlockHash',\n outputs: [\n {\n internalType: 'bytes32',\n name: 'blockHash',\n type: 'bytes32',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getBlockNumber',\n outputs: [\n {\n internalType: 'uint256',\n name: 'blockNumber',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getChainId',\n outputs: [\n {\n internalType: 'uint256',\n name: 'chainid',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getCurrentBlockCoinbase',\n outputs: [\n {\n internalType: 'address',\n name: 'coinbase',\n type: 'address',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getCurrentBlockDifficulty',\n outputs: [\n {\n internalType: 'uint256',\n name: 'difficulty',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getCurrentBlockGasLimit',\n outputs: [\n {\n internalType: 'uint256',\n name: 'gaslimit',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getCurrentBlockTimestamp',\n outputs: [\n {\n internalType: 'uint256',\n name: 'timestamp',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'addr',\n type: 'address',\n },\n ],\n name: 'getEthBalance',\n outputs: [\n {\n internalType: 'uint256',\n name: 'balance',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getLastBlockHash',\n outputs: [\n {\n internalType: 'bytes32',\n name: 'blockHash',\n type: 'bytes32',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'bool',\n name: 'requireSuccess',\n type: 'bool',\n },\n {\n components: [\n {\n internalType: 'address',\n name: 'target',\n type: 'address',\n },\n {\n internalType: 'bytes',\n name: 'callData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Call[]',\n name: 'calls',\n type: 'tuple[]',\n },\n ],\n name: 'tryAggregate',\n outputs: [\n {\n components: [\n {\n internalType: 'bool',\n name: 'success',\n type: 'bool',\n },\n {\n internalType: 'bytes',\n name: 'returnData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Result[]',\n name: 'returnData',\n type: 'tuple[]',\n },\n ],\n stateMutability: 'payable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'bool',\n name: 'requireSuccess',\n type: 'bool',\n },\n {\n components: [\n {\n internalType: 'address',\n name: 'target',\n type: 'address',\n },\n {\n internalType: 'bytes',\n name: 'callData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Call[]',\n name: 'calls',\n type: 'tuple[]',\n },\n ],\n name: 'tryBlockAndAggregate',\n outputs: [\n {\n internalType: 'uint256',\n name: 'blockNumber',\n type: 'uint256',\n },\n {\n internalType: 'bytes32',\n name: 'blockHash',\n type: 'bytes32',\n },\n {\n components: [\n {\n internalType: 'bool',\n name: 'success',\n type: 'bool',\n },\n {\n internalType: 'bytes',\n name: 'returnData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Result[]',\n name: 'returnData',\n type: 'tuple[]',\n },\n ],\n stateMutability: 'payable',\n type: 'function',\n },\n] as const\n","import type { Address, Client, Hex } from 'viem'\nimport { decodeFunctionResult, encodeFunctionData } from 'viem'\nimport { call } from 'viem/actions'\n\nimport { Multicall3Abi } from '../../../abis/multicall3'\nimport {\n MulticallNoDataError,\n MulticallResultFailedError,\n MulticallResultMissingError,\n} from '../errors'\nimport type { BlockMeta } from '../types'\n\nexport const MULTICALL3_ADDRESS = '0xcA11bde05977b3631167028862bE2a173976CA11' as const\n\nexport interface MulticallBlockCall {\n target: Address\n callData: Hex\n}\n\nexport interface MulticallBlockResult {\n success: boolean\n returnData: Hex\n}\n\ninterface ClientWithCall extends Client {\n call: (parameters: { to: Address; data: Hex; blockNumber?: bigint }) => Promise<{ data?: Hex }>\n}\n\nfunction hasCall(client: Client): client is ClientWithCall {\n return 'call' in client && typeof (client as Record<'call', unknown>).call === 'function'\n}\n\nfunction requireResult(\n results: readonly MulticallBlockResult[],\n index: number,\n label: string,\n): MulticallBlockResult {\n const result = results[index]\n if (result === undefined) {\n throw new MulticallResultMissingError(label, index)\n }\n if (!result.success) {\n throw new MulticallResultFailedError(label, index)\n }\n return result\n}\n\nexport function requireReturnData(\n results: readonly MulticallBlockResult[],\n index: number,\n label: string,\n): Hex {\n return requireResult(results, index, label).returnData\n}\n\nexport async function readBlockAndAggregate({\n client,\n calls,\n blockNumber,\n}: {\n client: Client\n calls: readonly MulticallBlockCall[]\n blockNumber?: bigint\n}): Promise<{ _meta: BlockMeta; results: readonly MulticallBlockResult[] }> {\n const aggregateCalls = [\n ...calls,\n {\n target: MULTICALL3_ADDRESS,\n callData: encodeFunctionData({\n abi: Multicall3Abi,\n functionName: 'getCurrentBlockTimestamp',\n }),\n },\n ]\n\n const data = encodeFunctionData({\n abi: Multicall3Abi,\n functionName: 'blockAndAggregate',\n args: [aggregateCalls],\n })\n const parameters = { to: MULTICALL3_ADDRESS, data, blockNumber }\n const response = hasCall(client) ? await client.call(parameters) : await call(client, parameters)\n\n if (response.data === undefined) {\n throw new MulticallNoDataError('blockAndAggregate')\n }\n const aggregateResult = decodeFunctionResult({\n abi: Multicall3Abi,\n functionName: 'blockAndAggregate',\n data: response.data,\n })\n const [aggregateBlockNumber, blockHash, rawResults] = aggregateResult as readonly [\n bigint,\n Hex,\n readonly MulticallBlockResult[],\n ]\n const timestampResult = requireReturnData(\n rawResults,\n calls.length,\n 'Multicall3.getCurrentBlockTimestamp',\n )\n const blockTimestamp = decodeFunctionResult({\n abi: Multicall3Abi,\n functionName: 'getCurrentBlockTimestamp',\n data: timestampResult,\n })\n\n return {\n _meta: {\n blockNumber: aggregateBlockNumber,\n blockHash,\n blockTimestamp,\n },\n results: rawResults.slice(0, calls.length),\n }\n}\n","/**\n * Position and account check functions for the Panoptic v2 SDK.\n *\n * These functions check account liquidatability.\n *\n * @module v2/reads/checks\n */\n\nimport type { Address, PublicClient } from 'viem'\nimport { decodeFunctionResult, encodeFunctionData } from 'viem'\n\nimport { collateralTrackerV2Abi, panopticPoolV2Abi } from '../../../generated'\nimport { tickToSqrtPriceX96 } from '../formatters/tick'\nimport type { BlockMeta } from '../types'\nimport { decodeLeftRightUnsigned } from '../writes/utils'\nimport { type MulticallBlockCall, readBlockAndAggregate, requireReturnData } from './multicallBlock'\n\nconst FP96 = 1n << 96n\nconst Q128 = 1n << 128n\n\nfunction convert0to1(amount: bigint, sqrtPriceX96: bigint): bigint {\n if (sqrtPriceX96 < Q128) {\n return (amount * sqrtPriceX96 * sqrtPriceX96) >> 192n\n }\n const sp2Hi = (sqrtPriceX96 * sqrtPriceX96) >> 64n\n return (amount * sp2Hi) >> 128n\n}\n\nfunction convert1to0(amount: bigint, sqrtPriceX96: bigint): bigint {\n if (sqrtPriceX96 < Q128) {\n const denom = sqrtPriceX96 * sqrtPriceX96\n return (amount * (1n << 192n)) / denom\n }\n const sp2Hi = (sqrtPriceX96 * sqrtPriceX96) >> 64n\n return (amount * (1n << 128n)) / sp2Hi\n}\n\n/**\n * Liquidation check result with detailed margin breakdown.\n *\n * **Denomination**: both per-token pairs hold the gross account total\n * cross-converted to that single token denomination at `atTick`.\n * - `currentMargin0` / `requiredMargin0` are in token0 units\n * - `currentMargin1` / `requiredMargin1` are in token1 units\n *\n * `denominatedInToken` indicates which pair is \"preferred\": 0n when\n * `atTick < 0` (token0), 1n otherwise.\n */\nexport interface LiquidationCheck {\n /** Whether the account is liquidatable */\n isLiquidatable: boolean\n /** Margin shortfall for slot 0 (positive = shortfall, negative = excess) */\n marginShortfall0: bigint\n /** Margin shortfall for slot 1 (positive = shortfall, negative = excess) */\n marginShortfall1: bigint\n /** Current (gross) margin (collateral balance), denominated in token0 */\n currentMargin0: bigint\n /** Current (gross) margin, denominated in token1 */\n currentMargin1: bigint\n /** Required margin (sum of per-position requirements), denominated in token0 */\n requiredMargin0: bigint\n /** Required margin, denominated in token1 */\n requiredMargin1: bigint\n /**\n * Which token the \"preferred\" margin pair is denominated in.\n * 0n = token0 (when atTick < 0), 1n = token1 (when atTick >= 0).\n */\n denominatedInToken: bigint\n /** Tick at which liquidation was checked */\n atTick: bigint\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Parameters for isLiquidatable.\n */\nexport interface IsLiquidatableParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account to check */\n account: Address\n /** TokenIds of open positions */\n tokenIds: bigint[]\n /**\n * Optional: Tick to check liquidation at (defaults to current tick).\n * Note: collateral requirements are evaluated by the contract at the\n * pool's current tick — `atTick` here governs only the cross-token\n * sqrtPrice used to express the totals in a single denomination.\n */\n atTick?: bigint\n /** PanopticQuery address (kept for backwards compatibility; unused). */\n queryAddress?: Address\n /**\n * Optional pre-fetched collateral tracker addresses (saves an RPC).\n * If omitted, they are fetched from the pool.\n */\n collateralAddresses?: { collateralToken0: Address; collateralToken1: Address }\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Check if an account is liquidatable with detailed margin breakdown.\n *\n * Sources gross collateral from `CollateralTracker.assetsOf` and per-position\n * required margin from `PanopticPool.getFullPositionsData.collateralRequirements[]`,\n * cross-converted to each token denomination at `atTick`. Loan tokenIds\n * (width=0 shorts) contribute correctly to required margin.\n *\n * @param params - The parameters\n * @returns Liquidation check result with detailed margin breakdown\n *\n * @example\n * ```typescript\n * const result = await isLiquidatable({\n * client,\n * poolAddress,\n * account,\n * tokenIds: [position1, position2],\n * })\n *\n * if (result.isLiquidatable) {\n * console.log('Account is liquidatable!')\n * }\n * ```\n */\nexport async function isLiquidatable(params: IsLiquidatableParams): Promise<LiquidationCheck> {\n const { client, poolAddress, account, tokenIds, atTick, blockNumber } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Resolve collateral tracker addresses (immutable; cache-friendly).\n let collateralToken0: Address\n let collateralToken1: Address\n if (params.collateralAddresses) {\n collateralToken0 = params.collateralAddresses.collateralToken0\n collateralToken1 = params.collateralAddresses.collateralToken1\n } else {\n const addrs = await client.multicall({\n contracts: [\n { address: poolAddress, abi: panopticPoolV2Abi, functionName: 'collateralToken0' },\n { address: poolAddress, abi: panopticPoolV2Abi, functionName: 'collateralToken1' },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n })\n collateralToken0 = addrs[0]\n collateralToken1 = addrs[1]\n }\n\n const calls: MulticallBlockCall[] = []\n const currentTickIndex = atTick === undefined ? calls.length : null\n if (currentTickIndex !== null) {\n calls.push({\n target: poolAddress,\n callData: encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n }),\n })\n }\n\n const assets0Index = calls.length\n calls.push({\n target: collateralToken0,\n callData: encodeFunctionData({\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n args: [account],\n }),\n })\n\n const assets1Index = calls.length\n calls.push({\n target: collateralToken1,\n callData: encodeFunctionData({\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n args: [account],\n }),\n })\n\n const positionDataIndex = tokenIds.length > 0 ? calls.length : null\n if (positionDataIndex !== null) {\n calls.push({\n target: poolAddress,\n callData: encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [account, true, tokenIds],\n }),\n })\n }\n\n const { _meta, results } = await readBlockAndAggregate({\n client,\n calls,\n blockNumber: targetBlockNumber,\n })\n\n let effectiveTick = atTick\n if (effectiveTick === undefined) {\n if (currentTickIndex === null) {\n throw new Error('Missing current tick Multicall3 result index')\n }\n effectiveTick = BigInt(\n decodeFunctionResult({\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n data: requireReturnData(results, currentTickIndex, 'PanopticPool.getCurrentTick'),\n }),\n )\n }\n const assets0 = decodeFunctionResult({\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n data: requireReturnData(results, assets0Index, 'CollateralTracker.assetsOf token0'),\n })\n const assets1 = decodeFunctionResult({\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n data: requireReturnData(results, assets1Index, 'CollateralTracker.assetsOf token1'),\n })\n const positionDataResult =\n positionDataIndex === null\n ? null\n : (decodeFunctionResult({\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n data: requireReturnData(results, positionDataIndex, 'PanopticPool.getFullPositionsData'),\n }) as readonly [bigint, bigint, readonly bigint[], readonly bigint[], readonly bigint[]])\n\n let required0Native = 0n\n let required1Native = 0n\n if (positionDataResult) {\n const collateralRequirements = positionDataResult[3]\n for (const packed of collateralRequirements) {\n const decoded = decodeLeftRightUnsigned(packed)\n required0Native += decoded.right\n required1Native += decoded.left\n }\n }\n\n const sqrtPriceX96 = tickToSqrtPriceX96(effectiveTick)\n const currentMargin0 = assets0 + convert1to0(assets1, sqrtPriceX96)\n const requiredMargin0 = required0Native + convert1to0(required1Native, sqrtPriceX96)\n const currentMargin1 = assets1 + convert0to1(assets0, sqrtPriceX96)\n const requiredMargin1 = required1Native + convert0to1(required0Native, sqrtPriceX96)\n\n const marginShortfall0 = requiredMargin0 - currentMargin0\n const marginShortfall1 = requiredMargin1 - currentMargin1\n const denominatedInToken: bigint = sqrtPriceX96 < FP96 ? 0n : 1n\n const isLiquidatableResult =\n denominatedInToken === 0n ? marginShortfall0 > 0n : marginShortfall1 > 0n\n\n return {\n isLiquidatable: isLiquidatableResult,\n marginShortfall0,\n marginShortfall1,\n currentMargin0,\n currentMargin1,\n requiredMargin0,\n requiredMargin1,\n denominatedInToken,\n atTick: effectiveTick,\n _meta,\n }\n}\n","/**\n * Account read functions for the Panoptic v2 SDK.\n *\n * ## Same-Block Guarantee\n *\n * All dynamic data is fetched in a SINGLE multicall to ensure block consistency.\n * Per PLAN.md §6, immutable \"static prefetch\" data (addresses) can be fetched\n * separately and cached - it's not subject to same-block consistency.\n *\n * @module v2/reads/account\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { collateralTrackerV2Abi, panopticPoolV2Abi } from '../../../generated'\nimport { panopticQueryAbi } from '../abis/panopticQuery'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport type {\n AccountCollateral,\n AccountSummaryBasic,\n AccountSummaryRisk,\n BlockMeta,\n LiquidationPrices,\n NetLiquidationValue,\n NetLiquidationValues,\n TokenCollateral,\n} from '../types'\nimport { isLiquidatable } from './checks'\nimport { type PoolMetadata, getPool } from './pool'\nimport { getPositions } from './position'\n\n/**\n * Collateral tracker addresses (immutable, can be cached).\n */\nexport interface CollateralAddresses {\n /** Collateral tracker 0 address */\n collateralToken0: Address\n /** Collateral tracker 1 address */\n collateralToken1: Address\n}\n\n/**\n * Extract collateral tracker addresses from a Pool object.\n *\n * Convenience helper that avoids re-fetching immutable addresses\n * when you already have a Pool from a prior `getPool()` call.\n *\n * @param pool - Pool object from getPool()\n * @returns Collateral tracker addresses\n */\nexport function getCollateralAddresses(pool: {\n collateralTracker0: { address: Address }\n collateralTracker1: { address: Address }\n}): CollateralAddresses {\n return {\n collateralToken0: pool.collateralTracker0.address,\n collateralToken1: pool.collateralTracker1.address,\n }\n}\n\n/**\n * Parameters for getAccountCollateral.\n */\nexport interface GetAccountCollateralParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched collateral addresses (for caching/optimization) */\n collateralAddresses?: CollateralAddresses\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get collateral data for an account.\n *\n * ## Same-Block Guarantee\n * All dynamic data is fetched in ONE multicall at the target block.\n * Collateral tracker addresses are either provided or fetched separately (static prefetch).\n *\n * @param params - The parameters\n * @returns Account collateral data with block metadata\n */\nexport async function getAccountCollateral(\n params: GetAccountCollateralParams,\n): Promise<AccountCollateral> {\n const { client, poolAddress, account, blockNumber, collateralAddresses } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Get collateral tracker addresses (static prefetch if not provided)\n let collateralToken0: Address\n let collateralToken1: Address\n\n if (collateralAddresses) {\n collateralToken0 = collateralAddresses.collateralToken0\n collateralToken1 = collateralAddresses.collateralToken1\n } else {\n // Static prefetch - addresses are immutable\n const addressResults = await client.multicall({\n contracts: [\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken0',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken1',\n },\n ],\n allowFailure: false,\n })\n collateralToken0 = addressResults[0]\n collateralToken1 = addressResults[1]\n }\n\n // SINGLE multicall for ALL dynamic data - ensures same-block consistency\n const [dynamicResults, _meta] = await Promise.all([\n client.multicall({\n contracts: [\n // Token 0 collateral data\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'balanceOf',\n args: [account],\n },\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n args: [account],\n },\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'maxWithdraw',\n args: [account],\n },\n // Token 1 collateral data\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'balanceOf',\n args: [account],\n },\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n args: [account],\n },\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'maxWithdraw',\n args: [account],\n },\n // Leg count from pool\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'numberOfLegs',\n args: [account],\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [shares0, assets0, maxWithdraw0, shares1, assets1, maxWithdraw1, legCount] = dynamicResults\n\n // Calculate locked assets as total - available (maxWithdraw)\n const locked0 = assets0 > maxWithdraw0 ? assets0 - maxWithdraw0 : 0n\n const locked1 = assets1 > maxWithdraw1 ? assets1 - maxWithdraw1 : 0n\n\n const token0: TokenCollateral = {\n assets: assets0,\n shares: shares0,\n availableAssets: maxWithdraw0,\n lockedAssets: locked0,\n }\n\n const token1: TokenCollateral = {\n assets: assets1,\n shares: shares1,\n availableAssets: maxWithdraw1,\n lockedAssets: locked1,\n }\n\n return {\n account,\n poolAddress,\n token0,\n token1,\n legCount,\n _meta,\n }\n}\n\n/**\n * Parameters for getAccountSummaryBasic.\n */\nexport interface GetAccountSummaryBasicParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** Chain ID */\n chainId: bigint\n /** TokenIds of open positions */\n tokenIds: bigint[]\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched pool metadata (for caching/optimization) */\n poolMetadata?: PoolMetadata\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Parameters for getAccountSummaryRisk.\n */\nexport interface GetAccountSummaryRiskParams extends GetAccountSummaryBasicParams {\n /** PanopticQuery address (required for risk fields) */\n queryAddress: Address\n /** Optional: Tick to calculate risk metrics at (defaults to current tick) */\n atTick?: bigint\n /** Optional: Whether to include pending premium in NLV */\n includePendingPremium?: boolean\n}\n\ninterface AccountSummaryCoreData {\n pool: Awaited<ReturnType<typeof getPool>>\n collateral: AccountCollateral\n positions: Awaited<ReturnType<typeof getPositions>>['positions']\n _meta: BlockMeta\n}\n\nasync function getAccountSummaryCore(\n params: GetAccountSummaryBasicParams,\n): Promise<AccountSummaryCoreData> {\n const { client, poolAddress, account, chainId, tokenIds, blockNumber, poolMetadata } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n const sharedMeta =\n params._meta ?? (await getBlockMeta({ client, blockNumber: targetBlockNumber }))\n\n const collateralAddresses = poolMetadata\n ? {\n collateralToken0: poolMetadata.collateralToken0Address,\n collateralToken1: poolMetadata.collateralToken1Address,\n }\n : undefined\n\n const [pool, collateral, { positions }] = await Promise.all([\n getPool({\n client,\n poolAddress,\n chainId,\n blockNumber: targetBlockNumber,\n poolMetadata,\n _meta: sharedMeta,\n }),\n getAccountCollateral({\n client,\n poolAddress,\n account,\n blockNumber: targetBlockNumber,\n collateralAddresses,\n _meta: sharedMeta,\n }),\n getPositions({\n client,\n poolAddress,\n owner: account,\n tokenIds,\n blockNumber: targetBlockNumber,\n _meta: sharedMeta,\n }),\n ])\n\n return {\n pool,\n collateral,\n positions,\n _meta: sharedMeta,\n }\n}\n\n/**\n * Get base account summary data for UI dashboards.\n *\n * ## Same-Block Guarantee\n * Uses the same blockNumber for pool, collateral, and position reads.\n *\n * @param params - The parameters\n * @returns Base account summary with block metadata\n */\nexport async function getAccountSummaryBasic(\n params: GetAccountSummaryBasicParams,\n): Promise<AccountSummaryBasic> {\n const { account } = params\n const { pool, collateral, positions, _meta } = await getAccountSummaryCore(params)\n\n return {\n account,\n pool,\n collateral,\n positions,\n healthStatus: pool.healthStatus,\n networkMismatch: false, // Requires wallet context, not available in read functions\n _meta,\n }\n}\n\n/**\n * Get risk-focused account summary including helper-dependent fields.\n *\n * ## Same-Block Guarantee\n * Uses one block target for all pool/collateral/position/risk reads.\n *\n * @param params - The parameters\n * @returns Risk-focused account summary with block metadata\n */\nexport async function getAccountSummaryRisk(\n params: GetAccountSummaryRiskParams,\n): Promise<AccountSummaryRisk> {\n const {\n client,\n poolAddress,\n account,\n tokenIds,\n queryAddress,\n atTick,\n includePendingPremium = true,\n blockNumber,\n } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n const sharedMeta =\n params._meta ?? (await getBlockMeta({ client, blockNumber: targetBlockNumber }))\n\n const [{ pool, collateral, positions }, nlv, liquidationCheck, liquidationPrices] =\n await Promise.all([\n getAccountSummaryCore({\n ...params,\n blockNumber: targetBlockNumber,\n _meta: sharedMeta,\n }),\n getNetLiquidationValue({\n client,\n poolAddress,\n account,\n tokenIds,\n atTick,\n includePendingPremium,\n queryAddress,\n blockNumber: targetBlockNumber,\n _meta: sharedMeta,\n }),\n isLiquidatable({\n client,\n poolAddress,\n account,\n tokenIds,\n atTick,\n queryAddress,\n blockNumber: targetBlockNumber,\n _meta: sharedMeta,\n }),\n getLiquidationPrices({\n client,\n poolAddress,\n account,\n tokenIds,\n queryAddress,\n blockNumber: targetBlockNumber,\n _meta: sharedMeta,\n }),\n ])\n\n const totalGreeks = {\n value: 0n,\n delta: 0n,\n gamma: 0n,\n }\n\n const maintenanceMargin0 = liquidationCheck.requiredMargin0\n const maintenanceMargin1 = liquidationCheck.requiredMargin1\n const marginExcess0 = liquidationCheck.currentMargin0 - liquidationCheck.requiredMargin0\n const marginExcess1 = liquidationCheck.currentMargin1 - liquidationCheck.requiredMargin1\n\n return {\n account,\n pool,\n collateral,\n positions,\n totalGreeks,\n netLiquidationValue0: nlv.value0,\n netLiquidationValue1: nlv.value1,\n maintenanceMargin0,\n maintenanceMargin1,\n marginExcess0,\n marginExcess1,\n marginShortfall0: liquidationCheck.marginShortfall0,\n marginShortfall1: liquidationCheck.marginShortfall1,\n currentMargin0: liquidationCheck.currentMargin0,\n currentMargin1: liquidationCheck.currentMargin1,\n isLiquidatable: liquidationCheck.isLiquidatable,\n liquidationPrices,\n healthStatus: pool.healthStatus,\n networkMismatch: false, // Requires wallet context, not available in read functions\n _meta: sharedMeta,\n }\n}\n\n/**\n * Parameters for getNetLiquidationValue.\n */\nexport interface GetNetLiquidationValueParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** TokenIds of open positions */\n tokenIds: bigint[]\n /** Optional: Tick to calculate NLV at (defaults to current tick) */\n atTick?: bigint\n /** Optional: Whether to include pending premium */\n includePendingPremium?: boolean\n /** PanopticQuery address (required) */\n queryAddress: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get net liquidation value for an account.\n *\n * ## Same-Block Guarantee\n * Tick and NLV are queried at the same target block.\n *\n * Requires PanopticQuery for accurate value and premium accounting.\n *\n * @param params - The parameters\n * @returns Net liquidation value with block metadata\n */\nexport async function getNetLiquidationValue(\n params: GetNetLiquidationValueParams,\n): Promise<NetLiquidationValue> {\n const {\n client,\n poolAddress,\n account,\n tokenIds,\n atTick,\n includePendingPremium = true,\n queryAddress,\n blockNumber,\n } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Skip getCurrentTick RPC call when atTick is provided\n const [currentTickResult, _meta] = await Promise.all([\n atTick != null\n ? Promise.resolve(atTick)\n : client\n .readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n blockNumber: targetBlockNumber,\n })\n .then((r) => BigInt(r)),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const effectiveTick = currentTickResult\n\n // PanopticQuery only exposes the int24[] overload; query a single tick and unwrap.\n const result = await client.readContract({\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'getNetLiquidationValue',\n args: [poolAddress, account, includePendingPremium, tokenIds, [Number(effectiveTick)]],\n blockNumber: targetBlockNumber,\n })\n\n const [values0, values1] = result\n const value0 = values0[0]\n const value1 = values1[0]\n\n return {\n value0,\n value1,\n atTick: effectiveTick,\n includedPendingPremium: includePendingPremium,\n _meta,\n }\n}\n\n/**\n * Parameters for getNetLiquidationValues (batch/multi-tick).\n */\nexport interface GetNetLiquidationValuesParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** TokenIds of open positions */\n tokenIds: bigint[]\n /** Ticks to calculate NLV at */\n atTicks: bigint[]\n /** Optional: Whether to include pending premium */\n includePendingPremium?: boolean\n /** PanopticQuery address (required) */\n queryAddress: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get net liquidation values at multiple ticks in a single contract call.\n *\n * Uses the `int24[]` overload of `getNetLiquidationValue` on PanopticQuery.\n *\n * @param params - The parameters\n * @returns Net liquidation values with block metadata\n */\nexport async function getNetLiquidationValues(\n params: GetNetLiquidationValuesParams,\n): Promise<NetLiquidationValues> {\n const {\n client,\n poolAddress,\n account,\n tokenIds,\n atTicks,\n includePendingPremium = true,\n queryAddress,\n blockNumber,\n } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Use an isolated ABI with only the int24[] overload to avoid viem overload ambiguity\n const batchNlvAbi = [\n {\n type: 'function' as const,\n name: 'getNetLiquidationValue' as const,\n inputs: [\n { name: 'pool', type: 'address' as const },\n { name: 'account', type: 'address' as const },\n { name: 'includePendingPremium', type: 'bool' as const },\n { name: 'positionIdList', type: 'uint256[]' as const },\n { name: 'atTicks', type: 'int24[]' as const },\n ],\n outputs: [\n { name: 'value0', type: 'int256[]' as const },\n { name: 'value1', type: 'int256[]' as const },\n ],\n stateMutability: 'view' as const,\n },\n ] as const\n\n const [result, _meta] = await Promise.all([\n client.readContract({\n address: queryAddress,\n abi: batchNlvAbi,\n functionName: 'getNetLiquidationValue',\n args: [poolAddress, account, includePendingPremium, tokenIds, atTicks.map((t) => Number(t))],\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [values0, values1] = result\n\n return {\n values0: [...values0],\n values1: [...values1],\n atTicks,\n _meta,\n }\n}\n\n/**\n * Parameters for getLiquidationPrices.\n */\nexport interface GetLiquidationPricesParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** TokenIds of open positions */\n tokenIds: bigint[]\n /** PanopticQuery address (required) */\n queryAddress: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get liquidation prices for an account.\n *\n * ## Same-Block Guarantee\n * Liquidation price query is made at a single block.\n *\n * @param params - The parameters\n * @returns Liquidation prices with block metadata\n */\nexport async function getLiquidationPrices(\n params: GetLiquidationPricesParams,\n): Promise<LiquidationPrices> {\n const { client, poolAddress, account, tokenIds, queryAddress, blockNumber } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // MIN_TICK and MAX_TICK indicate no liquidation at that boundary\n const MIN_TICK = -887272n\n const MAX_TICK = 887272n\n\n const [result, _meta] = await Promise.all([\n client.readContract({\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'getLiquidationPrices',\n args: [poolAddress, account, tokenIds],\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n // Convert from number (abitype default for int24) to bigint (viem runtime type)\n const liqPriceDown = BigInt(result[0])\n const liqPriceUp = BigInt(result[1])\n\n return {\n lowerTick: liqPriceDown === MIN_TICK ? null : liqPriceDown,\n upperTick: liqPriceUp === MAX_TICK ? null : liqPriceUp,\n isLiquidatable: liqPriceDown !== MIN_TICK || liqPriceUp !== MAX_TICK,\n _meta,\n }\n}\n","/**\n * Collateral read functions for the Panoptic v2 SDK.\n *\n * ## Same-Block Guarantee\n *\n * All dynamic data is fetched in a SINGLE multicall to ensure block consistency.\n * Per PLAN.md §6, immutable \"static prefetch\" data (addresses, symbols, decimals)\n * can be fetched separately and cached - it's not subject to same-block consistency.\n *\n * @module v2/reads/collateral\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { collateralTrackerV2Abi, panopticPoolV2Abi } from '../../../generated'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport type { BlockMeta, CollateralTracker, CurrentRates } from '../types'\n\nconst SECONDS_PER_YEAR = 31_536_000n\n\n// ERC20 minimal ABI for token metadata\nconst erc20Abi = [\n {\n type: 'function',\n name: 'symbol',\n inputs: [],\n outputs: [{ type: 'string' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'decimals',\n inputs: [],\n outputs: [{ type: 'uint8' }],\n stateMutability: 'view',\n },\n] as const\n\n/**\n * Pre-fetched collateral tracker metadata (immutable, can be cached).\n */\nexport interface CollateralTrackerMetadata {\n /** Collateral tracker address */\n address: Address\n /** Underlying asset address */\n assetAddress: Address\n /** Token symbol */\n symbol: string\n /** Token decimals */\n decimals: bigint\n}\n\n/**\n * Parameters for getCollateralData.\n */\nexport interface GetCollateralDataParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Which token's collateral tracker to query (0 or 1) */\n tokenIndex: 0 | 1\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched collateral tracker metadata (for caching/optimization) */\n trackerMetadata?: CollateralTrackerMetadata\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get collateral tracker data for a specific token.\n *\n * ## Same-Block Guarantee\n * All dynamic data is fetched in ONE multicall at the target block.\n * Static metadata (address, symbol, decimals) is either provided or fetched separately.\n *\n * @param params - The parameters\n * @returns Collateral tracker data with block metadata\n */\nexport async function getCollateralData(\n params: GetCollateralDataParams,\n): Promise<CollateralTracker & { _meta: BlockMeta }> {\n const { client, poolAddress, tokenIndex, blockNumber, trackerMetadata } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // If metadata is provided, we only need ONE multicall for dynamic data\n if (trackerMetadata) {\n const [dynamicResults, _meta] = await Promise.all([\n client.multicall({\n contracts: [\n {\n address: trackerMetadata.address,\n abi: collateralTrackerV2Abi,\n functionName: 'getPoolData',\n },\n {\n address: trackerMetadata.address,\n abi: collateralTrackerV2Abi,\n functionName: 'totalSupply',\n },\n {\n address: trackerMetadata.address,\n abi: collateralTrackerV2Abi,\n functionName: 'interestRate',\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [poolData, totalShares, interestRate] = dynamicResults\n const [depositedAssets, insideAMM, creditedShares, utilization] = poolData\n const totalAssets = depositedAssets + insideAMM\n\n const borrowRate = BigInt(interestRate) * SECONDS_PER_YEAR\n const supplyRate = (borrowRate * utilization) / 10000n\n\n return {\n address: trackerMetadata.address,\n token: trackerMetadata.assetAddress,\n symbol: trackerMetadata.symbol,\n decimals: trackerMetadata.decimals,\n totalAssets,\n insideAMM,\n creditedShares,\n totalShares,\n utilization,\n borrowRate,\n supplyRate,\n _meta,\n }\n }\n\n // Without metadata, fetch everything (original structure for backwards compatibility)\n // 1. Get tracker address (static)\n const collateralTrackerAddress = await client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: tokenIndex === 0 ? 'collateralToken0' : 'collateralToken1',\n })\n\n // 2. Get asset + dynamic data in one multicall (same-block guarantee for dynamic data)\n const [trackerData, _meta] = await Promise.all([\n client.multicall({\n contracts: [\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'asset',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'getPoolData',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'totalSupply',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'interestRate',\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [assetAddress, poolData, totalShares, interestRate] = trackerData\n\n // 3. Get token metadata (static - can be cached)\n const [symbol, decimals] = await client.multicall({\n contracts: [\n {\n address: assetAddress,\n abi: erc20Abi,\n functionName: 'symbol',\n },\n {\n address: assetAddress,\n abi: erc20Abi,\n functionName: 'decimals',\n },\n ],\n allowFailure: false,\n })\n\n // poolData returns: (depositedAssets, insideAMM, creditedShares, currentPoolUtilization)\n const [depositedAssets, insideAMM, creditedShares, utilization] = poolData\n const totalAssets = depositedAssets + insideAMM\n\n // Annualize rates: interestRate() returns WAD/s\n const borrowRate = BigInt(interestRate) * SECONDS_PER_YEAR\n const supplyRate = (borrowRate * utilization) / 10000n\n\n return {\n address: collateralTrackerAddress,\n token: assetAddress,\n symbol,\n decimals: BigInt(decimals),\n totalAssets,\n insideAMM,\n creditedShares,\n totalShares,\n utilization,\n borrowRate,\n supplyRate,\n _meta,\n }\n}\n\n/**\n * Collateral tracker addresses (immutable, can be cached).\n */\nexport interface CollateralAddresses {\n /** Collateral tracker 0 address */\n collateralToken0: Address\n /** Collateral tracker 1 address */\n collateralToken1: Address\n}\n\n/**\n * Parameters for getCurrentRates.\n */\nexport interface GetCurrentRatesParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched collateral tracker addresses (for caching/optimization) */\n collateralAddresses?: CollateralAddresses\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get current interest rates for both tokens.\n *\n * ## Same-Block Guarantee\n * All dynamic data is fetched in ONE multicall at the target block.\n * Collateral tracker addresses are either provided or fetched separately (static prefetch).\n *\n * @param params - The parameters\n * @returns Current rates with block metadata\n */\nexport async function getCurrentRates(params: GetCurrentRatesParams): Promise<CurrentRates> {\n const { client, poolAddress, blockNumber, collateralAddresses } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Get collateral tracker addresses (static prefetch if not provided)\n let collateralToken0: Address\n let collateralToken1: Address\n\n if (collateralAddresses) {\n collateralToken0 = collateralAddresses.collateralToken0\n collateralToken1 = collateralAddresses.collateralToken1\n } else {\n // Static prefetch - addresses are immutable\n const addressResults = await client.multicall({\n contracts: [\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken0',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken1',\n },\n ],\n allowFailure: false,\n })\n collateralToken0 = addressResults[0]\n collateralToken1 = addressResults[1]\n }\n\n // SINGLE multicall for ALL dynamic data - ensures same-block consistency\n const [rateData, _meta] = await Promise.all([\n client.multicall({\n contracts: [\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'interestRate',\n },\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'getPoolData',\n },\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'interestRate',\n },\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'getPoolData',\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [interestRate0, poolData0, interestRate1, poolData1] = rateData\n\n // Extract utilization from pool data\n const utilization0 = poolData0[3]\n const utilization1 = poolData1[3]\n\n // Annualize rates: interestRate() returns WAD/s\n const borrowRate0 = BigInt(interestRate0) * SECONDS_PER_YEAR\n const borrowRate1 = BigInt(interestRate1) * SECONDS_PER_YEAR\n\n // Supply rate = borrow rate * utilization (utilization is in bps, so /10000)\n const supplyRate0 = (borrowRate0 * utilization0) / 10000n\n const supplyRate1 = (borrowRate1 * utilization1) / 10000n\n\n return {\n borrowRate0,\n supplyRate0,\n borrowRate1,\n supplyRate1,\n _meta,\n }\n}\n\n// ─── Interest State (per-user borrows) ───────────────────────────────────────\n\n/**\n * Per-user interest state for a single collateral tracker.\n */\nexport interface TokenInterestState {\n /** User's borrow index snapshot (int128) */\n userBorrowIndex: bigint\n /** User's net borrows: positive = borrowing, negative = net supplying (int128) */\n netBorrows: bigint\n}\n\n/**\n * Interest state for both tokens in a Panoptic pool.\n */\nexport interface InterestState {\n /** Token 0 interest state */\n token0: TokenInterestState\n /** Token 1 interest state */\n token1: TokenInterestState\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Parameters for getInterestState.\n */\nexport interface GetInterestStateParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address to query */\n account: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched collateral tracker addresses */\n collateralAddresses?: CollateralAddresses\n /** Optional pre-fetched block metadata */\n _meta?: BlockMeta\n}\n\n/**\n * Get per-user interest state (borrow index + net borrows) for both tokens.\n *\n * Calls `collateralTracker.interestState(user)` on both trackers in a single multicall.\n *\n * @param params - The parameters\n * @returns Interest state for both tokens with block metadata\n */\nexport async function getInterestState(params: GetInterestStateParams): Promise<InterestState> {\n const { client, poolAddress, account, blockNumber, collateralAddresses } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n let collateralToken0: Address\n let collateralToken1: Address\n\n if (collateralAddresses) {\n collateralToken0 = collateralAddresses.collateralToken0\n collateralToken1 = collateralAddresses.collateralToken1\n } else {\n const addressResults = await client.multicall({\n contracts: [\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken0',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken1',\n },\n ],\n allowFailure: false,\n })\n collateralToken0 = addressResults[0]\n collateralToken1 = addressResults[1]\n }\n\n const [results, _meta] = await Promise.all([\n client.multicall({\n contracts: [\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'interestState',\n args: [account],\n },\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'interestState',\n args: [account],\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [state0, state1] = results\n\n return {\n token0: { userBorrowIndex: state0[0], netBorrows: state0[1] },\n token1: { userBorrowIndex: state1[0], netBorrows: state1[1] },\n _meta,\n }\n}\n","/**\n * Interest rate model (IRM) reads for Panoptic v2.\n * @module v2/reads/irm\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { collateralTrackerV2Abi, riskEngineAbi } from '../../../generated'\nimport { PanopticValidationError } from '../errors/sdk'\nimport type { IrmCurrent, IrmMarketStateInputs, IrmPoint } from '../types/irm'\nexport type { IrmCurrent, IrmMarketStateInputs, IrmPoint } from '../types/irm'\n\nexport const WAD = 10n ** 18n\nexport const BPS_SCALE = 10_000n\nexport const SECONDS_PER_YEAR = 31_536_000n\nexport const MARKET_EPOCH_SHIFT = 2n\nexport const BORROW_INDEX_BITS = 80n\nexport const MARKET_EPOCH_BITS = 32n\nexport const RATE_AT_TARGET_BITS = 38n\nexport const UNREALIZED_INTEREST_BITS = 106n\n\nconst BORROW_INDEX_SHIFT = 0n\nconst MARKET_EPOCH_FIELD_SHIFT = BORROW_INDEX_BITS\nconst RATE_AT_TARGET_FIELD_SHIFT = BORROW_INDEX_BITS + MARKET_EPOCH_BITS\nconst UNREALIZED_INTEREST_FIELD_SHIFT = RATE_AT_TARGET_FIELD_SHIFT + RATE_AT_TARGET_BITS\nconst MAX_IRM_CURVE_POINTS = 500\n\nconst clampUtilizationBps = (utilizationBps: bigint): bigint => {\n if (utilizationBps < 0n) {\n return 0n\n }\n if (utilizationBps > BPS_SCALE) {\n return BPS_SCALE\n }\n return utilizationBps\n}\n\nconst getMaxValue = (bits: bigint): bigint => (1n << bits) - 1n\n\nconst assertFitsBits = (value: bigint, bits: bigint, fieldName: string): void => {\n if (value < 0n) {\n throw new PanopticValidationError(`${fieldName} must be >= 0`)\n }\n if (value > getMaxValue(bits)) {\n throw new PanopticValidationError(`${fieldName} exceeds ${bits.toString()} bits`)\n }\n}\n\nexport function packMarketState(inputs: IrmMarketStateInputs): bigint {\n const { borrowIndex, lastInteractionTimestamp, rateAtTarget, unrealizedGlobalInterest } = inputs\n const marketEpoch = lastInteractionTimestamp >> MARKET_EPOCH_SHIFT\n\n assertFitsBits(borrowIndex, BORROW_INDEX_BITS, 'borrowIndex')\n assertFitsBits(marketEpoch, MARKET_EPOCH_BITS, 'marketEpoch')\n assertFitsBits(rateAtTarget, RATE_AT_TARGET_BITS, 'rateAtTarget')\n assertFitsBits(unrealizedGlobalInterest, UNREALIZED_INTEREST_BITS, 'unrealizedGlobalInterest')\n\n return (\n (borrowIndex << BORROW_INDEX_SHIFT) +\n (marketEpoch << MARKET_EPOCH_FIELD_SHIFT) +\n (rateAtTarget << RATE_AT_TARGET_FIELD_SHIFT) +\n (unrealizedGlobalInterest << UNREALIZED_INTEREST_FIELD_SHIFT)\n )\n}\n\nexport function utilizationPctToWad(utilizationPct: number): bigint {\n if (!Number.isFinite(utilizationPct)) {\n throw new PanopticValidationError('utilizationPct must be finite')\n }\n if (utilizationPct < 0 || utilizationPct > 100) {\n throw new PanopticValidationError('utilizationPct must be between 0 and 100')\n }\n\n const scaledPct = Math.round(utilizationPct * 1_000_000)\n return (BigInt(scaledPct) * WAD) / 100_000_000n\n}\n\nexport function utilizationBpsToWad(utilizationBps: bigint): bigint {\n return (clampUtilizationBps(utilizationBps) * WAD) / BPS_SCALE\n}\n\nexport function ratePerSecWadToAprPct(ratePerSecWad: bigint): number {\n return (Number(ratePerSecWad) * Number(SECONDS_PER_YEAR) * 100) / Number(WAD)\n}\n\nexport function deriveSupplyRatePerSecWad(\n borrowRatePerSecWad: bigint,\n utilizationWad: bigint,\n): bigint {\n return (borrowRatePerSecWad * utilizationWad) / WAD\n}\n\nexport async function getIrmCurrent(params: {\n client: PublicClient\n collateralTrackerAddress: Address\n blockNumber?: bigint\n}): Promise<IrmCurrent> {\n const { client, collateralTrackerAddress, blockNumber } = params\n const [\n borrowIndex,\n lastInteractionTimestamp,\n rateAtTarget,\n unrealizedGlobalInterest,\n poolData,\n riskEngineAddress,\n ] = await client.multicall({\n contracts: [\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'borrowIndex',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'lastInteractionTimestamp',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'rateAtTarget',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'unrealizedGlobalInterest',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'getPoolData',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'riskEngine',\n },\n ],\n blockNumber,\n allowFailure: false,\n })\n\n const currentUtilizationBps = clampUtilizationBps(poolData[3])\n const currentUtilizationWad = utilizationBpsToWad(currentUtilizationBps)\n const currentUtilizationPct = Number(currentUtilizationBps) / 100\n\n const marketStatePacked = packMarketState({\n borrowIndex,\n lastInteractionTimestamp,\n rateAtTarget,\n unrealizedGlobalInterest,\n })\n\n const borrowRatePerSecWad = await client.readContract({\n address: riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'interestRate',\n args: [currentUtilizationWad, marketStatePacked],\n blockNumber,\n })\n\n const supplyRatePerSecWad = deriveSupplyRatePerSecWad(borrowRatePerSecWad, currentUtilizationWad)\n\n return {\n collateralTrackerAddress,\n riskEngineAddress,\n currentUtilizationBps,\n currentUtilizationWad,\n currentUtilizationPct,\n borrowRatePerSecWad,\n supplyRatePerSecWad,\n borrowAprPct: ratePerSecWadToAprPct(borrowRatePerSecWad),\n supplyAprPct: ratePerSecWadToAprPct(supplyRatePerSecWad),\n marketStatePacked,\n }\n}\n\nexport async function getIrmCurve(params: {\n client: PublicClient\n collateralTrackerAddress: Address\n points?: number\n blockNumber?: bigint\n}): Promise<{\n current: IrmCurrent\n points: IrmPoint[]\n}> {\n const { client, collateralTrackerAddress, points = 201, blockNumber } = params\n\n if (!Number.isInteger(points) || points < 2) {\n throw new PanopticValidationError('points must be an integer >= 2')\n }\n if (points > MAX_IRM_CURVE_POINTS) {\n throw new PanopticValidationError(`points must be <= ${MAX_IRM_CURVE_POINTS}`)\n }\n\n const current = await getIrmCurrent({\n client,\n collateralTrackerAddress,\n blockNumber,\n })\n\n const denominator = BigInt(points - 1)\n const contracts = Array.from({ length: points }, (_, idx) => {\n const i = BigInt(idx)\n const utilizationWad = (i * WAD) / denominator\n\n return {\n address: current.riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'interestRate' as const,\n args: [utilizationWad, current.marketStatePacked] as const,\n }\n })\n\n const borrowRatesPerSecWad = await client.multicall({\n contracts,\n blockNumber,\n allowFailure: false,\n })\n\n const curvePoints: IrmPoint[] = borrowRatesPerSecWad.map((borrowRatePerSecWad, idx) => {\n const i = BigInt(idx)\n const utilizationWad = (i * WAD) / denominator\n const supplyRatePerSecWad = deriveSupplyRatePerSecWad(borrowRatePerSecWad, utilizationWad)\n\n return {\n utilizationWad,\n utilizationPct: (idx * 100) / (points - 1),\n borrowRatePerSecWad,\n supplyRatePerSecWad,\n borrowAprPct: ratePerSecWadToAprPct(borrowRatePerSecWad),\n supplyAprPct: ratePerSecWadToAprPct(supplyRatePerSecWad),\n }\n })\n\n return {\n current,\n points: curvePoints,\n }\n}\n","/**\n * Token flow simulation utility using PanopticPool.multicall.\n *\n * Uses getAssetsOf-dispatch-getAssetsOf pattern within a single eth_call\n * to measure exact collateral asset movements from any dispatch call.\n *\n * @module v2/simulations/tokenFlow\n */\n\nimport {\n type Address,\n type Hex,\n type PublicClient,\n decodeFunctionResult,\n encodeFunctionData,\n} from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { panopticErrorsAbi } from '../errors/errorsAbi'\n\n/**\n * PanopticPool getAssetsOf ABI.\n * Returns collateral assets (shares converted to underlying) for an account.\n */\nconst getAssetsOfAbi = [\n {\n type: 'function',\n name: 'getAssetsOf',\n inputs: [{ name: 'account', type: 'address' }],\n outputs: [\n { name: 'assets0', type: 'uint256' },\n { name: 'assets1', type: 'uint256' },\n ],\n stateMutability: 'view',\n },\n] as const\n\n/**\n * PanopticPool multicall ABI (inherited from Uniswap).\n * Uses delegatecall, preserving msg.sender throughout the chain.\n */\nconst multicallAbi = [\n {\n type: 'function',\n name: 'multicall',\n inputs: [{ name: 'data', type: 'bytes[]' }],\n outputs: [{ name: 'results', type: 'bytes[]' }],\n stateMutability: 'nonpayable',\n },\n // Include error definitions so viem can decode revert data with full args\n ...panopticErrorsAbi,\n] as const\n\n/**\n * Token flow result from simulation.\n * Measures collateral asset changes via getAssetsOf-dispatch-getAssetsOf pattern.\n */\nexport interface TokenFlow {\n /** Token 0 collateral change (negative = user deposits, positive = user receives) */\n delta0: bigint\n /** Token 1 collateral change (negative = user deposits, positive = user receives) */\n delta1: bigint\n /** Collateral assets in token 0 before the call */\n balanceBefore0: bigint\n /** Collateral assets in token 1 before the call */\n balanceBefore1: bigint\n /** Collateral assets in token 0 after the call */\n balanceAfter0: bigint\n /** Collateral assets in token 1 after the call */\n balanceAfter1: bigint\n /** Pool tick before the operation */\n tickBefore: bigint | null\n /** Pool tick after the operation */\n tickAfter: bigint | null\n}\n\n/**\n * Parameters for simulateWithTokenFlow.\n */\nexport interface SimulateWithTokenFlowParams {\n /** viem public client */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** User address whose collateral changes we're measuring */\n user: Address\n /** Encoded call data (typically dispatch) */\n callData: Hex\n /** Optional block number for simulation */\n blockNumber?: bigint\n /**\n * Optional additional encoded calls to append after the 5-call pattern.\n * These execute post-dispatch within the same multicall (same state).\n * Raw encoded bytes are returned in `postCallResults`.\n */\n postCallData?: Hex[]\n /**\n * Optional additional encoded calls to insert between the pre-dispatch\n * `getAssetsOf` / `getCurrentTick` and the target call. These execute\n * pre-dispatch within the same multicall — useful for reading per-position\n * data (e.g. `getFullPositionsData`) against the original `positionIdList`\n * before state mutates. Raw encoded bytes are returned in `preCallResults`.\n */\n preCallData?: Hex[]\n}\n\n/**\n * Result of simulateWithTokenFlow.\n */\nexport interface SimulateWithTokenFlowResult {\n /** Whether the simulation succeeded */\n success: boolean\n /** Token flow data (only if success) */\n tokenFlow?: TokenFlow\n /** Error message (only if failed) */\n error?: string\n /** Raw error object preserving viem cause chain and revert data */\n rawError?: Error\n /** Gas estimate for the inner call */\n gasEstimate: bigint\n /** Raw results from postCallData entries (only if success and postCallData was provided) */\n postCallResults?: Hex[]\n /** Raw results from preCallData entries (only if success and preCallData was provided) */\n preCallResults?: Hex[]\n}\n\n/**\n * Simulate a contract call and measure token flow using PanopticPool.multicall.\n *\n * This function uses PanopticPool's inherited multicall (delegatecall-based) to chain:\n * 1. getAssetsOf(user) - read collateral assets before\n * 2. getCurrentTick() - read pool tick before\n * 3. Execute the target call (e.g., dispatch)\n * 4. getCurrentTick() - read pool tick after\n * 5. getAssetsOf(user) - read collateral assets after\n *\n * ## Why PanopticPool.multicall instead of Multicall3?\n * - Measures **collateral assets** (shares → underlying), not raw wallet balances\n * - Uses **delegatecall**, preserving msg.sender throughout the chain\n * - Single contract interaction with PanopticPool\n * - Correctly reflects what happens during position operations\n *\n * ## Same-Block Guarantee\n * All operations execute within a single eth_call, ensuring atomic consistency.\n *\n * @param params - Simulation parameters\n * @returns Token flow result\n *\n * @example\n * ```typescript\n * const callData = encodeFunctionData({\n * abi: panopticPoolV2Abi,\n * functionName: 'dispatch',\n * args: [positionIdList, finalPositionIdList, positionSizes, tickAndSpreadLimits, false, 0n],\n * })\n *\n * const result = await simulateWithTokenFlow({\n * client,\n * poolAddress,\n * user: userAddress,\n * callData,\n * })\n *\n * if (result.success) {\n * console.log('Token 0 change:', result.tokenFlow.delta0)\n * console.log('Token 1 change:', result.tokenFlow.delta1)\n * }\n * ```\n */\nexport async function simulateWithTokenFlow(\n params: SimulateWithTokenFlowParams,\n): Promise<SimulateWithTokenFlowResult> {\n const { client, poolAddress, user, callData, blockNumber, postCallData, preCallData } = params\n\n // Encode getAssetsOf call\n const getAssetsOfCallData = encodeFunctionData({\n abi: getAssetsOfAbi,\n functionName: 'getAssetsOf',\n args: [user],\n })\n\n // Encode getCurrentTick call\n const getCurrentTickCallData = encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n })\n\n const preLen = preCallData?.length ?? 0\n\n // Build multicall: [getAssetsOf, getCurrentTick, ...preCallData, targetCall, getCurrentTick, getAssetsOf, ...postCallData]\n const multicallData: Hex[] = [\n getAssetsOfCallData,\n getCurrentTickCallData,\n ...(preCallData ?? []),\n callData,\n getCurrentTickCallData,\n getAssetsOfCallData,\n ...(postCallData ?? []),\n ]\n\n try {\n // Execute via simulateContract on PanopticPool's multicall\n const { result } = await client.simulateContract({\n address: poolAddress,\n abi: multicallAbi,\n functionName: 'multicall',\n args: [multicallData],\n account: user,\n blockNumber,\n })\n\n // Decode getAssetsOf results\n const decodeAssets = (data: Hex): { assets0: bigint; assets1: bigint } => {\n const decoded = decodeFunctionResult({\n abi: getAssetsOfAbi,\n functionName: 'getAssetsOf',\n data,\n })\n return { assets0: decoded[0], assets1: decoded[1] }\n }\n\n // Decode getCurrentTick result (int24 decodes as number, convert to bigint)\n const decodeTick = (data: Hex): bigint => {\n return BigInt(\n decodeFunctionResult({\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n data,\n }),\n )\n }\n\n const assetsBefore = decodeAssets(result[0])\n const tickBefore = decodeTick(result[1])\n // result[2..2+preLen-1] are preCallData results\n // result[2+preLen] is the target call result (dispatch)\n const tickAfter = decodeTick(result[3 + preLen])\n const assetsAfter = decodeAssets(result[4 + preLen])\n\n const preCallResults = preLen > 0 ? (result.slice(2, 2 + preLen) as Hex[]) : undefined\n const postCallResults =\n postCallData && postCallData.length > 0 ? (result.slice(5 + preLen) as Hex[]) : undefined\n\n const delta0 = assetsAfter.assets0 - assetsBefore.assets0\n const delta1 = assetsAfter.assets1 - assetsBefore.assets1\n\n // Estimate gas for the target call directly\n let gasEstimate = 0n\n try {\n gasEstimate = await client.estimateGas({\n account: user,\n to: poolAddress,\n data: callData,\n blockNumber,\n })\n } catch {\n // Gas estimation may fail, use 0\n }\n\n return {\n success: true,\n tokenFlow: {\n delta0,\n delta1,\n balanceBefore0: assetsBefore.assets0,\n balanceBefore1: assetsBefore.assets1,\n balanceAfter0: assetsAfter.assets0,\n balanceAfter1: assetsAfter.assets1,\n tickBefore,\n tickAfter,\n },\n gasEstimate,\n postCallResults,\n preCallResults,\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Simulation failed',\n rawError: error instanceof Error ? error : undefined,\n gasEstimate: 0n,\n }\n }\n}\n\n/**\n * Parameters for getting pool tokens.\n */\nexport interface GetPoolTokensParams {\n /** viem public client */\n client: PublicClient\n /** Pool address */\n poolAddress: Address\n /** Optional block number */\n blockNumber?: bigint\n}\n\n/**\n * Pool token addresses result.\n */\nexport interface PoolTokens {\n /** Token 0 address */\n token0: Address\n /** Token 1 address */\n token1: Address\n /** Collateral tracker 0 address */\n collateralTracker0: Address\n /** Collateral tracker 1 address */\n collateralTracker1: Address\n}\n\n/**\n * Get pool token addresses for reference.\n *\n * @param params - Parameters\n * @returns Pool token addresses\n */\nexport async function getPoolTokensForSimulation(params: GetPoolTokensParams): Promise<PoolTokens> {\n const { client, poolAddress, blockNumber } = params\n\n // Minimal ABI for the calls we need\n const poolAbi = [\n {\n type: 'function',\n name: 'collateralToken0',\n inputs: [],\n outputs: [{ type: 'address' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'collateralToken1',\n inputs: [],\n outputs: [{ type: 'address' }],\n stateMutability: 'view',\n },\n ] as const\n\n const collateralAbi = [\n {\n type: 'function',\n name: 'asset',\n inputs: [],\n outputs: [{ type: 'address' }],\n stateMutability: 'view',\n },\n ] as const\n\n // Get collateral tracker addresses\n const [ct0, ct1] = await client.multicall({\n contracts: [\n { address: poolAddress, abi: poolAbi, functionName: 'collateralToken0' },\n { address: poolAddress, abi: poolAbi, functionName: 'collateralToken1' },\n ],\n blockNumber,\n allowFailure: false,\n })\n\n // Get underlying token addresses from collateral trackers\n const [token0, token1] = await client.multicall({\n contracts: [\n { address: ct0, abi: collateralAbi, functionName: 'asset' },\n { address: ct1, abi: collateralAbi, functionName: 'asset' },\n ],\n blockNumber,\n allowFailure: false,\n })\n\n return {\n token0,\n token1,\n collateralTracker0: ct0,\n collateralTracker1: ct1,\n }\n}\n","/**\n * Price conversion between the two pool tokens at a given sqrtPriceX96.\n *\n * Mirrors the on-chain `PanopticMath.convert0to1` / `convert1to0` truncation,\n * with an overflow-safe branch for when `sqrtPriceX96^2` would not fit in a\n * uint256.\n *\n * @module v2/utils/priceConvert\n */\n\nimport { PanopticError } from '../errors'\n\nconst Q128 = 1n << 128n\n\n/**\n * A non-positive price has no meaningful conversion, and `convert1to0` would\n * divide by zero — surface that as a typed SDK error rather than a RangeError\n * thrown from inside the arithmetic.\n */\nfunction assertPositivePrice(sqrtPriceX96: bigint): void {\n if (sqrtPriceX96 <= 0n) {\n throw new PanopticError(`sqrtPriceX96 must be positive, got ${sqrtPriceX96}`)\n }\n}\n\n/** Convert a token0 amount to its token1-equivalent at the given sqrtPriceX96. */\nexport function convert0to1(amount: bigint, sqrtPriceX96: bigint): bigint {\n assertPositivePrice(sqrtPriceX96)\n if (sqrtPriceX96 < Q128) {\n return (amount * sqrtPriceX96 * sqrtPriceX96) >> 192n\n }\n const sp2Hi = (sqrtPriceX96 * sqrtPriceX96) >> 64n\n return (amount * sp2Hi) >> 128n\n}\n\n/** Convert a token1 amount to its token0-equivalent at the given sqrtPriceX96. */\nexport function convert1to0(amount: bigint, sqrtPriceX96: bigint): bigint {\n assertPositivePrice(sqrtPriceX96)\n if (sqrtPriceX96 < Q128) {\n const denom = sqrtPriceX96 * sqrtPriceX96\n return (amount * (1n << 192n)) / denom\n }\n const sp2Hi = (sqrtPriceX96 * sqrtPriceX96) >> 64n\n return (amount * (1n << 128n)) / sp2Hi\n}\n\n/**\n * Convert an amount denominated in `fromTokenIndex` into the other token's\n * terms, so the two sides of a pool flow can be compared on one scale.\n */\nexport function convertToTokenIndex(\n amount: bigint,\n fromTokenIndex: bigint,\n toTokenIndex: bigint,\n sqrtPriceX96: bigint,\n): bigint {\n if (fromTokenIndex === toTokenIndex) return amount\n return fromTokenIndex === 0n\n ? convert0to1(amount, sqrtPriceX96)\n : convert1to0(amount, sqrtPriceX96)\n}\n","/**\n * Snapshot recovery from dispatch calldata.\n * @module v2/sync/snapshotRecovery\n */\n\nimport type { AbiFunction, Address, Hash, Hex, PublicClient } from 'viem'\nimport { decodeFunctionData, getAddress, parseAbi, toFunctionSelector } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\n\nconst LOG_SCAN_WINDOW = 10_000n\nconst rolesExecutionAbi = parseAbi([\n 'function execTransactionWithRole(address to, uint256 value, bytes data, uint8 operation, bytes32 roleKey, bool shouldRevert)',\n])\n\ntype SnapshotEventLog = Awaited<ReturnType<PublicClient['getLogs']>>[number]\ntype SnapshotCandidateEvent = SnapshotEventLog & {\n transactionHash: Hash\n blockNumber: bigint\n logIndex: number\n}\n\n/**\n * Parameters for recovering position snapshot from dispatch calldata.\n */\nexport interface RecoverSnapshotParams {\n /** viem public client */\n client: PublicClient\n /** Pool address */\n poolAddress: Address\n /** Account to recover positions for */\n account: Address\n /** Starting block for transaction search (defaults to 0) */\n fromBlock?: bigint\n /** Ending block for transaction search (defaults to latest) */\n toBlock?: bigint\n}\n\n/**\n * Snapshot recovery result.\n */\nexport interface SnapshotRecoveryResult {\n /** Whether recovery was successful */\n success: boolean\n /** Position IDs from the final position list */\n positionIds: bigint[]\n /** Block number of the recovery transaction */\n blockNumber: bigint\n /** Block hash of the recovery transaction */\n blockHash: Hash\n /** Transaction hash used for recovery */\n transactionHash: Hash\n}\n\n/**\n * Recover position snapshot from the last dispatch transaction.\n * This is the primary recovery method - it finds the most recent dispatch()\n * call and extracts the finalPositionIdList from the calldata.\n *\n * @param params - Recovery parameters\n * @returns Snapshot recovery result\n */\nexport async function recoverSnapshot(\n params: RecoverSnapshotParams,\n): Promise<SnapshotRecoveryResult | null> {\n const { client, poolAddress, account, toBlock } = params\n\n // Get the latest block if not specified\n const latestBlock = toBlock ?? (await client.getBlockNumber())\n\n // Search for transactions from the account to the pool\n // We need to find dispatch() or dispatchFrom() calls\n // Note: This requires the account to have sent transactions directly,\n // or we need to look at internal transactions\n\n // Strategy: Look for OptionMinted or OptionBurnt events to find transactions,\n // then decode the transaction input to get the full position list\n\n const searchFromBlock = params.fromBlock ?? 0n\n if (latestBlock < searchFromBlock) return null\n\n // Fast path: a single getLogs per event type over the entire\n // [searchFromBlock, latest] range. The queries are filtered by `address` and\n // an indexed account topic, so providers like Alchemy impose no block-range\n // cap on them (only a result-count cap) — one call per event type is enough\n // and the returned set is already complete, so there are no older windows to\n // scan. This avoids walking the whole chain in 10k-block chunks (4 getLogs\n // per chunk), which for accounts with no history is thousands of empty calls.\n try {\n const events = await getSnapshotEventsForWindow({\n client,\n poolAddress,\n account,\n fromBlock: searchFromBlock,\n toBlock: latestBlock,\n })\n return await recoverSnapshotFromEvents({ client, account, events })\n } catch (error) {\n // Only fall back to windowed scanning when the provider rejected the wide\n // range. Any other error (e.g. transport failure) should propagate.\n if (!isRangeLimitError(error)) throw error\n }\n\n // Fallback for providers that cap getLogs block range: scan newest-to-oldest\n // in 10k-block windows and stop at the first window that yields a snapshot.\n let windowToBlock = latestBlock\n while (true) {\n const windowFromBlock =\n windowToBlock - searchFromBlock + 1n > LOG_SCAN_WINDOW\n ? windowToBlock - LOG_SCAN_WINDOW + 1n\n : searchFromBlock\n\n const events = await getSnapshotEventsForWindow({\n client,\n poolAddress,\n account,\n fromBlock: windowFromBlock,\n toBlock: windowToBlock,\n })\n const snapshot = await recoverSnapshotFromEvents({ client, account, events })\n if (snapshot) return snapshot\n\n if (windowFromBlock === searchFromBlock) break\n windowToBlock = windowFromBlock - 1n\n }\n\n // No snapshot found\n return null\n}\n\n/**\n * Detect provider errors that indicate the requested getLogs block range was\n * too wide (so the caller should retry with smaller windows). Covers the common\n * phrasings used by Alchemy, Infura, and other JSON-RPC providers.\n */\nfunction isRangeLimitError(error: unknown): boolean {\n const parts: string[] = []\n let current: unknown = error\n let depth = 0\n while (current && typeof current === 'object' && depth < 5) {\n const obj = current as Record<string, unknown>\n if (typeof obj.message === 'string') parts.push(obj.message)\n if (typeof obj.details === 'string') parts.push(obj.details)\n current = obj.cause\n depth += 1\n }\n if (typeof error === 'string') parts.push(error)\n\n const message = parts.join(' ').toLowerCase()\n if (!message) return false\n\n return (\n message.includes('block range') ||\n message.includes('range is too large') ||\n message.includes('range too large') ||\n message.includes('query returned more than') ||\n message.includes('too many results') ||\n message.includes('log response size exceeded') ||\n message.includes('exceeds the limit') ||\n (message.includes('range') && message.includes('limit'))\n )\n}\n\nasync function getSnapshotEventsForWindow(params: {\n client: PublicClient\n poolAddress: Address\n account: Address\n fromBlock: bigint\n toBlock: bigint\n}): Promise<SnapshotEventLog[]> {\n const { client, poolAddress, account, fromBlock, toBlock } = params\n\n // OptionMinted/OptionBurnt cover the account's own dispatches.\n // ForcedExercised/AccountLiquidated cover third-party dispatchFrom calls\n // where the tx sender is not the account but calldata contains the final list.\n const [mintEvents, burnEvents, forceExerciseEvents, liquidationEvents] = await Promise.all([\n client.getLogs({\n address: poolAddress,\n event: {\n type: 'event',\n name: 'OptionMinted',\n inputs: [\n { type: 'address', name: 'recipient', indexed: true },\n { type: 'uint256', name: 'tokenId', indexed: true },\n { type: 'uint256', name: 'balanceData', indexed: false },\n ],\n },\n args: {\n recipient: account,\n },\n fromBlock,\n toBlock,\n }),\n client.getLogs({\n address: poolAddress,\n event: {\n type: 'event',\n name: 'OptionBurnt',\n inputs: [\n { type: 'address', name: 'recipient', indexed: true },\n { type: 'uint128', name: 'positionSize', indexed: false },\n { type: 'uint256', name: 'tokenId', indexed: true },\n { type: 'int256[4]', name: 'premiaByLeg', indexed: false },\n ],\n },\n args: {\n recipient: account,\n },\n fromBlock,\n toBlock,\n }),\n client.getLogs({\n address: poolAddress,\n event: {\n type: 'event',\n name: 'ForcedExercised',\n inputs: [\n { type: 'address', name: 'exercisor', indexed: true },\n { type: 'address', name: 'user', indexed: true },\n { type: 'uint256', name: 'tokenId', indexed: true },\n { type: 'int256', name: 'exerciseFee', indexed: false },\n ],\n },\n args: {\n user: account,\n },\n fromBlock,\n toBlock,\n }),\n client.getLogs({\n address: poolAddress,\n event: {\n type: 'event',\n name: 'AccountLiquidated',\n inputs: [\n { type: 'address', name: 'liquidator', indexed: true },\n { type: 'address', name: 'liquidatee', indexed: true },\n { type: 'int256', name: 'bonusAmounts', indexed: false },\n ],\n },\n args: {\n liquidatee: account,\n },\n fromBlock,\n toBlock,\n }),\n ])\n\n return [...mintEvents, ...burnEvents, ...forceExerciseEvents, ...liquidationEvents]\n}\n\nasync function recoverSnapshotFromEvents(params: {\n client: PublicClient\n account: Address\n events: SnapshotEventLog[]\n}): Promise<SnapshotRecoveryResult | null> {\n const { client, account, events } = params\n\n // Combine and sort by block number (descending) to get most recent first\n const allEvents = events.filter(isSnapshotCandidateEvent).sort((a, b) => {\n const blockDiff = Number(b.blockNumber - a.blockNumber)\n if (blockDiff !== 0) return blockDiff\n return Number(b.logIndex - a.logIndex)\n })\n\n // Deduplicate by transaction hash — multiple events from the same tx\n // (e.g. OptionMinted for each leg) would produce duplicate entries\n const seen = new Set<string>()\n const uniqueEvents = allEvents.filter((e) => {\n if (seen.has(e.transactionHash)) return false\n seen.add(e.transactionHash)\n return true\n })\n\n // Find the most recent transaction with position data\n for (const event of uniqueEvents) {\n try {\n const [tx, block] = await Promise.all([\n client.getTransaction({ hash: event.transactionHash }),\n client.getBlock({ blockNumber: event.blockNumber }),\n ])\n\n // A single tx (e.g. a force-exercise multicall) can embed several\n // dispatch/dispatchFrom calls — the exercisor's own dispatch alongside the\n // victim's dispatchFrom. Select a strict account match first, then allow a\n // plain dispatch only because this tx came from an account-indexed event.\n const candidates = decodeAllDispatchCalldata(tx.input)\n const decoded =\n selectDispatchForAccount(candidates, account, tx.from) ??\n selectDispatchProvenByAccountEvent(candidates)\n if (!decoded) {\n continue\n }\n\n return {\n success: true,\n positionIds: decoded.positionIds,\n blockNumber: event.blockNumber,\n blockHash: block.hash,\n transactionHash: event.transactionHash,\n }\n } catch {\n // Transaction fetch failed, continue\n }\n }\n\n return null\n}\n\nfunction isSnapshotCandidateEvent(event: SnapshotEventLog): event is SnapshotCandidateEvent {\n return event.transactionHash !== null && event.blockNumber !== null && event.logIndex !== null\n}\n\n/**\n * Parameters for recovering a snapshot from a known transaction hash.\n */\nexport interface RecoverSnapshotFromTxParams {\n /** viem public client */\n client: PublicClient\n /** Transaction hash of a known dispatch() call */\n transactionHash: Hash\n /** Account to verify. When set, rejects transactions not sent by (or targeting) this account. */\n account?: Address\n /** Pool address to validate against. When set, rejects transactions not sent to this pool. */\n pool?: Address\n /** Expected Zodiac Roles wrapper for bot-originated Safe dispatches. */\n rolesContext?: {\n modifier: Address\n member: Address\n roleKey: Hash\n }\n}\n\nexport interface RolesSnapshotContext {\n modifier: Address\n member: Address\n roleKey: Hash\n}\n\nexport function decodeSnapshotTransaction(params: {\n input: Hex\n from: Address\n to: Address | null\n account?: Address\n pool?: Address\n rolesContext?: RolesSnapshotContext\n}): DispatchCalldata | null {\n const { account, pool, rolesContext } = params\n let dispatchInput = params.input\n let dispatchSender = params.from\n\n if (rolesContext) {\n if (\n params.to === null ||\n getAddress(params.to) !== getAddress(rolesContext.modifier) ||\n getAddress(params.from) !== getAddress(rolesContext.member)\n ) {\n return null\n }\n try {\n const decodedRoleCall = decodeFunctionData({ abi: rolesExecutionAbi, data: params.input })\n const [target, value, data, operation, roleKey, shouldRevert] = decodedRoleCall.args\n if (\n !pool ||\n getAddress(target) !== getAddress(pool) ||\n value !== 0n ||\n operation !== 0 ||\n roleKey.toLowerCase() !== rolesContext.roleKey.toLowerCase() ||\n !shouldRevert\n ) {\n return null\n }\n dispatchInput = data\n if (!account) return null\n dispatchSender = account\n } catch {\n return null\n }\n } else if (pool && (params.to === null || getAddress(params.to) !== getAddress(pool))) {\n return null\n }\n\n const candidates = decodeAllDispatchCalldata(dispatchInput)\n if (candidates.length === 0) return null\n return account\n ? selectDispatchForAccount(candidates, account, dispatchSender)\n : candidates[candidates.length - 1]\n}\n\n/**\n * Recover position snapshot from a specific dispatch transaction hash.\n *\n * This is an O(1) alternative to {@link recoverSnapshot} when you already\n * know the tx hash of the most recent dispatch. It fetches the transaction,\n * decodes the `finalPositionIdList` from the calldata, and returns the result\n * — no event scanning required.\n *\n * @param params - Recovery parameters including the transaction hash\n * @returns Snapshot recovery result, or null if the tx is not a dispatch call\n *\n * @example\n * ```typescript\n * const snapshot = await recoverSnapshotFromTx({\n * client,\n * transactionHash: '0xabc...',\n * })\n * if (snapshot) {\n * console.log('Open positions:', snapshot.positionIds)\n * }\n * ```\n */\nexport async function recoverSnapshotFromTx(\n params: RecoverSnapshotFromTxParams,\n): Promise<SnapshotRecoveryResult | null> {\n const { client, transactionHash, account, pool, rolesContext } = params\n\n const tx = await client.getTransaction({ hash: transactionHash })\n\n // Pending transactions have no block number — cannot recover snapshot\n if (tx.blockNumber == null) return null\n\n const decoded = decodeSnapshotTransaction({\n input: tx.input,\n from: tx.from,\n to: tx.to,\n account,\n pool,\n rolesContext,\n })\n if (!decoded) return null\n\n const blockNumber = tx.blockNumber\n const block = await client.getBlock({ blockNumber })\n\n return {\n success: true,\n positionIds: decoded.positionIds,\n blockNumber,\n blockHash: block.hash,\n transactionHash,\n }\n}\n\n/**\n * Decoded dispatch calldata result.\n */\nexport interface DispatchCalldata {\n /** Final position ID list after the dispatch */\n positionIds: bigint[]\n /** Target account (only set for dispatchFrom) */\n targetAccount?: Address\n}\n\n/**\n * Decode position IDs from dispatch calldata.\n *\n * When the tx embeds multiple dispatch/dispatchFrom calls (e.g. a force-exercise\n * multicall), this returns the last one — prefer {@link decodeAllDispatchCalldata}\n * plus {@link selectDispatchForAccount} when the account context matters.\n *\n * @param input - Transaction input data\n * @returns Decoded dispatch data or null if not a dispatch call\n */\nexport function decodeDispatchCalldata(input: `0x${string}`): DispatchCalldata | null {\n const all = decodeAllDispatchCalldata(input)\n return all.length > 0 ? all[all.length - 1] : null\n}\n\n/**\n * Decode every dispatch/dispatchFrom call embedded in transaction calldata.\n *\n * A single tx can carry more than one such call — most importantly a force-exercise\n * `multicall` that bundles the exercisor's own `dispatch` together with the victim's\n * `dispatchFrom`. Returning all candidates lets the caller select the one attributable\n * to the relevant account ({@link selectDispatchForAccount}).\n *\n * @param input - Transaction input data\n * @returns All decoded dispatch calls, in calldata order (may be empty)\n */\nexport function decodeAllDispatchCalldata(input: `0x${string}`): DispatchCalldata[] {\n // Try direct dispatch/dispatchFrom first\n const direct = decodeDirectDispatch(input)\n if (direct) return [direct]\n\n // Try unwrapping smart contract wallet wrappers (executeBatch, execute, multicall)\n return decodeWrappedDispatch(input)\n}\n\n/**\n * Select the dispatch call attributable to `account` from a set of candidates.\n *\n * - `dispatchFrom`: matches when `targetAccount === account` (builder/exercisor acting\n * on behalf of the account).\n * - `dispatch` (no `targetAccount`): matches only when the tx sender is the account.\n *\n * Returns the LAST matching candidate (in calldata order), or null when none are\n * attributable to `account`. The last dispatch reflects the final post-transaction\n * state when a single tx contains multiple dispatches for the same account (e.g. a\n * multicall). Matching also prevents accepting a third party's `dispatch` (e.g. the\n * exercisor's own, bundled in a force-exercise multicall) as the account's snapshot.\n *\n * @param candidates - Decoded dispatch calls from a single tx, in calldata order\n * @param account - Account whose position list we are recovering\n * @param txFrom - The transaction sender (`tx.from`)\n */\nexport function selectDispatchForAccount(\n candidates: DispatchCalldata[],\n account: Address,\n txFrom: Address,\n): DispatchCalldata | null {\n const acct = account.toLowerCase()\n let match: DispatchCalldata | null = null\n for (const candidate of candidates) {\n if (candidate.targetAccount) {\n if (candidate.targetAccount.toLowerCase() === acct) match = candidate\n } else if (txFrom.toLowerCase() === acct) {\n match = candidate\n }\n }\n return match\n}\n\nfunction selectDispatchProvenByAccountEvent(\n candidates: DispatchCalldata[],\n): DispatchCalldata | null {\n let match: DispatchCalldata | null = null\n for (const candidate of candidates) {\n if (candidate.targetAccount === undefined) match = candidate\n }\n return match\n}\n\n/**\n * Try to decode input as a direct dispatch or dispatchFrom call.\n */\nfunction decodeDirectDispatch(input: `0x${string}`): DispatchCalldata | null {\n try {\n const decoded = decodeFunctionData({\n abi: panopticPoolV2Abi,\n data: input,\n })\n\n if (decoded.functionName === 'dispatch') {\n const args = decoded.args as readonly [\n bigint[],\n bigint[],\n bigint[],\n readonly [number, number, number][],\n boolean,\n bigint,\n ]\n return { positionIds: [...args[1]] } // finalPositionIdList\n }\n\n if (decoded.functionName === 'dispatchFrom') {\n const args = decoded.args as readonly [bigint[], Address, bigint[], bigint[], bigint]\n return {\n positionIds: [...args[3]], // positionIdListToFinal\n targetAccount: args[1],\n }\n }\n\n return null\n } catch {\n return null\n }\n}\n\n/**\n * 4-byte function selectors for dispatch/dispatchFrom, derived from the generated ABI.\n * Used for scanning raw calldata inside smart contract wallet wrappers.\n */\nconst DISPATCH_SELECTOR = toFunctionSelector(\n panopticPoolV2Abi.find((e) => e.type === 'function' && e.name === 'dispatch') as AbiFunction,\n).slice(2) // strip 0x prefix for hex scanning\n\nconst DISPATCH_FROM_SELECTOR = toFunctionSelector(\n panopticPoolV2Abi.find((e) => e.type === 'function' && e.name === 'dispatchFrom') as AbiFunction,\n).slice(2)\n\n/**\n * Scan raw transaction input for embedded dispatch calldata.\n *\n * Smart contract wallets (Safe, Turnkey, ERC-4337) and vault managers\n * wrap dispatch calls inside executeBatch → manage → dispatch chains.\n * Instead of decoding each wrapper layer, we scan the raw hex for the\n * dispatch function selector and attempt to decode from that offset.\n *\n * This handles arbitrary nesting depth without knowing wrapper ABIs.\n */\nfunction decodeWrappedDispatch(input: `0x${string}`): DispatchCalldata[] {\n const hex = input.slice(2).toLowerCase()\n const selectors = [DISPATCH_SELECTOR, DISPATCH_FROM_SELECTOR]\n\n // Single left-to-right pass: find the earliest selector match at each offset and\n // collect every successful decode, in calldata order. The caller selects the call\n // attributable to the relevant account rather than blindly taking one.\n const results: DispatchCalldata[] = []\n let offset = 0\n\n while (offset < hex.length) {\n // Find the nearest selector match from current offset\n let earliestIdx = -1\n for (const selector of selectors) {\n const idx = hex.indexOf(selector, offset)\n if (idx !== -1 && (earliestIdx === -1 || idx < earliestIdx)) {\n earliestIdx = idx\n }\n }\n if (earliestIdx === -1) break\n\n const candidate = `0x${hex.slice(earliestIdx)}` as `0x${string}`\n const result = decodeDirectDispatch(candidate)\n if (result) results.push(result)\n\n offset = earliestIdx + 8 // Move past this selector\n }\n\n return results\n}\n","/**\n * Get tracked position IDs from local cache.\n * @module v2/sync/getTrackedPositionIds\n */\n\nimport type { Address, Hash, PublicClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport type { StorageAdapter } from '../storage'\nimport { getPositionsKey, jsonSerializer } from '../storage'\nimport {\n type SnapshotRecoveryResult,\n recoverSnapshot,\n recoverSnapshotFromTx,\n} from './snapshotRecovery'\n\n/**\n * Verify that a recovered position-id list still matches the account's current\n * on-chain state. `getFullPositionsData` reverts when the list contains a\n * tokenId the account no longer holds, so a successful call is proof the list\n * is live. Returns `false` on revert so the caller can fall back to an\n * authoritative event scan instead of trusting a stale checkpoint.\n */\nasync function isPositionListLive(params: {\n client: PublicClient\n poolAddress: Address\n account: Address\n positionIds: bigint[]\n blockNumber?: bigint\n}): Promise<boolean> {\n const { client, poolAddress, account, positionIds, blockNumber } = params\n // An empty list is always a valid (positionless) state — no need to probe.\n if (positionIds.length === 0) return true\n try {\n await client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [account, false, positionIds],\n blockNumber,\n })\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Parameters for getTrackedPositionIds.\n */\nexport interface GetTrackedPositionIdsParams {\n /** Chain ID */\n chainId: bigint\n /** Pool address */\n poolAddress: Address\n /** Account to get positions for */\n account: Address\n /** Storage adapter */\n storage: StorageAdapter\n}\n\n/**\n * Get all tracked position IDs for an account from local cache.\n *\n * This function reads from the storage adapter without making RPC calls.\n * The positions returned may include closed positions if the cache is stale.\n * Use `getPositions()` for authoritative on-chain data.\n *\n * @param params - Query parameters\n * @returns Array of position token IDs\n */\nexport async function getTrackedPositionIds(\n params: GetTrackedPositionIdsParams,\n): Promise<bigint[]> {\n const { chainId, poolAddress, account, storage } = params\n\n const key = getPositionsKey(chainId, poolAddress, account)\n const data = await storage.get(key)\n\n if (!data) {\n return []\n }\n\n try {\n const positionIds = jsonSerializer.parse(data) as bigint[]\n return positionIds\n } catch {\n // Corrupted data, return empty\n return []\n }\n}\n\n/**\n * Check if a specific position ID is tracked.\n *\n * @param params - Query parameters\n * @param tokenId - Token ID to check\n * @returns Whether the position is tracked\n */\nexport async function isPositionTracked(\n params: GetTrackedPositionIdsParams,\n tokenId: bigint,\n): Promise<boolean> {\n const positionIds = await getTrackedPositionIds(params)\n return positionIds.some((id) => id === tokenId)\n}\n\n/**\n * Clear all tracked positions for an account.\n *\n * @param params - Query parameters\n */\nexport async function clearTrackedPositions(params: GetTrackedPositionIdsParams): Promise<void> {\n const { chainId, poolAddress, account, storage } = params\n\n const key = getPositionsKey(chainId, poolAddress, account)\n await storage.delete(key)\n}\n\n/**\n * Parameters for getOpenPositionIds.\n */\nexport interface GetOpenPositionIdsParams {\n /** viem PublicClient */\n client: PublicClient\n /** Chain ID */\n chainId: bigint\n /** Pool address */\n poolAddress: Address\n /** Account to get positions for */\n account: Address\n /** Storage adapter (used to update local cache with the authoritative list) */\n storage?: StorageAdapter\n /**\n * Transaction hash of a known dispatch() call. When provided, the position\n * list is decoded directly from this tx's calldata (O(1)) instead of\n * scanning events to find the most recent dispatch.\n */\n lastDispatchTxHash?: Hash\n /**\n * Starting block for event scanning in recoverSnapshot.\n * When set, limits the getLogs window to [fromBlock, latest] instead of\n * scanning from block 0. Use the checkpoint's lastBlock for incremental syncs.\n */\n fromBlock?: bigint\n /** Upper bound for fallback event recovery. */\n toBlock?: bigint\n /** Expected Zodiac Roles wrapper for a bot-relayed Safe dispatch. */\n rolesContext?: {\n modifier: Address\n member: Address\n roleKey: Hash\n }\n}\n\n/**\n * Get the authoritative list of open position IDs from the chain.\n *\n * Recovers the `finalPositionIdList` from the account's most recent\n * `dispatch()` transaction calldata. This is the on-chain–validated set of\n * open positions (verified against `s_positionsHash` by the contract) and\n * requires only a few RPC calls regardless of account history length.\n *\n * This is the recommended way to get position IDs for `existingPositionIds`\n * (openPosition) and `positionIdList` (closePosition).\n *\n * If `storage` is provided, the local cache is updated with the result.\n *\n * @param params - Query parameters\n * @returns Array of currently open position token IDs, or null if no snapshot was found\n */\nexport async function getOpenPositionIds(\n params: GetOpenPositionIdsParams,\n): Promise<bigint[] | null> {\n const {\n client,\n chainId,\n poolAddress,\n account,\n storage,\n lastDispatchTxHash,\n fromBlock,\n toBlock,\n rolesContext,\n } = params\n\n // Fast path: decode directly from a known tx hash (O(1), no event scanning).\n // The tx's finalPositionIdList only reflects state as of THAT dispatch — if\n // positions changed afterwards (e.g. a dispatch this caller never recorded),\n // the list is stale and would revert downstream reads. So we validate the\n // recovered list against current on-chain state and fall through to the\n // authoritative event scan when it no longer matches.\n let snapshot: SnapshotRecoveryResult | null = null\n if (lastDispatchTxHash) {\n try {\n const candidate = await recoverSnapshotFromTx({\n client,\n transactionHash: lastDispatchTxHash,\n account,\n pool: poolAddress,\n rolesContext,\n })\n if (\n candidate &&\n (await isPositionListLive({\n client,\n poolAddress,\n account,\n positionIds: candidate.positionIds,\n blockNumber: toBlock,\n }))\n ) {\n snapshot = candidate\n }\n } catch {\n // Fast path failed (e.g. RPC error, validation mismatch); fall through to slow-path\n snapshot = null\n }\n }\n\n if (!snapshot) {\n snapshot = await recoverSnapshot({ client, poolAddress, account, fromBlock, toBlock })\n }\n\n if (!snapshot) {\n return null\n }\n\n // Update local cache if storage provided\n if (storage) {\n const key = getPositionsKey(chainId, poolAddress, account)\n await storage.set(key, jsonSerializer.stringify(snapshot.positionIds))\n }\n\n return snapshot.positionIds\n}\n","/**\n * Shared loan utilities for swap and lending modules.\n * @module v2/writes/loanUtils\n */\n\nimport type { Address } from 'viem'\n\nimport {\n InputListFailError,\n LoanSlotExhaustedError,\n MissingPositionIdsError,\n parsePanopticError,\n SwapTokenMismatchError,\n} from '../errors'\nimport type { StorageAdapter } from '../storage'\nimport { getTrackedPositionIds } from '../sync/getTrackedPositionIds'\nimport { createTokenIdBuilder } from '../tokenId/builder'\n\n/** Maximum retry attempts on InputListFail */\nexport const MAX_RETRIES = 3\n\n/**\n * Resolve token index (0 or 1) for the given token address against the pool.\n * Throws SwapTokenMismatchError if the token isn't in the pool.\n */\nexport function resolveTokenIndex(tokenAddress: Address, token0: Address, token1: Address): bigint {\n const lower = tokenAddress.toLowerCase()\n if (lower === token0.toLowerCase()) return 0n\n if (lower === token1.toLowerCase()) return 1n\n throw new SwapTokenMismatchError(tokenAddress, token0, token1)\n}\n\n/**\n * Resolve existing position IDs from explicit param or storage.\n */\nexport async function resolvePositionIds(\n explicit: bigint[] | undefined,\n storage: StorageAdapter | undefined,\n chainId: bigint,\n poolAddress: Address,\n account: Address,\n): Promise<bigint[]> {\n if (explicit !== undefined) return explicit\n if (storage) {\n return getTrackedPositionIds({ chainId, poolAddress, account, storage })\n }\n throw new MissingPositionIdsError()\n}\n\n/**\n * Check if a caught error is an InputListFail contract revert.\n * Works with both raw viem errors and parsed PanopticError instances.\n */\nexport function isInputListFailError(error: unknown): boolean {\n if (error instanceof InputListFailError) return true\n const parsed = parsePanopticError(error)\n return parsed?.errorName === 'InputListFail'\n}\n\n/**\n * Which kind of width=0 leg to build.\n *\n * Loans and credits are the same primitive with the `isLong` bit flipped:\n * a loan borrows from the pool (`isLong=0`), a credit pays into it\n * (`isLong=1`). See `createTokenIdBuilder`'s `addLoan` / `addCredit`.\n */\nexport type WidthZeroLegKind = 'loan' | 'credit'\n\n/**\n * Build a unique width=0 tokenId that doesn't collide with existing positions.\n * Bumps optionRatio (1-127) and returns adjusted size to maintain equivalent exposure.\n *\n * @param kind - Whether to build a loan (borrow) or a credit (pay-in) leg.\n * @param asset - Which token denominates the positionSize (0 or 1).\n */\nexport function buildUniqueWidthZeroLeg(\n kind: WidthZeroLegKind,\n poolId: bigint,\n asset: bigint,\n tokenType: bigint,\n currentTick: bigint,\n tickSpacing: bigint,\n existingPositionIds: bigint[],\n positionSize: bigint,\n): { tokenId: bigint; adjustedSize: bigint } {\n const addLeg = (strike: bigint, optionRatio?: bigint): bigint => {\n const builder = createTokenIdBuilder(poolId)\n const config = { asset, tokenType, strike, optionRatio }\n return (kind === 'loan' ? builder.addLoan(config) : builder.addCredit(config)).build()\n }\n\n // Floor-align to tick spacing (bigint % preserves sign, so handle negatives)\n const mod = currentTick % tickSpacing\n let strike = currentTick - ((mod + tickSpacing) % tickSpacing)\n\n for (let ratio = 1n; ratio <= 127n; ratio++) {\n const tokenId = addLeg(strike, ratio)\n\n if (!existingPositionIds.includes(tokenId)) {\n const adjustedSize = positionSize / ratio\n if (adjustedSize === 0n || positionSize % ratio !== 0n) {\n continue\n }\n return { tokenId, adjustedSize }\n }\n }\n\n // Fallback: try different strikes at ratio=1\n const mod2 = currentTick % tickSpacing\n strike = currentTick - ((mod2 + tickSpacing) % tickSpacing) + tickSpacing\n for (let i = 0; i < 100; i++) {\n const tokenId = addLeg(strike)\n\n if (!existingPositionIds.includes(tokenId)) {\n return { tokenId, adjustedSize: positionSize }\n }\n strike += tickSpacing\n }\n\n throw new LoanSlotExhaustedError()\n}\n\n/**\n * Build a unique loan (borrow) tokenId that doesn't collide with existing positions.\n *\n * @param asset - Which token denominates the positionSize (0 or 1).\n */\nexport function buildUniqueLoan(\n poolId: bigint,\n asset: bigint,\n tokenType: bigint,\n currentTick: bigint,\n tickSpacing: bigint,\n existingPositionIds: bigint[],\n positionSize: bigint,\n): { tokenId: bigint; adjustedSize: bigint } {\n return buildUniqueWidthZeroLeg(\n 'loan',\n poolId,\n asset,\n tokenType,\n currentTick,\n tickSpacing,\n existingPositionIds,\n positionSize,\n )\n}\n\n/**\n * Build a unique credit (pay-in) tokenId that doesn't collide with existing positions.\n *\n * Unlike a loan, a credit never borrows from the pool: it requires **zero** buying\n * power, leaves `s_assetsInAMM` (and therefore utilization and the borrow rate)\n * untouched, and accrues no interest. This is what lets a credit-based swap run\n * against a fully-utilized collateral tracker.\n *\n * @param asset - Which token denominates the positionSize (0 or 1).\n */\nexport function buildUniqueCredit(\n poolId: bigint,\n asset: bigint,\n tokenType: bigint,\n currentTick: bigint,\n tickSpacing: bigint,\n existingPositionIds: bigint[],\n positionSize: bigint,\n): { tokenId: bigint; adjustedSize: bigint } {\n return buildUniqueWidthZeroLeg(\n 'credit',\n poolId,\n asset,\n tokenType,\n currentTick,\n tickSpacing,\n existingPositionIds,\n positionSize,\n )\n}\n","/**\n * Shared construction for dispatches wrapped in a temporary width=0 **credit**\n * leg, used to move token flow from one collateral token to the other inside a\n * single `dispatch()`.\n *\n * A credit rather than a loan: a credit pays into the pool instead of borrowing\n * from it, so it requires zero buying power, never touches `s_assetsInAMM`, and\n * can never be capped by a collateral tracker's utilization.\n *\n * @module v2/simulations/creditWrap\n */\n\nimport type { BatchDispatchArgs } from '../batch/types'\nimport type { TickAndSpreadLimits } from '../writes/position'\n\n/**\n * Pre-encoded `dispatch()` arguments a credit wrap is applied to.\n *\n * Alias of {@link BatchDispatchArgs} — the two are the same concept.\n */\nexport type DispatchIntent = BatchDispatchArgs\n\n/**\n * Which side of the swap is exact.\n *\n * - `exact-out`: the credit **sources** a known amount of its token, paying a\n * swapped amount of the counter-token. Mint carries `swapAtMint=true`.\n * - `exact-in`: the credit **sells** a known amount of its token, receiving a\n * swapped amount of the counter-token. Burn carries `swapAtMint=true`.\n */\nexport type CreditWrapDirection = 'exact-in' | 'exact-out'\n\n/**\n * Where the two credit legs sit relative to the user's own operations.\n *\n * - `straddle`: mint first, user ops, burn last. Required for `exact-out`, where\n * the sourced token must be available while the user's ops run.\n * - `prepend`: both legs before the user's ops. Used by bootstrap recovery when\n * the account can sell one collateral token but holds none of the token it needs.\n * - `append`: both legs after the user's ops, for flows where the token being\n * sold does not exist until those operations run.\n */\nexport type CreditWrapPlacement = 'append' | 'prepend' | 'straddle'\n\nexport interface BuildCreditWrappedDispatchParams {\n dispatch: DispatchIntent\n /** The temporary width=0 credit leg. */\n creditTokenId: bigint\n /** Size of the mint leg. The burn leg always passes `0n` (= burn all). */\n creditPositionSize: bigint\n tickLimitLow: bigint\n tickLimitHigh: bigint\n direction: CreditWrapDirection\n placement: CreditWrapPlacement\n}\n\n/**\n * Wrap a dispatch with a temporary credit leg that is opened and closed in the\n * same transaction, netting to a swap.\n *\n * `swapAtMint` is not a calldata flag — it is the ORDER of the tick-limit pair:\n * descending `[high, low]` turns the swap on, ascending `[low, high]` leaves it\n * off. Exactly one of the two legs carries it, and which one is what makes the\n * swap exact-in vs exact-out.\n */\nexport function buildCreditWrappedDispatch(\n params: BuildCreditWrappedDispatchParams,\n): DispatchIntent {\n const { dispatch, creditTokenId, creditPositionSize, direction, placement } = params\n const low =\n params.tickLimitLow <= params.tickLimitHigh ? params.tickLimitLow : params.tickLimitHigh\n const high =\n params.tickLimitLow <= params.tickLimitHigh ? params.tickLimitHigh : params.tickLimitLow\n\n const swapping: TickAndSpreadLimits = [high, low, 0n]\n const notSwapping: TickAndSpreadLimits = [low, high, 0n]\n const mintLimits = direction === 'exact-out' ? swapping : notSwapping\n const burnLimits = direction === 'exact-out' ? notSwapping : swapping\n\n const positionIdList =\n placement === 'straddle'\n ? [creditTokenId, ...dispatch.positionIdList, creditTokenId]\n : placement === 'prepend'\n ? [creditTokenId, creditTokenId, ...dispatch.positionIdList]\n : [...dispatch.positionIdList, creditTokenId, creditTokenId]\n const positionSizes =\n placement === 'straddle'\n ? [creditPositionSize, ...dispatch.positionSizes, 0n]\n : placement === 'prepend'\n ? [creditPositionSize, 0n, ...dispatch.positionSizes]\n : [...dispatch.positionSizes, creditPositionSize, 0n]\n const tickAndSpreadLimits =\n placement === 'straddle'\n ? [mintLimits, ...dispatch.tickAndSpreadLimits, burnLimits]\n : placement === 'prepend'\n ? [mintLimits, burnLimits, ...dispatch.tickAndSpreadLimits]\n : [...dispatch.tickAndSpreadLimits, mintLimits, burnLimits]\n\n const wrapped: DispatchIntent = {\n positionIdList,\n finalPositionIdList: [...dispatch.finalPositionIdList],\n positionSizes,\n tickAndSpreadLimits,\n usePremiaAsCollateral: dispatch.usePremiaAsCollateral,\n builderCode: dispatch.builderCode,\n }\n return wrapped\n}\n","/**\n * Dispatch simulation for the Panoptic v2 SDK.\n * @module v2/simulations/simulateDispatch\n */\n\nimport type { Address, Hex, PublicClient } from 'viem'\nimport { decodeFunctionResult, encodeFunctionData } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { getBlockMeta } from '../clients'\nimport { PanopticError } from '../errors'\nimport type { DispatchSimulation, SimulationResult, TokenFlow } from '../types'\nimport type { TickAndSpreadLimits } from '../writes/position'\nimport { decodeLeftRightUnsigned } from '../writes/utils'\nimport { simulateWithTokenFlow } from './tokenFlow'\n\n/**\n * Parameters for simulating dispatch.\n */\nexport interface SimulateDispatchParams {\n /** Public client */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /**\n * Operation list passed to `dispatch()` — one tokenId per batch item, in\n * operation order. Mints reference NEW tokenIds the user doesn't yet own,\n * so this list is NOT safe to read against pre-dispatch storage.\n */\n positionIdList: bigint[]\n /** Final position ID list after operations */\n finalPositionIdList: bigint[]\n /**\n * The user's actual on-chain `positionIdList` BEFORE dispatch. Required to\n * populate `preMarginExcess0/1` (read via a pre-dispatch\n * `getFullPositionsData` chained in the same multicall). When omitted,\n * `preMarginExcess0/1` are returned as `null`.\n */\n existingPositionIdList?: bigint[]\n /** Position sizes for each operation */\n positionSizes: bigint[]\n /** Tick and spread limits for each operation */\n tickAndSpreadLimits: TickAndSpreadLimits[]\n /** Whether to use premia as collateral */\n usePremiaAsCollateral?: boolean\n /** Builder code */\n builderCode?: bigint\n /** Optional block number for simulation */\n blockNumber?: bigint\n}\n\n/**\n * Simulate a raw dispatch operation.\n *\n * Uses PanopticPool.multicall with getAssetsOf-dispatch-getAssetsOf pattern\n * to measure exact collateral asset movements.\n *\n * @param params - Simulation parameters\n * @returns Simulation result with dispatch data or error\n */\nexport async function simulateDispatch(\n params: SimulateDispatchParams,\n): Promise<SimulationResult<DispatchSimulation>> {\n const {\n client,\n poolAddress,\n account,\n positionIdList,\n finalPositionIdList,\n positionSizes,\n tickAndSpreadLimits,\n usePremiaAsCollateral = false,\n builderCode = 0n,\n blockNumber,\n existingPositionIdList,\n } = params\n\n const targetBlockNumber = blockNumber ?? (await client.getBlockNumber())\n const metaPromise = getBlockMeta({ client, blockNumber: targetBlockNumber })\n\n try {\n // Encode dispatch call data\n const callData = encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n positionIdList,\n finalPositionIdList,\n positionSizes,\n tickAndSpreadLimits.map(\n (t) => [Number(t[0]), Number(t[1]), Number(t[2])] as readonly [number, number, number],\n ),\n usePremiaAsCollateral,\n builderCode,\n ],\n })\n\n // Encode getFullPositionsData against the pre-dispatch (caller-supplied\n // existing list) and post-dispatch (finalPositionIdList) position lists.\n // Running both in the same multicall — pre-call before dispatch, post-call\n // after — lets the simulation report margin excess (= assets - required\n // collateral) on both sides atomically. Required collateral is summed\n // across the per-position LeftRightUnsigned entries.\n //\n // The pre-call uses `existingPositionIdList` (the user's actual storage\n // list), NOT `positionIdList` (the operation list, which contains\n // not-yet-minted tokenIds and would revert with PositionNotOwned).\n const preFullPositionsCallData =\n existingPositionIdList !== undefined\n ? encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [account, false, existingPositionIdList],\n })\n : undefined\n const postFullPositionsCallData = encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [account, false, finalPositionIdList],\n })\n\n // Simulate with token flow measurement using PanopticPool.multicall + getAssetsOf\n const flowResult = await simulateWithTokenFlow({\n client,\n poolAddress,\n user: account,\n callData,\n blockNumber: targetBlockNumber,\n preCallData: preFullPositionsCallData ? [preFullPositionsCallData] : undefined,\n postCallData: [postFullPositionsCallData],\n })\n\n if (!flowResult.success || !flowResult.tokenFlow) {\n throw (\n flowResult.rawError ?? new PanopticError(flowResult.error || 'Token flow simulation failed')\n )\n }\n\n const tokenFlow: TokenFlow = flowResult.tokenFlow\n\n // Determine which positions were created/closed by diffing the post-dispatch\n // list against the pre-dispatch on-chain snapshot. `positionIdList` is the\n // operation list (which contains not-yet-minted tokenIds and excludes\n // unaffected pre-existing ones), so it can't be used as the \"before\" set.\n const preSnapshot = existingPositionIdList ?? []\n const positionsCreated = finalPositionIdList.filter((id) => !preSnapshot.includes(id))\n const positionsClosed = preSnapshot.filter((id) => !finalPositionIdList.includes(id))\n\n // Sum collateralRequirements across all entries from one\n // getFullPositionsData multicall slot. Each entry is a LeftRightUnsigned\n // packed as right=token0, left=token1. Returns null on decode failure so\n // callers fall back gracefully (the type is bigint | null).\n const sumCollateralReq = (data: Hex | undefined): { token0: bigint; token1: bigint } | null => {\n if (!data) return null\n try {\n const decoded = decodeFunctionResult({\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n data,\n })\n const reqs = decoded[3] // collateralRequirements\n let token0 = 0n\n let token1 = 0n\n for (const packed of reqs) {\n const r = decodeLeftRightUnsigned(packed)\n token0 += r.right\n token1 += r.left\n }\n return { token0, token1 }\n } catch {\n return null\n }\n }\n\n const preReq = sumCollateralReq(flowResult.preCallResults?.[0])\n const postReq = sumCollateralReq(flowResult.postCallResults?.[0])\n\n const _meta = await metaPromise\n\n // Build simulation result with actual token flow data\n const data: DispatchSimulation = {\n netAmount0: tokenFlow.delta0,\n netAmount1: tokenFlow.delta1,\n positionsCreated,\n positionsClosed,\n postCollateral0: tokenFlow.balanceAfter0,\n postCollateral1: tokenFlow.balanceAfter1,\n preMarginExcess0: preReq ? tokenFlow.balanceBefore0 - preReq.token0 : null,\n preMarginExcess1: preReq ? tokenFlow.balanceBefore1 - preReq.token1 : null,\n postMarginExcess0: postReq ? tokenFlow.balanceAfter0 - postReq.token0 : null,\n postMarginExcess1: postReq ? tokenFlow.balanceAfter1 - postReq.token1 : null,\n }\n\n return {\n success: true,\n data,\n gasEstimate: flowResult.gasEstimate,\n tokenFlow,\n _meta,\n }\n } catch (error) {\n const _meta = await metaPromise\n return {\n success: false,\n error:\n error instanceof PanopticError\n ? error\n : new PanopticError(\n error instanceof Error ? error.message : 'Simulation failed',\n error instanceof Error ? error : undefined,\n ),\n _meta,\n }\n }\n}\n","import type { Address, PublicClient } from 'viem'\n\nimport { NotEnoughTokensError, PanopticError, parsePanopticError } from '../errors'\nimport { tickLimits } from '../formatters/tick'\nimport { getPool } from '../reads/pool'\nimport type { BlockMeta, DispatchSimulation, SimulationResult, TokenFlow } from '../types'\nimport { convertToTokenIndex } from '../utils/priceConvert'\nimport { buildUniqueCredit } from '../writes/loanUtils'\nimport {\n type CreditWrapDirection,\n type DispatchIntent,\n buildCreditWrappedDispatch,\n} from './creditWrap'\nimport { simulateDispatch } from './simulateDispatch'\n\nconst BPS_DENOMINATOR = 10_000n\nconst MAX_RECOVERY_QUOTE_ATTEMPTS = 8\n\nexport type { DispatchIntent }\n\nexport interface TokenShortfallRecoveryQuoteParams {\n client: PublicClient\n poolAddress: Address\n account: Address\n chainId: bigint\n existingPositionIds: bigint[]\n dispatch: DispatchIntent\n error: unknown\n /**\n * Slippage tolerance for the recovery swap, in **basis points** (1% = 100).\n * Applied to `estimatedAmountIn` to produce `maximumAmountIn`.\n * Values above `10_000` (100%) are rejected as `invalid-slippage`.\n */\n slippageBps: bigint\n /**\n * Price bound for the temporary credit legs. Defaults to a slippage-bounded\n * range around the pool's current tick.\n */\n tickLimitLow?: bigint\n /** See {@link TokenShortfallRecoveryQuoteParams.tickLimitLow}. */\n tickLimitHigh?: bigint\n blockNumber?: bigint\n}\n\nexport interface TokenShortfallRecoveryQuote {\n tokenIn: Address\n tokenOut: Address\n /** Swap construction used by the temporary credit wrapper. */\n direction: CreditWrapDirection\n /**\n * Exact amount of `tokenOut` the temporary credit sources. Covers the whole\n * dispatch, not just the first charge that reverted — a batch charges\n * commission/premia per operation, so the total needed is usually larger\n * than the `assetsRequested - assetBalance` of the first failure.\n */\n amountOut: bigint\n /** Output measured for the temporary swap alone. May exceed `amountOut` for exact-in. */\n estimatedAmountOut: bigint\n estimatedAmountIn: bigint\n maximumAmountIn: bigint\n slippageBps: bigint\n /**\n * Signed net change of `tokenIn` across the ENTIRE wrapped transaction —\n * the user's own operations plus the recovery swap. This is what a wallet\n * simulation shows, and it is not the same as `-estimatedAmountIn`, which\n * prices the swap leg alone.\n */\n netTokenInChange: bigint\n /** Signed net change of `tokenOut` across the entire wrapped transaction. */\n netTokenOutChange: bigint\n /** The temporary width=0 credit leg used to source the shortfall. */\n creditTokenId: bigint\n dispatch: DispatchIntent\n simulation: SimulationResult<DispatchSimulation> & { success: true }\n tokenFlow: TokenFlow\n _meta: BlockMeta\n}\n\nexport type TokenShortfallRecoveryUnavailableReason =\n | 'not-token-shortfall'\n | 'invalid-shortfall'\n | 'invalid-slippage'\n | 'unsupported-token'\n | 'invalid-tick-limits'\n | 'swap-unavailable'\n | 'recovery-unavailable'\n\nexport type TokenShortfallRecoveryResult =\n | { available: true; quote: TokenShortfallRecoveryQuote }\n | {\n available: false\n reason: TokenShortfallRecoveryUnavailableReason\n /** Human-readable description of the sub-step that failed, for diagnostics. */\n detail?: string\n error?: PanopticError\n }\n\nexport interface BuildTokenShortfallRecoveryDispatchParams {\n dispatch: DispatchIntent\n /** The temporary width=0 credit leg that sources the missing token. */\n creditTokenId: bigint\n creditPositionSize: bigint\n tickLimitLow: bigint\n tickLimitHigh: bigint\n}\n\n/**\n * Wrap a dispatch with a temporary credit leg that sources the shortfall.\n *\n * Exact-output construction: mint the credit with `swapAtMint=true` (paying a\n * swapped amount of the token the account has), run the user's operations, then\n * burn it with `swapAtMint=false` to receive exactly the missing token.\n *\n * A credit rather than a loan so the recovery is never capped by the shortfall\n * token's utilization — the case that fails today on a >94% utilized tracker.\n */\nexport function buildTokenShortfallRecoveryDispatch(\n params: BuildTokenShortfallRecoveryDispatchParams,\n): DispatchIntent {\n return buildCreditWrappedDispatch({ ...params, direction: 'exact-out', placement: 'straddle' })\n}\n\nfunction buildPrefixedExactInputRecoveryDispatch(\n params: BuildTokenShortfallRecoveryDispatchParams,\n): DispatchIntent {\n return buildCreditWrappedDispatch({ ...params, direction: 'exact-in', placement: 'prepend' })\n}\n\n/**\n * Extract a fully-decoded `NotEnoughTokens` revert from an arbitrary error.\n *\n * Returns `null` when the error is something else, or when only the 4-byte\n * selector could be matched (the parser's fallback path constructs the error\n * with undefined args, which is not actionable).\n */\nexport function getNotEnoughTokensError(error: unknown): NotEnoughTokensError | null {\n const visited = new Set<unknown>()\n let current: unknown = error\n\n while (current !== undefined && current !== null && !visited.has(current)) {\n visited.add(current)\n const parsed =\n current instanceof NotEnoughTokensError ? current : parsePanopticError(current)?.error\n const candidate = parsed instanceof NotEnoughTokensError ? parsed : null\n if (candidate !== null) {\n // Selector-only decodes yield undefined args at runtime despite the types.\n const args: Partial<\n Pick<NotEnoughTokensError, 'tokenAddress' | 'assetsRequested' | 'assetBalance'>\n > = candidate\n if (\n args.tokenAddress !== undefined &&\n args.assetsRequested !== undefined &&\n args.assetBalance !== undefined\n ) {\n return candidate\n }\n }\n\n current = current instanceof Error && 'cause' in current ? current.cause : undefined\n }\n return null\n}\n\nfunction maximumAmountIn(estimatedAmountIn: bigint, slippageBps: bigint): bigint {\n if (slippageBps < 0n) {\n throw new PanopticError('slippageBps must be non-negative')\n }\n return (\n (estimatedAmountIn * (BPS_DENOMINATOR + slippageBps) + BPS_DENOMINATOR - 1n) / BPS_DENOMINATOR\n )\n}\n\nfunction ceilDiv(numerator: bigint, denominator: bigint): bigint {\n return (numerator + denominator - 1n) / denominator\n}\n\nfunction getInputAmount(tokenFlow: TokenFlow, tokenInIndex: 0n | 1n): bigint {\n const delta = tokenInIndex === 0n ? tokenFlow.delta0 : tokenFlow.delta1\n return delta < 0n ? -delta : delta\n}\n\nfunction getBalanceBefore(tokenFlow: TokenFlow, tokenIndex: 0n | 1n): bigint {\n return tokenIndex === 0n ? tokenFlow.balanceBefore0 : tokenFlow.balanceBefore1\n}\n\nfunction getOutputAmount(tokenFlow: TokenFlow, tokenOutIndex: 0n | 1n): bigint {\n const delta = tokenOutIndex === 0n ? tokenFlow.delta0 : tokenFlow.delta1\n return delta > 0n ? delta : 0n\n}\n\nexport async function quoteTokenShortfallRecovery(\n params: TokenShortfallRecoveryQuoteParams,\n): Promise<TokenShortfallRecoveryResult> {\n const shortfallError = getNotEnoughTokensError(params.error)\n if (shortfallError === null) {\n return { available: false, reason: 'not-token-shortfall' }\n }\n\n let amountOut = shortfallError.assetsRequested - shortfallError.assetBalance\n if (amountOut <= 0n) {\n return {\n available: false,\n reason: 'invalid-shortfall',\n detail: `requested=${shortfallError.assetsRequested} <= balance=${shortfallError.assetBalance}`,\n }\n }\n if (params.slippageBps < 0n || params.slippageBps > BPS_DENOMINATOR) {\n return {\n available: false,\n reason: 'invalid-slippage',\n detail: `slippageBps=${params.slippageBps} is outside [0, ${BPS_DENOMINATOR}]`,\n }\n }\n const targetBlockNumber = params.blockNumber ?? (await params.client.getBlockNumber())\n const pool = await getPool({\n client: params.client,\n poolAddress: params.poolAddress,\n chainId: params.chainId,\n blockNumber: targetBlockNumber,\n })\n const defaultTickLimits = tickLimits(pool.currentTick, params.slippageBps)\n const tickLimitLow = params.tickLimitLow ?? defaultTickLimits.low\n const tickLimitHigh = params.tickLimitHigh ?? defaultTickLimits.high\n if (tickLimitLow >= tickLimitHigh) {\n return {\n available: false,\n reason: 'invalid-tick-limits',\n detail: `tickLimitLow=${tickLimitLow} >= tickLimitHigh=${tickLimitHigh}`,\n }\n }\n\n const token0 = pool.collateralTracker0.token\n const token1 = pool.collateralTracker1.token\n const shortfallTokenIndex = (error: NotEnoughTokensError): 0n | 1n | null => {\n const address = error.tokenAddress.toLowerCase()\n if (\n address === token0.toLowerCase() ||\n address === pool.collateralTracker0.address.toLowerCase()\n ) {\n return 0n\n }\n if (\n address === token1.toLowerCase() ||\n address === pool.collateralTracker1.address.toLowerCase()\n ) {\n return 1n\n }\n return null\n }\n const tokenOutIndex = shortfallTokenIndex(shortfallError)\n if (tokenOutIndex === null) {\n return {\n available: false,\n reason: 'unsupported-token',\n detail: `${shortfallError.tokenAddress} is neither collateral token of ${params.poolAddress}`,\n }\n }\n\n const tokenInIndex = tokenOutIndex === 0n ? 1n : 0n\n const tokenOut = tokenOutIndex === 0n ? token0 : token1\n const tokenIn = tokenInIndex === 0n ? token0 : token1\n const collisionIds = Array.from(\n new Set([\n ...params.existingPositionIds,\n ...params.dispatch.positionIdList,\n ...params.dispatch.finalPositionIdList,\n ]),\n )\n\n const quotePrefixedExactInput = async (\n initialRequiredOutput: bigint,\n ): Promise<TokenShortfallRecoveryResult> => {\n let requiredOutput = initialRequiredOutput\n const spotInput = convertToTokenIndex(\n requiredOutput,\n tokenOutIndex,\n tokenInIndex,\n pool.sqrtPriceX96,\n )\n let creditInput = maximumAmountIn(spotInput > 0n ? spotInput : 1n, params.slippageBps)\n\n for (let attempt = 0; attempt < MAX_RECOVERY_QUOTE_ATTEMPTS; attempt++) {\n const credit = buildUniqueCredit(\n pool.poolId,\n tokenInIndex,\n tokenInIndex,\n pool.currentTick,\n pool.tickSpacing,\n collisionIds,\n creditInput,\n )\n const wrapArgs = {\n creditTokenId: credit.tokenId,\n creditPositionSize: credit.adjustedSize,\n tickLimitLow,\n tickLimitHigh,\n }\n const swapDispatch = buildPrefixedExactInputRecoveryDispatch({\n ...wrapArgs,\n dispatch: {\n positionIdList: [],\n finalPositionIdList: [...params.existingPositionIds],\n positionSizes: [],\n tickAndSpreadLimits: [],\n usePremiaAsCollateral: false,\n builderCode: 0n,\n },\n })\n const swapSimulation = await simulateDispatch({\n client: params.client,\n poolAddress: params.poolAddress,\n account: params.account,\n existingPositionIdList: params.existingPositionIds,\n ...swapDispatch,\n blockNumber: targetBlockNumber,\n })\n if (!swapSimulation.success || swapSimulation.tokenFlow === undefined) {\n return {\n available: false,\n reason: 'swap-unavailable',\n detail: swapSimulation.success\n ? 'prefixed swap simulation returned no token flow'\n : `prefixed swap simulation reverted: ${swapSimulation.error.message}`,\n error: swapSimulation.success ? undefined : swapSimulation.error,\n }\n }\n\n const estimatedAmountIn = getInputAmount(swapSimulation.tokenFlow, tokenInIndex)\n const estimatedAmountOut = getOutputAmount(swapSimulation.tokenFlow, tokenOutIndex)\n const sourceBalance = getBalanceBefore(swapSimulation.tokenFlow, tokenInIndex)\n if (sourceBalance < estimatedAmountIn) {\n return {\n available: false,\n reason: 'swap-unavailable',\n detail: `source balance ${sourceBalance} < exact input cost ${estimatedAmountIn}`,\n error: new PanopticError('Insufficient source collateral for the recovery swap'),\n }\n }\n if (estimatedAmountOut < requiredOutput) {\n creditInput =\n estimatedAmountOut > 0n\n ? ceilDiv(creditInput * requiredOutput, estimatedAmountOut) + 1n\n : creditInput * 2n\n continue\n }\n\n const recoveredDispatch = buildPrefixedExactInputRecoveryDispatch({\n ...wrapArgs,\n dispatch: params.dispatch,\n })\n const recoverySimulation = await simulateDispatch({\n client: params.client,\n poolAddress: params.poolAddress,\n account: params.account,\n existingPositionIdList: params.existingPositionIds,\n ...recoveredDispatch,\n blockNumber: targetBlockNumber,\n })\n if (recoverySimulation.success && recoverySimulation.tokenFlow !== undefined) {\n return {\n available: true,\n quote: {\n tokenIn,\n tokenOut,\n direction: 'exact-in',\n amountOut: requiredOutput,\n estimatedAmountOut,\n estimatedAmountIn,\n // The input credit has a fixed size. Its tick limit protects output;\n // unlike exact-out, execution cannot consume an unbounded input.\n maximumAmountIn: estimatedAmountIn,\n slippageBps: params.slippageBps,\n netTokenInChange:\n tokenInIndex === 0n\n ? recoverySimulation.tokenFlow.delta0\n : recoverySimulation.tokenFlow.delta1,\n netTokenOutChange:\n tokenOutIndex === 0n\n ? recoverySimulation.tokenFlow.delta0\n : recoverySimulation.tokenFlow.delta1,\n creditTokenId: credit.tokenId,\n dispatch: recoveredDispatch,\n simulation: {\n ...recoverySimulation,\n tokenFlow: recoverySimulation.tokenFlow,\n },\n tokenFlow: recoverySimulation.tokenFlow,\n _meta: recoverySimulation._meta,\n },\n }\n }\n if (recoverySimulation.success) {\n return {\n available: false,\n reason: 'recovery-unavailable',\n detail: 'prefixed recovery simulation returned no token flow',\n error: new PanopticError('Recovery simulation did not return token flow'),\n }\n }\n\n const remainingShortfall = getNotEnoughTokensError(recoverySimulation.error)\n if (\n remainingShortfall === null ||\n shortfallTokenIndex(remainingShortfall) !== tokenOutIndex\n ) {\n return {\n available: false,\n reason: 'recovery-unavailable',\n detail: `prefixed recovery reverted with a non-output shortfall: ${recoverySimulation.error.message}`,\n error: recoverySimulation.error,\n }\n }\n const residual = remainingShortfall.assetsRequested - remainingShortfall.assetBalance\n requiredOutput += residual > 0n ? residual : requiredOutput\n creditInput = ceilDiv(creditInput * requiredOutput, estimatedAmountOut) + 1n\n }\n\n return {\n available: false,\n reason: 'recovery-unavailable',\n detail: `prefixed recovery remained short after ${MAX_RECOVERY_QUOTE_ATTEMPTS} attempts`,\n error: new PanopticError('Could not size the prefixed recovery swap'),\n }\n }\n\n for (let attempt = 0; attempt < MAX_RECOVERY_QUOTE_ATTEMPTS; attempt++) {\n // asset === tokenType === tokenOutIndex: the credit is denominated in the\n // token being sourced. Passing tokenInIndex as tokenType is the loan\n // convention and reverses the flow (pays the shortfall token instead of\n // receiving it).\n const credit = buildUniqueCredit(\n pool.poolId,\n tokenOutIndex,\n tokenOutIndex,\n pool.currentTick,\n pool.tickSpacing,\n collisionIds,\n amountOut,\n )\n const recoveredDispatch = buildTokenShortfallRecoveryDispatch({\n dispatch: params.dispatch,\n creditTokenId: credit.tokenId,\n creditPositionSize: credit.adjustedSize,\n tickLimitLow,\n tickLimitHigh,\n })\n const swapDispatch = buildTokenShortfallRecoveryDispatch({\n dispatch: {\n positionIdList: [],\n finalPositionIdList: [...params.existingPositionIds],\n positionSizes: [],\n tickAndSpreadLimits: [],\n usePremiaAsCollateral: false,\n builderCode: 0n,\n },\n creditTokenId: credit.tokenId,\n creditPositionSize: credit.adjustedSize,\n tickLimitLow,\n tickLimitHigh,\n })\n\n const swapSimulation = await simulateDispatch({\n client: params.client,\n poolAddress: params.poolAddress,\n account: params.account,\n existingPositionIdList: params.existingPositionIds,\n ...swapDispatch,\n blockNumber: targetBlockNumber,\n })\n if (!swapSimulation.success || swapSimulation.tokenFlow === undefined) {\n const bootstrapShortfall = swapSimulation.success\n ? null\n : getNotEnoughTokensError(swapSimulation.error)\n if (\n bootstrapShortfall !== null &&\n shortfallTokenIndex(bootstrapShortfall) === tokenOutIndex\n ) {\n return quotePrefixedExactInput(amountOut)\n }\n return {\n available: false,\n reason: 'swap-unavailable',\n detail: swapSimulation.success\n ? 'swap-only simulation returned no token flow'\n : `swap-only simulation reverted: ${swapSimulation.error.message}`,\n error: swapSimulation.success ? undefined : swapSimulation.error,\n }\n }\n const estimatedAmountIn = getInputAmount(swapSimulation.tokenFlow, tokenInIndex)\n const maxAmountIn = maximumAmountIn(estimatedAmountIn, params.slippageBps)\n const swapOutput = getOutputAmount(swapSimulation.tokenFlow, tokenOutIndex)\n const sourceBalance = getBalanceBefore(swapSimulation.tokenFlow, tokenInIndex)\n if (swapOutput < amountOut || sourceBalance < maxAmountIn) {\n return {\n available: false,\n reason: 'swap-unavailable',\n detail:\n swapOutput < amountOut\n ? `swap output ${swapOutput} < required ${amountOut}`\n : `source balance ${sourceBalance} < maximumAmountIn ${maxAmountIn} (estimated ${estimatedAmountIn}, slippageBps ${params.slippageBps})`,\n error: new PanopticError('Insufficient source collateral for the recovery swap'),\n }\n }\n\n const recoverySimulation = await simulateDispatch({\n client: params.client,\n poolAddress: params.poolAddress,\n account: params.account,\n existingPositionIdList: params.existingPositionIds,\n ...recoveredDispatch,\n blockNumber: targetBlockNumber,\n })\n if (recoverySimulation.success) {\n if (recoverySimulation.tokenFlow !== undefined) {\n return {\n available: true,\n quote: {\n tokenIn,\n tokenOut,\n direction: 'exact-out',\n amountOut,\n estimatedAmountOut: swapOutput,\n estimatedAmountIn,\n maximumAmountIn: maxAmountIn,\n slippageBps: params.slippageBps,\n netTokenInChange:\n tokenInIndex === 0n\n ? recoverySimulation.tokenFlow.delta0\n : recoverySimulation.tokenFlow.delta1,\n netTokenOutChange:\n tokenOutIndex === 0n\n ? recoverySimulation.tokenFlow.delta0\n : recoverySimulation.tokenFlow.delta1,\n creditTokenId: credit.tokenId,\n dispatch: recoveredDispatch,\n simulation: {\n ...recoverySimulation,\n tokenFlow: recoverySimulation.tokenFlow,\n },\n tokenFlow: recoverySimulation.tokenFlow,\n _meta: recoverySimulation._meta,\n },\n }\n }\n return {\n available: false,\n reason: 'recovery-unavailable',\n detail: 'wrapped dispatch simulation returned no token flow',\n error: new PanopticError('Recovery simulation did not return token flow'),\n }\n }\n\n const remainingShortfall = getNotEnoughTokensError(recoverySimulation.error)\n if (remainingShortfall === null || shortfallTokenIndex(remainingShortfall) !== tokenOutIndex) {\n return {\n available: false,\n reason: 'recovery-unavailable',\n detail: `wrapped dispatch reverted with a non-shortfall error: ${recoverySimulation.error.message}`,\n error: recoverySimulation.error,\n }\n }\n // Grow by the residual the contract just reported. If that residual is\n // non-positive (assetsRequested <= assetBalance, e.g. the shortfall moved to\n // a rounding/fee boundary the revert no longer quantifies), fall back to\n // reusing amountOut — i.e. DOUBLE the target each retry. Bounded by\n // MAX_RECOVERY_QUOTE_ATTEMPTS and by the source-balance check above, so a\n // runaway size fails as swap-unavailable rather than looping.\n const decodedShortfall = remainingShortfall.assetsRequested - remainingShortfall.assetBalance\n const additionalAmountOut = decodedShortfall > 0n ? decodedShortfall : amountOut\n amountOut += additionalAmountOut\n }\n\n return {\n available: false,\n reason: 'recovery-unavailable',\n detail: `still short after ${MAX_RECOVERY_QUOTE_ATTEMPTS} sizing attempts (last target ${amountOut})`,\n error: new PanopticError('Could not cover recovery swap costs within the quote attempt limit'),\n }\n}\n","/**\n * Collateral estimation functions for the Panoptic v2 SDK.\n *\n * These functions require the PanopticQuery contract which provides\n * on-chain calculation capabilities for collateral requirements.\n *\n * @module v2/reads/collateralEstimate\n */\n\nimport type { Address, PublicClient } from 'viem'\nimport { encodeFunctionData } from 'viem'\n\nimport { collateralTrackerV2Abi, panopticPoolV2Abi } from '../../../generated'\nimport { panopticQueryAbi } from '../abis/panopticQuery'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport { PanopticError } from '../errors'\nimport { sqrtPriceX96ToTick, tickToSqrtPriceX96 } from '../formatters/tick'\nimport {\n type TokenFlow,\n getPoolTokensForSimulation,\n simulateWithTokenFlow,\n} from '../simulations/tokenFlow'\nimport { getNotEnoughTokensError } from '../simulations/tokenShortfallRecovery'\nimport type { StorageAdapter } from '../storage'\nimport { getTrackedPositionIds } from '../sync/getTrackedPositionIds'\nimport { addLegToTokenId, countLegs, decodeAllLegs } from '../tokenId/encoding'\nimport type { BlockMeta } from '../types'\nimport { MAX_TICK, MIN_TICK } from '../utils/constants'\n\n/**\n * Max int24 (2^23 - 1), used as the per-position `effectiveLiquidityLimit` (the\n * 3rd element of the dispatch tickAndSpreadLimits triplet). Passing this lets the\n * contract clamp to its real on-chain `maxSpread()` ceiling, matching the live\n * trade. Passing 0 instead forces the limit to 0, so any long-leg removal reverts\n * with EffectiveLiquidityAboveThreshold and ITM/size measurements silently\n * collapse (see PanopticPool._mintInSFPMAndUpdateCollateral / _checkLiquiditySpread).\n */\nconst MAX_EFFECTIVE_LIQUIDITY_LIMIT = 8388607\n\n/**\n * Collateral estimate result.\n */\nexport interface CollateralEstimate {\n /** Required collateral for token 0 */\n required0: bigint\n /** Required collateral for token 1 */\n required1: bigint\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Parameters for estimateCollateralRequired.\n */\nexport interface EstimateCollateralRequiredParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** TokenId to estimate collateral for */\n tokenId: bigint\n /** Position size (number of contracts) */\n positionSize: bigint\n /** Optional: Tick to calculate collateral at (defaults to current tick) */\n atTick?: bigint\n /** PanopticQuery address */\n queryAddress: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Maximum value of a Solidity `uint64`. `PanopticQuery.getRequiredBase` computes\n * the requirement for a synthetic position sized at `type(uint64).max`, so the\n * returned value must be scaled down to the caller's actual `positionSize`.\n */\nconst MAX_UINT64 = 2n ** 64n - 1n\n\n/**\n * `getRequiredBase` returns `type(uint128).max` as an error sentinel (invalid\n * tokenId or reverting `getMargin`). Detect it so we don't scale a garbage value.\n */\nexport const REQUIRED_BASE_ERROR_SENTINEL = 2n ** 128n - 1n\n\n/**\n * Estimate the collateral required to open a position.\n *\n * Note: This function uses PanopticQuery.getRequiredBase for estimation, which\n * computes the requirement at `type(uint64).max` size and 0% utilization. Since\n * the requirement is linear in size, the raw result is scaled by\n * `positionSize / type(uint64).max` to yield the requirement for the requested\n * size. Returns collateral requirement in terms of token0.\n *\n * @param params - The parameters\n * @returns Estimated collateral requirements with block metadata\n */\nexport async function estimateCollateralRequired(\n params: EstimateCollateralRequiredParams,\n): Promise<CollateralEstimate> {\n const { client, poolAddress, tokenId, positionSize, atTick, queryAddress, blockNumber } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Get current tick if not provided\n let effectiveTick: bigint\n if (atTick !== undefined) {\n effectiveTick = atTick\n } else {\n const currentTickResult = await client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n blockNumber: targetBlockNumber,\n })\n // Bridge type from panopticPoolV2Abi (number | bigint) to bigint\n effectiveTick = BigInt(currentTickResult)\n }\n\n const [required0, _meta] = await Promise.all([\n client.readContract({\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'getRequiredBase',\n args: [poolAddress, tokenId, Number(effectiveTick)],\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n // getRequiredBase computes the requirement at type(uint64).max size. The\n // requirement is linear in size, so scale down to the requested positionSize.\n // Guard against the error sentinel (type(uint128).max) so we don't scale it.\n const scaled0 =\n required0 >= REQUIRED_BASE_ERROR_SENTINEL ? required0 : (required0 * positionSize) / MAX_UINT64\n\n // PanopticQuery.getRequiredBase returns collateral requirement in terms of token0\n // For token1 requirement, would need additional conversion or separate call\n return {\n required0: scaled0,\n required1: 0n, // Not available from getRequiredBase (token0-denominated only)\n _meta,\n }\n}\n\n/**\n * Max position size result.\n */\nexport interface MaxPositionSize {\n /** Refined maximum position size at current market conditions */\n maxSize: bigint\n /** Maximum position size at 0% utilization (best case / upper bound) */\n maxSizeAtMinUtil: bigint\n /** Maximum position size at 100% utilization (worst case / lower bound) */\n maxSizeAtMaxUtil: bigint\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Parameters for getMaxPositionSize.\n */\nexport interface GetMaxPositionSizeParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** TokenId to check max size for */\n tokenId: bigint\n /** PanopticQuery address (required for this function) */\n queryAddress: Address\n /**\n * Existing position IDs held by the account.\n * - If provided, uses these directly\n * - If not provided but storage + chainId given, fetches from getTrackedPositionIds()\n * - If neither provided, assumes empty array (new account with no positions)\n */\n existingPositionIds?: bigint[]\n /** Storage adapter for auto-fetching positions (requires chainId) */\n storage?: StorageAdapter\n /** Chain ID (required if using storage) */\n chainId?: bigint\n /** Whether to refine with dispatch simulation (default: true) */\n refine?: boolean\n /** Precision for binary search as percentage (default: 1 = 1%) */\n precisionPct?: number\n /** Whether to swap tokens at mint (affects collateral requirements, default: false) */\n swapAtMint?: boolean\n /**\n * Whether the solvency simulation may count accrued premia as collateral. MUST match the\n * mint (which uses `false`) — passing `true` credits premia the mint won't, so the search\n * returns a size larger than the account can actually mint. Defaults to `false`.\n */\n usePremiaAsCollateral?: boolean\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get the maximum position size an account can open given their current collateral.\n *\n * Uses PanopticQuery.getMaxPositionSizeBounds to get bounds at 0% and 100% utilization,\n * then refines with dispatch simulations to find the exact max at current conditions.\n *\n * @param params - The parameters\n * @returns Maximum position size with bounds and block metadata\n */\nexport async function getMaxPositionSize(\n params: GetMaxPositionSizeParams,\n): Promise<MaxPositionSize> {\n const {\n client,\n poolAddress,\n account,\n tokenId,\n queryAddress,\n existingPositionIds,\n storage,\n chainId,\n refine = true,\n precisionPct = 1,\n swapAtMint = false,\n usePremiaAsCollateral = false,\n blockNumber,\n } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Get existing position IDs\n let positionIds: bigint[]\n if (existingPositionIds !== undefined) {\n // Use explicitly provided position IDs\n positionIds = existingPositionIds\n } else if (storage && chainId !== undefined) {\n // Fetch from local cache via getTrackedPositionIds\n positionIds = await getTrackedPositionIds({\n chainId,\n poolAddress,\n account,\n storage,\n })\n } else {\n // Assume new account with no existing positions\n positionIds = []\n }\n // Get bounds and block meta in parallel\n const [boundsResult, _meta] = await Promise.all([\n client.readContract({\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'getMaxPositionSizeBounds',\n args: [poolAddress, positionIds, account, tokenId],\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [maxSizeAtMinUtil, maxSizeAtMaxUtil] = boundsResult\n\n // If bounds are equal or very close, or refinement disabled, return conservative estimate\n const precisionDivisor = BigInt(Math.floor(100 / precisionPct))\n if (\n !refine ||\n maxSizeAtMinUtil === maxSizeAtMaxUtil ||\n maxSizeAtMinUtil - maxSizeAtMaxUtil <= maxSizeAtMaxUtil / precisionDivisor\n ) {\n return {\n maxSize: maxSizeAtMaxUtil,\n maxSizeAtMinUtil,\n maxSizeAtMaxUtil,\n _meta,\n }\n }\n\n // Binary search between widened bounds using dispatch simulation\n // Widen by 2x in each direction to account for swapAtMint price impact\n const maxSize = await binarySearchMaxSize({\n client,\n poolAddress,\n account,\n tokenId,\n existingPositionIds: positionIds,\n low: maxSizeAtMaxUtil / 2n,\n high: maxSizeAtMinUtil * 2n,\n precisionDivisor,\n swapAtMint,\n usePremiaAsCollateral,\n })\n\n return {\n maxSize,\n maxSizeAtMinUtil,\n maxSizeAtMaxUtil,\n _meta,\n }\n}\n\n/**\n * Parallel search to find max position size using dispatch simulation.\n * Tests 5 points per round (sextiles), narrowing the range by 6x each iteration.\n */\nasync function binarySearchMaxSize(params: {\n client: PublicClient\n poolAddress: Address\n account: Address\n tokenId: bigint\n existingPositionIds: bigint[]\n low: bigint\n high: bigint\n precisionDivisor: bigint\n swapAtMint: boolean\n usePremiaAsCollateral: boolean\n}): Promise<bigint> {\n const {\n client,\n poolAddress,\n account,\n tokenId,\n existingPositionIds,\n precisionDivisor,\n swapAtMint,\n usePremiaAsCollateral,\n } = params\n let { low, high } = params\n\n const trySize = (positionSize: bigint) =>\n tryDispatchSimulation({\n client,\n poolAddress,\n account,\n tokenId,\n existingPositionIds,\n positionSize,\n swapAtMint,\n usePremiaAsCollateral,\n })\n\n while (high - low > 1n && high - low > low / precisionDivisor) {\n const range = high - low\n const p1 = low + range / 6n\n const p2 = low + (range * 2n) / 6n\n const p3 = low + (range * 3n) / 6n\n const p4 = low + (range * 4n) / 6n\n const p5 = low + (range * 5n) / 6n\n\n const [s1, s2, s3, s4, s5] = await Promise.all([\n trySize(p1),\n trySize(p2),\n trySize(p3),\n trySize(p4),\n trySize(p5),\n ])\n\n if (s5) {\n low = p5\n } else if (s4) {\n low = p4\n high = p5\n } else if (s3) {\n low = p3\n high = p4\n } else if (s2) {\n low = p2\n high = p3\n } else if (s1) {\n low = p1\n high = p2\n } else {\n high = p1\n }\n }\n\n return low\n}\n\n/**\n * Try to simulate opening a position with the given size.\n */\nasync function tryDispatchSimulation(params: {\n client: PublicClient\n poolAddress: Address\n account: Address\n tokenId: bigint\n existingPositionIds: bigint[]\n positionSize: bigint\n swapAtMint: boolean\n usePremiaAsCollateral: boolean\n}): Promise<boolean> {\n const {\n client,\n poolAddress,\n account,\n tokenId,\n existingPositionIds,\n positionSize,\n swapAtMint,\n usePremiaAsCollateral,\n } = params\n\n try {\n // Build final position list (existing + new position)\n const finalPositionIdList = [...existingPositionIds, tokenId]\n\n // Build tick limits based on swapAtMint flag:\n // - swapAtMint=true: descending order (high, low) triggers SFPM swap\n // - swapAtMint=false: ascending order (low, high) no swap\n //\n // The third element is the per-position `effectiveLiquidityLimit`; see the\n // MAX_EFFECTIVE_LIQUIDITY_LIMIT definition for why 0 must not be used here.\n const tickLimits: readonly [number, number, number] = swapAtMint\n ? [887272, -887272, MAX_EFFECTIVE_LIQUIDITY_LIMIT]\n : [-887272, 887272, MAX_EFFECTIVE_LIQUIDITY_LIMIT]\n\n // Encode dispatch call\n const callData = encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n [tokenId],\n finalPositionIdList,\n [positionSize],\n [tickLimits],\n usePremiaAsCollateral, // must match the mint (default false) so the max is mintable\n 0n, // builderCode\n ],\n })\n\n // Use PanopticPool.multicall to simulate\n await client.simulateContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'multicall',\n args: [[callData]],\n account,\n })\n\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Parameters for getRequiredCreditForITM.\n */\nexport interface GetRequiredCreditForITMParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** TokenId to check */\n tokenId: bigint\n /** Position size (number of contracts) */\n positionSize: bigint\n /** Existing position IDs held by the account (defaults to empty) */\n existingPositionIds?: bigint[]\n /**\n * Whether the position will be minted with a token swap (Zap). Controls the\n * dispatch tickLimit direction and therefore what the measured flow looks like:\n * - `true` (default): descending tickLimits → SFPM swap → flow consolidated to\n * the single token the mint would swap into.\n * - `false`: ascending tickLimits → no swap → the true two-sided flow (both\n * tokens), matching a cover-at-mint open.\n * Must match the swapAtMint used at mint for the measurement to be meaningful.\n */\n swapAtMint?: boolean\n /** Optional block number for simulation */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Result for getRequiredCreditForITM.\n */\nexport interface RequiredCreditForITM {\n /**\n * Required credit in token0 to neutralize ITM exposure.\n * Positive = credit needed (deposit), negative = loan proceeds (receive).\n */\n creditAmount0: bigint\n /**\n * Required credit in token1 to neutralize ITM exposure.\n * Positive = credit needed (deposit), negative = loan proceeds (receive).\n */\n creditAmount1: bigint\n /** The raw token flow from simulation */\n tokenFlow: TokenFlow\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Get the required credit (or loan) amount for an ITM position.\n *\n * Simulates opening the position with swapAtMint=true (descending tickLimits)\n * to get single-sided token flow. The token flow represents the ITM amount\n * that would need to be neutralized with a credit (or loan if negative).\n *\n * @param params - The parameters\n * @returns Required credit amounts with token flow and block metadata\n * @throws PanopticError - If simulation fails\n *\n * @example\n * ```typescript\n * const result = await getRequiredCreditForITM({\n * client,\n * poolAddress,\n * account,\n * tokenId,\n * positionSize: 1n,\n * })\n *\n * if (result.creditAmount0 > 0n) {\n * console.log('Need credit of', result.creditAmount0, 'token0')\n * } else if (result.creditAmount0 < 0n) {\n * console.log('Position yields loan of', -result.creditAmount0, 'token0')\n * }\n * ```\n */\nexport async function getRequiredCreditForITM(\n params: GetRequiredCreditForITMParams,\n): Promise<RequiredCreditForITM> {\n const {\n client,\n poolAddress,\n account,\n tokenId,\n positionSize,\n existingPositionIds = [],\n swapAtMint = true,\n blockNumber,\n } = params\n\n // Same-block guarantee: if the caller pins both a blockNumber and a pre-fetched\n // _meta, they must agree — otherwise the simulation (targetBlockNumber) and the\n // returned metadata would describe different blocks.\n if (\n blockNumber !== undefined &&\n params._meta !== undefined &&\n params._meta.blockNumber !== blockNumber\n ) {\n throw new PanopticError(\n 'getRequiredCreditForITM: blockNumber and _meta.blockNumber disagree; cannot guarantee same-block consistency',\n )\n }\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Build final position list (existing + new position)\n const finalPositionIdList = [...existingPositionIds, tokenId]\n\n // Encode dispatch call. The tickLimit direction encodes swapAtMint:\n // - swapAtMint=true (Zap): descending (MAX_TICK > MIN_TICK) triggers the SFPM swap,\n // consolidating the flow into the single token the mint swaps into.\n // - swapAtMint=false (Cover): ascending (MIN_TICK < MAX_TICK) does no swap, giving the\n // true two-sided flow. This must match the mint's swapAtMint for the measured flow to\n // reflect what actually happens at open.\n // The 3rd element is the per-position effectiveLiquidityLimit: use the max so the contract\n // clamps to its real maxSpread() ceiling (matching the live trade). Passing 0 here collapses\n // ITM measurement for positions with a long-leg removal (see MAX_EFFECTIVE_LIQUIDITY_LIMIT).\n const tickTriplet: readonly [number, number, number] = swapAtMint\n ? [Number(MAX_TICK), Number(MIN_TICK), MAX_EFFECTIVE_LIQUIDITY_LIMIT]\n : [Number(MIN_TICK), Number(MAX_TICK), MAX_EFFECTIVE_LIQUIDITY_LIMIT]\n const callData = encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n [tokenId], // positionIdList: positions being minted\n finalPositionIdList,\n [positionSize],\n [tickTriplet],\n false, // usePremiaAsCollateral\n 0n, // builderCode\n ],\n })\n\n // Simulate with token flow measurement and get block meta in parallel\n const [result, _meta] = await Promise.all([\n simulateWithTokenFlow({\n client,\n poolAddress,\n user: account,\n callData,\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n if (!result.success || !result.tokenFlow) {\n throw new PanopticError(result.error ?? 'Token flow simulation failed', result.rawError)\n }\n\n // The token flow deltas represent the ITM amount:\n // - Negative delta = user deposits (credit needed)\n // - Positive delta = user receives (loan proceeds)\n // We invert the sign so positive = credit needed, negative = loan\n return {\n creditAmount0: -result.tokenFlow.delta0,\n creditAmount1: -result.tokenFlow.delta1,\n tokenFlow: result.tokenFlow,\n _meta,\n }\n}\n\n/**\n * Parameters for getItmAmounts.\n */\nexport interface GetItmAmountsParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticQuery address (holds the getItmAmounts view) */\n queryAddress: Address\n /** PanopticPool address the position would be minted on */\n poolAddress: Address\n /** The option position (may already include width=0 neutralizing legs) */\n tokenId: bigint\n /** Position size (number of contracts) */\n positionSize: bigint\n /** Optional block number */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata */\n _meta?: BlockMeta\n}\n\n/**\n * Result of getItmAmounts: the net in-the-money amounts a mint of `tokenId` would\n * accumulate in the SFPM before the mint-time netting swap.\n */\nexport interface ItmAmounts {\n /** Net ITM amount of token0 (SFPM sign convention). */\n itm0: bigint\n /** Net ITM amount of token1. */\n itm1: bigint\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Read the net `itmAmounts` a mint of `tokenId` would produce, via\n * `PanopticQuery.getItmAmounts`. This is the swap-independent, per-leg-linear\n * projection that drives the SFPM's mint-time netting swap: the swap only fires\n * when `itmAmounts != 0`. Sizing width=0 legs so the combined tokenId returns\n * (~0, ~0) here makes the mint swap dust — regardless of Zap vs cover.\n *\n * @param params - The parameters\n * @returns The net itm0/itm1 with block metadata\n */\nexport async function getItmAmounts(params: GetItmAmountsParams): Promise<ItmAmounts> {\n const { client, queryAddress, poolAddress, tokenId, positionSize, blockNumber } = params\n\n // Same-block guarantee (see getRequiredCreditForITM): a pinned blockNumber and a\n // pre-fetched _meta must describe the same block.\n if (\n blockNumber !== undefined &&\n params._meta !== undefined &&\n params._meta.blockNumber !== blockNumber\n ) {\n throw new PanopticError(\n 'getItmAmounts: blockNumber and _meta.blockNumber disagree; cannot guarantee same-block consistency',\n )\n }\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n const [result, _meta] = await Promise.all([\n client.readContract({\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'getItmAmounts',\n args: [poolAddress, tokenId, positionSize],\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [itm0, itm1] = result as readonly [bigint, bigint]\n return { itm0, itm1, _meta }\n}\n\n/**\n * Dust threshold (token1 value units) below which an itm amount is treated as\n * zero — negligible token flow not worth a neutralizing leg. token0 amounts are\n * converted to token1 value at the current tick before comparison so a tiny\n * high-decimal amount can't masquerade as real flow.\n */\nconst FLOW_NEUTRAL_DUST_THRESHOLD = 1000n\n\nconst Q192 = 1n << 192n\nconst POOL_ID_MASK = (1n << 64n) - 1n\n\n/**\n * Floor integer square root for bigints (Newton's method). Exact for all\n * non-negative inputs — no float precision loss for values above 2^53.\n */\nfunction isqrt(value: bigint): bigint {\n if (value < 0n) throw new PanopticError('isqrt of negative number')\n if (value < 2n) return value\n let x = value\n let y = (x + 1n) >> 1n\n while (y < x) {\n x = y\n y = (x + value / x) >> 1n\n }\n return x\n}\n\n/**\n * Solve a single width=0 neutralizing leg sized to offset a token's signed itm.\n *\n * The leg moves `tokenIndex`'s token (`tokenType = tokenIndex`) and is denominated\n * in the opposite asset (`asset = 1 - tokenIndex`) so `asset ≠ tokenType` and the\n * notional scales continuously by strike: `notional ≈ positionSize · 1.0001^signed`.\n * `signedAmount` is the itm to cancel (the leg's itm contribution is `-signedAmount`):\n * positive itm ⇒ a short LOAN leg (isLong=0), negative itm ⇒ a long CREDIT leg (isLong=1).\n *\n * Width=0 legs never mint Uniswap liquidity (see SFPM `_createPositionInAMM`), so their\n * strike is NOT grid-constrained — we use full 1-tick granularity for the tightest sizing.\n * The closed form `positionSize·1.0001^strike` matches the contract's width-2-chunk\n * `getAmountsMoved` to within ~dust, so no correction loop is needed.\n * Throws `PanopticError` if the required strike leaves the valid (exclusive) tick range.\n */\nfunction buildNeutralLeg(\n tokenIndex: 0n | 1n,\n signedAmount: bigint,\n positionSize: bigint,\n): NeutralLeg {\n const absAmount = signedAmount < 0n ? -signedAmount : signedAmount\n const legAsset = tokenIndex === 0n ? 1n : 0n\n const legIsLong = signedAmount < 0n\n\n // 1.0001^signedStrike = absAmount / positionSize\n // sqrtKrawX96 = sqrt(absAmount / positionSize) · 2^96 = isqrt(absAmount · 2^192 / positionSize)\n const sqrtKrawX96 = isqrt((absAmount * Q192) / positionSize)\n\n let signedTick: bigint\n try {\n signedTick = sqrtPriceX96ToTick(sqrtKrawX96)\n } catch {\n throw new PanopticError(\n 'Cannot create flow-neutral position: neutralizing strike out of bounds',\n )\n }\n\n // TokenId.validate() rejects strike == MIN_TICK/MAX_TICK, so keep strictly inside.\n if (signedTick <= MIN_TICK || signedTick >= MAX_TICK) {\n throw new PanopticError(\n 'Cannot create flow-neutral position: neutralizing strike out of bounds',\n )\n }\n\n // signedStrike = (asset === 0 ? strike : -strike) — invert to recover the encoded\n // strike (mirrors getLegValueWidth0's convention).\n const strike = legAsset === 0n ? signedTick : -signedTick\n\n return {\n strike,\n asset: legAsset,\n tokenType: tokenIndex,\n isCredit: legIsLong,\n }\n}\n\n/**\n * Assemble a tokenId with the neutralizing legs (self-partnered, width=0) placed either\n * BEFORE or AFTER the base legs.\n *\n * The leg at index 0 sets the position's swap frame (the token the Zap sources) and the\n * canonical `positionSize` denomination, so placement is asset-directed:\n * - `prepend=false` (default, e.g. PUTs): base legs keep their indices (option leg stays\n * at index 0); neutral legs are appended at `baseLegCount..`.\n * - `prepend=true` (e.g. CALLs): neutral legs occupy indices `0..k-1` and the base legs\n * shift by `k` (riskPartner remapped: self-partners follow their new index, cross\n * partners +k). This puts the credit leg first so the mint swap is asset-token\n * friendly for a call.\n */\nfunction assembleNeutralTokenId(\n poolId: bigint,\n baseTokenId: bigint,\n neutralLegs: NeutralLeg[],\n prepend: boolean,\n): bigint {\n let out = poolId\n const baseLegs = decodeAllLegs(baseTokenId)\n const k = BigInt(neutralLegs.length)\n const shift = prepend ? k : 0n\n\n if (prepend) {\n neutralLegs.forEach((leg, i) => {\n const index = BigInt(i)\n out = addLegToTokenId(out, {\n index,\n asset: leg.asset,\n tokenType: leg.tokenType,\n optionRatio: 1n,\n isLong: leg.isCredit ? 1n : 0n,\n riskPartner: index,\n strike: leg.strike,\n width: 0n,\n })\n })\n }\n\n for (const leg of baseLegs) {\n const newIndex = leg.index + shift\n const newRiskPartner = leg.riskPartner === leg.index ? newIndex : leg.riskPartner + shift\n out = addLegToTokenId(out, {\n index: newIndex,\n asset: leg.asset,\n tokenType: leg.tokenType,\n optionRatio: leg.optionRatio,\n isLong: leg.isLong ? 1n : 0n,\n riskPartner: newRiskPartner,\n strike: leg.strike,\n width: leg.width,\n })\n }\n\n if (!prepend) {\n const base = BigInt(baseLegs.length)\n neutralLegs.forEach((leg, i) => {\n const index = base + BigInt(i)\n out = addLegToTokenId(out, {\n index,\n asset: leg.asset,\n tokenType: leg.tokenType,\n optionRatio: 1n,\n isLong: leg.isCredit ? 1n : 0n,\n riskPartner: index,\n strike: leg.strike,\n width: 0n,\n })\n })\n }\n\n return out\n}\n\n/**\n * Parameters for createFlowNeutralTokenId.\n */\nexport interface CreateFlowNeutralTokenIdParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address the position would be minted on */\n poolAddress: Address\n /** Account address (whose collateral flow the neutralization targets) */\n account: Address\n /** The base tokenId (without neutralizing legs) */\n tokenId: bigint\n /** Position size (number of contracts) — unchanged by this function */\n positionSize: bigint\n /**\n * PanopticQuery address. When provided, the position's true intrinsic (`getItmAmounts`)\n * gates neutralization: an OTM position (no ITM) gets NO leg, even though its realized\n * flow is non-zero from the open commission. Without it, OTM detection falls back to the\n * commission-inclusive realized flow, which spuriously neutralizes the fee.\n */\n queryAddress?: Address\n /** Existing position IDs held by the account (defaults to empty) */\n existingPositionIds?: bigint[]\n /**\n * Whether the position will be minted with a token swap (Zap). Must match the\n * mint: the neutralization targets the NET token flow under this swap mode, so a\n * mismatch would neutralize the wrong quantity. Defaults to `true`.\n */\n swapAtMint?: boolean\n /**\n * Size at which to MEASURE the base flow that sizes the neutralizing leg(s). The leg\n * strikes are position-size-independent (the flow is linear in size), so measuring at a\n * small affordable reference and reusing the result for `positionSize` yields the same\n * legs. Set this below `positionSize` to avoid the un-neutralized base dispatch reverting\n * with NotEnoughTokens at large sizes under Cover (the gross ITM would exceed the\n * account's balance even though the neutralized mint nets ~0). Defaults to `positionSize`;\n * clamped to `positionSize` if larger.\n */\n referenceSize?: bigint\n /** Optional block number (pins base + verify measurements to one block) */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata */\n _meta?: BlockMeta\n}\n\n/**\n * A single width=0 neutralizing leg emitted by {@link createFlowNeutralTokenId}.\n */\nexport interface NeutralLeg {\n /** The encoded strike of the leg (sign follows the `asset === 0 ? +t : -t` convention). */\n strike: bigint\n /** Asset (0n or 1n) of the leg. Always `1n - tokenType` (asset ≠ tokenType, so it is strike-tunable). */\n asset: bigint\n /** Token type (0n or 1n) — the token this leg neutralizes (its itm slot). */\n tokenType: bigint\n /** true = credit leg (isLong, offsets negative itm), false = loan leg (short, offsets positive itm). */\n isCredit: boolean\n}\n\n/**\n * Result of createFlowNeutralTokenId.\n */\nexport interface FlowNeutralTokenId {\n /**\n * New tokenId with the neutralizing legs appended after the base legs (base legs keep\n * their original indices, so the option leg stays at index 0). Equals the original\n * tokenId when OTM (`neutralLegs` empty).\n */\n tokenId: bigint\n /**\n * Position size to use when opening this tokenId. Always equal to the input\n * `positionSize` — neutralizing legs are sized via their strike, not by\n * rescaling the position.\n */\n positionSize: bigint\n /**\n * The neutralizing legs added, appended after the base legs. 0 entries = OTM/no leg;\n * 1 = the single dominant-token neutralizing leg (single-leg neutralization).\n */\n neutralLegs: NeutralLeg[]\n /** The BASE position's net-flow measurement (what the legs offset). */\n originalCredit?: RequiredCreditForITM\n /**\n * The COMBINED (neutralized) position's actual token flow under the mint's swap,\n * from a verify re-measurement. Use this for the Account-Balances display and to\n * gate the mint — its `delta0/delta1` are the residual net transfer (≈ dust).\n */\n neutralizedTokenFlow?: TokenFlow\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Create a flow-neutral tokenId by adding width=0 credit/loan leg(s) that zero the\n * position's NET token transfer at mint — the amount the user would otherwise send/receive\n * (and be surprised by at burn).\n *\n * Each leg is sized against the **realized net flow**, measured by\n * {@link getRequiredCreditForITM} under the mint's own `swapAtMint`. Verified on-chain: a\n * width=0 leg's marginal effect on its token's flow is LINEAR and 1:1 with its notional\n * (`positionSize · 1.0001^strike`, matching the contract's `getAmountsMoved`). So sizing the\n * notional to `|net flow|` and solving the strike directly drives the residual to ~dust in\n * ONE shot — no fixed-point loop. (Example: flow 122.08 USDC → strike −228275 → residual\n * −0.032 USDC.)\n *\n * How many legs, keyed on swap mode:\n * - **Zap** (`swapAtMint=true`): the mint swap consolidates the flow into ONE token and a\n * width=0 leg can only move the asset axis afterwards, so we add a single leg on the\n * dominant token; the smaller side is a swap artifact left as dust.\n * - **Cover** (`swapAtMint=false`): no swap, so the flow is genuinely two-sided and each\n * token's flow is independent — we add one leg PER token above dust (up to 2), each\n * sized 1:1 to its own side. This neutralizes both sides of e.g. a two-leg straddle.\n * Each width=0 leg has `asset ≠ tokenType` (strike-tunable):\n * - token0 flow ← width=0 call leg (tokenType0, asset1)\n * - token1 flow ← width=0 put leg (tokenType1, asset0)\n * `creditAmount = −delta`: a positive amount (user would deposit) → a short LOAN leg;\n * negative (user would receive) → a long CREDIT leg. `neutralizedTokenFlow` is a single\n * verify measurement of the combined position under the ACTUAL mint swap mode.\n *\n * Neutral legs (self-partnered, width=0) are placed so index 0 carries the correct swap\n * frame: for a single-leg CALL (option `tokenType === asset`) they are PREPENDED so the\n * credit leg leads and the mint swap is asset-token friendly; for a PUT (and any multi-leg\n * base) they are APPENDED so the option leg stays at index 0. `positionSize` is never\n * modified.\n *\n * @param params - The parameters\n * @returns The flow-neutral tokenId, the neutralizing legs, the base net-flow\n * measurement, and the combined position's residual flow. `neutralLegs` is empty\n * when the position is OTM (input tokenId returned unchanged).\n * @throws PanopticError if positionSize <= 0, base legs + 1 > 4, the current tick\n * is unavailable, or a neutralizing strike falls outside the valid tick range.\n */\nexport async function createFlowNeutralTokenId(\n params: CreateFlowNeutralTokenIdParams,\n): Promise<FlowNeutralTokenId> {\n const {\n client,\n poolAddress,\n account,\n tokenId,\n positionSize,\n existingPositionIds,\n swapAtMint = true,\n referenceSize,\n queryAddress,\n blockNumber,\n } = params\n\n if (positionSize <= 0n) {\n throw new PanopticError('positionSize must be positive to create flow-neutral position')\n }\n\n // Measure the base flow at a (possibly smaller) reference size to keep the un-neutralized\n // dispatch affordable; strikes are size-independent so the legs are identical. Verify runs\n // on the neutralized position at the full positionSize (which nets ~0, so it's affordable).\n const measureSize =\n referenceSize !== undefined && referenceSize > 0n && referenceSize < positionSize\n ? referenceSize\n : positionSize\n\n const legCount = countLegs(tokenId)\n if (legCount >= 4n) {\n throw new PanopticError('Cannot append neutralizing leg: tokenId already has 4 legs')\n }\n\n const poolId = tokenId & POOL_ID_MASK\n\n // Leg-0 placement of the neutral leg is asset-directed (it sets the mint's swap frame /\n // positionSize denomination). For a single-leg CALL (option leg's tokenType === asset)\n // the credit leg must lead so the swap sources the asset token; for a PUT the option leg\n // stays at index 0 and the neutral leg is appended. Multi-leg bases always append (their\n // neutralization is handled in a separate commit).\n const baseLegs = decodeAllLegs(tokenId)\n const prependNeutral = baseLegs.length === 1 && baseLegs[0].tokenType === baseLegs[0].asset\n\n // Size the neutral leg against the REALIZED (post-swap) net flow, measured by dispatch\n // under the mint's own `swapAtMint`. Empirically (verified on-chain against a live pool)\n // the leg's marginal effect on this flow is LINEAR and 1:1 with its notional: a width=0\n // leg of notional N (positionSize·1.0001^strike) shifts the measured net flow by exactly\n // N in that token. So sizing notional = |base net flow| and computing the strike directly\n // drives the residual to ~dust in ONE shot — no fixed-point loop.\n // creditAmount = −delta: positive = user deposits, negative = user receives.\n let credit: RequiredCreditForITM\n try {\n credit = await getRequiredCreditForITM({\n client,\n poolAddress,\n account,\n tokenId,\n positionSize: measureSize,\n existingPositionIds,\n swapAtMint,\n blockNumber,\n _meta: params._meta,\n })\n } catch (error) {\n const firstShortfall = getNotEnoughTokensError(error)\n if (firstShortfall === null || queryAddress === undefined) throw error\n\n const intrinsic = await getItmAmounts({\n client,\n queryAddress,\n poolAddress,\n tokenId,\n positionSize: measureSize,\n blockNumber,\n _meta: params._meta,\n })\n // OTM positions need no neutral leg. Their commission-only shortfall is\n // handled by the normal collateral-swap recovery around the final dispatch.\n if (intrinsic.itm0 === 0n && intrinsic.itm1 === 0n) {\n return {\n tokenId,\n positionSize,\n neutralLegs: [],\n _meta: intrinsic._meta,\n }\n }\n\n const pinnedBlock = blockNumber ?? intrinsic._meta.blockNumber\n const poolTokens = await getPoolTokensForSimulation({\n client,\n poolAddress,\n blockNumber: pinnedBlock,\n })\n const indexForShortfall = (shortfall: ReturnType<typeof getNotEnoughTokensError>) => {\n if (shortfall === null) return null\n const address = shortfall.tokenAddress.toLowerCase()\n if (\n address === poolTokens.token0.toLowerCase() ||\n address === poolTokens.collateralTracker0.toLowerCase()\n ) {\n return 0n as const\n }\n if (\n address === poolTokens.token1.toLowerCase() ||\n address === poolTokens.collateralTracker1.toLowerCase()\n ) {\n return 1n as const\n }\n return null\n }\n const firstIndex = indexForShortfall(firstShortfall)\n if (firstIndex === null) throw error\n\n // A failed dispatch still reveals the complete charge attempted for its\n // blocking collateral. Seed a neutralizing leg from that amount, then let\n // subsequent simulations refine commissions, rounding and Cover's second side.\n const targets: [bigint, bigint] = [0n, 0n]\n targets[Number(firstIndex)] = firstShortfall.assetsRequested\n let best:\n | {\n tokenId: bigint\n neutralLegs: NeutralLeg[]\n residual: RequiredCreditForITM\n residualScore: bigint\n }\n | undefined\n let previousTokenId: bigint | undefined\n\n for (let attempt = 0; attempt < 8; attempt++) {\n const indices = ([0n, 1n] as const).filter((index) => targets[Number(index)] !== 0n)\n if (swapAtMint && indices.length > 1) {\n const keep = indices.reduce((dominant, index) =>\n (targets[Number(index)] < 0n ? -targets[Number(index)] : targets[Number(index)]) >\n (targets[Number(dominant)] < 0n ? -targets[Number(dominant)] : targets[Number(dominant)])\n ? index\n : dominant,\n )\n targets[Number(keep === 0n ? 1n : 0n)] = 0n\n }\n const activeIndices = ([0n, 1n] as const).filter((index) => targets[Number(index)] !== 0n)\n if (legCount + BigInt(activeIndices.length) > 4n) {\n throw new PanopticError(\n `Cannot add ${activeIndices.length} neutralizing leg(s): tokenId would exceed 4 legs`,\n )\n }\n const neutralLegs = activeIndices.map((index) =>\n buildNeutralLeg(index, targets[Number(index)], measureSize),\n )\n const combined = assembleNeutralTokenId(poolId, tokenId, neutralLegs, prependNeutral)\n if (combined === previousTokenId) break\n previousTokenId = combined\n\n let residual: RequiredCreditForITM\n try {\n residual = await getRequiredCreditForITM({\n client,\n poolAddress,\n account,\n tokenId: combined,\n positionSize: measureSize,\n existingPositionIds,\n swapAtMint,\n blockNumber: pinnedBlock,\n _meta: intrinsic._meta,\n })\n } catch (retryError) {\n const retryShortfall = getNotEnoughTokensError(retryError)\n const retryIndex = indexForShortfall(retryShortfall)\n if (retryShortfall === null || retryIndex === null) throw retryError\n const deficit = retryShortfall.assetsRequested - retryShortfall.assetBalance\n targets[Number(retryIndex)] += deficit > 0n ? deficit : retryShortfall.assetsRequested\n continue\n }\n\n const residualScore =\n (residual.creditAmount0 < 0n ? -residual.creditAmount0 : residual.creditAmount0) +\n (residual.creditAmount1 < 0n ? -residual.creditAmount1 : residual.creditAmount1)\n if (best === undefined || residualScore < best.residualScore) {\n best = { tokenId: combined, neutralLegs, residual, residualScore }\n }\n const residualCredits = [residual.creditAmount0, residual.creditAmount1] as const\n let adjusted = false\n for (const index of [0n, 1n] as const) {\n if (swapAtMint && targets[Number(index)] === 0n) continue\n const amount = residualCredits[Number(index)]\n if (amount === 0n) continue\n targets[Number(index)] += amount\n adjusted = true\n }\n if (!adjusted) break\n }\n\n if (best === undefined) {\n throw new PanopticError('Could not create an affordable ITM-neutralizing position')\n }\n\n let verifiedFlow = best.residual.tokenFlow\n if (positionSize !== measureSize) {\n try {\n const verified = await getRequiredCreditForITM({\n client,\n poolAddress,\n account,\n tokenId: best.tokenId,\n positionSize,\n existingPositionIds,\n swapAtMint,\n blockNumber: pinnedBlock,\n _meta: intrinsic._meta,\n })\n verifiedFlow = verified.tokenFlow\n } catch {\n // The final mint hook can wrap any full-size rounding/commission shortfall\n // in the collateral recovery swap; the neutral tokenId itself is valid.\n }\n }\n\n return {\n tokenId: best.tokenId,\n positionSize,\n neutralLegs: best.neutralLegs,\n neutralizedTokenFlow: verifiedFlow,\n _meta: intrinsic._meta,\n }\n }\n\n const tickBefore = credit.tokenFlow.tickBefore\n if (tickBefore === null) {\n throw new PanopticError('Cannot create flow-neutral position: current tick unavailable')\n }\n // Value-aware compare: convert a token0 amount into token1 at the current price\n // (P = 1.0001^tick = sqrtP^2 / 2^192) so token0/token1 flows compare in one unit.\n const sqrtPX96 = tickToSqrtPriceX96(tickBefore)\n const valueAbs = (index: 0n | 1n, amount: bigint): bigint => {\n const abs = amount < 0n ? -amount : amount\n return index === 0n ? (abs * sqrtPX96 * sqrtPX96) / Q192 : abs\n }\n const flowFor = (index: 0n | 1n): bigint =>\n index === 0n ? credit.creditAmount0 : credit.creditAmount1\n\n // OTM gate on true INTRINSIC (getItmAmounts), not the realized flow. The realized\n // getAssetsOf flow includes the open commission, so an OTM position shows non-zero flow\n // (a fee, not ITM) — neutralizing it builds a spurious leg and moves tokens the mint\n // wouldn't. `getItmAmounts` is 0 for an OTM position, so this correctly skips it. Falls\n // back to the realized-flow dust check when no queryAddress is supplied.\n if (queryAddress !== undefined) {\n const itm = await getItmAmounts({\n client,\n queryAddress,\n poolAddress,\n tokenId,\n positionSize: measureSize,\n blockNumber: blockNumber ?? credit._meta.blockNumber,\n _meta: credit._meta,\n })\n if (\n valueAbs(0n, itm.itm0) <= FLOW_NEUTRAL_DUST_THRESHOLD &&\n valueAbs(1n, itm.itm1) <= FLOW_NEUTRAL_DUST_THRESHOLD\n ) {\n return {\n tokenId,\n positionSize,\n neutralLegs: [],\n originalCredit: credit,\n neutralizedTokenFlow: credit.tokenFlow,\n _meta: credit._meta,\n }\n }\n }\n\n // OTM — no net flow to neutralize (both sides negligible). This guard only avoids\n // building a leg with an out-of-bounds (log of ~0) strike; it is NOT a convergence\n // threshold.\n if (\n valueAbs(0n, credit.creditAmount0) <= FLOW_NEUTRAL_DUST_THRESHOLD &&\n valueAbs(1n, credit.creditAmount1) <= FLOW_NEUTRAL_DUST_THRESHOLD\n ) {\n return {\n tokenId,\n positionSize,\n neutralLegs: [],\n originalCredit: credit,\n neutralizedTokenFlow: credit.tokenFlow,\n _meta: credit._meta,\n }\n }\n\n // Which token(s) get a neutralizing leg:\n // - Zap (swapAtMint=true): the mint swap consolidates the flow to ONE token, and a\n // width=0 leg can only move the asset axis afterwards, so we neutralize just the\n // SINGLE dominant token; the smaller side is a swap artifact left as dust.\n // - Cover (swapAtMint=false): there is NO swap, so the flow is genuinely two-sided and\n // each token's flow is independent — neutralize EACH side above dust (up to 2 legs),\n // every leg sized 1:1 to its own token's net flow.\n const indices: (0n | 1n)[] = swapAtMint\n ? [valueAbs(0n, credit.creditAmount0) >= valueAbs(1n, credit.creditAmount1) ? 0n : 1n]\n : ([0n, 1n] as const).filter((i) => valueAbs(i, flowFor(i)) > FLOW_NEUTRAL_DUST_THRESHOLD)\n\n if (legCount + BigInt(indices.length) > 4n) {\n throw new PanopticError(\n `Cannot add ${indices.length} neutralizing leg(s): tokenId would exceed 4 legs`,\n )\n }\n\n // Legs sized from the flow measured at `measureSize`; strikes are size-independent so\n // they hold at the full positionSize.\n const neutralLegs = indices.map((i) => buildNeutralLeg(i, flowFor(i), measureSize))\n const combined = assembleNeutralTokenId(poolId, tokenId, neutralLegs, prependNeutral)\n\n // Verify/display: measure the COMBINED (neutralized) position's residual flow under the\n // ACTUAL mint swap mode at the FULL positionSize so the Account-Balances display and mint\n // gating reflect what the user will experience. The neutralized position nets ~0, so this\n // is affordable even when the un-neutralized base at full size would not be. If it still\n // reverts (edge: sits exactly at the solvency limit), fall back to the reference-size\n // measurement so we return a valid tokenId rather than throwing.\n const pinnedBlock = blockNumber ?? credit._meta.blockNumber\n let residual: RequiredCreditForITM\n try {\n residual = await getRequiredCreditForITM({\n client,\n poolAddress,\n account,\n tokenId: combined,\n positionSize,\n existingPositionIds,\n swapAtMint,\n blockNumber: pinnedBlock,\n _meta: credit._meta,\n })\n } catch {\n residual = await getRequiredCreditForITM({\n client,\n poolAddress,\n account,\n tokenId: combined,\n positionSize: measureSize,\n existingPositionIds,\n swapAtMint,\n blockNumber: pinnedBlock,\n _meta: credit._meta,\n })\n }\n\n return {\n tokenId: combined,\n positionSize,\n neutralLegs,\n originalCredit: credit,\n neutralizedTokenFlow: residual.tokenFlow,\n _meta: credit._meta,\n }\n}\n\n/**\n * Parameters for getMaxWithdrawable.\n */\nexport interface GetMaxWithdrawableParams {\n /** viem PublicClient */\n client: PublicClient\n /** CollateralTracker address */\n collateralTrackerAddress: Address\n /** Account address */\n account: Address\n /** Position IDs held by the account (required for solvency-checked withdraw) */\n positionIdList: bigint[]\n /** Upper bound for the binary search (e.g. user's total assets in this tracker) */\n totalAssets: bigint\n /** Whether to use premia as collateral (default: false) */\n usePremiaAsCollateral?: boolean\n /** Precision for binary search as percentage (default: 1 = 1%) */\n precisionPct?: number\n}\n\n/**\n * Find the maximum withdrawable amount from a CollateralTracker using binary search.\n *\n * When a user has open positions, the standard `maxWithdraw()` returns 0 because\n * the basic ERC4626 withdraw doesn't check solvency. The overloaded\n * `withdraw(assets, receiver, owner, positionIdList, usePremiaAsCollateral)` does\n * check solvency, so we binary search for the largest amount that doesn't revert.\n *\n * @param params - The parameters\n * @returns Maximum withdrawable amount in underlying asset units\n */\nexport async function getMaxWithdrawable(\n params: GetMaxWithdrawableParams,\n): Promise<{ maxWithdrawable: bigint; _meta: BlockMeta }> {\n const {\n client,\n collateralTrackerAddress,\n account,\n positionIdList,\n totalAssets,\n usePremiaAsCollateral = false,\n precisionPct = 1,\n } = params\n\n const _meta = await getBlockMeta({ client })\n\n if (totalAssets <= 0n || positionIdList.length === 0) {\n // No positions: use the standard maxWithdraw\n const maxWithdraw = await client.readContract({\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'maxWithdraw',\n args: [account],\n })\n return { maxWithdrawable: maxWithdraw, _meta }\n }\n\n const precisionDivisor = BigInt(Math.floor(100 / precisionPct))\n let low = 0n\n let high = totalAssets\n\n while (high - low > 1n && high - low > low / precisionDivisor) {\n const mid = low + (high - low) / 2n\n\n const success = await tryWithdrawSimulation({\n client,\n collateralTrackerAddress,\n account,\n assets: mid,\n positionIdList,\n usePremiaAsCollateral,\n })\n\n if (success) {\n low = mid\n } else {\n high = mid\n }\n }\n\n return { maxWithdrawable: low, _meta }\n}\n\n/**\n * Parameters for getMaxRedeem.\n */\nexport interface GetMaxRedeemParams {\n /** viem PublicClient */\n client: PublicClient\n /** CollateralTracker address */\n collateralTrackerAddress: Address\n /** Account address */\n account: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n}\n\n/**\n * Read the maximum number of shares an account can redeem from a CollateralTracker.\n *\n * This is the ERC4626 `maxRedeem(owner)`, i.e. `min(availableShares, balanceOf(owner))`,\n * and returns 0 when the account has open positions (legs). Redeeming exactly this many\n * shares burns the account's full (available) share balance, so a MAX withdraw leaves no\n * rounding dust — unlike an assets-based `withdraw`, which round-trips shares↔assets.\n *\n * @param params - The parameters\n * @returns Maximum redeemable shares with block metadata\n */\nexport async function getMaxRedeem(\n params: GetMaxRedeemParams,\n): Promise<{ maxRedeem: bigint; _meta: BlockMeta }> {\n const { client, collateralTrackerAddress, account, blockNumber } = params\n\n const targetBlockNumber = blockNumber ?? (await client.getBlockNumber())\n\n const [maxRedeem, _meta] = await Promise.all([\n client.readContract({\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'maxRedeem',\n args: [account],\n blockNumber: targetBlockNumber,\n }),\n getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n return { maxRedeem, _meta }\n}\n\n/**\n * Try to simulate a solvency-checked withdraw with the given amount.\n */\nasync function tryWithdrawSimulation(params: {\n client: PublicClient\n collateralTrackerAddress: Address\n account: Address\n assets: bigint\n positionIdList: bigint[]\n usePremiaAsCollateral: boolean\n}): Promise<boolean> {\n const {\n client,\n collateralTrackerAddress,\n account,\n assets,\n positionIdList,\n usePremiaAsCollateral,\n } = params\n\n try {\n await client.estimateContractGas({\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'withdraw',\n args: [assets, account, account, positionIdList, usePremiaAsCollateral],\n account,\n })\n return true\n } catch {\n return false\n }\n}\n","/**\n * Collateral strategy classification and per-strategy requirement attribution.\n *\n * `RiskEngine` does not charge collateral leg by leg. It walks the legs, and for\n * each one asks whether that leg's `riskPartner` forms one of a fixed list of\n * recognized strategies; if so, the pair is charged once, under that strategy's\n * own rule. This module reproduces that walk in TypeScript so the UI can name\n * what the contract is doing, and estimates how the authoritative total splits\n * across the recognized groups.\n *\n * **The classification is exact; the numbers are estimates.** Classification is a\n * pure re-implementation of the contract's branch conditions\n * (`RiskEngine._getRequiredCollateralSingleLegPartner`), so it either matches the\n * contract or it is a bug. The per-group amounts are NOT exact: they come from\n * pricing each group in isolation, which loses whatever the combined position\n * gets from cross-collateralization. They are used strictly as attribution\n * weights against the authoritative total — never as the total itself.\n *\n * @module v2/reads/collateralBreakdown\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { panopticQueryAbi } from '../abis/panopticQuery'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport { PanopticError } from '../errors'\nimport { type DecodedLeg, addLegToTokenId, decodeAllLegs } from '../tokenId/encoding'\nimport type { BlockMeta } from '../types'\nimport { REQUIRED_BASE_ERROR_SENTINEL } from './collateralEstimate'\n\n/** Mask selecting the poolId (low 64 bits) of a tokenId. */\nconst POOL_ID_MASK = (1n << 64n) - 1n\n\n/** `getRequiredBase` prices at `type(uint64).max`; results scale linearly in size. */\nconst MAX_UINT64 = 2n ** 64n - 1n\n\n/**\n * How the RiskEngine treats a group of one or two legs for collateral purposes.\n *\n * Every value maps to a real branch of the contract. Two caveats, both\n * deliberate:\n *\n * - `straddle` and `strangle` are ONE branch on-chain (`_computeStrangle`). They\n * are split here only because traders name them differently; they must share a\n * collateral-rule explanation, because they share a formula.\n * - `shortCall`/`shortPut` and `longCall`/`longPut` are presentation splits of\n * the single `_getRequiredCollateralSingleLegNoPartner` path.\n */\nexport type CollateralStrategyKind =\n /** Unpartnered short call — sold, collateralized at the seller ratio. */\n | 'shortCall'\n /** Unpartnered short put. */\n | 'shortPut'\n /** Unpartnered long call — bought, collateralized at the buyer ratio. */\n | 'longCall'\n /** Unpartnered long put. */\n | 'longPut'\n /** width=0 short leg: borrows the notional. Requires 100% + maintenance margin. */\n | 'loan'\n /** width=0 long leg: lends the notional. Requires 0 on its own. */\n | 'credit'\n /** Two short options, different tokenTypes, different strikes. */\n | 'strangle'\n /** Two short options, different tokenTypes, the same strike. */\n | 'straddle'\n /** Long + short, different tokenTypes, the SAME strike — the short leg only. */\n | 'synthetic'\n /** Long + short, same tokenType — defined risk, charged at max loss. */\n | 'spread'\n /** Long option funded by a credit — `max(long - credit, 1)`. */\n | 'prepaidLongOption'\n /** Short option funded by a credit — `max(short - credit, 1)`. */\n | 'cashSecuredOption'\n /** Long option paired with a loan — `max(loan, option)`. */\n | 'optionProtectedLoan'\n /** Short option paired with a loan — `max(loan, option)`. */\n | 'upfrontShortOption'\n /**\n * A leg naming a partner the contract does not recognize as a strategy —\n * mismatched asset or optionRatio, or a pairing outside the allowed list.\n * The contract silently falls back to charging each leg standalone, so this is\n * the one kind a trader most needs told: the intended netting did NOT apply.\n */\n | 'unrecognizedPair'\n\n/** Kinds whose collateral rule is identical on-chain and must share one explanation. */\nconst SHARED_RULE: Partial<Record<CollateralStrategyKind, CollateralStrategyKind>> = {\n straddle: 'strangle',\n}\n\n/**\n * Collapse presentation-only distinctions to the kind that owns the collateral\n * rule. Use this to look up a formula/explanation; use the raw kind to label.\n *\n * @param kind - The classified kind\n * @returns The kind whose rule governs it (itself, unless it is an alias)\n */\nexport function collateralRuleKindFor(kind: CollateralStrategyKind): CollateralStrategyKind {\n return SHARED_RULE[kind] ?? kind\n}\n\n/** One classified group of legs: either a recognized pair, or a single leg. */\nexport interface StrategyGroup {\n /** How the RiskEngine treats this group. */\n kind: CollateralStrategyKind\n /** Leg indices in the group, ascending. One entry, or two for a paired kind. */\n legIndices: bigint[]\n /**\n * The leg the contract actually charges, when only one of a pair carries the\n * requirement (spread charges the long leg, synthetic the short leg, the\n * composites the option leg). `null` when every leg in the group is charged —\n * standalone legs, and strangles/straddles, where each leg pays a reduced half.\n */\n chargedLegIndex: bigint | null\n}\n\n/** True when the two legs may be partnered at all (contract's gating condition). */\nconst partnersEligible = (a: DecodedLeg, b: DecodedLeg): boolean =>\n a.asset === b.asset && a.optionRatio === b.optionRatio\n\n/**\n * Classify a tokenId's legs into the groups the RiskEngine charges.\n *\n * Mirrors `RiskEngine._getRequiredCollateralSingleLegPartner`: a leg is paired\n * only if its partner is a different leg, the partnership is mutual, the two\n * share an `asset` and `optionRatio`, AND the (width, isLong, tokenType, strike)\n * combination is one the contract recognizes. Anything else degrades to\n * standalone treatment — reported as `unrecognizedPair` so it is visible rather\n * than silent.\n *\n * @param tokenId - The position to classify\n * @returns One group per charged unit, in ascending leg order\n */\nexport function classifyStrategyGroups(tokenId: bigint): StrategyGroup[] {\n const legs = decodeAllLegs(tokenId)\n const byIndex = new Map(legs.map((leg) => [leg.index, leg]))\n const groups: StrategyGroup[] = []\n const consumed = new Set<bigint>()\n\n for (const leg of legs) {\n if (consumed.has(leg.index)) continue\n\n const partner = leg.riskPartner === leg.index ? undefined : byIndex.get(leg.riskPartner)\n // A partner that doesn't exist, or doesn't point back, is not a partnership.\n // TokenId.validate() rejects non-mutual pairings on-chain, so this is a\n // defensive path for tokenIds assembled off-chain.\n const mutual = partner !== undefined && partner.riskPartner === leg.index\n\n if (!mutual) {\n groups.push({ kind: standaloneKind(leg), legIndices: [leg.index], chargedLegIndex: null })\n continue\n }\n\n consumed.add(leg.index)\n consumed.add(partner.index)\n groups.push(classifyPair(leg, partner))\n }\n\n return groups\n}\n\n/** The kind of a leg the contract charges on its own. */\nfunction standaloneKind(leg: DecodedLeg): CollateralStrategyKind {\n if (leg.width === 0n) return leg.isLong ? 'credit' : 'loan'\n if (leg.isLong) return leg.tokenType === 0n ? 'longCall' : 'longPut'\n return leg.tokenType === 0n ? 'shortCall' : 'shortPut'\n}\n\n/**\n * Classify a mutually-partnered pair. `a` and `b` are given in leg order; the\n * result is order-independent, which matters because the contract evaluates the\n * same pair from both indices and only charges one of them.\n */\nfunction classifyPair(a: DecodedLeg, b: DecodedLeg): StrategyGroup {\n const legIndices = [a.index, b.index].sort((x, y) => (x < y ? -1 : x > y ? 1 : 0))\n const unrecognized: StrategyGroup = {\n kind: 'unrecognizedPair',\n legIndices,\n chargedLegIndex: null,\n }\n\n if (!partnersEligible(a, b)) return unrecognized\n\n const aIsOption = a.width > 0n\n const bIsOption = b.width > 0n\n\n // Both legs are options.\n if (aIsOption && bIsOption) {\n if (a.tokenType !== b.tokenType) {\n if (!a.isLong && !b.isLong) {\n // STRANGLE / STRADDLE — both legs charged, each at half its base rate.\n // One branch on-chain; split here for naming only.\n return {\n kind: a.strike === b.strike ? 'straddle' : 'strangle',\n legIndices,\n chargedLegIndex: null,\n }\n }\n if (a.isLong !== b.isLong && a.strike === b.strike) {\n // SYNTHETIC STOCK — the same strike is mandatory; the short leg pays.\n return {\n kind: 'synthetic',\n legIndices,\n chargedLegIndex: a.isLong ? b.index : a.index,\n }\n }\n // Different tokenTypes, but neither a short/short pair nor a same-strike\n // long/short: e.g. a long/short pair at DIFFERENT strikes. Not recognized.\n return unrecognized\n }\n\n // Same tokenType.\n if (a.isLong !== b.isLong) {\n // SPREAD — defined risk, charged once, on the long leg.\n return {\n kind: 'spread',\n legIndices,\n chargedLegIndex: a.isLong ? a.index : b.index,\n }\n }\n // Same tokenType and same direction (both long or both short) — no netting.\n return unrecognized\n }\n\n // Exactly one leg is an option and the other is width=0 funding.\n if (aIsOption !== bIsOption) {\n const option = aIsOption ? a : b\n const funding = aIsOption ? b : a\n\n // The contract additionally requires matching tokenTypes for the composites.\n if (option.tokenType !== funding.tokenType) return unrecognized\n\n // A long funding leg is a CREDIT; a short one is a LOAN. Which composite it\n // forms then depends on the OPTION's direction. Note the contract reads this\n // off `isLongP` relative to whichever index it is evaluating — it returns 0\n // for the funding leg either way, so classifying from the option's\n // perspective is equivalent and order-independent.\n const kind: CollateralStrategyKind = funding.isLong\n ? option.isLong\n ? 'prepaidLongOption'\n : 'cashSecuredOption'\n : option.isLong\n ? 'optionProtectedLoan'\n : 'upfrontShortOption'\n\n return { kind, legIndices, chargedLegIndex: option.index }\n }\n\n // Both legs width=0 (two loans/credits partnered) — not a recognized strategy.\n return unrecognized\n}\n\n/**\n * Rebuild a group as a standalone tokenId on the same pool, so it can be priced\n * on its own.\n *\n * Legs are re-indexed to `0..n-1` and `riskPartner` is remapped to stay\n * self-consistent — otherwise an isolated leg would point at an index that no\n * longer exists and the contract would reject the tokenId.\n *\n * @param tokenId - The full position (supplies the poolId and leg data)\n * @param legIndices - Indices of the legs to isolate\n * @returns A valid tokenId containing only those legs\n */\nexport function isolateGroupTokenId(tokenId: bigint, legIndices: bigint[]): bigint {\n const legs = decodeAllLegs(tokenId)\n const byIndex = new Map(legs.map((leg) => [leg.index, leg]))\n const ordered = [...legIndices].sort((x, y) => (x < y ? -1 : x > y ? 1 : 0))\n const remapped = new Map(ordered.map((old, i) => [old, BigInt(i)]))\n\n let out = tokenId & POOL_ID_MASK\n for (const [index, oldIndex] of ordered.entries()) {\n const leg = byIndex.get(oldIndex)\n if (leg === undefined) {\n throw new PanopticError(`isolateGroupTokenId: leg ${oldIndex} is not present in the tokenId`)\n }\n const newIndex = BigInt(index)\n // A partner outside this group cannot survive isolation — self-partner it,\n // which is the encoding for \"no partner\".\n const newPartner = remapped.get(leg.riskPartner) ?? newIndex\n out = addLegToTokenId(out, {\n index: newIndex,\n asset: leg.asset,\n tokenType: leg.tokenType,\n optionRatio: leg.optionRatio,\n isLong: leg.isLong ? 1n : 0n,\n riskPartner: newPartner,\n strike: leg.strike,\n width: leg.width,\n })\n }\n return out\n}\n\n/** A classified group plus its share of the requirement. */\nexport interface StrategyAllocation extends StrategyGroup {\n /**\n * The group priced in isolation, in token0 units, scaled to `positionSize`.\n * `null` when that pricing failed (reverted or returned the sentinel).\n */\n isolatedRequired0: bigint | null\n /**\n * This group's share of the AUTHORITATIVE total, apportioned by\n * `isolatedRequired0`. `null` when this group could not be priced, or when no\n * group could — in which case the total is reported without a split rather\n * than with a fabricated one.\n */\n allocated: bigint | null\n}\n\n/** Parameters for {@link estimateCollateralBreakdown}. */\nexport interface EstimateCollateralBreakdownParams {\n /** Minimal viem client surface used by this read. */\n client: Pick<PublicClient, 'getBlock' | 'getBlockNumber' | 'multicall'>\n /** PanopticPool address */\n poolAddress: Address\n /** PanopticQuery address (holds `getRequiredBase`) */\n queryAddress: Address\n /** The position being explained */\n tokenId: bigint\n /** Position size (number of contracts) */\n positionSize: bigint\n /**\n * The authoritative requirement to apportion, in token0 units — the figure the\n * UI already displays, from the simulation or from `getRequiredBase` on the\n * whole position. Omit to report classification and isolated prices only.\n */\n authoritativeRequired0?: bigint\n /** Tick to price at. Defaults to the pool's current tick. */\n atTick?: bigint\n /** Optional block number, pinning every group to one block */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata */\n _meta?: BlockMeta\n}\n\n/** Result of {@link estimateCollateralBreakdown}. */\nexport interface CollateralBreakdown {\n /** One entry per charged group, in ascending leg order. */\n allocations: StrategyAllocation[]\n /** The total that was apportioned, echoed back. `null` if none was supplied. */\n authoritativeRequired0: bigint | null\n /**\n * True when at least one group could not be priced, so the split covers less\n * than the whole position. The total remains authoritative either way — the\n * UI must say the breakdown is partial rather than imply the rest is free.\n */\n partial: boolean\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Classify a position and estimate how its collateral requirement splits across\n * the strategies the RiskEngine recognizes.\n *\n * Every group is priced in ONE multicall, at one tick and one block, so the\n * weights are mutually consistent. A group that reverts or returns the\n * `getRequiredBase` error sentinel is dropped from the apportionment (and flips\n * `partial`) rather than being scaled from a garbage value.\n *\n * The apportionment preserves the total exactly: shares are floor-divided and\n * the rounding residue is given to the last priced group, so the allocations sum\n * to `authoritativeRequired0` with no bigint dust.\n *\n * @param params - The parameters\n * @returns The classified groups with their estimated allocations\n */\nexport async function estimateCollateralBreakdown(\n params: EstimateCollateralBreakdownParams,\n): Promise<CollateralBreakdown> {\n const {\n client,\n poolAddress,\n queryAddress,\n tokenId,\n positionSize,\n authoritativeRequired0,\n atTick,\n blockNumber,\n } = params\n\n if (\n blockNumber !== undefined &&\n params._meta !== undefined &&\n params._meta.blockNumber !== blockNumber\n ) {\n throw new PanopticError(\n 'estimateCollateralBreakdown: blockNumber and _meta.blockNumber disagree; cannot guarantee same-block consistency',\n )\n }\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n const groups = classifyStrategyGroups(tokenId)\n\n // One tick for every group, so the weights are mutually comparable.\n const effectiveTick =\n atTick ??\n BigInt(\n (\n await client.multicall({\n contracts: [\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n })\n )[0],\n )\n\n const [results, _meta] = await Promise.all([\n client.multicall({\n contracts: groups.map((group) => ({\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'getRequiredBase' as const,\n args: [poolAddress, isolateGroupTokenId(tokenId, group.legIndices), Number(effectiveTick)],\n })),\n blockNumber: targetBlockNumber,\n allowFailure: true,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const isolated = results.map((result) => {\n if (result.status !== 'success') return null\n const raw = result.result as bigint\n // The sentinel is type(uint128).max, not a requirement — never scale it.\n if (raw >= REQUIRED_BASE_ERROR_SENTINEL) return null\n return (raw * positionSize) / MAX_UINT64\n })\n\n const allocations = apportion(groups, isolated, authoritativeRequired0 ?? null)\n\n return {\n allocations,\n authoritativeRequired0: authoritativeRequired0 ?? null,\n partial: isolated.some((value) => value === null),\n _meta,\n }\n}\n\n/**\n * Split `total` across the priced groups in proportion to their isolated\n * requirements, giving the rounding residue to the last priced group so the\n * parts sum to the whole exactly.\n *\n * Exported for testing; the allocation is pure and worth pinning independently\n * of the RPC layer.\n *\n * @param groups - The classified groups\n * @param isolated - Per-group isolated price, `null` where pricing failed\n * @param total - The authoritative total to apportion, or `null` for none\n * @returns Allocations aligned 1:1 with `groups`\n */\nexport function apportion(\n groups: StrategyGroup[],\n isolated: (bigint | null)[],\n total: bigint | null,\n): StrategyAllocation[] {\n if (groups.length !== isolated.length) {\n throw new PanopticError(\n `apportion: groups and isolated must have equal lengths (${groups.length} !== ${isolated.length})`,\n )\n }\n\n const weightSum = isolated.reduce<bigint>((sum, value) => sum + (value ?? 0n), 0n)\n\n // Nothing to apportion, or nothing to apportion it by. Report the\n // classification without inventing numbers — a group showing 0 would read as\n // \"this part is free\", which is a different and wrong claim.\n if (total === null || total <= 0n || weightSum <= 0n) {\n return groups.map((group, i) => ({\n ...group,\n isolatedRequired0: isolated[i],\n allocated: null,\n }))\n }\n\n const lastPriced = isolated.reduce<number>((last, value, i) => (value === null ? last : i), -1)\n\n let assigned = 0n\n return groups.map((group, i) => {\n const weight = isolated[i]\n if (weight === null) {\n return { ...group, isolatedRequired0: null, allocated: null }\n }\n // The last priced group absorbs the floor-division residue, so the\n // allocations sum to `total` exactly.\n const allocated = i === lastPriced ? total - assigned : (total * weight) / weightSum\n assigned += allocated\n return { ...group, isolatedRequired0: weight, allocated }\n })\n}\n","/**\n * ERC4626 vault preview functions for the Panoptic v2 SDK.\n *\n * The CollateralTracker contract implements ERC4626, providing standard\n * vault functionality for depositing/withdrawing collateral.\n *\n * @module v2/reads/erc4626\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { collateralTrackerV2Abi, panopticPoolV2Abi } from '../../../generated'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport type { BlockMeta } from '../types'\n\n/**\n * Parameters for ERC4626 preview functions.\n */\nexport interface ERC4626PreviewParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Which token's collateral tracker to query (0 or 1) */\n tokenIndex: 0 | 1\n /** Amount to preview */\n amount: bigint\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched collateral tracker address */\n collateralTrackerAddress?: Address\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * ERC4626 preview result.\n */\nexport interface ERC4626PreviewResult {\n /** The resulting amount (shares or assets depending on function) */\n result: bigint\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Helper to get collateral tracker address.\n */\nasync function getCollateralTrackerAddress(\n client: PublicClient,\n poolAddress: Address,\n tokenIndex: 0 | 1,\n providedAddress?: Address,\n): Promise<Address> {\n if (providedAddress) return providedAddress\n\n return client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: tokenIndex === 0 ? 'collateralToken0' : 'collateralToken1',\n })\n}\n\n/**\n * Preview the amount of shares that would be minted for a deposit.\n *\n * @param params - The parameters\n * @returns Preview result with block metadata\n */\nexport async function previewDeposit(params: ERC4626PreviewParams): Promise<ERC4626PreviewResult> {\n const { client, poolAddress, tokenIndex, amount, blockNumber, collateralTrackerAddress } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n const trackerAddress = await getCollateralTrackerAddress(\n client,\n poolAddress,\n tokenIndex,\n collateralTrackerAddress,\n )\n\n const [result, _meta] = await Promise.all([\n client.readContract({\n address: trackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'previewDeposit',\n args: [amount],\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n return { result, _meta }\n}\n\n/**\n * Preview the amount of assets that would be returned for a withdrawal.\n *\n * @param params - The parameters\n * @returns Preview result with block metadata\n */\nexport async function previewWithdraw(params: ERC4626PreviewParams): Promise<ERC4626PreviewResult> {\n const { client, poolAddress, tokenIndex, amount, blockNumber, collateralTrackerAddress } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n const trackerAddress = await getCollateralTrackerAddress(\n client,\n poolAddress,\n tokenIndex,\n collateralTrackerAddress,\n )\n\n const [result, _meta] = await Promise.all([\n client.readContract({\n address: trackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'previewWithdraw',\n args: [amount],\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n return { result, _meta }\n}\n\n/**\n * Preview the amount of assets required for a mint.\n *\n * @param params - The parameters\n * @returns Preview result with block metadata\n */\nexport async function previewMint(params: ERC4626PreviewParams): Promise<ERC4626PreviewResult> {\n const { client, poolAddress, tokenIndex, amount, blockNumber, collateralTrackerAddress } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n const trackerAddress = await getCollateralTrackerAddress(\n client,\n poolAddress,\n tokenIndex,\n collateralTrackerAddress,\n )\n\n const [result, _meta] = await Promise.all([\n client.readContract({\n address: trackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'previewMint',\n args: [amount],\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n return { result, _meta }\n}\n\n/**\n * Preview the amount of shares that would be burned for a redeem.\n *\n * @param params - The parameters\n * @returns Preview result with block metadata\n */\nexport async function previewRedeem(params: ERC4626PreviewParams): Promise<ERC4626PreviewResult> {\n const { client, poolAddress, tokenIndex, amount, blockNumber, collateralTrackerAddress } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n const trackerAddress = await getCollateralTrackerAddress(\n client,\n poolAddress,\n tokenIndex,\n collateralTrackerAddress,\n )\n\n const [result, _meta] = await Promise.all([\n client.readContract({\n address: trackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'previewRedeem',\n args: [amount],\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n return { result, _meta }\n}\n\n/**\n * Convert an amount of assets to shares.\n *\n * @param params - The parameters\n * @returns Conversion result with block metadata\n */\nexport async function convertToShares(params: ERC4626PreviewParams): Promise<ERC4626PreviewResult> {\n const { client, poolAddress, tokenIndex, amount, blockNumber, collateralTrackerAddress } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n const trackerAddress = await getCollateralTrackerAddress(\n client,\n poolAddress,\n tokenIndex,\n collateralTrackerAddress,\n )\n\n const [result, _meta] = await Promise.all([\n client.readContract({\n address: trackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'convertToShares',\n args: [amount],\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n return { result, _meta }\n}\n\n/**\n * Convert an amount of shares to assets.\n *\n * @param params - The parameters\n * @returns Conversion result with block metadata\n */\nexport async function convertToAssets(params: ERC4626PreviewParams): Promise<ERC4626PreviewResult> {\n const { client, poolAddress, tokenIndex, amount, blockNumber, collateralTrackerAddress } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n const trackerAddress = await getCollateralTrackerAddress(\n client,\n poolAddress,\n tokenIndex,\n collateralTrackerAddress,\n )\n\n const [result, _meta] = await Promise.all([\n client.readContract({\n address: trackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'convertToAssets',\n args: [amount],\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n return { result, _meta }\n}\n","/**\n * PanopticGuardian read functions for the Panoptic v2 SDK.\n *\n * The Guardian can lock a pool into close-only mode. Unlocking is a two-step\n * timelocked flow: `requestUnlock(pool)` schedules an unlock ETA, and after the\n * ETA matures `executeUnlock(pool)` clears the lock. This module reads the\n * pending-unlock state so the UI can surface a countdown while a pool is locked.\n *\n * @module v2/reads/guardian\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { panopticGuardianAbi, panopticPoolV2Abi, riskEngineAbi } from '../../../generated'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport type { BlockMeta } from '../types'\n\n/**\n * Parameters for getGuardianUnlockState.\n */\nexport interface GetGuardianUnlockStateParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Optional RiskEngine address (skips the pool.riskEngine() read) */\n riskEngineAddress?: Address\n /** Optional PanopticGuardian address (skips the riskEngine.GUARDIAN() read) */\n guardianAddress?: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Guardian pool-unlock state.\n */\nexport interface GuardianUnlockState {\n /** Resolved PanopticGuardian contract address */\n guardianAddress: Address\n /** Unlock ETA as a Unix timestamp (seconds); 0n when no unlock is pending */\n unlockEta: bigint\n /** True when an unlock has been requested but not yet executed */\n hasPendingUnlock: boolean\n /** True when the pending unlock's timelock has elapsed and it can be executed */\n isReady: boolean\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Read the Guardian pending-unlock state for a pool.\n *\n * Resolves the Guardian address from the pool's RiskEngine when not provided,\n * then reads `unlockEta` and `isPoolUnlockReady` from the PanopticGuardian in a\n * single multicall pinned to the same block.\n *\n * @param params - The parameters\n * @returns Guardian unlock state with block metadata\n */\nexport async function getGuardianUnlockState(\n params: GetGuardianUnlockStateParams,\n): Promise<GuardianUnlockState> {\n const { client, poolAddress, blockNumber } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Only reuse caller-supplied metadata when it matches the block we read at,\n // otherwise data and metadata would come from different blocks.\n const reusableMeta =\n params._meta && params._meta.blockNumber === targetBlockNumber ? params._meta : undefined\n\n // Resolve the RiskEngine (immutable) unless caller supplied it.\n const riskEngineAddress =\n params.riskEngineAddress ??\n (await client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'riskEngine',\n blockNumber: targetBlockNumber,\n }))\n\n // Resolve the Guardian (immutable) unless caller supplied it.\n const guardianAddress =\n params.guardianAddress ??\n (await client.readContract({\n address: riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'GUARDIAN',\n blockNumber: targetBlockNumber,\n }))\n\n const [results, _meta] = await Promise.all([\n client.multicall({\n contracts: [\n {\n address: guardianAddress,\n abi: panopticGuardianAbi,\n functionName: 'unlockEta',\n args: [poolAddress],\n },\n {\n address: guardianAddress,\n abi: panopticGuardianAbi,\n functionName: 'isPoolUnlockReady',\n args: [poolAddress],\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n }),\n reusableMeta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [unlockEta, isReady] = results\n\n return {\n guardianAddress,\n unlockEta,\n hasPendingUnlock: unlockEta > 0n,\n isReady,\n _meta,\n }\n}\n","/**\n * Safe mode check functions for the Panoptic v2 SDK.\n *\n * Safe mode is a protective mechanism that activates when pool conditions\n * become dangerous (e.g., extreme price movements or liquidity issues).\n *\n * @module v2/reads/safeMode\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport type { BlockMeta, SafeModeState as OracleSafeModeState } from '../types'\n\n/**\n * Safe mode status values.\n */\nexport const SafeModeStatus = {\n /** Pool is operating normally */\n NORMAL: 0n,\n /** No new leveraged positions allowed */\n NO_LEVERAGE: 1n,\n /** No swaps allowed */\n NO_SWAP: 2n,\n /** Close-only mode */\n CLOSE_ONLY: 3n,\n} as const\n\nexport type SafeModeStatusValue = (typeof SafeModeStatus)[keyof typeof SafeModeStatus]\n\n/**\n * Safe mode state for bot preflight and operation guards.\n */\nexport type SafeModeState = OracleSafeModeState\n\n/**\n * Parameters for getSafeMode.\n */\nexport interface GetSafeModeParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get the current safe mode status of a pool.\n *\n * Safe mode is activated when:\n * - Pool liquidity drops below safe thresholds\n * - Price volatility exceeds safe limits\n * - Administrative pause is triggered\n *\n * @param params - The parameters\n * @returns Safe mode state with block metadata\n */\nexport async function getSafeMode(params: GetSafeModeParams): Promise<SafeModeState> {\n const { client, poolAddress, blockNumber } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n const [safeModeRaw, _meta] = await Promise.all([\n client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'isSafeMode',\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n // isSafeMode is additive: 0 = normal, 1 = cash-account collateral,\n // 2 = no swapAtMint, and every value >=3 is close-only.\n const level = BigInt(safeModeRaw)\n\n if (level >= SafeModeStatus.CLOSE_ONLY) {\n return {\n level,\n mode: 'emergency',\n canMint: false,\n canBurn: true,\n canForceExercise: true,\n canLiquidate: true,\n canSwapAtMint: false,\n reason: 'Pool is in close-only mode',\n _meta,\n }\n }\n if (level >= SafeModeStatus.NO_SWAP) {\n return {\n level,\n mode: 'restricted',\n canMint: true,\n canBurn: true,\n canForceExercise: true,\n canLiquidate: true,\n canSwapAtMint: false,\n reason: 'All positions require 100% collateral; swaps are disabled',\n _meta,\n }\n }\n if (level >= SafeModeStatus.NO_LEVERAGE) {\n return {\n level,\n mode: 'restricted',\n canMint: true,\n canBurn: true,\n canForceExercise: true,\n canLiquidate: true,\n canSwapAtMint: true,\n reason: 'All positions require 100% collateral',\n _meta,\n }\n }\n return {\n level,\n mode: 'normal',\n canMint: true,\n canBurn: true,\n canForceExercise: true,\n canLiquidate: true,\n canSwapAtMint: true,\n _meta,\n }\n}\n","/**\n * Additional utility functions using PanopticQuery contract.\n *\n * These functions provide enhanced analysis capabilities for portfolio management,\n * risk visualization, and TokenId optimization.\n *\n * @module v2/reads/queryUtils\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { panopticQueryAbi } from '../abis/panopticQuery'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport type { BlockMeta } from '../types'\n\n/**\n * Portfolio value result (without premia).\n */\nexport interface PortfolioValue {\n /** Value in token 0 */\n value0: bigint\n /** Value in token 1 */\n value1: bigint\n /** Tick at which value was calculated */\n atTick: bigint\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Parameters for getPortfolioValue.\n */\nexport interface GetPortfolioValueParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** TokenIds of open positions */\n tokenIds: bigint[]\n /** Optional: Tick to calculate value at (defaults to current tick) */\n atTick?: bigint\n /** PanopticQuery address (required for this function) */\n queryAddress: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get portfolio value (NAV) without premia.\n *\n * This calculates the net asset value of the portfolio based on Uniswap liquidity\n * at a given tick, excluding accumulated premia. Useful for PnL tracking separate\n * from liquidation value.\n *\n * ## Same-Block Guarantee\n * All data is fetched at a single block.\n *\n * @param params - The parameters\n * @returns Portfolio value with block metadata\n */\nexport async function getPortfolioValue(params: GetPortfolioValueParams): Promise<PortfolioValue> {\n const { client, poolAddress, account, tokenIds, atTick, queryAddress, blockNumber } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Skip getCurrentTick RPC call when atTick is provided\n const [currentTickResult, _meta] = await Promise.all([\n atTick != null\n ? Promise.resolve(atTick)\n : client\n .readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n blockNumber: targetBlockNumber,\n })\n .then((r) => BigInt(r)),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const effectiveTick = currentTickResult\n\n const result = await client.readContract({\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'getPortfolioValue',\n args: [poolAddress, account, Number(effectiveTick), tokenIds],\n blockNumber: targetBlockNumber,\n })\n\n const [value0, value1] = result\n\n return {\n value0,\n value1,\n atTick: effectiveTick,\n _meta,\n }\n}\n\n/**\n * Collateral data point across tick range.\n */\nexport interface CollateralDataPoint {\n /** Tick value */\n tick: bigint\n /** Collateral balance at this tick */\n balance: bigint\n /** Required collateral at this tick */\n required: bigint\n}\n\n/**\n * Collateral analysis across tick range result.\n */\nexport interface CollateralAcrossTicks {\n /** Array of data points (301 points from liquidation range) */\n dataPoints: CollateralDataPoint[]\n /** Liquidation price below current (null if none) */\n liquidationPriceDown: bigint | null\n /** Liquidation price above current (null if none) */\n liquidationPriceUp: bigint | null\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Parameters for checkCollateralAcrossTicks.\n */\nexport interface CheckCollateralAcrossTicksParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** TokenIds of open positions */\n tokenIds: bigint[]\n /** PanopticQuery address (required for this function) */\n queryAddress: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Check collateral balance vs requirement across a range of ticks.\n *\n * This function returns 301 data points spanning a range around the current price,\n * including liquidation prices. Perfect for charting liquidation risk in a UI.\n *\n * ## Same-Block Guarantee\n * All data is fetched at a single block.\n *\n * @param params - The parameters\n * @returns Collateral analysis across ticks with block metadata\n */\nexport async function checkCollateralAcrossTicks(\n params: CheckCollateralAcrossTicksParams,\n): Promise<CollateralAcrossTicks> {\n const { client, poolAddress, account, tokenIds, queryAddress, blockNumber } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n const [result, _meta] = await Promise.all([\n client.readContract({\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'checkCollateralListOutput',\n args: [poolAddress, account, tokenIds],\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [balanceRequired, tickData, liquidationPrices] = result\n\n // MIN_TICK and MAX_TICK indicate no liquidation at that boundary\n const MIN_TICK = -887272n\n const MAX_TICK = 887272n\n\n // Convert to data points\n const dataPoints: CollateralDataPoint[] = balanceRequired.map((point, index) => ({\n tick: BigInt(tickData[index]),\n balance: point[0],\n required: point[1],\n }))\n\n // Convert from number (abitype default for int24) to bigint (viem runtime type)\n const liqPriceDown = BigInt(liquidationPrices[0])\n const liqPriceUp = BigInt(liquidationPrices[1])\n\n return {\n dataPoints,\n liquidationPriceDown: liqPriceDown === MIN_TICK ? null : liqPriceDown,\n liquidationPriceUp: liqPriceUp === MAX_TICK ? null : liqPriceUp,\n _meta,\n }\n}\n\n/**\n * Parameters for optimizeTokenIdRiskPartners.\n */\nexport interface OptimizeTokenIdRiskPartnersParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** TokenId to optimize */\n tokenId: bigint\n /** Optional: Tick to optimize at (defaults to current tick) */\n atTick?: bigint\n /** PanopticQuery address (required for this function) */\n queryAddress: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Optimize risk partner assignments for a TokenId.\n *\n * Tests all valid risk partner permutations and returns the TokenId with\n * the lowest collateral requirement. Useful when building positions to\n * maximize capital efficiency.\n *\n * ## Same-Block Guarantee\n * Optimization is performed at a single block.\n *\n * Note: Only works for tokenIds with 2+ legs. Single-leg positions return unchanged.\n *\n * @param params - The parameters\n * @returns Optimized TokenId\n */\nexport async function optimizeTokenIdRiskPartners(\n params: OptimizeTokenIdRiskPartnersParams,\n): Promise<bigint> {\n const { client, poolAddress, tokenId, atTick, queryAddress, blockNumber } = params\n\n const targetBlockNumber = blockNumber ?? (await client.getBlockNumber())\n\n // Get current tick if not provided\n let effectiveTick: bigint\n if (atTick !== undefined) {\n effectiveTick = atTick\n } else {\n const currentTickResult = await client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n blockNumber: targetBlockNumber,\n })\n // Bridge type from panopticPoolV2Abi (number | bigint) to bigint\n effectiveTick = BigInt(currentTickResult)\n }\n\n const optimizedTokenId = await client.readContract({\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'optimizeRiskPartners',\n args: [poolAddress, Number(effectiveTick), tokenId],\n blockNumber: targetBlockNumber,\n })\n\n return optimizedTokenId\n}\n","/**\n * Pool liquidity distribution read function using PanopticQuery.\n *\n * @module v2/reads/liquidity\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { panopticQueryAbi } from '../abis/panopticQuery'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport type { BlockMeta } from '../types'\n\n/**\n * Result of getPoolLiquidities.\n */\nexport interface PoolLiquidities {\n /** Tick values for each data point */\n ticks: bigint[]\n /** Net liquidity at each tick */\n liquidityNets: bigint[]\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Parameters for getPoolLiquidities.\n */\nexport interface GetPoolLiquiditiesParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** PanopticQuery address */\n queryAddress: Address\n /** Starting tick of the range */\n startTick: bigint\n /** Number of ticks to query */\n nTicks: bigint\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get cumulative liquidity distribution across a tick range.\n *\n * Wraps `PanopticQuery.getTickNets()` to return tick data and net liquidity\n * for each tick in the specified range.\n *\n * ## Same-Block Guarantee\n * All data is fetched at a single block.\n *\n * @param params - The parameters\n * @returns Tick data and liquidity nets with block metadata\n */\nexport async function getPoolLiquidities(\n params: GetPoolLiquiditiesParams,\n): Promise<PoolLiquidities> {\n const { client, poolAddress, queryAddress, startTick, nTicks, blockNumber } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n const [result, _meta] = await Promise.all([\n client.readContract({\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'getTickNets',\n args: [poolAddress, Number(startTick), nTicks],\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [tickData, liquidityNets] = result\n\n return {\n ticks: [...tickData],\n liquidityNets: [...liquidityNets],\n _meta,\n }\n}\n","/**\n * Token amount formatters and parsers.\n *\n * All formatters require explicit precision - no hidden defaults.\n *\n * @module v2/formatters/amount\n */\n\nimport type { TokenFlow } from '../types'\n\n/**\n * Format a raw token amount to a human-readable string.\n *\n * @param amount - The amount in smallest units (e.g., wei)\n * @param decimals - Token decimals (e.g., 18n for WETH, 6n for USDC)\n * @param precision - Number of decimal places to display\n * @returns Formatted string\n *\n * @example\n * ```typescript\n * formatTokenAmount(1500000000000000000n, 18n, 4n) // \"1.5000\"\n * formatTokenAmount(1500000000000000000n, 18n, 2n) // \"1.50\"\n * formatTokenAmount(1500000n, 6n, 2n) // \"1.50\" (USDC)\n * formatTokenAmount(-500000000000000000n, 18n, 4n) // \"-0.5000\"\n * ```\n */\nexport function formatTokenAmount(amount: bigint, decimals: bigint, precision: bigint): string {\n const isNegative = amount < 0n\n const absAmount = isNegative ? -amount : amount\n const divisor = 10n ** decimals\n const integerPart = absAmount / divisor\n const fractionalPart = absAmount % divisor\n\n // Build fractional string with proper padding\n const fullFractionalStr = fractionalPart.toString().padStart(Number(decimals), '0')\n const truncatedFractionalStr = fullFractionalStr.slice(0, Number(precision))\n const paddedFractionalStr = truncatedFractionalStr.padEnd(Number(precision), '0')\n\n const sign = isNegative ? '-' : ''\n return precision > 0n ? `${sign}${integerPart}.${paddedFractionalStr}` : `${sign}${integerPart}`\n}\n\n/**\n * Format a token amount with a sign prefix (+/-) for non-zero values.\n * Useful for displaying PnL, deltas, or changes.\n *\n * @param amount - The amount in smallest units\n * @param decimals - Token decimals\n * @param precision - Number of decimal places to display\n * @returns Formatted string with sign prefix\n *\n * @example\n * ```typescript\n * formatTokenAmountSigned(1500000000000000000n, 18n, 4n) // \"+1.5000\"\n * formatTokenAmountSigned(-500000000000000000n, 18n, 4n) // \"-0.5000\"\n * formatTokenAmountSigned(0n, 18n, 4n) // \"0.0000\"\n * ```\n */\nexport function formatTokenAmountSigned(\n amount: bigint,\n decimals: bigint,\n precision: bigint,\n): string {\n const formatted = formatTokenAmount(amount, decimals, precision)\n if (amount > 0n) {\n return `+${formatted}`\n }\n return formatted\n}\n\n/**\n * Parse a human-readable token amount string to raw units.\n *\n * @param amount - Human-readable amount string (e.g., \"1.5\")\n * @param decimals - Token decimals\n * @returns Amount in smallest units\n *\n * @example\n * ```typescript\n * parseTokenAmount(\"1.5\", 18n) // 1500000000000000000n\n * parseTokenAmount(\"1.5\", 6n) // 1500000n (USDC)\n * parseTokenAmount(\"100\", 18n) // 100000000000000000000n\n * parseTokenAmount(\"-0.5\", 18n) // -500000000000000000n\n * ```\n */\nexport function parseTokenAmount(amount: string, decimals: bigint): bigint {\n const trimmed = amount.trim()\n const isNegative = trimmed.startsWith('-')\n const cleanAmount = isNegative ? trimmed.slice(1) : trimmed\n\n const [integerStr, fractionalStr = ''] = cleanAmount.split('.')\n const paddedFractional = fractionalStr.padEnd(Number(decimals), '0').slice(0, Number(decimals))\n\n const integerPart = BigInt(integerStr || '0') * 10n ** decimals\n const fractionalPart = BigInt(paddedFractional || '0')\n\n const result = integerPart + fractionalPart\n return isNegative ? -result : result\n}\n\n/**\n * Format a token delta amount with a sign prefix (+/-) for non-zero values.\n * Alias for formatTokenAmountSigned, useful for clarity at call sites.\n *\n * @param amount - The delta amount in smallest units\n * @param decimals - Token decimals\n * @param precision - Number of decimal places to display\n * @returns Formatted string with sign prefix\n */\nexport function formatTokenDelta(amount: bigint, decimals: bigint, precision: bigint): string {\n return formatTokenAmountSigned(amount, decimals, precision)\n}\n\n/**\n * Format token flow deltas and balances from simulation results.\n *\n * @param flow - Token flow data\n * @param decimals0 - Token0 decimals\n * @param decimals1 - Token1 decimals\n * @param precision0 - Precision for token0 formatting\n * @param precision1 - Precision for token1 formatting\n * @returns Formatted token flow strings\n */\nexport function formatTokenFlow(\n flow: TokenFlow,\n decimals0: bigint,\n decimals1: bigint,\n precision0: bigint,\n precision1: bigint,\n): {\n delta0: string\n delta1: string\n balanceBefore0: string\n balanceBefore1: string\n balanceAfter0: string\n balanceAfter1: string\n} {\n return {\n delta0: formatTokenAmountSigned(flow.delta0, decimals0, precision0),\n delta1: formatTokenAmountSigned(flow.delta1, decimals1, precision1),\n balanceBefore0: formatTokenAmount(flow.balanceBefore0, decimals0, precision0),\n balanceBefore1: formatTokenAmount(flow.balanceBefore1, decimals1, precision1),\n balanceAfter0: formatTokenAmount(flow.balanceAfter0, decimals0, precision0),\n balanceAfter1: formatTokenAmount(flow.balanceAfter1, decimals1, precision1),\n }\n}\n","/**\n * Percentage and ratio formatters.\n *\n * All formatters require explicit precision - no hidden defaults.\n *\n * @module v2/formatters/percentage\n */\n\nconst TEN = 10n\n\nfunction formatRatio(numerator: bigint, denominator: bigint, precision: bigint): string {\n if (precision < 0n) {\n throw new RangeError('Precision must be non-negative')\n }\n\n if (denominator === 0n) {\n return '0'\n }\n\n const isNegative = numerator < 0n !== denominator < 0n\n const absNumerator = numerator < 0n ? -numerator : numerator\n const absDenominator = denominator < 0n ? -denominator : denominator\n\n const scale = TEN ** precision\n const scaled = (absNumerator * scale + absDenominator / 2n) / absDenominator\n const integerPart = scaled / scale\n const fractionalPart = scaled % scale\n const sign = isNegative ? '-' : ''\n\n if (precision === 0n) {\n return `${sign}${integerPart}`\n }\n\n return `${sign}${integerPart}.${fractionalPart.toString().padStart(Number(precision), '0')}`\n}\n\n/**\n * Format basis points as a percentage string.\n * 100 bps = 1%\n *\n * @param bps - Basis points value\n * @param precision - Number of decimal places to display\n * @returns Formatted percentage string\n *\n * @example\n * ```typescript\n * formatBps(50n, 2n) // \"0.50%\"\n * formatBps(50n, 1n) // \"0.5%\"\n * formatBps(100n, 2n) // \"1.00%\"\n * formatBps(1500n, 2n) // \"15.00%\"\n * formatBps(-50n, 2n) // \"-0.50%\"\n * ```\n */\nexport function formatBps(bps: bigint, precision: bigint): string {\n const isNegative = bps < 0n\n const absBps = isNegative ? -bps : bps\n\n // bps to percentage: divide by 100\n // Scale up for precision, then divide\n const scaleFactor = 10n ** precision\n const scaled = (absBps * scaleFactor) / 100n\n const integerPart = scaled / scaleFactor\n const fractionalPart = scaled % scaleFactor\n\n const fractionalStr = fractionalPart.toString().padStart(Number(precision), '0')\n const sign = isNegative ? '-' : ''\n\n return precision > 0n ? `${sign}${integerPart}.${fractionalStr}%` : `${sign}${integerPart}%`\n}\n\n/**\n * Format utilization as a percentage string.\n * Utilization is stored as 0n-10000n, where 10000n = 100%.\n *\n * @param util - Utilization value (0-10000)\n * @param precision - Number of decimal places to display\n * @returns Formatted percentage string\n *\n * @example\n * ```typescript\n * formatUtilization(7500n, 2n) // \"75.00%\"\n * formatUtilization(7500n, 0n) // \"75%\"\n * formatUtilization(10000n, 2n) // \"100.00%\"\n * formatUtilization(123n, 2n) // \"1.23%\"\n * ```\n */\nexport function formatUtilization(util: bigint, precision: bigint): string {\n // util is in basis points (10000 = 100%)\n return formatBps(util, precision)\n}\n\n/**\n * Parse a percentage string to basis points.\n *\n * @param percent - Percentage string (e.g., \"1.5%\" or \"1.5\")\n * @returns Basis points value\n *\n * @example\n * ```typescript\n * parseBps(\"1.5%\") // 150n\n * parseBps(\"1.5\") // 150n\n * parseBps(\"100%\") // 10000n\n * parseBps(\"0.5%\") // 50n\n * ```\n */\nexport function parseBps(percent: string): bigint {\n // Remove % suffix if present\n const cleaned = percent.trim().replace(/%$/, '')\n const isNegative = cleaned.startsWith('-')\n const absValue = isNegative ? cleaned.slice(1) : cleaned\n\n const [integerStr, fractionalStr = ''] = absValue.split('.')\n\n // Convert to basis points: multiply by 100\n // Handle up to 2 decimal places in the percentage\n const paddedFractional = fractionalStr.padEnd(2, '0').slice(0, 2)\n\n const integerPart = BigInt(integerStr || '0') * 100n\n const fractionalPart = BigInt(paddedFractional || '0')\n\n const result = integerPart + fractionalPart\n return isNegative ? -result : result\n}\n\n/**\n * Format a ratio as a percentage string.\n *\n * @param numerator - Numerator of the ratio\n * @param denominator - Denominator of the ratio\n * @param precision - Number of decimal places to display\n * @returns Formatted percentage string\n *\n * @example\n * ```typescript\n * formatRatioPercent(1n, 4n, 1n) // \"25.0%\"\n * formatRatioPercent(3n, 4n, 2n) // \"75.00%\"\n * ```\n */\nexport function formatRatioPercent(\n numerator: bigint,\n denominator: bigint,\n precision: bigint,\n): string {\n const scaledNumerator = numerator * 100n\n return `${formatRatio(scaledNumerator, denominator, precision)}%`\n}\n","/**\n * WAD-scaled value formatters.\n *\n * WAD is a fixed-point representation where 1e18 = 1.0.\n * Used extensively in DeFi for representing ratios, prices, and multipliers.\n *\n * @module v2/formatters/wad\n */\n\nimport { formatTokenAmount } from './amount'\n\n/**\n * Format a WAD-scaled value (1e18 = 1.0).\n *\n * @param wad - WAD-scaled value\n * @param precision - Number of decimal places to display\n * @returns Formatted string\n *\n * @example\n * ```typescript\n * formatWad(1220000000000000000n, 2n) // \"1.22\"\n * formatWad(1220000000000000000n, 4n) // \"1.2200\"\n * formatWad(1000000000000000000n, 2n) // \"1.00\"\n * formatWad(500000000000000000n, 2n) // \"0.50\"\n * ```\n */\nexport function formatWad(wad: bigint, precision: bigint): string {\n return formatTokenAmount(wad, 18n, precision)\n}\n\n/**\n * Format a WAD-scaled value with sign prefix (+/-) for non-zero values.\n *\n * @param wad - WAD-scaled value\n * @param precision - Number of decimal places to display\n * @returns Formatted string with sign prefix\n *\n * @example\n * ```typescript\n * formatWadSigned(1220000000000000000n, 2n) // \"+1.22\"\n * formatWadSigned(-500000000000000000n, 2n) // \"-0.50\"\n * formatWadSigned(0n, 2n) // \"0.00\"\n * ```\n */\nexport function formatWadSigned(wad: bigint, precision: bigint): string {\n const formatted = formatWad(wad, precision)\n if (wad > 0n) {\n return `+${formatted}`\n }\n return formatted\n}\n\n/**\n * Format a WAD-scaled value as a percentage string.\n *\n * @param wad - WAD-scaled value\n * @param precision - Number of decimal places to display\n * @returns Formatted percentage string\n *\n * @example\n * ```typescript\n * formatWadPercent(50000000000000000n, 2n) // \"5.00%\"\n * formatWadPercent(1000000000000000000n, 1n) // \"100.0%\"\n * ```\n */\nexport function formatWadPercent(wad: bigint, precision: bigint): string {\n return `${formatTokenAmount(wad * 100n, 18n, precision)}%`\n}\n\n/**\n * Format an annualized rate stored as a WAD-scaled value.\n * Alias for formatWadPercent.\n *\n * @param rateWad - Rate in WAD (1e18 = 1.0)\n * @param precision - Number of decimal places to display\n * @returns Formatted percentage string\n */\nexport function formatRateWad(rateWad: bigint, precision: bigint): string {\n return formatWadPercent(rateWad, precision)\n}\n\n/**\n * Parse a decimal string to a WAD-scaled value.\n *\n * @param value - Decimal string (e.g., \"1.5\")\n * @returns WAD-scaled bigint\n *\n * @example\n * ```typescript\n * parseWad(\"1.5\") // 1500000000000000000n\n * parseWad(\"0.5\") // 500000000000000000n\n * parseWad(\"100\") // 100000000000000000000n\n * parseWad(\"-1.22\") // -1220000000000000000n\n * ```\n */\nexport function parseWad(value: string): bigint {\n const trimmed = value.trim()\n const isNegative = trimmed.startsWith('-')\n const cleanValue = isNegative ? trimmed.slice(1) : trimmed\n\n const [integerStr, fractionalStr = ''] = cleanValue.split('.')\n const paddedFractional = fractionalStr.padEnd(18, '0').slice(0, 18)\n\n const integerPart = BigInt(integerStr || '0') * 10n ** 18n\n const fractionalPart = BigInt(paddedFractional || '0')\n\n const result = integerPart + fractionalPart\n return isNegative ? -result : result\n}\n","/**\n * Per-second rate helpers.\n *\n * Collateral tracker rates are returned as WAD-scaled per-second rates.\n * These helpers annualize them for display.\n *\n * @module v2/formatters/rates\n */\n\nimport { formatWadPercent } from './wad'\n\nconst SECONDS_PER_DAY = 86_400n\nconst DAYS_PER_YEAR = 365n\nconst SECONDS_PER_YEAR = SECONDS_PER_DAY * DAYS_PER_YEAR\n\n/**\n * Annualize a per-second WAD-scaled rate to annual WAD.\n *\n * @param ratePerSecondWad - Rate in WAD per second\n * @returns Annualized rate in WAD\n */\nexport function annualizePerSecondRateWad(ratePerSecondWad: bigint): bigint {\n return ratePerSecondWad * SECONDS_PER_YEAR\n}\n\n/**\n * Format a per-second WAD rate as APY percentage text.\n * Uses linear annualization, then formats as WAD percent.\n *\n * @param ratePerSecondWad - Rate in WAD per second\n * @param precision - Decimal places\n * @returns Percentage string, e.g. \"2.41%\"\n */\nexport function formatPerSecondRateWadAsApyPct(\n ratePerSecondWad: bigint,\n precision: bigint,\n): string {\n return formatWadPercent(annualizePerSecondRateWad(ratePerSecondWad), precision)\n}\n\n/**\n * Format a per-second WAD rate as APR percentage text.\n * For this rate model, APR presentation uses the same annualized output.\n *\n * @param ratePerSecondWad - Rate in WAD per second\n * @param precision - Decimal places\n * @returns Percentage string, e.g. \"2.41%\"\n */\nexport function formatPerSecondRateWadAsAprPct(\n ratePerSecondWad: bigint,\n precision: bigint,\n): string {\n return formatWadPercent(annualizePerSecondRateWad(ratePerSecondWad), precision)\n}\n","/**\n * Pool-bound formatters factory.\n *\n * Creates formatter functions that capture pool context (token decimals)\n * for less verbose call sites in single-pool UI components.\n *\n * @module v2/formatters/poolFormatters\n */\n\nimport { formatTokenAmount, parseTokenAmount } from './amount'\nimport { priceToTick, tickToPrice, tickToPriceDecimalScaled } from './tick'\n\n/**\n * Pool-bound formatters interface.\n *\n * These formatters capture the pool's token decimals, so you don't need\n * to pass them at every call site.\n */\nexport interface PoolFormatters {\n /** Token0 decimals */\n readonly decimals0: bigint\n /** Token1 decimals */\n readonly decimals1: bigint\n\n /**\n * Convert tick to raw price (1.0001^tick).\n */\n tickToPrice(tick: bigint): string\n\n /**\n * Convert tick to decimal-scaled price (token1 per token0).\n */\n tickToPriceScaled(tick: bigint, precision: bigint): string\n\n /**\n * Convert tick to decimal-scaled inverse price (token0 per token1).\n */\n tickToInversePriceScaled(tick: bigint, precision: bigint): string\n\n /**\n * Convert a price (token1 per token0) to tick.\n */\n priceToTick(price: string): bigint\n\n /**\n * Format token0 amount with specified precision.\n */\n formatAmount0(amount: bigint, precision: bigint): string\n\n /**\n * Format token1 amount with specified precision.\n */\n formatAmount1(amount: bigint, precision: bigint): string\n\n /**\n * Parse token0 amount string to raw units.\n */\n parseAmount0(amount: string): bigint\n\n /**\n * Parse token1 amount string to raw units.\n */\n parseAmount1(amount: string): bigint\n}\n\n/**\n * Pool metadata required to create pool-bound formatters.\n */\nexport interface PoolFormatterConfig {\n /** Token0 decimals */\n decimals0: bigint\n /** Token1 decimals */\n decimals1: bigint\n}\n\n/**\n * Create pool-bound formatters that capture token decimals.\n *\n * Use this factory when working with a single pool to avoid passing\n * decimals at every call site.\n *\n * @param config - Pool configuration with token decimals\n * @returns Pool-bound formatter functions\n *\n * @example\n * ```typescript\n * // Get pool data\n * const pool = await getPool({ client, poolAddress })\n *\n * // Create formatters bound to this pool\n * const fmt = createPoolFormatters({\n * decimals0: pool.token0Decimals,\n * decimals1: pool.token1Decimals,\n * })\n *\n * // Now use without passing decimals each time\n * const priceStr = fmt.tickToPriceScaled(position.currentTick, 4n)\n * const amount0Str = fmt.formatAmount0(collateral.assets, 4n)\n * const amount1Str = fmt.formatAmount1(premia.token1, 2n)\n *\n * // Parse user input\n * const rawAmount0 = fmt.parseAmount0(\"1.5\")\n * const rawAmount1 = fmt.parseAmount1(\"3000\")\n * ```\n */\nexport function createPoolFormatters(config: PoolFormatterConfig): PoolFormatters {\n const { decimals0, decimals1 } = config\n\n return {\n decimals0,\n decimals1,\n\n tickToPrice(tick: bigint): string {\n return tickToPrice(tick)\n },\n\n tickToPriceScaled(tick: bigint, precision: bigint): string {\n return tickToPriceDecimalScaled(tick, decimals0, decimals1, precision)\n },\n\n tickToInversePriceScaled(tick: bigint, precision: bigint): string {\n // Swap decimals for inverse price\n return tickToPriceDecimalScaled(tick, decimals1, decimals0, precision)\n },\n\n priceToTick(price: string): bigint {\n return priceToTick(price, decimals0, decimals1)\n },\n\n formatAmount0(amount: bigint, precision: bigint): string {\n return formatTokenAmount(amount, decimals0, precision)\n },\n\n formatAmount1(amount: bigint, precision: bigint): string {\n return formatTokenAmount(amount, decimals1, precision)\n },\n\n parseAmount0(amount: string): bigint {\n return parseTokenAmount(amount, decimals0)\n },\n\n parseAmount1(amount: string): bigint {\n return parseTokenAmount(amount, decimals1)\n },\n }\n}\n","/**\n * Token list integration utilities.\n *\n * Provides helpers for integrating with standard token lists\n * (e.g., Uniswap token list, CoinGecko token list).\n *\n * @module v2/formatters/tokenList\n */\n\nimport type { Address } from 'viem'\n\nconst TEN = 10n\n\nfunction formatRatio(numerator: bigint, denominator: bigint, precision: bigint): string {\n if (precision < 0n) {\n throw new RangeError('Precision must be non-negative')\n }\n\n const scale = TEN ** precision\n const scaled = (numerator * scale + denominator / 2n) / denominator\n const integerPart = scaled / scale\n const fractionalPart = scaled % scale\n\n if (precision === 0n) {\n return integerPart.toString()\n }\n\n return `${integerPart}.${fractionalPart.toString().padStart(Number(precision), '0')}`\n}\n\n/**\n * Generate a token list ID for external token list integration.\n *\n * Token lists use a standardized format: `chainId:address`\n * This is compatible with most token list standards.\n *\n * @param chainId - The chain ID\n * @param address - The token address\n * @returns Token list ID string\n *\n * @example\n * ```typescript\n * getTokenListId(1n, '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2')\n * // \"1:0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\"\n *\n * getTokenListId(11155111n, '0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14')\n * // \"11155111:0xfff9976782d46cc05630d1f6ebab18b2324d6b14\"\n * ```\n */\nexport function getTokenListId(chainId: bigint, address: Address): string {\n return `${chainId}:${address.toLowerCase()}`\n}\n\n/**\n * Parse a token list ID back to chain ID and address.\n *\n * @param tokenListId - The token list ID string\n * @returns Object with chainId and address\n *\n * @example\n * ```typescript\n * parseTokenListId(\"1:0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\")\n * // { chainId: 1n, address: \"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\" }\n * ```\n */\nexport function parseTokenListId(tokenListId: string): {\n chainId: bigint\n address: Address\n} {\n const [chainIdStr, address] = tokenListId.split(':')\n if (!chainIdStr || !address) {\n throw new Error(`Invalid token list ID: ${tokenListId}`)\n }\n return {\n chainId: BigInt(chainIdStr),\n address: address as Address,\n }\n}\n\n/**\n * Generate a pool ID string for display purposes.\n *\n * @param token0Symbol - Symbol of token0\n * @param token1Symbol - Symbol of token1\n * @param feeBps - Fee in basis points (e.g., 500n for 0.05%)\n * @returns Pool ID string\n *\n * @example\n * ```typescript\n * getPoolDisplayId('WETH', 'USDC', 500n)\n * // \"WETH/USDC 0.05%\"\n *\n * getPoolDisplayId('WBTC', 'ETH', 3000n)\n * // \"WBTC/ETH 0.30%\"\n * ```\n */\nexport function getPoolDisplayId(\n token0Symbol: string,\n token1Symbol: string,\n feeBps: bigint,\n): string {\n return `${token0Symbol}/${token1Symbol} ${formatFeeTier(feeBps)}`\n}\n\n/**\n * Format a fee tier for display.\n *\n * @param feeBps - Fee in basis points (e.g., 500n for 0.05%)\n * @returns Fee tier string\n *\n * @example\n * ```typescript\n * formatFeeTier(500n) // \"0.05%\"\n * formatFeeTier(3000n) // \"0.30%\"\n * formatFeeTier(10000n) // \"1.0%\"\n * ```\n */\nexport function formatFeeTier(feeBps: bigint): string {\n const precision = feeBps < 10000n ? 2n : 1n\n const feeStr = formatRatio(feeBps, 10_000n, precision)\n return `${feeStr}%`\n}\n","/**\n * General display formatters for UI components.\n *\n * These are utility formatters for common display needs like\n * addresses, timestamps, and durations.\n *\n * @module v2/formatters/display\n */\n\nimport { formatTokenAmount } from './amount'\n\nconst TEN = 10n\n\nfunction formatRatio(numerator: bigint, denominator: bigint, precision: bigint): string {\n if (precision < 0n) {\n throw new RangeError('Precision must be non-negative')\n }\n\n const scale = TEN ** precision\n const scaled = (numerator * scale + denominator / 2n) / denominator\n const integerPart = scaled / scale\n const fractionalPart = scaled % scale\n\n if (precision === 0n) {\n return integerPart.toString()\n }\n\n return `${integerPart}.${fractionalPart.toString().padStart(Number(precision), '0')}`\n}\n\n/**\n * Truncate an address for display.\n *\n * @param address - Full address\n * @param chars - Characters to show on each side (default: 4)\n * @returns Truncated address like \"0x1234...5678\"\n *\n * @example\n * ```typescript\n * truncateAddress('0x1234567890abcdef1234567890abcdef12345678')\n * // \"0x1234...5678\"\n *\n * truncateAddress('0x1234567890abcdef1234567890abcdef12345678', 6)\n * // \"0x123456...345678\"\n * ```\n */\nexport function truncateAddress(address: string, chars = 4): string {\n const charsBig = BigInt(chars)\n const minLength = charsBig * 2n + 4n\n if (BigInt(address.length) <= minLength) return address\n return `${address.slice(0, Number(charsBig + 2n))}...${address.slice(-Number(charsBig))}`\n}\n\n/**\n * Format a Unix timestamp as an ISO date string (YYYY-MM-DD).\n *\n * @param timestamp - Unix timestamp in seconds\n * @returns ISO date string\n *\n * @example\n * ```typescript\n * formatTimestamp(1700000000n) // \"2023-11-14\"\n * ```\n */\nexport function formatTimestamp(timestamp: bigint): string {\n const ms = timestamp * 1000n\n return new Date(Number(ms)).toISOString().split('T')[0]\n}\n\n/**\n * Format a Unix timestamp as an ISO datetime string.\n *\n * @param timestamp - Unix timestamp in seconds\n * @returns ISO datetime string\n *\n * @example\n * ```typescript\n * formatDatetime(1700000000n) // \"2023-11-14T22:13:20.000Z\"\n * ```\n */\nexport function formatDatetime(timestamp: bigint): string {\n const ms = timestamp * 1000n\n return new Date(Number(ms)).toISOString()\n}\n\n/**\n * Format a Unix timestamp as a locale-aware date string.\n *\n * @param timestamp - Unix timestamp in seconds\n * @param locale - Locale string (default: system locale)\n * @param options - Intl.DateTimeFormat options\n * @returns Formatted date string\n *\n * @example\n * ```typescript\n * formatTimestampLocale(1700000000n)\n * // \"11/14/2023\" (US locale)\n *\n * formatTimestampLocale(1700000000n, 'de-DE')\n * // \"14.11.2023\" (German locale)\n * ```\n */\nexport function formatTimestampLocale(\n timestamp: bigint,\n locale?: string,\n options?: Intl.DateTimeFormatOptions,\n): string {\n const ms = timestamp * 1000n\n return new Date(Number(ms)).toLocaleDateString(locale, options)\n}\n\n/**\n * Format a duration in milliseconds as a human-readable string.\n *\n * @param ms - Duration in milliseconds\n * @returns Formatted duration string\n *\n * @example\n * ```typescript\n * formatDuration(1500n) // \"1.5s\"\n * formatDuration(150n) // \"150ms\"\n * formatDuration(90000n) // \"1m 30s\"\n * formatDuration(3661000n) // \"1h 1m\"\n * ```\n */\nexport function formatDuration(ms: bigint): string {\n const isNegative = ms < 0n\n const absMs = isNegative ? -ms : ms\n const sign = isNegative ? '-' : ''\n\n if (absMs < 1000n) {\n return `${sign}${absMs}ms`\n }\n\n if (absMs < 60000n) {\n const tenthsTotal = (absMs + 50n) / 100n\n const seconds = tenthsTotal / 10n\n const tenths = tenthsTotal % 10n\n return `${sign}${seconds}.${tenths}s`\n }\n\n if (absMs < 3600000n) {\n const minutes = absMs / 60000n\n const seconds = ((absMs % 60000n) + 500n) / 1000n\n return seconds > 0n ? `${sign}${minutes}m ${seconds}s` : `${sign}${minutes}m`\n }\n\n const hours = absMs / 3600000n\n const minutes = ((absMs % 3600000n) + 30000n) / 60000n\n return minutes > 0n ? `${sign}${hours}h ${minutes}m` : `${sign}${hours}h`\n}\n\n/**\n * Format a duration in seconds as a human-readable string.\n *\n * @param seconds - Duration in seconds\n * @returns Formatted duration string\n */\nexport function formatDurationSeconds(seconds: bigint): string {\n return formatDuration(seconds * 1000n)\n}\n\n/**\n * Format a block number for display.\n *\n * @param blockNumber - The block number\n * @returns Formatted block number with commas\n *\n * @example\n * ```typescript\n * formatBlockNumber(18000000n) // \"18,000,000\"\n * ```\n */\nexport function formatBlockNumber(blockNumber: bigint): string {\n return blockNumber.toLocaleString()\n}\n\n/**\n * Format a gas amount for display.\n *\n * @param gas - Gas units\n * @returns Formatted gas string\n */\nexport function formatGas(gas: bigint): string {\n return gas.toLocaleString()\n}\n\n/**\n * Format a transaction hash for display (truncated).\n *\n * @param hash - Full transaction hash\n * @param chars - Characters to show on each side (default: 6)\n * @returns Truncated hash like \"0x123456...abcdef\"\n *\n * @example\n * ```typescript\n * formatTxHash('0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef')\n * // \"0x123456...abcdef\"\n * ```\n */\nexport function formatTxHash(hash: string, chars = 6): string {\n const charsBig = BigInt(chars)\n const minLength = charsBig * 2n + 4n\n if (BigInt(hash.length) <= minLength) return hash\n return `${hash.slice(0, Number(charsBig + 2n))}...${hash.slice(-Number(charsBig))}`\n}\n\nfunction formatHex(value: bigint): string {\n return `0x${value.toString(16)}`\n}\n\n/**\n * Format a TokenId as a hex string.\n *\n * @param tokenId - TokenId value\n * @returns Hex string representation\n */\nexport function formatTokenIdHex(tokenId: bigint): string {\n return formatHex(tokenId)\n}\n\n/**\n * Format a PoolId as a hex string.\n *\n * @param poolId - PoolId value\n * @returns Hex string representation\n */\nexport function formatPoolIdHex(poolId: bigint): string {\n return formatHex(poolId)\n}\n\n/**\n * Format a TokenId as a shortened hex string.\n *\n * @param tokenId - TokenId value\n * @param chars - Characters to show on each side (default: 4)\n * @returns Truncated hex string like \"0x1234...abcd\"\n */\nexport function formatTokenIdShort(tokenId: bigint, chars = 4): string {\n const hex = formatHex(tokenId)\n const charsBig = BigInt(chars)\n const minLength = charsBig * 2n + 4n\n if (BigInt(hex.length) <= minLength) return hex\n return `${hex.slice(0, Number(charsBig + 2n))}...${hex.slice(-Number(charsBig))}`\n}\n\n/**\n * Format a large number with K/M/B suffixes.\n *\n * @param value - The numeric value\n * @param precision - Number of decimal places (default: 1n)\n * @returns Formatted string with suffix\n *\n * @example\n * ```typescript\n * formatCompact(1234n) // \"1.2K\"\n * formatCompact(1234567n) // \"1.2M\"\n * formatCompact(1234567890n) // \"1.2B\"\n * formatCompact(999n) // \"999\"\n * ```\n */\nexport function formatCompact(value: bigint, precision: bigint = 1n): string {\n const isNegative = value < 0n\n const absValue = isNegative ? -value : value\n\n let formatted: string\n\n if (absValue < 1000n) {\n formatted = absValue.toString()\n } else if (absValue < 1_000_000n) {\n formatted = `${formatRatio(absValue, 1000n, precision)}K`\n } else if (absValue < 1_000_000_000n) {\n formatted = `${formatRatio(absValue, 1_000_000n, precision)}M`\n } else {\n formatted = `${formatRatio(absValue, 1_000_000_000n, precision)}B`\n }\n\n return isNegative ? `-${formatted}` : formatted\n}\n\n/**\n * Format a wei amount as a display string.\n *\n * @param wei - Amount in wei\n * @returns Formatted string with unit\n */\nexport function formatWei(wei: bigint): string {\n return `${wei} wei`\n}\n\n/**\n * Format a wei amount as gwei.\n *\n * @param wei - Amount in wei\n * @param precision - Number of decimal places to display\n * @returns Formatted string with unit\n */\nexport function formatGwei(wei: bigint, precision: bigint): string {\n return `${formatTokenAmount(wei, 9n, precision)} gwei`\n}\n","/**\n * Account greeks calculation using stored position data.\n *\n * This module provides functions to calculate account-level greeks\n * using position data stored by syncPositions(). Only the current tick\n * is fetched via RPC - all other data comes from storage.\n *\n * @module v2/reads/accountGreeks\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport { PanopticError, StorageDataNotFoundError } from '../errors'\nimport { tickToSqrtPriceX96 } from '../formatters'\nimport {\n type PositionGreeksResult,\n calculatePositionDelta,\n calculatePositionGamma,\n calculatePositionValue,\n} from '../greeks'\nimport type { StorageAdapter } from '../storage'\nimport { getPoolMetaKey, getPositionMetaKey, getPositionsKey, jsonSerializer } from '../storage'\nimport type { BlockMeta, StoredPoolMeta, StoredPositionData } from '../types'\nimport { type CollateralAddresses, getAccountCollateral } from './account'\n\nconst Q192 = 1n << 192n\n\n/**\n * Parameters for getAccountGreeks.\n */\nexport interface GetAccountGreeksParams {\n /** viem PublicClient (only used to fetch current tick) */\n client: PublicClient\n /** Chain ID */\n chainId: bigint\n /** Pool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** Storage adapter containing synced position data */\n storage: StorageAdapter\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /**\n * When true, include collateral token balance as linear delta.\n * Requires `assetIndex` to specify which token is the asset.\n */\n includeCollateral?: boolean\n /**\n * Which token is the \"asset\" (the directional exposure token).\n * 0n = token0 is asset, 1n = token1 is asset.\n * Required when `includeCollateral` is true.\n */\n assetIndex?: 0n | 1n\n /** Optional pre-fetched collateral addresses (used when includeCollateral is true) */\n collateralAddresses?: CollateralAddresses\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Result of getAccountGreeks.\n *\n * Returns both granular breakdown (positions vs collateral) and computed totals.\n * - `positionsDelta` / `positionsValue`: Options exposure only\n * - `collateralDelta` / `collateralValue`: Collateral in the pool\n * - `totalDelta` / `totalValue`: Sum of both (use for net portfolio greeks)\n *\n * All values are in natural token smallest units (no WAD scaling).\n * - Value/gamma: numeraire token smallest units\n * - Delta: asset token smallest units\n */\nexport interface AccountGreeksResult {\n // --- Position greeks (options only) ---\n /** Sum of position values (numeraire smallest units, options only) */\n positionsValue: bigint\n /** Sum of position deltas (asset smallest units, options only) */\n positionsDelta: bigint\n /** Sum of position gammas (numeraire smallest units) */\n positionsGamma: bigint\n\n // --- Collateral greeks ---\n /**\n * Value of collateral holdings: asset balance × price + numeraire balance.\n * In numeraire smallest units. 0n when includeCollateral is not set.\n */\n collateralValue: bigint\n /**\n * Linear delta from the asset token's collateral balance (asset smallest units).\n * 0n when includeCollateral is not set.\n */\n collateralDelta: bigint\n\n // --- Computed totals ---\n /** Total portfolio value = positionsValue + collateralValue */\n totalValue: bigint\n /** Total portfolio delta = positionsDelta + collateralDelta */\n totalDelta: bigint\n\n // --- Metadata ---\n /** Number of positions included */\n positionCount: bigint\n /** Per-position greeks breakdown */\n positions: Array<{\n tokenId: bigint\n greeks: PositionGreeksResult\n }>\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Calculate account-level greeks using stored position data.\n *\n * This function reads position data from storage (populated by syncPositions)\n * and calculates greeks client-side. Only the current tick is fetched via RPC.\n *\n * @param params - The parameters\n * @returns Account greeks with per-position breakdown\n * @throws StorageDataNotFoundError if required data is not in storage\n * @throws PanopticError if includeCollateral is true but assetIndex is not provided\n *\n * @example\n * ```typescript\n * // First sync positions to populate storage\n * await syncPositions({ client, chainId, poolAddress, account, storage })\n *\n * // Then calculate greeks from stored data\n * const greeks = await getAccountGreeks({\n * client,\n * chainId,\n * poolAddress,\n * account,\n * storage,\n * })\n *\n * console.log('Positions delta:', greeks.positionsDelta)\n * ```\n */\nexport async function getAccountGreeks(\n params: GetAccountGreeksParams,\n): Promise<AccountGreeksResult> {\n const {\n client,\n chainId,\n poolAddress,\n account,\n storage,\n blockNumber,\n includeCollateral,\n assetIndex,\n collateralAddresses,\n } = params\n\n // 0. Validate: includeCollateral requires assetIndex\n if (includeCollateral && assetIndex === undefined) {\n throw new PanopticError('assetIndex is required when includeCollateral is true')\n }\n\n // 1. Read pool metadata from storage\n const poolMetaKey = getPoolMetaKey(chainId, poolAddress)\n const poolMetaRaw = await storage.get(poolMetaKey)\n if (!poolMetaRaw) {\n throw new StorageDataNotFoundError('poolMeta', poolMetaKey)\n }\n const poolMeta = jsonSerializer.parse(poolMetaRaw) as StoredPoolMeta\n\n // 2. Read position IDs from storage\n const positionsKey = getPositionsKey(chainId, poolAddress, account)\n const positionsRaw = await storage.get(positionsKey)\n if (!positionsRaw) {\n throw new StorageDataNotFoundError('positions', positionsKey)\n }\n const positionIds = jsonSerializer.parse(positionsRaw) as bigint[]\n\n // 3. If no positions and no collateral requested, return zeros\n if (positionIds.length === 0 && !includeCollateral) {\n const targetBlock = blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n const _meta = params._meta ?? (await getBlockMeta({ client, blockNumber: targetBlock }))\n\n return {\n positionsValue: 0n,\n positionsDelta: 0n,\n positionsGamma: 0n,\n collateralValue: 0n,\n collateralDelta: 0n,\n totalValue: 0n,\n totalDelta: 0n,\n positionCount: 0n,\n positions: [],\n _meta,\n }\n }\n\n // 4. Read position metadata for each position from storage\n const storedPositions = await Promise.all(\n positionIds.map(async (tokenId) => {\n const posMetaKey = getPositionMetaKey(chainId, poolAddress, tokenId)\n const posMetaRaw = await storage.get(posMetaKey)\n if (!posMetaRaw) {\n throw new StorageDataNotFoundError('positionMeta', posMetaKey)\n }\n return jsonSerializer.parse(posMetaRaw) as StoredPositionData\n }),\n )\n\n // 5. Fetch current tick (+ collateral if requested) from RPC\n const targetBlock = blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n const [currentTick, _meta, collateral] = await Promise.all([\n client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n blockNumber: targetBlock,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlock }),\n includeCollateral\n ? getAccountCollateral({\n client,\n poolAddress,\n account,\n blockNumber: targetBlock,\n collateralAddresses,\n _meta: params._meta,\n })\n : undefined,\n ])\n\n // 6. Calculate greeks for each position\n let positionsValue = 0n\n let positionsDelta = 0n\n let positionsGamma = 0n\n const positions: AccountGreeksResult['positions'] = []\n\n for (const pos of storedPositions) {\n const input = {\n legs: pos.legs,\n currentTick: BigInt(currentTick),\n mintTick: pos.tickAtMint,\n positionSize: pos.positionSize,\n poolTickSpacing: poolMeta.tickSpacing,\n assetIndex,\n }\n\n const value = calculatePositionValue(input)\n const delta = calculatePositionDelta(input)\n const gamma = calculatePositionGamma(input)\n\n positionsValue += value\n positionsDelta += delta\n positionsGamma += gamma\n\n positions.push({\n tokenId: pos.tokenId,\n greeks: { value, delta, gamma },\n })\n }\n\n // 7. Collateral value and delta\n let collateralValue = 0n\n let collateralDelta = 0n\n\n if (collateral) {\n const isAssetToken0 = assetIndex === 0n\n const assetBal = isAssetToken0 ? collateral.token0.assets : collateral.token1.assets\n const otherBal = isAssetToken0 ? collateral.token1.assets : collateral.token0.assets\n const sqrtPriceX96 = tickToSqrtPriceX96(BigInt(currentTick))\n\n // assetBal * price converts asset smallest units to numeraire smallest units\n // otherBal is already in numeraire smallest units\n if (isAssetToken0) {\n // price = token1/token0 = sqrtPriceX96² / 2¹⁹²\n collateralValue = (assetBal * sqrtPriceX96 * sqrtPriceX96) / Q192 + otherBal\n } else {\n // price = token0/token1 = 2¹⁹² / sqrtPriceX96²\n collateralValue = (assetBal * Q192) / (sqrtPriceX96 * sqrtPriceX96) + otherBal\n }\n collateralDelta = assetBal\n }\n\n return {\n positionsValue,\n positionsDelta,\n positionsGamma,\n collateralValue,\n collateralDelta,\n totalValue: positionsValue + collateralValue,\n totalDelta: positionsDelta + collateralDelta,\n positionCount: BigInt(positionIds.length),\n positions,\n _meta,\n }\n}\n\n/**\n * Parameters for calculateAccountGreeksPure.\n */\nexport interface CalculateAccountGreeksPureParams {\n /** Stored position data */\n positions: StoredPositionData[]\n /** Pool tick spacing */\n tickSpacing: bigint\n /** Ticks at which to evaluate greeks (one or more) */\n atTicks: bigint[]\n /**\n * Collateral balances [token0Assets, token1Assets] in token smallest units.\n * When provided, both tokens are included in totalValue and the\n * asset token's balance is added to totalDelta.\n */\n collateralAssets?: [bigint, bigint]\n /** Override for leg.asset on all legs (0n = token0 is asset, 1n = token1). Defaults to 0n. */\n assetIndex?: bigint\n}\n\n/**\n * Result of calculateAccountGreeksPure.\n *\n * Arrays are parallel to the input `atTicks` — index i corresponds to `atTicks[i]`.\n * Totals include both position greeks and collateral contributions.\n * All values in natural token smallest units (no WAD scaling).\n */\nexport interface AccountGreeksCurveResult {\n /** Total value at each tick: positions + collateral (numeraire smallest units) */\n totalValue: bigint[]\n /** Total delta at each tick: positions + asset collateral (asset smallest units) */\n totalDelta: bigint[]\n /** Total gamma at each tick: positions only (numeraire smallest units, collateral has zero gamma) */\n totalGamma: bigint[]\n /** Number of positions included */\n positionCount: bigint\n /** Per-position greeks curves (arrays parallel to atTicks) */\n positions: Array<{\n tokenId: bigint\n greeks: {\n value: bigint[]\n delta: bigint[]\n gamma: bigint[]\n }\n }>\n}\n\n/**\n * Pure function to calculate portfolio greeks across a range of ticks.\n *\n * No RPC calls — useful for plotting value/delta/gamma curves on a chart.\n * All returned arrays are parallel to the input `atTicks`.\n *\n * When `collateralAssets` is provided, both token balances are included in\n * `totalValue` (asset balance × price + numeraire balance) and\n * the asset token's balance is added to `totalDelta`.\n *\n * @param params - The parameters\n * @returns Portfolio greeks curves and per-position breakdown\n */\nexport function calculateAccountGreeksPure(\n params: CalculateAccountGreeksPureParams,\n): AccountGreeksCurveResult {\n const { positions, tickSpacing, atTicks, collateralAssets, assetIndex } = params\n const n = atTicks.length\n const isAssetToken0 = assetIndex === undefined || assetIndex === 0n\n\n // Collateral balances (already in token smallest units)\n const assetBal = collateralAssets ? collateralAssets[isAssetToken0 ? 0 : 1] : 0n\n const otherBal = collateralAssets ? collateralAssets[isAssetToken0 ? 1 : 0] : 0n\n\n if (positions.length === 0) {\n const totalValue: bigint[] = []\n const totalDelta: bigint[] = []\n for (let i = 0; i < n; i++) {\n const sqrtPriceX96 = tickToSqrtPriceX96(atTicks[i])\n const assetValueInNumeraire = isAssetToken0\n ? (assetBal * sqrtPriceX96 * sqrtPriceX96) / Q192\n : (assetBal * Q192) / (sqrtPriceX96 * sqrtPriceX96)\n totalValue.push(assetValueInNumeraire + otherBal)\n totalDelta.push(assetBal)\n }\n return {\n totalValue,\n totalDelta,\n totalGamma: new Array<bigint>(n).fill(0n),\n positionCount: 0n,\n positions: [],\n }\n }\n\n const totalValue = new Array<bigint>(n).fill(0n)\n const totalDelta = new Array<bigint>(n).fill(0n)\n const totalGamma = new Array<bigint>(n).fill(0n)\n const positionResults: AccountGreeksCurveResult['positions'] = []\n\n for (const pos of positions) {\n const posValues: bigint[] = []\n const posDeltas: bigint[] = []\n const posGammas: bigint[] = []\n\n for (let i = 0; i < n; i++) {\n const input = {\n legs: pos.legs,\n currentTick: atTicks[i],\n mintTick: pos.tickAtMint,\n positionSize: pos.positionSize,\n poolTickSpacing: tickSpacing,\n assetIndex,\n }\n\n const v = calculatePositionValue(input)\n const d = calculatePositionDelta(input)\n const g = calculatePositionGamma(input)\n\n posValues.push(v)\n posDeltas.push(d)\n posGammas.push(g)\n\n totalValue[i] += v\n totalDelta[i] += d\n totalGamma[i] += g\n }\n\n positionResults.push({\n tokenId: pos.tokenId,\n greeks: { value: posValues, delta: posDeltas, gamma: posGammas },\n })\n }\n\n // Add collateral contributions at each tick\n for (let i = 0; i < n; i++) {\n const sqrtPriceX96 = tickToSqrtPriceX96(atTicks[i])\n const assetValueInNumeraire = isAssetToken0\n ? (assetBal * sqrtPriceX96 * sqrtPriceX96) / Q192\n : (assetBal * Q192) / (sqrtPriceX96 * sqrtPriceX96)\n totalValue[i] += assetValueInNumeraire + otherBal\n totalDelta[i] += assetBal\n }\n\n return {\n totalValue,\n totalDelta,\n totalGamma,\n positionCount: BigInt(positions.length),\n positions: positionResults,\n }\n}\n","/**\n * Margin buffer and distance-to-liquidation convenience function.\n *\n * Sources current and required margin directly from\n * `PanopticPool.getFullPositionsData` + `CollateralTracker.assetsOf`,\n * rather than `PanopticQuery.checkCollateral`.\n *\n * Why: `checkCollateral` returns a `currentMargin` already netted of the\n * borrowing obligation of width=0 short (\"loan\") tokenIds, and a\n * `requiredMargin` that does NOT include the loan's collateral requirement.\n * That makes buying-power usage read 0% for accounts whose collateral\n * comes mostly from a loan, and double-subtracts the loan from Net Liq\n * when downstream callers add the position MtM (which already values the\n * loan at `-notional`).\n *\n * `getFullPositionsData.collateralRequirements[]` attributes the loan as\n * a margin requirement (the accurate primitive), and `assetsOf` returns\n * the gross collateral (deposits + borrowed shares) — pairing them yields\n * a consistent gross-collateral / gross-requirement view.\n *\n * @module v2/reads/margin\n */\n\nimport type { Address, PublicClient } from 'viem'\nimport { decodeFunctionResult, encodeFunctionData } from 'viem'\n\nimport { collateralTrackerV2Abi, panopticPoolV2Abi } from '../../../generated'\nimport { panopticQueryAbi } from '../abis/panopticQuery'\nimport { tickToSqrtPriceX96 } from '../formatters/tick'\nimport type { BlockMeta } from '../types'\nimport { decodeLeftRightUnsigned } from '../writes/utils'\nimport { type MintBufferRatio, mintableAfterBuffer } from './mintBuffer'\nimport { type MulticallBlockCall, readBlockAndAggregate, requireReturnData } from './multicallBlock'\n\n// Sentinel ticks used by PanopticQuery to indicate \"no liquidation at this boundary\"\nconst MIN_TICK = -887272n\nconst MAX_TICK = 887272n\n\nconst FP96 = 1n << 96n\nconst Q128 = 1n << 128n\n\n/** Cap for a usage ratio with no collateral behind it. */\nconst MAX_USAGE_BPS = 1_000_000n\n\nconst bigintMax = (a: bigint, b: bigint): bigint => (a > b ? a : b)\nconst bigintMin = (a: bigint, b: bigint): bigint => (a < b ? a : b)\n\n// `RiskEngine.BP_DECREASE_BUFFER / DECIMALS` — the extra margin the solvency\n// check demands at mint (and on collateral withdrawal), above the maintenance\n// requirement that governs liquidation. It lives in `./mintBuffer` so the SDK\n// and every UI surface share one implementation: applied per token, rounding\n// up, before any price conversion.\n\n/**\n * Convert a token0 amount to its token1-equivalent at the given sqrtPriceX96.\n *\n * Matches the on-chain `PanopticMath.convert0to1` truncation, with an\n * overflow-safe branch when `sqrtPriceX96^2` would not fit in uint256.\n */\nfunction convert0to1(amount: bigint, sqrtPriceX96: bigint): bigint {\n if (sqrtPriceX96 < Q128) {\n return (amount * sqrtPriceX96 * sqrtPriceX96) >> 192n\n }\n // amount * (sqrtPriceX96 * sqrtPriceX96 >> 64n) >> 128n\n const sp2Hi = (sqrtPriceX96 * sqrtPriceX96) >> 64n\n return (amount * sp2Hi) >> 128n\n}\n\n/**\n * Convert a token1 amount to its token0-equivalent at the given sqrtPriceX96.\n */\nfunction convert1to0(amount: bigint, sqrtPriceX96: bigint): bigint {\n if (sqrtPriceX96 < Q128) {\n const denom = sqrtPriceX96 * sqrtPriceX96\n return (amount * (1n << 192n)) / denom\n }\n const sp2Hi = (sqrtPriceX96 * sqrtPriceX96) >> 64n\n return (amount * (1n << 128n)) / sp2Hi\n}\n\n/**\n * Parameters for {@link getMarginBuffer}.\n */\nexport interface GetMarginBufferParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** TokenIds of open positions (loan/credit width=0 legs included) */\n tokenIds: bigint[]\n /** PanopticQuery address (required for liquidation prices) */\n queryAddress: Address\n /**\n * Optional pre-fetched collateral tracker addresses (saves an RPC).\n * If omitted, they are fetched from the pool.\n */\n collateralAddresses?: { collateralToken0: Address; collateralToken1: Address }\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n /** Optional live mint buffer returned by getRiskParameters. */\n mintBuffer?: MintBufferRatio\n}\n\n/**\n * Margin buffer result with distance-to-liquidation.\n *\n * **Denomination**: Both slots are populated with the account total\n * cross-converted into a single token denomination so they can be\n * compared directly.\n *\n * - `currentMargin0` / `requiredMargin0` / `buffer0` are denominated in **token0**.\n * - `currentMargin1` / `requiredMargin1` / `buffer1` are denominated in **token1**.\n *\n * `denominatedInToken` indicates which of the two pairs is \"preferred\":\n * 0 when `currentTick < 0`, 1 otherwise — matching the historical\n * `checkCollateral` convention so downstream consumers keep working\n * without changes.\n */\nexport interface MarginBuffer {\n /** Excess margin in token0 units (positive = safe, negative = shortfall) */\n buffer0: bigint\n /** Excess margin in token1 units (positive = safe, negative = shortfall) */\n buffer1: bigint\n /** Buffer as percentage of required margin in bps (slot 0). null if no requirement. */\n bufferPercent0: bigint | null\n /** Buffer as percentage of required margin in bps (slot 1). null if no requirement. */\n bufferPercent1: bigint | null\n /** Current (gross) account collateral, denominated in token0 */\n currentMargin0: bigint\n /** Current (gross) account collateral, denominated in token1 */\n currentMargin1: bigint\n /**\n * Sum of per-position collateral requirements from\n * `getFullPositionsData.collateralRequirements[]`, denominated in token0.\n * Loans/credits (width=0) contribute correctly.\n */\n requiredMargin0: bigint\n /** Same, denominated in token1 */\n requiredMargin1: bigint\n /**\n * Which token the \"preferred\" margin values are denominated in.\n * 0 = token0 (when currentTick < 0), 1 = token1 (when currentTick >= 0).\n */\n denominatedInToken: 0 | 1\n /** Tick distance to nearest liquidation boundary (null if no liquidation boundaries) */\n liquidationDistance: bigint | null\n /** Lower liquidation tick (null if safe at MIN_TICK) */\n lowerLiquidationTick: bigint | null\n /** Upper liquidation tick (null if safe at MAX_TICK) */\n upperLiquidationTick: bigint | null\n /**\n * Collateral usage against the constraint that actually liquidates, in bps\n * (10000 = at the liquidation threshold). Null when the account holds no\n * positions.\n *\n * NOT `requiredMargin / currentMargin`. That ratio pools both collateral\n * tokens into one number, which silently assumes cross-collateral is credited\n * at 100%. It is only credited at `RiskEngine.crossBufferRatio(utilization,\n * CROSS_BUFFER_n)`, which decays linearly from the configured buffer to ZERO\n * between 90% and 95% pool utilization. Measured on mainnet with\n * CROSS_BUFFER = 100% and the token0 tracker at 91.98% utilization, only\n * 60.4% of the token0 surplus counted toward the token1 requirement — the\n * pooled ratio read 40% while this one read ~90% and liquidation was 8.7%\n * away.\n *\n * Sourced from `PanopticQuery.checkCollateral` at the current tick, which\n * applies the live cross-buffer, and reported for whichever token side is\n * tighter. Solvency requires both to hold.\n */\n crossMarginUsageBps: bigint | null\n /** Usage of the token0 side alone, in bps. Null when no positions. */\n usageBps0: bigint | null\n /** Usage of the token1 side alone, in bps. Null when no positions. */\n usageBps1: bigint | null\n /**\n * Collateral still deployable before the mint solvency check would fail,\n * in `denominatedInToken` units. Null when the account holds no positions.\n *\n * The tighter of `balance - required * BP_DECREASE_BUFFER` across the two\n * token sides, from `checkCollateral` at the current tick. NOT\n * `currentMargin - requiredMargin * buffer`, which pools both collateral\n * tokens and so credits cross-collateral at 100% regardless of the live\n * `crossBufferRatio`. On a mainnet account that pooled figure read ~24,000\n * USDC of headroom while the binding side had ~890 — and a mint requiring\n * ~2,700 USDC duly reverted with AccountInsolvent.\n */\n mintableMarginBinding: bigint | null\n /** Current tick */\n currentTick: bigint\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Get margin buffer and distance-to-liquidation for an account.\n *\n * Reads, all pinned to the same block:\n * - `getCurrentTick` (sequencing dependency for sqrtPrice conversion)\n * - `getFullPositionsData(account, true, tokenIds)` → collateralRequirements\n * - `CollateralTracker.assetsOf(account)` on both trackers → gross collateral\n * - `PanopticQuery.getLiquidationPrices(...)` → liquidation boundaries\n *\n * @param params - The parameters\n * @returns Margin buffer with liquidation distance and block metadata\n */\nexport async function getMarginBuffer(params: GetMarginBufferParams): Promise<MarginBuffer> {\n const { client, poolAddress, account, tokenIds, queryAddress, blockNumber, mintBuffer } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Resolve collateral tracker addresses (immutable; cache-friendly).\n let collateralToken0: Address\n let collateralToken1: Address\n if (params.collateralAddresses) {\n collateralToken0 = params.collateralAddresses.collateralToken0\n collateralToken1 = params.collateralAddresses.collateralToken1\n } else {\n const addrs = await client.multicall({\n contracts: [\n { address: poolAddress, abi: panopticPoolV2Abi, functionName: 'collateralToken0' },\n { address: poolAddress, abi: panopticPoolV2Abi, functionName: 'collateralToken1' },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n })\n collateralToken0 = addrs[0]\n collateralToken1 = addrs[1]\n }\n\n const hasPositions = tokenIds.length > 0\n const calls: MulticallBlockCall[] = [\n {\n target: poolAddress,\n callData: encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n }),\n },\n {\n target: collateralToken0,\n callData: encodeFunctionData({\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n args: [account],\n }),\n },\n {\n target: collateralToken1,\n callData: encodeFunctionData({\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n args: [account],\n }),\n },\n ]\n\n const positionDataIndex = hasPositions ? calls.length : null\n if (positionDataIndex !== null) {\n calls.push({\n target: poolAddress,\n callData: encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [account, true, tokenIds],\n }),\n })\n }\n\n const liqPricesIndex = hasPositions ? calls.length : null\n if (liqPricesIndex !== null) {\n calls.push({\n target: queryAddress,\n callData: encodeFunctionData({\n abi: panopticQueryAbi,\n functionName: 'getLiquidationPrices',\n args: [poolAddress, account, tokenIds],\n }),\n })\n }\n\n // 3-arg overload: evaluates at (currentTick, fastOracleTick, slowOracleTick,\n // latestObservation) so it needs no tick input and fits this same multicall.\n // We read index 0 (currentTick) to stay consistent with the liquidation price\n // and the risk chart, which are also anchored there.\n const checkCollateralIndex = hasPositions ? calls.length : null\n if (checkCollateralIndex !== null) {\n calls.push({\n target: queryAddress,\n callData: encodeFunctionData({\n abi: panopticQueryAbi,\n functionName: 'checkCollateral',\n args: [poolAddress, account, tokenIds],\n }),\n })\n }\n\n const { _meta, results } = await readBlockAndAggregate({\n client,\n calls,\n blockNumber: targetBlockNumber,\n })\n\n const currentTickResult = decodeFunctionResult({\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n data: requireReturnData(results, 0, 'PanopticPool.getCurrentTick'),\n })\n const currentTick = BigInt(currentTickResult)\n const assets0 = decodeFunctionResult({\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n data: requireReturnData(results, 1, 'CollateralTracker.assetsOf token0'),\n })\n const assets1 = decodeFunctionResult({\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n data: requireReturnData(results, 2, 'CollateralTracker.assetsOf token1'),\n })\n const positionDataResult =\n positionDataIndex === null\n ? null\n : (decodeFunctionResult({\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n data: requireReturnData(results, positionDataIndex, 'PanopticPool.getFullPositionsData'),\n }) as readonly [bigint, bigint, readonly bigint[], readonly bigint[], readonly bigint[]])\n const liqPricesResult =\n liqPricesIndex === null\n ? null\n : (decodeFunctionResult({\n abi: panopticQueryAbi,\n functionName: 'getLiquidationPrices',\n data: requireReturnData(results, liqPricesIndex, 'PanopticQuery.getLiquidationPrices'),\n }) as readonly [number, number])\n\n const checkCollateralResult =\n checkCollateralIndex === null\n ? null\n : (decodeFunctionResult({\n abi: panopticQueryAbi,\n functionName: 'checkCollateral',\n data: requireReturnData(results, checkCollateralIndex, 'PanopticQuery.checkCollateral'),\n }) as readonly [readonly bigint[], readonly bigint[], readonly bigint[], readonly bigint[]])\n\n // Usage against the binding constraint, at the current tick (index 0).\n // checkCollateral has already applied the live cross-buffer, so this reflects\n // how much of the surplus in one token genuinely counts toward the other.\n let usageBps0: bigint | null = null\n let usageBps1: bigint | null = null\n let crossMarginUsageBps: bigint | null = null\n let mintableMarginBinding: bigint | null = null\n if (checkCollateralResult) {\n const [balances0, requireds0, balances1, requireds1] = checkCollateralResult\n const ratio = (required: bigint | undefined, balance: bigint | undefined): bigint | null => {\n if (required === undefined || balance === undefined) return null\n // No balance but a requirement is maximally used, not undefined.\n if (balance === 0n) return required > 0n ? MAX_USAGE_BPS : 0n\n return (required * 10_000n) / balance\n }\n usageBps0 = ratio(requireds0[0], balances0[0])\n usageBps1 = ratio(requireds1[0], balances1[0])\n if (usageBps0 !== null || usageBps1 !== null) {\n crossMarginUsageBps =\n usageBps0 === null\n ? usageBps1\n : usageBps1 === null\n ? usageBps0\n : bigintMax(usageBps0, usageBps1)\n }\n\n // Collateral still deployable before the mint solvency check would fail.\n // Per side: balance - required * mintBuffer, then the tighter of the two,\n // because the mint must satisfy BOTH. Both sides are already in\n // `denominatedInToken` units (checkCollateral branches on the same\n // sqrtPriceX96 < FP96 test), so the min is well defined.\n const mintable = (balance: bigint | undefined, required: bigint | undefined): bigint | null =>\n balance === undefined || required === undefined\n ? null\n : mintableAfterBuffer(balance, required, mintBuffer)\n const mintable0 = mintable(balances0[0], requireds0[0])\n const mintable1 = mintable(balances1[0], requireds1[0])\n if (mintable0 !== null || mintable1 !== null) {\n mintableMarginBinding =\n mintable0 === null\n ? mintable1\n : mintable1 === null\n ? mintable0\n : bigintMin(mintable0, mintable1)\n }\n }\n\n // Sum collateral requirements across all positions, per token.\n let required0Native = 0n\n let required1Native = 0n\n if (positionDataResult) {\n const collateralRequirements = positionDataResult[3]\n for (const packed of collateralRequirements) {\n const decoded = decodeLeftRightUnsigned(packed)\n required0Native += decoded.right // token0\n required1Native += decoded.left // token1\n }\n }\n\n // Cross-convert into a single denomination at current tick.\n // The conversion mirrors PanopticQuery.checkCollateral's effective-balance\n // shape so downstream callers keep their existing per-slot interpretation.\n const sqrtPriceX96 = tickToSqrtPriceX96(currentTick)\n const denominatedInToken: 0 | 1 = sqrtPriceX96 < FP96 ? 0 : 1\n\n // Token0-denominated totals\n const currentMargin0 = assets0 + convert1to0(assets1, sqrtPriceX96)\n const requiredMargin0 = required0Native + convert1to0(required1Native, sqrtPriceX96)\n // Token1-denominated totals\n const currentMargin1 = assets1 + convert0to1(assets0, sqrtPriceX96)\n const requiredMargin1 = required1Native + convert0to1(required0Native, sqrtPriceX96)\n\n const buffer0 = currentMargin0 - requiredMargin0\n const buffer1 = currentMargin1 - requiredMargin1\n const bufferPercent0 = requiredMargin0 === 0n ? null : (buffer0 * 10000n) / requiredMargin0\n const bufferPercent1 = requiredMargin1 === 0n ? null : (buffer1 * 10000n) / requiredMargin1\n\n // Liquidation prices: present only when the account has positions.\n let lowerLiquidationTick: bigint | null = null\n let upperLiquidationTick: bigint | null = null\n let liquidationDistance: bigint | null = null\n if (liqPricesResult) {\n const liqPriceDown = BigInt(liqPricesResult[0])\n const liqPriceUp = BigInt(liqPricesResult[1])\n lowerLiquidationTick = liqPriceDown === MIN_TICK ? null : liqPriceDown\n upperLiquidationTick = liqPriceUp === MAX_TICK ? null : liqPriceUp\n if (lowerLiquidationTick !== null && upperLiquidationTick !== null) {\n const distLower = currentTick - lowerLiquidationTick\n const distUpper = upperLiquidationTick - currentTick\n liquidationDistance = distLower < distUpper ? distLower : distUpper\n } else if (lowerLiquidationTick !== null) {\n liquidationDistance = currentTick - lowerLiquidationTick\n } else if (upperLiquidationTick !== null) {\n liquidationDistance = upperLiquidationTick - currentTick\n }\n }\n\n return {\n buffer0,\n buffer1,\n bufferPercent0,\n bufferPercent1,\n currentMargin0,\n currentMargin1,\n requiredMargin0,\n requiredMargin1,\n denominatedInToken,\n liquidationDistance,\n lowerLiquidationTick,\n upperLiquidationTick,\n crossMarginUsageBps,\n usageBps0,\n usageBps1,\n mintableMarginBinding,\n currentTick,\n _meta,\n }\n}\n","/**\n * Delta hedging utilities for the Panoptic v2 SDK.\n *\n * Provides functions to calculate loan parameters needed\n * to achieve a target delta for option positions.\n *\n * @module v2/reads/hedge\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { getBlockMeta } from '../clients/blockMeta'\nimport { PanopticValidationError } from '../errors/sdk'\nimport { calculatePositionDelta } from '../greeks'\nimport { decodeTokenId } from '../tokenId'\nimport type { LegConfig } from '../tokenId/builder'\nimport type { BlockMeta } from '../types'\nimport { getPool } from './pool'\n\n/**\n * Parameters for getDeltaHedgeParams.\n */\nexport interface GetDeltaHedgeParamsInput {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Chain ID */\n chainId: bigint\n /**\n * TokenId of the option position to hedge.\n * Optional when both `currentDelta` and `asset` are provided (whole-portfolio hedging).\n */\n tokenId?: bigint\n /**\n * Position size in contracts.\n * Optional when both `currentDelta` and `asset` are provided.\n */\n positionSize?: bigint\n /** Target delta (WAD-scaled, 0n for delta-neutral) */\n targetDelta: bigint\n /** Optional: current delta if adjusting existing position (WAD-scaled) */\n currentDelta?: bigint\n /**\n * Primary asset index (0n or 1n). Used to determine hedge direction.\n * Required when `tokenId` is not provided; ignored when `tokenId` is provided.\n */\n asset?: bigint\n /** Optional: tick at mint (defaults to current tick if not provided) */\n mintTick?: bigint\n /** Optional: block number for historical queries */\n blockNumber?: bigint\n /** Optional: current tick (skips getPool() when both currentTick and tickSpacing are provided) */\n currentTick?: bigint\n /** Optional: pool tick spacing (skips getPool() when both currentTick and tickSpacing are provided) */\n tickSpacing?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n\n // --- Simulation convergence options ---\n\n /**\n * Simulate the hedge swap and return the post-swap tick.\n * When provided (along with `computeDeltaAtTick`), an iterative loop refines\n * the hedge size to account for AMM price impact.\n */\n simulateSwap?: (hedgeAmount: bigint, hedgeLeg: LegConfig) => Promise<{ tickAfter: bigint } | null>\n\n /**\n * Recompute portfolio delta at a given tick.\n * Required when `simulateSwap` is provided.\n */\n computeDeltaAtTick?: (tick: bigint) => bigint\n\n /** Total position size — used for convergence check (sizeDelta * 10000 / totalPositionSize) */\n totalPositionSize?: bigint\n\n /** Max simulation iterations (default 5) */\n maxSimIterations?: number\n\n /** Convergence threshold in bps (default 10). Loop stops when size change < this. */\n convergenceThresholdBps?: bigint\n}\n\n/**\n * Result of getDeltaHedgeParams.\n */\nexport interface DeltaHedgeResult {\n /** LegConfig to add to the position for hedging */\n hedgeLeg: LegConfig\n /** The hedge amount (in position size units) */\n hedgeAmount: bigint\n /** Always 'loan' — the tokenType determines the delta direction */\n hedgeType: 'loan' | 'credit'\n /** Whether the hedge position should be opened with swapAtMint */\n swapAtMint: boolean\n /** Current position delta (WAD-scaled) */\n currentDelta: bigint\n /** Target delta (WAD-scaled) */\n targetDelta: bigint\n /** Delta adjustment needed (WAD-scaled) */\n deltaAdjustment: bigint\n /** Block metadata */\n _meta: BlockMeta\n /** Number of simulation iterations used (0 if no simulateSwap) */\n simulationIterations: number\n /** Post-swap tick from final simulation (undefined if no simulation) */\n simulatedTickAfter?: bigint\n /** Whether the convergence loop converged within threshold */\n converged: boolean\n}\n\n/**\n * Calculate loan parameters to achieve target delta via swapAtMint.\n *\n * Both delta directions use loans with swapAtMint — the tokenType\n * determines whether delta is added or removed:\n *\n * - **Need positive delta** (e.g. hedging a short call):\n * Loan with tokenType = numeraire + swapAtMint.\n * Borrows numeraire (e.g. USDC), swaps to asset (e.g. ETH).\n * Net: +asset exposure → positive delta.\n *\n * - **Need negative delta** (e.g. hedging a short put):\n * Loan with tokenType = asset + swapAtMint.\n * Borrows asset (e.g. ETH), swaps to numeraire (e.g. USDC).\n * Net: −asset exposure → negative delta.\n *\n * ## Example: Delta-neutral short call\n * ```typescript\n * const hedge = await getDeltaHedgeParams({\n * client, poolAddress, chainId,\n * tokenId: shortCallTokenId,\n * positionSize: 1000000000000000n,\n * targetDelta: 0n,\n * })\n *\n * // Open the hedge as a separate position with swapAtMint\n * const hedgeTokenId = builder\n * .addLoan({ tokenType: hedge.hedgeLeg.tokenType, strike: hedge.hedgeLeg.strike })\n * .build()\n *\n * await openPosition({ ..., tokenId: hedgeTokenId,\n * positionSize: hedge.hedgeAmount, swapAtMint: hedge.swapAtMint })\n * ```\n *\n * @param params - The parameters\n * @returns Delta hedge result with LegConfig (always a loan)\n */\nexport async function getDeltaHedgeParams(\n params: GetDeltaHedgeParamsInput,\n): Promise<DeltaHedgeResult> {\n const {\n client,\n poolAddress,\n chainId,\n tokenId,\n positionSize,\n targetDelta,\n currentDelta: providedCurrentDelta,\n asset: providedAsset,\n mintTick: providedMintTick,\n blockNumber,\n currentTick: providedCurrentTick,\n tickSpacing: providedTickSpacing,\n } = params\n\n // Validate: need either tokenId or (currentDelta + asset)\n const hasTokenId = tokenId !== undefined\n const hasDirectDelta = providedCurrentDelta !== undefined && providedAsset !== undefined\n\n if (!hasTokenId && !hasDirectDelta) {\n throw new PanopticValidationError(\n 'getDeltaHedgeParams requires either `tokenId` or both `currentDelta` and `asset`',\n )\n }\n\n // Validate simulateSwap and computeDeltaAtTick are provided together\n if ((params.simulateSwap !== undefined) !== (params.computeDeltaAtTick !== undefined)) {\n throw new PanopticValidationError(\n 'getDeltaHedgeParams: simulateSwap and computeDeltaAtTick must be provided together',\n )\n }\n\n // If both currentTick and tickSpacing are provided, skip the full getPool() call\n let currentTick: bigint\n let tickSpacing: bigint\n let poolMeta: BlockMeta\n\n if (providedCurrentTick !== undefined && providedTickSpacing !== undefined) {\n currentTick = providedCurrentTick\n tickSpacing = providedTickSpacing\n poolMeta =\n params._meta ??\n (await getBlockMeta({ client, blockNumber: blockNumber ?? (await client.getBlockNumber()) }))\n } else {\n const pool = await getPool({\n client,\n poolAddress,\n chainId,\n blockNumber,\n })\n currentTick = pool.currentTick\n tickSpacing = pool.tickSpacing\n poolMeta = pool._meta\n }\n\n // Determine primary asset and current delta\n let primaryAsset: bigint\n let currentDelta: bigint\n\n if (hasTokenId) {\n // Decode the tokenId to get legs\n const decoded = decodeTokenId(tokenId)\n primaryAsset = decoded.legs.length > 0 ? decoded.legs[0].asset : 0n\n\n // Use provided mintTick or default to currentTick\n const mintTick = providedMintTick ?? currentTick\n\n // Calculate position delta if not provided\n currentDelta =\n providedCurrentDelta ??\n calculatePositionDelta({\n legs: decoded.legs,\n currentTick,\n mintTick,\n positionSize: positionSize!,\n poolTickSpacing: tickSpacing,\n })\n } else {\n // Direct delta + asset mode (whole-portfolio hedging)\n if (providedAsset !== 0n && providedAsset !== 1n) {\n throw new PanopticValidationError(\n `getDeltaHedgeParams: asset must be 0n or 1n, got ${providedAsset}`,\n )\n }\n primaryAsset = providedAsset\n currentDelta = providedCurrentDelta!\n }\n\n // deltaAdjustment = targetDelta - currentDelta\n // Positive → need to add positive delta; Negative → need to add negative delta.\n const deltaAdjustment = targetDelta - currentDelta\n\n // Delta is in asset smallest units. A loan+swapAtMint of size X gives\n // effective delta ≈ ±X (in asset smallest units). So hedgeAmount = |deltaAdjustment|.\n const absDeltaAdjustment = deltaAdjustment < 0n ? -deltaAdjustment : deltaAdjustment\n let hedgeAmount = absDeltaAdjustment\n\n const numeraire = primaryAsset === 0n ? 1n : 0n\n\n // Both directions use a loan + swapAtMint. The tokenType determines direction:\n // deltaAdjustment > 0 (need +delta): loan numeraire → swap to asset → +asset exposure\n // deltaAdjustment < 0 (need −delta): loan asset → swap to numeraire → −asset exposure\n const needPositiveDelta = deltaAdjustment > 0n\n const hedgeTokenType = needPositiveDelta ? numeraire : primaryAsset\n\n const hedgeLeg: LegConfig = {\n asset: primaryAsset,\n optionRatio: 1n,\n isLong: false, // Always a loan\n tokenType: hedgeTokenType,\n strike: (currentTick / tickSpacing) * tickSpacing, // Round to tick spacing\n width: 0n, // Loan/credit indicator\n }\n\n // --- Simulation convergence loop ---\n const {\n simulateSwap,\n computeDeltaAtTick,\n totalPositionSize,\n maxSimIterations = 5,\n convergenceThresholdBps = 10n,\n } = params\n\n let simulationIterations = 0\n let simulatedTickAfter: bigint | undefined\n let converged = true\n\n if (simulateSwap && computeDeltaAtTick) {\n if (totalPositionSize === undefined || totalPositionSize === 0n) {\n throw new PanopticValidationError(\n 'getDeltaHedgeParams: totalPositionSize is required and must be > 0 when simulateSwap is provided',\n )\n }\n\n converged = false\n\n for (let i = 0; i < maxSimIterations; i++) {\n simulationIterations = i + 1\n\n const simResult = await simulateSwap(hedgeAmount, hedgeLeg)\n if (simResult == null) break\n\n simulatedTickAfter = simResult.tickAfter\n\n // Recompute portfolio delta at the post-swap tick\n const adjustedDelta = computeDeltaAtTick(simResult.tickAfter)\n const newAdjustment = targetDelta - adjustedDelta\n const newAmount = newAdjustment < 0n ? -newAdjustment : newAdjustment\n\n // Convergence check\n const sizeDelta = newAmount > hedgeAmount ? newAmount - hedgeAmount : hedgeAmount - newAmount\n const sizeChangeBps = (sizeDelta * 10000n) / totalPositionSize\n\n hedgeAmount = newAmount\n\n if (sizeChangeBps <= convergenceThresholdBps || sizeDelta === 0n) {\n converged = true\n break\n }\n }\n }\n\n return {\n hedgeLeg,\n hedgeAmount,\n hedgeType: 'loan',\n swapAtMint: true,\n currentDelta,\n targetDelta,\n deltaAdjustment,\n _meta: poolMeta,\n simulationIterations,\n simulatedTickAfter,\n converged,\n }\n}\n","/**\n * Collateral share price read for the Panoptic v2 SDK.\n *\n * Reads totalAssets and totalSupply from two CollateralTracker contracts\n * to compute share prices. Designed for APY calculations at historical blocks.\n *\n * @module v2/reads/collateralSharePrice\n */\n\nimport type { Address, Client } from 'viem'\nimport { ContractFunctionExecutionError } from 'viem'\nimport { multicall } from 'viem/actions'\n\nimport { collateralTrackerV2Abi } from '../../../generated'\n\n/**\n * Raw share price data for a single collateral tracker.\n */\nexport interface CollateralSharePriceData {\n totalAssets: bigint\n totalSupply: bigint\n}\n\n/**\n * Get totalAssets and totalSupply for two CollateralTracker contracts in a single multicall.\n *\n * Consumers can compute share price as `totalAssets / totalSupply` using their\n * preferred precision library (e.g. Decimal.js).\n *\n * If the collateral tracker reverts (e.g. uninitialized), returns zeros.\n *\n * @param collateralAddresses - Tuple of [token0 tracker, token1 tracker] addresses\n * @param blockNumber - Block number to query at\n * @param client - viem Client\n * @returns Tuple of raw share price data\n */\nexport async function getCollateralSharePrices(\n collateralAddresses: [Address, Address],\n blockNumber: bigint,\n client: Client,\n): Promise<[CollateralSharePriceData, CollateralSharePriceData]> {\n try {\n const results = await multicall(client, {\n contracts: [\n {\n address: collateralAddresses[0],\n abi: collateralTrackerV2Abi,\n functionName: 'totalAssets',\n },\n {\n address: collateralAddresses[0],\n abi: collateralTrackerV2Abi,\n functionName: 'totalSupply',\n },\n {\n address: collateralAddresses[1],\n abi: collateralTrackerV2Abi,\n functionName: 'totalAssets',\n },\n {\n address: collateralAddresses[1],\n abi: collateralTrackerV2Abi,\n functionName: 'totalSupply',\n },\n ],\n blockNumber,\n allowFailure: false,\n })\n\n const [assets0, supply0, assets1, supply1] = results\n\n return [\n { totalAssets: assets0, totalSupply: supply0 },\n { totalAssets: assets1, totalSupply: supply1 },\n ]\n } catch (e: unknown) {\n if (e instanceof ContractFunctionExecutionError) {\n return [\n { totalAssets: 0n, totalSupply: 0n },\n { totalAssets: 0n, totalSupply: 0n },\n ]\n }\n throw e\n }\n}\n","/**\n * Batch read of CollateralTracker.totalAssets() for multiple trackers.\n *\n * @module v2/reads/collateralTotalAssets\n */\n\nimport type { Address, Client } from 'viem'\nimport { getAddress, zeroAddress } from 'viem'\nimport { multicall } from 'viem/actions'\n\nimport { collateralTrackerV2Abi } from '../../../generated'\n\n/**\n * Get totalAssets for multiple CollateralTracker contracts in a single multicall.\n *\n * @param client - viem Client\n * @param collateralTrackerAddresses - Array of CollateralTracker addresses\n * @param chainId - Chain ID (for multicall routing)\n * @param blockNumber - Optional block number for historical queries\n * @returns Array of totalAssets (bigint) in the same order as input addresses\n */\nexport async function getCollateralTotalAssetsBatch(\n client: Client,\n collateralTrackerAddresses: Address[],\n chainId: number,\n blockNumber?: bigint,\n): Promise<bigint[]> {\n if (collateralTrackerAddresses.length === 0) return []\n\n try {\n const contracts = collateralTrackerAddresses.map((address) => ({\n address: getAddress(address ?? zeroAddress),\n abi: collateralTrackerV2Abi,\n functionName: 'totalAssets' as const,\n chainId,\n }))\n\n const results = await multicall(client, {\n contracts,\n blockNumber,\n allowFailure: false,\n })\n\n return results.map((result) => BigInt(result ?? 0))\n } catch (error) {\n console.error('Error reading collateral total assets:', error)\n return collateralTrackerAddresses.map(() => 0n)\n }\n}\n","/**\n * Account buying power read function for the Panoptic v2 SDK.\n *\n * Sources gross collateral from `CollateralTracker.assetsOf` and per-position\n * required margin from `PanopticPool.getFullPositionsData.collateralRequirements[]`,\n * cross-converted to both token denominations at the current tick.\n *\n * This replaces the prior `PanopticQuery.checkCollateral` (3-arg, oracle-ticks\n * overload) implementation that netted loan tokenId debt out of the balance\n * and excluded loans from required-collateral, causing buying-power readouts\n * to be wildly wrong for any account that had borrowed.\n *\n * @module v2/reads/buyingPower\n */\n\nimport type { Address, Client } from 'viem'\nimport { decodeFunctionResult, encodeFunctionData } from 'viem'\nimport { multicall } from 'viem/actions'\n\nimport { collateralTrackerV2Abi, panopticPoolV2Abi } from '../../../generated'\nimport { tickToSqrtPriceX96 } from '../formatters/tick'\nimport type { BlockMeta } from '../types'\nimport { decodeLeftRightUnsigned } from '../writes/utils'\nimport { type MulticallBlockCall, readBlockAndAggregate, requireReturnData } from './multicallBlock'\n\nconst Q128 = 1n << 128n\n\nfunction convert0to1(amount: bigint, sqrtPriceX96: bigint): bigint {\n if (sqrtPriceX96 < Q128) {\n return (amount * sqrtPriceX96 * sqrtPriceX96) >> 192n\n }\n const sp2Hi = (sqrtPriceX96 * sqrtPriceX96) >> 64n\n return (amount * sp2Hi) >> 128n\n}\n\nfunction convert1to0(amount: bigint, sqrtPriceX96: bigint): bigint {\n if (sqrtPriceX96 < Q128) {\n const denom = sqrtPriceX96 * sqrtPriceX96\n return (amount * (1n << 192n)) / denom\n }\n const sp2Hi = (sqrtPriceX96 * sqrtPriceX96) >> 64n\n return (amount * (1n << 128n)) / sp2Hi\n}\n\n/**\n * Parameters for getAccountBuyingPower.\n */\nexport interface GetAccountBuyingPowerParams {\n /** viem Client (PublicClient or basic Client with transport) */\n client: Client\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** TokenIds of open positions */\n tokenIds: bigint[]\n /** PanopticQuery address (kept for backwards compatibility; unused). */\n queryAddress?: Address\n /**\n * Optional pre-fetched collateral tracker addresses (saves an RPC).\n * If omitted, they are fetched from the pool.\n */\n collateralAddresses?: { collateralToken0: Address; collateralToken1: Address }\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips block metadata fetch) */\n _meta?: BlockMeta\n}\n\n/**\n * Result of getAccountBuyingPower.\n *\n * Both per-token values are the **gross** account total cross-converted\n * into the respective single-token denomination at the current tick:\n * - `collateralBalance0` / `requiredCollateral0` are in token0 units\n * - `collateralBalance1` / `requiredCollateral1` are in token1 units\n */\nexport interface AccountBuyingPower {\n /** Gross collateral (deposits + borrowed shares), denominated in token0 */\n collateralBalance0: bigint\n /** Sum of per-position collateral requirements, denominated in token0 */\n requiredCollateral0: bigint\n /** Gross collateral (deposits + borrowed shares), denominated in token1 */\n collateralBalance1: bigint\n /** Sum of per-position collateral requirements, denominated in token1 */\n requiredCollateral1: bigint\n /** Block metadata for the Multicall3 aggregate read */\n _meta: BlockMeta\n}\n\n/**\n * Get account-level buying power.\n *\n * Uses {@link https://github.com/panoptic-xyz CollateralTracker.assetsOf} for\n * gross collateral and `PanopticPool.getFullPositionsData.collateralRequirements[]`\n * for the per-position required margin — so loan tokenIds (width=0 shorts)\n * contribute to the requirement instead of being netted out of the balance.\n *\n * Accepts a plain viem `Client` (not just `PublicClient`) so it works with wagmi's\n * `useClient()` without needing a cast.\n *\n * @param params - The parameters\n * @returns Account buying power data with optional block metadata\n */\nexport async function getAccountBuyingPower(\n params: GetAccountBuyingPowerParams,\n): Promise<AccountBuyingPower> {\n const { client, poolAddress, account, tokenIds } = params\n const blockNumber = params.blockNumber ?? params._meta?.blockNumber\n\n // Resolve collateral tracker addresses (immutable; cache-friendly).\n let collateralToken0: Address\n let collateralToken1: Address\n if (params.collateralAddresses) {\n collateralToken0 = params.collateralAddresses.collateralToken0\n collateralToken1 = params.collateralAddresses.collateralToken1\n } else {\n const addrs = await multicall(client, {\n contracts: [\n { address: poolAddress, abi: panopticPoolV2Abi, functionName: 'collateralToken0' },\n { address: poolAddress, abi: panopticPoolV2Abi, functionName: 'collateralToken1' },\n ],\n blockNumber,\n allowFailure: false,\n })\n collateralToken0 = addrs[0]\n collateralToken1 = addrs[1]\n }\n\n const calls: MulticallBlockCall[] = [\n {\n target: poolAddress,\n callData: encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n }),\n },\n {\n target: collateralToken0,\n callData: encodeFunctionData({\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n args: [account],\n }),\n },\n {\n target: collateralToken1,\n callData: encodeFunctionData({\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n args: [account],\n }),\n },\n ]\n\n const positionDataIndex = tokenIds.length > 0 ? calls.length : null\n if (positionDataIndex !== null) {\n calls.push({\n target: poolAddress,\n callData: encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [account, true, tokenIds],\n }),\n })\n }\n\n const { _meta, results } = await readBlockAndAggregate({ client, calls, blockNumber })\n\n const currentTickResult = decodeFunctionResult({\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n data: requireReturnData(results, 0, 'PanopticPool.getCurrentTick'),\n })\n const assets0 = decodeFunctionResult({\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n data: requireReturnData(results, 1, 'CollateralTracker.assetsOf token0'),\n })\n const assets1 = decodeFunctionResult({\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n data: requireReturnData(results, 2, 'CollateralTracker.assetsOf token1'),\n })\n const currentTick = BigInt(currentTickResult)\n const positionDataResult =\n positionDataIndex === null\n ? null\n : (decodeFunctionResult({\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n data: requireReturnData(results, positionDataIndex, 'PanopticPool.getFullPositionsData'),\n }) as readonly [bigint, bigint, readonly bigint[], readonly bigint[], readonly bigint[]])\n\n // Sum collateral requirements across positions, per token.\n let required0Native = 0n\n let required1Native = 0n\n if (positionDataResult) {\n const collateralRequirements = positionDataResult[3]\n for (const packed of collateralRequirements) {\n const decoded = decodeLeftRightUnsigned(packed)\n required0Native += decoded.right // token0\n required1Native += decoded.left // token1\n }\n }\n\n // Cross-convert into each single-token denomination at current tick.\n const sqrtPriceX96 = tickToSqrtPriceX96(currentTick)\n const collateralBalance0 = assets0 + convert1to0(assets1, sqrtPriceX96)\n const requiredCollateral0 = required0Native + convert1to0(required1Native, sqrtPriceX96)\n const collateralBalance1 = assets1 + convert0to1(assets0, sqrtPriceX96)\n const requiredCollateral1 = required1Native + convert0to1(required0Native, sqrtPriceX96)\n\n return {\n collateralBalance0,\n requiredCollateral0,\n collateralBalance1,\n requiredCollateral1,\n _meta,\n }\n}\n","/**\n * Open position simulation for the Panoptic v2 SDK.\n * @module v2/simulations/simulateOpenPosition\n */\n\nimport type { Address, PublicClient } from 'viem'\nimport { decodeFunctionResult, encodeFunctionData } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { getBlockMeta } from '../clients'\nimport { PanopticError } from '../errors'\nimport { calculatePositionGreeks } from '../greeks'\nimport { getPool } from '../reads/pool'\nimport { decodeTokenId } from '../tokenId/decode'\nimport type { OpenPositionSimulation, SimulationResult } from '../types'\nimport { decodeLeftRightUnsigned } from '../writes/utils'\nimport { simulateWithTokenFlow } from './tokenFlow'\n\n/**\n * Parameters for simulating position opening.\n */\nexport interface SimulateOpenPositionParams {\n /** Public client */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** Existing position IDs held by the account (before this mint) */\n existingPositionIds: bigint[]\n /** TokenId of position to open */\n tokenId: bigint\n /** Position size */\n positionSize: bigint\n /**\n * Lower tick limit (always <= tickLimitHigh).\n * Use MIN_TICK (-887272n) to allow any downward price movement.\n */\n tickLimitLow: bigint\n /**\n * Upper tick limit (always >= tickLimitLow).\n * Use MAX_TICK (887272n) to allow any upward price movement.\n */\n tickLimitHigh: bigint\n /** Spread limit tick (use 0n for no spread limit) */\n spreadLimit?: bigint\n /**\n * Whether to swap tokens at mint to achieve single-sided exposure.\n * When true, tickLimits are passed to dispatch in descending order (high, low).\n * When false (default), tickLimits are passed in ascending order (low, high).\n */\n swapAtMint?: boolean\n /** Whether to use premia as collateral */\n usePremiaAsCollateral?: boolean\n /** Builder code */\n builderCode?: bigint\n /** Chain ID (required for pool data fetch used in greeks) */\n chainId?: bigint\n /** Optional block number for simulation */\n blockNumber?: bigint\n}\n\n/**\n * Simulate opening a position.\n *\n * Uses PanopticPool.multicall with getAssetsOf-dispatch-getAssetsOf pattern\n * to measure exact collateral asset movements, then enriches with decoded\n * position data and client-side greeks.\n *\n * @param params - Simulation parameters\n * @returns Simulation result with position data or error\n *\n * @example\n * ```typescript\n * import { MIN_TICK, MAX_TICK } from '@panoptic/sdk'\n *\n * const result = await simulateOpenPosition({\n * client,\n * poolAddress,\n * account,\n * existingPositionIds: [],\n * tokenId,\n * positionSize: 1n,\n * tickLimitLow: MIN_TICK,\n * tickLimitHigh: MAX_TICK,\n * swapAtMint: false,\n * chainId: 11155111n, // Sepolia\n * })\n *\n * if (result.success) {\n * console.log('Gas estimate:', result.gasEstimate)\n * console.log('Token 0 required:', result.data.amount0Required)\n * console.log('Token 1 required:', result.data.amount1Required)\n * console.log('Delta:', result.data.greeks.delta)\n * } else {\n * console.log('Error:', result.error)\n * }\n * ```\n */\nexport async function simulateOpenPosition(\n params: SimulateOpenPositionParams,\n): Promise<SimulationResult<OpenPositionSimulation>> {\n const {\n client,\n poolAddress,\n account,\n existingPositionIds,\n tokenId,\n positionSize,\n tickLimitLow,\n tickLimitHigh,\n spreadLimit = 0n,\n swapAtMint = false,\n usePremiaAsCollateral = false,\n builderCode = 0n,\n chainId,\n blockNumber,\n } = params\n\n const targetBlockNumber = blockNumber ?? (await client.getBlockNumber())\n const metaPromise = getBlockMeta({ client, blockNumber: targetBlockNumber })\n\n // Build tick limits based on swapAtMint flag:\n // - swapAtMint=true: descending order (high, low) triggers SFPM swap\n // - swapAtMint=false: ascending order (low, high) no swap\n const tickLimits: readonly [number, number, number] = swapAtMint\n ? [Number(tickLimitHigh), Number(tickLimitLow), Number(spreadLimit)]\n : [Number(tickLimitLow), Number(tickLimitHigh), Number(spreadLimit)]\n\n try {\n // Prepare position lists for dispatch:\n // - positionIdList: positions being minted in this call (just the new tokenId)\n // - finalPositionIdList: all positions the user will have after the mint\n const positionIdList = [tokenId]\n const finalPositionIdList = [...existingPositionIds, tokenId]\n\n // Encode dispatch call data\n const callData = encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n positionIdList,\n finalPositionIdList,\n // ABI declares uint128 but TS only knows bigint — viem/abitype limitation\n [BigInt(positionSize) as unknown as bigint & { readonly __uint128: true }],\n [tickLimits],\n usePremiaAsCollateral,\n builderCode,\n ],\n })\n\n // Encode getFullPositionsData to run post-dispatch in the same multicall\n const getFullPositionsDataCallData = encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [account, false, finalPositionIdList],\n })\n\n // Simulate with token flow measurement using PanopticPool.multicall + getAssetsOf\n const flowResult = await simulateWithTokenFlow({\n client,\n poolAddress,\n user: account,\n callData,\n blockNumber: targetBlockNumber,\n postCallData: [getFullPositionsDataCallData],\n })\n\n if (!flowResult.success || !flowResult.tokenFlow) {\n throw (\n flowResult.rawError ?? new PanopticError(flowResult.error || 'Token flow simulation failed')\n )\n }\n\n const tokenFlow = flowResult.tokenFlow\n\n // Decode post-mint collateral requirements from getFullPositionsData result\n let postMintCollateralReqToken0 = 0n\n let postMintCollateralReqToken1 = 0n\n const perPositionCollateralReqs: { token0: bigint; token1: bigint }[] = []\n if (flowResult.postCallResults?.[0]) {\n try {\n const decoded = decodeFunctionResult({\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n data: flowResult.postCallResults[0],\n })\n // Result: [shortPremium, longPremium, balances[], collateralReqs[], netPremia[]]\n const collateralReqs = decoded[3]\n if (collateralReqs.length > 0) {\n // Each entry is a LeftRightUnsigned: right=token0, left=token1\n // Sum across all positions in finalPositionIdList\n for (const packed of collateralReqs) {\n const req = decodeLeftRightUnsigned(packed)\n postMintCollateralReqToken0 += req.right\n postMintCollateralReqToken1 += req.left\n perPositionCollateralReqs.push({ token0: req.right, token1: req.left })\n }\n }\n } catch {\n // Decode failure — leave at 0n\n }\n }\n\n // Decode tokenId to get legs and tick spacing\n const decoded = decodeTokenId(tokenId)\n\n // Fetch pool state for greeks (currentTick, tickSpacing) if chainId provided\n let currentTick = 0n\n let poolTickSpacing = decoded.tickSpacing\n let utilization0 = 0n\n let utilization1 = 0n\n\n if (chainId !== undefined) {\n try {\n const pool = await getPool({ client, poolAddress, chainId, blockNumber: targetBlockNumber })\n currentTick = pool.currentTick\n poolTickSpacing = pool.tickSpacing\n utilization0 = pool.collateralTracker0.utilization\n utilization1 = pool.collateralTracker1.utilization\n } catch {\n // Pool fetch failed - use decoded tickSpacing, skip greeks\n }\n }\n\n // Calculate greeks if we have legs and pool data\n const greeks =\n decoded.legs.length > 0 && (chainId !== undefined || currentTick !== 0n)\n ? calculatePositionGreeks({\n legs: decoded.legs,\n currentTick,\n mintTick: currentTick, // At simulation time, mintTick = currentTick\n positionSize,\n poolTickSpacing,\n })\n : { value: 0n, delta: 0n, gamma: 0n }\n\n const _meta = await metaPromise\n\n // Map token flow to simulation fields:\n // Negative delta = user deposits (required), so amount required = -delta\n const amount0Required = -tokenFlow.delta0\n const amount1Required = -tokenFlow.delta1\n\n const data: OpenPositionSimulation = {\n position: {\n tokenId,\n positionSize,\n owner: account,\n poolAddress,\n legs: decoded.legs,\n poolUtilization0AtMint: utilization0,\n poolUtilization1AtMint: utilization1,\n tickAtMint: currentTick,\n timestampAtMint: _meta.blockTimestamp,\n blockNumberAtMint: _meta.blockNumber,\n swapAtMint,\n premiaOwed0: 0n,\n premiaOwed1: 0n,\n assetIndex: 0n,\n _meta,\n },\n greeks,\n amount0Required,\n amount1Required,\n postCollateral0: tokenFlow.balanceAfter0,\n postCollateral1: tokenFlow.balanceAfter1,\n postMintCollateralReqToken0,\n postMintCollateralReqToken1,\n perPositionCollateralReqs,\n commission0: null, // Embedded in contract logic, not extractable from token flow\n commission1: null,\n }\n\n return {\n success: true,\n data,\n gasEstimate: flowResult.gasEstimate,\n tokenFlow,\n _meta,\n }\n } catch (error) {\n const _meta = await metaPromise\n return {\n success: false,\n error:\n error instanceof PanopticError\n ? error\n : new PanopticError(\n error instanceof Error ? error.message : 'Simulation failed',\n error instanceof Error ? error : undefined,\n ),\n _meta,\n }\n }\n}\n","/**\n * Open position preview — combines buying power check with open position simulation.\n *\n * @module v2/reads/openPositionPreview\n */\n\nimport type { Address, Client, PublicClient } from 'viem'\n\nimport type { NotEnoughTokensError } from '../errors'\nimport { AccountInsolventError } from '../errors'\nimport { parsePanopticError } from '../errors/parser'\nimport type { SimulateOpenPositionParams } from '../simulations/simulateOpenPosition'\nimport { simulateOpenPosition } from '../simulations/simulateOpenPosition'\nimport { getNotEnoughTokensError } from '../simulations/tokenShortfallRecovery'\nimport type { OpenPositionSimulation, SimulationResult } from '../types'\nimport type { AccountBuyingPower } from './buyingPower'\nimport { getAccountBuyingPower } from './buyingPower'\n\n/**\n * Parameters for getOpenPositionPreview.\n */\nexport interface GetOpenPositionPreviewParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** Existing position IDs held by the account (before this mint) */\n existingPositionIds: bigint[]\n /** TokenId of position to open */\n tokenId: bigint\n /** Position size */\n positionSize: bigint\n /** PanopticQuery address */\n queryAddress: Address\n /** Lower tick limit */\n tickLimitLow: bigint\n /** Upper tick limit */\n tickLimitHigh: bigint\n /** Spread limit (default 0n) */\n spreadLimit?: bigint\n /** Whether to swap at mint */\n swapAtMint?: boolean\n /** Whether to use premia as collateral */\n usePremiaAsCollateral?: boolean\n /** Chain ID (for greeks calculation) */\n chainId?: bigint\n /** Optional block number */\n blockNumber?: bigint\n}\n\n/**\n * Result of getOpenPositionPreview.\n */\nexport interface OpenPositionPreview {\n /** Current buying power (from checkCollateral on existing positions) */\n currentBuyingPower: AccountBuyingPower\n /** Simulation result (from dry-run dispatch) */\n simulation: SimulationResult<OpenPositionSimulation>\n /**\n * Whether the account has enough *buying power* for the position.\n *\n * False only for a genuine `AccountInsolvent` revert. A token shortfall is\n * reported separately via {@link OpenPositionPreview.tokenShortfall} — the two\n * have different remedies (lower the size vs. source the missing token), so\n * do not collapse them back into one flag.\n */\n isSolvent: boolean\n /**\n * Set when the mint reverted because one collateral tracker lacked tokens,\n * not because the account is short on margin. The account may hold plenty of\n * value in the *other* token, in which case a collateral swap resolves it.\n */\n tokenShortfall: NotEnoughTokensError | null\n /** Token 0 amount required (negative delta = deposit). Null if simulation failed. */\n amount0Required: bigint | null\n /** Token 1 amount required. Null if simulation failed. */\n amount1Required: bigint | null\n /** Collateral balance in token 0 after mint. Null if simulation failed. */\n postCollateral0: bigint | null\n /** Collateral balance in token 1 after mint. Null if simulation failed. */\n postCollateral1: bigint | null\n /** Post-mint collateral requirement in token0 (per-token, not cross-margined). Null if sim failed. */\n postMintCollateralReqToken0: bigint | null\n /** Post-mint collateral requirement in token1 (per-token, not cross-margined). Null if sim failed. */\n postMintCollateralReqToken1: bigint | null\n /**\n * Collateral requirement for the new position only (last entry of perPositionCollateralReqs).\n * Use this for \"Margin Used\" display — postMintCollateralReqToken0/1 includes existing positions too.\n * Null if simulation failed or perPositionCollateralReqs is empty.\n */\n newPositionCollateralReqToken0: bigint | null\n /** Collateral requirement for the new position only, token1. Null if sim failed. */\n newPositionCollateralReqToken1: bigint | null\n}\n\n/**\n * Get a preview of opening a position.\n *\n * Composes two calls:\n * 1. `getAccountBuyingPower` — current margin state for existing positions\n * 2. `simulateOpenPosition` — dry-run dispatch to check feasibility & token flows\n *\n * @param params - Preview parameters\n * @returns Preview with buying power, simulation result, and derived convenience fields\n */\nexport async function getOpenPositionPreview(\n params: GetOpenPositionPreviewParams,\n): Promise<OpenPositionPreview> {\n const {\n client,\n poolAddress,\n account,\n existingPositionIds,\n tokenId,\n positionSize,\n queryAddress,\n tickLimitLow,\n tickLimitHigh,\n spreadLimit,\n swapAtMint,\n usePremiaAsCollateral,\n chainId,\n blockNumber,\n } = params\n\n // Run both calls in parallel\n const [currentBuyingPower, simulation] = await Promise.all([\n getAccountBuyingPower({\n client: client as Client,\n poolAddress,\n account,\n tokenIds: existingPositionIds,\n queryAddress,\n blockNumber,\n }),\n simulateOpenPosition({\n client,\n poolAddress,\n account,\n existingPositionIds,\n tokenId,\n positionSize,\n tickLimitLow,\n tickLimitHigh,\n spreadLimit,\n swapAtMint,\n usePremiaAsCollateral,\n chainId,\n blockNumber,\n } satisfies SimulateOpenPositionParams),\n ])\n\n // Two distinct failures, kept apart because they have different remedies:\n // AccountInsolvent -> not enough buying power; the size must come down.\n // NotEnoughTokens -> one tracker is short tokens; the account may still be\n // well within its buying power, just holding the wrong\n // token, so sourcing it (swap / loan leg) resolves it.\n // Everything else (PriceBoundFail, EffectiveLiquidityAboveThreshold, …) is\n // neither, and must not read as a collateral problem.\n let isSolvent = true\n let tokenShortfall: NotEnoughTokensError | null = null\n if (!simulation.success) {\n const parsed = parsePanopticError(simulation.error)\n const err = parsed?.error ?? simulation.error\n isSolvent = !(err instanceof AccountInsolventError)\n tokenShortfall = getNotEnoughTokensError(err)\n }\n const data = simulation.success ? simulation.data : null\n\n return {\n currentBuyingPower,\n simulation,\n isSolvent,\n tokenShortfall,\n amount0Required: data?.amount0Required ?? null,\n amount1Required: data?.amount1Required ?? null,\n postCollateral0: data?.postCollateral0 ?? null,\n postCollateral1: data?.postCollateral1 ?? null,\n postMintCollateralReqToken0: data?.postMintCollateralReqToken0 ?? null,\n postMintCollateralReqToken1: data?.postMintCollateralReqToken1 ?? null,\n newPositionCollateralReqToken0:\n data?.perPositionCollateralReqs && data.perPositionCollateralReqs.length > 0\n ? (data.perPositionCollateralReqs[data.perPositionCollateralReqs.length - 1]?.token0 ??\n null)\n : null,\n newPositionCollateralReqToken1:\n data?.perPositionCollateralReqs && data.perPositionCollateralReqs.length > 0\n ? (data.perPositionCollateralReqs[data.perPositionCollateralReqs.length - 1]?.token1 ??\n null)\n : null,\n }\n}\n","/**\n * Read the native token (e.g. ETH) price in USD from a PanopticPool's on-chain tick.\n *\n * @module v2/reads/nativeTokenPrice\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { tickToPriceDecimalScaled } from '../formatters/tick'\n\nexport interface GetNativeTokenPriceParams {\n client: PublicClient\n /** Address of a PanopticPool deployed on a native/USD stablecoin underlying pool */\n panopticPoolAddress: Address\n /** Decimals of token0 in the underlying pool */\n token0Decimals: bigint\n /** Decimals of token1 in the underlying pool */\n token1Decimals: bigint\n /** Whether the native asset is token0 (true) or token1 (false) */\n nativeIsToken0: boolean\n}\n\n/**\n * Fetch the native token price in USD by reading `getCurrentTick()` from a\n * PanopticPool deployed on a native/stablecoin pair.\n *\n * @returns The price as a decimal string (e.g. \"2000.00\")\n */\nexport async function getNativeTokenPrice(params: GetNativeTokenPriceParams): Promise<string> {\n const { client, panopticPoolAddress, token0Decimals, token1Decimals, nativeIsToken0 } = params\n\n const currentTick = await client.readContract({\n address: panopticPoolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n })\n\n // tickToPriceDecimalScaled returns token0/token1 price (price of token0 denominated in token1).\n // If nativeIsToken0: price = USD per native (what we want)\n // If !nativeIsToken0: price = native per USD → invert by swapping decimals\n if (nativeIsToken0) {\n return tickToPriceDecimalScaled(BigInt(currentTick), token0Decimals, token1Decimals, 2n)\n } else {\n // Swap decimals to get the inverse price\n return tickToPriceDecimalScaled(BigInt(currentTick), token1Decimals, token0Decimals, 2n)\n }\n}\n","/**\n * Account trade history for the Panoptic v2 SDK.\n *\n * Fetches OptionMinted and OptionBurnt events filtered by account address\n * using indexed topic filtering for RPC efficiency (2 calls total).\n *\n * @module v2/reads/history\n */\n\nimport type { Address, Hash, PublicClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { getBlockMeta } from '../clients'\nimport type { BlockMeta } from '../types'\nimport { decodePositionBalance } from '../writes/utils'\n\n/**\n * A single trade (mint or burn) in the account's history.\n */\nexport interface AccountTrade {\n /** Whether this was a mint or burn */\n action: 'mint' | 'burn'\n /** TokenId of the position */\n tokenId: bigint\n /** Position size */\n positionSize: bigint\n /** Block number of the trade */\n blockNumber: bigint\n /** Transaction hash */\n transactionHash: Hash\n /** Log index within the block */\n logIndex: bigint\n /** Tick at mint (only for mints) */\n tickAtMint?: bigint\n /** Timestamp at mint in Unix seconds (only for mints) */\n timestampAtMint?: bigint\n /** Whether a swap occurred at mint (only for mints) */\n swapAtMint?: boolean\n /** Pool utilization for token 0 at mint (only for mints) */\n poolUtilization0?: bigint\n /** Pool utilization for token 1 at mint (only for mints) */\n poolUtilization1?: bigint\n /** Premia settled per leg on burn (only for burns) */\n premiaByLeg?: readonly [bigint, bigint, bigint, bigint]\n}\n\n/**\n * Account history result.\n */\nexport interface AccountHistory {\n /** All trades sorted by block number ascending, then log index */\n trades: AccountTrade[]\n /** Block metadata at query time */\n _meta: BlockMeta\n}\n\n/**\n * Parameters for getAccountHistory.\n */\nexport interface GetAccountHistoryParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address to fetch history for */\n account: Address\n /** Start block (default: 0n) */\n fromBlock?: bigint\n /** End block (default: latest) */\n toBlock?: bigint\n /** Optional block number for _meta (default: toBlock or latest) */\n blockNumber?: bigint\n}\n\n/**\n * Fetch trade history for an account on a specific pool.\n *\n * Uses indexed topic filtering on the `recipient` field of OptionMinted\n * and OptionBurnt events, resulting in exactly 2 RPC calls regardless\n * of the number of trades.\n *\n * @param params - Query parameters\n * @returns Account trade history sorted chronologically\n *\n * @example\n * ```typescript\n * const history = await getAccountHistory({\n * client,\n * poolAddress,\n * account: '0x...',\n * fromBlock: 18_000_000n,\n * })\n *\n * for (const trade of history.trades) {\n * console.log(`${trade.action} tokenId=${trade.tokenId} size=${trade.positionSize}`)\n * }\n * ```\n */\nexport async function getAccountHistory(params: GetAccountHistoryParams): Promise<AccountHistory> {\n const { client, poolAddress, account, fromBlock = 0n, toBlock, blockNumber } = params\n\n const effectiveToBlock = toBlock ?? blockNumber ?? (await client.getBlockNumber())\n const metaBlockNumber = blockNumber ?? effectiveToBlock\n\n // Fetch mints and burns in parallel — 2 RPC calls total.\n // Both events have `recipient` as indexed topic[1], so the RPC node\n // filters server-side via the topic hash.\n const [mintLogs, burnLogs, _meta] = await Promise.all([\n client.getContractEvents({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n eventName: 'OptionMinted',\n args: { recipient: account },\n fromBlock,\n toBlock: effectiveToBlock,\n }),\n client.getContractEvents({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n eventName: 'OptionBurnt',\n args: { recipient: account },\n fromBlock,\n toBlock: effectiveToBlock,\n }),\n getBlockMeta({ client, blockNumber: metaBlockNumber }),\n ])\n\n const trades: AccountTrade[] = []\n\n // Parse mints\n for (const log of mintLogs) {\n const args = log.args as {\n recipient: Address\n tokenId: bigint\n balanceData: bigint\n }\n const balance = decodePositionBalance(args.balanceData)\n trades.push({\n action: 'mint',\n tokenId: args.tokenId,\n positionSize: balance.positionSize,\n blockNumber: log.blockNumber!,\n transactionHash: log.transactionHash!,\n logIndex: BigInt(log.logIndex!),\n tickAtMint: balance.tickAtMint,\n timestampAtMint: balance.timestampAtMint,\n swapAtMint: balance.swapAtMint,\n poolUtilization0: balance.poolUtilization0,\n poolUtilization1: balance.poolUtilization1,\n })\n }\n\n // Parse burns\n for (const log of burnLogs) {\n const args = log.args as {\n recipient: Address\n tokenId: bigint\n positionSize: bigint\n premiaByLeg: readonly [bigint, bigint, bigint, bigint]\n }\n trades.push({\n action: 'burn',\n tokenId: args.tokenId,\n positionSize: args.positionSize,\n blockNumber: log.blockNumber!,\n transactionHash: log.transactionHash!,\n logIndex: BigInt(log.logIndex!),\n premiaByLeg: args.premiaByLeg,\n })\n }\n\n // Sort chronologically: by block number, then log index\n trades.sort((a, b) => {\n if (a.blockNumber !== b.blockNumber) {\n return a.blockNumber < b.blockNumber ? -1 : 1\n }\n return a.logIndex < b.logIndex ? -1 : 1\n })\n\n return { trades, _meta }\n}\n","/**\n * Historical Uniswap fee reads for the Panoptic v2 SDK.\n *\n * Standalone function for fetching Uniswap fee accrual across historical blocks.\n * Works with any Uniswap V3/V4 pool — no Panoptic pool required.\n *\n * Also used internally by getStreamiaHistory for the Uniswap fee component.\n *\n * @module v2/reads/uniswapFeeHistory\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { stateViewAbi } from '../abis/stateView'\nimport { uniswapV3PoolAbi } from '../abis/uniswapV3Pool'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport { InvalidHistoryRangeError } from '../errors/sdk'\nimport type { BlockMeta } from '../types'\nimport type { PoolVersionConfig } from '../types/poolConfig'\nimport type { StreamiaLeg } from '../types/streamia'\n\n// ── Types ──────────────────────────────────────────────────────────────\n\n/** A single snapshot of Uniswap fee data at a particular block. */\nexport interface UniswapFeeSnapshot {\n /** Resolved block number for this snapshot. */\n blockNumber: bigint\n /** Timestamp of the resolved block in Unix seconds. */\n blockTimestamp: bigint\n /** Uniswap fee delta from the first block in the series */\n fees: { token0: bigint; token1: bigint }\n}\n\n/** Result from getUniswapFeeHistory. */\nexport interface UniswapFeeHistoryResult {\n /** Snapshots in the same order as input blockNumbers */\n snapshots: UniswapFeeSnapshot[]\n /** Block metadata for the latest block used */\n _meta: BlockMeta\n}\n\n/** Parameters for getUniswapFeeHistory. */\nexport interface GetUniswapFeeHistoryParams {\n /** viem PublicClient */\n client: PublicClient\n /** Block numbers to query; undefined entries resolve to latest */\n blockNumbers: (bigint | undefined)[]\n /** Decoded legs with pre-computed liquidity */\n legs: StreamiaLeg[]\n /** Pool version config (carries pool address / StateView + poolId) */\n poolConfig: PoolVersionConfig\n /** Pre-fetched block metadata (skips an extra eth_getBlockByNumber if provided) */\n _meta?: BlockMeta\n}\n\n// ── Public function ────────────────────────────────────────────────────\n\n/**\n * Get historical Uniswap fee accrual for a set of liquidity legs across multiple blocks.\n *\n * Works with any Uniswap V3/V4 pool — no Panoptic pool required.\n * Returns fee deltas relative to the first block in the series.\n *\n * @param params - The parameters\n * @returns Fee snapshots at each block\n */\nexport async function getUniswapFeeHistory(\n params: GetUniswapFeeHistoryParams,\n): Promise<UniswapFeeHistoryResult> {\n const { client, blockNumbers, legs, poolConfig } = params\n\n // Validate legs\n for (const leg of legs) {\n if (leg.lowerTick >= leg.upperTick) {\n throw new InvalidHistoryRangeError(\n `Leg lowerTick (${leg.lowerTick}) must be < upperTick (${leg.upperTick})`,\n )\n }\n if (leg.liquidity <= 0n) {\n throw new InvalidHistoryRangeError(`Leg liquidity must be > 0, got ${leg.liquidity}`)\n }\n }\n\n if (blockNumbers.length === 0 || legs.length === 0) {\n const _meta = params._meta ?? (await getBlockMeta({ client }))\n return { snapshots: [], _meta }\n }\n\n const [blockData, blockMetadata, _meta] = await Promise.all([\n fetchUniswapFeeData(client, blockNumbers, legs, poolConfig),\n Promise.all(blockNumbers.map((blockNumber) => getBlockMeta({ client, blockNumber }))),\n params._meta ? Promise.resolve(params._meta) : getBlockMeta({ client }),\n ])\n\n let initialFees0: bigint | null = null\n let initialFees1: bigint | null = null\n\n const snapshots: UniswapFeeSnapshot[] = blockData.map((bd, i) => {\n const { total0, total1 } = computeUniswapFeesForBlock(bd, legs)\n\n if (initialFees0 === null) {\n initialFees0 = total0\n initialFees1 = total1\n }\n\n return {\n blockNumber: blockMetadata[i].blockNumber,\n blockTimestamp: blockMetadata[i].blockTimestamp,\n fees: {\n token0: total0 - initialFees0,\n token1: total1 - (initialFees1 as bigint),\n },\n }\n })\n\n return { snapshots, _meta }\n}\n\n// ── Internals (also used by streamiaHistory) ─────────────────────────\n\n/** Raw Uniswap data fetched for a single block. */\nexport interface UniswapBlockData {\n currentTick: number\n feeGrowthGlobal0: bigint\n feeGrowthGlobal1: bigint\n /** Map from tick number → { feeGrowthOutside0, feeGrowthOutside1 } */\n tickData: Map<number, { feeGrowthOutside0: bigint; feeGrowthOutside1: bigint }>\n}\n\n/**\n * Fetch Uniswap pool data for all blocks in parallel.\n * Globals (slot0, feeGrowthGlobal) are fetched ONCE per block, not per-leg.\n * Tick data is fetched for each unique tick across all legs.\n */\nexport async function fetchUniswapFeeData(\n client: PublicClient,\n blockNumbers: (bigint | undefined)[],\n legs: StreamiaLeg[],\n poolConfig: PoolVersionConfig,\n): Promise<UniswapBlockData[]> {\n const uniqueTickSet = new Set<number>()\n for (const leg of legs) {\n uniqueTickSet.add(leg.lowerTick)\n uniqueTickSet.add(leg.upperTick)\n }\n const uniqueTicks = [...uniqueTickSet].sort((a, b) => a - b)\n\n const blockPromises = blockNumbers.map((bn) =>\n fetchUniswapBlockSnapshot(client, bn, uniqueTicks, poolConfig),\n )\n\n return Promise.all(blockPromises)\n}\n\n/**\n * Compute total Uniswap fees for all legs at a single block, using the\n * standard Uniswap V3 fee accumulation formula.\n */\nexport function computeUniswapFeesForBlock(\n blockData: UniswapBlockData,\n legs: StreamiaLeg[],\n): { total0: bigint; total1: bigint } {\n let total0 = 0n\n let total1 = 0n\n\n for (const leg of legs) {\n const lower = blockData.tickData.get(leg.lowerTick)\n const upper = blockData.tickData.get(leg.upperTick)\n if (!lower || !upper) continue\n\n const { feeGrowthGlobal0, feeGrowthGlobal1, currentTick } = blockData\n\n const feesBelow0 =\n currentTick >= leg.lowerTick\n ? lower.feeGrowthOutside0\n : feeGrowthGlobal0 - lower.feeGrowthOutside0\n const feesBelow1 =\n currentTick >= leg.lowerTick\n ? lower.feeGrowthOutside1\n : feeGrowthGlobal1 - lower.feeGrowthOutside1\n\n const feesAbove0 =\n currentTick < leg.upperTick\n ? upper.feeGrowthOutside0\n : feeGrowthGlobal0 - upper.feeGrowthOutside0\n const feesAbove1 =\n currentTick < leg.upperTick\n ? upper.feeGrowthOutside1\n : feeGrowthGlobal1 - upper.feeGrowthOutside1\n\n const fees0 = ((feeGrowthGlobal0 - feesBelow0 - feesAbove0) * leg.liquidity) / (1n << 128n)\n const fees1 = ((feeGrowthGlobal1 - feesBelow1 - feesAbove1) * leg.liquidity) / (1n << 128n)\n\n total0 += fees0\n total1 += fees1\n }\n\n return { total0, total1 }\n}\n\n// ── Block snapshot fetchers ──────────────────────────────────────────\n\nasync function fetchUniswapBlockSnapshot(\n client: PublicClient,\n blockNumber: bigint | undefined,\n uniqueTicks: number[],\n poolConfig: PoolVersionConfig,\n): Promise<UniswapBlockData> {\n if (poolConfig.version === 'v3') {\n return fetchV3BlockSnapshot(client, poolConfig.poolAddress, blockNumber, uniqueTicks)\n } else {\n return fetchV4BlockSnapshot(\n client,\n poolConfig.stateViewAddress,\n poolConfig.poolId,\n blockNumber,\n uniqueTicks,\n )\n }\n}\n\nasync function fetchV3BlockSnapshot(\n client: PublicClient,\n poolAddress: Address,\n blockNumber: bigint | undefined,\n uniqueTicks: number[],\n): Promise<UniswapBlockData> {\n const contracts = [\n { address: poolAddress, abi: uniswapV3PoolAbi, functionName: 'slot0' as const },\n { address: poolAddress, abi: uniswapV3PoolAbi, functionName: 'feeGrowthGlobal0X128' as const },\n { address: poolAddress, abi: uniswapV3PoolAbi, functionName: 'feeGrowthGlobal1X128' as const },\n ...uniqueTicks.map((tick) => ({\n address: poolAddress,\n abi: uniswapV3PoolAbi,\n functionName: 'ticks' as const,\n args: [tick] as const,\n })),\n ]\n\n const results = await client.multicall({ contracts, blockNumber, allowFailure: false })\n\n const slot0Result = results[0] as readonly [\n bigint,\n number,\n number,\n number,\n number,\n number,\n boolean,\n ]\n const feeGrowthGlobal0 = results[1] as bigint\n const feeGrowthGlobal1 = results[2] as bigint\n\n const tickData = new Map<number, { feeGrowthOutside0: bigint; feeGrowthOutside1: bigint }>()\n for (let i = 0; i < uniqueTicks.length; i++) {\n const tickResult = results[3 + i] as readonly [\n bigint,\n bigint,\n bigint,\n bigint,\n bigint,\n bigint,\n number,\n boolean,\n ]\n tickData.set(uniqueTicks[i], {\n feeGrowthOutside0: tickResult[2],\n feeGrowthOutside1: tickResult[3],\n })\n }\n\n return { currentTick: slot0Result[1], feeGrowthGlobal0, feeGrowthGlobal1, tickData }\n}\n\nasync function fetchV4BlockSnapshot(\n client: PublicClient,\n stateViewAddress: Address,\n poolId: `0x${string}`,\n blockNumber: bigint | undefined,\n uniqueTicks: number[],\n): Promise<UniswapBlockData> {\n const contracts = [\n {\n address: stateViewAddress,\n abi: stateViewAbi,\n functionName: 'getSlot0' as const,\n args: [poolId] as const,\n },\n {\n address: stateViewAddress,\n abi: stateViewAbi,\n functionName: 'getFeeGrowthGlobals' as const,\n args: [poolId] as const,\n },\n ...uniqueTicks.map((tick) => ({\n address: stateViewAddress,\n abi: stateViewAbi,\n functionName: 'getTickInfo' as const,\n args: [poolId, tick] as const,\n })),\n ]\n\n const results = await client.multicall({ contracts, blockNumber, allowFailure: false })\n\n const slot0Result = results[0] as readonly [bigint, number, number, number]\n const feeGrowthResult = results[1] as readonly [bigint, bigint]\n\n const tickData = new Map<number, { feeGrowthOutside0: bigint; feeGrowthOutside1: bigint }>()\n for (let i = 0; i < uniqueTicks.length; i++) {\n const tickResult = results[2 + i] as readonly [bigint, bigint, bigint, bigint]\n tickData.set(uniqueTicks[i], {\n feeGrowthOutside0: tickResult[2],\n feeGrowthOutside1: tickResult[3],\n })\n }\n\n return {\n currentTick: slot0Result[1],\n feeGrowthGlobal0: feeGrowthResult[0],\n feeGrowthGlobal1: feeGrowthResult[1],\n tickData,\n }\n}\n","/**\n * Historical streamia (streaming premia) reads for the Panoptic v2 SDK.\n *\n * Fetches Panoptic premia and optionally Uniswap fee accrual across a series\n * of historical block numbers for a single position. Composes\n * getUniswapFeeHistory internally for the Uniswap fee component.\n *\n * @module v2/reads/streamiaHistory\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport { InvalidHistoryRangeError } from '../errors/sdk'\nimport type { BlockMeta } from '../types'\nimport type { PoolVersionConfig } from '../types/poolConfig'\nimport type { StreamiaLeg } from '../types/streamia'\nimport { computeUniswapFeesForBlock, fetchUniswapFeeData } from './uniswapFeeHistory'\n\n// Re-export types that were originally defined here for backward compatibility\nexport type { PoolVersionConfig, V3PoolConfig, V4PoolConfig } from '../types/poolConfig'\nexport type { StreamiaLeg } from '../types/streamia'\n\n// ── Types ──────────────────────────────────────────────────────────────\n\n/** A settled premia event, used to subtract already-settled amounts. */\nexport interface SettledEvent {\n /** Block at which settlement occurred */\n blockNumber: bigint\n /** Amount settled for token 0 */\n settled0: bigint\n /** Amount settled for token 1 */\n settled1: bigint\n}\n\n/** Parameters for getStreamiaHistory. */\nexport interface GetStreamiaHistoryParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool contract address */\n panopticPoolAddress: Address\n /** Account whose position to query */\n account: Address\n /** The encoded tokenId */\n tokenId: bigint\n /** Block numbers to query; undefined entries resolve to latest */\n blockNumbers: (bigint | undefined)[]\n /** Decoded legs with pre-computed liquidity */\n legs: StreamiaLeg[]\n /** Pool version config (carries pool address / StateView + poolId) */\n poolConfig: PoolVersionConfig\n /** Whether to include Uniswap fee data (default: true) */\n includeUniswapFees?: boolean\n /** Settled premia events to subtract from Panoptic premia (optional) */\n settledEvents?: SettledEvent[]\n /** Pre-fetched block metadata (skips an extra eth_getBlockByNumber if provided) */\n _meta?: BlockMeta\n}\n\n/** A single snapshot of streamia data at a particular block. */\nexport interface StreamiaSnapshot {\n /** Block number (undefined if queried as latest) */\n blockNumber: bigint | undefined\n /** Net Panoptic premia (short - long), after subtracting settled amounts */\n panopticPremia: { token0: bigint; token1: bigint }\n /** Uniswap fee delta from the first block in the series */\n uniswapFees: { token0: bigint; token1: bigint }\n}\n\n/** Result from getStreamiaHistory. */\nexport interface StreamiaHistoryResult {\n /** Snapshots in the same order as input blockNumbers */\n snapshots: StreamiaSnapshot[]\n /** Block metadata for the latest block used */\n _meta: BlockMeta\n}\n\n// 128-bit mask for LeftRight decoding\nconst MASK_128 = (1n << 128n) - 1n\n\n// ── Main function ──────────────────────────────────────────────────────\n\n/**\n * Get historical streamia data for a position across multiple blocks.\n *\n * @param params - The parameters\n * @returns Snapshots of Panoptic premia and Uniswap fee deltas at each block\n */\nexport async function getStreamiaHistory(\n params: GetStreamiaHistoryParams,\n): Promise<StreamiaHistoryResult> {\n const {\n client,\n panopticPoolAddress,\n account,\n tokenId,\n blockNumbers,\n legs,\n poolConfig,\n includeUniswapFees = true,\n settledEvents,\n } = params\n\n // Validate legs\n for (const leg of legs) {\n if (leg.lowerTick >= leg.upperTick) {\n throw new InvalidHistoryRangeError(\n `Leg lowerTick (${leg.lowerTick}) must be < upperTick (${leg.upperTick})`,\n )\n }\n if (leg.liquidity <= 0n) {\n throw new InvalidHistoryRangeError(`Leg liquidity must be > 0, got ${leg.liquidity}`)\n }\n }\n\n if (blockNumbers.length === 0) {\n const _meta = params._meta ?? (await getBlockMeta({ client }))\n return { snapshots: [], _meta }\n }\n\n // ── 1. Panoptic premia: one readContract per block ─────────────────\n const premiaRequests = blockNumbers.map((bn) =>\n client.readContract({\n address: panopticPoolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [account, true, [tokenId]],\n blockNumber: bn,\n }),\n )\n\n // ── 2. Uniswap fees (delegated to uniswapFeeHistory internals) ────\n const uniswapDataPromise =\n includeUniswapFees && legs.length > 0\n ? fetchUniswapFeeData(client, blockNumbers, legs, poolConfig)\n : undefined\n\n // ── 3. Fire all in parallel ────────────────────────────────────────\n const [premiaResults, uniswapData, _meta] = await Promise.all([\n Promise.all(premiaRequests),\n uniswapDataPromise ?? Promise.resolve(undefined),\n params._meta ? Promise.resolve(params._meta) : getBlockMeta({ client }),\n ])\n\n // ── 4. Pre-sort settled events for O(n+m) accumulation ─────────────\n const sortedSettled = settledEvents\n ? [...settledEvents].sort((a, b) => (a.blockNumber < b.blockNumber ? -1 : 1))\n : []\n\n // ── 5. Build snapshots ─────────────────────────────────────────────\n let settledIdx = 0\n let accSettled0 = 0n\n let accSettled1 = 0n\n\n let initialUniswapFees0: bigint | null = null\n let initialUniswapFees1: bigint | null = null\n\n const snapshots: StreamiaSnapshot[] = premiaResults.map((result, i) => {\n const bn = blockNumbers[i]\n\n const shortPacked = result[0]\n const longPacked = result[1]\n\n const short0 = shortPacked & MASK_128\n const short1 = shortPacked >> 128n\n const long0 = longPacked & MASK_128\n const long1 = longPacked >> 128n\n\n // Advance settled accumulator\n const effectiveBn = bn ?? BigInt(Number.MAX_SAFE_INTEGER)\n while (\n settledIdx < sortedSettled.length &&\n sortedSettled[settledIdx].blockNumber <= effectiveBn\n ) {\n accSettled0 += sortedSettled[settledIdx].settled0\n accSettled1 += sortedSettled[settledIdx].settled1\n settledIdx++\n }\n\n const premia0 = short0 - long0 - accSettled0\n const premia1 = short1 - long1 - accSettled1\n\n let uniswapFees0 = 0n\n let uniswapFees1 = 0n\n\n if (uniswapData) {\n const blockData = uniswapData[i]\n const { total0, total1 } = computeUniswapFeesForBlock(blockData, legs)\n\n if (initialUniswapFees0 === null) {\n initialUniswapFees0 = total0\n initialUniswapFees1 = total1\n }\n uniswapFees0 = total0 - initialUniswapFees0\n uniswapFees1 = total1 - (initialUniswapFees1 as bigint)\n }\n\n return {\n blockNumber: bn,\n panopticPremia: { token0: premia0, token1: premia1 },\n uniswapFees: { token0: uniswapFees0, token1: uniswapFees1 },\n }\n })\n\n return { snapshots, _meta }\n}\n","/**\n * Direct Uniswap V3 pool read — no Panoptic deployment required.\n *\n * @module v2/reads/uniswapPool\n */\n\nimport type { Address, Hex, PublicClient } from 'viem'\nimport { encodeAbiParameters, keccak256, zeroAddress } from 'viem'\n\nimport { panopticQueryAbi } from '../abis/panopticQuery'\nimport { stateViewAbi } from '../abis/stateView'\nimport { uniswapV3PoolAbi } from '../abis/uniswapV3Pool'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport { PanopticValidationError } from '../errors'\nimport type { BlockMeta } from '../types'\n\nconst erc20MetaAbi = [\n {\n type: 'function',\n name: 'symbol',\n inputs: [],\n outputs: [{ type: 'string' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'name',\n inputs: [],\n outputs: [{ type: 'string' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'decimals',\n inputs: [],\n outputs: [{ type: 'uint8' }],\n stateMutability: 'view',\n },\n] as const\n\nexport interface UniswapV3PoolToken {\n address: Address\n symbol: string\n name: string\n decimals: number\n}\n\nexport interface UniswapV3PoolInfo {\n poolAddress: Address\n token0: UniswapV3PoolToken\n token1: UniswapV3PoolToken\n /** Fee tier in hundredths of a bip (e.g. 500 = 0.05%) */\n fee: number\n tickSpacing: number\n currentTick: number\n sqrtPriceX96: bigint\n liquidity: bigint\n /**\n * Packed protocol fee from slot0: `feeProtocol1 << 4 | feeProtocol0`. Each\n * nibble `n` denotes a protocol fee of `1/n` of the swap fee (`0` = off).\n */\n feeProtocol: bigint\n _meta: BlockMeta\n}\n\nexport interface GetUniswapV3PoolInfoParams {\n client: PublicClient\n poolAddress: Address\n}\n\n/**\n * Fetch core data for a Uniswap V3 pool directly from chain.\n *\n * Does NOT require a Panoptic deployment — works for any V3 pool address.\n */\nexport async function getUniswapV3PoolInfo(\n params: GetUniswapV3PoolInfoParams,\n): Promise<UniswapV3PoolInfo> {\n const { client, poolAddress } = params\n\n // Pin every read to the same block so pool state + token metadata are\n // self-consistent. Pool reads run first because token0/token1 are needed to\n // address the ERC20 metadata calls; the second multicall is pinned to the\n // same block as the first.\n const _meta = await getBlockMeta({ client })\n\n const [slot0, fee, tickSpacing, token0Addr, token1Addr, liquidity] = await client.multicall({\n allowFailure: false,\n blockNumber: _meta.blockNumber,\n contracts: [\n { address: poolAddress, abi: uniswapV3PoolAbi, functionName: 'slot0' },\n { address: poolAddress, abi: uniswapV3PoolAbi, functionName: 'fee' },\n { address: poolAddress, abi: uniswapV3PoolAbi, functionName: 'tickSpacing' },\n { address: poolAddress, abi: uniswapV3PoolAbi, functionName: 'token0' },\n { address: poolAddress, abi: uniswapV3PoolAbi, functionName: 'token1' },\n { address: poolAddress, abi: uniswapV3PoolAbi, functionName: 'liquidity' },\n ],\n })\n\n const [t0Symbol, t0Name, t0Decimals, t1Symbol, t1Name, t1Decimals] = await client.multicall({\n allowFailure: false,\n blockNumber: _meta.blockNumber,\n contracts: [\n { address: token0Addr, abi: erc20MetaAbi, functionName: 'symbol' },\n { address: token0Addr, abi: erc20MetaAbi, functionName: 'name' },\n { address: token0Addr, abi: erc20MetaAbi, functionName: 'decimals' },\n { address: token1Addr, abi: erc20MetaAbi, functionName: 'symbol' },\n { address: token1Addr, abi: erc20MetaAbi, functionName: 'name' },\n { address: token1Addr, abi: erc20MetaAbi, functionName: 'decimals' },\n ],\n })\n\n return {\n poolAddress,\n token0: {\n address: token0Addr,\n symbol: t0Symbol,\n name: t0Name,\n decimals: Number(t0Decimals),\n },\n token1: {\n address: token1Addr,\n symbol: t1Symbol,\n name: t1Name,\n decimals: Number(t1Decimals),\n },\n fee: Number(fee),\n tickSpacing: Number(tickSpacing),\n currentTick: Number(slot0[1]),\n sqrtPriceX96: slot0[0],\n liquidity,\n feeProtocol: BigInt(slot0[5]),\n _meta,\n }\n}\n\nexport interface UniswapV3Liquidities {\n ticks: bigint[]\n liquidityNets: bigint[]\n _meta: BlockMeta\n}\n\nexport interface GetUniswapV3PoolLiquiditiesParams {\n client: PublicClient\n /** Uniswap V3 pool address */\n poolAddress: Address\n /** PanopticQuery address — must expose the public `getTickNetsV3` overload */\n queryAddress: Address\n /** Center tick of the range to scan */\n startTick: number\n /** Number of ticks on each side of startTick to scan */\n nTicks: bigint\n}\n\n/** Absolute Uniswap V3/V4 tick bounds. */\nconst TICK_MIN = -887272\nconst TICK_MAX = 887272\n\n/**\n * Clamp `nTicks` so the scan range\n * [scaled(startTick) − nTicks·tickSpacing, scaled(startTick) + nTicks·tickSpacing]\n * stays within [TICK_MIN, TICK_MAX]. Required because PanopticQuery's\n * getTickNetsV3/V4 revert with \"Tick out of bounds\" otherwise.\n */\nfunction clampNTicks(startTick: number, tickSpacing: number, nTicks: bigint): bigint {\n if (!Number.isInteger(tickSpacing) || tickSpacing <= 0) {\n throw new PanopticValidationError(\n `clampNTicks: tickSpacing must be a positive integer, got ${tickSpacing}`,\n )\n }\n const scaled = Math.trunc(startTick / tickSpacing) * tickSpacing\n const maxUp = Math.floor((TICK_MAX - scaled) / tickSpacing)\n const maxDown = Math.floor((scaled - TICK_MIN) / tickSpacing)\n const safe = BigInt(Math.max(0, Math.min(maxUp, maxDown)))\n return nTicks < safe ? nTicks : safe\n}\n\n/**\n * Fetch cumulative liquidity distribution for a Uniswap V3 pool via\n * `PanopticQuery.getTickNetsV3`. Does NOT require a Panoptic market to exist\n * for the pool — only a deployed PanopticQuery on the chain.\n */\nexport async function getUniswapV3PoolLiquidities(\n params: GetUniswapV3PoolLiquiditiesParams,\n): Promise<UniswapV3Liquidities> {\n const { client, poolAddress, queryAddress, startTick, nTicks } = params\n\n // We don't know tickSpacing here; PanopticQuery reads it from the pool.\n // For safety, clamp against the worst case (tickSpacing = 1).\n const safeN = clampNTicks(startTick, 1, nTicks)\n\n // Pin the read to a specific block so the returned ticks/liquidityNets\n // are consistent with the _meta we hand back.\n const _meta = await getBlockMeta({ client })\n const [ticks, liquidityNets] = await client.readContract({\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'getTickNetsV3',\n args: [poolAddress, startTick, safeN],\n blockNumber: _meta.blockNumber,\n })\n\n return {\n ticks: [...ticks],\n liquidityNets: [...liquidityNets],\n _meta,\n }\n}\n\n// ============================================================================\n// V4\n// ============================================================================\n\nexport interface UniswapV4PoolKey {\n currency0: Address\n currency1: Address\n /** Fee in hundredths of a bip (e.g. 500 = 0.05%) */\n fee: number\n tickSpacing: number\n hooks: Address\n}\n\nconst POOL_KEY_ABI_PARAMS = [\n {\n type: 'tuple',\n components: [\n { name: 'currency0', type: 'address' },\n { name: 'currency1', type: 'address' },\n { name: 'fee', type: 'uint24' },\n { name: 'tickSpacing', type: 'int24' },\n { name: 'hooks', type: 'address' },\n ],\n },\n] as const\n\n/** Compute the v4 poolId from a PoolKey: `keccak256(abi.encode(poolKey))`. */\nexport function computeV4PoolId(poolKey: UniswapV4PoolKey): Hex {\n return keccak256(\n encodeAbiParameters(POOL_KEY_ABI_PARAMS, [\n {\n currency0: poolKey.currency0,\n currency1: poolKey.currency1,\n fee: poolKey.fee,\n tickSpacing: poolKey.tickSpacing,\n hooks: poolKey.hooks,\n },\n ]),\n )\n}\n\nexport interface ResolveUniswapV4PoolKeyParams {\n client: PublicClient\n /** Uniswap V4 PoolManager address */\n poolManager: Address\n /** The bytes32 poolId hash */\n poolId: Hex\n /** Lower bound block for the scan (defaults to 0n) */\n fromBlock?: bigint\n /**\n * Per-request block range. Many RPCs cap getLogs at 10k/50k blocks;\n * defaults to 9_500 to stay under common limits.\n */\n chunkSize?: bigint\n /**\n * Number of chunked getLogs requests fired in parallel per batch.\n * Higher = faster but more likely to trip RPC rate limits. Default 8.\n */\n concurrency?: number\n}\n\n/**\n * Resolve a V4 PoolKey from its poolId by scanning `Initialize` event logs\n * on the PoolManager, filtered on the indexed `id` topic.\n *\n * Walks backwards from the latest block in `chunkSize` increments to\n * accommodate RPCs that cap getLogs ranges. Chunks are fired in parallel\n * batches of `concurrency` to keep wall-clock time low; returns as soon as\n * any batch produces a match. Throws if no event is found or if the\n * recomputed poolId does not match the queried one.\n */\nexport async function resolveUniswapV4PoolKey(\n _params: ResolveUniswapV4PoolKeyParams,\n): Promise<UniswapV4PoolKey> {\n // Disabled to save on RPC costs — the Initialize-event scan over the full\n // PoolManager history can issue dozens of eth_getLogs requests per\n // first-load resolution. Re-enable by uncommenting the body below.\n throw new PanopticValidationError(\n 'resolveUniswapV4PoolKey is disabled. ' +\n 'Resolve the V4 PoolKey via your indexer (e.g. Ponder) and pass it to getUniswapV4PoolInfo directly.',\n )\n\n /*\n const {\n client,\n poolManager,\n poolId,\n fromBlock = 0n,\n chunkSize = 9_500n,\n concurrency = 8,\n } = _params\n\n const latest = await client.getBlockNumber()\n\n // Pre-compute all chunk ranges, walking backwards.\n const ranges: Array<{ from: bigint; to: bigint }> = []\n let to = latest\n while (to >= fromBlock) {\n const from = to - chunkSize + 1n > fromBlock ? to - chunkSize + 1n : fromBlock\n ranges.push({ from, to })\n if (from === fromBlock) break\n to = from - 1n\n }\n\n let foundLogs: Awaited<ReturnType<PublicClient['getLogs']>> = []\n\n for (let i = 0; i < ranges.length; i += concurrency) {\n const batch = ranges.slice(i, i + concurrency)\n const results = await Promise.all(\n batch.map((r) =>\n client.getLogs({\n address: poolManager,\n event: uniswapV4PoolManagerAbi[0],\n args: { id: poolId },\n fromBlock: r.from,\n toBlock: r.to,\n }),\n ),\n )\n const hit = results.find((logs) => logs.length > 0)\n if (hit) {\n foundLogs = hit\n break\n }\n }\n\n if (foundLogs.length === 0) {\n throw new Error(`No Initialize event found for poolId ${poolId} on PoolManager ${poolManager}`)\n }\n\n const args = (foundLogs[0] as { args: Record<string, unknown> }).args as {\n id: Hex\n currency0: Address\n currency1: Address\n fee: number\n tickSpacing: number\n hooks: Address\n }\n\n const key: UniswapV4PoolKey = {\n currency0: args.currency0,\n currency1: args.currency1,\n fee: Number(args.fee),\n tickSpacing: Number(args.tickSpacing),\n hooks: args.hooks,\n }\n\n const recomputed = computeV4PoolId(key)\n if (recomputed.toLowerCase() !== poolId.toLowerCase()) {\n throw new Error(\n `Recomputed poolId ${recomputed} does not match queried ${poolId} — PoolKey encoding mismatch`,\n )\n }\n\n return key\n */\n}\n\n/**\n * Slot0 + liquidity for a V4 pool by poolId — does NOT require the PoolKey.\n * Used to render basic info (currentTick, sqrtPriceX96, liquidity) when the\n * PoolKey is unknown.\n */\nexport interface UniswapV4PoolBasicState {\n poolId: Hex\n sqrtPriceX96: bigint\n currentTick: number\n /** Packed directional protocol fee: `oneForZero << 12 | zeroForOne`, in pips. */\n protocolFee: bigint\n /** Dynamic LP fee from slot0 (NOT necessarily the static PoolKey.fee). */\n lpFee: number\n liquidity: bigint\n _meta: BlockMeta\n}\n\nexport interface GetUniswapV4PoolBasicStateParams {\n client: Pick<PublicClient, 'getBlock' | 'multicall'>\n stateViewAddress: Address\n poolId: Hex\n}\n\nexport async function getUniswapV4PoolBasicState(\n params: GetUniswapV4PoolBasicStateParams,\n): Promise<UniswapV4PoolBasicState> {\n const { client, stateViewAddress, poolId } = params\n // Pin slot0 + liquidity to the same block as the returned _meta.\n const _meta = await getBlockMeta({ client })\n const [slot0, liquidity] = await client.multicall({\n allowFailure: false,\n blockNumber: _meta.blockNumber,\n contracts: [\n { address: stateViewAddress, abi: stateViewAbi, functionName: 'getSlot0', args: [poolId] },\n {\n address: stateViewAddress,\n abi: stateViewAbi,\n functionName: 'getLiquidity',\n args: [poolId],\n },\n ],\n })\n return {\n poolId,\n sqrtPriceX96: slot0[0],\n currentTick: Number(slot0[1]),\n protocolFee: BigInt(slot0[2]),\n lpFee: Number(slot0[3]),\n liquidity,\n _meta,\n }\n}\n\nexport interface UniswapV4PoolInfo {\n poolId: Hex\n poolKey: UniswapV4PoolKey\n token0: UniswapV3PoolToken\n token1: UniswapV3PoolToken\n fee: number\n tickSpacing: number\n hooks: Address\n currentTick: number\n sqrtPriceX96: bigint\n /** Packed directional protocol fee: `oneForZero << 12 | zeroForOne`, in pips. */\n protocolFee: bigint\n liquidity: bigint\n _meta: BlockMeta\n}\n\nexport interface GetUniswapV4PoolInfoParams {\n client: Pick<PublicClient, 'getBlock' | 'multicall'>\n stateViewAddress: Address\n poolKey: UniswapV4PoolKey\n}\n\n/** Synthetic token metadata for native ETH (currency address `0x0`). */\nconst NATIVE_ETH_META = { symbol: 'ETH', name: 'Ether', decimals: 18 } as const\n\nasync function readErc20Meta(\n client: Pick<PublicClient, 'multicall'>,\n address: Address,\n blockNumber?: bigint,\n): Promise<{ symbol: string; name: string; decimals: number }> {\n const [symbol, name, decimals] = await client.multicall({\n allowFailure: false,\n blockNumber,\n contracts: [\n { address, abi: erc20MetaAbi, functionName: 'symbol' },\n { address, abi: erc20MetaAbi, functionName: 'name' },\n { address, abi: erc20MetaAbi, functionName: 'decimals' },\n ],\n })\n return { symbol, name, decimals: Number(decimals) }\n}\n\n/**\n * Fetch core data for a Uniswap V4 pool directly from chain.\n *\n * Does NOT require a Panoptic deployment — only StateView + (for non-native\n * currencies) ERC20s. Caller must supply a resolved PoolKey (see\n * `resolveUniswapV4PoolKey`).\n */\nexport async function getUniswapV4PoolInfo(\n params: GetUniswapV4PoolInfoParams,\n): Promise<UniswapV4PoolInfo> {\n const { client, stateViewAddress, poolKey } = params\n const poolId = computeV4PoolId(poolKey)\n\n // Skip ERC20 metadata reads for native ETH (currency `0x0`) so the\n // multicall doesn't revert, and substitute synthetic metadata.\n const c0IsNative = poolKey.currency0 === zeroAddress\n const c1IsNative = poolKey.currency1 === zeroAddress\n\n const _meta = await getBlockMeta({ client })\n\n // State reads (slot0 + liquidity) batched in one multicall.\n const [slot0, liquidity] = await client.multicall({\n allowFailure: false,\n blockNumber: _meta.blockNumber,\n contracts: [\n { address: stateViewAddress, abi: stateViewAbi, functionName: 'getSlot0', args: [poolId] },\n {\n address: stateViewAddress,\n abi: stateViewAbi,\n functionName: 'getLiquidity',\n args: [poolId],\n },\n ],\n })\n\n // ERC20 metadata (skipped for native ETH) batched in a second multicall,\n // pinned to the same block as the state reads above for consistency.\n const token0Meta = c0IsNative\n ? { ...NATIVE_ETH_META }\n : await readErc20Meta(client, poolKey.currency0, _meta.blockNumber)\n const token1Meta = c1IsNative\n ? { ...NATIVE_ETH_META }\n : await readErc20Meta(client, poolKey.currency1, _meta.blockNumber)\n\n return {\n poolId,\n poolKey,\n token0: { address: poolKey.currency0, ...token0Meta },\n token1: { address: poolKey.currency1, ...token1Meta },\n fee: poolKey.fee,\n tickSpacing: poolKey.tickSpacing,\n hooks: poolKey.hooks,\n currentTick: Number(slot0[1]),\n sqrtPriceX96: slot0[0],\n protocolFee: BigInt(slot0[2]),\n liquidity,\n _meta,\n }\n}\n\nexport interface GetUniswapV4PoolLiquiditiesParams {\n client: PublicClient\n queryAddress: Address\n poolManager: Address\n poolId: Hex\n tickSpacing: number\n startTick: number\n nTicks: bigint\n}\n\n/**\n * Fetch cumulative liquidity distribution for a Uniswap V4 pool via\n * `PanopticQuery.getTickNetsV4`. Does NOT require a Panoptic market for the pool.\n */\nexport async function getUniswapV4PoolLiquidities(\n params: GetUniswapV4PoolLiquiditiesParams,\n): Promise<UniswapV3Liquidities> {\n const { client, queryAddress, poolManager, poolId, tickSpacing, startTick, nTicks } = params\n\n const safeN = clampNTicks(startTick, tickSpacing, nTicks)\n\n // Pin to a specific block so the returned ticks/liquidityNets match _meta.\n const _meta = await getBlockMeta({ client })\n const [ticks, liquidityNets] = await client.readContract({\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'getTickNetsV4',\n args: [poolManager, poolId, tickSpacing, startTick, safeN],\n blockNumber: _meta.blockNumber,\n })\n\n return {\n ticks: [...ticks],\n liquidityNets: [...liquidityNets],\n _meta,\n }\n}\n","export const StateViewAbi = [\n {\n inputs: [{ internalType: 'contract IPoolManager', name: '_poolManager', type: 'address' }],\n stateMutability: 'nonpayable',\n type: 'constructor',\n },\n {\n inputs: [{ internalType: 'PoolId', name: 'poolId', type: 'bytes32' }],\n name: 'getFeeGrowthGlobals',\n outputs: [\n { internalType: 'uint256', name: 'feeGrowthGlobal0', type: 'uint256' },\n { internalType: 'uint256', name: 'feeGrowthGlobal1', type: 'uint256' },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n { internalType: 'PoolId', name: 'poolId', type: 'bytes32' },\n { internalType: 'int24', name: 'tickLower', type: 'int24' },\n { internalType: 'int24', name: 'tickUpper', type: 'int24' },\n ],\n name: 'getFeeGrowthInside',\n outputs: [\n { internalType: 'uint256', name: 'feeGrowthInside0X128', type: 'uint256' },\n { internalType: 'uint256', name: 'feeGrowthInside1X128', type: 'uint256' },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [{ internalType: 'PoolId', name: 'poolId', type: 'bytes32' }],\n name: 'getLiquidity',\n outputs: [{ internalType: 'uint128', name: 'liquidity', type: 'uint128' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n { internalType: 'PoolId', name: 'poolId', type: 'bytes32' },\n { internalType: 'bytes32', name: 'positionId', type: 'bytes32' },\n ],\n name: 'getPositionInfo',\n outputs: [\n { internalType: 'uint128', name: 'liquidity', type: 'uint128' },\n { internalType: 'uint256', name: 'feeGrowthInside0LastX128', type: 'uint256' },\n { internalType: 'uint256', name: 'feeGrowthInside1LastX128', type: 'uint256' },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n { internalType: 'PoolId', name: 'poolId', type: 'bytes32' },\n { internalType: 'address', name: 'owner', type: 'address' },\n { internalType: 'int24', name: 'tickLower', type: 'int24' },\n { internalType: 'int24', name: 'tickUpper', type: 'int24' },\n { internalType: 'bytes32', name: 'salt', type: 'bytes32' },\n ],\n name: 'getPositionInfo',\n outputs: [\n { internalType: 'uint128', name: 'liquidity', type: 'uint128' },\n { internalType: 'uint256', name: 'feeGrowthInside0LastX128', type: 'uint256' },\n { internalType: 'uint256', name: 'feeGrowthInside1LastX128', type: 'uint256' },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n { internalType: 'PoolId', name: 'poolId', type: 'bytes32' },\n { internalType: 'bytes32', name: 'positionId', type: 'bytes32' },\n ],\n name: 'getPositionLiquidity',\n outputs: [{ internalType: 'uint128', name: 'liquidity', type: 'uint128' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [{ internalType: 'PoolId', name: 'poolId', type: 'bytes32' }],\n name: 'getSlot0',\n outputs: [\n { internalType: 'uint160', name: 'sqrtPriceX96', type: 'uint160' },\n { internalType: 'int24', name: 'tick', type: 'int24' },\n { internalType: 'uint24', name: 'protocolFee', type: 'uint24' },\n { internalType: 'uint24', name: 'lpFee', type: 'uint24' },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n { internalType: 'PoolId', name: 'poolId', type: 'bytes32' },\n { internalType: 'int16', name: 'tick', type: 'int16' },\n ],\n name: 'getTickBitmap',\n outputs: [{ internalType: 'uint256', name: 'tickBitmap', type: 'uint256' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n { internalType: 'PoolId', name: 'poolId', type: 'bytes32' },\n { internalType: 'int24', name: 'tick', type: 'int24' },\n ],\n name: 'getTickFeeGrowthOutside',\n outputs: [\n { internalType: 'uint256', name: 'feeGrowthOutside0X128', type: 'uint256' },\n { internalType: 'uint256', name: 'feeGrowthOutside1X128', type: 'uint256' },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n { internalType: 'PoolId', name: 'poolId', type: 'bytes32' },\n { internalType: 'int24', name: 'tick', type: 'int24' },\n ],\n name: 'getTickInfo',\n outputs: [\n { internalType: 'uint128', name: 'liquidityGross', type: 'uint128' },\n { internalType: 'int128', name: 'liquidityNet', type: 'int128' },\n { internalType: 'uint256', name: 'feeGrowthOutside0X128', type: 'uint256' },\n { internalType: 'uint256', name: 'feeGrowthOutside1X128', type: 'uint256' },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n { internalType: 'PoolId', name: 'poolId', type: 'bytes32' },\n { internalType: 'int24', name: 'tick', type: 'int24' },\n ],\n name: 'getTickLiquidity',\n outputs: [\n { internalType: 'uint128', name: 'liquidityGross', type: 'uint128' },\n { internalType: 'int128', name: 'liquidityNet', type: 'int128' },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'poolManager',\n outputs: [{ internalType: 'contract IPoolManager', name: '', type: 'address' }],\n stateMutability: 'view',\n type: 'function',\n },\n] as const\n","/**\n * Direct Uniswap V3/V4 LP position reads — no Panoptic deployment required.\n *\n * Fetches a position's liquidity, tick range and uncollected fees:\n * - V3: `NonfungiblePositionManager.positions` + a `collect` simulation\n * (exact fees, including tokensOwed and unaccrued feeGrowth).\n * - V4: `StateView.getPositionInfo` + `getFeeGrowthInside` and the\n * feeGrowthInside delta math from v4-core's `Position.calculatePositionFeesAccrued`.\n *\n * @module v2/reads/uniswapLpPosition\n */\n\nimport type { Address, Hex, PublicClient } from 'viem'\nimport { BaseError, ContractFunctionRevertedError, ExecutionRevertedError, toHex } from 'viem'\n\nimport { StateViewAbi } from '../../../abis/StateView'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport type { BlockMeta } from '../types'\n\n// The root NonFungiblePositionManagerAbi flattens collect's CollectParams\n// struct into scalar inputs, which yields a different function selector than\n// the deployed contract's `collect((uint256,address,uint128,uint128))` — so a\n// correct minimal ABI is defined here.\nconst nfpmAbi = [\n {\n type: 'function',\n name: 'positions',\n inputs: [{ name: 'tokenId', type: 'uint256' }],\n outputs: [\n { name: 'nonce', type: 'uint96' },\n { name: 'operator', type: 'address' },\n { name: 'token0', type: 'address' },\n { name: 'token1', type: 'address' },\n { name: 'fee', type: 'uint24' },\n { name: 'tickLower', type: 'int24' },\n { name: 'tickUpper', type: 'int24' },\n { name: 'liquidity', type: 'uint128' },\n { name: 'feeGrowthInside0LastX128', type: 'uint256' },\n { name: 'feeGrowthInside1LastX128', type: 'uint256' },\n { name: 'tokensOwed0', type: 'uint128' },\n { name: 'tokensOwed1', type: 'uint128' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'collect',\n inputs: [\n {\n name: 'params',\n type: 'tuple',\n components: [\n { name: 'tokenId', type: 'uint256' },\n { name: 'recipient', type: 'address' },\n { name: 'amount0Max', type: 'uint128' },\n { name: 'amount1Max', type: 'uint128' },\n ],\n },\n ],\n outputs: [\n { name: 'amount0', type: 'uint256' },\n { name: 'amount1', type: 'uint256' },\n ],\n stateMutability: 'payable',\n },\n] as const\n\nconst MAX_UINT128 = 2n ** 128n - 1n\nconst MAX_UINT256 = 2n ** 256n - 1n\nconst Q128 = 2n ** 128n\n\n/** Liquidity, range and uncollected fees for a single LP position. */\nexport interface UniswapLpPositionState {\n liquidity: bigint\n tickLower: number\n tickUpper: number\n /** Uncollected fees in token0, inclusive of tokensOwed (V3). */\n fees0: bigint\n /** Uncollected fees in token1, inclusive of tokensOwed (V3). */\n fees1: bigint\n /** Block metadata the reads were pinned to. */\n _meta: BlockMeta\n}\n\n/**\n * Whether an error thrown by a viem contract call is an on-chain revert (as\n * opposed to a transport/RPC failure such as a timeout or rate limit).\n */\nfunction isContractRevert(error: unknown): boolean {\n return (\n error instanceof BaseError &&\n error.walk(\n (err) =>\n err instanceof ContractFunctionRevertedError || err instanceof ExecutionRevertedError,\n ) != null\n )\n}\n\nexport interface UniswapV3LpPositionState extends UniswapLpPositionState {\n token0: Address\n token1: Address\n /** Fee tier in hundredths of a bip (e.g. 500 = 0.05%). */\n fee: number\n}\n\nexport interface GetUniswapV3LpPositionStateParams {\n client: PublicClient\n /** NonfungiblePositionManager address. */\n nfpmAddress: Address\n /** ERC721 tokenId of the position. */\n tokenId: bigint\n /** Current owner of the position NFT (used as `account` for the collect simulation). */\n owner: Address\n /** Optional historical block to pin the position read to. */\n blockNumber?: bigint\n}\n\n/**\n * Fetch a Uniswap V3 LP position's state and uncollected fees.\n *\n * Fees come from simulating `collect` with max amounts as the owner — one\n * eth_call returning the exact claimable amounts (tokensOwed + fee growth\n * since the last poke). The simulation is best-effort: if it reverts (e.g.\n * an empty position), fees fall back to 0.\n */\nexport async function getUniswapV3LpPositionState(\n params: GetUniswapV3LpPositionStateParams,\n): Promise<UniswapV3LpPositionState> {\n const { client, nfpmAddress, tokenId, owner, blockNumber } = params\n\n // Pin both reads to the same block so position state and fees are\n // self-consistent with the returned _meta. The collect simulation cannot be\n // folded into a Multicall3 batch: it must run with msg.sender = owner.\n const _meta = await getBlockMeta({ client, blockNumber })\n\n const position = await client.readContract({\n address: nfpmAddress,\n abi: nfpmAbi,\n functionName: 'positions',\n args: [tokenId],\n blockNumber: _meta.blockNumber,\n })\n const [, , token0, token1, fee, tickLower, tickUpper, liquidity] = position\n\n let fees0 = 0n\n let fees1 = 0n\n try {\n const { result } = await client.simulateContract({\n address: nfpmAddress,\n abi: nfpmAbi,\n functionName: 'collect',\n args: [{ tokenId, recipient: owner, amount0Max: MAX_UINT128, amount1Max: MAX_UINT128 }],\n account: owner,\n blockNumber: _meta.blockNumber,\n })\n ;[fees0, fees1] = result\n } catch (error) {\n // collect reverts for some empty positions — report zero fees. Transport\n // and RPC failures propagate so callers don't mistake them for no fees.\n if (!isContractRevert(error)) throw error\n }\n\n return {\n token0,\n token1,\n fee: Number(fee),\n tickLower: Number(tickLower),\n tickUpper: Number(tickUpper),\n liquidity,\n fees0,\n fees1,\n _meta,\n }\n}\n\n/**\n * Uncollected fees from a feeGrowthInside delta, mirroring v4-core's\n * `Position.calculatePositionFeesAccrued`: the subtraction wraps around\n * uint256 (feeGrowthInside can legitimately underflow in-protocol).\n */\nexport function feesFromFeeGrowthDelta(\n feeGrowthInsideCurrentX128: bigint,\n feeGrowthInsideLastX128: bigint,\n liquidity: bigint,\n): bigint {\n const delta = (feeGrowthInsideCurrentX128 - feeGrowthInsideLastX128) & MAX_UINT256\n return (delta * liquidity) / Q128\n}\n\nexport interface GetUniswapV4LpPositionStateParams {\n client: PublicClient\n /** StateView address. */\n stateViewAddress: Address\n /** Uniswap v4 PositionManager (posm) address — the position owner inside PoolManager. */\n positionManagerAddress: Address\n /** The bytes32 poolId hash. */\n poolId: Hex\n /** ERC721 tokenId of the position (posm salt = bytes32(tokenId)). */\n tokenId: bigint\n tickLower: number\n tickUpper: number\n /** Optional historical block to pin the position read to. */\n blockNumber?: bigint\n}\n\n/**\n * Fetch a Uniswap V4 LP position's state and uncollected fees via StateView.\n *\n * The position inside PoolManager is keyed by (positionManager, tickLower,\n * tickUpper, salt) where posm uses `bytes32(tokenId)` as the salt. Fees on\n * pools with fee-taking hooks may be approximate.\n */\nexport async function getUniswapV4LpPositionState(\n params: GetUniswapV4LpPositionStateParams,\n): Promise<UniswapLpPositionState> {\n const {\n client,\n stateViewAddress,\n positionManagerAddress,\n poolId,\n tokenId,\n tickLower,\n tickUpper,\n blockNumber,\n } = params\n\n const salt = toHex(tokenId, { size: 32 })\n\n // Pin both StateView reads to the same block as the returned _meta.\n const _meta = await getBlockMeta({ client, blockNumber })\n\n const [positionInfo, feeGrowthInside] = await client.multicall({\n allowFailure: false,\n blockNumber: _meta.blockNumber,\n contracts: [\n {\n address: stateViewAddress,\n abi: StateViewAbi,\n functionName: 'getPositionInfo',\n args: [poolId, positionManagerAddress, tickLower, tickUpper, salt],\n },\n {\n address: stateViewAddress,\n abi: StateViewAbi,\n functionName: 'getFeeGrowthInside',\n args: [poolId, tickLower, tickUpper],\n },\n ],\n })\n\n const [liquidity, feeGrowthInside0LastX128, feeGrowthInside1LastX128] = positionInfo\n const [feeGrowthInside0X128, feeGrowthInside1X128] = feeGrowthInside\n\n return {\n liquidity,\n tickLower,\n tickUpper,\n fees0: feesFromFeeGrowthDelta(feeGrowthInside0X128, feeGrowthInside0LastX128, liquidity),\n fees1: feesFromFeeGrowthDelta(feeGrowthInside1X128, feeGrowthInside1LastX128, liquidity),\n _meta,\n }\n}\n","/**\n * Historical price reads for the Panoptic v2 SDK.\n *\n * Fetches slot0 (tick + sqrtPriceX96) across a series of historical blocks\n * for price-over-time charting. All block reads are parallelized via\n * Promise.all (viem auto-batches into multicall).\n *\n * @module v2/reads/priceHistory\n */\n\nimport type { PublicClient } from 'viem'\n\nimport { stateViewAbi } from '../abis/stateView'\nimport { uniswapV3PoolAbi } from '../abis/uniswapV3Pool'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport type { BlockMeta } from '../types'\nimport type { PoolVersionConfig } from '../types/poolConfig'\n\n// ── Types ──────────────────────────────────────────────────────────────\n\n/** A single price snapshot at a particular block. */\nexport interface PriceSnapshot {\n /** Block number (undefined if queried as latest) */\n blockNumber: bigint | undefined\n /** Current tick of the pool at this block */\n tick: number\n /** sqrtPriceX96 at this block */\n sqrtPriceX96: bigint\n}\n\n/** Result from getPriceHistory. */\nexport interface PriceHistoryResult {\n /** Snapshots in the same order as input blockNumbers */\n snapshots: PriceSnapshot[]\n /** Block metadata for the latest block used */\n _meta: BlockMeta\n}\n\n/** Parameters for getPriceHistory. */\nexport interface GetPriceHistoryParams {\n /** viem PublicClient */\n client: PublicClient\n /** Block numbers to query; undefined entries resolve to latest */\n blockNumbers: (bigint | undefined)[]\n /** Pool version config (carries pool address / StateView + poolId) */\n poolConfig: PoolVersionConfig\n /** Pre-fetched block metadata (skips an extra eth_getBlockByNumber if provided) */\n _meta?: BlockMeta\n}\n\n// ── Main function ──────────────────────────────────────────────────────\n\n/**\n * Get historical price data (tick + sqrtPriceX96) for a pool across multiple blocks.\n *\n * @param params - The parameters\n * @returns Price snapshots at each block\n *\n * @example\n * ```typescript\n * const { snapshots } = await getPriceHistory({\n * client,\n * blockNumbers: [18000000n, 18000100n, 18000200n],\n * poolConfig: { version: 'v3', poolAddress: '0x...' },\n * })\n *\n * for (const snap of snapshots) {\n * console.log(`Block ${snap.blockNumber}: tick=${snap.tick}`)\n * }\n * ```\n */\nexport async function getPriceHistory(params: GetPriceHistoryParams): Promise<PriceHistoryResult> {\n const { client, blockNumbers, poolConfig } = params\n\n if (blockNumbers.length === 0) {\n const _meta = params._meta ?? (await getBlockMeta({ client }))\n return { snapshots: [], _meta }\n }\n\n // Fire one slot0 read per block. Calls at different historical blocks cannot\n // be coalesced into one multicall, so callers should not poll this path.\n const slot0Requests = blockNumbers.map((bn) => fetchSlot0(client, bn, poolConfig))\n\n const [slot0Results, _meta] = await Promise.all([\n Promise.all(slot0Requests),\n params._meta ? Promise.resolve(params._meta) : getBlockMeta({ client }),\n ])\n\n const snapshots: PriceSnapshot[] = slot0Results.map((result, i) => ({\n blockNumber: blockNumbers[i],\n tick: result.tick,\n sqrtPriceX96: result.sqrtPriceX96,\n }))\n\n return { snapshots, _meta }\n}\n\n// ── Internals ──────────────────────────────────────────────────────────\n\ninterface Slot0Data {\n tick: number\n sqrtPriceX96: bigint\n}\n\nasync function fetchSlot0(\n client: PublicClient,\n blockNumber: bigint | undefined,\n poolConfig: PoolVersionConfig,\n): Promise<Slot0Data> {\n if (poolConfig.version === 'v3') {\n const result = await client.readContract({\n address: poolConfig.poolAddress,\n abi: uniswapV3PoolAbi,\n functionName: 'slot0',\n blockNumber,\n })\n return {\n sqrtPriceX96: result[0],\n tick: result[1],\n }\n } else {\n const result = await client.readContract({\n address: poolConfig.stateViewAddress,\n abi: stateViewAbi,\n functionName: 'getSlot0',\n args: [poolConfig.poolId],\n blockNumber,\n })\n return {\n sqrtPriceX96: result[0],\n tick: result[1],\n }\n }\n}\n","/**\n * Position enrichment data for UI display.\n *\n * Batches all contract reads needed to enrich subgraph position data with\n * on-chain premia, portfolio values, and collateral requirements.\n *\n * @module v2/reads/enrichment\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { panopticPoolV2Abi, panopticQueryAbi } from '../../../generated'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport { PanopticError } from '../errors'\nimport type { BlockMeta } from '../types'\nimport { decodeLeftRightUnsigned } from '../writes/utils'\n\n/**\n * Error thrown when an enrichment contract call fails for a specific position.\n */\nexport class EnrichmentCallError extends PanopticError {\n /** The tokenId of the position that failed */\n readonly tokenId: bigint\n /** The name of the failing call */\n readonly callName: string\n\n constructor(tokenId: bigint, callName: string, cause?: unknown) {\n super(\n `Enrichment call \"${callName}\" failed for tokenId ${tokenId}`,\n cause instanceof Error ? cause : undefined,\n )\n this.tokenId = tokenId\n this.callName = callName\n }\n}\n\n/**\n * Input describing a position for enrichment.\n */\nexport interface PositionInput {\n /** The tokenId (256-bit identifier) */\n tokenId: bigint\n /** Whether the position is currently open */\n isOpen: boolean\n /** Tick at time of mint */\n tickAtMint: number\n /** Account address that owns the position */\n account: Address\n /** Pool address the position belongs to */\n poolAddress: Address\n /** Tick at burn (closed positions only) */\n tickAtBurn?: number\n /** Block number of the burn tx (closed positions only) */\n burnBlockNumber?: bigint\n /** Premium in token0 from subgraph (closed positions only) */\n burnPremium0?: bigint\n /** Premium in token1 from subgraph (closed positions only) */\n burnPremium1?: bigint\n}\n\n/**\n * Enrichment result for a single position.\n *\n * Values are in raw token units (token0 and token1), not asset/quote.\n * The UI maps these to asset/quote based on isAssetToken0.\n */\nexport interface PositionEnrichmentResult {\n /** Net premia owed: shortPremium - longPremium for token0 (open); burnPremium0 for closed */\n premiaOwed0: bigint\n /** Net premia owed: shortPremium - longPremium for token1 (open); burnPremium1 for closed */\n premiaOwed1: bigint\n /** Portfolio value in token0 at current tick (open) or burn tick (closed) */\n portfolioValue0: bigint\n /** Portfolio value in token1 at current tick (open) or burn tick (closed) */\n portfolioValue1: bigint\n /** Portfolio value in token0 at mint tick */\n portfolioValueAtMint0: bigint\n /** Portfolio value in token1 at mint tick */\n portfolioValueAtMint1: bigint\n /**\n * Per-token collateral requirement from `getFullPositionsData.collateralRequirements[]`.\n * These are NOT cross-margined — each is in its own token denomination.\n * For closed positions these are 0n (collateral is moot).\n */\n collateralReqToken0: bigint\n collateralReqToken1: bigint\n}\n\n/**\n * Parameters for getPositionEnrichmentData.\n */\nexport interface GetPositionEnrichmentDataParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticQuery helper contract address */\n queryAddress: Address\n /** Positions to enrich */\n positions: PositionInput[]\n /** Current pool tick (used for open position portfolio values) */\n currentTick: number\n /** Optional block number for open position reads */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata */\n _meta?: BlockMeta\n}\n\n/**\n * Result from getPositionEnrichmentData.\n */\nexport interface GetPositionEnrichmentDataResult {\n /** Enrichment data keyed by tokenId string */\n byTokenId: Map<string, PositionEnrichmentResult>\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Fetch enrichment data (premia, portfolio values, collateral requirements) for a set of positions.\n *\n * Batches all needed contract reads into efficient multicalls:\n * - **Open positions**: 3 calls per position in a single multicall at current block:\n * 1. `getFullPositionsData` → premia + collateral requirements\n * 2. `getPortfolioValue` at currentTick → current portfolio value\n * 3. `getPortfolioValue` at mintTick → portfolio value at mint\n * - **Closed positions**: 2 calls per position at `burnBlockNumber - 1`:\n * 1. `getPortfolioValue` at burnTick → portfolio value at close\n * 2. `getPortfolioValue` at mintTick → portfolio value at mint\n * (premia come from subgraph `burnPremium0/1`)\n *\n * ## Same-Block Guarantee\n * Open position data is fetched at a single block number.\n * Closed position data is fetched at `burnBlockNumber - 1` (per position).\n *\n * @param params - The parameters\n * @returns Map of tokenId → enrichment data, with block metadata\n */\nexport async function getPositionEnrichmentData(\n params: GetPositionEnrichmentDataParams,\n): Promise<GetPositionEnrichmentDataResult> {\n const { client, queryAddress, positions, currentTick, blockNumber } = params\n\n // Fetch a single block metadata for the entire enrichment result\n const _meta = params._meta ?? (await getBlockMeta({ client, blockNumber }))\n\n if (positions.length === 0) {\n return { byTokenId: new Map(), _meta }\n }\n\n const openPositions = positions.filter((p) => p.isOpen)\n const closedPositions = positions.filter((p) => !p.isOpen)\n\n const byTokenId = new Map<string, PositionEnrichmentResult>()\n\n // Process open and closed positions in parallel\n await Promise.all([\n processOpenPositions(client, queryAddress, openPositions, currentTick, blockNumber, _meta),\n processClosedPositions(client, queryAddress, closedPositions),\n ]).then(([openResults, closedResults]) => {\n // Merge results into byTokenId map\n for (const [key, value] of openResults.entries) {\n byTokenId.set(key, value)\n }\n for (const [key, value] of closedResults) {\n byTokenId.set(key, value)\n }\n })\n\n return { byTokenId, _meta }\n}\n\n/** Number of multicall contracts per open position */\nconst OPEN_CALLS_PER_POSITION = 3\n/** Number of multicall contracts per closed position */\nconst CLOSED_CALLS_PER_POSITION = 2\n\n/**\n * Process open positions: single multicall with 5 calls per position.\n */\nasync function processOpenPositions(\n client: PublicClient,\n queryAddress: Address,\n positions: PositionInput[],\n currentTick: number,\n blockNumber: bigint | undefined,\n _meta: BlockMeta,\n): Promise<{ entries: [string, PositionEnrichmentResult][] }> {\n if (positions.length === 0) {\n return { entries: [] }\n }\n\n const targetBlockNumber = blockNumber ?? _meta.blockNumber\n\n // Build multicall contracts: 3 calls per position\n const contracts = positions.flatMap((p) => [\n // 1. getFullPositionsData → premia + collateral requirements\n {\n address: p.poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData' as const,\n args: [p.account, true, [p.tokenId]] as const,\n },\n // 2. getPortfolioValue at currentTick\n {\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'getPortfolioValue' as const,\n args: [p.poolAddress, p.account, currentTick, [p.tokenId]] as const,\n },\n // 3. getPortfolioValue at mintTick\n {\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'getPortfolioValue' as const,\n args: [p.poolAddress, p.account, p.tickAtMint, [p.tokenId]] as const,\n },\n ])\n\n const multicallResults = await client.multicall({\n contracts,\n blockNumber: targetBlockNumber,\n allowFailure: true,\n })\n\n const entries: [string, PositionEnrichmentResult][] = []\n\n for (let i = 0; i < positions.length; i++) {\n const position = positions[i]\n const baseIdx = i * OPEN_CALLS_PER_POSITION\n\n const premiaResult = multicallResults[baseIdx]\n const portfolioResult = multicallResults[baseIdx + 1]\n const portfolioAtMintResult = multicallResults[baseIdx + 2]\n\n if (premiaResult.status !== 'success') {\n throw new EnrichmentCallError(position.tokenId, 'getFullPositionsData', premiaResult.error)\n }\n if (portfolioResult.status !== 'success') {\n throw new EnrichmentCallError(\n position.tokenId,\n 'getPortfolioValue (currentTick)',\n portfolioResult.error,\n )\n }\n if (portfolioAtMintResult.status !== 'success') {\n throw new EnrichmentCallError(\n position.tokenId,\n 'getPortfolioValue (mintTick)',\n portfolioAtMintResult.error,\n )\n }\n\n // Decode getFullPositionsData: [shortPremium, longPremium, balances[], collateralReqs[], netPremia[]]\n const [shortPremiumPacked, longPremiumPacked, , collateralReqsPacked] = premiaResult.result as [\n bigint,\n bigint,\n bigint[],\n bigint[],\n bigint[],\n ]\n const shortPremium = decodeLeftRightUnsigned(shortPremiumPacked)\n const longPremium = decodeLeftRightUnsigned(longPremiumPacked)\n\n const premiaOwed0 = shortPremium.right - longPremium.right // token0\n const premiaOwed1 = shortPremium.left - longPremium.left // token1\n\n // Decode per-token collateral requirements from collateralReqs[0] (LeftRightUnsigned)\n const collateralReq = decodeLeftRightUnsigned(collateralReqsPacked[0] ?? 0n)\n\n // Decode portfolio values\n const [portfolioValue0, portfolioValue1] = portfolioResult.result as [bigint, bigint]\n const [portfolioValueAtMint0, portfolioValueAtMint1] = portfolioAtMintResult.result as [\n bigint,\n bigint,\n ]\n\n entries.push([\n position.tokenId.toString(),\n {\n premiaOwed0,\n premiaOwed1,\n portfolioValue0,\n portfolioValue1,\n portfolioValueAtMint0,\n portfolioValueAtMint1,\n collateralReqToken0: collateralReq.right,\n collateralReqToken1: collateralReq.left,\n },\n ])\n }\n\n return { entries }\n}\n\n/**\n * Process closed positions: per-position calls at burnBlockNumber - 1.\n *\n * Returns entries array (not a map) to merge into the final result.\n */\nasync function processClosedPositions(\n client: PublicClient,\n queryAddress: Address,\n positions: PositionInput[],\n): Promise<[string, PositionEnrichmentResult][]> {\n if (positions.length === 0) return []\n\n // Group positions by burnBlockNumber for batch efficiency\n const byBlock = new Map<bigint, PositionInput[]>()\n for (const p of positions) {\n if (p.burnBlockNumber == null) continue\n const readBlock = p.burnBlockNumber - 1n\n const group = byBlock.get(readBlock) ?? []\n group.push(p)\n byBlock.set(readBlock, group)\n }\n\n const entries: [string, PositionEnrichmentResult][] = []\n\n // Process each block group\n await Promise.all(\n Array.from(byBlock.entries()).map(async ([readBlock, blockPositions]) => {\n // Build multicall contracts: 2 calls per position\n const contracts = blockPositions.flatMap((p) => [\n // 1. getPortfolioValue at burnTick\n {\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'getPortfolioValue' as const,\n args: [p.poolAddress, p.account, p.tickAtBurn ?? 0, [p.tokenId]] as const,\n },\n // 2. getPortfolioValue at mintTick\n {\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'getPortfolioValue' as const,\n args: [p.poolAddress, p.account, p.tickAtMint, [p.tokenId]] as const,\n },\n ])\n\n const multicallResults = await client.multicall({\n contracts,\n blockNumber: readBlock,\n allowFailure: true,\n })\n\n for (let i = 0; i < blockPositions.length; i++) {\n const position = blockPositions[i]\n const baseIdx = i * CLOSED_CALLS_PER_POSITION\n\n const portfolioAtBurnResult = multicallResults[baseIdx]\n const portfolioAtMintResult = multicallResults[baseIdx + 1]\n\n // Closed position reads can fail legitimately (e.g. position minted and burned\n // in the same block — at burnBlock-1 it doesn't exist yet). Fall back to zeros.\n const [portfolioValue0, portfolioValue1] =\n portfolioAtBurnResult.status === 'success'\n ? (portfolioAtBurnResult.result as [bigint, bigint])\n : [0n, 0n]\n const [portfolioValueAtMint0, portfolioValueAtMint1] =\n portfolioAtMintResult.status === 'success'\n ? (portfolioAtMintResult.result as [bigint, bigint])\n : [0n, 0n]\n\n entries.push([\n position.tokenId.toString(),\n {\n premiaOwed0: position.burnPremium0 ?? 0n,\n premiaOwed1: position.burnPremium1 ?? 0n,\n portfolioValue0,\n portfolioValue1,\n portfolioValueAtMint0,\n portfolioValueAtMint1,\n collateralReqToken0: 0n,\n collateralReqToken1: 0n,\n },\n ])\n }\n }),\n )\n\n return entries\n}\n","/**\n * Reorg detection and handling for position sync.\n * @module v2/sync/reorgHandling\n */\n\nimport type { Address, Hash, PublicClient } from 'viem'\n\nimport type { StorageAdapter } from '../storage'\nimport { getSyncCheckpointKey, jsonSerializer } from '../storage'\nimport type { ReorgDetection, SyncCheckpoint } from '../types'\nimport { REORG_DEPTH } from '../utils/constants'\n\n/**\n * Parameters for reorg detection.\n */\nexport interface DetectReorgParams {\n /** viem public client */\n client: PublicClient\n /** Chain ID */\n chainId: bigint\n /** Pool address */\n poolAddress: Address\n /** Account being synced */\n account: Address\n /** Storage adapter for checkpoint retrieval */\n storage: StorageAdapter\n}\n\n/**\n * Detect chain reorganization by comparing stored block hash with current chain.\n *\n * @param params - Detection parameters\n * @returns Reorg detection result\n */\nexport async function detectReorg(params: DetectReorgParams): Promise<ReorgDetection> {\n const { client, chainId, poolAddress, account, storage } = params\n\n // Load checkpoint\n const checkpointKey = getSyncCheckpointKey(chainId, poolAddress, account)\n const checkpointData = await storage.get(checkpointKey)\n\n if (!checkpointData) {\n // No checkpoint, no reorg to detect\n return { detected: false }\n }\n\n const checkpoint = jsonSerializer.parse(checkpointData) as SyncCheckpoint\n\n // Get the block at the checkpoint height\n try {\n const block = await client.getBlock({\n blockNumber: checkpoint.lastBlock,\n })\n\n // Compare hashes\n if (block.hash !== checkpoint.lastBlockHash) {\n // Reorg detected!\n return {\n detected: true,\n reorgBlock: checkpoint.lastBlock,\n expectedHash: checkpoint.lastBlockHash,\n actualHash: block.hash,\n blocksToResync: REORG_DEPTH,\n }\n }\n\n // No reorg\n return { detected: false }\n } catch (error) {\n // Block not found - this could mean the block was orphaned\n // Treat as a reorg\n return {\n detected: true,\n reorgBlock: checkpoint.lastBlock,\n expectedHash: checkpoint.lastBlockHash,\n actualHash: '0x0000000000000000000000000000000000000000000000000000000000000000' as Hash,\n blocksToResync: REORG_DEPTH,\n }\n }\n}\n\n/**\n * Calculate the safe resync block after a reorg.\n *\n * @param reorgBlock - Block where reorg was detected\n * @param reorgDepth - Number of blocks to roll back (default: REORG_DEPTH = 128)\n * @returns Safe block to resync from\n */\nexport function calculateResyncBlock(reorgBlock: bigint, reorgDepth: bigint = REORG_DEPTH): bigint {\n // Roll back reorgDepth blocks, but don't go below 0\n if (reorgBlock <= reorgDepth) {\n return 0n\n }\n return reorgBlock - reorgDepth\n}\n\n/**\n * Parameters for checkpoint save.\n */\nexport interface SaveCheckpointParams {\n /** Storage adapter */\n storage: StorageAdapter\n /** Chain ID */\n chainId: bigint\n /** Pool address */\n poolAddress: Address\n /** Account */\n account: Address\n /** Last synced block */\n lastBlock: bigint\n /** Last synced block hash */\n lastBlockHash: Hash\n /** Position IDs discovered */\n positionIds: bigint[]\n}\n\n/**\n * Save a sync checkpoint.\n *\n * @param params - Checkpoint parameters\n */\nexport async function saveCheckpoint(params: SaveCheckpointParams): Promise<void> {\n const { storage, chainId, poolAddress, account, lastBlock, lastBlockHash, positionIds } = params\n\n const checkpoint: SyncCheckpoint = {\n chainId,\n poolAddress,\n account,\n lastBlock,\n lastBlockHash,\n positionIds,\n createdAt: BigInt(Math.floor(Date.now() / 1000)),\n }\n\n const key = getSyncCheckpointKey(chainId, poolAddress, account)\n await storage.set(key, jsonSerializer.stringify(checkpoint))\n}\n\n/**\n * Load a sync checkpoint.\n *\n * @param storage - Storage adapter\n * @param chainId - Chain ID\n * @param poolAddress - Pool address\n * @param account - Account address\n * @returns Checkpoint or null if not found\n */\nexport async function loadCheckpoint(\n storage: StorageAdapter,\n chainId: bigint,\n poolAddress: Address,\n account: Address,\n): Promise<SyncCheckpoint | null> {\n const key = getSyncCheckpointKey(chainId, poolAddress, account)\n const data = await storage.get(key)\n\n if (!data) {\n return null\n }\n\n return jsonSerializer.parse(data) as SyncCheckpoint\n}\n\n/**\n * Clear a sync checkpoint.\n *\n * @param storage - Storage adapter\n * @param chainId - Chain ID\n * @param poolAddress - Pool address\n * @param account - Account address\n */\nexport async function clearCheckpoint(\n storage: StorageAdapter,\n chainId: bigint,\n poolAddress: Address,\n account: Address,\n): Promise<void> {\n const key = getSyncCheckpointKey(chainId, poolAddress, account)\n await storage.delete(key)\n}\n\n/**\n * Verify block continuity for a range of blocks.\n * This checks that each block's parentHash matches the previous block's hash.\n *\n * @param client - viem public client\n * @param fromBlock - Starting block\n * @param toBlock - Ending block\n * @returns True if blocks form a valid chain\n */\nexport async function verifyBlockContinuity(\n client: PublicClient,\n fromBlock: bigint,\n toBlock: bigint,\n): Promise<boolean> {\n if (fromBlock >= toBlock) {\n return true\n }\n\n // Sample a few blocks to verify continuity\n const sampleSize = Math.min(5, Number(toBlock - fromBlock))\n const step = (toBlock - fromBlock) / BigInt(sampleSize)\n\n let previousHash: Hash | null = null\n\n for (let i = 0; i <= sampleSize; i++) {\n const blockNumber = fromBlock + step * BigInt(i)\n const block = await client.getBlock({ blockNumber })\n\n if (previousHash !== null && i > 0) {\n // For non-consecutive blocks, we can't verify parentHash\n // but we can check that the block exists\n }\n\n previousHash = block.hash\n }\n\n return true\n}\n","/**\n * Get synchronization status for an account.\n * @module v2/sync/getSyncStatus\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport type { StorageAdapter } from '../storage'\nimport { loadCheckpoint } from './reorgHandling'\n\n/**\n * Parameters for getSyncStatus.\n */\nexport interface GetSyncStatusParams {\n /** viem public client */\n client: PublicClient\n /** Chain ID */\n chainId: bigint\n /** Pool address */\n poolAddress: Address\n /** Account to check */\n account: Address\n /** Storage adapter */\n storage: StorageAdapter\n}\n\n/**\n * Sync status result.\n */\nexport interface SyncStatusResult {\n /** Last synced block number (0n if never synced) */\n lastSyncedBlock: bigint\n /** Whether the account is fully synced to current block */\n isSynced: boolean\n /** Number of blocks behind (0n if synced) */\n blocksBehind: bigint\n /** Number of positions tracked */\n positionCount: bigint\n /** Whether a checkpoint exists */\n hasCheckpoint: boolean\n}\n\n/**\n * Get the synchronization status for an account.\n *\n * This function checks the stored checkpoint and compares against\n * the current chain head to determine sync status.\n *\n * @param params - Status parameters\n * @returns Sync status information\n */\nexport async function getSyncStatus(params: GetSyncStatusParams): Promise<SyncStatusResult> {\n const { client, chainId, poolAddress, account, storage } = params\n\n // Get current block\n const currentBlock = await client.getBlockNumber()\n\n // Load checkpoint\n const checkpoint = await loadCheckpoint(storage, chainId, poolAddress, account)\n\n if (!checkpoint) {\n return {\n lastSyncedBlock: 0n,\n isSynced: false,\n blocksBehind: currentBlock,\n positionCount: 0n,\n hasCheckpoint: false,\n }\n }\n\n const blocksBehind = currentBlock - checkpoint.lastBlock\n const isSynced = blocksBehind <= 0n\n\n return {\n lastSyncedBlock: checkpoint.lastBlock,\n isSynced,\n blocksBehind: blocksBehind > 0n ? blocksBehind : 0n,\n positionCount: BigInt(checkpoint.positionIds.length),\n hasCheckpoint: true,\n }\n}\n","/**\n * Event reconstruction for full position history scan.\n * @module v2/sync/eventReconstruction\n */\n\nimport type { Address, Hash, PublicClient } from 'viem'\nimport { getAbiItem } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport type { SyncEvent } from '../types'\n\ntype EventReconstructionClient = Pick<PublicClient, 'getBlock' | 'getLogs'>\n\n/**\n * Parameters for event reconstruction.\n */\nexport interface EventReconstructionParams {\n /** viem public client */\n client: EventReconstructionClient\n /** Pool address */\n poolAddress: Address\n /** Account to reconstruct positions for */\n account: Address\n /** Starting block for event scan */\n fromBlock: bigint\n /** Ending block for event scan */\n toBlock: bigint\n /** Batch size for log queries (default: 10000) */\n batchSize?: bigint\n /** Progress callback */\n onProgress?: (event: SyncEvent) => void\n}\n\n/**\n * Event reconstruction result.\n */\nexport interface EventReconstructionResult {\n /** Position IDs that are currently open */\n openPositions: bigint[]\n /** Position IDs that have been closed */\n closedPositions: bigint[]\n /** Number of blocks scanned */\n blocksScanned: bigint\n /** Last scanned block number */\n lastBlock: bigint\n /** Last scanned block hash */\n lastBlockHash: Hash\n}\n\n/**\n * Mint event from reconstruction.\n */\ninterface MintEvent {\n tokenId: bigint\n positionSize: bigint\n blockNumber: bigint\n blockHash: Hash\n transactionHash: Hash\n logIndex: number\n}\n\n/**\n * Burn event from reconstruction.\n */\ninterface BurnEvent {\n tokenId: bigint\n positionSize: bigint\n blockNumber: bigint\n blockHash: Hash\n transactionHash: Hash\n logIndex: number\n}\n\n/**\n * Reconstruct position history from events.\n * This is the fallback method when snapshot recovery fails.\n * It scans all OptionMinted and OptionBurnt events to build the position set.\n *\n * @param params - Reconstruction parameters\n * @returns Reconstruction result with open and closed positions\n */\nexport async function reconstructFromEvents(\n params: EventReconstructionParams,\n): Promise<EventReconstructionResult> {\n const {\n client,\n poolAddress,\n account,\n fromBlock,\n toBlock,\n batchSize = 10000n,\n onProgress,\n } = params\n\n const mintEvents: MintEvent[] = []\n const burnEvents: BurnEvent[] = []\n const totalBlocks = toBlock - fromBlock + 1n\n const safeBatchSize = batchSize > 0n ? batchSize : 10000n\n\n const scanRange = async (rangeFromBlock: bigint, rangeToBlock: bigint) => {\n const [mints, burns] = await Promise.all([\n client.getLogs({\n address: poolAddress,\n event: OPTION_MINTED_EVENT,\n args: { recipient: account },\n fromBlock: rangeFromBlock,\n toBlock: rangeToBlock,\n }),\n client.getLogs({\n address: poolAddress,\n event: OPTION_BURNT_EVENT,\n args: { recipient: account },\n fromBlock: rangeFromBlock,\n toBlock: rangeToBlock,\n }),\n ])\n\n // Process mint events\n for (const mint of mints) {\n // Decode position size from balanceData (first 128 bits)\n const balanceData = mint.args.balanceData as bigint\n const positionSize = balanceData & ((1n << 128n) - 1n)\n\n mintEvents.push({\n tokenId: mint.args.tokenId as bigint,\n positionSize,\n blockNumber: mint.blockNumber,\n blockHash: mint.blockHash,\n transactionHash: mint.transactionHash,\n logIndex: mint.logIndex,\n })\n }\n\n // Process burn events\n for (const burn of burns) {\n burnEvents.push({\n tokenId: burn.args.tokenId as bigint,\n positionSize: burn.args.positionSize as bigint,\n blockNumber: burn.blockNumber,\n blockHash: burn.blockHash,\n transactionHash: burn.transactionHash,\n logIndex: burn.logIndex,\n })\n }\n\n const blocksProcessed = rangeToBlock - fromBlock + 1n\n const progress = totalBlocks > 0n ? (blocksProcessed * 100n) / totalBlocks : 100n\n onProgress?.({\n currentBlock: rangeToBlock,\n targetBlock: toBlock,\n positionsFound: BigInt(mintEvents.length),\n progress: progress > 100n ? 100n : progress,\n })\n }\n\n // Account and pool topics make this query selective enough for providers that\n // permit wide eth_getLogs ranges. This keeps the fallback practical on mainnet.\n // Providers with an explicit range cap fall back to bounded requests.\n try {\n await scanRange(fromBlock, toBlock)\n } catch (error) {\n if (!isRangeLimitError(error)) throw error\n\n let currentBlock = fromBlock\n while (currentBlock <= toBlock) {\n const endBlock =\n currentBlock + safeBatchSize - 1n > toBlock ? toBlock : currentBlock + safeBatchSize - 1n\n await scanRange(currentBlock, endBlock)\n currentBlock = endBlock + 1n\n }\n }\n\n // Build position map: tokenId -> net position size\n const positionMap = new Map<bigint, bigint>()\n\n // Sort all events by block and log index\n const allEvents = [\n ...mintEvents.map((e) => ({ ...e, type: 'mint' as const })),\n ...burnEvents.map((e) => ({ ...e, type: 'burn' as const })),\n ].sort((a, b) => {\n const blockDiff = Number(a.blockNumber - b.blockNumber)\n if (blockDiff !== 0) return blockDiff\n return a.logIndex - b.logIndex\n })\n\n // Process events in order\n for (const event of allEvents) {\n const current = positionMap.get(event.tokenId) ?? 0n\n\n if (event.type === 'mint') {\n positionMap.set(event.tokenId, current + event.positionSize)\n } else {\n positionMap.set(event.tokenId, current - event.positionSize)\n }\n }\n\n // Separate open and closed positions\n const openPositions: bigint[] = []\n const closedPositions: bigint[] = []\n\n for (const [tokenId, size] of positionMap) {\n if (size > 0n) {\n openPositions.push(tokenId)\n } else {\n closedPositions.push(tokenId)\n }\n }\n\n // Get the last block hash\n const lastBlock = await client.getBlock({ blockNumber: toBlock })\n\n return {\n openPositions,\n closedPositions,\n blocksScanned: toBlock - fromBlock + 1n,\n lastBlock: toBlock,\n lastBlockHash: lastBlock.hash,\n }\n}\n\nconst OPTION_MINTED_EVENT = getAbiItem({ abi: panopticPoolV2Abi, name: 'OptionMinted' })\nconst OPTION_BURNT_EVENT = getAbiItem({ abi: panopticPoolV2Abi, name: 'OptionBurnt' })\n\nfunction isRangeLimitError(error: unknown): boolean {\n const messages: string[] = []\n let current: unknown = error\n for (let depth = 0; current && typeof current === 'object' && depth < 5; depth += 1) {\n if ('message' in current && typeof current.message === 'string') {\n messages.push(current.message)\n }\n if ('details' in current && typeof current.details === 'string') {\n messages.push(current.details)\n }\n current = 'cause' in current ? current.cause : undefined\n }\n if (typeof error === 'string') messages.push(error)\n\n const message = messages.join(' ').toLowerCase()\n return (\n message.includes('block range') ||\n message.includes('range is too large') ||\n message.includes('range too large') ||\n message.includes('query returned more than') ||\n message.includes('too many results') ||\n message.includes('log response size exceeded') ||\n message.includes('exceeds the limit') ||\n (message.includes('range') && message.includes('limit'))\n )\n}\n\n/**\n * Get the deployment block for a pool.\n * This searches for the first PoolInitialized event.\n *\n * @param client - viem public client\n * @param poolAddress - Pool address\n * @returns Deployment block number or null if not found\n */\nexport async function getPoolDeploymentBlock(\n client: PublicClient,\n poolAddress: Address,\n): Promise<bigint | null> {\n // Search for the first event from this pool\n // We use a binary search approach to find the deployment block\n\n const currentBlock = await client.getBlockNumber()\n let low = 0n\n let high = currentBlock\n let foundBlock: bigint | null = null\n\n // Binary search with scan windows to find the deployment block.\n // Each iteration checks [mid, mid + scanRange] for logs.\n const scanRange = 10000n\n\n while (low <= high) {\n const mid = (low + high) / 2n\n const rangeEnd = mid + scanRange > high ? high : mid + scanRange\n\n try {\n const logs = await client.getLogs({\n address: poolAddress,\n fromBlock: mid,\n toBlock: rangeEnd,\n })\n\n if (logs.length > 0) {\n // Found logs — record earliest and search before it\n const earliest = logs[0].blockNumber\n if (foundBlock === null || earliest < foundBlock) {\n foundBlock = earliest\n }\n high = earliest - 1n\n } else {\n // No logs in [mid, rangeEnd] — skip the entire checked range\n low = rangeEnd + 1n\n }\n } catch {\n // Range too large for RPC — halve the search space\n high = mid + (rangeEnd - mid) / 2n\n }\n }\n\n return foundBlock\n}\n","/**\n * Main position synchronization function.\n * @module v2/sync/syncPositions\n */\n\nimport type { Address, Hash, PublicClient } from 'viem'\n\nimport { PositionSnapshotNotFoundError, ProviderLagError, SyncTimeoutError } from '../errors'\nimport { getPoolMetadata } from '../reads/pool'\nimport { getPositions } from '../reads/position'\nimport type { StorageAdapter } from '../storage'\nimport { getPoolMetaKey, getPositionMetaKey, getPositionsKey, jsonSerializer } from '../storage'\nimport type { StoredPoolMeta, StoredPositionData } from '../types'\nimport { getPoolDeploymentBlock, reconstructFromEvents } from './eventReconstruction'\nimport { getOpenPositionIds } from './getTrackedPositionIds'\nimport { detectReorg, loadCheckpoint, saveCheckpoint } from './reorgHandling'\n\n/**\n * Parameters for syncPositions.\n */\nexport interface SyncPositionsParams {\n /** viem public client */\n client: PublicClient\n /** Chain ID */\n chainId: bigint\n /** Pool address */\n poolAddress: Address\n /** Account to sync */\n account: Address\n /** Storage adapter for persistence */\n storage: StorageAdapter\n /** Starting block for sync (defaults to pool deployment block) */\n fromBlock?: bigint\n /** Ending block for sync (defaults to latest) */\n toBlock?: bigint\n /** Max block range per eth_getLogs call (default: 10000n) */\n maxLogsPerQuery?: bigint\n /** Max sync duration in ms (default: 300000n = 5 min) */\n syncTimeout?: bigint\n /** Optional callback for sync progress */\n onUpdate?: (event: SyncProgressEvent) => void\n /** If provider is behind this block, throw ProviderLagError */\n minBlockNumber?: bigint\n /** Manual snapshot tx hash for recovery when automatic fails */\n snapshotTxHash?: Hash\n}\n\n/**\n * Sync progress event for callbacks.\n */\nexport interface SyncProgressEvent {\n /** Event type */\n type: 'position-opened' | 'position-closed' | 'progress' | 'reorg-detected'\n /** TokenId for position events */\n tokenId?: bigint\n /** Current block being processed */\n blockNumber: bigint\n /** Progress info */\n progress?: {\n /** Current block */\n current: bigint\n /** Total blocks to process */\n total: bigint\n }\n}\n\n/**\n * Result of syncPositions.\n */\nexport interface SyncPositionsResult {\n /** Last synced block number */\n lastSyncedBlock: bigint\n /** Last synced block hash */\n lastSyncedBlockHash: Hash\n /** Number of open positions */\n positionCount: bigint\n /** Position IDs discovered */\n positionIds: bigint[]\n /** Whether this was an incremental sync (vs full) */\n incremental: boolean\n /** Duration in milliseconds */\n durationMs: bigint\n}\n\n/**\n * Synchronize positions for an account.\n *\n * This function:\n * 1. Checks for existing checkpoint\n * 2. If no checkpoint: recovers from dispatch() calldata or falls back to full event scan\n * 3. If checkpoint exists: detects reorgs and syncs incrementally\n * 4. Persists positions and checkpoint to storage\n *\n * @param params - Sync parameters\n * @returns Sync result with position count and sync metadata\n * @throws SyncTimeoutError if sync exceeds timeout\n * @throws ProviderLagError if provider is behind minBlockNumber\n * @throws PositionSnapshotNotFoundError if no positions found and no snapshot available\n */\nexport async function syncPositions(params: SyncPositionsParams): Promise<SyncPositionsResult> {\n const {\n client,\n chainId,\n poolAddress,\n account,\n storage,\n syncTimeout = 300000n, // 5 minutes\n onUpdate,\n minBlockNumber,\n snapshotTxHash,\n } = params\n\n const startTime = Date.now()\n\n const checkTimeout = () => {\n const elapsed = BigInt(Date.now() - startTime)\n if (elapsed > syncTimeout) {\n throw new SyncTimeoutError(elapsed, toBlock, 0n)\n }\n }\n\n // Get latest block\n const latestBlock = await client.getBlockNumber()\n const toBlock = params.toBlock ?? latestBlock\n\n // Check for provider lag\n if (minBlockNumber !== undefined && latestBlock < minBlockNumber) {\n throw new ProviderLagError(minBlockNumber, latestBlock)\n }\n\n // Reorg detection using existing checkpoint\n const checkpoint = await loadCheckpoint(storage, chainId, poolAddress, account)\n if (checkpoint) {\n const reorgResult = await detectReorg({\n client,\n chainId,\n poolAddress,\n account,\n storage,\n })\n\n if (reorgResult.detected) {\n onUpdate?.({\n type: 'reorg-detected',\n blockNumber: reorgResult.reorgBlock ?? 0n,\n })\n }\n }\n\n checkTimeout()\n\n // Get authoritative position IDs from latest dispatch calldata.\n // When resuming from a checkpoint, narrow the event scan window to avoid\n // re-scanning the entire chain history on every incremental sync.\n // Returns null when no dispatch event was found in the scanned range,\n // or [] when a dispatch was found with an empty position list.\n const snapshotResult = await getOpenPositionIds({\n client,\n chainId,\n poolAddress,\n account,\n storage,\n lastDispatchTxHash: snapshotTxHash,\n fromBlock: checkpoint?.lastBlock ?? params.fromBlock,\n })\n\n // An explicit empty array is an authoritative snapshot. With no usable\n // snapshot, reconstruct the complete history from account-indexed events:\n // manager contracts can build dispatch calldata internally, so the outer\n // transaction may contain no decodable finalPositionIdList even though its\n // events identify the owner. Always rebuilding from the configured scan floor\n // also repairs older empty or stale checkpoints made for such accounts.\n let positionIds: bigint[]\n if (snapshotResult === null) {\n const fromBlock = params.fromBlock ?? (await getPoolDeploymentBlock(client, poolAddress))\n if (fromBlock === null) {\n throw new PositionSnapshotNotFoundError(new Error('Pool deployment block not found'))\n }\n\n const reconstruction = await reconstructFromEvents({\n client,\n poolAddress,\n account,\n fromBlock,\n toBlock,\n batchSize: params.maxLogsPerQuery,\n onProgress: (progress) => {\n checkTimeout()\n onUpdate?.({\n type: 'progress',\n blockNumber: progress.currentBlock,\n progress: {\n current: progress.currentBlock,\n total: progress.targetBlock,\n },\n })\n },\n })\n positionIds = reconstruction.openPositions\n } else {\n positionIds = snapshotResult\n }\n\n const finalBlock = await client.getBlock({ blockNumber: toBlock })\n\n // If no positions, persist an empty position list and return early.\n if (positionIds.length === 0) {\n await persistPoolAndCheckpoint(params, toBlock, finalBlock.hash, [])\n\n const positionsKey = getPositionsKey(chainId, poolAddress, account)\n await storage.set(positionsKey, jsonSerializer.stringify([]))\n\n return {\n lastSyncedBlock: toBlock,\n lastSyncedBlockHash: finalBlock.hash,\n positionCount: 0n,\n positionIds: [],\n incremental: !!checkpoint,\n durationMs: BigInt(Date.now() - startTime),\n }\n }\n\n checkTimeout()\n\n // Fetch and store position data for all positions\n if (positionIds.length > 0) {\n const { positions } = await getPositions({\n client,\n poolAddress,\n owner: account,\n tokenIds: positionIds,\n blockNumber: toBlock,\n })\n\n for (const pos of positions) {\n const positionMetaKey = getPositionMetaKey(chainId, poolAddress, pos.tokenId)\n const storedData: StoredPositionData = {\n tokenId: pos.tokenId,\n positionSize: pos.positionSize,\n legs: pos.legs,\n tickAtMint: pos.tickAtMint,\n poolUtilization0AtMint: pos.poolUtilization0AtMint,\n poolUtilization1AtMint: pos.poolUtilization1AtMint,\n timestampAtMint: pos.timestampAtMint,\n blockNumberAtMint: pos.blockNumberAtMint,\n swapAtMint: pos.swapAtMint,\n }\n await storage.set(positionMetaKey, jsonSerializer.stringify(storedData))\n }\n }\n\n await persistPoolAndCheckpoint(params, toBlock, finalBlock.hash, positionIds)\n\n // Save positions to storage\n const positionsKey = getPositionsKey(chainId, poolAddress, account)\n await storage.set(positionsKey, jsonSerializer.stringify(positionIds))\n\n return {\n lastSyncedBlock: toBlock,\n lastSyncedBlockHash: finalBlock.hash,\n positionCount: BigInt(positionIds.length),\n positionIds,\n incremental: !!checkpoint,\n durationMs: BigInt(Date.now() - startTime),\n }\n}\n\nasync function persistPoolAndCheckpoint(\n params: SyncPositionsParams,\n lastBlock: bigint,\n lastBlockHash: Hash,\n positionIds: bigint[],\n): Promise<void> {\n const { account, chainId, client, poolAddress, storage } = params\n const poolMetaKey = getPoolMetaKey(chainId, poolAddress)\n const existingPoolMeta = await storage.get(poolMetaKey)\n if (!existingPoolMeta) {\n await fetchAndStorePoolMeta(client, poolAddress, poolMetaKey, storage)\n }\n\n await saveCheckpoint({\n storage,\n chainId,\n poolAddress,\n account,\n lastBlock,\n lastBlockHash,\n positionIds,\n })\n}\n\n/**\n * Fetch full pool metadata and store it.\n * Uses getPoolMetadata to fetch all immutable pool data in minimal RPC calls.\n */\nasync function fetchAndStorePoolMeta(\n client: PublicClient,\n poolAddress: Address,\n poolMetaKey: string,\n storage: StorageAdapter,\n): Promise<void> {\n const metadata = await getPoolMetadata({ client, poolAddress })\n\n const poolMeta: StoredPoolMeta = {\n tickSpacing: metadata.tickSpacing,\n fee: metadata.fee,\n poolId: metadata.poolId,\n collateralToken0Address: metadata.collateralToken0Address,\n collateralToken1Address: metadata.collateralToken1Address,\n riskEngineAddress: metadata.riskEngineAddress,\n token0Asset: metadata.token0Asset,\n token1Asset: metadata.token1Asset,\n token0Symbol: metadata.token0Symbol,\n token1Symbol: metadata.token1Symbol,\n token0Decimals: metadata.token0Decimals,\n token1Decimals: metadata.token1Decimals,\n }\n\n await storage.set(poolMetaKey, jsonSerializer.stringify(poolMeta))\n}\n","/**\n * Trade history tracking for closed positions.\n * @module v2/sync/tradeHistory\n */\n\nimport type { Address } from 'viem'\n\nimport type { StorageAdapter } from '../storage'\nimport { getClosedPositionsKey, jsonSerializer } from '../storage'\nimport type { ClosedPosition, RealizedPnL } from '../types'\n\n/**\n * Parameters for saving a closed position.\n */\nexport interface SaveClosedPositionParams {\n /** Chain ID */\n chainId: bigint\n /** Pool address */\n poolAddress: Address\n /** Account that owned the position */\n account: Address\n /** Storage adapter */\n storage: StorageAdapter\n /** The closed position data */\n closedPosition: ClosedPosition\n}\n\n/**\n * Save a closed position to trade history.\n *\n * @param params - Save parameters\n */\nexport async function saveClosedPosition(params: SaveClosedPositionParams): Promise<void> {\n const { chainId, poolAddress, account, storage, closedPosition } = params\n\n const key = getClosedPositionsKey(chainId, poolAddress, account)\n const existingData = await storage.get(key)\n\n let history: ClosedPosition[]\n if (existingData) {\n try {\n history = jsonSerializer.parse(existingData) as ClosedPosition[]\n } catch {\n history = []\n }\n } else {\n history = []\n }\n\n // Add new closed position\n history.push(closedPosition)\n\n // Sort by close block (most recent first)\n history.sort((a, b) => Number(b.closeBlock - a.closeBlock))\n\n await storage.set(key, jsonSerializer.stringify(history))\n}\n\n/**\n * Parameters for getting trade history.\n */\nexport interface GetTradeHistoryParams {\n /** Chain ID */\n chainId: bigint\n /** Pool address */\n poolAddress: Address\n /** Account to get history for */\n account: Address\n /** Storage adapter */\n storage: StorageAdapter\n /** Maximum number of positions to return (default: 100) */\n limit?: bigint\n /** Offset for pagination */\n offset?: bigint\n /** Filter by closure reason */\n closureReason?: 'closed' | 'liquidated' | 'force_exercised'\n /** Filter by block range (from) */\n fromBlock?: bigint\n /** Filter by block range (to) */\n toBlock?: bigint\n}\n\n/**\n * Get trade history (closed positions) for an account.\n *\n * This function reads from local storage, no RPC calls.\n * Positions are returned in reverse chronological order (most recent first).\n *\n * @param params - Query parameters\n * @returns Array of closed positions\n */\nexport async function getTradeHistory(params: GetTradeHistoryParams): Promise<ClosedPosition[]> {\n const {\n chainId,\n poolAddress,\n account,\n storage,\n limit = 100n,\n offset = 0n,\n closureReason,\n fromBlock,\n toBlock,\n } = params\n\n const key = getClosedPositionsKey(chainId, poolAddress, account)\n const data = await storage.get(key)\n\n if (!data) {\n return []\n }\n\n let history: ClosedPosition[]\n try {\n history = jsonSerializer.parse(data) as ClosedPosition[]\n } catch {\n return []\n }\n\n // Apply filters\n if (closureReason) {\n history = history.filter((p) => p.closureReason === closureReason)\n }\n\n if (fromBlock !== undefined) {\n history = history.filter((p) => p.closeBlock >= fromBlock)\n }\n\n if (toBlock !== undefined) {\n history = history.filter((p) => p.closeBlock <= toBlock)\n }\n\n // Apply pagination\n const start = Number(offset)\n const end = start + Number(limit)\n return history.slice(start, end)\n}\n\n/**\n * Get closed positions (alias for getTradeHistory with specific closure reason).\n *\n * @param params - Query parameters\n * @returns Array of closed positions\n */\nexport async function getClosedPositions(params: GetTradeHistoryParams): Promise<ClosedPosition[]> {\n return getTradeHistory(params)\n}\n\n/**\n * Parameters for getting realized PnL.\n */\nexport interface GetRealizedPnLParams {\n /** Chain ID */\n chainId: bigint\n /** Pool address */\n poolAddress: Address\n /** Account to get PnL for */\n account: Address\n /** Storage adapter */\n storage: StorageAdapter\n /** Filter by block range (from) */\n fromBlock?: bigint\n /** Filter by block range (to) */\n toBlock?: bigint\n}\n\n/**\n * Get realized PnL summary for an account.\n *\n * Calculates totals from all closed positions in storage.\n *\n * @param params - Query parameters\n * @returns Realized PnL summary\n */\nexport async function getRealizedPnL(params: GetRealizedPnLParams): Promise<RealizedPnL> {\n const { chainId, poolAddress, account, storage, fromBlock, toBlock } = params\n\n const history = await getTradeHistory({\n chainId,\n poolAddress,\n account,\n storage,\n limit: BigInt(Number.MAX_SAFE_INTEGER), // Get all\n fromBlock,\n toBlock,\n })\n\n let total0 = 0n\n let total1 = 0n\n let winCount = 0n\n let lossCount = 0n\n\n for (const position of history) {\n total0 += position.realizedPnL0\n total1 += position.realizedPnL1\n\n // Consider it a win if either token had positive PnL\n // (in practice, one will usually dominate)\n const isWin = position.realizedPnL0 > 0n || position.realizedPnL1 > 0n\n const isLoss = position.realizedPnL0 < 0n || position.realizedPnL1 < 0n\n\n if (isWin && !isLoss) {\n winCount++\n } else if (isLoss && !isWin) {\n lossCount++\n }\n // Mixed results (win on one, loss on other) don't count as either\n }\n\n return {\n total0,\n total1,\n positionCount: BigInt(history.length),\n winCount,\n lossCount,\n }\n}\n\n/**\n * Clear all trade history for an account.\n *\n * @param params - Query parameters\n */\nexport async function clearTradeHistory(\n params: Omit<\n GetTradeHistoryParams,\n 'limit' | 'offset' | 'closureReason' | 'fromBlock' | 'toBlock'\n >,\n): Promise<void> {\n const { chainId, poolAddress, account, storage } = params\n\n const key = getClosedPositionsKey(chainId, poolAddress, account)\n await storage.delete(key)\n}\n","/**\n * Chunk spread tracking for volatility surface data.\n * @module v2/sync/chunkTracking\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { panopticQueryAbi } from '../abis/panopticQuery'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport { ChunkLimitError } from '../errors'\nimport type { StorageAdapter } from '../storage'\nimport { getTrackedChunksKey, jsonSerializer } from '../storage'\nimport { DEFAULT_VEGOID } from '../tokenId/constants'\nimport type { BlockMeta } from '../types'\nimport { MAX_TRACKED_CHUNKS, WAD } from '../utils/constants'\n\n/**\n * Key for identifying a liquidity chunk.\n * A chunk is a unique combination of (tokenType, tickLower, tickUpper).\n */\nexport interface LiquidityChunkKey {\n /** Token type: 0n = token0 (put), 1n = token1 (call) */\n tokenType: 0n | 1n\n /** Lower tick bound */\n tickLower: bigint\n /** Upper tick bound */\n tickUpper: bigint\n}\n\n/**\n * Full chunk data with spread calculation.\n */\nexport interface LiquidityChunkSpread extends LiquidityChunkKey {\n /** Liquidity currently deployed in Uniswap */\n netLiquidity: bigint\n /** Liquidity borrowed by option buyers */\n removedLiquidity: bigint\n /** Computed spread: (1 + (1/VEGOID) * removed/net) * 1e18 */\n spreadWad: bigint\n}\n\n/**\n * Parameters for adding tracked chunks.\n */\nexport interface AddTrackedChunksParams {\n /** Chain ID */\n chainId: bigint\n /** Pool address */\n poolAddress: Address\n /** Storage adapter */\n storage: StorageAdapter\n /** Chunks to add */\n chunks: LiquidityChunkKey[]\n}\n\n/**\n * Serialize a chunk key to a string for storage/comparison.\n */\nfunction serializeChunkKey(chunk: LiquidityChunkKey): string {\n return `${chunk.tokenType}:${chunk.tickLower}:${chunk.tickUpper}`\n}\n\n/**\n * Deserialize a chunk key from a string.\n */\nfunction deserializeChunkKey(key: string): LiquidityChunkKey {\n const [tokenType, tickLower, tickUpper] = key.split(':')\n return {\n tokenType: BigInt(tokenType) as 0n | 1n,\n tickLower: BigInt(tickLower),\n tickUpper: BigInt(tickUpper),\n }\n}\n\n/**\n * Add chunks to tracking.\n *\n * @param params - Parameters\n * @throws ChunkLimitError if adding would exceed 1000 chunks\n */\nexport async function addTrackedChunks(params: AddTrackedChunksParams): Promise<void> {\n const { chainId, poolAddress, storage, chunks } = params\n\n const key = getTrackedChunksKey(chainId, poolAddress)\n const existingData = await storage.get(key)\n\n let trackedKeys: Set<string>\n if (existingData) {\n try {\n const keys = jsonSerializer.parse(existingData) as string[]\n trackedKeys = new Set(keys)\n } catch {\n trackedKeys = new Set()\n }\n } else {\n trackedKeys = new Set()\n }\n\n // Add new chunks\n for (const chunk of chunks) {\n const serialized = serializeChunkKey(chunk)\n trackedKeys.add(serialized)\n }\n\n // Check limit\n if (trackedKeys.size > MAX_TRACKED_CHUNKS) {\n const attemptedAdd = BigInt(chunks.length)\n throw new ChunkLimitError(BigInt(trackedKeys.size - chunks.length), attemptedAdd)\n }\n\n await storage.set(key, jsonSerializer.stringify([...trackedKeys]))\n}\n\n/**\n * Parameters for removing tracked chunks.\n */\nexport interface RemoveTrackedChunksParams {\n /** Chain ID */\n chainId: bigint\n /** Pool address */\n poolAddress: Address\n /** Storage adapter */\n storage: StorageAdapter\n /** Chunks to remove */\n chunks: LiquidityChunkKey[]\n}\n\n/**\n * Remove chunks from tracking.\n *\n * @param params - Parameters\n */\nexport async function removeTrackedChunks(params: RemoveTrackedChunksParams): Promise<void> {\n const { chainId, poolAddress, storage, chunks } = params\n\n const key = getTrackedChunksKey(chainId, poolAddress)\n const existingData = await storage.get(key)\n\n if (!existingData) {\n return\n }\n\n let trackedKeys: Set<string>\n try {\n const keys = jsonSerializer.parse(existingData) as string[]\n trackedKeys = new Set(keys)\n } catch {\n return\n }\n\n // Remove chunks\n for (const chunk of chunks) {\n const serialized = serializeChunkKey(chunk)\n trackedKeys.delete(serialized)\n }\n\n if (trackedKeys.size === 0) {\n await storage.delete(key)\n } else {\n await storage.set(key, jsonSerializer.stringify([...trackedKeys]))\n }\n}\n\n/**\n * Parameters for getting tracked chunks.\n */\nexport interface GetTrackedChunksParams {\n /** Chain ID */\n chainId: bigint\n /** Pool address */\n poolAddress: Address\n /** Storage adapter */\n storage: StorageAdapter\n}\n\n/**\n * Get all tracked chunk keys.\n *\n * @param params - Parameters\n * @returns Array of tracked chunk keys\n */\nexport async function getTrackedChunks(\n params: GetTrackedChunksParams,\n): Promise<LiquidityChunkKey[]> {\n const { chainId, poolAddress, storage } = params\n\n const key = getTrackedChunksKey(chainId, poolAddress)\n const data = await storage.get(key)\n\n if (!data) {\n return []\n }\n\n try {\n const keys = jsonSerializer.parse(data) as string[]\n return keys.map(deserializeChunkKey)\n } catch {\n return []\n }\n}\n\n/**\n * Parameters for getting chunk spreads (legacy manual tracking).\n * @deprecated Use scanChunks() for automatic chunk discovery\n */\nexport interface GetChunkSpreadsParams {\n /** viem public client */\n client: PublicClient\n /** Chain ID */\n chainId: bigint\n /** Pool address (PanopticPool) */\n poolAddress: Address\n /** SFPM address */\n sfpmAddress: Address\n /** Storage adapter */\n storage: StorageAdapter\n /** Optional filter by token type */\n tokenType?: 0n | 1n\n /** VEGOID constant (default: 4n) */\n vegoid?: bigint\n}\n\n/**\n * Get spread data for all tracked chunks (legacy).\n *\n * @deprecated Use scanChunks() for automatic chunk discovery with on-chain data.\n * This function only returns manually tracked chunks.\n *\n * @param params - Parameters\n * @returns Array of chunk spreads with liquidity data\n */\nexport async function getChunkSpreads(\n params: GetChunkSpreadsParams,\n): Promise<LiquidityChunkSpread[]> {\n const { chainId, poolAddress, storage, tokenType } = params\n\n // Get tracked chunks\n let chunks = await getTrackedChunks({ chainId, poolAddress, storage })\n\n // Apply filter\n if (tokenType !== undefined) {\n chunks = chunks.filter((c) => c.tokenType === tokenType)\n }\n\n if (chunks.length === 0) {\n return []\n }\n\n // Return tracked chunks without liquidity data\n // Use scanChunks() for on-chain liquidity data\n return chunks.map((chunk) => ({\n ...chunk,\n netLiquidity: 0n,\n removedLiquidity: 0n,\n spreadWad: WAD,\n }))\n}\n\n/**\n * Calculate spread from liquidity values.\n *\n * spread = 1 + (1/VEGOID) * removedLiquidity / netLiquidity\n *\n * @param netLiquidity - Liquidity in Uniswap\n * @param removedLiquidity - Liquidity borrowed by buyers\n * @param vegoid - VEGOID constant (default: 4n)\n * @returns Spread in WAD (1e18 = 1.0x)\n */\nexport function calculateSpreadWad(\n netLiquidity: bigint,\n removedLiquidity: bigint,\n vegoid: bigint = DEFAULT_VEGOID,\n): bigint {\n if (netLiquidity === 0n) {\n return WAD // 1.0x spread if no liquidity\n }\n\n // spread = WAD + (WAD / vegoid) * removedLiquidity / netLiquidity\n // = WAD + (WAD * removedLiquidity) / (vegoid * netLiquidity)\n const bonus = (WAD * removedLiquidity) / (vegoid * netLiquidity)\n return WAD + bonus\n}\n\n/**\n * Clear all tracked chunks for a pool.\n *\n * @param params - Parameters\n */\nexport async function clearTrackedChunks(params: GetTrackedChunksParams): Promise<void> {\n const { chainId, poolAddress, storage } = params\n\n const key = getTrackedChunksKey(chainId, poolAddress)\n await storage.delete(key)\n}\n\n// ============================================================================\n// PanopticQuery-based chunk functions (recommended)\n// ============================================================================\n\n/**\n * Scanned chunk with liquidity data from PanopticQuery.scanChunks().\n */\nexport interface ScannedChunk {\n /** Strike tick (center of the chunk) */\n strike: bigint\n /** Token type 0 net liquidity */\n netLiquidity0: bigint\n /** Token type 1 net liquidity */\n netLiquidity1: bigint\n /** Token type 0 removed liquidity */\n removedLiquidity0: bigint\n /** Token type 1 removed liquidity */\n removedLiquidity1: bigint\n /** Computed spread for token type 0 */\n spreadWad0: bigint\n /** Computed spread for token type 1 */\n spreadWad1: bigint\n /** Token type 0 settled tokens (LeftRightUnsigned: left=token1, right=token0) */\n settledTokens0: bigint\n /** Token type 1 settled tokens (LeftRightUnsigned: left=token1, right=token0) */\n settledTokens1: bigint\n}\n\n/**\n * Result of scanning chunks in a tick range.\n */\nexport interface ScanChunksResult {\n /** Array of scanned chunks with liquidity data */\n chunks: ScannedChunk[]\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Parameters for scanChunks().\n */\nexport interface ScanChunksParams {\n /** viem public client */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** PanopticQuery contract address */\n queryAddress: Address\n /** Lower tick bound of range to scan */\n tickLower: bigint\n /** Upper tick bound of range to scan */\n tickUpper: bigint\n /** Width of chunks to scan (tickUpper - tickLower for each chunk) */\n width: bigint\n /** VEGOID constant for spread calculation (default: 4n) */\n vegoid?: bigint\n /** Optional block number for historical queries */\n blockNumber?: bigint\n}\n\n/**\n * Scan for non-empty liquidity chunks in a tick range.\n *\n * Uses PanopticQuery.scanChunks() to discover chunks with liquidity.\n * Returns only non-empty chunks, making it efficient for large ranges.\n *\n * ## Same-Block Guarantee\n * All data is fetched at a single block.\n *\n * @param params - Parameters\n * @returns Scanned chunks with liquidity data and block metadata\n *\n * @example\n * ```typescript\n * const result = await scanChunks({\n * client,\n * poolAddress: '0x...',\n * queryAddress: '0x...',\n * tickLower: -1000n,\n * tickUpper: 1000n,\n * width: 100n, // 100 tick wide chunks\n * })\n *\n * for (const chunk of result.chunks) {\n * console.log(`Strike ${chunk.strike}: spread0=${chunk.spreadWad0}, spread1=${chunk.spreadWad1}`)\n * }\n * ```\n */\nexport async function scanChunks(params: ScanChunksParams): Promise<ScanChunksResult> {\n const {\n client,\n poolAddress,\n queryAddress,\n tickLower,\n tickUpper,\n width,\n vegoid = 4n,\n blockNumber,\n } = params\n\n const targetBlockNumber = blockNumber ?? (await client.getBlockNumber())\n\n const [result, _meta] = await Promise.all([\n client.readContract({\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'scanChunks',\n args: [poolAddress, Number(tickLower), Number(tickUpper), Number(width)],\n blockNumber: targetBlockNumber,\n }),\n getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [strikes, netLiquidities, removedLiquidities, settledTokens] = result\n\n const chunks: ScannedChunk[] = strikes.map((strike, i) => {\n const net0 = netLiquidities[i][0]\n const net1 = netLiquidities[i][1]\n const removed0 = removedLiquidities[i][0]\n const removed1 = removedLiquidities[i][1]\n\n return {\n strike: BigInt(strike),\n netLiquidity0: net0,\n netLiquidity1: net1,\n removedLiquidity0: removed0,\n removedLiquidity1: removed1,\n spreadWad0: calculateSpreadWad(net0, removed0, vegoid),\n spreadWad1: calculateSpreadWad(net1, removed1, vegoid),\n settledTokens0: settledTokens[i][0],\n settledTokens1: settledTokens[i][1],\n }\n })\n\n return { chunks, _meta }\n}\n\n/**\n * Chunk data for a single leg of a position.\n */\nexport interface LegChunkData {\n /** Leg index (0-3) */\n legIndex: number\n /** Net liquidity (liquidity in Uniswap) */\n netLiquidity: bigint\n /** Removed liquidity (borrowed by option buyers) */\n removedLiquidity: bigint\n /** Computed spread */\n spreadWad: bigint\n}\n\n/**\n * Chunk data for a position (all legs).\n */\nexport interface PositionChunkData {\n /** TokenId of the position */\n tokenId: bigint\n /** Chunk data for each leg */\n legs: LegChunkData[]\n}\n\n/**\n * Result of getting position chunk data.\n */\nexport interface GetPositionChunkDataResult {\n /** Array of position chunk data */\n positions: PositionChunkData[]\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Parameters for getPositionChunkData().\n */\nexport interface GetPositionChunkDataParams {\n /** viem public client */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** PanopticQuery contract address */\n queryAddress: Address\n /** Array of tokenIds to query */\n tokenIds: bigint[]\n /** VEGOID constant for spread calculation (default: 4n) */\n vegoid?: bigint\n /** Optional block number for historical queries */\n blockNumber?: bigint\n}\n\n/**\n * Get chunk data (liquidity) for specific positions.\n *\n * Uses PanopticQuery.getChunkData() to fetch net and removed liquidity\n * for each leg of the given positions.\n *\n * ## Same-Block Guarantee\n * All data is fetched at a single block.\n *\n * @param params - Parameters\n * @returns Position chunk data with liquidity for each leg\n *\n * @example\n * ```typescript\n * const result = await getPositionChunkData({\n * client,\n * poolAddress: '0x...',\n * queryAddress: '0x...',\n * tokenIds: [tokenId1, tokenId2],\n * })\n *\n * for (const pos of result.positions) {\n * console.log(`Position ${pos.tokenId}:`)\n * for (const leg of pos.legs) {\n * console.log(` Leg ${leg.legIndex}: net=${leg.netLiquidity}, removed=${leg.removedLiquidity}`)\n * }\n * }\n * ```\n */\nexport async function getPositionChunkData(\n params: GetPositionChunkDataParams,\n): Promise<GetPositionChunkDataResult> {\n const {\n client,\n poolAddress,\n queryAddress,\n tokenIds,\n vegoid = DEFAULT_VEGOID,\n blockNumber,\n } = params\n\n if (tokenIds.length === 0) {\n const _meta = await getBlockMeta({ client, blockNumber })\n return { positions: [], _meta }\n }\n\n const targetBlockNumber = blockNumber ?? (await client.getBlockNumber())\n\n const [chunkData, _meta] = await Promise.all([\n client.readContract({\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'getChunkData',\n args: [poolAddress, tokenIds],\n blockNumber: targetBlockNumber,\n }),\n getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n // chunkData is uint256[2][4][] - [positionIndex][legIndex][0=net, 1=removed]\n const positions: PositionChunkData[] = tokenIds.map((tokenId, posIndex) => {\n const positionData = chunkData[posIndex]\n const legs: LegChunkData[] = []\n\n // Each position has up to 4 legs\n for (let legIndex = 0; legIndex < 4; legIndex++) {\n const legData = positionData[legIndex]\n const netLiquidity = legData[0]\n const removedLiquidity = legData[1]\n\n // Only include legs with data (non-zero liquidity indicates active leg)\n if (netLiquidity > 0n || removedLiquidity > 0n) {\n legs.push({\n legIndex,\n netLiquidity,\n removedLiquidity,\n spreadWad: calculateSpreadWad(netLiquidity, removedLiquidity, vegoid),\n })\n }\n }\n\n return { tokenId, legs }\n })\n\n return { positions, _meta }\n}\n","/**\n * Pending position tracking for optimistic updates.\n * @module v2/sync/pendingPositions\n */\n\nimport type { Address, Hash } from 'viem'\n\nimport type { StorageAdapter } from '../storage'\nimport { getPendingPositionsKey, jsonSerializer } from '../storage'\nimport type { TokenIdLeg } from '../types'\n\n/**\n * A pending position that has been submitted but not yet confirmed.\n */\nexport interface PendingPosition {\n /** The TokenId */\n tokenId: bigint\n /** Owner address */\n owner: Address\n /** Pool address */\n poolAddress: Address\n /** Position size (from simulation) */\n positionSize: bigint\n /** Decoded legs */\n legs: TokenIdLeg[]\n /** Transaction hash */\n txHash: Hash\n /** Block number when submitted */\n submittedAtBlock: bigint\n /** Timestamp when submitted */\n submittedAt: bigint\n /** Status */\n status: 'pending' | 'confirmed' | 'failed'\n}\n\n/**\n * Parameters for adding a pending position.\n */\nexport interface AddPendingPositionParams {\n /** Chain ID */\n chainId: bigint\n /** Pool address */\n poolAddress: Address\n /** Account (owner) */\n account: Address\n /** Storage adapter */\n storage: StorageAdapter\n /** Pending position data */\n position: PendingPosition\n}\n\n/**\n * Add a pending position for optimistic updates.\n *\n * Called when openPosition() submits a transaction.\n *\n * @param params - Parameters\n */\nexport async function addPendingPosition(params: AddPendingPositionParams): Promise<void> {\n const { chainId, poolAddress, account, storage, position } = params\n\n const key = getPendingPositionsKey(chainId, poolAddress, account)\n const existingData = await storage.get(key)\n\n let pending: PendingPosition[]\n if (existingData) {\n try {\n pending = jsonSerializer.parse(existingData) as PendingPosition[]\n } catch {\n pending = []\n }\n } else {\n pending = []\n }\n\n // Add new pending position\n pending.push(position)\n\n await storage.set(key, jsonSerializer.stringify(pending))\n}\n\n/**\n * Parameters for getting pending positions.\n */\nexport interface GetPendingPositionsParams {\n /** Chain ID */\n chainId: bigint\n /** Pool address */\n poolAddress: Address\n /** Account (owner) */\n account: Address\n /** Storage adapter */\n storage: StorageAdapter\n}\n\n/**\n * Get all pending positions for an account.\n *\n * @param params - Parameters\n * @returns Array of pending positions\n */\nexport async function getPendingPositions(\n params: GetPendingPositionsParams,\n): Promise<PendingPosition[]> {\n const { chainId, poolAddress, account, storage } = params\n\n const key = getPendingPositionsKey(chainId, poolAddress, account)\n const data = await storage.get(key)\n\n if (!data) {\n return []\n }\n\n try {\n const pending = jsonSerializer.parse(data) as PendingPosition[]\n // Only return pending status\n return pending.filter((p) => p.status === 'pending')\n } catch {\n return []\n }\n}\n\n/**\n * Parameters for confirming a pending position.\n */\nexport interface ConfirmPendingPositionParams {\n /** Chain ID */\n chainId: bigint\n /** Pool address */\n poolAddress: Address\n /** Account (owner) */\n account: Address\n /** Storage adapter */\n storage: StorageAdapter\n /** Token ID to confirm */\n tokenId: bigint\n}\n\n/**\n * Mark a pending position as confirmed.\n *\n * Called when syncPositions() finds the OptionMinted event.\n *\n * @param params - Parameters\n */\nexport async function confirmPendingPosition(params: ConfirmPendingPositionParams): Promise<void> {\n const { chainId, poolAddress, account, storage, tokenId } = params\n\n const key = getPendingPositionsKey(chainId, poolAddress, account)\n const existingData = await storage.get(key)\n\n if (!existingData) {\n return\n }\n\n let pending: PendingPosition[]\n try {\n pending = jsonSerializer.parse(existingData) as PendingPosition[]\n } catch {\n return\n }\n\n // Find and update the position\n const updated = pending.map((p) =>\n p.tokenId === tokenId ? { ...p, status: 'confirmed' as const } : p,\n )\n\n // Remove confirmed positions (they're now in the main position list)\n const remaining = updated.filter((p) => p.status === 'pending')\n\n if (remaining.length === 0) {\n await storage.delete(key)\n } else {\n await storage.set(key, jsonSerializer.stringify(remaining))\n }\n}\n\n/**\n * Parameters for failing a pending position.\n */\nexport interface FailPendingPositionParams {\n /** Chain ID */\n chainId: bigint\n /** Pool address */\n poolAddress: Address\n /** Account (owner) */\n account: Address\n /** Storage adapter */\n storage: StorageAdapter\n /** Transaction hash that failed */\n txHash: Hash\n}\n\n/**\n * Mark a pending position as failed (transaction reverted).\n *\n * @param params - Parameters\n */\nexport async function failPendingPosition(params: FailPendingPositionParams): Promise<void> {\n const { chainId, poolAddress, account, storage, txHash } = params\n\n const key = getPendingPositionsKey(chainId, poolAddress, account)\n const existingData = await storage.get(key)\n\n if (!existingData) {\n return\n }\n\n let pending: PendingPosition[]\n try {\n pending = jsonSerializer.parse(existingData) as PendingPosition[]\n } catch {\n return\n }\n\n // Remove the failed position\n const remaining = pending.filter((p) => p.txHash !== txHash)\n\n if (remaining.length === 0) {\n await storage.delete(key)\n } else {\n await storage.set(key, jsonSerializer.stringify(remaining))\n }\n}\n\n/**\n * Clear all pending positions for an account.\n *\n * @param params - Parameters\n */\nexport async function clearPendingPositions(params: GetPendingPositionsParams): Promise<void> {\n const { chainId, poolAddress, account, storage } = params\n\n const key = getPendingPositionsKey(chainId, poolAddress, account)\n await storage.delete(key)\n}\n\n/**\n * Clean up stale pending positions.\n *\n * Removes pending positions older than the specified block threshold.\n * This handles cases where transactions were dropped from the mempool.\n *\n * @param params - Parameters\n * @param maxAgeBlocks - Maximum age in blocks (default: 100)\n * @param currentBlock - Current block number\n */\nexport async function cleanupStalePendingPositions(\n params: GetPendingPositionsParams,\n currentBlock: bigint,\n maxAgeBlocks: bigint = 100n,\n): Promise<void> {\n const { chainId, poolAddress, account, storage } = params\n\n const key = getPendingPositionsKey(chainId, poolAddress, account)\n const existingData = await storage.get(key)\n\n if (!existingData) {\n return\n }\n\n let pending: PendingPosition[]\n try {\n pending = jsonSerializer.parse(existingData) as PendingPosition[]\n } catch {\n return\n }\n\n // Filter out stale positions\n const threshold = currentBlock - maxAgeBlocks\n const remaining = pending.filter((p) => p.status === 'pending' && p.submittedAtBlock > threshold)\n\n if (remaining.length === 0) {\n await storage.delete(key)\n } else if (remaining.length !== pending.length) {\n await storage.set(key, jsonSerializer.stringify(remaining))\n }\n}\n","/**\n * Transaction broadcaster utilities for the Panoptic v2 SDK.\n * @module v2/writes/broadcaster\n */\n\nimport type { Address, Hash, PublicClient, WalletClient } from 'viem'\n\nimport type { NonceManager, TxBroadcaster } from '../types'\n\n/**\n * Create a public broadcaster that sends transactions to the standard mempool.\n *\n * Use this factory to create a working broadcaster with a client.\n *\n * @param client - The public client for broadcasting\n * @returns A TxBroadcaster that sends to the public mempool\n *\n * @example\n * ```typescript\n * const broadcaster = createPublicBroadcaster(publicClient)\n * const hash = await broadcaster.broadcast(signedTx)\n * ```\n */\nexport function createPublicBroadcaster(client: PublicClient): TxBroadcaster {\n return {\n async broadcast(signedTx: `0x${string}`): Promise<Hash> {\n return client.sendRawTransaction({ serializedTransaction: signedTx })\n },\n }\n}\n\n/**\n * Default public broadcaster singleton.\n *\n * Note: This singleton requires a client to be provided via the broadcast call's context.\n * For standalone usage, use `createPublicBroadcaster(client)` instead.\n *\n * When used with write functions, the SDK handles client injection automatically.\n */\nexport const publicBroadcaster: TxBroadcaster = {\n async broadcast(signedTx: `0x${string}`): Promise<Hash> {\n // This singleton cannot broadcast without a client.\n // Write functions that use this broadcaster should inject their client.\n throw new Error(\n 'publicBroadcaster requires a client. Use createPublicBroadcaster(client) for standalone usage.',\n )\n },\n}\n\n/**\n * Create a nonce manager for concurrent transaction submission.\n *\n * The nonce manager tracks pending nonces to allow multiple transactions\n * to be submitted without waiting for confirmation.\n *\n * @param client - The public client for querying nonces\n * @returns A NonceManager instance\n *\n * @example\n * ```typescript\n * const nonceManager = createNonceManager(client)\n * const nonce1 = await nonceManager.getNextNonce(account)\n * const nonce2 = await nonceManager.getNextNonce(account) // nonce1 + 1\n * // On failure, reset to re-fetch from chain:\n * nonceManager.reset(account)\n * ```\n */\nexport function createNonceManager(client: PublicClient): NonceManager {\n const pendingNonces = new Map<Address, bigint>()\n\n return {\n async getNextNonce(account: Address): Promise<bigint> {\n const chainNonce = BigInt(\n await client.getTransactionCount({\n address: account,\n blockTag: 'pending',\n }),\n )\n\n const pending = pendingNonces.get(account)\n const localNext = pending !== undefined ? pending + 1n : chainNonce\n const nextNonce = localNext > chainNonce ? localNext : chainNonce\n\n pendingNonces.set(account, nextNonce)\n return nextNonce\n },\n\n reset(account: Address): void {\n pendingNonces.delete(account)\n },\n }\n}\n\n/**\n * Configuration for write operations.\n */\nexport interface WriteConfig {\n /** Wallet client for signing and submitting transactions */\n walletClient: WalletClient\n /** Public client for reading state */\n publicClient: PublicClient\n /** Optional custom broadcaster */\n broadcaster?: TxBroadcaster\n /** Optional nonce manager for concurrent transactions */\n nonceManager?: NonceManager\n /** Gas price multiplier (1.0 = no change, 1.1 = 10% increase) */\n gasPriceMultiplier?: number\n /** Optional gas limit override */\n gasLimit?: bigint\n}\n","/**\n * Approval functions for the Panoptic v2 SDK.\n * @module v2/writes/approve\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\nimport { erc20Abi } from 'viem'\n\nimport { collateralTrackerV2Abi, panopticPoolV2Abi } from '../../../generated'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport { submitWrite } from './utils'\n\n/**\n * Parameters for approve function.\n */\nexport interface ApproveParams {\n /** Public client for reading state */\n client: PublicClient\n /** Wallet client for signing transactions */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** Token address to approve */\n tokenAddress: Address\n /** Spender address (collateral tracker) */\n spenderAddress: Address\n /** Amount to approve (use MaxUint256 for unlimited) */\n amount: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Approve token spending for a collateral tracker.\n *\n * @param params - The approval parameters\n * @returns TxResult with hash and wait function\n *\n * @example\n * ```typescript\n * const result = await approve({\n * client,\n * walletClient,\n * account,\n * tokenAddress: WETH,\n * spenderAddress: collateralToken0,\n * amount: MaxUint256,\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function approve(params: ApproveParams): Promise<TxResult> {\n const { client, walletClient, account, tokenAddress, spenderAddress, amount, txOverrides } =\n params\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: tokenAddress,\n abi: erc20Abi,\n functionName: 'approve',\n args: [spenderAddress, amount],\n txOverrides,\n })\n}\n\n/**\n * Approve token spending and wait for confirmation.\n *\n * @param params - The approval parameters\n * @returns TxReceipt after confirmation\n */\nexport async function approveAndWait(params: ApproveParams): Promise<TxReceipt> {\n const result = await approve(params)\n return result.wait()\n}\n\n/**\n * Parameters for approving both tokens for a pool.\n */\nexport interface ApprovePoolParams {\n /** Public client for reading state */\n client: PublicClient\n /** Wallet client for signing transactions */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Amount to approve for token 0 */\n amount0: bigint\n /** Amount to approve for token 1 */\n amount1: bigint\n}\n\n/**\n * Approve both tokens for a Panoptic pool.\n * Fetches collateral tracker addresses and underlying tokens, then approves both.\n *\n * @param params - The approval parameters\n * @returns Array of two TxResults\n *\n * @example\n * ```typescript\n * const [result0, result1] = await approvePool({\n * client,\n * walletClient,\n * account,\n * poolAddress,\n * amount0: MaxUint256,\n * amount1: MaxUint256,\n * })\n * await Promise.all([result0.wait(), result1.wait()])\n * ```\n */\nexport async function approvePool(params: ApprovePoolParams): Promise<[TxResult, TxResult]> {\n const { client, walletClient, account, poolAddress, amount0, amount1 } = params\n\n // Get collateral tracker addresses\n const [collateralToken0, collateralToken1] = await client.multicall({\n contracts: [\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken0',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken1',\n },\n ],\n allowFailure: false,\n })\n\n // Get underlying token addresses\n const [token0, token1] = await client.multicall({\n contracts: [\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'asset',\n },\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'asset',\n },\n ],\n allowFailure: false,\n })\n\n // Approve both tokens in parallel\n const [result0, result1] = await Promise.all([\n approve({\n client,\n walletClient,\n account,\n tokenAddress: token0,\n spenderAddress: collateralToken0,\n amount: amount0,\n }),\n approve({\n client,\n walletClient,\n account,\n tokenAddress: token1,\n spenderAddress: collateralToken1,\n amount: amount1,\n }),\n ])\n\n return [result0, result1]\n}\n\n/**\n * Check if an approval is needed for a given amount.\n *\n * @param params - Parameters for checking approval\n * @returns Object with needsApproval flag and current allowance\n */\nexport interface CheckApprovalParams {\n /** Public client */\n client: PublicClient\n /** Token address */\n tokenAddress: Address\n /** Owner address */\n owner: Address\n /** Spender address */\n spender: Address\n /** Amount to check against */\n amount: bigint\n}\n\nexport interface ApprovalStatus {\n /** Whether approval is needed */\n needsApproval: boolean\n /** Current allowance */\n currentAllowance: bigint\n /** Amount that would be approved */\n requiredAmount: bigint\n}\n\n/**\n * Check if approval is needed for a token transfer.\n *\n * @param params - The check parameters\n * @returns Approval status\n */\nexport async function checkApproval(params: CheckApprovalParams): Promise<ApprovalStatus> {\n const { client, tokenAddress, owner, spender, amount } = params\n\n const currentAllowance = await client.readContract({\n address: tokenAddress,\n abi: erc20Abi,\n functionName: 'allowance',\n args: [owner, spender],\n })\n\n return {\n needsApproval: currentAllowance < amount,\n currentAllowance,\n requiredAmount: amount,\n }\n}\n","/**\n * ERC4626 vault operations for the Panoptic v2 SDK.\n * @module v2/writes/vault\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport { collateralTrackerV2Abi } from '../../../generated'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport { submitWrite } from './utils'\n\n/**\n * Parameters for deposit operation.\n */\nexport interface DepositParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** CollateralTracker address */\n collateralTrackerAddress: Address\n /** Amount of assets to deposit */\n assets: bigint\n /** Whether the collateral tracker wraps native ETH (requires sending msg.value) */\n isNativeETH?: boolean\n /** Receiver of shares (defaults to account) */\n receiver?: Address\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Deposit assets into a collateral tracker.\n *\n * @param params - Deposit parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * const result = await deposit({\n * client,\n * walletClient,\n * account,\n * collateralTrackerAddress,\n * assets: parseEther('1'),\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function deposit(params: DepositParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n collateralTrackerAddress,\n assets,\n isNativeETH,\n receiver = account,\n txOverrides,\n } = params\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'deposit',\n args: [assets, receiver],\n value: isNativeETH ? assets : undefined,\n txOverrides,\n })\n}\n\n/**\n * Deposit assets and wait for confirmation.\n */\nexport async function depositAndWait(params: DepositParams): Promise<TxReceipt> {\n const result = await deposit(params)\n return result.wait()\n}\n\n/**\n * Parameters for withdraw operation.\n */\nexport interface WithdrawParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** CollateralTracker address */\n collateralTrackerAddress: Address\n /** Amount of assets to withdraw */\n assets: bigint\n /** Receiver of assets */\n receiver?: Address\n /** Owner of shares (defaults to account) */\n owner?: Address\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Withdraw assets from a collateral tracker.\n *\n * @param params - Withdraw parameters\n * @returns TxResult\n */\nexport async function withdraw(params: WithdrawParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n collateralTrackerAddress,\n assets,\n receiver = account,\n owner = account,\n txOverrides,\n } = params\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'withdraw',\n args: [assets, receiver, owner],\n txOverrides,\n })\n}\n\n/**\n * Withdraw assets and wait for confirmation.\n */\nexport async function withdrawAndWait(params: WithdrawParams): Promise<TxReceipt> {\n const result = await withdraw(params)\n return result.wait()\n}\n\n/**\n * Parameters for withdraw with position list validation.\n */\nexport interface WithdrawWithPositionsParams extends WithdrawParams {\n /** Position ID list for collateral validation */\n positionIdList: bigint[]\n /** Whether to use premia as collateral */\n usePremiaAsCollateral: boolean\n}\n\n/**\n * Withdraw assets with position list validation.\n * This overload validates that the withdrawal won't make positions undercollateralized.\n *\n * @param params - Withdraw parameters with positions\n * @returns TxResult\n */\nexport async function withdrawWithPositions(\n params: WithdrawWithPositionsParams,\n): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n collateralTrackerAddress,\n assets,\n receiver = account,\n owner = account,\n positionIdList,\n usePremiaAsCollateral,\n txOverrides,\n } = params\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'withdraw',\n args: [assets, receiver, owner, positionIdList, usePremiaAsCollateral],\n txOverrides,\n })\n}\n\n/**\n * Withdraw with positions and wait for confirmation.\n */\nexport async function withdrawWithPositionsAndWait(\n params: WithdrawWithPositionsParams,\n): Promise<TxReceipt> {\n const result = await withdrawWithPositions(params)\n return result.wait()\n}\n\n/**\n * Parameters for mint operation.\n */\nexport interface MintParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** CollateralTracker address */\n collateralTrackerAddress: Address\n /** Amount of shares to mint */\n shares: bigint\n /** Receiver of shares */\n receiver?: Address\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Mint shares by depositing assets.\n *\n * @param params - Mint parameters\n * @returns TxResult\n */\nexport async function mint(params: MintParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n collateralTrackerAddress,\n shares,\n receiver = account,\n txOverrides,\n } = params\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'mint',\n args: [shares, receiver],\n txOverrides,\n })\n}\n\n/**\n * Mint shares and wait for confirmation.\n */\nexport async function mintAndWait(params: MintParams): Promise<TxReceipt> {\n const result = await mint(params)\n return result.wait()\n}\n\n/**\n * Parameters for redeem operation.\n */\nexport interface RedeemParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** CollateralTracker address */\n collateralTrackerAddress: Address\n /** Amount of shares to redeem */\n shares: bigint\n /** Receiver of assets */\n receiver?: Address\n /** Owner of shares */\n owner?: Address\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Redeem shares for assets.\n *\n * @param params - Redeem parameters\n * @returns TxResult\n */\nexport async function redeem(params: RedeemParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n collateralTrackerAddress,\n shares,\n receiver = account,\n owner = account,\n txOverrides,\n } = params\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'redeem',\n args: [shares, receiver, owner],\n txOverrides,\n })\n}\n\n/**\n * Redeem shares and wait for confirmation.\n */\nexport async function redeemAndWait(params: RedeemParams): Promise<TxReceipt> {\n const result = await redeem(params)\n return result.wait()\n}\n","/**\n * Position operations for the Panoptic v2 SDK.\n * @module v2/writes/position\n */\n\nimport type { Address, Hex, PublicClient, WalletClient } from 'viem'\nimport { encodeFunctionData } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { InvalidTickLimitsError, MissingPositionIdsError } from '../errors'\nimport type { StorageAdapter } from '../storage'\nimport { getPositionsKey, jsonSerializer } from '../storage'\nimport { getTrackedPositionIds } from '../sync/getTrackedPositionIds'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport { submitWrite } from './utils'\n\n/**\n * Optional storage parameters for auto-tracking positions.\n * When provided, `*AndWait` variants will automatically update the local\n * position cache after a successful transaction.\n */\nexport interface PositionStorageParams {\n /** Storage adapter for position tracking */\n storage: StorageAdapter\n /** Chain ID (required for storage key construction) */\n chainId: bigint\n}\n\n/**\n * Resolve the position ID list: use the explicit param if provided,\n * otherwise read from storage. Throws if neither is available.\n */\nasync function resolvePositionIds(\n explicit: bigint[] | undefined,\n storage: StorageAdapter | undefined,\n chainId: bigint | undefined,\n poolAddress: Address,\n account: Address,\n): Promise<bigint[]> {\n if (explicit !== undefined) return explicit\n if (storage && chainId !== undefined) {\n return getTrackedPositionIds({ chainId, poolAddress, account, storage })\n }\n throw new MissingPositionIdsError()\n}\n\n/**\n * Save a position ID list to storage.\n */\nasync function savePositionIds(\n storage: StorageAdapter,\n chainId: bigint,\n poolAddress: Address,\n account: Address,\n positionIds: bigint[],\n): Promise<void> {\n const key = getPositionsKey(chainId, poolAddress, account)\n await storage.set(key, jsonSerializer.stringify(positionIds))\n}\n\n/**\n * Tick and spread limits for position operations.\n * [tickLimitLow, tickLimitHigh, spreadLimitTick]\n *\n * SDK uses bigint for all numerics. Converted to number at viem boundary.\n *\n * @deprecated Use individual tickLimitLow, tickLimitHigh, spreadLimit params with swapAtMint flag\n */\nexport type TickAndSpreadLimits = readonly [bigint, bigint, bigint]\n\n/**\n * Parameters for opening a position.\n */\nexport interface OpenPositionParams extends Partial<PositionStorageParams> {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Existing position IDs held by the account (before this mint). Optional if storage + chainId are provided. */\n existingPositionIds?: bigint[]\n /** TokenId of the position to open */\n tokenId: bigint\n /** Position size (number of contracts) */\n positionSize: bigint\n /**\n * Lower tick limit (always <= tickLimitHigh).\n * Use MIN_TICK (-887272n) to allow any downward price movement.\n */\n tickLimitLow: bigint\n /**\n * Upper tick limit (always >= tickLimitLow).\n * Use MAX_TICK (887272n) to allow any upward price movement.\n */\n tickLimitHigh: bigint\n /** Spread limit tick (use 0n for no spread limit) */\n spreadLimit?: bigint\n /**\n * Whether to swap tokens at mint to achieve single-sided exposure.\n * When true, tickLimits are passed to dispatch in descending order (high, low).\n * When false (default), tickLimits are passed in ascending order (low, high).\n */\n swapAtMint?: boolean\n /** Whether to use premia as collateral */\n usePremiaAsCollateral?: boolean\n /** Builder code (defaults to 0) */\n builderCode?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Open a new position using dispatch.\n *\n * @param params - Position parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * import { MIN_TICK, MAX_TICK } from '@panoptic/sdk'\n *\n * const result = await openPosition({\n * client,\n * walletClient,\n * account,\n * poolAddress,\n * existingPositionIds: [], // Existing positions held before this mint\n * tokenId,\n * positionSize: 1n,\n * tickLimitLow: MIN_TICK,\n * tickLimitHigh: MAX_TICK,\n * swapAtMint: false, // true for covered/single-sided exposure\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function openPosition(params: OpenPositionParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n existingPositionIds: explicitIds,\n tokenId,\n positionSize,\n tickLimitLow,\n tickLimitHigh,\n spreadLimit = 0n,\n swapAtMint = false,\n usePremiaAsCollateral = false,\n builderCode = 0n,\n storage,\n chainId,\n txOverrides,\n } = params\n\n // Validate tick limits\n if (tickLimitLow > tickLimitHigh) {\n throw new InvalidTickLimitsError(tickLimitLow, tickLimitHigh)\n }\n\n const existingPositionIds = await resolvePositionIds(\n explicitIds,\n storage,\n chainId,\n poolAddress,\n account,\n )\n\n // Prepare position lists for dispatch:\n // - positionIdList: positions being minted in this call (just the new tokenId)\n // - finalPositionIdList: all positions the user will have after the mint\n const positionIdList = [tokenId]\n const finalPositionIdList = [...existingPositionIds, tokenId]\n\n // Position sizes array contains the size for the new position\n const positionSizes = [positionSize]\n\n // Build tick limits based on swapAtMint flag:\n // - swapAtMint=true: descending order (high, low) triggers SFPM swap\n // - swapAtMint=false: ascending order (low, high) no swap\n const tickLimits: readonly [number, number, number] = swapAtMint\n ? [Number(tickLimitHigh), Number(tickLimitLow), Number(spreadLimit)]\n : [Number(tickLimitLow), Number(tickLimitHigh), Number(spreadLimit)]\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n positionIdList,\n finalPositionIdList,\n positionSizes,\n [tickLimits],\n usePremiaAsCollateral,\n builderCode,\n ],\n txOverrides,\n })\n}\n\n/**\n * Build the dispatch calldata for opening a position without executing.\n * Returns the target address and encoded calldata, suitable for manual\n * transaction construction (e.g. RFQ broadcast-reconstruct flow).\n *\n * @param params - Position parameters (existingPositionIds required, no storage resolution)\n * @returns { to, data } — contract address and encoded dispatch calldata\n */\nexport function buildOpenPositionCalldata(params: {\n poolAddress: Address\n existingPositionIds: bigint[]\n tokenId: bigint\n positionSize: bigint\n tickLimitLow: bigint\n tickLimitHigh: bigint\n spreadLimit?: bigint\n swapAtMint?: boolean\n usePremiaAsCollateral?: boolean\n builderCode?: bigint\n}): { to: Address; data: Hex } {\n const {\n poolAddress,\n existingPositionIds,\n tokenId,\n positionSize,\n tickLimitLow,\n tickLimitHigh,\n spreadLimit = 0n,\n swapAtMint = false,\n usePremiaAsCollateral = false,\n builderCode = 0n,\n } = params\n\n if (tickLimitLow > tickLimitHigh) {\n throw new InvalidTickLimitsError(tickLimitLow, tickLimitHigh)\n }\n\n const positionIdList = [tokenId]\n const finalPositionIdList = [...existingPositionIds, tokenId]\n const positionSizes = [positionSize]\n\n const tickLimits: readonly [number, number, number] = swapAtMint\n ? [Number(tickLimitHigh), Number(tickLimitLow), Number(spreadLimit)]\n : [Number(tickLimitLow), Number(tickLimitHigh), Number(spreadLimit)]\n\n const data = encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n positionIdList,\n finalPositionIdList,\n positionSizes,\n [tickLimits],\n usePremiaAsCollateral,\n builderCode,\n ],\n })\n\n return { to: poolAddress, data }\n}\n\n/**\n * Open position and wait for confirmation.\n */\nexport async function openPositionAndWait(params: OpenPositionParams): Promise<TxReceipt> {\n const result = await openPosition(params)\n const receipt = await result.wait()\n\n // Auto-update storage if provided\n const {\n storage,\n chainId,\n account,\n poolAddress,\n tokenId,\n existingPositionIds: explicitIds,\n } = params\n if (storage && chainId !== undefined) {\n const base =\n explicitIds ?? (await getTrackedPositionIds({ chainId, poolAddress, account, storage }))\n await savePositionIds(storage, chainId, poolAddress, account, [...base, tokenId])\n }\n\n return receipt\n}\n\n/**\n * Parameters for closing a position.\n */\nexport interface ClosePositionParams extends Partial<PositionStorageParams> {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Current position ID list. Optional if storage + chainId are provided. */\n positionIdList?: bigint[]\n /** TokenId of the position to close */\n tokenId: bigint\n /** Position size to close (use full size for complete close) */\n positionSize: bigint\n /**\n * Lower tick limit (always <= tickLimitHigh).\n * Use MIN_TICK (-887272n) to allow any downward price movement.\n */\n tickLimitLow: bigint\n /**\n * Upper tick limit (always >= tickLimitLow).\n * Use MAX_TICK (887272n) to allow any upward price movement.\n */\n tickLimitHigh: bigint\n /** Spread limit tick (use 0n for no spread limit) */\n spreadLimit?: bigint\n /**\n * Whether to swap tokens at burn to achieve single-sided exposure.\n * When true, tickLimits are passed to dispatch in descending order (high, low).\n * When false (default), tickLimits are passed in ascending order (low, high).\n */\n swapAtMint?: boolean\n /** Whether to use premia as collateral */\n usePremiaAsCollateral?: boolean\n /** Builder code (defaults to 0) */\n builderCode?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Close an existing position using dispatch.\n *\n * @param params - Close parameters\n * @returns TxResult\n */\nexport async function closePosition(params: ClosePositionParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n positionIdList: explicitList,\n tokenId,\n tickLimitLow,\n tickLimitHigh,\n spreadLimit = 0n,\n swapAtMint = false,\n usePremiaAsCollateral = false,\n builderCode = 0n,\n storage,\n chainId,\n txOverrides,\n } = params\n\n // Validate tick limits\n if (tickLimitLow > tickLimitHigh) {\n throw new InvalidTickLimitsError(tickLimitLow, tickLimitHigh)\n }\n\n const positionIdList = await resolvePositionIds(\n explicitList,\n storage,\n chainId,\n poolAddress,\n account,\n )\n\n // For closing, final list excludes the closed position\n const finalPositionIdList = positionIdList.filter((id) => id !== tokenId)\n\n // Build tick limits based on swapAtMint flag:\n // - swapAtMint=true: descending order (high, low) triggers SFPM swap\n // - swapAtMint=false: ascending order (low, high) no swap\n const tickLimits: readonly [number, number, number] = swapAtMint\n ? [Number(tickLimitHigh), Number(tickLimitLow), Number(spreadLimit)]\n : [Number(tickLimitLow), Number(tickLimitHigh), Number(spreadLimit)]\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [[tokenId], finalPositionIdList, [0n], [tickLimits], usePremiaAsCollateral, builderCode],\n txOverrides,\n })\n}\n\n/**\n * Close position and wait for confirmation.\n */\nexport async function closePositionAndWait(params: ClosePositionParams): Promise<TxReceipt> {\n const result = await closePosition(params)\n const receipt = await result.wait()\n\n // Auto-update storage if provided\n const { storage, chainId, account, poolAddress, tokenId, positionIdList: explicitList } = params\n if (storage && chainId !== undefined) {\n const base =\n explicitList ?? (await getTrackedPositionIds({ chainId, poolAddress, account, storage }))\n await savePositionIds(\n storage,\n chainId,\n poolAddress,\n account,\n base.filter((id) => id !== tokenId),\n )\n }\n\n return receipt\n}\n\n/**\n * Parameters for rolling a position.\n */\nexport interface RollPositionParams extends Partial<PositionStorageParams> {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Current position ID list. Optional if storage + chainId are provided. */\n positionIdList?: bigint[]\n /** TokenId of position to close */\n oldTokenId: bigint\n /** Size of position being closed */\n oldPositionSize: bigint\n /** TokenId of new position to open */\n newTokenId: bigint\n /** Size of new position */\n newPositionSize: bigint\n /** Lower tick limit for close (always <= closeTickLimitHigh) */\n closeTickLimitLow: bigint\n /** Upper tick limit for close (always >= closeTickLimitLow) */\n closeTickLimitHigh: bigint\n /** Spread limit for close (use 0n for no spread limit) */\n closeSpreadLimit?: bigint\n /** Whether to swap tokens when closing */\n closeSwapAtMint?: boolean\n /** Lower tick limit for open (always <= openTickLimitHigh) */\n openTickLimitLow: bigint\n /** Upper tick limit for open (always >= openTickLimitLow) */\n openTickLimitHigh: bigint\n /** Spread limit for open (use 0n for no spread limit) */\n openSpreadLimit?: bigint\n /** Whether to swap tokens when opening */\n openSwapAtMint?: boolean\n /** Whether to use premia as collateral */\n usePremiaAsCollateral?: boolean\n /** Builder code */\n builderCode?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Roll a position (close one, open another) in a single transaction.\n *\n * @param params - Roll parameters\n * @returns TxResult\n */\nexport async function rollPosition(params: RollPositionParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n positionIdList: explicitList,\n oldTokenId,\n oldPositionSize,\n newTokenId,\n newPositionSize,\n closeTickLimitLow,\n closeTickLimitHigh,\n closeSpreadLimit = 0n,\n closeSwapAtMint = false,\n openTickLimitLow,\n openTickLimitHigh,\n openSpreadLimit = 0n,\n openSwapAtMint = false,\n usePremiaAsCollateral = false,\n builderCode = 0n,\n storage,\n chainId,\n txOverrides,\n } = params\n\n // Validate tick limits\n if (closeTickLimitLow > closeTickLimitHigh) {\n throw new InvalidTickLimitsError(closeTickLimitLow, closeTickLimitHigh)\n }\n if (openTickLimitLow > openTickLimitHigh) {\n throw new InvalidTickLimitsError(openTickLimitLow, openTickLimitHigh)\n }\n\n const positionIdList = await resolvePositionIds(\n explicitList,\n storage,\n chainId,\n poolAddress,\n account,\n )\n\n // Final list: remove old, add new\n const finalPositionIdList = positionIdList.filter((id) => id !== oldTokenId).concat([newTokenId])\n\n // Position sizes for both operations\n const positionSizes = [oldPositionSize, newPositionSize]\n\n // Build tick limits based on swapAtMint flags\n const closeLimits: readonly [number, number, number] = closeSwapAtMint\n ? [Number(closeTickLimitHigh), Number(closeTickLimitLow), Number(closeSpreadLimit)]\n : [Number(closeTickLimitLow), Number(closeTickLimitHigh), Number(closeSpreadLimit)]\n\n const openLimits: readonly [number, number, number] = openSwapAtMint\n ? [Number(openTickLimitHigh), Number(openTickLimitLow), Number(openSpreadLimit)]\n : [Number(openTickLimitLow), Number(openTickLimitHigh), Number(openSpreadLimit)]\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n positionIdList,\n finalPositionIdList,\n positionSizes as bigint[],\n [closeLimits, openLimits],\n usePremiaAsCollateral,\n builderCode,\n ],\n txOverrides,\n })\n}\n\n/**\n * Roll position and wait for confirmation.\n */\nexport async function rollPositionAndWait(params: RollPositionParams): Promise<TxReceipt> {\n const result = await rollPosition(params)\n const receipt = await result.wait()\n\n // Auto-update storage if provided\n const {\n storage,\n chainId,\n account,\n poolAddress,\n oldTokenId,\n newTokenId,\n positionIdList: explicitList,\n } = params\n if (storage && chainId !== undefined) {\n const base =\n explicitList ?? (await getTrackedPositionIds({ chainId, poolAddress, account, storage }))\n const updated = base.filter((id) => id !== oldTokenId).concat([newTokenId])\n await savePositionIds(storage, chainId, poolAddress, account, updated)\n }\n\n return receipt\n}\n","/**\n * Raw dispatch function for the Panoptic v2 SDK.\n * @module v2/writes/dispatch\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport type { TickAndSpreadLimits } from './position'\nimport { submitWrite } from './utils'\n\n/**\n * Parameters for dispatch function.\n */\nexport interface DispatchParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Current position ID list */\n positionIdList: bigint[]\n /** Final position ID list after operations */\n finalPositionIdList: bigint[]\n /** Position sizes for each operation */\n positionSizes: bigint[]\n /** Tick and spread limits for each operation */\n tickAndSpreadLimits: TickAndSpreadLimits[]\n /** Whether to use premia as collateral */\n usePremiaAsCollateral?: boolean\n /** Builder code */\n builderCode?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Execute a raw dispatch operation.\n * This is the low-level function for multi-position operations.\n *\n * @param params - Dispatch parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * // Open multiple positions atomically\n * const result = await dispatch({\n * client,\n * walletClient,\n * account,\n * poolAddress,\n * positionIdList: [],\n * finalPositionIdList: [tokenId1, tokenId2],\n * positionSizes: [size1, size2],\n * tickAndSpreadLimits: [limits1, limits2],\n * })\n * ```\n */\nexport async function dispatch(params: DispatchParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n positionIdList,\n finalPositionIdList,\n positionSizes,\n tickAndSpreadLimits,\n usePremiaAsCollateral = false,\n builderCode = 0n,\n txOverrides,\n } = params\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n positionIdList,\n finalPositionIdList,\n positionSizes.map((s) => BigInt(s) as unknown as bigint & { readonly __uint128: true }),\n tickAndSpreadLimits.map(\n (t) => [Number(t[0]), Number(t[1]), Number(t[2])] as readonly [number, number, number],\n ),\n usePremiaAsCollateral,\n builderCode,\n ],\n txOverrides,\n })\n}\n\n/**\n * Execute dispatch and wait for confirmation.\n */\nexport async function dispatchAndWait(params: DispatchParams): Promise<TxReceipt> {\n const result = await dispatch(params)\n return result.wait()\n}\n","/**\n * Item-based wrapper around dispatch() for batched mint/burn ops.\n * @module v2/writes/executeBatchDispatch\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport { buildBatchDispatchArgs } from '../batch/build'\nimport type { BatchOp } from '../batch/types'\nimport { BatchValidationError } from '../errors'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport { dispatch } from './dispatch'\n\nexport interface ExecuteBatchDispatchParams {\n client: PublicClient\n walletClient: WalletClient\n account: Address\n poolAddress: Address\n /** Batch ops in operation order. */\n items: BatchOp[]\n /** Current on-chain positionIdList for the account (fresh). */\n existingPositionIds: bigint[]\n /** Apply across the whole dispatch. Defaults to false. */\n usePremiaAsCollateral?: boolean\n /** Apply across the whole dispatch. Defaults to 0n. */\n builderCode?: bigint\n txOverrides?: TxOverrides\n}\n\n/**\n * Build dispatch args from a batch and submit them as a single transaction.\n *\n * Throws `BatchValidationError` (with the full diagnostics list) when the batch\n * fails validation. Callers that want to render diagnostics in UI should run\n * `buildBatchDispatchArgs` or `simulateBatchDispatch` first.\n */\nexport async function executeBatchDispatch(params: ExecuteBatchDispatchParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n items,\n existingPositionIds,\n usePremiaAsCollateral = false,\n builderCode = 0n,\n txOverrides,\n } = params\n\n const { args, diagnostics } = buildBatchDispatchArgs({\n items,\n existingPositionIds,\n usePremiaAsCollateral,\n builderCode,\n })\n\n if (args === null) {\n throw new BatchValidationError(diagnostics)\n }\n\n return dispatch({\n client,\n walletClient,\n account,\n poolAddress,\n positionIdList: args.positionIdList,\n finalPositionIdList: args.finalPositionIdList,\n positionSizes: args.positionSizes,\n tickAndSpreadLimits: args.tickAndSpreadLimits,\n usePremiaAsCollateral: args.usePremiaAsCollateral,\n builderCode: args.builderCode,\n txOverrides,\n })\n}\n\n/**\n * Execute a batch dispatch and wait for confirmation.\n */\nexport async function executeBatchDispatchAndWait(\n params: ExecuteBatchDispatchParams,\n): Promise<TxReceipt> {\n const result = await executeBatchDispatch(params)\n return result.wait()\n}\n","/**\n * Liquidation functions for the Panoptic v2 SDK.\n * @module v2/writes/liquidate\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport { submitWrite } from './utils'\n\n/**\n * Parameters for liquidating an account.\n */\nexport interface LiquidateParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Liquidator account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Account being liquidated */\n liquidatee: Address\n /** Position IDs from the liquidator's account */\n positionIdListFrom: bigint[]\n /** Position IDs of the liquidatee (positions to liquidate) */\n positionIdListTo: bigint[]\n /** Final position ID list for the liquidatee after liquidation */\n positionIdListToFinal: bigint[]\n /** Packed value for using premia as collateral */\n usePremiaAsCollateral?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Liquidate an undercollateralized account using dispatchFrom.\n *\n * The liquidator calls dispatchFrom to close the liquidatee's positions\n * and receive a bonus.\n *\n * @param params - Liquidation parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * const result = await liquidate({\n * client,\n * walletClient,\n * account: liquidatorAddress,\n * poolAddress,\n * liquidatee: undercollateralizedAccount,\n * positionIdListFrom: liquidatorPositions,\n * positionIdListTo: liquidateePositions,\n * positionIdListToFinal: [], // Close all positions\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function liquidate(params: LiquidateParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n liquidatee,\n positionIdListFrom,\n positionIdListTo,\n positionIdListToFinal,\n usePremiaAsCollateral = 0n,\n txOverrides,\n } = params\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatchFrom',\n args: [\n positionIdListFrom,\n liquidatee,\n positionIdListTo,\n positionIdListToFinal,\n usePremiaAsCollateral,\n ],\n txOverrides,\n })\n}\n\n/**\n * Liquidate and wait for confirmation.\n */\nexport async function liquidateAndWait(params: LiquidateParams): Promise<TxReceipt> {\n const result = await liquidate(params)\n return result.wait()\n}\n","/**\n * Force exercise functions for the Panoptic v2 SDK.\n * @module v2/writes/forceExercise\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport type { StorageAdapter } from '../storage'\nimport { syncPositions } from '../sync/syncPositions'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport { submitWrite } from './utils'\n\n/**\n * Parameters for force exercising a position.\n */\nexport interface ForceExerciseParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Exercisor account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Account whose position is being exercised */\n user: Address\n /** Position IDs from the exercisor's account */\n positionIdListFrom: bigint[]\n /** Position IDs of the target user */\n positionIdListTo: bigint[]\n /** Final position ID list for the user after exercise */\n positionIdListToFinal: bigint[]\n /** Packed value for using premia as collateral */\n usePremiaAsCollateral?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n /** Storage adapter for auto-syncing positions after confirmation */\n storage?: StorageAdapter\n /** Chain ID (required when storage is provided) */\n chainId?: bigint\n}\n\n/**\n * Force exercise an ITM (in-the-money) long position.\n *\n * The exercisor calls dispatchFrom to exercise another user's ITM long positions,\n * paying the exercise fee.\n *\n * @param params - Force exercise parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * const result = await forceExercise({\n * client,\n * walletClient,\n * account: exercisorAddress,\n * poolAddress,\n * user: targetAccount,\n * positionIdListFrom: exercisorPositions,\n * positionIdListTo: targetPositions,\n * positionIdListToFinal: [], // Exercise all ITM positions\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function forceExercise(params: ForceExerciseParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n user,\n positionIdListFrom,\n positionIdListTo,\n positionIdListToFinal,\n usePremiaAsCollateral = 0n,\n txOverrides,\n } = params\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatchFrom',\n args: [\n positionIdListFrom,\n user,\n positionIdListTo,\n positionIdListToFinal,\n usePremiaAsCollateral,\n ],\n txOverrides,\n })\n}\n\n/**\n * Force exercise and wait for confirmation.\n *\n * When `storage` and `chainId` are provided, automatically syncs the\n * exercisor's positions after the transaction confirms.\n */\nexport async function forceExerciseAndWait(params: ForceExerciseParams): Promise<TxReceipt> {\n const result = await forceExercise(params)\n const receipt = await result.wait()\n\n const { storage, chainId, client, poolAddress, account } = params\n if (storage && chainId !== undefined) {\n await syncPositions({\n client,\n chainId,\n poolAddress,\n account,\n storage,\n })\n }\n\n return receipt\n}\n","/**\n * Premium settlement functions for the Panoptic v2 SDK.\n * @module v2/writes/settle\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport type { TickAndSpreadLimits } from './position'\nimport { submitWrite } from './utils'\n\n/**\n * Parameters for settling accumulated premia.\n */\nexport interface SettleParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Current position ID list */\n positionIdList: bigint[]\n /** Whether to use premia as collateral */\n usePremiaAsCollateral?: boolean\n /** Builder code */\n builderCode?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Settle accumulated premia on existing positions.\n *\n * This function triggers premium collection without changing position size.\n * It calls dispatch with unchanged position lists.\n *\n * @param params - Settlement parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * const result = await settleAccumulatedPremia({\n * client,\n * walletClient,\n * account,\n * poolAddress,\n * positionIdList: existingPositions,\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function settleAccumulatedPremia(params: SettleParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n positionIdList,\n usePremiaAsCollateral = false,\n builderCode = 0n,\n txOverrides,\n } = params\n\n // For settlement, we call dispatch with:\n // - Same position lists (no change)\n // - Zero position sizes (no size change, just settle)\n // - Wide tick limits\n const positionSizes: bigint[] = positionIdList.map(() => 0n)\n const tickAndSpreadLimits: TickAndSpreadLimits[] = positionIdList.map(\n () => [-887272n, 887272n, 0n] as const,\n )\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n positionIdList,\n positionIdList, // Same list - no change\n positionSizes.map((s) => BigInt(s) as unknown as bigint & { readonly __uint128: true }),\n tickAndSpreadLimits.map(\n (t) => [Number(t[0]), Number(t[1]), Number(t[2])] as readonly [number, number, number],\n ),\n usePremiaAsCollateral,\n builderCode,\n ],\n txOverrides,\n })\n}\n\n/**\n * Settle premia and wait for confirmation.\n */\nexport async function settleAccumulatedPremiaAndWait(params: SettleParams): Promise<TxReceipt> {\n const result = await settleAccumulatedPremia(params)\n return result.wait()\n}\n","/**\n * Oracle poke function for the Panoptic v2 SDK.\n * @module v2/writes/pokeOracle\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { OracleRateLimitedError } from '../errors'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport { decodeOracleTiming, oracleEpochAt } from '../utils/oraclePack'\nimport { submitWrite } from './utils'\n\n/**\n * Parameters for poking the oracle.\n */\nexport interface PokeOracleParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Whether to check rate limit before calling (optional) */\n checkRateLimit?: boolean\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Poke the oracle to update its state.\n *\n * This function can be called to advance the oracle epoch.\n * Note: The oracle can only be poked once per epoch (64 seconds).\n *\n * @param params - Poke oracle parameters\n * @returns TxResult\n * @throws OracleRateLimitedError if checkRateLimit is true and oracle was recently poked\n *\n * @example\n * ```typescript\n * const result = await pokeOracle({\n * client,\n * walletClient,\n * account,\n * poolAddress,\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function pokeOracle(params: PokeOracleParams): Promise<TxResult> {\n const { client, walletClient, account, poolAddress, checkRateLimit = false, txOverrides } = params\n\n if (checkRateLimit) {\n // Check current oracle state to see if we can poke\n // Fetch oracle data and block in parallel\n const [oracleData, block] = await Promise.all([\n client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getOracleTicks',\n }),\n client.getBlock(),\n ])\n\n // oracleData[4] is the oraclePack\n const oraclePack = oracleData[4]\n const { epoch } = decodeOracleTiming(oraclePack, block.timestamp)\n\n const currentEpoch = oracleEpochAt(block.timestamp)\n\n // If current epoch equals oracle epoch, we can't poke yet\n if (currentEpoch === epoch) {\n const lastUpdate = epoch << 6n\n throw new OracleRateLimitedError(lastUpdate, block.timestamp)\n }\n }\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'pokeOracle',\n args: [],\n txOverrides,\n })\n}\n\n/**\n * Poke oracle and wait for confirmation.\n */\nexport async function pokeOracleAndWait(params: PokeOracleParams): Promise<TxReceipt> {\n const result = await pokeOracle(params)\n return result.wait()\n}\n","/**\n * Factory write functions for the Panoptic v2 SDK.\n * @module v2/writes/factory\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport { panopticFactoryV3Abi, panopticFactoryV4Abi } from '../../../generated'\nimport type { PoolKey, TxOverrides, TxResult } from '../types'\nimport { submitWrite } from './utils'\n\ninterface DeployNewPoolCommon {\n /** Public client */\n client: PublicClient\n /** Wallet client for signing */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticFactory address */\n factoryAddress: Address\n /** Risk engine address */\n riskEngine: Address\n /** Salt (uint96) */\n salt: bigint\n /** Optional transaction overrides */\n txOverrides?: TxOverrides\n}\n\nexport interface DeployNewPoolV3Params extends DeployNewPoolCommon {\n /** Token 0 address */\n token0: Address\n /** Token 1 address */\n token1: Address\n /** Fee tier (uint24) */\n fee: bigint\n}\n\nexport interface DeployNewPoolV4Params extends DeployNewPoolCommon {\n /** V4 pool key */\n poolKey: PoolKey\n}\n\nexport type DeployNewPoolParams =\n | ({ version: 'v3' } & DeployNewPoolV3Params)\n | ({ version: 'v4' } & DeployNewPoolV4Params)\n\n/**\n * Deploy a new Panoptic pool via the factory.\n *\n * @param params - Deployment parameters (versioned: 'v3' or 'v4')\n * @returns Transaction result with hash and wait function\n */\nexport async function deployNewPool(params: DeployNewPoolParams): Promise<TxResult> {\n const { client, walletClient, account, factoryAddress, riskEngine, salt, txOverrides } = params\n\n if (params.version === 'v3') {\n return submitWrite({\n client,\n walletClient,\n account,\n address: factoryAddress,\n abi: panopticFactoryV3Abi,\n functionName: 'deployNewPool',\n args: [params.token0, params.token1, params.fee, riskEngine, salt],\n txOverrides,\n })\n }\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: factoryAddress,\n abi: panopticFactoryV4Abi,\n functionName: 'deployNewPool',\n args: [\n {\n currency0: params.poolKey.currency0,\n currency1: params.poolKey.currency1,\n fee: Number(params.poolKey.fee),\n tickSpacing: Number(params.poolKey.tickSpacing),\n hooks: params.poolKey.hooks,\n },\n riskEngine,\n salt,\n ],\n txOverrides,\n })\n}\n\n/**\n * Deploy a new Panoptic pool and wait for confirmation.\n */\nexport async function deployNewPoolAndWait(params: DeployNewPoolParams) {\n const result = await deployNewPool(params)\n return result.wait()\n}\n","/**\n * Transaction replacement utilities for the Panoptic v2 SDK.\n * Provides speedUp and cancel functionality for pending transactions.\n * @module v2/writes/txManagement\n */\n\nimport type { Address, Hash, PublicClient, WalletClient } from 'viem'\n\nimport type { TxBroadcaster, TxResult } from '../types'\nimport { createTxResult } from './utils'\n\n/** Default gas price multiplier for replacement (12.5% bump = minimum for replacement) */\nconst DEFAULT_GAS_PRICE_MULTIPLIER = 1.125\n\n/**\n * Parameters for speeding up a pending transaction.\n */\nexport interface SpeedUpParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Hash of the pending transaction to speed up */\n hash: Hash\n /** Explicit max fee per gas (overrides multiplier) */\n maxFeePerGas?: bigint\n /** Explicit max priority fee per gas (overrides multiplier) */\n maxPriorityFeePerGas?: bigint\n /** Multiplier for gas price bump (default 1.125 = 12.5%, minimum to replace) */\n gasPriceMultiplier?: number\n /** Custom broadcaster for MEV protection */\n broadcaster?: TxBroadcaster\n}\n\n/**\n * Parameters for cancelling a pending transaction.\n */\nexport interface CancelParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address (for self-transfer) */\n account: Address\n /** Hash of the pending transaction to cancel */\n hash: Hash\n /** Explicit max fee per gas (overrides multiplier) */\n maxFeePerGas?: bigint\n /** Explicit max priority fee per gas (overrides multiplier) */\n maxPriorityFeePerGas?: bigint\n /** Multiplier for gas price bump (default 1.125 = 12.5%, minimum to replace) */\n gasPriceMultiplier?: number\n /** Custom broadcaster for MEV protection */\n broadcaster?: TxBroadcaster\n}\n\n/**\n * Apply a multiplier to a bigint gas value.\n * Uses integer arithmetic to avoid floating point issues.\n */\nfunction applyMultiplier(value: bigint, multiplier: number): bigint {\n // Convert multiplier to basis points (e.g., 1.125 => 11250)\n const bps = BigInt(Math.ceil(multiplier * 10000))\n return (value * bps) / 10000n\n}\n\n/**\n * Compute bumped gas parameters from the original transaction.\n */\nfunction computeBumpedGas(\n originalMaxFeePerGas: bigint | undefined,\n originalMaxPriorityFeePerGas: bigint | undefined,\n explicitMaxFeePerGas: bigint | undefined,\n explicitMaxPriorityFeePerGas: bigint | undefined,\n multiplier: number,\n): { maxFeePerGas: bigint; maxPriorityFeePerGas: bigint } {\n const maxFeePerGas =\n explicitMaxFeePerGas ?? applyMultiplier(originalMaxFeePerGas ?? 0n, multiplier)\n\n const maxPriorityFeePerGas =\n explicitMaxPriorityFeePerGas ?? applyMultiplier(originalMaxPriorityFeePerGas ?? 0n, multiplier)\n\n return { maxFeePerGas, maxPriorityFeePerGas }\n}\n\n/**\n * Speed up a pending transaction by resubmitting with higher gas.\n *\n * Fetches the original transaction, extracts its parameters,\n * bumps the gas price, and resubmits with the same nonce.\n *\n * @param params - Speed up parameters\n * @returns TxResult for the replacement transaction\n * @throws Error if the original transaction is not found\n *\n * @example\n * ```typescript\n * // Speed up with default 12.5% bump\n * const result = await speedUpTransaction({\n * client,\n * walletClient,\n * hash: pendingTxHash,\n * })\n *\n * // Speed up with explicit gas prices\n * const result = await speedUpTransaction({\n * client,\n * walletClient,\n * hash: pendingTxHash,\n * maxFeePerGas: 50_000_000_000n, // 50 gwei\n * maxPriorityFeePerGas: 3_000_000_000n, // 3 gwei\n * })\n * ```\n */\nexport async function speedUpTransaction(params: SpeedUpParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n hash,\n maxFeePerGas: explicitMaxFee,\n maxPriorityFeePerGas: explicitMaxPriority,\n gasPriceMultiplier = DEFAULT_GAS_PRICE_MULTIPLIER,\n broadcaster,\n } = params\n\n const tx = await client.getTransaction({ hash })\n\n const { maxFeePerGas, maxPriorityFeePerGas } = computeBumpedGas(\n tx.maxFeePerGas ?? undefined,\n tx.maxPriorityFeePerGas ?? undefined,\n explicitMaxFee,\n explicitMaxPriority,\n gasPriceMultiplier,\n )\n\n if (broadcaster) {\n const request = await walletClient.prepareTransactionRequest({\n account: tx.from,\n to: tx.to ?? undefined,\n data: tx.input,\n value: tx.value,\n nonce: tx.nonce,\n gas: tx.gas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n chain: walletClient.chain,\n })\n\n const signedTx = await walletClient.signTransaction({\n ...request,\n account: tx.from,\n } as unknown as Parameters<WalletClient['signTransaction']>[0])\n const replacementHash = await broadcaster.broadcast(signedTx)\n return createTxResult(client, replacementHash)\n }\n\n const replacementHash = await walletClient.sendTransaction({\n account: tx.from,\n to: tx.to ?? undefined,\n data: tx.input,\n value: tx.value,\n nonce: tx.nonce,\n gas: tx.gas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n chain: walletClient.chain,\n })\n\n return createTxResult(client, replacementHash)\n}\n\n/**\n * Cancel a pending transaction by sending a 0-value self-transfer\n * with the same nonce and higher gas price.\n *\n * @param params - Cancel parameters\n * @returns TxResult for the cancellation transaction\n * @throws Error if the original transaction is not found\n *\n * @example\n * ```typescript\n * const result = await cancelTransaction({\n * client,\n * walletClient,\n * account,\n * hash: pendingTxHash,\n * })\n * await result.wait()\n * ```\n */\nexport async function cancelTransaction(params: CancelParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n hash,\n maxFeePerGas: explicitMaxFee,\n maxPriorityFeePerGas: explicitMaxPriority,\n gasPriceMultiplier = DEFAULT_GAS_PRICE_MULTIPLIER,\n broadcaster,\n } = params\n\n const tx = await client.getTransaction({ hash })\n\n const { maxFeePerGas, maxPriorityFeePerGas } = computeBumpedGas(\n tx.maxFeePerGas ?? undefined,\n tx.maxPriorityFeePerGas ?? undefined,\n explicitMaxFee,\n explicitMaxPriority,\n gasPriceMultiplier,\n )\n\n if (broadcaster) {\n const request = await walletClient.prepareTransactionRequest({\n account,\n to: account,\n value: 0n,\n nonce: tx.nonce,\n gas: 21000n,\n maxFeePerGas,\n maxPriorityFeePerGas,\n chain: walletClient.chain,\n })\n\n const signedTx = await walletClient.signTransaction({\n ...request,\n account,\n } as unknown as Parameters<WalletClient['signTransaction']>[0])\n const cancelHash = await broadcaster.broadcast(signedTx)\n return createTxResult(client, cancelHash)\n }\n\n const cancelHash = await walletClient.sendTransaction({\n account,\n to: account,\n value: 0n,\n nonce: tx.nonce,\n gas: 21000n,\n maxFeePerGas,\n maxPriorityFeePerGas,\n chain: walletClient.chain,\n })\n\n return createTxResult(client, cancelHash)\n}\n","/**\n * Swap functions for the Panoptic v2 SDK.\n *\n * Implements token swaps via Panoptic's **credit** mechanism: open a width=0\n * credit leg and immediately close it in the same dispatch, with `swapAtMint`\n * on exactly one of the two ops.\n *\n * Credits rather than loans because a credit pays into the pool instead of\n * borrowing from it: it requires zero buying power, never touches\n * `s_assetsInAMM`, and so can never be capped by a collateral tracker's\n * utilization or available-to-borrow. A loan-based swap against a\n * fully-utilized tracker simply fails.\n *\n * @module v2/writes/swap\n */\n\nimport type { Address, Hex, PublicClient, WalletClient } from 'viem'\nimport { encodeFunctionData } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { MaxRetriesExceededError } from '../errors'\nimport { tickLimits } from '../formatters/tick'\nimport { getPool } from '../reads/pool'\nimport type { StorageAdapter } from '../storage'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport {\n buildUniqueCredit,\n isInputListFailError,\n MAX_RETRIES,\n resolvePositionIds,\n resolveTokenIndex,\n} from './loanUtils'\nimport { submitWrite } from './utils'\n\n/**\n * Parameters for building an atomic credit swap call.\n *\n * `tokenIndex` is tokenOut for exact-out swaps and tokenIn for exact-in swaps.\n * Passing the counter-token reverses the intended swap direction.\n */\nexport type CreditSwapCallParams = {\n poolAddress: Address\n poolId: bigint\n currentTick: bigint\n tickSpacing: bigint\n existingPositionIds: bigint[]\n tokenIndex: bigint\n slippageBps: bigint\n builderCode?: bigint\n} & ({ kind: 'exactIn'; amountIn: bigint } | { kind: 'exactOut'; amountOut: bigint })\n\n/** Encoded atomic credit mint/burn dispatch and its derived credit position. */\nexport interface CreditSwapCall {\n to: Address\n data: Hex\n creditTokenId: bigint\n adjustedSize: bigint\n args: readonly [\n readonly bigint[],\n readonly bigint[],\n readonly bigint[],\n readonly (readonly [number, number, number])[],\n boolean,\n bigint,\n ]\n}\n\n/** Build an atomic credit mint/burn swap without fetching or sending anything. */\nexport function buildCreditSwapCall(params: CreditSwapCallParams): CreditSwapCall {\n const amount = params.kind === 'exactIn' ? params.amountIn : params.amountOut\n if (amount <= 0n) throw new Error('credit swap amount must be positive')\n if (params.tokenIndex !== 0n && params.tokenIndex !== 1n) {\n throw new Error('credit swap tokenIndex must be 0 or 1')\n }\n\n const { low, high } = tickLimits(params.currentTick, params.slippageBps)\n const { tokenId: creditTokenId, adjustedSize } = buildUniqueCredit(\n params.poolId,\n params.tokenIndex,\n params.tokenIndex,\n params.currentTick,\n params.tickSpacing,\n params.existingPositionIds,\n amount,\n )\n const ascending = [Number(low), Number(high), 0] as const\n const descending = [Number(high), Number(low), 0] as const\n const limits =\n params.kind === 'exactIn'\n ? ([ascending, descending] as const)\n : ([descending, ascending] as const)\n const args = [\n [creditTokenId, creditTokenId],\n [...params.existingPositionIds],\n [adjustedSize, 0n],\n limits,\n false,\n params.builderCode ?? 0n,\n ] as const\n\n return {\n to: params.poolAddress,\n data: encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args,\n }),\n creditTokenId,\n adjustedSize,\n args,\n }\n}\n\n/**\n * Parameters for swapExactOut.\n */\nexport interface SwapExactOutParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Chain ID (required for pool data fetch) */\n chainId: bigint\n /** Token address you want to receive */\n tokenOut: Address\n /** Exact amount of tokenOut to receive */\n amountOut: bigint\n /** Slippage tolerance in bps (e.g. 500n = 5%) */\n slippageBps: bigint\n /** Existing position IDs. If omitted, resolved from storage. */\n existingPositionIds?: bigint[]\n /** Storage adapter for position ID resolution */\n storage?: StorageAdapter\n /** Builder code for referral fee attribution. Defaults to `0n`. */\n builderCode?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Parameters for swapExactIn.\n */\nexport interface SwapExactInParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Chain ID (required for pool data fetch) */\n chainId: bigint\n /** Token address you want to sell */\n tokenIn: Address\n /** Exact amount of tokenIn to spend */\n amountIn: bigint\n /** Slippage tolerance in bps (e.g. 500n = 5%) */\n slippageBps: bigint\n /** Existing position IDs. If omitted, resolved from storage. */\n existingPositionIds?: bigint[]\n /** Storage adapter for position ID resolution */\n storage?: StorageAdapter\n /** Builder code for referral fee attribution. Defaults to `0n`. */\n builderCode?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Swap tokens using Panoptic's exact-output mechanism.\n *\n * Opens a credit in `tokenOut` with `swapAtMint=true` (paying a swapped amount of\n * the other token), then burns it with `swapAtMint=false` to receive exactly\n * `amountOut` of `tokenOut`.\n *\n * @param params - Swap parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * const result = await swapExactOut({\n * client, walletClient, account, poolAddress,\n * chainId: 11155111n,\n * tokenOut: WETH_ADDRESS,\n * amountOut: 5n * 10n**16n, // 0.05 WETH\n * slippageBps: 500n, // 5% slippage\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function swapExactOut(params: SwapExactOutParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n chainId,\n tokenOut,\n amountOut,\n slippageBps,\n existingPositionIds: explicitIds,\n storage,\n builderCode = 0n,\n txOverrides,\n } = params\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n // Re-fetch pool + positions on each attempt for freshness\n const [pool, positionIds] = await Promise.all([\n getPool({ client, poolAddress, chainId }),\n resolvePositionIds(explicitIds, storage, chainId, poolAddress, account),\n ])\n\n const token0 = pool.collateralTracker0.token\n const token1 = pool.collateralTracker1.token\n const tokenOutIndex = resolveTokenIndex(tokenOut, token0, token1)\n\n // The credit is denominated in the EXACT token — tokenOut here, mirroring\n // swapExactIn's tokenIn. asset === tokenType.\n //\n // Do NOT set tokenType to the other token. That is correct for a *loan*\n // (which borrows the counter-token and swaps it in), and carrying it over to\n // the credit inverts the whole swap: an exact-out for 4 ETH then PAYS 4 ETH\n // and receives USDC. Verified on mainnet before/after.\n const call = buildCreditSwapCall({\n kind: 'exactOut',\n poolAddress,\n poolId: pool.poolId,\n currentTick: pool.currentTick,\n tickSpacing: pool.tickSpacing,\n existingPositionIds: positionIds,\n tokenIndex: tokenOutIndex,\n amountOut,\n slippageBps,\n builderCode,\n })\n\n try {\n return await submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: call.args,\n txOverrides,\n })\n } catch (error) {\n if (isInputListFailError(error) && attempt < MAX_RETRIES - 1) {\n continue\n }\n throw error\n }\n }\n\n throw new MaxRetriesExceededError('swapExactOut')\n}\n\n/**\n * Swap exact output and wait for confirmation.\n */\nexport async function swapExactOutAndWait(params: SwapExactOutParams): Promise<TxReceipt> {\n const result = await swapExactOut(params)\n return result.wait()\n}\n\n/**\n * Swap tokens using Panoptic's exact-input mechanism.\n *\n * Opens a credit in `tokenIn` with `swapAtMint=false` (paying exactly `amountIn`),\n * then burns it with `swapAtMint=true` to receive the swapped amount of the other\n * token. The user spends exactly `amountIn` of `tokenIn`.\n *\n * @param params - Swap parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * const result = await swapExactIn({\n * client, walletClient, account, poolAddress,\n * chainId: 11155111n,\n * tokenIn: USDC_ADDRESS,\n * amountIn: 1000n * 10n**6n, // 1000 USDC\n * slippageBps: 500n,\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function swapExactIn(params: SwapExactInParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n chainId,\n tokenIn,\n amountIn,\n slippageBps,\n existingPositionIds: explicitIds,\n storage,\n builderCode = 0n,\n txOverrides,\n } = params\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n const [pool, positionIds] = await Promise.all([\n getPool({ client, poolAddress, chainId }),\n resolvePositionIds(explicitIds, storage, chainId, poolAddress, account),\n ])\n\n const token0 = pool.collateralTracker0.token\n const token1 = pool.collateralTracker1.token\n const tokenInIndex = resolveTokenIndex(tokenIn, token0, token1)\n\n // For exact input: the credit is denominated in tokenIn and paid in tokenIn\n const call = buildCreditSwapCall({\n kind: 'exactIn',\n poolAddress,\n poolId: pool.poolId,\n currentTick: pool.currentTick,\n tickSpacing: pool.tickSpacing,\n existingPositionIds: positionIds,\n tokenIndex: tokenInIndex,\n amountIn,\n slippageBps,\n builderCode,\n })\n\n try {\n return await submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: call.args,\n txOverrides,\n })\n } catch (error) {\n if (isInputListFailError(error) && attempt < MAX_RETRIES - 1) {\n continue\n }\n throw error\n }\n }\n\n throw new MaxRetriesExceededError('swapExactIn')\n}\n\n/**\n * Swap exact input and wait for confirmation.\n */\nexport async function swapExactInAndWait(params: SwapExactInParams): Promise<TxReceipt> {\n const result = await swapExactIn(params)\n return result.wait()\n}\n","/**\n * Wrap / unwrap operations for Backed xStock ERC4626 wrappers.\n *\n * xStocks are rebasing and can't be used in Panoptic/Uniswap pools directly;\n * those trade the non-rebasing **wrapper** (a standard ERC4626 vault whose\n * `asset()` is the underlying xStock). Wrapping is an ERC4626 `deposit`,\n * unwrapping an ERC4626 `redeem`. CoW Swap trades the unwrapped token, so a\n * user who buys an xStock on CoW must wrap it before lending it or selling it\n * through the Uniswap venue.\n *\n * Resolve a token's wrapper with `getXstockWrapper` from `@panoptic-eng/sdk`.\n *\n * @module v2/writes/wrap\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport { submitWrite } from './utils'\n\n/** Minimal ERC4626 surface used by the xStock wrappers. */\nexport const xstockWrapperAbi = [\n {\n type: 'function',\n name: 'deposit',\n stateMutability: 'nonpayable',\n inputs: [\n { name: 'assets', type: 'uint256' },\n { name: 'receiver', type: 'address' },\n ],\n outputs: [{ name: 'shares', type: 'uint256' }],\n },\n {\n type: 'function',\n name: 'redeem',\n stateMutability: 'nonpayable',\n inputs: [\n { name: 'shares', type: 'uint256' },\n { name: 'receiver', type: 'address' },\n { name: 'owner', type: 'address' },\n ],\n outputs: [{ name: 'assets', type: 'uint256' }],\n },\n {\n type: 'function',\n name: 'asset',\n stateMutability: 'view',\n inputs: [],\n outputs: [{ type: 'address' }],\n },\n {\n type: 'function',\n name: 'previewDeposit',\n stateMutability: 'view',\n inputs: [{ name: 'assets', type: 'uint256' }],\n outputs: [{ name: 'shares', type: 'uint256' }],\n },\n {\n type: 'function',\n name: 'previewRedeem',\n stateMutability: 'view',\n inputs: [{ name: 'shares', type: 'uint256' }],\n outputs: [{ name: 'assets', type: 'uint256' }],\n },\n {\n type: 'function',\n name: 'maxRedeem',\n stateMutability: 'view',\n inputs: [{ name: 'owner', type: 'address' }],\n outputs: [{ name: 'maxShares', type: 'uint256' }],\n },\n] as const\n\n/** Parameters for {@link wrapXstock}. */\nexport interface WrapXstockParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** Wrapper (ERC4626) address — resolve via `getXstockWrapper`. */\n wrapper: Address\n /** Amount of the underlying xStock to wrap. */\n assets: bigint\n /** Receiver of the wrapper shares (defaults to account). */\n receiver?: Address\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Wrap an underlying xStock into its ERC4626 wrapper (`deposit`). Requires a\n * prior ERC20 approval of the underlying to the wrapper address.\n *\n * @returns TxResult with hash and wait function\n */\nexport async function wrapXstock(params: WrapXstockParams): Promise<TxResult> {\n const { client, walletClient, account, wrapper, assets, receiver = account, txOverrides } = params\n return submitWrite({\n client,\n walletClient,\n account,\n address: wrapper,\n abi: xstockWrapperAbi,\n functionName: 'deposit',\n args: [assets, receiver],\n txOverrides,\n })\n}\n\n/** Wrap and wait for confirmation. */\nexport async function wrapXstockAndWait(params: WrapXstockParams): Promise<TxReceipt> {\n const result = await wrapXstock(params)\n return result.wait()\n}\n\n/** Parameters for {@link unwrapXstock}. */\nexport interface UnwrapXstockParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** Wrapper (ERC4626) address — resolve via `getXstockUnderlying`. */\n wrapper: Address\n /** Amount of wrapper shares to unwrap (redeem). */\n shares: bigint\n /** Receiver of the underlying xStock (defaults to account). */\n receiver?: Address\n /** Owner of the shares (defaults to account). */\n owner?: Address\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Unwrap wrapper shares back into the underlying xStock (`redeem`). When\n * `owner` defaults to (or equals) `account` the caller burns their own shares\n * and no approval is needed. Passing a different `owner` redeems on its behalf\n * and requires that owner to have granted the caller an ERC-4626 share\n * allowance (`approve`), or the `redeem` call reverts.\n *\n * @returns TxResult with hash and wait function\n */\nexport async function unwrapXstock(params: UnwrapXstockParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n wrapper,\n shares,\n receiver = account,\n owner = account,\n txOverrides,\n } = params\n return submitWrite({\n client,\n walletClient,\n account,\n address: wrapper,\n abi: xstockWrapperAbi,\n functionName: 'redeem',\n args: [shares, receiver, owner],\n txOverrides,\n })\n}\n\n/** Unwrap and wait for confirmation. */\nexport async function unwrapXstockAndWait(params: UnwrapXstockParams): Promise<TxReceipt> {\n const result = await unwrapXstock(params)\n return result.wait()\n}\n\n/** Parameters for the wrap/unwrap amount previews. */\nexport interface PreviewWrapParams {\n /** Public client */\n client: PublicClient\n /** Wrapper (ERC4626) address. */\n wrapper: Address\n /** Amount to convert: underlying assets for wrap, shares for unwrap. */\n amount: bigint\n}\n\n/**\n * Preview the wrapper shares minted for a given amount of underlying xStock.\n */\nexport async function previewWrap(params: PreviewWrapParams): Promise<bigint> {\n const { client, wrapper, amount } = params\n return client.readContract({\n address: wrapper,\n abi: xstockWrapperAbi,\n functionName: 'previewDeposit',\n args: [amount],\n })\n}\n\n/**\n * Preview the underlying xStock returned for a given amount of wrapper shares.\n */\nexport async function previewUnwrap(params: PreviewWrapParams): Promise<bigint> {\n const { client, wrapper, amount } = params\n return client.readContract({\n address: wrapper,\n abi: xstockWrapperAbi,\n functionName: 'previewRedeem',\n args: [amount],\n })\n}\n\n/**\n * Minimal canonical WETH9 surface used for ETH<->WETH wrapping. Unlike the\n * ERC4626 xStock wrapper, WETH is a 1:1 wrapper: `deposit` is payable and wraps\n * `msg.value`, `withdraw` unwraps an exact amount back to native ETH.\n */\nexport const wethWrapAbi = [\n {\n type: 'function',\n name: 'deposit',\n stateMutability: 'payable',\n inputs: [],\n outputs: [],\n },\n {\n type: 'function',\n name: 'withdraw',\n stateMutability: 'nonpayable',\n inputs: [{ name: 'wad', type: 'uint256' }],\n outputs: [],\n },\n] as const\n\n/** Parameters for {@link wrapEth}. */\nexport interface WrapEthParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** Canonical WETH9 address for the chain. */\n weth: Address\n /** Amount of native ETH to wrap (sent as msg.value). */\n amount: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Wrap native ETH into WETH (`deposit` payable). No approval needed.\n *\n * @returns TxResult with hash and wait function\n */\nexport async function wrapEth(params: WrapEthParams): Promise<TxResult> {\n const { client, walletClient, account, weth, amount, txOverrides } = params\n return submitWrite({\n client,\n walletClient,\n account,\n address: weth,\n abi: wethWrapAbi,\n functionName: 'deposit',\n args: [],\n value: amount,\n txOverrides,\n })\n}\n\n/** Wrap ETH and wait for confirmation. */\nexport async function wrapEthAndWait(params: WrapEthParams): Promise<TxReceipt> {\n const result = await wrapEth(params)\n return result.wait()\n}\n\n/** Parameters for {@link unwrapWeth}. */\nexport interface UnwrapWethParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** Canonical WETH9 address for the chain. */\n weth: Address\n /** Amount of WETH to unwrap back to native ETH. */\n amount: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Unwrap WETH back into native ETH (`withdraw`). Burns the caller's own WETH —\n * no approval needed.\n *\n * @returns TxResult with hash and wait function\n */\nexport async function unwrapWeth(params: UnwrapWethParams): Promise<TxResult> {\n const { client, walletClient, account, weth, amount, txOverrides } = params\n return submitWrite({\n client,\n walletClient,\n account,\n address: weth,\n abi: wethWrapAbi,\n functionName: 'withdraw',\n args: [amount],\n txOverrides,\n })\n}\n\n/** Unwrap WETH and wait for confirmation. */\nexport async function unwrapWethAndWait(params: UnwrapWethParams): Promise<TxReceipt> {\n const result = await unwrapWeth(params)\n return result.wait()\n}\n","/**\n * Lending API for the Panoptic v2 SDK.\n *\n * Provides Aave/Compound-style supply/borrow/repay/unsupply functions\n * that wrap the lower-level vault and position primitives.\n *\n * @module v2/writes/lending\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { MaxRetriesExceededError, NoLoanPositionsError } from '../errors'\nimport { tickLimits } from '../formatters/tick'\nimport { getPool } from '../reads/pool'\nimport { simulateOpenPosition } from '../simulations/simulateOpenPosition'\nimport type { StorageAdapter } from '../storage'\nimport { getPositionsKey, jsonSerializer } from '../storage'\nimport { getTrackedPositionIds } from '../sync/getTrackedPositionIds'\nimport { isLoan } from '../tokenId/decode'\nimport { decodeAllLegs } from '../tokenId/encoding'\nimport type {\n OpenPositionSimulation,\n SimulationResult,\n TxOverrides,\n TxReceipt,\n TxResult,\n} from '../types'\nimport {\n buildUniqueLoan,\n isInputListFailError,\n MAX_RETRIES,\n resolvePositionIds,\n resolveTokenIndex,\n} from './loanUtils'\nimport { submitWrite } from './utils'\nimport { deposit, withdraw } from './vault'\n\n// ---------------------------------------------------------------------------\n// Parameter types\n// ---------------------------------------------------------------------------\n\n/** Parameters for supplying collateral into a pool. */\nexport interface SupplyParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Chain ID */\n chainId: bigint\n /** Token address to supply (must be token0 or token1 of the pool) */\n token: Address\n /** Amount of token to supply */\n amount: bigint\n /** Whether the token is native ETH (requires sending msg.value) */\n isNativeETH?: boolean\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/** Parameters for withdrawing (unsupplying) collateral from a pool. */\nexport interface UnsupplyParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Chain ID */\n chainId: bigint\n /** Token address to withdraw (must be token0 or token1 of the pool) */\n token: Address\n /** Amount of token to withdraw */\n amount: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/** Parameters for borrowing tokens via a loan position. */\nexport interface BorrowParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Chain ID */\n chainId: bigint\n /** Token address to borrow (must be token0 or token1 of the pool) */\n token: Address\n /** Amount of token to borrow */\n amount: bigint\n /** Slippage tolerance in bps (e.g. 500n = 5%) */\n slippageBps: bigint\n /** Existing position IDs. If omitted, resolved from storage. */\n existingPositionIds?: bigint[]\n /** Storage adapter for position ID resolution and tracking */\n storage?: StorageAdapter\n /** Builder code for fee routing (0 = no builder). */\n builderCode?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/** Parameters for repaying a loan (full or partial). */\nexport interface RepayParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Chain ID */\n chainId: bigint\n /** TokenId of the loan position to repay */\n loanTokenId: bigint\n /** Amount to repay. If >= current position size, does full repay. */\n amount: bigint\n /** Slippage tolerance in bps (e.g. 500n = 5%) */\n slippageBps: bigint\n /** Current position IDs. If omitted, resolved from storage. */\n existingPositionIds?: bigint[]\n /** Storage adapter for position ID resolution and tracking */\n storage?: StorageAdapter\n /** Builder code for fee routing (0 = no builder). */\n builderCode?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve collateral tracker address for a given token in the pool.\n */\nasync function resolveCollateralTracker(\n client: PublicClient,\n poolAddress: Address,\n chainId: bigint,\n token: Address,\n): Promise<Address> {\n const pool = await getPool({ client, poolAddress, chainId })\n const tokenIndex = resolveTokenIndex(\n token,\n pool.collateralTracker0.token,\n pool.collateralTracker1.token,\n )\n return tokenIndex === 0n ? pool.collateralTracker0.address : pool.collateralTracker1.address\n}\n\n/**\n * Save a position ID list to storage.\n */\nasync function savePositionIds(\n storage: StorageAdapter,\n chainId: bigint,\n poolAddress: Address,\n account: Address,\n positionIds: bigint[],\n): Promise<void> {\n const key = getPositionsKey(chainId, poolAddress, account)\n await storage.set(key, jsonSerializer.stringify(positionIds))\n}\n\n// ---------------------------------------------------------------------------\n// supply / unsupply\n// ---------------------------------------------------------------------------\n\n/**\n * Supply collateral into a pool.\n *\n * Resolves the correct collateral tracker from the token address,\n * then delegates to the low-level `deposit()`.\n *\n * @param params - Supply parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * const result = await supply({\n * client, walletClient, account, poolAddress,\n * chainId: 11155111n,\n * token: WETH_ADDRESS,\n * amount: 1n * 10n**18n,\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function supply(params: SupplyParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n chainId,\n token,\n amount,\n isNativeETH,\n txOverrides,\n } = params\n const collateralTrackerAddress = await resolveCollateralTracker(\n client,\n poolAddress,\n chainId,\n token,\n )\n return deposit({\n client,\n walletClient,\n account,\n collateralTrackerAddress,\n assets: amount,\n isNativeETH,\n txOverrides,\n })\n}\n\n/**\n * Supply collateral and wait for confirmation.\n */\nexport async function supplyAndWait(params: SupplyParams): Promise<TxReceipt> {\n const result = await supply(params)\n return result.wait()\n}\n\n/**\n * Withdraw (unsupply) collateral from a pool.\n *\n * Resolves the correct collateral tracker from the token address,\n * then delegates to the low-level `withdraw()`.\n *\n * @param params - Unsupply parameters\n * @returns TxResult\n */\nexport async function unsupply(params: UnsupplyParams): Promise<TxResult> {\n const { client, walletClient, account, poolAddress, chainId, token, amount, txOverrides } = params\n const collateralTrackerAddress = await resolveCollateralTracker(\n client,\n poolAddress,\n chainId,\n token,\n )\n return withdraw({\n client,\n walletClient,\n account,\n collateralTrackerAddress,\n assets: amount,\n txOverrides,\n })\n}\n\n/**\n * Withdraw collateral and wait for confirmation.\n */\nexport async function unsupplyAndWait(params: UnsupplyParams): Promise<TxReceipt> {\n const result = await unsupply(params)\n return result.wait()\n}\n\n// ---------------------------------------------------------------------------\n// borrow\n// ---------------------------------------------------------------------------\n\n/**\n * Borrow tokens from a pool via a loan position.\n *\n * Creates a loan tokenId and mints it via dispatch. The loan borrows the\n * specified token without swapping (ascending tick limits = no swap).\n *\n * @param params - Borrow parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * const result = await borrow({\n * client, walletClient, account, poolAddress,\n * chainId: 11155111n,\n * token: USDC_ADDRESS,\n * amount: 100n * 10n**6n,\n * slippageBps: 500n,\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function borrow(params: BorrowParams): Promise<TxResult & { loanTokenId: bigint }> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n chainId,\n token,\n amount,\n slippageBps,\n existingPositionIds: explicitIds,\n builderCode = 0n,\n storage,\n txOverrides,\n } = params\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n const [pool, positionIds] = await Promise.all([\n getPool({ client, poolAddress, chainId }),\n resolvePositionIds(explicitIds, storage, chainId, poolAddress, account),\n ])\n\n const token0 = pool.collateralTracker0.token\n const token1 = pool.collateralTracker1.token\n const tokenIndex = resolveTokenIndex(token, token0, token1)\n\n // For a loan: both asset and tokenType = the borrowed token index\n const { tokenId: loanTokenId, adjustedSize } = buildUniqueLoan(\n pool.poolId,\n tokenIndex,\n tokenIndex,\n pool.currentTick,\n pool.tickSpacing,\n positionIds,\n amount,\n )\n\n const { low: tickLimitLow, high: tickLimitHigh } = tickLimits(pool.currentTick, slippageBps)\n\n // Ascending tick limits = no swap at mint\n const mintTickLimits: readonly [number, number, number] = [\n Number(tickLimitLow),\n Number(tickLimitHigh),\n 0,\n ]\n\n const positionIdList = [loanTokenId]\n const finalPositionIdList = [...positionIds, loanTokenId]\n const positionSizes = [adjustedSize]\n\n try {\n const txResult = await submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n positionIdList,\n finalPositionIdList,\n positionSizes,\n [mintTickLimits],\n false,\n builderCode,\n ],\n txOverrides,\n })\n return { ...txResult, loanTokenId }\n } catch (error) {\n if (isInputListFailError(error) && attempt < MAX_RETRIES - 1) {\n continue\n }\n throw error\n }\n }\n\n throw new MaxRetriesExceededError('borrow')\n}\n\n/**\n * Borrow tokens and wait for confirmation.\n * If storage is provided, auto-tracks the new loan position.\n */\nexport async function borrowAndWait(params: BorrowParams): Promise<TxReceipt> {\n const result = await borrow(params)\n const receipt = await result.wait()\n\n // Auto-update storage if provided\n if (params.storage && params.chainId !== undefined) {\n const { poolAddress, chainId, storage, account, existingPositionIds: explicitIds } = params\n\n const positionIds =\n explicitIds ?? (await getTrackedPositionIds({ chainId, poolAddress, account, storage }))\n\n await savePositionIds(storage, chainId, poolAddress, account, [\n ...positionIds,\n result.loanTokenId,\n ])\n }\n\n return receipt\n}\n\n// ---------------------------------------------------------------------------\n// preview borrow\n// ---------------------------------------------------------------------------\n\n/** Parameters for previewing a borrow (read-only, no wallet required). */\nexport interface PreviewBorrowParams {\n /** Public client */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** Chain ID */\n chainId: bigint\n /** Token address to borrow (must be token0 or token1 of the pool) */\n token: Address\n /** Amount of token to borrow */\n amount: bigint\n /** Slippage tolerance in bps (e.g. 500n = 5%) */\n slippageBps: bigint\n /** Existing position IDs */\n existingPositionIds: bigint[]\n}\n\n/** Result of a borrow preview. */\nexport interface PreviewBorrowResult {\n /** The loan tokenId that would be minted */\n loanTokenId: bigint\n /** Adjusted position size (after optionRatio scaling) */\n adjustedSize: bigint\n /** Simulation result from dry-run dispatch */\n simulation: SimulationResult<OpenPositionSimulation>\n /** Collateral requirement for the new loan position only (token0). Null if simulation failed. */\n collateralReqToken0: bigint | null\n /** Collateral requirement for the new loan position only (token1). Null if simulation failed. */\n collateralReqToken1: bigint | null\n}\n\n/**\n * Preview a borrow without executing it.\n *\n * Builds the loan tokenId (same logic as `borrow`) and runs a\n * dry-run `simulateOpenPosition` to check feasibility and return\n * post-mint collateral requirements.\n *\n * @param params - Preview parameters\n * @returns Preview result with tokenId, size, and simulation data\n */\nexport async function previewBorrow(params: PreviewBorrowParams): Promise<PreviewBorrowResult> {\n const { client, poolAddress, chainId, token, amount, slippageBps, account, existingPositionIds } =\n params\n\n const pool = await getPool({ client, poolAddress, chainId })\n\n const token0 = pool.collateralTracker0.token\n const token1 = pool.collateralTracker1.token\n const tokenIndex = resolveTokenIndex(token, token0, token1)\n\n const { tokenId: loanTokenId, adjustedSize } = buildUniqueLoan(\n pool.poolId,\n tokenIndex,\n tokenIndex,\n pool.currentTick,\n pool.tickSpacing,\n existingPositionIds,\n amount,\n )\n\n const { low: tickLimitLow, high: tickLimitHigh } = tickLimits(pool.currentTick, slippageBps)\n\n const simulation = await simulateOpenPosition({\n client,\n poolAddress,\n account,\n existingPositionIds,\n tokenId: loanTokenId,\n positionSize: adjustedSize,\n tickLimitLow: BigInt(tickLimitLow),\n tickLimitHigh: BigInt(tickLimitHigh),\n chainId,\n })\n\n // Extract the new loan's collateral requirement (last entry in perPositionCollateralReqs)\n let collateralReqToken0: bigint | null = null\n let collateralReqToken1: bigint | null = null\n if (simulation.success) {\n const reqs = simulation.data.perPositionCollateralReqs\n if (reqs.length > 0) {\n const loanReq = reqs[reqs.length - 1]\n collateralReqToken0 = loanReq.token0\n collateralReqToken1 = loanReq.token1\n }\n }\n\n return { loanTokenId, adjustedSize, simulation, collateralReqToken0, collateralReqToken1 }\n}\n\n// ---------------------------------------------------------------------------\n// repay\n// ---------------------------------------------------------------------------\n\n/**\n * Repay a loan position (full or partial).\n *\n * - Full repay (`amount >= currentSize`): Burns the loan position entirely.\n * - Partial repay (`amount < currentSize`): Uses roll-same-tokenId pattern\n * to reduce the position size.\n *\n * @param params - Repay parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * // Full repay\n * await repay({\n * client, walletClient, account, poolAddress,\n * chainId: 11155111n,\n * loanTokenId,\n * amount: MAX_UINT128, // repay all\n * slippageBps: 500n,\n * })\n *\n * // Partial repay\n * await repay({\n * client, walletClient, account, poolAddress,\n * chainId: 11155111n,\n * loanTokenId,\n * amount: 50n * 10n**6n, // repay 50 USDC\n * slippageBps: 500n,\n * })\n * ```\n */\nexport async function repay(params: RepayParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n chainId,\n loanTokenId,\n amount,\n slippageBps,\n existingPositionIds: explicitIds,\n builderCode = 0n,\n storage,\n txOverrides,\n } = params\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n const [positionIds, fullDataResult] = await Promise.all([\n resolvePositionIds(explicitIds, storage, chainId, poolAddress, account),\n client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [account, false, [loanTokenId]],\n }),\n ])\n\n // Extract positionSize from the packed PositionBalance\n const balanceRaw = fullDataResult[2][0] // positionBalances[0]\n const currentSize = balanceRaw & ((1n << 128n) - 1n)\n\n const pool = await getPool({ client, poolAddress, chainId })\n const { low: tickLimitLow, high: tickLimitHigh } = tickLimits(pool.currentTick, slippageBps)\n\n // Ascending tick limits = no swap\n const ascendingLimits: readonly [number, number, number] = [\n Number(tickLimitLow),\n Number(tickLimitHigh),\n 0,\n ]\n\n if (amount >= currentSize) {\n // Full repay: burn the entire position\n const finalPositionIdList = positionIds.filter((id) => id !== loanTokenId)\n\n try {\n return await submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n [loanTokenId],\n finalPositionIdList,\n [0n], // 0n = burn all\n [ascendingLimits],\n false,\n builderCode,\n ],\n txOverrides,\n })\n } catch (error) {\n if (isInputListFailError(error) && attempt < MAX_RETRIES - 1) {\n continue\n }\n throw error\n }\n } else {\n // Partial repay: roll-same-tokenId pattern\n // Op 1: burn current position at full size\n // Op 2: re-mint same tokenId at reduced size\n const newSize = currentSize - amount\n const finalPositionIdList = positionIds\n .filter((id) => id !== loanTokenId)\n .concat([loanTokenId])\n\n try {\n return await submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n [loanTokenId, loanTokenId],\n finalPositionIdList,\n [currentSize, newSize],\n [ascendingLimits, ascendingLimits],\n false,\n builderCode,\n ],\n txOverrides,\n })\n } catch (error) {\n if (isInputListFailError(error) && attempt < MAX_RETRIES - 1) {\n continue\n }\n throw error\n }\n }\n }\n\n throw new MaxRetriesExceededError('repay')\n}\n\n/**\n * Repay a loan and wait for confirmation.\n * If storage is provided, auto-updates the tracked positions (removes on full repay).\n */\nexport async function repayAndWait(params: RepayParams): Promise<TxReceipt> {\n const result = await repay(params)\n const receipt = await result.wait()\n\n // Auto-update storage on full repay\n if (params.storage && params.chainId !== undefined) {\n const {\n client,\n account,\n poolAddress,\n chainId,\n loanTokenId,\n storage,\n existingPositionIds: explicitIds,\n } = params\n\n const fullDataResult = await client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [account, false, [loanTokenId]],\n })\n const balanceRaw = fullDataResult[2][0] // positionBalances[0]\n const currentSize = balanceRaw & ((1n << 128n) - 1n)\n\n // Only remove if the position was fully burned\n if (currentSize === 0n) {\n const positionIds =\n explicitIds ?? (await getTrackedPositionIds({ chainId, poolAddress, account, storage }))\n await savePositionIds(\n storage,\n chainId,\n poolAddress,\n account,\n positionIds.filter((id) => id !== loanTokenId),\n )\n }\n }\n\n return receipt\n}\n\n// ---------------------------------------------------------------------------\n// smart repay\n// ---------------------------------------------------------------------------\n\n/** Parameters for smart repay (burns all loans for a token, optionally re-opens a smaller one). */\nexport interface SmartRepayParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Chain ID */\n chainId: bigint\n /** Token address to repay loans for (must be token0 or token1 of the pool) */\n token: Address\n /** Amount of token to repay */\n amount: bigint\n /** Slippage tolerance in bps (e.g. 500n = 5%) */\n slippageBps: bigint\n /** Existing position IDs (all positions, not just loans) */\n existingPositionIds: bigint[]\n /** Builder code for fee routing (0 = no builder). */\n builderCode?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n /** Optional storage adapter — when provided, smartRepayAndWait auto-updates tracked positions. */\n storage?: StorageAdapter\n}\n\n/**\n * Identify loan tokenIds for a specific token and return their sizes.\n */\nasync function getLoanPositionsForToken(\n client: PublicClient,\n poolAddress: Address,\n account: Address,\n existingPositionIds: bigint[],\n tokenIndex: bigint,\n): Promise<{ tokenId: bigint; positionSize: bigint; optionRatio: bigint; tokenAmount: bigint }[]> {\n const loanIds = existingPositionIds.filter((id) => {\n if (!isLoan(id)) return false\n const legs = decodeAllLegs(id)\n return legs.length > 0 && legs[0].tokenType === tokenIndex\n })\n\n if (loanIds.length === 0) return []\n\n const fullData = await client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [account, false, loanIds],\n })\n\n const balances = fullData[2]\n return loanIds.map((tokenId, i) => {\n const positionSize = balances[i] & ((1n << 128n) - 1n)\n const legs = decodeAllLegs(tokenId)\n const optionRatio = legs[0].optionRatio\n // Actual token amount = positionSize * optionRatio\n const tokenAmount = positionSize * optionRatio\n return { tokenId, positionSize, optionRatio, tokenAmount }\n })\n}\n\n/**\n * Smart repay: burns all loan positions for a token and optionally re-opens a smaller one.\n *\n * Unlike `repay()` which targets a single loanTokenId, this function handles\n * multiple loans transparently. The user specifies a repay amount and the SDK:\n * 1. Finds all loan positions for the specified token\n * 2. Burns them all\n * 3. If repayAmount < totalDebt, opens a new loan for the remainder\n *\n * @param params - Smart repay parameters\n * @returns TxResult\n */\nexport async function smartRepay(params: SmartRepayParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n chainId,\n token,\n amount,\n slippageBps,\n existingPositionIds,\n builderCode = 0n,\n txOverrides,\n } = params\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n const pool = await getPool({ client, poolAddress, chainId })\n const tokenIndex = resolveTokenIndex(\n token,\n pool.collateralTracker0.token,\n pool.collateralTracker1.token,\n )\n\n const loans = await getLoanPositionsForToken(\n client,\n poolAddress,\n account,\n existingPositionIds,\n tokenIndex,\n )\n if (loans.length === 0) {\n throw new NoLoanPositionsError(token)\n }\n\n const totalDebt = loans.reduce((sum, l) => sum + l.tokenAmount, 0n)\n const loanIds = loans.map((l) => l.tokenId)\n const remainder = totalDebt > amount ? totalDebt - amount : 0n\n\n const { low: tickLimitLow, high: tickLimitHigh } = tickLimits(pool.currentTick, slippageBps)\n const ascendingLimits: readonly [number, number, number] = [\n Number(tickLimitLow),\n Number(tickLimitHigh),\n 0,\n ]\n\n const nonLoanIds = existingPositionIds.filter((id) => !loanIds.includes(id))\n\n const opsPositionIds: bigint[] = [...loanIds]\n const opsSizes: bigint[] = loanIds.map(() => 0n)\n const opsLimits = loanIds.map(() => ascendingLimits)\n\n let finalPositionIdList: bigint[]\n\n if (remainder > 0n) {\n const { tokenId: newLoanId, adjustedSize } = buildUniqueLoan(\n pool.poolId,\n tokenIndex,\n tokenIndex,\n pool.currentTick,\n pool.tickSpacing,\n nonLoanIds,\n remainder,\n )\n opsPositionIds.push(newLoanId)\n opsSizes.push(adjustedSize)\n opsLimits.push(ascendingLimits)\n finalPositionIdList = [...nonLoanIds, newLoanId]\n } else {\n finalPositionIdList = nonLoanIds\n }\n\n try {\n return await submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [opsPositionIds, finalPositionIdList, opsSizes, opsLimits, false, builderCode],\n txOverrides,\n })\n } catch (error) {\n if (isInputListFailError(error) && attempt < MAX_RETRIES - 1) {\n continue\n }\n throw error\n }\n }\n\n throw new MaxRetriesExceededError('smartRepay')\n}\n\n/**\n * Smart repay and wait for confirmation.\n */\nexport async function smartRepayAndWait(params: SmartRepayParams): Promise<TxReceipt> {\n const result = await smartRepay(params)\n const receipt = await result.wait()\n\n // Auto-update storage: remove fully-repaid loans, insert remainder loan if any\n if (params.storage && params.chainId !== undefined) {\n const { client, account, poolAddress, chainId, token, amount, storage, existingPositionIds } =\n params\n\n const pool = await getPool({ client, poolAddress, chainId })\n const tokenIndex = resolveTokenIndex(\n token,\n pool.collateralTracker0.token,\n pool.collateralTracker1.token,\n )\n\n const loans = await getLoanPositionsForToken(\n client,\n poolAddress,\n account,\n existingPositionIds,\n tokenIndex,\n )\n const loanIds = loans.map((l) => l.tokenId)\n const totalDebt = loans.reduce((sum, l) => sum + l.tokenAmount, 0n)\n const remainder = totalDebt > amount ? totalDebt - amount : 0n\n\n const positionIds =\n existingPositionIds ??\n (await getTrackedPositionIds({ chainId, poolAddress, account, storage }))\n\n // Remove all old loan IDs\n let updatedIds = positionIds.filter((id) => !loanIds.includes(id))\n\n // If there's a remainder, the contract minted a new loan — find it\n if (remainder > 0n) {\n const nonLoanIds = existingPositionIds.filter((id) => !loanIds.includes(id))\n const newLoan = buildUniqueLoan(\n pool.poolId,\n tokenIndex,\n tokenIndex,\n pool.currentTick,\n pool.tickSpacing,\n nonLoanIds,\n remainder,\n )\n updatedIds = [...updatedIds, newLoan.tokenId]\n }\n\n await savePositionIds(storage, chainId, poolAddress, account, updatedIds)\n }\n\n return receipt\n}\n","/**\n * Item-based wrapper around simulateDispatch for batched mint/burn ops.\n * @module v2/simulations/simulateBatchDispatch\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { buildBatchDispatchArgs } from '../batch/build'\nimport type { BatchDiagnostic, BatchOp } from '../batch/types'\nimport { getBlockMeta } from '../clients'\nimport type { BlockMeta, DispatchSimulation, SimulationResult } from '../types'\nimport { simulateDispatch } from './simulateDispatch'\n\n/**\n * Parameters for `simulateBatchDispatch`.\n *\n * - `client`: viem PublicClient used for read calls.\n * - `poolAddress`: PanopticPool address the batch targets.\n * - `account`: account whose collateral and positions are simulated against.\n * - `items`: ordered batch ops (mints + burns) — order matters because dispatch\n * applies them sequentially.\n * - `existingPositionIds`: account's current on-chain `positionIdList`. Must\n * reflect FRESH on-chain state (not a cached/optimistic snapshot) — stale\n * data here yields incorrect pre-dispatch margin excess and false\n * burn-not-found diagnostics.\n * - `usePremiaAsCollateral`: applied across the whole dispatch. Defaults to\n * `false`.\n * - `builderCode`: applied across the whole dispatch. Defaults to `0n`.\n * - `blockNumber`: optional pinned block; defaults to the client's latest.\n */\nexport interface SimulateBatchDispatchParams {\n client: PublicClient\n poolAddress: Address\n account: Address\n /** Batch ops in operation order. */\n items: BatchOp[]\n /** Current on-chain positionIdList for the account (fresh). */\n existingPositionIds: bigint[]\n /** Apply across the whole dispatch. Defaults to false. */\n usePremiaAsCollateral?: boolean\n /** Apply across the whole dispatch. Defaults to 0n. */\n builderCode?: bigint\n /** Optional pinned block. */\n blockNumber?: bigint\n}\n\n/**\n * Result returned by `simulateBatchDispatch`.\n *\n * Either delegates to `simulateDispatch` (and therefore matches its\n * `SimulationResult<DispatchSimulation>` shape), or short-circuits with\n * batch-level diagnostics when the items fail validation. In either case the\n * shape includes a `diagnostics` field so callers can render conflicts before\n * deciding what to do — UIs typically gray out the Execute button when\n * `diagnostics.length > 0`.\n */\nexport type SimulateBatchDispatchResult =\n | (SimulationResult<DispatchSimulation> & { diagnostics: BatchDiagnostic[] })\n | { success: false; diagnostics: BatchDiagnostic[]; _meta: BlockMeta }\n\n/**\n * Simulate a batch dispatch built from `items` + the current on-chain\n * positionIdList. Returns batch diagnostics OR a real simulation result.\n */\nexport async function simulateBatchDispatch(\n params: SimulateBatchDispatchParams,\n): Promise<SimulateBatchDispatchResult> {\n const {\n client,\n poolAddress,\n account,\n items,\n existingPositionIds,\n usePremiaAsCollateral = false,\n builderCode = 0n,\n blockNumber,\n } = params\n\n const { args, diagnostics } = buildBatchDispatchArgs({\n items,\n existingPositionIds,\n usePremiaAsCollateral,\n builderCode,\n })\n\n if (args === null) {\n const targetBlockNumber = blockNumber ?? (await client.getBlockNumber())\n const meta = await getBlockMeta({ client, blockNumber: targetBlockNumber })\n return { success: false, diagnostics, _meta: meta }\n }\n\n const sim = await simulateDispatch({\n client,\n poolAddress,\n account,\n positionIdList: args.positionIdList,\n finalPositionIdList: args.finalPositionIdList,\n existingPositionIdList: existingPositionIds,\n positionSizes: args.positionSizes,\n tickAndSpreadLimits: args.tickAndSpreadLimits,\n usePremiaAsCollateral: args.usePremiaAsCollateral,\n builderCode: args.builderCode,\n blockNumber,\n })\n\n return { ...sim, diagnostics: [] }\n}\n","/**\n * Close position simulation for the Panoptic v2 SDK.\n * @module v2/simulations/simulateClosePosition\n */\n\nimport type { Address, PublicClient } from 'viem'\nimport { encodeFunctionData } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { getBlockMeta } from '../clients'\nimport { PanopticError } from '../errors'\nimport type { ClosePositionSimulation, SimulationResult } from '../types'\nimport { simulateWithTokenFlow } from './tokenFlow'\n\n/**\n * Parameters for simulating position closing.\n */\nexport interface SimulateClosePositionParams {\n /** Public client */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** Current position ID list */\n positionIdList: bigint[]\n /** TokenId of position to close */\n tokenId: bigint\n /** Position size to close */\n positionSize: bigint\n /**\n * Lower tick limit (always <= tickLimitHigh).\n * Use MIN_TICK (-887272n) to allow any downward price movement.\n */\n tickLimitLow: bigint\n /**\n * Upper tick limit (always >= tickLimitLow).\n * Use MAX_TICK (887272n) to allow any upward price movement.\n */\n tickLimitHigh: bigint\n /** Spread limit tick (use 0n for no spread limit) */\n spreadLimit?: bigint\n /**\n * Whether to swap tokens at burn to achieve single-sided exposure.\n * When true, tickLimits are passed to dispatch in descending order (high, low).\n * When false (default), tickLimits are passed in ascending order (low, high).\n */\n swapAtMint?: boolean\n /** Whether to use premia as collateral */\n usePremiaAsCollateral?: boolean\n /** Builder code */\n builderCode?: bigint\n /** Optional block number for simulation */\n blockNumber?: bigint\n}\n\n/**\n * Simulate closing a position.\n *\n * Uses PanopticPool.multicall with getAssetsOf-dispatch-getAssetsOf pattern\n * to measure exact collateral asset movements from the burn.\n *\n * @param params - Simulation parameters\n * @returns Simulation result with close data or error\n */\nexport async function simulateClosePosition(\n params: SimulateClosePositionParams,\n): Promise<SimulationResult<ClosePositionSimulation>> {\n const {\n client,\n poolAddress,\n account,\n positionIdList,\n tokenId,\n tickLimitLow,\n tickLimitHigh,\n spreadLimit = 0n,\n swapAtMint = false,\n usePremiaAsCollateral = false,\n builderCode = 0n,\n blockNumber,\n } = params\n\n const targetBlockNumber = blockNumber ?? (await client.getBlockNumber())\n const metaPromise = getBlockMeta({ client, blockNumber: targetBlockNumber })\n\n // Build tick limits based on swapAtMint flag:\n // - swapAtMint=true: descending order (high, low) triggers SFPM swap\n // - swapAtMint=false: ascending order (low, high) no swap\n const tickLimits: readonly [number, number, number] = swapAtMint\n ? [Number(tickLimitHigh), Number(tickLimitLow), Number(spreadLimit)]\n : [Number(tickLimitLow), Number(tickLimitHigh), Number(spreadLimit)]\n\n try {\n // Prepare final position list (without the closed position)\n const finalPositionIdList = positionIdList.filter((id) => id !== tokenId)\n\n // Encode dispatch call data for burn (positionSize = 0 signals close)\n const callData = encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n [tokenId],\n finalPositionIdList,\n [0n],\n [tickLimits],\n usePremiaAsCollateral,\n builderCode,\n ],\n })\n\n // Simulate with token flow measurement using PanopticPool.multicall + getAssetsOf\n const flowResult = await simulateWithTokenFlow({\n client,\n poolAddress,\n user: account,\n callData,\n blockNumber: targetBlockNumber,\n })\n\n if (!flowResult.success || !flowResult.tokenFlow) {\n throw (\n flowResult.rawError ?? new PanopticError(flowResult.error || 'Token flow simulation failed')\n )\n }\n\n const tokenFlow = flowResult.tokenFlow\n const _meta = await metaPromise\n\n // Map token flow to simulation fields:\n // Positive delta = user receives collateral back\n const data: ClosePositionSimulation = {\n amount0Received: tokenFlow.delta0,\n amount1Received: tokenFlow.delta1,\n premiaCollected0: null, // Requires pre-close premia snapshot\n premiaCollected1: null,\n postCollateral0: tokenFlow.balanceAfter0,\n postCollateral1: tokenFlow.balanceAfter1,\n realizedPnL0: null, // Requires open position cost basis\n realizedPnL1: null,\n }\n\n return {\n success: true,\n data,\n gasEstimate: flowResult.gasEstimate,\n tokenFlow,\n _meta,\n }\n } catch (error) {\n const _meta = await metaPromise\n return {\n success: false,\n error:\n error instanceof PanopticError\n ? error\n : new PanopticError(\n error instanceof Error ? error.message : 'Simulation failed',\n error instanceof Error ? error : undefined,\n ),\n _meta,\n }\n }\n}\n","/**\n * Force exercise simulation for the Panoptic v2 SDK.\n * @module v2/simulations/simulateForceExercise\n */\n\nimport type { Address, PublicClient } from 'viem'\nimport { encodeFunctionData } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { getBlockMeta } from '../clients'\nimport { PanopticError } from '../errors'\nimport type { ForceExerciseSimulation, SimulationResult, TokenFlow } from '../types'\nimport { simulateWithTokenFlow } from './tokenFlow'\n\n/**\n * Parameters for simulating force exercise.\n */\nexport interface SimulateForceExerciseParams {\n /** Public client */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Exercisor account address */\n account: Address\n /** Account whose position is being exercised */\n user: Address\n /** Position IDs from the exercisor's account */\n positionIdListFrom: bigint[]\n /** Position IDs of the target user */\n positionIdListTo: bigint[]\n /** Final position ID list for the user after exercise */\n positionIdListToFinal: bigint[]\n /** Optional block number for simulation */\n blockNumber?: bigint\n}\n\n/**\n * Simulate a force exercise operation.\n *\n * @param params - Simulation parameters\n * @returns Simulation result with exercise data or error\n */\nexport async function simulateForceExercise(\n params: SimulateForceExerciseParams,\n): Promise<SimulationResult<ForceExerciseSimulation>> {\n const {\n client,\n poolAddress,\n account,\n user,\n positionIdListFrom,\n positionIdListTo,\n positionIdListToFinal,\n blockNumber,\n } = params\n\n const targetBlockNumber = blockNumber ?? (await client.getBlockNumber())\n const metaPromise = getBlockMeta({ client, blockNumber: targetBlockNumber })\n\n // Default token flow for failure cases\n const emptyTokenFlow: TokenFlow = {\n delta0: 0n,\n delta1: 0n,\n balanceBefore0: 0n,\n balanceBefore1: 0n,\n balanceAfter0: 0n,\n balanceAfter1: 0n,\n tickBefore: null,\n tickAfter: null,\n }\n\n try {\n // Encode dispatchFrom call data\n const callData = encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'dispatchFrom',\n args: [positionIdListFrom, user, positionIdListTo, positionIdListToFinal, 0n],\n })\n\n // Simulate with token flow measurement using PanopticPool.multicall + getAssetsOf\n const flowResult = await simulateWithTokenFlow({\n client,\n poolAddress,\n user: account, // Measure exercisor's collateral change\n callData,\n blockNumber: targetBlockNumber,\n })\n\n if (!flowResult.success || !flowResult.tokenFlow) {\n // Check for specific exercise-related errors\n const errorMessage = flowResult.error || 'Simulation failed'\n const isNotExercisable =\n errorMessage.includes('NoLegsExercisable') || errorMessage.includes('NotALongLeg')\n\n if (isNotExercisable) {\n const _meta = await metaPromise\n const data: ForceExerciseSimulation = {\n exerciseFee0: 0n,\n exerciseFee1: 0n,\n canExercise: false,\n reason: errorMessage.includes('NoLegsExercisable')\n ? 'No legs are exercisable (not ITM)'\n : 'Position does not have a long leg',\n }\n\n return {\n success: true,\n data,\n gasEstimate: 0n,\n tokenFlow: emptyTokenFlow,\n _meta,\n }\n }\n\n throw new PanopticError(errorMessage)\n }\n\n const _meta = await metaPromise\n const tokenFlow: TokenFlow = flowResult.tokenFlow\n\n // Build simulation result with actual token flow data\n // Exercise fee is what the exercisor receives (positive delta)\n const data: ForceExerciseSimulation = {\n exerciseFee0: tokenFlow.delta0,\n exerciseFee1: tokenFlow.delta1,\n canExercise: true,\n }\n\n return {\n success: true,\n data,\n gasEstimate: flowResult.gasEstimate,\n tokenFlow,\n _meta,\n }\n } catch (error) {\n const _meta = await metaPromise\n // If simulation fails, check the reason\n const errorMessage = error instanceof Error ? error.message : 'Simulation failed'\n\n // Check for specific exercise-related errors\n const isNotExercisable =\n errorMessage.includes('NoLegsExercisable') || errorMessage.includes('NotALongLeg')\n\n if (isNotExercisable) {\n const data: ForceExerciseSimulation = {\n exerciseFee0: 0n,\n exerciseFee1: 0n,\n canExercise: false,\n reason: errorMessage.includes('NoLegsExercisable')\n ? 'No legs are exercisable (not ITM)'\n : 'Position does not have a long leg',\n }\n\n return {\n success: true,\n data,\n gasEstimate: 0n,\n tokenFlow: emptyTokenFlow,\n _meta,\n }\n }\n\n return {\n success: false,\n error:\n error instanceof PanopticError\n ? error\n : new PanopticError(errorMessage, error instanceof Error ? error : undefined),\n _meta,\n }\n }\n}\n","/**\n * Liquidation simulation for the Panoptic v2 SDK.\n * @module v2/simulations/simulateLiquidate\n */\n\nimport type { Address, PublicClient } from 'viem'\nimport { encodeFunctionData } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { getBlockMeta } from '../clients'\nimport { PanopticError } from '../errors'\nimport type { LiquidateSimulation, SimulationResult, TokenFlow } from '../types'\nimport { simulateWithTokenFlow } from './tokenFlow'\n\n/**\n * Parameters for simulating liquidation.\n */\nexport interface SimulateLiquidateParams {\n /** Public client */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Liquidator account address */\n account: Address\n /** Account being liquidated */\n liquidatee: Address\n /** Position IDs from the liquidator's account */\n positionIdListFrom: bigint[]\n /** Position IDs of the liquidatee */\n positionIdListTo: bigint[]\n /** Final position ID list for the liquidatee after liquidation */\n positionIdListToFinal: bigint[]\n /** Optional block number for simulation */\n blockNumber?: bigint\n}\n\n/**\n * Simulate a liquidation operation.\n *\n * @param params - Simulation parameters\n * @returns Simulation result with liquidation data or error\n */\nexport async function simulateLiquidate(\n params: SimulateLiquidateParams,\n): Promise<SimulationResult<LiquidateSimulation>> {\n const {\n client,\n poolAddress,\n account,\n liquidatee,\n positionIdListFrom,\n positionIdListTo,\n positionIdListToFinal,\n blockNumber,\n } = params\n\n const targetBlockNumber = blockNumber ?? (await client.getBlockNumber())\n const metaPromise = getBlockMeta({ client, blockNumber: targetBlockNumber })\n\n // Default token flow for failure cases\n const emptyTokenFlow: TokenFlow = {\n delta0: 0n,\n delta1: 0n,\n balanceBefore0: 0n,\n balanceBefore1: 0n,\n balanceAfter0: 0n,\n balanceAfter1: 0n,\n tickBefore: null,\n tickAfter: null,\n }\n\n try {\n // Encode dispatchFrom call data\n const callData = encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'dispatchFrom',\n args: [positionIdListFrom, liquidatee, positionIdListTo, positionIdListToFinal, 0n],\n })\n\n // Simulate with token flow measurement using PanopticPool.multicall + getAssetsOf\n const flowResult = await simulateWithTokenFlow({\n client,\n poolAddress,\n user: account, // Measure liquidator's collateral change\n callData,\n blockNumber: targetBlockNumber,\n })\n\n if (!flowResult.success || !flowResult.tokenFlow) {\n // Check if it's a specific error indicating not liquidatable\n const errorMessage = flowResult.error || 'Simulation failed'\n const isNotLiquidatable =\n errorMessage.includes('NotMarginCalled') || errorMessage.includes('AccountInsolvent')\n\n if (isNotLiquidatable) {\n const _meta = await metaPromise\n const data: LiquidateSimulation = {\n bonus0: 0n,\n bonus1: 0n,\n positionsClosed: [],\n isLiquidatable: false,\n shortfall0: 0n,\n shortfall1: 0n,\n }\n return {\n success: true,\n data,\n gasEstimate: 0n,\n tokenFlow: emptyTokenFlow,\n _meta,\n }\n }\n\n throw new PanopticError(errorMessage)\n }\n\n const _meta = await metaPromise\n const tokenFlow: TokenFlow = flowResult.tokenFlow\n\n // Positions that would be closed\n const positionsClosed = positionIdListTo.filter((id) => !positionIdListToFinal.includes(id))\n\n // Build simulation result with actual token flow data\n // Positive delta = liquidator receives bonus\n const data: LiquidateSimulation = {\n bonus0: tokenFlow.delta0 > 0n ? tokenFlow.delta0 : 0n,\n bonus1: tokenFlow.delta1 > 0n ? tokenFlow.delta1 : 0n,\n positionsClosed,\n isLiquidatable: true,\n shortfall0: 0n, // Would need additional calculation\n shortfall1: 0n,\n }\n\n return {\n success: true,\n data,\n gasEstimate: flowResult.gasEstimate,\n tokenFlow,\n _meta,\n }\n } catch (error) {\n const _meta = await metaPromise\n // If simulation fails, the account might not be liquidatable\n const errorMessage = error instanceof Error ? error.message : 'Simulation failed'\n const isNotLiquidatable =\n errorMessage.includes('NotMarginCalled') || errorMessage.includes('AccountInsolvent')\n\n if (isNotLiquidatable) {\n const data: LiquidateSimulation = {\n bonus0: 0n,\n bonus1: 0n,\n positionsClosed: [],\n isLiquidatable: false,\n shortfall0: 0n,\n shortfall1: 0n,\n }\n return {\n success: true,\n data,\n gasEstimate: 0n,\n tokenFlow: emptyTokenFlow,\n _meta,\n }\n }\n\n return {\n success: false,\n error:\n error instanceof PanopticError\n ? error\n : new PanopticError(errorMessage, error instanceof Error ? error : undefined),\n _meta,\n }\n }\n}\n","/**\n * Settle simulation for the Panoptic v2 SDK.\n * @module v2/simulations/simulateSettle\n */\n\nimport type { Address, Hex, PublicClient } from 'viem'\nimport { decodeFunctionResult, encodeFunctionData } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { getBlockMeta } from '../clients'\nimport { PanopticError } from '../errors'\nimport type { SettleSimulation, SimulationResult, TokenFlow } from '../types'\nimport { simulateWithTokenFlow } from './tokenFlow'\n\n/** BIT_MASK_128 = (1n << 128n) - 1n */\nconst BIT_MASK_128 = (1n << 128n) - 1n\n\n/**\n * PanopticPool multicall ABI (inherited from Uniswap).\n */\nconst multicallAbi = [\n {\n type: 'function',\n name: 'multicall',\n inputs: [{ name: 'data', type: 'bytes[]' }],\n outputs: [{ name: 'results', type: 'bytes[]' }],\n stateMutability: 'nonpayable',\n },\n] as const\n\n/**\n * Parameters for simulating premium settlement.\n */\nexport interface SimulateSettleParams {\n /** Public client */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** Current position ID list */\n positionIdList: bigint[]\n /** Optional tokenId to compute forfeit amounts for */\n tokenId?: bigint\n /** Optional block number for simulation */\n blockNumber?: bigint\n}\n\n/**\n * Simulate premium settlement.\n *\n * When `tokenId` is provided, the simulation also computes forfeit amounts\n * by chaining the dispatch with `getFullPositionsData` reads\n * in a single multicall.\n *\n * @param params - Simulation parameters\n * @returns Simulation result with settlement data or error\n */\nexport async function simulateSettle(\n params: SimulateSettleParams,\n): Promise<SimulationResult<SettleSimulation>> {\n const { client, poolAddress, account, positionIdList, tokenId, blockNumber } = params\n\n const targetBlockNumber = blockNumber ?? (await client.getBlockNumber())\n const metaPromise = getBlockMeta({ client, blockNumber: targetBlockNumber })\n\n try {\n // For settlement, we call dispatch with unchanged position lists\n const positionSizes = positionIdList.map(() => 0n)\n const tickAndSpreadLimits = positionIdList.map(() => [-887272n, 887272n, 0n] as const)\n\n // Encode dispatch call data\n const callData = encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n positionIdList,\n positionIdList,\n positionSizes.map((s) => BigInt(s) as unknown as bigint & { readonly __uint128: true }),\n tickAndSpreadLimits.map(\n (t) => [Number(t[0]), Number(t[1]), Number(t[2])] as readonly [number, number, number],\n ),\n false,\n 0n,\n ],\n })\n\n // Simulate with token flow measurement using PanopticPool.multicall + getAssetsOf\n const flowResult = await simulateWithTokenFlow({\n client,\n poolAddress,\n user: account,\n callData,\n blockNumber: targetBlockNumber,\n })\n\n if (!flowResult.success || !flowResult.tokenFlow) {\n throw (\n flowResult.rawError ?? new PanopticError(flowResult.error || 'Token flow simulation failed')\n )\n }\n\n const tokenFlow: TokenFlow = flowResult.tokenFlow\n\n // Compute forfeit amounts if tokenId is provided\n let forfeitAmounts: [bigint, bigint] | undefined\n if (tokenId !== undefined) {\n forfeitAmounts = await computeForfeitAmounts({\n client,\n poolAddress,\n account,\n positionIdList,\n tokenId,\n dispatchCallData: callData,\n blockNumber: targetBlockNumber,\n })\n }\n\n const _meta = await metaPromise\n\n // Build simulation result with actual token flow data\n // Positive delta = premia received\n const data: SettleSimulation = {\n premiaReceived0: tokenFlow.delta0 > 0n ? tokenFlow.delta0 : 0n,\n premiaReceived1: tokenFlow.delta1 > 0n ? tokenFlow.delta1 : 0n,\n postCollateral0: tokenFlow.balanceAfter0,\n postCollateral1: tokenFlow.balanceAfter1,\n forfeitAmounts,\n }\n\n return {\n success: true,\n data,\n gasEstimate: flowResult.gasEstimate,\n tokenFlow,\n _meta,\n }\n } catch (error) {\n const _meta = await metaPromise\n return {\n success: false,\n error:\n error instanceof PanopticError\n ? error\n : new PanopticError(\n error instanceof Error ? error.message : 'Simulation failed',\n error instanceof Error ? error : undefined,\n ),\n _meta,\n }\n }\n}\n\n/**\n * Compute forfeit amounts by chaining dispatch + getFullPositionsData\n * in a single PanopticPool.multicall.\n */\nasync function computeForfeitAmounts(params: {\n client: PublicClient\n poolAddress: Address\n account: Address\n positionIdList: bigint[]\n tokenId: bigint\n dispatchCallData: Hex\n blockNumber: bigint\n}): Promise<[bigint, bigint]> {\n const { client, poolAddress, account, tokenId, dispatchCallData, blockNumber } = params\n\n // Encode getFullPositionsData calls (available = false, total = true)\n const feesCallAvailable = encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [account, false, [tokenId]],\n })\n const feesCallTotal = encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [account, true, [tokenId]],\n })\n\n try {\n // Chain: dispatch (settle) + fees(available) + fees(total) in one multicall\n const { result } = await client.simulateContract({\n address: poolAddress,\n abi: multicallAbi,\n functionName: 'multicall',\n args: [[dispatchCallData, feesCallAvailable, feesCallTotal]],\n account,\n blockNumber,\n })\n\n // Decode the two fee reads (result[0] is dispatch, result[1] and result[2] are fees)\n const decodeFeesResult = (data: Hex): bigint => {\n return decodeFunctionResult({\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n data,\n })[0]\n }\n\n const availablePremium = decodeFeesResult(result[1])\n const totalPremium = decodeFeesResult(result[2])\n\n const available0 = availablePremium & BIT_MASK_128\n const available1 = availablePremium >> 128n\n const total0 = totalPremium & BIT_MASK_128\n const total1 = totalPremium >> 128n\n\n return [total0 - available0, total1 - available1]\n } catch (error) {\n throw new PanopticError(\n 'Forfeit amount computation failed',\n error instanceof Error ? error : undefined,\n )\n }\n}\n","/**\n * Vault simulation functions for the Panoptic v2 SDK.\n * @module v2/simulations/simulateVault\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { collateralTrackerV2Abi } from '../../../generated'\nimport { getBlockMeta } from '../clients'\nimport { PanopticError } from '../errors'\nimport type { DepositSimulation, SimulationResult, WithdrawSimulation } from '../types'\n\n/**\n * Parameters for simulating deposit.\n */\nexport interface SimulateDepositParams {\n /** Public client */\n client: PublicClient\n /** CollateralTracker address */\n collateralTrackerAddress: Address\n /** Account address */\n account: Address\n /** Assets to deposit */\n assets: bigint\n /** Whether the collateral tracker wraps native ETH (requires sending msg.value) */\n isNativeETH?: boolean\n /** Optional block number for simulation */\n blockNumber?: bigint\n}\n\n/**\n * Simulate a deposit operation.\n *\n * @param params - Simulation parameters\n * @returns Simulation result with deposit data or error\n */\nexport async function simulateDeposit(\n params: SimulateDepositParams,\n): Promise<SimulationResult<DepositSimulation>> {\n const { client, collateralTrackerAddress, account, assets, isNativeETH, blockNumber } = params\n\n const targetBlockNumber = blockNumber ?? (await client.getBlockNumber())\n const metaPromise = getBlockMeta({ client, blockNumber: targetBlockNumber })\n\n try {\n // Run multicall (historical block), gas estimate (latest), and block meta in parallel\n const [[currentShares, currentAssets, previewedShares], gasEstimate, _meta] = await Promise.all(\n [\n client.multicall({\n contracts: [\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'balanceOf',\n args: [account],\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n args: [account],\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'previewDeposit',\n args: [assets],\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n }),\n client.estimateContractGas({\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'deposit',\n args: [assets, account],\n account,\n ...(isNativeETH && { value: assets }),\n blockNumber: targetBlockNumber,\n }),\n metaPromise,\n ],\n )\n\n const data: DepositSimulation = {\n sharesMinted: previewedShares,\n postAssets: currentAssets + assets,\n postShares: currentShares + previewedShares,\n }\n\n return {\n success: true,\n data,\n gasEstimate,\n _meta,\n }\n } catch (error) {\n const _meta = await metaPromise\n return {\n success: false,\n error:\n error instanceof PanopticError\n ? error\n : new PanopticError(\n error instanceof Error ? error.message : 'Simulation failed',\n error instanceof Error ? error : undefined,\n ),\n _meta,\n }\n }\n}\n\n/**\n * Parameters for simulating withdrawal.\n */\nexport interface SimulateWithdrawParams {\n /** Public client */\n client: PublicClient\n /** CollateralTracker address */\n collateralTrackerAddress: Address\n /** Account address */\n account: Address\n /** Assets to withdraw */\n assets: bigint\n /** Optional block number for simulation */\n blockNumber?: bigint\n}\n\n/**\n * Simulate a withdrawal operation.\n *\n * @param params - Simulation parameters\n * @returns Simulation result with withdrawal data or error\n */\nexport async function simulateWithdraw(\n params: SimulateWithdrawParams,\n): Promise<SimulationResult<WithdrawSimulation>> {\n const { client, collateralTrackerAddress, account, assets, blockNumber } = params\n\n const targetBlockNumber = blockNumber ?? (await client.getBlockNumber())\n const metaPromise = getBlockMeta({ client, blockNumber: targetBlockNumber })\n\n try {\n // Get current state\n const [currentShares, currentAssets, maxWithdrawable, previewedShares] = await client.multicall(\n {\n contracts: [\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'balanceOf',\n args: [account],\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n args: [account],\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'maxWithdraw',\n args: [account],\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'previewWithdraw',\n args: [assets],\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n },\n )\n\n // Check if withdrawal is possible\n const canWithdraw = assets <= maxWithdrawable\n\n const _meta = await metaPromise\n\n if (!canWithdraw) {\n const data: WithdrawSimulation = {\n sharesBurned: 0n,\n assetsReceived: 0n,\n postAssets: currentAssets,\n postShares: currentShares,\n canWithdraw: false,\n reason: `Requested ${assets}, but max withdrawable is ${maxWithdrawable}`,\n }\n\n return {\n success: true,\n data,\n gasEstimate: 0n,\n _meta,\n }\n }\n\n const gasEstimate = await client.estimateContractGas({\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'withdraw',\n args: [assets, account, account],\n account,\n blockNumber: targetBlockNumber,\n })\n\n const data: WithdrawSimulation = {\n sharesBurned: previewedShares,\n assetsReceived: assets,\n postAssets: currentAssets - assets,\n postShares: currentShares - previewedShares,\n canWithdraw: true,\n }\n\n return {\n success: true,\n data,\n gasEstimate,\n _meta,\n }\n } catch (error) {\n const _meta = await metaPromise\n return {\n success: false,\n error:\n error instanceof PanopticError\n ? error\n : new PanopticError(\n error instanceof Error ? error.message : 'Simulation failed',\n error instanceof Error ? error : undefined,\n ),\n _meta,\n }\n }\n}\n","/**\n * SFPM simulation functions for the Panoptic v2 SDK.\n *\n * These simulate `mintTokenizedPosition` and `burnTokenizedPosition` on the\n * SemiFungiblePositionManager, called with `account: poolAddress` (the pool\n * is the caller in the actual protocol flow).\n *\n * @module v2/simulations/sfpm\n */\n\nimport type { Address, Hex, PublicClient } from 'viem'\nimport { encodeAbiParameters } from 'viem'\n\nimport { semiFungiblePositionManagerV4Abi } from '../../../generated'\nimport type { PoolKey } from '../types'\n\n/**\n * Encode a V4 PoolKey struct as bytes for the SFPM.\n */\nexport function encodePoolKeyBytes(poolKey: PoolKey): Hex {\n return encodeAbiParameters(\n [\n {\n type: 'tuple',\n components: [\n { name: 'currency0', type: 'address' },\n { name: 'currency1', type: 'address' },\n { name: 'fee', type: 'uint24' },\n { name: 'tickSpacing', type: 'int24' },\n { name: 'hooks', type: 'address' },\n ],\n },\n ],\n [\n {\n currency0: poolKey.currency0,\n currency1: poolKey.currency1,\n fee: Number(poolKey.fee),\n tickSpacing: Number(poolKey.tickSpacing),\n hooks: poolKey.hooks,\n },\n ],\n )\n}\n\n/**\n * Encode a V3 pool address as poolKey bytes for the V3 SFPM.\n * V3 SFPM expects `abi.encode(uniswapV3PoolAddress)`.\n */\nexport function encodeV3PoolKeyBytes(v3PoolAddress: Address): Hex {\n return encodeAbiParameters([{ type: 'address' }], [v3PoolAddress])\n}\n\n/**\n * Parameters for simulating an SFPM mint or burn.\n */\nexport interface SimulateSFPMParams {\n /** Public client */\n client: PublicClient\n /** SemiFungiblePositionManager address */\n sfpmAddress: Address\n /** PanopticPool address (used as `account` — the pool is the caller) */\n poolAddress: Address\n /** Encoded pool key (bytes) */\n poolKey: Hex\n /** TokenId to mint/burn */\n tokenId: bigint\n /** Position size (uint128) */\n positionSize: bigint\n /** Lower tick limit */\n tickLimitLow: number\n /** Upper tick limit */\n tickLimitHigh: number\n}\n\n/** Return type from SFPM mintTokenizedPosition / burnTokenizedPosition */\nexport type SFPMSimulationResult = readonly [\n readonly [bigint, bigint, bigint, bigint],\n bigint,\n number,\n]\n\n/**\n * Simulate an SFPM mintTokenizedPosition call.\n *\n * @param params - Simulation parameters\n * @returns The result tuple: [collectedAmounts[4], totalSwapped, newTick]\n */\nexport async function simulateSFPMMint(params: SimulateSFPMParams): Promise<SFPMSimulationResult> {\n const {\n client,\n sfpmAddress,\n poolAddress,\n poolKey,\n tokenId,\n positionSize,\n tickLimitLow,\n tickLimitHigh,\n } = params\n\n const { result } = await client.simulateContract({\n address: sfpmAddress,\n abi: semiFungiblePositionManagerV4Abi,\n functionName: 'mintTokenizedPosition',\n args: [\n poolKey,\n tokenId,\n BigInt(positionSize) as bigint & { readonly __uint128: true },\n tickLimitLow,\n tickLimitHigh,\n ],\n account: poolAddress,\n })\n\n return result\n}\n\n/**\n * Simulate an SFPM burnTokenizedPosition call.\n *\n * @param params - Simulation parameters\n * @returns The result tuple: [collectedAmounts[4], totalSwapped, newTick]\n */\nexport async function simulateSFPMBurn(params: SimulateSFPMParams): Promise<SFPMSimulationResult> {\n const {\n client,\n sfpmAddress,\n poolAddress,\n poolKey,\n tokenId,\n positionSize,\n tickLimitLow,\n tickLimitHigh,\n } = params\n\n const { result } = await client.simulateContract({\n address: sfpmAddress,\n abi: semiFungiblePositionManagerV4Abi,\n functionName: 'burnTokenizedPosition',\n args: [\n poolKey,\n tokenId,\n BigInt(positionSize) as bigint & { readonly __uint128: true },\n tickLimitLow,\n tickLimitHigh,\n ],\n account: poolAddress,\n })\n\n return result\n}\n","/**\n * Swap simulation for the Panoptic v2 SDK.\n *\n * Mirrors `writes/swap.ts`, which swaps via width=0 **credit** legs rather than\n * loans so the swap can never be capped by a collateral tracker's utilization.\n *\n * @module v2/simulations/simulateSwap\n */\n\nimport type { Address, PublicClient } from 'viem'\nimport { encodeFunctionData } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { getBlockMeta } from '../clients'\nimport { PanopticError } from '../errors'\nimport { tickLimits } from '../formatters/tick'\nimport { getPool } from '../reads/pool'\nimport type { SimulationResult, TokenFlow } from '../types'\nimport { buildUniqueCredit, resolveTokenIndex } from '../writes/loanUtils'\nimport { simulateWithTokenFlow } from './tokenFlow'\n\n/**\n * Swap simulation data.\n */\nexport interface SwapSimulation {\n /** Amount of tokenIn spent (positive) */\n amountIn: bigint\n /** Amount of tokenOut received (positive) */\n amountOut: bigint\n /** Raw token flow from the simulation */\n tokenFlow: TokenFlow\n}\n\n/**\n * Parameters for simulateSwapExactOut.\n */\nexport interface SimulateSwapExactOutParams {\n /** Public client */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** Chain ID */\n chainId: bigint\n /** Token address to receive */\n tokenOut: Address\n /** Exact amount of tokenOut */\n amountOut: bigint\n /** Slippage tolerance in bps */\n slippageBps: bigint\n /** Existing position IDs */\n existingPositionIds: bigint[]\n /** Builder code for referral fee attribution. Defaults to `0n`. */\n builderCode?: bigint\n /** Optional block number */\n blockNumber?: bigint\n}\n\n/**\n * Parameters for simulateSwapExactIn.\n */\nexport interface SimulateSwapExactInParams {\n /** Public client */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** Chain ID */\n chainId: bigint\n /** Token address to sell */\n tokenIn: Address\n /** Exact amount of tokenIn */\n amountIn: bigint\n /** Slippage tolerance in bps */\n slippageBps: bigint\n /** Existing position IDs */\n existingPositionIds: bigint[]\n /** Builder code for referral fee attribution. Defaults to `0n`. */\n builderCode?: bigint\n /** Optional block number */\n blockNumber?: bigint\n}\n\n/**\n * Build dispatch calldata for swap simulation.\n */\nfunction buildSwapCallData(\n creditTokenId: bigint,\n existingPositionIds: bigint[],\n amount: bigint,\n mintTickLimits: readonly [number, number, number],\n burnTickLimits: readonly [number, number, number],\n builderCode: bigint,\n): `0x${string}` {\n return encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n [creditTokenId, creditTokenId],\n [...existingPositionIds],\n [amount, 0n],\n [mintTickLimits, burnTickLimits],\n false,\n builderCode,\n ],\n })\n}\n\n/**\n * Build SwapSimulation from token flow, given which token index is \"out\".\n */\nfunction buildSwapResult(tokenFlow: TokenFlow, tokenOutIndex: bigint): SwapSimulation {\n // delta is negative when user deposits, positive when user receives\n // For a swap: one delta should be negative (spent) and one positive (received)\n const delta0 = tokenFlow.delta0\n const delta1 = tokenFlow.delta1\n\n if (tokenOutIndex === 0n) {\n return {\n amountOut: delta0 > 0n ? delta0 : -delta0,\n amountIn: delta1 < 0n ? -delta1 : delta1,\n tokenFlow,\n }\n } else {\n return {\n amountOut: delta1 > 0n ? delta1 : -delta1,\n amountIn: delta0 < 0n ? -delta0 : delta0,\n tokenFlow,\n }\n }\n}\n\n/**\n * Simulate an exact-output swap.\n *\n * @param params - Simulation parameters\n * @returns Simulation result with swap data or error\n */\nexport async function simulateSwapExactOut(\n params: SimulateSwapExactOutParams,\n): Promise<SimulationResult<SwapSimulation>> {\n const {\n client,\n poolAddress,\n account,\n chainId,\n tokenOut,\n amountOut,\n slippageBps,\n existingPositionIds,\n builderCode = 0n,\n blockNumber,\n } = params\n\n try {\n const targetBlockNumber = blockNumber ?? (await client.getBlockNumber())\n const metaPromise = getBlockMeta({ client, blockNumber: targetBlockNumber })\n\n const pool = await getPool({ client, poolAddress, chainId, blockNumber: targetBlockNumber })\n const token0 = pool.collateralTracker0.token\n const token1 = pool.collateralTracker1.token\n const tokenOutIndex = resolveTokenIndex(tokenOut, token0, token1)\n // Credit is denominated in the exact token (tokenOut); asset === tokenType.\n // Using the counter-token here is the loan convention and inverts the swap.\n const tokenType = tokenOutIndex\n\n const { low: tickLimitLow, high: tickLimitHigh } = tickLimits(pool.currentTick, slippageBps)\n\n const { tokenId: creditTokenId, adjustedSize } = buildUniqueCredit(\n pool.poolId,\n tokenOutIndex,\n tokenType,\n pool.currentTick,\n pool.tickSpacing,\n existingPositionIds,\n amountOut,\n )\n\n // Mint: swapAtMint=true (descending), Burn: swapAtMint=false (ascending)\n const mintTickLimits: readonly [number, number, number] = [\n Number(tickLimitHigh),\n Number(tickLimitLow),\n 0,\n ]\n const burnTickLimits: readonly [number, number, number] = [\n Number(tickLimitLow),\n Number(tickLimitHigh),\n 0,\n ]\n\n const callData = buildSwapCallData(\n creditTokenId,\n existingPositionIds,\n adjustedSize,\n mintTickLimits,\n burnTickLimits,\n builderCode,\n )\n\n const flowResult = await simulateWithTokenFlow({\n client,\n poolAddress,\n user: account,\n callData,\n blockNumber: targetBlockNumber,\n })\n\n if (!flowResult.success || !flowResult.tokenFlow) {\n throw flowResult.rawError ?? new PanopticError(flowResult.error || 'Swap simulation failed')\n }\n\n const _meta = await metaPromise\n const data = buildSwapResult(flowResult.tokenFlow, tokenOutIndex)\n\n return {\n success: true,\n data,\n gasEstimate: flowResult.gasEstimate,\n tokenFlow: flowResult.tokenFlow,\n _meta,\n }\n } catch (error) {\n // Build a fallback _meta if getBlockMeta also failed\n const fallbackMeta = { blockNumber: 0n, blockTimestamp: 0n, blockHash: '0x0' as `0x${string}` }\n return {\n success: false,\n error:\n error instanceof PanopticError\n ? error\n : new PanopticError(\n error instanceof Error ? error.message : 'Simulation failed',\n error instanceof Error ? error : undefined,\n ),\n _meta: fallbackMeta,\n }\n }\n}\n\n/**\n * Simulate an exact-input swap.\n *\n * @param params - Simulation parameters\n * @returns Simulation result with swap data or error\n */\nexport async function simulateSwapExactIn(\n params: SimulateSwapExactInParams,\n): Promise<SimulationResult<SwapSimulation>> {\n const {\n client,\n poolAddress,\n account,\n chainId,\n tokenIn,\n amountIn,\n slippageBps,\n existingPositionIds,\n builderCode = 0n,\n blockNumber,\n } = params\n\n try {\n const targetBlockNumber = blockNumber ?? (await client.getBlockNumber())\n const metaPromise = getBlockMeta({ client, blockNumber: targetBlockNumber })\n\n const pool = await getPool({ client, poolAddress, chainId, blockNumber: targetBlockNumber })\n const token0 = pool.collateralTracker0.token\n const token1 = pool.collateralTracker1.token\n const tokenInIndex = resolveTokenIndex(tokenIn, token0, token1)\n const tokenType = tokenInIndex\n\n const { low: tickLimitLow, high: tickLimitHigh } = tickLimits(pool.currentTick, slippageBps)\n\n const { tokenId: creditTokenId, adjustedSize } = buildUniqueCredit(\n pool.poolId,\n tokenInIndex,\n tokenType,\n pool.currentTick,\n pool.tickSpacing,\n existingPositionIds,\n amountIn,\n )\n\n // Mint: swapAtMint=false (ascending), Burn: swapAtMint=true (descending)\n const mintTickLimits: readonly [number, number, number] = [\n Number(tickLimitLow),\n Number(tickLimitHigh),\n 0,\n ]\n const burnTickLimits: readonly [number, number, number] = [\n Number(tickLimitHigh),\n Number(tickLimitLow),\n 0,\n ]\n\n // tokenOut is the OTHER token\n const tokenOutIndex = tokenInIndex === 0n ? 1n : 0n\n\n const callData = buildSwapCallData(\n creditTokenId,\n existingPositionIds,\n adjustedSize,\n mintTickLimits,\n burnTickLimits,\n builderCode,\n )\n\n const flowResult = await simulateWithTokenFlow({\n client,\n poolAddress,\n user: account,\n callData,\n blockNumber: targetBlockNumber,\n })\n\n if (!flowResult.success || !flowResult.tokenFlow) {\n throw flowResult.rawError ?? new PanopticError(flowResult.error || 'Swap simulation failed')\n }\n\n const _meta = await metaPromise\n const data = buildSwapResult(flowResult.tokenFlow, tokenOutIndex)\n\n return {\n success: true,\n data,\n gasEstimate: flowResult.gasEstimate,\n tokenFlow: flowResult.tokenFlow,\n _meta,\n }\n } catch (error) {\n const fallbackMeta = { blockNumber: 0n, blockTimestamp: 0n, blockHash: '0x0' as `0x${string}` }\n return {\n success: false,\n error:\n error instanceof PanopticError\n ? error\n : new PanopticError(\n error instanceof Error ? error.message : 'Simulation failed',\n error instanceof Error ? error : undefined,\n ),\n _meta: fallbackMeta,\n }\n }\n}\n","/**\n * \"One token out\": force the net token flow of an arbitrary dispatch into a\n * single collateral token.\n *\n * Closing a multi-leg position normally settles in BOTH collateral tokens — a\n * straddle with one ITM leg pays out in one and charges in the other. This\n * module wraps the user's dispatch with a temporary width=0 credit leg that\n * cancels the non-target side, so the account's net change is (up to dust) in\n * one token only.\n *\n * Generalises {@link quoteTokenShortfallRecovery}, which handles the same\n * mechanism but only in the \"user is short a token\" direction and only when the\n * pool has already reverted with `NotEnoughTokens`.\n *\n * @module v2/simulations/oneTokenFlow\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { PanopticError } from '../errors'\nimport { getPool } from '../reads/pool'\nimport type { BlockMeta, TokenFlow } from '../types'\nimport { MAX_TICK, MIN_TICK } from '../utils/constants'\nimport { convertToTokenIndex } from '../utils/priceConvert'\nimport { buildUniqueCredit } from '../writes/loanUtils'\nimport {\n type CreditWrapDirection,\n type DispatchIntent,\n buildCreditWrappedDispatch,\n} from './creditWrap'\nimport { simulateDispatch } from './simulateDispatch'\nimport { getNotEnoughTokensError, quoteTokenShortfallRecovery } from './tokenShortfallRecovery'\n\nconst BPS_DENOMINATOR = 10_000n\n\n/**\n * Default {@link OneTokenFlowQuoteParams.minSwapRatioBps}: 0.5%.\n *\n * A swap pays a pool fee of roughly 5-30 bps plus slippage, so a non-target\n * flow below this fraction of the target flow cannot pay for itself — while\n * still leaving any residual small enough not to surprise someone who asked to\n * settle in one token.\n */\nexport const DEFAULT_MIN_SWAP_RATIO_BPS = 50n\n\nexport interface OneTokenFlowQuoteParams {\n client: PublicClient\n poolAddress: Address\n account: Address\n chainId: bigint\n /** The user's actual on-chain position list BEFORE the dispatch. */\n existingPositionIds: bigint[]\n /** The dispatch the user is about to send, unwrapped. */\n dispatch: DispatchIntent\n /** Index of the token the whole net flow should land in: `0n` or `1n`. */\n targetTokenIndex: bigint\n /**\n * Slippage tolerance for the credit swap, in **basis points** (1% = 100).\n * Applied to the estimated target-token cost of an exact-out swap to produce\n * `maximumAmountIn`. Values above `10_000` (100%) are rejected.\n */\n slippageBps: bigint\n /**\n * Minimum size of the non-target flow, in **basis points** of the target\n * token's own flow, for the swap to be worth doing. Below this the residual\n * is dust and the swap would cost more in pool fee and slippage than it\n * settles, so the quote reports `below-threshold` and the caller falls back\n * to the native two-token flow. Defaults to\n * {@link DEFAULT_MIN_SWAP_RATIO_BPS}. Pass `0n` to always swap.\n *\n * Only applied when the unwrapped dispatch simulates successfully. When it\n * reverts on a shortfall, the swap is what makes the transaction possible at\n * all, so no threshold is applied.\n */\n minSwapRatioBps?: bigint\n /**\n * Price bound for the temporary credit legs. Defaults to the full tick range —\n * the swap is protected economically by the balance check, not by a price\n * band, and the user's own operations keep their own limits.\n */\n tickLimitLow?: bigint\n /** See {@link OneTokenFlowQuoteParams.tickLimitLow}. */\n tickLimitHigh?: bigint\n blockNumber?: bigint\n}\n\nexport interface OneTokenFlowQuote {\n targetToken: Address\n otherToken: Address\n targetTokenIndex: bigint\n otherTokenIndex: bigint\n direction: CreditWrapDirection\n /**\n * Amount of `otherToken` the credit sources (`exact-out`) or sells\n * (`exact-in`) — i.e. the non-target flow being cancelled.\n */\n swapAmount: bigint\n /**\n * Target-token side of the swap leg alone, priced by a swap-only simulation:\n * spent for `exact-out`, received for `exact-in`. NOT the same as\n * `netTargetChange`, which also includes the user's own operations.\n */\n estimatedCounterAmount: bigint\n /** `estimatedCounterAmount` padded by `slippageBps`. `exact-out` only. */\n maximumAmountIn: bigint\n slippageBps: bigint\n /** Signed net change of the target token across the ENTIRE wrapped tx. */\n netTargetChange: bigint\n /**\n * Signed net change of the other token across the entire wrapped tx — the\n * residual dust left by sizing the credit from a single simulation. Disclose\n * this to the user rather than claiming an exact zero.\n */\n residualOtherChange: bigint\n /** The temporary width=0 credit leg used to move the flow. */\n creditTokenId: bigint\n dispatch: DispatchIntent\n tokenFlow: TokenFlow\n _meta: BlockMeta\n}\n\nexport type OneTokenFlowUnavailableReason =\n | 'already-single-token'\n | 'below-threshold'\n | 'base-simulation-failed'\n | 'invalid-slippage'\n | 'invalid-target-token'\n | 'invalid-tick-limits'\n | 'swap-unavailable'\n | 'wrap-unavailable'\n\nexport type OneTokenFlowResult =\n | { available: true; quote: OneTokenFlowQuote }\n | {\n available: false\n reason: OneTokenFlowUnavailableReason\n /** Human-readable description of the sub-step that failed, for diagnostics. */\n detail?: string\n error?: PanopticError\n }\n\nfunction deltaAt(tokenFlow: TokenFlow, index: bigint): bigint {\n return index === 0n ? tokenFlow.delta0 : tokenFlow.delta1\n}\n\nfunction balanceBeforeAt(tokenFlow: TokenFlow, index: bigint): bigint {\n return index === 0n ? tokenFlow.balanceBefore0 : tokenFlow.balanceBefore1\n}\n\nfunction abs(value: bigint): bigint {\n return value < 0n ? -value : value\n}\n\nfunction padForSlippage(amount: bigint, slippageBps: bigint): bigint {\n return (amount * (BPS_DENOMINATOR + slippageBps) + BPS_DENOMINATOR - 1n) / BPS_DENOMINATOR\n}\n\n/**\n * Quote a dispatch wrapped so its net flow lands in `targetTokenIndex` only.\n *\n * Three simulations, all pinned to one block and with no convergence loop:\n *\n * 1. the user's dispatch as-is, to measure the non-target flow to cancel;\n * 2. the credit legs alone, to price the swap and check the source balance;\n * 3. the wrapped dispatch, whose token flow is what the user is shown and what\n * the residual dust is read from.\n */\nexport async function quoteOneTokenFlow(\n params: OneTokenFlowQuoteParams,\n): Promise<OneTokenFlowResult> {\n const { targetTokenIndex } = params\n const minSwapRatioBps = params.minSwapRatioBps ?? DEFAULT_MIN_SWAP_RATIO_BPS\n if (targetTokenIndex !== 0n && targetTokenIndex !== 1n) {\n return {\n available: false,\n reason: 'invalid-target-token',\n detail: `targetTokenIndex=${targetTokenIndex} is neither 0 nor 1`,\n }\n }\n if (params.slippageBps < 0n || params.slippageBps > BPS_DENOMINATOR) {\n return {\n available: false,\n reason: 'invalid-slippage',\n detail: `slippageBps=${params.slippageBps} is outside [0, ${BPS_DENOMINATOR}]`,\n }\n }\n const tickLimitLow = params.tickLimitLow ?? MIN_TICK\n const tickLimitHigh = params.tickLimitHigh ?? MAX_TICK\n if (tickLimitLow >= tickLimitHigh) {\n return {\n available: false,\n reason: 'invalid-tick-limits',\n detail: `tickLimitLow=${tickLimitLow} >= tickLimitHigh=${tickLimitHigh}`,\n }\n }\n\n const otherTokenIndex = targetTokenIndex === 0n ? 1n : 0n\n const targetBlockNumber = params.blockNumber ?? (await params.client.getBlockNumber())\n const simulateArgs = {\n client: params.client,\n poolAddress: params.poolAddress,\n account: params.account,\n existingPositionIdList: params.existingPositionIds,\n blockNumber: targetBlockNumber,\n }\n\n // Read ahead of the simulation: the shortfall branch below has to know which\n // collateral a NotEnoughTokens revert refers to before it can size a credit.\n const pool = await getPool({\n client: params.client,\n poolAddress: params.poolAddress,\n chainId: params.chainId,\n blockNumber: targetBlockNumber,\n })\n const token0 = pool.collateralTracker0.token\n const token1 = pool.collateralTracker1.token\n const targetToken = targetTokenIndex === 0n ? token0 : token1\n const otherToken = otherTokenIndex === 0n ? token0 : token1\n // NotEnoughTokens is raised by the CollateralTracker and carries ITS address,\n // not the underlying token's.\n const otherTracker =\n otherTokenIndex === 0n ? pool.collateralTracker0.address : pool.collateralTracker1.address\n\n // 1. The user's dispatch as-is. When it reverts because the account is short\n // the non-target token, the revert itself quantifies the flow to cancel —\n // so one-token-out subsumes the plain shortfall-recovery case.\n const baseSimulation = await simulateDispatch({ ...simulateArgs, ...params.dispatch })\n let swapAmount: bigint\n let direction: CreditWrapDirection\n // The target-token flow of the user's ops alone. Null when the base dispatch\n // reverted, which only happens on the exact-out path.\n let baseTargetDelta: bigint | null = null\n if (baseSimulation.success && baseSimulation.tokenFlow !== undefined) {\n baseTargetDelta = deltaAt(baseSimulation.tokenFlow, targetTokenIndex)\n const otherDelta = deltaAt(baseSimulation.tokenFlow, otherTokenIndex)\n if (otherDelta === 0n) {\n return {\n available: false,\n reason: 'already-single-token',\n detail: 'the dispatch does not move the non-target token',\n }\n }\n // delta < 0: the account PAYS the other token — source it (exact-out).\n // delta > 0: the account RECEIVES it — sell it into the target (exact-in).\n direction = otherDelta < 0n ? 'exact-out' : 'exact-in'\n swapAmount = abs(otherDelta)\n } else {\n const shortfall = baseSimulation.success ? null : getNotEnoughTokensError(baseSimulation.error)\n if (shortfall === null) {\n return {\n available: false,\n reason: 'base-simulation-failed',\n detail: baseSimulation.success\n ? 'base simulation returned no token flow'\n : `base simulation reverted: ${baseSimulation.error.message}`,\n error: baseSimulation.success ? undefined : baseSimulation.error,\n }\n }\n // Only a shortfall in the NON-target collateral can be sized as a credit in\n // otherTokenIndex. A shortfall in the target token (or in neither) means the\n // account cannot fund the position at all, and sourcing the other token\n // would quote a swap that does not address it.\n if (shortfall.tokenAddress.toLowerCase() !== otherTracker.toLowerCase()) {\n return {\n available: false,\n reason: 'base-simulation-failed',\n detail: `shortfall is in ${shortfall.tokenAddress}, not the non-target collateral ${otherTracker}`,\n error: baseSimulation.success ? undefined : baseSimulation.error,\n }\n }\n const pending = shortfall.assetsRequested - shortfall.assetBalance\n if (pending <= 0n) {\n return {\n available: false,\n reason: 'base-simulation-failed',\n detail: `requested=${shortfall.assetsRequested} <= balance=${shortfall.assetBalance}`,\n }\n }\n const recovery = await quoteTokenShortfallRecovery({\n client: params.client,\n poolAddress: params.poolAddress,\n account: params.account,\n chainId: params.chainId,\n existingPositionIds: params.existingPositionIds,\n dispatch: params.dispatch,\n error: shortfall,\n slippageBps: params.slippageBps,\n tickLimitLow: params.tickLimitLow,\n tickLimitHigh: params.tickLimitHigh,\n blockNumber: targetBlockNumber,\n })\n if (!recovery.available) {\n return {\n available: false,\n reason: recovery.reason === 'swap-unavailable' ? 'swap-unavailable' : 'wrap-unavailable',\n detail: recovery.detail,\n error: recovery.error,\n }\n }\n return {\n available: true,\n quote: {\n targetToken,\n otherToken,\n targetTokenIndex,\n otherTokenIndex,\n direction: recovery.quote.direction,\n swapAmount: recovery.quote.amountOut,\n estimatedCounterAmount: recovery.quote.estimatedAmountIn,\n maximumAmountIn: recovery.quote.maximumAmountIn,\n slippageBps: params.slippageBps,\n netTargetChange: recovery.quote.netTokenInChange,\n residualOtherChange: recovery.quote.netTokenOutChange,\n creditTokenId: recovery.quote.creditTokenId,\n dispatch: recovery.quote.dispatch,\n tokenFlow: recovery.quote.tokenFlow,\n _meta: recovery.quote._meta,\n },\n }\n }\n\n // Dust gate. The non-target flow is only worth swapping if it is material\n // next to the flow being settled; below that the swap burns a pool fee and\n // slippage to move an amount the user cannot see. Skipped when the base\n // dispatch reverted (baseTargetDelta === null), because there the swap is\n // what makes the transaction possible rather than a convenience.\n //\n // Compared in the target token's terms so the two sides share a scale. Note\n // this is deliberately NOT a fraction of notional: Neutralize ITM drives the\n // net flow toward zero while notional stays large, which would suppress the\n // swap on nearly every neutralized position.\n if (baseTargetDelta !== null && minSwapRatioBps > 0n) {\n const swapInTargetTerms = convertToTokenIndex(\n swapAmount,\n otherTokenIndex,\n targetTokenIndex,\n pool.sqrtPriceX96,\n )\n if (swapInTargetTerms * BPS_DENOMINATOR < minSwapRatioBps * abs(baseTargetDelta)) {\n return {\n available: false,\n reason: 'below-threshold',\n detail:\n `non-target flow ${swapInTargetTerms} (in target token terms) is below ` +\n `${minSwapRatioBps}bps of the target flow ${abs(baseTargetDelta)}`,\n }\n }\n }\n\n // asset === tokenType === otherTokenIndex: the credit is denominated in the\n // token whose flow is being cancelled. Passing the counter-token as tokenType\n // is the LOAN convention and silently inverts the swap.\n const collisionIds = Array.from(\n new Set([\n ...params.existingPositionIds,\n ...params.dispatch.positionIdList,\n ...params.dispatch.finalPositionIdList,\n ]),\n )\n const credit = buildUniqueCredit(\n pool.poolId,\n otherTokenIndex,\n otherTokenIndex,\n pool.currentTick,\n pool.tickSpacing,\n collisionIds,\n swapAmount,\n )\n\n // exact-out must straddle the user's ops so the sourced token is available\n // while they run; exact-in can only follow them, since the token being sold\n // does not exist until they have run.\n const placement = direction === 'exact-out' ? 'straddle' : 'append'\n const creditWrapArgs = {\n creditTokenId: credit.tokenId,\n creditPositionSize: credit.adjustedSize,\n tickLimitLow,\n tickLimitHigh,\n direction,\n placement,\n } as const\n\n // 2. For exact-out ONLY, the credit legs alone: prices the swap and proves the\n // account can cover it out of the target token before it is committed to.\n //\n // Deliberately skipped for exact-in. There, the token being sold does not\n // exist until the user's ops have run, so a swap-only simulation reverts\n // for an account holding none of it — refusing a wrap that would in fact\n // have worked. Its price is recovered from the wrapped run instead, and no\n // balance guard is needed since the ops themselves fund the sale.\n let estimatedCounterAmount = 0n\n let maximumAmountIn = 0n\n if (direction === 'exact-out') {\n const swapOnlyDispatch = buildCreditWrappedDispatch({\n ...creditWrapArgs,\n dispatch: {\n positionIdList: [],\n finalPositionIdList: [...params.existingPositionIds],\n positionSizes: [],\n tickAndSpreadLimits: [],\n usePremiaAsCollateral: false,\n builderCode: 0n,\n },\n })\n const swapSimulation = await simulateDispatch({ ...simulateArgs, ...swapOnlyDispatch })\n if (!swapSimulation.success || swapSimulation.tokenFlow === undefined) {\n return {\n available: false,\n reason: 'swap-unavailable',\n detail: swapSimulation.success\n ? 'swap-only simulation returned no token flow'\n : `swap-only simulation reverted: ${swapSimulation.error.message}`,\n error: swapSimulation.success ? undefined : swapSimulation.error,\n }\n }\n estimatedCounterAmount = abs(deltaAt(swapSimulation.tokenFlow, targetTokenIndex))\n maximumAmountIn = padForSlippage(estimatedCounterAmount, params.slippageBps)\n const sourceBalance = balanceBeforeAt(swapSimulation.tokenFlow, targetTokenIndex)\n if (sourceBalance < maximumAmountIn) {\n return {\n available: false,\n reason: 'swap-unavailable',\n detail: `source balance ${sourceBalance} < maximumAmountIn ${maximumAmountIn} (estimated ${estimatedCounterAmount}, slippageBps ${params.slippageBps})`,\n error: new PanopticError('Insufficient collateral to fund the one-token-out swap'),\n }\n }\n }\n\n // 3. The wrapped dispatch. Single pass — the swap itself shifts fees and\n // commission slightly, so the non-target side lands near, not exactly at,\n // zero. That remainder is surfaced as `residualOtherChange`.\n const wrappedDispatch = buildCreditWrappedDispatch({\n ...creditWrapArgs,\n dispatch: params.dispatch,\n })\n const wrappedSimulation = await simulateDispatch({ ...simulateArgs, ...wrappedDispatch })\n if (!wrappedSimulation.success || wrappedSimulation.tokenFlow === undefined) {\n return {\n available: false,\n reason: 'wrap-unavailable',\n detail: wrappedSimulation.success\n ? 'wrapped dispatch simulation returned no token flow'\n : `wrapped dispatch reverted: ${wrappedSimulation.error.message}`,\n error: wrappedSimulation.success ? undefined : wrappedSimulation.error,\n }\n }\n\n // exact-in never priced the swap on its own (see above): recover it as the\n // extra target-token the wrap produced over the plain dispatch.\n if (direction === 'exact-in' && baseTargetDelta !== null) {\n estimatedCounterAmount = abs(\n deltaAt(wrappedSimulation.tokenFlow, targetTokenIndex) - baseTargetDelta,\n )\n }\n\n return {\n available: true,\n quote: {\n targetToken,\n otherToken,\n targetTokenIndex,\n otherTokenIndex,\n direction,\n swapAmount,\n estimatedCounterAmount,\n maximumAmountIn,\n slippageBps: params.slippageBps,\n netTargetChange: deltaAt(wrappedSimulation.tokenFlow, targetTokenIndex),\n residualOtherChange: deltaAt(wrappedSimulation.tokenFlow, otherTokenIndex),\n creditTokenId: credit.tokenId,\n dispatch: wrappedDispatch,\n tokenFlow: wrappedSimulation.tokenFlow,\n _meta: wrappedSimulation._meta,\n },\n }\n}\n","/**\n * Uniswap v4 PoolManager event ABI (subset for event watching).\n * @module abis/poolManager\n */\n\nexport const poolManagerAbi = [\n {\n type: 'event',\n anonymous: false,\n inputs: [\n { name: 'id', internalType: 'PoolId', type: 'bytes32', indexed: true },\n { name: 'sender', internalType: 'address', type: 'address', indexed: true },\n { name: 'tickLower', internalType: 'int24', type: 'int24', indexed: false },\n { name: 'tickUpper', internalType: 'int24', type: 'int24', indexed: false },\n { name: 'liquidityDelta', internalType: 'int256', type: 'int256', indexed: false },\n { name: 'salt', internalType: 'bytes32', type: 'bytes32', indexed: false },\n ],\n name: 'ModifyLiquidity',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n { name: 'id', internalType: 'PoolId', type: 'bytes32', indexed: true },\n { name: 'sender', internalType: 'address', type: 'address', indexed: true },\n { name: 'amount0', internalType: 'int128', type: 'int128', indexed: false },\n { name: 'amount1', internalType: 'int128', type: 'int128', indexed: false },\n { name: 'sqrtPriceX96', internalType: 'uint160', type: 'uint160', indexed: false },\n { name: 'liquidity', internalType: 'uint128', type: 'uint128', indexed: false },\n { name: 'tick', internalType: 'int24', type: 'int24', indexed: false },\n { name: 'fee', internalType: 'uint24', type: 'uint24', indexed: false },\n ],\n name: 'Swap',\n },\n {\n type: 'event',\n anonymous: false,\n inputs: [\n { name: 'id', internalType: 'PoolId', type: 'bytes32', indexed: true },\n { name: 'sender', internalType: 'address', type: 'address', indexed: true },\n { name: 'amount0', internalType: 'uint256', type: 'uint256', indexed: false },\n { name: 'amount1', internalType: 'uint256', type: 'uint256', indexed: false },\n ],\n name: 'Donate',\n },\n] as const\n","/**\n * Simple WebSocket event watching for the Panoptic v2 SDK.\n * @module v2/events/watchEvents\n */\n\nimport type { Address, Hash, Log, PublicClient } from 'viem'\n\nimport {\n collateralTrackerV2Abi,\n panopticPoolV2Abi,\n riskEngineAbi,\n semiFungiblePositionManagerV4Abi,\n} from '../../../generated'\nimport { poolManagerAbi } from '../abis/poolManager'\nimport type { PanopticEvent, PanopticEventType } from '../types'\nimport { decodeLeftRightSigned, decodePositionBalance } from '../writes/utils'\n\n/**\n * A decoded contract event log that includes both base Log fields and typed args.\n * viem's getContractEvents/watchContractEvent return logs with `.args`,\n * but the generic `Log` type doesn't include it. We use `unknown` for args\n * and narrow to specific types in each parse function's switch cases.\n */\ntype DecodedLog = Log & { args: unknown }\n\n/**\n * Parameters for watching events.\n */\nexport interface WatchEventsParams {\n /** Public client (must have WebSocket transport for real-time watching) */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** CollateralTracker0 address (optional, for Deposit/Withdraw/ProtocolLossRealized events) */\n collateralTracker0?: Address\n /** CollateralTracker1 address (optional, for Deposit/Withdraw/ProtocolLossRealized events) */\n collateralTracker1?: Address\n /** RiskEngine address (optional, for BorrowRateUpdated events) */\n riskEngineAddress?: Address\n /** SemiFungiblePositionManager address (optional, for LiquidityChunkUpdated events) */\n sfpmAddress?: Address\n /** v4 PoolManager address (optional, for ModifyLiquidity/Swap/Donate events) */\n poolManagerAddress?: Address\n /** Event types to filter (omit for all events) */\n eventTypes?: PanopticEventType[]\n /** Callback for received events */\n onLogs: (events: PanopticEvent[]) => void\n /** Callback for errors */\n onError?: (error: Error) => void\n}\n\n/**\n * Event name to ABI event mapping for PanopticPool.\n */\nconst POOL_EVENT_NAMES: Record<string, PanopticEventType> = {\n OptionMinted: 'OptionMinted',\n OptionBurnt: 'OptionBurnt',\n AccountLiquidated: 'AccountLiquidated',\n ForcedExercised: 'ForcedExercised',\n PremiumSettled: 'PremiumSettled',\n}\n\n/**\n * Event name to ABI event mapping for CollateralTracker.\n */\nconst COLLATERAL_EVENT_NAMES: Record<string, PanopticEventType> = {\n Deposit: 'Deposit',\n Withdraw: 'Withdraw',\n ProtocolLossRealized: 'ProtocolLossRealized',\n}\n\n/**\n * Event name to ABI event mapping for RiskEngine.\n */\nconst RISK_ENGINE_EVENT_NAMES: Record<string, PanopticEventType> = {\n BorrowRateUpdated: 'BorrowRateUpdated',\n}\n\n/**\n * Event name to ABI event mapping for SFPM.\n */\nconst SFPM_EVENT_NAMES: Record<string, PanopticEventType> = {\n LiquidityChunkUpdated: 'LiquidityChunkUpdated',\n}\n\n/**\n * Event name to ABI event mapping for v4 PoolManager.\n */\nconst POOL_MANAGER_EVENT_NAMES: Record<string, PanopticEventType> = {\n ModifyLiquidity: 'ModifyLiquidity',\n Swap: 'Swap',\n Donate: 'Donate',\n}\n\n/**\n * Parse a decoded log into a typed PanopticEvent.\n */\nfunction parsePoolLog(log: DecodedLog, eventName: string): PanopticEvent | null {\n const baseEvent = {\n transactionHash: log.transactionHash!,\n blockNumber: log.blockNumber!,\n blockHash: log.blockHash!,\n logIndex: BigInt(log.logIndex!),\n }\n\n // Type narrowing based on event name\n switch (eventName) {\n case 'OptionMinted': {\n const args = log.args as { recipient: Address; tokenId: bigint; balanceData: bigint }\n const balanceData = decodePositionBalance(args.balanceData)\n return {\n type: 'OptionMinted',\n ...baseEvent,\n recipient: args.recipient,\n tokenId: args.tokenId,\n positionSize: balanceData.positionSize,\n poolUtilization0: balanceData.poolUtilization0,\n poolUtilization1: balanceData.poolUtilization1,\n tickAtMint: balanceData.tickAtMint,\n timestampAtMint: balanceData.timestampAtMint,\n blockAtMint: balanceData.blockAtMint,\n swapAtMint: balanceData.swapAtMint,\n }\n }\n\n case 'OptionBurnt': {\n const args = log.args as {\n recipient: Address\n positionSize: bigint\n tokenId: bigint\n premiaByLeg: readonly [bigint, bigint, bigint, bigint]\n }\n return {\n type: 'OptionBurnt',\n ...baseEvent,\n recipient: args.recipient,\n tokenId: args.tokenId,\n positionSize: args.positionSize,\n premiaByLeg: args.premiaByLeg,\n }\n }\n\n case 'AccountLiquidated': {\n const args = log.args as { liquidator: Address; liquidatee: Address; bonusAmounts: bigint }\n const bonus = decodeLeftRightSigned(args.bonusAmounts)\n return {\n type: 'AccountLiquidated',\n ...baseEvent,\n liquidator: args.liquidator,\n liquidatee: args.liquidatee,\n bonusAmount0: bonus.right,\n bonusAmount1: bonus.left,\n }\n }\n\n case 'ForcedExercised': {\n const args = log.args as {\n exercisor: Address\n user: Address\n tokenId: bigint\n exerciseFee: bigint\n }\n const fee = decodeLeftRightSigned(args.exerciseFee)\n return {\n type: 'ForcedExercised',\n ...baseEvent,\n exercisor: args.exercisor,\n user: args.user,\n tokenId: args.tokenId,\n exerciseFee0: fee.right,\n exerciseFee1: fee.left,\n }\n }\n\n case 'PremiumSettled': {\n const args = log.args as {\n user: Address\n tokenId: bigint\n legIndex: bigint\n settledAmounts: bigint\n }\n const settled = decodeLeftRightSigned(args.settledAmounts)\n return {\n type: 'PremiumSettled',\n ...baseEvent,\n user: args.user,\n tokenId: args.tokenId,\n legIndex: args.legIndex,\n settledAmount0: settled.right,\n settledAmount1: settled.left,\n }\n }\n\n default:\n return null\n }\n}\n\n/**\n * Parse a CollateralTracker log into a typed PanopticEvent.\n */\nfunction parseCollateralLog(log: DecodedLog, eventName: string): PanopticEvent | null {\n const baseEvent = {\n transactionHash: log.transactionHash!,\n blockNumber: log.blockNumber!,\n blockHash: log.blockHash!,\n logIndex: BigInt(log.logIndex!),\n }\n\n switch (eventName) {\n case 'Deposit': {\n const args = log.args as { sender: Address; owner: Address; assets: bigint; shares: bigint }\n return {\n type: 'Deposit',\n ...baseEvent,\n sender: args.sender,\n owner: args.owner,\n assets: args.assets,\n shares: args.shares,\n }\n }\n\n case 'Withdraw': {\n const args = log.args as {\n sender: Address\n receiver: Address\n owner: Address\n assets: bigint\n shares: bigint\n }\n return {\n type: 'Withdraw',\n ...baseEvent,\n sender: args.sender,\n receiver: args.receiver,\n owner: args.owner,\n assets: args.assets,\n shares: args.shares,\n }\n }\n\n case 'ProtocolLossRealized': {\n const args = log.args as {\n liquidatee: Address\n liquidator: Address\n protocolLossAssets: bigint\n protocolLossShares: bigint\n }\n return {\n type: 'ProtocolLossRealized',\n ...baseEvent,\n liquidatee: args.liquidatee,\n liquidator: args.liquidator,\n protocolLossAssets: args.protocolLossAssets,\n protocolLossShares: args.protocolLossShares,\n }\n }\n\n default:\n return null\n }\n}\n\n/**\n * Parse a RiskEngine log into a typed PanopticEvent.\n */\nfunction parseRiskEngineLog(log: DecodedLog, eventName: string): PanopticEvent | null {\n const baseEvent = {\n transactionHash: log.transactionHash!,\n blockNumber: log.blockNumber!,\n blockHash: log.blockHash!,\n logIndex: BigInt(log.logIndex!),\n }\n\n switch (eventName) {\n case 'BorrowRateUpdated': {\n const args = log.args as {\n collateralToken: Address\n avgBorrowRate: bigint\n rateAtTarget: bigint\n }\n return {\n type: 'BorrowRateUpdated',\n ...baseEvent,\n collateralToken: args.collateralToken,\n avgBorrowRate: args.avgBorrowRate,\n rateAtTarget: args.rateAtTarget,\n }\n }\n\n default:\n return null\n }\n}\n\n/**\n * Parse an SFPM log into a typed PanopticEvent.\n */\nfunction parseSfpmLog(log: DecodedLog, eventName: string): PanopticEvent | null {\n const baseEvent = {\n transactionHash: log.transactionHash!,\n blockNumber: log.blockNumber!,\n blockHash: log.blockHash!,\n logIndex: BigInt(log.logIndex!),\n }\n\n switch (eventName) {\n case 'LiquidityChunkUpdated': {\n const args = log.args as {\n poolId: Hash\n owner: Address\n tokenType: bigint\n tickLower: number\n tickUpper: number\n liquidityDelta: bigint\n }\n return {\n type: 'LiquidityChunkUpdated',\n ...baseEvent,\n poolId: args.poolId,\n owner: args.owner,\n tokenType: args.tokenType,\n tickLower: args.tickLower,\n tickUpper: args.tickUpper,\n liquidityDelta: args.liquidityDelta,\n }\n }\n\n default:\n return null\n }\n}\n\n/**\n * Parse a v4 PoolManager log into a typed PanopticEvent.\n */\nfunction parsePoolManagerLog(log: DecodedLog, eventName: string): PanopticEvent | null {\n const baseEvent = {\n transactionHash: log.transactionHash!,\n blockNumber: log.blockNumber!,\n blockHash: log.blockHash!,\n logIndex: BigInt(log.logIndex!),\n }\n\n switch (eventName) {\n case 'ModifyLiquidity': {\n const args = log.args as {\n id: Hash\n sender: Address\n tickLower: number\n tickUpper: number\n liquidityDelta: bigint\n salt: Hash\n }\n return {\n type: 'ModifyLiquidity',\n ...baseEvent,\n id: args.id,\n sender: args.sender,\n tickLower: args.tickLower,\n tickUpper: args.tickUpper,\n liquidityDelta: args.liquidityDelta,\n salt: args.salt,\n }\n }\n\n case 'Swap': {\n const args = log.args as {\n id: Hash\n sender: Address\n amount0: bigint\n amount1: bigint\n sqrtPriceX96: bigint\n liquidity: bigint\n tick: number\n fee: number\n }\n return {\n type: 'Swap',\n ...baseEvent,\n id: args.id,\n sender: args.sender,\n amount0: args.amount0,\n amount1: args.amount1,\n sqrtPriceX96: args.sqrtPriceX96,\n liquidity: args.liquidity,\n tick: args.tick,\n fee: args.fee,\n }\n }\n\n case 'Donate': {\n const args = log.args as { id: Hash; sender: Address; amount0: bigint; amount1: bigint }\n return {\n type: 'Donate',\n ...baseEvent,\n id: args.id,\n sender: args.sender,\n amount0: args.amount0,\n amount1: args.amount1,\n }\n }\n\n default:\n return null\n }\n}\n\n/**\n * Watch for Panoptic events in real-time using WebSocket.\n *\n * This is a one-shot watcher - if the WebSocket disconnects, it stops.\n * For production bots that need automatic reconnection, use `createEventSubscription()`.\n *\n * @param params - Watch parameters\n * @returns Unwatch function to stop watching\n *\n * @example\n * ```typescript\n * const unwatch = watchEvents({\n * client,\n * poolAddress,\n * eventTypes: ['OptionMinted', 'OptionBurnt'],\n * onLogs: (events) => {\n * for (const event of events) {\n * console.log(event.type, event)\n * }\n * },\n * onError: (error) => console.error(error),\n * })\n *\n * // Later: stop watching\n * unwatch()\n * ```\n */\nexport function watchEvents(params: WatchEventsParams): () => void {\n const {\n client,\n poolAddress,\n collateralTracker0,\n collateralTracker1,\n riskEngineAddress,\n sfpmAddress,\n poolManagerAddress,\n eventTypes,\n onLogs,\n onError,\n } = params\n\n const unwatchFns: (() => void)[] = []\n\n // Determine which pool events to watch\n const poolEventTypesToWatch = eventTypes\n ? eventTypes.filter((t) => t in POOL_EVENT_NAMES)\n : (Object.keys(POOL_EVENT_NAMES) as PanopticEventType[])\n\n // Watch PanopticPool events\n for (const eventType of poolEventTypesToWatch) {\n try {\n const unwatch = client.watchContractEvent({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n eventName: eventType as\n | 'OptionMinted'\n | 'OptionBurnt'\n | 'AccountLiquidated'\n | 'ForcedExercised'\n | 'PremiumSettled',\n onLogs: (logs) => {\n const events: PanopticEvent[] = []\n for (const log of logs) {\n const parsed = parsePoolLog(log as DecodedLog, eventType)\n if (parsed) {\n events.push(parsed)\n }\n }\n if (events.length > 0) {\n onLogs(events)\n }\n },\n onError: onError,\n })\n unwatchFns.push(unwatch)\n } catch (error) {\n onError?.(error instanceof Error ? error : new Error(String(error)))\n }\n }\n\n // Determine which collateral events to watch\n const collateralEventTypesToWatch = eventTypes\n ? eventTypes.filter((t) => t in COLLATERAL_EVENT_NAMES)\n : (Object.keys(COLLATERAL_EVENT_NAMES) as PanopticEventType[])\n\n // Watch CollateralTracker events (if addresses provided)\n const collateralTrackers = [collateralTracker0, collateralTracker1].filter(Boolean) as Address[]\n\n for (const trackerAddress of collateralTrackers) {\n for (const eventType of collateralEventTypesToWatch) {\n try {\n const unwatch = client.watchContractEvent({\n address: trackerAddress,\n abi: collateralTrackerV2Abi,\n eventName: eventType as 'Deposit' | 'Withdraw' | 'ProtocolLossRealized',\n onLogs: (logs) => {\n const events: PanopticEvent[] = []\n for (const log of logs) {\n const parsed = parseCollateralLog(log as DecodedLog, eventType)\n if (parsed) {\n events.push(parsed)\n }\n }\n if (events.length > 0) {\n onLogs(events)\n }\n },\n onError: onError,\n })\n unwatchFns.push(unwatch)\n } catch (error) {\n onError?.(error instanceof Error ? error : new Error(String(error)))\n }\n }\n }\n\n // Watch RiskEngine events (if address provided)\n if (riskEngineAddress) {\n const riskEngineEventTypesToWatch = eventTypes\n ? eventTypes.filter((t) => t in RISK_ENGINE_EVENT_NAMES)\n : (Object.keys(RISK_ENGINE_EVENT_NAMES) as PanopticEventType[])\n\n for (const eventType of riskEngineEventTypesToWatch) {\n try {\n const unwatch = client.watchContractEvent({\n address: riskEngineAddress,\n abi: riskEngineAbi,\n eventName: eventType as 'BorrowRateUpdated',\n onLogs: (logs) => {\n const events: PanopticEvent[] = []\n for (const log of logs) {\n const parsed = parseRiskEngineLog(log as DecodedLog, eventType)\n if (parsed) {\n events.push(parsed)\n }\n }\n if (events.length > 0) {\n onLogs(events)\n }\n },\n onError: onError,\n })\n unwatchFns.push(unwatch)\n } catch (error) {\n onError?.(error instanceof Error ? error : new Error(String(error)))\n }\n }\n }\n\n // Watch SFPM events (if address provided)\n if (sfpmAddress) {\n const sfpmEventTypesToWatch = eventTypes\n ? eventTypes.filter((t) => t in SFPM_EVENT_NAMES)\n : (Object.keys(SFPM_EVENT_NAMES) as PanopticEventType[])\n\n for (const eventType of sfpmEventTypesToWatch) {\n try {\n const unwatch = client.watchContractEvent({\n address: sfpmAddress,\n abi: semiFungiblePositionManagerV4Abi,\n eventName: eventType as 'LiquidityChunkUpdated',\n onLogs: (logs) => {\n const events: PanopticEvent[] = []\n for (const log of logs) {\n const parsed = parseSfpmLog(log as DecodedLog, eventType)\n if (parsed) {\n events.push(parsed)\n }\n }\n if (events.length > 0) {\n onLogs(events)\n }\n },\n onError: onError,\n })\n unwatchFns.push(unwatch)\n } catch (error) {\n onError?.(error instanceof Error ? error : new Error(String(error)))\n }\n }\n }\n\n // Watch PoolManager events (if address provided)\n if (poolManagerAddress) {\n const poolManagerEventTypesToWatch = eventTypes\n ? eventTypes.filter((t) => t in POOL_MANAGER_EVENT_NAMES)\n : (Object.keys(POOL_MANAGER_EVENT_NAMES) as PanopticEventType[])\n\n for (const eventType of poolManagerEventTypesToWatch) {\n try {\n const unwatch = client.watchContractEvent({\n address: poolManagerAddress,\n abi: poolManagerAbi,\n eventName: eventType as 'ModifyLiquidity' | 'Swap' | 'Donate',\n onLogs: (logs) => {\n const events: PanopticEvent[] = []\n for (const log of logs) {\n const parsed = parsePoolManagerLog(log as DecodedLog, eventType)\n if (parsed) {\n events.push(parsed)\n }\n }\n if (events.length > 0) {\n onLogs(events)\n }\n },\n onError: onError,\n })\n unwatchFns.push(unwatch)\n } catch (error) {\n onError?.(error instanceof Error ? error : new Error(String(error)))\n }\n }\n }\n\n // Return combined unwatch function\n return () => {\n for (const unwatch of unwatchFns) {\n unwatch()\n }\n }\n}\n\nexport type { DecodedLog }\nexport { parseCollateralLog, parsePoolLog, parsePoolManagerLog, parseRiskEngineLog, parseSfpmLog }\n","/**\n * Resilient event subscription with auto-reconnect for the Panoptic v2 SDK.\n * @module v2/events/subscription\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport {\n collateralTrackerV2Abi,\n panopticPoolV2Abi,\n riskEngineAbi,\n semiFungiblePositionManagerV4Abi,\n} from '../../../generated'\nimport { poolManagerAbi } from '../abis/poolManager'\nimport type { EventSubscription, PanopticEvent, PanopticEventType } from '../types'\nimport type { DecodedLog } from './watchEvents'\nimport {\n parseCollateralLog,\n parsePoolLog,\n parsePoolManagerLog,\n parseRiskEngineLog,\n parseSfpmLog,\n} from './watchEvents'\n\n/**\n * Reconnection strategy configuration.\n */\nexport interface ReconnectConfig {\n /** Maximum reconnection attempts (0n = infinite) */\n maxAttempts: bigint\n /** Initial delay before first retry (ms) */\n initialDelayMs: bigint\n /** Maximum delay between retries (ms) */\n maxDelayMs: bigint\n /** Backoff multiplier */\n backoffMultiplier: bigint\n}\n\n/**\n * Default reconnection configuration.\n */\nexport const DEFAULT_RECONNECT_CONFIG: ReconnectConfig = {\n maxAttempts: 10n,\n initialDelayMs: 1000n,\n maxDelayMs: 30000n,\n backoffMultiplier: 2n,\n}\n\n/**\n * Parameters for creating an event subscription.\n */\nexport interface CreateEventSubscriptionParams {\n /** Public client (must have WebSocket transport) */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** CollateralTracker0 address (optional, for Deposit/Withdraw events) */\n collateralTracker0?: Address\n /** CollateralTracker1 address (optional, for Deposit/Withdraw/ProtocolLossRealized events) */\n collateralTracker1?: Address\n /** RiskEngine address (optional, for BorrowRateUpdated events) */\n riskEngineAddress?: Address\n /** SemiFungiblePositionManager address (optional, for LiquidityChunkUpdated events) */\n sfpmAddress?: Address\n /** v4 PoolManager address (optional, for ModifyLiquidity/Swap/Donate events) */\n poolManagerAddress?: Address\n /** Event types to filter (omit for all events) */\n eventTypes?: PanopticEventType[]\n /** Callback for received events */\n onLogs: (events: PanopticEvent[]) => void\n /** Callback for errors (subscription will auto-reconnect) */\n onError?: (error: Error) => void\n /** Callback for reconnection attempts */\n onReconnect?: (attempt: bigint, nextDelayMs: bigint) => void\n /** Callback when connected */\n onConnected?: () => void\n /** Reconnection strategy configuration */\n reconnect?: Partial<ReconnectConfig>\n}\n\n/**\n * Event subscription handle with additional state.\n */\nexport interface EventSubscriptionHandle extends EventSubscription {\n /** Start watching */\n start: () => void\n /** Stop watching (cleans up, no more reconnects) */\n stop: () => void\n /** Number of reconnection attempts */\n reconnectAttempts: bigint\n /** Last processed block number */\n lastProcessedBlock: bigint\n}\n\n/**\n * Create a resilient event subscription with auto-reconnect and gap filling.\n *\n * Unlike `watchEvents()`, this subscription automatically reconnects on\n * disconnection and fills gaps by fetching missed events.\n *\n * @param params - Subscription parameters\n * @returns Event subscription handle\n *\n * @example\n * ```typescript\n * const subscription = createEventSubscription({\n * client,\n * poolAddress,\n * eventTypes: ['OptionMinted', 'OptionBurnt', 'AccountLiquidated'],\n * onLogs: (events) => {\n * for (const event of events) {\n * console.log(event.type, event)\n * }\n * },\n * onError: (error) => console.error('Subscription error:', error),\n * onReconnect: (attempt, nextDelay) => {\n * console.log(`Reconnecting (attempt ${attempt}, next in ${nextDelay}ms)`)\n * },\n * onConnected: () => console.log('Subscription connected'),\n * })\n *\n * // Start watching\n * subscription.start()\n *\n * // Check state\n * console.log('Connected:', subscription.isConnected())\n * console.log('Reconnect attempts:', subscription.reconnectAttempts)\n * console.log('Last processed block:', subscription.lastProcessedBlock)\n *\n * // Stop (cleans up, no more reconnects)\n * subscription.stop()\n * ```\n */\nexport function createEventSubscription(\n params: CreateEventSubscriptionParams,\n): EventSubscriptionHandle {\n const {\n client,\n poolAddress,\n collateralTracker0,\n collateralTracker1,\n riskEngineAddress,\n sfpmAddress,\n poolManagerAddress,\n eventTypes,\n onLogs,\n onError,\n onReconnect,\n onConnected,\n reconnect: reconnectConfig,\n } = params\n\n const config: ReconnectConfig = {\n ...DEFAULT_RECONNECT_CONFIG,\n ...reconnectConfig,\n }\n\n // State\n let isRunning = false\n let connected = false\n let reconnectAttempts = 0n\n let lastProcessedBlock = 0n\n let lastProcessedLogIndex = -1n\n let currentDelay = config.initialDelayMs\n let unwatchFns: (() => void)[] = []\n let reconnectTimeout: ReturnType<typeof setTimeout> | null = null\n\n const compareEvents = (a: PanopticEvent, b: PanopticEvent): number => {\n if (a.blockNumber !== b.blockNumber) {\n return a.blockNumber < b.blockNumber ? -1 : 1\n }\n if (a.logIndex !== b.logIndex) {\n return a.logIndex < b.logIndex ? -1 : 1\n }\n return 0\n }\n\n const isAfterCursor = (event: PanopticEvent): boolean => {\n if (event.blockNumber > lastProcessedBlock) {\n return true\n }\n if (event.blockNumber < lastProcessedBlock) {\n return false\n }\n return event.logIndex > lastProcessedLogIndex\n }\n\n const advanceCursor = (event: PanopticEvent): void => {\n lastProcessedBlock = event.blockNumber\n lastProcessedLogIndex = event.logIndex\n }\n\n // Pool event types\n const poolEventTypes: PanopticEventType[] = eventTypes\n ? eventTypes.filter((t) =>\n [\n 'OptionMinted',\n 'OptionBurnt',\n 'AccountLiquidated',\n 'ForcedExercised',\n 'PremiumSettled',\n ].includes(t),\n )\n : ['OptionMinted', 'OptionBurnt', 'AccountLiquidated', 'ForcedExercised', 'PremiumSettled']\n\n // Collateral event types\n const collateralEventTypes: PanopticEventType[] = eventTypes\n ? eventTypes.filter((t) => ['Deposit', 'Withdraw', 'ProtocolLossRealized'].includes(t))\n : ['Deposit', 'Withdraw', 'ProtocolLossRealized']\n\n // RiskEngine event types\n const riskEngineEventTypes: PanopticEventType[] = eventTypes\n ? eventTypes.filter((t) => ['BorrowRateUpdated'].includes(t))\n : ['BorrowRateUpdated']\n\n // SFPM event types\n const sfpmEventTypes: PanopticEventType[] = eventTypes\n ? eventTypes.filter((t) => ['LiquidityChunkUpdated'].includes(t))\n : ['LiquidityChunkUpdated']\n\n // PoolManager event types\n const poolManagerEventTypes: PanopticEventType[] = eventTypes\n ? eventTypes.filter((t) => ['ModifyLiquidity', 'Swap', 'Donate'].includes(t))\n : ['ModifyLiquidity', 'Swap', 'Donate']\n\n /**\n * Fetch missed events between lastProcessedBlock and currentBlock.\n */\n async function fillGap(fromBlock: bigint, toBlock: bigint): Promise<void> {\n if (fromBlock >= toBlock) return\n\n const allEvents: PanopticEvent[] = []\n\n // Fetch pool events\n for (const eventType of poolEventTypes) {\n try {\n const logs = await client.getContractEvents({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n eventName: eventType as\n | 'OptionMinted'\n | 'OptionBurnt'\n | 'AccountLiquidated'\n | 'ForcedExercised'\n | 'PremiumSettled',\n fromBlock,\n toBlock,\n })\n for (const log of logs) {\n const parsed = parsePoolLog(log as DecodedLog, eventType)\n if (parsed) {\n allEvents.push(parsed)\n }\n }\n } catch (error) {\n onError?.(error instanceof Error ? error : new Error(`Failed to fetch ${eventType} events`))\n }\n }\n\n // Fetch collateral events\n const collateralTrackers = [collateralTracker0, collateralTracker1].filter(Boolean) as Address[]\n for (const trackerAddress of collateralTrackers) {\n for (const eventType of collateralEventTypes) {\n try {\n const logs = await client.getContractEvents({\n address: trackerAddress,\n abi: collateralTrackerV2Abi,\n eventName: eventType as 'Deposit' | 'Withdraw' | 'ProtocolLossRealized',\n fromBlock,\n toBlock,\n })\n for (const log of logs) {\n const parsed = parseCollateralLog(log as DecodedLog, eventType)\n if (parsed) {\n allEvents.push(parsed)\n }\n }\n } catch (error) {\n onError?.(\n error instanceof Error ? error : new Error(`Failed to fetch ${eventType} events`),\n )\n }\n }\n }\n\n // Fetch RiskEngine events\n if (riskEngineAddress) {\n for (const eventType of riskEngineEventTypes) {\n try {\n const logs = await client.getContractEvents({\n address: riskEngineAddress,\n abi: riskEngineAbi,\n eventName: eventType as 'BorrowRateUpdated',\n fromBlock,\n toBlock,\n })\n for (const log of logs) {\n const parsed = parseRiskEngineLog(log as DecodedLog, eventType)\n if (parsed) {\n allEvents.push(parsed)\n }\n }\n } catch (error) {\n onError?.(\n error instanceof Error ? error : new Error(`Failed to fetch ${eventType} events`),\n )\n }\n }\n }\n\n // Fetch SFPM events\n if (sfpmAddress) {\n for (const eventType of sfpmEventTypes) {\n try {\n const logs = await client.getContractEvents({\n address: sfpmAddress,\n abi: semiFungiblePositionManagerV4Abi,\n eventName: eventType as 'LiquidityChunkUpdated',\n fromBlock,\n toBlock,\n })\n for (const log of logs) {\n const parsed = parseSfpmLog(log as DecodedLog, eventType)\n if (parsed) {\n allEvents.push(parsed)\n }\n }\n } catch (error) {\n onError?.(\n error instanceof Error ? error : new Error(`Failed to fetch ${eventType} events`),\n )\n }\n }\n }\n\n // Fetch PoolManager events\n if (poolManagerAddress) {\n for (const eventType of poolManagerEventTypes) {\n try {\n const logs = await client.getContractEvents({\n address: poolManagerAddress,\n abi: poolManagerAbi,\n eventName: eventType as 'ModifyLiquidity' | 'Swap' | 'Donate',\n fromBlock,\n toBlock,\n })\n for (const log of logs) {\n const parsed = parsePoolManagerLog(log as DecodedLog, eventType)\n if (parsed) {\n allEvents.push(parsed)\n }\n }\n } catch (error) {\n onError?.(\n error instanceof Error ? error : new Error(`Failed to fetch ${eventType} events`),\n )\n }\n }\n }\n\n // Sort by block number and log index, then drop anything at/before cursor.\n const newEvents = allEvents.sort(compareEvents).filter(isAfterCursor)\n\n if (newEvents.length > 0) {\n onLogs(newEvents)\n advanceCursor(newEvents[newEvents.length - 1])\n }\n }\n\n /**\n * Start watching events.\n */\n async function setupWatchers(): Promise<void> {\n // Clean up any existing watchers\n cleanup()\n\n try {\n // Get current block for gap detection\n const currentBlock = await client.getBlockNumber()\n\n // Fill gap if we have a previous position\n if (lastProcessedBlock > 0n && lastProcessedBlock < currentBlock) {\n await fillGap(lastProcessedBlock, currentBlock)\n }\n\n // Set baseline for this subscription start (from \"head\"), unless fillGap\n // already advanced us into this block with a concrete log index.\n if (currentBlock > lastProcessedBlock) {\n lastProcessedBlock = currentBlock\n lastProcessedLogIndex = -1n\n }\n\n const createOnLogsHandler = (\n parseLog: (log: DecodedLog) => PanopticEvent | null,\n ): ((logs: readonly unknown[]) => void) => {\n return (logs) => {\n const events: PanopticEvent[] = []\n for (const log of logs) {\n const parsed = parseLog(log as DecodedLog)\n if (parsed && isAfterCursor(parsed)) {\n events.push(parsed)\n }\n }\n if (events.length > 0) {\n events.sort(compareEvents)\n onLogs(events)\n advanceCursor(events[events.length - 1])\n }\n }\n }\n\n const createPoolOnLogs = (eventType: PanopticEventType) =>\n createOnLogsHandler((log) => parsePoolLog(log, eventType))\n const createCollateralOnLogs = (eventType: PanopticEventType) =>\n createOnLogsHandler((log) => parseCollateralLog(log, eventType))\n const createRiskEngineOnLogs = (eventType: PanopticEventType) =>\n createOnLogsHandler((log) => parseRiskEngineLog(log, eventType))\n const createSfpmOnLogs = (eventType: PanopticEventType) =>\n createOnLogsHandler((log) => parseSfpmLog(log, eventType))\n const createPoolManagerOnLogs = (eventType: PanopticEventType) =>\n createOnLogsHandler((log) => parsePoolManagerLog(log, eventType))\n\n // Watch pool events\n for (const eventType of poolEventTypes) {\n const unwatch = client.watchContractEvent({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n eventName: eventType as\n | 'OptionMinted'\n | 'OptionBurnt'\n | 'AccountLiquidated'\n | 'ForcedExercised'\n | 'PremiumSettled',\n onLogs: createPoolOnLogs(eventType),\n onError: handleError,\n })\n unwatchFns.push(unwatch)\n }\n\n // Watch collateral events\n const collateralTrackers = [collateralTracker0, collateralTracker1].filter(\n Boolean,\n ) as Address[]\n for (const trackerAddress of collateralTrackers) {\n for (const eventType of collateralEventTypes) {\n const unwatch = client.watchContractEvent({\n address: trackerAddress,\n abi: collateralTrackerV2Abi,\n eventName: eventType as 'Deposit' | 'Withdraw' | 'ProtocolLossRealized',\n onLogs: createCollateralOnLogs(eventType),\n onError: handleError,\n })\n unwatchFns.push(unwatch)\n }\n }\n\n // Watch RiskEngine events\n if (riskEngineAddress) {\n for (const eventType of riskEngineEventTypes) {\n const unwatch = client.watchContractEvent({\n address: riskEngineAddress,\n abi: riskEngineAbi,\n eventName: eventType as 'BorrowRateUpdated',\n onLogs: createRiskEngineOnLogs(eventType),\n onError: handleError,\n })\n unwatchFns.push(unwatch)\n }\n }\n\n // Watch SFPM events\n if (sfpmAddress) {\n for (const eventType of sfpmEventTypes) {\n const unwatch = client.watchContractEvent({\n address: sfpmAddress,\n abi: semiFungiblePositionManagerV4Abi,\n eventName: eventType as 'LiquidityChunkUpdated',\n onLogs: createSfpmOnLogs(eventType),\n onError: handleError,\n })\n unwatchFns.push(unwatch)\n }\n }\n\n // Watch PoolManager events\n if (poolManagerAddress) {\n for (const eventType of poolManagerEventTypes) {\n const unwatch = client.watchContractEvent({\n address: poolManagerAddress,\n abi: poolManagerAbi,\n eventName: eventType as 'ModifyLiquidity' | 'Swap' | 'Donate',\n onLogs: createPoolManagerOnLogs(eventType),\n onError: handleError,\n })\n unwatchFns.push(unwatch)\n }\n }\n\n // Mark as connected\n connected = true\n reconnectAttempts = 0n\n currentDelay = config.initialDelayMs\n onConnected?.()\n } catch (error) {\n handleError(error instanceof Error ? error : new Error(String(error)))\n }\n }\n\n /**\n * Clean up watchers.\n */\n function cleanup(): void {\n for (const unwatch of unwatchFns) {\n try {\n unwatch()\n } catch {\n // Ignore cleanup errors\n }\n }\n unwatchFns = []\n connected = false\n }\n\n /**\n * Handle errors and schedule reconnection.\n */\n function handleError(error: Error): void {\n connected = false\n onError?.(error)\n\n if (!isRunning) return\n\n // Reconnect already scheduled; avoid duplicate timers.\n if (reconnectTimeout) return\n\n // Check if we've exceeded max attempts\n if (config.maxAttempts > 0n && reconnectAttempts >= config.maxAttempts) {\n onError?.(new Error(`Max reconnection attempts (${config.maxAttempts}) exceeded`))\n return\n }\n\n // Schedule reconnection\n reconnectAttempts++\n onReconnect?.(reconnectAttempts, currentDelay)\n\n reconnectTimeout = setTimeout(() => {\n reconnectTimeout = null\n if (isRunning) {\n setupWatchers()\n }\n }, Number(currentDelay))\n\n // Increase delay for next attempt (exponential backoff)\n currentDelay = currentDelay * config.backoffMultiplier\n if (currentDelay > config.maxDelayMs) {\n currentDelay = config.maxDelayMs\n }\n }\n\n /**\n * Start the subscription.\n */\n function start(): void {\n if (isRunning) return\n isRunning = true\n setupWatchers()\n }\n\n /**\n * Stop the subscription.\n */\n function stop(): void {\n isRunning = false\n if (reconnectTimeout) {\n clearTimeout(reconnectTimeout)\n }\n reconnectTimeout = null\n cleanup()\n }\n\n return {\n start,\n stop,\n unsubscribe: stop,\n isConnected: () => connected,\n get reconnectAttempts() {\n return reconnectAttempts\n },\n get lastProcessedBlock() {\n return lastProcessedBlock\n },\n }\n}\n","/**\n * HTTP polling-based event fetching for the Panoptic v2 SDK.\n * @module v2/events/poller\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport {\n collateralTrackerV2Abi,\n panopticPoolV2Abi,\n riskEngineAbi,\n semiFungiblePositionManagerV4Abi,\n} from '../../../generated'\nimport { poolManagerAbi } from '../abis/poolManager'\nimport type { PanopticEvent, PanopticEventType } from '../types'\nimport type { DecodedLog } from './watchEvents'\nimport {\n parseCollateralLog,\n parsePoolLog,\n parsePoolManagerLog,\n parseRiskEngineLog,\n parseSfpmLog,\n} from './watchEvents'\n\n/**\n * Event poller handle.\n */\nexport interface EventPoller {\n /** Start polling */\n start: () => void\n /** Stop polling */\n stop: () => void\n /** Check if polling is active */\n isPolling: () => boolean\n /** Get last polled block */\n lastPolledBlock: bigint\n}\n\n/**\n * Parameters for creating an event poller.\n */\nexport interface CreateEventPollerParams {\n /** Public client (works with HTTP transport) */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** CollateralTracker0 address (optional, for Deposit/Withdraw events) */\n collateralTracker0?: Address\n /** CollateralTracker1 address (optional, for Deposit/Withdraw/ProtocolLossRealized events) */\n collateralTracker1?: Address\n /** RiskEngine address (optional, for BorrowRateUpdated events) */\n riskEngineAddress?: Address\n /** SemiFungiblePositionManager address (optional, for LiquidityChunkUpdated events) */\n sfpmAddress?: Address\n /** v4 PoolManager address (optional, for ModifyLiquidity/Swap/Donate events) */\n poolManagerAddress?: Address\n /** Event types to filter (omit for all events) */\n eventTypes?: PanopticEventType[]\n /** Callback for received events */\n onLogs: (events: PanopticEvent[]) => void\n /** Callback for errors */\n onError?: (error: Error) => void\n /** Polling interval in milliseconds (default: 12000 = 1 block on mainnet) */\n intervalMs?: bigint\n /** Maximum blocks to query per poll (default: 1000) */\n maxBlockRange?: bigint\n /** Starting block number (default: current block) */\n fromBlock?: bigint\n}\n\n/**\n * Default polling interval (12 seconds = ~1 mainnet block).\n */\nconst DEFAULT_INTERVAL_MS = 12000n\n\n/**\n * Default maximum block range per poll.\n */\nconst DEFAULT_MAX_BLOCK_RANGE = 1000n\n\n/**\n * Create an HTTP polling-based event fetcher.\n *\n * Use this for environments where WebSocket connections are unreliable or unavailable.\n * It polls `eth_getLogs` at regular intervals to fetch new events.\n *\n * @param params - Poller parameters\n * @returns Event poller handle\n *\n * @example\n * ```typescript\n * const poller = createEventPoller({\n * client,\n * poolAddress,\n * onLogs: (events) => {\n * for (const event of events) {\n * console.log(event.type, event)\n * }\n * },\n * onError: (error) => console.error('Polling error:', error),\n * intervalMs: 12000n, // 12 seconds\n * maxBlockRange: 1000n,\n * })\n *\n * // Start polling\n * poller.start()\n *\n * // Check state\n * console.log('Polling:', poller.isPolling())\n * console.log('Last polled block:', poller.lastPolledBlock)\n *\n * // Stop polling\n * poller.stop()\n * ```\n */\nexport function createEventPoller(params: CreateEventPollerParams): EventPoller {\n const {\n client,\n poolAddress,\n collateralTracker0,\n collateralTracker1,\n riskEngineAddress,\n sfpmAddress,\n poolManagerAddress,\n eventTypes,\n onLogs,\n onError,\n intervalMs = DEFAULT_INTERVAL_MS,\n maxBlockRange = DEFAULT_MAX_BLOCK_RANGE,\n fromBlock,\n } = params\n\n // State\n let isRunning = false\n let lastPolledBlock = fromBlock ?? 0n\n let pollTimeout: ReturnType<typeof setTimeout> | null = null\n\n // Pool event types\n const poolEventTypes: PanopticEventType[] = eventTypes\n ? eventTypes.filter((t) =>\n [\n 'OptionMinted',\n 'OptionBurnt',\n 'AccountLiquidated',\n 'ForcedExercised',\n 'PremiumSettled',\n ].includes(t),\n )\n : ['OptionMinted', 'OptionBurnt', 'AccountLiquidated', 'ForcedExercised', 'PremiumSettled']\n\n // Collateral event types\n const collateralEventTypes: PanopticEventType[] = eventTypes\n ? eventTypes.filter((t) => ['Deposit', 'Withdraw', 'ProtocolLossRealized'].includes(t))\n : ['Deposit', 'Withdraw', 'ProtocolLossRealized']\n\n // RiskEngine event types\n const riskEngineEventTypes: PanopticEventType[] = eventTypes\n ? eventTypes.filter((t) => ['BorrowRateUpdated'].includes(t))\n : ['BorrowRateUpdated']\n\n // SFPM event types\n const sfpmEventTypes: PanopticEventType[] = eventTypes\n ? eventTypes.filter((t) => ['LiquidityChunkUpdated'].includes(t))\n : ['LiquidityChunkUpdated']\n\n // PoolManager event types\n const poolManagerEventTypes: PanopticEventType[] = eventTypes\n ? eventTypes.filter((t) => ['ModifyLiquidity', 'Swap', 'Donate'].includes(t))\n : ['ModifyLiquidity', 'Swap', 'Donate']\n\n /**\n * Fetch events for a block range.\n */\n async function fetchEvents(from: bigint, to: bigint): Promise<PanopticEvent[]> {\n const allEvents: PanopticEvent[] = []\n\n // Fetch pool events\n for (const eventType of poolEventTypes) {\n try {\n const logs = await client.getContractEvents({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n eventName: eventType as\n | 'OptionMinted'\n | 'OptionBurnt'\n | 'AccountLiquidated'\n | 'ForcedExercised'\n | 'PremiumSettled',\n fromBlock: from,\n toBlock: to,\n })\n for (const log of logs) {\n const parsed = parsePoolLog(log as DecodedLog, eventType)\n if (parsed) {\n allEvents.push(parsed)\n }\n }\n } catch (error) {\n onError?.(error instanceof Error ? error : new Error(`Failed to fetch ${eventType} events`))\n }\n }\n\n // Fetch collateral events\n const collateralTrackers = [collateralTracker0, collateralTracker1].filter(Boolean) as Address[]\n for (const trackerAddress of collateralTrackers) {\n for (const eventType of collateralEventTypes) {\n try {\n const logs = await client.getContractEvents({\n address: trackerAddress,\n abi: collateralTrackerV2Abi,\n eventName: eventType as 'Deposit' | 'Withdraw' | 'ProtocolLossRealized',\n fromBlock: from,\n toBlock: to,\n })\n for (const log of logs) {\n const parsed = parseCollateralLog(log as DecodedLog, eventType)\n if (parsed) {\n allEvents.push(parsed)\n }\n }\n } catch (error) {\n onError?.(\n error instanceof Error ? error : new Error(`Failed to fetch ${eventType} events`),\n )\n }\n }\n }\n\n // Fetch RiskEngine events\n if (riskEngineAddress) {\n for (const eventType of riskEngineEventTypes) {\n try {\n const logs = await client.getContractEvents({\n address: riskEngineAddress,\n abi: riskEngineAbi,\n eventName: eventType as 'BorrowRateUpdated',\n fromBlock: from,\n toBlock: to,\n })\n for (const log of logs) {\n const parsed = parseRiskEngineLog(log as DecodedLog, eventType)\n if (parsed) {\n allEvents.push(parsed)\n }\n }\n } catch (error) {\n onError?.(\n error instanceof Error ? error : new Error(`Failed to fetch ${eventType} events`),\n )\n }\n }\n }\n\n // Fetch SFPM events\n if (sfpmAddress) {\n for (const eventType of sfpmEventTypes) {\n try {\n const logs = await client.getContractEvents({\n address: sfpmAddress,\n abi: semiFungiblePositionManagerV4Abi,\n eventName: eventType as 'LiquidityChunkUpdated',\n fromBlock: from,\n toBlock: to,\n })\n for (const log of logs) {\n const parsed = parseSfpmLog(log as DecodedLog, eventType)\n if (parsed) {\n allEvents.push(parsed)\n }\n }\n } catch (error) {\n onError?.(\n error instanceof Error ? error : new Error(`Failed to fetch ${eventType} events`),\n )\n }\n }\n }\n\n // Fetch PoolManager events\n if (poolManagerAddress) {\n for (const eventType of poolManagerEventTypes) {\n try {\n const logs = await client.getContractEvents({\n address: poolManagerAddress,\n abi: poolManagerAbi,\n eventName: eventType as 'ModifyLiquidity' | 'Swap' | 'Donate',\n fromBlock: from,\n toBlock: to,\n })\n for (const log of logs) {\n const parsed = parsePoolManagerLog(log as DecodedLog, eventType)\n if (parsed) {\n allEvents.push(parsed)\n }\n }\n } catch (error) {\n onError?.(\n error instanceof Error ? error : new Error(`Failed to fetch ${eventType} events`),\n )\n }\n }\n }\n\n // Sort by block number and log index\n allEvents.sort((a, b) => {\n if (a.blockNumber !== b.blockNumber) {\n return a.blockNumber < b.blockNumber ? -1 : 1\n }\n return a.logIndex < b.logIndex ? -1 : 1\n })\n\n return allEvents\n }\n\n /**\n * Perform a single poll iteration.\n */\n async function poll(): Promise<void> {\n if (!isRunning) return\n\n try {\n // Get current block\n const currentBlock = await client.getBlockNumber()\n\n // Initialize lastPolledBlock if not set\n if (lastPolledBlock === 0n) {\n lastPolledBlock = currentBlock\n schedulePoll()\n return\n }\n\n // Check if there are new blocks\n if (currentBlock <= lastPolledBlock) {\n schedulePoll()\n return\n }\n\n // Calculate range to query (respect maxBlockRange)\n let toBlock = currentBlock\n const range = toBlock - lastPolledBlock\n if (range > maxBlockRange) {\n toBlock = lastPolledBlock + maxBlockRange\n }\n\n // Fetch events\n const events = await fetchEvents(lastPolledBlock + 1n, toBlock)\n\n // Update last polled block\n lastPolledBlock = toBlock\n\n // Deliver events\n if (events.length > 0) {\n onLogs(events)\n }\n\n // If we didn't catch up to current block, poll again immediately\n if (toBlock < currentBlock && isRunning) {\n // Use setImmediate-like behavior with 0ms timeout\n pollTimeout = setTimeout(poll, 0)\n } else {\n schedulePoll()\n }\n } catch (error) {\n onError?.(error instanceof Error ? error : new Error(String(error)))\n schedulePoll()\n }\n }\n\n /**\n * Schedule next poll.\n */\n function schedulePoll(): void {\n if (!isRunning) return\n pollTimeout = setTimeout(poll, Number(intervalMs))\n }\n\n /**\n * Start polling.\n */\n function start(): void {\n if (isRunning) return\n isRunning = true\n poll()\n }\n\n /**\n * Stop polling.\n */\n function stop(): void {\n isRunning = false\n if (pollTimeout) {\n clearTimeout(pollTimeout)\n pollTimeout = null\n }\n }\n\n return {\n start,\n stop,\n isPolling: () => isRunning,\n get lastPolledBlock() {\n return lastPolledBlock\n },\n }\n}\n","/**\n * Bot utilities for the Panoptic v2 SDK.\n *\n * Assertion functions for validating preconditions before executing operations.\n * These throw typed errors on failure, making bot code cleaner and failures explicit.\n *\n * @module v2/bot\n */\n\nimport { SafeModeError, StaleDataError, UnhealthyPoolError } from '../errors'\nimport type { BlockMeta, Pool, SafeModeState } from '../types'\n\n/**\n * Data with block metadata (anything returned by SDK read functions).\n */\nexport interface DataWithMeta {\n _meta: BlockMeta\n}\n\n/**\n * Assert that data is fresh (not stale).\n *\n * Throws StaleDataError if the data's block timestamp is older than maxAgeSeconds.\n *\n * @param data - Any SDK data with _meta field\n * @param maxAgeSeconds - Maximum allowed age in seconds\n * @param currentTimestamp - Current timestamp (defaults to Date.now() / 1000)\n * @throws StaleDataError if data is stale\n *\n * @example\n * ```typescript\n * const pool = await getPool({ client, poolAddress })\n * assertFresh(pool, 60) // Must be < 60 seconds old\n * ```\n */\nexport function assertFresh(\n data: DataWithMeta,\n maxAgeSeconds: bigint | number,\n currentTimestamp?: bigint | number,\n): void {\n const maxAge = BigInt(maxAgeSeconds)\n const now =\n currentTimestamp !== undefined\n ? BigInt(currentTimestamp)\n : BigInt(Math.floor(Date.now() / 1000))\n const blockTimestamp = data._meta.blockTimestamp\n const age = now - blockTimestamp\n\n if (age > maxAge) {\n throw new StaleDataError(blockTimestamp, now, age)\n }\n}\n\n/**\n * Assert that a pool is healthy.\n *\n * Throws UnhealthyPoolError if the pool health status is not 'active'.\n *\n * @param pool - Pool data from getPool()\n * @throws UnhealthyPoolError if pool is unhealthy (low_liquidity or paused)\n *\n * @example\n * ```typescript\n * const pool = await getPool({ client, poolAddress })\n * assertHealthy(pool) // Throws if pool is paused or has low liquidity\n * ```\n */\nexport function assertHealthy(pool: Pool): void {\n if (pool.healthStatus !== 'active') {\n throw new UnhealthyPoolError(pool.healthStatus)\n }\n}\n\n/**\n * Assert that trading is allowed on a pool.\n *\n * Checks both pool health and safe mode status. Throws appropriate errors\n * if trading is restricted.\n *\n * @param pool - Pool data from getPool()\n * @param safeMode - Optional SafeModeState from getSafeMode()\n * @throws UnhealthyPoolError if pool is unhealthy\n * @throws SafeModeError if pool is in restricted or emergency safe mode\n *\n * @example\n * ```typescript\n * const pool = await getPool({ client, poolAddress })\n * const safeMode = await getSafeMode({ client, poolAddress })\n * assertTradeable(pool, safeMode)\n * ```\n */\nexport function assertTradeable(pool: Pool, safeMode?: SafeModeState): void {\n // First check pool health\n assertHealthy(pool)\n\n // Then check safe mode if provided\n if (safeMode && safeMode.mode !== 'normal') {\n throw new SafeModeError(safeMode.mode, safeMode.reason ?? 'Trading restricted')\n }\n}\n\n/**\n * Assert that minting is allowed.\n *\n * @param safeMode - SafeModeState from getSafeMode()\n * @throws SafeModeError if minting is not allowed\n *\n * @example\n * ```typescript\n * const safeMode = await getSafeMode({ client, poolAddress })\n * assertCanMint(safeMode)\n * await openPosition({ ... })\n * ```\n */\nexport function assertCanMint(safeMode: SafeModeState): void {\n if (!safeMode.canMint) {\n throw new SafeModeError(safeMode.mode, safeMode.reason ?? 'Minting not allowed')\n }\n}\n\n/**\n * Assert that burning is allowed.\n *\n * @param safeMode - SafeModeState from getSafeMode()\n * @throws SafeModeError if burning is not allowed\n */\nexport function assertCanBurn(safeMode: SafeModeState): void {\n if (!safeMode.canBurn) {\n throw new SafeModeError(safeMode.mode, safeMode.reason ?? 'Burning not allowed')\n }\n}\n\n/**\n * Assert that liquidations are allowed.\n *\n * @param safeMode - SafeModeState from getSafeMode()\n * @throws SafeModeError if liquidations are not allowed\n */\nexport function assertCanLiquidate(safeMode: SafeModeState): void {\n if (!safeMode.canLiquidate) {\n throw new SafeModeError(safeMode.mode, safeMode.reason ?? 'Liquidations not allowed')\n }\n}\n\n/**\n * Assert that force exercise is allowed.\n *\n * @param safeMode - SafeModeState from getSafeMode()\n * @throws SafeModeError if force exercise is not allowed\n */\nexport function assertCanForceExercise(safeMode: SafeModeState): void {\n if (!safeMode.canForceExercise) {\n throw new SafeModeError(safeMode.mode, safeMode.reason ?? 'Force exercise not allowed')\n }\n}\n\n// --- RPC Error Classification ---\n\n/**\n * Common retryable RPC error codes.\n */\nconst RETRYABLE_RPC_CODES = new Set([\n -32000, // Server error (generic)\n -32001, // Resource not found (can be transient)\n -32002, // Resource unavailable\n -32003, // Transaction rejected (can retry with new nonce)\n -32005, // Limit exceeded (rate limit)\n -32097, // Rate limit\n -32098, // Request timeout\n -32099, // Internal error\n])\n\n/**\n * Common retryable error message patterns.\n */\nconst RETRYABLE_PATTERNS = [\n /timeout/i,\n /timed out/i,\n /rate limit/i,\n /too many requests/i,\n /429/i,\n /503/i,\n /504/i,\n /502/i,\n /connection refused/i,\n /connection reset/i,\n /network error/i,\n /econnreset/i,\n /econnrefused/i,\n /etimedout/i,\n /socket hang up/i,\n /temporarily unavailable/i,\n /service unavailable/i,\n /server error/i,\n /internal error/i,\n /nonce too low/i, // Can retry with correct nonce\n /replacement transaction underpriced/i, // Can retry with higher gas\n /already known/i, // Transaction already in mempool\n]\n\n/**\n * Check if an error is a retryable RPC error.\n *\n * Returns true for transient errors that may succeed on retry:\n * - Timeouts\n * - Rate limits\n * - Connection errors\n * - Server errors (5xx)\n * - Nonce errors (recoverable with correct nonce)\n *\n * @param error - The error to check\n * @returns True if the error is likely retryable\n *\n * @example\n * ```typescript\n * try {\n * await openPosition({ ... })\n * } catch (error) {\n * if (isRetryableRpcError(error)) {\n * // Wait and retry\n * await sleep(1000)\n * await openPosition({ ... })\n * } else {\n * throw error // Non-retryable, propagate\n * }\n * }\n * ```\n */\nexport function isRetryableRpcError(error: unknown): boolean {\n if (error === null || error === undefined) {\n return false\n }\n\n // Check for RPC error code\n if (typeof error === 'object') {\n const errorObj = error as Record<string, unknown>\n\n // Check code property (standard JSON-RPC error)\n if (typeof errorObj.code === 'number' && RETRYABLE_RPC_CODES.has(errorObj.code)) {\n return true\n }\n\n // Check nested cause\n if (errorObj.cause && isRetryableRpcError(errorObj.cause)) {\n return true\n }\n\n // Check details object (viem style)\n if (errorObj.details && typeof errorObj.details === 'object') {\n const details = errorObj.details as Record<string, unknown>\n if (typeof details.code === 'number' && RETRYABLE_RPC_CODES.has(details.code)) {\n return true\n }\n }\n }\n\n // Check error message patterns\n const message = getErrorMessage(error)\n if (message) {\n for (const pattern of RETRYABLE_PATTERNS) {\n if (pattern.test(message)) {\n return true\n }\n }\n }\n\n return false\n}\n\n/**\n * Extract error message from various error types.\n */\nfunction getErrorMessage(error: unknown): string | undefined {\n if (typeof error === 'string') {\n return error\n }\n if (error instanceof Error) {\n return error.message\n }\n if (typeof error === 'object' && error !== null) {\n const errorObj = error as Record<string, unknown>\n if (typeof errorObj.message === 'string') {\n return errorObj.message\n }\n if (typeof errorObj.shortMessage === 'string') {\n return errorObj.shortMessage\n }\n }\n return undefined\n}\n\n/**\n * Check if an error is a nonce-related error that can be recovered.\n *\n * @param error - The error to check\n * @returns True if this is a nonce error\n */\nexport function isNonceError(error: unknown): boolean {\n const message = getErrorMessage(error)\n if (!message) return false\n\n return (\n /nonce too low/i.test(message) ||\n /nonce too high/i.test(message) ||\n /already known/i.test(message)\n )\n}\n\n/**\n * Check if an error is a gas-related error that can be recovered.\n *\n * @param error - The error to check\n * @returns True if this is a gas error\n */\nexport function isGasError(error: unknown): boolean {\n const message = getErrorMessage(error)\n if (!message) return false\n\n return (\n /replacement transaction underpriced/i.test(message) ||\n /gas too low/i.test(message) ||\n /intrinsic gas too low/i.test(message) ||\n /max fee per gas less than block base fee/i.test(message)\n )\n}\n","{\n \"1\": {\n \"chainId\": 1,\n \"infrastructure\": {\n \"uniswapV3Factory\": \"0x1F98431c8aD98523631AE4a59f267346ea31F984\",\n \"poolManager\": \"0x000000000004444c5dc75cB358380D2e3dE08A90\",\n \"stateView\": \"0x7ffe42c4a5deea5b0fec41c94c136cf115597227\"\n },\n \"hypovault\": {\n \"core\": {\n \"hypoVaultImplementation\": \"0xF16714665955DBd0361D997eFc50fe391D96E8D0\",\n \"factory\": \"0xd5049B2647de57141dE7F65E5124707B99A452A3\",\n \"accountant\": \"0x65aA902AE3135658587FFC36ED51B61c927114e1\",\n \"rolesAuthority\": \"0xb952D345c413Ddb7850173422bAe4968e0330598\",\n \"collateralTrackerDecoderAndSanitizer\": \"0xC87c45d2dbE5acb56013e2591427ECC84Fa251E6\"\n },\n \"vaults\": {\n \"wethPlpVault\": \"0xd4e2c720a760049cc4151bcf61e3a9348db9cd92\",\n \"usdcPlpVault\": \"0x236d0558f06cd60780b232d4Ec4c92d2cb7e4D18\"\n },\n \"managers\": {\n \"wethPlpVaultManager\": \"0xB6Fc48e658C9B1a7dbdFA51A5E153ab60BB2e04d\",\n \"usdcPlpVaultManager\": \"0x2ce65016366ef7320078e0758D58Cf1038bc7C4e\"\n },\n \"turnkeySigners\": {\n \"wethPlpVaultManager\": \"0x8FfA6DAB99f8afc64F61BeF83F0966eD6362f24F\",\n \"usdcPlpVaultManager\": \"0x3c1c79d0cfc316Ba959194c89696a8382d7d283b\"\n }\n },\n \"panoptic\": {\n \"pool\": {\n \"version\": \"v4\",\n \"panopticPool\": \"0x00000000563b70d704f4c6675a5f6ac989fbae13\",\n \"collateralTracker0\": \"0x1e46b0289B7E0F710E2Db8Ab87800dd782D624f7\",\n \"collateralTracker1\": \"0x12bF31955522BAC337D93e1bC0a39F68D8BDa216\"\n },\n \"additionalPools\": {\n \"ethUsdc5bpsV3\": {\n \"version\": \"v3\",\n \"panopticPool\": \"0x00000000009C7B687e833559e34503f64d7ed7c4\",\n \"collateralTracker0\": \"0x3CCdA7d5E841d6543D90BcEc20b36a724C184DE9\",\n \"collateralTracker1\": \"0x69E9f9e44E5F52237493b980dd7306198C64A4E4\"\n }\n },\n \"v2\": {\n \"semiFungiblePositionManagerV4\": \"0x000000000000047534b9E1D528ED997169865a64\",\n \"semiFungiblePositionManagerV3\": \"0x000000000000031d296bBA22f188472157eEb01f\",\n \"builderFactory\": \"0x00000000000008D41F2cd5bF144F61cEB3661F98\",\n \"riskEngine\": \"0x0000000000000e673aECBDB5f5fE5DFAf4a8e9Ac\",\n \"panopticPoolImplementation\": \"0x00000000000010bb6695dAAC60D0515c0A01a948\",\n \"collateralTrackerImplementation\": \"0x0000000000002038055dB8f2B2Fd356598935C51\",\n \"panopticFactoryV4\": \"0x0000000000000c51d0f8cf4bd9adE7191372a625\",\n \"panopticFactoryV3\": \"0x0000000000000aDC9A108591e718F2aee963a2a7\",\n \"panopticHelper\": \"0x0000000000000000000000000000000000000000\",\n \"panopticMath\": \"0x000000000000301F5BC0171C75967b8e78a92b10\",\n \"panopticQuery\": \"0x0000000000000e1aE9c66C1c3B0A547D23389C93\",\n \"interactionHelper\": \"0x00000000000040ae7CD505F4E0e3F34195D8c08C\"\n }\n },\n \"riskEngines\": [\n \"0x000000000000075e29cdaa9cb640a69e148ca7da\",\n \"0x0000000000000fe1e261f66ce2f44def4f5ae0cb\",\n \"0x0000000000000e673aECBDB5f5fE5DFAf4a8e9Ac\"\n ],\n \"markets\": {\n \"ethUsdc30bps\": {\n \"currency0\": \"0x0000000000000000000000000000000000000000\",\n \"currency1\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n \"fee\": 3000,\n \"tickSpacing\": 60,\n \"poolId\": \"0x3C08AE4977F78D\"\n }\n },\n \"subgraphs\": {\n \"hypovault\": \"https://api.goldsky.com/api/public/project_cl9gc21q105380hxuh8ks53k3/subgraphs/hypovault-subgraph-mainnet/prod/gn\",\n \"panoptic\": \"https://api.goldsky.com/api/public/project_cl9gc21q105380hxuh8ks53k3/subgraphs/panoptic-subgraph-mainnet/v2_prod/gn\"\n },\n \"sfpmSwap\": {\n \"version\": \"v3\",\n \"sfpm\": \"0x00000000000005E4693aDc8Ec0f12D686f728198\",\n \"poolAddress\": \"0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640\",\n \"poolId\": \"2824133844976349\",\n \"fee\": 500,\n \"weth\": \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\"\n }\n },\n \"8453\": {\n \"chainId\": 8453,\n \"infrastructure\": {\n \"uniswapV3Factory\": \"0x33128a8fC17869897dcE68Ed026d694621f6FDfD\",\n \"poolManager\": \"0x498581fF718922c3f8e6A244956aF099B2652b2b\",\n \"stateView\": \"0xA3c0c9b65baD0b08107Aa264b0f3dB444b867A71\"\n },\n \"hypovault\": {\n \"core\": {\n \"hypoVaultImplementation\": \"0xec311aE06486ad44Ba782133b502A34aCE0f479E\",\n \"factory\": \"0x9bE53b169a41030f1710A9B82e9eA6413f14D12E\",\n \"accountant\": \"0x345cA3407942f9d175c9eA8B90e83A36F570f852\",\n \"rolesAuthority\": \"0x278D37CaBFFB4B72D2866E30fEFE08aef773E0B6\",\n \"collateralTrackerDecoderAndSanitizer\": \"0x4A290b3EC46cF320421Bb2aaee96d445de31CF0b\"\n },\n \"vaults\": {\n \"wethPlpVault\": \"0x41b7D0515d709A4Fd2CF27f9d141D0c2F8713D04\",\n \"usdcPlpVault\": \"0xb452af299c565D04B05E601efF2840e000C922f1\"\n },\n \"managers\": {\n \"wethPlpVaultManager\": \"0x2a4923456c79E9ebD10F5Bf5305a5C742bBc1D7C\",\n \"usdcPlpVaultManager\": \"0xdd6E2406a044582463CFE9F0C774870eAf4A310B\"\n },\n \"turnkeySigners\": {\n \"wethPlpVaultManager\": \"0x8FfA6DAB99f8afc64F61BeF83F0966eD6362f24F\",\n \"usdcPlpVaultManager\": \"0x3c1c79d0cfc316Ba959194c89696a8382d7d283b\"\n }\n },\n \"panoptic\": {\n \"pool\": {\n \"version\": \"v4\",\n \"panopticPool\": \"0xB50e8bb68f5855DA742f4579274902a20454174a\",\n \"collateralTracker0\": \"0x0d82b189c96EbB1f44A7207e6A9cfB1e490f2869\",\n \"collateralTracker1\": \"0x9ba1082Ab3cb9edEA988697A14BBe543A3dABEd2\"\n },\n \"v2\": {\n \"semiFungiblePositionManagerV4\": \"0x8dcAa08cF298F8b4830FAf56d47930981AdE33af\",\n \"semiFungiblePositionManagerV3\": \"0xFB1c06B491305d618bb8a7a368C6e50c001C153A\",\n \"builderFactory\": \"0x6d26E916a18d522f7DdA2a26d9E1645564ccDcA5\",\n \"riskEngine\": \"0x8bbce8b1eb64118cfe6c1eab0afe13b80ea41481\",\n \"panopticPoolImplementation\": \"0x5BA68a018fF149c38ec52D181Dd24aBabE9a07DB\",\n \"collateralTrackerImplementation\": \"0x34B3a4e4F14f292575ECe3EF67886C4598af459f\",\n \"panopticFactoryV4\": \"0x9ac0317fcd124aff0b5429beb8de17020bc45f9a\",\n \"panopticFactoryV3\": \"0x687f616d68c483a7223e6922f59aef7452e26c1d\",\n \"panopticHelper\": \"0x0000000000000000000000000000000000000000\",\n \"panopticMath\": \"0x6d21699192f5aF112C87e53b32ff846782afF407\",\n \"panopticQuery\": \"0xd2586E1bbdd1169F597F3A370117EdF7372A7350\",\n \"interactionHelper\": \"0x643d8DD5372FD6c71f8fAbCce4Eb8857704F3E15\"\n }\n },\n \"riskEngines\": [\n \"0x8bbce8b1eb64118cfe6c1eab0afe13b80ea41481\"\n ],\n \"markets\": {\n \"ethUsdc5bps\": {\n \"currency0\": \"0x0000000000000000000000000000000000000000\",\n \"currency1\": \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n \"fee\": 500,\n \"tickSpacing\": 10,\n \"poolId\": \"0x96d4b53a38337a5733179751781178a2613306063c511b78cd02684739288c0a\"\n }\n },\n \"subgraphs\": {\n \"hypovault\": \"https://api.goldsky.com/api/public/project_cl9gc21q105380hxuh8ks53k3/subgraphs/hypovault-subgraph-base/prod/gn\",\n \"panoptic\": \"https://api.goldsky.com/api/public/project_cl9gc21q105380hxuh8ks53k3/subgraphs/panoptic-subgraph-base/v2_prod/gn\"\n }\n },\n \"11155111\": {\n \"chainId\": 11155111,\n \"infrastructure\": {\n \"uniswapV3Factory\": \"0x0227628f3F023bb0B980b67D528571c95c6DaC1c\",\n \"poolManager\": \"0xE03A1074c86CFeDd5C142C4F04F1a1536e203543\",\n \"stateView\": \"0xE1Dd9c3fA50EDB962E442f60DfBc432e24537E4C\"\n },\n \"hypovault\": {\n \"core\": {\n \"hypoVaultImplementation\": \"0xC5b415Db4087228Af817893769DC3a205160160B\",\n \"factory\": \"0x363a9d605ca45cBfF3b597350DeADb53cdC292c7\",\n \"accountant\": \"0x25BBef1DF262c24aa1AACD1F7eCeEcc1a7AD08ab\",\n \"rolesAuthority\": \"0x673BfafB4e2712215B422347c1571421B83E8A3d\",\n \"collateralTrackerDecoderAndSanitizer\": \"0xb899BE50BAF25BBB3A3ca3403256B3c703E5AB5d\"\n },\n \"vaults\": {\n \"wethPlpVault\": \"0xD58C4F9AEe5bBfcf28dC9a8d3D57b323fA6521b1\",\n \"usdcPlpVault\": \"0xdd7a8d6c6975488e801129bC84302d74e2361208\"\n },\n \"managers\": {\n \"wethPlpVaultManager\": \"0x95eC124FAAB70D7aE147c3BE0336E01a828AE2d5\",\n \"usdcPlpVaultManager\": \"0xFB5aa3e0b46F3859D90B14b52ffd287013b5Ec53\"\n },\n \"turnkeySigners\": {\n \"wethPlpVaultManager\": \"0x8FfA6DAB99f8afc64F61BeF83F0966eD6362f24F\",\n \"usdcPlpVaultManager\": \"0x3c1c79d0cfc316Ba959194c89696a8382d7d283b\"\n }\n },\n \"panoptic\": {\n \"pool\": {\n \"version\": \"v4\",\n \"panopticPool\": \"0x872b98C46b2062F663BEb2CC9D4cE046Da2a2918\",\n \"collateralTracker0\": \"0x09a60b78d06a03e5148faedd3bfee6f58b22012f\",\n \"collateralTracker1\": \"0x7365664c8101ff7e9422ae2b203822253c31e69c\"\n },\n \"v2\": {\n \"semiFungiblePositionManagerV3\": \"0x9DaD2C40107Db4B29a5450401BB7A28e6eA00e43\",\n \"semiFungiblePositionManagerV4\": \"0xD2615995A71644E122cC2FD7FeC2392b971220DE\",\n \"builderFactory\": \"0x55f3D2d9D065AA5Fcc11D94c55a6085849e8b6C3\",\n \"riskEngine\": \"0x1376aF5ca426B6B9fad6a712c21f6Cf58a94b93c\",\n \"panopticPoolImplementation\": \"0x969235B5830f13b58BB699305d9c70A8Cd3BD97C\",\n \"collateralTrackerImplementation\": \"0xafcd5F651Ae0403Ff668bb2dAc38BEa907a35Dba\",\n \"panopticFactoryV3\": \"0xd9FFCa53C0A6155001Ce8cbcAEfe89DB204690F1\",\n \"panopticFactoryV4\": \"0x8FCBb59b05779818D9BAD2686cc44B705603ce03\",\n \"panopticHelper\": \"0xfFEbB3A4ab793cB244209d4dA0Cb3e6B07133bd0\",\n \"panopticMath\": \"0x6d21699192f5aF112C87e53b32ff846782afF407\",\n \"panopticQuery\": \"0x74057945467Fb4eAE9193B46A60ae66a53f06A5b\",\n \"interactionHelper\": \"0x643d8DD5372FD6c71f8fAbCce4Eb8857704F3E15\"\n }\n },\n \"riskEngines\": [\n \"0x1376aF5ca426B6B9fad6a712c21f6Cf58a94b93c\"\n ],\n \"markets\": {\n \"ethUsdc5bps\": {\n \"currency0\": \"0x0000000000000000000000000000000000000000\",\n \"currency1\": \"0xFFFeD8254566B7F800f6D8CDb843ec75AE49B07A\",\n \"fee\": 500,\n \"tickSpacing\": 10,\n \"poolId\": \"0xba6673bcb27568a73a93dd23b20c8174fa16193cd90905be859144e8f13097a5\"\n }\n },\n \"subgraphs\": {\n \"hypovault\": \"https://api.goldsky.com/api/public/project_cl9gc21q105380hxuh8ks53k3/subgraphs/hypovault-subgraph-sepolia/prod/gn\",\n \"panoptic\": \"https://api.goldsky.com/api/public/project_cl9gc21q105380hxuh8ks53k3/subgraphs/panoptic-subgraph-sepolia/v2_prod/gn\"\n }\n }\n}\n","import chainDeploymentsData from './chainDeployments.data.json' with { type: 'json' }\n\nexport const MAINNET_CHAIN_ID = 1\nexport const SEPOLIA_CHAIN_ID = 11155111\nexport const BASE_CHAIN_ID = 8453\n\nexport const CHAIN_DEPLOYMENTS = chainDeploymentsData\n\nexport function getChainDeployment(chainId) {\n return CHAIN_DEPLOYMENTS[chainId]\n}\n\nexport function requireChainDeployment(chainId) {\n const deployment = getChainDeployment(chainId)\n if (deployment === undefined) {\n throw new Error(`Unsupported chain deployment for chainId ${chainId}`)\n }\n return deployment\n}\n\nexport function isSupportedChain(chainId) {\n return getChainDeployment(chainId) !== undefined\n}\n\nexport function getEthUsdcMarket(deployment) {\n const market = deployment.markets.ethUsdc5bps ?? deployment.markets.ethUsdc30bps\n if (market === undefined) {\n throw new Error(`Missing ETH/USDC market for chainId ${deployment.chainId}`)\n }\n return market\n}\n\n\nexport const MAINNET_DEPLOYMENT = CHAIN_DEPLOYMENTS[MAINNET_CHAIN_ID]\nexport const MAINNET_ETH_USDC_5BPS_V3_PANOPTIC_POOL_ADDRESSES =\n MAINNET_DEPLOYMENT.panoptic.additionalPools?.ethUsdc5bpsV3\nexport const MAINNET_PANOPTIC_V2_ADDRESSES = MAINNET_DEPLOYMENT.panoptic.v2\nexport const SEPOLIA_DEPLOYMENT = CHAIN_DEPLOYMENTS[SEPOLIA_CHAIN_ID]\nexport const SEPOLIA_HYPOVAULT_CORE_ADDRESSES = SEPOLIA_DEPLOYMENT.hypovault.core\nexport const SEPOLIA_HYPOVAULT_ADDRESSES = SEPOLIA_DEPLOYMENT.hypovault.vaults\nexport const SEPOLIA_HYPOVAULT_MANAGER_ADDRESSES = SEPOLIA_DEPLOYMENT.hypovault.managers\nexport const SEPOLIA_HYPOVAULT_MANAGER_TURNKEY_SIGNERS = SEPOLIA_DEPLOYMENT.hypovault.turnkeySigners\nexport const SEPOLIA_PANOPTIC_POOL_ADDRESSES = SEPOLIA_DEPLOYMENT.panoptic.pool\nexport const SEPOLIA_PANOPTIC_V2_ADDRESSES = SEPOLIA_DEPLOYMENT.panoptic.v2\nexport const BASE_DEPLOYMENT = CHAIN_DEPLOYMENTS[BASE_CHAIN_ID]\nexport const BASE_HYPOVAULT_CORE_ADDRESSES = BASE_DEPLOYMENT.hypovault.core\nexport const BASE_HYPOVAULT_ADDRESSES = BASE_DEPLOYMENT.hypovault.vaults\nexport const BASE_HYPOVAULT_MANAGER_ADDRESSES = BASE_DEPLOYMENT.hypovault.managers\nexport const BASE_HYPOVAULT_MANAGER_TURNKEY_SIGNERS = BASE_DEPLOYMENT.hypovault.turnkeySigners\nexport const BASE_PANOPTIC_POOL_ADDRESSES = BASE_DEPLOYMENT.panoptic.pool\nexport const BASE_PANOPTIC_V2_ADDRESSES = BASE_DEPLOYMENT.panoptic.v2\nexport const BASE_ETH_USDC_5BPS_MARKET = getEthUsdcMarket(BASE_DEPLOYMENT)\nexport const SEPOLIA_ETH_USDC_5BPS_MARKET = getEthUsdcMarket(SEPOLIA_DEPLOYMENT)\n\nexport const MAINNET_RISK_ENGINES = MAINNET_DEPLOYMENT.riskEngines\nexport const BASE_RISK_ENGINES = BASE_DEPLOYMENT.riskEngines\nexport const SEPOLIA_RISK_ENGINES = SEPOLIA_DEPLOYMENT.riskEngines\n","import {\n BASE_CHAIN_ID,\n MAINNET_CHAIN_ID,\n requireChainDeployment,\n SEPOLIA_CHAIN_ID,\n} from './chainDeployments.js'\n\nconst mainnetDeployment = requireChainDeployment(MAINNET_CHAIN_ID)\nconst mainnetVaults = mainnetDeployment.hypovault.vaults\nconst legacyMainnetVaults = {\n wethPlpVault: '0x779a2aa634A004b3a3f3b322083744869BBC6D66',\n usdcPlpVault: '0x963Fe9c93bc353602656ee4051A75114bA74d6c5',\n}\nconst sepoliaDeployment = requireChainDeployment(SEPOLIA_CHAIN_ID)\nconst sepoliaVaults = sepoliaDeployment.hypovault.vaults\nconst baseDeployment = requireChainDeployment(BASE_CHAIN_ID)\nconst baseVaults = baseDeployment.hypovault.vaults\n\nexport const VAULT_DISPLAY_NAMES_PER_CHAIN = {\n [MAINNET_CHAIN_ID]: {\n [mainnetVaults.wethPlpVault.toLowerCase()]: 'PLP Vault',\n [mainnetVaults.usdcPlpVault.toLowerCase()]: 'Unicorn Vault',\n [legacyMainnetVaults.wethPlpVault.toLowerCase()]: 'PLP Vault',\n [legacyMainnetVaults.usdcPlpVault.toLowerCase()]: 'Unicorn Vault',\n },\n [BASE_CHAIN_ID]: {\n [baseVaults.wethPlpVault.toLowerCase()]: 'PLP Vault',\n [baseVaults.usdcPlpVault.toLowerCase()]: 'Unicorn Vault',\n },\n [SEPOLIA_CHAIN_ID]: {\n [sepoliaVaults.wethPlpVault.toLowerCase()]: 'PLP Vault',\n [sepoliaVaults.usdcPlpVault.toLowerCase()]: 'Unicorn Vault',\n },\n}\n\nexport const VAULT_DISPLAY_NAME_RESOLVERS_PER_CHAIN = {\n [MAINNET_CHAIN_ID]: {\n [mainnetVaults.wethPlpVault.toLowerCase()]: () => 'PLP Vault',\n [mainnetVaults.usdcPlpVault.toLowerCase()]: () => 'Unicorn Vault',\n [legacyMainnetVaults.wethPlpVault.toLowerCase()]: () => 'PLP Vault',\n [legacyMainnetVaults.usdcPlpVault.toLowerCase()]: () => 'Unicorn Vault',\n },\n [BASE_CHAIN_ID]: {\n [baseVaults.wethPlpVault.toLowerCase()]: () => 'PLP Vault',\n [baseVaults.usdcPlpVault.toLowerCase()]: () => 'Unicorn Vault',\n },\n [SEPOLIA_CHAIN_ID]: {\n [sepoliaVaults.wethPlpVault.toLowerCase()]: () => 'PLP Vault',\n [sepoliaVaults.usdcPlpVault.toLowerCase()]: () => 'Unicorn Vault',\n },\n}\n\nexport function resolveVaultDisplayName({ chainId, vaultAddress, underlyingSymbol, fallbackName }) {\n const vaultAddressLower = vaultAddress.toLowerCase()\n const resolver = VAULT_DISPLAY_NAME_RESOLVERS_PER_CHAIN[chainId]?.[vaultAddressLower]\n if (resolver !== undefined) {\n return resolver({\n chainId,\n vaultAddress: vaultAddressLower,\n underlyingSymbol,\n fallbackName,\n })\n }\n\n const staticName = VAULT_DISPLAY_NAMES_PER_CHAIN[chainId]?.[vaultAddressLower]\n if (staticName !== undefined) {\n return staticName\n }\n\n if (fallbackName !== undefined && fallbackName !== null) {\n return fallbackName\n }\n\n return 'Vault'\n}\n"],"mappings":"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AC3D;GAAE,MAAM;GAAW,cAAc;GAAQ,MAAM;EAAQ,CACxD;EACD,MAAM;EACN,SAAS,CAAE;EACX,iBAAiB;CAClB;CACD;EACE,MAAM;EACN,QAAQ,CAAC;GAAE,MAAM;GAAI,cAAc;GAA2B,MAAM;EAAW,CAAC;EAChF,MAAM;EACN,SAAS,CAAC;GAAE,MAAM;GAAI,cAAc;GAAW,MAAM;EAAW,CAAC;EACjE,iBAAiB;CAClB;CACD;EACE,MAAM;EACN,WAAW;EACX,QAAQ,CACN;GACE,MAAM;GACN,cAAc;GACd,MAAM;GACN,SAAS;EACV,CACF;EACD,MAAM;CACP;CACD;EACE,MAAM;EACN,WAAW;EACX,QAAQ,CACN;GACE,MAAM;GACN,cAAc;GACd,MAAM;GACN,SAAS;EACV,CACF;EACD,MAAM;CACP;CACD;EACE,MAAM;EACN,WAAW;EACX,QAAQ,CACN;GACE,MAAM;GACN,cAAc;GACd,MAAM;GACN,SAAS;EACV,GACD;GACE,MAAM;GACN,cAAc;GACd,MAAM;GACN,SAAS;EACV,CACF;EACD,MAAM;CACP;CACD;EACE,MAAM;EACN,WAAW;EACX,QAAQ,CACN;GACE,MAAM;GACN,cAAc;GACd,MAAM;GACN,SAAS;EACV,GACD;GACE,MAAM;GACN,cAAc;GACd,MAAM;GACN,SAAS;EACV,CACF;EACD,MAAM;CACP;CACD;EACE,MAAM;EACN,WAAW;EACX,QAAQ,CACN;GACE,MAAM;GACN,cAAc;GACd,MAAM;GACN,SAAS;EACV,CACF;EACD,MAAM;CACP;CACD;EACE,MAAM;EACN,WAAW;EACX,QAAQ;GACN;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;EACF;EACD,MAAM;CACP;CACD;EACE,MAAM;EACN,WAAW;EACX,QAAQ,CACN;GACE,MAAM;GACN,cAAc;GACd,MAAM;GACN,SAAS;EACV,CACF;EACD,MAAM;CACP;CACD;EACE,MAAM;EACN,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IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;EACF;EACD,MAAM;CACP;CACD;EACE,MAAM;EACN,WAAW;EACX,QAAQ;GACN;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;EACF;EACD,MAAM;CACP;CACD;EACE,MAAM;EACN,WAAW;EACX,QAAQ;GACN;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;EACF;EACD,MAAM;CACP;CACD;EACE,MAAM;EACN,WAAW;EACX,QAAQ;GACN;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;EACF;EACD,MAAM;CACP;CACD;EACE,MAAM;EACN,WAAW;EACX,QAAQ;GACN;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IAAE,MAAM;IAAQ,cAAc;IAAW,MAAM;IAAW,SAAS;GAAM;GACzE;IAAE,MAAM;IAAM,cAAc;IAAW,MAAM;IAAW,SAAS;GAAM;GACvE;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;EACF;EACD,MAAM;CACP;CACD;EACE,MAAM;EACN,WAAW;EACX,QAAQ;GACN;IACE,MAAM;IACN,cAAc;IAC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GACV;EACF;EACD,MAAM;CACP;CACD;EACE,MAAM;EACN,WAAW;EACX,QAAQ;GACN;IAAE,MAAM;IAAQ,cAAc;IAAU,MAAM;IAAW,SAAS;GAAM;GACxE;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;EACF;EACD,MAAM;CACP;CACD;EACE,MAAM;EACN,WAAW;EACX,QAAQ;GACN;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;EACF;EACD,MAAM;CACP;CACD;EACE,MAAM;EACN,WAAW;EACX,QAAQ;GACN;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;EACF;EACD,MAAM;CACP;CACD;EACE,MAAM;EACN,WAAW;EACX,QAAQ;GACN;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IAAE,MAAM;IAAQ,cAAc;IAAW,MAAM;IAAW,SAAS;GAAM;GACzE;IAAE,MAAM;IAAM,cAAc;IAAW,MAAM;IAAW,SAAS;GAAM;GACvE;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;EACF;EACD,MAAM;CACP;CACD;EACE,MAAM;EACN,WAAW;EACX,QAAQ;GACN;IACE,MAAM;IACN,cAAc;IACd,MAAM;IACN,SAAS;GACV;GACD;IAAE,MAAM;IAAQ,cAAc;IAAW,MAAM;IAAW,SAAS;GAAM;GACzE;IAAE,MAAM;IAAM,cAAc;IAAW,MAAM;IAAW,SAAS;GAAM;GACvE;IAAE,MAAM;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M;EACN,MAAM;EACN,QAAQ,CAAE;CACX;AACF;;;;ACrSD,MAAa,gBAAgB;CAC3B;EACE,QAAQ,CACN;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,GACD;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,YAAY;IACV;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;IACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;IACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;GACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS,CACP;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,YAAY;IACV;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;IACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;IACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;IACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;GACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS,CACP;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS;GACP;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP;GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP;GACD;IACE,YAAY,CACV;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP,GACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP,CACF;IACD,cAAc;IACd,MAAM;IACN,MAAM;GACP;EACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,GACD;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS,CACP;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,GACD;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS;GACP;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP;GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP;GACD;IACE,YAAY,CACV;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP,GACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP,CACF;IACD,cAAc;IACd,MAAM;IACN,MAAM;GACP;E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"}