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

# Migrate from v3 to v4

> Migration guide for upgrading LI.FI Widget v3 to v4

## Overview

**LI.FI Widget v4** introduces a modular provider architecture, internal routing improvements with TanStack Router, and enhanced multi-ecosystem support for Ethereum, Solana, Bitcoin, Sui, and Tron chains. This guide covers all breaking changes and migration steps.

### What's new in v4

Beyond the breaking changes below, v4 adds:

* **Modular providers** — Install only `@lifi/widget-provider-*` packages for the ecosystems you need; the core widget no longer bundles wallet stacks.
* **TanStack Router** — In-widget navigation uses TanStack Router instead of react-router compatibility layers.
* **wagmi v3** — Ethereum flows align with wagmi and `@wagmi/core` v3 when using `@lifi/widget-provider-ethereum`.
* **Tron (TVM)** — Full Tron support via `@lifi/widget-provider-tron` and matching Widget Light handlers.
* **Widget Light** — Continued improvements to the iframe integration surface (configuration, events, multi-chain handlers).

To get started, install the latest version of Widget.

```bash theme={"system"}
# Core widget only
pnpm add @lifi/widget @tanstack/react-query

# With blockchain providers (recommended)
pnpm add @lifi/widget @lifi/widget-provider-ethereum @lifi/widget-provider-solana @lifi/widget-provider-bitcoin @lifi/widget-provider-sui @lifi/widget-provider-tron wagmi @wagmi/core @bigmi/react bs58 @mysten/dapp-kit-react @tronweb3/tronwallet-adapter-react-hooks @tanstack/react-query
```

***

## Provider Architecture (biggest change)

### New Provider Packages

Widget v4 introduces a modular provider system. Instead of the widget internally creating all wallet providers, you now explicitly install and configure only the provider packages you need:

| Package                          | Ecosystem | Peer Dependencies                                  |
| -------------------------------- | --------- | -------------------------------------------------- |
| `@lifi/widget-provider-ethereum` | EVM       | `wagmi` ^3, `@wagmi/core` ^3                       |
| `@lifi/widget-provider-solana`   | SVM       | `bs58` >=4.0.1                                     |
| `@lifi/widget-provider-bitcoin`  | UTXO      | `@bigmi/react` ^0.8.0                              |
| `@lifi/widget-provider-sui`      | MVM       | `@mysten/dapp-kit-react` ^2.0.0                    |
| `@lifi/widget-provider-tron`     | TVM       | `@tronweb3/tronwallet-adapter-react-hooks` ^1.1.11 |

Additional supporting packages:

| Package                 | Description                                                                                                                                                     |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `@lifi/widget-provider` | Base provider abstraction with hooks (`useBitcoinContext`, `useEthereumContext`, `useSolanaContext`, `useSuiContext`, `useTronContext`) and `isWalletInstalled` |

### Core Widget Peer Dependencies Changed

**Widget v3** core had blockchain-specific peer dependencies: `wagmi ^2`, `@bigmi/react`, `@mysten/dapp-kit`, `@solana/wallet-adapter-react`.

**Widget v4** core only requires: `react >=19`, `react-dom >=19`, `@tanstack/react-query >=5.90.0`.

Blockchain-specific peer dependencies are now on the individual provider packages.

### Configuring Providers

**Widget v3** - Dependencies installed separately, providers detected automatically:

```typescript theme={"system"}
// Widget v3
import { LiFiWidget } from '@lifi/widget';
import { WagmiProvider } from 'wagmi';

export const WidgetPage = () => {
  return (
    <WagmiProvider config={wagmiConfig}>
      <LiFiWidget integrator="your-dapp" />
    </WagmiProvider>
  );
};
```

**Widget v4** - Use the new `providers` config option:

```typescript theme={"system"}
// Widget v4
import { LiFiWidget, WidgetConfig } from '@lifi/widget';
import { EthereumProvider } from '@lifi/widget-provider-ethereum';
import { SolanaProvider } from '@lifi/widget-provider-solana';
import { BitcoinProvider } from '@lifi/widget-provider-bitcoin';
import { SuiProvider } from '@lifi/widget-provider-sui';
import { TronProvider } from '@lifi/widget-provider-tron';

const widgetConfig: WidgetConfig = {
  providers: [
    EthereumProvider(),
    SolanaProvider(),
    BitcoinProvider(),
    SuiProvider(),
    TronProvider(),
  ],
};

export const WidgetPage = () => {
  return <LiFiWidget integrator="your-dapp" config={widgetConfig} />;
};
```

If you only need EVM support, you only install `@lifi/widget-provider-ethereum`:

```typescript theme={"system"}
import { EthereumProvider } from '@lifi/widget-provider-ethereum';

const widgetConfig: WidgetConfig = {
  providers: [EthereumProvider()],
};
```

### EthereumProvider Configuration

Wallet connector options have moved from `walletConfig` to `EthereumProvider`:

**Widget v3:**

```typescript theme={"system"}
// Widget v3
const widgetConfig: WidgetConfig = {
  walletConfig: {
    walletConnect: {
      projectId: 'your-project-id',
    },
    coinbase: {
      appName: 'Your App',
    },
  },
};
```

**Widget v4:**

```typescript theme={"system"}
// Widget v4
import { EthereumProvider } from '@lifi/widget-provider-ethereum';

const widgetConfig: WidgetConfig = {
  providers: [
    EthereumProvider({
      walletConnect: {
        projectId: 'your-project-id',
      },
      coinbase: {
        appName: 'Your App',
      },
      metaMask: {
        // MetaMask SDK options
      },
      porto: {
        // Porto connector options (EIP-7702)
      },
      baseAccount: {
        // Base Account options
      },
    }),
  ],
};
```

### Wagmi v2 to v3

Widget v4 requires **Wagmi v3** (was v2 in Widget v3). If you use an external Wagmi setup, you must upgrade Wagmi to v3. See the [Wagmi v3 migration guide](https://wagmi.sh/react/guides/migrate-from-v2-to-v3) for details.

### Sui Package Change

The Sui peer dependency changed from `@mysten/dapp-kit` to `@mysten/dapp-kit-react` ^2.0.0:

```bash theme={"system"}
# Remove old package
pnpm remove @mysten/dapp-kit

# Install new package
pnpm add @mysten/dapp-kit-react
```

Update any imports in your code accordingly.

***

## Import Changes

### Moved Exports

Several exports have moved to new packages:

| Export                     | v3 Package                | v4 Package                       |
| -------------------------- | ------------------------- | -------------------------------- |
| `createDefaultWagmiConfig` | `@lifi/wallet-management` | `@lifi/widget-provider-ethereum` |
| `createDefaultBigmiConfig` | `@lifi/wallet-management` | `@lifi/widget-provider-bitcoin`  |
| `useSyncWagmiConfig`       | `@lifi/wallet-management` | `@lifi/widget-provider-ethereum` |
| `isWalletInstalled`        | `@lifi/wallet-management` | `@lifi/widget-provider`          |

### Renamed Hooks

```typescript theme={"system"}
// Widget v3
import { useAvailableChains } from '@lifi/widget';
const { chains } = useAvailableChains();

// Widget v4
import { useWidgetChains } from '@lifi/widget';
import type { WidgetConfig } from '@lifi/widget';
const widgetConfig: WidgetConfig = { integrator: 'your-dapp' };
const { chains } = useWidgetChains(widgetConfig);
```

`useWidgetChains` takes a `WidgetConfig` parameter (used to create an SDK client for fetching chains).

***

## Wallet Configuration

### Updated WidgetWalletConfig

The wallet configuration interface has been simplified. Connector-specific options (`walletConnect`, `coinbase`, `metaMask`, `baseAccount`, `porto`) have moved to `EthereumProvider`:

**Widget v3:**

```typescript theme={"system"}
// Widget v3
interface WidgetWalletConfig {
  onConnect(): void
  walletConnect?: WalletConnectParameters
  coinbase?: CoinbaseWalletParameters
}
```

**Widget v4:**

```typescript theme={"system"}
// Widget v4
interface WidgetWalletConfig {
  onConnect?(args?: WalletMenuOpenArgs): void
  walletEcosystemsOrder?: Record<string, ChainType[]>
  usePartialWalletManagement?: boolean
  forceInternalWalletManagement?: boolean
}
```

### disableMessageSigning Moved

`disableMessageSigning` has moved from `sdkConfig.executionOptions` to the `EthereumProvider` configuration:

```typescript theme={"system"}
// Widget v3
const widgetConfig: WidgetConfig = {
  sdkConfig: {
    executionOptions: {
      disableMessageSigning: true,
    },
  },
};

// Widget v4
import { EthereumProvider } from '@lifi/widget-provider-ethereum';

const widgetConfig: WidgetConfig = {
  providers: [
    EthereumProvider({
      disableMessageSigning: true,
    }),
  ],
};
```

### SDK Execution Options

`sdkConfig.executionOptions` has been reduced. `disableMessageSigning` and `getContractCalls` were removed. Only `updateTransactionRequestHook` remains:

```typescript theme={"system"}
// Widget v4
interface WidgetSDKConfig {
  executionOptions?: {
    updateTransactionRequestHook?: (request: TransactionRequest) => Promise<TransactionRequest>
  }
}
```

***

## Routing Changes

### Internal Router Migration

Widget v4 uses **TanStack Router** internally instead of React Router v6. This is an internal change that should not affect most integrations.

**If you're using React Router in your app:**

No special configuration is needed. The widget's internal router is completely isolated.

**Widget v3** - Required catch-all route:

```typescript theme={"system"}
// Widget v3 - React Router needed special handling
<BrowserRouter>
  <Routes>
    <Route path="/swap/*" element={<LiFiWidgetPage />} />
  </Routes>
</BrowserRouter>
```

**Widget v4** - No special route configuration:

```typescript theme={"system"}
// Widget v4 - Standard routes work fine
<BrowserRouter>
  <Routes>
    <Route path="/swap" element={<LiFiWidgetPage />} />
  </Routes>
</BrowserRouter>
```

***

## Navigation Route Changes

Navigation route names have been updated:

```typescript theme={"system"}
// Widget v3
navigationRoutes.activeTransactions  // 'active-transactions'
navigationRoutes.transactionHistory  // 'transaction-history'

// Widget v4
navigationRoutes.activities          // 'activities' (replaces both)
```

`transactionHistory` was removed entirely and merged into `activities`.

***

## WidgetConfig Changes

### Subvariant Renamed to Mode

`subvariant` is now `mode`, and `subvariantOptions` is now `modeOptions`. All related types have been renamed:

```typescript theme={"system"}
// Widget v3
const widgetConfig: WidgetConfig = {
  subvariant: 'split',
  subvariantOptions: {
    split: 'bridge',
  },
};

// Widget v4
const widgetConfig: WidgetConfig = {
  mode: 'split',
  modeOptions: {
    split: 'bridge',
  },
};
```

| v3                       | v4                 |
| ------------------------ | ------------------ |
| `subvariant`             | `mode`             |
| `subvariantOptions`      | `modeOptions`      |
| `WidgetSubvariant`       | `WidgetMode`       |
| `SplitSubvariant`        | `SplitMode`        |
| `SplitSubvariantOptions` | `SplitModeOptions` |
| `SubvariantOptions`      | `ModeOptions`      |
| `CustomSubvariant`       | `CustomMode`       |

### Custom Mode Options Restructured

The `custom` mode option is now an object with a `type` field. The `'fund'` value has been removed:

```typescript theme={"system"}
// Widget v3
subvariantOptions: {
  custom: 'checkout',  // string shorthand
}

// Widget v4
modeOptions: {
  custom: { type: 'checkout' },  // object with type field
}
```

### Wide Variant Chain Sidebar Moved to HiddenUI

The chain sidebar option has moved from `modeOptions` to `hiddenUI`:

```typescript theme={"system"}
// Widget v3
subvariantOptions: {
  wide: {
    disableChainSidebar: true,
  },
}

// Widget v4
hiddenUI: {
  chainSidebar: true,  // Hide the chain sidebar in wide variant
}
```

### UI Controls Changed from Arrays to Objects

`disabledUI`, `hiddenUI`, and `requiredUI` now use object configs instead of enum arrays:

```typescript theme={"system"}
// Widget v3
import { DisabledUI, HiddenUI } from '@lifi/widget';

const widgetConfig: WidgetConfig = {
  disabledUI: [DisabledUI.ToAddress],
  hiddenUI: [HiddenUI.Appearance, HiddenUI.Language, HiddenUI.PoweredBy],
};

// Widget v4
const widgetConfig: WidgetConfig = {
  disabledUI: { toAddress: true },
  hiddenUI: { appearance: true, language: true, poweredBy: true },
};
```

The `DisabledUI`, `HiddenUI`, and `RequiredUI` enums have been replaced by `DisabledUIConfig`, `HiddenUIConfig`, and `RequiredUIConfig` interfaces.

### useRecommendedRoute Renamed to showSingleRoute

```typescript theme={"system"}
// Widget v3
const widgetConfig: WidgetConfig = {
  useRecommendedRoute: true,
};

// Widget v4
const widgetConfig: WidgetConfig = {
  showSingleRoute: true,
};
```

### Top-level fee Removed

The top-level `fee` shorthand has been removed. Use `feeConfig.fee` instead:

```typescript theme={"system"}
// Widget v3
const widgetConfig: WidgetConfig = {
  fee: 0.03,
};

// Widget v4
const widgetConfig: WidgetConfig = {
  feeConfig: {
    fee: 0.03,
  },
};
```

### SDK Route Options Restricted

`fee`, `referrer`, `order`, and `slippage` can no longer be passed through `sdkConfig.routeOptions`. Use the top-level config fields (`feeConfig`, `referrer`, `routePriority`, `slippage`) instead.

### Split Mode Options Enhanced

The `split` mode now supports an object form with `defaultTab`:

```typescript theme={"system"}
// New in v4 - both tabs with configurable default
modeOptions: {
  split: { defaultTab: 'swap' },
}
```

***

## Event Changes

### Event Bus Migrated to eventemitter3

The internal event bus has migrated from `mitt` to `eventemitter3`. Event type signatures now use callback functions:

```typescript theme={"system"}
// Widget v3 (mitt-style)
type WidgetEvents = {
  availableRoutes: Route[]
  routeExecutionStarted: Route
}

// Widget v4 (eventemitter3-style)
type WidgetEvents = {
  availableRoutes: (data: Route[]) => void
  routeExecutionStarted: (data: Route) => void
}
```

The `on`/`off` subscription API remains the same — this change only affects custom type declarations.

### WalletConnected Event Moved

The `walletConnected` event has moved from `WidgetEvents` to `WalletManagementEvents` in the `@lifi/wallet-management` package. The event type also changed — all fields are now required and two new fields were added:

```typescript theme={"system"}
// Widget v3
interface WalletConnected {
  address?: string
  chainId?: number
  chainType?: ChainType
}

// Widget v4
import { useWalletManagementEvents, WalletManagementEvent } from '@lifi/wallet-management';
import type { WalletConnected } from '@lifi/wallet-management';

interface WalletConnected {
  address: string
  chainId: number
  chainType: ChainType
  connectorId: string
  connectorName: string
}
```

### TokensReversed Event Removed

`WidgetEvent.TokensReversed` has been removed entirely.

### RouteExecutionUpdate Type Changed

The `RouteExecutionUpdate` type now uses `action` (type `ExecutionAction`) instead of `process` (type `Process`):

```typescript theme={"system"}
// Widget v3
type RouteExecutionUpdate = {
  route: Route
  process: Process
}

// Widget v4
type RouteExecutionUpdate = {
  route: Route
  action: ExecutionAction
}
```

Update any event handlers that access the `process` property:

```typescript theme={"system"}
// Widget v3
widgetEvents.on(WidgetEvent.RouteExecutionUpdated, (update) => {
  console.log(update.process);
});

// Widget v4
widgetEvents.on(WidgetEvent.RouteExecutionUpdated, (update) => {
  console.log(update.action);
});
```

### ReviewTransactionPageEntered Deprecated

`WidgetEvent.ReviewTransactionPageEntered` is deprecated. Use `WidgetEvent.PageEntered` instead, which fires for all page navigation with a `NavigationRouteType` payload.

***

## SDK v4 Dependency

Widget v4 depends on LI.FI SDK v4, which has its own breaking changes:

* `createConfig` is now `createClient`
* `Process` type is now `ExecutionAction`

These changes primarily affect the event types as noted above. If you use the SDK directly alongside the widget, consult the [SDK migration guide](/sdk/migrate-v3-to-v4).

***

## Quick Migration Checklist

1. **Update packages**: Install `@lifi/widget` v4 and the provider packages you need
2. **Add `providers` to config**: Pass `EthereumProvider()`, `SolanaProvider()`, etc. via `config.providers`
3. **Move wallet connector config**: Move `walletConnect`, `coinbase`, etc. from `walletConfig` to `EthereumProvider({...})`
4. **Move `disableMessageSigning`**: From `sdkConfig.executionOptions` to `EthereumProvider({ disableMessageSigning: true })`
5. **Update Wagmi to v3** if using an external Wagmi setup
6. **Update Sui package**: Replace `@mysten/dapp-kit` with `@mysten/dapp-kit-react`
7. **Update `useAvailableChains`**: Replace with `useWidgetChains(widgetConfig)`
8. **Update `useSyncWagmiConfig` import**: From `@lifi/wallet-management` to `@lifi/widget-provider-ethereum`
9. **Update `createDefaultWagmiConfig` import**: From `@lifi/wallet-management` to `@lifi/widget-provider-ethereum`
10. **Rename `subvariant` → `mode`** and `subvariantOptions` → `modeOptions`
11. **Update custom mode options**: Change `custom: 'checkout'` to `custom: { type: 'checkout' }`
12. **Move chain sidebar config**: From `subvariantOptions.wide.disableChainSidebar` to `hiddenUI: { chainSidebar: true }`
13. **Update UI controls to object configs**: Replace `disabledUI: [DisabledUI.X]` with `disabledUI: { x: true }`, same for `hiddenUI` and `requiredUI`
14. **Rename `useRecommendedRoute`** → `showSingleRoute`
15. **Replace top-level `fee`** with `feeConfig: { fee: 0.03 }`
16. **Remove `fee`/`referrer`/`order`/`slippage` from `sdkConfig.routeOptions`**: Use top-level config fields instead
17. **Fix event handlers**: Replace `update.process` with `update.action` in route execution event handlers
18. **Remove `TokensReversed` event**: If subscribed, remove the handler
19. **Update `walletConnected` event**: Now in `WalletManagementEvents`, not `WidgetEvents`
20. **Update navigation routes**: Replace `activeTransactions`/`transactionHistory` with `activities`
21. **Remove `'fund'` custom mode**: If used, replace with `'checkout'` or `'deposit'`
22. **Remove React Router catch-all**: No longer needed for widget routes
