BAL — Inheritance Options Guide

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.pyis_will_valid / check_willexecutors_and_heirs and gui/qt/window.pybuild_inheritance_transaction). It is meant for end users and for anyone wanting to understand the on‑chain consequences of each action.

1. The mental model in one paragraph

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:

  1. Do nothing — the will is still coherent.
  2. Rebuild (re‑prepare + re‑sign, no on‑chain cost) — the will changed but nothing dangerous is committed yet.
  3. Invalidate on‑chain first (costs a real Bitcoin fee) — a previously signed/sent transaction must be neutralised by spending its inputs before a new will can safely replace it.
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.

2. Transaction states (status flags)

StatusMeaningSet when
VALIDThe current, usable plandefault; cleared by INVALIDATED/REPLACED/CONFIRMED/MEMPOOL
COMPLETE (Signed)The transaction has been signedafter Sign
PUSHEDSigned tx sent to executor(s)after Broadcast to executors
CHECKEDExecutor confirmed it holds the txafter a successful server Check (implies PUSHED)
CHECK_FAILServer check faileda queried executor did not return the tx
PUSH_FAILSending to the executor failedcleared when PUSHED becomes true
CONFIRMEDTx mined on‑chainseen on‑chain, height > 0
MEMPOOLTx in the Electrum mempoolseen on‑chain, height 0 (named PENDING before v0.3.4)
INVALIDATEDInputs spent → can never confirminvalidation tx / inputs gone
REPLACEDSuperseded by an earlier‑locktime childa replacing child found
ANTICIPATEDLocktime anticipated by 1 day vs a pre‑existing tx with the same heirsset_anticipate (tx stays VALID)
UPDATEDReplaced by a new tx keeping the same locktime + same heirssame‑locktime replacement (tx stays VALID)
EXPIREDLocktime already in the past vs the check datecheck_will_expired

Safety rules baked into set_status

How states map to row colour

PriorityStateColourHex
1INVALIDATEDorange#f87838
2REPLACEDpink#ff97e9
3UPDATEDlight violet#b266b2
4CONFIRMEDgrey#bfbfbf
5MEMPOOLyellow#ffce30
6CHECK_FAIL (and not CHECKED)red#e83845
7CHECKEDgreen#8afa6c
8PUSH_FAILred#e83845
9PUSHEDteal#73f3c8
10COMPLETE (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 (COMPLETE and not PUSHED) is not queried on the server, so it stays blue instead of turning red. Only PUSHED wills are checked.

3. The decision flow

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

4. Every option, explained

4.1 Changing the Check‑Alive date / heir locktime

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?ResultOn‑chain fee?
Move date LATER (postpone)No (never signed)Plain rebuildNo
Move date LATER (postpone)YesInvalidate 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 invalidatesNo
Move date EARLIER into the past (new date already passed)Will is genuinely expired → invalidate (WillExpired)Yes
Check‑Alive threshold already passedInvalidate (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).

4.2 Adding an heir

An heir present in your set but not yet in the will raises HeirNotFoundException.

4.3 Removing an heir

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.

4.4 Changing an heir's percentage or address

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.

4.5 Changing the transaction fee (sat/byte)

A different rate raises TxFeesChangedException.

4.6 Changing or removing a will‑executor

4.7 Nothing changed

If heirs, percentages, fees, executors and locktimes all still match the signed transactions, is_will_valid returns True and nothing happens.

5. What happens on the will‑executor servers

Your actionEffect on the servers
Prepare (rebuild)Nothing yet — new txs are local until Sign + Broadcast.
SignStill local; tx becomes COMPLETE (blue).
Broadcast to executorsSigned txs uploaded; items become PUSHED.
CheckEach 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 willExecutors 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.

6. Quick reference — does it cost a Bitcoin fee?

ChangeRebuild?On‑chain invalidation (real fee)?
Add heir (only prepared)YesNo
Remove heir (only prepared)YesNo
Change % / address (only prepared)YesNo
Change fee rateYesNo
Change / remove will‑executorYesNo
Move date earlier, still in the future (anticipate) — signed or notYesNo
Move date earlier into the past (new date already passed)Yes afterYes
Move date later — will signed/sentYes afterYes
Move date later — will only preparedYesNo
Check‑Alive threshold already passedYes afterYes
Any change to an already signed/sent will that postpones it or expires itYes afterYes
Nothing changedNoNo

7. Golden rules

  1. Before it's signed, changing anything is free — just Prepare again.
  2. After it's signed/sent, only postponing the date (moving it later), or letting it expire (a date now in the past), requires an on‑chain invalidation first (a small Bitcoin fee) so an old transaction can never execute early. Anticipating (moving the date earlier, still in the future) never invalidates — it is just a free rebuild.
  3. Always finish with Sign → Broadcast → Check so executors hold the current plan (green).
  4. The wallet is always fully emptied by the inheritance, so heir amounts must add up.