Estimate → Build → Track
Both directions follow the same shape. Each section below is a complete walkthrough using only
HTTP. A successful response wraps its payload as { "data": ..., "success": true }, and the
fields named below live under data. An estimate for a pair that is not enabled still returns
HTTP 200, with success: false. Errors return a 4xx or 5xx status with a message.
BTC → EVM
This walks the full lifecycle of a BTC → EVM request. (The SDK does the same in a few lines.)
1. Estimate
curl -X POST https://api.teleportdao.xyz/api/v2/teleswap/utils/wrap-and-swap-estimate \
-H "Content-Type: application/json" \
-d '{
"amountBTC": "0.001",
"networkName": "optimism",
"outputToken": "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"
}'
Returns the expected outputAmount, minInputAmountBTC, maxInputAmountBTC (null when no
maximum is set), and a teleswapFee breakdown.
2. Build the unsigned transaction
curl -X POST https://api.teleportdao.xyz/api/v2/teleswap/utils/wrap-and-swap-unsigned \
-H "Content-Type: application/json" \
-d '{
"recipientAddress": "0x4e3e1807aa17aed8d1FC580dDa552079d9427ece",
"amountBTC": "0.001",
"networkName": "optimism",
"signer": {
"addressType": "p2wpkh",
"publicKey": "...",
"address": "bc1..."
}
}'
Sign the returned transaction with your Bitcoin wallet and broadcast it.
3. Track
Poll by the Bitcoin TXID until state is Done:
curl https://api.teleportdao.xyz/api/v2/teleswap/requests/tx/<txId>
{ "state": "Pending" } // → later → { "state": "Done", "status": "Submitted", ... }
EVM → BTC
This walks the full lifecycle of an EVM → BTC request. Both endpoints are on /api/v3 — the
recommended path for this direction.
1. Estimate
curl -X POST https://api.teleportdao.xyz/api/v3/teleswap/utils/swap-and-unwrap-estimate \
-H "Content-Type: application/json" \
-d '{
"exchangeInfo": {
"inputToken": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
"inputAmount": "20000000"
},
"networkName": "arbitrum"
}'
Returns the expected outputAmountBTC, minInputAmountBTC, maxInputAmountBTC (null when no
maximum is set), and a teleswapFee breakdown.
inputAmount is in the token's smallest unit; omit inputToken to sell the chain's native coin.
2. Build the contract call
Apply your slippage tolerance to outputAmountBTC and send the result as minBtcAmount — the
floor the contract enforces. Use at most 8 decimals, rounded down. For a 1% tolerance, send
outputAmountBTC × 0.99.
curl -X POST https://api.teleportdao.xyz/api/v3/teleswap/utils/swap-and-unwrap-inputs \
-H "Content-Type: application/json" \
-d '{
"exchangeInfo": {
"inputToken": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
"inputAmount": "20000000"
},
"bitcoinAddress": "bc1...",
"networkName": "arbitrum",
"minBtcAmount": "<outputAmountBTC × 0.99>",
"userAddress": "0x..."
}'
Returns contractAddress, method, methodABI, and inputs — the params to pass and the
value to send.
userAddress is forOn cross-chain networks it is required: if the request fails, this is the address that receives the assets back.
On base networks it is not used. There the only failure mode reverts the whole transaction, so the input token never leaves the user's wallet and there is nothing to refund.
3. Approve and send
Call method on contractAddress with inputs.params, using methodABI and passing
inputs.value as the transaction value.
When inputs.value is 0 the input is an ERC-20 — approve contractAddress to spend
inputAmount first. A non-zero value means the input is the chain's native coin, and there is
nothing to approve.
const contract = new Contract(contractAddress, [methodABI], wallet);
const tx = await contract[method](...inputs.params, {
value: BigInt(inputs.value || "0"),
});
Take contractAddress, method and methodABI from every response rather than hardcoding them.
They depend on the route.
4. Track
Poll by the transaction hash until state is Done or Failed. data is null until the
request has been indexed.
curl https://api.teleportdao.xyz/api/v2/teleswap/requests/tx/<txId>
{ "data": null, "success": true } // not indexed yet
{ "data": { "state": "Pending", ... }, "success": true }
{ "data": { "state": "Done", ... }, "success": true } // or "Failed"
See the full API reference for every parameter.