Cross-chain Swaps (Alpha)
Cross-chain swaps let you convert tokens across different blockchain networks in a single transaction. They’re built natively into Smart Wallets and you can integrate in minutes.
Cross-chain swaps work just like any other Smart Wallet transaction, so you can sponsor gas to do gasless swaps, or pay for gas in an ERC-20 token.
Cross-chain swaps are in alpha. Note that there may be changes in the future to simplify the endpoint/sdk. We will let you know if/when that happens.
The Cross-chain Swap flow
Flow
- Request a cross-chain swap quote
- Sign the prepared swap calls
- Send prepared calls
- Wait for cross-chain confirmation
Swap options
Important: Cross-chain swaps do not support postCalls
. You cannot batch
additional actions after a cross-chain swap completes (for now).
When requesting a cross-chain swap quote, you can specify either a fromAmount
, or a minimumToAmount
.
Prerequisites
Before you begin, ensure you have:
- An Alchemy API Key
- If you’re sponsoring gas, then a Gas Manager policy
- A small amount of tokens for testing (~$1 worth is enough!)
- Important: You’ll need to send these tokens to your smart wallet address to be able to swap!
- A signer to own the account and sign messages
Note that Cross-chain Swaps are currently supported via direct APIs. SDK & React support coming soon!
APIs
JavaScript
React
You will need to fill in values wrapped in curly braces like {SIGNER_ADDRESS}
.
Request a cross-chain swap quote
Important: Cross-chain swaps do not support postCalls
. You cannot batch
additional actions after a cross-chain swap.
Request a cross-chain swap quote by specifying both the source chain (chainId
) and destination chain (toChainId
). In addition, just like in single-chain swaps you can specify either a minimumToAmount
or a fromAmount
.
If you’re using an EOA or just want the raw array of calls returned, pass the
optional parameter "returnRawCalls": true
, this will return a calls
array.
This returns:
Note the callId
in the response! You’ll use this to track the cross-chain swap status. Also note the signatureRequest
- this is what you need to sign, and the returned data
field is what you’ll need to send the transaction.
Sign the signature request
To sign the signature request, sign the raw
field (note, this is not a string! You need to pass it to your signer as raw bytes, generally like so: { raw: "0x..." }
) with your signer of choice.
This should use the personal_sign
RPC method, as noted by the type
in the signatureRequest
.
Alternatively, you can sign the raw payload with a simple eth_sign
but this RPC method is not favored due to security concerns.
Send the prepared call
Pass the callId
from Step 2 to sendPreparedCalls
. This makes the response return the same callId
with additional cross-chain status tracking information:
This returns:
The response returns the same callId
you passed in, which you’ll use to track the cross-chain swap status in the next step.
For other potential responses, check out the API reference!
Track the cross-chain swap
Use the wallet_getCallsStatus
endpoint to check the status of your cross-chain swap. Cross-chain swaps may take longer than single-chain swaps due to cross-chain messaging.
This returns:
Cross-chain swaps have additional status codes to reflect the cross-chain nature of the transaction:
To get your transaction hash, you can access result.receipts[0].transactionHash
.
For more details, check out the API reference!
FAQs
What chains are supported for cross-chain swaps?
Chains supported (for now) are: Arbitrum, Arbitrum Nova, Base, Berachain, Boba Network, BSC/BNB, Celo, Ethereum, Hyperliquid, Ink, Optimism, Plasma, Polygon, Shape, Soneium, Story, Unichain, World Chain, and Zora mainnets.
Can I batch additional calls after a cross-chain swap?
No, postCalls
are not supported for cross-chain swaps (for now). You can only perform the swap itself across chains.
How long do cross-chain swaps take?
Cross-chain swaps typically take longer than single-chain swaps due to the need for cross-chain messaging and confirmation. The exact time depends on the source and destination chains involved in the swap.
How do you encode values?
Values are simply passed as hexadecimal strings. The Swap API doesn’t add complexity to consider decimals, so 0x01 is always the smallest amount of a given asset.
1 ETH, or DAI (18 decimals) is 0xDE0B6B3A7640000
1 USDC (6 decimals) is 0xF4240
This removes any ambiguity— if it’s numerical, it’s a hex.
What is the expiry?
The expiry is an informational indicator of when you can expect to be able to process the swap request. If you’re at/near the expiry, it might be a good time to request a new quote.
What are the different status codes for cross-chain swaps?
Cross-chain swaps may have additional status codes beyond standard transaction statuses to reflect the cross-chain nature of the transaction. These are:
- 120: Cross-chain in progress
- 410: Cross-chain refund
When is a CallId returned from wallet_requestQuote_v0
?
Any time you’re requesting a cross-chain quote via wallet_requestQuote_v0
, a callId
is returned. This callId
includes important data for cross-chain tracking. You can use this just like any other callId
in wallet_getCallsStatus
!