Skip to main content
POST
Create a chain-agnostic EVM-to-Lightning swap.

Body

application/json

Request to create an EVM-to-Lightning swap.

User sends any ERC-20 token on EVM, receives BTC on a Lightning invoice.

evm_chain_id
integer<int64>
required

Numeric EVM chain ID: 1 (Ethereum), 137 (Polygon), 42161 (Arbitrum).

Required range: x >= 0
token_address
string
required

ERC-20 contract address of the source token on the EVM chain.

user_address
string
required

User's EVM address (sender of the ERC-20 token).

user_id
string
required

User ID derived from wallet for recovery purposes.

amount_in
string | null

Source token amount in smallest units (send-max: fees are deducted from the Lightning payout). Only valid with lightning_address/lnurl; mutually exclusive with target_amount_sats.

bridge_source_chain
string | null

Optional: CCTP bridge source chain (e.g., "Ethereum", "Optimism", "Solana"). When set, the user's source USDC originates on this chain and hops through CCTPv2 to Arbitrum before the HTLC is created.

bridge_source_token_address
string | null

Optional: USDC address on the bridge source chain (0x address on EVM chains, base58 mint on Solana).

extra_fees
integer<int32> | null

Optional per-swap fee surcharge in basis points (0..=max_extra_fee_bps configured on the matching developer key).

Required range: x >= 0
gasless
boolean

Whether to use gasless relay for funding (server submits tx on behalf of user).

lightning_address
string | null

Lightning address (user@domain) to resolve into an invoice over the payout amount. Mutually exclusive with the other destination fields.

lightning_invoice
string | null

BOLT11 invoice the user wants paid. Must carry an amount (which pins the payout — amount_in cannot be combined with it). Mutually exclusive with lightning_address and lnurl.

lnurl
string | null

LNURL-pay string to resolve into an invoice over the payout amount. Mutually exclusive with the other destination fields.

referral_code
string | null

Optional referral code for fee exemption.

target_amount_sats
integer<int64> | null

Amount the recipient should receive over Lightning in satoshis (fees are added on top). Required with lightning_address/lnurl unless amount_in is given; optional with lightning_invoice, where it must match the invoice amount.

Response

Swap created successfully

EVM → Lightning swap response.

chain
string
required
client_evm_address
string
required
client_lightning_invoice
string
required

BOLT11 invoice the server will pay once the HTLC funding is final

created_at
string<date-time>
required
evm_chain_id
integer<int64>
required
evm_coordinator_address
string
required

The coordinator this swap is pinned to (the HTLC refundAddress).

evm_expected_sats
string
required

WBTC/tBTC the coordinator locks in the HTLC, in token smallest units

evm_funding_confirmations
integer<int64>
required

Blocks the deposit must be buried under before the server acts on it (funding finality on this chain). With the funding receipt's block and the chain head a client can show the confirmation progress.

Required range: x >= 0
evm_htlc_address
string
required
evm_htlc_kind
enum<string>
required

HTLC family of the lock: erc20 (HTLCErc20 + HTLCCoordinator) or native (HTLCNative + HTLCNativeCoordinator). Selects how the client funds (Permit2 vs a payable lock) and refunds the swap.

Available options:
erc20,
native
evm_htlc_version
integer<int64>
required

HTLC contract VERSION of the deployment this swap lives on — the EIP-712 domain version string for redeem/refund signatures.

evm_refund_locktime
integer<int64>
required
fee_sats
integer<int64>
required

Protocol fee in satoshis

gasless
boolean
required

Whether this swap was created with gasless relay (Permit2)

hash_lock
string
required

Hash lock (0x-prefixed 32-byte hex; the invoice's payment hash)

id
string
required
invoice_expires_at
integer<int64>
required

Unix timestamp after which the invoice can no longer be paid

lightning_payment_settled
boolean
required

Whether the invoice has settled. serverfunded only says the payment was initiated; the preimage the recipient revealed is what proves it landed, and the server claims the HTLC with it next.

network
string
required
network_fee_sats
integer<int64>
required

Network fee in satoshis: the provider's quoted Lightning send fee plus the server's HTLC claim gas. The actual send fee is paid out of fee_sats + network_fee_sats, never on top.

server_evm_address
string
required
source_amount
string
required

Source token amount in smallest units

source_token
object
required
status
enum<string>
required

Atomic swap state machine for BTC --> Target Asset swaps using HTLCs.

Overview

This enum tracks the state of an atomic swap between Bitcoin (via Lightning/Arkade) and Target Asset (on Polygon, Ethereum, etc). The swap uses Hash Time-Locked Contracts (HTLCs) to ensure atomicity without requiring trust.

Normal Flow

  1. Client creates swap request → Pending
  2. Client sends BTC → ClientFunded
  3. Server locks WBTC in Polygon HTLC → ServerFunded
  4. Client reveals secret to claim Target Asset → ClientRedeemed
  5. Server uses secret to claim BTC → ServerRedeemed (terminal)

Refund Flows

State Diagram

See swap_states.md for a complete state diagram and detailed documentation.

Security

  • Bitcoin HTLC timeout must be longer than Polygon HTLC timeout
  • Secret becomes public when client claims TargetAsset on Polygon
  • ClientRefundedServerFunded is an error state that should never occur
Available options:
pending,
clientfundingseen,
clientfunded,
clientrefunded,
serverfunded,
clientredeeming,
clientredeemed,
serverredeemed,
clientfundedserverrefunded,
clientrefundedserverfunded,
clientrefundedserverrefunded,
expired,
clientinvalidfunded,
clientfundedtoolate,
serverwontfund,
clientredeemedandclientrefunded
target_amount
string
required

Amount paid out on the user's Lightning invoice in satoshis

target_token
object
required
wbtc_address
string
required

WBTC/tBTC token contract address on the EVM chain (the token locked in the HTLC).

bridge_source_chain
string | null

CCTP bridge source chain. Set when the source USDC originated on another CCTP chain and hopped to Arbitrum via CCTPv2 before the HTLC was created.

bridge_source_token_address
string | null

Native USDC address on the bridge source chain (base58 mint on Solana).

evm_claim_txid
string | null
evm_fund_txid
string | null