= image:./docs/orly.png[orly.dev]
:toc:
:note-caption: note 👉

image:https://img.shields.io/badge/godoc-documentation-blue.svg[Documentation,link=https://pkg.go.dev/orly.lol]
image:https://img.shields.io/badge/donate-geyser_crowdfunding_project_page-orange.svg[Support this project,link=https://geyser.fund/project/orly]
zap me: ⚡️mlekudev@getalby.com
follow me on link:https://jumble.social/users/npub1fjqqy4a93z5zsjwsfxqhc2764kvykfdyttvldkkkdera8dr78vhsmmleku[nostr]

nostr relay built from a heavily modified fork of https://github.com/nbd-wtf/go-nostr[nbd-wtf/go-nostr]
and https://github.com/fiatjaf/relayer[fiatjaf/relayer] aimed at maximum performance, simplicity and memory efficiency.

== Features

* a lot of bits and pieces accumulated from nearly 8 years of working with Go, logging and run control, XDG user data directories (windows, mac, linux, android)
* a cleaned up and unified fork of the btcd/dcred BIP-340 signatures, including the use of bitcoin core's BIP-340 implementation (more than 4x faster than btcd) (todo: ECDH from the C library tbd).
* AVX/AVX2 optimized SHA256 and SIMD hex encoder
* https://github.com/bitcoin/secp256k1[libsecp256k1]-enabled signature and signature verification (see link:p256k/README.md[here]).
* efficient, mutable byte slice-based hash/pubkey/signature encoding in memory (zero allocation decode from wire of all but id/pubkey/signature, can tolerate whitespace, at a speed penalty)
* custom badger-based event store that uses fast binary encoder for storage of events, and has a complete set of indexes so it doesn't need to decode events for any query until delivering them.
* link:cmd/vainstr[vainstr] vanity npub generator that can mine a 5-letter suffix in around 15 minutes on a 6 core Ryzen 5 processor using the CGO bitcoin core signature library.
* reverse proxy tool link:cmd/lerproxy[lerproxy] with support for Go vanity imports and https://github.com/nostr-protocol/nips/blob/master/05.md[nip-05] npub DNS verification and own TLS certificates
* link:https://github.com/nostr-protocol/nips/blob/master/98.md[nip-98] implementation with new expiring variant for vanilla HTTP tools and browsers.

== Releases

see link:https://github.com/mleku/orly/releases[Releases] for pre-built binaries built on latest stable Go 1.24. Linux binaries are built static and have no dependencies on `*.so` files on the host (so they can run on bare metal and in containers with nothing added).

== Building

If you just want to make it run from source, you should check out a tagged version.

The commits on these tags will explain what state the commit is at.

In general, the most stable versions are new minor tags, eg v1.2.0 or v1.23.0, and minor patch versions may not be
stable and occasionally may not compile (not very often).

Go 1.24 or better is required.

== Repository Policy

In general, the `main` branch will build, but occasionally may not.
It is where new commits are added once they are working, mostly, and allows people to easily see ongoing activity.

WARNING: IT IS NOT GUARANTEED TO BE STABLE... but it is getting there.

Use tags to pin to a specific version.
Tags are in standard Go semver pattern `vX.X.X`

== CGO and secp256k1 signatures library

By default, Go will usually be configured with `CGO_ENABLED=1`.
This selects the use of the C library from bitcoin core, which does signatures and verifications much faster (4x and
better) but complicates the build process as you have to install the library beforehand.
There is instructions in link:p256k/README.md[p256k/README.md] for doing this.

=== Disabling CGO

In order to disable the use of this, you must set the environment variable `CGO_ENABLED=0` and it the Go compiler will
automatically revert to using the btcec based secp256k1 signatures library.

----
export CGO_ENABLED=0
go build .
----

This will build the binary and place it in the root of the repository, and then you can move it where you like.

=== Static build

To produce a static binary, whether you use the CGO secp256k1 or disable CGO as above:

----
go build --ldflags '-extldflags "-static"' -o ~/bin/orly .
----

will place it into your `~/bin/` directory, and it will work on any system of the same architecture with the same glibc
major version (has been 2 for a long time).

== Configuration

The default will run the relay with default settings, which will not be what you want.

=== Show Current Configuration

To see the current active configuration:

----
orly env
----

To see the help information:

----
orly help
----

Environment variables that configure orly:

[cols="4"]
|===
| Environment variable | type | default | description 
| ORLY_APP_NAME              | string         | orly |
| ORLY_CONFIG_DIR            | string         | ~/.config/orly                                                                                                                            | location for configuration file, which has the name '.env' to make it harder to delete, and is a standard environment KEY=value<newline>... style
| ORLY_STATE_DATA_DIR        | string         | ~/.local/state/orly                                                                                                                       | storage location for state data affected by dynamic interactive interfaces
| ORLY_DATA_DIR              | string         | ~/.local/cache/orly                                                                                                                       | storage location for the event store
| ORLY_LISTEN                | string         | 0.0.0.0                                                                                                                                   | network listen address
| ORLY_PORT                  | int            | 3334                                                                                                                                      | port to listen on
| ORLY_LOG_LEVEL             | string         | info                                                                                                                                      | debug level: fatal error warn info debug trace
| ORLY_DB_LOG_LEVEL          | string         | info                                                                                                                                      | debug level: fatal error warn info debug trace
| ORLY_PPROF                 | string         | <empty>                                                                                                                                   | enable pprof on 127.0.0.1:6060
| ORLY_AUTH_REQUIRED         | bool           | false                                                                                                                                     | require authentication for all requests
| ORLY_PUBLIC_READABLE       | bool           | true                                                                                                                                      | allow public read access to regardless of whether the client is authed
| ORLY_SPIDER_SEEDS          | []string       | wss://profiles.nostr1.com/,
wss://relay.nostr.band/,
wss://relay.damus.io/,
wss://nostr.wine/,
wss://nostr.land/,
wss://theforest.nostr1.com/,
wss://profiles.nostr1.com
| seeds to use for the spider (relays that are looked up initially to find owner relay lists) (comma separated)
| ORLY_SPIDER_TYPE           | string         | directory                                                                                                                                 | whether to spider, and what degree of spidering: none, directory, follows (follows means to the second degree of the follow graph)
| ORLY_SPIDER_FREQUENCY      | time.Duration  | 1h                                                                                                                                        | how often to run the spider, uses notation 0h0m0s
| ORLY_SPIDER_SECOND_DEGREE  | bool           | true                                                                                                                                      | whether to enable spidering the second degree of follows for non-directory events if ORLY_SPIDER_TYPE is set to 'follows'
| ORLY_OWNERS                | []string       | []                                                                                                                                        | list of users whose follow lists designate whitelisted users who can publish events, and who can read if public readable is false (comma separated)
| ORLY_PRIVATE               | bool           | false                                                                                                                                     | do not spider for user metadata because the relay is private and this would leak relay memberships
| ORLY_WHITELIST             | []string       | []                                                                                                                                        | only allow connections from this list of IP addresses
| ORLY_SECRET_KEY            | string         | <empty>                                                                                                                                   | secret key for relay cluster replication authentication
| ORLY_PEER_RELAYS           | []string       | []                                                                                                                                        | list of peer relays URLs that new events are pushed to in format <pubkey>\|<url>
|===

=== Create Persistent Configuration

This output can be directed to the profile location to make the settings editable without manually setting them on the
commandline:

----
orly env > $HOME/.config/orly/.env
----

You can now edit this file to alter the configuration.

Regarding the configuration system, this is an element of many servers that is absurdly complex, and for which reason
orly doesn't use a complicated scheme, a simple library that allows automatic configuration of a series of options,
added a simple info print:

----
orly help
----

will show you the instructions, and the one simple extension of being able to use a standard formated .env file to
configure all the options for an instance.

=== Database Storage Location

The database is stored in `$HOME/.local/share/orly` and if need be you can stop `orly` delete everything in this
directory and restart to "nuke" the database.

== API support

=== Standard Nostr NIPs

`orly` already accepts all the standard NIPs mainly nip-01, and many other types are recognised such an NIP-42 auth
messages and it uses and parses relay lists, and all that other stuff.

[#_simplified_nostr]
=== Simplified Nostr

Rather than write a text that will likely fall out of date very quickly, simply run `orly` and visit its listener
address (eg link:http://localhost:3334/api[http://localhost:3334/api]) to see the full documentation.

By default, this presents you with a Scalar Docs page that lets you browse the available API methods and shows examples
in many forms including cURL and most languages how to call and what data needs to go in headers, body, and parameters
and what results will come back.

There is even a subscription endpoint, also, which uses SSE format and doesn't require a websocket upgrade to work with.