A production-ready, censorship-resistant, non-custodial Lightning Network peer-to-peer exchange built on Nostr

Mostro is a production-ready Lightning Network peer-to-peer exchange that enables Bitcoin trading without custodial risk or KYC requirements. Built on the censorship-resistant Nostr protocol, Mostro provides a decentralized alternative to centralized exchanges and custodial platforms.
The need for KYC-free Bitcoin trading has never been greater. @lnp2pBot, a Telegram-based P2P exchange, has demonstrated strong global demand—particularly in regions facing monetary instability like Latin America, Cuba, and Venezuela, where citizens resist tyranny by adopting Bitcoin over broken fiat currencies.
While @lnp2pBot works excellently, it relies on Telegram—a platform potentially vulnerable to government pressure. Nostr solves this: as a decentralized protocol with no single point of failure, it provides the censorship-resistant foundation needed for a truly unstoppable peer-to-peer exchange.
Mostro brings this vision to life. It's not just a proof of concept—it's a fully operational daemon powering real trades today, with robust features including dispute resolution, reputation systems, development fee transparency, and admin tooling.
tracing, configurable log levelsMostro uses a small set of Nostr event kinds. Some are part of the public protocol, and some are transport-only details that live inside NIP-59 GiftWrap envelopes.
| Kind | Name / Constant | Used for | Notes |
|---|---|---|---|
0 |
Metadata |
Mostro profile metadata | Standard Nostr profile event published at startup when metadata is configured. |
1 |
TextNote |
Inner rumor in NIP-59 | Transport-only. Mostro creates and reads it inside GiftWrap; it is not published as a standalone public event. |
13 |
Seal |
Inner sealed envelope in NIP-59 | Transport-only. Mostro creates and reads it inside GiftWrap; it is not published as a standalone public event. |
1059 |
GiftWrap |
NIP-59 outer envelope | This is the relay-visible event kind that Mostro subscribes to and publishes for wrapped messages. |
10002 |
RelayList |
Relay metadata | Standard Nostr relay list event published periodically by the scheduler. |
8383 |
DEV_FEE_AUDIT_EVENT_KIND |
Dev fee audit event | Public audit event used for transparent fee accounting. |
30078 |
NOSTR_EXCHANGE_RATES_EVENT_KIND |
Exchange rates | NIP-33 replaceable event for BTC/fiat rate publishing. |
38383 |
NOSTR_ORDER_EVENT_KIND |
Orders | NIP-33 replaceable event for order publications. |
38384 |
NOSTR_RATING_EVENT_KIND |
Ratings | NIP-33 replaceable event for reputation snapshots. |
38385 |
NOSTR_INFO_EVENT_KIND |
Mostro info | NIP-33 replaceable event for operator / node metadata. |
38386 |
NOSTR_DISPUTE_EVENT_KIND |
Disputes | NIP-33 replaceable event for dispute publications. |
Note:
kind 1andkind 13are inside thekind 1059GiftWrap transport. They are created and verified by the wrapping/unwrapping code, but they are not emitted or consumed as standalone public relay events by the daemon.
Mostro acts as a non-custodial escrow coordinator between buyers and sellers using the Lightning Network. The daemon handles three primary flows: order lifecycle, dispute resolution, and fee distribution.
sequenceDiagram
autonumber
participant S as Seller
participant M as Mostro
participant LN as Lightning Node
participant B as Buyer
Note over S,B: 1. ORDER CREATION
S->>M: Create sell order (100k sats @ market)
M->>M: Calculate fees (1% = 1k sats total)
M-->>S: Order published (pending)
Note over S,B: 2. ORDER ACCEPTANCE
B->>M: Take order
M->>M: Reserve order for buyer
M-->>S: Buyer found, prepare hold invoice
M-->>B: Order reserved, wait for seller
Note over S,B: 3. ESCROW SETUP
M->>LN: Create hold invoice (100,500 sats)
LN-->>M: Hold invoice + preimage
M->>S: Pay this hold invoice
S->>LN: Payment (holds funds)
LN-->>M: Payment received (held)
M-->>S: Escrowed! Wait for buyer invoice
M-->>B: Seller paid, send your invoice
Note over S,B: 4. BUYER INVOICE & FIAT TRANSFER
B->>M: Here's my invoice (99,500 sats)
M-->>S: Buyer ready, send fiat via [payment method]
S->>B: [Off-chain fiat transfer]
B->>M: Fiat sent
M-->>S: Buyer claims fiat sent
Note over S,B: 5. RELEASE
S->>M: Fiat received, release!
M->>LN: Settle hold invoice (preimage)
LN-->>M: Released (1,000 sats fee to Mostro)
M->>LN: Pay buyer invoice (99,500 sats)
LN-->>B: Payment received
M-->>S: Trade complete ✓
M-->>B: Trade complete ✓
Note over S,B: 6. POST-TRADE
M->>M: Update reputations
M->>M: Schedule dev fee payment (300 sats)
M->>LN: Pay dev fee to fund
M->>M: Publish audit event (kind 8383)
Key Points: - Non-Custodial: Lightning hold invoices ensure Mostro never controls funds - Trustless: Preimage released only when seller confirms fiat receipt - Fee Structure: Seller pays 500 sats, buyer pays 500 sats (split from 1% of 100k) - Dev Sustainability: Mostro pays 30% of its fee (300 sats) to development fund
For more detailed protocol specifications, see the official protocol documentation.
When disputes occur, Mostro's arbiter system ensures fair resolution:
sequenceDiagram
autonumber
participant U as User (Buyer/Seller)
participant M as Mostro
participant A as Admin/Arbiter
participant LN as Lightning Node
U->>M: Open dispute (order stuck)
M->>M: Mark order as "Dispute"
M->>M: Record initiator (buyer/seller)
M-->>U: Dispute created, awaiting arbiter
M-->>A: New dispute notification
A->>M: Take dispute (via RPC or Nostr)
M->>M: Assign arbiter to case
M-->>U: Arbiter assigned
Note over U,A: Investigation & Communication
A->>U: Request evidence/information
U->>A: Provide proof of payment/issue
Note over A,LN: Resolution Decision
alt Settle to seller
A->>M: Settle order (seller wins)
M->>LN: Settle hold invoice
LN-->>M: Released to seller
M-->>U: Dispute resolved (seller)
else Cancel/Refund to buyer
A->>M: Cancel order (buyer wins)
M->>LN: Cancel hold invoice
LN-->>M: Refunded to buyer
M-->>U: Dispute resolved (buyer)
end
M->>M: Log resolution for audit
M-->>U: Case closed
Dispute Tracking (v0.15.6): Each dispute includes initiator identification (buyer or seller), arbiter assignment, resolution status, and audit trail in the database.
Operators can require an opt-in anti-abuse bond — a second Lightning
hold invoice, separate from the trade escrow — to discourage no-shows and
griefing. It is off by default; nodes that leave
[anti_abuse_bond].enabled = false behave exactly as before. Full design:
docs/ANTI_ABUSE_BOND.md.
The feature deliberately keeps two axes separate:
apply_to
setting (take | make | both) selects which side(s) post one.slash_seller / slash_buyer. The order kind maps
these to the right bond row (sell → maker is seller; buy → maker is
buyer).Lifecycle:
Action::PayBondInvoice; once the HTLC is held, the bond is Locked
and the trade proceeds.Released — nothing is captured.BondResolution payload on admin-settle / admin-cancel, or a
waiting-state timeout elapses (when slash_on_waiting_timeout = true).
The bond HTLC is settled into Mostro's wallet, then split per
slash_node_share_pct: the node keeps its share (funds solver
compensation) and the winning counterparty is paid the rest
asynchronously after submitting a payout invoice.Nodes advertise their bond policy in the kind-38385 info event
(bond_enabled, bond_apply_to, bond_amount_pct, …) so clients can
warn users before they trade.
Mostro implements a transparent development sustainability model:
sequenceDiagram
autonumber
participant M as Mostro Daemon
participant DB as Database
participant LN as Lightning Node
participant Fund as Dev Fund (Lightning Address)
participant Nostr as Nostr Relays
Note over M,Nostr: After Successful Trade
M->>M: Order completed (status: settled-hold-invoice)
M->>M: Mostro collected 1,000 sats fee
M->>DB: Mark dev_fee=300, dev_fee_paid=0
Note over M,Nostr: Scheduler (every 60s)
M->>DB: Query unpaid dev fees
DB-->>M: Order #123: 300 sats unpaid
M->>LN: Resolve Lightning address (LNURL)
LN-->>M: Payment request
M->>LN: Send payment (300 sats)
LN-->>Fund: Payment delivered
LN-->>M: Payment hash: abc123...
M->>DB: UPDATE dev_fee_paid=1, hash=abc123...
M->>Nostr: Publish audit event (kind 8383)
Note over Nostr: Transparent, queryable by anyone
Nostr-->>M: Event published
Note over M,Nostr: Result
M->>M: Mostro keeps 700 sats (70%)
Fund->>Fund: Dev fund receives 300 sats (30%)
Transparency Features:
- Configurable: Node operators set dev_fee_percentage (min 10%, max 100%, default 30%)
- Non-Blocking: Failed payments don't prevent order completion; retries automatic
- Auditable: All dev fee payments published to Nostr (kind 8383 events)
- Operator Contribution: Mostro daemon pays from its earnings, not charged to users
Query all dev fee payments on Nostr:
# Requires nostreq and nostcat tools
nostreq --kinds 8383 --tag y=mostro --tag z=dev-fee-payment | nostcat --stream wss://relay.damus.io
Mostro is a Rust-based daemon with a modular architecture:
```mermaid flowchart TB subgraph "External Systems" Nostr[Nostr Relays
NIP-59 GiftWrap] LND[LND Node
Hold Invoices] API[Price API
Yadio] end
subgraph "Mostro Daemon (mostrod)"
Main[main.rs
Entry Point]
subgraph "Core Modules"
$ claude mcp add mostro \
-- python -m otcore.mcp_server <graph>