Skip to main content
The deposit authorization system uses discriminated unions to represent the three possible authorization methods. Type guards are provided for TypeScript narrowing.

Import

import {
  DepositAuthMethod,
  isPermitAuth,
  isApprovalAuth,
  isAlreadyApprovedAuth,
  type DepositAuthorizationResult,
  type PermitAuthorizationResult,
  type ApprovalAuthorizationResult,
  type AlreadyApprovedAuthorizationResult,
} from "@paxoslabs/amplify-sdk";

DepositAuthMethod Enum

export const DepositAuthMethod = {
  PERMIT: "permit",           // EIP-2612 off-chain signature (gas efficient)
  APPROVAL: "approval",       // Traditional ERC20 approval (two transactions)
  ALREADY_APPROVED: "already_approved", // Existing allowance sufficient
} as const;

export type DepositAuthMethod =
  (typeof DepositAuthMethod)[keyof typeof DepositAuthMethod];

Result Types

DepositAuthorizationResult (Discriminated Union)

export type DepositAuthorizationResult =
  | PermitAuthorizationResult
  | ApprovalAuthorizationResult
  | AlreadyApprovedAuthorizationResult;

PermitAuthorizationResult

Returned when the token supports EIP-2612 permit signatures.
interface PermitAuthorizationResult {
  method: "permit";
  /** EIP-712 typed data ready for wallet signing */
  permitData: {
    /** User's wallet address (permit signer) */
    account: `0x${string}`;
    domain: {
      name: string;
      version: string;
      chainId: number;
      verifyingContract: `0x${string}`;
    };
    types: {
      Permit: Array<{ name: string; type: string }>;
    };
    primaryType: "Permit";
    message: {
      owner: `0x${string}`;
      spender: `0x${string}`;
      value: bigint;
      nonce: bigint;
      deadline: bigint;
    };
  };
}

ApprovalAuthorizationResult

Returned when an ERC20 approval transaction is needed.
interface ApprovalAuthorizationResult {
  method: "approval";
  /** Transaction data for ERC20 approve() call */
  txData: {
    abi: typeof erc20Abi;
    address: `0x${string}`;
    functionName: "approve";
    args: [`0x${string}`, bigint]; // [spender, amount]
  };
}

AlreadyApprovedAuthorizationResult

Returned when existing allowance is sufficient.
interface AlreadyApprovedAuthorizationResult {
  method: "already_approved";
  /** Current allowance (human-readable) */
  allowance: string;
  /** Current allowance as BigInt string */
  allowanceAsBigInt: string;
}

Type Guards

Use type guards for TypeScript narrowing:
import {
  prepareDepositAuthorization,
  isPermitAuth,
  isApprovalAuth,
  isAlreadyApprovedAuth,
} from "@paxoslabs/amplify-sdk";

const auth = await prepareDepositAuthorization(params);

if (isPermitAuth(auth)) {
  // TypeScript knows: auth.method === "permit"
  // auth.permitData is fully typed
  const { domain, types, message } = auth.permitData;

  const signature = await walletClient.signTypedData({
    account,
    domain,
    types,
    primaryType: "Permit",
    message,
  });
}

if (isApprovalAuth(auth)) {
  // TypeScript knows: auth.method === "approval"
  // auth.txData is available with abi, address, functionName, args
  await walletClient.writeContract(auth.txData);
}

if (isAlreadyApprovedAuth(auth)) {
  // TypeScript knows: auth.method === "already_approved"
  // auth.allowance is available
  console.log(`Existing allowance: ${auth.allowance}`);
}

Using Switch Statements

You can also use switch statements with the method discriminant:
const auth = await prepareDepositAuthorization(params);

switch (auth.method) {
  case "permit":
    // auth is narrowed to PermitAuthorizationResult
    const signature = await signTypedData(auth.permitData);
    break;

  case "approval":
    // auth is narrowed to ApprovalAuthorizationResult
    await writeContract(auth.txData);
    break;

  case "already_approved":
    // auth is narrowed to AlreadyApprovedAuthorizationResult
    console.log(`Allowance: ${auth.allowance}`);
    break;
}