10 KiB
ORLY Relay Domain Glossary
This glossary defines the ubiquitous language used throughout the ORLY codebase. All contributors should use these terms consistently in code, comments, and documentation.
Core Domain Concepts
Event
A Nostr event as defined in NIP-01. The fundamental unit of data in the Nostr protocol. Contains: id, pubkey, created_at, kind, tags, content, sig.
- Code location:
git.mleku.dev/mleku/nostr/encoders/event - Key type:
event.E
Serial
A monotonically increasing 40-bit identifier assigned to each event upon storage. Used for efficient range queries, synchronization, and garbage collection ordering.
- Code location:
pkg/database/indexes/types.Uint40 - Related types: EventRef, IdPkTs
Pubkey
A 32-byte secp256k1 public key identifying a Nostr user. Stored as binary internally, displayed as 64-character lowercase hex or bech32 npub format externally.
- Code location:
git.mleku.dev/mleku/nostr/types.Pubkey
Access Level
The permission tier granted to a pubkey. Determines what operations are allowed.
| Level | Description |
|---|---|
none |
No access, authentication required |
read |
Read-only access (REQ allowed, EVENT denied) |
write |
Read and write access |
admin |
Write + import/export + arbitrary delete |
owner |
Admin + wipe + system configuration |
blocked |
IP address blocked |
banned |
Pubkey banned |
- Code location:
pkg/interfaces/acl/acl.goconstants
ACL (Access Control List)
The authorization system that determines access levels for pubkeys and IP addresses. Supports multiple modes with different authorization strategies.
- Code location:
pkg/acl/ - Interface:
pkg/interfaces/acl/acl.go
Event Processing Pipeline
The event processing pipeline transforms incoming WebSocket messages into stored events. Each stage has distinct responsibilities and produces typed results.
Raw JSON → Validation → Authorization → Routing → Processing → Delivery
Validation
The process of verifying event structure, signature, and protocol compliance.
Checks performed:
-
Raw JSON validation (hex case normalization)
-
Event ID verification (hash matches content)
-
Signature verification (schnorr signature valid)
-
Timestamp validation (not too far in future)
-
NIP-70 protected tag validation
-
Code location:
pkg/event/validation/ -
Result type:
validation.ResultwithValid,Code,Msg
Authorization
The decision process determining if an event is allowed based on ACL and policy. Returns a structured decision with access level and deny reason.
- Code location:
pkg/event/authorization/ - Result type:
authorization.DecisionwithAllowed,AccessLevel,DenyReason,RequireAuth
Routing
Dispatching events to specialized handlers based on event kind. Determines whether events should be processed normally, delivered ephemerally, or handled specially.
Examples:
-
Ephemeral events (kinds 20000-29999): Deliver without storage
-
Delete events (kind 5): Trigger deletion cascade
-
NIP-43 events (kinds 28934, 28936): Membership requests
-
Code location:
pkg/event/routing/ -
Result type:
routing.ResultwithAction,Error
Processing
The final stage: persisting events, running post-save hooks, and delivering to subscribers. Handles deduplication, replaceable event logic, and event delivery.
- Code location:
pkg/event/processing/ - Result type:
processing.ResultwithSaved,Duplicate,Blocked,Error
ACL Modes
None Mode
Open relay - all pubkeys have write access by default.
No authentication required unless explicitly configured via ORLY_AUTH_REQUIRED.
- Code location:
pkg/acl/none.go
Follows Mode
Whitelist based on admin/owner follow lists (kind 3 events). Followed pubkeys get write access; others get read-only or denied based on configuration. Supports progressive throttling for non-followed users.
- Code location:
pkg/acl/follows.go - Config:
ORLY_ACL_MODE=follows
Managed Mode
Fine-grained control via NIP-86 management API. Supports pubkey bans, event bans, IP blocks, kind restrictions, and custom rules. All management operations require NIP-98 HTTP authentication.
- Code location:
pkg/acl/managed.go - Config:
ORLY_ACL_MODE=managed
Curating Mode
Curator-based content moderation system. Curators can approve/reject events from non-followed users. Events from non-curated users are held pending approval.
- Code location:
pkg/acl/curating.go - Config:
ORLY_ACL_MODE=curating
Protocol Concepts
NIP-42 Authentication
Challenge-response authentication for WebSocket connections. Used to verify pubkey ownership before granting elevated access.
Flow:
- Relay sends AUTH challenge with random string
- Client signs challenge with private key
- Relay verifies signature and grants access level
- Code location:
pkg/protocol/auth/
NIP-70 Protected Events
Events with - (protected) tag that can only be replaced/deleted by the author.
Prevents relays from accepting replacements from unauthorized pubkeys.
- Tag format:
["-"]in tags array
NIP-43 Relay Access
Invite-based membership system for restricted relays. Supports join requests, leave requests, and membership tracking.
| Kind | Purpose |
|---|---|
| 28934 | Join request with invite code |
| 28936 | Leave request |
| 8000 | Member added (relay-published) |
- Code location:
pkg/protocol/nip43/
NIP-86 Relay Management
HTTP JSON-RPC API for relay administration. Requires NIP-98 HTTP authentication with admin/owner access level.
- Endpoint:
/api/v1/management - Code location:
app/handle-nip86.go
NIP-77 Negentropy
Set reconciliation protocol for efficient relay-to-relay synchronization. Uses negentropy algorithm to identify missing events with minimal bandwidth.
- Code location:
pkg/sync/negentropy/ - Envelope types: NEG-OPEN, NEG-MSG, NEG-CLOSE, NEG-ERR
Infrastructure Concepts
Publisher
The event delivery system that sends events to subscribers. Composed of multiple publisher implementations (socket, internal, etc.).
- Code location:
pkg/protocol/publish/ - Interface:
pkg/interfaces/publisher/publisher.go
Sprocket
External event processing plugin (JavaScript/Rhai script). Can accept, reject, or shadow-reject events before normal processing.
| Action | Effect |
|---|---|
| accept | Event proceeds to normal processing |
| reject | Event rejected with error message |
| shadowReject | Event appears accepted but is not stored |
- Code location:
app/sprocket.go
Policy Manager
Rule-based event filtering system configured via JSON or kind 30078 events. Evaluates events against configurable rules for allow/deny decisions.
- Code location:
pkg/policy/ - Config file:
~/.config/orly/policy.json
Rate Limiter
PID controller-based adaptive throttling system. Adjusts delays based on system load (memory pressure, write throughput).
- Code location:
pkg/ratelimit/ - Interface:
pkg/interfaces/loadmonitor/
Supervisor
Process lifecycle manager for split IPC mode deployment. Manages database, ACL, sync, and relay processes with dependency ordering.
- Code location:
cmd/orly-launcher/supervisor.go
Data Types
EventRef
Stack-allocated event reference with fixed-size ID and pubkey arrays. 80 bytes total, fits in cache line, safe for concurrent use. Immutable - all fields are unexported with accessor methods.
type EventRef struct {
id ntypes.EventID // 32 bytes
pub ntypes.Pubkey // 32 bytes
ts int64 // 8 bytes
ser uint64 // 8 bytes
}
- Code location:
pkg/interfaces/store/store_interface.go
IdPkTs
Event reference with slice-based fields for backward compatibility.
Mutable - use ToEventRef() for safe concurrent access.
type IdPkTs struct {
Id []byte // Event ID
Pub []byte // Pubkey
Ts int64 // Timestamp
Ser uint64 // Serial number
}
- Code location:
pkg/interfaces/store/store_interface.go
Decision
Authorization result carrying allowed status, access level, and context. Used to communicate authorization outcomes through the pipeline.
- Code location:
pkg/event/authorization/authorization.go
Result (Validation)
Validation outcome with Valid bool, ReasonCode enum, and message string. Codes: ReasonNone, ReasonBlocked, ReasonInvalid, ReasonError.
- Code location:
pkg/event/validation/validation.go
Result (Processing)
Processing outcome indicating whether event was saved, duplicate, or blocked. Includes error field for unexpected failures.
- Code location:
pkg/event/processing/processing.go
Subscription Terminology
Note: "Subscription" has two distinct meanings in the codebase:
Event Subscription (REQ)
An active filter receiving matching events in real-time.
Created via REQ envelope, cancelled via CLOSE envelope.
Stored in Listener.subscriptions map with cancel function.
- Code location:
app/listener.gosubscriptions field
Payment Subscription
Paid access tier granting elevated permissions for a time period. Managed via NWC payments or manual extension.
- Code location:
pkg/database/interface.goSubscription type
Sync Terminology
Spider
Event aggregator that fetches events from external relays. Subscribes to events for followed pubkeys on configured relay lists.
- Code location:
pkg/spider/
Sync
Peer-to-peer replication between relay instances. Multiple implementations: negentropy, cluster, distributed, relaygroup.
- Code location:
pkg/sync/
Cluster
Group of relay instances sharing events via HTTP-based pull replication. Membership tracked via kind 39108 events.
- Code location:
pkg/sync/cluster/
Relay Group
Configuration of relay sets for synchronized operation. Tracked via kind 39105 events.
- Code location:
pkg/sync/relaygroup/
Driver Pattern
Driver
A pluggable implementation of a core interface. Selected at runtime via configuration or command-line flags.
Examples:
- Database drivers: badger, neo4j, wasmdb, grpc
- ACL drivers: none, follows, managed, curating
- Sync drivers: negentropy, cluster, distributed, relaygroup
// Check if driver is available
database.HasDriver("badger")
// Create instance from driver
db := database.NewFromDriver("badger", config)
- Pattern location:
pkg/database/,pkg/acl/,pkg/sync/
Last updated: 2026-01-24 Based on ORLY codebase v0.56.4