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

# Project Setup

> Configure your project structure and SDK initialization

This guide covers the recommended project structure and SDK initialization patterns for Amplify SDK integrations.

## Recommended Directory Structure

A consistent file layout keeps vault logic, wallet plumbing, and UI concerns easy to reason about:

```text theme={null}
├─ .env.local             # Privy App ID, Amplify API key, RPC URLs (never commit)
├─ package.json
├─ src/
│  ├─ app/
│  │  ├─ App.tsx          # Top-level routes, feature shells
│  │  └─ providers.tsx    # React providers (PrivyProvider, AmplifyProvider, QueryClient)
│  ├─ components/
│  │  ├─ DepositForm.tsx
│  │  ├─ WithdrawForm.tsx
│  │  └─ StatusBanner.tsx
│  ├─ hooks/
│  │  ├─ useAmplify.ts    # initAmplifySDK + helper wrappers
│  │  └─ useBalances.ts   # data fetching with react-query / wagmi
│  ├─ lib/
│  │  ├─ privy.ts         # Privy login/logout helpers
│  │  └─ viem.ts          # Public/wallet client factories
│  ├─ pages/              # Optional route segments (Next.js / Remix)
│  ├─ styles/
│  └─ main.tsx            # Vite entry point
├─ tests/                 # Component and integration tests
└─ docs/                  # Internal runbooks and integration notes
```

### Separation of Concerns

* **Providers layer** – initialize Privy, React Query, and the Amplify SDK once. Re-export hooks for the rest of the app.
* **Hooks layer** – wrap SDK helpers (`prepareDeposit`, `prepareWithdrawal`) with domain-specific logic and query invalidation.
* **Components layer** – pure UI components that receive prepared data plus callbacks for execution.
* **Lib layer** – interaction helpers for viem, Privy, or analytics that should not depend on React state.

## SDK Initialization

All Amplify SDK functions require initialization before use. Call `initAmplifySDK()` once at application startup.

### Basic Initialization

```ts theme={null}
import { initAmplifySDK } from "@paxoslabs/amplify-sdk";

await initAmplifySDK("pxl_your_api_key");
```

### With Custom RPCs

For the best user experience and reliability, we recommend using your own RPCs:

```ts theme={null}
import { initAmplifySDK } from "@paxoslabs/amplify-sdk";
import { mainnet, sepolia } from "viem/chains";

await initAmplifySDK("pxl_your_api_key", {
  rpcUrls: {
    [mainnet.id]: import.meta.env.VITE_APP_ETHEREUM_MAINNET_RPC,
    [sepolia.id]: import.meta.env.VITE_APP_ETHEREUM_SEPOLIA_RPC,
  },
});
```

### With Configuration Options

```ts theme={null}
import { initAmplifySDK, LogLevel } from "@paxoslabs/amplify-sdk";

await initAmplifySDK("pxl_your_api_key", {
  telemetry: true,           // Enable PostHog error tracking (default)
  logLevel: LogLevel.ERROR,  // Minimum log level (default)
});
```

### React Integration Hook

Create a hook to initialize the SDK once and expose ready state:

```ts theme={null}
// src/hooks/useAmplify.ts
import { initAmplifySDK, LogLevel } from "@paxoslabs/amplify-sdk";
import { useEffect, useState } from "react";
import { mainnet } from "viem/chains";

let initialized = false;

export function useAmplify() {
  const [isReady, setIsReady] = useState(initialized);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    if (initialized) {
      setIsReady(true);
      return;
    }

    const apiKey = import.meta.env.VITE_AMPLIFY_API_KEY;
    if (!apiKey) {
      setError(new Error("Missing VITE_AMPLIFY_API_KEY env variable"));
      return;
    }

    async function init() {
      try {
        await initAmplifySDK(apiKey, {
          rpcUrls: {
            [mainnet.id]: import.meta.env.VITE_APP_ETHEREUM_MAINNET_RPC,
          },
          logLevel: LogLevel.ERROR,
          telemetry: true,
        });
        initialized = true;
        setIsReady(true);
      } catch (err) {
        setError(err instanceof Error ? err : new Error("SDK initialization failed"));
      }
    }

    init();
  }, []);

  return { isReady, error };
}
```

### Usage in App

```tsx theme={null}
// src/App.tsx
import { useAmplify } from "./hooks/useAmplify";

export function App() {
  const { isReady, error } = useAmplify();

  if (error) {
    return <div>Failed to initialize SDK: {error.message}</div>;
  }

  if (!isReady) {
    return <div>Initializing...</div>;
  }

  return <YourApp />;
}
```

## Environment Variables

Create `.env.local` (ignored by Vite by default):

```bash theme={null}
VITE_PRIVY_APP_ID=your-privy-app-id
VITE_AMPLIFY_API_KEY=pxl_your_api_key
VITE_RPC_URL=https://eth-mainnet.g.alchemy.com/v2/your-key
VITE_APP_ETHEREUM_MAINNET_RPC=https://eth-mainnet.g.alchemy.com/v2/your-key
VITE_APP_ETHEREUM_SEPOLIA_RPC=https://eth-sepolia.g.alchemy.com/v2/your-key
```

<Warning>
  Never commit `.env.local`. Provide an `.env.example` without secrets for teammates.
</Warning>

## Global Providers

Set up React Query and your wallet provider:

```tsx theme={null}
// src/app/providers.tsx
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { PrivyProvider } from "@privy-io/react-auth";
import type { ReactNode } from "react";

const queryClient = new QueryClient();

export function AmplifyProviders({ children }: { children: ReactNode }) {
  if (!import.meta.env.VITE_PRIVY_APP_ID) {
    throw new Error("Missing VITE_PRIVY_APP_ID env variable");
  }

  return (
    <PrivyProvider appId={import.meta.env.VITE_PRIVY_APP_ID}>
      <QueryClientProvider client={queryClient}>
        {children}
      </QueryClientProvider>
    </PrivyProvider>
  );
}
```

Wire the providers in your entry point:

```tsx theme={null}
// src/main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App.tsx";
import { AmplifyProviders } from "./providers.tsx";

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <AmplifyProviders>
      <App />
    </AmplifyProviders>
  </StrictMode>,
);
```

## Server-Side Usage

If you execute transactions from a backend service, mirror the same separation:

* `server/app.ts` – Express/Fastify entry point
* `server/clients/amplify.ts` – `initAmplifySDK` and helper wrappers
* `server/services/deposits.ts` – orchestrates approvals, permits, or withdrawals

## Next Steps

* Follow the [Deposits guide](./deposits) to implement your first deposit flow
* See [initAmplifySDK](/v0.4.2/intro/products/earn/developers/api/initAmplifySDK) for full API reference
* Check [Logging](./logging) for debug configuration
