Skip to content

feat(react): quorum-aware recovery handling in wallet providers - #2000

Open
panosinthezone wants to merge 3 commits into
panos/wal-11292-m4-4-sdk-quorum-aware-recovery-identity-usesignerfrom
panos/wal-11294-m4-6-sdk-react-react-native-provider-audit-for-quorum
Open

feat(react): quorum-aware recovery handling in wallet providers#2000
panosinthezone wants to merge 3 commits into
panos/wal-11292-m4-4-sdk-quorum-aware-recovery-identity-usesignerfrom
panos/wal-11294-m4-6-sdk-react-react-native-provider-audit-for-quorum

Conversation

@panosinthezone

Copy link
Copy Markdown
Contributor

Description

M4-6 of the quorum recovery milestone: audits the React / React Native providers for the create-side quorum recovery widening (WAL-11290) and fixes every check that assumed a flat single-signer recovery. Stacked on the M4-4 stack (#1997#1998#1999#1996).

All five flat-recovery checks now descend into quorum methods via a new shared recoverySigners helper in react-base:

  1. RN WebView init (initializeWebViewIfNeeded): a quorum containing an email/phone member now boots the hidden signer WebView before wallet creation — previously it never initialized and creation crashed with "WebView not ready or handshake incomplete". Resolves the TODO(WAL-11294) left by M4-4. Member-aware: an all-external-wallet quorum still skips the WebView.
  2. RN passkey guard: a passkey member hidden inside recovery.methods is now rejected with the same clear PASSKEY_RN_ERROR as a flat passkey recovery (both the mount-time check and createWallet).
  3. Email auto-population: a quorum email member missing its email is auto-filled from the logged-in user — only when exactly one email member is incomplete; filling several with the same address would create duplicate members (which the API rejects), so those configs pass through and validation surfaces the real problem.
  4. External-wallet address guard: wallet creation now also waits when an external-wallet quorum member lacks an address (previously create fired prematurely).
  5. Web passkey helper UI: shows for a passkey quorum member, not just a flat passkey recovery.

Verification-only findings (no code needed): the OTP / onAuthRequired flow is already recovery-shape-agnostic — it keys off the active signer instance's (type, locator), and the device-signer-while-recovering fallback (activeAuthEmail/activeAuthPhone) already covers a quorum member driving OTP. Known limitation flagged for M4-7: useSignerAuth holds a single set of send/verify/reject refs, so two members needing OTP concurrently would clobber — unreachable at launch (threshold = 1).

Docs: quorum recovery examples in the react-ui / react-native / wallets READMEs (RN notes that passkey quorum members are rejected), examples.json snippets, and the reference generator's recovery fallback now renders RecoveryConfigForChain with quorum prose.

Test plan

  • New quorum-recovery.test.ts in react-base: recoverySigners flat/quorum/undefined, recoveryNeedsEmailAutoFill exactly-one semantics, fillRecoveryEmail fill/no-mutation/pass-through cases. Full react-base suite: 23 pass.
  • RN provider test wiring deferred to M4-7 (package has no vitest script yet).
  • tsc --noEmit for react-base, react-ui, react-native: 0 errors in src (only pre-existing env noise).
  • Biome clean on changed files.
  • Changeset: minor for @crossmint/client-sdk-react-base and @crossmint/client-sdk-react-native-ui.

Checklist

  • Run mainonly E2E tests (these tests always run in the merge queue regardless of this checkbox).

🤖 Generated with Claude Code

panosinthezone and others added 3 commits July 29, 2026 10:56
…e round-trip

The API cannot store runtime member data (server secret, external-wallet
onSign, passkey callbacks), so createWallet now grafts each user-provided
quorum method onto the API member it identifies, with API identity fields
winning. API members with no matching method pass through verbatim.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… held member

useSigner now resolves a config against the wallet's quorum members and
assembles the matched member as an admin signer under its API locator, with
an optional { quorumLocator } to force the member interpretation. Device-signer
recovery reuses a member previously selected this session, replacing the last
QuorumSignerNotSupportedError guards with working flows or actionable errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
All provider recovery checks now descend into quorum members: RN WebView
init, RN passkey rejection, web passkey helpers, email auto-population
(exactly-one rule), and the external-wallet address guard. Documents the
quorum recovery form in READMEs and the reference generator.

WAL-11294

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Jul 29, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 2ab673a

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

This PR includes changesets to release 8 packages
Name Type
@crossmint/client-sdk-react-base Minor
@crossmint/client-sdk-react-native-ui Minor
@crossmint/client-sdk-react-ui Patch
@crossmint/wallets-playground-expo Patch
@crossmint/auth-ssr-nextjs-demo Patch
@crossmint/client-sdk-nextjs-starter Patch
@crossmint/wallets-quickstart-devkit Patch
@crossmint/wallets-playground-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

@panosinthezone panosinthezone self-assigned this Jul 29, 2026
@greptile-apps

greptile-apps Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "feat(react): quorum-aware recovery handl..." | Re-trigger Greptile

@panosinthezone panosinthezone changed the title feat(react): quorum-aware recovery handling in wallet providers (WAL-11294) feat(react): quorum-aware recovery handling in wallet providers Jul 29, 2026
@panosinthezone
panosinthezone force-pushed the panos/wal-11292-m4-4-sdk-quorum-aware-recovery-identity-usesigner branch from 87e7fca to 186a28a Compare July 30, 2026 20:43
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.

1 participant