Skip to main content

Overview

The OpenAgents CLI exposes offline Nostr utilities. You can:
  • generate and derive NIP-06 keypairs and BIP39 seeds
  • encode/decode NIP-19 entities and NIP-21 nostr: URIs
  • sign, verify, hash, serialize, and validate NIP-01 events
  • encrypt/decrypt payloads (NIP-04 / NIP-44)
  • create/validate delegation and auth helpers (NIP-26 / NIP-42 / NIP-98)
  • encrypt/decrypt private keys (NIP-49)
  • parse and verify NIP-05 identifiers
  • inspect proof-of-work (NIP-13)
All commands live under the nostr namespace of the OpenAgents CLI.

Nostr in OpenAgents

Nostr is the protocol layer for decentralized coordination in OpenAgents. It provides cryptographic identity and a relay-based pub/sub fabric for agent workflows like job requests, results, and capability discovery. Autopilot Desktop currently connects to Codex for run execution, while Nostr is already wired into protocol and market components for marketplace and relay flows. This page documents the offline CLI surface (no relay connections or WebSocket subscriptions). For the broader protocol design, see:

Protocol snapshot (OpenAgents view)

  • NIP-01: base events, relays, subscriptions
  • NIP-42: relay auth to prevent anonymous spam
  • NIP-44: encrypted payloads for sensitive data
  • NIP-89: provider capability discovery
  • NIP-90: job request/result flow (kinds 5050/6050/7000)
  • NIP-57: Lightning payments tied to events
  • NIP-34: Git collaboration (GitAfter)
  • NIP-SA: proposed agent lifecycle events (profiles, ticks, trajectories)
The CLI implements offline helpers for NIP-01/04/05/06/13/19/21/26/42/44/49/98.

CLI entrypoints

The CLI ships two binaries that behave the same:
  • openagents
  • oa
Examples below use oa. If you are running from source:
cargo run -p openagents-cli --bin oa -- nostr new --words 12

Command map

  • oa nostr new|derive|seed|pubkey|encode|decode
  • oa nostr event sign|verify|hash|validate|serialize|kind
  • oa nostr nip19 encode|decode
  • oa nostr uri encode|decode|strip
  • oa nostr nip04 encrypt|decrypt
  • oa nostr nip44 encrypt|decrypt
  • oa nostr nip26 create|verify|validate
  • oa nostr nip42 auth|validate
  • oa nostr nip49 encrypt|decrypt
  • oa nostr nip98 create|validate|decode
  • oa nostr nip05 parse|well-known|verify
  • oa nostr pow difficulty|check|nonce

Key generation and identity (NIP-06)

Create a new mnemonic + keypair

oa nostr new --words 12
Options:
  • --words 12|24 (default: 12)
  • --account <n> (derivation path: m/44'/1237'/<account>'/0/0)
  • --agent <n> (maps to account = agent + 1)
  • --passphrase "..." (optional BIP39 passphrase)
  • --no-mnemonic (hide mnemonic in output)
  • --json (structured output)
To avoid printing the mnemonic in logs or terminals:
oa nostr new --no-mnemonic --json

Derive from an existing mnemonic

oa nostr derive --mnemonic "word1 ... word12" --account 0
Or via stdin:
echo "word1 ... word12" | oa nostr derive --stdin --json
Options:
  • --mnemonic "..." or --stdin (required)
  • --account <n>
  • --agent <n> (maps to account = agent + 1)
  • --passphrase "..."
  • --show-mnemonic
  • --json

Derive public key from a secret

oa nostr pubkey --secret <priv_hex>
Or with nsec:
oa nostr pubkey --nsec <nsec>

Bech32 encoding/decoding (NIP-19)

Encode npub/nsec

oa nostr encode --public <pubkey_hex> --private <privkey_hex>
Inputs must be 32-byte hex values (64 hex characters). You may provide only --public or only --private.

Decode npub/nsec

oa nostr decode --npub <npub> --nsec <nsec>
You may provide only --npub or only --nsec.

Encode other NIP-19 entities

oa nostr nip19 encode --entity nprofile --pubkey <pubkey_hex> --relay wss://relay.example.com
Supported entity types: npub, nsec, note, nprofile, nevent, naddr.

Decode any NIP-19 entity

oa nostr nip19 decode --bech32 <nprofile|nevent|naddr|note|npub|nsec>

nostr: URI helpers (NIP-21)

oa nostr uri encode --entity <npub|note|nprofile|nevent|naddr>
oa nostr uri decode --uri "nostr:npub1..."
oa nostr uri strip --uri "nostr:npub1..."

Events (NIP-01)

Sign an event

oa nostr event sign --secret <priv_hex> --kind 1 --content "hello" \
  --tags-json '[["p","<pubkey_hex>"]]'
You can also pass a full template JSON:
oa nostr event sign --secret <priv_hex> --template-json '{"kind":1,"content":"hello","tags":[],"created_at":1700000000}'

Verify an event

oa nostr event verify --event-json '<signed_event_json>'

Hash/serialize/validate

oa nostr event hash --event-json '<signed_or_unsigned_event_json>'
oa nostr event serialize --event-json '<signed_or_unsigned_event_json>'
oa nostr event validate --event-json '<signed_or_unsigned_event_json>'

Classify event kind

oa nostr event kind --kind 30023

Encryption (NIP-04 / NIP-44)

NIP-04 (AES-CBC) encrypted DMs:
oa nostr nip04 encrypt --secret <priv_hex> --pubkey <pubkey_hex> --plaintext "hello"
oa nostr nip04 decrypt --secret <priv_hex> --pubkey <pubkey_hex> --ciphertext "..."
NIP-44 v2 encryption:
oa nostr nip44 encrypt --secret <priv_hex> --pubkey <pubkey_hex> --plaintext "hello"
oa nostr nip44 decrypt --secret <priv_hex> --pubkey <pubkey_hex> --payload "..."
Public keys can be provided as 32-byte hex (x-only), 33-byte compressed hex, or 65-byte uncompressed hex. The CLI accepts --pubkey or --npub.

Delegation (NIP-26)

oa nostr nip26 create --secret <delegator_priv> --delegatee-pubkey <pub_hex> --conditions "kind=1&created_at>1700000000"
oa nostr nip26 verify --delegator-pubkey <pub_hex> --delegatee-pubkey <pub_hex> --conditions "kind=1" --token <sig>
oa nostr nip26 validate --delegator-pubkey <pub_hex> --delegatee-pubkey <pub_hex> --conditions "kind=1" --token <sig> --event-kind 1 --event-created-at 1700000000

Relay auth events (NIP-42)

oa nostr nip42 auth --relay wss://relay.example.com --challenge "abc" --secret <priv_hex>
oa nostr nip42 validate --relay wss://relay.example.com --challenge "abc" --event-json '<signed_event_json>'

Private key encryption (NIP-49)

oa nostr nip49 encrypt --secret <priv_hex> --password "pass"
oa nostr nip49 decrypt --ncryptsec <ncryptsec> --password "pass"

HTTP auth events (NIP-98)

oa nostr nip98 create --url https://example.com/api --method POST --secret <priv_hex> --payload "hello"
oa nostr nip98 validate --event-json '<signed_event_json>' --url https://example.com/api --method POST --payload "hello" --verify-sig
oa nostr nip98 decode --header "Nostr <base64>"

NIP-05 helpers

oa nostr nip05 parse --identifier [email protected]
oa nostr nip05 well-known --identifier [email protected]
The CLI does not fetch .well-known/nostr.json. Provide the response JSON:
oa nostr nip05 verify --identifier [email protected] --pubkey <pub_hex> \
  --response-json '{"names":{"alice":"<pub_hex>"},"relays":{"<pub_hex>":["wss://relay.example.com"]}}'

Proof-of-work (NIP-13)

oa nostr pow difficulty --event-id <event_id_hex>
oa nostr pow check --event-json '<signed_event_json>' --min 12
oa nostr pow nonce --event-json '<signed_event_json>'

Output format

With --json, output is stable and machine-readable. Example from nostr new:
{
  "mnemonic": "...",
  "account": 0,
  "agent": null,
  "public_key_hex": "...",
  "private_key_hex": "...",
  "npub": "npub1...",
  "nsec": "nsec1..."
}
Example from nostr seed:
{
  "seed_hex": "..."
}

Security notes

  • Mnemonics and nsec values are full private keys. Store them securely.
  • --no-mnemonic is recommended when recording logs or terminals.
  • BIP39 passphrases change derived keys; keep them with the mnemonic.
  • The CLI is offline-only; it does not contact relays or external services.

NIP-06 compliance

The CLI derives keys according to NIP-06:
  • BIP39 mnemonic
  • Derivation path: m/44'/1237'/<account>'/0/0
npub/nsec are bech32 encodings per NIP-19.