Installation
npm install @crossmint/client-sdk-react-native-ui
Peer Dependencies
The SDK requires Expo and React Native:
npm install expo react-native
Setup
Wrap your application with CrossmintProvider:
import { CrossmintProvider } from '@crossmint/client-sdk-react-native-ui';
import { View } from 'react-native';
export default function App() {
return (
<CrossmintProvider apiKey="YOUR_API_KEY">
<View>{/* Your app components */}</View>
</CrossmintProvider>
);
}
Provider Props
consoleLogLevel
'debug' | 'info' | 'warn' | 'error' | 'silent'
default:"debug"
Minimum log level for console output
Override the default API base URL
App Configuration
The SDK automatically reads your app’s bundle identifier from Expo config:
{
"expo": {
"ios": {
"bundleIdentifier": "com.yourcompany.yourapp"
},
"android": {
"package": "com.yourcompany.yourapp"
}
}
}
See implementation at /home/daytona/workspace/source/packages/client/ui/react-native/src/providers/CrossmintProvider.tsx:32
Authentication
CrossmintAuthProvider
Enables authentication with multiple methods:
import {
CrossmintAuthProvider,
useCrossmintAuth
} from '@crossmint/client-sdk-react-native-ui';
import { View, Button, Text } from 'react-native';
function App() {
return (
<CrossmintProvider apiKey="YOUR_API_KEY">
<CrossmintAuthProvider
loginMethods={['email', 'google', 'twitter']}
onLoginSuccess={(user) => console.log('Logged in:', user)}
>
<AuthScreen />
</CrossmintAuthProvider>
</CrossmintProvider>
);
}
function AuthScreen() {
const { login, logout, status, user } = useCrossmintAuth();
if (status === 'authenticated') {
return (
<View>
<Text>Logged in as {user?.email}</Text>
<Button title="Sign Out" onPress={logout} />
</View>
);
}
return <Button title="Sign In" onPress={() => login()} />;
}
Props
loginMethods
array
default:["email","google"]
Available login methods:
'email' - Email OTP authentication
'google' - Google OAuth
'twitter' - Twitter OAuth
'farcaster' - Farcaster authentication
Customize the auth UI appearance
Callback fired when user successfully authenticates
Custom title for the authentication modal
useCrossmintAuth Hook
Access authentication state and methods:
import { useCrossmintAuth } from '@crossmint/client-sdk-react-native-ui';
import { View, Text, Button } from 'react-native';
function LoginButton() {
const { login, logout, status, user, jwt } = useCrossmintAuth();
if (status === 'authenticated') {
return (
<View>
<Text>User: {user?.email}</Text>
<Text>JWT: {jwt?.slice(0, 20)}...</Text>
<Button title="Sign Out" onPress={logout} />
</View>
);
}
return <Button title="Sign In" onPress={() => login()} />;
}
Return Values
status
'initializing' | 'authenticated' | 'not-authenticated'
Current authentication status
user
SDKExternalUser | undefined
Authenticated user with email, userId, and linkedAccounts
JWT token for the authenticated user
login
(defaultEmail?: string) => void
Opens the authentication modal
Signs out the current user
Wallet Management
CrossmintWalletProvider
Manages custodial wallet creation and transactions:
import {
CrossmintWalletProvider,
useWallet
} from '@crossmint/client-sdk-react-native-ui';
import type { EVMWallet } from '@crossmint/client-sdk-react-native-ui';
import { View, Text, Button } from 'react-native';
function App() {
return (
<CrossmintProvider apiKey="YOUR_API_KEY">
<CrossmintAuthProvider>
<CrossmintWalletProvider
createOnLogin={{ chain: 'ethereum' }}
callbacks={{
onWalletCreationStart: async () => {
console.log('Creating wallet...');
},
onTransactionStart: async () => {
console.log('Transaction starting...');
},
}}
>
<WalletScreen />
</CrossmintWalletProvider>
</CrossmintAuthProvider>
</CrossmintProvider>
);
}
function WalletScreen() {
const { wallet, status } = useWallet<EVMWallet>();
if (status === 'not-loaded') {
return <Text>No wallet</Text>;
}
return (
<View>
<Text>Address: {wallet.address}</Text>
<Text>Chain: {wallet.chain}</Text>
<Button
title="Get Balance"
onPress={async () => {
const balance = await wallet.getBalance();
console.log('Balance:', balance);
}}
/>
</View>
);
}
Props
Automatically create a wallet when user logs increateOnLogin={{ chain: 'ethereum' | 'solana' | 'stellar' }}
Show UI helpers for passkey creation and management
Customize wallet UI appearance
Lifecycle callbacks:
onWalletCreationStart - Called before wallet creation
onTransactionStart - Called before transaction signing
useWallet Hook
Access wallet state and methods:
import { useWallet } from '@crossmint/client-sdk-react-native-ui';
import type { SolanaWallet } from '@crossmint/client-sdk-react-native-ui';
import { View, Text, Button } from 'react-native';
function SolanaWalletInfo() {
const { wallet, status } = useWallet<SolanaWallet>();
if (status !== 'loaded') {
return <Text>Loading wallet...</Text>;
}
return (
<View>
<Text>Address: {wallet.address}</Text>
<Button
title="Sign Message"
onPress={async () => {
const signature = await wallet.signMessage('Hello Solana!');
console.log('Signature:', signature);
}}
/>
</View>
);
}
Return Values
Wallet instance (EVMWallet, SolanaWallet, or StellarWallet) with methods:
address - Wallet address
chain - Blockchain identifier
getBalance() - Fetch wallet balance
signMessage(message) - Sign arbitrary message
sendTransaction(tx) - Send transaction
status
'not-loaded' | 'loading' | 'loaded'
Current wallet loading status
useWalletEmailSigner Hook
Manage email-based transaction signing:
import { useWalletEmailSigner } from '@crossmint/client-sdk-react-native-ui';
import { View, Button } from 'react-native';
function EmailSignerSettings() {
const { requestEmailSigner } = useWalletEmailSigner();
return (
<View>
<Button
title="Add Email Signer"
onPress={async () => {
await requestEmailSigner('[email protected]');
}}
/>
</View>
);
}
Checkout Components
CrossmintEmbeddedCheckout
Embedded checkout WebView for accepting payments:
import { CrossmintEmbeddedCheckout } from '@crossmint/client-sdk-react-native-ui';
import { View } from 'react-native';
function CheckoutScreen() {
return (
<View style={{ flex: 1 }}>
<CrossmintEmbeddedCheckout
lineItems={{
collectionLocator: 'crossmint:collection-id',
callData: {
totalPrice: '0.1',
quantity: 1,
},
}}
payment={{
crypto: { enabled: true },
fiat: { enabled: true },
}}
recipient={{
email: '[email protected]',
}}
onEvent={(event) => {
console.log('Checkout event:', event);
if (event.type === 'order:completed') {
// Navigate to success screen
}
}}
/>
</View>
);
}
Props
Items to purchase:{
collectionLocator: 'crossmint:collection-id',
callData: { totalPrice: '0.1', quantity: 1 }
}
Payment method configuration:{
crypto: { enabled: true },
fiat: { enabled: true }
}
Checkout UI locale (e.g., ‘en-US’, ‘es-ES’)
Customize checkout appearance
Callback for checkout events:
'order:created' - Order was created
'order:completed' - Payment completed successfully
'order:failed' - Payment failed
useCrossmintCheckout Hook
Access current checkout order state:
import { useCrossmintCheckout } from '@crossmint/client-sdk-react-native-ui';
import { View, Text } from 'react-native';
function OrderStatus() {
const { order, orderClientSecret } = useCrossmintCheckout();
if (!order) return null;
return (
<View>
<Text>Order ID: {order.id}</Text>
<Text>Status: {order.status}</Text>
<Text>Total: {order.totalPrice}</Text>
</View>
);
}
Hooks Reference
All hooks exported from /home/daytona/workspace/source/packages/client/ui/react-native/src/hooks:
useCrossmint
import { useCrossmint } from '@crossmint/client-sdk-react-native-ui';
const { crossmint, experimental_customAuth } = useCrossmint();
Provides access to the core Crossmint SDK instance.
useAuth
Alias for useCrossmintAuth.
Type Exports
Key TypeScript types:
import type {
// Provider types
CrossmintProviderProps,
CrossmintWalletProviderProps,
// Auth types
SDKExternalUser,
OAuthProvider,
// Wallet types
Wallet,
EVMWallet,
SolanaWallet,
StellarWallet,
DelegatedSigner,
// Transaction types
Transaction,
Signature,
Activity,
Balances,
Chain,
// Event types
CrossmintEvent,
CrossmintEventMap,
} from '@crossmint/client-sdk-react-native-ui';
iOS
- OAuth flows open in
SFSafariViewController
- Ensure your bundle identifier is configured in
app.json
- Handle deep links for OAuth callback
Android
- OAuth flows use Chrome Custom Tabs
- Configure package name in
app.json
- Add intent filters for OAuth redirect URIs
WebView Security
The checkout component uses a secure WebView implementation. See:
/home/daytona/workspace/source/packages/client/ui/react-native/src/components/embed/v3/CrossmintEmbeddedCheckoutV3.tsx
Example App Structure
import {
CrossmintProvider,
CrossmintAuthProvider,
CrossmintWalletProvider,
useCrossmintAuth,
useWallet
} from '@crossmint/client-sdk-react-native-ui';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
const Stack = createNativeStackNavigator();
export default function App() {
return (
<CrossmintProvider apiKey="YOUR_API_KEY">
<CrossmintAuthProvider loginMethods={['email', 'google']}>
<CrossmintWalletProvider createOnLogin={{ chain: 'ethereum' }}>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Wallet" component={WalletScreen} />
<Stack.Screen name="Checkout" component={CheckoutScreen} />
</Stack.Navigator>
</NavigationContainer>
</CrossmintWalletProvider>
</CrossmintAuthProvider>
</CrossmintProvider>
);
}
Next Steps
React SDK
Compare with web SDK features
Auth SDK
Build custom auth flows
Expo Documentation
Learn more about Expo
Examples
View example apps