@blackpool/cli 0.2.0 → 0.2.1
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/AGENTS.md +349 -86
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -1,130 +1,393 @@
|
|
|
1
1
|
# AGENTS.md — Blackpool for agents
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Private payments for AI agents and scripts. This file is the complete guide to using Blackpool through its CLI: setup, every command, the JSON each one returns, chains and limits, recipes, integration code, errors and safety rules. Start with the quickstart; everything after it is reference.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
| | |
|
|
6
|
+
|---|---|
|
|
7
|
+
| This file | https://blackpool.cash/AGENTS.md (plain markdown, no JavaScript, no bot challenge) |
|
|
8
|
+
| Mirrors | https://raw.githubusercontent.com/blackpooldev/blackpool/main/AGENTS.md · inside the npm package at `node_modules/@blackpool/cli/AGENTS.md` |
|
|
9
|
+
| Index for LLMs | https://blackpool.cash/llms.txt |
|
|
10
|
+
| CLI | [`@blackpool/cli`](https://www.npmjs.com/package/@blackpool/cli) — Node.js 18+ |
|
|
11
|
+
| API | `https://api.blackpool.cash` (the CLI calls it for you) |
|
|
12
|
+
| Live status | https://blackpool.cash/status |
|
|
13
|
+
| Human docs | https://blackpool.cash/docs |
|
|
8
14
|
|
|
9
|
-
|
|
15
|
+
---
|
|
10
16
|
|
|
11
|
-
|
|
17
|
+
## 1. Quickstart (60 seconds)
|
|
12
18
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
19
|
+
```sh
|
|
20
|
+
npm i -g @blackpool/cli # or prefix every command with: npx -y @blackpool/cli@latest
|
|
21
|
+
export BLACKPOOL_KEY=0x<agent-wallet-private-key> # a dedicated wallet, never your main one
|
|
22
|
+
export BLACKPOOL_JSON=1 # every command prints one JSON object on stdout
|
|
23
|
+
|
|
24
|
+
blackpool address # → {"ok":true,"command":"address","address":"0x…"} fund this address
|
|
25
|
+
blackpool deposit 25 --pool usdc --chain base # shield 25 USDC (the only step that needs gas)
|
|
26
|
+
blackpool send 0xRECIPIENT 10 --pool usdc --chain base # private payment, relayer pays gas
|
|
27
|
+
blackpool balance --chain base --pool usdc # → {"ok":true,…,"balance":"13.965",…}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Paste this into your agent's instructions:
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
You can make private crypto payments with the `blackpool` CLI (env BLACKPOOL_KEY and BLACKPOOL_JSON=1 are set).
|
|
34
|
+
Always run commands with a timeout of at least 300 seconds and parse the single JSON object on stdout.
|
|
35
|
+
"ok": true means it succeeded; "ok": false has an "error" to report. Exit code 2 means you called it wrong.
|
|
36
|
+
Before paying, check `blackpool balance --chain <c> --pool <p>`; if it is short, `blackpool deposit` first.
|
|
37
|
+
Never retry deposit, send, swap or bridge after a timeout or unclear failure: run `blackpool balance --wait`
|
|
38
|
+
(or `blackpool bridges`) to see whether it landed. `blackpool recover --chain all` is always safe to run.
|
|
39
|
+
Never print, log or share BLACKPOOL_KEY or anything in ~/.blackpool.
|
|
40
|
+
Full guide: https://blackpool.cash/AGENTS.md
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 2. How Blackpool works (what an agent needs to know)
|
|
46
|
+
|
|
47
|
+
- **Public balance**: tokens in the agent wallet, visible to everyone.
|
|
48
|
+
- **Private balance**: notes inside a Blackpool pool contract. Spending them reveals neither the agent wallet nor which deposit paid.
|
|
49
|
+
- **Shield (`deposit`)**: moves public funds into the pool. Signed and paid (gas) by the agent wallet. This is the only on-chain action that shows your wallet.
|
|
50
|
+
- **Private operations (`send`, `swap`, `bridge`)**: a zero-knowledge proof spends notes; the Blackpool relayer submits the transaction and pays gas. The fee is taken from the amount moved, so the agent needs no gas for these.
|
|
51
|
+
- **Burner**: a one-time wallet used inside `swap` and `bridge`. Its key is encrypted locally and registered before it is funded, so `recover` can always sweep it.
|
|
52
|
+
- **Account**: derived from one signature of the Blackpool sign-in message by the agent wallet. Same key → same private account on every chain and machine.
|
|
53
|
+
- **Pools are per chain and per asset.** A private USDC balance on Base cannot pay on Arbitrum; use `bridge` to move between chains.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 3. Setup
|
|
58
|
+
|
|
59
|
+
### 3.1 Install
|
|
38
60
|
|
|
39
61
|
```sh
|
|
40
|
-
npm i -g @blackpool/cli
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
blackpool
|
|
62
|
+
npm i -g @blackpool/cli # global: `blackpool …`
|
|
63
|
+
npx -y @blackpool/cli@latest … # no install, always the newest version
|
|
64
|
+
blackpool version --json # {"ok":true,"command":"version","version":"0.2.0"}
|
|
65
|
+
blackpool latest --json # {"ok":true,"command":"latest","installed":"0.2.0","latest":"0.2.0","upToDate":true}
|
|
44
66
|
```
|
|
45
67
|
|
|
46
|
-
|
|
68
|
+
### 3.2 Configure
|
|
47
69
|
|
|
48
|
-
| Variable | Purpose |
|
|
49
|
-
|
|
50
|
-
| `BLACKPOOL_KEY` | Agent wallet private key
|
|
51
|
-
| `BLACKPOOL_JSON` | `1` = JSON output for every command. |
|
|
52
|
-
| `BLACKPOOL_HOME` | Config directory
|
|
53
|
-
| `BLACKPOOL_API` | API base URL
|
|
70
|
+
| Variable | Required | Purpose |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| `BLACKPOOL_KEY` | yes (or run `blackpool login` once) | Agent wallet private key, 0x-prefixed hex. Used only locally. |
|
|
73
|
+
| `BLACKPOOL_JSON` | recommended | `1` = JSON output for every command (same as adding `--json`). |
|
|
74
|
+
| `BLACKPOOL_HOME` | no | Config/cache directory, default `~/.blackpool`. Set it when the home directory is read-only (containers, serverless). |
|
|
75
|
+
| `BLACKPOOL_API` | no | API base URL, default `https://api.blackpool.cash`. |
|
|
54
76
|
|
|
55
|
-
|
|
77
|
+
Without `BLACKPOOL_KEY`, `blackpool login` asks for the key with a hidden prompt and stores it at `~/.blackpool/wallet.json` (mode 600). Agents should prefer the environment variable.
|
|
56
78
|
|
|
57
|
-
|
|
79
|
+
### 3.3 Fund
|
|
58
80
|
|
|
59
81
|
```sh
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
82
|
+
blackpool address --json
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Send the agent wallet the asset you want to shield **plus a little native gas for the deposit** (a deposit uses about 1.3M gas; keep at least 0.0005 ETH on Robinhood Chain, Base or Arbitrum, or 0.002 BNB on BNB Chain). After shielding, private operations need no gas.
|
|
86
|
+
|
|
87
|
+
### 3.4 Verify
|
|
63
88
|
|
|
64
|
-
|
|
65
|
-
|
|
89
|
+
```sh
|
|
90
|
+
blackpool balance --chain all --json
|
|
66
91
|
```
|
|
67
92
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## 4. Command reference
|
|
96
|
+
|
|
97
|
+
Every command accepts `--json`. Amounts are plain decimals in token units (`10`, `0.25`), never wei. `--chain` defaults to `base`. Typical durations assume a healthy network.
|
|
98
|
+
|
|
99
|
+
### `address`
|
|
100
|
+
Print the agent wallet address.
|
|
101
|
+
```json
|
|
102
|
+
{"ok":true,"command":"address","address":"0x70997970C51812dc3A010C7d01b50e0d17dc79C8"}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### `balance [--chain C|all] [--pool P] [--wait]`
|
|
106
|
+
Private and public balances. `--pool` limits the answer to one private pool. `--wait` polls up to 30 s while a private balance reads 0 (use right after a deposit). ~5–15 s.
|
|
107
|
+
```json
|
|
108
|
+
{"ok":true,"command":"balance","chain":"base","pool":"usdc","address":"0x…","balance":"13.965","symbol":"USDC","utxos":2}
|
|
109
|
+
```
|
|
110
|
+
Without `--pool` (one entry per chain; `--chain all` returns four):
|
|
111
|
+
```json
|
|
112
|
+
{"ok":true,"command":"balance","balances":[{"chain":"base","address":"0x…",
|
|
113
|
+
"private":{"ETH":{"balance":"0.0","utxos":0},"USDC":{"balance":"13.965","utxos":2}},
|
|
114
|
+
"public":{"ETH":"0.00412","USDC":"0.0"}}]}
|
|
115
|
+
```
|
|
116
|
+
A value of `"?"` with an `error` field means that read failed; retry.
|
|
117
|
+
|
|
118
|
+
### `deposit <amount> [--pool P] [--chain C]`
|
|
119
|
+
Shield public funds from the agent wallet. ERC-20 pools approve first (one extra transaction). Needs native gas. ~30–90 s.
|
|
120
|
+
```json
|
|
121
|
+
{"ok":true,"command":"deposit","chain":"base","pool":"usdc","amount":25,"symbol":"USDC",
|
|
122
|
+
"txHash":"0x…","explorer":"https://basescan.org/tx/0x…","privateBalance":"25.0"}
|
|
123
|
+
```
|
|
124
|
+
`--pool` defaults to the chain's stablecoin pool.
|
|
125
|
+
|
|
126
|
+
### `send <recipient> <amount> [--pool P] [--chain C]`
|
|
127
|
+
Private payment to any EVM address on the same chain. `amount` is what leaves your private balance; the recipient gets `amount − fee`. No gas needed. ~30–90 s.
|
|
128
|
+
```json
|
|
129
|
+
{"ok":true,"command":"send","chain":"base","pool":"usdc","recipient":"0x…","amount":10,
|
|
130
|
+
"received":"8.965","fee":"1.035","symbol":"USDC","txHash":"0x…","explorer":"https://basescan.org/tx/0x…"}
|
|
131
|
+
```
|
|
132
|
+
To make the recipient receive exactly `X`, send `(X + flat) / (1 − 0.0035)` rounded up (see §5).
|
|
133
|
+
|
|
134
|
+
### `swap <amount> --from P [--chain C] [--slippage BPS]`
|
|
135
|
+
Private same-chain swap between the chain's native pool and stablecoin pool; the output is re-shielded into your private balance. `--slippage` in basis points, default `100` (1%). No gas needed. ~1–3 min.
|
|
136
|
+
```json
|
|
137
|
+
{"ok":true,"command":"swap","chain":"base","from":"eth","amount":0.01,"received":"22.41",
|
|
138
|
+
"symbol":"USDC","txHash":"0x…","explorer":"https://basescan.org/tx/0x…","privateBalance":"36.375"}
|
|
139
|
+
```
|
|
140
|
+
If it fails half-way, funds sit on a registered burner: run `recover`.
|
|
141
|
+
|
|
142
|
+
### `bridge <dest-asset> <recipient> <amount> --from ORIGIN [--no-wait]`
|
|
143
|
+
Private cross-chain transfer through NEAR Intents. `ORIGIN` is the private pool paying (default `base_usdc`); `dest-asset` and recipient format are listed in §6. The withdrawal is private; the solver delivers on the destination chain. Without `--no-wait` the CLI polls up to 6 minutes.
|
|
144
|
+
```json
|
|
145
|
+
{"ok":true,"command":"bridge","from":"base_usdc","to":"sol_usdc","recipient":"7Gx4…kQ2m","amount":10,
|
|
146
|
+
"amountOutQuote":"8.91","withdrawTx":"0x…","depositAddress":"0x…","statusUrl":"https://…",
|
|
147
|
+
"status":"SUCCESS","amountOut":"8.93"}
|
|
148
|
+
```
|
|
149
|
+
`status` is `SUBMITTED` (with `--no-wait`), `SUCCESS`, or `PENDING` (still running after 6 min; check `bridges` later). A refund or failure returns `"ok":false`; refunds go to the agent wallet on the origin chain.
|
|
150
|
+
|
|
151
|
+
### `bridges`
|
|
152
|
+
Every bridge this account has made, newest first, from the server-side intent registry (works from any machine).
|
|
153
|
+
```json
|
|
154
|
+
{"ok":true,"command":"bridges","bridges":[{"status":"SUCCESS","createdAt":1793760000000,"amountIn":"10",
|
|
155
|
+
"fromAsset":"base_usdc","toAsset":"sol_usdc","recipient":"7Gx4…","refundTo":"0x…","originChain":"base",
|
|
156
|
+
"amountOutQuote":"8.91","amountOut":"8.93","destTx":"…","depositAddress":"0x…","statusUrl":"https://…"}]}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### `assets`
|
|
160
|
+
Bridge destinations and valid origins, live from the API.
|
|
161
|
+
```json
|
|
162
|
+
{"ok":true,"command":"assets","assets":{"sol_usdc":{"chain":"sol","symbol":"USDC","decimals":6,"isNative":false},"…":{}},
|
|
163
|
+
"origins":["base_eth","base_usdc","hood_eth","hood_usdg","arb_eth","arb_usdc","bsc_bnb","bsc_usdc","bsc_usdt"]}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### `recover [--to ADDR] [--chain C|all]`
|
|
167
|
+
Sweep every registered burner that still holds funds to the agent wallet (or `--to`). Idempotent and safe at any time. Swept funds land in the **public** wallet; `deposit` again to make them private. ~10–60 s per chain.
|
|
168
|
+
```json
|
|
169
|
+
{"ok":true,"command":"recover","recovered":[{"chain":"base","to":"0x…","swept":1,"dust":0,"errors":0}]}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### `login`, `logout`, `version`, `latest`, `help`
|
|
173
|
+
`login` signs and caches the sign-in message (`{"address"}`); `logout` deletes the stored key and cache (`{"removed":[…]}`); `version` and `latest` report versions.
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## 5. Chains, pools, fees and minimums
|
|
178
|
+
|
|
179
|
+
| `--chain` | Pools (`--pool`) | Min deposit | Min send / swap / bridge | Flat fee | DEX for `swap` |
|
|
180
|
+
|---|---|---|---|---|---|
|
|
181
|
+
| `base` (default) | `eth`, `usdc` | 0.001 ETH · 3 USDC | 0.001 ETH · 2 USDC | 0.00015 ETH · 1 USDC | Uniswap V3 |
|
|
182
|
+
| `robinhood` | `eth`, `usdg` | 0.001 ETH · 3 USDG | 0.001 ETH · 2 USDG | 0.00015 ETH · 0.5 USDG | Uniswap V3 |
|
|
183
|
+
| `arbitrum` | `eth`, `usdc` | 0.001 ETH · 3 USDC | 0.001 ETH · 2 USDC | 0.00015 ETH · 0.5 USDC | Uniswap V3 |
|
|
184
|
+
| `bsc` | `bnb`, `usdc`, `usdt` | 0.02 BNB · 3 USDC/USDT | 0.001 BNB · 2 USDC/USDT | 0.001 BNB · 0.5 USDC/USDT | PancakeSwap V3 |
|
|
185
|
+
|
|
186
|
+
- **Fee** on every private spend = flat fee + 0.35% of the amount, deducted from the amount. Example: `send 10` USDC on Base → fee 1 + 0.035 = 1.035, recipient gets 8.965.
|
|
187
|
+
- A spend must be more than twice its own fee; the CLI enforces the minimums above before doing anything.
|
|
188
|
+
- Bridges pay the pool fee plus the solver's quote (shown as `amountOutQuote`); each route also has a solver minimum.
|
|
189
|
+
- `deposit` costs only network gas; there is no Blackpool fee on shielding.
|
|
79
190
|
|
|
80
|
-
|
|
191
|
+
---
|
|
81
192
|
|
|
82
|
-
|
|
193
|
+
## 6. Bridging
|
|
83
194
|
|
|
84
|
-
|
|
195
|
+
**Origins** (`--from`): `base_eth`, `base_usdc`, `hood_eth`, `hood_usdg` (Robinhood Chain), `arb_eth`, `arb_usdc`, `bsc_bnb`, `bsc_usdc`, `bsc_usdt`.
|
|
85
196
|
|
|
86
|
-
|
|
197
|
+
**Destinations** (`dest-asset`; run `blackpool assets` for the live list):
|
|
87
198
|
|
|
199
|
+
| Chain | Assets | Recipient format |
|
|
200
|
+
|---|---|---|
|
|
201
|
+
| Base | `base_eth`, `base_weth`, `base_usdc`, `base_cbbtc` | EVM `0x…` |
|
|
202
|
+
| Ethereum | `eth_eth`, `eth_weth`, `eth_usdc`, `eth_usdt`, `eth_cbbtc` | EVM `0x…` |
|
|
203
|
+
| Arbitrum | `arb_eth`, `arb_weth`, `arb_usdc`, `arb_usdt`, `arb_arb` | EVM `0x…` |
|
|
204
|
+
| BNB Chain | `bsc_bnb`, `bsc_usdc`, `bsc_usdt` | EVM `0x…` |
|
|
205
|
+
| Robinhood Chain | `hood_eth`, `hood_usdg`, `hood_weth`, `hood_usde` | EVM `0x…` |
|
|
206
|
+
| Solana | `sol_sol`, `sol_usdc`, `sol_usdt` | base58 public key |
|
|
207
|
+
|
|
208
|
+
**Statuses** in `bridges`: `PENDING_DEPOSIT` → `PROCESSING` → `SUCCESS`, or `REFUNDED` / `FAILED` (refund to `refundTo` on `originChain`). Treat any other value as in progress.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## 7. Recipes
|
|
213
|
+
|
|
214
|
+
### Pay an invoice exactly
|
|
88
215
|
```sh
|
|
89
|
-
|
|
90
|
-
blackpool
|
|
216
|
+
# recipient must receive 50 USDC on Base: amount = (50 + 1) / 0.9965 = 51.18 (round up)
|
|
217
|
+
blackpool balance --chain base --pool usdc --json # need >= 51.18
|
|
218
|
+
blackpool send 0xVENDOR 51.18 --pool usdc --chain base --json
|
|
91
219
|
```
|
|
92
220
|
|
|
93
|
-
|
|
221
|
+
### Top up only when needed
|
|
222
|
+
```sh
|
|
223
|
+
bal=$(blackpool balance --chain base --pool usdc --json | jq -r .balance)
|
|
224
|
+
if (( $(echo "$bal < 51.18" | bc -l) )); then blackpool deposit 100 --pool usdc --chain base --json; fi
|
|
225
|
+
```
|
|
94
226
|
|
|
227
|
+
### Batch payouts (sequential, never parallel)
|
|
95
228
|
```sh
|
|
96
|
-
|
|
229
|
+
while IFS=, read -r to amount; do
|
|
230
|
+
out=$(blackpool send "$to" "$amount" --pool usdc --chain base --json)
|
|
231
|
+
echo "$out" >> payouts.jsonl
|
|
232
|
+
[ "$(echo "$out" | jq -r .ok)" = "true" ] || { echo "stopped at $to"; break; }
|
|
233
|
+
done < payouts.csv
|
|
97
234
|
```
|
|
235
|
+
Run payouts one at a time: each spend consumes notes and returns change, so parallel sends from one account can race.
|
|
98
236
|
|
|
99
|
-
|
|
237
|
+
### Swap ETH to USDC privately
|
|
238
|
+
```sh
|
|
239
|
+
blackpool swap 0.01 --from eth --chain base --json
|
|
240
|
+
```
|
|
100
241
|
|
|
242
|
+
### Bridge to Solana without blocking
|
|
101
243
|
```sh
|
|
102
244
|
blackpool bridge sol_usdc <solana-address> 10 --from base_usdc --no-wait --json
|
|
103
|
-
blackpool bridges --json
|
|
245
|
+
blackpool bridges --json | jq '.bridges[0].status' # poll every minute until SUCCESS / REFUNDED
|
|
104
246
|
```
|
|
105
247
|
|
|
106
|
-
|
|
248
|
+
### Move private funds to another chain (rebalance)
|
|
249
|
+
```sh
|
|
250
|
+
blackpool bridge arb_usdc $(blackpool address --json | jq -r .address) 20 --from base_usdc --json
|
|
251
|
+
blackpool deposit 19 --pool usdc --chain arbitrum --json # re-shield on the destination chain
|
|
252
|
+
```
|
|
253
|
+
The bridge delivers to a public address; shield it again on the destination chain.
|
|
107
254
|
|
|
255
|
+
### Health check before a run
|
|
108
256
|
```sh
|
|
109
|
-
|
|
257
|
+
curl -s https://api.blackpool.cash/api/health | jq '.ok, .relayerGas'
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Clean up after an interrupted swap or bridge
|
|
261
|
+
```sh
|
|
262
|
+
blackpool recover --chain all --json
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## 8. Integration code
|
|
268
|
+
|
|
269
|
+
### Node.js
|
|
270
|
+
```js
|
|
271
|
+
import { execFile } from 'node:child_process'
|
|
272
|
+
|
|
273
|
+
export function blackpool(args, { timeoutMs = 300_000 } = {}) {
|
|
274
|
+
return new Promise((resolve) => {
|
|
275
|
+
execFile('blackpool', [...args, '--json'], { timeout: timeoutMs, env: process.env }, (err, stdout, stderr) => {
|
|
276
|
+
try { resolve(JSON.parse(stdout.trim().split('\n').pop())) }
|
|
277
|
+
catch { resolve({ ok: false, error: (stderr || err?.message || 'no output').trim(), exitCode: err?.code }) }
|
|
278
|
+
})
|
|
279
|
+
})
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const r = await blackpool(['send', '0xRECIPIENT', '10', '--pool', 'usdc', '--chain', 'base'])
|
|
283
|
+
if (!r.ok) throw new Error(r.error)
|
|
284
|
+
console.log(r.txHash, r.received)
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Python
|
|
288
|
+
```python
|
|
289
|
+
import json, subprocess
|
|
290
|
+
|
|
291
|
+
def blackpool(*args, timeout=300):
|
|
292
|
+
p = subprocess.run(["blackpool", *args, "--json"], capture_output=True, text=True, timeout=timeout)
|
|
293
|
+
try:
|
|
294
|
+
return json.loads(p.stdout.strip().splitlines()[-1])
|
|
295
|
+
except (ValueError, IndexError):
|
|
296
|
+
return {"ok": False, "error": (p.stderr or "no output").strip(), "exitCode": p.returncode}
|
|
297
|
+
|
|
298
|
+
r = blackpool("balance", "--chain", "base", "--pool", "usdc")
|
|
299
|
+
print(r["balance"] if r["ok"] else r["error"])
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Tool definition for function-calling models
|
|
303
|
+
Expose one tool and let the model choose the command:
|
|
304
|
+
```json
|
|
305
|
+
{
|
|
306
|
+
"name": "blackpool",
|
|
307
|
+
"description": "Private crypto payments via the Blackpool CLI. Commands: address; balance [--chain base|robinhood|arbitrum|bsc|all] [--pool P] [--wait]; deposit <amount> [--pool P] [--chain C]; send <recipient> <amount> [--pool P] [--chain C]; swap <amount> --from P [--chain C]; bridge <dest-asset> <recipient> <amount> --from ORIGIN [--no-wait]; bridges; assets; recover [--chain C|all]. Returns one JSON object; ok=false carries an error. Never retry deposit/send/swap/bridge without checking balance first.",
|
|
308
|
+
"input_schema": {
|
|
309
|
+
"type": "object",
|
|
310
|
+
"properties": {
|
|
311
|
+
"args": { "type": "array", "items": { "type": "string" }, "description": "CLI arguments, e.g. [\"send\",\"0xabc…\",\"10\",\"--pool\",\"usdc\",\"--chain\",\"base\"]" }
|
|
312
|
+
},
|
|
313
|
+
"required": ["args"]
|
|
314
|
+
}
|
|
315
|
+
}
|
|
110
316
|
```
|
|
317
|
+
Implement it with the Node or Python wrapper above. Allow-list the first argument to the commands you want the agent to use (for example only `balance`, `send` and `bridges`).
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## 9. Output contract
|
|
322
|
+
|
|
323
|
+
- stdout: exactly one line of JSON when `--json` (or `BLACKPOOL_JSON=1`) is set. stderr: human progress, safe to log.
|
|
324
|
+
- Envelope: `{"ok": true, "command": "<name>", …fields}` or `{"ok": false, "command": "<name>", "error": "<message>"}`.
|
|
325
|
+
- Amounts are decimal strings in token units (some input echoes such as `amount` are numbers). Tx hashes are 0x-hex; `explorer` is a full URL.
|
|
326
|
+
- Exit codes: `0` success · `1` failed or refused (including amounts under a minimum) · `2` usage (unknown command, missing arguments).
|
|
327
|
+
- New fields may be added; existing fields are not renamed or removed without a major version bump.
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## 10. Errors and what to do
|
|
332
|
+
|
|
333
|
+
| `error` contains | Meaning | Do |
|
|
334
|
+
|---|---|---|
|
|
335
|
+
| `no wallet configured` | `BLACKPOOL_KEY` missing | Set it, or run `blackpool login`. |
|
|
336
|
+
| `invalid BLACKPOOL_KEY` / `stored key invalid` | Not a 0x hex private key | Fix the key. |
|
|
337
|
+
| `minimum deposit is …` / `minimum send is …` | Below the floor in §5 | Use a larger amount. |
|
|
338
|
+
| `unknown pool` / `unknown chain` / `unknown --from` | Wrong flag value | Use the values in §5–6. |
|
|
339
|
+
| `invalid recipient address` | Wrong format for the destination | EVM `0x…` (40 hex) or Solana base58. |
|
|
340
|
+
| `insufficient` / `no unspent` | Private balance too low | `balance`, then `deposit` more. |
|
|
341
|
+
| `Withdrawal must be more than twice the fee` | Amount too close to the fee | Larger amount. |
|
|
342
|
+
| `Amount is too low for this route. Minimum is …` | Solver minimum for that bridge | Bridge at least that much. |
|
|
343
|
+
| `rate limited, slow down` | API limit (40 relay ops, 600 reads per minute per IP) | The CLI already waited and retried 4 times; pause a minute. |
|
|
344
|
+
| `simulation failed: …` | The relayer refused a transaction that would revert | Do not retry blindly; check `balance`; report the message. |
|
|
345
|
+
| `reshield would revert` / `swap output … too small` | Swap stopped after funds reached the burner | `recover`, then `deposit` again. |
|
|
346
|
+
| `solver refunded` / `bridge failed at solver` | Bridge did not complete | Refund goes to the agent wallet on the origin chain; `deposit` to re-shield. |
|
|
347
|
+
| `timeout` / `fetch failed` / `HTTP 5xx` | Network or service problem | Check https://blackpool.cash/status; for write commands check `balance --wait` before retrying. |
|
|
348
|
+
|
|
349
|
+
---
|
|
111
350
|
|
|
112
|
-
##
|
|
351
|
+
## 11. Retries, timeouts, concurrency
|
|
113
352
|
|
|
114
|
-
-
|
|
115
|
-
-
|
|
116
|
-
-
|
|
117
|
-
-
|
|
118
|
-
-
|
|
119
|
-
|
|
353
|
+
- Safe to retry any time: `address`, `balance`, `assets`, `bridges`, `recover`, `version`, `latest`.
|
|
354
|
+
- **Not** safe to retry blindly: `deposit`, `send`, `swap`, `bridge`. A timeout can mean the transaction landed. Check `balance --wait` (or `bridges`) and only retry if the balance is unchanged.
|
|
355
|
+
- Give every command a timeout of **at least 300 s** (`bridge` without `--no-wait` up to 420 s).
|
|
356
|
+
- One write command at a time per account. Reads can run in parallel.
|
|
357
|
+
- A private balance can read `0` for a few seconds after a deposit while the indexer catches up; use `--wait`.
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## 12. Security
|
|
362
|
+
|
|
363
|
+
- **Dedicated agent wallet.** Fund it with only what the agent may spend. Never use a personal or treasury key.
|
|
364
|
+
- `BLACKPOOL_KEY` never leaves the machine: it signs the sign-in message, deposit approvals and deposit transactions locally.
|
|
365
|
+
- The **sign-in signature** is cached in `$BLACKPOOL_HOME/config.json` (mode 600) and sent to the API with each private operation. The API derives the private account keys from it in memory to build the proof and does not store or log it, but anyone holding that signature can spend the agent's private balance. Treat the config directory like a key: never print it, never put it in prompts, logs or tool output.
|
|
366
|
+
- Only sign the Blackpool sign-in message on blackpool.cash or with this CLI.
|
|
367
|
+
- The contracts and circuits have not been externally audited; pools are upgradeable by an admin key during launch. Size balances accordingly. Details: https://blackpool.cash/docs#security
|
|
368
|
+
- Report vulnerabilities privately to hello@blackpool.cash (subject `security`).
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## 13. Direct API (advanced)
|
|
373
|
+
|
|
374
|
+
The CLI is the supported interface. If you cannot run Node.js, the same operations are HTTP calls on `https://api.blackpool.cash` (`/api/balance`, `/api/deposit/prepare`, `/api/withdraw`, `/api/swap-private`, `/api/bridge/quote`, `/api/swap`, `/api/intents`, `/api/burner/*`, `/api/health`), all JSON. They need the sign-in signature (EIP-191 signature of the exact message below by the agent wallet), and deposits need you to sign and broadcast the returned transaction yourself. Endpoint list: https://blackpool.cash/docs#api
|
|
375
|
+
|
|
376
|
+
```text
|
|
377
|
+
Welcome to Blackpool
|
|
378
|
+
|
|
379
|
+
Sign this message to access your private account.
|
|
380
|
+
|
|
381
|
+
- Gas free: no transaction is sent
|
|
382
|
+
- Your private account keys are derived from this signature
|
|
383
|
+
- It cannot move funds from your wallet or approve spending
|
|
384
|
+
- Only sign it on blackpool.cash or the Blackpool CLI
|
|
385
|
+
```
|
|
120
386
|
|
|
121
|
-
|
|
387
|
+
The message is part of the account: a different message, even by one character, is a different (empty) account.
|
|
122
388
|
|
|
123
|
-
|
|
124
|
-
- `BLACKPOOL_KEY` stays on the machine. It is used to sign the sign-in message and the deposit transaction locally; it is never sent to the API.
|
|
125
|
-
- The sign-in signature **is** sent to the API with each private operation: the API derives your private account keys from it in memory to build the proof, and does not store or log it. Anyone holding that signature can spend the agent's private balance, so protect `~/.blackpool/config.json` like a key, and never paste the signature into prompts, logs or tool output.
|
|
126
|
-
- Pools and circuits have not been externally audited yet. Keep balances proportional to that risk. Details: https://blackpool.cash/docs#security
|
|
389
|
+
---
|
|
127
390
|
|
|
128
|
-
## Working on this repository
|
|
391
|
+
## 14. Working on this repository
|
|
129
392
|
|
|
130
|
-
If you are a coding agent editing this repository rather than using the CLI: the CLI lives in `cli/`, contracts in `contracts/`, circuits in `circuits/`, the web app in `frontend/`. Run `npx hardhat test` before changing contracts or core libraries
|
|
393
|
+
If you are a coding agent editing this repository rather than using the CLI: the CLI lives in `cli/`, contracts in `contracts/`, circuits in `circuits/`, client libraries in `src/`, the web app in `frontend/`. Run `npx hardhat test` before changing contracts or core libraries. Keep the sign-in message, note format and circuit byte-identical across `src/`, `cli/` and `frontend/` (changing any of them changes every account). Never commit keys, `.env` files or credentials. Keep this file in sync with `cli/bin/blackpool.js` when commands or output fields change.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blackpool/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Private payments for onchain agents. CLI for BLACKPOOL - shield, send, swap, bridge with zero-knowledge privacy on Base, Robinhood Chain, Arbitrum, and BNB Smart Chain.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"blackpool": "bin/blackpool.js"
|