Address the signing request to the account that must sign it - #141
Open
n13 wants to merge 1 commit into
Open
Conversation
The QR carried the payload and nothing else, so a wallet holding several
accounts could not tell which key the request wanted, and one holding none of
them could not tell that it held the wrong key - it would sign with whatever it
had and produce a signature the chain rejects, or worse, one it accepts from an
account the user did not mean to spend from.
The payload now travels in the same JSON envelope the mobile app, the cold
wallet app and the Keystone firmware read: {v, signer, payload}, refused
outright if it is not exactly that. cold-sign-sim reads it too, and refuses a
request addressed to an account other than the wallet it was asked to sign
with, which is what the devices do.
Adds `quantus signing-qr`: the first half of the cold signing flow on its own -
print the request for an address and stop, submitting nothing and needing no
wallet imported first. It reuses the same context capture, payload builder and
animated display as the real flow, so what it prints is what a signer is really
asked to read, which is what makes it useful for checking how a device
displays a call.
illuzen
approved these changes
Aug 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The cold-signing QR carried the SCALE payload and nothing else. A wallet holding several accounts could not tell which key the request wanted, and one holding none of them could not tell that it held the wrong key — it would sign with whatever it had, producing a signature the chain rejects, or worse, one it accepts from an account the user did not mean to spend from.
The payload now travels in the same JSON envelope the mobile app, the cold wallet app and the Keystone firmware read:
{"v": 1, "signer": "<ss58>", "payload": "0x<scale>"}Changes
src/qr/sign_request.rs(new) — the envelope, encoded and decoded as strictly as the wallets do: exactly these three keys, this version,0xhex payload, bounded by the same 8 KiB cap as the SDK. The doc comment namesSigningRequestinquantus_sdk/lib/src/models/signing_request.dartso the two stay in step.src/cli/cold_signing.rs— the request is wrapped before UR encoding.cold-sign-sim, which plays the cold-wallet side, decodes it and refuses a request addressed to an account other than the wallet it was asked to sign with, which is what the real devices do. The offline end-to-end test now round-trips through the envelope, so it asserts the format actually on the wire.src/cli/signing_qr.rs(new) —quantus signing-qr --from <address>: the first half of the signing flow on its own. Prints the request for an address and stops — nothing submitted, no wallet imported first. It reuses the same context capture, payload builder and animated display as the real flow, so what it prints is what a signer is really asked to read, which is what makes it useful for checking how a device displays a call.Compatibility
This is a breaking wire change against wallet builds that predate the envelope: they read the bare payload and will refuse this. The Quantus mobile app, cold wallet app and Keystone firmware that speak the envelope are the counterpart.
Testing
./clippy.sh(fmt + taplo + clippy-D warnings) is clean.wss://a1-planck.quantus.cat): the requestsigning-qrproduced parses in the cold wallet's ownQuantusPayloadParserasPlanck/SEND/ 1.5 QUAN to the expected destination, mortal era, correct nonce.