The Blockchain Commons Uniform Resource (UR) technology is designed to make it easy to transmit structured binary data via several methods, including text and QR codes. It addresses the inherent size limits of QR codes by supporting streaming message fragments using fountain codes.
Blockchain Commons, in cooperation with members of the airgapped wallet community, has expanded URs by developing a proposed standard for a UR-based message architecture that can be used as a standard design pattern to request various actions from network-isolated devices (crypto-request
), and for those devices to respond to those requests (crypto-response
).
For the purpose of signing Partially Signed Bitcoin Transactions (PSBTs), some developers have chosen to use a bare UR-encoded PSBT (crypto-psbt
) as a way to request a signature instead of using crypto-request
and crypto-response
. This approach, while straightforward, has a number of distinct disadvantages over the request-response pattern that Blockchain Commons has proposed. The purpose of this document is to explain the motivation for the request-response architecture, in order to encourage its universal adoption by the airgapped wallet community.
As a tool for handing structured data, each top-level UR has a type. The bare UR-encoded crypto-psbt
, which represents a single PSBT, is one of those. The intention with PSBTs is that they be generated by one party, and then passed around to one or more other parties for co-signing. The co-signed PSBTs are then passed to another party (which could be the originating party) who finalizes the transaction and produces a fully-signed transaction ready to be transmitted to the Bitcoin network.
The PSBT specification allows for the inclusion of additional metadata about the transaction such as the identity and derivation paths of the BIP-32 HD keys that must be used to sign the transaction's inputs. PSBTs can also contain user-specified data, but this usage can become problematic if a user attempts to convey complex policies that PSBTs themselves were never designed to handle, such as the creator of the transaction, the intention for the transaction's use, the business rules that are being enforced or that must be enforced by the co-signers, or the motivation that signers should have to actually sign the transaction.
PSBTs were never meant to convey general business rules of this sort: they are not a mechanism of coordination between parties. Instead, in order to convey higher-level communications between parties, a PSBT may need to be used in conjunction with other structures. That's where the crypto-request
and crypto-response
URs come in.
Any UR type that can be conveyed as a top-level UR (such as crypto-psbt
) can also be embedded as a CBOR object within a larger object (such as crypto-request
or crypto-response
). While Blockchain Commons produced the spec for a crypto-psbt
type, which presents only a raw PSBT, we also recognized the need to more generally facilitate higher-level conversations between participants. The crypto-psbt
spec does nothing more than present a transaction that may or may not have some of its inputs signed; it does not carry any semantics about what the recipient should actually do with the transaction it receives. While the recipient of a PSBT might assume that its mere receipt implies a request to sign the transaction, we can easily imagine scenarios where the intent of transmitting a PSBT is not for it to be signed, but for it to be stored for later retrieval, relayed to another party, validated against some set of business rules, or finalized and transmitted to the network.
Therefore as a best practice, requests for actions should be explicit between participants. This is similar in nature to other established protocols like HTTP, where a request consists of a both verb and a noun, e.g., GET https://blockchaincommons.com
. A URL by itself is just a pointer, and as such is ambiguous. PSBTs are similar: by itself, a PSBT is not actually a request to sign a transaction; it is merely a transaction in a possibly unsigned and unfinalized state.
This need for clarity was the motivation for Blockchain Commons to create the crypto-request
and crypto-response
specifications. These URs are messages designed to facilitate participants' understanding of what they are being asked to do, in workflows that vary in complexity.
NOTE: To avoid terminology confusion with PSBTs and finalized Bitcoin "transactions", in the present document we will resist the urge to call the sending of requests and receiving of responses "transactions between the parties" and shall instead simply refer to them as requests and responses.
The initial specification for crypto-request
and crypto-response
supports three scenarios:
- The requester provides a seed digest, and wishes the responder to reply with the corresponding
crypto-seed
. - The requester provides an HD key fingerprint, derivation path, and type of desired key (private or public), and wishes the responder to reply with the corresponding derived HD key. The fingerprint may also be omitted, in which case the respondant can choose the seed or key from which to perform the specified derivation.
- The requester provides a
crypto-psbt
, and wishes the responder to reply with anothercrypto-psbt
containing as many output signatures as it can perform.
The crypto-request
CBOR object is currently defined as follows:
crypto-request = {
transaction-id: uuid,
body: request-seed / request-hdkey-derivation / request-psbt-signature,
? description: text ; Text to be displayed to the approving user.
}
The crypto-request
structure includes a transaction-id
field and an optional description
field. Fields at this level are intended to help facilitate all sorts of requests.
The purpose of the transaction-id
is so that transaction producer/coordinators can receive responses to their requests and know that these responses have been generated specifically to service their particular requests, and are not responses to some other request. In general, the sender of a request must not accept a response that does not contain the same transaction-id
as the one in the request. This may not be necessary for simple, relatively stateless interactions, but could be crucial for more complex ones.
The purpose of the optional description
field is to provide an advisory to the human user receiving the request as to its meaning or purpose.
In the case of a request for a PSBT signature, the body
field is defined as follows:
;
; Returns the given PSBT with one or more outputs signed.
;
request-psbt-signature = #6.502({
psbt: crypto-psbt
})
As you can see, the body
of a crypto-request
is an enumerated type that expresses the nature of the request (e.g., "sign this psbt") and the data needed to perform the action (e.g., the PSBT itself). Because this information is being conveyed as structured CBOR data, it also inheres the possibility for future extension: both in the kind of actions that can be requested, and in what data is included as parameters for particular requests.
The higher-level crypto-request
structure may thus be extended with other alternatives for the body
field, and the nested request-psbt-signature
structure may be extended with additional fields that specify, for example, additional validations to be performed or additional business rules to be enforced. Extending the existing structures would involve identifying use-case scenarios that the community would find useful, specifying additional fields and/or semantics to be added to the existing specifications, and updating reference implementations to support those extensions, including ensuring backward compatibility.
Given the structured nature of CBOR, future request types could even contain sub-requests of their own, enabling multi-level scenarios. The simplest practical use of this capability would be to specify an extension to crypto-request
that supports the ability to encapsulate several sub-requests to be performed by the receiver and returned in a single crypto-response
.
The purpose for this generality is so that Blockchain Commons can work with the larger community to build the extensions needed to work with emergent scenarios, and to standardize on solutions that meet the greatest shared needs. Please consider how this general design pattern might fulfill your own needs for higher-level communications associated with Bitcoin transactions, and talk to us about how the design pattern might best be utilized for your purposes.
Taken together, crypto-request
and crypto-response
provide a powerful general architecture for facilitating multi-party, multi-way conversations. It was never the intent of Blockchain Commons that crypto-psbt
was to be used a signing request, but rather as a more general component in larger scenarios. The present particular need for requesting signatures on PSBTs and returning signed PSBTs is a use-case for early adoption of the request-response framework in the airgapped wallet community. It can and will be extended. Blockchain Commons strongly recommends that airgapped wallet providers support crypto-request
and crypto-response
out of the box, and not rely on more ambiguous and less future-proof methods.