@veil-cash/sdk
v0.6.2
Published
SDK and CLI for interacting with Veil Cash privacy pools - keypair generation, deposits, and status checking
Maintainers
Readme
@veil-cash/sdk
npm version npm downloads license
SDK and CLI for interacting with Veil Cash privacy pools on Base.
Generate keypairs, register, deposit, withdraw, transfer, and merge ETH and USDC privately.
0.6.2 adds mergeSubaccount — transfer a subaccount's private pool balance back to the main wallet via a ZK proof. Also adds veil subaccount merge CLI command.
0.6.0 adds SDK-first subaccount support for deterministic slot derivation, forwarder status, relay-backed deploy/sweep, and direct recovery.
Installation
npm install @veil-cash/sdk
# or
yarn add @veil-cash/sdk
# or
pnpm add @veil-cash/sdkFor global CLI access:
npm install -g @veil-cash/sdkAgent Skill
This repo includes a Veil agent skill at skills/veil/SKILL.md.
Quick mapping:
- npm package:
@veil-cash/sdk - CLI binary:
veil - agent skill file:
skills/veil/SKILL.md
If you are pointing an agent at this repo, send it to skills/veil/SKILL.md for the canonical CLI workflow.
If you install the npm package, the published package also includes the skills/ directory so the same skill can be discovered from the installed package contents.
Supported Assets
| Asset | Decimals | Token Contract |
| ----- | -------- | -------------------------------------------- |
| ETH | 18 | Native ETH (via WETH) |
| USDC | 6 | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 |
CLI Quick Start
The CLI is human-readable by default. Add --json when you want stable machine-readable output. --unsigned commands always emit transaction payload JSON for automation and agents.
# 1. Set your Ethereum wallet key
export WALLET_KEY=0x...
# 2. Derive and save your Veil keypair
veil init
# 3. Register your deposit key (one-time)
veil register
# 4. Check your setup
veil status
# 5. Deposit into the pool (amount is what arrives in your balance; fee added automatically)
veil deposit ETH 0.1
veil deposit USDC 100
# 6. Inspect balances
veil balance
veil balance --pool eth
veil balance queue --pool usdc
veil balance private
# 7. Use privacy actions
veil withdraw ETH 0.05 0xRecipientAddress
veil transfer ETH 0.02 0xRecipientAddress
veil merge ETH 0.1
# 8. Work with subaccounts
veil subaccount derive --slot 0
veil subaccount status --slot 0
veil subaccount deploy --slot 0
veil subaccount sweep --slot 0 --asset eth
veil subaccount merge --slot 0 --pool eth
veil subaccount recover --slot 0 --asset usdc --to 0xRecipientAddress --amount 25
# 9. Use JSON or unsigned modes when you need automation
veil status --json
veil deposit ETH 0.1 --unsigned
veil subaccount status --slot 0 --jsonCLI Tasks
Setup
Derive a Veil keypair from your wallet (default) or generate a random one:
veil init
veil init --generate
veil init --signature 0x...
veil init --force
veil init --no-save
veil init --jsonShow the current keypair from VEIL_KEY:
veil keypair
veil keypair --jsonCheck local configuration, registration, and relay health:
veil status
veil status --jsonveil status shows a Signing row that reflects the active mode: local (WALLET_KEY), external (SIGNER_ADDRESS), or not configured. It also shows the resolved address, public ETH balance when available, and registration state. For unsigned or agent flows, set SIGNER_ADDRESS to let veil status and balance commands resolve address and registration without a private key.
Registration and Deposits
Register or update your deposit key on-chain:
veil register
veil register --force
veil register --json
veil register --unsigned --address 0x...
SIGNER_ADDRESS=0x... veil register --unsignedIn --unsigned mode, --address is optional when SIGNER_ADDRESS is set. veil register --force checks on-chain state first and emits a changeDepositKey payload only if the address is already registered; otherwise it emits a normal register payload.
Deposit ETH or USDC into Veil. The amount you specify is the net amount that arrives in your Veil balance. The 0.3% protocol fee is calculated on-chain and added automatically:
veil deposit ETH 0.1 # 0.1 ETH lands in pool, ~0.1003 ETH sent
veil deposit USDC 100 # 100 USDC lands in pool, ~100.30 USDC sent
veil deposit ETH 0.1 --json
veil deposit ETH 0.1 --unsignedBalances
Show combined balances across queue and private pools:
veil balance
veil balance --pool eth
veil balance --pool usdc
veil balance --jsonInspect queue balances directly:
veil balance queue
veil balance queue --pool usdc
veil balance queue --address 0x... --jsonInspect private balances directly:
veil balance private
veil balance private --pool usdc
veil balance private --jsonPrivate Actions
Withdraw from the private pool to a public address:
veil withdraw ETH 0.05 0xRecipientAddress
veil withdraw USDC 50 0xRecipientAddress
veil withdraw ETH 0.05 0xRecipientAddress --jsonTransfer privately to another registered Veil user:
veil transfer ETH 0.02 0xRecipientAddress
veil transfer USDC 25 0xRecipientAddress
veil transfer ETH 0.02 0xRecipientAddress --jsonMerge small UTXOs into one:
veil merge ETH 0.1
veil merge USDC 100
veil merge ETH 0.1 --jsonSubaccounts
Subaccounts are deterministic child slots derived from your main VEIL_KEY:
root key -> slot -> child key -> child deposit key -> forwarder
Base mainnet only. Deploy and sweep are relay-backed. Merge transfers the subaccount's private pool balance back to the main wallet via a ZK proof. Status reports forwarder wallet balances, private pool balances, and queue state for the child slot. Recovery is for assets still sitting on the forwarder after refund or rejection, and is submitted directly on-chain by your CLI gas payer.
veil subaccount derive --slot 0
veil subaccount status --slot 0
veil subaccount address --slot 0
veil subaccount deploy --slot 0
veil subaccount sweep --slot 0 --asset eth
veil subaccount merge --slot 0 --pool eth
veil subaccount recover --slot 0 --asset usdc --to 0xRecipientAddress --amount 25
veil subaccount status --slot 0 --jsonEnvironment Variables
The CLI uses two config files:
| File | Purpose |
| ----------- | ---------------------------------------------------------------------------- |
| .env.veil | Veil keypair (VEIL_KEY, DEPOSIT_KEY) - created by veil init |
| .env | Wallet config (WALLET_KEY or SIGNER_ADDRESS, RPC_URL) - your existing config |
Variables
| Variable | Description |
| ---------------- | ---------------------------------------------------------------------------------------------- |
| VEIL_KEY | Your Veil private key (for ZK proofs, withdrawals, transfers) |
| DEPOSIT_KEY | Your Veil deposit key (public, for register/deposit) |
| WALLET_KEY | Ethereum wallet private key (for signing transactions) |
| SIGNER_ADDRESS | Ethereum address for unsigned/query flows when signing is handled externally |
| RPC_URL | Base RPC URL (optional, defaults to public RPC) |
| RELAY_URL | Override relay base URL for relayed CLI operations, subaccount deploy/sweep, and status checks |
WALLET_KEY and SIGNER_ADDRESS are mutually exclusive. Use WALLET_KEY for commands that sign transactions, and SIGNER_ADDRESS for address-only agent flows like status, balance, and register --unsigned.
Error Handling
Commands print human-readable success output by default. Errors are standardized JSON with machine-readable error codes so scripts can detect failure cases reliably:
{
"success": false,
"errorCode": "VEIL_KEY_MISSING",
"error": "VEIL_KEY required. Set VEIL_KEY env"
}Error Codes
| Code | Description |
| ---------------------- | --------------------------------- |
| VEIL_KEY_MISSING | VEIL_KEY not provided |
| WALLET_KEY_MISSING | WALLET_KEY not provided |
| DEPOSIT_KEY_MISSING | DEPOSIT_KEY not provided |
| CONFIG_CONFLICT | Conflicting CLI env vars provided |
| INVALID_ADDRESS | Invalid Ethereum address format |
| INVALID_SLOT | Invalid subaccount slot format |
| INVALID_AMOUNT | Invalid or below minimum amount |
| INSUFFICIENT_BALANCE | Not enough ETH balance |
| USER_NOT_REGISTERED | Recipient not registered in Veil |
| NO_UTXOS | No unspent UTXOs available |
| RELAY_ERROR | Error from relayer service |
| RPC_ERROR | RPC/network error |
| CONTRACT_ERROR | Smart contract reverted |
| UNKNOWN_ERROR | Unexpected error |
SDK Docs
The CLI is the main entrypoint for most users. If you are integrating Veil programmatically, use the dedicated SDK guide:
Deposit Flow
- Set Wallet Key:
export WALLET_KEY=0x...in your.envor shell - Derive Keypair: Run
veil initto derive and save your Veil keypair - Register: Run
veil registerto link your deposit key on-chain (one-time) - Check Status: Run
veil statusto verify your setup - Deposit: Run
veil deposit <asset> <amount>— the amount is what lands in your balance (e.g.,veil deposit ETH 0.1deposits 0.1 ETH; the 0.3% fee is added automatically) - Wait: The Veil deposit engine processes your deposit
- Done: Your deposit is accepted into the privacy pool
Withdrawal Flow
- Check Balance: Run
veil balance --pool <pool>to see your private balance - Withdraw: Run
veil withdraw <asset> <amount> <recipient> - Done: The SDK builds ZK proofs and submits via the relayer
License
MIT
