@panoptic-eng/sdk 1.0.3 → 1.0.5

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.
@@ -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","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","startBlock: bigint","endBlock: bigint","points: number","solvent: bigint","numberOfTicks: bigint","cause?: Error","tokenAddress: Address","assetsRequested: bigint","assetBalance: bigint","parameterType: bigint","currentTick: bigint","token: Address","from: Address","amount: bigint","balance: bigint","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","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: ResolveBlockNumbersParams","blockNumber: bigint","targetTimestamp: number","low: bigint","high: bigint","params: GetPanopticPoolAddressParams","params: GetFactoryTokenURIParams","params: GetFactoryOwnerOfParams","params: MinePoolAddressParams","params: GetFactoryConstructMetadataParams","params: SimulateDeployNewPoolParams","params: GetAccountPremiaParams","_meta","params: GetPositionsWithPremiaParams","positions: PositionWithPremia[]","legs: TokenIdLeg[]","multicallAbi","params: SimulateWithTokenFlowParams","data: Hex","params: RecoverSnapshotParams","params: RecoverSnapshotFromTxParams","input: `0x${string}`","params: GetTrackedPositionIdsParams","tokenId: bigint","params: GetOpenPositionIdsParams","snapshot: SnapshotRecoveryResult | null","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}","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}","tickLimits: readonly [number, number, number]","tickLimits","params: GetRequiredCreditForITMParams","params: GetMaxWithdrawableParams","params: {\n client: PublicClient\n collateralTrackerAddress: Address\n account: Address\n assets: bigint\n positionIdList: bigint[]\n usePremiaAsCollateral: boolean\n}","client: PublicClient","poolAddress: Address","tokenIndex: 0 | 1","providedAddress?: Address","params: ERC4626PreviewParams","params: GetSafeModeParams","params: GetPortfolioValueParams","params: CheckCollateralAcrossTicksParams","MIN_TICK","MAX_TICK","dataPoints: CollateralDataPoint[]","params: OptimizeTokenIdRiskPartnersParams","effectiveTick: bigint","params: GetPoolLiquiditiesParams","TEN","formatRatio","numerator: bigint","denominator: bigint","precision: bigint","bps: bigint","util: bigint","percent: string","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","params: GetMarginBufferParams","liquidationDistance: bigint | null","strike: bigint","encodedStrike: bigint","legIndex: bigint","address: Address","tickSpacing: bigint","vegoid: bigint","bytes: number[]","poolIdHex: Hex","tokenId: bigint","decodeTickSpacing","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","expectedPoolId: bigint","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","ZERO_RESULT: Omit<AccountBuyingPower, '_meta'>","params: GetAccountBuyingPowerParams","checkCollateralError: unknown","getOracleTicksError: unknown","params: MulticallReadParams<TContracts>","results: MulticallResult<unknown>[]","params: SimulateOpenPositionParams","tickLimits: readonly [number, number, number]","tickLimits","data: OpenPositionSimulation","params: GetOpenPositionPreviewParams","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: 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][]","result: { status: string; result?: unknown }","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","data: DataWithMeta","maxAgeSeconds: bigint | number","currentTimestamp?: bigint | number","pool: Pool","safeMode?: SafeModeState","safeMode: SafeModeState","error: unknown","params: EventReconstructionParams","mintEvents: MintEvent[]","burnEvents: BurnEvent[]","mint","openPositions: bigint[]","closedPositions: bigint[]","client: PublicClient","poolAddress: Address","foundBlock: bigint | null","params: SyncPositionsParams","positionIds: bigint[]","fromBlock: bigint","finalBlock","poolMetaKey","existingPoolMeta","positionsKey","endTime","event: SyncEvent","storedData: StoredPositionData","params: {\n client: PublicClient\n poolAddress: Address\n account: Address\n fromBlock?: bigint\n toBlock: bigint\n}","client: PublicClient","poolAddress: Address","poolMetaKey: string","storage: StorageAdapter","poolMeta: StoredPoolMeta","fn: () => Promise<T>","lastError: unknown","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","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","scope?: string","client: unknown","storage: unknown","atTick?: bigint","chainId: bigint","poolAddress: Address","tokenId: bigint","account: Address","atTick: bigint","collateralTrackerAddress: Address","positionIdList: bigint[]","totalAssets: bigint","token: Address","owner: Address","spender: Address","tracker: Address","operation: string","amount: bigint","poolAddress: string","timestampsHash: string","rangeHash: string","poolAddress: Address","options?: QueryOptions","tokenIndex: 0 | 1","params: { queryAddress: Address; startTick: bigint; nTicks: bigint }","params: { sfpmAddress: Address }","owner: Address","tokenId: bigint","tokenIds: bigint[]","owner?: Address","account?: Address","queryAddress: Address","options?: QueryOptions & { atTick?: bigint; includePendingPremium?: boolean }","options?: QueryOptions & { atTick?: bigint }","amount: bigint","positionSize: bigint","options?: QueryOptions & {\n existingPositionIds?: bigint[]\n swapAtMint?: boolean\n precisionPct?: number\n }","atTick?: bigint","collateralTrackerAddress: Address","positionIdList: bigint[]","totalAssets: bigint","options?: QueryOptions & { client?: PublicClient }","account: Address | undefined","existingPositionIds: bigint[]","tickLimitLow: bigint","tickLimitHigh: bigint","options?: QueryOptions & {\n spreadLimit?: bigint\n swapAtMint?: boolean\n usePremiaAsCollateral?: boolean\n }","params?: OmitFactoryClient<GetPanopticPoolAddressParams>","params?: OmitFactoryClient<GetFactoryTokenURIParams>","params?: OmitFactoryClient<GetFactoryOwnerOfParams>","params: OmitMineClient<MinePoolAddressParams>","params?: OmitFactoryClient<GetFactoryConstructMetadataParams>","params?: OmitMineClient<SimulateDeployNewPoolParams>","timeRange: PriceHistoryTimeRange","client: PublicClient","poolConfig: PoolVersionConfig","panopticPoolAddress: Address","account: Address","legs: StreamiaLeg[]","options?: QueryOptions & {\n includeUniswapFees?: boolean\n settledEvents?: Array<{ blockNumber: bigint; settled0: bigint; settled1: bigint }>\n }","panopticPoolAddress: Address | undefined","token0Decimals: bigint","token1Decimals: bigint","nativeIsToken0: boolean","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","storage: StorageAdapter","chainId: bigint","positionIds: bigint[]","params: OpenPositionParams","tickLimits: readonly [number, number, number]","tickLimits","params: ClosePositionParams","params: RollPositionParams","closeLimits: readonly [number, number, number]","openLimits: readonly [number, number, number]","params: DispatchParams","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: MutationEffectParams","keys: (readonly string[])[]","chainId: bigint","token: Address","owner: Address","spender: Address","params: Pick<MutationEffectParams, 'chainId' | 'poolAddress'>","inputs: WalletInputs","queryClient: QueryClient","keysToInvalidate: readonly (readonly string[])[]","params: OmitInjected<ApproveParams>","poolAddress: Address","params: OmitInjectedWithPool<ApprovePoolParams>","params: OmitInjected<DepositParams>","params: OmitInjected<WithdrawParams>","params: OmitInjected<MintParams>","params: OmitInjected<RedeemParams>","params: OmitInjected<WithdrawWithPositionsParams>","params: OmitInjectedWithPool<OpenPositionParams>","params: OmitInjectedWithPool<ClosePositionParams>","params: OmitInjectedWithPool<RollPositionParams>","params: OmitInjectedWithPool<LiquidateParams>","params: OmitInjectedWithPool<ForceExerciseParams>","params: OmitInjectedWithPool<SettleParams>","params?: OmitInjectedWithPool<PokeOracleParams>","params: OmitInjectedWithPool<DispatchParams>","params: OmitInjected<DeployNewPoolParams>","params: SimulateClosePositionParams","tickLimits: readonly [number, number, number]","tickLimits","data: ClosePositionSimulation","params: SimulateDispatchParams","tokenFlow: TokenFlow","data: DispatchSimulation","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","params: SimulateSFPMParams","poolAddress: Address","params?: OmitClientAndPool<SimulateOpenPositionParams>","params?: OmitClientAndPool<SimulateClosePositionParams>","params?: OmitClient<SimulateDepositParams>","params?: OmitClient<SimulateWithdrawParams>","params?: OmitClientAndPool<SimulateLiquidateParams>","params?: OmitClientAndPool<SimulateForceExerciseParams>","params?: OmitClientAndPool<SimulateSettleParams>","params?: OmitClientAndPool<SimulateDispatchParams>","params?: OmitClient<SimulateSFPMParams>","poolAddress: Address","params?: { fromBlock?: bigint; toBlock?: bigint }","position: PendingPosition","tokenId: bigint","txHash: Hash","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[]","poolAddress: Address","eventTypes: PanopticEventType[] | undefined","onEvent: (events: PanopticEvent[]) => void","options?: {\n enabled?: boolean\n collateralTracker0?: Address\n collateralTracker1?: Address\n riskEngineAddress?: Address\n sfpmAddress?: Address\n poolManagerAddress?: Address\n onError?: (error: Error) => void\n }","options?: {\n enabled?: boolean\n collateralTracker0?: Address\n collateralTracker1?: Address\n riskEngineAddress?: Address\n sfpmAddress?: Address\n poolManagerAddress?: Address\n onError?: (error: Error) => void\n onReconnect?: (attempt: bigint, nextDelayMs: bigint) => void\n onConnected?: () => void\n }","handle: EventSubscriptionHandle","options?: {\n enabled?: boolean\n intervalMs?: bigint\n collateralTracker0?: Address\n collateralTracker1?: Address\n riskEngineAddress?: Address\n sfpmAddress?: Address\n poolManagerAddress?: Address\n onError?: (error: Error) => void\n }","poller: EventPoller"],"sources":["../../../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/errors/contract.ts","../../../src/panoptic/v2/errors/errorsAbi.ts","../../../src/panoptic/v2/errors/parser.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/blocksByTimestamp.ts","../../../src/panoptic/v2/reads/factory.ts","../../../src/panoptic/v2/reads/premia.ts","../../../src/panoptic/v2/simulations/tokenFlow.ts","../../../src/panoptic/v2/sync/snapshotRecovery.ts","../../../src/panoptic/v2/sync/getTrackedPositionIds.ts","../../../src/panoptic/v2/reads/collateralEstimate.ts","../../../src/panoptic/v2/reads/erc4626.ts","../../../src/panoptic/v2/reads/safeMode.ts","../../../src/panoptic/v2/reads/queryUtils.ts","../../../src/panoptic/v2/reads/liquidity.ts","../../../src/panoptic/v2/formatters/percentage.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/tokenId/constants.ts","../../../src/panoptic/v2/tokenId/encoding.ts","../../../src/panoptic/v2/tokenId/builder.ts","../../../src/panoptic/v2/tokenId/decode.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/clients/multicall.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/abis/stateView.ts","../../../src/panoptic/v2/abis/uniswapV3Pool.ts","../../../src/panoptic/v2/reads/uniswapFeeHistory.ts","../../../src/panoptic/v2/reads/streamiaHistory.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/bot/index.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/react/cacheScopes.ts","../../../src/panoptic/v2/react/provider.tsx","../../../src/panoptic/v2/react/queryKeys.ts","../../../src/panoptic/v2/react/hooks/reads.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/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/react/mutationEffects.ts","../../../src/panoptic/v2/react/hooks/writes.ts","../../../src/panoptic/v2/simulations/simulateClosePosition.ts","../../../src/panoptic/v2/simulations/simulateDispatch.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/react/hooks/simulations.ts","../../../src/panoptic/v2/react/hooks/sync.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/react/hooks/events.ts"],"sourcesContent":["/**\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 { 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// 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 * 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","/**\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 * 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 { collateralTrackerAbi, panopticPoolAbi, 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 ...panopticPoolAbi,\n ...collateralTrackerAbi,\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","/**\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 * 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 * Factory read functions for the Panoptic v2 SDK.\n *\n * Reads from the PanopticFactory contract (V2 only).\n *\n * @module v2/reads/factory\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { panopticFactoryAbi } from '../../../generated'\nimport type { PoolKey } from '../types'\n\n/**\n * Parameters for getPanopticPoolAddress.\n */\nexport interface GetPanopticPoolAddressParams {\n /** Public client */\n client: PublicClient\n /** PanopticFactory address */\n factoryAddress: Address\n /** V4 pool key */\n poolKey: PoolKey\n /** Risk engine address */\n riskEngine: Address\n}\n\n/**\n * Get the PanopticPool address for a given pool key and risk engine.\n *\n * @param params - Read parameters\n * @returns The PanopticPool address\n */\nexport async function getPanopticPoolAddress(\n params: GetPanopticPoolAddressParams,\n): Promise<Address> {\n const { client, factoryAddress, poolKey, riskEngine } = params\n\n return client.readContract({\n address: factoryAddress,\n abi: panopticFactoryAbi,\n functionName: 'getPanopticPool',\n args: [\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 riskEngine,\n ],\n })\n}\n\n/**\n * Parameters for getFactoryTokenURI.\n */\nexport interface GetFactoryTokenURIParams {\n /** Public client */\n client: PublicClient\n /** PanopticFactory address */\n factoryAddress: Address\n /** Token ID (encoded pool address) */\n tokenId: bigint\n}\n\n/**\n * Get the token URI from the PanopticFactory NFT.\n *\n * @param params - Read parameters\n * @returns The token URI string\n */\nexport async function getFactoryTokenURI(params: GetFactoryTokenURIParams): Promise<string> {\n const { client, factoryAddress, tokenId } = params\n\n return client.readContract({\n address: factoryAddress,\n abi: panopticFactoryAbi,\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 /** Token ID (encoded pool address) */\n tokenId: bigint\n}\n\n/**\n * Get the owner of a PanopticFactory NFT.\n *\n * @param params - Read parameters\n * @returns The owner address\n */\nexport async function getFactoryOwnerOf(params: GetFactoryOwnerOfParams): Promise<Address> {\n const { client, factoryAddress, tokenId } = params\n\n return client.readContract({\n address: factoryAddress,\n abi: panopticFactoryAbi,\n functionName: 'ownerOf',\n args: [tokenId],\n })\n}\n\n/**\n * Parameters for minePoolAddress.\n */\nexport interface MinePoolAddressParams {\n /** Public client */\n client: PublicClient\n /** PanopticFactory address */\n factoryAddress: Address\n /** Deployer address (msg.sender for deployment) */\n deployerAddress: Address\n /** V4 pool key */\n poolKey: PoolKey\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\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 *\n * @param params - Mining parameters\n * @returns The best salt and its rarity score\n */\nexport async function minePoolAddress(\n params: MinePoolAddressParams,\n): Promise<MinePoolAddressResult> {\n const {\n client,\n factoryAddress,\n deployerAddress,\n poolKey,\n riskEngine,\n salt,\n loops,\n minTargetRarity,\n } = params\n\n const result = await client.readContract({\n address: factoryAddress,\n abi: panopticFactoryAbi,\n functionName: 'minePoolAddress',\n args: [\n deployerAddress,\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 riskEngine,\n salt,\n loops,\n minTargetRarity,\n ],\n })\n\n return { bestSalt: BigInt(result[0]), highestRarity: result[1] }\n}\n\n/**\n * Parameters for getFactoryConstructMetadata.\n */\nexport interface GetFactoryConstructMetadataParams {\n /** Public client */\n client: PublicClient\n /** PanopticFactory address */\n factoryAddress: Address\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 *\n * @param params - Read parameters\n * @returns Encoded metadata URI string\n */\nexport async function getFactoryConstructMetadata(\n params: GetFactoryConstructMetadataParams,\n): Promise<string> {\n const { client, factoryAddress, panopticPoolAddress, symbol0, symbol1, fee } = params\n\n return client.readContract({\n address: factoryAddress,\n abi: panopticFactoryAbi,\n functionName: 'constructMetadata',\n args: [panopticPoolAddress, symbol0, symbol1, fee],\n })\n}\n\n/**\n * Parameters for simulateDeployNewPool.\n */\nexport interface SimulateDeployNewPoolParams {\n /** Public client */\n client: PublicClient\n /** PanopticFactory address */\n factoryAddress: Address\n /** Account address (deployer) */\n account: Address\n /** V4 pool key */\n poolKey: PoolKey\n /** Risk engine address */\n riskEngine: Address\n /** Salt (uint96) */\n salt: bigint\n}\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. Replaces off-chain deterministic\n * address prediction with no external library dependency.\n *\n * @param params - Simulation parameters\n * @returns The predicted PanopticPool address\n */\nexport async function simulateDeployNewPool(params: SimulateDeployNewPoolParams): Promise<Address> {\n const { client, factoryAddress, account, poolKey, riskEngine, salt } = params\n\n const { result } = await client.simulateContract({\n address: factoryAddress,\n abi: panopticFactoryAbi,\n functionName: 'deployNewPool',\n args: [\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 riskEngine,\n salt,\n ],\n account,\n })\n\n return result\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 { panopticPoolAbi } 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: panopticPoolAbi,\n functionName: 'getAccumulatedFeesAndPositionsData',\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 getAccumulatedFeesAndPositionsData 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 getAccumulatedFeesAndPositionsData call per tokenId\n // This gives us per-position premia\n const contracts = tokenIds.map((tokenId) => ({\n address: poolAddress,\n abi: panopticPoolAbi,\n functionName: 'getAccumulatedFeesAndPositionsData' 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 * 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 { panopticPoolAbi } 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\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}\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: panopticPoolAbi,\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 } = 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: panopticPoolAbi,\n functionName: 'getCurrentTick',\n })\n\n // Build multicall data array: [getAssetsOf, getCurrentTick, targetCall, getCurrentTick, getAssetsOf]\n const multicallData = [\n getAssetsOfCallData,\n getCurrentTickCallData,\n callData,\n getCurrentTickCallData,\n getAssetsOfCallData,\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: panopticPoolAbi,\n functionName: 'getCurrentTick',\n data,\n }),\n )\n }\n\n const assetsBefore = decodeAssets(result[0])\n const tickBefore = decodeTick(result[1])\n // result[2] is the target call result (dispatch)\n const tickAfter = decodeTick(result[3])\n const assetsAfter = decodeAssets(result[4])\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 }\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 * Snapshot recovery from dispatch calldata.\n * @module v2/sync/snapshotRecovery\n */\n\nimport type { Address, Hash, PublicClient } from 'viem'\nimport { decodeFunctionData } from 'viem'\n\nimport { panopticPoolAbi } from '../../../generated'\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 // Get recent events for this account\n const [mintEvents, burnEvents] = 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: params.fromBlock ?? 0n,\n toBlock: latestBlock,\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: params.fromBlock ?? 0n,\n toBlock: latestBlock,\n }),\n ])\n\n // Combine and sort by block number (descending) to get most recent first\n const allEvents = [...mintEvents, ...burnEvents].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 const decoded = decodeDispatchCalldata(tx.input)\n if (!decoded) {\n continue\n }\n\n // For dispatchFrom, verify target account matches\n if (decoded.targetAccount && decoded.targetAccount.toLowerCase() !== account.toLowerCase()) {\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 // No snapshot found\n return 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}\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 } = 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 // Validate pool: transaction must have been sent to the expected pool address\n if (pool && tx.to?.toLowerCase() !== pool.toLowerCase()) {\n return null\n }\n\n const decoded = decodeDispatchCalldata(tx.input)\n if (!decoded) return null\n\n // Validate account context:\n // - dispatch: tx.from must be the account (msg.sender is the trader)\n // - dispatchFrom: decoded.targetAccount must be the account (builder sends on behalf of trader)\n if (account) {\n if (decoded.targetAccount) {\n if (decoded.targetAccount.toLowerCase() !== account.toLowerCase()) {\n return null\n }\n } else {\n if (tx.from.toLowerCase() !== account.toLowerCase()) {\n return null\n }\n }\n }\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 * @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 try {\n const decoded = decodeFunctionData({\n abi: panopticPoolAbi,\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 * Get tracked position IDs from local cache.\n * @module v2/sync/getTrackedPositionIds\n */\n\nimport type { Address, Hash, PublicClient } from 'viem'\n\nimport type { StorageAdapter } from '../storage'\nimport { getPositionsKey, jsonSerializer } from '../storage'\nimport {\n type SnapshotRecoveryResult,\n recoverSnapshot,\n recoverSnapshotFromTx,\n} from './snapshotRecovery'\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\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\n */\nexport async function getOpenPositionIds(params: GetOpenPositionIdsParams): Promise<bigint[]> {\n const { client, chainId, poolAddress, account, storage, lastDispatchTxHash } = params\n\n // Fast path: decode directly from a known tx hash (O(1), no event scanning)\n // Falls back to full event-scanning recovery if the fast path returns null or throws\n let snapshot: SnapshotRecoveryResult | null = null\n if (lastDispatchTxHash) {\n try {\n snapshot = await recoverSnapshotFromTx({\n client,\n transactionHash: lastDispatchTxHash,\n account,\n pool: poolAddress,\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 })\n }\n\n if (!snapshot) {\n return []\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 * 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 { collateralTrackerAbi, panopticPoolAbi } from '../../../generated'\nimport { panopticQueryAbi } from '../abis/panopticQuery'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport { PanopticError } from '../errors'\nimport { type TokenFlow, simulateWithTokenFlow } from '../simulations/tokenFlow'\nimport type { StorageAdapter } from '../storage'\nimport { getTrackedPositionIds } from '../sync/getTrackedPositionIds'\nimport type { BlockMeta } from '../types'\nimport { MAX_TICK, MIN_TICK } from '../utils/constants'\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 * Estimate the collateral required to open a position.\n *\n * Note: This function uses PanopticQuery.getRequiredBase for estimation.\n * 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, 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: panopticPoolAbi,\n functionName: 'getCurrentTick',\n blockNumber: targetBlockNumber,\n })\n // Bridge type from panopticPoolAbi (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 // PanopticQuery.getRequiredBase returns collateral requirement in terms of token0\n // For token1 requirement, would need additional conversion or separate call\n return {\n required0,\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 /** 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 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 })\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}): Promise<bigint> {\n const {\n client,\n poolAddress,\n account,\n tokenId,\n existingPositionIds,\n precisionDivisor,\n swapAtMint,\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 })\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}): Promise<boolean> {\n const { client, poolAddress, account, tokenId, existingPositionIds, positionSize, swapAtMint } =\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 const tickLimits: readonly [number, number, number] = swapAtMint\n ? [887272, -887272, 0]\n : [-887272, 887272, 0]\n\n // Encode dispatch call\n const callData = encodeFunctionData({\n abi: panopticPoolAbi,\n functionName: 'dispatch',\n args: [\n [tokenId],\n finalPositionIdList,\n [positionSize as unknown as bigint & { readonly __uint128: true }],\n [tickLimits],\n true, // usePremiaAsCollateral\n 0n, // builderCode\n ],\n })\n\n // Use PanopticPool.multicall to simulate\n await client.simulateContract({\n address: poolAddress,\n abi: panopticPoolAbi,\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 /** 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 blockNumber,\n } = params\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 with swapAtMint=true (descending tickLimits)\n // Descending order (MAX_TICK > MIN_TICK) triggers SFPM swap, giving single-sided token flow\n const callData = encodeFunctionData({\n abi: panopticPoolAbi,\n functionName: 'dispatch',\n args: [\n [tokenId], // positionIdList: positions being minted\n finalPositionIdList,\n [positionSize as unknown as bigint & { readonly __uint128: true }],\n [[Number(MAX_TICK), Number(MIN_TICK), 0] as readonly [number, number, number]], // Descending = swapAtMint\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')\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 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: collateralTrackerAbi,\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 * 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: collateralTrackerAbi,\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 * 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 { collateralTrackerAbi, panopticPoolAbi } 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: panopticPoolAbi,\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: collateralTrackerAbi,\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: collateralTrackerAbi,\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: collateralTrackerAbi,\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: collateralTrackerAbi,\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: collateralTrackerAbi,\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: collateralTrackerAbi,\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 * 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 { panopticPoolAbi } 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: panopticPoolAbi,\n functionName: 'isSafeMode',\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n // isSafeMode returns uint8:\n // 0 = normal, 1 = no leverage, 2 = no swap, 3 = close only\n const status = BigInt(safeModeRaw) as SafeModeStatusValue\n\n switch (status) {\n case SafeModeStatus.NO_LEVERAGE:\n return {\n mode: 'restricted',\n canMint: false,\n canBurn: true,\n canForceExercise: true,\n canLiquidate: true,\n reason: 'No new leveraged positions allowed',\n _meta,\n }\n case SafeModeStatus.NO_SWAP:\n return {\n mode: 'restricted',\n canMint: true,\n canBurn: true,\n canForceExercise: true,\n canLiquidate: true,\n reason: 'Swaps are disabled',\n _meta,\n }\n case SafeModeStatus.CLOSE_ONLY:\n return {\n mode: 'emergency',\n canMint: false,\n canBurn: true,\n canForceExercise: true,\n canLiquidate: true,\n reason: 'Pool is in close-only mode',\n _meta,\n }\n default:\n return {\n mode: 'normal',\n canMint: true,\n canBurn: true,\n canForceExercise: true,\n canLiquidate: true,\n _meta,\n }\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 { panopticPoolAbi } 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: panopticPoolAbi,\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: panopticPoolAbi,\n functionName: 'getCurrentTick',\n blockNumber: targetBlockNumber,\n })\n // Bridge type from panopticPoolAbi (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 * 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 * 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 { panopticPoolAbi } 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: panopticPoolAbi,\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 * Composes `checkCollateral` + `getLiquidationPrices` into a single call\n * with all RPC reads pinned to the same block.\n *\n * @module v2/reads/margin\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { panopticPoolAbi } from '../../../generated'\nimport { panopticQueryAbi } from '../abis/panopticQuery'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport type { BlockMeta } from '../types'\n\n// Sentinel ticks used by PanopticQuery to indicate \"no liquidation at this boundary\"\nconst MIN_TICK = -887272n\nconst MAX_TICK = 887272n\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 */\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 * Margin buffer result with distance-to-liquidation.\n *\n * **Denomination**: `checkCollateral` cross-converts both collateral slots\n * into a single token so they can be compared directly.\n * When `currentTick < 0` (`sqrtPriceX96 < FP96`) all values are in **token0**\n * units; otherwise they are in **token1** units.\n * The `denominatedInToken` field tells you which (0 or 1).\n */\nexport interface MarginBuffer {\n /** Excess margin for slot 0 (positive = safe, negative = shortfall) */\n buffer0: bigint\n /** Excess margin for slot 1 (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 collateral balance for slot 0 */\n currentMargin0: bigint\n /** Current collateral balance for slot 1 */\n currentMargin1: bigint\n /** Required margin for slot 0 */\n requiredMargin0: bigint\n /** Required margin for slot 1 */\n requiredMargin1: bigint\n /**\n * Which token all 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 /** 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 * Composes `checkCollateral` and `getLiquidationPrices` RPC calls\n * into a single function, with all reads pinned to the same block.\n *\n * Uses a two-phase approach: first fetches the current tick (needed as\n * input for `checkCollateral`), then runs `checkCollateral`,\n * `getLiquidationPrices`, and `getBlockMeta` in parallel.\n *\n * @param params - The parameters\n * @returns Margin buffer with liquidation distance and block metadata\n * @throws PanopticHelperNotDeployedError - when queryAddress is not provided\n *\n * @example\n * ```typescript\n * const margin = await getMarginBuffer({\n * client,\n * poolAddress,\n * account,\n * tokenIds: [position1, position2],\n * queryAddress,\n * })\n *\n * if (margin.buffer0 < 0n || margin.buffer1 < 0n) {\n * console.log('Account has margin shortfall!')\n * }\n *\n * if (margin.liquidationDistance !== null) {\n * console.log('Ticks to liquidation:', margin.liquidationDistance)\n * }\n * ```\n */\nexport async function getMarginBuffer(params: GetMarginBufferParams): Promise<MarginBuffer> {\n const { client, poolAddress, account, tokenIds, queryAddress, blockNumber } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Phase 1: Get current tick (needed for checkCollateral's atTick param)\n const currentTickResult = await client.readContract({\n address: poolAddress,\n abi: panopticPoolAbi,\n functionName: 'getCurrentTick',\n blockNumber: targetBlockNumber,\n })\n\n const currentTick = BigInt(currentTickResult)\n\n // Phase 2: checkCollateral, getLiquidationPrices, getBlockMeta in parallel\n const [checkResult, liqPricesResult, _meta] = await Promise.all([\n client.readContract({\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'checkCollateral',\n args: [poolAddress, account, tokenIds, Number(currentTick)],\n blockNumber: targetBlockNumber,\n }) as Promise<readonly [bigint, bigint, bigint, bigint]>,\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 // checkCollateral returns uint256[4]: [effectiveBal0, effectiveReq0, effectiveBal1, effectiveReq1]\n // All values are in the same denomination: token0 if tick < 0, token1 if tick >= 0\n const [effectiveBal0, effectiveReq0, effectiveBal1, effectiveReq1] = checkResult\n\n const currentMargin0 = effectiveBal0\n const currentMargin1 = effectiveBal1\n const requiredMargin0 = effectiveReq0\n const requiredMargin1 = effectiveReq1\n\n // Buffer = current - required (positive = safe, negative = shortfall)\n const buffer0 = currentMargin0 - requiredMargin0\n const buffer1 = currentMargin1 - requiredMargin1\n\n // Buffer as percentage of required margin in bps (null when no requirement)\n const bufferPercent0 = requiredMargin0 === 0n ? null : (buffer0 * 10000n) / requiredMargin0\n const bufferPercent1 = requiredMargin1 === 0n ? null : (buffer1 * 10000n) / requiredMargin1\n\n // Decode liquidation prices (int24 → number from ABI, convert to bigint)\n const liqPriceDown = BigInt(liqPricesResult[0])\n const liqPriceUp = BigInt(liqPricesResult[1])\n\n const lowerLiquidationTick = liqPriceDown === MIN_TICK ? null : liqPriceDown\n const upperLiquidationTick = liqPriceUp === MAX_TICK ? null : liqPriceUp\n\n // Distance to nearest liquidation boundary\n let liquidationDistance: bigint | null = null\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 return {\n buffer0,\n buffer1,\n bufferPercent0,\n bufferPercent1,\n currentMargin0,\n currentMargin1,\n requiredMargin0,\n requiredMargin1,\n denominatedInToken: currentTick < 0n ? 0 : 1,\n liquidationDistance,\n lowerLiquidationTick,\n upperLiquidationTick,\n currentTick,\n _meta,\n }\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 = 4n\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 * 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.poolKey.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 { collateralTrackerAbi } 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: collateralTrackerAbi,\n functionName: 'totalAssets',\n },\n {\n address: collateralAddresses[0],\n abi: collateralTrackerAbi,\n functionName: 'totalSupply',\n },\n {\n address: collateralAddresses[1],\n abi: collateralTrackerAbi,\n functionName: 'totalAssets',\n },\n {\n address: collateralAddresses[1],\n abi: collateralTrackerAbi,\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 { collateralTrackerAbi } 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: collateralTrackerAbi,\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 * Wraps the 3-arg PanopticQuery.checkCollateral overload that uses oracle ticks\n * to compute account-level collateral balance and requirements.\n *\n * @module v2/reads/buyingPower\n */\n\nimport type { Address, Client } from 'viem'\nimport { ContractFunctionRevertedError } from 'viem'\nimport { readContract } from 'viem/actions'\n\nimport { panopticPoolAbi } from '../../../generated'\nimport { panopticQueryAbi } from '../abis/panopticQuery'\nimport type { BlockMeta } from '../types'\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 (required) */\n queryAddress: 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 */\nexport interface AccountBuyingPower {\n /** Collateral balance for token0 (at fastOracleTick) */\n collateralBalance0: bigint\n /** Required collateral for token0 (at fastOracleTick) */\n requiredCollateral0: bigint\n /** Collateral balance for token1 (at fastOracleTick) */\n collateralBalance1: bigint\n /** Required collateral for token1 (at fastOracleTick) */\n requiredCollateral1: bigint\n /** Block metadata (present only if _meta was provided) */\n _meta?: BlockMeta\n}\n\nconst ZERO_RESULT: Omit<AccountBuyingPower, '_meta'> = {\n collateralBalance0: 0n,\n requiredCollateral0: 0n,\n collateralBalance1: 0n,\n requiredCollateral1: 0n,\n}\n\n/**\n * Get account-level buying power using the 3-arg checkCollateral overload.\n *\n * This calls PanopticQuery.checkCollateral(pool, account, positionIdList) which\n * returns 4 arrays of 4 values each, evaluated at [currentTick, fastOracleTick,\n * slowOracleTick, latestObservation]. We extract index [1] (fastOracleTick)\n * which is the tick used for buying power calculations.\n *\n * If checkCollateral reverts due to an uninitialized oracle (pool.getOracleTicks()\n * also reverts with a contract error), returns zeros. For all other errors, re-throws.\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, queryAddress, blockNumber } = params\n const _meta = params._meta\n\n try {\n const res = await readContract(client, {\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'checkCollateral',\n args: [poolAddress, account, tokenIds],\n blockNumber,\n })\n\n // res is [collateralBalances0[4], requiredCollaterals0[4], collateralBalances1[4], requiredCollaterals1[4]]\n // Index [1] = fastOracleTick values\n return {\n collateralBalance0: res[0][1],\n requiredCollateral0: res[1][1],\n collateralBalance1: res[2][1],\n requiredCollateral1: res[3][1],\n _meta,\n }\n } catch (checkCollateralError: unknown) {\n // Fallback: check if the revert is due to uninitialized oracle\n try {\n await readContract(client, {\n address: poolAddress,\n abi: panopticPoolAbi,\n functionName: 'getOracleTicks',\n blockNumber,\n })\n } catch (getOracleTicksError: unknown) {\n if (getOracleTicksError instanceof ContractFunctionRevertedError) {\n // Oracle not initialized — return zeros\n return { ...ZERO_RESULT, _meta }\n }\n }\n // getOracleTicks succeeded or threw a non-contract error — re-throw original\n throw checkCollateralError\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 * Open position simulation for the Panoptic v2 SDK.\n * @module v2/simulations/simulateOpenPosition\n */\n\nimport type { Address, PublicClient } from 'viem'\nimport { encodeFunctionData } from 'viem'\n\nimport { panopticPoolAbi } 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 { 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: panopticPoolAbi,\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 // 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\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.poolKey.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 postMarginExcess0: null, // Requires PanopticQuery.checkCollateral\n postMarginExcess1: null,\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 { AccountInsolventError, NotEnoughTokensError } from '../errors'\nimport { parsePanopticError } from '../errors/parser'\nimport type { SimulateOpenPositionParams } from '../simulations/simulateOpenPosition'\nimport { simulateOpenPosition } from '../simulations/simulateOpenPosition'\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 /** Whether the simulated mint succeeded (position is solvent post-mint) */\n isSolvent: boolean\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}\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 // isSolvent should only be false for actual solvency errors (AccountInsolvent, NotEnoughTokens).\n // Other simulation failures (PriceBoundFail, EffectiveLiquidityAboveThreshold, etc.) are not\n // solvency issues and should not trigger the \"buying power exceeded\" message.\n let isSolvent = true\n if (!simulation.success) {\n const parsed = parsePanopticError(simulation.error)\n const err = parsed?.error ?? simulation.error\n isSolvent = !(err instanceof AccountInsolventError || err instanceof NotEnoughTokensError)\n }\n const data = simulation.success ? simulation.data : null\n\n return {\n currentBuyingPower,\n simulation,\n isSolvent,\n amount0Required: data?.amount0Required ?? null,\n amount1Required: data?.amount1Required ?? null,\n postCollateral0: data?.postCollateral0 ?? null,\n postCollateral1: data?.postCollateral1 ?? 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 { panopticPoolAbi } 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: panopticPoolAbi,\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 { panopticPoolAbi } 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: panopticPoolAbi,\n eventName: 'OptionMinted',\n args: { recipient: account },\n fromBlock,\n toBlock: effectiveToBlock,\n }),\n client.getContractEvents({\n address: poolAddress,\n abi: panopticPoolAbi,\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 * 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] 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] as const\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 /** Block number (undefined if queried as latest) */\n blockNumber: bigint | undefined\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, _meta] = await Promise.all([\n fetchUniswapFeeData(client, blockNumbers, legs, poolConfig),\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: blockNumbers[i],\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 { panopticPoolAbi } 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: panopticPoolAbi,\n functionName: 'getAccumulatedFeesAndPositionsData',\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 * 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 — viem auto-batches into multicall\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 { panopticPoolAbi, 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 * Cross-margined collateral data at pnlEndTick, from `checkCollateral(pool, account, [tokenId], pnlEndTick)`.\n * All values are in the same denomination after cross-margining:\n * token0 when atTick < 0, token1 when atTick >= 0.\n * Slot 0/1 refer to the two collateral trackers, not token0/token1.\n */\n collateralEffectiveBal0: bigint\n collateralEffectiveReq0: bigint\n collateralEffectiveBal1: bigint\n collateralEffectiveReq1: bigint\n /** Cross-margined collateral data at mint tick (same denomination rules) */\n collateralAtMintEffectiveBal0: bigint\n collateralAtMintEffectiveReq0: bigint\n collateralAtMintEffectiveBal1: bigint\n collateralAtMintEffectiveReq1: 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**: 5 calls per position in a single multicall at current block:\n * 1. `getAccumulatedFeesAndPositionsData` → per-position premia\n * 2. `getPortfolioValue` at currentTick → current portfolio value\n * 3. `getPortfolioValue` at mintTick → portfolio value at mint\n * 4. `checkCollateral` at currentTick → collateral requirement at current tick\n * 5. `checkCollateral` at mintTick → collateral requirement at mint tick\n * - **Closed positions**: 4 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 * 3. `checkCollateral` at burnTick → collateral requirement at burn tick\n * 4. `checkCollateral` at mintTick → collateral requirement at mint tick\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 = 5\n/** Number of multicall contracts per closed position */\nconst CLOSED_CALLS_PER_POSITION = 4\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: 5 calls per position\n const contracts = positions.flatMap((p) => [\n // 1. getAccumulatedFeesAndPositionsData → premia\n {\n address: p.poolAddress,\n abi: panopticPoolAbi,\n functionName: 'getAccumulatedFeesAndPositionsData' 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 // 4. checkCollateral at currentTick\n {\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'checkCollateral' as const,\n args: [p.poolAddress, p.account, [p.tokenId], currentTick] as const,\n },\n // 5. checkCollateral at mintTick\n {\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'checkCollateral' as const,\n args: [p.poolAddress, p.account, [p.tokenId], p.tickAtMint] 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 const collateralResult = multicallResults[baseIdx + 3]\n const collateralAtMintResult = multicallResults[baseIdx + 4]\n\n if (premiaResult.status !== 'success') {\n throw new EnrichmentCallError(\n position.tokenId,\n 'getAccumulatedFeesAndPositionsData',\n premiaResult.error,\n )\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 premia: shortPremium - longPremium\n const [shortPremiumPacked, longPremiumPacked] = premiaResult.result as [\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 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 // Decode collateral requirements (graceful fallback to 0 if call failed)\n const collateral = decodeCollateralResult(collateralResult)\n const collateralAtMint = decodeCollateralResult(collateralAtMintResult)\n\n entries.push([\n position.tokenId.toString(),\n {\n premiaOwed0,\n premiaOwed1,\n portfolioValue0,\n portfolioValue1,\n portfolioValueAtMint0,\n portfolioValueAtMint1,\n collateralEffectiveBal0: collateral.effectiveBal0,\n collateralEffectiveReq0: collateral.effectiveReq0,\n collateralEffectiveBal1: collateral.effectiveBal1,\n collateralEffectiveReq1: collateral.effectiveReq1,\n collateralAtMintEffectiveBal0: collateralAtMint.effectiveBal0,\n collateralAtMintEffectiveReq0: collateralAtMint.effectiveReq0,\n collateralAtMintEffectiveBal1: collateralAtMint.effectiveBal1,\n collateralAtMintEffectiveReq1: collateralAtMint.effectiveReq1,\n },\n ])\n }\n\n return { entries }\n}\n\n/**\n * Decode a checkCollateral(pool, account, positionIdList, atTick) result.\n *\n * The contract returns uint256[4]: [effectiveBal0, effectiveReq0, effectiveBal1, effectiveReq1].\n * All values are in the same denomination after cross-margining:\n * - token0 units when atTick < 0 (sqrtPriceX96 < FP96)\n * - token1 units when atTick >= 0 (sqrtPriceX96 >= FP96)\n *\n * Slot 0 and slot 1 refer to the two collateral trackers, not token0/token1 directly.\n */\nfunction decodeCollateralResult(result: { status: string; result?: unknown }): {\n effectiveBal0: bigint\n effectiveReq0: bigint\n effectiveBal1: bigint\n effectiveReq1: bigint\n} {\n if (result.status !== 'success') {\n return { effectiveBal0: 0n, effectiveReq0: 0n, effectiveBal1: 0n, effectiveReq1: 0n }\n }\n\n const [effectiveBal0, effectiveReq0, effectiveBal1, effectiveReq1] = result.result as readonly [\n bigint,\n bigint,\n bigint,\n bigint,\n ]\n\n return { effectiveBal0, effectiveReq0, effectiveBal1, effectiveReq1 }\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: 4 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 // 3. checkCollateral at burnTick\n {\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'checkCollateral' as const,\n args: [p.poolAddress, p.account, [p.tokenId], p.tickAtBurn ?? 0] as const,\n },\n // 4. checkCollateral at mintTick\n {\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'checkCollateral' as const,\n args: [p.poolAddress, p.account, [p.tokenId], p.tickAtMint] 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 const collateralResult = multicallResults[baseIdx + 2]\n const collateralAtMintResult = multicallResults[baseIdx + 3]\n\n if (portfolioAtBurnResult.status !== 'success') {\n throw new EnrichmentCallError(\n position.tokenId,\n 'getPortfolioValue (burnTick)',\n portfolioAtBurnResult.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 const [portfolioValue0, portfolioValue1] = portfolioAtBurnResult.result as [bigint, bigint]\n const [portfolioValueAtMint0, portfolioValueAtMint1] = portfolioAtMintResult.result as [\n bigint,\n bigint,\n ]\n\n const collateral = decodeCollateralResult(collateralResult)\n const collateralAtMint = decodeCollateralResult(collateralAtMintResult)\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 collateralEffectiveBal0: collateral.effectiveBal0,\n collateralEffectiveReq0: collateral.effectiveReq0,\n collateralEffectiveBal1: collateral.effectiveBal1,\n collateralEffectiveReq1: collateral.effectiveReq1,\n collateralAtMintEffectiveBal0: collateralAtMint.effectiveBal0,\n collateralAtMintEffectiveReq0: collateralAtMint.effectiveReq0,\n collateralAtMintEffectiveBal1: collateralAtMint.effectiveBal1,\n collateralAtMintEffectiveReq1: collateralAtMint.effectiveReq1,\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 * 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 * Event reconstruction for full position history scan.\n * @module v2/sync/eventReconstruction\n */\n\nimport type { Address, Hash, PublicClient } from 'viem'\n\nimport type { SyncEvent } from '../types'\n\n/**\n * Parameters for event reconstruction.\n */\nexport interface EventReconstructionParams {\n /** viem public client */\n client: PublicClient\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\n let currentBlock = fromBlock\n const totalBlocks = toBlock - fromBlock\n\n // Scan in batches\n while (currentBlock <= toBlock) {\n const endBlock =\n currentBlock + batchSize - 1n > toBlock ? toBlock : currentBlock + batchSize - 1n\n\n // Fetch mint events for this batch\n const [mints, burns] = 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: currentBlock,\n toBlock: endBlock,\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: 'uint256', name: 'tokenId', indexed: true },\n { type: 'uint256', name: 'positionSize', indexed: false },\n { type: 'int256[4]', name: 'premiaByLeg', indexed: false },\n ],\n },\n args: {\n recipient: account,\n },\n fromBlock: currentBlock,\n toBlock: endBlock,\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 // Report progress\n if (onProgress) {\n const blocksProcessed = endBlock - fromBlock + 1n\n const progress = totalBlocks > 0n ? (blocksProcessed * 100n) / totalBlocks : 100n\n\n onProgress({\n currentBlock: endBlock,\n targetBlock: toBlock,\n positionsFound: BigInt(mintEvents.length),\n progress,\n })\n }\n\n currentBlock = endBlock + 1n\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\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 { isRetryableRpcError } from '../bot'\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, SyncEvent } from '../types'\nimport { REORG_DEPTH } from '../utils/constants'\nimport { getPoolDeploymentBlock, reconstructFromEvents } from './eventReconstruction'\nimport { calculateResyncBlock, detectReorg, loadCheckpoint, saveCheckpoint } from './reorgHandling'\nimport { decodeDispatchCalldata, recoverSnapshot } from './snapshotRecovery'\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 maxLogsPerQuery = 10000n,\n syncTimeout = 300000n, // 5 minutes\n onUpdate,\n minBlockNumber,\n snapshotTxHash,\n } = params\n\n const startTime = Date.now()\n\n // Track progress for timeout errors\n let lastProcessedBlock = 0n\n let targetBlockForTimeout = 0n\n\n // Check for timeout\n const checkTimeout = () => {\n const elapsed = BigInt(Date.now() - startTime)\n if (elapsed > syncTimeout) {\n const blocksRemaining =\n targetBlockForTimeout > lastProcessedBlock ? targetBlockForTimeout - lastProcessedBlock : 0n\n throw new SyncTimeoutError(elapsed, lastProcessedBlock, blocksRemaining)\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 // Load existing checkpoint\n const checkpoint = await loadCheckpoint(storage, chainId, poolAddress, account)\n\n let positionIds: bigint[] = []\n let fromBlock: bigint\n let incremental = false\n let skipEventScan = false\n\n if (checkpoint) {\n // Check for reorg\n const reorgResult = await detectReorg({\n client,\n chainId,\n poolAddress,\n account,\n storage,\n })\n\n if (reorgResult.detected) {\n // Notify about reorg\n onUpdate?.({\n type: 'reorg-detected',\n blockNumber: reorgResult.reorgBlock ?? 0n,\n })\n\n // Roll back and resync from safe block\n fromBlock = calculateResyncBlock(checkpoint.lastBlock, REORG_DEPTH)\n positionIds = [] // Clear positions, will re-discover\n\n // If we rolled back to 0, do a full scan\n if (fromBlock === 0n) {\n const deploymentBlock = await getPoolDeploymentBlock(client, poolAddress)\n fromBlock = deploymentBlock ?? 0n\n }\n } else {\n // Incremental sync from last checkpoint\n fromBlock = checkpoint.lastBlock + 1n\n positionIds = [...checkpoint.positionIds]\n incremental = true\n }\n } else {\n // No checkpoint - need to do initial sync\n // First, quick check if account has ANY position events at all\n // This is fast because 'recipient' is indexed\n const hasAnyEvents = await accountHasPositionEvents({\n client,\n poolAddress,\n account,\n fromBlock: params.fromBlock,\n toBlock,\n })\n\n if (!hasAnyEvents) {\n // Account has never had any positions - short circuit\n // Save empty checkpoint at current block and return immediately\n const finalBlock = await client.getBlock({ blockNumber: toBlock })\n\n // Store pool metadata if not already stored\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: toBlock,\n lastBlockHash: finalBlock.hash,\n positionIds: [],\n })\n\n const positionsKey = getPositionsKey(chainId, poolAddress, account)\n await storage.set(positionsKey, jsonSerializer.stringify([]))\n\n const endTime = Date.now()\n return {\n lastSyncedBlock: toBlock,\n lastSyncedBlockHash: finalBlock.hash,\n positionCount: 0n,\n positionIds: [],\n incremental: false,\n durationMs: BigInt(endTime - startTime),\n }\n }\n\n // Try snapshot recovery first (finds most recent dispatch calldata)\n const snapshot = await recoverSnapshot({\n client,\n poolAddress,\n account,\n fromBlock: params.fromBlock,\n toBlock,\n })\n\n if (snapshot) {\n // Snapshot from the most recent dispatch is authoritative —\n // finalPositionIdList IS the current open position set.\n // No event scan needed since recoverSnapshot already searched\n // all events up to toBlock and found the most recent one.\n positionIds = snapshot.positionIds\n fromBlock = snapshot.blockNumber + 1n\n skipEventScan = true\n } else if (snapshotTxHash) {\n // Manual snapshot tx hash provided - decode via shared helper\n try {\n const tx = await client.getTransaction({ hash: snapshotTxHash })\n const decoded = decodeDispatchCalldata(tx.input)\n\n if (!decoded) {\n throw new PositionSnapshotNotFoundError()\n }\n\n positionIds = decoded.positionIds\n const block = await client.getBlock({\n blockNumber: tx.blockNumber ?? 0n,\n })\n fromBlock = (tx.blockNumber ?? 0n) + 1n\n\n // Save initial checkpoint from manual snapshot\n await saveCheckpoint({\n storage,\n chainId,\n poolAddress,\n account,\n lastBlock: tx.blockNumber ?? 0n,\n lastBlockHash: block.hash,\n positionIds,\n })\n } catch (error) {\n if (error instanceof PositionSnapshotNotFoundError) {\n throw error\n }\n throw new PositionSnapshotNotFoundError(error instanceof Error ? error : undefined)\n }\n } else {\n // No snapshot found - fall back to full event reconstruction\n const deploymentBlock =\n params.fromBlock ?? (await getPoolDeploymentBlock(client, poolAddress))\n fromBlock = deploymentBlock ?? 0n\n }\n }\n\n // If we need to sync (fromBlock <= toBlock) and snapshot wasn't already authoritative\n if (!skipEventScan && fromBlock <= toBlock) {\n // Update tracking for timeout errors\n targetBlockForTimeout = toBlock\n lastProcessedBlock = fromBlock\n\n checkTimeout()\n\n // Scan events incrementally\n const result = await reconstructFromEvents({\n client,\n poolAddress,\n account,\n fromBlock,\n toBlock,\n batchSize: maxLogsPerQuery,\n onProgress: (event: SyncEvent) => {\n lastProcessedBlock = event.currentBlock\n checkTimeout()\n onUpdate?.({\n type: 'progress',\n blockNumber: event.currentBlock,\n progress: {\n current: event.currentBlock - fromBlock,\n total: toBlock - fromBlock + 1n,\n },\n })\n },\n })\n\n // Merge with existing positions\n // Open positions: add new, keep existing that aren't in closed\n const closedSet = new Set(result.closedPositions.map((id) => id.toString()))\n\n // Filter out closed positions from existing\n positionIds = positionIds.filter((id) => !closedSet.has(id.toString()))\n\n // Add newly opened positions\n for (const newId of result.openPositions) {\n if (!positionIds.some((id) => id === newId)) {\n positionIds.push(newId)\n onUpdate?.({\n type: 'position-opened',\n tokenId: newId,\n blockNumber: result.lastBlock,\n })\n }\n }\n\n // Notify about closed positions\n for (const closedId of result.closedPositions) {\n onUpdate?.({\n type: 'position-closed',\n tokenId: closedId,\n blockNumber: result.lastBlock,\n })\n }\n }\n\n // Get final block info\n const finalBlock = await client.getBlock({ blockNumber: toBlock })\n\n // Fetch and store pool metadata if not already stored\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 // 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 // Store each position's immutable data\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 // Save checkpoint\n await saveCheckpoint({\n storage,\n chainId,\n poolAddress,\n account,\n lastBlock: toBlock,\n lastBlockHash: finalBlock.hash,\n positionIds,\n })\n\n // Save positions to storage\n const positionsKey = getPositionsKey(chainId, poolAddress, account)\n await storage.set(positionsKey, jsonSerializer.stringify(positionIds))\n\n const endTime = Date.now()\n\n return {\n lastSyncedBlock: toBlock,\n lastSyncedBlockHash: finalBlock.hash,\n positionCount: BigInt(positionIds.length),\n positionIds,\n incremental,\n durationMs: BigInt(endTime - startTime),\n }\n}\n\n/**\n * Quick check if an account has ANY position events (OptionMinted or OptionBurnt).\n * This is fast because 'recipient' is indexed.\n *\n * **Warning:** RPC index lag can cause false negatives for recently minted positions.\n * If the RPC node's event index is behind the chain tip, this function may return\n * `false` even though the account has just minted a position. Callers should either\n * wait a few blocks after minting before calling syncPositions, or skip this\n * optimization (by providing a `snapshotTxHash`) when freshness is critical.\n *\n * @param params - Check parameters\n * @returns true if account has any position events, false otherwise\n */\nasync function accountHasPositionEvents(params: {\n client: PublicClient\n poolAddress: Address\n account: Address\n fromBlock?: bigint\n toBlock: bigint\n}): Promise<boolean> {\n const { client, poolAddress, account, fromBlock = 0n, toBlock } = params\n\n // Query with limit: 1 to check existence quickly\n // Check OptionMinted events first (most common for accounts with positions)\n const [mintEvents, burnEvents] = await Promise.all([\n withRetry(() =>\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 ),\n withRetry(() =>\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: 'uint256', name: 'tokenId', indexed: true },\n { type: 'uint256', name: 'positionSize', indexed: false },\n { type: 'int256[4]', name: 'premiaByLeg', indexed: false },\n ],\n },\n args: {\n recipient: account,\n },\n fromBlock,\n toBlock,\n }),\n ),\n ])\n\n return mintEvents.length > 0 || burnEvents.length > 0\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 // Parse tickSpacing and fee from poolKeyBytes\n const hex = metadata.poolKeyBytes.slice(2)\n const fee = BigInt(`0x${hex.slice(128, 192)}`)\n const tickSpacing = BigInt(`0x${hex.slice(192, 256)}`)\n\n const poolMeta: StoredPoolMeta = {\n tickSpacing,\n 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/**\n * Retry helper with exponential backoff for transient RPC errors.\n *\n * @param fn - Async function to retry\n * @param maxRetries - Maximum number of retries (default: 3)\n * @returns The result of the function\n */\nasync function withRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {\n let lastError: unknown\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn()\n } catch (error) {\n lastError = error\n if (attempt < maxRetries && isRetryableRpcError(error)) {\n // Exponential backoff: 1s, 2s, 4s\n await new Promise((resolve) => setTimeout(resolve, 1000 * 2 ** attempt))\n continue\n }\n throw error\n }\n }\n throw lastError\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 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 = 4n,\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 { client, poolAddress, queryAddress, tokenIds, vegoid = 4n, blockNumber } = 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 * Stable cache-scope helpers for React query keys.\n * @module v2/react/cacheScopes\n */\n\nconst DEFAULT_CLIENT_CACHE_SCOPE = 'default-client'\nconst DEFAULT_STORAGE_CACHE_SCOPE = 'default-storage'\n\nexport function getClientCacheScope(scope?: string): string {\n return scope ?? DEFAULT_CLIENT_CACHE_SCOPE\n}\n\nexport function getStorageCacheScope(scope?: string): string {\n return scope ?? DEFAULT_STORAGE_CACHE_SCOPE\n}\n\nexport function getClientCacheScopeKey(client: unknown, scope?: string): string {\n // Keep client in the queryKey expression for exhaustive-deps while keying by stable scope.\n void client\n return getClientCacheScope(scope)\n}\n\nexport function getStorageCacheScopeKey(storage: unknown, scope?: string): string {\n // Keep storage in the queryKey expression for exhaustive-deps while keying by stable scope.\n void storage\n return getStorageCacheScope(scope)\n}\n\nexport function getAtTickCacheKey(atTick?: bigint): string {\n return atTick === undefined ? 'latest' : atTick.toString()\n}\n","/**\n * React context provider for the Panoptic v2 SDK.\n * @module v2/react/provider\n */\n\nimport { type ReactNode, createContext, useContext } from 'react'\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport type { StorageAdapter } from '../storage'\n\n/**\n * Panoptic SDK context value.\n */\nexport interface PanopticContextValue {\n /** viem PublicClient for reading chain state */\n publicClient: PublicClient\n /**\n * Optional cache scope for read/simulation query keys.\n * Use this when multiple environments share the same QueryClient.\n */\n clientScope?: string\n /** Optional viem WalletClient for write operations */\n walletClient?: WalletClient\n /** Optional account address for write operations */\n account?: Address\n /** Chain ID */\n chainId: bigint\n /** Optional storage adapter for position tracking */\n storage?: StorageAdapter\n /**\n * Optional cache scope for storage-backed query keys.\n * Set this when swapping storage adapters at runtime.\n */\n storageScope?: string\n}\n\nconst PanopticContext = createContext<PanopticContextValue | null>(null)\n\n/**\n * Props for PanopticProvider.\n */\nexport interface PanopticProviderProps extends PanopticContextValue {\n children: ReactNode\n}\n\n/**\n * Context provider for Panoptic v2 SDK hooks.\n *\n * Wraps children with shared publicClient, walletClient, account, chainId, and storage.\n * Does NOT include QueryClientProvider — you must provide your own.\n *\n * @example\n * ```tsx\n * <QueryClientProvider client={queryClient}>\n * <PanopticProvider\n * publicClient={publicClient}\n * walletClient={walletClient}\n * account={address}\n * chainId={1n}\n * >\n * <App />\n * </PanopticProvider>\n * </QueryClientProvider>\n * ```\n */\nexport function PanopticProvider({ children, ...value }: PanopticProviderProps) {\n return <PanopticContext.Provider value={value}>{children}</PanopticContext.Provider>\n}\n\n/**\n * Access the Panoptic SDK context.\n *\n * @throws Error if used outside PanopticProvider\n * @returns PanopticContextValue\n */\nexport function usePanopticContext(): PanopticContextValue {\n const ctx = useContext(PanopticContext)\n if (!ctx) {\n throw new Error('usePanopticContext must be used within a PanopticProvider')\n }\n return ctx\n}\n\n/**\n * Internal hook that requires walletClient and account.\n *\n * @throws Error if walletClient or account not provided in context\n * @returns { walletClient, account } guaranteed non-undefined\n */\nexport function useRequireWallet(): { walletClient: WalletClient; account: Address } {\n const { walletClient, account } = usePanopticContext()\n if (!walletClient || !account) {\n throw new Error('walletClient and account are required. Provide them via PanopticProvider.')\n }\n return { walletClient, account }\n}\n\n/**\n * Internal hook that requires storage adapter.\n *\n * @throws Error if storage not provided in context\n * @returns StorageAdapter guaranteed non-undefined\n */\nexport function useRequireStorage(): StorageAdapter {\n const { storage } = usePanopticContext()\n if (!storage) {\n throw new Error('storage is required. Provide a StorageAdapter via PanopticProvider.')\n }\n return storage\n}\n","/**\n * Query key factory for TanStack Query / SWR integration.\n * @module v2/react/queryKeys\n */\n\nimport type { Address } from 'viem'\n\n/**\n * Query key factory for Panoptic v2 SDK data.\n *\n * Use with TanStack Query or SWR for cache key consistency.\n * All keys are arrays for proper cache matching and invalidation.\n *\n * @example\n * ```typescript\n * import { useQuery } from '@tanstack/react-query'\n * import { queryKeys, getPool } from 'panoptic-v2-sdk'\n *\n * function usePool(config: PanopticConfig) {\n * return useQuery({\n * queryKey: queryKeys.pool(config.chainId, config.poolAddress),\n * queryFn: () => getPool(config),\n * })\n * }\n * ```\n */\nexport const queryKeys = {\n /**\n * Base key for all Panoptic v2 queries.\n */\n all: ['panoptic-v2'] as const,\n\n /**\n * Key for pool data.\n */\n pool: (chainId: bigint, poolAddress: Address) =>\n [...queryKeys.all, 'pool', chainId.toString(), poolAddress] as const,\n\n /**\n * Key for pool utilization.\n */\n utilization: (chainId: bigint, poolAddress: Address) =>\n [...queryKeys.all, 'utilization', chainId.toString(), poolAddress] as const,\n\n /**\n * Key for oracle state.\n */\n oracle: (chainId: bigint, poolAddress: Address) =>\n [...queryKeys.all, 'oracle', chainId.toString(), poolAddress] as const,\n\n /**\n * Key for safe mode state.\n */\n safeMode: (chainId: bigint, poolAddress: Address) =>\n [...queryKeys.all, 'safeMode', chainId.toString(), poolAddress] as const,\n\n /**\n * Key for risk parameters.\n */\n riskParameters: (chainId: bigint, poolAddress: Address) =>\n [...queryKeys.all, 'riskParameters', chainId.toString(), poolAddress] as const,\n\n /**\n * Key for current rates.\n */\n rates: (chainId: bigint, poolAddress: Address) =>\n [...queryKeys.all, 'rates', chainId.toString(), poolAddress] as const,\n\n /**\n * Key for a single position.\n */\n position: (chainId: bigint, poolAddress: Address, tokenId: bigint) =>\n [...queryKeys.all, 'position', chainId.toString(), poolAddress, tokenId.toString()] as const,\n\n /**\n * Key for all positions of an account.\n */\n positions: (chainId: bigint, poolAddress: Address, account: Address) =>\n [...queryKeys.all, 'positions', chainId.toString(), poolAddress, account] as const,\n\n /**\n * Key for tracked position IDs.\n */\n trackedPositionIds: (chainId: bigint, poolAddress: Address, account: Address) =>\n [...queryKeys.all, 'trackedPositionIds', chainId.toString(), poolAddress, account] as const,\n\n /**\n * Key for sync status.\n */\n syncStatus: (chainId: bigint, poolAddress: Address, account: Address) =>\n [...queryKeys.all, 'syncStatus', chainId.toString(), poolAddress, account] as const,\n\n /**\n * Key for account collateral.\n */\n accountCollateral: (chainId: bigint, poolAddress: Address, account: Address) =>\n [...queryKeys.all, 'accountCollateral', chainId.toString(), poolAddress, account] as const,\n\n /**\n * Key for base account summary (aggregate dashboard data).\n */\n accountSummaryBasic: (chainId: bigint, poolAddress: Address, account: Address) =>\n [...queryKeys.all, 'accountSummaryBasic', chainId.toString(), poolAddress, account] as const,\n\n /**\n * Key for risk-focused account summary.\n */\n accountSummaryRisk: (chainId: bigint, poolAddress: Address, account: Address) =>\n [...queryKeys.all, 'accountSummaryRisk', chainId.toString(), poolAddress, account] as const,\n\n /**\n * Key for liquidation check.\n */\n isLiquidatable: (chainId: bigint, poolAddress: Address, account: Address) =>\n [...queryKeys.all, 'isLiquidatable', chainId.toString(), poolAddress, account] as const,\n\n /**\n * Key for liquidation prices.\n */\n liquidationPrices: (chainId: bigint, poolAddress: Address, account: Address) =>\n [...queryKeys.all, 'liquidationPrices', chainId.toString(), poolAddress, account] as const,\n\n /**\n * Key for net liquidation value.\n */\n netLiquidationValue: (chainId: bigint, poolAddress: Address, account: Address, atTick: bigint) =>\n [\n ...queryKeys.all,\n 'netLiquidationValue',\n chainId.toString(),\n poolAddress,\n account,\n atTick.toString(),\n ] as const,\n\n /**\n * Key for chunk spreads.\n */\n chunkSpreads: (chainId: bigint, poolAddress: Address) =>\n [...queryKeys.all, 'chunkSpreads', chainId.toString(), poolAddress] as const,\n\n /**\n * Key for closed positions.\n */\n closedPositions: (chainId: bigint, poolAddress: Address, account: Address) =>\n [...queryKeys.all, 'closedPositions', chainId.toString(), poolAddress, account] as const,\n\n /**\n * Key for trade history.\n */\n tradeHistory: (chainId: bigint, poolAddress: Address, account: Address) =>\n [...queryKeys.all, 'tradeHistory', chainId.toString(), poolAddress, account] as const,\n\n /**\n * Key for realized PnL.\n */\n realizedPnL: (chainId: bigint, poolAddress: Address, account: Address) =>\n [...queryKeys.all, 'realizedPnL', chainId.toString(), poolAddress, account] as const,\n\n /**\n * Key for position greeks.\n */\n positionGreeks: (chainId: bigint, poolAddress: Address, tokenId: bigint) =>\n [\n ...queryKeys.all,\n 'positionGreeks',\n chainId.toString(),\n poolAddress,\n tokenId.toString(),\n ] as const,\n\n /**\n * Key for account greeks.\n */\n accountGreeks: (chainId: bigint, poolAddress: Address, account: Address) =>\n [...queryKeys.all, 'accountGreeks', chainId.toString(), poolAddress, account] as const,\n\n /**\n * Key for collateral estimate.\n */\n collateralEstimate: (chainId: bigint, poolAddress: Address, account: Address, tokenId: bigint) =>\n [\n ...queryKeys.all,\n 'collateralEstimate',\n chainId.toString(),\n poolAddress,\n account,\n tokenId.toString(),\n ] as const,\n\n /**\n * Key for max position size.\n */\n maxPositionSize: (chainId: bigint, poolAddress: Address, account: Address, tokenId: bigint) =>\n [\n ...queryKeys.all,\n 'maxPositionSize',\n chainId.toString(),\n poolAddress,\n account,\n tokenId.toString(),\n ] as const,\n\n /**\n * Key for max withdrawable assets from a collateral tracker.\n */\n maxWithdrawable: (\n chainId: bigint,\n collateralTrackerAddress: Address,\n positionIdList: bigint[],\n totalAssets: bigint,\n account: Address,\n ) =>\n [\n ...queryKeys.all,\n chainId.toString(),\n 'maxWithdrawable',\n collateralTrackerAddress,\n positionIdList.map(String).join(','),\n totalAssets.toString(),\n account,\n ] as const,\n\n /**\n * Key for approval check.\n */\n approval: (chainId: bigint, token: Address, owner: Address, spender: Address) =>\n [...queryKeys.all, 'approval', chainId.toString(), token, owner, spender] as const,\n\n /**\n * Key for ERC4626 preview operations.\n */\n erc4626Preview: (chainId: bigint, tracker: Address, operation: string, amount: bigint) =>\n [\n ...queryKeys.all,\n 'erc4626Preview',\n chainId.toString(),\n tracker,\n operation,\n amount.toString(),\n ] as const,\n\n /**\n * Key for margin buffer.\n */\n marginBuffer: (chainId: bigint, poolAddress: Address, account: Address) =>\n [...queryKeys.all, 'marginBuffer', chainId.toString(), poolAddress, account] as const,\n\n /**\n * Key for account premia.\n */\n accountPremia: (chainId: bigint, poolAddress: Address, account: Address) =>\n [...queryKeys.all, 'accountPremia', chainId.toString(), poolAddress, account] as const,\n\n /**\n * Key for positions with premia.\n */\n positionsWithPremia: (chainId: bigint, poolAddress: Address, account: Address) =>\n [...queryKeys.all, 'positionsWithPremia', chainId.toString(), poolAddress, account] as const,\n\n /**\n * Key for collateral data.\n */\n collateralData: (chainId: bigint, poolAddress: Address) =>\n [...queryKeys.all, 'collateralData', chainId.toString(), poolAddress] as const,\n\n /**\n * Key for pool liquidities.\n */\n poolLiquidities: (chainId: bigint, poolAddress: Address) =>\n [...queryKeys.all, 'poolLiquidities', chainId.toString(), poolAddress] as const,\n\n /**\n * Key for optimized risk partners.\n */\n optimizeRiskPartners: (chainId: bigint, poolAddress: Address, tokenId: bigint) =>\n [\n ...queryKeys.all,\n 'optimizeRiskPartners',\n chainId.toString(),\n poolAddress,\n tokenId.toString(),\n ] as const,\n /**\n * Key for price history.\n * Uses a hash of timestamps for cache busting when the time range changes.\n */\n priceHistory: (chainId: bigint, poolAddress: string, timestampsHash: string) =>\n [...queryKeys.all, 'priceHistory', chainId.toString(), poolAddress, timestampsHash] as const,\n\n /**\n * Key for streamia history.\n */\n streamiaHistory: (chainId: bigint, poolAddress: string, rangeHash: string) =>\n [...queryKeys.all, 'streamiaHistory', chainId.toString(), poolAddress, rangeHash] as const,\n\n /**\n * Key for Uniswap fee history.\n */\n uniswapFeeHistory: (chainId: bigint, poolAddress: string, rangeHash: string) =>\n [...queryKeys.all, 'uniswapFeeHistory', chainId.toString(), poolAddress, rangeHash] as const,\n\n /**\n * Key for required credit for ITM position.\n */\n requiredCreditForITM: (\n chainId: bigint,\n poolAddress: Address,\n account: Address,\n tokenId: bigint,\n ) =>\n [\n ...queryKeys.all,\n 'requiredCreditForITM',\n chainId.toString(),\n poolAddress,\n account,\n tokenId.toString(),\n ] as const,\n} as const\n","/**\n * TanStack Query v5 read hooks for the Panoptic v2 SDK.\n * @module v2/react/hooks/reads\n */\n\nimport { keepPreviousData, useMutation, useQuery } from '@tanstack/react-query'\nimport type { Address, PublicClient } from 'viem'\n\nimport { resolveBlockNumbers } from '../../clients/blocksByTimestamp'\nimport {\n type GetFactoryConstructMetadataParams,\n type GetFactoryOwnerOfParams,\n type GetFactoryTokenURIParams,\n type GetPanopticPoolAddressParams,\n type MinePoolAddressParams,\n type SimulateDeployNewPoolParams,\n estimateCollateralRequired,\n getAccountCollateral,\n getAccountGreeks,\n getAccountPremia,\n getAccountSummaryBasic,\n getAccountSummaryRisk,\n getCollateralData,\n getCurrentRates,\n getFactoryConstructMetadata,\n getFactoryOwnerOf,\n getFactoryTokenURI,\n getLiquidationPrices,\n getMarginBuffer,\n getMaxPositionSize,\n getMaxWithdrawable,\n getNativeTokenPrice,\n getNetLiquidationValue,\n getOpenPositionPreview,\n getOracleState,\n getPanopticPoolAddress,\n getPool,\n getPoolLiquidities,\n getPosition,\n getPositionGreeks,\n getPositions,\n getPositionsWithPremia,\n getRequiredCreditForITM,\n getRiskParameters,\n getSafeMode,\n getUtilization,\n isLiquidatable,\n minePoolAddress,\n previewDeposit,\n previewMint,\n previewRedeem,\n previewWithdraw,\n simulateDeployNewPool,\n} from '../../reads'\nimport { getPriceHistory } from '../../reads/priceHistory'\nimport { optimizeTokenIdRiskPartners } from '../../reads/queryUtils'\nimport type { StreamiaLeg } from '../../reads/streamiaHistory'\nimport { getStreamiaHistory } from '../../reads/streamiaHistory'\nimport { getUniswapFeeHistory } from '../../reads/uniswapFeeHistory'\nimport {\n getChunkSpreads,\n getClosedPositions,\n getRealizedPnL,\n getSyncStatus,\n getTrackedPositionIds,\n getTradeHistory,\n} from '../../sync'\nimport type { PoolVersionConfig } from '../../types/poolConfig'\nimport { interpolateBlocks } from '../../utils/interpolateBlocks'\nimport { getAtTickCacheKey, getClientCacheScopeKey, getStorageCacheScopeKey } from '../cacheScopes'\nimport { usePanopticContext, useRequireStorage } from '../provider'\nimport { queryKeys } from '../queryKeys'\n\n/**\n * Common query options exposed to consumers.\n */\nexport interface QueryOptions {\n /** Whether the query is enabled */\n enabled?: boolean\n /** Refetch interval in milliseconds */\n refetchInterval?: number\n}\n\n// --- Pool reads ---\n\nexport function usePool(poolAddress: Address, options?: QueryOptions) {\n const { publicClient, chainId, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.pool(chainId, poolAddress),\n getClientCacheScopeKey(publicClient, clientScope),\n ],\n queryFn: () => getPool({ client: publicClient, poolAddress, chainId }),\n enabled: options?.enabled,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useUtilization(poolAddress: Address, options?: QueryOptions) {\n const { publicClient, chainId, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.utilization(chainId, poolAddress),\n getClientCacheScopeKey(publicClient, clientScope),\n ],\n queryFn: () => getUtilization({ client: publicClient, poolAddress }),\n enabled: options?.enabled,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useOracleState(poolAddress: Address, options?: QueryOptions) {\n const { publicClient, chainId, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.oracle(chainId, poolAddress),\n getClientCacheScopeKey(publicClient, clientScope),\n ],\n queryFn: () => getOracleState({ client: publicClient, poolAddress }),\n enabled: options?.enabled,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useRiskParameters(poolAddress: Address, options?: QueryOptions) {\n const { publicClient, chainId, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.riskParameters(chainId, poolAddress),\n getClientCacheScopeKey(publicClient, clientScope),\n ],\n queryFn: () => getRiskParameters({ client: publicClient, poolAddress }),\n enabled: options?.enabled,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useCurrentRates(poolAddress: Address, options?: QueryOptions) {\n const { publicClient, chainId, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.rates(chainId, poolAddress),\n getClientCacheScopeKey(publicClient, clientScope),\n ],\n queryFn: () => getCurrentRates({ client: publicClient, poolAddress }),\n enabled: options?.enabled,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useSafeMode(poolAddress: Address, options?: QueryOptions) {\n const { publicClient, chainId, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.safeMode(chainId, poolAddress),\n getClientCacheScopeKey(publicClient, clientScope),\n ],\n queryFn: () => getSafeMode({ client: publicClient, poolAddress }),\n enabled: options?.enabled,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useCollateralData(poolAddress: Address, tokenIndex: 0 | 1, options?: QueryOptions) {\n const { publicClient, chainId, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.collateralData(chainId, poolAddress),\n getClientCacheScopeKey(publicClient, clientScope),\n tokenIndex,\n ],\n queryFn: () => getCollateralData({ client: publicClient, poolAddress, tokenIndex }),\n enabled: options?.enabled,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function usePoolLiquidities(\n poolAddress: Address,\n params: { queryAddress: Address; startTick: bigint; nTicks: bigint },\n options?: QueryOptions,\n) {\n const { publicClient, chainId, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.poolLiquidities(chainId, poolAddress),\n getClientCacheScopeKey(publicClient, clientScope),\n params.queryAddress,\n params.startTick,\n params.nTicks,\n ],\n queryFn: () =>\n getPoolLiquidities({\n client: publicClient,\n poolAddress,\n queryAddress: params.queryAddress,\n startTick: params.startTick,\n nTicks: params.nTicks,\n }),\n enabled: options?.enabled,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useChunkSpreads(\n poolAddress: Address,\n params: { sfpmAddress: Address },\n options?: QueryOptions,\n) {\n const { publicClient, chainId, clientScope, storageScope } = usePanopticContext()\n const storage = useRequireStorage()\n return useQuery({\n queryKey: [\n ...queryKeys.chunkSpreads(chainId, poolAddress),\n getClientCacheScopeKey(publicClient, clientScope),\n params.sfpmAddress,\n getStorageCacheScopeKey(storage, storageScope),\n ],\n queryFn: () =>\n getChunkSpreads({\n client: publicClient,\n chainId,\n poolAddress,\n sfpmAddress: params.sfpmAddress,\n storage,\n }),\n enabled: options?.enabled,\n refetchInterval: options?.refetchInterval,\n })\n}\n\n// --- Position reads ---\n\nexport function usePosition(\n poolAddress: Address,\n owner: Address,\n tokenId: bigint,\n options?: QueryOptions,\n) {\n const { publicClient, chainId, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.position(chainId, poolAddress, tokenId),\n getClientCacheScopeKey(publicClient, clientScope),\n owner,\n ],\n queryFn: () => getPosition({ client: publicClient, poolAddress, owner, tokenId }),\n enabled: options?.enabled,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function usePositions(\n poolAddress: Address,\n tokenIds: bigint[],\n owner?: Address,\n options?: QueryOptions,\n) {\n const ctx = usePanopticContext()\n const resolvedOwner = owner ?? ctx.account\n return useQuery({\n queryKey: [\n ...queryKeys.positions(ctx.chainId, poolAddress, resolvedOwner ?? ('' as Address)),\n getClientCacheScopeKey(ctx.publicClient, ctx.clientScope),\n tokenIds,\n ],\n queryFn: () => {\n if (!resolvedOwner) throw new Error('owner required for getPositions')\n return getPositions({ client: ctx.publicClient, poolAddress, owner: resolvedOwner, tokenIds })\n },\n enabled: (options?.enabled ?? true) && !!resolvedOwner,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function usePositionGreeks(\n poolAddress: Address,\n tokenId: bigint,\n owner: Address,\n options?: QueryOptions,\n) {\n const { publicClient, chainId, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.positionGreeks(chainId, poolAddress, tokenId),\n getClientCacheScopeKey(publicClient, clientScope),\n owner,\n ],\n queryFn: () => getPositionGreeks({ client: publicClient, poolAddress, tokenId, owner }),\n enabled: options?.enabled,\n refetchInterval: options?.refetchInterval,\n })\n}\n\n// --- Account reads ---\n\nexport function useAccountCollateral(\n poolAddress: Address,\n account?: Address,\n options?: QueryOptions,\n) {\n const ctx = usePanopticContext()\n const resolvedAccount = account ?? ctx.account\n return useQuery({\n queryKey: [\n ...queryKeys.accountCollateral(ctx.chainId, poolAddress, resolvedAccount ?? ('' as Address)),\n getClientCacheScopeKey(ctx.publicClient, ctx.clientScope),\n ],\n queryFn: () => {\n if (!resolvedAccount) throw new Error('account required for getAccountCollateral')\n return getAccountCollateral({\n client: ctx.publicClient,\n poolAddress,\n account: resolvedAccount,\n })\n },\n enabled: (options?.enabled ?? true) && !!resolvedAccount,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useAccountSummaryBasic(\n poolAddress: Address,\n tokenIds: bigint[],\n account?: Address,\n options?: QueryOptions,\n) {\n const ctx = usePanopticContext()\n const resolvedAccount = account ?? ctx.account\n return useQuery({\n queryKey: [\n ...queryKeys.accountSummaryBasic(\n ctx.chainId,\n poolAddress,\n resolvedAccount ?? ('' as Address),\n ),\n getClientCacheScopeKey(ctx.publicClient, ctx.clientScope),\n tokenIds,\n ],\n queryFn: () => {\n if (!resolvedAccount) throw new Error('account required for getAccountSummaryBasic')\n return getAccountSummaryBasic({\n client: ctx.publicClient,\n poolAddress,\n account: resolvedAccount,\n chainId: ctx.chainId,\n tokenIds,\n })\n },\n enabled: (options?.enabled ?? true) && !!resolvedAccount,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useAccountSummaryRisk(\n poolAddress: Address,\n tokenIds: bigint[],\n queryAddress: Address,\n account?: Address,\n options?: QueryOptions & { atTick?: bigint; includePendingPremium?: boolean },\n) {\n const ctx = usePanopticContext()\n const resolvedAccount = account ?? ctx.account\n return useQuery({\n queryKey: [\n ...queryKeys.accountSummaryRisk(ctx.chainId, poolAddress, resolvedAccount!),\n getClientCacheScopeKey(ctx.publicClient, ctx.clientScope),\n tokenIds,\n queryAddress,\n options?.atTick,\n options?.includePendingPremium,\n ],\n queryFn: () =>\n getAccountSummaryRisk({\n client: ctx.publicClient,\n poolAddress,\n account: resolvedAccount!,\n chainId: ctx.chainId,\n tokenIds,\n queryAddress,\n atTick: options?.atTick,\n includePendingPremium: options?.includePendingPremium,\n }),\n enabled: (options?.enabled ?? true) && !!resolvedAccount,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useNetLiquidationValue(\n poolAddress: Address,\n tokenIds: bigint[],\n queryAddress: Address,\n account?: Address,\n options?: QueryOptions & { atTick?: bigint },\n) {\n const ctx = usePanopticContext()\n const resolvedAccount = account ?? ctx.account\n return useQuery({\n queryKey: [\n ...queryKeys.all,\n 'netLiquidationValue',\n ctx.chainId.toString(),\n poolAddress,\n resolvedAccount!,\n getAtTickCacheKey(options?.atTick),\n getClientCacheScopeKey(ctx.publicClient, ctx.clientScope),\n tokenIds,\n queryAddress,\n ],\n queryFn: () =>\n getNetLiquidationValue({\n client: ctx.publicClient,\n poolAddress,\n account: resolvedAccount!,\n tokenIds,\n atTick: options?.atTick,\n queryAddress,\n }),\n enabled: (options?.enabled ?? true) && !!resolvedAccount,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useLiquidationPrices(\n poolAddress: Address,\n tokenIds: bigint[],\n queryAddress: Address,\n account?: Address,\n options?: QueryOptions,\n) {\n const ctx = usePanopticContext()\n const resolvedAccount = account ?? ctx.account\n return useQuery({\n queryKey: [\n ...queryKeys.liquidationPrices(ctx.chainId, poolAddress, resolvedAccount!),\n getClientCacheScopeKey(ctx.publicClient, ctx.clientScope),\n tokenIds,\n queryAddress,\n ],\n queryFn: () =>\n getLiquidationPrices({\n client: ctx.publicClient,\n poolAddress,\n account: resolvedAccount!,\n tokenIds,\n queryAddress,\n }),\n enabled: (options?.enabled ?? true) && !!resolvedAccount,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useAccountGreeks(poolAddress: Address, account?: Address, options?: QueryOptions) {\n const ctx = usePanopticContext()\n const storage = useRequireStorage()\n const resolvedAccount = account ?? ctx.account\n return useQuery({\n queryKey: [\n ...queryKeys.accountGreeks(ctx.chainId, poolAddress, resolvedAccount!),\n getClientCacheScopeKey(ctx.publicClient, ctx.clientScope),\n getStorageCacheScopeKey(storage, ctx.storageScope),\n ],\n queryFn: () =>\n getAccountGreeks({\n client: ctx.publicClient,\n chainId: ctx.chainId,\n poolAddress,\n account: resolvedAccount!,\n storage,\n }),\n enabled: (options?.enabled ?? true) && !!resolvedAccount,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useMarginBuffer(\n poolAddress: Address,\n tokenIds: bigint[],\n queryAddress: Address,\n account?: Address,\n options?: QueryOptions,\n) {\n const ctx = usePanopticContext()\n const resolvedAccount = account ?? ctx.account\n return useQuery({\n queryKey: [\n ...queryKeys.marginBuffer(ctx.chainId, poolAddress, resolvedAccount!),\n getClientCacheScopeKey(ctx.publicClient, ctx.clientScope),\n tokenIds,\n queryAddress,\n ],\n queryFn: () =>\n getMarginBuffer({\n client: ctx.publicClient,\n poolAddress,\n account: resolvedAccount!,\n tokenIds,\n queryAddress,\n }),\n enabled: (options?.enabled ?? true) && !!resolvedAccount,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useIsLiquidatable(\n poolAddress: Address,\n tokenIds: bigint[],\n queryAddress: Address,\n account?: Address,\n options?: QueryOptions,\n) {\n const ctx = usePanopticContext()\n const resolvedAccount = account ?? ctx.account\n return useQuery({\n queryKey: [\n ...queryKeys.isLiquidatable(ctx.chainId, poolAddress, resolvedAccount!),\n getClientCacheScopeKey(ctx.publicClient, ctx.clientScope),\n tokenIds,\n queryAddress,\n ],\n queryFn: () =>\n isLiquidatable({\n client: ctx.publicClient,\n poolAddress,\n account: resolvedAccount!,\n tokenIds,\n queryAddress,\n }),\n enabled: (options?.enabled ?? true) && !!resolvedAccount,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useAccountPremia(\n poolAddress: Address,\n tokenIds: bigint[],\n account?: Address,\n options?: QueryOptions,\n) {\n const ctx = usePanopticContext()\n const resolvedAccount = account ?? ctx.account\n return useQuery({\n queryKey: [\n ...queryKeys.accountPremia(ctx.chainId, poolAddress, resolvedAccount!),\n getClientCacheScopeKey(ctx.publicClient, ctx.clientScope),\n tokenIds,\n ],\n queryFn: () =>\n getAccountPremia({\n client: ctx.publicClient,\n poolAddress,\n account: resolvedAccount!,\n tokenIds,\n }),\n enabled: (options?.enabled ?? true) && !!resolvedAccount,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function usePositionsWithPremia(\n poolAddress: Address,\n tokenIds: bigint[],\n account?: Address,\n options?: QueryOptions,\n) {\n const ctx = usePanopticContext()\n const resolvedAccount = account ?? ctx.account\n return useQuery({\n queryKey: [\n ...queryKeys.positionsWithPremia(ctx.chainId, poolAddress, resolvedAccount!),\n getClientCacheScopeKey(ctx.publicClient, ctx.clientScope),\n tokenIds,\n ],\n queryFn: () =>\n getPositionsWithPremia({\n client: ctx.publicClient,\n poolAddress,\n account: resolvedAccount!,\n tokenIds,\n }),\n enabled: (options?.enabled ?? true) && !!resolvedAccount,\n refetchInterval: options?.refetchInterval,\n })\n}\n\n// --- ERC4626 previews ---\n\nexport function usePreviewDeposit(\n poolAddress: Address,\n tokenIndex: 0 | 1,\n amount: bigint,\n options?: QueryOptions,\n) {\n const { publicClient, chainId, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.erc4626Preview(chainId, poolAddress, 'deposit', amount),\n getClientCacheScopeKey(publicClient, clientScope),\n tokenIndex,\n ],\n queryFn: () => previewDeposit({ client: publicClient, poolAddress, tokenIndex, amount }),\n enabled: options?.enabled,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function usePreviewWithdraw(\n poolAddress: Address,\n tokenIndex: 0 | 1,\n amount: bigint,\n options?: QueryOptions,\n) {\n const { publicClient, chainId, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.erc4626Preview(chainId, poolAddress, 'withdraw', amount),\n getClientCacheScopeKey(publicClient, clientScope),\n tokenIndex,\n ],\n queryFn: () => previewWithdraw({ client: publicClient, poolAddress, tokenIndex, amount }),\n enabled: options?.enabled,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function usePreviewMint(\n poolAddress: Address,\n tokenIndex: 0 | 1,\n amount: bigint,\n options?: QueryOptions,\n) {\n const { publicClient, chainId, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.erc4626Preview(chainId, poolAddress, 'mint', amount),\n getClientCacheScopeKey(publicClient, clientScope),\n tokenIndex,\n ],\n queryFn: () => previewMint({ client: publicClient, poolAddress, tokenIndex, amount }),\n enabled: options?.enabled,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function usePreviewRedeem(\n poolAddress: Address,\n tokenIndex: 0 | 1,\n amount: bigint,\n options?: QueryOptions,\n) {\n const { publicClient, chainId, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.erc4626Preview(chainId, poolAddress, 'redeem', amount),\n getClientCacheScopeKey(publicClient, clientScope),\n tokenIndex,\n ],\n queryFn: () => previewRedeem({ client: publicClient, poolAddress, tokenIndex, amount }),\n enabled: options?.enabled,\n refetchInterval: options?.refetchInterval,\n })\n}\n\n// --- Collateral estimation ---\n\nexport function useEstimateCollateralRequired(\n poolAddress: Address,\n tokenId: bigint,\n positionSize: bigint,\n queryAddress: Address,\n account?: Address,\n options?: QueryOptions & { atTick?: bigint },\n) {\n const ctx = usePanopticContext()\n const resolvedAccount = account ?? ctx.account\n return useQuery({\n queryKey: [\n ...queryKeys.collateralEstimate(ctx.chainId, poolAddress, resolvedAccount!, tokenId),\n getClientCacheScopeKey(ctx.publicClient, ctx.clientScope),\n positionSize,\n queryAddress,\n options?.atTick,\n ],\n queryFn: () =>\n estimateCollateralRequired({\n client: ctx.publicClient,\n poolAddress,\n account: resolvedAccount!,\n tokenId,\n positionSize,\n queryAddress,\n atTick: options?.atTick,\n }),\n enabled: (options?.enabled ?? true) && !!resolvedAccount,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useRequiredCreditForITM(\n poolAddress: Address,\n tokenId: bigint,\n positionSize: bigint,\n account?: Address,\n options?: QueryOptions & { existingPositionIds?: bigint[] },\n) {\n const ctx = usePanopticContext()\n const resolvedAccount = account ?? ctx.account\n return useQuery({\n queryKey: [\n ...queryKeys.requiredCreditForITM(\n ctx.chainId,\n poolAddress,\n resolvedAccount ?? ('' as Address),\n tokenId,\n ),\n getClientCacheScopeKey(ctx.publicClient, ctx.clientScope),\n positionSize,\n options?.existingPositionIds,\n ],\n queryFn: () => {\n if (!resolvedAccount) throw new Error('account required for getRequiredCreditForITM')\n return getRequiredCreditForITM({\n client: ctx.publicClient,\n poolAddress,\n account: resolvedAccount,\n tokenId,\n positionSize,\n existingPositionIds: options?.existingPositionIds,\n })\n },\n enabled: (options?.enabled ?? true) && !!resolvedAccount && tokenId !== 0n && positionSize > 0n,\n refetchInterval: options?.refetchInterval,\n placeholderData: keepPreviousData,\n })\n}\n\nexport function useMaxPositionSize(\n poolAddress: Address,\n tokenId: bigint,\n queryAddress: Address,\n account?: Address,\n options?: QueryOptions & {\n existingPositionIds?: bigint[]\n swapAtMint?: boolean\n precisionPct?: number\n },\n) {\n const ctx = usePanopticContext()\n const resolvedAccount = account ?? ctx.account\n return useQuery({\n queryKey: [\n ...queryKeys.maxPositionSize(\n ctx.chainId,\n poolAddress,\n resolvedAccount ?? ('' as Address),\n tokenId,\n ),\n getClientCacheScopeKey(ctx.publicClient, ctx.clientScope),\n queryAddress,\n options?.existingPositionIds?.map(String).join(',') ?? '',\n options?.existingPositionIds,\n options?.swapAtMint ?? false,\n options?.precisionPct ?? 1,\n ],\n queryFn: () => {\n if (!resolvedAccount) throw new Error('account required for getMaxPositionSize')\n return getMaxPositionSize({\n client: ctx.publicClient,\n poolAddress,\n account: resolvedAccount,\n tokenId,\n queryAddress,\n existingPositionIds: options?.existingPositionIds,\n swapAtMint: options?.swapAtMint,\n precisionPct: options?.precisionPct,\n })\n },\n enabled: (options?.enabled ?? true) && !!resolvedAccount,\n refetchInterval: options?.refetchInterval,\n placeholderData: keepPreviousData,\n })\n}\n\nexport function useOptimizeRiskPartners(\n poolAddress: Address,\n tokenId: bigint,\n queryAddress: Address,\n atTick?: bigint,\n options?: QueryOptions,\n) {\n const { publicClient, chainId, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.optimizeRiskPartners(chainId, poolAddress, tokenId),\n getClientCacheScopeKey(publicClient, clientScope),\n queryAddress,\n getAtTickCacheKey(atTick),\n ],\n queryFn: () =>\n optimizeTokenIdRiskPartners({\n client: publicClient,\n poolAddress,\n tokenId,\n queryAddress,\n atTick,\n }),\n enabled: options?.enabled,\n refetchInterval: options?.refetchInterval,\n placeholderData: keepPreviousData,\n })\n}\n\nexport function useMaxWithdrawable(\n collateralTrackerAddress: Address,\n positionIdList: bigint[],\n totalAssets: bigint,\n account?: Address,\n options?: QueryOptions & { client?: PublicClient },\n) {\n const ctx = usePanopticContext()\n const client = options?.client ?? ctx.publicClient\n const resolvedAccount = account ?? ctx.account\n return useQuery({\n queryKey: [\n ...queryKeys.maxWithdrawable(\n ctx.chainId,\n collateralTrackerAddress,\n positionIdList,\n totalAssets,\n resolvedAccount ?? ('' as Address),\n ),\n getClientCacheScopeKey(client, ctx.clientScope),\n ],\n queryFn: () => {\n if (!resolvedAccount) throw new Error('account required for getMaxWithdrawable')\n return getMaxWithdrawable({\n client,\n collateralTrackerAddress,\n account: resolvedAccount,\n positionIdList,\n totalAssets,\n })\n },\n enabled: (options?.enabled ?? true) && !!resolvedAccount && totalAssets > 0n,\n refetchInterval: options?.refetchInterval,\n })\n}\n\n// --- Open position preview ---\n\nexport function useOpenPositionPreview(\n poolAddress: Address,\n account: Address | undefined,\n existingPositionIds: bigint[],\n tokenId: bigint,\n positionSize: bigint,\n queryAddress: Address,\n tickLimitLow: bigint,\n tickLimitHigh: bigint,\n options?: QueryOptions & {\n spreadLimit?: bigint\n swapAtMint?: boolean\n usePremiaAsCollateral?: boolean\n },\n) {\n const ctx = usePanopticContext()\n const resolvedAccount = account ?? ctx.account\n return useQuery({\n // eslint-disable-next-line @tanstack/query/exhaustive-deps -- deps serialized as strings\n queryKey: [\n ...queryKeys.all,\n 'openPositionPreview',\n ctx.chainId.toString(),\n poolAddress,\n resolvedAccount!,\n getClientCacheScopeKey(ctx.publicClient, ctx.clientScope),\n tokenId.toString(),\n positionSize.toString(),\n existingPositionIds.map(String).join(','),\n queryAddress,\n tickLimitLow.toString(),\n tickLimitHigh.toString(),\n options?.spreadLimit?.toString(),\n options?.swapAtMint,\n options?.usePremiaAsCollateral,\n ],\n queryFn: () =>\n getOpenPositionPreview({\n client: ctx.publicClient,\n poolAddress,\n account: resolvedAccount!,\n existingPositionIds,\n tokenId,\n positionSize,\n queryAddress,\n tickLimitLow,\n tickLimitHigh,\n spreadLimit: options?.spreadLimit,\n swapAtMint: options?.swapAtMint,\n usePremiaAsCollateral: options?.usePremiaAsCollateral,\n chainId: ctx.chainId,\n }),\n enabled: (options?.enabled ?? true) && !!resolvedAccount && tokenId !== 0n,\n staleTime: 0,\n })\n}\n\n// --- Storage-backed reads ---\n\nexport function useTrackedPositionIds(\n poolAddress: Address,\n account?: Address,\n options?: QueryOptions,\n) {\n const ctx = usePanopticContext()\n const storage = useRequireStorage()\n const resolvedAccount = account ?? ctx.account\n return useQuery({\n queryKey: [\n ...queryKeys.trackedPositionIds(ctx.chainId, poolAddress, resolvedAccount!),\n getStorageCacheScopeKey(storage, ctx.storageScope),\n ],\n queryFn: () =>\n getTrackedPositionIds({\n chainId: ctx.chainId,\n poolAddress,\n account: resolvedAccount!,\n storage,\n }),\n enabled: (options?.enabled ?? true) && !!resolvedAccount,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useTradeHistory(poolAddress: Address, account?: Address, options?: QueryOptions) {\n const ctx = usePanopticContext()\n const storage = useRequireStorage()\n const resolvedAccount = account ?? ctx.account\n return useQuery({\n queryKey: [\n ...queryKeys.tradeHistory(ctx.chainId, poolAddress, resolvedAccount!),\n getStorageCacheScopeKey(storage, ctx.storageScope),\n ],\n queryFn: () =>\n getTradeHistory({ chainId: ctx.chainId, poolAddress, account: resolvedAccount!, storage }),\n enabled: (options?.enabled ?? true) && !!resolvedAccount,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useRealizedPnL(poolAddress: Address, account?: Address, options?: QueryOptions) {\n const ctx = usePanopticContext()\n const storage = useRequireStorage()\n const resolvedAccount = account ?? ctx.account\n return useQuery({\n queryKey: [\n ...queryKeys.realizedPnL(ctx.chainId, poolAddress, resolvedAccount!),\n getStorageCacheScopeKey(storage, ctx.storageScope),\n ],\n queryFn: () =>\n getRealizedPnL({ chainId: ctx.chainId, poolAddress, account: resolvedAccount!, storage }),\n enabled: (options?.enabled ?? true) && !!resolvedAccount,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useClosedPositions(\n poolAddress: Address,\n account?: Address,\n options?: QueryOptions,\n) {\n const ctx = usePanopticContext()\n const storage = useRequireStorage()\n const resolvedAccount = account ?? ctx.account\n return useQuery({\n queryKey: [\n ...queryKeys.closedPositions(ctx.chainId, poolAddress, resolvedAccount!),\n getStorageCacheScopeKey(storage, ctx.storageScope),\n ],\n queryFn: () =>\n getClosedPositions({ chainId: ctx.chainId, poolAddress, account: resolvedAccount!, storage }),\n enabled: (options?.enabled ?? true) && !!resolvedAccount,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useSyncStatus(poolAddress: Address, account?: Address, options?: QueryOptions) {\n const ctx = usePanopticContext()\n const storage = useRequireStorage()\n const resolvedAccount = account ?? ctx.account\n return useQuery({\n queryKey: [\n ...queryKeys.syncStatus(ctx.chainId, poolAddress, resolvedAccount!),\n getClientCacheScopeKey(ctx.publicClient, ctx.clientScope),\n getStorageCacheScopeKey(storage, ctx.storageScope),\n ],\n queryFn: () =>\n getSyncStatus({\n client: ctx.publicClient,\n chainId: ctx.chainId,\n poolAddress,\n account: resolvedAccount!,\n storage,\n }),\n enabled: (options?.enabled ?? true) && !!resolvedAccount,\n refetchInterval: options?.refetchInterval,\n })\n}\n\n// --- Factory reads ---\n\ntype OmitFactoryClient<T> = Omit<T, 'client'>\n\nexport function usePanopticPoolAddress(\n params?: OmitFactoryClient<GetPanopticPoolAddressParams>,\n options?: QueryOptions,\n) {\n const { publicClient, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.all,\n 'factory',\n 'getPanopticPool',\n params?.factoryAddress,\n getClientCacheScopeKey(publicClient, clientScope),\n params,\n ] as const,\n queryFn: () => getPanopticPoolAddress({ client: publicClient, ...params! }),\n enabled: (options?.enabled ?? true) && params !== undefined,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useFactoryTokenURI(\n params?: OmitFactoryClient<GetFactoryTokenURIParams>,\n options?: QueryOptions,\n) {\n const { publicClient, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.all,\n 'factory',\n 'tokenURI',\n params?.factoryAddress,\n params?.tokenId?.toString(),\n getClientCacheScopeKey(publicClient, clientScope),\n params,\n ] as const,\n queryFn: () => getFactoryTokenURI({ client: publicClient, ...params! }),\n enabled: (options?.enabled ?? true) && params !== undefined,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useFactoryOwnerOf(\n params?: OmitFactoryClient<GetFactoryOwnerOfParams>,\n options?: QueryOptions,\n) {\n const { publicClient, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.all,\n 'factory',\n 'ownerOf',\n params?.factoryAddress,\n params?.tokenId?.toString(),\n getClientCacheScopeKey(publicClient, clientScope),\n params,\n ] as const,\n queryFn: () => getFactoryOwnerOf({ client: publicClient, ...params! }),\n enabled: (options?.enabled ?? true) && params !== undefined,\n refetchInterval: options?.refetchInterval,\n })\n}\n\ntype OmitMineClient<T> = Omit<T, 'client'>\n\nexport function useMinePoolAddress() {\n const { publicClient } = usePanopticContext()\n return useMutation({\n mutationFn: (params: OmitMineClient<MinePoolAddressParams>) =>\n minePoolAddress({ client: publicClient, ...params }),\n })\n}\n\nexport function useFactoryConstructMetadata(\n params?: OmitFactoryClient<GetFactoryConstructMetadataParams>,\n options?: QueryOptions,\n) {\n const { publicClient, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.all,\n 'factory',\n 'constructMetadata',\n params?.factoryAddress,\n params?.panopticPoolAddress,\n params?.symbol0,\n params?.symbol1,\n params?.fee?.toString(),\n getClientCacheScopeKey(publicClient, clientScope),\n params,\n ] as const,\n queryFn: () => getFactoryConstructMetadata({ client: publicClient, ...params! }),\n enabled: (options?.enabled ?? true) && params !== undefined,\n refetchInterval: options?.refetchInterval,\n })\n}\n\nexport function useSimulateDeployNewPool(\n params?: OmitMineClient<SimulateDeployNewPoolParams>,\n options?: QueryOptions,\n) {\n const { publicClient, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.all,\n 'factory',\n 'simulateDeployNewPool',\n params?.factoryAddress,\n params?.account,\n params?.salt?.toString(),\n getClientCacheScopeKey(publicClient, clientScope),\n params,\n ] as const,\n queryFn: () => simulateDeployNewPool({ client: publicClient, ...params! }),\n enabled: (options?.enabled ?? true) && params !== undefined,\n refetchInterval: options?.refetchInterval,\n })\n}\n\n// --- Price history ---\n\n/** Timestamp-based time range. Start/end resolved to blocks via RPC binary search. */\nexport interface TimestampTimeRange {\n mode: 'timestamps'\n /** Start of the range (Unix seconds) */\n startTimestamp: number\n /** End of the range (Unix seconds). Defaults to now if omitted. */\n endTimestamp?: number\n /** Number of evenly-spaced data points to fetch */\n points: number\n}\n\n/** Block-based time range. No RPC resolution needed. */\nexport interface BlockTimeRange {\n mode: 'blocks'\n /** Start block number */\n startBlock: bigint\n /** End block number. Defaults to latest if omitted. */\n endBlock?: bigint\n /** Number of evenly-spaced data points to fetch */\n points: number\n}\n\nexport type PriceHistoryTimeRange = TimestampTimeRange | BlockTimeRange\n\n/**\n * Build a stable string cache key from time range params (no object references).\n */\nfunction buildRangeHash(timeRange: PriceHistoryTimeRange): string {\n return timeRange.mode === 'timestamps'\n ? `ts:${timeRange.startTimestamp}-${timeRange.endTimestamp ?? 'now'}-${timeRange.points}`\n : `blk:${timeRange.startBlock}-${timeRange.endBlock ?? 'latest'}-${timeRange.points}`\n}\n\n/**\n * Resolve a PriceHistoryTimeRange to start/end block numbers.\n */\nasync function resolveTimeRange(\n client: PublicClient,\n timeRange: PriceHistoryTimeRange,\n): Promise<{ startBlock: bigint; endBlock: bigint }> {\n if (timeRange.mode === 'timestamps') {\n if (timeRange.endTimestamp !== undefined) {\n const resolved = await resolveBlockNumbers({\n client,\n timestamps: [timeRange.startTimestamp, timeRange.endTimestamp],\n })\n return { startBlock: resolved[0], endBlock: resolved[1] }\n } else {\n const [resolved, latest] = await Promise.all([\n resolveBlockNumbers({ client, timestamps: [timeRange.startTimestamp] }),\n client.getBlockNumber(),\n ])\n return { startBlock: resolved[0], endBlock: latest }\n }\n } else {\n return {\n startBlock: timeRange.startBlock,\n endBlock: timeRange.endBlock ?? (await client.getBlockNumber()),\n }\n }\n}\n\n/**\n * Hook to fetch historical price data (tick + sqrtPriceX96) for a pool.\n *\n * Supports two modes:\n * - **timestamps**: Resolves start/end timestamps to blocks (2 RPC binary searches),\n * then interpolates the blocks in between (pure math).\n * - **blocks**: Uses start/end blocks directly, interpolates in between.\n * Zero resolution overhead.\n *\n * In both cases, the actual price reads are O(points) slot0 calls,\n * HTTP-batched by viem.\n *\n * @param poolConfig - Pool version config (V3 pool address or V4 StateView + poolId)\n * @param timeRange - Time range specification (timestamps or blocks)\n * @param options - Query options (enabled, refetchInterval)\n */\nexport function usePriceHistory(\n poolConfig: PoolVersionConfig,\n timeRange: PriceHistoryTimeRange,\n options?: QueryOptions,\n) {\n const { publicClient, chainId, clientScope } = usePanopticContext()\n\n const poolKey = poolConfig.version === 'v3' ? poolConfig.poolAddress : poolConfig.poolId\n const rangeHash = buildRangeHash(timeRange)\n\n return useQuery({\n // rangeHash serializes timeRange; poolKey serializes poolConfig\n // eslint-disable-next-line @tanstack/query/exhaustive-deps\n queryKey: [\n ...queryKeys.priceHistory(chainId, poolKey, rangeHash),\n getClientCacheScopeKey(publicClient, clientScope),\n ],\n queryFn: async () => {\n const { startBlock, endBlock } = await resolveTimeRange(publicClient, timeRange)\n const blockNumbers = interpolateBlocks(startBlock, endBlock, timeRange.points)\n return getPriceHistory({ client: publicClient, blockNumbers, poolConfig })\n },\n enabled: (options?.enabled ?? true) && timeRange.points > 0,\n refetchInterval: options?.refetchInterval,\n })\n}\n\n/**\n * Hook to fetch historical streamia (streaming premia + Uniswap fee) data for a position.\n *\n * @param panopticPoolAddress - PanopticPool contract address\n * @param account - Account whose position to query\n * @param tokenId - The encoded tokenId\n * @param legs - Decoded legs with pre-computed liquidity\n * @param poolConfig - Pool version config (V3 pool address or V4 StateView + poolId)\n * @param timeRange - Time range specification (timestamps or blocks)\n * @param options - Query options + optional includeUniswapFees and settledEvents\n */\nexport function useStreamiaHistory(\n panopticPoolAddress: Address,\n account: Address,\n tokenId: bigint,\n legs: StreamiaLeg[],\n poolConfig: PoolVersionConfig,\n timeRange: PriceHistoryTimeRange,\n options?: QueryOptions & {\n includeUniswapFees?: boolean\n settledEvents?: Array<{ blockNumber: bigint; settled0: bigint; settled1: bigint }>\n },\n) {\n const { publicClient, chainId, clientScope } = usePanopticContext()\n\n const poolKey = poolConfig.version === 'v3' ? poolConfig.poolAddress : poolConfig.poolId\n const rangeHash = buildRangeHash(timeRange)\n\n const legsKey = legs.map((l) => `${l.lowerTick}:${l.upperTick}:${l.liquidity}`).join(',')\n const includeUniswapFees = options?.includeUniswapFees ?? true\n const settledEventsKey = options?.settledEvents\n ? options.settledEvents.map((e) => `${e.blockNumber}:${e.settled0}:${e.settled1}`).join(',')\n : ''\n\n return useQuery({\n // rangeHash serializes timeRange; poolKey serializes poolConfig; legsKey serializes legs\n // eslint-disable-next-line @tanstack/query/exhaustive-deps\n queryKey: [\n ...queryKeys.streamiaHistory(chainId, poolKey, rangeHash),\n getClientCacheScopeKey(publicClient, clientScope),\n panopticPoolAddress,\n account,\n tokenId.toString(),\n legsKey,\n includeUniswapFees,\n settledEventsKey,\n ],\n queryFn: async () => {\n const { startBlock, endBlock } = await resolveTimeRange(publicClient, timeRange)\n const blockNumbers = interpolateBlocks(startBlock, endBlock, timeRange.points)\n return getStreamiaHistory({\n client: publicClient,\n panopticPoolAddress,\n account,\n tokenId,\n blockNumbers,\n legs,\n poolConfig,\n includeUniswapFees: options?.includeUniswapFees,\n settledEvents: options?.settledEvents,\n })\n },\n enabled: (options?.enabled ?? true) && timeRange.points > 0,\n refetchInterval: options?.refetchInterval,\n })\n}\n\n/**\n * Hook to fetch historical Uniswap fee data for a set of liquidity legs.\n *\n * @param legs - Decoded legs with pre-computed liquidity\n * @param poolConfig - Pool version config (V3 pool address or V4 StateView + poolId)\n * @param timeRange - Time range specification (timestamps or blocks)\n * @param options - Query options (enabled, refetchInterval)\n */\nexport function useUniswapFeeHistory(\n legs: StreamiaLeg[],\n poolConfig: PoolVersionConfig,\n timeRange: PriceHistoryTimeRange,\n options?: QueryOptions,\n) {\n const { publicClient, chainId, clientScope } = usePanopticContext()\n\n const poolKey = poolConfig.version === 'v3' ? poolConfig.poolAddress : poolConfig.poolId\n const rangeHash = buildRangeHash(timeRange)\n\n const legsKey = legs.map((l) => `${l.lowerTick}:${l.upperTick}:${l.liquidity}`).join(',')\n\n return useQuery({\n // rangeHash serializes timeRange; poolKey serializes poolConfig; legsKey serializes legs\n // eslint-disable-next-line @tanstack/query/exhaustive-deps\n queryKey: [\n ...queryKeys.uniswapFeeHistory(chainId, poolKey, rangeHash),\n getClientCacheScopeKey(publicClient, clientScope),\n legsKey,\n ],\n queryFn: async () => {\n const { startBlock, endBlock } = await resolveTimeRange(publicClient, timeRange)\n const blockNumbers = interpolateBlocks(startBlock, endBlock, timeRange.points)\n return getUniswapFeeHistory({ client: publicClient, blockNumbers, legs, poolConfig })\n },\n enabled: (options?.enabled ?? true) && timeRange.points > 0 && legs.length > 0,\n refetchInterval: options?.refetchInterval,\n })\n}\n\n// --- Native token price ---\n\nexport function useNativeTokenPrice(\n panopticPoolAddress: Address | undefined,\n token0Decimals: bigint,\n token1Decimals: bigint,\n nativeIsToken0: boolean,\n options?: QueryOptions,\n) {\n const { publicClient, chainId, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.all,\n 'nativeTokenPrice',\n chainId,\n panopticPoolAddress,\n token0Decimals,\n token1Decimals,\n nativeIsToken0,\n getClientCacheScopeKey(publicClient, clientScope),\n ],\n queryFn: () =>\n getNativeTokenPrice({\n client: publicClient,\n panopticPoolAddress: panopticPoolAddress!,\n token0Decimals,\n token1Decimals,\n nativeIsToken0,\n }),\n enabled: (options?.enabled ?? true) && panopticPoolAddress !== undefined,\n refetchInterval: options?.refetchInterval ?? 30_000,\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 { collateralTrackerAbi, panopticPoolAbi } 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: panopticPoolAbi,\n functionName: 'collateralToken0',\n },\n {\n address: poolAddress,\n abi: panopticPoolAbi,\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: collateralTrackerAbi,\n functionName: 'asset',\n },\n {\n address: collateralToken1,\n abi: collateralTrackerAbi,\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 { collateralTrackerAbi } 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: collateralTrackerAbi,\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: collateralTrackerAbi,\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: collateralTrackerAbi,\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: collateralTrackerAbi,\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: collateralTrackerAbi,\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, PublicClient, WalletClient } from 'viem'\n\nimport { panopticPoolAbi } 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: panopticPoolAbi,\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 * 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: panopticPoolAbi,\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: panopticPoolAbi,\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 { panopticPoolAbi } 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: panopticPoolAbi,\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 * Liquidation functions for the Panoptic v2 SDK.\n * @module v2/writes/liquidate\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport { panopticPoolAbi } 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: panopticPoolAbi,\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 { panopticPoolAbi } from '../../../generated'\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}\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: panopticPoolAbi,\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 */\nexport async function forceExerciseAndWait(params: ForceExerciseParams): Promise<TxReceipt> {\n const result = await forceExercise(params)\n return result.wait()\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 { panopticPoolAbi } 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: panopticPoolAbi,\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 { panopticPoolAbi } from '../../../generated'\nimport { OracleRateLimitedError } from '../errors'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\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: panopticPoolAbi,\n functionName: 'getOracleTicks',\n }),\n client.getBlock(),\n ])\n\n // oracleData[4] is the oraclePack\n const oraclePack = oracleData[4]\n // Epoch is in bits 232-255 (24 bits)\n const epoch = oraclePack >> 232n\n\n const currentEpoch = block.timestamp / 64n\n\n // If current epoch equals oracle epoch, we can't poke yet\n if (currentEpoch <= epoch) {\n const lastUpdate = epoch * 64n\n throw new OracleRateLimitedError(lastUpdate, block.timestamp)\n }\n }\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolAbi,\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 { panopticFactoryAbi } from '../../../generated'\nimport type { PoolKey, TxOverrides, TxResult } from '../types'\nimport { submitWrite } from './utils'\n\n/**\n * Parameters for deploying a new Panoptic pool.\n */\nexport interface DeployNewPoolParams {\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 /** V4 pool key */\n poolKey: PoolKey\n /** Risk engine address */\n riskEngine: Address\n /** Salt (uint96) */\n salt: bigint\n /** Optional transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Deploy a new Panoptic pool via the factory.\n *\n * @param params - Deployment parameters\n * @returns Transaction result with hash and wait function\n */\nexport async function deployNewPool(params: DeployNewPoolParams): Promise<TxResult> {\n const { client, walletClient, account, factoryAddress, poolKey, riskEngine, salt, txOverrides } =\n params\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: factoryAddress,\n abi: panopticFactoryAbi,\n functionName: 'deployNewPool',\n args: [\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 riskEngine,\n salt,\n ],\n txOverrides,\n })\n}\n\n/**\n * Deploy a new Panoptic pool and wait for confirmation.\n *\n * @param params - Deployment parameters\n * @returns Transaction receipt\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 * Mutation effects for cache invalidation with TanStack Query / SWR.\n * @module v2/react/mutationEffects\n */\n\nimport type { Address } from 'viem'\n\nimport { queryKeys } from './queryKeys'\n\n/**\n * Mutation type identifiers.\n */\nexport type MutationType =\n | 'openPosition'\n | 'closePosition'\n | 'forceExercise'\n | 'liquidate'\n | 'settleAccumulatedPremia'\n | 'deposit'\n | 'withdraw'\n | 'mint'\n | 'redeem'\n | 'approve'\n | 'pokeOracle'\n\n/**\n * Parameters for determining which queries to invalidate.\n */\nexport interface MutationEffectParams {\n chainId: bigint\n poolAddress: Address\n account: Address\n tokenId?: bigint\n}\n\n/**\n * Returns query keys that should be invalidated after a mutation.\n *\n * Use with TanStack Query's `queryClient.invalidateQueries()` or SWR's `mutate()`.\n *\n * @example\n * ```typescript\n * import { useMutation, useQueryClient } from '@tanstack/react-query'\n * import { mutationEffects, openPosition } from 'panoptic-v2-sdk'\n *\n * function useOpenPosition(config: WriteConfig) {\n * const queryClient = useQueryClient()\n *\n * return useMutation({\n * mutationFn: (params) => openPosition(config, params),\n * onSuccess: () => {\n * const keysToInvalidate = mutationEffects.openPosition({\n * chainId: config.chainId,\n * poolAddress: config.poolAddress,\n * account: config.walletClient.account.address,\n * })\n *\n * for (const key of keysToInvalidate) {\n * queryClient.invalidateQueries({ queryKey: key })\n * }\n * },\n * })\n * }\n * ```\n */\nexport const mutationEffects = {\n /**\n * Queries to invalidate after opening a position.\n */\n openPosition: (params: MutationEffectParams): readonly (readonly string[])[] => {\n const { chainId, poolAddress, account } = params\n return [\n queryKeys.pool(chainId, poolAddress),\n queryKeys.utilization(chainId, poolAddress),\n queryKeys.positions(chainId, poolAddress, account),\n queryKeys.trackedPositionIds(chainId, poolAddress, account),\n queryKeys.accountCollateral(chainId, poolAddress, account),\n queryKeys.accountSummaryBasic(chainId, poolAddress, account),\n queryKeys.accountSummaryRisk(chainId, poolAddress, account),\n queryKeys.isLiquidatable(chainId, poolAddress, account),\n queryKeys.liquidationPrices(chainId, poolAddress, account),\n queryKeys.accountGreeks(chainId, poolAddress, account),\n queryKeys.chunkSpreads(chainId, poolAddress),\n ]\n },\n\n /**\n * Queries to invalidate after closing a position.\n */\n closePosition: (params: MutationEffectParams): readonly (readonly string[])[] => {\n const { chainId, poolAddress, account, tokenId } = params\n const keys: (readonly string[])[] = [\n queryKeys.pool(chainId, poolAddress),\n queryKeys.utilization(chainId, poolAddress),\n queryKeys.positions(chainId, poolAddress, account),\n queryKeys.trackedPositionIds(chainId, poolAddress, account),\n queryKeys.accountCollateral(chainId, poolAddress, account),\n queryKeys.accountSummaryBasic(chainId, poolAddress, account),\n queryKeys.accountSummaryRisk(chainId, poolAddress, account),\n queryKeys.isLiquidatable(chainId, poolAddress, account),\n queryKeys.liquidationPrices(chainId, poolAddress, account),\n queryKeys.accountGreeks(chainId, poolAddress, account),\n queryKeys.closedPositions(chainId, poolAddress, account),\n queryKeys.tradeHistory(chainId, poolAddress, account),\n queryKeys.realizedPnL(chainId, poolAddress, account),\n queryKeys.chunkSpreads(chainId, poolAddress),\n ]\n\n if (tokenId !== undefined) {\n keys.push(queryKeys.position(chainId, poolAddress, tokenId))\n keys.push(queryKeys.positionGreeks(chainId, poolAddress, tokenId))\n }\n\n return keys\n },\n\n /**\n * Queries to invalidate after force exercising a position.\n */\n forceExercise: (params: MutationEffectParams): readonly (readonly string[])[] => {\n const { chainId, poolAddress, account, tokenId } = params\n const keys: (readonly string[])[] = [\n queryKeys.pool(chainId, poolAddress),\n queryKeys.utilization(chainId, poolAddress),\n queryKeys.accountCollateral(chainId, poolAddress, account),\n queryKeys.accountSummaryBasic(chainId, poolAddress, account),\n queryKeys.accountSummaryRisk(chainId, poolAddress, account),\n queryKeys.chunkSpreads(chainId, poolAddress),\n ]\n\n if (tokenId !== undefined) {\n keys.push(queryKeys.position(chainId, poolAddress, tokenId))\n }\n\n return keys\n },\n\n /**\n * Queries to invalidate after liquidating an account.\n */\n liquidate: (params: MutationEffectParams): readonly (readonly string[])[] => {\n const { chainId, poolAddress, account } = params\n return [\n queryKeys.pool(chainId, poolAddress),\n queryKeys.utilization(chainId, poolAddress),\n queryKeys.positions(chainId, poolAddress, account),\n queryKeys.trackedPositionIds(chainId, poolAddress, account),\n queryKeys.accountCollateral(chainId, poolAddress, account),\n queryKeys.accountSummaryBasic(chainId, poolAddress, account),\n queryKeys.accountSummaryRisk(chainId, poolAddress, account),\n queryKeys.isLiquidatable(chainId, poolAddress, account),\n queryKeys.liquidationPrices(chainId, poolAddress, account),\n queryKeys.accountGreeks(chainId, poolAddress, account),\n queryKeys.closedPositions(chainId, poolAddress, account),\n queryKeys.chunkSpreads(chainId, poolAddress),\n ]\n },\n\n /**\n * Queries to invalidate after settling accumulated premia.\n */\n settleAccumulatedPremia: (params: MutationEffectParams): readonly (readonly string[])[] => {\n const { chainId, poolAddress, account, tokenId } = params\n const keys: (readonly string[])[] = [\n queryKeys.accountCollateral(chainId, poolAddress, account),\n queryKeys.accountSummaryBasic(chainId, poolAddress, account),\n queryKeys.accountSummaryRisk(chainId, poolAddress, account),\n ]\n\n if (tokenId !== undefined) {\n keys.push(queryKeys.position(chainId, poolAddress, tokenId))\n }\n\n return keys\n },\n\n /**\n * Queries to invalidate after depositing to collateral tracker.\n */\n deposit: (params: MutationEffectParams): readonly (readonly string[])[] => {\n const { chainId, poolAddress, account } = params\n return [\n queryKeys.accountCollateral(chainId, poolAddress, account),\n queryKeys.accountSummaryBasic(chainId, poolAddress, account),\n queryKeys.accountSummaryRisk(chainId, poolAddress, account),\n queryKeys.isLiquidatable(chainId, poolAddress, account),\n queryKeys.liquidationPrices(chainId, poolAddress, account),\n ]\n },\n\n /**\n * Queries to invalidate after withdrawing from collateral tracker.\n */\n withdraw: (params: MutationEffectParams): readonly (readonly string[])[] => {\n const { chainId, poolAddress, account } = params\n return [\n queryKeys.accountCollateral(chainId, poolAddress, account),\n queryKeys.accountSummaryBasic(chainId, poolAddress, account),\n queryKeys.accountSummaryRisk(chainId, poolAddress, account),\n queryKeys.isLiquidatable(chainId, poolAddress, account),\n queryKeys.liquidationPrices(chainId, poolAddress, account),\n ]\n },\n\n /**\n * Queries to invalidate after minting collateral shares.\n */\n mint: (params: MutationEffectParams): readonly (readonly string[])[] => {\n return mutationEffects.deposit(params)\n },\n\n /**\n * Queries to invalidate after redeeming collateral shares.\n */\n redeem: (params: MutationEffectParams): readonly (readonly string[])[] => {\n return mutationEffects.withdraw(params)\n },\n\n /**\n * Queries to invalidate after approving token spending.\n */\n approve: (\n chainId: bigint,\n token: Address,\n owner: Address,\n spender: Address,\n ): readonly (readonly string[])[] => {\n return [queryKeys.approval(chainId, token, owner, spender)]\n },\n\n /**\n * Queries to invalidate after poking the oracle.\n */\n pokeOracle: (\n params: Pick<MutationEffectParams, 'chainId' | 'poolAddress'>,\n ): readonly (readonly string[])[] => {\n const { chainId, poolAddress } = params\n return [queryKeys.oracle(chainId, poolAddress), queryKeys.safeMode(chainId, poolAddress)]\n },\n} as const\n","/**\n * TanStack Query v5 mutation hooks for the Panoptic v2 SDK.\n * @module v2/react/hooks/writes\n */\n\nimport { type QueryClient, useMutation, useQueryClient } from '@tanstack/react-query'\nimport type { Address, WalletClient } from 'viem'\n\nimport {\n type ApproveParams,\n type ApprovePoolParams,\n type ClosePositionParams,\n type DeployNewPoolParams,\n type DepositParams,\n type DispatchParams,\n type ForceExerciseParams,\n type LiquidateParams,\n type MintParams,\n type OpenPositionParams,\n type PokeOracleParams,\n type RedeemParams,\n type RollPositionParams,\n type SettleParams,\n type WithdrawParams,\n type WithdrawWithPositionsParams,\n approve,\n approvePool,\n closePosition,\n deployNewPool,\n deposit,\n dispatch,\n forceExercise,\n liquidate,\n mint,\n openPosition,\n pokeOracle,\n redeem,\n rollPosition,\n settleAccumulatedPremia,\n withdraw,\n withdrawWithPositions,\n} from '../../writes'\nimport { mutationEffects } from '../mutationEffects'\nimport { usePanopticContext } from '../provider'\nimport { queryKeys } from '../queryKeys'\n\ntype OmitInjected<T> = Omit<T, 'client' | 'walletClient' | 'account'>\ntype OmitInjectedWithPool<T> = Omit<T, 'client' | 'walletClient' | 'account' | 'poolAddress'>\n\ntype WalletInputs = {\n walletClient?: WalletClient\n account?: Address\n}\n\ntype WalletMutationContext = {\n signerAccount: Address\n}\n\nfunction requireWallet(inputs: WalletInputs): { walletClient: WalletClient; account: Address } {\n if (!inputs.walletClient || !inputs.account) {\n throw new Error('walletClient and account are required. Provide them via PanopticProvider.')\n }\n\n return {\n walletClient: inputs.walletClient,\n account: inputs.account,\n }\n}\n\nfunction createWalletMutationContext(inputs: WalletInputs): WalletMutationContext {\n return { signerAccount: requireWallet(inputs).account }\n}\n\nfunction invalidateKeys(\n queryClient: QueryClient,\n keysToInvalidate: readonly (readonly string[])[],\n): void {\n const seen = new Set<string>()\n\n for (const key of keysToInvalidate) {\n const serialized = JSON.stringify(key)\n if (seen.has(serialized)) {\n continue\n }\n\n seen.add(serialized)\n queryClient.invalidateQueries({ queryKey: key })\n }\n}\n\nexport function useApprove() {\n const { publicClient, chainId, walletClient, account } = usePanopticContext()\n const queryClient = useQueryClient()\n\n return useMutation({\n onMutate: () => createWalletMutationContext({ walletClient, account }),\n mutationFn: (params: OmitInjected<ApproveParams>) => {\n const wallet = requireWallet({ walletClient, account })\n return approve({ client: publicClient, ...wallet, ...params })\n },\n onSuccess: (_data, params, context) => {\n if (!context) {\n return\n }\n\n invalidateKeys(\n queryClient,\n mutationEffects.approve(\n chainId,\n params.tokenAddress,\n context.signerAccount,\n params.spenderAddress,\n ),\n )\n },\n })\n}\n\nexport function useApprovePool(poolAddress: Address) {\n const { publicClient, walletClient, account } = usePanopticContext()\n const queryClient = useQueryClient()\n\n return useMutation({\n onMutate: () => createWalletMutationContext({ walletClient, account }),\n mutationFn: (params: OmitInjectedWithPool<ApprovePoolParams>) => {\n const wallet = requireWallet({ walletClient, account })\n return approvePool({ client: publicClient, ...wallet, poolAddress, ...params })\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [...queryKeys.all, 'approval'] })\n },\n })\n}\n\nexport function useDeposit(poolAddress: Address) {\n const { publicClient, chainId, walletClient, account } = usePanopticContext()\n const queryClient = useQueryClient()\n\n return useMutation({\n onMutate: () => createWalletMutationContext({ walletClient, account }),\n mutationFn: (params: OmitInjected<DepositParams>) => {\n const wallet = requireWallet({ walletClient, account })\n return deposit({ client: publicClient, ...wallet, ...params })\n },\n onSuccess: (_data, _params, context) => {\n if (!context) {\n return\n }\n\n invalidateKeys(\n queryClient,\n mutationEffects.deposit({ chainId, poolAddress, account: context.signerAccount }),\n )\n },\n })\n}\n\nexport function useWithdraw(poolAddress: Address) {\n const { publicClient, chainId, walletClient, account } = usePanopticContext()\n const queryClient = useQueryClient()\n\n return useMutation({\n onMutate: () => createWalletMutationContext({ walletClient, account }),\n mutationFn: (params: OmitInjected<WithdrawParams>) => {\n const wallet = requireWallet({ walletClient, account })\n return withdraw({ client: publicClient, ...wallet, ...params })\n },\n onSuccess: (_data, _params, context) => {\n if (!context) {\n return\n }\n\n invalidateKeys(\n queryClient,\n mutationEffects.withdraw({ chainId, poolAddress, account: context.signerAccount }),\n )\n },\n })\n}\n\nexport function useMintShares(poolAddress: Address) {\n const { publicClient, chainId, walletClient, account } = usePanopticContext()\n const queryClient = useQueryClient()\n\n return useMutation({\n onMutate: () => createWalletMutationContext({ walletClient, account }),\n mutationFn: (params: OmitInjected<MintParams>) => {\n const wallet = requireWallet({ walletClient, account })\n return mint({ client: publicClient, ...wallet, ...params })\n },\n onSuccess: (_data, _params, context) => {\n if (!context) {\n return\n }\n\n invalidateKeys(\n queryClient,\n mutationEffects.mint({ chainId, poolAddress, account: context.signerAccount }),\n )\n },\n })\n}\n\nexport function useRedeem(poolAddress: Address) {\n const { publicClient, chainId, walletClient, account } = usePanopticContext()\n const queryClient = useQueryClient()\n\n return useMutation({\n onMutate: () => createWalletMutationContext({ walletClient, account }),\n mutationFn: (params: OmitInjected<RedeemParams>) => {\n const wallet = requireWallet({ walletClient, account })\n return redeem({ client: publicClient, ...wallet, ...params })\n },\n onSuccess: (_data, _params, context) => {\n if (!context) {\n return\n }\n\n invalidateKeys(\n queryClient,\n mutationEffects.redeem({ chainId, poolAddress, account: context.signerAccount }),\n )\n },\n })\n}\n\nexport function useWithdrawWithPositions(poolAddress: Address) {\n const { publicClient, chainId, walletClient, account } = usePanopticContext()\n const queryClient = useQueryClient()\n\n return useMutation({\n onMutate: () => createWalletMutationContext({ walletClient, account }),\n mutationFn: (params: OmitInjected<WithdrawWithPositionsParams>) => {\n const wallet = requireWallet({ walletClient, account })\n return withdrawWithPositions({ client: publicClient, ...wallet, ...params })\n },\n onSuccess: (_data, _params, context) => {\n if (!context) {\n return\n }\n\n invalidateKeys(\n queryClient,\n mutationEffects.withdraw({ chainId, poolAddress, account: context.signerAccount }),\n )\n },\n })\n}\n\nexport function useOpenPosition(poolAddress: Address) {\n const { publicClient, chainId, walletClient, account } = usePanopticContext()\n const queryClient = useQueryClient()\n\n return useMutation({\n onMutate: () => createWalletMutationContext({ walletClient, account }),\n mutationFn: (params: OmitInjectedWithPool<OpenPositionParams>) => {\n const wallet = requireWallet({ walletClient, account })\n return openPosition({ client: publicClient, ...wallet, poolAddress, ...params })\n },\n onSuccess: (_data, _params, context) => {\n if (!context) {\n return\n }\n\n invalidateKeys(\n queryClient,\n mutationEffects.openPosition({ chainId, poolAddress, account: context.signerAccount }),\n )\n },\n })\n}\n\nexport function useClosePosition(poolAddress: Address) {\n const { publicClient, chainId, walletClient, account } = usePanopticContext()\n const queryClient = useQueryClient()\n\n return useMutation({\n onMutate: () => createWalletMutationContext({ walletClient, account }),\n mutationFn: (params: OmitInjectedWithPool<ClosePositionParams>) => {\n const wallet = requireWallet({ walletClient, account })\n return closePosition({ client: publicClient, ...wallet, poolAddress, ...params })\n },\n onSuccess: (_data, params, context) => {\n if (!context) {\n return\n }\n\n invalidateKeys(\n queryClient,\n mutationEffects.closePosition({\n chainId,\n poolAddress,\n account: context.signerAccount,\n tokenId: params.tokenId,\n }),\n )\n },\n })\n}\n\nexport function useRollPosition(poolAddress: Address) {\n const { publicClient, chainId, walletClient, account } = usePanopticContext()\n const queryClient = useQueryClient()\n\n return useMutation({\n onMutate: () => createWalletMutationContext({ walletClient, account }),\n mutationFn: (params: OmitInjectedWithPool<RollPositionParams>) => {\n const wallet = requireWallet({ walletClient, account })\n return rollPosition({ client: publicClient, ...wallet, poolAddress, ...params })\n },\n onSuccess: (_data, _params, context) => {\n if (!context) {\n return\n }\n\n invalidateKeys(\n queryClient,\n mutationEffects.openPosition({ chainId, poolAddress, account: context.signerAccount }),\n )\n },\n })\n}\n\nexport function useLiquidate(poolAddress: Address) {\n const { publicClient, chainId, walletClient, account } = usePanopticContext()\n const queryClient = useQueryClient()\n\n return useMutation({\n onMutate: () => createWalletMutationContext({ walletClient, account }),\n mutationFn: (params: OmitInjectedWithPool<LiquidateParams>) => {\n const wallet = requireWallet({ walletClient, account })\n return liquidate({ client: publicClient, ...wallet, poolAddress, ...params })\n },\n onSuccess: (_data, params, context) => {\n if (!context) {\n return\n }\n\n invalidateKeys(queryClient, [\n ...mutationEffects.liquidate({ chainId, poolAddress, account: context.signerAccount }),\n ...mutationEffects.liquidate({ chainId, poolAddress, account: params.liquidatee }),\n ])\n },\n })\n}\n\nexport function useForceExercise(poolAddress: Address) {\n const { publicClient, chainId, walletClient, account } = usePanopticContext()\n const queryClient = useQueryClient()\n\n return useMutation({\n onMutate: () => createWalletMutationContext({ walletClient, account }),\n mutationFn: (params: OmitInjectedWithPool<ForceExerciseParams>) => {\n const wallet = requireWallet({ walletClient, account })\n return forceExercise({ client: publicClient, ...wallet, poolAddress, ...params })\n },\n onSuccess: (_data, params, context) => {\n if (!context) {\n return\n }\n\n invalidateKeys(queryClient, [\n ...mutationEffects.forceExercise({ chainId, poolAddress, account: context.signerAccount }),\n ...mutationEffects.forceExercise({ chainId, poolAddress, account: params.user }),\n ])\n },\n })\n}\n\nexport function useSettleAccumulatedPremia(poolAddress: Address) {\n const { publicClient, chainId, walletClient, account } = usePanopticContext()\n const queryClient = useQueryClient()\n\n return useMutation({\n onMutate: () => createWalletMutationContext({ walletClient, account }),\n mutationFn: (params: OmitInjectedWithPool<SettleParams>) => {\n const wallet = requireWallet({ walletClient, account })\n return settleAccumulatedPremia({ client: publicClient, ...wallet, poolAddress, ...params })\n },\n onSuccess: (_data, _params, context) => {\n if (!context) {\n return\n }\n\n invalidateKeys(\n queryClient,\n mutationEffects.settleAccumulatedPremia({\n chainId,\n poolAddress,\n account: context.signerAccount,\n }),\n )\n },\n })\n}\n\nexport function usePokeOracle(poolAddress: Address) {\n const { publicClient, chainId, walletClient, account } = usePanopticContext()\n const queryClient = useQueryClient()\n\n return useMutation({\n onMutate: () => createWalletMutationContext({ walletClient, account }),\n mutationFn: (params?: OmitInjectedWithPool<PokeOracleParams>) => {\n const wallet = requireWallet({ walletClient, account })\n return pokeOracle({ client: publicClient, ...wallet, poolAddress, ...params })\n },\n onSuccess: () => {\n invalidateKeys(queryClient, mutationEffects.pokeOracle({ chainId, poolAddress }))\n },\n })\n}\n\nexport function useDispatch(poolAddress: Address) {\n const { publicClient, chainId, walletClient, account } = usePanopticContext()\n const queryClient = useQueryClient()\n\n return useMutation({\n onMutate: () => createWalletMutationContext({ walletClient, account }),\n mutationFn: (params: OmitInjectedWithPool<DispatchParams>) => {\n const wallet = requireWallet({ walletClient, account })\n return dispatch({ client: publicClient, ...wallet, poolAddress, ...params })\n },\n onSuccess: (_data, _params, context) => {\n if (!context) {\n return\n }\n\n invalidateKeys(\n queryClient,\n mutationEffects.openPosition({ chainId, poolAddress, account: context.signerAccount }),\n )\n },\n })\n}\n\nexport function useDeployNewPool() {\n const { publicClient, walletClient, account } = usePanopticContext()\n const queryClient = useQueryClient()\n\n return useMutation({\n onMutate: () => createWalletMutationContext({ walletClient, account }),\n mutationFn: (params: OmitInjected<DeployNewPoolParams>) => {\n const wallet = requireWallet({ walletClient, account })\n return deployNewPool({ client: publicClient, ...wallet, ...params })\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [...queryKeys.all, 'factory'] })\n },\n })\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 { panopticPoolAbi } 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: panopticPoolAbi,\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 * Dispatch simulation for the Panoptic v2 SDK.\n * @module v2/simulations/simulateDispatch\n */\n\nimport type { Address, PublicClient } from 'viem'\nimport { encodeFunctionData } from 'viem'\n\nimport { panopticPoolAbi } from '../../../generated'\nimport { getBlockMeta } from '../clients'\nimport { PanopticError } from '../errors'\nimport type { DispatchSimulation, SimulationResult, TokenFlow } from '../types'\nimport type { TickAndSpreadLimits } from '../writes/position'\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 /** 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 /** 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 } = 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: panopticPoolAbi,\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 // 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 // Determine which positions were created/closed\n const positionsCreated = finalPositionIdList.filter((id) => !positionIdList.includes(id))\n const positionsClosed = positionIdList.filter((id) => !finalPositionIdList.includes(id))\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 postMarginExcess0: null, // Requires PanopticQuery.checkCollateral\n postMarginExcess1: 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 { panopticPoolAbi } 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: panopticPoolAbi,\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 { panopticPoolAbi } 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: panopticPoolAbi,\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 { panopticPoolAbi } 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 `getAccumulatedFeesAndPositionsData` 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: panopticPoolAbi,\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 + getAccumulatedFeesAndPositionsData\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 getAccumulatedFeesAndPositionsData calls (available = false, total = true)\n const feesCallAvailable = encodeFunctionData({\n abi: panopticPoolAbi,\n functionName: 'getAccumulatedFeesAndPositionsData',\n args: [account, false, [tokenId]],\n })\n const feesCallTotal = encodeFunctionData({\n abi: panopticPoolAbi,\n functionName: 'getAccumulatedFeesAndPositionsData',\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: panopticPoolAbi,\n functionName: 'getAccumulatedFeesAndPositionsData',\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 { collateralTrackerAbi } 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: collateralTrackerAbi,\n functionName: 'balanceOf',\n args: [account],\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerAbi,\n functionName: 'assetsOf',\n args: [account],\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerAbi,\n functionName: 'previewDeposit',\n args: [assets],\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n }),\n client.estimateContractGas({\n address: collateralTrackerAddress,\n abi: collateralTrackerAbi,\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: collateralTrackerAbi,\n functionName: 'balanceOf',\n args: [account],\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerAbi,\n functionName: 'assetsOf',\n args: [account],\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerAbi,\n functionName: 'maxWithdraw',\n args: [account],\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerAbi,\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: collateralTrackerAbi,\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 { semiFungiblePositionManagerAbi } from '../../../generated'\nimport type { PoolKey } from '../types'\n\n/**\n * Encode a 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 * 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: semiFungiblePositionManagerAbi,\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: semiFungiblePositionManagerAbi,\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 * TanStack Query v5 simulation hooks for the Panoptic v2 SDK.\n * @module v2/react/hooks/simulations\n */\n\nimport { useQuery } from '@tanstack/react-query'\nimport type { Address } from 'viem'\n\nimport {\n type SimulateClosePositionParams,\n type SimulateDepositParams,\n type SimulateDispatchParams,\n type SimulateForceExerciseParams,\n type SimulateLiquidateParams,\n type SimulateOpenPositionParams,\n type SimulateSettleParams,\n type SimulateSFPMParams,\n type SimulateWithdrawParams,\n simulateClosePosition,\n simulateDeposit,\n simulateDispatch,\n simulateForceExercise,\n simulateLiquidate,\n simulateOpenPosition,\n simulateSettle,\n simulateSFPMBurn,\n simulateSFPMMint,\n simulateWithdraw,\n} from '../../simulations'\nimport { getClientCacheScopeKey } from '../cacheScopes'\nimport { usePanopticContext } from '../provider'\nimport { queryKeys } from '../queryKeys'\n\ntype OmitClient<T> = Omit<T, 'client'>\ntype OmitClientAndPool<T> = Omit<T, 'client' | 'poolAddress'>\n\nexport function useSimulateOpenPosition(\n poolAddress: Address,\n params?: OmitClientAndPool<SimulateOpenPositionParams>,\n) {\n const { publicClient, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.all,\n 'sim',\n 'openPosition',\n poolAddress,\n params?.tokenId?.toString(),\n getClientCacheScopeKey(publicClient, clientScope),\n params,\n ] as const,\n queryFn: () => simulateOpenPosition({ client: publicClient, poolAddress, ...params! }),\n enabled: params !== undefined,\n staleTime: 0,\n })\n}\n\nexport function useSimulateClosePosition(\n poolAddress: Address,\n params?: OmitClientAndPool<SimulateClosePositionParams>,\n) {\n const { publicClient, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.all,\n 'sim',\n 'closePosition',\n poolAddress,\n params?.tokenId?.toString(),\n getClientCacheScopeKey(publicClient, clientScope),\n params,\n ] as const,\n queryFn: () => simulateClosePosition({ client: publicClient, poolAddress, ...params! }),\n enabled: params !== undefined,\n staleTime: 0,\n })\n}\n\nexport function useSimulateDeposit(params?: OmitClient<SimulateDepositParams>) {\n const { publicClient, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.all,\n 'sim',\n 'deposit',\n params?.collateralTrackerAddress,\n params?.assets?.toString(),\n getClientCacheScopeKey(publicClient, clientScope),\n params,\n ] as const,\n queryFn: () => simulateDeposit({ client: publicClient, ...params! }),\n enabled: params !== undefined,\n staleTime: 0,\n })\n}\n\nexport function useSimulateWithdraw(params?: OmitClient<SimulateWithdrawParams>) {\n const { publicClient, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.all,\n 'sim',\n 'withdraw',\n params?.collateralTrackerAddress,\n params?.assets?.toString(),\n getClientCacheScopeKey(publicClient, clientScope),\n params,\n ] as const,\n queryFn: () => simulateWithdraw({ client: publicClient, ...params! }),\n enabled: params !== undefined,\n staleTime: 0,\n })\n}\n\nexport function useSimulateLiquidate(\n poolAddress: Address,\n params?: OmitClientAndPool<SimulateLiquidateParams>,\n) {\n const { publicClient, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.all,\n 'sim',\n 'liquidate',\n poolAddress,\n params?.liquidatee,\n getClientCacheScopeKey(publicClient, clientScope),\n params,\n ] as const,\n queryFn: () => simulateLiquidate({ client: publicClient, poolAddress, ...params! }),\n enabled: params !== undefined,\n staleTime: 0,\n })\n}\n\nexport function useSimulateForceExercise(\n poolAddress: Address,\n params?: OmitClientAndPool<SimulateForceExerciseParams>,\n) {\n const { publicClient, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.all,\n 'sim',\n 'forceExercise',\n poolAddress,\n params?.user,\n getClientCacheScopeKey(publicClient, clientScope),\n params,\n ] as const,\n queryFn: () => simulateForceExercise({ client: publicClient, poolAddress, ...params! }),\n enabled: params !== undefined,\n staleTime: 0,\n })\n}\n\nexport function useSimulateSettle(\n poolAddress: Address,\n params?: OmitClientAndPool<SimulateSettleParams>,\n) {\n const { publicClient, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.all,\n 'sim',\n 'settle',\n poolAddress,\n params?.account,\n getClientCacheScopeKey(publicClient, clientScope),\n params,\n ] as const,\n queryFn: () => simulateSettle({ client: publicClient, poolAddress, ...params! }),\n enabled: params !== undefined,\n staleTime: 0,\n })\n}\n\nexport function useSimulateDispatch(\n poolAddress: Address,\n params?: OmitClientAndPool<SimulateDispatchParams>,\n) {\n const { publicClient, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.all,\n 'sim',\n 'dispatch',\n poolAddress,\n JSON.stringify(params?.positionIdList?.map(String)),\n getClientCacheScopeKey(publicClient, clientScope),\n params,\n ] as const,\n queryFn: () => simulateDispatch({ client: publicClient, poolAddress, ...params! }),\n enabled: params !== undefined,\n staleTime: 0,\n })\n}\n\nexport function useSimulateSFPMMint(params?: OmitClient<SimulateSFPMParams>) {\n const { publicClient, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.all,\n 'sim',\n 'sfpmMint',\n params?.sfpmAddress,\n params?.tokenId?.toString(),\n getClientCacheScopeKey(publicClient, clientScope),\n params,\n ] as const,\n queryFn: () => {\n if (!params) throw new Error('params required for simulateSFPMMint')\n return simulateSFPMMint({ client: publicClient, ...params })\n },\n enabled: params !== undefined,\n staleTime: 0,\n })\n}\n\nexport function useSimulateSFPMBurn(params?: OmitClient<SimulateSFPMParams>) {\n const { publicClient, clientScope } = usePanopticContext()\n return useQuery({\n queryKey: [\n ...queryKeys.all,\n 'sim',\n 'sfpmBurn',\n params?.sfpmAddress,\n params?.tokenId?.toString(),\n getClientCacheScopeKey(publicClient, clientScope),\n params,\n ] as const,\n queryFn: () => {\n if (!params) throw new Error('params required for simulateSFPMBurn')\n return simulateSFPMBurn({ client: publicClient, ...params })\n },\n enabled: params !== undefined,\n staleTime: 0,\n })\n}\n","/**\n * TanStack Query v5 sync hooks for the Panoptic v2 SDK.\n * @module v2/react/hooks/sync\n */\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { useState } from 'react'\nimport type { Address, Hash } from 'viem'\n\nimport {\n type PendingPosition,\n type SyncProgressEvent,\n addPendingPosition,\n clearTrackedPositions,\n confirmPendingPosition,\n failPendingPosition,\n syncPositions,\n} from '../../sync'\nimport { usePanopticContext, useRequireStorage } from '../provider'\nimport { queryKeys } from '../queryKeys'\n\n/**\n * Hook for syncing positions with progress tracking.\n */\nexport function useSyncPositions(poolAddress: Address) {\n const { publicClient, chainId } = usePanopticContext()\n const storage = useRequireStorage()\n const account = usePanopticContext().account\n const queryClient = useQueryClient()\n const [progress, setProgress] = useState<SyncProgressEvent | null>(null)\n\n const mutation = useMutation({\n mutationFn: async (params?: { fromBlock?: bigint; toBlock?: bigint }) => {\n if (!account) throw new Error('account is required for sync')\n const result = await syncPositions({\n client: publicClient,\n chainId,\n poolAddress,\n account,\n storage,\n fromBlock: params?.fromBlock,\n toBlock: params?.toBlock,\n onUpdate: setProgress,\n })\n return result\n },\n onSuccess: () => {\n if (!account) return\n queryClient.invalidateQueries({\n queryKey: queryKeys.trackedPositionIds(chainId, poolAddress, account),\n })\n queryClient.invalidateQueries({\n queryKey: queryKeys.syncStatus(chainId, poolAddress, account),\n })\n queryClient.invalidateQueries({\n queryKey: queryKeys.positions(chainId, poolAddress, account),\n })\n queryClient.invalidateQueries({\n queryKey: queryKeys.closedPositions(chainId, poolAddress, account),\n })\n queryClient.invalidateQueries({\n queryKey: queryKeys.tradeHistory(chainId, poolAddress, account),\n })\n },\n })\n\n return { ...mutation, progress }\n}\n\n/**\n * Hook for adding a pending position (optimistic update).\n */\nexport function useAddPendingPosition(poolAddress: Address) {\n const { chainId } = usePanopticContext()\n const storage = useRequireStorage()\n const account = usePanopticContext().account\n const queryClient = useQueryClient()\n\n return useMutation({\n mutationFn: (position: PendingPosition) => {\n if (!account) throw new Error('account is required')\n return addPendingPosition({ chainId, poolAddress, account, storage, position })\n },\n onSuccess: () => {\n if (!account) return\n queryClient.invalidateQueries({\n queryKey: queryKeys.trackedPositionIds(chainId, poolAddress, account),\n })\n },\n })\n}\n\n/**\n * Hook for confirming a pending position.\n */\nexport function useConfirmPendingPosition(poolAddress: Address) {\n const { chainId } = usePanopticContext()\n const storage = useRequireStorage()\n const account = usePanopticContext().account\n const queryClient = useQueryClient()\n\n return useMutation({\n mutationFn: (tokenId: bigint) => {\n if (!account) throw new Error('account is required')\n return confirmPendingPosition({ chainId, poolAddress, account, storage, tokenId })\n },\n onSuccess: () => {\n if (!account) return\n queryClient.invalidateQueries({\n queryKey: queryKeys.trackedPositionIds(chainId, poolAddress, account),\n })\n queryClient.invalidateQueries({\n queryKey: queryKeys.positions(chainId, poolAddress, account),\n })\n },\n })\n}\n\n/**\n * Hook for marking a pending position as failed.\n */\nexport function useFailPendingPosition(poolAddress: Address) {\n const { chainId } = usePanopticContext()\n const storage = useRequireStorage()\n const account = usePanopticContext().account\n const queryClient = useQueryClient()\n\n return useMutation({\n mutationFn: (txHash: Hash) => {\n if (!account) throw new Error('account is required')\n return failPendingPosition({ chainId, poolAddress, account, storage, txHash })\n },\n onSuccess: () => {\n if (!account) return\n queryClient.invalidateQueries({\n queryKey: queryKeys.trackedPositionIds(chainId, poolAddress, account),\n })\n },\n })\n}\n\n/**\n * Hook for clearing all tracked positions.\n */\nexport function useClearTrackedPositions(poolAddress: Address) {\n const { chainId } = usePanopticContext()\n const storage = useRequireStorage()\n const account = usePanopticContext().account\n const queryClient = useQueryClient()\n\n return useMutation({\n mutationFn: () => {\n if (!account) throw new Error('account is required')\n return clearTrackedPositions({ chainId, poolAddress, account, storage })\n },\n onSuccess: () => {\n if (!account) return\n queryClient.invalidateQueries({\n queryKey: queryKeys.trackedPositionIds(chainId, poolAddress, account),\n })\n queryClient.invalidateQueries({\n queryKey: queryKeys.positions(chainId, poolAddress, account),\n })\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 collateralTrackerAbi,\n panopticPoolAbi,\n riskEngineAbi,\n semiFungiblePositionManagerAbi,\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: panopticPoolAbi,\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: collateralTrackerAbi,\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: semiFungiblePositionManagerAbi,\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 collateralTrackerAbi,\n panopticPoolAbi,\n riskEngineAbi,\n semiFungiblePositionManagerAbi,\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: panopticPoolAbi,\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: collateralTrackerAbi,\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: semiFungiblePositionManagerAbi,\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: panopticPoolAbi,\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: collateralTrackerAbi,\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: semiFungiblePositionManagerAbi,\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 collateralTrackerAbi,\n panopticPoolAbi,\n riskEngineAbi,\n semiFungiblePositionManagerAbi,\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: panopticPoolAbi,\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: collateralTrackerAbi,\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: semiFungiblePositionManagerAbi,\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 * TanStack Query v5 event hooks for the Panoptic v2 SDK.\n * @module v2/react/hooks/events\n */\n\nimport { useEffect, useRef } from 'react'\nimport type { Address } from 'viem'\n\nimport { watchEvents } from '../../events'\nimport {\n type EventPoller,\n type EventSubscriptionHandle,\n createEventPoller,\n createEventSubscription,\n} from '../../events'\nimport type { PanopticEvent, PanopticEventType } from '../../types'\nimport { usePanopticContext } from '../provider'\n\n/**\n * Watch events via WebSocket. Returns cleanup automatically on unmount.\n */\nexport function useWatchEvents(\n poolAddress: Address,\n eventTypes: PanopticEventType[] | undefined,\n onEvent: (events: PanopticEvent[]) => void,\n options?: {\n enabled?: boolean\n collateralTracker0?: Address\n collateralTracker1?: Address\n riskEngineAddress?: Address\n sfpmAddress?: Address\n poolManagerAddress?: Address\n onError?: (error: Error) => void\n },\n) {\n const { publicClient } = usePanopticContext()\n const onEventRef = useRef(onEvent)\n onEventRef.current = onEvent\n const onErrorRef = useRef(options?.onError)\n onErrorRef.current = options?.onError\n\n const eventTypesKey = eventTypes?.join(',')\n\n useEffect(() => {\n if (options?.enabled === false) return\n\n const unwatch = watchEvents({\n client: publicClient,\n poolAddress,\n eventTypes,\n collateralTracker0: options?.collateralTracker0,\n collateralTracker1: options?.collateralTracker1,\n riskEngineAddress: options?.riskEngineAddress,\n sfpmAddress: options?.sfpmAddress,\n poolManagerAddress: options?.poolManagerAddress,\n onLogs: (events) => onEventRef.current(events),\n onError: (error) => onErrorRef.current?.(error),\n })\n\n return unwatch\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n publicClient,\n poolAddress,\n options?.enabled,\n options?.collateralTracker0,\n options?.collateralTracker1,\n options?.riskEngineAddress,\n options?.sfpmAddress,\n options?.poolManagerAddress,\n eventTypesKey,\n ])\n}\n\n/**\n * Create a resilient event subscription with auto-reconnect.\n */\nexport function useEventSubscription(\n poolAddress: Address,\n eventTypes: PanopticEventType[] | undefined,\n onEvent: (events: PanopticEvent[]) => void,\n options?: {\n enabled?: boolean\n collateralTracker0?: Address\n collateralTracker1?: Address\n riskEngineAddress?: Address\n sfpmAddress?: Address\n poolManagerAddress?: Address\n onError?: (error: Error) => void\n onReconnect?: (attempt: bigint, nextDelayMs: bigint) => void\n onConnected?: () => void\n },\n) {\n const { publicClient } = usePanopticContext()\n const onEventRef = useRef(onEvent)\n onEventRef.current = onEvent\n const onErrorRef = useRef(options?.onError)\n onErrorRef.current = options?.onError\n const onReconnectRef = useRef(options?.onReconnect)\n onReconnectRef.current = options?.onReconnect\n const onConnectedRef = useRef(options?.onConnected)\n onConnectedRef.current = options?.onConnected\n\n const eventTypesKey = eventTypes?.join(',')\n\n useEffect(() => {\n if (options?.enabled === false) return\n\n const handle: EventSubscriptionHandle = createEventSubscription({\n client: publicClient,\n poolAddress,\n eventTypes,\n collateralTracker0: options?.collateralTracker0,\n collateralTracker1: options?.collateralTracker1,\n riskEngineAddress: options?.riskEngineAddress,\n sfpmAddress: options?.sfpmAddress,\n poolManagerAddress: options?.poolManagerAddress,\n onLogs: (events) => onEventRef.current(events),\n onError: (error) => onErrorRef.current?.(error),\n onReconnect: (attempt, delay) => onReconnectRef.current?.(attempt, delay),\n onConnected: () => onConnectedRef.current?.(),\n })\n\n handle.start()\n return () => handle.stop()\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n publicClient,\n poolAddress,\n options?.enabled,\n options?.collateralTracker0,\n options?.collateralTracker1,\n options?.riskEngineAddress,\n options?.sfpmAddress,\n options?.poolManagerAddress,\n eventTypesKey,\n ])\n}\n\n/**\n * Create an HTTP polling event fetcher.\n */\nexport function useEventPoller(\n poolAddress: Address,\n eventTypes: PanopticEventType[] | undefined,\n onEvent: (events: PanopticEvent[]) => void,\n options?: {\n enabled?: boolean\n intervalMs?: bigint\n collateralTracker0?: Address\n collateralTracker1?: Address\n riskEngineAddress?: Address\n sfpmAddress?: Address\n poolManagerAddress?: Address\n onError?: (error: Error) => void\n },\n) {\n const { publicClient } = usePanopticContext()\n const onEventRef = useRef(onEvent)\n onEventRef.current = onEvent\n const onErrorRef = useRef(options?.onError)\n onErrorRef.current = options?.onError\n\n const eventTypesKey = eventTypes?.join(',')\n\n useEffect(() => {\n if (options?.enabled === false) return\n\n const poller: EventPoller = createEventPoller({\n client: publicClient,\n poolAddress,\n eventTypes,\n collateralTracker0: options?.collateralTracker0,\n collateralTracker1: options?.collateralTracker1,\n riskEngineAddress: options?.riskEngineAddress,\n sfpmAddress: options?.sfpmAddress,\n poolManagerAddress: options?.poolManagerAddress,\n intervalMs: options?.intervalMs,\n onLogs: (events) => onEventRef.current(events),\n onError: (error) => onErrorRef.current?.(error),\n })\n\n poller.start()\n return () => poller.stop()\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n publicClient,\n poolAddress,\n options?.enabled,\n options?.intervalMs,\n options?.collateralTracker0,\n options?.collateralTracker1,\n options?.riskEngineAddress,\n options?.sfpmAddress,\n options?.poolManagerAddress,\n eventTypesKey,\n ])\n}\n"],"mappings":"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"}