A TypeScript interface for Aleo, inspired by viem. Wraps existing Aleo wallets and SDKs behind a unified, familiar API — for human developers and AI agents alike.
Aleo allows users privacy in their assets and data and allows developers to build privacy into their Dapps.
Veil provides semantics familiar to what EVM developers and agents expect. If you've built on Ethereum with viem, you already know how to use veil — same patterns, same method names, applied to Aleo.
import { createPublicClient, createWalletClient, http } from '@provablehq/veil-core'
import { fromWalletAdapter } from '@provablehq/veil-aleo-wallet-adapter'
// A read-only client — point a transport at an Aleo node (viem's createPublicClient).
const client = createPublicClient({
transport: http('https://api.provable.com/v2'),
})
// Similar method names as in viem, now reading Aleo state.
const height = await client.getBlockNumber() // current chain height
const balance = await client.getBalance({ address: 'aleo1...' }) // public credits
// readContract reads a program mapping: mapping[key] in `credits.aleo`.
const value = await client.readContract({
programId: 'credits.aleo',
mapping: 'account',
key: 'aleo1...',
})
// For writes, a wallet client pairs a transport with an account — same as viem.
// A connected wallet supplies both; a local key path uses @provablehq/veil-aleo-sdk.
const { account, transport } = fromWalletAdapter(walletAdapter)
const wallet = createWalletClient({ account, transport })
// writeContract mirrors viem: name the program + function, pass typed inputs.
const txId = await wallet.writeContract({
program: 'my_program.aleo',
function: 'transfer',
inputs: ['aleo1...', '100u64'],
})👛 Wallet-connected dApps — browser apps where a user's wallet (Shield, Leo, Puzzle, Fox) holds the keys and proves. (@provablehq/veil-aleo-react-hooks)
🔭 Explorers, dashboards, and indexers — read blocks, transactions, mappings, staking, and network metrics with no keys and no proving. (@provablehq/veil-core)
💸 Payments and token flows — public or private credit transfers and ARC-0020 tokens, including confidential transfers.
📈 Shield Swap trading — private swaps, liquidity, and pool/price reads, from a frontend, a programmatic bot, or an agent. (@provablehq/shield-swap-sdk)
🤖 AI agents that use Aleo — expose Aleo as MCP tools or drop tool schemas into any agent framework; agents can also write viem-style code directly. (@provablehq/veil-core/agent, @provablehq/veil-core/mcp)
🖥️ Servers, CLIs, and custodial services — hold a private key and sign and prove locally, unattended. (@provablehq/veil-aleo-sdk)
📜 Typed clients for your own contracts — generate bindings from a program ABI and call it with typed reads and writes. (@provablehq/veil-codegen, getContract)
🦁 Leo program pipelines — build, deploy, and test programs against a local node, including in CI. (@provablehq/veil-leo, @provablehq/veil-aleo-devnode)
⚡ Viem-compatible API — getBalance, readContract, writeContract, deployContract, sendTransaction, signMessage, and more
🧩 Interface-first — core has zero hard dependencies on any SDK. Wallets and SDKs plug in via adapter packages.
🔑 Multiple account types — RPC accounts (wallet adapters), local accounts (private key, mnemonic), view-only accounts
🔌 Pluggable transports — http() for Aleo REST API, custom() for injected providers, fallback() for chaining
📜 Contract instances — getContract() parses Aleo program source and provides typed read/write methods
🔏 Proving as configuration — proving strategy is a client config concern (delegated or local), not a separate abstraction
🤖 Agent-first — every action ships with an MCP tool, agent tool schema, and structured JSON output. AI agents can call Aleo directly via tool use or write code against the library using viem patterns they already know.
@provablehq/veil-core is the base — every other package builds on its client, action,
and transport interfaces.
| Package | What it's for | When to reach for it |
|---|---|---|
@provablehq/veil-core |
Clients, actions, transports, types — the base SDK. Also ships LLM agent (/agent) and MCP (/mcp) bindings. |
Every Veil project — reading or writing Aleo, or as the base you extend. |
@provablehq/veil-aleo-sdk |
Local accounts, signing, and proving via @provablehq/sdk. Build a client from a private key. |
Your code holds a private key and must sign and prove itself — bots, servers, CLIs, tests. |
@provablehq/veil-aleo-wallet-adapter |
Bridge any Provable-standard wallet (Shield, Leo, Puzzle, Fox) into a Veil client. | You need wallet signing outside React, or a custom (non-React) wallet integration. |
@provablehq/veil-aleo-react-hooks |
VeilProvider + useVeilWallet() — wallet connection and clients for React apps. |
You're building a React dApp with wallet connection. |
@provablehq/shield-swap-sdk |
Client for the shield_swap AMM/DEX — private swaps, liquidity, and the DEX API. |
You're integrating the Shield Swap DEX — swaps, liquidity, or pool/price data. |
@provablehq/shield-swap-cli |
The shield-swap command — setup, pools, balances, swaps, and liquidity from a terminal. |
You want to trade or script against the DEX rather than build a client into an app. |
@provablehq/veil-codegen |
Generate typed bindings from an Aleo program ABI (library + veil-codegen CLI). |
You want typed reads and writes for a specific program's ABI. |
@provablehq/veil-aleo-devnode |
Run and drive a local Aleo devnode for tests. | You need a local Aleo node in tests or local development. |
@provablehq/veil-leo |
Typed wrapper around the leo CLI (build, deploy, …). |
You compile or deploy Leo programs — including during testing, where it pairs with @provablehq/veil-aleo-devnode. |
@provablehq/aleo-bridge-sdk |
Cross-chain bridge client (preview). | Not yet — in preview, not published. |
import { createPublicClient, http } from '@provablehq/veil-core'
const client = createPublicClient({
transport: http('https://api.provable.com/v2'),
})
// Familiar viem-style actions
const height = await client.getBlockNumber()
const block = await client.getBlock({ height: 1000 })
const tx = await client.getTransaction({ id: 'at1...' })
const balance = await client.getBalance({ address: 'aleo1...' })
const source = await client.getCode({ programId: 'credits.aleo' })
const value = await client.readContract({
programId: 'credits.aleo',
mapping: 'account',
key: 'aleo1...',
})import { createWalletClient } from '@provablehq/veil-core'
import { fromWalletAdapter } from '@provablehq/veil-aleo-wallet-adapter'
const { account, transport } = fromWalletAdapter(walletAdapter)
const client = createWalletClient({ account, transport })
// writeContract or its alias executeTransaction
await client.writeContract({
program: 'my_program.aleo',
function: 'transfer',
inputs: ['aleo1...', '100u64'],
fee: 1000n,
})
await client.deployContract({
program: myProgramSource,
fee: 5000n,
})
await client.transfer({
to: 'aleo1...',
amount: 1_000_000n,
})import { loadNetwork } from '@provablehq/veil-aleo-sdk'
// loadNetwork builds the account, proving, and clients from a private key.
const aleo = await loadNetwork('testnet')
const { publicClient, walletClient } = aleo.createAleoClient({
privateKey: 'APrivateKey1...',
networkUrl: 'https://api.provable.com/v2',
provingMode: 'delegated', // or 'local' to prove in-process
proverUrl: 'https://api.provable.com/prove/testnet',
})import { getContract } from '@provablehq/veil-core'
const contract = getContract({
programSource: tokenProgramSource,
client: { public: publicClient, wallet: walletClient },
})
// Typed read/write from parsed program source
const balance = await contract.read.balances({ key: 'aleo1...' })
const txId = await contract.write.transfer({
inputs: ['aleo1...', '100u64'],
fee: 1000n,
})import { createPublicClient, http, viewOnlyAccount } from '@provablehq/veil-core'
const client = createPublicClient({
transport: http('https://api.provable.com/v2'),
})
const account = viewOnlyAccount({
address: 'aleo1...',
viewKey: 'AViewKey1...',
})
// Use the view key to decrypt records without signing authority@provablehq/aleo-bridge-sdk assigns each supported asset family to a
protocol: Circle xReserve for USDCx, and Hyperlane Warp Routes for ETH, WBTC,
SOL, ALEO, and USAD. The package is in preview. Its current foundation exposes
a versioned route registry and non-fund-moving transfer plans; transaction
execution is under development.
import { createBridgeClient } from '@provablehq/aleo-bridge-sdk'
const bridge = createBridgeClient({ environment: 'mainnet' })
const [route] = bridge.getRoutes({
protocol: 'xreserve',
sourceChainId: 'ethereum',
destinationChainId: 'aleo',
})
const plan = bridge.prepareTransfer({
routeId: route.id,
amount: '25',
recipient: aleoAddress,
})
plan.steps // approve → deposit → wait-attestation → mintprepareTransfer validates the route, amount precision, and recipient without
querying fees, signing, submitting, or moving funds. See
packages/bridge/README.md for registry status
and the remaining execution phases.
veil is designed for two audiences equally: human developers who write code against the TypeScript library, and AI agents that either write code using viem patterns or call tools directly.
Run the MCP server to expose all veil actions as tools:
import { createMcpServer } from '@provablehq/veil-core/mcp'
import { createPublicClient, http } from '@provablehq/veil-core'
const client = createPublicClient({
transport: http('https://api.provable.com/v2'),
})
await createMcpServer({ client })Agents can then call tools like aleo_get_balance, aleo_read_mapping, aleo_execute, aleo_describe_program, etc. All tools return structured JSON with parsed Aleo values.
Use agent tool schemas and handlers directly in any agent framework:
import { aleoAgentTools } from '@provablehq/veil-core/agent'
const tools = aleoAgentTools({
client: publicClient,
walletClient: walletClient,
})
// Each tool has { schema, handler } — plug into LangChain, Vercel AI SDK, etc.Code-writing agents use the TypeScript library directly. Since it follows viem patterns, agents trained on viem can use it with minimal guidance. Key differences from viem that agents should know:
- Programs are identified by name (
'credits.aleo'), not address - Inputs are Aleo-encoded strings (
'100u64'), not hex — useencodeValue(100n, 'u64') - Use
describeProgramto discover what a program can do before calling it writeContracthas an aliasexecuteTransactionconsistent with Aleo wallet adapter terminology
All values are returned as structured JSON rather than Aleo's native string encoding:
import { parseValue, encodeValue } from '@provablehq/veil-core'
parseValue('100u64') // → { value: 100n, type: 'u64' }
parseValue('aleo1abc...') // → { value: 'aleo1abc...', type: 'address' }
encodeValue(100n, 'u64') // → '100u64'Every error message is an instruction an agent can act on:
Program "my_program.aleo" not found. Verify the program ID is correct
and has been deployed: await client.getCode({ programId: 'my_program.aleo' })
┌─────────────────────────────────────────────────┐
│ Your dApp / AI Agent │
├─────────────────────────────────────────────────┤
│ PublicClient WalletClient │
│ (read-only) (sign + execute) │
├─────────────────────────────────────────────────┤
│ Actions │
│ getBlockNumber writeContract │
│ getBalance executeTransaction (alias) │
│ readContract deployContract │
│ getCode sendTransaction │
│ getBlock signMessage │
│ getRecords transfer │
│ describeProgram decrypt │
│ requestRecords │
├─────────────────────────────────────────────────┤
│ Contract Instances │
│ getContract({ programSource, client }) │
│ → contract.read.mappingName() │
│ → contract.write.functionName() │
├─────────────────────────────────────────────────┤
│ Agent Tooling │
│ @provablehq/veil-core/agent — tool schemas + handlers │
│ @provablehq/veil-core/mcp — MCP server │
├─────────────────────────────────────────────────┤
│ Accounts │
│ RpcAccount LocalAccount ViewOnlyAccount │
│ (wallet) (private key) (view key) │
├─────────────────────────────────────────────────┤
│ Transports │
│ http() custom() fallback() │
├─────────────────────────────────────────────────┤
│ Client Configuration │
│ proving: { mode, url, apiKey } │
│ records: config object or custom impl │
├─────────────────────────────────────────────────┤
│ Adapter Packages │
│ @provablehq/veil-aleo-wallet-adapter @provablehq/veil-aleo-sdk │
├─────────────────────────────────────────────────┤
│ Aleo Network / Wallet Adapter │
└─────────────────────────────────────────────────┘
veil defines interfaces. Implementations plug in.
- Transport — any object with a
request(method, params)function - Account — describes capabilities (can sign? has private key? has view key?), not origin
- Proving — a client configuration (
mode: 'delegated' | 'local'), not a standalone interface. Wallets handle proving internally; only SDK/local users configure it. - Records — config object for common cases (
{ mode: 'network', url }) or custom implementation ({ getRecords: ... }) for advanced use cases.
Core has zero hard dependencies. Adapter packages (@provablehq/veil-aleo-wallet-adapter, @provablehq/veil-aleo-sdk) bridge to the ecosystem's existing SDKs.
veil wraps these existing tools through its adapter packages:
- Aleo Wallet Adapter — Leo Wallet, Puzzle Wallet, Fox Wallet, Shield Mobile Wallet
- @provablehq/sdk — WASM-based SDK for browser/node
| Method | Description | Agent Tool |
|---|---|---|
getBlockNumber() |
Current chain height | aleo_get_block_number |
getBlock({ height?, hash? }) |
Fetch block by height or hash | aleo_get_block |
getTransaction({ id }) |
Fetch transaction by ID | aleo_get_transaction |
getBalance({ address }) |
Public credits balance | aleo_get_balance |
readContract({ programId, mapping, key }) |
Read a program mapping value | aleo_read_mapping |
getCode({ programId }) |
Fetch program source code | aleo_get_program_source |
describeProgram({ program }) |
Introspect program functions and mappings | aleo_describe_program |
getRecords({ program }) |
Fetch records (Aleo-native) | aleo_get_records |
getTransitionViewKeys({ transactionId }) |
Get transition view keys (Aleo-native) | aleo_get_transition_view_keys |
| Method | Description | Agent Tool |
|---|---|---|
sendTransaction({ transaction }) |
Broadcast a built transaction | aleo_send_transaction |
writeContract({ program, function, inputs, fee }) |
Execute a program transition | aleo_execute |
executeTransaction(...) |
Alias for writeContract |
aleo_execute |
deployContract({ program, fee }) |
Deploy a program | aleo_deploy |
signMessage({ message }) |
Sign an arbitrary message | — |
transfer({ to, amount }) |
Transfer credits (convenience) | aleo_transfer |
decrypt({ ciphertext }) |
Decrypt a ciphertext (Aleo-native) | — |
requestRecords({ program }) |
Request records (Aleo-native) | — |
waitForTransaction({ id }) |
Wait for confirmation | aleo_wait_for_transaction |
If viem has a name for the concept, veil uses it. Aleo-specific names are only used for concepts with no EVM equivalent (records, decrypt, transition view keys). executeTransaction is provided as an alias for writeContract to stay consistent with Aleo wallet adapter terminology.
| viem concept | veil equivalent |
|---|---|
getBalance |
getBalance — reads public credits |
readContract |
readContract — reads program mapping |
writeContract |
writeContract / executeTransaction — executes program transition |
deployContract |
deployContract — deploys program |
getCode |
getCode — fetches program source |
sendTransaction |
sendTransaction — broadcasts transaction |
signMessage |
signMessage — signs message |
getContract |
getContract — typed contract instance from program source |
veil/
├── packages/
│ ├── core/ # @provablehq/veil-core (zero dependencies)
│ │ └── src/
│ │ ├── clients/ # createPublicClient, createWalletClient
│ │ ├── accounts/ # rpcAccount, privateKeyToAccount, etc.
│ │ ├── transports/ # http, custom, fallback
│ │ ├── actions/ # public/ and wallet/ actions
│ │ ├── contract/ # getContract, parseProgram
│ │ ├── agent/ # Agent tool schemas + handlers (@provablehq/veil-core/agent)
│ │ ├── mcp/ # MCP server (@provablehq/veil-core/mcp)
│ │ ├── types/ # core type definitions
│ │ ├── errors/ # error types (actionable messages)
│ │ └── utils/ # address validation, credits, value parsing
│ ├── provable-sdk/ # @provablehq/veil-aleo-sdk (wraps @provablehq/sdk)
│ ├── wallet-adapter/ # @provablehq/veil-aleo-wallet-adapter (wraps wallet standard)
│ ├── react/ # @provablehq/veil-aleo-react-hooks (VeilProvider, useVeilWallet)
│ ├── shield-swap/ # @provablehq/shield-swap-sdk (shield_swap AMM/DEX client)
│ ├── codegen/ # @provablehq/veil-codegen (ABI → typed bindings + CLI)
│ ├── devnode/ # @provablehq/veil-aleo-devnode (local Aleo devnode for tests)
│ ├── leo/ # @provablehq/veil-leo (typed leo CLI wrapper)
│ └── bridge/ # @provablehq/aleo-bridge-sdk (cross-chain bridge client, preview)
├── skills/ # Skill definitions for code-writing agents
├── site/ # Docusaurus documentation site
└── package.json
pnpm install
pnpm test
pnpm build
pnpm typecheckMIT