{"type":"rich","version":"1.0","title":"Innis wrote","author_name":"Innis (npub1l3…5cxyz)","author_url":"https://yabu.me/npub1l33660awkeycecn9grhrvzyn0fmes8245ke7k82y8njz8uqu3vlqk5cxyz","provider_name":"njump","provider_url":"https://yabu.me","html":"Shipping two libraries today: nostr-relay-selection in TypeScript and PHP. They answer one question: given a Nostr event, which relays should it go to. Covers outbox publish routing, NIP-17 DMs, NIP-65 list parsing, author set-cover, e/p relay hints.\n\nBoth libraries are pure functions. No state, no I/O, no caches, no fallback URLs, no tie-breaks by Math.random or time decay. Same inputs, same outputs, every time.\n\nThe existing implementations (NDK's OutboxTracker, rust-nostr's gossip, go-nostr's sdk, welshman/router) are engines: stateful, heuristic, coupled to a pool. None are deterministic.\n\nThese libraries take the opposite trade. They are a spec. The TypeScript and PHP ports share a JSON corpus of test vectors. A vector that passes in one passes in the other. A Go or Rust port joins the same compliance suite or it doesn't conform.\n\nIf you're building a client, a relay, a bot, an indexer, the win is having routing live behind one auditable path. One place that knows the NIPs. One set of vectors that decide whether the answer is right. When NIP-65 grows a marker or NIP-17 tightens a rule, you update the library and every caller gets the new policy.\n\nPost-spec decisions belong in an adapter at the boundary. Onion-only routing for a privacy build, dropping unresponsive relays based on pool state, home-relay ordering, scoring by past success — whatever your runtime knows that the spec doesn't. The library returns the NIP-derived answer; the adapter overlays your application's intuition on top.\n\nIn use across the rest of my Nostr stack, to be released soon. I'm also putting these out because I want them stress-tested by people who have shipped more Nostr than I have. If you spot a corpus (Claude's favourite word right now) vector that's wrong, a NIP rule I've misread, or a routing decision you'd make differently, the issue tracker is open.\n\ndeno add jsr:@innis/nostr-relay-selection\nhttps://github.com/johninnis/nostr-relay-selection-ts\n\ncomposer require innis/nostr-relay-selection\nhttps://github.com/johninnis/nostr-relay-selection-php\n\nMIT.\n\n#nostr #typescript #php #opensource #nostrdev"}
