@nostrwatch/nostrings
v0.6.0
Published
library of functions for sanitizing and normalizing relay urls
Readme
@nostrwatch/nostrings
Relay URL sanitization, validation, normalization, and deduplication for the Nostr protocol.
Overview
@nostrwatch/nostrings cleans, validates, normalizes, and deduplicates relay URLs for the Nostr protocol. A relay is a WebSocket server that stores and forwards Nostr events; relay URLs must conform to wss:// or ws:// format and must not point to local or reserved IP ranges. This library provides four composable operations — sanitize, qualify, normalize, and dedup — that handle messy real-world relay URL inputs from user input, scraped lists, and network data.
The sanitize function runs all four operations in a single call and is the recommended entry point for most use cases.
Installation
pnpm add @nostrwatch/nostringsOr with npm:
npm install @nostrwatch/nostringsQuick Start
import {sanitize, normalize} from '@nostrwatch/nostrings'
const raw = [
' WSS://RELAY.DAMUS.IO/#fragment ',
'wss://nos.lol',
'ws://localhost',
'wss://nos.lol'
]
const clean = sanitize(raw)
console.log(clean)
// ['wss://relay.damus.io/', 'wss://nos.lol/']API
sanitize(relays, rules?)
sanitize(relays: string[], rules?: RuleSet): string[] | voidRuns the full pipeline on an array of relay URLs: splits comma-separated entries, sanitizes each URL, filters with qualifyRelayUrl, applies optional custom discriminators and mutators, normalizes, and deduplicates. Returns the cleaned array, or void if the input is empty.
| Parameter | Type | Description |
|-----------|------|-------------|
| relays | string[] | Raw relay URLs to process |
| rules | RuleSet (optional) | Custom discriminators (filter functions) and mutators (transform functions) |
qualify(relay)
qualifyRelayUrl(relay: string): booleanReturns true if the URL passes all qualification checks: starts with wss:// or ws://, is not a local or reserved IP, is not localhost, and has no embedded protocol strings. Returns false otherwise. Uses a pessimistic invalidation pattern — any failure disqualifies the URL.
| Parameter | Type | Description |
|-----------|------|-------------|
| relay | string | A single relay URL string |
normalize(relay)
normalizeRelayUrl(relay: string): stringStrips the hash, search, and username components from a relay URL using the browser-native URL API. Returns the canonical form, or an empty string if the URL cannot be parsed.
| Parameter | Type | Description |
|-----------|------|-------------|
| relay | string | A single relay URL string |
dedup(relays)
dedup(relays: string[]): string[]Removes duplicate URLs from an array using a Set. Returns a new array with unique entries only.
| Parameter | Type | Description |
|-----------|------|-------------|
| relays | string[] | Array of relay URLs, possibly with duplicates |
Additional exports
sanitizeRelayUrl(relay: string): string— sanitizes a single URL (lowercase, trim, remove fragments, trailing slashes, and blob hashes)maybeSplitRelayList(relays: string[]): string[]— splits comma-separated relay strings into individual entriesnormalizeRelayUrls(relays: string[]): string[]— normalizes an array of relay URLsnormalizeRelayUrlAcc(acc: string[], relay: string): string[]— reducer form ofnormalizeRelayUrlfor use withArray.reduceisLocal(url: string): boolean— returnstrueif the URL is a local file path or network pathisLocalNet(url: string): boolean— returnstrueif the URL hostname is in a reserved IP range (127.x, 10.x, 192.168.x, 172.16-31.x)
Known Limitations
No known limitations at this time.
Agent Skills
No agent skills defined yet for this package.
Related Packages
@nostrwatch/nocap— relay capability checker that uses nostrings for URL validation before connecting@nostrwatch/route66— relay aggregation and state management; passes relay URLs through nostrings before storage
