Skip to main content

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

apiKey
string
required
Your Crossmint API key from the Developer Console
consoleLogLevel
'debug' | 'info' | 'warn' | 'error' | 'silent'
default:"debug"
Minimum log level for console output
overrideBaseUrl
string
Override the default API base URL

App Configuration

The SDK automatically reads your app’s bundle identifier from Expo config:
app.json
{
  "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
appearance
UIConfig
Customize the auth UI appearance
onLoginSuccess
(user) => void
Callback fired when user successfully authenticates
authModalTitle
string
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
string | undefined
JWT token for the authenticated user
login
(defaultEmail?: string) => void
Opens the authentication modal
logout
() => Promise<void>
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

createOnLogin
CreateOnLogin
Automatically create a wallet when user logs in
createOnLogin={{ chain: 'ethereum' | 'solana' | 'stellar' }}
showPasskeyHelpers
boolean
default:true
Show UI helpers for passkey creation and management
appearance
UIConfig
Customize wallet UI appearance
callbacks
object
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
Wallet
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

lineItems
object
required
Items to purchase:
{
  collectionLocator: 'crossmint:collection-id',
  callData: { totalPrice: '0.1', quantity: 1 }
}
payment
object
Payment method configuration:
{
  crypto: { enabled: true },
  fiat: { enabled: true }
}
recipient
object
Recipient details:
{
  email: '[email protected]',
  wallet: '0x...' // Optional delivery address
}
locale
string
Checkout UI locale (e.g., ‘en-US’, ‘es-ES’)
appearance
object
Customize checkout appearance
onEvent
(event) => void
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';

Platform-Specific Considerations

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

Build docs developers (and LLMs) love