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