LI.FI Documentation
LI.FI WebsiteAPI ReferenceHelp / FAQ / Create support ticketRequest API Key
  • 🏡Getting Started
    • ❓What is LI.FI
    • 🌟Why LI.FI?
    • 🆚LI.FI vs Aggregators/DEXs/Bridges
    • 📖LI.FI Terminology
    • ❓FAQ
    • 💡Use Cases
      • Mobile/Gaming Wallets
    • 🏹LI.FI vs. Other Aggregators
    • 🤝Partnership
    • 🌐Powered by LI.FI
  • 🔐Security First
  • ✅List: Chains, Bridges, DEX Aggregators, Solvers
  • 💲Monetization / Take Fees
  • 🔎Transaction Explorer
  • 🔏Rate Limits & API Key
  • How to get integrated by LI.FI?
    • For Bridges
    • For DEXs/Aggregators/Solvers
  • 🆘Technical FAQ
  • LI.FI PRODUCTS
    • Glacis
    • LI.FI Solver
    • LI.FI Intents System
  • LI.FI API
    • ⚙️LI.FI API
      • Transferring Tokens (Example)
      • Requesting supported Chains
      • Requesting all supported Tools
      • Requesting all known Tokens
      • Getting Token Information
      • Getting all possible Connections
      • Requesting a Quote
        • Token Transfer
        • Optimizing quote response timing
        • Cross-Chain Contract Calls
        • Possible Tool Errors
        • Testing your integration
      • Status of a Transaction
      • Requesting Analytics Data
    • ⚔️TX-Batching aka "Zaps"
    • 🏄Solana
      • Request examples
    • 🪙Bitcoin
      • Request examples
    • ⛽LI.Fuel
  • Integrate LI.FI SDK
    • 🚀LI.FI SDK Overview
    • 📦Install LI.FI SDK
    • ⚙️Configure SDK
    • 🪐Configure SDK Providers
    • 📜Request Routes/Quotes
    • 🎯Execute Routes/Quotes
    • ⛓️Chains and Tools
    • 💰Token Management
    • 🕵️Testing Integration
    • 🚗Migrate from v2 to v3
  • INTEGRATE LI.FI WIDGET
    • 🧩LI.FI Widget Overview
    • 📦Install Widget
    • 🎮Select Widget Variants
    • ⚙️Configure Widget
    • 🎨Customize Widget
    • ⚡Widget Events
    • 👛Wallet Management
    • 🌍Internationalization
    • ⚛️Compatibility with Next.js, Remix, Nuxt, etc.
    • 🛣️React Router Compatibility
    • 📖Widget API Reference
    • 🚗Migrate from v2 to v3
  • Smart Contracts
    • Overview
    • Deployments/Contract Addresses
    • Audits
  • Support & Misc.
    • API Status
    • Technical Help Desk & FAQ
    • Create a Partner Ticket
    • Discord Support
    • Telegram Support
    • Twitter
    • Github
    • Licenses
Powered by GitBook
LogoLogo

Connect with us

  • Github
  • Twitter
  • Discord
  • LinkedIn

More Information

  • Help Desk / FAQ
  • API Reference
  • Website
On this page
  • Step 1: Requesting a Quote
  • Step 2: Sending the Transaction
  • Step 3: Waiting for the transfer to complete
  • Links to the example transactions
  • All things plugged together
  • Checking and setting the Allowance

Was this helpful?

Export as PDF
  1. LI.FI API
  2. LI.FI API

Transferring Tokens (Example)

Transferring from one token to another, across one or more chains, is simple.

Last updated 8 months ago

Was this helpful?

The following section will explain step by step how to transfer tokens across one or more chains.

Here you can find our full

Step 1: Requesting a Quote

You can request a quote either by specifying the fromAmount or toAmount

Quoting by Sending Amount (fromAmount)

To generate a quote based on the amount you are sending, use the /quote endpoint. This method is useful when you know exactly how much you want to send and want to calculate how much the recipient will receive.

API reference for endpoint

Example: Requesting a quote for transferring 1 USDC from Gnosis to USDC on Polygon:

const getQuote = async (fromChain, toChain, fromToken, toToken, fromAmount, fromAddress) => {
    const result = await axios.get('https://li.quest/v1/quote', {
        params: {
            fromChain,
            toChain,
            fromToken,
            toToken,
            fromAmount,
            fromAddress,
        }
    });
    return result.data;
}

const fromChain = 'DAI';
const fromToken = 'USDC';
const toChain = 'POL';
const toToken = 'USDC';
const fromAmount = '1000000';
const fromAddress = YOUR_WALLET_ADDRESS;

const quote = await getQuote(fromChain, toChain, fromToken, toToken, fromAmount, fromAddress);

Quoting by Receiving Amount (toAmount)

To generate a quote based on the amount the recipient will receive, use the /quote/toAmount endpoint. This method is helpful when you want to ensure that the recipient receives an exact amount of tokens.

Example: Requesting a quote for ensuring the recipient gets 1 USDC on Polygon:

const getQuoteByReceivingAmount = async (fromChain, toChain, fromToken, toToken, toAmount, fromAddress) => {
    const result = await axios.get('https://li.quest/v1/quote/toAmount', {
        params: {
            fromChain,
            toChain,
            fromToken,
            toToken,
            toAmount,
            fromAddress,
        }
    });
    return result.data;
}

const fromChain = 'DAI';
const fromToken = 'USDC';
const toChain = 'POL';
const toToken = 'USDC';
const toAmount = '1000000';  // Amount the recipient should receive (e.g., 1 USDC = 1000000)
const fromAddress = YOUR_WALLET_ADDRESS;

const quote = await getQuoteByReceivingAmount(fromChain, toChain, fromToken, toToken, toAmount, fromAddress);

The recipient might receive slightly more toToken than requested due to slippage or rounding

The quote response contains a transactionRequest object which can be directly passed on to your wallet/signer.

Step 2: Sending the Transaction

After receiving a quote, the transaction has to be sent to trigger the transfer.

Firstly, the wallet has to be configured. The following example connects your wallet to the Gnosis Chain.

const provider = new ethers.providers.JsonRpcProvider('https://rpc.xdaichain.com/', 100);
const wallet = ethers.Wallet.fromMnemonic(YOUR_PERSONAL_MNEMONIC).connect(
    provider
);

Afterward, the transaction can be sent using the transactionRequest inside the previously retrieved quote:

const tx = await wallet.sendTransaction(quote.transactionRequest);
await tx.wait();

For simple swaps on a single chain, this is enough. For cross-chain transfers, the processing takes a bit longer. To handle this the API provides an endpoint to check the transfer status.

Step 3: Waiting for the transfer to complete

Checking the status of the transfer is only necessary for cross-chain transfers

To check if the token was successfully sent to the receiving chain, the /status endpoint can be called:

const getStatus = async (bridge, fromChain, toChain, txHash) => {
    const result = await axios.get('https://li.quest/v1/status', {
        params: {
            bridge,
            fromChain,
            toChain,
            txHash,
        }
    });
    return result.data;
}

result = await getStatus(quote.tool, fromChain, toChain, tx.hash);

Links to the example transactions

Here you can find links to the sending and receiving transactions for the transfer from USDC on Gnosis to USDC on Polygon.

All things plugged together

The whole process then looks like this:

const ethers = require('ethers');
const axios = require('axios');

const API_URL = 'https://li.quest/v1';

// Get a quote for your desired transfer
const getQuote = async (fromChain, toChain, fromToken, toToken, fromAmount, fromAddress) => {
    const result = await axios.get(`${API_URL}/quote`, {
        params: {
            fromChain,
            toChain,
            fromToken,
            toToken,
            fromAmount,
            fromAddress,
        }
    });
    return result.data;
}

// Check the status of your transfer
const getStatus = async (bridge, fromChain, toChain, txHash) => {
    const result = await axios.get(`${API_URL}/status`, {
        params: {
            bridge,
            fromChain,
            toChain,
            txHash,
        }
    });
    return result.data;
}

const fromChain = 'DAI';
const fromToken = 'USDC';
const toChain = 'POL';
const toToken = 'USDC';
const fromAmount = '1000000';
const fromAddress = YOUR_WALLET_ADDRESS;

// Set up your wallet
const provider = new ethers.providers.JsonRpcProvider('https://rpc.xdaichain.com/', 100);
const wallet = ethers.Wallet.fromMnemonic(YOUR_PERSONAL_MNEMONIC).connect(
    provider
);

const run = async () => {
    const quote = await getQuote(fromChain, toChain, fromToken, toToken, fromAmount, fromAddress);
    const tx = await wallet.sendTransaction(quote.transactionRequest);

    await tx.wait();

    // Only needed for cross chain transfers
    if (fromChain !== toChain) {
        let result;
        do {
            result = await getStatus(quote.tool, fromChain, toChain, tx.hash);
        } while (result.status !== 'DONE' && result.status !== 'FAILED')
    }
}

run().then(() => {
    console.log('DONE!')
});

Checking and setting the Allowance

Before any transaction can be sent, it must be made sure that the user is allowed to send the requested amount from his wallet.

This can be achieved like this:

const { Contract } = require('ethers');

const ERC20_ABI = [
    {
        "name": "approve",
        "inputs": [
            {
                "internalType": "address",
                "name": "spender",
                "type": "address"
            },
            {
                "internalType": "uint256",
                "name": "amount",
                "type": "uint256"
            }
        ],
        "outputs": [
            {
                "internalType": "bool",
                "name": "",
                "type": "bool"
            }
        ],
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "name": "allowance",
        "inputs": [
            {
                "internalType": "address",
                "name": "owner",
                "type": "address"
            },
            {
                "internalType": "address",
                "name": "spender",
                "type": "address"
            }
        ],
        "outputs": [
            {
                "internalType": "uint256",
                "name": "",
                "type": "uint256"
            }
        ],
        "stateMutability": "view",
        "type": "function"
    }
];

// Get the current allowance and update it if needed
const checkAndSetAllowance = async (wallet, tokenAddress, approvalAddress, amount) => {
    // Transactions with the native token don't need approval
    if (tokenAddress === ethers.constants.AddressZero) {
        return
    }

    const erc20 = new Contract(tokenAddress, ERC20_ABI, wallet);
    const allowance = await erc20.allowance(await wallet.getAddress(), approvalAddress);

    if (allowance.lt(amount)) {
        const approveTx = await erc20.approve(approvalAddress, amount);
        await approveTx.wait();
    }
}

await checkAndSetAllowance(wallet, quote.action.fromToken.address, quote.estimate.approvalAddress, fromAmount);

API reference for endpoint

To learn more about quotes, head over to our guide.

If you want to learn more about the status endpoint and how to deal with the potential results check our .

Sending:

Receiving:

⚙️
API reference
/quote
/quote/toAmount
Requesting a Quote
Status Guide
https://blockscout.com/xdai/mainnet/tx/0x32375265d54d2897f776b10729fb7ba8f7ed4cb329364d8fa0e13c89ecbb9085
https://polygonscan.com/tx/0x9c762972efd140124a7a3c2753f56dac35968b279dd678f043e716fe0d0dbc67