GRAIN is a comprehensive Nostr solution that serves primarily as a powerful relay for operators who need fine-grained control, while also providing a complete Go client library for developers building Nostr applications.
Nostr is a simple, open protocol for creating censorship-resistant social networks. Users publish signed events (posts, profiles, reactions) to relays, which store and distribute them. Unlike centralized platforms, users control their identity through cryptographic keys and can freely move between relays.
GRAIN acts as one of these relays - storing events, serving them to clients, and ensuring your relay operates according to your policies. It also provides the building blocks for creating your own Nostr clients.
- Real-time blacklist/whitelist filtering with automatic caching
- Word-based content filtering that escalates temporary bans to permanent ones
- Import blacklists from Nostr mute lists (kind 10000 events)
- Domain-based whitelisting by fetching pubkeys from
.well-known/nostr.json
- Hot configuration reloading - change settings without restarting
- Comprehensive structured logging with automatic rotation
- Memory-aware connection management prevents resource exhaustion
- Multi-layer rate limiting (connections, events, queries) with per-kind controls
- Supports all Nostr event categories: regular, replaceable, addressable, ephemeral & deletion events
- Automatic event deletion handling (kind 5 events) with proper cascade cleanup
- Intelligent event purging with category-based retention policies
- MongoDB storage optimized for Nostr's event structure
- Unified cross-collection database queries for efficient event retrieval
- Per-kind MongoDB collections with automatic indexing
- Configurable event size limits to prevent abuse
- Connection pooling and timeout management
GRAIN now includes a full-featured Nostr client library that developers can use to build their own applications:
- Connection pooling with automatic relay management
- Event publishing with multi-relay broadcasting and result aggregation
- Subscription management with filter support and relay hints
- Event signing with private key support and extensible signer interface
- Session management with user authentication and session persistence
- Structured logging integration matching relay standards
- Error handling with proper context and type safety
- Concurrent operations with proper synchronization
- Memory management with buffered channels and cleanup routines
- Standard library first - minimal dependencies
- Clear documentation with examples and best practices
- Go modules support for easy integration
- Consistent API following Go conventions
GRAIN includes a modern web interface that serves as both a relay dashboard and reference client implementation:
- Real-time monitoring of relay status, connections, and event flow
- Configuration management with hot-reload support for all settings
- User management with whitelist/blacklist administration
- Visual analytics showing relay performance and usage patterns
The web interface showcases the client library capabilities with:
- User authentication supporting multiple signing methods
- Event publishing with multi-relay support and status tracking
- Profile management with metadata caching and display
- Session handling demonstrating secure user flows
This reference implementation serves as both a functional interface and documentation for developers using the client library.
- RESTful APIs for client integration and relay management
- NIP-11 compliance for relay discovery and metadata
- Progressive Web App features for mobile-friendly usage
Development Relay: wss://wheat.happytavern.co
π View Detailed Status & Historical Data
My development relay wheat.happytavern.co serves as the testing and demo environment for Grain. This relay helps me validate new features, test performance optimizations, and provide a platform for developers to experiment with grain. This relay routinely runs unreleased versions of grain and may contain bugs.
Wheat is a public nostr relay that anyone can write to and read from. Wheat will delete events from non whitelisted users periodically. You can add your npub to the whitelist by paying for a Happy Tavern NIP05.
Status monitoring powered by Upptime
-
Download the latest release for your system from the releases page
-
Extract the archive and ensure both the binary and
www
folder are in the same directory:grain/ βββ grain (or grain.exe on Windows) βββ www/
-
Install MongoDB for your system:
-
Run GRAIN -
./grain
(Linux) orgrain.exe
(Windows)
GRAIN will automatically create default configuration files on first run and start serving on port :8181
.
Docker Installation
Docker Setup Guide (includes MongoDB)
Build from Source
- Requirements:
Go 1.21+ + MongoDB
Complete Installation Guide
- Full Installation Documentation - includes system service setup for Linux (systemd) and Windows (NSSM)
Note: Docker installations include MongoDB automatically. For other methods, you'll need to install MongoDB separately.
GRAIN uses four main configuration files with hot-reload support:
config.yml
- Server, database, and rate limiting settingswhitelist.yml
- Allowed users, domains, and event typesblacklist.yml
- Banned content and escalation policiesrelay_metadata.json
- Public relay information (NIP-11)
Configuration files are automatically created from embedded examples on first run. Changes to any configuration file are detected and applied automatically without requiring a restart.
π For detailed configuration options and examples, see Configuration Documentation
GRAIN can be imported as a Go module for building Nostr clients:
package main
import (
"fmt"
"github.com/0ceanslim/grain/client/core"
nostr "github.com/0ceanslim/grain/server/types"
)
func main() {
// Create client with default configuration
client := core.NewClient(nil)
// Connect to relays
relays := []string{"wss://relay.damus.io", "wss://nos.lol"}
if err := client.ConnectToRelays(relays); err != nil {
panic(err)
}
// Create and sign an event
signer, _ := core.NewEventSigner("your-private-key-hex")
event := signer.CreateEvent(1, "Hello Nostr!", nil)
// Broadcast to all connected relays
results := client.BroadcastEvent(event, nil)
fmt.Printf("Broadcast results: %+v\n", results)
// Subscribe to events
filters := []nostr.Filter{{Kinds: []int{1}, Limit: 10}}
sub, _ := client.Subscribe(filters, nil)
// Handle incoming events
go func() {
for event := range sub.Events {
fmt.Printf("Received event: %s\n", event.Content)
}
}()
}
Note: A comprehensive Client Library Guide with complete examples and documentation will be available soon after all client methods are fully implemented.
This project is Open Source and licensed under the MIT License. See the LICENSE file for details.
I welcome contributions, bug reports, and feature requests via GitHub.
Repository: https://github.com/0ceanslim/grain
Issues: https://github.com/0ceanslim/grain/issues
- π§ Development Guide - Development Documentation
- π§ͺ Testing Guide - Testing Documentation
- π API Documentation - API Documentation
These guides cover setting up your development environment, code standards, testing procedures, client library usage, and contribution workflows.
made with π¦ by OceanSlim
Reliable infrastructure for the decentralized web.