> For the complete documentation index, see [llms.txt](https://sodex.com/documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sodex.com/documentation/for-developers/developers/wealth/vault-lifecycle/direct-deposits.md).

# Direct Deposits

Submit an `escrow_vault` deposit from the user's wallet. The wallet pays ValueChain gas. This is not a signed `OnBehalf` call and not a SoDEX RWA (`clob`) trade. See [Vault Lifecycle](/documentation/for-developers/developers/wealth/vault-lifecycle.md) for settlement. Encode `referral` first ([Referrals](/documentation/for-developers/developers/wealth/referrals.md)).

Credit is the vault ERC-20 share balance on ValueChain, not Spot or Perps. A successful `requestDeposit` does not mint shares in the same transaction. Claim only if settlement did not auto-deliver — that step is on [Settlement and Claims](/documentation/for-developers/developers/wealth/vault-lifecycle/settlement-and-claims.md).

## 1. Select the vault

Load `contracts.vault` from [Fund Information](/documentation/for-developers/api-reference/wealth-api/funds.md#get-fund-information) for an `escrow_vault` `fundId`. Check `fundStatus` and `chainConfig.paused`. `getMinDepositAmount()` is raw underlying units; `chainConfig.assetDecimals` is the decimal count for `RAW_AMOUNT`.

The underlying must already be on ValueChain. If it is not, move it with [Mirror Protocol](/documentation/for-developers/developers/mirror-protocol.md) first.

## 2. Submit `requestDeposit`

Install `viem` and `tsx`. Set `PRIVATE_KEY`, `VAULT_ADDRESS`, `RECEIVER`, `RAW_AMOUNT` (underlying base units), and `REFERRAL` (the `bytes32` from Referrals, or omit it for `bytes32(0)`). This broadcasts an approval when needed and a deposit request.

Save as `direct-deposit.mts` and run `npx tsx direct-deposit.mts`.

```typescript
import {
  createPublicClient, createWalletClient, defineChain, http, parseAbi, zeroHash,
  type Address, type Hex,
} from "viem";
import { privateKeyToAccount } from "viem/accounts";

const valuechain = defineChain({
  id: 286623, name: "ValueChain",
  nativeCurrency: { name: "SOSO", symbol: "SOSO", decimals: 18 },
  rpcUrls: { default: { http: ["https://mainnet.valuechain.xyz"] } },
});
const account = privateKeyToAccount(process.env.PRIVATE_KEY as Hex);
const publicClient = createPublicClient({ chain: valuechain, transport: http() });
const walletClient = createWalletClient({ account, chain: valuechain, transport: http() });
const vault = process.env.VAULT_ADDRESS as Address;
const receiver = process.env.RECEIVER as Address;
const amount = BigInt(process.env.RAW_AMOUNT!);
const referral = (process.env.REFERRAL as Hex | undefined) ?? zeroHash;
const vaultAbi = parseAbi([
  "function getAsset() view returns (address)",
  "function getMinDepositAmount() view returns (uint256)",
  "function requestDeposit(uint256 assets, address receiver, bytes32 referral)",
]);
const erc20Abi = parseAbi([
  "function approve(address spender, uint256 amount) returns (bool)",
  "function allowance(address owner, address spender) view returns (uint256)",
]);

const [asset, minDeposit] = await Promise.all([
  publicClient.readContract({ address: vault, abi: vaultAbi, functionName: "getAsset" }),
  publicClient.readContract({ address: vault, abi: vaultAbi, functionName: "getMinDepositAmount" }),
]);
if (amount < minDeposit) throw new Error(`Amount below min deposit: ${minDeposit}`);

const allowance = await publicClient.readContract({
  address: asset, abi: erc20Abi, functionName: "allowance", args: [account.address, vault],
});
if (allowance < amount) {
  const approveHash = await walletClient.writeContract({
    address: asset, abi: erc20Abi, functionName: "approve", args: [vault, amount],
  });
  const approveReceipt = await publicClient.waitForTransactionReceipt({ hash: approveHash });
  if (approveReceipt.status !== "success") throw new Error("Approval reverted");
}

const hash = await walletClient.writeContract({
  address: vault, abi: vaultAbi, functionName: "requestDeposit",
  args: [amount, receiver, referral],
});
console.log({ requestTxHash: hash });
const receipt = await publicClient.waitForTransactionReceipt({ hash });
if (receipt.status !== "success") throw new Error("requestDeposit reverted");
```

Save `requestTxHash`. Do not use `getNextDepositRequestId` as the claim ID.

## 3. Track settlement

Query [Settlement and Claims](/documentation/for-developers/developers/wealth/vault-lifecycle/settlement-and-claims.md) with that hash and `KIND=deposit`. Empty or `processing` records do not confirm shares. Do not send a second deposit to retry a status query.

To submit with a user signature instead of this wallet paying gas, use [Signed Deposits](/documentation/for-developers/developers/wealth/vault-lifecycle/signed-deposits.md) and the [Transaction Relayer](/documentation/for-developers/developers/valuechain-evm/relayer.md).
