@evaafi/bridge-widget
v0.8.11
Published
Cross-chain bridge widget powered by Stargate Protocol with multi-chain wallet support
Readme
EVAA Bridge Widget
A production-ready cross-chain bridge widget powered by Stargate Protocol with comprehensive multi-chain wallet support (Ethereum, TON, Tron).
Features
- 🔗 Multi-Chain Support: Ethereum, TON, Tron, and other EVM chains
- 🦊 Wallet Integration: MetaMask, TonConnect, TronLink, WalletConnect
- 💱 Real-time Quotes: Get instant cross-chain swap quotes via Stargate Protocol
- ⚡ Transaction Management: Built-in transaction monitoring and status tracking
- 📊 Balance Tracking: Real-time wallet balance updates
- 🎨 Themeable: Light/dark mode with customizable styling
- 🌐 i18n: Built-in internationalization (EN/RU, easily extensible)
- 📱 Responsive: Mobile-friendly design
Installation
npm install @evaa/bridge-widget
# or
yarn add @evaa/bridge-widget
# or
pnpm add @evaa/bridge-widgetPeer Dependencies
Install required peer dependencies:
npm install react react-dom @tanstack/react-queryFor specific chain support, install additional peer dependencies:
# For Ethereum/EVM chains
npm install wagmi ethers connectkit
# For TON
npm install @tonconnect/ui-react @ton/core @ton/crypto @ton/ton
# For Tron (with specific WalletConnect versions)
npm install @tronweb3/tronwallet-adapter-react-hooks @tronweb3/tronwallet-adapters tronweb @walletconnect/universal-provider@^2.23.0 @walletconnect/modal@^2.7.0⚠️ Important: When using TRON WalletConnect support, ensure you install the exact versions specified above (
@walletconnect/modal@^2.7.0and@walletconnect/universal-provider@^2.23.0) to avoid runtime errors likethis.client.core.relayer.publishCustom is not a function.
Version Lock (Recommended)
To prevent version conflicts, add these overrides to your package.json:
{
"overrides": {
"@walletconnect/modal": "^2.7.0",
"@walletconnect/universal-provider": "^2.23.0"
}
}For yarn, use resolutions instead of overrides. For pnpm, add to your .npmrc:
@walletconnect/modal=^2.7.0
@walletconnect/universal-provider=^2.23.0Required shadcn/ui Components
This library requires certain shadcn/ui components to be installed in your project. The library does not bundle these components to avoid duplication and allow you to use your own styled versions.
Required components: accordion, button, card, dialog, input, skeleton, switch, tooltip
Install them using shadcn CLI:
npx shadcn@latest add accordion button card dialog input skeleton switch tooltipImportant: Your project must have the following path aliases configured:
@/components/ui- for UI components@/lib/utils- for thecnutility function
For detailed setup instructions, see SHADCN_COMPONENTS.md.
Quick Start
1. Basic Setup
import { animated, useSpring } from '@react-spring/web';
import { useTranslation } from 'react-i18next';
import { WalletProvider } from '@tronweb3/tronwallet-adapter-react-hooks';
import { TronLinkAdapter } from '@tronweb3/tronwallet-adapters';
import { ConnectKitProvider } from 'connectkit';
import { EvaaBridge } from '@rash2x/bridge-widget';
import { TransactionConfirmVector } from '@/components/vectors/TransactionConfirm';
import { TransactionProgressVector } from '@/components/vectors/TransactionProgress';
import { TransactionSuccessVector } from '@/components/vectors/TransactionSuccess';
import Fireworks from 'react-canvas-confetti/dist/presets/fireworks';
import { TransactionFailedVector } from '@/components/vectors/TransactionFailed';
import { useMemo } from 'react';
import { WagmiProvider, createConfig, http } from 'wagmi';
import { mainnet, arbitrum, polygon, base, bsc } from 'wagmi/chains';
import { injected, walletConnect, metaMask } from 'wagmi/connectors';
import { Card } from '@/components/ui/card';
const walletConnectProjectId = import.meta.env.VITE_WALLETCONNECT_PROJECT_ID || '5e81fa2f7739ab20482103c77a1b5cbf';
const config = createConfig({
chains: [mainnet, arbitrum, polygon, base, bsc],
connectors: [injected(), metaMask(), walletConnect({ projectId: walletConnectProjectId })],
transports: {
[mainnet.id]: http(),
[arbitrum.id]: http(),
[polygon.id]: http(),
[base.id]: http(),
[bsc.id]: http()
}
});
export const BridgePage = () => {
const { t, i18n } = useTranslation();
const [props] = useSpring(() => ({
from: { opacity: 0 },
to: { opacity: 1 }
}));
const tronAdapters = useMemo(() => [new TronLinkAdapter()], []);
const transactionIcons = useMemo(
() => ({
confirm: (
<>
<TransactionConfirmVector />
<div className="on-circle on-circle-confirm-small under-noise"></div>
<div className="on-circle on-circle-confirm-big under-noise"></div>
</>
),
progress: (
<>
<TransactionProgressVector className="progress-rocket" />
<div className="on-circle on-circle-progress-small under-noise"></div>
<div className="on-circle on-circle-progress-big under-noise"></div>
<div className="meteors-container under-noise">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</>
),
success: (
<>
<TransactionSuccessVector />
<Fireworks
autorun={{
speed: 3,
duration: 1000,
delay: 300
}}
/>
<div className="on-circle on-circle-success-small under-noise"></div>
<div className="on-circle on-circle-success-big under-noise"></div>
</>
),
failed: (
<>
<TransactionFailedVector />
<div className="on-circle on-circle-failed-small under-noise"></div>
<div className="on-circle on-circle-failed-big under-noise"></div>
</>
)
}),
[]
);
return (
<animated.div style={props} className="space-y-4 pb-5 overflow-auto">
<Card className="bg-master rounded-lg py-6 px-5 md:grid md:grid-cols-2 gap-8 lg:gap-10">
<header className="px-5 space-y-3 md:px-0">
<h1 className="font-display font-black shrink-0 text-5xl">{t('bridge')}</h1>
<p className="text-sm text-muted-foreground">{t('bridgeDescription')}</p>
</header>
<WagmiProvider config={config}>
<ConnectKitProvider>
<WalletProvider adapters={tronAdapters} disableAutoConnectOnLoad={true}>
<EvaaBridge defaultLanguage={i18n.language} transactionIcons={transactionIcons} />
</WalletProvider>
</ConnectKitProvider>
</WagmiProvider>
</Card>
</animated.div>
);
};2. With Event Handlers and Language
<EvaaBridge
defaultLanguage="ru" // Set default language (en, ru)
onSwapSuccess={(data) => {
console.log("Swap completed:", data);
}}
onSwapError={(error) => {
console.error("Swap failed:", error);
}}
onInitialized={() => {
console.log("Bridge initialized");
}}
onDataUpdate={(data) => {
console.log("Bridge data updated:", data);
}}
/>Props
EvaaBridgeProps
| Prop | Type | Description |
| ----------------- | ------------------------------------------- | ----------------------------------------------------------------------- |
| className | string | Optional CSS class for custom styling |
| defaultLanguage | string | Language for the widget UI (default: 'en'). Supported: 'en', 'ru' |
| tonClient | TonClient | Optional TON client instance |
| tonApiKey | string | Optional TON API key |
| onInitialized | () => void | Callback when bridge is initialized |
| onSwapStart | (data: SwapStartData) => void | Callback when swap starts |
| onSwapSuccess | (data: SwapSuccessData) => void | Callback when swap succeeds |
| onSwapError | (error: SwapErrorData) => void | Callback when swap fails |
| onDataUpdate | (data: BridgeExternalData) => void | Unified callback with chains/tokens/url params and quote details |
Bridge Data Callback
onDataUpdate fires whenever the user changes the amount, token, chains or when a new quote arrives.
The BridgeExternalData payload includes:
fromChain/toChain– currently selected networkssourceToken/destinationToken– token metadata per chainamount&urlParams– current form state (ready to persist in URL/router)quoteDetails– parsed amounts, min received, and fee breakdown (no raw quote exposure)
This makes it easy to persist widget state, update analytics, or show custom UI in a host app with a single subscription.
If you prefer to pull the same snapshot from your own components (without using the callback) you can call the exported useBridgeExternalData hook directly.
Theme Customization
Customize the widget's appearance by overriding CSS variables in your own stylesheet:
:root {
--primary: #0095f9; /* Primary brand color */
--background: #ffffff; /* Background color */
--foreground: #171717; /* Text color */
--card: #f2f2f2; /* Card background */
--border: #00000029; /* Border color */
--radius: 0.625rem; /* Border radius */
/* ... see dist/styles.css for all available variables */
}
[data-theme="dark"] {
--primary: #5200ff;
--background: #000000;
--foreground: #ffffff;
/* ... dark theme overrides */
}Supported Chains
- Ethereum (Mainnet)
- Arbitrum
- Polygon
- Base
- BNB Chain
- TON (The Open Network)
- Tron
API Integration
The widget integrates with Stargate Protocol API for:
- Cross-chain token swaps
- Real-time quotes
- Transaction routing
- Fee estimation
TypeScript
The package is written in TypeScript and includes full type definitions.
import type { EvaaBridgeProps, Chain, Token } from "@evaa/bridge-widget";Development
# Install dependencies
npm install
# Run development server
npm run dev
# Build library
npm run build:lib
# Lint
npm run lintTroubleshooting
WalletConnect Error: this.client.core.relayer.publishCustom is not a function
This error occurs due to version conflicts with WalletConnect packages. To fix:
Ensure exact versions are installed:
npm install @walletconnect/modal@^2.7.0 @walletconnect/universal-provider@^2.23.0Add package overrides to your
package.json:{ "overrides": { "@walletconnect/modal": "^2.7.0", "@walletconnect/universal-provider": "^2.23.0" } }Delete
node_modulesand lock file, then reinstall:rm -rf node_modules package-lock.json npm installFor yarn users, use
resolutionsinstead ofoverrides:{ "resolutions": { "@walletconnect/modal": "^2.7.0", "@walletconnect/universal-provider": "^2.23.0" } }For pnpm users, add to
.npmrc:@walletconnect/modal=^2.7.0 @walletconnect/universal-provider=^2.23.0
Other Common Issues
- Missing peer dependencies: Check that all required peer dependencies are installed for your chain (see Installation section)
- shadcn/ui component errors: Ensure all required shadcn components are installed (see Required shadcn/ui Components)
- Theme not working: Make sure you have CSS variables configured properly (see Theme Customization)
Contributing
Contributions are welcome! Please open an issue or submit a pull request.
License
MIT © EVAA Finance
Links
Support
For issues and questions:
- GitHub Issues: https://github.com/evaa-finance/bridge-widget/issues
- Email: [email protected]
