Skip to main content
This example demonstrates a complete deposit flow using pure viem without React, suitable for Node.js scripts or vanilla TypeScript applications.
This example uses the unified deposit API which automatically detects the optimal authorization method (permit vs approval).

Prerequisites

  • Node.js 18+
  • viem 2+
  • Amplify API key from Paxos Labs

Installation

pnpm add @paxoslabs/amplify-sdk viem

Complete Example

// deposit.ts
import { createWalletClient, createPublicClient, custom, http } from "viem";
import { mainnet } from "viem/chains";
import {
  initAmplifySDK,
  prepareDepositAuthorization,
  prepareDepositTxData,
  prepareDepositWithPermitTxData,
  DepositAuthMethod,
  YieldType,
} from "@paxoslabs/amplify-sdk";

// Configuration
const CONFIG = {
  apiKey: process.env.AMPLIFY_API_KEY!,
  depositToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" as `0x${string}`, // USDC
  depositAmount: "1000",
  yieldType: YieldType.PRIME,
};

async function main() {
  // Step 1: Initialize SDK
  console.log("Initializing SDK...");
  await initAmplifySDK(CONFIG.apiKey);

  // Step 2: Connect wallet
  console.log("Connecting wallet...");
  const ethereum = (window as any).ethereum;
  if (!ethereum) {
    throw new Error("No wallet found");
  }

  const [account] = (await ethereum.request({
    method: "eth_requestAccounts",
  })) as `0x${string}`[];

  const walletClient = createWalletClient({
    account,
    chain: mainnet,
    transport: custom(ethereum),
  });

  const publicClient = createPublicClient({
    chain: mainnet,
    transport: http(),
  });

  // Step 3: Prepare deposit parameters
  const params = {
    yieldType: CONFIG.yieldType,
    depositToken: CONFIG.depositToken,
    depositAmount: CONFIG.depositAmount,
    recipientAddress: account,
    chainId: mainnet.id,
  };

  // Step 4: Get authorization method
  console.log("Checking authorization method...");
  const auth = await prepareDepositAuthorization(params);
  console.log(`Authorization method: ${auth.method}`);

  // Step 5: Handle based on method
  switch (auth.method) {
    case DepositAuthMethod.PERMIT: {
      console.log("Signing permit...");
      const signature = await walletClient.signTypedData({
        account,
        domain: auth.permitData.domain,
        types: auth.permitData.types,
        primaryType: auth.permitData.primaryType,
        message: auth.permitData.message,
      });

      console.log("Submitting deposit with permit...");
      const permitTx = await prepareDepositWithPermitTxData({
        ...params,
        signature,
        deadline: BigInt(auth.permitData.message.deadline),
      });

      const permitHash = await walletClient.writeContract({
        address: permitTx.address,
        abi: permitTx.data.abi,
        functionName: permitTx.data.functionName,
        args: permitTx.data.args,
        account,
      });

      console.log(`Deposit submitted: ${permitHash}`);
      await publicClient.waitForTransactionReceipt({ hash: permitHash });
      console.log("Deposit confirmed!");
      break;
    }

    case DepositAuthMethod.APPROVAL: {
      console.log(`Current allowance: ${auth.currentAllowance}`);
      console.log("Sending approval transaction...");

      const approvalHash = await walletClient.writeContract({
        ...auth.txData,
        account,
      });

      console.log(`Approval submitted: ${approvalHash}`);
      await publicClient.waitForTransactionReceipt({ hash: approvalHash });
      console.log("Approval confirmed!");

      console.log("Submitting deposit...");
      const depositTx = await prepareDepositTxData(params);

      const depositHash = await walletClient.writeContract({
        ...depositTx,
        account,
      });

      console.log(`Deposit submitted: ${depositHash}`);
      await publicClient.waitForTransactionReceipt({ hash: depositHash });
      console.log("Deposit confirmed!");
      break;
    }

    case DepositAuthMethod.ALREADY_APPROVED: {
      console.log(`Existing allowance: ${auth.allowance}`);
      console.log("Submitting deposit directly...");

      const directTx = await prepareDepositTxData(params);

      const directHash = await walletClient.writeContract({
        ...directTx,
        account,
      });

      console.log(`Deposit submitted: ${directHash}`);
      await publicClient.waitForTransactionReceipt({ hash: directHash });
      console.log("Deposit confirmed!");
      break;
    }
  }
}

main().catch(console.error);

What This Code Does

  1. Initializes the SDK - Required before any SDK calls
  2. Connects to wallet - Uses injected provider (MetaMask, etc.)
  3. Checks authorization - Determines permit, approval, or already approved
  4. Signs permit if supported - Off-chain signature for gas efficiency
  5. Sends transactions - Approval and/or deposit
  6. Waits for confirmation - Uses waitForTransactionReceipt

Key Features

  • No React required - Pure TypeScript/JavaScript
  • Full transaction lifecycle - From authorization to confirmation
  • Console logging - Clear progress indicators
  • Error handling - Proper async/await with catch

Running the Script

# Set environment variable
export AMPLIFY_API_KEY=pxl_your_api_key

# Run with tsx or ts-node
npx tsx deposit.ts

Expected Output

Initializing SDK...
Connecting wallet...
Checking authorization method...
Authorization method: permit
Signing permit...
Submitting deposit with permit...
Deposit submitted: 0x1234...
Deposit confirmed!

Customization

Custom Slippage

const depositTx = await prepareDepositTxData({
  ...params,
  slippage: 100, // 1% instead of default 0.5%
});

Partner Code

const depositTx = await prepareDepositTxData({
  ...params,
  partnerCode: "your_partner_code",
});

Force Approval Flow

const auth = await prepareDepositAuthorization({
  ...params,
  forceMethod: "approval", // Skip permit detection
});

Troubleshooting

IssueSolution
”No wallet found”Ensure MetaMask or similar is installed
”SDK not initialized”Call initAmplifySDK() first
Transaction revertsCheck token balance and allowance
Permit failsToken may not support EIP-2612
For more details, see Deposits.