6. Transport
6.1 QR
SP-TX-1. A payload that fits in one QR frame SHOULD be sent bare, without a multi-frame header, so a generic scanner reads it. Check: nullroute INV-UI-22.
SP-TX-2. A payload that does not fit MUST be sent as BBQr frames (Coinkite,
BBQr.md; the project README gives its status as "Deployed Widely"). A PSBT
MUST be sent as file type P carrying the binary PSBT, which is the form
BIP-174 calls the file ("Binary PSBT files should use the .psbt file
extension"). Check: vector bbqr-psbt.json, which MUST include at least one
sequence produced by another implementation; nullroute INV-UI-21
(sends-a-psbt-as-the-binary-file-bbqr-defines), INV-QR-2, INV-QR-3.
SP-TX-3. A receiver MUST read BBQr encodings H, 2 and Z, since BBQr
states "The above encodings must be implemented by receivers". Check:
vector bbqr-psbt.json; nullroute INV-QR-2 and the Z read test in
packages/core/test/qr.bbqr.test.ts.
SP-TX-4. A signer MUST NOT write BBQr encoding Z, so that no compressor
sits in the path that emits signed transactions. This is stricter than BBQr,
which permits Z. Check: nullroute bbqr.spec.yaml lines 36-41 and 108-110;
vector bbqr-psbt.json (writer output is 2 or H only).
SP-TX-5. Frames from two transfers MUST NOT be assembled into one payload.
A receiver MUST refuse a frame whose total, file type or encoding differs from
the transfer in progress, or whose index repeats with different contents.
Because BBQr carries no whole-payload checksum ("All "N" QR codes must be
scanned"), the receiver SHOULD also check a digest of the assembled payload
where the sender provides one. Check: nullroute INV-QR-4; vector
bbqr-psbt.json (two transfers sharing total, type and encoding with disjoint
indices, which nullroute's collector would join: gap N5 in
research/00-current-state.md).
SP-TX-6. BBQr frames MUST use the QR alphanumeric mode, which BBQr states as
"Your QR MUST use the "alphanumeric" character encoding". Check: vector
bbqr-psbt.json (mode indicator of every emitted frame).
SP-TX-7. A signer MAY also read and write Blockchain Commons UR
(BCR-2020-005, multipart per BCR-2024-001). One that does MUST read a PSBT
under both crypto-psbt and psbt, SHOULD write it as crypto-psbt, MUST
refuse a part whose sequence length, message length, checksum or fragment
length differs from the transfer in progress, and MUST NOT return a message
whose CRC-32 does not match. The registry (BCR-2020-006) recommends writing
psbt; this profile departs from it because SeedSigner and Jade read only
crypto-psbt and every wallet checked writes it (research/ur-notes.md,
"PSBT types"). Check: vector ur-psbt.json (frames written by SeedSigner's own
encoder); vector spec/vectors/ur-bcr.json (bc-ur's test suite and the BCR
papers, pinned); nullroute INV-UR-1 to INV-UR-6.
6.2 nullroute conformance
| Id | Status | Evidence |
|---|---|---|
| SP-TX-1 | Met | INV-UI-22 |
| SP-TX-2 | Met | INV-UI-21; reads sequences from Coinkite's reference splitter, and the frames it writes join to the binary PSBT (bbqr-psbt.json) |
| SP-TX-3 | Met | Reads reference sequences in 2, H and Z and a real Coldcard scan (bbqr-psbt.json) |
| SP-TX-4 | Met | Writer emits 2 only (bbqr-psbt.json) |
| SP-TX-5 | Met for PSBT and transaction frames | INV-QR-4 covers mismatched headers and conflicting repeats. INV-QR-10 refuses a PSBT or transaction set that does not join into exactly one (bbqr-psbt.json, two-transfers-disjoint-indices). A structural check, not a digest: other file types, and a splice that happens to parse, are not caught |
| SP-TX-6 | Met | Every BBQr frame is drawn in QR alphanumeric mode (INV-QR-8, INV-QR-9); bbqr-psbt.json, both writer cases, read the mode indicator from the modules |
| SP-TX-7 | Met | Reads crypto-psbt and psbt, writes crypto-psbt, and reproduces every value in spec/vectors/ur-bcr.json (INV-UR-1 to INV-UR-6). Reads every case in ur-psbt.json, written by SeedSigner's own encoder, and SeedSigner's own decoder reads what it writes (make interop-ur). Stricter than the reference: dCBOR only, and a part from another transfer is refused with a message rather than dropped |
Rendered from spec/signer-profile.md, the same bytes that ship with the code. SHA-256 4138440d8a2b925d07a9b6d1d96d4189a74c399b5fc717ae27a79d65c0065817