A transaction parser for Bitcoin data protocols like B, MAP, BAP, 1Sat Ordinals, SIGMA, METANET, and AIP/HAIP.


Keywords
bitcoin, bmap, magic, attribute, protocol, bsv
License
BSD-3-Clause-Open-MPI
Install
npm install bmapjs@0.4.0-beta.50

Documentation

BMAPjs

npm downloads GitHub

BMAPjs is a transaction parser for Bitcoin data protocols like B, MAP, BAP, 1Sat Ordinals, METANET and AIP/HAIP. Supports multiple outputs, signature verification, and multiple instances in a single OP_RETURN. It also has support for some Script based protocols like 21e8.

It processes BOB formatted transactions for B | MAP OP_RETURN protocols. It processes transaction outputs and transforms them into self-descriptive TypeScript objects based on the OP_RETURN protocols it discovers in the data.

It supports B, MAP, AIP, METANET and a list of other popular protocols. It ingests structured JSON objects in BOB format.

It is written in TypeScript and can be used both as an ESM module or in the browser as CommonJS via script tag. See the dist folder for compiled outputs.

Why this exists

BOB format is a great way to express Bitcoin transaction outputs, especially those containing data protocols, but there are some problems. For example, each field has multiple options to choose from, be it a base64 encoded binary representation in the b field, a string value in the s field, or a hex value in the h field. Depending on the protocol and the specific field you might choose one or another. This means you have to have a full understanding of the protocol you're trying to use. That's where bmapjs comes in. It can recognize many protocols, structure the data according to their individual protocols, and provide an easy to use BMAP transaction object with no mysteries about the data.

Pre-requisites

  • A BOB formatted transaction. If you only have a raw transaction you can convert to BOB using BPU. More information here
  • Bun (for development)

Install

bun add bmapjs

or

npm install bmapjs

Development Setup

# Install dependencies
bun install

# Run tests
bun test

# Build
bun run build

# Lint
bun run lint

# Format
bun run format

Importing

You can import bmap using require:

const { BMAP } = require('bmapjs')

or using ESM module import:

import { BMAP, TransformTx } from 'bmapjs'

Using in the browser

You can use bmapjs in the browser by pointing to the .cjs file in the dist folder:

<script src="dist/bmap.cjs"></script>

The CJS is by far the largest package since it includes dependencies. It is also possible to import in the browser using the module syntax:

<script src="dist/bmap.es.js" type="module">
    import { TransformTx } from 'bmapjs'
    // more code here
</script>

Other languages

Go

Usage

Turn a BOB formatted transaction into a BMAP tx. It will throw an error if the transaction is malformed.

In Node.js/Bun:

import { TransformTx } from 'bmapjs'

try {
    const bmapTx = await TransformTx(bob_tx_object)
} catch (e) {
    console.error(e)
}

or in the browser:

<script src="dist/bmap.cjs"></script>

bmap will be available on the window object:

const bmapTx = await bmap.TransformTx(bob_tx_object)

BMAP (Transaction object)

After transforming the object will contain a key for each protocol found within the transaction. Each value will be an array. Most of the time the array will have only one value indicating the protocol was detected only once. However, in some cases where protocols will be used multiple times in the same transaction, the array will contain one object for each protocol instance detected.

interface BmapTx {
  tx: {
    h: string;  // Transaction hash
    r: string;  // Raw transaction
  };
  blk?: {
    i: number;  // Block index
    h: string;  // Block hash
    t: number;  // Block time
  };
  in: Input[];  // Transaction inputs
  out: Output[];  // Transaction outputs
  
  // Protocol data
  AIP?: AIP[];  // Identity protocol
  B?: B[];      // Data protocol
  BAP?: BAP[];  // Bitcoin Attestation Protocol
  MAP?: MAP[];  // Magic Attribute Protocol
  ORD?: ORD[];  // 1Sat Ordinals
  "21E8"?: _21E8[];  // Proof of work protocol
  BITCOM?: BITCOM[];
  BITKEY?: BITKEY[];
  BITPIC?: BITPIC[];
  METANET?: METANET[];
  RON?: RON[];
  SYMRE?: SYMRE[];
  HAIP?: HAIP[];
}

Adding other protocols

Not all protocols available in bmap.js are active by default. These are less used or older protocols, but they can be easily added at runtime.

import { BMAP, RON } from 'bmapjs'

const bmap = new BMAP()
bmap.addProtocolHandler(RON)

The protocols that are available but not active by default are BITCOM, BITKEY, BITPIC, RON and SYMRE.

Extending the BMAP class

You can also easily add new handlers for processing any type of bitcom output.

import { BMAP } from 'bmapjs'
import type { Protocol, SchemaField } from 'bmapjs'

const bmap = new BMAP()
const opReturnSchema: SchemaField[] = [{}] // optional

const handler: Protocol['handler'] = ({ dataObj, cell, tape, tx }) => {
    // dataObj is the object that all data is added to
    // cell is the current cell being processed
    // tape is the tape the cell is in
    // tx is the total transaction
}

bmap.addProtocolHandler({
    name: 'TEST',
    address: '1FJrobAYoQ6qSVJH7yiawfaUmZ3G13q9iJ',
    opReturnSchema,
    handler,
})

await bmap.transformTx(bob_tx)

You can also use the default protocol handler with a well-defined schema to make it even easier:

import { BMAP } from 'bmapjs'
import { bmapOpReturnSchemaHandler } from './utils'
import type { SchemaField } from 'bmapjs'

const opReturnSchema: SchemaField[] = [
  { type: 'string' },
  { hash: 'string' },
  { sequence: 'string' },
]

const handler = ({ dataObj, cell, tape, tx }) => {
  bmapOpReturnSchemaHandler('TEST', opReturnSchema, dataObj, cell, tx)
}

bmap.addProtocolHandler({
  name: 'TEST',
  address: '1FJrobAYoQ6qSVJH7yiawfaUmZ3G13q9iJ',
  opReturnSchema,
  handler,
})

License

Open BSV