diff --git a/indexer/packages/postgres/src/db/migrations/migration_files/20260302120000_add_created_at_to_orders.ts b/indexer/packages/postgres/src/db/migrations/migration_files/20260302120000_add_created_at_to_orders.ts new file mode 100644 index 0000000000..f296c1930b --- /dev/null +++ b/indexer/packages/postgres/src/db/migrations/migration_files/20260302120000_add_created_at_to_orders.ts @@ -0,0 +1,13 @@ +import * as Knex from 'knex'; + +export async function up(knex: Knex): Promise { + return knex.schema.alterTable('orders', (table) => { + table.timestamp('createdAt').nullable(); + }); +} + +export async function down(knex: Knex): Promise { + return knex.schema.alterTable('orders', (table) => { + table.dropColumn('createdAt'); + }); +} diff --git a/indexer/packages/postgres/src/models/order-model.ts b/indexer/packages/postgres/src/models/order-model.ts index 22ae83b018..632eed175e 100644 --- a/indexer/packages/postgres/src/models/order-model.ts +++ b/indexer/packages/postgres/src/models/order-model.ts @@ -96,6 +96,7 @@ export default class OrderModel extends BaseModel { goodTilBlock: { type: ['string', 'null'], default: null, pattern: IntegerPattern }, goodTilBlockTime: { type: ['string', 'null'], default: null, format: 'date-time' }, createdAtHeight: { type: ['string', 'null'], default: null, pattern: IntegerPattern }, + createdAt: { type: ['string', 'null'], default: null, format: 'date-time' }, clientMetadata: { type: 'string', pattern: IntegerPattern }, triggerPrice: { type: ['string', 'null'], default: null, pattern: NonNegativeNumericPattern }, updatedAt: { type: 'string', format: 'date-time' }, @@ -134,6 +135,7 @@ export default class OrderModel extends BaseModel { goodTilBlock: 'string', goodTilBlockTime: 'date-time', createdAtHeight: 'string', + createdAt: 'date-time', clientMetadata: 'string', triggerPrice: 'string', updatedAt: 'date-time', @@ -181,6 +183,8 @@ export default class OrderModel extends BaseModel { createdAtHeight?: string; + createdAt?: IsoString; + clientMetadata!: string; triggerPrice?: string; diff --git a/indexer/packages/postgres/src/types/db-model-types.ts b/indexer/packages/postgres/src/types/db-model-types.ts index a3d69aada6..25b6753a03 100644 --- a/indexer/packages/postgres/src/types/db-model-types.ts +++ b/indexer/packages/postgres/src/types/db-model-types.ts @@ -72,8 +72,9 @@ export interface OrderFromDatabase extends IdBasedModelFromDatabase { updatedAtHeight: string, goodTilBlock?: string, goodTilBlockTime?: string, - // createdAtHeight is optional because short term orders do not have a createdAtHeight. + // createdAtHeight and createdAt are optional because short term orders do not have them. createdAtHeight?: string, + createdAt?: IsoString, clientMetadata: string, triggerPrice?: string, builderAddress?: string, diff --git a/indexer/packages/postgres/src/types/order-types.ts b/indexer/packages/postgres/src/types/order-types.ts index 239bedf280..40a597b902 100644 --- a/indexer/packages/postgres/src/types/order-types.ts +++ b/indexer/packages/postgres/src/types/order-types.ts @@ -62,8 +62,9 @@ export interface OrderCreateObject { updatedAtHeight: string, goodTilBlock?: string, goodTilBlockTime?: string, - // createdAtHeight is optional because short term orders do not have a createdAtHeight. + // createdAtHeight and createdAt are optional because short term orders do not have them. createdAtHeight?: string, + createdAt?: IsoString, clientMetadata: string, triggerPrice?: string, builderAddress?: string, @@ -119,6 +120,7 @@ export enum OrderColumns { updatedAt = 'updatedAt', updatedAtHeight = 'updatedAtHeight', createdAtHeight = 'createdAtHeight', + createdAt = 'createdAt', clientMetadata = 'clientMetadata', triggerPrice = 'triggerPrice', duration = 'duration', diff --git a/indexer/services/comlink/public/api-documentation.md b/indexer/services/comlink/public/api-documentation.md index 24b937a528..232a7358b3 100644 --- a/indexer/services/comlink/public/api-documentation.md +++ b/indexer/services/comlink/public/api-documentation.md @@ -2382,6 +2382,7 @@ fetch(`${baseURL}/orders?address=string&subaccountNumber=0.1`, "goodTilBlock": "string", "goodTilBlockTime": "string", "createdAtHeight": "string", + "createdAt": "string", "clientMetadata": "string", "triggerPrice": "string", "builderAddress": "string", @@ -2428,6 +2429,7 @@ Status Code **200** |» goodTilBlock|string|false|none|none| |» goodTilBlockTime|string|false|none|none| |» createdAtHeight|string|false|none|none| +|» createdAt|[IsoString](#schemaisostring)|false|none|none| |» clientMetadata|string|true|none|none| |» triggerPrice|string|false|none|none| |» builderAddress|string|false|none|none| @@ -2615,6 +2617,7 @@ fetch(`${baseURL}/orders/parentSubaccountNumber?address=string&parentSubaccountN "goodTilBlock": "string", "goodTilBlockTime": "string", "createdAtHeight": "string", + "createdAt": "string", "clientMetadata": "string", "triggerPrice": "string", "builderAddress": "string", @@ -2661,6 +2664,7 @@ Status Code **200** |» goodTilBlock|string|false|none|none| |» goodTilBlockTime|string|false|none|none| |» createdAtHeight|string|false|none|none| +|» createdAt|[IsoString](#schemaisostring)|false|none|none| |» clientMetadata|string|true|none|none| |» triggerPrice|string|false|none|none| |» builderAddress|string|false|none|none| @@ -2798,6 +2802,7 @@ fetch(`${baseURL}/orders/{orderId}`, "goodTilBlock": "string", "goodTilBlockTime": "string", "createdAtHeight": "string", + "createdAt": "string", "clientMetadata": "string", "triggerPrice": "string", "builderAddress": "string", @@ -6513,6 +6518,7 @@ or "goodTilBlock": "string", "goodTilBlockTime": "string", "createdAtHeight": "string", + "createdAt": "string", "clientMetadata": "string", "triggerPrice": "string", "builderAddress": "string", @@ -6550,6 +6556,7 @@ or |goodTilBlock|string|false|none|none| |goodTilBlockTime|string|false|none|none| |createdAtHeight|string|false|none|none| +|createdAt|[IsoString](#schemaisostring)|false|none|none| |clientMetadata|string|true|none|none| |triggerPrice|string|false|none|none| |builderAddress|string|false|none|none| diff --git a/indexer/services/comlink/public/swagger.json b/indexer/services/comlink/public/swagger.json index e5616990c7..3ad8a53e14 100644 --- a/indexer/services/comlink/public/swagger.json +++ b/indexer/services/comlink/public/swagger.json @@ -1108,6 +1108,9 @@ "createdAtHeight": { "type": "string" }, + "createdAt": { + "$ref": "#/components/schemas/IsoString" + }, "clientMetadata": { "type": "string" }, diff --git a/indexer/services/comlink/src/request-helpers/request-transformer.ts b/indexer/services/comlink/src/request-helpers/request-transformer.ts index d8b0a928ee..24b4e48f4a 100644 --- a/indexer/services/comlink/src/request-helpers/request-transformer.ts +++ b/indexer/services/comlink/src/request-helpers/request-transformer.ts @@ -494,6 +494,7 @@ export function postgresOrderToResponseObject( goodTilBlock: order.goodTilBlock ?? undefined, goodTilBlockTime: order.goodTilBlockTime ?? undefined, createdAtHeight: order.createdAtHeight ?? undefined, + createdAt: order.createdAt ?? undefined, ticker: perpetualMarketRefresher.getPerpetualMarketTicker(order.clobPairId)!, triggerPrice: order.triggerPrice ?? undefined, builderAddress: order.builderAddress ?? undefined, diff --git a/indexer/services/ender/__tests__/handlers/stateful-order/conditional-order-placement-handler.test.ts b/indexer/services/ender/__tests__/handlers/stateful-order/conditional-order-placement-handler.test.ts index 4cc6972e2a..29472bcbd4 100644 --- a/indexer/services/ender/__tests__/handlers/stateful-order/conditional-order-placement-handler.test.ts +++ b/indexer/services/ender/__tests__/handlers/stateful-order/conditional-order-placement-handler.test.ts @@ -157,6 +157,7 @@ describe('conditionalOrderPlacementHandler', () => { goodTilBlock: null, goodTilBlockTime: protocolTranslations.getGoodTilBlockTime(defaultOrder), createdAtHeight: '3', + createdAt: defaultDateTime.toISO(), clientMetadata: '0', triggerPrice: getTriggerPrice(defaultOrder, testConstants.defaultPerpetualMarket), updatedAt: defaultDateTime.toISO(), @@ -225,6 +226,7 @@ describe('conditionalOrderPlacementHandler', () => { goodTilBlock: null, goodTilBlockTime: protocolTranslations.getGoodTilBlockTime(defaultOrder), createdAtHeight: '3', + createdAt: defaultDateTime.toISO(), clientMetadata: '0', triggerPrice: getTriggerPrice(defaultOrder, testConstants.defaultPerpetualMarket), updatedAt: defaultDateTime.toISO(), diff --git a/indexer/services/ender/__tests__/handlers/stateful-order/stateful-order-placement-handler.test.ts b/indexer/services/ender/__tests__/handlers/stateful-order/stateful-order-placement-handler.test.ts index 0ee6a48661..984ff8236a 100644 --- a/indexer/services/ender/__tests__/handlers/stateful-order/stateful-order-placement-handler.test.ts +++ b/indexer/services/ender/__tests__/handlers/stateful-order/stateful-order-placement-handler.test.ts @@ -215,6 +215,7 @@ describe('statefulOrderPlacementHandler', () => { goodTilBlock: null, goodTilBlockTime: protocolTranslations.getGoodTilBlockTime(testOrder), createdAtHeight: '3', + createdAt: defaultDateTime.toISO(), clientMetadata: '0', triggerPrice: null, updatedAt: defaultDateTime.toISO(), @@ -299,6 +300,7 @@ describe('statefulOrderPlacementHandler', () => { goodTilBlock: null, goodTilBlockTime: protocolTranslations.getGoodTilBlockTime(testOrder), createdAtHeight: '3', + createdAt: defaultDateTime.toISO(), clientMetadata: '0', triggerPrice: null, updatedAt: defaultDateTime.toISO(), @@ -367,6 +369,7 @@ describe('statefulOrderPlacementHandler', () => { goodTilBlock: null, goodTilBlockTime: protocolTranslations.getGoodTilBlockTime(defaultOrder), createdAtHeight: '3', + createdAt: defaultDateTime.toISO(), clientMetadata: '0', triggerPrice: null, updatedAt: defaultDateTime.toISO(), diff --git a/indexer/services/ender/src/scripts/handlers/dydx_stateful_order_handler.sql b/indexer/services/ender/src/scripts/handlers/dydx_stateful_order_handler.sql index 3bf21c48f7..ecf5fc6cd8 100644 --- a/indexer/services/ender/src/scripts/handlers/dydx_stateful_order_handler.sql +++ b/indexer/services/ender/src/scripts/handlers/dydx_stateful_order_handler.sql @@ -60,6 +60,7 @@ BEGIN order_record."goodTilBlockTime" = to_timestamp((order_->'goodTilBlockTime')::double precision); order_record."clientMetadata" = (order_->'clientMetadata')::bigint; order_record."createdAtHeight" = block_height; + order_record."createdAt" = block_time; order_record."updatedAt" = block_time; order_record."updatedAtHeight" = block_height; order_record."orderRouterAddress" = order_->>'orderRouterAddress'; @@ -99,7 +100,7 @@ BEGIN INSERT INTO orders ( "id", "subaccountId", "clientId", "clobPairId", "side", "size", "totalFilled", "price", "timeInForce", "reduceOnly", "orderFlags", "goodTilBlockTime", - "clientMetadata", "createdAtHeight", "updatedAt", "updatedAtHeight", + "clientMetadata", "createdAtHeight", "createdAt", "updatedAt", "updatedAtHeight", "orderRouterAddress", "type", "status", "triggerPrice", "builderAddress", "feePpm", "duration", "interval", "priceTolerance" ) VALUES ( @@ -107,11 +108,11 @@ BEGIN order_record."clobPairId", order_record."side", order_record."size", order_record."totalFilled", order_record."price", order_record."timeInForce", order_record."reduceOnly", order_record."orderFlags", order_record."goodTilBlockTime", - order_record."clientMetadata", order_record."createdAtHeight", order_record."updatedAt", - order_record."updatedAtHeight", order_record."orderRouterAddress", order_record."type", - order_record."status", order_record."triggerPrice", order_record."builderAddress", - order_record."feePpm", order_record."duration", order_record."interval", - order_record."priceTolerance" + order_record."clientMetadata", order_record."createdAtHeight", order_record."createdAt", + order_record."updatedAt", order_record."updatedAtHeight", order_record."orderRouterAddress", + order_record."type", order_record."status", order_record."triggerPrice", + order_record."builderAddress", order_record."feePpm", order_record."duration", + order_record."interval", order_record."priceTolerance" ) ON CONFLICT ("id") DO UPDATE SET "subaccountId" = order_record."subaccountId", diff --git a/indexer/services/ender/src/scripts/helpers/dydx_liquidation_fill_handler_per_order.sql b/indexer/services/ender/src/scripts/helpers/dydx_liquidation_fill_handler_per_order.sql index 34ec5ac8aa..a4f7c3f883 100644 --- a/indexer/services/ender/src/scripts/helpers/dydx_liquidation_fill_handler_per_order.sql +++ b/indexer/services/ender/src/scripts/helpers/dydx_liquidation_fill_handler_per_order.sql @@ -184,6 +184,7 @@ BEGIN order_record."totalFilled" = fill_amount; order_record."status" = dydx_get_order_status(fill_amount, order_size, 'NOT_CANCELED', order_record."orderFlags", order_record."timeInForce"); order_record."createdAtHeight" = block_height; + order_record."createdAt" = block_time; IF jsonb_extract_path(order_, 'orderId', 'orderFlags')::bigint = constants.order_flag_twap_suborder() THEN -- This is a handled case but is not expected for twap. Parent orders should always exist @@ -200,16 +201,17 @@ BEGIN INSERT INTO orders ("id", "subaccountId", "clientId", "clobPairId", "side", "size", "totalFilled", "price", "type", "status", "timeInForce", "reduceOnly", "orderFlags", "goodTilBlock", "goodTilBlockTime", "createdAtHeight", - "clientMetadata", "triggerPrice", "updatedAt", "updatedAtHeight", "builderAddress", "feePpm", + "createdAt", "clientMetadata", "triggerPrice", "updatedAt", "updatedAtHeight", "builderAddress", "feePpm", "orderRouterAddress", "duration", "interval", "priceTolerance") VALUES ( order_record."id", order_record."subaccountId", order_record."clientId", order_record."clobPairId", order_record."side", order_record."size", order_record."totalFilled", order_record."price", order_record."type", order_record."status", order_record."timeInForce", order_record."reduceOnly", order_record."orderFlags", order_record."goodTilBlock", order_record."goodTilBlockTime", order_record."createdAtHeight", - order_record."clientMetadata", order_record."triggerPrice", order_record."updatedAt", order_record."updatedAtHeight", - order_record."builderAddress", order_record."feePpm", order_record."orderRouterAddress", order_record."duration", - order_record."interval", order_record."priceTolerance" + order_record."createdAt", order_record."clientMetadata", order_record."triggerPrice", + order_record."updatedAt", order_record."updatedAtHeight", + order_record."builderAddress", order_record."feePpm", order_record."orderRouterAddress", + order_record."duration", order_record."interval", order_record."priceTolerance" ); END IF; END IF; diff --git a/indexer/services/ender/src/scripts/helpers/dydx_order_fill_handler_per_order.sql b/indexer/services/ender/src/scripts/helpers/dydx_order_fill_handler_per_order.sql index 7247b487d8..99b0a29221 100644 --- a/indexer/services/ender/src/scripts/helpers/dydx_order_fill_handler_per_order.sql +++ b/indexer/services/ender/src/scripts/helpers/dydx_order_fill_handler_per_order.sql @@ -174,6 +174,7 @@ BEGIN order_record."totalFilled" = fill_amount; order_record."status" = dydx_get_order_status(fill_amount, order_size, order_canceled_status, order_record."orderFlags", order_record."timeInForce"); order_record."createdAtHeight" = block_height; + order_record."createdAt" = block_time; order_record."duration" = NULL; order_record."interval" = NULL; @@ -190,16 +191,17 @@ BEGIN INSERT INTO orders ("id", "subaccountId", "clientId", "clobPairId", "side", "size", "totalFilled", "price", "type", "status", "timeInForce", "reduceOnly", "orderFlags", "goodTilBlock", "goodTilBlockTime", "createdAtHeight", - "clientMetadata", "triggerPrice", "updatedAt", "updatedAtHeight", "builderAddress", "feePpm", + "createdAt", "clientMetadata", "triggerPrice", "updatedAt", "updatedAtHeight", "builderAddress", "feePpm", "orderRouterAddress", "duration", "interval", "priceTolerance") VALUES ( order_record."id", order_record."subaccountId", order_record."clientId", order_record."clobPairId", order_record."side", order_record."size", order_record."totalFilled", order_record."price", order_record."type", order_record."status", order_record."timeInForce", order_record."reduceOnly", order_record."orderFlags", order_record."goodTilBlock", order_record."goodTilBlockTime", order_record."createdAtHeight", - order_record."clientMetadata", order_record."triggerPrice", order_record."updatedAt", order_record."updatedAtHeight", - order_record."builderAddress", order_record."feePpm", order_record."orderRouterAddress", order_record."duration", - order_record."interval", order_record."priceTolerance" + order_record."createdAt", order_record."clientMetadata", order_record."triggerPrice", + order_record."updatedAt", order_record."updatedAtHeight", + order_record."builderAddress", order_record."feePpm", order_record."orderRouterAddress", + order_record."duration", order_record."interval", order_record."priceTolerance" ); END IF;