Skip to content

feat(bridge): add Arc xReserve and CCTP support - #73

Merged
iamalwaysuncomfortable merged 8 commits into
masterfrom
feat/arc-bridge
Sep 30, 2026
Merged

iamalwaysuncomfortable merged 8 commits into
masterfrom
feat/arc-bridge

Conversation

@iamalwaysuncomfortable

@iamalwaysuncomfortable iamalwaysuncomfortable commented Sep 29, 2026 •

Copy link
Copy Markdown
Member

Adds native Arc support to the Python bridge based on Veil #148, pinned to 3c3b457bd5f63620657321893a2487e489750d24.

  • Support Arc ↔ Aleo USDC/USDCx through xReserve and all six native-USDC CCTP directions between Arc and Ethereum, Base, and Arbitrum.
  • Select EVM connections by route while preserving ethereum=, bridge.eth, existing calling forms, and compatible checkpoints for the 22 original routes.
  • Preserve CCTP fee ceilings through execution and recovery; verify source intent, attestation, and exact destination mint evidence. Support explicit manual minting, approval replacement, and durable broadcast checkpoints.
  • Add agent/MCP options, resumable examples, live integrations, deployment reads, documentation, and regression coverage.
  • Fix two issues exposed during live validation: reconcile approvals after unrelated confirmed account activity against a verified scan head; retry wrapped Circle transport errors while keeping malformed attestation evidence fatal.

Review fixes preserve testnet construction when mainnet RPC variables are exported; retry Circle 429/5xx and truncated responses; backfill old destination receipts; quote 10% default fee headroom without increasing explicit or saved caps; return resumable approval-only progress when fees rise; reuse one xReserve execution fee estimate; and reconcile source history in bounded batches. Scan cursors stay in memory, check block-hash anchors (including while extending a scan), and safely restart after a process restart. Public calling signatures remain compatible.

Validation

  • 1,000 hermetic tests passed on 885519a, including 23 added regression cases; project and strict new-module Pyright reported 0 errors, 0 warnings. Generated-context and diff checks passed. Independent review found a scan-extension reorg race; its regression failed before the fix and passed afterward, with no remaining reviewer findings.
  • The funded results below and the inspected wheel build were completed on 1152925, before the review fixes. No new funded transactions were submitted for 885519a.
  • 27 funded live integration cases passed, covering all 18 eligible registry routes, including the previous lifecycle tests and every new Arc lifecycle case. Results are aggregated across funded runs and successful checkpoint recoveries.
  • 30 live read/authorization checks passed, plus the registry coverage assertion. The authorization simulation is supplemental to the funded executions.
  • All 14 existing and new example programs were exercised against live services. Transfer examples submitted real transactions; recovery examples verified existing transfers. All four Hyperlane bridge examples completed: WBTC and SOL in both directions.
  • All 20 executed CI jobs passed on 1152925, including cross-platform tests, proving/network tests, lint, and bridge/package builds. Four release jobs were skipped for the PR. CI results.
Funded coverage Verified result
CCTP All six individual lifecycle directions passed; Ethereum/Arc, Base/Arc, and Arbitrum/Arc 5-USDC roundtrips also passed
Public L2 journeys Base and Arbitrum each completed L2 → Arc → Aleo → Arc → original L2, using received funds for subsequent legs
Arc xReserve Public mint, private mint/claim, generic private withdrawal, and exact 2-USDCx withdrawal passed
Existing Hyperlane ETH/WBTC between Ethereum and Aleo, SOL between Solana and Aleo, both directions; disk recovery passed
Existing Ethereum xReserve Private-mint lifecycle, private withdrawal, private-balance example, and private-recipient example with claim completed
Existing testnet Private Sepolia deposit and return passed; public deposit test passed with separately confirmed destination delivery
Other examples Fresh Ethereum → Arc → Aleo and four-step L2 CLI journeys, USDCx withdrawal, shielding, live quotes, journal recovery, and transaction-history recovery completed

USDT was excluded at the account owner's request. Ten registry routes marked metadata-required remain unavailable.

Initial attempts encountered gas shortfalls, an expired Solana blockhash, RPC allowance propagation, changing fee quotes, finality timeouts, and concurrent-wallet interference with a WBTC assertion/approval. These were resolved through funding, serialized reruns, fresh quotes before any submission, or recovery of recorded transactions. Assertions were retained, submitted checkpoints retained their fee caps, and pending deposits were not repeated.

Outbound xReserve completion generally uses balance observation. The dedicated Arc withdrawal test additionally requires an exact successful destination receipt and balance delta. Both public integration journeys and the funded L2 CLI withdrawal were also independently audited against accepted Aleo burns and exact successful Arc transfer receipts.

@iamalwaysuncomfortable iamalwaysuncomfortable left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review of the Arc xReserve + CCTP work. Ten inline comments, ranked most severe first.

Blocking, in my view:

  • cctp.py:417 — delivered transfers can get stuck in DELIVERY_PENDING with no way to complete.
  • _evm_connections.py:53 — testnet clients fail to construct when any mainnet EVM RPC var is exported.
  • cctp.py:122 — Circle 429/5xx are classified as non-transient, so wait() aborts on the first blip.
  • cctp.py:151 — the default max_fee pins the cap to the live fee, so execute can spend approval gas and then abort.

The remaining six are duplication and efficiency cleanups (double checkpoint writes, triple quoting, unbounded log scan on recovery, duplicated env parsing and fee reads, hardcoded xReserve domains) that could land as a follow-up.

Comment thread bridge-sdk/python/aleo_bridge/cctp.py
Comment thread bridge-sdk/python/aleo_bridge/cctp.py Outdated
Comment thread bridge-sdk/python/aleo_bridge/cctp.py Outdated
Comment thread bridge-sdk/python/aleo_bridge/cctp.py
Comment thread bridge-sdk/python/aleo_bridge/cctp.py Outdated
Comment thread bridge-sdk/python/aleo_bridge/cctp.py
if not floor.isdigit():
raise ConfigurationError("BRIDGE_MIN_PRIORITY_FEE_WEI must be a whole number of wei")
kwargs["min_priority_fee_wei"] = int(floor)
for chain, variable in RPC_VARIABLES.items():

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Breaks testnet clients with a shared .env. from_env unconditionally builds connections for ARC_RPC_URL, BASE_RPC_URL, ARBITRUM_RPC_URL (all mainnet-only), and normalize() then rejects them for a testnet client. Reproduced: ALEO_NETWORK=testnet + ARC_RPC_URL set → Bridge.from_env() raises ConfigurationError "EVM connection 'arc' must belong to testnet and the EVM family". Previously working testnet setups break on upgrade with no fix except unsetting mainnet variables. Suggest filtering by the client's network before building, or skipping incompatible chains in normalize.

Comment thread bridge-sdk/python/aleo_bridge/_evm_connections.py
Comment thread bridge-sdk/python/aleo_bridge/xreserve.py Outdated
Comment thread bridge-sdk/python/aleo_bridge/xreserve.py
@iamalwaysuncomfortable
iamalwaysuncomfortable merged commit b74a7df into master Sep 30, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant