Skip to content

Conversation

@Crypto2099
Copy link
Collaborator

@Crypto2099 Crypto2099 commented Jun 16, 2024

Rendered Version

This proposal seeks to extend the CIP-13 payment URIs and address some of the issues raised here: #836

We need an enhanced and more explicit Payment type of Cardano URI in the modern era of native assets, smart contracts, and transactional metadata.

Because of legacy integrations with existing URI payments (lacking a dedicated authority) I have chosen to break this extension out into a new CIP with an explicit authority to avoid having to change or update CIP-13.

@rphair
Copy link
Collaborator

rphair commented Jun 16, 2024

@Crypto2099 good to have a stub here for the current discussion of how a comprehensive and ambiguity-free payment URI syntax would look. Cross-referencing my #836 (comment) and #836 (comment) to be sure scenarios involving these boundary cases will be handled properly by any proposed syntax:

  • keyword(s) used to specify metadata collide with token name(s)

... including these cases if payment handles are supported by this protocol (I would insist that they should be):

  • payment handles (if supported by this protocol) are ambiguous as per CPS-0008? | Domain Name Resolution #605 (cc @SIDANWhatever)
  • keyword(s) used to disambiguate payment handles collide with token name(s)
  • payment handles collide with bare payment addresses (unlikely but possible)

@Crypto2099
Copy link
Collaborator Author

Thanks @rphair excited to start the conversation and hoping to have some first-draft specs delivered over the course of the next week for discussion! These are great starting points for consideration though!

@rphair
Copy link
Collaborator

rphair commented Jun 16, 2024

you're welcome @Crypto2099 & if you feel potential specs could use community brainstorming then feel free to add this to the agenda in a week-plus time: https://hackmd.io/@cip-editors/91

@MadOrkestra
Copy link
Contributor

MadOrkestra commented Jul 7, 2025

Quick heads up: beginWallet implemented a "CIP13-like" solution now (https://x.com/BeginWallet/status/1941614893691724100) - so I'll leave this here as starting point for a discussion to turn this into a standard CIP addressing at least some of the downfalls of the original payment scheme.

the beginWallet URI scheme @francisluz already implemented looks like this:
web+cardano:addr?amount=1&token=ADA&paymentID=123-ABC&note=abcdedafad

What it solves

  • Payments with other tokens than ADA (think USDM)
  • Linking payments to offchain data (to link a payment to a shopping cart of whatever)

What it doesn't solve / Downfalls

  • Transactions with multiple tokens
  • Uses a ticker symbol instead of a policyId
  • Not using the //payment authority

I think the biggest issue here is the ticker symbol and the centralized whitelists that have to come with it to convert the ticker into a policyId to build the transaction. But: I think we have to abandon the original idea of multiple assets to fit into a payment URL anyways, because while URLs can be quite lengthy today in most modern browsers (up to 10,000 characters or something), the bottleneck is the QR-Code with "only" 300-500 characters before the "scanability" decreases massively, which especially for the use case of providing a slick and quick payment method is a no-go.

If we were to go with policyIds instead of ticker symbols, the overall character length excluding the note/msg field would still perfectly fit within these limitations:

  • Identifier, params and stuff: 43+ Characters
  • Amount: 1 to whatever (100bn are still only 12 digits)
  • Bech32 Address: 104 Characters
  • PolicyId: 56 Characters
  • PaymentID/Note: 32-36 Characters (for UUIDv4 e.g., could be shorter or longer ofc)

I think the dedicated paymentId field is debatable, as long as you can put some metadata into a transaction via URL, we cover a lot of use cases.

Given that we've spent another year or so without proper definition of this very rudimentary functionality on Cardano, I'd rather see this moving quickly now and enabling stable coins or Hosky or whatever as possible payment method across the ecosystem instead of looking for the perfect solution while seeing wallets coming up with their own individual solutions, but thats just my take ofc.

@rphair
Copy link
Collaborator

rphair commented Jul 7, 2025

thanks @MadOrkestra - this covers everything I would have said. Just one clarification though (cc @francisluz):

What it solves

  • Payments with other tokens than ADA

When paying a non-Ada token, is the minimum amount of ada (to carry the tokens) implicit in the transfer?

@francisluz
Copy link
Contributor

francisluz commented Jul 7, 2025 via email

@rphair
Copy link
Collaborator

rphair commented Jul 7, 2025

p.s. regarding the "unresolved" points (we can discuss in person tomorrow):

What it doesn't solve / Downfalls

  • Transactions with multiple tokens
  • Uses a ticker symbol instead of a policyId

These 2 points go together. The discussion I raised in #836 (comment) about a general design to include multiple native token transfers could be trumped (after another year of scams) by some practical insecurity of using ticker symbols:

  • We would have to assume, until demonstrated otherwise, that fake tokens with the same ticker as real ones might be used to spoof users through such a payment URL scheme.
  • Even without the threat of malicious usage, we would still need a rigorously defined selection process to determine an exact Policy ID from a ticker name.

Such improvements, if we can make them, would provide a way around the URL length problem and fit poly-token transfer URLs into QR codes.

  • Not using the //payment authority

This alone currently makes the Begin Wallet / @francisluz solution outlined in #843 (comment) non-CIP-0013-compliant. "We" (the general community?) could simply wash our hands of this and apply future discussion of a cooperative standard (as per #836 (comment)) into a complete CIP for //payment links: especially since without that authority term, it can't comply either with CIP-0013 or the extension proposed in #843 for which //payment has been slated (though not set in CPS-0016 yet).

@Crypto2099 Crypto2099 marked this pull request as ready for review July 9, 2025 06:12
@Crypto2099
Copy link
Collaborator Author

Thanks to @MadOrkestra and @francisluz for finally dragging this one out of the shadows and into the light for some proper definition and refinement. I've done my best to try and stay close to the version as implemented by Begin (as slurped from generating a payment request URI in their app) while still extending the definition a bit, particularly for supporting multiple native assets and moving away from a ticker whitelist.

Note that we do fall back to a bech32 representation of native assets because this allows for a predictable-length URI regardless of the token name (which can be an additional 32-bytes in addition to the policy ID, particularly tricky for NFTs) which should still allow wallets to maintain a "known whitelist" of their own for popular tokens such as USDM and HOSKY and others.

@rphair rphair added Category: Wallets Proposals belonging to the 'Wallets' category. State: Triage Applied to new PR afer editor cleanup on GitHub, pending CIP meeting introduction. labels Jul 9, 2025
Copy link
Collaborator

@rphair rphair left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking forward to confirming this at the next meeting (https://hackmd.io/@cip-editors/116) and recording the feedback here from any interested parties especially @MadOrkestra @francisluz and any other implementors following this issue.

I might only be half-complete tagging reps from other wallets besides Begin, so please I will leave that to @MadOrkestra @Crypto2099 @Ryun1 - with invitations to that meeting & calls for review and suggestions all around this proposal. (Normally we would wait 1 more meeting cycle for detailed Review after Triage first, but time seems essential because of the implementation in progress.)

@rphair rphair changed the title CIP-???? | Cardano URIs - Enhanced Payments CIP-0157? | Cardano URIs - Enhanced Payments Jul 23, 2025
@rphair rphair added State: Confirmed Candiate with CIP number (new PR) or update under review. and removed State: Triage Applied to new PR afer editor cleanup on GitHub, pending CIP meeting introduction. labels Jul 23, 2025
Copy link
Collaborator

@rphair rphair left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work finally bringing this home @Crypto2099 - candidacy confirmed @ yesterday's CIP meeting & please update the document & directory name accordingly 🎉

Personally I expect to ✅ this soon but want to give it one more detailed read when settled again from travelling around the end of this week: especially cross referencing with CIP-0013 family members & #1058.

@MadOrkestra
Copy link
Contributor

MadOrkestra commented Jul 24, 2025

Way more complex than I initially thought, but great job @Crypto2099

I have one thing to at least think about: As per RFC3986 "|" (used to separate the asset count here) is not allowed as unencoded character in URLs. Not sure if this can cause problems with individual URL schemes like web+cardano, but it might be worth looking into?

@Crypto2099
Copy link
Collaborator Author

Way more complex than I initially thought, but great job @Crypto2099

I have one thing to at least think about: As per RFC3986 "|" (used to separate the asset count here) is not allowed as unencoded character in URLs. Not sure if this can cause problems with individual URL schemes like web+cardano, but it might be worth looking into?

Thanks for the heads up on this, I will take a look and pivot the standard to use a URI-safe character

Co-authored-by: Robert Phair <[email protected]>
@MadOrkestra
Copy link
Contributor

MadOrkestra commented Jul 25, 2025

I have one thing to at least think about: As per RFC3986 "|" (used to separate the asset count here) is not allowed as unencoded character in URLs. Not sure if this can cause problems with individual URL schemes like web+cardano, but it might be worth looking into?

Thanks for the heads up on this, I will take a look and pivot the standard to use a URI-safe character

Sorry, didn't have too much time for this earlier... my understanding of RFC 3986 is, it it basically comes down to one of these:

- . _ ~ ! $ ( ) * + ;

So unless we wanna drive every single dev out there mad with bringing back the good old tilde or cause confusion with a semicolon, I think ?t=asset1*amount1,asset2*amount2 is the logical way to go? Amounts could be optional (1 if not set - to save URL characters) and have a decimal point too (if needed) - with no URL encoding necessary at all.

@Crypto2099
Copy link
Collaborator Author

I have one thing to at least think about: As per RFC3986 "|" (used to separate the asset count here) is not allowed as unencoded character in URLs. Not sure if this can cause problems with individual URL schemes like web+cardano, but it might be worth looking into?

Thanks for the heads up on this, I will take a look and pivot the standard to use a URI-safe character

Sorry, didn't have too much time for this earlier... my understanding of RFC 3986 is, it it basically comes down to one of these:

- . _ ~ ! $ ( ) * + ;

So unless we wanna drive every single dev out there mad with bringing back the good old tilde or cause confusion with a semicolon, I think ?t=asset1*amount1,asset2*amount2 is the logical way to go? Amounts could be optional (1 if not set - to save URL characters) and have a decimal point too (if needed) - with no URL encoding necessary at all.

The asterisk should do the job nicely without causing too much confusion (like the dash or plus sign would). I think we can stick to whole-integer representation since the ledger does not natively understand Native Asset decimals anyway and wallets need to build the transaction with the whole integer amount of the native asset in question. I do agree that removing *1 also seems a logical default to save characters and space.

- Added initial version information to URI
- Expanded abbreviated addresses and asset IDs
- Clarified some info on token parameters such as whole integer quantities and making quantity default to 1 if not otherwise specified
- Switch from pipe character to the use of an asterisk for the quantity separator for RFC compliance
@Crypto2099
Copy link
Collaborator Author

The devs from Vespr pointed out to me that very few wallets and none of the current data providers (Koios, Blockfrost, etc) support querying assets by their fingerprint. While I feel that the fingerprint is preferable due to being a fixed-length string so having predictable URLs lengths is ideal, for ease of implementation we should probably at least make an update to also support the traditional <policy_id>.<asset_id> format for sending tokens

@AlexDochioiu
Copy link

Appreciate the update to support asset unit @Crypto2099 🙏🏻

@AlexDochioiu
Copy link

@Crypto2099 I'd add an explicit remark in the CIP that token quantity is not decimals adjusted. (token quantity is always int / bigint ; never float or decimal)

Kingsleyioryoo

This comment was marked as abuse.

Copy link
Collaborator

@rphair rphair left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I just posted for candidate CIP-0158 (Browse Authority) (#1058 (review)) I believe this has all the elements of a proper CIP: with exhaustive detail & pre-emptive consideration of valuable use cases.

I think it is especially valuable that an ABNF grammar has been included: not because it will be automatically parseable or useful in validating URI syntax, but to eliminate ambiguities & edge cases that could otherwise emerge between different wallets & apps.

So as also posted for the parallel candidate CIP I am tentatively ✅ing this proposal as we begin the inevitable period of convergence between in-progress implementations (thanks @AlexDochioiu) and the standard expressed in ideal form.

If implementors ever think it would help to brainstorm in a "working group" setting around particular syntax / interpretation challenges for either of these proposals, please post to say so here and I'll put it up for Review on the CIP agenda.

Comment on lines +283 to +284
* [ ] At least one wallet supports this payment standard
* [ ] At least one project using this payment standard
Copy link
Collaborator

@rphair rphair Jul 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I also posted in #1058 (comment) @Ryun1 (our usual parameter setter for this, or @perturbing or any other community reviewer) may think this should be increased from 1 to 2 or maybe more.

Personally I think 1 is fine on each side (producer + consumer) due to reasons of inevitable imitation that I mentioned in the other comment: but will agree to increase it if other editors request.

@Crypto2099 I do think the term project needs to be elaborated, since wallets are also "projects" — whatever it takes to establish that the "producer" and "consumer" of payment URIs are distinct projects. As we mentioned at the meeting I think it would also help to specify that those 2 projects should be from distinct vendors... a statement that would also support the Path to Active credibility of #1058.

Copy link
Contributor

@MadOrkestra MadOrkestra Jul 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just FYI, the OG CIP13 stated "one or more wallets" as acceptance criteria - no mention of projects whatsoever, so this is already a neat step up ;)

Maybe lets go with "At least one website using this payment standard" instead of project? Or maybe thats exactly Adams point, as a project using QR-Codes for payments doesn't necessarily need to be a website (which is the beauty of this...)

@MadOrkestra
Copy link
Contributor

Just revisited the state of CIP13 integrations: Yoroi is the only mobile wallet supporting the web+cardano:addr scheme, Vespr went with web+cardano://addr (which - from what I hear - is actually needed for apps to enable proper deeplinking)

So yeah, can't stress enough how important it'd be to finish this CIP and pressure every wallet into supporting this, so we can maybe in 2026 pay with ADA by phone...

@rphair
Copy link
Collaborator

rphair commented Dec 10, 2025

@Crypto2099 you're the best candidate I can think of to bring together all possible approaches to this... so please let us know what you think needs to be done & editors will do anything possible to ensure it's merged promptly: with no time to waste, as @MadOrkestra says 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Category: Wallets Proposals belonging to the 'Wallets' category. State: Confirmed Candiate with CIP number (new PR) or update under review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants