blackbox-mcp 0.1.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 +497 -0
- package/dist/api.d.ts +99 -0
- package/dist/api.js +160 -0
- package/dist/api.js.map +1 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.js +25 -0
- package/dist/config.js.map +1 -0
- package/dist/crypto.d.ts +18 -0
- package/dist/crypto.js +100 -0
- package/dist/crypto.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +932 -0
- package/dist/index.js.map +1 -0
- package/dist/wallet.d.ts +35 -0
- package/dist/wallet.js +144 -0
- package/dist/wallet.js.map +1 -0
- package/package.json +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
# BlackBox MCP Server
|
|
2
|
+
|
|
3
|
+
A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that enables AI agents to interact with the [BlackBox Protocol](https://theblackbox.network) — a privacy-preserving, cross-chain payment system built on distributed threshold cryptography.
|
|
4
|
+
|
|
5
|
+
## What is This?
|
|
6
|
+
|
|
7
|
+
This MCP server gives any AI agent the ability to:
|
|
8
|
+
|
|
9
|
+
- **Deposit** funds into the BlackBox treasury on any supported chain
|
|
10
|
+
- **Claim** one-time-use private keys via 3-of-5 distributed key generation
|
|
11
|
+
- **Withdraw** funds on any supported chain (including cross-chain)
|
|
12
|
+
- **Relay** gas-free withdrawals via the built-in relayer
|
|
13
|
+
- **Manage** wallets with encrypted local storage
|
|
14
|
+
|
|
15
|
+
The agent never sees the full private key during key generation — each of the 5 DKG nodes only holds a share. The agent reconstructs the key locally using Lagrange interpolation over secp256k1.
|
|
16
|
+
|
|
17
|
+
## Architecture
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
AI Agent (Claude, Cursor, Windsurf, custom agents)
|
|
21
|
+
|
|
|
22
|
+
| MCP Protocol (stdio)
|
|
23
|
+
|
|
|
24
|
+
BlackBox MCP Server
|
|
25
|
+
|
|
|
26
|
+
|--- DKG Node 1 (theblackbox.network/node1)
|
|
27
|
+
|--- DKG Node 2 (theblackbox.network/node2)
|
|
28
|
+
|--- DKG Node 3 (theblackbox.network/node3) ← 3-of-5 threshold
|
|
29
|
+
|--- DKG Node 4 (theblackbox.network/node4)
|
|
30
|
+
|--- DKG Node 5 (theblackbox.network/node5)
|
|
31
|
+
|
|
|
32
|
+
|--- EVM Chains (Sepolia, Base Sepolia, BNB Testnet, Polygon Amoy, Hyperliquid)
|
|
33
|
+
|--- Solana (Devnet)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Supported Chains & Denominations
|
|
37
|
+
|
|
38
|
+
50 registered merkle roots across 7 chains, 4 tokens, and 14 chain+token combinations:
|
|
39
|
+
|
|
40
|
+
| Chain | Token | Denominations |
|
|
41
|
+
|-------|-------|---------------|
|
|
42
|
+
| Sepolia | ETH | 0.001, 0.01, 0.05, 0.1, 0.5, 1 |
|
|
43
|
+
| Sepolia | USDC | 1, 2, 5, 10 |
|
|
44
|
+
| Sepolia | LINK | 0.5, 1, 2 |
|
|
45
|
+
| Base Sepolia | ETH | 0.001, 0.01, 0.05, 0.1 |
|
|
46
|
+
| Base Sepolia | USDC | 1, 2, 5 |
|
|
47
|
+
| BNB Testnet | TBNB | 0.01, 0.05, 0.1, 0.5 |
|
|
48
|
+
| BNB Testnet | USDC | 1, 2, 5 |
|
|
49
|
+
| BNB Testnet | LINK | 0.5, 1, 2 |
|
|
50
|
+
| Polygon Amoy | POL | 1, 2 |
|
|
51
|
+
| Polygon Amoy | USDC | 1, 2, 5 |
|
|
52
|
+
| Hyperliquid Testnet | HYPE | 0.01, 0.1, 0.5 |
|
|
53
|
+
| Hyperliquid Testnet | USDC | 1, 2, 5 |
|
|
54
|
+
| Solana Devnet | SOL | 0.1, 0.5, 1 |
|
|
55
|
+
| Solana Devnet | USDC | 1, 2, 5 |
|
|
56
|
+
|
|
57
|
+
> Use the `get_available_denominations` tool to query live denominations — new ones are added regularly.
|
|
58
|
+
|
|
59
|
+
## Quick Start
|
|
60
|
+
|
|
61
|
+
### 1. Install
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
git clone https://github.com/InterNullOrg/blackbox_mcp.git
|
|
65
|
+
cd blackbox_mcp
|
|
66
|
+
npm install
|
|
67
|
+
npm run build
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 2. Configure Your MCP Client
|
|
71
|
+
|
|
72
|
+
Add the server to your AI agent's MCP configuration.
|
|
73
|
+
|
|
74
|
+
<details>
|
|
75
|
+
<summary><strong>Claude Desktop</strong></summary>
|
|
76
|
+
|
|
77
|
+
Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"mcpServers": {
|
|
82
|
+
"blackbox": {
|
|
83
|
+
"command": "node",
|
|
84
|
+
"args": ["/absolute/path/to/blackbox_mcp/dist/index.js"],
|
|
85
|
+
"env": {
|
|
86
|
+
"DKG_NODE_1": "https://theblackbox.network/node1",
|
|
87
|
+
"DKG_NODE_2": "https://theblackbox.network/node2",
|
|
88
|
+
"DKG_NODE_3": "https://theblackbox.network/node3",
|
|
89
|
+
"DKG_NODE_4": "https://theblackbox.network/node4",
|
|
90
|
+
"DKG_NODE_5": "https://theblackbox.network/node5"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
</details>
|
|
97
|
+
|
|
98
|
+
<details>
|
|
99
|
+
<summary><strong>Claude Code</strong></summary>
|
|
100
|
+
|
|
101
|
+
Add to project `.mcp.json` or `~/.claude/settings.json`:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"mcpServers": {
|
|
106
|
+
"blackbox": {
|
|
107
|
+
"command": "node",
|
|
108
|
+
"args": ["/absolute/path/to/blackbox_mcp/dist/index.js"],
|
|
109
|
+
"env": {
|
|
110
|
+
"DKG_NODE_1": "https://theblackbox.network/node1",
|
|
111
|
+
"DKG_NODE_2": "https://theblackbox.network/node2",
|
|
112
|
+
"DKG_NODE_3": "https://theblackbox.network/node3",
|
|
113
|
+
"DKG_NODE_4": "https://theblackbox.network/node4",
|
|
114
|
+
"DKG_NODE_5": "https://theblackbox.network/node5"
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
</details>
|
|
121
|
+
|
|
122
|
+
<details>
|
|
123
|
+
<summary><strong>Cursor</strong></summary>
|
|
124
|
+
|
|
125
|
+
Add to `.cursor/mcp.json` in your project root:
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"mcpServers": {
|
|
130
|
+
"blackbox": {
|
|
131
|
+
"command": "node",
|
|
132
|
+
"args": ["/absolute/path/to/blackbox_mcp/dist/index.js"],
|
|
133
|
+
"env": {
|
|
134
|
+
"DKG_NODE_1": "https://theblackbox.network/node1",
|
|
135
|
+
"DKG_NODE_2": "https://theblackbox.network/node2",
|
|
136
|
+
"DKG_NODE_3": "https://theblackbox.network/node3",
|
|
137
|
+
"DKG_NODE_4": "https://theblackbox.network/node4",
|
|
138
|
+
"DKG_NODE_5": "https://theblackbox.network/node5"
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
</details>
|
|
145
|
+
|
|
146
|
+
<details>
|
|
147
|
+
<summary><strong>Development mode (hot reload)</strong></summary>
|
|
148
|
+
|
|
149
|
+
Use `tsx` instead of `node` for development:
|
|
150
|
+
|
|
151
|
+
```json
|
|
152
|
+
{
|
|
153
|
+
"mcpServers": {
|
|
154
|
+
"blackbox": {
|
|
155
|
+
"command": "npx",
|
|
156
|
+
"args": ["tsx", "/absolute/path/to/blackbox_mcp/src/index.ts"],
|
|
157
|
+
"env": {
|
|
158
|
+
"DKG_NODE_1": "https://theblackbox.network/node1",
|
|
159
|
+
"DKG_NODE_2": "https://theblackbox.network/node2",
|
|
160
|
+
"DKG_NODE_3": "https://theblackbox.network/node3",
|
|
161
|
+
"DKG_NODE_4": "https://theblackbox.network/node4",
|
|
162
|
+
"DKG_NODE_5": "https://theblackbox.network/node5"
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
</details>
|
|
169
|
+
|
|
170
|
+
### 3. Talk to Your Agent
|
|
171
|
+
|
|
172
|
+
Once configured, the agent automatically discovers all 18 tools. Example prompts:
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
"Create a wallet and deposit 0.1 ETH on Sepolia"
|
|
176
|
+
"Claim 10 keys of 0.001 ETH on Base Sepolia from my deposit"
|
|
177
|
+
"Withdraw key #3 to my wallet on Base Sepolia"
|
|
178
|
+
"Check the health of the DKG network"
|
|
179
|
+
"Move 0.05 ETH from Sepolia to Base Sepolia privately"
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Available Tools (18)
|
|
183
|
+
|
|
184
|
+
### Wallet Management
|
|
185
|
+
| Tool | Description |
|
|
186
|
+
|------|-------------|
|
|
187
|
+
| `create_wallet` | Create a new EVM or Solana wallet with encrypted storage |
|
|
188
|
+
| `import_wallet` | Import an existing wallet from a private key |
|
|
189
|
+
| `list_wallets` | List all stored wallets |
|
|
190
|
+
| `get_balance` | Get native and token balances on any chain |
|
|
191
|
+
|
|
192
|
+
### Protocol Discovery
|
|
193
|
+
| Tool | Description |
|
|
194
|
+
|------|-------------|
|
|
195
|
+
| `get_supported_chains` | List all supported chains with RPC URLs and treasury addresses |
|
|
196
|
+
| `get_chain_tokens` | Get tokens and denominations for a specific chain |
|
|
197
|
+
| `get_available_denominations` | Get registered denominations (merkle roots) for a chain |
|
|
198
|
+
| `get_token_mappings` | Get cross-chain token mapping rules |
|
|
199
|
+
| `check_health` | Check DKG network health |
|
|
200
|
+
| `get_leaderboard` | Get top depositors leaderboard |
|
|
201
|
+
|
|
202
|
+
### Core Operations
|
|
203
|
+
| Tool | Description |
|
|
204
|
+
|------|-------------|
|
|
205
|
+
| `deposit` | Deposit funds into the treasury (handles ERC20 approval automatically) |
|
|
206
|
+
| `claim_keys` | Request keyshares from DKG nodes and reconstruct private keys via Lagrange interpolation |
|
|
207
|
+
| `withdraw_onchain` | Execute on-chain withdrawal using a one-time key |
|
|
208
|
+
| `deposit_and_claim` | Combined deposit + claim in one step |
|
|
209
|
+
|
|
210
|
+
### Relay & Swap
|
|
211
|
+
| Tool | Description |
|
|
212
|
+
|------|-------------|
|
|
213
|
+
| `relay_withdraw` | Gas-free withdrawal via the relayer service |
|
|
214
|
+
| `check_relay_status` | Check relay job status |
|
|
215
|
+
| `get_relay_info` | Get relay service info and fees |
|
|
216
|
+
| `get_swap_quote` | Get cross-chain swap quote |
|
|
217
|
+
|
|
218
|
+
### Agent Guide Resource
|
|
219
|
+
|
|
220
|
+
The server exposes a `blackbox://agent-guide` resource containing detailed instructions for agents — denomination rules, security model, error handling, and step-by-step workflows. MCP-compatible agents read this automatically.
|
|
221
|
+
|
|
222
|
+
## Environment Variables
|
|
223
|
+
|
|
224
|
+
| Variable | Description | Default |
|
|
225
|
+
|----------|-------------|---------|
|
|
226
|
+
| `MCP_TRANSPORT` | Transport mode: `stdio` or `http` | `stdio` |
|
|
227
|
+
| `PORT` | HTTP server port (when `MCP_TRANSPORT=http`) | `3001` |
|
|
228
|
+
| `CORS_ORIGIN` | Allowed CORS origin (when `MCP_TRANSPORT=http`) | `*` |
|
|
229
|
+
| `DKG_NODE_1` through `DKG_NODE_5` | Individual DKG node URLs | `http://localhost:8081-8085` |
|
|
230
|
+
| `DKG_NODE_URLS` | Comma-separated node URLs (alternative) | — |
|
|
231
|
+
| `DKG_THRESHOLD` | Minimum shares needed for reconstruction | `3` |
|
|
232
|
+
| `WALLET_STORE_PATH` | Path to encrypted wallet storage | `./wallets` |
|
|
233
|
+
|
|
234
|
+
## Deployment
|
|
235
|
+
|
|
236
|
+
The server supports two transport modes:
|
|
237
|
+
|
|
238
|
+
| Mode | Use Case | How |
|
|
239
|
+
|------|----------|-----|
|
|
240
|
+
| **stdio** (default) | Local MCP clients (Claude Desktop, Cursor, Claude Code) | `node dist/index.js` |
|
|
241
|
+
| **http** | Hosted server for web agents, remote access | `MCP_TRANSPORT=http node dist/index.js` |
|
|
242
|
+
|
|
243
|
+
### Deploy on EC2 (Docker)
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
# On your EC2 instance
|
|
247
|
+
git clone https://github.com/InterNullOrg/blackbox_mcp.git
|
|
248
|
+
cd blackbox_mcp
|
|
249
|
+
docker compose up -d
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
The server will be available at `http://<your-ec2-ip>:3001/mcp` with a health check at `/health`.
|
|
253
|
+
|
|
254
|
+
To use a custom port or restrict CORS:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
PORT=8080 CORS_ORIGIN=https://yourdomain.com docker compose up -d
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Deploy on EC2 (without Docker)
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
git clone https://github.com/InterNullOrg/blackbox_mcp.git
|
|
264
|
+
cd blackbox_mcp
|
|
265
|
+
npm install
|
|
266
|
+
npm run build
|
|
267
|
+
|
|
268
|
+
# Run with systemd, pm2, or directly:
|
|
269
|
+
MCP_TRANSPORT=http PORT=3001 \
|
|
270
|
+
DKG_NODE_1=https://theblackbox.network/node1 \
|
|
271
|
+
DKG_NODE_2=https://theblackbox.network/node2 \
|
|
272
|
+
DKG_NODE_3=https://theblackbox.network/node3 \
|
|
273
|
+
DKG_NODE_4=https://theblackbox.network/node4 \
|
|
274
|
+
DKG_NODE_5=https://theblackbox.network/node5 \
|
|
275
|
+
node dist/index.js
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
With pm2 for process management:
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
npm install -g pm2
|
|
282
|
+
MCP_TRANSPORT=http PORT=3001 pm2 start dist/index.js --name blackbox-mcp
|
|
283
|
+
pm2 save
|
|
284
|
+
pm2 startup # auto-start on reboot
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Deploy behind Nginx (HTTPS)
|
|
288
|
+
|
|
289
|
+
```nginx
|
|
290
|
+
server {
|
|
291
|
+
listen 443 ssl;
|
|
292
|
+
server_name mcp.yourdomain.com;
|
|
293
|
+
|
|
294
|
+
ssl_certificate /etc/letsencrypt/live/mcp.yourdomain.com/fullchain.pem;
|
|
295
|
+
ssl_certificate_key /etc/letsencrypt/live/mcp.yourdomain.com/privkey.pem;
|
|
296
|
+
|
|
297
|
+
location / {
|
|
298
|
+
proxy_pass http://127.0.0.1:3001;
|
|
299
|
+
proxy_http_version 1.1;
|
|
300
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
301
|
+
proxy_set_header Connection "upgrade";
|
|
302
|
+
proxy_set_header Host $host;
|
|
303
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
304
|
+
proxy_read_timeout 300s;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### HTTP API Endpoints
|
|
310
|
+
|
|
311
|
+
| Endpoint | Method | Description |
|
|
312
|
+
|----------|--------|-------------|
|
|
313
|
+
| `/mcp` | POST | MCP Streamable HTTP endpoint (all tool calls go here) |
|
|
314
|
+
| `/mcp` | GET | SSE stream for server-initiated messages |
|
|
315
|
+
| `/mcp` | DELETE | Close session |
|
|
316
|
+
| `/health` | GET | Health check — returns `{"status":"ok","sessions":N}` |
|
|
317
|
+
|
|
318
|
+
### Connecting Web Agents to Hosted Server
|
|
319
|
+
|
|
320
|
+
Web-based agents connect via the Streamable HTTP transport:
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
324
|
+
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
325
|
+
|
|
326
|
+
const transport = new StreamableHTTPClientTransport(
|
|
327
|
+
new URL('https://mcp.yourdomain.com/mcp')
|
|
328
|
+
);
|
|
329
|
+
|
|
330
|
+
const client = new Client({ name: 'my-web-agent', version: '1.0.0' });
|
|
331
|
+
await client.connect(transport);
|
|
332
|
+
|
|
333
|
+
// Now call any of the 18 tools
|
|
334
|
+
const result = await client.callTool('check_health', {});
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### NPM Install (for local agents)
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
# Install globally
|
|
341
|
+
npm install -g @anthropic-ai/blackbox-mcp
|
|
342
|
+
|
|
343
|
+
# Then use in MCP config:
|
|
344
|
+
# "command": "blackbox-mcp"
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Or use npx without installing:
|
|
348
|
+
|
|
349
|
+
```json
|
|
350
|
+
{
|
|
351
|
+
"mcpServers": {
|
|
352
|
+
"blackbox": {
|
|
353
|
+
"command": "npx",
|
|
354
|
+
"args": ["@anthropic-ai/blackbox-mcp"],
|
|
355
|
+
"env": {
|
|
356
|
+
"DKG_NODE_1": "https://theblackbox.network/node1",
|
|
357
|
+
"DKG_NODE_2": "https://theblackbox.network/node2",
|
|
358
|
+
"DKG_NODE_3": "https://theblackbox.network/node3",
|
|
359
|
+
"DKG_NODE_4": "https://theblackbox.network/node4",
|
|
360
|
+
"DKG_NODE_5": "https://theblackbox.network/node5"
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## How It Works
|
|
368
|
+
|
|
369
|
+
### Deposit
|
|
370
|
+
|
|
371
|
+
1. Agent calls `deposit` with chain, amount, and token
|
|
372
|
+
2. MCP server submits a deposit transaction to the on-chain treasury contract
|
|
373
|
+
3. Treasury locks the funds
|
|
374
|
+
|
|
375
|
+
### Key Claim (Distributed Key Generation)
|
|
376
|
+
|
|
377
|
+
1. Agent calls `claim_keys` with the deposit tx hash and withdrawal requests
|
|
378
|
+
2. MCP server signs a proof message with the agent's wallet
|
|
379
|
+
3. Each of the 5 DKG nodes independently:
|
|
380
|
+
- Verifies the deposit on-chain
|
|
381
|
+
- Verifies the signature
|
|
382
|
+
- Returns its keyshare (a partial secret)
|
|
383
|
+
4. MCP server reconstructs the full private key locally using **Lagrange interpolation** over secp256k1
|
|
384
|
+
5. Each key is a one-time-use ECDSA key tied to a specific merkle root and key index
|
|
385
|
+
|
|
386
|
+
No single node ever knows the full private key. Any 3-of-5 shares are sufficient.
|
|
387
|
+
|
|
388
|
+
### Withdrawal
|
|
389
|
+
|
|
390
|
+
1. Agent calls `withdraw_onchain` (or `relay_withdraw` for gas-free)
|
|
391
|
+
2. MCP server signs the withdrawal message with the reconstructed one-time key
|
|
392
|
+
3. The treasury contract verifies:
|
|
393
|
+
- ECDSA signature validity
|
|
394
|
+
- Merkle proof (key belongs to a registered batch)
|
|
395
|
+
- Nullifier (key hasn't been used before)
|
|
396
|
+
4. Funds are released to the recipient
|
|
397
|
+
5. The key is permanently marked as spent
|
|
398
|
+
|
|
399
|
+
### Cross-Chain
|
|
400
|
+
|
|
401
|
+
Deposits on chain A can generate withdrawal keys for chain B. Requirements:
|
|
402
|
+
- A valid token mapping exists between the chains (admin-configured)
|
|
403
|
+
- The denomination is registered on the target chain
|
|
404
|
+
- The deposit amount covers the total requested value
|
|
405
|
+
|
|
406
|
+
## Security Model
|
|
407
|
+
|
|
408
|
+
| Property | Implementation |
|
|
409
|
+
|----------|---------------|
|
|
410
|
+
| No single point of failure | 3-of-5 threshold — any 3 nodes reconstruct, no pair can |
|
|
411
|
+
| One-time keys | On-chain nullifier prevents reuse |
|
|
412
|
+
| Wallet encryption | AES-256-GCM with PBKDF2 (100k iterations) |
|
|
413
|
+
| Request authentication | ECDSA/Ed25519 signature on every keyshare request |
|
|
414
|
+
| Deposit verification | Each node independently verifies deposits on-chain |
|
|
415
|
+
| Idempotent claims | Re-requesting same deposit returns identical keys |
|
|
416
|
+
| UTXO model | Deposit fully allocated on first claim; different configs rejected |
|
|
417
|
+
| Timestamp validation | Requests must be within 5 minutes |
|
|
418
|
+
|
|
419
|
+
## Agentic Usage Patterns
|
|
420
|
+
|
|
421
|
+
### Privacy Payment Agent
|
|
422
|
+
```
|
|
423
|
+
1. create_wallet → agent wallet
|
|
424
|
+
2. (user funds wallet with ETH)
|
|
425
|
+
3. deposit → 0.001 ETH on Sepolia
|
|
426
|
+
4. claim_keys → 1 key for base_sepolia
|
|
427
|
+
5. withdraw_onchain → sends to recipient on Base Sepolia
|
|
428
|
+
(deposit chain != withdrawal chain = unlinkable)
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### Batch Payment Agent
|
|
432
|
+
```
|
|
433
|
+
1. deposit → 0.1 ETH on Sepolia
|
|
434
|
+
2. claim_keys → 100 keys of 0.001 ETH across multiple chains
|
|
435
|
+
3. withdraw_onchain → execute each withdrawal to different recipients
|
|
436
|
+
(each withdrawal is independent and unlinkable)
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
### Gas-Free Agent
|
|
440
|
+
```
|
|
441
|
+
1. claim_keys → get keys from a previous deposit
|
|
442
|
+
2. get_relay_info → check if relay is enabled + get fees
|
|
443
|
+
3. relay_withdraw → relayer pays gas on target chain
|
|
444
|
+
4. check_relay_status → poll until confirmed
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
## Testing
|
|
448
|
+
|
|
449
|
+
The repository includes test suites that were used to validate the protocol:
|
|
450
|
+
|
|
451
|
+
```bash
|
|
452
|
+
# End-to-end: deposit → claim → withdraw
|
|
453
|
+
npx tsx test-e2e.ts
|
|
454
|
+
|
|
455
|
+
# Edge cases: invalid denominations, double-spend, wrong signer, expired timestamps
|
|
456
|
+
npx tsx test-edge-cases.ts
|
|
457
|
+
|
|
458
|
+
# 100-key stress test: all C(5,3)=10 share combinations per key
|
|
459
|
+
npx tsx test-100-keys.ts
|
|
460
|
+
|
|
461
|
+
# Cross-chain 50+50 split with timing measurements
|
|
462
|
+
npx tsx test-100-keys-v2.ts
|
|
463
|
+
|
|
464
|
+
# Idempotency: re-claim returns identical keys
|
|
465
|
+
npx tsx test-idempotency-splits.ts
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### Test Results (Verified)
|
|
469
|
+
|
|
470
|
+
- 200 keys generated across test runs — all reconstructed successfully
|
|
471
|
+
- 2000 share combinations tested (10 per key) — all passed
|
|
472
|
+
- All key_indexes and addresses are unique per batch
|
|
473
|
+
- Re-claims return identical keys (verified 3 times independently)
|
|
474
|
+
- Backend rejects different claim configs for same deposit (UTXO model)
|
|
475
|
+
- Key retrieval: ~52s for 100 keys (P2P mini-VSS exchange)
|
|
476
|
+
- Local reconstruction: ~5ms per key (Lagrange interpolation)
|
|
477
|
+
|
|
478
|
+
## Project Structure
|
|
479
|
+
|
|
480
|
+
```
|
|
481
|
+
blackbox_mcp/
|
|
482
|
+
├── src/
|
|
483
|
+
│ ├── index.ts # MCP server — 18 tools + agent guide resource (stdio + HTTP)
|
|
484
|
+
│ ├── api.ts # BlackBox API client (DKG node communication)
|
|
485
|
+
│ ├── config.ts # Environment configuration loader
|
|
486
|
+
│ ├── crypto.ts # Lagrange interpolation, ECDSA signatures, key reconstruction
|
|
487
|
+
│ └── wallet.ts # Encrypted wallet manager (AES-256-GCM + PBKDF2)
|
|
488
|
+
├── Dockerfile # Docker image for EC2/cloud deployment
|
|
489
|
+
├── docker-compose.yml # One-command deployment
|
|
490
|
+
├── package.json
|
|
491
|
+
├── tsconfig.json
|
|
492
|
+
└── test-*.ts # Test suites
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
## License
|
|
496
|
+
|
|
497
|
+
MIT
|
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { BlackBoxConfig } from './config.js';
|
|
2
|
+
export interface ChainInfo {
|
|
3
|
+
chain_name: string;
|
|
4
|
+
chain_id: number;
|
|
5
|
+
chain_type: string;
|
|
6
|
+
name: string;
|
|
7
|
+
rpc_url: string;
|
|
8
|
+
treasury_address: string;
|
|
9
|
+
block_explorer: string;
|
|
10
|
+
native_currency: string;
|
|
11
|
+
supported_tokens: string[];
|
|
12
|
+
}
|
|
13
|
+
export interface MerkleRoot {
|
|
14
|
+
denomination: string;
|
|
15
|
+
merkle_root_id_on_chain: number;
|
|
16
|
+
token_symbol: string;
|
|
17
|
+
chain_name: string;
|
|
18
|
+
}
|
|
19
|
+
export interface KeyshareResult {
|
|
20
|
+
share_id: string;
|
|
21
|
+
share_value: string;
|
|
22
|
+
key_index: number;
|
|
23
|
+
address: string;
|
|
24
|
+
merkle_root: string;
|
|
25
|
+
merkle_root_id: number;
|
|
26
|
+
merkle_proof: string[];
|
|
27
|
+
denomination: string;
|
|
28
|
+
chain_name: string;
|
|
29
|
+
chain_id: number;
|
|
30
|
+
treasury_address: string;
|
|
31
|
+
token_symbol: string;
|
|
32
|
+
token_address: string;
|
|
33
|
+
token_decimals: number;
|
|
34
|
+
}
|
|
35
|
+
export interface NodeKeyshareResponse {
|
|
36
|
+
success: boolean;
|
|
37
|
+
node_id: number;
|
|
38
|
+
keyshares: KeyshareResult[];
|
|
39
|
+
threshold: number;
|
|
40
|
+
total_nodes: number;
|
|
41
|
+
deposit_amount: number;
|
|
42
|
+
claimed_amount: number;
|
|
43
|
+
remaining_deposit: number;
|
|
44
|
+
}
|
|
45
|
+
export declare class BlackBoxAPI {
|
|
46
|
+
private config;
|
|
47
|
+
constructor(config: BlackBoxConfig);
|
|
48
|
+
private fetchFromAnyNode;
|
|
49
|
+
getHealth(): Promise<any>;
|
|
50
|
+
getChains(): Promise<ChainInfo[]>;
|
|
51
|
+
getTokens(chain: string): Promise<any[]>;
|
|
52
|
+
getMerkleRoots(chain?: string): Promise<MerkleRoot[]>;
|
|
53
|
+
getTokenMappings(): Promise<any>;
|
|
54
|
+
getLeaderboard(limit?: number): Promise<any>;
|
|
55
|
+
requestKeyshares(params: {
|
|
56
|
+
depositTxHash: string;
|
|
57
|
+
sourceChain: string;
|
|
58
|
+
withdrawalRequests: Array<{
|
|
59
|
+
target_chain: string;
|
|
60
|
+
token_symbol: string;
|
|
61
|
+
denomination: string;
|
|
62
|
+
}>;
|
|
63
|
+
userAddress: string;
|
|
64
|
+
signature: string;
|
|
65
|
+
timestamp: number;
|
|
66
|
+
occurrenceOffset?: number;
|
|
67
|
+
spendRequestId?: string;
|
|
68
|
+
}): Promise<Array<{
|
|
69
|
+
success: boolean;
|
|
70
|
+
nodeId?: number;
|
|
71
|
+
keyshares?: KeyshareResult[];
|
|
72
|
+
threshold?: number;
|
|
73
|
+
depositAmount?: number;
|
|
74
|
+
claimedAmount?: number;
|
|
75
|
+
remainingDeposit?: number;
|
|
76
|
+
error?: string;
|
|
77
|
+
}>>;
|
|
78
|
+
relayWithdraw(params: {
|
|
79
|
+
chain: string;
|
|
80
|
+
chainType: string;
|
|
81
|
+
recipient: string;
|
|
82
|
+
amount: string;
|
|
83
|
+
token?: string;
|
|
84
|
+
signature: string;
|
|
85
|
+
merkleProof: string[];
|
|
86
|
+
merkleRootId: number;
|
|
87
|
+
keyIndex: number;
|
|
88
|
+
maxRelayerFee?: string;
|
|
89
|
+
}): Promise<any>;
|
|
90
|
+
getRelayStatus(jobId: string): Promise<any>;
|
|
91
|
+
getSwapQuote(params: {
|
|
92
|
+
assetIn: string;
|
|
93
|
+
assetOut: string;
|
|
94
|
+
amount: string;
|
|
95
|
+
swapType?: string;
|
|
96
|
+
dry?: boolean;
|
|
97
|
+
}): Promise<any>;
|
|
98
|
+
getRelayInfo(): Promise<any>;
|
|
99
|
+
}
|