bitcoin-wallet, extracted into plugins/bitcoin-wallet — the platform half
Tenth extraction, and the first where the blocker was a permission rather than a path. The wallet was kind: 'admin' — owner only, never grantable — and plugin permissions are always kind: 'app'. mount.ts forces that and the manifest has no field for anything else, deliberately, so a plugin cannot ask to be restricted. Extraction therefore could not preserve admin. Raised before moving any code, because turning "the server owner's bitcoin" into a row in the grants list beside Photos and Music is the kind of change nobody notices until someone ticks it. Made anyway, and the objection inverts: every wallet query is scoped by user_id, taken from X-Officer-User which the platform injects from the session, so granting the permission gives an account its OWN wallet rather than access to anyone else's — including to the owner, whose bypass covers permission checks and not query scoping. kind: 'admin' was single-user thinking. Named bitcoin-wallet, not wallet: appName drives route, API prefix, table prefix and install key together, so the name should say what it is. Tables are bitcoin_wallet_*; the prefix guard normalises the hyphen. Verified free before committing to it — no wallet table exists on any server, and db:push would treat a rename as a drop plus a create. registry.test.ts re-anchored: `wallet` was its canonical kind: 'admin' fixture and its no-selfService fixture. Now user-admin/server-admin and terminal, with a note that a plugin's permissions are always `app` — which is exactly why this one needed a decision rather than a default. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,16 +0,0 @@
|
||||
import { createSidecarProxy } from '../../sidecar/create-proxy';
|
||||
|
||||
// /api/wallet/* — auth, then forward to officer-wallet. No routes of its own, and no wallet knowledge
|
||||
// whatsoever: not a seed, not a node credential, not an xpub. The platform cannot spend and cannot read a
|
||||
// balance except by asking the sidecar.
|
||||
//
|
||||
// The unlock passphrase DOES transit this proxy — the browser has to send it somewhere — but it is
|
||||
// forwarded as an opaque body and never parsed, logged or retained. See sidecar/create-proxy.ts, which
|
||||
// deliberately performs no body inspection; that restraint matters more for this sidecar than any other.
|
||||
|
||||
const proxy = createSidecarProxy({ name: 'wallet', prefix: '/api/wallet' });
|
||||
|
||||
export const walletRouter = proxy.router;
|
||||
|
||||
/** Base URL of the sidecar's HTTP server, or null if it hasn't reported in yet. */
|
||||
export const getWalletServerUrl = proxy.getHttpUrl;
|
||||
Reference in New Issue
Block a user