Page cover

ℹ️Quick Deposit

Deposit into Veil Cash from any wallet

Overview

Quick Deposit is a convenience feature that allows users to send ETH directly to verified addresses without needing to be a verified themselves or to have build ZK proves on the frontend.

Quick deposit can be used to move funds without an onchain link between a users own addresses

Use Cases

  • Veil users can deposit into Veil from other non verified wallets

  • Depositing into Veil via mini app on Farcaster or Base App

  • Allows third party dApps and agents to integrate into Veil Cash

How does it work?

Instead of having the user build the deposit proof on the Veil Cash frontend, for quick deposits the proof is built by a backend engine. Because the proof is built by Veil, it can be checked that the destination address passes as a Verified Users. This allows deposits from wallets that have not registered or verified previously.

Steps to use

  1. Connect wallet (can be any EVM)

  2. Enter amount — Minimum 0.001 ETH

  3. Enter recipient address (Must be registered and verified)

Veil frontend will check that the address passes both checks, encrypt the recipient to avoid an onchain link and allows the users to deposit into the queue contract.

The recipient of the deposit is encrypted to preserve onchain privacy

Veil Backend Engine

Once a deposit is made, it passed into Queue Contract. Veil backend engine checks for deposits every 60 seconds. Once found:

  • Recipient deposit address / key is decrypted

  • Address is validated as registered and verified

  • ZK Proof is built and deposit is relayed into the Veil Pool

If a deposit fails these checks, it is refunded automatically back to the deposit address.


Integration and Docs

Third party apps can forward ETH to the deposit queue and they will be processed just like a deposit from the frontend. The Veil API provides endpoints for managing deposit preparation. The API handles address verification, registration status checks, and deposit key encryption in a streamlined manner.

Prepare Deposit Endpoint

Endpoint: GET /v1/address/prepareDeposit

Description: A comprehensive endpoint that performs all necessary checks and preparations for deposit operations. This endpoint:

  1. Validates the provided Ethereum address format

  2. Checks if the address is verified on-chain

  3. Checks if the address is registered for deposits

  4. If both conditions are met, retrieves and encrypts the deposit key

Parameters:

Parameter
Type
Required
Description

address

string

Yes

Valid Ethereum address (0x format, 40 characters)

Example Request:

"http://api.veil.cash/v1/address/prepareDeposit?address=0x777c47498b42dbe449fB4cB810871A46cD777777"

Response Schemas

Success Response (Ready for Deposit)

Status Code: 200 OK

Response Body:

{
  "address": "0x777c47498b42dbe449fB4cB810871A46cD777777",
  "result": "success",
  "isVerified": true,
  "isRegistered": true,
  "message": "encrypted deposit key generated",
  "depositKey": "0x13c400eff26354716592f5f56300cebd3f432889f06db664fa59bac1cfc48d247606b69ad5a22d34c9cea8bd9d33279af7276fade2210d6f8a4a4b5342a49812",
  "encryptedDepositKey": "0x7b2276657273696f6e223a227832353531392d7873616c736132302d706f6c7931333035222c226e6f6e6365223a2241437a3947323350356f4e6d6a76316356496e2f5179305346436c6177666b61222c22657068656d5075626c69634b6579223a224459594557726d574f5a6c52572f2b5844547431313967437367703953524c44674e4e7839524d6f6342383d222c2263697068657274657874223a2231594437763678615a777255432b386e447a62324e537769653932623546392f6f6e5464725141304d4e4f596153747a772f76544733657a50484b4636554167597237",
  "timestamp": "2025-09-02T10:06:05.398Z",
  "network": "Base"
}

Contract Call

Queue Contract address

Deposit Contract

After successfully calling the prepareDeposit API endpoint and receiving the encrypted deposit key, users need to interact with the deposit smart contract to complete their deposit.

The contract exposes a queueDeposit function for making deposits:

Contract Address: 0x2797Ee4bD08f97fad3015AA4C7183a28D2f60bb6 (Base Mainnet)

Function Signature

/// @notice Queue a deposit with a deposit key
function queueDeposit(bytes calldata _depositKey) external payable

Contract ABI

{
  "inputs": [
    {
      "internalType": "bytes",
      "name": "_depositKey", 
      "type": "bytes"
    }
  ],
  "name": "queueDeposit",
  "outputs": [],
  "stateMutability": "payable",
  "type": "function"
}

Parameters:

  • _depositKey: The encrypted deposit key obtained from the API (as bytes)

Integration Flow

  1. Call API to prepare deposit and get encrypted key

  2. Call contract with the encrypted key with ETH amount

Example Transaction Data:

To: 0x2797Ee4bD08f97fad3015AA4C7183a28D2f60bb6
Value: 100000000000000000 (0.1 ETH in wei)
Data: queueDeposit(0x7b2276657273696f6e223a227832353531392d7873616c736132302d706f6c7931333035)


Further Reading

Privacy & Encryption

When you make a deposit using the encrypted deposit key, the recipient address is encrypted and stored securely on the Veil server.

This encrypted recipient information is made available through this API endpoint, ensuring that deposit routing can occur while maintaining privacy.

Schema for successful responses

type: object
properties:
  address:
    type: string
    description: The Ethereum address that was checked
    example: "0x777c47498b42dbe449fB4cB810871A46cD777777"
  result:
    type: string
    enum: [success]
    description: Operation result status
  isVerified:
    type: boolean
    description: Whether the address is verified on-chain
    example: true
  isRegistered:
    type: boolean
    description: Whether the address is registered for deposits
    example: true
  message:
    type: string
    description: Human-readable status message
    example: "encrypted deposit key generated"
  depositKey:
    type: string
    description: The raw deposit key for the address
    example: "0x13c400eff26354716592f5f56300cebd3f432889f06db664fa59bac1cfc48d247606b69ad5a22d34c9cea8bd9d33279af7276fade2210d6f8a4a4b5342a49812"
  encryptedDepositKey:
    type: string
    description: The deposit key encrypted with the backend's public key (hex-encoded JSON)
    example: "0x7b2276657273696f6e223a227832353531392d7873616c736132302d706f6c7931333035222c226e6f6e6365223a2241437a3947323350356f4e6d6a76316356496e2f5179305346436c6177666b61222c22657068656d5075626c69634b6579223a224459594557726d574f5a6c52572f2b5844547431313967437367703953524c44674e4e7839524d6f6342383d222c2263697068657274657874223a2231594437763678615a777255432b386e447a62324e537769653932623546392f6f6e5464725141304d4e4f596153747a772f76544733657a50484b4636554167597237..."
  timestamp:
    type: string
    format: date-time
    description: ISO 8601 timestamp of the response
  network:
    type: string
    description: The blockchain network
    example: "Base"
required:
  - address
  - result
  - isVerified
  - isRegistered
  - message
  - timestamp
  - network

Failed Response (Not Verified)

Status Code: 200 OK

Response Body:

{
  "address": "0x1234567890123456789012345678901234567890",
  "result": "failed",
  "isVerified": false,
  "isRegistered": false,
  "message": "Address is not verified for deposits",
  "depositKey": null,
  "encryptedDepositKey": null,
  "timestamp": "2025-09-02T10:06:11.815Z",
  "network": "Base"
}

Failed Response (Verified but Not Registered)

Status Code: 200 OK

Response Body:

{
  "address": "0x1234567890123456789012345678901234567890",
  "result": "failed",
  "isVerified": true,
  "isRegistered": false,
  "message": "Address is verified but not registered for deposits",
  "depositKey": null,
  "encryptedDepositKey": null,
  "timestamp": "2025-09-02T10:06:11.815Z",
  "network": "Base"
}

Error Response (Invalid Address)

Status Code: 400 Bad Request

Response Body:

{
  "isVerified": false,
  "isRegistered": false,
  "error": "Invalid address format",
  "address": "invalid",
  "network": "Base",
  "timestamp": "2025-09-02T10:06:16.819Z"
}

Error Response (Server Error)

Status Code: 500 Internal Server Error

Response Body:

{
  "address": "0x1234567890123456789012345678901234567890",
  "result": "error",
  "isVerified": false,
  "isRegistered": false,
  "message": "Failed to prepare deposit",
  "error": "Failed to prepare deposit",
  "details": "Specific error message",
  "depositKey": null,
  "encryptedDepositKey": null,
  "timestamp": "2025-09-02T10:06:16.819Z",
  "network": "Base"
}

Schema for Failed Responses:

type: object
properties:
  address:
    type: string
    description: The Ethereum address that was checked
  result:
    type: string
    enum: [failed]
    description: Operation result status
  isVerified:
    type: boolean
    description: Whether the address is verified on-chain
  isRegistered:
    type: boolean
    description: Whether the address is registered for deposits
  message:
    type: string
    description: Human-readable explanation of why the operation failed
    enum: 
      - "Address is not verified for deposits"
      - "Address is verified but not registered for deposits"
  depositKey:
    type: null
    description: Always null for failed responses
  encryptedDepositKey:
    type: null
    description: Always null for failed responses
  timestamp:
    type: string
    format: date-time
    description: ISO 8601 timestamp of the response
  network:
    type: string
    description: The blockchain network
    example: "Base"
required:
  - address
  - result
  - isVerified
  - isRegistered
  - message
  - depositKey
  - encryptedDepositKey
  - timestamp
  - network

Last updated