Integration Guide
Quick Start
2
Example: Swap CRV (Ethereum) → CRV (Arbitrum)
import { ethers } from 'ethers';
const API_BASE = 'https://api.crosscurve.fi';
// Initialize provider and signer (example for browser with MetaMask)
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
// 1. Find route
const routeResponse = await fetch(`${API_BASE}/routing/scan`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
params: {
chainIdIn: 1, // Ethereum
chainIdOut: 42161, // Arbitrum
tokenIn: '0xD533a949740bb3306d119CC777fa900bA034cd52', // CRV on Ethereum
tokenOut: '0x11cDb42B0EB46D95f990BeDD4695A6e3fA034978', // CRV on Arbitrum
amountIn: '1000000000000000000000' // 1000 CRV (18 decimals)
},
slippage: 1 // 1%
})
});
const routes = await routeResponse.json();
if (!routes.length) {
throw new Error('No routes available for this pair');
}
const selectedRoute = routes[0]; // first route from list
console.log(`Expected output: ${selectedRoute.amountOut}`);
console.log(`Price impact: ${selectedRoute.priceImpact}%`);
console.log(`Fee: ${selectedRoute.totalFee.percent}%`);
// 2. Get estimate
const estimateResponse = await fetch(`${API_BASE}/estimate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(selectedRoute)
});
const estimate = await estimateResponse.json();
// 3. Build transaction
// buildCalldata: true — returns ready calldata for sendTransaction
const txResponse = await fetch(`${API_BASE}/tx/create`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
from: '0xYourWalletAddress', // With correct checksum!
recipient: '0xRecipientAddress', // Can match from
routing: selectedRoute,
estimate: estimate,
buildCalldata: true // Get ready calldata
})
});
const txData = await txResponse.json();
// txData: { to, value, data } — ready for sendTransaction
// 4. Approve tokens (check allowance to avoid unnecessary TX)
const tokenContract = new ethers.Contract(
'0xD533a949740bb3306d119CC777fa900bA034cd52', // CRV token
['function approve(address spender, uint256 amount) returns (bool)',
'function allowance(address owner, address spender) view returns (uint256)'],
signer
);
const ownerAddress = await signer.getAddress();
const allowance = await tokenContract.allowance(ownerAddress, txData.to);
if (allowance.lt('1000000000000000000000')) { // if allowance < amountIn
await tokenContract.approve(txData.to, ethers.constants.MaxUint256);
console.log('Token approved');
}
// 5. Send transaction to blockchain
const tx = await signer.sendTransaction({
to: txData.to,
data: txData.data,
value: txData.value || '0'
});
console.log(`TX sent: ${tx.hash}`);
const receipt = await tx.wait();
console.log(`TX confirmed in block: ${receipt.blockNumber}`);
// 6. Get requestId
// Option A: via API (wait for indexing ~3 sec)
await new Promise(r => setTimeout(r, 3000));
const searchResponse = await fetch(`${API_BASE}/search?search=${tx.hash}`);
const searchResult = await searchResponse.json();
let requestId = searchResult.result[0]?.requestId;
// Option B: from transaction events (faster, no waiting)
if (!requestId) {
const COMPLEX_OP_TOPIC = '0x830adbcf80ee865e0f0883ad52e813fdbf061b0216b724694a2b4e06708d243c';
const log = receipt.logs.find(l => l.topics[0] === COMPLEX_OP_TOPIC);
if (log) {
// Decode event to get nextRequestId
const iface = new ethers.utils.Interface([
'event ComplexOpProcessed(uint64 indexed currentChainId, bytes32 indexed currentRequestId, uint64 nextChainId, bytes32 nextRequestId, uint8 result, uint8 lastOp)'
]);
const decoded = iface.parseLog(log);
requestId = decoded.args.nextRequestId;
}
}
console.log(`RequestId: ${requestId}`);
// 7. Track status (polling every 5 sec)
let status;
for (let i = 0; i < 60; i++) { // max 5 minutes
const statusResponse = await fetch(`${API_BASE}/transaction/${requestId}`);
status = await statusResponse.json();
console.log(`Status: ${status.status}`);
if (status.status === 'completed') {
console.log('Swap completed!');
break;
}
if (status.inconsistency) {
console.log('Refund required, see /inconsistency');
break;
}
if (status.destination?.emergency) {
console.log('Recovery required, see /tx/create/emergency');
break;
}
await new Promise(r => setTimeout(r, 5000)); // wait 5 sec
}Test Examples
Source Network
Target Network
Token In
Token Out
If No Route Found
cURL Examples for Quick Testing
Integration Architecture
Process Diagram
Cross-Chain Swap Stages
Stage
Description
API / Action
Supported Networks
Network
Chain ID
API Name
Reference Data
GET /networks
Parameter
Type
Description
GET /tokenlist
Tag
Description
GET /prices/{token}
Parameter
Type
Description
GET /prices/{token}/{chainId}
POST /prices
Executing Cross-Chain Swaps
POST /routing/scan
Field
Type
Required
Description
POST /estimate
POST /tx/create
Field
Type
Required
Description
Token Approval
Standard Approve (ERC-20)
Permit (EIP-2612) - Approve via Signature
Transaction Tracking
GET /transaction/{requestId}
Parameter
Type
Description
Status
Description
GET /search
Parameter
Type
Required
Description
GET /history
Parameter
Type
Required
Description
Error Handling
Scenarios
Flag
Action
GET /inconsistency/{requestId}
POST /inconsistency
1
2
3
Field
Type
Required
Description
POST /tx/create/emergency
Field
Type
Required
Description
Creating Signature for Emergency/Inconsistency
1
2
3
Common API Errors
Error
Cause
Solution
API Reference
Endpoint List
Reference Data
Method
Endpoint
Description
Routing and Swap
Method
Endpoint
Description
Monitoring
Method
Endpoint
Description
Error Handling
Method
Endpoint
Description
Supply and Statistics
Method
Endpoint
Description
Response Format
NFT Operations
Method
Endpoint
Description
Required Parameters
1
2
Code Examples
TypeScript: Types and Polling
JavaScript: Getting Networks and Tokens
Python: Finding Route
Route Operation Codes
Code
Description
Rate Limits and Best Practices
Rate Limits
Endpoint
Usage Example
Best Practices
1
2
3
4
5
6
7
8
9
Limitations
Parameter
Description
Contract Addresses
Contract
Description
Field in /networks
Fee Structure
Fee Type
Description
Response Field
FAQ
Glossary
Term
Description
Changelog
Date
Change

