Withdraw

Interface

/**
 * 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: number;
  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;
}

Function Overview

import { prepareWithdrawData, TokenKey } from '@molecularlabs/nucleus-frontend';
import { mainnet, optimism } from 'viem/chains';

const COOLVAULT_VAULT_KEY = VaultKeys.COOLVAULT;

// Prepare withdrawal transaction data
const withdrawData = await prepareWithdrawData({
  vaultKey: COOLVAULT_VAULT_KEY,
  chainId: mainnet.id, // Ethereum mainnet
  userAddress: '0x1234...',
  wantAsset: TokenKey.WETH,
  redeemAmount: 2, // 2 COOLVAULT Tokens
  deadline: 3, // 3 days from now (optional)
  slippage: 0.01, // 1% slippage (optional)
});

const {
  abi, // AtomicQueueAbi
  address, // Contract address for the atomic queue
  functionName, // 'updateAtomicRequest'
  args: // [offer: Address, want: Address, userRequest: UserRequest];
  chainId, // Chain ID for the transaction
} = withdrawData;

Wagmi Example

Wagmi Example

import { useState } from 'react';
import { useAccount, useWriteContract, useWaitForTransactionReceipt } from 'wagmi';
import { parseUnits } from 'viem';
import { prepareWithdrawData, VaultKeys } from '@molecularlabs/nucleus-frontend';
import { TokenKey } from './path/to/vaults/tokens';
import { ChainId } from './path/to/vaults/chains';

const COOLVAULT_VAULT_KEY = VaultKeys.COOLVAULT;

function WithdrawForm() {
  const { address } = useAccount();
  const [amount, setAmount] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  
  const { writeContract, data: hash, error, isPending } = useWriteContract();
  
  const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({
    hash,
  });
  
  const handleWithdraw = async () => {
    if (!address || !amount) return;
    
    try {
      setIsLoading(true);
      
      // Convert user input to bigint with proper decimals (assuming 18 decimals for this example)
      const redeemAmount = parseUnits(amount, 18);
      
      // Calculate deadline (1 hour from now)
      const deadline = Math.floor(Date.now() / 1000) + 3600;
      
      // In an application, I would recommend pairing this with @tanstack/react-query
      // Prepare the withdrawal transaction data
      const withdrawData = await prepareWithdrawTransactionData({
        vaultKey: COOLVAULT_VAULT_KEY, // Replace with your target vault
        chainId: ChainId.ETHEREUM, // Replace with appropriate chain ID
        userAddress: address,
        wantAsset: TokenKey.WETH, // Replace with desired asset
        redeemAmount,
        deadline,
        slippage: 0.005, // 0.5% slippage
      });
      
      // Execute the transaction using Wagmi's writeContract
      writeContract({
        abi: withdrawData.abi,
        address: withdrawData.address,
        functionName: withdrawData.functionName,
        args: withdrawData.args,
        chainId: withdrawData.chainId,
      });
      
    } catch (err) {
      console.error('Error preparing withdrawal:', err);
    } finally {
      setIsLoading(false);
    }
  };
  
  return (
    <div>
      <h2>Withdraw from Vault</h2>
      <input
        type="text"
        value={amount}
        onChange={(e) => setAmount(e.target.value)}
        placeholder="Amount to withdraw"
        disabled={isPending || isConfirming}
      />
      <button 
        onClick={handleWithdraw} 
        disabled={!amount || isPending || isConfirming || isLoading}
      >
        {isPending ? 'Confirming...' : isConfirming ? 'Processing...' : 'Withdraw'}
      </button>
      
      {error && <div className="error">Error: {error.message}</div>}
      {isSuccess && (
        <div className="success">
          Withdrawal request submitted! Your request has been added to the atomic queue.
        </div>
      )}
      
      <div className="note">
        <p>Note: Withdrawals are processed through an atomic queue system. Your funds will be available once the request is processed.</p>
      </div>
    </div>
  );
}

Last updated