Skip to main content

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

Project description

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 (recommended)

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

basic_nostr-1.1.0.tar.gz (16.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

basic_nostr-1.1.0-py3-none-any.whl (17.7 kB view details)

Uploaded Python 3

File details

Details for the file basic_nostr-1.1.0.tar.gz.

File metadata

  • Download URL: basic_nostr-1.1.0.tar.gz
  • Upload date:
  • Size: 16.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for basic_nostr-1.1.0.tar.gz
Algorithm Hash digest
SHA256 55d15b549dbce2297e6cfad3d550876d6437fa89dea766c20e0acab1c1d181ca
MD5 da1897213d14f7eb385c972f6538ce3c
BLAKE2b-256 038a4808f8a598d78cf3d18f39e3cd1f3dda62c018340d6202e3b982719e4ab4

See more details on using hashes here.

File details

Details for the file basic_nostr-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: basic_nostr-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 17.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for basic_nostr-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 237905f568138d29a0d917010fa32a01f42cbb16334b7405c50d782b3d724109
MD5 774ed7753b87cf35972324df371a7fd3
BLAKE2b-256 47009eddce3243d7f0fa8598a47133a056bcf0b2a7fbdd8b7f379788abff37a3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page