Overview
The swap component library provides a complete token swap interface with real-time quotes, slippage protection, and price charts. Designed for seamless integration with your DApp.
Composants internes au dashboard YaniPay
@yanipay/ui publié sur npm. Les exemples de code ci-dessous montrent les patterns réels utilisés dans la codebase, avec les imports corrects depuis les chemins internes du projet.Composants Production-Ready
SwapWidget
Complete swap interface
TokenSelector
Searchable token picker
SwapPriceChart
Interactive price history
Pourquoi ces Composants ?
Construire une interface de swap DeFi from scratch est complexe et risqué. Ces composants encapsulent les meilleures pratiques et éliminent les erreurs courantes.
Avantages de la librairie
- Intégration rapide : Ajoutez un swap complet en 3 lignes de code avec le SwapWidget
- Gestion du slippage : Protection automatique contre les attaques sandwich et le front-running
- UX optimisée : Animations fluides, feedback instantané, états de loading clairs
- Thème personnalisable: S'adapte à votre design system avec des variables CSS
Mode Embedded
variant="embedded"pour intégrer le swap sans la card wrapper. Idéal pour l'intégrer dans votre propre UI sans conflit de styles.Cas d'Utilisation
Découvrez comment différents profils utilisent ces composants.
Sophie
Développeur DApp
Intègre SwapWidget dans sa DApp
Sophie utilise le SwapWidget pré-construit pour ajouter une fonctionnalité d'échange à son application NFT marketplace. 3 lignes de code suffisent pour une intégration complète.
Lucas
Trader crypto
Personnalise les paramètres de slippage
Lucas utilise le mode expert pour ajuster le slippage à 0.1% sur ses swaps de tokens volatils. Le SwapSettings lui donne un contrôle total.
Marie
Investisseur DeFi
Analyse les prix avant swap
Marie utilise le SwapPriceChart pour analyser l'historique des prix sur 7 jours avant de décider du timing optimal pour son échange YANI/USDC.
Thomas
Holder long terme
Sélectionne rapidement ses tokens favoris
Thomas a configuré YANI, ETH et USDC comme tokens favoris. Le TokenSelector les affiche en premier pour des swaps ultra-rapides.
Architecture du Swap
Comment les composants interagissent avec le DEX YaniPay.
Vue d'ensemble
Flux d'exécution
Séquence détaillée d'un swap de tokens, de l'input utilisateur à la confirmation on-chain.
Slippage et Price Impact
SwapWidget Component
The main swap interface with token inputs, quote display, and execution:
1 // NOTE: Ces composants font partie du dashboard YaniPay. 2 // Ils ne sont PAS disponibles en tant que package npm standalone. 3 // Chemin réel : app/(dashboard)/dashboard/defi/swap/PageContent.tsx 4 5 'use client'; 6 7 import { useState } from 'react'; 8 import { defiApi } from '@platform/api/clients/web'; 9 import { 10 useAccount, 11 useSwapTokens, 12 useYaniTokenBalance, 13 useYaniApprove, 14 getContractAddress, 15 } from '@/lib/web3'; 16 import { useChainId } from 'wagmi'; 17 import { toast } from 'sonner'; 18 import type { CryptoAssetDTO, SwapQuoteDTO } from '@platform/api/contracts/defi'; 19 20 // Obtenir un devis de swap via l'API 21 export async function getSwapQuote( 22 tokenIn: string, 23 tokenOut: string, 24 amount: string 25 ): Promise<SwapQuoteDTO> { 26 const data = await defiApi.getSwapQuoteGet({ tokenIn, tokenOut, amount }); 27 return data; 28 } 29 30 // Exécuter un swap via l'API 31 export async function executeSwap(quoteId: string, slippage: string) { 32 const result = await defiApi.executeSwap({ quoteId, slippage }); 33 return result; 34 } 35 36 // Exemple d'usage dans un composant 37 export function SwapExample() { 38 const { address, isConnected } = useAccount(); 39 const chainId = useChainId(); 40 const { swap: onChainSwap, isPending: swapPending } = useSwapTokens(); 41 const { data: yaniBalance } = useYaniTokenBalance(); 42 43 const handleSwap = async (tokenIn: string, tokenOut: string, amount: string) => { 44 try { 45 // 1. Obtenir le devis 46 const quote = await getSwapQuote(tokenIn, tokenOut, amount); 47 48 // 2. Exécuter via l'API (mode off-chain) ou on-chain 49 const result = await executeSwap(quote.id, '0.5'); 50 toast.success(`Swap effectué ! TX: ${result.transactionHash}`); 51 } catch (error) { 52 toast.error('Erreur lors du swap'); 53 } 54 }; 55 56 return null; // Voir le composant complet dans le dashboard 57 }
TokenSelector Component
A searchable modal for selecting tokens with balance display:
1 // NOTE: Pas de composant TokenSelector standalone dans YaniPay. 2 // La sélection de tokens est gérée inline dans le SwapPage du dashboard. 3 // Chemin réel : app/(dashboard)/dashboard/defi/swap/PageContent.tsx 4 5 import { defiApi } from '@platform/api/clients/web'; 6 import type { CryptoAssetDTO } from '@platform/api/contracts/defi'; 7 8 // Charger la liste des assets disponibles pour le swap 9 async function loadSwapAssets(): Promise<CryptoAssetDTO[]> { 10 // GET /api/defi/assets?type=swap 11 const assets = await defiApi.getSwapAssets('swap'); 12 return assets; 13 } 14 15 // Pattern utilisé dans le dashboard YaniPay 16 // Les assets incluent : symbol, name, address, decimals, logoUrl, priceUsd 17 18 // Exemple de rendu d'un token dans une liste de sélection 19 function TokenItem({ asset, balance }: { asset: CryptoAssetDTO; balance?: number }) { 20 return ( 21 <div className="flex items-center gap-3 p-3 rounded-lg cursor-pointer hover:bg-gray-800"> 22 <div className="w-10 h-10 rounded-full bg-gray-700 flex items-center justify-center"> 23 <span className="text-xs font-bold">{asset.symbol.slice(0, 2)}</span> 24 </div> 25 <div className="flex-1"> 26 <div className="flex justify-between"> 27 <span className="font-semibold">{asset.symbol}</span> 28 <span>{balance?.toFixed(4) ?? '0.0000'}</span> 29 </div> 30 <div className="flex justify-between text-sm text-gray-500"> 31 <span>{asset.name}</span> 32 <span>${((balance ?? 0) * (asset.priceUsd ?? 0)).toFixed(2)}</span> 33 </div> 34 </div> 35 </div> 36 ); 37 }
SwapSettings Component
Configure slippage tolerance, deadline, and other swap parameters:
1 // NOTE: Les paramètres de swap sont gérés par état local dans le SwapPage dashboard. 2 // Pas de composant SwapSettings standalone dans le package @yanipay/ui (qui n'existe pas). 3 4 'use client'; 5 6 import { useState } from 'react'; 7 import { Settings } from 'lucide-react'; 8 9 // Pattern réel utilisé dans app/(dashboard)/dashboard/defi/swap/PageContent.tsx 10 interface SwapSettings { 11 slippage: string; // ex: '0.5' (en %) 12 deadline: number; // ex: 20 (en minutes) 13 expertMode: boolean; 14 } 15 16 export function useSwapSettings(initial?: Partial<SwapSettings>) { 17 const [settings, setSettings] = useState<SwapSettings>({ 18 slippage: initial?.slippage ?? '0.5', 19 deadline: initial?.deadline ?? 20, 20 expertMode: initial?.expertMode ?? false, 21 }); 22 23 return { 24 settings, 25 updateSettings: (patch: Partial<SwapSettings>) => 26 setSettings((prev) => ({ ...prev, ...patch })), 27 }; 28 } 29 30 // Rendu des presets de slippage dans le dashboard 31 export function SlippagePresets({ value, onChange }: { 32 value: string; 33 onChange: (v: string) => void; 34 }) { 35 const presets = ['0.1', '0.5', '1.0']; 36 37 return ( 38 <div className="flex gap-2"> 39 {presets.map((preset) => ( 40 <button 41 key={preset} 42 onClick={() => onChange(preset)} 43 className={`px-3 py-1 rounded-lg text-sm ${ 44 value === preset 45 ? 'bg-purple-600 text-white' 46 : 'bg-gray-800 text-gray-400 hover:text-white' 47 }`} 48 > 49 {preset}% 50 </button> 51 ))} 52 </div> 53 ); 54 }
SwapPriceChart Component
Interactive price chart for the selected token pair:
1 // NOTE: Le graphique de prix utilise l'API GET /api/defi/dex/chart 2 // et la librairie recharts (pas @yanipay/ui qui n'existe pas). 3 4 'use client'; 5 6 import { useState, useEffect } from 'react'; 7 import { LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts'; 8 import { apiGet } from '@/lib/api/client'; 9 10 // Endpoint réel : GET /api/defi/dex/chart?tokenIn=YANI&tokenOut=USDC&timeframe=24h 11 interface PricePoint { 12 timestamp: number; 13 price: number; 14 volume?: number; 15 } 16 17 export function SwapPriceChart({ 18 tokenIn, 19 tokenOut, 20 timeframe = '24h', 21 height = 300, 22 }: { 23 tokenIn: string; 24 tokenOut: string; 25 timeframe?: '1h' | '24h' | '7d' | '30d'; 26 height?: number; 27 }) { 28 const [data, setData] = useState<PricePoint[]>([]); 29 30 useEffect(() => { 31 apiGet<PricePoint[]>( 32 `/api/defi/dex/chart?tokenIn=${tokenIn}&tokenOut=${tokenOut}&timeframe=${timeframe}` 33 ).then(setData).catch(console.error); 34 }, [tokenIn, tokenOut, timeframe]); 35 36 return ( 37 <ResponsiveContainer width="100%" height={height}> 38 <LineChart data={data}> 39 <XAxis dataKey="timestamp" /> 40 <YAxis /> 41 <Tooltip /> 42 <Line 43 type="monotone" 44 dataKey="price" 45 stroke="#8b5cf6" 46 dot={false} 47 strokeWidth={2} 48 /> 49 </LineChart> 50 </ResponsiveContainer> 51 ); 52 }
Props Reference
SwapWidget Props
| Prop | Type | Description |
|---|---|---|
defaultTokenIn | string | Initial input token |
defaultTokenOut | string | Initial output token |
defaultSlippage | string | Default slippage (e.g., '0.5') |
allowedTokens | string[] | Restrict to specific tokens |
showPriceChart | boolean | Show price chart |
onSwapComplete | (result) => void | Swap success callback |
TokenSelector Props
| Prop | Type | Description |
|---|---|---|
value | Token | null | Selected token |
onChange | (token) => void | Selection handler |
showBalance | boolean | Show user's balance |
showFavorites | boolean | Show favorites section |
Best Practice
onError pour gérer gracieusement les échecs de swap. Les erreurs les plus courantes (insufficient balance, slippage exceeded) ont des messages user-friendly.Références
Ressources officielles pour approfondir les concepts DEX et AMM.
AMM & DEX
React Components
Related Resources
Derniere mise a jour : 2026-03-31