wallets: fall back to recovery signer when multiple delegated signers exist#1752
wallets: fall back to recovery signer when multiple delegated signers exist#1752devin-ai-integration[bot] wants to merge 1 commit into
Conversation
…signers Co-Authored-By: Agus <agustin@paella.dev>
Original prompt from Agus
|
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
🦋 Changeset detectedLatest commit: c3927e4 The changes in this PR will be included in the next version bump. This PR includes changesets to release 8 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 |
Important Files Changed
Prompt To Fix All With AIThis is a comment left during a code review.
Path: packages/wallets/src/wallets/wallet.ts
Line: 171-188
Comment:
**Duplicated recovery signer logic**
The 0-signers case (lines 172-174) and the >1-signers case (lines 186-187) now perform identical logic: build the recovery signer config and assemble it. Consider consolidating them to reduce duplication:
```suggestion
if (this.#initialSigners.length === 1) {
// Exactly 1 auto-assemblable signer → use it
const internalConfig = this.buildInternalSignerConfig(this.#initialSigners[0]);
this.#signer = await this.assembleFullSigner(internalConfig);
} else {
// 0 or >1 signers → fall back to recovery signer so the wallet remains usable.
// Users who need a specific delegated signer can call useSigner() to override.
if (this.#initialSigners.length > 1) {
walletsLogger.info("wallet.initDefaultSigner.multipleSignersFallbackToRecovery", {
signerCount: this.#initialSigners.length,
recoveryType: this.#recovery.type,
});
}
const internalConfig = this.buildInternalSignerConfig(this.#recovery);
this.#signer = await this.assembleFullSigner(internalConfig);
}
```
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "fix: fall back to recovery signer when w..." | Re-trigger Greptile |
Description
Fixes a bug where wallets with more than one delegated signer become completely unusable for signing operations (
approve,send, etc.).After the wallets-v1 merge (#1721),
initDefaultSignerwas intentionally leaving#signerundefined when >1 delegated signers existed, expecting the consumer to callwallet.useSigner(). However, client-side consumers like lobster.cash useuseWallet()→wallet.approve()directly and never calluseSigner(). This causes the error:This surfaces in lobster.cash when a user tries to set up a second agent — the first agent adds a delegated signer, and the second adds another, putting the wallet into the >1 signers state.
The fix: In the >1 signers case, fall back to the recovery signer (same behavior as the 0-signers case). The recovery signer represents the wallet owner and is the safest default.
useSigner()still works as an explicit override.Key things for review
Test plan
wallet.test.tssuite passes (50 tests)@crossmint/wallets-sdktests pass (258 passed, 68 skipped)pnpm lintpasses cleanlyrequireSigner()(line 1102) is only reachable when#signeris null AND >1 initial signers — this fix ensures#signeris set via recovery in that casePackage updates
@crossmint/wallets-sdk— patch changeset added via.changeset/fix-multi-signer-recovery-fallback.mdLink to Devin session: https://crossmint.devinenterprise.com/sessions/262eeb98fa3f4f1ebae9ba85728721da
Requested by: @aigustin