Skip to main content

Requirements

  • Node.js 22 or higher
  • npm, yarn, pnpm, or bun

Install the SDK

pnpm add @paxoslabs/amplify-sdk

Install Peer Dependencies

The SDK works with various wallet libraries. Install the dependencies for your chosen stack:
pnpm add @privy-io/react-auth viem @tanstack/react-query

Environment Variables

Create .env.local (ignored by Vite by default):
# Required
VITE_AMPLIFY_API_KEY=pxl_your_api_key

# Optional: Wallet provider credentials
VITE_PRIVY_APP_ID=your-privy-app-id

# Recommended: Custom RPC endpoints
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
Never commit .env.local. Provide an .env.example without secrets for teammates.

Initialize the SDK

Call initAmplifySDK() once at application startup before using any other SDK functions.

Basic

import { initAmplifySDK } from "@paxoslabs/amplify-sdk";

await initAmplifySDK("pxl_your_api_key");

With Custom RPCs

For the best user experience and reliability, use your own RPC endpoints:
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 All Options

import { initAmplifySDK, LogLevel } from "@paxoslabs/amplify-sdk";

await initAmplifySDK("pxl_your_api_key", {
  rpcUrls: {
    1: import.meta.env.VITE_APP_ETHEREUM_MAINNET_RPC,
  },
  telemetry: true,
  logLevel: LogLevel.ERROR,
});

React Integration Hook

Create a hook to initialize the SDK once and expose ready state:
// 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 };
}

Verify Installation

Test that everything is working:
import { initAmplifySDK, getVaultsByConfig } from "@paxoslabs/amplify-sdk";

async function verify() {
  await initAmplifySDK("pxl_your_api_key");

  const vaults = await getVaultsByConfig();
  console.log(`Found ${vaults.length} vaults:`);
  for (const vault of vaults) {
    console.log(`  ${vault.name}${vault.yieldType} on chain ${vault.chainId}`);
  }
}

verify();

Package Exports

The SDK supports focused imports for tree-shaking:
// Main entry — all public APIs
import { initAmplifySDK, getVaultsByConfig } from "@paxoslabs/amplify-sdk";

// Low-level helpers (contract reads, price feeds)
import { getEthPrice, getRateInQuoteWithAssetDecimals } from "@paxoslabs/amplify-sdk/core";

// Vault operations
import { prepareDeposit, prepareDepositAuthorization } from "@paxoslabs/amplify-sdk/vaults";

// Utility helpers
import { calculateDeadline } from "@paxoslabs/amplify-sdk/utils";

Global Providers

Set up React Query and your wallet provider:
// 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:
// 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>,
);
.env.local
package.json
src
app
App.tsx
providers.tsx
components
DepositForm.tsx
WithdrawForm.tsx
hooks
useAmplify.ts
useBalances.ts
lib
privy.ts
viem.ts
pages
styles
main.tsx
LayerDirectoryPurpose
Providerssrc/app/providers.tsxInitialize Privy, React Query, and the Amplify SDK once.
Hookssrc/hooks/Wrap SDK helpers with domain-specific logic and query invalidation.
Componentssrc/components/Pure UI components that receive prepared data plus callbacks for execution.
Libsrc/lib/Interaction helpers for viem, Privy, or analytics that should not depend on React state.

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.tsinitAmplifySDK and helper wrappers
  • server/services/deposits.ts – orchestrates approvals, permits, or withdrawals

Next Steps