mirror of
https://github.com/Permissionless-Software-Foundation/psffpp-payments.git
synced 2026-09-21 16:52:04 -07:00
Initial UI
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
# UI deferred features
|
||||
|
||||
Features intentionally **not** built in the first PSFFPP Payments React UI (`ui/`). This document describes what should be built later and how, so a follow-up implementation can reuse the existing browser service layer under `ui/src/services/psffpp/`.
|
||||
|
||||
Shipped in v1 UI: deploy-config paste/upload, pool status, consolidate, split (with fee carve), claim cosign JSON, claim assemble/broadcast. Wallet / BCH / Configuration / Sign views are retained from the wallet SPA fork.
|
||||
|
||||
---
|
||||
|
||||
## 1. Migrate (K-of-M)
|
||||
|
||||
### Why deferred
|
||||
|
||||
First UI release covers a single payout epoch end-to-end (deposit → consolidate → split → claim). Epoch rollover (`migrate`) is rarer, needs a destination address (usually a newly deployed next-epoch pool), and mirrors the claim cosign/assemble pattern that should be proven first.
|
||||
|
||||
### User story
|
||||
|
||||
As two federation operators, we want to move remaining value from an old PoolContract to a next-epoch Pool address after a new deploy, without a privileged admin key.
|
||||
|
||||
### Contract behavior (reference)
|
||||
|
||||
`PoolContract.migrate(s0, s1, s2)`:
|
||||
|
||||
- Requires ≥2-of-3 valid ECDSA signatures over the migrate transaction (`SIGHASH_ALL | SIGHASH_UTXOS`).
|
||||
- 1–2 pure-BCH outputs; destinations are **not** baked — authorized only by signatures.
|
||||
- Unused signature slots must be empty (`0x`), same NULLFAIL rule as claim.
|
||||
- See [`test/pool-migrate.mock.test.js`](../test/pool-migrate.mock.test.js) and [`contracts/PoolContract.cash`](../contracts/PoolContract.cash).
|
||||
|
||||
### Suggested UI
|
||||
|
||||
| Route | Role |
|
||||
|-------|------|
|
||||
| `/migrate/cosign` | Build migrate tx (pool UTXO(s) → destination address(es)), capture one operator’s ECDSA sig into a JSON envelope |
|
||||
| `/migrate` | Assemble ≥2 migrate-sig JSON files and broadcast |
|
||||
|
||||
Envelope sketch (parallel to `psffpp-share-claim-sig`):
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "psffpp-pool-migrate-sig",
|
||||
"version": 1,
|
||||
"network": "mainnet",
|
||||
"migrate": {
|
||||
"poolAddress": "bitcoincash:p…",
|
||||
"poolUtxo": { "txid": "…", "vout": 0, "satoshis": "…" },
|
||||
"outputs": [{ "address": "bitcoincash:p…", "satoshis": "…" }],
|
||||
"feeMode": "from_pool_or_companion",
|
||||
"sighash": "ALL|UTXOS",
|
||||
"signatureAlgorithm": "ECDSA",
|
||||
"constructorPubkeys": ["…", "…", "…"]
|
||||
},
|
||||
"signer": { "nodeIndex": 0, "name": "node0", "pubkey": "…" },
|
||||
"signature": "<hex>"
|
||||
}
|
||||
```
|
||||
|
||||
### Implementation notes
|
||||
|
||||
- Reuse `SignatureTemplate` capture pattern from `ui/src/services/psffpp/claim-cosign.js`.
|
||||
- Reuse assemble/empty-slot logic from `claim-broadcast.js`.
|
||||
- Decide fee policy up front: deduct from pool vs companion fee input (companion is safer when leftover is near `minConsolidation`).
|
||||
- Require loaded deploy config for the **source** pool; destination may be pasted as a cashaddr (next-epoch pool) after a separate config derive step.
|
||||
- Acceptance: 2-of-3 migrate dry-run builds; broadcast moves value; 1-of-3 fails; mismatched envelope params rejected.
|
||||
|
||||
---
|
||||
|
||||
## 2. Next-epoch deploy helper
|
||||
|
||||
### Why deferred
|
||||
|
||||
Deploy today is CLI (`npm run addresses` / `npm run deploy`). The UI only loads an existing deploy JSON.
|
||||
|
||||
### User story
|
||||
|
||||
As an operator, I want to enter the next `splitBlockheight` (and optional membership tweaks), see new Share + Pool addresses, download a deploy record, then hand that address into Migrate.
|
||||
|
||||
### Suggested UI
|
||||
|
||||
- Route `/deploy` or extend `/contracts` with a “New epoch” wizard.
|
||||
- Client-side: validate config → `instantiateContracts` → show addresses (same as Contracts view).
|
||||
- Optional: download a deployment record JSON matching `scripts/deploy.mjs` shape (timestamps, locking bytecodes, artifact fingerprints). Fingerprints need a browser SHA-256 (Web Crypto), not Node `crypto`.
|
||||
- Do **not** broadcast funding from this wizard unless explicitly requested; publish address only.
|
||||
|
||||
### Acceptance
|
||||
|
||||
Derived addresses match `npm run addresses` for the same JSON; downloadable record is usable as `/contracts` paste input for the next epoch.
|
||||
|
||||
---
|
||||
|
||||
## 3. Registry announce (OP_RETURN PSP1)
|
||||
|
||||
### Why deferred
|
||||
|
||||
Pin-service / indexer registry protocol is specified in [`infra-changes.md`](infra-changes.md) but not yet implemented in CLIs or UI. Only the trusted controller key should post updates.
|
||||
|
||||
### User story
|
||||
|
||||
As the registry controller, I post an append-only OP_RETURN announcing the current pool address so pin-service sync can validate historical payments.
|
||||
|
||||
### Suggested UI
|
||||
|
||||
- Route `/registry` (controller wallet only).
|
||||
- Build OP_RETURN payload per infra-changes protocol (`PSP1` + pool cashaddr / metadata).
|
||||
- Use in-app wallet to fund and broadcast; show confirmation + explorer link.
|
||||
- Read-only mode: sync controller address history and list known pool addresses (Electrum or consumer-api tx history).
|
||||
|
||||
### Acceptance
|
||||
|
||||
Posted tx is parseable by the future pin-service registry sync; UI lists prior announcements for the configured controller.
|
||||
|
||||
---
|
||||
|
||||
## 4. Automation (cron / agent)
|
||||
|
||||
### Why deferred
|
||||
|
||||
Browser UI is interactive. Monthly consolidate→split should eventually run unattended after the height gate without an operator clicking Broadcast.
|
||||
|
||||
### User story
|
||||
|
||||
As federation ops, a scheduled job consolidates if needed, waits for `splitBlockheight`, carves a fee UTXO, and splits — logging txids to a channel.
|
||||
|
||||
### Suggested build
|
||||
|
||||
- Prefer **Node CLIs** already in `scripts/` (`consolidate.mjs`, `split.mjs`) wrapped by systemd/cron or a small agent, not the CRA app.
|
||||
- Optionally extract `ui/src/services/psffpp/*` into a shared package used by both UI and agent to avoid drift.
|
||||
- Secrets: fee-payer WIF in env / file permissions; never in localStorage of a public web host.
|
||||
- Acceptance: dry-run then live run on mainnet smoke pool; idempotent if already split.
|
||||
|
||||
---
|
||||
|
||||
## 5. Federation admin UX
|
||||
|
||||
### Why deferred
|
||||
|
||||
v1 assumes a single pasted config. Production may juggle multiple epochs, remote config, and membership changes.
|
||||
|
||||
### User stories / features
|
||||
|
||||
| Feature | Approach |
|
||||
|---------|----------|
|
||||
| Multi-config profiles | Store named configs in localStorage; switch active profile for all contract views |
|
||||
| Remote config fetch | Load JSON from HTTPS URL / gist / IPFS CID with checksum; allow local override (was plan option C) |
|
||||
| Membership change | Wizard: new 3 pubkeys/PKHs → new deploy → migrate remaining → claim old shares under old contracts |
|
||||
| Read-only explorer links | Deep-link pool/share addresses to block explorers from Pool status |
|
||||
|
||||
### Acceptance
|
||||
|
||||
Operators can keep “epoch N” and “epoch N+1” configs without re-pasting; switching profile refreshes Pool status addresses.
|
||||
|
||||
---
|
||||
|
||||
## Reuse map
|
||||
|
||||
| Deferred feature | Existing building blocks |
|
||||
|------------------|--------------------------|
|
||||
| Migrate cosign/broadcast | `claim-cosign.js`, `claim-broadcast.js`, mock migrate tests |
|
||||
| Next-epoch deploy | `lib.js` `instantiateContracts`, Contracts view UI |
|
||||
| Registry announce | Wallet `send` / OP_RETURN helpers in bch-js; infra-changes.md |
|
||||
| Automation | Parent `scripts/*.mjs` |
|
||||
| Federation admin | `psffppDeployConfig` localStorage pattern in `hooks/state.js` |
|
||||
|
||||
## Out of scope reminders
|
||||
|
||||
Still out of scope for the payments UI unless product requirements change: treasury multisig / withdrawal caps, pin-service dual-mode screens, rewriting the UI to Vite, shipping a hardcoded production federation config with real keys.
|
||||
Reference in New Issue
Block a user