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

# Withdraw

> Withdraw ETH or ERC-20 tokens from Privacy Cash on EVM

## Withdraw

Withdraw ETH or a supported ERC-20 token from your private balance to any EVM recipient address.

```typescript theme={null}
import { withdraw } from 'privacycash-evm'

const txHash = await withdraw({
  withdrawAmountInput: number,
  recipient: string,
  keyBasePath: string,
  signature: string,
  address: string,
  token?: 'eth' | 'usdc' | 'usdt',
  network?: NetworkConfig | number
})
```

### Parameters

| Parameter             | Type                        | Required | Description                                                                  |
| --------------------- | --------------------------- | -------- | ---------------------------------------------------------------------------- |
| `withdrawAmountInput` | `number`                    | Yes      | Total amount in the selected token to withdraw (fees are deducted from this) |
| `recipient`           | `string`                    | Yes      | EVM address to receive the funds                                             |
| `keyBasePath`         | `string`                    | Yes      | Base path to the circuit zkey file (without extension)                       |
| `signature`           | `string`                    | Yes      | Wallet signature of the Privacy Cash sign-in message                         |
| `address`             | `string`                    | Yes      | The withdrawer's EVM wallet address                                          |
| `token`               | `'eth' \| 'usdc' \| 'usdt'` | No       | Token to withdraw. Defaults to `'eth'`                                       |
| `network`             | `NetworkConfig \| number`   | No       | EVM network. Defaults from `NEXT_PUBLIC_CHAIN_ID`, then Base                 |

### Returns

The transaction hash (`string`).

### Example

```typescript theme={null}
import { ethers } from 'ethers'
import { BASE_NETWORK, ETH_NETWORK, withdraw } from 'privacycash-evm'

const network = ETH_NETWORK // or BASE_NETWORK
const SIGN_MESSAGE = 'Privacy Money account sign in'

const provider = new ethers.providers.JsonRpcProvider(network.rpcUrl, {
  name: network.chainKey,
  chainId: network.chainId,
})
const signer = new ethers.Wallet(process.env.PRIVATE_KEY!, provider)

const signature = await signer.signMessage(SIGN_MESSAGE)
const address = await signer.getAddress()

const txHash = await withdraw({
  withdrawAmountInput: 0.05,         // Total amount including fees
  recipient: '0xRECIPIENT_ADDRESS',  // Any EVM address
  keyBasePath: './circuits/transaction',
  signature,
  address,
  token: 'eth',
  network,
})

console.log('Withdraw tx:', txHash)
```

***

## Withdrawal Fees

Fees are deducted from the `withdrawAmountInput`, so the recipient receives less than the requested amount.

| Component    | Amount                     |
| ------------ | -------------------------- |
| Flat fee     | 0.00025 ETH per withdrawal |
| Protocol fee | 0.35% of withdrawal amount |

### Fee Calculation Example

```typescript theme={null}
const withdrawAmount = 0.1 // ETH

// Flat fee: 0.00025 ETH
// Protocol fee: 0.1 × 0.35% = 0.00035 ETH
// Total fee: ~0.00060 ETH
// Recipient receives: ~0.09940 ETH
```

***

## How Withdrawals Work

<Steps>
  <Step title="UTXO Selection">
    The SDK scans on-chain events to find your unspent UTXOs (up to 2) to cover the withdrawal amount.
  </Step>

  <Step title="ZK Proof Generation">
    A zero-knowledge proof is generated proving you own the funds and authorizing the exact recipient and amount.
  </Step>

  <Step title="On-Chain Submission">
    The transaction is submitted directly to the selected EVM smart contract. No relayer is needed for EVM withdrawals.
  </Step>

  <Step title="Funds Received">
    The recipient receives ETH with no on-chain link to your depositing wallet.
  </Step>
</Steps>

### Privacy Guarantee

The withdrawal transaction on-chain contains **no information** about the original depositor. The zero-knowledge proof ensures:

* The recipient address cannot be modified
* The amount cannot be modified
* Any tampering causes the transaction to revert

***

## Insufficient Balance

If your private balance is less than `withdrawAmountInput`, the SDK throws:

```
Insufficient balance. Have X ETH, need Y ETH.
```

Check your balance first with [`getBalance()`](/evmsdk/balance).
