Skip to main content

Examples

The write examples on this page use vaultWithWallet and account, which example 5 creates. The read examples use the vault from example 3.

1. Check and top up allowance​

Before depositing, confirm the user has approved enough underlying for the vault. If not, approve the difference.

const vaultAddr = vaultWithWallet.getAddress();
const erc20 = await vaultWithWallet.getUnderlyingErc20();
const depositAmount = await vaultWithWallet.toUnderlyingBigInt("5.0"); // 5 underlying tokens

// Check existing allowance
const currentAllowance = await erc20.allowance(
account.address,
vaultAddr
);

if (currentAllowance < depositAmount) {
const approveAmount = depositAmount - currentAllowance;
console.log("Approving extra allowance:", approveAmount.toString());
await (await erc20.approve(vaultAddr, approveAmount)).wait();
}

// Safe to deposit
await (await vaultWithWallet.deposit(depositAmount)).wait();

2. Read total assets​

Get the vault's total assets and format the value with the SDK's helpers.

const details = await vault.getVaultDetails();
const total = await vault.totalAssets();

console.log(
"Total assets:",
await vault.toUnderlyingDecimals(total),
details.underlying.symbol
);

3. Fetch vault details​

import { getVault } from "@concrete-xyz/sdk";
import { createPublicClient, http } from "viem";
import { mainnet } from "viem/chains";

const transport = http("https://ethereum-rpc.publicnode.com");
const publicClient = createPublicClient({ chain: mainnet, transport });
const vault = getVault("v2", "0xYourVault", 1, publicClient);

const details = await vault.getVaultDetails();
console.log("Vault shares:", details.vaultAsset.symbol);
console.log("Underlying:", details.underlying.symbol);

4. Preview deposit​

Estimate how many shares (ctAssets) you will receive for a deposit.

const oneUnderlying = await vault.toUnderlyingBigInt("1.0");
const preview = await vault.previewConversion(oneUnderlying);

console.log(
`1 ${details.underlying.symbol} ≈ ${await vault.applyDecimals(preview.vaultTokensReceivingRaw)} ${details.vaultAsset.symbol}`
);

5. Deposit flow​

import { createWalletClient } from "viem";
import { privateKeyToAccount } from "viem/accounts";

// 1. Approve vault to spend the underlying
// 2. Deposit underlying into the vault
// 3. Receive vault shares

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const walletClient = createWalletClient({ account, chain: mainnet, transport });
const vaultWithWallet = getVault("v2", "0xYourVault", 1, publicClient, walletClient);

const depositAmount = await vaultWithWallet.toUnderlyingBigInt("1.0");

// (1) Approve underlying to the vault
const erc20 = await vaultWithWallet.getUnderlyingErc20();
await (await erc20.approve(vaultWithWallet.getAddress(), depositAmount)).wait();

// (2) Deposit
const receipt = await (await vaultWithWallet.deposit(depositAmount)).wait();
console.log("Deposit confirmed:", receipt.transactionHash);

6. Redeem flow​

const owner = account.address;
const shareBalance = await vaultWithWallet.balanceOf(owner);

if (shareBalance > 0n) {
const preview = await vaultWithWallet.previewConversion(shareBalance);
const details = await vaultWithWallet.getVaultDetails();

console.log(
`${await vaultWithWallet.applyDecimals(shareBalance)} ${details.vaultAsset.symbol} ≈ ` +
`${await vaultWithWallet.toUnderlyingDecimals(preview.underlyingReceivingRaw)} ${details.underlying.symbol}`
);

const receipt = await (await vaultWithWallet.redeem(shareBalance)).wait();
console.log("Redeemed:", receipt.transactionHash);
}

7. Transfer ctAssets​

Shares (ctAssets) behave like ERC20 tokens and can be transferred.

const recipient = "0xRecipient...";
const tenShares = await vaultWithWallet.toBigInt("10.0");
await (await vaultWithWallet.transfer(recipient, tenShares)).wait();

8. Move shares with allowance​

Grant another address permission to spend your shares.

const spender = "0xSpender...";
const owner = account.address;
const recipient = "0xRecipient...";
const allowance = await vaultWithWallet.toBigInt("5.0");

// Owner approves spender
await (await vaultWithWallet.approve(spender, allowance)).wait();

// Spender calls transferFrom (as the connected account)
await (await vaultWithWallet.transferFrom(owner, recipient, allowance)).wait();

9. End-to-end example​

// 1 underlying deposit, then redeem

const oneUnderlying = await vaultWithWallet.toUnderlyingBigInt("1.0");

// Preview deposit
const pvDeposit = await vaultWithWallet.previewConversion(oneUnderlying);
console.log("Expected shares:", await vaultWithWallet.applyDecimals(pvDeposit.vaultTokensReceivingRaw));

// Approve and deposit
const erc20 = await vaultWithWallet.getUnderlyingErc20();
await (await erc20.approve(vaultWithWallet.getAddress(), oneUnderlying)).wait();
await (await vaultWithWallet.deposit(oneUnderlying)).wait();

// Redeem
const owner = account.address;
const shares = await vaultWithWallet.balanceOf(owner);
await (await vaultWithWallet.redeem(shares)).wait();