nips icon indicating copy to clipboard operation
nips copied to clipboard

NIP-89: payto: Payment Targets

Open ATXMJ opened this issue 2 years ago • 19 comments

This is a NIP for adding support for the RFC-8905 "payto:" URI scheme standard for payment target invocations

ATXMJ avatar Feb 16 '23 00:02 ATXMJ

Would it be better to name the set_metadata field payto, rather than nip89?

ATXMJ avatar Feb 16 '23 00:02 ATXMJ

This looks fine, but would be great to have representatives of other shitcoins agreeing that this is the way to go so that tomorrow a proponent of Hive or Cardamom doesn't show up here proposing yet another field.

fiatjaf avatar Feb 16 '23 15:02 fiatjaf

This looks fine, but would be great to have representatives of other shitcoins agreeing that this is the way to go so that tomorrow a proponent of Hive or Cardamom doesn't show up here proposing yet another field.

Don't love the disingenuous "shitcoin" reference from a proponent for open and decentralized systems...

Nano clients don't even support this standard yet.

It's the only standard I've seen for universal payment target URIs.

It's not just for crypto. Should eventually be supported by just about every financial app in the same way that mailto: URIs are now supported by just about every email client and even many other more general communication clients.

It's even intended for adoption by Bitcoin clients.

ATXMJ avatar Feb 16 '23 16:02 ATXMJ

I'm not really familiar with it, but the RFC-8905 seems like an attempt at creating a new standard for implementing payments, which has obvious benefits. Do we know of any competing standards? If not, has this attempt at a standard had much traction anywhere (is it actively being used by anybody)?

brianhaugen avatar Feb 16 '23 16:02 brianhaugen

I'm not really familiar with it, but the RFC-8905 seems like an attempt at creating a new standard for implementing payments, which has obvious benefits. Do we know of any competing standards? If not, has this attempt at a standard had much traction anywhere (is it actively being used by anybody)?

I haven't found any competing standards, other than many other cryptocurrencies standardizing around similar schemes to the bitcoin: URI scheme.

It's hard to find any mainstream products leveraging payto: URIs, though it's a relatively new standard (originally proposed in October 2020), but there are references to it all over the web, as well as several open-source libraries available for generating and parsing payto: URIs for the most popular platforms and languages (Java/JVM, nodejs, Python, etc)

ATXMJ avatar Feb 16 '23 17:02 ATXMJ

It seems better than having a bunch of different fields for each possible payment network.

I just don't agree with the single payment icon for all of them. You need to tell the user what's in the field so that they know if they have the wallet installed that can reply to that specific payment request. Otherwise, we are just going to have a bunch of very confused users that click the button and nothing happens.

In fact, I would recommend that UIs add specific icons to all supported payment methods.

Also, I don't really know why the spec asks for reassembling the pay to URI if individual schemas should work fine. Meaning, why do: payto://bitcoin/bc1qxq66e0t8d7ugdecwnmv58e90tpry23nc84pg9k

if you can just do: bitcoin:bc1qxq66e0t8d7ugdecwnmv58e90tpry23nc84pg9k or lightning:bc1qxq66e0t8d7ugdecwnmv58e90tpry23nc84pg9k or iban:DE75512108001245126199

You can just pass the value along to the OS to resolve which app handles that URI.

In fact, I don't really know why this RFC 8905 even exists if it just adds payto:// to a set of already defined IANA schemes that can be used directly.

vitorpamplona avatar Feb 16 '23 18:02 vitorpamplona

Thanks for the reply!

I just don't agree with the single payment icon for all of them. You need to tell the user what's in the field so that they know if they have the wallet installed that can reply to that specific payment request. Otherwise, we are just going to have a bunch of very confused users that click the button and nothing happens.

Good point. Indeed, that could create confusion for users clicking the payment button and nothing happening. But how do we enable "payment target type"-specific icons/stylizations in a generalized manner?

I don't like the idea of having the client need to manually specify each one.

I also don't like the idea of having users somehow manually specify icons or stylizations.

While I don't love the idea, maybe we could have an official list of recognized target types in this NIP. Essentially adding a table of recognized target types along with their corresponding icon(s) and stylized names. At least this would allow for the addition of new recognized target types through open source PRs.

Thoughts on this?

Also, I don't really know why the spec asks for reassembling the pay to URI if individual schemas should work fine.

It's two-fold.

The idea is to create a standardized field and experience for payment invocations. If we allow a field that supports any URI scheme, users could put whatever deep link they want, potentially creating very undesirable actions for unexpectant users clicking on it. This could have some very serious security and safety implications.

Secondly, those individual URI schemes often have very different specifications. Using a universal standard for payment targets pushes just that: a universal standard with a consistent and expected behavior for nostr clients, payment clients, and users alike.

ATXMJ avatar Feb 16 '23 19:02 ATXMJ

Perhaps it may make sense to separate each value in the set_metadata nip89/payto field list into two separate fields, payment_target_type and authority.

For example

{
  "pubkey": "afc93622eb4d79c0fb75e56e0c14553f7214b0a466abeba14cb38968c6755e6a",
  "kind": 0,
  "content": "{\"nip89\": [
                                             {
                                                 \"payment_target_type\": \"bitcoin\", 
                                                 \"authority\": \"bc1qxq66e0t8d7ugdecwnmv58e90tpry23nc84pg9k\"
                                             }
                                         ]}"
  ...
}

This may reduce confusion for users, and make it easier for nostr clients to prompt users for these fields, potentially even using a simple form that lets them select one of the supported target types.

ATXMJ avatar Feb 16 '23 19:02 ATXMJ

"payment target type"-specific icons/stylizations in a generalized manner

I think the NIP text shouldn't say anything about icons or how information must be displayed. Clients can figure out what best serves the needs of their users. The same icons proposal doesn't work. Every platform/language/regulation has its own symbols.

If we allow a field that supports any URI scheme, users could put whatever deep link they want, potentially creating very undesirable actions for unexpectant users clicking on it. This could have some very serious security and safety implications.

Users will put whatever deep link they want. It doesn't matter what any NIP says. You can't block anything in Nostr. Clients already have to make sure they consider any URI, JSON, or binary content in every field. Otherwise, the app crashes or there might be unintended consequences. It's the same for any payment field specification.

Secondly, those individual URI schemes often have very different specifications. Using a universal standard for payment targets pushes just that: a universal standard with a consistent and expected behavior for nostr clients, payment clients, and users alike.

The different specifications will remain. RFC 8905 is not trying to standardize them. Just adding a prefix is not that useful.

vitorpamplona avatar Feb 16 '23 20:02 vitorpamplona

I think the NIP text shouldn't say anything about icons or how information must be displayed. Clients can figure out what best serves the needs of their users.

So you think it should be up to the clients to recognize payment target types and provide icons & stylizations? That doesn't seem like a good general solution to me, as it would make it hard for client developers to keep up with them all, and very hard for anyone to request a new target type be added for every client.

Users will put whatever deep link they want. It doesn't matter what any NIP says. You can't block anything in Nostr. Clients already have to make sure they consider any URI, JSON, or binary content in every field. Otherwise, the app crashes or there might be unintended consequences. It's the same for any payment field specification.

But we're talking about an experience intended to entice users to click these buttons/links with the explicit expectation of opening a relevant payment app.

I don't see any problem with clients validating and showing errors when a user is attempting to set payto: URIs for their profile, and validating them before displaying in the user profile.

Standardizing on RFC-8905 makes the validation process very simple and straightforward, regardless of which payment target type the user is specifying.

The different specifications will remain. RFC 8905 is not trying to standardize them. Just adding a prefix is not that useful.

They don't need to remain. RFC 8905 is indeed a standard to replace all the various existing schemes. It's not just adding a prefix, it's an entirely new standard for specifying all of the parameters for payment targets.

ATXMJ avatar Feb 16 '23 21:02 ATXMJ

Re: recognized payment target types

What if the NIP only provided a table of recommended target types for clients, with the target type "code", recommended textual stylizations, and a list of links to relevant resources for obtaining icons and other resources & assets?

For example:

Recommended Payment Target Stylizations & References

Payment Target Type Code Long Stylization Short Stylization Symbol References
bitcoin Bitcoin BTC https://bitcoin.design/
lightning Lightning Network LBTC https://github.com/shocknet/bitcoin-lightning-logo
cashme Cash App Cash https://cash.app/press
nano Nano XNO Ӿ https://nano.org/en/currency
venmo Venmo Venmo https://venmo.com/about/brand/
paypal PayPal PayPal https://developer.paypal.com/docs/multiparty/checkout/standard/customize/buttons-style-guide/
stripe Stripe Stripe https://stripe.com/payments/elements
zelle Zelle Zelle https://www.zellepay.com/disbursements/marketing-guide

ATXMJ avatar Feb 16 '23 21:02 ATXMJ

So you think it should be up to the clients to recognize payment target types and provide icons & stylizations? That doesn't seem like a good general solution to me, as it would make it hard for client developers to keep up with them all, and very hard for anyone to request a new target type be added for every client.

Client apps will have to always recognize and approve each individual method that shows up. There are too many security problems with accepting whatever valid URI comes into this field. The RFC already requires clients to support Internationalization and character encoding on a per-method basis. So, there is no chance this is going to be a "general solution". Clients will hardcode the payments they support in the way they see matching their user's needs.

Users will put whatever deep link they want...

You missed the point. You said, "If we allow a field that supports any URI scheme...". My answer is that the NIP process doesn't have the authority to "allow". People can always write whatever they want, relays will take it in and pass it forward. Scammers will do whatever it takes to fool a user. Client apps need to delete the trash when it arrives. So, in practice, we already have to check each method anyway. The NIP is just a guidance.

My point is that, no matter what this NIP says, a client will always make the incoming info work if it makes sense to their users. The NIP helps solidify a good practice in the input side. But there is absolutely no guarantees. It does not remove any of the work we already have to do to figure what each payment URI is about.

vitorpamplona avatar Feb 16 '23 22:02 vitorpamplona

Client apps will have to always recognize and approve each individual method that shows up. There are too many security problems with accepting whatever valid URI comes into this field.

It's not a recommendation to "accept whatever valid URI comes into the field". It would only be to accept validly formatted payto: URIs. Parsing and validation of the payto: URI scheme would only need to be implemented once by the client developer, and they can likely do so with some of the open source payto: URI libraries that already exist.

By adopting this universal standard URI scheme for payment deep links, we can significantly reduce the amount of work needed by client developers to add support for new payment target types, right?

It would essentially reduce the work needed to just adding/linking the corresponding icon (and maybe a couple other stylizing configurations) for each added payment target type. There would be no need to do any new parsing or validation of the URIs for new targets types.

Maybe I'm missing your point here?

My answer is that the NIP process doesn't have the authority to "allow". People can always write whatever they want, relays will take it in and pass it forward. Scammers will do whatever it takes to fool a user. Client apps need to delete the trash when it arrives. So, in practice, we already have to check each method anyway. The NIP is just a guidance.

Right, but like I said, if we standardize around the payto: URI scheme, most clients should do validation on user entry to avoid accidental malformed entry, and can do validation on reading the notes to ensure that the "trash" is removed prior to embedding in user profiles.

The point is that this is all far simpler if we have a single standard for parsing and validating these values than it would be if separate parsers and validators were needed for each new payment protocol URI.

Of course the NIP can't "enforce" or "require" this parsing and validation by clients on user entry or rendering, but it would allow them to do so with a single recommended standard.

Is your argument that allowing for any properly-formed payto: URI might create security/safety vulnerabilities?

If so, then I think the recommendation to use a list of recognized target types (as described in previous comments), whether or not there is a recommended list of supported target types in a NIP, would mitigate this concern, right?

ATXMJ avatar Feb 17 '23 00:02 ATXMJ

It would only be to accept validly formatted payto: URIs

Clients cannot just generally accept validly formatted payto. That's what I am saying. I know this feels like a bummer, but it's true :)

By adopting this universal standard URI scheme for payment deep links, we can significantly reduce the amount of work needed by client developers to add support for new payment target types, right?

That is not a lot of work compared to the rest of the work to support each payment type (parsing amount, preparing descriptions, etc). Since you already have to investigate how each method works and what information it needs to be displayed/captured in what encoding, etc, the work of adding an icon is not a lot. If that is the motivation for the NIP, it's not a good one. :)

vitorpamplona avatar Feb 17 '23 01:02 vitorpamplona

Clients cannot just generally accept validly formatted payto. That's what I am saying. I know this feels like a bummer, but it's true :)

To be more specific, it's a suggestion to generally accept any valid payment_target_type and authority for generating a payto URI, not necessarily to blindly accept any payto URI.

But regardless, why couldn't the client just generally accept any validly formatted payto URI?

That is not a lot of work compared to the rest of the work to support each payment type (parsing amount, preparing descriptions, etc). Since you already have to investigate how each method works and what information it needs to be displayed/captured in what encoding, etc, the work of adding an icon is not a lot.

I think you're misunderstanding the intention a bit.

With this proposal, there will be no need for clients to "investigate how each method works and what information it needs to be displayed/captured in what encoding, etc".

The entire intention of this NIP is to generalize that process to be the same for all payment networks.

The only work needed from the client is

  • on input, allow the user to specify a payment_target_type and authority of their choice
  • on input, optionally do some minimal validation on those fields in a generalized way that applies to any payment network
  • on observation, optionally do some minimal validation on the specified payment_target_type and authority fields
  • check if the payment_target_type is recognized
  • assemble a payto:// deep link URI, with the corresponding icon/stylization configuration for recognized payment_target_type values
  • embed the assembled URIs as a buttons/links/dropdown in user profiles, posts, chats, etc

And in order to add new payment networks to the client's recognized payment networks, the only work needed would be to add the new payment_target_type and corresponding icon/stylization configuration to the client's map of recognized payment_target_type values

ATXMJ avatar Feb 17 '23 18:02 ATXMJ

But regardless, why couldn't the client just generally accept any validly formatted payto URI?

I also don't see why a client cannot just generally accept any validly formatted payto URI. An application has to register to handle the payto uri, so it seems that it is the responsibility of the receiving application to ensure that it can safely parse it.

Also, I don't really know why the spec asks for reassembling the pay to URI if individual schemas should work fine.

If the application didn't reassemble the URI, then you could accidentally dangerously link into another application and you would have to manually check each link. In the case of payto, the client just has to make sure its a payto link and then it is safe to display it because it would only ever be routed to apps that said they could handle it.

UncleSamtoshi avatar Feb 23 '23 03:02 UncleSamtoshi

For context, I am interested in this NIP, because I want to improve the zap experience by having zap invoices be automatically paid instead of having to switch to your lightning wallet to pay the invoice.

I was thinking that there could be some kind of event that was a request to pay a bolt11 invoice, and then in your profile metadata you would specify an lnurl withdraw endpoint that the client could automatically send payment request notes to. So when you zapped someone, the client would create a payment request note with the invoice and then automatically send it off to get paid.

I was looking to see if there was anything similar and NIP 89 seemed slightly on the radar. However, I was thinking more along the lines of a specific event that requested a payment instead of just profile metadata.

UncleSamtoshi avatar Feb 23 '23 04:02 UncleSamtoshi

@UncleSamtoshi yeah I had been thinking about similar experiences being built on top of this NIP, namely an event type for logging when a user sends a payment to another user.

Lightning in particular is a little unique in that it needs an invoice to be generated, so I hadn't really spent much time thinking on that.

But allowing for optional tracking of user-to-user payments could provide an interesting experience. It could potentially even be used as a prioritization mechanism: eg "sort my feed by most tipped notes", and for activity insights.

But I think that should all be considered separate from this NIP.

ATXMJ avatar Feb 23 '23 06:02 ATXMJ

@UncleSamtoshi yeah I had been thinking about similar experiences being built on top of this NIP, namely an event type for logging when a user sends a payment to another user.

This isn't quite what I'm thinking. I essentially want a wallet connect feature, so that zaps and other invoices can be automatically paid without having to leave the client. In order to accomplish this, I think it makes sense to create a new event that represents a request to pay some kind of invoice. In the case of zaps, the client could construct a request payment note and then send it to a lnurl withdraw endpoint that was configured in your profile. However more generally, you could imagine seeing in your feed someone creating a payment request note, and then the client could display a button to click and pay it.

The overlap between that and this nip could be the payment request being a payto link.

UncleSamtoshi avatar Feb 23 '23 14:02 UncleSamtoshi

@fiatjaf what else does this PR need for merge?

ATXMJ avatar Mar 09 '23 01:03 ATXMJ

It's been months. What else is needed to merge this PR?

ATXMJ avatar May 15 '23 08:05 ATXMJ

Would be better to put the data in tags rather than JSON in content so that it can be consumed directly and easier to be denormalized in relay databases etc.

It's been months. What else is needed to merge this PR?

Where is this implemented?

gsovereignty avatar Aug 14 '23 08:08 gsovereignty

It's been months. What else is needed to merge this PR?

Where is this implemented?

Our team is building a client that will implement this feature.

gemmyclub avatar Aug 16 '23 04:08 gemmyclub

I won't rewrite this. I'd recommend calling it type instead of payment_target_type

Semisol avatar Sep 07 '23 21:09 Semisol