@veil-cash/sdk 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +130 -464
- package/SDK.md +365 -0
- package/dist/cli/index.cjs +2260 -955
- package/dist/index.cjs +561 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +486 -1
- package/dist/index.d.ts +486 -1
- package/dist/index.js +544 -27
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
- package/skills/veil/SKILL.md +526 -0
- package/skills/veil/reference.md +231 -0
- package/src/abi.ts +172 -0
- package/src/addresses.ts +20 -2
- package/src/balance.ts +4 -4
- package/src/cli/commands/balance.ts +126 -38
- package/src/cli/commands/deposit.ts +136 -63
- package/src/cli/commands/init.ts +95 -72
- package/src/cli/commands/keypair.ts +34 -16
- package/src/cli/commands/private-balance.ts +37 -35
- package/src/cli/commands/queue-balance.ts +48 -36
- package/src/cli/commands/register.ts +67 -53
- package/src/cli/commands/status.ts +196 -70
- package/src/cli/commands/subaccount.ts +354 -0
- package/src/cli/commands/transfer.ts +62 -53
- package/src/cli/commands/withdraw.ts +32 -30
- package/src/cli/config.ts +85 -5
- package/src/cli/errors.ts +8 -0
- package/src/cli/index.ts +27 -5
- package/src/cli/output.ts +87 -0
- package/src/cli/wallet.ts +75 -16
- package/src/index.ts +41 -1
- package/src/prover.ts +3 -0
- package/src/relay.ts +36 -24
- package/src/subaccount.ts +476 -0
- package/src/types.ts +134 -0
package/README.md
CHANGED
|
@@ -8,6 +8,8 @@ SDK and CLI for interacting with [Veil Cash](https://veil.cash) privacy pools on
|
|
|
8
8
|
|
|
9
9
|
Generate keypairs, register, deposit, withdraw, transfer, and merge ETH and USDC privately.
|
|
10
10
|
|
|
11
|
+
`0.6.0` adds SDK-first subaccount support for deterministic slot derivation, forwarder status, relay-backed deploy/sweep, and direct recovery.
|
|
12
|
+
|
|
11
13
|
## Installation
|
|
12
14
|
|
|
13
15
|
```bash
|
|
@@ -23,6 +25,20 @@ For global CLI access:
|
|
|
23
25
|
npm install -g @veil-cash/sdk
|
|
24
26
|
```
|
|
25
27
|
|
|
28
|
+
## Agent Skill
|
|
29
|
+
|
|
30
|
+
This repo includes a Veil agent skill at [`skills/veil/SKILL.md`](./skills/veil/SKILL.md).
|
|
31
|
+
|
|
32
|
+
Quick mapping:
|
|
33
|
+
|
|
34
|
+
- npm package: `@veil-cash/sdk`
|
|
35
|
+
- CLI binary: `veil`
|
|
36
|
+
- agent skill file: `skills/veil/SKILL.md`
|
|
37
|
+
|
|
38
|
+
If you are pointing an agent at this repo, send it to [`skills/veil/SKILL.md`](./skills/veil/SKILL.md) for the canonical CLI workflow.
|
|
39
|
+
|
|
40
|
+
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.
|
|
41
|
+
|
|
26
42
|
## Supported Assets
|
|
27
43
|
|
|
28
44
|
| Asset | Decimals | Token Contract |
|
|
@@ -32,239 +48,172 @@ npm install -g @veil-cash/sdk
|
|
|
32
48
|
|
|
33
49
|
## CLI Quick Start
|
|
34
50
|
|
|
35
|
-
|
|
36
|
-
# 1. Generate and save your Veil keypair
|
|
37
|
-
veil init
|
|
51
|
+
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.
|
|
38
52
|
|
|
39
|
-
|
|
53
|
+
```bash
|
|
54
|
+
# 1. Set your Ethereum wallet key
|
|
40
55
|
export WALLET_KEY=0x...
|
|
41
56
|
|
|
57
|
+
# 2. Derive and save your Veil keypair
|
|
58
|
+
veil init
|
|
59
|
+
|
|
42
60
|
# 3. Register your deposit key (one-time)
|
|
43
61
|
veil register
|
|
44
62
|
|
|
45
63
|
# 4. Check your setup
|
|
46
64
|
veil status
|
|
47
65
|
|
|
48
|
-
# 5. Deposit (
|
|
66
|
+
# 5. Deposit into the pool (amount is what arrives in your balance; fee added automatically)
|
|
49
67
|
veil deposit ETH 0.1
|
|
50
68
|
veil deposit USDC 100
|
|
51
69
|
|
|
52
|
-
# 6.
|
|
53
|
-
veil balance
|
|
54
|
-
veil balance --pool
|
|
70
|
+
# 6. Inspect balances
|
|
71
|
+
veil balance
|
|
72
|
+
veil balance --pool eth
|
|
73
|
+
veil balance queue --pool usdc
|
|
74
|
+
veil balance private
|
|
55
75
|
|
|
56
|
-
# 7.
|
|
76
|
+
# 7. Use privacy actions
|
|
57
77
|
veil withdraw ETH 0.05 0xRecipientAddress
|
|
58
|
-
veil withdraw USDC 50 0xRecipientAddress
|
|
59
|
-
|
|
60
|
-
# 8. Transfer privately to another registered user
|
|
61
78
|
veil transfer ETH 0.02 0xRecipientAddress
|
|
62
|
-
|
|
63
|
-
# 9. Merge small UTXOs (consolidate balances)
|
|
64
79
|
veil merge ETH 0.1
|
|
65
|
-
```
|
|
66
80
|
|
|
67
|
-
|
|
81
|
+
# 8. Work with subaccounts
|
|
82
|
+
veil subaccount derive --slot 0
|
|
83
|
+
veil subaccount status --slot 0
|
|
84
|
+
veil subaccount deploy --slot 0
|
|
85
|
+
veil subaccount sweep --slot 0 --asset eth
|
|
86
|
+
veil subaccount recover --slot 0 --asset usdc --to 0xRecipientAddress --amount 25
|
|
68
87
|
|
|
69
|
-
|
|
88
|
+
# 9. Use JSON or unsigned modes when you need automation
|
|
89
|
+
veil status --json
|
|
90
|
+
veil deposit ETH 0.1 --unsigned
|
|
91
|
+
veil subaccount status --slot 0 --json
|
|
92
|
+
```
|
|
70
93
|
|
|
71
|
-
|
|
94
|
+
## CLI Tasks
|
|
72
95
|
|
|
73
|
-
|
|
74
|
-
veil init # Random keypair, saves to .env.veil
|
|
75
|
-
veil init --force # Overwrite existing without prompting
|
|
76
|
-
veil init --json # Output as JSON (no prompts, no file save)
|
|
77
|
-
veil init --no-save # Print keypair without saving
|
|
96
|
+
### Setup
|
|
78
97
|
|
|
79
|
-
|
|
80
|
-
veil init --sign-message --wallet-key 0x...
|
|
98
|
+
Derive a Veil keypair from your wallet (default) or generate a random one:
|
|
81
99
|
|
|
82
|
-
|
|
100
|
+
```bash
|
|
101
|
+
veil init
|
|
102
|
+
veil init --generate
|
|
83
103
|
veil init --signature 0x...
|
|
104
|
+
veil init --force
|
|
105
|
+
veil init --no-save
|
|
106
|
+
veil init --json
|
|
84
107
|
```
|
|
85
108
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
Show current Veil keypair as JSON (from VEIL_KEY env).
|
|
109
|
+
Show the current keypair from `VEIL_KEY`:
|
|
89
110
|
|
|
90
111
|
```bash
|
|
91
112
|
veil keypair
|
|
92
|
-
|
|
113
|
+
veil keypair --json
|
|
93
114
|
```
|
|
94
115
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
Check configuration and service status.
|
|
116
|
+
Check local configuration, registration, and relay health:
|
|
98
117
|
|
|
99
118
|
```bash
|
|
100
119
|
veil status
|
|
120
|
+
veil status --json
|
|
101
121
|
```
|
|
102
122
|
|
|
103
|
-
|
|
104
|
-
```json
|
|
105
|
-
{
|
|
106
|
-
"walletKey": { "found": true, "address": "0x..." },
|
|
107
|
-
"veilKey": { "found": true },
|
|
108
|
-
"depositKey": { "found": true, "key": "0x1234...abcd" },
|
|
109
|
-
"rpcUrl": { "found": false, "url": "https://mainnet.base.org" },
|
|
110
|
-
"registration": {
|
|
111
|
-
"checked": true,
|
|
112
|
-
"registered": true,
|
|
113
|
-
"matches": true,
|
|
114
|
-
"onChainKey": "0x..."
|
|
115
|
-
},
|
|
116
|
-
"relay": {
|
|
117
|
-
"checked": true,
|
|
118
|
-
"healthy": true,
|
|
119
|
-
"status": "ok",
|
|
120
|
-
"network": "mainnet"
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
```
|
|
123
|
+
`veil 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.
|
|
124
124
|
|
|
125
|
-
###
|
|
125
|
+
### Registration and Deposits
|
|
126
126
|
|
|
127
|
-
Register or update your deposit key on-chain
|
|
127
|
+
Register or update your deposit key on-chain:
|
|
128
128
|
|
|
129
129
|
```bash
|
|
130
|
-
veil register
|
|
131
|
-
veil register --
|
|
132
|
-
veil register --
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
veil register --force # Change to local deposit key
|
|
136
|
-
veil register --force --unsigned # Unsigned change payload for agents
|
|
130
|
+
veil register
|
|
131
|
+
veil register --force
|
|
132
|
+
veil register --json
|
|
133
|
+
veil register --unsigned --address 0x...
|
|
134
|
+
SIGNER_ADDRESS=0x... veil register --unsigned
|
|
137
135
|
```
|
|
138
136
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
### `veil deposit <asset> <amount>`
|
|
137
|
+
In `--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.
|
|
142
138
|
|
|
143
|
-
Deposit ETH or USDC into the
|
|
139
|
+
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:
|
|
144
140
|
|
|
145
141
|
```bash
|
|
146
|
-
veil deposit ETH 0.1
|
|
147
|
-
veil deposit USDC 100
|
|
148
|
-
veil deposit ETH 0.1 --
|
|
149
|
-
veil deposit ETH 0.1 --
|
|
142
|
+
veil deposit ETH 0.1 # 0.1 ETH lands in pool, ~0.1003 ETH sent
|
|
143
|
+
veil deposit USDC 100 # 100 USDC lands in pool, ~100.30 USDC sent
|
|
144
|
+
veil deposit ETH 0.1 --json
|
|
145
|
+
veil deposit ETH 0.1 --unsigned
|
|
150
146
|
```
|
|
151
147
|
|
|
152
|
-
|
|
153
|
-
```json
|
|
154
|
-
{
|
|
155
|
-
"success": true,
|
|
156
|
-
"hash": "0x...",
|
|
157
|
-
"asset": "ETH",
|
|
158
|
-
"amount": "0.1",
|
|
159
|
-
"blockNumber": "12345678",
|
|
160
|
-
"gasUsed": "150000"
|
|
161
|
-
}
|
|
162
|
-
```
|
|
148
|
+
### Balances
|
|
163
149
|
|
|
164
|
-
|
|
150
|
+
Show combined balances across queue and private pools:
|
|
165
151
|
|
|
166
|
-
|
|
152
|
+
```bash
|
|
153
|
+
veil balance
|
|
154
|
+
veil balance --pool eth
|
|
155
|
+
veil balance --pool usdc
|
|
156
|
+
veil balance --json
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Inspect queue balances directly:
|
|
167
160
|
|
|
168
161
|
```bash
|
|
169
|
-
veil balance
|
|
170
|
-
veil balance --pool usdc
|
|
171
|
-
veil balance --
|
|
162
|
+
veil balance queue
|
|
163
|
+
veil balance queue --pool usdc
|
|
164
|
+
veil balance queue --address 0x... --json
|
|
172
165
|
```
|
|
173
166
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
"depositKey": "0x...",
|
|
181
|
-
"totalBalance": "0.15",
|
|
182
|
-
"totalBalanceWei": "150000000000000000",
|
|
183
|
-
"private": {
|
|
184
|
-
"balance": "0.10",
|
|
185
|
-
"balanceWei": "100000000000000000",
|
|
186
|
-
"utxoCount": 2,
|
|
187
|
-
"utxos": [
|
|
188
|
-
{ "index": 5, "amount": "0.05" },
|
|
189
|
-
{ "index": 8, "amount": "0.05" }
|
|
190
|
-
]
|
|
191
|
-
},
|
|
192
|
-
"queue": {
|
|
193
|
-
"balance": "0.05",
|
|
194
|
-
"balanceWei": "50000000000000000",
|
|
195
|
-
"count": 1,
|
|
196
|
-
"deposits": [
|
|
197
|
-
{ "nonce": 42, "amount": "0.05", "status": "pending" }
|
|
198
|
-
]
|
|
199
|
-
}
|
|
200
|
-
}
|
|
167
|
+
Inspect private balances directly:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
veil balance private
|
|
171
|
+
veil balance private --pool usdc
|
|
172
|
+
veil balance private --json
|
|
201
173
|
```
|
|
202
174
|
|
|
203
|
-
###
|
|
175
|
+
### Private Actions
|
|
204
176
|
|
|
205
|
-
Withdraw from the
|
|
177
|
+
Withdraw from the private pool to a public address:
|
|
206
178
|
|
|
207
179
|
```bash
|
|
208
180
|
veil withdraw ETH 0.05 0xRecipientAddress
|
|
209
181
|
veil withdraw USDC 50 0xRecipientAddress
|
|
210
|
-
veil withdraw ETH 0.05 0xRecipientAddress --
|
|
182
|
+
veil withdraw ETH 0.05 0xRecipientAddress --json
|
|
211
183
|
```
|
|
212
184
|
|
|
213
|
-
|
|
214
|
-
```json
|
|
215
|
-
{
|
|
216
|
-
"success": true,
|
|
217
|
-
"transactionHash": "0x...",
|
|
218
|
-
"blockNumber": 12345678,
|
|
219
|
-
"asset": "ETH",
|
|
220
|
-
"amount": "0.05",
|
|
221
|
-
"recipient": "0x..."
|
|
222
|
-
}
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
### `veil transfer <asset> <amount> <recipient>`
|
|
226
|
-
|
|
227
|
-
Transfer privately to another registered Veil user.
|
|
185
|
+
Transfer privately to another registered Veil user:
|
|
228
186
|
|
|
229
187
|
```bash
|
|
230
188
|
veil transfer ETH 0.02 0xRecipientAddress
|
|
231
189
|
veil transfer USDC 25 0xRecipientAddress
|
|
232
|
-
veil transfer ETH 0.02 0xRecipientAddress --
|
|
190
|
+
veil transfer ETH 0.02 0xRecipientAddress --json
|
|
233
191
|
```
|
|
234
192
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
"asset": "ETH",
|
|
242
|
-
"amount": "0.02",
|
|
243
|
-
"recipient": "0x...",
|
|
244
|
-
"type": "transfer"
|
|
245
|
-
}
|
|
193
|
+
Merge small UTXOs into one:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
veil merge ETH 0.1
|
|
197
|
+
veil merge USDC 100
|
|
198
|
+
veil merge ETH 0.1 --json
|
|
246
199
|
```
|
|
247
200
|
|
|
248
|
-
###
|
|
201
|
+
### Subaccounts
|
|
249
202
|
|
|
250
|
-
|
|
203
|
+
Subaccounts are deterministic child slots derived from your main `VEIL_KEY`:
|
|
251
204
|
|
|
252
|
-
|
|
253
|
-
veil merge ETH 0.1 # Merge ETH UTXOs totaling 0.1 ETH
|
|
254
|
-
veil merge USDC 100 # Merge USDC UTXOs
|
|
255
|
-
veil merge ETH 0.1 --quiet
|
|
256
|
-
```
|
|
205
|
+
`root key -> slot -> child key -> child deposit key -> forwarder`
|
|
257
206
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
207
|
+
Base mainnet only. Deploy and sweep are relay-backed. Status reports the forwarder wallet and queue state only, not private pool attribution after queued funds are accepted. Recovery is for assets still sitting on the forwarder after refund or rejection, and is submitted directly on-chain by your CLI gas payer.
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
veil subaccount derive --slot 0
|
|
211
|
+
veil subaccount status --slot 0
|
|
212
|
+
veil subaccount address --slot 0
|
|
213
|
+
veil subaccount deploy --slot 0
|
|
214
|
+
veil subaccount sweep --slot 0 --asset eth
|
|
215
|
+
veil subaccount recover --slot 0 --asset usdc --to 0xRecipientAddress --amount 25
|
|
216
|
+
veil subaccount status --slot 0 --json
|
|
268
217
|
```
|
|
269
218
|
|
|
270
219
|
## Environment Variables
|
|
@@ -274,7 +223,7 @@ The CLI uses two config files:
|
|
|
274
223
|
| File | Purpose |
|
|
275
224
|
|------|---------|
|
|
276
225
|
| `.env.veil` | Veil keypair (VEIL_KEY, DEPOSIT_KEY) - created by `veil init` |
|
|
277
|
-
| `.env` | Wallet config (WALLET_KEY, RPC_URL) - your existing config |
|
|
226
|
+
| `.env` | Wallet config (WALLET_KEY or SIGNER_ADDRESS, RPC_URL) - your existing config |
|
|
278
227
|
|
|
279
228
|
### Variables
|
|
280
229
|
|
|
@@ -283,17 +232,21 @@ The CLI uses two config files:
|
|
|
283
232
|
| `VEIL_KEY` | Your Veil private key (for ZK proofs, withdrawals, transfers) |
|
|
284
233
|
| `DEPOSIT_KEY` | Your Veil deposit key (public, for register/deposit) |
|
|
285
234
|
| `WALLET_KEY` | Ethereum wallet private key (for signing transactions) |
|
|
235
|
+
| `SIGNER_ADDRESS` | Ethereum address for unsigned/query flows when signing is handled externally |
|
|
286
236
|
| `RPC_URL` | Base RPC URL (optional, defaults to public RPC) |
|
|
237
|
+
| `RELAY_URL` | Override relay base URL for relayed CLI operations, subaccount deploy/sweep, and status checks |
|
|
238
|
+
|
|
239
|
+
`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`.
|
|
287
240
|
|
|
288
241
|
## Error Handling
|
|
289
242
|
|
|
290
|
-
|
|
243
|
+
Commands print human-readable success output by default. Errors are standardized JSON with machine-readable error codes so scripts can detect failure cases reliably:
|
|
291
244
|
|
|
292
245
|
```json
|
|
293
246
|
{
|
|
294
247
|
"success": false,
|
|
295
248
|
"errorCode": "VEIL_KEY_MISSING",
|
|
296
|
-
"error": "VEIL_KEY required.
|
|
249
|
+
"error": "VEIL_KEY required. Set VEIL_KEY env"
|
|
297
250
|
}
|
|
298
251
|
```
|
|
299
252
|
|
|
@@ -304,7 +257,9 @@ All CLI commands output JSON with standardized error codes:
|
|
|
304
257
|
| `VEIL_KEY_MISSING` | VEIL_KEY not provided |
|
|
305
258
|
| `WALLET_KEY_MISSING` | WALLET_KEY not provided |
|
|
306
259
|
| `DEPOSIT_KEY_MISSING` | DEPOSIT_KEY not provided |
|
|
260
|
+
| `CONFIG_CONFLICT` | Conflicting CLI env vars provided |
|
|
307
261
|
| `INVALID_ADDRESS` | Invalid Ethereum address format |
|
|
262
|
+
| `INVALID_SLOT` | Invalid subaccount slot format |
|
|
308
263
|
| `INVALID_AMOUNT` | Invalid or below minimum amount |
|
|
309
264
|
| `INSUFFICIENT_BALANCE` | Not enough ETH balance |
|
|
310
265
|
| `USER_NOT_REGISTERED` | Recipient not registered in Veil |
|
|
@@ -314,311 +269,22 @@ All CLI commands output JSON with standardized error codes:
|
|
|
314
269
|
| `CONTRACT_ERROR` | Smart contract reverted |
|
|
315
270
|
| `UNKNOWN_ERROR` | Unexpected error |
|
|
316
271
|
|
|
317
|
-
## SDK
|
|
318
|
-
|
|
319
|
-
```typescript
|
|
320
|
-
import {
|
|
321
|
-
Keypair, buildRegisterTx, buildDepositETHTx,
|
|
322
|
-
buildDepositUSDCTx, buildApproveUSDCTx,
|
|
323
|
-
withdraw, transfer,
|
|
324
|
-
} from '@veil-cash/sdk';
|
|
325
|
-
import { createWalletClient, http } from 'viem';
|
|
326
|
-
import { base } from 'viem/chains';
|
|
327
|
-
import { privateKeyToAccount } from 'viem/accounts';
|
|
328
|
-
|
|
329
|
-
// 1. Generate a Veil keypair (do this once, save securely!)
|
|
330
|
-
const keypair = new Keypair();
|
|
331
|
-
console.log('Veil Private Key:', keypair.privkey); // SAVE THIS!
|
|
332
|
-
console.log('Deposit Key:', keypair.depositKey()); // Register this on-chain
|
|
333
|
-
|
|
334
|
-
// 2. Setup your Ethereum wallet
|
|
335
|
-
const account = privateKeyToAccount('0x...');
|
|
336
|
-
const client = createWalletClient({
|
|
337
|
-
account,
|
|
338
|
-
chain: base,
|
|
339
|
-
transport: http(),
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
// 3. Register your deposit key (one-time)
|
|
343
|
-
const registerTx = buildRegisterTx(keypair.depositKey(), account.address);
|
|
344
|
-
await client.sendTransaction(registerTx);
|
|
345
|
-
|
|
346
|
-
// 4. Deposit ETH
|
|
347
|
-
const depositTx = buildDepositETHTx({
|
|
348
|
-
depositKey: keypair.depositKey(),
|
|
349
|
-
amount: '0.1',
|
|
350
|
-
});
|
|
351
|
-
await client.sendTransaction({ ...depositTx, value: depositTx.value });
|
|
352
|
-
|
|
353
|
-
// 4b. Deposit USDC (approve first)
|
|
354
|
-
const approveTx = buildApproveUSDCTx({ amount: '100' });
|
|
355
|
-
await client.sendTransaction(approveTx);
|
|
356
|
-
const usdcTx = buildDepositUSDCTx({
|
|
357
|
-
depositKey: keypair.depositKey(),
|
|
358
|
-
amount: '100',
|
|
359
|
-
});
|
|
360
|
-
await client.sendTransaction(usdcTx);
|
|
361
|
-
|
|
362
|
-
// 5. Withdraw (sent via relayer, no wallet signing needed)
|
|
363
|
-
const withdrawResult = await withdraw({
|
|
364
|
-
amount: '0.05',
|
|
365
|
-
recipient: '0xRecipientAddress',
|
|
366
|
-
keypair,
|
|
367
|
-
pool: 'eth', // 'eth' | 'usdc' (default: 'eth')
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
// 6. Transfer privately
|
|
371
|
-
const transferResult = await transfer({
|
|
372
|
-
amount: '0.02',
|
|
373
|
-
recipientAddress: '0xRecipientAddress',
|
|
374
|
-
senderKeypair: keypair,
|
|
375
|
-
pool: 'eth', // 'eth' | 'usdc' (default: 'eth')
|
|
376
|
-
});
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
## SDK API Reference
|
|
380
|
-
|
|
381
|
-
### Keypair
|
|
382
|
-
|
|
383
|
-
```typescript
|
|
384
|
-
import { Keypair, VEIL_SIGNED_MESSAGE } from '@veil-cash/sdk';
|
|
385
|
-
import type { MessageSigner } from '@veil-cash/sdk';
|
|
386
|
-
|
|
387
|
-
// Generate random keypair
|
|
388
|
-
const keypair = new Keypair();
|
|
389
|
-
|
|
390
|
-
// Restore from saved Veil private key
|
|
391
|
-
const restored = new Keypair(savedVeilKey);
|
|
392
|
-
|
|
393
|
-
// Derive from wallet key (same keypair as frontend login)
|
|
394
|
-
const derived = await Keypair.fromWalletKey('0xYOUR_WALLET_KEY');
|
|
395
|
-
|
|
396
|
-
// Derive from a raw EIP-191 signature
|
|
397
|
-
const fromSig = Keypair.fromSignature('0xSIGNATURE...');
|
|
398
|
-
|
|
399
|
-
// Derive from any external signer (Bankr, MPC, custodial, etc.)
|
|
400
|
-
const fromSigner = await Keypair.fromSigner(async (message) => {
|
|
401
|
-
// Sign `message` using any personal_sign provider and return the signature
|
|
402
|
-
return await mySigningService.personalSign(message);
|
|
403
|
-
});
|
|
404
|
-
|
|
405
|
-
// Get deposit key (for registration)
|
|
406
|
-
keypair.depositKey(); // '0x...' (130 hex chars)
|
|
407
|
-
|
|
408
|
-
// Veil private key (store securely!)
|
|
409
|
-
keypair.privkey; // '0x...'
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
### Transaction Builders
|
|
413
|
-
|
|
414
|
-
```typescript
|
|
415
|
-
import {
|
|
416
|
-
buildRegisterTx, buildChangeDepositKeyTx, buildDepositETHTx, buildDepositTx,
|
|
417
|
-
buildDepositUSDCTx, buildApproveUSDCTx,
|
|
418
|
-
} from '@veil-cash/sdk';
|
|
419
|
-
|
|
420
|
-
// Register deposit key (first time)
|
|
421
|
-
const registerTx = buildRegisterTx(depositKey, ownerAddress);
|
|
422
|
-
// → { to: '0x...', data: '0x...' }
|
|
423
|
-
|
|
424
|
-
// Change deposit key (must already be registered)
|
|
425
|
-
const changeTx = buildChangeDepositKeyTx(newDepositKey, ownerAddress);
|
|
426
|
-
// → { to: '0x...', data: '0x...' }
|
|
427
|
-
|
|
428
|
-
// Deposit ETH
|
|
429
|
-
const depositTx = buildDepositETHTx({
|
|
430
|
-
depositKey: keypair.depositKey(),
|
|
431
|
-
amount: '0.1',
|
|
432
|
-
});
|
|
433
|
-
// → { to: '0x...', data: '0x...', value: 100000000000000000n }
|
|
434
|
-
|
|
435
|
-
// Deposit USDC (approve + deposit)
|
|
436
|
-
const approveUsdcTx = buildApproveUSDCTx({ amount: '100' });
|
|
437
|
-
const depositUsdcTx = buildDepositUSDCTx({
|
|
438
|
-
depositKey: keypair.depositKey(),
|
|
439
|
-
amount: '100',
|
|
440
|
-
});
|
|
441
|
-
|
|
442
|
-
// Generic builder (routes by token)
|
|
443
|
-
const tx = buildDepositTx({
|
|
444
|
-
depositKey: keypair.depositKey(),
|
|
445
|
-
amount: '0.1',
|
|
446
|
-
token: 'ETH', // 'ETH' | 'USDC'
|
|
447
|
-
});
|
|
448
|
-
```
|
|
449
|
-
|
|
450
|
-
### Withdraw & Transfer
|
|
451
|
-
|
|
452
|
-
All withdraw, transfer, and merge functions accept an optional `pool` parameter (`'eth'` | `'usdc'`), defaulting to `'eth'`.
|
|
453
|
-
|
|
454
|
-
```typescript
|
|
455
|
-
import { withdraw, transfer, mergeUtxos } from '@veil-cash/sdk';
|
|
456
|
-
|
|
457
|
-
// Withdraw ETH to public address
|
|
458
|
-
const withdrawResult = await withdraw({
|
|
459
|
-
amount: '0.05',
|
|
460
|
-
recipient: '0xRecipientAddress',
|
|
461
|
-
keypair,
|
|
462
|
-
pool: 'eth', // default
|
|
463
|
-
onProgress: (stage, detail) => console.log(stage, detail),
|
|
464
|
-
});
|
|
465
|
-
|
|
466
|
-
// Withdraw USDC
|
|
467
|
-
const withdrawUsdc = await withdraw({
|
|
468
|
-
amount: '50',
|
|
469
|
-
recipient: '0xRecipientAddress',
|
|
470
|
-
keypair,
|
|
471
|
-
pool: 'usdc',
|
|
472
|
-
});
|
|
473
|
-
|
|
474
|
-
// Merge UTXOs (consolidate small balances)
|
|
475
|
-
const mergeResult = await mergeUtxos({
|
|
476
|
-
amount: '0.1',
|
|
477
|
-
keypair,
|
|
478
|
-
pool: 'eth',
|
|
479
|
-
});
|
|
480
|
-
```
|
|
481
|
-
|
|
482
|
-
### Balance Queries
|
|
483
|
-
|
|
484
|
-
Balance functions accept an optional `pool` parameter (`'eth'` | `'usdc'`), defaulting to `'eth'`.
|
|
485
|
-
|
|
486
|
-
```typescript
|
|
487
|
-
import { getQueueBalance, getPrivateBalance } from '@veil-cash/sdk';
|
|
488
|
-
|
|
489
|
-
// Check ETH queue balance (pending deposits)
|
|
490
|
-
const queueBalance = await getQueueBalance({
|
|
491
|
-
address: '0x...',
|
|
492
|
-
pool: 'eth', // default
|
|
493
|
-
});
|
|
494
|
-
|
|
495
|
-
// Check USDC private balance (requires keypair)
|
|
496
|
-
const privateBalance = await getPrivateBalance({
|
|
497
|
-
keypair,
|
|
498
|
-
pool: 'usdc',
|
|
499
|
-
});
|
|
500
|
-
|
|
501
|
-
```
|
|
502
|
-
|
|
503
|
-
### Addresses
|
|
504
|
-
|
|
505
|
-
```typescript
|
|
506
|
-
import { getAddresses, getPoolAddress, getQueueAddress } from '@veil-cash/sdk';
|
|
272
|
+
## SDK Docs
|
|
507
273
|
|
|
508
|
-
|
|
509
|
-
console.log(addresses.entry); // Entry contract
|
|
510
|
-
console.log(addresses.ethPool); // ETH pool
|
|
511
|
-
console.log(addresses.usdcPool); // USDC pool
|
|
274
|
+
The CLI is the main entrypoint for most users. If you are integrating Veil programmatically, use the dedicated SDK guide:
|
|
512
275
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
console.log(getPoolAddress('usdc')); // USDC pool address
|
|
516
|
-
```
|
|
517
|
-
|
|
518
|
-
## For AI Agents
|
|
519
|
-
|
|
520
|
-
This SDK is designed to work with AI agent frameworks like [Bankr](https://bankr.bot).
|
|
521
|
-
|
|
522
|
-
### Non-Interactive CLI
|
|
523
|
-
|
|
524
|
-
All commands output JSON and support non-interactive usage:
|
|
525
|
-
|
|
526
|
-
```bash
|
|
527
|
-
# Generate keypair as JSON (no prompts, no file save)
|
|
528
|
-
veil init --json
|
|
529
|
-
|
|
530
|
-
# Get unsigned transaction payloads for agent signing
|
|
531
|
-
veil register --unsigned --address 0x...
|
|
532
|
-
veil deposit ETH 0.1 --unsigned
|
|
533
|
-
veil deposit USDC 100 --unsigned # Outputs approve + deposit payloads
|
|
534
|
-
|
|
535
|
-
# Suppress progress output for clean JSON
|
|
536
|
-
veil balance --quiet
|
|
537
|
-
veil balance --pool usdc --quiet
|
|
538
|
-
veil withdraw ETH 0.05 0xRecipient --quiet
|
|
539
|
-
```
|
|
540
|
-
|
|
541
|
-
### Bankr Integration
|
|
542
|
-
|
|
543
|
-
#### Keypair Derivation via Bankr Sign API
|
|
544
|
-
|
|
545
|
-
Use `Keypair.fromSigner()` with Bankr's `POST /agent/sign` endpoint to derive the same keypair as the frontend:
|
|
546
|
-
|
|
547
|
-
```typescript
|
|
548
|
-
import { Keypair } from '@veil-cash/sdk';
|
|
549
|
-
|
|
550
|
-
const keypair = await Keypair.fromSigner(async (message) => {
|
|
551
|
-
const res = await fetch('https://api.bankr.bot/agent/sign', {
|
|
552
|
-
method: 'POST',
|
|
553
|
-
headers: { 'X-API-Key': BANKR_API_KEY, 'Content-Type': 'application/json' },
|
|
554
|
-
body: JSON.stringify({ signatureType: 'personal_sign', message }),
|
|
555
|
-
});
|
|
556
|
-
return (await res.json()).signature;
|
|
557
|
-
});
|
|
558
|
-
```
|
|
559
|
-
|
|
560
|
-
Or via CLI (two-step):
|
|
561
|
-
```bash
|
|
562
|
-
# 1. Get signature from Bankr sign API
|
|
563
|
-
SIG=$(curl -s -X POST "https://api.bankr.bot/agent/sign" \
|
|
564
|
-
-H "X-API-Key: $BANKR_API_KEY" \
|
|
565
|
-
-H "Content-Type: application/json" \
|
|
566
|
-
-d "{\"signatureType\":\"personal_sign\",\"message\":\"$(node -e "const{VEIL_SIGNED_MESSAGE}=require('@veil-cash/sdk');console.log(VEIL_SIGNED_MESSAGE)")\"}" \
|
|
567
|
-
| jq -r '.signature')
|
|
568
|
-
|
|
569
|
-
# 2. Derive keypair from signature
|
|
570
|
-
veil init --signature $SIG
|
|
571
|
-
```
|
|
572
|
-
|
|
573
|
-
#### Unsigned Transaction Payloads
|
|
574
|
-
|
|
575
|
-
Use `--unsigned` to get Bankr-compatible transaction payloads:
|
|
576
|
-
|
|
577
|
-
```bash
|
|
578
|
-
veil deposit ETH 0.1 --unsigned
|
|
579
|
-
# {"to":"0x...","data":"0x...","value":"100000000000000000","chainId":8453}
|
|
580
|
-
```
|
|
581
|
-
|
|
582
|
-
The `--unsigned` flag outputs the [Bankr arbitrary transaction format](https://github.com/BankrBot/moltbot-skills/blob/main/bankr/references/arbitrary-transaction.md).
|
|
583
|
-
|
|
584
|
-
### Programmatic SDK Usage
|
|
585
|
-
|
|
586
|
-
```typescript
|
|
587
|
-
import { Keypair, buildDepositETHTx, buildDepositTx, withdraw } from '@veil-cash/sdk';
|
|
588
|
-
|
|
589
|
-
// For deposits: build transaction, let agent sign via Bankr
|
|
590
|
-
const keypair = new Keypair(veilKey);
|
|
591
|
-
const tx = buildDepositETHTx({
|
|
592
|
-
depositKey: keypair.depositKey(),
|
|
593
|
-
amount: '0.1',
|
|
594
|
-
});
|
|
595
|
-
// → { to, data, value } - pass to Bankr for signing
|
|
596
|
-
|
|
597
|
-
// Generic builder works for any asset
|
|
598
|
-
const usdcTx = buildDepositTx({
|
|
599
|
-
depositKey: keypair.depositKey(),
|
|
600
|
-
amount: '100',
|
|
601
|
-
token: 'USDC',
|
|
602
|
-
});
|
|
603
|
-
|
|
604
|
-
// For withdrawals: SDK handles ZK proofs, submits to relayer
|
|
605
|
-
const result = await withdraw({
|
|
606
|
-
amount: '0.05',
|
|
607
|
-
recipient: '0xRecipient',
|
|
608
|
-
keypair,
|
|
609
|
-
pool: 'eth', // 'eth' | 'usdc'
|
|
610
|
-
});
|
|
611
|
-
// → { success, transactionHash, blockNumber }
|
|
612
|
-
```
|
|
276
|
+
- [SDK Quick Start and API Reference](./SDK.md)
|
|
277
|
+
- [AI agent and signer integration notes](./SDK.md#for-ai-agents)
|
|
613
278
|
|
|
614
279
|
## Deposit Flow
|
|
615
280
|
|
|
616
|
-
1. **
|
|
617
|
-
2. **
|
|
618
|
-
3. **
|
|
619
|
-
4. **
|
|
620
|
-
5. **
|
|
621
|
-
6. **
|
|
281
|
+
1. **Set Wallet Key**: `export WALLET_KEY=0x...` in your `.env` or shell
|
|
282
|
+
2. **Derive Keypair**: Run `veil init` to derive and save your Veil keypair
|
|
283
|
+
3. **Register**: Run `veil register` to link your deposit key on-chain (one-time)
|
|
284
|
+
4. **Check Status**: Run `veil status` to verify your setup
|
|
285
|
+
5. **Deposit**: Run `veil deposit <asset> <amount>` — the amount is what lands in your balance (e.g., `veil deposit ETH 0.1` deposits 0.1 ETH; the 0.3% fee is added automatically)
|
|
286
|
+
6. **Wait**: The Veil deposit engine processes your deposit
|
|
287
|
+
7. **Done**: Your deposit is accepted into the privacy pool
|
|
622
288
|
|
|
623
289
|
## Withdrawal Flow
|
|
624
290
|
|