LogoLogo
  • README
  • Contribute
    • Discuss on Github
  • Example
    • Banana-Powered Bitcoin Wallet Control Protocol
  • Apps
    • The deployment-info.json Specification
  • Wallet
    • Transaction Creation
    • Data Encryption and Decryption
    • Digital Signature Creation and Verification
    • Input Redemption
    • HTTP Wallet Communications Substrate
    • XDM Wallet Communications Substrate
    • Window Wallet Communication Substrate
    • Wallet Transaction Output Tracking (Output Baskets)
    • Submitting Received Payments to a Wallet
    • Certificate Creation and Revelation
    • Unified Abstract Wallet-to-Application Messaging Layer
    • Transaction Labels and List Actions
    • Output Basket Removal and Certificate Deletion
    • Group Permissions for App Access
    • Extensible Proof-Type Format for Specific Key Linkage Claims
    • P Protocols: Allowing future wallet protocol permission schemes
    • P Baskets: Allowing Future Wallet Basket and Digital Asset Permission Schemes
    • Unified, Vendor-Neutral, Unchanging, and Open BSV Blockchain Standard Wallet-to-Application Interface
  • Transactions
    • Everett-style Transaction Envelopes
    • Simplified Payment Verification
    • Merkle proof standardised format
    • TSC Proof Format with Heights
    • Raw Transaction Format
    • TXO Transaction Object Format
    • Transaction Extended Format (EF)
    • Merkle Path JSON format
    • Compound Merkle Path Format
    • Background Evaluation Extended Format (BEEF) Transactions
    • Simplified Payment Verification
    • Merkle Path Binary Format
    • BSV Unified Merkle Path (BUMP) Format
    • Graph Aware Sync Protocol
    • Scalable Transaction Processing in the BSV Network
    • Atomic BEEF Transactions
    • BEEF V2 Txid Only Extension
  • Scripts
    • Bitcoin Script Binary, Hex and ASM Formats
    • Bitcoin Script Assembly Language
    • Pay to Public Key Hash
    • Pay to R Puzzle Hash
    • Pay to False Return
    • Pay to True Return
    • Push TX
    • Bare Multi-Signature
    • Pay to Push Drop
  • Tokens
    • There is no BRC-20
    • Definition of UTXOs as Bitcoin Tokens
    • Token Exchange Protocol for UTXO-based Overlay Networks
    • Mandala Token Protocol
  • Overlays
    • Overlay Network Data Synchronization
    • Confederacy Host Interconnect Protocol (CHIP)
    • Overlay Network Lookup Services
    • Confederacy Lookup Availability Protocol (CLAP)
    • Universal Hash Resolution Protocol
    • Overlay Network Transaction History Tracking
    • Private Overlays with P2PKH Transactions
    • Standardized Naming Conventions for BRC-22 Topic Managers and BRC-24 Lookup Services
    • Overlay Services Synchronization Architecture
    • Diverse Facilitators and URL Protocols for SHIP and SLAP Overlay Advertisements
  • Payments
    • Direct Payment Protocol (DPP)
    • Paymail Payment Destinations
    • Simple Authenticated BSV P2PKH Payment Protocol
    • PacketPay HTTP Payment Mechanism
    • Hybrid Payment Mode for DPP
    • HTTPS Transport Mechanism for DPP
    • Paymail BEEF Transaction
    • HTTP Service Monetization Framework
  • Peer-to-Peer
    • Authrite Mutual Authentication
    • PeerServ Message Relay Interface
    • PeerServ Host Interconnect Protocol
    • Identity Certificates
    • Genealogical Identity Protocol
    • Publishing Trust Anchor Details at an Internet Domain
    • Message Signature Creation and Verification
    • Serialization Format for Portable Encrypted Messages
    • Defining a Scalable IPv6 Multicast Protocol for Blockchain Transaction Broadcast and Update Delivery
    • Proven Identity Key Exchange (PIKE)
    • Peer-to-Peer Mutual Authentication and Certificate Exchange Protocol
    • HTTP Transport for BRC-103 Mutual Authentication
  • Key Derivation
    • BIP32 Key Derivation Scheme
    • BSV Key Derivation Scheme (BKDS)
    • Security Levels, Protocol IDs, Key IDs and Counterparties
    • Admin-reserved and Prohibited Key Derivation Protocols
    • Revealing Key Linkages
    • Protecting BRC-69 Key Linkage Information in Transit
    • Mnemonic For Master Private Key
    • Linked Key Derivation Scheme
    • Bidirectionally Authenticated Derivation of Privacy Restricted Type 42 Keys
    • Limitations of BRC-69 Key Linkage Revelation
    • Verifiable Revelation of Shared Secrets Using Schnorr Protocol
  • Outpoints
    • Format for Bitcoin Outpoints
    • Spending Instructions Extension for UTXO Storage Format
  • Opinions
    • Users should never see an address
    • List of user experiences
    • Legitimate Uses for mAPI
    • Security and Scalability Benefits of UTXO-based Overlay Networks
    • Improving on MLD for BSV Multicast Services
    • Web 3.0 Standard (at a high level)
    • Thoughts on the Mandala Network
    • Outputs, Overlays, and Scripts in the Mandala Network
  • State Machines
    • Simplifying State Machine Event Chains in Bitcoin
Powered by GitBook
On this page
  • Abstract
  • Motivation
  • Specification
  • Application Message Sending and Processing
  • Wallet Message Receipt, Processing and Response
  • Values for call Associated with Various Message Types
  • Implementations

Was this helpful?

Edit on GitHub
Export as PDF
  1. Wallet

XDM Wallet Communications Substrate

PreviousHTTP Wallet Communications SubstrateNextWindow Wallet Communication Substrate

Last updated 1 year ago

Was this helpful?

Ty Everett (ty@projectbabbage.com)

Abstract

Cross-document messaging enables web-based applications to communicate with one another in a secure manner, without allowing the two applications to manipulate each other's DOM trees. It defines a mechanism by which messages can be sent and received, with browser-based attestation of the origin of each message. We define the framework and conventions for operating a wallet over XDM, enabling a parent page that runs a wallet to communicate with one or multiple child pages that run applications.

Motivation

defines a suite of abstract messages used by applications and wallets to facilitate various Bitcoin and MetaNet operations that enable micropayments, protect user privacy and ensure secure authentication without the need for each application to maintain a separate user account. While defines a method of using a wallet over HTTP on the local machine, some mobile devices are unable to support running HTTP servers due to platform-specific limitations. Additionally, it is sometimes desirable for a MetaNet environment to run fully in the browser, enabling users to access their identities on devices or platforms where a desktop-based client cannot be installed. This specification provides a ubiquitous communications substrate enabling the use of functionality across a wide range of devices and deployment contexts, including fully in-browser experiences.

Specification

We specify that the parent page runs the wallet, responding to messages from child pages. This has several advantages:

  • The wallet can always pop-up any necessary permission popups or user-interactive authorization screens without interference from client pages

  • When the user visits the parent page, they log in once, then they can access any applications after login

  • Multiple applications, all running in the same parent page, can access and utilize the wallet at once

  • Reducing the number of wallets running in parallel reduces the chances of UTXO synchronization or corruption issues

  • It is possible to run the parent wallet page locally, connecting to remote services only when required by specific applications

  • If a specific application was the parent and the wallet was a child, failure of the parent page to respond could constitute failure of a user to access their identity or assets, which might otherwise be available through another application

Application Message Sending and Processing

We start with the message relay interface defined by XDM. JavaScript code for sending messages from the application to the wallet is as follows:

new Promise((resolve, reject) => {
  const id = 'abcdabcd' // get a random message ID
  window.addEventListener('message', async e => {
    if (e.data.type !== 'CWI' || !e.isTrusted || e.data.id !== id || e.data.isInvocation) return
    if (e.data.status === 'error') {
      const err = new Error(e.data.description)
      err.code = e.data.code
      reject(err)
    } else {
      resolve(e.data.result)
    }
  })
  window.parent.postMessage({
    type: 'CWI',
    isInvocation: true,
    id,
    call: 'getVersion',
    params: {}
  }, '*')
})

We stipulate that:

  1. All messages (requests, responses and errors) have a type property equal to CWI (this value, which stands for Computing with Integrity, is historical)

  2. A random message ID is generated by the application

  3. The application listens for new, incoming response messages. As part of the listener, the application:

    • Drops any events without the correct type in the event data

    • Drops any events where isTrusted is not true

    • Drops any events where the event data contains the isInvocation flag, denoting any outgoing messages that were echoed back

    • Drops any events where the event data contains an id field other than the one generated by step 2

    • Handles any error messages if the event's data contains a status field equal to error, relying on the code and description fields to construct an appropriate error

    • Otherwise, if no errors are detected, the application is now free to make use of the result field from the event's data payload, which will be the response from the wallet as specified by the relevant BRC standard for the specific message being sent

  4. With the listener in place and ready to process the response when it arrives, the application now constructs and sends the message to the wallet through the parent window:

    • Like all messages, the outgoing message contains a type field equal to CWI

    • An isInvocation flag is set to true, allowing listeners to easily drop outgoing messages rather than trying to process them as responses

    • The id that was generated in step 2 is included. The same id must be used by wallets when sending back the response

    • The call determines which message is being sent. Specific call values are defined below

    • The params field comprises the specific parameters as specified in BRCs that define specific message types

Wallet Message Receipt, Processing and Response

The wallet listens for incoming messages and replies to the originator with appropriate responses after obtaining permission from the user (if applicable) and processing the request. Some JavaScript code that implements this functionality is provided:

window.addEventListener('message', async e => {
  if (e.data.type !== 'CWI' || !e.isTrusted || typeof e.data.call !== 'string') return

  // This is where the wallet will do its processing, based on `call` and `params`.

  // ... in a rudamentary implementation ...

  if (e.data.call === 'createAction') { // BRC-1
    try {
      let result = await doBRC1Thing({
        ...e.data.params,
        originator: e.origin // You might let BRC1Thing know which app is sending the request, for permission purposes
      })
      e.source.postMessage({
        type: 'CWI', result, id: e.data.id
      }, e.origin)
    } catch (error) {
      e.source.postMessage({
        type: 'CWI',
        id: e.data.id,
        status: 'error',
        code: error.code || 'ERR_UNKNOWN',
        description: error.message
      }, e.origin)
    }
  } else if (e.data.call === 'encrypt') { // BRC-2 encrypt
    try {
      let result = await doBRC2Thing({
        ...e.data.params,
        originator: e.origin // You might let BRC2Thing know which app is sending the request, for permission purposes
      })
      e.source.postMessage({
        type: 'CWI', result, id: e.data.id
      }, e.origin)
    } catch (error) {
      e.source.postMessage({
        type: 'CWI',
        id: e.data.id,
        status: 'error',
        code: error.code || 'ERR_UNKNOWN',
        description: error.message
      }, e.origin)
    }
  } // ... implement all functions ...

})

We stipulate, before any client applications are loaded which might send any messages to the wallet, that the wallet running on the parent page must bind a message event handler that:

  1. Upon receipt of a message with an event data field type not equal to CWI will drop the message

  2. Upon receipt of an untrusted message, or one without a call will drop the message

  3. Upon receipt of a message with an unknown or unsupported call will proceed to step 6

  4. Based on the call and params will perform the necessary steps as required by the relevant BRC specifications for the specific operation

  5. Compose a response message and send it back to the originator, the response message comprising an event payload with the following fields:

    • A type value of CWI

    • The id that was specified by the application when the message was created

    • A result value that is the result of the operation being performed, as specified by the particular operation

  6. In case of any errors with the operation, the wallet will instead send back a response message comprising an event payload with the following fields:

    • A type value of CWI

    • A status value of error

    • The id that was specified by the application when the message was created

    • A relevant code for the error, as specified by the particular operation in question

    • A human-readable description for the error

Values for call Associated with Various Message Types

Message Pair

call Value

Specific Implementation Notes

createAction

encrypt

decrypt

createSignature

verifySignature

createCertificate

proveCertificate

createHmac

verifyHmac

getPublicKey

ninja.findCertificates

This call name prefix is historical and retained for compatibility

getVersion

getNetwork

isAuthenticated

waitForAuthentication

Implementations

Implementation questions should be directed to the author.

This application-side interface facilitates exchanging and receiving messages with the wallet over XDM. We now proceed to how the wallet handles its side of the interaction.

For each of the message pairs (request and response) incorporated into , we specify the existence of a corresponding XDM message pair with a specific call value:

Transaction Creation

Encryption

Decryption

Signature Creation

Signature Verification

Certificate Creation

Certificate Verification

HMAC Creation

HMAC Verification

Public Key Derivation

Certificate List

Version Request

Network Request

Authentication Request

Async Auth Request

Implementers of applications and wallets will need to create and process XDM messages in the manner described, according to the various fields and properties as required by , and in a manner consistent with the reference implementation, which is the 's XDM substrate functionality.

One (crude) example of a deployed architecture in which a parent page uses XDM to communicate with child application pages, facilitating the operation of multiple client applications which communicate with the parent wallet, has been implemented by the Babbage team at .

BRC-56
BRC-56
BRC-5
BRC-56
BRC-5
BRC-56
BRC-56
BRC-56
BRC-56
BRC-56
Babbage SDK
BabbageOS.com
BRC-1
BRC-2
BRC-2
BRC-3
BRC-3
BRC-53
BRC-53
BRC-56
BRC-56
BRC-56
BRC-56
BRC-56
BRC-56
BRC-56
BRC-56