core+gui: compact BAL QR v2 wire format + best-of compression default

BAL QR export now ships a fixed 11-char 'BAL1<TTT><iii><F><payload>' header
(3-char base36 zero-padded count fields, cap 46655 frames) and, by default,
the shorter of plain vs zlib+base64 (flag '0'/'Z'). parse_frame remains dual:
legacy 'BALQR1|total|index|flags|' frames still import. detect_format accepts
'BAL1'. New exports are not readable by builds older than this change.

Also add a will-detail test for heir/willexecutor addresses and decoded
OP_RETURN payloads. Docs updated (CHANGELOG, COMPATIBILITY, PLAN_QR_TRANSFER,
README); 345 core tests + 89 GUI tests pass.
This commit is contained in:
2026-09-14 04:42:30 -04:00
parent c040d5323c
commit 7bf05172b3
10 changed files with 391 additions and 79 deletions

View File

@@ -53,6 +53,7 @@ from ...core.qrtransfer import (
QrTransferError,
decode_transfer,
encode_transfer,
encode_transfer_best,
preset_index_for_chunk_size,
split_frames,
)
@@ -2799,6 +2800,12 @@ class BalQrExportWidget(QWidget):
self.tx_strings = list(tx_strings)
self._stop_auto()
self.transfer = encode_transfer(self.tx_strings, compress=False)
# BAL QR now ships compact (best-of) compressed by default: smaller
# frames, and the importer reverses it via the per-frame flag. The
# other formats keep the raw transfer (they compress internally).
self._balqr_transfer, self._balqr_compressed = encode_transfer_best(
self.tx_strings
)
self._refresh_frames()
self._update_intro()
self._render()
@@ -2810,7 +2817,9 @@ class BalQrExportWidget(QWidget):
def _refresh_frames(self):
if self.format == "balqr":
self.frames = split_frames(
self.transfer, self.chunk_size, compressed=False
self._balqr_transfer,
self.chunk_size,
compressed=self._balqr_compressed,
)
else:
self.frames = encode_animated_frames(