Last Notes
You missed Hubstr Relay, and Hubstr Blossom:
https://github.com/johninnis/hubstr-relay
https://github.com/johninnis/hubstr-blossom
Thank you! It means a lot that you noticed the care I take, and even more that you're building on top of it. Looking forward to checking out Decent Newsroom!
Yeah, I still use Symfony for work apps. This is a different paradigm tho, a long-running async process, so it's AMPHP. I'll do a write-up once the last piece ships.
Shipped Hubstr Blossom yesterday too.
A personal Blossom server: your images, video, and files stored under their SHA-256, served from your own origin, and managed with your Nostr key. Two kinds of visitor. Anyone can fetch a blob by its hash. Tenants can upload, mirror, optimise, list, and delete them.
Every upload is hashed and type-sniffed on arrival, so the stored hash is what was received and the stored type is what the bytes are, not what the header said. PUT /media re-encodes an image and drops its metadata, applying the EXIF orientation first. The result is kept only if it is smaller. Dimensions and a blurhash are computed for NIP-94. Kind 1984 reports are accepted and kept.
Blobs live on the filesystem, sharded by hash, moved into place with one atomic rename. The SQLite index holds one row per tenant per blob, so the same bytes uploaded by two tenants are stored once and removed only when the last of them deletes. Nothing else deletes them. Bytes are streamed from the process with ranges, ETags, and CORS handled in application code, so a plain reverse proxy is all it needs. Hashing and media work run on a worker pool, off the event loop.
BUDs 01, 02, 04, 05, 06, 08, 09, 11, and 12, and an acceptance suite that boots a real daemon and drives every one of them over HTTP. Caddyfile and systemd unit included. PHP 8.4, two config keys to change, and it starts.
A version of this server has been running on blossom.innis.xyz for months, with earlier versions in the wild for longer.
Built on innis/nostr-blossom, innis/nostr-core, and innis/hubstr-core.
https://github.com/johninnis/hubstr-blossom
Thanks to @nprofile…9x4s for the elegant protocol.
MIT.
#nostr #php #opensource #nostrdev #blossom
Yesterday I shipped Hubstr Relay. Not a library. A relay you can run.
A personal relay: one PHP process, one SQLite file, and two kinds of visitor. Guests see your public presence, the notes, profile, articles, reactions, and lists you signed, and can reply, react, zap, and DM you. Tenants, authenticated over NIP-42, see every kind, and everything the relay holds, including events from other users cached there... More on that soon.
Point your kind 10050 at it and it is your DM inbox. Gift wraps come in from anyone and go out only to you. It carries NIP-46 traffic, so it works as a bunker relay too. Full-text search over NIP-50, COUNT over NIP-45, expiry swept under NIP-40, protected events under NIP-70.
The policy is managed at runtime over NIP-86, signed with NIP-98. Add a tenant. Decide which kinds guests may read and write. Ban a word, a pubkey, or a hashtag, and what is already stored goes with it. Block an IP. Set the rate limits. Watch every open connection and the subscriptions it holds. And an explore feed computed from what the relay has seen: trending hashtags, most followed, most muted, most zapped by count or sats, top zappers, most reacted to, most reposted, over a day, a week, a month, or all time, plus a web-of-trust score for any pubkey as seen from your follows. As above, more on relay management and content discovery soon...
Another feature of guest writes is that admitting an event by the prefix of a tag value allows sites to host their own NIP-22 comments without becoming a public free-for-all.
Database work runs on worker processes, off the event loop. Tested at two million events, with author and kind lookups under a millisecond. A version of this relay has been running on relay.innis.xyz since December, but earlier versions have been elsewhere in the wild for far longer.
Import and export are JSONL, and an export can pull one key's whole presence, everything it wrote and everything that tagged it. Caddyfile and systemd unit included. PHP 8.4, three config keys, and it starts.
Built on innis/nostr-relay, innis/nostr-core, and innis/hubstr-core.
https://github.com/johninnis/hubstr-relay
MIT.
#nostr #php #opensource #nostrdev
Sorry for the radio silence. My body called in another debt, and I went analogue while I paid it: my Bible, pen and paper, and not much else.
The debt's paid down for now, but the field's been fallow long enough. I'm going to try and push some more code. It's not ready, but it never will be...
Thank you, I'm glad you found my code useful!
I've just had a look tho, and neither the PHP nor the TS client compares the connect result to 'ack' at all. They only fail on an error field or a timeout, so an echoed secret resolves the same as an ack.
I'm using my innis/nostr-nip46 based bunker daily on a handful of third party apps, but had never tried with Amethyst Desktop. I logged in just fine tho?
If you're not subscribed to Nick Cave's newsletter, I'd recommend checking it out:
https://www.theredhandfiles.com/
This is the day that the Lord has made.
We will rejoice and be glad in it.
- Psalm 118:24
4.6 was peak Claude. Everything since then has been an expensive downgrade.
heh, I just wrote this in another thread.
#nevent1q…s5y0
So teach us to number our days,
That we may gain a heart of wisdom.
- Psalm 90:12
Today if you will, hear His voice. Harden not your heart.
- Psalm 95:7-8
That was quick!
Quietly pleased with myself this morning, learning my code can hold its own. Nipworker is clearly serious work, and I'm glad to be measured against it.
Thank you.
Many thanks!
Very curious, and quietly anxious.
(Tho I can't zap you for some reason - tried on multiple clients?)
Would love to know how the Innis libs performed in your tests:
https://github.com/johninnis/
https://jsr.io/@innis
https://packagist.org/packages/innis/
Almighty God, to whom all hearts are open, all desires known, and from whom no secrets are hidden: cleanse the thoughts of our hearts by the inspiration of your Holy Spirit, that we may perfectly love you, and worthily magnify your holy name; through Christ our Lord. Amen.
Still down the fiat mine, but the old libraries are getting time when I can.
Shipping innis/nostr-blossom today: Blossom, blob storage on Nostr, in PHP.
The counterpart to the TypeScript client from June, but not a port of it. That library is a Blossom client, this is the layer a server is built from. The BUD use cases, the kind 24242 auth validation, the policies that decide who may store what. BUDs 01, 02, 04, 05, 06, 08, 09, 11 and 12.
Spec, not server. No filesystem, no database, no HTTP. Storage, indexing and inspection are injected ports a host wires to its own runtime, with one such host coming soon. Where the spec left room I took the strict side. Judgement calls are recorded as ADRs in the repo, so if you would have called it differently, there is something specific to argue with.
Built on innis/nostr-core. PHPStan level 9.
Many thanks to @nprofile…9x4s for this fine protocol.
composer require innis/nostr-blossom
https://github.com/johninnis/nostr-blossom
MIT.
#nostr #php #opensource #nostrdev
Nostr draws the kind of person who is not lonely for a crowd. But a network grows on people who need to be seen, so the ones best suited to this place are the ones least able to grow it. They publish and expect nothing in return. They are content with the crickets.
The people who need the validation stayed where it is manufactured. The people who came here came because they had stopped needing it. A network of remnants fills slowly, and most of them prefer it that way.
The fiat mine has been calling, but I'm getting the Nostr hours in where I can, tidying up age old libraries...
Shipping innis/nostr-nip46 today: the bunker, NIP-46, in PHP.
The PHP companion to the TypeScript nip46 I put out in June. Same two roles.
A PHP app pairs with a bunker:// URL and has events signed on the user's behalf without ever holding the key. The bunker is the other end. It lends your signer to another device, holding each sign_event in a queue until you approve or reject.
Pairing is bunker:// only, minted by the signer. The client-initiated nostrconnect:// flow is not yet implemented. I will wait for a need so I can be sure I get it right.
Built on innis/nostr-core. No network I/O of its own; the relay transport is an injected port. PHPStan level 9.
composer require innis/nostr-nip46
https://github.com/johninnis/nostr-nip46
MIT.
#nostr #php #opensource #nostrdev
A week in the fiat mines. Life too. I get back on Nostr and there's already another private messaging standard.
Thank you Dawn. The dendritic agate is my favourite. Easy to get lost in there.
Beautiful! I wonder if @nprofile…9vs7 knows what they are?
Fable is still a waste of time. It asserts false claims about NIPs with total confidence, then refuses to touch anything even adjacent to cryptography, which rules out low-level Nostr work. A model that won't go near a signature is no help on a protocol built out of them...
Network map of your Nostr followers?
I'm not sure what is more beautiful, the finished product or the plans to build them. Really inspiring work.
Last night, in a semi-lucid moment of realising I was waking, I reached to commit the dream to the repo before I lost it. Fiat mining by day, Nostr by night. All work and no play makes Innis dream in code.
Sorry, brother. You don't have to carry it well, and you don't have to carry it alone.
Paul made tents so the preaching wouldn't cost anyone anything. Most days my work feels less like the tentmaker and more like the prostitutes Jesus ate with, tho they might enjoy their work a little more. Fear not. I'll soon be back doing what I love. More releases to come.
Shipping jsr:@innis/nostr-nip29 today. Pure domain helpers for NIP-29 relay-based groups. A group is owned by the relay that hosts it; the relay publishes a kind 39000 metadata event for each one. This turns those into Group value objects and builds the kind 9 replies. No I/O, querying and rendering stay in the consumer.
This is in the spirit of the relay-selection library I put out in May. This library is small, and only implements part of the NIP-29 spec, but addresses some inconsistencies I was encountering when building my client: the relay hint on the group h tag, how a chat reply should be structured, which metadata markers matter. I wanted to get those right, and after encountering differing implementations in the wild, decided to read how existing clients handle them, and where the spec is silent they each made their own reasonable call. Fair enough; there was nothing written to follow.
So I pulled that common core into one place, fully tested, with every step past the written spec flagged as a convention rather than passed off as protocol. I'm a perfectionist and I would rather be corrected than be quietly wrong, so this is published on its own to open the discussion more than settle it. If I've misread a NIP, or you'd shape one of these conventions differently, I'm happy to be corrected. The point is to improve everyone's code, mine included.
The scope is deliberately narrow. It models the parts of NIP-29 the app I've built against it actually uses: metadata, chat, replies, and nothing else. Admins, roles, the group lifecycle are not modelled, because nothing I've built needs them yet, and I would rather leave the shape unwritten than guess it from the spec and be wrong. They'll get the same scrutiny the rest got, when I eventually need them.
Built on @innis/nostr-core, alongside the signers, the pool, the event store, Blossom, and relay-management. AI was involved, same terms as before. The architecture is mine. The decisions are mine.
deno add jsr:@innis/nostr-nip29
https://github.com/johninnis/nostr-nip29-ts
MIT.
#nostr #typescript #opensource #nostrdev
Thanks to @nprofile…9vs7 @nprofile…u0w6 @nprofile…jejf @nprofile…fjwq and @nprofile…v4ps
Coming so soon! This week for sure. I'm still untangling things...
Shipping jsr:@innis/nostr-relay-management today. A signed client for NIP-86, the HTTP surface a relay exposes for its own administration. Banning a pubkey, allowing one, blocking events, blocking IPs, reading the moderation queue, and on a relay running the Hubstr extensions, stats and connections and rate limits and guest policy too.
A small library, but it gives away some of what the rest of the stack is being built toward. More to come.
Built on @innis/nostr-core, alongside the signers, the pool, the event store, and Blossom. AI was involved, same terms as before. The architecture is mine. The decisions are mine.
deno add jsr:@innis/nostr-relay-management
https://github.com/johninnis/nostr-relay-management-ts
MIT.
#nostr #typescript #opensource #nostrdev
I didn't notice any difference at all. Every time it might have been amazing for me I was reverted to Opus:
#nevent1q…5uav
Similar trajectory and timing. Slackware, to Red Hat, but then quickly onto Debian. I haven't left.
Nostr is no fun when I can't zap. Have tried to restore the wallet elsewhere and no dice, so am reluctant to reset minibits. But it's looking like these sats may have to be gifted to God.
#nevent1q…y3p4
Every fight over human rights has been a fight over who gets counted as fully human, and it is no longer just the slave or the undocumented. I have been mistaken for a model more than once, and the mistake was honest. Even I could see where they were coming from. We are now generated until proven otherwise. This started with CAPTCHAs, but won't stop with KYC. Nostr and Bitcoin are so important that those who hold the keys now are still figuring it out for everyone who comes after us.
Anyone else having trouble with @nprofile…d4vz this morning? I can't zap anyone, the funds keep getting sent back to my wallet.
It's not hundreds of dollars, but would have kept me zapping for the next little while, so am reluctant to try anything drastic on the off chance it fixes itself.
I can't zap anyone this morning via minibits.
Which mint did you use instead?
I've already been banned. For making some changes to my relay and running some tests...
#nevent1q…5uav
Fable 5’s safety measures flagged this message for cybersecurity or biology topics. They may flag safe, normal content as well. These measures let us bring you Mythos-level capability in other areas sooner, and we’re working to refine them. Switched to Opus 4.8. Send feedback with /feedback or learn more
Oh well, that was fun while it lasted...
The firehose of any popular relay will unfortunately subject you to people spamming Telegram groups promising all kinds of filth. I'm not sure how it works, but I presume they're selling content? I imagine they'll upload it wherever they can host it.
The appetite's real. The slop they're being fed is the problem. Surely they'll tire of it?
Even when it's just bots talking to bots? Surely they'll leave an empty room. Or maybe I just have too much faith in people.
What a great gig. Getting paid to accelerate the downfall of traditional social media, one automated post at a time. Why didn't I think of that...
When someone sends you a large zap, you briefly become a mini @nprofile…pqk6 and can start micro-funding the kind of content you want to see on Nostr.
I'm convinced your focus on small communities is the right instinct. Money is still the best proxy we have, but I haven't found a way to make it pay. I hope the Coracle Hosting model works out for you.
This has been my biggest fear with Nostr. I'd love to run relays for people, but don't want to open myself up to litigation, nor become responsible for moderation. I really admire what you're doing. There's no wrong answer. You're doing the Lord's work.
Aaaah. New Anthropic model out. That explains why Claude's been so daft all week... Every time.