feat(core): multisig Signers#349
Conversation
🦋 Changeset detectedLatest commit: ad03855 The changes in this PR will be included in the next version bump. This PR includes changesets to release 20 packages
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 |
✅ Deploy Preview for liveccc ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for apiccc ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for docsccc ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Summary of ChangesHello @Hanssen0, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the core library by introducing robust support for CKB multisig transactions. It provides new abstract and concrete signer classes, refactors existing signing mechanisms for better modularity, and improves transaction witness argument handling. The changes aim to make multisig operations more accessible and reliable for developers, complete with illustrative examples. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces multisig signer capabilities, which is a significant feature. The changes include new SignerMultisigCkbPrivateKey and SignerMultisigCkbReadonly classes, along with a new SignerMultisig abstract class. The implementation looks mostly correct, but I've found a few issues:
- A critical bug in
getSignaturesCountthat would cause incorrect signature counting. - A misleading example in
transaction.tsfor a new method. - Some minor issues like a
console.logand an incorrect error message. - I've also pointed out a potential API inconsistency in one of the new example files.
Please address these points to improve the quality and correctness of the code. Overall, good work on adding this complex feature.
✅ Deploy Preview for appccc ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
2d37e11 to
7e47bbe
Compare
|
Related to #196 @ashuralyk, please review. |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a significant feature: support for multisig signers in @ckb-ccc/core. It also includes a major dependency upgrade for @noble packages and a migration of the build system to tsdown. The core logic for creating, signing, and aggregating multisig transactions is well-implemented, and the refactoring to accommodate the new dependency versions is clean. My review includes a few suggestions to improve type safety and error message clarity.
7e47bbe to
5cd022e
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces significant new functionality by adding multisig signer support for CKB, a major feature for the core package. It also includes a substantial dependency upgrade for all @noble packages to their latest major versions and a migration of the build system to tsdown. The implementation of the multisig feature is well-structured, separating read-only and private key signing logic, and is accompanied by new tests and examples. The breaking changes from the dependency upgrades seem to be handled correctly throughout the codebase. My review includes a few suggestions to enhance maintainability and correct a minor documentation error.
5cd022e to
858410d
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces significant new functionality for multisig signers in the core package, which is a valuable addition. The implementation is well-structured, with clear abstractions for multisig signers and thorough handling of CKB-specific multisig logic, including witness encoding, signature aggregation, and transaction preparation.
The PR also includes a major version bump for @noble dependencies, and the necessary code adaptations for the new APIs are correctly implemented across the affected modules. The migration of the build process to tsdown is a good modernization step.
I have one suggestion for a minor refactoring to reduce code duplication. Overall, this is a high-quality contribution with good test coverage and examples for the new features.
87e10d9 to
a137473
Compare
| * @param txs - The transactions to aggregate. | ||
| * @returns The aggregated transaction. | ||
| */ | ||
| async aggregateTransactions(txs: TransactionLike[]): Promise<Transaction> { |
There was a problem hiding this comment.
What's the scenario for calling transactions aggregation?
There was a problem hiding this comment.
The scenario comes from the current ckb-cli usage. First, one transaction constructor builds the original transaction, then distributes it to others by email/IM. After everybody signs their transaction, respectively, and sends them back to the constructor/aggregator, they merge/finalise the transactions into a final one so that they can send it to the blockchain.
|
I've skimmed all code and tried examples relating to Multisig feature in native running Playground that all of them are passed the trial, and code in this PR conforms all items of merging criteria, so I'll give my approval to it. |
| for (const txLike of txs) { | ||
| const tx = Transaction.from(txLike); | ||
| const multisigWitness = this.decodeWitnessArgsAt(tx, info.position); | ||
|
|
||
| if (!multisigWitness) { | ||
| continue; | ||
| } | ||
|
|
||
| for (const sig of multisigWitness.signatures) { | ||
| try { | ||
| signatures.set(recoverMessageSecp256k1(info.message, sig), sig); | ||
| } catch (_) { | ||
| // Ignore invalid signatures | ||
| } | ||
| if (signatures.size >= this.multisigInfo.threshold) { | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| if (signatures.size >= this.multisigInfo.threshold) { | ||
| break; | ||
| } | ||
| } |
There was a problem hiding this comment.
As I understand it, the aggregation logic here doesn't take mustMatch into consideration. The process stops immediately when threshold is met. The must match part might be ignored. Could you please clarify this?
|
Hey @Hanssen0! We're integrating CKB into Rosen Bridge and we are considering Omnilock with multisig auth (flag 0x06) for bridge custody. The witness layout is identical to the standalone multisig script, just wrapped in an OmniLockWitnessLock molecule envelope. Looking at your multisig signers, I noticed the Omnilock variant would duplicate ~46% of SignerMultisigCkbReadonly. The only real differences are:
I put together a refactoring that extracts a shared Branch here: #360 (single commit on top of this PR) What's your take? Phroi |
|
After completing the guard-signing comparison, we are leaning towards ECDSA TSS over Omnilock multisig for the Rosen Bridge CKB integration. Details in the #360 closing comment. Hopefully that multisig signer refactoring in that PR will be still useful for other Omnilock users, |
d4a3188 to
4c20867
Compare
|
The |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces CKB multisig signers (SignerMultisigCkbPrivateKey, SignerMultisigCkbReadonly, and MultisigCkbWitness) along with corresponding tests, examples, and documentation. It also upgrades @noble packages to v2 across the workspace, transitions the core package build system to tsdown, and adds Transaction.getWitnessArgsAtUnsafe. The review feedback highlights several critical improvements: resolving a logical bug in multisig transaction signing that can append redundant signatures, adding a length guard check to prevent runtime crashes during witness decoding, utilizing the new hashCkbShort helper to clean up manual slicing, and normalizing recovery bits (v) to ensure compatibility with Ethereum-compatible wallets.
4c20867 to
ef773e2
Compare
|
/gemini review |
ef773e2 to
ba8ad01
Compare
There was a problem hiding this comment.
Code Review
This pull request introduces multisig signers, relaxes @ccc.codec's type restrictions, adds Transaction.getWitnessArgsAtUnsafe, and upgrades @noble dependencies to v2 while migrating the build system to tsdown. The code review highlights critical compatibility issues resulting from the @noble/curves v2 upgrade. Specifically, secp256k1.sign now returns a Signature object rather than a Uint8Array, which will cause runtime errors when calling .slice or accessing array indices in both CKB and Dogecoin signing implementations. Furthermore, secp256k1.verify and secp256k1.recoverPublicKey now require compact 64-byte signatures and recovery bits as separate arguments instead of accepting 65-byte signatures directly.
We didn't check if adding the last flexible signature letting us met the threshold, causing an edge case with excess flexible signatures.
ba8ad01 to
ad03855
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces CKB multisig signers (SignerMultisigCkbReadonly and SignerMultisigCkbPrivateKey), updates @noble cryptographic dependencies to version 2.x, and migrates the build process to tsdown. A critical correctness issue was identified in the multisig signing logic, where signatures are appended without being sorted in the same order as their corresponding public key hashes, which will cause on-chain verification to fail.

This PR should be reviewed one by one according to the commits.