@firefly-exchange/firefly-client
Version:
The Firefly Client Library allows traders to sign, create, retrieve and listen to orders on Firefly Exchange.
926 lines (925 loc) • 98.5 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable prettier/prettier */
/* eslint-disable no-undef */
const chai_1 = __importStar(require("chai"));
const chai_as_promised_1 = __importDefault(require("chai-as-promised"));
const promises_1 = require("timers/promises");
const library_1 = require("@firefly-exchange/library");
const index_1 = require("../index");
chai_1.default.use(chai_as_promised_1.default);
const testAcctKey = "4d6c9531e0042cc8f7cf13d8c3cf77bfe239a8fed95e198d498ee1ec0b1a7e83";
const testAcctPubAddr = "0xFEa83f912CF21d884CDfb66640CfAB6029D940aF";
const testSubAccKey = "7540d48032c731b3a17947b63a04763492d84aef854246d355a703adc9b54ce9";
const testSubAccPubAddr = "0xDa53d33E49F1f4689C3B9e1EB6E265244C77B92B";
let client;
const network = index_1.Networks.TESTNET_ARBITRUM;
describe("FireflyClient", () => {
//* set environment from here
const symbol = "BTC-PERP";
let defaultLeverage = 3;
let buyPrice = 18000;
let sellPrice = 20000;
let marketPrice = 0;
let indexPrice = 1600;
before(() => __awaiter(void 0, void 0, void 0, function* () {
client = new index_1.FireflyClient(true, network, testAcctKey);
yield client.init();
// TODO! uncomment when done testing specifically on BTC-PERP
// const allSymbols = await client.getMarketSymbols();
// //get first symbol to run tests on
// if (allSymbols.data) {
// symbol = allSymbols.data[0];
// }
// TODO! uncomment above code when done testing specifically on BTC-PERP
console.log(`--- Trading symbol: ${symbol} ---`);
// get default leverage
defaultLeverage = yield client.getUserDefaultLeverage(symbol);
console.log(`- on leverage: ${defaultLeverage}`);
// market data
const marketData = yield client.getMarketData(symbol);
if (marketData.data && (0, library_1.bnStrToBaseNumber)(marketData.data.marketPrice) > 0) {
marketPrice = (0, library_1.bnStrToBaseNumber)(marketData.data.marketPrice);
indexPrice = (0, library_1.bnStrToBaseNumber)(marketData.data.indexPrice || "0");
const percentChange = 3 / 100; // 3%
buyPrice = Number((marketPrice - marketPrice * percentChange).toFixed(0));
sellPrice = Number((marketPrice + marketPrice * percentChange).toFixed(0));
console.log(`- market price: ${marketPrice}`);
console.log(`- index price: ${indexPrice}`);
}
}));
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
client = new index_1.FireflyClient(true, network, testAcctKey);
yield client.init();
client.addMarket(symbol);
}));
afterEach(() => {
client.sockets.close();
});
it("should initialize the client", () => __awaiter(void 0, void 0, void 0, function* () {
(0, chai_1.expect)(client).to.be.not.eq(undefined);
}));
it("should return public address of account", () => __awaiter(void 0, void 0, void 0, function* () {
(0, chai_1.expect)(client.getPublicAddress()).to.be.equal(testAcctPubAddr);
}));
describe("Sub account Tests", () => {
let clientSubAccount;
before(() => __awaiter(void 0, void 0, void 0, function* () {
clientSubAccount = new index_1.FireflyClient(true, network, testSubAccKey);
yield clientSubAccount.init();
clientSubAccount.addMarket(symbol);
// adding sub acc
const resp = yield client.setSubAccount(testSubAccPubAddr.toLowerCase(), symbol, true);
if (!resp.ok) {
throw Error(resp.message);
}
}));
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
clientSubAccount = new index_1.FireflyClient(true, network, testSubAccKey);
yield clientSubAccount.init();
clientSubAccount.addMarket(symbol);
}));
it("set and get leverage on behalf of parent account", () => __awaiter(void 0, void 0, void 0, function* () {
// make sure to first whitelist the subaccount with the below parent account to run this test.
// To whitelist the subaccount use the above test {set sub account}
// and subaccount must be authenticated/initialized with the client.
// When
const newLeverage = 5;
const res = yield clientSubAccount.adjustLeverage({
symbol,
leverage: newLeverage,
parentAddress: testAcctPubAddr.toLowerCase(),
}); // set leverage will do contract call as the account using is new
const lev = yield clientSubAccount.getUserDefaultLeverage(symbol, testAcctPubAddr.toLowerCase()); // get leverage
// Then
(0, chai_1.expect)(res.ok).to.eq(true);
(0, chai_1.expect)(lev).to.equal(newLeverage);
}));
it("should place a MARKET BUY order on behalf of parent exchange", () => __awaiter(void 0, void 0, void 0, function* () {
// make sure to first whitelist the subaccount with the below parent account to run this test.
// To whitelist the subaccount use the above test {set sub account}
// and subaccount must be authenticated/initialized with the client.
const signedOrder = yield clientSubAccount.createSignedOrder({
symbol,
price: 0,
quantity: 0.01,
side: library_1.ORDER_SIDE.BUY,
leverage: defaultLeverage,
orderType: library_1.ORDER_TYPE.MARKET,
// parent account
maker: testAcctPubAddr,
});
const response = yield clientSubAccount.placeSignedOrder(Object.assign({}, signedOrder));
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should cancel the open order on behalf of parent account", () => __awaiter(void 0, void 0, void 0, function* () {
// make sure to first whitelist the subaccount with the below parent account to run this test.
// To whitelist the subaccount use the above test {set sub account}
// and subaccount must be authenticated/initialized with the client.
const signedOrder = yield clientSubAccount.createSignedOrder({
symbol,
price: sellPrice,
quantity: 0.01,
side: library_1.ORDER_SIDE.SELL,
leverage: defaultLeverage,
orderType: library_1.ORDER_TYPE.LIMIT,
maker: testAcctPubAddr,
});
const response = yield clientSubAccount.placeSignedOrder(Object.assign(Object.assign({}, signedOrder), { clientId: "test cancel order" }));
const cancelSignature = yield clientSubAccount.createOrderCancellationSignature({
symbol,
hashes: [response.response.data.hash],
parentAddress: testAcctPubAddr.toLowerCase(),
});
const cancellationResponse = yield clientSubAccount.placeCancelOrder({
symbol,
hashes: [response.response.data.hash],
signature: cancelSignature,
parentAddress: testAcctPubAddr.toLowerCase(),
});
(0, chai_1.expect)(cancellationResponse.ok).to.be.equal(true);
}));
it("should get all open orders on behalf of parent account", () => __awaiter(void 0, void 0, void 0, function* () {
// make sure to first whitelist the subaccount with the below parent account to run this test.
// To whitelist the subaccount use the above test {set sub account}
// and subaccount must be authenticated/initialized with the client.
const data = yield clientSubAccount.getUserOrders({
statuses: [library_1.ORDER_STATUS.OPEN],
symbol,
parentAddress: testAcctPubAddr.toLowerCase(),
});
(0, chai_1.expect)(data.ok).to.be.equals(true);
(0, chai_1.expect)(data.response.data.length).to.be.gte(0);
}));
it("should get user's Position on behalf of parent account", () => __awaiter(void 0, void 0, void 0, function* () {
// make sure to first whitelist the subaccount with the below parent account to run this test.
// To whitelist the subaccount use the above test {set sub account}
// and subaccount must be authenticated/initialized with the client.
const response = yield clientSubAccount.getUserPosition({
symbol,
parentAddress: testAcctPubAddr.toLowerCase(),
});
const position = response.data;
if (Object.keys(position).length > 0) {
(0, chai_1.expect)(response.response.data.symbol).to.be.equal(symbol);
}
}));
it("should get user's Trades on behalf of parent account", () => __awaiter(void 0, void 0, void 0, function* () {
// make sure to first whitelist the subaccount with the below parent account to run this test.
// To whitelist the subaccount use the above test {set sub account}
// and subaccount must be authenticated/initialized with the client.
const response = yield clientSubAccount.getUserTrades({
symbol,
parentAddress: testAcctPubAddr,
});
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get user's Trades history on behalf of parent account", () => __awaiter(void 0, void 0, void 0, function* () {
// make sure to first whitelist the subaccount with the below parent account to run this test.
// To whitelist the subaccount use the above test {set sub account}
// and subaccount must be authenticated/initialized with the client.
const response = yield clientSubAccount.getUserTradesHistory({
symbol,
parentAddress: testAcctPubAddr,
});
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get User Account Data on behalf of parent account", () => __awaiter(void 0, void 0, void 0, function* () {
// make sure to first whitelist the subaccount with the below parent account to run this test.
// To whitelist the subaccount use the above test {set sub account}
// and subaccount must be authenticated/initialized with the client.
const response = yield clientSubAccount.getUserAccountData(testAcctPubAddr);
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get Funding History records for user on behalf of parent account", () => __awaiter(void 0, void 0, void 0, function* () {
// make sure to first whitelist the subaccount with the below parent account to run this test.
// To whitelist the subaccount use the above test {set sub account}
// and subaccount must be authenticated/initialized with the client.
const response = yield clientSubAccount.getUserFundingHistory({
symbol,
parentAddress: testAcctPubAddr,
});
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
});
describe("Market", () => {
it(`should add ${symbol} market`, () => __awaiter(void 0, void 0, void 0, function* () {
(0, chai_1.expect)(client.addMarket(symbol)).to.be.equal(true);
}));
it(`should add ${symbol} market with custom orders contract address`, () => __awaiter(void 0, void 0, void 0, function* () {
(0, chai_1.expect)(client.addMarket(symbol, "0x36AAc8c385E5FA42F6A7F62Ee91b5C2D813C451C")).to.be.equal(true);
}));
it("should throw error as there is no market by name of TEST-PERP in deployedContracts", () => __awaiter(void 0, void 0, void 0, function* () {
chai_1.assert.throws(() => {
client.addMarket("TEST-PERP");
}, Error, `Contract "IsolatedTrader" not found in contract addresses for network id ${network.chainId}`);
}));
it("should add market despite not existing in deployed contracts", () => __awaiter(void 0, void 0, void 0, function* () {
(0, chai_1.expect)(client.addMarket("TEST-PERP", "0x36AAc8c385E5FA42F6A7F62Ee91b5C2D813C451C")).to.be.equal(true);
}));
it("should return False as BTC-PERP market is already added", () => __awaiter(void 0, void 0, void 0, function* () {
(0, chai_1.expect)(client.addMarket(symbol)).to.be.equal(true);
(0, chai_1.expect)(client.addMarket(symbol)).to.be.equal(false);
}));
it("should remove the BTC market", () => __awaiter(void 0, void 0, void 0, function* () {
(0, chai_1.expect)(client.addMarket(symbol)).to.be.equal(true);
(0, chai_1.expect)(client.removeMarket(symbol)).to.be.equal(true);
}));
it("should return false when trying to remove a non-existent market", () => __awaiter(void 0, void 0, void 0, function* () {
(0, chai_1.expect)(client.removeMarket(symbol)).to.be.equal(false);
}));
});
describe("Fund Gas", () => {
it("get gas token balance", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getChainNativeBalance();
(0, chai_1.expect)(new library_1.BigNumber(response).gte(new library_1.BigNumber(0))).to.eq(true);
}));
});
describe("Balance", () => {
it("should get 10K Test USDCs", () => __awaiter(void 0, void 0, void 0, function* () {
const usdcBalance = yield client.getUSDCBalance();
(0, chai_1.expect)(yield client.mintTestUSDC()).to.be.equal(true);
(0, chai_1.expect)(yield client.getUSDCBalance()).to.be.gte(usdcBalance + 10000);
}));
it("should move 1 USDC token to Margin Bank", () => __awaiter(void 0, void 0, void 0, function* () {
var _a;
const usdcBalance = yield client.getUSDCBalance();
(0, chai_1.expect)((_a = (yield client.depositToMarginBank(1))) === null || _a === void 0 ? void 0 : _a.ok).to.be.equal(true);
(0, chai_1.expect)(yield client.getMarginBankBalance()).to.be.gte(1);
(0, chai_1.expect)(yield client.getUSDCBalance()).to.be.gte(usdcBalance - 1);
}));
it("should withdraw 1 USDC token from Margin Bank", () => __awaiter(void 0, void 0, void 0, function* () {
var _b;
const usdcBalance = yield client.getUSDCBalance();
(0, chai_1.expect)((_b = (yield client.withdrawFromMarginBank(1))) === null || _b === void 0 ? void 0 : _b.ok).to.be.equal(true);
(0, chai_1.expect)(yield client.getUSDCBalance()).to.be.gte(usdcBalance + 1);
}));
it("should move all USDC token from Margin Bank", () => __awaiter(void 0, void 0, void 0, function* () {
var _c;
(0, chai_1.expect)((_c = (yield client.withdrawFromMarginBank())) === null || _c === void 0 ? void 0 : _c.ok).to.be.equal(true);
(0, chai_1.expect)(yield client.getMarginBankBalance()).to.be.eql(0);
}));
});
describe("Leverage getter and setter", () => {
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
client.addMarket(symbol);
}));
it("set and get leverage", () => __awaiter(void 0, void 0, void 0, function* () {
// Given
const web3 = new library_1.Web3(network.url);
const wallet = web3.eth.accounts.create();
const clientTemp = new index_1.FireflyClient(true, network, wallet.privateKey);
yield clientTemp.init();
// When
const newLeverage = 4;
const res = yield clientTemp.adjustLeverage({
symbol,
leverage: newLeverage,
}); // set leverage will do contract call as the account using is new
const lev = yield clientTemp.getUserDefaultLeverage(symbol); // get leverage
// Then
(0, chai_1.expect)(res.ok).to.eq(true);
(0, chai_1.expect)(lev).to.equal(4);
}));
});
describe("Create/Place/Post Orders", () => {
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
client.addMarket(symbol);
}));
it("should put 10K in margin bank", () => __awaiter(void 0, void 0, void 0, function* () {
const minted = yield client.mintTestUSDC();
const deposited = yield client.depositToMarginBank(10000);
(0, chai_1.expect)(minted).to.eq(true);
(0, chai_1.expect)(deposited.ok).to.eq(true);
}));
it("should throw error as DOT market is not added to client", () => __awaiter(void 0, void 0, void 0, function* () {
yield (0, chai_1.expect)(client.createSignedOrder({
symbol: "DOT-TEST",
price: 0,
quantity: 0.1,
side: library_1.ORDER_SIDE.SELL,
orderType: library_1.ORDER_TYPE.MARKET,
})).to.be.eventually.rejectedWith("Provided Market Symbol(DOT-TEST) is not added to client library");
}));
it("should create signed order", () => __awaiter(void 0, void 0, void 0, function* () {
const signedOrder = yield client.createSignedOrder({
symbol,
price: 0,
quantity: 0.1,
side: library_1.ORDER_SIDE.SELL,
orderType: library_1.ORDER_TYPE.MARKET,
});
(0, chai_1.expect)(signedOrder.leverage).to.be.equal(1);
(0, chai_1.expect)(signedOrder.price).to.be.equal(0);
(0, chai_1.expect)(signedOrder.quantity).to.be.equal(0.1);
}));
it("should create signed order and verify the signature", () => __awaiter(void 0, void 0, void 0, function* () {
const params = {
symbol,
price: 0,
quantity: 0.1,
side: library_1.ORDER_SIDE.SELL,
orderType: library_1.ORDER_TYPE.MARKET,
};
const signedOrder = yield client.createSignedOrder(params);
const isValid = client.verifyOrderSignature(signedOrder);
(0, chai_1.expect)(isValid).to.be.equal(true);
}));
it("should place a LIMIT SELL order on exchange", () => __awaiter(void 0, void 0, void 0, function* () {
const signedOrder = yield client.createSignedOrder({
symbol,
price: sellPrice,
quantity: 0.1,
side: library_1.ORDER_SIDE.SELL,
leverage: defaultLeverage,
orderType: library_1.ORDER_TYPE.LIMIT,
});
const response = yield client.placeSignedOrder(Object.assign({}, signedOrder));
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should place a MARKET BUY order on exchange", () => __awaiter(void 0, void 0, void 0, function* () {
const signedOrder = yield client.createSignedOrder({
symbol,
price: 0,
quantity: 0.1,
side: library_1.ORDER_SIDE.SELL,
leverage: defaultLeverage,
orderType: library_1.ORDER_TYPE.MARKET,
});
const response = yield client.placeSignedOrder(Object.assign({}, signedOrder));
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should post a LIMIT order on exchange", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.postOrder({
symbol,
price: buyPrice,
quantity: 0.1,
side: library_1.ORDER_SIDE.BUY,
leverage: defaultLeverage,
orderType: library_1.ORDER_TYPE.LIMIT,
clientId: "Test limit order",
});
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should post a BUY STOP LIMIT order on exchange", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.postOrder({
symbol,
quantity: 0.1,
side: library_1.ORDER_SIDE.BUY,
leverage: defaultLeverage,
orderType: library_1.ORDER_TYPE.STOP_LIMIT,
clientId: "Test stop limit order",
price: indexPrice + 4,
triggerPrice: indexPrice + 2,
});
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should post a SELL STOP LIMIT order on exchange", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.postOrder({
symbol,
quantity: 0.1,
side: library_1.ORDER_SIDE.SELL,
leverage: defaultLeverage,
orderType: library_1.ORDER_TYPE.STOP_LIMIT,
clientId: "Test stop limit order",
price: indexPrice - 4,
triggerPrice: indexPrice - 2,
});
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
});
describe("Cancel Orders", () => {
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
client.addMarket(symbol);
}));
it("should cancel the open order", () => __awaiter(void 0, void 0, void 0, function* () {
const signedOrder = yield client.createSignedOrder({
symbol,
price: sellPrice,
quantity: 0.001,
side: library_1.ORDER_SIDE.SELL,
leverage: defaultLeverage,
orderType: library_1.ORDER_TYPE.LIMIT,
});
const response = yield client.placeSignedOrder(Object.assign(Object.assign({}, signedOrder), { clientId: "test cancel order" }));
const cancelSignature = yield client.createOrderCancellationSignature({
symbol,
hashes: [response.response.data.hash],
});
const cancellationResponse = yield client.placeCancelOrder({
symbol,
hashes: [response.response.data.hash],
signature: cancelSignature,
});
(0, chai_1.expect)(cancellationResponse.ok).to.be.equal(true);
}));
it("should get Invalid Order Signature error", () => __awaiter(void 0, void 0, void 0, function* () {
const signedOrder = yield client.createSignedOrder({
symbol,
price: sellPrice,
quantity: 0.001,
side: library_1.ORDER_SIDE.SELL,
leverage: defaultLeverage,
orderType: library_1.ORDER_TYPE.LIMIT,
});
const response = yield client.placeSignedOrder(Object.assign({}, signedOrder));
const cancellationResponse = yield client.placeCancelOrder({
symbol,
hashes: [response.response.data.hash],
signature: "0xSomeRandomStringWhichIsNotACorrectSignature",
});
(0, chai_1.expect)(cancellationResponse.ok).to.be.equal(false);
(0, chai_1.expect)(cancellationResponse.response.message).to.be.equal("Invalid Order Signature");
}));
it("should post a cancel order on exchange", () => __awaiter(void 0, void 0, void 0, function* () {
var _a;
const response = yield client.postOrder({
symbol,
price: sellPrice + 2,
quantity: 0.1,
side: library_1.ORDER_SIDE.SELL,
leverage: defaultLeverage,
orderType: library_1.ORDER_TYPE.LIMIT,
});
(0, chai_1.expect)(response.ok).to.be.equal(true);
const cancelResponse = yield client.postCancelOrder({
symbol,
hashes: [(_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.hash],
});
(0, chai_1.expect)(cancelResponse.ok).to.be.equal(true);
}));
it("should cancel all open orders", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.cancelAllOpenOrders(symbol);
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should cancel all open orders on behalf of parent account", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.cancelAllOpenOrders(symbol, testAcctPubAddr);
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should cancel STOP LIMIT order on exchange", () => __awaiter(void 0, void 0, void 0, function* () {
var _b;
const response = yield client.postOrder({
symbol,
quantity: 0.1,
side: library_1.ORDER_SIDE.SELL,
leverage: defaultLeverage,
orderType: library_1.ORDER_TYPE.STOP_LIMIT,
price: indexPrice - 4,
triggerPrice: indexPrice - 2,
});
(0, chai_1.expect)(response.ok).to.be.equal(true);
const cancelResponse = yield client.postCancelOrder({
symbol,
hashes: [(_b = response === null || response === void 0 ? void 0 : response.data) === null || _b === void 0 ? void 0 : _b.hash],
});
(0, chai_1.expect)(cancelResponse.ok).to.be.equal(true);
}));
it("should cancel STOP MARKET order on exchange", () => __awaiter(void 0, void 0, void 0, function* () {
var _c;
const response = yield client.postOrder({
symbol,
quantity: 0.1,
side: library_1.ORDER_SIDE.SELL,
leverage: defaultLeverage,
orderType: library_1.ORDER_TYPE.STOP_MARKET,
price: indexPrice - 4,
triggerPrice: indexPrice - 2,
});
(0, chai_1.expect)(response.ok).to.be.equal(true);
const cancelResponse = yield client.postCancelOrder({
symbol,
hashes: [(_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.hash],
});
(0, chai_1.expect)(cancelResponse.ok).to.be.equal(true);
}));
});
describe("Get User Orders", () => {
it("should get all open orders", () => __awaiter(void 0, void 0, void 0, function* () {
const data = yield client.getUserOrders({
statuses: [library_1.ORDER_STATUS.OPEN],
symbol,
});
(0, chai_1.expect)(data.ok).to.be.equals(true);
(0, chai_1.expect)(data.response.data.length).to.be.gte(0);
}));
it("should get all stand by stop orders", () => __awaiter(void 0, void 0, void 0, function* () {
const data = yield client.getUserOrders({
statuses: [library_1.ORDER_STATUS.STAND_BY, library_1.ORDER_STATUS.STAND_BY_PENDING],
symbol,
});
(0, chai_1.expect)(data.ok).to.be.equals(true);
(0, chai_1.expect)(data.response.data.length).to.be.gte(0);
}));
it("should get all open orders on behalf of parent account", () => __awaiter(void 0, void 0, void 0, function* () {
// make sure to first whitelist the subaccount with the below parent account to run this test.
// To whitelist the subaccount use the above test {set sub account}
// and subaccount must be authenticated/initialized with the client.
const data = yield client.getUserOrders({
statuses: [library_1.ORDER_STATUS.OPEN],
symbol,
parentAddress: "0xFEa83f912CF21d884CDfb66640CfAB6029D940aF".toLowerCase(),
});
(0, chai_1.expect)(data.ok).to.be.equals(true);
(0, chai_1.expect)(data.response.data.length).to.be.gte(0);
}));
it("should handle get open orders of non-existent hashes", () => __awaiter(void 0, void 0, void 0, function* () {
const data = yield client.getUserOrders({
statuses: [library_1.ORDER_STATUS.OPEN],
symbol,
orderHashes: ["test0"], // incorrect hash
});
(0, chai_1.expect)(data.ok).to.be.equals(true);
(0, chai_1.expect)(data.response.data.length).to.be.eq(0);
}));
it("should get open orders of specific hashes", () => __awaiter(void 0, void 0, void 0, function* () {
const data = yield client.getUserOrders({
statuses: [library_1.ORDER_STATUS.OPEN],
symbol,
});
if (data.ok && data.data.length > 0) {
const data1 = yield client.getUserOrders({
statuses: [library_1.ORDER_STATUS.OPEN],
symbol,
orderHashes: data.response.data[0].hash,
});
(0, chai_1.expect)(data1.ok).to.be.equals(true);
(0, chai_1.expect)(data1.data.length).to.be.eq(1);
}
(0, chai_1.expect)(data.ok).to.be.equals(true);
}));
it("should get all cancelled orders", () => __awaiter(void 0, void 0, void 0, function* () {
const data = yield client.getUserOrders({
statuses: [library_1.ORDER_STATUS.CANCELLED],
symbol,
});
(0, chai_1.expect)(data.ok).to.be.equal(true);
}));
it("should get cancelled orders", () => __awaiter(void 0, void 0, void 0, function* () {
const data = yield client.getUserOrders({
statuses: [library_1.ORDER_STATUS.CANCELLED],
symbol,
pageSize: 1,
});
(0, chai_1.expect)(data.ok).to.be.equals(true);
}));
it("should get 0 expired orders as page 10 does not exist for expired orders", () => __awaiter(void 0, void 0, void 0, function* () {
const data = yield client.getUserOrders({
statuses: [library_1.ORDER_STATUS.EXPIRED],
symbol,
pageNumber: 10,
});
(0, chai_1.expect)(data.response.data.length).to.be.equals(0);
}));
it("should get only LIMIT filled orders", () => __awaiter(void 0, void 0, void 0, function* () {
const data = yield client.getUserOrders({
statuses: [library_1.ORDER_STATUS.FILLED],
orderType: [library_1.ORDER_TYPE.LIMIT],
symbol,
});
(0, chai_1.expect)(data.ok).to.be.equals(true);
(0, chai_1.expect)(data.response.data.length).to.be.gte(0);
}));
});
describe("Get User Position", () => {
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
client.addMarket(symbol);
}));
it("should return zero open positions for the user", () => __awaiter(void 0, void 0, void 0, function* () {
// Given
const web3 = new library_1.Web3(network.url);
const wallet = web3.eth.accounts.create();
const clientTemp = new index_1.FireflyClient(true, network, wallet.privateKey);
yield clientTemp.init();
// When
clientTemp.addMarket(symbol);
const response = yield clientTemp.getUserPosition({});
// Then
(0, chai_1.expect)(response.ok).to.be.equal(true);
(0, chai_1.expect)(response.response.data.length).to.be.equal(0);
clientTemp.sockets.close();
}));
it("should get user's BTC-PERP Position", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getUserPosition({
symbol,
});
const position = response.data;
if (Object.keys(position).length > 0) {
(0, chai_1.expect)(response.response.data.symbol).to.be.equal(symbol);
}
}));
it("should get all open positions for the user across all markets", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getUserPosition({});
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
});
describe("Get User Trades", () => {
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
client.addMarket(symbol);
}));
it("should return zero trades for the user", () => __awaiter(void 0, void 0, void 0, function* () {
// Given
const web3 = new library_1.Web3(network.url);
const wallet = web3.eth.accounts.create();
const clientTemp = new index_1.FireflyClient(true, network, wallet.privateKey);
yield clientTemp.init();
// When
clientTemp.addMarket(symbol);
const response = yield clientTemp.getUserTrades({});
// Then
(0, chai_1.expect)(response.ok).to.be.equal(true);
(0, chai_1.expect)(response.response.data.length).to.be.equal(0);
clientTemp.sockets.close();
}));
it("should return zero trades history for the user", () => __awaiter(void 0, void 0, void 0, function* () {
// Given
const web3 = new library_1.Web3(network.url);
const wallet = web3.eth.accounts.create();
const clientTemp = new index_1.FireflyClient(true, network, wallet.privateKey);
yield clientTemp.init();
// When
clientTemp.addMarket(symbol);
const response = yield clientTemp.getUserTradesHistory({});
// Then
(0, chai_1.expect)(response.ok).to.be.equal(true);
(0, chai_1.expect)(response.response.data.data.length).to.be.equal(0);
clientTemp.sockets.close();
}));
it("should get user's BTC-PERP Trades", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getUserTrades({
symbol,
});
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get user's BTC-PERP Trades History", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getUserTradesHistory({
symbol,
});
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
});
describe("Get Market Orderbook", () => {
it(`should get ${symbol} orderbook with best ask and bid`, () => __awaiter(void 0, void 0, void 0, function* () {
var _a, _b;
const response = yield client.getOrderbook({
symbol,
limit: 1,
});
(0, chai_1.expect)(response.ok).to.be.equal(true);
(0, chai_1.expect)((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.limit).to.be.equal(1);
(0, chai_1.expect)((_b = response === null || response === void 0 ? void 0 : response.data) === null || _b === void 0 ? void 0 : _b.symbol).to.be.equal(symbol);
}));
it("should get no orderbook data as market for DOGE-PERP does not exist", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getOrderbook({
symbol: "DODGE-PERP",
limit: 1,
});
(0, chai_1.expect)(response.ok).to.be.equal(false);
}));
});
describe("User History and Account Related Routes", () => __awaiter(void 0, void 0, void 0, function* () {
it("should get User Account Data", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getUserAccountData();
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get Transaction History records for user", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getUserTransactionHistory({
symbol,
pageSize: 2,
pageNumber: 1,
});
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get Funding History records for user", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getUserFundingHistory({
pageSize: 2,
cursor: 1,
});
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it(`should get Funding History records of ${symbol}`, () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getUserFundingHistory({
symbol,
pageSize: 2,
cursor: 1,
});
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get all Transfer History records for user", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getUserTransferHistory({});
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get Transfer History of `Withdraw` records for user", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getUserTransferHistory({
action: "Withdraw",
});
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
}));
describe("Growth Routes", () => __awaiter(void 0, void 0, void 0, function* () {
it("should not generate referral code for non affiliated user", () => __awaiter(void 0, void 0, void 0, function* () {
var _a;
const response = yield client.generateReferralCode({
referralCode: "testReferCode",
campaignId: 2,
});
(0, chai_1.expect)(response.ok).to.be.equal(false);
(0, chai_1.expect)((_a = (response === null || response === void 0 ? void 0 : response.data).error) === null || _a === void 0 ? void 0 : _a.code).to.be.equal(3078);
}));
it("should not link referred user when given incorrect refer code", () => __awaiter(void 0, void 0, void 0, function* () {
var _b;
const response = yield client.affiliateLinkReferredUser({
referralCode: "testReferCode"
});
(0, chai_1.expect)(response.ok).to.be.equal(false);
(0, chai_1.expect)((_b = (response === null || response === void 0 ? void 0 : response.data).error) === null || _b === void 0 ? void 0 : _b.code).to.be.equal(9000);
}));
it("should get referrer info", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getReferrerInfo();
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get campaign details", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getCampaignDetails();
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get campaign rewards", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getCampaignRewards(3);
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get user rewards history", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getUserRewardsHistory();
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get user rewards summary", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getUserRewardsSummary();
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get trade & earn rewards overview", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getTradeAndEarnRewardsOverview(2);
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get trade & earn rewards details", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getTradeAndEarnRewardsDetail({
campaignId: 3,
});
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get trade & earn historical rewards total", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getTotalHistoricalTradingRewards();
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should not get affiliate payouts when user is not an affiliate", () => __awaiter(void 0, void 0, void 0, function* () {
var _c;
const response = yield client.getAffiliatePayouts(1);
(0, chai_1.expect)(response.ok).to.be.equal(false);
(0, chai_1.expect)((_c = (response === null || response === void 0 ? void 0 : response.data).error) === null || _c === void 0 ? void 0 : _c.code).to.be.equal(3078);
}));
it("should not get affiliate referee details when user is not an affiliate", () => __awaiter(void 0, void 0, void 0, function* () {
var _d;
const response = yield client.getAffiliateRefereeDetails({
campaignId: 2,
});
(0, chai_1.expect)(response.ok).to.be.equal(false);
(0, chai_1.expect)((_d = (response === null || response === void 0 ? void 0 : response.data).error) === null || _d === void 0 ? void 0 : _d.code).to.be.equal(3078);
}));
it("should not get referee count when user is not an affiliate", () => __awaiter(void 0, void 0, void 0, function* () {
var _e;
const response = yield client.getAffiliateRefereeCount(2);
(0, chai_1.expect)(response.ok).to.be.equal(false);
(0, chai_1.expect)((_e = (response === null || response === void 0 ? void 0 : response.data).error) === null || _e === void 0 ? void 0 : _e.code).to.be.equal(9000);
}));
}));
it("should get contract address", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getContractAddresses();
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get recent market trades of BTC-PERP Market", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getMarketRecentTrades({
symbol,
});
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get candle stick data", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getMarketCandleStickData({
symbol,
interval: "1m",
});
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get exchange info for BTC Market", () => __awaiter(void 0, void 0, void 0, function* () {
var _f;
const response = yield client.getExchangeInfo(symbol);
(0, chai_1.expect)(response.ok).to.be.equal(true);
(0, chai_1.expect)((_f = response.data) === null || _f === void 0 ? void 0 : _f.symbol).to.be.equal(symbol);
}));
it("should get exchange info for all markets", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getExchangeInfo();
(0, chai_1.expect)(response.ok).to.be.equal(true);
(0, chai_1.expect)(response.response.data.length).to.be.gte(1);
}));
it("should get market data for BTC Market", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getMarketData(symbol);
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get market meta info for BTC Market", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getMarketMetaInfo(symbol);
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get market ticker data for BTC Market", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getTickerData(symbol);
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get master info of all markets", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getMasterInfo();
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it(`should get master info of ${symbol}`, () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getMasterInfo(symbol);
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get market symbols", () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getMarketSymbols();
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it("should get status of exchange to be alive", () => __awaiter(void 0, void 0, void 0, function* () {
var _g;
const response = yield client.getExchangeStatus();
(0, chai_1.expect)(response.ok).to.be.equal(true);
(0, chai_1.expect)((_g = response.data) === null || _g === void 0 ? void 0 : _g.isAlive).to.be.equal(true);
}));
it(`should return funding rate of ${symbol}`, () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.getMarketFundingRate(symbol);
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
it(`should return verification status`, () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield client.verifyDeposit(100);
(0, chai_1.expect)(response.ok).to.be.equal(true);
}));
describe("Sockets", () => {
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
client.sockets.open();
client.addMarket(symbol);
client.sockets.subscribeGlobalUpdatesBySymbol(symbol);
client.sockets.subscribeUserUpdateByToken();
}));
it("should receive an event from candle stick", (done) => {
const callback = (candle) => {
(0, chai_1.expect)(candle[candle.length - 1]).to.be.equal(symbol);
done();
};
client.sockets.onCandleStickUpdate(symbol, "1m", callback);
});
it("should receive an event for orderbook update when an order is placed on exchange", (done) => {
const callback = ({ orderbook }) => {
(0, chai_1.expect)(orderbook.symbol).to.be.equal(symbol);
done();
};
client.sockets.onOrderBookUpdate(callback);
// wait for 1 sec as room might not had been subscribed
(0, promises_1.setTimeout)(1000).then(() => {
client.postOrder({
symbol,
price: sellPrice + 3,
quantity: 0.1,
side: library_1.ORDER_SIDE.SELL,
leverage: defaultLeverage,
orderType: library_1.ORDER_TYPE.LIMIT,
});
});
});
it("should receive an event for ticker update", (done) => {
const callback = (tickerUpdate) => {