JavaScript client library for Openchain
npm install openchainOpenchain is an open source distributed ledger technology. It is suited for organizations wishing to issue and manage digital assets in a robust, secure and scalable way. Visit openchain.org for more information.
The full documentation for Openchain is available at docs.openchain.org.
This module is a NodeJS client library to use in conjunction with the Openchain server.
bash
$ npm install openchain
`
Import the module:
` js
var openchain = require("openchain");
`
$3
Install the module through Bower:
` bash
$ bower install openchain
`
Reference the scripts:
` html
`
Import the module:
` js
var openchain = require("openchain");
`
Modules
The openchain module exports the following objects:
- ApiClient: A class wrapping the Openchain API calls.
- Schema: A set of classes (Schema.Record, Schema.Mutation and Schema.Transaction) that can be used for serialization and deserialization of transactions and mutations.
- TransactionBuilder: A class facilitating the construction, signature and submission of transactions to an Openchain instance.
- LedgerPath: A class representing a path within the Openchain structure.
- RecordKey: A class representing a record key.
- encoding: A submodule that contains methods that can be used for encoding and decoding integers and string to/from a ByteBuffer object.
- MutationSigner: A class that can be used to sign a mutation.
- ByteBuffer: A buffer of raw bytes.
- Long: A class for representing a 64 bit integer value.
Code samples
$3
This code queries an Openchain server for the balance of the account represented by the path /p2pkh/Xat6UaXpQE9Dxv6rLtxY1peBkzC1SQDiEX/ for the asset represented by the path /asset/p2pkh/XcDCGPMtdrKxodQ4soFyYfDmr78gTvJ9jN/.
` js
var openchain = require("openchain");
var client = new openchain.ApiClient("http://localhost:8080/");
client.getAccountRecord(
// Account path
"/p2pkh/Xat6UaXpQE9Dxv6rLtxY1peBkzC1SQDiEX/",
// Asset path
"/asset/p2pkh/XcDCGPMtdrKxodQ4soFyYfDmr78gTvJ9jN/")
.then(function (result) {
console.log("Balance: " + result.balance.toString());
});
`
$3
This code submits a transaction that transfers 100 units of an asset from an issuance account (e.g. /asset/p2pkh/Xat6UaXpQE9Dxv6rLtxY1peBkzC1SQDiEX/) to a normal wallet account (e.g. /p2pkh/Xat6UaXpQE9Dxv6rLtxY1peBkzC1SQDiEX/).
` js
var openchain = require("openchain");
var bitcore = require("bitcore-lib");
var seed = "0123456789abcdef0123456789abcdef";
// Load a private key from a seed
var privateKey = bitcore.HDPrivateKey.fromSeed(seed, "openchain");
var address = privateKey.publicKey.toAddress();
// Calculate the accounts corresponding to the private key
var issuancePath = "/asset/p2pkh/" + address + "/";
var assetPath = issuancePath;
var walletPath = "/p2pkh/" + address + "/";
console.log("Issuance path: " + issuancePath);
console.log("Wallet path: " + walletPath);
// Create an Openchain client and signer
var client = new openchain.ApiClient("http://localhost:8080/");
var signer = new openchain.MutationSigner(privateKey);
// Initialize the client
client.initialize()
.then(function () {
// Create a new transaction builder
return new openchain.TransactionBuilder(client)
// Add the key to the transaction builder
.addSigningKey(signer)
// Add some metadata to the transaction
.setMetadata({ "memo": "Issued through NodeJS" })
// Take 100 units of the asset from the issuance path
.updateAccountRecord(issuancePath, assetPath, -100);
})
.then(function (transactionBuilder) {
// Add 100 units of the asset to the target wallet path
return transactionBuilder.updateAccountRecord(walletPath, assetPath, 100);
})
.then(function (transactionBuilder) {
// Submit the transaction
return transactionBuilder.submit();
})
.then(function (result) { console.log(result); });
`
$3
This code submits a transaction recording a piece of arbitrary data (the storedData variable) into the chain. The data may be anything: arbitrary text, JSON data, XML data or even binary data.
Asset definition records, ACL records and goto records use this approach.
` js
var openchain = require("openchain");
var bitcore = require("bitcore-lib");
var seed = "0123456789abcdef0123456789abcdef";
// Load a private key from a seed
var privateKey = bitcore.HDPrivateKey.fromSeed(seed, "openchain");
var address = privateKey.publicKey.toAddress();
// Calculate the accounts corresponding to the private key
var dataPath = "/asset/p2pkh/" + address + "/metadata/";
var recordName = "datarecord";
var storedData = "This is the data to store in the chain";
console.log("Account path: " + dataPath);
console.log("Record name: " + recordName);
// Create an Openchain client and signer
var client = new openchain.ApiClient("http://localhost:8080/");
var signer = new openchain.MutationSigner(privateKey);
// Initialize the client
client.initialize()
.then(function () {
// Retrieve the record being modified
return client.getDataRecord(dataPath, recordName)
})
.then(function (dataRecord) {
// Encode the data into a ByteBuffer
var newValue = openchain.encoding.encodeString(storedData);
// Create a new transaction builder
return new openchain.TransactionBuilder(client)
// Add the key to the transaction builder
.addSigningKey(signer)
// Modify the record
.addRecord(dataRecord.key, newValue, dataRecord.version)
// Submit the transaction
.submit();
})
.then(function (result) { console.log(result); });
`
$3
Openchain exposes the transaction stream via a WebSocket. The following code snippet will connect to an endpoint and pull the transactions from the Openchain server.
` js
var WebSocket = require("ws");
var openchain = require("openchain");
var ByteBuffer = require("protobufjs").ByteBuffer;
var bitcore = require("bitcore-lib");
// The URL of the WebSocket endpoint
var ws = new WebSocket("ws://localhost:5000/stream");
// Format the raw transaction into readable text
function decodeTransaction(data) {
var buffer = ByteBuffer.fromBinary(data);
var transaction = openchain.Schema.Transaction.decode(buffer.clone());
var mutation = openchain.Schema.Mutation.decode(transaction.mutation.clone());
var transactionBuffer = new Uint8Array(buffer.toArrayBuffer());
var transactionHash = bitcore.crypto.Hash.sha256(
bitcore.crypto.Hash.sha256(transactionBuffer));
var mutationBuffer = new Uint8Array(transaction.mutation.toArrayBuffer());
var mutationHash = bitcore.crypto.Hash.sha256(
bitcore.crypto.Hash.sha256(mutationBuffer));
return JSON.stringify({
mutation_hash: ByteBuffer.wrap(mutationHash).toHex(),
transaction_hash: ByteBuffer.wrap(transactionHash).toHex(),
timestamp: transaction.timestamp.toString(),
mutation: {
namespace: mutation.namespace.toHex(),
metadata: mutation.metadata.toHex(),
records: mutation.records.map(function (record) {
return {
key: openchain.encoding.decodeString(record.key),
value: record.value == null ? null : record.value.data.toHex(),
version: record.version.toHex()
};
})
},
transaction_metadata: transaction.transaction_metadata.toHex(),
}, null, " ");
}
ws.on('open', function open() {
console.log("Connected to the WebSocket endpoint...\n")
});
// Process every incoming transaction
ws.on('message', function (data, flags) {
console.log(decodeTransaction(data) + "\n");
});
`
Use the following command to install the required dependencies:
` bash
$ npm install ws openchain bitcore-lib
``