I've been building monostr for a few weeks: an Android Nostr client where the "zap" is a Monero tip. No Lightning, no custodian, no KYC wallet in the middle.
How it works: you register your primary address and private view key with a watcher (the same trust model as stasher.news, which is where I took the idea from). The watcher sees incoming payments, never spends, and publishes a signed tip receipt on Nostr, so any client can show the tip under the note. Paying is a plain monero: link: tap ɱ under a note or on a profile, pick an amount, and Cake, Monerujo, Feather or whatever wallet you use opens with the payment. Likes stay free. Tips can be anonymous (default).
What's there today: feed with separate Posts/Replies tabs, threads, profiles, quotes, reposts, likes and emoji reactions (undo included), tips on notes and profiles (XMR or mXMR), NIP-17 DMs, picture upload to our own Blossom server, mutes, private bookmarks, search, optional proof of work, Amber (NIP-55) or key login, light/dark/OLED black, 8 languages. Own relay at relay.monostr.com. AGPL, everything in one repo (app, watcher, relay, media server), reproducible release builds.
What it is not: no iOS, no embedded wallet, one watcher running (the protocol is federated, the watcher URL lives in your profile, but mine is the only public one so far). Expect beta bugs; releases come every few days.
I'd like feedback from people who actually tip in XMR: does the flow make sense, what's missing before you'd use it daily?
Get it: Zapstore (zapstore.dev/apps/com.monostr.app), GitHub releases (also works with Obtainium); F-Droid is in review. Site: monostr.com · Source: github.com/schmidt1024/monostr
Nice work, I was also thinking about integrating Monero in Nostr recently. Your protocol document also looks very interesting, though I needed a translation since it's only in German. Here's my feedback:
General
I think you're assuming Watchers to be big centralised services that run on their own internet domains (probably alongside their own Nostr relay infrastructure).
I'm not against lightweight wallet service itself, but the specification should leave out some room for individual users to be able to become self-custodial.
In my opinion, watcher should be able to run on any computer that is always online; ideally, even smartphones could become a watcher and sync the wallet periodically (e.g. every 1 hour) and watch for tips. This way users can avoid giving out private view keys to big watcher providers with minimal friction.
Payment-Info (kind 10037)
watchertag expects its own internet domain as the first argument. Your 'Watcher HTTP API' section implies all watchers must expose an HTTP server. This is just too big of a burden. The HTTP API can be replaced with encrypted messages on Nostr, if such an interaction is absolutely required.["watcher", "<watcher-hex-pubkey>", "<optional-relay>"]? This way, if relay is not specified, it would imply payer can send tip intent events to any inbox relay of the tip recipient.watchertag itself can be optional, in this case it would mean the tip recipient can watch and sign payment receipts using her own pubkey.Tip-Intent (kind 9738)
HMAC-SHA256("<payer-pubkey>", "<recipient-pubkey>:<note-id>:<nonce>"), but I don't think it is worth complicating the specification. Simply mentioning clients should generate payment IDs using a secure pseudorandom algorithm would be sufficient.Tip-Receipt (kind 9739)
typetag is for. Maybe omission can be the default, and the tag can be optionally set to indicate other modes of payment?Sorry for being a bit harsh (maybe too toxic), but that is what went through my mind when reading the proposal. Further criticism and discussion are welcome :)
Your idea made it into 0.17: the watcher can now be addressed by its pubkey and relays instead of a domain. It runs on your own machine without a node or domain; the app sets it up from an nprofile. https://github.com/schmidt1024/monostr/blob/main/watcher/SELFHOST.md
Thanks, this is exactly the kind of review I was hoping for; not harsh at all.
pid: agreed. The app already uses a CSPRNG. It is now a MUST. The watcher accepts only the first intent per (recipient, pid) so a predictable pid would let someone front-run an intent and claim another person's payment. I kept random pids rather than HMAC derivation, since the intent is public anyway and fresh randomness is the simplest thing to get right.
type tag: it's display-only, so clients can count a tip that was coupled to a like or repost on that button instead of listing it as a separate tip. A missing tag now means tip. App and watcher still always write it, so older versions don't break.
Both changes are done (spec v0.3) and will ship with the next release.
Personal watchers / pubkey instead of domain: this is the strongest point and I think you're right. Running a watcher shouldn't need a domain, TLS and an HTTP API. ["watcher", "<pubkey>", "<relay>"] plus encrypted Nostr messages for registration would let anyone run one on a home box and an optional tag fits that model too. That's a bigger change to spec, watcher and app, so it won't be in the next release. I want to design it properly first, but it's now at the top of the protocol list.
No txid: glad we agree.
Nice work. The flow makes sense for someone who already tips in XMR. One thing worth saying louder, for Stashers and monostr users both -- the watcher does not only see tips. A view key on the primary address sees every incoming payment to it. The receipt then publishes the tip amount on Nostr, so the amount privacy Monero gave you is gone on the social side. Fine if that address is only for tips. Less fine if it is the one you actually use.
Update: both points are addressed now. 0.17: a personal watcher runs on your own machine, so the view key never leaves you. 0.18: tip amounts are hidden by default, intent and receipt no longer carry the amount. Guide: https://github.com/schmidt1024/monostr/blob/main/watcher/SELFHOST.md
that's why setup tells you to use a separate wallet just for tips and offers to create a fresh one right there. The watcher sees every incoming payment to that wallet (!) and the receipt makes amount + recipient public by design (that's what makes tips visible under notes, like zaps). Senders can stay anonymous; amounts can't. If you want zero exposure, run your own watcher.
Awesome. Just downloaded it and checking it out.
FWIW: I run a paid Monero relay. 0.007 XMR to have write access forever. Just a way to tailor content to Monero users and fight spam.
https://xmr.ithurtswhenip.ee
wss://xmr.ithurtswhenip.ee
Been using this for a couple days and I really like it. It's the first client that I've used that's managed to replace Primal for me, which I knew I had to leave, but didn't have a good option to go to
Update: Since this post, monostr got two changes that answer the main concerns raised here:
If you'd rather run a full watcher with your own node, for yourself or for others: https://monostr.com/watcher/self-host/
Feedback welcome, here or on Nostr.
we need more desktop clients
i'm slowly getting rid of smartphone for good