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

# Developer Guide

> End-to-end workflow for shipping Amplify Earn features

This guide walks through the lifecycle of launching and maintaining a Stablecoin Earn integration—from sandbox setup to production operations. Treat it as the map that connects the [Quickstart](./quickstart), [Concepts](./concepts), and [Functions](./functions/index) sections.

## 1. Access & Environment

1. Request a Paxos-issued Amplify **API key** for your environment (sandbox, staging, production).
2. Store the key as a secret (`.env`, HashiCorp Vault, CI secrets manager).
3. Confirm network access to required RPC endpoints (Alchemy, Infura, or your in-house nodes).
4. Decide where transactions are signed (end-user wallet via Privy, custodial flow, or backend signer).

## 2. Scaffold the App

* Follow the [Quickstart](./quickstart) to spin up a Vite + React + Privy project.
* Mirror the recommended [Directory Structure](./directory-structure) and create providers for Privy, Amplify, and your data cache.
* Add feature flags or progressive rollout gates if you are staging Earn access.

## 3. Initialize the SDK

* Call `initAmplifySDK(apiKey)` once on boot (client or server).
* Wrap the call in a provider that throws if the key is missing or the init step fails.
* Track initialization metrics to catch missing environment variables early.

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

// Initialize with configuration
await initAmplifySDK(import.meta.env.VITE_APP_PAXOS_API_KEY, {
  logLevel: LogLevel.ERROR,
  telemetry: true,
});
```

For advanced configuration (custom loggers, telemetry control), see [SDK Initialization](./sdk-initialization) and [Logging](./logging).

## 4. Discover Vaults & Assets

* Use `fetchSupportedAssets` to build product selectors.

```ts theme={null}
// App.tsx
import {
  fetchSupportedAssets,
  initAmplifySDK,
  YieldType,
  type SupportedAsset,
} from "@paxoslabs/amplify-sdk";

// Initialize sdk with your PaxosLabs API key
initAmplifySDK(import.meta.env.VITE_APP_PAXOS_API_KEY as string);

// Fetch supported assets based on the specific YieldType
// Note: the example given is using TanStack Query
const {
  data: sdkAssets,
  isLoading: isLoadingSdkAssets,
  isError: isErrorSdkAssets,
} = useQuery({
  queryKey: ["amplifySDK"], // query key is part of TanStack Query and can be anything.
  queryFn: () => fetchSupportedAssets({ yieldType: YieldType.PRIME }),
});
```

* Cache results (React Query, SWR, server-side caches) with sensible revalidation periods.
* Map vault metadata to your UI components (APY, supported assets, min/max).

## 5. Execute Flows

Our focus is on providing the best UX possible for our users. The **Unified Deposit API** simplifies this with automatic authorization detection.

### Unified Deposit API (Recommended)

The unified API automatically determines the optimal authorization method:

| Authorization Method | Description                                                      |
| -------------------- | ---------------------------------------------------------------- |
| `PERMIT`             | EIP-2612 off-chain signature (gas efficient, single transaction) |
| `APPROVAL`           | Traditional ERC20 approval (two transactions)                    |
| `ALREADY_APPROVED`   | Existing allowance sufficient (no authorization needed)          |

```ts theme={null}
import {
  prepareDepositAuthorization,
  prepareDeposit,
  DepositAuthMethod,
} from "@paxoslabs/amplify-sdk";

// Step 1: Determine authorization method
const auth = await prepareDepositAuthorization({
  yieldType: YieldType.CORE,
  depositToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
  depositAmount: "1000",
  recipientAddress: userAddress,
  chainId: 1,
});

// Step 2: Handle based on method
switch (auth.method) {
  case DepositAuthMethod.PERMIT:
    // Sign permit, then deposit with signature
    break;
  case DepositAuthMethod.APPROVAL:
    // Send approval tx, then deposit
    break;
  case DepositAuthMethod.ALREADY_APPROVED:
    // Deposit directly
    break;
}
```

### Flow Comparison

| Flow              | Functions                                                         | Transactions | Best For                |
| ----------------- | ----------------------------------------------------------------- | ------------ | ----------------------- |
| Unified Deposit   | `prepareDepositAuthorization`, `prepareDeposit`                   | 1-2          | All cases (recommended) |
| Permit Deposit    | `prepareDepositPermitSignature`, `prepareDepositWithPermitTxData` | 1            | EIP-2612 tokens only    |
| Approve & Deposit | `prepareApproveDepositTokenTxData`, `prepareDepositTxData`        | 2            | Legacy integration      |
| Withdraw          | `prepareApproveWithdrawTxData`, `prepareWithdrawTxData`           | 2            | All withdrawals         |

### Notes

* Each helper returns deterministic calldata and throws `APIError` with actionable metadata.
* Execute transactions with `viem`, `wagmi`, or Privy helpers—never with raw `ethers.js` strings.
* Record failed transactions alongside the `endpoint` value to accelerate debugging.
* Default slippage is 50 basis points (0.5%). Increase for volatile conditions.

## 6. Error Handling

All SDK functions throw `APIError` with actionable information:

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

try {
  const auth = await prepareDepositAuthorization(params);
} catch (error) {
  if (error instanceof APIError) {
    if (error.code === "VAULT_NOT_FOUND") {
      // Show user that vault/token/chain combination is unsupported
    }
    if (error.code === "SDK_NOT_INITIALIZED") {
      // Ensure initAmplifySDK() was called
    }
  } else {
    // Handle unexpected errors (network issues, etc.)
    throw error;
  }
}
```

| Error Code               | Description                                        |
| ------------------------ | -------------------------------------------------- |
| `SDK_NOT_INITIALIZED`    | Call `initAmplifySDK()` before other functions     |
| `VAULT_NOT_FOUND`        | No vault matches the yieldType, token, and chainId |
| `PERMIT_NOT_SUPPORTED`   | Token doesn't support EIP-2612, use approval flow  |
| `INSUFFICIENT_ALLOWANCE` | Need larger approval or use permit                 |

You now have the skeleton needed to build durable Earn experiences. Dive into the [Concepts](./concepts) section for protocol context or jump back to the [Quickstart](./quickstart) when onboarding new teammates.
