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

# Llms header

# Para

> Non-custodial embedded wallet infrastructure using MPC for building embedded wallet integrations across web, mobile, and server platforms supporting EVM, Solana, and Cosmos chains.

## Para SDK Implementation Supplement

> Concrete build-time details: packages, initialization, authentication, signing, connectors, account abstraction, and configuration for building Para integrations.

## 1. SDK Package Matrix

All `@getpara/*` packages must use the **same version** as each other. Always pin every `@getpara/*` dependency to the same release to avoid mismatches.

### Core SDKs

| Package                        | Use When                                                                                        |
| ------------------------------ | ----------------------------------------------------------------------------------------------- |
| `@getpara/react-sdk`           | React/Next.js apps with ParaProvider + hooks + ParaModal                                        |
| `@getpara/react-sdk-lite`      | React apps using Para only through a connector (Wagmi/Graz) - lighter bundle, exports `ParaWeb` |
| `@getpara/web-sdk`             | Non-React web frameworks (Vue, Svelte) - exports `ParaWeb` imperative class                     |
| `@getpara/server-sdk`          | Node.js/Bun/Deno server-side - exports `Para` (aliased as `ParaServer`)                         |
| `@getpara/react-native-wallet` | React Native / Expo mobile apps                                                                 |

### Signing Integration Packages

| Package                                  | Web3 Library       | Companion Deps                                              |
| ---------------------------------------- | ------------------ | ----------------------------------------------------------- |
| `@getpara/viem-v2-integration`           | Viem 2.x           | `viem@^2.27.0`                                              |
| `@getpara/ethers-v6-integration`         | Ethers 6.x         | `ethers@^6.13.0`                                            |
| `@getpara/ethers-v5-integration`         | Ethers 5.x         | `ethers@^5.8.0`                                             |
| `@getpara/solana-web3.js-v1-integration` | Solana Web3.js 1.x | `@solana/web3.js@^1.98.0`                                   |
| `@getpara/solana-signers-v2-integration` | Solana Signers 2.x | `@solana/web3.js@^1.98.0`                                   |
| `@getpara/cosmjs-v0-integration`         | CosmJS 0.34+       | `@cosmjs/stargate@^0.34.0`, `@cosmjs/proto-signing@^0.34.0` |

### Connector Packages

| Package                         | Connector Ecosystem | Companion Deps                                                  |
| ------------------------------- | ------------------- | --------------------------------------------------------------- |
| `@getpara/wagmi-v2-integration` | Wagmi 2.x / 3.x     | `wagmi@^2.15.0`, `viem@^2.27.0`, `@tanstack/react-query@^5.0.0` |
| `@getpara/rainbowkit-wallet`    | RainbowKit          | `@rainbow-me/rainbowkit@^2.0.0`, `wagmi`, `viem`                |
| `@getpara/graz-integration`     | Graz (Cosmos)       | `graz@^0.4.1`                                                   |

### Wallet Connector Packages (for bulk pregen)

| Package                             | Purpose                            |
| ----------------------------------- | ---------------------------------- |
| `@getpara/evm-wallet-connectors`    | EVM external wallet connections    |
| `@getpara/solana-wallet-connectors` | Solana external wallet connections |
| `@getpara/cosmos-wallet-connectors` | Cosmos external wallet connections |

### Account Abstraction Companion Deps

| AA Provider        | Key Packages                                                           |
| ------------------ | ---------------------------------------------------------------------- |
| Alchemy (ERC-4337) | `@aa-sdk/core`, `@account-kit/infra`, `@account-kit/smart-contracts`   |
| Alchemy (EIP-7702) | Same as above, uses `createModularAccountV2Client` with `mode: "7702"` |
| ZeroDev (ERC-4337) | `@zerodev/sdk`, `@zerodev/ecdsa-validator`                             |
| ZeroDev (EIP-7702) | Same packages, uses `create7702KernelAccount` + `KERNEL_V3_3`          |
| Gelato             | `@gelatonetwork/smartwallet`                                           |
| Thirdweb           | `thirdweb`                                                             |
| Rhinestone         | `@rhinestone/sdk`                                                      |
| Porto              | `porto`                                                                |

### Required Companion Dependency

All React examples require:

```
@tanstack/react-query@^5.0.0
```

***

## 2. Initialization Patterns

### React / Next.js (ParaProvider)

```tsx theme={null}
// src/components/ParaProvider.tsx
"use client";

import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { Environment, ParaProvider as ParaSDKProvider } from "@getpara/react-sdk";

const API_KEY = process.env.NEXT_PUBLIC_PARA_API_KEY ?? "";
const ENVIRONMENT = (process.env.NEXT_PUBLIC_PARA_ENVIRONMENT as Environment) || Environment.BETA;

if (!API_KEY) {
  throw new Error("API key is not defined. Please set NEXT_PUBLIC_PARA_API_KEY in your environment variables.");
}

const queryClient = new QueryClient();

export function ParaProvider({ children }: { children: React.ReactNode }) {
  return (
    <QueryClientProvider client={queryClient}>
      <ParaSDKProvider
        paraClientConfig={{
          apiKey: API_KEY,
          env: ENVIRONMENT,
        }}
        config={{ appName: "My App" }}
        paraModalConfig={{
          disableEmailLogin: false,
          disablePhoneLogin: false,
          authLayout: ["AUTH:FULL", "EXTERNAL:FULL"],
          oAuthMethods: ["APPLE", "DISCORD", "FACEBOOK", "FARCASTER", "GOOGLE", "TWITTER"],
          onRampTestMode: true,
          theme: {
            foregroundColor: "#222222",
            backgroundColor: "#FFFFFF",
            accentColor: "#888888",
            darkForegroundColor: "#EEEEEE",
            darkBackgroundColor: "#111111",
            darkAccentColor: "#AAAAAA",
            mode: "light",
            borderRadius: "none",
            font: "Inter",
          },
          logo: "/logo.svg",
          recoverySecretStepEnabled: true,
          twoFactorAuthEnabled: false,
        }}>
        {children}
      </ParaSDKProvider>
    </QueryClientProvider>
  );
}
```

The `config` prop accepts:

```ts theme={null}
interface ParaProviderConfig {
  appName: string;                        // required
  disableAutoSessionKeepAlive?: boolean;  // disable automatic session refresh
  disableEmbeddedModal?: boolean;         // set true only when rendering your own ParaModal
  rpcUrl?: string;
  farcasterMiniAppConfig?: FarcasterMiniAppConfig;
}
```

Wrap your app root (e.g., `layout.tsx`):

```tsx theme={null}
import { ParaProvider } from "@/components/ParaProvider";
export default function RootLayout({ children }) {
  return <html><body><ParaProvider>{children}</ParaProvider></body></html>;
}
```

`ParaProvider` also accepts an optional `callbacks` prop for event handling:

```ts theme={null}
type Callbacks = {
  onLogout?: (event) => void;
  onLogin?: (event) => void;
  onAccountSetup?: (event) => void;
  onAccountCreation?: (event) => void;
  onSignMessage?: (event) => void;
  onSignTransaction?: (event) => void;
  onWalletsChange?: (event) => void;
  onWalletCreated?: (event) => void;
  onPregenWalletClaimed?: (event) => void;
};
```

### Vue / Svelte (ParaWeb - imperative)

```ts theme={null}
// src/lib/para.ts
import { Environment, ParaWeb } from "@getpara/web-sdk";

const API_KEY = import.meta.env.VITE_PARA_API_KEY;
const ENVIRONMENT = (import.meta.env.VITE_PARA_ENVIRONMENT as Environment) || Environment.BETA;

if (!API_KEY) {
  throw new Error("API key is not defined. Please set VITE_PARA_API_KEY in your environment variables.");
}

export const para = new ParaWeb(ENVIRONMENT, API_KEY);
```

### Server (ParaServer)

```ts theme={null}
import { Para as ParaServer, Environment } from "@getpara/server-sdk";

const PARA_API_KEY = process.env.PARA_API_KEY;
const PARA_ENVIRONMENT = (process.env.PARA_ENVIRONMENT as Environment) || Environment.BETA;

const para = new ParaServer(PARA_ENVIRONMENT, PARA_API_KEY);
```

### React Native / Expo (ParaMobile)

```ts theme={null}
import ParaMobile, { Environment } from "@getpara/react-native-wallet";

const para = new ParaMobile(
  Environment.BETA,
  process.env.EXPO_PUBLIC_PARA_API_KEY,
  undefined,
  { disableWorkers: true }
);
```

The `{ disableWorkers: true }` option is **required** for React Native because Web Workers are not available.

### Chrome Extension (storage overrides)

```ts theme={null}
import { ParaWeb } from "@getpara/react-sdk";
import { chromeStorageOverrides } from "../chrome-storage";

export const para = new ParaWeb(ENVIRONMENT, API_KEY, {
  ...chromeStorageOverrides,
  useStorageOverrides: true,
});

// Shared init promise - await in any script that needs Para
export const paraReady = para.init();
```

The `chromeStorageOverrides` object maps `chrome.storage.local` / `chrome.storage.session` to replace `localStorage` / `sessionStorage` which are not available in extension service workers. See `examples-hub/web/with-chrome-extension/src/lib/chrome-storage.ts` for the full implementation.

***

## 3. Environment Variables

### Naming Conventions by Framework

| Framework         | Prefix         | Example                    |
| ----------------- | -------------- | -------------------------- |
| Next.js (client)  | `NEXT_PUBLIC_` | `NEXT_PUBLIC_PARA_API_KEY` |
| Next.js (server)  | none           | `PARA_API_KEY`             |
| Vite (Vue/Svelte) | `VITE_`        | `VITE_PARA_API_KEY`        |
| Expo              | `EXPO_PUBLIC_` | `EXPO_PUBLIC_PARA_API_KEY` |
| Node.js server    | none           | `PARA_API_KEY`             |

### Common Variables

```env theme={null}
# Required - Para
PARA_API_KEY=your_api_key
PARA_ENVIRONMENT=BETA          # or PRODUCTION

# Client-side variants (pick one based on framework)
NEXT_PUBLIC_PARA_API_KEY=your_api_key
NEXT_PUBLIC_PARA_ENVIRONMENT=BETA
VITE_PARA_API_KEY=your_api_key
VITE_PARA_ENVIRONMENT=BETA
EXPO_PUBLIC_PARA_API_KEY=your_api_key

# Server-side pregen encryption
ENCRYPTION_KEY=a_32_byte_string_exactly_this_l   # Must be exactly 32 bytes

# Account Abstraction
ALCHEMY_API_KEY=your_alchemy_key
ALCHEMY_GAS_POLICY_ID=your_policy_id
ALCHEMY_RPC_URL=https://arb-sepolia.g.alchemy.com/v2/your_key
ZERODEV_PROJECT_ID=your_zerodev_project_id
ZERODEV_BUNDLER_RPC=https://rpc.zerodev.app/api/v2/bundler/...
ZERODEV_PAYMASTER_RPC=https://rpc.zerodev.app/api/v2/paymaster/...
ZERODEV_ARBITRUM_SEPOLIA_RPC=https://rpc.zerodev.app/api/v2/rpc/...

# REST API
PARA_REST_BASE_URL=https://api.beta.getpara.com   # or https://api.getpara.com
```

***

## 4. Authentication Flows

### Email Auth (React hooks pattern)

```tsx theme={null}
import {
  useSignUpOrLogIn,
  useWaitForLogin,
  useWaitForWalletCreation,
  type AuthStateVerify,
} from "@getpara/react-sdk";

// In your hook/component:
const { signUpOrLogIn, isPending: isSigningUp } = useSignUpOrLogIn();
const { waitForLogin, isPending: isWaitingForLogin } = useWaitForLogin();
const { waitForWalletCreation, isPending: isWaitingForWallet } = useWaitForWalletCreation();

const shouldCancel = useRef(false);

// Step 1: Submit email
signUpOrLogIn(
  { auth: { email } },
  {
    onSuccess: (authState) => {
      if (authState?.stage === "verify") {
        const verifyState = authState as AuthStateVerify;
        // verifyState.loginUrl -> open in iframe or popup for passkey verification
        // verifyState.nextStage -> "signup" (new user) or "login" (returning user)
        const isNewUser = verifyState.nextStage === "signup";
        handleAuthComplete(isNewUser);
      }
    },
    onError: (err) => { /* handle error */ },
  }
);

// Step 2: Wait for auth completion
function handleAuthComplete(isNewUser: boolean) {
  if (isNewUser) {
    waitForWalletCreation(
      { isCanceled: () => shouldCancel.current },
      { onSuccess: () => { /* user is logged in with wallet */ } }
    );
  } else {
    waitForLogin(
      { isCanceled: () => shouldCancel.current },
      { onSuccess: () => { /* user is logged in */ } }
    );
  }
}
```

The `loginUrl` from Step 1 must be displayed to the user in an iframe or popup - it's the passkey verification page hosted by Para.

### Email Auth (Imperative / Svelte / Vue)

```ts theme={null}
import { para } from "@/lib/para";

// Step 1: Submit email
const authState = await para.signUpOrLogIn({ auth: { email } });

if (authState.stage === "verify" && authState.loginUrl) {
  const isNewUser = authState.nextStage === "signup";
  // Show authState.loginUrl to user in iframe/popup

  // Step 2: Wait for completion
  if (isNewUser) {
    await para.waitForWalletCreation({ isCanceled: () => shouldCancel });
  } else {
    const result = await para.waitForLogin({ isCanceled: () => shouldCancel });
    if (result.needsWallet) {
      await para.waitForWalletCreation({ isCanceled: () => shouldCancel });
    }
  }
}
```

### OAuth Auth (React hooks)

```tsx theme={null}
import {
  useVerifyOAuth,
  useVerifyFarcaster,
  useWaitForLogin,
  useWaitForWalletCreation,
  type TOAuthMethod,
} from "@getpara/react-sdk";

const { verifyOAuth } = useVerifyOAuth();
const { verifyFarcaster } = useVerifyFarcaster();

// Standard OAuth (Google, Apple, Discord, Facebook, Twitter)
verifyOAuth(
  {
    method: "GOOGLE", // TOAuthMethod excluding "TELEGRAM" | "FARCASTER"
    onOAuthUrl: (url) => {
      window.open(url, "oauth", "popup=true");
    },
    isCanceled: () => shouldCancel.current || !!popupWindow.current?.closed,
  },
  {
    onSuccess: (authState) => {
      if (authState.stage === "done") {
        handleAuthComplete(authState.isNewUser);
      }
    },
  }
);

// Farcaster
verifyFarcaster(
  {
    onConnectUri: (uri) => {
      window.open(uri, "farcaster", "popup=true");
    },
    isCanceled: () => shouldCancel.current || !!popupWindow.current?.closed,
  },
  {
    onSuccess: (authState) => {
      if (authState.stage === "done") {
        handleAuthComplete(authState.isNewUser);
      }
    },
  }
);
```

### Verify iframe listener

When showing the `loginUrl` in an iframe, listen for the close message:

```ts theme={null}
useEffect(() => {
  const portalBase = "https://app.beta.getpara.com"; // or https://app.getpara.com
  const handleMessage = (event: MessageEvent) => {
    if (!event.origin.startsWith(portalBase)) return;
    if (event.data?.type === "CLOSE_WINDOW" && event.data.success) {
      setVerifyUrl(null);
    }
  };
  window.addEventListener("message", handleMessage);
  return () => window.removeEventListener("message", handleMessage);
}, []);
```

***

## 5. Signing Integration Code

### Viem v2

```ts theme={null}
import { createParaAccount, createParaViemClient } from "@getpara/viem-v2-integration";
import { http, parseEther, parseGwei } from "viem";
import { sepolia } from "viem/chains";

// From client (using useClient hook):
import { useClient } from "@getpara/react-sdk";
const client = useClient(); // returns the Para client instance

// Create account + client
const viemParaAccount = createParaAccount(para); // para = ParaServer or client
const viemClient = createParaViemClient(para, {
  account: viemParaAccount,
  chain: sepolia,
  transport: http("https://ethereum-sepolia-rpc.publicnode.com"),
});

// Sign transaction
const request = await viemClient.prepareTransactionRequest({
  account: viemParaAccount,
  to: "0x...",
  value: parseEther("0.0001"),
  gas: BigInt(21000),
  maxFeePerGas: parseGwei("20"),
  maxPriorityFeePerGas: parseGwei("3"),
  chain: sepolia,
});
const signedTx = await viemClient.signTransaction(request);
```

### Ethers v6

```ts theme={null}
import { ParaEthersSigner } from "@getpara/ethers-v6-integration";
import { ethers } from "ethers";

const provider = new ethers.JsonRpcProvider("https://ethereum-sepolia-rpc.publicnode.com");
const signer = new ParaEthersSigner(para, provider as ethers.Provider);

const address = await signer.getAddress();
const tx = {
  to: address,
  value: ethers.parseEther("0.0001"),
  nonce: await provider.getTransactionCount(address),
  gasLimit: 21000,
  gasPrice: (await provider.getFeeData()).gasPrice,
};
await signer.signTransaction(tx);
```

### Ethers v5

```ts theme={null}
import { ParaEthersV5Signer } from "@getpara/ethers-v5-integration";
import { ethers } from "ethers";

const provider = new ethers.providers.JsonRpcProvider(RPC_URL);
const signer = new ParaEthersV5Signer(client, provider); // client from useClient()

await signer.signMessage("Hello, Para!");
await signer.sendTransaction(tx);
```

### Solana Web3.js v1

```ts theme={null}
import { ParaSolanaWeb3Signer } from "@getpara/solana-web3.js-v1-integration";
import { Connection, Transaction, SystemProgram, LAMPORTS_PER_SOL } from "@solana/web3.js";

const connection = new Connection("https://api.testnet.solana.com");
const signer = new ParaSolanaWeb3Signer(para, connection);

const { blockhash } = await connection.getLatestBlockhash();
const tx = new Transaction();
tx.recentBlockhash = blockhash;
tx.feePayer = signer.sender; // PublicKey from Para wallet

tx.add(
  SystemProgram.transfer({
    fromPubkey: signer.sender,
    toPubkey: signer.sender,
    lamports: LAMPORTS_PER_SOL / 1000,
  })
);

await signer.signTransaction(tx);
```

### CosmJS

```ts theme={null}
import { ParaProtoSigner } from "@getpara/cosmjs-v0-integration";
import { SigningStargateClient } from "@cosmjs/stargate";

const signer = new ParaProtoSigner(para, "cosmos"); // second arg is bech32 prefix

const stargateClient = await SigningStargateClient.connectWithSigner(
  "https://rpc-rs.cosmos.nodestake.top/",
  signer
);

const fee = { amount: [{ denom: "uatom", amount: "500" }], gas: "200000" };
await stargateClient.sign(
  signer.address,
  [{ typeUrl: "/cosmos.bank.v1beta1.MsgSend", value: { fromAddress: signer.address, toAddress: "cosmos1...", amount: [{ denom: "uatom", amount: "1000" }] } }],
  fee,
  "Signed with Para"
);
```

***

## 6. Wallet Pre-generation (Server-Side)

### Create pre-generated wallet

```ts theme={null}
import { Para as ParaServer, Environment } from "@getpara/server-sdk";
import { encrypt } from "./encryption-utils";
import { setKeyShareInDB } from "./keySharesDB";

const para = new ParaServer(PARA_ENVIRONMENT, PARA_API_KEY);

// Check if wallet already exists
const walletExists = await para.hasPregenWallet({ pregenId: { email } });

// Create wallets for all chain types
const wallets = await para.createPregenWalletPerType({
  types: ["EVM", "SOLANA", "COSMOS"],
  pregenId: { email },
});

// Get and encrypt the user share
const keyShare = para.getUserShare();
const encryptedKeyShare = await encrypt(keyShare);
await setKeyShareInDB(email, encryptedKeyShare);
```

### Restore user share for signing

```ts theme={null}
const keyShare = await getKeyShareInDB(email);
const decryptedKeyShare = await decrypt(keyShare);
await para.setUserShare(decryptedKeyShare);

// Now para is ready for signing with any integration
```

### AES-GCM Encryption Pattern

```ts theme={null}
// encryption-utils.ts
const ALGORITHM = "AES-GCM";
const IV_LENGTH = 12;

// ENCRYPTION_KEY env var must be exactly 32 bytes
async function importSecretKey(keyString: string): Promise<CryptoKey> {
  const keyBuffer = Buffer.from(keyString, "utf-8");
  return await crypto.subtle.importKey("raw", keyBuffer, { name: ALGORITHM }, false, ["encrypt", "decrypt"]);
}

export async function encrypt(text: string): Promise<string> {
  const cryptoKey = await importSecretKey(process.env.ENCRYPTION_KEY);
  const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH));
  const encoded = new TextEncoder().encode(text);
  const encrypted = await crypto.subtle.encrypt({ name: ALGORITHM, iv }, cryptoKey, encoded);
  return `${Buffer.from(iv).toString("base64")}:${Buffer.from(encrypted).toString("base64")}`;
}

export async function decrypt(encryptedText: string): Promise<string> {
  const [ivBase64, dataBase64] = encryptedText.split(":");
  const iv = new Uint8Array(Buffer.from(ivBase64, "base64"));
  const data = Buffer.from(dataBase64, "base64");
  const cryptoKey = await importSecretKey(process.env.ENCRYPTION_KEY);
  const decrypted = await crypto.subtle.decrypt({ name: ALGORITHM, iv }, cryptoKey, data);
  return new TextDecoder().decode(decrypted);
}
```

### SQLite Storage Schema

```ts theme={null}
// keySharesDB.ts - uses `sqlite` + `sqlite3` packages
import { open } from "sqlite";
import sqlite3 from "sqlite3";

const db = await open({ filename: "keyShares.db", driver: sqlite3.Database });

await db.exec(`
  CREATE TABLE IF NOT EXISTS keyShares (
    email TEXT PRIMARY KEY NOT NULL,
    keyShare TEXT NOT NULL
  )
`);

// Get
const row = await db.get("SELECT keyShare FROM keyShares WHERE email = ?", [email]);

// Upsert
await db.run(
  "INSERT INTO keyShares (email, keyShare) VALUES (?, ?) ON CONFLICT(email) DO UPDATE SET keyShare = excluded.keyShare",
  [email, encryptedKeyShare]
);
```

***

## 7. Account Abstraction Patterns

### Alchemy ERC-4337

```ts theme={null}
import { alchemy, arbitrumSepolia } from "@account-kit/infra";
import { WalletClientSigner } from "@aa-sdk/core";
import { createModularAccountAlchemyClient } from "@account-kit/smart-contracts";
import { createParaAccount, createParaViemClient } from "@getpara/viem-v2-integration";

const viemParaAccount = createParaAccount(para);
const viemClient = createParaViemClient(para, {
  account: viemParaAccount,
  chain: arbitrumSepolia,
  transport: http(ALCHEMY_RPC_URL),
});

const walletClientSigner = new WalletClientSigner(viemClient, "para");

const alchemyClient = await createModularAccountAlchemyClient({
  transport: alchemy({ rpcUrl: ALCHEMY_RPC_URL }),
  chain: arbitrumSepolia,
  signer: walletClientSigner,
  policyId: ALCHEMY_GAS_POLICY_ID,
});

const result = await alchemyClient.sendUserOperation({ uo: batchCalls });
await alchemyClient.waitForUserOperationTransaction(result);
```

### Alchemy EIP-7702

```ts theme={null}
import { createModularAccountV2Client } from "@account-kit/smart-contracts";
import { createParaAccount } from "@getpara/viem-v2-integration";
import type { SmartAccountSigner, LocalAccount } from "@aa-sdk/core";

const viemParaAccount = createParaAccount(para);

// Wrap as SmartAccountSigner
const paraSigner: SmartAccountSigner<LocalAccount> = {
  signerType: "para",
  inner: viemParaAccount,
  getAddress: async () => viemParaAccount.address,
  signMessage: async (message) => viemParaAccount.signMessage({ message }),
  signTypedData: async (typedData) => viemParaAccount.signTypedData(typedData),
  signAuthorization: async (auth) => viemParaAccount.signAuthorization(auth),
};

const alchemyClient = await createModularAccountV2Client({
  mode: "7702",
  transport: alchemy({ rpcUrl: ALCHEMY_RPC_URL }),
  chain: arbitrumSepolia,
  signer: paraSigner,
  policyId: ALCHEMY_GAS_POLICY_ID,
});
```

### ZeroDev ERC-4337

```ts theme={null}
import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator";
import { createKernelAccount, createKernelAccountClient, createZeroDevPaymasterClient } from "@zerodev/sdk";
import { getEntryPoint, KERNEL_V3_1 } from "@zerodev/sdk/constants";

const viemParaAccount = createParaAccount(para);
const viemClient = createParaViemClient(para, { account: viemParaAccount, chain: arbitrumSepolia, transport: http(ZERODEV_RPC_URL) });
const publicClient = createPublicClient({ chain: arbitrumSepolia, transport: http(ZERODEV_RPC_URL) });

const entryPoint = getEntryPoint("0.7");

const ecdsaValidator = await signerToEcdsaValidator(viemClient, {
  signer: viemParaAccount,
  entryPoint,
  kernelVersion: KERNEL_V3_1,
});

const kernelAccount = await createKernelAccount(publicClient, {
  plugins: { sudo: ecdsaValidator },
  entryPoint,
  kernelVersion: KERNEL_V3_1,
});

const kernelClient = createKernelAccountClient({
  account: kernelAccount,
  chain: arbitrumSepolia,
  bundlerTransport: http(ZERODEV_BUNDLER_RPC),
  paymaster: {
    getPaymasterData: (userOp) =>
      createZeroDevPaymasterClient({ chain: arbitrumSepolia, transport: http(ZERODEV_PAYMASTER_RPC) })
        .sponsorUserOperation({ userOperation: userOp }),
  },
});

const hash = await kernelClient.sendUserOperation({ callData: await kernelClient.account.encodeCalls(calls) });
await kernelClient.waitForUserOperationReceipt({ hash, timeout: 30000 });
```

### ZeroDev EIP-7702

```ts theme={null}
import { create7702KernelAccount, create7702KernelAccountClient } from "@zerodev/ecdsa-validator";
import { KERNEL_V3_3 } from "@zerodev/sdk/constants";

const kernelAccount = await create7702KernelAccount(publicClient, {
  signer: viemParaAccount,
  entryPoint: getEntryPoint("0.7"),
  kernelVersion: KERNEL_V3_3,
});

const kernelClient = create7702KernelAccountClient({
  account: kernelAccount,
  chain: arbitrumSepolia,
  bundlerTransport: http(ZERODEV_BUNDLER_RPC),
  paymaster: createZeroDevPaymasterClient({ chain: arbitrumSepolia, transport: http(ZERODEV_PAYMASTER_RPC) }),
  client: publicClient,
});

const hash = await kernelClient.sendUserOperation({ calls });
```

### Gelato ERC-4337

```ts theme={null}
import { accounts, createGelatoSmartWalletClient } from "@gelatonetwork/smartwallet";

const viemParaAccount = createParaAccount(para);
const viemClient = createParaViemClient(para, { account: viemParaAccount, chain: sepolia, transport: http() });

const account = await accounts.kernel({ eip7702: false, signer: viemClient });
const gelatoClient = createGelatoSmartWalletClient({ account, apiKey: GELATO_API_KEY });

const result = await gelatoClient.execute({
  payment: { type: "sponsored" },
  calls: [{ to: "0x...", value: 0n, data: "0x" }],
});
await result.wait();
```

### Gelato EIP-7702

```ts theme={null}
import { gelato } from "@gelatonetwork/smartwallet/accounts";
import { createGelatoSmartWalletClient } from "@gelatonetwork/smartwallet";

const account = await gelato({ signer: viemClient }); // Different subpath from 4337's accounts.kernel()
const gelatoClient = createGelatoSmartWalletClient({ account, apiKey: GELATO_API_KEY });
// Same execute pattern as 4337
```

### Thirdweb ERC-4337

```ts theme={null}
import { createThirdwebClient, sendTransaction, prepareTransaction } from "thirdweb";
import { viemAdapter, smartWallet } from "thirdweb/wallets";
import { sepolia } from "thirdweb/chains";

const thirdwebClient = createThirdwebClient({ clientId: THIRDWEB_CLIENT_ID });
const personalAccount = viemAdapter.walletClient.fromViem({ walletClient: viemClient });
const wallet = smartWallet({ chain: sepolia, sponsorGas: true });
const smartAccount = await wallet.connect({ client: thirdwebClient, personalAccount });

const tx = prepareTransaction({ to: "0x...", value: 0n, chain: sepolia, client: thirdwebClient });
await sendTransaction({ account: smartAccount, transaction: tx });
```

### Porto EIP-7702

Porto operates on Base Sepolia with a unique EOA-to-smart-account upgrade flow. See `examples-hub/web/with-react-nextjs/aa-porto-7702/` for the full implementation using `Account.from()`, `Key.createSecp256k1()`, and `RelayActions.prepareUpgradeAccount()`.

### Rhinestone ERC-4337

Rhinestone provides cross-chain account abstraction using `@rhinestone/sdk`. See `examples-hub/web/with-react-nextjs/aa-rhinestone-4337/` for cross-chain USDC transfers (Arbitrum->Base) with sponsored transactions.

***

## 8. Connector Integrations

### Wagmi Connector

```ts theme={null}
// src/config/wagmi.ts
import { paraConnector } from "@getpara/wagmi-v2-integration";
import { ParaWeb } from "@getpara/react-sdk-lite"; // or @getpara/react-sdk
import { createConfig, http, cookieStorage, createStorage } from "wagmi";
import { sepolia } from "wagmi/chains";

// Initialize ParaWeb (not ParaProvider - connector manages its own UI)
const para = new ParaWeb(Environment.BETA, API_KEY);

const connector = paraConnector({
  para,
  appName: "My App",
  chains: [sepolia],
  queryClient,
  authLayout: ["AUTH:FULL", "EXTERNAL:FULL"],
  oAuthMethods: ["APPLE", "DISCORD", "FACEBOOK", "FARCASTER", "GOOGLE", "TWITTER"],
  disableEmailLogin: false,
  disablePhoneLogin: false,
  logo: "/logo.svg",
  onRampTestMode: true,
  recoverySecretStepEnabled: true,
  twoFactorAuthEnabled: false,
  theme: {
    foregroundColor: "#222222",
    backgroundColor: "#FFFFFF",
    accentColor: "#888888",
    mode: "light",
    borderRadius: "none",
    font: "Inter",
  },
});

export const wagmiConfig = createConfig({
  chains: [sepolia],
  connectors: [connector, injected(), metaMask(), coinbaseWallet()],
  ssr: true,
  storage: createStorage({ storage: cookieStorage }),
  transports: { [sepolia.id]: http(RPC_URL) },
});
```

Important: The Wagmi connector uses `@getpara/react-sdk-lite` (not the full `@getpara/react-sdk`) to avoid bundle bloat, since the connector provides its own modal.

### RainbowKit

```ts theme={null}
// src/client/wagmi.ts
import { getParaWallet } from "@getpara/rainbowkit-wallet";
import { connectorsForWallets } from "@rainbow-me/rainbowkit";
import { createConfig, http } from "wagmi";
import { sepolia } from "wagmi/chains";

const paraWallet = getParaWallet({
  para,             // ParaWeb instance
  chains: [sepolia],
  appName: "My App",
  // Same modal config options as paraConnector: oAuthMethods, theme, etc.
});

const connectors = connectorsForWallets(
  [{ groupName: "Para", wallets: [paraWallet] }],
  { appName: "My App", projectId: WALLETCONNECT_PROJECT_ID }
);

export const wagmiConfig = createConfig({
  chains: [sepolia],
  connectors,
  transports: { [sepolia.id]: http(RPC_URL) },
});

// Providers: WagmiProvider + QueryClientProvider + RainbowKitProvider
// Then use wagmi hooks: useSignMessage(), useSendTransaction(), etc.
```

### Graz (Cosmos)

```tsx theme={null}
// src/context/Provider.tsx
import { ParaGrazConnector } from "@getpara/graz-integration";
import { ParaWeb, Environment } from "@getpara/react-sdk-lite";
import { GrazProvider, defineChainInfo, type ParaGrazConfig } from "graz";

const para = new ParaWeb(Environment.BETA, API_KEY);

const cosmosTestnet = defineChainInfo({
  chainId: "provider",
  chainName: "Cosmos ICS Provider Testnet",
  rpc: "https://rpc.provider-sentry-01.ics-testnet.polypore.xyz",
  rest: "https://rest.provider-sentry-01.ics-testnet.polypore.xyz",
  bip44: { coinType: 118 },
  bech32Config: { bech32PrefixAccAddr: "cosmos", /* ... other prefixes */ },
  stakeCurrency: { coinDenom: "ATOM", coinMinimalDenom: "uatom", coinDecimals: 6 },
  currencies: [{ coinDenom: "ATOM", coinMinimalDenom: "uatom", coinDecimals: 6 }],
  feeCurrencies: [{ coinDenom: "ATOM", coinMinimalDenom: "uatom", coinDecimals: 6 }],
});

const paraConfig: ParaGrazConfig = {
  paraWeb: para as ParaGrazConfig["paraWeb"],
  connectorClass: ParaGrazConnector,       // Note: connectorClass, not connector instance
  modalProps: { appName: "My App" },
  queryClient: queryClient,
};

// Wrap your app:
<GrazProvider
  grazOptions={{
    chains: [cosmosTestnet],
    paraConfig,
  }}>
  {children}
</GrazProvider>
```

Note: `defineChainInfo` and `ParaGrazConfig` type are imported from `graz`, not from `@getpara/graz-integration`.

***

## 9. Session Management

### Check and keep alive

```ts theme={null}
// Client-side (React hooks)
import { useAccount, useKeepSessionAlive } from "@getpara/react-sdk";
const { isConnected } = useAccount();

// Imperative
const isActive = await para.isSessionActive();
if (isActive) {
  await para.keepSessionAlive();
}
```

### Export / Import session (server transfer)

```ts theme={null}
// Client: export session string
const sessionString = await para.exportSession();

// Send sessionString to server via API call

// Server: import session
const serverPara = new ParaServer(PARA_ENVIRONMENT, PARA_API_KEY);
await serverPara.importSession(sessionString);

// Server can now sign on behalf of the user
const isActive = await serverPara.isSessionActive();
```

### Issue JWT

```ts theme={null}
// Client-side
import { useIssueJwt } from "@getpara/react-sdk";
const { issueJwt } = useIssueJwt();

const { token, keyId } = await issueJwt();
// Send `token` to your server for verification

// Imperative
const { token, keyId } = await para.issueJWT();
```

***

## 10. ParaModal Configuration

The `paraModalConfig` prop on `<ParaSDKProvider>` (or the config object for `paraConnector`) accepts:

```ts theme={null}
interface ParaModalConfig {
  // Authentication layout
  authLayout?: ("AUTH:FULL" | "AUTH:CONDENSED" | "EXTERNAL:FULL" | "EXTERNAL:CONDENSED")[];

  // Email / Phone login toggles
  disableEmailLogin?: boolean;
  disablePhoneLogin?: boolean;
  defaultAuthIdentifier?: string; // Pre-fill email/phone

  // OAuth providers
  oAuthMethods?: TOAuthMethod[];
  // TOAuthMethod = "APPLE" | "DISCORD" | "FACEBOOK" | "FARCASTER" | "GOOGLE" | "TWITTER" | "TELEGRAM"

  // Branding
  logo?: string; // recommended 372x160px

  // Theme
  theme?: {
    foregroundColor?: string;
    backgroundColor?: string;
    accentColor?: string;
    darkForegroundColor?: string;
    darkBackgroundColor?: string;
    darkAccentColor?: string;
    overlayBackground?: string;
    mode?: "light" | "dark";
    borderRadius?: "none" | "xs" | "sm" | "md" | "lg" | "xl" | "full";
    font?: string;
    oAuthLogoVariant?: "dark" | "light" | "default";
  };

  // Features
  onRampTestMode?: boolean;
  recoverySecretStepEnabled?: boolean;
  twoFactorAuthEnabled?: boolean;
  hideWallets?: boolean;           // Hide wallet terminology
  isGuestModeEnabled?: boolean;    // Enable guest login
  bareModal?: boolean;             // No overlay backdrop
  embeddedModal?: boolean;         // Embedded styling
  className?: string;              // Custom CSS class

  // Account linking
  supportedAccountLinks?: ("EMAIL" | "PHONE" | "GOOGLE" | "EXTERNAL_WALLET")[];

  // Step override
  currentStepOverride?: ModalStepProp;
  // Steps: AUTH_MAIN, AUTH_MORE, AWAITING_OAUTH, VERIFICATIONS,
  //   BIOMETRIC_CREATION, PASSWORD_CREATION, SECRET, AWAITING_WALLET_CREATION,
  //   ACCOUNT_MAIN, ACCOUNT_PROFILE, CHAIN_SWITCH,
  //   EX_WALLET_MORE, EX_WALLET_SELECTED,
  //   ADD_FUNDS_BUY, ADD_FUNDS_RECEIVE, ADD_FUNDS_WITHDRAW,
  //   SETUP_2FA, VERIFY_2FA

  // Callbacks
  onModalStepChange?: (value: any) => void;
  onClose?: () => void;

  // Advanced overrides
  loginTransitionOverride?: (para: ParaWeb) => Promise<void>;
  createWalletOverride?: (para: ParaWeb) => Promise<{ recoverySecret?: string; walletIds: any }>;
}
```

> **Note:** Password and PIN screens render in an iframe and use the Developer Portal theme settings, not `paraModalConfig.theme`.

***

## 11. Mobile Setup Requirements

### Required Native Modules (Expo)

```json theme={null}
{
  "@craftzdog/react-native-buffer": "^6.1.0",
  "@getpara/react-native-wallet": "<same version as other @getpara/* packages>",
  "@peculiar/webcrypto": "^1.5.0",
  "@react-native-async-storage/async-storage": "^2.2.0",
  "react-native-keychain": "^10.0.0",
  "react-native-modpow": "^1.1.0",
  "react-native-passkey": "^3.3.2",
  "react-native-quick-base64": "^2.2.0",
  "react-native-quick-crypto": "^0.7.14",
  "react-native-worklets": "^0.5.1",
  "readable-stream": "^4.5.2"
}
```

### Metro Config (polyfills)

```js theme={null}
// metro.config.js
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;
```

### Babel Config

```js theme={null}
// babel.config.js
module.exports = function (api) {
  api.cache(true);
  return {
    presets: [['babel-preset-expo', { jsxImportSource: 'nativewind' }], 'nativewind/babel'],
    plugins: ['react-native-worklets/plugin'],
  };
};
```

### iOS Passkey Setup

For passkey support on iOS, you must configure your app's Associated Domains capability with a `webcredentials:` entry pointing to your domain. The domain must serve an `apple-app-site-association` file. See `examples-hub/mobile/with-expo-one-click-login/ios/` for an example Xcode project configuration.

### Key Init Option

Always pass `{ disableWorkers: true }` when initializing `ParaMobile` - Web Workers are not available in React Native.

***

## 12. Vite Polyfill Configuration

Vue and Svelte projects using Vite need `vite-plugin-node-polyfills` because the Para SDK uses Node.js built-in modules (`buffer`, `crypto`, `stream`).

```ts theme={null}
// vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue"; // or svelte()
import { nodePolyfills } from "vite-plugin-node-polyfills";

export default defineConfig({
  plugins: [vue(), nodePolyfills()],
});
```

Install:

```bash theme={null}
npm install -D vite-plugin-node-polyfills
```

This is required for `@getpara/web-sdk`. The `@getpara/react-sdk` with Next.js does **not** need this (Next.js handles polyfills via `npx setup-para` postinstall script).

***

## 13. REST API Direct Usage

For server-to-server integrations without the SDK, use the REST API directly.

### Base URLs

| Environment | URL                            |
| ----------- | ------------------------------ |
| Beta        | `https://api.beta.getpara.com` |
| Production  | `https://api.getpara.com`      |

### Authentication Header

```
X-API-Key: your_api_key
X-Request-Id: <uuid>          # optional, for request tracing
Content-Type: application/json
```

### Endpoints

```
POST /v1/wallets                     - Create wallet
GET  /v1/wallets/{walletId}          - Get wallet details
POST /v1/wallets/{walletId}/sign-raw - Sign raw bytes (0x-prefixed hex)
```

### Create Wallet Request

```json theme={null}
{
  "type": "EVM",
  "userIdentifier": "alice@example.com",
  "userIdentifierType": "EMAIL",
  "scheme": "DKLS"
}
```

* `type`: `"EVM"` | `"SOLANA"` | `"COSMOS"`
* `userIdentifierType`: `"EMAIL"` | `"PHONE"` | `"CUSTOM_ID"` | `"GUEST_ID"` | `"TELEGRAM"` | `"DISCORD"` | `"TWITTER"`
* `scheme`: `"DKLS"` | `"CGGMP"` | `"ED25519"` (optional, defaults based on wallet type)
* `cosmosPrefix`: string (optional, for Cosmos wallets)

### Sign Raw Request

```json theme={null}
{
  "data": "0xdeadbeef..."
}
```

### Error Codes

| Code | Meaning                          |
| ---- | -------------------------------- |
| 201  | Created                          |
| 200  | Success                          |
| 400  | Bad request (invalid params)     |
| 401  | Unauthorized (invalid API key)   |
| 404  | Not found                        |
| 409  | Conflict (wallet already exists) |
| 429  | Rate limited                     |
| 500  | Server error                     |

### Example Node.js client

```ts theme={null}
const PARA_API_KEY = process.env.PARA_API_KEY;
const BASE_URL = process.env.PARA_REST_BASE_URL ?? "https://api.beta.getpara.com";

async function callPara<T>(path: string, options: { method?: string; body?: unknown } = {}): Promise<T> {
  const { method = "GET", body } = options;
  const headers: Record<string, string> = {
    "X-API-Key": PARA_API_KEY,
    "X-Request-Id": crypto.randomUUID(),
  };
  if (body) headers["Content-Type"] = "application/json";

  const res = await fetch(`${BASE_URL}${path}`, {
    method,
    headers,
    body: body ? JSON.stringify(body) : undefined,
  });

  const data = await res.json();
  if (!res.ok) throw new Error(`Para ${res.status}: ${JSON.stringify(data)}`);
  return data as T;
}
```

***

## 14. React Hook Reference

### CSS Import

ParaModal requires its stylesheet:

```tsx theme={null}
import "@getpara/react-sdk/styles.css";
```

Add this in your root layout or ParaProvider component.

`ParaProvider` renders an embedded `ParaModal` by default. Do not render a separate `<ParaModal />` unless `config.disableEmbeddedModal` is set to `true`.

### From `@getpara/react-sdk`

**Account & Connection:**

* `useAccount()` -> `{ isConnected, isConnecting, address, embedded }` - `embedded.wallets` contains wallet array
* `useClient()` -> Para client instance (for passing to signer constructors)
* `useIsFullyLoggedIn()` -> `boolean | undefined`
* `useParaStatus()` -> `ParaStatus` (readiness and Farcaster Mini App detection)
* `useModal()` -> `{ isOpen, openModal, closeModal }`
* `useWallet()` -> `Wallet | null | undefined` (active wallet)
* `useWalletState()` -> `{ selectedWallet, setSelectedWallet, updateSelectedWallet }`
* `useLinkedAccounts()` -> `LinkedAccounts & { userId: string }`

**Authentication:**

* `useSignUpOrLogIn()` -> `{ signUpOrLogIn, signUpOrLogInAsync, isPending }`
* `useVerifyOAuth()` -> `{ verifyOAuth, isPending }`
* `useVerifyFarcaster()` -> `{ verifyFarcaster, isPending }`
* `useVerifyNewAccount()` -> `{ verifyNewAccount, verifyNewAccountAsync }`
* `useWaitForLogin()` -> `{ waitForLogin, isPending }`
* `useWaitForWalletCreation()` -> `{ waitForWalletCreation, isPending }`
* `useLoginExternalWallet()` -> `{ loginExternalWallet, loginExternalWalletAsync }`
* `useLogout()` -> `{ logout, logoutAsync }`
* `useAddAuthMethod()` -> `{ addCredential, addCredentialAsync }`
* `useLinkAccount()` -> `{ linkAccount, isPending, error }`

**Signing (low-level):**

* `useSignMessage()` -> `{ signMessage, signMessageAsync }` - signs base64-encoded message with wallet ID
* `useSignTransaction()` -> `{ signTransaction, signTransactionAsync }`

**Session:**

* `useKeepSessionAlive()` -> `{ keepSessionAlive, keepSessionAliveAsync }`
* `useIssueJwt()` -> `{ issueJwt, issueJwtAsync }` -> `{ token, keyId }`

**Wallet Management:**

* `useCreateWallet()` -> `{ createWallet, createWalletAsync }`
* `useCreateWalletPerType()` -> `{ createWalletPerType, createWalletPerTypeAsync }` - create wallets for multiple chain types
* `useCreateGuestWallets()` -> `{ createGuestWallets, createGuestWalletsAsync }`
* `useWalletBalance()` -> `string | null` - balance in native units

### From `@getpara/react-sdk/evm`

EVM-specific hooks for direct Viem client access. `@getpara/react-sdk` includes `@getpara/viem-v2-integration`; install `viem` when your app imports Viem helpers directly:

* `useViemClient({ address, walletClientConfig })` -> `{ viemClient }` - returns a Viem WalletClient pre-configured with the Para signer

```ts theme={null}
import { useAccount } from "@getpara/react-sdk";
import { useViemClient } from "@getpara/react-sdk/evm";
import { http } from "viem";
import { sepolia } from "viem/chains";

const { embedded } = useAccount();
const address = embedded?.wallets?.[0]?.address as `0x${string}`;
const { viemClient } = useViemClient({
  address,
  walletClientConfig: { chain: sepolia, transport: http() },
});

// viemClient.sendTransaction, viemClient.signMessage, etc.
```

This is the preferred way to use Viem in React - no need to import `createParaAccount` / `createParaViemClient` directly.

### From `@getpara/react-sdk/viem`

* `useViemAccount({ address? })` -> `{ viemAccount: Account | null, isLoading }` - lower-level access to the viem Account without creating a full WalletClient

### From `@getpara/react-sdk/solana`

* `useSolanaSigner({ rpc, walletId? })` -> `{ solanaSigner: SignerWalletAdapter | null, isLoading }` - for Solana Signers v2 integration

### From `@getpara/react-sdk/cosmos`

* `useCosmjsProtoSigner({ prefix?, walletId?, messageSigningTimeoutMs? })` -> `{ protoSigner: OfflineDirectSigner | null, isLoading }` - for CosmJS proto signing
* `useCosmjsAminoSigner({ prefix?, walletId?, messageSigningTimeoutMs? })` -> `{ aminoSigner: OfflineAminoSigner | null, isLoading }` - for CosmJS amino signing

```ts theme={null}
// CosmJS example using hooks
import { useCosmjsProtoSigner } from "@getpara/react-sdk/cosmos";
import { SigningStargateClient } from "@cosmjs/stargate";

const { protoSigner } = useCosmjsProtoSigner({ prefix: "cosmos" });
const stargateClient = await SigningStargateClient.connectWithSigner(RPC_URL, protoSigner);
```

***

## 15. Testing Credentials

### Beta Environment

* **Environment**: `Environment.BETA` / `"BETA"`
* **Portal base URL**: `https://app.beta.getpara.com`
* **API base URL**: `https://api.beta.getpara.com`

### Test Email Pattern

Use any email ending in `@test.getpara.com` (e.g., `dev@test.getpara.com`, `test1@test.getpara.com`). **Any OTP code works** (e.g., `123456`, `000000`).

### Test Phone Numbers

Use US numbers (+1) with format `(area code)-555-xxxx` (e.g., `(425)-555-1234`, `(206)-555-9876`). **Any OTP code works**.

### User Limits

50 users per beta account. Delete test users via [Developer Portal](https://developer.getpara.com) -> Users section. Users can only be deleted in BETA; in production, wallets are permanent.

### Post-Install Setup

Many Next.js examples include a `postinstall` script:

```json theme={null}
"postinstall": "npx setup-para"
```

This configures Next.js webpack to handle Para SDK's WASM and worker files. Always run it after `npm install`.

***

## 16. Examples Hub Directory Map

### Web - Framework Setup

| Directory                           | Framework      | SDK                  | Key Concept                         |
| ----------------------------------- | -------------- | -------------------- | ----------------------------------- |
| `web/with-react-nextjs/para-modal/` | Next.js        | `@getpara/react-sdk` | ParaProvider + ParaModal quickstart |
| `web/with-react-vite/`              | React + Vite   | `@getpara/react-sdk` | Vite with React                     |
| `web/with-svelte-vite/`             | Svelte + Vite  | `@getpara/web-sdk`   | Imperative ParaWeb init             |
| `web/with-vue-vite/`                | Vue + Vite     | `@getpara/web-sdk`   | Imperative ParaWeb init             |
| `web/with-react-tanstack-start/`    | TanStack Start | `@getpara/react-sdk` | Full-stack meta-framework           |
| `web/with-chrome-extension/`        | Chrome Ext     | `@getpara/react-sdk` | Storage overrides                   |
| `web/with-pwa/`                     | PWA            | `@getpara/react-sdk` | Progressive Web App                 |

### Web - Authentication

| Directory                                     | Auth Method                             |
| --------------------------------------------- | --------------------------------------- |
| `web/with-react-nextjs/custom-email-auth/`    | Email + passkey verification            |
| `web/with-react-nextjs/custom-phone-auth/`    | Phone + OTP verification                |
| `web/with-react-nextjs/custom-oauth-auth/`    | OAuth (Google, Apple, etc.) + Farcaster |
| `web/with-react-nextjs/custom-combined-auth/` | All auth methods combined               |

### Web - Signing Libraries

| Directory                                         | Library           | Package                                                           |
| ------------------------------------------------- | ----------------- | ----------------------------------------------------------------- |
| `web/with-react-nextjs/signer-viem-v2/`           | Viem 2.x          | `@getpara/viem-v2-integration`                                    |
| `web/with-react-nextjs/signer-ethers-v5/`         | Ethers 5.x        | `@getpara/ethers-v5-integration`                                  |
| `web/with-react-nextjs/signer-ethers-v6/`         | Ethers 6.x        | `@getpara/ethers-v6-integration`                                  |
| `web/with-react-nextjs/signer-solana-web3/`       | Solana Web3.js    | `@getpara/solana-web3.js-v1-integration`                          |
| `web/with-react-nextjs/signer-solana-anchor/`     | Anchor            | `@getpara/solana-web3.js-v1-integration`                          |
| `web/with-react-nextjs/signer-solana-signers-v2/` | Solana Signers v2 | `@getpara/solana-signers-v2-integration`                          |
| `web/with-react-nextjs/signer-cosmjs/`            | CosmJS            | `@getpara/react-sdk` (uses `useCosmjsProtoSigner` from `/cosmos`) |

### Web - Connectors

| Directory                                       | Connector     | Package                                                     |
| ----------------------------------------------- | ------------- | ----------------------------------------------------------- |
| `web/with-react-nextjs/connector-wagmi/`        | Wagmi v2      | `@getpara/wagmi-v2-integration` + `@getpara/react-sdk-lite` |
| `web/with-react-nextjs/connector-rainbowkit/`   | RainbowKit    | `@getpara/rainbowkit-wallet`                                |
| `web/with-react-nextjs/connector-graz/`         | Graz (Cosmos) | `@getpara/graz-integration`                                 |
| `web/with-react-nextjs/connector-reown-appkit/` | Reown AppKit  | `@getpara/wagmi-v2-integration`                             |

### Web - Account Abstraction

| Directory                                   | Provider   | Standard |
| ------------------------------------------- | ---------- | -------- |
| `web/with-react-nextjs/aa-alchemy-4337/`    | Alchemy    | ERC-4337 |
| `web/with-react-nextjs/aa-alchemy-7702/`    | Alchemy    | EIP-7702 |
| `web/with-react-nextjs/aa-zerodev-4337/`    | ZeroDev    | ERC-4337 |
| `web/with-react-nextjs/aa-zerodev-7702/`    | ZeroDev    | EIP-7702 |
| `web/with-react-nextjs/aa-gelato-4337/`     | Gelato     | ERC-4337 |
| `web/with-react-nextjs/aa-gelato-7702/`     | Gelato     | EIP-7702 |
| `web/with-react-nextjs/aa-thirdweb-4337/`   | Thirdweb   | ERC-4337 |
| `web/with-react-nextjs/aa-rhinestone-4337/` | Rhinestone | ERC-4337 |
| `web/with-react-nextjs/aa-porto-7702/`      | Porto      | EIP-7702 |

### Web - Modal Variants

| Directory                                      | Chain Focus                   |
| ---------------------------------------------- | ----------------------------- |
| `web/with-react-nextjs/para-modal/`            | Default (all chains)          |
| `web/with-react-nextjs/para-modal-evm/`        | EVM only                      |
| `web/with-react-nextjs/para-modal-solana/`     | Solana only                   |
| `web/with-react-nextjs/para-modal-cosmos/`     | Cosmos only                   |
| `web/with-react-nextjs/para-modal-multichain/` | Explicit multi-chain          |
| `web/with-react-nextjs/para-pregen-claim/`     | Pre-generated wallet claiming |

### Server

| Directory                | Runtime | Key Features                                                              |
| ------------------------ | ------- | ------------------------------------------------------------------------- |
| `server/with-node/`      | Node.js | Pregen wallets, Viem/Ethers/Solana/CosmJS signing, Alchemy AA, ZeroDev AA |
| `server/with-bun/`       | Bun     | Session-based signing, Alchemy/ZeroDev EIP-7702                           |
| `server/with-deno/`      | Deno    | Session-based signing, Alchemy/ZeroDev EIP-7702                           |
| `server/rest-with-node/` | Node.js | REST API direct usage (no SDK, raw fetch)                                 |

### Mobile

| Directory                           | Platform     | Key Features                                       |
| ----------------------------------- | ------------ | -------------------------------------------------- |
| `mobile/with-react-native/`         | React Native | Standard RN setup                                  |
| `mobile/with-expo-one-click-login/` | Expo         | One-click login, passkeys, native crypto polyfills |

### Advanced Patterns

| Directory                                    | Pattern                                                 |
| -------------------------------------------- | ------------------------------------------------------- |
| `advanced-patterns/client-auth-server-sign/` | Client authenticates, exports session, server signs     |
| `advanced-patterns/with-bulk-pregen/`        | Bulk wallet pre-generation with multi-chain claiming UI |

### DeFi Integrations

| Directory                                  | Integration              |
| ------------------------------------------ | ------------------------ |
| `defi-integrations/with-jupiter-dex-api/`  | Jupiter DEX (Solana)     |
| `defi-integrations/with-squid-router-api/` | Squid cross-chain router |
| `defi-integrations/with-relay-bridge-api/` | Relay Protocol bridge    |

***
