zinc-wallet-cli 0.4.0

Agent-first Bitcoin + Ordinals CLI wallet with account-based taproot ordinals + native segwit payment addresses (optional human mode)
1
2
3
4
5
6
7
8
9
10
11
12
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
# zinc-cli Usage (Human + Agent)

This guide is task-oriented. For strict response contracts, see `COMMAND_CONTRACT_V1.md` and `SCHEMAS.md`.

## 1) Command Shape

Global flags can appear before or after command tokens:

```bash
zinc-cli [global flags] <command> [command flags]
```

`dashboard` and the interactive setup wizard are available only in builds compiled with the `ui` feature (for example: `cargo install zinc-wallet-cli --features ui`).
With `ui` enabled, the basic dashboard shows account balance, inscriptions, and ordinals/payment addresses for each account.

Useful globals:

- `--agent` machine output mode (returns structured JSON)
- `--profile <name>` select profile (default: `default`)
- `--data-dir <path>` override data root
- `--password-env <ENV_NAME>` (default env: `ZINC_WALLET_PASSWORD`)
- `--password-stdin`
- `--reveal` show mnemonic fields in `--agent` mode, and on `wallet import`
- `--payment-address-type native|nested|legacy` override payment address branch
- `--correlation-id <id>` set a stable workflow/request identifier
- `--log-json` emit structured lifecycle logs to stderr (`command_start|command_finish|command_error`)
- `--idempotency-key <key>` de-duplicate mutating commands for retry-safe automation
- `--network-timeout-secs <n>` timeout for remote calls (default: `30`)
- `--network-retries <n>` retry count for transient network failures/timeouts (default: `0`)
- `--policy-mode warn|strict` transaction safety behavior (default: `warn`)
- `--esplora-url <url>` override Esplora API URL
- `--ord-url <url>` override Ordinals indexer URL
- `--pulse-url <url>` override Pulse Oracle URL
- `--pulse-api-token <token>` override Pulse Oracle API Token
- `--thumb` force inscription thumbnails on
- `--no-thumb` disable inscription thumbnails

Environment defaults (optional):

- `ZINC_CLI_PROFILE`
- `ZINC_CLI_DATA_DIR`
- `ZINC_CLI_PASSWORD_ENV`
- `ZINC_CLI_OUTPUT` (`human|agent`)
- `ZINC_CLI_NETWORK`
- `ZINC_CLI_SCHEME`
- `ZINC_CLI_PAYMENT_ADDRESS_TYPE` (`native|nested|legacy`)
- `ZINC_CLI_ESPLORA_URL`
- `ZINC_CLI_ORD_URL`
- `ZINC_CLI_PULSE_URL`
- `ZINC_CLI_PULSE_API_TOKEN`
- `ZINC_CLI_CORRELATION_ID`
- `ZINC_CLI_LOG_JSON` (`1|true|yes|on`)
- `ZINC_CLI_IDEMPOTENCY_KEY`
- `ZINC_CLI_NETWORK_TIMEOUT_SECS`
- `ZINC_CLI_NETWORK_RETRIES`
- `ZINC_CLI_POLICY_MODE` (`warn|strict`)

Inspect effective config:

```bash
zinc-cli --agent config show
```

Persist config defaults:

```bash
zinc-cli setup
zinc-cli setup --profile bot-a --data-dir /var/lib/zinc --password-env BOT_PASS
zinc-cli config set network signet
zinc-cli config set scheme unified
zinc-cli config set payment-address-type nested
zinc-cli config set account-gap-limit 20
zinc-cli config set address-scan-depth 5
```

`zinc-cli setup` starts an interactive wizard when run in a terminal and can initialize a wallet profile at the end (generate new or restore existing mnemonic).

Password precedence:

1. `--password-stdin`
2. `--password-env`

## 2) Human Quick Start

Set a default password env once:

```bash
export ZINC_WALLET_PASSWORD='your-wallet-password'
```

Initialize wallet:

```bash
zinc-cli wallet init --network signet --overwrite
zinc-cli wallet init --network signet --payment-address-type legacy --overwrite
```

Import existing mnemonic:

```bash
zinc-cli wallet import --mnemonic "your twelve word mnemonic ..." --network signet --overwrite
```

Import watch-only xpubs (Taproot + Payment):

```bash
zinc-cli wallet import --taproot-xpub "xpub..." --payment-xpub "xpub..." --network signet --overwrite
```

Import watch-only single address:

```bash
zinc-cli wallet import --address "bc1p..." --network signet --overwrite
```

Show wallet info:

```bash
zinc-cli wallet info
```

Reveal seed phrase (sensitive):

```bash
zinc-cli --yes --agent wallet reveal-mnemonic
```

Sync and check balance:

```bash
zinc-cli sync chain
zinc-cli sync ordinals
zinc-cli balance
zinc-cli inscription list
```

Get addresses:

```bash
zinc-cli address taproot
zinc-cli address payment
```



## 3) Agent Mode (Recommended)

Use `--agent` and parse stdout as one JSON object.

```bash
zinc-cli --agent wallet info
```

Expected envelope:

```json
{
  "ok": true,
  "schema_version": "1.0",
  "command": "wallet info"
}
```

Error envelope:

```json
{
  "ok": false,
  "schema_version": "1.0",
  "command": "wallet info",
  "error": {
    "type": "config",
    "message": "failed to read profile: ...",
    "exit_code": 10
  }
}
```

Bash error handling pattern:

```bash
out="$(zinc-cli --agent wallet info)"
ok="$(printf '%s' "$out" | jq -r '.ok')"
if [ "$ok" != "true" ]; then
  printf '%s\n' "$out" | jq -r '.error.type + ": " + .error.message' >&2
  exit "$(printf '%s' "$out" | jq -r '.error.exit_code')"
fi
```

## 4) Agent Reliability Controls

Use strict policy, idempotency, and retry controls together:

```bash
CID="agent-run-42"
zinc-cli --agent \
  --correlation-id "$CID" \
  --log-json \
  --idempotency-key "send-0001" \
  --network-timeout-secs 20 \
  --network-retries 2 \
  --policy-mode strict \
  psbt broadcast --psbt-file /tmp/send.signed.psbt
```

Behavior:
- repeated call with the same `--idempotency-key` + same mutating payload replays cached success
- reusing the same key with a different mutating payload returns `error.type=invalid`
- in `--policy-mode strict`, risky/unknown PSBT policy outcomes are blocked with `error.type=policy`

## 5) PSBT Flow

Create:

```bash
zinc-cli --agent psbt create \
  --to <address> --amount-sats 10000 --fee-rate 2 --out-file /tmp/send.psbt
```

Analyze:

```bash
zinc-cli --agent psbt analyze --psbt-file /tmp/send.psbt
```

Sign:

```bash
zinc-cli --agent psbt sign \
  --psbt-file /tmp/send.psbt --finalize --out-file /tmp/send.signed.psbt
```

Broadcast:

```bash
zinc-cli --agent psbt broadcast --psbt-file /tmp/send.signed.psbt
```

Rules:

- For `psbt analyze/sign/broadcast`, exactly one of `--psbt`, `--psbt-file`, `--psbt-stdin` is required.
- `--password-stdin` cannot be combined with `--psbt-stdin` in one invocation.

## 6) Offer Commands (Nostr + Ord, Advanced)

Create an ord-compatible buyer offer PSBT and a relay-ready offer envelope:

```bash
zinc-cli --agent --ord-url https://ord.example offer create \
  --inscription <inscription-id> \
  --amount 100000 \
  --fee-rate 1 \
  --expires-in-secs 3600 \
  --seller-payout-address <seller-payment-address> \
  --publisher-pubkey-hex <xonly-pubkey-hex> \
  --offer-out-file /tmp/offer.json \
  --psbt-out-file /tmp/offer.psbt
```

Create and immediately submit the PSBT to ord:

```bash
zinc-cli --agent --ord-url https://ord.example offer create \
  --inscription <inscription-id> \
  --amount 100000 \
  --fee-rate 1 \
  --submit-ord
```

Publish a signed offer event to one or more relays:

```bash
zinc-cli --agent offer publish \
  --offer-json '{"version":1,"seller_pubkey_hex":"<xonly-pubkey-hex>","network":"regtest","inscription_id":"<inscription-id>","seller_outpoint":"<txid:vout>","ask_sats":100000,"fee_rate_sat_vb":1,"psbt_base64":"<base64-psbt>","created_at_unix":1710000000,"expires_at_unix":1710003600,"nonce":42}' \
  --secret-key-hex <seller-secret-key-hex> \
  --relay wss://nostr.example
```

Human-focused, glanceable offer output (great for demos):

```bash
zinc-cli --ord-url https://ord.example --thumb offer create \
  --inscription <inscription-id> \
  --amount 100000 \
  --fee-rate 1
```

```bash
zinc-cli --ord-url https://ord.example --thumb offer discover \
  --relay wss://nostr.example
```

```bash
zinc-cli --ord-url https://ord.example --thumb offer accept \
  --offer-file /tmp/offer.json
```

Discover offers from one or more relays:

```bash
zinc-cli --agent offer discover \
  --relay wss://nostr.example \
  --limit 256 \
  --timeout-ms 5000
```

Accept an offer from an offer envelope (sign seller input and optionally broadcast):

```bash
zinc-cli --agent offer accept \
  --offer-file /tmp/offer.json \
  --expect-inscription <inscription-id> \
  --expect-ask-sats 100000
```

Dry run acceptance checks (no broadcast):

```bash
zinc-cli --agent offer accept \
  --offer-file /tmp/offer.json \
  --dry-run
```

Submit an offer PSBT to ord:

```bash
zinc-cli --agent --ord-url https://ord.example \
  offer submit-ord --psbt-file /tmp/offer.psbt
```

List offer PSBTs from ord:

```bash
zinc-cli --agent --ord-url https://ord.example \
  offer list-ord
```

Rules:

- For `offer publish`, exactly one of `--offer-json`, `--offer-file`, `--offer-stdin` is required.
- For `offer accept`, exactly one of `--offer-json`, `--offer-file`, `--offer-stdin` is required.
- For `offer submit-ord`, exactly one of `--psbt`, `--psbt-file`, `--psbt-stdin` is required.
- `offer create` requires `--ord-url` and inscription metadata available from ord indexer.
- `offer create --seller-payout-address` is optional; when omitted, payout defaults to the inscription output address from ord metadata.
- For dual-scheme sellers, pass `--seller-payout-address <payment-address>` to direct proceeds to the seller payment branch.
- `offer create --publisher-pubkey-hex` can override the default publisher pubkey embedded in the offer envelope.
- `offer publish` and `offer discover` require at least one `--relay`.
- `--thumb` and `--no-thumb` are boolean toggles.
- In human mode, thumbnails are enabled by default unless `--no-thumb` or `--no-images` is set.
- In `--agent` mode, thumbnails are disabled by default unless `--thumb` is explicitly set.
- `insight appraise` uses the configured Pulse Oracle to provide collection metadata and floor prices for all inscriptions in the current account.
- `pulse login` authenticates you with Pulse Oracle using OAuth2 Device Authorization (default) or a manual token.

## 6.1) Fixed-Price Listing Commands (Nostr + Sale PSBT, Advanced)

Listings are seller-initiated fixed-price sale PSBTs. Use `offer` when a buyer proposes to buy; use `listing` when a seller publishes a buyable price.

Recommended agent path: use `listing sell` and `listing purchase` as the compact workflow, and fall back to the primitive commands below when you need manual checkpoints.

Create, optionally activate, and publish a seller listing:

```bash
zinc-cli --agent --ord-url https://ord.example listing sell \
  --inscription <inscription-id> \
  --amount 100000 \
  --fee-rate 1 \
  --coordinator-pubkey-hex <coordinator-xonly-pubkey-hex> \
  --activate \
  --relay wss://nostr.example \
  --secret-key-hex <seller-secret-key-hex> \
  --listing-out-file /tmp/listing.json
```

Discover a matching listing from relays, fund buyer inputs, and write the updated envelope:

```bash
zinc-cli --agent listing purchase \
  --relay wss://nostr.example \
  --expect-inscription <inscription-id> \
  --expect-ask-sats 100000 \
  --listing-out-file /tmp/listing.buyer.json \
  --psbt-out-file /tmp/listing.buyer.psbt
```

If the caller also controls the coordinator key, `listing purchase` can complete the remaining sale path:

```bash
zinc-cli --agent listing purchase \
  --listing-file /tmp/listing.json \
  --expect-inscription <inscription-id> \
  --expect-ask-sats 100000 \
  --coordinator-secret-key-hex <coordinator-secret-key-hex> \
  --finalize \
  --broadcast
```

Primitive seller flow: create a listing and write the relay-ready envelope:

```bash
zinc-cli --agent --ord-url https://ord.example listing create \
  --inscription <inscription-id> \
  --amount 100000 \
  --fee-rate 1 \
  --coordinator-pubkey-hex <coordinator-xonly-pubkey-hex> \
  --listing-out-file /tmp/listing.json \
  --tx1-out-file /tmp/listing.tx1.psbt \
  --sale-psbt-out-file /tmp/listing.sale.psbt \
  --recovery-psbt-out-file /tmp/listing.recovery.psbt
```

Activate the listing by signing and broadcasting TX1:

```bash
zinc-cli --agent listing activate \
  --listing-file /tmp/listing.json
```

Publish and discover listings over Nostr:

```bash
zinc-cli --agent listing publish \
  --listing-file /tmp/listing.json \
  --secret-key-hex <seller-secret-key-hex> \
  --relay wss://nostr.example

zinc-cli --agent listing discover \
  --relay wss://nostr.example \
  --limit 256
```

Buyer funds and signs buyer inputs:

```bash
zinc-cli --agent listing buy \
  --listing-file /tmp/listing.json \
  --expect-inscription <inscription-id> \
  --expect-ask-sats 100000 \
  --listing-out-file /tmp/listing.buyer.json \
  --psbt-out-file /tmp/listing.buyer.psbt
```

Coordinator signs, then finalize and optionally broadcast:

```bash
zinc-cli --agent listing coordinator-sign \
  --listing-file /tmp/listing.buyer.json \
  --secret-key-hex <coordinator-secret-key-hex> \
  --listing-out-file /tmp/listing.coordinator.json

zinc-cli --agent listing finalize \
  --listing-file /tmp/listing.coordinator.json \
  --broadcast
```

Rules:

- Listing source commands require exactly one of `--listing-json`, `--listing-file`, `--listing-stdin`.
- `--password-stdin` cannot be combined with `--listing-stdin`.
- `listing publish` and `listing discover` require at least one `--relay`.
- `listing sell --relay` requires `--secret-key-hex`; `listing sell --dry-run` requires `--activate`.
- `listing purchase` accepts either a listing source or relay discovery, not both.
- `listing purchase --relay` requires `--expect-inscription`.
- `listing purchase --finalize` requires `--coordinator-secret-key-hex`; `--broadcast` requires `--finalize`.
- `listing create` requires `--ord-url` and a wallet-owned inscription available from the ord indexer.
- `listing activate --dry-run` signs TX1 locally without broadcasting.

## 7) Oracle & Market Insight

Appraise your wallet (requires Pulse Oracle):

```bash
zinc-cli insight appraise
```

Filter for recognized collections only:

```bash
zinc-cli insight appraise --known-only
```

Search for collections and floor prices:

```bash
zinc-cli insight search "pizza comrades"
```

Bind the active wallet to ord.net through the Pulse service gateway:

```bash
zinc-cli --agent pulse ordnet bind
```

Hosted ord.net market data through Pulse:

```bash
zinc-cli --agent insight market listings \
  --collection-slug <slug> \
  --limit 20

zinc-cli --agent insight market sales \
  --collection-slug <slug> \
  --limit 20

zinc-cli --agent insight market collection-inscriptions \
  --slug <slug> \
  --sort newest \
  --limit 20
```

Hosted purchase preflight through Pulse:

```bash
zinc-cli --agent insight market buy-preflight \
  --collection-slug <slug> \
  --listing-id <listing-id> \
  --inscription-id <inscription-id> \
  --expect-price-sats 100000 \
  --raw-out-file /tmp/ordnet-buy-preflight.json
```

Hosted purchase submit through Pulse:

```bash
zinc-cli --agent insight market buy-submit \
  --collection-slug <slug> \
  --expect-inscription <inscription-id> \
  --expect-listing-id <listing-id> \
  --expect-price-sats 100000 \
  --file /tmp/ordnet-buy-preflight.json
```

Rules:

- `pulse ordnet bind` signs ord.net wallet challenges with the active wallet; the CLI does not store ord.net API keys.
- ord.net requires a wallet binding and a payment address with 0.01 BTC confirmed for authenticated trading access.
- Hosted market write flows stay two-phase: preflight first, then submit with explicit `--expect-*` checks.
- Submit commands analyze preflight PSBT steps, honor `--policy-mode strict`, sign only upstream-declared input indices when present, and send the signed payload through Pulse.
- Hosted trading requires Pulse's trading provider to be `ordnet`; Satflow can inform decisions with metadata/statistics but cannot create, buy, delist, accept, counter, or submit trades.
- Existing decentralized `offer` and `listing` Nostr workflows are unchanged.

Authenticate with Pulse:

```bash
# Starts interactive OAuth browser flow (suggested)
zinc-cli pulse login

# Global login (shares session across all profiles)
zinc-cli pulse login --global

# Manual/CI login with token
zinc-cli pulse login --token <your-api-token>
```

Check session status:

```bash
zinc-cli pulse whoami
```

Logout:

```bash
zinc-cli pulse logout
```

Authentication precedence for Pulse:
1. `--pulse-api-token` flag
2. `ZINC_CLI_PULSE_API_TOKEN` env
3. Profile session (from `pulse login`)
4. Global session (from `pulse login --global`)
5. Legacy global API token fallback

## 8) Profiles, Accounts, and Waits

Use named profile and custom data directory:

```bash
zinc-cli --agent --profile bot-a --data-dir /var/lib/zinc wallet info
```

Switch account:

```bash
zinc-cli --agent account use --index 1
```

Wait for confirmation:

```bash
zinc-cli --agent wait tx-confirmed --txid <txid> --timeout-secs 300
```

## 8) Safety Notes

- Prefer setting `ZINC_WALLET_PASSWORD` once for automation.
- Use `--password-env` only when you need a non-default env var name.
- `wallet init` in human mode prints the new seed phrase once; in `--agent` mode mnemonic output is redacted unless `--reveal` is set.
- In `--agent` mode, consume stdout as machine data and treat stderr as diagnostics only.

## 9) Agent Flow Integration Test

Run the complete agentic wallet flow:

```bash
ZINC_CLI_LIVE_TESTS=1 cargo test --test agent_flow test_agent_wallet_workflow -- --nocapture
```

Run the live offer create -> accept integration test:

```bash
ZINC_CLI_LIVE_TESTS=1 cargo test --test offer_live test_offer_create_and_accept_live -- --nocapture
```

Sample run from a funded regtest environment:

```text
[1] Import wallet with seed phrase (dual scheme)
  ✓ Network: regtest, Scheme: dual
[2] Get wallet info
  ✓ Profile: default, Network: regtest, Scheme: dual
[3] Sync chain
  ✓ Chain synced
[4] Sync ordinals
  ✓ Ordinals synced: 3 inscriptions
[5] List inscriptions
  ✓ Inscriptions listed: 3
[6] Get account 0 taproot/payment addresses
  ✓ A0 taproot=bcrt1p...lts0 payment=bcrt1q...pee3
[7] Get taproot address at index 3
  ✓ Taproot[3]: bcrt1p...yk0g
[8] Get account 0 balance
  ✓ Account 0 total sats before transfer: 3118181 (spendable: 3117191)
[9] Account list
  ✓ Account 0 taproot=bcrt1p...lts0 payment=bcrt1q...pee3
[10] Switch to account 1
  ✓ Switched to account 1 taproot=bcrt1p...emmn payment=bcrt1q...36mn
[11] Verify new taproot after account switch
  ✓ Address changed: bcrt1p...lts0 -> bcrt1p...ydta
  ✓ Account 1 total sats before transfer: 0
[12] Switch back to account 0
  ✓ Switched back to account 0
[13] Create PSBT to transfer 1000 sats from account 0 -> account 1 payment
  ✓ PSBT created
[14] Analyze PSBT
  ✓ PSBT analyzed
[15] Sign + finalize PSBT
  ✓ PSBT signed
[16] Broadcast transaction
  ✓ Broadcast txid=eb7696...6017
[17] Verify account 0 sees transfer tx
  ✓ Account 0 total sats after transfer: 3117040 (before 3118181)
[18] Verify account 1 sees transfer tx + balance increase
  ✓ Account 1 total sats after transfer: 1000 (before 0)

✅ Wallet workflow test passed!
test test_agent_wallet_workflow ... ok
```

If account 0 does not have enough spendable balance, the transfer portion is skipped by design.

## 10) Offer Live Integration Tests (Ord + Nostr)

Run the ord submit/list live round-trip:

```bash
ZINC_CLI_LIVE_TESTS=1 \
cargo test --test offer_live test_offer_ord_submit_and_list_live -- --nocapture
```

Run the nostr publish/discover live round-trip using default relay:

```bash
ZINC_CLI_LIVE_TESTS=1 \
cargo test --test offer_live test_offer_nostr_publish_discover_live -- --nocapture
```

Use a custom nostr relay endpoint:

```bash
ZINC_CLI_LIVE_TESTS=1 \
ZINC_CLI_TEST_NOSTR_RELAY_URL=wss://nostr-regtest.exittheloop.com \
cargo test --test offer_live test_offer_nostr_publish_discover_live -- --nocapture
```

Notes:
- Tests are opt-in and skipped unless `ZINC_CLI_LIVE_TESTS=1` is set.
- Live infra defaults used by the suite:
  - Esplora: `https://esplora-rt.exittheloop.com`
  - Ord: `https://ord-rt.exittheloop.com`
  - Nostr relay: `wss://nostr-regtest.exittheloop.com`