What is an HTLC?
An HTLC is a smart contract that locks funds with two conditions:- Hash Lock: Funds can be claimed by revealing a secret (preimage)
- Time Lock: Funds are automatically refunded after a timeout
How It Works
Hash Lock
- Only the party with the secret can claim funds
- The same 32-byte secret unlocks both sides; only the hash function differs:
- EVM HTLC verifies
sha256(preimage) == preimageHash(32-byte digest) - Bitcoin on-chain HTLC and Arkade VHTLC use
OP_HASH160, i.e.RIPEMD160(SHA256(preimage)) == hashLock(20-byte digest)
- EVM HTLC verifies
- 32-byte secret = 2^256 possible values (cryptographically secure)
Time Lock
- Before timeout: Only recipient can claim with secret
- After timeout: Sender can refund (no secret needed)
These values are hardcoded per network in the SDK (
HtlcRefundTimeouts::new): 24h client / 12h server on Bitcoin mainnet. Regtest can override via LENDASWAP_REGTEST_CLIENT_TIMEOUT_SECS / LENDASWAP_REGTEST_SERVER_TIMEOUT_SECS. They are not server-configurable in production.
Contract Architecture
Satora Swaps uses a two-contract architecture on each EVM chain (Polygon, Ethereum, Arbitrum): HTLCErc20 - The core HTLC contract that holds ERC-20 tokens. Supports:- Direct claiming by the designated claim address
- EIP-712 signature-based claiming for gasless execution (
redeemBySig) - Refund to sender or explicit destination after timelock
executeAndCreateWithPermit2- Pull tokens via Permit2, execute DEX swap calls, then lock the result in an HTLCredeemAndExecute- Redeem an HTLC via EIP-712 signature, execute DEX swap, sweep tokens to destinationrefundAndExecute- Refund an expired HTLC, optionally swap tokens back, sweep to destinationrefundTo- Simple refund of an expired HTLC directly to the original depositor or a specified address
DEX-agnostic design: The coordinator accepts arbitrary call arrays for DEX aggregation.
Satora Swaps HTLC Flow (BTC → EVM)
1
Client Generates Secret
Client generates a random 32-byte preimage S. From it the client derives both hash locks the swap needs:
H_evm = SHA256(S) for the EVM HTLC and H_btc = HASH160(S) = RIPEMD160(SHA256(S)) for the Bitcoin / Arkade side. The client shares the hashes with the service - never the preimage itself. This ensures only the client can initiate the claim.2
Client Pays BTC
Client pays via a Boltz reverse swap (Lightning), sends to an Arkade VHTLC, or sends to an on-chain Bitcoin P2TR (Taproot) HTLC. The Taproot output commits to a script of the form
<server_pk> OP_CHECKSIGVERIFY OP_HASH160 <H_btc> OP_EQUAL, so the same OP_HASH160 rule covers the on-chain HTLC and Arkade VHTLC. For Lightning, Boltz locks BTC in an Arkade VHTLC using H_btc.3
Service Creates EVM HTLC
Service locks tokens in the EVM smart contract (HTLCErc20) using the same hash H:
- Claim address (user or coordinator)
- Hash lock H
- Timelock (24 hours for client, 12 hours for server on mainnet)
- Token address and amount
executeAndCreateWithPermit2 on the coordinator. The depositor authorizes the input-token transfer with a Permit2 signature; the coordinator pulls the tokens via Permit2, runs the DEX swap calls, and locks the resulting balance in the HTLC - all in a single transaction.4
Client Claims Tokens
Client reveals the preimage S to claim their tokens:
- Gasless (recommended): Client signs an EIP-712 message. Server calls
redeemAndExecuteon the coordinator, which redeems the HTLC, optionally swaps tokens via DEX routing, and sweeps to the client’s destination. - Manual: Client calls
redeemdirectly on HTLCErc20 with the preimage (requires signer + gas).
5
Service Settles BTC
Service extracts S from the EVM chain and claims the Arkade VHTLC via Boltz (or spends the on-chain P2TR HTLC by revealing the hashlock script path with S).
Gasless Execution
Satora Swaps uses EIP-712 typed data signatures so users never need to pay gas:- User signs an EIP-712 message binding: preimage, destination address, sweep token, and minimum output amount
- Server submits
redeemAndExecuteon the HTLCCoordinator (server pays gas) - The coordinator redeems the HTLC, executes any DEX swap calls, and sweeps tokens to the user’s signed destination
- User receives tokens with zero gas cost
msg.sender, preventing front-running. The signed destination address ensures tokens can only go to the address the user specified.
Gasless fee: A small gas fee is deducted from the swap amount depending on network conditions. This fee is included in the quote. Alternatively, you can claim manually with your own signer and pay gas yourself.