This guide walks you through a complete swap flow from Bitcoin (BTC) to Ethereum USDC using the LeoKit API. We’ll cover all five steps: getting a quote, generating a deposit transaction, signing and broadcasting, saving the transaction hash, and tracking the swap status.
Overview
The complete swap flow consists of 5 steps:
Get Quote - Request swap rates from multiple protocols
Generate Deposit - Create an unsigned transaction
Sign & Broadcast - Sign with wallet and broadcast to blockchain
Save Transaction - Register the transaction hash with LeoKit
Track Status - Monitor swap progress until completion
Example: BTC → ETH USDC
Let’s swap 1 BTC (100,000,000 satoshis) to USDC on Ethereum.
Step 1: Get Quote
Request quotes from all supported protocols to find the best rate.
curl -X GET 'https://api.leodex.io/leokit/quote?from_asset=BTC.BTC&to_asset=ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&amount=100000000&destination=0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb&origin=bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh&slippage_bps=150' \
-H 'Api-Key: your_api_key_here'
Response:
{
"quotes" : [
{
"protocol" : "thorchain" ,
"data" : {
"expected_amount_out" : "9850000000" ,
"total_swap_seconds" : 180 ,
"fees" : [ ... ],
"route" : [ "BTC.BTC" , "THOR.RUNE" , "ETH.USDC-0xA0b86991..." ],
"flags" : [ "OPTIMAL" , "CHEAPEST" ]
}
}
],
"timestamp" : "2026-01-15T12:34:56.789Z" ,
"quote_id" : "01936b4a-7c8e-7890-abcd-ef1234567890"
}
Save the quote_id - you’ll need it for all subsequent steps. Quote IDs expire after 15 minutes.
Step 2: Generate Deposit Transaction
Create an unsigned transaction using the quote ID and your selected protocol.
curl -X POST 'https://api.leodex.io/leokit/deposit' \
-H 'Api-Key: your_api_key_here' \
-H 'Content-Type: application/json' \
-d '{
"quote_id": "01936b4a-7c8e-7890-abcd-ef1234567890",
"selected_protocol": "thorchain"
}'
Response:
{
"type" : "UTXO" ,
"protocol" : "thorchain" ,
"quote_id" : "01936b4a-7c8e-7890-abcd-ef1234567890" ,
"details" : {
"from_address" : "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh" ,
"to_address" : "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb" ,
"from_asset" : "BTC.BTC" ,
"to_asset" : "ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" ,
"amount" : "100000000" ,
"decimals" : 8 ,
"memo" : "=:ETH.USDC-0xA0b86991:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb:985000000"
},
"unsigned_transaction" : {
"psbt_hex" : "cHNidP8BAH0CAAAAAR..." ,
"selected_utxos" : [ ... ],
"chain" : "BTC"
}
}
For Bitcoin transactions, LeoKit returns a PSBT (Partially Signed Bitcoin Transaction) that you’ll sign in the next step.
Step 3: Sign & Broadcast (Client-Side)
Sign the transaction with your wallet and broadcast it to the Bitcoin network.
// Using bitcoinjs-lib
import * as bitcoin from "bitcoinjs-lib" ;
const psbt = bitcoin . Psbt . fromHex ( depositData . unsigned_transaction . psbt_hex );
// Sign with wallet (example with private key)
psbt . signAllInputs ( keyPair );
psbt . finalizeAllInputs ();
const txHex = psbt . extractTransaction (). toHex ();
// Broadcast to Bitcoin network
const txHash = await broadcastBitcoinTransaction ( txHex );
Never expose your private keys. This example is for educational purposes. Use secure wallet libraries in production.
Step 4: Save Transaction Hash
Register the transaction hash with LeoKit to enable status tracking.
curl -X POST 'https://api.leodex.io/leokit/save-transaction' \
-H 'Api-Key: your_api_key_here' \
-H 'Content-Type: application/json' \
-d '{
"quote_id": "01936b4a-7c8e-7890-abcd-ef1234567890",
"tx_hash": "a1b2c3d4e5f67890abcdef1234567890abcdef1234567890abcdef1234567890"
}'
Step 5: Track Status
Poll the status endpoint to monitor your swap progress.
curl -X POST 'https://api.leodex.io/leokit/status' \
-H 'Api-Key: your_api_key_here' \
-H 'Content-Type: application/json' \
-d '{
"quote_id": "01936b4a-7c8e-7890-abcd-ef1234567890"
}'
Status Values
Status Description pendingTransaction broadcasted, waiting for confirmation observedTransaction confirmed on source chain inbound_observedProtocol detected the deposit swap_in_progressCross-chain swap executing outbound_observedTokens being sent to destination completedSwap successful, tokens received failedSwap failed (reverted or error)
Best Practices
Use appropriate polling intervals - Poll every 10-15 seconds. Faster polling won’t speed up the swap.
Save quote_id persistently - Store it in your database to track swaps even after page refreshes.
Handle timeouts gracefully - Cross-chain swaps can take 5-10 minutes. Show progress indicators to users.
Test with small amounts first - Always test new integrations with minimal amounts on testnet/mainnet.
Next Steps
ERC20 Approvals Learn how to handle token approvals for ERC20 swaps
Error Debugging Debug failed swaps using trace IDs