nip_append_only_list library
Local-first Dart implementation of the Nostr append-only lists NIP.
The NIP defines two regular event kinds - kind:1990 (Add) and
kind:1991 (Remove) - that complement NIP-51 by storing list membership
as an OR-Set CRDT instead of last-write-wins replaceable events. State
is computed client-side; concurrent edits from multiple devices converge
without coordination.
This library provides:
- A pure CRDT core (AppendOnlyListState, AppendOnlyListEntry, AppendOnlyListEvent) for parsing and folding events independently of NDK.
- Filter helpers (listFilter, deletionFilter) for relay queries.
- A persistent cleartext projection store (ProjectionStore) backed by sembast - keeps previously-decrypted private entries readable across restarts even before a signer is connected.
- AppendOnlyLists, a high-level usecase wiring NDK's cache + requests,
the projection, and an injected
OfflineBroadcastqueue for durable write delivery.
Classes
- AppendOnlyListEntry
- A single entry in an append-only list.
- AppendOnlyListEvent
-
A parsed append-only list event, with public and private entries already
separated. Private entries are populated only when content decryption
succeeded (i.e. a capable
EventSignerwas provided to parse). - AppendOnlyLists
- Local-first usecase for NIP append-only lists (kinds 1990/1991).
- AppendOnlyListState
- Resolved state of an append-only list for a single (author, listName).
- EntryStat
- Per-entry OR-Set timestamps.
- ProjectionStore
- Persistent cleartext projection of computed list state.
Enums
- AppendOnlyListOp
- Operation carried by an append-only list event.
Constants
-
appendOnlyKinds
→ const List<
int> - dTag → const String
-
Tag name identifying the list (
dtag, inherited from NIP-51). - kindAdd → const int
- kindRemove → const int
Functions
-
buildAppendOnlyEvent(
{required AppendOnlyListOp op, required String listName, required List< AppendOnlyListEntry> entries, required String pubkey, EventSigner? signer, int? createdAt}) → Future<Nip01Event> - Builds (but does not sign or broadcast) a kind 1990 / 1991 event.
-
deletionFilter(
{required String pubkey, int? since}) → Filter -
Returns a
Filterthat fetches NIP-09 deletion events frompubkeythat target append-only kinds. The#ktag constraint is what makes this query cheap: relays only return deletions whosektag is"1990"or"1991", skipping every unrelated deletion the author has ever made. -
listFilter(
{required String pubkey, required String listName, int? since}) → Filter -
Returns a
Filterthat fetches an author's append-only list events.