Repository navigation
Add Bitcoin and Ethereum banks: wallets that work like cards - #27
Merged
Merged
Conversation
IAmJSD
added this pull request to stack #29
October 19, 2026 15:34
IAmJSD
force-pushed
the
bank/4-crypto
branch
2 times, most recently
from
October 19, 2026 21:28
45cec95 to
c1e17b4
Compare
Each crypto card is a fresh wallet funded from the server's treasury with exactly the card's limit, so the limit holds on chain, and swept back to the treasury when it's killed. Wallet keys are derived from the treasury key and the card's id, so none is stored and a restarted container can be given its key again. `@nibblet/bank-bitcoin` uses native segwit and an Esplora API, signing with `@scure/btc-signer`; it needs `BITCOIN_TREASURY_KEY` and an explicit `BITCOIN_NETWORK`. `@nibblet/bank-ethereum` sends plain transfers through viem to `ETHEREUM_RPC_URL`, optionally pinned to `ETHEREUM_CHAIN_ID`. The plugin base gains what they share: a queue for treasury sends and how a wallet's spending is counted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KGXXQcj3hZN2jiB6As6kk5
Only a 4xx from Esplora means a broadcast went nowhere. A 5xx can come after the transaction was relayed, so it's now an unclear failure: the server keeps the card pending and looks for it, instead of forgetting a funded wallet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part 4 of 7 in the bank stack, on #26.
What this adds
Each crypto "card" is a fresh wallet funded from the server's treasury with exactly the card's limit, so the limit holds on chain. Killing the card sweeps what's left back to the treasury. A wallet's key is derived from the treasury key and the card's id, so none is stored, and a restarted container can be given its key again.
@nibblet/bank-bitcoin):@scure/btc-signer; reads and broadcasts through an Esplora API (mempool.space by default).BITCOIN_TREASURY_KEYand an explicitBITCOIN_NETWORK, with no default, so a test key never lands on mainnet. OptionalBITCOIN_ESPLORA_URLandBITCOIN_FEE_RATE.@nibblet/bank-ethereum):ETHEREUM_RPC_URL. OptionalETHEREUM_CHAIN_ID, checked before anything is sent, andETHEREUM_ASSETfor another EVM chain's coin.settled: falseinstead of sweeping nothing and writing the money off. The server keeps itclosingand tries again.#31 (part 6) moves these settings into a form in Settings → Bank; the environment stays as a fallback.
Limits worth knowing
Screenshots
From #28's UI, in the mock server (
?mock=1): the Bitcoin bank with its treasury balance, and two wallet cards. The second has been killed and is waiting for its funding to show before it sweeps.Review fixes
Checks
pnpm format:check,pnpm -r typecheckandpnpm testpass on this branch on its own. Bitcoin tests sign and apply real transactions against an in-memory Esplora; an Ethereum test checks a real viem-signed transfer.Generated by Claude Code