@trucore/atf 1.0.2 → 1.3.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.
Files changed (3) hide show
  1. package/README.md +579 -260
  2. package/dist/index.js +4101 -786
  3. package/package.json +50 -47
package/README.md CHANGED
@@ -1,260 +1,579 @@
1
- # @trucore/atf
2
-
3
- > Agent Transaction Firewall CLI — simulate, verify, and audit on-chain transactions trustlessly.
4
-
5
- ## One-Liner
6
-
7
- ```bash
8
- npx @trucore/atf@1.0.0 simulate --preset swap_small --verify --pretty
9
- ```
10
-
11
- That's it. No install, no config, no API key required.
12
-
13
- ## What It Does
14
-
15
- 1. Sends a deterministic preset transaction to the ATF public API
16
- 2. Returns **allowed** or **denied** with a reason and receipt hash
17
- 3. Verifies **content_hash** integrity client-side — don't trust TruCore, verify
18
-
19
- ## Install (optional)
20
-
21
- ```bash
22
- npm install -g @trucore/atf@1.0.0
23
- ```
24
-
25
- Or use directly with `npx` (always pin the version):
26
-
27
- ```bash
28
- npx @trucore/atf@1.0.0 simulate --preset swap_small
29
- ```
30
-
31
- ## Commands
32
-
33
- ### `health`
34
-
35
- Check API health and round-trip latency.
36
-
37
- ```bash
38
- npx @trucore/atf@1.0.0 health
39
- npx @trucore/atf@1.0.0 health --pretty
40
- npx @trucore/atf@1.0.0 health --base-url http://localhost:3000
41
- ```
42
-
43
- **Output shape:**
44
-
45
- ```json
46
- { "ok": true, "base_url": "https://api.trucore.xyz", "latency_ms": 42, "response": { "status": "ok" } }
47
- ```
48
-
49
- ### `simulate`
50
-
51
- Run a transaction simulation against the ATF API.
52
-
53
- ```bash
54
- npx @trucore/atf@1.0.0 simulate --preset swap_small --verify
55
- npx @trucore/atf@1.0.0 simulate --preset swap_too_large --pretty
56
- npx @trucore/atf@1.0.0 simulate --json '{"chain_id":1,"value_eth":"0.5"}' --base-url http://localhost:3000
57
- ```
58
-
59
- **Output shape:**
60
-
61
- ```json
62
- { "ok": true, "base_url": "https://api.trucore.xyz", "preset": "swap_small", "verified": true, "response": { "decision": "allowed", "reasons": [], "receipt_hash": "a1b2...64hex", "content_hash": "c3d4...64hex" } }
63
- ```
64
-
65
- ### `approve`
66
-
67
- Approve a pending intent (requires authentication).
68
-
69
- ```bash
70
- npx @trucore/atf@1.0.0 approve --intent abc123 --token mytoken
71
- npx @trucore/atf@1.0.0 approve --intent abc123 --token mytoken --pretty
72
- ```
73
-
74
- **Output shape:**
75
-
76
- ```json
77
- { "ok": true, "base_url": "https://api.trucore.xyz", "intent": "abc123", "response": { "intent_id": "abc123", "status": "approved" } }
78
- ```
79
-
80
- ### `version`
81
-
82
- Show rich version information (CLI version, Node version, build info).
83
-
84
- ```bash
85
- npx @trucore/atf@1.0.0 version
86
- npx @trucore/atf@1.0.0 version --pretty
87
- ```
88
-
89
- **Output shape:**
90
-
91
- ```json
92
- { "ok": true, "cli_version": "1.0.1", "node_version": "v22.0.0", "platform": "linux", "arch": "x64", "default_base_url": "https://api.trucore.xyz", "build_commit": "abc1234", "build_date": "2025-01-01T00:00:00Z" }
93
- ```
94
-
95
- ## Global Options
96
-
97
- | Flag | Description | Default |
98
- |------|-------------|---------|
99
- | `--base-url <url>` | API base URL | `https://api.trucore.xyz` |
100
- | `--timeout-ms <ms>` | Request timeout in milliseconds | `20000` |
101
- | `--format <fmt>` | Output: `json` or `pretty` | `json` |
102
- | `--pretty` | Shorthand for `--format pretty` | `false` |
103
- | `--no-color` | Disable ANSI colors | `false` |
104
- | `--api-key <key>` | API key (also: `ATF_API_KEY` env var) | — |
105
-
106
- ## Simulate Options
107
-
108
- | Flag | Description | Default |
109
- |------|-------------|---------|
110
- | `--preset <name>` | Built-in preset: `swap_small`, `swap_too_large`, `ttl_too_high` | — |
111
- | `--json '<json>'` | Raw JSON transaction body | — |
112
- | `--verify` | Verify content_hash integrity | `false` |
113
- | `--quiet` | Suppress non-essential output | `false` |
114
-
115
- ## Approve Options
116
-
117
- | Flag | Description | Default |
118
- |------|-------------|---------|
119
- | `--intent <id>` | Intent ID to approve (required) | |
120
- | `--intent-id <id>` | Alias for `--intent` (backward compat) | — |
121
- | `--token <bearer>` | Bearer token for auth (also: `ATF_API_KEY` env var) | — |
122
-
123
- ### Presets
124
-
125
- | Preset | Description | Expected |
126
- |--------|-------------|----------|
127
- | `swap_small` | Small 0.01 ETH swap | ALLOWED |
128
- | `swap_too_large` | 999,999 ETH swap | DENIED (value limit) |
129
- | `ttl_too_high` | Swap with 24h TTL | DENIED (TTL policy) |
130
-
131
- ## Output
132
-
133
- All commands return a JSON envelope with `"ok": true/false`.
134
-
135
- ### Success (JSON, default)
136
-
137
- ```json
138
- {
139
- "ok": true,
140
- "base_url": "https://api.trucore.xyz",
141
- "preset": "swap_small",
142
- "verified": true,
143
- "response": {
144
- "decision": "allowed",
145
- "reasons": [],
146
- "receipt_hash": "a1b2c3...64hex",
147
- "content_hash": "d4e5f6...64hex"
148
- }
149
- }
150
- ```
151
-
152
- When `--verify` is not used, the `verified` field is `null`.
153
- When a preset is not used, the `preset` field is `null`.
154
- ```
155
-
156
- ### Success (Pretty, `--pretty`)
157
-
158
- ```
159
- ALLOWED
160
- Reason: All policies passed
161
- Receipt: a1b2c3...64hex
162
-
163
- Content hash verified
164
- ```
165
-
166
- ### Errors
167
-
168
- All errors return a structured JSON envelope:
169
-
170
- ```json
171
- {
172
- "ok": false,
173
- "error": {
174
- "code": "NETWORK_ERROR",
175
- "message": "Network failure — fetch failed",
176
- "details": {
177
- "hint": "Check your network connection and base URL."
178
- }
179
- }
180
- }
181
- ```
182
-
183
- Error codes: `USER_ERROR`, `DENIED`, `NETWORK_ERROR`, `SERVER_ERROR`, `VALIDATION_ERROR`, `AUTH_ERROR`, `VERIFY_FAILED`.
184
-
185
- ## Exit Codes
186
-
187
- | Code | Meaning |
188
- |------|---------|
189
- | 0 | Success (allowed, healthy, approved, etc.) |
190
- | 1 | User error or denied (bad input, auth failure, transaction denied, verify failed) |
191
- | 2 | Network / server error (unreachable, 5xx, timeout, rate limited) |
192
-
193
- ## Trustless Verification
194
-
195
- **Don't trust TruCore — verify.**
196
-
197
- Every simulation produces a `content_hash` (SHA-256). You can:
198
-
199
- 1. **Use `--verify` flag:** Automatically recomputes and checks content_hash integrity client-side.
200
- 2. **Recompute locally:** The policy engine is deterministic. Same input → same hash.
201
- 3. **Check receipt signatures** (when available): `GET /api/receipt-signing-key`
202
-
203
- The `--verify` flag checks content_hash integrity automatically. On mismatch it exits 1 with `VERIFY_FAILED`.
204
-
205
- ## Token Redaction
206
-
207
- Bearer tokens are **never** emitted in CLI output. All stdout/stderr is scrubbed
208
- for token values and `Bearer <token>` patterns before printing.
209
-
210
- ## Environment Variables
211
-
212
- | Variable | Description |
213
- |----------|-------------|
214
- | `ATF_API_KEY` | API key (sent as `x-api-key` header or Bearer token) |
215
- | `ATF_BASE_URL` | Override default base URL |
216
- | `ATF_TIMEOUT_MS` | Override default timeout (milliseconds, default: `20000`) |
217
- | `NO_COLOR` | Disable ANSI colors when set |
218
-
219
- ## Requirements
220
-
221
- - Node.js 18+
222
- - **Zero** runtime dependencies
223
-
224
- ## Development
225
-
226
- ```bash
227
- # Build
228
- node build.mjs
229
-
230
- # Test (all offline — no network calls)
231
- node --test tests/*.mjs
232
-
233
- # Pack (dry run — verify included files)
234
- npm pack --dry-run
235
- ```
236
-
237
- ## Publishing
238
-
239
- ```bash
240
- # 1. Build
241
- node build.mjs
242
-
243
- # 2. Run all tests
244
- node --test tests/*.mjs
245
-
246
- # 3. Inspect the tarball
247
- npm pack --dry-run
248
- # Expected files: LICENSE, README.md, dist/index.js, package.json
249
-
250
- # 4. Publish to npm (requires npm login)
251
- npm publish --access public
252
-
253
- # 5. Verify install (from a clean machine or CI)
254
- npx @trucore/atf@1.0.0 version
255
- npx @trucore/atf@1.0.0 health
256
- ```
257
-
258
- ## License
259
-
260
- MIT
1
+ # @trucore/atf
2
+
3
+ > Agent Transaction Firewall CLI — simulate, verify, and execute on-chain transactions trustlessly.
4
+
5
+ ## One-Liner
6
+
7
+ ```bash
8
+ npx @trucore/atf@1.3.1 simulate --preset swap_small --verify --pretty
9
+ ```
10
+
11
+ That's it. No install, no config, no API key required.
12
+
13
+ ## What It Does
14
+
15
+ 1. Sends a deterministic preset transaction to the ATF public API
16
+ 2. Returns **allowed** or **denied** with a reason and receipt hash
17
+ 3. Verifies **content_hash** integrity client-side — don't trust TruCore, verify
18
+ 4. Executes **real on-chain Solana swaps** (Jupiter DEX) gated by ATF policy
19
+ 5. **Profile-based config** — switch between mainnet/devnet, Helius RPC, keypairs
20
+ 6. **Transaction tooling** — sign, send, confirm, and verify receipts offline
21
+
22
+ ## Install (optional)
23
+
24
+ ```bash
25
+ npm install -g @trucore/atf@1.3.1
26
+ ```
27
+
28
+ Or use directly with `npx` (always pin the version):
29
+
30
+ ```bash
31
+ npx @trucore/atf@1.3.1 simulate --preset swap_small
32
+ ```
33
+
34
+ ## Quickstart: Doctor (Dev Environment Check)
35
+
36
+ ```bash
37
+ npx @trucore/atf@1.3.1 doctor --pretty
38
+ ```
39
+
40
+ ## Quickstart: Devnet Burner
41
+
42
+ ```bash
43
+ npx @trucore/atf@1.3.1 swap --burner --devnet --in SOL --out USDC --amount-in 0.01 --execute --yes --confirm
44
+ ```
45
+
46
+ ## Quickstart: Helius Profile Setup
47
+
48
+ ```bash
49
+ npx @trucore/atf@1.3.1 config init --yes
50
+ npx @trucore/atf@1.3.1 profile create devnet
51
+ npx @trucore/atf@1.3.1 profile use devnet
52
+ npx @trucore/atf@1.3.1 config set solana_cluster devnet
53
+ npx @trucore/atf@1.3.1 config set rpc_url helius
54
+ export HELIUS_API_KEY=your_key_here
55
+ npx @trucore/atf@1.3.1 rpc ping
56
+ ```
57
+
58
+ ## Commands
59
+
60
+ ### `health`
61
+
62
+ Check API health and round-trip latency.
63
+
64
+ ```bash
65
+ npx @trucore/atf@1.3.1 health
66
+ npx @trucore/atf@1.3.1 health --pretty
67
+ npx @trucore/atf@1.3.1 health --base-url http://localhost:3000
68
+ ```
69
+
70
+ **Output shape:**
71
+
72
+ ```json
73
+ { "ok": true, "base_url": "https://api.trucore.xyz", "latency_ms": 42, "response": { "status": "ok" } }
74
+ ```
75
+
76
+ ### `simulate`
77
+
78
+ Run a transaction simulation against the ATF API.
79
+
80
+ ```bash
81
+ npx @trucore/atf@1.3.1 simulate --preset swap_small --verify
82
+ npx @trucore/atf@1.3.1 simulate --preset swap_too_large --pretty
83
+ npx @trucore/atf@1.3.1 simulate --json '{"chain_id":1,"value_eth":"0.5"}' --base-url http://localhost:3000
84
+ ```
85
+
86
+ **Output shape:**
87
+
88
+ ```json
89
+ { "ok": true, "base_url": "https://api.trucore.xyz", "preset": "swap_small", "verified": true, "response": { "decision": "allowed", "reasons": [], "receipt_hash": "a1b2...64hex", "content_hash": "c3d4...64hex" } }
90
+ ```
91
+
92
+ ### `approve`
93
+
94
+ Approve a pending intent (requires authentication).
95
+
96
+ ```bash
97
+ npx @trucore/atf@1.3.1 approve --intent abc123 --token mytoken
98
+ npx @trucore/atf@1.3.1 approve --intent abc123 --token mytoken --pretty
99
+ ```
100
+
101
+ **Output shape:**
102
+
103
+ ```json
104
+ { "ok": true, "base_url": "https://api.trucore.xyz", "intent": "abc123", "response": { "intent_id": "abc123", "status": "approved" } }
105
+ ```
106
+
107
+ ### `version`
108
+
109
+ Show rich version information (CLI version, Node version, build info).
110
+
111
+ ```bash
112
+ npx @trucore/atf@1.3.1 version
113
+ npx @trucore/atf@1.3.1 version --pretty
114
+ ```
115
+
116
+ **Output shape:**
117
+
118
+ ```json
119
+ { "ok": true, "cli_version": "1.3.1", "node_version": "v22.0.0", "platform": "linux", "arch": "x64", "default_base_url": "https://api.trucore.xyz", "build_commit": "abc1234", "build_date": "2025-01-01T00:00:00Z" }
120
+ ```
121
+
122
+ ### `swap`
123
+
124
+ Execute a **real on-chain Solana swap** (Jupiter DEX) gated by ATF policy evaluation.
125
+
126
+ > **⚠ WARNING:** This command signs transactions with your local keypair.
127
+ > Use a burner wallet for demos. Start with a tiny amount (e.g. 0.001 SOL).
128
+
129
+ **Dry run (no funds move):**
130
+
131
+ ```bash
132
+ npx @trucore/atf@1.3.1 swap \
133
+ --in SOL --out USDC \
134
+ --amount-in 0.001 \
135
+ --slippage-bps 50 \
136
+ --keypair ~/.config/solana/id.json \
137
+ --dry-run
138
+ ```
139
+
140
+ **Real transaction (mainnet):**
141
+
142
+ ```bash
143
+ npx @trucore/atf@1.3.1 swap \
144
+ --in SOL --out USDC \
145
+ --amount-in 0.001 \
146
+ --slippage-bps 50 \
147
+ --keypair ~/.config/solana/id.json \
148
+ --rpc https://api.mainnet-beta.solana.com \
149
+ --confirm
150
+ ```
151
+
152
+ **Devnet burner one-liner (generates ephemeral keypair, no files needed):**
153
+
154
+ ```bash
155
+ npx @trucore/atf@1.3.1 swap \
156
+ --burner --devnet \
157
+ --in SOL --out USDC \
158
+ --amount-in 0.01 \
159
+ --slippage-bps 100 \
160
+ --execute --yes --confirm
161
+ ```
162
+
163
+ > **⚠️ burner is devnet-only.** The `--burner` flag auto-generates an ephemeral
164
+ > keypair in memory. It forces devnet mode and will refuse any mainnet RPC. Do
165
+ > not use for real funds. Devnet swaps use a SOL transfer fallback since Jupiter
166
+ > does not support devnet.
167
+
168
+ **Output shape (success):**
169
+
170
+ ```json
171
+ {
172
+ "ok": true,
173
+ "request_id": "abc123...",
174
+ "base_url": "https://api.trucore.xyz",
175
+ "preset": null,
176
+ "verified": true,
177
+ "response": {
178
+ "decision": "allowed",
179
+ "receipt_hash": "a1b2...64hex",
180
+ "content_hash": "c3d4...64hex"
181
+ },
182
+ "execution": {
183
+ "rpc": "https://api.mainnet-beta.solana.com",
184
+ "signature": "5SiGA...",
185
+ "explorer_url": "https://solscan.io/tx/5SiGA...",
186
+ "jupiter": { "inAmount": "1000000", "outAmount": "150000", "priceImpactPct": "0.01" },
187
+ "confirmation_status": "confirmed",
188
+ "sent_at": "2026-02-28T12:00:00.000Z"
189
+ }
190
+ }
191
+ ```
192
+
193
+ **If denied:** exits 1 with `ok: false`, no on-chain transaction executed.
194
+
195
+ ### `config`
196
+
197
+ Manage CLI configuration (init, set, get, list).
198
+
199
+ ```bash
200
+ atf config init --yes # Create default config
201
+ atf config set solana_cluster devnet
202
+ atf config set rpc_url helius # Use Helius RPC (requires HELIUS_API_KEY)
203
+ atf config set tx.max_retries 5
204
+ atf config get rpc_url
205
+ atf config list # Show merged effective config
206
+ atf config list --pretty
207
+ ```
208
+
209
+ ### `profile`
210
+
211
+ Manage named configuration profiles.
212
+
213
+ ```bash
214
+ atf profile list # List all profiles
215
+ atf profile create staging # Create new profile
216
+ atf profile use staging # Switch active profile
217
+ atf profile delete staging # Delete a profile
218
+ ```
219
+
220
+ Use `--profile <name>` on any command to override the active profile for that invocation.
221
+
222
+ ### `secret`
223
+
224
+ Manage sensitive credentials (stored in `~/.config/atf/secrets.json` with `0600` permissions).
225
+
226
+ ```bash
227
+ echo "my-helius-key" | atf secret set helius
228
+ atf secret list # Shows namespaces/profiles, never values
229
+ atf secret unset helius
230
+ ```
231
+
232
+ Secrets are resolved with priority: environment variable > secrets store.
233
+
234
+ ### `rpc ping`
235
+
236
+ Check Solana RPC connectivity and latency.
237
+
238
+ ```bash
239
+ atf rpc ping # Uses profile RPC or default
240
+ atf rpc ping --devnet # Ping devnet
241
+ atf rpc ping --rpc https://custom-rpc.example.com
242
+ atf rpc ping --pretty
243
+ ```
244
+
245
+ **Output shape:**
246
+
247
+ ```json
248
+ { "ok": true, "cluster": "mainnet-beta", "rpc_host": "mainnet.helius-rpc.com", "latency_ms": 85, "version": "2.2.1", "slot": 348123456 }
249
+ ```
250
+
251
+ ### `tx sign`
252
+
253
+ Offline-sign a base64-encoded Solana transaction.
254
+
255
+ ```bash
256
+ atf tx sign --tx-base64 <base64> --keypair ~/.config/solana/id.json
257
+ atf tx sign --tx-file unsigned.bin --keypair ~/.config/solana/id.json
258
+ ```
259
+
260
+ **Output shape:**
261
+
262
+ ```json
263
+ { "ok": true, "signed_tx_base64": "..." }
264
+ ```
265
+
266
+ ### `tx send`
267
+
268
+ Sign, send, and optionally confirm a Solana transaction.
269
+
270
+ ```bash
271
+ atf tx send --tx-base64 <base64> --keypair ~/.config/solana/id.json
272
+ atf tx send --tx-base64 <base64> --keypair ~/id.json --confirm --rpc helius
273
+ ```
274
+
275
+ **Output shape:**
276
+
277
+ ```json
278
+ { "ok": true, "signature": "5SiGA...", "explorer_url": "https://solscan.io/tx/5SiGA...", "confirmation_status": "confirmed" }
279
+ ```
280
+
281
+ ### `tx status`
282
+
283
+ Poll the confirmation status of a transaction signature.
284
+
285
+ ```bash
286
+ atf tx status --sig 5SiGA...
287
+ atf tx status --sig 5SiGA... --pretty
288
+ ```
289
+
290
+ **Output shape:**
291
+
292
+ ```json
293
+ { "ok": true, "signature": "5SiGA...", "status": "finalized", "slot": 348123456, "err": null }
294
+ ```
295
+
296
+ ### `receipts verify`
297
+
298
+ Verify ATF receipt hash integrity offline.
299
+
300
+ ```bash
301
+ atf receipts verify --file receipt.json
302
+ cat receipt.json | atf receipts verify --stdin
303
+ atf receipts verify --file receipt.json --pretty
304
+ ```
305
+
306
+ **Output shape:**
307
+
308
+ ```json
309
+ { "ok": true, "content_hash_valid": true, "receipt_hash_valid": true, "file": "receipt.json" }
310
+ ```
311
+
312
+ ### `whoami`
313
+
314
+ Show current profile context, config, and CLI version.
315
+
316
+ ```bash
317
+ atf whoami
318
+ atf whoami --pretty
319
+ atf whoami --profile staging
320
+ ```
321
+
322
+ **Output shape:**
323
+
324
+ ```json
325
+ { "ok": true, "profile": "default", "atf_base_url": "https://api.trucore.xyz", "solana_cluster": "mainnet-beta", "rpc_host": "mainnet.helius-rpc.com", "commitment": "confirmed", "explorer": "solscan", "cli_version": "1.3.1" }
326
+ ```
327
+
328
+ ### `ls`
329
+
330
+ Alias for `config list`.
331
+
332
+ ```bash
333
+ atf ls
334
+ atf ls --pretty
335
+ ```
336
+
337
+ ### `completion`
338
+
339
+ Generate shell completion scripts.
340
+
341
+ ```bash
342
+ atf completion bash >> ~/.bashrc
343
+ atf completion zsh >> ~/.zshrc
344
+ atf completion fish > ~/.config/fish/completions/atf.fish
345
+ atf completion powershell >> $PROFILE
346
+ ```
347
+
348
+ ### `doctor`
349
+
350
+ Run a comprehensive dev environment health check — ATF API, RPC, config, keypair, and explorer.
351
+
352
+ ```bash
353
+ npx @trucore/atf@1.3.1 doctor --pretty
354
+ npx @trucore/atf@1.3.1 doctor --profile devnet --pretty
355
+ npx @trucore/atf@1.3.1 doctor --rpc https://custom-rpc.example.com
356
+ npx @trucore/atf@1.3.1 doctor --verbose
357
+ ```
358
+
359
+ **Output shape (JSON, default):**
360
+
361
+ ```json
362
+ {
363
+ "ok": true,
364
+ "summary": { "status": "ok", "passed": 5, "warned": 0, "failed": 0 },
365
+ "env": { "cli_version": "1.3.1", "node_version": "v22.0.0", "platform": "linux", "arch": "x64" },
366
+ "effective": { "profile": "default", "atf_base_url": "https://api.trucore.xyz", "solana_cluster": "mainnet" },
367
+ "checks": [
368
+ { "name": "atf_health", "status": "pass", "latency_ms": 42, "details": { "http_status": 200 }, "actions": [] },
369
+ { "name": "simulate_sanity", "status": "pass", "latency_ms": 55, "details": { "decision": "allowed" }, "actions": [] },
370
+ { "name": "rpc_health", "status": "pass", "latency_ms": 30, "details": { "solana_version": "2.2.1" }, "actions": [] },
371
+ { "name": "keypair", "status": "pass", "details": { "configured": true, "valid": true }, "actions": [] },
372
+ { "name": "explorer_link", "status": "pass", "details": { "explorer": "solscan" }, "actions": [] }
373
+ ]
374
+ }
375
+ ```
376
+
377
+ **Exit codes:**
378
+
379
+ | Code | Meaning |
380
+ |------|---------|
381
+ | 0 | All checks pass (or warn-only) |
382
+ | 1 | User/actionable misconfiguration (missing Helius key, invalid config) |
383
+ | 2 | Network/server failure (ATF API or RPC unreachable) |
384
+
385
+ ## Global Options
386
+
387
+ | Flag | Description | Default |
388
+ |------|-------------|---------|
389
+ | `--base-url <url>` | API base URL | `https://api.trucore.xyz` |
390
+ | `--timeout-ms <ms>` | Request timeout in milliseconds | `20000` |
391
+ | `--format <fmt>` | Output: `json` or `pretty` | `json` |
392
+ | `--pretty` | Shorthand for `--format pretty` | `false` |
393
+ | `--no-color` | Disable ANSI colors | `false` |
394
+ | `--api-key <key>` | API key (also: `ATF_API_KEY` env var) | — |
395
+ | `--profile <name>` | Use a named config profile | `default` |
396
+
397
+ ## Simulate Options
398
+
399
+ | Flag | Description | Default |
400
+ |------|-------------|---------|
401
+ | `--preset <name>` | Built-in preset: `swap_small`, `swap_too_large`, `ttl_too_high` | — |
402
+ | `--json '<json>'` | Raw JSON transaction body | — |
403
+ | `--verify` | Verify content_hash integrity | `false` |
404
+ | `--quiet` | Suppress non-essential output | `false` |
405
+
406
+ ## Approve Options
407
+
408
+ | Flag | Description | Default |
409
+ |------|-------------|---------|
410
+ | `--intent <id>` | Intent ID to approve (required) | — |
411
+ | `--intent-id <id>` | Alias for `--intent` (backward compat) | — |
412
+ | `--token <bearer>` | Bearer token for auth (also: `ATF_API_KEY` env var) | — |
413
+
414
+ ## Swap Options
415
+
416
+ | Flag | Description | Default |
417
+ |------|-------------|---------|
418
+ | `--in <symbol\|mint>` | Input token symbol or mint address | — |
419
+ | `--out <symbol\|mint>` | Output token symbol or mint address | — |
420
+ | `--amount-in <number>` | Amount of input token (human units, e.g. 0.001) | — |
421
+ | `--slippage-bps <int>` | Slippage tolerance in basis points | `50` |
422
+ | `--keypair <path>` | Path to Solana id.json keypair file | — |
423
+ | `--rpc <url>` | Solana RPC URL (or `"helius"` to auto-build) | `https://api.mainnet-beta.solana.com` |
424
+ | `--dry-run` | Simulate + quote only; do NOT sign or send | `false` |
425
+ | `--confirm` | Poll signature status until confirmed or timeout | `false` |
426
+ | `--verify` | Verify content_hash integrity | `false` |
427
+ | `--burner` | Generate ephemeral keypair (devnet only, never printed) | `false` |
428
+ | `--devnet` | Force devnet mode (RPC, token mints, explorer links) | `false` |
429
+ | `--faucet` | Print faucet instructions + burner pubkey and exit | `false` |
430
+ | `--airdrop <sol>` | Request devnet SOL airdrop (e.g. `--airdrop 1`) | — |
431
+ | `--save-burner <path>` | Save burner keypair to disk (explicit opt-in, 0600) | — |
432
+ | `--load-burner <path>` | Load a previously saved burner keypair | — |
433
+
434
+ **Supported tokens (mainnet v1):** SOL, USDC, USDT
435
+
436
+ **Supported tokens (devnet):** SOL, USDC
437
+
438
+ ### Presets
439
+
440
+ | Preset | Description | Expected |
441
+ |--------|-------------|----------|
442
+ | `swap_small` | Small 0.01 ETH swap | ALLOWED |
443
+ | `swap_too_large` | 999,999 ETH swap | DENIED (value limit) |
444
+ | `ttl_too_high` | Swap with 24h TTL | DENIED (TTL policy) |
445
+
446
+ ## Output
447
+
448
+ All commands return a JSON envelope with `"ok": true/false`.
449
+
450
+ ### Success (JSON, default)
451
+
452
+ ```json
453
+ {
454
+ "ok": true,
455
+ "base_url": "https://api.trucore.xyz",
456
+ "preset": "swap_small",
457
+ "verified": true,
458
+ "response": {
459
+ "decision": "allowed",
460
+ "reasons": [],
461
+ "receipt_hash": "a1b2c3...64hex",
462
+ "content_hash": "d4e5f6...64hex"
463
+ }
464
+ }
465
+ ```
466
+
467
+ When `--verify` is not used, the `verified` field is `null`.
468
+ When a preset is not used, the `preset` field is `null`.
469
+ ```
470
+
471
+ ### Success (Pretty, `--pretty`)
472
+
473
+ ```
474
+ ✓ ALLOWED
475
+ Reason: All policies passed
476
+ Receipt: a1b2c3...64hex
477
+
478
+ ✓ Content hash verified
479
+ ```
480
+
481
+ ### Errors
482
+
483
+ All errors return a structured JSON envelope:
484
+
485
+ ```json
486
+ {
487
+ "ok": false,
488
+ "error": {
489
+ "code": "NETWORK_ERROR",
490
+ "message": "Network failure — fetch failed",
491
+ "details": {
492
+ "hint": "Check your network connection and base URL."
493
+ }
494
+ }
495
+ }
496
+ ```
497
+
498
+ Error codes: `USER_ERROR`, `DENIED`, `NETWORK_ERROR`, `SERVER_ERROR`, `VALIDATION_ERROR`, `AUTH_ERROR`, `VERIFY_FAILED`.
499
+
500
+ ## Exit Codes
501
+
502
+ | Code | Meaning |
503
+ |------|---------|
504
+ | 0 | Success (allowed, healthy, approved, etc.) |
505
+ | 1 | User error or denied (bad input, auth failure, transaction denied, verify failed) |
506
+ | 2 | Network / server error (unreachable, 5xx, timeout, rate limited) |
507
+
508
+ ## Trustless Verification
509
+
510
+ **Don't trust TruCore — verify.**
511
+
512
+ Every simulation produces a `content_hash` (SHA-256). You can:
513
+
514
+ 1. **Use `--verify` flag:** Automatically recomputes and checks content_hash integrity client-side.
515
+ 2. **Recompute locally:** The policy engine is deterministic. Same input → same hash.
516
+ 3. **Check receipt signatures** (when available): `GET /api/receipt-signing-key`
517
+
518
+ The `--verify` flag checks content_hash integrity automatically. On mismatch it exits 1 with `VERIFY_FAILED`.
519
+
520
+ ## Token Redaction
521
+
522
+ Bearer tokens are **never** emitted in CLI output. All stdout/stderr is scrubbed
523
+ for token values and `Bearer <token>` patterns before printing.
524
+
525
+ ## Environment Variables
526
+
527
+ | Variable | Description |
528
+ |----------|-------------|
529
+ | `ATF_API_KEY` | API key (sent as `x-api-key` header or Bearer token) |
530
+ | `ATF_BASE_URL` | Override default base URL |
531
+ | `ATF_TIMEOUT_MS` | Override default timeout (milliseconds, default: `20000`) |
532
+ | `ATF_DEVNET_RPC` | Override devnet RPC URL (default: `https://api.devnet.solana.com`) |
533
+ | `HELIUS_API_KEY` | Helius RPC API key (used when `rpc_url=helius`) |
534
+ | `NO_COLOR` | Disable ANSI colors when set |
535
+
536
+ ## Requirements
537
+
538
+ - Node.js 18+
539
+ - Runtime dependency: `tweetnacl@1.0.3` (ed25519 signing for Solana transactions)
540
+
541
+ ## Development
542
+
543
+ ```bash
544
+ # Build
545
+ node build.mjs
546
+
547
+ # Test (all offline — no network calls)
548
+ node --test tests/*.mjs
549
+
550
+ # Pack (dry run — verify included files)
551
+ npm pack --dry-run
552
+ ```
553
+
554
+ ## Publishing
555
+
556
+ ```bash
557
+ # 1. Build
558
+ node build.mjs
559
+
560
+ # 2. Run all tests
561
+ node --test tests/*.mjs
562
+
563
+ # 3. Inspect the tarball
564
+ npm pack --dry-run
565
+ # Expected files: LICENSE, README.md, dist/index.js, package.json
566
+
567
+ # 4. Publish to npm (requires npm login)
568
+ npm publish --access public
569
+
570
+ # 5. Verify install (from a clean machine or CI)
571
+ npx @trucore/atf@1.3.1 version
572
+ npx @trucore/atf@1.3.1 health
573
+ npx @trucore/atf@1.3.1 whoami
574
+ npx @trucore/atf@1.3.1 doctor --pretty
575
+ ```
576
+
577
+ ## License
578
+
579
+ MIT