A React application demonstrating advanced Haystack Router SDK integration with TanStack Query (React Query) for automatic quote fetching and optimistic updates.
- Automatic quote fetching - Quotes are fetched automatically when a valid amount is entered
- Fresh quotes - Quotes automatically refetch every 15 seconds
- React Query integration - Uses
useQueryfor quotes anduseMutationfor swaps - Multiple wallet support (Pera, Defly, Lute)
- Modern wallet UI with
@txnlab/use-wallet-reactv4 - Real-time updates - No "Get Quote" button needed
- Execute swaps with slippage protection
- Display quote details and routing information
- Haystack Router API Key - A free tier key is included in
.env.example(60 requests/min). For production rate limits, request a key from support@txnlab.dev. - Node.js >= 20
- pnpm 10.20.0 or later
- Install dependencies from the repository root:
pnpm install- Create a
.envfile in this directory:
cp .env.example .env- The
.envfile comes pre-configured with the free tier API key. For production use, replace it with your dedicated key.
Run the development server:
pnpm devThe app will be available at http://localhost:5173
Build for production:
pnpm buildPreview the production build:
pnpm preview- Choose a wallet from the available options (Pera, Defly, or Lute)
- Click to connect your chosen wallet
- If you have multiple accounts, select the active account from the dropdown
- Select the assets you want to swap
- Enter the amount and slippage tolerance
- Quotes are fetched automatically - no button needed!
- Quotes refresh every 15 seconds to ensure you have the latest pricing
- Review the quote details (output amount, price impact, routing)
- Click "Execute Swap" to perform the swap
This example showcases how to use TanStack Query (React Query) with the Haystack Router SDK:
const { data: quote, error, isLoading } = useQuery({
queryKey: ['quote', fromAsset, toAsset, amount],
queryFn: async () => {
const router = new RouterClient({ apiKey, autoOptIn: true })
return await router.newQuote({
fromASAID: fromAsset,
toASAID: toAsset,
amount: amountInBaseUnits,
address: activeAddress,
})
},
enabled: isValidQuoteRequest(),
refetchInterval: 15000, // Refetch every 15 seconds
})const swapMutation = useMutation({
mutationFn: async () => {
const router = new RouterClient({ apiKey, autoOptIn: true })
const swap = await router.newSwap({
quote,
address: activeAddress,
signer: transactionSigner,
slippage: parseFloat(slippage),
})
return await swap.execute()
},
onSuccess: (result) => {
// Handle success
},
})- No manual "Get Quote" button - Quotes fetch automatically
- Auto-refresh - Fresh quotes every 15 seconds
- React Query hooks -
useQueryanduseMutationreplace manual state management - Simplified state - No
loadingorexecutingstate variables needed - Better UX - Users see quotes immediately as they type
The example is configured with multiple wallet providers in src/main.tsx:
const walletManager = new WalletManager({
wallets: [WalletId.DEFLY, WalletId.PERA, WalletId.LUTE],
defaultNetwork: 'mainnet',
options: {
resetNetwork: true,
},
});You can customize which wallets are available by modifying this configuration.
- This example uses mainnet (real assets!)
- Make sure you have sufficient ALGO/assets in your account
- The SDK automatically handles app and asset opt-ins when needed
- Slippage is set to 1% by default but can be adjusted
- Quotes automatically refresh to ensure accurate pricing