Skip to main content
The Flutter SDK uses 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

auth
CrossmintAuthClient
The authentication client for login/logout flows.
wallets
CrossmintWalletsClient
The wallets API client for direct wallet operations.
credentials
CrossmintCredentialsClient
The verifiable credentials client.
orders
CrossmintOrdersClient
The orders API client.
tokens
CrossmintTokensClient
The tokens API client.
users
CrossmintUsersClient
The users API client.

Methods

initialize()
Future<void>
Initializes the SDK. Must be called before using any other methods.
dispose()
void
Cleans up resources.
createWalletController(config)
CrossmintWalletController
Creates a wallet controller with the specified configuration.

Usage

import 'package:crossmint_flutter/crossmint_client.dart';

final client = CrossmintClient(
  config: CrossmintClientConfig(
    apiKey: 'YOUR_CLIENT_API_KEY',
    appScheme: 'myapp',
  ),
);

await client.initialize();
await client.auth.restoreSession();

CrossmintAuthClient

Manages authentication state and login flows. Exposes state via ValueListenable and Stream for reactive UI updates.

Properties

state
CrossmintAuthState
The current auth state (synchronous getter).
stateListenable
ValueListenable<CrossmintAuthState>
Listenable for auth state changes. Use with ListenableBuilder or ValueListenableBuilder.

Methods

restoreSession()
Future<void>
Restores a persisted auth session on app launch. Call during app initialization.
sendEmailOtp(email)
Future<CrossmintEmailOtpChallenge>
Sends a one-time password to the user’s email address.
confirmEmailOtp(email, emailId, token)
Future<bool>
Verifies the one-time password and completes authentication.
loginWithOAuth(provider)
Future<void>
Initiates an OAuth login flow with the specified provider.
setJwt(jwt)
Future<void>
Sets a JWT for bring-your-own-auth (BYOA) flows. Pass a valid JWT to authenticate; pass null to log out. The SDK does not refresh the token — callers are responsible for updating it before expiration.
getSession()
Future<CrossmintAuthSession?>
Returns the current auth session, or null if not authenticated.
getUser({forceRefresh})
Future<CrossmintAuthenticatedUser?>
Returns the authenticated user profile, or null if not authenticated.
logout()
Future<void>
Signs out and clears the session.

Usage

import 'package:crossmint_flutter/crossmint_flutter_auth.dart';

client.auth.stateListenable.addListener(() {
  print('Auth state: ${client.auth.state}');
});

final challenge = await client.auth.sendEmailOtp('YOUR_USER_EMAIL');
await client.auth.confirmEmailOtp(
  email: 'YOUR_USER_EMAIL',
  emailId: challenge.id,
  token: 'YOUR_OTP_CODE',
);

await client.auth.loginWithOAuth(CrossmintOAuthProvider.google);

await client.auth.logout();

CrossmintWalletController

Manages wallet lifecycle — creation, loading, signing, and OTP flows. Extends ChangeNotifier for reactive UI updates.

Properties

currentWallet
CrossmintWallet?
The currently-loaded wallet domain model, or null if no wallet is loaded. Use createEvmWallet / createSolanaWallet / createStellarWallet to wrap it in a runtime wallet that exposes signing, balance, and transaction methods.
status
CrossmintWalletStatus
Current wallet status: notLoaded, inProgress, loaded, or error.
state
CrossmintWalletStateView
Read-only Listenable surface exposing currentWallet, currentWalletId, and status. Subscribe to this (or to the controller itself — it extends ChangeNotifier) to react to wallet lifecycle changes.
otp
CrossmintWalletOtpController
OTP controller for managing email/phone signer challenges.

Methods

createWallet(request)
Future<CrossmintWallet>
Creates a new wallet and stores it as the controller’s currentWallet.
getWallet(request)
Future<CrossmintWallet?>
Retrieves an existing wallet and stores it as the controller’s currentWallet.
createEvmWallet({signer, additionalSigners})
CrossmintEvmWallet
Wraps the currently-loaded wallet in a runtime EVM wallet bound to the given signer. The controller must already have a loaded wallet (via getWallet / createWallet or auto-creation on login). Returns an instance that exposes sendToken, balances, signMessage, signTypedData, sendTransaction, etc.
createSolanaWallet({signer, additionalSigners})
CrossmintSolanaWallet
Solana equivalent of createEvmWallet. Solana wallets do not support device signers.
createStellarWallet({signer, additionalSigners})
CrossmintStellarWallet
Stellar equivalent of createEvmWallet.
The controller also provides chain-specific convenience factories that build the signer for you: createEvmWalletWithDeviceSigner, createEvmWalletWithPasskeySigner, createEvmWalletWithExternalWalletSigner, createEvmWalletWithNonCustodialSigner, and their Solana / Stellar counterparts.

Usage

import 'package:crossmint_flutter/crossmint_flutter_controllers.dart';

final controller = client.createWalletController(
  CrossmintWalletControllerConfig(
    createOnLogin: CrossmintCreateOnLoginConfig(
      chain: 'base-sepolia',
      recovery: const CrossmintEmailSignerConfig(),
    ),
  ),
);

// Listen to status changes
controller.addListener(() {
  print('Status: ${controller.status}');
  final wallet = controller.currentWallet;
  if (wallet != null) {
    print('Address: ${wallet.address}');
  }
});

// Manual OTP handling
controller.otp.challengeListenable.addListener(() {
  final challenge = controller.otp.challengeListenable.value;
  if (challenge != null) {
    // Show your own OTP prompt UI
    // Then call: controller.otp.verifyOtp('123456');
  }
});

CrossmintWallets

Stateless convenience facade for wallet operations. Mirrors the CrossmintWallets 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

CrossmintWallets.from(client, {onAuthRequired, deviceSignerKeyStorage})
CrossmintWallets
Creates a facade backed by the given client.

Methods

getWallet({chain, alias, plugins})
Future<CrossmintRuntimeWalletBase>
Retrieves an existing wallet. Throws CrossmintWalletException if not found.
createWallet({chain, recovery, signers, owner, alias, plugins})
Future<CrossmintRuntimeWalletBase>
Creates a new wallet and returns a typed runtime wallet.
createDeviceSigner({storage, address})
Future<CrossmintDeviceSignerDescriptor>
Creates a device signer descriptor for hardware-backed signing.
createPasskeySigner({name, config})
Future<CrossmintPasskeySignerConfig>
Creates a passkey signer configuration.

Usage

import 'package:crossmint_flutter/crossmint_flutter_wallets.dart';

final wallets = CrossmintWallets.from(
  client,
  onAuthRequired: (challenge) {
    // Show your OTP prompt UI, then call challenge.verify(code)
  },
);

// Get an existing wallet
final wallet = await wallets.getWallet(chain: 'base-sepolia');
print('Address: ${wallet.address}');

// Create a new wallet
final newWallet = await wallets.createWallet(
  chain: 'base-sepolia',
  recovery: CrossmintEmailSignerConfig(email: 'YOUR_USER_EMAIL'),
);

// Send tokens
final tx = await newWallet.sendToken('RECIPIENT_WALLET_ADDRESS', 'usdc', '10');

Wallet Methods

The runtime wallet instances returned by the controller provide methods for token transfers, balances, signing, and more.

Properties

PropertyTypeDescription
wallet.addressStringThe wallet address
wallet.chainStringThe chain this wallet lives on
wallet.ownerString?The wallet owner identifier (e.g. email or user ID)
wallet.recoveryCrossmintSignerConfig?The recovery signer configuration
wallet.locatorStringThe wallet ID used for API calls

Methods

MethodDescription
wallet.sendToken(to, token, amount)Send a token using positional arguments (convenience)
wallet.send(request)Send a token using a CrossmintWalletTokenTransferRequest (advanced)
wallet.balances({tokens})Get the wallet balances — always includes USDC and native token; pass tokens: to include extras
wallet.signers()List the signers for this wallet
wallet.addSigner(config)Add a signer to the wallet using the recovery signer
wallet.removeSigner(locator)Remove a signer from the wallet
wallet.signerIsRegistered(locator)Check if a signer is registered
wallet.transactions()Get the wallet transaction history
wallet.transaction(id)Get a transaction by ID
wallet.transfers()Get the wallet transfers
wallet.nfts()Get the wallet NFTs
wallet.fund()Fund the wallet with test tokens (staging only)
Chain-specific methods:
  • CrossmintEvmWalletsendTransaction(), signMessage(), signTypedData()
  • CrossmintSolanaWalletsendTransaction()
  • CrossmintStellarWalletsendTransaction()

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).
if (controller.currentWallet == null) return;

final wallet = controller.createEvmWallet();

final balances = await wallet.balances(tokens: <String>['usdc']);
print('USDC: ${balances.usdc.amount}');
print('Native: ${balances.nativeToken.amount}');

final tx = await wallet.sendToken('RECIPIENT_WALLET_ADDRESS', 'usdc', '10');
print('Transaction: ${tx.id}');

final signature = await wallet.signMessage('Hello, Web3!');
print('Signature: $signature');