Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CIP-0013 | Generalise for further protocols #559

Merged
merged 15 commits into from
Aug 1, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 71 additions & 37 deletions CIP-0013/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ Title: Cardano URI Scheme
Status: Proposed
Category: Wallets
Authors:
- Robert Phair <rphair@cosd.com>
- Sebastien Guillemot <sebastien@emurgo.io>
- Vicente Almonacid <vicente@emurgo.io>
- Robert Phair <rphair@cosd.com>
Implementors: N/A
Discussions:
- https://github.com/Emurgo/EmIPs/pull/2
Expand All @@ -15,16 +15,25 @@ Discussions:
- https://github.com/cardano-foundation/CIPs/pull/61
- https://github.com/cardano-foundation/CIPs/pull/86
- https://forum.cardano.org/t/cip-stake-uri-scheme-for-pools-delegation-portfolios/40594
- https://forum.cardano.org/t/cip-generalized-cardano-urls/57464
- https://github.com/cardano-foundation/CIPs/pull/546
- https://github.com/cardano-foundation/CIPs/pull/559
Created: 2020-09-22
License: CC-BY-4.0
---

## Abstract

This proposal describes a basic URI scheme to handle Ada transfers and links to single stake pools or weighted lists of multiple pools.
This describes a general standard URI scheme with two specific protocols to handle Ada transfers and links to weighted lists of stake pools.

## Motivation: why is this CIP necessary?

### In general:

Developers of protocols that use URI schemes should be able to choose unique protocol keywords indicating how these links are handled by applications.

Beyond the two earliest defined protocols below, protocols using distinct keywords (e.g. `//stake`) can be defined in other CIPs and implemented without ambiguity by applications which interpret those particular URI protocols.

### For payment URIs:

Users who create community content often want donations as a financial incentive. However, forcing users to open their wallet and copy-paste an address lowers the amount of people likely to send tokens (especially if they have to sync their wallet first).
Expand All @@ -49,74 +58,79 @@ URIs for weighted stake pool lists provide alternatives to using a JSON file to

The core implementation should follow the [BIP-21](https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki) standard (with `bitcoin:` replaced with `web+cardano:`)

Rationale:
- Use `cardano:` over `ada:` as other projects that implement this standard tend to take the project name over the currency name (this makes sense if we consider this protocol as a generic way for interacting with the blockchain through wallets - as opposed to a simple payment system)
- Many wallets support multiple currencies. Following the same standard will ensure higher adoption of our protocol.

Examples:
```
<a href="web+cardano:Ae2tdPwUPEZ76BjmWDTS7poTekAvNqBjgfthF92pSLSDVpRVnLP7meaFhVd">Donate</a>
Copy link
Collaborator

Choose a reason for hiding this comment

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

<a href="web+cardano:Ae2tdPwUPEZ76BjmWDTS7poTekAvNqBjgfthF92pSLSDVpRVnLP7meaFhVd">Donate</a>

Is there a reason why this URI schema has persisted to this point lacking the two forward slashes? (//)

Since we are looking to standardize this and prepare for future expansion, would it be safe to require that web+cardano:// always be present?

Further, should we consider a "pay to" authority rather than defaulting to hoping that it is a valid address?

Copy link
Collaborator Author

@rphair rphair Jul 25, 2023

Choose a reason for hiding this comment

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

The URI spec only has a // when the authority field is present; this from the Wiki page (which is quoting the RFC) & itself an ABNF grammar... either the // and the authority or present together or neither of them are present, so // is definitely not a requirement for all URIs:

URI = scheme ":" ["//" authority] path ["?" query] ["#" fragment]

To disambiguate your middle question: for our URI spec, web+cardano: always has to be present but // does not.

We are locked into supporting the payment links without an authority because for a long time that was the only implementation of these URIs that was getting professional consideration (someone suggested stake pool links in 2018 but nobody ever moved on it; timeline & links are in the PRs at the Discussion links).

As far as I know Yoroi in particular has supported payment links with only a path-query string that whole time: about 5 years now. If I had to tell them they needed to commit to honouring an authority prefix (let's call it //payment) I would therefore expect about 5 years to get a response.

For some of the reasons in #559 (comment), I'd be open to a new CIP with a //payment schema supporting a more developed syntax, but in the meantime those 2 interpretations (payment vs. authority) of everything after the : can never collide: because one never has // and the others always do.

The "hope" that a payment address is valid would have been considered by editors when this CIP was originally debated from original authors @SebastienGllmt and @v-almonacid for that part of the scheme. I believe it's not in the CIP because it's not the URI's "job"... how a wallet or perhaps a dApp would handle a URI with an invalid payment address would be up to the designers.

One application for a further //payment protocol (with a separate CIP) might be to use higher-level addresses e.g. AdaHandles. In fact it could create a beautiful range of possibility (e.g. multiple and/or proportional payments): all of which are beyond the scope of this CIP which is basically becoming a switch to get to newly defined protocols for everything not considered 3 to 5 years ago.

Choose a reason for hiding this comment

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

We are locked into supporting the payment links without an authority because for a long time that was the only implementation of these URIs that was getting professional consideration (someone suggested stake pool links in 2018 but nobody ever moved on it; timeline & links are in the PRs at the Discussion links).

As far as I know Yoroi in particular has supported payment links with a bare path-query string that whole time: about 5 years now. If I had to tell them they needed to commit to honouring an authority prefix (let's call it //payment) I would therefore expect about 5 years to get a response.

Personally I think it's not too late to change the URI scheme to add an authority for payments, if that's what you think is best (I do). And while it is difficult to say whether there is a lot of people using payments URIs right now with Yoroi, I don't think it's a big deal to add this breaking change. But it'd be better of course if you try to get feedback from wallet providers first.

how a wallet or perhaps a dApp would handle a URI with an invalid payment address would be up to the designers

Exactly

<a href="web+cardano://stake?c94e6fe1123bf111b77b57994bcd836af8ba2b3aa72cfcefbec2d3d4">Stake with us</a>
<a href="web+cardano://stake?POOL1=3.14159&POOL2=2.71828">Split between our 2 related pools</a>
<a href="web+cardano://stake?COSD">Choose our least saturated pool</a>
<a href="web+cardano://claim/v1?faucet_url=https%3A%2F%2Fclaim.hosky.io&code=consensus2023">Claim $HOSKY</a>
```

### Considerations
The protocol term (e.g. `//stake`) is called the _authority_ as defined in [Wikipedia > Uniform Resource Identifier > Syntax](https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Syntax).

1. BIP-21 is limited to only features Bitcoin supports. A similar feature for Ethereum would, for example, also support gas as an extra parameter. BIP-21 is easily extensible but we have to take precaution to avoid different wallets having different implementations of these features as they become available on Cardano. To get an idea of some extra features that could be added, consider this (still under discussion) proposal for Ethereum: [EIP-681](https://eips.ethereum.org/EIPS/eip-681)
### Choice of URI scheme name

2. Depending on the protocol registration method (see next section), browsers generally enforce a `web+` or `ext+` prefix for non-whitelisted protocols (note: `bitcoin:` was whitelisted; see [registerProtocolHandler > Permitted schemes](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/registerProtocolHandler#permitted_schemes)). The prefix `ext+` is recommended for extensions, but not mandatory (see [protocol_handlers](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/protocol_handlers)).
`cardano:` is chosen over `ada:` because other projects that implement this standard tend to take the project name over the currency name (this makes sense if we consider this protocol as a generic way for interacting with the blockchain through wallets and dApps - as opposed to a simple payment system).

### ABNF Grammar (Proposal)
Depending on the protocol registration method (see Rationale), browsers generally enforce a `web+` or `ext+` prefix for non-whitelisted protocols (note: `bitcoin:` was whitelisted; see [registerProtocolHandler > Permitted schemes](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/registerProtocolHandler#permitted_schemes)). The prefix `ext+` is recommended for extensions, but not mandatory (see [protocol_handlers](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/protocol_handlers)).

This is an initial, simplified protocol definition for fast implementation; it only requires:
### Grammar & interpretation

* for a payment URI (authority unspecified), an address and an optional amount parameter;
* for a stake pool URI (authority = `stake`), a weighted list of one or more stake pools.
This top-level definition is mainly to allow switching to a particular protocol for each separately defined `authority`, with a payment link being the default:

As discussed above, these rules are likely to evolve in order to support other capabilities of the Cardano blockchain.
* When `authority` is unspecified, it is a payment URI (with an address and an optional amount parameter;
* When `authority` is explicit (containing `//` followed by the authority keyword), it is defined in the `//stake` case below or in a separate CIP for that protocol.

```
cardanourn = "web+cardano:" (paymentref | stakepoolref)

paymentref = cardanoaddress [ "?" amountparam ]
cardanoaddress = *(base58 | bech32)
amountparam = "amount=" *digit [ "." *digit ]

stakepoolref = "//stake" stakequery
stakequery = ( "?" stakepoolpair) *( "&" stakepoolpair)
stakepoolpair = stakepool [ "=" proportion]
cardanouri = "web+cardano:" (paymentref | authorityref)

stakepool = poolhexid | poolticker
poolhexid = 56HEXDIG
poolticker = 3*5UNICODE

proportion = *digit [ "." *digit ]
authorityref = (stakepoolref | otherref)
otherref = "//" authority query
```

For grammar reference, see:

- [Wikipedia > Augmented Backus–Naur form](https://en.wikipedia.org/wiki/Augmented_Backus%E2%80%93Naur_form)
- [RFC 2234: Augmented BNF for Syntax Specifications: ABNF](https://datatracker.ietf.org/doc/html/rfc2234)
- [Unicode in ABNF](https://tools.ietf.org/html/draft-seantek-unicode-in-abnf-00)

#### Payment URI queries

```
paymentref = cardanoaddress [ "?" amountparam ]
cardanoaddress = *(base58 | bech32)
amountparam = "amount=" *digit [ "." *digit ]
```

The amount parameter must follow the [same rules](https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki#transfer-amountsize) described in BIP-21, namely, it must be specified in decimal ADA, without commas and using the period (.) decimal separator.

#### Stake pool URI queries

For brevity, essential in many Internet contexts, `poolticker` must be supported here in addition to the unambiguous `poolhexid`.
```
stakepoolref = "//stake" query
query = ( "?" stakepoolpair) *( "&" stakepoolpair)
stakepoolpair = stakepool [ "=" proportion]

When there is more than one pool registered with any of the specified `poolticker` parameters (whether for pool groups which have the same ticker for all pools, or for separate pools using the same ticker), the choice to which pool(s) to finally delegate is left to the user through the wallet UI.
stakepool = poolhexid | poolticker
poolhexid = 56HEXDIG
poolticker = 3*5UNICODE

proportion = *digit [ "." *digit ]
```

For brevity, essential in many Internet contexts, `poolticker` must be supported here in addition to the unambiguous `poolhexid`.

##### Interpretation of `proportion`:
##### Interpretation of `proportion`

* If only one stake pool is specified, any proportion is meaningless and ignored.
* If all stake pools have a numerical proportion, each component of the resulting stake distribution will have the same ratio as the provided `proportion` to the sum of all the propotions.
* Any missing `proportion` is assigned a precise value of `1`.
* If a stake pool is listed multiple times, the URI is rejected as invalid.

### Handling stake pool links
##### Handling stake pool links

When there is more than one pool registered with any of the specified `poolticker` parameters (whether for pool groups which have the same ticker for all pools, or for separate pools using the same ticker), the choice to which pool(s) to finally delegate is left to the user through the wallet UI.

The wallet UI should always confirm the exact delegation choice even when it is unambiguous from the URI. When the user has multiple wallets, the wallet UI must select which wallet(s) the user will be delegating from.

Expand All @@ -125,6 +139,10 @@ If, during a wallet or other application's development process, it is still only
* any value for the first URI query argument;
* any URI query argument beyond the first.

#### Other URI queries

An ABNF grammar should be specified and explained similarly for each CIP that defines a new Cardano URI authority by explicitly defining the terms `authority` and `query` as for the "Stake pool" case above.

### Security Considerations

1. For payment links, we cannot prompt the user to send the funds right away as they may not be fully aware of the URI they clicked or were redirected to. Instead, it may be better to simply pre-populate fields in a transaction.
Expand All @@ -133,7 +151,9 @@ If, during a wallet or other application's development process, it is still only

## Rationale: how does this CIP achieve its goals?

### Why not use Universal links, deep links or other non-protocol-based Solution?
### Rationale for general URI scheme

#### Why not use Universal links, deep links or other non-protocol-based Solution?

An alternative solution to the original problem described above is to use standard URL links in combination with a routing backend system. The routing system is used to redirect to the app's URI. The advantage of this scheme is that it allows to provide a fallback mechanism to handle the case when no application implementing the protocol is installed (for instance, by redirecting to the App Store or Google Play). This is the approach behind iOS Universal Links and Android App Links. In general, it provides a better user experience but requires a centralized system which makes it unsuitable for as a multi-app standard.

Expand All @@ -143,13 +163,21 @@ For background, see
- [Apple Developer Docs > Defining a custom URL scheme for your app](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app)
- [React Native > Linking](https://reactnative.dev/docs/linking.html)

### How URI delegation portfolio links supplement use of JSON files for the same purpose?
### Rationale for payment links

#### Why confine payment links to address and amount like BIP-21?

BIP-21 is limited to only features Bitcoin supports. A similar feature for Ethereum would, for example, also support gas as an extra parameter. BIP-21 is easily extensible but we have to take precaution to avoid different wallets having different implementations of these features as they become available on Cardano. To get an idea of some extra features that could be added, consider this (still under discussion) proposal for Ethereum: [EIP-681](https://eips.ethereum.org/EIPS/eip-681)

### Rationale for stake pool links

#### How do URI delegation portfolio links supplement use of JSON files for the same purpose?

URIs facilitate the "social element" of delegated staking and pool promotion through a socially familiar, easily accessible, and less centralised convention for sharing stake pool references and potential delegation portfolios without having to construct or host a JSON file.

The processing of a JSON file delivered by a web server will depend highly on a user's platform and might not even be seen by the wallet application at all. With a properly associated `web+cardano:` protocol, developers and users have another option available in case JSON files are not delivered properly to the wallet application.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could we better and more cleanly handle the varied methods of delegation via a link that would "point" to a well-defined JSON/CBOR schema metadata file that can be fetched? This would greatly simplify the URIs themselves and the associated HTML where they are embedded in addition to improving troubleshooting and diagnostics.

Copy link
Collaborator Author

@rphair rphair Jul 25, 2023

Choose a reason for hiding this comment

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

In the months it took the stake pool links to be put through as an addition to this CIP, the counter of a JSON file query was the main objection. Rather than look at the stake pool approach on its own merit, most CIP editors at the time and IOG developers who jumped in said that JSON would be "better" and for a while the discussion just ended there: let alone being open to a cooperative approach. //stake was eventually merged when I managed to show that a rigorously defined URI syntax had fewer practical limitations than the JSON proponents had all assumed.

That is at least an indicator that a hybrid URI-to-JSON stake portfolio protocol would be unpopular. In fact, over 2 years after those discussions, CIP-0017 remains unimplemented as far as I know

The motivation for having the one-line, simple syntax available is for the sake of web designers, SPOs, and marketers & is already in the currently defined CIP (the reasons they would find JSON impractical are detailed in the associated PRs). Other resource locators like encapsulated JSON URLs might be useful generally... though still no commercial interest I know of in supporting more flexible delegation. If & when the time comes, we can suggest to those implementors that they create a new authority (e.g. //stakelink) with a separate CIP for it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

... some dev will come along someday wanting to put urlencoded CBOR in a URL: so rather than create a precedent to support this in a constantly modified (or deprecated) CIP-0013 we can simply tell them, "Create a new authority keyword for it & define your support for it there" ... whether it relates to payments, delegation and/or anything else 🤓

Copy link
Collaborator

Choose a reason for hiding this comment

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

I suppose my primary objection is to the use of potentially unicode pool tickers as the "keys" in the URL arguments, I feel like this creates a cumbersome barrier to implementation for the wallets. However, I also understand this was introduced most likely in response to URL max-length limitations that could quickly be exceeded by 3+ pool hex IDs.

The parser that I've written to handle logical parsing of CIP-13 URIs does manage to handle it but has not been rigorously tested against things like URL-encoded UTF-8 tickers so will need some additional work there for matching.

https://github.com/Crypto2099/POO/blob/main/packages/lib/cardano-poo-ts/src/CIP13Parser.ts

Copy link
Collaborator Author

@rphair rphair Jul 25, 2023

Choose a reason for hiding this comment

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

The problem with not using the stake pools as keys is that the syntax expands greatly, and then fails for multi pool links, when using them as values.

After months of debate, those against using the stake pools as keys couldn't come up with an alternative syntax which was concise and unambiguous:

I don't know if any alternative syntax you might be thinking of would have this same problem, but the main problem with the last suggestion (having a poolticker keyword with the hex pool ID as the value) was lack of support for multi-pool delegation links, since URI query variables can't have more than one value:

So as difficult as it might be for parsers and wallets to implement this (as I remember pointed out by @SebastienGllmt in the earlier threads, though I can't find this comment now), I don't see a way around it unless someone wants to spell out an alternative syntax & attempt another disqualification of the CIP-13 stake pool link protocol as it's now been defined for the last 2 years... keeping in mind that the main problem would be the support of multiple pool values rather than the length of the URI string.


For a CIP based on this principle, see [CIP-0017](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0017).
For a CIP based on this principle, see [CIP-0017](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0017/README.md).

## Path to Active

Expand All @@ -159,18 +187,24 @@ For a CIP based on this principle, see [CIP-0017](https://github.com/cardano-fou
- [x] Yoroi
- [x] There exist one or more wallets supporting Stake Pool URIs.
- [ ] TBD
- [x] There exist other CIPs or drafts defining additional URI protocols.
- [ ] There exist one or more wallets supporting additional URI protocols.
- [ ] TBD

### Implementation Plan

Survey contemporary wallet developers to suggest adoption of both feature sets, since they are likely to be considered separately:
Encourage wallet and dApp developers to support all currently defined URI protocols, keeping in mind these are each likely to be considered separately:

- Payment URIs
- Stake Pool URIs
- all other URI schemes defined in separate CIPs

This survey can be conducted and/or advocated by either (ideally both):
Education and advocacy about these standards should be done by:

- Developers of applications and standards requiring new URI schemes
- Cardano sponsoring companies
- Community advocates
- CIP editors

## Copyright

Expand Down