Nostr Forever
Jumble has been my go-to web client for more than a year, because of its versatility, customizability, and overall design. It’s built the way I like to use Nostr in the browser, doesn’t prioritize fluff influencer content, and supports features I actually use, like custom emojis and relay feeds. @8125b...00883, its creator, has also been a pleasure to work with. He encouraged me early in my vibecoding journey, and has merged several of my feature submissions and bug fixes along the way. When I had the idea to attempt the first @9711d...ebd81 SDK integration into a Nostr client, I chose Jumble to build on first.
A few months ago, I had the idea to attempt a massively challenging project to build a best-in-class NIP-07 signer that sits alongside your browser window as an active companion to your Nostr experience. @c746f...9abbd, as I named it, securely stores multiple nsecs to allow fast user switching in browser clients. This is ideal if you manage a brand account, or a fun alt (I have one for my dog @c71bd...89d7f), or you need a throwaway account to test while you’re building something. It also lets you connect an NWC wallet to each account, and stores backups of your profile, follows, and mute lists on your relays in case another client nukes them by mistake. It even warns you if something you’re about to sign will erase any of your information, so you can avoid even needing to recover it after the fact.
Anyway, for the longest time, I struggled to get Sidecar to work properly with Jumble. Reposts and reactions did absolutely nothing. I couldn’t find an error, just loading indicators that pulsed forever as if the client was waiting for something that never arrived. Relay authentication took 30 seconds or more, when it even worked at all. Clearing the cache and restarting the browser usually fixed it, and not long after, it was broken again.
I began to think the bug was somewhere in Sidecar. I went looking through the app’s signing queue, its relay handling, and its permissions. I found bugs in all three and fixed them, but none of it made any difference. Then I checked the relays themselves from outside the browser and every one of them answered almost instantly. The relays were working. Sidecar was signing normally. But there was something else in the way.
The answer turned out to be the browser’s network tab. It was full of connections to the same handful of relays, over and over, seven to one relay alone. Every one of them had connected successfully and then transferred nothing at all. Some had been sitting open for more than an hour. In that one session the browser had opened roughly 700 of them.
That’s when it all made sense. The problem had to be in the client’s own dependencies. Jumble, like many other Nostr web clients including Sidecar, relies on the nostr-tools library. When the client needs to talk to a relay, it opens a websocket, and when one of those connections fails, it stays open for the entire life of that browser session. Clients that use the outbox model connect to the relays of everyone you follow to find their latest notes, and that list piles up very quickly. A browser is only designed to hold a limited number of these connections, and once those are exhausted, nothing else can connect. Not Jumble, not Sidecar, not any other tab you have open. Signing still works, because signing doesn’t need a relay, so your client hands you a perfectly good signed event that can’t go anywhere. That’s exactly why nothing seemed to be happening.
I worked through these problems methodically using two different agent sessions, one with Claude Opus 5 and the other with GLM 5.3-Flash. We passed information back and forth, and ultimately, Claude came back with the fix. I opened an issue with a full explanation of the problem and a solution in code. Within half an hour, @3bf0c...a459d had already patched it, published nostr-tools 2.25.2, and commented, “Did you just save Nostr forever?”
The fix is one line, in two places, slightly modified from the original:
this.ws?.close?.()
That’s it. That’s the fix. Close the broken socket you left open.
Now, every client using the nostr-tools relay pool gets this with a dependency bump. Other clients that run on NDK or maintain their own networking layer don’t need the fix, and were never affected by this issue.
This is what I love about open source software, and it’s what keeps drawing me in deeper. I don’t have a strong background in handwritten code, but I have a career of solving complex problems in creative ways, and as any of you who know me well will probably agree, I am fucking relentless when I set my mind on accomplishing something.
In the past two years, I pivoted my entire career direction, for at least the third time in under a decade. In that time, I received two awards in the Breez challenge. I got accepted into the @eccf5...bca4f Startup School, where I’ve been building @319ad...1d50a with my friend @a7238...2dc9c. I joined @4ef93...e79c0, a company with deep roots in Nostr and the Bitcoin community, that has given me the freedom and tools to build and experiment alongside a team of absolute rockstars.
I choose to build on the Nostr and Bitcoin ecosystem because nothing else I’ve found has ever given me this level of ownership, and personal fulfillment, and I couldn’t imagine being anywhere else. Even if almost nobody gets it yet.
#NostrForever
Write a comment