For the complete documentation index, see llms.txt. This page is also available as Markdown.

Simple Authenticated BSV P2PKH Payment Protocol

Ty Everett (ty@projectbabbage.com)

Abstract

This BRC specifies a protocol for exchanging simple P2PKH payments between a sender and a recipient in a way that is SPV-compliant and cross-compatible. The protocol makes use of BRC-42 key derivation to derive public and private keys between users and BRC-62 / BRC-95 BEEF data to relay transaction validation information. Current wallet implementations use BRC-100 createAction and internalizeAction to construct and receive these payments.

Motivation

The motivation for this BRC is to establish a simple, secure, and cross-compatible payment protocol that facilitates P2PKH payments across the BSV ecosystem. The protocol utilizes BRC-42 key derivation to provide a privacy-enhanced approach to P2PKH transactions. The incorporation of BRC-9 SPV checking ensures secure validation of transactions while maintaining efficient processing times. This standard aims to simplify the process of P2PKH payments for wallets and applications, providing a straightforward implementation path for developers.

Status Note

The original JSON payment message in this document used extended BRC-8 transaction envelopes. That framing is historical for new wallet integrations. Current bsv-blockchain/ts-sdk and wallet-toolbox integrations use BRC-100 transaction creation, Atomic BEEF transport, and internalizeAction remittance metadata.

Implementers SHOULD treat the legacy transactions array of BRC-8 envelopes as deprecated unless explicitly maintaining compatibility with older systems.

Specification

We specify a protocol for exchanging simple P2PKH payments between a sender and a recipient. The protocol employs BRC-42 key derivation to derive related public and private keys with invoice numbers, BEEF transaction data to relay SPV-related information, and recipient-side wallet validation to internalize the payment.

Key Derivation Scheme

As defined by BRC-42, the sender and the recipient each have a master private key and a master public key. The invoice number is used to derive related keys, which can be used to facilitate payments. A payment sender can derive a public key for the recipient, and with the same invoice number, the recipient can derive the corresponding private key.

We start with the need for a unique identifier for the payment, used for key derivation. To provide for the possibility that multiple outputs can be exchanged as part of the same payment, we also need a UTXO-specific number. We specify these two values as follows:

  • Derivation Prefix: A unique value generated by the sender of a payment to distinguish keys used within this payment from keys used in other payments.

  • Derivation Suffix: Each suffix is a unique value generated by the sender, so that each UTXO in the same payment has a different key, and so that the keys are not linkable by third parties.

The keys that protect the funds exchanged under this protocol are derived with BRC-42 key derivation by the sender from the identity key of the recipient. The invoice number is specified as follows:

Where:

  • 2 is a protocol security level denoting the access restrictions applied under this protocol (see BRC-43 Security Levels)

  • 3241645161d8 is a magic number that denotes compliance with this BRC

  • <derivationPrefix> is the payment-specific prefix used to arrive at a common key universe for all outputs in this payment

  • <derivationSuffix> is the UTXO-specific suffix used to arrive at a unique key for a specific P2PKH UTXO

Current BRC-100 Payment Construction

The sender creates one or more P2PKH outputs spendable by the recipient-derived key:

  1. Obtain the recipient identity key.

  2. Generate a payment-wide derivationPrefix.

  3. Generate a unique derivationSuffix for each payment output.

  4. Derive the recipient public key with BRC-42 using:

    • protocol ID [2, "3241645161d8"]

    • key ID <derivationPrefix> <derivationSuffix>

    • counterparty equal to the recipient identity key

  5. Convert the derived public key into a P2PKH locking script as defined by BRC-16.

  6. Call BRC-100 createAction with outputs paying those locking scripts.

For each BRC-100 output, customInstructions SHOULD carry enough remittance data for the recipient or service layer to identify the payment, commonly:

When a protocol requires a known payment output index, the sender SHOULD set options.randomizeOutputs to false.

Current Payment Message Construction

Current integrations transport the resulting transaction as Atomic BEEF. A JSON payment message for a single transaction commonly contains:

If multiple outputs or transactions are used, the message MUST include the derivation suffix and output index for every output intended for the recipient. The exact outer envelope may be defined by the higher-level protocol carrying the payment, such as BRC-105 for HTTP service monetization.

Legacy JSON Envelope

The legacy payment message was a JSON object with:

  • "protocol" equal to 3241645161d8

  • "senderIdentityKey" as the sender identity key

  • "derivationPrefix" as the payment-wide prefix

  • "transactions" as an array of extended BRC-8 transaction envelopes

Each legacy envelope included an outputs object mapping output indices to suffix values. This format is deprecated for new BRC-100 integrations.

Sending Payments

The steps for a sender to send a payment under this protocol are as follows:

  1. Learn the identity key of the recipient, determine the total amount of the payment and generate a derivation prefix.

  2. Decide on the number of outputs (across one or multiple transactions) that will comprise the payment.

  3. For each output, generate a derivation suffix for the output and decide on the number of satoshis in the output.

  4. For each output, use BRC-42 key derivation to derive a public key for the recipient for the output, and use the public key to construct a P2PKH Bitcoin output script as per BRC-16.

  5. Use a BRC-100 wallet to construct and sign transactions that contain the output scripts derived for the recipient from the previous step.

  6. With the Atomic BEEF transaction data, derivation prefix, derivation suffixes, output indices, and sender identity key in hand, construct a payment message for the recipient that contains this information.

Recipient Validation

When the recipient processes an incoming payment, it checks that the public key hashes in the output scripts are properly derived from the sender and recipient identities, the derivation prefix, and the output suffixes. The recipient should also validate the supplied BEEF data according to its wallet policy.

Current BRC-100 wallets receive the payment by calling internalizeAction with output metadata such as the following. The tx value shown is a placeholder for the Atomic BEEF byte array:

If these checks pass, the payment is marked as accepted and acknowledged, and goods or services can be rendered to the payee.

Implementations

Implementations of this protocol should adhere to the key derivation scheme and current BRC-100 remittance behavior specified in this BRC. The transaction submission system within any wallet can implement this protocol and validate that incoming transactions submitted under this protocol contain UTXOs that are properly derivable by the recipient. The protocol is intended to be cross-compatible and SPV-compliant.

Last updated