For the complete documentation index, see [llms.txt](https://docs.tesseract.fi/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tesseract.fi/dedicated-client-vaults/integration-guide/scenario-a/instant-withdrawals.md).

# Instant Withdrawals

For amounts that fit within the vault's available liquidity, withdrawal is a single transaction. Call `withdraw` (specifying an asset amount) or `redeem` (specifying a share amount) and receive the underlying asset in the same block.

There is no reliable on-chain view for "how much can clear instantly right now" — the vault's standard ERC‑4626 `maxWithdraw` / `maxRedeem` don't reflect the real instant-withdrawal capacity. The correct pattern is to **try the instant call (or simulate it first) and fall back to the scheduled flow if it reverts.**

### Withdraw

```ts
const vaultAbi = [{
  type: 'function', stateMutability: 'nonpayable', name: 'withdraw',
  inputs: [
    {name: 'assets',   type: 'uint256'},
    {name: 'receiver', type: 'address'},
    {name: 'owner',    type: 'address'},
  ],
  outputs: [{name: 'shares', type: 'uint256'}],
}] as const

await walletClient.writeContract({
  address: vault,
  abi: vaultAbi,
  functionName: 'withdraw',
  args: [assets, receiver, owner],
})
```

`receiver` gets the asset; `owner` is the wallet whose shares are burned. For a straightforward own-withdrawal, `receiver === owner === msg.sender`.

### Redeem (by share count)

```ts
await walletClient.writeContract({
  address: vault, abi: vaultAbi, functionName: 'redeem',
  args: [shares, receiver, owner],
})
```

Use `redeem` when you want to burn a specific share count (e.g. "withdraw half of my position"). Use `withdraw` when you want a precise asset amount out.

### Falling back to scheduled

If the requested amount exceeds what the vault can free instantly, the call reverts. Detect this and fall back. Two patterns:

**Simulate first, then send.** Cleaner for production — you learn whether the call will succeed before asking the user to sign:

```ts
try {
  await client.simulateContract({
    address: vault, abi: vaultAbi, functionName: 'withdraw',
    args: [assets, receiver, owner],
    account: owner,
  })
  // Simulation succeeded — send the real transaction
  await walletClient.writeContract({
    address: vault, abi: vaultAbi, functionName: 'withdraw',
    args: [assets, receiver, owner],
  })
} catch (err) {
  // Instant path can't satisfy — request a scheduled withdrawal
  await requestScheduledWithdrawal(shares)
}
```

**Try directly, catch on revert.** Simpler, but costs the user a rejected signature / failed tx:

```ts
try {
  await walletClient.writeContract({
    address: vault, abi: vaultAbi, functionName: 'withdraw',
    args: [assets, receiver, owner],
  })
} catch (err) {
  await requestScheduledWithdrawal(shares)
}
```

***

Continue to [**Scheduled Withdrawals**](/dedicated-client-vaults/integration-guide/scenario-a/scheduled-withdrawals.md) for the larger-amount flow.
