OpenBazaar died of availability. A store existed while its owner’s laptop was open. LocalMonero died of having an address. It ran servers, and servers have operators, jurisdictions, and an off switch.
Those are the two ways a peer-to-peer market fails, and they pull in opposite directions. Put the market on a server and someone can close it. Take the server away and someone has to keep the market running. Agora Bazaar is an attempt to hold both on the Logos stack, for ordinary trade: digital goods, services sold by AI agents, and swaps between currencies.
Permission is the product
Every marketplace most people use sells permission before it sells anything else. The platform decides who may list, what is allowed, which payment methods work, and when an account stops existing. The payment processor behind it makes the same decisions one layer down. None of this requires bad intent. It only requires an operator, and an operator is a single place where pressure lands, whether that pressure is a regulator, a lawsuit, a bank, or a quiet policy change.
Censorship resistance, stated plainly, means there is no such place. Nobody approves a listing, because there is no listing server. Nobody freezes a trade, because the funds are meant to sit under a contract rather than in a company’s account. A seller exists as long as the seller’s node does.
The record is the risk
A market also produces a record: who bought what, from whom, for how much, and when. On a platform that record belongs to the operator. On a public chain it belongs to everyone, permanently. Neither is a good home for the purchase history of a person who has done nothing wrong.
Haveno shows how narrow the margin is. Its trade protocol is mature: a maker, a taker, and an arbitrator holding the third key of a 2-of-3 Monero multisig, all over Tor. My research notes cite a 2025 paper showing that Haveno-related Monero transactions can be picked out by their multisig patterns on chain. The protocol held. The settlement layer leaked. Privacy in a market is set by its weakest layer, and every layer counts: the chain, the messages, and the timing between them.
Messages inform, the chain decides
A market without an operator still needs someone to be right when two parties disagree. A trade has three sources of state: the chain, each side’s local software, and the messages arriving from the other side. Bazaar fixes the order. The escrow contract is the truth about funds. The local state machine is the truth about where the trade stands. Messages from the peer are notifications.
Before every transition, the local machine checks escrow state and follows the chain. A peer that reconnects claiming to be further along doesn’t get believed; the node asks the chain again. A forged “payment received” message can’t move funds, because funds never move on messages. That ordering is the design decision I would keep if everything else changed. It is what lets strangers trade without a referee who owns the room.
Presence costs something
Removing the server moves its job to the participants. A listing is only findable while someone serves it, and a seller is only reachable while their node is up. OpenBazaar learned this the expensive way. Bazaar’s answer is to make the market a set of background services, packaged as NixOS modules with a health-check timer, and to keep search local, so a buyer’s node indexes the offers it has seen instead of querying a central index. Whether that keeps a store reachable across machines, NATs, and restarts is the open half of the problem.
The experiment
Bazaar keeps Haveno’s trade flow and replaces the layers beneath it. A Python Trade Manager runs a 13-state trade machine. Offers, trade events, and disputes travel over three Waku content topics, and every message carries a timestamp and a random nonce so replays get dropped. Received offers go into a local SQLite full-text index. Each trade gets its own Monero subaddress, and the payment broadcast waits a random 30 to 300 seconds so the Waku message and the chain transaction don’t line up in time. Lightning goes through LND. Escrow, identity, and reputation are three Rust crates aimed at the Logos Execution Zone (LEZ). The interface is a Logos Basecamp module in QML that holds no keys. The repo has 127 tests.
Some of this ran against real systems. A 0.005 XMR payment moved between two stagenet wallets and verified with check_tx_key. The LEZ client reads the testnet sequencer. Two Trade Manager instances sharing one nwaku relay took a trade from listing to completion, each driving its own Basecamp. That demo proves discovery and messaging. It skips escrow, because escrow isn’t on chain yet: the LEZ escrow calls are stubs, after the multisig program failed to build on an upstream version mismatch. The Rust crates are tested models, not LEZ programs. Signature checks are placeholders, and the trade channel carries plaintext JSON.
What remains
Escrow is the project. Without it a market is a messaging layer with a checkout button, and the chain-first ordering above checks against an empty record.
The trade channel needs encryption before the privacy measures mean much. A randomized delay and a fresh subaddress protect timing and addresses. Plaintext on a shared topic gives both away to anyone reading it.
Arbiters have to come from somewhere. The plan moves from a hardcoded arbiter to one both parties nominate to a staked pool with random selection, and each step changes the trust model. Only the first exists today, and it is a string.
Offers already move between nodes without anyone’s permission. Funds don’t yet move under a contract. That’s the gap.