Choose how funds arrive
Your application can send funds to a public balance or, for USDCx, directly to a balance held in token records. The Fund guide explains which balances you can use for trading. You authorize the transfer with the source wallet. Some routes also need the receiving wallet to finish delivery. A confirmed source transaction means the transfer has started; check destination delivery before treating the funds as available.Supported pairs
The following mainnet pairs support transfers in both directions. Each row connects the external asset to its Aleo counterpart. The interface column distinguishes executable SDK routes from direct Hyperlane routes exposed by the wallet services API.
USDC from Base or Arbitrum can also reach USDCx through a composed SDK route: CCTP moves USDC to Arc, then xReserve bridges it to Aleo. The reverse route returns USDC through Arc. The packaged examples cover these transfers. ZEC in the table is a Solana token, not a transfer from the Zcash network.
Check route discovery before requesting a quote. SDK routes marked
metadata-required cannot execute. The REST catalog can also return providers that exchange different assets; those quotes are separate from the direct bridge pairs above. A listed route still needs a valid quote for your amount and addresses.
Bridge SOL between Solana and Aleo
Prerequisites: Your mainnet Aleo account from Setup, a Solana wallet, and a Solana mainnet RPC endpoint. Keep enough SOL for the transfer, network fees, delivery payment, and any account rent shown in the quote. The service examples use Node.js 22 or later or Python 3.11 or later.1. Connect the accounts
For a service or agent, supply credentials through your application’s configuration or secret manager. These examples read them from environment variables. A browser application or embedded wallet supplies a wallet connection instead of a source private key.- TypeScript
- Python
- REST
Install the bridge packages and Solana signing dependency:
solanaBridge can request quotes and authorize transfers with either account. Creating it does not move funds.2. Review a SOL quote
Prerequisites: The Solana connections from Connect the accounts. These examples request 0.01 SOL in display units, not lamports. The recipient is your configured Aleo account. The quote identifies the route, expected delivery, and fees before you authorize a transfer. The SDK examples select Hyperlane explicitly; review the provider in the REST response before choosing a quote.- TypeScript
- Python
- REST
solanaQuote.plan before submitting it. For a withdrawal, reverse the source and destination, use your Aleo address as sender, and set recipient to the receiving Solana address.3. Submit and check delivery
Prerequisites: Your reviewed quote from Review a SOL quote. For TypeScript, supplysaveCheckpoint, your application callback that durably saves each BridgeCheckpoint before returning. It may return void or Promise<void>.
- TypeScript
- Python
- REST
solanaProgress.next === "done" confirms delivery. A pending result needs monitoring or recovery, not a new transfer.sol instead of eth in those examples. After outbound delivery, the receiving Solana wallet holds native SOL.
Receive USDCx confidentially
Prerequisites: The mainnet Ethereum and Aleo clients from Configure access, USDC plus ETH for source fees, and the recipient’s Aleo wallet with destination fee payment configured. The examples below use that section’s TypeScriptbridge and account, or Python bridge and ethereum.
Circle xReserve offers two ways to receive USDCx directly in token records. They differ in whether the Ethereum deposit exposes the Aleo recipient and who completes delivery.
Both modes avoid a separate shielding transaction. Neither conceals the source transaction. Destination fee payment can also be public; the TypeScript completion example below uses a public fee. See public data and confidentiality boundaries for trading disclosures.
1. Keep the secret needed for completion
Theprivate flow commits to the recipient and a secret nonce, a random value needed again to receive the funds. Generate a nonzero Aleo scalar once and save it in your application’s secret store before depositing. Load that same value for quoting, submission, and completion. Bridge checkpoints omit it.
These examples load the saved scalar string, such as a decimal integer followed by scalar, from BRIDGE_MINT_SECRET_NONCE. Use a cryptographically random value, not a fixed sample or 0scalar.
2. Review a private-mint quote
Prerequisites: The clients named in Receive USDCx confidentially and the saved nonce from Keep the secret needed for completion. Each example requests 2 USDC in display units; the quote supplies the current constraints and fees. Your Ethereum account must already hold the requested USDC amount. Both SDKs check that balance while quoting, before any deposit is submitted.- TypeScript
- Python
private delivery for the configured recipient. Review the amount, allowance, approval requirement, and fees before execution.mintMode in TypeScript and mint_mode in Python are optional strings with a public default; select private explicitly for this flow. The corresponding nonce fields are scalar strings required by this tutorial. To use provider-delivered records instead, select record, omit the nonce, and follow the packaged record-delivery example. A Circle attestation alone does not confirm that the provider has delivered the record.
The wallet services REST examples do not expose these xReserve mint-mode controls. Use an SDK for this flow; a REST quote for USDC to USDCx may select a different provider.
3. Deposit and complete the mint
Prerequisites: The quote and saved nonce from Review a private-mint quote. TypeScript also needs the durablesaveCheckpoint callback described in Submit and check delivery. Python uses the checkpoint store configured in the Fund guide.
Run the source submission after reviewing the quote:
- TypeScript
- Python
privateProgress.next === "complete" means Circle’s attestation is ready and the recipient can authorize the destination mint. It does not mean USDCx has arrived.resume, recover and resume the remaining source action with the same nonce; an approval may have confirmed before the deposit was sent. A wait result needs further monitoring. The recovery guide explains these states.
When the result is complete, approve the destination mint with the recipient’s Aleo wallet:
- TypeScript
- Python
next: "done" confirms destination delivery. The resulting USDCx record can be used for trading without another shielding step.
Integrate bridging with a frontend
Prerequisites: A TypeScript browser application, the connected Aleoclient from Browser client setup, an Ethereum wallet provider, and a connected Solana Wallet Standard account when offering Solana routes. Each wallet and RPC endpoint must target mainnet.
Your frontend requests quotes through public RPC connections and asks a connected wallet to authorize fund movements. Private keys stay in the wallets. Your application still needs to retain bridge progress so a page reload does not lose the transfer reference.
1. Connect the bridge to browser wallets
Install the bridge and Solana packages alongside the wallet packages from Setup:solana:signAndSendTransaction; an Ethereum connector supplies an EIP-1193 provider after account access is approved.
2. Separate quote review from authorization
Use the returned bridge to request a quote when the amount or destination changes. Show the recipient, source amount, expected output, and fees before asking for approval. For USDCx, also show the selected delivery mode and whether a destination claim is required. Call this function from your confirmation handler with the reviewedBridgePlan. Supply saveCheckpoint from your application’s durable storage; it receives a serializable BridgeCheckpoint and resolves only after saving it.
createBrowserBridge from Connect the bridge to browser wallets. The optional nonce is required for a private USDCx mint and must come from the saved secret, not from a new generation on each click.
Disable repeat submission while the request is in progress. The returned next value tells your UI what the transfer needs:
After a reload, load the checkpoint and call
bridge.recover({ checkpoint }) before enabling another transfer. Wallet transaction history does not replace your application’s bridge checkpoint.
For a frontend built around REST, keep the same review and confirmation boundaries while following the order flow. The connected wallet signs the returned transactions. A wallet that broadcasts must report the original transaction to the API rather than submit it again.
Use Embedded Wallets for bridging
Prerequisites: A Node.js 22 or later service or Python 3.11 or later service, the bridge packages and Aleo client from Connect the accounts, and mainnet RPC endpoints for your source networks. Reuse the Aleo initialization from that setup: TypeScript’snativeAleo or Python’s aleo. Your chosen embedded wallet supplies the source signer below.
Dynamic and Privy embedded wallets can authorize bridge transfers for your service or agent without an interactive browser prompt. The source wallet signs the Ethereum or Solana transfer; your Aleo account handles shielding, withdrawals, and USDCx destination claims.
Choose one provider below. Each example connects Ethereum and Solana; keep only the connections your application uses. Supply credentials through your service’s configuration or secret manager. These examples use environment variables.
For a frontend, pass the connected wallet provider from Dynamic or Privy to the browser bridge. Server API tokens, app secrets, and signing passwords stay in your service.
Dynamic
Dynamic’s server wallet setup covers creating wallets and API credentials. Reconnect the existing wallets when your service restarts so their addresses stay the same. These examples use encrypted key shares backed up to Dynamic. The wallet password unlocks those shares for signing. For TypeScript, retain the complete metadata objects returned by wallet creation asevmWalletMetadata and solanaWalletMetadata; an address alone does not include the required backup information. Dynamic’s storage guide describes what to retain. The Python signers resolve the existing wallets by address.
- TypeScript
- Python
Install the Dynamic clients alongside the bridge packages. The server clients need native addon support; run them in your Node.js service. Use The
module: "ESNext" and moduleResolution: "Bundler" in TypeScript.bridge now uses the selected Dynamic wallets for source authorization. "101" is Dynamic’s Solana mainnet identifier and must match your Solana RPC endpoint.Privy
Privy’s wallet creation guide covers provisioning a wallet and choosing who controls it. Retain each wallet’s ID and address; they must identify the same wallet when you reconnect it. Your app credentials identify the service. Permission to sign depends on the wallet’s owner and signer configuration. If that configuration requires an authorization key, supply it with the request. This key authorizes requests to Privy and is separate from a chain private key. Privy’s request-signing guide explains those permissions.- TypeScript
- Python
Install Privy’s server client alongside the bridge packages:The
bridge uses the saved wallet IDs to request source signatures from Privy.Continue with the bridge flow
Use the provider’sbridge in the SOL quote and submission steps, replacing solanaBridge in TypeScript or solana_bridge in Python. For Ethereum assets, use the ETH example or the USDCx flow. Use your configured Aleo account as the USDCx recipient so it can authorize destination completion.
For REST, use the embedded wallet’s Ethereum or Solana address as SOURCE_ADDRESS and your Aleo recipient as DESTINATION_ADDRESS. The order flow returns transactions for your service to sign through Dynamic or Privy. Submit signed bytes only if the wallet has not broadcast them; otherwise report the original transaction ID. Provider credentials stay with the signing client.
Next Steps
Run packaged examples
The TypeScript bridge examples cover Solana transfers, USDCx delivery modes, and USDC routes through Arc. From that example package, after its documented setup, these commands preview a quote:USDCX_SECRET_NONCE and the matching Aleo recipient. Previewing a quote does not authorize a deposit. Follow the example’s execution acknowledgement only after review.
The Python bridge examples include bridge_sol, bridge_usdc_private_balance, bridge_usdc_private_recipient, and l2_arc_aleo_roundtrip. Their help lists the required account and route inputs:
dynamic_wallets and privy_wallets examples include quoting and optional execution. Run without execution flags first to review the transfer.