pastilhasandClaude Opus 5 b2722df5aa name the over-long foreign keys so db:push can be a no-op
Drizzle generates names past Postgres's 63-character identifier limit. Postgres
stores the truncated form, drizzle compares against its own longer one, and every
push on every host drops and re-adds constraints that are already identical.

Deferred as harmless noise since 2026-08-19. What ended that was a deploy plan
saying "expect no changes, stop if it wants to alter something" — which this made
impossible to satisfy, so the deploy agent had to overrule its own instructions.

Verified by pushing twice against a scratch database: the fleet-wide second-push
churn went from ten statements to two, and the two that remain are a composite
primary key that cannot be fixed either way.

Naming a foreign key means removing the inline .references() or drizzle creates
both.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 14:16:31 +00:00

Wallet

A self-custodial bitcoin wallet inside Officer, with the keys held on your server rather than on a phone or in a browser.

What you get

  • On-chain balance, receive addresses and transaction history
  • Send, with fee control, coin selection and UTXO freezing
  • Labels for addresses and transactions
  • Multiple wallets, one active
  • Chain data from Esplora or your own NBXplorer

How the keys are held

Read docs/wallet-key-custody.md in the platform for the full design. The short version:

  • Your seed is encrypted under a key derived from your own passphrase (scrypt, N=2¹⁷), then encrypted again at rest. The server never stores the passphrase.
  • The wallet is usable while locked — balances, history and fresh receive addresses all work without it. Unlocking is required only to sign.
  • An unlock lasts 15 minutes by default and does not extend on use. A restart relocks everything.
  • There is no "forgot passphrase". There is no recovery. Your seed backup is the recovery.

Multi-user

Each account gets its own wallet, sealed under its own passphrase. Granting the bitcoin-wallet permission to a role gives those people a wallet of their own — it does not give them yours, and it does not give you theirs. Not through the app, and not with root either: their seed is sealed under a passphrase you do not have.

One caveat, stated plainly: balances and history are stored unencrypted so a locked wallet still shows them. Anyone with the database — or a backup of it — can see any user's balances. They can never move anything.

Permissions

One permission, bitcoin-wallet. Grantable per role like any other app permission.

Requirements

None to start. Esplora is used by default; point it at your own NBXplorer if you run one.

S
Description
No description provided
Readme
2 MiB
Languages
TypeScript 100%