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

# Migration Guide

> Upgrade from @metalayer/widget v0.x to v1.x

This guide helps you upgrade from `@metalayer/widget` v0.x to v1.x, which introduces a cleaner API, improved naming conventions, and a powerful new theme system.

## Breaking Changes

### 1. External WagmiProvider Required (disableWagmi removed)

The widget no longer ships an internal `WagmiProvider`. The `disableWagmi` prop has been removed — you **must** provide your own `WagmiProvider` in your application.

If you were already using `disableWagmi={true}`, simply remove the prop:

```diff theme={null}
  <WagmiProvider config={wagmiConfig}>
    <WidgetProvider
-     disableWagmi
      sdkConfig={sdkConfig}
      onSupportedChainsLoad={handleSupportedChainsLoad}
    >
```

If you were relying on the widget's internal `WagmiProvider` (the old default), wrap your app with your own:

```diff theme={null}
+ <WagmiProvider config={wagmiConfig}>
    <WidgetProvider
      sdkConfig={sdkConfig}
+     onSupportedChainsLoad={(chains) => {
+       // Update wagmi config with supported chains
+     }}
    >
      <Widget onConnectClick={openModal} />
    </WidgetProvider>
+ </WagmiProvider>
```

Use `onSupportedChainsLoad` to update your wagmi config with the chains the widget supports.

### 2. Widget Props Structure

The widget no longer uses a nested `config` object. Props are now passed directly to the component.

<CodeGroup>
  ```tsx Before (v0.x) theme={null}
  <Widget
    config={{
      onOpenConnectModal: openModal,
      onDisconnectWallet: disconnect,
      onSubmitTransaction: handleSubmit,
      onSelectToken: handleTokenSelect,
      className: 'custom-class',
      source: sourceConfig,
      destination: destinationConfig,
    }}
  />
  ```

  ```tsx After (v1.x) theme={null}
  <Widget
    onConnectClick={openModal}
    onDisconnectClick={disconnect}
    onTransactionSubmitted={handleSubmit}
    onTokenSelected={handleTokenSelect}
    className="custom-class"
    source={sourceConfig}
    destination={destinationConfig}
  />
  ```
</CodeGroup>

### 3. Callback Naming Changes

All callbacks have been renamed for clarity and consistency with React conventions:

| Old Name (v0.x)       | New Name (v1.x)          | Description                         |
| --------------------- | ------------------------ | ----------------------------------- |
| `onOpenConnectModal`  | `onConnectClick`         | Handler when user clicks connect    |
| `onDisconnectWallet`  | `onDisconnectClick`      | Handler when user clicks disconnect |
| `onSubmitTransaction` | `onTransactionSubmitted` | Fired after transaction submission  |
| `onSelectToken`       | `onTokenSelected`        | Fired after token selection         |

### 4. Theme System

The `brandColor` prop has been **removed** in favor of the new comprehensive theme system.

<CodeGroup>
  ```tsx Before (v0.x) theme={null}
  <WidgetProvider
    sdkConfig={{ apiKey: 'key', environment: 'mainnet' }}
    brandColor="#6750A4"
  >
  ```

  ```tsx After (v1.x) theme={null}
  <WidgetProvider
    sdkConfig={{ apiKey: 'key', environment: 'mainnet' }}
    theme={{
      colors: { primary: '#6750A4' }
    }}
  >
  ```
</CodeGroup>

**Note:** `brandColor` has been completely removed in v1.x. You must use the new `theme` prop. See the [New Theme System Features](#new-theme-system-features) section below for comprehensive theming options.

### 5. WidgetProvider Props Update

The `chains` prop has been renamed to `enabledChains` for clarity:

<CodeGroup>
  ```tsx Before (v0.x) theme={null}
  <WidgetProvider
    sdkConfig={{ apiKey: 'key', environment: 'mainnet' }}
    chains={supportedChains}
  >
  ```

  ```tsx After (v1.x) theme={null}
  <WidgetProvider
    sdkConfig={{ apiKey: 'key', environment: 'mainnet' }}
    enabledChains={supportedChains}
  >
  ```
</CodeGroup>

### 6. RPC / wagmi transports (Metalayer RPC helpers)

v1.x expects you to own **`WagmiProvider`** and therefore your **transports**. Using plain viem **`http()`** (or other defaults that ignore Metalayer metadata) does **not** use Metalayer’s ordered RPCs or **`alternativeRpcs`** as viem **`fallback`** endpoints, which can lead to rate limits or mismatches with the chains the widget loads.

Prefer:

* **`createWidgetClient`** with wagmi **`createConfig`** using a **`client({ chain }) { return createWidgetClient(chain) }`** callback, typically **`multiInjectedProviderDiscovery: false`**, after converting `onSupportedChainsLoad` chains with **`chainsToViemChains`** / **`chainToViemChain`** (see [Components](/metalayer/widget/components#wagmi-client-callback)), or
* **`createWidgetTransportsRecord(viemChains)`** with **`createConfig({ chains, transports })`** or RainbowKit **`getDefaultConfig({ transports })`**.

```diff theme={null}
- transports: { [chain.id]: http() },
+ transports: createWidgetTransportsRecord(viemChains),
```

## Step-by-Step Migration

### Step 1: Update Package Version

<CodeGroup>
  ```bash pnpm theme={null}
  pnpm update @metalayer/widget@^1.0.0
  ```

  ```bash npm theme={null}
  npm update @metalayer/widget@^1.0.0
  ```

  ```bash yarn theme={null}
  yarn upgrade @metalayer/widget@^1.0.0
  ```
</CodeGroup>

### Step 2: Update Widget Component Usage

Find all `<Widget>` components and update the props:

```diff theme={null}
- <Widget
-   config={{
-     onOpenConnectModal: openConnectModal,
-     onDisconnectWallet: () => disconnect(),
-     onSubmitTransaction: (source, dest, amount) => {
-       console.log('Transaction submitted', { source, dest, amount });
-     },
-     className: 'rounded-xl',
-   }}
- />
+ <Widget
+   onConnectClick={openConnectModal}
+   onDisconnectClick={() => disconnect()}
+   onTransactionSubmitted={(source, dest, amount) => {
+     console.log('Transaction submitted', { source, dest, amount });
+   }}
+   className="rounded-xl"
+ />
```

### Step 3: Update WidgetProvider Theme

Replace `brandColor` with the new theme configuration:

```diff theme={null}
  <WidgetProvider
    sdkConfig={{ apiKey: 'your-key', environment: 'mainnet' }}
-   brandColor="#6750A4"
+   theme={{
+     colors: { primary: '#6750A4' }
+   }}
  >
```

### Step 4: Update Token Selection Callbacks

If you're using token selection callbacks, update the naming:

```diff theme={null}
  <Widget
-   config={{
-     onSelectToken: (direction, chainId, tokenAddress) => {
-       console.log('Token selected', { direction, chainId, tokenAddress });
-     }
-   }}
+   onTokenSelected={(direction, chainId, tokenAddress) => {
+     console.log('Token selected', { direction, chainId, tokenAddress });
+   }}
  />
```

### Step 5: Update Controlled Token Selection

If using controlled source/destination props:

```diff theme={null}
  <Widget
-   config={{
-     source: { chainId: 1, tokenAddress: '0x...' },
-     destination: { chainId: 42161, tokenAddress: '0x...' },
-     onOpenConnectModal: openModal,
-   }}
+   source={{ chainId: 1, tokenAddress: '0x...' }}
+   destination={{ chainId: 42161, tokenAddress: '0x...' }}
+   onConnectClick={openModal}
  />
```

## New Theme System Features

Take advantage of the new theming capabilities:

### Predefined Themes

```tsx theme={null}
<WidgetProvider
  sdkConfig={sdkConfig}
  theme={{ predefined: 'modern' }} // 'comfy' | 'modern'
>
```

### Custom Color Palette

```tsx theme={null}
<WidgetProvider
  sdkConfig={sdkConfig}
  theme={{
    mode: 'light',       // 'light' | 'dark'
    colors: {
      primary: '#6750A4',
      neutral: '#5E5E5E',
      success: '#00C853',
      warning: '#FFB300',
      info: '#2196F3',
      failure: '#F44336',
    },
    corners: 'rounded',  // 'none' | 'minimal' | 'soft' | 'medium' | 'rounded'
    shadow: 'light',     // 'none' | 'sharp' | 'light' | 'heavy'
  }}
>
```

### Feature Toggles

```tsx theme={null}
<WidgetProvider
  sdkConfig={sdkConfig}
  theme={{
    colors: { primary: '#6750A4' },
    features: {
      headerIcons: true,
      headerBackground: false,
      background: true,
      outlineComponents: false,
    }
  }}
>
```

### Advanced Overrides

```tsx theme={null}
<WidgetProvider
  sdkConfig={sdkConfig}
  theme={{
    colors: { primary: '#6750A4' },
    overrides: {
      background: {
        main: '#FFFFFF',
        layer1: '#F5F5F5',
        layer2: '#EEEEEE',
        layer3: '#E0E0E0',
      },
      text: {
        primary: '#1A1A1A',
        secondary: '#666666',
        disabled: '#9E9E9E',
      }
    }
  }}
>
```

## Common Integration Updates

### RainbowKit

```diff theme={null}
  function BridgePage() {
    const { openConnectModal } = useConnectModal();
    const { disconnect } = useDisconnect();

    return (
      <Widget
-       config={{
-         onOpenConnectModal: openConnectModal,
-         onDisconnectWallet: disconnect,
-       }}
+       onConnectClick={openConnectModal}
+       onDisconnectClick={disconnect}
      />
    );
  }
```

### Dynamic.xyz

```diff theme={null}
  function BridgePage() {
    const { setShowAuthFlow } = useDynamicContext();

    return (
      <Widget
-       config={{
-         onOpenConnectModal: () => setShowAuthFlow(true),
-       }}
+       onConnectClick={() => setShowAuthFlow(true)}
      />
    );
  }
```

### ConnectKit

```diff theme={null}
  function BridgePage() {
    const { openConnectModal } = useModal();
    const { disconnect } = useDisconnect();

    return (
      <Widget
-       config={{
-         onOpenConnectModal: openConnectModal,
-         onDisconnectWallet: disconnect,
-       }}
+       onConnectClick={openConnectModal}
+       onDisconnectClick={disconnect}
      />
    );
  }
```

## TypeScript Updates

The type definitions have changed significantly:

```typescript theme={null}
// Old types (v0.x)
import type { WidgetProps, WidgetConfig } from '@metalayer/widget';

// v0.x used nested config object
const props: WidgetProps = {
  config: {
    onOpenConnectModal: () => void,
    onDisconnectWallet?: () => void,
    onSubmitTransaction?: (sourceChainId?: number, destChainId?: number, amount?: string) => void,
    onSelectToken?: (direction: 'source' | 'destination', chainId: number, tokenAddress: string) => void,
    className?: string,
    source?: { chainId: number; tokenAddress?: string },
    destination?: { chainId: number; tokenAddress?: string },
  }
};

// New types (v1.x)
import type { WidgetProps } from '@metalayer/widget';

const props: WidgetProps = {
  // REQUIRED callback
  onConnectClick: () => void,

  // Optional callbacks
  onDisconnectClick?: () => void,
  onTransactionSubmitted?: (
    sourceChainId?: number,
    destChainId?: number,
    amount?: string
  ) => void,
  onTokenSelected?: (
    direction: 'source' | 'destination',
    chainId: number,
    tokenAddress: string
  ) => void,

  // Optional configuration
  source?: { chainId: number; tokenAddress?: string },
  destination?: { chainId: number; tokenAddress?: string },
  className?: string,
  isConnecting?: boolean,
};
```

### Additional Exported Types

v1.x exports comprehensive TypeScript types for all configuration:

```typescript theme={null}
import type {
  // Widget types
  WidgetProps,

  // Provider types
  WidgetProviderProps,

  // Theme types
  ThemeConfig,
  Theme,
  ThemeMode,
  PredefinedTheme,
  ThemeFeatures,
  CornerRadiusStyle,
  ShadowStyle,
  FontFamilyConfig,
  GoogleFontsConfig,
  CustomFontConfig,

  // Solana types (if using Solana support)
  WidgetSolanaSigner,
  WidgetSolanaProps,
} from '@metalayer/widget';
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="Property 'config' does not exist">
    Remove the `config` wrapper and pass props directly to `<Widget>`.
  </Accordion>

  <Accordion title="brandColor is deprecated">
    Use `theme={{ colors: { primary: 'your-color' } }}` instead.
  </Accordion>

  <Accordion title="onOpenConnectModal is not a valid prop">
    Rename to `onConnectClick`.
  </Accordion>

  <Accordion title="onSelectToken callback not firing">
    Rename to `onTokenSelected`.
  </Accordion>
</AccordionGroup>

## Best Practices

1. **Use the new theme system** - It provides better customization and consistency
2. **Leverage TypeScript** - The new types provide better autocomplete and type safety
3. **Optional disconnect** - Only provide `onDisconnectClick` if your wallet library supports it
4. **Test callbacks** - Ensure all renamed callbacks are working correctly after migration
