20 KiB
Executable File
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_infoprobe, 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. - Pilot identity/schema slice implemented: schema v10 additively records a separate identity binding
wikideck-randomx-pilot-1+ current pilot chain ID to Moneromainnet, with an immutableidentity-onlyactivation 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 durablecreatingstate and stop for operator reconciliation. No HTTP enrollment, observer, credit, withdrawal, or sale path is enabled. - Operator address command implemented:
monero:pilot-addressloads 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-seenevents. 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 newmonero:pilot-observecommand. 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 for the separate role and command boundary.
- Observer connection boundary advanced: the mTLS gateway now maps each client certificate fingerprint to explicit
observeroraddress-allocatormethod 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.
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
- Run observer → reviewed deposit → withdrawal on Stagenet using the real gateway/deployment where an endpoint is available; exercise recovery and ambiguous-send handling.
- 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.
- 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.
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.