grain

command module
v0.7.1 Latest Latest
Warning

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

Go to latest
Published: Jun 3, 2026 License: MIT Imports: 8 Imported by: 0

README ยถ

GRAIN ๐ŸŒพ

Go Version GitHub release Go Reference GitHub downloads GitHub stars

Go Relay Architecture for Implementing Nostr

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.

What is Nostr?

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.

Why GRAIN?

Powerful Relay Engine
Intelligent Content Control
  • 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
Intelligent Management
  • 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
Event Management
  • 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
  • nostrdb storage (LMDB-based) optimized for Nostr's event structure
Performance Focused
  • Unified high-performance database queries for efficient event retrieval
  • Zero-dependency embedded storage via nostrdb
  • Configurable event size limits to prevent abuse
  • Connection pooling and timeout management
Complete Go Client Library

GRAIN now includes a full-featured Nostr client library that developers can use to build their own applications:

Core Client Features
  • 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
Production-Ready Components
  • 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
Developer Experience
  • Standard library first - minimal dependencies
  • Clear documentation with examples and best practices
  • Go modules support for easy integration
  • Consistent API following Go conventions

Web Interface & Reference Implementation

GRAIN includes a modern web interface that serves as both a relay dashboard and reference client implementation:

Relay Dashboard
  • 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
Reference Client

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.

API Endpoints
  • RESTful APIs for client integration and relay management
  • NIP-11 compliance for relay discovery and metadata
  • Progressive Web App features for mobile-friendly usage

๐ŸŒพ Wheat Relay Status

Wheat Status 24h Uptime Overall Uptime Response Time

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

Installation

  1. Download the latest release for your system from the releases page
  2. Run GRAIN - ./grain (Linux) or grain.exe (Windows)

GRAIN is a zero-dependency, single-binary application. All assets (including the web interface) are embedded in the binary. On first run, it will automatically create default configuration files and a local database in the platform-appropriate data directory:

  • Linux: ~/.grain/
  • macOS: ~/Library/Application Support/grain/
  • Windows: %APPDATA%\grain\

You can override the data directory using the --data-dir <path> CLI flag or the GRAIN_DATA_DIR environment variable.

Alternative Installation Methods

Docker Installation

Build from Source

Complete Installation Guide

Configuration

GRAIN uses four main configuration files with hot-reload support:

  • config.yml - Server, database, and rate limiting settings
  • whitelist.yml - Allowed users, domains, and event types
  • blacklist.yml - Banned content and escalation policies
  • relay_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

Using GRAIN as a Go Library

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)
        }
    }()
}

๐Ÿ“– See the Client Library Guide for complete examples covering connection management, subscriptions, event building/signing, and authentication flows.

License

This project is Open Source and licensed under the MIT License. See the LICENSE file for details.

Contributing

I welcome contributions, bug reports, and feature requests via GitHub.

Repository: https://github.com/0ceanslim/grain
Issues: https://github.com/0ceanslim/grain/issues

Development Resources

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.

Documentation ยถ

Overview ยถ

Package main is the GRAIN relay entry point.

The swag annotations on this file (@title, @version, etc.) populate the top-level info block of the generated OpenAPI document. The per-route annotations live on the individual handlers โ€” search the codebase for `@Router` to find them.

@title GRAIN Relay API @version 0.7 @description HTTP API for grain โ€” Nostr relay and client tooling. Includes read-only relay configuration endpoints, key utilities, event publishing/query helpers, and (gated behind NIP-98) the NIP-86 relay management endpoint. @license.name MIT @license.url https://github.com/0ceanslim/grain/blob/main/LICENSE @BasePath / @securityDefinitions.apikey NostrAuth @in header @name Authorization @description NIP-98 HTTP Auth. Value is `Nostr <base64-encoded-kind-27235-event>` signed by the relay owner.

Directories ยถ

Path Synopsis
Admin dashboard: server-rendered page at /admin for the relay owner to tune every config knob live via NIP-86.
Admin dashboard: server-rendered page at /admin for the relay owner to tune every config knob live via NIP-86.
api
core
client/core/eventSerializer.go
client/core/eventSerializer.go
api
Package api hosts the relay-management HTTP handlers.
Package api hosts the relay-management HTTP handlers.
api/docs
Package docs serves grain's OpenAPI specification.
Package docs serves grain's OpenAPI specification.
utils/relayurl
Package relayurl applies NIP-42-flavored URL normalization for the purpose of comparing a client-supplied AUTH `relay` tag against the relay's configured Auth.RelayURL.
Package relayurl applies NIP-42-flavored URL normalization for the purpose of comparing a client-supplied AUTH `relay` tag against the relay's configured Auth.RelayURL.
genconfigs command
genconfigs writes dynamic test fixtures that depend on deterministically derived keypairs (so test Go code and config YAML agree on the same pubkey).
genconfigs writes dynamic test fixtures that depend on deterministically derived keypairs (so test Go code and config YAML agree on the same pubkey).

Jump to

Keyboard shortcuts

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