This Javascript library can be used to connect software
to leverage the capabilities of the hybrix platform. It
serves two purposes: first to facilitate the logistics of
interfacing with
the hybrixd
API, secondly to handle all client-side operations
securely and privately. This ensures that keys required for
transactions never leave the users device and communication
happens over an encrypted channel.
There are two flavours of the library: the web version to include in your webpage or front-end, and the node js version to include when you are building back-end software.
Here is a Hello World example of how to use hybrix-lib.js in your front-end. First include the library using script tags.
<html>
<head>
<script src='hybrix-lib.web.js'></script>
</head>
<body>
<script>
var hybrix = new Hybrix.Interface();
hybrix.sequential(
[
{host:'https://api.hybrix.io/'}, 'addHost' // Connect to host
],
host => alert('Connected to '+ host), // Define action to execute on successfull completion
error => alert('Oops, something went wrong: '+error) // Define action to exectue when an error is encountered
);
</script>
</body>
</html>
For nodejs projects:
const Hybrix = require('./hybrix-lib.nodejs.js');
const hybrix = new Hybrix.Interface();
hybrix.sequential(
[
{host:'https://api.hybrix.io/'}, 'addHost' // Connect to host
],
host => console.log('Connected to '+ host), // Define action to execute on successfull completion
error => console.error('Oops, something went wrong: ' + error) // Define action to exectue when an error is encountered
);
Or using npm:
Install the package using npm
npm install hybrix-jslib
const Hybrix = require('hybrix-jslib');
const hybrix = new Hybrix.Interface();
hybrix.sequential(
[
{host:'https://api.hybrix.io/'}, 'addHost' // Connect to host
],
host => console.log('Connected to '+ host), // Define action to execute on successfull completion
error => console.error('Oops, something went wrong: ' + error) // Define action to exectue when an error is encountered
);
Callbacks
Each command is implemented as a member function of the Hybrix.Interface class. Adding a host can be done as follows.
hybrix.addHost({host:'https://www.example.com'});
Here only one parameter is passed but each member function has four parameters: data, onSuccess, onError and onProgress.
The first is used to pass parameter data to the function. The last three are callback functions. onSuccess is called once when the method has finished successfully. onError is called once when an error is encountered. onProgress is called whenever a progress update is available, passing a number between 0 and 1, and 1 upon completion.
To first add a host and then query for asset balance one could try the following:
hybrix.addHost({host:'https://www.example.com'}); // This is an asynchronous function. It can take some time to complete.
hybrix.rout({query: 'Query for asset balance'}); // Problem! This will try to request routing before the addition of the host is done.
This results in serious problems due to asynchronicity. One could use the callbacks to ensure the execution order.
hybrix.addHost({host:'https://www.example.com'},
function(){
hybrix.rout({query:'/asset/btc/balance/32FCGFdRGeho2HBeWQPaAYawJfPqHHvsCJ'}); // This will now be called after the addition of the host is successfully completed.
}
);
But adding more steps or error handling will end up with code that is both very hard to read and maintain. (This is sometimes dubbed callback hell.) To mitigate this the library comes equiped with a sequential and a parallel command to handle these asynchronious call flows. With an added bonus of handling the progress for combined commands as well.
hybrix.sequential([
{host: 'http://localhost:1111/'}, 'addHost', // Add and initialize the host
{query: '/asset/btc/balance/32FCGFdRGeho2HBeWQPaAYawJfPqHHvsCJ'}, 'rout' // Query for asset balance
],
onSuccess, // Define action to execute on successfull completion
onError, // Define action to execute when an error is encountered
onProgress // Define action to execute whenever there is a progress update
);
hybrix.sequential([
{host: 'http://localhost:1111/'}, 'addHost', // Add and initialize the host
{query: '/asset/btc/balance/32FCGFdRGeho2HBeWQPaAYawJfPqHHvsCJ'}, 'rout' // Query for asset balance
],
onSuccess, // Define action to execute on successfull completion
onError, // Define action to execute when an error is encountered
onProgress // Define action to execute whenever there is a progress update
);
For even more complex behaviour we advice you to implement your own favourite flavour method of handling the call flow, be it promises, streams, or async, etc.
addAsset{symbol, [seed], [keys], [privateKey], [clientModuleCodeBlob], [check=true], [offset=0], [host], [channel], [includeBaseAssets=true]} Add an asset (crypto currency or token) to the session.
Add an asset (crypto currency or token) to the session.
Name
Type
Description
data
Object
data.symbol
string
The symbol of the asset
data.seed
string
[Optional] CAREFUL! Using this feature incorrectly can reduce your security and privacy. Only use when you know what you're doing. Pass a custom seed to generate the asset keys
data.keys
string
[Optional] CAREFUL! Using this feature incorrectly can reduce your security and privacy. Only use when you know what you're doing. Pass a keypair
data.privateKey
string
[Optional] CAREFUL! Using this feature incorrectly can reduce your security and privacy. Only use when you know what you're doing. Pass a privateKey
data.clientModuleCodeBlob
string
[Optional] A string containing the client module code blob.
data.check
Boolean
[Optional, default = true] Whether to check if the provided clientModuleCodeBlob matches the remote version
data.offset
string
[Optional, default = 0] The deterministic offset
data.host
string
[Optional] The host used for the calls.
data.channel
string
[Optional] The channel used for the calls. 'y' for encryped, 'z' for encryped and compresses;
data.includeBaseAssets
string
[Optional, default = true] Add the base asset too. (Main chain for token)
getLoginKeyPair{[username], [password], [offset=0]} Get the keys associated with a login username/password. Important: handle your private keys confidentially.
Get the keys associated with a login username/password. Important: handle your private keys confidentially.
Name
Type
Description
data
Object
data.username
string
[Optional] The login username.
data.password
string
[Optional] The login password.
data.offset
number
[Optional, default = 0] The eterministic offset to use.
[Optional] The secret key to recreate a public key from.
hybrix.sequential([
'keys' // generate random public and secret key pair
{seed:true}, 'keys' // generate keys derived from current user seed
someString => {seed:someString}, 'keys' // generate keys derived from seed string
mySecretKey => {secretKey:mySecretKey}, 'keys' // return keypair for mySecretKey
]
, onSuccess
, onError
, onProgress
);
sign{message, [public], [secret], [signature]} Sign a message with a secret key or verify the signature for a public key.
Sign a message with a secret key or verify the signature for a public key.
Name
Type
Description
data
Object
data.message
String
The message to sign or open.
data.public
String
[Optional] The public key to verify.
data.secret
String
[Optional] The secret key to sign with.
data.signature
Boolean | String
[Optional] Indication to create a detached signature or a detached signature to verify.
var myKeys;
hybrix.sequential([
'keys', // Create key pair
keys => { myKeys = keys; }, // Store key pair
myKeys => {return {message:'Hello World', secretKey:myKeys.secret}}, 'sign', // Sign message with secret key, returns signature
input => {return {message:'Hello World', publicKey:input.myKeys.public, signature:input.mySignature}}, 'sign' // Verify message with public key and signature
]
, onSuccess
, onError
, onProgress
);
Flow
call{func, [data]} Execute a custom function with callbacks. Usefull for sequential and parallel.
Execute a custom function with callbacks. Usefull for sequential and parallel.
Name
Type
Description
data
Object
data.func
Function
A function expecting data, dataCallback, errorCallback and optional progressCallback parameters.
data.data
Object
[Optional] The data to be passed to the function. If ommitted and call is used in a sequential command it will be passed from previous step.
hybrix.sequential([
{func: (data,onSuccess,onError,onProgress)=>{ // Declare a custom function
onProgress(0.5); // Set the progress to 50%
setTimeout(onSuccess,2000,data+1); // Wait to seconds, then output result + 1
}, data:1} , 'call' // Provide the initial data
],
onSuccess, // Define action to execute on successfull completion
onError, // Define action to execute when an error is encountered
onProgress // Define action to execute whenever there is a progress update
);
id{} Identity function, outputs the data that is passed
Identity function, outputs the data that is passed
parallel{$label, $label,data, $label,step, [_options], [_options,passErrors=false], [_options,failIfAllFail=true], [_options,failIfAnyFails=false]} Parallely executes several threads and collects results in a single object.
Parallely executes several threads and collects results in a single object.
Name
Type
Description
data
Object
Parallel steps to be processed.
data.$label
Object
A label given to the thread.
data.$label.data
Object
The initial data passed to this thread.
data.$label.step
Object
The step to execute with the data. Use 'sequential' to create multi step thread process.
data._options
Object
[Optional] An options object
data._options.passErrors
Object
[Optional, default = false] Whether to pass error results to the collected results object.
data._options.failIfAllFail
Object
[Optional, default = true] Whether fali stream if all steps fail
data._options.failIfAnyFails
Object
[Optional, default = false] Whether to fail entire stream if any step fail
sequential{} Sequentually executes functions and passes results to next step.
Sequentually executes functions and passes results to next step.
Name
Type
Description
data
Array
Sequential steps to be processed. An object indicates data that is supplied to the next step. A function is a transformation of the data of the previous step and given to the next step. A string is a method that used the data from the last step and supplies to the next step.
rout{query, [fallback], [channel], [meta=false], [retries=3], [cache=0], [host], [regular=true], [encryptByDefault=false], [data]} Make an api call to hybrixd node
createAccount{[entropy], [offset], [pool]} Create a new deterministic account with the entropy provided.
Create a new deterministic account with the entropy provided.
Name
Type
Description
data
Object
data.entropy
string
[Optional] CAREFUL! Using this feature incorrectly can reduce your security and privacy. Only use when you know what you're doing. Entropy can be provided. Must be a sufficient random string of at least 482 bytes.
data.offset
Function
[Optional] CAREFUL! Using this feature incorrectly can reduce your security and privacy. Only use when you know what you're doing. Use an offset to create multiple accounts from same entropy.
data.pool
Function
[Optional] CAREFUL! Using this feature incorrectly can reduce your security and privacy. Only use when you know what you're doing. Pool function can be overridden by a custom 1600 byte pool generator.
deterministic
login{host} Create an encrypted session with a host.
session{username, password, publicKey, secretKey, symbol, privateKey, [offset]} Create a local deterministic session and - if required - log out of current session.
Create a local deterministic session and - if required - log out of current session.
Name
Type
Description
data
Object
data.username
string
The username for the deterministic session
data.password
string
The password for the deterministic session
data.publicKey
string
The public key to use for the deterministic session (can not be used in combination with username/password!)
data.secretKey
string
The secret key to use for the deterministic session (can not be used in combination with username/password!)
data.symbol
string
The symbol to use for universal login
data.privateKey
string
The privateKey key to use for universal login(can not be used in combination with username/password!)
data.offset
string
[Optional] The offset to create alternative accounts
list{pattern, [sessionKey=false], [host], [channel=''], [local=true], [remote=true]} Check which keys matching a given pattern exist in hybrixd node storage
Check which keys matching a given pattern exist in hybrixd node storage
Name
Type
Description
data
Object
data.pattern
String
The pattern identifier for the data.
data.sessionKey
Boolean
[Optional, default = false] A toggle to use a sessionKey storage method.
data.host
String
[Optional] The host to store the data on.
data.channel
String
[Optional, default = ''] Indicate the channel 'y' for encryption, 'z' for both encryption and compression.
data.local
Boolean
[Optional, default = true] Whether to use local storage if available
data.remote
Boolean
[Optional, default = true] Whether to use remote storage
load{key, [encrypted=true], [sessionKey=false], [fallback], [host], [channel=''], [local=true], [remote=true], [mergeStrategy=(local,remote)], [sync=true]} Retrieve value associated with key from the hybrixd node storage
Retrieve value associated with key from the hybrixd node storage
Name
Type
Description
data
Object
data.key
String
The key identifier for the data.
data.encrypted
Boolean
[Optional, default = true] whether to encrypt the data with the user key, true by default.
data.sessionKey
Boolean
[Optional, default = false] A toggle to use a sessionKey storage method.
data.fallback
String
[Optional] Provide a fallback value, if call fails this value is used
data.host
String
[Optional] The host to store the data on.
data.channel
String
[Optional, default = ''] Indicate the channel 'y' for encryption, 'z' for both encryption and compression.
data.local
Boolean
[Optional, default = true] Whether to use local storage if available
data.remote
Boolean
[Optional, default = true] Whether to use remote storage
data.mergeStrategy
Boolean
[Optional, default = (local,remote)] What to do if results from local and remote storage differs
data.sync
Boolean
[Optional, default = true] If only available on either remote or storage, save it to the other as well
save{key, value, [sessionKey=false], [encrypted=true], [work=true], [queue=false], [submit=true], [host], [channel=''], [local=true], [remote=true]} Stringify and encrypt data with user keys.
Stringify and encrypt data with user keys.
Name
Type
Description
data
Object
data.key
String
The key identifier for the data.
data.value
Object
A string, array or object.
data.sessionKey
Boolean
[Optional, default = false] A toggle to use a sessionKey storage method.
data.encrypted
Boolean
[Optional, default = true] whether to encrypt the data with the user key.
data.work
String
[Optional, default = true] whether to perform proof of work.
data.queue
String
[Optional, default = false] whether to queue proof of work. Execute later with queue method
data.submit
String
[Optional, default = true] whether to submit proof of work.
data.host
String
[Optional] The host to store the data on.
data.channel
String
[Optional, default = ''] Indicate the channel 'y' for encryption, 'z' for both encryption and compression.
data.local
Boolean
[Optional, default = true] Whether to use local storage if available
data.remote
Boolean
[Optional, default = true] Whether to use remote storage
rawTransaction{symbol, target, amount, [validate=true], [message], [unspent], [source=address], [offset=0], [comparisonSymbol=hy], [fee], [time], [host], [channel]} Creates a raw transaction that is signed but not yet pushed to the network. Required assets and inputs are collected accordingly.
Creates a raw transaction that is signed but not yet pushed to the network. Required assets and inputs are collected accordingly.
Name
Type
Description
data
Object
data.symbol
String
The symbol of the asset
data.target
String
The target address
data.amount
Number
The amount that should be transferred
data.validate
Boolean
[Optional, default = true] Validate target address and available funds.
data.message
String
[Optional] Option to add data (message, attachment, op return) to a transaction.
data.unspent
Object
[Optional] Manually set the unspent data
data.source
String
[Optional, default = address] Provide optional (partial) source address.
data.offset
number
[Optional, default = 0] The deterministic offset
data.comparisonSymbol
String
[Optional, default = hy] Provide symbol to compare fees for multi transactions
data.fee
Number
[Optional] The fee.
data.time
Number
[Optional] Provide an explicit time timestamp.
data.host
String
[Optional] The host that should be used.
data.channel
String
[Optional] Indicate the channel 'y' for encryption, 'z' for both encryption and compression
transaction{symbol, target, amount, [validate=true], [message], [unspent], [source=address], [comparisonSymbol=hy], [offset=0], [fee], [time], [host], [channel], [addToPending=true]} Create, sign and execute a transaction e.g. push it into the network.
Create, sign and execute a transaction e.g. push it into the network.
Name
Type
Description
data
Object
data.symbol
String
The symbol of the asset
data.target
String
The target address
data.amount
Number
The amount that should be transferred
data.validate
Boolean
[Optional, default = true] Validate target address and available funds.
data.message
String
[Optional] Option to add data (message, attachment, op return) to a transaction.
data.unspent
Object
[Optional] Manually set the unspent data
data.source
String
[Optional, default = address] Provide optional (partial) source address.
data.comparisonSymbol
String
[Optional, default = hy] Provide symbol to compare fees for multi transactions
data.offset
number
[Optional, default = 0] The source offset
data.fee
Number
[Optional] The fee.
data.time
Number
[Optional] Provide an explicit time timestamp.
data.host
String
[Optional] The host that should be used.
data.channel
String
[Optional] Indicate the channel 'y' for encryption, 'z' for both encryption and compression
data.addToPending
Boolean
[Optional, default = true] Indicate whether to add the transaction to pending transaction list.
hybrix.sequential([
{username: 'DUMMYDUMMYDUMMY0', password: 'DUMMYDUMMYDUMMY0'}, 'session',
{host: 'http://localhost:1111/'}, 'addHost',
{symbol: 'dummy', target: '_dummyaddress_', amount:1}, 'transaction',
]
, onSuccess
, onError
, onProgress
);
const sha256 = require('js-sha256')
const TX_MAX_GET_LENGTH = 0; // all transactions currently default to using POST method
Misc
atom{amount, [factor], [symbol]} Convert decimal numbers to atomic numbers
Convert decimal numbers to atomic numbers
Name
Type
Description
data
Object
data.amount
string
amount to be formatted
data.factor
string
[Optional] number of decimals
data.symbol
string
[Optional] symbol of asset, can be used to retrieve the factor