@panoptic-eng/sdk 1.0.36 → 1.0.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dist/cow/index.d.ts +4 -5
  2. package/dist/cow/index.js +3 -3
  3. package/dist/cow/types.d.ts +3 -2
  4. package/dist/{cow-aX6of9TS.js → cow-DB8siv6M.js} +2 -2
  5. package/dist/{cow-aX6of9TS.js.map → cow-DB8siv6M.js.map} +1 -1
  6. package/dist/deployments.d.ts +3 -2
  7. package/dist/deployments.d.ts.map +1 -1
  8. package/dist/deployments.js +4 -0
  9. package/dist/deployments.js.map +1 -1
  10. package/dist/{position-C8rkkKhi.js → getTrackedPositionIds-zYPIs5dt.js} +1086 -34
  11. package/dist/getTrackedPositionIds-zYPIs5dt.js.map +1 -0
  12. package/dist/hypoVault/vaultDisplayNames.d.ts +2 -0
  13. package/dist/hypoVault/vaultDisplayNames.js +4 -0
  14. package/dist/{index-CURXeKNy.d.ts → index-BhEBx83X.d.ts} +405 -351
  15. package/dist/index-BhEBx83X.d.ts.map +1 -0
  16. package/dist/index-Bo9tHtD7.d.ts +1901 -0
  17. package/dist/index-Bo9tHtD7.d.ts.map +1 -0
  18. package/dist/{index-Cp-nCeV2.d.ts → index-CttjEZ-S.d.ts} +3 -4
  19. package/dist/index-CttjEZ-S.d.ts.map +1 -0
  20. package/dist/{index-Zvu-rJpV.d.ts → index-DktZq9Kb.d.ts} +2 -2
  21. package/dist/{index-Zvu-rJpV.d.ts.map → index-DktZq9Kb.d.ts.map} +1 -1
  22. package/dist/index.d.ts +159 -39
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +323 -70
  25. package/dist/index.js.map +1 -1
  26. package/dist/{irm-DnM96-X4.js → irm-ChkvYphK.js} +3 -318
  27. package/dist/irm-ChkvYphK.js.map +1 -0
  28. package/dist/{irm-CmgC1Mqi.d.ts → irm-D2WTHtuo.d.ts} +3 -30
  29. package/dist/{irm-CmgC1Mqi.d.ts.map → irm-D2WTHtuo.d.ts.map} +1 -1
  30. package/dist/irm-D5plRhpB.d.ts +32 -0
  31. package/dist/irm-D5plRhpB.d.ts.map +1 -0
  32. package/dist/panoptic/v2/greeks/index.d.ts +3 -2
  33. package/dist/panoptic/v2/index.d.ts +7 -8
  34. package/dist/panoptic/v2/index.js +7 -6
  35. package/dist/panoptic/v2/react-public.d.ts +29 -13
  36. package/dist/panoptic/v2/react-public.d.ts.map +1 -1
  37. package/dist/panoptic/v2/react-public.js +48 -8
  38. package/dist/panoptic/v2/react-public.js.map +1 -1
  39. package/dist/panoptic/v2/types/index.d.ts +3 -0
  40. package/dist/panoptic/v2/types/index.js +0 -0
  41. package/dist/quote-DeHNUR0Z.d.ts +52 -0
  42. package/dist/quote-DeHNUR0Z.d.ts.map +1 -0
  43. package/dist/{router-CS86ptMu.js → router-BCUJkY8j.js} +3 -3
  44. package/dist/{router-CS86ptMu.js.map → router-BCUJkY8j.js.map} +1 -1
  45. package/dist/{router-DcoU2KmV.js → router-tCRa0ekE.js} +2 -2
  46. package/dist/{router-DcoU2KmV.js.map → router-tCRa0ekE.js.map} +1 -1
  47. package/dist/src-CRAtPwWk.js +321 -0
  48. package/dist/src-CRAtPwWk.js.map +1 -0
  49. package/dist/test/index.d.ts +2 -2
  50. package/dist/test/index.d.ts.map +1 -1
  51. package/dist/transactionFees-CVi2TrJh.js +175 -0
  52. package/dist/transactionFees-CVi2TrJh.js.map +1 -0
  53. package/dist/transactionFees-DzDyt50k.d.ts +63 -0
  54. package/dist/transactionFees-DzDyt50k.d.ts.map +1 -0
  55. package/dist/{types-D_jcYss-.d.ts → types-Cad5m4Td.d.ts} +3 -5
  56. package/dist/types-Cad5m4Td.d.ts.map +1 -0
  57. package/dist/{types-BHdnurYr.d.ts → types-DM0nxlZr.d.ts} +2 -2
  58. package/dist/{types-BHdnurYr.d.ts.map → types-DM0nxlZr.d.ts.map} +1 -1
  59. package/dist/uniswap/index.d.ts +4 -5
  60. package/dist/uniswap/index.d.ts.map +1 -1
  61. package/dist/uniswap/index.js +4 -4
  62. package/dist/{v2-D0dEatKb.js → v2-BxtzpUnV.js} +3267 -2675
  63. package/dist/v2-BxtzpUnV.js.map +1 -0
  64. package/dist/vault-transaction-fees.d.ts +2 -0
  65. package/dist/vault-transaction-fees.js +3 -0
  66. package/dist/vaultDisplayNames-CKpz51Hu.js +0 -0
  67. package/dist/vaultDisplayNames-Q6htUcch.d.ts +2 -0
  68. package/dist/{writes-AupZCK4M.js → writes-D3bj1wth.js} +326 -1292
  69. package/dist/writes-D3bj1wth.js.map +1 -0
  70. package/package.json +5 -1
  71. package/dist/index-CURXeKNy.d.ts.map +0 -1
  72. package/dist/index-Cp-nCeV2.d.ts.map +0 -1
  73. package/dist/irm-DnM96-X4.js.map +0 -1
  74. package/dist/position-BqIgubs5.d.ts +0 -199
  75. package/dist/position-BqIgubs5.d.ts.map +0 -1
  76. package/dist/position-C8rkkKhi.js.map +0 -1
  77. package/dist/quote-BxQkPBRg.d.ts +0 -718
  78. package/dist/quote-BxQkPBRg.d.ts.map +0 -1
  79. package/dist/simulation-zM6-YUaw.d.ts +0 -258
  80. package/dist/simulation-zM6-YUaw.d.ts.map +0 -1
  81. package/dist/tx-CbDQ58Io.d.ts +0 -367
  82. package/dist/tx-CbDQ58Io.d.ts.map +0 -1
  83. package/dist/types-D_jcYss-.d.ts.map +0 -1
  84. package/dist/v2-D0dEatKb.js.map +0 -1
  85. package/dist/writes-AupZCK4M.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writes-D3bj1wth.js","names":["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","resolvePositionIds","explicit: bigint[] | undefined","storage: StorageAdapter | undefined","chainId: bigint | undefined","poolAddress: Address","account: Address","savePositionIds","storage: StorageAdapter","chainId: bigint","positionIds: bigint[]","params: OpenPositionParams","tickLimits: readonly [number, number, number]","tickLimits","params: {\n poolAddress: Address\n existingPositionIds: bigint[]\n tokenId: bigint\n positionSize: bigint\n tickLimitLow: bigint\n tickLimitHigh: bigint\n spreadLimit?: bigint\n swapAtMint?: boolean\n usePremiaAsCollateral?: boolean\n builderCode?: bigint\n}","params: ClosePositionParams","params: RollPositionParams","closeLimits: readonly [number, number, number]","openLimits: readonly [number, number, number]","params: DispatchParams","params: ValidateBatchParams","diagnostics: BatchDiagnostic[]","params: BuildBatchDispatchArgsParams","tickAndSpreadLimits: TickAndSpreadLimits[]","params: ExecuteBatchDispatchParams","params: LiquidateParams","params: EventReconstructionParams","mintEvents: MintEvent[]","burnEvents: BurnEvent[]","rangeFromBlock: bigint","rangeToBlock: bigint","mint","openPositions: bigint[]","closedPositions: bigint[]","error: unknown","messages: string[]","current: unknown","client: PublicClient","poolAddress: Address","foundBlock: bigint | null","params: 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: SyncPositionsParams","positionIds: bigint[]","positionsKey","storedData: StoredPositionData","lastBlock: bigint","lastBlockHash: Hash","client: PublicClient","poolAddress: Address","poolMetaKey: string","storage: StorageAdapter","poolMeta: StoredPoolMeta","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","strike: bigint","encodedStrike: bigint","legIndex: bigint","address: Address","tickSpacing: bigint","vegoid: bigint","bytes: number[]","poolIdHex: Hex","tokenId: bigint","value: bigint","bitPosition: bigint","leg: EncodeLegParams","legs: DecodedLeg[]","poolId: bigint","config: LegConfig","legIndex: bigint","builder: TokenIdBuilder","leg: EncodeLegParams","config: Omit<LegConfig, 'tokenType' | 'asset'> & { asset?: bigint }","config: LoanCreditConfig","tokenAddress: Address","token0: Address","token1: Address","explicit: bigint[] | undefined","storage: StorageAdapter | undefined","chainId: bigint","poolAddress: Address","account: Address","error: unknown","kind: WidthZeroLegKind","poolId: bigint","asset: bigint","tokenType: bigint","currentTick: bigint","tickSpacing: bigint","existingPositionIds: bigint[]","positionSize: bigint","strike: bigint","optionRatio?: bigint","params: CreditSwapCallParams","params: SwapExactOutParams","params: SwapExactInParams","params: WrapXstockParams","params: UnwrapXstockParams","params: PreviewWrapParams","params: WrapEthParams","params: UnwrapWethParams","leg: DecodedLeg","tickSpacing: bigint","tokenId: bigint","expectedPoolId: bigint","params: SimulateWithTokenFlowParams","multicallData: Hex[]","data: Hex","params: GetPoolTokensParams","params: SimulateOpenPositionParams","tickLimits: readonly [number, number, number]","tickLimits","perPositionCollateralReqs: { token0: bigint; token1: bigint }[]","decoded","data: OpenPositionSimulation","client: PublicClient","poolAddress: Address","chainId: bigint","token: Address","storage: StorageAdapter","account: Address","positionIds: bigint[]","params: SupplyParams","params: UnsupplyParams","params: BorrowParams","mintTickLimits: readonly [number, number, number]","params: PreviewBorrowParams","collateralReqToken0: bigint | null","collateralReqToken1: bigint | null","params: RepayParams","ascendingLimits: readonly [number, number, number]","existingPositionIds: bigint[]","tokenIndex: bigint","params: SmartRepayParams","opsPositionIds: bigint[]","opsSizes: bigint[]","finalPositionIdList: bigint[]"],"sources":["../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/batch/validate.ts","../src/panoptic/v2/batch/build.ts","../src/panoptic/v2/writes/executeBatchDispatch.ts","../src/panoptic/v2/writes/liquidate.ts","../src/panoptic/v2/sync/eventReconstruction.ts","../src/panoptic/v2/sync/reorgHandling.ts","../src/panoptic/v2/sync/syncPositions.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/tokenId/encoding.ts","../src/panoptic/v2/tokenId/builder.ts","../src/panoptic/v2/writes/loanUtils.ts","../src/panoptic/v2/writes/swap.ts","../src/panoptic/v2/writes/wrap.ts","../src/panoptic/v2/tokenId/decode.ts","../src/panoptic/v2/simulations/tokenFlow.ts","../src/panoptic/v2/simulations/simulateOpenPosition.ts","../src/panoptic/v2/writes/lending.ts"],"sourcesContent":["/**\n * Transaction broadcaster utilities for the Panoptic v2 SDK.\n * @module v2/writes/broadcaster\n */\n\nimport type { Address, Hash, PublicClient, WalletClient } from 'viem'\n\nimport type { NonceManager, TxBroadcaster } from '../types'\n\n/**\n * Create a public broadcaster that sends transactions to the standard mempool.\n *\n * Use this factory to create a working broadcaster with a client.\n *\n * @param client - The public client for broadcasting\n * @returns A TxBroadcaster that sends to the public mempool\n *\n * @example\n * ```typescript\n * const broadcaster = createPublicBroadcaster(publicClient)\n * const hash = await broadcaster.broadcast(signedTx)\n * ```\n */\nexport function createPublicBroadcaster(client: PublicClient): TxBroadcaster {\n return {\n async broadcast(signedTx: `0x${string}`): Promise<Hash> {\n return client.sendRawTransaction({ serializedTransaction: signedTx })\n },\n }\n}\n\n/**\n * Default public broadcaster singleton.\n *\n * Note: This singleton requires a client to be provided via the broadcast call's context.\n * For standalone usage, use `createPublicBroadcaster(client)` instead.\n *\n * When used with write functions, the SDK handles client injection automatically.\n */\nexport const publicBroadcaster: TxBroadcaster = {\n async broadcast(signedTx: `0x${string}`): Promise<Hash> {\n // This singleton cannot broadcast without a client.\n // Write functions that use this broadcaster should inject their client.\n throw new Error(\n 'publicBroadcaster requires a client. Use createPublicBroadcaster(client) for standalone usage.',\n )\n },\n}\n\n/**\n * Create a nonce manager for concurrent transaction submission.\n *\n * The nonce manager tracks pending nonces to allow multiple transactions\n * to be submitted without waiting for confirmation.\n *\n * @param client - The public client for querying nonces\n * @returns A NonceManager instance\n *\n * @example\n * ```typescript\n * const nonceManager = createNonceManager(client)\n * const nonce1 = await nonceManager.getNextNonce(account)\n * const nonce2 = await nonceManager.getNextNonce(account) // nonce1 + 1\n * // On failure, reset to re-fetch from chain:\n * nonceManager.reset(account)\n * ```\n */\nexport function createNonceManager(client: PublicClient): NonceManager {\n const pendingNonces = new Map<Address, bigint>()\n\n return {\n async getNextNonce(account: Address): Promise<bigint> {\n const chainNonce = BigInt(\n await client.getTransactionCount({\n address: account,\n blockTag: 'pending',\n }),\n )\n\n const pending = pendingNonces.get(account)\n const localNext = pending !== undefined ? pending + 1n : chainNonce\n const nextNonce = localNext > chainNonce ? localNext : chainNonce\n\n pendingNonces.set(account, nextNonce)\n return nextNonce\n },\n\n reset(account: Address): void {\n pendingNonces.delete(account)\n },\n }\n}\n\n/**\n * Configuration for write operations.\n */\nexport interface WriteConfig {\n /** Wallet client for signing and submitting transactions */\n walletClient: WalletClient\n /** Public client for reading state */\n publicClient: PublicClient\n /** Optional custom broadcaster */\n broadcaster?: TxBroadcaster\n /** Optional nonce manager for concurrent transactions */\n nonceManager?: NonceManager\n /** Gas price multiplier (1.0 = no change, 1.1 = 10% increase) */\n gasPriceMultiplier?: number\n /** Optional gas limit override */\n gasLimit?: bigint\n}\n","/**\n * Approval functions for the Panoptic v2 SDK.\n * @module v2/writes/approve\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\nimport { erc20Abi } from 'viem'\n\nimport { collateralTrackerV2Abi, panopticPoolV2Abi } from '../../../generated'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport { submitWrite } from './utils'\n\n/**\n * Parameters for approve function.\n */\nexport interface ApproveParams {\n /** Public client for reading state */\n client: PublicClient\n /** Wallet client for signing transactions */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** Token address to approve */\n tokenAddress: Address\n /** Spender address (collateral tracker) */\n spenderAddress: Address\n /** Amount to approve (use MaxUint256 for unlimited) */\n amount: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Approve token spending for a collateral tracker.\n *\n * @param params - The approval parameters\n * @returns TxResult with hash and wait function\n *\n * @example\n * ```typescript\n * const result = await approve({\n * client,\n * walletClient,\n * account,\n * tokenAddress: WETH,\n * spenderAddress: collateralToken0,\n * amount: MaxUint256,\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function approve(params: ApproveParams): Promise<TxResult> {\n const { client, walletClient, account, tokenAddress, spenderAddress, amount, txOverrides } =\n params\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: tokenAddress,\n abi: erc20Abi,\n functionName: 'approve',\n args: [spenderAddress, amount],\n txOverrides,\n })\n}\n\n/**\n * Approve token spending and wait for confirmation.\n *\n * @param params - The approval parameters\n * @returns TxReceipt after confirmation\n */\nexport async function approveAndWait(params: ApproveParams): Promise<TxReceipt> {\n const result = await approve(params)\n return result.wait()\n}\n\n/**\n * Parameters for approving both tokens for a pool.\n */\nexport interface ApprovePoolParams {\n /** Public client for reading state */\n client: PublicClient\n /** Wallet client for signing transactions */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Amount to approve for token 0 */\n amount0: bigint\n /** Amount to approve for token 1 */\n amount1: bigint\n}\n\n/**\n * Approve both tokens for a Panoptic pool.\n * Fetches collateral tracker addresses and underlying tokens, then approves both.\n *\n * @param params - The approval parameters\n * @returns Array of two TxResults\n *\n * @example\n * ```typescript\n * const [result0, result1] = await approvePool({\n * client,\n * walletClient,\n * account,\n * poolAddress,\n * amount0: MaxUint256,\n * amount1: MaxUint256,\n * })\n * await Promise.all([result0.wait(), result1.wait()])\n * ```\n */\nexport async function approvePool(params: ApprovePoolParams): Promise<[TxResult, TxResult]> {\n const { client, walletClient, account, poolAddress, amount0, amount1 } = params\n\n // Get collateral tracker addresses\n const [collateralToken0, collateralToken1] = await client.multicall({\n contracts: [\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken0',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken1',\n },\n ],\n allowFailure: false,\n })\n\n // Get underlying token addresses\n const [token0, token1] = await client.multicall({\n contracts: [\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'asset',\n },\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'asset',\n },\n ],\n allowFailure: false,\n })\n\n // Approve both tokens in parallel\n const [result0, result1] = await Promise.all([\n approve({\n client,\n walletClient,\n account,\n tokenAddress: token0,\n spenderAddress: collateralToken0,\n amount: amount0,\n }),\n approve({\n client,\n walletClient,\n account,\n tokenAddress: token1,\n spenderAddress: collateralToken1,\n amount: amount1,\n }),\n ])\n\n return [result0, result1]\n}\n\n/**\n * Check if an approval is needed for a given amount.\n *\n * @param params - Parameters for checking approval\n * @returns Object with needsApproval flag and current allowance\n */\nexport interface CheckApprovalParams {\n /** Public client */\n client: PublicClient\n /** Token address */\n tokenAddress: Address\n /** Owner address */\n owner: Address\n /** Spender address */\n spender: Address\n /** Amount to check against */\n amount: bigint\n}\n\nexport interface ApprovalStatus {\n /** Whether approval is needed */\n needsApproval: boolean\n /** Current allowance */\n currentAllowance: bigint\n /** Amount that would be approved */\n requiredAmount: bigint\n}\n\n/**\n * Check if approval is needed for a token transfer.\n *\n * @param params - The check parameters\n * @returns Approval status\n */\nexport async function checkApproval(params: CheckApprovalParams): Promise<ApprovalStatus> {\n const { client, tokenAddress, owner, spender, amount } = params\n\n const currentAllowance = await client.readContract({\n address: tokenAddress,\n abi: erc20Abi,\n functionName: 'allowance',\n args: [owner, spender],\n })\n\n return {\n needsApproval: currentAllowance < amount,\n currentAllowance,\n requiredAmount: amount,\n }\n}\n","/**\n * ERC4626 vault operations for the Panoptic v2 SDK.\n * @module v2/writes/vault\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport { collateralTrackerV2Abi } from '../../../generated'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport { submitWrite } from './utils'\n\n/**\n * Parameters for deposit operation.\n */\nexport interface DepositParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** CollateralTracker address */\n collateralTrackerAddress: Address\n /** Amount of assets to deposit */\n assets: bigint\n /** Whether the collateral tracker wraps native ETH (requires sending msg.value) */\n isNativeETH?: boolean\n /** Receiver of shares (defaults to account) */\n receiver?: Address\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Deposit assets into a collateral tracker.\n *\n * @param params - Deposit parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * const result = await deposit({\n * client,\n * walletClient,\n * account,\n * collateralTrackerAddress,\n * assets: parseEther('1'),\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function deposit(params: DepositParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n collateralTrackerAddress,\n assets,\n isNativeETH,\n receiver = account,\n txOverrides,\n } = params\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'deposit',\n args: [assets, receiver],\n value: isNativeETH ? assets : undefined,\n txOverrides,\n })\n}\n\n/**\n * Deposit assets and wait for confirmation.\n */\nexport async function depositAndWait(params: DepositParams): Promise<TxReceipt> {\n const result = await deposit(params)\n return result.wait()\n}\n\n/**\n * Parameters for withdraw operation.\n */\nexport interface WithdrawParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** CollateralTracker address */\n collateralTrackerAddress: Address\n /** Amount of assets to withdraw */\n assets: bigint\n /** Receiver of assets */\n receiver?: Address\n /** Owner of shares (defaults to account) */\n owner?: Address\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Withdraw assets from a collateral tracker.\n *\n * @param params - Withdraw parameters\n * @returns TxResult\n */\nexport async function withdraw(params: WithdrawParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n collateralTrackerAddress,\n assets,\n receiver = account,\n owner = account,\n txOverrides,\n } = params\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'withdraw',\n args: [assets, receiver, owner],\n txOverrides,\n })\n}\n\n/**\n * Withdraw assets and wait for confirmation.\n */\nexport async function withdrawAndWait(params: WithdrawParams): Promise<TxReceipt> {\n const result = await withdraw(params)\n return result.wait()\n}\n\n/**\n * Parameters for withdraw with position list validation.\n */\nexport interface WithdrawWithPositionsParams extends WithdrawParams {\n /** Position ID list for collateral validation */\n positionIdList: bigint[]\n /** Whether to use premia as collateral */\n usePremiaAsCollateral: boolean\n}\n\n/**\n * Withdraw assets with position list validation.\n * This overload validates that the withdrawal won't make positions undercollateralized.\n *\n * @param params - Withdraw parameters with positions\n * @returns TxResult\n */\nexport async function withdrawWithPositions(\n params: WithdrawWithPositionsParams,\n): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n collateralTrackerAddress,\n assets,\n receiver = account,\n owner = account,\n positionIdList,\n usePremiaAsCollateral,\n txOverrides,\n } = params\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'withdraw',\n args: [assets, receiver, owner, positionIdList, usePremiaAsCollateral],\n txOverrides,\n })\n}\n\n/**\n * Withdraw with positions and wait for confirmation.\n */\nexport async function withdrawWithPositionsAndWait(\n params: WithdrawWithPositionsParams,\n): Promise<TxReceipt> {\n const result = await withdrawWithPositions(params)\n return result.wait()\n}\n\n/**\n * Parameters for mint operation.\n */\nexport interface MintParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** CollateralTracker address */\n collateralTrackerAddress: Address\n /** Amount of shares to mint */\n shares: bigint\n /** Receiver of shares */\n receiver?: Address\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Mint shares by depositing assets.\n *\n * @param params - Mint parameters\n * @returns TxResult\n */\nexport async function mint(params: MintParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n collateralTrackerAddress,\n shares,\n receiver = account,\n txOverrides,\n } = params\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'mint',\n args: [shares, receiver],\n txOverrides,\n })\n}\n\n/**\n * Mint shares and wait for confirmation.\n */\nexport async function mintAndWait(params: MintParams): Promise<TxReceipt> {\n const result = await mint(params)\n return result.wait()\n}\n\n/**\n * Parameters for redeem operation.\n */\nexport interface RedeemParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** CollateralTracker address */\n collateralTrackerAddress: Address\n /** Amount of shares to redeem */\n shares: bigint\n /** Receiver of assets */\n receiver?: Address\n /** Owner of shares */\n owner?: Address\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Redeem shares for assets.\n *\n * @param params - Redeem parameters\n * @returns TxResult\n */\nexport async function redeem(params: RedeemParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n collateralTrackerAddress,\n shares,\n receiver = account,\n owner = account,\n txOverrides,\n } = params\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'redeem',\n args: [shares, receiver, owner],\n txOverrides,\n })\n}\n\n/**\n * Redeem shares and wait for confirmation.\n */\nexport async function redeemAndWait(params: RedeemParams): Promise<TxReceipt> {\n const result = await redeem(params)\n return result.wait()\n}\n","/**\n * Position operations for the Panoptic v2 SDK.\n * @module v2/writes/position\n */\n\nimport type { Address, Hex, PublicClient, WalletClient } from 'viem'\nimport { encodeFunctionData } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { InvalidTickLimitsError, MissingPositionIdsError } from '../errors'\nimport type { StorageAdapter } from '../storage'\nimport { getPositionsKey, jsonSerializer } from '../storage'\nimport { getTrackedPositionIds } from '../sync/getTrackedPositionIds'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport { submitWrite } from './utils'\n\n/**\n * Optional storage parameters for auto-tracking positions.\n * When provided, `*AndWait` variants will automatically update the local\n * position cache after a successful transaction.\n */\nexport interface PositionStorageParams {\n /** Storage adapter for position tracking */\n storage: StorageAdapter\n /** Chain ID (required for storage key construction) */\n chainId: bigint\n}\n\n/**\n * Resolve the position ID list: use the explicit param if provided,\n * otherwise read from storage. Throws if neither is available.\n */\nasync function resolvePositionIds(\n explicit: bigint[] | undefined,\n storage: StorageAdapter | undefined,\n chainId: bigint | undefined,\n poolAddress: Address,\n account: Address,\n): Promise<bigint[]> {\n if (explicit !== undefined) return explicit\n if (storage && chainId !== undefined) {\n return getTrackedPositionIds({ chainId, poolAddress, account, storage })\n }\n throw new MissingPositionIdsError()\n}\n\n/**\n * Save a position ID list to storage.\n */\nasync function savePositionIds(\n storage: StorageAdapter,\n chainId: bigint,\n poolAddress: Address,\n account: Address,\n positionIds: bigint[],\n): Promise<void> {\n const key = getPositionsKey(chainId, poolAddress, account)\n await storage.set(key, jsonSerializer.stringify(positionIds))\n}\n\n/**\n * Tick and spread limits for position operations.\n * [tickLimitLow, tickLimitHigh, spreadLimitTick]\n *\n * SDK uses bigint for all numerics. Converted to number at viem boundary.\n *\n * @deprecated Use individual tickLimitLow, tickLimitHigh, spreadLimit params with swapAtMint flag\n */\nexport type TickAndSpreadLimits = readonly [bigint, bigint, bigint]\n\n/**\n * Parameters for opening a position.\n */\nexport interface OpenPositionParams extends Partial<PositionStorageParams> {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Existing position IDs held by the account (before this mint). Optional if storage + chainId are provided. */\n existingPositionIds?: bigint[]\n /** TokenId of the position to open */\n tokenId: bigint\n /** Position size (number of contracts) */\n positionSize: bigint\n /**\n * Lower tick limit (always <= tickLimitHigh).\n * Use MIN_TICK (-887272n) to allow any downward price movement.\n */\n tickLimitLow: bigint\n /**\n * Upper tick limit (always >= tickLimitLow).\n * Use MAX_TICK (887272n) to allow any upward price movement.\n */\n tickLimitHigh: bigint\n /** Spread limit tick (use 0n for no spread limit) */\n spreadLimit?: bigint\n /**\n * Whether to swap tokens at mint to achieve single-sided exposure.\n * When true, tickLimits are passed to dispatch in descending order (high, low).\n * When false (default), tickLimits are passed in ascending order (low, high).\n */\n swapAtMint?: boolean\n /** Whether to use premia as collateral */\n usePremiaAsCollateral?: boolean\n /** Builder code (defaults to 0) */\n builderCode?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Open a new position using dispatch.\n *\n * @param params - Position parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * import { MIN_TICK, MAX_TICK } from '@panoptic/sdk'\n *\n * const result = await openPosition({\n * client,\n * walletClient,\n * account,\n * poolAddress,\n * existingPositionIds: [], // Existing positions held before this mint\n * tokenId,\n * positionSize: 1n,\n * tickLimitLow: MIN_TICK,\n * tickLimitHigh: MAX_TICK,\n * swapAtMint: false, // true for covered/single-sided exposure\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function openPosition(params: OpenPositionParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n existingPositionIds: explicitIds,\n tokenId,\n positionSize,\n tickLimitLow,\n tickLimitHigh,\n spreadLimit = 0n,\n swapAtMint = false,\n usePremiaAsCollateral = false,\n builderCode = 0n,\n storage,\n chainId,\n txOverrides,\n } = params\n\n // Validate tick limits\n if (tickLimitLow > tickLimitHigh) {\n throw new InvalidTickLimitsError(tickLimitLow, tickLimitHigh)\n }\n\n const existingPositionIds = await resolvePositionIds(\n explicitIds,\n storage,\n chainId,\n poolAddress,\n account,\n )\n\n // Prepare position lists for dispatch:\n // - positionIdList: positions being minted in this call (just the new tokenId)\n // - finalPositionIdList: all positions the user will have after the mint\n const positionIdList = [tokenId]\n const finalPositionIdList = [...existingPositionIds, tokenId]\n\n // Position sizes array contains the size for the new position\n const positionSizes = [positionSize]\n\n // Build tick limits based on swapAtMint flag:\n // - swapAtMint=true: descending order (high, low) triggers SFPM swap\n // - swapAtMint=false: ascending order (low, high) no swap\n const tickLimits: readonly [number, number, number] = swapAtMint\n ? [Number(tickLimitHigh), Number(tickLimitLow), Number(spreadLimit)]\n : [Number(tickLimitLow), Number(tickLimitHigh), Number(spreadLimit)]\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n positionIdList,\n finalPositionIdList,\n positionSizes,\n [tickLimits],\n usePremiaAsCollateral,\n builderCode,\n ],\n txOverrides,\n })\n}\n\n/**\n * Build the dispatch calldata for opening a position without executing.\n * Returns the target address and encoded calldata, suitable for manual\n * transaction construction (e.g. RFQ broadcast-reconstruct flow).\n *\n * @param params - Position parameters (existingPositionIds required, no storage resolution)\n * @returns { to, data } — contract address and encoded dispatch calldata\n */\nexport function buildOpenPositionCalldata(params: {\n poolAddress: Address\n existingPositionIds: bigint[]\n tokenId: bigint\n positionSize: bigint\n tickLimitLow: bigint\n tickLimitHigh: bigint\n spreadLimit?: bigint\n swapAtMint?: boolean\n usePremiaAsCollateral?: boolean\n builderCode?: bigint\n}): { to: Address; data: Hex } {\n const {\n poolAddress,\n existingPositionIds,\n tokenId,\n positionSize,\n tickLimitLow,\n tickLimitHigh,\n spreadLimit = 0n,\n swapAtMint = false,\n usePremiaAsCollateral = false,\n builderCode = 0n,\n } = params\n\n if (tickLimitLow > tickLimitHigh) {\n throw new InvalidTickLimitsError(tickLimitLow, tickLimitHigh)\n }\n\n const positionIdList = [tokenId]\n const finalPositionIdList = [...existingPositionIds, tokenId]\n const positionSizes = [positionSize]\n\n const tickLimits: readonly [number, number, number] = swapAtMint\n ? [Number(tickLimitHigh), Number(tickLimitLow), Number(spreadLimit)]\n : [Number(tickLimitLow), Number(tickLimitHigh), Number(spreadLimit)]\n\n const data = encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n positionIdList,\n finalPositionIdList,\n positionSizes,\n [tickLimits],\n usePremiaAsCollateral,\n builderCode,\n ],\n })\n\n return { to: poolAddress, data }\n}\n\n/**\n * Open position and wait for confirmation.\n */\nexport async function openPositionAndWait(params: OpenPositionParams): Promise<TxReceipt> {\n const result = await openPosition(params)\n const receipt = await result.wait()\n\n // Auto-update storage if provided\n const {\n storage,\n chainId,\n account,\n poolAddress,\n tokenId,\n existingPositionIds: explicitIds,\n } = params\n if (storage && chainId !== undefined) {\n const base =\n explicitIds ?? (await getTrackedPositionIds({ chainId, poolAddress, account, storage }))\n await savePositionIds(storage, chainId, poolAddress, account, [...base, tokenId])\n }\n\n return receipt\n}\n\n/**\n * Parameters for closing a position.\n */\nexport interface ClosePositionParams extends Partial<PositionStorageParams> {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Current position ID list. Optional if storage + chainId are provided. */\n positionIdList?: bigint[]\n /** TokenId of the position to close */\n tokenId: bigint\n /** Position size to close (use full size for complete close) */\n positionSize: bigint\n /**\n * Lower tick limit (always <= tickLimitHigh).\n * Use MIN_TICK (-887272n) to allow any downward price movement.\n */\n tickLimitLow: bigint\n /**\n * Upper tick limit (always >= tickLimitLow).\n * Use MAX_TICK (887272n) to allow any upward price movement.\n */\n tickLimitHigh: bigint\n /** Spread limit tick (use 0n for no spread limit) */\n spreadLimit?: bigint\n /**\n * Whether to swap tokens at burn to achieve single-sided exposure.\n * When true, tickLimits are passed to dispatch in descending order (high, low).\n * When false (default), tickLimits are passed in ascending order (low, high).\n */\n swapAtMint?: boolean\n /** Whether to use premia as collateral */\n usePremiaAsCollateral?: boolean\n /** Builder code (defaults to 0) */\n builderCode?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Close an existing position using dispatch.\n *\n * @param params - Close parameters\n * @returns TxResult\n */\nexport async function closePosition(params: ClosePositionParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n positionIdList: explicitList,\n tokenId,\n tickLimitLow,\n tickLimitHigh,\n spreadLimit = 0n,\n swapAtMint = false,\n usePremiaAsCollateral = false,\n builderCode = 0n,\n storage,\n chainId,\n txOverrides,\n } = params\n\n // Validate tick limits\n if (tickLimitLow > tickLimitHigh) {\n throw new InvalidTickLimitsError(tickLimitLow, tickLimitHigh)\n }\n\n const positionIdList = await resolvePositionIds(\n explicitList,\n storage,\n chainId,\n poolAddress,\n account,\n )\n\n // For closing, final list excludes the closed position\n const finalPositionIdList = positionIdList.filter((id) => id !== tokenId)\n\n // Build tick limits based on swapAtMint flag:\n // - swapAtMint=true: descending order (high, low) triggers SFPM swap\n // - swapAtMint=false: ascending order (low, high) no swap\n const tickLimits: readonly [number, number, number] = swapAtMint\n ? [Number(tickLimitHigh), Number(tickLimitLow), Number(spreadLimit)]\n : [Number(tickLimitLow), Number(tickLimitHigh), Number(spreadLimit)]\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [[tokenId], finalPositionIdList, [0n], [tickLimits], usePremiaAsCollateral, builderCode],\n txOverrides,\n })\n}\n\n/**\n * Close position and wait for confirmation.\n */\nexport async function closePositionAndWait(params: ClosePositionParams): Promise<TxReceipt> {\n const result = await closePosition(params)\n const receipt = await result.wait()\n\n // Auto-update storage if provided\n const { storage, chainId, account, poolAddress, tokenId, positionIdList: explicitList } = params\n if (storage && chainId !== undefined) {\n const base =\n explicitList ?? (await getTrackedPositionIds({ chainId, poolAddress, account, storage }))\n await savePositionIds(\n storage,\n chainId,\n poolAddress,\n account,\n base.filter((id) => id !== tokenId),\n )\n }\n\n return receipt\n}\n\n/**\n * Parameters for rolling a position.\n */\nexport interface RollPositionParams extends Partial<PositionStorageParams> {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Current position ID list. Optional if storage + chainId are provided. */\n positionIdList?: bigint[]\n /** TokenId of position to close */\n oldTokenId: bigint\n /** Size of position being closed */\n oldPositionSize: bigint\n /** TokenId of new position to open */\n newTokenId: bigint\n /** Size of new position */\n newPositionSize: bigint\n /** Lower tick limit for close (always <= closeTickLimitHigh) */\n closeTickLimitLow: bigint\n /** Upper tick limit for close (always >= closeTickLimitLow) */\n closeTickLimitHigh: bigint\n /** Spread limit for close (use 0n for no spread limit) */\n closeSpreadLimit?: bigint\n /** Whether to swap tokens when closing */\n closeSwapAtMint?: boolean\n /** Lower tick limit for open (always <= openTickLimitHigh) */\n openTickLimitLow: bigint\n /** Upper tick limit for open (always >= openTickLimitLow) */\n openTickLimitHigh: bigint\n /** Spread limit for open (use 0n for no spread limit) */\n openSpreadLimit?: bigint\n /** Whether to swap tokens when opening */\n openSwapAtMint?: boolean\n /** Whether to use premia as collateral */\n usePremiaAsCollateral?: boolean\n /** Builder code */\n builderCode?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Roll a position (close one, open another) in a single transaction.\n *\n * @param params - Roll parameters\n * @returns TxResult\n */\nexport async function rollPosition(params: RollPositionParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n positionIdList: explicitList,\n oldTokenId,\n oldPositionSize,\n newTokenId,\n newPositionSize,\n closeTickLimitLow,\n closeTickLimitHigh,\n closeSpreadLimit = 0n,\n closeSwapAtMint = false,\n openTickLimitLow,\n openTickLimitHigh,\n openSpreadLimit = 0n,\n openSwapAtMint = false,\n usePremiaAsCollateral = false,\n builderCode = 0n,\n storage,\n chainId,\n txOverrides,\n } = params\n\n // Validate tick limits\n if (closeTickLimitLow > closeTickLimitHigh) {\n throw new InvalidTickLimitsError(closeTickLimitLow, closeTickLimitHigh)\n }\n if (openTickLimitLow > openTickLimitHigh) {\n throw new InvalidTickLimitsError(openTickLimitLow, openTickLimitHigh)\n }\n\n const positionIdList = await resolvePositionIds(\n explicitList,\n storage,\n chainId,\n poolAddress,\n account,\n )\n\n // Final list: remove old, add new\n const finalPositionIdList = positionIdList.filter((id) => id !== oldTokenId).concat([newTokenId])\n\n // Position sizes for both operations\n const positionSizes = [oldPositionSize, newPositionSize]\n\n // Build tick limits based on swapAtMint flags\n const closeLimits: readonly [number, number, number] = closeSwapAtMint\n ? [Number(closeTickLimitHigh), Number(closeTickLimitLow), Number(closeSpreadLimit)]\n : [Number(closeTickLimitLow), Number(closeTickLimitHigh), Number(closeSpreadLimit)]\n\n const openLimits: readonly [number, number, number] = openSwapAtMint\n ? [Number(openTickLimitHigh), Number(openTickLimitLow), Number(openSpreadLimit)]\n : [Number(openTickLimitLow), Number(openTickLimitHigh), Number(openSpreadLimit)]\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n positionIdList,\n finalPositionIdList,\n positionSizes as bigint[],\n [closeLimits, openLimits],\n usePremiaAsCollateral,\n builderCode,\n ],\n txOverrides,\n })\n}\n\n/**\n * Roll position and wait for confirmation.\n */\nexport async function rollPositionAndWait(params: RollPositionParams): Promise<TxReceipt> {\n const result = await rollPosition(params)\n const receipt = await result.wait()\n\n // Auto-update storage if provided\n const {\n storage,\n chainId,\n account,\n poolAddress,\n oldTokenId,\n newTokenId,\n positionIdList: explicitList,\n } = params\n if (storage && chainId !== undefined) {\n const base =\n explicitList ?? (await getTrackedPositionIds({ chainId, poolAddress, account, storage }))\n const updated = base.filter((id) => id !== oldTokenId).concat([newTokenId])\n await savePositionIds(storage, chainId, poolAddress, account, updated)\n }\n\n return receipt\n}\n","/**\n * Raw dispatch function for the Panoptic v2 SDK.\n * @module v2/writes/dispatch\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport type { TickAndSpreadLimits } from './position'\nimport { submitWrite } from './utils'\n\n/**\n * Parameters for dispatch function.\n */\nexport interface DispatchParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Current position ID list */\n positionIdList: bigint[]\n /** Final position ID list after operations */\n finalPositionIdList: bigint[]\n /** Position sizes for each operation */\n positionSizes: bigint[]\n /** Tick and spread limits for each operation */\n tickAndSpreadLimits: TickAndSpreadLimits[]\n /** Whether to use premia as collateral */\n usePremiaAsCollateral?: boolean\n /** Builder code */\n builderCode?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Execute a raw dispatch operation.\n * This is the low-level function for multi-position operations.\n *\n * @param params - Dispatch parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * // Open multiple positions atomically\n * const result = await dispatch({\n * client,\n * walletClient,\n * account,\n * poolAddress,\n * positionIdList: [],\n * finalPositionIdList: [tokenId1, tokenId2],\n * positionSizes: [size1, size2],\n * tickAndSpreadLimits: [limits1, limits2],\n * })\n * ```\n */\nexport async function dispatch(params: DispatchParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n positionIdList,\n finalPositionIdList,\n positionSizes,\n tickAndSpreadLimits,\n usePremiaAsCollateral = false,\n builderCode = 0n,\n txOverrides,\n } = params\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n positionIdList,\n finalPositionIdList,\n positionSizes.map((s) => BigInt(s) as unknown as bigint & { readonly __uint128: true }),\n tickAndSpreadLimits.map(\n (t) => [Number(t[0]), Number(t[1]), Number(t[2])] as readonly [number, number, number],\n ),\n usePremiaAsCollateral,\n builderCode,\n ],\n txOverrides,\n })\n}\n\n/**\n * Execute dispatch and wait for confirmation.\n */\nexport async function dispatchAndWait(params: DispatchParams): Promise<TxReceipt> {\n const result = await dispatch(params)\n return result.wait()\n}\n","/**\n * Pure validator for batched mint/burn dispatch operations.\n * @module v2/batch/validate\n */\n\nimport type { BatchDiagnostic, BatchOp } from './types'\n\nexport interface ValidateBatchParams {\n items: BatchOp[]\n /** Current on-chain positionIdList for the account. */\n existingPositionIds: bigint[]\n}\n\n/**\n * Run all batch-level and item-level validations.\n * Pure function; never throws. Empty array means \"ready to build\".\n */\nexport function validateBatch(params: ValidateBatchParams): BatchDiagnostic[] {\n const { items, existingPositionIds } = params\n const diagnostics: BatchDiagnostic[] = []\n\n if (items.length === 0) {\n diagnostics.push({\n itemIndex: -1n,\n tokenId: 0n,\n code: 'empty-batch',\n message: 'Batch is empty.',\n })\n return diagnostics\n }\n\n const head = items[0]\n if (!head) return diagnostics\n const firstPool = head.poolAddress.toLowerCase()\n const existing = new Set(existingPositionIds)\n const seen = new Map<bigint, bigint>()\n\n items.forEach((item, idx) => {\n const itemIndex = BigInt(idx)\n if (item.poolAddress.toLowerCase() !== firstPool) {\n diagnostics.push({\n itemIndex,\n tokenId: item.tokenId,\n code: 'cross-pool',\n message: `Item ${idx} targets pool ${item.poolAddress}, expected ${head.poolAddress}.`,\n })\n }\n\n if (item.tickLimitLow > item.tickLimitHigh) {\n diagnostics.push({\n itemIndex,\n tokenId: item.tokenId,\n code: 'invalid-tick-limits',\n message: `Item ${idx} tickLimitLow (${item.tickLimitLow}) > tickLimitHigh (${item.tickLimitHigh}).`,\n })\n }\n\n if (item.kind === 'mint') {\n if (item.positionSize <= 0n) {\n diagnostics.push({\n itemIndex,\n tokenId: item.tokenId,\n code: 'invalid-position-size',\n message: `Mint at index ${idx} must have positionSize > 0.`,\n })\n }\n if (existing.has(item.tokenId)) {\n diagnostics.push({\n itemIndex,\n tokenId: item.tokenId,\n code: 'mint-already-onchain',\n message: `Mint at index ${idx} targets tokenId ${item.tokenId} which is already open on-chain.`,\n })\n }\n } else if (!existing.has(item.tokenId)) {\n diagnostics.push({\n itemIndex,\n tokenId: item.tokenId,\n code: 'burn-not-found',\n message: `Burn at index ${idx} targets tokenId ${item.tokenId} which is not in the account's positions.`,\n })\n }\n\n const prior = seen.get(item.tokenId)\n if (prior !== undefined) {\n diagnostics.push({\n itemIndex,\n tokenId: item.tokenId,\n code: 'duplicate-tokenid-in-batch',\n message: `Item ${idx} duplicates tokenId ${item.tokenId} also at index ${prior}.`,\n })\n } else {\n seen.set(item.tokenId, itemIndex)\n }\n })\n\n return diagnostics\n}\n","/**\n * Pure builder converting batched mint/burn ops into PanopticPool.dispatch() args.\n * @module v2/batch/build\n */\n\nimport type { TickAndSpreadLimits } from '../writes/position'\nimport type { BatchDiagnostic, BatchDispatchArgs, BatchOp } from './types'\nimport { validateBatch } from './validate'\n\nexport interface BuildBatchDispatchArgsParams {\n items: BatchOp[]\n /** Current on-chain positionIdList for the account. */\n existingPositionIds: bigint[]\n /** Apply across the whole dispatch. Defaults to false. */\n usePremiaAsCollateral?: boolean\n /** Apply across the whole dispatch. Defaults to 0n. */\n builderCode?: bigint\n}\n\nexport interface BuildBatchDispatchArgsResult {\n /** Null when diagnostics are non-empty. */\n args: BatchDispatchArgs | null\n diagnostics: BatchDiagnostic[]\n}\n\n/**\n * Build dispatch() args from a list of batch ops + the account's current\n * on-chain positionIdList. Returns diagnostics instead of throwing so callers\n * (UIs, bots) can render conflicts before deciding what to do.\n *\n * The order in `items` is preserved as the operation order in `positionIdList`,\n * `positionSizes`, and `tickAndSpreadLimits`. `finalPositionIdList` is the\n * post-execution state: existing minus burns, plus mints.\n */\nexport function buildBatchDispatchArgs(\n params: BuildBatchDispatchArgsParams,\n): BuildBatchDispatchArgsResult {\n const { items, existingPositionIds, usePremiaAsCollateral = false, builderCode = 0n } = params\n\n const diagnostics = validateBatch({ items, existingPositionIds })\n if (diagnostics.length > 0) {\n return { args: null, diagnostics }\n }\n\n const positionIdList = items.map((i) => i.tokenId)\n const positionSizes = items.map((i) => (i.kind === 'mint' ? i.positionSize : 0n))\n\n const tickAndSpreadLimits: TickAndSpreadLimits[] = items.map((i) => {\n const low = i.tickLimitLow <= i.tickLimitHigh ? i.tickLimitLow : i.tickLimitHigh\n const high = i.tickLimitLow <= i.tickLimitHigh ? i.tickLimitHigh : i.tickLimitLow\n const spread = i.kind === 'mint' ? i.spreadLimit : 0n\n return i.swapAtMint ? ([high, low, spread] as const) : ([low, high, spread] as const)\n })\n\n const mintIds = items.filter((i) => i.kind === 'mint').map((i) => i.tokenId)\n const burnIds = new Set(items.filter((i) => i.kind === 'burn').map((i) => i.tokenId))\n const mintIdSet = new Set(mintIds)\n const finalPositionIdList = [\n ...existingPositionIds.filter((id) => !burnIds.has(id) && !mintIdSet.has(id)),\n ...mintIds,\n ]\n\n return {\n args: {\n positionIdList,\n finalPositionIdList,\n positionSizes,\n tickAndSpreadLimits,\n usePremiaAsCollateral,\n builderCode,\n },\n diagnostics: [],\n }\n}\n","/**\n * Item-based wrapper around dispatch() for batched mint/burn ops.\n * @module v2/writes/executeBatchDispatch\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport { buildBatchDispatchArgs } from '../batch/build'\nimport type { BatchOp } from '../batch/types'\nimport { BatchValidationError } from '../errors'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport { dispatch } from './dispatch'\n\nexport interface ExecuteBatchDispatchParams {\n client: PublicClient\n walletClient: WalletClient\n account: Address\n poolAddress: Address\n /** Batch ops in operation order. */\n items: BatchOp[]\n /** Current on-chain positionIdList for the account (fresh). */\n existingPositionIds: bigint[]\n /** Apply across the whole dispatch. Defaults to false. */\n usePremiaAsCollateral?: boolean\n /** Apply across the whole dispatch. Defaults to 0n. */\n builderCode?: bigint\n txOverrides?: TxOverrides\n}\n\n/**\n * Build dispatch args from a batch and submit them as a single transaction.\n *\n * Throws `BatchValidationError` (with the full diagnostics list) when the batch\n * fails validation. Callers that want to render diagnostics in UI should run\n * `buildBatchDispatchArgs` or `simulateBatchDispatch` first.\n */\nexport async function executeBatchDispatch(params: ExecuteBatchDispatchParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n items,\n existingPositionIds,\n usePremiaAsCollateral = false,\n builderCode = 0n,\n txOverrides,\n } = params\n\n const { args, diagnostics } = buildBatchDispatchArgs({\n items,\n existingPositionIds,\n usePremiaAsCollateral,\n builderCode,\n })\n\n if (args === null) {\n throw new BatchValidationError(diagnostics)\n }\n\n return dispatch({\n client,\n walletClient,\n account,\n poolAddress,\n positionIdList: args.positionIdList,\n finalPositionIdList: args.finalPositionIdList,\n positionSizes: args.positionSizes,\n tickAndSpreadLimits: args.tickAndSpreadLimits,\n usePremiaAsCollateral: args.usePremiaAsCollateral,\n builderCode: args.builderCode,\n txOverrides,\n })\n}\n\n/**\n * Execute a batch dispatch and wait for confirmation.\n */\nexport async function executeBatchDispatchAndWait(\n params: ExecuteBatchDispatchParams,\n): Promise<TxReceipt> {\n const result = await executeBatchDispatch(params)\n return result.wait()\n}\n","/**\n * Liquidation functions for the Panoptic v2 SDK.\n * @module v2/writes/liquidate\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport { submitWrite } from './utils'\n\n/**\n * Parameters for liquidating an account.\n */\nexport interface LiquidateParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Liquidator account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Account being liquidated */\n liquidatee: Address\n /** Position IDs from the liquidator's account */\n positionIdListFrom: bigint[]\n /** Position IDs of the liquidatee (positions to liquidate) */\n positionIdListTo: bigint[]\n /** Final position ID list for the liquidatee after liquidation */\n positionIdListToFinal: bigint[]\n /** Packed value for using premia as collateral */\n usePremiaAsCollateral?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Liquidate an undercollateralized account using dispatchFrom.\n *\n * The liquidator calls dispatchFrom to close the liquidatee's positions\n * and receive a bonus.\n *\n * @param params - Liquidation parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * const result = await liquidate({\n * client,\n * walletClient,\n * account: liquidatorAddress,\n * poolAddress,\n * liquidatee: undercollateralizedAccount,\n * positionIdListFrom: liquidatorPositions,\n * positionIdListTo: liquidateePositions,\n * positionIdListToFinal: [], // Close all positions\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function liquidate(params: LiquidateParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n liquidatee,\n positionIdListFrom,\n positionIdListTo,\n positionIdListToFinal,\n usePremiaAsCollateral = 0n,\n txOverrides,\n } = params\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatchFrom',\n args: [\n positionIdListFrom,\n liquidatee,\n positionIdListTo,\n positionIdListToFinal,\n usePremiaAsCollateral,\n ],\n txOverrides,\n })\n}\n\n/**\n * Liquidate and wait for confirmation.\n */\nexport async function liquidateAndWait(params: LiquidateParams): Promise<TxReceipt> {\n const result = await liquidate(params)\n return result.wait()\n}\n","/**\n * Event reconstruction for full position history scan.\n * @module v2/sync/eventReconstruction\n */\n\nimport type { Address, Hash, PublicClient } from 'viem'\nimport { getAbiItem } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport type { SyncEvent } from '../types'\n\ntype EventReconstructionClient = Pick<PublicClient, 'getBlock' | 'getLogs'>\n\n/**\n * Parameters for event reconstruction.\n */\nexport interface EventReconstructionParams {\n /** viem public client */\n client: EventReconstructionClient\n /** Pool address */\n poolAddress: Address\n /** Account to reconstruct positions for */\n account: Address\n /** Starting block for event scan */\n fromBlock: bigint\n /** Ending block for event scan */\n toBlock: bigint\n /** Batch size for log queries (default: 10000) */\n batchSize?: bigint\n /** Progress callback */\n onProgress?: (event: SyncEvent) => void\n}\n\n/**\n * Event reconstruction result.\n */\nexport interface EventReconstructionResult {\n /** Position IDs that are currently open */\n openPositions: bigint[]\n /** Position IDs that have been closed */\n closedPositions: bigint[]\n /** Number of blocks scanned */\n blocksScanned: bigint\n /** Last scanned block number */\n lastBlock: bigint\n /** Last scanned block hash */\n lastBlockHash: Hash\n}\n\n/**\n * Mint event from reconstruction.\n */\ninterface MintEvent {\n tokenId: bigint\n positionSize: bigint\n blockNumber: bigint\n blockHash: Hash\n transactionHash: Hash\n logIndex: number\n}\n\n/**\n * Burn event from reconstruction.\n */\ninterface BurnEvent {\n tokenId: bigint\n positionSize: bigint\n blockNumber: bigint\n blockHash: Hash\n transactionHash: Hash\n logIndex: number\n}\n\n/**\n * Reconstruct position history from events.\n * This is the fallback method when snapshot recovery fails.\n * It scans all OptionMinted and OptionBurnt events to build the position set.\n *\n * @param params - Reconstruction parameters\n * @returns Reconstruction result with open and closed positions\n */\nexport async function reconstructFromEvents(\n params: EventReconstructionParams,\n): Promise<EventReconstructionResult> {\n const {\n client,\n poolAddress,\n account,\n fromBlock,\n toBlock,\n batchSize = 10000n,\n onProgress,\n } = params\n\n const mintEvents: MintEvent[] = []\n const burnEvents: BurnEvent[] = []\n const totalBlocks = toBlock - fromBlock + 1n\n const safeBatchSize = batchSize > 0n ? batchSize : 10000n\n\n const scanRange = async (rangeFromBlock: bigint, rangeToBlock: bigint) => {\n const [mints, burns] = await Promise.all([\n client.getLogs({\n address: poolAddress,\n event: OPTION_MINTED_EVENT,\n args: { recipient: account },\n fromBlock: rangeFromBlock,\n toBlock: rangeToBlock,\n }),\n client.getLogs({\n address: poolAddress,\n event: OPTION_BURNT_EVENT,\n args: { recipient: account },\n fromBlock: rangeFromBlock,\n toBlock: rangeToBlock,\n }),\n ])\n\n // Process mint events\n for (const mint of mints) {\n // Decode position size from balanceData (first 128 bits)\n const balanceData = mint.args.balanceData as bigint\n const positionSize = balanceData & ((1n << 128n) - 1n)\n\n mintEvents.push({\n tokenId: mint.args.tokenId as bigint,\n positionSize,\n blockNumber: mint.blockNumber,\n blockHash: mint.blockHash,\n transactionHash: mint.transactionHash,\n logIndex: mint.logIndex,\n })\n }\n\n // Process burn events\n for (const burn of burns) {\n burnEvents.push({\n tokenId: burn.args.tokenId as bigint,\n positionSize: burn.args.positionSize as bigint,\n blockNumber: burn.blockNumber,\n blockHash: burn.blockHash,\n transactionHash: burn.transactionHash,\n logIndex: burn.logIndex,\n })\n }\n\n const blocksProcessed = rangeToBlock - fromBlock + 1n\n const progress = totalBlocks > 0n ? (blocksProcessed * 100n) / totalBlocks : 100n\n onProgress?.({\n currentBlock: rangeToBlock,\n targetBlock: toBlock,\n positionsFound: BigInt(mintEvents.length),\n progress: progress > 100n ? 100n : progress,\n })\n }\n\n // Account and pool topics make this query selective enough for providers that\n // permit wide eth_getLogs ranges. This keeps the fallback practical on mainnet.\n // Providers with an explicit range cap fall back to bounded requests.\n try {\n await scanRange(fromBlock, toBlock)\n } catch (error) {\n if (!isRangeLimitError(error)) throw error\n\n let currentBlock = fromBlock\n while (currentBlock <= toBlock) {\n const endBlock =\n currentBlock + safeBatchSize - 1n > toBlock ? toBlock : currentBlock + safeBatchSize - 1n\n await scanRange(currentBlock, endBlock)\n currentBlock = endBlock + 1n\n }\n }\n\n // Build position map: tokenId -> net position size\n const positionMap = new Map<bigint, bigint>()\n\n // Sort all events by block and log index\n const allEvents = [\n ...mintEvents.map((e) => ({ ...e, type: 'mint' as const })),\n ...burnEvents.map((e) => ({ ...e, type: 'burn' as const })),\n ].sort((a, b) => {\n const blockDiff = Number(a.blockNumber - b.blockNumber)\n if (blockDiff !== 0) return blockDiff\n return a.logIndex - b.logIndex\n })\n\n // Process events in order\n for (const event of allEvents) {\n const current = positionMap.get(event.tokenId) ?? 0n\n\n if (event.type === 'mint') {\n positionMap.set(event.tokenId, current + event.positionSize)\n } else {\n positionMap.set(event.tokenId, current - event.positionSize)\n }\n }\n\n // Separate open and closed positions\n const openPositions: bigint[] = []\n const closedPositions: bigint[] = []\n\n for (const [tokenId, size] of positionMap) {\n if (size > 0n) {\n openPositions.push(tokenId)\n } else {\n closedPositions.push(tokenId)\n }\n }\n\n // Get the last block hash\n const lastBlock = await client.getBlock({ blockNumber: toBlock })\n\n return {\n openPositions,\n closedPositions,\n blocksScanned: toBlock - fromBlock + 1n,\n lastBlock: toBlock,\n lastBlockHash: lastBlock.hash,\n }\n}\n\nconst OPTION_MINTED_EVENT = getAbiItem({ abi: panopticPoolV2Abi, name: 'OptionMinted' })\nconst OPTION_BURNT_EVENT = getAbiItem({ abi: panopticPoolV2Abi, name: 'OptionBurnt' })\n\nfunction isRangeLimitError(error: unknown): boolean {\n const messages: string[] = []\n let current: unknown = error\n for (let depth = 0; current && typeof current === 'object' && depth < 5; depth += 1) {\n if ('message' in current && typeof current.message === 'string') {\n messages.push(current.message)\n }\n if ('details' in current && typeof current.details === 'string') {\n messages.push(current.details)\n }\n current = 'cause' in current ? current.cause : undefined\n }\n if (typeof error === 'string') messages.push(error)\n\n const message = messages.join(' ').toLowerCase()\n return (\n message.includes('block range') ||\n message.includes('range is too large') ||\n message.includes('range too large') ||\n message.includes('query returned more than') ||\n message.includes('too many results') ||\n message.includes('log response size exceeded') ||\n message.includes('exceeds the limit') ||\n (message.includes('range') && message.includes('limit'))\n )\n}\n\n/**\n * Get the deployment block for a pool.\n * This searches for the first PoolInitialized event.\n *\n * @param client - viem public client\n * @param poolAddress - Pool address\n * @returns Deployment block number or null if not found\n */\nexport async function getPoolDeploymentBlock(\n client: PublicClient,\n poolAddress: Address,\n): Promise<bigint | null> {\n // Search for the first event from this pool\n // We use a binary search approach to find the deployment block\n\n const currentBlock = await client.getBlockNumber()\n let low = 0n\n let high = currentBlock\n let foundBlock: bigint | null = null\n\n // Binary search with scan windows to find the deployment block.\n // Each iteration checks [mid, mid + scanRange] for logs.\n const scanRange = 10000n\n\n while (low <= high) {\n const mid = (low + high) / 2n\n const rangeEnd = mid + scanRange > high ? high : mid + scanRange\n\n try {\n const logs = await client.getLogs({\n address: poolAddress,\n fromBlock: mid,\n toBlock: rangeEnd,\n })\n\n if (logs.length > 0) {\n // Found logs — record earliest and search before it\n const earliest = logs[0].blockNumber\n if (foundBlock === null || earliest < foundBlock) {\n foundBlock = earliest\n }\n high = earliest - 1n\n } else {\n // No logs in [mid, rangeEnd] — skip the entire checked range\n low = rangeEnd + 1n\n }\n } catch {\n // Range too large for RPC — halve the search space\n high = mid + (rangeEnd - mid) / 2n\n }\n }\n\n return foundBlock\n}\n","/**\n * 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 * Main position synchronization function.\n * @module v2/sync/syncPositions\n */\n\nimport type { Address, Hash, PublicClient } from 'viem'\n\nimport { PositionSnapshotNotFoundError, ProviderLagError, SyncTimeoutError } from '../errors'\nimport { getPoolMetadata } from '../reads/pool'\nimport { getPositions } from '../reads/position'\nimport type { StorageAdapter } from '../storage'\nimport { getPoolMetaKey, getPositionMetaKey, getPositionsKey, jsonSerializer } from '../storage'\nimport type { StoredPoolMeta, StoredPositionData } from '../types'\nimport { getPoolDeploymentBlock, reconstructFromEvents } from './eventReconstruction'\nimport { getOpenPositionIds } from './getTrackedPositionIds'\nimport { detectReorg, loadCheckpoint, saveCheckpoint } from './reorgHandling'\n\n/**\n * Parameters for syncPositions.\n */\nexport interface SyncPositionsParams {\n /** viem public client */\n client: PublicClient\n /** Chain ID */\n chainId: bigint\n /** Pool address */\n poolAddress: Address\n /** Account to sync */\n account: Address\n /** Storage adapter for persistence */\n storage: StorageAdapter\n /** Starting block for sync (defaults to pool deployment block) */\n fromBlock?: bigint\n /** Ending block for sync (defaults to latest) */\n toBlock?: bigint\n /** Max block range per eth_getLogs call (default: 10000n) */\n maxLogsPerQuery?: bigint\n /** Max sync duration in ms (default: 300000n = 5 min) */\n syncTimeout?: bigint\n /** Optional callback for sync progress */\n onUpdate?: (event: SyncProgressEvent) => void\n /** If provider is behind this block, throw ProviderLagError */\n minBlockNumber?: bigint\n /** Manual snapshot tx hash for recovery when automatic fails */\n snapshotTxHash?: Hash\n}\n\n/**\n * Sync progress event for callbacks.\n */\nexport interface SyncProgressEvent {\n /** Event type */\n type: 'position-opened' | 'position-closed' | 'progress' | 'reorg-detected'\n /** TokenId for position events */\n tokenId?: bigint\n /** Current block being processed */\n blockNumber: bigint\n /** Progress info */\n progress?: {\n /** Current block */\n current: bigint\n /** Total blocks to process */\n total: bigint\n }\n}\n\n/**\n * Result of syncPositions.\n */\nexport interface SyncPositionsResult {\n /** Last synced block number */\n lastSyncedBlock: bigint\n /** Last synced block hash */\n lastSyncedBlockHash: Hash\n /** Number of open positions */\n positionCount: bigint\n /** Position IDs discovered */\n positionIds: bigint[]\n /** Whether this was an incremental sync (vs full) */\n incremental: boolean\n /** Duration in milliseconds */\n durationMs: bigint\n}\n\n/**\n * Synchronize positions for an account.\n *\n * This function:\n * 1. Checks for existing checkpoint\n * 2. If no checkpoint: recovers from dispatch() calldata or falls back to full event scan\n * 3. If checkpoint exists: detects reorgs and syncs incrementally\n * 4. Persists positions and checkpoint to storage\n *\n * @param params - Sync parameters\n * @returns Sync result with position count and sync metadata\n * @throws SyncTimeoutError if sync exceeds timeout\n * @throws ProviderLagError if provider is behind minBlockNumber\n * @throws PositionSnapshotNotFoundError if no positions found and no snapshot available\n */\nexport async function syncPositions(params: SyncPositionsParams): Promise<SyncPositionsResult> {\n const {\n client,\n chainId,\n poolAddress,\n account,\n storage,\n syncTimeout = 300000n, // 5 minutes\n onUpdate,\n minBlockNumber,\n snapshotTxHash,\n } = params\n\n const startTime = Date.now()\n\n const checkTimeout = () => {\n const elapsed = BigInt(Date.now() - startTime)\n if (elapsed > syncTimeout) {\n throw new SyncTimeoutError(elapsed, toBlock, 0n)\n }\n }\n\n // Get latest block\n const latestBlock = await client.getBlockNumber()\n const toBlock = params.toBlock ?? latestBlock\n\n // Check for provider lag\n if (minBlockNumber !== undefined && latestBlock < minBlockNumber) {\n throw new ProviderLagError(minBlockNumber, latestBlock)\n }\n\n // Reorg detection using existing checkpoint\n const checkpoint = await loadCheckpoint(storage, chainId, poolAddress, account)\n if (checkpoint) {\n const reorgResult = await detectReorg({\n client,\n chainId,\n poolAddress,\n account,\n storage,\n })\n\n if (reorgResult.detected) {\n onUpdate?.({\n type: 'reorg-detected',\n blockNumber: reorgResult.reorgBlock ?? 0n,\n })\n }\n }\n\n checkTimeout()\n\n // Get authoritative position IDs from latest dispatch calldata.\n // When resuming from a checkpoint, narrow the event scan window to avoid\n // re-scanning the entire chain history on every incremental sync.\n // Returns null when no dispatch event was found in the scanned range,\n // or [] when a dispatch was found with an empty position list.\n const snapshotResult = await getOpenPositionIds({\n client,\n chainId,\n poolAddress,\n account,\n storage,\n lastDispatchTxHash: snapshotTxHash,\n fromBlock: checkpoint?.lastBlock ?? params.fromBlock,\n })\n\n // An explicit empty array is an authoritative snapshot. With no usable\n // snapshot, reconstruct the complete history from account-indexed events:\n // manager contracts can build dispatch calldata internally, so the outer\n // transaction may contain no decodable finalPositionIdList even though its\n // events identify the owner. Always rebuilding from the configured scan floor\n // also repairs older empty or stale checkpoints made for such accounts.\n let positionIds: bigint[]\n if (snapshotResult === null) {\n const fromBlock = params.fromBlock ?? (await getPoolDeploymentBlock(client, poolAddress))\n if (fromBlock === null) {\n throw new PositionSnapshotNotFoundError(new Error('Pool deployment block not found'))\n }\n\n const reconstruction = await reconstructFromEvents({\n client,\n poolAddress,\n account,\n fromBlock,\n toBlock,\n batchSize: params.maxLogsPerQuery,\n onProgress: (progress) => {\n checkTimeout()\n onUpdate?.({\n type: 'progress',\n blockNumber: progress.currentBlock,\n progress: {\n current: progress.currentBlock,\n total: progress.targetBlock,\n },\n })\n },\n })\n positionIds = reconstruction.openPositions\n } else {\n positionIds = snapshotResult\n }\n\n const finalBlock = await client.getBlock({ blockNumber: toBlock })\n\n // If no positions, persist an empty position list and return early.\n if (positionIds.length === 0) {\n await persistPoolAndCheckpoint(params, toBlock, finalBlock.hash, [])\n\n const positionsKey = getPositionsKey(chainId, poolAddress, account)\n await storage.set(positionsKey, jsonSerializer.stringify([]))\n\n return {\n lastSyncedBlock: toBlock,\n lastSyncedBlockHash: finalBlock.hash,\n positionCount: 0n,\n positionIds: [],\n incremental: !!checkpoint,\n durationMs: BigInt(Date.now() - startTime),\n }\n }\n\n checkTimeout()\n\n // Fetch and store position data for all positions\n if (positionIds.length > 0) {\n const { positions } = await getPositions({\n client,\n poolAddress,\n owner: account,\n tokenIds: positionIds,\n blockNumber: toBlock,\n })\n\n for (const pos of positions) {\n const positionMetaKey = getPositionMetaKey(chainId, poolAddress, pos.tokenId)\n const storedData: StoredPositionData = {\n tokenId: pos.tokenId,\n positionSize: pos.positionSize,\n legs: pos.legs,\n tickAtMint: pos.tickAtMint,\n poolUtilization0AtMint: pos.poolUtilization0AtMint,\n poolUtilization1AtMint: pos.poolUtilization1AtMint,\n timestampAtMint: pos.timestampAtMint,\n blockNumberAtMint: pos.blockNumberAtMint,\n swapAtMint: pos.swapAtMint,\n }\n await storage.set(positionMetaKey, jsonSerializer.stringify(storedData))\n }\n }\n\n await persistPoolAndCheckpoint(params, toBlock, finalBlock.hash, positionIds)\n\n // Save positions to storage\n const positionsKey = getPositionsKey(chainId, poolAddress, account)\n await storage.set(positionsKey, jsonSerializer.stringify(positionIds))\n\n return {\n lastSyncedBlock: toBlock,\n lastSyncedBlockHash: finalBlock.hash,\n positionCount: BigInt(positionIds.length),\n positionIds,\n incremental: !!checkpoint,\n durationMs: BigInt(Date.now() - startTime),\n }\n}\n\nasync function persistPoolAndCheckpoint(\n params: SyncPositionsParams,\n lastBlock: bigint,\n lastBlockHash: Hash,\n positionIds: bigint[],\n): Promise<void> {\n const { account, chainId, client, poolAddress, storage } = params\n const poolMetaKey = getPoolMetaKey(chainId, poolAddress)\n const existingPoolMeta = await storage.get(poolMetaKey)\n if (!existingPoolMeta) {\n await fetchAndStorePoolMeta(client, poolAddress, poolMetaKey, storage)\n }\n\n await saveCheckpoint({\n storage,\n chainId,\n poolAddress,\n account,\n lastBlock,\n lastBlockHash,\n positionIds,\n })\n}\n\n/**\n * Fetch full pool metadata and store it.\n * Uses getPoolMetadata to fetch all immutable pool data in minimal RPC calls.\n */\nasync function fetchAndStorePoolMeta(\n client: PublicClient,\n poolAddress: Address,\n poolMetaKey: string,\n storage: StorageAdapter,\n): Promise<void> {\n const metadata = await getPoolMetadata({ client, poolAddress })\n\n const poolMeta: StoredPoolMeta = {\n tickSpacing: metadata.tickSpacing,\n fee: metadata.fee,\n poolId: metadata.poolId,\n collateralToken0Address: metadata.collateralToken0Address,\n collateralToken1Address: metadata.collateralToken1Address,\n riskEngineAddress: metadata.riskEngineAddress,\n token0Asset: metadata.token0Asset,\n token1Asset: metadata.token1Asset,\n token0Symbol: metadata.token0Symbol,\n token1Symbol: metadata.token1Symbol,\n token0Decimals: metadata.token0Decimals,\n token1Decimals: metadata.token1Decimals,\n }\n\n await storage.set(poolMetaKey, jsonSerializer.stringify(poolMeta))\n}\n","/**\n * Force exercise functions for the Panoptic v2 SDK.\n * @module v2/writes/forceExercise\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport type { StorageAdapter } from '../storage'\nimport { syncPositions } from '../sync/syncPositions'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport { submitWrite } from './utils'\n\n/**\n * Parameters for force exercising a position.\n */\nexport interface ForceExerciseParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Exercisor account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Account whose position is being exercised */\n user: Address\n /** Position IDs from the exercisor's account */\n positionIdListFrom: bigint[]\n /** Position IDs of the target user */\n positionIdListTo: bigint[]\n /** Final position ID list for the user after exercise */\n positionIdListToFinal: bigint[]\n /** Packed value for using premia as collateral */\n usePremiaAsCollateral?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n /** Storage adapter for auto-syncing positions after confirmation */\n storage?: StorageAdapter\n /** Chain ID (required when storage is provided) */\n chainId?: bigint\n}\n\n/**\n * Force exercise an ITM (in-the-money) long position.\n *\n * The exercisor calls dispatchFrom to exercise another user's ITM long positions,\n * paying the exercise fee.\n *\n * @param params - Force exercise parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * const result = await forceExercise({\n * client,\n * walletClient,\n * account: exercisorAddress,\n * poolAddress,\n * user: targetAccount,\n * positionIdListFrom: exercisorPositions,\n * positionIdListTo: targetPositions,\n * positionIdListToFinal: [], // Exercise all ITM positions\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function forceExercise(params: ForceExerciseParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n user,\n positionIdListFrom,\n positionIdListTo,\n positionIdListToFinal,\n usePremiaAsCollateral = 0n,\n txOverrides,\n } = params\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatchFrom',\n args: [\n positionIdListFrom,\n user,\n positionIdListTo,\n positionIdListToFinal,\n usePremiaAsCollateral,\n ],\n txOverrides,\n })\n}\n\n/**\n * Force exercise and wait for confirmation.\n *\n * When `storage` and `chainId` are provided, automatically syncs the\n * exercisor's positions after the transaction confirms.\n */\nexport async function forceExerciseAndWait(params: ForceExerciseParams): Promise<TxReceipt> {\n const result = await forceExercise(params)\n const receipt = await result.wait()\n\n const { storage, chainId, client, poolAddress, account } = params\n if (storage && chainId !== undefined) {\n await syncPositions({\n client,\n chainId,\n poolAddress,\n account,\n storage,\n })\n }\n\n return receipt\n}\n","/**\n * Premium settlement functions for the Panoptic v2 SDK.\n * @module v2/writes/settle\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport type { TickAndSpreadLimits } from './position'\nimport { submitWrite } from './utils'\n\n/**\n * Parameters for settling accumulated premia.\n */\nexport interface SettleParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Current position ID list */\n positionIdList: bigint[]\n /** Whether to use premia as collateral */\n usePremiaAsCollateral?: boolean\n /** Builder code */\n builderCode?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Settle accumulated premia on existing positions.\n *\n * This function triggers premium collection without changing position size.\n * It calls dispatch with unchanged position lists.\n *\n * @param params - Settlement parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * const result = await settleAccumulatedPremia({\n * client,\n * walletClient,\n * account,\n * poolAddress,\n * positionIdList: existingPositions,\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function settleAccumulatedPremia(params: SettleParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n positionIdList,\n usePremiaAsCollateral = false,\n builderCode = 0n,\n txOverrides,\n } = params\n\n // For settlement, we call dispatch with:\n // - Same position lists (no change)\n // - Zero position sizes (no size change, just settle)\n // - Wide tick limits\n const positionSizes: bigint[] = positionIdList.map(() => 0n)\n const tickAndSpreadLimits: TickAndSpreadLimits[] = positionIdList.map(\n () => [-887272n, 887272n, 0n] as const,\n )\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n positionIdList,\n positionIdList, // Same list - no change\n positionSizes.map((s) => BigInt(s) as unknown as bigint & { readonly __uint128: true }),\n tickAndSpreadLimits.map(\n (t) => [Number(t[0]), Number(t[1]), Number(t[2])] as readonly [number, number, number],\n ),\n usePremiaAsCollateral,\n builderCode,\n ],\n txOverrides,\n })\n}\n\n/**\n * Settle premia and wait for confirmation.\n */\nexport async function settleAccumulatedPremiaAndWait(params: SettleParams): Promise<TxReceipt> {\n const result = await settleAccumulatedPremia(params)\n return result.wait()\n}\n","/**\n * Oracle poke function for the Panoptic v2 SDK.\n * @module v2/writes/pokeOracle\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { OracleRateLimitedError } from '../errors'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport { decodeOracleTiming, oracleEpochAt } from '../utils/oraclePack'\nimport { submitWrite } from './utils'\n\n/**\n * Parameters for poking the oracle.\n */\nexport interface PokeOracleParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Whether to check rate limit before calling (optional) */\n checkRateLimit?: boolean\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Poke the oracle to update its state.\n *\n * This function can be called to advance the oracle epoch.\n * Note: The oracle can only be poked once per epoch (64 seconds).\n *\n * @param params - Poke oracle parameters\n * @returns TxResult\n * @throws OracleRateLimitedError if checkRateLimit is true and oracle was recently poked\n *\n * @example\n * ```typescript\n * const result = await pokeOracle({\n * client,\n * walletClient,\n * account,\n * poolAddress,\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function pokeOracle(params: PokeOracleParams): Promise<TxResult> {\n const { client, walletClient, account, poolAddress, checkRateLimit = false, txOverrides } = params\n\n if (checkRateLimit) {\n // Check current oracle state to see if we can poke\n // Fetch oracle data and block in parallel\n const [oracleData, block] = await Promise.all([\n client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getOracleTicks',\n }),\n client.getBlock(),\n ])\n\n // oracleData[4] is the oraclePack\n const oraclePack = oracleData[4]\n const { epoch } = decodeOracleTiming(oraclePack, block.timestamp)\n\n const currentEpoch = oracleEpochAt(block.timestamp)\n\n // If current epoch equals oracle epoch, we can't poke yet\n if (currentEpoch === epoch) {\n const lastUpdate = epoch << 6n\n throw new OracleRateLimitedError(lastUpdate, block.timestamp)\n }\n }\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'pokeOracle',\n args: [],\n txOverrides,\n })\n}\n\n/**\n * Poke oracle and wait for confirmation.\n */\nexport async function pokeOracleAndWait(params: PokeOracleParams): Promise<TxReceipt> {\n const result = await pokeOracle(params)\n return result.wait()\n}\n","/**\n * Factory write functions for the Panoptic v2 SDK.\n * @module v2/writes/factory\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport { panopticFactoryV3Abi, panopticFactoryV4Abi } from '../../../generated'\nimport type { PoolKey, TxOverrides, TxResult } from '../types'\nimport { submitWrite } from './utils'\n\ninterface DeployNewPoolCommon {\n /** Public client */\n client: PublicClient\n /** Wallet client for signing */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticFactory address */\n factoryAddress: Address\n /** Risk engine address */\n riskEngine: Address\n /** Salt (uint96) */\n salt: bigint\n /** Optional transaction overrides */\n txOverrides?: TxOverrides\n}\n\nexport interface DeployNewPoolV3Params extends DeployNewPoolCommon {\n /** Token 0 address */\n token0: Address\n /** Token 1 address */\n token1: Address\n /** Fee tier (uint24) */\n fee: bigint\n}\n\nexport interface DeployNewPoolV4Params extends DeployNewPoolCommon {\n /** V4 pool key */\n poolKey: PoolKey\n}\n\nexport type DeployNewPoolParams =\n | ({ version: 'v3' } & DeployNewPoolV3Params)\n | ({ version: 'v4' } & DeployNewPoolV4Params)\n\n/**\n * Deploy a new Panoptic pool via the factory.\n *\n * @param params - Deployment parameters (versioned: 'v3' or 'v4')\n * @returns Transaction result with hash and wait function\n */\nexport async function deployNewPool(params: DeployNewPoolParams): Promise<TxResult> {\n const { client, walletClient, account, factoryAddress, riskEngine, salt, txOverrides } = params\n\n if (params.version === 'v3') {\n return submitWrite({\n client,\n walletClient,\n account,\n address: factoryAddress,\n abi: panopticFactoryV3Abi,\n functionName: 'deployNewPool',\n args: [params.token0, params.token1, params.fee, riskEngine, salt],\n txOverrides,\n })\n }\n\n return submitWrite({\n client,\n walletClient,\n account,\n address: factoryAddress,\n abi: panopticFactoryV4Abi,\n functionName: 'deployNewPool',\n args: [\n {\n currency0: params.poolKey.currency0,\n currency1: params.poolKey.currency1,\n fee: Number(params.poolKey.fee),\n tickSpacing: Number(params.poolKey.tickSpacing),\n hooks: params.poolKey.hooks,\n },\n riskEngine,\n salt,\n ],\n txOverrides,\n })\n}\n\n/**\n * Deploy a new Panoptic pool and wait for confirmation.\n */\nexport async function deployNewPoolAndWait(params: DeployNewPoolParams) {\n const result = await deployNewPool(params)\n return result.wait()\n}\n","/**\n * Transaction replacement utilities for the Panoptic v2 SDK.\n * Provides speedUp and cancel functionality for pending transactions.\n * @module v2/writes/txManagement\n */\n\nimport type { Address, Hash, PublicClient, WalletClient } from 'viem'\n\nimport type { TxBroadcaster, TxResult } from '../types'\nimport { createTxResult } from './utils'\n\n/** Default gas price multiplier for replacement (12.5% bump = minimum for replacement) */\nconst DEFAULT_GAS_PRICE_MULTIPLIER = 1.125\n\n/**\n * Parameters for speeding up a pending transaction.\n */\nexport interface SpeedUpParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Hash of the pending transaction to speed up */\n hash: Hash\n /** Explicit max fee per gas (overrides multiplier) */\n maxFeePerGas?: bigint\n /** Explicit max priority fee per gas (overrides multiplier) */\n maxPriorityFeePerGas?: bigint\n /** Multiplier for gas price bump (default 1.125 = 12.5%, minimum to replace) */\n gasPriceMultiplier?: number\n /** Custom broadcaster for MEV protection */\n broadcaster?: TxBroadcaster\n}\n\n/**\n * Parameters for cancelling a pending transaction.\n */\nexport interface CancelParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address (for self-transfer) */\n account: Address\n /** Hash of the pending transaction to cancel */\n hash: Hash\n /** Explicit max fee per gas (overrides multiplier) */\n maxFeePerGas?: bigint\n /** Explicit max priority fee per gas (overrides multiplier) */\n maxPriorityFeePerGas?: bigint\n /** Multiplier for gas price bump (default 1.125 = 12.5%, minimum to replace) */\n gasPriceMultiplier?: number\n /** Custom broadcaster for MEV protection */\n broadcaster?: TxBroadcaster\n}\n\n/**\n * Apply a multiplier to a bigint gas value.\n * Uses integer arithmetic to avoid floating point issues.\n */\nfunction applyMultiplier(value: bigint, multiplier: number): bigint {\n // Convert multiplier to basis points (e.g., 1.125 => 11250)\n const bps = BigInt(Math.ceil(multiplier * 10000))\n return (value * bps) / 10000n\n}\n\n/**\n * Compute bumped gas parameters from the original transaction.\n */\nfunction computeBumpedGas(\n originalMaxFeePerGas: bigint | undefined,\n originalMaxPriorityFeePerGas: bigint | undefined,\n explicitMaxFeePerGas: bigint | undefined,\n explicitMaxPriorityFeePerGas: bigint | undefined,\n multiplier: number,\n): { maxFeePerGas: bigint; maxPriorityFeePerGas: bigint } {\n const maxFeePerGas =\n explicitMaxFeePerGas ?? applyMultiplier(originalMaxFeePerGas ?? 0n, multiplier)\n\n const maxPriorityFeePerGas =\n explicitMaxPriorityFeePerGas ?? applyMultiplier(originalMaxPriorityFeePerGas ?? 0n, multiplier)\n\n return { maxFeePerGas, maxPriorityFeePerGas }\n}\n\n/**\n * Speed up a pending transaction by resubmitting with higher gas.\n *\n * Fetches the original transaction, extracts its parameters,\n * bumps the gas price, and resubmits with the same nonce.\n *\n * @param params - Speed up parameters\n * @returns TxResult for the replacement transaction\n * @throws Error if the original transaction is not found\n *\n * @example\n * ```typescript\n * // Speed up with default 12.5% bump\n * const result = await speedUpTransaction({\n * client,\n * walletClient,\n * hash: pendingTxHash,\n * })\n *\n * // Speed up with explicit gas prices\n * const result = await speedUpTransaction({\n * client,\n * walletClient,\n * hash: pendingTxHash,\n * maxFeePerGas: 50_000_000_000n, // 50 gwei\n * maxPriorityFeePerGas: 3_000_000_000n, // 3 gwei\n * })\n * ```\n */\nexport async function speedUpTransaction(params: SpeedUpParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n hash,\n maxFeePerGas: explicitMaxFee,\n maxPriorityFeePerGas: explicitMaxPriority,\n gasPriceMultiplier = DEFAULT_GAS_PRICE_MULTIPLIER,\n broadcaster,\n } = params\n\n const tx = await client.getTransaction({ hash })\n\n const { maxFeePerGas, maxPriorityFeePerGas } = computeBumpedGas(\n tx.maxFeePerGas ?? undefined,\n tx.maxPriorityFeePerGas ?? undefined,\n explicitMaxFee,\n explicitMaxPriority,\n gasPriceMultiplier,\n )\n\n if (broadcaster) {\n const request = await walletClient.prepareTransactionRequest({\n account: tx.from,\n to: tx.to ?? undefined,\n data: tx.input,\n value: tx.value,\n nonce: tx.nonce,\n gas: tx.gas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n chain: walletClient.chain,\n })\n\n const signedTx = await walletClient.signTransaction({\n ...request,\n account: tx.from,\n } as unknown as Parameters<WalletClient['signTransaction']>[0])\n const replacementHash = await broadcaster.broadcast(signedTx)\n return createTxResult(client, replacementHash)\n }\n\n const replacementHash = await walletClient.sendTransaction({\n account: tx.from,\n to: tx.to ?? undefined,\n data: tx.input,\n value: tx.value,\n nonce: tx.nonce,\n gas: tx.gas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n chain: walletClient.chain,\n })\n\n return createTxResult(client, replacementHash)\n}\n\n/**\n * Cancel a pending transaction by sending a 0-value self-transfer\n * with the same nonce and higher gas price.\n *\n * @param params - Cancel parameters\n * @returns TxResult for the cancellation transaction\n * @throws Error if the original transaction is not found\n *\n * @example\n * ```typescript\n * const result = await cancelTransaction({\n * client,\n * walletClient,\n * account,\n * hash: pendingTxHash,\n * })\n * await result.wait()\n * ```\n */\nexport async function cancelTransaction(params: CancelParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n hash,\n maxFeePerGas: explicitMaxFee,\n maxPriorityFeePerGas: explicitMaxPriority,\n gasPriceMultiplier = DEFAULT_GAS_PRICE_MULTIPLIER,\n broadcaster,\n } = params\n\n const tx = await client.getTransaction({ hash })\n\n const { maxFeePerGas, maxPriorityFeePerGas } = computeBumpedGas(\n tx.maxFeePerGas ?? undefined,\n tx.maxPriorityFeePerGas ?? undefined,\n explicitMaxFee,\n explicitMaxPriority,\n gasPriceMultiplier,\n )\n\n if (broadcaster) {\n const request = await walletClient.prepareTransactionRequest({\n account,\n to: account,\n value: 0n,\n nonce: tx.nonce,\n gas: 21000n,\n maxFeePerGas,\n maxPriorityFeePerGas,\n chain: walletClient.chain,\n })\n\n const signedTx = await walletClient.signTransaction({\n ...request,\n account,\n } as unknown as Parameters<WalletClient['signTransaction']>[0])\n const cancelHash = await broadcaster.broadcast(signedTx)\n return createTxResult(client, cancelHash)\n }\n\n const cancelHash = await walletClient.sendTransaction({\n account,\n to: account,\n value: 0n,\n nonce: tx.nonce,\n gas: 21000n,\n maxFeePerGas,\n maxPriorityFeePerGas,\n chain: walletClient.chain,\n })\n\n return createTxResult(client, cancelHash)\n}\n","/**\n * 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 * Shared loan utilities for swap and lending modules.\n * @module v2/writes/loanUtils\n */\n\nimport type { Address } from 'viem'\n\nimport {\n InputListFailError,\n LoanSlotExhaustedError,\n MissingPositionIdsError,\n parsePanopticError,\n SwapTokenMismatchError,\n} from '../errors'\nimport type { StorageAdapter } from '../storage'\nimport { getTrackedPositionIds } from '../sync/getTrackedPositionIds'\nimport { createTokenIdBuilder } from '../tokenId/builder'\n\n/** Maximum retry attempts on InputListFail */\nexport const MAX_RETRIES = 3\n\n/**\n * Resolve token index (0 or 1) for the given token address against the pool.\n * Throws SwapTokenMismatchError if the token isn't in the pool.\n */\nexport function resolveTokenIndex(tokenAddress: Address, token0: Address, token1: Address): bigint {\n const lower = tokenAddress.toLowerCase()\n if (lower === token0.toLowerCase()) return 0n\n if (lower === token1.toLowerCase()) return 1n\n throw new SwapTokenMismatchError(tokenAddress, token0, token1)\n}\n\n/**\n * Resolve existing position IDs from explicit param or storage.\n */\nexport async function resolvePositionIds(\n explicit: bigint[] | undefined,\n storage: StorageAdapter | undefined,\n chainId: bigint,\n poolAddress: Address,\n account: Address,\n): Promise<bigint[]> {\n if (explicit !== undefined) return explicit\n if (storage) {\n return getTrackedPositionIds({ chainId, poolAddress, account, storage })\n }\n throw new MissingPositionIdsError()\n}\n\n/**\n * Check if a caught error is an InputListFail contract revert.\n * Works with both raw viem errors and parsed PanopticError instances.\n */\nexport function isInputListFailError(error: unknown): boolean {\n if (error instanceof InputListFailError) return true\n const parsed = parsePanopticError(error)\n return parsed?.errorName === 'InputListFail'\n}\n\n/**\n * Which kind of width=0 leg to build.\n *\n * Loans and credits are the same primitive with the `isLong` bit flipped:\n * a loan borrows from the pool (`isLong=0`), a credit pays into it\n * (`isLong=1`). See `createTokenIdBuilder`'s `addLoan` / `addCredit`.\n */\nexport type WidthZeroLegKind = 'loan' | 'credit'\n\n/**\n * Build a unique width=0 tokenId that doesn't collide with existing positions.\n * Bumps optionRatio (1-127) and returns adjusted size to maintain equivalent exposure.\n *\n * @param kind - Whether to build a loan (borrow) or a credit (pay-in) leg.\n * @param asset - Which token denominates the positionSize (0 or 1).\n */\nexport function buildUniqueWidthZeroLeg(\n kind: WidthZeroLegKind,\n poolId: bigint,\n asset: bigint,\n tokenType: bigint,\n currentTick: bigint,\n tickSpacing: bigint,\n existingPositionIds: bigint[],\n positionSize: bigint,\n): { tokenId: bigint; adjustedSize: bigint } {\n const addLeg = (strike: bigint, optionRatio?: bigint): bigint => {\n const builder = createTokenIdBuilder(poolId)\n const config = { asset, tokenType, strike, optionRatio }\n return (kind === 'loan' ? builder.addLoan(config) : builder.addCredit(config)).build()\n }\n\n // Floor-align to tick spacing (bigint % preserves sign, so handle negatives)\n const mod = currentTick % tickSpacing\n let strike = currentTick - ((mod + tickSpacing) % tickSpacing)\n\n for (let ratio = 1n; ratio <= 127n; ratio++) {\n const tokenId = addLeg(strike, ratio)\n\n if (!existingPositionIds.includes(tokenId)) {\n const adjustedSize = positionSize / ratio\n if (adjustedSize === 0n || positionSize % ratio !== 0n) {\n continue\n }\n return { tokenId, adjustedSize }\n }\n }\n\n // Fallback: try different strikes at ratio=1\n const mod2 = currentTick % tickSpacing\n strike = currentTick - ((mod2 + tickSpacing) % tickSpacing) + tickSpacing\n for (let i = 0; i < 100; i++) {\n const tokenId = addLeg(strike)\n\n if (!existingPositionIds.includes(tokenId)) {\n return { tokenId, adjustedSize: positionSize }\n }\n strike += tickSpacing\n }\n\n throw new LoanSlotExhaustedError()\n}\n\n/**\n * Build a unique loan (borrow) tokenId that doesn't collide with existing positions.\n *\n * @param asset - Which token denominates the positionSize (0 or 1).\n */\nexport function buildUniqueLoan(\n poolId: bigint,\n asset: bigint,\n tokenType: bigint,\n currentTick: bigint,\n tickSpacing: bigint,\n existingPositionIds: bigint[],\n positionSize: bigint,\n): { tokenId: bigint; adjustedSize: bigint } {\n return buildUniqueWidthZeroLeg(\n 'loan',\n poolId,\n asset,\n tokenType,\n currentTick,\n tickSpacing,\n existingPositionIds,\n positionSize,\n )\n}\n\n/**\n * Build a unique credit (pay-in) tokenId that doesn't collide with existing positions.\n *\n * Unlike a loan, a credit never borrows from the pool: it requires **zero** buying\n * power, leaves `s_assetsInAMM` (and therefore utilization and the borrow rate)\n * untouched, and accrues no interest. This is what lets a credit-based swap run\n * against a fully-utilized collateral tracker.\n *\n * @param asset - Which token denominates the positionSize (0 or 1).\n */\nexport function buildUniqueCredit(\n poolId: bigint,\n asset: bigint,\n tokenType: bigint,\n currentTick: bigint,\n tickSpacing: bigint,\n existingPositionIds: bigint[],\n positionSize: bigint,\n): { tokenId: bigint; adjustedSize: bigint } {\n return buildUniqueWidthZeroLeg(\n 'credit',\n poolId,\n asset,\n tokenType,\n currentTick,\n tickSpacing,\n existingPositionIds,\n positionSize,\n )\n}\n","/**\n * Swap functions for the Panoptic v2 SDK.\n *\n * Implements token swaps via Panoptic's **credit** mechanism: open a width=0\n * credit leg and immediately close it in the same dispatch, with `swapAtMint`\n * on exactly one of the two ops.\n *\n * Credits rather than loans because a credit pays into the pool instead of\n * borrowing from it: it requires zero buying power, never touches\n * `s_assetsInAMM`, and so can never be capped by a collateral tracker's\n * utilization or available-to-borrow. A loan-based swap against a\n * fully-utilized tracker simply fails.\n *\n * @module v2/writes/swap\n */\n\nimport type { Address, Hex, PublicClient, WalletClient } from 'viem'\nimport { encodeFunctionData } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { MaxRetriesExceededError } from '../errors'\nimport { tickLimits } from '../formatters/tick'\nimport { getPool } from '../reads/pool'\nimport type { StorageAdapter } from '../storage'\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport {\n buildUniqueCredit,\n isInputListFailError,\n MAX_RETRIES,\n resolvePositionIds,\n resolveTokenIndex,\n} from './loanUtils'\nimport { submitWrite } from './utils'\n\n/**\n * Parameters for building an atomic credit swap call.\n *\n * `tokenIndex` is tokenOut for exact-out swaps and tokenIn for exact-in swaps.\n * Passing the counter-token reverses the intended swap direction.\n */\nexport type CreditSwapCallParams = {\n poolAddress: Address\n poolId: bigint\n currentTick: bigint\n tickSpacing: bigint\n existingPositionIds: bigint[]\n tokenIndex: bigint\n slippageBps: bigint\n builderCode?: bigint\n} & ({ kind: 'exactIn'; amountIn: bigint } | { kind: 'exactOut'; amountOut: bigint })\n\n/** Encoded atomic credit mint/burn dispatch and its derived credit position. */\nexport interface CreditSwapCall {\n to: Address\n data: Hex\n creditTokenId: bigint\n adjustedSize: bigint\n args: readonly [\n readonly bigint[],\n readonly bigint[],\n readonly bigint[],\n readonly (readonly [number, number, number])[],\n boolean,\n bigint,\n ]\n}\n\n/** Build an atomic credit mint/burn swap without fetching or sending anything. */\nexport function buildCreditSwapCall(params: CreditSwapCallParams): CreditSwapCall {\n const amount = params.kind === 'exactIn' ? params.amountIn : params.amountOut\n if (amount <= 0n) throw new Error('credit swap amount must be positive')\n if (params.tokenIndex !== 0n && params.tokenIndex !== 1n) {\n throw new Error('credit swap tokenIndex must be 0 or 1')\n }\n\n const { low, high } = tickLimits(params.currentTick, params.slippageBps)\n const { tokenId: creditTokenId, adjustedSize } = buildUniqueCredit(\n params.poolId,\n params.tokenIndex,\n params.tokenIndex,\n params.currentTick,\n params.tickSpacing,\n params.existingPositionIds,\n amount,\n )\n const ascending = [Number(low), Number(high), 0] as const\n const descending = [Number(high), Number(low), 0] as const\n const limits =\n params.kind === 'exactIn'\n ? ([ascending, descending] as const)\n : ([descending, ascending] as const)\n const args = [\n [creditTokenId, creditTokenId],\n [...params.existingPositionIds],\n [adjustedSize, 0n],\n limits,\n false,\n params.builderCode ?? 0n,\n ] as const\n\n return {\n to: params.poolAddress,\n data: encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args,\n }),\n creditTokenId,\n adjustedSize,\n args,\n }\n}\n\n/**\n * Parameters for swapExactOut.\n */\nexport interface SwapExactOutParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Chain ID (required for pool data fetch) */\n chainId: bigint\n /** Token address you want to receive */\n tokenOut: Address\n /** Exact amount of tokenOut to receive */\n amountOut: bigint\n /** Slippage tolerance in bps (e.g. 500n = 5%) */\n slippageBps: bigint\n /** Existing position IDs. If omitted, resolved from storage. */\n existingPositionIds?: bigint[]\n /** Storage adapter for position ID resolution */\n storage?: StorageAdapter\n /** Builder code for referral fee attribution. Defaults to `0n`. */\n builderCode?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Parameters for swapExactIn.\n */\nexport interface SwapExactInParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Chain ID (required for pool data fetch) */\n chainId: bigint\n /** Token address you want to sell */\n tokenIn: Address\n /** Exact amount of tokenIn to spend */\n amountIn: bigint\n /** Slippage tolerance in bps (e.g. 500n = 5%) */\n slippageBps: bigint\n /** Existing position IDs. If omitted, resolved from storage. */\n existingPositionIds?: bigint[]\n /** Storage adapter for position ID resolution */\n storage?: StorageAdapter\n /** Builder code for referral fee attribution. Defaults to `0n`. */\n builderCode?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Swap tokens using Panoptic's exact-output mechanism.\n *\n * Opens a credit in `tokenOut` with `swapAtMint=true` (paying a swapped amount of\n * the other token), then burns it with `swapAtMint=false` to receive exactly\n * `amountOut` of `tokenOut`.\n *\n * @param params - Swap parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * const result = await swapExactOut({\n * client, walletClient, account, poolAddress,\n * chainId: 11155111n,\n * tokenOut: WETH_ADDRESS,\n * amountOut: 5n * 10n**16n, // 0.05 WETH\n * slippageBps: 500n, // 5% slippage\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function swapExactOut(params: SwapExactOutParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n chainId,\n tokenOut,\n amountOut,\n slippageBps,\n existingPositionIds: explicitIds,\n storage,\n builderCode = 0n,\n txOverrides,\n } = params\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n // Re-fetch pool + positions on each attempt for freshness\n const [pool, positionIds] = await Promise.all([\n getPool({ client, poolAddress, chainId }),\n resolvePositionIds(explicitIds, storage, chainId, poolAddress, account),\n ])\n\n const token0 = pool.collateralTracker0.token\n const token1 = pool.collateralTracker1.token\n const tokenOutIndex = resolveTokenIndex(tokenOut, token0, token1)\n\n // The credit is denominated in the EXACT token — tokenOut here, mirroring\n // swapExactIn's tokenIn. asset === tokenType.\n //\n // Do NOT set tokenType to the other token. That is correct for a *loan*\n // (which borrows the counter-token and swaps it in), and carrying it over to\n // the credit inverts the whole swap: an exact-out for 4 ETH then PAYS 4 ETH\n // and receives USDC. Verified on mainnet before/after.\n const call = buildCreditSwapCall({\n kind: 'exactOut',\n poolAddress,\n poolId: pool.poolId,\n currentTick: pool.currentTick,\n tickSpacing: pool.tickSpacing,\n existingPositionIds: positionIds,\n tokenIndex: tokenOutIndex,\n amountOut,\n slippageBps,\n builderCode,\n })\n\n try {\n return await submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: call.args,\n txOverrides,\n })\n } catch (error) {\n if (isInputListFailError(error) && attempt < MAX_RETRIES - 1) {\n continue\n }\n throw error\n }\n }\n\n throw new MaxRetriesExceededError('swapExactOut')\n}\n\n/**\n * Swap exact output and wait for confirmation.\n */\nexport async function swapExactOutAndWait(params: SwapExactOutParams): Promise<TxReceipt> {\n const result = await swapExactOut(params)\n return result.wait()\n}\n\n/**\n * Swap tokens using Panoptic's exact-input mechanism.\n *\n * Opens a credit in `tokenIn` with `swapAtMint=false` (paying exactly `amountIn`),\n * then burns it with `swapAtMint=true` to receive the swapped amount of the other\n * token. The user spends exactly `amountIn` of `tokenIn`.\n *\n * @param params - Swap parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * const result = await swapExactIn({\n * client, walletClient, account, poolAddress,\n * chainId: 11155111n,\n * tokenIn: USDC_ADDRESS,\n * amountIn: 1000n * 10n**6n, // 1000 USDC\n * slippageBps: 500n,\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function swapExactIn(params: SwapExactInParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n chainId,\n tokenIn,\n amountIn,\n slippageBps,\n existingPositionIds: explicitIds,\n storage,\n builderCode = 0n,\n txOverrides,\n } = params\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n const [pool, positionIds] = await Promise.all([\n getPool({ client, poolAddress, chainId }),\n resolvePositionIds(explicitIds, storage, chainId, poolAddress, account),\n ])\n\n const token0 = pool.collateralTracker0.token\n const token1 = pool.collateralTracker1.token\n const tokenInIndex = resolveTokenIndex(tokenIn, token0, token1)\n\n // For exact input: the credit is denominated in tokenIn and paid in tokenIn\n const call = buildCreditSwapCall({\n kind: 'exactIn',\n poolAddress,\n poolId: pool.poolId,\n currentTick: pool.currentTick,\n tickSpacing: pool.tickSpacing,\n existingPositionIds: positionIds,\n tokenIndex: tokenInIndex,\n amountIn,\n slippageBps,\n builderCode,\n })\n\n try {\n return await submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: call.args,\n txOverrides,\n })\n } catch (error) {\n if (isInputListFailError(error) && attempt < MAX_RETRIES - 1) {\n continue\n }\n throw error\n }\n }\n\n throw new MaxRetriesExceededError('swapExactIn')\n}\n\n/**\n * Swap exact input and wait for confirmation.\n */\nexport async function swapExactInAndWait(params: SwapExactInParams): Promise<TxReceipt> {\n const result = await swapExactIn(params)\n return result.wait()\n}\n","/**\n * Wrap / unwrap operations for Backed xStock ERC4626 wrappers.\n *\n * xStocks are rebasing and can't be used in Panoptic/Uniswap pools directly;\n * those trade the non-rebasing **wrapper** (a standard ERC4626 vault whose\n * `asset()` is the underlying xStock). Wrapping is an ERC4626 `deposit`,\n * unwrapping an ERC4626 `redeem`. CoW Swap trades the unwrapped token, so a\n * user who buys an xStock on CoW must wrap it before lending it or selling it\n * through the Uniswap venue.\n *\n * Resolve a token's wrapper with `getXstockWrapper` from `@panoptic-eng/sdk`.\n *\n * @module v2/writes/wrap\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport type { TxOverrides, TxReceipt, TxResult } from '../types'\nimport { submitWrite } from './utils'\n\n/** Minimal ERC4626 surface used by the xStock wrappers. */\nexport const xstockWrapperAbi = [\n {\n type: 'function',\n name: 'deposit',\n stateMutability: 'nonpayable',\n inputs: [\n { name: 'assets', type: 'uint256' },\n { name: 'receiver', type: 'address' },\n ],\n outputs: [{ name: 'shares', type: 'uint256' }],\n },\n {\n type: 'function',\n name: 'redeem',\n stateMutability: 'nonpayable',\n inputs: [\n { name: 'shares', type: 'uint256' },\n { name: 'receiver', type: 'address' },\n { name: 'owner', type: 'address' },\n ],\n outputs: [{ name: 'assets', type: 'uint256' }],\n },\n {\n type: 'function',\n name: 'asset',\n stateMutability: 'view',\n inputs: [],\n outputs: [{ type: 'address' }],\n },\n {\n type: 'function',\n name: 'previewDeposit',\n stateMutability: 'view',\n inputs: [{ name: 'assets', type: 'uint256' }],\n outputs: [{ name: 'shares', type: 'uint256' }],\n },\n {\n type: 'function',\n name: 'previewRedeem',\n stateMutability: 'view',\n inputs: [{ name: 'shares', type: 'uint256' }],\n outputs: [{ name: 'assets', type: 'uint256' }],\n },\n {\n type: 'function',\n name: 'maxRedeem',\n stateMutability: 'view',\n inputs: [{ name: 'owner', type: 'address' }],\n outputs: [{ name: 'maxShares', type: 'uint256' }],\n },\n] as const\n\n/** Parameters for {@link wrapXstock}. */\nexport interface WrapXstockParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** Wrapper (ERC4626) address — resolve via `getXstockWrapper`. */\n wrapper: Address\n /** Amount of the underlying xStock to wrap. */\n assets: bigint\n /** Receiver of the wrapper shares (defaults to account). */\n receiver?: Address\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Wrap an underlying xStock into its ERC4626 wrapper (`deposit`). Requires a\n * prior ERC20 approval of the underlying to the wrapper address.\n *\n * @returns TxResult with hash and wait function\n */\nexport async function wrapXstock(params: WrapXstockParams): Promise<TxResult> {\n const { client, walletClient, account, wrapper, assets, receiver = account, txOverrides } = params\n return submitWrite({\n client,\n walletClient,\n account,\n address: wrapper,\n abi: xstockWrapperAbi,\n functionName: 'deposit',\n args: [assets, receiver],\n txOverrides,\n })\n}\n\n/** Wrap and wait for confirmation. */\nexport async function wrapXstockAndWait(params: WrapXstockParams): Promise<TxReceipt> {\n const result = await wrapXstock(params)\n return result.wait()\n}\n\n/** Parameters for {@link unwrapXstock}. */\nexport interface UnwrapXstockParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** Wrapper (ERC4626) address — resolve via `getXstockUnderlying`. */\n wrapper: Address\n /** Amount of wrapper shares to unwrap (redeem). */\n shares: bigint\n /** Receiver of the underlying xStock (defaults to account). */\n receiver?: Address\n /** Owner of the shares (defaults to account). */\n owner?: Address\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Unwrap wrapper shares back into the underlying xStock (`redeem`). When\n * `owner` defaults to (or equals) `account` the caller burns their own shares\n * and no approval is needed. Passing a different `owner` redeems on its behalf\n * and requires that owner to have granted the caller an ERC-4626 share\n * allowance (`approve`), or the `redeem` call reverts.\n *\n * @returns TxResult with hash and wait function\n */\nexport async function unwrapXstock(params: UnwrapXstockParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n wrapper,\n shares,\n receiver = account,\n owner = account,\n txOverrides,\n } = params\n return submitWrite({\n client,\n walletClient,\n account,\n address: wrapper,\n abi: xstockWrapperAbi,\n functionName: 'redeem',\n args: [shares, receiver, owner],\n txOverrides,\n })\n}\n\n/** Unwrap and wait for confirmation. */\nexport async function unwrapXstockAndWait(params: UnwrapXstockParams): Promise<TxReceipt> {\n const result = await unwrapXstock(params)\n return result.wait()\n}\n\n/** Parameters for the wrap/unwrap amount previews. */\nexport interface PreviewWrapParams {\n /** Public client */\n client: PublicClient\n /** Wrapper (ERC4626) address. */\n wrapper: Address\n /** Amount to convert: underlying assets for wrap, shares for unwrap. */\n amount: bigint\n}\n\n/**\n * Preview the wrapper shares minted for a given amount of underlying xStock.\n */\nexport async function previewWrap(params: PreviewWrapParams): Promise<bigint> {\n const { client, wrapper, amount } = params\n return client.readContract({\n address: wrapper,\n abi: xstockWrapperAbi,\n functionName: 'previewDeposit',\n args: [amount],\n })\n}\n\n/**\n * Preview the underlying xStock returned for a given amount of wrapper shares.\n */\nexport async function previewUnwrap(params: PreviewWrapParams): Promise<bigint> {\n const { client, wrapper, amount } = params\n return client.readContract({\n address: wrapper,\n abi: xstockWrapperAbi,\n functionName: 'previewRedeem',\n args: [amount],\n })\n}\n\n/**\n * Minimal canonical WETH9 surface used for ETH<->WETH wrapping. Unlike the\n * ERC4626 xStock wrapper, WETH is a 1:1 wrapper: `deposit` is payable and wraps\n * `msg.value`, `withdraw` unwraps an exact amount back to native ETH.\n */\nexport const wethWrapAbi = [\n {\n type: 'function',\n name: 'deposit',\n stateMutability: 'payable',\n inputs: [],\n outputs: [],\n },\n {\n type: 'function',\n name: 'withdraw',\n stateMutability: 'nonpayable',\n inputs: [{ name: 'wad', type: 'uint256' }],\n outputs: [],\n },\n] as const\n\n/** Parameters for {@link wrapEth}. */\nexport interface WrapEthParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** Canonical WETH9 address for the chain. */\n weth: Address\n /** Amount of native ETH to wrap (sent as msg.value). */\n amount: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Wrap native ETH into WETH (`deposit` payable). No approval needed.\n *\n * @returns TxResult with hash and wait function\n */\nexport async function wrapEth(params: WrapEthParams): Promise<TxResult> {\n const { client, walletClient, account, weth, amount, txOverrides } = params\n return submitWrite({\n client,\n walletClient,\n account,\n address: weth,\n abi: wethWrapAbi,\n functionName: 'deposit',\n args: [],\n value: amount,\n txOverrides,\n })\n}\n\n/** Wrap ETH and wait for confirmation. */\nexport async function wrapEthAndWait(params: WrapEthParams): Promise<TxReceipt> {\n const result = await wrapEth(params)\n return result.wait()\n}\n\n/** Parameters for {@link unwrapWeth}. */\nexport interface UnwrapWethParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** Canonical WETH9 address for the chain. */\n weth: Address\n /** Amount of WETH to unwrap back to native ETH. */\n amount: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/**\n * Unwrap WETH back into native ETH (`withdraw`). Burns the caller's own WETH —\n * no approval needed.\n *\n * @returns TxResult with hash and wait function\n */\nexport async function unwrapWeth(params: UnwrapWethParams): Promise<TxResult> {\n const { client, walletClient, account, weth, amount, txOverrides } = params\n return submitWrite({\n client,\n walletClient,\n account,\n address: weth,\n abi: wethWrapAbi,\n functionName: 'withdraw',\n args: [amount],\n txOverrides,\n })\n}\n\n/** Unwrap WETH and wait for confirmation. */\nexport async function unwrapWethAndWait(params: UnwrapWethParams): Promise<TxReceipt> {\n const result = await unwrapWeth(params)\n return result.wait()\n}\n","/**\n * 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 * Token flow simulation utility using PanopticPool.multicall.\n *\n * Uses getAssetsOf-dispatch-getAssetsOf pattern within a single eth_call\n * to measure exact collateral asset movements from any dispatch call.\n *\n * @module v2/simulations/tokenFlow\n */\n\nimport {\n type Address,\n type Hex,\n type PublicClient,\n decodeFunctionResult,\n encodeFunctionData,\n} from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { panopticErrorsAbi } from '../errors/errorsAbi'\n\n/**\n * PanopticPool getAssetsOf ABI.\n * Returns collateral assets (shares converted to underlying) for an account.\n */\nconst getAssetsOfAbi = [\n {\n type: 'function',\n name: 'getAssetsOf',\n inputs: [{ name: 'account', type: 'address' }],\n outputs: [\n { name: 'assets0', type: 'uint256' },\n { name: 'assets1', type: 'uint256' },\n ],\n stateMutability: 'view',\n },\n] as const\n\n/**\n * PanopticPool multicall ABI (inherited from Uniswap).\n * Uses delegatecall, preserving msg.sender throughout the chain.\n */\nconst multicallAbi = [\n {\n type: 'function',\n name: 'multicall',\n inputs: [{ name: 'data', type: 'bytes[]' }],\n outputs: [{ name: 'results', type: 'bytes[]' }],\n stateMutability: 'nonpayable',\n },\n // Include error definitions so viem can decode revert data with full args\n ...panopticErrorsAbi,\n] as const\n\n/**\n * Token flow result from simulation.\n * Measures collateral asset changes via getAssetsOf-dispatch-getAssetsOf pattern.\n */\nexport interface TokenFlow {\n /** Token 0 collateral change (negative = user deposits, positive = user receives) */\n delta0: bigint\n /** Token 1 collateral change (negative = user deposits, positive = user receives) */\n delta1: bigint\n /** Collateral assets in token 0 before the call */\n balanceBefore0: bigint\n /** Collateral assets in token 1 before the call */\n balanceBefore1: bigint\n /** Collateral assets in token 0 after the call */\n balanceAfter0: bigint\n /** Collateral assets in token 1 after the call */\n balanceAfter1: bigint\n /** Pool tick before the operation */\n tickBefore: bigint | null\n /** Pool tick after the operation */\n tickAfter: bigint | null\n}\n\n/**\n * Parameters for simulateWithTokenFlow.\n */\nexport interface SimulateWithTokenFlowParams {\n /** viem public client */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** User address whose collateral changes we're measuring */\n user: Address\n /** Encoded call data (typically dispatch) */\n callData: Hex\n /** Optional block number for simulation */\n blockNumber?: bigint\n /**\n * Optional additional encoded calls to append after the 5-call pattern.\n * These execute post-dispatch within the same multicall (same state).\n * Raw encoded bytes are returned in `postCallResults`.\n */\n postCallData?: Hex[]\n /**\n * Optional additional encoded calls to insert between the pre-dispatch\n * `getAssetsOf` / `getCurrentTick` and the target call. These execute\n * pre-dispatch within the same multicall — useful for reading per-position\n * data (e.g. `getFullPositionsData`) against the original `positionIdList`\n * before state mutates. Raw encoded bytes are returned in `preCallResults`.\n */\n preCallData?: Hex[]\n}\n\n/**\n * Result of simulateWithTokenFlow.\n */\nexport interface SimulateWithTokenFlowResult {\n /** Whether the simulation succeeded */\n success: boolean\n /** Token flow data (only if success) */\n tokenFlow?: TokenFlow\n /** Error message (only if failed) */\n error?: string\n /** Raw error object preserving viem cause chain and revert data */\n rawError?: Error\n /** Gas estimate for the inner call */\n gasEstimate: bigint\n /** Raw results from postCallData entries (only if success and postCallData was provided) */\n postCallResults?: Hex[]\n /** Raw results from preCallData entries (only if success and preCallData was provided) */\n preCallResults?: Hex[]\n}\n\n/**\n * Simulate a contract call and measure token flow using PanopticPool.multicall.\n *\n * This function uses PanopticPool's inherited multicall (delegatecall-based) to chain:\n * 1. getAssetsOf(user) - read collateral assets before\n * 2. getCurrentTick() - read pool tick before\n * 3. Execute the target call (e.g., dispatch)\n * 4. getCurrentTick() - read pool tick after\n * 5. getAssetsOf(user) - read collateral assets after\n *\n * ## Why PanopticPool.multicall instead of Multicall3?\n * - Measures **collateral assets** (shares → underlying), not raw wallet balances\n * - Uses **delegatecall**, preserving msg.sender throughout the chain\n * - Single contract interaction with PanopticPool\n * - Correctly reflects what happens during position operations\n *\n * ## Same-Block Guarantee\n * All operations execute within a single eth_call, ensuring atomic consistency.\n *\n * @param params - Simulation parameters\n * @returns Token flow result\n *\n * @example\n * ```typescript\n * const callData = encodeFunctionData({\n * abi: panopticPoolV2Abi,\n * functionName: 'dispatch',\n * args: [positionIdList, finalPositionIdList, positionSizes, tickAndSpreadLimits, false, 0n],\n * })\n *\n * const result = await simulateWithTokenFlow({\n * client,\n * poolAddress,\n * user: userAddress,\n * callData,\n * })\n *\n * if (result.success) {\n * console.log('Token 0 change:', result.tokenFlow.delta0)\n * console.log('Token 1 change:', result.tokenFlow.delta1)\n * }\n * ```\n */\nexport async function simulateWithTokenFlow(\n params: SimulateWithTokenFlowParams,\n): Promise<SimulateWithTokenFlowResult> {\n const { client, poolAddress, user, callData, blockNumber, postCallData, preCallData } = params\n\n // Encode getAssetsOf call\n const getAssetsOfCallData = encodeFunctionData({\n abi: getAssetsOfAbi,\n functionName: 'getAssetsOf',\n args: [user],\n })\n\n // Encode getCurrentTick call\n const getCurrentTickCallData = encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n })\n\n const preLen = preCallData?.length ?? 0\n\n // Build multicall: [getAssetsOf, getCurrentTick, ...preCallData, targetCall, getCurrentTick, getAssetsOf, ...postCallData]\n const multicallData: Hex[] = [\n getAssetsOfCallData,\n getCurrentTickCallData,\n ...(preCallData ?? []),\n callData,\n getCurrentTickCallData,\n getAssetsOfCallData,\n ...(postCallData ?? []),\n ]\n\n try {\n // Execute via simulateContract on PanopticPool's multicall\n const { result } = await client.simulateContract({\n address: poolAddress,\n abi: multicallAbi,\n functionName: 'multicall',\n args: [multicallData],\n account: user,\n blockNumber,\n })\n\n // Decode getAssetsOf results\n const decodeAssets = (data: Hex): { assets0: bigint; assets1: bigint } => {\n const decoded = decodeFunctionResult({\n abi: getAssetsOfAbi,\n functionName: 'getAssetsOf',\n data,\n })\n return { assets0: decoded[0], assets1: decoded[1] }\n }\n\n // Decode getCurrentTick result (int24 decodes as number, convert to bigint)\n const decodeTick = (data: Hex): bigint => {\n return BigInt(\n decodeFunctionResult({\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n data,\n }),\n )\n }\n\n const assetsBefore = decodeAssets(result[0])\n const tickBefore = decodeTick(result[1])\n // result[2..2+preLen-1] are preCallData results\n // result[2+preLen] is the target call result (dispatch)\n const tickAfter = decodeTick(result[3 + preLen])\n const assetsAfter = decodeAssets(result[4 + preLen])\n\n const preCallResults = preLen > 0 ? (result.slice(2, 2 + preLen) as Hex[]) : undefined\n const postCallResults =\n postCallData && postCallData.length > 0 ? (result.slice(5 + preLen) as Hex[]) : undefined\n\n const delta0 = assetsAfter.assets0 - assetsBefore.assets0\n const delta1 = assetsAfter.assets1 - assetsBefore.assets1\n\n // Estimate gas for the target call directly\n let gasEstimate = 0n\n try {\n gasEstimate = await client.estimateGas({\n account: user,\n to: poolAddress,\n data: callData,\n blockNumber,\n })\n } catch {\n // Gas estimation may fail, use 0\n }\n\n return {\n success: true,\n tokenFlow: {\n delta0,\n delta1,\n balanceBefore0: assetsBefore.assets0,\n balanceBefore1: assetsBefore.assets1,\n balanceAfter0: assetsAfter.assets0,\n balanceAfter1: assetsAfter.assets1,\n tickBefore,\n tickAfter,\n },\n gasEstimate,\n postCallResults,\n preCallResults,\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Simulation failed',\n rawError: error instanceof Error ? error : undefined,\n gasEstimate: 0n,\n }\n }\n}\n\n/**\n * Parameters for getting pool tokens.\n */\nexport interface GetPoolTokensParams {\n /** viem public client */\n client: PublicClient\n /** Pool address */\n poolAddress: Address\n /** Optional block number */\n blockNumber?: bigint\n}\n\n/**\n * Pool token addresses result.\n */\nexport interface PoolTokens {\n /** Token 0 address */\n token0: Address\n /** Token 1 address */\n token1: Address\n /** Collateral tracker 0 address */\n collateralTracker0: Address\n /** Collateral tracker 1 address */\n collateralTracker1: Address\n}\n\n/**\n * Get pool token addresses for reference.\n *\n * @param params - Parameters\n * @returns Pool token addresses\n */\nexport async function getPoolTokensForSimulation(params: GetPoolTokensParams): Promise<PoolTokens> {\n const { client, poolAddress, blockNumber } = params\n\n // Minimal ABI for the calls we need\n const poolAbi = [\n {\n type: 'function',\n name: 'collateralToken0',\n inputs: [],\n outputs: [{ type: 'address' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'collateralToken1',\n inputs: [],\n outputs: [{ type: 'address' }],\n stateMutability: 'view',\n },\n ] as const\n\n const collateralAbi = [\n {\n type: 'function',\n name: 'asset',\n inputs: [],\n outputs: [{ type: 'address' }],\n stateMutability: 'view',\n },\n ] as const\n\n // Get collateral tracker addresses\n const [ct0, ct1] = await client.multicall({\n contracts: [\n { address: poolAddress, abi: poolAbi, functionName: 'collateralToken0' },\n { address: poolAddress, abi: poolAbi, functionName: 'collateralToken1' },\n ],\n blockNumber,\n allowFailure: false,\n })\n\n // Get underlying token addresses from collateral trackers\n const [token0, token1] = await client.multicall({\n contracts: [\n { address: ct0, abi: collateralAbi, functionName: 'asset' },\n { address: ct1, abi: collateralAbi, functionName: 'asset' },\n ],\n blockNumber,\n allowFailure: false,\n })\n\n return {\n token0,\n token1,\n collateralTracker0: ct0,\n collateralTracker1: ct1,\n }\n}\n","/**\n * Open position simulation for the Panoptic v2 SDK.\n * @module v2/simulations/simulateOpenPosition\n */\n\nimport type { Address, PublicClient } from 'viem'\nimport { decodeFunctionResult, encodeFunctionData } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { getBlockMeta } from '../clients'\nimport { PanopticError } from '../errors'\nimport { calculatePositionGreeks } from '../greeks'\nimport { getPool } from '../reads/pool'\nimport { decodeTokenId } from '../tokenId/decode'\nimport type { OpenPositionSimulation, SimulationResult } from '../types'\nimport { decodeLeftRightUnsigned } from '../writes/utils'\nimport { simulateWithTokenFlow } from './tokenFlow'\n\n/**\n * Parameters for simulating position opening.\n */\nexport interface SimulateOpenPositionParams {\n /** Public client */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** Existing position IDs held by the account (before this mint) */\n existingPositionIds: bigint[]\n /** TokenId of position to open */\n tokenId: bigint\n /** Position size */\n positionSize: bigint\n /**\n * Lower tick limit (always <= tickLimitHigh).\n * Use MIN_TICK (-887272n) to allow any downward price movement.\n */\n tickLimitLow: bigint\n /**\n * Upper tick limit (always >= tickLimitLow).\n * Use MAX_TICK (887272n) to allow any upward price movement.\n */\n tickLimitHigh: bigint\n /** Spread limit tick (use 0n for no spread limit) */\n spreadLimit?: bigint\n /**\n * Whether to swap tokens at mint to achieve single-sided exposure.\n * When true, tickLimits are passed to dispatch in descending order (high, low).\n * When false (default), tickLimits are passed in ascending order (low, high).\n */\n swapAtMint?: boolean\n /** Whether to use premia as collateral */\n usePremiaAsCollateral?: boolean\n /** Builder code */\n builderCode?: bigint\n /** Chain ID (required for pool data fetch used in greeks) */\n chainId?: bigint\n /** Optional block number for simulation */\n blockNumber?: bigint\n}\n\n/**\n * Simulate opening a position.\n *\n * Uses PanopticPool.multicall with getAssetsOf-dispatch-getAssetsOf pattern\n * to measure exact collateral asset movements, then enriches with decoded\n * position data and client-side greeks.\n *\n * @param params - Simulation parameters\n * @returns Simulation result with position data or error\n *\n * @example\n * ```typescript\n * import { MIN_TICK, MAX_TICK } from '@panoptic/sdk'\n *\n * const result = await simulateOpenPosition({\n * client,\n * poolAddress,\n * account,\n * existingPositionIds: [],\n * tokenId,\n * positionSize: 1n,\n * tickLimitLow: MIN_TICK,\n * tickLimitHigh: MAX_TICK,\n * swapAtMint: false,\n * chainId: 11155111n, // Sepolia\n * })\n *\n * if (result.success) {\n * console.log('Gas estimate:', result.gasEstimate)\n * console.log('Token 0 required:', result.data.amount0Required)\n * console.log('Token 1 required:', result.data.amount1Required)\n * console.log('Delta:', result.data.greeks.delta)\n * } else {\n * console.log('Error:', result.error)\n * }\n * ```\n */\nexport async function simulateOpenPosition(\n params: SimulateOpenPositionParams,\n): Promise<SimulationResult<OpenPositionSimulation>> {\n const {\n client,\n poolAddress,\n account,\n existingPositionIds,\n tokenId,\n positionSize,\n tickLimitLow,\n tickLimitHigh,\n spreadLimit = 0n,\n swapAtMint = false,\n usePremiaAsCollateral = false,\n builderCode = 0n,\n chainId,\n blockNumber,\n } = params\n\n const targetBlockNumber = blockNumber ?? (await client.getBlockNumber())\n const metaPromise = getBlockMeta({ client, blockNumber: targetBlockNumber })\n\n // Build tick limits based on swapAtMint flag:\n // - swapAtMint=true: descending order (high, low) triggers SFPM swap\n // - swapAtMint=false: ascending order (low, high) no swap\n const tickLimits: readonly [number, number, number] = swapAtMint\n ? [Number(tickLimitHigh), Number(tickLimitLow), Number(spreadLimit)]\n : [Number(tickLimitLow), Number(tickLimitHigh), Number(spreadLimit)]\n\n try {\n // Prepare position lists for dispatch:\n // - positionIdList: positions being minted in this call (just the new tokenId)\n // - finalPositionIdList: all positions the user will have after the mint\n const positionIdList = [tokenId]\n const finalPositionIdList = [...existingPositionIds, tokenId]\n\n // Encode dispatch call data\n const callData = encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n positionIdList,\n finalPositionIdList,\n // ABI declares uint128 but TS only knows bigint — viem/abitype limitation\n [BigInt(positionSize) as unknown as bigint & { readonly __uint128: true }],\n [tickLimits],\n usePremiaAsCollateral,\n builderCode,\n ],\n })\n\n // Encode getFullPositionsData to run post-dispatch in the same multicall\n const getFullPositionsDataCallData = encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [account, false, finalPositionIdList],\n })\n\n // Simulate with token flow measurement using PanopticPool.multicall + getAssetsOf\n const flowResult = await simulateWithTokenFlow({\n client,\n poolAddress,\n user: account,\n callData,\n blockNumber: targetBlockNumber,\n postCallData: [getFullPositionsDataCallData],\n })\n\n if (!flowResult.success || !flowResult.tokenFlow) {\n throw (\n flowResult.rawError ?? new PanopticError(flowResult.error || 'Token flow simulation failed')\n )\n }\n\n const tokenFlow = flowResult.tokenFlow\n\n // Decode post-mint collateral requirements from getFullPositionsData result\n let postMintCollateralReqToken0 = 0n\n let postMintCollateralReqToken1 = 0n\n const perPositionCollateralReqs: { token0: bigint; token1: bigint }[] = []\n if (flowResult.postCallResults?.[0]) {\n try {\n const decoded = decodeFunctionResult({\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n data: flowResult.postCallResults[0],\n })\n // Result: [shortPremium, longPremium, balances[], collateralReqs[], netPremia[]]\n const collateralReqs = decoded[3]\n if (collateralReqs.length > 0) {\n // Each entry is a LeftRightUnsigned: right=token0, left=token1\n // Sum across all positions in finalPositionIdList\n for (const packed of collateralReqs) {\n const req = decodeLeftRightUnsigned(packed)\n postMintCollateralReqToken0 += req.right\n postMintCollateralReqToken1 += req.left\n perPositionCollateralReqs.push({ token0: req.right, token1: req.left })\n }\n }\n } catch {\n // Decode failure — leave at 0n\n }\n }\n\n // Decode tokenId to get legs and tick spacing\n const decoded = decodeTokenId(tokenId)\n\n // Fetch pool state for greeks (currentTick, tickSpacing) if chainId provided\n let currentTick = 0n\n let poolTickSpacing = decoded.tickSpacing\n let utilization0 = 0n\n let utilization1 = 0n\n\n if (chainId !== undefined) {\n try {\n const pool = await getPool({ client, poolAddress, chainId, blockNumber: targetBlockNumber })\n currentTick = pool.currentTick\n poolTickSpacing = pool.tickSpacing\n utilization0 = pool.collateralTracker0.utilization\n utilization1 = pool.collateralTracker1.utilization\n } catch {\n // Pool fetch failed - use decoded tickSpacing, skip greeks\n }\n }\n\n // Calculate greeks if we have legs and pool data\n const greeks =\n decoded.legs.length > 0 && (chainId !== undefined || currentTick !== 0n)\n ? calculatePositionGreeks({\n legs: decoded.legs,\n currentTick,\n mintTick: currentTick, // At simulation time, mintTick = currentTick\n positionSize,\n poolTickSpacing,\n })\n : { value: 0n, delta: 0n, gamma: 0n }\n\n const _meta = await metaPromise\n\n // Map token flow to simulation fields:\n // Negative delta = user deposits (required), so amount required = -delta\n const amount0Required = -tokenFlow.delta0\n const amount1Required = -tokenFlow.delta1\n\n const data: OpenPositionSimulation = {\n position: {\n tokenId,\n positionSize,\n owner: account,\n poolAddress,\n legs: decoded.legs,\n poolUtilization0AtMint: utilization0,\n poolUtilization1AtMint: utilization1,\n tickAtMint: currentTick,\n timestampAtMint: _meta.blockTimestamp,\n blockNumberAtMint: _meta.blockNumber,\n swapAtMint,\n premiaOwed0: 0n,\n premiaOwed1: 0n,\n assetIndex: 0n,\n _meta,\n },\n greeks,\n amount0Required,\n amount1Required,\n postCollateral0: tokenFlow.balanceAfter0,\n postCollateral1: tokenFlow.balanceAfter1,\n postMintCollateralReqToken0,\n postMintCollateralReqToken1,\n perPositionCollateralReqs,\n commission0: null, // Embedded in contract logic, not extractable from token flow\n commission1: null,\n }\n\n return {\n success: true,\n data,\n gasEstimate: flowResult.gasEstimate,\n tokenFlow,\n _meta,\n }\n } catch (error) {\n const _meta = await metaPromise\n return {\n success: false,\n error:\n error instanceof PanopticError\n ? error\n : new PanopticError(\n error instanceof Error ? error.message : 'Simulation failed',\n error instanceof Error ? error : undefined,\n ),\n _meta,\n }\n }\n}\n","/**\n * Lending API for the Panoptic v2 SDK.\n *\n * Provides Aave/Compound-style supply/borrow/repay/unsupply functions\n * that wrap the lower-level vault and position primitives.\n *\n * @module v2/writes/lending\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\n\nimport { panopticPoolV2Abi } from '../../../generated'\nimport { MaxRetriesExceededError, NoLoanPositionsError } from '../errors'\nimport { tickLimits } from '../formatters/tick'\nimport { getPool } from '../reads/pool'\nimport { simulateOpenPosition } from '../simulations/simulateOpenPosition'\nimport type { StorageAdapter } from '../storage'\nimport { getPositionsKey, jsonSerializer } from '../storage'\nimport { getTrackedPositionIds } from '../sync/getTrackedPositionIds'\nimport { isLoan } from '../tokenId/decode'\nimport { decodeAllLegs } from '../tokenId/encoding'\nimport type {\n OpenPositionSimulation,\n SimulationResult,\n TxOverrides,\n TxReceipt,\n TxResult,\n} from '../types'\nimport {\n buildUniqueLoan,\n isInputListFailError,\n MAX_RETRIES,\n resolvePositionIds,\n resolveTokenIndex,\n} from './loanUtils'\nimport { submitWrite } from './utils'\nimport { deposit, withdraw } from './vault'\n\n// ---------------------------------------------------------------------------\n// Parameter types\n// ---------------------------------------------------------------------------\n\n/** Parameters for supplying collateral into a pool. */\nexport interface SupplyParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Chain ID */\n chainId: bigint\n /** Token address to supply (must be token0 or token1 of the pool) */\n token: Address\n /** Amount of token to supply */\n amount: bigint\n /** Whether the token is native ETH (requires sending msg.value) */\n isNativeETH?: boolean\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/** Parameters for withdrawing (unsupplying) collateral from a pool. */\nexport interface UnsupplyParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Chain ID */\n chainId: bigint\n /** Token address to withdraw (must be token0 or token1 of the pool) */\n token: Address\n /** Amount of token to withdraw */\n amount: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/** Parameters for borrowing tokens via a loan position. */\nexport interface BorrowParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Chain ID */\n chainId: bigint\n /** Token address to borrow (must be token0 or token1 of the pool) */\n token: Address\n /** Amount of token to borrow */\n amount: bigint\n /** Slippage tolerance in bps (e.g. 500n = 5%) */\n slippageBps: bigint\n /** Existing position IDs. If omitted, resolved from storage. */\n existingPositionIds?: bigint[]\n /** Storage adapter for position ID resolution and tracking */\n storage?: StorageAdapter\n /** Builder code for fee routing (0 = no builder). */\n builderCode?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n/** Parameters for repaying a loan (full or partial). */\nexport interface RepayParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Chain ID */\n chainId: bigint\n /** TokenId of the loan position to repay */\n loanTokenId: bigint\n /** Amount to repay. If >= current position size, does full repay. */\n amount: bigint\n /** Slippage tolerance in bps (e.g. 500n = 5%) */\n slippageBps: bigint\n /** Current position IDs. If omitted, resolved from storage. */\n existingPositionIds?: bigint[]\n /** Storage adapter for position ID resolution and tracking */\n storage?: StorageAdapter\n /** Builder code for fee routing (0 = no builder). */\n builderCode?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve collateral tracker address for a given token in the pool.\n */\nasync function resolveCollateralTracker(\n client: PublicClient,\n poolAddress: Address,\n chainId: bigint,\n token: Address,\n): Promise<Address> {\n const pool = await getPool({ client, poolAddress, chainId })\n const tokenIndex = resolveTokenIndex(\n token,\n pool.collateralTracker0.token,\n pool.collateralTracker1.token,\n )\n return tokenIndex === 0n ? pool.collateralTracker0.address : pool.collateralTracker1.address\n}\n\n/**\n * Save a position ID list to storage.\n */\nasync function savePositionIds(\n storage: StorageAdapter,\n chainId: bigint,\n poolAddress: Address,\n account: Address,\n positionIds: bigint[],\n): Promise<void> {\n const key = getPositionsKey(chainId, poolAddress, account)\n await storage.set(key, jsonSerializer.stringify(positionIds))\n}\n\n// ---------------------------------------------------------------------------\n// supply / unsupply\n// ---------------------------------------------------------------------------\n\n/**\n * Supply collateral into a pool.\n *\n * Resolves the correct collateral tracker from the token address,\n * then delegates to the low-level `deposit()`.\n *\n * @param params - Supply parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * const result = await supply({\n * client, walletClient, account, poolAddress,\n * chainId: 11155111n,\n * token: WETH_ADDRESS,\n * amount: 1n * 10n**18n,\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function supply(params: SupplyParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n chainId,\n token,\n amount,\n isNativeETH,\n txOverrides,\n } = params\n const collateralTrackerAddress = await resolveCollateralTracker(\n client,\n poolAddress,\n chainId,\n token,\n )\n return deposit({\n client,\n walletClient,\n account,\n collateralTrackerAddress,\n assets: amount,\n isNativeETH,\n txOverrides,\n })\n}\n\n/**\n * Supply collateral and wait for confirmation.\n */\nexport async function supplyAndWait(params: SupplyParams): Promise<TxReceipt> {\n const result = await supply(params)\n return result.wait()\n}\n\n/**\n * Withdraw (unsupply) collateral from a pool.\n *\n * Resolves the correct collateral tracker from the token address,\n * then delegates to the low-level `withdraw()`.\n *\n * @param params - Unsupply parameters\n * @returns TxResult\n */\nexport async function unsupply(params: UnsupplyParams): Promise<TxResult> {\n const { client, walletClient, account, poolAddress, chainId, token, amount, txOverrides } = params\n const collateralTrackerAddress = await resolveCollateralTracker(\n client,\n poolAddress,\n chainId,\n token,\n )\n return withdraw({\n client,\n walletClient,\n account,\n collateralTrackerAddress,\n assets: amount,\n txOverrides,\n })\n}\n\n/**\n * Withdraw collateral and wait for confirmation.\n */\nexport async function unsupplyAndWait(params: UnsupplyParams): Promise<TxReceipt> {\n const result = await unsupply(params)\n return result.wait()\n}\n\n// ---------------------------------------------------------------------------\n// borrow\n// ---------------------------------------------------------------------------\n\n/**\n * Borrow tokens from a pool via a loan position.\n *\n * Creates a loan tokenId and mints it via dispatch. The loan borrows the\n * specified token without swapping (ascending tick limits = no swap).\n *\n * @param params - Borrow parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * const result = await borrow({\n * client, walletClient, account, poolAddress,\n * chainId: 11155111n,\n * token: USDC_ADDRESS,\n * amount: 100n * 10n**6n,\n * slippageBps: 500n,\n * })\n * const receipt = await result.wait()\n * ```\n */\nexport async function borrow(params: BorrowParams): Promise<TxResult & { loanTokenId: bigint }> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n chainId,\n token,\n amount,\n slippageBps,\n existingPositionIds: explicitIds,\n builderCode = 0n,\n storage,\n txOverrides,\n } = params\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n const [pool, positionIds] = await Promise.all([\n getPool({ client, poolAddress, chainId }),\n resolvePositionIds(explicitIds, storage, chainId, poolAddress, account),\n ])\n\n const token0 = pool.collateralTracker0.token\n const token1 = pool.collateralTracker1.token\n const tokenIndex = resolveTokenIndex(token, token0, token1)\n\n // For a loan: both asset and tokenType = the borrowed token index\n const { tokenId: loanTokenId, adjustedSize } = buildUniqueLoan(\n pool.poolId,\n tokenIndex,\n tokenIndex,\n pool.currentTick,\n pool.tickSpacing,\n positionIds,\n amount,\n )\n\n const { low: tickLimitLow, high: tickLimitHigh } = tickLimits(pool.currentTick, slippageBps)\n\n // Ascending tick limits = no swap at mint\n const mintTickLimits: readonly [number, number, number] = [\n Number(tickLimitLow),\n Number(tickLimitHigh),\n 0,\n ]\n\n const positionIdList = [loanTokenId]\n const finalPositionIdList = [...positionIds, loanTokenId]\n const positionSizes = [adjustedSize]\n\n try {\n const txResult = await submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n positionIdList,\n finalPositionIdList,\n positionSizes,\n [mintTickLimits],\n false,\n builderCode,\n ],\n txOverrides,\n })\n return { ...txResult, loanTokenId }\n } catch (error) {\n if (isInputListFailError(error) && attempt < MAX_RETRIES - 1) {\n continue\n }\n throw error\n }\n }\n\n throw new MaxRetriesExceededError('borrow')\n}\n\n/**\n * Borrow tokens and wait for confirmation.\n * If storage is provided, auto-tracks the new loan position.\n */\nexport async function borrowAndWait(params: BorrowParams): Promise<TxReceipt> {\n const result = await borrow(params)\n const receipt = await result.wait()\n\n // Auto-update storage if provided\n if (params.storage && params.chainId !== undefined) {\n const { poolAddress, chainId, storage, account, existingPositionIds: explicitIds } = params\n\n const positionIds =\n explicitIds ?? (await getTrackedPositionIds({ chainId, poolAddress, account, storage }))\n\n await savePositionIds(storage, chainId, poolAddress, account, [\n ...positionIds,\n result.loanTokenId,\n ])\n }\n\n return receipt\n}\n\n// ---------------------------------------------------------------------------\n// preview borrow\n// ---------------------------------------------------------------------------\n\n/** Parameters for previewing a borrow (read-only, no wallet required). */\nexport interface PreviewBorrowParams {\n /** Public client */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** Chain ID */\n chainId: bigint\n /** Token address to borrow (must be token0 or token1 of the pool) */\n token: Address\n /** Amount of token to borrow */\n amount: bigint\n /** Slippage tolerance in bps (e.g. 500n = 5%) */\n slippageBps: bigint\n /** Existing position IDs */\n existingPositionIds: bigint[]\n}\n\n/** Result of a borrow preview. */\nexport interface PreviewBorrowResult {\n /** The loan tokenId that would be minted */\n loanTokenId: bigint\n /** Adjusted position size (after optionRatio scaling) */\n adjustedSize: bigint\n /** Simulation result from dry-run dispatch */\n simulation: SimulationResult<OpenPositionSimulation>\n /** Collateral requirement for the new loan position only (token0). Null if simulation failed. */\n collateralReqToken0: bigint | null\n /** Collateral requirement for the new loan position only (token1). Null if simulation failed. */\n collateralReqToken1: bigint | null\n}\n\n/**\n * Preview a borrow without executing it.\n *\n * Builds the loan tokenId (same logic as `borrow`) and runs a\n * dry-run `simulateOpenPosition` to check feasibility and return\n * post-mint collateral requirements.\n *\n * @param params - Preview parameters\n * @returns Preview result with tokenId, size, and simulation data\n */\nexport async function previewBorrow(params: PreviewBorrowParams): Promise<PreviewBorrowResult> {\n const { client, poolAddress, chainId, token, amount, slippageBps, account, existingPositionIds } =\n params\n\n const pool = await getPool({ client, poolAddress, chainId })\n\n const token0 = pool.collateralTracker0.token\n const token1 = pool.collateralTracker1.token\n const tokenIndex = resolveTokenIndex(token, token0, token1)\n\n const { tokenId: loanTokenId, adjustedSize } = buildUniqueLoan(\n pool.poolId,\n tokenIndex,\n tokenIndex,\n pool.currentTick,\n pool.tickSpacing,\n existingPositionIds,\n amount,\n )\n\n const { low: tickLimitLow, high: tickLimitHigh } = tickLimits(pool.currentTick, slippageBps)\n\n const simulation = await simulateOpenPosition({\n client,\n poolAddress,\n account,\n existingPositionIds,\n tokenId: loanTokenId,\n positionSize: adjustedSize,\n tickLimitLow: BigInt(tickLimitLow),\n tickLimitHigh: BigInt(tickLimitHigh),\n chainId,\n })\n\n // Extract the new loan's collateral requirement (last entry in perPositionCollateralReqs)\n let collateralReqToken0: bigint | null = null\n let collateralReqToken1: bigint | null = null\n if (simulation.success) {\n const reqs = simulation.data.perPositionCollateralReqs\n if (reqs.length > 0) {\n const loanReq = reqs[reqs.length - 1]\n collateralReqToken0 = loanReq.token0\n collateralReqToken1 = loanReq.token1\n }\n }\n\n return { loanTokenId, adjustedSize, simulation, collateralReqToken0, collateralReqToken1 }\n}\n\n// ---------------------------------------------------------------------------\n// repay\n// ---------------------------------------------------------------------------\n\n/**\n * Repay a loan position (full or partial).\n *\n * - Full repay (`amount >= currentSize`): Burns the loan position entirely.\n * - Partial repay (`amount < currentSize`): Uses roll-same-tokenId pattern\n * to reduce the position size.\n *\n * @param params - Repay parameters\n * @returns TxResult\n *\n * @example\n * ```typescript\n * // Full repay\n * await repay({\n * client, walletClient, account, poolAddress,\n * chainId: 11155111n,\n * loanTokenId,\n * amount: MAX_UINT128, // repay all\n * slippageBps: 500n,\n * })\n *\n * // Partial repay\n * await repay({\n * client, walletClient, account, poolAddress,\n * chainId: 11155111n,\n * loanTokenId,\n * amount: 50n * 10n**6n, // repay 50 USDC\n * slippageBps: 500n,\n * })\n * ```\n */\nexport async function repay(params: RepayParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n chainId,\n loanTokenId,\n amount,\n slippageBps,\n existingPositionIds: explicitIds,\n builderCode = 0n,\n storage,\n txOverrides,\n } = params\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n const [positionIds, fullDataResult] = await Promise.all([\n resolvePositionIds(explicitIds, storage, chainId, poolAddress, account),\n client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [account, false, [loanTokenId]],\n }),\n ])\n\n // Extract positionSize from the packed PositionBalance\n const balanceRaw = fullDataResult[2][0] // positionBalances[0]\n const currentSize = balanceRaw & ((1n << 128n) - 1n)\n\n const pool = await getPool({ client, poolAddress, chainId })\n const { low: tickLimitLow, high: tickLimitHigh } = tickLimits(pool.currentTick, slippageBps)\n\n // Ascending tick limits = no swap\n const ascendingLimits: readonly [number, number, number] = [\n Number(tickLimitLow),\n Number(tickLimitHigh),\n 0,\n ]\n\n if (amount >= currentSize) {\n // Full repay: burn the entire position\n const finalPositionIdList = positionIds.filter((id) => id !== loanTokenId)\n\n try {\n return await submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n [loanTokenId],\n finalPositionIdList,\n [0n], // 0n = burn all\n [ascendingLimits],\n false,\n builderCode,\n ],\n txOverrides,\n })\n } catch (error) {\n if (isInputListFailError(error) && attempt < MAX_RETRIES - 1) {\n continue\n }\n throw error\n }\n } else {\n // Partial repay: roll-same-tokenId pattern\n // Op 1: burn current position at full size\n // Op 2: re-mint same tokenId at reduced size\n const newSize = currentSize - amount\n const finalPositionIdList = positionIds\n .filter((id) => id !== loanTokenId)\n .concat([loanTokenId])\n\n try {\n return await submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [\n [loanTokenId, loanTokenId],\n finalPositionIdList,\n [currentSize, newSize],\n [ascendingLimits, ascendingLimits],\n false,\n builderCode,\n ],\n txOverrides,\n })\n } catch (error) {\n if (isInputListFailError(error) && attempt < MAX_RETRIES - 1) {\n continue\n }\n throw error\n }\n }\n }\n\n throw new MaxRetriesExceededError('repay')\n}\n\n/**\n * Repay a loan and wait for confirmation.\n * If storage is provided, auto-updates the tracked positions (removes on full repay).\n */\nexport async function repayAndWait(params: RepayParams): Promise<TxReceipt> {\n const result = await repay(params)\n const receipt = await result.wait()\n\n // Auto-update storage on full repay\n if (params.storage && params.chainId !== undefined) {\n const {\n client,\n account,\n poolAddress,\n chainId,\n loanTokenId,\n storage,\n existingPositionIds: explicitIds,\n } = params\n\n const fullDataResult = await client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [account, false, [loanTokenId]],\n })\n const balanceRaw = fullDataResult[2][0] // positionBalances[0]\n const currentSize = balanceRaw & ((1n << 128n) - 1n)\n\n // Only remove if the position was fully burned\n if (currentSize === 0n) {\n const positionIds =\n explicitIds ?? (await getTrackedPositionIds({ chainId, poolAddress, account, storage }))\n await savePositionIds(\n storage,\n chainId,\n poolAddress,\n account,\n positionIds.filter((id) => id !== loanTokenId),\n )\n }\n }\n\n return receipt\n}\n\n// ---------------------------------------------------------------------------\n// smart repay\n// ---------------------------------------------------------------------------\n\n/** Parameters for smart repay (burns all loans for a token, optionally re-opens a smaller one). */\nexport interface SmartRepayParams {\n /** Public client */\n client: PublicClient\n /** Wallet client */\n walletClient: WalletClient\n /** Account address */\n account: Address\n /** PanopticPool address */\n poolAddress: Address\n /** Chain ID */\n chainId: bigint\n /** Token address to repay loans for (must be token0 or token1 of the pool) */\n token: Address\n /** Amount of token to repay */\n amount: bigint\n /** Slippage tolerance in bps (e.g. 500n = 5%) */\n slippageBps: bigint\n /** Existing position IDs (all positions, not just loans) */\n existingPositionIds: bigint[]\n /** Builder code for fee routing (0 = no builder). */\n builderCode?: bigint\n /** Gas and transaction overrides */\n txOverrides?: TxOverrides\n /** Optional storage adapter — when provided, smartRepayAndWait auto-updates tracked positions. */\n storage?: StorageAdapter\n}\n\n/**\n * Identify loan tokenIds for a specific token and return their sizes.\n */\nasync function getLoanPositionsForToken(\n client: PublicClient,\n poolAddress: Address,\n account: Address,\n existingPositionIds: bigint[],\n tokenIndex: bigint,\n): Promise<{ tokenId: bigint; positionSize: bigint; optionRatio: bigint; tokenAmount: bigint }[]> {\n const loanIds = existingPositionIds.filter((id) => {\n if (!isLoan(id)) return false\n const legs = decodeAllLegs(id)\n return legs.length > 0 && legs[0].tokenType === tokenIndex\n })\n\n if (loanIds.length === 0) return []\n\n const fullData = await client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [account, false, loanIds],\n })\n\n const balances = fullData[2]\n return loanIds.map((tokenId, i) => {\n const positionSize = balances[i] & ((1n << 128n) - 1n)\n const legs = decodeAllLegs(tokenId)\n const optionRatio = legs[0].optionRatio\n // Actual token amount = positionSize * optionRatio\n const tokenAmount = positionSize * optionRatio\n return { tokenId, positionSize, optionRatio, tokenAmount }\n })\n}\n\n/**\n * Smart repay: burns all loan positions for a token and optionally re-opens a smaller one.\n *\n * Unlike `repay()` which targets a single loanTokenId, this function handles\n * multiple loans transparently. The user specifies a repay amount and the SDK:\n * 1. Finds all loan positions for the specified token\n * 2. Burns them all\n * 3. If repayAmount < totalDebt, opens a new loan for the remainder\n *\n * @param params - Smart repay parameters\n * @returns TxResult\n */\nexport async function smartRepay(params: SmartRepayParams): Promise<TxResult> {\n const {\n client,\n walletClient,\n account,\n poolAddress,\n chainId,\n token,\n amount,\n slippageBps,\n existingPositionIds,\n builderCode = 0n,\n txOverrides,\n } = params\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n const pool = await getPool({ client, poolAddress, chainId })\n const tokenIndex = resolveTokenIndex(\n token,\n pool.collateralTracker0.token,\n pool.collateralTracker1.token,\n )\n\n const loans = await getLoanPositionsForToken(\n client,\n poolAddress,\n account,\n existingPositionIds,\n tokenIndex,\n )\n if (loans.length === 0) {\n throw new NoLoanPositionsError(token)\n }\n\n const totalDebt = loans.reduce((sum, l) => sum + l.tokenAmount, 0n)\n const loanIds = loans.map((l) => l.tokenId)\n const remainder = totalDebt > amount ? totalDebt - amount : 0n\n\n const { low: tickLimitLow, high: tickLimitHigh } = tickLimits(pool.currentTick, slippageBps)\n const ascendingLimits: readonly [number, number, number] = [\n Number(tickLimitLow),\n Number(tickLimitHigh),\n 0,\n ]\n\n const nonLoanIds = existingPositionIds.filter((id) => !loanIds.includes(id))\n\n const opsPositionIds: bigint[] = [...loanIds]\n const opsSizes: bigint[] = loanIds.map(() => 0n)\n const opsLimits = loanIds.map(() => ascendingLimits)\n\n let finalPositionIdList: bigint[]\n\n if (remainder > 0n) {\n const { tokenId: newLoanId, adjustedSize } = buildUniqueLoan(\n pool.poolId,\n tokenIndex,\n tokenIndex,\n pool.currentTick,\n pool.tickSpacing,\n nonLoanIds,\n remainder,\n )\n opsPositionIds.push(newLoanId)\n opsSizes.push(adjustedSize)\n opsLimits.push(ascendingLimits)\n finalPositionIdList = [...nonLoanIds, newLoanId]\n } else {\n finalPositionIdList = nonLoanIds\n }\n\n try {\n return await submitWrite({\n client,\n walletClient,\n account,\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'dispatch',\n args: [opsPositionIds, finalPositionIdList, opsSizes, opsLimits, false, builderCode],\n txOverrides,\n })\n } catch (error) {\n if (isInputListFailError(error) && attempt < MAX_RETRIES - 1) {\n continue\n }\n throw error\n }\n }\n\n throw new MaxRetriesExceededError('smartRepay')\n}\n\n/**\n * Smart repay and wait for confirmation.\n */\nexport async function smartRepayAndWait(params: SmartRepayParams): Promise<TxReceipt> {\n const result = await smartRepay(params)\n const receipt = await result.wait()\n\n // Auto-update storage: remove fully-repaid loans, insert remainder loan if any\n if (params.storage && params.chainId !== undefined) {\n const { client, account, poolAddress, chainId, token, amount, storage, existingPositionIds } =\n params\n\n const pool = await getPool({ client, poolAddress, chainId })\n const tokenIndex = resolveTokenIndex(\n token,\n pool.collateralTracker0.token,\n pool.collateralTracker1.token,\n )\n\n const loans = await getLoanPositionsForToken(\n client,\n poolAddress,\n account,\n existingPositionIds,\n tokenIndex,\n )\n const loanIds = loans.map((l) => l.tokenId)\n const totalDebt = loans.reduce((sum, l) => sum + l.tokenAmount, 0n)\n const remainder = totalDebt > amount ? totalDebt - amount : 0n\n\n const positionIds =\n existingPositionIds ??\n (await getTrackedPositionIds({ chainId, poolAddress, account, storage }))\n\n // Remove all old loan IDs\n let updatedIds = positionIds.filter((id) => !loanIds.includes(id))\n\n // If there's a remainder, the contract minted a new loan — find it\n if (remainder > 0n) {\n const nonLoanIds = existingPositionIds.filter((id) => !loanIds.includes(id))\n const newLoan = buildUniqueLoan(\n pool.poolId,\n tokenIndex,\n tokenIndex,\n pool.currentTick,\n pool.tickSpacing,\n nonLoanIds,\n remainder,\n )\n updatedIds = [...updatedIds, newLoan.tokenId]\n }\n\n await savePositionIds(storage, chainId, poolAddress, account, updatedIds)\n }\n\n return receipt\n}\n"],"mappings":"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"}