Documentation
¶
Overview ¶
Package database provides filter utilities for normalizing tag values.
The nostr library optimizes e/p tag values by storing them in binary format (32 bytes + null terminator) rather than hex strings (64 chars). However, filter tags from client queries come as hex strings and don't go through the same binary encoding during unmarshalling.
This file provides utilities to normalize filter tags to match the binary encoding used in stored events, ensuring consistent index lookups and tag comparisons.
Package database provides shared import utilities for events
Index ¶
- Constants
- Variables
- func BinaryToHex(binVal []byte) []byte
- func CanUsePTagGraph(f *filter.F) bool
- func CheckExpiration(ev *event.E) (expired bool)
- func CreateIdHashFromData(data []byte) (i *types2.IdHash, err error)
- func CreatePubHashFromData(data []byte) (p *types2.PubHash, err error)
- func GetIndexesForEvent(ev *event.E, serial uint64) (idxs [][]byte, err error)
- func HexToBinary(hexVal []byte) []byte
- func IsBinaryEncoded(val []byte) bool
- func IsBinaryOptimizedTag(key byte) bool
- func IsHexString(data []byte) (isHex bool)
- func IsValidHexValue(b []byte) bool
- func NewLogger(logLevel int, label string) (l *logger)
- func NormalizeFilter(f *filter.F) *filter.F
- func NormalizeFilterTag(t *tag.T) *tag.T
- func NormalizeFilterTags(tags *tag.S) *tag.S
- func NormalizeTagToHex(val []byte) []byte
- func NormalizeTagValue(key byte, val []byte) []byte
- func NormalizeTagValueForHash(key byte, valueBytes []byte) []byte
- func RegisterDgraphFactory(...)
- func RegisterNeo4jFactory(...)
- func RegisterWasmDBFactory(...)
- func TagValuesMatch(key byte, eventVal, filterVal []byte) bool
- func TagValuesMatchUsingTagMethods(eventTag *tag.T, filterVal []byte) bool
- func TokenHashes(content []byte) [][]byte
- type AllowedEvent
- type AllowedKind
- type AllowedPubkey
- type BannedEvent
- type BannedPubkey
- type BlockedIP
- type D
- func (d *D) AddNIP43Member(pubkey []byte, inviteCode string) error
- func (d *D) CacheEvents(f *filter.F, events event.S)
- func (d *D) CacheMarshaledJSON(f *filter.F, marshaledJSON [][]byte)
- func (d *D) CheckForDeleted(ev *event.E, admins [][]byte) (err error)
- func (d *D) CleanupEphemeralEvents()
- func (d *D) CleanupKind3WithoutPTags(ctx context.Context) error
- func (d *D) Close() (err error)
- func (d *D) ConvertSmallEventsToInline()
- func (d *D) CountEvents(c context.Context, f *filter.F) (count int, approx bool, err error)
- func (d *D) DeleteEvent(c context.Context, eid []byte) (err error)
- func (d *D) DeleteEventBySerial(c context.Context, ser *types.Uint40, ev *event.E) (err error)
- func (d *D) DeleteExpired()
- func (d *D) DeleteInviteCode(code string) error
- func (d *D) DeleteMarker(key string) (err error)
- func (d *D) EventIdsBySerial(start uint64, count int) (evs []uint64, err error)
- func (d *D) Export(c context.Context, w io.Writer, pubkeys ...[]byte)
- func (d *D) ExtendBlossomSubscription(pubkey []byte, level string, storageMB int64, days int) error
- func (d *D) ExtendSubscription(pubkey []byte, days int) error
- func (d *D) FetchEventBySerial(ser *types.Uint40) (ev *event.E, err error)
- func (d *D) FetchEventsBySerials(serials []*types.Uint40) (events map[uint64]*event.E, err error)
- func (d *D) GetAllNIP43Members() ([][]byte, error)
- func (d *D) GetBlossomStorageQuota(pubkey []byte) (quotaMB int64, err error)
- func (d *D) GetCachedEvents(f *filter.F) (event.S, bool)
- func (d *D) GetCachedJSON(f *filter.F) ([][]byte, bool)
- func (d *D) GetFullIdPubkeyBySerial(ser *types.Uint40) (fidpk *store.IdPkTs, err error)
- func (d *D) GetFullIdPubkeyBySerials(sers []*types.Uint40) (fidpks []*store.IdPkTs, err error)
- func (d *D) GetMarker(key string) (value []byte, err error)
- func (d *D) GetNIP43Membership(pubkey []byte) (*NIP43Membership, error)
- func (d *D) GetOrCreatePubkeySerial(pubkey []byte) (ser *types.Uint40, err error)
- func (d *D) GetOrCreateRelayIdentitySecret() (skb []byte, err error)
- func (d *D) GetPaymentHistory(pubkey []byte) ([]Payment, error)
- func (d *D) GetPubkeyBySerial(ser *types.Uint40) (pubkey []byte, err error)
- func (d *D) GetPubkeySerial(pubkey []byte) (ser *types.Uint40, err error)
- func (d *D) GetRelayIdentitySecret() (skb []byte, err error)
- func (d *D) GetSerialById(id []byte) (ser *types.Uint40, err error)
- func (d *D) GetSerialsByIds(ids *tag.T) (serials map[string]*types.Uint40, err error)
- func (d *D) GetSerialsByIdsWithFilter(ids *tag.T, fn func(ev *event.E, ser *types.Uint40) bool) (serials map[string]*types.Uint40, err error)
- func (d *D) GetSerialsByRange(idx Range) (sers types.Uint40s, err error)
- func (d *D) GetSerialsFromFilter(f *filter.F) (sers types.Uint40s, err error)
- func (d *D) GetSubscription(pubkey []byte) (*Subscription, error)
- func (d *D) HasMarker(key string) (exists bool)
- func (d *D) Import(rr io.Reader)
- func (d *D) ImportEventsFromReader(ctx context.Context, rr io.Reader) error
- func (d *D) ImportEventsFromStrings(ctx context.Context, eventJSONs []string, policyManager interface{ ... }) error
- func (d *D) Init(path string) (err error)
- func (d *D) InvalidateQueryCache()
- func (d *D) IsFirstTimeUser(pubkey []byte) (bool, error)
- func (d *D) IsNIP43Member(pubkey []byte) (isMember bool, err error)
- func (d *D) IsSubscriptionActive(pubkey []byte) (bool, error)
- func (d *D) Path() string
- func (d *D) ProcessDelete(ev *event.E, admins [][]byte) (err error)
- func (d *D) PublishNIP43MembershipEvent(kind int, pubkey []byte) error
- func (d *D) QueryAllVersions(c context.Context, f *filter.F) (evs event.S, err error)
- func (d *D) QueryCacheStats() querycache.CacheStats
- func (d *D) QueryDeleteEventsByTargetId(c context.Context, targetEventId []byte) (evs event.S, err error)
- func (d *D) QueryEvents(c context.Context, f *filter.F) (evs event.S, err error)
- func (d *D) QueryEventsWithOptions(c context.Context, f *filter.F, includeDeleteEvents bool, showAllVersions bool) (evs event.S, err error)
- func (d *D) QueryForIds(c context.Context, f *filter.F) (idPkTs []*store.IdPkTs, err error)
- func (d *D) QueryForSerials(c context.Context, f *filter.F) (sers types.Uint40s, err error)
- func (d *D) QueryPTagGraph(f *filter.F) (sers types.Uint40s, err error)
- func (d *D) Ready() <-chan struct{}
- func (d *D) RecordPayment(pubkey []byte, amount int64, invoice, preimage string) error
- func (d *D) ReencodeEventsWithOptimizedTags()
- func (d *D) RemoveNIP43Member(pubkey []byte) error
- func (d *D) RunMigrations()
- func (d *D) SaveEvent(c context.Context, ev *event.E) (replaced bool, err error)
- func (d *D) SetLogLevel(level string)
- func (d *D) SetMarker(key string, value []byte) (err error)
- func (d *D) SetRelayIdentitySecret(skb []byte) (err error)
- func (d *D) StoreInviteCode(code string, expiresAt time.Time) error
- func (d *D) Sync() (err error)
- func (d *D) UpdateExpirationTags()
- func (d *D) UpdateWordIndexes()
- func (d *D) ValidateInviteCode(code string) (valid bool, err error)
- func (d *D) Wipe() (err error)
- func (d *D) WouldReplaceEvent(ev *event.E) (bool, types.Uint40s, error)
- type Database
- type DatabaseConfig
- type EventNeedingModeration
- type ManagedACL
- func (m *ManagedACL) GetRelayConfig() (ManagedACLConfig, error)
- func (m *ManagedACL) IsEventAllowed(eventID string) (bool, error)
- func (m *ManagedACL) IsEventBanned(eventID string) (bool, error)
- func (m *ManagedACL) IsIPBlocked(ip string) (bool, error)
- func (m *ManagedACL) IsKindAllowed(kind int) (bool, error)
- func (m *ManagedACL) IsPubkeyAllowed(pubkey string) (bool, error)
- func (m *ManagedACL) IsPubkeyBanned(pubkey string) (bool, error)
- func (m *ManagedACL) ListAllowedEvents() ([]AllowedEvent, error)
- func (m *ManagedACL) ListAllowedKinds() ([]int, error)
- func (m *ManagedACL) ListAllowedPubkeys() ([]AllowedPubkey, error)
- func (m *ManagedACL) ListBannedEvents() ([]BannedEvent, error)
- func (m *ManagedACL) ListBannedPubkeys() ([]BannedPubkey, error)
- func (m *ManagedACL) ListBlockedIPs() ([]BlockedIP, error)
- func (m *ManagedACL) ListEventsNeedingModeration() ([]EventNeedingModeration, error)
- func (m *ManagedACL) RemoveAllowedEvent(eventID string) error
- func (m *ManagedACL) RemoveAllowedKind(kind int) error
- func (m *ManagedACL) RemoveAllowedPubkey(pubkey string) error
- func (m *ManagedACL) RemoveBannedEvent(eventID string) error
- func (m *ManagedACL) RemoveBannedPubkey(pubkey string) error
- func (m *ManagedACL) RemoveBlockedIP(ip string) error
- func (m *ManagedACL) RemoveEventNeedingModeration(eventID string) error
- func (m *ManagedACL) SaveAllowedEvent(eventID string, reason string) error
- func (m *ManagedACL) SaveAllowedKind(kind int) error
- func (m *ManagedACL) SaveAllowedPubkey(pubkey string, reason string) error
- func (m *ManagedACL) SaveBannedEvent(eventID string, reason string) error
- func (m *ManagedACL) SaveBannedPubkey(pubkey string, reason string) error
- func (m *ManagedACL) SaveBlockedIP(ip string, reason string) error
- func (m *ManagedACL) SaveEventNeedingModeration(eventID string, reason string) error
- func (m *ManagedACL) SaveRelayConfig(config ManagedACLConfig) error
- type ManagedACLConfig
- type NIP43Membership
- type Payment
- type Range
- type Subscription
Constants ¶
const ( // BinaryEncodedLen is the length of a binary-encoded 32-byte hash with null terminator BinaryEncodedLen = 33 // HexEncodedLen is the length of a hex-encoded 32-byte hash HexEncodedLen = 64 // HashLen is the raw length of a hash (pubkey/event ID) HashLen = 32 )
Tag binary encoding constants (matching the nostr library)
Variables ¶
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 BinaryToHex ¶ added in v0.30.3
BinaryToHex converts a 33-byte binary value to 64-character hex string Returns nil if the input is not in binary format
func CanUsePTagGraph ¶ added in v0.29.11
CanUsePTagGraph determines if a filter can benefit from p-tag graph optimization.
Requirements: - Filter must have #p tags - Filter should NOT have authors (different index is better for that case) - Optimization works best with kinds filter but is optional
func CreateIdHashFromData ¶
CreateIdHashFromData creates an IdHash from data that could be hex or binary
func CreatePubHashFromData ¶
CreatePubHashFromData creates a PubHash from data that could be hex or binary
func GetIndexesForEvent ¶
GetIndexesForEvent creates all the indexes for an event.E instance as defined in keys.go. It returns a slice of byte slices that can be used to store the event in the database.
func HexToBinary ¶ added in v0.30.3
HexToBinary converts a 64-character hex string to 33-byte binary format Returns nil if the input is not a valid hex string
func IsBinaryEncoded ¶ added in v0.30.3
IsBinaryEncoded checks if a value field is stored in optimized binary format
func IsBinaryOptimizedTag ¶ added in v0.30.3
IsBinaryOptimizedTag returns true if the given tag key uses binary encoding
func IsHexString ¶
IsHexString checks if the byte slice contains only hex characters
func IsValidHexValue ¶ added in v0.30.3
IsValidHexValue checks if a byte slice is a valid 64-character hex string
func NewLogger ¶
NewLogger creates a new badger logger.
func NormalizeFilter ¶ added in v0.30.3
NormalizeFilter normalizes a filter's tags for consistent database queries. This should be called before using a filter for database lookups. The original filter is not modified; a copy with normalized tags is returned.
func NormalizeFilterTag ¶ added in v0.30.3
NormalizeFilterTag creates a new tag with binary-encoded values for e/p tags. The original tag is not modified.
func NormalizeFilterTags ¶ added in v0.30.3
NormalizeFilterTags normalizes all tags in a tag.S, converting e/p hex values to binary. Returns a new tag.S with normalized tags.
func NormalizeTagToHex ¶ added in v0.30.3
NormalizeTagToHex returns the hex representation of a tag value. For binary-encoded values, converts to hex. For hex values, returns as-is.
func NormalizeTagValue ¶ added in v0.30.3
NormalizeTagValue normalizes a tag value for the given key. For e/p tags, hex values are converted to binary format. Other tags are returned unchanged.
func NormalizeTagValueForHash ¶ added in v0.30.3
NormalizeTagValueForHash normalizes a tag value for consistent hashing. For 'e' and 'p' tags, the nostr library stores values in binary format (32 bytes), but filters from clients come with hex strings (64 chars). This function ensures that filter values are converted to binary to match the stored index format.
This function delegates to NormalizeTagValue from filter_utils.go for consistency.
func RegisterDgraphFactory ¶ added in v0.29.1
func RegisterDgraphFactory(factory func(context.Context, context.CancelFunc, *DatabaseConfig) (Database, error))
RegisterDgraphFactory registers the dgraph database factory This is called from the dgraph package's init() function
func RegisterNeo4jFactory ¶ added in v0.29.3
func RegisterNeo4jFactory(factory func(context.Context, context.CancelFunc, *DatabaseConfig) (Database, error))
RegisterNeo4jFactory registers the neo4j database factory This is called from the neo4j package's init() function
func RegisterWasmDBFactory ¶ added in v0.32.0
func RegisterWasmDBFactory(factory func(context.Context, context.CancelFunc, *DatabaseConfig) (Database, error))
RegisterWasmDBFactory registers the wasmdb database factory This is called from the wasmdb package's init() function
func TagValuesMatch ¶ added in v0.30.3
TagValuesMatch compares two tag values, handling both binary and hex encodings. This is useful for post-query tag matching where event values may be binary and filter values may be hex (or vice versa).
func TagValuesMatchUsingTagMethods ¶ added in v0.30.3
TagValuesMatchUsingTagMethods compares an event tag's value with a filter value using the tag.T methods. This leverages the nostr library's ValueHex() method for proper binary/hex conversion.
func TokenHashes ¶ added in v0.9.0
TokenHashes extracts unique word hashes (8-byte truncated sha256) from content. Rules: - Unicode-aware: words are sequences of letters or numbers. - Lowercased using unicode case mapping. - Ignore URLs (starting with http://, https://, www., or containing "://"). - Ignore nostr: URIs and #[n] mentions. - Ignore words shorter than 2 runes. - Exclude 64-character hexadecimal strings (likely IDs/pubkeys).
Types ¶
type AllowedEvent ¶ added in v0.17.0
type AllowedEvent struct {
ID string `json:"id"`
Reason string `json:"reason,omitempty"`
Added time.Time `json:"added"`
}
AllowedEvent represents an allowed event entry
type AllowedKind ¶ added in v0.17.0
AllowedKind represents an allowed event kind
type AllowedPubkey ¶ added in v0.17.0
type AllowedPubkey struct {
Pubkey string `json:"pubkey"`
Reason string `json:"reason,omitempty"`
Added time.Time `json:"added"`
}
AllowedPubkey represents an allowed public key entry
type BannedEvent ¶ added in v0.17.0
type BannedEvent struct {
ID string `json:"id"`
Reason string `json:"reason,omitempty"`
Added time.Time `json:"added"`
}
BannedEvent represents a banned event entry
type BannedPubkey ¶ added in v0.17.0
type BannedPubkey struct {
Pubkey string `json:"pubkey"`
Reason string `json:"reason,omitempty"`
Added time.Time `json:"added"`
}
BannedPubkey represents a banned public key entry
type BlockedIP ¶ added in v0.17.0
type BlockedIP struct {
IP string `json:"ip"`
Reason string `json:"reason,omitempty"`
Added time.Time `json:"added"`
}
BlockedIP represents a blocked IP address entry
type D ¶
D implements the Database interface using Badger as the storage backend
func New ¶
func New( ctx context.Context, cancel context.CancelFunc, dataDir, logLevel string, ) ( d *D, err error, )
New creates a new Badger database instance with default configuration. This is provided for backward compatibility with existing callers. For full configuration control, use NewWithConfig instead.
func NewWithConfig ¶ added in v0.31.8
func NewWithConfig( ctx context.Context, cancel context.CancelFunc, cfg *DatabaseConfig, ) ( d *D, err error, )
NewWithConfig creates a new Badger database instance with full configuration. This is the preferred method when you have access to DatabaseConfig.
func (*D) AddNIP43Member ¶ added in v0.27.0
AddNIP43Member adds a member to the NIP-43 membership list
func (*D) CacheEvents ¶ added in v0.29.11
CacheEvents stores events for a filter (without subscription ID)
func (*D) CacheMarshaledJSON ¶ added in v0.29.1
CacheMarshaledJSON stores marshaled JSON event envelopes for a filter
func (*D) CheckForDeleted ¶
CheckForDeleted checks if the event is deleted, and returns an error with prefix "blocked:" if it is. This function also allows designating admin pubkeys that also may delete the event, normally only the author is allowed to delete an event.
func (*D) CleanupKind3WithoutPTags ¶ added in v0.31.1
CleanupKind3WithoutPTags scans for kind 3 follow list events that have no p tags and deletes them. This cleanup is needed because the directory spider may have saved malformed events that lost their tags during serialization.
func (*D) ConvertSmallEventsToInline ¶ added in v0.28.0
func (d *D) ConvertSmallEventsToInline()
ConvertSmallEventsToInline migrates small events (<=384 bytes) to inline storage. This is a Reiser4-inspired optimization that stores small event data in the key itself, avoiding a second database lookup and improving query performance. Also handles replaceable and addressable events with specialized storage.
func (*D) CountEvents ¶ added in v0.10.0
CountEvents mirrors the initial selection logic of QueryEvents but stops once we have identified candidate event serials (id/pk/ts). It returns the count of those serials. The `approx` flag is always false as requested.
func (*D) DeleteEvent ¶
DeleteEvent removes an event from the database identified by `eid`. If noTombstone is false or not provided, a tombstone is created for the event.
func (*D) DeleteEventBySerial ¶
func (*D) DeleteInviteCode ¶ added in v0.27.0
DeleteInviteCode removes an invite code (after use)
func (*D) DeleteMarker ¶ added in v0.6.0
DeleteMarker removes a marker from the database
func (*D) EventIdsBySerial ¶
func (*D) Export ¶
Export the complete database of stored events to an io.Writer in line structured minified JSON.
func (*D) ExtendBlossomSubscription ¶ added in v0.23.3
func (d *D) ExtendBlossomSubscription( pubkey []byte, level string, storageMB int64, days int, ) error
ExtendBlossomSubscription extends or creates a blossom subscription with service level
func (*D) FetchEventBySerial ¶
func (*D) FetchEventsBySerials ¶ added in v0.4.9
FetchEventsBySerials fetches multiple events by their serials in a single database transaction. Returns a map of serial uint64 value to event, only including successfully fetched events.
func (*D) GetAllNIP43Members ¶ added in v0.27.0
GetAllNIP43Members returns all NIP-43 members
func (*D) GetBlossomStorageQuota ¶ added in v0.23.3
GetBlossomStorageQuota returns the current blossom storage quota in MB for a pubkey
func (*D) GetCachedEvents ¶ added in v0.29.11
GetCachedEvents retrieves cached events for a filter (without subscription ID) Returns nil, false if not found
func (*D) GetCachedJSON ¶ added in v0.29.1
GetCachedJSON retrieves cached marshaled JSON for a filter Returns nil, false if not found
func (*D) GetFullIdPubkeyBySerial ¶
func (*D) GetFullIdPubkeyBySerials ¶
GetFullIdPubkeyBySerials seeks directly to each serial's prefix in the FullIdPubkey index. The input sers slice is expected to be sorted in ascending order, allowing efficient forward-only iteration via a single Badger iterator.
func (*D) GetMarker ¶ added in v0.6.0
GetMarker retrieves an arbitrary marker from the database
func (*D) GetNIP43Membership ¶ added in v0.27.0
func (d *D) GetNIP43Membership(pubkey []byte) (*NIP43Membership, error)
GetNIP43Membership retrieves membership details for a pubkey
func (*D) GetOrCreatePubkeySerial ¶ added in v0.29.11
GetOrCreatePubkeySerial returns the serial for a pubkey, creating one if it doesn't exist. The pubkey parameter should be 32 bytes (schnorr public key). This function is thread-safe and uses transactions to ensure atomicity.
func (*D) GetOrCreateRelayIdentitySecret ¶ added in v0.8.0
GetOrCreateRelayIdentitySecret retrieves the existing relay identity secret key or creates and stores a new one if none exists.
func (*D) GetPubkeyBySerial ¶ added in v0.29.11
GetPubkeyBySerial returns the full 32-byte pubkey for a given serial.
func (*D) GetPubkeySerial ¶ added in v0.29.11
GetPubkeySerial returns the serial for a pubkey if it exists. Returns an error if the pubkey doesn't have a serial yet.
func (*D) GetRelayIdentitySecret ¶ added in v0.8.0
GetRelayIdentitySecret returns the relay identity secret key bytes if present. If the key is not found, returns (nil, badger.ErrKeyNotFound).
func (*D) GetSerialsByIds ¶ added in v0.4.9
GetSerialsByIds takes a tag.T containing multiple IDs and returns a map of IDs to their corresponding serial numbers. It directly queries the IdPrefix index for matching IDs, which is more efficient than using GetIndexesFromFilter.
func (*D) GetSerialsByIdsWithFilter ¶ added in v0.4.9
func (d *D) GetSerialsByIdsWithFilter( ids *tag.T, fn func(ev *event.E, ser *types.Uint40) bool, ) (serials map[string]*types.Uint40, err error)
GetSerialsByIdsWithFilter takes a tag.T containing multiple IDs and returns a map of IDs to their corresponding serial numbers, applying a filter function to each event. The function directly creates ID index prefixes for efficient querying.
func (*D) GetSerialsByRange ¶
func (*D) GetSerialsFromFilter ¶
func (*D) GetSubscription ¶
func (d *D) GetSubscription(pubkey []byte) (*Subscription, error)
func (*D) HasMarker ¶ added in v0.6.0
HasMarker checks if a marker exists in the database
func (*D) Import ¶
Import a collection of events in line structured minified JSON format (JSONL).
func (*D) ImportEventsFromReader ¶ added in v0.24.0
ImportEventsFromReader imports events from an io.Reader containing JSONL data
func (*D) ImportEventsFromStrings ¶ added in v0.24.0
func (d *D) 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 a slice of JSON strings with policy filtering
func (*D) Init ¶
Init initializes the database with the given path.
func (*D) InvalidateQueryCache ¶ added in v0.29.1
func (d *D) InvalidateQueryCache()
InvalidateQueryCache clears all entries from the query cache
func (*D) IsFirstTimeUser ¶ added in v0.8.0
IsFirstTimeUser checks if a user is logging in for the first time and marks them as seen
func (*D) IsNIP43Member ¶ added in v0.27.0
IsNIP43Member checks if a pubkey is a NIP-43 member
func (*D) Path ¶
Path returns the path where the database files are stored.
func (*D) PublishNIP43MembershipEvent ¶ added in v0.27.0
PublishNIP43MembershipEvent publishes membership change events
func (*D) QueryAllVersions ¶ added in v0.17.4
QueryAllVersions queries events and returns all versions of replaceable events
func (*D) QueryCacheStats ¶ added in v0.29.1
func (d *D) QueryCacheStats() querycache.CacheStats
QueryCacheStats returns statistics about the query cache
func (*D) QueryDeleteEventsByTargetId ¶ added in v0.14.0
func (d *D) QueryDeleteEventsByTargetId(c context.Context, targetEventId []byte) ( evs event.S, err error, )
QueryDeleteEventsByTargetId queries for delete events that target a specific event ID
func (*D) QueryEvents ¶
func (*D) QueryEventsWithOptions ¶ added in v0.14.0
func (*D) QueryForIds ¶
QueryForIds retrieves a list of IdPkTs based on the provided filter. It supports filtering by ranges and tags but disallows filtering by Ids. Results are sorted by timestamp in reverse chronological order by default. When a search query is present, results are ranked by a 50/50 blend of match count (how many distinct search terms matched) and recency. Returns an error if the filter contains Ids or if any operation fails.
func (*D) QueryForSerials ¶
QueryForSerials takes a filter and returns the serials of events that match, sorted in reverse chronological order.
func (*D) QueryPTagGraph ¶ added in v0.29.11
QueryPTagGraph uses the pubkey graph index for efficient p-tag queries.
This query path is optimized for filters like:
{"#p": ["<pubkey>"], "kinds": [1, 6, 7]}
Performance benefits: - 41% smaller index keys (16 bytes vs 27 bytes) - No hash collisions (exact serial match) - Kind-indexed in key structure - Direction-aware filtering
func (*D) Ready ¶ added in v0.29.1
func (d *D) Ready() <-chan struct{}
Ready returns a channel that closes when the database is ready to serve requests. This allows callers to wait for database warmup to complete.
func (*D) RecordPayment ¶
func (*D) ReencodeEventsWithOptimizedTags ¶ added in v0.29.15
func (d *D) ReencodeEventsWithOptimizedTags()
ReencodeEventsWithOptimizedTags re-encodes all events to use the new binary tag format that stores e/p tag values as 33-byte binary (32-byte hash + null) instead of 64-byte hex strings. This reduces memory usage by ~48% for these tags.
func (*D) RemoveNIP43Member ¶ added in v0.27.0
RemoveNIP43Member removes a member from the NIP-43 membership list
func (*D) SaveEvent ¶
SaveEvent saves an event to the database, generating all the necessary indexes.
func (*D) SetMarker ¶ added in v0.6.0
SetMarker stores an arbitrary marker in the database
func (*D) SetRelayIdentitySecret ¶ added in v0.8.0
SetRelayIdentitySecret stores the relay identity secret key bytes (expects 32 bytes).
func (*D) StoreInviteCode ¶ added in v0.27.0
StoreInviteCode stores an invite code with expiry
func (*D) ValidateInviteCode ¶ added in v0.27.0
ValidateInviteCode checks if an invite code is valid and not expired
func (*D) WouldReplaceEvent ¶ added in v0.10.5
WouldReplaceEvent checks if the provided event would replace existing events based on Nostr's replaceable or parameterized replaceable semantics. It returns true if the candidate is newer-or-equal than existing events. If an existing event is newer, it returns (false, nil, ErrOlderThanExisting). If no conflicts exist, it returns (false, nil, nil).
type Database ¶ added in v0.29.1
type Database interface {
// Core lifecycle methods
Path() string
Init(path string) error
Sync() error
Close() error
Wipe() error
SetLogLevel(level string)
Ready() <-chan struct{} // Returns a channel that closes when database is ready to serve requests
// Event storage and retrieval
SaveEvent(c context.Context, ev *event.E) (exists bool, err error)
GetSerialsFromFilter(f *filter.F) (serials types.Uint40s, err error)
WouldReplaceEvent(ev *event.E) (bool, types.Uint40s, error)
QueryEvents(c context.Context, f *filter.F) (evs event.S, err error)
QueryAllVersions(c context.Context, f *filter.F) (evs event.S, err error)
QueryEventsWithOptions(c context.Context, f *filter.F, includeDeleteEvents bool, showAllVersions bool) (evs event.S, err error)
QueryDeleteEventsByTargetId(c context.Context, targetEventId []byte) (evs event.S, err error)
QueryForSerials(c context.Context, f *filter.F) (serials types.Uint40s, err error)
QueryForIds(c context.Context, f *filter.F) (idPkTs []*store.IdPkTs, err error)
CountEvents(c context.Context, f *filter.F) (count int, approximate bool, err error)
FetchEventBySerial(ser *types.Uint40) (ev *event.E, err error)
FetchEventsBySerials(serials []*types.Uint40) (events map[uint64]*event.E, err error)
GetSerialById(id []byte) (ser *types.Uint40, err error)
GetSerialsByIds(ids *tag.T) (serials map[string]*types.Uint40, err error)
GetSerialsByIdsWithFilter(ids *tag.T, fn func(ev *event.E, ser *types.Uint40) bool) (serials map[string]*types.Uint40, err error)
GetSerialsByRange(idx Range) (serials types.Uint40s, err error)
GetFullIdPubkeyBySerial(ser *types.Uint40) (fidpk *store.IdPkTs, err error)
GetFullIdPubkeyBySerials(sers []*types.Uint40) (fidpks []*store.IdPkTs, err error)
// Event deletion
DeleteEvent(c context.Context, eid []byte) error
DeleteEventBySerial(c context.Context, ser *types.Uint40, ev *event.E) error
DeleteExpired()
ProcessDelete(ev *event.E, admins [][]byte) error
CheckForDeleted(ev *event.E, admins [][]byte) error
// Import/Export
Import(rr io.Reader)
Export(c context.Context, w io.Writer, pubkeys ...[]byte)
ImportEventsFromReader(ctx context.Context, rr io.Reader) error
ImportEventsFromStrings(ctx context.Context, eventJSONs []string, policyManager interface {
CheckPolicy(action string, ev *event.E, pubkey []byte, remote string) (bool, error)
}) error
// Relay identity
GetRelayIdentitySecret() (skb []byte, err error)
SetRelayIdentitySecret(skb []byte) error
GetOrCreateRelayIdentitySecret() (skb []byte, err error)
// Markers (metadata key-value storage)
SetMarker(key string, value []byte) error
GetMarker(key string) (value []byte, err error)
HasMarker(key string) bool
DeleteMarker(key string) error
// Subscriptions (payment-based access control)
GetSubscription(pubkey []byte) (*Subscription, error)
IsSubscriptionActive(pubkey []byte) (bool, error)
ExtendSubscription(pubkey []byte, days int) error
RecordPayment(pubkey []byte, amount int64, invoice, preimage string) error
GetPaymentHistory(pubkey []byte) ([]Payment, error)
ExtendBlossomSubscription(pubkey []byte, tier string, storageMB int64, daysExtended int) error
GetBlossomStorageQuota(pubkey []byte) (quotaMB int64, err error)
IsFirstTimeUser(pubkey []byte) (bool, error)
// NIP-43 Invite-based ACL
AddNIP43Member(pubkey []byte, inviteCode string) error
RemoveNIP43Member(pubkey []byte) error
IsNIP43Member(pubkey []byte) (isMember bool, err error)
GetNIP43Membership(pubkey []byte) (*NIP43Membership, error)
GetAllNIP43Members() ([][]byte, error)
StoreInviteCode(code string, expiresAt time.Time) error
ValidateInviteCode(code string) (valid bool, err error)
DeleteInviteCode(code string) error
PublishNIP43MembershipEvent(kind int, pubkey []byte) error
// Migrations (version tracking for schema updates)
RunMigrations()
// Query cache methods
GetCachedJSON(f *filter.F) ([][]byte, bool)
CacheMarshaledJSON(f *filter.F, marshaledJSON [][]byte)
GetCachedEvents(f *filter.F) (event.S, bool)
CacheEvents(f *filter.F, events event.S)
InvalidateQueryCache()
// Utility methods
EventIdsBySerial(start uint64, count int) (evs []uint64, err error)
}
Database defines the interface that all database implementations must satisfy. This allows switching between different storage backends (badger, dgraph, etc.)
func NewDatabase ¶ added in v0.29.1
func NewDatabase( ctx context.Context, cancel context.CancelFunc, dbType string, dataDir string, logLevel string, ) (Database, error)
NewDatabase creates a database instance based on the specified type. Supported types: "badger", "dgraph", "neo4j"
func NewDatabaseWithConfig ¶ added in v0.31.8
func NewDatabaseWithConfig( ctx context.Context, cancel context.CancelFunc, dbType string, cfg *DatabaseConfig, ) (Database, error)
NewDatabaseWithConfig creates a database instance with full configuration. This is the preferred method when you have access to the app config.
type DatabaseConfig ¶ added in v0.31.8
type DatabaseConfig struct {
// Common settings for all backends
DataDir string
LogLevel string
// Badger-specific settings
BlockCacheMB int // ORLY_DB_BLOCK_CACHE_MB
IndexCacheMB int // ORLY_DB_INDEX_CACHE_MB
QueryCacheSizeMB int // ORLY_QUERY_CACHE_SIZE_MB
QueryCacheMaxAge time.Duration // ORLY_QUERY_CACHE_MAX_AGE
InlineEventThreshold int // ORLY_INLINE_EVENT_THRESHOLD
// DGraph-specific settings
DgraphURL string // ORLY_DGRAPH_URL
// Neo4j-specific settings
Neo4jURI string // ORLY_NEO4J_URI
Neo4jUser string // ORLY_NEO4J_USER
Neo4jPassword string // ORLY_NEO4J_PASSWORD
}
DatabaseConfig holds all database configuration options that can be passed to any database backend. Each backend uses the relevant fields for its type. This centralizes configuration instead of having each backend read env vars directly.
type EventNeedingModeration ¶ added in v0.17.0
type EventNeedingModeration struct {
ID string `json:"id"`
Reason string `json:"reason,omitempty"`
Added time.Time `json:"added"`
}
EventNeedingModeration represents an event that needs moderation
type ManagedACL ¶ added in v0.17.0
type ManagedACL struct {
*D
}
ManagedACL database operations
func NewManagedACL ¶ added in v0.17.0
func NewManagedACL(db *D) *ManagedACL
NewManagedACL creates a new ManagedACL instance
func (*ManagedACL) GetRelayConfig ¶ added in v0.17.0
func (m *ManagedACL) GetRelayConfig() (ManagedACLConfig, error)
GetRelayConfig returns relay configuration
func (*ManagedACL) IsEventAllowed ¶ added in v0.17.0
func (m *ManagedACL) IsEventAllowed(eventID string) (bool, error)
Check if an event is explicitly allowed
func (*ManagedACL) IsEventBanned ¶ added in v0.17.0
func (m *ManagedACL) IsEventBanned(eventID string) (bool, error)
Check if an event is banned
func (*ManagedACL) IsIPBlocked ¶ added in v0.17.0
func (m *ManagedACL) IsIPBlocked(ip string) (bool, error)
Check if an IP is blocked
func (*ManagedACL) IsKindAllowed ¶ added in v0.17.0
func (m *ManagedACL) IsKindAllowed(kind int) (bool, error)
Check if a kind is allowed
func (*ManagedACL) IsPubkeyAllowed ¶ added in v0.17.0
func (m *ManagedACL) IsPubkeyAllowed(pubkey string) (bool, error)
Check if a pubkey is explicitly allowed
func (*ManagedACL) IsPubkeyBanned ¶ added in v0.17.0
func (m *ManagedACL) IsPubkeyBanned(pubkey string) (bool, error)
Check if a pubkey is banned
func (*ManagedACL) ListAllowedEvents ¶ added in v0.17.0
func (m *ManagedACL) ListAllowedEvents() ([]AllowedEvent, error)
ListAllowedEvents returns all allowed events
func (*ManagedACL) ListAllowedKinds ¶ added in v0.17.0
func (m *ManagedACL) ListAllowedKinds() ([]int, error)
ListAllowedKinds returns all allowed kinds
func (*ManagedACL) ListAllowedPubkeys ¶ added in v0.17.0
func (m *ManagedACL) ListAllowedPubkeys() ([]AllowedPubkey, error)
ListAllowedPubkeys returns all allowed pubkeys
func (*ManagedACL) ListBannedEvents ¶ added in v0.17.0
func (m *ManagedACL) ListBannedEvents() ([]BannedEvent, error)
ListBannedEvents returns all banned events
func (*ManagedACL) ListBannedPubkeys ¶ added in v0.17.0
func (m *ManagedACL) ListBannedPubkeys() ([]BannedPubkey, error)
ListBannedPubkeys returns all banned pubkeys
func (*ManagedACL) ListBlockedIPs ¶ added in v0.17.0
func (m *ManagedACL) ListBlockedIPs() ([]BlockedIP, error)
ListBlockedIPs returns all blocked IPs
func (*ManagedACL) ListEventsNeedingModeration ¶ added in v0.17.0
func (m *ManagedACL) ListEventsNeedingModeration() ([]EventNeedingModeration, error)
ListEventsNeedingModeration returns all events needing moderation
func (*ManagedACL) RemoveAllowedEvent ¶ added in v0.17.0
func (m *ManagedACL) RemoveAllowedEvent(eventID string) error
RemoveAllowedEvent removes an allowed event from the database
func (*ManagedACL) RemoveAllowedKind ¶ added in v0.17.0
func (m *ManagedACL) RemoveAllowedKind(kind int) error
RemoveAllowedKind removes an allowed kind from the database
func (*ManagedACL) RemoveAllowedPubkey ¶ added in v0.17.0
func (m *ManagedACL) RemoveAllowedPubkey(pubkey string) error
RemoveAllowedPubkey removes an allowed pubkey from the database
func (*ManagedACL) RemoveBannedEvent ¶ added in v0.17.0
func (m *ManagedACL) RemoveBannedEvent(eventID string) error
RemoveBannedEvent removes a banned event from the database
func (*ManagedACL) RemoveBannedPubkey ¶ added in v0.17.0
func (m *ManagedACL) RemoveBannedPubkey(pubkey string) error
RemoveBannedPubkey removes a banned pubkey from the database
func (*ManagedACL) RemoveBlockedIP ¶ added in v0.17.0
func (m *ManagedACL) RemoveBlockedIP(ip string) error
RemoveBlockedIP removes a blocked IP from the database
func (*ManagedACL) RemoveEventNeedingModeration ¶ added in v0.17.0
func (m *ManagedACL) RemoveEventNeedingModeration(eventID string) error
RemoveEventNeedingModeration removes an event from moderation queue
func (*ManagedACL) SaveAllowedEvent ¶ added in v0.17.0
func (m *ManagedACL) SaveAllowedEvent(eventID string, reason string) error
SaveAllowedEvent saves an allowed event to the database
func (*ManagedACL) SaveAllowedKind ¶ added in v0.17.0
func (m *ManagedACL) SaveAllowedKind(kind int) error
SaveAllowedKind saves an allowed kind to the database
func (*ManagedACL) SaveAllowedPubkey ¶ added in v0.17.0
func (m *ManagedACL) SaveAllowedPubkey(pubkey string, reason string) error
SaveAllowedPubkey saves an allowed pubkey to the database
func (*ManagedACL) SaveBannedEvent ¶ added in v0.17.0
func (m *ManagedACL) SaveBannedEvent(eventID string, reason string) error
SaveBannedEvent saves a banned event to the database
func (*ManagedACL) SaveBannedPubkey ¶ added in v0.17.0
func (m *ManagedACL) SaveBannedPubkey(pubkey string, reason string) error
SaveBannedPubkey saves a banned pubkey to the database
func (*ManagedACL) SaveBlockedIP ¶ added in v0.17.0
func (m *ManagedACL) SaveBlockedIP(ip string, reason string) error
SaveBlockedIP saves a blocked IP to the database
func (*ManagedACL) SaveEventNeedingModeration ¶ added in v0.17.0
func (m *ManagedACL) SaveEventNeedingModeration(eventID string, reason string) error
SaveEventNeedingModeration saves an event that needs moderation
func (*ManagedACL) SaveRelayConfig ¶ added in v0.17.0
func (m *ManagedACL) SaveRelayConfig(config ManagedACLConfig) error
SaveRelayConfig saves relay configuration
type ManagedACLConfig ¶ added in v0.17.0
type ManagedACLConfig struct {
RelayName string `json:"relay_name"`
RelayDescription string `json:"relay_description"`
RelayIcon string `json:"relay_icon"`
}
ManagedACLConfig represents the configuration for managed ACL mode
type NIP43Membership ¶ added in v0.27.0
NIP43Membership represents membership metadata for NIP-43
type Payment ¶
type Payment struct {
Amount int64 `json:"amount"`
Timestamp time.Time `json:"timestamp"`
Invoice string `json:"invoice"`
Preimage string `json:"preimage"`
}
Payment represents a recorded payment
type Range ¶
type Range struct {
Start, End []byte
}
func GetIndexesFromFilter ¶
GetIndexesFromFilter returns encoded indexes based on the given filter.
An error is returned if any input values are invalid during encoding.
The indexes are designed so that only one table needs to be iterated, being a complete set of combinations of all fields in the event, thus there is no need to decode events until they are to be delivered.
type Subscription ¶
type Subscription struct {
TrialEnd time.Time `json:"trial_end"`
PaidUntil time.Time `json:"paid_until"`
BlossomLevel string `json:"blossom_level,omitempty"` // Service level name (e.g., "basic", "premium")
BlossomStorage int64 `json:"blossom_storage,omitempty"` // Storage quota in MB
}
Subscription represents a user's subscription status
Source Files
¶
- cleanup-kind3.go
- count.go
- database.go
- delete-event.go
- delete-expired.go
- export.go
- factory.go
- fetch-event-by-serial.go
- fetch-events-by-serials.go
- filter_utils.go
- get-fullidpubkey-by-serial.go
- get-fullidpubkey-by-serials.go
- get-indexes-for-event.go
- get-indexes-from-filter.go
- get-serial-by-id.go
- get-serials-by-range.go
- identity.go
- import.go
- import_utils.go
- interface.go
- logger.go
- managed-acl.go
- markers.go
- migrations.go
- nip43.go
- process-delete.go
- pubkey-serial.go
- query-events.go
- query-for-deleted.go
- query-for-ids.go
- query-for-ptag-graph.go
- query-for-serials.go
- save-event.go
- subscriptions.go
- tokenize.go
- types.go