Files
wikideck/docs/real-xmr-pilot-plan.md
T

129 lines
17 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
- **Step 1 browser smoke verified; acceptance remains partial.** 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 in the same browser origin. A hardened disposable Linux container, capped at one CPU core, one block, and five minutes, used its encrypted backup read-only and mined/accepted block 1 (article: Portlaoise railway station); the UI then showed height 1 and one confirmed wallet NFT. A second browser wallet was not created, and no external Monero daemon or funds path was tested. Therefore Step 1's planned two-wallet flow is not yet complete.
- **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.
- **Validation:** focused schema and observer PostgreSQL tests passed; full disposable PostgreSQL suite passed 46/46 and full serial offline suite passed 191/191. Tests cover assigned versus suspense outputs, replay, disappearance/reappearance evidence, exact large atomic amounts, zero financial posting, and observer role denials. No operator database or live node was accessed.
- **Step 1 remains incomplete only for the planned second browser wallet.** The external daemon is still not connected and there is no live-fund path. The stack remains private/mock-only and must not receive funds.
- **Validation history:** earlier pilot-only checks passed 10/10. An earlier full-suite attempt had a transient RandomX peer-gossip failure; the most recent serial offline suite subsequently exited 0.
- **Step 2 is in progress at review-preparation only.** Actual observer setup/scans against operator infrastructure, signed credit approval/staging/release, 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 now checks that evidence and emits an unsigned subject without posting. 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 and first wallet were exercised, and the first native RandomX proof-of-work test card was accepted by the isolated pilot chain. **Still required for this step:** create the second browser wallet and verify the two-wallet UI flow. The hosted daemon's intended network, synchronization and private RPC reachability remain unverified; do not start a duplicate daemon. A Stagenet rehearsal still requires a Stagenet daemon endpoint; an operator's 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.
- Support the pilot identity in the existing prepare/stage/release workflow. Keep approvals operator-driven rather than adding automation.
- Report capabilities truthfully as the flow becomes available; keep mock-credit controls unreachable in real-fund mode.
**Result:** a real Stagenet deposit is observed and approved into the buyer's available balance through the running application, using a Stagenet daemon endpoint. For the eventual real-XMR run, use the operator-hosted Monero Mainnet node only after network and synchronization checks pass. This is private development progress, not a reason to solicit real deposits before cash-out works.
### 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.
- Add browser withdrawal inputs, status and receipt. A CLI command can process the queue; no automatic payout scheduler is needed.
**Result:** deposit → signed withdrawal → operator send → XMR received, with correct balances and fees.
### 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 complete deployed flow, then test real XMR
1. Run deposit → purchase → seller withdrawal on Stagenet using the actual browsers and deployment.
2. Include focused implementation checks for duplicate requests, restart after preparation/relay, cancellation versus send and canonical sale disconnect. These protect the flow from duplicate money/asset movement; they are not a separate certification program.
3. With explicit wallet/network/amount approval, configure Monero mainnet and repeat with operator-controlled accounts and a small amount sufficient for fees.
**Result:** a functional private real-XMR market with repeatable startup and operator commands. Public launch is outside this increment.
## Parallel work
| Workstream | Start | Delivers |
| --- | --- | --- |
| Pilot identity + deployment | First | Running stack and unblocked integration |
| Deposit UI + reviewed credit | After identity/setup | Funded buyer balance |
| Treasury tool + withdrawal UI | Alongside deposits | Actual cash-out |
| Sale-lock activation + custody settlement | After identity is defined, alongside payment work | Paid NFT delivery and seller earnings |
| Browser end-to-end flow | As slices connect | Deployable functional pilot |
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 an operator-only pilot credit-review preparation path that consumes these pilot-bound assigned observations, validates confirmation/unlock/double-spend and freshness, and produces a review subject without posting a journal.** Keep unallocated outputs in suspense; do not add automatic credit, customer HTTP enrollment, or withdrawal activation. Continue after this with the separate pending-credit posting/release roles and reorg hold resolution, still gated until cash-out and recovery work is ready.