From 358aee1bc7a04ebadb0072d50928689589a8dd57 Mon Sep 17 00:00:00 2001 From: Uddhav <255779543+letstokenize@users.noreply.github.com> Date: Tue, 31 Mar 2026 15:11:15 -0700 Subject: [PATCH 1/3] fix(docs): restore index supply query examples Co-Authored-By: Uddhav <255779543+letstokenize@users.noreply.github.com> --- env.d.ts | 1 + src/components/IndexSupplyQuery.tsx | 11 ++- src/components/lib/IndexSupply.ts | 2 + src/pages/_api/api/index-supply.ts | 32 +++++++-- .../stablecoin-dex/view-the-orderbook.mdx | 71 +++++++++++-------- 5 files changed, 81 insertions(+), 36 deletions(-) diff --git a/env.d.ts b/env.d.ts index 5a86c157..b0199a77 100644 --- a/env.d.ts +++ b/env.d.ts @@ -2,6 +2,7 @@ interface EnvironmentVariables { readonly NODE_ENV: 'development' | 'production' | 'test' readonly VITE_BASE_URL: string + readonly VITE_INDEXSUPPLY_API_KEY?: [REDACTED:api-key] readonly VITE_POSTHOG_KEY: string readonly VITE_POSTHOG_HOST: string readonly VITE_TEMPO_ENV: 'localnet' | 'devnet' | 'moderato' diff --git a/src/components/IndexSupplyQuery.tsx b/src/components/IndexSupplyQuery.tsx index 6df8045c..20b8fc8a 100644 --- a/src/components/IndexSupplyQuery.tsx +++ b/src/components/IndexSupplyQuery.tsx @@ -57,6 +57,7 @@ const EVM_TABLE_COLUMNS = { } as const type IndexSupplyQueryProps = { + chainId?: number signatures?: string[] query?: string title?: string @@ -207,7 +208,10 @@ export function IndexSupplyQuery(props: IndexSupplyQueryProps = {}) { setResult(null) try { - const options = signatures.length > 0 ? { signatures } : {} + const options = { + chainId: props.chainId, + ...(signatures.length > 0 ? { signatures } : {}), + } const queryResult = await runIndexSupplyQuery(queryToRun, options) setResult(queryResult) } catch (err) { @@ -230,7 +234,10 @@ export function IndexSupplyQuery(props: IndexSupplyQueryProps = {}) { setError(null) setResult(null) - runIndexSupplyQuery(queryToRun, signatures.length > 0 ? { signatures } : {}) + runIndexSupplyQuery(queryToRun, { + chainId: props.chainId, + ...(signatures.length > 0 ? { signatures } : {}), + }) .then((queryResult) => { setResult(queryResult) }) diff --git a/src/components/lib/IndexSupply.ts b/src/components/lib/IndexSupply.ts index 400cea1b..6d6bdbe0 100644 --- a/src/components/lib/IndexSupply.ts +++ b/src/components/lib/IndexSupply.ts @@ -43,6 +43,7 @@ export function toAddressValue(value: RowValue | null | undefined): Address.Addr } type RunQueryOptions = { + chainId?: number signatures?: string[] } @@ -53,6 +54,7 @@ export async function runIndexSupplyQuery(query: string, options: RunQueryOption 'content-type': 'application/json', }, body: JSON.stringify({ + chainId: options.chainId, query: query.replace(/\s+/g, ' ').trim(), signatures: options.signatures, }), diff --git a/src/pages/_api/api/index-supply.ts b/src/pages/_api/api/index-supply.ts index b796567e..2ebc05d6 100644 --- a/src/pages/_api/api/index-supply.ts +++ b/src/pages/_api/api/index-supply.ts @@ -1,6 +1,7 @@ -import { tempo } from 'viem/chains' +import { tempo, tempoDevnet, tempoLocalnet, tempoModerato } from 'viem/chains' type QueryRequest = { + chainId?: number query: string signatures?: string[] } @@ -35,9 +36,19 @@ export async function POST(request: Request): Promise { ) } - const apiKey = import.meta.env.VITE_INDEXSUPPLY_API_KEY + if (body.chainId !== undefined && (!Number.isInteger(body.chainId) || body.chainId <= 0)) { + return Response.json( + { error: 'Invalid request: chainId must be a positive integer' }, + { status: 400, headers: corsHeaders }, + ) + } + + const apiKey = + process.env.INDEXSUPPLY_API_KEY || + import.meta.env.INDEXSUPPLY_API_KEY || + import.meta.env.VITE_INDEXSUPPLY_API_KEY if (!apiKey) { - console.error('VITE_INDEXSUPPLY_API_KEY is not configured') + console.error('INDEXSUPPLY_API_KEY is not configured') return Response.json( { error: 'Server configuration error: API key not found' }, { status: 500, headers: corsHeaders }, @@ -51,7 +62,7 @@ export async function POST(request: Request): Promise { const signatures = body.signatures && body.signatures.length > 0 ? body.signatures : [''] - const chainId = tempo.id + const chainId = body.chainId ?? getDefaultChainId() const chainCursor = `${chainId}-0` const response = await fetch(url.toString(), { @@ -130,3 +141,16 @@ function cors(origin: string | null): Record { return headers } + +function getDefaultChainId() { + switch (import.meta.env.VITE_TEMPO_ENV) { + case 'localnet': + return tempoLocalnet.id + case 'devnet': + return tempoDevnet.id + case 'mainnet': + return tempo.id + default: + return tempoModerato.id + } +} diff --git a/src/pages/guide/stablecoin-dex/view-the-orderbook.mdx b/src/pages/guide/stablecoin-dex/view-the-orderbook.mdx index 3666a078..e6e53f64 100644 --- a/src/pages/guide/stablecoin-dex/view-the-orderbook.mdx +++ b/src/pages/guide/stablecoin-dex/view-the-orderbook.mdx @@ -21,15 +21,18 @@ In this guide, we use [Index Supply](https://www.indexsupply.net) as our indexin Query the best bid and ask prices to calculate the current spread for a token pair. -Find the highest bid prices (buyers) for PathUSD. This query filters out fully filled and cancelled orders, groups by price level (tick), and shows the top 5 bid prices with their total liquidity. +These examples use the mainnet `USDC.e` orderbook. In the DEX event data, the `token` column stores the traded asset, so each query filters directly on the `USDC.e` token address. + +Find the highest bid prices (buyers) for `USDC.e`. This query filters out fully filled and cancelled orders, groups by price level (tick), and shows the top 5 bid prices with their total liquidity. -Find the lowest ask prices (sellers) for PathUSD. The spread is the difference between the highest bid and lowest ask price. +Find the lowest ask prices (sellers) for `USDC.e`. The spread is the difference between the highest bid and lowest ask price. #### Cancelled orders -Check if an order has been cancelled. This query returns an order for PathUSD that was explicitly cancelled by the maker before being fully filled. +Check if a `USDC.e` order has been cancelled. This query returns a recent `USDC.e` order that was explicitly cancelled by the maker before being fully filled. @@ -170,10 +180,11 @@ Check if an order has been cancelled. This query returns an order for PathUSD th View the last prices a token traded at to understand recent market activity. -This query joins order fill events with their corresponding placement details to show the price tick and amount for recent trades. +This query joins order fill events with their corresponding placement details to show the price tick and amount for recent `USDC.e` trades. Date: Tue, 31 Mar 2026 15:47:25 -0700 Subject: [PATCH 2/3] docs: simplify quote token note Co-Authored-By: Uddhav <255779543+letstokenize@users.noreply.github.com> --- .../guide/stablecoin-dex/view-the-orderbook.mdx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pages/guide/stablecoin-dex/view-the-orderbook.mdx b/src/pages/guide/stablecoin-dex/view-the-orderbook.mdx index e6e53f64..c151d7b7 100644 --- a/src/pages/guide/stablecoin-dex/view-the-orderbook.mdx +++ b/src/pages/guide/stablecoin-dex/view-the-orderbook.mdx @@ -21,9 +21,9 @@ In this guide, we use [Index Supply](https://www.indexsupply.net) as our indexin Query the best bid and ask prices to calculate the current spread for a token pair. -These examples use the mainnet `USDC.e` orderbook. In the DEX event data, the `token` column stores the traded asset, so each query filters directly on the `USDC.e` token address. +These examples use the mainnet `USDC.e / pathUSD` orderbook; `pathUSD` is the quote token for `USDC.e` — see [Quote Tokens](/protocol/exchange/quote-tokens). -Find the highest bid prices (buyers) for `USDC.e`. This query filters out fully filled and cancelled orders, groups by price level (tick), and shows the top 5 bid prices with their total liquidity. +Find the highest bid prices (buyers) for the `USDC.e / pathUSD` book. This query filters out fully filled and cancelled orders, groups by price level (tick), and shows the top 5 bid prices with their total liquidity. -Find the lowest ask prices (sellers) for `USDC.e`. The spread is the difference between the highest bid and lowest ask price. +Find the lowest ask prices (sellers) for the `USDC.e / pathUSD` book. The spread is the difference between the highest bid and lowest ask price. Date: Tue, 31 Mar 2026 15:56:24 -0700 Subject: [PATCH 3/3] refactor(docs): require explicit index supply config Co-Authored-By: Uddhav <255779543+letstokenize@users.noreply.github.com> --- env.d.ts | 1 - src/components/IndexSupplyQuery.tsx | 4 ++-- src/components/lib/IndexSupply.ts | 4 ++-- src/pages/_api/api/index-supply.ts | 29 +++++------------------------ 4 files changed, 9 insertions(+), 29 deletions(-) diff --git a/env.d.ts b/env.d.ts index b0199a77..5a86c157 100644 --- a/env.d.ts +++ b/env.d.ts @@ -2,7 +2,6 @@ interface EnvironmentVariables { readonly NODE_ENV: 'development' | 'production' | 'test' readonly VITE_BASE_URL: string - readonly VITE_INDEXSUPPLY_API_KEY?: [REDACTED:api-key] readonly VITE_POSTHOG_KEY: string readonly VITE_POSTHOG_HOST: string readonly VITE_TEMPO_ENV: 'localnet' | 'devnet' | 'moderato' diff --git a/src/components/IndexSupplyQuery.tsx b/src/components/IndexSupplyQuery.tsx index 20b8fc8a..7bec084d 100644 --- a/src/components/IndexSupplyQuery.tsx +++ b/src/components/IndexSupplyQuery.tsx @@ -57,7 +57,7 @@ const EVM_TABLE_COLUMNS = { } as const type IndexSupplyQueryProps = { - chainId?: number + chainId: number signatures?: string[] query?: string title?: string @@ -133,7 +133,7 @@ function renderCellValue(cell: string | number | boolean | null): React.ReactNod ) } -export function IndexSupplyQuery(props: IndexSupplyQueryProps = {}) { +export function IndexSupplyQuery(props: IndexSupplyQueryProps) { const isReadOnly = props.query !== undefined const allSignatures = React.useMemo(() => getAllSignatures(), []) diff --git a/src/components/lib/IndexSupply.ts b/src/components/lib/IndexSupply.ts index 6d6bdbe0..bceb76a0 100644 --- a/src/components/lib/IndexSupply.ts +++ b/src/components/lib/IndexSupply.ts @@ -43,11 +43,11 @@ export function toAddressValue(value: RowValue | null | undefined): Address.Addr } type RunQueryOptions = { - chainId?: number + chainId: number signatures?: string[] } -export async function runIndexSupplyQuery(query: string, options: RunQueryOptions = {}) { +export async function runIndexSupplyQuery(query: string, options: RunQueryOptions) { const response = await fetch('/api/index-supply', { method: 'POST', headers: { diff --git a/src/pages/_api/api/index-supply.ts b/src/pages/_api/api/index-supply.ts index 2ebc05d6..ed8f4782 100644 --- a/src/pages/_api/api/index-supply.ts +++ b/src/pages/_api/api/index-supply.ts @@ -1,7 +1,5 @@ -import { tempo, tempoDevnet, tempoLocalnet, tempoModerato } from 'viem/chains' - type QueryRequest = { - chainId?: number + chainId: number query: string signatures?: string[] } @@ -36,17 +34,14 @@ export async function POST(request: Request): Promise { ) } - if (body.chainId !== undefined && (!Number.isInteger(body.chainId) || body.chainId <= 0)) { + if (!Number.isInteger(body.chainId) || body.chainId <= 0) { return Response.json( - { error: 'Invalid request: chainId must be a positive integer' }, + { error: 'Invalid request: chainId is required and must be a positive integer' }, { status: 400, headers: corsHeaders }, ) } - const apiKey = - process.env.INDEXSUPPLY_API_KEY || - import.meta.env.INDEXSUPPLY_API_KEY || - import.meta.env.VITE_INDEXSUPPLY_API_KEY + const apiKey = process.env.INDEXSUPPLY_API_KEY if (!apiKey) { console.error('INDEXSUPPLY_API_KEY is not configured') return Response.json( @@ -62,8 +57,7 @@ export async function POST(request: Request): Promise { const signatures = body.signatures && body.signatures.length > 0 ? body.signatures : [''] - const chainId = body.chainId ?? getDefaultChainId() - const chainCursor = `${chainId}-0` + const chainCursor = `${body.chainId}-0` const response = await fetch(url.toString(), { method: 'POST', @@ -141,16 +135,3 @@ function cors(origin: string | null): Record { return headers } - -function getDefaultChainId() { - switch (import.meta.env.VITE_TEMPO_ENV) { - case 'localnet': - return tempoLocalnet.id - case 'devnet': - return tempoDevnet.id - case 'mainnet': - return tempo.id - default: - return tempoModerato.id - } -}