Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.mls.onchainden.com/llms.txt

Use this file to discover all available pages before exploring further.

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 } from "@onchainden/mls-sdk-ts";
import { privateKeyToAccount } from "viem/accounts";
import { encodeFunctionData } from "viem";

const signer = privateKeyToAccount("0xYOUR_PRIVATE_KEY");

const client = new DenClient({
  apiKey: process.env.DEN_API_KEY!,
  baseUrl: process.env.DEN_API_BASE_URL!,
});

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 callData = 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 { data: queued } = await client.createTransaction({
  accountId: "acc_123",
  initiatorWalletAddress: signer.address,
  networkId: 1,
  policyId: "pol_123",
  description: "Deposit into vault",
  to: "0xVaultAddress...",
  value: "0",
  data: callData,
});

4) Sign and execute

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

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

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

Full example

import { DenClient } from "@onchainden/mls-sdk-ts";
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: process.env.DEN_API_KEY!,
  baseUrl: process.env.DEN_API_BASE_URL!,
});

// 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 callData = encodeFunctionData({
  abi: erc4626DepositAbi,
  functionName: "deposit",
  args: [1_000_000_000n, "0xReceiver..."],
});

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

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

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

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