Updated to use same formatting as monorepo

This commit is contained in:
Luke Steyn
2023-05-31 23:08:37 +09:00
parent a86a1f0e3e
commit c0c97c9b63
5 changed files with 771 additions and 763 deletions

8
.prettierrc.js Normal file
View File

@@ -0,0 +1,8 @@
module.exports = {
semi: true,
trailingComma: 'es5',
singleQuote: true,
printWidth: 80,
tabWidth: 2,
useTabs: true,
};

4
.vscode/launch.json vendored
View File

@@ -10,7 +10,7 @@
"name": "Debug",
"port": 2230,
"timeout": 3000,
"restart": true,
},
"restart": true
}
]
}

View File

@@ -1,13 +1,13 @@
import { program, Option } from "commander";
import { program, Option } from 'commander';
import responseTime = require("response-time");
import express from "express";
import rateLimit from "express-rate-limit";
import compression from "compression";
import morgan from "morgan";
import cors from "cors";
import responseTime = require('response-time');
import express from 'express';
import rateLimit from 'express-rate-limit';
import compression from 'compression';
import morgan from 'morgan';
import cors from 'cors';
import { Connection, Commitment, PublicKey } from "@solana/web3.js";
import { Connection, Commitment, PublicKey } from '@solana/web3.js';
import {
getVariant,
@@ -27,29 +27,29 @@ import {
SpotMarketConfig,
PhoenixSubscriber,
SerumSubscriber,
} from "@drift-labs/sdk";
} from '@drift-labs/sdk';
import { Mutex } from "async-mutex";
import { Mutex } from 'async-mutex';
import { getWallet } from "./utils";
import { logger, setLogLevel } from "./logger";
import { getWallet } from './utils';
import { logger, setLogLevel } from './logger';
import { PrometheusExporter } from "@opentelemetry/exporter-prometheus";
import { PrometheusExporter } from '@opentelemetry/exporter-prometheus';
import {
ExplicitBucketHistogramAggregation,
InstrumentType,
MeterProvider,
View,
} from "@opentelemetry/sdk-metrics-base";
import { ObservableResult } from "@opentelemetry/api";
} from '@opentelemetry/sdk-metrics-base';
import { ObservableResult } from '@opentelemetry/api';
require("dotenv").config();
const driftEnv = (process.env.ENV || "devnet") as DriftEnv;
require('dotenv').config();
const driftEnv = (process.env.ENV || 'devnet') as DriftEnv;
const commitHash = process.env.COMMIT;
//@ts-ignore
const sdkConfig = initialize({ env: process.env.ENV });
const stateCommitment: Commitment = "confirmed";
const stateCommitment: Commitment = 'confirmed';
const serverPort = process.env.PORT || 6969;
const bulkAccountLoaderPollingInterval = process.env
@@ -70,13 +70,13 @@ const logHttp = morgan(logFormat, {
function errorHandler(err, _req, res, _next) {
logger.error(err.stack);
res.status(500).send("Internal error");
res.status(500).send('Internal error');
}
const app = express();
app.use(cors({ origin: "*" }));
app.use(cors({ origin: '*' }));
app.use(compression());
app.set("trust proxy", 1);
app.set('trust proxy', 1);
app.use(logHttp);
app.use(
@@ -90,29 +90,29 @@ app.use(
// strip off /dlob, if the request comes from exchange history server LB
app.use((req, _res, next) => {
if (req.url.startsWith("/dlob")) {
req.url = req.url.replace("/dlob", "");
if (req.url === "") {
req.url = "/";
if (req.url.startsWith('/dlob')) {
req.url = req.url.replace('/dlob', '');
if (req.url === '') {
req.url = '/';
}
}
next();
});
program
.option("-d, --dry-run", "Dry run, do not send transactions on chain")
.option("--test-liveness", "Purposefully fail liveness test after 1 minute")
.option('-d, --dry-run', 'Dry run, do not send transactions on chain')
.option('--test-liveness', 'Purposefully fail liveness test after 1 minute')
.addOption(
new Option(
"-p, --private-key <string>",
"private key, supports path to id.json, or list of comma separate numbers"
).env("ANCHOR_PRIVATE_KEY")
'-p, --private-key <string>',
'private key, supports path to id.json, or list of comma separate numbers'
).env('ANCHOR_PRIVATE_KEY')
)
.option("--debug", "Enable debug logging")
.option('--debug', 'Enable debug logging')
.parse();
const opts = program.opts();
setLogLevel(opts.debug ? "debug" : "info");
setLogLevel(opts.debug ? 'debug' : 'info');
const endpoint = process.env.ENDPOINT;
const wsEndpoint = process.env.WS_ENDPOINT;
@@ -143,9 +143,9 @@ const createHistogramBuckets = (
};
enum METRIC_TYPES {
runtime_specs = "runtime_specs",
endpoint_response_times_histogram = "endpoint_response_times_histogram",
health_status = "health_status",
runtime_specs = 'runtime_specs',
endpoint_response_times_histogram = 'endpoint_response_times_histogram',
health_status = 'health_status',
}
export enum HEALTH_STATUS {
@@ -169,7 +169,7 @@ const exporter = new PrometheusExporter(
);
}
);
const meterName = "dlob-meter";
const meterName = 'dlob-meter';
const meterProvider = new MeterProvider({
views: [
new View({
@@ -186,7 +186,7 @@ const meter = meterProvider.getMeter(meterName);
const runtimeSpecsGauge = meter.createObservableGauge(
METRIC_TYPES.runtime_specs,
{
description: "Runtime sepcification of this program",
description: 'Runtime sepcification of this program',
}
);
const bootTimeMs = Date.now();
@@ -203,7 +203,7 @@ let healthStatus: HEALTH_STATUS = HEALTH_STATUS.Ok;
const healthStatusGauge = meter.createObservableGauge(
METRIC_TYPES.health_status,
{
description: "Health status of this program",
description: 'Health status of this program',
}
);
healthStatusGauge.addCallback((obs: ObservableResult) => {
@@ -213,8 +213,8 @@ healthStatusGauge.addCallback((obs: ObservableResult) => {
const endpointResponseTimeHistogram = meter.createHistogram(
METRIC_TYPES.endpoint_response_times_histogram,
{
description: "Duration of endpoint responses",
unit: "ms",
description: 'Duration of endpoint responses',
unit: 'ms',
}
);
@@ -228,7 +228,7 @@ const getPhoenixSubscriber = (
programId: new PublicKey(sdkConfig.PHOENIX),
marketAddress: marketConfig.phoenixMarket,
accountSubscription: {
type: "polling",
type: 'polling',
accountLoader,
},
});
@@ -244,7 +244,7 @@ const getSerumSubscriber = (
programId: new PublicKey(sdkConfig.SERUM_V3),
marketAddress: marketConfig.serumMarket,
accountSubscription: {
type: "polling",
type: 'polling',
accountLoader,
},
});
@@ -322,7 +322,7 @@ const main = async () => {
return { publicKey: mkt.oracle, source: mkt.oracleSource };
}),
accountSubscription: {
type: "polling",
type: 'polling',
accountLoader: bulkAccountLoader,
},
env: driftEnv,
@@ -345,13 +345,13 @@ const main = async () => {
logger.info(` . SOL balance: ${lamportsBalance / 10 ** 9}`);
await driftClient.subscribe();
driftClient.eventEmitter.on("error", (e) => {
logger.info("clearing house error");
driftClient.eventEmitter.on('error', (e) => {
logger.info('clearing house error');
logger.error(e);
});
await slotSubscriber.subscribe();
slotSubscriber.eventEmitter.on("newSlot", async (slot: number) => {
slotSubscriber.eventEmitter.on('newSlot', async (slot: number) => {
await lastSlotReceivedMutex.runExclusive(async () => {
lastSlotReceived = slot;
});
@@ -398,15 +398,15 @@ const main = async () => {
);
// start http server listening to /health endpoint using http package
app.get("/health", handleResponseTime, async (req, res, next) => {
app.get('/health', handleResponseTime, async (req, res, next) => {
try {
if (req.url === "/health") {
if (req.url === '/health') {
if (opts.testLiveness) {
if (Date.now() > startupTime + 60 * 1000) {
healthStatus = HEALTH_STATUS.LivenessTesting;
res.writeHead(500);
res.end("Testing liveness test fail");
res.end('Testing liveness test fail');
return;
}
}
@@ -466,17 +466,17 @@ const main = async () => {
// liveness check passed
healthStatus = HEALTH_STATUS.Ok;
res.writeHead(200);
res.end("OK");
res.end('OK');
} else {
res.writeHead(404);
res.end("Not found");
res.end('Not found');
}
} catch (e) {
next(e);
}
});
app.get("/orders/json/raw", handleResponseTime, async (_req, res, next) => {
app.get('/orders/json/raw', handleResponseTime, async (_req, res, next) => {
try {
// object with userAccount key and orders object serialized
const orders: Array<any> = [];
@@ -497,7 +497,7 @@ const main = async () => {
const userAccount = user.getUserAccount();
for (const order of userAccount.orders) {
if (getVariant(order.status) === "init") {
if (getVariant(order.status) === 'init') {
continue;
}
@@ -522,7 +522,7 @@ const main = async () => {
}
});
app.get("/orders/json", handleResponseTime, async (_req, res, next) => {
app.get('/orders/json', handleResponseTime, async (_req, res, next) => {
try {
// object with userAccount key and orders object serialized
const slot = bulkAccountLoader.mostRecentSlot;
@@ -541,10 +541,10 @@ const main = async () => {
oracle.hasSufficientNumberOfDataPoints,
};
if (oracle.twap) {
oracleHuman["twap"] = oracle.twap.toString();
oracleHuman['twap'] = oracle.twap.toString();
}
if (oracle.twapConfidence) {
oracleHuman["twapConfidence"] = oracle.twapConfidence.toString();
oracleHuman['twapConfidence'] = oracle.twapConfidence.toString();
}
oracles.push(oracleHuman);
}
@@ -552,7 +552,7 @@ const main = async () => {
const userAccount = user.getUserAccount();
for (const order of userAccount.orders) {
if (getVariant(order.status) === "init") {
if (getVariant(order.status) === 'init') {
continue;
}
@@ -584,7 +584,7 @@ const main = async () => {
maxTs: order.maxTs.toString(),
};
if (order.quoteAssetAmount) {
orderHuman["quoteAssetAmount"] = order.quoteAssetAmount.toString();
orderHuman['quoteAssetAmount'] = order.quoteAssetAmount.toString();
}
orders.push({
@@ -608,7 +608,7 @@ const main = async () => {
}
});
app.get("/orders/idl", handleResponseTime, async (_req, res, next) => {
app.get('/orders/idl', handleResponseTime, async (_req, res, next) => {
try {
const dlobOrders: DLOBOrders = [];
@@ -616,7 +616,7 @@ const main = async () => {
const userAccount = user.getUserAccount();
for (const order of userAccount.orders) {
if (getVariant(order.status) === "init") {
if (getVariant(order.status) === 'init') {
continue;
}
@@ -634,7 +634,7 @@ const main = async () => {
}
});
app.get("/orders/idlWithSlot", handleResponseTime, async (req, res, next) => {
app.get('/orders/idlWithSlot', handleResponseTime, async (req, res, next) => {
try {
const { marketName, marketIndex, marketType } = req.query;
const { normedMarketType, normedMarketIndex, error } = validateDlobQuery(
@@ -664,7 +664,7 @@ const main = async () => {
const userAccount = user.getUserAccount();
for (const order of userAccount.orders) {
if (getVariant(order.status) === "init") {
if (getVariant(order.status) === 'init') {
continue;
}
@@ -687,7 +687,7 @@ const main = async () => {
res.end(
JSON.stringify({
slot: bulkAccountLoader.mostRecentSlot,
data: dlobCoder.encode(dlobOrders).toString("base64"),
data: dlobCoder.encode(dlobOrders).toString('base64'),
})
);
} catch (err) {
@@ -711,13 +711,13 @@ const main = async () => {
if (marketIndex === undefined || marketType === undefined) {
return {
error:
"Bad Request: (marketName) or (marketIndex and marketType) must be supplied",
'Bad Request: (marketName) or (marketIndex and marketType) must be supplied',
};
}
// validate marketType
switch ((marketType as string).toLowerCase()) {
case "spot": {
case 'spot': {
normedMarketType = MarketType.SPOT;
normedMarketIndex = parseInt(marketIndex as string);
const spotMarketIndicies = SpotMarkets[driftEnv].map(
@@ -725,12 +725,12 @@ const main = async () => {
);
if (!spotMarketIndicies.includes(normedMarketIndex)) {
return {
error: "Bad Request: invalid marketIndex",
error: 'Bad Request: invalid marketIndex',
};
}
break;
}
case "perp": {
case 'perp': {
normedMarketType = MarketType.PERP;
normedMarketIndex = parseInt(marketIndex as string);
const perpMarketIndicies = PerpMarkets[driftEnv].map(
@@ -738,7 +738,7 @@ const main = async () => {
);
if (!perpMarketIndicies.includes(normedMarketIndex)) {
return {
error: "Bad Request: invalid marketIndex",
error: 'Bad Request: invalid marketIndex',
};
}
break;
@@ -755,7 +755,7 @@ const main = async () => {
driftClient.getMarketIndexAndType(normedMarketName);
if (!derivedMarketInfo) {
return {
error: "Bad Request: unrecognized marketName",
error: 'Bad Request: unrecognized marketName',
};
}
normedMarketType = derivedMarketInfo.marketType;
@@ -768,7 +768,7 @@ const main = async () => {
};
};
app.get("/l2", handleResponseTime, async (req, res, next) => {
app.get('/l2', handleResponseTime, async (req, res, next) => {
try {
const {
marketName,
@@ -790,18 +790,18 @@ const main = async () => {
return;
}
const isSpot = marketType === "spot";
const isSpot = marketType === 'spot';
const l2 = await dlobSubscriber.getL2({
marketIndex: normedMarketIndex,
marketType: normedMarketType,
depth: depth ? parseInt(depth as string) : 10,
includeVamm: `${includeVamm}`.toLowerCase() === "true",
includeVamm: `${includeVamm}`.toLowerCase() === 'true',
fallbackL2Generators: isSpot
? [
`${includePhoenix}`.toLowerCase() === "true" &&
`${includePhoenix}`.toLowerCase() === 'true' &&
MARKET_SUBSCRIBERS[normedMarketIndex].phoenix,
`${includeSerum}`.toLowerCase() === "true" &&
`${includeSerum}`.toLowerCase() === 'true' &&
MARKET_SUBSCRIBERS[normedMarketIndex].serum,
].filter((a) => !!a)
: [],
@@ -810,7 +810,7 @@ const main = async () => {
for (const key of Object.keys(l2)) {
for (const idx in l2[key]) {
const level = l2[key][idx];
const sources = level["sources"];
const sources = level['sources'];
for (const sourceKey of Object.keys(sources)) {
sources[sourceKey] = sources[sourceKey].toString();
}
@@ -829,7 +829,7 @@ const main = async () => {
}
});
app.get("/l3", handleResponseTime, async (req, res, next) => {
app.get('/l3', handleResponseTime, async (req, res, next) => {
try {
const { marketName, marketIndex, marketType } = req.query;

View File

@@ -1,4 +1,4 @@
import { createLogger, transports, format } from "winston";
import { createLogger, transports, format } from 'winston';
export const logger = createLogger({
transports: [new transports.Console()],

View File

@@ -1,15 +1,15 @@
import fs from "fs";
import { Keypair } from "@solana/web3.js";
import { bs58 } from "@project-serum/anchor/dist/cjs/utils/bytes";
import { Wallet } from "@drift-labs/sdk";
import fs from 'fs';
import { Keypair } from '@solana/web3.js';
import { bs58 } from '@project-serum/anchor/dist/cjs/utils/bytes';
import { Wallet } from '@drift-labs/sdk';
import { logger } from "./logger";
import { logger } from './logger';
export function getWallet(): Wallet {
const privateKey = process.env.ANCHOR_PRIVATE_KEY;
if (!privateKey) {
throw new Error(
"Must set environment variable ANCHOR_PRIVATE_KEY with the path to a id.json or a list of commma separated numbers"
'Must set environment variable ANCHOR_PRIVATE_KEY with the path to a id.json or a list of commma separated numbers'
);
}
// try to load privateKey as a filepath
@@ -20,10 +20,10 @@ export function getWallet(): Wallet {
JSON.parse(fs.readFileSync(privateKey).toString())
);
} else {
if (privateKey.includes(",")) {
if (privateKey.includes(',')) {
logger.info(`Trying to load private key as comma separated numbers`);
loadedKey = Uint8Array.from(
privateKey.split(",").map((val) => Number(val))
privateKey.split(',').map((val) => Number(val))
);
} else {
logger.info(`Trying to load private key as base58 string`);