feat(dlob): support two sources + per-user switch

- Add "source" column + composite PKs for DLOB tables\n- Filter public Hasura selects by X-Hasura-Dlob-Source\n- Run parallel workers for mevnode + dlob.drift.trade\n- Frontend proxy sets x-hasura-dlob-source from cookie and injects UI switch
This commit is contained in:
u1
2026-02-13 10:48:20 +01:00
parent 9e7d7b88ac
commit 57433c7e75
17 changed files with 501 additions and 54 deletions

View File

@@ -89,6 +89,8 @@ async function main() {
console.log(`[hasura-bootstrap] HASURA_URL=${HASURA_URL}`);
await waitForHasura();
const PUBLIC_DLOB_SOURCE_HEADER = 'X-Hasura-Dlob-Source';
const apiTokensTable = { schema: 'public', name: 'api_tokens' };
const source = 'default';
@@ -187,7 +189,7 @@ async function main() {
'updated_at',
]);
const ensureDlobTable = async (table, columns) => {
const ensureDlobTable = async (table, columns, { publicFilter } = {}) => {
await metadataIgnore({ type: 'pg_untrack_table', args: { source, table } });
await metadata({ type: 'pg_track_table', args: { source, table } });
@@ -200,7 +202,7 @@ async function main() {
role: 'public',
permission: {
columns,
filter: {},
filter: publicFilter || {},
},
},
});
@@ -236,7 +238,7 @@ async function main() {
});
};
async function ensurePublicSelectTable(table, columns) {
async function ensurePublicSelectTable(table, columns, { publicFilter } = {}) {
await metadataIgnore({ type: 'pg_untrack_table', args: { source, table } });
await metadata({ type: 'pg_track_table', args: { source, table } });
@@ -249,7 +251,7 @@ async function main() {
role: 'public',
permission: {
columns,
filter: {},
filter: publicFilter || {},
},
},
});
@@ -259,7 +261,10 @@ async function main() {
await metadataIgnore({ type: 'pg_drop_update_permission', args: { source, table, role: 'ingestor' } });
}
const dlobPublicFilter = { source: { _eq: PUBLIC_DLOB_SOURCE_HEADER } };
await ensureDlobTable(dlobL2LatestTable, [
'source',
'market_name',
'market_type',
'market_index',
@@ -273,9 +278,10 @@ async function main() {
'asks',
'raw',
'updated_at',
]);
], { publicFilter: dlobPublicFilter });
await ensureDlobTable(dlobStatsLatestTable, [
'source',
'market_name',
'market_type',
'market_index',
@@ -296,9 +302,10 @@ async function main() {
'imbalance',
'raw',
'updated_at',
]);
], { publicFilter: dlobPublicFilter });
await ensurePublicSelectTable(dlobDepthBpsLatestTable, [
'source',
'market_name',
'band_bps',
'market_type',
@@ -315,9 +322,10 @@ async function main() {
'imbalance',
'raw',
'updated_at',
]);
], { publicFilter: dlobPublicFilter });
await ensurePublicSelectTable(dlobSlippageLatestTable, [
'source',
'market_name',
'side',
'size_usd',
@@ -337,9 +345,10 @@ async function main() {
'fill_pct',
'raw',
'updated_at',
]);
], { publicFilter: dlobPublicFilter });
await ensurePublicSelectTable(dlobSlippageLatestV2Table, [
'source',
'market_name',
'side',
'size_usd',
@@ -359,11 +368,12 @@ async function main() {
'fill_pct',
'raw',
'updated_at',
]);
], { publicFilter: dlobPublicFilter });
await ensurePublicSelectTable(dlobStatsTsTable, [
'ts',
'id',
'source',
'market_name',
'market_type',
'market_index',
@@ -383,11 +393,12 @@ async function main() {
'depth_ask_usd',
'imbalance',
'raw',
]);
], { publicFilter: dlobPublicFilter });
await ensurePublicSelectTable(dlobDepthBpsTsTable, [
'ts',
'id',
'source',
'market_name',
'band_bps',
'market_type',
@@ -403,11 +414,12 @@ async function main() {
'ask_usd',
'imbalance',
'raw',
]);
], { publicFilter: dlobPublicFilter });
await ensurePublicSelectTable(dlobSlippageTsTable, [
'ts',
'id',
'source',
'market_name',
'side',
'size_usd',
@@ -424,11 +436,12 @@ async function main() {
'levels_consumed',
'fill_pct',
'raw',
]);
], { publicFilter: dlobPublicFilter });
await ensurePublicSelectTable(dlobSlippageTsV2Table, [
'ts',
'id',
'source',
'market_name',
'side',
'size_usd',
@@ -445,7 +458,7 @@ async function main() {
'levels_consumed',
'fill_pct',
'raw',
]);
], { publicFilter: dlobPublicFilter });
// Return table type for candle functions (needed for Hasura to track the function).
await metadataIgnore({ type: 'pg_track_table', args: { source, table: candlesReturnTable } });