cryptomarket
Version:
The CryptoMarket for Node.js
448 lines (402 loc) • 10.9 kB
text/typescript
import { Fee, Report } from "../lib/models";
export const timeout = (ms: number) => {
return new Promise((resolve) => setTimeout(resolve, ms));
};
export const SECOND = 1000;
// defined checks if a key is present in a dict, and if its value is str, checks if its defined.
// return false when the key is not present or when the value is an empty string, return true otherwise.
export function defined(anObject: { [x: string]: any }, key: string) {
if (!(key in anObject)) return false;
const val = anObject[key];
if ((typeof val === "string" || val instanceof String) && val === "")
return false;
return true;
}
// goodObject checks all of the values in the fields list to be present in the dict, and if they are
// present, check the defined() condition to be true. if any of the fields fails to be defined(), then
// this function returns false
export function goodObject(anObject: any, fields: string[]) {
if (!anObject) return false;
if (!(typeof anObject === "object" || anObject instanceof Object))
return false;
for (const field of fields) {
if (!defined(anObject, field)) return false;
}
return true;
}
export function emptyList(list: any[]) {
return list.length == 0;
}
export function listSize(list: string | any[], size: any) {
return list.length == size;
}
export function goodList(
checkFn: { (trade: any): boolean; (arg0: any): any },
list: any
) {
for (const elem of list) {
if (!checkFn(elem)) return false;
}
return true;
}
export function emptyDict(dict: {}) {
return Object.keys(dict).length == 0;
}
export function dictSize(dict: {}, size: number) {
return Object.keys(dict).length == size;
}
export function goodDict(checkFn: (arg0: any) => any, dict: { [x: string]: any }) {
for (const key in dict) {
if (!checkFn(dict[key])) return false;
}
return true;
}
// goodCurrency checks the precence of every field in the currency dict
export function goodCurrency(currency: { [x: string]: any }) {
let good = goodObject(currency, [
"fullName",
"payinEnabled",
"payoutEnabled",
"transferEnabled",
"precisionTransfer",
// "accountTopOrder", // Optional
"networks",
]);
if (!good) {
return false;
}
for (const network of currency["networks"]) {
if (!goodNetwork(network)) {
return false;
}
}
return true;
}
export function goodNetwork(network: any) {
return goodObject(network, [
"network",
"default",
"payinEnabled",
"payoutEnabled",
"precisionPayout",
"payoutFee",
"payoutIsPaymentId",
"payinPaymentId",
"payinConfirmations",
]);
}
// goodSymbol check the precence of every field in the symbol dict
export function goodSymbol(symbol: any) {
return goodObject(symbol, [
"type",
"baseCurrency",
"quoteCurrency",
"status",
"quantityIncrement",
"tickSize",
"takeRate",
"makeRate",
"feeCurrency",
// "marginTrading",
// "maxInitialLeverage",
]);
}
// goodTicker check the precence of every field in the ticker dict
export function goodTicker(ticker: any) {
return goodObject(ticker, [
"ask",
"bid",
"last",
"low",
"high",
"open",
"volume",
"volumeQuote",
"timestamp",
]);
}
export function goodPrice(price: any) {
return goodObject(price, ["currency", "price", "timestamp"]);
}
export function goodTickerPrice(price: any) {
return goodObject(price, ["price", "timestamp"]);
}
export function goodPriceHistory(priceHistory: { [x: string]: any }) {
let good = goodObject(priceHistory, ["currency", "history"]);
if (!good) return false;
for (const point of priceHistory["history"]) {
if (!goodHistoryPoint(point)) return false;
}
return true;
}
export function goodHistoryPoint(point: any) {
return goodObject(point, ["timestamp", "open", "close", "min", "max"]);
}
// goodPublicTrade check the precence of every field in the trade dict
export function goodPublicTrade(trade: any) {
return goodObject(trade, ["id", "price", "qty", "side", "timestamp"]);
}
// goodPublicTrade check the precence of every field in the trade dict
export function goodWSTrade(trade: any) {
return goodObject(trade, ["timestamp", "id", "price", "quantity", "side"]);
}
// goodPublicTrade check the precence of every field in the trade dict
export function goodWSCandle(candle: any) {
return goodObject(candle, ["timestamp", "openPrice", "closePrice", "highPrice", "lowPrice", "baseVolume", "quoteVolume"]);
}
// goodPublicTrade check the precence of every field in the trade dict
export function goodWSTicker(ticker: any) {
return goodObject(ticker, [
"timestamp",
"bestAsk",
"bestAskQuantity",
"bestBid",
"bestBidQuantity",
"closePrice",
"openPrice",
"highPrice",
"lowPrice",
"baseVolume",
"quoteVolume",
"priceChange",
"PriceChangePercent",
"lastTradeId"]);
}
export function goodWSOrderbook(orderbook: any) {
const goodOrderbook = goodObject(orderbook, [
"timestamp",
"sequence",
"asks",
"bids"]);
if (!goodOrderbook) return false;
for (const level of orderbook["asks"]) {
if (!goodOrderbookLevel(level)) return false;
}
for (const level of orderbook["bids"]) {
if (!goodOrderbookLevel(level)) return false;
}
return true;
}
// goodPublicTrade check the precence of every field in the trade dict
export function goodWSOrderbookTop(orderbookTop: any) {
return goodObject(orderbookTop, [
"timestamp",
"bestAsk",
"bestAskQuantity",
"bestBid",
"bestBidQuantity",]);
}
// goodOrderbookLevel check the precence of every field in the level dict
export function goodOrderbookLevel(level: string | any[]) {
return level.length == 2;
}
// goodOrderbook check the precence of every field in the orderbook dict
// and the fields of each level in each side of the orderbook
export function goodOrderbook(orderbook: { [x: string]: any }) {
const goodOrderbook = goodObject(orderbook, ["timestamp", "ask", "bid"]);
if (!goodOrderbook) return false;
for (const level of orderbook["ask"]) {
if (!goodOrderbookLevel(level)) return false;
}
for (const level of orderbook["bid"]) {
if (!goodOrderbookLevel(level)) return false;
}
return true;
}
// goodCandle check the precence of every field in the candle dict
export function goodCandle(candle: any) {
return goodObject(candle, [
"timestamp",
"open",
"close",
"min",
"max",
"volume",
"volumeQuote",
]);
}
// goodBalance check the precence of every field on every balance dict
export function goodBalance(balance: any) {
return goodObject(balance, [
"currency",
"available",
"reserved",
// "reservedMargin" optional.
]);
}
// goodOrder check the precence of every field in the order dict
export function goodOrder(order: { [x: string]: any }) {
let good = goodObject(order, [
"id",
"clientOrderId",
"symbol",
"side",
"status",
"type",
"timeInForce",
"quantity",
"quantityCumulative",
// "price", // optional
// "stotPrice", // optional
// "expireTime", // optional
// "originalClientOrderId", // optional
"createdAt",
"updatedAt",
// "trades", // optional. List of trades
]);
if (!good) return false;
if ("trades" in order) {
return goodList(goodTradeOfOrder, order["trades"]);
}
return true;
}
// goodTradeOfOrder checks orders that are part of an order model.
export function goodTradeOfOrder(trade: any) {
return goodObject(trade, [
"id",
"quantity",
"price",
"fee",
"timestamp",
"taker",
]);
}
// goodTrade check the precence of every field in the trade dict. trades of this type are present in trade history.
export function goodTrade(trade: any) {
return goodObject(trade, [
"id",
"orderId",
"clientOrderId",
"symbol",
"side",
"quantity",
"price",
"fee",
"timestamp",
"taker",
]);
}
export function goodTradingCommission(transaction: any) {
return goodObject(transaction, ["symbol", "takeRate", "makeRate"]);
}
// goodTransaction check the precence of every field in the transaction dict
export function goodAddress(transaction: any) {
return goodObject(transaction, [
"currency",
"address",
// "paymentId", // optional
// "publicKey", // optional
]);
}
export function goodFee(fee: Fee) {
return goodObject(fee, [
"fee",
// "networkFee", // Optional
"amount",
"currency"
]);
}
// goodTransaction check the precence of every field in the transaction dict
export function goodTransaction(transaction: { native: any }) {
let good = goodObject(transaction, [
"id",
"status",
"type",
"subtype",
"createdAt",
"updatedAt",
"lastActivityAt",
"commitRisk",
// "native", // optional
// "primetrust", // optional
// "meta" // optional
]);
if (!good) return false;
if ("native" in transaction && !goodNativeTransaction(transaction.native)) {
return false;
}
if ("commitRisk" in transaction && !goodCommitRisk(transaction.commitRisk)) {
return false;
}
// if ("meta" in transaction && !goodMetaTransaction(transaction.meta)) {
// return false;
// }
return true;
}
export function goodNativeTransaction(transaction: any) {
return goodObject(transaction, [
"txId",
"index",
"currency",
"amount",
// "fee", // optional
// "address", // optional
// "paymentId", // optional
// "hash", // optional
// "offchainId", // optional
// "confirmations", // optional
// "publicComment", // optional
// "errorCode", // optional
// "senders" // optional
]);
}
export function goodMetaTransaction(transaction: any) {
return goodObject(transaction, [
"fiatToCrypto",
"id",
"providerName",
"orderType",
"orderType",
"sourceCurrency",
"targetCurrency",
"walletAddress",
"txHash",
"targetAmount",
"sourceAmount",
"status",
"createdAt",
"updatedAt",
"deletedAt",
"paymentMethodType",
]);
}
export function goodCommitRisk(commitRisk: any) {
return goodObject(commitRisk, []);
}
export function goodReport(report: Report) {
return goodObject(report, [
"id",
"clientOrderId",
"symbol",
"side",
"status",
"type",
"timeInForce",
"quantity",
"quantityCumulative",
"price",
"postOnly",
"createdAt",
"updatedAt",
// "reportType", not present in order list reports
]);
}
export function goodAmountLock(report: any) {
return goodObject(report, [
"id",
"currency",
"amount",
"dateEnd",
"description",
"cancelled",
"cancelledAt",
"cancelDescription",
"createdAt",
]);
}
export function goodPriceRate(report: any) {
return goodObject(report, [
"timestamp",
"rate"
]);
}