Files
wikideck/docs/real-xmr-pilot-plan.md
T
2026-10-22 16:11:36 -04:00

125 lines
14 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 started; mock-only foundation implemented.** Added a distinct `pilot` profile with its own network/genesis identity, explicit private-mock-only startup opt-in, separate local ledger/market/custody paths and browser wallet database, and a loopback-bound PostgreSQL sandbox stack. Setup and limits are in [the pilot deployment guide](real-xmr-pilot-deployment.md). Testnet v6 and mainnet candidate identities/gates were left intact.
- **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. Explicit pilot-only schema-migration and identity-initialization CLI actions require exact no-funds acknowledgements, reject non-pilot profiles, and refuse any target DB with pre-existing mock/financial/deposit data. No runtime roles/grants or deposit/withdrawal routes were added. Existing v1-v9 migration definitions/digests remain unchanged.
- **Pilot deposit-contract slice implemented:** added a separate signed pilot request schema that explicitly binds the Wikideck pilot network/chain, Monero Mainnet, custodian, beneficiary and watch-only wallet generation. Its validator checks signature, expiry, identity-only status and wallet context, and returns only a validated intent digest—no address/index or RPC/DB side effect. It is not connected to HTTP or an allocator.
- **Validation:** the latest serial offline suite passed 189/189; the new pilot contract tests passed 3/3. PostgreSQL integration suite passed 42/42 after schema v10, including v1/v2 upgrades, identity replay/mismatch checks, dirty-database rejection, and no role access to the identity table. The isolated pilot identity operation itself requires a separate fresh database and has not been run outside disposable tests.
- **Step 1 is not complete.** The current pilot stack does not connect to that external daemon and still has no Wallet-RPC gateway, observer, real-fund deposit or withdrawal path. It is useful for isolated UI/mock-flow work 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.
- **Steps 2–5:** not started. Existing deposit/withdrawal APIs still require the separately gated mainnet profile; the new pilot record is identity metadata only. 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 v10 and accounting/reorg records.
- 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 v10 and a pilot-only CLI bind the separate Wikideck pilot chain to Monero Mainnet in a fresh identity-only database; this grants no runtime access and cannot be used to enroll or credit deposits. Observer/Wallet-RPC roles and all real-fund integrations remain outstanding. See [pilot deployment status and startup](real-xmr-pilot-deployment.md).
**Result:** start the stack, open the UI, create two wallets and obtain a test card; verify the hosted daemon's intended network, synchronization and private RPC reachability from the pilot runtime. Do not start a duplicate daemon. Prepare the watch-only/observer and separately controlled spending-wallet services while application development proceeds. 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 the separate durable pilot allocation and observer identity path, then test it only with disposable fixtures—still without enabling an HTTP enrollment route or creating addresses.** The signed pilot request contract now defines the dual-network authorization boundary. Next migration/role work must preserve `identity-only`, separate pilot records from mock custody, and reject credit until reviewed funding, withdrawal execution and recovery are ready. Run the read-only daemon check when the protected endpoint config is available; no duplicate daemon is planned. Continue treasury execution and active sale-lock settlement as parallel tracks once their shared identity boundary is defined. Completion means a buyer purchasing a card and the seller receiving withdrawable XMR—not another scaffold or release checklist.