This sample app demonstrates how to use Circle's Bridge Kit to transfer USDC across chains with a wallet-connect experience for both EVM and Solana testnets.
- Node.js 24+ (recommended LTS) and npm
- An EVM wallet (e.g., MetaMask) and a Solana wallet (e.g., Phantom)
- Testnet USDC on the relevant chains and native tokens for gas fees
-
Install dependencies:
npm install
-
Start the app in development:
npm run dev
This runs both:
- Client (Vite) on
http://localhost:5173 - Preview server (Hono) on
http://localhost:8787
The Vite dev server proxies /api to the preview server per vite.config.ts.
-
Build for production:
npm run build
Outputs static assets to dist/ and type-checks the project.
-
Preview the production build locally:
npm run preview
Serves dist/ using the Hono server on http://localhost:8787.
- Supported chains are fetched from Bridge Kit at runtime and mapped to Wagmi in
src/lib/wagmiConfig.tsandsrc/lib/mapChains.ts. - Wallet wiring:
useEvmAdapterbuilds a Bridge Kit EVM adapter from the active Wagmi connector provider.useSolanaWalletconnects towindow.solanaand builds a Solana adapter.
- The main flow is in
src/App.tsx:- Pick source and destination chains (testnets), enter USDC amount, connect wallets.
- On submit, we optionally switch the EVM network, then call
useBridge().bridge(...). - Bridge Kit emits events; the UI updates progress and logs.
- On success, balances refresh and success UI appears.
- USDC balances are queried via Bridge Kit actions (
usdc.balanceOf) insrc/hooks/useUsdcBalance.ts.
src/App.tsx: Main UI and bridging flowsrc/lib/wagmiConfig.ts: Dynamically builds Wagmi config from Bridge Kit chainssrc/lib/mapChains.ts: Maps Bridge Kit chain metadata to WagmiChainsrc/hooks/useBridge.ts: Thin wrapper aroundBridgeKit().bridge(...)with event handlingsrc/hooks/useEvmAdapter.ts: Creates EVM adapter from Wagmi providersrc/hooks/useSolanaWallet.ts: Connects Solana wallet and creates adaptersrc/hooks/useUsdcBalance.ts: Reads USDC balances per chainapi/server.ts: Hono server to serve the built app (dist/)
- This sample is scoped to testnets (filters Bridge Kit chains by
isTestnet === true). - If multiple EVM providers are present (e.g., Phantom EVM + MetaMask), the app attempts a sane default; you can switch via the wallet UI.
- If wallet network switching is rejected, the bridging flow will skip and you can try again.
- After use, disconnecting directly from your wallet UI can improve reliability between sessions.
npm run dev: Run preview server and Vite dev server concurrentlynpm run dev:server: Start the Hono preview server with live reloadnpm run dev:client: Start Vite dev servernpm run build: Build static assets and run type-checkingnpm run preview: Servedist/via Hono server
This sample application:
- Assumes testnet or sandbox usage only
- Does not store private keys in plaintext
- Uses environment variables for secrets
- Is not intended for production use without modification
See SECURITY.md for vulnerability reporting guidelines. Please report issues privately via Circle's bug bounty program.