npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

minercraft

v0.0.8

Published

interact with bitcoin miner apis

Downloads

590

Readme

Minercraft

Interact with Bitcoin miner APIs

Minercraft is a JavaScript library for effortlessly interacting with Bitcoin Miner APIs. Currently supporting the beta version of the Merchant API.

Minercraft works both on the server as well as inside a browser.


What it does

Miner merchant APIs must follow the BRFC spec at https://github.com/bitcoin-sv/merchantapi-reference

  1. Get fee rates from a miner
  2. Calculate fee from a raw transaction
  3. Query the status of a single transaction
  4. Push a transaction to a miner

Miners

The bitcoin miners currently providing the merchant API beta endpoints are:

  • Matterpool: https://matterpool.io
  • Mempool: https://mempool.com
  • TAAL: https://taal.com
  • YOU CAN TOO! (Please give a heads up to @_unwriter when you implement the API)

install

1. In browser

<script src='https://unpkg.com/minercraft'></script>

Check out an in-browser demo here: Minercraft Browser Demo (Source code here)

2. In node.js

npm install --save minercraft

API

0. Create a miner unit

Initialize with a miner API (must follow the miner merchant API spec: https://github.com/bitcoin-sv-specs/brfc-merchantapi)

Example:

const miner = new Minercraft({
  url: "https://www.ddpurse.com/openapi",
  headers: {
    // The following token value is a "free trial" value. For more info visit https://developers.dotwallet.com/en/dev/api/merchant
    token: "561b756d12572020ea9a104c3441b71790acbbce95a6ddbf7e0630971af9424b"
  }
})

a. TAAL.com

You can use the following config to connect to TAAL merchant API (Tentative):

const miner = new Minercraft({
  "url": "https://merchantapi.taal.com"
})

b. Mempool.com

You can use the following config to connect to Mempool.com merchant API (Tentative) using the beta token (free):

const miner = new Minercraft({
  url: "https://www.ddpurse.com/openapi",
  headers: {
    // The following token value is a "free trial" value. For more info visit https://developers.dotwallet.com/en/dev/api/merchant
    token: "561b756d12572020ea9a104c3441b71790acbbce95a6ddbf7e0630971af9424b"
  }
})

c. Matterpool.io

You can use the following config to connect to Matterpool.io merchant API:

const miner = new Minercraft({
  url: "https://merchantapi.matterpool.io"
})

1. Get the fee rate

Query a miner's fee rate:

let rate = await miner.fee.rate()
console.log("fee rate:", rate)

will print:

fee rate: {
  "valid": true,
  "expires": "2020-04-30T13:05:16.925Z",
  "mine": { "standard": 0.5, "data": 0.5 },
  "relay": { "standard": 0.25, "data": 0.25 }
}

You can also pass in an additional parameter verbose: true to get the raw response from the API, which includes other metadata such as minerID and signature, which you can use to verify authenticity:

let rate = await miner.fee.rate({ verbose: true })
console.log("verbose fee rate:", rate)

2. Calculate fee for a transaction

Calculate total fee, based on a fixed rate:

let fee = miner.fee.get({
  rate: { data: 0.5, standard: 0.5 },
  tx: "0100000001648ed7d1c1a27ec923445c8d404e227145218c4ce01cf958a898c5a048e8f264020000006a47304402207dc1953455be091c8df18e7f7e1424bc4efdced3e400642f8316e3ef298c3f30022062d833b3f1b94593ec7c088b930e2987475c7d99bf19f5714b12a9facff100df41210273f105be3e7ca116e96c7c40f17267ae05ede7160eb099aa2146a88b6328f4ecffffffff030000000000000000fdc901006a223144535869386876786e36506434546176686d544b7855374255715337636e7868770c57544458565633505a4b474414e5ae89e5bebd2fe585ade5ae892fe99c8de982b119323032302d30342d30365430363a30303a30302b30383a30304c697b22617169223a223538222c22706d3235223a223332222c22706d3130223a223636222c22736f32223a2235222c226e6f32223a223235222c22636f223a22302e373530222c226f33223a223635222c22706f6c223a22504d3130222c22717561223a22e889af227d4cfb78da75d1c16a02311006e077c959964cb29944dfa1d07bf1209e0a6b57b137114aaf2d2d5e446d7b29d59e3c492f22f834d9ea5b3859e826bba4b73fc34cf898b999b0dee89675184ad662c3815094a5293370ca1a298f73415151ba2b9370cdfd9c124f34c55c563fe419c5eb2b9aa5b1fb1e3d7edf66c5cf93fdfa2ed6072a66ae2621d15203775d99fb070013c50da7cab45599c09b04062688999437993f53d91933ade6a7f5d16e37e7e5676842307553aa1b2685c19e02137a93a94c92c74c69dc54bc7f9c173bfbf21882745b379784a60e0a0f071ea4fce1a45f521a399cfae770f6f0605f67f6795f0381688010dd1da7dd0b690c97db22020000000000001976a914666675d887a7ae09835af934096d9fcbbb70eed288ac61290000000000001976a9149e7520bc258934a3d58704ab98ed0200e2c1bb9688ac00000000"
})

First query the fee rate from a miner, and then use it to calcluate the total fee for a transaction:

let rate = await miner.fee.rate()
let fee = miner.fee.get({
  rate: rate.mine,  // use the mining rate
  tx: "0100000001648ed7d1c1a27ec923445c8d404e227145218c4ce01cf958a898c5a048e8f264020000006a47304402207dc1953455be091c8df18e7f7e1424bc4efdced3e400642f8316e3ef298c3f30022062d833b3f1b94593ec7c088b930e2987475c7d99bf19f5714b12a9facff100df41210273f105be3e7ca116e96c7c40f17267ae05ede7160eb099aa2146a88b6328f4ecffffffff030000000000000000fdc901006a223144535869386876786e36506434546176686d544b7855374255715337636e7868770c57544458565633505a4b474414e5ae89e5bebd2fe585ade5ae892fe99c8de982b119323032302d30342d30365430363a30303a30302b30383a30304c697b22617169223a223538222c22706d3235223a223332222c22706d3130223a223636222c22736f32223a2235222c226e6f32223a223235222c22636f223a22302e373530222c226f33223a223635222c22706f6c223a22504d3130222c22717561223a22e889af227d4cfb78da75d1c16a02311006e077c959964cb29944dfa1d07bf1209e0a6b57b137114aaf2d2d5e446d7b29d59e3c492f22f834d9ea5b3859e826bba4b73fc34cf898b999b0dee89675184ad662c3815094a5293370ca1a298f73415151ba2b9370cdfd9c124f34c55c563fe419c5eb2b9aa5b1fb1e3d7edf66c5cf93fdfa2ed6072a66ae2621d15203775d99fb070013c50da7cab45599c09b04062688999437993f53d91933ade6a7f5d16e37e7e5676842307553aa1b2685c19e02137a93a94c92c74c69dc54bc7f9c173bfbf21882745b379784a60e0a0f071ea4fce1a45f521a399cfae770f6f0605f67f6795f0381688010dd1da7dd0b690c97db22020000000000001976a914666675d887a7ae09835af934096d9fcbbb70eed288ac61290000000000001976a9149e7520bc258934a3d58704ab98ed0200e2c1bb9688ac00000000"
})
console.log("fee = ", fee)

will print:

fee = 348

3. Get transaction status

Query the miner to check what the status of a transaction is:

let status = miner.tx.status("e4763d71925c2ac11a4de0b971164b099dbdb67221f03756fc79708d53b8800e")
console.log(status)

will print:

{
  "apiVersion": "0.1.0",
  "timestamp": "2020-04-15T19:51:51.020Z",
  "returnResult": "success",
  "resultDescription": "",
  "blockHash": "000000000000000004a5686ff15cdb3950939bdc5725970d963e2b03d3d43d45",
  "blockHeight": 630700,
  "confirmations": 50,
  "minerId": "03c51d59a737a0ebc064344bf206b7140bf51a9ef8d6cb75dc2d726853d7c76758",
  "txSecondMempoolExpiry": 0,
  "valid": true
}

If you want to get a more detailed response, including the minerID and signature, you can call the method with {verbose: true}:

let status = await miner.tx.status(txid, { verbose: true })
console.log(status)

will print something like:

{
  "payload": {
    "apiVersion": "0.1.0",
    "timestamp": "2020-04-19T15:06:56.299Z",
    "returnResult": "success",
    "resultDescription": "",
    "blockHash": "000000000000000004a5686ff15cdb3950939bdc5725970d963e2b03d3d43d45",
    "blockHeight": 630700,
    "confirmations": 603,
    "minerId": "03e92d3e5c3f7bd945dfbf48e7a99393b1bfb3f11f380ae30d286e7ff2aec5a270",
    "txSecondMempoolExpiry": 0
  },
  "signature": "3044022032eb418ea68a0825767fa6bf038cca200acbbbabeadd7f7e3b203594e3ef3ee60220224fc0657a5c7c8b3b4a8b71de897655a990b975ae9e9f8d574eb806663bc839",
  "publicKey": "03e92d3e5c3f7bd945dfbf48e7a99393b1bfb3f11f380ae30d286e7ff2aec5a270",
  "encoding": "UTF-8",
  "mimetype": "application/json",
  "valid": true
}

4. Push transaction

Pass a raw transaction hex string into the push() function and it will send the transaction directly to the miner.

let response = await miner.tx.push("0100000001648ed7d1c1a27ec923445c8d404e227145218c4ce01cf958a898c5a048e8f264020000006a47304402207dc1953455be091c8df18e7f7e1424bc4efdced3e400642f8316e3ef298c3f30022062d833b3f1b94593ec7c088b930e2987475c7d99bf19f5714b12a9facff100df41210273f105be3e7ca116e96c7c40f17267ae05ede7160eb099aa2146a88b6328f4ecffffffff030000000000000000fdc901006a223144535869386876786e36506434546176686d544b7855374255715337636e7868770c57544458565633505a4b474414e5ae89e5bebd2fe585ade5ae892fe99c8de982b119323032302d30342d30365430363a30303a30302b30383a30304c697b22617169223a223538222c22706d3235223a223332222c22706d3130223a223636222c22736f32223a2235222c226e6f32223a223235222c22636f223a22302e373530222c226f33223a223635222c22706f6c223a22504d3130222c22717561223a22e889af227d4cfb78da75d1c16a02311006e077c959964cb29944dfa1d07bf1209e0a6b57b137114aaf2d2d5e446d7b29d59e3c492f22f834d9ea5b3859e826bba4b73fc34cf898b999b0dee89675184ad662c3815094a5293370ca1a298f73415151ba2b9370cdfd9c124f34c55c563fe419c5eb2b9aa5b1fb1e3d7edf66c5cf93fdfa2ed6072a66ae2621d15203775d99fb070013c50da7cab45599c09b04062688999437993f53d91933ade6a7f5d16e37e7e5676842307553aa1b2685c19e02137a93a94c92c74c69dc54bc7f9c173bfbf21882745b379784a60e0a0f071ea4fce1a45f521a399cfae770f6f0605f67f6795f0381688010dd1da7dd0b690c97db22020000000000001976a914666675d887a7ae09835af934096d9fcbbb70eed288ac61290000000000001976a9149e7520bc258934a3d58704ab98ed0200e2c1bb9688ac00000000")

Again, to get more verbose response, you can pass in { verbose: true }:

let response = await miner.tx.push("0100000001648ed7d1c1a27ec923445c8d404e227145218c4ce01cf958a898c5a048e8f264020000006a47304402207dc1953455be091c8df18e7f7e1424bc4efdced3e400642f8316e3ef298c3f30022062d833b3f1b94593ec7c088b930e2987475c7d99bf19f5714b12a9facff100df41210273f105be3e7ca116e96c7c40f17267ae05ede7160eb099aa2146a88b6328f4ecffffffff030000000000000000fdc901006a223144535869386876786e36506434546176686d544b7855374255715337636e7868770c57544458565633505a4b474414e5ae89e5bebd2fe585ade5ae892fe99c8de982b119323032302d30342d30365430363a30303a30302b30383a30304c697b22617169223a223538222c22706d3235223a223332222c22706d3130223a223636222c22736f32223a2235222c226e6f32223a223235222c22636f223a22302e373530222c226f33223a223635222c22706f6c223a22504d3130222c22717561223a22e889af227d4cfb78da75d1c16a02311006e077c959964cb29944dfa1d07bf1209e0a6b57b137114aaf2d2d5e446d7b29d59e3c492f22f834d9ea5b3859e826bba4b73fc34cf898b999b0dee89675184ad662c3815094a5293370ca1a298f73415151ba2b9370cdfd9c124f34c55c563fe419c5eb2b9aa5b1fb1e3d7edf66c5cf93fdfa2ed6072a66ae2621d15203775d99fb070013c50da7cab45599c09b04062688999437993f53d91933ade6a7f5d16e37e7e5676842307553aa1b2685c19e02137a93a94c92c74c69dc54bc7f9c173bfbf21882745b379784a60e0a0f071ea4fce1a45f521a399cfae770f6f0605f67f6795f0381688010dd1da7dd0b690c97db22020000000000001976a914666675d887a7ae09835af934096d9fcbbb70eed288ac61290000000000001976a9149e7520bc258934a3d58704ab98ed0200e2c1bb9688ac00000000", {
  verbose: true
})

This will provide more information about the response.

5. Validate API responses

Minercraft takes care of all the cryptographic validation of the API responses automatically.

Note that every response contains a "valid" attribute which is either true or false.

It will be true if the signature matches the publickey and the content. Otherwise it will be false. This is the same for both the normal mode and the verbose mode. Here are some examples:

Normal Mode:

{
  "valid": true,
  "expires": "2020-04-30T13:05:16.525Z",
  "mine": { "standard": 0.5, "data": 0.5 },
  "relay": { "standard": 0.25, "data": 0.25 }
}

Verbose Mode:

{
  "payload": {
    "apiVersion": "0.1.0",
    "timestamp": "2020-04-30T12:55:26.581Z",
    "returnResult": "success",
    "resultDescription": "",
    "blockHash": "000000000000000004a5686ff15cdb3950939bdc5725970d963e2b03d3d43d45",
    "blockHeight": 630700,
    "confirmations": 2167,
    "minerId": "03c51d59a737a0ebc064344bf206b7140bf51a9ef8d6cb75dc2d726853d7c76758",
    "txSecondMempoolExpiry": 0
  },
  "signature": "304402206a15cc626cb8e959aeb53eb4224cdd7150c56ae662ed236d7042265f21cbc8f802200bf97202bc0c09aae1f3993d28d4175ae24dd53225321c64cb9492c81f2ede03",
  "publicKey": "03c51d59a737a0ebc064344bf206b7140bf51a9ef8d6cb75dc2d726853d7c76758",
  "encoding": "UTF-8",
  "mimetype": "applicaton/json",
  "valid": true
}