Guide: Native Swap Example
This guide provides a complete, code-first walkthrough for creating and submitting a swap transaction using the API. We will build a real-world example: swapping USD to cBTC on the Citrea blockchain backed by Sepolia ETH as collateral, using Crest as a liquidity source.The Goal
Our goal is to create an “intent” that performs the following actions:- On Sepolia Testnet: A user deposits
0.0001Sepolia ETH into an escrow EOA. - On Citrea Testnet: Using the value from the deposit, execute a swap for cBTC via
crestcontract. - Finally: The solver sends the principal amount of the deposit back to the user on Citrea.
Prerequisites
You’ll needviem to interact with chains, create authorizations, and sign messages. For frontend applications, you would need to use privy SDK to work with embedded wallets.
Step 1: Setting up Accounts and Clients
First, we define the accounts and blockchain clients we’ll be working with. In a real application, theuser would be the end-user interacting with your application, and their private key would be managed by their wallet.
Step 2: Define the Intent Parameters
We’ll define the amounts and generate a quote for the swap part of our intent.Step 3: Create EIP-7702 Authorizations
The core of the process is the user granting our system one-time authority on each chain. The user’s wallet will sign an EIP-7702 authorization for eachdelegate contract on each chain.
authorization objects are what a solver will use to execute transactions on the user’s behalf.
Step 4: Construct the Chain Batches
Now we define the specific on-chain actions. Each object in thechainBatches array represents a set of calls to be executed on a specific blockchain, in order.
Import the hashing helpers from @spicenet-io/spiceflow-core. Do not hand-roll them, and do not add a
recentBlock field: the current chain-batch shape is { chainId, calls }, and the request schema
rejects unknown keys.
hashChainBatches returns each batch as { hash, chainId, calls }.
Step 5: Sign the Intent and Build the Request
The user signs the intent hash.getIntentHash takes the signature type, a not-before timestamp
(nbf), an expiry (exp), and the hashed chain batches:
POST /actions request body. chainAuthorizations are the EIP-7702 authorizations from
Step 3, each { r, s, yParity, address, chainId, nonce } (drop the legacy v field). Each chain
batch also carries its tokenTransfers (how the solver moves tokens):
POST /actions. See the POST /actions reference
for the full request and response schema.
What Happens Next: The Solver
After you submit the intent, the API makes it available to a network of solvers. A solver will:- Pick up your intent.
- Execute Step 0 by sending a transaction to the
Delegatecontract on Sepolia, using your signed authorization. This deposits your funds to escrow. - Wait for the required block confirmations.
- Execute Step 1 by sending a transaction to the
Delegatecontract on Citrea, which performs the swap. - As part of the final transaction, the solver also transfers the principal deposit amount (
tokenAmount) back to your address (address) on the destination chain (Citrea).
GET /actions/{actionId}/intents/{intentIndex}/steps/{stepIndex} endpoint.
You have successfully orchestrated a cross-chain action without requiring the user to switch networks or manage gas on the destination chain.