Executing Swaps
Execute swaps between stablecoins on the exchange. Swaps execute immediately against existing orders in the orderbook, providing instant liquidity for cross-stablecoin payments.
By the end of this guide you will be able to execute swaps, get price quotes, and manage slippage protection.
pnpx gitpick tempoxyz/examples/tree/main/examples/exchange
Swap implementation steps
Stablecoin swap recipes
Handling insufficient liquidity
Quote requests will fail with an InsufficientLiquidity error if there isn't enough liquidity in the orderbook to satisfy the requested amount.
Handle this error when fetching quotes:
import { Hooks } from 'wagmi/tempo'
import { parseUnits } from 'viem'
const alphaUsd = '0x20c0000000000000000000000000000000000001'
const betaUsd = '0x20c0000000000000000000000000000000000002'
function Swap () {
const amount = parseUnits ( '10' , 6
Stablecoin swap best practices
Always get quotes before swapping
Query the expected price before executing a swap to ensure you're getting a fair rate and to set appropriate slippage protection.
Set appropriate slippage protection
Use minAmountOut or maxAmountIn to protect against unfavorable price movements between quoting and execution.
Stablecoin swap learning resources
Set up your swap client Ensure that you have set up your client by following the guide .
Get a price quote Before executing a swap, get a quote to see the expected price.
Buy.tsx Sell.tsx
import { Hooks } from 'wagmi/tempo'
import { formatUnits , parseUnits } from 'viem'
const alphaUsd = '0x20c0000000000000000000000000000000000001'
const betaUsd = '0x20c0000000000000000000000000000000000002'
function Buy () {
const amount = parseUnits ( '10' , 6 )
// How much AlphaUSD do I need to spend to receive 10 BetaUSD?
const { data : quote } = Hooks . dex . useBuyQuote
tokenIn : alphaUsd ,
tokenOut : betaUsd ,
amountOut : amount ,
})
return < div >Quote: { formatUnits ( quote , 6 ) } </ div >
} import { Hooks } from 'wagmi/tempo'
import { formatUnits , parseUnits
Calculate slippage tolerance Set appropriate slippage based on your quote to protect against unfavorable price movements.
Approve stablecoin spend To execute a swap, you need to approve the Stablecoin DEX contract to spend the token you're using to fund the swap.
Execute a swap Batch the token approval with the swap in a single transaction for better UX.
)
const { data : quote , error } = Hooks.dex. useSellQuote ({
tokenIn: alphaUsd,
tokenOut: betaUsd,
amountIn: amount,
})
if (error) {
if (error.message. includes ( 'InsufficientLiquidity' )) {
return < div >Not enough liquidity available. Try a smaller amount.</ div >
}
return < div >Error: { error.message } </ div >
}
if ( ! quote) {
return < div >Loading quote...</ div >
}
return < div >Quote: { quote. toString () } </ div >
}
({
}
from
'viem'
const alphaUsd = '0x20c0000000000000000000000000000000000001'
const betaUsd = '0x20c0000000000000000000000000000000000002'
function Sell () {
const amount = parseUnits ( '10' , 6 )
// How much BetaUSD will I receive for 10 AlphaUSD?
const { data : quote } = Hooks . dex . useSellQuote
tokenIn : alphaUsd ,
tokenOut : betaUsd ,
amountIn : amount ,
})
return < div >Quote: { formatUnits ( quote , 6 ) } </ div >
}
Buy.tsx Sell.tsx
import { Hooks } from 'wagmi/tempo'
import { formatUnits , parseUnits } from 'viem'
const alphaUsd = '0x20c0000000000000000000000000000000000001'
const betaUsd = '0x20c0000000000000000000000000000000000002'
function Buy () {
const amount = parseUnits ( '10' , 6 )
// How much AlphaUSD do I need to spend to receive 10 BetaUSD?
const { data : quote } = Hooks . dex . useBuyQuote ({
tokenIn : alphaUsd ,
tokenOut : betaUsd ,
amountOut : amount ,
})
// Calculate 0.5% slippage tolerance
const slippageTolerance = 0.005
const maxAmountIn = quote
? quote * BigInt ( Math . floor (( 1 + slippageTolerance ) * 1000 )) /
: 0 n
return (
< div >
< div >Quote: { formatUnits ( quote , 6 ) } </ div >
< div >Max input (0.5% slippage): { formatUnits ( maxAmountIn , 6 ) } </ div >
</ div >
)
} import { Hooks } from 'wagmi/tempo'
import { formatUnits , parseUnits }
Buy.tsx Sell.tsx
import { Actions , Addresses } from 'viem/tempo'
import { Hooks } from 'wagmi/tempo'
import { formatUnits , parseUnits } from 'viem'
import { useSendCallsSync } from 'wagmi'
const alphaUsd = '0x20c0000000000000000000000000000000000001'
const betaUsd = '0x20c0000000000000000000000000000000000002'
function Buy () {
const amount = parseUnits ( '10' , 6 )
// How much AlphaUSD do I need to spend to receive 10 BetaUSD?
const { data : quote } = Hooks . dex . useBuyQuote ({
tokenIn : alphaUsd ,
tokenOut : betaUsd ,
amountOut : amount ,
})
// Calculate 0.5% slippage tolerance
const slippageTolerance = 0.005
const maxAmountIn = quote
? quote * BigInt ( Math . floor (( 1 + slippageTolerance ) * 1000 )) /
: 0 n
const sendCalls = useSendCallsSync ()
return (
< div >
< div >Quote: { formatUnits ( quote , 6 ) } </ div >
< div >Max input (0.5% slippage): { formatUnits ( maxAmountIn , 6 ) } </ div >
< button type = "button" onClick = { () => {
const calls = [
Actions . token . approve . call
amount : maxAmountIn , // Approve the max amount with slippage
spender : Addresses . stablecoinDex ,
token : alphaUsd ,
}),
]
sendCalls . sendCallsSync ({ calls })
} } >
Approve Spend
</ button >
</ div >
)
} import { Actions , Addresses } from 'viem/tempo'
import { Hooks } from 'wagmi/tempo'
import { formatUnits
Buy.tsx Sell.tsx
import { Actions , Addresses } from 'viem/tempo'
import { Hooks } from 'wagmi/tempo'
import { formatUnits , parseUnits } from 'viem'
import { useSendCallsSync } from 'wagmi'
const alphaUsd = '0x20c0000000000000000000000000000000000001'
const betaUsd = '0x20c0000000000000000000000000000000000002'
function Buy () {
const amount = parseUnits ( '10' , 6 )
// How much AlphaUSD do I need to spend to receive 10 BetaUSD?
const { data : quote } = Hooks . dex . useBuyQuote ({
tokenIn : alphaUsd ,
tokenOut : betaUsd ,
amountOut : amount ,
})
// Calculate 0.5% slippage tolerance
const slippageTolerance = 0.005
const maxAmountIn = quote
? quote * BigInt ( Math . floor (( 1 + slippageTolerance ) * 1000 )) /
: 0 n
const sendCalls = useSendCallsSync ()
return (
< div >
< div >Quote: { formatUnits ( quote , 6 ) } </ div >
< div >Max input (0.5% slippage): { formatUnits ( maxAmountIn , 6 ) } </ div >
< button type = "button" onClick = { () => {
const calls = [
Actions . token . approve . call
amount : maxAmountIn , // Approve the max amount with slippage
spender : Addresses . stablecoinDex ,
token : alphaUsd ,
}),
Actions . dex . buy . call
amountOut : amount ,
maxAmountIn ,
tokenIn : alphaUsd ,
tokenOut : betaUsd ,
}),
]
sendCalls . sendCallsSync ({ calls })
} } >
Execute Swap
</ button >
</ div >
)
} import { Actions , Addresses } from 'viem/tempo'
import { Hooks } from 'wagmi/tempo'
import { formatUnits
({
1000
n
from
'viem'
const alphaUsd = '0x20c0000000000000000000000000000000000001'
const betaUsd = '0x20c0000000000000000000000000000000000002'
function Sell () {
const amount = parseUnits ( '10' , 6 )
// How much BetaUSD will I receive for 10 AlphaUSD?
const { data : quote } = Hooks . dex . useSellQuote
tokenIn : alphaUsd ,
tokenOut : betaUsd ,
amountIn : amount ,
})
// Calculate 0.5% slippage tolerance
const slippageTolerance = 0.005
const minAmountOut = quote
? quote * BigInt ( Math . floor (( 1 - slippageTolerance ) * 1000 )) /
: 0 n
return (
< div >
< div >Quote: { formatUnits ( quote , 6 ) } </ div >
< div >Min output (0.5% slippage): { formatUnits ( minAmountOut , 6 ) } </ div >
</ div >
)
}
1000
n
({
,
parseUnits
}
from
'viem'
import { useSendCallsSync } from 'wagmi'
const alphaUsd = '0x20c0000000000000000000000000000000000001'
const betaUsd = '0x20c0000000000000000000000000000000000002'
function Sell () {
const amount = parseUnits ( '10' , 6 )
// How much BetaUSD will I receive for 10 AlphaUSD?
const { data : quote } = Hooks . dex . useSellQuote
tokenIn : alphaUsd ,
tokenOut : betaUsd ,
amountIn : amount ,
})
// Calculate 0.5% slippage tolerance
const slippageTolerance = 0.005
const minAmountOut = quote
? quote * BigInt ( Math . floor (( 1 - slippageTolerance ) * 1000 )) /
: 0 n
const sendCalls = useSendCallsSync ()
return (
< div >
< div >Quote: { formatUnits ( quote , 6 ) } </ div >
< div >Min output (0.5% slippage): { formatUnits ( minAmountOut , 6 ) } </ div >
< button type = "button" onClick = { () => {
const calls = [
Actions . token . approve . call
amount , // Approve the exact amount being sold
spender : Addresses . stablecoinDex ,
token : alphaUsd ,
}),
]
sendCalls . sendCallsSync ({ calls })
} } >
Approve Spend
</ button >
</ div >
)
}
1000
n
({
({
,
parseUnits
}
from
'viem'
import { useSendCallsSync } from 'wagmi'
const alphaUsd = '0x20c0000000000000000000000000000000000001'
const betaUsd = '0x20c0000000000000000000000000000000000002'
function Sell () {
const amount = parseUnits ( '10' , 6 )
// How much BetaUSD will I receive for 10 AlphaUSD?
const { data : quote } = Hooks . dex . useSellQuote
tokenIn : alphaUsd ,
tokenOut : betaUsd ,
amountIn : amount ,
})
// Calculate 0.5% slippage tolerance
const slippageTolerance = 0.005
const minAmountOut = quote
? quote * BigInt ( Math . floor (( 1 - slippageTolerance ) * 1000 )) /
: 0 n
const sendCalls = useSendCallsSync ()
return (
< div >
< div >Quote: { formatUnits ( quote , 6 ) } </ div >
< div >Min output (0.5% slippage): { formatUnits ( minAmountOut , 6 ) } </ div >
< button type = "button" onClick = { () => {
const calls = [
Actions . token . approve . call
amount , // Approve the exact amount being sold
spender : Addresses . stablecoinDex ,
token : alphaUsd ,
}),
Actions . dex . sell . call
amountIn : amount ,
minAmountOut ,
tokenIn : alphaUsd ,
tokenOut : betaUsd ,
}),
]
sendCalls . sendCallsSync ({ calls })
} } >
Execute Swap
</ button >
</ div >
)
}
({
1000
n
({
1000
n
({
({
1000
n
({
({