This guide is task-oriented. For strict response contracts, see COMMAND_CONTRACT_V1.md and SCHEMAS.md.
Global flags can appear before or after command tokens:
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:
--agentmachine output mode (returns structured JSON)--profile <name>select profile (default:default)--data-dir <path>override data root--password <value>--password-env <ENV_NAME>(default env:ZINC_WALLET_PASSWORD)--password-stdin--revealshow mnemonic fields in--agentmode, and onwallet import--correlation-id <id>set a stable workflow/request identifier--log-jsonemit 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|stricttransaction safety behavior (default:warn)--thumbforce inscription thumbnails on--no-thumbdisable inscription thumbnails
Environment defaults (optional):
ZINC_CLI_PROFILEZINC_CLI_DATA_DIRZINC_CLI_PASSWORD_ENVZINC_CLI_OUTPUT(human|agent)ZINC_CLI_NETWORKZINC_CLI_SCHEMEZINC_CLI_ESPLORA_URLZINC_CLI_ORD_URLZINC_CLI_CORRELATION_IDZINC_CLI_LOG_JSON(1|true|yes|on)ZINC_CLI_IDEMPOTENCY_KEYZINC_CLI_NETWORK_TIMEOUT_SECSZINC_CLI_NETWORK_RETRIESZINC_CLI_POLICY_MODE(warn|strict)
Inspect effective config:
zinc-cli --agent config showPersist config defaults:
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 unifiedzinc-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:
--password--password-stdin--password-env
Set a default password env once:
export ZINC_WALLET_PASSWORD='your-wallet-password'Initialize wallet:
zinc-cli wallet init --network signet --overwriteShow wallet info:
zinc-cli wallet infoReveal seed phrase (sensitive):
zinc-cli --yes --agent wallet reveal-mnemonicSync and check balance:
zinc-cli sync chain
zinc-cli sync ordinals
zinc-cli balance
zinc-cli inscription listGet addresses:
zinc-cli address taproot
zinc-cli address paymentUse --agent and parse stdout as one JSON object.
zinc-cli --agent wallet infoExpected envelope:
{
"ok": true,
"schema_version": "1.0",
"command": "wallet info"
}Error envelope:
{
"ok": false,
"schema_version": "1.0",
"command": "wallet info",
"error": {
"type": "config",
"message": "failed to read profile: ...",
"exit_code": 10
}
}Bash error handling pattern:
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')"
fiUse strict policy, idempotency, and retry controls together:
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.psbtBehavior:
- 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 witherror.type=policy
Create:
zinc-cli --agent psbt create \
--to <address> --amount-sats 10000 --fee-rate 2 --out-file /tmp/send.psbtAnalyze:
zinc-cli --agent psbt analyze --psbt-file /tmp/send.psbtSign:
zinc-cli --agent psbt sign \
--psbt-file /tmp/send.psbt --finalize --out-file /tmp/send.signed.psbtBroadcast:
zinc-cli --agent psbt broadcast --psbt-file /tmp/send.signed.psbtRules:
- For
psbt analyze/sign/broadcast, exactly one of--psbt,--psbt-file,--psbt-stdinis required. --password-stdincannot be combined with--psbt-stdinin one invocation.
offer is callable directly (zinc-cli offer ...) but intentionally hidden from top-level zinc-cli --help.
Create an ord-compatible buyer offer PSBT and a relay-ready offer envelope:
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.psbtCreate and immediately submit the PSBT to ord:
zinc-cli --agent --ord-url https://ord.example offer create \
--inscription <inscription-id> \
--amount 100000 \
--fee-rate 1 \
--submit-ordPublish a signed offer event to one or more relays:
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.exampleHuman-focused, glanceable offer output (great for demos):
zinc-cli --ord-url https://ord.example --thumb offer create \
--inscription <inscription-id> \
--amount 100000 \
--fee-rate 1zinc-cli --ord-url https://ord.example --thumb offer discover \
--relay wss://nostr.examplezinc-cli --ord-url https://ord.example --thumb offer accept \
--offer-file /tmp/offer.jsonDiscover offers from one or more relays:
zinc-cli --agent offer discover \
--relay wss://nostr.example \
--limit 256 \
--timeout-ms 5000Accept an offer from an offer envelope (sign seller input and optionally broadcast):
zinc-cli --agent offer accept \
--offer-file /tmp/offer.json \
--expect-inscription <inscription-id> \
--expect-ask-sats 100000Dry run acceptance checks (no broadcast):
zinc-cli --agent offer accept \
--offer-file /tmp/offer.json \
--dry-runSubmit an offer PSBT to ord:
zinc-cli --agent --ord-url https://ord.example \
offer submit-ord --psbt-file /tmp/offer.psbtList offer PSBTs from ord:
zinc-cli --agent --ord-url https://ord.example \
offer list-ordRules:
- For
offer publish, exactly one of--offer-json,--offer-file,--offer-stdinis required. - For
offer accept, exactly one of--offer-json,--offer-file,--offer-stdinis required. - For
offer submit-ord, exactly one of--psbt,--psbt-file,--psbt-stdinis required. offer createrequires--ord-urland inscription metadata available from ord indexer.offer create --seller-payout-addressis 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-hexcan override the default publisher pubkey embedded in the offer envelope.offer publishandoffer discoverrequire at least one--relay.--thumband--no-thumbare boolean toggles.- In human mode, thumbnails are enabled by default unless
--no-thumbor--no-imagesis set. - In
--agentmode, thumbnails are disabled by default unless--thumbis explicitly set.
Use named profile and custom data directory:
zinc-cli --agent --profile bot-a --data-dir /var/lib/zinc wallet infoSwitch account:
zinc-cli --agent account use --index 1Wait for confirmation:
zinc-cli --agent wait tx-confirmed --txid <txid> --timeout-secs 300- Prefer setting
ZINC_WALLET_PASSWORDonce for automation. - Use
--password-envonly when you need a non-default env var name. - Avoid
--passwordin shared process environments. wallet initin human mode prints the new seed phrase once; in--agentmode mnemonic output is redacted unless--revealis set.- In
--agentmode, consume stdout as machine data and treat stderr as diagnostics only.
Run the complete agentic wallet flow:
ZINC_CLI_LIVE_TESTS=1 cargo test --test agent_flow test_agent_wallet_workflow -- --nocaptureRun the live offer create -> accept integration test:
ZINC_CLI_LIVE_TESTS=1 cargo test --test offer_live test_offer_create_and_accept_live -- --nocaptureSample run from a funded regtest environment:
[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.
Run the ord submit/list live round-trip:
ZINC_CLI_LIVE_TESTS=1 \
cargo test --test offer_live test_offer_ord_submit_and_list_live -- --nocaptureRun the nostr publish/discover live round-trip using default relay:
ZINC_CLI_LIVE_TESTS=1 \
cargo test --test offer_live test_offer_nostr_publish_discover_live -- --nocaptureUse a custom nostr relay endpoint:
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 -- --nocaptureNotes:
- Tests are opt-in and skipped unless
ZINC_CLI_LIVE_TESTS=1is set. - Live infra defaults used by the suite:
- Esplora:
https://regtest.exittheloop.com/api - Ord:
https://ord-regtest.exittheloop.com - Nostr relay:
wss://nostr-regtest.exittheloop.com
- Esplora: