> ## 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 SOL from Privacy Cash to any wallet

## Withdraw SOL

Withdraw SOL from your private balance to any recipient address.

```typescript theme={null}
const result = await client.withdraw({
  lamports: number,
  recipientAddress?: string,
  referrer?: string
})
```

### Parameters

| Parameter          | Type     | Required | Description                                           |
| ------------------ | -------- | -------- | ----------------------------------------------------- |
| `lamports`         | `number` | Yes      | Amount in lamports to withdraw                        |
| `recipientAddress` | `string` | No       | Recipient wallet address. Defaults to your own wallet |
| `referrer`         | `string` | No       | Optional referrer wallet address                      |

### Returns

```typescript theme={null}
{
  tx: string,              // Transaction signature
  recipient: string,       // Recipient address
  amount_in_lamports: number,  // Amount received (after fees)
  fee_in_lamports: number,     // Fee paid
  isPartial: boolean       // True if balance was insufficient for full amount
}
```

### Example

```typescript theme={null}
import { PrivacyCash } from 'privacycash'

const client = new PrivacyCash({
  RPC_url: process.env.SOLANA_RPC_URL!,
  owner: process.env.PRIVATE_KEY!
})

// Withdraw 0.1 SOL to a clean wallet
const result = await client.withdraw({
  lamports: 0.1 * 1_000_000_000,
  recipientAddress: 'CLEAN_WALLET_ADDRESS'
})

console.log('Transaction:', result.tx)
console.log('Amount received:', result.amount_in_lamports / 1_000_000_000, 'SOL')
console.log('Fee paid:', result.fee_in_lamports / 1_000_000_000, 'SOL')
```

***

## Withdrawal Fees

| Component    | Amount                     |
| ------------ | -------------------------- |
| Base fee     | 0.006 SOL per recipient    |
| Protocol fee | 0.35% of withdrawal amount |

### Fee Calculation Example

```typescript theme={null}
// Withdrawing 1 SOL
const withdrawAmount = 1_000_000_000 // 1 SOL in lamports

// Fee calculation:
// Base: 0.006 SOL = 6,000,000 lamports
// Protocol: 1 SOL × 0.35% = 0.0035 SOL = 3,500,000 lamports
// Total fee: ~9,500,000 lamports (~0.0095 SOL)

const result = await client.withdraw({
  lamports: withdrawAmount,
  recipientAddress: 'RECIPIENT'
})

console.log('Requested:', withdrawAmount / 1e9, 'SOL')
console.log('Received:', result.amount_in_lamports / 1e9, 'SOL')
console.log('Fee:', result.fee_in_lamports / 1e9, 'SOL')
```

***

## How Withdrawals Work

<Steps>
  <Step title="UTXO Selection">
    The SDK selects your largest UTXOs to cover the withdrawal amount
  </Step>

  <Step title="ZK Proof Generation">
    A zero-knowledge proof is generated proving you own the funds
  </Step>

  <Step title="Relayer Submission">
    The proof is sent to the relayer, which signs and submits the transaction
  </Step>

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

### Privacy Guarantee

The withdrawal transaction on-chain (visible on SolScan or other explorers) contains **no information** about the original depositor. The zero-knowledge proof ensures:

* The relayer cannot modify the recipient address
* The relayer cannot modify the amount
* Any tampering causes the transaction to fail

***

## Partial Withdrawals

If your private balance is less than the requested amount, the SDK performs a partial withdrawal:

```typescript theme={null}
// You have 0.05 SOL private balance
// Request to withdraw 0.1 SOL

const result = await client.withdraw({
  lamports: 100_000_000, // 0.1 SOL
  recipientAddress: 'RECIPIENT'
})

if (result.isPartial) {
  console.log('Partial withdrawal - balance was insufficient')
  console.log('Actually withdrew:', result.amount_in_lamports / 1e9, 'SOL')
}
```

***

## Withdraw to Self

If you omit `recipientAddress`, funds are withdrawn to your own wallet:

```typescript theme={null}
// Withdraw to your own wallet (unshield)
const result = await client.withdraw({
  lamports: 50_000_000 // 0.05 SOL
})

console.log('Withdrawn to:', result.recipient) // Your wallet address
```

<Warning>
  Withdrawing to your own wallet reduces privacy since it links your deposit and withdrawal addresses.
</Warning>

***

## Best Practices

<CardGroup cols={2}>
  <Card title="Use Clean Wallets" icon="broom">
    Always withdraw to a fresh, never-used wallet address
  </Card>

  <Card title="Wait Before Withdrawing" icon="clock">
    Wait at least a day between deposit and withdrawal
  </Card>

  <Card title="Split Withdrawals" icon="scissors">
    Split large amounts into multiple smaller withdrawals over time
  </Card>

  <Card title="Vary Amounts" icon="shuffle">
    Don't withdraw the exact same amount you deposited
  </Card>
</CardGroup>

### Example: Privacy-Optimized Withdrawal

```typescript theme={null}
// Deposited 1 SOL yesterday

// Good: Withdraw different amounts over multiple days
await client.withdraw({
  lamports: 400_000_000, // 0.4 SOL
  recipientAddress: 'CLEAN_WALLET_1'
})

// Wait a day...

await client.withdraw({
  lamports: 350_000_000, // 0.35 SOL
  recipientAddress: 'CLEAN_WALLET_2'
})

// Wait another day...

await client.withdraw({
  lamports: 200_000_000, // 0.2 SOL
  recipientAddress: 'CLEAN_WALLET_3'
})
```

***

## Error Handling

```typescript theme={null}
try {
  const result = await client.withdraw({
    lamports: 100_000_000,
    recipientAddress: 'RECIPIENT'
  })
  console.log('Withdrawal successful:', result.tx)
} catch (error) {
  if (error.message.includes('no balance')) {
    console.error('No private balance available')
  } else if (error.message.includes('Need at least 1 unspent UTXO')) {
    console.error('No UTXOs available for withdrawal')
  } else {
    console.error('Withdrawal failed:', error.message)
  }
}
```

### Common Errors

| Error                          | Solution                                 |
| ------------------------------ | ---------------------------------------- |
| `no balance`                   | Deposit funds first                      |
| `Need at least 1 unspent UTXO` | Wait for pending deposits to confirm     |
| `withdraw amount too low`      | Increase withdrawal amount to cover fees |
