crossmint_flutter 0.1.2
crossmint_flutter: ^0.1.2 copied to clipboard
Flutter SDK for Crossmint wallets, authentication, signers, embedded checkout, and verifiable credentials. Headless-first — you own the UI.
Crossmint Flutter SDK
The Flutter SDK for integrating Crossmint wallets, authentication, checkout, and verifiable credentials into your mobile app
Explore the docs »
View Example App
·
Report Bug
·
Request Feature
Table of Contents
About The Project #
The Crossmint Flutter SDK brings the full power of the Crossmint platform to Flutter mobile apps. It is the Flutter counterpart to the Crossmint SDK for React and React Native.
The SDK is headless-first: you own the app UI, while the SDK provides client surfaces, runtime wallet helpers, auth callback wiring, a hidden signer runtime, and native device-signer integration. Optional UI components are available for common flows like authentication forms and OTP prompts.
Why Crossmint? #
- Quick Integration: Get up and running in minutes with a single package dependency
- Developer-First: Build end-to-end blockchain solutions without deep Web3 expertise
- Secure: Enterprise-grade security with Secure Enclave / Android Keystore device signers
- Fiat-First: Enable users to participate in Web3 without cryptocurrency via embedded checkout
- Free to Start: Start developing at no cost
Core Features #
- Embedded wallets: Create and manage EVM, Solana, and Stellar wallets
- Authentication: Email OTP, OAuth (Google, Twitter), wallet-based sign-in, and session management
- Signers: Email, phone, device, external wallet, passkey, and server signers
- Embedded checkout: Credit card and crypto payments via a drop-in WebView widget
- Verifiable credentials: Issue, present, and verify on-chain credentials
Package Overview #
Most apps should depend only on the main SDK package:
crossmint_flutter: The main Flutter SDK — auth, wallets, signers, checkout, and credentials.
The SDK is composed of several internal packages that you typically do not need to depend on directly:
crossmint_core: Pure Dart base abstractions (no Flutter or external dependencies)crossmint_auth: Authentication domain logiccrossmint_wallets: Wallet domain logiccrossmint_verifiable_credentials: Verifiable credentials helperscrossmint_device_signer: Native plugin for on-device key storage (Secure Enclave / Android Keystore)
Getting Started #
Prerequisites #
- Flutter mobile app targeting iOS and/or Android
- Flutter 3.41+ and Dart 3.11+
- A Crossmint client key (get one here)
- An app callback scheme for OAuth flows on mobile
Installation #
Add the SDK to your project:
flutter pub add crossmint_flutter
Quickstart #
Initialize the SDK, restore any existing session, and start the OAuth callback router early in app startup:
import 'package:flutter/widgets.dart';
import 'package:crossmint_flutter/crossmint_client.dart';
import 'package:crossmint_flutter/crossmint_flutter_auth.dart';
import 'package:crossmint_flutter/crossmint_flutter_controllers.dart';
late final CrossmintClient client;
late final CrossmintWalletController walletController;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
client = CrossmintClient(
config: const CrossmintClientConfig(
apiKey: String.fromEnvironment('CROSSMINT_API_KEY'),
appScheme: String.fromEnvironment('CROSSMINT_APP_SCHEME'),
),
);
await client.initialize();
await client.auth.restoreSession();
final authRouter = CrossmintAuthCallbackRouter(auth: client.auth);
await authRouter.start();
walletController = client.createWalletController(
const CrossmintWalletControllerConfig(
showOtpSignerPrompt: true,
),
);
runApp(MyApp(client: client, walletController: walletController));
}
Wrap your app tree in CrossmintWalletHost so the hidden signer WebView bridge has a place to run:
class MyApp extends StatelessWidget {
const MyApp({super.key, required this.client, required this.walletController});
final CrossmintClient client;
final CrossmintWalletController walletController;
@override
Widget build(BuildContext context) {
return CrossmintWalletHost(
client: client,
walletController: walletController,
child: /* your app tree */,
);
}
}
Required for non-custodial signers. Email and phone signers run inside a hidden WebView that the SDK manages for you.
CrossmintWalletHost(headless, re-exported fromcrossmint_flutter_controllers.dart) — orCrossmintWalletProviderfromcrossmint_flutter_ui.dartif you want the opt-in default UI — must be mounted in the widget tree. Without one,wallet.useSigner(CrossmintEmailSignerConfig(...))throwsCrossmintSignerException(code: nonCustodialBridgeHostNotMounted). Passkey signers sign viaonSignWithPasskeycallbacks and do not require a host.
Once a wallet is loaded (e.g. via walletController.getWallet(...) or walletController.createWallet(...)), interact with it using the CrossmintWallets facade:
final wallets = CrossmintWallets.from(
client,
onAuthRequired: (signerType, signerLocator, needsAuth, sendOtp, verifyOtp, reject) async {
// Show your OTP prompt UI, then call verifyOtp(code) or reject().
await sendOtp();
final code = await showMyOtpDialog();
await verifyOtp(code);
},
);
final wallet = await wallets.getWallet(chain: 'base-sepolia');
await wallet.useSigner(CrossmintEmailSignerConfig(email: 'user@example.com'));
await wallet.sendToken('0xRecipient', 'usdc', '1.0');
For more details, see the Crossmint documentation.
Embedded Checkout #
The SDK includes CrossmintEmbeddedCheckout, a drop-in WebView widget for credit card and crypto payments. It supports fiat and crypto payment methods, custom theming, and can delegate crypto signing to a runtime wallet:
import 'package:crossmint_flutter/crossmint_flutter_ui.dart';
import 'package:crossmint_flutter/crossmint_flutter_wallets.dart';
final config = CrossmintCheckoutConfig(
order: CrossmintCheckoutNewOrder.typed(
lineItems: [
CrossmintCheckoutLineItem.collection(
collectionLocator: 'crossmint:your-collection-id',
callData: const {'quantity': 1},
),
],
),
payment: CrossmintCheckoutPayment(
crypto: CrossmintCheckoutCryptoPayment(
enabled: true,
payer: CrossmintEvmWalletCheckoutPayer(
wallet: wallet,
supportedChains: const ['base-sepolia'],
),
),
defaultMethodType: CrossmintCheckoutDefaultMethod.crypto,
),
);
// In your widget tree:
CrossmintEmbeddedCheckout(
apiKey: 'ck_staging_...',
config: config,
onOrderUpdated: (order) => debugPrint('Order: ${order.orderId}'),
);
Fiat-only checkout #
For a pure credit-card / Apple Pay / Google Pay flow, omit the crypto payer
and pass an email recipient so Crossmint mints into a managed wallet. Swap
in CrossmintCheckoutWalletRecipient when minting directly to a
user-owned external wallet address instead:
final config = CrossmintCheckoutConfig(
order: CrossmintCheckoutNewOrder.typed(
lineItems: [
CrossmintCheckoutLineItem.collection(
collectionLocator: 'crossmint:your-collection-id',
),
],
recipient: const CrossmintCheckoutEmailRecipient(email: 'user@example.com'),
),
payment: const CrossmintCheckoutPayment(
fiat: CrossmintCheckoutFiatPayment(enabled: true, defaultCurrency: 'USD'),
defaultMethodType: CrossmintCheckoutDefaultMethod.fiat,
),
);
Physical goods #
For a merchandise-style line item, use
CrossmintCheckoutPhysicalRecipient with a shipping address:
final config = CrossmintCheckoutConfig(
order: CrossmintCheckoutNewOrder.typed(
lineItems: [
CrossmintCheckoutLineItem.product(productLocator: 'crossmint:tshirt'),
],
recipient: CrossmintCheckoutPhysicalRecipient(
email: 'user@example.com',
physicalAddress: const CrossmintCheckoutPhysicalAddress(
name: 'Jane Doe',
line1: '123 Market St',
city: 'San Francisco',
state: 'CA',
postalCode: '94103',
country: 'US',
),
),
),
payment: const CrossmintCheckoutPayment(
fiat: CrossmintCheckoutFiatPayment(enabled: true),
),
);
Observing diagnostics #
onDiagnostic surfaces navigation blocks, malformed hosted messages, and
WebView resource errors — wire it to your logger in staging / production:
CrossmintEmbeddedCheckout(
apiKey: 'ck_staging_...',
config: config,
onDiagnostic: (diag) {
debugPrint('[${diag.severity.name}] ${diag.code}: ${diag.message}');
},
);
Demo Applications #
- Wallets Playground — the main example app with auth, wallets, signer management, and transaction flows. Supports multiple scenarios via environment config. See the playground feature checklist.
- Checkout Playground — a standalone app for interactively testing the embedded checkout widget with real-time configuration: payment methods, theming, product metadata, and more.
Building the SDK Locally #
- Clone the repository:
git clone https://github.com/Paella-Labs/crossmint-flutter-sdk.git
- Install dependencies:
cd crossmint-flutter-sdk
flutter pub get
- Run checks:
./scripts/check_pr_gate.sh
For dependency and publish validation:
./scripts/check_dependency_hygiene.sh
Documentation #
- Official Crossmint Docs
- Architecture
- Public API Spec
- Host App Integration Guide
Known Limitations #
- iOS physical-device test automation is limited by Flutter #184254 — physical iOS validation requires manual QA.
- Solana device signers are intentionally unsupported to match current Crossmint wallet behavior.
- Passkey signers require explicit callbacks (Stage 1). Native platform passkey support (Stage 2) is pending.
- Some Crossmint API families may require project entitlements.
Contact #
To get in touch with the Crossmint team, visit our contact page or find us on X.