Skip to content

useTransaction

The useTransaction hook handles the execution of bridge transactions, including automatic chain switching, transaction sending, and status monitoring.

Import

import { useTransaction } from '@silentswap/react';

Basic Usage

import { useTransaction, useQuote } from '@silentswap/react';
import { useAccount, useWalletClient } from 'wagmi';
 
function BridgeComponent() {
  const { address, connector } = useAccount();
  const { data: walletClient } = useWalletClient();
 
  const { getQuote } = useQuote({ address });
  const {
    executeTransaction,
    getStatus,
    isLoading,
    currentStep,
    error,
  } = useTransaction({
    address: address!,
    walletClient: walletClient as any,
    connector,
  });
 
  const handleBridge = async () => {
    // Get quote first
    const quote = await getQuote(
      1, // Ethereum
      '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
      '1000000', // 1 USDC
      43114, // Avalanche
      '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E' // USDC.e
    );
 
    if (!quote) {
      console.error('Failed to get quote');
      return;
    }
 
    // Execute the bridge transaction
    const result = await executeTransaction(quote);
 
    if (result) {
      console.log('Bridge completed:', result);
      
      // Check status if we have a request ID
      if (result.requestId) {
        const status = await getStatus(result.requestId, quote.provider);
        console.log('Bridge status:', status);
      }
    }
  };
 
  return (
    <div>
      {isLoading && (
        <div>
          <p>{currentStep || 'Processing...'}</p>
          <progress value={0.5} />
        </div>
      )}
      {error && <div>Error: {error.message}</div>}
      <button onClick={handleBridge} disabled={isLoading}>
        {isLoading ? currentStep || 'Executing...' : 'Execute Bridge'}
      </button>
    </div>
  );
}

API Reference

Options

interface useTransactionOptions {
  /** User's EVM address */
  address: `0x${string}`;
  /** Wallet client for signing operations */
  walletClient?: WalletClient;
  /** Wagmi connector */
  connector?: Connector;
}

Return Value

interface useTransactionReturn {
  // State
  isLoading: boolean;
  currentStep: string;
  error: Error | null;
 
  // Methods
  executeTransaction: (quote: BridgeQuote) => Promise<BridgeStatus | null>;
  getStatus: (requestId: string, provider: BridgeProvider) => Promise<BridgeStatus | null>;
}

BridgeQuote

The executeTransaction method expects a BridgeQuote object. You can convert a BridgeQuoteResult from useQuote to a BridgeQuote:

interface BridgeQuote {
  provider: BridgeProvider;
  estimatedTime: number;
  fee: {
    amount: string;
    token: string;
    usdValue: number;
  };
  slippage: number;
  route: RelayQuoteResponse | DeBridgeOrderResponse;
  txs: BridgeTransaction[];
}
 
interface BridgeTransaction {
  to: `0x${string}`;
  value: string;
  data: `0x${string}`;
  gasLimit?: string;
  chainId: number;
}

BridgeStatus

interface BridgeStatus {
  status: 'pending' | 'completed' | 'failed';
  requestId?: string;
  txHashes?: string[];
  error?: string;
}

Advanced Usage

Converting Quote to BridgeQuote

import { parseUnits } from 'viem';
import { getAllAssetsArray } from '@silentswap/sdk';
 
function convertQuoteToBridgeQuote(
  quote: BridgeQuoteResult,
  sourceTokenInfo: AssetInfo
): BridgeQuote {
  return {
    provider: quote.provider,
    estimatedTime: quote.estimatedTime,
    fee: {
      amount: '0',
      token: sourceTokenInfo.symbol,
      usdValue: quote.feeUsd,
    },
    slippage: quote.slippage,
    route: quote.rawResponse,
    txs: extractTransactions(quote.rawResponse, quote.provider, sourceChainId),
  };
}
 
function extractTransactions(
  rawResponse: any,
  provider: string,
  chainId: number
): BridgeTransaction[] {
  if (provider === 'relay') {
    return rawResponse.steps?.flatMap((step: any) =>
      step.items?.map((item: any) => ({
        to: item.data?.to,
        value: item.data?.value || '0',
        data: item.data?.data || '0x',
        gasLimit: item.data?.gas,
        chainId: item.data?.chainId || chainId,
      })) || []
    ) || [];
  } else if (provider === 'debridge') {
    return rawResponse.tx ? [{
      to: rawResponse.tx.to,
      value: rawResponse.tx.value || '0',
      data: rawResponse.tx.data || '0x',
      chainId: chainId,
    }] : [];
  }
  return [];
}

Monitoring Transaction Progress

const { executeTransaction, getStatus, currentStep } = useTransaction({
  address: address!,
  walletClient,
  connector,
});
 
const handleBridge = async () => {
  const quote = await getQuote(/* ... */);
  if (!quote) return;
 
  const result = await executeTransaction(quote);
 
  if (result?.requestId) {
    // Poll for status updates
    const checkStatus = setInterval(async () => {
      const status = await getStatus(result.requestId!, quote.provider);
      
      if (status?.status === 'completed') {
        clearInterval(checkStatus);
        console.log('Bridge completed!');
      } else if (status?.status === 'failed') {
        clearInterval(checkStatus);
        console.error('Bridge failed:', status.error);
      }
    }, 5000); // Check every 5 seconds
 
    // Cleanup after 5 minutes
    setTimeout(() => clearInterval(checkStatus), 5 * 60 * 1000);
  }
};

Error Handling

const { executeTransaction, error } = useTransaction({
  address: address!,
  walletClient,
  connector,
});
 
const handleBridge = async () => {
  try {
    const quote = await getQuote(/* ... */);
    if (!quote) {
      throw new Error('Failed to get quote');
    }
 
    const result = await executeTransaction(quote);
    
    if (!result) {
      throw new Error('Transaction execution failed');
    }
 
    if (result.status === 'failed') {
      throw new Error(result.error || 'Bridge transaction failed');
    }
 
    // Success!
    console.log('Bridge completed:', result);
  } catch (err) {
    console.error('Bridge error:', err);
    // Show error to user
  }
};

Transaction Flow

  1. Chain Switching - Automatically switches to the source chain if needed
  2. Transaction Sending - Sends the bridge transaction(s)
  3. Confirmation - Waits for transaction confirmation
  4. Status Updates - Provides real-time status updates via currentStep
  5. Completion - Returns final status with transaction hashes

Supported Providers

  • Relay.link - Multi-step bridge transactions
  • deBridge - Single transaction bridges

Best Practices

  1. Always Check Quote - Verify quote exists before executing
  2. Handle Loading States - Show progress using currentStep
  3. Monitor Status - Poll for status updates on long-running bridges
  4. Error Recovery - Provide retry mechanisms for failed transactions
  5. User Feedback - Keep users informed of transaction progress

Next Steps