{"version":3,"sources":["../../../src/vaults/deposit/deposit.ts"],"sourcesContent":["/**\n * @file Deposit functionality for Nucleus vaults\n * @module vaults/deposit\n */\n\nimport { type Address, erc20Abi, parseUnits } from 'viem';\nimport { getRateInQuoteWithAssetDecimals } from '../../api/accountant';\nimport { getErc20Decimals } from '../../api/erc20';\nimport { getPreviewFee, type BridgeData } from '../../api/teller';\nimport { type ChainId, toChainId } from '../../api/vault-config';\nimport {\n  DEFAULT_APPROVAL_AMOUNT,\n  DEFAULT_DEPOSIT_SLIPPAGE,\n} from '../../constants';\nimport { TellerAbi } from '../../contracts/teller-abi';\nimport { tryCatch } from '../../utils/try-catch';\nimport { prepareBridgeContractArg } from '../bridge';\nimport type { VaultKey } from '../config';\nimport { getVaultByKey } from '../index';\nimport type { TokenKey } from '../tokens';\nimport { calculateMinimumMint } from './utils';\n\n/**\n * Parameters required for preparing a deposit transaction\n * @interface PrepareDepositTransactionDataParams\n * @property {VaultKey} vaultKey - Unique identifier for the target vault\n * @property {Address} userAddress - Ethereum address of the user making the deposit\n * @property {string} depositTokenSymbol - Symbol of the token being deposited (e.g., 'WETH', 'USDC')\n * @property {string} depositAmount - Amount of assets to deposit as a decimal string (e.g., \"1.5\")\n * @property {number | string} chainId - ID of the chain where the deposit will occur\n * @property {number} [slippage] - Maximum acceptable slippage percentage as a decimal (e.g., 0.01 for 1%)\n */\ninterface PrepareDepositTransactionDataParams {\n  vaultKey: VaultKey;\n  userAddress: Address;\n  depositTokenSymbol: TokenKey;\n  depositAmount: string;\n  chainId: ChainId;\n  slippage?: number;\n}\n\n/**\n * Result object containing transaction data for a deposit operation\n * @interface DepositTransactionData\n * @property {typeof TellerAbi} abi - ABI for the Teller contract\n * @property {Address} address - Address of the Teller contract\n * @property {'deposit'} functionName - Name of the function to call\n * @property {[Address, bigint, bigint]} args - Arguments for the deposit function:\n *   [depositAsset, depositAmount, minimumMint]\n * @property {number} chainId - ID of the chain where the transaction should be executed\n */\ninterface DepositTransactionData {\n  abi: typeof TellerAbi;\n  address: Address;\n  functionName: 'deposit';\n  args: [Address, bigint, bigint];\n  chainId: number;\n}\n\n/**\n * Prepares the transaction data needed to deposit assets into a vault\n *\n * This function calculates the minimum amount of vault tokens to be minted based on\n * the current exchange rate and the specified slippage tolerance. It returns a transaction\n * object that can be used with viem or ethers.js to execute the deposit.\n *\n * @example\n * ```typescript\n * const depositData = await prepareDepositData({\n *   vaultKey: 'bobaeth',\n *   userAddress: '0x1234...',\n *   depositTokenSymbol: 'WETH',\n *   depositAmount: \"1.0\", // 1 WETH\n *   chainId: 1,\n *   slippage: 0.01, // 1% slippage\n * });\n * ```\n *\n * @param {PrepareDepositTransactionDataParams} params - Parameters for the deposit operation\n * @param {VaultKey} params.vaultKey - Unique identifier for the vault\n * @param {Address} params.userAddress - Ethereum address of the user making the deposit\n * @param {string} params.depositTokenSymbol - Symbol of the token being deposited\n * @param {string} params.depositAmount - Amount of assets to deposit as a string\n * @param {number | string} params.chainId - ID of the chain where the deposit will occur\n * @param {number} [params.slippage=DEFAULT_DEPOSIT_SLIPPAGE] - Maximum acceptable slippage percentage\n *\n * @returns {Promise<DepositTransactionData>} Promise resolving to the prepared transaction data\n * @throws {Error} If the vault key is invalid or if contracts are not properly configured\n */\nconst prepareDepositTransactionData = async ({\n  vaultKey,\n  depositTokenSymbol,\n  depositAmount,\n  chainId,\n  slippage = DEFAULT_DEPOSIT_SLIPPAGE,\n}: PrepareDepositTransactionDataParams): Promise<DepositTransactionData> => {\n  try {\n    const normalizedChainId = toChainId(chainId);\n    const vault = await getVaultByKey(vaultKey);\n\n    const depositAssetAddress =\n      vault.deposit.sourceChains[normalizedChainId].depositTokens[\n        depositTokenSymbol\n      ].address;\n\n    if (!vault) {\n      throw new Error(`Invalid vault key: ${vaultKey}`);\n    }\n    if (!depositAssetAddress) {\n      throw new Error(\n        `Couldn't find address for ${depositTokenSymbol} on ${chainId}`\n      );\n    }\n\n    if (!vault.contracts) {\n      throw new Error(`Contracts not configured for vault ${vaultKey}`);\n    }\n\n    if (!vault.contracts.teller) {\n      throw new Error(`Teller contract not configured for vault ${vaultKey}`);\n    }\n\n    const [depositAssetDecimals, rate] = await getRateInQuoteWithAssetDecimals({\n      assetAddress: depositAssetAddress,\n      accountantAddress: vault.contracts.accountant,\n      chainId: normalizedChainId,\n    });\n\n    if (depositAssetDecimals.status === 'failure') {\n      throw new Error(depositAssetDecimals.error.message);\n    }\n\n    if (rate.status === 'failure') {\n      throw new Error(rate.error.message);\n    }\n\n    const depositAmountAsBitInt = parseUnits(\n      depositAmount,\n      depositAssetDecimals.result\n    );\n\n    const minimumMint = calculateMinimumMint(\n      depositAmountAsBitInt,\n      rate.result,\n      slippage\n    );\n\n    return {\n      abi: TellerAbi,\n      address: vault.contracts.teller,\n      functionName: 'deposit',\n      args: [depositAssetAddress, depositAmountAsBitInt, minimumMint],\n      chainId: normalizedChainId,\n    };\n  } catch (error) {\n    console.error(error);\n    throw new Error(`Failed to get rate in quote for vault ${vaultKey}`);\n  }\n};\n\n/**\n * Parameters required for preparing a deposit and bridge transaction\n * @interface PrepareDepositAndBridgeTransactionDataParams\n * @property {VaultKey} vaultKey - Unique identifier for the target vault\n * @property {string} depositTokenSymbol - Symbol of the token being deposited\n * @property {string} depositAmount - Amount of assets to deposit as a string\n * @property {number | string} sourceChainId - ID of the chain where the deposit originates\n * @property {number | string} destinationChainId - ID of the chain where tokens will be bridged to\n * @property {Address} userAddress - Ethereum address of the user making the deposit\n * @property {number} [slippage] - Maximum acceptable slippage percentage (defaults to DEFAULT_DEPOSIT_SLIPPAGE)\n */\ninterface PrepareDepositAndBridgeTransactionDataParams {\n  depositAmount: string;\n  depositTokenSymbol: TokenKey;\n  destinationChainId: ChainId;\n  slippage?: number;\n  sourceChainId: ChainId;\n  userAddress: Address;\n  vaultKey: VaultKey;\n}\n\n/**\n * Result object containing transaction data for a deposit and bridge operation\n * @interface DepositAndBridgeTransactionData\n * @property {typeof TellerAbi} abi - ABI for the Teller contract\n * @property {Address} address - Address of the Teller contract\n * @property {'depositAndBridge'} functionName - Name of the function to call\n * @property {[Address, bigint, bigint, BridgeData]} args - Arguments for the depositAndBridge function:\n *   - depositAsset: Address of the token being deposited\n *   - depositAmount: Amount of tokens to deposit in base units (e.g., wei)\n *   - minimumMint: Minimum amount of vault tokens to receive after slippage\n *   - bridgeData: Data required for cross-chain bridging\n * @property {number} chainId - ID of the chain where the transaction should be executed\n * @property {bigint} value - Amount of native token to send with the transaction (for bridge fees)\n */\ninterface DepositAndBridgeTransactionData {\n  abi: typeof TellerAbi;\n  address: Address;\n  functionName: 'depositAndBridge';\n  args: [Address, bigint, bigint, BridgeData];\n  chainId: number;\n  value: bigint;\n}\n\n/**\n * Prepares the transaction data needed to deposit assets into a vault and bridge them to another chain\n *\n * This function calculates the minimum amount of vault tokens to be minted based on\n * the current exchange rate and the specified slippage tolerance, then prepares the bridge data\n * for cross-chain transfer. It returns a transaction object that can be used with viem or ethers.js\n * to execute the deposit and bridge operation.\n *\n * @example\n * ```typescript\n * const depositAndBridgeData = await prepareDepositAndBridgeData({\n *   vaultKey: 'bobaeth',\n *   depositTokenSymbol: 'WETH',\n *   depositAmount: \"1.0\", // 1 WETH\n *   sourceChainId: 1,\n *   destinationChainId: 10,\n *   userAddress: '0x1234...',\n *   slippage: 0.01, // 1% slippage\n * });\n * ```\n *\n * @param {PrepareDepositAndBridgeTransactionDataParams} params - Parameters for the deposit and bridge operation\n * @param {VaultKey} params.vaultKey - Unique identifier for the vault\n * @param {string} params.depositTokenSymbol - Symbol of the token being deposited\n * @param {string} params.depositAmount - Amount of assets to deposit as a string\n * @param {number | string} params.sourceChainId - ID of the chain where the deposit originates\n * @param {number | string} params.destinationChainId - ID of the chain where tokens will be bridged to\n * @param {Address} params.userAddress - Ethereum address of the user making the deposit\n * @param {number} [params.slippage=DEFAULT_DEPOSIT_SLIPPAGE] - Maximum acceptable slippage percentage\n *\n * @returns {Promise<DepositAndBridgeTransactionData>} Promise resolving to the prepared transaction data\n * @throws {Error} If the vault key is invalid or if contracts are not properly configured\n */\nconst prepareDepositAndBridgeTransactionData = async ({\n  depositAmount,\n  depositTokenSymbol,\n  destinationChainId,\n  slippage = DEFAULT_DEPOSIT_SLIPPAGE,\n  sourceChainId,\n  userAddress,\n  vaultKey,\n}: PrepareDepositAndBridgeTransactionDataParams): Promise<DepositAndBridgeTransactionData> => {\n  const normalizedSourceChainId = toChainId(sourceChainId);\n  const normalizedDestinationChainId = toChainId(destinationChainId);\n  const vault = await getVaultByKey(vaultKey);\n  const depositAssetAddress =\n    vault.deposit.sourceChains[normalizedSourceChainId].depositTokens[\n      depositTokenSymbol\n    ].address;\n\n  if (!vault) {\n    throw new Error(`Invalid vault key: ${vaultKey}`);\n  }\n\n  if (!vault.contracts) {\n    throw new Error(`Contracts not configured for vault ${vaultKey}`);\n  }\n\n  if (!vault.contracts.accountant) {\n    throw new Error(`Accountant contract not configured for vault ${vaultKey}`);\n  }\n\n  const bridgeIdentifier =\n    vault.deposit.sourceChains[normalizedSourceChainId].destinationChains[\n      normalizedDestinationChainId\n    ].bridge.chainIdentifier;\n\n  // Calculate minimum mint amount based on rate\n  const [depositAssetDecimals, rate] = await getRateInQuoteWithAssetDecimals({\n    assetAddress: depositAssetAddress,\n    accountantAddress: vault.contracts.accountant,\n    chainId: normalizedSourceChainId,\n  });\n\n  if (depositAssetDecimals.status === 'failure') {\n    throw new Error(depositAssetDecimals.error.message);\n  }\n\n  if (rate.status === 'failure') {\n    throw new Error(rate.error.message);\n  }\n\n  const depositAmountAsBitInt = parseUnits(\n    depositAmount,\n    depositAssetDecimals.result\n  );\n\n  const minimumMint = calculateMinimumMint(\n    depositAmountAsBitInt,\n    rate.result,\n    vault.token.decimals,\n    slippage\n  );\n\n  // Prepare bridge data\n  const bridgeData = prepareBridgeContractArg({\n    bridgeChainIdentifier: bridgeIdentifier,\n    userAddress,\n  });\n\n  const previewFee = await getPreviewFee({\n    shareAmount: depositAmountAsBitInt,\n    bridgeData: bridgeData,\n    contractAddress: vault.contracts.teller,\n    chainId: normalizedSourceChainId,\n  });\n\n  return {\n    abi: TellerAbi,\n    address: vault.contracts.teller,\n    functionName: 'depositAndBridge',\n    args: [depositAssetAddress, depositAmountAsBitInt, minimumMint, bridgeData],\n    chainId: normalizedSourceChainId,\n    value: previewFee,\n  };\n};\n\ninterface PrepareApproveDepositTokenParams {\n  vaultKey: VaultKey;\n  depositTokenSymbol: string;\n  depositAmount?: string;\n  chainId: ChainId;\n}\n\ninterface ApproveDepositTokenTransactionData {\n  abi: typeof erc20Abi;\n  address: Address;\n  functionName: 'approve';\n  args: [Address, bigint];\n}\n\nconst prepareApproveDepositToken = async ({\n  vaultKey,\n  depositTokenSymbol,\n  depositAmount,\n  chainId,\n}: PrepareApproveDepositTokenParams): Promise<ApproveDepositTokenTransactionData> => {\n  const normalizedChainId = toChainId(chainId);\n  const vault = await getVaultByKey(vaultKey);\n\n  if (!vault) {\n    throw new Error(`Invalid vault key: ${vaultKey}`);\n  }\n\n  if (!vault.contracts) {\n    throw new Error(`Contracts not configured for vault ${vaultKey}`);\n  }\n\n  if (!vault.contracts.boringVault) {\n    throw new Error(`Teller contract not configured for vault ${vaultKey}`);\n  }\n\n  const depositAssetAddress =\n    vault.deposit.sourceChains[normalizedChainId].depositTokens[\n      depositTokenSymbol\n    ].address;\n\n  if (!depositAssetAddress) {\n    throw new Error(`Invalid deposit token symbol: ${depositTokenSymbol}`);\n  }\n\n  const {\n    data: depositAssetDecimals,\n    error: depositAssetDecimalsError,\n    success: depositAssetDecimalsSuccess,\n  } = await tryCatch(\n    getErc20Decimals({\n      chainId: normalizedChainId,\n      tokenAddress: depositAssetAddress,\n    })\n  );\n\n  if (depositAssetDecimalsSuccess === false) {\n    throw new Error(\n      `Error getting deposit asset decimals. ${depositAssetDecimalsError.name}: ${depositAssetDecimalsError.message}`\n    );\n  }\n\n  if (!depositAssetDecimals) {\n    throw new Error(`Invalid deposit token symbol: ${depositTokenSymbol}`);\n  }\n\n  const depositAmountAsBigInt = depositAmount\n    ? parseUnits(depositAmount, depositAssetDecimals)\n    : DEFAULT_APPROVAL_AMOUNT;\n\n  return {\n    abi: erc20Abi,\n    address: depositAssetAddress,\n    functionName: 'approve',\n    args: [vault.contracts.boringVault, depositAmountAsBigInt],\n  };\n};\n\nexport {\n  prepareApproveDepositToken,\n  prepareDepositAndBridgeTransactionData,\n  prepareDepositTransactionData,\n};\n\nexport type {\n  ApproveDepositTokenTransactionData,\n  DepositAndBridgeTransactionData,\n  DepositTransactionData,\n};\n"],"mappings":"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","names":[]}