{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/createPool.ts","../src/token.ts","../src/sysvar.ts","../src/actionHelpers.ts","../src/decreaseLiquidity.ts","../src/harvest.ts","../src/position.ts","../src/utils.ts","../src/increaseLiquidity.ts","../src/pool.ts","../src/swap.ts"],"sourcesContent":["export * from \"./config\";\nexport * from \"./createPool\";\nexport * from \"./decreaseLiquidity\";\nexport * from \"./harvest\";\nexport * from \"./increaseLiquidity\";\nexport * from \"./pool\";\nexport * from \"./position\";\nexport * from \"./swap\";\nexport { orderMints } from \"./token\";\n","import { getWhirlpoolsConfigExtensionAddress } from \"@orca-so/whirlpools-client\";\nimport type { Address, TransactionSigner, KeyPairSigner } from \"@solana/kit\";\nimport {\n  address,\n  createNoopSigner,\n  isAddress,\n  createKeyPairFromBytes,\n  createSignerFromKeyPair,\n} from \"@solana/kit\";\n\nexport {\n  setComputeUnitMarginMultiplier,\n  setJitoBlockEngineUrl,\n  setJitoTipSetting,\n  setPriorityFeeSetting,\n  setRpc,\n  setJitoFeePercentile,\n  setPriorityFeePercentile,\n  getRpcConfig,\n} from \"@orca-so/tx-sender\";\n/**\n * The default (null) address.\n */\nexport const DEFAULT_ADDRESS = address(\"11111111111111111111111111111111\");\n\n/**\n * The WhirlpoolsConfig addresses for various networks.\n */\nexport const DEFAULT_WHIRLPOOLS_CONFIG_ADDRESSES = {\n  solanaMainnet: address(\"2LecshUwdy9xi7meFgHtFJQNSKk4KdTrcpvaB56dP2NQ\"),\n  solanaDevnet: address(\"FcrweFY1G9HJAHG5inkGB6pKg1HZ6x9UC2WioAfWrGkR\"),\n  eclipseMainnet: address(\"FVG4oDbGv16hqTUbovjyGmtYikn6UBEnazz6RVDMEFwv\"),\n  eclipseTestnet: address(\"FPydDjRdZu9sT7HVd6ANhfjh85KLq21Pefr5YWWMRPFp\"),\n};\n\n/**\n * The default WhirlpoolsConfigExtension address.\n */\nexport const DEFAULT_WHIRLPOOLS_CONFIG_EXTENSION_ADDRESS = address(\n  \"777H5H3Tp9U11uRVRzFwM8BinfiakbaLT8vQpeuhvEiH\",\n);\n\n/**\n * The WhirlpoolsConfig address.\n */\nexport let WHIRLPOOLS_CONFIG_ADDRESS: Address =\n  DEFAULT_WHIRLPOOLS_CONFIG_ADDRESSES.solanaMainnet;\n\n/**\n * The WhirlpoolsConfigExtension address.\n */\nexport let WHIRLPOOLS_CONFIG_EXTENSION_ADDRESS: Address =\n  DEFAULT_WHIRLPOOLS_CONFIG_EXTENSION_ADDRESS;\n\n/**\n * Updates the WhirlpoolsConfig and WhirlpoolsConfigExtension addresses.\n *\n * @param {Address | keyof typeof NETWORK_ADDRESSES} config - A WhirlpoolsConfig address or a network name.\n * @returns {Promise<void>} - Resolves when the addresses have been updated.\n */\nexport async function setWhirlpoolsConfig(\n  config: Address | keyof typeof DEFAULT_WHIRLPOOLS_CONFIG_ADDRESSES,\n): Promise<void> {\n  if (isAddress(config)) {\n    WHIRLPOOLS_CONFIG_ADDRESS = config;\n  } else {\n    WHIRLPOOLS_CONFIG_ADDRESS =\n      DEFAULT_WHIRLPOOLS_CONFIG_ADDRESSES[\n        config as keyof typeof DEFAULT_WHIRLPOOLS_CONFIG_ADDRESSES\n      ];\n  }\n\n  WHIRLPOOLS_CONFIG_EXTENSION_ADDRESS =\n    await getWhirlpoolsConfigExtensionAddress(WHIRLPOOLS_CONFIG_ADDRESS).then(\n      (x) => x[0],\n    );\n}\n\n/**\n * The tick spacing for the Splash pools.\n */\nexport const SPLASH_POOL_TICK_SPACING = 32896;\n\n/**\n * The default funder for transactions. No explicit funder specified.\n */\nexport const DEFAULT_FUNDER: TransactionSigner =\n  createNoopSigner(DEFAULT_ADDRESS);\n\n/**\n * The currently selected funder for transactions.\n */\nexport let FUNDER: TransactionSigner = DEFAULT_FUNDER;\n\n/**\n * Sets the default funder for transactions.\n *\n * @param {TransactionSigner | Address | null} funder - The funder to be set as default, either as an address or a transaction signer.\n */\nexport function setDefaultFunder(\n  funder: TransactionSigner | Address | null,\n): void {\n  if (typeof funder === \"string\") {\n    FUNDER = createNoopSigner(funder);\n  } else {\n    FUNDER = funder ?? createNoopSigner(DEFAULT_ADDRESS);\n  }\n}\n\n/**\n * The default slippage tolerance, expressed in basis points. Value of 100 is equivalent to 1%.\n */\nexport const DEFAULT_SLIPPAGE_TOLERANCE_BPS = 100;\n\n/**\n * The currently selected slippage tolerance, expressed in basis points. Value of 100 is equivalent to 1%.\n */\nexport let SLIPPAGE_TOLERANCE_BPS = DEFAULT_SLIPPAGE_TOLERANCE_BPS;\n\n/**\n * Sets the default slippage tolerance for transactions.\n *\n * @param {number} slippageToleranceBps - The slippage tolerance, expressed basis points. Value of 100 is equivalent to 1%.\n */\nexport function setDefaultSlippageToleranceBps(\n  slippageToleranceBps: number,\n): void {\n  SLIPPAGE_TOLERANCE_BPS = Math.floor(slippageToleranceBps);\n}\n\n/**\n * Defines the strategy for handling Native Mint wrapping in a transaction.\n *\n * - **Keypair**:\n *   Creates an auxiliary token account using a keypair.\n *   Optionally adds funds to the account.\n *   Closes it at the end of the transaction.\n *\n * - **Seed**:\n *   Functions similarly to Keypair, but uses a seed account instead.\n *\n * - **ATA**:\n *   Treats the native balance and associated token account (ATA) for `NATIVE_MINT` as one.\n *   Will create the ATA if it doesn't exist.\n *   Optionally adds funds to the account.\n *   Closes it at the end of the transaction if it did not exist before.\n *\n * - **None**:\n *   Uses or creates the ATA without performing any Native Mint wrapping or unwrapping.\n */\nexport type NativeMintWrappingStrategy = \"keypair\" | \"seed\" | \"ata\" | \"none\";\n\n/**\n * The default native mint wrapping strategy.\n */\nexport const DEFAULT_NATIVE_MINT_WRAPPING_STRATEGY: NativeMintWrappingStrategy =\n  \"keypair\";\n\n/**\n * The currently selected native mint wrapping strategy.\n */\nexport let NATIVE_MINT_WRAPPING_STRATEGY: NativeMintWrappingStrategy =\n  DEFAULT_NATIVE_MINT_WRAPPING_STRATEGY;\n\n/**\n * Sets the native mint wrapping strategy.\n *\n * @param {NativeMintWrappingStrategy} strategy - The native mint wrapping strategy.\n */\nexport function setNativeMintWrappingStrategy(\n  strategy: NativeMintWrappingStrategy,\n): void {\n  NATIVE_MINT_WRAPPING_STRATEGY = strategy;\n}\n\n/**\n * The default setting for enforcing balance checks during token account preparation.\n */\nexport const DEFAULT_ENFORCE_TOKEN_BALANCE_CHECK = false;\n\n/**\n * The currently selected setting for enforcing balance checks during token account preparation.\n * When true, the system will assert that token accounts have sufficient balance before proceeding.\n * When false, balance checks are skipped, allowing users to get quotes and instructions even with insufficient balance.\n */\nexport let ENFORCE_TOKEN_BALANCE_CHECK = DEFAULT_ENFORCE_TOKEN_BALANCE_CHECK;\n\n/**\n * Sets whether to enforce balance checks during token account preparation.\n *\n * @param {boolean} enforceBalanceCheck - When true, the system will assert that token accounts have sufficient balance. When false, balance checks are skipped.\n */\nexport function setEnforceTokenBalanceCheck(\n  enforceBalanceCheck: boolean,\n): void {\n  ENFORCE_TOKEN_BALANCE_CHECK = enforceBalanceCheck;\n}\n\n/**\n * Resets the configuration to its default state.\n *\n * @returns {Promise<void>} - Resolves when the configuration has been reset.\n */\nexport function resetConfiguration() {\n  WHIRLPOOLS_CONFIG_ADDRESS = DEFAULT_WHIRLPOOLS_CONFIG_ADDRESSES.solanaMainnet;\n  WHIRLPOOLS_CONFIG_EXTENSION_ADDRESS =\n    DEFAULT_WHIRLPOOLS_CONFIG_EXTENSION_ADDRESS;\n  FUNDER = DEFAULT_FUNDER;\n  SLIPPAGE_TOLERANCE_BPS = DEFAULT_SLIPPAGE_TOLERANCE_BPS;\n  NATIVE_MINT_WRAPPING_STRATEGY = DEFAULT_NATIVE_MINT_WRAPPING_STRATEGY;\n  ENFORCE_TOKEN_BALANCE_CHECK = DEFAULT_ENFORCE_TOKEN_BALANCE_CHECK;\n}\n\nlet _payer: KeyPairSigner | undefined;\n\n/**\n * Sets the payer from a private key byte array.\n *\n * @param {Uint8Array<ArrayBuffer>} pkBytes - The private key bytes to create the payer from.\n * @returns {Promise<KeyPairSigner>} - A promise that resolves to the created signer.\n *\n * @example\n * ```ts\n * // Set payer from a private key byte array\n * const privateKeyBytes = new Uint8Array([\n *   55, 244, 186, 115, 93, 3, 9, 47, 12, 168,\n *   86, 1, 5, 155, 127, 3, 44, 165, 155, 3,\n *   112, 1, 3, 99, 3, 211, 3, 77, 153,\n *   44, 1, 179\n * ]);\n * const signer = await setPayerFromBytes(privateKeyBytes);\n * ```\n */\nexport async function setPayerFromBytes(pkBytes: Uint8Array<ArrayBuffer>) {\n  const kp = await createKeyPairFromBytes(pkBytes);\n  const signer = await createSignerFromKeyPair(kp);\n  _payer = signer;\n  return signer;\n}\n\nexport function getPayer(): KeyPairSigner {\n  if (!_payer) {\n    throw new Error(\"Payer not set. Call setPayer() first.\");\n  }\n  return _payer;\n}\n","import {\n  getFeeTierAddress,\n  getInitializePoolV2Instruction,\n  getInitializeDynamicTickArrayInstruction,\n  getTickArrayAddress,\n  getDynamicTickArrayMinSize,\n  getTokenBadgeAddress,\n  getWhirlpoolAddress,\n  getWhirlpoolSize,\n} from \"@orca-so/whirlpools-client\";\nimport type {\n  Address,\n  GetAccountInfoApi,\n  GetMultipleAccountsApi,\n  IInstruction,\n  Lamports,\n  Rpc,\n  TransactionSigner,\n} from \"@solana/kit\";\nimport { generateKeyPairSigner, lamports } from \"@solana/kit\";\nimport { fetchSysvarRent } from \"@solana/sysvars\";\nimport {\n  DEFAULT_ADDRESS,\n  FUNDER,\n  SPLASH_POOL_TICK_SPACING,\n  WHIRLPOOLS_CONFIG_ADDRESS,\n} from \"./config\";\nimport {\n  getFullRangeTickIndexes,\n  getTickArrayStartTickIndex,\n  priceToSqrtPrice,\n  sqrtPriceToTickIndex,\n} from \"@orca-so/whirlpools-core\";\nimport { fetchAllMint } from \"@solana-program/token-2022\";\nimport assert from \"assert\";\nimport { getTokenSizeForMint, orderMints } from \"./token\";\nimport { calculateMinimumBalanceForRentExemption } from \"./sysvar\";\nimport { wrapFunctionWithExecution } from \"./actionHelpers\";\n\n/**\n * Represents the instructions and metadata for creating a pool.\n */\nexport type CreatePoolInstructions = {\n  /** The list of instructions needed to create the pool. */\n  instructions: IInstruction[];\n\n  /** The estimated rent exemption cost for initializing the pool, in lamports. */\n  initializationCost: Lamports;\n\n  /** The address of the newly created pool. */\n  poolAddress: Address;\n};\n\n/**\n * Creates the necessary instructions to initialize a Splash Pool on Orca Whirlpools.\n *\n * @param {SolanaRpc} rpc - A Solana RPC client for communicating with the blockchain.\n * @param {Address} tokenMintA - The first token mint address to include in the pool.\n * @param {Address} tokenMintB - The second token mint address to include in the pool.\n * @param {number} [initialPrice=1] - The initial price of token 1 in terms of token 2.\n * @param {TransactionSigner} [funder=FUNDER] - The account that will fund the initialization process.\n *\n * @returns {Promise<CreatePoolInstructions>} A promise that resolves to an object containing the pool creation instructions, the estimated initialization cost, and the pool address.\n *\n * @example\n * import { createSplashPoolInstructions, setWhirlpoolsConfig } from '@orca-so/whirlpools';\n * import { generateKeyPairSigner, createSolanaRpc, devnet, address } from '@solana/kit';\n *\n * await setWhirlpoolsConfig('solanaDevnet');\n * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));\n * const wallet = await generateKeyPairSigner(); // CAUTION: This wallet is not persistent.\n *\n * const tokenMintOne = address(\"So11111111111111111111111111111111111111112\");\n * const tokenMintTwo = address(\"BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k\"); // devUSDC\n * const initialPrice = 0.01;\n *\n * const { poolAddress, instructions, initializationCost } = await createSplashPoolInstructions(\n *     devnetRpc,\n *     tokenMintOne,\n *     tokenMintTwo,\n *     initialPrice,\n *     wallet\n * );\n *\n * console.log(`Pool Address: ${poolAddress}`);\n * console.log(`Initialization Cost: ${initializationCost} lamports`);\n */\nexport function createSplashPoolInstructions(\n  rpc: Rpc<GetAccountInfoApi & GetMultipleAccountsApi>,\n  tokenMintA: Address,\n  tokenMintB: Address,\n  initialPrice: number = 1,\n  funder: TransactionSigner = FUNDER,\n): Promise<CreatePoolInstructions> {\n  return createConcentratedLiquidityPoolInstructions(\n    rpc,\n    tokenMintA,\n    tokenMintB,\n    SPLASH_POOL_TICK_SPACING,\n    initialPrice,\n    funder,\n  );\n}\n\n/**\n * Creates the necessary instructions to initialize a Concentrated Liquidity Pool (CLMM) on Orca Whirlpools.\n *\n * @param {SolanaRpc} rpc - A Solana RPC client for communicating with the blockchain.\n * @param {Address} tokenMintA - The first token mint address to include in the pool.\n * @param {Address} tokenMintB - The second token mint address to include in the pool.\n * @param {number} tickSpacing - The spacing between price ticks for the pool.\n * @param {number} [initialPrice=1] - The initial price of token 1 in terms of token 2.\n * @param {TransactionSigner} [funder=FUNDER] - The account that will fund the initialization process.\n *\n * @returns {Promise<CreatePoolInstructions>} A promise that resolves to an object containing the pool creation instructions, the estimated initialization cost, and the pool address.\n *\n * @example\n * import { createConcentratedLiquidityPoolInstructions, setWhirlpoolsConfig } from '@orca-so/whirlpools';\n * import { generateKeyPairSigner, createSolanaRpc, devnet, address } from '@solana/kit';\n *\n * await setWhirlpoolsConfig('solanaDevnet');\n * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));\n * const wallet = await generateKeyPairSigner(); // CAUTION: This wallet is not persistent.\n *\n * const tokenMintOne = address(\"So11111111111111111111111111111111111111112\");\n * const tokenMintTwo = address(\"BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k\"); // devUSDC\n * const tickSpacing = 64;\n * const initialPrice = 0.01;\n *\n * const { poolAddress, instructions, initializationCost } = await createConcentratedLiquidityPoolInstructions(\n *     devnetRpc,\n *     tokenMintOne,\n *     tokenMintTwo,\n *     tickSpacing,\n *     initialPrice,\n *     wallet\n * );\n *\n * console.log(`Pool Address: ${poolAddress}`);\n * console.log(`Initialization Cost: ${initializationCost} lamports`);\n */\nexport async function createConcentratedLiquidityPoolInstructions(\n  rpc: Rpc<GetAccountInfoApi & GetMultipleAccountsApi>,\n  tokenMintA: Address,\n  tokenMintB: Address,\n  tickSpacing: number,\n  initialPrice: number = 1,\n  funder: TransactionSigner = FUNDER,\n): Promise<CreatePoolInstructions> {\n  assert(\n    funder.address !== DEFAULT_ADDRESS,\n    \"Either supply a funder or set the default funder\",\n  );\n  assert(\n    orderMints(tokenMintA, tokenMintB)[0] === tokenMintA,\n    \"Token order needs to be flipped to match the canonical ordering (i.e. sorted on the byte repr. of the mint pubkeys)\",\n  );\n  const instructions: IInstruction[] = [];\n\n  const rent = await fetchSysvarRent(rpc);\n  let nonRefundableRent: bigint = 0n;\n\n  // Since TE mint data is an extension of T mint data, we can use the same fetch function\n  const [mintA, mintB] = await fetchAllMint(rpc, [tokenMintA, tokenMintB]);\n  const decimalsA = mintA.data.decimals;\n  const decimalsB = mintB.data.decimals;\n  const tokenProgramA = mintA.programAddress;\n  const tokenProgramB = mintB.programAddress;\n\n  const initialSqrtPrice = priceToSqrtPrice(initialPrice, decimalsA, decimalsB);\n\n  const [\n    poolAddress,\n    feeTier,\n    tokenBadgeA,\n    tokenBadgeB,\n    tokenVaultA,\n    tokenVaultB,\n  ] = await Promise.all([\n    getWhirlpoolAddress(\n      WHIRLPOOLS_CONFIG_ADDRESS,\n      tokenMintA,\n      tokenMintB,\n      tickSpacing,\n    ).then((x) => x[0]),\n    getFeeTierAddress(WHIRLPOOLS_CONFIG_ADDRESS, tickSpacing).then((x) => x[0]),\n    getTokenBadgeAddress(WHIRLPOOLS_CONFIG_ADDRESS, tokenMintA).then(\n      (x) => x[0],\n    ),\n    getTokenBadgeAddress(WHIRLPOOLS_CONFIG_ADDRESS, tokenMintB).then(\n      (x) => x[0],\n    ),\n    generateKeyPairSigner(),\n    generateKeyPairSigner(),\n  ]);\n\n  instructions.push(\n    getInitializePoolV2Instruction({\n      whirlpoolsConfig: WHIRLPOOLS_CONFIG_ADDRESS,\n      tokenMintA,\n      tokenMintB,\n      tokenBadgeA,\n      tokenBadgeB,\n      funder,\n      whirlpool: poolAddress,\n      tokenVaultA,\n      tokenVaultB,\n      tokenProgramA,\n      tokenProgramB,\n      feeTier,\n      tickSpacing,\n      initialSqrtPrice,\n    }),\n  );\n\n  nonRefundableRent += calculateMinimumBalanceForRentExemption(\n    rent,\n    getTokenSizeForMint(mintA),\n  );\n  nonRefundableRent += calculateMinimumBalanceForRentExemption(\n    rent,\n    getTokenSizeForMint(mintB),\n  );\n  nonRefundableRent += calculateMinimumBalanceForRentExemption(\n    rent,\n    getWhirlpoolSize(),\n  );\n\n  const fullRange = getFullRangeTickIndexes(tickSpacing);\n  const lowerTickIndex = getTickArrayStartTickIndex(\n    fullRange.tickLowerIndex,\n    tickSpacing,\n  );\n  const upperTickIndex = getTickArrayStartTickIndex(\n    fullRange.tickUpperIndex,\n    tickSpacing,\n  );\n  const initialTickIndex = sqrtPriceToTickIndex(initialSqrtPrice);\n  const currentTickIndex = getTickArrayStartTickIndex(\n    initialTickIndex,\n    tickSpacing,\n  );\n\n  const tickArrayIndexes = Array.from(\n    new Set([lowerTickIndex, upperTickIndex, currentTickIndex]),\n  );\n\n  const tickArrayAddresses = await Promise.all(\n    tickArrayIndexes.map((x) =>\n      getTickArrayAddress(poolAddress, x).then((x) => x[0]),\n    ),\n  );\n\n  for (let i = 0; i < tickArrayIndexes.length; i++) {\n    instructions.push(\n      getInitializeDynamicTickArrayInstruction({\n        whirlpool: poolAddress,\n        funder,\n        tickArray: tickArrayAddresses[i],\n        startTickIndex: tickArrayIndexes[i],\n        idempotent: false,\n      }),\n    );\n    nonRefundableRent += calculateMinimumBalanceForRentExemption(\n      rent,\n      getDynamicTickArrayMinSize(),\n    );\n  }\n\n  return {\n    instructions,\n    poolAddress,\n    initializationCost: lamports(nonRefundableRent),\n  };\n}\n\n// -------- ACTIONS --------\n\nexport const createSplashPool = wrapFunctionWithExecution(\n  createSplashPoolInstructions,\n);\nexport const createConcentratedLiquidityPool = wrapFunctionWithExecution(\n  createConcentratedLiquidityPoolInstructions,\n);\n","import {\n  fetchAllMaybeToken,\n  fetchAllMint,\n  findAssociatedTokenPda,\n  getCloseAccountInstruction,\n  getCreateAssociatedTokenInstruction,\n  getInitializeAccount3Instruction,\n  getSyncNativeInstruction,\n  TOKEN_PROGRAM_ADDRESS,\n} from \"@solana-program/token\";\nimport type {\n  Account,\n  Address,\n  GetAccountInfoApi,\n  GetMinimumBalanceForRentExemptionApi,\n  GetMultipleAccountsApi,\n  IInstruction,\n  MaybeAccount,\n  Rpc,\n  TransactionSigner,\n} from \"@solana/kit\";\nimport {\n  address,\n  generateKeyPairSigner,\n  getAddressDecoder,\n  getAddressEncoder,\n  lamports,\n} from \"@solana/kit\";\nimport {\n  NATIVE_MINT_WRAPPING_STRATEGY,\n  ENFORCE_TOKEN_BALANCE_CHECK,\n} from \"./config\";\nimport {\n  getCreateAccountInstruction,\n  getCreateAccountWithSeedInstruction,\n  getTransferSolInstruction,\n} from \"@solana-program/system\";\nimport { getTokenSize } from \"@solana-program/token\";\nimport {\n  getTokenSize as getTokenSizeWithExtensions,\n  TOKEN_2022_PROGRAM_ADDRESS,\n} from \"@solana-program/token-2022\";\nimport type { ExtensionArgs, Mint } from \"@solana-program/token-2022\";\nimport type { TransferFee } from \"@orca-so/whirlpools-core\";\nimport assert from \"assert\";\n\n// This file is not exported through the barrel file\n\n/** The public key for the native mint (SOL) */\nexport const NATIVE_MINT = address(\n  \"So11111111111111111111111111111111111111112\",\n);\n\n/**\n * Represents the instructions and associated addresses for preparing token accounts during a transaction.\n */\ntype TokenAccountInstructions = {\n  /** A list of instructions required to create the necessary token accounts. */\n  createInstructions: IInstruction[];\n\n  /** A list of instructions to clean up (e.g., close) token accounts after the transaction is complete. */\n  cleanupInstructions: IInstruction[];\n\n  /** A mapping of mint addresses to their respective token account addresses. */\n  tokenAccountAddresses: Record<Address, Address>;\n};\n\nfunction mintFilter(x: Address) {\n  if (\n    NATIVE_MINT_WRAPPING_STRATEGY === \"none\" ||\n    NATIVE_MINT_WRAPPING_STRATEGY === \"ata\"\n  ) {\n    return true;\n  }\n  return x != NATIVE_MINT;\n}\n\n/**\n *\n * Prepare token acounts required for a transaction. This will create\n * ATAs for the supplied mints.\n *\n * The NATIVE_MINT is a special case where this function will optionally wrap/unwrap\n * Native Mint based on the NATIVE_MINT_WRAPPING_STRATEGY.\n *\n * @param rpc\n * @param owner the owner to create token accounts for\n * @param spec the mints (and amounts) required in the token accounts\n * @returns Instructions and addresses for the required token accounts\n */\nexport async function prepareTokenAccountsInstructions(\n  rpc: Rpc<\n    GetAccountInfoApi &\n      GetMultipleAccountsApi &\n      GetMinimumBalanceForRentExemptionApi\n  >,\n  owner: TransactionSigner,\n  spec: Address[] | Record<Address, bigint | number>,\n): Promise<TokenAccountInstructions> {\n  const mintAddresses = Array.isArray(spec)\n    ? spec\n    : (Object.keys(spec) as Address[]);\n  const nativeMintIndex = mintAddresses.indexOf(NATIVE_MINT);\n  const hasNativeMint = nativeMintIndex !== -1;\n  const mints = await fetchAllMint(rpc, mintAddresses.filter(mintFilter));\n  const tokenAddresses = await Promise.all(\n    mints.map((mint) =>\n      findAssociatedTokenPda({\n        owner: owner.address,\n        mint: mint.address,\n        tokenProgram: mint.programAddress,\n      }).then((x) => x[0]),\n    ),\n  );\n  const tokenAccounts = await fetchAllMaybeToken(rpc, tokenAddresses);\n  const tokenAccountAddresses: Record<Address, Address> = {};\n\n  const createInstructions: IInstruction[] = [];\n  const cleanupInstructions: IInstruction[] = [];\n\n  for (let i = 0; i < mints.length; i++) {\n    const mint = mints[i];\n    const tokenAccount = tokenAccounts[i];\n    tokenAccountAddresses[mint.address] = tokenAccount.address;\n    if (tokenAccount.exists) {\n      continue;\n    }\n    createInstructions.push(\n      getCreateAssociatedTokenInstruction({\n        payer: owner,\n        owner: owner.address,\n        ata: tokenAccount.address,\n        mint: mint.address,\n        tokenProgram: mint.programAddress,\n      }),\n    );\n  }\n\n  if (!Array.isArray(spec)) {\n    for (let i = 0; i < mints.length; i++) {\n      const mint = mints[i];\n      if (\n        mint.address === NATIVE_MINT &&\n        NATIVE_MINT_WRAPPING_STRATEGY !== \"none\"\n      ) {\n        continue;\n      }\n      const tokenAccount = tokenAccounts[i];\n      const existingBalance = tokenAccount.exists\n        ? tokenAccount.data.amount\n        : 0n;\n      if (ENFORCE_TOKEN_BALANCE_CHECK) {\n        assert(\n          BigInt(spec[mint.address]) <= existingBalance,\n          `Token account for ${mint.address} does not have the required balance`,\n        );\n      }\n    }\n  }\n\n  if (hasNativeMint && NATIVE_MINT_WRAPPING_STRATEGY === \"keypair\") {\n    const keypair = await generateKeyPairSigner();\n    const space = getTokenSize();\n    let amount = await rpc\n      .getMinimumBalanceForRentExemption(BigInt(space))\n      .send();\n\n    if (!Array.isArray(spec)) {\n      amount = lamports(amount + BigInt(spec[NATIVE_MINT]));\n    }\n\n    createInstructions.push(\n      getCreateAccountInstruction({\n        payer: owner,\n        newAccount: keypair,\n        lamports: amount,\n        space,\n        programAddress: TOKEN_PROGRAM_ADDRESS,\n      }),\n      getInitializeAccount3Instruction({\n        account: keypair.address,\n        mint: NATIVE_MINT,\n        owner: owner.address,\n      }),\n    );\n    cleanupInstructions.push(\n      getCloseAccountInstruction({\n        account: keypair.address,\n        owner,\n        destination: owner.address,\n      }),\n    );\n    tokenAccountAddresses[NATIVE_MINT] = keypair.address;\n  }\n\n  if (hasNativeMint && NATIVE_MINT_WRAPPING_STRATEGY === \"seed\") {\n    const space = getTokenSize();\n    let amount = await rpc\n      .getMinimumBalanceForRentExemption(BigInt(space))\n      .send();\n\n    if (!Array.isArray(spec)) {\n      amount = lamports(amount + BigInt(spec[NATIVE_MINT]));\n    }\n\n    // Generating secure seed takes longer and is not really needed here.\n    // With date, it should only create collisions if the same owner\n    // creates multiple accounts at exactly the same time (in ms)\n    const seed = Date.now().toString();\n    const buffer = await crypto.subtle.digest(\n      \"SHA-256\",\n      Buffer.concat([\n        Buffer.from(getAddressEncoder().encode(owner.address)),\n        Buffer.from(seed),\n        Buffer.from(getAddressEncoder().encode(TOKEN_PROGRAM_ADDRESS)),\n      ]),\n    );\n    tokenAccountAddresses[NATIVE_MINT] = getAddressDecoder().decode(\n      new Uint8Array(buffer),\n    );\n\n    createInstructions.push(\n      getCreateAccountWithSeedInstruction({\n        payer: owner,\n        newAccount: tokenAccountAddresses[NATIVE_MINT],\n        base: owner.address,\n        baseAccount: owner,\n        seed: seed,\n        space,\n        amount,\n        programAddress: TOKEN_PROGRAM_ADDRESS,\n      }),\n      getInitializeAccount3Instruction({\n        account: tokenAccountAddresses[NATIVE_MINT],\n        mint: NATIVE_MINT,\n        owner: owner.address,\n      }),\n    );\n\n    cleanupInstructions.push(\n      getCloseAccountInstruction({\n        account: tokenAccountAddresses[NATIVE_MINT],\n        owner,\n        destination: owner.address,\n      }),\n    );\n  }\n\n  if (hasNativeMint && NATIVE_MINT_WRAPPING_STRATEGY === \"ata\") {\n    const account = tokenAccounts[nativeMintIndex];\n    const existingBalance = account.exists ? account.data.amount : 0n;\n\n    if (!Array.isArray(spec) && existingBalance < BigInt(spec[NATIVE_MINT])) {\n      createInstructions.push(\n        getTransferSolInstruction({\n          source: owner,\n          destination: tokenAccountAddresses[NATIVE_MINT],\n          amount: BigInt(spec[NATIVE_MINT]) - existingBalance,\n        }),\n        getSyncNativeInstruction({\n          account: tokenAccountAddresses[NATIVE_MINT],\n        }),\n      );\n    }\n\n    if (!account.exists) {\n      cleanupInstructions.push(\n        getCloseAccountInstruction({\n          account: account.address,\n          owner,\n          destination: owner.address,\n        }),\n      );\n    }\n  }\n\n  return {\n    createInstructions,\n    cleanupInstructions,\n    tokenAccountAddresses,\n  };\n}\n\n/**\n * Retrieves the current transfer fee configuration for a given token mint based on the current epoch.\n *\n * This function checks the mint's transfer fee configuration and returns the appropriate fee\n * structure (older or newer) depending on the current epoch. If no transfer fee configuration is found,\n * it returns `undefined`.\n *\n * @param {Mint} mint - The mint account of the token, which may include transfer fee extensions.\n * @param {bigint} currentEpoch - The current epoch to determine the applicable transfer fee.\n *\n * @returns {TransferFee | undefined} - The transfer fee configuration for the given mint, or `undefined` if no transfer fee is configured.\n */\nexport function getCurrentTransferFee(\n  mint: MaybeAccount<Mint> | Account<Mint> | null,\n  currentEpoch: bigint,\n): TransferFee | undefined {\n  if (\n    mint == null ||\n    (\"exists\" in mint && !mint.exists) ||\n    mint.data.extensions.__option === \"None\"\n  ) {\n    return undefined;\n  }\n  const feeConfig = mint.data.extensions.value.find(\n    (x) => x.__kind === \"TransferFeeConfig\",\n  );\n  if (feeConfig == null) {\n    return undefined;\n  }\n  const transferFee =\n    currentEpoch >= feeConfig.newerTransferFee.epoch\n      ? feeConfig.newerTransferFee\n      : feeConfig.olderTransferFee;\n  return {\n    feeBps: transferFee.transferFeeBasisPoints,\n    maxFee: transferFee.maximumFee,\n  };\n}\n\n/**\n * Builds the required account extensions for a given mint. This should only be used\n * for non-ATA token accounts since ATA accounts should also add the ImmutableOwner extension.\n *\n * https://github.com/solana-labs/solana-program-library/blob/3844bfac50990c1aa4dfb30f244f8c13178fc3fa/token/program-2022/src/extension/mod.rs#L1276\n *\n * @param {Mint} mint - The mint account to build extensions for.\n * @returns {ExtensionArgs[]} An array of extension arguments.\n */\nexport function getAccountExtensions(mint: Mint): ExtensionArgs[] {\n  if (mint.extensions.__option === \"None\") {\n    return [];\n  }\n  const extensions: ExtensionArgs[] = [];\n  for (const extension of mint.extensions.value) {\n    switch (extension.__kind) {\n      case \"TransferFeeConfig\":\n        extensions.push({\n          __kind: \"TransferFeeAmount\",\n          withheldAmount: 0n,\n        });\n        break;\n      case \"NonTransferable\":\n        extensions.push({\n          __kind: \"NonTransferableAccount\",\n        });\n        break;\n      case \"TransferHook\":\n        extensions.push({\n          __kind: \"TransferHookAccount\",\n          transferring: false,\n        });\n        break;\n      case \"PausableConfig\":\n        extensions.push({\n          __kind: \"PausableAccount\",\n        });\n        break;\n    }\n  }\n  return extensions;\n}\n\n/**\n * Orders two mints by canonical byte order.\n *\n * @param {Address} mint1\n * @param {Address} mint2\n * @returns {[Address, Address]} [mint1, mint2] if mint1 should come first, [mint2, mint1] otherwise\n */\nexport function orderMints(mint1: Address, mint2: Address): [Address, Address] {\n  const encoder = getAddressEncoder();\n  const mint1Bytes = new Uint8Array(encoder.encode(mint1));\n  const mint2Bytes = new Uint8Array(encoder.encode(mint2));\n  return Buffer.compare(mint1Bytes, mint2Bytes) < 0\n    ? [mint1, mint2]\n    : [mint2, mint1];\n}\n\n/**\n * Returns the token size for a given mint account.\n *\n * @param {Account<Mint>} mint - The mint account to get the token size for.\n * @returns {number} The token size for the given mint account.\n */\nexport function getTokenSizeForMint(mint: Account<Mint>): number {\n  const extensions = getAccountExtensions(mint.data);\n  if (\n    mint.programAddress === TOKEN_2022_PROGRAM_ADDRESS &&\n    !extensions.find((x) => x.__kind === \"ImmutableOwner\")\n  ) {\n    // For token-2022 accounts, we always include ImmutableOwner extension\n    extensions.push({\n      __kind: \"ImmutableOwner\",\n    });\n  }\n  return extensions.length === 0\n    ? getTokenSize()\n    : getTokenSizeWithExtensions(extensions);\n}\n","import type { SysvarRent } from \"@solana/sysvars\";\n\n/**\n * The overhead storage size for accounts.\n */\nconst ACCOUNT_STORAGE_OVERHEAD = 128;\n\n/**\n * Calculates the minimum balance required for rent exemption for a given account size.\n *\n * @param {Rpc} rpc - The Solana RPC client to fetch sysvar rent data.\n * @param {number} dataSize - The size of the account data in bytes.\n * @returns {bigint} The minimum balance required for rent exemption in lamports.\n */\nexport function calculateMinimumBalanceForRentExemption(\n  rent: SysvarRent,\n  dataSize: number,\n): bigint {\n  const dataSizeForRent = BigInt(dataSize + ACCOUNT_STORAGE_OVERHEAD);\n  const rentLamportsPerYear = rent.lamportsPerByteYear * dataSizeForRent;\n  const minimumBalance = rentLamportsPerYear * BigInt(rent.exemptionThreshold);\n\n  return minimumBalance;\n}\n","import {\n  address,\n  createNoopSigner,\n  getBase64EncodedWireTransaction,\n  type IInstruction,\n  type Rpc,\n  type Signature,\n  type SolanaRpcApi,\n  type TransactionSigner,\n} from \"@solana/kit\";\nimport { getPayer, getRpcConfig } from \"./config\";\nimport {\n  rpcFromUrl,\n  buildAndSendTransaction,\n  buildTransaction,\n} from \"@orca-so/tx-sender\";\n\n/**\n * A generic wrapper function to reduce boilerplate when working with Whirlpool instructions\n * @param instructionFn The Whirlpool instruction function to execute\n * @returns A wrapped function that automatically includes rpc and owner params\n */\nexport function wrapFunctionWithExecution<T extends unknown[], R>(\n  instructionFn: (\n    rpc: Rpc<SolanaRpcApi>,\n    ...params: [...T, TransactionSigner]\n  ) => Promise<R & { instructions: IInstruction[] }>,\n): (...params: T) => Promise<R & { callback: () => Promise<Signature> }> {\n  return async (...params: T) => {\n    const { rpcUrl } = getRpcConfig();\n    const rpc = rpcFromUrl(rpcUrl);\n    const owner = getPayer();\n\n    const result = await instructionFn(rpc, ...params, owner);\n\n    return {\n      ...result,\n      callback: () => buildAndSendTransaction(result.instructions, owner),\n    };\n  };\n}\n\n/**\n * Check if adding additional instructions would exceed transaction size limits\n * @param currentInstructions Current list of instructions in transaction\n * @param instructionsToAdd Instructions to check if they can be added\n * @returns True if adding instructions would exceed size limit, false otherwise\n */\nexport async function wouldExceedTransactionSize(\n  currentInstructions: IInstruction[],\n  instructionsToAdd: IInstruction[],\n): Promise<boolean> {\n  const noopSginer = createNoopSigner(\n    address(\"11111111111111111111111111111111\"),\n  );\n  const tx = await buildTransaction(\n    [...currentInstructions, ...instructionsToAdd],\n    noopSginer,\n  );\n  const encodedTransaction = getBase64EncodedWireTransaction(tx);\n\n  // The maximum size for a base64 encoded transaction is 1644 bytes\n  // This is derived from PACKET_DATA_SIZE (1232) with base64 encoding overhead\n  const TX_BASE64_ENCODED_SIZE_LIMIT = 1644;\n\n  return encodedTransaction.length >= TX_BASE64_ENCODED_SIZE_LIMIT;\n}\n","import type { Whirlpool } from \"@orca-so/whirlpools-client\";\nimport {\n  fetchAllTickArray,\n  fetchPosition,\n  fetchWhirlpool,\n  getClosePositionInstruction,\n  getClosePositionWithTokenExtensionsInstruction,\n  getCollectFeesV2Instruction,\n  getCollectRewardV2Instruction,\n  getDecreaseLiquidityV2Instruction,\n  getPositionAddress,\n  getTickArrayAddress,\n} from \"@orca-so/whirlpools-client\";\nimport type {\n  CollectFeesQuote,\n  CollectRewardsQuote,\n  DecreaseLiquidityQuote,\n  TickRange,\n  TransferFee,\n} from \"@orca-so/whirlpools-core\";\nimport {\n  _MAX_TICK_INDEX,\n  _MIN_TICK_INDEX,\n  getTickArrayStartTickIndex,\n  decreaseLiquidityQuote,\n  decreaseLiquidityQuoteA,\n  decreaseLiquidityQuoteB,\n  collectFeesQuote,\n  collectRewardsQuote,\n  getTickIndexInArray,\n} from \"@orca-so/whirlpools-core\";\nimport type {\n  Address,\n  GetAccountInfoApi,\n  GetEpochInfoApi,\n  GetMinimumBalanceForRentExemptionApi,\n  GetMultipleAccountsApi,\n  IInstruction,\n  Rpc,\n  TransactionSigner,\n} from \"@solana/kit\";\nimport { DEFAULT_ADDRESS, FUNDER, SLIPPAGE_TOLERANCE_BPS } from \"./config\";\nimport {\n  findAssociatedTokenPda,\n  TOKEN_PROGRAM_ADDRESS,\n} from \"@solana-program/token\";\nimport {\n  getCurrentTransferFee,\n  prepareTokenAccountsInstructions,\n} from \"./token\";\nimport {\n  fetchAllMint,\n  fetchAllMaybeMint,\n  TOKEN_2022_PROGRAM_ADDRESS,\n} from \"@solana-program/token-2022\";\nimport { MEMO_PROGRAM_ADDRESS } from \"@solana-program/memo\";\nimport assert from \"assert\";\nimport { wrapFunctionWithExecution } from \"./actionHelpers\";\n// TODO: allow specify number as well as bigint\n// TODO: transfer hook\n\n/**\n * Represents the parameters for decreasing liquidity.\n * You must choose only one of the properties (`liquidity`, `tokenA`, or `tokenB`).\n * The SDK will compute the other two based on the input provided.\n */\nexport type DecreaseLiquidityQuoteParam =\n  | {\n      /** The amount of liquidity to decrease.*/\n      liquidity: bigint;\n    }\n  | {\n      /** The amount of Token A to withdraw.*/\n      tokenA: bigint;\n    }\n  | {\n      /** The amount of Token B to withdraw.*/\n      tokenB: bigint;\n    };\n\n/**\n * Represents the instructions and quote for decreasing liquidity in a position.\n */\nexport type DecreaseLiquidityInstructions = {\n  /** The quote details for decreasing liquidity, including the liquidity delta, estimated tokens, and minimum token amounts based on slippage tolerance. */\n  quote: DecreaseLiquidityQuote;\n\n  /** The list of instructions required to decrease liquidity. */\n  instructions: IInstruction[];\n};\n\nfunction getDecreaseLiquidityQuote(\n  param: DecreaseLiquidityQuoteParam,\n  pool: Whirlpool,\n  tickRange: TickRange,\n  slippageToleranceBps: number,\n  transferFeeA: TransferFee | undefined,\n  transferFeeB: TransferFee | undefined,\n): DecreaseLiquidityQuote {\n  if (\"liquidity\" in param) {\n    return decreaseLiquidityQuote(\n      param.liquidity,\n      slippageToleranceBps,\n      pool.sqrtPrice,\n      tickRange.tickLowerIndex,\n      tickRange.tickUpperIndex,\n      transferFeeA,\n      transferFeeB,\n    );\n  } else if (\"tokenA\" in param) {\n    return decreaseLiquidityQuoteA(\n      param.tokenA,\n      slippageToleranceBps,\n      pool.sqrtPrice,\n      tickRange.tickLowerIndex,\n      tickRange.tickUpperIndex,\n      transferFeeA,\n      transferFeeB,\n    );\n  } else {\n    return decreaseLiquidityQuoteB(\n      param.tokenB,\n      slippageToleranceBps,\n      pool.sqrtPrice,\n      tickRange.tickLowerIndex,\n      tickRange.tickUpperIndex,\n      transferFeeA,\n      transferFeeB,\n    );\n  }\n}\n\n/**\n * Generates instructions to decrease liquidity from an existing position in an Orca Whirlpool.\n *\n * @param {SolanaRpc} rpc - A Solana RPC client for fetching necessary accounts and pool data.\n * @param {Address} positionMintAddress - The mint address of the NFT that represents ownership of the position from which liquidity will be removed.\n * @param {DecreaseLiquidityQuoteParam} param - Defines the liquidity removal method (liquidity, tokenA, or tokenB).\n * @param {number} [slippageToleranceBps=SLIPPAGE_TOLERANCE_BPS] - The acceptable slippage tolerance in basis points.\n * @param {TransactionSigner} [authority=FUNDER] - The account authorizing the liquidity removal.\n *\n * @returns {Promise<DecreaseLiquidityInstructions>} A promise resolving to an object containing the decrease liquidity quote and instructions.\n *\n * @example\n * import { decreaseLiquidityInstructions, setWhirlpoolsConfig } from '@orca-so/whirlpools';\n * import { createSolanaRpc, devnet, address } from '@solana/kit';\n * import { loadWallet } from './utils';\n *\n * await setWhirlpoolsConfig('solanaDevnet');\n * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));\n * const wallet = await loadWallet();\n * const positionMint = address(\"HqoV7Qv27REUtmd9UKSJGGmCRNx3531t33bDG1BUfo9K\");\n * const param = { tokenA: 10n };\n * const { quote, instructions } = await decreaseLiquidityInstructions(\n *   devnetRpc,\n *   positionMint,\n *   param,\n *   100,\n *   wallet\n * );\n *\n * console.log(`Quote token max B: ${quote.tokenEstB}`);\n */\nexport async function decreaseLiquidityInstructions(\n  rpc: Rpc<\n    GetAccountInfoApi &\n      GetMultipleAccountsApi &\n      GetMinimumBalanceForRentExemptionApi &\n      GetEpochInfoApi\n  >,\n  positionMintAddress: Address,\n  param: DecreaseLiquidityQuoteParam,\n  slippageToleranceBps: number = SLIPPAGE_TOLERANCE_BPS,\n  authority: TransactionSigner = FUNDER,\n): Promise<DecreaseLiquidityInstructions> {\n  assert(\n    authority.address !== DEFAULT_ADDRESS,\n    \"Either supply the authority or set the default funder\",\n  );\n\n  const positionAddress = await getPositionAddress(positionMintAddress);\n  const position = await fetchPosition(rpc, positionAddress[0]);\n  const whirlpool = await fetchWhirlpool(rpc, position.data.whirlpool);\n\n  const currentEpoch = await rpc.getEpochInfo().send();\n  const [mintA, mintB, positionMint] = await fetchAllMint(rpc, [\n    whirlpool.data.tokenMintA,\n    whirlpool.data.tokenMintB,\n    positionMintAddress,\n  ]);\n  const transferFeeA = getCurrentTransferFee(mintA, currentEpoch.epoch);\n  const transferFeeB = getCurrentTransferFee(mintB, currentEpoch.epoch);\n\n  const quote = getDecreaseLiquidityQuote(\n    param,\n    whirlpool.data,\n    position.data,\n    slippageToleranceBps,\n    transferFeeA,\n    transferFeeB,\n  );\n  const instructions: IInstruction[] = [];\n\n  const lowerTickArrayStartIndex = getTickArrayStartTickIndex(\n    position.data.tickLowerIndex,\n    whirlpool.data.tickSpacing,\n  );\n  const upperTickArrayStartIndex = getTickArrayStartTickIndex(\n    position.data.tickUpperIndex,\n    whirlpool.data.tickSpacing,\n  );\n\n  const [positionTokenAccount, tickArrayLower, tickArrayUpper] =\n    await Promise.all([\n      findAssociatedTokenPda({\n        owner: authority.address,\n        mint: positionMintAddress,\n        tokenProgram: positionMint.programAddress,\n      }).then((x) => x[0]),\n      getTickArrayAddress(whirlpool.address, lowerTickArrayStartIndex).then(\n        (x) => x[0],\n      ),\n      getTickArrayAddress(whirlpool.address, upperTickArrayStartIndex).then(\n        (x) => x[0],\n      ),\n    ]);\n\n  const { createInstructions, cleanupInstructions, tokenAccountAddresses } =\n    await prepareTokenAccountsInstructions(rpc, authority, [\n      whirlpool.data.tokenMintA,\n      whirlpool.data.tokenMintB,\n    ]);\n\n  instructions.push(...createInstructions);\n\n  instructions.push(\n    getDecreaseLiquidityV2Instruction({\n      whirlpool: whirlpool.address,\n      positionAuthority: authority,\n      position: position.address,\n      positionTokenAccount,\n      tokenOwnerAccountA: tokenAccountAddresses[whirlpool.data.tokenMintA],\n      tokenOwnerAccountB: tokenAccountAddresses[whirlpool.data.tokenMintB],\n      tokenVaultA: whirlpool.data.tokenVaultA,\n      tokenVaultB: whirlpool.data.tokenVaultB,\n      tokenMintA: whirlpool.data.tokenMintA,\n      tokenMintB: whirlpool.data.tokenMintB,\n      tokenProgramA: mintA.programAddress,\n      tokenProgramB: mintB.programAddress,\n      memoProgram: MEMO_PROGRAM_ADDRESS,\n      tickArrayLower,\n      tickArrayUpper,\n      liquidityAmount: quote.liquidityDelta,\n      tokenMinA: quote.tokenMinA,\n      tokenMinB: quote.tokenMinB,\n      remainingAccountsInfo: null,\n    }),\n  );\n\n  instructions.push(...cleanupInstructions);\n\n  return { quote, instructions };\n}\n\n/**\n * Represents the instructions and quotes for closing a liquidity position in an Orca Whirlpool.\n * Extends `DecreaseLiquidityInstructions` and adds additional fee and reward details.\n */\nexport type ClosePositionInstructions = DecreaseLiquidityInstructions & {\n  /** The fees collected from the position, including the amounts for token A (`fee_owed_a`) and token B (`fee_owed_b`). */\n  feesQuote: CollectFeesQuote;\n\n  /** The rewards collected from the position, including up to three reward tokens (`reward_owed_1`, `reward_owed_2`, and `reward_owed_3`). */\n  rewardsQuote: CollectRewardsQuote;\n};\n\n/**\n * Generates instructions to close a liquidity position in an Orca Whirlpool. This includes collecting all fees,\n * rewards, removing any remaining liquidity, and closing the position.\n *\n * @param {SolanaRpc} rpc - A Solana RPC client for fetching accounts and pool data.\n * @param {Address} positionMintAddress - The mint address of the NFT that represents ownership of the position to be closed.\n * @param {number} [slippageToleranceBps=SLIPPAGE_TOLERANCE_BPS] - The acceptable slippage tolerance in basis points.\n * @param {TransactionSigner} [authority=FUNDER] - The account authorizing the transaction.\n *\n * @returns {Promise<ClosePositionInstructions>} A promise resolving to an object containing instructions, fees quote, rewards quote, and the liquidity quote for the closed position.\n *\n * @example\n * import { closePositionInstructions, setWhirlpoolsConfig } from '@orca-so/whirlpools';\n * import { createSolanaRpc, devnet, address } from '@solana/kit';\n * import { loadWallet } from './utils';\n *\n * await setWhirlpoolsConfig('solanaDevnet');\n * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));\n * const wallet = await loadWallet();\n * const positionMint = address(\"HqoV7Qv27REUtmd9UKSJGGmCRNx3531t33bDG1BUfo9K\");\n *\n * const { instructions, quote, feesQuote, rewardsQuote } = await closePositionInstructions(\n *   devnetRpc,\n *   positionMint,\n *   100,\n *   wallet\n * );\n *\n * console.log(`Quote token max B: ${quote.tokenEstB}`);\n * console.log(`Fees owed token A: ${feesQuote.feeOwedA}`);\n * console.log(`Rewards '1' owed: ${rewardsQuote.rewards[0].rewardsOwed}`);\n * console.log(`Number of instructions:, ${instructions.length}`);\n */\nexport async function closePositionInstructions(\n  rpc: Rpc<\n    GetAccountInfoApi &\n      GetMultipleAccountsApi &\n      GetMinimumBalanceForRentExemptionApi &\n      GetEpochInfoApi\n  >,\n  positionMintAddress: Address,\n  slippageToleranceBps: number = SLIPPAGE_TOLERANCE_BPS,\n  authority: TransactionSigner = FUNDER,\n): Promise<ClosePositionInstructions> {\n  assert(\n    authority.address !== DEFAULT_ADDRESS,\n    \"Either supply an authority or set the default funder\",\n  );\n\n  const positionAddress = await getPositionAddress(positionMintAddress);\n  const position = await fetchPosition(rpc, positionAddress[0]);\n  const whirlpool = await fetchWhirlpool(rpc, position.data.whirlpool);\n\n  const currentEpoch = await rpc.getEpochInfo().send();\n  const [mintA, mintB, positionMint, ...rewardMints] = await fetchAllMaybeMint(\n    rpc,\n    [\n      whirlpool.data.tokenMintA,\n      whirlpool.data.tokenMintB,\n      positionMintAddress,\n      ...whirlpool.data.rewardInfos\n        .map((x) => x.mint)\n        .filter((x) => x !== DEFAULT_ADDRESS),\n    ],\n  );\n\n  assert(mintA.exists, \"Token A not found\");\n  assert(mintB.exists, \"Token B not found\");\n  assert(positionMint.exists, \"Position mint not found\");\n\n  const transferFeeA = getCurrentTransferFee(mintA, currentEpoch.epoch);\n  const transferFeeB = getCurrentTransferFee(mintB, currentEpoch.epoch);\n\n  const quote = getDecreaseLiquidityQuote(\n    { liquidity: position.data.liquidity },\n    whirlpool.data,\n    position.data,\n    slippageToleranceBps,\n    transferFeeA,\n    transferFeeB,\n  );\n\n  const lowerTickArrayStartIndex = getTickArrayStartTickIndex(\n    position.data.tickLowerIndex,\n    whirlpool.data.tickSpacing,\n  );\n  const upperTickArrayStartIndex = getTickArrayStartTickIndex(\n    position.data.tickUpperIndex,\n    whirlpool.data.tickSpacing,\n  );\n\n  const [positionTokenAccount, lowerTickArrayAddress, upperTickArrayAddress] =\n    await Promise.all([\n      findAssociatedTokenPda({\n        owner: authority.address,\n        mint: positionMintAddress,\n        tokenProgram: positionMint.programAddress,\n      }).then((x) => x[0]),\n      getTickArrayAddress(whirlpool.address, lowerTickArrayStartIndex).then(\n        (x) => x[0],\n      ),\n      getTickArrayAddress(whirlpool.address, upperTickArrayStartIndex).then(\n        (x) => x[0],\n      ),\n    ]);\n\n  const [lowerTickArray, upperTickArray] = await fetchAllTickArray(rpc, [\n    lowerTickArrayAddress,\n    upperTickArrayAddress,\n  ]);\n\n  const lowerTick =\n    lowerTickArray.data.ticks[\n      getTickIndexInArray(\n        position.data.tickLowerIndex,\n        lowerTickArrayStartIndex,\n        whirlpool.data.tickSpacing,\n      )\n    ];\n  const upperTick =\n    upperTickArray.data.ticks[\n      getTickIndexInArray(\n        position.data.tickUpperIndex,\n        upperTickArrayStartIndex,\n        whirlpool.data.tickSpacing,\n      )\n    ];\n\n  const feesQuote = collectFeesQuote(\n    whirlpool.data,\n    position.data,\n    lowerTick,\n    upperTick,\n    transferFeeA,\n    transferFeeB,\n  );\n  const currentUnixTimestamp = BigInt(Math.floor(Date.now() / 1000));\n  const rewardsQuote = collectRewardsQuote(\n    whirlpool.data,\n    position.data,\n    lowerTick,\n    upperTick,\n    currentUnixTimestamp,\n    getCurrentTransferFee(rewardMints[0], currentEpoch.epoch),\n    getCurrentTransferFee(rewardMints[1], currentEpoch.epoch),\n    getCurrentTransferFee(rewardMints[2], currentEpoch.epoch),\n  );\n\n  const requiredMints: Set<Address> = new Set();\n  if (\n    quote.liquidityDelta > 0n ||\n    feesQuote.feeOwedA > 0n ||\n    feesQuote.feeOwedB > 0n\n  ) {\n    requiredMints.add(whirlpool.data.tokenMintA);\n    requiredMints.add(whirlpool.data.tokenMintB);\n  }\n\n  for (let i = 0; i < rewardsQuote.rewards.length; i++) {\n    if (rewardsQuote.rewards[i].rewardsOwed > 0n) {\n      requiredMints.add(whirlpool.data.rewardInfos[i].mint);\n    }\n  }\n\n  const { createInstructions, cleanupInstructions, tokenAccountAddresses } =\n    await prepareTokenAccountsInstructions(\n      rpc,\n      authority,\n      Array.from(requiredMints),\n    );\n\n  const instructions: IInstruction[] = [];\n  instructions.push(...createInstructions);\n\n  if (quote.liquidityDelta > 0n) {\n    instructions.push(\n      getDecreaseLiquidityV2Instruction({\n        whirlpool: whirlpool.address,\n        positionAuthority: authority,\n        position: positionAddress[0],\n        positionTokenAccount,\n        tokenOwnerAccountA: tokenAccountAddresses[whirlpool.data.tokenMintA],\n        tokenOwnerAccountB: tokenAccountAddresses[whirlpool.data.tokenMintB],\n        tokenVaultA: whirlpool.data.tokenVaultA,\n        tokenVaultB: whirlpool.data.tokenVaultB,\n        tickArrayLower: lowerTickArrayAddress,\n        tickArrayUpper: upperTickArrayAddress,\n        liquidityAmount: quote.liquidityDelta,\n        tokenMinA: quote.tokenMinA,\n        tokenMinB: quote.tokenMinB,\n        tokenMintA: whirlpool.data.tokenMintA,\n        tokenMintB: whirlpool.data.tokenMintB,\n        tokenProgramA: mintA.programAddress,\n        tokenProgramB: mintB.programAddress,\n        memoProgram: MEMO_PROGRAM_ADDRESS,\n        remainingAccountsInfo: null,\n      }),\n    );\n  }\n\n  if (feesQuote.feeOwedA > 0n || feesQuote.feeOwedB > 0n) {\n    instructions.push(\n      getCollectFeesV2Instruction({\n        whirlpool: whirlpool.address,\n        positionAuthority: authority,\n        position: positionAddress[0],\n        positionTokenAccount,\n        tokenOwnerAccountA: tokenAccountAddresses[whirlpool.data.tokenMintA],\n        tokenOwnerAccountB: tokenAccountAddresses[whirlpool.data.tokenMintB],\n        tokenVaultA: whirlpool.data.tokenVaultA,\n        tokenVaultB: whirlpool.data.tokenVaultB,\n        tokenMintA: whirlpool.data.tokenMintA,\n        tokenMintB: whirlpool.data.tokenMintB,\n        tokenProgramA: mintA.programAddress,\n        tokenProgramB: mintB.programAddress,\n        memoProgram: MEMO_PROGRAM_ADDRESS,\n        remainingAccountsInfo: null,\n      }),\n    );\n  }\n\n  for (let i = 0; i < rewardsQuote.rewards.length; i++) {\n    if (rewardsQuote.rewards[i].rewardsOwed === 0n) {\n      continue;\n    }\n    const rewardMint = rewardMints[i];\n    assert(rewardMint.exists, `Reward mint ${i} not found`);\n    instructions.push(\n      getCollectRewardV2Instruction({\n        whirlpool: whirlpool.address,\n        positionAuthority: authority,\n        position: positionAddress[0],\n        positionTokenAccount,\n        rewardOwnerAccount: tokenAccountAddresses[rewardMint.address],\n        rewardVault: whirlpool.data.rewardInfos[i].vault,\n        rewardIndex: i,\n        rewardMint: rewardMint.address,\n        rewardTokenProgram: rewardMint.programAddress,\n        memoProgram: MEMO_PROGRAM_ADDRESS,\n        remainingAccountsInfo: null,\n      }),\n    );\n  }\n\n  switch (positionMint.programAddress) {\n    case TOKEN_PROGRAM_ADDRESS:\n      instructions.push(\n        getClosePositionInstruction({\n          positionAuthority: authority,\n          position: positionAddress[0],\n          positionTokenAccount,\n          positionMint: positionMintAddress,\n          receiver: authority.address,\n        }),\n      );\n      break;\n    case TOKEN_2022_PROGRAM_ADDRESS:\n      instructions.push(\n        getClosePositionWithTokenExtensionsInstruction({\n          positionAuthority: authority,\n          position: positionAddress[0],\n          positionTokenAccount,\n          positionMint: positionMintAddress,\n          receiver: authority.address,\n          token2022Program: TOKEN_2022_PROGRAM_ADDRESS,\n        }),\n      );\n      break;\n    default:\n      throw new Error(\"Invalid token program\");\n  }\n\n  instructions.push(...cleanupInstructions);\n\n  return {\n    instructions,\n    quote,\n    feesQuote,\n    rewardsQuote,\n  };\n}\n\n// -------- ACTIONS --------\n\nexport const closePosition = wrapFunctionWithExecution(\n  closePositionInstructions,\n);\n\nexport const decreaseLiquidity = wrapFunctionWithExecution(\n  decreaseLiquidityInstructions,\n);\n","import type {\n  CollectFeesQuote,\n  CollectRewardsQuote,\n} from \"@orca-so/whirlpools-core\";\nimport {\n  collectFeesQuote,\n  collectRewardsQuote,\n  getTickArrayStartTickIndex,\n  getTickIndexInArray,\n} from \"@orca-so/whirlpools-core\";\nimport type {\n  Rpc,\n  GetAccountInfoApi,\n  Address,\n  IInstruction,\n  TransactionSigner,\n  GetMultipleAccountsApi,\n  GetMinimumBalanceForRentExemptionApi,\n  GetEpochInfoApi,\n  Signature,\n} from \"@solana/kit\";\nimport { DEFAULT_ADDRESS, FUNDER, getPayer, getRpcConfig } from \"./config\";\nimport {\n  fetchAllTickArray,\n  fetchPosition,\n  fetchWhirlpool,\n  getCollectFeesV2Instruction,\n  getCollectRewardV2Instruction,\n  getPositionAddress,\n  getTickArrayAddress,\n  getUpdateFeesAndRewardsInstruction,\n} from \"@orca-so/whirlpools-client\";\nimport { findAssociatedTokenPda } from \"@solana-program/token\";\nimport {\n  getCurrentTransferFee,\n  prepareTokenAccountsInstructions,\n} from \"./token\";\nimport { fetchAllMaybeMint } from \"@solana-program/token-2022\";\nimport { MEMO_PROGRAM_ADDRESS } from \"@solana-program/memo\";\nimport assert from \"assert\";\nimport {\n  wouldExceedTransactionSize,\n  wrapFunctionWithExecution,\n} from \"./actionHelpers\";\nimport { rpcFromUrl, buildAndSendTransaction } from \"@orca-so/tx-sender\";\nimport { fetchPositionsForOwner } from \"./position\";\n\n// TODO: Transfer hook\n\n/**\n * Represents the instructions and quotes for harvesting a position.\n */\nexport type HarvestPositionInstructions = {\n  /** A breakdown of the fees owed to the position owner, detailing the amounts for token A (`fee_owed_a`) and token B (`fee_owed_b`). */\n  feesQuote: CollectFeesQuote;\n\n  /** A breakdown of the rewards owed, detailing up to three reward tokens (`reward_owed_1`, `reward_owed_2`, and `reward_owed_3`). */\n  rewardsQuote: CollectRewardsQuote;\n\n  /** A list of instructions required to harvest the position. */\n  instructions: IInstruction[];\n};\n\n/**\n * This function creates a set of instructions that collect any accumulated fees and rewards from a position.\n * The liquidity remains in place, and the position stays open.\n *\n * @param {SolanaRpc} rpc\n *    A Solana RPC client used to interact with the blockchain.\n * @param {Address} positionMintAddress\n *    The position mint address you want to harvest fees and rewards from.\n * @param {TransactionSigner} [authority=FUNDER]\n *    The account that authorizes the transaction. Defaults to a predefined funder.\n *\n * @returns {Promise<HarvestPositionInstructions>}\n *    A promise that resolves to an object containing the instructions, fees, and rewards quotes.\n * @example\n * import { harvestPositionInstructions, setWhirlpoolsConfig } from '@orca-so/whirlpools';\n * import { createSolanaRpc, devnet, address } from '@solana/kit';\n * import { loadWallet } from './utils';\n *\n * await setWhirlpoolsConfig('solanaDevnet');\n * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));\n * const wallet = await loadWallet();\n * const positionMint = address(\"HqoV7Qv27REUtmd9UKSJGGmCRNx3531t33bDG1BUfo9K\");\n *\n * const { feesQuote, rewardsQuote, instructions } = await harvestPositionInstructions(\n *   devnetRpc,\n *   positionMint,\n *   wallet\n * );\n *\n * console.log(`Fees owed token A: ${feesQuote.feeOwedA}`);\n * console.log(`Rewards '1' owed: ${rewardsQuote.rewards[0].rewardsOwed}`);\n */\nexport async function harvestPositionInstructions(\n  rpc: Rpc<\n    GetAccountInfoApi &\n      GetMultipleAccountsApi &\n      GetMinimumBalanceForRentExemptionApi &\n      GetEpochInfoApi\n  >,\n  positionMintAddress: Address,\n  authority: TransactionSigner = FUNDER,\n): Promise<HarvestPositionInstructions> {\n  assert(\n    authority.address !== DEFAULT_ADDRESS,\n    \"Either supply an authority or set the default funder\",\n  );\n\n  const currentEpoch = await rpc.getEpochInfo().send();\n  const positionAddress = await getPositionAddress(positionMintAddress);\n  const position = await fetchPosition(rpc, positionAddress[0]);\n  const whirlpool = await fetchWhirlpool(rpc, position.data.whirlpool);\n  const [mintA, mintB, positionMint, ...rewardMints] = await fetchAllMaybeMint(\n    rpc,\n    [\n      whirlpool.data.tokenMintA,\n      whirlpool.data.tokenMintB,\n      positionMintAddress,\n      ...whirlpool.data.rewardInfos\n        .map((x) => x.mint)\n        .filter((x) => x !== DEFAULT_ADDRESS),\n    ],\n  );\n\n  assert(mintA.exists, \"Token A not found\");\n  assert(mintB.exists, \"Token B not found\");\n  assert(positionMint.exists, \"Position mint not found\");\n\n  const lowerTickArrayStartIndex = getTickArrayStartTickIndex(\n    position.data.tickLowerIndex,\n    whirlpool.data.tickSpacing,\n  );\n  const upperTickArrayStartIndex = getTickArrayStartTickIndex(\n    position.data.tickUpperIndex,\n    whirlpool.data.tickSpacing,\n  );\n\n  const [positionTokenAccount, lowerTickArrayAddress, upperTickArrayAddress] =\n    await Promise.all([\n      findAssociatedTokenPda({\n        owner: authority.address,\n        mint: positionMintAddress,\n        tokenProgram: positionMint.programAddress,\n      }).then((x) => x[0]),\n      getTickArrayAddress(whirlpool.address, lowerTickArrayStartIndex).then(\n        (x) => x[0],\n      ),\n      getTickArrayAddress(whirlpool.address, upperTickArrayStartIndex).then(\n        (x) => x[0],\n      ),\n    ]);\n\n  const [lowerTickArray, upperTickArray] = await fetchAllTickArray(rpc, [\n    lowerTickArrayAddress,\n    upperTickArrayAddress,\n  ]);\n\n  const lowerTick =\n    lowerTickArray.data.ticks[\n      getTickIndexInArray(\n        position.data.tickLowerIndex,\n        lowerTickArrayStartIndex,\n        whirlpool.data.tickSpacing,\n      )\n    ];\n  const upperTick =\n    upperTickArray.data.ticks[\n      getTickIndexInArray(\n        position.data.tickUpperIndex,\n        upperTickArrayStartIndex,\n        whirlpool.data.tickSpacing,\n      )\n    ];\n\n  const feesQuote = collectFeesQuote(\n    whirlpool.data,\n    position.data,\n    lowerTick,\n    upperTick,\n    getCurrentTransferFee(mintA, currentEpoch.epoch),\n    getCurrentTransferFee(mintB, currentEpoch.epoch),\n  );\n  const currentUnixTimestamp = BigInt(Math.floor(Date.now() / 1000));\n  const rewardsQuote = collectRewardsQuote(\n    whirlpool.data,\n    position.data,\n    lowerTick,\n    upperTick,\n    currentUnixTimestamp,\n    getCurrentTransferFee(rewardMints[0], currentEpoch.epoch),\n    getCurrentTransferFee(rewardMints[1], currentEpoch.epoch),\n    getCurrentTransferFee(rewardMints[2], currentEpoch.epoch),\n  );\n\n  const requiredMints: Set<Address> = new Set();\n  if (feesQuote.feeOwedA > 0n || feesQuote.feeOwedB > 0n) {\n    requiredMints.add(whirlpool.data.tokenMintA);\n    requiredMints.add(whirlpool.data.tokenMintB);\n  }\n\n  for (let i = 0; i < rewardsQuote.rewards.length; i++) {\n    if (rewardsQuote.rewards[i].rewardsOwed > 0n) {\n      requiredMints.add(whirlpool.data.rewardInfos[i].mint);\n    }\n  }\n\n  const { createInstructions, cleanupInstructions, tokenAccountAddresses } =\n    await prepareTokenAccountsInstructions(\n      rpc,\n      authority,\n      Array.from(requiredMints),\n    );\n\n  const instructions: IInstruction[] = [];\n  instructions.push(...createInstructions);\n\n  if (position.data.liquidity > 0n) {\n    instructions.push(\n      getUpdateFeesAndRewardsInstruction({\n        whirlpool: whirlpool.address,\n        position: positionAddress[0],\n        tickArrayLower: lowerTickArrayAddress,\n        tickArrayUpper: upperTickArrayAddress,\n      }),\n    );\n  }\n\n  if (feesQuote.feeOwedA > 0n || feesQuote.feeOwedB > 0n) {\n    instructions.push(\n      getCollectFeesV2Instruction({\n        whirlpool: whirlpool.address,\n        positionAuthority: authority,\n        position: positionAddress[0],\n        positionTokenAccount,\n        tokenOwnerAccountA: tokenAccountAddresses[whirlpool.data.tokenMintA],\n        tokenOwnerAccountB: tokenAccountAddresses[whirlpool.data.tokenMintB],\n        tokenVaultA: whirlpool.data.tokenVaultA,\n        tokenVaultB: whirlpool.data.tokenVaultB,\n        tokenMintA: whirlpool.data.tokenMintA,\n        tokenMintB: whirlpool.data.tokenMintB,\n        tokenProgramA: mintA.programAddress,\n        tokenProgramB: mintB.programAddress,\n        memoProgram: MEMO_PROGRAM_ADDRESS,\n        remainingAccountsInfo: null,\n      }),\n    );\n  }\n\n  for (let i = 0; i < rewardsQuote.rewards.length; i++) {\n    if (rewardsQuote.rewards[i].rewardsOwed === 0n) {\n      continue;\n    }\n    const rewardMint = rewardMints[i];\n    assert(rewardMint.exists, `Reward mint ${i} not found`);\n    instructions.push(\n      getCollectRewardV2Instruction({\n        whirlpool: whirlpool.address,\n        positionAuthority: authority,\n        position: positionAddress[0],\n        positionTokenAccount,\n        rewardOwnerAccount: tokenAccountAddresses[rewardMint.address],\n        rewardVault: whirlpool.data.rewardInfos[i].vault,\n        rewardIndex: i,\n        rewardMint: rewardMint.address,\n        rewardTokenProgram: rewardMint.programAddress,\n        memoProgram: MEMO_PROGRAM_ADDRESS,\n        remainingAccountsInfo: null,\n      }),\n    );\n  }\n\n  instructions.push(...cleanupInstructions);\n\n  return {\n    feesQuote,\n    rewardsQuote,\n    instructions,\n  };\n}\n\n// -------- ACTIONS --------\n\nexport const harvestPosition = wrapFunctionWithExecution(\n  harvestPositionInstructions,\n);\n\nexport async function harvestAllPositionFees(): Promise<Signature[]> {\n  const { rpcUrl } = getRpcConfig();\n  const rpc = rpcFromUrl(rpcUrl);\n  const owner = getPayer();\n\n  const positions = await fetchPositionsForOwner(rpc, owner.address);\n  const instructionSets: IInstruction[][] = [];\n  let currentInstructions: IInstruction[] = [];\n  for (const position of positions) {\n    if (\"positionMint\" in position.data) {\n      const { instructions } = await harvestPositionInstructions(\n        rpc,\n        position.data.positionMint,\n        owner,\n      );\n      if (await wouldExceedTransactionSize(currentInstructions, instructions)) {\n        instructionSets.push(currentInstructions);\n        currentInstructions = [...instructions];\n      } else {\n        currentInstructions.push(...instructions);\n      }\n    }\n  }\n  return Promise.all(\n    instructionSets.map(async (instructions) => {\n      let txHash = await buildAndSendTransaction(instructions, owner);\n      return txHash;\n    }),\n  );\n}\n","import type { Position, PositionBundle } from \"@orca-so/whirlpools-client\";\nimport {\n  decodePosition,\n  decodePositionBundle,\n  fetchAllPositionWithFilter,\n  getBundledPositionAddress,\n  getPositionAddress,\n  getPositionBundleAddress,\n  positionWhirlpoolFilter,\n} from \"@orca-so/whirlpools-client\";\nimport { _POSITION_BUNDLE_SIZE } from \"@orca-so/whirlpools-core\";\nimport { getTokenDecoder, TOKEN_PROGRAM_ADDRESS } from \"@solana-program/token\";\nimport { TOKEN_2022_PROGRAM_ADDRESS } from \"@solana-program/token-2022\";\nimport type {\n  Account,\n  Address,\n  GetMultipleAccountsApi,\n  GetProgramAccountsApi,\n  GetTokenAccountsByOwnerApi,\n  Rpc,\n} from \"@solana/kit\";\nimport { assertAccountExists, getBase64Encoder } from \"@solana/kit\";\nimport { fetchMultipleAccountsBatched } from \"./utils\";\n\n/**\n * Represents a Position account.\n */\nexport type HydratedPosition = Account<Position> & {\n  isPositionBundle: false;\n};\n\n/**\n * Represents a Position Bundle account including its associated positions.\n */\nexport type HydratedPositionBundle = Account<PositionBundle> & {\n  positions: Account<Position>[];\n  isPositionBundle: true;\n};\n\n/**\n * Represents either a Position or Position Bundle account.\n */\nexport type PositionOrBundle = HydratedPosition | HydratedPositionBundle;\n\n/**\n * Represents a decoded Position or Position Bundle account.\n * Includes the token program address associated with the position.\n */\nexport type PositionData = PositionOrBundle & {\n  /** The token program associated with the position (either TOKEN_PROGRAM_ADDRESS or TOKEN_2022_PROGRAM_ADDRESS). */\n  tokenProgram: Address;\n};\n\nfunction getPositionInBundleAddresses(\n  positionBundle: PositionBundle,\n): Promise<Address>[] {\n  const buffer = Buffer.from(positionBundle.positionBitmap);\n  const positions: Promise<Address>[] = [];\n  for (let i = 0; i < _POSITION_BUNDLE_SIZE(); i++) {\n    const byteIndex = Math.floor(i / 8);\n    const bitIndex = i % 8;\n    if (buffer[byteIndex] & (1 << bitIndex)) {\n      positions.push(\n        getBundledPositionAddress(positionBundle.positionBundleMint, i).then(\n          (x) => x[0],\n        ),\n      );\n    }\n  }\n  return positions;\n}\n\n/**\n * Fetches all positions owned by a given wallet in the Orca Whirlpools.\n * It looks for token accounts owned by the wallet using both the TOKEN_PROGRAM_ADDRESS and TOKEN_2022_PROGRAM_ADDRESS.\n * For token accounts holding exactly 1 token (indicating a position or bundle), it fetches the corresponding position addresses,\n * decodes the accounts, and returns an array of position or bundle data.\n *\n * @param {SolanaRpc} rpc - The Solana RPC client used to fetch token accounts and multiple accounts.\n * @param {Address} owner - The wallet address whose positions you want to fetch.\n * @returns {Promise<PositionData[]>} - A promise that resolves to an array of decoded position data for the given owner.\n *\n * @example\n * import { fetchPositionsForOwner } from '@orca-so/whirlpools';\n * import { generateKeyPairSigner, createSolanaRpc, devnet } from '@solana/kit';\n *\n * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));\n * const wallet = address(\"INSERT_WALLET_ADDRESS\");\n *\n * const positions = await fetchPositionsForOwner(devnetRpc, wallet.address);\n */\nexport async function fetchPositionsForOwner(\n  rpc: Rpc<GetTokenAccountsByOwnerApi & GetMultipleAccountsApi>,\n  owner: Address,\n): Promise<PositionData[]> {\n  const [tokenAccounts, token2022Accounts] = await Promise.all([\n    rpc\n      .getTokenAccountsByOwner(\n        owner,\n        { programId: TOKEN_PROGRAM_ADDRESS },\n        { encoding: \"base64\" },\n      )\n      .send(),\n    rpc\n      .getTokenAccountsByOwner(\n        owner,\n        { programId: TOKEN_2022_PROGRAM_ADDRESS },\n        { encoding: \"base64\" },\n      )\n      .send(),\n  ]);\n\n  const encoder = getBase64Encoder();\n  const decoder = getTokenDecoder();\n\n  const potentialTokens = [...tokenAccounts.value, ...token2022Accounts.value]\n    .map((x) => ({\n      ...decoder.decode(encoder.encode(x.account.data[0])),\n      tokenProgram: x.account.owner,\n    }))\n    .filter((x) => x.amount === 1n);\n\n  const positionAddresses = await Promise.all(\n    potentialTokens.map((x) => getPositionAddress(x.mint).then((x) => x[0])),\n  );\n\n  const positionBundleAddresses = await Promise.all(\n    potentialTokens.map((x) =>\n      getPositionBundleAddress(x.mint).then((x) => x[0]),\n    ),\n  );\n\n  const positions = await fetchMultipleAccountsBatched(\n    rpc,\n    positionAddresses,\n    decodePosition,\n  );\n\n  const positionBundles = await fetchMultipleAccountsBatched(\n    rpc,\n    positionBundleAddresses,\n    decodePositionBundle,\n  );\n\n  const bundledPositionAddresses = await Promise.all(\n    positionBundles\n      .filter((x) => x.exists)\n      .flatMap((x) => getPositionInBundleAddresses(x.data)),\n  );\n\n  const bundledPositions = (\n    await fetchMultipleAccountsBatched(\n      rpc,\n      bundledPositionAddresses,\n      decodePosition,\n    )\n  )\n    .filter((x) => x.exists)\n    .map((x) => {\n      assertAccountExists(x);\n      return x;\n    });\n\n  const bundledPositionMap = bundledPositions.reduce((acc, x) => {\n    const current = acc.get(x.data.positionMint) ?? [];\n    return acc.set(x.data.positionMint, [...current, x]);\n  }, new Map<Address, Account<Position>[]>());\n\n  const positionsOrBundles: PositionData[] = [];\n\n  for (let i = 0; i < potentialTokens.length; i++) {\n    const position = positions[i];\n    const positionBundle = positionBundles[i];\n    const token = potentialTokens[i];\n\n    if (position.exists) {\n      positionsOrBundles.push({\n        ...position,\n        tokenProgram: token.tokenProgram,\n        isPositionBundle: false,\n      });\n    }\n\n    if (positionBundle.exists) {\n      const positions =\n        bundledPositionMap.get(positionBundle.data.positionBundleMint) ?? [];\n      positionsOrBundles.push({\n        ...positionBundle,\n        positions,\n        tokenProgram: token.tokenProgram,\n        isPositionBundle: true,\n      });\n    }\n  }\n\n  return positionsOrBundles;\n}\n\n/**\n * Fetches all positions for a given Whirlpool.\n *\n * @param {SolanaRpc} rpc - The Solana RPC client used to fetch positions.\n * @param {Address} whirlpool - The address of the Whirlpool.\n * @returns {Promise<HydratedPosition[]>} - A promise that resolves to an array of hydrated positions.\n *\n * @example\n * import { fetchPositionsInWhirlpool } from '@orca-so/whirlpools';\n * import { createSolanaRpc, devnet, address } from '@solana/kit';\n *\n * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));\n *\n * const whirlpool = address(\"Czfq3xZZDmsdGdUyrNLtRhGc47cXcZtLG4crryfu44zE\");\n * const positions = await fetchPositionsInWhirlpool(devnetRpc, whirlpool);\n */\nexport async function fetchPositionsInWhirlpool(\n  rpc: Rpc<GetProgramAccountsApi>,\n  whirlpool: Address,\n): Promise<HydratedPosition[]> {\n  const positions = await fetchAllPositionWithFilter(\n    rpc,\n    positionWhirlpoolFilter(whirlpool),\n  );\n  return positions.map((x) => ({\n    ...x,\n    isPositionBundle: false,\n  }));\n}\n","import {\n  fetchEncodedAccounts,\n  type Address,\n  type GetMultipleAccountsApi,\n  type MaybeAccount,\n  type MaybeEncodedAccount,\n  type Rpc,\n} from \"@solana/kit\";\n\nconst MAX_CHUNK_SIZE = 100;\n\nexport async function fetchMultipleAccountsBatched<T extends object>(\n  rpc: Rpc<GetMultipleAccountsApi>,\n  addresses: Address[],\n  decoder: (account: MaybeEncodedAccount) => MaybeAccount<T>,\n): Promise<MaybeAccount<T>[]> {\n  const numChunks = Math.ceil(addresses.length / MAX_CHUNK_SIZE);\n  const chunks = [...Array(numChunks).keys()].map((i) =>\n    addresses.slice(i * MAX_CHUNK_SIZE, (i + 1) * MAX_CHUNK_SIZE),\n  );\n\n  const results: MaybeAccount<T>[] = [];\n  for (const chunk of chunks) {\n    const chunkResult = await fetchEncodedAccounts(rpc, chunk);\n    chunkResult.forEach((account, _) => {\n      const data = decoder(account);\n      results.push(data);\n    });\n  }\n  return results;\n}\n","import type { Whirlpool } from \"@orca-so/whirlpools-client\";\nimport {\n  fetchAllMaybeTickArray,\n  fetchPosition,\n  fetchWhirlpool,\n  getIncreaseLiquidityV2Instruction,\n  getInitializeDynamicTickArrayInstruction,\n  getOpenPositionWithTokenExtensionsInstruction,\n  getPositionAddress,\n  getTickArrayAddress,\n  getDynamicTickArrayMinSize,\n} from \"@orca-so/whirlpools-client\";\nimport type {\n  IncreaseLiquidityQuote,\n  TransferFee,\n} from \"@orca-so/whirlpools-core\";\nimport {\n  _MAX_TICK_INDEX,\n  _MIN_TICK_INDEX,\n  getFullRangeTickIndexes,\n  getTickArrayStartTickIndex,\n  increaseLiquidityQuote,\n  increaseLiquidityQuoteA,\n  increaseLiquidityQuoteB,\n  priceToTickIndex,\n  getInitializableTickIndex,\n  orderTickIndexes,\n} from \"@orca-so/whirlpools-core\";\nimport type {\n  Account,\n  Address,\n  GetAccountInfoApi,\n  GetEpochInfoApi,\n  GetMinimumBalanceForRentExemptionApi,\n  GetMultipleAccountsApi,\n  IInstruction,\n  Lamports,\n  Rpc,\n  TransactionSigner,\n} from \"@solana/kit\";\nimport { address, generateKeyPairSigner, lamports } from \"@solana/kit\";\nimport { fetchSysvarRent } from \"@solana/sysvars\";\nimport {\n  DEFAULT_ADDRESS,\n  FUNDER,\n  SLIPPAGE_TOLERANCE_BPS,\n  SPLASH_POOL_TICK_SPACING,\n} from \"./config\";\nimport {\n  ASSOCIATED_TOKEN_PROGRAM_ADDRESS,\n  findAssociatedTokenPda,\n} from \"@solana-program/token\";\nimport {\n  getCurrentTransferFee,\n  prepareTokenAccountsInstructions,\n} from \"./token\";\nimport type { Mint } from \"@solana-program/token-2022\";\nimport {\n  fetchAllMint,\n  TOKEN_2022_PROGRAM_ADDRESS,\n} from \"@solana-program/token-2022\";\nimport { MEMO_PROGRAM_ADDRESS } from \"@solana-program/memo\";\nimport assert from \"assert\";\nimport { calculateMinimumBalanceForRentExemption } from \"./sysvar\";\nimport { wrapFunctionWithExecution } from \"./actionHelpers\";\n\n// TODO: allow specify number as well as bigint\n// TODO: transfer hook\n\n/**\n * Represents the parameters for increasing liquidity.\n * You must choose only one of the properties (`liquidity`, `tokenA`, or `tokenB`).\n * The SDK will compute the other two based on the input provided.\n */\nexport type IncreaseLiquidityQuoteParam =\n  | {\n      /** The amount of liquidity to increase. */\n      liquidity: bigint;\n    }\n  | {\n      /** The amount of Token A to add. */\n      tokenA: bigint;\n    }\n  | {\n      /** The amount of Token B to add. */\n      tokenB: bigint;\n    };\n\n/**\n * Represents the instructions and quote for increasing liquidity in a position.\n */\nexport type IncreaseLiquidityInstructions = {\n  /** The quote object with details about the increase in liquidity, including the liquidity delta, estimated tokens, and maximum token amounts based on slippage tolerance. */\n  quote: IncreaseLiquidityQuote;\n\n  /** List of Solana transaction instructions to execute. */\n  instructions: IInstruction[];\n};\n\nfunction getIncreaseLiquidityQuote(\n  param: IncreaseLiquidityQuoteParam,\n  pool: Whirlpool,\n  tickLowerIndex: number,\n  tickUpperIndex: number,\n  slippageToleranceBps: number,\n  transferFeeA: TransferFee | undefined,\n  transferFeeB: TransferFee | undefined,\n): IncreaseLiquidityQuote {\n  if (\"liquidity\" in param) {\n    return increaseLiquidityQuote(\n      param.liquidity,\n      slippageToleranceBps,\n      pool.sqrtPrice,\n      tickLowerIndex,\n      tickUpperIndex,\n      transferFeeA,\n      transferFeeB,\n    );\n  } else if (\"tokenA\" in param) {\n    return increaseLiquidityQuoteA(\n      param.tokenA,\n      slippageToleranceBps,\n      pool.sqrtPrice,\n      tickLowerIndex,\n      tickUpperIndex,\n      transferFeeA,\n      transferFeeB,\n    );\n  } else {\n    return increaseLiquidityQuoteB(\n      param.tokenB,\n      slippageToleranceBps,\n      pool.sqrtPrice,\n      tickLowerIndex,\n      tickUpperIndex,\n      transferFeeA,\n      transferFeeB,\n    );\n  }\n}\n\n/**\n * Generates instructions to increase liquidity for an existing position.\n *\n * @param {SolanaRpc} rpc - The Solana RPC client.\n * @param {Address} positionMintAddress - The mint address of the NFT that represents the position.\n * @param {IncreaseLiquidityQuoteParam} param - The parameters for adding liquidity. Can specify liquidity, Token A, or Token B amounts.\n * @param {number} [slippageToleranceBps=SLIPPAGE_TOLERANCE_BPS] - The maximum acceptable slippage, in basis points (BPS).\n * @param {TransactionSigner} [authority=FUNDER] - The account that authorizes the transaction.\n * @returns {Promise<IncreaseLiquidityInstructions>} A promise that resolves to an object containing instructions, quote, position mint address, and initialization costs for increasing liquidity.\n *\n * @example\n * import { increaseLiquidityInstructions, setWhirlpoolsConfig } from '@orca-so/whirlpools';\n * import { createSolanaRpc, devnet, address } from '@solana/kit';\n * import { loadWallet } from './utils';\n *\n * await setWhirlpoolsConfig('solanaDevnet');\n * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));\n * const wallet = await loadWallet();\n * const positionMint = address(\"HqoV7Qv27REUtmd9UKSJGGmCRNx3531t33bDG1BUfo9K\");\n * const param = { tokenA: 10n };\n * const { quote, instructions } = await increaseLiquidityInstructions(\n *   devnetRpc,\n *   positionMint,\n *   param,\n *   100,\n *   wallet\n * );\n *\n * console.log(`Quote token max B: ${quote.tokenEstB}`);\n */\nexport async function increaseLiquidityInstructions(\n  rpc: Rpc<\n    GetAccountInfoApi &\n      GetMultipleAccountsApi &\n      GetMinimumBalanceForRentExemptionApi &\n      GetEpochInfoApi\n  >,\n  positionMintAddress: Address,\n  param: IncreaseLiquidityQuoteParam,\n  slippageToleranceBps: number = SLIPPAGE_TOLERANCE_BPS,\n  authority: TransactionSigner = FUNDER,\n): Promise<IncreaseLiquidityInstructions> {\n  assert(\n    authority.address !== DEFAULT_ADDRESS,\n    \"Either supply the authority or set the default funder\",\n  );\n\n  const positionAddress = await getPositionAddress(positionMintAddress);\n  const position = await fetchPosition(rpc, positionAddress[0]);\n  const whirlpool = await fetchWhirlpool(rpc, position.data.whirlpool);\n\n  const currentEpoch = await rpc.getEpochInfo().send();\n  const [mintA, mintB, positionMint] = await fetchAllMint(rpc, [\n    whirlpool.data.tokenMintA,\n    whirlpool.data.tokenMintB,\n    positionMintAddress,\n  ]);\n  const transferFeeA = getCurrentTransferFee(mintA, currentEpoch.epoch);\n  const transferFeeB = getCurrentTransferFee(mintB, currentEpoch.epoch);\n\n  const quote = getIncreaseLiquidityQuote(\n    param,\n    whirlpool.data,\n    position.data.tickLowerIndex,\n    position.data.tickUpperIndex,\n    slippageToleranceBps,\n    transferFeeA,\n    transferFeeB,\n  );\n  const instructions: IInstruction[] = [];\n\n  const lowerTickArrayStartIndex = getTickArrayStartTickIndex(\n    position.data.tickLowerIndex,\n    whirlpool.data.tickSpacing,\n  );\n  const upperTickArrayStartIndex = getTickArrayStartTickIndex(\n    position.data.tickUpperIndex,\n    whirlpool.data.tickSpacing,\n  );\n\n  const [positionTokenAccount, tickArrayLower, tickArrayUpper] =\n    await Promise.all([\n      findAssociatedTokenPda({\n        owner: authority.address,\n        mint: positionMintAddress,\n        tokenProgram: positionMint.programAddress,\n      }).then((x) => x[0]),\n      getTickArrayAddress(whirlpool.address, lowerTickArrayStartIndex).then(\n        (x) => x[0],\n      ),\n      getTickArrayAddress(whirlpool.address, upperTickArrayStartIndex).then(\n        (x) => x[0],\n      ),\n    ]);\n\n  const { createInstructions, cleanupInstructions, tokenAccountAddresses } =\n    await prepareTokenAccountsInstructions(rpc, authority, {\n      [whirlpool.data.tokenMintA]: quote.tokenMaxA,\n      [whirlpool.data.tokenMintB]: quote.tokenMaxB,\n    });\n\n  instructions.push(...createInstructions);\n\n  // Since position exists tick arrays must also already exist\n\n  instructions.push(\n    getIncreaseLiquidityV2Instruction({\n      whirlpool: whirlpool.address,\n      positionAuthority: authority,\n      position: position.address,\n      positionTokenAccount,\n      tokenOwnerAccountA: tokenAccountAddresses[whirlpool.data.tokenMintA],\n      tokenOwnerAccountB: tokenAccountAddresses[whirlpool.data.tokenMintB],\n      tokenVaultA: whirlpool.data.tokenVaultA,\n      tokenVaultB: whirlpool.data.tokenVaultB,\n      tokenMintA: whirlpool.data.tokenMintA,\n      tokenMintB: whirlpool.data.tokenMintB,\n      tokenProgramA: mintA.programAddress,\n      tokenProgramB: mintB.programAddress,\n      tickArrayLower,\n      tickArrayUpper,\n      liquidityAmount: quote.liquidityDelta,\n      tokenMaxA: quote.tokenMaxA,\n      tokenMaxB: quote.tokenMaxB,\n      memoProgram: MEMO_PROGRAM_ADDRESS,\n      remainingAccountsInfo: null,\n    }),\n  );\n\n  instructions.push(...cleanupInstructions);\n\n  return {\n    quote,\n    instructions,\n  };\n}\n\n/**\n * Represents the instructions and quote for opening a position.\n * Extends IncreaseLiquidityInstructions with additional fields for position initialization.\n */\nexport type OpenPositionInstructions = IncreaseLiquidityInstructions & {\n  /** The initialization cost for opening the position in lamports. */\n  initializationCost: Lamports;\n\n  /** The mint address of the position NFT. */\n  positionMint: Address;\n};\n\nasync function internalOpenPositionInstructions(\n  rpc: Rpc<\n    GetAccountInfoApi &\n      GetMultipleAccountsApi &\n      GetMinimumBalanceForRentExemptionApi &\n      GetEpochInfoApi\n  >,\n  whirlpool: Account<Whirlpool>,\n  param: IncreaseLiquidityQuoteParam,\n  lowerTickIndex: number,\n  upperTickIndex: number,\n  mintA: Account<Mint>,\n  mintB: Account<Mint>,\n  slippageToleranceBps: number = SLIPPAGE_TOLERANCE_BPS,\n  funder: TransactionSigner = FUNDER,\n): Promise<OpenPositionInstructions> {\n  assert(\n    funder.address !== DEFAULT_ADDRESS,\n    \"Either supply a funder or set the default funder\",\n  );\n  const instructions: IInstruction[] = [];\n\n  const rent = await fetchSysvarRent(rpc);\n  let nonRefundableRent: bigint = 0n;\n\n  const tickRange = orderTickIndexes(lowerTickIndex, upperTickIndex);\n\n  const initializableLowerTickIndex = getInitializableTickIndex(\n    tickRange.tickLowerIndex,\n    whirlpool.data.tickSpacing,\n    false,\n  );\n  const initializableUpperTickIndex = getInitializableTickIndex(\n    tickRange.tickUpperIndex,\n    whirlpool.data.tickSpacing,\n    true,\n  );\n\n  const currentEpoch = await rpc.getEpochInfo().send();\n  const transferFeeA = getCurrentTransferFee(mintA, currentEpoch.epoch);\n  const transferFeeB = getCurrentTransferFee(mintB, currentEpoch.epoch);\n\n  const quote = getIncreaseLiquidityQuote(\n    param,\n    whirlpool.data,\n    initializableLowerTickIndex,\n    initializableUpperTickIndex,\n    slippageToleranceBps,\n    transferFeeA,\n    transferFeeB,\n  );\n\n  const positionMint = await generateKeyPairSigner();\n\n  const lowerTickArrayIndex = getTickArrayStartTickIndex(\n    initializableLowerTickIndex,\n    whirlpool.data.tickSpacing,\n  );\n  const upperTickArrayIndex = getTickArrayStartTickIndex(\n    initializableUpperTickIndex,\n    whirlpool.data.tickSpacing,\n  );\n\n  const [\n    positionAddress,\n    positionTokenAccount,\n    lowerTickArrayAddress,\n    upperTickArrayAddress,\n  ] = await Promise.all([\n    getPositionAddress(positionMint.address),\n    findAssociatedTokenPda({\n      owner: funder.address,\n      mint: positionMint.address,\n      tokenProgram: TOKEN_2022_PROGRAM_ADDRESS,\n    }).then((x) => x[0]),\n    getTickArrayAddress(whirlpool.address, lowerTickArrayIndex).then(\n      (x) => x[0],\n    ),\n    getTickArrayAddress(whirlpool.address, upperTickArrayIndex).then(\n      (x) => x[0],\n    ),\n  ]);\n\n  const { createInstructions, cleanupInstructions, tokenAccountAddresses } =\n    await prepareTokenAccountsInstructions(rpc, funder, {\n      [whirlpool.data.tokenMintA]: quote.tokenMaxA,\n      [whirlpool.data.tokenMintB]: quote.tokenMaxB,\n    });\n\n  instructions.push(...createInstructions);\n\n  const [lowerTickArray, upperTickArray] = await fetchAllMaybeTickArray(rpc, [\n    lowerTickArrayAddress,\n    upperTickArrayAddress,\n  ]);\n\n  if (!lowerTickArray.exists) {\n    instructions.push(\n      getInitializeDynamicTickArrayInstruction({\n        whirlpool: whirlpool.address,\n        funder,\n        tickArray: lowerTickArrayAddress,\n        startTickIndex: lowerTickArrayIndex,\n        idempotent: false,\n      }),\n    );\n    nonRefundableRent += calculateMinimumBalanceForRentExemption(\n      rent,\n      getDynamicTickArrayMinSize(),\n    );\n  }\n\n  if (!upperTickArray.exists && lowerTickArrayIndex !== upperTickArrayIndex) {\n    instructions.push(\n      getInitializeDynamicTickArrayInstruction({\n        whirlpool: whirlpool.address,\n        funder,\n        tickArray: upperTickArrayAddress,\n        startTickIndex: upperTickArrayIndex,\n        idempotent: false,\n      }),\n    );\n    nonRefundableRent += calculateMinimumBalanceForRentExemption(\n      rent,\n      getDynamicTickArrayMinSize(),\n    );\n  }\n\n  instructions.push(\n    getOpenPositionWithTokenExtensionsInstruction({\n      funder,\n      owner: funder.address,\n      position: positionAddress[0],\n      positionMint,\n      positionTokenAccount,\n      whirlpool: whirlpool.address,\n      associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ADDRESS,\n      tickLowerIndex: initializableLowerTickIndex,\n      tickUpperIndex: initializableUpperTickIndex,\n      token2022Program: TOKEN_2022_PROGRAM_ADDRESS,\n      metadataUpdateAuth: address(\n        \"3axbTs2z5GBy6usVbNVoqEgZMng3vZvMnAoX29BFfwhr\",\n      ),\n      withTokenMetadataExtension: true,\n    }),\n  );\n\n  instructions.push(\n    getIncreaseLiquidityV2Instruction({\n      whirlpool: whirlpool.address,\n      positionAuthority: funder,\n      position: positionAddress[0],\n      positionTokenAccount,\n      tokenOwnerAccountA: tokenAccountAddresses[whirlpool.data.tokenMintA],\n      tokenOwnerAccountB: tokenAccountAddresses[whirlpool.data.tokenMintB],\n      tokenVaultA: whirlpool.data.tokenVaultA,\n      tokenVaultB: whirlpool.data.tokenVaultB,\n      tokenMintA: whirlpool.data.tokenMintA,\n      tokenMintB: whirlpool.data.tokenMintB,\n      tokenProgramA: mintA.programAddress,\n      tokenProgramB: mintB.programAddress,\n      tickArrayLower: lowerTickArrayAddress,\n      tickArrayUpper: upperTickArrayAddress,\n      liquidityAmount: quote.liquidityDelta,\n      tokenMaxA: quote.tokenMaxA,\n      tokenMaxB: quote.tokenMaxB,\n      memoProgram: MEMO_PROGRAM_ADDRESS,\n      remainingAccountsInfo: null,\n    }),\n  );\n\n  instructions.push(...cleanupInstructions);\n\n  return {\n    instructions,\n    quote,\n    positionMint: positionMint.address,\n    initializationCost: lamports(nonRefundableRent),\n  };\n}\n\n/**\n * Opens a full-range position for a pool, typically used for Splash Pools or other full-range liquidity provisioning.\n *\n * @param {SolanaRpc} rpc - The Solana RPC client.\n * @param {Address} poolAddress - The address of the liquidity pool.\n * @param {IncreaseLiquidityQuoteParam} param - The parameters for adding liquidity, where one of `liquidity`, `tokenA`, or `tokenB` must be specified. The SDK will compute the others.\n * @param {number} [slippageToleranceBps=SLIPPAGE_TOLERANCE_BPS] - The maximum acceptable slippage, in basis points (BPS).\n * @param {TransactionSigner} [funder=FUNDER] - The account funding the transaction.\n * @returns {Promise<OpenPositionInstructions>} A promise that resolves to an object containing the instructions, quote, position mint address, and initialization costs for increasing liquidity.\n *\n * @example\n * import { openFullRangePositionInstructions, setWhirlpoolsConfig } from '@orca-so/whirlpools';\n * import { generateKeyPairSigner, createSolanaRpc, devnet, address } from '@solana/kit';\n *\n * await setWhirlpoolsConfig('solanaDevnet');\n * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));\n * const wallet = await generateKeyPairSigner(); // CAUTION: This wallet is not persistent.\n *\n * const whirlpoolAddress = address(\"POOL_ADDRESS\");\n *\n * const param = { tokenA: 1_000_000n };\n *\n * const { quote, instructions, initializationCost, positionMint } = await openFullRangePositionInstructions(\n *   devnetRpc,\n *   whirlpoolAddress,\n *   param,\n *   100,\n *   wallet\n * );\n */\nexport async function openFullRangePositionInstructions(\n  rpc: Rpc<\n    GetAccountInfoApi &\n      GetMultipleAccountsApi &\n      GetMinimumBalanceForRentExemptionApi &\n      GetEpochInfoApi\n  >,\n  poolAddress: Address,\n  param: IncreaseLiquidityQuoteParam,\n  slippageToleranceBps: number = SLIPPAGE_TOLERANCE_BPS,\n  funder: TransactionSigner = FUNDER,\n): Promise<OpenPositionInstructions> {\n  const whirlpool = await fetchWhirlpool(rpc, poolAddress);\n  const tickRange = getFullRangeTickIndexes(whirlpool.data.tickSpacing);\n  const [mintA, mintB] = await fetchAllMint(rpc, [\n    whirlpool.data.tokenMintA,\n    whirlpool.data.tokenMintB,\n  ]);\n  return internalOpenPositionInstructions(\n    rpc,\n    whirlpool,\n    param,\n    tickRange.tickLowerIndex,\n    tickRange.tickUpperIndex,\n    mintA,\n    mintB,\n    slippageToleranceBps,\n    funder,\n  );\n}\n\n/**\n * Opens a new position in a concentrated liquidity pool within a specific price range.\n * This function allows you to provide liquidity for the specified range of prices and adjust liquidity parameters accordingly.\n *\n * **Note:** This function cannot be used with Splash Pools.\n *\n * @param {SolanaRpc} rpc - A Solana RPC client used to interact with the blockchain.\n * @param {Address} poolAddress - The address of the liquidity pool where the position will be opened.\n * @param {IncreaseLiquidityQuoteParam} param - The parameters for increasing liquidity, where you must choose one (`liquidity`, `tokenA`, or `tokenB`). The SDK will compute the other two.\n * @param {number} lowerPrice - The lower bound of the price range for the position.\n * @param {number} upperPrice - The upper bound of the price range for the position.\n * @param {number} [slippageToleranceBps=SLIPPAGE_TOLERANCE_BPS] - The slippage tolerance for adding liquidity, in basis points (BPS).\n * @param {TransactionSigner} [funder=FUNDER] - The account funding the transaction.\n *\n * @returns {Promise<OpenPositionInstructions>} A promise that resolves to an object containing instructions, quote, position mint address, and initialization costs for increasing liquidity.\n *\n * @example\n * import { openPositionInstructions, setWhirlpoolsConfig } from '@orca-so/whirlpools';\n * import { generateKeyPairSigner, createSolanaRpc, devnet, address } from '@solana/kit';\n *\n * await setWhirlpoolsConfig('solanaDevnet');\n * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));\n * const wallet = await generateKeyPairSigner(); // CAUTION: This wallet is not persistent.\n *\n * const whirlpoolAddress = address(\"POOL_ADDRESS\");\n *\n * const param = { tokenA: 1_000_000n };\n * const lowerPrice = 0.00005;\n * const upperPrice = 0.00015;\n *\n * const { quote, instructions, initializationCost, positionMint } = await openPositionInstructions(\n *   devnetRpc,\n *   whirlpoolAddress,\n *   param,\n *   lowerPrice,\n *   upperPrice,\n *   100,\n *   wallet\n * );\n */\nexport async function openPositionInstructions(\n  rpc: Rpc<\n    GetAccountInfoApi &\n      GetMultipleAccountsApi &\n      GetMinimumBalanceForRentExemptionApi &\n      GetEpochInfoApi\n  >,\n  poolAddress: Address,\n  param: IncreaseLiquidityQuoteParam,\n  lowerPrice: number,\n  upperPrice: number,\n  slippageToleranceBps: number = SLIPPAGE_TOLERANCE_BPS,\n  funder: TransactionSigner = FUNDER,\n): Promise<OpenPositionInstructions> {\n  const whirlpool = await fetchWhirlpool(rpc, poolAddress);\n  assert(\n    whirlpool.data.tickSpacing !== SPLASH_POOL_TICK_SPACING,\n    \"Splash pools only support full range positions\",\n  );\n  const [mintA, mintB] = await fetchAllMint(rpc, [\n    whirlpool.data.tokenMintA,\n    whirlpool.data.tokenMintB,\n  ]);\n  const decimalsA = mintA.data.decimals;\n  const decimalsB = mintB.data.decimals;\n  const lowerTickIndex = priceToTickIndex(lowerPrice, decimalsA, decimalsB);\n  const upperTickIndex = priceToTickIndex(upperPrice, decimalsA, decimalsB);\n  return internalOpenPositionInstructions(\n    rpc,\n    whirlpool,\n    param,\n    lowerTickIndex,\n    upperTickIndex,\n    mintA,\n    mintB,\n    slippageToleranceBps,\n    funder,\n  );\n}\n\n// -------- ACTIONS --------\n\nexport const increasePosLiquidity = wrapFunctionWithExecution(\n  increaseLiquidityInstructions,\n);\n\nexport const openFullRangePosition = wrapFunctionWithExecution(\n  openFullRangePositionInstructions,\n);\n\nexport const openConcentratedPosition = wrapFunctionWithExecution(\n  openPositionInstructions,\n);\n","import type { Whirlpool } from \"@orca-so/whirlpools-client\";\nimport {\n  getFeeTierAddress,\n  getWhirlpoolAddress,\n  fetchWhirlpoolsConfig,\n  fetchFeeTier,\n  fetchMaybeWhirlpool,\n  fetchAllMaybeWhirlpool,\n  fetchAllFeeTierWithFilter,\n  feeTierWhirlpoolsConfigFilter,\n} from \"@orca-so/whirlpools-client\";\nimport type {\n  Rpc,\n  GetAccountInfoApi,\n  GetMultipleAccountsApi,\n  Address,\n  GetProgramAccountsApi,\n} from \"@solana/kit\";\nimport { SPLASH_POOL_TICK_SPACING, WHIRLPOOLS_CONFIG_ADDRESS } from \"./config\";\nimport { orderMints } from \"./token\";\nimport { sqrtPriceToPrice } from \"@orca-so/whirlpools-core\";\nimport { fetchAllMint } from \"@solana-program/token\";\n\n/**\n * Type representing a pool that is not yet initialized.\n */\nexport type InitializablePool = {\n  /** Indicates the pool is not initialized. */\n  initialized: false;\n} & Pick<\n  Whirlpool,\n  | \"whirlpoolsConfig\"\n  | \"tickSpacing\"\n  | \"feeRate\"\n  | \"protocolFeeRate\"\n  | \"tokenMintA\"\n  | \"tokenMintB\"\n>;\n\n/**\n * Type representing a pool that has been initialized.\n * Extends the `Whirlpool` type, inheriting all its properties.\n */\nexport type InitializedPool = {\n  /** Indicates the pool is initialized. */\n  initialized: true;\n  price: number;\n} & Whirlpool;\n\n/**\n * Combined type representing both initialized and uninitialized pools.\n */\nexport type PoolInfo = (InitializablePool | InitializedPool) & {\n  /** The address of the pool. */\n  address: Address;\n};\n\n/**\n * Fetches the details of a specific Splash Pool.\n *\n * @param {SolanaRpc} rpc - The Solana RPC client.\n * @param {Address} tokenMintOne - The first token mint address in the pool.\n * @param {Address} tokenMintTwo - The second token mint address in the pool.\n * @returns {Promise<PoolInfo>} - A promise that resolves to the pool information, which includes whether the pool is initialized or not.\n *\n * @example\n * import { fetchSplashPool, setWhirlpoolsConfig } from '@orca-so/whirlpools';\n * import { createSolanaRpc, devnet, address } from '@solana/kit';\n *\n * await setWhirlpoolsConfig('solanaDevnet');\n * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));\n * const tokenMintOne = address(\"So11111111111111111111111111111111111111112\");\n * const tokenMintTwo = address(\"BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k\"); //devUSDC\n *\n * const poolInfo = await fetchSplashPool(\n *   devnetRpc,\n *   tokenMintOne,\n *   tokenMintTwo\n * );\n *\n * if (poolInfo.initialized) {\n *   console.log(\"Pool is initialized:\", poolInfo);\n * } else {\n *   console.log(\"Pool is not initialized:\", poolInfo);\n * };\n */\nexport async function fetchSplashPool(\n  rpc: Rpc<GetAccountInfoApi & GetMultipleAccountsApi>,\n  tokenMintOne: Address,\n  tokenMintTwo: Address,\n): Promise<PoolInfo> {\n  return fetchConcentratedLiquidityPool(\n    rpc,\n    tokenMintOne,\n    tokenMintTwo,\n    SPLASH_POOL_TICK_SPACING,\n  );\n}\n\n/**\n * Fetches the details of a specific Concentrated Liquidity Pool.\n *\n * @param {SolanaRpc} rpc - The Solana RPC client.\n * @param {Address} tokenMintOne - The first token mint address in the pool.\n * @param {Address} tokenMintTwo - The second token mint address in the pool.\n * @param {number} tickSpacing - The tick spacing of the pool.\n * @returns {Promise<PoolInfo>} - A promise that resolves to the pool information, which includes whether the pool is initialized or not.\n *\n * @example\n * import { fetchConcentratedLiquidityPool, setWhirlpoolsConfig } from '@orca-so/whirlpools';\n * import { createSolanaRpc, devnet, address } from '@solana/kit';\n *\n * await setWhirlpoolsConfig('solanaDevnet');\n * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));\n *\n * const tokenMintOne = address(\"So11111111111111111111111111111111111111112\");\n * const tokenMintTwo = address(\"BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k\");\n * const tickSpacing = 64;\n *\n * const poolInfo = await fetchConcentratedLiquidityPool(\n *   devnetRpc,\n *   tokenMintOne,\n *   tokenMintTwo,\n *   tickSpacing\n * );\n *\n * if (poolInfo.initialized) {\n *   console.log(\"Pool is initialized:\", poolInfo);\n * } else {\n *   console.log(\"Pool is not initialized:\", poolInfo);\n * };\n */\nexport async function fetchConcentratedLiquidityPool(\n  rpc: Rpc<GetAccountInfoApi & GetMultipleAccountsApi>,\n  tokenMintOne: Address,\n  tokenMintTwo: Address,\n  tickSpacing: number,\n): Promise<PoolInfo> {\n  const [tokenMintA, tokenMintB] = orderMints(tokenMintOne, tokenMintTwo);\n  const feeTierAddress = await getFeeTierAddress(\n    WHIRLPOOLS_CONFIG_ADDRESS,\n    tickSpacing,\n  ).then((x) => x[0]);\n  const poolAddress = await getWhirlpoolAddress(\n    WHIRLPOOLS_CONFIG_ADDRESS,\n    tokenMintA,\n    tokenMintB,\n    tickSpacing,\n  ).then((x) => x[0]);\n\n  // TODO: this is multiple rpc calls. Can we do it in one?\n  const [configAccount, feeTierAccount, poolAccount] = await Promise.all([\n    fetchWhirlpoolsConfig(rpc, WHIRLPOOLS_CONFIG_ADDRESS),\n    fetchFeeTier(rpc, feeTierAddress),\n    fetchMaybeWhirlpool(rpc, poolAddress),\n  ]);\n\n  const [mintA, mintB] = await fetchAllMint(rpc, [tokenMintA, tokenMintB]);\n\n  if (poolAccount.exists) {\n    const poolPrice = sqrtPriceToPrice(\n      poolAccount.data.sqrtPrice,\n      mintA.data.decimals,\n      mintB.data.decimals,\n    );\n    return {\n      initialized: true,\n      address: poolAddress,\n      price: poolPrice,\n      ...poolAccount.data,\n    };\n  } else {\n    return {\n      initialized: false,\n      address: poolAddress,\n      whirlpoolsConfig: WHIRLPOOLS_CONFIG_ADDRESS,\n      tickSpacing,\n      feeRate: feeTierAccount.data.defaultFeeRate,\n      protocolFeeRate: configAccount.data.defaultProtocolFeeRate,\n      tokenMintA: tokenMintA,\n      tokenMintB: tokenMintB,\n    };\n  }\n}\n\n/**\n * Fetches all possible liquidity pools between two token mints in Orca Whirlpools.\n * If a pool does not exist, it creates a placeholder account for the uninitialized pool with default data\n *\n * @param {SolanaRpc} rpc - The Solana RPC client.\n * @param {Address} tokenMintOne - The first token mint address in the pool.\n * @param {Address} tokenMintTwo - The second token mint address in the pool.\n * @returns {Promise<PoolInfo[]>} - A promise that resolves to an array of pool information for each pool between the two tokens.\n *\n * @example\n * import { fetchWhirlpoolsByTokenPair, setWhirlpoolsConfig } from '@orca-so/whirlpools';\n * import { createSolanaRpc, devnet, address } from '@solana/kit';\n *\n * await setWhirlpoolsConfig('solanaDevnet');\n * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));\n *\n * const tokenMintOne = address(\"So11111111111111111111111111111111111111112\");\n * const tokenMintTwo = address(\"BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k\");\n *\n * const poolInfos = await fetchWhirlpoolsByTokenPair(\n *   devnetRpc,\n *   tokenMintOne,\n *   tokenMintTwo\n * );\n *\n * poolInfos.forEach((poolInfo) => {\n *   if (poolInfo.initialized) {\n *     console.log(\"Pool is initialized:\", poolInfo);\n *   } else {\n *     console.log(\"Pool is not initialized:\", poolInfo);\n *   }\n * });\n */\nexport async function fetchWhirlpoolsByTokenPair(\n  rpc: Rpc<GetAccountInfoApi & GetMultipleAccountsApi & GetProgramAccountsApi>,\n  tokenMintOne: Address,\n  tokenMintTwo: Address,\n): Promise<PoolInfo[]> {\n  const [tokenMintA, tokenMintB] = orderMints(tokenMintOne, tokenMintTwo);\n  const feeTierAccounts = await fetchAllFeeTierWithFilter(\n    rpc,\n    feeTierWhirlpoolsConfigFilter(WHIRLPOOLS_CONFIG_ADDRESS),\n  );\n\n  const supportedTickSpacings = feeTierAccounts.map((x) => x.data.tickSpacing);\n\n  const poolAddresses = await Promise.all(\n    supportedTickSpacings.map((x) =>\n      getWhirlpoolAddress(\n        WHIRLPOOLS_CONFIG_ADDRESS,\n        tokenMintA,\n        tokenMintB,\n        x,\n      ).then((x) => x[0]),\n    ),\n  );\n\n  // TODO: this is multiple rpc calls. Can we do it in one?\n  const [configAccount, poolAccounts] = await Promise.all([\n    fetchWhirlpoolsConfig(rpc, WHIRLPOOLS_CONFIG_ADDRESS),\n    fetchAllMaybeWhirlpool(rpc, poolAddresses),\n  ]);\n\n  const [mintA, mintB] = await fetchAllMint(rpc, [tokenMintA, tokenMintB]);\n\n  const pools: PoolInfo[] = [];\n  for (let i = 0; i < supportedTickSpacings.length; i++) {\n    const tickSpacing = supportedTickSpacings[i];\n    const feeTierAccount = feeTierAccounts[i];\n    const poolAccount = poolAccounts[i];\n    const poolAddress = poolAddresses[i];\n\n    if (poolAccount.exists) {\n      const poolPrice = sqrtPriceToPrice(\n        poolAccount.data.sqrtPrice,\n        mintA.data.decimals,\n        mintB.data.decimals,\n      );\n      pools.push({\n        initialized: true,\n        address: poolAddress,\n        price: poolPrice,\n        ...poolAccount.data,\n      });\n    } else {\n      pools.push({\n        initialized: false,\n        address: poolAddress,\n        whirlpoolsConfig: WHIRLPOOLS_CONFIG_ADDRESS,\n        tickSpacing,\n        feeRate: feeTierAccount.data.defaultFeeRate,\n        protocolFeeRate: configAccount.data.defaultProtocolFeeRate,\n        tokenMintA,\n        tokenMintB,\n      });\n    }\n  }\n  return pools;\n}\n","import type {\n  Account,\n  Address,\n  GetAccountInfoApi,\n  GetEpochInfoApi,\n  GetMinimumBalanceForRentExemptionApi,\n  GetMultipleAccountsApi,\n  IInstruction,\n  Rpc,\n  TransactionSigner,\n} from \"@solana/kit\";\nimport { AccountRole, lamports } from \"@solana/kit\";\nimport { FUNDER, SLIPPAGE_TOLERANCE_BPS } from \"./config\";\nimport type {\n  ExactInSwapQuote,\n  ExactOutSwapQuote,\n  TickArrayFacade,\n  TransferFee,\n} from \"@orca-so/whirlpools-core\";\nimport {\n  _TICK_ARRAY_SIZE,\n  getTickArrayStartTickIndex,\n  swapQuoteByInputToken,\n  swapQuoteByOutputToken,\n} from \"@orca-so/whirlpools-core\";\nimport type { Whirlpool, Oracle } from \"@orca-so/whirlpools-client\";\nimport {\n  AccountsType,\n  fetchAllMaybeTickArray,\n  fetchWhirlpool,\n  fetchOracle,\n  getOracleAddress,\n  getSwapV2Instruction,\n  getTickArrayAddress,\n} from \"@orca-so/whirlpools-client\";\nimport {\n  getCurrentTransferFee,\n  prepareTokenAccountsInstructions,\n} from \"./token\";\nimport { MEMO_PROGRAM_ADDRESS } from \"@solana-program/memo\";\nimport { fetchAllMint } from \"@solana-program/token-2022\";\nimport { wrapFunctionWithExecution } from \"./actionHelpers\";\n\n// TODO: allow specify number as well as bigint\n// TODO: transfer hook\n\n/**\n * Parameters for an exact input swap.\n */\nexport type ExactInParams = {\n  /** The exact amount of input tokens to be swapped. */\n  inputAmount: bigint;\n};\n\n/**\n * Parameters for an exact output swap.\n */\nexport type ExactOutParams = {\n  /** The exact amount of output tokens to be received from the swap. */\n  outputAmount: bigint;\n};\n\n/**\n * Swap parameters, either for an exact input or exact output swap.\n */\nexport type SwapParams = (ExactInParams | ExactOutParams) & {\n  /** The mint address of the token being swapped. */\n  mint: Address;\n};\n\n/**\n * Swap quote that corresponds to the type of swap being executed (either input or output swap).\n *\n * @template T - The type of swap (input or output).\n */\nexport type SwapQuote<T extends SwapParams> = T extends ExactInParams\n  ? ExactInSwapQuote\n  : ExactOutSwapQuote;\n\n/**\n * Instructions and quote for executing a swap.\n *\n * @template T - The type of swap (input or output).\n */\nexport type SwapInstructions<T extends SwapParams> = {\n  /** The list of instructions needed to perform the swap. */\n  instructions: IInstruction[];\n\n  /** The swap quote, which includes information about the amounts involved in the swap. */\n  quote: SwapQuote<T>;\n\n  /** The timestamp when the trade was enabled. */\n  tradeEnableTimestamp: bigint;\n};\n\nfunction createUninitializedTickArray(\n  address: Address,\n  startTickIndex: number,\n  programAddress: Address,\n): Account<TickArrayFacade> {\n  return {\n    address,\n    data: {\n      startTickIndex,\n      ticks: Array(_TICK_ARRAY_SIZE()).fill({\n        initialized: false,\n        liquidityNet: 0n,\n        liquidityGross: 0n,\n        feeGrowthOutsideA: 0n,\n        feeGrowthOutsideB: 0n,\n        rewardGrowthsOutside: [0n, 0n, 0n],\n      }),\n    },\n    space: 0n,\n    executable: false,\n    lamports: lamports(0n),\n    programAddress,\n  };\n}\n\nasync function fetchTickArrayOrDefault(\n  rpc: Rpc<GetMultipleAccountsApi>,\n  whirlpool: Account<Whirlpool>,\n): Promise<Account<TickArrayFacade>[]> {\n  const tickArrayStartIndex = getTickArrayStartTickIndex(\n    whirlpool.data.tickCurrentIndex,\n    whirlpool.data.tickSpacing,\n  );\n  const offset = whirlpool.data.tickSpacing * _TICK_ARRAY_SIZE();\n\n  const tickArrayIndexes = [\n    tickArrayStartIndex,\n    tickArrayStartIndex + offset,\n    tickArrayStartIndex + offset * 2,\n    tickArrayStartIndex - offset,\n    tickArrayStartIndex - offset * 2,\n  ];\n\n  const tickArrayAddresses = await Promise.all(\n    tickArrayIndexes.map((startIndex) =>\n      getTickArrayAddress(whirlpool.address, startIndex).then((x) => x[0]),\n    ),\n  );\n\n  const maybeTickArrays = await fetchAllMaybeTickArray(rpc, tickArrayAddresses);\n\n  const tickArrays: Account<TickArrayFacade>[] = [];\n\n  for (let i = 0; i < maybeTickArrays.length; i++) {\n    const maybeTickArray = maybeTickArrays[i];\n    if (maybeTickArray.exists) {\n      tickArrays.push(maybeTickArray);\n    } else {\n      tickArrays.push(\n        createUninitializedTickArray(\n          tickArrayAddresses[i],\n          tickArrayIndexes[i],\n          whirlpool.programAddress,\n        ),\n      );\n    }\n  }\n\n  return tickArrays;\n}\n\nasync function getOracle(\n  rpc: Rpc<GetAccountInfoApi>,\n  oracleAddress: Address,\n  whirlpool: Whirlpool,\n): Promise<Oracle | undefined> {\n  // no need to fetch oracle for non-adaptive fee whirlpools\n  const feeTierIndex =\n    whirlpool.feeTierIndexSeed[0] + whirlpool.feeTierIndexSeed[1] * 256;\n  if (whirlpool.tickSpacing == feeTierIndex) {\n    return undefined;\n  }\n  return (await fetchOracle(rpc, oracleAddress)).data;\n}\n\nfunction getSwapQuote<T extends SwapParams>(\n  params: T,\n  whirlpool: Whirlpool,\n  transferFeeA: TransferFee | undefined,\n  transferFeeB: TransferFee | undefined,\n  tickArrays: TickArrayFacade[],\n  oracle: Oracle | undefined,\n  specifiedTokenA: boolean,\n  slippageToleranceBps: number,\n  timestamp: bigint,\n): SwapQuote<T> {\n  if (\"inputAmount\" in params) {\n    return swapQuoteByInputToken(\n      params.inputAmount,\n      specifiedTokenA,\n      slippageToleranceBps,\n      whirlpool,\n      oracle,\n      tickArrays,\n      timestamp,\n      transferFeeA,\n      transferFeeB,\n    ) as SwapQuote<T>;\n  }\n\n  return swapQuoteByOutputToken(\n    params.outputAmount,\n    specifiedTokenA,\n    slippageToleranceBps,\n    whirlpool,\n    oracle,\n    tickArrays,\n    timestamp,\n    transferFeeA,\n    transferFeeB,\n  ) as SwapQuote<T>;\n}\n\n/**\n * Generates the instructions necessary to execute a token swap in an Orca Whirlpool.\n * It handles both exact input and exact output swaps, fetching the required accounts, tick arrays, and determining the swap quote.\n *\n * @template T - The type of swap (exact input or output).\n * @param {SolanaRpc} rpc - The Solana RPC client.\n * @param {T} params - The swap parameters, specifying either the input or output amount and the mint address of the token being swapped.\n * @param {Address} poolAddress - The address of the Whirlpool against which the swap will be made.\n * @param {number} [slippageToleranceBps=SLIPPAGE_TOLERANCE_BPS] - The maximum acceptable slippage tolerance for the swap, in basis points (BPS).\n * @param {TransactionSigner} [signer=FUNDER] - The wallet or signer executing the swap.\n * @returns {Promise<SwapInstructions<T>>} - A promise that resolves to an object containing the swap instructions and the swap quote.\n *\n * @example\n * import { setWhirlpoolsConfig, swapInstructions } from '@orca-so/whirlpools';\n * import { createSolanaRpc, devnet, address } from '@solana/kit';\n * import { loadWallet } from './utils';\n *\n * await setWhirlpoolsConfig('solanaDevnet');\n * const devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));\n * const wallet = await loadWallet(); // CAUTION: This wallet is not persistent.\n * const whirlpoolAddress = address(\"3KBZiL2g8C7tiJ32hTv5v3KM7aK9htpqTw4cTXz1HvPt\");\n * const mintAddress = address(\"BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k\");\n * const inputAmount = 1_000_000n;\n *\n * const { instructions, quote } = await swapInstructions(\n *   devnetRpc,\n *   { inputAmount, mint: mintAddress },\n *   whirlpoolAddress,\n *   100,\n *   wallet\n * );\n *\n * console.log(`Quote estimated token out: ${quote.tokenEstOut}`);\n * console.log(`Number of instructions:, ${instructions.length}`);\n */\nexport async function swapInstructions<T extends SwapParams>(\n  rpc: Rpc<\n    GetAccountInfoApi &\n      GetMultipleAccountsApi &\n      GetMinimumBalanceForRentExemptionApi &\n      GetEpochInfoApi\n  >,\n  params: T,\n  poolAddress: Address,\n  slippageToleranceBps: number = SLIPPAGE_TOLERANCE_BPS,\n  signer: TransactionSigner = FUNDER,\n): Promise<SwapInstructions<T>> {\n  const whirlpool = await fetchWhirlpool(rpc, poolAddress);\n  const [tokenA, tokenB] = await fetchAllMint(rpc, [\n    whirlpool.data.tokenMintA,\n    whirlpool.data.tokenMintB,\n  ]);\n  const specifiedTokenA = params.mint === whirlpool.data.tokenMintA;\n  const specifiedInput = \"inputAmount\" in params;\n\n  const tickArrays = await fetchTickArrayOrDefault(rpc, whirlpool);\n\n  const oracleAddress = await getOracleAddress(whirlpool.address).then(\n    (x) => x[0],\n  );\n  const oracle = await getOracle(rpc, oracleAddress, whirlpool.data);\n\n  const currentEpoch = await rpc.getEpochInfo().send();\n  const transferFeeA = getCurrentTransferFee(tokenA, currentEpoch.epoch);\n  const transferFeeB = getCurrentTransferFee(tokenB, currentEpoch.epoch);\n\n  const timestamp = BigInt(Math.floor(Date.now() / 1000));\n  const tradeEnableTimestamp = oracle?.tradeEnableTimestamp ?? 0n;\n\n  const quote = getSwapQuote<T>(\n    params,\n    whirlpool.data,\n    transferFeeA,\n    transferFeeB,\n    tickArrays.map((x) => x.data),\n    oracle,\n    specifiedTokenA,\n    slippageToleranceBps,\n    timestamp,\n  );\n  const maxInAmount = \"tokenIn\" in quote ? quote.tokenIn : quote.tokenMaxIn;\n  const aToB = specifiedTokenA === specifiedInput;\n\n  const { createInstructions, cleanupInstructions, tokenAccountAddresses } =\n    await prepareTokenAccountsInstructions(rpc, signer, {\n      [whirlpool.data.tokenMintA]: aToB ? maxInAmount : 0n,\n      [whirlpool.data.tokenMintB]: aToB ? 0n : maxInAmount,\n    });\n\n  const instructions: IInstruction[] = [];\n\n  instructions.push(...createInstructions);\n\n  const specifiedAmount =\n    \"inputAmount\" in params ? params.inputAmount : params.outputAmount;\n  const otherAmountThreshold =\n    \"tokenMaxIn\" in quote ? quote.tokenMaxIn : quote.tokenMinOut;\n\n  const swapInstruction = getSwapV2Instruction({\n    tokenProgramA: tokenA.programAddress,\n    tokenProgramB: tokenB.programAddress,\n    memoProgram: MEMO_PROGRAM_ADDRESS,\n    tokenAuthority: signer,\n    whirlpool: whirlpool.address,\n    tokenMintA: whirlpool.data.tokenMintA,\n    tokenMintB: whirlpool.data.tokenMintB,\n    tokenOwnerAccountA: tokenAccountAddresses[whirlpool.data.tokenMintA],\n    tokenOwnerAccountB: tokenAccountAddresses[whirlpool.data.tokenMintB],\n    tokenVaultA: whirlpool.data.tokenVaultA,\n    tokenVaultB: whirlpool.data.tokenVaultB,\n    tickArray0: tickArrays[0].address,\n    tickArray1: tickArrays[1].address,\n    tickArray2: tickArrays[2].address,\n    amount: specifiedAmount,\n    otherAmountThreshold,\n    sqrtPriceLimit: 0,\n    amountSpecifiedIsInput: specifiedInput,\n    aToB,\n    oracle: oracleAddress,\n    remainingAccountsInfo: {\n      slices: [\n        { accountsType: AccountsType.SupplementalTickArrays, length: 2 },\n      ],\n    },\n  });\n\n  swapInstruction.accounts.push(\n    { address: tickArrays[3].address, role: AccountRole.WRITABLE },\n    { address: tickArrays[4].address, role: AccountRole.WRITABLE },\n  );\n\n  instructions.push(swapInstruction);\n  instructions.push(...cleanupInstructions);\n\n  return {\n    quote,\n    instructions,\n    tradeEnableTimestamp,\n  };\n}\n\n// -------- ACTIONS --------\n\nexport const swap = wrapFunctionWithExecution(swapInstructions);\n"],"mappings":"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","names":["import_whirlpools_client","import_kit","import_token_2022","import_assert","import_kit","import_token","assert","getTokenSizeWithExtensions","import_kit","import_tx_sender","assert","x","import_whirlpools_client","import_whirlpools_core","import_token","import_token_2022","import_assert","assert","import_whirlpools_core","import_whirlpools_client","import_token","import_token_2022","import_memo","import_assert","import_tx_sender","import_whirlpools_client","import_whirlpools_core","import_token","import_token_2022","import_kit","import_kit","x","positions","assert","import_whirlpools_client","import_whirlpools_core","import_kit","import_sysvars","import_token","import_token_2022","import_memo","import_assert","assert","import_whirlpools_client","import_whirlpools_core","import_token","x","import_kit","import_whirlpools_core","import_whirlpools_client","import_memo","import_token_2022","address"]}