Developer tooling for Nostr workflows.
Project description
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nostr_dev-1.0.0.tar.gz.
File metadata
- Download URL: nostr_dev-1.0.0.tar.gz
- Upload date:
- Size: 98.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a082626c04c054bb3efd12cb4321143ddf41bee2b4b56dbb080a495fcaade10c
|
|
| MD5 |
4598ee3187867e01d860a38a1c329ffc
|
|
| BLAKE2b-256 |
00dcf363bb0d3596cee9928aeedb8d49b32423d151b7c25159d93e7718839ed5
|
File details
Details for the file nostr_dev-1.0.0-py3-none-any.whl.
File metadata
- Download URL: nostr_dev-1.0.0-py3-none-any.whl
- Upload date:
- Size: 37.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
68b42dc76f515e9d15c1f372cc01763001293daf0421c81ddc950625a8c2feac
|
|
| MD5 |
1e4b1facdb049309167f0e5db9a9eb99
|
|
| BLAKE2b-256 |
6d5bdd21f467522617b088cf55e8b28d99dd125d2614ca1f2d0e028cbb4da798
|