Wallet Transaction Output Tracking (Output Baskets)

Ty Everett (ty@projectbabbage.com)

Abstract

We define an extension to BRC-1 that enables a wallet to facilitate the tracking of specific application-defined transaction outputs within baskets. A new set of messages across the abstract messaging interface facilitates applications' access to unspent outputs stored in these baskets, with a permission system similar to that described in BRC-43 employed to regulate access by applications. Spending an output stored in a basket removes it, while new outputs can be added by specifying their basket as part of BRC-1 transaction creation requests.

Motivation

Transaction outputs in Bitcoin take many forms, and serve many purposes. While BRC-1 defines a way for applications to request the creation of transaction outputs by wallets, there is no way for applications to request that a wallet tracks these outputs. Enabling applications to request that wallets track outputs provides a number of advantages: First, applications may no longer need to rely on external data storage and retrieval systems, simplifying their architecture. Second, there is the potential to represent different types of Bitcoin-native tokens within specific baskets, and define protocols for manipulating specific types of tokens based on which baskets they are stored in. Finally, when permission to access a basket is decided by the user on a per-application basis, it facilitates a greater degree of control for users over their tokens, enabling multiple applications to access and use the same tokens.

Specification

We extend the BRC-1 Transaction Creation Request message so that, in addition to the normal script and satoshis fields defined in each element of the outputs array, there is another basket field. The new basket field is a string comprising the name of the basket into which this output is to be inserted and tracked by the wallet. We specify that, when a wallet creates a transaction responsive to the Transaction Creation Request, it utilizes some internal storage and retrieval system (beyond the scope of this specification) to associate the specified output with the specified basket.

To allow applications to specify information that would later be needed to unlock and use outputs that are stored in baskets, an optional customInstructions field can also be added when basket is given. This field is retained by the wallet and included as part of the Transaction Outputs Response (defined below).

To facilitate permissioned access to baskets by applications, we stipulate that the wallet, upon receiving a transaction creation request, may prompt the user to grant permission for the application to use the basket. The method by which the wallet seeks the consent of the user is out-of-scope for this standard, but the process, if it occurs, must be facilitated by the wallet asynchronously between the receipt of the Transaction Creation Request and the furnishment of any Transaction Creation Response or Transaction Creation Error messages.

To facilitate access to the tokens stored within baskets by applications, we define a new set of messages across the abstract communications channel between the wallet and the application, as follows:

Transaction Outputs Request

This message constitutes a request by the application for a list of Bitcoin UTXOs that are responsive to the request. The message contains the following information:

FieldRequiredDescription

basket

yes

The basket from which outputs should be returned

includeEnvelope

no

Whether BRC-8 transaction envelopes are requested for the outputs

limit

no

The maximum number of outputs to return

offset

no

The number of outputs from the beginning of the list to skip

spendable

no

Always considered to be true, included by some implementations for historical reasons

This provides the wallet with enough information to furnish the outputs requested by the application. Here is an example of a simple Transaction Outputs Request in JSON:

{
  "basket": "todo tokens",
  "includeEnvelope": true,
  "limit": 25,
  "offset": 0,
  "spendable": true
}

In this example, the application is stipulating that a maximum of 25 outputs from the todo tokens basket are to be returned, including their BRC-8 transaction envelopes.

Transaction Outputs Response

The response comprises a list of transaction outputs currently in the specified basket. This is an array of objects where each object has the following fields:

FieldDescription

amount

The number of satoshis in the transaction output

txid

The TXID of the transaction that created the output, given as a hex string

vout

The output index number of this output within the transaction that created it

outputScript

The hex-encoded Bitcoin script program that locks the output

customInstructions

The spending instructions that were stored when the output was created

envelope

If envelopes were requested, the BRC-8 Transaction Envelope for this transaction

Here is an example of a simple Transaction Outputs Response:

[{
  "amount":1000,
  "customInstructions":null,
  "envelope":{
    "rawTx":"010000000135620d3a8fb626b763cb7b9a3c3197eda9bd6709ef1e4ebc2b359607800eaa95020000006b483045022100c3ec1792f1780e453c6ea692271bcc5388fb179d6455897f4b4200706e8b9f150220352cc2ff81a5c698e4626aec8976643134efab91ca1c80729670c2d007c77cfd4121037798f038cb7fc18b9d67baa87ed33122eb7be65b95b0dd304dc476c60043773dffffffff03e803000000000000c4210399322f558d92ced9c45d3bfe7dc5c01b830a4b61d71695ab0a1fa2cd90aba8b9ac2131546f446f44744b7265457a6248594b466a6d6f42756475466d53585855475a473462812d4eeb030fa496c2965f7e0f0b0e825d0547aceb7a9d4c76fd17e795753d8e2e0e82274ab36744a7968a43dc45b1cbdfab6c473045022100a58914da5346960ecb4de964f0f1e1be43a7645a11449c3a209f3fd69b34209b02205d4d4294d04c5f87fb16c2cdc3d9b41f9866fb3d7a690da08089c972d1393d816d75c8000000000000001976a91473a95c0b12e33b3d79f80508200a075bbab0906588ac4ea80200000000001976a91478daf10df51b3ea4c9292a72bf2e1e1d48ebe11288ac00000000",
    "mapiResponses":[{
      "publicKey":"030d1fe5c1b560efe196ba40540ce9017c20daa9504c4c4cec6184fc702d9f274e",
      "payload":"{\"apiVersion\":\"1.5.0\",\"timestamp\":\"2023-04-07T08:19:10.2186219Z\",\"txid\":\"900b7e9ced44f8a7605bd4c1b7054b8fb958385998954d772820a8b81eabb56f\",\"returnResult\":\"success\",\"resultDescription\":\"\",\"minerId\":\"030d1fe5c1b560efe196ba40540ce9017c20daa9504c4c4cec6184fc702d9f274e\",\"currentHighestBlockHash\":\"000000000000032b2a17b3003b5cbb484b284bda4ffd7c15edd6c038429840ed\",\"currentHighestBlockHeight\":1545664,\"txSecondMempoolExpiry\":0,\"warnings\":[],\"failureRetryable\":false}",
      "signature":"30440220066e711073f08d6302a33acb2863557b13465f5381a3355eaee9a5e08909abfc0220695fedf9800226d9f430f8a0177c1e4bde8134d350a8eb3bfd0d5d77925cac4d"
    }],
    "inputs":{
      "95aa0e800796352bbc4e1eef0967bda9ed97313c9a7bcb63b726b68f3a0d6235":{
        "rawTx":"0100000001ce31fcf049468a1e3a2cd56c598d5452f6bfbc95bac036eda769531795e3198c020000006a4730440220721e1e12c2540cccf01fed09560daf2dddebec959e39481c6f27bf366d8b3c5d0220040562db8f91b13b7ad33ac9f01adbbfa748c375ff2c8201929828537e7fb81841210306d6a463a7f204b050ffeba596fe9a2466f416b008d6954ce425304660abe450ffffffff0322020000000000001976a914268b68eb0ee5ed10decbf38fa47cdc2e3df7af2b88acc8000000000000001976a91426db399bdfe2ff5e413c60930b3f760a4db625db88ac30ad0200000000001976a9149cbb583bcc1d80d37669e930dca22655d621990088ac00000000",
        "proof":{
          "txOrId":"95aa0e800796352bbc4e1eef0967bda9ed97313c9a7bcb63b726b68f3a0d6235","target":"a4f45102baefabafb1ad7376f754c219411e45439fd31c2b082051f0e58e08e3",
          "targetType":"merkleRoot",
          "nodes":[
            "8d8403f47e3e9a461848b5d45ee173d49ef4afb2c952e26ff2ffa95e2ae96a7c",
            "04f653cc1e2e5376600ec83c93d3ac7309dd29662b69f329511a020c9ecf5b67",
            "3c8a8b183008fa56dfe432ab7ccb10e47e36537c21a152466de7e1a3572a5286",
            "cb798749f39ce21c360cea90973a2eeb4740a7db05b7f42f1b33b81448369753",
            "3fb4036561bb38c0c2096512818bcfc425ead33f0a10272def77d8bf6243ae94"
          ],
          "index":15
        }
      }
    }
  },
  "outputScript":"210399322f558d92ced9c45d3bfe7dc5c01b830a4b61d71695ab0a1fa2cd90aba8b9ac2131546f446f44744b7265457a6248594b466a6d6f42756475466d53585855475a473462812d4eeb030fa496c2965f7e0f0b0e825d0547aceb7a9d4c76fd17e795753d8e2e0e82274ab36744a7968a43dc45b1cbdfab6c473045022100a58914da5346960ecb4de964f0f1e1be43a7645a11449c3a209f3fd69b34209b02205d4d4294d04c5f87fb16c2cdc3d9b41f9866fb3d7a690da08089c972d1393d816d75",
  "spendable":true,
  "txid":"900b7e9ced44f8a7605bd4c1b7054b8fb958385998954d772820a8b81eabb56f",
  "vout":0
}]

Transaction Outputs Error

If the Bitcoin wallet is unable to fulfill the Transaction Outputs Request for any reason, we specify that it should respond with a JSON-formatted Transaction Outputs Error. The fields for the object are specified as follows:

FieldDescription

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 Transaction Outputs Error is given below:

{
  "status": "error",
  "code": "ERR_PERMISSION_DENIED",
  "description": "You have denied permission for accessing this output basket."
}

Implementations

This functionality is implemented as part of the Babbage SDK, via the getTransactionOutputs function.

Last updated