3131 * handlers — they remain exported and documented for future use.
3232 */
3333import { Router } from "express" ;
34- import type { Request } from "express" ;
34+ import type { Request , Response } from "express" ;
3535import { z } from "zod" ;
3636import { shortString } from "starknet" ;
3737import { agreementContract , escrowContract , provider } from "../starknet/client.js" ;
3838import { u256ToString , toHexString } from "../utils/codec.js" ;
3939import { env } from "../config.js" ;
4040import { NumericCursorSchema , loggedParse } from "../utils/validation.js" ;
41+ import { applyIndexedCacheHeaders } from "../utils/cache-headers.js" ;
4142
4243// ---------- validation ----------
4344
@@ -379,6 +380,16 @@ function logReadTelemetry(entry: TelemetryEntry) {
379380
380381export const readRouter = Router ( ) ;
381382
383+ /** Send a read-only indexed response with conditional-request support. */
384+ function sendIndexedResponse ( req : Request , res : Response , body : unknown ) : void {
385+ applyIndexedCacheHeaders ( res , body ) ;
386+ if ( req . fresh ) {
387+ res . status ( 304 ) . end ( ) ;
388+ return ;
389+ }
390+ res . json ( body ) ;
391+ }
392+
382393// ---------- token / balances ----------
383394
384395readRouter . get ( "/token/:token/balance/:owner" , async ( req , res , next ) => {
@@ -388,7 +399,7 @@ readRouter.get("/token/:token/balance/:owner", async (req, res, next) => {
388399 const token = AddressParam . parse ( req . params . token ) ;
389400 const owner = AddressParam . parse ( req . params . owner ) ;
390401 const balance = await erc20BalanceOf ( token , owner ) ;
391- res . json ( { token, owner, balance } ) ;
402+ sendIndexedResponse ( req , res , { token, owner, balance } ) ;
392403 } catch ( e : any ) {
393404 const duration = Number ( process . hrtime . bigint ( ) - start ) / 1_000_000 ;
394405 logReadTelemetry ( {
@@ -427,7 +438,7 @@ readRouter.get("/token/:token/decimals", async (req, res, next) => {
427438 token,
428439 request_id : res . locals . requestId ,
429440 } ) ;
430- res . json ( { token, decimals } ) ;
441+ sendIndexedResponse ( req , res , { token, decimals } ) ;
431442 } catch ( e : any ) {
432443 const duration = Number ( process . hrtime . bigint ( ) - start ) / 1_000_000 ;
433444 logReadTelemetry ( {
@@ -465,7 +476,7 @@ readRouter.get("/token/:token/symbol", async (req, res, next) => {
465476 token,
466477 request_id : res . locals . requestId ,
467478 } ) ;
468- res . json ( { token, symbol } ) ;
479+ sendIndexedResponse ( req , res , { token, symbol } ) ;
469480 } catch ( e : any ) {
470481 const duration = Number ( process . hrtime . bigint ( ) - start ) / 1_000_000 ;
471482 logReadTelemetry ( {
@@ -509,7 +520,7 @@ readRouter.get("/escrow/:address/balance/:agreement_id", async (req, res, next)
509520 agreement_id : agreement_id . toString ( ) ,
510521 request_id : requestId ,
511522 } ) ;
512- res . json ( {
523+ sendIndexedResponse ( req , res , {
513524 escrow : escrowAddress ,
514525 agreement_id : agreement_id . toString ( ) ,
515526 balance : u256ToString ( balance ) ,
@@ -562,7 +573,7 @@ readRouter.get("/escrow/:address/summary/:agreement_id", async (req, res, next)
562573 agreement_id : agreement_id . toString ( ) ,
563574 request_id : requestId ,
564575 } ) ;
565- res . json ( {
576+ sendIndexedResponse ( req , res , {
566577 escrow : escrowAddress ,
567578 agreement_id : agreement_id . toString ( ) ,
568579 employer : toHexString ( employer ) ,
@@ -622,7 +633,7 @@ readRouter.get("/agreement/:address/summary/:agreement_id", async (req, res, nex
622633 agreement_id : agreement_id . toString ( ) ,
623634 request_id : requestId ,
624635 } ) ;
625- res . json ( {
636+ sendIndexedResponse ( req , res , {
626637 agreement : agreementAddress ,
627638 agreement_id : agreement_id . toString ( ) ,
628639 employer : toHexString ( employer ) ,
0 commit comments