Skip to content

feat: merge wallets-v1 into main#1721

Merged
albertoelias-crossmint merged 103 commits intomainfrom
devin/1774053734-merge-wallets-v1-into-main
Mar 21, 2026
Merged

feat: merge wallets-v1 into main#1721
albertoelias-crossmint merged 103 commits intomainfrom
devin/1774053734-merge-wallets-v1-into-main

Conversation

@albertoelias-crossmint
Copy link
Collaborator

@albertoelias-crossmint albertoelias-crossmint commented Mar 21, 2026

Description

Merges the wallets-v1 feature branch into main, resolving all 47 merge conflicts. This brings in the new wallet architecture where device signers become the default operational signer and the API shifts from a single signer parameter to a recovery + signers[] pattern.

Key changes from wallets-v1:

  • BREAKING: signer removed from WalletArgsFor/WalletCreateArgs; recovery is now required on WalletCreateArgs
  • BREAKING: Removed assembleSigner, onChangeSigner, getOrCreateWallet from public API
  • Renamed SignerSignerAdapter, experimental_signersigner, GetActivityResponseGetTransfersResponse, DelegatedSignerInputSignerInput
  • ServerSignerLocator is now a branded type (not plain string)
  • Added device signer support (DeviceInternalSignerConfig, DeviceSignerKeyStorage, auto-registration)
  • Added external wallet registration support
  • Removed toInternalSignerConfig in favor of a simpler createWalletInstance that preserves user-provided recovery/signer configs
  • Numerous bug fixes (TEE double-init, passkey publicKey, server recovery addSigner, etc.)

Conflict resolution strategy:

  • Source code (packages/wallets/src/): wallets-v1's approach preferred for all naming, types, and implementation patterns
  • Version files (CHANGELOG.md, package.json): wallets-v1 versions kept
  • pnpm-lock.yaml: regenerated via pnpm install

Post-merge fixes:

  • Removed duplicate case "server" merge artifact in assembleSigner (packages/wallets/src/signers/index.ts) — both wallets-v1 and main had this case, resulting in dead code after merge
  • Memoized renderUI in CrossmintWalletProvider (packages/client/ui/react-ui/src/providers/CrossmintWalletProvider.tsx) — createRenderWebUI() was called inline in JSX, creating a new function reference on every render
  • Removed .changeset/pre.json (stale pre-release mode file from wallets-v1)
  • Fixed React Native README (packages/client/ui/react-native/README.md) — replaced stale headlessSigningFlow references with the current prop name showOtpSignerPrompt, and corrected default-value documentation to match the code (showOtpSignerPrompt defaults to true, meaning OTP dialogs are shown by default)

🔍 Human review checklist:

  • wallet-factory.ts — most complex merge (8 conflict regions); verify createWallet (recovery + signers pattern) and validateSigners / isMatchingPasskeySigner logic are correct
  • wallets/types.ts — confirm SignerInput replaces DelegatedSignerInput consistently, no stale DelegatedSigner references
  • api/types.tsGetNftsResponse was intentionally dropped (unused); verify no runtime references exist
  • signers/types.ts — duplicate ServerInternalSignerConfig removed; InternalSignerConfig union includes DeviceInternalSignerConfig
  • signers/index.ts — verify no other duplicate case branches remain in assembleSigner switch after merge artifact cleanup
  • CHANGELOG/package.json versions — bulk-resolved with --ours; spot-check a few for correctness

Test plan

  • All existing vitest tests pass (258 passed, 68 skipped across 10 test suites)
  • pnpm lint passes cleanly (Biome, 835 files checked)
  • pnpm build:libs succeeds (17 packages built)
  • wallet-factory tests cover the new recovery + signers creation pattern
  • CI passes (build & test, lint, smoke tests)

Package updates

Multiple changesets already included from the wallets-v1 branch (see .changeset/ files). Key version bumps:

  • @crossmint/wallets-sdk: major (breaking API changes)
  • @crossmint/client-sdk-react-base: major (breaking API changes)
  • @crossmint/expo-device-signer: minor (device name support)
  • @crossmint/common-sdk-base: patch (address validation)

No additional pnpm change:add needed — all changesets were authored on the wallets-v1 branch. .changeset/pre.json was removed as it is a stale pre-release mode artifact.

Link to Devin session: https://crossmint.devinenterprise.com/sessions/af280747ba884a5ca8ce503d4af29529
Requested by: @albertoelias-crossmint


Open with Devin

guilleasz-crossmint and others added 30 commits October 21, 2025 00:36
…1454)

* feat: add onCreateConfig support to separate admin and usage signers

- Add OnCreateConfig<C> type to wallets SDK types
- Update WalletArgsFor<C> to include optional onCreateConfig field
- Modify WalletFactory.createWallet() to use onCreateConfig admin signer when provided
- Update validateExistingWalletConfig() to validate onCreateConfig parameters
- Add validateSignerCanUseWallet() helper to ensure signer can use wallet
- Add getSignerLocator() helper for determining signer locators
- Remove server-side restriction from getWallet() method
- Add comprehensive tests for onCreateConfig functionality
- Update React Base SDK to export OnCreateConfig and support getWallet
- Implement getWallet() in CrossmintWalletBaseProvider
- Update getOrCreateWallet() to pass through onCreateConfig
- Export OnCreateConfig type from React UI SDK

This allows delegated signers to use the SDK by separating the concept of
admin signer (who creates/owns the wallet) from usage signer (who interacts
with it).

Co-Authored-By: Guille <guille.a@paella.dev>

* fix: export OnCreateConfig and fix getChainType access

- Export OnCreateConfig from wallets SDK index
- Inline chainType logic in CrossmintWalletBaseProvider instead of accessing private method

Co-Authored-By: Guille <guille.a@paella.dev>

* refactor: remove args.delegatedSigners field (BREAKING CHANGE)

Breaking changes:
- Remove delegatedSigners field from WalletArgsFor type
- Remove delegatedSigners field from CreateOnLogin type
- delegatedSigners now ONLY exist within onCreateConfig

When onCreateConfig is provided:
- args.signer = the signer that will USE the wallet (can be admin or delegated)
- onCreateConfig.adminSigner = the admin who OWNS the wallet (only for creation)
- onCreateConfig.delegatedSigners = delegated signers (only for creation)

When onCreateConfig is NOT provided (backward compat):
- args.signer acts as BOTH the admin and usage signer

Updated:
- WalletFactory validation logic to handle both cases
- React providers to not pass delegatedSigners
- Tests to only use onCreateConfig for delegated signers

Co-Authored-By: Guille <guille.a@paella.dev>

* feat: make onCreateConfig required via WalletCreateArgs type

- Created WalletCreateArgs type that extends WalletArgsFor with required onCreateConfig
- Updated getOrCreateWallet and createWallet to use WalletCreateArgs
- Updated CreateOnLogin type to use WalletCreateArgs
- Made onCreateConfig optional in WalletArgsFor for getWallet use cases
- args.signer is now always the usage signer, not the admin signer

Co-Authored-By: Guille <guille.a@paella.dev>

* chore: fix lint issues

Co-Authored-By: Guille <guille.a@paella.dev>

* chore: update demo apps to use onCreateConfig

- Updated smart-wallet/next, quickstart-devkit, and expo apps
- All createOnLogin usages now include onCreateConfig with adminSigner
- Delegated signers moved from top-level to onCreateConfig

Co-Authored-By: Guille <guille.a@paella.dev>

* fix: correctly mutate signer in validateExistingWalletConfig

- Create tempArgs to capture mutation from mutateSignerFromCustomAuth
- Reassign expectedAdminSigner from mutated tempArgs.signer
- Ensures external wallet signer reassignment is captured correctly

Co-Authored-By: Guille <guille.a@paella.dev>

* fix: correctly mutate adminSignerConfig in createWallet

- Create tempArgs to capture mutation from mutateSignerFromCustomAuth
- Reassign adminSignerConfig from mutated tempArgs.signer
- Ensures external wallet signer reassignment works correctly

Co-Authored-By: Guille <guille.a@paella.dev>

* remove unnecesary type

* reuse common functionality from get and create

* remove redundant comments

* fix tsc issue

* fix linter

* added client side specific get wallet

* fix signers and transactions

* fix delegated signer

* remove redundant check

* fix unit test

* make oncreateconfig optional

* remove unnecesary format changes

* unify getWallet functionality

* remove admin from name

* fix react provider

* remove unnecessary types

* remove optional param

* refactor: replace 'as any' with custom SmartWalletConfig type

- Create SmartWalletConfig type to properly type wallet.config
- Replace all 'as any' casts with SmartWalletConfig type
- Improve error message clarity by avoiding 'args' in developer-facing text
- Addresses PR feedback from Alberto

Co-Authored-By: Guille <guille.a@paella.dev>

* fix: format error message to meet line length requirements

Co-Authored-By: Guille <guille.a@paella.dev>

* add passkey logic to delegate signer comparison

* fix wallet with multiple passkey signers

* remove console.log

* appplied albertos comment

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ers (#1458)

* feat: add onCreateConfig support to separate admin and usage signers

- Add OnCreateConfig<C> type to wallets SDK types
- Update WalletArgsFor<C> to include optional onCreateConfig field
- Modify WalletFactory.createWallet() to use onCreateConfig admin signer when provided
- Update validateExistingWalletConfig() to validate onCreateConfig parameters
- Add validateSignerCanUseWallet() helper to ensure signer can use wallet
- Add getSignerLocator() helper for determining signer locators
- Remove server-side restriction from getWallet() method
- Add comprehensive tests for onCreateConfig functionality
- Update React Base SDK to export OnCreateConfig and support getWallet
- Implement getWallet() in CrossmintWalletBaseProvider
- Update getOrCreateWallet() to pass through onCreateConfig
- Export OnCreateConfig type from React UI SDK

This allows delegated signers to use the SDK by separating the concept of
admin signer (who creates/owns the wallet) from usage signer (who interacts
with it).

Co-Authored-By: Guille <guille.a@paella.dev>

* fix: export OnCreateConfig and fix getChainType access

- Export OnCreateConfig from wallets SDK index
- Inline chainType logic in CrossmintWalletBaseProvider instead of accessing private method

Co-Authored-By: Guille <guille.a@paella.dev>

* refactor: remove args.delegatedSigners field (BREAKING CHANGE)

Breaking changes:
- Remove delegatedSigners field from WalletArgsFor type
- Remove delegatedSigners field from CreateOnLogin type
- delegatedSigners now ONLY exist within onCreateConfig

When onCreateConfig is provided:
- args.signer = the signer that will USE the wallet (can be admin or delegated)
- onCreateConfig.adminSigner = the admin who OWNS the wallet (only for creation)
- onCreateConfig.delegatedSigners = delegated signers (only for creation)

When onCreateConfig is NOT provided (backward compat):
- args.signer acts as BOTH the admin and usage signer

Updated:
- WalletFactory validation logic to handle both cases
- React providers to not pass delegatedSigners
- Tests to only use onCreateConfig for delegated signers

Co-Authored-By: Guille <guille.a@paella.dev>

* feat: make onCreateConfig required via WalletCreateArgs type

- Created WalletCreateArgs type that extends WalletArgsFor with required onCreateConfig
- Updated getOrCreateWallet and createWallet to use WalletCreateArgs
- Updated CreateOnLogin type to use WalletCreateArgs
- Made onCreateConfig optional in WalletArgsFor for getWallet use cases
- args.signer is now always the usage signer, not the admin signer

Co-Authored-By: Guille <guille.a@paella.dev>

* chore: fix lint issues

Co-Authored-By: Guille <guille.a@paella.dev>

* chore: update demo apps to use onCreateConfig

- Updated smart-wallet/next, quickstart-devkit, and expo apps
- All createOnLogin usages now include onCreateConfig with adminSigner
- Delegated signers moved from top-level to onCreateConfig

Co-Authored-By: Guille <guille.a@paella.dev>

* fix: correctly mutate signer in validateExistingWalletConfig

- Create tempArgs to capture mutation from mutateSignerFromCustomAuth
- Reassign expectedAdminSigner from mutated tempArgs.signer
- Ensures external wallet signer reassignment is captured correctly

Co-Authored-By: Guille <guille.a@paella.dev>

* fix: correctly mutate adminSignerConfig in createWallet

- Create tempArgs to capture mutation from mutateSignerFromCustomAuth
- Reassign adminSignerConfig from mutated tempArgs.signer
- Ensures external wallet signer reassignment works correctly

Co-Authored-By: Guille <guille.a@paella.dev>

* remove unnecesary type

* reuse common functionality from get and create

* remove redundant comments

* fix tsc issue

* fix linter

* added client side specific get wallet

* fix signers and transactions

* fix delegated signer

* remove redundant check

* fix unit test

* make oncreateconfig optional

* remove unnecesary format changes

* unify getWallet functionality

* remove admin from name

* fix react provider

* remove unnecessary types

* remove optional param

* feat(wallets): add shadow signer support for automatic delegated signers

- Add shadowSigner option to WalletOptions type
- Create shadow-signer.ts utility for generating device-bound keypairs
- Automatically generate shadow signers during wallet creation (client-side only)
- Store shadow signer metadata in localStorage
- Pass shadow signer configuration through React providers
- Support ed25519 for Solana/Stellar and p256 passkeys for EVM chains
- Gracefully handle shadow signer creation failures

Co-Authored-By: Guille <guille.a@paella.dev>

* fix: remove unused @ts-expect-error directive

Co-Authored-By: Guille <guille.a@paella.dev>

* refactor: replace 'as any' with custom SmartWalletConfig type

- Create SmartWalletConfig type to properly type wallet.config
- Replace all 'as any' casts with SmartWalletConfig type
- Improve error message clarity by avoiding 'args' in developer-facing text
- Addresses PR feedback from Alberto

Co-Authored-By: Guille <guille.a@paella.dev>

* fix: format error message to meet line length requirements

Co-Authored-By: Guille <guille.a@paella.dev>

* refactor: remove Flow-specific check, let API handle incompatible chains

Co-Authored-By: Guille <guille.a@paella.dev>

* feat: use shadow signer as active signer for wallet instances

- Modified createWallet to set shadow signer as the active signer
- Updated getOrCreateWallet to use shadow signer when retrieving existing wallets
- Shadow signer now becomes the default signer instead of the one passed by the user

Co-Authored-By: Guille <guille.a@paella.dev>

* fix: apply biome lint formatting

Co-Authored-By: Guille <guille.a@paella.dev>

* fix: add localStorage checks for Node.js test environment

Co-Authored-By: Guille <guille.a@paella.dev>

* wip shadow

* remove support for evm

* add passkey logic to delegate signer comparison

* fix wallet with multiple passkey signers

* remove console.log

* remove all shadow passkey references

* appplied albertos comment

* differentiate wallet creation for stellar and solana

* fix shadow signer for stellar

* move signing shado logic to signer

* change shado signer option config

* move delegated signer logic to a new function

* abstract signature

* remove unnecessary change

* restructure folder

* improve has shadow signer condition

* fix import

* fix import

* fix vitest test in wallets package

* refactor: address PR feedback from Alberto

- Replace all @ imports with relative imports
- Change != null to == null for style consistency
- Rename updatedDelegatedSigners to delegatedSigners for clarity
- Extract delegated signer registration logic to registerDelegatedSigners method

Co-Authored-By: Guille <guille.a@paella.dev>

* fix: apply biome formatting

Co-Authored-By: Guille <guille.a@paella.dev>

* applied comments

* added changeset

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* feat: add onCreateConfig support to separate admin and usage signers

- Add OnCreateConfig<C> type to wallets SDK types
- Update WalletArgsFor<C> to include optional onCreateConfig field
- Modify WalletFactory.createWallet() to use onCreateConfig admin signer when provided
- Update validateExistingWalletConfig() to validate onCreateConfig parameters
- Add validateSignerCanUseWallet() helper to ensure signer can use wallet
- Add getSignerLocator() helper for determining signer locators
- Remove server-side restriction from getWallet() method
- Add comprehensive tests for onCreateConfig functionality
- Update React Base SDK to export OnCreateConfig and support getWallet
- Implement getWallet() in CrossmintWalletBaseProvider
- Update getOrCreateWallet() to pass through onCreateConfig
- Export OnCreateConfig type from React UI SDK

This allows delegated signers to use the SDK by separating the concept of
admin signer (who creates/owns the wallet) from usage signer (who interacts
with it).

Co-Authored-By: Guille <guille.a@paella.dev>

* fix: export OnCreateConfig and fix getChainType access

- Export OnCreateConfig from wallets SDK index
- Inline chainType logic in CrossmintWalletBaseProvider instead of accessing private method

Co-Authored-By: Guille <guille.a@paella.dev>

* refactor: remove args.delegatedSigners field (BREAKING CHANGE)

Breaking changes:
- Remove delegatedSigners field from WalletArgsFor type
- Remove delegatedSigners field from CreateOnLogin type
- delegatedSigners now ONLY exist within onCreateConfig

When onCreateConfig is provided:
- args.signer = the signer that will USE the wallet (can be admin or delegated)
- onCreateConfig.adminSigner = the admin who OWNS the wallet (only for creation)
- onCreateConfig.delegatedSigners = delegated signers (only for creation)

When onCreateConfig is NOT provided (backward compat):
- args.signer acts as BOTH the admin and usage signer

Updated:
- WalletFactory validation logic to handle both cases
- React providers to not pass delegatedSigners
- Tests to only use onCreateConfig for delegated signers

Co-Authored-By: Guille <guille.a@paella.dev>

* feat: make onCreateConfig required via WalletCreateArgs type

- Created WalletCreateArgs type that extends WalletArgsFor with required onCreateConfig
- Updated getOrCreateWallet and createWallet to use WalletCreateArgs
- Updated CreateOnLogin type to use WalletCreateArgs
- Made onCreateConfig optional in WalletArgsFor for getWallet use cases
- args.signer is now always the usage signer, not the admin signer

Co-Authored-By: Guille <guille.a@paella.dev>

* chore: fix lint issues

Co-Authored-By: Guille <guille.a@paella.dev>

* chore: update demo apps to use onCreateConfig

- Updated smart-wallet/next, quickstart-devkit, and expo apps
- All createOnLogin usages now include onCreateConfig with adminSigner
- Delegated signers moved from top-level to onCreateConfig

Co-Authored-By: Guille <guille.a@paella.dev>

* fix: correctly mutate signer in validateExistingWalletConfig

- Create tempArgs to capture mutation from mutateSignerFromCustomAuth
- Reassign expectedAdminSigner from mutated tempArgs.signer
- Ensures external wallet signer reassignment is captured correctly

Co-Authored-By: Guille <guille.a@paella.dev>

* fix: correctly mutate adminSignerConfig in createWallet

- Create tempArgs to capture mutation from mutateSignerFromCustomAuth
- Reassign adminSignerConfig from mutated tempArgs.signer
- Ensures external wallet signer reassignment works correctly

Co-Authored-By: Guille <guille.a@paella.dev>

* remove unnecesary type

* reuse common functionality from get and create

* remove redundant comments

* fix tsc issue

* fix linter

* added client side specific get wallet

* fix signers and transactions

* fix delegated signer

* remove redundant check

* fix unit test

* make oncreateconfig optional

* remove unnecesary format changes

* unify getWallet functionality

* remove admin from name

* fix react provider

* remove unnecessary types

* remove optional param

* feat(wallets): add shadow signer support for automatic delegated signers

- Add shadowSigner option to WalletOptions type
- Create shadow-signer.ts utility for generating device-bound keypairs
- Automatically generate shadow signers during wallet creation (client-side only)
- Store shadow signer metadata in localStorage
- Pass shadow signer configuration through React providers
- Support ed25519 for Solana/Stellar and p256 passkeys for EVM chains
- Gracefully handle shadow signer creation failures

Co-Authored-By: Guille <guille.a@paella.dev>

* fix: remove unused @ts-expect-error directive

Co-Authored-By: Guille <guille.a@paella.dev>

* refactor: replace 'as any' with custom SmartWalletConfig type

- Create SmartWalletConfig type to properly type wallet.config
- Replace all 'as any' casts with SmartWalletConfig type
- Improve error message clarity by avoiding 'args' in developer-facing text
- Addresses PR feedback from Alberto

Co-Authored-By: Guille <guille.a@paella.dev>

* fix: format error message to meet line length requirements

Co-Authored-By: Guille <guille.a@paella.dev>

* refactor: remove Flow-specific check, let API handle incompatible chains

Co-Authored-By: Guille <guille.a@paella.dev>

* feat: use shadow signer as active signer for wallet instances

- Modified createWallet to set shadow signer as the active signer
- Updated getOrCreateWallet to use shadow signer when retrieving existing wallets
- Shadow signer now becomes the default signer instead of the one passed by the user

Co-Authored-By: Guille <guille.a@paella.dev>

* fix: apply biome lint formatting

Co-Authored-By: Guille <guille.a@paella.dev>

* fix: add localStorage checks for Node.js test environment

Co-Authored-By: Guille <guille.a@paella.dev>

* wip shadow

* remove support for evm

* add passkey logic to delegate signer comparison

* fix wallet with multiple passkey signers

* remove console.log

* remove all shadow passkey references

* appplied albertos comment

* differentiate wallet creation for stellar and solana

* fix shadow signer for stellar

* implement shadow signers for react native

* move signing shado logic to signer

* change shado signer option config

* move delegated signer logic to a new function

* abstract signature

* remove unnecessary change

* restructure folder

* improve has shadow signer condition

* fix import

* fix import

* move shadow signers

* fix naming

* fix vitest test in wallets package

* refactor: address PR feedback from Alberto

- Replace all @ imports with relative imports
- Change != null to == null for style consistency
- Rename updatedDelegatedSigners to delegatedSigners for clarity
- Extract delegated signer registration logic to registerDelegatedSigners method

Co-Authored-By: Guille <guille.a@paella.dev>

* fix: apply biome formatting

Co-Authored-By: Guille <guille.a@paella.dev>

* move storage to rn package

* make shad signer work for react native

* applied comments

* added changeset

* cleanup PR

* change back to string

* revert chain change

* move back to usdc

* fix browser storage

* add changeset

* make browserstorage a string to inject in webview

* add all the == null missing

* move shadow signer to its own class

* fix imports

* applied comments

* avoid injectin javascript

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* device signer for solana working

* change shadow signer config

* improve isShadowSignerEnabled logic

* fix options

* improve signature type

* fix tsc issue

* added changeset
…let calls (#1559)

BREAKING CHANGE: The owner field can no longer be specified in client-side
getOrCreateWallet calls. Owner is now determined from JWT authentication.

- Add validation in WalletFactory to throw WalletCreationError when owner is provided
- Create ClientSideWalletArgsFor and ClientSideWalletCreateArgs types
- Update CreateOnLogin type to use client-side types without owner
- Remove owner parameter from CrossmintWalletBaseProvider wallet creation

Addresses WAL-8180

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* remove device signers code

* fix lint

* remove related changesets

* restore change
* add device signer config

* fix issues on device signer

* add changeset

* Update packages/wallets/src/wallets/wallet-factory.ts

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Update packages/wallets/src/wallets/wallet-factory.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* add device signer to all chains

* receive key storage as prop

* Update packages/wallets/src/utils/device-signers/DeviceSignerKeyStorage.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* add dependency to use callback

* throw error if admin signer is device signer

* Update packages/wallets/src/wallets/wallet-factory.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* don't use generic error

* apply greptile suggestion

* Update packages/wallets/src/wallets/wallet-factory.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* fix wait for signing email

* Apply suggestion from @greptile-apps[bot]

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* change savedevice signer method name

* add defensive check

---------

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
…er with iframe (#1605)

* add device signer config

* fix issues on device signer

* add changeset

* Update packages/wallets/src/wallets/wallet-factory.ts

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Update packages/wallets/src/wallets/wallet-factory.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* add device signer to all chains

* receive key storage as prop

* Update packages/wallets/src/utils/device-signers/DeviceSignerKeyStorage.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* add dependency to use callback

* throw error if admin signer is device signer

* Update packages/wallets/src/wallets/wallet-factory.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* don't use generic error

* apply greptile suggestion

* Update packages/wallets/src/wallets/wallet-factory.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* fix wait for signing email

* added iframe key storage

* remove unnecessary change

* add changeset

* add origin validation

* Update packages/wallets/src/utils/device-signers/IframeDeviceSignerKeyStorage.ts

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* unmount iframe when provider is unmounted

* fix unit tests

---------

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* added biometric check

* send signature back to iframe

* panos comments
* add device signer to new device

* add changeset

* remove unnecessary code

* put ensure in a more general method

* apply ais comments

* apply comments

* remove reactive signer

* make biopolicy optional
* fix device signer solana

* add changeset

* added changset
* feat: add SDK logger decorator to device signer key storage methods

Co-Authored-By: Guille <guille.a@paella.dev>

* chore: add changeset for device signer logger decorator

Co-Authored-By: Guille <guille.a@paella.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…try (#1613)

* feat: handle device signer IDB fatal errors with iframe reload and retry

- Detect 'indexeddb-fatal' error code from device signer iframe responses
- Add reloadIframe() with single-flight pattern to prevent concurrent reloads
- Split rpc() into rpc() + sendRpc() for clean retry flow
- On fatal IDB error: reload iframe and retry the operation once
- Throw descriptive error if fatal persists after reload

WAL-9179

Co-Authored-By: Guille <guille.a@paella.dev>

* chore: add changeset for wallets package

Co-Authored-By: Guille <guille.a@paella.dev>

* Apply suggestions from code review

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* refactor: flatten nested if statements in sendRpc handler

Co-Authored-By: Guille <guille.a@paella.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* auth: remove farcaster login

Remove all Farcaster authentication code including:
- signInWithFarcaster method from CrossmintAuthClient
- FarcasterSignIn component
- FarcasterProvider component
- Farcaster icon
- FarcasterMetadata type
- 'farcaster' from LoginMethod union type
- @farcaster/auth-kit dependencies
- Farcaster test cases
- Farcaster from demo app loginMethods

Co-Authored-By: Alberto Elias <alberto.elias@paella.dev>

* chore: update pnpm-lock.yaml after removing @farcaster/auth-kit

Co-Authored-By: Alberto Elias <alberto.elias@paella.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
github-actions bot and others added 13 commits March 20, 2026 16:22
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* fix: remove incorrect signer mention from getWallet JSDoc

Co-Authored-By: Alberto Elias <alberto.elias@paella.dev>

* chore: add changeset for getWallet JSDoc fix

Co-Authored-By: Alberto Elias <alberto.elias@paella.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: disallow passkey signers in React Native

Passkeys (WebAuthn) are not supported in React Native. This adds
proper error handling at the provider level to throw clear errors
when passkeys are used as recovery signers, delegated signers, or
via createPasskeySigner in a React Native context.

Co-Authored-By: Alberto Elias <alberto.elias@paella.dev>

* refactor: move passkey validation from base provider to React Native provider

Instead of adding a disablePasskeys prop to CrossmintWalletBaseProvider,
all passkey validation now lives in the React Native CrossmintWalletProvider:

- PasskeyGuard component wraps children and overrides the wallet context
  to reject createWallet with passkey signers and createPasskeySigner calls
- hasPasskeySigner check on createOnLogin throws at render time
- Base provider remains unchanged

Co-Authored-By: Alberto Elias <alberto.elias@paella.dev>

* fix: move passkey check into useEffect to respect Rules of Hooks

The conditional throw was before hook calls, which violates React's
Rules of Hooks if createOnLogin changes dynamically. Moving it into
a useEffect ensures all hooks run on every render.

Co-Authored-By: Alberto Elias <alberto.elias@paella.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
#1699)

* feat: unify OTP signer API with showOtpSignerPrompt and otpSignerState

- Replace headlessSigningFlow with showOtpSignerPrompt (defaults true)
- Add showOtpSignerPrompt to react-ui CrossmintWalletProvider
- Rename emailSignerState to otpSignerState in context
- Update useWalletOtpSigner to use otpSignerState
- Update demo app and README references

Co-Authored-By: Alberto Elias <alberto.elias@paella.dev>

* fix: remove explicit showOtpSignerPrompt from README since it defaults to true

Co-Authored-By: Alberto Elias <alberto.elias@paella.dev>

* fix: showOtpSignerPrompt=false no longer suppresses passkey UI

Move OTP dialog gating into the renderUI functions themselves so that
passkey prompts are always rendered regardless of showOtpSignerPrompt.
renderUI is now always passed to CrossmintWalletBaseProvider.

Co-Authored-By: Alberto Elias <alberto.elias@paella.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…-9467) (#1712)

* fix: improve error messages when server wallet signer is missing (WAL-9467)

Co-Authored-By: Alberto Elias <alberto.elias@paella.dev>

* fix: reorder multi-signer check first, remove docs link from server error

Co-Authored-By: Alberto Elias <alberto.elias@paella.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* Fixes modal icons and other stuff

* changeset

* undo conflict

* lockfile

* fixes

---------

Co-authored-by: Alberto Elias <hi@albertoelias.me>
…ey (WAL-9470) (#1717)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* If a signer is in a pending state, approve it and then use it

* changeset

* fixesl int

* handle failed state and fallthrough to create a new signer

* use recovery signer to approve delegated signer

* stellar fix

---------

Co-authored-by: Alberto Elias <hi@albertoelias.me>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Updated pod version

* Removed pod injection from plugin

* Add podspec to pull podspec from cocoapods trunk

* Bundle device signer Podfile fixes into client-sdk-react-native-ui plugin

* Update expo demo to use client-sdk-react-native-ui plugin instead of expo-device-signer

* Update lockfile after removing expo-device-signer from demo app deps

* Add podspec to files allowlist in expo-device-signer package.json

* Format package.json to satisfy biome
Co-Authored-By: Alberto Elias <alberto.elias@paella.dev>
Co-Authored-By: Alberto Elias <alberto.elias@paella.dev>
@devin-ai-integration
Copy link
Contributor

Original prompt from Alberto Elias

create a pr for wallets-v1 into main. there are merge conflicts, use all your knowledge about wallets-v1 to solve them

You only need to look in the following repo: Crossmint/crossmint-sdk

@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@changeset-bot
Copy link

changeset-bot bot commented Mar 21, 2026

🦋 Changeset detected

Latest commit: 7212419

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

This PR includes changesets to release 18 packages
Name Type
@crossmint/wallets-sdk Major
@crossmint/client-sdk-react-base Major
@crossmint/common-sdk-base Minor
@crossmint/expo-device-signer Minor
@crossmint/client-sdk-react-native-ui Major
@crossmint/client-sdk-react-ui Major
@crossmint/client-sdk-auth Minor
@crossmint/common-sdk-auth Minor
expo-demo Patch
@crossmint/client-sdk-base Patch
@crossmint/client-sdk-verifiable-credentials Patch
@crossmint/client-sdk-smart-wallet Patch
@crossmint/client-sdk-walletconnect Patch
@crossmint/server-sdk Patch
@crossmint/auth-ssr-nextjs-demo Patch
@crossmint/client-sdk-nextjs-starter Patch
@crossmint/wallets-quickstart-devkit Patch
crossmint-auth-node 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

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 21, 2026

Too many files changed for review. (303 files found, 100 file limit)

Co-Authored-By: Alberto Elias <alberto.elias@paella.dev>
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 3 potential issues.

View 7 additional findings in Devin Review.

Open in Devin Review

@github-actions
Copy link
Contributor

github-actions bot commented Mar 21, 2026

🔥 Smoke Test Results

Status: Passed

Statistics

  • Total Tests: 5
  • Passed: 5 ✅
  • Failed: 0
  • Skipped: 0
  • Duration: 3.28 min

✅ All smoke tests passed!

All critical flows are working correctly.


This is a non-blocking smoke test. Full regression tests run separately.

Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 new potential issues.

View 12 additional findings in Devin Review.

Open in Devin Review

devin-ai-integration bot and others added 2 commits March 21, 2026 01:22
Co-Authored-By: Alberto Elias <alberto.elias@paella.dev>
…ry re-renders

Co-Authored-By: Alberto Elias <alberto.elias@paella.dev>
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 new potential issues.

View 12 additional findings in Devin Review.

Open in Devin Review

…ingFlow

Co-Authored-By: Alberto Elias <alberto.elias@paella.dev>
@albertoelias-crossmint albertoelias-crossmint merged commit 02ac7bc into main Mar 21, 2026
2 checks passed
@albertoelias-crossmint albertoelias-crossmint deleted the devin/1774053734-merge-wallets-v1-into-main branch March 21, 2026 02:32
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.

7 participants