Skip to the content
nullroute
Browse the docs

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