Deposit and Bridge
Interface
/**
* Parameters required for preparing a deposit and bridge transaction
* @interface PrepareDepositAndBridgeTransactionDataParams
* @property {VaultKey} vaultKey - Unique identifier for the target vault
* @property {string} depositTokenSymbol - Symbol of the token being deposited
* @property {string} depositAmount - Amount of assets to deposit as a string
* @property {number | string} sourceChainId - ID of the chain where the deposit originates
* @property {number | string} destinationChainId - ID of the chain where tokens will be bridged to
* @property {Address} userAddress - Ethereum address of the user making the deposit
* @property {number} [slippage] - Maximum acceptable slippage percentage (defaults to DEFAULT_DEPOSIT_SLIPPAGE)
*/
interface PrepareDepositAndBridgeTransactionDataParams {
depositAmount: string;
depositTokenSymbol: string;
destinationChainId: number | string;
slippage?: number;
sourceChainId: number | string;
userAddress: Address;
vaultKey: VaultKey;
}
/**
* Result object containing transaction data for a deposit and bridge operation
* @interface DepositAndBridgeTransactionData
* @property {typeof TellerAbi} abi - ABI for the Teller contract
* @property {Address} address - Address of the Teller contract
* @property {'depositAndBridge'} functionName - Name of the function to call
* @property {[Address, bigint, bigint, BridgeData]} args - Arguments for the depositAndBridge function:
* - depositAsset: Address of the token being deposited
* - depositAmount: Amount of tokens to deposit in base units (e.g., wei)
* - minimumMint: Minimum amount of vault tokens to receive after slippage
* - bridgeData: Data required for cross-chain bridging
* @property {number} chainId - ID of the chain where the transaction should be executed
* @property {bigint} value - Amount of native token to send with the transaction (for bridge fees)
*/
interface DepositAndBridgeTransactionData {
abi: typeof TellerAbi;
address: Address;
functionName: 'depositAndBridge';
args: [Address, bigint, bigint, BridgeData];
chainId: number;
value: bigint;
}
Function Overview
import { prepareDepositAndBridgeData, VaultKeys } from '@molecularlabs/nucleus-frontend';
import { mainnet, optimism } from 'viem/chains';
const COOLVAULT_VAULT_KEY = VaultKeys.COOLVAULT;
// Prepare withdrawal and bridge transaction data
const bridgeAndWithdrawData = await prepareBridgeAndWithdrawTransactionData({
vaultKey: 'bobaeth',
sourceChainId: 42161, // Arbitrum
destinationChainId: mainnet.id, // Ethereum mainnet
userAddress: '0x1234...', // User's wallet address
wantTokenSymbol: TokenKey.WETH, // Token to receive
offerAmount: 1.5, // Amount of vault shares to withdraw
deadline: // Optional: must be passed in whole day values. ex. 1 for 1 day from now
slippage: 0.005, // Optional: 0.5% slippage
});
const {
bridgeTransactionData: {
abi, // Contract ABI (CrossChainTellerBaseAbi)
address, // Bridge contract address
functionName, // Bridge function name
args, // [bridgeAmount, bridgeContractArg]
chainId, // Chain ID for the bridge transaction
value, // Amount of native token to send for bridge fees
},
withdrawTransactionData: {
abi: withdrawAbi, // AtomicQueueAbi
address: withdrawAddress, // AtomicQueue contract address
functionName: withdrawFunctionName, // 'updateAtomicRequest'
args: withdrawArgs, // [offerTokenAddress, wantTokenAddress, userRequest]
chainId: withdrawChainId, // Chain ID for the withdraw transaction
}
} = bridgeAndWithdrawData;
Viem Example
import { createPublicClient, http, createWalletClient, custom } from 'viem';
import { mainnet, optimism } from 'viem/chains';
import { prepareDepositAndBridgeData, VaultKeys } from '@molecularlabs/nucleus-frontend';
// Example using Viem with MetaMask
const publicClient = createPublicClient({
chain: mainnet,
transport: http()
});
const walletClient = createWalletClient({
chain: mainnet,
transport: custom(window.ethereum)
});
const COOLVAULT_VAULT_KEY = VaultKeys.COOLVAULT;
async function depositAndBridgeToVault() {
try {
// Get user's address
const [address] = await walletClient.requestAddresses();
// Prepare deposit and bridge data
const depositAndBridgeData = await prepareDepositAndBridgeTransactionData({
vaultKey: COOLVAULT_VAULT_KEY,
depositTokenSymbol: 'WETH',
depositAmount: '1.0', // Depositing 1 WETH
sourceChainId: mainnet.id, // Ethereum Mainnet
destinationChainId: optimism.id, // Optimism
userAddress: address,
slippage: 0.01 // 1% slippage
});
// Send the transaction
const hash = await walletClient.writeContract({
...depositAndBridgeData,
value: depositAndBridgeData.value // Include bridge fee
});
// Wait for transaction
const receipt = await publicClient.waitForTransactionReceipt({ hash });
console.log('Deposit and bridge successful:', receipt);
} catch (error) {
console.error('Deposit and bridge failed:', error);
}
}
Wagmi Example
import { useState } from 'react';
import { useAccount, useContractWrite, usePrepareContractWrite, useWaitForTransaction } from 'wagmi';
import { useQuery } from '@tanstack/react-query';
import { mainnet, optimism } from 'viem/chains';
import { prepareDepositAndBridgeData, VaultKeys } from '@molecularlabs/nucleus-frontend';
const COOLVAULT_VAULT_KEY = VaultKeys.COOLVAULT;
function DepositAndBridgeForm() {
const { address } = useAccount();
const [amount, setAmount] = useState('');
// Fetch deposit data
const { data: depositData, isLoading: isPreparingDeposit, error: prepareError } = useQuery({
queryKey: ['prepareDepositAndBridge', COOLVAULT_VAULT_KEY, amount, address],
queryFn: async () => {
if (!amount || !address) return null;
return prepareDepositAndBridgeData({
vaultKey: COOLVAULT_VAULT_KEY,
depositTokenSymbol: 'WETH',
depositAmount: amount,
sourceChainId: mainnet.id, // Ethereum Mainnet
destinationChainId: optimism.id, // Optimism
userAddress: address,
slippage: 0.01 // optional
});
},
enabled: Boolean(amount && address),
});
// Prepare the contract write
const { config, error: prepareWriteError } = usePrepareContractWrite({
address: depositData?.address,
abi: depositData?.abi,
functionName: depositData?.functionName,
args: depositData?.args,
value: depositData?.value,
enabled: Boolean(depositData),
});
// Handle the contract write
const { write, data: writeData, error: writeError } = useContractWrite(config);
// Handle transaction status
const { isLoading: isTransactionPending, isSuccess } = useWaitForTransaction({
hash: writeData?.hash,
});
// Combine all errors
const error = prepareError || prepareWriteError || writeError;
return (
<div className="max-w-md mx-auto p-6 bg-white rounded-xl shadow-lg">
<h2 className="text-2xl font-bold mb-6">Deposit and Bridge WETH</h2>
{/* Amount Input */}
<div className="mb-4">
<label className="block text-sm font-medium text-gray-700 mb-2">
Amount (WETH)
</label>
<input
type="number"
value={amount}
onChange={(e) => setAmount(e.target.value)}
placeholder="0.0"
className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500"
disabled={isTransactionPending}
/>
</div>
{/* Bridge Details */}
<div className="mb-6 text-sm text-gray-600">
<p>From: Ethereum Mainnet</p>
<p>To: Optimism</p>
<p>Slippage: 1%</p>
</div>
{/* Action Button */}
<button
onClick={() => write?.()}
disabled={!write || isPreparingDeposit || isTransactionPending}
className={`w-full py-3 px-4 rounded-lg font-medium text-white
${(!write || isPreparingDeposit || isTransactionPending)
? 'bg-gray-400'
: 'bg-blue-600 hover:bg-blue-700'
} transition-colors`}
>
{isPreparingDeposit ? (
'Preparing...'
) : isTransactionPending ? (
'Processing...'
) : (
'Deposit and Bridge'
)}
</button>
{/* Status Messages */}
{isSuccess && (
<div className="mt-4 p-4 bg-green-100 text-green-700 rounded-lg">
Transaction successful! Your tokens are being bridged.
</div>
)}
{error && (
<div className="mt-4 p-4 bg-red-100 text-red-700 rounded-lg">
{error.message}
</div>
)}
{/* Transaction Progress */}
{isTransactionPending && (
<div className="mt-4">
<div className="h-2 w-full bg-gray-200 rounded-full overflow-hidden">
<div className="h-full bg-blue-600 animate-pulse rounded-full" />
</div>
<p className="text-sm text-gray-600 mt-2">
Bridging in progress. Please wait...
</p>
</div>
)}
</div>
);
}
export default DepositAndBridgeForm;
Last updated