NostrElixir
A complete Elixir wrapper for the nostr Rust library, built with Rustler for high performance.
Requirements
This package compiles a native NIF. You need:
- Elixir 1.14+ (and a compatible OTP)
- A Rust toolchain (
rustcandcargo), for example via rustup
def deps do
[{:nostr_elixir, "~> 0.45.4"}]
end
Modular API Structure
NostrElixir is organized into logical modules for clarity and maintainability:
NostrElixir.Keys– Key management (generation, parsing, conversions)NostrElixir.Nip19– NIP-19 encoding/decodingNostrElixir.Nip19.Address– NIP-19 TLV entities (naddr,nevent,nprofile)NostrElixir.Event– Event creation, signing, verification, helpersNostrElixir.Filter– Filter creation and helpersNostrElixir.Nip02– Follow list events (NIP-02)NostrElixir.Nip04– Encrypted DMs (NIP-04)NostrElixir.Nip06– HD wallet derivation (NIP-06)NostrElixir.Nip09– Deletion events (NIP-09)NostrElixir.Nip10– Threading and text note helpers (NIP-10)NostrElixir.Nip17– Private DMs (kind 4 events)NostrElixir.Nip23– Long-form content (NIP-23)NostrElixir.Nip44– Encrypted DMs v2 (NIP-44)NostrElixir.Nip57– Zaps (NIP-57)NostrElixir.Nip65– Relay list metadata (NIP-65)NostrElixir.Mnemonic– Mnemonic generation and seed conversion (helpers for NIP-06)
The root NostrElixir module provides a facade for common operations, but direct use of submodules is recommended for clarity and maintainability.
Usage Examples
Key Management
alias NostrElixir.Keys
# Generate a new keypair
keys = Keys.generate_keypair()
# %{public_key: ..., secret_key: ..., npub: ..., nsec: ...}
# Parse a secret key
parsed = Keys.parse_keypair(keys.nsec)
# Convert keys
npub = Keys.public_key_to_bech32(parsed.public_key)
nsec = Keys.secret_key_to_bech32(parsed.secret_key)
NIP-19 Encoding/Decoding
alias NostrElixir.Nip19
npub = Nip19.encode("npub", "eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619")
result = Nip19.decode_map(npub)
# %{data_type: "npub", data: ...}
NIP-04 Encrypted Direct Messages
alias NostrElixir.Nip04
alias NostrElixir.Keys
sender = Keys.generate_keypair()
receiver = Keys.generate_keypair()
ciphertext = Nip04.encrypt(sender.secret_key, receiver.public_key, "hello")
plaintext = Nip04.decrypt(receiver.secret_key, sender.public_key, ciphertext)
# "hello"
NIP-44 Encrypted Direct Messages v2
alias NostrElixir.Nip44
alias NostrElixir.Keys
sender = Keys.generate_keypair()
receiver = Keys.generate_keypair()
ciphertext = Nip44.encrypt(sender.secret_key, receiver.public_key, "hello")
plaintext = Nip44.decrypt(receiver.secret_key, sender.public_key, ciphertext)
# "hello"
Event Creation, Signing, and Verification
alias NostrElixir.{Keys, Event}
keys = Keys.generate_keypair()
event_json = Event.new(keys.public_key, "Hello, Nostr!", 1, [])
signed_event_json = Event.sign(event_json, keys.secret_key)
verified = Event.verify(signed_event_json) # true
Filter Creation and Helpers
alias NostrElixir.Filter
# Create a filter for fetching text notes (kind 1) by a user
filter_json = Filter.user_notes_filter("eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619")
filter = Jason.decode!(filter_json)
# filter["authors"] == ["..."]
# Create a filter for fetching a user's follow list (kind 3)
follow_list_filter_json = Filter.user_follow_list_filter("eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619")
follow_list_filter = Jason.decode!(follow_list_filter_json)
# follow_list_filter["kinds"] == [3]
# Hashtag search
filter_json = Filter.search_hashtag("nostr")
Backward Compatibility
The root NostrElixir module still provides delegates for the most common operations, so existing code will continue to work. However, for new code, it is recommended to use the submodules directly.
Features
- Key Management: Generate, parse, and convert keys
- NIP-19: Encode/decode bech32 addresses (
npub/nsec/noteand TLVnaddr/nevent/nprofile) - Event Management: Create, sign, verify, and serialize events
- Filter Management: Create filters for querying events
- Built on rust-nostr
nostr0.45.4 (package version kept in sync)
See CHANGELOG.md for breaking changes.
Roadmap
- Async event signing support (if/when needed)
- Full event verification implementation (if nostr Rust API changes)
- Relay connection management
- Event subscription handling
- More convenience functions for common nostr operations
License
MIT