@firefly-exchange/firefly-client
Version:
The Firefly Client Library allows traders to sign, create, retrieve and listen to orders on Firefly Exchange.
949 lines • 63.8 kB
JavaScript
"use strict";
/* eslint-disable prettier/prettier */
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());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FireflyClient = void 0;
const ethers_aws_kms_signer_1 = require("ethers-aws-kms-signer");
const ethers_1 = require("ethers");
const library_1 = require("@firefly-exchange/library");
const library_2 = require("@firefly-exchange/library");
const constants_1 = require("./constants");
const apiService_1 = require("./exchange/apiService");
const apiUrls_1 = require("./exchange/apiUrls");
const contractErrorHandling_service_1 = require("./exchange/contractErrorHandling.service");
const contractService_1 = require("./exchange/contractService");
const sockets_1 = require("./exchange/sockets");
// @ts-ignore
const utils_1 = require("../utils/utils");
const WebSocket_1 = require("./exchange/WebSocket");
class FireflyClient {
// ◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢
/**
* initializes the class instance
* @param _isTermAccepted boolean indicating if exchange terms and conditions are accepted
* @param _network containing network rpc url and chain id
* @param _account accepts either privateKey or AWS-KMS-SIGNER object if user intend to sign using kms
*/
constructor(_isTermAccepted, _network, _account) {
this.orderSigners = new Map();
this.marketSymbols = []; // to save array market symbols [DOT-PERP, SOL-PERP]
this.walletAddress = ""; // to save user's public address when connecting from UI
this.signingMethod = library_1.SigningMethod.MetaMaskLatest; // to save signing method when integrating on UI
this.isTermAccepted = false;
this.networkName = library_1.NETWORK_NAME.arbitrum; //arbitrum | boba
this.maxBlockGasLimit = 0;
this.maxSaltLimit = 2 ** 60;
// the number of decimals supported by USDC contract
this.MarginTokenPrecision = 6;
// ◥◤◥◤◥◤◥◤◥◤ Private Contracts Names ◥◤◥◤◥◤◥◤◥◤
this._usdcToken = "USDC";
this._perpetual = "Perpetual";
this._marginBank = "MarginBank";
this._isolatedTrader = "IsolatedTrader";
this.initializeWithKMS = (awsKmsSigner) => __awaiter(this, void 0, void 0, function* () {
try {
this.kmsSigner = awsKmsSigner;
//fetching public address of the account
this.walletAddress = yield this.kmsSigner.getAddress();
}
catch (err) {
console.log(err);
throw Error("Failed to initialize KMS");
}
});
/**
* initializes web3 with the given provider and creates a signer to sign transactions like placing order
* @param _web3Provider provider HttpProvider | IpcProvider | WebsocketProvider | AbstractProvider | string
* @param _signingMethod method to sign transactions with, by default its MetaMaskLatest
*/
this.initializeWithProvider = (_web3Provider, _signingMethod) => __awaiter(this, void 0, void 0, function* () {
this.web3Provider = _web3Provider;
this.web3 = new library_1.Web3(_web3Provider);
const provider = new ethers_1.ethers.providers.Web3Provider(_web3Provider);
this.signer = provider.getSigner();
this.walletAddress = yield this.signer.getAddress();
if (_signingMethod) {
this.signingMethod = _signingMethod;
}
});
/**
* initializes web3 and wallet with the given account private key
* @param _acctPvtKey private key for the account to be used for placing orders
*/
this.initializeWithPrivateKey = (_acctPvtKey) => {
this.web3.eth.accounts.wallet.add(_acctPvtKey);
this.wallet = new ethers_1.Wallet(_acctPvtKey, new ethers_1.providers.StaticJsonRpcProvider(this.network.url));
};
/***
* Set UUID to api headers for colocation partners
*/
this.setUUID = (uuid) => {
this.apiService.setUUID(uuid);
};
/**
* initializes contract addresses & onboards user
*/
this.init = (userOnboarding = true, apiToken = "") => __awaiter(this, void 0, void 0, function* () {
var _a;
// get contract addresses
const addresses = yield this.getContractAddresses();
if (!addresses.ok) {
throw Error("Failed to fetch contract addresses");
}
this.contractAddresses = addresses.data;
if (apiToken) {
this.apiService.setAPIToken(apiToken);
// for socket
this.sockets.setAPIToken(apiToken);
(_a = this.webSockets) === null || _a === void 0 ? void 0 : _a.setAPIToken(apiToken);
}
// onboard user if not onboarded
else if (userOnboarding) {
yield this.userOnBoarding();
}
if (this.network.UUID) {
this.setUUID(this.network.UUID);
}
// fetch gas limit
this.maxBlockGasLimit = (yield this.web3.eth.getBlock("latest")).gasLimit;
// check if Network is arbitrum
this.networkName = this.network.url.includes(constants_1.ARBITRUM_NETWROK)
? library_1.NETWORK_NAME.arbitrum
: library_1.NETWORK_NAME.bobabeam;
});
this.setSubAccount = (publicAddress, market, status) => __awaiter(this, void 0, void 0, function* () {
const perpContract = this.getContract(this._perpetual, undefined, market);
const resp = yield (0, contractService_1.setSubAccount)(perpContract, publicAddress, status, this.getWallet(), this.maxBlockGasLimit, this.networkName);
return resp;
});
/**
* Allows caller to add a market, internally creates order signer for the provided market
* @param symbol Symbol of MARKET in form of DOT-PERP, BTC-PERP etc.
* @param isolatedTraderContract (Optional) address of isolatedTrader contract address for market
* @returns boolean true if market is added else false
*/
this.addMarket = (symbol, isolatedTraderContract) => {
// if signer for market already exists return false
if (this.orderSigners.get(symbol)) {
return false;
}
const contract = this.getContract(this._isolatedTrader, isolatedTraderContract, symbol);
this.orderSigners.set(symbol, new library_1.OrderSigner(this.web3, Number(this.network.chainId), contract.address));
return true;
};
/**
* Removes the provided symbol market order signer and also unsubsribes socket from it
* @param market symbol of the market to be removed
* @returns boolean true if market is removed false other wise
*/
this.removeMarket = (market) => {
this.sockets.unsubscribeGlobalUpdatesBySymbol(market);
return this.orderSigners.delete(market);
};
/**
* Returns the USDC balance of user in USDC contract
* @param contract (optional) address of USDC contract
* @returns Number representing balance of user in USDC contract
*/
this.getUSDCBalance = (contract) => __awaiter(this, void 0, void 0, function* () {
const tokenContract = this.getContract(this._usdcToken, contract);
const balance = yield tokenContract
.connect(this.getWallet())
.balanceOf(this.getPublicAddress());
return (0, library_1.bnStrToBaseNumber)((0, library_1.bnToString)(balance.toHexString()), this.MarginTokenPrecision);
});
/**
* Returns the usdc Balance(Free Collateral) of the account in Margin Bank contract
* @param contract (optional) address of Margin Bank contract
* @returns Number representing balance of user in Margin Bank contract
*/
this.getMarginBankBalance = (contract) => __awaiter(this, void 0, void 0, function* () {
const marginBankContract = this.getContract(this._marginBank, contract);
const mbContract = (0, library_1.mapContract)(this.networkName, library_1.FactoryName.marginBank, marginBankContract);
const balance = yield mbContract
.connect(this.getWallet())
.getAccountBankBalance(this.getPublicAddress());
const balanceNumber = (0, library_1.bnStrToBaseNumber)((0, library_1.bnToString)(balance.toHexString()));
return Math.floor(balanceNumber * 1000000) / 1000000; // making balance returned always in 6 precision
});
/**
* Faucet function, mints 10K USDC to wallet - Only works on Testnet
* Assumes that the user wallet has native gas Tokens on Testnet
* @param contract (optional) address of USDC contract
* @returns Boolean true if user is funded, false otherwise
*/
this.mintTestUSDC = (contract) => __awaiter(this, void 0, void 0, function* () {
if (this.network === constants_1.Networks.PRODUCTION_ARBITRUM) {
throw Error(`Function does not work on PRODUCTION`);
}
const amountString = (0, library_1.toBigNumberStr)(10000, this.MarginTokenPrecision);
const contractAdd = this.getContract(this._usdcToken, contract);
const tokenContract = contractAdd.connect(this.getWallet());
let gasLimit = this.maxBlockGasLimit;
if (this.networkName == library_1.NETWORK_NAME.arbitrum) {
gasLimit =
+(yield tokenContract.estimateGas.approve(this.getPublicAddress(), amountString)) + constants_1.EXTRA_FEES;
}
// mint 10K usdc token
yield (yield tokenContract.mint(this.getPublicAddress(), amountString, {
gasLimit: gasLimit,
})).wait();
return true;
});
/**
* Returns Native token balance in user's account
* @returns Number representing native token balance in account
*/
this.getChainNativeBalance = () => __awaiter(this, void 0, void 0, function* () {
return (0, library_1.bnStrToBaseNumber)((0, library_1.bnToString)((yield this.getWallet().getBalance()).toHexString()));
});
/**
* Transfers usdc to margin bank to be used for placing orders and opening
* positions on Firefly Exchange
* @param amount the number of usdc to be transferred
* @param usdcContract (optional) address of usdc contract
* @param mbContract (address) address of Margin Bank contract
* @returns ResponseSchema
*/
this.depositToMarginBank = (amount, usdcContract, mbContract) => __awaiter(this, void 0, void 0, function* () {
const tokenContract = this.getContract(this._usdcToken, usdcContract);
const marginBankContract = this.getContract(this._marginBank, mbContract);
return yield (0, contractService_1.depositToMarginBankContractCall)(tokenContract, marginBankContract, amount, this.MarginTokenPrecision, this.getWallet(), this.maxBlockGasLimit, this.networkName, this.getPublicAddress);
});
/**
* Approves margin to deposit form USDC contract
* @param amount the number of usdc to approve
* @param usdcContract (optional) address of usdc contract
* @param mbContract (address) address of Margin Bank contract
* @returns ResponseSchema
*/
this.approvalFromUSDC = (amount, usdcContract, mbContract) => __awaiter(this, void 0, void 0, function* () {
const tokenContract = this.getContract(this._usdcToken, usdcContract);
const marginBankContract = this.getContract(this._marginBank, mbContract);
//verify the user address via chainalysis
const apiResponse = yield this.verifyDeposit(amount);
if (apiResponse.status > 300) {
const response = {
ok: apiResponse.ok,
data: apiResponse.response.data,
message: apiResponse.response.message,
code: apiResponse.status,
};
return response;
}
if (apiResponse.response.data.verificationStatus &&
apiResponse.response.data.verificationStatus.toLowerCase() !=
contractErrorHandling_service_1.VerificationStatus.Success) {
apiResponse.ok = false;
apiResponse.status = 5001;
apiResponse.response.message = contractErrorHandling_service_1.APIErrorMessages.restrictedUser;
return this.apiService.transformAPItoResponseSchema(apiResponse);
}
// approve usdc contract to allow margin bank to take funds out for user's behalf
return (0, contractService_1.approvalFromUSDCContractCall)(tokenContract, marginBankContract, amount, this.MarginTokenPrecision, this.getWallet(), this.maxBlockGasLimit, this.networkName);
});
/**
* Transfers usdc from MarginBank, back to usdc contract
* @param amount (optional) if not provided, transfers all available usdc tokens
* from Margin Bank to usdc contract
* @param mbContract (address) address of Margin Bank contract
* @returns boolean true if funds are withdrawn, false otherwise
*/
this.withdrawFromMarginBank = (amount, mbContract) => __awaiter(this, void 0, void 0, function* () {
const marginBankContract = this.getContract(this._marginBank, mbContract);
return yield (0, contractService_1.withdrawFromMarginBankContractCall)(marginBankContract, this.MarginTokenPrecision, this.getWallet(), this.maxBlockGasLimit, this.networkName, this.getMarginBankBalance, this.getPublicAddress, amount);
});
/**
* @notice Withdraw the number of margin tokens equal to the value of the account at the time
* perpetual was delisted. A position can only be closed once.
* @param symbol market on which to close position
* @param perpContract (optional) address of perpetual contract
* @returns boolean true if position is closed, false otherwise
*/
this.closePosition = (symbol, perpContract) => __awaiter(this, void 0, void 0, function* () {
const contract = this.getContract(this._perpetual, perpContract, symbol);
return yield (0, contractService_1.closePositionCall)(contract, this.getWallet(), this.maxBlockGasLimit, this.networkName, this.getPublicAddress);
});
/**
* Gets balance of position open
* @param symbol market symbol get information about
* @param perpContract (address) address of Perpetual address comes in metaInfo
* @returns balance of positions of given symbol
*/
this.getAccountPositionBalance = (symbol, perpContract) => __awaiter(this, void 0, void 0, function* () {
const contract = this.getContract(this._perpetual, perpContract, symbol);
return contract
.connect(this.getWallet())
.getAccountBalance(this.getPublicAddress());
});
/**
* Creates order signature and returns it. The signed order can be placed on exchange
* @param params OrderSignatureRequest params needed to be signed
* @returns OrderSignatureResponse with the payload signed on-chain along with order signature
*/
this.createSignedOrder = (params) => __awaiter(this, void 0, void 0, function* () {
const order = this.createOrderToSign(params, params.maker);
const signer = this.orderSigners.get(params.symbol);
if (!signer) {
throw Error(`Provided Market Symbol(${params.symbol}) is not added to client library`);
}
let orderSignature;
if (this.kmsSigner !== undefined) {
const orderHash = signer.getOrderHash(order);
/*
For every orderHash sent to etherium etherium will hash it and wrap
it with "\\x19Ethereum Signed Message:\\n" + message.length + message
Hence for that we have to hash it again.
*/
const orderEthHash = this.web3.eth.accounts.hashMessage(orderHash);
const signedMessage = yield this.kmsSigner._signDigest(orderEthHash);
// This just adds 01 at the end of the message if we pass 1
orderSignature = (0, library_2.createTypedSignature)(signedMessage, 1);
}
else {
orderSignature = yield signer.signOrder(order, this.getSigningMethod(), this.getPublicAddress());
}
const signedOrder = Object.assign(Object.assign({}, order), { typedSignature: orderSignature });
return {
symbol: params.symbol,
price: params.price,
quantity: params.quantity,
side: params.side,
leverage: params.leverage || 1,
reduceOnly: order.reduceOnly,
salt: order.salt.toNumber(),
expiration: order.expiration.toNumber(),
orderSignature: signedOrder.typedSignature,
orderType: params.orderType,
maker: params.maker
? params.maker
: this.getPublicAddress().toLocaleLowerCase(),
triggerPrice: (0, library_1.isStopOrder)(params.orderType) ? params.triggerPrice : 0,
};
});
/**
* Places a signed order on firefly exchange
* @param params PlaceOrderRequest containing the signed order created using createSignedOrder
* @returns PlaceOrderResponse containing status and data. If status is not 201, order placement failed.
*/
this.placeSignedOrder = (params) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.post(apiUrls_1.SERVICE_URLS.ORDERS.ORDERS, {
symbol: params.symbol,
userAddress: params.maker,
orderType: params.orderType,
price: (0, library_1.toBigNumberStr)(params.price),
triggerPrice: (0, library_1.toBigNumberStr)(params.triggerPrice || "0"),
quantity: (0, library_1.toBigNumberStr)(params.quantity),
leverage: (0, library_1.toBigNumberStr)(params.leverage),
side: params.side,
reduceOnly: params.reduceOnly,
salt: params.salt,
expiration: params.expiration,
orderSignature: params.orderSignature,
timeInForce: params.timeInForce || library_1.TIME_IN_FORCE.GOOD_TILL_TIME,
postOnly: params.postOnly == true,
cancelOnRevert: params.cancelOnRevert == true,
clientId: params.clientId
? `firefly-client: ${params.clientId}`
: "firefly-client",
}, { isAuthenticationRequired: true });
return response;
});
/**
* Given an order payload, signs it on chain and submits to exchange for placement
* @param params PostOrderRequest
* @returns PlaceOrderResponse
*/
this.postOrder = (params) => __awaiter(this, void 0, void 0, function* () {
const signedOrder = yield this.createSignedOrder(params);
const response = yield this.placeSignedOrder(Object.assign(Object.assign({}, signedOrder), { timeInForce: params.timeInForce, postOnly: params.postOnly, cancelOnRevert: params.cancelOnRevert, clientId: params.clientId }));
return response;
});
/**
* Verifies if the order
* @param params OrderSignatureResponse
* @returns boolean indicating if order signature is valid
*/
this.verifyOrderSignature = (params) => {
const signedOrder = {
isBuy: params.side === library_1.ORDER_SIDE.BUY,
reduceOnly: params.reduceOnly,
quantity: (0, library_1.toBigNumber)(params.quantity),
price: (0, library_1.toBigNumber)(params.price),
triggerPrice: (0, library_1.isStopOrder)(params.orderType)
? (0, library_1.toBigNumber)(params.triggerPrice || "0")
: (0, library_1.toBigNumber)(0),
leverage: (0, library_1.toBigNumber)(params.leverage),
maker: this.getPublicAddress().toLocaleLowerCase(),
expiration: (0, library_1.bigNumber)(params.expiration),
salt: (0, library_1.bigNumber)(params.salt),
typedSignature: params.orderSignature,
};
const signer = this.orderSigners.get(params.symbol);
if (!signer) {
throw Error(`Provided Market Symbol(${params.symbol}) is not added to client library`);
}
return signer.orderHasValidSignature(signedOrder);
};
/**
* Creates signature for cancelling orders
* @param params OrderCancelSignatureRequest containing market symbol and order hashes to be cancelled
* @returns generated signature string
*/
this.createOrderCancellationSignature = (params) => __awaiter(this, void 0, void 0, function* () {
const signer = this.orderSigners.get(params.symbol);
if (!signer) {
throw Error(`Provided Market Symbol(${params.symbol}) is not added to client library`);
}
return signer.signCancelOrdersByHash(params.hashes, this.getPublicAddress().toLowerCase(), this.getSigningMethod());
});
/**
* Posts to exchange for cancellation of provided orders with signature
* @param params OrderCancellationRequest containing order hashes to be cancelled and cancellation signature
* @returns response from exchange server
*/
this.placeCancelOrder = (params) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.delete(apiUrls_1.SERVICE_URLS.ORDERS.ORDERS_HASH, {
symbol: params.symbol,
orderHashes: params.hashes,
cancelSignature: params.signature,
parentAddress: params.parentAddress,
}, { isAuthenticationRequired: true });
return response;
});
/**
* Creates signature and posts order for cancellation on exchange of provided orders
* @param params OrderCancelSignatureRequest containing order hashes to be cancelled
* @returns response from exchange server
*/
this.postCancelOrder = (params) => __awaiter(this, void 0, void 0, function* () {
if (params.hashes.length <= 0) {
throw Error(`No orders to cancel`);
}
const signature = yield this.createOrderCancellationSignature(params);
const response = yield this.placeCancelOrder(Object.assign(Object.assign({}, params), { signature }));
return response;
});
/**
* Cancels all open orders for a given market
* @param symbol DOT-PERP, market symbol
* @returns cancellation response
*/
this.cancelAllOpenOrders = (symbol, parentAddress) => __awaiter(this, void 0, void 0, function* () {
var _b;
const openOrders = yield this.getUserOrders({
symbol,
statuses: [
library_1.ORDER_STATUS.OPEN,
library_1.ORDER_STATUS.PARTIAL_FILLED,
library_1.ORDER_STATUS.PENDING,
],
parentAddress,
});
const hashes = (_b = openOrders.data) === null || _b === void 0 ? void 0 : _b.map((order) => order.hash);
const response = yield this.postCancelOrder({
hashes,
symbol,
parentAddress,
});
return response;
});
/**
* Updates user's leverage to given leverage
* @param adjustLeverageRequest
* @returns ResponseSchema
*/
this.adjustLeverage = (params) => __awaiter(this, void 0, void 0, function* () {
const userPosition = yield this.getUserPosition({
symbol: params.symbol,
parentAddress: params.parentAddress,
});
if (!userPosition.data) {
throw Error(`User positions data doesn't exist`);
}
const position = userPosition.data;
// if user position exists, make contract call
if (Object.keys(position).length > 0) {
// TODO [BFLY-603]: this should be returned as array from dapi, remove this typecasting when done
const perpContract = this.getContract(this._perpetual, params.perpetualAddress, params.symbol);
//Adjust leverage V2 implementation only works on Wallet
//Create signed tx to pass to api call
if (this.getWallet() instanceof ethers_1.Wallet) {
const signedTx = yield (0, contractService_1.adjustLeverageContractCallRawTransaction)(perpContract, this.getWallet(), params.leverage, this.maxBlockGasLimit, this.networkName, params.parentAddress
? () => {
return params.parentAddress;
}
: this.getPublicAddress);
// call API to update leverage
const { ok, data, response: { errorCode, message }, } = yield this.updateLeverage({
symbol: params.symbol,
leverage: params.leverage,
parentAddress: params.parentAddress,
signedTransaction: signedTx,
});
const response = { ok, data, code: errorCode, message };
//If API is successful return response else make direct contract call to update the leverage
if (response.ok) {
return response;
}
}
return yield (0, contractService_1.adjustLeverageContractCall)(perpContract, this.getWallet(), params.leverage, this.maxBlockGasLimit, this.networkName, params.parentAddress
? () => {
return params.parentAddress;
}
: this.getPublicAddress);
}
// call API to update leverage
const { ok, data, response: { errorCode, message }, } = yield this.updateLeverage({
symbol: params.symbol,
leverage: params.leverage,
parentAddress: params.parentAddress,
});
const response = { ok, data, code: errorCode, message };
return response;
});
/**
* Gets Users default leverage.
* @param symbol market symbol get information about
* @returns user default leverage
*/
this.getUserDefaultLeverage = (symbol, parentAddress) => __awaiter(this, void 0, void 0, function* () {
const accData = yield this.getUserAccountData(parentAddress);
if (!accData.data) {
throw Error(`Account data does not exist`);
}
const accDataByMarket = accData.data.accountDataByMarket.filter((data) => {
return data.symbol === symbol;
});
/// found accountDataByMarket
if (accDataByMarket && accDataByMarket.length > 0) {
return (0, library_1.bnStrToBaseNumber)(accDataByMarket[0].selectedLeverage);
}
/// user is new and symbol data is not present in accountDataByMarket
const exchangeInfo = yield this.getExchangeInfo(symbol);
if (!exchangeInfo.data) {
throw Error(`Provided Market Symbol(${symbol}) does not exist`);
}
return (0, library_1.bnStrToBaseNumber)(exchangeInfo.data.defaultLeverage);
});
/**
* Add or remove margin from the open position
* @param symbol market symbol of the open position
* @param operationType operation you want to perform `Add` | `Remove` margin
* @param amount (number) amount user wants to add or remove from the position
* @param perpetualAddress (address) address of Perpetual contract
* @returns ResponseSchema
*/
this.adjustMargin = (symbol, operationType, amount, perpetualAddress) => __awaiter(this, void 0, void 0, function* () {
const perpContract = this.getContract(this._perpetual, perpetualAddress, symbol);
return yield (0, contractService_1.adjustMarginContractCall)(operationType, perpContract, this.getWallet(), amount, this.maxBlockGasLimit, this.networkName, this.getPublicAddress);
});
/**
* Generate and receive readOnlyToken, this can only be accessed at the time of generation
* @returns readOnlyToken string
*/
this.generateReadOnlyToken = () => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.post(apiUrls_1.SERVICE_URLS.USER.GENERATE_READONLY_TOKEN, {}, { isAuthenticationRequired: true });
return response;
});
/**
* Gets Orders placed by the user. Returns the first 50 orders by default.
* @param params of type OrderRequest,
* @returns OrderResponse array
*/
this.getUserOrders = (params) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.USER.ORDERS, Object.assign({}, params), { isAuthenticationRequired: true });
return response;
});
/**
* Gets Orders by type and statuses. Returns the first 50 orders by default.
* @param params of type OrderByTypeRequest,
* @returns OrderResponse array
*/
this.getUserOrdersByType = (params) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.USER.ORDERS_BY_TYPE, Object.assign({}, params), { isAuthenticationRequired: true });
return response;
});
/**
* Gets user open position. If the market is not specified then will return first 50 open positions for 50 markets.
* @param params GetPositionRequest
* @returns GetPositionResponse
*/
this.getUserPosition = (params) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.USER.USER_POSITIONS, Object.assign({}, params), { isAuthenticationRequired: true });
return response;
});
/**
* Gets state of orderbook for provided market. At max top 50 bids/asks are retrievable
* @param params GetOrdebookRequest
* @returns GetOrderbookResponse
*/
this.getOrderbook = (params) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.MARKET.ORDER_BOOK, params);
return response;
});
/**
* Gets user trades
* @param params PlaceOrderResponse
* @returns GetUserTradesResponse
*/
this.getUserTrades = (params) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.USER.USER_TRADES, Object.assign({}, params), { isAuthenticationRequired: true });
return response;
});
/**
* Gets user trades
* @param params PlaceOrderResponse
* @returns GetUserTradesHistoryResponse
*/
this.getUserTradesHistory = (params) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.USER.USER_TRADES_HISTORY, Object.assign({}, params), { isAuthenticationRequired: true });
return response;
});
/**
* Gets user Account Data
* @returns GetAccountDataResponse
*/
this.getUserAccountData = (parentAddress) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.USER.ACCOUNT, { parentAddress }, { isAuthenticationRequired: true });
return response;
});
/**
* Gets verification status of user account
* @param amount deposit amount
* @returns verification status of user
*/
this.verifyDeposit = (amount) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.USER.VERIFY_DEPOSIT, { depositAmount: amount }, { isAuthenticationRequired: true });
return response;
});
/**
* Gets user transaction history
* @param params GetTransactionHistoryRequest
* @returns GetUserTransactionHistoryResponse
*/
this.getUserTransactionHistory = (params) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.USER.USER_TRANSACTION_HISTORY, Object.assign({}, params), { isAuthenticationRequired: true });
return response;
});
/**
* Gets user funding history
* @param params GetFundingHistoryRequest
* @returns GetUserTransactionHistoryResponse
*/
this.getUserFundingHistory = (params) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.USER.FUNDING_HISTORY, Object.assign({}, params), { isAuthenticationRequired: true });
return response;
});
/**
* Gets user transfer history
* @param params GetTransferHistoryRequest
* @returns GetUserTransferHistoryResponse
*/
this.getUserTransferHistory = (params) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.USER.TRANSFER_HISTORY, Object.assign({}, params), { isAuthenticationRequired: true });
return response;
});
/**
* Gets market funding rate
* @param symbol market symbol to fetch funding rate of
* @returns GetFundingRateResponse
*/
this.getMarketFundingRate = (symbol) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.MARKET.FUNDING_RATE, {
symbol,
});
return response;
});
/**
* Gets market recent trades
* @param params GetMarketRecentTradesRequest
* @returns GetMarketRecentTradesResponse
*/
this.getMarketRecentTrades = (params) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.MARKET.RECENT_TRADE, params);
return response;
});
/**
* Gets market candle stick data
* @param params GetMarketRecentTradesRequest
* @returns DAPIKlineResponse
*/
this.getMarketCandleStickData = (params) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.MARKET.CANDLE_STICK_DATA, params);
return response;
});
/**
* Gets publically available market info about market(s)
* @param symbol (optional) market symbol get information about, by default fetches info on all available markets
* @returns ExchangeInfo or ExchangeInfo[] in case no market was provided as input
*/
this.getExchangeInfo = (symbol) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.MARKET.EXCHANGE_INFO, { symbol });
return response;
});
/**
* Gets MarketData data for market(s)
* @param symbol (optional) market symbol get information about, by default fetches info on all available markets
* @returns MarketData or MarketData[] in case no market was provided as input
*/
this.getMarketData = (symbol) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.MARKET.MARKET_DATA, { symbol });
return response;
});
/**
* Gets Meta data of the market(s)
* @param symbol (optional) market symbol get information about, by default fetches info on all available markets
* @returns MarketMeta or MarketMeta[] in case no market was provided as input
*/
this.getMarketMetaInfo = (symbol) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.MARKET.META, { symbol });
return response;
});
/**
* Gets Master Info of the market(s)
* @param symbol (optional) market symbol get information about, by default fetches info on all available markets
* @returns MasterInfo
*/
this.getMasterInfo = (symbol) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.MARKET.MASTER_INFO, { symbol });
return response;
});
/**
* Gets the list of market symbols available on exchange
* @returns array of strings representing MARKET SYMBOLS
*/
this.getMarketSymbols = () => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.MARKET.SYMBOLS);
return response;
});
/**
* Gets contract addresses of market
* @param symbol (optional) market symbol get information about, by default fetches info on all available markets
* @returns deployed contract addresses
*/
this.getContractAddresses = (symbol) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.MARKET.CONTRACT_ADDRESSES, { symbol });
return response;
});
/**
* Gets status of the exchange
* @returns StatusResponse
*/
this.getExchangeStatus = () => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.MARKET.STATUS);
return response;
});
/**
* Gets ticker data of any market
* @param symbol market symbol to get information about, if not provided fetches data of all markets
* @returns TickerData
*/
this.getTickerData = (symbol) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.MARKET.TICKER, { symbol });
return response;
});
/**
* Returns the public address of account connected with the client
* @returns string | address
*/
this.getPublicAddress = () => {
const address = this.wallet ? this.wallet.address : this.walletAddress;
if (address === "") {
throw Error(`Invalid user address`);
}
return address;
};
/**
* Creates message to be signed, creates signature and authorize it from dapi
* @returns auth token
*/
this.userOnBoarding = (token) => __awaiter(this, void 0, void 0, function* () {
var _c;
let userAuthToken = token;
if (!userAuthToken) {
let signature;
if (this.kmsSigner !== undefined) {
const hashedMessageSHA = this.web3.utils.sha3(this.network.onboardingUrl);
/*
For every orderHash sent to etherium, etherium will hash it and wrap
it with "\\x19Ethereum Signed Message:\\n" + message.length + message
Hence for that we have to hash it again.
*/
//@ts-ignore
const hashedMessageETH = this.web3.eth.accounts.hashMessage(hashedMessageSHA || "");
signature = yield this.kmsSigner._signDigest(hashedMessageETH);
}
else {
// sign onboarding message
signature = yield library_1.OnboardingSigner.createOnboardSignature(this.network.onboardingUrl, this.wallet ? this.wallet.privateKey : undefined, this.web3Provider);
}
// authorize signature created by dAPI
const authTokenResponse = yield this.authorizeSignedHash(signature);
if (!authTokenResponse.ok || !authTokenResponse.data) {
throw Error(`Authorization error: ${authTokenResponse.response.message}`);
}
userAuthToken = authTokenResponse.data.token;
}
// for api
this.apiService.setAuthToken(userAuthToken);
// this.apiService.setWalletAddress(this.getPublicAddress());
// for socket
this.sockets.setAuthToken(userAuthToken);
(_c = this.webSockets) === null || _c === void 0 ? void 0 : _c.setAuthToken(userAuthToken);
// TODO: remove this when all endpoints on frontend are integrated from client library
return userAuthToken;
});
/**
* Reset timer for cancel on disconnect for open orders
* @param params PostTimerAttributes containing the countdowns of all markets
* @returns PostTimerResponse containing accepted and failed countdowns. If status is not 201, request wasn't successful.
*/
this.resetCancelOnDisconnectTimer = (params) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.post(apiUrls_1.SERVICE_URLS.USER.CANCEL_ON_DISCONNECT, params, { isAuthenticationRequired: true }, this.network.dmsURL);
if (response.status == 503) {
throw Error(`Cancel on Disconnect (dead-mans-switch) feature is currently unavailable`);
}
return response;
});
/**
* Gets user Cancel on Disconnect timer
* @returns GetCountDownsResponse
*/
this.getCancelOnDisconnectTimer = (symbol, parentAddress) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.USER.CANCEL_ON_DISCONNECT, {
parentAddress,
symbol,
}, { isAuthenticationRequired: true }, this.network.dmsURL);
if (response.status == 503) {
throw Error(`Cancel on Disconnect (dead-mans-switch) feature is currently unavailable`);
}
return response;
});
/**
* Generates referral code
* @param params GenerateReferralCodeRequest
* @returns GenerateReferralCodeResponse
*/
this.generateReferralCode = (params) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.post(apiUrls_1.SERVICE_URLS.GROWTH.GENERATE_CODE, params, { isAuthenticationRequired: true });
return response;
});
/**
* Links referred user
* @param params LinkReferredUserRequest
* @returns LinkReferredUserResponse
*/
this.affiliateLinkReferredUser = (params) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.post(apiUrls_1.SERVICE_URLS.GROWTH.AFFILIATE_LINK_REFERRED_USER, params, { isAuthenticationRequired: true });
return response;
});
/**
* Gets referrer Info
* @param parentAddress
* @returns GetReferrerInfoResponse
*/
this.getReferrerInfo = (parentAddress) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.GROWTH.REFERRER_INFO, { parentAddress }, { isAuthenticationRequired: true });
return response;
});
/**
* Gets campaign details
* @returns Array of GetCampaignDetailsResponse
*/
this.getCampaignDetails = () => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.GROWTH.CAMPAIGN_DETAILS);
return response;
});
/**
* Gets campaign reward details
* @param campaignId
* @param parentAddress
* @returns GetCampaignRewardsResponse
*/
this.getCampaignRewards = (campaignId, parentAddress) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.GROWTH.CAMPAIGN_REWARDS, { campaignId, parentAddress }, { isAuthenticationRequired: true });
return response;
});
//Open referral Program
/**
* get open referral referee details
* @param payload
* @returns OpenReferralRefereeDetails
*/
this.getOpenReferralRefereeDetails = (payload) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.GROWTH.OPEN_REFERRAL_REFEREE_DETAILS, payload, {
isAuthenticationRequired: true,
});
return response;
});
/**
* get open referral payouts
* @param payload
* @returns OpenReferralDetails
*/
this.getOpenReferralDetails = (payload) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.GROWTH.OPEN_REFERRAL_REFEREES_COUNT, payload, { isAuthenticationRequired: true });
return response;
});
/**
* get open referral payouts
* @param payload
* @returns OpenReferralPayoutList
*/
this.getOpenReferralPayouts = (payload) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.GROWTH.OPEN_REFERRAL_PAYOUTS, payload, {
isAuthenticationRequired: true,
});
return response;
});
/**
* generate open referral code
* @param campaignId
* @param parentAddress
* @returns OpenReferralOverview
*/
this.generateOpenReferralReferralCode = (payload) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.post(apiUrls_1.SERVICE_URLS.GROWTH.OPEN_REFERRAL_GENERATE_CODE, payload, {
isAuthenticationRequired: true,
});
return response;
});
/**
* get open referral overview
* @returns OpenReferralOverview
*/
this.getOpenReferralOverview = (parentAddress) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.get(apiUrls_1.SERVICE_URLS.GROWTH.OPEN_REFERRAL_OVERVIEW, { parentAddress }, {
isAuthenticationRequired: true,
});
return response;
});
/**
* Link open referral
* @param referralCode
* @returns boolean
*/
this.openReferralLinkReferredUser = (payload) => __awaiter(this, void 0, void 0, function* () {
const response = yield this.apiService.post(apiUrls_1.SERVICE_URLS.GROWTH.OPEN_REFERRAL_LINK_REFERRED_USER, payload, {
isAuthenticationRequired: true,
});
return response;
});
//Open referral Program
/**
* Gets affiliate payout details
* @param campaignId
* @param parentAddress
* @returns Array of GetAffiliatePayoutsResponse
*/
this.getAffiliatePayouts = (campaignId, parentAddress) => __awaiter(this, void 0, void 0, function* () {
const response = yield thi