Skip to main content

basic-nostr

An intentionally tiny NOSTR library for Python: Keys, DMs, Posts, & Products.

Description

basic-nostr does exactly four things:

  • Generate Nostr keys
  • Send and read direct messages (in both formats NIP-04 and NIP-17)
  • Post and read NIP-01 notes (kind 1)
  • Post and read NIP-99 products (kind 30402)

I made basic-nostr because no other Python packages make it this simple.

If it does exactly what you need → great, use it. If it doesn't → don't use it. Simple as that.

Install

pip install basic-nostr

Usage

All functions take keys as bech32 nsec1.../npub1... strings (you never need to think about hex).

NostrClient handles relay connections and async internals for you. No asyncio knowledge needed. Connects automatically on first use.

from basic_nostr import make_keys, NostrClient

npub, nsec = make_keys()
print(npub)  # npub1...  (share this)
print(nsec)  # nsec1...  (keep secret — paste into Amethyst to log in)

nostr = NostrClient(nsec)

# Post a note
nostr.make_post("Hello Nostr!", tags=[["t", "introduction"]])

# Read posts — filter by author, hashtag, or both
posts = nostr.read_posts(authors=[npub], limit=20)
posts = nostr.read_posts(tag_filters={"t": ["monero"]})

# Send DM (NIP-17 by default — sender hidden from relays)
nostr.send_dm(their_npub, "hey!")
nostr.send_dm(their_npub, "hey!", protocol="nip04")  # legacy (older clients)
nostr.send_dm(their_npub, "hey!", protocol="both")   # maximum compatibility

# Read DMs (reads both NIP-17 and NIP-04 by default)
dms = nostr.read_dms()
for dm in dms:
    print(f"From: {dm['sender']}")       # npub1...
    print(f"Message: {dm['message']}")
    print(f"Protocol: NIP-{dm['nip']}")  # 17 or 4
    print(f"Time: {dm['timestamp']}")    # unix timestamp

# List a product — shows up on Shopstr, Plebeian Market, etc.
nostr.list_product(
    title="Vintage Keyboard",
    description="Cherry MX Blues, great condition.",
    price=75,
    currency="USD",
    image_urls=["https://example.com/keyboard.jpg"],
    categories=["electronics"],
    condition="used",
    location="US",
)

# Read products and parse tags
products = nostr.read_products(limit=50)
for product in products:
    tags = {t[0]: t[1:] for t in product["tags"]}
    print(f"{tags['title'][0]} — {tags['price'][0]} {tags['price'][1]}")

# Close when done (or use context manager below)
nostr.close()

Read-only usage (no private key needed):

nostr = NostrClient()
posts = nostr.read_posts(tag_filters={"t": ["monero"]})
products = nostr.read_products(limit=10)
nostr.close()

Context manager works too (auto-closes):

with NostrClient(nsec) as nostr:
    nostr.make_post("Hello!")

Custom relays:

nostr = NostrClient(nsec, relay_urls=["wss://relay.damus.io", "wss://nos.lol"])
nostr.make_post("Hello from custom relays!")

Async API

All async functions are also exported if you need them directly:

import asyncio
from basic_nostr import make_keys, connect_to_relays, close_relays, make_post, read_posts

async def main():
    npub, nsec = make_keys()
    relays = await connect_to_relays()
    try:
        await make_post(relays, "Hello Nostr!", [["t", "introduction"]], nsec)
        posts = await read_posts(relays, authors=[npub], limit=20)
    finally:
        await close_relays(relays)

asyncio.run(main())

Available async functions: connect_to_relays, close_relays, make_post, read_posts, list_product, read_products, send_dm, read_dms, read_events_from_relays.

Contributing

If you want to add more functionality to this, open a PR. I'll merge it if it keeps it simple and matches the patterns.

Metadata

Release files for basic-nostr 1.1.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 basic-nostr 1.1.0
File Size Uploaded
basic_nostr-1.1.0.tar.gz 16.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for basic-nostr 1.1.0
File Interpreter ABI Platform
basic_nostr-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 34.6 kB

Release files / basic_nostr-1.1.0.tar.gz

Download URL basic_nostr-1.1.0.tar.gz
Size 16.9 kB
Tags Source
SHA-256 checksum
How to use checksums
55d15b549dbce2297e6cfad3d550876d6437fa89dea766c20e0acab1c1d181ca
BLAKE2b-256 checksum
How to use checksums
038a4808f8a598d78cf3d18f39e3cd1f3dda62c018340d6202e3b982719e4ab4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.0

Release files / basic_nostr-1.1.0-py3-none-any.whl

Download URL basic_nostr-1.1.0-py3-none-any.whl
Size 17.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
237905f568138d29a0d917010fa32a01f42cbb16334b7405c50d782b3d724109
BLAKE2b-256 checksum
How to use checksums
47009eddce3243d7f0fa8598a47133a056bcf0b2a7fbdd8b7f379788abff37a3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.0

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files

1.0.0

2 release files

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