|
1 | 1 | # mocrelay |
2 | 2 |
|
3 | | -A Nostr relay implementation in Go. |
| 3 | +A middleware-composable Nostr relay implementation in Go. |
4 | 4 |
|
5 | | -## Status |
| 5 | +## Features |
6 | 6 |
|
7 | | -🚧 Under development (rewrite branch) |
| 7 | +- **Middleware Architecture**: Compose handlers and middlewares to build your relay |
| 8 | +- **NIP-11 Driven**: Middlewares map directly to NIP-11 `limitation` fields |
| 9 | +- **Pure Go**: No cgo dependencies, easy deployment |
| 10 | +- **Persistent Storage**: Pebble-based storage with MVCC support |
| 11 | + |
| 12 | +## Installation |
| 13 | + |
| 14 | +```bash |
| 15 | +go get github.com/high-moctane/mocrelay |
| 16 | +``` |
| 17 | + |
| 18 | +## Quick Start |
| 19 | + |
| 20 | +```go |
| 21 | +package main |
| 22 | + |
| 23 | +import ( |
| 24 | + "log" |
| 25 | + "net/http" |
| 26 | + |
| 27 | + "github.com/high-moctane/mocrelay" |
| 28 | +) |
| 29 | + |
| 30 | +func main() { |
| 31 | + // Create storage |
| 32 | + storage, _ := mocrelay.NewPebbleStorage("/var/lib/mocrelay/data", nil) |
| 33 | + defer storage.Close() |
| 34 | + |
| 35 | + // Build handler with middlewares |
| 36 | + handler := mocrelay.NewMergeHandler( |
| 37 | + mocrelay.NewStorageHandler(storage), |
| 38 | + mocrelay.NewRouterHandler(mocrelay.NewRouter()), |
| 39 | + ) |
| 40 | + |
| 41 | + // Apply middlewares |
| 42 | + handler = mocrelay.NewMaxSubscriptionsMiddleware(10)(handler) |
| 43 | + handler = mocrelay.NewMaxContentLengthMiddleware(8192)(handler) |
| 44 | + handler = mocrelay.NewCreatedAtLimitsMiddleware(60*60*24*30, 60*60)(handler) // 30 days old to 1 hour future |
| 45 | + |
| 46 | + // Create relay |
| 47 | + relay := mocrelay.NewRelay(handler, nil) |
| 48 | + |
| 49 | + log.Fatal(http.ListenAndServe(":8080", relay)) |
| 50 | +} |
| 51 | +``` |
| 52 | + |
| 53 | +## Available Middlewares |
| 54 | + |
| 55 | +| Middleware | NIP-11 Field | Description | |
| 56 | +|------------|--------------|-------------| |
| 57 | +| `NewMaxSubscriptionsMiddleware` | `max_subscriptions` | Limit subscriptions per connection | |
| 58 | +| `NewMaxSubidLengthMiddleware` | `max_subid_length` | Limit subscription ID length | |
| 59 | +| `NewMaxLimitMiddleware` | `max_limit` | Clamp filter limit values | |
| 60 | +| `NewMaxEventTagsMiddleware` | `max_event_tags` | Limit tags per event | |
| 61 | +| `NewMaxContentLengthMiddleware` | `max_content_length` | Limit content length | |
| 62 | +| `NewCreatedAtLimitsMiddleware` | `created_at_*_limit` | Restrict event timestamps | |
| 63 | +| `NewKindBlacklistMiddleware` | `retention` | Block specific event kinds | |
| 64 | +| `NewRestrictedWritesMiddleware` | `restricted_writes` | Pubkey whitelist/blacklist | |
| 65 | +| `NewMinPowDifficultyMiddleware` | `min_pow_difficulty` | Require proof-of-work (NIP-13) | |
| 66 | +| `NewAuthMiddleware` | `auth_required` | Require authentication (NIP-42) | |
| 67 | +| `NewExpirationMiddleware` | - | Handle event expiration (NIP-40) | |
| 68 | +| `NewProtectedEventsMiddleware` | - | Protect events from republishing (NIP-70) | |
| 69 | + |
| 70 | +## NIP Support |
| 71 | + |
| 72 | +| NIP | Status | Description | |
| 73 | +|-----|--------|-------------| |
| 74 | +| [01](https://github.com/nostr-protocol/nips/blob/master/01.md) | ✅ | Basic Protocol | |
| 75 | +| [09](https://github.com/nostr-protocol/nips/blob/master/09.md) | ✅ | Event Deletion | |
| 76 | +| [11](https://github.com/nostr-protocol/nips/blob/master/11.md) | ✅ | Relay Information | |
| 77 | +| [13](https://github.com/nostr-protocol/nips/blob/master/13.md) | ✅ | Proof of Work | |
| 78 | +| [40](https://github.com/nostr-protocol/nips/blob/master/40.md) | ✅ | Expiration Timestamp | |
| 79 | +| [42](https://github.com/nostr-protocol/nips/blob/master/42.md) | ✅ | Authentication | |
| 80 | +| [70](https://github.com/nostr-protocol/nips/blob/master/70.md) | ✅ | Protected Events | |
8 | 81 |
|
9 | 82 | ## License |
10 | 83 |
|
|
0 commit comments