> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://www.openfort.io/api/mcp` to find what you need.
>
> **Have feedback?** Use `submit_feedback` on the same MCP server.

# Swap on LI.FI

Build a cross-chain bridge and swap experience by pairing Openfort's embedded wallet infrastructure with LiFi's routing engine. Users authenticate with email or social login, then swap tokens across Ethereum, Polygon, Arbitrum, Optimism, Base, and Avalanche — all from a single Next.js interface.

:::tip
You'll build a full-stack Next.js app where users sign in with an Openfort embedded wallet and execute cross-chain token swaps powered by LiFi's routing engine, with optional gas sponsorship.
:::

[View Sample Code](https://github.com/openfort-xyz/recipes-hub/tree/main/lifi) — GitHub Repository. Complete source code for the LiFi cross-chain swap application with Next.js frontend and LiFi SDK integration.

![lifi recipe interface](https://www.openfort.io/images/blog/crosschain_lifi_3fe4e9eec8.jpg?updated_at=2025-10-21T13:08:50.619Z)

## Getting started

::::steps
### Set up your project

Clone the recipe and install dependencies:

```bash
pnpx gitpick openfort-xyz/recipes-hub/tree/main/lifi openfort-lifi
cd openfort-lifi
pnpm install
```

### Get your Openfort credentials

1. Sign in to [dashboard.openfort.io](https://dashboard.openfort.io) and create a project
2. Go to **API Keys** and copy your **publishable key**
3. Go to **Shield** settings and copy your **Shield publishable key**
4. (Optional) Create a **Policy** for gas sponsorship and copy the policy ID

:::tip
You can find all your keys in the [Openfort Dashboard](https://dashboard.openfort.io). Gas sponsorship lets your users swap without paying network fees.
:::

### Configure your environment

Copy the template and fill in your credentials:

```bash
cp .env.example .env.local
```

```bash
NEXT_PUBLIC_OPENFORT_PUBLISHABLE_KEY=pk_...
NEXT_PUBLIC_OPENFORT_SHIELD_PUBLISHABLE_KEY=...
NEXT_PUBLIC_OPENFORT_POLICY_ID=pol_...              # Optional — for gas sponsorship
NEXT_PUBLIC_OPENFORT_DEFAULT_CHAIN_ID=11155111      # Sepolia testnet

NEXT_PUBLIC_LIFI_INTEGRATOR=YourAppName
NEXT_PUBLIC_LIFI_API_KEY=...                        # Optional — for higher rate limits
```

### Run the application

```bash
pnpm dev
```

Open [http://localhost:3000](http://localhost:3000), sign in with your email, and try a cross-chain swap.
::::

## How it works

The app wraps the Openfort embedded wallet with LiFi's SDK to handle chain switching and route execution automatically.

### Provider setup

The root layout nests Openfort, wagmi, and LiFi providers so the wallet context is available everywhere:

```tsx
// src/app/providers.tsx
<WagmiProvider config={wagmiConfig}>
  <QueryClientProvider client={queryClient}>
    <OpenfortProviderBoundary>
      <LiFiProvider wagmiConfig={wagmiConfig} connectors={connectors}>
        {children}
      </LiFiProvider>
    </OpenfortProviderBoundary>
  </QueryClientProvider>
</WagmiProvider>
```

### LiFi SDK configuration

The LI.FI SDK v4 is headless: you create a client with the modular Ethereum provider and pass that client to every action. Wallet and chain switching are wired into the provider via wagmi:

```typescript
// src/features/lifi/services/lifi-config.ts
import { createClient } from "@lifi/sdk";
import { EthereumProvider } from "@lifi/sdk-provider-ethereum";
import { getWalletClient, switchChain } from "wagmi/actions";

let client;

export const initializeLiFiConfig = (wagmiConfig) => {
  client = createClient({
    integrator: process.env.NEXT_PUBLIC_LIFI_INTEGRATOR,
    apiKey: process.env.NEXT_PUBLIC_LIFI_API_KEY,
    providers: [
      EthereumProvider({
        getWalletClient: () => getWalletClient(wagmiConfig),
        switchChain: async (chainId) => {
          const chain = await switchChain(wagmiConfig, { chainId });
          return getWalletClient(wagmiConfig, { chainId: chain.id });
        },
      }),
    ],
  });
  return client;
};

export const getLiFiClient = () => client;
```

:::note
In v4 every action takes the client as its first argument — `getRoutes(client, …)`, `getChains(client)`, `executeRoute(client, route, opts)`. The bundled `EVM()` provider and `createConfig` from v3 are gone, replaced by `createClient` + `@lifi/sdk-provider-ethereum`.
:::

### Swap execution flow

The `useSwapController` hook in `src/features/lifi/hooks/use-swap-controller.ts` manages the full swap lifecycle:

1. **Fetch routes** — calls LiFi's `getRoutes` with source/destination chain, tokens, and amount
2. **Select route** — presents the cheapest route (or lets the user pick from alternatives)
3. **Execute swap** — calls `executeRoute(client, route, …)` with hooks for rate-change confirmation and progress monitoring (chain switching is handled by the provider's `switchChain`, not an execution hook in v4)
4. **Track progress** — the `updateRouteHook` callback streams execution status from `step.execution.actions[]` for each step, with explorer links

### Multi-chain support

The wagmi config auto-selects mainnet or testnet chains based on `NEXT_PUBLIC_OPENFORT_DEFAULT_CHAIN_ID`:

```typescript
// src/features/openfort/config/wagmi-config.ts
const mainnetChains = [mainnet, polygon, arbitrum, optimism, base, avalanche];
const testnetChains = [sepolia, polygonAmoy, arbitrumSepolia, optimismSepolia, baseSepolia];

const chains = mainnetIds.has(DEFAULT_CHAIN_ID)
  ? mainnetChains
  : testnetChains;
```

## Next steps

* [Embedded Wallet Guide](https://www.openfort.io/docs/products/embedded-wallet) — learn more about embedded wallet security
* [Gas sponsorship with policies](https://www.openfort.io/docs/configuration/policies) — sponsor user transactions
* [LiFi SDK docs](https://docs.li.fi/) — explore advanced routing and fee options
