npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@veil-cash/sdk

v0.3.0

Published

SDK and CLI for interacting with Veil Cash privacy pools - keypair generation, deposits, and status checking

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, USDC, and cbBTC privately.

Installation

npm install @veil-cash/sdk
# or
yarn add @veil-cash/sdk
# or
pnpm add @veil-cash/sdk

For global CLI access:

npm install -g @veil-cash/sdk

Supported Assets

| Asset | Decimals | Token Contract | |-------|----------|---------------| | ETH | 18 | Native ETH (via WETH) | | USDC | 6 | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 | | cbBTC | 8 | 0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf |

CLI Quick Start

# 1. Generate and save your Veil keypair
veil init

# 2. Set your Ethereum wallet key (for signing transactions)
export WALLET_KEY=0x...

# 3. Register your deposit key (one-time)
veil register

# 4. Check your setup
veil status

# 5. Deposit (ETH, USDC, or cbBTC)
veil deposit ETH 0.1
veil deposit USDC 100
veil deposit CBBTC 0.001

# 6. Check your balance
veil balance                  # ETH pool (default)
veil balance --pool usdc      # USDC pool
veil balance --pool cbbtc       # cbBTC pool

# 7. Withdraw to any address
veil withdraw ETH 0.05 0xRecipientAddress
veil withdraw USDC 50 0xRecipientAddress
veil withdraw CBBTC 0.0005 0xRecipientAddress

# 8. Transfer privately to another registered user
veil transfer ETH 0.02 0xRecipientAddress

# 9. Merge small UTXOs (consolidate balances)
veil merge ETH 0.1

CLI Commands

veil init

Generate or derive a Veil keypair.

veil init                                  # Random keypair, saves to .env.veil
veil init --force                          # Overwrite existing without prompting
veil init --json                           # Output as JSON (no prompts, no file save)
veil init --no-save                        # Print keypair without saving

# Derive from wallet (same keypair as frontend login)
veil init --sign-message --wallet-key 0x...

# Derive from a pre-computed EIP-191 signature (from Bankr, MPC, etc.)
veil init --signature 0x...

veil keypair

Show current Veil keypair as JSON (from VEIL_KEY env).

veil keypair
# {"veilPrivateKey":"0x...","depositKey":"0x..."}

veil status

Check configuration and service status.

veil status

Output:

{
  "walletKey": { "found": true, "address": "0x..." },
  "veilKey": { "found": true },
  "depositKey": { "found": true, "key": "0x1234...abcd" },
  "rpcUrl": { "found": false, "url": "https://mainnet.base.org" },
  "registration": {
    "checked": true,
    "registered": true,
    "matches": true,
    "onChainKey": "0x..."
  },
  "relay": {
    "checked": true,
    "healthy": true,
    "status": "ok",
    "network": "mainnet"
  }
}

veil register

Register or update your deposit key on-chain.

veil register                              # Register (first time)
veil register --json                       # JSON output
veil register --unsigned --address 0x...   # Unsigned payload for agents

# Change deposit key (if already registered with a different key)
veil register --force                      # Change to local deposit key
veil register --force --unsigned           # Unsigned change payload for agents

If already registered with the same key, the command exits successfully. If registered with a different key (e.g. after veil init --sign-message), use --force to update it on-chain.

veil deposit <asset> <amount>

Deposit ETH, USDC, or cbBTC into the privacy pool. For USDC and cbBTC, the CLI automatically handles ERC20 approval before depositing.

veil deposit ETH 0.1                    # Deposit ETH
veil deposit USDC 100                   # Approve + deposit USDC
veil deposit CBBTC 0.001                  # Approve + deposit cbBTC
veil deposit ETH 0.1 --unsigned         # Unsigned payload for agents
veil deposit ETH 0.1 --quiet            # Suppress progress output

Output:

{
  "success": true,
  "hash": "0x...",
  "asset": "ETH",
  "amount": "0.1",
  "blockNumber": "12345678",
  "gasUsed": "150000"
}

veil balance

Show both queue and private balances.

veil balance                        # ETH pool (default)
veil balance --pool usdc            # USDC pool
veil balance --pool cbbtc             # cbBTC pool
veil balance --quiet                # Suppress progress output

Output:

{
  "address": "0x...",
  "pool": "ETH",
  "symbol": "ETH",
  "depositKey": "0x...",
  "totalBalance": "0.15",
  "totalBalanceWei": "150000000000000000",
  "private": {
    "balance": "0.10",
    "balanceWei": "100000000000000000",
    "utxoCount": 2,
    "utxos": [
      { "index": 5, "amount": "0.05" },
      { "index": 8, "amount": "0.05" }
    ]
  },
  "queue": {
    "balance": "0.05",
    "balanceWei": "50000000000000000",
    "count": 1,
    "deposits": [
      { "nonce": 42, "amount": "0.05", "status": "pending" }
    ]
  }
}

veil withdraw <asset> <amount> <recipient>

Withdraw from the privacy pool to any public address.

veil withdraw ETH 0.05 0xRecipientAddress
veil withdraw USDC 50 0xRecipientAddress
veil withdraw CBBTC 0.0005 0xRecipientAddress
veil withdraw ETH 0.05 0xRecipientAddress --quiet

Output:

{
  "success": true,
  "transactionHash": "0x...",
  "blockNumber": 12345678,
  "asset": "ETH",
  "amount": "0.05",
  "recipient": "0x..."
}

veil transfer <asset> <amount> <recipient>

Transfer privately to another registered Veil user.

veil transfer ETH 0.02 0xRecipientAddress
veil transfer USDC 25 0xRecipientAddress
veil transfer CBBTC 0.0002 0xRecipientAddress
veil transfer ETH 0.02 0xRecipientAddress --quiet

Output:

{
  "success": true,
  "transactionHash": "0x...",
  "blockNumber": 12345678,
  "asset": "ETH",
  "amount": "0.02",
  "recipient": "0x...",
  "type": "transfer"
}

veil merge <asset> <amount>

Consolidate multiple small UTXOs into one (self-transfer).

veil merge ETH 0.1                      # Merge ETH UTXOs totaling 0.1 ETH
veil merge USDC 100                     # Merge USDC UTXOs
veil merge CBBTC 0.001                    # Merge cbBTC UTXOs
veil merge ETH 0.1 --quiet

Output:

{
  "success": true,
  "transactionHash": "0x...",
  "blockNumber": 12345678,
  "asset": "ETH",
  "amount": "0.1",
  "type": "merge"
}

Environment 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, 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) | | RPC_URL | Base RPC URL (optional, defaults to public RPC) |

Error Handling

All CLI commands output JSON with standardized error codes:

{
  "success": false,
  "errorCode": "VEIL_KEY_MISSING",
  "error": "VEIL_KEY required. Use --veil-key or 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 | | INVALID_ADDRESS | Invalid Ethereum address 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 Quick Start

import {
  Keypair, buildRegisterTx, buildDepositETHTx,
  buildDepositUSDCTx, buildApproveUSDCTx,
  buildDepositCBBTCTx, buildApproveCBBTCTx,
  withdraw, transfer,
} from '@veil-cash/sdk';
import { createWalletClient, http } from 'viem';
import { base } from 'viem/chains';
import { privateKeyToAccount } from 'viem/accounts';

// 1. Generate a Veil keypair (do this once, save securely!)
const keypair = new Keypair();
console.log('Veil Private Key:', keypair.privkey);  // SAVE THIS!
console.log('Deposit Key:', keypair.depositKey());  // Register this on-chain

// 2. Setup your Ethereum wallet
const account = privateKeyToAccount('0x...');
const client = createWalletClient({
  account,
  chain: base,
  transport: http(),
});

// 3. Register your deposit key (one-time)
const registerTx = buildRegisterTx(keypair.depositKey(), account.address);
await client.sendTransaction(registerTx);

// 4. Deposit ETH
const depositTx = buildDepositETHTx({
  depositKey: keypair.depositKey(),
  amount: '0.1',
});
await client.sendTransaction({ ...depositTx, value: depositTx.value });

// 4b. Deposit USDC (approve first)
const approveTx = buildApproveUSDCTx({ amount: '100' });
await client.sendTransaction(approveTx);
const usdcTx = buildDepositUSDCTx({
  depositKey: keypair.depositKey(),
  amount: '100',
});
await client.sendTransaction(usdcTx);

// 4c. Deposit cbBTC (approve first)
const approveCbbtcTx = buildApproveCBBTCTx({ amount: '0.001' });
await client.sendTransaction(approveCbbtcTx);
const cbbtcTx = buildDepositCBBTCTx({
  depositKey: keypair.depositKey(),
  amount: '0.001',
});
await client.sendTransaction(cbbtcTx);

// 5. Withdraw (sent via relayer, no wallet signing needed)
const withdrawResult = await withdraw({
  amount: '0.05',
  recipient: '0xRecipientAddress',
  keypair,
  pool: 'eth', // 'eth' | 'usdc' | 'cbbtc' (default: 'eth')
});

// 6. Transfer privately
const transferResult = await transfer({
  amount: '0.02',
  recipientAddress: '0xRecipientAddress',
  senderKeypair: keypair,
  pool: 'eth', // 'eth' | 'usdc' | 'cbbtc' (default: 'eth')
});

SDK API Reference

Keypair

import { Keypair, VEIL_SIGNED_MESSAGE } from '@veil-cash/sdk';
import type { MessageSigner } from '@veil-cash/sdk';

// Generate random keypair
const keypair = new Keypair();

// Restore from saved Veil private key
const restored = new Keypair(savedVeilKey);

// Derive from wallet key (same keypair as frontend login)
const derived = await Keypair.fromWalletKey('0xYOUR_WALLET_KEY');

// Derive from a raw EIP-191 signature
const fromSig = Keypair.fromSignature('0xSIGNATURE...');

// Derive from any external signer (Bankr, MPC, custodial, etc.)
const fromSigner = await Keypair.fromSigner(async (message) => {
  // Sign `message` using any personal_sign provider and return the signature
  return await mySigningService.personalSign(message);
});

// Get deposit key (for registration)
keypair.depositKey(); // '0x...' (130 hex chars)

// Veil private key (store securely!)
keypair.privkey; // '0x...'

Transaction Builders

import {
  buildRegisterTx, buildChangeDepositKeyTx, buildDepositETHTx, buildDepositTx,
  buildDepositUSDCTx, buildApproveUSDCTx,
  buildDepositCBBTCTx, buildApproveCBBTCTx,
} from '@veil-cash/sdk';

// Register deposit key (first time)
const registerTx = buildRegisterTx(depositKey, ownerAddress);
// → { to: '0x...', data: '0x...' }

// Change deposit key (must already be registered)
const changeTx = buildChangeDepositKeyTx(newDepositKey, ownerAddress);
// → { to: '0x...', data: '0x...' }

// Deposit ETH
const depositTx = buildDepositETHTx({
  depositKey: keypair.depositKey(),
  amount: '0.1',
});
// → { to: '0x...', data: '0x...', value: 100000000000000000n }

// Deposit USDC (approve + deposit)
const approveUsdcTx = buildApproveUSDCTx({ amount: '100' });
const depositUsdcTx = buildDepositUSDCTx({
  depositKey: keypair.depositKey(),
  amount: '100',
});

// Deposit cbBTC (approve + deposit)
const approveCbbtcTx = buildApproveCBBTCTx({ amount: '0.001' });
const depositCbbtcTx = buildDepositCBBTCTx({
  depositKey: keypair.depositKey(),
  amount: '0.001',
});

// Generic builder (routes by token)
const tx = buildDepositTx({
  depositKey: keypair.depositKey(),
  amount: '0.1',
  token: 'ETH', // 'ETH' | 'USDC' | 'CBBTC'
});

Withdraw & Transfer

All withdraw, transfer, and merge functions accept an optional pool parameter ('eth' | 'usdc' | 'cbbtc'), defaulting to 'eth'.

import { withdraw, transfer, mergeUtxos } from '@veil-cash/sdk';

// Withdraw ETH to public address
const withdrawResult = await withdraw({
  amount: '0.05',
  recipient: '0xRecipientAddress',
  keypair,
  pool: 'eth', // default
  onProgress: (stage, detail) => console.log(stage, detail),
});

// Withdraw USDC
const withdrawUsdc = await withdraw({
  amount: '50',
  recipient: '0xRecipientAddress',
  keypair,
  pool: 'usdc',
});

// Transfer cbBTC to another registered user
const transferResult = await transfer({
  amount: '0.0002',
  recipientAddress: '0xRecipientAddress',
  senderKeypair: keypair,
  pool: 'cbbtc',
});

// Merge UTXOs (consolidate small balances)
const mergeResult = await mergeUtxos({
  amount: '0.1',
  keypair,
  pool: 'eth',
});

Balance Queries

Balance functions accept an optional pool parameter ('eth' | 'usdc' | 'cbbtc'), defaulting to 'eth'.

import { getQueueBalance, getPrivateBalance } from '@veil-cash/sdk';

// Check ETH queue balance (pending deposits)
const queueBalance = await getQueueBalance({
  address: '0x...',
  pool: 'eth', // default
});

// Check USDC private balance (requires keypair)
const privateBalance = await getPrivateBalance({
  keypair,
  pool: 'usdc',
});

// Check cbBTC private balance
const btcBalance = await getPrivateBalance({
  keypair,
  pool: 'cbbtc',
});

Addresses

import { getAddresses, getPoolAddress, getQueueAddress } from '@veil-cash/sdk';

const addresses = getAddresses();
console.log(addresses.entry);     // Entry contract
console.log(addresses.ethPool);   // ETH pool
console.log(addresses.usdcPool);  // USDC pool
console.log(addresses.cbbtcPool);   // cbBTC pool

// Helper functions to resolve by pool name
console.log(getPoolAddress('eth'));   // ETH pool address
console.log(getPoolAddress('usdc')); // USDC pool address
console.log(getPoolAddress('cbbtc'));  // cbBTC pool address
console.log(getQueueAddress('cbbtc')); // cbBTC queue address

For AI Agents

This SDK is designed to work with AI agent frameworks like Bankr.

Non-Interactive CLI

All commands output JSON and support non-interactive usage:

# Generate keypair as JSON (no prompts, no file save)
veil init --json

# Get unsigned transaction payloads for agent signing
veil register --unsigned --address 0x...
veil deposit ETH 0.1 --unsigned
veil deposit USDC 100 --unsigned    # Outputs approve + deposit payloads
veil deposit CBBTC 0.001 --unsigned

# Suppress progress output for clean JSON
veil balance --quiet
veil balance --pool usdc --quiet
veil withdraw ETH 0.05 0xRecipient --quiet

Bankr Integration

Keypair Derivation via Bankr Sign API

Use Keypair.fromSigner() with Bankr's POST /agent/sign endpoint to derive the same keypair as the frontend:

import { Keypair } from '@veil-cash/sdk';

const keypair = await Keypair.fromSigner(async (message) => {
  const res = await fetch('https://api.bankr.bot/agent/sign', {
    method: 'POST',
    headers: { 'X-API-Key': BANKR_API_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({ signatureType: 'personal_sign', message }),
  });
  return (await res.json()).signature;
});

Or via CLI (two-step):

# 1. Get signature from Bankr sign API
SIG=$(curl -s -X POST "https://api.bankr.bot/agent/sign" \
  -H "X-API-Key: $BANKR_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"signatureType\":\"personal_sign\",\"message\":\"$(node -e "const{VEIL_SIGNED_MESSAGE}=require('@veil-cash/sdk');console.log(VEIL_SIGNED_MESSAGE)")\"}" \
  | jq -r '.signature')

# 2. Derive keypair from signature
veil init --signature $SIG

Unsigned Transaction Payloads

Use --unsigned to get Bankr-compatible transaction payloads:

veil deposit ETH 0.1 --unsigned
# {"to":"0x...","data":"0x...","value":"100000000000000000","chainId":8453}

The --unsigned flag outputs the Bankr arbitrary transaction format.

Programmatic SDK Usage

import { Keypair, buildDepositETHTx, buildDepositTx, withdraw } from '@veil-cash/sdk';

// For deposits: build transaction, let agent sign via Bankr
const keypair = new Keypair(veilKey);
const tx = buildDepositETHTx({
  depositKey: keypair.depositKey(),
  amount: '0.1',
});
// → { to, data, value } - pass to Bankr for signing

// Generic builder works for any asset
const usdcTx = buildDepositTx({
  depositKey: keypair.depositKey(),
  amount: '100',
  token: 'USDC',
});

// For withdrawals: SDK handles ZK proofs, submits to relayer
const result = await withdraw({
  amount: '0.05',
  recipient: '0xRecipient',
  keypair,
  pool: 'eth', // 'eth' | 'usdc' | 'cbbtc'
});
// → { success, transactionHash, blockNumber }

Deposit Flow

  1. Generate Keypair: Run veil init to create and save your Veil keypair
  2. Register: Run veil register to link your deposit key on-chain (one-time)
  3. Check Status: Run veil status to verify your setup
  4. Deposit: Run veil deposit <asset> <amount> (e.g., veil deposit ETH 0.1, veil deposit USDC 100, veil deposit CBBTC 0.001)
  5. Wait: The Veil deposit engine processes your deposit
  6. Done: Your deposit is accepted into the privacy pool

Withdrawal Flow

  1. Check Balance: Run veil balance --pool <pool> to see your private balance
  2. Withdraw: Run veil withdraw <asset> <amount> <recipient>
  3. Done: The SDK builds ZK proofs and submits via the relayer

License

MIT