import { Address } from 'viem'; import { ChainId } from '../../api/vault-config.js'; import { AtomicQueueAbi } from '../../contracts/atomic-queue-abi.js'; import { BoringVaultAbi } from '../../contracts/boring-vault-abi.js'; import { BridgeTransactionData } from '../bridge.js'; import { VaultKey } from '../config.js'; import { TokenKey } from '../tokens.js'; import 'viem/chains'; import '../../api/teller.js'; import '../../contracts/teller-abi.js'; /** * @file Withdraw functionality for Nucleus vaults * @module vaults/withdraw */ /** * Arguments for an atomic request to the AtomicQueue contract * @typedef {Object} AtomicRequestArgs * @property {Address} offer - Address of the token being offered (shares token address) * @property {Address} want - Address of the token being requested (want token address) * @property {UserRequest} userRequest - User request details */ type AtomicRequestArgs = { offer: Address; want: Address; userRequest: UserRequest; }; /** * Options for an atomic request * @typedef {Object} AtomicRequestOptions * @property {Address} atomicQueueContractAddress - Address of the AtomicQueue contract * @property {number} chainId - ID of the destination chain */ type AtomicRequestOptions = { atomicQueueContractAddress: Address; chainId: ChainId; }; /** * User request details for an atomic swap * @typedef {Object} UserRequest * @property {number} deadline - Unix timestamp when the request expires * @property {bigint} atomicPrice - Rate in quote with fee applied * @property {bigint} offerAmount - Amount of shares token to redeem * @property {boolean} inSolve - Whether the request is in solve mode (always false for new requests) */ type UserRequest = { deadline: bigint; atomicPrice: bigint; offerAmount: bigint; inSolve: boolean; }; /** * Parameters for preparing a withdrawal transaction from a vault * @interface PrepareWithdrawTransactionDataParams * @property {ChainId} chainId - ID of the chain where the withdrawal will occur * @property {number} [deadline] - Unix timestamp when the request expires (optional) * @property {number} offerAmount - Amount of vault shares to withdraw * @property {number} [slippage] - Maximum acceptable slippage percentage (optional) * @property {Address} userAddress - Ethereum address of the user making the withdrawal * @property {VaultKey} vaultKey - Unique identifier for the vault * @property {TokenKey} wantTokenSymbol - Symbol of the token the user wants to receive */ interface PrepareWithdrawTransactionDataParams { chainId: ChainId; deadline?: number; offerAmount: string; slippage?: number; userAddress: Address; vaultKey: VaultKey; wantTokenSymbol: TokenKey; } /** * Result object containing transaction data for a withdrawal operation * @interface WithdrawTransactionData * @property {typeof AtomicQueueAbi} abi - ABI for the AtomicQueue contract * @property {Address} address - Address of the AtomicQueue contract * @property {'updateAtomicRequest'} functionName - Name of the function to call * @property {[Address, Address, UserRequest]} args - Arguments for the updateAtomicRequest function: * [offer, want, userRequest] * @property {number} chainId - ID of the chain where the transaction should be executed */ interface WithdrawTransactionData { abi: typeof AtomicQueueAbi; address: Address; functionName: "updateAtomicRequest"; args: [offer: Address, want: Address, userRequest: UserRequest]; chainId: number; } /** * Prepares the transaction data needed to withdraw assets from a vault * * This function calculates the appropriate exchange rate with slippage protection * and prepares a user request for the AtomicQueue contract. It returns a transaction * object that can be used with viem or ethers.js to execute the withdrawal. * * @example * ```typescript * const withdrawData = await prepareWithdrawData({ * vaultKey: 'bobaeth', * chainId: 1, // Ethereum mainnet * userAddress: '0x1234...', * wantAsset: TokenKey.WETH, * redeemAmount: BigInt('1000000000000000000'), // 1 token * deadline: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now * slippage: 0.01, // 1% slippage * }); * ``` * * @param {PrepareWithdrawTransactionParams} params - Parameters for the withdraw operation * @param {VaultKey} params.vaultKey - Unique identifier for the vault * @param {ChainId} params.chainId - ID of the chain where the withdrawal will occur * @param {Address} params.userAddress - Ethereum address of the user making the withdrawal * @param {TokenKey} params.wantAsset - Key of the asset the user wants to receive * @param {bigint} params.offerAmount - Amount of vault tokens to redeem (in base units) * @param {number} [params.deadline] - Unix timestamp when the request expires * @param {number} [params.slippage] - Maximum acceptable slippage in basis points (bps). * e.g., 20 for 0.2%, 50 for 0.5% * * @returns {Promise} Promise resolving to the prepared transaction data * @throws {Error} If the vault key is invalid, if contracts are not properly configured, * or if the specified chain or token is not supported */ declare const prepareWithdrawTransactionData: ({ vaultKey, chainId, wantTokenSymbol, offerAmount, deadline, slippage, }: PrepareWithdrawTransactionDataParams) => Promise; /** * Parameters for preparing a cross-chain bridge and withdrawal transaction * @interface PrepareBridgeAndWithdrawTransactionDataParams * @extends {Omit} * @property {ChainId} sourceChainId - Chain ID where shares currently exist * @property {ChainId} destinationChainId - Chain ID where assets will be withdrawn * @property {number} offerAmount - Amount of vault shares to withdraw * @property {number} [deadline] - Unix timestamp when the request expires (optional) * @property {number} [slippage] - Maximum acceptable slippage percentage (optional) * @property {Address} userAddress - Ethereum address of the user making the withdrawal * @property {VaultKey} vaultKey - Unique identifier for the vault * @property {TokenKey} wantTokenSymbol - Symbol of the token the user wants to receive */ interface PrepareBridgeAndWithdrawTransactionDataParams extends Omit { sourceChainId: ChainId; destinationChainId: ChainId; } /** * Combined result containing both bridge and withdrawal transaction data * @interface BridgeAndWithdrawResult */ interface BridgeAndWithdrawTransactionData { bridgeTransactionData: BridgeTransactionData; withdrawTransactionData: WithdrawTransactionData; } /** * Prepares transaction data for cross-chain withdrawals from a vault * * This function handles both: * 1. Bridging vault shares from source chain to destination chain * 2. Creating a withdraw request on the destination chain * * The withdraw request can be submitted before the bridge completes - the solver * will wait for bridged shares to arrive before processing the request. * * @example * ```typescript * const result = await prepareBridgeAndWithdrawData({ * vaultKey: 'bobaeth', * sourceChainId: 42161, // Arbitrum * destinationChainId: 1, // Ethereum * userAddress: '0x1234...', * wantTokenSymbol: TokenKey.ETH, * offerAmount: 1.5, // 1.5 shares * deadline: Math.floor(Date.now() / 1000) + 3600, // 1 hour * slippage: 0.005 // 0.5% * }); * ``` * * @param {PrepareBridgeAndWithdrawParams} params - Parameters for the cross-chain withdraw * @returns {Promise} Transaction data for both bridge and withdraw operations * @throws {Error} If vault configuration is invalid or if preparing either transaction fails */ declare const prepareBridgeAndWithdrawTransactionData: ({ deadline, destinationChainId, offerAmount, slippage, sourceChainId, userAddress, vaultKey, wantTokenSymbol, }: PrepareBridgeAndWithdrawTransactionDataParams) => Promise; interface PrepareApproveWithdrawTokenParams { vaultKey: VaultKey; withdrawAmount?: string; chainId: ChainId; } interface ApproveWithdrawTokenTransactionData { abi: typeof BoringVaultAbi; address: Address; functionName: "approve"; args: [Address, bigint]; } declare const prepareApproveWithdrawToken: ({ vaultKey, withdrawAmount, chainId, }: PrepareApproveWithdrawTokenParams) => Promise; export { type ApproveWithdrawTokenTransactionData, type AtomicRequestArgs, type AtomicRequestOptions, type BridgeAndWithdrawTransactionData, type PrepareBridgeAndWithdrawTransactionDataParams, type PrepareWithdrawTransactionDataParams, type UserRequest, type WithdrawTransactionData, prepareApproveWithdrawToken, prepareBridgeAndWithdrawTransactionData, prepareWithdrawTransactionData };