curl --request POST \
--url https://api.satora.io/swap/lightning/arkade \
--header 'Content-Type: application/json' \
--data '
{
"arkade_htlc_script_version": 123,
"claim_pk": "<string>",
"hash_lock": "<string>",
"target_arkade_address": "<string>",
"user_id": "<string>",
"extra_fees": 1,
"invoice_description": "<string>",
"referral_code": "<string>",
"source_amount_sats": 123,
"target_amount_sats": 123
}
'import requests
url = "https://api.satora.io/swap/lightning/arkade"
payload = {
"arkade_htlc_script_version": 123,
"claim_pk": "<string>",
"hash_lock": "<string>",
"target_arkade_address": "<string>",
"user_id": "<string>",
"extra_fees": 1,
"invoice_description": "<string>",
"referral_code": "<string>",
"source_amount_sats": 123,
"target_amount_sats": 123
}
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,
claim_pk: '<string>',
hash_lock: '<string>',
target_arkade_address: '<string>',
user_id: '<string>',
extra_fees: 1,
invoice_description: '<string>',
referral_code: '<string>',
source_amount_sats: 123,
target_amount_sats: 123
})
};
fetch('https://api.satora.io/swap/lightning/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/lightning/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,
'claim_pk' => '<string>',
'hash_lock' => '<string>',
'target_arkade_address' => '<string>',
'user_id' => '<string>',
'extra_fees' => 1,
'invoice_description' => '<string>',
'referral_code' => '<string>',
'source_amount_sats' => 123,
'target_amount_sats' => 123
]),
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/lightning/arkade"
payload := strings.NewReader("{\n \"arkade_htlc_script_version\": 123,\n \"claim_pk\": \"<string>\",\n \"hash_lock\": \"<string>\",\n \"target_arkade_address\": \"<string>\",\n \"user_id\": \"<string>\",\n \"extra_fees\": 1,\n \"invoice_description\": \"<string>\",\n \"referral_code\": \"<string>\",\n \"source_amount_sats\": 123,\n \"target_amount_sats\": 123\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/lightning/arkade")
.header("Content-Type", "application/json")
.body("{\n \"arkade_htlc_script_version\": 123,\n \"claim_pk\": \"<string>\",\n \"hash_lock\": \"<string>\",\n \"target_arkade_address\": \"<string>\",\n \"user_id\": \"<string>\",\n \"extra_fees\": 1,\n \"invoice_description\": \"<string>\",\n \"referral_code\": \"<string>\",\n \"source_amount_sats\": 123,\n \"target_amount_sats\": 123\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.satora.io/swap/lightning/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 \"claim_pk\": \"<string>\",\n \"hash_lock\": \"<string>\",\n \"target_arkade_address\": \"<string>\",\n \"user_id\": \"<string>\",\n \"extra_fees\": 1,\n \"invoice_description\": \"<string>\",\n \"referral_code\": \"<string>\",\n \"source_amount_sats\": 123,\n \"target_amount_sats\": 123\n}"
response = http.request(request)
puts response.read_body{
"arkade_htlc_script_version": 123,
"arkade_server_pk": "<string>",
"arkade_vhtlc_address": "<string>",
"bolt11_invoice": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"fee_sats": 123,
"hash_lock": "<string>",
"id": "<string>",
"invoice_expires_at": 123,
"network": "<string>",
"network_fee_sats": 123,
"receiver_pk": "<string>",
"sender_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>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}Create a new Lightning-to-Arkade swap.
The user pays a BOLT11 hold invoice and receives Arkade VTXOs. Flow:
- User pays the returned hold invoice (the payment is held, not settled)
- Server creates an Arkade VHTLC locked to the same hash
- User claims the VHTLC with their secret, revealing it
- Server settles the held Lightning payment with the revealed secret
curl --request POST \
--url https://api.satora.io/swap/lightning/arkade \
--header 'Content-Type: application/json' \
--data '
{
"arkade_htlc_script_version": 123,
"claim_pk": "<string>",
"hash_lock": "<string>",
"target_arkade_address": "<string>",
"user_id": "<string>",
"extra_fees": 1,
"invoice_description": "<string>",
"referral_code": "<string>",
"source_amount_sats": 123,
"target_amount_sats": 123
}
'import requests
url = "https://api.satora.io/swap/lightning/arkade"
payload = {
"arkade_htlc_script_version": 123,
"claim_pk": "<string>",
"hash_lock": "<string>",
"target_arkade_address": "<string>",
"user_id": "<string>",
"extra_fees": 1,
"invoice_description": "<string>",
"referral_code": "<string>",
"source_amount_sats": 123,
"target_amount_sats": 123
}
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,
claim_pk: '<string>',
hash_lock: '<string>',
target_arkade_address: '<string>',
user_id: '<string>',
extra_fees: 1,
invoice_description: '<string>',
referral_code: '<string>',
source_amount_sats: 123,
target_amount_sats: 123
})
};
fetch('https://api.satora.io/swap/lightning/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/lightning/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,
'claim_pk' => '<string>',
'hash_lock' => '<string>',
'target_arkade_address' => '<string>',
'user_id' => '<string>',
'extra_fees' => 1,
'invoice_description' => '<string>',
'referral_code' => '<string>',
'source_amount_sats' => 123,
'target_amount_sats' => 123
]),
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/lightning/arkade"
payload := strings.NewReader("{\n \"arkade_htlc_script_version\": 123,\n \"claim_pk\": \"<string>\",\n \"hash_lock\": \"<string>\",\n \"target_arkade_address\": \"<string>\",\n \"user_id\": \"<string>\",\n \"extra_fees\": 1,\n \"invoice_description\": \"<string>\",\n \"referral_code\": \"<string>\",\n \"source_amount_sats\": 123,\n \"target_amount_sats\": 123\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/lightning/arkade")
.header("Content-Type", "application/json")
.body("{\n \"arkade_htlc_script_version\": 123,\n \"claim_pk\": \"<string>\",\n \"hash_lock\": \"<string>\",\n \"target_arkade_address\": \"<string>\",\n \"user_id\": \"<string>\",\n \"extra_fees\": 1,\n \"invoice_description\": \"<string>\",\n \"referral_code\": \"<string>\",\n \"source_amount_sats\": 123,\n \"target_amount_sats\": 123\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.satora.io/swap/lightning/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 \"claim_pk\": \"<string>\",\n \"hash_lock\": \"<string>\",\n \"target_arkade_address\": \"<string>\",\n \"user_id\": \"<string>\",\n \"extra_fees\": 1,\n \"invoice_description\": \"<string>\",\n \"referral_code\": \"<string>\",\n \"source_amount_sats\": 123,\n \"target_amount_sats\": 123\n}"
response = http.request(request)
puts response.read_body{
"arkade_htlc_script_version": 123,
"arkade_server_pk": "<string>",
"arkade_vhtlc_address": "<string>",
"bolt11_invoice": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"fee_sats": 123,
"hash_lock": "<string>",
"id": "<string>",
"invoice_expires_at": 123,
"network": "<string>",
"network_fee_sats": 123,
"receiver_pk": "<string>",
"sender_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>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}Body
Arkade VHTLC script version. New swaps must use version 1.
User's claim public key for the Arkade VHTLC
Hash lock provided by the client (0x-prefixed 32-byte hex). The client generates a secret and computes SHA256(secret); the hold invoice and the Arkade VHTLC both lock on this hash.
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 BOLT11 invoice description (max 639 bytes).
Optional referral code for fee exemption
Amount the user wants to send via Lightning in satoshis (fees are
deducted from it — use this for send-max flows). Mutually exclusive
with target_amount_sats.
Amount the user wants to receive on Arkade in satoshis (fees are
added on top of it). Mutually exclusive with source_amount_sats.
Response
Swap created successfully
Lightning → Arkade swap response.
Arkade server's public key
Arkade VHTLC address the server funds
BOLT11 hold invoice the user must pay
Timestamp of when the swap was created
Protocol fee in satoshis
Hash lock (0x-prefixed 32-byte hex; sha256 of the client's secret)
Unique swap identifier
Unix timestamp after which the invoice can no longer be paid
Bitcoin network
Flat network fee in satoshis; the provider's actual Lightning
receive fee is paid out of fee_sats + network_fee_sats
User's claim public key (receiver in the VHTLC)
Server's VHTLC public key (sender in the VHTLC)
Amount the user must pay via Lightning 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 on Arkade in satoshis
User's target Arkade address
Target token info
Show child attributes
Show child attributes
VHTLC refund locktime (unix timestamp)
Arkade VHTLC claim transaction ID (user claim)
Arkade VHTLC fund transaction ID (server funding)