Skip to content

getQuote

The getQuote composable provides optimized bridge quotes by comparing multiple providers (Relay.link and deBridge) and selecting the best option based on retention rate.

Import

import { getQuote } from '@silentswap/vue';

Basic Usage

<script setup lang="ts">
import { getQuote, getSilentSwapClient } from '@silentswap/vue';
import { useAccount } from 'wagmi';
import { ENVIRONMENT } from '@silentswap/sdk';
 
const { address } = useAccount();
 
// Initialize client to get depositor address
const { client } = getSilentSwapClient({
  config: {
    environment: ENVIRONMENT.MAINNET,
  },
});
 
const {
  getQuote: getBridgeQuote,
  isLoading,
  error,
  ingressEstimates,
  egressEstimates,
} = getQuote({
  address: address.value || undefined,
  depositorAddress: client.s0xDepositorAddress,
  maxImpactPercent: 5,
});
 
const handleGetQuote = async () => {
  const quote = await getBridgeQuote(
    1, // Source chain ID (Ethereum)
    '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // Source token (USDC)
    '1000000', // Amount in token units (1 USDC = 1e6)
    43114, // Destination chain ID (Avalanche)
    '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E' // Destination token (USDC.e)
  );
 
  if (quote) {
    console.log('Provider:', quote.provider);
    console.log('Output Amount:', quote.outputAmount);
    console.log('Fee (USD):', quote.feeUsd);
  }
};
</script>
 
<template>
  <div>
    <button @click="handleGetQuote" :disabled="isLoading">
      Get Quote
    </button>
    <div v-if="error">Error: {{ error.message }}</div>
  </div>
</template>

Getting the Depositor Address

The depositorAddress parameter is required for the solveUsdcAmount method. You can obtain it from the SilentSwap client:

import { getSilentSwapClient } from '@silentswap/vue';
import { ENVIRONMENT } from '@silentswap/sdk';
 
const { client } = getSilentSwapClient({
  config: {
    environment: ENVIRONMENT.MAINNET, // or ENVIRONMENT.TESTNET
  },
});
 
// Use client.s0xDepositorAddress
const { getQuote } = getQuote({
  address,
  depositorAddress: client.s0xDepositorAddress,
});

The depositor address is environment-specific and is automatically set based on your client configuration.

API Reference

Options

interface GetQuoteOptions {
  /** User's EVM address */
  address?: `0x${string}`;
  /** Depositor address for bridge operations (required for solveUsdcAmount) */
  depositorAddress: Hex;
  /** Maximum price impact percentage allowed (default from SDK constants) */
  maxImpactPercent?: number;
  /** Timeout for quote requests in milliseconds (default: 30000) */
  quoteTimeout?: number;
}

Return Value

interface GetQuoteReturn {
  // State (reactive)
  isLoading: Readonly<Ref<boolean>>;
  error: Readonly<Ref<Error | null>>;
  
  // Estimates cache (reactive)
  ingressEstimates: Readonly<Ref<Record<string, Estimate>>>;
  egressEstimates: Readonly<Ref<Record<string, Estimate>>>;
 
  // Methods
  getQuote: (
    srcChainId: number,
    srcToken: string,
    srcAmount: string,
    dstChainId: number,
    dstToken: string
  ) => Promise<BridgeQuoteResult>;
  
  solveUsdcAmount: (
    srcChainId: number,
    srcToken: string,
    srcAmount: string,
    depositCalldata?: string
  ) => Promise<SolveResult>;
  
  estimateLive: (
    direction: 'ingress' | 'egress',
    assetCaip19: string,
    chainId: number | string,
    tokenAddress: string,
    amount: number,
    usdPrice: number,
    externalSignal?: AbortSignal,
    recipientAddress?: string,
    isReverseCalculation?: boolean,
    targetAmount?: number
  ) => Promise<EstimateResult>;
  
  interpolateSamples: (
    samples: EstimateSample[],
    usdValue: number,
    marginHi?: number
  ) => number;
}

Advanced Usage

Auto-fetch Quote on Amount Change

<script setup lang="ts">
import { ref, watch } from 'vue';
import { getQuote, getSilentSwapClient } from '@silentswap/vue';
import { parseUnits } from 'viem';
import { ENVIRONMENT } from '@silentswap/sdk';
 
const amount = ref('');
const quote = ref<BridgeQuoteResult | null>(null);
 
// Initialize client to get depositor address
const { client } = getSilentSwapClient({
  config: {
    environment: ENVIRONMENT.MAINNET,
  },
});
 
const { getQuote: getBridgeQuote, isLoading } = getQuote({ 
  address,
  depositorAddress: client.s0xDepositorAddress,
});
 
watch(amount, async (newAmount) => {
  if (!newAmount || parseFloat(newAmount) <= 0) {
    quote.value = null;
    return;
  }
 
  // Debounce
  const timeout = setTimeout(async () => {
    const result = await getBridgeQuote(
      1, // Ethereum
      '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
      parseUnits(newAmount, 6).toString(),
      43114, // Avalanche
      '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E' // USDC.e
    );
    quote.value = result;
  }, 800);
 
  return () => clearTimeout(timeout);
});
</script>

Using solveUsdcAmount

The solveUsdcAmount method calculates the optimal USDC amount for a given input:

<script setup lang="ts">
import { getQuote, getSilentSwapClient } from '@silentswap/vue';
import { ENVIRONMENT } from '@silentswap/sdk';
 
const { client } = getSilentSwapClient({
  config: {
    environment: ENVIRONMENT.MAINNET,
  },
});
 
const { solveUsdcAmount, isLoading } = getQuote({
  address,
  depositorAddress: client.s0xDepositorAddress,
});
 
const handleSolve = async () => {
  const result = await solveUsdcAmount(
    1, // Source chain ID (Ethereum)
    '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // Source token (USDC)
    '1000000', // Source amount (1 USDC)
    // Optional: depositCalldata for custom deposit transactions
  );
  
  if (result) {
    console.log('Optimal USDC amount:', result.usdcAmount);
    console.log('Retention rate:', result.retentionRate);
  }
};
</script>

Using estimateLive

The estimateLive method gets live estimates for ingress or egress directions with retention rate tracking:

<script setup lang="ts">
import { ref } from 'vue';
import { getQuote, getSilentSwapClient } from '@silentswap/vue';
import { ENVIRONMENT } from '@silentswap/sdk';
 
const { client } = getSilentSwapClient({
  config: {
    environment: ENVIRONMENT.MAINNET,
  },
});
 
const { estimateLive, ingressEstimates, egressEstimates } = getQuote({
  address,
  depositorAddress: client.s0xDepositorAddress,
});
 
const handleGetEstimate = async () => {
  // Get ingress estimate (source chain to Avalanche)
  const ingressResult = await estimateLive(
    'ingress',
    'eip155:1/erc20:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC on Ethereum
    1, // Chain ID
    '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // Token address
    100, // Amount in human-readable units
    1.0, // USD price per token
    // Optional: externalSignal for abort control
    // Optional: recipientAddress for Solana destinations
    // Optional: isReverseCalculation for output-to-input
    // Optional: targetAmount for reverse calculation
  );
 
  if (ingressResult) {
    console.log('Retention rate:', ingressResult.estimate.samples[0]?.retention);
    console.log('Gas amount:', ingressResult.gasAmount);
    console.log('Provider:', ingressResult.provider);
  }
};
</script>

Best Practices

  1. Debounce Quote Requests - Don't fetch quotes on every keystroke
  2. Handle Loading States - Show loading indicators while fetching
  3. Cache Quotes - Store quotes locally to avoid unnecessary requests
  4. Validate Amounts - Check that amounts are valid before fetching quotes
  5. Handle Errors Gracefully - Provide fallback UI when quotes fail

Next Steps