Files
bitcoin-wallet/manifest.ts
T
pastilhasandClaude Opus 5 76a7f0c53f release 2026.08.27.01
first dated version. plugins were all sitting on 1.0.0, which said nothing about
when a build was made or which of two copies is newer — the platform already
uses YYYY.MM.DD.NN and this follows it.

the version lives in manifest.ts because a plugin has no package.json; that is
the field the marketplace publishes and the installer compares.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-27 07:36:14 +00:00

58 lines
2.6 KiB
TypeScript

import type { PluginManifest } from '@@/plugins/manifest';
/**
* Wallet — a self-custodial bitcoin wallet, with the keys on the server rather than on a device.
*
* ── Read `docs/wallet-key-custody.md` before changing anything here ──
*
* The seed is sealed under a key derived from the OWNER OF THAT WALLET's passphrase by scrypt
* (N=2¹⁷), then encrypted again at rest. The server cannot open it without the passphrase, which it
* never stores. That is not incidental — it is what makes the next paragraph safe.
*
* ── This permission is GRANTABLE, and that is deliberate ──
*
* It was `kind: 'admin'` — owner only — until this extraction, which was single-user thinking. Every
* wallet query is scoped by `user_id`, and the id comes from `X-Officer-User`, injected by the platform
* from the authenticated session. A caller cannot name someone else's.
*
* So granting this to a role gives that person THEIR OWN wallet. It does not give them yours, and it
* does not give you theirs: not through the API, and not with root either, because their seed is sealed
* under a passphrase you do not have.
*
* ── The gap that is real, and deferred on purpose ──
*
* Watch-only data — xpubs, and the balances, addresses and history derived from them — is stored in the
* CLEAR, so a locked wallet still shows a balance without anyone typing a passphrase. That ergonomics
* choice is why the wallet spends its life locked. The cost: anyone with the Postgres database or a
* backup of it can read any user's balances and history. They can never move a coin.
*
* Encrypting it per-user is a future option, and it costs balance-while-locked. Recorded here rather
* than discovered later.
*
* ── No `osDependencies` ──
*
* Everything is JS. Chain data comes from Esplora or NBXplorer over `fetch`.
*/
export const manifest: PluginManifest = {
publisher: 'officerdev',
version: '2026.08.27.01',
platform: '>=1.0.0',
label: 'Bitcoin Wallet',
summary: 'A self-custodial bitcoin wallet — keys sealed on the server, never on a device',
/** self-custody is the point, and keys are the risk. */
tags: ['Personal', 'Security'],
icon: 'Bitcoin',
color: '#f7931a',
permissions: [
{
key: 'bitcoin-wallet',
label: 'Bitcoin Wallet',
// Written to be read in the grants list, where it sits beside Photos and Music and must not look
// like them. Granting gives that account its own wallet; it never exposes anyone else's.
description: "Bitcoin wallet — each account gets its own, sealed under that account's own passphrase",
},
],
};