curl --request POST \
--url https://api.satora.io/swap/bitcoin/arkade \
--header 'Content-Type: application/json' \
--data '
{
"arkade_htlc_script_version": 123,
"btc_htlc_script_version": 123,
"claim_pk": "<string>",
"hash_lock": "<string>",
"refund_pk": "<string>",
"sats_receive": 123,
"target_arkade_address": "<string>",
"user_id": "<string>",
"extra_fees": 1,
"referral_code": "<string>"
}
'import requests
url = "https://api.satora.io/swap/bitcoin/arkade"
payload = {
"arkade_htlc_script_version": 123,
"btc_htlc_script_version": 123,
"claim_pk": "<string>",
"hash_lock": "<string>",
"refund_pk": "<string>",
"sats_receive": 123,
"target_arkade_address": "<string>",
"user_id": "<string>",
"extra_fees": 1,
"referral_code": "<string>"
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
arkade_htlc_script_version: 123,
btc_htlc_script_version: 123,
claim_pk: '<string>',
hash_lock: '<string>',
refund_pk: '<string>',
sats_receive: 123,
target_arkade_address: '<string>',
user_id: '<string>',
extra_fees: 1,
referral_code: '<string>'
})
};
fetch('https://api.satora.io/swap/bitcoin/arkade', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.satora.io/swap/bitcoin/arkade",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'arkade_htlc_script_version' => 123,
'btc_htlc_script_version' => 123,
'claim_pk' => '<string>',
'hash_lock' => '<string>',
'refund_pk' => '<string>',
'sats_receive' => 123,
'target_arkade_address' => '<string>',
'user_id' => '<string>',
'extra_fees' => 1,
'referral_code' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.satora.io/swap/bitcoin/arkade"
payload := strings.NewReader("{\n \"arkade_htlc_script_version\": 123,\n \"btc_htlc_script_version\": 123,\n \"claim_pk\": \"<string>\",\n \"hash_lock\": \"<string>\",\n \"refund_pk\": \"<string>\",\n \"sats_receive\": 123,\n \"target_arkade_address\": \"<string>\",\n \"user_id\": \"<string>\",\n \"extra_fees\": 1,\n \"referral_code\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.satora.io/swap/bitcoin/arkade")
.header("Content-Type", "application/json")
.body("{\n \"arkade_htlc_script_version\": 123,\n \"btc_htlc_script_version\": 123,\n \"claim_pk\": \"<string>\",\n \"hash_lock\": \"<string>\",\n \"refund_pk\": \"<string>\",\n \"sats_receive\": 123,\n \"target_arkade_address\": \"<string>\",\n \"user_id\": \"<string>\",\n \"extra_fees\": 1,\n \"referral_code\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.satora.io/swap/bitcoin/arkade")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"arkade_htlc_script_version\": 123,\n \"btc_htlc_script_version\": 123,\n \"claim_pk\": \"<string>\",\n \"hash_lock\": \"<string>\",\n \"refund_pk\": \"<string>\",\n \"sats_receive\": 123,\n \"target_arkade_address\": \"<string>\",\n \"user_id\": \"<string>\",\n \"extra_fees\": 1,\n \"referral_code\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"arkade_htlc_script_version": 123,
"arkade_server_pk": "<string>",
"arkade_vhtlc_address": "<string>",
"asset_amount": 123,
"btc_htlc_address": "<string>",
"btc_htlc_script_version": 123,
"btc_refund_locktime": 123,
"created_at": "2023-11-07T05:31:56Z",
"fee_sats": 123,
"hash_lock": "<string>",
"id": "<string>",
"network": "<string>",
"sats_receive": 123,
"server_vhtlc_pk": "<string>",
"source_amount": "<string>",
"source_token": {
"chain": "Arkade",
"decimals": 1,
"name": "<string>",
"symbol": "<string>",
"token_id": "btc"
},
"status": "pending",
"target_amount": "<string>",
"target_arkade_address": "<string>",
"target_token": {
"chain": "Arkade",
"decimals": 1,
"name": "<string>",
"symbol": "<string>",
"token_id": "btc"
},
"unilateral_claim_delay": 123,
"unilateral_refund_delay": 123,
"unilateral_refund_without_receiver_delay": 123,
"vhtlc_refund_locktime": 123,
"arkade_claim_txid": "<string>",
"arkade_fund_txid": "<string>",
"btc_claim_txid": "<string>",
"btc_fund_txid": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}Create a new Bitcoin (on-chain) to Arkade swap request
The user provides an on-chain BTC amount to swap and receives Arkade VTXOs. Flow:
- User sends BTC to the Taproot HTLC address returned
- After 1 confirmation, server creates Arkade VHTLC for user
- User claims Arkade VHTLC with secret, revealing it
- Server claims on-chain BTC with the revealed secret
curl --request POST \
--url https://api.satora.io/swap/bitcoin/arkade \
--header 'Content-Type: application/json' \
--data '
{
"arkade_htlc_script_version": 123,
"btc_htlc_script_version": 123,
"claim_pk": "<string>",
"hash_lock": "<string>",
"refund_pk": "<string>",
"sats_receive": 123,
"target_arkade_address": "<string>",
"user_id": "<string>",
"extra_fees": 1,
"referral_code": "<string>"
}
'import requests
url = "https://api.satora.io/swap/bitcoin/arkade"
payload = {
"arkade_htlc_script_version": 123,
"btc_htlc_script_version": 123,
"claim_pk": "<string>",
"hash_lock": "<string>",
"refund_pk": "<string>",
"sats_receive": 123,
"target_arkade_address": "<string>",
"user_id": "<string>",
"extra_fees": 1,
"referral_code": "<string>"
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
arkade_htlc_script_version: 123,
btc_htlc_script_version: 123,
claim_pk: '<string>',
hash_lock: '<string>',
refund_pk: '<string>',
sats_receive: 123,
target_arkade_address: '<string>',
user_id: '<string>',
extra_fees: 1,
referral_code: '<string>'
})
};
fetch('https://api.satora.io/swap/bitcoin/arkade', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.satora.io/swap/bitcoin/arkade",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'arkade_htlc_script_version' => 123,
'btc_htlc_script_version' => 123,
'claim_pk' => '<string>',
'hash_lock' => '<string>',
'refund_pk' => '<string>',
'sats_receive' => 123,
'target_arkade_address' => '<string>',
'user_id' => '<string>',
'extra_fees' => 1,
'referral_code' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.satora.io/swap/bitcoin/arkade"
payload := strings.NewReader("{\n \"arkade_htlc_script_version\": 123,\n \"btc_htlc_script_version\": 123,\n \"claim_pk\": \"<string>\",\n \"hash_lock\": \"<string>\",\n \"refund_pk\": \"<string>\",\n \"sats_receive\": 123,\n \"target_arkade_address\": \"<string>\",\n \"user_id\": \"<string>\",\n \"extra_fees\": 1,\n \"referral_code\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.satora.io/swap/bitcoin/arkade")
.header("Content-Type", "application/json")
.body("{\n \"arkade_htlc_script_version\": 123,\n \"btc_htlc_script_version\": 123,\n \"claim_pk\": \"<string>\",\n \"hash_lock\": \"<string>\",\n \"refund_pk\": \"<string>\",\n \"sats_receive\": 123,\n \"target_arkade_address\": \"<string>\",\n \"user_id\": \"<string>\",\n \"extra_fees\": 1,\n \"referral_code\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.satora.io/swap/bitcoin/arkade")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"arkade_htlc_script_version\": 123,\n \"btc_htlc_script_version\": 123,\n \"claim_pk\": \"<string>\",\n \"hash_lock\": \"<string>\",\n \"refund_pk\": \"<string>\",\n \"sats_receive\": 123,\n \"target_arkade_address\": \"<string>\",\n \"user_id\": \"<string>\",\n \"extra_fees\": 1,\n \"referral_code\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"arkade_htlc_script_version": 123,
"arkade_server_pk": "<string>",
"arkade_vhtlc_address": "<string>",
"asset_amount": 123,
"btc_htlc_address": "<string>",
"btc_htlc_script_version": 123,
"btc_refund_locktime": 123,
"created_at": "2023-11-07T05:31:56Z",
"fee_sats": 123,
"hash_lock": "<string>",
"id": "<string>",
"network": "<string>",
"sats_receive": 123,
"server_vhtlc_pk": "<string>",
"source_amount": "<string>",
"source_token": {
"chain": "Arkade",
"decimals": 1,
"name": "<string>",
"symbol": "<string>",
"token_id": "btc"
},
"status": "pending",
"target_amount": "<string>",
"target_arkade_address": "<string>",
"target_token": {
"chain": "Arkade",
"decimals": 1,
"name": "<string>",
"symbol": "<string>",
"token_id": "btc"
},
"unilateral_claim_delay": 123,
"unilateral_refund_delay": 123,
"unilateral_refund_without_receiver_delay": 123,
"vhtlc_refund_locktime": 123,
"arkade_claim_txid": "<string>",
"arkade_fund_txid": "<string>",
"btc_claim_txid": "<string>",
"btc_fund_txid": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}Body
Arkade VHTLC script version. New swaps must use version 1.
Bitcoin HTLC script version. New swaps must use version 1.
User's claim public key for the Arkade VHTLC
Hash lock provided by the client (20-byte hex string, no 0x prefix). The client generates a secret and computes HASH160(secret) = RIPEMD160(SHA256(secret)). This hash is used for both the on-chain Bitcoin HTLC (OP_HASH160) and the Arkade VHTLC. Client will use the secret to claim the Arkade VHTLC later.
User's refund public key for the on-chain Bitcoin HTLC
Amount the user wants to receive on Arkade in satoshis
User's target Arkade address to receive VTXOs
User ID derived from wallet for recovery purposes
Optional per-swap fee surcharge in basis points (0..=max_extra_fee_bps configured on the matching developer key).
x >= 0Optional referral code for fee exemption
Response
Swap created successfully
BTC → Arkade swap response
Arkade server's public key
Arkade VHTLC address
Amount user must send in satoshis
Deprecated: please use [target_amount]
On-chain Bitcoin HTLC P2WSH address (user sends BTC here)
On-chain refund locktime (unix timestamp)
Timestamp of when the swap was created
Protocol fee in satoshis
Hash lock (32-byte hex, no 0x prefix)
Unique swap identifier
Bitcoin network
Amount user will receive on Arkade in satoshis
Server's VHTLC public key (sender in the VHTLC)
Amount user must send in satoshis
Source token info
Show child attributes
Show child attributes
Current status of the swap
pending, clientfundingseen, clientfunded, clientrefunded, serverfunded, clientredeeming, clientredeemed, serverredeemed, clientfundedserverrefunded, clientrefundedserverfunded, clientrefundedserverrefunded, expired, clientinvalidfunded, clientfundedtoolate, serverwontfund, clientredeemedandclientrefunded Amount the user will receive
User's target Arkade address
Target token info
Show child attributes
Show child attributes
Unilateral claim delay in seconds
Unilateral refund delay in seconds
Unilateral refund without receiver delay in seconds
VHTLC refund locktime (unix timestamp)
Arkade VHTLC claim transaction ID (user claim)
Arkade VHTLC fund transaction ID
On-chain claim transaction ID (server claim)
On-chain funding transaction ID