This page has been updated for Wallets SDK V1. If you are using the previous version,
see the previous version docs or the V1 migration guide.
Device signers are not currently available for Solana. For Solana wallets, the recovery signer is used as a fallback for signing transactions.
How It Works
When a client-side wallet is created, the SDK automatically generates a device signer unless you explicitly configure a different signer. The flow:- The SDK initializes secure storage on the device (Secure Enclave, Keystore, or a hidden iframe in the browser)
- A P256 keypair is generated — the private key is non-extractable and never leaves the hardware boundary
- The public key is sent to the Crossmint backend, which registers the device signer on the wallet
- Subsequent transactions are signed locally on the device — no OTP, no network round-trips for signing
Browser Architecture
In browser environments, the device signer key lives inside a hidden iframe hosted atcrossmint-signer.io — a separate origin from your application. Key generation and signing happen inside the iframe via postMessage. Keys are stored as non-extractable CryptoKey objects in the iframe’s IndexedDB, isolated from the parent page by the browser’s same-origin policy.
Mobile Architecture
On iOS, keys are stored in the Secure Enclave. On Android, keys are stored in the Android Keystore. Both provide hardware-level isolation for the private key material.Setup
No explicit configuration is needed. When you create a wallet on the client side, a device signer is added automatically.- React
- React Native
Using Or using
createOnLogin on the provider (recommended for most apps):createWallet directly:Signing Transactions
With a device signer,useSigner() is not needed — the device signer is auto-selected as the default. Transactions are signed without any user-facing prompts:
New Device Recovery
Device signers are per-device — they do not sync across devices. When a user accesses their wallet from a new device:- The user authenticates via your app (JWT) and the SDK retrieves the wallet
- No local device signer exists on the new device, so
wallet.needsRecovery()returnstrue - On the first transaction, the SDK automatically triggers recovery: the user verifies via their recovery signer (e.g., email OTP) to authorize a new device signer for this device
- After recovery, all subsequent transactions on the new device are frictionless again
Pre-emptive Recovery
Recovery runs automatically before the first signing operation on a new device. If you want to trigger it earlier (e.g., on app startup to avoid an OTP prompt mid-transaction), callrecover() explicitly:
Chain Support
| Chain | Device Signer Support |
|---|---|
| EVM (Base, Ethereum, Polygon, etc.) | Supported |
| Stellar | Supported |
| Solana | Not currently available |
Next Steps
Configure Recovery
Set up email or phone recovery for new device flows
Add Signers
Add passkeys or external wallets as additional signers
Transfer Tokens
Send tokens from your wallet

