Instant Withdrawals | Tesseract Documentation
For the complete documentation index, see llms.txt. This page is also available as Markdown.
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
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)
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:
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:
try {
await walletClient.writeContract({
address: vault, abi: vaultAbi, functionName: 'withdraw',
args: [assets, receiver, owner],
})
} catch (err) {
await requestScheduledWithdrawal(shares)
}
Continue to Scheduled Withdrawals for the larger-amount flow.