> ## 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.

# Account Abstraction Integrations

> Set up smart accounts with Para's unified SDK interface across all supported AA providers on React Native

## Account Abstraction

Account abstraction (AA) replaces traditional externally owned accounts (EOAs) with programmable smart contract accounts. This unlocks capabilities that EOAs alone cannot provide:

* **Gas sponsorship** — let users transact without holding native tokens for gas fees
* **Batched transactions** — bundle multiple operations into a single atomic transaction
* **Session keys** — grant temporary, scoped permissions without exposing the primary key
* **Custom authorization** — implement multi-factor auth, spending limits, or recovery logic at the account level
* **Programmable accounts** — create accounts with built-in rules for corporate or multi-user scenarios

Two standards are currently in use for AA on EVM-based chains:

|                     | EIP-4337                                                        | EIP-7702                                                   |
| ------------------- | --------------------------------------------------------------- | ---------------------------------------------------------- |
| **How it works**    | UserOperations processed by bundlers via an EntryPoint contract | EOA delegates to a smart contract via a type-4 transaction |
| **Account address** | New smart contract address (different from EOA)                 | Same as your EOA                                           |
| **Chain support**   | All EVM chains                                                  | Requires chain-level support                               |
| **Infrastructure**  | Bundler + Paymaster                                             | Provider-dependent                                         |
| **Gas overhead**    | Higher (extra validation steps)                                 | Lower (native execution)                                   |
| **Maturity**        | Production-ready                                                | Emerging                                                   |
| **Best for**        | Maximum compatibility, dedicated smart wallet                   | Keeping EOA address, simpler flows                         |

Both standards support **gas sponsorship** and **batched transactions**.

<Tip>
  Learn more about [EIP-4337](https://eips.ethereum.org/EIPS/eip-4337) and [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) on the Ethereum Improvement Proposals site.
</Tip>

## Para Integrations

Para acts as the **signer** (EOA) that controls smart contract wallets — it is not a smart wallet itself. Para handles secure key management via MPC, while the AA provider deploys and manages the smart contract account on-chain. This means your users' private keys remain secure and under their control regardless of which provider you choose.

Para wraps each provider in a shared `SmartAccount` interface. Whether you use EIP-4337 or EIP-7702 mode, your application code stays the same — you can swap providers or switch between standards without rewriting transaction logic.

Every provider integration is available as an **action function** (`createXxxSmartAccount`) — an imperative async function you can call anywhere, including outside React components, inside custom hooks, or in server-side code. React Native applications also get a **hook** (`useXxxSmartAccount`) — a declarative wrapper powered by React Query that handles initialization, caching, and automatic re-creation when config changes.

Both return the same `SmartAccount` object:

```typescript theme={null}
import type { Chain, Hex, LocalAccount, TransactionReceipt } from "viem";

interface SmartAccount {
  smartAccountAddress: Hex;              // On-chain account address
  signer: LocalAccount;                 // Para viem signer
  chain: Chain;                          // Configured chain
  mode: "4337" | "7702";                // Account type
  provider: string;                      // Provider name

  // Send a single transaction and wait for receipt
  sendTransaction(params: {
    to: Hex;
    value?: bigint;
    data?: Hex;
  }): Promise<TransactionReceipt>;

  // Send batched transactions atomically
  sendBatchTransaction(calls: Array<{
    to: Hex;
    value?: bigint;
    data?: Hex;
  }>): Promise<TransactionReceipt>;

  client: any;                           // Provider-specific client for advanced usage
}
```

When using `mode: "7702"`, the return type narrows to include an optional `delegationAddress` field — the smart
contract the EOA delegates to. When using `mode: "4337"`, `smartAccountAddress` is the counterfactual smart
contract address (different from `signer.address`).

## Provider Comparison

| Provider                                                      | 4337 | 7702 | Chain Restrictions                        | Key Feature                                       |
| ------------------------------------------------------------- | :--: | :--: | ----------------------------------------- | ------------------------------------------------- |
| [Alchemy](https://accountkit.alchemy.com/react/quickstart)    |   ✓  |   ✓  | Alchemy-supported chains                  | Modular accounts, gas policies                    |
| [ZeroDev](https://docs.zerodev.app/)                          |   ✓  |   ✓  | Any EVM chain                             | Kernel accounts, session keys, plugins            |
| [Pimlico](https://docs.pimlico.io/)                           |   ✓  |   ✓  | Any EVM chain                             | Permissionless SDK, flexible paymaster            |
| [Biconomy](https://docs.biconomy.io/)                         |   ✓  |   ✓  | MEE-supported chains                      | Cross-chain orchestration via MEE                 |
| [Thirdweb](https://portal.thirdweb.com/)                      |   ✓  |   ✓  | Any EVM chain                             | Smart wallets, gas sponsorship                    |
| [Gelato](https://docs.gelato.network/)                        |      |   ✓  | Any EVM chain                             | Native 7702, built-in gas sponsorship             |
| [Porto](https://porto.sh)                                     |      |   ✓  | [Multiple chains](https://porto.sh/relay) | 7702-native relay, merchant-based gas sponsorship |
| [Safe](https://docs.safe.global/)                             |   ✓  |      | Any EVM chain                             | Multi-sig, modular accounts                       |
| [Rhinestone](https://docs.rhinestone.wtf/)                    |   ✓  |      | Any EVM chain                             | Cross-chain orchestration                         |
| [Coinbase Developer Platform](https://docs.cdp.coinbase.com/) |   ✓  |      | Base, Base Sepolia only                   | Coinbase smart accounts                           |

## Provider Guides

Select a provider below for installation and usage instructions.

<Tabs>
  <Tab title="Alchemy">
    Alchemy Account Kit provides modular smart accounts with built-in gas sponsorship via Alchemy's Gas Manager. Create and manage smart accounts, submit gasless transactions, and execute batched UserOperations — all without requiring users to leave your application. Supports both EIP-4337 and EIP-7702 modes.

    ### Setup

    1. Create an [Alchemy account](https://dashboard.alchemy.com/signup) and obtain your **API key** and **Gas Policy ID** from the Alchemy dashboard.

    2. Install the required dependencies:

    <CodeGroup>
      ```bash npm theme={null}
      npm install @getpara/react-native-wallet @getpara/aa-alchemy viem
      ```

      ```bash yarn theme={null}
      yarn add @getpara/react-native-wallet @getpara/aa-alchemy viem
      ```

      ```bash pnpm theme={null}
      pnpm add @getpara/react-native-wallet @getpara/aa-alchemy viem
      ```
    </CodeGroup>

    ### Usage

    <Tabs>
      <Tab title="useAlchemySmartAccount">
        The simplest way to integrate Alchemy smart accounts into your React Native application. The hook manages initialization, caching, and re-creation automatically via React Query.

        ```tsx AlchemySmartAccount.tsx theme={null}
        import { useAlchemySmartAccount } from "@getpara/react-native-wallet";
        import { useMutation } from "@tanstack/react-query";
        import { View, Text, Button } from "react-native";
        import { sepolia } from "viem/chains";
        import { parseEther } from "viem";

        const ALCHEMY_API_KEY = process.env.EXPO_PUBLIC_ALCHEMY_API_KEY!;
        const GAS_POLICY_ID = process.env.EXPO_PUBLIC_ALCHEMY_GAS_POLICY_ID!;

        export function AlchemySmartAccount() {
          // Initialize the smart account. The hook handles Para signer creation,
          // account client setup, and paymaster configuration internally.
          // It re-creates the account automatically if any config value changes.
          const { smartAccount, isLoading, error } = useAlchemySmartAccount({
            apiKey: ALCHEMY_API_KEY,
            chain: sepolia,
            gasPolicyId: GAS_POLICY_ID, // enables gas sponsorship
            mode: "4337", // or "7702" — see EIP comparison above
          });

          // Wrap sendTransaction in a mutation for loading/error state management.
          const {
            mutate: sendTransaction,
            isPending: isSending,
            error: sendError,
          } = useMutation({
            mutationFn: async () => {
              if (!smartAccount) throw new Error("Smart account not ready");
              return smartAccount.sendTransaction({
                to: "0xRecipient",
                value: parseEther("0.01"),
              });
            },
            onSuccess: (receipt) => {
              console.log("Transaction hash:", receipt.transactionHash);
            },
          });

          // Wrap sendBatchTransaction for executing multiple calls atomically.
          // All calls are bundled into a single on-chain transaction.
          const {
            mutate: sendBatch,
            isPending: isBatching,
            error: batchError,
          } = useMutation({
            mutationFn: async () => {
              if (!smartAccount) throw new Error("Smart account not ready");
              return smartAccount.sendBatchTransaction([
                { to: "0xRecipientA", value: parseEther("0.01") },
                { to: "0xRecipientB", data: "0xencodedCallData" },
              ]);
            },
            onSuccess: (receipt) => {
              console.log("Batch tx hash:", receipt.transactionHash);
            },
          });

          if (isLoading) return <Text>Setting up smart account...</Text>;
          if (error) return <Text>Error: {error.message}</Text>;
          if (!smartAccount) return null;

          return (
            <View>
              <Text>Smart Account: {smartAccount.smartAccountAddress}</Text>
              <Text>Mode: {smartAccount.mode}</Text>
              <Button
                title={isSending ? "Sending..." : "Send Transaction"}
                onPress={() => sendTransaction()}
                disabled={isSending}
              />
              {sendError && <Text>Send failed: {sendError.message}</Text>}
              <Button
                title={isBatching ? "Batching..." : "Send Batch"}
                onPress={() => sendBatch()}
                disabled={isBatching}
              />
              {batchError && <Text>Batch failed: {batchError.message}</Text>}
            </View>
          );
        }
        ```
      </Tab>

      <Tab title="createAlchemySmartAccount">
        For use outside React components or when you need more control over initialization.

        ```typescript alchemy-action.ts theme={null}
        import { createAlchemySmartAccount } from "@getpara/aa-alchemy";
        import { sepolia } from "viem/chains";
        import { parseEther } from "viem";

        // `para` is your authenticated Para instance
        const smartAccount = await createAlchemySmartAccount({
          para,
          apiKey: "YOUR_ALCHEMY_API_KEY",
          chain: sepolia,
          gasPolicyId: "YOUR_GAS_POLICY_ID",
          mode: "4337", // or "7702"
        });

        if (smartAccount) {
          // Send a single transaction
          const receipt = await smartAccount.sendTransaction({
            to: "0xRecipient",
            value: parseEther("0.01"),
          });

          // Send batched transactions
          const batchReceipt = await smartAccount.sendBatchTransaction([
            { to: "0xRecipientA", value: parseEther("0.01") },
            { to: "0xRecipientB", data: "0xencodedCallData" },
          ]);
        }
        ```
      </Tab>
    </Tabs>

    <Note>
      Alchemy requires chains from `@account-kit/infra` (e.g. `sepolia`, `baseSepolia`). Plain viem chains are automatically mapped if an Alchemy equivalent exists. For gasless transactions, set up a Gas Manager Policy in your [Alchemy Dashboard](https://dashboard.alchemy.com) and pass the policy ID as `gasPolicyId`.
    </Note>
  </Tab>

  <Tab title="ZeroDev">
    [ZeroDev](https://docs.zerodev.app/) is an embedded AA wallet powering many smart accounts across EVM chains. Known for its extensive feature set including gas sponsorship, session keys, recovery, multisig, and chain abstraction. Supports both EIP-4337 and EIP-7702 modes.

    ### Setup

    1. Create a [ZeroDev account](https://dashboard.zerodev.app/) and obtain your **Project ID** from the ZeroDev dashboard.

    2. Install the required dependencies:

    <CodeGroup>
      ```bash npm theme={null}
      npm install @getpara/react-native-wallet @getpara/aa-zerodev viem
      ```

      ```bash yarn theme={null}
      yarn add @getpara/react-native-wallet @getpara/aa-zerodev viem
      ```

      ```bash pnpm theme={null}
      pnpm add @getpara/react-native-wallet @getpara/aa-zerodev viem
      ```
    </CodeGroup>

    ### Usage

    <Tabs>
      <Tab title="useZeroDevSmartAccount">
        The simplest way to integrate ZeroDev smart accounts into your React Native application. The hook manages initialization, caching, and re-creation automatically via React Query.

        ```tsx ZeroDevSmartAccount.tsx theme={null}
        import { useZeroDevSmartAccount } from "@getpara/react-native-wallet";
        import { useMutation } from "@tanstack/react-query";
        import { View, Text, Button } from "react-native";
        import { sepolia } from "viem/chains";
        import { parseEther } from "viem";

        const ZERODEV_PROJECT_ID = process.env.EXPO_PUBLIC_ZERODEV_PROJECT_ID!;

        export function ZeroDevSmartAccount() {
          // Initialize the smart account. The hook handles Para signer creation,
          // Kernel account setup, and ECDSA validator configuration internally.
          const { smartAccount, isLoading, error } = useZeroDevSmartAccount({
            projectId: ZERODEV_PROJECT_ID,
            chain: sepolia,
            mode: "4337", // or "7702"
          });

          const {
            mutate: sendTransaction,
            isPending: isSending,
            error: sendError,
          } = useMutation({
            mutationFn: async () => {
              if (!smartAccount) throw new Error("Smart account not ready");
              return smartAccount.sendTransaction({
                to: "0xRecipient",
                value: parseEther("0.01"),
              });
            },
            onSuccess: (receipt) => {
              console.log("Transaction hash:", receipt.transactionHash);
            },
          });

          const {
            mutate: sendBatch,
            isPending: isBatching,
            error: batchError,
          } = useMutation({
            mutationFn: async () => {
              if (!smartAccount) throw new Error("Smart account not ready");
              return smartAccount.sendBatchTransaction([
                { to: "0xRecipientA", value: parseEther("0.01") },
                { to: "0xRecipientB", data: "0xencodedCallData" },
              ]);
            },
            onSuccess: (receipt) => {
              console.log("Batch tx hash:", receipt.transactionHash);
            },
          });

          if (isLoading) return <Text>Setting up smart account...</Text>;
          if (error) return <Text>Error: {error.message}</Text>;
          if (!smartAccount) return null;

          return (
            <View>
              <Text>Smart Account: {smartAccount.smartAccountAddress}</Text>
              <Text>Mode: {smartAccount.mode}</Text>
              <Button
                title={isSending ? "Sending..." : "Send Transaction"}
                onPress={() => sendTransaction()}
                disabled={isSending}
              />
              {sendError && <Text>Send failed: {sendError.message}</Text>}
              <Button
                title={isBatching ? "Batching..." : "Send Batch"}
                onPress={() => sendBatch()}
                disabled={isBatching}
              />
              {batchError && <Text>Batch failed: {batchError.message}</Text>}
            </View>
          );
        }
        ```
      </Tab>

      <Tab title="createZeroDevSmartAccount">
        For use outside React components or when you need more control over initialization.

        ```typescript zerodev-action.ts theme={null}
        import { createZeroDevSmartAccount } from "@getpara/aa-zerodev";
        import { sepolia } from "viem/chains";
        import { parseEther } from "viem";

        // `para` is your authenticated Para instance
        const smartAccount = await createZeroDevSmartAccount({
          para,
          projectId: "YOUR_ZERODEV_PROJECT_ID",
          chain: sepolia,
          mode: "4337", // or "7702"
        });

        if (smartAccount) {
          const receipt = await smartAccount.sendTransaction({
            to: "0xRecipient",
            value: parseEther("0.01"),
          });

          const batchReceipt = await smartAccount.sendBatchTransaction([
            { to: "0xRecipientA", value: parseEther("0.01") },
            { to: "0xRecipientB", data: "0xencodedCallData" },
          ]);
        }
        ```
      </Tab>
    </Tabs>

    <Note>
      You can optionally pass `bundlerUrl` and `paymasterUrl` to use custom infrastructure instead of ZeroDev's defaults. For more on managing your ZeroDev project and RPC endpoints, see the [ZeroDev RPC documentation](https://docs.zerodev.app/).
    </Note>
  </Tab>

  <Tab title="Pimlico">
    [Pimlico](https://docs.pimlico.io/) provides flexible bundler and paymaster infrastructure for account abstraction. Built on the permissionless.js SDK, it supports a wide range of smart account types and any EVM chain. Supports both EIP-4337 and EIP-7702 modes.

    ### Setup

    1. Create a [Pimlico account](https://dashboard.pimlico.io/) and obtain your **API key** from the Pimlico dashboard.

    2. Install the required dependencies:

    <CodeGroup>
      ```bash npm theme={null}
      npm install @getpara/react-native-wallet @getpara/aa-pimlico viem
      ```

      ```bash yarn theme={null}
      yarn add @getpara/react-native-wallet @getpara/aa-pimlico viem
      ```

      ```bash pnpm theme={null}
      pnpm add @getpara/react-native-wallet @getpara/aa-pimlico viem
      ```
    </CodeGroup>

    ### Usage

    <Tabs>
      <Tab title="usePimlicoSmartAccount">
        The simplest way to integrate Pimlico smart accounts into your React Native application. The hook manages initialization, caching, and re-creation automatically via React Query.

        ```tsx PimlicoSmartAccount.tsx theme={null}
        import { usePimlicoSmartAccount } from "@getpara/react-native-wallet";
        import { useMutation } from "@tanstack/react-query";
        import { View, Text, Button } from "react-native";
        import { sepolia } from "viem/chains";
        import { parseEther } from "viem";

        const PIMLICO_API_KEY = process.env.EXPO_PUBLIC_PIMLICO_API_KEY!;

        export function PimlicoSmartAccount() {
          // Initialize the smart account. The hook handles Para signer creation,
          // simple account setup, and Pimlico paymaster configuration internally.
          const { smartAccount, isLoading, error } = usePimlicoSmartAccount({
            apiKey: PIMLICO_API_KEY,
            chain: sepolia,
            mode: "4337", // or "7702"
          });

          const {
            mutate: sendTransaction,
            isPending: isSending,
            error: sendError,
          } = useMutation({
            mutationFn: async () => {
              if (!smartAccount) throw new Error("Smart account not ready");
              return smartAccount.sendTransaction({
                to: "0xRecipient",
                value: parseEther("0.01"),
              });
            },
            onSuccess: (receipt) => {
              console.log("Transaction hash:", receipt.transactionHash);
            },
          });

          const {
            mutate: sendBatch,
            isPending: isBatching,
            error: batchError,
          } = useMutation({
            mutationFn: async () => {
              if (!smartAccount) throw new Error("Smart account not ready");
              return smartAccount.sendBatchTransaction([
                { to: "0xRecipientA", value: parseEther("0.01") },
                { to: "0xRecipientB", data: "0xencodedCallData" },
              ]);
            },
            onSuccess: (receipt) => {
              console.log("Batch tx hash:", receipt.transactionHash);
            },
          });

          if (isLoading) return <Text>Setting up smart account...</Text>;
          if (error) return <Text>Error: {error.message}</Text>;
          if (!smartAccount) return null;

          return (
            <View>
              <Text>Smart Account: {smartAccount.smartAccountAddress}</Text>
              <Text>Mode: {smartAccount.mode}</Text>
              <Button
                title={isSending ? "Sending..." : "Send Transaction"}
                onPress={() => sendTransaction()}
                disabled={isSending}
              />
              {sendError && <Text>Send failed: {sendError.message}</Text>}
              <Button
                title={isBatching ? "Batching..." : "Send Batch"}
                onPress={() => sendBatch()}
                disabled={isBatching}
              />
              {batchError && <Text>Batch failed: {batchError.message}</Text>}
            </View>
          );
        }
        ```
      </Tab>

      <Tab title="createPimlicoSmartAccount">
        For use outside React components or when you need more control over initialization.

        ```typescript pimlico-action.ts theme={null}
        import { createPimlicoSmartAccount } from "@getpara/aa-pimlico";
        import { sepolia } from "viem/chains";
        import { parseEther } from "viem";

        // `para` is your authenticated Para instance
        const smartAccount = await createPimlicoSmartAccount({
          para,
          apiKey: "YOUR_PIMLICO_API_KEY",
          chain: sepolia,
          mode: "4337", // or "7702"
        });

        if (smartAccount) {
          const receipt = await smartAccount.sendTransaction({
            to: "0xRecipient",
            value: parseEther("0.01"),
          });

          const batchReceipt = await smartAccount.sendBatchTransaction([
            { to: "0xRecipientA", value: parseEther("0.01") },
            { to: "0xRecipientB", data: "0xencodedCallData" },
          ]);
        }
        ```
      </Tab>
    </Tabs>

    <Note>
      The Pimlico bundler/paymaster URL is automatically constructed from your API key and chain name. You can override it with a custom `rpcUrl`. Pimlico's permissionless.js also supports other account types (Safe, Kernel, Biconomy, SimpleAccount) — see the [permissionless.js tutorial](https://docs.pimlico.io/).
    </Note>
  </Tab>

  <Tab title="Biconomy">
    [Biconomy](https://docs.biconomy.io/) provides the Nexus smart account with cross-chain transaction orchestration via the MEE (Multi-chain Execution Environment). Supports both EIP-4337 and EIP-7702 modes.

    ### Setup

    1. Create a [Biconomy account](https://dashboard.biconomy.io/) and obtain your **API key** from the Biconomy dashboard.

    2. Install the required dependencies:

    <CodeGroup>
      ```bash npm theme={null}
      npm install @getpara/react-native-wallet @getpara/aa-biconomy viem
      ```

      ```bash yarn theme={null}
      yarn add @getpara/react-native-wallet @getpara/aa-biconomy viem
      ```

      ```bash pnpm theme={null}
      pnpm add @getpara/react-native-wallet @getpara/aa-biconomy viem
      ```
    </CodeGroup>

    ### Usage

    <Tabs>
      <Tab title="useBiconomySmartAccount">
        The simplest way to integrate Biconomy smart accounts into your React Native application. The hook manages initialization, caching, and re-creation automatically via React Query.

        ```tsx BiconomySmartAccount.tsx theme={null}
        import { useBiconomySmartAccount } from "@getpara/react-native-wallet";
        import { useMutation } from "@tanstack/react-query";
        import { View, Text, Button } from "react-native";
        import { sepolia } from "viem/chains";
        import { parseEther } from "viem";

        const BICONOMY_API_KEY = process.env.EXPO_PUBLIC_BICONOMY_API_KEY!;

        export function BiconomySmartAccount() {
          // Initialize the smart account. The hook handles Para signer creation,
          // Nexus account setup, and MEE client configuration internally.
          const { smartAccount, isLoading, error } = useBiconomySmartAccount({
            apiKey: BICONOMY_API_KEY,
            chain: sepolia,
            mode: "4337", // or "7702"
          });

          const {
            mutate: sendTransaction,
            isPending: isSending,
            error: sendError,
          } = useMutation({
            mutationFn: async () => {
              if (!smartAccount) throw new Error("Smart account not ready");
              return smartAccount.sendTransaction({
                to: "0xRecipient",
                value: parseEther("0.01"),
              });
            },
            onSuccess: (receipt) => {
              console.log("Transaction hash:", receipt.transactionHash);
            },
          });

          const {
            mutate: sendBatch,
            isPending: isBatching,
            error: batchError,
          } = useMutation({
            mutationFn: async () => {
              if (!smartAccount) throw new Error("Smart account not ready");
              return smartAccount.sendBatchTransaction([
                { to: "0xRecipientA", value: parseEther("0.01") },
                { to: "0xRecipientB", data: "0xencodedCallData" },
              ]);
            },
            onSuccess: (receipt) => {
              console.log("Batch tx hash:", receipt.transactionHash);
            },
          });

          if (isLoading) return <Text>Setting up smart account...</Text>;
          if (error) return <Text>Error: {error.message}</Text>;
          if (!smartAccount) return null;

          return (
            <View>
              <Text>Smart Account: {smartAccount.smartAccountAddress}</Text>
              <Text>Mode: {smartAccount.mode}</Text>
              <Button
                title={isSending ? "Sending..." : "Send Transaction"}
                onPress={() => sendTransaction()}
                disabled={isSending}
              />
              {sendError && <Text>Send failed: {sendError.message}</Text>}
              <Button
                title={isBatching ? "Batching..." : "Send Batch"}
                onPress={() => sendBatch()}
                disabled={isBatching}
              />
              {batchError && <Text>Batch failed: {batchError.message}</Text>}
            </View>
          );
        }
        ```
      </Tab>

      <Tab title="createBiconomySmartAccount">
        For use outside React components or when you need more control over initialization.

        ```typescript biconomy-action.ts theme={null}
        import { createBiconomySmartAccount } from "@getpara/aa-biconomy";
        import { sepolia } from "viem/chains";
        import { parseEther } from "viem";

        // `para` is your authenticated Para instance
        const smartAccount = await createBiconomySmartAccount({
          para,
          apiKey: "YOUR_BICONOMY_API_KEY",
          chain: sepolia,
          mode: "4337", // or "7702"
        });

        if (smartAccount) {
          const receipt = await smartAccount.sendTransaction({
            to: "0xRecipient",
            value: parseEther("0.01"),
          });

          const batchReceipt = await smartAccount.sendBatchTransaction([
            { to: "0xRecipientA", value: parseEther("0.01") },
            { to: "0xRecipientB", data: "0xencodedCallData" },
          ]);
        }
        ```
      </Tab>
    </Tabs>

    <Note>
      Biconomy transactions are executed via the MEE (Multi-chain Execution Environment). You can optionally pass a custom `meeUrl` to use your own MEE node.
    </Note>
  </Tab>

  <Tab title="Thirdweb">
    [Thirdweb](https://portal.thirdweb.com/) provides smart wallets with gas sponsorship and a broad ecosystem of tools. Supports both EIP-4337 and EIP-7702 modes.

    ### Setup

    1. Create a [Thirdweb account](https://thirdweb.com/dashboard) and obtain your **Client ID** from the Thirdweb dashboard.

    2. Install the required dependencies:

    <CodeGroup>
      ```bash npm theme={null}
      npm install @getpara/react-native-wallet @getpara/aa-thirdweb viem
      ```

      ```bash yarn theme={null}
      yarn add @getpara/react-native-wallet @getpara/aa-thirdweb viem
      ```

      ```bash pnpm theme={null}
      pnpm add @getpara/react-native-wallet @getpara/aa-thirdweb viem
      ```
    </CodeGroup>

    ### Usage

    <Tabs>
      <Tab title="useThirdwebSmartAccount">
        The simplest way to integrate Thirdweb smart accounts into your React Native application. The hook manages initialization, caching, and re-creation automatically via React Query.

        ```tsx ThirdwebSmartAccount.tsx theme={null}
        import { useThirdwebSmartAccount } from "@getpara/react-native-wallet";
        import { useMutation } from "@tanstack/react-query";
        import { View, Text, Button } from "react-native";
        import { sepolia } from "viem/chains";
        import { parseEther } from "viem";

        const THIRDWEB_CLIENT_ID = process.env.EXPO_PUBLIC_THIRDWEB_CLIENT_ID!;

        export function ThirdwebSmartAccount() {
          // Initialize the smart account. The hook handles Para signer creation,
          // smart wallet setup, and gas sponsorship configuration internally.
          const { smartAccount, isLoading, error } = useThirdwebSmartAccount({
            clientId: THIRDWEB_CLIENT_ID,
            chain: sepolia,
            sponsorGas: true, // enable gas sponsorship (default)
            mode: "4337", // or "7702"
          });

          const {
            mutate: sendTransaction,
            isPending: isSending,
            error: sendError,
          } = useMutation({
            mutationFn: async () => {
              if (!smartAccount) throw new Error("Smart account not ready");
              return smartAccount.sendTransaction({
                to: "0xRecipient",
                value: parseEther("0.01"),
              });
            },
            onSuccess: (receipt) => {
              console.log("Transaction hash:", receipt.transactionHash);
            },
          });

          const {
            mutate: sendBatch,
            isPending: isBatching,
            error: batchError,
          } = useMutation({
            mutationFn: async () => {
              if (!smartAccount) throw new Error("Smart account not ready");
              return smartAccount.sendBatchTransaction([
                { to: "0xRecipientA", value: parseEther("0.01") },
                { to: "0xRecipientB", data: "0xencodedCallData" },
              ]);
            },
            onSuccess: (receipt) => {
              console.log("Batch tx hash:", receipt.transactionHash);
            },
          });

          if (isLoading) return <Text>Setting up smart account...</Text>;
          if (error) return <Text>Error: {error.message}</Text>;
          if (!smartAccount) return null;

          return (
            <View>
              <Text>Smart Account: {smartAccount.smartAccountAddress}</Text>
              <Text>Mode: {smartAccount.mode}</Text>
              <Button
                title={isSending ? "Sending..." : "Send Transaction"}
                onPress={() => sendTransaction()}
                disabled={isSending}
              />
              {sendError && <Text>Send failed: {sendError.message}</Text>}
              <Button
                title={isBatching ? "Batching..." : "Send Batch"}
                onPress={() => sendBatch()}
                disabled={isBatching}
              />
              {batchError && <Text>Batch failed: {batchError.message}</Text>}
            </View>
          );
        }
        ```
      </Tab>

      <Tab title="createThirdwebSmartAccount">
        For use outside React components or when you need more control over initialization.

        ```typescript thirdweb-action.ts theme={null}
        import { createThirdwebSmartAccount } from "@getpara/aa-thirdweb";
        import { sepolia } from "viem/chains";
        import { parseEther } from "viem";

        // `para` is your authenticated Para instance
        const smartAccount = await createThirdwebSmartAccount({
          para,
          clientId: "YOUR_THIRDWEB_CLIENT_ID",
          chain: sepolia,
          sponsorGas: true,
          mode: "4337", // or "7702"
        });

        if (smartAccount) {
          const receipt = await smartAccount.sendTransaction({
            to: "0xRecipient",
            value: parseEther("0.01"),
          });

          const batchReceipt = await smartAccount.sendBatchTransaction([
            { to: "0xRecipientA", value: parseEther("0.01") },
            { to: "0xRecipientB", data: "0xencodedCallData" },
          ]);
        }
        ```
      </Tab>
    </Tabs>

    <Note>
      Set `sponsorGas: false` to disable gas sponsorship. In EIP-4337 mode, you can optionally provide `factoryAddress` and `accountAddress` for custom smart wallet deployments.
    </Note>
  </Tab>

  <Tab title="Gelato">
    [Gelato](https://docs.gelato.network/) provides native EIP-7702 smart accounts with built-in gas sponsorship via Gelato's relay infrastructure. No separate paymaster configuration is needed.

    ### Setup

    1. Create a [Gelato account](https://app.gelato.network/) and obtain your **API key** from the Gelato dashboard.

    2. Install the required dependencies:

    <CodeGroup>
      ```bash npm theme={null}
      npm install @getpara/react-native-wallet @getpara/aa-gelato viem
      ```

      ```bash yarn theme={null}
      yarn add @getpara/react-native-wallet @getpara/aa-gelato viem
      ```

      ```bash pnpm theme={null}
      pnpm add @getpara/react-native-wallet @getpara/aa-gelato viem
      ```
    </CodeGroup>

    ### Usage

    <Tabs>
      <Tab title="useGelatoSmartAccount">
        The simplest way to integrate Gelato smart accounts into your React Native application. The hook manages initialization, caching, and re-creation automatically via React Query.

        ```tsx GelatoSmartAccount.tsx theme={null}
        import { useGelatoSmartAccount } from "@getpara/react-native-wallet";
        import { useMutation } from "@tanstack/react-query";
        import { View, Text, Button } from "react-native";
        import { sepolia } from "viem/chains";
        import { parseEther } from "viem";

        const GELATO_API_KEY = process.env.EXPO_PUBLIC_GELATO_API_KEY!;

        export function GelatoSmartAccount() {
          // Initialize the smart account. The hook handles Para signer creation,
          // Gelato account setup, and 7702 delegation internally.
          // Gelato only supports EIP-7702 mode.
          const { smartAccount, isLoading, error } = useGelatoSmartAccount({
            apiKey: GELATO_API_KEY,
            chain: sepolia,
          });

          const {
            mutate: sendTransaction,
            isPending: isSending,
            error: sendError,
          } = useMutation({
            mutationFn: async () => {
              if (!smartAccount) throw new Error("Smart account not ready");
              return smartAccount.sendTransaction({
                to: "0xRecipient",
                value: parseEther("0.01"),
              });
            },
            onSuccess: (receipt) => {
              console.log("Transaction hash:", receipt.transactionHash);
            },
          });

          const {
            mutate: sendBatch,
            isPending: isBatching,
            error: batchError,
          } = useMutation({
            mutationFn: async () => {
              if (!smartAccount) throw new Error("Smart account not ready");
              return smartAccount.sendBatchTransaction([
                { to: "0xRecipientA", value: parseEther("0.01") },
                { to: "0xRecipientB", data: "0xencodedCallData" },
              ]);
            },
            onSuccess: (receipt) => {
              console.log("Batch tx hash:", receipt.transactionHash);
            },
          });

          if (isLoading) return <Text>Setting up smart account...</Text>;
          if (error) return <Text>Error: {error.message}</Text>;
          if (!smartAccount) return null;

          return (
            <View>
              <Text>Smart Account: {smartAccount.smartAccountAddress}</Text>
              <Text>Mode: {smartAccount.mode}</Text>
              <Button
                title={isSending ? "Sending..." : "Send Transaction"}
                onPress={() => sendTransaction()}
                disabled={isSending}
              />
              {sendError && <Text>Send failed: {sendError.message}</Text>}
              <Button
                title={isBatching ? "Batching..." : "Send Batch"}
                onPress={() => sendBatch()}
                disabled={isBatching}
              />
              {batchError && <Text>Batch failed: {batchError.message}</Text>}
            </View>
          );
        }
        ```
      </Tab>

      <Tab title="createGelatoSmartAccount">
        For use outside React components or when you need more control over initialization.

        ```typescript gelato-action.ts theme={null}
        import { createGelatoSmartAccount } from "@getpara/aa-gelato";
        import { sepolia } from "viem/chains";
        import { parseEther } from "viem";

        // `para` is your authenticated Para instance
        const smartAccount = await createGelatoSmartAccount({
          para,
          apiKey: "YOUR_GELATO_API_KEY",
          chain: sepolia,
        });

        if (smartAccount) {
          const receipt = await smartAccount.sendTransaction({
            to: "0xRecipient",
            value: parseEther("0.01"),
          });

          const batchReceipt = await smartAccount.sendBatchTransaction([
            { to: "0xRecipientA", value: parseEther("0.01") },
            { to: "0xRecipientB", data: "0xencodedCallData" },
          ]);
        }
        ```
      </Tab>
    </Tabs>

    <Note>
      Gelato only supports EIP-7702 mode. Gas sponsorship is built into Gelato's relay infrastructure — no separate paymaster configuration is needed.
    </Note>
  </Tab>

  <Tab title="Porto">
    [Porto](https://porto.sh) is a 7702-native relay with merchant-based gas sponsorship, supporting multiple chains including Base, Optimism, Arbitrum, and Ethereum mainnet.

    ### Setup

    Porto requires no external API key. On testnets, gas is sponsored automatically. For mainnet, configure a merchant account in your Porto setup.

    Install the required dependencies:

    <CodeGroup>
      ```bash npm theme={null}
      npm install @getpara/react-native-wallet @getpara/aa-porto viem
      ```

      ```bash yarn theme={null}
      yarn add @getpara/react-native-wallet @getpara/aa-porto viem
      ```

      ```bash pnpm theme={null}
      pnpm add @getpara/react-native-wallet @getpara/aa-porto viem
      ```
    </CodeGroup>

    ### Usage

    <Tabs>
      <Tab title="usePortoSmartAccount">
        The simplest way to integrate Porto smart accounts into your React Native application. The hook manages initialization, caching, and re-creation automatically via React Query.

        ```tsx PortoSmartAccount.tsx theme={null}
        import { usePortoSmartAccount } from "@getpara/react-native-wallet";
        import { useMutation } from "@tanstack/react-query";
        import { View, Text, Button } from "react-native";
        import { parseEther } from "viem";
        import { base } from "viem/chains";

        export function PortoSmartAccount() {
          // Initialize the smart account. The hook handles Para signer creation
          // and Porto relay configuration internally.
          // Testnets: gas is sponsored by default, no merchantUrl needed.
          // Mainnet: merchantUrl is required for gas sponsorship.
          const { smartAccount, isLoading, error } = usePortoSmartAccount({
            chain: base,
            merchantUrl: "/porto/merchant", // required for mainnet
          });

          const {
            mutate: sendTransaction,
            isPending: isSending,
            error: sendError,
          } = useMutation({
            mutationFn: async () => {
              if (!smartAccount) throw new Error("Smart account not ready");
              return smartAccount.sendTransaction({
                to: "0xRecipient",
                value: parseEther("0.01"),
              });
            },
            onSuccess: (receipt) => {
              console.log("Transaction hash:", receipt.transactionHash);
            },
          });

          const {
            mutate: sendBatch,
            isPending: isBatching,
            error: batchError,
          } = useMutation({
            mutationFn: async () => {
              if (!smartAccount) throw new Error("Smart account not ready");
              return smartAccount.sendBatchTransaction([
                { to: "0xRecipientA", value: parseEther("0.01") },
                { to: "0xRecipientB", data: "0xencodedCallData" },
              ]);
            },
            onSuccess: (receipt) => {
              console.log("Batch tx hash:", receipt.transactionHash);
            },
          });

          if (isLoading) return <Text>Setting up smart account...</Text>;
          if (error) return <Text>Error: {error.message}</Text>;
          if (!smartAccount) return null;

          return (
            <View>
              <Text>Smart Account: {smartAccount.smartAccountAddress}</Text>
              <Text>Mode: {smartAccount.mode}</Text>
              <Button
                title={isSending ? "Sending..." : "Send Transaction"}
                onPress={() => sendTransaction()}
                disabled={isSending}
              />
              {sendError && <Text>Send failed: {sendError.message}</Text>}
              <Button
                title={isBatching ? "Batching..." : "Send Batch"}
                onPress={() => sendBatch()}
                disabled={isBatching}
              />
              {batchError && <Text>Batch failed: {batchError.message}</Text>}
            </View>
          );
        }
        ```
      </Tab>

      <Tab title="createPortoSmartAccount">
        For use outside React components or when you need more control over initialization.

        ```typescript porto-action.ts theme={null}
        import { createPortoSmartAccount } from "@getpara/aa-porto";
        import { parseEther } from "viem";
        import { base } from "viem/chains";

        // `para` is your authenticated Para instance
        const smartAccount = await createPortoSmartAccount({
          para,
          chain: base,
          merchantUrl: "/porto/merchant", // required for mainnet
        });

        if (smartAccount) {
          const receipt = await smartAccount.sendTransaction({
            to: "0xRecipient",
            value: parseEther("0.01"),
          });

          const batchReceipt = await smartAccount.sendBatchTransaction([
            { to: "0xRecipientA", value: parseEther("0.01") },
            { to: "0xRecipientB", data: "0xencodedCallData" },
          ]);
        }
        ```
      </Tab>
    </Tabs>

    <Note>
      Porto only supports EIP-7702 mode. The Porto relay supports multiple chains including Base, Optimism, Arbitrum, Ethereum, and several testnets. On testnets, gas fees are sponsored by default. For mainnet, a merchant account is required — pass `merchantUrl` to enable gas sponsorship.
    </Note>
  </Tab>

  <Tab title="Safe">
    [Safe](https://docs.safe.global/) provides battle-tested multi-signature smart accounts with modular extension support, deployed on hundreds of EVM chains. Uses Pimlico for bundler and paymaster infrastructure. Supports EIP-4337 mode only.

    ### Setup

    1. Obtain a [Pimlico API key](https://dashboard.pimlico.io/) for bundler and paymaster infrastructure.

    2. Install the required dependencies:

    <CodeGroup>
      ```bash npm theme={null}
      npm install @getpara/react-native-wallet @getpara/aa-safe viem
      ```

      ```bash yarn theme={null}
      yarn add @getpara/react-native-wallet @getpara/aa-safe viem
      ```

      ```bash pnpm theme={null}
      pnpm add @getpara/react-native-wallet @getpara/aa-safe viem
      ```
    </CodeGroup>

    ### Usage

    <Tabs>
      <Tab title="useSafeSmartAccount">
        The simplest way to integrate Safe smart accounts into your React Native application. The hook manages initialization, caching, and re-creation automatically via React Query.

        ```tsx SafeSmartAccount.tsx theme={null}
        import { useSafeSmartAccount } from "@getpara/react-native-wallet";
        import { useMutation } from "@tanstack/react-query";
        import { View, Text, Button } from "react-native";
        import { sepolia } from "viem/chains";
        import { parseEther } from "viem";

        const PIMLICO_API_KEY = process.env.EXPO_PUBLIC_PIMLICO_API_KEY!;

        export function SafeSmartAccount() {
          // Initialize the smart account. The hook handles Para signer creation,
          // Safe account setup, and Pimlico paymaster configuration internally.
          // Safe only supports EIP-4337 mode.
          const { smartAccount, isLoading, error } = useSafeSmartAccount({
            pimlicoApiKey: PIMLICO_API_KEY,
            chain: sepolia,
          });

          const {
            mutate: sendTransaction,
            isPending: isSending,
            error: sendError,
          } = useMutation({
            mutationFn: async () => {
              if (!smartAccount) throw new Error("Smart account not ready");
              return smartAccount.sendTransaction({
                to: "0xRecipient",
                value: parseEther("0.01"),
              });
            },
            onSuccess: (receipt) => {
              console.log("Transaction hash:", receipt.transactionHash);
            },
          });

          const {
            mutate: sendBatch,
            isPending: isBatching,
            error: batchError,
          } = useMutation({
            mutationFn: async () => {
              if (!smartAccount) throw new Error("Smart account not ready");
              return smartAccount.sendBatchTransaction([
                { to: "0xRecipientA", value: parseEther("0.01") },
                { to: "0xRecipientB", data: "0xencodedCallData" },
              ]);
            },
            onSuccess: (receipt) => {
              console.log("Batch tx hash:", receipt.transactionHash);
            },
          });

          if (isLoading) return <Text>Setting up smart account...</Text>;
          if (error) return <Text>Error: {error.message}</Text>;
          if (!smartAccount) return null;

          return (
            <View>
              <Text>Smart Account: {smartAccount.smartAccountAddress}</Text>
              <Text>Mode: {smartAccount.mode}</Text>
              <Button
                title={isSending ? "Sending..." : "Send Transaction"}
                onPress={() => sendTransaction()}
                disabled={isSending}
              />
              {sendError && <Text>Send failed: {sendError.message}</Text>}
              <Button
                title={isBatching ? "Batching..." : "Send Batch"}
                onPress={() => sendBatch()}
                disabled={isBatching}
              />
              {batchError && <Text>Batch failed: {batchError.message}</Text>}
            </View>
          );
        }
        ```
      </Tab>

      <Tab title="createSafeSmartAccount">
        For use outside React components or when you need more control over initialization.

        ```typescript safe-action.ts theme={null}
        import { createSafeSmartAccount } from "@getpara/aa-safe";
        import { sepolia } from "viem/chains";
        import { parseEther } from "viem";

        // `para` is your authenticated Para instance
        const smartAccount = await createSafeSmartAccount({
          para,
          pimlicoApiKey: "YOUR_PIMLICO_API_KEY",
          chain: sepolia,
        });

        if (smartAccount) {
          const receipt = await smartAccount.sendTransaction({
            to: "0xRecipient",
            value: parseEther("0.01"),
          });

          const batchReceipt = await smartAccount.sendBatchTransaction([
            { to: "0xRecipientA", value: parseEther("0.01") },
            { to: "0xRecipientB", data: "0xencodedCallData" },
          ]);
        }
        ```
      </Tab>
    </Tabs>

    <Note>
      Safe only supports EIP-4337 mode. You can optionally pass `safeVersion` (default: `"1.4.1"`) and `saltNonce` for deterministic address generation.
    </Note>
  </Tab>

  <Tab title="Rhinestone">
    [Rhinestone](https://docs.rhinestone.wtf/) enables cross-chain smart account orchestration with automatic bridging. Built on the modular account stack, it supports cross-chain token transfers and transactions from a single account. Supports EIP-4337 mode only.

    ### Setup

    1. Obtain a [Rhinestone API key](https://dashboard.rhinestone.wtf/) and a [Pimlico API key](https://dashboard.pimlico.io/).

    2. Install the required dependencies:

    <CodeGroup>
      ```bash npm theme={null}
      npm install @getpara/react-native-wallet @getpara/aa-rhinestone viem
      ```

      ```bash yarn theme={null}
      yarn add @getpara/react-native-wallet @getpara/aa-rhinestone viem
      ```

      ```bash pnpm theme={null}
      pnpm add @getpara/react-native-wallet @getpara/aa-rhinestone viem
      ```
    </CodeGroup>

    ### Usage

    <Tabs>
      <Tab title="useRhinestoneSmartAccount">
        The simplest way to integrate Rhinestone smart accounts into your React Native application. The hook manages initialization, caching, and re-creation automatically via React Query.

        ```tsx RhinestoneSmartAccount.tsx theme={null}
        import { useRhinestoneSmartAccount } from "@getpara/react-native-wallet";
        import { useMutation } from "@tanstack/react-query";
        import { View, Text, Button } from "react-native";
        import { sepolia } from "viem/chains";
        import { parseEther } from "viem";

        const RHINESTONE_API_KEY = process.env.EXPO_PUBLIC_RHINESTONE_API_KEY!;
        const PIMLICO_API_KEY = process.env.EXPO_PUBLIC_PIMLICO_API_KEY!;

        export function RhinestoneSmartAccount() {
          // Initialize the smart account. The hook handles Para signer creation,
          // Rhinestone account setup, and orchestrator configuration internally.
          // Rhinestone only supports EIP-4337 mode.
          const { smartAccount, isLoading, error } = useRhinestoneSmartAccount({
            chain: sepolia,
            rhinestoneApiKey: RHINESTONE_API_KEY,
            pimlicoApiKey: PIMLICO_API_KEY,
          });

          const {
            mutate: sendTransaction,
            isPending: isSending,
            error: sendError,
          } = useMutation({
            mutationFn: async () => {
              if (!smartAccount) throw new Error("Smart account not ready");
              return smartAccount.sendTransaction({
                to: "0xRecipient",
                value: parseEther("0.01"),
              });
            },
            onSuccess: (receipt) => {
              console.log("Transaction hash:", receipt.transactionHash);
            },
          });

          const {
            mutate: sendBatch,
            isPending: isBatching,
            error: batchError,
          } = useMutation({
            mutationFn: async () => {
              if (!smartAccount) throw new Error("Smart account not ready");
              return smartAccount.sendBatchTransaction([
                { to: "0xRecipientA", value: parseEther("0.01") },
                { to: "0xRecipientB", data: "0xencodedCallData" },
              ]);
            },
            onSuccess: (receipt) => {
              console.log("Batch tx hash:", receipt.transactionHash);
            },
          });

          if (isLoading) return <Text>Setting up smart account...</Text>;
          if (error) return <Text>Error: {error.message}</Text>;
          if (!smartAccount) return null;

          return (
            <View>
              <Text>Smart Account: {smartAccount.smartAccountAddress}</Text>
              <Text>Mode: {smartAccount.mode}</Text>
              <Button
                title={isSending ? "Sending..." : "Send Transaction"}
                onPress={() => sendTransaction()}
                disabled={isSending}
              />
              {sendError && <Text>Send failed: {sendError.message}</Text>}
              <Button
                title={isBatching ? "Batching..." : "Send Batch"}
                onPress={() => sendBatch()}
                disabled={isBatching}
              />
              {batchError && <Text>Batch failed: {batchError.message}</Text>}
            </View>
          );
        }
        ```
      </Tab>

      <Tab title="createRhinestoneSmartAccount">
        For use outside React components or when you need more control over initialization.

        ```typescript rhinestone-action.ts theme={null}
        import { createRhinestoneSmartAccount } from "@getpara/aa-rhinestone";
        import { sepolia } from "viem/chains";
        import { parseEther } from "viem";

        // `para` is your authenticated Para instance
        const smartAccount = await createRhinestoneSmartAccount({
          para,
          chain: sepolia,
          rhinestoneApiKey: "YOUR_RHINESTONE_API_KEY",
          pimlicoApiKey: "YOUR_PIMLICO_API_KEY",
        });

        if (smartAccount) {
          const receipt = await smartAccount.sendTransaction({
            to: "0xRecipient",
            value: parseEther("0.01"),
          });

          const batchReceipt = await smartAccount.sendBatchTransaction([
            { to: "0xRecipientA", value: parseEther("0.01") },
            { to: "0xRecipientB", data: "0xencodedCallData" },
          ]);
        }
        ```
      </Tab>
    </Tabs>

    <Note>
      Rhinestone only supports EIP-4337 mode. Both `rhinestoneApiKey` and `pimlicoApiKey` are optional but recommended for production use. For advanced cross-chain use cases with automatic bridging, see the [Rhinestone documentation](https://docs.rhinestone.wtf/).
    </Note>
  </Tab>

  <Tab title="Coinbase Developer Platform">
    [Coinbase Developer Platform (CDP)](https://docs.cdp.coinbase.com/) provides Coinbase smart accounts on Base and Base Sepolia. Uses viem's built-in `toCoinbaseSmartAccount` with CDP's bundler and paymaster. Supports EIP-4337 mode only.

    ### Setup

    1. Create a [Coinbase Developer Platform account](https://portal.cdp.coinbase.com/) and obtain your **RPC token**.

    2. Install the required dependencies:

    <CodeGroup>
      ```bash npm theme={null}
      npm install @getpara/react-native-wallet @getpara/aa-cdp viem
      ```

      ```bash yarn theme={null}
      yarn add @getpara/react-native-wallet @getpara/aa-cdp viem
      ```

      ```bash pnpm theme={null}
      pnpm add @getpara/react-native-wallet @getpara/aa-cdp viem
      ```
    </CodeGroup>

    ### Usage

    <Tabs>
      <Tab title="useCDPSmartAccount">
        The simplest way to integrate CDP smart accounts into your React Native application. The hook manages initialization, caching, and re-creation automatically via React Query.

        ```tsx CDPSmartAccount.tsx theme={null}
        import { useCDPSmartAccount } from "@getpara/react-native-wallet";
        import { useMutation } from "@tanstack/react-query";
        import { View, Text, Button } from "react-native";
        import { baseSepolia } from "viem/chains";
        import { parseEther } from "viem";

        const CDP_RPC_TOKEN = process.env.EXPO_PUBLIC_CDP_RPC_TOKEN!;

        export function CDPSmartAccount() {
          // Initialize the smart account. The hook handles Para signer creation,
          // Coinbase account setup, and CDP paymaster configuration internally.
          // CDP only supports EIP-4337 mode on Base and Base Sepolia.
          const { smartAccount, isLoading, error } = useCDPSmartAccount({
            rpcToken: CDP_RPC_TOKEN,
            chain: baseSepolia,
          });

          const {
            mutate: sendTransaction,
            isPending: isSending,
            error: sendError,
          } = useMutation({
            mutationFn: async () => {
              if (!smartAccount) throw new Error("Smart account not ready");
              return smartAccount.sendTransaction({
                to: "0xRecipient",
                value: parseEther("0.01"),
              });
            },
            onSuccess: (receipt) => {
              console.log("Transaction hash:", receipt.transactionHash);
            },
          });

          const {
            mutate: sendBatch,
            isPending: isBatching,
            error: batchError,
          } = useMutation({
            mutationFn: async () => {
              if (!smartAccount) throw new Error("Smart account not ready");
              return smartAccount.sendBatchTransaction([
                { to: "0xRecipientA", value: parseEther("0.01") },
                { to: "0xRecipientB", data: "0xencodedCallData" },
              ]);
            },
            onSuccess: (receipt) => {
              console.log("Batch tx hash:", receipt.transactionHash);
            },
          });

          if (isLoading) return <Text>Setting up smart account...</Text>;
          if (error) return <Text>Error: {error.message}</Text>;
          if (!smartAccount) return null;

          return (
            <View>
              <Text>Smart Account: {smartAccount.smartAccountAddress}</Text>
              <Text>Mode: {smartAccount.mode}</Text>
              <Button
                title={isSending ? "Sending..." : "Send Transaction"}
                onPress={() => sendTransaction()}
                disabled={isSending}
              />
              {sendError && <Text>Send failed: {sendError.message}</Text>}
              <Button
                title={isBatching ? "Batching..." : "Send Batch"}
                onPress={() => sendBatch()}
                disabled={isBatching}
              />
              {batchError && <Text>Batch failed: {batchError.message}</Text>}
            </View>
          );
        }
        ```
      </Tab>

      <Tab title="createCDPSmartAccount">
        For use outside React components or when you need more control over initialization.

        ```typescript cdp-action.ts theme={null}
        import { createCDPSmartAccount } from "@getpara/aa-cdp";
        import { baseSepolia } from "viem/chains";
        import { parseEther } from "viem";

        // `para` is your authenticated Para instance
        const smartAccount = await createCDPSmartAccount({
          para,
          rpcToken: "YOUR_CDP_RPC_TOKEN",
          chain: baseSepolia,
        });

        if (smartAccount) {
          const receipt = await smartAccount.sendTransaction({
            to: "0xRecipient",
            value: parseEther("0.01"),
          });

          const batchReceipt = await smartAccount.sendBatchTransaction([
            { to: "0xRecipientA", value: parseEther("0.01") },
            { to: "0xRecipientB", data: "0xencodedCallData" },
          ]);
        }
        ```
      </Tab>
    </Tabs>

    <Note>
      CDP only supports EIP-4337 mode and is limited to Base and Base Sepolia chains. No additional bundler packages are needed — CDP uses viem's built-in `toCoinbaseSmartAccount`.
    </Note>
  </Tab>
</Tabs>

## Next Steps

<CardGroup cols={3}>
  <Card title="Execute Transactions" description="Execute transactions with Para signers" href="/v3/react-native/guides/web3-operations/evm/execute-transactions" icon="bolt" />

  <Card title="Sign Messages" description="Sign messages for authentication" href="/v3/react-native/guides/web3-operations/evm/sign-messages" icon="signature" />

  <Card title="Configure RPC" description="Set up custom RPC endpoints" href="/v3/react-native/guides/web3-operations/evm/configure-rpc" icon="globe" />
</CardGroup>
