NAV Navbar

Introduction

const { Token, Db, Wallet, Source } = require('bitcointoken')

The BitcoinToken library is a collection of tools that make it easy to integrate Bitcoin into web applications.

We will be supporting Bitcoin Cash and Bitcoin SV at launch.

Install and run

You need node.js and npm installed.

Install

Install BitcoinToken

npm i bitcointoken

Run npm init -yes and

npm install bitcointoken

If you only want to use BitcoinWallet you are done. If you want to use BitcoinDb or BitcoinToken you need to install and run a non-standard server in a second terminal window.

Install and run the non-standard server

Install and run the non-standard server

git clone https://github.com/BitcoinDB/bitcoin-non-standard-server.git
cd bitcoin-non-standard-server
docker-compose up

We recommend to use Docker and Docker Compose to build and run the server using the commands on the right. If you do not use docker you can find instructions in the Github repo.

Run in Node

File index.js

const { Wallet } = require('bitcointoken')

const wallet = new Wallet()
console.log(`address: ${wallet.getAddress()}`)

After installing BitcoinToken, create a file index.js with the content shown on the right. Run the code using

node index.js

The output should be similar to

address: mwZd1bgRYhxY4JLyx1sdEGBYFZnXVDvgmp

Run in the browser

File index.js

const Bitcoin = require('bitcointoken')

const wallet = new Bitcoin.Wallet()
document.body.innerHTML = `address: ${wallet.getAddress()}`

File index.html

<html>
  <body>
    <script src="./bundle.js"></script>
  </body>
</html>

After installing BitcoinToken, create files index.js and index.html as shown.

Install and run browserify

npm install -g browserify
browserify index.js > bundle.js

Open index.html in a web browser

Troubleshooting

If you have a problem that is not discussed here, please let us know in the Telegram group.

"Communication error: Service unavailable"

The problem is most likely that you are not running the non-standard server.

"Error: Insufficient balance in address ..."

File generate-mnemonic.js

const { Wallet } = require('bitcointoken')
console.log(Wallet.getRandomMnemonic())

You have to fund your wallet. First check that the same wallet is generated every time you run your code: Run it multiple times and check if the same address is logged every time.

If so you can fund that address using a testnet faucet.

Otherwise you need to initialize your object from a mnemonic. To generate a mnemonic, create the file generate-mnemonic.js and run it using node --experimental-repl-await generate-mnemonic.js. Now you can generate your object using the logged mnemonic using Wallet.fromMnemonic() and fund it using the testnet faucet

BitcoinWallet

BitcoinWallet allows you to receive, store, and send Bitcoin Cash.

const { Wallet } = require('bitcointoken')

A BitcoinWallet stores a secrete passphrase called menmonic. The mnemonic represents an identity, for example every user in an application would have their own mnemonic. The mnemonic can be used to send Bitcoin to another user, or to generate public addresses that can receive Bitcoin.

constructor

Generate a random BitcoinWallet

const randomWallet = new Wallet()

Generates a new BitcoinWallet with a random mnemonic.

getRandomMnemonic

Generate a mnemonic

const mnemonic = Wallet.getRandomMnemonic()

// mnemonic === 'rail install size scorpion orchard kingdom vacuum collect pencil element fall enhance media island medal'

Generates a new mnemonic from a secure random source.

Type

static getRandomMnemonic(): string

fromMnemonic

Generate a BitcoinWallet from a mnemonic

const mnemonic = Wallet.getRandomMnemonic()
const wallet = Wallet.fromMnemonic(mnemonic)

Generates BitcoinWallet from a mnemonic.

Type

static fromMnemonic(mnemonic: string): BitcoinWallet

getMnemonic

Return the mnemonic

const wallet = Wallet.fromMnemonic('rail install size scorpion orchard kingdom vacuum collect pencil element fall enhance media island medal')
const mnemonic = wallet.getMnemonic()

// menominc === 'rail install size scorpion orchard kingdom vacuum collect pencil element fall enhance media island medal'

Returns the mnemonic of the wallet

Type

getMnemonic(): string

getPrivateKey

Return the private key

const privateKey = wallet.getPrivateKey()

Every BitcoinWallet is associated with a Bitcoin account consisting of a private-public keypair and an address. These can be accessed using getPrivateKey, getPublicKey and getAddress.

getPrivateKey return the private key stored in the wallet.

Type

getPrivateKey(): string

getPublicKey

Return the public key

const publicKey = wallet.getPublicKey()

Returns the public key.

Type

getPublicKey(): string

getAddress

Return the address

const address = wallet.getAddress()
const CashAddress = wallet.getAddress('cashaddr')

Returns the address in legacy format. To return the address in a different format pass in legacy, bitpay, or cashaddr as a parameter.

Type

type Format = 'legacy' | 'bitpay' | 'cashaddr'
getAddress(format?: Format = 'legacy'): string

getBalance

Return the current balance

const satoshi = await wallet.getBalance()
const bitcoin = satoshi / 1e8

Returns the current balance in satoshi. Divide by 1e8 to compute the balance in Bitcoin.

Type

async getBalance(): number

send

Send Bitcoin

const address = randomWallet.getAddress()
const outputId = await wallet.send(15000, address)

// outputId === {
//   txId: '3404832a17d996dffaa9ac1aea48a2fafc9d855e5fdca5100481d8a562523dfb',
//   outputNumber: 0
// }

Sends bitcoin. The first parameter is the amount to send in satoshi, the second is the recipients address, and the third (optional) paramater is the change address. If no change address is provided, the address of the wallet is used.

Type

type OutputId = {|
  txId: string,
  outputNumber: number
}

async send(
  amount: number,
  address: string,
  changeAddress: ?string
): Promise<OutputId>

transaction

Send Bitcoin to multiple recipients

const address = randomWallet.getAddress()
const data1 = { amount: 2000, address: 'mvQPGnzRT6gMWASZBMg7NcT3vmvsSKSQtf' }
const data2 = { amount: 5000, address: 'n1xqzrckuoohZPj3XoMn1mRgJZ3nkCLSq3' }
const outputIds = await wallet.transaction([data1, data2])

// outputIds === [{
//   txId: '3404832a17d996dffaa9ac1aea48a2fafc9d855e5fdca5100481d8a562523dfb',
//   outputNumber: 0
// }, {
//   txId: '3404832a17d996dffaa9ac1aea48a2fafc9d855e5fdca5100481d8a562523dfb',
//   outputNumber: 1
// }]

Use transaction to pay multiple parties at once.

Type

type OutputId = {|
  txId: string,
  outputNumber: number
}

type PkhData = {|
  amount: number,
  address: string
|}

async transaction(
  outputs: Array<PkhData>,
  changeAddress?: string
): Promise<Array<OutputId>>

derive

Derive a child wallet

const derivedWallet = wallet.derive(4)

A BitcoinWallet can deterministically derive 232 child wallets. To derive a child wallet call derive with a number ≤ 232. The second optional parameter determines if the wallet if hardened or not. Read more about hardened wallets in BIP32.

Derive wallet with path m/44'/0'/0'

const wallet = wallet.derive('m', false).derive(44, true).derive(0, true).derive(0, true)

There exists a standard for how to use derivation paths to generate interoperable wallets (BIP44). Two popular derivation paths are

Type

derive(
  index: ?number = 0,
  hardened: ?boolean = false
): BitcoinWallet

getPath

Return the current derivation path

const wallet = wallet.derive('m', false).derive(44, true).derive(0, true).derive(0, true)
const path = wallet.getPath()

// path === `m/44'/0'/0'`

Returns the current derivation path.

Type

getPath(): string

BitcoinDb

BitcoinDb can read, store, and update data on the Bitcoin Cash blockchain.

const { Db } = require('bitcointoken')

Bitcoin exposes two ways to store data: in op_return outputs and in output scripts via p2sh. Both are supported by BitcoinToken.

constructor

Create random BitcoinDb

const randomDb = new Db()

A BicoinDb object stores a BitcoinWallet object to pay for storage space on the blockchain. To generate a BitcoinDb object from a new randomly generated BitcoinWallet object call the constructor without a parameter.

Create BitcoinDb from a BitcoinWallet

const wallet = new Wallet()
const db = new Db(wallet)

You can also create a new BitcoinWallet object from an existing BitcoinWallet object by passing it into the constructor.

fromMnemonic

Generate a BitcoinDb from a mnemonic

const mnemonic = Wallet.getRandomMnemonic()
const db = Db.fromMnemonic(mnemonic)

Generates BitcoinDb object and initialize the embedded BitcoinWallet using the mnemonic.

Type

static fromMnemonic(mnemonic: string): BitcoinWallet

getWallet

Return the wallet stored in the db

const wallet = db.getWallet()

// wallet.constructor.name === 'BitcoinWallet`

Returns the BitcoinWallet stored in a BitcoinDb object.

Type

getWallet(): BitcoinWallet

putReturn

Store a string on the blockchain

const data = 'some string'
const outputId = await db.putReturn(data)

// outputId === {
//   txId: '3404832a17d996dffaa9ac1aea48a2fafc9d855e5fdca5100481d8a562523dfb',
//   outputNumber: 0
// }

Stores a string in an op_return output of a Bitcoin transaction. The string can have up to 110 characters.

Type

async putReturn(data: string): OutputId

put

Store structured data

const outputId = await db.put({
  text: 'Lorem ipsum',
  author: 'Alice'
})

// outputId === {
//   txId: '3404832a17d996dffaa9ac1aea48a2fafc9d855e5fdca5100481d8a562523dfb',
//   outputNumber: 0
// }

Stores json on the Bitcoin Cash blockchain.

The data is stored in a Bitcoin output script. Data stored in this way can be updated the same way that coin ownership is updated in Bitcoin: by spending the outputs containing the old data into outputs containing the new data.

Script encoding the above json

// 1-of-1 multisig script
OP_1 
33 0x03a70e0e5f7c300d9685195bbac132873cb5b68e9787aa7d63549cd0de5e4ace10
OP_1
OP_CHECKMULTISIG

// section encoding the data
 4 0x74657874 OP_DROP // text
11 0x4c6f72656d20697073756d OP_DROP // Lorem ipsum
 6 0x617574686f72 OP_DROP // author
13 0x416c69636520616e6420426f62 OP_DROP // Alice and Bob

The json data get's encoded into the script on the right. It consists of a 1-of-1 multisig script and a section that encodes the data. The data is stored by pushing a value onto the stack and popping it off immediately thereafter (OP_DROP).

Data stored in this way comes with a very strong guaranty: only the person in possession of the private key for 0x03a70e0e5f7... can spend the output containing the data. We call that user the owner of the data. By default the user to issue the command is the owner, to designate a different owner, pass in that users public key as the second argument. Multiple public keys can be passed in to model co-ownership of data.

Store structured data and it's owner

const publicKey = randomWallet.getPublicKey()
const outputId = await db.put({ key: 'string value'}, [publicKey])

The third argument is an amount of satoshi that will be stored in the output containing the data.

Store a structured data, it's owner, and an amount

const publicKey = randomWallet.getPublicKey()
const outputId = await db.put({ key: 'string value'}, [publicKey], 1 * 1e8)

Type

type OutputId = {|
  txId: string,
  outputNumber: number
|}

async put(
  data: Object,
  owners?: Array<string>,
  amount?: number = MIN_NON_DUST_AMOUNT
): Promise<OutputId>

get

Retrieve data from the blockchain

const id = BitcoinDb.put({ value: 'a' })
const res = BitcoinDb.get(id)

// res === { 
//   data: { value: 'a' },
//   owners: [ '03223d34686d6f19d20519156a030f7216e5d5bd6daa9442572bbaa446d06c8dfe' ],
//   amount: 2750
// }

Retrieves a json object from the Bitcoin Cash blockchain given an OutputId object that specifies a location on the blockchain.

The return value is an object with three keys: data contains the data stored at the OutputId, owners contains the owners string encoded public keys, and amount is the number of satoshis stored in the output.

Type

type OutputId = {|
  txId: string,
  outputNumber: number
|}

type OutputData = {|
  data: string,
  owners: Array<string>,
  amount: number
|}

async get(
  outputId: OutputId
): Promise<OutputData>

update

Update a piece of data

const db = new BitcoinDb()
const outputId1 = await db.put({ value: 'a' })
const outputId2 = await db.update(outputId1, { value: 'b'})

// outputId2 === {
//   txId: '3404832a17d996dffaa9ac1aea48a2fafc9d855e5fdca5100481d8a562523dfb',
//   outputNumber: 0
// }

Updates an object stored on the blockchain and returns the location of the new data. The first parameter is the OutputId of the output containing the data that is to be updated, the second parameter is the new data. There are two optional parameters "owners" and "amount" that act just like the optional parameters of db.put.

Only the owner can update data

const db1 = new BitcoinDb()
const db2 = new BitcoinDb()
const outputId1 = await db1.put({ value: 'a' })

// works bc data at outputId1 is owned by db1
const outputId2 = await db1.update(outputId1, { value: 'b'}, [db2.getWallet().getPublicKey()])

// throws an error bc the data at outputId2 is owned by db2
const outputId3 = await db1.update(outputId2, { value: 'c'})

BitcoinDb enforces two properties with respect to updates:

Data can only be updated once

const db = new BitcoinDb()
const outputId1 = await db.put({ value: 'a' })

// works 
const outputId2 = await db.update(outputId1, { value: 'b'})

// throws an error bc the data at outputId1 has been updated
const outputId3 = await db.update(outputId1, { value: 'c'})

Type

type OutputId = {|
  txId: string,
  outputNumber: number
|}

async update(
  outputId: OutputId,
  data: object,
  owners?: Array<string>,
  amount?: number = MIN_NON_DUST_AMOUNT
): Promise<OutputId>

transaction

Update multiple pieces of data simultaneously

const db = new BitcoinDb()
const outputId1 = await db.put({ value: 'a' })
const outputId2 = await db.put({ value: 'b' })
const [outputId3, outputId4] = await db.transaction([
  {
    outputId: outputId1,
    value: 'aa'
  }, {
    outputId: outputId2,
    value: 'bb',
    owners: [<publicKey>]
  }
])

You can group multiple updates into a single transaction by calling db.transaction. A BitcoinDb transaction satisfies the ACID properties of traditional database systems.

Type

type OutputId = {|
  txId: string,
  outputNumber: number
|}

type Update = {|
  outputId: OutputId,
  data: Object,
  owners: Array<string>,
  amount?: number
|}

async transaction(
  update: Array<Update>
): Promise<Array<OutputId>> {

BitcoinToken

BitcoinToken can issue, send, and store tokens on the Bitcoin Cash blockchain.

const { Token } = require('bitcointoken')

It uses BitcoinDb to build and broadcast transactions that encode meta information about token issuances and transfers.

constructor

Create random BitcoinToken

const { Token } = require('bitcointoken')
const randomToken = new Token()

A BitcoinToken object contains a BitcoinDb object to store data on the blockchain. Recall that each BitcoinDb object stores a mnemonic that serves as it's identity. To generate a BitcoinToken object from a new randomly generated BitcoinWallet object call the constructor without a parameter.

Create BitcoinToken from a BitcoinDb

const { Token, Db } = require('bitcointoken')
const db = new Db()
const token = new Token(db)

You can also create a new BitcoinToken object from an existing BitcoinDb object by passing it into the constructor.

fromMnemonic

Generate a BitcoinToken from a mnemonic

const mnemonic = Wallet.getRandomMnemonic()
const token = Token.fromMnemonic(mnemonic)

Generates BitcoinToken object and initialize the embedded BitcoinWallet using the mnemonic.

Type

static fromMnemonic(mnemonic: string): BitcoinToken

getWallet

Return the wallet

const wallet = token.getWallet()

// wallet.constructor.name === 'Wallet`

Returns the wallet stored in the db contained in the BitcoinToken object.

Type

getWallet(): BitcoinWallet

getDb

Return the db

const db = token.getDb()

// db.constructor.name === 'Db`

Returns the BitcoinDb stored in the BitcoinToken object.

Type

getDb(): BitcoinDb

create

Issue a token

const tokenId = await token.create({
  balance: '10',
  name: 'my-token',
  url: 'www.mytoken.com',
})

Issues a new fungible token, similar to ERC20 tokens on Ethereum. The parameter must be an object that can be passes into BitcoinDb.put, that is a json object with string keys and string values. It must have one key balance whose value indicates the initial number of tokens.

The create command calls db.put to store the token meta data in the blockchain. The return value is the id of the output that stores the data.

Type

async create(data: Object): Promise<OutputId>

join

Connect to an issued token

const tokenAlice = new Token()
const tokenBob = new Token()
const tokenId = await tokenAlice.create({ balance: '10' })
tokenBob.join(tokenId)

Connects a BitcoinToken object a token that has been issued using token.create. The balance will be calculated with respect to the token being joined.

Type

join(tokenId: OutputId): void

send

Send a token

const tokenAlice = new Token()
const tokenId = await tokenAlice.create({ balance: '10' })

const tokenBob = new Token()
tokenBob.join(tokenId)

const publicKeyBob = tokenBob.getWallet().getPublicKey()
const outputIds = const tokenAlice.send(1, publicKeyBob)

// outputIds === [{
//   txId: '3404832a17d996dffaa9ac1aea48a2fafc9d855e5fdca5100481d8a562523dfb',
//   outputNumber: 0
// }]

Sends tokens to another user. The first parameter is the number of tokens to send and the second is the public key of the recipient. Sending a token might involve a change output, just like the change output used when sending Bitcoin. The function returns a promise that resolves to an array of OutputIds that containing the newly created outputs that reflect the new state.

token.send calls db.transaction to broadcast a transaction that stores meta data about associated with the token transfer.

Type

type OutputId = {|
  txId: string,
  outputNumber: number
|}

async send(
  amount: number,
  publicKey: string
): Promise<Array<OutputId>>

getBalance

Return the balance in tokens

const token = new BitcoinToken()
const tokenId = await token.create({
  balance: 10
})

const balance1 = await token.getBalance()
// balance1 === 10

const randomPublicKey  = new BitcoinWallet().getPublicKey()
await token.send(1, randomPublicKey)

const balance2 = await token.getBalance()
// balance2 === 9

Returns the number of tokens owned by the current BitcoinToken object. The balance will be computed with respect to the token that was created by the object, or with respect to the token that was joined. token.getBalance() will throw an error if the token object has not created or joined a token.

Type

async getBalance(): Promise<number>

BitcoinSource

BitcoinSource is a readable Bitcoin implementation in modern Javascript.

const { Source } = require('bitcointoken')

It is a fork of Bitcore and shares it's api. You can find the source code here