Finex REST API Usage in JS

const axios = require('axios');
const crypto = require('crypto');
const WebSocket = require('ws');

const BASE_URL = 'https://your.deployed.stack';
const WS_URL = 'wss://your.deployed.stack';

const KID = 'kid';
const SECRET = 'secret';

// Auth headers

// In Barong Api keys HMAC-SHA256 is used.
// HMAC (hash-based message authentication code)
// https://en.wikipedia.org/wiki/HMAC Signature is a HMAC hash computed on
// message. Message is composed of nonce and KID.
const generateSignature = (nonce, key, secret) =>
  (crypto.createHmac('sha256', secret).update(nonce + key).digest('hex'));

// X-Auth-Apikey - Barong's Api Key KID
// X-Auth-Nonce - current timestamp (UNIX).
// X-Auth-Signature - HMAC signature, check generateSignature
const authHeaders = () => {
  const nonce = Date.now().toString();

  return {
    'X-Auth-Apikey': KID,
    'X-Auth-Nonce': nonce,
    'X-Auth-Signature': generateSignature(nonce, KID, SECRET)
  };
};

// testAuth is getting info about api key owner.
async function testAuth() {
  try {
    const response = await axios.get(
      BASE_URL + '/api/v2/barong/resource/users/me',
      { headers: authHeaders() });

    console.log({ response })
  } catch (error) {
    console.error({ error });
  }
}

// Finex API

async function finexOrderCreate() {
  try {
    const response = await axios.post(
      BASE_URL + '/api/v2/finex/market/orders', {
      type: 'post_only',
      price: '1.01',
      amount: '0.07',
      market: 'ethusdt',
      side: 'sell'
    },
      { headers: authHeaders() });

    return response;
  } catch (error) {
    console.error({ error });
  }
}

async function finexOrderCancel(id) {
  try {
    await axios.post(
      BASE_URL + '/api/v2/finex/market/orders/cancel/' + id, {},
      { headers: authHeaders() });
  } catch (error) {
    console.error({ error });
  }
}

async function finexOrderCreateBulk() {
  try {
    const response = await axios.post(
      BASE_URL + '/api/v2/finex/market/bulk/orders',
      [
        {
          type: 'post_only',
          price: '1.01',
          amount: '0.07',
          market: 'ethusdt',
          side: 'sell'
        },
        {
          type: 'post_only',
          price: '1.01',
          amount: '0.07',
          market: 'ethusdt',
          side: 'sell'
        },
        {
          type: 'post_only',
          price: '1.01',
          amount: '0.07',
          market: 'ethusdt',
          side: 'sell'
        }
      ],
      { headers: authHeaders() });

    return response;
  } catch (error) {
    console.error({ error });
  }
}

async function finexOrderCancelBulk(uuids) {
  try {
    await axios.delete(
      BASE_URL + '/api/v2/finex/market/bulk/orders',
      { data: uuids, headers: authHeaders() });
  } catch (error) {
    console.error({ error });
  }
}

// WebSocket

function subscribePublic() {
  const ws =
    new WebSocket(WS_URL + '/api/v2/ranger/public/?stream=global.tickers');

  ws.on('message', data => console.log(data));
}

function subscribePrivate() {
  const ws = new WebSocket(
    WS_URL +
    '/api/v2/ranger/private/?stream=order&stream=trade&stream=balances',
    { headers: authHeaders() },
  );

  ws.on('message', data => console.log(data));
}


async function runExample() {
  subscribePublic();
  subscribePrivate();

  await testAuth();
  const orderResponse = await finexOrderCreate();
  await finexOrderCancel(orderResponse.data.uuid);
  const orderResponseBulk = await finexOrderCreateBulk();
  await finexOrderCancelBulk(orderResponseBulk.data.map(e => e.uuid));
}

runExample();