# Aave Simple Earn Vault Operations

Execute core vault operations such as deposits and withdrawals. Users can choose to interact with the vault using either the asset amount deposited or the vault shares minted.

Shares start at a 1:1 ratio when the vault launches. As the vault earns interest, each share is worth more of the underlying asset, so a deposit mints fewer shares than the assets it adds.

## Identify the Vault

[Fetch the vault](/vaults/simple-earn/data#fetching-a-single-vault) with the user address to populate `userShares`. This page uses the following vault in its examples:

```ts title="Vault"
const vault: Vault = {
  __typename: "Vault",
  address: "0x1234567890abcdef1234567890abcdef12345678",
  shareName: "Aave USDC Vault Shares",
  shareSymbol: "avUSDC",
  chainId: 1,
  usedReserve: {
    __typename: "Reserve",
    underlyingToken: {
      __typename: "Currency",
      symbol: "USDC",
      name: "USD Coin",
      address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
      // …
    },
    isFrozen: false,
    isPaused: false,
    // …
  },
  userShares: {
    __typename: "UserVaultShares",
    shares: {
      __typename: "TokenAmount",
      amount: {
        __typename: "DecimalValue",
        value: "1000.0", // User has 1000 vault shares
        // …
      },
      // …
    },
    // …
  },
  // …
};
```

> [!NOTE]
> Deposits and mints need the reserve not frozen and not paused. Withdrawals and
> redeems need it not paused.

## Deposit Assets

Depositing assets into an Aave Simple Earn Vault gives the user an amount of vault shares.

To deposit assets into an Aave Simple Earn Vault, follow these steps.

### 1. Preview the Deposit

First, preview the deposit operation to determine the amount of vault shares that would be received for a given amount of assets. Use the `useVaultDepositPreview` hook in React, the `vaultPreviewDeposit` action in TypeScript, or the `vaultPreviewDeposit` query in GraphQL to preview the deposit operation.

<tabgroup>
<tab label="React">

```tsx title="Preview the Deposit"
import { bigDecimal, useVaultDepositPreview } from "@aave/react";

// …

const [preview /* , { loading, error } */] = useVaultDepositPreview();

// …

const result = await preview({
  vault: vault.address,
  chainId: vault.chainId,
  amount: bigDecimal(1000), // 1000 USDC
});

// …

if (result.isErr()) {
  console.error(result.error);
} else {
  // result.value: TokenAmount
  console.log(result.value.amount.value); // 975.13408 (shares to receive)
}
```

</tab>
<tab label="TypeScript">

```ts title="Preview the Deposit"
import { bigDecimal } from "@aave/client";
import { vaultPreviewDeposit } from "@aave/client/actions";

import { client } from "./client";

const result = await vaultPreviewDeposit(client, {
  vault: vault.address,
  chainId: vault.chainId,
  amount: bigDecimal(1000), // 1000 USDC
});

if (result.isErr()) {
  console.error(result.error);
} else {
  // result.value: TokenAmount
  console.log(result.value.amount.value); // 975.13408 (shares to receive)
}
```

</tab>
<tab label="GraphQL">

```graphql title="Query"
query {
  vaultPreviewDeposit(
    request: {
      vault: "0x1234567890abcdef1234567890abcdef12345678"
      chainId: 1
      amount: "1000"
    }
  ) {
    usdPerToken
    amount {
      raw
      decimals
      value
    }
    usd
  }
}
```

```json title="Response"
{
  "data": {
    "vaultPreviewDeposit": {
      "usdPerToken": "1.0255",
      "amount": {
        "raw": "975134080",
        "decimals": 6,
        "value": "975.13408"
      },
      "usd": "1000"
    }
  }
}
```

</tab>
</tabgroup>
### 2. Prepare the Deposit Execution Plan

Next, create the execution plan for the deposit operation. Use the `useVaultDeposit` hook in React, the `vaultDeposit` action in TypeScript, or the `vaultDeposit` query in GraphQL to create the execution plan for depositing assets into a vault.

> [!NOTE]
> Deposits the underlying asset by default. Set `asAToken` to `true` to deposit
> the aToken instead.

<tabgroup>
<tab label="React">

```tsx title="Deposit Assets"
import { useWalletClient } from "wagmi";
import { useVaultDeposit, bigDecimal, evmAddress } from "@aave/react";

// …

const { data: walletClient } = useWalletClient();

const [deposit, depositing] = useVaultDeposit();

const execute = async () => {
  const result = await deposit({
    chainId: vault.chainId,
    vault: vault.address,
    amount: {
      value: bigDecimal(1000), // 1000 USDC
      // Optional: If set to true, the aToken associated with the vault will be deposited
      // asAToken: false (default)
    },
    depositor: evmAddress(walletClient!.account.address),
  });

  // …
};
```

</tab>
<tab label="TypeScript">

```ts title="Deposit Assets"
import { bigDecimal, evmAddress } from "@aave/client";
import { vaultDeposit } from "@aave/client/actions";

import { client } from "./client";
import { wallet } from "./wallet";

const result = await vaultDeposit(client, {
  chainId: vault.chainId,
  vault: vault.address,
  amount: {
    value: bigDecimal(1000), // 1000 USDC
    // Optional: If set to true, the aToken associated with the vault will be deposited
    // asAToken: false (default)
  },
  depositor: evmAddress(wallet.account.address),
});

// …
```

```ts title="client.ts"
import { AaveClient } from "@aave/client";

export const client = AaveClient.create();
```

```ts title="wallet.ts"
import { createWalletClient, http, type Hex } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { mainnet } from "viem/chains";

export const wallet = createWalletClient({
  account: privateKeyToAccount(process.env.PRIVATE_KEY as Hex),
  chain: mainnet,
  transport: http(),
});
```

</tab>
<tab label="GraphQL">

```graphql title="Query"
query {
  vaultDeposit(
    request: {
      chainId: 1
      vault: "0x1234567890abcdef1234567890abcdef12345678"
      amount: {
        value: "1000"
        # Optional: If set to true, the aToken associated with the vault will be deposited
        # asAToken: false (default)
      }
      depositor: "0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234"
    }
  ) {
    __typename
    ... on TransactionRequest {
      to
      from
      data
      value
      chainId
      operation
    }
    ... on ApprovalRequired {
      reason
      requiredAmount {
        value
        decimals
      }
      currentAllowance {
        value
        decimals
      }
      approval {
        to
        from
        data
        value
        chainId
        operation
      }
      originalTransaction {
        to
        from
        data
        value
        chainId
        operation
      }
    }
    ... on InsufficientBalanceError {
      required {
        value
        decimals
      }
      available {
        value
        decimals
      }
    }
  }
}
```

</tab>
</tabgroup>
### 3. Process the Deposit Execution Plan

Finally, handle the execution plan.

- **React**: Use the `useSendTransaction` hook for the [wallet library of your choice](/aave-v3/getting-started/react#send-aave-transactions) to send the transactions in the execution plan.
- **TypeScript**: Use `sendWith` for your [chosen wallet library](/aave-v3/getting-started/typescript#send-aave-transactions) to send the transactions in the execution plan, and await indexing with `client.waitForTransaction`.

<tabgroup>
<tab label="React">

```tsx title="Viem"
import { useWalletClient } from "wagmi";
import { errAsync, useVaultDeposit } from "@aave/react";
import { useSendTransaction } from "@aave/react/viem";

// …

const { data: walletClient } = useWalletClient();

const [deposit, depositing] = useVaultDeposit();
const [sendTransaction, sending] = useSendTransaction(walletClient);

// …

const loading = depositing.loading || sending.loading;
const error = depositing.error || sending.error;

// …

const execute = async () => {
  const result = await deposit({
    // …
  }).andThen((plan) => {
    switch (plan.__typename) {
      case "TransactionRequest":
        // Single transaction execution
        return sendTransaction(plan);

      case "ApprovalRequired":
        // Approval + transaction sequence
        return sendTransaction(plan.approval).andThen(() =>
          sendTransaction(plan.originalTransaction)
        );

      case "InsufficientBalanceError":
        return errAsync(
          new Error(`Insufficient balance: ${plan.required.value} required.`)
        );
    }
  });

  if (result.isErr()) {
    console.error("Deposit failed:", result.error);
  } else {
    console.log("Deposit successful with hash:", result.value);
  }
};
```

</tab>
<tab label="TypeScript">

```ts title="Viem"
import { vaultDeposit } from "@aave/client/actions";
import { sendWith } from "@aave/client/viem";

import { client } from "./client";
import { wallet } from "./wallet";

const result = await vaultDeposit(client, {
  // …
})
  .andThen(sendWith(wallet))
  .andThen(client.waitForTransaction);

if (result.isErr()) {
  console.error("Deposit failed:", result.error);
} else {
  console.log("Deposit successful:", result.value);
}
```

</tab>
</tabgroup>
In GraphQL, if the response is a `TransactionRequest`, you can send it directly using the wallet associated with the `from` address.

<tabgroup>
<tab label="GraphQL">

```json title="TransactionRequest"
{
  "data": {
    "vaultDeposit": {
      "to": "0x1234567890abcdef1234567890abcdef12345678",
      "from": "0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234",
      "data": "0x6e553f65000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234",
      "value": "0",
      "chainId": 1,
      "operation": "VAULT_DEPOSIT"
    }
  }
}
```

</tab>
</tabgroup>
If the response is an `ApprovalRequired`, you must first send the `approval` transaction. Once it succeeds, you can then send the `originalTransaction`.

<tabgroup>
<tab label="GraphQL">

```json title="ApprovalRequired"
{
  "data": {
    "vaultDeposit": {
      "__typename": "ApprovalRequired",
      "reason": "Insufficient allowance for ERC-20 token transfer",
      "requiredAmount": {
        "value": "1000.0",
        "decimals": 6
      },
      "currentAllowance": {
        "value": "0.0",
        "decimals": 6
      },
      "approval": {
        "to": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
        "from": "0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234",
        "data": "0x095ea7b3000000000000000000000000123456789…",
        "value": "0",
        "chainId": 1,
        "operation": null
      },
      "originalTransaction": {
        "to": "0x1234567890abcdef1234567890abcdef12345678",
        "from": "0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234",
        "data": "0x6e553f65000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234",
        "value": "0",
        "chainId": 1,
        "operation": "VAULT_DEPOSIT"
      }
    }
  }
}
```

</tab>
</tabgroup>
If the response is an `InsufficientBalanceError`, inform the user that they don’t have enough balance to deposit the requested amount.

<tabgroup>
<tab label="GraphQL">

```json title="InsufficientBalanceError"
{
  "data": {
    "vaultDeposit": {
      "__typename": "InsufficientBalanceError",
      "required": {
        "value": "1000.0",
        "decimals": 6
      },
      "available": {
        "value": "750.0",
        "decimals": 6
      }
    }
  }
}
```

</tab>
</tabgroup>
## Mint Vault Shares

Minting vault shares is the process of creating new vault shares by depositing assets into the vault.

To mint vault shares, follow these steps.

### 1. Preview the Mint

First, preview the mint operation to determine the amount of assets needed to mint the requested amount of vault shares. Use the `useVaultMintPreview` hook in React, the `vaultPreviewMint` action in TypeScript, or the `vaultPreviewMint` query in GraphQL to preview the mint operation.

<tabgroup>
<tab label="React">

```tsx title="Preview the Mint"
import { bigDecimal, useVaultMintPreview } from "@aave/react";

// …

const [preview /* , { loading, error } */] = useVaultMintPreview();

// …

const result = await preview({
  vault: vault.address,
  chainId: vault.chainId,
  amount: bigDecimal(1000), // 1000 vault shares
});

// …

if (result.isErr()) {
  console.error(result.error);
} else {
  // result.value: TokenAmount
  console.log(result.value.amount.value); // 1025.5 (assets needed)
}
```

</tab>
<tab label="TypeScript">

```ts title="Preview the Mint"
import { bigDecimal } from "@aave/client";
import { vaultPreviewMint } from "@aave/client/actions";

import { client } from "./client";

const result = await vaultPreviewMint(client, {
  vault: vault.address,
  chainId: vault.chainId,
  amount: bigDecimal(1000), // 1000 vault shares
});

if (result.isErr()) {
  console.error(result.error);
} else {
  // result.value: TokenAmount
  console.log(result.value.amount.value); // 1025.5 (assets needed)
}
```

</tab>
<tab label="GraphQL">

```graphql title="Query"
query {
  vaultPreviewMint(
    request: {
      vault: "0x1234567890abcdef1234567890abcdef12345678"
      chainId: 1
      amount: "1000"
    }
  ) {
    usdPerToken
    amount {
      raw
      decimals
      value
    }
    usd
  }
}
```

```json title="Response"
{
  "data": {
    "vaultPreviewMint": {
      "usdPerToken": "1.0",
      "amount": {
        "raw": "1025500000",
        "decimals": 6,
        "value": "1025.5"
      },
      "usd": "1025.5"
    }
  }
}
```

</tab>
</tabgroup>
### 2. Prepare the Mint Execution Plan

Next, create the execution plan for the mint shares operation. Use the `useVaultMintShares` hook in React, the `vaultMintShares` action in TypeScript, or the `vaultMintShares` query in GraphQL to create the execution plan for minting vault shares.

<tabgroup>
<tab label="React">

```tsx title="Mint Shares"
import { useWalletClient } from "wagmi";
import { useVaultMintShares, bigDecimal, evmAddress } from "@aave/react";

// …

const { data: walletClient } = useWalletClient();

const [mintShares, minting] = useVaultMintShares();

const execute = async () => {
  const result = await mintShares({
    chainId: vault.chainId,
    vault: vault.address,
    shares: {
      amount: bigDecimal(1000), // 1000 vault shares
    },
    minter: evmAddress(walletClient!.account.address),
    // sharesRecipient: evmAddress("0x1234…"), if different from minter
  });

  // …
};
```

</tab>
<tab label="TypeScript">

```ts title="Mint Shares"
import { bigDecimal, evmAddress } from "@aave/client";
import { vaultMintShares } from "@aave/client/actions";

import { client } from "./client";
import { wallet } from "./wallet";

const result = await vaultMintShares(client, {
  chainId: vault.chainId,
  vault: vault.address,
  shares: {
    amount: bigDecimal(1000), // 1000 vault shares
  },
  minter: evmAddress(wallet.account.address),
  // sharesRecipient: evmAddress("0x1234…"), if different from minter
});

// …
```

```ts title="client.ts"
import { AaveClient } from "@aave/client";

export const client = AaveClient.create();
```

```ts title="wallet.ts"
import { createWalletClient, http, type Hex } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { mainnet } from "viem/chains";

export const wallet = createWalletClient({
  account: privateKeyToAccount(process.env.PRIVATE_KEY as Hex),
  chain: mainnet,
  transport: http(),
});
```

</tab>
<tab label="GraphQL">

```graphql title="Query"
query {
  vaultMintShares(
    request: {
      chainId: 1
      vault: "0x1234567890abcdef1234567890abcdef12345678"
      shares: { amount: "1000" }
      minter: "0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234"
      # sharesRecipient: "0x1234…", if different from minter
    }
  ) {
    __typename
    ... on TransactionRequest {
      to
      from
      data
      value
      chainId
      operation
    }
    ... on ApprovalRequired {
      reason
      requiredAmount {
        value
        decimals
      }
      currentAllowance {
        value
        decimals
      }
      approval {
        to
        from
        data
        value
        chainId
        operation
      }
      originalTransaction {
        to
        from
        data
        value
        chainId
        operation
      }
    }
    ... on InsufficientBalanceError {
      required {
        value
        decimals
      }
      available {
        value
        decimals
      }
    }
  }
}
```

</tab>
</tabgroup>
### 3. Process the Mint Execution Plan

Finally, handle the execution plan.

- **React**: Use the `useSendTransaction` hook for the [wallet library of your choice](/aave-v3/getting-started/react#send-aave-transactions) to send the transactions in the execution plan.
- **TypeScript**: Use `sendWith` for your [chosen wallet library](/aave-v3/getting-started/typescript#send-aave-transactions) to send the transactions in the execution plan, and await indexing with `client.waitForTransaction`.

<tabgroup>
<tab label="React">

```tsx title="Viem"
import { useWalletClient } from "wagmi";
import { errAsync, useVaultMintShares } from "@aave/react";
import { useSendTransaction } from "@aave/react/viem";

// …

const { data: walletClient } = useWalletClient();

const [mintShares, minting] = useVaultMintShares();
const [sendTransaction, sending] = useSendTransaction(walletClient);

// …

const loading = minting.loading || sending.loading;
const error = minting.error || sending.error;

// …

const execute = async () => {
  const result = await mintShares({
    // …
  }).andThen((plan) => {
    switch (plan.__typename) {
      case "TransactionRequest":
        // Single transaction execution
        return sendTransaction(plan);

      case "ApprovalRequired":
        // Approval + transaction sequence
        return sendTransaction(plan.approval).andThen(() =>
          sendTransaction(plan.originalTransaction)
        );

      case "InsufficientBalanceError":
        return errAsync(
          new Error(`Insufficient balance: ${plan.required.value} required.`)
        );
    }
  });

  if (result.isErr()) {
    console.error("Mint shares failed:", result.error);
  } else {
    console.log("Mint shares successful with hash:", result.value);
  }
};
```

</tab>
<tab label="TypeScript">

```ts title="Viem"
import { vaultMintShares } from "@aave/client/actions";
import { sendWith } from "@aave/client/viem";

import { client } from "./client";
import { wallet } from "./wallet";

const result = await vaultMintShares(client, {
  // …
})
  .andThen(sendWith(wallet))
  .andThen(client.waitForTransaction);

if (result.isErr()) {
  console.error("Mint shares failed:", result.error);
} else {
  console.log("Mint shares successful:", result.value);
}
```

</tab>
</tabgroup>
In GraphQL, if the response is a `TransactionRequest`, you can send it directly using the wallet associated with the `from` address.

<tabgroup>
<tab label="GraphQL">

```json title="TransactionRequest"
{
  "data": {
    "vaultMintShares": {
      "to": "0x1234567890abcdef1234567890abcdef12345678",
      "from": "0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234",
      "data": "0x94bf804d000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234",
      "value": "0",
      "chainId": 1,
      "operation": "VAULT_DEPOSIT"
    }
  }
}
```

</tab>
</tabgroup>
If the response is an `ApprovalRequired`, you must first send the `approval` transaction. Once it succeeds, you can then send the `originalTransaction`.

<tabgroup>
<tab label="GraphQL">

```json title="ApprovalRequired"
{
  "data": {
    "vaultMintShares": {
      "__typename": "ApprovalRequired",
      "reason": "Insufficient allowance for ERC-20 token transfer",
      "requiredAmount": {
        "value": "1025.5",
        "decimals": 6
      },
      "currentAllowance": {
        "value": "0.0",
        "decimals": 6
      },
      "approval": {
        "to": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
        "from": "0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234",
        "data": "0x095ea7b3000000000000000000000000123456789…",
        "value": "0",
        "chainId": 1,
        "operation": null
      },
      "originalTransaction": {
        "to": "0x1234567890abcdef1234567890abcdef12345678",
        "from": "0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234",
        "data": "0x94bf804d000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234",
        "value": "0",
        "chainId": 1,
        "operation": "VAULT_DEPOSIT"
      }
    }
  }
}
```

</tab>
</tabgroup>
If the response is an `InsufficientBalanceError`, inform the user that they don’t have enough balance to mint the requested amount of shares.

<tabgroup>
<tab label="GraphQL">

```json title="InsufficientBalanceError"
{
  "data": {
    "vaultMintShares": {
      "__typename": "InsufficientBalanceError",
      "required": {
        "value": "1025.5",
        "decimals": 6
      },
      "available": {
        "value": "750.0",
        "decimals": 6
      }
    }
  }
}
```

</tab>
</tabgroup>
## Withdraw Assets

Withdrawing assets from an Aave Simple Earn Vault gives the user an amount of assets. The corresponding amount of vault shares is burned.

To withdraw assets from an Aave Simple Earn Vault, follow these steps.

### 1. Preview the Withdraw

First, preview the withdraw operation to determine the amount of shares that will be burned for a given amount of assets. Use the `useVaultWithdrawPreview` hook in React, the `vaultPreviewWithdraw` action in TypeScript, or the `vaultPreviewWithdraw` query in GraphQL to preview the withdraw operation.

<tabgroup>
<tab label="React">

```tsx title="Preview the Withdraw"
import { bigDecimal, useVaultWithdrawPreview } from "@aave/react";

// …

const [preview /* , { loading, error } */] = useVaultWithdrawPreview();

// …

const result = await preview({
  vault: vault.address,
  chainId: vault.chainId,
  amount: bigDecimal(1000), // 1000 USDC
});

// …

if (result.isErr()) {
  console.error(result.error);
} else {
  // result.value: TokenAmount
  console.log(result.value.amount.value); // 975.134081 (shares to burn)
}
```

</tab>
<tab label="TypeScript">

```ts title="Preview the Withdraw"
import { bigDecimal } from "@aave/client";
import { vaultPreviewWithdraw } from "@aave/client/actions";

import { client } from "./client";

const result = await vaultPreviewWithdraw(client, {
  vault: vault.address,
  chainId: vault.chainId,
  amount: bigDecimal(1000), // 1000 USDC
});

if (result.isErr()) {
  console.error(result.error);
} else {
  // result.value: TokenAmount
  console.log(result.value.amount.value); // 975.134081 (shares to burn)
}
```

</tab>
<tab label="GraphQL">

```graphql title="Query"
query {
  vaultPreviewWithdraw(
    request: {
      vault: "0x1234567890abcdef1234567890abcdef12345678"
      chainId: 1
      amount: "1000"
    }
  ) {
    usdPerToken
    amount {
      raw
      decimals
      value
    }
    usd
  }
}
```

```json title="Response"
{
  "data": {
    "vaultPreviewWithdraw": {
      "usdPerToken": "1.0255",
      "amount": {
        "raw": "975134081",
        "decimals": 6,
        "value": "975.134081"
      },
      "usd": "1000"
    }
  }
}
```

</tab>
</tabgroup>
### 2. Prepare the Withdraw Transaction

Next, create the transaction request for the withdrawal operation. Use the `useVaultWithdraw` hook in React, the `vaultWithdraw` action in TypeScript, or the `vaultWithdraw` query in GraphQL to create the transaction request for withdrawing assets from a vault.

> [!NOTE]
> Withdraws the underlying asset by default. Set `asAToken` to `true` to
> withdraw the aToken instead.

<tabgroup>
<tab label="React">

```tsx title="Withdraw Assets"
import { useWalletClient } from "wagmi";
import { useVaultWithdraw, bigDecimal, evmAddress } from "@aave/react";

// …

const { data: walletClient } = useWalletClient();

const [withdraw, withdrawing] = useVaultWithdraw();

const execute = async () => {
  const result = await withdraw({
    chainId: vault.chainId,
    vault: vault.address,
    amount: {
      value: bigDecimal(500), // 500 USDC
      // Optional: If set to true, the aToken associated with the vault will be withdrawn
      // asAToken: false (default)
    },
    sharesOwner: evmAddress(walletClient!.account.address),
    // recipient: evmAddress("0x1234…"), if different from sharesOwner
  });

  // …
};
```

</tab>
<tab label="TypeScript">

```ts title="Withdraw Assets"
import { bigDecimal, evmAddress } from "@aave/client";
import { vaultWithdraw } from "@aave/client/actions";

import { client } from "./client";
import { wallet } from "./wallet";

const result = await vaultWithdraw(client, {
  chainId: vault.chainId,
  vault: vault.address,
  amount: {
    value: bigDecimal(500), // 500 USDC
    // Optional: If set to true, the aToken associated with the vault will be withdrawn
    // asAToken: false (default)
  },
  sharesOwner: evmAddress(wallet.account.address),
  // recipient: evmAddress("0x1234…"), if different from sharesOwner
});

// …
```

</tab>
<tab label="GraphQL">

```graphql title="Query"
query {
  vaultWithdraw(
    request: {
      chainId: 1
      vault: "0x1234567890abcdef1234567890abcdef12345678"
      amount: {
        value: "500"
        # Optional: If set to true, the aToken associated with the vault will be withdrawn
        # asAToken: false (default)
      }
      sharesOwner: "0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234"
      # recipient: "0x1234…", if different from sharesOwner
    }
  ) {
    to
    from
    data
    value
    chainId
  }
}
```

</tab>
</tabgroup>
### 3. Send the Withdraw Transaction

Finally, send the transaction.

- **React**: Use the `useSendTransaction` hook for the [wallet library of your choice](/aave-v3/getting-started/react#send-aave-transactions) to send the transaction.
- **TypeScript**: Use `sendWith` for your [chosen wallet library](/aave-v3/getting-started/typescript#send-aave-transactions) to initiate the transaction, and await indexing with `client.waitForTransaction`.
- **GraphQL**: The response is a `TransactionRequest` that can be sent directly using the wallet associated with the `from` address.

<tabgroup>
<tab label="React">

```tsx title="Viem"
import { useWalletClient } from "wagmi";
import { useVaultWithdraw } from "@aave/react";
import { useSendTransaction } from "@aave/react/viem";

// …

const { data: walletClient } = useWalletClient();

const [withdraw, withdrawing] = useVaultWithdraw();
const [sendTransaction, sending] = useSendTransaction(walletClient);

const loading = withdrawing.loading || sending.loading;
const error = withdrawing.error || sending.error;

// …

const execute = async () => {
  const result = await withdraw({
    // …
  }).andThen(sendTransaction);

  if (result.isErr()) {
    console.error("Withdrawal failed:", result.error);
  } else {
    console.log("Withdrawal successful with hash:", result.value);
  }
};
```

</tab>
<tab label="TypeScript">

```ts title="Viem"
import { vaultWithdraw } from "@aave/client/actions";
import { sendWith } from "@aave/client/viem";

import { client } from "./client";
import { wallet } from "./wallet";

const result = await vaultWithdraw(client, {
  // …
})
  .andThen(sendWith(wallet))
  .andThen(client.waitForTransaction);

if (result.isErr()) {
  console.error("Withdrawal failed:", result.error);
} else {
  console.log("Withdrawal successful:", result.value);
}
```

</tab>
<tab label="GraphQL">

```json title="TransactionRequest"
{
  "data": {
    "vaultWithdraw": {
      "to": "0x1234567890abcdef1234567890abcdef12345678",
      "from": "0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234",
      "data": "0xb460af94000000000000000000000000000000000000000000000000000000001dcd6500000000000000000000000000742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234000000000000000000000000742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234",
      "value": "0",
      "chainId": 1,
      "operation": "VAULT_WITHDRAW"
    }
  }
}
```

</tab>
</tabgroup>
## Redeem Vault Shares

Redeeming vault shares is the process of burning vault shares and receiving the underlying assets.

To redeem vault shares, follow these steps.

### 1. Preview the Redeem

First, preview the redeem operation to determine the amount of assets that will be received for a given amount of shares burned. Use the `useVaultRedeemPreview` hook in React, the `vaultPreviewRedeem` action in TypeScript, or the `vaultPreviewRedeem` query in GraphQL to preview the redeem operation.

<tabgroup>
<tab label="React">

```tsx title="Preview the Redeem"
import { bigDecimal, useVaultRedeemPreview } from "@aave/react";

// …

const [preview /* , { loading, error } */] = useVaultRedeemPreview();

// …

const result = await preview({
  vault: vault.address,
  chainId: vault.chainId,
  amount: bigDecimal(1000), // 1000 vault shares
});

// …

if (result.isErr()) {
  console.error(result.error);
} else {
  // result.value: TokenAmount
  console.log(result.value.amount.value); // 1025.5 (assets to receive)
}
```

</tab>
<tab label="TypeScript">

```ts title="Preview the Redeem"
import { bigDecimal } from "@aave/client";
import { vaultPreviewRedeem } from "@aave/client/actions";

import { client } from "./client";

const result = await vaultPreviewRedeem(client, {
  vault: vault.address,
  chainId: vault.chainId,
  amount: bigDecimal(1000), // 1000 vault shares
});

if (result.isErr()) {
  console.error(result.error);
} else {
  // result.value: TokenAmount
  console.log(result.value.amount.value); // 1025.5 (assets to receive)
}
```

</tab>
<tab label="GraphQL">

```graphql title="Query"
query {
  vaultPreviewRedeem(
    request: {
      vault: "0x1234567890abcdef1234567890abcdef12345678"
      chainId: 1
      amount: "1000"
    }
  ) {
    usdPerToken
    amount {
      raw
      decimals
      value
    }
    usd
  }
}
```

```json title="Response"
{
  "data": {
    "vaultPreviewRedeem": {
      "usdPerToken": "1.0",
      "amount": {
        "raw": "1025500000",
        "decimals": 6,
        "value": "1025.5"
      },
      "usd": "1025.5"
    }
  }
}
```

</tab>
</tabgroup>
### 2. Prepare the Redeem Transaction

Next, create the transaction request for the redeem operation. Use the `useVaultRedeemShares` hook in React, the `vaultRedeemShares` action in TypeScript, or the `vaultRedeemShares` query in GraphQL to create the transaction request for redeeming vault shares.

<tabgroup>
<tab label="React">

```tsx title="Redeem Shares"
import { useWalletClient } from "wagmi";
import { useVaultRedeemShares, bigDecimal, evmAddress } from "@aave/react";

// …

const { data: walletClient } = useWalletClient();

const [redeemShares, redeeming] = useVaultRedeemShares();

const execute = async () => {
  const result = await redeemShares({
    chainId: vault.chainId,
    vault: vault.address,
    shares: {
      amount: bigDecimal(1000), // 1000 vault shares
    },
    sharesOwner: evmAddress(walletClient!.account.address),
    // recipient: evmAddress("0x1234…"), if different from sharesOwner
  });

  // …
};
```

</tab>
<tab label="TypeScript">

```ts title="Redeem Shares"
import { bigDecimal, evmAddress } from "@aave/client";
import { vaultRedeemShares } from "@aave/client/actions";

import { client } from "./client";
import { wallet } from "./wallet";

const result = await vaultRedeemShares(client, {
  chainId: vault.chainId,
  vault: vault.address,
  shares: {
    amount: bigDecimal(1000), // 1000 vault shares
  },
  sharesOwner: evmAddress(wallet.account.address),
  // recipient: evmAddress("0x1234…"), if different from sharesOwner
});

// …
```

</tab>
<tab label="GraphQL">

```graphql title="Query"
query {
  vaultRedeemShares(
    request: {
      chainId: 1
      vault: "0x1234567890abcdef1234567890abcdef12345678"
      shares: { amount: "1000" }
      sharesOwner: "0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234"
      # recipient: "0x1234…", if different from sharesOwner
    }
  ) {
    to
    from
    data
    value
    chainId
  }
}
```

</tab>
</tabgroup>
### 3. Send the Redeem Transaction

Finally, send the transaction.

- **React**: Use the `useSendTransaction` hook for the [wallet library of your choice](/aave-v3/getting-started/react#send-aave-transactions) to send the transaction.
- **TypeScript**: Use `sendWith` for your [chosen wallet library](/aave-v3/getting-started/typescript#send-aave-transactions) to initiate the transaction, and await indexing with `client.waitForTransaction`.
- **GraphQL**: The response is a `TransactionRequest` that can be sent directly using the wallet associated with the `from` address.

<tabgroup>
<tab label="React">

```tsx title="Viem"
import { useWalletClient } from "wagmi";
import { useVaultRedeemShares } from "@aave/react";
import { useSendTransaction } from "@aave/react/viem";

// …

const { data: walletClient } = useWalletClient();

const [redeemShares, redeeming] = useVaultRedeemShares();
const [sendTransaction, sending] = useSendTransaction(walletClient);

const loading = redeeming.loading || sending.loading;
const error = redeeming.error || sending.error;

// …

const execute = async () => {
  const result = await redeemShares({
    // …
  }).andThen(sendTransaction);

  if (result.isErr()) {
    console.error("Redeem shares failed:", result.error);
  } else {
    console.log("Redeem shares successful with hash:", result.value);
  }
};
```

</tab>
<tab label="TypeScript">

```ts title="Viem"
import { vaultRedeemShares } from "@aave/client/actions";
import { sendWith } from "@aave/client/viem";

import { client } from "./client";
import { wallet } from "./wallet";

const result = await vaultRedeemShares(client, {
  // …
})
  .andThen(sendWith(wallet))
  .andThen(client.waitForTransaction);

if (result.isErr()) {
  console.error("Redeem shares failed:", result.error);
} else {
  console.log("Redeem shares successful:", result.value);
}
```

</tab>
<tab label="GraphQL">

```json title="TransactionRequest"
{
  "data": {
    "vaultRedeemShares": {
      "to": "0x1234567890abcdef1234567890abcdef12345678",
      "from": "0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234",
      "data": "0xba087652000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234000000000000000000000000742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234",
      "value": "0",
      "chainId": 1,
      "operation": "VAULT_WITHDRAW"
    }
  }
}
```

</tab>
</tabgroup>
