Skip to main content

WidgetProvider

The provider component that sets up the widget context and configuration.

Props

PropTypeDescriptionDefaultRequired
sdkConfigMetalayerConfigSDK configuration-
themeWidgetThemeTheme configuration for customizing colors, corners, shadows, and moreundefined
defaultSourceDefaultChainTokenDefault source chain and tokenundefined
defaultDestinationDefaultChainTokenDefault destination chain and tokenundefined
enabledChainsChain[]Pre-loaded chains (bypasses fetching)undefined
onSupportedChainsLoad(chains: Chain[]) => voidCallback when chains are loadedundefined
onError(error: Error) => voidError handling callbackundefined
debugEnabledbooleanEnable debug loggingfalse

SDK Configuration

<WidgetProvider
  sdkConfig={{
    apiKey: 'your-api-key',
    environment: 'mainnet', // or 'testnet'
  }}
>
The defaultOptions configuration is optional. When not specified, the widget will display all supported chains and use default quote preference.

Default Source and Destination

<WidgetProvider
  defaultSource={{
    chainId: 1, // Ethereum Mainnet
    tokenAddress: '0x0000000000000000000000000000000000000000', // ETH
  }}
  defaultDestination={{
    chainId: 33139, // ApeChain
    tokenAddress: '0x0000000000000000000000000000000000000000', // ETH
  }}
>

Chain Loading Callback

onSupportedChainsLoad receives Metalayer Chain values from the SDK. Convert them with chainsToViemChains or chainToViemChain before passing them to wagmi, viem, or the RPC transport helpers below.
import { chainsToViemChains } from '@metalayer/sdk';
import { WidgetProvider } from '@metalayer/widget';

<WidgetProvider
  onSupportedChainsLoad={(chains) => {
    const viemChains = chainsToViemChains(chains);
    updateWalletConfig(viemChains);
  }}
>
Use createWidgetClient so each chain’s public client uses Metalayer’s RPC ordering and fallbacks. Build a non-empty viem chain tuple from chainsToViemChains(metalayerChains) (or a filtered list). Below, ViemChain is viem’s Chain type under an alias so it is not confused with the Metalayer Chain from the SDK.
import { chainsToViemChains } from '@metalayer/sdk';
import { createWidgetClient } from '@metalayer/widget';
import type { Chain as ViemChain } from 'viem';
import { createConfig } from 'wagmi';

function createWagmiConfig(chains: [ViemChain, ...ViemChain[]]) {
  return createConfig({
    chains,
    multiInjectedProviderDiscovery: false,
    client({ chain }) {
      return createWidgetClient(chain);
    },
  });
}
📋 Note: The widget requires an external WagmiProvider — it does not create its own. Use onSupportedChainsLoad to update your wagmi config with the widget’s supported chains.

RPC transport helpers

These helpers take viem Chain objects—the same shape returned by chainToViemChain / chainsToViemChains in @metalayer/sdk. Internally, createWidgetTransport calls collectChainHttpRpcUrls (see SDK utilities) and builds a viem fallback transport over those HTTP URLs: Metalayer default RPC first, then rpc-0, rpc-1, … slots that chainToViemChain fills from alternativeRpcs. If no URLs are present, it falls back to viem’s default http() behavior.

createWidgetTransport(chain)

Returns a viem Transport for a single chain. It reads every HTTP RPC URL from the chain via collectChainHttpRpcUrls and wraps them in a viem fallback() transport, so requests automatically retry on the next endpoint when one is rate-limited or unavailable. If no URLs are present it returns a plain http() transport. Most integrations should use createWidgetClient (wagmi client callback) or createWidgetTransportsRecord (wagmi transports map) instead of calling this directly. Use createWidgetTransport when you need the raw transport for a custom viem client or want to compose it with other transports:
import { createWidgetTransport } from '@metalayer/widget';
import { createClient } from 'viem';

const client = createClient({
  chain: viemChain,
  transport: createWidgetTransport(viemChain),
});

createWidgetClient(chain)

Convenience wrapper: creates a viem Client with createWidgetTransport already wired in. This is the recommended way to configure wagmi via the client callback (see Wagmi client callback above).
import { createWidgetClient } from '@metalayer/widget';

const client = createWidgetClient(viemChain);

createWidgetTransportsRecord(chains)

Builds Record<number, Transport> keyed by chain id. Useful with RainbowKit’s getDefaultConfig or any wagmi setup that takes a transports map instead of a client callback:
import { createWidgetTransportsRecord } from '@metalayer/widget';
import { getDefaultConfig } from '@rainbow-me/rainbowkit';

const config = getDefaultConfig({
  appName: 'My App',
  projectId: 'your-walletconnect-project-id',
  chains: supportedChains as unknown as readonly [Chain, ...Chain[]],
  transports: createWidgetTransportsRecord(supportedChains),
});
For custom transport stacks (for example viem fallback()), you can read ordered HTTP URLs from a viem chain with collectChainHttpRpcUrls in @metalayer/sdk.

Theme Configuration

The widget supports extensive theming options including predefined themes, custom colors, fonts, and advanced overrides. See the Theming page for complete customization options and visual examples.

Widget

The main UI component that renders the bridge interface.

Props

See WidgetProps for the complete props reference.
<Widget
  onConnectClick={() => openWalletModal()}
  onDisconnectClick={() => disconnect()}
  solanaSigner={solanaSigner}
/>

Type Definitions

MetalayerConfig

SDK configuration object. See MetalayerConfig in the SDK documentation for full details.

WidgetProps

PropertyTypeDescriptionDefaultRequired
onConnectClick() => voidCallback when user clicks connect-
onDisconnectClick() => voidCallback when user clicks disconnect. When provided, widget manages wallet connection internallyundefined
onTransactionSubmitted(sourceChainId?: number, destChainId?: number, amount?: string) => voidCallback when user submits a transactionundefined
onTokenSelected(direction: 'source' | 'destination', chainId: number, tokenAddress: string) => voidCallback when user selects a tokenundefined
source{ chainId: number; tokenAddress?: string }Controlled source chain and tokenundefined
destination{ chainId: number; tokenAddress?: string }Controlled destination chain and tokenundefined
isConnectingbooleanWhether a wallet is connectingfalse
solanaSignerWidgetSolanaSignerSolana wallet signer for Solana transactionsundefined
classNamestringCSS class name for custom stylingundefined
When onDisconnectClick is provided, the widget manages wallet connection state internally and displays wallet info in the settings tab. If your page already handles wallet connect/disconnect logic, you don’t need to set this prop; the widget will work with your existing wallet connection management.
import type { WidgetProps } from '@metalayer/widget';

WidgetSolanaSigner

Solana support is currently in beta and requires additional dependencies. See the EVM + Solana installation for setup instructions.
PropertyTypeDescriptionDefaultRequired
addressstringSolana wallet address-
isConnected() => booleanFunction that returns whether the wallet is connected-
signTransaction(transaction: Transaction) => Promise<Transaction>Function to sign a Solana transaction-
const solanaSigner = {
  address: wallet.publicKey.toString(),
  isConnected: () => wallet.connected,
  signTransaction: async (transaction) => await wallet.signTransaction(transaction),
};

DefaultChainToken

interface DefaultChainToken {
  chainId: number;
  tokenAddress: string;
}
PropertyTypeDescriptionDefaultRequired
chainIdnumberChain ID of the default network-
tokenAddressstringToken contract address-

Utility Functions

CSS Styling

The widget requires a CSS import for proper styling:
import '@metalayer/widget/styles.css';

Error Handling

Error Callback

Handle errors in the widget through the onError callback:
<WidgetProvider
  onError={(error) => {
    console.error('Widget error:', error);
    // Handle error (show toast, log to service, etc.)
  }}
>