ChangeNotifier-based controllers instead of React hooks. Controllers can be used directly (headless) or accessed through the widget tree via providers.
CrossmintClient
The top-level facade for the Crossmint SDK. Provides access to auth, wallets, and all sub-clients.Properties
Authentication sub-client — email OTP, OAuth, wallet sign-in, session persistence, JWT refresh.
Wallet sub-client — create, list, and read Crossmint-hosted wallets (EVM, Solana, Stellar) and their signers.
The effective app ID — explicit [CrossmintClientConfig.appId] if set, otherwise the value auto-resolved from platform metadata during [initialize]. May be
null until [initialize] has completed.Whether [dispose] has been called. Once disposed, the client cannot be reused — construct a new one.
The shared hidden signer bridge controller, lazily constructed on first access. Powers non-custodial email/phone signing inside a hidden WebView.
The auth storage adapter resolved during construction — either the one passed via [CrossmintClientConfig.authStorage] or the default
flutter_secure_storage-backed implementation.The HTTP transport resolved during construction. Shared by every sub-client; injects the live JWT via a closure so token refresh works without rebuilding dependencies.
Methods
Builds a new [HiddenSignerBridgeRuntimeController] instance — used internally by [hiddenSignerBridgeController]. Override the bridge
config to point at a custom signer URL (e.g. for testing).Builds a new [CrossmintExportSignerBridgeRuntimeController] instance. Used internally by [exportSignerBridgeController].
Builds a non-custodial EVM signer bound to an existing [HiddenSignerBridge]. Produces secp256k1 signatures inside the WebView without exposing keys to Dart.
Builds a non-custodial Solana signer bound to an existing [HiddenSignerBridge]. Produces ed25519 signatures inside the WebView.
Builds a non-custodial Stellar signer bound to an existing [HiddenSignerBridge]. Produces ed25519 signatures inside the WebView.
Wraps a server-issued [CrossmintWallet] in a runtime [CrossmintStellarWallet].
Builds an external-wallet EVM signer that delegates to a user-supplied [CrossmintExternalWalletSignCallback]. Use for wallets owned by the user (e.g. MetaMask, Rainbow) where the SDK only needs to request signatures.
Builds an external-wallet Solana signer that delegates to a user-supplied [CrossmintExternalWalletSignCallback].
Builds an external-wallet Stellar signer that delegates to a user-supplied [CrossmintExternalWalletSignCallback].
Builds a passkey approval signer. The caller provides
onSign — a callback that performs the WebAuthn / platform-native passkey assertion and returns a [CrossmintPasskeySignResult]. Native platform passkey support is pending (Stage 2); today every passkey signer requires an explicit callback or CrossmintSignerException(code: passkeyCallbackMissing) is thrown during signing.Releases the signer bridges and auth client, then marks the client as disposed. Safe to call multiple times. After disposal, construct a new [CrossmintClient] rather than reusing this one.
Usage
CrossmintAuthClient
Manages authentication state and login flows. Exposes state viaValueListenable and Stream for reactive UI updates. Use setJwt() to provide your own JWT when not using the built-in auth flows.
Properties
Reactive handle on [state] — suitable for [ValueListenableBuilder].
Methods
Reads any persisted session from [CrossmintAuthStorage] and applies it to the client. Safe to call once per app launch — prefer using the result of
CrossmintClient.initialize which calls this internally.Opens the Crossmint-hosted OAuth flow for [provider] (Google, Twitter, etc.). The response comes back through [CrossmintAuthCallbackRouter] — make sure it is started before calling this.
Requests the Crossmint API to send an email OTP to [email]. Returns a challenge that [confirmEmailOtp] completes.
Submits an email OTP challenge — pass the
emailId from the challenge and the token the user entered. Returns true on success.Completes an OAuth flow from a deep-link callback URI. This method accepts any link, also one from a login that the app did not start. For custom link routing, use [completePendingOAuth].
Completes an OAuth flow from a deep-link callback URI only when it belongs to a login that [loginWithOAuth] started. Returns
false and ignores the link when its scheme is not the app scheme or when no login is pending. [CrossmintAuthCallbackRouter] uses this for incoming links.Completes an OAuth flow from a one-time secret (SSR / server-mediated callbacks). Returns
true on success.Starts wallet-based authentication. Returns a challenge that the wallet must sign. [type] is
'evm' or 'solana'.Returns the current session (JWT + metadata), or
null if not signed in. Does not hit the network — reads from in-memory state.Returns the authenticated user’s profile. Caches the result; pass
forceRefresh: true to bypass the cache and refetch.Signs the user out — clears persisted storage, cached session/user, and POSTs to the Crossmint (or custom) logout endpoint.
Usage
CrossmintWalletController
Manages wallet lifecycle — creation, loading, signing, and OTP flows. ExtendsChangeNotifier for reactive UI updates.
Properties
The underlying client — exposed for code that needs direct access to sub-clients (auth, orders, credentials, etc.).
Read-only observation surface for the underlying wallet state. Advanced consumers can subscribe to wallet / status changes directly via this [Listenable] while still routing all mutations through the controller’s public API (
getWallet, createWallet, refresh, clear, …).The auth-required callback the controller wires into every signer it builds. Exposed so apps building signers manually can share the same OTP-handling path.
Shortcut to [CrossmintWalletOtpController.challengeListenable].
Returns the currently-loaded wallet or throws [CrossmintWalletException] when none is loaded.
Methods
Looks up an existing wallet and stores the result in controller state. Returns
null when no wallet matches. Listeners fire on state changes.Creates a new wallet and stores it in controller state. Validates passkey signers up-front via [crossmintValidatePasskeySigners] and fires [CrossmintWalletLifecycleCallbacks.onWalletCreationStart] if set.
Re-fetches the currently-loaded wallet from the API. Returns
null when nothing is loaded.Wraps the currently-loaded wallet as a runtime [CrossmintEvmWallet]. Throws [CrossmintWalletException] if no wallet is loaded.
Wraps the currently-loaded wallet as a runtime [CrossmintSolanaWallet]. On Solana, device signer support depends on the wallet type and is validated server-side. A default device signer is not auto-injected for Solana; it is registered reactively and falls back to the recovery signer when the server rejects it.
Builds a runtime EVM wallet backed by a hardware-backed device signer. Use for low-friction, day-to-day signing with keys in Secure Enclave / Android Keystore.
Builds a runtime EVM wallet backed by a non-custodial email/phone signer. Requires [CrossmintWalletHost] (or
CrossmintWalletProvider) mounted in the widget tree.Builds a runtime Solana wallet backed by a non-custodial email/phone signer. Requires a mounted wallet host.
Builds a runtime Stellar wallet backed by a non-custodial email/phone signer. Requires a mounted wallet host.
Builds a runtime EVM wallet backed by a user-owned external wallet (e.g. MetaMask). The caller supplies [onSign] to perform signatures.
Builds a runtime Solana wallet backed by a passkey signer. See [createEvmWalletWithPasskeySigner] for passkey selection semantics.
Builds a runtime Stellar wallet backed by a passkey signer. See [createEvmWalletWithPasskeySigner] for passkey selection semantics.
The controller also provides chain-specific convenience factories that build
the signer for you:
createEvmWalletWithDeviceSigner,
createEvmWalletWithPasskeySigner,
createEvmWalletWithExternalWalletSigner,
createEvmWalletWithNonCustodialSigner, and their Solana / Stellar
counterparts.Usage
CrossmintWallets
Stateless convenience facade for wallet operations. Mirrors theCrossmintWallets entry point used by the TS, Kotlin, and Swift SDKs. For reactive state management (e.g. listening to wallet changes in a widget tree), use CrossmintWalletController instead.
Unlike the controller, the facade does not auto-resolve signer configs. Callers must provide fully-resolved configs (e.g. include the email address in CrossmintEmailSignerConfig, or pre-create a device signer via createDeviceSigner()).
Constructor
Methods
Usage
Wallet Methods
The runtime wallet instances returned by the controller provide methods for token transfers, balances, signing, and more.Properties
Methods
Chain-specific methods:
CrossmintEvmWallet—sendTransaction(),signMessage(),signTypedData()CrossmintSolanaWallet—sendTransaction()CrossmintStellarWallet—sendTransaction()
Usage
controller.currentWallet holds the loaded domain model. Signing, balance, and transaction methods live on the runtime wallet returned by controller.createEvmWallet() (or createSolanaWallet / createStellarWallet).

