Skip to main content

Prerequisites

Before integrating Para into your React Native app, make sure you have:
  1. An API key — create your account at the
  2. A React Native project — bare workflow or Expo development build (managed workflow is not supported)

Install

yarn add @getpara/react-native-wallet @tanstack/react-query @react-native-async-storage/async-storage react-native-keychain react-native-modpow react-native-passkey react-native-quick-base64 @craftzdog/react-native-buffer react-native-quick-crypto
For iOS, run cd ios && pod install after installing to link native dependencies.

Set Up the Provider

Import the crypto shim at your app’s entry point, then wrap your app with ParaProvider and a React Query QueryClientProvider:
App.tsx
import "@getpara/react-native-wallet/shim";

import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ParaProvider } from "@getpara/react-native-wallet";

const queryClient = new QueryClient();

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <ParaProvider
        paraClientConfig={{ apiKey: "YOUR_API_KEY" }}
        config={{ appName: "My App" }}
      >
        <AppContent />
      </ParaProvider>
    </QueryClientProvider>
  );
}
If you’re using a legacy API key (one without an environment prefix), pass env explicitly: paraClientConfig={{ apiKey: "YOUR_API_KEY", env: Environment.BETA }}.

Authenticate a User

Use the built-in hooks to handle authentication:
AuthScreen.tsx
import {
  useSignUpOrLogIn,
  useVerifyNewAccount,
  useIsFullyLoggedIn,
} from "@getpara/react-native-wallet";
import { useState } from "react";
import { View, TextInput, Button, Text } from "react-native";

export function AuthScreen() {
  const [email, setEmail] = useState("");
  const [code, setCode] = useState("");
  const { data: isFullyLoggedIn } = useIsFullyLoggedIn();
  const { signUpOrLogInAsync, isPending: isSending } = useSignUpOrLogIn();
  const { verifyNewAccountAsync, isPending: isVerifying } =
    useVerifyNewAccount();

  if (isFullyLoggedIn) {
    return <Text>You're logged in!</Text>;
  }

  const handleSendCode = async () => {
    await signUpOrLogInAsync({ email });
  };

  const handleVerify = async () => {
    await verifyNewAccountAsync({ verificationCode: code });
  };

  return (
    <View>
      <TextInput value={email} onChangeText={setEmail} placeholder="Email" />
      <Button
        title={isSending ? "Sending..." : "Send Code"}
        onPress={handleSendCode}
        disabled={isSending}
      />
      <TextInput
        value={code}
        onChangeText={setCode}
        placeholder="Verification code"
      />
      <Button
        title={isVerifying ? "Verifying..." : "Verify"}
        onPress={handleVerify}
        disabled={isVerifying}
      />
    </View>
  );
}

Sign a Message

Once authenticated, use the useSignMessage hook:
SignScreen.tsx
import { useSignMessage, useWallet } from "@getpara/react-native-wallet";
import { Button, Alert } from "react-native";

export function SignScreen() {
  const { data: wallet } = useWallet();
  const { signMessageAsync, isPending } = useSignMessage();

  const handleSign = async () => {
    if (!wallet) return;
    const result = await signMessageAsync({
      walletId: wallet.id,
      messageBase64: btoa("Hello, Para!"),
    });
    Alert.alert("Signature", `0x${result.signature}`);
  };

  return (
    <Button
      title={isPending ? "Signing..." : "Sign Message"}
      onPress={handleSign}
      disabled={isPending}
    />
  );
}
Need an API Key? Head to the to create your account and get your API key.

Next Steps