moos

monero ⇔ ethereum atomic swaps · one maker, one machine, no accounts


moos is an open-source atomic-swap client. I run a maker for it: you take one of my offers from your own machine, lock your side on-chain, and the swap either completes both legs or returns yours after a timelock. No account, no deposit with me, no identity check.

CustodyNone. Your keys stay on your machine.
Fee1% of the trade, split between both sides.
MinimumAbout €5.
SoftwareRust, GPL-3.0, source on Radicle.
NetworkTor-native offer book; Ethereum mainnet escrow.

How a swap works

Two chains cannot be swapped by trusting a middleman, so moos does not use one. The Monero leg goes to a per-swap address that only the swap secret can spend; the Ethereum leg goes to a public escrow contract. One secret settles both sides, and if it is never revealed the timelocks let each side take its funds back.

  1. Get the client. Build it from source (below). The first run creates your identity on your machine — an Ethereum key and a Monero wallet. Nothing about it is sent to me.
  2. Pick an offer. The client lists offers with direction, rate, fee and limits. An offer is signed and self-contained: the exact amount you pay and receive is shown before you commit.
  3. Fund your side. XMR goes to the per-swap address; ETH goes to the escrow contract with enough left for gas. I fund my side of the same swap.
  4. Claim or refund. If I claim, the secret is revealed on-chain and your side unlocks. If I stall past the deadline, you refund yourself. Neither of us can move the other's funds in between.

The escrow is public and immutable: 0x377ed3a60007048DF00135637521170628De89E5 on Ethereum mainnet (Etherscan). Before it runs a swap the client checks that the bytecode at that address matches the build it was compiled with. The contract has no owner function: funds move only through a swap's own claim or refund.

Fees

Protocol fee1% of the trade, charged in XMR inside the lock transaction.
SplitHalf each side. The client shows your exact payout and fee before you confirm.
Minimum tradeAbout €5. The client also refuses any payout too small to pay for its own Monero sweep.
Gas and network feesPaid to the chains, not to me. A reverted Ethereum transaction still costs gas.
Accounts, deposits, withdrawalsNone — there is nothing to deposit and nothing to withdraw.

What can go wrong

Run it

Linux x86-64. You need Rust (rustup) and a C toolchain. The first run downloads the pinned Monero CLI once; the build itself is offline from vendored crates.

# install Radicle first: https://radicle.xyz
rad clone rad:z2SEZa9usoc7o2pMNNUGn2zjSjdrV moos
cd moos
./moos

./moos builds the client and its maker daemon, then opens the terminal UI. Mainnet is the default; --devnet starts a local test chain instead.

The source is on Radicle at rad:z2SEZa9usoc7o2pMNNUGn2zjSjdrV. Its delegate key is z6MkovoPb1igAceXq73EatP2KACC3MG727Rq2kecwScdYtx5; commits signed by that key are the code this page describes.

Why this exists

I run this because I wanted to swap these two coins without an exchange account. It is a small service on purpose: one maker, one machine, and a client you can read. The status page is generated from the daemon's own journals every ten minutes, so you can see what has actually been recorded rather than what a website claims.

Contact

SimpleX is the only direct channel: https://smp9.simplex.im/c#VItzf7jh401dMzrnaz3BuqOhCh1VCe-8d5bAkjLj_u0. I answer when I am at the machine. For protocol questions the source is better documentation than I am.