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

Body

application/json

Request to create an EVM-to-Arkade swap.

User sends any ERC-20 token on EVM, receives BTC on Arkade.

arkade_htlc_script_version
integer<int64>
required

Arkade HTLC script version. New swaps must use version 1.

evm_chain_id
integer<int64>
required

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

Required range: x >= 0
hash_lock
string
required

Hash lock (0x-prefixed 32-byte hex). Client generates secret, computes SHA256(secret).

receiver_pk
string
required

User's Arkade VHTLC claim key (receiver).

target_address
string
required

Arkade address where the user wants to receive BTC.

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 (mutually exclusive with amount_out).

amount_out
integer<int64> | null

Desired BTC output in sats (mutually exclusive with amount_in).

Required range: x >= 0
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. The backend pads deposit_amount by the fast-transfer fee at UserOp-calldata time.

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).

referral_code
string | null

Optional referral code for tracking.

Response

Swap created successfully

EVM → Arkade (generic) swap response

arkade_htlc_script_version
integer<int64>
required
arkade_server_pk
string
required
btc_vhtlc_address
string
required
chain
string
required
client_evm_address
string
required
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
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).

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

HTLCErc20 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
gasless
boolean
required

Whether this swap was created with gasless relay (Permit2)

hash_lock
string
required
id
string
required
network
string
required
receiver_pk
string
required
sender_pk
string
required
server_evm_address
string
required
source_amount
string
required
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
target_arkade_address
string
required
target_token
object
required
unilateral_claim_delay
integer<int64>
required
unilateral_refund_delay
integer<int64>
required
unilateral_refund_without_receiver_delay
integer<int64>
required
vhtlc_refund_locktime
integer<int64>
required
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. source_token still reports the post-hop Arbitrum USDC; this field tells the SDK what chain the user is expected to burn from.

bridge_source_token_address
string | null

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

btc_claim_txid
string | null
btc_fund_txid
string | null
evm_claim_txid
string | null
evm_fund_txid
string | null