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

# prepareWithdrawalAuthorization

> Determine if vault share approval is needed for withdrawal and prepare the authorization

Determine whether vault share approval is needed for a withdrawal operation and prepare the appropriate authorization.

This is the recommended entry point for the withdrawal flow. It automatically:

* Checks existing vault share allowance
* Detects smart contract wallets (Safe, EIP-4337, EIP-7702)
* Returns the appropriate authorization result

## Import

```typescript theme={null}
import {
  prepareWithdrawalAuthorization,
  isWithdrawApprovalAuth,
  isWithdrawAlreadyApprovedAuth,
  WithdrawAuthMethod,
} from "@paxoslabs/amplify-sdk";
```

## Usage

```typescript theme={null}
const auth = await prepareWithdrawalAuthorization({
  yieldType: "CORE",
  wantAsset: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
  withdrawAmount: "1.0",
  userAddress: "0x1234...",
  chainId: 1,
});

if (isWithdrawApprovalAuth(auth)) {
  // Execute approval transaction
  await walletClient.writeContract(auth.txData);
} else {
  // Already approved, proceed to withdrawal
  console.log(`Allowance: ${auth.allowance}`);
}
```

***

## Parameters

| Parameter        | Type                              | Required | Description                               |
| ---------------- | --------------------------------- | -------- | ----------------------------------------- |
| `yieldType`      | `YieldType`                       | Yes      | Yield strategy (CORE, TREASURY, FRONTIER) |
| `wantAsset`      | `Address`                         | Yes      | Token address to receive upon withdrawal  |
| `withdrawAmount` | `string`                          | Yes      | Vault shares to withdraw (decimal string) |
| `userAddress`    | `Address`                         | Yes      | Owner of vault shares                     |
| `chainId`        | `ChainId`                         | Yes      | Blockchain network ID                     |
| `forceMethod`    | `"approval" \| "allowance_check"` | No       | Override auto routing behavior            |

***

## Return Type

Returns a discriminated union `WithdrawAuthorizationResult`:

### WithdrawAuthMethod.APPROVAL

Returned when approval is needed (insufficient allowance, smart wallet detected in auto mode, or `forceMethod: "approval"`).

```typescript theme={null}
interface WithdrawApprovalAuthorizationResult {
  method: "approval";
  txData: ApproveWithdrawOrderTxData; // Ready-to-use approval tx
}
```

### WithdrawAuthMethod.ALREADY\_APPROVED

Returned when existing allowance is sufficient.

```typescript theme={null}
interface WithdrawAlreadyApprovedAuthorizationResult {
  method: "already_approved";
  allowance: string;
  allowanceAsBigInt: string;
}
```

***

## Type Guards

Use type guards for type-safe handling:

```typescript theme={null}
import {
  isWithdrawApprovalAuth,
  isWithdrawAlreadyApprovedAuth,
} from "@paxoslabs/amplify-sdk";

const auth = await prepareWithdrawalAuthorization({ ... });

if (isWithdrawApprovalAuth(auth)) {
  // TypeScript knows auth.txData exists
  await walletClient.writeContract(auth.txData);
}

if (isWithdrawAlreadyApprovedAuth(auth)) {
  // TypeScript knows auth.allowance exists
  console.log(auth.allowance);
}
```

Or use a switch statement:

```typescript theme={null}
switch (auth.method) {
  case WithdrawAuthMethod.APPROVAL:
    await walletClient.writeContract(auth.txData);
    break;
  case WithdrawAuthMethod.ALREADY_APPROVED:
    console.log(`Approved: ${auth.allowance}`);
    break;
}
```

***

## Smart Wallet Behavior

In auto mode, smart contract wallets (Safe, EIP-4337, EIP-7702) are routed to `APPROVAL` with approve tx data so they can batch approve + withdraw atomically.

```typescript theme={null}
// Smart wallet detected automatically
const auth = await prepareWithdrawalAuthorization({
  yieldType: "CORE",
  wantAsset: USDC_ADDRESS,
  withdrawAmount: "1.0",
  userAddress: safeAddress, // Smart contract wallet
  chainId: 1,
});

// Returns APPROVAL in auto mode for smart wallets
// auth.method === WithdrawAuthMethod.APPROVAL
```

The SDK detects smart wallets by checking for deployed bytecode at the address using `getCode`. This covers:

* **Safe (Gnosis Safe)** multi-sig wallets
* **EIP-4337** smart accounts (e.g., Biconomy, ZeroDev, Alchemy)
* **EIP-7702** delegated EOAs
* **Privy embedded wallets** (when using smart wallets)

***

## Force Method Overrides

Use `forceMethod` for deterministic behavior:

```typescript theme={null}
// Always return approval tx data (skip checks)
const forceApproval = await prepareWithdrawalAuthorization({
  yieldType: "CORE",
  wantAsset: USDC_ADDRESS,
  withdrawAmount: "1.0",
  userAddress,
  chainId: 1,
  forceMethod: "approval",
});

// Always run allowance check (skip smart-wallet heuristic)
const forceAllowanceCheck = await prepareWithdrawalAuthorization({
  yieldType: "CORE",
  wantAsset: USDC_ADDRESS,
  withdrawAmount: "1.0",
  userAddress,
  chainId: 1,
  forceMethod: "allowance_check",
});
```

***

## Examples

<Tabs>
  <Tab title="Complete Viem Flow">
    ```typescript theme={null}
    import {
      prepareWithdrawalAuthorization,
      isWithdrawApprovalAuth,
      prepareWithdrawal,
    } from "@paxoslabs/amplify-sdk";

    async function withdraw(
      walletClient: WalletClient,
      publicClient: PublicClient,
      userAddress: `0x${string}`,
    ) {
      const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
      const withdrawAmount = "1.0";

      // Step 1: Authorize
      const auth = await prepareWithdrawalAuthorization({
        yieldType: "CORE",
        wantAsset: USDC,
        withdrawAmount,
        userAddress,
        chainId: 1,
      });

      if (isWithdrawApprovalAuth(auth)) {
        const approveHash = await walletClient.writeContract(auth.txData);
        await publicClient.waitForTransactionReceipt({ hash: approveHash });
      }

      // Step 2: Submit withdrawal order
      const withdrawTx = await prepareWithdrawal({
        yieldType: "CORE",
        wantAsset: USDC,
        userAddress,
        chainId: 1,
        withdrawAmount,
      });

      const hash = await walletClient.writeContract(withdrawTx);
      return hash;
    }
    ```
  </Tab>

  <Tab title="Smart Wallet Batching">
    ```typescript theme={null}
    import {
      prepareWithdrawalAuthorization,
      isWithdrawApprovalAuth,
      prepareWithdrawal,
    } from "@paxoslabs/amplify-sdk";
    import { encodeFunctionData } from "viem";

    async function batchedWithdraw(safeAddress: `0x${string}`) {
      const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
      const withdrawAmount = "1.0";

      // Get authorization (default: APPROVAL for smart wallets)
      const auth = await prepareWithdrawalAuthorization({
        yieldType: "CORE",
        wantAsset: USDC,
        withdrawAmount,
        userAddress: safeAddress,
        chainId: 1,
      });

      const calls = [];

      // Add approval call
      if (isWithdrawApprovalAuth(auth)) {
        calls.push({
          to: auth.txData.address,
          data: encodeFunctionData({
            abi: auth.txData.abi,
            functionName: auth.txData.functionName,
            args: auth.txData.args,
          }),
          value: 0n,
        });
      }

      // Add withdrawal call
      const withdrawTx = await prepareWithdrawal({
        yieldType: "CORE",
        wantAsset: USDC,
        userAddress: safeAddress,
        chainId: 1,
        withdrawAmount,
      });

      calls.push({
        to: withdrawTx.address,
        data: encodeFunctionData({
          abi: withdrawTx.abi,
          functionName: withdrawTx.functionName,
          args: withdrawTx.args,
        }),
        value: 0n,
      });

      // Execute both atomically via smart wallet
      return calls;
    }
    ```
  </Tab>
</Tabs>

***

## Comparison with Deposit Authorization

`prepareWithdrawalAuthorization()` mirrors the deposit flow's `prepareDepositAuthorization()`:

| Feature                  | Deposit Auth                          | Withdrawal Auth                                |
| ------------------------ | ------------------------------------- | ---------------------------------------------- |
| Methods                  | PERMIT, APPROVAL, ALREADY\_APPROVED   | APPROVAL, ALREADY\_APPROVED                    |
| Permit Support           | Yes (EIP-2612)                        | No                                             |
| Smart Wallet Auto-Detect | Yes                                   | Yes                                            |
| Force Method             | `forceMethod: "permit" \| "approval"` | `forceMethod: "approval" \| "allowance_check"` |

Withdrawals don't support EIP-2612 permits since the approval is on vault shares (BoringVault ERC20), not the deposit token.

***

## Error Handling

| Error                                 | Description                                     | Resolution                                |
| ------------------------------------- | ----------------------------------------------- | ----------------------------------------- |
| `No vault found for asset`            | Invalid yield type, chain, or asset combination | Verify parameters match an existing vault |
| `Failed to check withdrawal approval` | On-chain multicall failed                       | Check RPC connectivity and retry          |

```typescript theme={null}
import { prepareWithdrawalAuthorization, APIError } from "@paxoslabs/amplify-sdk";

try {
  const auth = await prepareWithdrawalAuthorization({
    yieldType: "CORE",
    wantAsset: USDC_ADDRESS,
    withdrawAmount: "1.0",
    userAddress: "0x...",
    chainId: 1,
  });
} catch (error) {
  if (error instanceof APIError) {
    console.error("SDK Error:", error.message);
  }
}
```

***

## Related

* [prepareDepositAuthorization](/v0.4.2/intro/products/earn/developers/api/deposit-workflow) - Deposit authorization (equivalent for deposits)
* [prepareWithdrawal](/v0.4.2/intro/products/earn/developers/api/prepareWithdrawal) - Unified withdrawal wrapper
* [prepareWithdrawOrderTxData](/v0.4.2/intro/products/earn/developers/api/prepareWithdrawOrderTxData) - Low-level withdrawal tx builder
* [prepareApproveWithdrawOrderTxData](/v0.4.2/intro/products/earn/developers/api/prepareApproveWithdrawOrderTxData) - Manual approval
* [Withdrawals Guide](/v0.4.2/intro/products/earn/developers/guides/withdrawals) - Complete withdrawal integration guide
* [Smart Wallets Guide](/v0.4.2/intro/products/earn/developers/guides/smart-wallets) - Smart wallet integration patterns
