# Contract Integration

Examples for integrating with YieldFi v3 smart contracts. The v3 contracts use a Manager contract for deposits/redemptions and Vault contracts (ERC-4626) for vault tokens.

### Getting V3 Contract ABIs

V3 contract ABIs are included in the SDK package:

```typescript
import ManagerV3ABI from "yieldfi-sdk/abis/v3/Manager.json";
import VaultABI from "yieldfi-sdk/abis/v3/Vault.json";
```

Or import from the abis directory in your project:

```typescript
import ManagerV3ABI from "./abis/v3/Manager.json";
import VaultABI from "./abis/v3/Vault.json";
```

### Deposit to Vault

Deposit assets to a v3 vault using the Manager contract.

<pre class="language-typescript"><code class="lang-typescript">import {
  connectManagerV3,
  connectVault,
  getContractAddresses,
  Chain,
} from "yieldfi-sdk";
import { ethers } from "ethers";
import ManagerV3ABI from "yieldfi-sdk/abis/v3/Manager.json";

// Request Redemption (V3)

<strong>//Request redemption from a v3 vault. Shares are locked in a queue until processed.
</strong>
<strong>//### Using Wagmi
</strong>
import { connectManagerV3, getContractAddresses, Chain } from "yieldfi-sdk";
import { ethers } from "ethers";
import { useAccount, useWalletClient } from "wagmi";
import ManagerV3ABI from "yieldfi-sdk/abis/v3/Manager.json";

function RedemptionButton() {
  const { address } = useAccount();
  const { data: walletClient } = useWalletClient();

  const requestRedemption = async (
    vaultAddress: string,
    shares: bigint,
    receiver?: string
  ) => {
    if (!walletClient || !address) {
      throw new Error("Wallet not connected");
    }

    const provider = new ethers.BrowserProvider(walletClient);
    const signer = await provider.getSigner();

    const contracts = getContractAddresses(Chain.ETHEREUM);
    const managerV3 = connectManagerV3(contracts.manager, ManagerV3ABI, signer);

    // Request redemption (shares are locked, not burned)
    const redeemTx = await managerV3.requestRedemption(
      vaultAddress,
      shares,
      address, // Owner
      receiver || address // Receiver (defaults to owner)
    );

    const receipt = await redeemTx.wait();
    console.log(`Redemption requested: ${receipt.hash}`);
    return receipt;
  };

  return (
    &#x3C;button
      onClick={() =>
        requestRedemption(
          "0x5bE91d34FeFbB7554497a74e25dC6df96bFef5DB",
          ethers.parseUnits("100", 18)
        )
      }
    >
      Request Redemption
    &#x3C;/button>
  );
}
</code></pre>

#### Using Browser Provider

```typescript
import { connectManagerV3, getContractAddresses, Chain } from "yieldfi-sdk";
import { ethers } from "ethers";
import ManagerV3ABI from "yieldfi-sdk/abis/v3/Manager.json";

async function requestRedemptionV3(
  vaultAddress: string,
  shares: bigint,
  receiver?: string
) {
  if (!window.ethereum) {
    throw new Error("No wallet found");
  }

  const provider = new ethers.BrowserProvider(window.ethereum);
  const signer = await provider.getSigner();
  const userAddress = await signer.getAddress();

  const contracts = getContractAddresses(Chain.ETHEREUM);
  const managerV3 = connectManagerV3(contracts.manager, ManagerV3ABI, signer);

  // Request redemption (shares are locked, not burned)
  const redeemTx = await managerV3.requestRedemption(
    vaultAddress,
    shares,
    userAddress, // Owner
    receiver || userAddress // Receiver (defaults to owner)
  );

  const receipt = await redeemTx.wait();
  console.log(`Redemption requested: ${receipt.hash}`);
  return receipt;
}

// Usage
requestRedemptionV3(
  "0x5bE91d34FeFbB7554497a74e25dC6df96bFef5DB",
  ethers.parseUnits("100", 18)
);
```

### Check Vault Balance (V3)

Check vault token balance and convert between shares and assets.

#### Using Wagmi

```typescript
import { connectVault } from "yieldfi-sdk";
import { ethers } from "ethers";
import { useAccount, useWalletClient } from "wagmi";
import VaultABI from "yieldfi-sdk/abis/v3/Vault.json";

function VaultBalance() {
  const { address } = useAccount();
  const { data: walletClient } = useWalletClient();

  const checkVaultBalance = async (vaultAddress: string) => {
    if (!walletClient || !address) {
      throw new Error("Wallet not connected");
    }

    const provider = new ethers.BrowserProvider(walletClient);
    const vault = connectVault(vaultAddress, VaultABI, provider);

    // Get user's share balance
    const shares = await vault.balanceOf(address);
    console.log(`Shares: ${ethers.formatUnits(shares, 18)}`);

    // Get total assets and supply
    const totalAssets = await vault.totalAssets();
    const totalSupply = await vault.totalSupply();
    console.log(`Total Assets: ${ethers.formatUnits(totalAssets, 6)}`);
    console.log(`Total Supply: ${ethers.formatUnits(totalSupply, 18)}`);

    // Convert shares to assets (ERC-4626 method)
    const assets = await vault.convertToAssets(shares);
    console.log(`Your Assets: ${ethers.formatUnits(assets, 6)}`);

    // Get asset address
    const assetAddress = await vault.asset();
    console.log(`Asset Address: ${assetAddress}`);

    // Get vault info
    const name = await vault.name();
    const symbol = await vault.symbol();
    const decimals = await vault.decimals();
    console.log(`Vault: ${name} (${symbol}) - ${decimals} decimals`);

    return {
      shares,
      assets,
      totalAssets,
      totalSupply,
      assetAddress,
    };
  };

  return (
    <button
      onClick={() =>
        checkVaultBalance("0x5bE91d34FeFbB7554497a74e25dC6df96bFef5DB")
      }
    >
      Check Balance
    </button>
  );
}
```

#### Using Browser Provider

```typescript
import { connectVault } from "yieldfi-sdk";
import { ethers } from "ethers";
import VaultABI from "yieldfi-sdk/abis/v3/Vault.json";

async function checkVaultBalance(vaultAddress: string) {
  if (!window.ethereum) {
    throw new Error("No wallet found");
  }

  const provider = new ethers.BrowserProvider(window.ethereum);
  const signer = await provider.getSigner();
  const userAddress = await signer.getAddress();

  // Connect to Vault contract (ERC-4626)
  const vault = connectVault(vaultAddress, VaultABI, provider);

  // Get user's share balance
  const shares = await vault.balanceOf(userAddress);
  console.log(`Shares: ${ethers.formatUnits(shares, 18)}`);

  // Get total assets and supply
  const totalAssets = await vault.totalAssets();
  const totalSupply = await vault.totalSupply();
  console.log(`Total Assets: ${ethers.formatUnits(totalAssets, 6)}`);
  console.log(`Total Supply: ${ethers.formatUnits(totalSupply, 18)}`);

  // Convert shares to assets (ERC-4626 method)
  const assets = await vault.convertToAssets(shares);
  console.log(`Your Assets: ${ethers.formatUnits(assets, 6)}`);

  // Get asset address
  const assetAddress = await vault.asset();
  console.log(`Asset Address: ${assetAddress}`);

  // Get vault info
  const name = await vault.name();
  const symbol = await vault.symbol();
  const decimals = await vault.decimals();
  console.log(`Vault: ${name} (${symbol}) - ${decimals} decimals`);

  return {
    shares,
    assets,
    totalAssets,
    totalSupply,
    assetAddress,
  };
}

// Usage
checkVaultBalance("0x5bE91d34FeFbB7554497a74e25dC6df96bFef5DB");
```

### Check Redemption Queue (V3)

Check redemption queue status and entries.

#### Using Wagmi

```typescript
import { connectManagerV3, getContractAddresses, Chain } from "yieldfi-sdk";
import { ethers } from "ethers";
import { useWalletClient } from "wagmi";
import ManagerV3ABI from "yieldfi-sdk/abis/v3/Manager.json";

function RedemptionQueue() {
  const { data: walletClient } = useWalletClient();

  const checkRedemptionQueue = async (vaultAddress: string) => {
    if (!walletClient) {
      throw new Error("Wallet not connected");
    }

    const provider = new ethers.BrowserProvider(walletClient);
    const contracts = getContractAddresses(Chain.ETHEREUM);
    const managerV3 = connectManagerV3(contracts.manager, ManagerV3ABI, provider);

    // Get queue length
    const queueLength = await managerV3.getRedemptionQueueLength(vaultAddress);
    console.log(`Redemption Queue Length: ${queueLength}`);

    // Get standard debt (total locked shares)
    const standardDebt = await managerV3.getStandardDebt(vaultAddress);
    console.log(`Standard Debt (Locked Shares): ${ethers.formatUnits(standardDebt, 18)}`);

    // Get next queue index
    const nextIndex = await managerV3.nextQueueIndex(vaultAddress);
    console.log(`Next Queue Index: ${nextIndex}`);

    // Get a specific queue entry
    if (queueLength > 0n) {
      const queueEntry = await managerV3.getRedemptionQueueEntry(vaultAddress, 0);
      console.log(`Queue Entry 0:`);
      console.log(`  Owner: ${queueEntry.owner}`);
      console.log(`  Receiver: ${queueEntry.receiver}`);
      console.log(`  Locked Shares: ${ethers.formatUnits(queueEntry.lockedShares, 18)}`);
      console.log(`  NAV at Request: ${ethers.formatUnits(queueEntry.navAtRequest, 18)}`);
      console.log(`  Timestamp: ${new Date(Number(queueEntry.timestamp) * 1000).toLocaleString()}`);
    }

    return {
      queueLength,
      standardDebt,
      nextIndex,
    };
  };

  return (
    <button
      onClick={() =>
        checkRedemptionQueue("0x5bE91d34FeFbB7554497a74e25dC6df96bFef5DB")
      }
    >
      Check Queue
    </button>
  );
}
```

#### Using Browser Provider

```typescript
import { connectManagerV3, getContractAddresses, Chain } from "yieldfi-sdk";
import { ethers } from "ethers";
import ManagerV3ABI from "yieldfi-sdk/abis/v3/Manager.json";

async function checkRedemptionQueue(vaultAddress: string) {
  if (!window.ethereum) {
    throw new Error("No wallet found");
  }

  const provider = new ethers.BrowserProvider(window.ethereum);
  const contracts = getContractAddresses(Chain.ETHEREUM);
  const managerV3 = connectManagerV3(contracts.manager, ManagerV3ABI, provider);

  // Get queue length
  const queueLength = await managerV3.getRedemptionQueueLength(vaultAddress);
  console.log(`Redemption Queue Length: ${queueLength}`);

  // Get standard debt (total locked shares)
  const standardDebt = await managerV3.getStandardDebt(vaultAddress);
  console.log(`Standard Debt (Locked Shares): ${ethers.formatUnits(standardDebt, 18)}`);

  // Get next queue index
  const nextIndex = await managerV3.nextQueueIndex(vaultAddress);
  console.log(`Next Queue Index: ${nextIndex}`);

  // Get a specific queue entry
  if (queueLength > 0n) {
    const queueEntry = await managerV3.getRedemptionQueueEntry(vaultAddress, 0);
    console.log(`Queue Entry 0:`);
    console.log(`  Owner: ${queueEntry.owner}`);
    console.log(`  Receiver: ${queueEntry.receiver}`);
    console.log(`  Locked Shares: ${ethers.formatUnits(queueEntry.lockedShares, 18)}`);
    console.log(`  NAV at Request: ${ethers.formatUnits(queueEntry.navAtRequest, 18)}`);
    console.log(`  Timestamp: ${new Date(Number(queueEntry.timestamp) * 1000).toLocaleString()}`);
  }

  return {
    queueLength,
    standardDebt,
    nextIndex,
  };
}

// Usage
checkRedemptionQueue("0x5bE91d34FeFbB7554497a74e25dC6df96bFef5DB");
```

### Cancel Redemption (V3)

Cancel a pending redemption request.

#### Using Wagmi

```typescript
import { connectManagerV3, getContractAddresses, Chain } from "yieldfi-sdk";
import { ethers } from "ethers";
import { useAccount, useWalletClient } from "wagmi";
import ManagerV3ABI from "yieldfi-sdk/abis/v3/Manager.json";

function CancelRedemptionButton() {
  const { address } = useAccount();
  const { data: walletClient } = useWalletClient();

  const cancelRedemption = async (vaultAddress: string, queueIndex: bigint) => {
    if (!walletClient || !address) {
      throw new Error("Wallet not connected");
    }

    const provider = new ethers.BrowserProvider(walletClient);
    const signer = await provider.getSigner();

    const contracts = getContractAddresses(Chain.ETHEREUM);
    const managerV3 = connectManagerV3(contracts.manager, ManagerV3ABI, signer);

    // Cancel redemption (unlocks shares)
    const cancelTx = await managerV3.cancelRedemption(vaultAddress, queueIndex);
    const receipt = await cancelTx.wait();

    console.log(`Redemption cancelled: ${receipt.hash}`);
    return receipt;
  };

  return (
    <button onClick={() => cancelRedemption(vaultAddress, queueIndex)}>
      Cancel Redemption
    </button>
  );
}
```

#### Using Browser Provider

```typescript
import { connectManagerV3, getContractAddresses, Chain } from "yieldfi-sdk";
import { ethers } from "ethers";
import ManagerV3ABI from "yieldfi-sdk/abis/v3/Manager.json";

async function cancelRedemption(vaultAddress: string, queueIndex: bigint) {
  if (!window.ethereum) {
    throw new Error("No wallet found");
  }

  const provider = new ethers.BrowserProvider(window.ethereum);
  const signer = await provider.getSigner();

  const contracts = getContractAddresses(Chain.ETHEREUM);
  const managerV3 = connectManagerV3(contracts.manager, ManagerV3ABI, signer);

  // Cancel redemption (unlocks shares)
  const cancelTx = await managerV3.cancelRedemption(vaultAddress, queueIndex);
  const receipt = await cancelTx.wait();

  console.log(`Redemption cancelled: ${receipt.hash}`);
  return receipt;
}

// Usage
cancelRedemption(
  "0x5bE91d34FeFbB7554497a74e25dC6df96bFef5DB",
  0n // Queue index
);
```

### Process Redemption (V3) - Admin/Operator Only

Process a redemption from the queue. This is typically called by vault operators.

#### Using Wagmi

```typescript
import { connectManagerV3, getContractAddresses, Chain } from "yieldfi-sdk";
import { ethers } from "ethers";
import { useAccount, useWalletClient } from "wagmi";
import ManagerV3ABI from "yieldfi-sdk/abis/v3/Manager.json";

function ProcessRedemptionButton() {
  const { address } = useAccount();
  const { data: walletClient } = useWalletClient();

  const processRedemption = async (
    vaultAddress: string,
    queueIndex: bigint,
    gasFeeShares: bigint = 0n
  ) => {
    if (!walletClient || !address) {
      throw new Error("Wallet not connected");
    }

    const provider = new ethers.BrowserProvider(walletClient);
    const signer = await provider.getSigner();

    const contracts = getContractAddresses(Chain.ETHEREUM);
    const managerV3 = connectManagerV3(contracts.manager, ManagerV3ABI, signer);

    // Process redemption (burns locked shares, transfers assets)
    const processTx = await managerV3.processRedemption(
      vaultAddress,
      queueIndex,
      gasFeeShares
    );

    const receipt = await processTx.wait();
    console.log(`Redemption processed: ${receipt.hash}`);
    return receipt;
  };

  return (
    <button
      onClick={() => processRedemption(vaultAddress, queueIndex, 0n)}
    >
      Process Redemption
    </button>
  );
}
```

#### Using Browser Provider

```typescript
import { connectManagerV3, getContractAddresses, Chain } from "yieldfi-sdk";
import { ethers } from "ethers";
import ManagerV3ABI from "yieldfi-sdk/abis/v3/Manager.json";

async function processRedemption(
  vaultAddress: string,
  queueIndex: bigint,
  gasFeeShares: bigint = 0n
) {
  if (!window.ethereum) {
    throw new Error("No wallet found");
  }

  const provider = new ethers.BrowserProvider(window.ethereum);
  const signer = await provider.getSigner();

  const contracts = getContractAddresses(Chain.ETHEREUM);
  const managerV3 = connectManagerV3(contracts.manager, ManagerV3ABI, signer);

  // Process redemption (burns locked shares, transfers assets)
  const processTx = await managerV3.processRedemption(
    vaultAddress,
    queueIndex,
    gasFeeShares
  );

  const receipt = await processTx.wait();
  console.log(`Redemption processed: ${receipt.hash}`);
  return receipt;
}

// Usage (operator only)
processRedemption(
  "0x5bE91d34FeFbB7554497a74e25dC6df96bFef5DB",
  0n, // Queue index
  0n // No gas fee
);
```

### Complete V3 Integration Example

Complete example showing deposit, balance check, and redemption flow using wagmi:

```typescript
import {
  connectManagerV3,
  connectVault,
  getContractAddresses,
  Chain,
} from "yieldfi-sdk";
import { ethers } from "ethers";
import { useAccount, useWalletClient } from "wagmi";
import ManagerV3ABI from "yieldfi-sdk/abis/v3/Manager.json";
import VaultABI from "yieldfi-sdk/abis/v3/Vault.json";

function VaultOperations() {
  const { address } = useAccount();
  const { data: walletClient } = useWalletClient();

  const completeV3VaultFlow = async (
    vaultAddress: string,
    assetAddress: string
  ) => {
    if (!walletClient || !address) {
      throw new Error("Wallet not connected");
    }

    const provider = new ethers.BrowserProvider(walletClient);
    const signer = await provider.getSigner();

    const contracts = getContractAddresses(Chain.ETHEREUM);

    // Connect to contracts
    const managerV3 = connectManagerV3(contracts.manager, ManagerV3ABI, signer);
    const vault = connectVault(vaultAddress, VaultABI, provider);
    const assetToken = new ethers.Contract(
      assetAddress,
      [
        "function approve(address spender, uint256 amount) returns (bool)",
        "function balanceOf(address account) view returns (uint256)",
        "function decimals() view returns (uint8)",
      ],
      signer
    );

    // 1. Check current vault balance
    const currentShares = await vault.balanceOf(address);
    const currentAssets = await vault.convertToAssets(currentShares);
    console.log(`Current Vault Balance:`);
    console.log(`  Shares: ${ethers.formatUnits(currentShares, 18)}`);
    console.log(`  Assets: ${ethers.formatUnits(currentAssets, 6)}`);

    // 2. Deposit assets
    const depositAmount = ethers.parseUnits("100", 6); // 100 USDC
    const assetBalance = await assetToken.balanceOf(address);

    if (assetBalance < depositAmount) {
      console.log("Insufficient asset balance");
      return;
    }

    // Calculate minimum shares with slippage protection
    const previewShares = await vault.previewDeposit(depositAmount);
    const minShares = (previewShares * 95n) / 100n; // 5% slippage tolerance

    // Approve and deposit
    const approveTx = await assetToken.approve(managerV3.target, depositAmount);
    await approveTx.wait();

    const depositTx = await managerV3.deposit(
      vaultAddress,
      assetAddress,
      depositAmount,
      address,
      minShares,
      ethers.ZeroHash // referralCode
    );
    await depositTx.wait();
    console.log(`Deposit successful: ${depositTx.hash}`);

    // 3. Check new balance
    const newShares = await vault.balanceOf(address);
    const newAssets = await vault.convertToAssets(newShares);
    console.log(`New Vault Balance:`);
    console.log(`  Shares: ${ethers.formatUnits(newShares, 18)}`);
    console.log(`  Assets: ${ethers.formatUnits(newAssets, 6)}`);

    // 4. Request redemption (redeem half)
    const redeemShares = newShares / 2n;
    const redeemTx = await managerV3.requestRedemption(
      vaultAddress,
      redeemShares,
      address,
      address
    );
    await redeemTx.wait();
    console.log(`Redemption requested: ${redeemTx.hash}`);

    // 5. Check redemption queue
    const queueLength = await managerV3.getRedemptionQueueLength(vaultAddress);
    console.log(`Redemption Queue Length: ${queueLength}`);

    // 6. Check updated balance (shares are locked, not burned)
    const lockedShares = await vault.lockedShares(address);
    const activeShares = await vault.balanceOf(address);
    console.log(`Active Shares: ${ethers.formatUnits(activeShares, 18)}`);
    console.log(`Locked Shares: ${ethers.formatUnits(lockedShares, 18)}`);

    // 7. Cancel redemption (optional)
    if (queueLength > 0n) {
      const cancelTx = await managerV3.cancelRedemption(
        vaultAddress,
        queueLength - 1n
      );
      await cancelTx.wait();
      console.log(`Redemption cancelled: ${cancelTx.hash}`);
    }
  };

  return (
    <div>
      <button
        onClick={() =>
          completeV3VaultFlow(
            "0x5bE91d34FeFbB7554497a74e25dC6df96bFef5DB",
            "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
          )
        }
      >
        Complete Vault Flow
      </button>
    </div>
  );
}
```

#### Using Browser Provider Directly

```typescript
import {
  connectManagerV3,
  connectVault,
  getContractAddresses,
  Chain,
} from "yieldfi-sdk";
import { ethers } from "ethers";
import ManagerV3ABI from "yieldfi-sdk/abis/v3/Manager.json";
import VaultABI from "yieldfi-sdk/abis/v3/Vault.json";

async function completeV3VaultFlow() {
  if (!window.ethereum) {
    throw new Error("No wallet found");
  }

  const provider = new ethers.BrowserProvider(window.ethereum);
  const signer = await provider.getSigner();
  const userAddress = await signer.getAddress();

  const contracts = getContractAddresses(Chain.ETHEREUM);
  const vaultAddress = "0x5bE91d34FeFbB7554497a74e25dC6df96bFef5DB";
  const assetAddress = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"; // USDC

  // Connect to contracts
  const managerV3 = connectManagerV3(contracts.manager, ManagerV3ABI, signer);
  const vault = connectVault(vaultAddress, VaultABI, provider);
  const assetToken = new ethers.Contract(
    assetAddress,
    [
      "function approve(address spender, uint256 amount) returns (bool)",
      "function balanceOf(address account) view returns (uint256)",
    ],
    signer
  );

  // 1. Check current vault balance
  const currentShares = await vault.balanceOf(userAddress);
  const currentAssets = await vault.convertToAssets(currentShares);
  console.log(`Current Vault Balance:`);
  console.log(`  Shares: ${ethers.formatUnits(currentShares, 18)}`);
  console.log(`  Assets: ${ethers.formatUnits(currentAssets, 6)}`);

  // 2. Deposit assets
  const depositAmount = ethers.parseUnits("100", 6);
  const assetBalance = await assetToken.balanceOf(userAddress);

  if (assetBalance < depositAmount) {
    console.log("Insufficient asset balance");
    return;
  }

  // Calculate minimum shares with slippage protection
  const previewShares = await vault.previewDeposit(depositAmount);
  const minShares = (previewShares * 95n) / 100n; // 5% slippage tolerance

  // Approve and deposit
  await assetToken.approve(managerV3.target, depositAmount);
  const depositTx = await managerV3.deposit(
    vaultAddress,
    assetAddress,
    depositAmount,
    userAddress,
    minShares,
    ethers.ZeroHash
  );
  await depositTx.wait();
  console.log(`Deposit successful: ${depositTx.hash}`);

  // 3. Check new balance
  const newShares = await vault.balanceOf(userAddress);
  const newAssets = await vault.convertToAssets(newShares);
  console.log(`New Vault Balance:`);
  console.log(`  Shares: ${ethers.formatUnits(newShares, 18)}`);
  console.log(`  Assets: ${ethers.formatUnits(newAssets, 6)}`);

  // 4. Request redemption
  const redeemShares = newShares / 2n;
  const redeemTx = await managerV3.requestRedemption(
    vaultAddress,
    redeemShares,
    userAddress,
    userAddress
  );
  await redeemTx.wait();
  console.log(`Redemption requested: ${redeemTx.hash}`);

  // 5. Check redemption queue
  const queueLength = await managerV3.getRedemptionQueueLength(vaultAddress);
  console.log(`Redemption Queue Length: ${queueLength}`);

  // 6. Check locked shares
  const lockedShares = await vault.lockedShares(userAddress);
  const activeShares = await vault.balanceOf(userAddress);
  console.log(`Active Shares: ${ethers.formatUnits(activeShares, 18)}`);
  console.log(`Locked Shares: ${ethers.formatUnits(lockedShares, 18)}`);
}

completeV3VaultFlow();
```

### V3 Contract Features

#### Manager V3 Contract

* **Deposit**: Deposit assets to vaults with slippage protection (`minShares`)
* **Request Redemption**: Request redemption (shares are locked, not burned)
* **Cancel Redemption**: Cancel pending redemption requests
* **Process Redemption**: Process redemptions from queue (operator only)
* **Redemption Queue**: Query queue entries and status

#### Vault Contract (ERC-4626)

* **Standard ERC-4626**: Full ERC-4626 vault interface
* **Share Locking**: Shares can be locked for redemption requests
* **Asset Conversion**: `convertToAssets()` and `convertToShares()` methods
* **Preview Functions**: Preview deposit/redeem amounts

### Getting Contract Addresses

```typescript
import { getContractAddresses, Chain } from "yieldfi-sdk";

const contracts = getContractAddresses(Chain.ETHEREUM);
console.log(`Manager V3: ${contracts.manager}`);

// Vault addresses are specific to each vault
// Get them from the Vault API or registry
```

### Type Safety

The SDK provides full TypeScript types for v3 contracts:

```typescript
import type { ManagerV3, VaultContract } from "yieldfi-sdk";
import { Contract } from "ethers";
import { useWalletClient } from "wagmi";

function TypedContractExample() {
  const { data: walletClient } = useWalletClient();

  const useTypedContracts = async () => {
    if (!walletClient) return;

    const provider = new ethers.BrowserProvider(walletClient);
    const signer = await provider.getSigner();

    const managerV3 = new Contract(
      contracts.manager,
      ManagerV3ABI,
      signer
    ) as unknown as ManagerV3;

    const vault = new Contract(
      vaultAddress,
      VaultABI,
      provider
    ) as unknown as VaultContract;

    // Full type safety and IntelliSense
    await managerV3.deposit(/* ... */);
    await vault.balanceOf(/* ... */);
  };
}
```

### Wallet Integration Best Practices

#### Always Check Wallet Connection

```typescript
if (!window.ethereum) {
  throw new Error("Please install a wallet like MetaMask");
}

// Or with wagmi
const { isConnected } = useAccount();
if (!isConnected) {
  throw new Error("Please connect your wallet");
}
```

#### Handle User Rejection

```typescript
try {
  const tx = await managerV3.deposit(/* ... */);
  await tx.wait();
} catch (error: any) {
  if (error.code === 4001) {
    // User rejected the transaction
    console.log("Transaction rejected by user");
  } else {
    throw error;
  }
}
```

#### Request Account Access

```typescript
// Request account access if needed
await window.ethereum.request({ method: "eth_requestAccounts" });

// Or with wagmi, use useConnect hook
const { connect } = useConnect();
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.yield.fi/earn-with-yieldfi/integration-sdk/examples-and-guides/contract-integration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
