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
| Parameter | Description | Example |
|---|---|---|
tokenIn | Input token contract address | tokenIn=0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392 |
tokenOut | Output token contract address | tokenOut=0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7 |
Tokens can be changed by the user after the widget loads.
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) |
For hex colors, use
%23 instead of # in the URL (e.g., %23FFFFFF for white).Features
| Parameter | Description | Values |
|---|---|---|
notifications | Show/hide notification cards | true (default) or false |
Complete Example
HTML
<iframe
src="https://symph.ag/embed?tokenIn=0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392&tokenOut=0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7&bgColor=white&theme=light¬ifications=false"
style="width: 100%; min-height: 650px; border: none; border-radius: 12px;"
title="Symphony Swap Widget"
></iframe>Popular Sei Token Addresses (Mainnet)
| Token | Address |
|---|---|
| WSEI | 0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7 |
| USDC (native) | 0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392 |
| USDT0 | 0x9151434b16b9763660705744891fA906F660EcC5 |
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