Skip to main content

nostr-dev

Developer tooling for Nostr workflows: local key management, relay health checks, note publishing, event querying, and GitHub-to-Nostr activity sync from the command line.

Status: MVP complete.

Install

From a local checkout with uv:

uv sync
uv run nostr-dev --help

Install as a CLI in an isolated environment:

uv tool install .
nostr-dev --help

Or with pipx:

pipx install .
nostr-dev --help

Architecture

                 +---------------------------+
                 |        nostr-dev CLI      |
                 | Typer + Rich command UX   |
                 +-------------+-------------+
                               |
        +----------------------+----------------------+
        |                                             |
+-------v--------+                           +--------v-------+
| Local SQLite   |                           | SecretStore    |
| SQLModel       |                           | keyring first  |
| Alembic-ready  |                           | encrypted file |
+-------+--------+                           +--------+-------+
        |                                             |
        |                                             |
+-------v--------+       +--------------------+--------v-------+
| GitHub service |       | Nostr services     | RelayPool      |
| httpx API      |       | key/event/filter   | publish/query  |
| rate-limit UX  |       | builders           | nostr-sdk      |
+-------+--------+       +---------+----------+--------+-------+
        |                          |                   |
        v                          v                   v
   api.github.com             NIP-01 events       Nostr relays

Command Reference

Command Purpose
nostr-dev --version Print the installed version.
nostr-dev --verbose Raise terminal log level to INFO.
nostr-dev --debug Raise log level to DEBUG and show full tracebacks for unexpected errors.
nostr-dev keygen [--show-secret] [--force] Generate a Nostr keypair, store the nsec in SecretStore, and store only npub metadata in SQLite.
nostr-dev import [NSEC] [--force] Import an nsec from an argument or stdin.
nostr-dev whoami Show the active npub.
nostr-dev relay add URL Add a wss:// relay.
nostr-dev relay list List configured relays.
nostr-dev relay ping [URL] Ping one relay or all active relays and record latency.
nostr-dev relay remove URL [--yes] Remove a relay.
nostr-dev publish "CONTENT" Publish a NIP-01 kind:1 note to all active relays.
nostr-dev events [--author NPUB] [--kind K] [--limit N] Query active relays and print matching events.
nostr-dev github login Validate and store a GitHub PAT. Reads GITHUB_TOKEN when set.
nostr-dev github watch OWNER/REPO Validate and watch a GitHub repository.
nostr-dev github list List watched repositories.
nostr-dev github sync Fetch recent PRs, releases, and issues for watched repos, save new events, and publish them to Nostr when relays and a key are configured.
nostr-dev github inbox [--all] Show locally stored GitHub events, unpublished by default.
nostr-dev github opportunities [--label LABEL] [--repo OWNER/REPO] Live query for labeled open issues across watched repos. Does not publish or store notifications.
nostr-dev github daemon Run scheduled GitHub sync using APScheduler and the configured sync interval.

Demo Walkthrough

Day 1: Nostr toolkit

$ nostr-dev keygen
Generated Nostr key:
npub1vwpkjqgdl6k6autnc7wmfdmmuf9

$ nostr-dev relay add wss://relay.damus.io
Added relay: wss://relay.damus.io

$ nostr-dev relay add wss://relay.primal.net
Added relay: wss://relay.primal.net

$ nostr-dev relay ping
                 Relay Ping
+-------------------------------------------+
| Relay                  | Status | Latency |
|------------------------+--------+---------|
| wss://relay.damus.io   | Online | 420 ms  |
| wss://relay.primal.net | Online | 515 ms  |
+-------------------------------------------+

$ nostr-dev publish "hello nostr, testing nostr-dev"
Event ID: a9368a716899e4c0de7cabdc359af05bde99bdf89034cfae263c9fbbc5aef4a8
2/2 relays confirmed
               Publish Results
+--------------------------------------------+
| Relay                  | Status   | Reason |
|------------------------+----------+--------|
| wss://relay.damus.io   | accepted | -      |
| wss://relay.primal.net | accepted | -      |
+--------------------------------------------+

$ nostr-dev events --author npub1vwpkjqgdl6k6autnc7wmfdmmuf9 --kind 1 --limit 5
                                 Nostr Events
+-----------------------------------------------------------------------------+
| Author                | Kind | Created               | Content              |
|-----------------------+------+-----------------------+----------------------|
| npub1vwpkjqgdl6k6aut… | 1    | 2026-07-11T22:02:38+… | hello nostr, testing |
|                       |      |                       | nostr-dev            |
+-----------------------------------------------------------------------------+

Day 2: GitHub workflows

$ GITHUB_TOKEN=github_pat_redacted nostr-dev github login
Authenticated as octocat

$ nostr-dev github watch bitcoin/bitcoin
Watching bitcoin/bitcoin

$ nostr-dev github watch rust-nostr/nostr
Watching rust-nostr/nostr

$ nostr-dev github sync
3 new events found, 3 published to Nostr

$ nostr-dev github inbox --all
                                GitHub Inbox
+-----------------------------------------------------------------------------+
| Repo            | Type         | Title                     | Published | Created |
|-----------------+--------------+---------------------------+-----------+---------|
| bitcoin/bitcoin | pull_request | PR #35120 Improve package | yes       | 2026-… |
| rust-nostr/nostr| release      | Release v1.0.0            | yes       | 2026-… |
+-----------------------------------------------------------------------------+

$ nostr-dev github opportunities
                 GitHub Opportunities: bitcoin/bitcoin
+-----------------------------------------------------------------------------+
| Issue | Title                         | Label            | URL                  |
|-------+-------------------------------+------------------+----------------------|
| #315  | Add focused relay smoke tests | good first issue | https://github.com/… |
+-----------------------------------------------------------------------------+

$ nostr-dev github opportunities --repo rust-nostr/nostr --label "help wanted"
                 GitHub Opportunities: rust-nostr/nostr
+-----------------------------------------------------------------------------+
| Issue | Title                         | Label       | URL                  |
|-------+-------------------------------+-------------+----------------------|
| #42   | Improve subscription examples | help wanted | https://github.com/… |
+-----------------------------------------------------------------------------+

Run recurring GitHub sync as a long-lived process:

nostr-dev github daemon

The daemon uses NOSTR_DEV_SYNC_INTERVAL_SECONDS and stores scheduler jobs in the same SQLite database.

Configuration

nostr-dev reads non-secret config from environment variables prefixed with NOSTR_DEV_ and from ~/.nostr-dev/config.toml. Environment variables win.

Useful variables:

Variable Purpose
GITHUB_TOKEN Optional PAT source for nostr-dev github login.
NOSTR_DEV_DB_PATH Override the SQLite database path.
NOSTR_DEV_GITHUB_API_BASE_URL Override the GitHub API base URL.
NOSTR_DEV_SYNC_INTERVAL_SECONDS Scheduler interval for github daemon.
NOSTR_DEV_OPPORTUNITY_LABELS Default labels for github opportunities.
NOSTR_DEV_SECRET_BACKEND Force keyring or file secret storage.

Testing

Default tests are unit tests only:

uv run pytest
uv run ruff check .
uv run mypy src

Integration tests require Docker and a local nostr-rs-relay:

docker compose up -d
uv run pytest -m integration

The local relay is exposed at ws://127.0.0.1:7777. Override it with NOSTR_DEV_INTEGRATION_RELAY_URL.

Security Notes

  • Secret values are never logged intentionally.
  • nostr-dev keygen and nostr-dev import store nsec values in SecretStore, not SQLite.
  • nostr-dev whoami, publish, events, GitHub commands, and sync output never print nsec values.
  • nostr-dev keygen --show-secret is the only command path that prints a newly generated nsec, and it asks for confirmation first.
  • GitHub PATs are read from GITHUB_TOKEN or an interactive prompt, validated, then stored in SecretStore.
  • The OS keychain backend is preferred. The encrypted-file backend is a compatibility fallback protected by a passphrase-derived Fernet key. It is best-effort local protection, not HSM-grade storage.
  • Relay publishing is public by design. Do not publish sensitive content to Nostr relays.

Non-Goals

  • Multi-identity workflows. The MVP assumes a single active key.
  • NIP-65 relay discovery.
  • A web UI.
  • HSM-grade secret storage for the encrypted-file backend.
  • Running a production Nostr relay.
  • Replacing GitHub notification systems; sync is intentionally small and explicit.

Metadata

Release files for nostr-dev 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nostr-dev 1.0.0
File Size Uploaded Provenance Actions
nostr_dev-1.0.0.tar.gz 98.6 kB Without provenance Details for nostr_dev-1.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for nostr-dev 1.0.0
File Interpreter ABI Platform Actions
nostr_dev-1.0.0-py3-none-any.whl Python 3 none any Details for nostr_dev-1.0.0-py3-none-any.whl

Total release size: 136.0 kB

Release files / nostr_dev-1.0.0.tar.gz

Download URL nostr_dev-1.0.0.tar.gz
Size 98.6 kB
Tags Source
SHA-256 checksum
How to use checksums
a082626c04c054bb3efd12cb4321143ddf41bee2b4b56dbb080a495fcaade10c
BLAKE2b-256 checksum
How to use checksums
00dcf363bb0d3596cee9928aeedb8d49b32423d151b7c25159d93e7718839ed5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.3

Release files / nostr_dev-1.0.0-py3-none-any.whl

Download URL nostr_dev-1.0.0-py3-none-any.whl
Size 37.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
68b42dc76f515e9d15c1f372cc01763001293daf0421c81ddc950625a8c2feac
BLAKE2b-256 checksum
How to use checksums
6d5bdd21f467522617b088cf55e8b28d99dd125d2614ca1f2d0e028cbb4da798
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.3

Security for nostr-dev 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page