Skip to content

fix(sign-psbt): strip compressed key parity prefix for tapscript pubkey matching#17

Merged
tiero merged 2 commits intomainfrom
claude/epic-hodgkin
Mar 1, 2026
Merged

fix(sign-psbt): strip compressed key parity prefix for tapscript pubkey matching#17
tiero merged 2 commits intomainfrom
claude/epic-hodgkin

Conversation

@tiero
Copy link
Owner

@tiero tiero commented Mar 1, 2026

Summary

  • config.publicKey stores the 33-byte compressed key returned by the API (02/03 prefix), but tapscripts embed 32-byte x-only pubkeys — the byte-by-byte comparison always failed at position 0, so canSign was always false for tapscript inputs
  • Derives xOnlyPubkeyBytes once (strips parity prefix when 33 bytes) and applies it to the script scan, tapScriptSig.pubKey injection, and tapInternalKey comparison
  • Also fixes the ClwApiClient mock in tests (arrow fn can't be used as constructor with new) and adds two end-to-end integration tests

Test plan

  • npm test — all 39 unit tests pass
  • cash sign-psbt <psbt> with a real 2-of-2 tapscript PSBT now shows canSign: true and proceeds to signing

🤖 Generated with Claude Code

…arison

config.publicKey stores the 33-byte compressed public key returned by the
API (02/03 prefix), but tapscripts embed 32-byte x-only pubkeys. The
pubkey scan in sign-psbt.ts was comparing bytes directly, so the parity
prefix caused every match to fail, returning canSign: false for all
tapscript inputs.

Fix: derive xOnlyPubkeyBytes once by slicing the prefix when the key is
33 bytes. Apply the x-only key to all three affected call-sites: the
script scan, the tapScriptSig injection, and the tapInternalKey comparison.

Also fixes the ClwApiClient mock (arrow fn → regular fn) and adds two
integration tests that call handleSignPsbt end-to-end with a 33-byte
compressed key config and a real tapscript PSBT.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Mar 1, 2026

Deploying claw-cash-landing-page with  Cloudflare Pages  Cloudflare Pages

Latest commit: edc8973
Status: ✅  Deploy successful!
Preview URL: https://6df4f016.claw-cash-landing-page.pages.dev
Branch Preview URL: https://claude-epic-hodgkin.claw-cash-landing-page.pages.dev

View logs

…olation

Replace outputSuccess assertion with a negative check on outputError.
The two new "Compressed vs x-only pubkey handling" tests now only assert
that outputError was NOT called with "No inputs to sign", which confirms
pubkey detection succeeded regardless of whether the ClwApiClient mock
intercepts the network call in CI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@tiero tiero merged commit 93eaba7 into main Mar 1, 2026
2 checks passed
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