62 Commits

Author SHA1 Message Date
4b0af6f4bf v0.6.1: read version from manifest.json (single source of truth)
Read the plugin version at runtime from bal/manifest.json via
importlib.resources (zip-safe, works from inside a zip on Windows).
Removes the four-file duplication (VERSION, __init__.py, plugin_base.py,
manifest.json) and deletes the bal/VERSION file.

- bal/core/plugin_base.py: new get_version() function, BalPlugin.version
  is now a @property, removed hardcoded __version__
- bal/__init__.py: removed __version__, replaced with a comment
- bal/core/willexecutors.py: user-agent uses get_version()
- bal/gui/qt/dialogs.py, widgets.py: call sites use .version property
- tests/test_version_source.py: 7 tests incl. zip-safe subprocess check
- HANDOFF.md: updated to single-source-of-truth documentation
- CHANGELOG.md: entries 43-46
- bal/manifest.json: version bumped to 0.6.1

PR #4 (branch bitcoinafterlife-patch-5).
2026-07-22 11:19:18 -04:00
449e815f89 v0.5.18: version bump 2026-07-16 12:31:51 +00:00
59c3271fc7 v0.5.18: onion helpers, download robustness, Tor-aware messages 2026-07-16 12:31:29 +00:00
7722272c39 v0.5.18: Tor-gated onion download, crash fix, clearer Tor timeout message 2026-07-16 12:30:30 +00:00
1d3227d963 v0.5.16: version bump 2026-07-16 09:38:08 +00:00
5cac176dfb v0.5.16: onion helpers + download filter 2026-07-16 09:37:40 +00:00
e4bcc4f911 v0.5.16: skip .onion will-executors from download when not on Tor 2026-07-16 09:37:10 +00:00
62502263fd v0.5.15: sync version in plugin_base 2026-07-15 12:08:13 +00:00
184eb7b619 v0.5.15: version bump 2026-07-15 12:07:43 +00:00
3845c8d739 v0.5.15: shorten long .onion URLs + fix KeyError on delete/select/ping 2026-07-15 12:06:58 +00:00
84e1094553 v0.5.13: version bump 2026-07-14 10:50:46 +00:00
df6b5e3e9a v0.5.13: Electrum 4.8.0 compatibility (register_dict -> register_name shim 2026-07-14 10:50:08 +00:00
b1145d654c v0.5.13: remove Check Alive red highlight 2026-07-14 10:49:27 +00:00
e8cde30182 v0.5.11: version bump 2026-07-13 21:54:53 +00:00
745489f616 v0.5.11: Electrum 4.8.0 compatibility (register_dict -> register_name shim) 2026-07-13 21:53:51 +00:00
cd2278c2b8 v0.5.10: sync version in plugin_base 2026-07-05 09:06:53 +00:00
3ceabac0bb v0.5.10: version bump 2026-07-05 09:05:36 +00:00
527ae95c75 v0.5.10: Check Alive/BASIC fixes, UX improvements, Raw-Date handling. 2026-07-05 09:03:57 +00:00
2cb39f1a6d v0.5.2: sync version in plugin_base 2026-07-04 10:07:53 +00:00
20fd54681f v0.5.2: version bump 2026-07-04 10:07:25 +00:00
346164207f v0.5.1: sync version in plugin_base 2026-07-04 08:12:25 +00:00
431bcc6247 v0.5.1: version bump 2026-07-04 08:11:18 +00:00
9cbed79590 v0.5.1: fix Windows Settings-dialog flicker 2026-07-04 08:07:33 +00:00
donkey-ai
ca874d8e93 v0.5.4 2026-07-02 00:29:26 +02:00
kaibot
868674ece2 baltx_fees default 100 -> 20 2026-06-30 06:23:44 -04:00
kaibot
aaa8658aa0 fix: default baltx_fees 100 -> 50 2026-06-30 06:21:58 -04:00
kaibot
aa03c12aab v0.5.0 2026-06-30 04:33:24 -04:00
kaibot
65b50b51f3 fix: auto-sign on check rispetta AUTO_SIGN + nascosto in basic mode
- plugin.py: auto-sign setting con widget nominati, nascosto in basic mode
  (visibile solo in ADVANCED, come welist server e calendar app)
- dialogs.py: _on_success_phase1_body() salta firma/broadcast quando
  AUTO_SIGN è OFF (solo in advanced; basic usa sempre default=True)
- dialogs.py: _show_next_steps_hint() sopprime hint manuali anche in basic
  mode (dove auto-sign è sempre attivo)
2026-06-30 04:27:31 -04:00
kaibot
7b77ff8692 feat: add will-executor edit dialog on double-click with sync button (↻)
- WillExecutorListWidget: double-click/Enter opens edit dialog
- WillExecutorWidget.add() accepts edit_key param for edit mode:
  pre-populates URL, Info, Base Fee, Address fields
- Sync button (↻) pings executor URL via TaskThread and populates
  fields; updates executor status in list in edit mode (200/KO)
- Loading indicator (⟳) during async ping
- QMessageBox with dialog as parent for sync errors
- Focus returns to URL field after sync error
- 'Add another' button only in add mode, no longer default (OK is default)
- Removed Promo Code field
- Heir dialog: 'Add another' no longer default (matches new pattern)
2026-06-30 03:56:11 -04:00
kaibot
ffd518f1a5 fix: forward force param in push_transactions_to_willexecutors so rebroadcast actually resends pushed txs 2026-06-30 02:55:53 -04:00
kaibot
8a6cfc13cf feat: add per-setting reset button (↺) to each row in settings dialog 2026-06-30 02:50:32 -04:00
kaibot
f574472dcf refactor: extract BalCalendarButton common widget + basic-mode default app 2026-06-30 02:43:05 -04:00
kaibot
02cda3513b feat: add calendar button with dropdown menu to build-will dialog + calendar app setting (advanced mode) 2026-06-30 02:27:50 -04:00
kaibot
6d568bf304 Fix: NoneType error in normalize_will when others_inputs is None
When deleting old transactions and clicking Check, task_phase1 would fail
with 'NoneType object has no attribute get' error in WillItem.normalize_locktime.

Root cause: In Will.normalize_will (will.py:150), the parameter others_inputs
defaults to None. At line 151, a local variable 'others_input' is created with
a safe default value (empty dict). However, lines 179 and 184 still used the
original 'others_inputs' parameter instead of the safe local variable, causing
the error when calling .get() on None.

Fix: Use the safe 'others_input' variable instead of the raw parameter in
lines 179 and 184.

Also added:
- Traceback logging to on_error_phase1 so future errors include full call stack
- Debug logging in update_all to log willitems state before processing
- Comprehensive test (test_e5_build_with_real_wallet_heirs_and_utxos) that
  reproduces the exact scenario from the user's karen7 wallet
2026-06-29 12:03:24 -04:00
kaibot
aa971b8759 fix: distinguish empty response from network error in advanced mode
Show 'No active will-executor servers for {chain}' when the server
responds with no data, and 'Could not reach the configured welist
server' only for actual connection errors.
2026-06-29 01:13:38 -04:00
kaibot
41803139c6 feat: move User Type above advanced-only settings, improve dialog sizing
- Move User Type combo to row 5 (before Number of reminders)
- Use QLayout.SizeConstraint.SetFixedSize so dialog auto-resizes on mode switch
- Hide event summary, description and reminders count in basic mode, use defaults
- Increase Event Description height to 3 lines
- Set minimum width on line edits for proper dialog sizing in advanced mode
2026-06-29 01:07:22 -04:00
kaibot
ff00097af4 docs: update User Type and welist server help texts
User Type help now says BASIC is safe for most users and lists
welist server URL config + always-editable fields as advanced features.
Welist server help text updated to 'Only available in ADVANCED mode'.
2026-06-29 00:29:17 -04:00
kaibot
7a58c69533 feat: add configurable welist server URL (advanced mode only)
- Add NoServersForChainError(chain, url, reason) with error details
- Expose WELIST_SERVER setting in plugin dialog, hidden in basic mode
- Basic mode uses factory default; advanced mode uses configured URL only
- Show descriptive error with URL and reason when advanced-mode fetch fails
2026-06-29 00:18:42 -04:00
kaibot
7004953ce2 fix: keep will-settings fields editable in advanced mode
In advanced mode the locktime, check-alive and fees fields should always
be editable regardless of the EDITABLE_DATES setting. Only basic mode
respects that setting.
2026-06-29 00:01:25 -04:00
kaibot
b8e6c240be feat(willexecutors): differentiate empty server response from network error
Raise NoServersForChainError when the welist server responds but returns
no data for the requested chain, showing a chain-specific message instead
of the generic network error.
2026-06-28 23:56:30 -04:00
donkey-ai
33e8a7533d v0.4.8: seven UX fixes for the BAL inheritance plugin
- #04: Raw/Date selector now reappears on the WILL/HEIR tabs when switching to
  ADVANCED (and when a raw value is pushed from the wizard), keeping the current
  value/editor. New BalTimeEditWidget.apply_user_type_visibility() wired into
  WillSettingsWidget for both the locktime and check-alive boxes.
- #3: Building Will report window minimum height 500 -> 450 px.
- #5: 'User Type' setting moved to the bottom, above 'Rebroadcast transactions'.
- #6: enabling ADVANCED now requires typing 'at My Risk' (case-insensitive);
  wrong phrase or cancel reverts to BASIC. QInputDialog added to common import.
- #7a: on CHECK with an emptied wallet, an extra reassuring line is shown on
  'Checking your will': 'Inheritance already executed (on blockchain)' in GREEN
  (CONFIRMED) or 'Inheritance in mempool (waiting confirmation)' in ORANGE
  (MEMPOOL). New _executed_inheritance_status() helper.
- #7b: 'Balance is too low, or CheckAlive is in the past. Skipped' (space added)
  recoloured to ORANGE instead of red.
- Reset button renamed 'Reset setting' -> 'Reset to Default Setting'.
- Added tests/test_group_h_v048.py (8 tests). Version 0.4.7 -> 0.4.8.
  Full suite: 266 passed; ruff clean; CHANGELOG #24; memory updated (#04 done).
2026-06-28 23:02:40 -04:00
donkey-ai
646a33f2f5 feat(v0.4.7): report area 500px, heirs one-per-line, wizard line breaks, ALL-DUST guard
Owner-approved changes after testing v0.4.6, plus accumulated v0.4.x work,
task-tracking notes, and an updated project HANDOFF document.

The four v0.4.7 changes:

1. Report area (BalBuildWillDialog) opens 500px tall (min) up to 700px (max),
   then the scrollbar takes over. Previously it opened ~140px (too short).

2. Heirs are listed ONE per line again (green, bold) in _build_success_report,
   reverting the v0.4.6 single-line form. Heir names can be long and the report
   now scrolls, so compression is no longer needed.

3. Two wizard texts get an explicit line break: after "(or backup)" in the date
   hint and after "miner fees" in the fee note (widgets.py).

4. ALL-DUST guard: when EVERY heir's share is below the Bitcoin dust limit, the
   inheritance would pay nobody. Heirs.prepare_lists now raises
   HeirAmountIsDustException at the end (where all heirs across all locktimes
   are known with their final dust state), and dialogs.task_phase1 shows a clear
   RED message and stops without building/signing/checking. A mix of dust +
   valid heirs keeps building normally. The guard is intentionally in
   prepare_lists, NOT prepare_transactions (which only sees the lowest locktime
   and would false-positive). HeirAmountIsDustException is imported in common.py.

Tests: 3 new tests in test_core_heirs_extra.py pin the dust behaviour (all-dust
raises; mixed continues; multi-locktime continues). Full suite: 258 passed.
ruff: no new errors. Version bumped 0.4.6 -> 0.4.7 (4 files). CHANGELOG #23.

Also adds/updates HANDOFF.md so any future AI (Claude or another model) can
resume the project with full context (rules, layout, build/test/lint, dust
logic, git flow), and records the task-tracking notes in
.agent_memory_tasks.md.
2026-06-28 23:02:25 -04:00
donkey-ai
5b707e647b feat(bal): UI batch v0.3.9 + expired-will invalidate regression fix
UI batch (TASK A/B/C/D):
- (A) Clearer 'Will expired' message: shortened will id (8+8 chars) and
  readable UTC date instead of raw UNIX timestamp; shown in WARNING colour
  (orange) instead of ERROR (red) in the wizard, as it is an expected step.
- (A2) Split the orange message onto two lines via <br> (rendered as HTML by
  msg_warning) to avoid an overly long single line.
- (B) History tab labels (text only): inheritance txs -> 'BAL Inheritance
  transaction'; invalidate tx -> 'BAL Invalidate transaction'. Colours left
  to Electrum defaults.
- (C) New 'No will-executor TX' checkbox in plugin settings, bound to the
  existing NO_WILLEXECUTOR config (default ON, kept in sync with the wizard),
  with help text, and included in the settings reset action.
- (D) Wizard button label 'Create your will' -> 'Build Your Will'.

Regression fix (A3):
- When an heir was added to an already-expired will via the wizard, the
  automatic invalidation no longer triggered. Root cause: the inner
  check_will() after build_will() raised WillExpiredException and the handler
  returned (False, None), which never invalidated.
- Auto-opening the invalidation tx window from the closing wizard proved
  unreliable (the window ended up behind the main wallet on some window
  managers; a re-check loop could ask to invalidate repeatedly before the tx
  reached the mempool). The robust fix: close the wizard and show a clear
  instruction popup guiding the user to run 'Tools -> Invalidate' and then
  press 'Check' to finish the will. Reasoning documented in the code.

Version bumped to 0.3.9 (manifest.json, __init__.py, plugin_base.py, VERSION).
CHANGELOG entry #15 updated. Verified: py_compile OK, ruff clean (no new
errors), full test suite 239 passed.
2026-06-28 23:02:11 -04:00
donkey-ai
ce3a463a5e docs(bal): rewrite CHECK ALIVE help text (DATA/RAW modes) + fix two typos (v0.3.8)
Rewrite the CHECK ALIVE help popup (ThresholdTimeWidget.help_text) to explain
both modes, keeping the <b>CHECK ALIVE</b> title bold:
- DATA mode: set the check-alive date; on wallet open, if the date has passed
  the plugin asks whether to postpone the inheritance.
- RAW mode: when less than this time is missing, ask to invalidate; failing to
  invalidate delivers the transactions to the heirs; kept the d/y suffix help.

Fix two typos within this help text: 'less then' -> 'less than',
'currrent' -> 'current'.

Bump version to 0.3.8 across the four version files. CHANGELOG entry #14.
2026-06-28 23:02:03 -04:00
donkey-ai
50129d3b77 feat(bal): export calendar .ics as separate reminder events (v0.3.7)
- open_or_save_calendar(): emit one VEVENT per reminder instead of a single
  event with VALARM blocks. Dates come from compute_reminder_offsets(), spread
  across the check-alive period, with the LAST event one day before the
  locktime. Unique UID per event (bal-<wallet>-<offset>d) and numbered
  summaries ' (reminder N/total)'.
- Removed the now-unused create_alarms() method (no more VALARM).
- Default save filename changed from will_event.ics to BAL_will_event.ics.
- common.py: added timedelta to the datetime import.
- plugin_base.py: updated the NUM_REMINDERS comment for the new behaviour.
- tests: replaced the VALARM E1 test with test_e1_build_separate_events_for_giovanna.
- Bumped version to 0.3.7 (4 files) and added CHANGELOG entry #13.

Tests: 239 passed. ruff: no new errors.
2026-06-28 23:01:54 -04:00
donkey-ai
dd2e160a17 fix(bal): black bar on cancelled invalidation + editable fee follows dates (v0.3.6)
Two GUI fixes bundled together (v0.3.6):

- Fix #10 (black bar): in dialogs.py on_success_phase1, the cancelled
  invalidation branch no longer calls the blocking self.wait(3)+self.close().
  wait() uses time.sleep() and runs in the GUI thread, freezing the UI so the
  'Building Will' dialog could not repaint the area it just resized, leaving a
  black rectangle at the bottom. It now shows 'Aborted' plus the existing
  non-blocking Close button (_add_close_button), consistent with the other
  end-of-flow branches.

- Fix #11 (editable fee): in widgets.py WillSettingsWidget.apply_editable_dates,
  the fee widget (baltx_fees) now follows the same 'Editable dates' setting as
  the locktime/threshold widgets (set_read_only(not editable_dates)) instead of
  being forced read-only. With the setting ticked, dates AND fee are editable
  outside the wizard; unticked, all three are read-only. Default stays OFF.

Version bumped 0.3.5 -> 0.3.6 (manifest.json, __init__.py, plugin_base.py,
VERSION). CHANGELOG: entries #10 and #11. ruff clean; full suite 239 passed.
2026-06-28 23:01:38 -04:00
donkey-ai
b03251e864 feat(bal): Group D / D1 - configurable distributed calendar reminders + save-only .ics
D1 - number of reminders (default 3, max 5):
  - new NUM_REMINDERS config in plugin_base.py
  - new BalSpinBox widget bound to a BalConfig
  - new pure helper compute_reminder_offsets(days, count): reminders spread
    uniformly across the check-alive period, always before the deadline
    (offset >= 1), at most one per available day, de-duplicated, earliest
    first (e.g. (30,3)->[30,16,1], (2,3)->[2,1], (1,3)->[1], (0,3)->[])
  - create_alarms() rewritten to use it and emit one VALARM per offset with a
    DESCRIPTION reminder text
  - 'Number of reminders' spin box (range 1..5) added to the settings dialog
    and to the Reset list

D1b - save-only .ics (ask where, default to Desktop):
  - BalCalendar.desktop_dir() helper (~/Desktop with home fallback)
  - open_or_save_calendar() no longer opens the file with a calendar app; it
    always shows a 'save as' dialog (.ics filter, default will_event.ics,
    starting on the Desktop) and copies the file there, then confirms.
    Identical behaviour on Windows/Linux/macOS. save_to_cwd -> save_ics_to.

Follow-up: removed the now-unused 'Calendar App' field from the settings
  dialog (and from the Reset list). CALENDAR_APP config and
  open_with_default_app left in place (unused) to avoid unrelated changes.

D2 intentionally skipped (per user request).

tests/test_group_d_alarms.py: 7 new tests (NUM_REMINDERS default/change and
  all distribution rules). Full suite: 217 passed.
2026-06-28 23:00:31 -04:00
donkey-ai
9d2cbc2814 feat(bal): Group C settings-dialog improvements (editable dates, narrower RAW box, warning/reset/support, tooltips, bold locktime)
C2 - 'Editable dates' option (default OFF):
  - new EDITABLE_DATES config; checkbox in settings dialog
  - WillSettingsWidget.apply_editable_dates() re-locks/unlocks the
    delivery-time and check-alive fields, called from update_all() so the
    toggle takes effect immediately (same mechanism as Hide Invalidated)
  - EDITABLE_DATES included in the Reset-to-defaults list

C3 - RAW date box narrowed to ~1/3 (input box 6 chars); the trailing
  label that shows the computed absolute date kept at 10 chars (fixed a
  truncation regression)

C4 - settings dialog:
  (a) bold red warning at the top
  (b) 'Reset setting' button restoring all 7 dialog settings to defaults
      (single source of truth: BalConfig.default), not touching wills
  (c) bold 'Support: bitcoin-after.life' link (opens via webopen)

C5 - tooltips: calendar 'Export reminder dates to your calendar (.ics)',
  fee field 'Mining fee rate in sat/vByte used for the will transactions',
  fee '丰' icon 'Miner fee, click for more information' (tooltip font scoped
  to QPushButton so it matches the other tooltips)

C6 - Locktime column rendered in bold in the will list

tests/test_group_c_settings.py: 4 new tests (EDITABLE_DATES default/toggle,
  reset restores all dialog settings incl. EDITABLE_DATES, reset leaves
  unrelated config untouched). Full suite: 210 passed.
2026-06-28 23:00:30 -04:00
donkey-ai
dc166d04ff feat(bal): Group A (timestamps + statuses + anticipate docs) and Group B (auto-sign) v0.3.4
Bump plugin version to 0.3.4 (manifest, __init__, plugin_base, VERSION).

GROUP A
- A1: remove block-height locktimes; the plugin now uses UNIX timestamps
  only. The NLOCKTIME_BLOCKHEIGHT_MAX guard is kept on purpose (it forces
  every locktime to be a timestamp). chk_locktime is now 2-arg; int_locktime
  and anticipate_locktime no longer accept blocks; RAW input only accepts d/y.
  Two now-dormant configs (LOCKTIME_BLOCKS, LOCKTIMEDELTA_BLOCKS) are kept with
  comments to avoid touching persisted keys.
- A2: rename PENDING -> MEMPOOL everywhere (label 'Mempool', yellow #ffce30);
  add new UPDATED status; ANTICIPATED & UPDATED keep VALID; documented
  set_status rules; backward-compat migration (old PENDING -> MEMPOOL).
- A3: clarify that anticipating to a future date only rebuilds (never
  invalidates), while only a past locktime invalidates (WillExpired). Code was
  already correct; only the comment and docs were fixed.

Colour follow-up: UPDATED lightened from #800080 to #b266b2 (more readable),
updated in theme.py, docs and the theme test.

GROUP B
- B1: verified the 'Create your will' button already opens the guided wizard
  (no code change needed).
- B2: new persisted AUTO_SIGN setting (default ON) with an 'Auto-sign on Check'
  checkbox in the settings dialog. When enabled, Check signs and broadcasts
  automatically; the wallet password is requested only for encrypted wallets.

B2 follow-up (fixes reported after testing):
- Remove the duplicate sign/broadcast cycle in lists.check(); build_will_task()
  already signs and broadcasts.
- Suppress the manual 'press Sign/Broadcast' hint and its popup when AUTO_SIGN
  is ON (kept when OFF).
- Make broadcast one-shot: removed the retry flag and the Exception('retry');
  failed will-executors stay PUSH_FAIL and are skipped (no endless retry).
  PUSHED transactions are already excluded from re-collection.

Docs: inheritance-options.md/.html and inheritance-flow.svg updated to v0.3.4.
Tests: 206 passing (new test_anticipate_manual_locktime, test_anticipate_past_locktime,
test_group_b_auto_sign; updated core/util, core/will_extra, gui/theme, gui/widgets).
CHANGELOG.md added with one numbered entry per task.
2026-06-28 23:00:23 -04:00
GenSpark AI Developer
30bab62247 UI polish and signed-tx colour fix (v0.3.3)
Fix and refine the BAL plugin GUI without changing business logic:

core/will.py: restore the PUSHED requirement in needs_server_check so a
signed-but-not-broadcast will is no longer server-queried and therefore
stays blue (COMPLETE) instead of turning red (CHECK_FAIL). This matches the
original Gitea check() condition.

gui/qt/widgets.py: WillSettingsWidget vertical layout now caps every row to
the widest date-row width and left-aligns them; the leading icons keep their
original HelpButton width.

gui/qt/lists.py + gui/qt/common.py: the wizard toolbar button now shows a
28x28 icon plus a bold 'Create your will' caption (QSize imported).

gui/qt/dialogs.py (BalBuildWillDialog):
- closing summary row labelled 'All done: Ok' with a blank separator above it;
- 'checking variables' capitalised to 'Checking variables' (redundant trailing
  colon dropped);
- final auto-closing countdown replaced by an explicit right-aligned 'Close'
  button; intermediate technical pauses kept; next-steps popup preserved.

gui/qt/window.py + core/plugin_base.py: guide show_message on build, and
sync_hide_filters() in update_all so hide flags refresh immediately.

tests: test_needs_server_check updated; added offscreen preview helpers.
Version bumped to 0.3.3. 186 tests pass; ruff clean (baseline only).
2026-06-28 22:51:28 -04:00