> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getpara.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Expo

> Set up the Para SDK in an Expo project.

export const Link = ({href, label, newTab = false}) => {
  const [isHovered, setIsHovered] = useState(false);
  return <a href={href} target={newTab ? '_blank' : '_self'} rel={newTab ? 'noopener noreferrer' : undefined} className="not-prose inline-block relative text-black font-semibold cursor-pointer border-b-0 no-underline" onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}>
      {label}
      <span className={`absolute left-0 bottom-0 w-full rounded-sm bg-gradient-to-r from-orange-600 to-purple-600 transition-all duration-300 ${isHovered ? 'h-0.5' : 'h-px'}`} />
    </a>;
};

export const Card = ({imgUrl, title, description, href, horizontal = false, newTab = false}) => {
  const [isHovered, setIsHovered] = useState(false);
  const handleClick = e => {
    e.preventDefault();
    if (newTab) {
      window.open(href, '_blank', 'noopener,noreferrer');
    } else {
      window.location.href = href;
    }
  };
  return <div className={`not-prose relative my-2 p-[1px] rounded-xl transition-all duration-300 ${isHovered ? 'bg-gradient-to-r from-[#FF4E00] to-[#874AE3]' : 'bg-gray-200'}`} onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}>
      <a href={href} onClick={handleClick} className={`not-prose flex ${horizontal ? 'flex-row' : 'flex-col'} font-normal h-full bg-white overflow-hidden w-full cursor-pointer rounded-[11px] no-underline`}>
        {imgUrl && <div className={`relative overflow-hidden flex-shrink-0 ${horizontal ? 'w-[30%] rounded-l-[11px]' : 'w-full'}`} onClick={e => e.stopPropagation()}>
            <img src={imgUrl} alt={title} className="w-full h-full object-cover pointer-events-none select-none" draggable="false" />
            <div className="absolute inset-0 pointer-events-none" />
          </div>}
        <div className={`flex-grow px-6 py-5 ${horizontal ? 'w-[70%]' : 'w-full'} flex flex-col ${horizontal && imgUrl ? 'justify-center' : 'justify-start'}`}>
          {title && <h2 className="font-semibold text-base text-gray-800 m-0">{title}</h2>}
          {description && <div className={`font-normal text-gray-500 re leading-6 ${horizontal || !imgUrl ? 'mt-0' : 'mt-1'}`}>
              <p className="m-0 text-xs">{description}</p>
            </div>}
        </div>
      </a>
    </div>;
};

<Link label="Expo" href="https://expo.dev/" /> is a framework built on React Native that provides many out-of-the-box features, similar to NextJS for web but designed
for mobile development. Para provides a `@getpara/react-native-wallet` package that works seamlessly in both React Native bare and Expo workflows.

## Prerequisites

To use Para, you need an API key. This key authenticates your requests to Para services and is essential for integration.

<Warning>
  Don't have an API key yet? Request access to the <Link label="Developer Portal" href="https://developer.getpara.com" /> to create API keys, manage billing, teams, and more.
</Warning>

## Dependency Installation

Install the required dependencies:

<CodeGroup>
  ```bash npm theme={null}
  npm install @getpara/react-native-wallet @react-native-async-storage/async-storage react-native-keychain react-native-modpow react-native-nitro-modules react-native-passkey react-native-quick-base64 @craftzdog/react-native-buffer react-native-quick-crypto viem --save-exact
  ```

  ```bash yarn theme={null}
  yarn add @getpara/react-native-wallet @react-native-async-storage/async-storage react-native-keychain react-native-modpow react-native-nitro-modules react-native-passkey react-native-quick-base64 @craftzdog/react-native-buffer react-native-quick-crypto viem --exact
  ```

  ```bash pnpm theme={null}
  pnpm add @getpara/react-native-wallet @react-native-async-storage/async-storage react-native-keychain react-native-modpow react-native-nitro-modules react-native-passkey react-native-quick-base64 @craftzdog/react-native-buffer react-native-quick-crypto viem --save-exact
  ```

  ```bash bun theme={null}
  bun add @getpara/react-native-wallet @react-native-async-storage/async-storage react-native-keychain react-native-modpow react-native-nitro-modules react-native-passkey react-native-quick-base64 @craftzdog/react-native-buffer react-native-quick-crypto viem --exact
  ```
</CodeGroup>

## Project Setup

<Info>If you plan to use native passkeys, additional platform configuration (associated domains, SHA-256 fingerprints) is required. See <Link label="Add Passkeys" href="/v2/react-native/guides/add-passkeys" /> for iOS and Android setup.</Info>

### Configure Metro Bundler

Create or update `metro.config.js` so Metro knows how to resolve the Node polyfills Para depends on (for example `crypto` and `buffer`). For more details on Metro configuration, see the <Link label="official Expo Metro documentation" href="https://docs.expo.dev/versions/latest/config/metro/" />.

```javascript metro.config.js theme={null}
const { getDefaultConfig } = require("expo/metro-config");

const config = getDefaultConfig(__dirname);

config.resolver.extraNodeModules = {
  crypto: require.resolve("react-native-quick-crypto"),
  buffer: require.resolve("@craftzdog/react-native-buffer"),
};

module.exports = config;
```

### Import Required Shims

Import the Para Wallet shim in your root layout file to ensure proper global module shimming. This ensures that the necessary modules are available globally in your application. Ensure this is the very first import in your root layout file.

```typescript app/_layout.tsx theme={null}
import "@getpara/react-native-wallet/shim";
// ... rest of your imports and layout code
```

<Note>
  Alternatively, you can create a custom entry point to handle the shimming. This will ensure that the shim occurs before the Expo Router entry point.

  <Accordion title="Custom Entry Point">
    Create `index.js` in your project root and add the following imports:

    ```javascript index.js theme={null}
    import "@getpara/react-native-wallet/shim";
    import "expo-router/entry";
    ```

    Update `package.json` to point to your new entry file:

    ```json package.json theme={null}
    {
      "main": "index.js"
    }
    ```
  </Accordion>
</Note>

### Prebuild and Run

Since native modules are required, you'll need to use Expo Development Build to ensure that linking is successful. This means using the `expo prebuild` command to generate the necessary native code and then run your app using `expo run:ios` or `expo run:android`.

```bash theme={null}
npx expo prebuild
npx expo run:ios
npx expo run:android
```

<Warning>You **cannot** use Expo Go as it doesn't support native module linking. When running via `yarn start`, switch to development mode by pressing `s`, then `i` for iOS or `a` for Android.</Warning>

## Initialize the SDK

Set up the Para client singleton and initialize it in your app:

```typescript para.ts theme={null}
import { ParaMobile } from "@getpara/react-native-wallet";

export const para = new ParaMobile(YOUR_API_KEY, undefined, {
  disableWorkers: true,
});
```

Initialize it in your app entry point:

```typescript app/_layout.tsx theme={null}
import { para } from "../para";
import { useEffect } from "react";

export default function Layout() {
  useEffect(() => {
    const initPara = async () => {
      await para.init();
    };

    initPara();
  }, []);
  // ... rest of your layout code
}
```

<Note>
  **Beta Testing Credentials** In the `BETA` Environment, you can use any email ending in `@test.getpara.com` (like
  [dev@test.getpara.com](mailto:dev@test.getpara.com)) or US phone numbers (+1) in the format `(area code)-555-xxxx` (like (425)-555-1234). Any OTP
  code will work for verification with these test credentials. These credentials are for beta testing only. You can
  delete test users anytime in the beta developer console to free up user slots.
</Note>

<Note>If you're using a legacy API key (one without an environment prefix) you must provide the `Environment` as the first argument to the `ParaMobile` constructor. You can retrieve your updated API key from the Para Developer Portal at [https://developer.getpara.com/](https://developer.getpara.com/)</Note>

## Examples

<Card horizontal title="Para Expo Integration Examples" imgUrl="/images/v2/framework-expo.png" href="https://github.com/getpara/examples-hub/tree/2.0.0/mobile/with-expo-one-click-login" description="Explore our repository containing Expo implementations, along with shared UI components demonstrating Para integration." />

## Troubleshooting

<AccordionGroup>
  <Accordion title="Para SDK initialization fails">
    If you're having trouble initializing the Para SDK:

    * Ensure that you've called `para.init()` after creating the Para instance.
    * Verify that you're using the correct API key and environment.
    * Check that all necessary dependencies are installed and linked properly.
    * Look for any JavaScript errors in your Expo bundler console.
  </Accordion>

  <Accordion title="Native modules are not found or linked">
    If you're seeing errors about missing native modules:

    * Ensure you've run `expo prebuild` to generate native code.
    * Run `expo run:ios` and `expo run:android` to rebuild your app after adding new native dependencies.
    * Verify that your `app.json` file includes the necessary configurations for native modules.
  </Accordion>

  <Accordion title="Crypto-related errors or undefined functions">
    If you're seeing errors related to crypto functions:

    * Ensure you've properly set up the `expo-crypto` and `react-native-quick-crypto` polyfills.
    * Verify that your `metro.config.js` file is configured correctly to include the necessary Node.js core modules.
    * Check that you've imported the shim file at the top of your root layout or `index.js` file.
  </Accordion>

  <Accordion title="Authentication fails or API requests are rejected">
    If you're experiencing authentication issues:

    * Double-check that your API key is correct and properly set in your environment variables.
    * Verify you're using the correct environment (`BETA` or `PRODUCTION`) that matches your API key.
    * Ensure your account has the necessary permissions for the operations you're attempting.
    * Check your network requests for any failed API calls and examine the error messages.
  </Accordion>

  <Accordion title="Expo-specific build issues">
    If you're encountering problems during the Expo build process:

    * Ensure you're using a compatible Expo SDK version with all your dependencies.
    * Run `expo doctor` to check for any configuration issues in your project.
    * For EAS builds, check your `eas.json` configuration and ensure it's set up correctly for both iOS and Android.
  </Accordion>
</AccordionGroup>

For a more comprehensive list of solutions, visit our <Link label="troubleshooting guide" href="/v2/react-native/troubleshooting" />.

## Next Steps

<CardGroup cols={3}>
  <Card title="Email & Phone Login" imgUrl="/images/v2/custom-ui-social.png" href="/v2/react-native/guides/add-email-phone" description="Add email and phone authentication to your app." />

  <Card title="Add Social Login" imgUrl="/images/v2/custom-ui-social.png" href="/v2/react-native/guides/add-social-login" description="Authenticate users with Google, Apple, Discord, and more." />

  <Card title="EVM Integration" imgUrl="/images/v2/network-evm.png" href="/v2/react-native/guides/evm" description="Use Para with EVM-compatible libraries like ethers.js and viem." />
</CardGroup>
