Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -103,5 +103,21 @@ WOT_REFRESH_INTERVAL="24h"
WHITELISTED_NPUBS_FILE="whitelisted_npubs.json"
BLACKLISTED_NPUBS_FILE="blacklisted_npubs.json"

# Optional: whitelist by Namecoin (.bit) names. Each entry in the JSON
# file is a .bit identifier (e.g. "me@me.bit", "d/me", "id/alice").
# At startup, HAVEN resolves each name to its underlying npub via
# public Namecoin ElectrumX servers and merges them into the whitelist
# alongside WHITELISTED_NPUBS_FILE. Spec:
# https://github.com/nostr-protocol/nips/pull/2349
# WHITELISTED_NAMECOIN_NAMES_FILE="whitelisted_namecoin_names.json"

# Optional: whitelist by Namecoin (.bit) names. Each entry in the JSON
# file is a .bit identifier (e.g. "me@me.bit", "d/me", "id/alice").
# At startup, HAVEN resolves each name to its underlying npub via
# public Namecoin ElectrumX servers and merges them into the whitelist
# alongside WHITELISTED_NPUBS_FILE. Spec:
# https://github.com/nostr-protocol/nips/pull/2349
# WHITELISTED_NAMECOIN_NAMES_FILE="whitelisted_namecoin_names.json"

## LOGGING
HAVEN_LOG_LEVEL="INFO" # DEBUG, INFO, WARNING or ERROR
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,18 @@ interaction with your relay.

See the [Access Control Documentation](docs/access-control.md) for more details on how to set up whitelists and blacklists.

#### Whitelisting by Namecoin (`.bit`) name

As an additive opt-in alternative, you can whitelist users by their Namecoin (`.bit`) name instead of (or in
addition to) their npub. Point `WHITELISTED_NAMECOIN_NAMES_FILE` at a JSON file containing `.bit` identifiers
(e.g. `me@me.bit`, `d/example`, `id/alice`). At startup, Haven resolves each name to its underlying pubkey via
public Namecoin ElectrumX servers and merges the result into the whitelist alongside `WHITELISTED_NPUBS_FILE`.

Resolution is best-effort: if a name can't be resolved (no Namecoin record, ElectrumX unreachable, etc.) Haven
logs a warning and keeps starting. If both `WHITELISTED_NPUBS_FILE` and `WHITELISTED_NAMECOIN_NAMES_FILE` are
set, both contribute to the same in-memory whitelist. See `whitelisted_namecoin_names.example.json` for the
file shape. Spec reference: [NIP-05 Namecoin extension](https://github.com/nostr-protocol/nips/pull/2349).

### 5. Run on System Startup

#### Linux – Create a Systemd Service
Expand Down
26 changes: 26 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"strings"
"time"

"github.com/barrydeen/haven/pkg/nip05namecoin"
"github.com/joho/godotenv"
"github.com/nbd-wtf/go-nostr/nip19"
)
Expand Down Expand Up @@ -62,6 +63,7 @@ type Config struct {
WotFetchTimeoutSeconds int `json:"wot_fetch_timeout_seconds"`
WotRefreshInterval time.Duration `json:"wot_refresh_interval"`
WhitelistedPubKeys map[string]struct{} `json:"whitelisted_pubkeys"`
WhitelistedNamecoinNames map[string]struct{} `json:"whitelisted_namecoin_names"`
BlacklistedPubKeys map[string]struct{} `json:"blacklisted_pubkeys"`
LogLevel string `json:"log_level"`
BlastrRelays []string `json:"blastr_relays"`
Expand Down Expand Up @@ -114,6 +116,7 @@ func loadConfig() Config {
WotFetchTimeoutSeconds: getEnvInt("WOT_FETCH_TIMEOUT_SECONDS", 30),
WotRefreshInterval: getEnvDuration("WOT_REFRESH_INTERVAL", 24*time.Hour),
WhitelistedPubKeys: getNpubsFromFile(getEnvString("WHITELISTED_NPUBS_FILE", "")),
WhitelistedNamecoinNames: getNamesFromFile(getEnvString("WHITELISTED_NAMECOIN_NAMES_FILE", "")),
BlacklistedPubKeys: getNpubsFromFile(getEnvString("BLACKLISTED_NPUBS_FILE", "")),
LogLevel: getEnvString("HAVEN_LOG_LEVEL", "INFO"),
BlastrRelays: getRelayListFromFile(getEnv("BLASTR_RELAYS_FILE")),
Expand All @@ -124,6 +127,16 @@ func loadConfig() Config {
// Relay owner is always whitelisted
cfg.WhitelistedPubKeys[cfg.OwnerPubKey] = struct{}{}

// Resolve any configured Namecoin (.bit) names into pubkeys and
// merge them into the existing whitelist. Best-effort: failures
// log a warning but do not abort startup, so an operator can bring
// their pod online before the resolver succeeds.
nip05namecoin.ResolveNamesToPubkeys(
cfg.WhitelistedPubKeys,
cfg.WhitelistedNamecoinNames,
nip05namecoin.ResolveOptions{Logger: log.Default()},
)

return cfg

}
Expand Down Expand Up @@ -173,6 +186,19 @@ func getRelayListFromFile(filePath string) []string {
return relayList
}

// getNamesFromFile loads a JSON array of Namecoin (.bit) identifiers
// from `filePath` and returns them as a set. Identifiers are kept as
// strings (e.g. "me@me.bit", "d/me") and resolved later at startup.
// Mirrors getNpubsFromFile: parse failures abort startup, since the
// operator clearly intended to load a whitelist file.
func getNamesFromFile(filePath string) map[string]struct{} {
names, err := nip05namecoin.LoadNamesFile(filePath)
if err != nil {
log.Fatalf("Failed to load Namecoin names file: %s", err)
}
return names
}

func getNpubsFromFile(filePath string) map[string]struct{} {
pubKeys := map[string]struct{}{}
if filePath == "" {
Expand Down
Loading