Overview
paymail is a collection of protocols for Bitcoin SV wallets that allow for a set of simplified user experiences to be delivered across all wallets in the ecosystem.
❌ No more complicated 17Dx2iAnGWPJCdqVvRFr45vL9YvT86TDsn
addresses
✅ Simple payment handles like <alias>@<domain>.<tld>
The goals of the paymail protocol are:
- User friendly payment destinations through memorable handles
- Permissionless implementation
- Self-hosted or delegated to a managed service
- Automatic service discovery/location
- PKI infrastructure
- Cross-wallet exchange of single-use transaction output scripts of any construction
- Request and response authentication
- Security and policy management
- Capability extensibility and discovery
bsvalias
The family of related protocols are collectively referred to as the bsvalias
protocols. At the time of writing, these include:
paymail
paymail is the name for the implementation of the following protocols:
- Service Discovery
- Public Key Infrastructure
- Basic Address Resolution from the Payment Addressing protocol group
The paymail brand is reserved for products and services that, at a minimum, implement each of the above.
Extension Protocols
As defined in the BRFC Specifications, anybody can propose an extension to the bsvalias
and paymail protocols, and as per the Capability Discovery section of the Service Discovery protocol, implementations can declare support for extensions to allow for cross-wallet processes.
Extension protocols are the collection of protocols not contained within the core paymail set defined above, but that are fully compatible with bsvalias
protocols and paymail implementations. Notable examples presently include:
- Sender Validation
- Receiver Approvals
- PayTo Protocol Prefix
- MultiSig authorisations
- Threshold signature group secret setup and message signing
- Payment channels
Copyright 2019 nChain and Money Button
BRFC Specifications
BRFC (Bitcoin SV Request-For-Comments) Specifications describe functionality across the ecosystem. bsvalias
protocols and paymail implementations are described across a series of BRFC documents.
Whilst this is not the authoritative definition of the BRFC process, a summary is included here as the BRFC process is the nominated mechanism through which extensions to the paymail system are defined and discovered during Service Discovery.
The BRFC process is a decentralised process, meaning anybody is free to propose anything without a central authority to approve the publication of new standards. In the context of paymail, implementers express their support for a proposal by actually implementing it, and advertising the endpoint(s) as part of their service discovery implementation.
Copyright 2019 nChain and Money Button
Specification Documents
There is no fixed format or central location for BRFC documents. They may be authored as markdown documents and hosted in a GitHub repository, published to a corporate website, embedded into the Bitcoin SV blockchain, shared on a mailing list, or distributed by any other means deemed appropriate by the author(s).
It is however recommended that at a minimum, the following metadata be included somewhere in the document:
Field | Required | Description |
---|---|---|
title | required | Proposal title |
author | Free-form, could include a name, alias, paymail address, GitHub/social media handle, etc. | |
version | No set format; could be a sequence number, publication date, or any other scheme | |
supersedes | A BRFC ID (or list of IDs) that this document supersedes |
For markdown files, it is recommended that these fields are embedded as YAML front-matter.
It is not recommended that version fields follow semver. With semver's <major>.<minor>.<patch>
format, it is expected that only an increment to the <major>
element indicates a breaking change. An increment of the <minor>
field indicates that additional functionality is available but that it will not break existing clients.
This is at odds with the binary nature of implementing a specification; either the specification is supported or it is not. The preferred methods of adding new features to a specification are:
- Introduce a new extension specification describing the additional functionality
- Update the specification and include the old BRFC ID in the
supersedes
field
Copyright 2019 nChain and Money Button
BRFC ID Assignment
It is desirable that a BRFC document be uniquely identified. Without a central authority to issue an identification number, we have chosen to borrow inspiration from Bitcoin and use hashes of content.
ID Construction
To construct a BRFC ID from a specification, take the UTF8 string value of the title
, author
and version
metadata fields (omit those not present), trim leading and trailing whitespace (leaving whitespace mid-way through the value), concatenate each value, then reinterpret the string as a byte array, and apply a double SHA256 hash.
let hash = sha256d(
spec.title.trim() +
(spec.author || '').trim() +
(spec.version || '').trim()
);
Hex-format the hash as per Bitcoin conventions (usually this means reversing the bytes before converting to hex).
let bitcoinDisplayHash = hash
.reverse()
.toString('hex');
Take the first 12 characters of the Bitcoin-style display hash (representing the last six bytes of the underlying sha256d
value):
let brfcId = bitcoinDisplayHash.substring(0, 12);
Considerations
Hashing the title, author and version metadata of a specification allows us to generate a unique ID without central authority. Hashing the entire specification was considered, however this was discounted due to the following drawbacks:
- Any change, however minor (like typo fixes) would create an entirely new specification id
- Different platforms handle line endings differently, and different source control and editor software can replace these without warning. This leads to unstable hashes across seemingly identical documents
- Some file formats update metadata even when content remains unchanged. Again, this would lead to unstable hashes over otherwise stable content
Test Cases
title: BRFC Specifications
author: andy (nChain)
version: 1
Expected BRFC ID: 57dd1f54fc67
title: bsvalias Payment Addressing (PayTo Protocol Prefix)
author: andy (nChain)
version: 1
Expected BRFC ID: 74524c4d6274
title: bsvalias Integration with Simplified Payment Protocol
author: andy (nChain)
version: 1
Expected BRFC ID: 0036f9b8860f
Copyright 2019 nChain and Money Button
Service Discovery
brfc | title | authors | version |
---|---|---|---|
b2aa66e26b43 | bsvalias Service Discovery | andy (nChain), Ryan X. Charles (Money Button) | 1 |
Service discovery is separated into two phases:
- Host Discovery is a DNS based lookup of the responsible host for a given paymail alias
- Capability Discovery resolves the paymail service endpoint URIs from the responsible DNS host and describes the capabilities supported by a given paymail service instance
Service Discovery Process
Copyright 2019 nChain and Money Button
Host Discovery
Host discovery is the process through which a domain owner optionally specifies which web host to interrogate during capability discovery. The host discovery process involves the creation and subsequent query of SRV
DNS records.
The use of an SRV
record was chosen for the following reasons:
- Domain owners may choose to use a third-party paymail service provider. Delegating authority to this provider is a one-time activity (the creation of a DNS
SRV
record). TXT
records were considered, however should the paymail service be reconfigured (for example, the root URI change from.../api/v1/...
to.../api/v2/...
), the domain owner would have to coordinate with the service provider to ensure theTXT
record (containing a full endpoint URI) was updated. WithSRV
records (plus the Capability Discovery protocol), the Host Discovery phase is set-and-forget.- As an optional step, if the canonical Capability Discovery host is the same as the domain found in the paymail alias, the DNS record can be omitted entirely.
- DNS records (including
SRV
) feature a TTL, which clients can use for caching responses. All common DNS clients implement this caching out-of-the-box, meaning implementers do not have to roll this themselves.
Setup
A domain owner may create an SRV
record with the following parameters:
Parameter | Value |
---|---|
Service | _bsvalias |
Proto | _tcp |
Name | <domain>.<tld>. |
TTL | 3600 (see notes) |
Class | IN |
Priority | 10 |
Weight | 10 |
Port | 443 |
Target | <endpoint-discovery-host> |
The TTL
parameter should be set very low for test configurations (a few seconds), whereas for production deployments this should be set higher, to allow caching to work. A value of 3600
is suggested for production deployments.
Although the DNS system allows for multiple records with a variety of priorities and weights, which allows for some level of traffic management, resilience, and load-balancing via DNS records, it is recommended by this specification that these considerations be handled by more modern infrastructure and only a single SRV
record be created.
See https://en.wikipedia.org/wiki/SRV_record for more information on SRV
DNS records.
SRV
records must be served with a valid DNSSEC signature chain with the exception that if the SRV
record points to <domain>.<tld>
or www.<domain>.<tld>
, then the SRV
records should be served with a valid DNSSEC signature chain.
Client Queries
Given a paymail alias <alias>@<domain>.<tld>
, a paymail client would perform a DNS lookup for an SRV
record matching _bsvalias._tcp.<domain>.<tld>
. The combination of Target
and Port
fields are then used for Capability Discovery. Should no record be returned, a paymail client should assume a host of <domain>.<tld>
and a port of 443
.
Security and SRV Records
In its legacy form, that is, without DNSSEC, DNS is not a secure mechanism. It is susceptible to a range of attacks, the most serious for the purposes of the BSV Alias protocol being an intercept or man-in-the-middle (MITM) attack. In this scenario an attacker intercepts DNS queries and responds with their own data. This would allow an attacker to direct a client to a paymail implementation of their choosing, which would further allow for them to control all further communications with a client.
Note: whilst an exception to the requirement for DNSSEC is made for cases where the SRV
record points to the same target domain as the SRV
record itself it is best practice to enable DNSSEC in all cases.
Clients must, therefore, resolve hosts with the following procedure.
- Query for an
SRV
endpoint at_bsvalias._tcp.<domain>.<tld>.
. - If an
SRV
record is found and the reponse target points to<domain>.<tld>
orwww.<domain>.<tld>
, but the response is not served with a valid DNSSEC signature chain, proceed to capability discovery using the target/port combination as specified by theSRV
record and rely on the SSL certificate for the prevention of man in the middle attacks. Note that in this scenario it is possible to still receive malicious DNS information, however SSL certificates prevent further MITM attacks. - If an
SRV
record is found, but the response is not served with a valid DNSSEC signature chain and the response target does NOT point to<domain>.<tld>
orwww.<domain>.<tld>
, ignore theSRV
record completely and continue with anA
record query as in step 5, relying on the SSL certificate for the prevention of man in the middle attacks. Note that in this scenario it is possible to still receive malicious DNS information, however SSL certificates prevent further MITM attacks. The worst that may happen here is that, for a domain that has delegated BSV Alias services out to a service provider, further lookups fail and the client cannot proceed at this time. However the option of falling back to anA
record and relying on SSL prevents a possible denial of service vector where a malicious actor has compromised DNS. - If an
SRV
record is found, and the response is served with a valid DNSSEC signature chain, proceed to capability discovery using the target/port combination as specified by theSRV
record. - If no
SRV
record is found, instead query for anA
record for<domain>.<tld>.
and proceed to capability discovery, verifying that the SSL certificate presented by the remote host is valid for<domain>.<tld>.
.
A client must fail the request in the following cases:
- The SSL certificate for the target domain does not verify as valid for that target domain regardless of whether the target domain is discovered via the
SRV
record or via theA
record. - An
SRV
record is not served; AND AND<domain>.<tld>
does not host a valid capability discovery service. - The
SRV
response target does NOT point<domain>.<tld>
orwww.<domain>.<tld>
; AND theSRV
record is not served with a valid DNSSEC signature chain; AND<domain>.<tld>
does not host a valid capability discovery service.
Copyright 2019 nChain and Money Button
Capability Discovery
Following on from Host Discovery, the next step a paymail client performs is Capability Discovery.
Capability Discovery is the process by which a paymail client learns the supported features of a paymail service and their respective endpoints and configurations.
Drawing inspiration from RFC 5785 and IANA's Well-Known URIs resource, the Capability Discovery protocol dictates that a machine-readable document is placed in a predictable location on a web server.
Setup
A paymail service operator creates a JSON formatted text file at the following location:
https://<host-discovery-target>:<host-discovery-port>/.well-known/bsvalias
.
- The file name
bsvalias
is chosen to allow implementers to move forward with a stable specification whilst the final product name is under consideration - The file MUST be served over HTTPS
- The value of the HTTP
Content-Type
header MUST be set toapplication/json
and optionally MAY indicate a schema as an attribute, for exampleapplication/json; schema="https://schemas.nchain.com/bsvalias/1.0/capability-discovery"
- The successful response status code MUST be either
200
(OK) if thebsvalias
file exists, or304
(Not Modified) if valid cache query headers are supplied within the request. - The response MAY indicate the document's validity via standard HTTP caching and expiry related headers. Operators are advised to consider configuring their web server to support the broadest range of supported client caching mechanisms, including
Cache-Control
,Last-Modified
/If-Modified-Since
,Etag
, andExpires
. Many standard clients and libraries implement standards-compliant caching behaviour. Further details are available from MDN - The
bsvalias
file must conform to the following format:
{
"bsvalias": "1.0",
"capabilities": {
"pki": "https://bsvalias.example.org/{alias}@{domain.tld}/id",
"paymentDestination": "https://bsvalias.example.org/{alias}@{domain.tld}/payment-destination"
}
}
- The template values
{alias}
and{domain.tld}
refer to the components of paymail handle format<alias>@<domain>.<tld>
and are literal; clients are expected to replace them wherever they appear in the endpoint URI with the actual values from the paymail handle - Additional BRFCs may extend this document. It is a matter for each specification author to describe the data structure required for their particular protocol, however the location of that data structure must be a key within the
capabilities
object named after the BRFC ID. As an example, a (fictional) BRFC with ID001122334455
requires a simple boolean flag in addition to an endpoint URI. It would extend the.well-known/bsvalias
document like this:
{
"bsvalias": "1.0",
"capabilities": {
"001122334455": {
"endpoint": "https://bsvalias.example.org/{alias}@{domain.tld}/example",
"flag": true
}
}
}
Note that the capabilities pki
and paymentDestination
are not named for their BRFC IDs, as these are the minimum set of capabilities required for a service to qualify as a paymail service and are treated as special cases.
Client Queries
Having retrieved a Target
:Port
pair using Host Discovery, a paymail client constructs an HTTP GET request to https://<target>:<port>/.well-known/bsvalias
, including caching hints from previous requests (if any).
Following a successful request, clients have now discovered all configuration information required for interacting with a paymail service and are aware of all supported extension protocols offered by the remote.
Changes from previous versions
In the original drafts, the bsvalias
file was a text based, tab-delimited list of <domain>.<tld> \tab https://<base-uri>
pairs.
- This was removed to avoid data leakage about domains hosted by a given paymail service
- The format was changed from tab-delimited text to JSON
- Capability Discovery was merged into the previous Address Discovery base URI approach
- A paymail (
bsvalias
) version field was added for forward compatibility, although its interpretation is unspecified at this time
Design Considerations
In a previous version of this specification, this step of the service discovery returned a base URI from which all request URIs would be built. It was suggested that the .well-known/bsvalias
document merge a separate capability discovery which was originally planned to exist at <base-uri>/capabilities
. In doing so, the following points were considered:
Capabilities differ by domain and by user within a domain
- Service providers hosting multiple domains may offer different capabilities at different price points
- Administrators may enable or disable capabilities on a per-user bases
A single .well-known/bsvalias
document cannot describe the per-alias/per-domain capabilities. Instead it describes the services supported by the implementation, regardless of account-level availability. Where a paymail implementation supports a particular protocol but it is not enabled for a given account, upon receiving a request that will not be fulfilled, a 404
(Not Found) response should be given. This is (deliberately) indistinguishable from {alias}
/{domain.tld}
not found.
Simplified client/request flow
Merging capability discovery reduces the amount of requests made in order to locate a given service endpoint, and simplifies client implementations.
More complicated deployment
One drawback of merging the two phases of discovery is that .well-known/bsvalias
is no longer set-and-forget.
Prior to merging these to functions, a redeployment of the paymail service implementation may deliver new capabilities. These would be automatically discovered by clients.
Having merged service location and capability discovery into .well-known/bsvalias
, this file must also be updated when a service deployment delivers enhanced capabilities. It is recommended that implementers of server software deliver an endpoint that can generate a valid .well-known/bsvalias
response, and that operators configure a proxy to transparently service this implementation-provided endpoint when a request for the well known capabilities file is received.
Copyright 2019 nChain and Money Button
Public Key Infrastructure
brfc | title | authors | version |
---|---|---|---|
0c4339ef99c2 | bsvalias Public Key Infrastructure | andy (nChain), Ryan X. Charles (Money Button) | 1 |
Each paymail handle <alias>@<domain>.<tld>
MUST be issued a stable ECDSA public key that SHOULD NOT be used as part of any on-chain transaction. Clients must be able to locate the public key from information within the .well-known/bsvalias
configuration file:
{
"bsvalias": "1.0",
"capabilities": {
"pki": "https://bsvalias.example.org/{alias}@{domain.tld}/id",
}
}
The template values {alias}
and {domain.tld}
refer to the components of target paymail handle <alias>@<domain>.<tld>
and must be substituted by the client before issuing a request.
PKI Flow
Client Request
The capabilities.pki
path returns a URI template. Clients should replace the {alias}
and {domain.tld}
template parameters and then make an HTTP GET request against this URI.
Standard HTTP caching headers SHOULD be supported, and clients that have previously requested the public key SHOULD NOT re-request information within any server-advertised caching window.
Server Responses
Below are the responses that have meaning to this protocol. A server may return other status codes, for example 5xx
indicating some sort of server failure. Clients should treat status codes not specified as part of this specification as some sort of transient error and may retry at their leisure.
200 OK
Returned when a valid request for a known paymail handle has been received. The return message MUST have a content type of application/json
. The response body MUST conform to the following schema:
{
"bsvalias": "1.0",
"handle": "<alias>@<domain>.<tld>",
"pubkey": "..."
}
The public key MUST be a valid point on the secp256k1 curve, compressed, and hex-encoded. This means that the pubkey string length MUST be 66 bytes long (33 bytes binary, each byte encoded as two hex characters):
Start | Length | Value |
---|---|---|
00 | 02 | "Odd/even" indicator, must be either 02 or 03 |
02 | 64 | Elliptic curve point x-coordinate |
304 Not Modified
No public key rotation has taken place since the previous request, based on caching headers supplied.
404 Not Found
The paymail handle was not found by this service.
Copyright 2019 nChain and Money Button
Payment Addressing
Payment Addressing is the mechanism through which a wallet can, on behalf of a user making a payment transaction, discover the preferred Bitcoin output script of a receiver given only their paymail handle, in the form <alias>@<domain>.<tld>
.
Payment Addressing is specified across a number of BRFCs:
Only Basic Address Resolution is required in order for an implementation to carry the paymail branding.
Copyright 2019 nChain and Money Button
Basic Address Resolution
brfc | title | authors | version |
---|---|---|---|
759684b1a19a | bsvalias Payment Addressing (Basic Address Resolution) | andy (nChain), Ryan X. Charles (Money Button) | 1 |
Given a sender and a receiver, where the sender knows the receiver's paymail handle <alias>@<domain>.<tld>
, the sender can perform Service Discovery against the receiver and request a payment destination from the receiver's paymail service.
The payment destination request endpoint is described in the .well-known/bsvalias
configuration file:
{
"bsvalias": "1.0",
"capabilities": {
"paymentDestination": "https://bsvalias.example.org/{alias}@{domain.tld}/payment-destination",
}
}
The template values {alias}
and {domain.tld}
refer to the components of the receiver's paymail handle <alias>@<domain>.<tld>
and must be substituted by the client before issuing a request.
The sender will receive a Bitcoin output script, which should be used in the construction of the payment transaction to the receiver.
Flow
Sender Request
The capabilities.paymentDestination
path returns a URI template. Senders should replace the {alias}
and {domain.tld}
template parameters with the values from the receiver's paymail handle and then make an HTTP POST request against this URI.
The body of the POST request MUST have a content type of application/json
and MUST conform to the following schema:
{
"senderName": "FirstName LastName",
"senderHandle": "<alias>@<domain.tld>",
"dt": "<ISO-8601 timestamp>",
"amount": 550,
"purpose": "message to receiver",
"signature": "<compact Bitcoin message signature>"
}
Field | Required | Description |
---|---|---|
senderName | Human-readable sender display name | |
senderHandle | ✓ | sender's paymail handle |
dt | ✓ | ISO-8601 formatted timestamp; see notes |
amount | The amount, in Satoshis, that the sender intends to transfer to the receiver | |
purpose | Human-readable description of the purpose of the payment | |
signature | Compact Bitcoin message signature; see notes |
Timestamp field (dt)
The timestamp field should contain the ISO-8601 formatted current time at the point the receiver initiates a payment destination request. From JavaScript this can be constructed using JSON.stringify()
:
let now = JSON.stringify({'now': new Date()});
Which yields:
{
"now": "2013-10-21T13:28:06.419Z"
}
Signature field
The Bitcoin client has long offered the ability to sign messages and verify message signatures. The Bitcoin functionality is essentially an implementation of standard ECDSA, however along with the (r, s) signature pair there is additional information to allow the Bitcoin client to verify a message signature against a P2PKH address (a hash of a public key) rather than directly against a public key.
In the original draft of this specification, the signature was the raw (r, s) fields, computed over a double-SHA256 hash of the message. However in order to leverage existing Bitcoin client libraries, such as MoneyButton's BSV library, it has been decided instead to follow the Bitcoin client's signing and verification protocol.
The MoneyButton BSV library's implementation is nominated as the standard message digest construction and signature encoding method for signatures included in payment destination requests. Usage and reference implementation are available from GitHub.
The message to be signed begins with the Bitcoin signature scheme's traditional preamble (as documented within the BSV library's source code) and is followed by the UTF8 string concatenation of senderHandle
, dt
, amount
and purpose
fields.
- If
amount
is present, it is converted to a string (with no leading zeros) - If
amount
is not present, the string"0"
is used - If purpose is not present, an empty string
""
is used (effectively purpose is not included in the message)
Receiver Response
Below are the responses that have meaning to this protocol. A server may return other status codes, for example 5xx
indicating some sort of server failure. Clients should treat status codes not specified as part of this specification as some sort of transient error and may retry at their leisure.
200 OK
Returned when a valid request for a known paymail handle has been received. The return message MUST have a content type of application/json
. The response body MUST conform to the following schema:
{
"output": "..."
}
The value of the output
field MUST be a hex-encoded Bitcoin script, which the sender MUST use during the construction of a payment transaction.
It is beyond the scope of this specification to describe the various possible types of output script, however it is expected that paymail services will implement at a minimum P2PKH output scripts.
Wallet implementers have expressed a desire to standardise their approach to key management within paymail implementations; this desire extends beyond the scope of paymail and covers cross-wallet key and seed import/recovery processes.
It is suggested that wallet implementers agree upon a mechanism for generating P2PKH output scripts, and create a BRFC to describe that scheme. Such a scheme is advised to avoid address re-use (that is, each P2PKH script includes the hash of the public key of a newly created key pair) and that existing mechanisms such as Type 2 HD Wallet key derivation be used. One advantage to this suggestion is that paymail services can be implemented such that they derive new keys from only an
xpub
. In this way, neither the wallet seed nor any private keys are held by the paymail service implementation.
To illustrate a typical output
field value, a standard P2PKH output script is constructed and encoded below.
Given a key pair with the public key 027c1404c3ecb034053e6dd90bc68f7933284559c7d0763367584195a8796d9b0e
, a P2PKH output script for the same would be hex-encoded as:
76a9140806efc8bedc8afb37bf484f352e6f79bff1458c88ac
This can be broken down as follows:
76 ;OP_DUP
a9 ;OP_HASH160
14 ;Push the next 20 bytes on to the stack
08 06 ef c8 ;ripemd160(sha256(compressed_public_key))
be dc 8a fb
37 bf 48 4f
35 2e 6f 79
bf f1 45 8c
88 ;OP_EQUALVERIFY
ac ;OP_CHECKSIG
The service response body would be:
{
"output": "76a9140806efc8bedc8afb37bf484f352e6f79bff1458c88ac"
}
404 Not Found
The paymail handle was not found by this service.
Extensions to this Specification
- Sender Validation which performs a reverse PKI lookup on the sender then verifies the message signature
- Receiver Approvals extends the payment destination process with asynchronous approvals by the receiver before yielding a payment destination script
Copyright 2019 nChain and Money Button
Sender Validation
brfc | title | author | version |
---|---|---|---|
6745385c3fc0 | bsvalias Payment Addressing (Payer Validation) | andy (nChain) | 1 |
In this extension specification to the Basic Address Resolution, the receiver's paymail service, in response to a request from a sender, performs a Public Key Infrastructure lookup against the sender, to resolve their public key. The receiver's service then verifies the message signature (which is mandatory under this specification), verifies the timestamp of the receiver's request to limit the scope of message replay attacks, and signs the returned output script to prevent message tampering.
Capability Discovery
The .well-known/bsvalias
document is updated to include a declaration of sender validation enforcement:
{
"bsvalias": "1.0",
"capabilities": {
"6745385c3fc0": true
}
}
The capabilities.6745385c3fc0
path is set to true
to indicate that sender validation is in force. Any value other than true
must be considered equivalent to false
and indicates that Sender Validation is not in force.
Changes to Basic Address Resolution:
- Additional capability added to receiver's
.well-known/bsvalias
- Sender clients MUST include a digital signature in the payment destination request message. This changes the
signature
field from optional, under the Basic Address Resolution specification, to mandatory - Receiver services MUST perform a PKI lookup of the sender's paymail handle included in the request
senderHandle
field. If no public key can be resolved, the request MUST fail with HTTP response code401
(Unauthorized) - Receiver services MUST verify that the signature over the payment destination request message is valid. If an invalid signature is present, or no signature is present at all, the request MUST fail with HTTP response code
401
(Unauthorized) - Receiver services MUST verify that the declared date/time in the payment destination request message
dt
field is within two minutes of the receiver service's own clock, in order to limit the scope of replay request attacks. If the value of thedt
field in the request exceeds the allowed time window, the request MUST fail with HTTP response code401
(Unauthorized)
Flow
Sender Request
The body of the POST request is unchanged, however the signature is now a mandatory field:
{
"senderName": "FirstName LastName",
"senderHandle": "<alias>@<domain.tld>",
"dt": "<ISO-8601 timestamp>",
"amount": 550,
"purpose": "message to receiver",
"signature": "<compact Bitcoin message signature>"
}
Receiver Response
200 OK
{
"output": "...",
"signature": "<compact Bitcoin message signature>"
}
The output
field is unchanged from Basic Address Resolution.
The signature
field is added and MUST contain a valid Bitcoin message signature over the UTF8 byte string content of the output
field that senders MUST validate against the receiver's public key. The message digest process and signature encoding scheme is unchanged from that defined in Basic Address Resolution.
401 Unauthorised
This response type is returned when any of the following conditions are true:
- No
signature
is included in the receiver request - The signature included in the receiver request does not validate for the public key returned from the receiver's paymail PKI service
- The timestamp in the
dt
field is more than two minutes away from the sender's paymail service view of the current time
Copyright 2019 nChain and Money Button
Receiver Approvals
brfc | title | author | version |
---|---|---|---|
3d7c2ca83a46 | bsvalias Payment Addressing (Payee Approvals) | andy (nChain) | 1 |
The Receiver Approvals specification extends both Basic Address Resolution and Sender Validation specifications by introducing a callback-based message flow and moving the payment destination process from a synchronous request-response flow to an asynchronous flow. Additional steps for the receiver are introduced, along with additional responses back to the sender, and additional demands on the capabilities of the sender's paymail service.
Capability Discovery
The .well-known/bsvalias
document is updated to include a declaration of Receiver Approval flow support:
{
"bsvalias": "1.0",
"capabilities": {
"3d7c2ca83a46": {
"callback": "https://bsvalias.example.org/{alias}@{domain.tld}/payment-destination-response"
}
}
}
The capabilities.3d7c2ca83a46
object contains a callback
property with a template endpoint URI for incoming payment destination request callbacks.
Changes to Basic Address Resolution and Sender Validation
- An additional response type with HTTP status code
202
(Accepted) is introduced. The body of the202
response contains a token used to correlate a later callback from the receiver to the sender's paymail system with the initiating request from the sender - The receiver's paymail system asynchronously notifies the receiver that the request has been received. The receiver is free to respond to the request at any time; that is to say this step is asynchronous and does not rely on the user being available at the time the request is received
- The specific interaction between the receiver's paymail service and the receiver's client is beyond the scope of this specification
Flow
The Receiver Approval flow diagram detailed below does not include the Sender Validation steps in order to reduce diagrammatic complexity. These steps are mandatory and the flow is detailed in the Sender Validation specification.
Sender Request
There are no changes to the Sender Request as described in the Sender Validation specification.
Receiver Response
Existing 200
, 401
and 404
responses remain unchanged.
202 Accepted
The request was received but further action from the receiver is required. The body of the 202
response MUST contain a correlation token for the sender to later match a callback from the receiver's system to a request initiated by the sender. The response content type MUST be application/json
and MUST conform to the following schema:
{
"token": "...",
"signature": "..."
}
token
MUST be unique across all requests. It is suggested that implementers use a token derivation function over the initiating request, for example the token could be a hex-encoded double-SHA256 hash of all fields of the request.
Sender systems are expected to annotate their local copy of the request with this token in order to match a response callback at some point in the future to the originating request.
The signature
field MUST contain a valid Bitcoin message signature over the UTF8 byte string content of the token
field that senders MUST validate against the receiver's public key. The message digest process and signature encoding scheme is unchanged from that defined in Basic Address Resolution.
Receiver Callback
The capabilities.3d7c2ca83a46.callback
path of the sender's .well-known/bsvalias
document returns a URI template. Receivers should replace the {alias}
and {domain.tld}
template parameters with the values from the receiver's paymail handle and then make an HTTP POST request against this URI.
The request MUST have a content type of application/json
and MUST conform to the following schema:
{
"token": "...",
"output": "...",
"signature": "..."
}
The token
field contains the same token as returned from be Receiver's paymail service during the 202
response.
The output
field is unchanged from Basic Address Resolution.
The signature
field is added and MUST contain a valid Bitcoin message signature over the UTF8 byte string content of the concatenation of the token
and output
field that senders MUST validate against the receiver's public key. The message digest process and signature encoding scheme is unchanged from that defined in Basic Address Resolution.
Rejected Requests
No callback is specified for rejections. Sender clients receive no information about a rejected request. A rejection and an outstanding request are, by design, indistinguishable.
Copyright 2019 nChain and Money Button
PayTo Protocol Prefix
brfc | title | author | version |
---|---|---|---|
7bd25e5a1fc6 | bsvalias Payment Addressing (PayTo Protocol Prefix) | andy (nChain) | 1 |
The PayTo Protocol Prefix specification defines the URI prefix payto:
to mean launch a paymail payment to the specified paymail handle. Additional query string parameters MAY be included; these are defined below.
paymail client implementers SHOULD ensure that their application is registered with the target device operating system as a protocol/deeplink handler for the payto:
protocol prefix.
Full Specification
payto:<receiver>?amount=<amount>&purpose=<purpose>
Token | Required | Description |
---|---|---|
receiver | ✓ | <alias>@<domain>.<tld> formatted paymail handle, for example [email protected] |
amount | Integer number of satoshis to be paid. | |
purpose | Human-readable description of the purpose of the payment |
Capability Discovery
This specification governs client-side behaviour. No specific capabilities are delivered by paymail implementations.
Copyright 2019 nChain and Money Button
Verify Public Key Owner
brfc | title | authors | version |
---|---|---|---|
a9f510c16bde | bsvalias public key verify (Verify Public Key Owner) | andy (nChain), Ryan X. Charles (Money Button), Miguel Duarte (Money Button) | 1 |
This capability allows clients to verify if a given public key is a valid identity key for a given paymail handle.
Motivation
The public key returned by pki flow for a given paymail handle may change over time. This situation may produce troubles to verify data signed using old keys, because even having the keys, the verifier doesn't know if the public key actually belongs to the right user.
Capability discovery
The .well-known/bsvalias
document is updated to include a declaration public key owner validation enpoint:
{
"bsvalias": "1.0",
"capabilities": {
"a9f510c16bde": "https://example.bsvalias.tld/api/{alias}@{domain.tld}/{pubkey}"
}
}
The capabilities.a9f510c16bde
is a template URL to verify the ownership of the public key.
Client Request
The capabilities.a9f510c16bde
path returns a URI template. Senders MUST replace {alias}
, {domain.tld}
placeholders with a valid paymail handle. {pubkey}
placeholder MUST be a valid point on the secp256k1 curve, compressed, and hex-encoded. The client MUST perform a GET request to the obtained URL.
Server Response
Below are the responses that have meaning to this protocol. A server may return other status codes, for example 5xx
indicating some sort of server failure. Clients should treat status codes not specified as part of this specification as some sort of transient error and may retry at their leisure.
200 OK
Returned when a valid request was made. The response MUST have application/json
as content type. The response body MUST follow this schema:
{
"handle":"[email protected]",
"pubkey":"<consulted pubkey>",
"match": true,
}
Field | Description |
---|---|
handle | queried handle |
pubkey | queried public key |
match | true if pubkey belongs to paymail handle. false otherwise. |
This endpoint returns status 200 everytime the request is valid. If the paymail handle is unknown to the server it returns 200 anyway, but false
in the match field.
Changes to Address Resolution
Basic Address Resolution is extended as follows:
In order to use this capability the client needs to send a public key. The server will verify the signature against that public key and also will verify that the signature belongs to the sender.
Client Request
A public key is added to the body of the request. The final schema is the following:
{
"senderName": "FirstName LastName",
"senderHandle": "<alias>@<domain.tld>",
"dt": "<ISO-8601 timestamp>",
"amount": 550,
"purpose": "message to receiver",
"signature": "<compact Bitcoin message signature>",
"pubkey":"<valid public key>"
}
Flow
Copyright 2019 nChain and Money Button
Recommendations
paymail lives on the public web. As such, it is recommended that standard defensive mechanisms are deployed. These include, but are not limited to:
- maintain access logs
- prevent information leakage, including through error messages
- do not keep sensitive information on internet-connected servers
- place limits on everything, even if they are high
- rate limits
- maximum message size limits
- bad request limits (leading to a ban)
- malformed requests
- suspicious requests
- secure the host operating system and environment
- operate under the principle of least privilege
- do not trust any input to any API endpoint
- assume all API calls are hostile until proven otherwise
- sanitize everything
- keep software/library/dependency versions up to date
There are additional concerns that are specific to the paymail service:
- consider the meanings of request bodies
- whilst it might be normal for an online retail store to receive a high volume of payment destination requests and pay to email posts, consider the amounts being paid. a valid transaction might not count towards some sort of ban limit, but maybe it should if the service receives thousands of dust transactions a second
- infinite-loop payment destination requests might be valid but can lead to resource exhaustion, both CPU (during key derivation) and address space (individual Type 2 HD Wallet derivation paths, for example, are not infinite)
- consider if the request is really probing for leaked information, rather than performing its intended function
- see the 401 Unauthorised response section of the Pay-to-Email specification for an example
- consider risks to funds
- use
xpub
or nChain public key derivation for payment destination discovery. do not keep wallet seeds or private keys in paymail services, as these are a gold mine waiting to be stolen by a malicious adversary
- use
Copyright 2019 nChain and Money Button