Cash out USDC to naira. Escrow first.

MELO is off-ramp infrastructure for USDC to NGN bank payouts. Funds sit in an onchain escrow on Arc and are released only after the payout is verified. Otherwise, they're refunded.

In development on Arc testnet. Not production-ready.

Five states between a wallet and a bank account.

Each step has one source of truth. The chain holds the money, the provider moves the naira, and the attestation connects the two.

Quote

Provider quotes are normalised into net naira, fees and an expiry. A quote is a price, not a reservation of liquidity.

State
QUOTE_AVAILABLE
Source of truth
MELO router

Built around four rules.

  • No release without verified payment.

    A row in MELO's database can't release escrow. Only a valid, unexpired attestation can.

  • Release or refund. Never both.

    Settlement and refund are mutually exclusive in the contract and race-tested in the suite.

  • Every payout is idempotent.

    Retries look up the provider reference first. Ambiguous outcomes go to reconciliation, never a blind retry.

  • Amounts are integers.

    Base units with explicit decimals from API to contract. No floating-point money anywhere.

Settles on Arc.

USDC is the gas token and finality is deterministic, so an escrow deposit is final after one confirmation and there's no second token to hold for fees.

Source: Arc on/off-ramp docs
Network
Arc
Chain ID
5042
Gas token
USDC
Finality
Deterministic, under 1s
USDC contract
0x3600…0000

An API shaped like the lifecycle.

Quotes, escrow, payouts and settlement are separate objects with their own states. Amounts travel as strings in base units, and every write takes an idempotency key.

  • POST /v1/intents
  • POST /v1/intents/{id}/quotes
  • POST /v1/intents/{id}/authorization
  • GET /v1/intents/{id}
  • GET /v1/intents/{id}/receipt

Draft contract. These endpoints aren't live yet.

POST /v1/intents
Idempotency-Key: 5b1e0c2a-intent-001
Content-Type: application/json

{
  "input": {
    "asset": "USDC",
    "chain": "arc-testnet",
    "amount": "100000000"
  },
  "payout": {
    "currency": "NGN",
    "bank_code": "058",
    "account_number": "0123454821"
  }
}

Illustrative draft of the intent contract. Not a live endpoint.

Try the flow on testnet.