FAQ
⚙️ General Architecture
Q: What is the overall swap flow? A:
/quote → returns prices, fees, slippage, route type, and path.
/buildTransaction → builds the exact calldata for the router.
Approve → the sender wallet (EOA or SCA) approves
spender = routerAddress.Execute → call the router function (usually
swapExactInputViaorswapExactInputPathVia) using the builder output.Track → poll transaction status on-chain or through Circle’s API.
🔢 Units & Amounts
Q: Should I send HUMAN or RAW values?
/quote→amountis HUMAN (e.g."1.25"USDC)./buildTransaction→amountOutandminAmountInare RAW (exact integers from the quote). Never runparseUnits()onamountOutagain—just forward what you got.
Q: How are decimals handled?
All normalization happens internally using token metadata. You can safely send strings like "0.00001"; the backend truncates to token decimals.
🧮 Quotes
Q: What happens inside /quote?
It aggregates routes (Uniswap V2/V3, Slipstream, Aerodrome, etc.), applies your configured Emigro fee, computes output, slippage, and builds a canonical path array.
Q: Why does my quote sometimes say routeAllowed:false?
The pair is disabled by admin config or missing liquidity. You can still get a price estimate but cannot execute it.
Q: Can I force a specific router (e.g. only Uniswap V3)?
Yes—send routerType explicitly in your request if your integration UI allows router selection. Otherwise the aggregator picks the best route automatically.
🧩 Build Transaction
Q: Do I have to specify router addresses or adapters?
No. The builder resolves them automatically for the given chainId and routerType. Always use the returned routerAddress, adapterAddress, and adapterData.
Q: Why are there two function signatures (swapExactInputVia vs. swapExactInputPathVia)?
swapExactInputVia: single-hop swap.swapExactInputPathVia: multi-hop swap. The builder chooses the correct one; you don’t need to detect this yourself.
Q: What are abiFunctionSignature and abiParameters for?
They’re ready-to-use Circle parameters—pass them verbatim to
sendSmartContractTransaction({ contractAddress, abiFunctionSignature, abiParameters }).
💳 Circle Smart Contract Accounts (SCA)
Q: How do I get the wallet address for my SCA? Use
Q: Does the SCA need native gas (ETH/Base)? No—Circle handles gas sponsorship behind the scenes. You don’t transfer ETH manually.
Q: Can I reuse the same SCA for many swaps? Yes. Each Circle wallet can execute unlimited contract calls and approvals.
Q: What’s the difference between walletId, walletSetId, and walletPublicAddress?
walletId: Circle’s unique identifier for the SCA.
walletSetId: logical grouping under your entity.
walletPublicAddress: the on-chain address you use for approvals and recipients.
🪙 Approvals & Balances
Q: How do I approve tokens for a Circle wallet? Send:
Wait for CONFIRMED before swapping.
Q: Do I need to re-approve every swap? Only if allowance < amountOut. Many integrators approve a large static amount once or uses others onchain artifacts being completly up to the design application.
Q: What if approval is confirmed but swap still fails? Check that you approved the input token, on the same chain, from the same wallet that’s executing the swap.
🔀 Multi-Hop Routes
Q: How do I know if a route is multi-hop?
If quote.multihop is not null and path.length > 2. The displayPathText may look like "BRZ > USDC > EURC".
Q: What must I include in /buildTransaction for multi-hop?
Pass both:
The builder will automatically encode adapterData arrays of fees/spacings.
Q: Can I mix Uniswap V3 and Slipstream hops? Not within a single transaction. Each routerType uses one adapter family; if you need cross-router hops, split them into sequential swaps.
⛽ Execution
Q: Why does Circle show ESTIMATION_ERROR?
That means the router’s eth_call failed during gas estimation. Check allowance, slippage, and ensure the calldata matches the builder output.
Q: Can I pre-simulate before Circle submission?
Yes—take the builder’s abiFunctionSignature and abiParameters, encode with Interface, and run eth_call against the chain RPC.
Q: How long does a Circle transaction take?
Usually < 60 s, but your code should poll until state === CONFIRMED or timeout after ~90 s.
Q: How can I get the on-chain txHash?
(await circleClient.getTransaction({ id })).data.transaction.txHash
📈 Slippage, Fees & Pricing
Q: How is slippage applied?
minAmountIn = estimatedAmount × (1 − slippage%).
At execution time the router reverts if output < minAmountIn.
Q: What is emigroFeePercent?
Your platform’s service fee on the input amount (e.g., 0.5%). It’s deducted before routing.
Q: Can I customize slippage per request?
Yes—send a slippage field in the /quote body.
Q: How do I show final price impact?
Use priceImpactPercent from the quote response.
🧰 Debugging & Logging
Q: How do I debug failed quotes? Enable verbose logging and check:
chainId / token addresses valid?
aggregator response (routerType, path)?
backend logs may show
[getQuote]messages for asset fetch failures.
Q: How do I debug failed swaps? Log:
payload of
/buildTransactionabiFunctionSignature+abiParametersCircle transaction state trace (
getTransaction) Most issues fall under allowance, decimals, or slippage mismatch.
Q: My swap pair was not found or the price impact is too high. The quote functions as an aggregator to bring the best possible price for the swap from the whitelisted DEXs. If the pair does not have a liquidity pool (LP) in any of the DEXs, the quote will return an error of pair not found. If the pair has very low liquidity, the quote may return a high price impact.
🔐 Security & Safety
Q: Can I use a custom adapter? No. For security reasons, only whitelisted adapters are accepted for interaction with the router. If you wish to add a specific DEX, please contact technical support.
Q: Are approvals unlimited?
Yes if you choose a large allowance. You can later revoke via on-chain call approve(spender,0).
Q: How are private keys managed for Circle wallets? They’re held by Circle’s HSM infrastructure; you never access them directly. Every transaction is API-signed and auditable.
🧱 Integration Best Practices
Cache quotes for ~30 s to avoid rate-limit bursts.
Always use builder outputs unchanged.
Run an RPC pre-simulation to catch reverts early.
Confirm approval before sending swap.
Handle retries with idempotency keys on your side.
Log chainId, routerType, path, and Circle txId for every swap.
🧩 Miscellaneous
Q: Can I build calldata manually without the API? Yes, but discouraged—the builder enforces proper encoding and router compatibility. Manual encoding is error-prone.
Q: Can I run this with EOAs instead of Circle SCA? Yes. Use the same API endpoints, then sign and send via ethers.js using your EOA signer instead of Circle.
Q: Is there support for other chains?
Yes—any chain configured in your chain table with circle_enabled=true. Add its RPC + adapter addresses, and the flow works identically.
Q: Where can I see all supported routers?
Check /public/emigroswap/quote with a test pair and inspect routerDisplay. Typical keys:
uniswap-v2uniswap-v3aerodrome-v2aerodrome-slipstream
Last updated

