nsigner_client — Linux CLI for n_signer
A standalone Linux command-line client that connects to a running n_signer process and calls its JSON-RPC verbs over stdin/stdout. Designed for pipe-to-nak workflows.
Build
Produces build/nsigner_client. Links nostr_core_lib exactly like the existing examples.
Usage
Global options
| Flag |
Default |
Meaning |
--socket-name, -n <name> |
auto-discover |
Abstract socket name without @ |
--timeout <ms> |
5000 |
Transport timeout |
--tcp <host:port> |
none |
TCP transport (requires --auth-privkey) |
--serial <device> |
none |
USB CDC-ACM serial transport |
--qrexec <qube:service> |
none |
Qubes qrexec transport |
--auth-privkey <32-byte hex> |
none |
Auth envelope privkey for TCP |
--auth-label <text> |
none |
Auth envelope label |
Selector options (for nostr_* verbs)
| Flag |
Meaning |
JSON emitted |
--role <name> |
Named path-role registered in the signer |
{"role":"<name>"} |
--path <path> |
Full BIP-44 derivation path |
{"role_path":"<path>"} |
Algorithm options (for algorithm-based verbs)
| Flag |
Default |
Meaning |
--algorithm <alg> |
none |
secp256k1/ed25519/x25519/ml-dsa-65/slh-dsa-128s/ml-kem-768/otp |
--index <N> |
0 |
Algorithm derivation index |
--scheme <schnork|ecdsa> |
schnorr |
secp256k1 sign/verify only |
--encoding <base64|hex> |
base64 |
OTP encrypt/decrypt only |
--format <plain|structured> |
plain |
nostr_get_public_key output shape |
Mine-event options
| Flag |
Meaning |
--difficulty <N> |
Target leading zero bits |
--threads <N> |
Mining threads (default 1) |
--timeout-sec <N> |
Mining timeout in seconds |
Verb reference
Utility
| Verb |
stdout |
list |
Lists running n_signer abstract sockets (one @name per line) |
Metadata
| Verb |
RPC method |
stdout |
get-info |
get_info |
raw result JSON (name, version, verbs, algorithms) |
Nostr verbs (role-based)
| Verb |
RPC method |
stdin/argv |
stdout |
get-public-key |
nostr_get_public_key |
none |
pubkey hex (or structured JSON with --format structured) |
sign-event |
nostr_sign_event |
event JSON from argv or stdin |
signed event JSON |
mine-event |
nostr_mine_event |
event JSON from argv or stdin |
signed mined event JSON |
nip04-encrypt <peer> |
nostr_nip04_encrypt |
plaintext from argv or stdin |
ciphertext |
nip04-decrypt <peer> |
nostr_nip04_decrypt |
ciphertext from argv or stdin |
plaintext |
nip44-encrypt <peer> |
nostr_nip44_encrypt |
plaintext from argv or stdin |
ciphertext |
nip44-decrypt <peer> |
nostr_nip44_decrypt |
ciphertext from argv or stdin |
plaintext |
Algorithm-based verbs
| Verb |
RPC method |
argv |
stdout |
get-public-key |
get_public_key |
none |
structured JSON {"algorithm":...,"public_key":...,"key_id":...} |
sign <msg-hex> |
sign |
hex bytes |
structured JSON {"signature":...,"algorithm":...,"key_id":...} |
verify <msg-hex> <sig-hex> |
verify |
hex bytes |
valid / invalid (exit 0/1) |
derive <data> |
derive |
UTF-8 data (argv or stdin) |
structured JSON |
encapsulate <peer-pubkey-hex> |
encapsulate |
hex |
structured JSON |
decapsulate <ciphertext-hex> |
decapsulate |
hex |
structured JSON |
derive-shared-secret <peer-pubkey-hex> |
derive_shared_secret |
hex |
shared secret hex |
encrypt <plaintext> |
encrypt |
plaintext (base64 by default) |
ciphertext |
decrypt <ciphertext> |
decrypt |
ciphertext |
plaintext |
Generic escape hatch
| Verb |
RPC method |
input |
stdout |
call <method> |
<method> |
JSON params array from stdin or argv |
raw result JSON |
Selector explanation
The nostr_* verbs select a key via the options object using both --role and --path:
--role <name> --path <path> — Both are required for all nostr_* verbs. The role authorizes the request and determines the encryption scheme. The path selects the specific key to derive. Sends {"role":"<name>","role_path":"<path>"} to the server.
--role without --path — Client-side error: --path is required for nostr verbs.
--path without --role — Client-side error: --role is required for nostr verbs.
For algorithm verbs, --algorithm and --index populate the options object instead.
Pipe-to-nak recipes
Transport options
| Transport |
Flag |
Notes |
| UNIX abstract socket |
--socket-name <name> or auto-discover |
Default. Auto-discovers if exactly one @nsigner* socket exists. |
| TCP |
--tcp <host:port> |
Requires --auth-privkey for auth envelope. |
| Serial (USB CDC-ACM) |
--serial <device> |
e.g. --serial /dev/ttyACM0 |
| Qubes qrexec |
--qrexec <qube:service> |
e.g. --qrexec sys-signer:qubes.NsignerRpc |
Exit codes
| Code |
Meaning |
| 0 |
Success |
| 1 |
Invalid (verify verb only — signature is invalid) |
| 2 |
Error (transport, RPC, or usage error) |
For verify: exit 0 = valid signature, exit 1 = invalid signature, exit 2 = error.
stdin/stdout contract
- All payload output goes to stdout as a single line, newline-terminated.
- All diagnostics (errors, warnings) go to stderr.
sign-event, nip04-*, nip44-*, derive, encrypt, decrypt read their payload from argv if present, otherwise from stdin (one line).
sign, verify, encapsulate, decapsulate, derive-shared-secret take hex from argv only (binary payloads).
call reads a JSON params array from stdin (one line) or argv.
See also