pull down to refresh

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)

  • Again, the watcher tag 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.
  • Why not have ["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.
  • Maybe the watcher tag 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)

  • Payer unilaterally deciding the payment ID looks fine, although I concern some security implications. I once thought payment IDs could be derived in somewhat more deterministically random process, something like 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.
  • The current way has some advantages over alternatives, e.g. asking recipient to generate a subaddress or payment ID; other methods would require the process to go through more steps (payer publishes tip intent → recipient gives an address → payer pays XMR (outside Nostr) → recipient or watcher confirms receipt), which means more problems (How do recipients manage subaddresses? Should the address be sent encrypted to payer? etc.). So I'm okay with keeping with the current proposal.

Tip-Receipt (kind 9739)

  • I also think not containing txid in the receipt is the way to go. This does place some trust on the watcher, and there is some hypothetical issue of watchers manipulating fake tip receipts. But such dishonesty can be discovered by other means, and it is also discouraged by social incentives (it hurts watcher's reputation, whether or not it's a big central service or just a recipient running her own watcher).
  • It also appears on Tip-Intent event, but I don't know what the type tag 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

reply

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.

reply