IPrivacy.deposit

deposit(
  PrivacyDepositRequest request
) external payable returns (bool success)

Escrows the caller's transparent OKRW (attached as msg.value) into the shielded pool and appends the note commitment from request to the Merkle tree. deposit is the only payable method on IPrivacy. The shielded amount is bounded by a 64-bit field, so a single deposit is capped at 18446744073709551615 base units (~18.446744073709551615 OKRW) — larger balances are held as multiple notes. Failures revert with typed custom errors on IPrivacy or inherited errors on IPrecompile.

Parameters

Name Type Required Description
request PrivacyDepositRequest ✓ The deposit payload: noteCommitment (the shielded output), encryptedNote (the ciphertext the recipient will decrypt), and proof (the deposit validity proof).

Returns

Type: bool

Returns true on success. Failures revert with a typed custom error rather than returning false.

Errors

Code Name Description
InvalidAmount InvalidAmount Inherited from IPrecompile. Reverts when msg.value fails shielded-amount validation (zero, negative-in-unsigned-form, or exceeding the 64-bit shielded cap). Encoded as InvalidAmount(string amount) where the payload is the decimal string of the amount.
InvalidAddress InvalidAddress Inherited from IPrecompile. Reverts when the caller address cannot be converted to a valid account address (usually the zero address). Encoded as InvalidAddress(string bad).
PrivacyCommitmentAlreadyExists PrivacyCommitmentAlreadyExists Reverts when the noteCommitment already exists in the shielded-pool Merkle tree.
PrivacyMerkleCapacityExceeded PrivacyMerkleCapacityExceeded Reverts when appending the deposit's commitment would exceed the Merkle tree capacity.
InvalidNumberOfArgs InvalidNumberOfArgs Declared in the shared IPrecompile error set as InvalidNumberOfArgs(uint256 expected, uint256 got), but this function does not revert with it for a wrong argument count: calldata too short for the request reverts with ABISetupFailed, and bytes after the request are ignored.
ABISetupFailed ABISetupFailed Inherited from IPrecompile as ABISetupFailed(string reason). Reverts when the calldata cannot be decoded against the precompile's ABI: an unknown 4-byte selector gives the reason no method with id: 0x… (usually a stale ABI), and calldata too short for the arguments gives the decoder's message, for example abi: cannot marshal in to go type: length insufficient 32 require 64. An unknown selector does not revert with UnknownMethod, although the precompile declares it.

Examples

Deposit 15 OKRW into the shielded pool

Larger balances (e.g. 10,000,000 OKRW) are held as many notes — split the amount across many deposits, each below the 64-bit cap.

import { createWalletClient, http, parseEther } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { iPrivacyAbi } from "@maroo-chain/contracts/abi/precompiles/privacy/IPrivacy";

const PRIVACY = "0x100000000000000000000000000000000000000b" as const;

const wallet = createWalletClient({
  account: privateKeyToAccount(process.env.USER_KEY as `0x${string}`),
  transport: http("https://rpc-testnet.maroo.io"),
});

// Stays under the 64-bit shielded cap (~18.446... OKRW per deposit).
await wallet.writeContract({
  address: PRIVACY,
  abi: iPrivacyAbi,
  functionName: "deposit",
  args: [request],
  value: parseEther("15"),
});

Handling the 64-bit shielded amount cap

The 64-bit shielded cap is enforced by the underlying ValidateShieldedAmount check, which now surfaces as InvalidAmount(string) after the shared-error refactor. Update any ABI fragment that previously declared it as InvalidAmount(uint256).

import { BaseError, ContractFunctionRevertedError, decodeErrorResult, parseEther } from "viem";
import { iPrivacyAbi } from "@maroo-chain/contracts/abi/precompiles/privacy/IPrivacy";

try {
  await wallet.writeContract({
    address: PRIVACY,
    abi: iPrivacyAbi,
    functionName: "deposit",
    args: [request],
    value: parseEther("20"), // above the 64-bit shielded cap — will revert
  });
} catch (err) {
  // viem keeps the revert data on the ContractFunctionRevertedError in the cause chain, not on err.
  const revert = err instanceof BaseError ? err.walk((e) => e instanceof ContractFunctionRevertedError) : null;
  if (!(revert instanceof ContractFunctionRevertedError) || !revert.raw) throw err;
  const decoded = decodeErrorResult({ abi: iPrivacyAbi, data: revert.raw });
  if (decoded.errorName === "InvalidAmount") {
    const [amount] = decoded.args as [string];
    console.warn(`deposit amount ${amount} exceeds 64-bit shielded cap — split across multiple notes`);
  } else {
    throw err;
  }
}
ESC
Type to search