> ## Documentation Index
> Fetch the complete documentation index at: https://developers.paxoslabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Deposit Workflow

> Unified deposit API with automatic permit/approval detection

The unified deposit API simplifies deposits by automatically detecting the optimal authorization method. Use `prepareDepositAuthorization()` to determine the method, then `prepareDeposit()` to execute.

<Warning>
  **Breaking change in v0.5.0**: All transaction functions identify accounts by
  `vaultName: string` instead of `yieldType`. Use `getVaultsByConfig()` or
  `findVaultByConfig()` to discover account names first. See the
  [migration guide](/v0.5.2/intro/products/earn/developers/changelog#migration-guide).
</Warning>

## Import

```ts theme={null}
import {
  prepareDepositAuthorization,
  prepareDeposit,
  getVaultsByConfig,
  isPermitAuth,
  isApprovalAuth,
  isAlreadyApprovedAuth,
  YieldType,
} from '@paxoslabs/amplify-sdk'
```

## prepareDepositAuthorization()

Determines the optimal authorization method for a deposit operation.

### Function Signature

```ts theme={null}
async function prepareDepositAuthorization(
  params: PrepareDepositAuthorizationParams
): Promise<DepositAuthorizationResult>
```

### Parameters

```ts theme={null}
interface PrepareDepositAuthorizationParams {
  /** Human-readable vault name (from AmplifyVault.name) */
  vaultName: string

  /** Token contract address to deposit */
  depositAsset: Address

  /** Amount of assets to deposit as decimal string (e.g., "100.25") */
  depositAmount: string

  /** User's wallet address (permit owner / approval sender) */
  to: Address

  /** Blockchain network ID */
  chainId: number

  /** Optional deadline for permit signature (defaults to 1 hour from now) */
  deadline?: bigint

  /** Force specific authorization method (bypasses automatic detection) */
  forceMethod?: 'permit' | 'approval'
}
```

| Parameter       | Type                     | Required | Description                                                             |
| --------------- | ------------------------ | -------- | ----------------------------------------------------------------------- |
| `vaultName`     | `string`                 | Yes      | Account name from `AmplifyVault.name` (e.g. from `getVaultsByConfig()`) |
| `depositAsset`  | `Address`                | Yes      | Token contract address to deposit                                       |
| `depositAmount` | `string`                 | Yes      | Amount as decimal string (e.g., "100.25")                               |
| `to`            | `Address`                | Yes      | Recipient address for account shares                                    |
| `chainId`       | `number`                 | Yes      | Blockchain network ID                                                   |
| `deadline`      | `bigint`                 | No       | Permit deadline (defaults to 1 hour)                                    |
| `forceMethod`   | `"permit" \| "approval"` | No       | Override automatic detection                                            |

### Return Type (Discriminated Union)

<Tabs>
  <Tab title="Type Definition">
    ```ts theme={null}
    type DepositAuthorizationResult =
      | PermitAuthorizationResult
      | ApprovalAuthorizationResult
      | AlreadyApprovedAuthorizationResult;
    ```
  </Tab>

  <Tab title="Permit Result">
    ```ts theme={null}
    /** Returned when token supports EIP-2612 permit */
    interface PermitAuthorizationResult {
      method: "permit";
      /** EIP-712 typed data ready for wallet signing */
      permitData: PermitSignatureData;
    }
    ```
  </Tab>

  <Tab title="Approval Result">
    ```ts theme={null}
    /** Returned when an ERC20 approval transaction is needed */
    interface ApprovalAuthorizationResult {
      method: "approval";
      /** Transaction data for ERC20 approve() call */
      txData: ApproveDepositTokenTxData;
    }
    ```
  </Tab>

  <Tab title="Already Approved Result">
    ```ts theme={null}
    /** Returned when existing allowance is sufficient */
    interface AlreadyApprovedAuthorizationResult {
      method: "already_approved";
      /** Current allowance (human-readable) */
      allowance: string;
      /** Current allowance as BigInt string */
      allowanceAsBigInt: string;
    }
    ```
  </Tab>
</Tabs>

### Decision Logic

The function follows this priority order:

1. **Check `forceMethod`** — If specified, use that method directly
2. **Detect smart wallet** — If the address has deployed bytecode (Safe, EIP-4337, EIP-7702), route to `APPROVAL` so callers can batch approve + deposit atomically
3. **Check permit support** — If the token supports EIP-2612, return permit signature data
4. **Check existing allowance** — If sufficient, return `ALREADY_APPROVED`
5. **Default to approval** — Return approval transaction data

### Token Permit Support

The following table shows which supported tokens use the gas-efficient EIP-2612 permit path versus the standard ERC-20 approval path. The SDK detects this automatically — use `forceMethod: "approval"` to override when needed (e.g., smart contract wallets).

| Token | Authorization Method | Notes                                                                                                                                               |
| ----- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| USDC  | Permit (EIP-2612)    | Single-transaction gasless signature                                                                                                                |
| USDG  | Permit (EIP-2612)    | Single-transaction gasless signature                                                                                                                |
| pyUSD | Permit (EIP-2612)    | Single-transaction gasless signature                                                                                                                |
| USD₮0 | Permit (EIP-2612)    | Single-transaction gasless signature                                                                                                                |
| USDT  | Approval (ERC-20)    | Requires separate approval transaction. Also requires resetting allowance to 0 before setting a new value when a non-zero allowance already exists. |

***

## prepareDeposit()

Prepares transaction data for a deposit, automatically using the correct method based on provided parameters.

### Function Signature

```ts theme={null}
async function prepareDeposit(
  params: PrepareDepositParams
): Promise<PrepareDepositResult>
```

### Parameters

```ts theme={null}
interface PrepareDepositParams {
  /** Human-readable vault name (from AmplifyVault.name) */
  vaultName: string

  /** Token contract address to deposit */
  depositAsset: Address

  /** Amount of assets to deposit as decimal string (e.g., "100.25") */
  depositAmount: string

  /** Recipient address for vault shares */
  to: Address

  /** Blockchain network ID */
  chainId: number

  /** Permit signature (required for permit flow) */
  signature?: Hex

  /** Permit deadline (required for permit flow) */
  deadline?: bigint

  /** Optional slippage in basis points (default: 50 = 0.5%) */
  slippage?: number

  /** Optional distributor code for fee attribution */
  distributorCode?: string

  /** Force deposit method (bypasses automatic routing) */
  forceMethod?: 'permit' | 'approval'
}
```

### Return Type

Returns a discriminated union based on which deposit method is used:

```ts theme={null}
/** Standard deposit (after approval or when already approved) */
interface StandardDepositResult {
  method: 'approval'
  txData: DepositTxData // flat: { abi, address, functionName, args, chainId }
}

/** Permit deposit (with signature) */
interface PermitDepositResult {
  method: 'permit'
  txData: UnencodedDepositWithPermitData // flat: { depositType, abi, address, functionName, args, chainId }
}

type PrepareDepositResult = StandardDepositResult | PermitDepositResult
```

<Info>
  Both result variants have the same flat `txData` shape — `txData.abi`,
  `txData.address`, `txData.functionName`, `txData.args`, `txData.chainId`. You
  can spread `txData` directly into viem's `writeContract` regardless of method.
</Info>

***

## Complete Flow Example

```ts theme={null}
import { mainnet } from 'viem/chains'
import {
  getVaultsByConfig,
  prepareDepositAuthorization,
  prepareDeposit,
  isPermitAuth,
  isApprovalAuth,
  isAlreadyApprovedAuth,
  YieldType,
} from '@paxoslabs/amplify-sdk'

const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' as `0x${string}`

// Step 0: Discover the vault to get its name
const [vault] = await getVaultsByConfig({
  yieldType: YieldType.CORE,
  chainId: mainnet.id,
  depositAssetAddress: USDC,
})

const params = {
  vaultName: vault.name,
  depositAsset: USDC,
  depositAmount: '1000',
  to: userAddress,
  chainId: mainnet.id,
}

// Step 1: Get authorization method
const auth = await prepareDepositAuthorization(params)

// Step 2: Handle based on method using type guards
if (isPermitAuth(auth)) {
  // Sign permit off-chain
  const signature = await walletClient.signTypedData({
    account: userAddress,
    ...auth.permitData,
  })

  // Prepare and execute deposit with permit
  const prepared = await prepareDeposit({
    ...params,
    signature,
    deadline: auth.permitData.message.deadline,
  })

  await walletClient.writeContract({
    ...prepared.txData,
    account: userAddress,
  })
} else if (isApprovalAuth(auth)) {
  // Execute approval first
  const approvalHash = await walletClient.writeContract(auth.txData)
  await publicClient.waitForTransactionReceipt({ hash: approvalHash })

  // Then deposit (standard path: txData is flat)
  const prepared = await prepareDeposit(params)
  await walletClient.writeContract(prepared.txData)
} else if (isAlreadyApprovedAuth(auth)) {
  // Deposit directly (standard path: txData is flat)
  const prepared = await prepareDeposit(params)
  await walletClient.writeContract(prepared.txData)
}
```

## Force Specific Method

Override automatic detection when needed:

```ts theme={null}
// Force permit even if automatic detection would choose approval
const authForcePermit = await prepareDepositAuthorization({
  ...params,
  forceMethod: 'permit',
})

// Force approval even for permit-supporting tokens (useful for smart wallets)
const authForceApproval = await prepareDepositAuthorization({
  ...params,
  forceMethod: 'approval',
})
```

## Slippage Configuration

```ts theme={null}
const prepared = await prepareDeposit({
  ...params,
  slippage: 100, // 1% instead of default 0.5%
})
```

## Error Handling

| Error Message Pattern                    | Description                    | Resolution                                         |
| ---------------------------------------- | ------------------------------ | -------------------------------------------------- |
| `"SDK not initialized"`                  | SDK used before init           | Call `initAmplifySDK()` first                      |
| `"Vault not found"`                      | No account matches `vaultName` | Verify account name via `getVaultsByConfig()`      |
| `"does not support EIP-2612 permit"`     | Token doesn't support permits  | Use approval flow instead                          |
| `"requires both signature and deadline"` | Missing permit params          | Provide signature and deadline for permit deposits |

## Related

* [getVaultsByConfig](/v0.5.2/intro/products/earn/developers/api/getVaultsByConfig) - Discover account names
* [Deposits Guide](/v0.5.2/intro/products/earn/developers/guides/deposits) - Complete integration examples
* [DepositAuthMethod](/v0.5.2/intro/products/earn/developers/types/DepositAuthMethod) - Type definitions
* [prepareDepositTxData](./prepareDepositTxData) - Lower-level deposit function
