Skip to main content

What is a vault deposit transaction?

A vault deposit transaction sends assets into a DeFi vault (often ERC-4626) and receives vault shares in return. This example uses an ERC-4626 vault deposit. Adjust the contract address, function signature, and amount for your protocol.

1) Set up the client and signer

Create the SDK client and signer used for approvals.
import { DenClient, NetworkId } from "@den/sdk";
import { privateKeyToAccount } from "viem/accounts";
import { encodeFunctionData } from "viem";

const signer = privateKeyToAccount("0xYOUR_PRIVATE_KEY");

const client = new DenClient({
  apiKey: "ck_live_...",
  rpcProviders: {
    1: "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY",
  },
});

2) Encode the vault deposit

Encode the ERC-4626 deposit call data for the vault.
const erc4626DepositAbi = [
  {
    name: "deposit",
    type: "function",
    stateMutability: "nonpayable",
    inputs: [
      { name: "assets", type: "uint256" },
      { name: "receiver", type: "address" },
    ],
    outputs: [{ name: "shares", type: "uint256" }],
  },
];

const data = encodeFunctionData({
  abi: erc4626DepositAbi,
  functionName: "deposit",
  args: [1_000_000_000n, "0xReceiver..."],
});

3) Create the deposit transaction

Create a transaction proposal with the encoded deposit data.
const queued = await client.createTransaction("acc_123", {
  networkId: NetworkId.ETHEREUM,
  policyId: "pol_123",
  description: "Deposit into vault",
  to: "0xVaultAddress...",
  value: "0",
  data,
});

4) Sign and execute

Sign as the initiator, then execute once approvals are ready.
const initiatorSig = await signer.signMessage({
  message: queued.signingPayloads.initiatorPayload,
});

const afterInitiator = await client.signTransaction("acc_123", queued.id, {
  type: "initiator",
  signature: initiatorSig,
});

if (afterInitiator.signatureStatus === "approvalReady") {
  await client.executeTransaction("acc_123", queued.id, { type: "approve" });
}

Full example

import { DenClient, NetworkId } from "@den/sdk";
import { privateKeyToAccount } from "viem/accounts";
import { encodeFunctionData } from "viem";

// 1) Set up the client and signer.
const signer = privateKeyToAccount("0xYOUR_PRIVATE_KEY");

const client = new DenClient({
  apiKey: "ck_live_...",
  rpcProviders: {
    1: "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY",
  },
});

// 2) Encode the vault deposit.
const erc4626DepositAbi = [
  {
    name: "deposit",
    type: "function",
    stateMutability: "nonpayable",
    inputs: [
      { name: "assets", type: "uint256" },
      { name: "receiver", type: "address" },
    ],
    outputs: [{ name: "shares", type: "uint256" }],
  },
];

const data = encodeFunctionData({
  abi: erc4626DepositAbi,
  functionName: "deposit",
  args: [1_000_000_000n, "0xReceiver..."],
});

// 3) Create the deposit transaction.
const queued = await client.createTransaction("acc_123", {
  networkId: NetworkId.ETHEREUM,
  policyId: "pol_123",
  description: "Deposit into vault",
  to: "0xVaultAddress...",
  value: "0",
  data,
});

// 4) Sign and execute.
const initiatorSig = await signer.signMessage({
  message: queued.signingPayloads.initiatorPayload,
});

const afterInitiator = await client.signTransaction("acc_123", queued.id, {
  type: "initiator",
  signature: initiatorSig,
});

if (afterInitiator.signatureStatus === "approvalReady") {
  await client.executeTransaction("acc_123", queued.id, { type: "approve" });
}