Repository navigation
fix(wallets): addSigner and addRecoveryMethod create the passkey when the config has none - #2275
Open
albertoelias-crossmint wants to merge 4 commits into
Open
albertoelias-crossmint wants to merge 4 commits into
albertoelias-crossmint wants to merge 4 commits into
Conversation
…n the config has none
`wallet.addSigner({ type: "passkey" })`, as the add-signers guide shows, never created a
credential: the SDK looked up signer locator "passkey" (400, "Invalid address: passkey") and
then sent the bare config, which the API rejects (`signer: Invalid input`, wallet:signer-invalid).
A passkey config without a credential id is now created first, with the config's
onCreatePasskey, else the wallet's passkeyProvider, else WebAuthn (the same order wallet
creation uses, now shared through createPasskeyCredential). The pre-registration signer
lookup is skipped for a passkey created in the call. addRecoveryMethod does the same and keeps
the created credential in the wallet's recovery methods. Configs with an id are unchanged,
and the passkey request body now carries only type, id, name and publicKey.
🦋 Changeset detectedLatest commit: 7f0dce0 The changes in this PR will be included in the next version bump. This PR includes changesets to release 10 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 |
Contributor
[Medium impact] The PR appears safe to merge; no actionable defects were found. Reviews (1) · Last reviewed commit: "docs(wallets): shorten passkey registrat..." · Reviewed by Greptile |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Problem
A developer who follows the docs and calls
wallet.addSigner({ type: "passkey" }), orwallet.addRecoveryMethod({ type: "passkey" }), never gets a passkey prompt. The SDK looks up a signer literally namedpasskeyand posts the bare config. The API answerssigner: Invalid input: expected string, received object, which says nothing about the real cause: the request carries no credential id and no public key.The only way around it today is to know that
createPasskeySignerhas to run first, then pass its result back in by hand.wallet.createalready creates the passkey for you, so the two entry points behave differently for the same config.What this PR does
id, nopasskey:{id}locator),addSignerandaddRecoveryMethodcreate the credential first, then register its id and public key.onCreatePasskey, else the wallet'spasskeyProvider, else the browser WebAuthn API. The same code now backswallet.create(moved, not changed).type,id,name,publicKey), no callbacks or locator.flowchart LR subgraph Before A1["addSigner({ type: passkey })"] --> C1["POST bare config"] --> D1["signer: Invalid input"] end subgraph After A2["addSigner({ type: passkey })"] --> B2["create passkey (callback, provider or browser)"] --> C2["POST id + publicKey"] --> D2["pending approval"] endResult
addSigner({ type: "passkey" })signer: Invalid input: expected string, received objectaddRecoveryMethod({ type: "passkey" })createPasskeySigner, thenaddSignerwith its output)Unchanged: a config that already has
id(or apasskey:{id}locator) registers as before;wallet.createbehaviour; public types (PasskeySignerConfiggains an optionalpublicKey,SignerDescriptoran optionalprepareRegistration).What to check when reviewing
signers/descriptors/passkey.ts:prepareRegistrationand the narroweraddSignerPayload. A config with an id but no public key is still sent as given, so the API reports it.wallets/wallet.ts(addSigner,addRecoveryMethod): the passkey is created after the approver is resolved, so a failed approver lookup does not leave an unused passkey.signers/passkey-credential.tsis the code lifted out ofwallet-factory.ts.navigator.credentials.create(Safari) may reject it; callers that hit this can keep callingcreatePasskeySignerfrom the click handler and pass its result, which still works unchanged.wallet.tsandwallet-factory.ts. This PR touchesaddSigner,addRecoveryMethodandcreatePasskeySigner's body only; expect small textual conflicts, no behavioural ones. Nothing in those PRs creates passkeys.Test plan
pnpm --filter @crossmint/wallets-sdk test:vitest: 772 tests pass.src/api/client.test.tsneedsPREVIEW_CK_KEYand was not run locally; it does not touch this code.prepareRegistrationkeeps configs with an id, creates via callback, provider and browser;addSignerPayloadfields) and wallet (addSignerandaddRecoveryMethodcreate and register, and register nothing when the prompt is cancelled). All 11 new tests fail when the source change is reverted and the tests are kept.pnpm biome checkon the changed files andpnpm --filter @crossmint/wallets-sdk buildpass.Package updates
@crossmint/wallets-sdkpatch changeset (.changeset/passkey-add-signer-creates-credential.md)Checklist
Rollback
Revert the commit; no state or schema is written. Passkeys already registered through this path stay valid.
Closes WAL-13395
🤖 Generated with Claude Code