You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
docs: Circle AppKit v1.5.x kit.bridge() and kit.send() have no documented Arc Testnet integration path — only kit.swap() / estimateSwap() are viable #88
Circle AppKit v1.5.x (@circle-fin/app-kit) documents kit.bridge() and kit.send() as top-level primitives, but neither has a documented path for Arc Testnet. When building a swap DApp that needed cross-chain bridging (Ethereum Sepolia → Arc Testnet) and wallet-to-wallet token sends, only kit.swap() and kit.estimateSwap() worked reliably.
What we expected
The AppKit README implies that kit.bridge() enables USDC bridging between any two supported chains including Arc Testnet, and that kit.send() sends USDC/EURC between wallets on the same chain.
What actually happened
kit.bridge() — No documentation on which chain identifiers are valid for Arc Testnet (e.g. "Arc_Testnet" string constant). The CCTP attestation service used internally does not document Arc Testnet support.
kit.send() — No documentation on whether Arc Testnet is supported, or whether the underlying transfer is an on-chain ERC-20 transfer() or a Circle-mediated off-chain transfer.
Both methods require the backend wallet private key to execute, which conflicts with the client-side viem adapter pattern shown in docs — creating a security/UX architecture mismatch.
Workaround
Bridge: Guide users to faucet.circle.com manually. No programmatic on-chain bridge path was available.
Send: Implemented a direct ERC-20 transfer() call via MetaMask + viem, bypassing AppKit entirely.
Environment
@circle-fin/app-kit v1.5.0
@circle-fin/adapter-viem-v2 v1.10.0
Arc Testnet (Chain ID 5042002)
Observed: May 2025
Request
Please add to the Arc developer docs:
Which AppKit methods are supported on Arc Testnet
The correct chain identifier string for Arc Testnet in kit.bridge()
Whether kit.send() is implemented for Arc Testnet or falls back to raw ERC-20
Confirmed findings + working alternative for cross-chain USDC bridging
Based on our experience building a bridge DApp on Arc Testnet:
What works:
kit.swap() and kit.estimateSwap() work for same-chain USDC swaps on Arc Testnet
For Arc Testnet ↔ Ethereum Sepolia/Base Sepolia/Avalanche Fuji bridging, CCTP V2 directly is the only fully documented path
What doesn't have an official Arc path:
kit.bridge() — no documented Arc Testnet configuration in AppKit v1.5.x
kit.send() — no documented Arc Testnet wallet-to-wallet send path
Working alternative for USDC bridging (CCTP V2):
The CCTP V2 contracts are live on Arc Testnet. All chains (Arc, Sepolia, Base Sepolia, Fuji) share the same contract addresses:
Arc Testnet's CCTP domain ID is 26. See docs/cctp-v2.md in PR #79 for a complete
integration guide including the Arc-specific minFinalityThreshold and attestation timing.
Additional findings: kit.swap() itself also fails on Arc Testnet with ONCHAIN_SIMULATION_FAILED
Building a swap DApp (Arc Swap / live) on Arc Testnet, we found that kit.swap() — not just kit.bridge() and kit.send() — is also completely non-functional on Arc Testnet.
The error is thrown regardless of token direction (USDC→EURC or EURC→USDC), amount, or wallet state. kit.estimateSwap() does not throw but returns wildly incorrect rates (e.g. 17 EURC per 1 USDC instead of ~0.91), which suggests the swap router contract has no real liquidity on Arc Testnet.
Root cause
The Circle swap router contract at 0xBBD70b01a1CAbc96d5b7b129Ae1AAabdf50dd40b appears to have no deployed liquidity pool on Arc Testnet. The on-chain simulation step inside kit.swap() therefore always fails.
Workaround we shipped
We replaced Circle Kit entirely with a backend-facilitated peer-to-peer model:
User approves ERC-20 allowance to a backend wallet
Backend calls transferFrom to pull amountIn from user
Backend calculates amountOut using real market rates (Frankfurter ECB forex for USDC/EURC, CoinGecko for BTC/USD)
Backend calls transfer to send amountOut to user
Auto-refund if step 4 fails
This is a workable testnet pattern but obviously not suitable for production. The underlying issue is that kit.swap() should either work on Arc Testnet or throw a clear CHAIN_NOT_SUPPORTED error rather than an opaque ONCHAIN_SIMULATION_FAILED.
Confirmed: kit.swap() also fails with ONCHAIN_SIMULATION_FAILED on Arc Testnet
Building on this issue with additional findings from Arc Swap (Uniswap V2 DEX on Arc Testnet, App Kit v1.7.0 + adapter-viem-v2 v1.11.2):
kit.swap() status update
In v1.7.x, kit.swap() — not just kit.bridge() and kit.send() — also fails on Arc Testnet with ONCHAIN_SIMULATION_FAILED in both directions (USDC→EURC and EURC→USDC). Arc Testnet (Chain ID 5042002) appears to not be in Circle's supported chains for any swap routing.
kit.estimateSwap() returns rates that diverge significantly from real EUR/USD forex:
// 1. On-chain pool quote via getReserves() — exact constant-product mathconst[reserve0,reserve1]=awaitpublicClient.readContract({address: PAIR_ADDRESS,abi: PAIR_ABI,functionName: "getReserves",});constpoolRate=Number(reserve1)/Number(reserve0);// 2. Real forex as sanity check — if pool is >5% off, use forex directlyconstforexRate=awaitfrankfurterFetch();// USD/EUR from api.frankfurter.appif(Math.abs(poolRate-forexRate)/forexRate>0.05){returnforexRate;// pool imbalanced — use market rate}returnpoolRate;// pool price is accurate — use it (matches what router will execute)
The 5% guard also routes backend swaps away from the pool automatically when it drifts, so users always get a rate close to real EUR/USD regardless of pool state.
What this tells us about kit.swap() on Arc Testnet
App Kit does NOT use Uniswap-style AMMs for USDC/EURC — it routes through LiFi Diamond → Curve StableSwap pools with WUSDC as an intermediate token
ONCHAIN_SIMULATION_FAILED appears to be liquidity-conditional, not a permanent chain incompatibility — it likely occurs when the Curve pools don't have sufficient depth for the requested amount
The working tx above (1.99 USDC) succeeded; larger amounts or different market conditions may still fail
Revised recommendation
Use tryKitSwap() as the primary path but keep a fallback (peer-to-peer at market rate or Uniswap V2 pool) for when it fails. Do not treat ONCHAIN_SIMULATION_FAILED as permanent — it's a liquidity signal, not a chain compatibility error.
// Try App Kit first — works when Curve pool liquidity is sufficientconstkitResult=awaittryKitSwap(tokenIn,tokenOut,amountIn);if(kitResult){returnkitResult;// App Kit succeeded — route: LiFi → Curve → WUSDC → EURC}// Fallback — direct Uniswap V2 router or peer-to-peer at Frankfurter ratereturnfallbackSwap(tokenIn,tokenOut,amountIn);
Rate accuracy
The successful tx gave 1.173 EURC/USDC vs real EUR/USD of ~1.146 — approximately 2.3% above market on testnet. For production usage, real forex validation (e.g. Frankfurter) is still recommended as a sanity check on kit.estimateSwap() output.
Taking this. Official App Kit docs now document Arc Testnet for bridge/send/swap with the Arc_Testnet chain id; I will add an in-repo developer note that points at those paths and answers the three questions in this issue.
@ZhiyuCircle requesting assignment — linked PR is already open, CI-green, and mergeable. Per CONTRIBUTING the only remaining gate is assignment; happy to rebase or adjust scope once assigned.
Activity
osr21 commentedon May 25, 2026
Confirmed findings + working alternative for cross-chain USDC bridging
Based on our experience building a bridge DApp on Arc Testnet:
What works:
kit.swap()andkit.estimateSwap()work for same-chain USDC swaps on Arc TestnetWhat doesn't have an official Arc path:
kit.bridge()— no documented Arc Testnet configuration in AppKit v1.5.xkit.send()— no documented Arc Testnet wallet-to-wallet send pathWorking alternative for USDC bridging (CCTP V2):
The CCTP V2 contracts are live on Arc Testnet. All chains (Arc, Sepolia, Base Sepolia, Fuji) share the same contract addresses:
0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275Arc Testnet's CCTP domain ID is
26. Seedocs/cctp-v2.mdin PR #79 for a completeintegration guide including the Arc-specific
minFinalityThresholdand attestation timing.osr21 commentedon Jun 16, 2026
Additional findings:
kit.swap()itself also fails on Arc Testnet withONCHAIN_SIMULATION_FAILEDBuilding a swap DApp (Arc Swap / live) on Arc Testnet, we found that
kit.swap()— not justkit.bridge()andkit.send()— is also completely non-functional on Arc Testnet.Error
The error is thrown regardless of token direction (USDC→EURC or EURC→USDC), amount, or wallet state.
kit.estimateSwap()does not throw but returns wildly incorrect rates (e.g. 17 EURC per 1 USDC instead of ~0.91), which suggests the swap router contract has no real liquidity on Arc Testnet.Root cause
The Circle swap router contract at
0xBBD70b01a1CAbc96d5b7b129Ae1AAabdf50dd40bappears to have no deployed liquidity pool on Arc Testnet. The on-chain simulation step insidekit.swap()therefore always fails.Workaround we shipped
We replaced Circle Kit entirely with a backend-facilitated peer-to-peer model:
transferFromto pullamountInfrom useramountOutusing real market rates (Frankfurter ECB forex for USDC/EURC, CoinGecko for BTC/USD)transferto sendamountOutto userThis is a workable testnet pattern but obviously not suitable for production. The underlying issue is that
kit.swap()should either work on Arc Testnet or throw a clearCHAIN_NOT_SUPPORTEDerror rather than an opaqueONCHAIN_SIMULATION_FAILED.Environment
@circle-fin/app-kitv1.5.x0x36000000000000000000000000000000000000000x89B50855Aa3bE2F677cD6303Cec089B5F319D72aosr21 commentedon Jun 19, 2026
Confirmed: kit.swap() also fails with ONCHAIN_SIMULATION_FAILED on Arc Testnet
Building on this issue with additional findings from Arc Swap (Uniswap V2 DEX on Arc Testnet, App Kit v1.7.0 + adapter-viem-v2 v1.11.2):
kit.swap() status update
In v1.7.x,
kit.swap()— not justkit.bridge()andkit.send()— also fails on Arc Testnet withONCHAIN_SIMULATION_FAILEDin both directions (USDC→EURC and EURC→USDC). Arc Testnet (Chain ID 5042002) appears to not be in Circle's supported chains for any swap routing.kit.estimateSwap()returns rates that diverge significantly from real EUR/USD forex:These appear to reflect Circle's internal liquidity pool prices, not live market rates.
Working alternatives for each App Kit method on Arc Testnet
kit.swap()kit.estimateSwap()getReserves()+ Frankfurter/CoinGeckokit.bridge()kit.send()transfer()via viemSwap estimate priority that works
The 5% guard also routes backend swaps away from the pool automatically when it drifts, so users always get a rate close to real EUR/USD regardless of pool state.
osr21 commentedon Jun 19, 2026
Update: kit.swap() is intermittent, not always broken — confirmed working tx
Correction to my earlier comment:
kit.swap()does not always fail on Arc Testnet. We observed a successful execution in production:Transaction:
0x237678e4eb865f07b597eb930a3194fb7ae309b513a07fd60f4f0a6fceb65a15The swap went through successfully — 1.99 USDC → 2.333 EURC — via Circle's App Kit Adapter. The routing chain was:
What this tells us about kit.swap() on Arc Testnet
ONCHAIN_SIMULATION_FAILEDappears to be liquidity-conditional, not a permanent chain incompatibility — it likely occurs when the Curve pools don't have sufficient depth for the requested amountRevised recommendation
Use
tryKitSwap()as the primary path but keep a fallback (peer-to-peer at market rate or Uniswap V2 pool) for when it fails. Do not treatONCHAIN_SIMULATION_FAILEDas permanent — it's a liquidity signal, not a chain compatibility error.Rate accuracy
The successful tx gave 1.173 EURC/USDC vs real EUR/USD of ~1.146 — approximately 2.3% above market on testnet. For production usage, real forex validation (e.g. Frankfurter) is still recommended as a sanity check on
kit.estimateSwap()output.kutluhaneth46 commentedon Sep 14, 2026
Taking this. Official App Kit docs now document Arc Testnet for bridge/send/swap with the
Arc_Testnetchain id; I will add an in-repo developer note that points at those paths and answers the three questions in this issue.kutluhaneth46 commentedon Sep 14, 2026
Opened #404 — in-repo note for
Arc_Testnetplus bridge/send/swap coverage, linked from the README.docs: document App Kit Arc Testnet chain id and capabilities
kutluhaneth46 commentedon Sep 28, 2026
@ZhiyuCircle requesting assignment — linked PR is already open, CI-green, and mergeable. Per CONTRIBUTING the only remaining gate is assignment; happy to rebase or adjust scope once assigned.