# Get the real-XMR market running Updated: 2026-10-22. Implementation plan for a private, operator-supervised functional pilot—not a public production release. Wallet access and fund movement require separate explicit approval. ## Progress checkpoint — 2026-10-22 - **Pilot smoke evidence recorded; two-wallet UI check deferred.** The isolated Compose stack started with healthy PostgreSQL/app and completed migration; the browser showed `PRIVATE PILOT`, `RPC available`, `wikideck-randomx-pilot-1`, and mock-only/no-real-XMR status. One encrypted local pilot wallet was created and unlocked. A disposable Linux container capped at one CPU core, one block, and five minutes used the encrypted backup read-only and mined/accepted block 1 (article: Portlaoise railway station); the UI showed height 1 and one wallet NFT. A second browser wallet and external Monero daemon have not been exercised. The second-wallet demonstration is no longer a prerequisite for funds-enabling work. - **Operator infrastructure update:** a Monero full node is hosted on the operator's network and is intended to be reused; the pilot does not need to deploy or synchronize another daemon. Its network mode, RPC reachability from the pilot host/container, authentication/transport boundary and sync health still need verification. This does not provide Wallet-RPC, deposit observation, address allocation or a spending wallet. - **Next integration slice implemented:** added an operator-triggered, read-only `monerod get_info` probe, opt-in Compose check service, and mocked regression coverage. The Linux test image builds and focused probe/deployment tests pass (6/6). The probe validates expected Mainnet/Stagenet identity and synchronization, but has not been run against the operator's node because its private endpoint/configuration has not been provided. It does not enable wallet access, addresses, deposits, or credits. See [the probe setup and security boundary](real-xmr-pilot-deployment.md). - **Pilot identity/schema slice implemented:** schema v10 additively records a separate identity binding `wikideck-randomx-pilot-1` + current pilot chain ID to Monero `mainnet`, with an immutable `identity-only` activation status. Schema v11 adds separate immutable pilot reservation rows. Explicit pilot-only migration, identity, and reservation-role CLI actions require exact acknowledgements, reject non-pilot profiles, and refuse reused financial databases. - **Durable pilot allocation implemented:** a signed pilot request now reserves the next never-reused index transactionally, serializes concurrent allocators, replays idempotently, and rejects request/beneficiary conflicts. PostgreSQL enforces the reservation's custodian, market-chain, and Monero-network binding with a composite foreign key to the immutable pilot identity. A dedicated role can read schema digests and pilot identity, execute the isolation check, and read/insert reservations only; it cannot read balances, register addresses, or access observation, credit, or withdrawal tables. This code does not call Wallet-RPC, return a Monero address, or connect to HTTP. - **Wallet-RPC address create/recover implemented:** the operator/library-only function verifies the configured wallet fingerprint, checks the reserved index and stable allocation label, persists a create intent before `create_address`, then reads back and validates the exact Mainnet subaddress before registering it once. Lost responses recover by the stable label without repeating creation; ambiguous missing responses remain in a durable `creating` state and stop for operator reconciliation. No HTTP enrollment, observer, credit, withdrawal, or sale path is enabled. - **Operator address command implemented:** `monero:pilot-address` loads an owner-only signed request file, requires the pilot profile plus exact operator-action acknowledgement, checks the configured custodian and watch-only wallet generation/fingerprint/account, loads the protected Wallet-RPC and mTLS configs, verifies the wallet fingerprint, and invokes the durable create/recover library. It returns the address to that one-shot operator caller only; it is not wired into server startup, HTTP, or the browser. - **Pilot observation persistence implemented:** schema v14 stores pilot-only wallet cursors, scan records, assigned/unallocated outputs, and append-only `seen`/`changed`/`reappeared`/`not-seen` events. The separate observer role matches outputs only to a registered reservation with the same wallet generation, fingerprint, account/index, and address; unknown outputs remain suspense. A one-shot bounded scanner resumes with overlap through the new `monero:pilot-observe` command. This is observation-only: no journal, credit, HTTP route, or background service is enabled. - **Pilot deposit review preparation implemented:** an operator-only CLI action reads persisted pilot observations through a dedicated read-only PostgreSQL role and emits a pilot/Mainnet/custodian/allocation-bound review subject. It checks exact reservation and wallet binding, amount range, confirmations, unlock time, freshness, scan context, current presence, double-spend flag, and bounded append-only event history; changed/disappeared/reappeared evidence fails closed. The action is preparation-only: no signature approval, journal, pending/available balance, credit event, HTTP enrollment, or startup worker is involved. See [the deployment guide](real-xmr-pilot-deployment.md) for the separate role and command boundary. - **Observer connection boundary advanced:** the mTLS gateway now maps each client certificate fingerprint to explicit `observer` or `address-allocator` method roles. Observer credentials cannot create addresses; allocator credentials cannot scan transfers; neither role can call transfer, relay, or sweep methods. Compose now defines an opt-in, no-port, one-shot pilot observer using separate external database and mTLS file mounts, read-only and on a distinct egress network. It is not included in ordinary startup and has not connected to the hosted node; required private endpoint, gateway, wallet and database configuration are not available in the workspace. - **Validation:** targeted pilot review-preparation PostgreSQL coverage passed; the latest disposable PostgreSQL run passed 47/47 and the latest serial offline run passed 193/193. These are baseline evidence, not a request to keep rerunning broad suites. No operator database or live node was accessed. - **Funds readiness remains blocked.** The hosted daemon is not connected; no pilot observation scan, real credit, live withdrawal send, or recovery exercise has occurred. The stack remains private/mock-only and must not receive funds. - **Step 2 is in progress at review-preparation and dormant observer wiring.** Pilot-bound assigned-output review preparation and the one-shot deployment boundary exist, but there has been no connection to operator infrastructure or observation scan. Signed pilot credit staging/release, pilot-bound withdrawal execution/recovery, and sale settlement remain unavailable. Existing deposit/withdrawal APIs still require the separately gated mainnet profile; sale-lock transactions remain candidate-only and are not accepted by active consensus. ## Finish line Two browser wallets complete this flow on one deployed stack: **Buyer deposits XMR → available balance → fixed-price purchase → card ownership changes → seller receives proceeds → seller withdraws XMR.** Use the existing pooled-custody architecture, PostgreSQL accounting, native Monero integration and UI. Do not restart architecture research, introduce another payment provider or build a general-purpose payment platform. ## Reuse what exists - Exact atomic-XMR prices and fee calculations. - PostgreSQL schema v14, including pilot identity, reservations, persisted observation, and append-only reorg evidence. - Signed deposit enrollment, observation worker and reviewed credit/release commands. - Signed balance reads and withdrawal reservation/cancellation APIs. - Marketplace/custody UI and executable sale-lock/accounting models. The missing work is integration plus two substantial features: **actual withdrawal execution and activated NFT sale settlement**. Current market commands remain sandbox-only; reserved withdrawals never send XMR; active consensus rejects sale-lock transactions. ## Smallest useful scope One Linux host, one authoritative market writer, one treasury tool/worker, fixed-price sales and operator-controlled accounts initially. Manual signed deposit approvals and operator-triggered sends are sufficient. Reuse existing UI components; no admin dashboard, unattended treasury or auction system is needed. ## Implementation sequence ### 1. Make one pilot stack runnable - Add an explicitly identified private pilot profile for the sale protocol, distinct from existing v6 and the final mainnet candidate. - Bind signed market/payment requests to the pilot chain and custodian; select the Monero network explicitly. Real XMR requires Monero mainnet, not a public Wikideck launch. - Give the pilot its own explicit genesis/startup configuration rather than inheriting the candidate's January 1, 2027 delay and public-peer requirements. Leave existing mainnet protections unchanged; do not fake review acknowledgements or alter v6 in place. - Add one pilot deployment definition using existing Docker patterns: app, PostgreSQL, observer and private Wallet-RPC gateway. Reuse the operator-hosted full node over a verified private network connection; do not add a duplicate daemon service. Connect the observer/watch-only wallet and separate spending wallet explicitly. Keep daemon and Wallet-RPC endpoints private, authenticated and unavailable from the public Internet; supply credentials through protected files/secrets, not checked-in Compose values. - Include schema initialization, role grants and required configuration in a short setup procedure. Keep spending keys outside the web app and Wallet RPC off the public Internet. **Progress:** A separate mock-only pilot network/profile, launch opt-in, profile-isolated local storage, PostgreSQL deployment, and opt-in read-only daemon probe now exist. The probe awaits the operator's protected endpoint config. Additive schema v14 binds the pilot chain to Monero Mainnet, durably reserves signed beneficiary-bound address indexes, and stores pilot-only observation/reorg evidence in a dedicated database. A separate read-only CLI review preparer checks that evidence and emits an unsigned subject without posting. A role-separated mTLS gateway policy and opt-in one-shot Compose observer are wired, but no operator Wallet-RPC address, daemon observation, credit, or real-fund operation has been run. See [pilot deployment status and startup](real-xmr-pilot-deployment.md). **Observed so far:** the private stack/browser health, first wallet, and one native RandomX proof-of-work test card were exercised. **Deferred:** the second-wallet browser demonstration; it is useful UI evidence but not on the funds-enabling critical path. The hosted daemon's intended network, synchronization and private RPC reachability remain unverified; reuse it rather than starting a duplicate. A Stagenet rehearsal requires a Stagenet endpoint; the hosted Mainnet daemon cannot substitute for it. ### 2. Connect deposits to spendable balances - Add a deposit panel that signs the existing enrollment request and displays the allocated address. - Run the observer against the configured watch-only wallet and operator-hosted daemon; show pending and available balances. Explicitly bind the Monero network and refuse a daemon/wallet network mismatch or stale/unsynchronized RPC state. - Extend the pilot-specific review subject into explicit operator-signed pending-credit and release/reorg-hold operations. Keep approvals manual; do not inherit or expose mainnet-only APIs through the browser by default. - Report capabilities truthfully as the flow becomes available; keep mock-credit controls unreachable in real-fund mode. **Result:** the operator can observe and reconcile a deposit, then explicitly approve its pending and available-balance transitions. Do not expose addresses or accept funds until Step 3 withdrawal and recovery gates are met. Use Stagenet first if a rehearsal endpoint is available; the eventual real-XMR run must use the operator-hosted Mainnet node only after its network, sync, and private transport are verified. ### 3. Finish withdrawals with an operator tool - Extend signed reservations with durable preparation, prepared-transaction, relay and confirmation states, including an uncertain/review outcome. - Claim a request exclusively and block cancellation once preparation begins. - Construct/sign using the separate treasury wallet, enforcing destination, amount and maximum fee. - Record preparation intent before wallet side effects and retain the recoverable signed transaction identity/blob before relay. Reconcile ambiguous preparation before trying again. - Relay and track the stored transaction. Retries reuse that transaction rather than creating another payment. - Settle the reserved liability with the actual fee and return unused fee allowance; keep uncertain sends reserved. - Implement and rehearse backup/restore and restart recovery for the database, watch-only observer state, and separately controlled treasury wallet. Reconcile ambiguous sends before retrying; never treat a backup file as proof that funds can be restored. - Add browser withdrawal inputs, status and receipt. A CLI command can process the queue; no automatic payout scheduler is needed. **Hard gate before accepting deposits:** a bounded Stagenet withdrawal, restart/recovery, and ambiguous-send reconciliation succeed through the actual operator path. Only then consider enabling a tightly capped private Mainnet deposit pilot with explicit operator approval. **Result:** deposit → signed withdrawal → operator send → XMR received, with correct balances, fees, and recoverable state. ### 4. Connect purchases to NFT delivery and seller earnings Start this alongside steps 2–3 after defining the pilot identity. Do not wait for a separate release-hardening phase. - Integrate the existing lock/completion/cancellation/expiry model into pilot transaction validation, state commitments, mempool, canonical indexes/events, peer processing and restart replay. Use the existing RandomX ledger, not a toy substitute. - Adapt custody listing/purchase commands for real balances and fresh signatures. Atomically reserve buyer funds with the order; exclude mock funding/payment authorizations. - Collect seller/buyer lock consent, submit the lock and have the host attest completion only against the funded reservation. - Feed actual canonical outcomes into PostgreSQL settlement instead of synthetic rehearsal witnesses. - Credit seller, author and host once after configured confirmation depth; release buyer funds only after safe cancellation/expiry/non-admission evidence. Hold conflicting reorg outcomes rather than paying/refunding again. - Allow withdrawal of legitimate sale and fee earnings. The current own-deposit backing limit prevents a seller who never deposited from cashing out. Replace it with pooled-backing accounting covering liabilities, pending sends and fees—not merely removal of the check. - Apply existing accounting checks and incident holds to the connected sale and treasury writers. - Adapt the existing marketplace UI to show funded checkout, lock/completion progress, delivered ownership and proceeds. **Result:** seller lists → buyer buys → card changes owner → exact seller/fee balances appear → seller withdraws, even without a prior seller deposit. ### 5. Exercise the money path narrowly, then consider real XMR 1. Run observer → reviewed deposit → withdrawal on Stagenet using the real gateway/deployment where an endpoint is available; exercise recovery and ambiguous-send handling. 2. Validate only the money-moving failure cases that could duplicate, lose, or misdirect funds (idempotency, restart/recovery, cancel/send race, and reorg holds). Do not make broad suite reruns, second-wallet UI coverage, benchmarks, or certification the critical path. 3. After the withdrawal/recovery gate and explicit operator approval, configure Monero Mainnet and start with tightly capped operator-controlled amounts. Keep incoming funds disabled until those prerequisites are satisfied. **Result:** a functional private real-XMR market with repeatable startup and operator commands. Public launch is outside this increment. ## Parallel work | Workstream | Start | Delivers | | --- | --- | --- | | Hosted-node verification + private gateway/watch-only setup | Next operational dependency | Verified Mainnet/Stagenet reachability and observation boundary; no duplicate daemon | | Pilot observation + operator-reviewed credit path | After identity/setup | Persisted evidence and controlled pending/available transitions; remain disabled until cash-out gate | | Treasury withdrawal + recovery | Implement alongside observer work; gate before inbound funds | Actual cash-out, uncertain-send reconciliation, restorable state | | Sale-lock activation + custody settlement | After identity is defined, alongside payment work | Paid NFT delivery and seller earnings | | Focused deployed money-path exercise | Once slices connect | Evidence against loss/duplication/misdirection; not a broad certification phase | Build each slice with its actual callers. Do not spend another increment adding a disconnected model or endpoint. ## Move out of the functional critical path Track these separately as public-release/hardening follow-ups, rather than front-loading them as engineering phases: - Broad audit/certification and release evidence packets. - Production-scale benchmarks, SLOs, HA, multi-host operations and additional orchestrators. - SBOM/provenance automation, comprehensive scanning programs and artifact signing. - Automated certificate rotation, backup scheduling, off-site recovery certification and full on-call systems. - Automatic credit approval, unattended signing, batching and admin dashboards. - Auctions, fiat conversion, alternate processors and final public-mainnet launch preparation. Keep the functional essentials: signed authorization, correct network binding, private wallet access, exact balanced accounting, one-time settlement and recoverable sends. Deferring broader hardening does not make this production-ready; public/customer-fund rollout still needs the separate policy/legal/security decisions in [the production plan](production-plan.md). ## Next coding task **Next: add a pilot-bound durable withdrawal lifecycle and operator-only no-send preparation review.** Existing mainnet withdrawal intents are bound to a different identity; sandbox `prepared` rows are fixture-only, so neither can be reused as the pilot treasury workflow. Start with a pilot-specific schema/role and a read-only manifest of the exact beneficiary, destination, amount, fee cap, reservation, backing and identity. Then add an exclusive signer handoff, recoverable prepared transaction identity, relay/reconciliation states and a separately controlled treasury boundary. Keep live sends and all real deposits disabled until Stagenet recovery and uncertain-send behavior are operationally demonstrated. The observer is now wired as an opt-in one-shot service; actual connection awaits the operator's protected endpoint/gateway/database configuration. In parallel, add manual pilot pending-credit/release and reorg-hold operations. Defer the second-wallet demo and broad test/certification work; use focused checks for idempotency, cancel/send races, restart recovery, role boundaries and reorgs.