This guide covers every breaking change in the Wallets SDK V1 release. It is organized by audience — client-side (React / React Native, Swift, Kotlin), server-side (Node.js), and REST API — so you can jump to the section that applies to you.Documentation Index
Fetch the complete documentation index at: https://docs.crossmint.com/llms.txt
Use this file to discover all available pages before exploring further.
V1 is a major release with breaking changes. Read through the relevant sections before upgrading your packages.
Terminology changes
V1 renames several concepts. Use this table as a find-and-replace checklist across your codebase.| Old term | New term | Notes |
|---|---|---|
adminSigner | Recovery signer | Recovery signers are high-friction (OTP-based). They can also sign transactions as a fallback when no operational signer is available. |
delegatedSigner | Signer (operational) | Day-to-day signers: device, passkey, server, external-wallet. |
getOrCreateWallet() | createWallet() + getWallet() | Separate calls. getWallet() throws WalletNotAvailableError if no wallet exists. |
addDelegatedSigner() | addSigner() | Signature also changed — accepts config objects, not just locator strings. |
experimental_activity() | transfers(params) | Name and signature changed. tokens and status params are optional. |
experimental_ prefix | Removed | experimental_prepareOnly → prepareOnly, experimental_signer → signer, experimental_approval → approval, experimental_nfts() → nfts(), experimental_transactions() → transactions(), experimental_transaction(id) → transaction(id). |
customAuth / experimental_setCustomAuth | setJwt() | setJwt(jwt) replaces the old experimental_setCustomAuth({ jwt, email, externalWalletSigner }). |
useWalletEmailSigner | useWalletOtpSigner | Now works for both email and phone OTP signers. |
createOnLogin.signer | createOnLogin.recovery | The signer field in createOnLogin is now recovery. |
createOnLogin.delegatedSigners | createOnLogin.signers | Array of operational signers to register at wallet creation. |
Activity type | Transfers type | Find-and-replace import. |
Client-side migration (React / React Native)
1. Update packages
Update all@crossmint packages to V1 versions:
2. Update createOnLogin in your provider
The signer field is now recovery, and delegatedSigners is now signers.
Device signers are now the default operational signer. If you do not specify
signers, a device signer is created automatically on EVM chains. Solana does not support device signers yet — the recovery signer is used as a fallback for signing.3. Replace getOrCreateWallet with getWallet + createWallet
getOrCreateWallet has been removed. Use getWallet to retrieve an existing wallet. If it throws WalletNotAvailableError, call createWallet.
4. Replace customAuth with setJwt
If you use a third-party auth provider (BYOA), replace experimental_setCustomAuth with setJwt.
5. Remove experimental_ prefixes
All experimental_ prefixes have been removed from wallet methods and options.
6. Replace useWalletEmailSigner with useWalletOtpSigner
The useWalletEmailSigner hook has been replaced by useWalletOtpSigner, which works for both email and phone OTP flows.
7. Replace addDelegatedSigner with addSigner
The method name and signature have changed. addSigner now accepts signer config objects in addition to locator strings.
8. Remove Farcaster and Dynamic login references
Farcaster sign-in and Dynamic wallet login have been removed entirely. If you used either, migrate to an alternative auth method.- Remove
"farcaster"fromloginMethodsinCrossmintAuthProvider. - Remove
"web3"fromloginMethods. - Remove any
FarcasterSignIn,Web3AuthFlow, orDynamicWalletProviderimports.
9. Understand device signers
Device signers are a new signer type backed by the device’s hardware security module (Secure Enclave on mobile, IndexedDB on web). They are the default operational signer for EVM wallets — no OTP is required for day-to-day signing. Key points:- No code change is needed if you want the default device signer behavior.
- Call
wallet.needsRecovery()to check if the device signer needs to be re-established (e.g. after the user switches devices). - Call
wallet.recover()to trigger recovery using the recovery signer. - Solana does not support device signers yet. The recovery signer is used as a fallback.
10. Use useSigner() for non-device signers
If you need to sign with a non-device signer (e.g. passkey, external wallet, server), call wallet.useSigner() first.
useSigner() only accepts signer config objects — locator strings (e.g. "external-wallet:0x...") are no longer accepted.11. Update external wallet signer to use onSign
V1 replaces chain-specific signing props (provider, viemAccount, onSignTransaction, onSignStellarTransaction) with a single unified onSign callback. When using an external-wallet signer (via useSigner), both address and onSign are required.
Registration vs. usage: When registering an external-wallet signer (in
createWallet({ signers: [...] }) or addSigner()), only address is needed — no onSign. The onSign callback is only required when actively signing via useSigner().Client-side migration (Swift)
1. Update the SDK version
In Xcode, go to your package dependency forcrossmint-swift-sdk and update the version requirement:
2. Replace getOrCreateWallet with getWallet + createWallet
getOrCreateWallet has been removed. Use getWallet to retrieve an existing wallet. If it returns nil, call createWallet. The signer parameter is now named recovery.
3. Update OTP authentication
The singleotpAuthentication() method has been replaced with two explicit steps: sendEmailOtp and confirmEmailOtp.
4. Understand device signers
Device signers are a new signer type backed by the device’s hardware security module (Secure Enclave). They are the default operational signer for EVM wallets — no OTP is required for day-to-day signing. Key points:- No code change is needed if you want the default device signer behavior.
- Opt in explicitly via
WalletOptions(deviceSigner: true)if you need to control it. - Call
wallet.needsRecovery()to check if the device signer needs to be re-established (e.g. after the user reinstalls the app or switches devices). - Call
wallet.recover()to trigger recovery using the recovery signer. - Solana does not support device signers yet. The recovery signer is used as a fallback.
5. Add and manage signers
Signer management is available onWallet.
6. Update ApiKeySigner initialization
ApiKeySigner no longer provides a default ApiKeySignerData — you must pass one explicitly.
7. Replace the deprecated Signers enum
The Signers enum is deprecated. Use EVMSigners or SolanaSigners for type-safe chain compatibility.
Client-side migration (Kotlin)
1. Update the SDK version
Update the version in yourlibs.versions.toml or build.gradle.kts:
2. Replace getOrCreateWallet with getWallet + createWallet
getOrCreateWallet has been removed. Use getWallet to retrieve an existing wallet. If it returns a failure, call createWallet. The signer parameter is now named recovery.
3. Understand device signers
Device signers are a new signer type backed by the device’s hardware security module (Android Keystore). They are the default operational signer for EVM wallets — no OTP is required for day-to-day signing. Key points:- No code change is needed if you want the default device signer behavior.
- Call
wallet.needsRecovery()to check if the device signer needs to be re-established (e.g. after the user reinstalls the app or switches devices). - Call
wallet.recover()to trigger recovery using the recovery signer. - Solana does not support device signers yet. The recovery signer is used as a fallback.
4. Add and manage signers
Signer management is a first-class API onWallet.
5. Use SignerSelection in send and approve
send() and approve() now accept an optional signer: SignerSelection parameter. It defaults to SignerSelection.Admin (the recovery signer), so existing call sites without the parameter continue to work. Pass SignerSelection.Delegated(...) to sign with an operational signer.
6. Check balances and list transfers
balances(), fund(), and listTransfers() are available directly on Wallet.
Server-side migration (Node.js)
1. Update packages
2. Replace getOrCreateWallet with createWallet / getWallet
3. Update signer configuration
The oldsigner field (admin signer) is now recovery, and delegatedSigners is now signers.
4. Migrate from API key signer to server signer
If you were using the API key as a signer for server-side operations, migrate to the new server signer. Server signers use deterministic key derivation from a secret you control.5. Remove experimental_ prefixes
Same as client-side — remove all experimental_ prefixes from method names and option fields.
REST API migration
The REST API changes in V1 are additive — there are no breaking changes to existing endpoints. The main addition is server signer support.Switch to the 2025-06-09 API version
Server signers require the 2025-06-09 API version. Update your base URL:
Create a wallet with a server signer
Previously, server-managed signing used theexternal-wallet type. V1 introduces a dedicated server signer type.
The REST API accepts
address (not secret) for server signers. Derive the address from your secret in your backend before passing it to the API.Submit approvals with a server signer
Use theserver:<address> locator format when submitting approvals.
REST ↔ SDK signer type mapping
Use this table to map between REST API signer types and SDK signer config objects.| REST API signer type | REST locator format | SDK signer config |
|---|---|---|
evm-keypair / solana-keypair | external-wallet:<address> | { type: "external-wallet", address, provider } |
server | server:<address> | { type: "server", secret: "..." } |
evm-passkey | passkey:<credentialId> | { type: "passkey" } |
| N/A (client-only) | device:<publicKey> | { type: "device" } |
evm-email-otp | email:<email> | { type: "email", email: "..." } |
evm-phone-otp | phone:<number> | { type: "phone", phone: "..." } |
Checklist
Use this checklist to verify your migration is complete:- Updated all
@crossmintpackages to V1 versions - Replaced
getOrCreateWalletwithcreateWallet/getWallet - (Android) Updated SDK to
1.0.0 - (Android/iOS) Replaced
getOrCreateWalletwithcreateWallet/getWallet, renamedsigner→recovery - (iOS) Replaced
otpAuthenticationwithsendEmailOtp+confirmEmailOtp - (iOS) Updated
ApiKeySignerinitialization — no longer has a default parameter - (iOS) Replaced deprecated
Signersenum withEVMSigners/SolanaSigners - Updated
createOnLogin:signer→recovery,delegatedSigners→signers - Replaced
experimental_setCustomAuthwithsetJwt(if using BYOA) - Removed all
experimental_prefixes from methods and options - Replaced
useWalletEmailSignerwithuseWalletOtpSigner - Replaced
addDelegatedSignerwithaddSigner - Removed Farcaster / Dynamic login references (if applicable)
- Updated REST API calls to use
serversigner type (if applicable) - Searched codebase for old terms:
adminSigner,getOrCreateWallet,delegatedSigner,experimental_
Next steps
Error handling
Handle WalletNotAvailableError and other common errors
Add a signer
Register operational signers on your wallet

