Skip to content

fix(btc): validate scure wallet PSBT responses - #605

Open
Hanssen0-Alter-Ego wants to merge 6 commits into
ckb-devrel:devfrom
Hanssen0-Alter-Ego:fix/scure-psbt-validation
Open

Hanssen0-Alter-Ego wants to merge 6 commits into
ckb-devrel:devfrom
Hanssen0-Alter-Ego:fix/scure-psbt-validation

Conversation

@Hanssen0-Alter-Ego

@Hanssen0-Alter-Ego Hanssen0-Alter-Ego commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Continues #581 by @fghdotio. Both original commits are preserved, with current dev merged at 02631e90; no rebase.

Changes

  • Validate JoyID and Xverse PSBT responses against the requested transaction, trusted metadata, signature hash modes, and caller policy, including partial-signing flows.
  • Preserve existing signatures and finalized inputs, with focused Taproot and bare-input compatibility fixes.
  • Bundle a shared private PSBT compatibility, validation, and finalization helper using stock scure 2.4.1 in ESM and CommonJS, with regression tests and a changeset.

Validation

  • 249 shared-helper and wallet-adapter tests passed; both adapters' typechecks, ESLint, and builds passed.
  • 218 assertions passed against built ESM/CommonJS artifacts.
  • Local validation used Node 24.19.0; full Node 26 repository CI passed build, lint, and 863 tests across 62 files on 747521a.

Generated by ChatGPT · Alter Ego

@changeset-bot

changeset-bot Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 654aa2b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@ckb-ccc/joy-id Patch
@ckb-ccc/xverse Patch
@ckb-ccc/ccc Patch
ckb-ccc Patch
@ckb-ccc/connector Patch
@ckb-ccc/connector-react Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

⛔ Files ignored due to path filters: 1
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 79ba54c5-a818-4331-9acf-0af6cefba99b
📥 Commits

Reviewing files that changed from the base of the PR and between 747521a and 654aa2b.

⛔ Files ignored due to path filters: 1
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ddd6a1f5-c740-45cc-adde-daec24daa468
📥 Commits

Reviewing files that changed from the base of the PR and between 02631e9 and 747521a.

⛔ Files ignored due to path filters: 1
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing: 33
  • .changeset/joy-id-sign-psbt-return-psbt.md
  • .changeset/scure-btc-signer.md
  • .changeset/secure-wallet-psbt-responses.md
  • package.json
  • packages/btc-psbt/README.md
  • packages/btc-psbt/eslint.config.mjs
  • packages/btc-psbt/package.json
  • packages/btc-psbt/prettier.config.cjs
  • packages/btc-psbt/src/compatibility.test.ts
  • packages/btc-psbt/src/index.test.ts
  • packages/btc-psbt/src/index.ts
  • packages/btc-psbt/tsconfig.json
  • packages/btc-psbt/vitest.config.mts
  • packages/examples/package.json
  • packages/examples/src/playground/index.d.ts
  • packages/examples/src/transferBtc.ts
  • packages/joy-id/README.md
  • packages/joy-id/package.json
  • packages/joy-id/src/btc/index.test.ts
  • packages/joy-id/src/btc/index.ts
  • packages/joy-id/src/btc/psbt.ts
  • packages/joy-id/tsdown.config.mts
  • packages/playground/package.json
  • packages/playground/src/app/components/Editor.tsx
  • packages/playground/src/app/execute/index.tsx
  • packages/xverse/README.md
  • packages/xverse/package.json
  • packages/xverse/src/signer.test.ts
  • packages/xverse/src/signer.ts
  • packages/xverse/tsdown.config.mts
  • pnpm-workspace.yaml
  • scripts/test-psbt-artifacts.mjs
  • vitest.config.mts
💤 Files with no reviewable changes: 1
  • packages/examples/src/playground/index.d.ts

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📝 Summary

Summary by CodeRabbit

  • Bug Fixes

    • JoyID now consistently returns a signed PSBT, including when automatic finalization is requested. Apps can extract the finalized transaction for broadcasting or use signAndBroadcastPsbt.
    • JoyID and Xverse now check that wallet responses match the original transaction and requested signing policies, helping prevent altered transactions or signatures from being accepted.
    • Signing preserves existing signatures and finalized inputs, supporting partial and multisignature workflows.
  • Documentation

    • Added guidance on PSBT validation, automatic finalization, Taproot signing, and cases that require application-managed finalization.

JoyID and Xverse now validate signed PSBT responses against the original transaction and selected inputs. Both adapters use local finalization for eligible inputs. The change adds a shared PSBT package, updates Bitcoin signer integrations in examples and the playground, and adds build-artifact tests to CI.

Changes: Bitcoin PSBT signing and validation

Layer / File(s) Summary
PSBT response validation and signature checks
packages/btc-psbt/src/index.ts, packages/btc-psbt/src/index.test.ts, packages/btc-psbt/README.md, packages/btc-psbt/package.json, packages/btc-psbt/*config*, vitest.config.mts
The shared package validates input selections, binds wallet responses to the original transaction and trusted metadata, checks signatures and sighash modes, and verifies Taproot key-path signatures. Tests cover PSBTv0/v2 cases and these validation rules.
PSBT compatibility and staged finalization
packages/btc-psbt/src/index.ts, packages/btc-psbt/src/compatibility.test.ts, packages/btc-psbt/src/index.test.ts
WalletPsbt adds compatibility validation for recognized bare scripts and incomplete Taproot tree metadata. It validates inputs before serialization and stages finalization before committing changes.
JoyID and Xverse signing flows
packages/joy-id/src/btc/*, packages/xverse/src/signer*, packages/joy-id/README.md, packages/xverse/README.md, packages/joy-id/package.json, packages/xverse/package.json, packages/joy-id/tsdown.config.mts, packages/xverse/tsdown.config.mts
Both adapters validate wallet responses before returning them. When automatic finalization is enabled, they locally finalize eligible inputs. Adapter tests cover selected inputs, partial signatures, metadata, and invalid responses.
scure signer in examples and playground
packages/examples/package.json, packages/examples/src/transferBtc.ts, packages/examples/src/playground/index.d.ts, packages/playground/package.json, packages/playground/src/app/*
The Bitcoin transfer example and playground use @scure/btc-signer instead of bitcoinjs-lib. The playground directs legacy bitcoin imports to the new package.
Build outputs and artifact validation
scripts/test-psbt-artifacts.mjs, package.json, pnpm-workspace.yaml, .changeset/*
The artifact test checks JoyID and Xverse ESM and CommonJS builds and exercises their PSBT signing flows. CI runs the test, and changesets record patch releases for both adapters.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~60 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant JoyIDSigner
  participant JoyID
  participant BTCPSBT
  participant LocalFinalizer
  Caller->>JoyIDSigner: Submit PSBT and signing options
  JoyIDSigner->>BTCPSBT: Validate input selection
  JoyIDSigner->>JoyID: Request an unfinalized PSBT
  JoyID-->>JoyIDSigner: Return signed PSBT
  JoyIDSigner->>BTCPSBT: Validate response against original PSBT
  BTCPSBT-->>JoyIDSigner: Return validated PSBT
  JoyIDSigner->>LocalFinalizer: Finalize eligible inputs when requested
  LocalFinalizer-->>JoyIDSigner: Return finalized PSBT
  JoyIDSigner-->>Caller: Return PSBT
Loading
Merge Risk: ⚪ Minimal · up to 74752

JoyID and Xverse now check signed Bitcoin PSBT responses against the original request before returning or finalizing them. JoyID now always returns a PSBT, as the signer interface documents. No concrete defect remains open, and the change appears ready to merge after normal checks.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 21.43% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 84 functions across 22 files. (14 skipped… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: validation of scure wallet PSBT responses.
Description check Passed The description clearly covers the changes, validation results, and related context. It omits the template checkbox confirming that the Contributing Guidelines were read, but the description is otherw…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description clearly covers the changes, validation results, and related context. It omits the template checkbox confirming that the Contributing Guidelines were read, but the description is otherwise complete and relevant.

Full details: Docstring Coverage

Explanation

Docstring coverage is 21.43% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 84 functions across 22 files. (14 skipped: 14 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@netlify

netlify Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for appccc ready!

Name Link
🔨 Latest commit 654aa2b
🔍 Latest deploy log https://app.netlify.com/projects/appccc/deploys/6ad3d52ebf220d2551fdbc9b
😎 Deploy Preview https://deploy-preview-605--appccc.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 38 (🔴 down 24 from production)
Accessibility: 98 (🟢 up 1 from production)
Best Practices: 92 (🔴 down 8 from production)
SEO: 99 (🟢 up 11 from production)
PWA: -
View the detailed breakdown and full score reports
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for liveccc ready!

Name Link
🔨 Latest commit 654aa2b
🔍 Latest deploy log https://app.netlify.com/projects/liveccc/deploys/6ad3d52e5a797162bee7a67a
😎 Deploy Preview https://deploy-preview-605--liveccc.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 11 (🔴 down 1 from production)
Accessibility: 88 (no change from production)
Best Practices: 92 (🔴 down 8 from production)
SEO: 100 (no change from production)
PWA: -
View the detailed breakdown and full score reports
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for apiccc ready!

Name Link
🔨 Latest commit 654aa2b
🔍 Latest deploy log https://app.netlify.com/projects/apiccc/deploys/6ad3d52e307d004ba2a665a7
😎 Deploy Preview https://deploy-preview-605--apiccc.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 84 (🔴 down 5 from production)
Accessibility: 100 (no change from production)
Best Practices: 100 (no change from production)
SEO: 95 (no change from production)
PWA: -
View the detailed breakdown and full score reports
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for docsccc ready!

Name Link
🔨 Latest commit 654aa2b
🔍 Latest deploy log https://app.netlify.com/projects/docsccc/deploys/6ad3d52ec33cbf726ca7f557
😎 Deploy Preview https://deploy-preview-605--docsccc.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 77 (🔴 down 15 from production)
Accessibility: 95 (no change from production)
Best Practices: 92 (🔴 down 8 from production)
SEO: 75 (no change from production)
PWA: -
View the detailed breakdown and full score reports
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@Hanssen0-Alter-Ego Hanssen0-Alter-Ego left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One P2 finding in the inline comment.

Generated by ChatGPT · Alter Ego

Comment thread packages/xverse/src/signer.ts Outdated
@Hanssen0-Alter-Ego
Hanssen0-Alter-Ego marked this pull request as ready for review October 16, 2026 19:25
@Hanssen0-Alter-Ego
Hanssen0-Alter-Ego force-pushed the fix/scure-psbt-validation branch 2 times, most recently from 469780e to 747521a Compare October 17, 2026 15:17
@Hanssen0-Alter-Ego

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
✅ Action performed

Full review finished.

…ion-recovery

# Conflicts:
#	packages/playground/package.json
#	pnpm-lock.yaml
Bind wallet responses to the requested transaction and signature policy,
including finalizer public-key binding. Share encapsulated stock-scure
compatibility and finalization across both adapters while preserving
their transport and input-selection policies. Add core regression coverage.
Add parser acceptance and lifecycle regressions plus ESM/CommonJS
artifact checks for both adapters. Cover wrong-key rejection, partial
returns, wrapper types, and PSBT v0/v2 with nonzero input indexes.
Run the artifact harness from the repository CI test command.
Explain the shared private helper, stock-scure compatibility, signature
validation, and adapter-specific finalization policies. Add the wallet
validation changeset.
@Hanssen0-Alter-Ego
Hanssen0-Alter-Ego force-pushed the fix/scure-psbt-validation branch from 747521a to 654aa2b Compare October 17, 2026 20:06
@Hanssen0-Alter-Ego

Copy link
Copy Markdown
Contributor Author

@coderabbitai resume

Generated by ChatGPT · Alter Ego

@coderabbitai

coderabbitai Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

@Hanssen0-Alter-Ego I’ll resume automatic reviews for this PR.

⚠️ Action not completed

No files to review.

This branch has not been deployed

No deployments
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.

2 participants