Get started in three steps
Integrate the dKit API into your application with this quick guide.Step 1: Get Your First Quote
Start by requesting a swap quote to see available routes and prices.Copy
curl --location 'https://api.dkit.xyz/v1/quote' \
--header 'Content-Type: application/json' \
--header 'api-key: 86c3fc76-25c8-455c-8d6d-0ecea88d0f6e' \
--data '{
"sellAsset": "ZEC.ZEC",
"sellAmount": "2",
"buyAsset": "ETH.ETH",
"slippage": 1,
"affiliate": "eld",
"affiliateFee": 88,
"includeTx": true,
"providers": [
"MAYACHAIN"
],
"sourceAddress": "t1Tmw3syVocrsRUDuCq7jteVjMSNfwpgz88",
"destinationAddress": "0x817bFA97Cc8E5Bfa499D401f43E3087B07AE96f9"
}'
Step 2: Execute the Swap
Use the transaction details from the quote to execute the swap on-chain.- Native Transaction
- EVM Transaction
For native cross-chain swaps (e.g., BTC to ETH via THORChain):
Copy
const route = quote.routes[0]; // Select best route
// Send native transaction to the inbound address with memo
const tx = {
to: route.inboundAddress,
value: sellAmount,
memo: route.memo // Required for THORChain/Maya
};
// Execute with your wallet
const txHash = await wallet.sendTransaction(tx);
Step 3: Track the Swap
Monitor your swap progress in real-time.Copy
const trackSwap = async (txHash, 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: txHash,
chainId: chainId,
quoteId: quoteId,
routeIndex: routeIndex
})
});
const tracking = await response.json();
if (tracking.success) {
console.log(`Status: ${tracking.data.trackingStatus}`);
// Check if complete
if (tracking.data.trackingStatus === 'completed') {
console.log(`Output tx: ${tracking.data.trackMeta.outputTxHash}`);
}
}
return tracking;
};
// Poll for updates
const pollStatus = async (params) => {
let status = 'not_started';
while (status !== 'completed' && status !== 'refunded') {
const result = await trackSwap(params);
if (result.success) {
status = result.data.trackingStatus;
console.log(`Current status: ${status}`);
}
await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
}
};
Complete Example
Here’s a complete example that ties everything together:Copy
async function performSwap() {
try {
// 1. Get quote
const quote = await fetch('https://api.dkit.xyz/v1/quote', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
sellAsset: 'ETH.ETH',
buyAsset: 'BTC.BTC',
sellAmount: '1.0',
sourceAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb8',
destinationAddress: 'bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh',
slippage: 3
})
}).then(r => r.json());
console.log(`Got ${quote.routes.length} routes`);
// 2. Select best route
const route = quote.routes[0];
console.log(`Best route: ${route.providers.join(' → ')}`);
console.log(`Expected output: ${route.expectedBuyAmount} sats`);
// 3. Execute swap (implementation depends on your wallet)
const txHash = await executeSwap(route);
console.log(`Transaction sent: ${txHash}`);
// 4. Track the swap
let tracking;
do {
tracking = await fetch('https://api.dkit.xyz/v1/track', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
hash: txHash,
chainId: '1', // Ethereum mainnet
quoteId: quote.quoteId,
routeIndex: 0
})
}).then(r => r.json());
if (tracking.success) {
console.log(`Status: ${tracking.data.trackingStatus}`);
if (tracking.data.isStreaming) {
const progress = tracking.data.streamingProgress;
console.log(`Streaming: ${progress.percentage}% complete`);
}
}
await new Promise(r => setTimeout(r, 5000)); // Wait 5 seconds
} while (
tracking.success &&
!['completed', 'refunded'].includes(tracking.data.trackingStatus)
);
if (tracking.data.trackingStatus === 'completed') {
console.log('Swap completed successfully!');
console.log(`Output tx: ${tracking.data.trackMeta.outputTxHash}`);
}
} catch (error) {
console.error('Swap failed:', error);
}
}
Next Steps
API Reference
Explore all available endpoints and parameters
Quote Endpoint
Deep dive into quote requests and responses
Error Handling
Learn how to handle errors gracefully
Getting Quotes Guide
Advanced strategies for optimizing quotes
Common Integration Patterns
Wallet Integration
Wallet Integration
Copy
// MetaMask example
const executeEVMSwap = async (route) => {
const accounts = await ethereum.request({
method: 'eth_requestAccounts'
});
const tx = {
from: accounts[0],
to: route.targetAddress || route.inboundAddress,
value: route.tx?.value || '0x0',
data: route.tx?.data || route.memo || '0x'
};
return await ethereum.request({
method: 'eth_sendTransaction',
params: [tx]
});
};
Error Recovery
Error Recovery
Copy
const swapWithRetry = async (params, maxRetries = 3) => {
for (let i = 0; i < maxRetries; i++) {
try {
const quote = await getQuote(params);
if (quote.routes.length > 0) {
return await executeSwap(quote.routes[0]);
}
// Check provider errors
if (quote.providerErrors) {
const retriable = quote.providerErrors.some(e =>
e.errorCode === 'RATE_LIMITED' ||
e.errorCode === 'PROVIDER_UNAVAILABLE'
);
if (!retriable) throw new Error('No routes available');
}
} catch (error) {
if (i === maxRetries - 1) throw error;
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
}
}
};
Amount Formatting
Amount Formatting
Copy
// Convert human-readable amounts to base units
const toBaseUnits = (amount, decimals) => {
const factor = BigInt(10 ** decimals);
const [whole, fraction = ''] = amount.split('.');
const fractionPadded = fraction.padEnd(decimals, '0').slice(0, decimals);
return (BigInt(whole) * factor + BigInt(fractionPadded)).toString();
};
// Convert base units to human-readable
const fromBaseUnits = (amount, decimals) => {
const value = BigInt(amount);
const factor = BigInt(10 ** decimals);
const whole = value / factor;
const remainder = value % factor;
if (remainder === 0n) return whole.toString();
const fraction = remainder.toString().padStart(decimals, '0');
return `${whole}.${fraction.replace(/0+$/, '')}`;
};