You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
mleku 6e4f24329e
fix silent fail of loading policy with panic, and bogus fallback logic
2 months ago
.aiassistant/rules Refactor export functionality in App.svelte to support both GET and POST methods for event exports, enhancing flexibility in user permissions. Update server-side handling to accommodate pubkey filtering and improve response handling for file downloads. Adjust UI components to reflect these changes, ensuring a seamless user experience. 3 months ago
.claude fix silent fail of loading policy with panic, and bogus fallback logic 2 months ago
.gitea fix workflow setup 2 months ago
.idea migrate to new nostr library 2 months ago
app blossom works fully correctly 2 months ago
cmd blossom works fully correctly 2 months ago
contrib/stella enhance spider with rate limit handling, follow list updates, and improved reconnect logic; bump version to v0.29.0 2 months ago
docs develop registration ratelimit mechanism 2 months ago
pkg fix silent fail of loading policy with panic, and bogus fallback logic 2 months ago
relay-tester migrate to new nostr library 2 months ago
scripts unignore files that should be there 2 months ago
.dockerignore optimizing badger cache, won a 10-15% improvement in most benchmarks 2 months ago
.gitignore unignore files that should be there 2 months ago
BADGER_MIGRATION_GUIDE.md optimizing badger cache, won a 10-15% improvement in most benchmarks 2 months ago
CLAUDE.md initial draft of neo4j database driver 2 months ago
DGRAPH_IMPLEMENTATION_STATUS.md optimizing badger cache, won a 10-15% improvement in most benchmarks 2 months ago
Dockerfile unignore files that should be there 2 months ago
Dockerfile.relay-tester unignore files that should be there 2 months ago
INDEX.md Add comprehensive documentation for CLAUDE and Nostr WebSocket skills 2 months ago
LICENSE Add initial project structure with README, LICENSE, and .gitignore config 5 months ago
MIGRATION_SUMMARY.md migrate to new nostr library 2 months ago
POLICY_BUG_FIX_SUMMARY.md fix silent fail of loading policy with panic, and bogus fallback logic 2 months ago
conversation.md fix policy to ignore all req/events without auth 2 months ago
enable-policy.sh fix silent fail of loading policy with panic, and bogus fallback logic 2 months ago
go.mod migrate to new nostr library 2 months ago
go.sum migrate to new nostr library 2 months ago
libsecp256k1.so fully test and verify policy script functionality 2 months ago
main.go migrate to new nostr library 2 months ago
policyfixes.md fix policy to ignore all req/events without auth 2 months ago
readme.adoc Add cluster replication configuration and enhance event handling 2 months ago

readme.adoc

go= next.orly.dev
:toc:
:note-caption: note 👉

image:./docs/orly.png[orly.dev]

image:https://img.shields.io/badge/version-v0.24.1-blue.svg[Version v0.24.1]
image:https://img.shields.io/badge/godoc-documentation-blue.svg[Documentation,link=https://pkg.go.dev/next.orly.dev]
image:https://img.shields.io/badge/donate-geyser_crowdfunding_project_page-orange.svg[Support this project,link=https://geyser.fund/project/orly]
zap me: ⚡<span class="escaped-code-point" data-escaped="[U+FE0F]"><span class="char">️</span></span>mlekudev@getalby.com
follow me on link:https://jumble.social/users/npub1fjqqy4a93z5zsjwsfxqhc2764kvykfdyttvldkkkdera8dr78vhsmmleku[nostr]

== about

ORLY is a nostr relay written from the ground up to be performant, low latency, and built with a number of features designed to make it well suited for

- personal relays
- small community relays
- business deployments and RaaS (Relay as a Service) with a nostr-native NWC client to allow accepting payments through NWC capable lightning nodes
- high availability clusters for reliability and/or providing a unified data set across multiple regions

== performance & cryptography

ORLY leverages high-performance libraries and custom optimizations for exceptional speed:

* **SIMD Libraries**: Uses link:https://github.com/minio/sha256-simd[minio/sha256-simd] for accelerated SHA256 hashing
* **p256k1 Cryptography**: Implements link:https://github.com/p256k1/p256k1[p256k1.mleku.dev] for fast elliptic curve operations optimized for nostr
* **Fast Message Encoders**: High-performance encoding/decoding with link:https://github.com/templexxx/xhex[templexxx/xhex] for SIMD-accelerated hex operations

The encoders achieve **24% faster JSON marshaling**, **16% faster canonical encoding**, and **54-91% reduction in memory allocations** through custom buffer pre-allocation and zero-allocation optimization techniques.

ORLY uses a fast embedded link:https://github.com/hypermodeinc/badger[badger] database with a database designed for high performance querying and event storage.

== building

ORLY is a standard Go application that can be built using the Go toolchain.

=== prerequisites

- Go 1.25.0 or later
- Git
- For web UI: link:https://bun.sh/[Bun] JavaScript runtime

=== basic build

To build the relay binary only:

[source,bash]
----
git clone <repository-url>
cd next.orly.dev
go build -o orly
----

=== building with web UI

To build with the embedded web interface:

[source,bash]
----
# Build the Svelte web application
cd app/web
bun install
bun run build

# Build the Go binary from project root
cd ../../
go build -o orly
----

The recommended way to build and embed the web UI is using the provided script:

[source,bash]
----
./scripts/update-embedded-web.sh
----

This script will:
- Build the Svelte app in `app/web` to `app/web/dist` using Bun (preferred) or fall back to npm/yarn/pnpm
- Run `go install` from the repository root so the binary picks up the new embedded assets
- Automatically detect and use the best available JavaScript package manager

For manual builds, you can also use:

[source,bash]
----
#!/bin/bash
# build.sh
echo "Building Svelte app..."
cd app/web
bun install
bun run build

echo "Building Go binary..."
cd ../../
go build -o orly

echo "Build complete!"
----

Make it executable with `chmod +x build.sh` and run with `./build.sh`.

== core features

=== web UI

ORLY includes a modern web-based user interface built with link:https://svelte.dev/[Svelte] for relay management and monitoring.

* **Secure Authentication**: Nostr key pair authentication with challenge-response
* **Event Management**: Browse, export, import, and search events
* **User Administration**: Role-based permissions (guest, user, admin, owner)
* **Sprocket Management**: Upload and monitor event processing scripts
* **Real-time Updates**: Live event streaming and system monitoring
* **Responsive Design**: Works on desktop and mobile devices
* **Dark/Light Themes**: Persistent theme preferences

The web UI is embedded in the relay binary and accessible at the relay's root path. For development with hot-reloading:

[source,bash]
----
export ORLY_WEB_DISABLE_EMBEDDED=true
export ORLY_WEB_DEV_PROXY_URL=localhost:5000
./orly &
cd app/web && bun run dev
----

=== sprocket event processing

ORLY includes a powerful sprocket system for external event processing scripts. Sprocket scripts enable custom filtering, validation, and processing logic for Nostr events before storage.

* **Real-time Processing**: Scripts receive events via stdin and respond with JSONL decisions
* **Three Actions**: `accept`, `reject`, or `shadowReject` events based on custom logic
* **Automatic Recovery**: Failed scripts are automatically disabled with periodic recovery attempts
* **Web UI Management**: Upload, configure, and monitor scripts through the admin interface

[source,bash]
----
export ORLY_SPROCKET_ENABLED=true
export ORLY_APP_NAME="ORLY"
# Place script at ~/.config/ORLY/sprocket.sh
----

For detailed configuration and examples, see the link:docs/sprocket/[sprocket documentation].

=== policy system

ORLY includes a comprehensive policy system for fine-grained control over event storage and retrieval. Configure custom validation rules, access controls, size limits, and age restrictions.

* **Access Control**: Allow/deny based on pubkeys, roles, or social relationships
* **Content Filtering**: Size limits, age validation, and custom rules
* **Script Integration**: Execute custom scripts for complex policy logic
* **Real-time Enforcement**: Policies applied to both read and write operations

[source,bash]
----
export ORLY_POLICY_ENABLED=true
# Create policy file at ~/.config/ORLY/policy.json
----

For detailed configuration and examples, see the link:docs/POLICY_USAGE_GUIDE.md[Policy Usage Guide].

== deployment

ORLY includes an automated deployment script that handles Go installation, dependency setup, building, and systemd service configuration.

=== automated deployment

The deployment script (`scripts/deploy.sh`) provides a complete setup solution:

[source,bash]
----
# Clone the repository
git clone <repository-url>
cd next.orly.dev

# Run the deployment script
./scripts/deploy.sh
----

The script will:

1. **Install Go 1.25.0** if not present (in `~/.local/go`)
2. **Configure environment** by creating `~/.goenv` and updating `~/.bashrc`
3. **Build the relay** with embedded web UI using `update-embedded-web.sh`
4. **Set capabilities** for port 443 binding (requires sudo)
5. **Install binary** to `~/.local/bin/orly`
6. **Create systemd service** and enable it

After deployment, reload your shell environment:

[source,bash]
----
source ~/.bashrc
----

=== TLS configuration

ORLY supports automatic TLS certificate management with Let's Encrypt and custom certificates:

[source,bash]
----
# Enable TLS with Let's Encrypt for specific domains
export ORLY_TLS_DOMAINS=relay.example.com,backup.relay.example.com

# Optional: Use custom certificates (will load .pem and .key files)
export ORLY_CERTS=/path/to/cert1,/path/to/cert2

# When TLS domains are configured, ORLY will:
# - Listen on port 443 for HTTPS/WSS
# - Listen on port 80 for ACME challenges
# - Ignore ORLY_PORT setting
----

Certificate files should be named with `.pem` and `.key` extensions:
- `/path/to/cert1.pem` (certificate)
- `/path/to/cert1.key` (private key)

=== systemd service management

The deployment script creates a systemd service for easy management:

[source,bash]
----
# Start the service
sudo systemctl start orly

# Stop the service
sudo systemctl stop orly

# Restart the service
sudo systemctl restart orly

# Enable service to start on boot
sudo systemctl enable orly --now

# Disable service from starting on boot
sudo systemctl disable orly --now

# Check service status
sudo systemctl status orly

# View service logs
sudo journalctl -u orly -f

# View recent logs
sudo journalctl -u orly --since "1 hour ago"
----

=== remote deployment

You can deploy ORLY on a remote server using SSH:

[source,bash]
----
# Deploy to a VPS with SSH key authentication
ssh user@your-server.com << 'EOF'
# Clone and deploy
git clone <repository-url>
cd next.orly.dev
./scripts/deploy.sh

# Configure your relay
echo 'export ORLY_TLS_DOMAINS=relay.example.com' >> ~/.bashrc
echo 'export ORLY_ADMINS=npub1your_admin_key_here' >> ~/.bashrc

# Start the service
sudo systemctl start orly --now
EOF

# Check deployment status
ssh user@your-server.com 'sudo systemctl status orly'
----

=== configuration

After deployment, configure your relay by setting environment variables in your shell profile:

[source,bash]
----
# Add to ~/.bashrc or ~/.profile
export ORLY_TLS_DOMAINS=relay.example.com
export ORLY_ADMINS=npub1your_admin_key
export ORLY_ACL_MODE=follows
export ORLY_APP_NAME="MyRelay"
----

Then restart the service:

[source,bash]
----
source ~/.bashrc
sudo systemctl restart orly
----

=== firewall configuration

Ensure your firewall allows the necessary ports:

[source,bash]
----
# For TLS-enabled relays
sudo ufw allow 80/tcp # HTTP (ACME challenges)
sudo ufw allow 443/tcp # HTTPS/WSS

# For non-TLS relays
sudo ufw allow 3334/tcp # Default ORLY port

# Enable firewall if not already enabled
sudo ufw enable
----

=== monitoring

Monitor your relay using systemd and standard Linux tools:

[source,bash]
----
# Service status and logs
sudo systemctl status orly
sudo journalctl -u orly -f

# Resource usage
htop
sudo ss -tulpn | grep orly

# Disk usage (database grows over time)
du -sh ~/.local/share/ORLY/

# Check TLS certificates (if using Let's Encrypt)
ls -la ~/.local/share/ORLY/autocert/
----

== testing

ORLY includes comprehensive testing tools for protocol validation and performance testing.

* **Protocol Testing**: Use `relay-tester` for Nostr protocol compliance validation
* **Stress Testing**: Performance testing under various load conditions
* **Benchmark Suite**: Comparative performance testing across relay implementations

For detailed testing instructions, multi-relay testing scenarios, and advanced usage, see the link:docs/RELAY_TESTING_GUIDE.md[Relay Testing Guide].

The benchmark suite provides comprehensive performance testing and comparison across multiple relay implementations, including throughput, latency, and memory usage metrics.

== access control

=== follows ACL

The follows ACL (Access Control List) system provides flexible relay access control based on social relationships in the Nostr network.

[source,bash]
----
export ORLY_ACL_MODE=follows
export ORLY_ADMINS=npub1fjqqy4a93z5zsjwsfxqhc2764kvykfdyttvldkkkdera8dr78vhsmmleku
./orly
----

The system grants write access to users followed by designated admins, with read-only access for others. Follow lists update dynamically as admins modify their relationships.

=== cluster replication

ORLY supports distributed relay clusters using active replication. When configured with peer relays, ORLY will automatically synchronize events between cluster members using efficient HTTP polling.

[source,bash]
----
export ORLY_RELAY_PEERS=https://peer1.example.com,https://peer2.example.com
export ORLY_CLUSTER_ADMINS=npub1cluster_admin_key
----

**Privacy Considerations:** By default, ORLY propagates all events including privileged events (DMs, gift wraps, etc.) to cluster peers for complete synchronization. This ensures no data loss but may expose private communications to other relay operators in your cluster.

To enhance privacy, you can disable propagation of privileged events:

[source,bash]
----
export ORLY_CLUSTER_PROPAGATE_PRIVILEGED_EVENTS=false
----

**Important:** When disabled, privileged events will not be replicated to peer relays. This provides better privacy but means these events will only be available on the originating relay. Users should be aware that accessing their privileged events may require connecting directly to the relay where they were originally published.