wasmdb

package
v0.52.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 19, 2026 License: Unlicense Imports: 33 Imported by: 0

Documentation

Rendered for js/wasm

Overview

Package wasmdb provides a WebAssembly-compatible database implementation using IndexedDB as the storage backend. It replicates the Badger database's index schema for full query compatibility.

This implementation uses aperturerobotics/go-indexeddb (a fork of hack-pad/go-indexeddb) which provides full IndexedDB bindings with cursor/range support and transaction retry mechanisms to handle IndexedDB's transaction expiration issues in Go WASM.

Architecture:

  • Each index type (evt, eid, kc-, pc-, etc.) maps to an IndexedDB object store
  • Keys are binary-encoded using the same format as the Badger implementation
  • Range queries use IndexedDB cursors with KeyRange bounds
  • Serial numbers are managed using a dedicated "meta" object store

Index

Constants

View Source
const (
	// NIP43StoreName is the object store for NIP-43 membership
	NIP43StoreName = "nip43"

	// InvitesStoreName is the object store for invite codes
	InvitesStoreName = "invites"
)
View Source
const (
	// SubscriptionsStoreName is the object store for payment subscriptions
	SubscriptionsStoreName = "subscriptions"

	// PaymentsPrefix is the key prefix for payment records
	PaymentsPrefix = "payment:"
)
View Source
const (
	// DatabaseName is the IndexedDB database name
	DatabaseName = "orly-nostr-relay"

	// DatabaseVersion is incremented when schema changes require migration
	DatabaseVersion = 1

	// MetaStoreName holds metadata like serial counters
	MetaStoreName = "meta"

	// EventSerialKey is the key for the event serial counter in meta store
	EventSerialKey = "event_serial"

	// PubkeySerialKey is the key for the pubkey serial counter in meta store
	PubkeySerialKey = "pubkey_serial"

	// RelayIdentityKey is the key for the relay identity secret
	RelayIdentityKey = "relay_identity"
)

Variables

View Source
var (
	// ErrOlderThanExisting is returned when a candidate event is older than an existing replaceable/addressable event.
	ErrOlderThanExisting = errors.New("older than existing event")
	// ErrMissingDTag is returned when a parameterized replaceable event lacks the required 'd' tag.
	ErrMissingDTag = errors.New("event is missing a d tag identifier")
)

Functions

func CheckExpiration

func CheckExpiration(ev *event.E) (expired bool)

CheckExpiration checks if an event has expired based on its "expiration" tag

func NewLogger

func NewLogger(level int) *logger

NewLogger creates a new logger with the specified level

func RegisterJSBridge added in v0.48.9

func RegisterJSBridge(db *W, ctx context.Context, cancel context.CancelFunc)

RegisterJSBridge exposes the relay protocol API to JavaScript

Types

type JSBridge added in v0.48.9

type JSBridge struct {
	// contains filtered or unexported fields
}

JSBridge wraps the WasmDB instance for JavaScript interop Exposes a relay protocol interface (NIP-01) rather than direct database access

type W

type W struct {
	Logger *logger
	// contains filtered or unexported fields
}

W implements the database.Database interface using IndexedDB

func New

func New(
	ctx context.Context, cancel context.CancelFunc, dataDir, logLevel string,
) (*W, error)

New creates a new IndexedDB-based database instance with default configuration

func NewWithConfig

func NewWithConfig(
	ctx context.Context, cancel context.CancelFunc, cfg *database.DatabaseConfig,
) (*W, error)

NewWithConfig creates a new IndexedDB-based database instance

func (*W) AddNIP43Member

func (w *W) AddNIP43Member(pubkey []byte, inviteCode string) error

AddNIP43Member adds a pubkey as a NIP-43 member with the given invite code

func (*W) CacheEvents

func (w *W) CacheEvents(f *filter.F, events event.S)

func (*W) CacheMarshaledJSON

func (w *W) CacheMarshaledJSON(f *filter.F, marshaledJSON [][]byte)

func (*W) CheckForDeleted

func (w *W) CheckForDeleted(ev *event.E, admins [][]byte) (err error)

CheckForDeleted checks if the event has been deleted, and returns an error with prefix "blocked:" if it is. This function also allows designating admin pubkeys that may also delete the event.

func (*W) Close

func (w *W) Close() error

Close closes the database

func (*W) CountEvents

func (w *W) CountEvents(c context.Context, f *filter.F) (count int, approx bool, err error)

CountEvents counts events matching a filter

func (*W) DeleteEvent

func (w *W) DeleteEvent(c context.Context, eid []byte) (err error)

DeleteEvent removes an event from the database identified by `eid`.

func (*W) DeleteEventBySerial

func (w *W) DeleteEventBySerial(c context.Context, ser *types.Uint40, ev *event.E) (err error)

DeleteEventBySerial removes an event and all its indexes by serial number.

func (*W) DeleteExpired

func (w *W) DeleteExpired()

DeleteExpired scans for events with expiration timestamps that have passed and deletes them.

func (*W) DeleteInviteCode

func (w *W) DeleteInviteCode(code string) error

DeleteInviteCode removes an invite code

func (*W) DeleteMarker

func (w *W) DeleteMarker(key string) error

func (*W) EventIdsBySerial

func (w *W) EventIdsBySerial(start uint64, count int) ([]uint64, error)

EventIdsBySerial retrieves event IDs by serial range

func (*W) Export

func (w *W) Export(c context.Context, wr io.Writer, pubkeys ...[]byte)

Export writes events to a JSONL writer, optionally filtered by pubkeys

func (*W) ExtendBlossomSubscription

func (w *W) ExtendBlossomSubscription(pubkey []byte, level string, storageMB int64, days int) error

ExtendBlossomSubscription extends a blossom subscription with storage quota

func (*W) ExtendSubscription

func (w *W) ExtendSubscription(pubkey []byte, days int) error

ExtendSubscription extends a subscription by the given number of days

func (*W) FetchEventBySerial

func (w *W) FetchEventBySerial(ser *types.Uint40) (ev *event.E, err error)

FetchEventBySerial retrieves an event by its serial number

func (*W) FetchEventsBySerials

func (w *W) FetchEventsBySerials(serials []*types.Uint40) (events map[uint64]*event.E, err error)

FetchEventsBySerials retrieves multiple events by their serial numbers

func (*W) GetAllNIP43Members

func (w *W) GetAllNIP43Members() ([][]byte, error)

GetAllNIP43Members returns all NIP-43 member pubkeys

func (*W) GetBlossomStorageQuota

func (w *W) GetBlossomStorageQuota(pubkey []byte) (quotaMB int64, err error)

GetBlossomStorageQuota returns the storage quota for a pubkey

func (*W) GetCachedEvents

func (w *W) GetCachedEvents(f *filter.F) (event.S, bool)

func (*W) GetCachedJSON

func (w *W) GetCachedJSON(f *filter.F) ([][]byte, bool)

Query cache methods (simplified for WASM - no caching)

func (*W) GetEventAccessInfo added in v0.46.0

func (w *W) GetEventAccessInfo(serial uint64) (lastAccess int64, accessCount uint32, err error)

GetEventAccessInfo is a stub for WasmDB.

func (*W) GetFullIdPubkeyBySerial

func (w *W) GetFullIdPubkeyBySerial(ser *types.Uint40) (fidpk *store.IdPkTs, err error)

GetFullIdPubkeyBySerial retrieves the ID, pubkey hash, and timestamp for a serial

func (*W) GetFullIdPubkeyBySerials

func (w *W) GetFullIdPubkeyBySerials(sers []*types.Uint40) (fidpks []*store.IdPkTs, err error)

GetFullIdPubkeyBySerials retrieves ID/pubkey/timestamp for multiple serials

func (*W) GetLeastAccessedEvents added in v0.46.0

func (w *W) GetLeastAccessedEvents(limit int, minAgeSec int64) (serials []uint64, err error)

GetLeastAccessedEvents is a stub for WasmDB.

func (*W) GetMarker

func (w *W) GetMarker(key string) (value []byte, err error)

func (*W) GetNIP43Membership

func (w *W) GetNIP43Membership(pubkey []byte) (*database.NIP43Membership, error)

GetNIP43Membership returns the full membership details for a pubkey

func (*W) GetOrCreateRelayIdentitySecret

func (w *W) GetOrCreateRelayIdentitySecret() (skb []byte, err error)

func (*W) GetPaymentHistory

func (w *W) GetPaymentHistory(pubkey []byte) ([]database.Payment, error)

GetPaymentHistory retrieves all payments for a pubkey

func (*W) GetRelayIdentitySecret

func (w *W) GetRelayIdentitySecret() (skb []byte, err error)

func (*W) GetSerialById

func (w *W) GetSerialById(id []byte) (ser *types.Uint40, err error)

GetSerialById looks up the serial number for an event ID

func (*W) GetSerialsByIds

func (w *W) GetSerialsByIds(ids *tag.T) (serials map[string]*types.Uint40, err error)

GetSerialsByIds looks up serial numbers for multiple event IDs

func (*W) GetSerialsByIdsWithFilter

func (w *W) GetSerialsByIdsWithFilter(ids *tag.T, fn func(ev *event.E, ser *types.Uint40) bool) (serials map[string]*types.Uint40, err error)

GetSerialsByIdsWithFilter looks up serial numbers with a filter function

func (*W) GetSerialsByPubkey

func (w *W) GetSerialsByPubkey(pubkey []byte) ([]*types.Uint40, error)

GetSerialsByPubkey returns all event serials for a given pubkey

func (*W) GetSerialsByRange

func (w *W) GetSerialsByRange(idx database.Range) (sers types.Uint40s, err error)

GetSerialsByRange retrieves serials from an index range using cursor iteration. The index keys must end with a 5-byte serial number.

func (*W) GetSerialsFromFilter

func (w *W) GetSerialsFromFilter(f *filter.F) (serials types.Uint40s, err error)

GetSerialsFromFilter is an alias for QueryForSerials for interface compatibility

func (*W) GetSubscription

func (w *W) GetSubscription(pubkey []byte) (*database.Subscription, error)

GetSubscription retrieves a subscription for a pubkey

func (*W) HasMarker

func (w *W) HasMarker(key string) bool

func (*W) Import

func (w *W) Import(rr io.Reader)

Import reads events from a JSONL reader and imports them into the database

func (*W) ImportEventsFromReader

func (w *W) ImportEventsFromReader(ctx context.Context, rr io.Reader) error

ImportEventsFromReader imports events from a JSONL reader with context support

func (*W) ImportEventsFromStrings

func (w *W) ImportEventsFromStrings(
	ctx context.Context,
	eventJSONs []string,
	policyManager interface {
		CheckPolicy(action string, ev *event.E, pubkey []byte, remote string) (bool, error)
	},
) error

ImportEventsFromStrings imports events from JSON strings with policy checking

func (*W) Init

func (w *W) Init(path string) error

Init initializes the database (no-op, done in New)

func (*W) InvalidateQueryCache

func (w *W) InvalidateQueryCache()

func (*W) IsFirstTimeUser

func (w *W) IsFirstTimeUser(pubkey []byte) (bool, error)

IsFirstTimeUser checks if a pubkey is a first-time user (no subscription history)

func (*W) IsNIP43Member

func (w *W) IsNIP43Member(pubkey []byte) (isMember bool, err error)

IsNIP43Member checks if a pubkey is a NIP-43 member

func (*W) IsSubscriptionActive

func (w *W) IsSubscriptionActive(pubkey []byte) (bool, error)

IsSubscriptionActive checks if a pubkey has an active subscription If no subscription exists, creates a 30-day trial

func (*W) Path

func (w *W) Path() string

Path returns the database path (not used in WASM)

func (*W) ProcessDelete

func (w *W) ProcessDelete(ev *event.E, admins [][]byte) (err error)

ProcessDelete processes a kind 5 deletion event, deleting referenced events.

func (*W) PublishNIP43MembershipEvent

func (w *W) PublishNIP43MembershipEvent(kind int, pubkey []byte) error

PublishNIP43MembershipEvent is a no-op in WASM (events are handled by the relay)

func (*W) QueryAllVersions

func (w *W) QueryAllVersions(c context.Context, f *filter.F) (evs event.S, err error)

QueryAllVersions queries events and returns all versions of replaceable events

func (*W) QueryDeleteEventsByTargetId

func (w *W) QueryDeleteEventsByTargetId(c context.Context, targetEventId []byte) (evs event.S, err error)

QueryDeleteEventsByTargetId queries for delete events targeting a specific event ID

func (*W) QueryEvents

func (w *W) QueryEvents(c context.Context, f *filter.F) (evs event.S, err error)

QueryEvents queries events based on a filter

func (*W) QueryEventsWithOptions

func (w *W) QueryEventsWithOptions(c context.Context, f *filter.F, includeDeleteEvents bool, showAllVersions bool) (evs event.S, err error)

QueryEventsWithOptions queries events with additional options for deletion and versioning

func (*W) QueryForIds

func (w *W) QueryForIds(c context.Context, f *filter.F) (idPkTs []*store.IdPkTs, err error)

QueryForIds retrieves IdPkTs records based on a filter. Results are sorted by timestamp in reverse chronological order.

func (*W) QueryForSerials

func (w *W) QueryForSerials(c context.Context, f *filter.F) (sers types.Uint40s, err error)

QueryForSerials takes a filter and returns matching event serials

func (*W) Ready

func (w *W) Ready() <-chan struct{}

Ready returns a channel that closes when the database is ready

func (*W) RecordEventAccess added in v0.46.0

func (w *W) RecordEventAccess(serial uint64, connectionID string) error

RecordEventAccess is a stub for WasmDB. Access tracking is not implemented for the WebAssembly backend as it's primarily used for client-side applications where storage management is handled differently.

func (*W) RecordPayment

func (w *W) RecordPayment(pubkey []byte, amount int64, invoice, preimage string) error

RecordPayment records a payment for a pubkey

func (*W) RemoveNIP43Member

func (w *W) RemoveNIP43Member(pubkey []byte) error

RemoveNIP43Member removes a pubkey from NIP-43 membership

func (*W) RunMigrations

func (w *W) RunMigrations()

RunMigrations runs database migrations (handled by IndexedDB upgrade)

func (*W) SaveEvent

func (w *W) SaveEvent(c context.Context, ev *event.E) (replaced bool, err error)

SaveEvent saves an event to the database, generating all necessary indexes.

func (*W) SetLogLevel

func (w *W) SetLogLevel(level string)

SetLogLevel sets the logging level

func (*W) SetMarker

func (w *W) SetMarker(key string, value []byte) error

func (*W) SetRelayIdentitySecret

func (w *W) SetRelayIdentitySecret(skb []byte) error

func (*W) StoreInviteCode

func (w *W) StoreInviteCode(code string, expiresAt time.Time) error

StoreInviteCode stores an invite code with expiration time

func (*W) Sync

func (w *W) Sync() error

Sync flushes pending writes (IndexedDB handles persistence automatically)

func (*W) ValidateInviteCode

func (w *W) ValidateInviteCode(code string) (valid bool, err error)

ValidateInviteCode checks if an invite code is valid (exists and not expired)

func (*W) Wipe

func (w *W) Wipe() error

Wipe removes all data and recreates object stores

func (*W) WouldReplaceEvent

func (w *W) WouldReplaceEvent(ev *event.E) (bool, types.Uint40s, error)

WouldReplaceEvent checks if the provided event would replace existing events

Source Files

  • access_tracking.go
  • delete-event.go
  • fetch-event.go
  • helpers.go
  • import-export.go
  • jsbridge.go
  • logger.go
  • nip43.go
  • query-events.go
  • save-event.go
  • subscriptions.go
  • wasmdb.go

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL