Node side modules (Recipes)
A recipe file is a json file describing the properties of an asset (also token), a (data) source or an engine implementation.
For example: when you query hybrixd for the balance of your waves address: /asset/waves/$ADDRESS
this will be routed to the Node side module defined in
recipes/asset.waves.json
.
The logic there (written in qrtz) will reformat the request to
https://nodes.wavesplatform.com/addresses/balance/details/$YOUR_ADDRESS
it will retrieve the result, extract the required information, reformat that and return the standardized end result.
Recipes are stored in the $HYBRIXD/node/recipes
folder. View on gitlab
For a token only a basic recipe is required that will import an existing chain's properties.
Example for an asset foo with properties host and cache and quartz program for balance that does something and returns something:
asset.foo.json { "symbol" :"foo", "host" : "http://foo.bar", "quartz" : { "balance" : ["dosomething", "returnsomething"] }, "router" : { "balance" : "Does something and then returns something to the user." } }
A recipe defines either an asset/token or a source. For assets (and tokens) a symbol is required, for sources an id.
To facilitate some common standards there are qrtz engines available for Insight and Electrum rpc's. Import these to use their functionality
Filename
For assets the filename is defined as /recipes/asset.$SYMBOL.json
or /recipes/token.$SYMBOL.json
For sources the filename is defined as /recipes/source.$TYPE.$ID.json
For engines the filename is defined as /recipes/engine.$NAME.json
Properties
symbol |
(Only required for assets)
Discription: A string containing the symbol. This is used as the main idenitfier.
Format: "$BASE[.$TOKEN]"
Examples: "BTC" , "ETH.SHIFT"
|
source |
(Only required for sources)
Discription:
Examples: "abe.bitcoin" , "insight.litecoin" , "deterministic"
|
engine |
(Only required for engines)
Discription:
Examples: "storage"
|
name |
Discription: A string containing the display name (for pretty printing).
Example: "Bitcoin"
|
mode |
Discription: A string containing the deterministic mode.
Format: "$DETERMINISTIC_MODULE.$SUBMODE"
Example: "bitjoinjslib.bitcoin"
|
contract | (Only required for token assets) Description: The unique identifier for an asset token |
originator | (Only required for token assets) Description: The creator or origin address for an asset token |
import |
Discription: A string or array of strings containing the id's /
symbols of the recipes from which this recipe should inherit
properties. Cf Import section below
Example: "btc" , ["btc","eth"] , "btc::host"
|
module | Discription: The name of the server/node side code implementation |
module-deterministic | (Only required for assets) Discription: The name of the client side code implementation (TODO TO BE RENAMED!) |
factor | (Only required for assets) Discription: The number of decimal digits used for this asset. |
fee | (Only required for assets) Discription: A number representing the fee associated with transfering assets |
fee-symbol | (Optional for assets) Discription: the symbol in which the fee is calculated |
host | A string or array of strings containing the hosts
|
quartz | Defines the Qrtz code. A function is defined by an array of qrtz statements. |
router | Defines the routing definitions. Used to expose functions as API endpoints and to generate documentation. |
Asset Endpoints
An asset should provide the following endpoints: TODO TODO mention default.qrtzEndpoint | Description | Expected output |
/balance/$ADDRESS | ||
/transaction/$TRANSACTION_ID | ||
/validate/$ADDRESS | ||
/sample/$ADDRESS | ||
/details/$ADDRESS | ||
/fee | ||
/factor | ||
/unspent/$ADDRESS |
qrtz
Browse to https://api.hybrix.io/help/qrtz for more help on qrtz.
$ Operator $PROPERTY
For qrtz commands the $
is used (inspired by posix) to retrieve variables:
Calling /asset/foo/balance/bar
on
asset.foo.json { "id" :"foo", "a" : 1, "b" : 2, "quartz" : { "balance" : ["dosomething with $a, $b, $0", "returns $1"] } }
Results in
asset.foo.json { "id" :"foo", "a" : 1, "b" : 2, "quartz" : { "balance" : ["dosomething with 1, 2, balance", "returns bar"] } }
Cross recipe variables $RECIPE::PROPERTY
The $foo::bar
notation can be used to reference variables in other
(non imported files)
Given
asset.foo.json { "id" :"foo", "a" : 1, }
then
asset.bar.json { "id" :"bar", "a" : -1, "quartz" : { "balance" : ["dosomething with $a, $foo::a", "returnsomething"] } }
Compiles to:
{ "id" :"bar", "a" : -1, "quartz" : { "balance" : ["dosomething with -1, 1", "returnsomething"] } }
Import
Inheritance using "import"
:
Given foo.json
asset.foo.json { "id" :"foo", "a" : 1, "b" : 2, }
bar.json
can inherit foo.json
by using
asset.bar.json { "id" :"bar", "a" : -1, "c" : 3, "import" : "foo" }
which compiles to
asset.bar.json { "id" :"bar", "a" : -1, "b" : 2, "c" : 3, "import" : "foo" }
Note that the value of a
is retained, bu b
is added.
Multi-inheritance
Multi-inheritance can be defined by using:
asset.bar.json { "id" :"bar", "a" : -1, "c" : 3, "import" : ["foo1","foo2","foo3"] }
They are imported from left to right (values in foo3
overwrite those of foo1
and foo2
)
Token inheritance
A token asset, identified by a two part symbol "$BASE.$TOKEN"
, for
example: "eth.shift"
will automatically inherit the qrtz code from its
base asset "eth"
.
Javascript modules
To run your javascript code directly you can use the qrtz func method.
To create a helloworld module create a folder in the modules
folder with the following
files:
modules/
-
helloworld/
-
engine.helloworld.json
module.js
With the following content:
modules/helloworld/engine.helloworld.json:
{
"engine":"helloworld"
"name":"Hello World",
"module":"helloworld",
"router":{
"example" : "Returns the text 'example'",
"hello" : "Returns the text 'hello world'"
},
"quartz": {
"example" : [
"done example"
],
"hello" : [
"func hello"
]
}
}
The router defines the api endpoints and their corresponding api
endpoints. With this module you can now
call /engine/helloworld/example
and /engine/helloworld/hello
and view the automatically generated help page on /help/api/engine/helloworld
The qrtz function example
returns 'example'
immediatly by using qrtz directly. The function hello will call the
hello function in de module.js:
modules/helloworld/module.js:
function hello(proc, data){ // proc, the process handle and the data from the data stream are passed (data is unused in this example
proc.done('hello world'); // pass 'hello world' as output
// proc.fail('Oops! Someting gone wrong'); // return a failure
// proc.peek('myVariable'); // retrieve the content of the variable named myVariable
// proc.poke('myVariable',123); // set the content of the myVariable variable
}
exports.hello = hello; // export the function so it can be used by qrtz func
Check out the existing modules: View on gitlab