Skip to content

Recognize Canon declaration challenges in connect sign-requests - #9

Open
cdonnachie wants to merge 3 commits into
fix/sanitize-untrusted-display-textfrom
feat/canon-declaration-recognition
Open

Recognize Canon declaration challenges in connect sign-requests#9
cdonnachie wants to merge 3 commits into
fix/sanitize-untrusted-display-textfrom
feat/canon-declaration-recognition

Conversation

@cdonnachie

Copy link
Copy Markdown

What

A Canon creator declaration arrives as a sign-request whose challenge is the canonical declaration message. Without recognition, the approval screen shows the orange Unrecognized badge and the "Not a standard connect request" warning for a format this wallet can fully understand.

  • parseCanonDeclaration in the protocol module: a pure, display-only parser for both canonical message versions. v2 (canon-declaration:wallet-connect:v2:<network>:<body>) already matches the recognized connect-challenge shape; v1 (canon-declaration|v1|…) is recognized explicitly. A challenge that fails the parser is simply not a Canon declaration — never an error.
  • The approval screen shows a green Canon declaration badge, skips the not-a-standard-connect warning, and renders the declaration structured — what the key recognizes or revokes (kind, sanitized label, full ref), network, dates, comment, and a permanence note — above the exact signed text.

Security notes

  • Parsing is display-only. The signature always covers the raw challenge verbatim; nothing about signing changes.
  • Labels and comments are attacker-controlled text and go through sanitizeForDisplay (this is why the PR is stacked on Show what is actually being approved: sanitise untrusted text, render data outputs #8).
  • The v2 head puts the network in the challenge's nonce slot, so extractChallengeNonce echoes something short and harmless into callbacks.

Stacked on #8

Base is fix/sanitize-untrusted-display-text — this diff is only the recognition commit. Merge #8 first; GitHub will retarget this to main automatically.

Tests

vitest run src/connect/__tests__/protocol.test.ts — 130 passing, including round-trips for both message versions, terminal-comment pipes, revocations, and rejection of every tampered shape.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NQWcT2EiTgiMS2487f7ger

cdonnachie and others added 3 commits September 2, 2026 12:45
A Canon (canon.rxd.zone) creator declaration arrives as a sign-request
whose challenge is the canonical declaration message. Recognize both
message versions in the protocol module (pure, display-only — the
signature always covers the raw challenge verbatim): v2's
canon-declaration:wallet-connect:v2:<network>:<body> head already
matches the recognized connect-challenge shape, and v1's pipe form is
recognized explicitly. The approval screen shows a "Canon declaration"
badge, skips the not-a-standard-connect warning, and renders the
declaration structured — what the key recognizes or revokes, network,
dates, comment, plus a permanence note — above the exact signed text.

Stacked on fix/sanitize-untrusted-display-text (uses
sanitizeForDisplay for the hostile label/comment fields).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NQWcT2EiTgiMS2487f7ger
New connect request type mirroring mint-request's self-funded
commit+reveal pattern: the dApp hands over a SIGNED Canon declaration
document (exact JSON string — its bytes are the docHash identity), and
after approval the wallet publishes it as a cnd1 anchor pair, funded
from its own RXD UTXOs. The commit script is a minimal non-token
covenant (OP_HASH256 <sha256d(payload)> OP_EQUALVERIFY + own-key p2pkh);
the reveal scriptSig appends the payload push behind sig+pubkey via
buildTx's input-script callback. Nothing is minted.

Anchoring is permanent, so the gate is strict: the envelope refuses any
document that is not a well-formed declaration (both message versions),
and the flow re-verifies the signmessage signature against the signer
address inside the document before building anything. The approval
screen renders the declaration structured with a permanence warning and
the exact bytes to be committed; results return commit/reveal txids
(or unsent hex for broadcast:false) plus the docHash.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NQWcT2EiTgiMS2487f7ger
Standalone NFTs with no container or creator token to derive trust from
declare as kind "work"; the parser accepts it and both approval panels
render it as "individual work".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NQWcT2EiTgiMS2487f7ger
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant