> ## Documentation Index
> Fetch the complete documentation index at: https://docs.crossmint.com/llms.txt
> Use this file to discover all available pages before exploring further.

# LI.FI

> Bridge tokens between chains using Crossmint wallets and LI.FI

<Warning>
  **You are viewing docs for the previous version of the Wallets SDK.** We recommend upgrading to V1.
  See the [updated version of this page](/wallets/guides/wallet-extensions/bridge-lifi) or the [V1 migration guide](/wallets/guides/migrate-to-v1).
</Warning>

This guide explains how to bridge tokens across chains using the <a href="https://docs.li.fi/li.fi-api/li.fi-api" target="_blank">LI.FI</a> API with Crossmint wallets. LI.FI aggregates bridges and DEXs to find optimal cross-chain routes.

## Prerequisites

To use LI.FI bridging with Crossmint wallets, you need:

* A Crossmint [wallet](/wallets/v0/guides/create-wallet) on any supported EVM chain
* A **production** **API Key** with the scope: `wallets:transactions.create` (create in the <a href="https://www.crossmint.com/console" target="_blank">Production Console</a>)

This guide uses Base → Polygon as an example. To follow along, you will also need:

* USDC on Base mainnet in the wallet
* ETH on Base for gas fees (not required if [gas sponsorship](/wallets/guides/gas-sponsorship) is enabled)

You can adapt the code to bridge between any chains and tokens that LI.FI supports. See [Customizing the Bridge](#customizing-the-bridge) below.

## Bridge Tokens

High level steps to bridging tokens with LI.FI and Crossmint:

1. Request a bridge quote from the LI.FI API
2. Approve the LI.FI router to spend the source token
3. Execute the bridge transaction using the quote calldata
4. Poll the LI.FI status endpoint until the bridge completes

<Warning>
  Cross-chain bridges operate on mainnet only. The wallet must hold sufficient tokens on the source chain and ETH for gas fees.
</Warning>

<Tabs>
  <Tab title="React">
    ```typescript theme={null}
    import { useWallet, EVMWallet } from "@crossmint/client-sdk-react-ui";
    import { encodeFunctionData, erc20Abi, parseUnits } from "viem";

    const LIFI_API = "https://li.quest/v1";
    const FROM_CHAIN = "8453"; // Base
    const TO_CHAIN = "137"; // Polygon
    const FROM_TOKEN = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"; // USDC on Base
    const TO_TOKEN = "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"; // USDC on Polygon
    const USDC_DECIMALS = 6;

    export function BridgeComponent() {
        const { wallet } = useWallet();

        async function bridge(amount: string) {
            if(!wallet) return;
            const evmWallet = EVMWallet.from(wallet);

            // 1. Get a bridge quote from the LI.FI API
            const quoteRes = await fetch(
                `${LIFI_API}/quote?` +
                    new URLSearchParams({
                        fromChain: FROM_CHAIN,
                        toChain: TO_CHAIN,
                        fromToken: FROM_TOKEN,
                        toToken: TO_TOKEN,
                        fromAmount: parseUnits(amount, USDC_DECIMALS).toString(),
                        fromAddress: wallet.address,
                        integrator: "crossmint",
                    })
            );
            if (!quoteRes.ok) {
                throw new Error(`Quote request failed: ${quoteRes.status}`);
            }
            const quote = await quoteRes.json();

            // 2. Approve the LI.FI router to spend USDC
            if (quote.estimate.approvalAddress) {
                await evmWallet.sendTransaction({
                    to: FROM_TOKEN,
                    data: encodeFunctionData({
                        abi: erc20Abi,
                        functionName: "approve",
                        args: [
                            quote.estimate.approvalAddress,
                            parseUnits(amount, USDC_DECIMALS),
                        ],
                    }),
                });
            }

            // 3. Execute the bridge transaction
            const tx = await evmWallet.sendTransaction({
                to: quote.transactionRequest.to,
                data: quote.transactionRequest.data,
                value: quote.transactionRequest.value
                    ? BigInt(quote.transactionRequest.value)
                    : 0n,
            });

            // 4. Poll the LI.FI status endpoint until completion
            let status = "PENDING";
            while (status === "PENDING" || status === "NOT_FOUND") {
                await new Promise((r) => setTimeout(r, 5000));
                const statusRes = await fetch(
                    `${LIFI_API}/status?` +
                        new URLSearchParams({
                            txHash: tx.hash,
                            fromChain: FROM_CHAIN,
                            toChain: TO_CHAIN,
                        })
                );
                const s = await statusRes.json();
                status = s.status;
            }
        }

        return (
            <button onClick={() => bridge("5")}>Bridge Tokens</button>
        );
    }
    ```

    See the [React SDK reference](/sdk-reference/wallets/v0/react/hooks#wallet-methods) for more details.
  </Tab>

  <Tab title="Node.js">
    ```typescript theme={null}
    import { CrossmintWallets, createCrossmint, EVMWallet } from "@crossmint/wallets-sdk";
    import { encodeFunctionData, erc20Abi, parseUnits } from "viem";

    const crossmint = createCrossmint({
        apiKey: <YOUR_SERVER_API_KEY>,
    });
    const crossmintWallets = CrossmintWallets.from(crossmint);

    const wallet = await crossmintWallets.getWallet(
        "email:user@example.com:evm",
        { chain: "base", signer: { type: "email" } }
    );
    if(!wallet) throw new Error("Wallet not found");
    const evmWallet = EVMWallet.from(wallet);

    const LIFI_API = "https://li.quest/v1";
    const FROM_CHAIN = "8453"; // Base
    const TO_CHAIN = "137"; // Polygon
    const FROM_TOKEN = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"; // USDC on Base
    const TO_TOKEN = "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"; // USDC on Polygon
    const USDC_DECIMALS = 6;
    const amount = "5";

    // 1. Get a bridge quote from the LI.FI API
    const quoteRes = await fetch(
        `${LIFI_API}/quote?` +
            new URLSearchParams({
                fromChain: FROM_CHAIN,
                toChain: TO_CHAIN,
                fromToken: FROM_TOKEN,
                toToken: TO_TOKEN,
                fromAmount: parseUnits(amount, USDC_DECIMALS).toString(),
                fromAddress: wallet.address,
                integrator: "crossmint",
            })
    );
    if (!quoteRes.ok) {
        throw new Error(`Quote request failed: ${quoteRes.status}`);
    }
    const quote = await quoteRes.json();

    // 2. Approve the LI.FI router to spend USDC
    if (quote.estimate.approvalAddress) {
        await evmWallet.sendTransaction({
            to: FROM_TOKEN,
            data: encodeFunctionData({
                abi: erc20Abi,
                functionName: "approve",
                args: [
                    quote.estimate.approvalAddress,
                    parseUnits(amount, USDC_DECIMALS),
                ],
            }),
        });
    }

    // 3. Execute the bridge transaction
    const tx = await evmWallet.sendTransaction({
        to: quote.transactionRequest.to,
        data: quote.transactionRequest.data,
        value: quote.transactionRequest.value
            ? BigInt(quote.transactionRequest.value)
            : 0n,
    });

    // 4. Poll the LI.FI status endpoint until completion
    let status = "PENDING";
    while (status === "PENDING" || status === "NOT_FOUND") {
        await new Promise((r) => setTimeout(r, 5000));
        const statusRes = await fetch(
            `${LIFI_API}/status?` +
                new URLSearchParams({
                    txHash: tx.hash,
                    fromChain: FROM_CHAIN,
                    toChain: TO_CHAIN,
                })
        );
        const s = await statusRes.json();
        status = s.status;
    }

    console.log("Bridge complete!");
    ```
  </Tab>

  <Tab title="React Native">
    ```typescript theme={null}
    import { useWallet, EVMWallet } from "@crossmint/client-sdk-react-native-ui";
    import { View, Button } from "react-native";
    import { encodeFunctionData, erc20Abi, parseUnits } from "viem";

    const LIFI_API = "https://li.quest/v1";
    const FROM_CHAIN = "8453"; // Base
    const TO_CHAIN = "137"; // Polygon
    const FROM_TOKEN = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"; // USDC on Base
    const TO_TOKEN = "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"; // USDC on Polygon
    const USDC_DECIMALS = 6;

    export function BridgeComponent() {
        const { wallet } = useWallet();

        async function bridge(amount: string) {
            if(!wallet) return;
            const evmWallet = EVMWallet.from(wallet);

            // 1. Get a bridge quote from the LI.FI API
            const quoteRes = await fetch(
                `${LIFI_API}/quote?` +
                    new URLSearchParams({
                        fromChain: FROM_CHAIN,
                        toChain: TO_CHAIN,
                        fromToken: FROM_TOKEN,
                        toToken: TO_TOKEN,
                        fromAmount: parseUnits(amount, USDC_DECIMALS).toString(),
                        fromAddress: wallet.address,
                        integrator: "crossmint",
                    })
            );
            if (!quoteRes.ok) {
                throw new Error(`Quote request failed: ${quoteRes.status}`);
            }
            const quote = await quoteRes.json();

            // 2. Approve the LI.FI router to spend USDC
            if (quote.estimate.approvalAddress) {
                await evmWallet.sendTransaction({
                    to: FROM_TOKEN,
                    data: encodeFunctionData({
                        abi: erc20Abi,
                        functionName: "approve",
                        args: [
                            quote.estimate.approvalAddress,
                            parseUnits(amount, USDC_DECIMALS),
                        ],
                    }),
                });
            }

            // 3. Execute the bridge transaction
            const tx = await evmWallet.sendTransaction({
                to: quote.transactionRequest.to,
                data: quote.transactionRequest.data,
                value: quote.transactionRequest.value
                    ? BigInt(quote.transactionRequest.value)
                    : 0n,
            });

            // 4. Poll the LI.FI status endpoint until completion
            let status = "PENDING";
            while (status === "PENDING" || status === "NOT_FOUND") {
                await new Promise((r) => setTimeout(r, 5000));
                const statusRes = await fetch(
                    `${LIFI_API}/status?` +
                        new URLSearchParams({
                            txHash: tx.hash,
                            fromChain: FROM_CHAIN,
                            toChain: TO_CHAIN,
                        })
                );
                const s = await statusRes.json();
                status = s.status;
            }
        }

        return (
            <View>
                <Button title="Bridge Tokens" onPress={() => bridge("5")} />
            </View>
        );
    }
    ```

    See the [React Native SDK reference](/sdk-reference/wallets/v0/react-native/hooks#wallet-methods) for more details.
  </Tab>

  <Tab title="Swift">
    ```swift theme={null}
    import CrossmintClient
    import Wallet
    import Foundation

    let sdk = CrossmintSDK.shared

    let wallet = try await sdk.crossmintWallets
        .getOrCreateWallet(
            chain: .base,
            signer: .email(email: "user@example.com")
        )

    let evmWallet = try EVMWallet.from(wallet: wallet)

    let fromChain = "8453"
    let toChain = "137"
    let fromToken = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
    let toToken = "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"
    let amount = "5000000" // 5 USDC (6 decimals)

    // 1. Get a bridge quote from the LI.FI API
    var quoteURL = URLComponents(string: "https://li.quest/v1/quote")!
    quoteURL.queryItems = [
        URLQueryItem(name: "fromChain", value: fromChain),
        URLQueryItem(name: "toChain", value: toChain),
        URLQueryItem(name: "fromToken", value: fromToken),
        URLQueryItem(name: "toToken", value: toToken),
        URLQueryItem(name: "fromAmount", value: amount),
        URLQueryItem(name: "fromAddress", value: wallet.address),
        URLQueryItem(name: "integrator", value: "crossmint"),
    ]

    let (quoteData, quoteResponse) = try await URLSession.shared.data(from: quoteURL.url!)
    guard let httpResponse = quoteResponse as? HTTPURLResponse,
          httpResponse.statusCode == 200 else {
        throw URLError(.badServerResponse)
    }
    let quote = try JSONSerialization.jsonObject(with: quoteData) as! [String: Any]
    let estimate = quote["estimate"] as! [String: Any]
    let txRequest = quote["transactionRequest"] as! [String: Any]

    // 2. Approve the LI.FI router to spend USDC
    //    Encodes ERC-20 approve(address,uint256) — selector 0x095ea7b3
    //    Note: UInt64 supports up to ~18.4e18. For tokens with 18 decimals
    //    and large amounts, use a big-integer hex conversion instead.
    func leftPad(_ str: String, toLength len: Int) -> String {
        String(repeating: "0", count: max(0, len - str.count)) + str
    }

    if let approvalAddress = estimate["approvalAddress"] as? String {
        let addr = leftPad(String(approvalAddress.dropFirst(2)), toLength: 64)
        let amt = leftPad(String(UInt64(amount)!, radix: 16), toLength: 64)
        let approveData = "0x095ea7b3" + addr + amt
        let _ = try await evmWallet.sendTransaction(
            to: fromToken,
            value: "0",
            data: approveData
        )
    }

    // 3. Execute the bridge transaction
    let result = try await evmWallet.sendTransaction(
        to: txRequest["to"] as! String,
        value: (txRequest["value"] as? String) ?? "0",
        data: txRequest["data"] as! String
    )

    // 4. Poll the LI.FI status endpoint until completion
    var bridgeStatus = "PENDING"
    while bridgeStatus == "PENDING" || bridgeStatus == "NOT_FOUND" {
        try await Task.sleep(nanoseconds: 5_000_000_000)

        var statusURL = URLComponents(string: "https://li.quest/v1/status")!
        statusURL.queryItems = [
            URLQueryItem(name: "txHash", value: result.hash),
            URLQueryItem(name: "fromChain", value: fromChain),
            URLQueryItem(name: "toChain", value: toChain),
        ]
        let (statusData, _) = try await URLSession.shared.data(from: statusURL.url!)
        let statusJSON = try JSONSerialization.jsonObject(with: statusData) as! [String: Any]
        bridgeStatus = statusJSON["status"] as! String
    }
    ```

    See the [Swift SDK reference](/sdk-reference/wallets/swift/classes/evmwallet) for more details.
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    import com.crossmint.kotlin.compose.LocalCrossmintSDK
    import com.crossmint.kotlin.types.EVMChain
    import com.crossmint.kotlin.types.SignerData
    import kotlinx.coroutines.Dispatchers
    import kotlinx.coroutines.delay
    import kotlinx.coroutines.withContext
    import kotlinx.serialization.json.Json
    import kotlinx.serialization.json.buildJsonObject
    import kotlinx.serialization.json.contentOrNull
    import kotlinx.serialization.json.jsonObject
    import kotlinx.serialization.json.jsonPrimitive
    import kotlinx.serialization.json.put
    import kotlinx.serialization.json.putJsonArray
    import kotlinx.serialization.json.putJsonObject
    import java.net.HttpURLConnection
    import java.net.URL

    val API_KEY = "<YOUR_API_KEY>"
    val SIGNER_EMAIL = "user@example.com"
    val LIFI_API = "https://li.quest/v1"
    val CROSSMINT_API = "https://www.crossmint.com/api/2025-06-09"
    val FROM_CHAIN = "8453"  // Base
    val TO_CHAIN = "137"     // Polygon
    val FROM_TOKEN = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"  // USDC on Base
    val TO_TOKEN = "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"    // USDC on Polygon
    val AMOUNT = "5000000"   // 5 USDC (6 decimals)

    // Access the SDK — must be called inside a CrossmintSDKProvider composable
    val sdk = LocalCrossmintSDK.current
    val wallet = sdk.crossmintWallets
        .getOrCreateWallet(EVMChain.Base, SignerData.Email(SIGNER_EMAIL))
        .getOrThrow()

    val json = Json { ignoreUnknownKeys = true }

    // 1. Get a bridge quote from the LI.FI API
    val quoteText = withContext(Dispatchers.IO) {
        val conn = URL(
            "$LIFI_API/quote?fromChain=$FROM_CHAIN&toChain=$TO_CHAIN" +
                "&fromToken=$FROM_TOKEN&toToken=$TO_TOKEN" +
                "&fromAmount=$AMOUNT&fromAddress=${wallet.address}&integrator=crossmint"
        ).openConnection() as HttpURLConnection
        check(conn.responseCode == 200) { "Quote request failed: ${conn.responseCode}" }
        conn.inputStream.bufferedReader().readText()
    }
    val quote = json.parseToJsonElement(quoteText).jsonObject
    val estimate = quote["estimate"]!!.jsonObject
    val txRequest = quote["transactionRequest"]!!.jsonObject

    // The Kotlin SDK's send() only supports simple token transfers, not raw calldata.
    // The REST API is used here to create approval and bridge transactions directly.
    suspend fun sendEvmTransaction(to: String, data: String, value: String = "0"): String {
        val body = buildJsonObject {
            putJsonObject("params") {
                put("chain", "base")
                put("signer", "email:$SIGNER_EMAIL")
                putJsonArray("calls") {
                    add(buildJsonObject {
                        put("to", to)
                        put("value", value)
                        put("data", data)
                    })
                }
            }
        }.toString()
        val responseText = withContext(Dispatchers.IO) {
            val conn = URL("$CROSSMINT_API/wallets/${wallet.address}/transactions")
                .openConnection() as HttpURLConnection
            conn.requestMethod = "POST"
            conn.setRequestProperty("X-API-KEY", API_KEY)
            conn.setRequestProperty("Content-Type", "application/json")
            conn.doOutput = true
            conn.outputStream.write(body.toByteArray())
            val code = conn.responseCode
            if (code !in 200..299) {
                val err = conn.errorStream?.bufferedReader()?.readText()
                error("Transaction request failed ($code): $err")
            }
            conn.inputStream.bufferedReader().readText()
        }
        val transactionId = json.parseToJsonElement(responseText)
            .jsonObject["id"]!!.jsonPrimitive.content
        val tx = wallet.approve(transactionId).getOrThrow()
        return tx.onChain.txId ?: tx.onChain.userOperationHash
            ?: error("Transaction completed but no hash was returned")
    }

    // 2. Approve the LI.FI router to spend USDC
    //    Encodes ERC-20 approve(address,uint256) — selector 0x095ea7b3
    //    Note: Long supports up to ~9.2e18. For tokens with 18 decimals
    //    and large amounts, use a BigInteger hex conversion instead.
    val approvalAddress = estimate["approvalAddress"]?.jsonPrimitive?.contentOrNull
    if (approvalAddress != null) {
        val addr = approvalAddress.removePrefix("0x").padStart(64, '0')
        val amt = AMOUNT.toLong().toString(16).padStart(64, '0')
        sendEvmTransaction(to = FROM_TOKEN, data = "0x095ea7b3$addr$amt")
    }

    // 3. Execute the bridge transaction
    val txHash = sendEvmTransaction(
        to = txRequest["to"]!!.jsonPrimitive.content,
        data = txRequest["data"]!!.jsonPrimitive.content,
        value = txRequest["value"]?.jsonPrimitive?.contentOrNull ?: "0",
    )

    // 4. Poll the LI.FI status endpoint until completion
    var bridgeStatus = "PENDING"
    while (bridgeStatus == "PENDING" || bridgeStatus == "NOT_FOUND") {
        delay(5_000)
        val statusText = withContext(Dispatchers.IO) {
            val conn = URL("$LIFI_API/status?txHash=$txHash&fromChain=$FROM_CHAIN&toChain=$TO_CHAIN")
                .openConnection() as HttpURLConnection
            check(conn.responseCode == 200) { "Status request failed: ${conn.responseCode}" }
            conn.inputStream.bufferedReader().readText()
        }
        bridgeStatus = json.parseToJsonElement(statusText).jsonObject["status"]!!.jsonPrimitive.content
    }
    ```

    See the [Kotlin SDK reference](/sdk-reference/wallets/kotlin/classes/wallet) for more details.
  </Tab>

  <Tab title="REST">
    Transactions must be approved by one of the wallet's [signers](/wallets/v0/concepts/wallet-signers).
    The SDK handles this automatically, but with the REST API you must [approve the transaction](/api-reference/wallets/approve-transaction) to complete it.

    <Steps>
      <Step title="Get a bridge quote from the LI.FI API">
        Call the <a href="https://docs.li.fi/li.fi-api/li.fi-api" target="_blank">LI.FI API</a> `/quote` endpoint with the source and destination chain, token addresses, and amount.

        <CodeGroup>
          ```bash cURL theme={null}
          curl --request GET \
              --url 'https://li.quest/v1/quote?fromChain=8453&toChain=137&fromToken=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913&toToken=0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359&fromAmount=5000000&fromAddress=<wallet-address>&integrator=crossmint' \
              --header 'Content-Type: application/json'
          ```

          ```js Node.js theme={null}
          const params = new URLSearchParams({
              fromChain: "8453",
              toChain: "137",
              fromToken:
                  "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
              toToken:
                  "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
              fromAmount: "5000000",
              fromAddress: "<wallet-address>",
              integrator: "crossmint",
          });

          const response = await fetch(
              `https://li.quest/v1/quote?${params}`
          );
          const quote = await response.json();
          ```

          ```python Python theme={null}
          import requests

          response = requests.get(
              "https://li.quest/v1/quote",
              params={
                  "fromChain": "8453",
                  "toChain": "137",
                  "fromToken": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
                  "toToken": "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
                  "fromAmount": "5000000",
                  "fromAddress": "<wallet-address>",
                  "integrator": "crossmint",
              }
          )
          quote = response.json()
          ```
        </CodeGroup>

        The response includes `estimate.approvalAddress` and `transactionRequest` with the bridge calldata.
      </Step>

      <Step title="Send the approve and bridge transactions">
        Use the quote response to send two transactions via the Crossmint REST API:

        1. **Approve** — call the USDC contract with ERC-20 `approve` calldata targeting `estimate.approvalAddress`
        2. **Bridge** — send `transactionRequest.to`, `transactionRequest.data`, and `transactionRequest.value`

        Follow the steps in the [Send a transaction](/wallets/v0/guides/send-transaction-evm#rest) guide to submit each transaction via the Crossmint REST API.
      </Step>

      <Step title="Poll for bridge status">
        Call the LI.FI `/status` endpoint every five seconds until the bridge completes.

        <CodeGroup>
          ```bash cURL theme={null}
          curl --request GET \
              --url 'https://li.quest/v1/status?txHash=<bridge-tx-hash>&fromChain=8453&toChain=137' \
              --header 'Content-Type: application/json'
          ```

          ```js Node.js theme={null}
          const statusParams = new URLSearchParams({
              txHash: "<bridge-tx-hash>",
              fromChain: "8453",
              toChain: "137",
          });

          const statusRes = await fetch(
              `https://li.quest/v1/status?${statusParams}`
          );
          const status = await statusRes.json();
          // status.status is "DONE", "FAILED",
          // "PENDING", or "NOT_FOUND"
          ```

          ```python Python theme={null}
          import requests

          response = requests.get(
              "https://li.quest/v1/status",
              params={
                  "txHash": "<bridge-tx-hash>",
                  "fromChain": "8453",
                  "toChain": "137",
              }
          )
          status = response.json()
          # status["status"] is "DONE", "FAILED",
          # "PENDING", or "NOT_FOUND"
          ```
        </CodeGroup>

        The bridge is complete when `status` is `DONE`. If `FAILED`, check the transaction on the block explorer for details.
      </Step>
    </Steps>
  </Tab>
</Tabs>

## Customizing the Bridge

You can bridge any token pair that LI.FI supports by changing the chain and token constants. You can also perform cross-chain swaps — changing both the asset and the chain in a single operation:

```typescript theme={null}
const FROM_CHAIN = "1"; // Ethereum
const TO_CHAIN = "42161"; // Arbitrum
const FROM_TOKEN =
    "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"; // USDC on Ethereum
const TO_TOKEN =
    "0xaf88d065e77c8cC2239327C5EDb3A432268e5831"; // USDC on Arbitrum
```

See the full list of supported chains and tokens in the <a href="https://docs.li.fi/introduction/chains#chain-overview" target="_blank">LI.FI Documentation</a>.

## Troubleshooting

<AccordionGroup>
  <Accordion title="Transaction fails with insufficient balance">
    Verify the wallet holds enough USDC on Base and ETH for gas fees.
    Use the [Check Balances](/wallets/v0/guides/check-balances) guide to confirm token balances before bridging.
  </Accordion>

  <Accordion title="ERC-20 approval transaction is rejected">
    Ensure the approval amount is greater than or equal to the bridge amount.
    If a previous approval exists for a smaller amount, send a new approval transaction with the correct value.
    Verify the API key has the `wallets:transactions.create` scope.
  </Accordion>

  <Accordion title="Bridge status stays PENDING for a long time">
    Cross-chain bridges can take several minutes depending on the route and chain congestion.
    The LI.FI `/status` endpoint returns `PENDING` until both the source and destination chain transactions confirm.
    If the status does not change after 10 minutes, check the source transaction on a block explorer to verify it was included.
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Check Balances" icon="wallet" href="/wallets/v0/guides/check-balances">
    Verify updated token balances after bridging on any chain
  </Card>

  <Card title="Send a Transaction" icon="arrow-right" href="/wallets/v0/guides/transfer-tokens">
    Transfer tokens from any chain
  </Card>
</CardGroup>
