TestnetSwap lets you swap one testnet coin for another instantly, without custody and without trusting anyone. It feels like a one-provider instant exchange — pick a pair, see the rate, confirm — but it is not custodial. Each swap is a cross-chain HTLC atomic swap: your funds are only ever in a contract that either completes the swap or refunds to you.
You are the taker and you run nothing but the wallet. The other side of every swap is a single always-on maker daemon, funded from CypherFaucet — so there's never a wait for a second human.
Setup
Your wallet generates a random 32-byte secret S and computes its hash H = SHA256(S). Over the relay (a dumb message pipe), the wallet and maker exchange H, both public keys, the amounts, and two absolute timelocks — T1 for you (longer) and T2 for the maker (shorter).
You lock
Your wallet builds an HTLC on the send chain with deadline T1, funds it, and broadcasts. The contract pays the maker if it reveals S, or refunds to you after T1.
They lock
The maker waits for your funded contract to confirm, verifies it on-chain, then builds a matching HTLC on the receive chain with the shorter deadline T2 — paying you if you reveal S, or refunding to the maker after T2.
You claim
Your wallet verifies the maker's contract, then claims it by revealing S in the spend. You now have the receive-chain coins — and S is public on that chain. The maker reads S from your spend and uses it to claim your contract. Swap complete, atomically.
Atomicity is the whole point. The maker cannot claim your contract without revealing the secret S — and the moment S is revealed, you can claim the maker's contract. The two are bound by the same hash H.
If the maker vanishes after you lock, it simply never reveals S; you reclaim your coins after T1. The worst case is always: you get back exactly what you locked.
The load-bearing rule: T1 > T2
You (the initiator, who reveals the secret first) always get the longer refund window. If it were inverted, you could reveal at the last moment, claim, and still refund — breaking atomicity. TestnetSwap enforces a safe gap between the two deadlines.
A P2WSH hash-timelock contract, identical on both chains (both are secp256k1 UTXO chains with Script):
OP_IF
OP_SIZE 0x20 OP_EQUALVERIFY # secret must be exactly 32 bytes
OP_SHA256 <secret_hash> OP_EQUALVERIFY
OP_DUP OP_HASH160 <recipient_pkh>
OP_ELSE
<locktime> OP_CHECKLOCKTIMEVERIFY OP_DROP
OP_DUP OP_HASH160 <refund_pkh>
OP_ENDIF
OP_EQUALVERIFY
OP_CHECKSIG
Redeem path (IF): reveal a 32-byte secret whose SHA256 matches, signed by the recipient. Refund path (ELSE): after the timelock (CLTV), signed by the refunder. Timelocks are time-based (wall-clock), so your wallet can show a clear "refundable after HH:MM".
Monero
tXMR can't ride a client-side atomic swap (BTC↔XMR needs cross-curve adaptor signatures that aren't browser-runnable). For tXMR, use the faucet.
Custody & mainnet
No custodial mode (it would defeat the purpose) and testnet only for now. The non-custodial design would port to mainnet, but that's a separate, heavier decision.