How the Bitcoin After Life Electrum plugin reacts to every change you can make to your will: changing the date (earlier / later), adding or removing an heir, changing percentages, fees or will‑executors — and what happens to the transactions held by the will‑executor servers.
This page reflects the actual behaviour of the code (core/will.py→is_will_valid/check_willexecutors_and_heirsandgui/qt/window.py→build_inheritance_transaction). It is meant for end users and for anyone wanting to understand the on‑chain consequences of each action.
Your will is a tree of pre‑signed Bitcoin transactions. Each leaf transaction sends your
coins to your heirs and is time‑locked (nLockTime) so it can only be broadcast
after a future date/block. A copy of each signed transaction is handed to one or more
will‑executor servers. While you are alive you periodically prove you are alive (the
Check‑Alive threshold). When you change anything, BAL chooses between three outcomes:
The whole point of rule 3 is safety: a will‑executor must never be able to broadcast an old transaction that would execute your inheritance too early.
| Status | Meaning | Set when |
|---|---|---|
VALID | The current, usable plan | default; cleared by INVALIDATED/REPLACED/CONFIRMED/MEMPOOL |
COMPLETE (Signed) | The transaction has been signed | after Sign |
PUSHED | Signed tx sent to executor(s) | after Broadcast to executors |
CHECKED | Executor confirmed it holds the tx | after a successful server Check (implies PUSHED) |
CHECK_FAIL | Server check failed | a queried executor did not return the tx |
PUSH_FAIL | Sending to the executor failed | cleared when PUSHED becomes true |
CONFIRMED | Tx mined on‑chain | seen on‑chain, height > 0 |
MEMPOOL | Tx in the Electrum mempool | seen on‑chain, height 0 (named PENDING before v0.3.4) |
INVALIDATED | Inputs spent → can never confirm | invalidation tx / inputs gone |
REPLACED | Superseded by an earlier‑locktime child | a replacing child found |
ANTICIPATED | Locktime anticipated by 1 day vs a pre‑existing tx with the same heirs | set_anticipate (tx stays VALID) |
UPDATED | Replaced by a new tx keeping the same locktime + same heirs | same‑locktime replacement (tx stays VALID) |
EXPIRED | Locktime already in the past vs the check date | check_will_expired |
set_statusINVALIDATED / REPLACED / CONFIRMED / MEMPOOL → clears VALID.ANTICIPATED → keeps VALID (only moves the locktime 1 day earlier).UPDATED → keeps VALID (same locktime + same heirs).CONFIRMED / MEMPOOL → clears INVALIDATED.PUSHED → clears PUSH_FAIL and CHECK_FAIL.CHECKED → implies PUSHED.| Priority | State | Colour | Hex |
|---|---|---|---|
| 1 | INVALIDATED | orange | #f87838 |
| 2 | REPLACED | pink | #ff97e9 |
| 3 | UPDATED | light violet | #b266b2 |
| 4 | CONFIRMED | grey | #bfbfbf |
| 5 | MEMPOOL | yellow | #ffce30 |
| 6 | CHECK_FAIL (and not CHECKED) | red | #e83845 |
| 7 | CHECKED | green | #8afa6c |
| 8 | PUSH_FAIL | red | #e83845 |
| 9 | PUSHED | teal | #73f3c8 |
| 10 | COMPLETE (signed, not pushed) | blue | #2bc8ed |
| — | none of the above (plain VALID) | default white | #ffffff |
v0.3.3 fix: a will that is signed but not yet broadcast (COMPLETEand notPUSHED) is not queried on the server, so it stays blue instead of turning red. OnlyPUSHEDwills are checked.
On Prepare (or the periodic Check, or on Electrum close) BAL runs
is_will_valid, raises a specific exception, and each maps to one action:
flowchart TD
A([You change something & press Prepare / Check]) --> B{Heirs defined?}
B -- No --> Z1[/Show: Heirs are not defined — stop/]
B -- Yes --> C{Check-Alive threshold in the future?}
C -- "No, it's in the past" --> INV1[[Invalidate on-chain
CheckAliveError]]
C -- Yes --> D{New delivery date already in the PAST?}
D -- "Yes date is now expired" --> INV2[[Invalidate on-chain FIRST
WillExpired]]
D -- "No date still in the future" --> AN{Did you move the date EARLIER anticipate?}
AN -- "Yes anticipate — signed or not" --> R1[[Rebuild only
no on-chain cost
NEVER invalidates]]
AN -- No --> F{Will-executor / fee / heirs unchanged?}
F -- "Fee changed" --> R2[[Rebuild
TxFeesChanged]]
F -- "Will-executor changed/absent" --> R3[[Rebuild
WillExecutorNotPresent / Change]]
F -- "Heir added/removed, % or address changed" --> G{POSTPONE of an already signed/sent tx?}
G -- "Yes date later + signed/sent" --> INV3[[Invalidate on-chain FIRST then rebuild
WillPostponed]]
G -- "No never signed, or pure heir/% change" --> R4[[Rebuild only
HeirNotFound / HeirChange]]
F -- "Nothing changed" --> OK([Will still coherent — do nothing])
R1 --> SIGN
R2 --> SIGN
R3 --> SIGN
R4 --> SIGN
SIGN([Re-sign the new transactions]) --> PUSH([Broadcast to will-executors])
INV1 --> SB
INV2 --> SB
INV3 --> SB
SB([Sign & broadcast the INVALIDATION tx on-chain]) --> WAIT{Invalidation confirmed?}
WAIT -- Yes --> REBUILD([Press Prepare again → build the new will])
REBUILD --> SIGN
BAL compares the requested locktime against the locktime frozen inside the
already‑signed transaction (w.tx.locktime) — exactly what the will‑executors hold.
| You do… | Tx already signed/sent? | Result | On‑chain fee? |
|---|---|---|---|
| Move date LATER (postpone) | No (never signed) | Plain rebuild | No |
| Move date LATER (postpone) | Yes | Invalidate first, then rebuild (WillPostponed) | Yes |
| Move date EARLIER, still in the future (anticipate) | any (signed or not) | Plain rebuild with the new earlier locktime — never invalidates | No |
| Move date EARLIER into the past (new date already passed) | — | Will is genuinely expired → invalidate (WillExpired) | Yes |
| Check‑Alive threshold already passed | — | Invalidate (CheckAliveError) | Yes |
Why postpone needs on‑chain invalidation: the executor still holds the old transaction with the earlier locktime. Spending its inputs on‑chain makes it un‑minable, so it can never execute the inheritance early. The plugin tells you this and offers to build the invalidation tx.
Why anticipate (move earlier, still future) is NOT on‑chain: moving the delivery
date earlier only makes the inheritance available sooner; there is no early‑execution risk,
so the plugin simply rebuilds the transactions with the new earlier locktime — no
on‑chain invalidation and no Bitcoin fee. This holds even if the will was already
signed/sent: anticipating never invalidates. Only a date that lands in the past is treated
as expired and invalidated (WillExpired).
An heir present in your set but not yet in the will raises HeirNotFoundException.
The will still carries an heir no longer in your set → HeirNotFoundException (removed‑heir branch).
v0.3.2 fix: removing an heir is now detected on Check and on Electrum close, not only on Prepare.
A changed [address, amount] is treated like an heir change (HeirChange / HeirNotFound).
The wallet is always fully emptied by the inheritance; amounts must add up, or an
AmountException warns you to adjust.
A different rate raises TxFeesChangedException.
WillExecutorNotPresent.WillexecutorChangeException.NoWillExecutorNotPresent.If heirs, percentages, fees, executors and locktimes all still match the signed transactions,
is_will_valid returns True and nothing happens.
Bitcoin refuses outputs that are too small to spend — the dust limit
(the wallet's dust_threshold). BAL resolves each heir's final amount when it builds
the will (Heirs.prepare_lists) and compares every share against that limit.
HeirAmountIsDustException) and the Building Will window stops with a
clear red message: “All heirs' shares are below the dust limit:
the inheritance cannot be created. Increase the amounts or reduce the number of heirs.”
Nothing is built, signed, checked or added to the list.When? Typically with a very small balance split among percentage heirs, or when every fixed amount is below the dust limit. Fix: raise the per‑heir amounts or use fewer heirs.
Note (v0.4.7): the dust check lives in prepare_lists, which sees
all heirs across all locktimes — a single transaction only covers the
earliest locktime, so checking there would wrongly block a will whose later dates still have valid
heirs. On‑chain fee: none (pre‑build safety check).
| Your action | Effect on the servers |
|---|---|
| Prepare (rebuild) | Nothing yet — new txs are local until Sign + Broadcast. |
| Sign | Still local; tx becomes COMPLETE (blue). |
| Broadcast to executors | Signed txs uploaded; items become PUSHED. |
| Check | Each PUSHED will is queried; success → CHECKED (green), failure → CHECK_FAIL (red). |
| Invalidate (on‑chain) | You spend the committed inputs on the network. Once confirmed, the executor's stored tx can no longer be mined and is dropped on the next check. |
| Re‑broadcast a new will | Executors replace the obsolete copy with the new signed tx. |
A row turning red (CHECK_FAIL) after a Check means an
executor that should hold your tx did not return it — re‑Broadcast or rebuild. A merely
blue row is signed‑but‑not‑yet‑sent and perfectly normal.
| Change | Rebuild? | On‑chain invalidation (real fee)? |
|---|---|---|
| Add heir (only prepared) | Yes | No |
| Remove heir (only prepared) | Yes | No |
| Change % / address (only prepared) | Yes | No |
| Change fee rate | Yes | No |
| Change / remove will‑executor | Yes | No |
| Move date earlier, still in the future (anticipate) — signed or not | Yes | No |
| Move date earlier into the past (new date already passed) | Yes after | Yes |
| Move date later — will signed/sent | Yes after | Yes |
| Move date later — will only prepared | Yes | No |
| Check‑Alive threshold already passed | Yes after | Yes |
| Any change to an already signed/sent will that postpones it or expires it | Yes after | Yes |
| Nothing changed | No | No |
| Every heir's share below the dust limit (all‑dust) — build blocked (§4.8) | No | No |