Skip to main content
This guide demonstrates complete deposit flows using the unified deposit API, which automatically detects the optimal authorization method (permit vs approval).
The unified deposit API handles three authorization paths automatically:
  • Permit - Gas-efficient off-chain signature (EIP-2612)
  • Approval - Standard ERC-20 approval transaction
  • Already Approved - Direct deposit when allowance exists

Prerequisites

  • Node.js 22+
  • Amplify API key from Paxos Labs
  • SDK initialized with initAmplifySDK()

Installation

pnpm add @paxoslabs/amplify-sdk @privy-io/react-auth viem @tanstack/react-query

Imports

// SDK imports
import {
  prepareDepositAuthorization,
  prepareDeposit,
  isPermitAuth,
  isApprovalAuth,
  isAlreadyApprovedAuth,
  YieldType,
} from "@paxoslabs/amplify-sdk";

// Privy imports
import { usePrivy, useWallets } from "@privy-io/react-auth";

// Viem imports
import { encodeFunctionData } from "viem";
import { mainnet } from "viem/chains";

Complete Examples

useDeposit Hook

// src/hooks/useDeposit.ts
import { ,  } from "react";
import {  } from "viem";
import {  } from "viem/chains";
import {
  ,
  ,
  ,
  ,
  ,
  ,
} from "@paxoslabs/amplify-sdk";

declare const : () => { : (: any) => <string> };
declare const : () => { : <{ : string; : () => <any> }> };

interface DepositParams {
  : string;
  : `0x${string}`;
  : ;
}

export function () {
  const {  } = ();
  const {  } = ();
  const [, ] = <string>("");
  const [, ] = (false);

  const  = (
    async ({ , ,  }: DepositParams) => {
      const  = [0];
      if (!) {
        throw new ("Connect a wallet first");
      }

      (true);
      const  = . as `0x${string}`;

      try {
        const  = {
          ,
          ,
          : ,
          ,
          : .id,
        };

        // Step 1: Get authorization method
        ("Checking authorization...");
        const  = await ();

        // Step 2: Handle based on method using type guards
        if (()) {
          ("Please sign permit in your wallet...");
          const  = await .();
          const  = (await .request({
            : "eth_signTypedData_v4",
            : [
              ,
              .({
                : .permitData.domain,
                : .permitData.types,
                : .permitData.primaryType,
                : .permitData.message,
              }),
            ],
          })) as `0x${string}`;

          ("Submitting deposit...");
          const  = await ({
            ...,
            ,
            : (.permitData.message.deadline),
          });

          await ({
            : .txData.chainId,
            : .txData.address,
            : ({
              : .txData.abi,
              : .txData.functionName,
              : .txData.args,
            }),
          });
        } else if (()) {
          ("Approving token spend...");
          await ({
            : .id,
            : .txData.address,
            : ({
              : .txData.abi,
              : .txData.functionName,
              : .txData.args,
            }),
          });

          ("Submitting deposit...");
          const  = await ();
          await ({
            : .txData.chainId,
            : .txData.address,
            : ({
              : .txData.abi,
              : .txData.functionName,
              : .txData.args,
            }),
          });
        } else if (()) {
          ("Submitting deposit...");
          const  = await ();
          await ({
            : .txData.chainId,
            : .txData.address,
            : ({
              : .txData.abi,
              : .txData.functionName,
              : .txData.args,
            }),
          });
        }

        ("Deposit successful!");
      } catch () {
        (`Error: ${ instanceof  ? . : "Unknown"}`);
        throw ;
      } finally {
        (false);
      }
    },
    [, ]
  );

  return { , ,  };
}

Deposit Component

// src/components/DepositForm.tsx
import { useState } from "react";
import { YieldType } from "@paxoslabs/amplify-sdk";
import { useDeposit } from "../hooks/useDeposit";

const USDC_ADDRESS = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" as const;

export function DepositForm() {
  const [amount, setAmount] = useState("100");
  const { deposit, status, isLoading } = useDeposit();

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    await deposit({
      amount,
      depositAsset: USDC_ADDRESS,
      yieldType: YieldType.CORE,
    });
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Amount (USDC):
        <input
          type="number"
          value={amount}
          onChange={(e) => setAmount(e.target.value)}
          disabled={isLoading}
          min="0"
          step="0.01"
        />
      </label>
      <button type="submit" disabled={isLoading}>
        {isLoading ? "Processing..." : "Deposit"}
      </button>
      {status && <p>{status}</p>}
    </form>
  );
}

What the Code Does

  1. Checks authorization method - Determines if permit, approval, or already approved
  2. Handles permit flow - Signs typed data off-chain for gas-efficient authorization
  3. Handles approval flow - Sends approval transaction then deposit
  4. Handles pre-approved - Deposits directly if allowance exists
  5. Reports status - Updates UI with current operation status

Customization

Custom Slippage

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

Partner Code

const  = await ({
  ...,
  : "your_partner_code",
});

Force Approval Flow

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

Troubleshooting

IssueSolution
”SDK not initialized”Call initAmplifySDK() before using hooks
”Connect a wallet first”Ensure user has connected wallet
Permit signature failsToken may not support EIP-2612, falls back to approval
Transaction revertsCheck token balance and allowance
For more details on the deposit API, see Deposit Workflow.