Basic Tutorial: Hello Exchange Plugin

We will go over how to develop and install a basic plugin called hello-exchange. After developing this plugin, we will be able to call the endpoint GET /plugins/hello-exchange and receive the response:

{
public_message: 'Hello Exchange!',
private_message: 'Hello exchange...',
library_message: 'Hello World NPM',
moment_timestamp: <ISO_STRING>
}
  • public_message: A value set in public_meta.

  • private_message: A value set in meta

  • library_message: The string produced by our third-party npm library.

  • moment_timestamp: Date ISO string produced by a default library (moment).

Step 1: Add the basic values of the plugin to your JSON file.

{
name: 'hello-exchange',
version: 1,
bio: 'Demo plugin',
description: 'Demo plugin for proof of concept',
author: 'bitHolla',
...
}

Step 2: Add updatable values in public_meta and meta

The public_meta and meta objects are where you can add values that you may need to change while the plugin is running or values that will be unique for each instance of the plugin.

The public_meta object holds values that will be publicly available. It can be accessed in the script as publicMeta.

The meta object holds values that will only be available to the admin. An example of a good value to put here is an access token for a third party service like AWS. It can be accessed in the script as meta.

Both the public_meta and meta objects require the keys type, required, description, and value for each parameter added.

  • type is the data type of the parameter (only number, string, boolean, and date-time are allowed).

  • required is whether or not the parameter is required for the plugin.

  • description is the description of the parameter in use.

  • value is the actual value set for the plugin.

{
...
public_meta: {
public_message: {
type: 'string',
required: false,
description: 'A public message',
value: 'Hello Exchange!'
}
},
meta: {
public_message: {
type: 'string',
required: false,
description: 'A private message',
value: 'Hello exchange...'
}
},
...
}

Step 3: Add the necessary third party libraries to prescript

This exchange will use the NPM library hello-world-npm. This library only returns the string Hello World NPM. The purpose of this library for this plugin is to demonstrate how to use NPM libraries inside plugins.

To have the plugin add this library on installation, include the library name inside the install array in the prescript object.

{
...
prescript: {
install: ['hello-world-npm']
},
...
}

There are libraries that are automatically included in plugins. They can be access directly within the script.

Please do not add any libraries that are already included in the plugins. It is possible a different version of the library can be installed which can cause some unexpected bugs.

Step 4: Set script as the JavaScript ES6+ code for the plugin

The code in script is what is ran for a plugin. The code must be written in ES6+ and also has to be minified before. The library we recommend is uglify-es.

The code for our plugin is below.

const helloWorld = installedLibraries['hello-world-npm'];
const { public_message } = publicMeta;
const { private_message } = meta;
app.get('/plugins/hello-exchange', (req, res) => {
return res.json({
public_message: public_message.value,
private_message: private_message.value,
library_message: helloWorld(),
moment_timestamp: moment().toISOString()
});
});

Let's break the code down:

const helloWorld = installedLibraries['hello-world-npm'];

The libraries you installed through the prescripts.install array are stored in an object called installedLibraries. You can access them by passing the name of the installed library as a key to installedLibraries. We are accessing our hello-world-npm library in this line of code.

const { public_message } = publicMeta;
const { private_message } = meta;

The parameters added to public_meta and meta are stored in values publicMeta and meta, respectively. We are getting our public_message parameter from publicMeta and private_message parameter from our meta.

app.get('/plugins/hello-exchange', (req, res) => {
return res.json({
public_message: public_message.value,
private_message: private_message.value,
library_message: helloWorld(),
moment_timestamp: moment().toISOString()
});
});

The included plugin libraries listed in step 3 can be accessed directly in the script. In our example, we are using the app Express library to create a new endpoint and the moment library to get the current datetime.

In our response, we will return the values of our public_message and private_message. We will also output the value returned from helloWorld() to demonstrate how to use an outside library. Finally, we will return the current time using the included library moment.

Once we have our script for our plugin, we have to wrap it all into a string.

`const helloWorld = installedLibraries['hello-world-npm'];
const { public_message } = publicMeta;
const { private_message } = meta;
app.get('/plugins/hello-exchange', (req, res) => {
return res.json({
public_message: public_message.value,
private_message: private_message.value,
library_message: helloWorld(),
moment_timestamp: moment().toISOString()
});
});`

We also recommend minifying the script before you install your plugin. Your script will be minified after installation automatically but doing so before will ensure that the minifying process will succeed. We recommend using the library uglify-es.

const UglifyEs = require('uglify-es');
const minifiedScript = UglifyEs.minify(`
const helloWorld = installedLibraries['hello-world-npm'];
const { public_message } = publicMeta;
const { private_message } = meta;
app.get('/plugins/hello-exchange', (req, res) => {
return res.json({
public_message: public_message.value,
private_message: private_message.value,
library_message: helloWorld(),
moment_timestamp: moment().toISOString()
});
});
`).code;
console.log(minifiedScript);
// "script": "const helloWorld=installedLibraries[\"hello-world-npm\"],{public_message:public_message}=publicMeta,{private_message:private_message}=meta;app.get(\"/plugins/hello-exchange\",(e,s)=>s.json({public_message:public_message.value,private_message:private_message.value,library_message:helloWorld(),moment_timestamp:moment().toISOString()}));"

Once minified, add the script to the script field in your plugin JSON file.

{
...
script: "const helloWorld=installedLibraries[\"hello-world-npm\"],{public_message:public_message}=publicMeta,{private_message:private_message}=meta;app.get(\"/plugins/hello-exchange\",(e,s)=>s.json({public_message:public_message.value,private_message:private_message.value,library_message:helloWorld(),moment_timestamp:moment().toISOString()}));",
...
}

Step 5: Install the plugin

Once you've followed the steps above, you should have a JSON object for your plugin that looks like the one below:

{
"name": "hello-exchange",
"version": 1,
"type": null,
"author": "bitHolla",
"bio": "Say hello from an exchange",
"description": "Demo plugin for proof of concept",
"documentation": null,
"logo": null,
"icon": null,
"url": null,
"meta": {
"private_message": {
"type": "string",
"required": false,
"description": "A secret",
"value": "hello exchange..."
}
},
"public_meta": {
"public_message": {
"type": "string",
"required": false,
"description": "Not a secret",
"value": "Hello Exchange!"
}
},
"prescript": {
"install": [
"hello-world-npm"
],
"run": null
},
"postscript": {
"run": null
},
"script": "const helloWorld=installedLibraries[\"hello-world-npm\"],{public_message:public_message}=publicMeta,{private_message:private_message}=meta;app.get(\"/plugins/hello-exchange\",(e,s)=>s.json({public_message:public_message.value,private_message:private_message.value,library_message:helloWorld(),moment_timestamp:moment().toISOString()}));",
"admin_view": null,
"web_view": null
}

To install a plugin, you can use the endpoint POST <API_URL>/plugins with the JSON object above passed as the request body.

Once installed, you will be able to access the endpoint GET /plugins/hello-exchange. Your response should be:

{
public_message: 'Hello Exchange!',
private_message: 'Hello exchange...',
library_message: 'Hello World NPM',
moment_timestamp: <ISO_STRING>
}

Congratulations, you've created your first plugin!