diff --git a/README.md b/README.md index cc2567f..d027425 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,19 @@ -nostr library -============= +# nostr -supposed to contain everything you need to write a relay or client or hybrid or anything else. +A comprehensive Go library for the Nostr protocol, providing everything needed to build relays, clients, or hybrid applications. -this is a fork of https://github.com/nbd-wtf/go-nostr with better types and other random changes or features. +This is a fork of [go-nostr](https://github.com/nbd-wtf/go-nostr) with enhanced types, additional features, and extensive NIP support. + +## Installation ```sh go get fiatjaf.com/nostr ``` + +## Components + +- **eventstore**: Pluggable storage backends (Bluge, BoltDB, LMDB, in-memory, nullstore) +- **khatru**: Relay framework for building Nostr relays +- **sdk**: Client SDK with caching, data loading, and relay management +- **keyer**: Key management utilities +- **NIPs**: Implementations for NIPs 4-94, covering encryption, metadata, relays, and more diff --git a/eventstore/README.md b/eventstore/README.md index 67647e6..9dfaac6 100644 --- a/eventstore/README.md +++ b/eventstore/README.md @@ -11,21 +11,35 @@ type Store interface { // Close must be called after you're done using the store, to free up resources and so on. Close() - // QueryEvents is invoked upon a client's REQ as described in NIP-01. - // it should return a channel with the events as they're recovered from a database. - // the channel should be closed after the events are all delivered. - QueryEvents(context.Context, nostr.Filter) (chan *nostr.Event, error) + // QueryEvents returns events that match the filter + QueryEvents(filter nostr.Filter, maxLimit int) iter.Seq[nostr.Event] - // DeleteEvent is used to handle deletion events, as per NIP-09. - DeleteEvent(context.Context, *nostr.Event) error + // DeleteEvent deletes an event atomically by ID + DeleteEvent(nostr.ID) error - // SaveEvent is called once Relay.AcceptEvent reports true. - SaveEvent(context.Context, *nostr.Event) error + // SaveEvent just saves an event, no side-effects. + SaveEvent(nostr.Event) error + + // ReplaceEvent atomically replaces a replaceable or addressable event. + // Conceptually it is like a Query->Delete->Save, but streamlined. + ReplaceEvent(nostr.Event) error + + // CountEvents counts all events that match a given filter + CountEvents(nostr.Filter) (uint32, error) } ``` [![Go Reference](https://pkg.go.dev/badge/fiatjaf.com/nostr/eventstore.svg)](https://pkg.go.dev/fiatjaf.com/nostr/eventstore) [![Run Tests](https://fiatjaf.com/nostr/eventstore/actions/workflows/test.yml/badge.svg)](https://fiatjaf.com/nostr/eventstore/actions/workflows/test.yml) -## command-line tool +## Available Implementations + +- **bluge**: Full-text search and indexing using the Bluge search library +- **boltdb**: Embedded key-value database using BoltDB +- **lmdb**: High-performance embedded database using LMDB +- **mmm**: Custom memory-mapped storage with advanced indexing +- **nullstore**: No-op store for testing and development +- **slicestore**: Simple in-memory slice-based store + +## Command-line Tool There is an [`eventstore` command-line tool](cmd/eventstore) that can be used to query these databases directly. diff --git a/eventstore/cmd/eventstore/README.md b/eventstore/cmd/eventstore/README.md index c75463e..2d0f997 100644 --- a/eventstore/cmd/eventstore/README.md +++ b/eventstore/cmd/eventstore/README.md @@ -26,14 +26,23 @@ This will automatically determine the storage type being used at `/path/to/store ~> echo '{"id":"35369e6bae5f77c4e1745c2eb5db84c4493e87f6e449aee62a261bbc1fea2788","pubkey":"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798","created_at":1701193836,"kind":1,"tags":[],"content":"hello","sig":"ef08d559e042d9af4cdc3328a064f737603d86ec4f929f193d5a3ce9ea22a3fb8afc1923ee3c3742fd01856065352c5632e91f633528c80e9c5711fa1266824c"}' | eventstore -d /path/to/store save ``` -You can also create a database from scratch if it's a disk database, but then you have to specify `-t` to `boltdb` or `lmdb`. +### Counting events matching a filter -### Connecting to Postgres, MySQL and other remote databases - -You should be able to connect by just passing the database connection URI to `-d`: - -```bash -~> eventstore -d 'postgres://myrelay:38yg4o83yf48a3s7g@localhost:5432/myrelay?sslmode=disable' +```fish +~> echo '{"kinds":[1]}' | eventstore -d /path/to/store count ``` -That should be prefixed with `postgres://` for Postgres, `mysql://` for MySQL and `https://` for ElasticSearch. +### Deleting an event by ID + +```fish +~> echo '35369e6bae5f77c4e1745c2eb5db84c4493e87f6e449aee62a261bbc1fea2788' | eventstore -d /path/to/store delete +``` + +### Query or save (default command) + +Pipes events or filters and handles them appropriately. + +You can also create a database from scratch if it's a disk database, but then you have to specify `-t` to `boltdb` or `lmdb`. + +Supported store types: `lmdb`, `boltdb`, `mmm`, `file` (for JSONL files). + diff --git a/eventstore/nullstore/README.md b/eventstore/nullstore/README.md index 8f9673d..c943ee5 100644 --- a/eventstore/nullstore/README.md +++ b/eventstore/nullstore/README.md @@ -1,2 +1,11 @@ -`nullstore` is an eventstore that doesn't actually do anything. -It doesn't store anything, it doesn't return anything. +# NullStore + +`nullstore` is a no-op implementation of the eventstore interface that doesn't actually store or retrieve any events. + +All operations succeed without error but have no effect: +- `SaveEvent` and `ReplaceEvent` do nothing +- `QueryEvents` returns an empty iterator +- `DeleteEvent` does nothing +- `CountEvents` returns 0 + +This is useful for testing, development environments, or when event persistence is not required. diff --git a/nip44/README.md b/nip44/README.md deleted file mode 100644 index 2ca8f06..0000000 --- a/nip44/README.md +++ /dev/null @@ -1 +0,0 @@ -Code copied from https://github.com/paulmillr/nip44/tree/e7aed61aaf77240ac10c325683eed14b22e7950f/go.