# Integrating the LI.FI SDK

The [**LI.FI**](https://li.fi/) **SDK** lets you add cross-chain and same-chain swaps and bridging directly inside your Somnia dApp. Instead of redirecting users to an external bridge, you request a route, execute it, and track its status. All from your own interface.

Under the hood, LI.FI aggregates dozens of bridges and DEX aggregators across 50+ chains, normalises token standards, and picks the optimal route. Your dApp only talks to one SDK.

In this guide, you'll learn how to:

* Install and configure the LI.FI SDK for Somnia
* Request a quote to **bridge assets into Somnia**
* Execute the route and **track its status** in your app
* Query supported **chains, tokens, and tools** to keep your UI accurate

{% hint style="info" %}
The LI.FI SDK is a JavaScript/TypeScript toolkit that runs in both front-end and back-end environments. This guide shows the front-end (browser wallet) flow. For the full API surface and the latest details, always refer to the official docs: <https://docs.li.fi/sdk/overview>.
{% endhint %}

## Prerequisites

Before you start, ensure you have:

* A working JavaScript/TypeScript dApp (React or Next.js recommended). This guide assumes familiarity with both.
* Wallet connection already set up. If not, see [Wallet Integration and Auth](/developer/building-dapps/wallet-integration-and-auth.md).
* [Node.js](https://nodejs.org/) 18+ and a package manager (npm, pnpm, or yarn).
* The Somnia network details on hand:

| Property        | Value                                       |
| --------------- | ------------------------------------------- |
| Chain ID        | `5031`                                      |
| Native currency | SOMI (18 decimals)                          |
| RPC URL         | `https://api.infra.mainnet.somnia.network/` |
| Explorer        | `https://explorer.somnia.network`           |

## Step 1: Install the SDK

The SDK uses [Viem](https://viem.sh/) under the hood, so install it alongside.

```bash
npm install @lifi/sdk viem
```

{% hint style="info" %}
This guide was written and verified against `@lifi/sdk` v3.16.x and `viem` v2.x. API surfaces evolve — if a signature differs in your version, the [official SDK docs](https://docs.li.fi/sdk/overview) are the source of truth.
{% endhint %}

## Step 2: Configure the SDK

Call `createConfig` once when your app boots. The `integrator` string identifies your app to LI.FI (and is used for fee monetisation later).

Because Somnia may not ship in Viem's default chain list, define it explicitly with `defineChain` so the SDK's wallet provider can switch to it.

{% code title="lib/lifi.ts" %}

```typescript
import { createConfig, EVM, ChainId } from '@lifi/sdk';
import { createWalletClient, custom, defineChain } from 'viem';
import { mainnet, arbitrum, optimism, base } from 'viem/chains';
import { switchChain } from 'viem/actions';

// Somnia may be newer than the ChainId enum in your installed SDK version,
// so cast the numeric id where the SDK's TypeScript types expect a ChainId.
const SOMNIA = 5031 as ChainId;

// Define Somnia Mainnet for Viem
export const somnia = defineChain({
  id: 5031,
  name: 'Somnia',
  nativeCurrency: { name: 'Somnia', symbol: 'SOMI', decimals: 18 },
  rpcUrls: {
    default: { http: ['https://api.infra.mainnet.somnia.network/'] },
  },
  blockExplorers: {
    default: { name: 'Somnia Explorer', url: 'https://explorer.somnia.network' },
  },
});

// Chains your dApp will let users move assets between
const chains = [mainnet, arbitrum, optimism, base, somnia];

// A Viem wallet client backed by the user's injected wallet (e.g. MetaMask)
const walletClient = createWalletClient({
  chain: mainnet,
  transport: custom(window.ethereum!),
});

createConfig({
  integrator: 'YourSomniaDApp', // required; max 23 chars (letters, numbers, . - _)
  rpcUrls: {
    [SOMNIA]: ['https://api.infra.mainnet.somnia.network/'], // let the SDK use Somnia's RPC
  },
  providers: [
    EVM({
      getWalletClient: async () => walletClient,
      switchChain: async (chainId) => {
        await switchChain(walletClient, { id: chainId });
        return walletClient;
      },
    }),
  ],
});
```

{% endcode %}

{% hint style="success" %}
The SDK automatically fetches chain, bridge, and token metadata from LI.FI at runtime — you don't have to hard-code bridge addresses. The `defineChain` block is only needed so the wallet can **switch networks** during execution, and `rpcUrls` lets the SDK use your preferred Somnia endpoint. For production, pass an authenticated RPC URL rather than a public one.
{% endhint %}

{% hint style="warning" %}
**TypeScript note:** the SDK's types use a `ChainId` enum for parameters like `rpcUrls` keys and `getTokens({ chains })`. If your installed SDK version predates Somnia's addition to that enum, the raw number `5031` will fail to type-check — cast it with `5031 as ChainId` (shown above). The runtime value is unaffected; this is purely a type-level workaround. `getQuote`'s `fromChain` / `toChain` accept a plain `number` and need no cast.
{% endhint %}

## Step 3: Request a quote

A **quote** is a single, ready-to-execute route with the optimal pricing LI.FI could find. The example below bridges **USDC on Arbitrum → USDC.e on Somnia** (routed via Stargate at the time of writing).

Amounts are always passed as strings in the token's **smallest unit** (USDC has 6 decimals, so `10` USDC = `"10000000"`). A chain's native token is represented by the zero address.

{% code title="Bridge USDC (Arbitrum) → USDC.e (Somnia)" %}

```typescript
import { getQuote } from '@lifi/sdk';

const quote = await getQuote({
  fromChain: 42161, // Arbitrum
  toChain: 5031,    // Somnia
  fromToken: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', // USDC on Arbitrum
  toToken: '0x28BEc7E30E6faee657a03e19Bf1128AaD7632A00',   // USDC.e (bridged USDC) on Somnia
  fromAmount: '10000000', // 10 USDC (6 decimals)
  fromAddress: userWalletAddress, // the connected wallet
});

console.log(quote.estimate.toAmount); // estimated USDC.e received (6 decimals)
```

{% endcode %}

### Tokens routable to Somnia

These are the tokens LI.FI can currently route to Somnia (Chain ID `5031`):

| Symbol | Address                                      | Decimals | Notes                   |
| ------ | -------------------------------------------- | -------- | ----------------------- |
| SOMI   | `0x0000000000000000000000000000000000000000` | 18       | Native gas token        |
| WSOMI  | `0x046EDe9564A72571df6F5e44d0405360c0f4dCab` | 18       | Wrapped SOMI            |
| USDC.e | `0x28BEc7E30E6faee657a03e19Bf1128AaD7632A00` | 6        | Bridged USDC (Stargate) |
| USDT   | `0x67B302E35Aef5EEE8c32D934F5856869EF428330` | 6        | Bridged USDT (Stargate) |
| WETH   | `0x936Ab8C674bcb567CD5dEB85D8A216494704E9D8` | 18       | Wrapped ETH             |

{% hint style="warning" %}
This list reflects LI.FI's coverage at the time of writing and grows over time. Always fetch the current set with `getTokens` at runtime rather than hard-coding it (see [Step 6](#step-6-keep-your-ui-in-sync)).
{% endhint %}

## Step 4: Execute the route

A quote must first be converted to a **route** with `convertQuoteToRoute`, then passed to `executeRoute`. The SDK handles token approvals, network switching, and signing through the wallet provider you configured in Step 2. Use `updateRouteHook` to react to progress in your UI.

```typescript
import { convertQuoteToRoute, executeRoute } from '@lifi/sdk';

// A quote cannot be executed directly — convert it to a route first
const route = convertQuoteToRoute(quote);

const executedRoute = await executeRoute(route, {
  updateRouteHook: (updatedRoute) => {
    // Called whenever the route changes during execution — drive your progress UI from here
    updatedRoute.steps.forEach((step, i) => {
      step.execution?.process.forEach((process) => {
        console.log(`Step ${i + 1}:`, process.type, process.status);
        if (process.txHash) console.log('  tx hash:', process.txHash);
      });
    });
  },
});
```

{% hint style="info" %}
`executeRoute` also accepts other hooks such as `acceptExchangeRateUpdateHook` (confirm a changed rate before continuing) and `switchChainHook`. See the official [Execute Routes](https://docs.li.fi/sdk/execute-routes) guide for the full list.
{% endhint %}

## Step 5: Handle the outcome

Status updates arrive through the `updateRouteHook` from Step 4, read each step's `execution.status` and `execution.process` to drive your UI. Cross-chain transfers don't always end in an exact 1:1 result, so handle the final states explicitly:

| Final state | Meaning                                                        | What to show the user                       |
| ----------- | -------------------------------------------------------------- | ------------------------------------------- |
| Completed   | Success, exact destination token received                      | "Funds arrived on Somnia"                   |
| Partial     | Success, but a different token was received (still full value) | "Completed, received an alternate token"    |
| Refunded    | The transfer failed and funds were returned                    | "Refunded on the source chain"              |
| Failed      | Execution failed                                               | Prompt the user to retry or contact support |

{% hint style="info" %}
A **same-chain** swap is atomic: it either fully succeeds or reverts. A **cross-chain** transfer can have the bridge succeed while the destination step fails, in that case the bridged asset is refunded on the destination chain.
{% endhint %}

To resume tracking an interrupted transfer (for example, after a page reload), the SDK can pick up an in-progress route again. See the official [Execute Routes](https://docs.li.fi/sdk/execute-routes) guide. For server-side or out-of-band status checks, query the REST [status endpoint](https://docs.li.fi/api-reference/check-the-status-of-a-cross-chain-transfer) directly.

## Step 6: Keep your UI in sync

Use the SDK's query helpers to populate dropdowns and **verify that Somnia routes and tokens are live** before showing them to users.

```typescript
import { ChainId, ChainType, getChains, getTokens, getTools } from '@lifi/sdk';

// Confirm Somnia (5031) is currently supported
const chains = await getChains({ chainTypes: [ChainType.EVM] });
const somniaSupported = chains.some((c) => c.id === 5031);

// Tokens available on Somnia — getTokens returns a map keyed by chain ID
// (cast 5031 to ChainId if your SDK version predates Somnia in the enum)
const { tokens } = await getTokens({ chains: [5031 as ChainId] });
const somniaTokens = tokens[5031] ?? [];

// Available bridges and exchanges
const { bridges, exchanges } = await getTools();
```

{% hint style="warning" %}
Somnia support on LI.FI is live and expanding. Treat `getChains` and `getTokens` as the source of truth at runtime rather than hard-coding lists, new tokens and bridges are added regularly.
{% endhint %}

## Monetization (optional)

Integrators can charge a fee on transactions routed through their app. Configure a fee when requesting a route and withdraw collected fees via LI.FI's Partner Portal.

See the official guide for the current setup: <https://docs.li.fi/sdk/monetize-sdk>.

## Troubleshooting

* **No route found:** Try a different token pair or a larger amount. Very small amounts may not cover bridge/gas costs.
* **Slippage / minimum-received error:** Increase the `slippage` parameter (default `0.005` = 0.5%) when requesting the quote.
* **Rate limited (`429`):** Without an API key you're limited to 200 requests / 2 hours. [Request a key](https://li.fi/) for production and back off with retries.
* **Insufficient balance:** Ensure the user holds enough of the source token **plus** native gas on the source chain.
* **Network switch fails:** Confirm Somnia (`5031`) is added to the user's wallet. See [Connect Your Wallet to Mainnet](/get-started/connect-your-wallet-to-mainnet.md).

## Need Help?

* LI.FI SDK docs (source of truth): <https://docs.li.fi/sdk/overview>
* Somnia Discord: <https://discord.gg/somnia>
* Somnia Developer Telegram: <https://t.me/+s_oRMnGpOyQ3ODQ0>

## Disclaimers

* LI.FI is a third-party provider. Always integrate from the official packages (`@lifi/sdk`) and verify chain/token data against the live API.
* Bridging and swapping involve smart-contract and market risk. Test thoroughly on a small amount before enabling production flows.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.somnia.network/developer/building-dapps/cross-chain-swaps-and-bridging/integrating-the-li.fi-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
