🚗Migrate from v2 to v3

Migration guide for upgrading LI.FI Widget v2 to v3

Overview

LI.FI Widget v3 introduces a comprehensive overhaul of its core, enhancing compatibility with popular account management libraries like Wagmi and RainbowKit and incorporating many new features, including multi-ecosystem support starting with Solana. Therefore, there are some breaking changes and deprecations to be aware of, as outlined in this guide. Additionally, we encourage you to read the updated documentation, which includes new features that are not mentioned here.

To get started, install the latest version of Widget.

yarn add @lifi/widget

Configuration

Renamed variants

The following widget variants were renamed to better reflect their functionality:

default is now compact

expandable is now wide

See Select Widget Variants for more details.

Updated toAddress type

In Widget v3 we updated destination wallet functionality to have wallet bookmarks, recently used addresses and more. Previously, the toAddress option had a type string. To extend the feature in v3 we added a specific type for this field.

// Widget v2
interface WidgetConfig {
  // ...
  toAddress?: string;
  // ...
}

// Widget v3
interface ToAddress {
  name?: string;
  address: string;
  chainType: ChainType;
  logoURI?: string;
}

interface WidgetConfig {
  // ...
  toAddress?: ToAddress;
  // ...
}

Updated subvariantOptions type

In Widget v3 we extended the functionality of subvariants and subvariantOptions required type update. Previously, subvariantOptions supported only split subvariant and had SplitSubvariantOptions type and now we added support for custom subvariant with possibly more subvariant options coming in the future.

// Widget v2
type SplitSubvariantOptions = 'bridge' | 'swap';
interface WidgetConfig {
  // ...
  subvariantOptions?: SplitSubvariantOptions;
  // ...
}

// Widget v3
type SplitSubvariant = 'bridge' | 'swap';
type CustomSubvariant = 'checkout' | 'deposit';
interface SubvariantOptions {
  split?: SplitSubvariant;
  custom?: CustomSubvariant;
}

interface WidgetConfig {
  // ...
  subvariantOptions?: SubvariantOptions;
  // ...
}

SDK configuration

Following the release of LI.FI SDK v3 there are some changes to SDK configuration in the widget.

SDKConfig type is now WidgetSDKConfig.

defaultRouteOptions renamed to routeOptions.

Removed pre-built drawer button

Previously in Widget v2 there were two ways of controlling the drawer. The first one was pre-built button which came with drawer variant to open and close it. The second one was hiding the button via hiddenUI option and controlling the drawer by attaches the ref. Since the title and positioning often required some adjustments we decided to remove pre-built drawer button in favor of controlling the drawer with external button.

Here is the example of controlling the drawer with ref and you can customize the button as you like.

export const WidgetPage = () => {
  const drawerRef = useRef<WidgetDrawer>(null);

  const toggleWidget = () => {
    drawerRef.current?.toggleDrawer();
  };

  return (
    <div>
      <button onClick={toggleWidget}>Open LI.FI Widget</button>
      <LiFiWidget
        ref={drawerRef}
        config={{
          variant: 'drawer',
        }}
        integrator="drawer-example"
      />
    </div>
  );
}

We also removed HiddenUI.DrawerButton option since there is no default button anymore. However, we added a new option HiddenUI.DrawerCloseButton to hide the close button inside the drawer.

Theming

In Widget v3, we revamped customization and theming possibilities and did a small cleanup.

The top-level containerStyle option is moved under the umbrella of the theme option and was renamed to container.

// Widget v2
export const WidgetPage = () => {
  return (
    <LiFiWidget
      integrator="vite-example"
      config={{
        containerStyle: {
          border: `1px solid rgb(234, 234, 234)`,
          borderRadius: '16px',
        },
      }}
    />
  );
};

// Widget v3
export const WidgetPage = () => {
  return (
    <LiFiWidget
      integrator="example"
      config={{
        theme: {
          container: {
            border: `1px solid rgb(234, 234, 234)`,
            borderRadius: '16px',
          },
        },
      }}
    />
  );
};

Also, theme option type was renamed from ThemeConfig to WidgetTheme.

Please check out more in Customize Widget section.

Miscellaneous

disableLanguageDetector configuration option was removed. Language detection should now be inherited from the integration dApp.

Wallet Management

Moved from Ethers.js to Wagmi

We dropped support for Ethers.js. Instead, Widget now has a first-class Wagmi and all Wagmi-based libraries support like RainbowKit. You can still use Ethers.js in your project and convert Signer/Provider object to use Wagmi's injected connector before wrapping the Widget with WagmiProvider. However, we suggest moving your dApp's wallet management to use Wagmi as a more future proof solution.

Widget v2 setup with Ethers.js

import { LiFiWidget, WidgetConfig } from '@lifi/widget';

export const WidgetPage = () => {
  const { account, connect, disconnect, switchChain } = useWallet();

  const widgetConfig = useMemo((): WidgetConfig => {
    return {
      walletManagement: {
        signer: account.signer,
        connect: async () => {
          const signer = await connect();
          return signer;
        },
        disconnect: async () => {
          await disconnect();
        },
        switchChain: async (chainId: number) => {
          await switchChain(chainId);
          if (account.signer) {
            return account.signer;
          } else {
            throw Error('No signer object is found after the chain switch.');
          }
        },
      },
    };
  }, [account.signer, connect, disconnect, switchChain]);

  return (
    <LiFiWidget integrator="Your dApp/company name" config={widgetConfig} />
  );
}

Widget v3 setup with Wagmi

No more complicated callbacks, just wrap the Widget in WagmiProvider and you are set. If you already have one in your dApp, just make sure to keep the Wagmi chains configuration in sync with the Widget chain list, so all functionality like switching chains can keep working.

See Wallet Management for more details.

import { LiFiWidget } from '@lifi/widget';
import { createClient } from 'viem';
import { WagmiProvider, createConfig, http } from 'wagmi';
import { mainnet } from 'wagmi/chains';
import { injected } from 'wagmi/connectors';

const wagmiConfig = createConfig({
  // Make sure to provide the full list of chains
  // you would like to support in the Widget
  // and keep them in sync, so all functionality
  // like switching chains can work correctly.
  chains: [mainnet],
  connectors: [injected()],
  client({ chain }) {
    return createClient({ chain, transport: http() });
  },
});

export const WidgetPage = () => {
  return (
    <WagmiProvider config={wagmiConfig} reconnectOnMount>
      <LiFiWidget integrator="wagmi-example" />
    </WagmiProvider>
  );
};

Updated wallet management configuration

Since we don't need to provide callbacks and signers to widget configuration, walletManagement option was renamed to walletConfig and now has the following interface:

interface WidgetWalletConfig {
  // Can be used to open the external wallet menu, 
  // if the user is not connected and dApp uses external wallet management
  onConnect(): void;
  // Provide your projectId and other WalletConnect properties 
  // when using Widget's internal wallet management
  walletConnect?: WalletConnectParameters;
  // Provide your app name and other Coinbase properties 
  // when using Widget's internal wallet management
  coinbase?: CoinbaseWalletParameters;
}

Dependencies

Wagmi is a new peer dependency

Since we moved from ethers.js to Wagmi we added it to our peer dependencies.

Dropped CommonJS support

LI.FI Widget v3 no longer publishes a separate CommonJS build since most of the modern front-end tooling supports ESM and ESM is the future. See Sindre Sorhus' guide for more info about switching to ESM.

Last updated