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.
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.
# 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 |
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 >=18, react-dom >=18, @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:
// 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:
// 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:
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:
// Widget v3
const widgetConfig: WidgetConfig = {
walletConfig: {
walletConnect: {
projectId: 'your-project-id',
},
coinbase: {
appName: 'Your App',
},
},
};
Widget v4:
// 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 for details.
Sui Package Change
The Sui peer dependency changed from @mysten/dapp-kit to @mysten/dapp-kit-react ^2.0.0:
# 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
// 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
The wallet configuration interface has been simplified. Connector-specific options (walletConnect, coinbase, metaMask, baseAccount, porto) have moved to EthereumProvider:
Widget v3:
// Widget v3
interface WidgetWalletConfig {
onConnect(): void
walletConnect?: WalletConnectParameters
coinbase?: CoinbaseWalletParameters
}
Widget v4:
// 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:
// 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:
// 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:
// Widget v3 - React Router needed special handling
<BrowserRouter>
<Routes>
<Route path="/swap/*" element={<LiFiWidgetPage />} />
</Routes>
</BrowserRouter>
Widget v4 - No special route configuration:
// Widget v4 - Standard routes work fine
<BrowserRouter>
<Routes>
<Route path="/swap" element={<LiFiWidgetPage />} />
</Routes>
</BrowserRouter>
Navigation Route Changes
Navigation route names have been updated:
// 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.
Subvariant Renamed to Mode
subvariant is now mode, and subvariantOptions is now modeOptions. All related types have been renamed:
// 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:
// Widget v3
subvariantOptions: {
custom: 'checkout', // string shorthand
}
// Widget v4
modeOptions: {
custom: { type: 'checkout' }, // object with type field
}
The chain sidebar option has moved from modeOptions to hiddenUI:
// 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:
// 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
// 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:
// 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:
// 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:
// 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:
// 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):
// 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:
// 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.
Quick Migration Checklist
- Update packages: Install
@lifi/widget v4 and the provider packages you need
- Add
providers to config: Pass EthereumProvider(), SolanaProvider(), etc. via config.providers
- Move wallet connector config: Move
walletConnect, coinbase, etc. from walletConfig to EthereumProvider({...})
- Move
disableMessageSigning: From sdkConfig.executionOptions to EthereumProvider({ disableMessageSigning: true })
- Update Wagmi to v3 if using an external Wagmi setup
- Update Sui package: Replace
@mysten/dapp-kit with @mysten/dapp-kit-react
- Update
useAvailableChains: Replace with useWidgetChains(widgetConfig)
- Update
useSyncWagmiConfig import: From @lifi/wallet-management to @lifi/widget-provider-ethereum
- Update
createDefaultWagmiConfig import: From @lifi/wallet-management to @lifi/widget-provider-ethereum
- Rename
subvariant → mode and subvariantOptions → modeOptions
- Update custom mode options: Change
custom: 'checkout' to custom: { type: 'checkout' }
- Move chain sidebar config: From
subvariantOptions.wide.disableChainSidebar to hiddenUI: { chainSidebar: true }
- Update UI controls to object configs: Replace
disabledUI: [DisabledUI.X] with disabledUI: { x: true }, same for hiddenUI and requiredUI
- Rename
useRecommendedRoute → showSingleRoute
- Replace top-level
fee with feeConfig: { fee: 0.03 }
- Remove
fee/referrer/order/slippage from sdkConfig.routeOptions: Use top-level config fields instead
- Fix event handlers: Replace
update.process with update.action in route execution event handlers
- Remove
TokensReversed event: If subscribed, remove the handler
- Update
walletConnected event: Now in WalletManagementEvents, not WidgetEvents
- Update navigation routes: Replace
activeTransactions/transactionHistory with activities
- Remove
'fund' custom mode: If used, replace with 'checkout' or 'deposit'
- Remove React Router catch-all: No longer needed for widget routes