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