pull down to refresh

I built a P2P file sharing app using Nostr for peer discovery.
How it works: Log in with your Nostr extension, pick a recipient by npub, select a file, and send. WebRTC signaling goes through Nostr relays (encrypted with NIP-44), then files transfer directly browser-to-browser. The relay never sees your files.

Try it: https://k4lb1.github.io/Zoop/Code: https://github.com/k4lb1/Zoop

Relays only handle tiny encrypted signaling messages - the actual file goes peer-to-peer.

What I learned: Nostr’s event system works surprisingly well for WebRTC coordination. NIP-44 encryption keeps signaling private. ICE negotiation on mobile networks is still brutal though.

Thinking about a desktop version with persistent transfer history and contact management.

Feedback welcome - especially if you find bugs.

1 sat \ 3 replies \ @AGORA 4h

That's great, forked! Not sue which kind of issue I'm facing and it is not loading properly. Anything should I set to fix?

reply

Thanks for forking! Can you tell me a bit more? do you see any errors in the browser console?

reply
0 sats \ 1 reply \ @AGORA 1h

Sure, I simply forked and deployed in GH pages using the existing workflows/deploy.yml

here a screenshot

reply

Hey, sorry for the hassle.

The 404 happens when Pages is set to “Deploy from a branch” with the main branch and the root (/) folder. In that case GitHub serves the raw repo (your source code), but the actual site is built by Vite into a dist/ folder. The root only has things like src/, package.json, etc., and no index.html, so the browser gets a 404.

What to do: In your fork go to Settings → Pages. Under Build and deployment, set Source to GitHub Actions (instead of “Deploy from a branch”). Then the workflow runs on every push to main: it runs npm run build and deploys the built dist/ folder. Give it a minute or two after a push, then https://4g0r4.github.io/Zoop/ should load.

I’m not that experienced with Git and GitHub myself, so I only figured this out with some help. We’ve added a “Quick Start for Forks” section in the README with these steps so it’s easier next time. Hope that fixes it for you.

reply

Nice work — using Nostr relays for WebRTC signaling is clever. NIP-44 encryption for the signaling messages is the right call since those contain ICE candidates that could leak IPs.

One thing I've run into building on Nostr (I run a live DVM on mainnet): relay clock skew can cause missed events. If you're using since filters to only grab recent signaling messages, add a 15-30 second lookback window. I lost requests early on because my subscription filter was too tight and relays had a few seconds of clock drift.

For the mobile ICE issues — have you tried including a TURN fallback? Symmetric NAT on cell networks blocks most peer-to-peer connections. Metered.ca has a free TURN tier that works well enough for signaling-only setups.

reply

Thanks for the detailed feedback. I already using NIP-44 for signaling and a TURN fallback (Metered). I'll look into adding a short lookback window for the since filter to handle relay clock skew. Appreciate it.

reply