Skip to Content
EVMIn-App Swaps

In-App Swaps Integration Guide

Integrating in-app swap functionality into your Sei application enables users to exchange tokens directly within your platform, enhancing user experience and engagement.

Overview

Swap widgets are embeddable UI components that abstract the complexity of interacting with decentralized exchanges (DEXs) and liquidity aggregators. They provide:

  • Seamless UX: Users can swap tokens without leaving your app
  • Reduced Friction: No need to redirect users to external DEX interfaces
  • Revenue Opportunities: Many providers offer fee-sharing mechanisms
  • Cross-Chain Support: Some widgets enable bridging assets from other chains

Symphony Swap Widget

Symphony  is a native DEX aggregator on Sei, offering the simplest integration via iframe embedding.

Quick Start

<iframe src="https://symph.ag/embed"></iframe>

Live Demo

Size Requirements

  • Minimum Width: 377px
  • Minimum Height: 650px (recommended to prevent wallet modal scrolling)
  • Optimal Height: 680-685px

URL Parameters

Customize the widget by appending query parameters:

Token Selection

ParameterDescriptionExample
tokenInInput token contract addresstokenIn=0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392
tokenOutOutput token contract addresstokenOut=0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7
Tokens can be changed by the user after the widget loads.

Appearance

ParameterDescriptionSupported Formats
bgColorBackground colorHex (%23FFFFFF), Named (white), RGB (rgb(255,255,255)), RGBA (rgba(255,255,255,0.9))
themeColor theme of the widgetlight or dark (defaults to dark if not specified)
For hex colors, use %23 instead of # in the URL (e.g., %23FFFFFF for white).

Features

ParameterDescriptionValues
notificationsShow/hide notification cardstrue (default) or false

Complete Example

<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>
TokenAddress
WSEI0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7
USDC (native)0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392
USDT00x9151434b16b9763660705744891fA906F660EcC5

Best Practices

Security Considerations

Security Checklist

  • ✅ Validate that iframe sources match official domains
  • ✅ Implement Content Security Policy (CSP) headers

Performance Optimization

// 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 rounded-xl" />, ssr: false });

Responsive Design

/* 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

import { useState } from 'react'; function SwapWidgetWithFallback() { const [error, setError] = useState(false); if (error) { return ( <div className="p-6 bg-red-900/20 rounded-xl 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

Last updated on