2020-09-04 09:56:06 -07:00
|
|
|
::
|
|
|
|
|
|
|
|
ZIP: 321
|
|
|
|
Title: Payment Request URIs
|
2020-09-14 07:22:13 -07:00
|
|
|
Owners: Kris Nuttycombe (kris@electriccoin.co)
|
2020-09-04 09:56:06 -07:00
|
|
|
Daira Hopwood (daira@electriccoin.co)
|
2020-09-24 06:56:57 -07:00
|
|
|
Status: Proposed
|
2020-09-14 07:22:13 -07:00
|
|
|
Category: Wallet
|
2020-09-04 09:56:06 -07:00
|
|
|
Created: 2020-08-28
|
2020-09-14 07:22:13 -07:00
|
|
|
Discussions-To: <https://github.com/zcash/zips/issues/347>
|
|
|
|
Pull-Request: <https://github.com/zcash/zips/pull/395>
|
2020-09-04 09:56:06 -07:00
|
|
|
License: MIT
|
|
|
|
|
|
|
|
|
|
|
|
Terminology
|
|
|
|
===========
|
|
|
|
|
|
|
|
The key words "MUST", "MUST NOT", "SHOULD", "RECOMMENDED", and "MAY" in this
|
|
|
|
document are to be interpreted as described in RFC 2119. [#RFC2119]_
|
|
|
|
|
|
|
|
The terms below are to be interpreted as follows:
|
|
|
|
|
|
|
|
payment
|
2020-09-24 08:26:13 -07:00
|
|
|
A transfer of funds implemented by a shielded or transparent output of
|
|
|
|
a single Zcash transaction.
|
2020-09-04 09:56:06 -07:00
|
|
|
|
|
|
|
|
|
|
|
Abstract
|
|
|
|
========
|
|
|
|
|
2020-09-24 08:26:13 -07:00
|
|
|
This ZIP proposes a standard format for payment request URIs. Wallets that
|
2020-09-04 09:56:06 -07:00
|
|
|
recognize this format enable users to construct payments simply by
|
|
|
|
clicking links on webpages or scanning QR codes.
|
|
|
|
|
|
|
|
|
|
|
|
Motivation
|
|
|
|
==========
|
|
|
|
|
|
|
|
In order for a robust transactional ecosystem to evolve for Zcash, it is
|
|
|
|
necessary for vendors to be able to issue requests for payment. At present, the
|
|
|
|
best option available is to manually specify a payment address, a payment
|
|
|
|
amount, and potentially memo field content. Of these three components, existing
|
|
|
|
wallets only provide functionality for reading payment addresses in a
|
|
|
|
semi-automated fashion. It is then necessary for the user to manually enter
|
|
|
|
payment amounts and any associated memo information, which is tedious and may
|
2020-09-17 11:26:22 -07:00
|
|
|
be error-prone, particularly if a payment is intended for multiple recipients
|
2020-09-04 09:56:06 -07:00
|
|
|
or the memo field information contains structured data that must be faithfully
|
2020-09-24 08:26:13 -07:00
|
|
|
reproduced.
|
2020-09-04 09:56:06 -07:00
|
|
|
|
2020-09-17 11:26:22 -07:00
|
|
|
This ZIP seeks to eliminate these issues by proposing a standard format that
|
2020-09-04 09:56:06 -07:00
|
|
|
wallet vendors may support so that human intervention is required only for
|
|
|
|
approval, not creation, of such a payment transaction.
|
|
|
|
|
2020-09-17 11:26:22 -07:00
|
|
|
In Bitcoin, two different standards exist to permit vendors to issue payment
|
2020-09-24 10:51:28 -07:00
|
|
|
requests that are understood by wallets: BIP-0021 [#bip-0021]_ and BIP-0070
|
|
|
|
[#bip-0070]_. BIP-0021 provides a URI format that can be interpreted by a
|
2020-09-17 11:26:22 -07:00
|
|
|
wallet to construct simple, single-recipient transactions; while BIP-0070 uses a
|
|
|
|
protobuf-based protocol that permits payment requests to specify the creation
|
2020-09-04 11:20:47 -07:00
|
|
|
of transactions of arbitrary complexity.
|
2020-09-04 09:56:06 -07:00
|
|
|
|
|
|
|
The format proposed in this ZIP seeks a middle ground between these approaches:
|
|
|
|
to provide a URI-based format which supports both the trivial use case and
|
|
|
|
the slightly-more-complex situation where a payment may be intended for
|
2020-09-24 08:26:13 -07:00
|
|
|
multiple recipients.
|
2020-09-04 09:56:06 -07:00
|
|
|
|
|
|
|
Requirements
|
|
|
|
============
|
|
|
|
|
|
|
|
The format must be a valid URI.
|
|
|
|
|
2020-09-24 08:26:13 -07:00
|
|
|
The format must permit the representation of one or more (payment address, amount,
|
2020-09-04 09:56:06 -07:00
|
|
|
memo) tuples.
|
|
|
|
|
|
|
|
Specification
|
|
|
|
=============
|
|
|
|
|
2020-09-15 10:48:48 -07:00
|
|
|
The following syntax specification uses ABNF [#RFC5234]_.
|
|
|
|
|
2020-09-04 09:56:06 -07:00
|
|
|
URI Syntax:
|
|
|
|
|
2020-09-04 10:59:01 -07:00
|
|
|
.. code-block:: EBNF
|
|
|
|
|
2020-09-04 09:56:06 -07:00
|
|
|
zcashurn = "zcash:" ( zcashaddress [ "?" zcashparams ] / "?" zcashparams )
|
2020-09-17 11:26:22 -07:00
|
|
|
zcashaddress = 1*base58
|
2020-09-04 09:56:06 -07:00
|
|
|
zcashparams = zcashparam [ "&" zcashparams ]
|
2020-09-16 21:22:50 -07:00
|
|
|
zcashparam = [ addrparam / amountparam / memoparam / messageparam / labelparam / reqparam / otherparam ]
|
2020-09-04 09:56:06 -07:00
|
|
|
NONZERO = %x31-39
|
|
|
|
DIGIT = %x30-39
|
2020-09-15 10:48:48 -07:00
|
|
|
paramindex = "." NONZERO *DIGIT
|
|
|
|
addrparam = "address" [ paramindex ] "=" zcashaddress
|
2020-09-24 06:06:55 -07:00
|
|
|
amountparam = "amount" [ paramindex ] "=" 1*DIGIT [ "." 1*8DIGIT ]
|
2020-09-15 10:48:48 -07:00
|
|
|
labelparam = "label" [ paramindex ] "=" *qchar
|
2020-09-22 17:51:29 -07:00
|
|
|
memoparam = "memo" [ paramindex ] "=" *base64url
|
2020-09-15 10:48:48 -07:00
|
|
|
messageparam = "message" [ paramindex ] "=" *qchar
|
|
|
|
paramname = ALPHA *( ALPHA / DIGIT / "+" / "-" )
|
|
|
|
reqparam = "req-" paramname [ paramindex ] [ "=" *qchar ]
|
|
|
|
otherparam = paramname [ paramindex ] [ "=" *qchar ]
|
2020-09-04 09:56:06 -07:00
|
|
|
qchar = unreserved / pct-encoded / allowed-delims / ":" / "@"
|
|
|
|
allowed-delims = "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / ";"
|
|
|
|
|
2020-09-04 11:24:46 -07:00
|
|
|
Here, ``ALPHA``, ``unreserved`` and ``pct-encoded`` are as defined in
|
2020-09-22 17:51:29 -07:00
|
|
|
[#RFC3986]_. "base58" is defined as in [#base58check]_. "base64url" is defined
|
2020-09-24 06:09:45 -07:00
|
|
|
as in [#base64url]_ with padding omitted. (Note that this uses a different
|
|
|
|
alphabet to the usual base64; the values 62 and 63 in the alphabet are encoded
|
|
|
|
as ``-`` and ``_`` respectively.)
|
2020-09-24 08:26:13 -07:00
|
|
|
|
2020-09-04 09:56:06 -07:00
|
|
|
A ZIP-321 URI represents a request for the construction of a transaction having
|
|
|
|
one or more *payments*. In the case that only a single payment is being
|
|
|
|
requested, the recipient address MAY be included in the ``hier-part`` component
|
|
|
|
of the RFC 3986 URI; otherwise, multiple recipient addresses can be specified
|
2020-09-24 08:26:13 -07:00
|
|
|
using ``addrparam`` parameters with different indices.
|
2020-09-04 09:56:06 -07:00
|
|
|
|
2020-09-24 08:26:13 -07:00
|
|
|
Addresses, amounts, labels, and messages sharing the same ``paramindex``
|
|
|
|
(including the empty ``paramindex``) are interpreted to be associated with
|
|
|
|
the same payment for the purposes of payment construction. A ``paramindex``
|
|
|
|
MUST NOT have leading zero(s). There is no significance to the ordering of
|
|
|
|
parameters, and ``paramindex`` values need not be sequential.
|
2020-09-04 09:56:06 -07:00
|
|
|
|
|
|
|
A URI of the form ``zcash:<address>?...`` MUST be considered equivalent to a
|
|
|
|
URI of the form ``zcash:?address=<address>&...`` where ``<address>`` is an
|
|
|
|
instance of ``zcashaddress``.
|
|
|
|
|
2020-09-24 08:26:13 -07:00
|
|
|
If there are any non-address parameters having a given ``paramindex``, then
|
2020-09-24 06:22:09 -07:00
|
|
|
the URI MUST contain an address parameter having that ``paramindex``. There
|
|
|
|
MUST NOT be more than one occurrence of a given parameter and ``paramindex``.
|
2020-09-04 09:56:06 -07:00
|
|
|
|
2020-09-18 21:35:09 -07:00
|
|
|
Productions of the form ``1*x`` indicate one or more successive instances of the
|
2020-09-24 06:06:55 -07:00
|
|
|
production ``x``. Productions of the form ``<n>*<m>x`` indicate at least `<n>` and
|
|
|
|
at most `<m>` instances of production ``x``.
|
2020-09-18 21:35:09 -07:00
|
|
|
|
2020-09-04 11:20:47 -07:00
|
|
|
Transfer amount
|
2020-09-15 10:48:48 -07:00
|
|
|
---------------
|
2020-09-04 11:20:47 -07:00
|
|
|
|
2020-09-24 08:44:10 -07:00
|
|
|
If an amount is provided, it MUST be specified in decimal ZEC. If a decimal fraction
|
|
|
|
is present then a period (`.`) MUST be used as the separating character to separate
|
|
|
|
the whole number from the decimal fraction, and both the whole number and the
|
|
|
|
decimal fraction MUST be nonempty. No other separators (such as commas for
|
|
|
|
grouping or thousands) are permitted. Leading zeros in the whole number or trailing
|
|
|
|
zeros in the decimal fraction are ignored. There MUST NOT be more than 8 digits in
|
|
|
|
the decimal fraction.
|
|
|
|
|
2020-09-24 06:07:39 -07:00
|
|
|
For example,
|
2020-09-21 08:51:38 -07:00
|
|
|
* ``amount=50.00`` or ``amount=50`` or ``amount=050`` is treated as 50 ZEC;
|
|
|
|
* ``amount=0.5`` or ``amount=00.500`` is treated as 0.5 ZEC; and
|
|
|
|
* ``amount=50,000.00`` or ``amount=50,00`` or ``amount=50.`` or ``amount=.5``
|
2020-09-24 06:22:09 -07:00
|
|
|
or ``amount=0.123456789`` are invalid.
|
2020-09-04 11:20:47 -07:00
|
|
|
|
|
|
|
Query Keys
|
|
|
|
----------
|
|
|
|
|
|
|
|
label
|
|
|
|
Label for an address (e.g. name of receiver)
|
|
|
|
|
|
|
|
address
|
2020-09-15 10:48:48 -07:00
|
|
|
Zcash address string (shielded or transparent)
|
2020-09-04 11:20:47 -07:00
|
|
|
|
|
|
|
memo
|
2020-09-24 10:42:33 -07:00
|
|
|
Contents for the Zcash shielded memo field, encoded as base64url without
|
2020-09-24 06:22:09 -07:00
|
|
|
``=`` padding. The decoded memo contents MUST NOT exceed 512 bytes, and
|
|
|
|
if shorter, will be filled with trailing zeros to 512 bytes.
|
2020-09-04 11:20:47 -07:00
|
|
|
Parsers MUST consider the entire URI invalid if the address associated with
|
|
|
|
the same ``paramindex`` is not a valid shielded address.
|
|
|
|
|
|
|
|
message
|
|
|
|
Message that clients can display for the purpose of presenting descriptive
|
|
|
|
information about the transaction to the user.
|
|
|
|
|
2020-09-22 17:51:29 -07:00
|
|
|
Examples
|
|
|
|
--------
|
|
|
|
|
|
|
|
Valid examples
|
|
|
|
~~~~~~~~~~~~~~
|
|
|
|
|
2020-09-24 10:51:28 -07:00
|
|
|
::
|
2020-09-22 17:51:29 -07:00
|
|
|
|
|
|
|
zcash:ztestsapling10yy2ex5dcqkclhc7z7yrnjq2z6feyjad56ptwlfgmy77dmaqqrl9gyhprdx59qgmsnyfska2kez?amount=1&memo=VGhpcyBpcyBhIHNpbXBsZSBtZW1vLg&message=Thank%20you%20for%20your%20purchase
|
|
|
|
|
2020-09-24 10:48:05 -07:00
|
|
|
A valid payment request for a payment of 1 ZEC to a single shielded address,
|
|
|
|
with a base64url-encoded memo and a message for display by the wallet.
|
2020-09-22 17:51:29 -07:00
|
|
|
|
2020-09-24 10:51:28 -07:00
|
|
|
::
|
2020-09-22 17:51:29 -07:00
|
|
|
|
|
|
|
zcash:?address=tmEZhbWHTpdKMw5it8YDspUXSMGQyFwovpU&amount=123.456&memo=eyAia2V5IjogIlRoaXMgaXMgYSBKU09OLXN0cnVjdHVyZWQgbWVtby4iIH0&address.1=ztestsapling10yy2ex5dcqkclhc7z7yrnjq2z6feyjad56ptwlfgmy77dmaqqrl9gyhprdx59qgmsnyfska2kez&amount.1=0.789&memo.1=VGhpcyBpcyBhIHVuaWNvZGUgbWVtbyDinKjwn6aE8J-PhvCfjok
|
|
|
|
|
2020-09-24 10:48:05 -07:00
|
|
|
A valid payment request with one transparent and one shielded recipient address,
|
|
|
|
with encoded JSON and Unicode memos.
|
2020-09-22 17:51:29 -07:00
|
|
|
|
|
|
|
Invalid Examples
|
|
|
|
~~~~~~~~~~~~~~~~
|
|
|
|
|
2020-09-24 10:51:28 -07:00
|
|
|
::
|
2020-09-22 17:51:29 -07:00
|
|
|
|
|
|
|
zcash:?amount=3491405.05201255&address.1=ztestsapling10yy2ex5dcqkclhc7z7yrnjq2z6feyjad56ptwlfgmy77dmaqqrl9gyhprdx59qgmsnyfska2kez&amount.1=5740296.87793245
|
|
|
|
|
2020-09-24 06:22:09 -07:00
|
|
|
An invalid payment request; this is missing a payment address with empty ``paramindex``.
|
2020-09-22 17:51:29 -07:00
|
|
|
|
2020-09-24 10:51:28 -07:00
|
|
|
::
|
2020-09-24 08:26:13 -07:00
|
|
|
|
|
|
|
zcash:?address=tmEZhbWHTpdKMw5it8YDspUXSMGQyFwovpU&amount=1&amount.1=2&address.2=ztestsapling10yy2ex5dcqkclhc7z7yrnjq2z6feyjad56ptwlfgmy77dmaqqrl9gyhprdx59qgmsnyfska2kez
|
|
|
|
|
2020-09-24 08:44:45 -07:00
|
|
|
Also invalid; this request is missing ``address.1=``.
|
2020-09-22 17:51:29 -07:00
|
|
|
|
2020-09-24 10:51:28 -07:00
|
|
|
::
|
2020-09-22 17:51:29 -07:00
|
|
|
|
2020-09-24 08:26:13 -07:00
|
|
|
zcash:?address.0=ztestsapling10yy2ex5dcqkclhc7z7yrnjq2z6feyjad56ptwlfgmy77dmaqqrl9gyhprdx59qgmsnyfska2kez&amount.0=2
|
2020-09-24 06:22:09 -07:00
|
|
|
|
2020-09-24 08:26:13 -07:00
|
|
|
Also invalid; ``address.0=`` and ``amount.0=`` are not permitted as leading 0s are
|
|
|
|
forbidden in ``paramindex``.
|
|
|
|
|
2020-09-24 10:51:28 -07:00
|
|
|
::
|
2020-09-24 06:22:09 -07:00
|
|
|
|
|
|
|
zcash:?amount=1.234&amount=2.345&address=tmEZhbWHTpdKMw5it8YDspUXSMGQyFwovpU
|
|
|
|
|
2020-09-24 08:26:13 -07:00
|
|
|
zcash:?amount.1=1.234&amount.1=2.345&address.1=tmEZhbWHTpdKMw5it8YDspUXSMGQyFwovpU"
|
|
|
|
|
|
|
|
Also invalid; duplicate ``amount=`` or ``amount.1=`` fields
|
2020-09-22 17:51:29 -07:00
|
|
|
|
2020-09-04 09:56:06 -07:00
|
|
|
Forward compatibility
|
|
|
|
---------------------
|
|
|
|
|
|
|
|
Variables which are prefixed with a ``req-`` are considered required. If a
|
|
|
|
parser does not recognize any variables which are prefixed with ``req-``, it
|
|
|
|
MUST consider the entire URI invalid. Any other variables that are not
|
|
|
|
recognized, but that are not prefixed with a ``req-``, SHOULD be ignored.
|
|
|
|
|
|
|
|
Backward compatibility
|
|
|
|
----------------------
|
|
|
|
|
|
|
|
As this ZIP is written, several clients already implement a ``zcash:`` URI
|
|
|
|
scheme similar to this one, however usually without the additional ``req-``
|
2020-09-24 08:46:38 -07:00
|
|
|
prefix requirement or the facility to specify multiple payments using
|
|
|
|
``paramindex``. Thus, it is RECOMMENDED that these features not be used in
|
|
|
|
a mission-critical way until a grace period of 6 months from the finalization
|
|
|
|
of this ZIP has passed, in order to allow client developers to release new
|
|
|
|
versions, and users of old clients to upgrade.
|
2020-09-04 09:56:06 -07:00
|
|
|
|
|
|
|
References
|
|
|
|
==========
|
|
|
|
|
2020-09-15 10:48:48 -07:00
|
|
|
.. [#RFC2119] `RFC 2119: Key words for use in RFCs to Indicate Requirement Levels <https://www.rfc-editor.org/rfc/rfc2119.html>`_
|
|
|
|
.. [#RFC5234] `RFC 5234: Augmented BNF for Syntax Specifications: ABNF <https://www.rfc-editor.org/rfc/rfc5234.html>`_
|
|
|
|
.. [#RFC3986] `RFC 3986: URI Generic Syntax, Appendix A. Collected ABNF for URI <https://www.rfc-editor.org/rfc/rfc3986.html#appendix-A>`_
|
|
|
|
.. [#bip-0021] `BIP 21: URI Scheme <https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki>`_
|
|
|
|
.. [#bip-0070] `BIP 70: Payment Protocol <https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki>`_
|
2020-09-04 09:56:06 -07:00
|
|
|
.. [#base58check] `Base58Check encoding <https://en.bitcoin.it/wiki/Base58Check_encoding>`_
|
2020-09-22 17:51:29 -07:00
|
|
|
.. [#base64url] `RFC 4648 section 5: Base64 Encoding with URL and Filename Safe Alphabet <https://tools.ietf.org/html/rfc4648#section-5>`_
|