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('user@example.com');
        }}
      />
    </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: 'user@example.com',
        }}
        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: 'user@example.com',
  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