Files
bal-electrum-plugin/README.md
svatantrya 1e80f7a0e0 docs: align all markdown docs with current code (v0.6.1)
- CHANGELOG: add entries #47 (is_selected/is_valid fee bounds, extremes allowed) and #48 (merge_will crash fix on missing date_to_check)
- HANDOFF: Electrum 4.7.2 and 4.8.0, current layout (qt.py, plugin.py, wallet_util/, docs/, bal_cli.py, 36-file ZIP), runtime/lint venv paths, standalone-script tests (427 collected), direct-to-main workflow, version history up to v0.6.1
- README: drop VERSION from layout, correct anticipate/expire/postpone behavior, update test commands
- docs/manual/README.md: fix Tools menu label to Will-Executors, add BASIC/ADVANCED notes, extend chromatic status table (Partially signed, Updated)
- docs/inheritance-options.md: add PARTIALLY_SIGNED status/transition/colour, version note to v0.6.1
- docs/README.md: make HTML-hosting instructions host-agnostic
- bal/README.md: Prepare button lives on the WILL tab
2026-08-01 23:08:07 -04:00

149 lines
6.1 KiB
Markdown

# BAL — Bitcoin After Life (Electrum plugin)
Free and decentralized **Bitcoin inheritance** support for the
[Electrum](https://electrum.org) wallet. Build time-locked "will" transactions
that transfer your funds to your heirs if you stop refreshing them
(dead-man's switch), optionally relayed by will-executor servers.
This repository contains a **behavior-preserving refactor** of the original
plugin. The logic was kept byte-identical wherever possible; only the file
layout was reorganized to cleanly separate **business logic** from the
**PyQt GUI**.
## Repository layout
```
bal/ the installable Electrum plugin package
├── manifest.json plugin metadata (Electrum reads this)
├── qt.py Qt entry-point shim (re-exports Plugin)
├── core/ GUI-free logic (importable without Qt)
│ ├── util.py
│ ├── plugin_base.py
│ ├── heirs.py
│ ├── will.py
│ └── willexecutors.py
├── gui/qt/ PyQt6 presentation layer
│ ├── theme.py status → color mapping
│ ├── common.py shared imports / helpers
│ ├── widgets.py leaf widgets
│ ├── calendar.py calendar widget
│ ├── dialogs.py dialog windows
│ ├── lists.py tree/list views
│ ├── window.py per-wallet GUI controller
│ └── plugin.py Plugin (Electrum @hooks → GUI)
├── icons/ wallet_util/ LICENSE README.md
build_zip.py builds a clean, zipimport-friendly distribution zip
tests/ smoke + external-zip regression tests
```
## Requirements
- **Electrum 4.7.2 or 4.8.0** — the plugin detects which wallet-DB
registration API is available (`json_db.register_dict` on 4.7.2,
`stored_dict.register_name` on 4.8.0) and adapts automatically.
- **PyQt6** (bundled with the Electrum desktop GUI).
## Wallet compatibility
BAL currently supports **standard (single-signature) wallets** and
**hardware wallets** supported by Electrum. **Multisig wallets** and
**Electrum TrustedCoin (2FA) wallets** are **not yet supported** — see
[`COMPATIBILITY.md`](COMPATIBILITY.md) for the full compatibility matrix and
current status.
## Installation
### Build the distribution archive
```bash
python3 build_zip.py
# -> bal-electrum-plugin.zip (prints size + SHA-256 for integrity checks)
```
The builder writes a `zipimport`-friendly archive (files only, standard
DEFLATE, deterministic order) to avoid loader errors seen on some Electrum
portable builds.
### Install as an external plugin (zip)
1. Electrum → **Tools → Plugins** → install from file → pick the built zip.
2. Enable **Bitcoin After Life** and restart Electrum.
3. (Recommended) verify the downloaded zip's SHA-256 matches the value printed
by `build_zip.py`.
### Install as an internal plugin
Copy the `bal/` directory into your Electrum installation's
`electrum/plugins/` directory, so that `electrum/plugins/bal/manifest.json`
exists, then enable it from **Tools → Plugins**.
## Inheritance safety: anticipate / postpone
A will transaction is signed with a **fixed, immutable locktime** and then
optionally sent to will-executor servers, which are economically incentivised
to broadcast it (they collect fees). Because the locktime is baked into the
signed transaction, simply changing the delivery time later is **not enough**:
the old, already-signed transaction keeps living on the will-executors.
The plugin handles the cases as follows (triggered when you press
**Prepare** on the **WILL** tab):
* **Anticipate** (new delivery time *earlier* than the signed locktime, still
in the future): a plain **rebuild** — the transactions are re-created with
the new, earlier locktime. **No on-chain invalidation and no Bitcoin fee**,
even if the will was already signed/sent: moving the date earlier only makes
the inheritance available *sooner*, so there is no early-execution risk.
* **Expire** (new delivery time now in the **past**): the will is genuinely
expired and you are asked to **invalidate** the old transaction on-chain,
then rebuild.
* **Postpone** (new delivery time *later* than the signed locktime) on a will
that was already **signed and/or pushed**: the previously committed coins
must be invalidated on-chain **first**, otherwise a will-executor could
broadcast the old (earlier-locktime) transaction and execute the inheritance
*too early*. The plugin detects this by comparing the requested locktime with
the locktime **frozen inside the signed transaction** (`tx.locktime`), and
asks you to sign and broadcast an invalidation transaction. After it is
broadcast, press **Prepare** again to rebuild, re-sign and re-send the new
(postponed) inheritance. Postponing a will that was *never* signed/sent just
rebuilds it (no on-chain fee).
## Transaction list: the "Server" column
The will transaction list shows a dedicated **Server** column so you always
know whether each inheritance transaction is actually stored on the
will-executor servers, independently of the row colour:
| Label | Meaning |
| --- | --- |
| `Confirmed on server` | the will-executor confirmed it stored the transaction |
| `Sent (not checked)` | pushed to the will-executor, not yet re-checked |
| `Send failed` / `Not on server` | push failed or the server no longer has it |
| `Signed (not sent)` | signed locally, not sent to any will-executor |
| `Not sent` | not signed/sent yet |
Hovering the cell shows a tooltip with the will-executor URL and the current
state.
## Testing
Run the tests with the **runtime environment** active (see `HANDOFF.md` §3 for
the two venvs and how to activate them):
```bash
# imports + behavior
QT_QPA_PLATFORM=offscreen python3 tests/smoke_test.py electrum.plugins.bal
# external-zip loading regression (run after build_zip.py)
QT_QPA_PLATFORM=offscreen python3 tests/external_zip_test.py bal-electrum-plugin.zip
```
## ⚠️ Safety
This plugin builds real Bitcoin inheritance transactions with time-locks. Test
on **testnet** or a fund-less wallet first, and review the generated
transactions before broadcasting.
## License
MIT — see [`bal/LICENSE`](bal/LICENSE).