Real XMR pilot

This commit is contained in:
2026-10-22 14:40:00 -04:00
parent 52559f65d7
commit 3f04c3afa9
19 changed files with 408 additions and 50 deletions
+23
View File
@@ -0,0 +1,23 @@
# Private pilot deployment: mock-only foundation
Status: **application and isolated PostgreSQL sandbox only**. This is not a real-XMR stack, a public node, or an approval to accept deposits. The first deployment increment intentionally has no Monero daemon, Wallet-RPC gateway, observer, deposit enrollment, or withdrawal execution.
## Start the isolated profile
Use [compose.custody-pilot.yaml](../compose.custody-pilot.yaml) with the stable project name `wikideck-xmr-pilot`. Do not combine it with [the existing local custody sandbox](../compose.custody.yaml), the disposable PostgreSQL fixture, or another pilot project name. Project-scoped volumes hold the pilot's PostgreSQL database, credentials, and node state separately.
Build/start with `docker compose -p wikideck-xmr-pilot -f compose.custody-pilot.yaml up -d --build`. Open `http://127.0.0.1:3423/` and confirm the page identifies **PRIVATE PILOT**. The service binds to loopback by default; set `WIKIDECK_PILOT_PORT` only when changing the local port.
The app and browser bundle both select the `pilot` identity. Startup requires `WIKIDECK_PILOT_MODE=private-mock-only`; payments are fixed to `mock`. The market sandbox and PostgreSQL schema are freshly bound to this distinct chain ID. Do not point this stack at existing testnet/mainnet node or custody volumes.
To stop while preserving pilot data, run `docker compose -p wikideck-xmr-pilot -f compose.custody-pilot.yaml down` without volume removal. Do not use `--volumes` unless the database, credentials, and node history are intentionally being destroyed.
## What this enables—and does not
The independent private chain uses a fixed pilot genesis time and its own deterministic chain/genesis identity. The app can run with the current sandbox features and mock balances while test cards and UI flows are exercised. Testnet and mainnet candidate identities and launch gates remain unchanged.
This stack does **not** create real Monero deposit addresses, scan a wallet, approve real credits, construct or relay withdrawals, or settle NFT sales against active consensus. Deposit enrollment and withdrawal request flags remain rejected outside the mainnet profile, and mainnet remains separately gated. Do not expose the service publicly or solicit funds. Wallet integration requires the later observer/gateway and schema/role work, then actual withdrawal execution and activated sale settlement described in [the implementation plan](real-xmr-pilot-plan.md).
## Initial checks
The network manifest reports `profile: pilot`, `network: wikideck-randomx-pilot-1`, and `launchStatus: private-pilot-mock-only`. Verify startup refuses a missing pilot-mode opt-in and any non-mock payment setting. Deployment tests check loopback binding, distinct profile selection, database secret isolation, and absence of Monero services. A successful mock deployment is only evidence for this first slice, not for real-XMR readiness.
+119
View File
@@ -0,0 +1,119 @@
# 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.
- **Step 1 is not complete.** This first stack has no Monero daemon, 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:** pilot-specific network/startup/storage/Compose tests pass (10/10); pilot runtime Docker image builds. The attempted serial full offline suite had one native RandomX HTTP peer-gossip convergence failure in `tests/api.test.ts`; the other reported tests passed. Treat full-suite status as not yet clean and rerun after the next increment.
- **Steps 2–5:** not started. 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 v9 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, with explicit connections to the daemon/watch-only wallet and separate spending wallet.
- 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 Compose deployment and setup guide now exist. This establishes the private application base only; the planned Monero daemon/observer/gateway and any 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. Start preparing/syncing the Monero daemon and wallet while application development proceeds.
### 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 wallet; show pending and available balances.
- 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. 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
**Finish step 1's operational checks, then design the pilot's separate Wikideck-chain/Monero-mainnet financial identity and schema/role contract before connecting deposits.** Existing observer/deposit contracts are mainnet-specific, so do not simply enable their flags on the pilot. Keep the next deployment mock-only until network binding, reviewed credit, actual withdrawal execution, recovery, and sale settlement are connected. Continue with the operator treasury tool and active sale-lock settlement as parallel implementation tracks where the identity contract permits. Completion means a buyer purchasing a card and the seller receiving withdrawable XMR—not another scaffold or release checklist.