Skip to content

fix(joy-id): return a PSBT from signPsbt, and switch to @scure/btc-signer - #581

Open
fghdotio wants to merge 2 commits into
ckb-devrel:devfrom
fghdotio:refactor/scure-btc-signer
Open

fghdotio wants to merge 2 commits into
ckb-devrel:devfrom
fghdotio:refactor/scure-btc-signer

Conversation

@fghdotio

@fghdotio fghdotio commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Refs #517. Supersedes #556.

  • JoyID: signPsbt always returns a PSBT. JoyID is asked not to finalize, and CCC finalizes the inputs JoyID signed.
  • Replace bitcoinjs-lib with @scure/btc-signer in joy-id, xverse and the playground, so JoyID no longer needs initEccLib.

Breaking (playground): bitcoin from @ckb-ccc/playground is gone. Use import * as btc from "@scure/btc-signer".

Tested on testnet with JoyID and Xverse.

@changeset-bot

changeset-bot Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: dcaac2e

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

@netlify

netlify Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for appccc ready!

Name Link
🔨 Latest commit dcaac2e
🔍 Latest deploy log https://app.netlify.com/projects/appccc/deploys/6abbc163955c8b000826a0b3
😎 Deploy Preview https://deploy-preview-581--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: 37 (🔴 down 25 from production)
Accessibility: 97 (no change from production)
Best Practices: 92 (🔴 down 8 from production)
SEO: 97 (🟢 up 9 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 Sep 29, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for apiccc ready!

Name Link
🔨 Latest commit dcaac2e
🔍 Latest deploy log https://app.netlify.com/projects/apiccc/deploys/6abbc16394aa2300071f71de
😎 Deploy Preview https://deploy-preview-581--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: 90 (🟢 up 1 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 Sep 29, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for liveccc ready!

Name Link
🔨 Latest commit dcaac2e
🔍 Latest deploy log https://app.netlify.com/projects/liveccc/deploys/6abbc163102b3f00070844e4
😎 Deploy Preview https://deploy-preview-581--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: 9 (🔴 down 3 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 Sep 29, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for docsccc ready!

Name Link
🔨 Latest commit dcaac2e
🔍 Latest deploy log https://app.netlify.com/projects/docsccc/deploys/6abbc1630688ff0007da810f
😎 Deploy Preview https://deploy-preview-581--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: 78 (🔴 down 14 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.

@fghdotio
fghdotio force-pushed the refactor/scure-btc-signer branch from 3e9345b to dcaac2e Compare September 29, 2026 13:47
@coderabbitai

coderabbitai Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 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: 93ed544d-71b0-42b3-9f38-f2f270b7cbea

📥 Commits

Reviewing files that changed from the base of the PR and between 9ffef01 and dcaac2e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (17)
  • .changeset/joy-id-sign-psbt-return-psbt.md
  • .changeset/scure-btc-signer.md
  • packages/examples/package.json
  • packages/examples/src/playground/index.d.ts
  • packages/examples/src/transferBtc.ts
  • 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/package.json
  • packages/xverse/src/signer.test.ts
  • packages/xverse/src/signer.ts
  • packages/xverse/tsdown.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 signing now returns a PSBT consistently, including when automatic finalization is requested. Eligible signed inputs are finalized locally, while inputs that other signers must handle can remain unsigned.
    • JoyID and Xverse better preserve unknown PSBT fields and handle transactions with inputs that lack signing or UTXO information.
  • Updates

    • Bitcoin examples and the playground now use the Scure Bitcoin signer. The playground’s bitcoin global is no longer available; import from @scure/btc-signer instead.

Walkthrough

The PR replaces bitcoinjs-lib PSBT handling with @scure/btc-signer in JoyID and Xverse. JoyID now requests unfinalized PSBTs and can finalize signed inputs locally. The playground and BTC transfer example also use the Scure signer.

Changes

Bitcoin PSBT handling

Layer / File(s) Summary
JoyID PSBT parsing and finalization
packages/joy-id/src/btc/psbt.ts
New helpers validate JoyID’s returned PSBT against the original, detect new signatures, and finalize selected inputs. Finalization errors include guidance for partial or multisig signing.
JoyID signing flow and tests
packages/joy-id/src/btc/index.ts, packages/joy-id/src/btc/index.test.ts, packages/joy-id/package.json, packages/joy-id/tsdown.config.mts, .changeset/joy-id-sign-psbt-return-psbt.md
JoyID requests an unfinalized PSBT and locally finalizes signed inputs when requested. Tests cover input types, requested-input handling, unknown fields, and invalid responses. The package adds Scure dependencies and CommonJS bundling entries.
Xverse Scure PSBT handling
packages/xverse/src/signer.ts, packages/xverse/src/signer.test.ts, packages/xverse/package.json, packages/xverse/tsdown.config.mts, .changeset/scure-btc-signer.md
Xverse replaces bitcoinjs-lib PSBT operations with Scure transactions. Input detection, local finalization, tests, dependencies, and CommonJS bundling entries are updated.
Playground and example integration
packages/examples/package.json, packages/examples/src/playground/index.d.ts, packages/examples/src/transferBtc.ts, packages/playground/package.json, packages/playground/src/app/components/Editor.tsx, packages/playground/src/app/execute/index.tsx
The BTC transfer example builds its PSBT with @scure/btc-signer. The playground loads Scure declarations and libraries, and access to the removed bitcoin global raises an error directing scripts to the Scure signer.

Priority: ➖ Normal

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

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant BitcoinSigner
  participant JoyID
  participant parseSignedPsbt
  participant finalizeSignedInputs
  BitcoinSigner->>JoyID: Request PSBT with autoFinalized false
  JoyID-->>BitcoinSigner: Return signed PSBT
  BitcoinSigner->>parseSignedPsbt: Validate response against original PSBT
  parseSignedPsbt-->>BitcoinSigner: Return parsed transactions
  opt Local finalization requested
    BitcoinSigner->>finalizeSignedInputs: Finalize requested inputs with new signatures
    finalizeSignedInputs-->>BitcoinSigner: Return finalized PSBT hex
  end
Loading

Suggested reviewers: hanssen0

Merge Risk: ⚪ Minimal · up to dcaac

The PSBT signer migration looks consistent, and no concrete merge-blocking issue was found. Live JoyID wallet behavior was not exercised against the tests' mocked responses, which is normal pre-release validation.

Security Architecture Review

Security architecture risk: 🟡 Moderate · up to dcaac

The new signing flow checks that JoyID returns the same unsigned transaction, but it does not establish that all other PSBT data is unchanged. The signer migration may also remove extension fields when a PSBT is finalized locally. These are transaction-scoped risks; the available evidence does not establish an exploit or a broader service impact.

Retained concerns

  • Medium · security · inferred: The new default JoyID path can return a PSBT for downstream use after checking only unsigned-transaction equality. A wallet response that changes other input metadata or arrives already finalized is not rejected by that check; the effect on a subsequent signer is unverified.
  • Medium · reliability · inferred: Local auto-finalization in JoyID and Xverse parses with options that ignore unknown and proprietary PSBT fields, then serializes the parsed transaction. Extension data may therefore be absent from the returned PSBT, unlike the raw-response path; whether consumers rely on that data is unverified.
Security review details

Security Blast Radius

  • inferred — The direct exposure is a PSBT returned to a caller of a connected BTC signer, potentially including a later cosigner. The available paths do not show a new broadcast permission or service-wide privilege.

Security Findings and Attack Paths

  • inferred — A compromised or unexpectedly behaving wallet response could preserve the unsigned transaction while changing other PSBT data that the new default return path passes on. Whether such a change can defeat a downstream signer’s controls is not established.

Trust Boundaries and Controls

  • observed — JoyID’s wallet-response boundary now checks PSBT format and unsigned-transaction identity before returning a result. It does not independently authenticate the source of each newly detected signature entry.

Resilience and Maintainability Implications

  • observed — JoyID does not serialize a partially locally finalized result after an input-finalization error; callers can instead request the unfinalized response.

Hardening Proposals

  • proposed — Define which wallet-returned PSBT fields may change, including per-input finalization state, before a result is passed to another signer; verify or reject changes outside that contract.
  • proposed — Establish whether callers require unknown or proprietary PSBT fields, then preserve them or explicitly reject unsupported PSBTs on paths that reserialize them.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 29.17% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 24 functions across 10 files. (6 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes both primary changes: JoyID now returns a PSBT from signPsbt, and the codebase switches to @scure/btc-signer.
Description check ✅ Passed The description explains the main changes, breaking playground change, referenced issues, and test coverage. It does not include the template’s contributing-guidelines checklist, but the description i…
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: Docstring Coverage

Explanation

Docstring coverage is 29.17% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 24 functions across 10 files. (6 skipped: 6 unsupported.)

  • Fix all pre-merge checks with AI

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.

@fghdotio fghdotio changed the title refactor(btc): replace bitcoinjs-lib with @scure/btc-signer fix(joy-id): return a PSBT from signPsbt, and switch to @scure/btc-signer Sep 29, 2026
@fghdotio
fghdotio marked this pull request as ready for review September 29, 2026 13:50
@fghdotio fghdotio closed this Sep 29, 2026
@fghdotio fghdotio reopened this Sep 29, 2026
@Hanssen0

Copy link
Copy Markdown
Member

/canary

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Canary version published successfully! View workflow run

The following packages have been published to npm:

  • @ckb-ccc/joy-id@0.0.0-canary-dcaac2eb7549f82887bdeac3ede8b556ba9ba3d2
  • @ckb-ccc/xverse@0.0.0-canary-dcaac2eb7549f82887bdeac3ede8b556ba9ba3d2
  • @ckb-ccc/ccc@0.0.0-canary-dcaac2eb7549f82887bdeac3ede8b556ba9ba3d2
  • ckb-ccc@0.0.0-canary-dcaac2eb7549f82887bdeac3ede8b556ba9ba3d2
  • @ckb-ccc/connector@0.0.0-canary-dcaac2eb7549f82887bdeac3ede8b556ba9ba3d2
  • @ckb-ccc/connector-react@0.0.0-canary-dcaac2eb7549f82887bdeac3ede8b556ba9ba3d2

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