Skip to main content

Usage-Example

The following is a complete cross-chain transfer application, demonstrating how to integrate all Hooks with UI interaction.

import { useState, useEffect } from 'react';
import {
useChainList,
useTokenList,
useCrossChainFee,
useCrossChainTransfer,
useTokenBalance,
configureBridge
} from 'gatex-sdk-hooks';
import { parseUnits, formatUnits } from 'viem';

function CrossChainApp() {
// State management
const [sourceChainId, setSourceChainId] = useState('');
const [destChainId, setDestChainId] = useState('');
const [sourceToken, setSourceToken] = useState('');
const [destToken, setDestToken] = useState('');
const [amount, setAmount] = useState('');
const [recipient, setRecipient] = useState('');
const [destAmount, setDestAmount] = useState('');

// Hooks initialization
const { data: chainList, fetchData: fetchChainList } = useChainList();
const { data: tokenList, fetchData: fetchTokenList } = useTokenList();
const { data: feeData, fetchData: fetchFee, loading: feeLoading } = useCrossChainFee();
const { transfer, loading: transferLoading, error: transferError } = useCrossChainTransfer();
const { balance: sourceBalance, symbol: sourceSymbol } = useTokenBalance(sourceToken, {
walletAddress: '0x...',
evmChainId: sourceChainId
});

// Fetch chain and token lists
useEffect(() => {
fetchChainList();
fetchTokenList();
}, []);

// Calculate fee
const calculateFee = async () => {
try {
const decimals = tokenList?.find((t) => t.address === sourceToken)?.decimals || 18;
const result = await fetchFee({
sourceChain: sourceChainId,
destChain: destChainId,
sourceToken,
destToken,
amount: String(parseUnits(amount, decimals)),
to: recipient,
});

if (result) {
const receiveAmount = formatUnits(result.destMinAmount, decimals);
setDestAmount(receiveAmount);
}
} catch (err) {
console.error('Fee calculation failed:', err);
}
};

// Execute transfer
const handleTransfer = async () => {
try {
const decimals = tokenList?.find((t) => t.address === sourceToken)?.decimals || 18;
await transfer(feeData.routerResult);
alert('Transfer successful!');
} catch (err) {
console.error('Transfer failed:', err);
alert('Transfer failed: ' + err.message);
}
};

return (
<div style={{ padding: '20px', maxWidth: '600px', margin: 'auto' }}>
<h2>Cross-Chain Transfer</h2>

{/* Source Chain Selection */}
<div>
<label>Source Chain</label>
<select value={sourceChainId} onChange={(e) => setSourceChainId(e.target.value)}>
<option value="">Select Chain</option>
{chainList?.map((chain) => (
<option key={chain.id} value={chain.id}>{chain.chainName}</option>
))}
</select>
</div>

{/* Destination Chain Selection */}
<div>
<label>Destination Chain</label>
<select value={destChainId} onChange={(e) => setDestChainId(e.target.value)}>
<option value="">Select Chain</option>
{chainList?.map((chain) => (
<option key={chain.id} value={chain.id}>{chain.chainName}</option>
))}
</select>
</div>

{/* Source Token Selection */}
<div>
<label>Source Token</label>
<select value={sourceToken} onChange={(e) => setSourceToken(e.target.value)}>
<option value="">Select Token</option>
{tokenList?.filter((t) => t.chain_id === sourceChainId).map((token) => (
<option key={token.address} value={token.address}>{token.name}</option>
))}
</select>
{sourceBalance && <span>Balance: {sourceBalance} {sourceSymbol}</span>}
</div>

{/* Destination Token Selection */}
<div>
<label>Destination Token</label>
<select value={destToken} onChange={(e) => setDestToken(e.target.value)}>
<option value="">Select Token</option>
{tokenList?.filter((t) => t.chain_id === destChainId).map((token) => (
<option key={token.address} value={token.address}>{token.name}</option>
))}
</select>
</div>

{/* Amount Input */}
<div>
<label>Amount</label>
<input
type="text"
value={amount}
onChange={(e) => setAmount(e.target.value)}
placeholder="Enter amount"
/>
</div>

{/* Recipient Address */}
<div>
<label>Recipient Address</label>
<input
type="text"
value={recipient}
onChange={(e) => setRecipient(e.target.value)}
placeholder="Enter recipient address"
/>
</div>

{/* Calculate Fee Button */}
<button onClick={calculateFee} disabled={feeLoading || !amount || !recipient}>
{feeLoading ? 'Calculating...' : 'Calculate Fee'}
</button>

{/* Expected Receive Amount */}
{destAmount && <div>Expected Receive: {destAmount}</div>}

{/* Transfer Button */}
<button onClick={handleTransfer} disabled={transferLoading || !feeData}>
{transferLoading ? 'Transferring...' : 'Transfer'}
</button>

{/* Error Message */}
{transferError && <div style={{ color: 'red' }}>Error: {transferError.message}</div>}
</div>
);
}