xmrswap
connecting…

Monero in. USDC out.

Deposit XMR to a one-time address; receive USDC on Solana, Ethereum, or Polygon after 1 confirmation (~2 min).

Receive USDC on
Rate
Service fee
Minimum deposit

API

Base URL http://127.0.0.1:4100 · JSON in, JSON out · no auth on public endpoints · swap creation is rate-limited to 20/hour per IP.

POST/api/swaps

Create a swap. Returns a one-time Monero deposit subaddress and an indicative quote. Anything sent to that address (≥ the minimum, dust ignored) is swapped after 1 confirmation.

Request body

fieldtypedescription
to_chain"sol" | "eth" | "polygon"Chain to receive USDC on
to_addressstringDestination address: base58 for Solana, 0x-hex for EVM chains

Example

curl -X POST http://127.0.0.1:4100/api/swaps \
  -H 'Content-Type: application/json' \
  -d '{"to_chain":"sol","to_address":"Apewggxx…XbLp"}'

{
  "id": "984bcdce-4416-444b-bd28-28e8fd6d5af4",
  "status": "awaiting_deposit",
  "deposit_address": "88GHU2vA…5VA",
  "min_confirmations": 1,
  "min_deposit_xmr": 0.01,
  "expires_at": 1784655383973,
  "quote": { "usdc_per_xmr": 337.34, "source": "jupiter", "service_fee_bps": 100, "note": "float rate…" },
  "depeg_warning": false
}

Errors

statusmeaning
400to_chain not one of sol/eth/polygon, or the address fails validation for that chain
429rate limited (20 creations/hour per IP)
GET/api/swaps/:id

Swap status. Poll this (the UI polls every 5 s). Amounts are decimal strings; XMR has 12 decimals, USDC 6.

Response fields

fielddescription
statussee lifecycle below
deposit_addressthe one-time XMR subaddress for this swap
deposited_xmrconfirmed XMR credited to the swap
unconfirmed_xmrXMR seen in the mempool, not yet 1-conf
delivered_usdcnet USDC sent, once completed
delivery_refSolana tx signature, or the Mayan order signature for eth/polygon (track at explorer.mayan.finance/swap/<sig>)
expires_atepoch ms; deposits after expiry are held for manual review, never lost
GET/api/swaps/:id/qr

The deposit address as a QR code (SVG, monero: URI). Suitable for direct use in an <img>.

GET/api/quote

Current indicative rate and limits. The executable rate comes from Jupiter (selling wXMR→USDC on Solana: real liquidity, not an oracle); CoinGecko XMR/USD is returned as a reference. depeg_warning is set when they diverge >5%.

Example

curl http://127.0.0.1:4100/api/quote

{
  "usdc_per_xmr": 337.34,
  "xmr_usd_reference": 336.5,
  "source": "jupiter",
  "depeg_warning": false,
  "service_fee_bps": 100,
  "min_deposit_xmr": 0.01,
  "min_confirmations": 1,
  "chains": ["sol", "eth", "polygon"]
}
GET/api/health

Service health: Monero wallet and daemon heights, sync state, and whether execution is dry-run or live. Returns 503 when the wallet RPC is unreachable.

GET/api/admin/overviewBearer auth

Operator view: all swaps, the manual-review queue, rebalance plan and history, and Solana reserve balances. Requires Authorization: Bearer <ADMIN_TOKEN>.

Swap lifecycle
awaiting_depositsubaddress issued, nothing received yet
deposit_unconfirmeddeposit seen in the mempool
deposit_confirmed1 confirmation reached, queued for execution
executingselling wXMR reserves → USDC at the live rate
deliveringUSDC payout in flight (SPL transfer or Mayan order)
completeddone; delivered_usdc and delivery_ref are final
expiredno deposit within 24 h; late deposits are held for review
under_reviewparked for a human (late/extra deposit, price moved >3% against the quote, or an execution error); funds are never silently dropped