Make sure you have your wallet connected and funded with the asset you want to swap.
Step 1: Get a Quote
First, get available routes and pricing for your swap. The quote endpoint will return the best available routes across all integrated DEXs.- cURL
- JavaScript
- Python
Copy
curl --location 'https://api.dkit.xyz/v1/quote' \
--header 'Content-Type: application/json' \
--header 'x-api-key: 86c3fc76-25c8-455c-8d6d-0ecea88d0f6e' \
--data '{
"sellAsset": "ETH.ETH",
"sellAmount": "0.5",
"buyAsset": "BTC.BTC",
"slippage": 3,
"affiliate": "dkit",
"affiliateFee": 50,
"includeTx": true,
"providers": [
"THORCHAIN"
],
"sourceAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7",
"destinationAddress": "bc1qns9f7yfx3ry9lj6yz7c9er0vwa0ye2eklpzqfw"
}'
Copy
const getQuote = async () => {
const response = await fetch('https://api.dkit.xyz/v1/quote', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': '86c3fc76-25c8-455c-8d6d-0ecea88d0f6e'
},
body: JSON.stringify({
sellAsset: 'ETH.ETH',
sellAmount: '0.5',
buyAsset: 'BTC.BTC',
slippage: 3,
affiliate: 'dkit',
affiliateFee: 50,
includeTx: true,
providers: ['THORCHAIN'],
sourceAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7',
destinationAddress: 'bc1qns9f7yfx3ry9lj6yz7c9er0vwa0ye2eklpzqfw'
})
});
const quote = await response.json();
console.log('Best route:', quote.routes[0]);
return quote.routes[0]; // Use the best route
};
Copy
import requests
import json
def get_quote():
url = "https://api.dkit.xyz/v1/quote"
headers = {
'Content-Type': 'application/json',
'x-api-key': '86c3fc76-25c8-455c-8d6d-0ecea88d0f6e'
}
payload = {
'sellAsset': 'ETH.ETH',
'sellAmount': '0.5',
'buyAsset': 'BTC.BTC',
'slippage': 3,
'affiliate': 'dkit',
'affiliateFee': 50,
'includeTx': True,
'providers': ['THORCHAIN'],
'sourceAddress': '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7',
'destinationAddress': 'bc1qns9f7yfx3ry9lj6yz7c9er0vwa0ye2eklpzqfw'
}
response = requests.post(url, headers=headers, json=payload)
quote = response.json()
best_route = quote['routes'][0]
print(f"Best route via: {best_route['providers']}")
print(f"Expected output: {best_route['expectedBuyAmount']} BTC")
return best_route
The
quoteId and routeIndex of the response are used to fetch the status of the swap via the /track endpoint and return rich information on the route.Example Response
Example Response
Copy
{
"quoteId": "a7c4b3ef-51d2-4c78-b8e1-8b3e12f7a6d9",
"routes": [
{
"buyAsset": "BTC.BTC",
"destinationAddress": "bc1qns9f7yfx3ry9lj6yz7c9er0vwa0ye2eklpzqfw",
"estimatedTime": {
"inbound": 600,
"swap": 6,
"outbound": 600,
"total": 1206
},
"expectedBuyAmount": "0.02145678",
"expectedBuyAmountMaxSlippage": "0.02081307",
"expiration": "1754920807",
"fees": [
{
"type": "liquidity",
"amount": "1245",
"asset": "BTC.BTC",
"chain": "THOR",
"protocol": "THORCHAIN"
},
{
"type": "outbound",
"amount": "15000",
"asset": "BTC.BTC",
"chain": "BTC",
"protocol": "THORCHAIN"
},
{
"type": "affiliate",
"amount": "10728",
"asset": "BTC.BTC",
"chain": "THOR",
"protocol": "THORCHAIN"
},
{
"type": "inbound",
"amount": "0",
"asset": "ETH.ETH",
"chain": "ETH",
"protocol": "THORCHAIN"
}
],
"inboundAddress": "0x8c7c3f4e8b1d3a4e5c9f2b6a7d9e1f3c5b8a2d6e",
"legs": [
{
"provider": "THORCHAIN",
"sellAsset": "ETH.ETH",
"sellAmount": "0.5",
"buyAsset": "BTC.BTC",
"buyAmount": "0.02145678",
"buyAmountMaxSlippage": "0.02081307",
"fees": [
{
"type": "liquidity",
"amount": "1245",
"asset": "BTC.BTC",
"chain": "THOR",
"protocol": "THORCHAIN"
},
{
"type": "outbound",
"amount": "15000",
"asset": "BTC.BTC",
"chain": "BTC",
"protocol": "THORCHAIN"
},
{
"type": "affiliate",
"amount": "10728",
"asset": "BTC.BTC",
"chain": "THOR",
"protocol": "THORCHAIN"
},
{
"type": "inbound",
"amount": "0",
"asset": "ETH.ETH",
"chain": "ETH",
"protocol": "THORCHAIN"
}
]
}
],
"memo": "=:BTC.BTC:bc1qns9f7yfx3ry9lj6yz7c9er0vwa0ye2eklpzqfw:2081307:dkit:50",
"meta": {
"priceImpact": 0.12,
"assets": [
{
"asset": "ETH.ETH",
"price": 3450.25,
"image": "https://crispy.sfo3.cdn.digitaloceanspaces.com/eth.eth.png"
},
{
"asset": "BTC.BTC",
"price": 67890.50,
"image": "https://crispy.sfo3.cdn.digitaloceanspaces.com/btc.btc.png"
}
],
"affiliate": "dkit",
"affiliateFee": 50,
"tags": [],
"txType": "EVM"
},
"providers": [
"THORCHAIN"
],
"sellAmount": "0.5",
"sellAsset": "ETH.ETH",
"sourceAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7",
"totalSlippageBps": 300,
"warnings": []
}
]
}
Step 2: Execute the Swap
Use the quote information to submit your transaction on-chain. For this ETH to BTC swap via THORChain, you’ll send ETH to the inbound address with the memo.Copy
import { ethers } from 'ethers';
const executeSwap = async (route) => {
// Connect to wallet (MetaMask, WalletConnect, etc.)
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
// For THORChain swaps: send ETH to inbound address with memo
const tx = {
to: route.inboundAddress,
value: ethers.utils.parseEther(route.sellAmount), // Convert 0.5 ETH to wei
data: ethers.utils.toUtf8Bytes(route.memo),
gasLimit: 100000
};
const txResponse = await signer.sendTransaction(tx);
console.log('Transaction sent:', txResponse.hash);
// Wait for transaction confirmation
const receipt = await txResponse.wait();
console.log('Transaction confirmed in block:', receipt.blockNumber);
return txResponse.hash;
};
// Execute using the route from Step 1
const route = await getQuote();
const txHash = await executeSwap(route);
Always verify the
targetAddress or inboundAddress matches what the quote returned before sending funds.Step 3: Track Your Swap
Monitor the progress of your swap until completion. The swap tracking endpoint accepts thequoteId and routeIndex from the quote response and provides real-time status updates with rich route information.
- cURL
- JavaScript
- Python
Copy
curl --location 'https://api.dkit.xyz/v1/track' \
--header 'content-type: application/json' \
--header 'x-api-key: 86c3fc76-25c8-455c-8d6d-0ecea88d0f6e' \
--data '{
"hash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"chainId": "ethereum",
"quoteId": "a7c4b3ef-51d2-4c78-b8e1-8b3e12f7a6d9",
"routeIndex": 0
}'
Copy
const trackSwap = async (hash, chainId, quoteId, routeIndex) => {
const response = await fetch('https://api.dkit.xyz/v1/track', {
method: 'POST',
headers: {
'content-type': 'application/json',
'x-api-key': '86c3fc76-25c8-455c-8d6d-0ecea88d0f6e'
},
body: JSON.stringify({
hash: hash,
chainId: chainId,
quoteId: quoteId,
routeIndex: routeIndex
})
});
const status = await response.json();
return status;
};
// Poll for updates
const pollSwapStatus = async (hash, chainId, quoteId, routeIndex) => {
let isComplete = false;
while (!isComplete) {
const status = await trackSwap(hash, chainId, quoteId, routeIndex);
console.log(`Status: ${status.trackingStatus}`);
console.log(`Stage: ${status.stage}`);
if (status.trackingStatus === 'completed') {
console.log('Swap completed!');
console.log(`BTC output tx: ${status.data.outbound?.hash}`);
isComplete = true;
} else if (status.trackingStatus === 'failed' || status.trackingStatus === 'refunded') {
console.error('Swap failed or refunded:', status.error);
isComplete = true;
}
// Wait 10 seconds before next check
if (!isComplete) {
await new Promise(resolve => setTimeout(resolve, 10000));
}
}
};
// Track the swap from Step 2 (use actual values from your transaction)
await pollSwapStatus(
txHash, // from Step 2
'ethereum',
'a7c4b3ef-51d2-4c78-b8e1-8b3e12f7a6d9', // from Step 1 quote response
0
);
Copy
import time
import requests
def track_swap(hash, chain_id, quote_id, route_index):
url = "https://api.dkit.xyz/v1/track"
headers = {
'content-type': 'application/json',
'x-api-key': '86c3fc76-25c8-455c-8d6d-0ecea88d0f6e'
}
payload = {
"hash": hash,
"chainId": chain_id,
"quoteId": quote_id,
"routeIndex": route_index
}
response = requests.post(url, headers=headers, json=payload)
return response.json()
def poll_swap_status(hash, chain_id, quote_id, route_index):
"""Poll swap status until completion"""
while True:
status = track_swap(hash, chain_id, quote_id, route_index)
print(f"Status: {status['trackingStatus']}")
print(f"Stage: {status.get('stage', 'N/A')}")
if status['trackingStatus'] == 'completed':
print('Swap completed!')
if 'data' in status and 'outbound' in status['data']:
print(f"BTC output tx: {status['data']['outbound'].get('hash')}")
break
elif status['trackingStatus'] in ['failed', 'refunded']:
print(f"Swap failed or refunded: {status.get('error', 'Unknown error')}")
break
# Wait 10 seconds before next check
time.sleep(10)
return status
# Example usage (use actual values from your transaction)
final_status = poll_swap_status(
"0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"ethereum",
"a7c4b3ef-51d2-4c78-b8e1-8b3e12f7a6d9",
0
)
Example Tracking Response
Example Tracking Response
Copy
{
"success": true,
"trackingStatus": "completed",
"stage": "outbound",
"data": {
"quoteInfo": {
"quoteId": "a7c4b3ef-51d2-4c78-b8e1-8b3e12f7a6d9",
"routeIndex": 0,
"senderAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7",
"recipientAddress": "bc1qns9f7yfx3ry9lj6yz7c9er0vwa0ye2eklpzqfw",
"provider": "THORCHAIN",
"trackParams": {
"hash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"chainId": "ethereum"
}
},
"inbound": {
"hash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"amount": "0.5",
"asset": "ETH.ETH",
"confirmations": 12,
"blockNumber": 18765432
},
"swap": {
"swapId": "ABC123DEF456",
"status": "success",
"swapTime": 8
},
"outbound": {
"hash": "3f2329b4d5e6c8a9f1b7d4c5e6f8a9b0c1d2e3f4567890abcdef1234567890ab",
"amount": "0.02081307",
"asset": "BTC.BTC",
"confirmations": 2,
"blockNumber": 823456
},
"route": {
"fees": [
{
"type": "liquidity",
"asset": "BTC.BTC",
"chain": "THOR",
"amount": "1245",
"protocol": "THORCHAIN"
},
{
"type": "outbound",
"asset": "BTC.BTC",
"chain": "BTC",
"amount": "15000",
"protocol": "THORCHAIN"
},
{
"type": "affiliate",
"asset": "BTC.BTC",
"chain": "THOR",
"amount": "10728",
"protocol": "THORCHAIN"
}
],
"legs": [
{
"provider": "THORCHAIN",
"sellAsset": "ETH.ETH",
"sellAmount": "0.5",
"buyAsset": "BTC.BTC",
"buyAmount": "0.02081307",
"actualBuyAmount": "0.02081307"
}
],
"memo": "=:BTC.BTC:bc1qns9f7yfx3ry9lj6yz7c9er0vwa0ye2eklpzqfw:2081307:dkit:50",
"meta": {
"assets": [
{
"asset": "ETH.ETH",
"image": "https://crispy.sfo3.cdn.digitaloceanspaces.com/eth.eth.png",
"price": 3450.25
},
{
"asset": "BTC.BTC",
"image": "https://crispy.sfo3.cdn.digitaloceanspaces.com/btc.btc.png",
"price": 67890.50
}
],
"txType": "EVM",
"affiliate": "dkit",
"priceImpact": 0.12,
"affiliateFee": 50
},
"buyAsset": "BTC.BTC",
"providers": ["THORCHAIN"],
"sellAsset": "ETH.ETH",
"sellAmount": "0.5",
"actualBuyAmount": "0.02081307",
"expectedBuyAmount": "0.02145678",
"sourceAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7",
"destinationAddress": "bc1qns9f7yfx3ry9lj6yz7c9er0vwa0ye2eklpzqfw",
"inboundAddress": "0x8c7c3f4e8b1d3a4e5c9f2b6a7d9e1f3c5b8a2d6e",
"totalSlippageBps": 300
}
}
}
Congratulations! You’ve completed your first cross-chain swap with dKit.
What’s Next?
- Quote Endpoint - Detailed quote parameters and options
- Track Endpoint - Advanced tracking features
- Supported Assets - Browse all available tokens
- Fee Structure - Understand fee breakdowns