Unified Abstract Wallet-to-Application Messaging Layer
Ty Everett (ty@projectbabbage.com)
Brayden Langley (brayden@projectbabbage.com)
Abstract
The importance of a standard interface by which Bitcoin applications can communicate with wallets and underlying infrastructure cannot be overstated. We propose an identity interface facilitating the creation of Bitcoin transactions, the use of user-held keys for encryption and digital signatures, and the employment of identity certificates to authenticate users with their counterparties. We set a baseline standard and create a versioning system that facilitates continued expansion and extensibility over time.
Motivation
Computing has long been subject to shortfalls in the areas of information centralization and architectural cross-compatibility. Users on the internet struggle with complex and insecure authentication systems which leave them vulnerable and leak their data. Websites rely on advertising to monetize their offerings, but ads warp the incentives of platforms and creators in ways that ultimately harm everyone involved. By defining a standard interface by which users can identify themselves, protect their data and engage in e-commerce with Bitcoin, this standard offers a solution to problems that have long plagued the existing model.
Specification
We specify a baseline standard for an abstract messaging layer which facilitates an identity interface between an application and an underlying MetaNet Client. As part of this messaging layer, we incorporate various message types defined by other BRC standards:
BRC-1: We incorporate by reference the message types relating to Bitcoin transaction creation as specified by BRC-1. This facilitates micropayment-based interactions as part of applications, enabling new monetization models that are not subject to the same problematic incentives as internet-based advertising.
BRC-3: We incorporate by reference the message types relating to digital signatures as specified by BRC-3. This facilitates generalized message sender attestation and endorsement, solving problems such as fake AI-generated content by allowing relevant parties or the entire world to check whether something has been endorsed by its purported originator.
BRC-4: We incorporate by reference the extension to BRC-1 as defined by BRC-4, providing for the consumption and utilization of arbitrary UTXO-based Bitcoin tokens as part of transactions. This facilitates the creation and transfer between users of tokenized assets without restrictions beyond those set by their respective output locking scripts.
BRC-46: We incorporate by reference the extension to BRC-1 as defined by BRC-46, providing for the tracking and management of Bitcoin UTXOs in baskets. This facilitates the storage and retrieval of single-party tokens and digital assets in the user's wallet while removing the need to rely on a single trusted application for asset management.
BRC-50: We incorporate by reference the message types relating to incoming transaction submission as specified by BRC-50, ensuring users have a way to receive funds into their wallets from within applications. This gives them a way to receive payment for the value they create as part of their interactions within applications.
BRC-53: We incorporate by reference the message types relating to digital identity certificate creation and revelation, as specified by BRC-53. This provides a way for users to maintain and selectively reveal their identities with specific counterparties in the digital world, facilitating an increased level of trust and accountability.
With these core components in place, we are left only with the need to specify a few other messages that are necessary to facilitate versioning, user network checking and user-to-wallet authentication status discovery. We now proceed to the specification of those auxiliary messages.
HMACs
The introduction of HMACs are the most significant addition aside from the core message types. HMACs facilitate authenticating messages sent between users, and are generally useful for a wide range of applications.
We stipulate the following process for HMAC creation:
The message sender begins by computing the BRC-43 invoice number based on the security level, protocol ID, and key ID
The message sender uses BRC-42 key derivation with the computed invoice number to derive a child public key for the recipient
The message sender uses BRC-42 key derivation with the computed invoice number to derive their own child private key
The message sender computes the ECDH shared secret between the two derived child keys
The resulting elliptic curve point's X and Y values are hashed with SHA256 to create a SHA-256 HMAC key
The resulting 256-bit value is used to compute the SHA-256 HMAC for the message
The HMAC value is returned by the client to the application over the abstract BRC-1 communications substrate.
We stipulate the following process for HMAC verification:
The recipient somehow comes to know the HMAC, the message, the counterparty, the security level, protocol ID, and key ID. The mechanism for conveying this information to the recipient is beyond the scope of this specification.
The recipient begins by computing the BRC-43 invoice number based on the security level, protocol ID, and key ID
The recipient uses BRC-42 key derivation with the computed invoice number, their own private key and the public key of the sender, to compute the sender's child public key
The recipient uses the same process to compute his own child private key
The recipient computes a shared secret between the two child keys, using the hash of the X and Y values as a SHA-256 HMAC key
The recipient then uses the HMAC key to compute the HMAC of the message, checking that the computed value matches the provided value
HMAC Creation Request
The HMAC Creation Request is a message sent by the BRC-43 application to the client. It contains a header with the following information:
protocolID
keyID
counterparty
The message payload comprises the data to HMAC.
HMAC Creation Response
The response message comprises a payload containing the computed HMAC value.
HMAC Verification Request
The HMAC Verification Request is a message sent by the application to the client. It contains a header with the following information:
protocolID
keyID
counterparty
hmac
This is the HMAC value that is to be verified, for the provided message
The message payload comprises the data to verify against the HMAC provided in the header.
HMAC Verification Response
The response message comprises a payload containing a boolean that indicates whether the HMAC was successfully verified.
HMAC Error
If the client is unable to fulfill the HMAC Creation or Verification Requests for any reason except failed verification, we specify that it should respond with a JSON-formatted HMAC Error. The fields for the object are specified as follows:
status
This should always be a string comprising "error"
.
code
A machine-readable error code. Extensions to this standard can define specific error codes and standardize additional fields. Codes are strings, for example "ERR_PERMISSION_DENIED"
.
description
All errors must have a human-readable description
field that describes the error. This allows the application to represent the error for the user.
One example of an HMAC Error is given below:
Public Key and Certificate Retrieval
Facilitating access to public keys and certificates are a crucial part of the wallet messaging layer as they provide the necessary components for identity verification. BRC-43 is used for defining the protocolID and keyID formats, and BRC-52 defines the format of certificates requested.
Public Key Request
To request a public key, we define the following standard request fields:
protocolID
keyID
counterparty
forSelf
Whether the derived child public key corresponds to a private key held by the current user. (optional, default false)
identityKey
If true, the identity key will be returned, and no key derivation will be performed (optional, default false). Overrides protocolID
, keyID
, counterparty
, and forSelf
.
When the wallet receives this request from the application, after obtaining requisite permission from the user, we stipulate the following process for key derivation:
If
identityKey
is true, the wallet returns its root public identity key to the application without proceeding to the other steps.The wallet checks the BRC-43 invoice number based on the security level, protocol ID, and key ID
If
forSelf
isfalse
, the wallet uses BRC-42 key derivation with the computed invoice number to derive a child public key for the counterparty, returning the public key.Otherwise, if
forSelf
istrue
, the wallet uses BRC-42 key derivation with the computed invoice number to derive their own child private key. The wallet then multiplies the private key by the generator point, G, to arrive at their own child public key, as would be derived by a counterparty. The computed public key is returned.
Public Key Response
The response message comprises a 33-byte, DER-encoded public key X coordinate value.
Public Key Error
If the client is unable to fulfill the Public Key Request for any reason, we specify that it should respond with a JSON-formatted Public Key Error. The fields for the object are specified as follows:
status
This should always be a string comprising "error"
.
code
A machine-readable error code. Extensions to this standard can define specific error codes and standardize additional fields. Codes are strings, for example "ERR_PERMISSION_DENIED"
.
description
All errors must have a human-readable description
field that describes the error. This allows the application to represent the error for the user.
One example of a Public Key Error is given below:
Certificate List Request
To request a list of BRC-52 identity certificates belonging to the user, we define these standard request fields:
certifiers
An array of the public keys for certifiers to filter certificates by: only certificates issued by these certifiers will be returned.
types
The certificate types to filter certificates by, given as an object whose keys are types and whose values are, for historical reasons, arrays of fields to request from certificates of the given type. Note that unless all fields are returned, no one can validate the certificate signature. We therefore specify that if true
is provided in place of an array of fields, that all fields should always be returned.
When the wallet receives this message from the application, the wallet will ascertain based on user preferences and the information provided which certificates will be returned. The wallet is by no means required to return all responsive certificates, if for example the user does not want to reveal a particular affiliation in a particular context. The wallet composes a list, which may be empty, of responsive certificates.
Certificate List Response
The response from the wallet to the application comprises an array of BRC-52 identity certificates, which may be empty.
Certificate List Error
If the client is unable to fulfill the Certificate List Request for any reason except an empty list, we specify that it should respond with a JSON-formatted HMAC Error. The fields for the object are specified as follows:
status
This should always be a string comprising "error"
.
code
A machine-readable error code. Extensions to this standard can define specific error codes and standardize additional fields. Codes are strings, for example "ERR_PERMISSION_DENIED"
.
description
All errors must have a human-readable description
field that describes the error. This allows the application to represent the error for the user.
One example of a Certificate List Error is given below:
Network, Versioning and Authentication
Another important aspect of the wallet messaging layer is allowing applications the ability to check which Bitcoin network is in use, and whether or not a user has been authenticated.
Bitcoin Network Request
To determine which Bitcoin network a user's MetaNet Client is currently using, applications can make requests to a standardized endpoint to ensure compatibility.
We define that the request message has no content (beyond the fact of it being a Bitcoin Network Request) and simply returns a string of either "test"
or "main"
indicating the current network in use.
Client Version Request
We define the standard client version request to contain no parameters (beyond the fact of it being a Client Version Request) and to simply return the version of the MetaNet Client in use as a string.
For historical reasons, to denote compatibility with these specifications, we stipulate that the version should be in the range 0.3.x
. For example, 0.3.80
.
Authentication Status Request
The authentication status request requires no parameters and returns a boolean indicating whether the current user is "authenticated" or not.
The purpose of this functionality is to facilitate software where the user can "log in" once in their client, and never need a separate login for MetaNet applications. When not authenticated, the application should assume that none of the other functionality, aside from client version checks, will work. It provides a way for applications, when they load, to ensure that the communication system with the client is operational, as a sort of "ping" request that also ensures the user is set up with a wallet.
Asynchronous Authentication Request
The asynchronous authentication request requires no parameters and waits until the user is authenticated before returning a response of true.
Implementations
Implementations of this specification will need to decide on a concrete transport layer (referred to as a "substrate") to facilitate communication between the wallet and applications. Application developers will then need to write their applications in a way that facilitates communication over the substrate, and wallets will need to properly handle incoming requests from applications.
Some examples of communication substrates include:
BRC-5, for operating a wallet over HTTP on a local machine, enabling applications on that machine to interact with the running wallet.
BRC-6, for cross-document messaging between a parent page which runs a wallet and a set of child pages which run various applications.
BRC-7, for exposing an identity interface via the
window
object in web browsers.
The BRC-56 functions and messages, across these three substrates, have been implemented by the Babbage team in the Babbage SDK.
Last updated