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
}