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 keygenandnostr-dev importstore nsec values in SecretStore, not SQLite.nostr-dev whoami,publish,events, GitHub commands, and sync output never print nsec values.nostr-dev keygen --show-secretis the only command path that prints a newly generated nsec, and it asks for confirmation first.- GitHub PATs are read from
GITHUB_TOKENor 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)
| 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)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| 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.