👛Wallet Management

Configure your widget for seamless wallet management

The widget has a built-in wallet management UI, so you can connect the wallet and use the widget as a standalone dApp out of the box. However, when embedding the widget into the dApp, reusing the existing wallet management UI of that dApp makes the most sense.

There are several ecosystems and types of chains (EVM, SVM, UTXO) supported by the widget, and therefore, there are several different libraries used to manage wallet connections to these chains.

EVM wallet connection

To manage wallet connection to EVM (Ethereum Virtual Machine) chains, switching chains, etc., the widget uses the Wagmi library internally and also provides first-class support for all Wagmi-based libraries such as RainbowKit, Dynamic, Reown AppKit.

If you already manage wallets using Wagmi or Wagmi-based library in your dApp and the Widget detects that it is wrapped in WagmiProvider it will start re-using your wallet management without any additional configuration.

The example below shows how to preconfigure a basic wallet management using Wagmi.

import { LiFiWidget } from '@lifi/widget';
import { createClient } from 'viem';
import { WagmiProvider, createConfig, http } from 'wagmi';
import { mainnet, arbitrum, optimism, scroll } 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, arbitrum, optimism, scroll],
  connectors: [injected()],
  client({ chain }) {
    return createClient({ chain, transport: http() });
  },
});

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

Keep chains in sync

It is important to keep the Wagmi chains configuration in sync with the Widget chain list so all functionality, like switching chains, can keep working correctly.

There are two approaches to this:

  1. Manually update the Widget and Wagmi chains configuration to specify all chains you would like to support in your dApp and the Widget. See Configure Widget page to know more about the Widget's allow/deny chains configuration.

  2. Get all available chains from LI.FI API and dynamically update Wagmi configuration. The Widget provides hooks to ease this approach.

Here is an example of how to support all available LI.FI chains dynamically using Wagmi and additional hooks from @lifi/widget package.

import { useSyncWagmiConfig } from '@lifi/wallet-management';
import { useAvailableChains } from '@lifi/widget';
import { injected } from '@wagmi/connectors';
import { useRef, type FC, type PropsWithChildren } from 'react';
import { createClient, http } from 'viem';
import { mainnet } from 'viem/chains';
import type { Config } from 'wagmi';
import { createConfig, WagmiProvider } from 'wagmi';

const connectors = [injected()];

export const WalletProvider: FC<PropsWithChildren> = ({ children }) => {
  const { chains } = useAvailableChains();
  const wagmi = useRef<Config>();

  if (!wagmi.current) {
    wagmi.current = createConfig({
      chains: [mainnet],
      client({ chain }) {
        return createClient({ chain, transport: http() });
      },
      ssr: true,
    });
  }

  useSyncWagmiConfig(wagmi.current, connectors, chains);

  return (
    <WagmiProvider config={wagmi.current} reconnectOnMount={false}>
      {children}
    </WagmiProvider>
  );
};

Please check out our complete examples in the widget repository here.

Support for Ethers.js and other alternatives

Developers can still use Ethers.js or any other alternative library in their project and convert Signer/Provider objects to Wagmi's injected connector before wrapping the Widget with WagmiProvider.

SVM wallet connection

To manage wallet connection to SVM (Solana Virtual Machine) chains the widget uses the Solana Wallet Standard library.

If you already manage wallets using Solana Wallet Standard library in your dApp and the Widget detects that it is wrapped in ConnectionProvider and WalletProvider it will start re-using your wallet management without any additional configuration.

The example below shows how to preconfigure a basic wallet management for SVM.

import type { Adapter } from '@solana/wallet-adapter-base';
import { WalletAdapterNetwork } from '@solana/wallet-adapter-base';
import {
  ConnectionProvider,
  WalletProvider,
} from '@solana/wallet-adapter-react';
import { clusterApiUrl } from '@solana/web3.js';
import type { FC, PropsWithChildren } from 'react';

const endpoint = clusterApiUrl(WalletAdapterNetwork.Mainnet);
/**
 * Wallets that implement either of these standards will be available automatically.
 *
 *   - Solana Mobile Stack Mobile Wallet Adapter Protocol
 *     (https://github.com/solana-mobile/mobile-wallet-adapter)
 *   - Solana Wallet Standard
 *     (https://github.com/solana-labs/wallet-standard)
 *
 * If you wish to support a wallet that supports neither of those standards,
 * instantiate its legacy wallet adapter here. Common legacy adapters can be found
 * in the npm package `@solana/wallet-adapter-wallets`.
 */
const wallets: Adapter[] = [];

export const SolanaWalletProvider: FC<PropsWithChildren> = ({ children }) => {
  return (
    <ConnectionProvider endpoint={endpoint}>
      <WalletProvider wallets={wallets} autoConnect>
        {children}
      </WalletProvider>
    </ConnectionProvider>
  );
};

Configuration

There are additional configurations to smooth integration for external wallet management or in case of internal one provide options for WalletConnect and Coinbase Wallet.

interface WidgetWalletConfig {
  onConnect?(): void;
  walletConnect?: WalletConnectParameters;
  coinbase?: CoinbaseWalletParameters;
  metaMask?: MetaMaskParameters;
  usePartialWalletManagement?: boolean;
}

interface WidgetConfig {
  // ...
  walletConfig?: WidgetWalletConfig;
}

Connect wallet button

Using internal wallet management clicking the Connect wallet button triggers the opening of an internal wallet menu. In cases where external wallet management is used we provide onConnect configuration option. This option allows developers to specify a callback function that will be executed when the Connect wallet button is clicked.

Please see modified RainbowKit example below. Here we use openConnectModal function provided by useConnectModal hook to open RainbowKit wallet menu when the Connect wallet button is clicked.

import { LiFiWidget } from '@lifi/widget';
import { useConnectModal } from '@rainbow-me/rainbowkit';
import { WalletProvider } from '../providers/WalletProvider';

export const WidgetPage = () => {
  const { openConnectModal } = useConnectModal();
  return (
    <WalletProvider>
      <LiFiWidget
        integrator="wagmi-example"
        config={{
          walletConfig: {
            onConnect() {
              openConnectModal?.();
            },
          },
        }}
      />
    </WalletProvider>
  );
};

WalletConnect and Coinbase Wallet

We provide additional configuration for WalletConnect and Coinbase Wallet Wagmi connectors so when using built-in wallet management in the widget you can set WalletConnect's projectId or Coinbase Wallet's appName parameters.

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

const widgetConfig: WidgetConfig = {
  walletConfig: {
    walletConnect: {
      projectId: 'Your Wallet Connect Project Id',
    },
  },
};

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

Partial Wallet Management

Your external wallet management may not support all ecosystems provided by our widget, or you may be in the process of migrating to a new setup. To help with these cases, we've got you covered! The usePartialWalletManagement configuration option allows the widget to offer partial wallet management functionality. When enabled, this option provides a hybrid approach, effectively combining both external and internal wallet management.

In partial mode, external wallet management is used for "opt-out" providers, while internal management applies to any remaining providers that do not opt out. This setup creates a flexible balance between the integrator’s custom wallet menu and the widget’s native wallet menu, ensuring a smooth user experience across all ecosystems, even if external support is incomplete or in transition.

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

const widgetConfig: WidgetConfig = {
  walletConfig: {
    usePartialWalletManagement: true,
  },
};

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

As shown in the GIF above, this setup allows both the integrator's and the widget's wallet menus to operate together, each supporting different ecosystems. In the example, RainbowKit manages EVM wallet support, while the internal wallet menu handles Solana and Bitcoin.

🌍Internationalization

Last updated