Nostr
A comprehensive low-level Elixir library implementing the Nostr protocol. Provides structures, parsing, serialization, and cryptographic functions for building Nostr applications.
Features
- Full event lifecycle: creation, signing, validation, serialization
- Schnorr signature support (secp256k1)
- NIP-44 encryption (versioned encrypted payloads)
- NIP-19 bech32 encoding (npub, nsec, note, nprofile, nevent, naddr)
- NIP-59 gift wrap protocol for private messaging
- WebSocket message protocol handling
- Subscription filter building
Installation
Add nostr_lib to your dependencies in mix.exs:
def deps do
[
{:nostr_lib, "~> 0.2.0"}
]
endQuick Start
Create and Sign an Event
# Generate or use existing private key (32 bytes hex)
private_key = "your_private_key_hex"
# Create a text note (kind 1)
{:ok, event} = Nostr.Event.Note.create("Hello Nostr!", private_key)
# Serialize for sending to relay
json = Nostr.Event.serialize(event)Parse Incoming Events
# Parse JSON from relay
{:ok, event} = Nostr.Event.parse(json_string)
# Validate event signature
case Nostr.Event.Validator.validate(event) do
{:ok, event} -> # Valid event
{:error, reason, event} -> # Invalid
endBuild Subscription Filters
# Create a filter for text notes from specific authors
filter = %Nostr.Filter{
kinds: [1],
authors: ["pubkey1", "pubkey2"],
limit: 100
}Bech32 Encoding
# Encode public key as npub
{:ok, npub} = Nostr.Bech32.encode(:npub, pubkey_hex)
# => "npub1..."
# Decode back
{:ok, {:npub, pubkey}} = Nostr.Bech32.decode(npub)Implemented NIPs
| NIP | Status | Description | Event Kinds |
|---|---|---|---|
| NIP-01 | Full | Basic protocol | 0, 1 |
| NIP-02 | Full | Follow list | 3 |
| NIP-03 | Full | OpenTimestamps | 1040 |
| NIP-04 | Deprecated | Encrypted DMs (use NIP-17) | 4 |
| NIP-05 | Full | DNS-based identifiers | - |
| NIP-09 | Full | Event deletion | 5 |
| NIP-16 | Full | Event kind ranges | 1000-39999 |
| NIP-17 | Full | Private direct messages | 14, 15, 10050 |
| NIP-18 | Deprecated | Reposts | 6 |
| NIP-19 | Full | Bech32 encoding | - |
| NIP-21 | Full | nostr: URI scheme | - |
| NIP-22 | Full | Comments | 1111 |
| NIP-23 | Full | Long-form content | 30023, 30024 |
| NIP-25 | Full | Reactions | 7, 17 |
| NIP-28 | Full | Public chat channels | 40-44 |
| NIP-30 | Full | Custom emoji | - |
| NIP-32 | Full | Labeling | 1985 |
| NIP-36 | Full | Sensitive content | - |
| NIP-37 | Full | Draft events | 31234 |
| NIP-38 | Full | User statuses | 30315 |
| NIP-39 | Full | External identities | - |
| NIP-42 | Full | Relay authentication | 22242 |
| NIP-44 | Full | Versioned encryption | - |
| NIP-45 | Partial | Event counting | - |
| NIP-49 | Full | Private key encryption | - |
| NIP-51 | Full | Lists | 10001-10030, 30000-30030 |
| NIP-52 | Full | Calendar | 31924 |
| NIP-56 | Full | Reporting | 1984 |
| NIP-57 | Full | Lightning zaps | 9734, 9735 |
| NIP-58 | Full | Badges | 8 |
| NIP-59 | Full | Gift wrap | 13, 1059 |
| NIP-65 | Full | Relay list metadata | 10002 |
| NIP-94 | Full | File metadata | 1063 |
Core Modules
| Module | Description |
|---|---|
Nostr.Event | Core event struct with create, parse, serialize, sign, validate |
Nostr.Crypto | Cryptographic operations (keys, signing, encryption) |
Nostr.Message | WebSocket protocol messages (EVENT, REQ, CLOSE, etc.) |
Nostr.Filter | Subscription filter building |
Nostr.Bech32 | NIP-19 bech32 encoding/decoding |
Nostr.NIP44 | Versioned encrypted payloads |
Nostr.NIP17 | Private message convenience functions |
Nostr.NIP05 | DNS-based identifier verification |
Event Types
Each event kind has a dedicated module in Nostr.Event.*:
| Kind | Module | Description |
|---|---|---|
| 0 | Metadata | User profile metadata |
| 1 | Note | Text notes/posts |
| 3 | Contacts | Follow list |
| 4 | DirectMessage | Encrypted DMs (deprecated) |
| 5 | Deletion | Event deletion requests |
| 6 | Repost | Reposts (deprecated) |
| 7 | Reaction | Reactions to events |
| 8 | BadgeAward | Badge awards |
| 13 | Seal | Sealed/encrypted events |
| 14 | PrivateMessage | Private chat messages |
| 15 | FileMessage | Encrypted file messages |
| 17 | ExternalReaction | Reactions to external content |
| 40-44 | Channel* | Public chat channels |
| 1040 | OpenTimestamps | Timestamp attestations |
| 1059 | GiftWrap | Gift wrapped events |
| 1063 | FileMetadata | File metadata |
| 1111 | Comment | Threaded comments |
| 1984 | Report | Content reports |
| 1985 | Label | Content labels |
| 9734 | ZapRequest | Lightning zap requests |
| 9735 | ZapReceipt | Lightning zap receipts |
| 10002 | RelayList | Relay list metadata |
| 10050 | DMRelayList | DM relay preferences |
| 22242 | ClientAuth | Client authentication |
| 30023 | Article | Long-form content |
| 30315 | UserStatus | User status updates |
Related Packages
This library is part of a larger Nostr ecosystem for Elixir:
- nostr_lib (this package) - Low-level protocol implementation
- nostr_client - WebSocket client for connecting to relays
- nostr_server - WebSocket server for building relays
- nostr_relay - Full relay implementation
Documentation
Full documentation is available on HexDocs.
Contributing
Contributions are welcome! Please feel free to submit issues and pull requests.