disable orders endpoint, add flag to disable gpa refresh
This commit is contained in:
428
src/index.ts
428
src/index.ts
@@ -46,6 +46,7 @@ import {
|
|||||||
sleep,
|
sleep,
|
||||||
validateDlobQuery,
|
validateDlobQuery,
|
||||||
} from './utils/utils';
|
} from './utils/utils';
|
||||||
|
import FEATURE_FLAGS from './utils/featureFlags';
|
||||||
import {
|
import {
|
||||||
DLOBProvider,
|
DLOBProvider,
|
||||||
getDLOBProviderFromOrderSubscriber,
|
getDLOBProviderFromOrderSubscriber,
|
||||||
@@ -174,7 +175,7 @@ const main = async () => {
|
|||||||
const clearingHousePublicKey = new PublicKey(sdkConfig.DRIFT_PROGRAM_ID);
|
const clearingHousePublicKey = new PublicKey(sdkConfig.DRIFT_PROGRAM_ID);
|
||||||
|
|
||||||
const connection = new Connection(endpoint, {
|
const connection = new Connection(endpoint, {
|
||||||
wsEndpoint: wsEndpoint,
|
wsEndpoint,
|
||||||
commitment: stateCommitment,
|
commitment: stateCommitment,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -274,7 +275,8 @@ const main = async () => {
|
|||||||
`dlob provider initialized in ${Date.now() - initDLOBProviderStart} ms`
|
`dlob provider initialized in ${Date.now() - initDLOBProviderStart} ms`
|
||||||
);
|
);
|
||||||
logger.info(`dlob provider size ${dlobProvider.size()}`);
|
logger.info(`dlob provider size ${dlobProvider.size()}`);
|
||||||
if (useWebsocket) {
|
|
||||||
|
if (useWebsocket && !FEATURE_FLAGS.DISABLE_GPA_REFRESH) {
|
||||||
const recursiveFetch = (delay = WS_FALLBACK_FETCH_INTERVAL) => {
|
const recursiveFetch = (delay = WS_FALLBACK_FETCH_INTERVAL) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
dlobProvider.fetch().then(() => {
|
dlobProvider.fetch().then(() => {
|
||||||
@@ -322,218 +324,234 @@ const main = async () => {
|
|||||||
app.get('/startup', handleStartup);
|
app.get('/startup', handleStartup);
|
||||||
app.get('/', handleHealthCheck(slotSource));
|
app.get('/', handleHealthCheck(slotSource));
|
||||||
|
|
||||||
app.get('/orders/json/raw', async (_req, res, next) => {
|
if (FEATURE_FLAGS.ENABLE_ORDERS_ENDPOINTS) {
|
||||||
try {
|
app.get('/orders/json/raw', async (_req, res, next) => {
|
||||||
// object with userAccount key and orders object serialized
|
try {
|
||||||
const orders: Array<any> = [];
|
// object with userAccount key and orders object serialized
|
||||||
const oracles: Array<any> = [];
|
const orders: Array<any> = [];
|
||||||
const slot = slotSource.getSlot();
|
const oracles: Array<any> = [];
|
||||||
|
const slot = slotSource.getSlot();
|
||||||
|
|
||||||
for (const market of driftClient.getPerpMarketAccounts()) {
|
for (const market of driftClient.getPerpMarketAccounts()) {
|
||||||
const oracle = driftClient.getOracleDataForPerpMarket(
|
const oracle = driftClient.getOracleDataForPerpMarket(
|
||||||
market.marketIndex
|
market.marketIndex
|
||||||
);
|
);
|
||||||
oracles.push({
|
oracles.push({
|
||||||
marketIndex: market.marketIndex,
|
marketIndex: market.marketIndex,
|
||||||
...oracle,
|
...oracle,
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const { userAccount, publicKey } of dlobProvider.getUserAccounts()) {
|
|
||||||
for (const order of userAccount.orders) {
|
|
||||||
if (isVariant(order.status, 'init')) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
orders.push({
|
|
||||||
user: publicKey.toBase58(),
|
|
||||||
order: order,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// respond with orders
|
for (const {
|
||||||
res.writeHead(200);
|
userAccount,
|
||||||
res.end(
|
publicKey,
|
||||||
JSON.stringify({
|
} of dlobProvider.getUserAccounts()) {
|
||||||
slot,
|
for (const order of userAccount.orders) {
|
||||||
oracles,
|
if (isVariant(order.status, 'init')) {
|
||||||
orders,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
next(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.get('/orders/json', async (_req, res, next) => {
|
|
||||||
try {
|
|
||||||
// object with userAccount key and orders object serialized
|
|
||||||
const slot = slotSource.getSlot();
|
|
||||||
const orders: Array<any> = [];
|
|
||||||
const oracles: Array<any> = [];
|
|
||||||
for (const market of driftClient.getPerpMarketAccounts()) {
|
|
||||||
const oracle = driftClient.getOracleDataForPerpMarket(
|
|
||||||
market.marketIndex
|
|
||||||
);
|
|
||||||
const oracleHuman = {
|
|
||||||
marketIndex: market.marketIndex,
|
|
||||||
price: oracle.price.toString(),
|
|
||||||
slot: oracle.slot.toString(),
|
|
||||||
confidence: oracle.confidence.toString(),
|
|
||||||
hasSufficientNumberOfDataPoints:
|
|
||||||
oracle.hasSufficientNumberOfDataPoints,
|
|
||||||
};
|
|
||||||
if (oracle.twap) {
|
|
||||||
oracleHuman['twap'] = oracle.twap.toString();
|
|
||||||
}
|
|
||||||
if (oracle.twapConfidence) {
|
|
||||||
oracleHuman['twapConfidence'] = oracle.twapConfidence.toString();
|
|
||||||
}
|
|
||||||
oracles.push(oracleHuman);
|
|
||||||
}
|
|
||||||
for (const { userAccount, publicKey } of dlobProvider.getUserAccounts()) {
|
|
||||||
for (const order of userAccount.orders) {
|
|
||||||
if (isVariant(order.status, 'init')) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const orderHuman = {
|
|
||||||
status: getVariant(order.status),
|
|
||||||
orderType: getVariant(order.orderType),
|
|
||||||
marketType: getVariant(order.marketType),
|
|
||||||
slot: order.slot.toString(),
|
|
||||||
orderId: order.orderId,
|
|
||||||
userOrderId: order.userOrderId,
|
|
||||||
marketIndex: order.marketIndex,
|
|
||||||
price: order.price.toString(),
|
|
||||||
baseAssetAmount: order.baseAssetAmount.toString(),
|
|
||||||
baseAssetAmountFilled: order.baseAssetAmountFilled.toString(),
|
|
||||||
quoteAssetAmountFilled: order.quoteAssetAmountFilled.toString(),
|
|
||||||
direction: getVariant(order.direction),
|
|
||||||
reduceOnly: order.reduceOnly,
|
|
||||||
triggerPrice: order.triggerPrice.toString(),
|
|
||||||
triggerCondition: getVariant(order.triggerCondition),
|
|
||||||
existingPositionDirection: getVariant(
|
|
||||||
order.existingPositionDirection
|
|
||||||
),
|
|
||||||
postOnly: order.postOnly,
|
|
||||||
immediateOrCancel: order.immediateOrCancel,
|
|
||||||
oraclePriceOffset: order.oraclePriceOffset,
|
|
||||||
auctionDuration: order.auctionDuration,
|
|
||||||
auctionStartPrice: order.auctionStartPrice.toString(),
|
|
||||||
auctionEndPrice: order.auctionEndPrice.toString(),
|
|
||||||
maxTs: order.maxTs.toString(),
|
|
||||||
};
|
|
||||||
if (order.quoteAssetAmount) {
|
|
||||||
orderHuman['quoteAssetAmount'] = order.quoteAssetAmount.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
orders.push({
|
|
||||||
user: publicKey.toBase58(),
|
|
||||||
order: orderHuman,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// respond with orders
|
|
||||||
res.writeHead(200);
|
|
||||||
res.end(
|
|
||||||
JSON.stringify({
|
|
||||||
slot,
|
|
||||||
oracles,
|
|
||||||
orders,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} catch (err) {
|
|
||||||
next(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.get('/orders/idl', async (_req, res, next) => {
|
|
||||||
try {
|
|
||||||
const dlobOrders: DLOBOrders = [];
|
|
||||||
|
|
||||||
for (const { userAccount, publicKey } of dlobProvider.getUserAccounts()) {
|
|
||||||
for (const order of userAccount.orders) {
|
|
||||||
if (isVariant(order.status, 'init')) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
dlobOrders.push({
|
|
||||||
user: publicKey,
|
|
||||||
order,
|
|
||||||
} as DLOBOrder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
res.writeHead(200);
|
|
||||||
res.end(dlobCoder.encode(dlobOrders));
|
|
||||||
} catch (err) {
|
|
||||||
next(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.get('/orders/idlWithSlot', async (req, res, next) => {
|
|
||||||
try {
|
|
||||||
const { marketName, marketIndex, marketType } = req.query;
|
|
||||||
const { normedMarketType, normedMarketIndex, error } = validateDlobQuery(
|
|
||||||
driftClient,
|
|
||||||
driftEnv,
|
|
||||||
marketType as string,
|
|
||||||
marketIndex as string,
|
|
||||||
marketName as string
|
|
||||||
);
|
|
||||||
const useFilter =
|
|
||||||
marketName !== undefined ||
|
|
||||||
marketIndex !== undefined ||
|
|
||||||
marketType !== undefined;
|
|
||||||
|
|
||||||
if (useFilter) {
|
|
||||||
if (
|
|
||||||
error ||
|
|
||||||
normedMarketType === undefined ||
|
|
||||||
normedMarketIndex === undefined
|
|
||||||
) {
|
|
||||||
res.status(400).send(error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const dlobOrders: DLOBOrders = [];
|
|
||||||
|
|
||||||
for (const { userAccount, publicKey } of dlobProvider.getUserAccounts()) {
|
|
||||||
for (const order of userAccount.orders) {
|
|
||||||
if (isVariant(order.status, 'init')) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (useFilter) {
|
|
||||||
if (
|
|
||||||
getVariant(order.marketType) !== getVariant(normedMarketType) ||
|
|
||||||
order.marketIndex !== normedMarketIndex
|
|
||||||
) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
orders.push({
|
||||||
|
user: publicKey.toBase58(),
|
||||||
|
order: order,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
dlobOrders.push({
|
|
||||||
user: publicKey,
|
|
||||||
order,
|
|
||||||
} as DLOBOrder);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
res.end(
|
// respond with orders
|
||||||
JSON.stringify({
|
res.writeHead(200);
|
||||||
slot: slotSource.getSlot(),
|
res.end(
|
||||||
data: dlobCoder.encode(dlobOrders).toString('base64'),
|
JSON.stringify({
|
||||||
})
|
slot,
|
||||||
);
|
oracles,
|
||||||
} catch (err) {
|
orders,
|
||||||
next(err);
|
})
|
||||||
}
|
);
|
||||||
});
|
} catch (e) {
|
||||||
|
next(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/orders/json', async (_req, res, next) => {
|
||||||
|
try {
|
||||||
|
// object with userAccount key and orders object serialized
|
||||||
|
const slot = slotSource.getSlot();
|
||||||
|
const orders: Array<any> = [];
|
||||||
|
const oracles: Array<any> = [];
|
||||||
|
for (const market of driftClient.getPerpMarketAccounts()) {
|
||||||
|
const oracle = driftClient.getOracleDataForPerpMarket(
|
||||||
|
market.marketIndex
|
||||||
|
);
|
||||||
|
const oracleHuman = {
|
||||||
|
marketIndex: market.marketIndex,
|
||||||
|
price: oracle.price.toString(),
|
||||||
|
slot: oracle.slot.toString(),
|
||||||
|
confidence: oracle.confidence.toString(),
|
||||||
|
hasSufficientNumberOfDataPoints:
|
||||||
|
oracle.hasSufficientNumberOfDataPoints,
|
||||||
|
};
|
||||||
|
if (oracle.twap) {
|
||||||
|
oracleHuman['twap'] = oracle.twap.toString();
|
||||||
|
}
|
||||||
|
if (oracle.twapConfidence) {
|
||||||
|
oracleHuman['twapConfidence'] = oracle.twapConfidence.toString();
|
||||||
|
}
|
||||||
|
oracles.push(oracleHuman);
|
||||||
|
}
|
||||||
|
for (const {
|
||||||
|
userAccount,
|
||||||
|
publicKey,
|
||||||
|
} of dlobProvider.getUserAccounts()) {
|
||||||
|
for (const order of userAccount.orders) {
|
||||||
|
if (isVariant(order.status, 'init')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const orderHuman = {
|
||||||
|
status: getVariant(order.status),
|
||||||
|
orderType: getVariant(order.orderType),
|
||||||
|
marketType: getVariant(order.marketType),
|
||||||
|
slot: order.slot.toString(),
|
||||||
|
orderId: order.orderId,
|
||||||
|
userOrderId: order.userOrderId,
|
||||||
|
marketIndex: order.marketIndex,
|
||||||
|
price: order.price.toString(),
|
||||||
|
baseAssetAmount: order.baseAssetAmount.toString(),
|
||||||
|
baseAssetAmountFilled: order.baseAssetAmountFilled.toString(),
|
||||||
|
quoteAssetAmountFilled: order.quoteAssetAmountFilled.toString(),
|
||||||
|
direction: getVariant(order.direction),
|
||||||
|
reduceOnly: order.reduceOnly,
|
||||||
|
triggerPrice: order.triggerPrice.toString(),
|
||||||
|
triggerCondition: getVariant(order.triggerCondition),
|
||||||
|
existingPositionDirection: getVariant(
|
||||||
|
order.existingPositionDirection
|
||||||
|
),
|
||||||
|
postOnly: order.postOnly,
|
||||||
|
immediateOrCancel: order.immediateOrCancel,
|
||||||
|
oraclePriceOffset: order.oraclePriceOffset,
|
||||||
|
auctionDuration: order.auctionDuration,
|
||||||
|
auctionStartPrice: order.auctionStartPrice.toString(),
|
||||||
|
auctionEndPrice: order.auctionEndPrice.toString(),
|
||||||
|
maxTs: order.maxTs.toString(),
|
||||||
|
};
|
||||||
|
if (order.quoteAssetAmount) {
|
||||||
|
orderHuman['quoteAssetAmount'] =
|
||||||
|
order.quoteAssetAmount.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
orders.push({
|
||||||
|
user: publicKey.toBase58(),
|
||||||
|
order: orderHuman,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// respond with orders
|
||||||
|
res.writeHead(200);
|
||||||
|
res.end(
|
||||||
|
JSON.stringify({
|
||||||
|
slot,
|
||||||
|
oracles,
|
||||||
|
orders,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/orders/idl', async (_req, res, next) => {
|
||||||
|
try {
|
||||||
|
const dlobOrders: DLOBOrders = [];
|
||||||
|
|
||||||
|
for (const {
|
||||||
|
userAccount,
|
||||||
|
publicKey,
|
||||||
|
} of dlobProvider.getUserAccounts()) {
|
||||||
|
for (const order of userAccount.orders) {
|
||||||
|
if (isVariant(order.status, 'init')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dlobOrders.push({
|
||||||
|
user: publicKey,
|
||||||
|
order,
|
||||||
|
} as DLOBOrder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res.writeHead(200);
|
||||||
|
res.end(dlobCoder.encode(dlobOrders));
|
||||||
|
} catch (err) {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/orders/idlWithSlot', async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
const { marketName, marketIndex, marketType } = req.query;
|
||||||
|
const { normedMarketType, normedMarketIndex, error } =
|
||||||
|
validateDlobQuery(
|
||||||
|
driftClient,
|
||||||
|
driftEnv,
|
||||||
|
marketType as string,
|
||||||
|
marketIndex as string,
|
||||||
|
marketName as string
|
||||||
|
);
|
||||||
|
const useFilter =
|
||||||
|
marketName !== undefined ||
|
||||||
|
marketIndex !== undefined ||
|
||||||
|
marketType !== undefined;
|
||||||
|
|
||||||
|
if (useFilter) {
|
||||||
|
if (
|
||||||
|
error ||
|
||||||
|
normedMarketType === undefined ||
|
||||||
|
normedMarketIndex === undefined
|
||||||
|
) {
|
||||||
|
res.status(400).send(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const dlobOrders: DLOBOrders = [];
|
||||||
|
|
||||||
|
for (const {
|
||||||
|
userAccount,
|
||||||
|
publicKey,
|
||||||
|
} of dlobProvider.getUserAccounts()) {
|
||||||
|
for (const order of userAccount.orders) {
|
||||||
|
if (isVariant(order.status, 'init')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useFilter) {
|
||||||
|
if (
|
||||||
|
getVariant(order.marketType) !== getVariant(normedMarketType) ||
|
||||||
|
order.marketIndex !== normedMarketIndex
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dlobOrders.push({
|
||||||
|
user: publicKey,
|
||||||
|
order,
|
||||||
|
} as DLOBOrder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res.end(
|
||||||
|
JSON.stringify({
|
||||||
|
slot: slotSource.getSlot(),
|
||||||
|
data: dlobCoder.encode(dlobOrders).toString('base64'),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
app.get('/topMakers', async (req, res, next) => {
|
app.get('/topMakers', async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,7 +1,17 @@
|
|||||||
// TODO : Is it worth adding proper infrastructure for feature flags? .. Would allow more powerful things like toggling them at runtime rather than being hardcoded
|
|
||||||
export const FEATURE_FLAGS = {
|
export const FEATURE_FLAGS = {
|
||||||
OLD_ORACLE_PRICE_IN_L2: true, // TODO : Remove this once we're confident that NEW_ORACLE_DATA_IN_L2 works .. delete corresponding code
|
// TODO : Remove this once we're confident that NEW_ORACLE_DATA_IN_L2 works .. delete corresponding code
|
||||||
|
OLD_ORACLE_PRICE_IN_L2: true,
|
||||||
NEW_ORACLE_DATA_IN_L2: true,
|
NEW_ORACLE_DATA_IN_L2: true,
|
||||||
|
|
||||||
|
// enables old orders endpoint, disabled by default since the response is too big now
|
||||||
|
ENABLE_ORDERS_ENDPOINTS: process.env.ENABLE_ORDERS_ENDPOINTS
|
||||||
|
? process.env.ENABLE_ORDERS_ENDPOINTS.toLowerCase()
|
||||||
|
: false,
|
||||||
|
|
||||||
|
// disables periodically refreshing userAccounts via gPA
|
||||||
|
DISABLE_GPA_REFRESH: process.env.DISABLE_GPA_REFRESH
|
||||||
|
? process.env.DISABLE_GPA_REFRESH.toLowerCase()
|
||||||
|
: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FEATURE_FLAGS;
|
export default FEATURE_FLAGS;
|
||||||
|
|||||||
Reference in New Issue
Block a user