> ## Documentation Index
> Fetch the complete documentation index at: https://seilabs-docs-evm-cookbook.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# In-App Swaps - Symphony Integration Guide

> Guide to integrating the Symphony swap widget into your Sei application for seamless token exchanges.

export const ThemeAwareIframe = ({src, title, className, style, loading = 'lazy', allow, allowFullScreen} = {}) => {
  const [frameSrc, setFrameSrc] = useState(null);
  useEffect(() => {
    if (!src) {
      setFrameSrc(null);
      return;
    }
    try {
      const url = new URL(src);
      url.searchParams.set('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light');
      setFrameSrc(url.toString());
    } catch {
      setFrameSrc(src);
    }
  }, [src]);
  if (!frameSrc) {
    return <div className={className} style={style} aria-hidden="true" />;
  }
  return <iframe src={frameSrc} title={title} className={className} style={style} loading={loading} allow={allow} allowFullScreen={allowFullScreen} />;
};

In-app swaps let users exchange tokens directly in your Sei dApp.

## Overview

Swap widgets are embeddable UI components that hide the complexity of interacting with decentralized exchanges (DEXs) and liquidity aggregators. They have these benefits:

* Users can swap tokens without leaving your dApp.
* You do not need to redirect users to external DEX interfaces.
* Many providers offer fee-sharing mechanisms, which can give you revenue.
* Some widgets let users bridge assets from other chains.

## Symphony swap widget

[Symphony](https://symph.ag) is a native DEX aggregator on Sei. It offers the simplest integration: an embedded iframe.

### Quick start

```html theme={null}
<iframe src="https://symph.ag/embed"></iframe>
```

### Live demo

<div style={{ display: 'flex', justifyContent: 'center' }}>
  <ThemeAwareIframe src="https://symph.ag/embed" style={{ width: '100%', maxWidth: '420px', minWidth: '377px', minHeight: '680px', border: 'none', borderRadius: '12px' }} loading="lazy" title="Symphony Swap Widget Demo" />
</div>

### Size requirements

* **Minimum width**: `377px`
* **Minimum height**: `650px` (recommended to prevent scrolling in the wallet modal)
* **Optimal height**: `680-685px`

### URL parameters

To customize the widget, append query parameters to the URL:

#### Token selection

| Parameter | Description | Example |
| - | - | - |
| `tokenIn` | Input token contract address | `tokenIn=0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392` |
| `tokenOut` | Output token contract address | `tokenOut=0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7` |

<Info>Users can change the tokens after the widget loads.</Info>

#### Appearance

| Parameter | Description | Supported Formats |
| - | - | - |
| `bgColor` | Background color | Hex (`%23FFFFFF`), Named (`white`), RGB (`rgb(255,255,255)`), RGBA (`rgba(255,255,255,0.9)`) |
| `theme` | Color theme of the widget | `light` or `dark` (defaults to `dark` if not specified) |

<Warning>For hex colors, use `%23` instead of `#` in the URL. For example, use `%23FFFFFF` for white.</Warning>

#### Features

| Parameter | Description | Values |
| - | - | - |
| `notifications` | Show/hide notification cards | `true` (default) or `false` |

### Complete example

<Tabs>
  <Tab title="HTML">
    ```html theme={null}
    <iframe
      src="https://symph.ag/embed?tokenIn=0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392&tokenOut=0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7&bgColor=white&theme=light&notifications=false"
      style="width: 100%; min-height: 650px; border: none; border-radius: 12px;"
      title="Symphony Swap Widget"
    ></iframe>
    ```
  </Tab>

  <Tab title="React">
    ```jsx theme={null}
    function SwapWidget() {
      const tokenIn = "0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392";
      const tokenOut = "0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7";
      
      return (
        <iframe
          src={`https://symph.ag/embed?tokenIn=${tokenIn}&tokenOut=${tokenOut}&theme=dark`}
          style={{
            width: '100%',
            minHeight: '650px',
            border: 'none',
            borderRadius: '12px'
          }}
          title="Symphony Swap Widget"
        />
      );
    }
    ```
  </Tab>

  <Tab title="Next.js">
    ```tsx theme={null}
    'use client';

    export default function SwapPage() {
      const params = new URLSearchParams({
        tokenIn: '0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392',
        tokenOut: '0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7',
        theme: 'dark',
        notifications: 'true'
      });

    return (

    <div className="max-w-md mx-auto">
      <iframe src={`https://symph.ag/embed?${params.toString()}`} className="w-full min-h-[650px] border-0" title="Symphony Swap" />
    </div>
    ); }

    ```
  </Tab>
</Tabs>

### Popular Sei token addresses (Mainnet)

| Token | Address |
| - | - |
| WSEI | [`0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7`](https://seiscan.io/address/0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7) |
| USDC (native) | [`0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392`](https://seiscan.io/address/0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392) |
| USDT0 | [`0x9151434b16b9763660705744891fA906F660EcC5`](https://seiscan.io/address/0x9151434b16b9763660705744891fA906F660EcC5) |

***

## Best practices

### Security considerations

<Warning>
  **Security checklist**

  * Check that iframe sources match the official domains.
  * Add Content Security Policy (CSP) headers.
</Warning>

### Performance optimization

```tsx theme={null}
// Lazy load swap widgets to improve initial page load
import dynamic from 'next/dynamic';

const SwapWidget = dynamic(() => import('./SwapWidget'), {
  loading: () => <div className="animate-pulse h-[650px] bg-gray-800 " />,
  ssr: false
});
```

### Responsive design

```css theme={null}
/* Ensure swap widgets are responsive */
.swap-container {
  width: 100%;
  max-width: 420px;
  margin: 0 auto;
}

.swap-container iframe {
  width: 100%;
  min-height: 650px;
  border: none;
  border-radius: 12px;
}

@media (max-width: 480px) {
  .swap-container {
    max-width: 100%;
    padding: 0 16px;
  }
}
```

### Error handling

```tsx theme={null}
import { useState } from 'react';

function SwapWidgetWithFallback() {
  const [error, setError] = useState(false);

  if (error) {
    return (
      <div className="p-6 bg-sei-maroon-200/20  text-center">
        <p>Swap widget failed to load.</p>
        <a href="https://symph.ag" target="_blank" rel="noopener noreferrer" className="text-blue-400 underline">
          Open Symphony directly →
        </a>
      </div>
    );
  }

  return <iframe src="https://symph.ag/embed" onError={() => setError(true)} style={{ width: '100%', minHeight: '650px', border: 'none' }} title="Swap Widget" />;
}
```

***

## Additional resources

* [Symphony Swap Widget Documentation](https://docs.symph.ag/widget/symphony-swap-widget)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.