> ## 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.

## Import

```ts theme={null}
import {
  prepareDepositAuthorization,
  prepareDeposit,
  isPermitAuth,
  isApprovalAuth,
  isAlreadyApprovedAuth,
} 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 {
  /** Yield strategy type (e.g., YieldType.CORE) */
  yieldType: YieldType;

  /** 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: ChainId;

  /** 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                                  |
| --------------- | ------------------------ | -------- | -------------------------------------------- |
| `yieldType`     | `YieldType`              | Yes      | Yield strategy type (e.g., `YieldType.CORE`) |
| `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 vault 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 {
  /** Yield strategy type (e.g., YieldType.CORE) */
  yieldType: YieldType;

  /** 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: ChainId;

  /** 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; // nested: { address, chainId, data: { abi, functionName, args } }
}

type PrepareDepositResult = StandardDepositResult | PermitDepositResult;
```

<Warning>
  The two result variants have different `txData` shapes. Standard deposits use a flat structure (`txData.abi`), while permit deposits use a nested structure (`txData.data.abi`). Use `result.method` to determine which shape you're working with.
</Warning>

***

## Complete Flow Example

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

const params = {
  yieldType: YieldType.CORE,
  depositAsset: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" as `0x${string}`, // 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,
  });

  // Permit path: txData has nested .data structure
  await walletClient.writeContract({
    address: prepared.txData.address,
    abi: prepared.txData.data.abi,
    functionName: prepared.txData.data.functionName,
    args: prepared.txData.data.args,
    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                      |
| `"No vault found for token..."`          | No vault matches params       | Verify yieldType, token, chainId                   |
| `"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

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