diff --git a/src/typescript/frontend/src/app/candlesticks/route.ts b/src/typescript/frontend/src/app/candlesticks/route.ts index 5a683e67d..dfcd22274 100644 --- a/src/typescript/frontend/src/app/candlesticks/route.ts +++ b/src/typescript/frontend/src/app/candlesticks/route.ts @@ -1,34 +1,110 @@ -import { type Period, toPeriod } from "@sdk/index"; +// cspell:word timespan + +import { type AnyNumberString, getPeriodStartTimeFromTime, toPeriod } from "@sdk/index"; import { parseInt } from "lodash"; import { type NextRequest } from "next/server"; import { type CandlesticksSearchParams, + type GetCandlesticksParams, getPeriodDurationSeconds, HISTORICAL_CACHE_DURATION, + indexToParcelEndDate, + indexToParcelStartDate, isValidCandlesticksSearchParams, + jsonStrAppend, NORMAL_CACHE_DURATION, + PARCEL_SIZE, + toIndex, } from "./utils"; +import { unstable_cache } from "next/cache"; import { getLatestProcessedEmojicoinTimestamp } from "@sdk/indexer-v2/queries/utils"; -import { fetchPeriodicEventsTo, tryFetchMarketRegistration } from "@/queries/market"; -import { Parcel } from "lib/parcel"; +import { parseJSON, stringifyJSON } from "utils"; +import { fetchMarketRegistration, fetchPeriodicEventsSince } from "@/queries/market"; + +/** + * @property `data` the stringified version of {@link CandlesticksDataType}. + * @property `count` the number of rows returned. + */ +type GetCandlesticksResponse = { + data: string; + count: number; +}; -type CandlesticksDataType = Awaited>; +type CandlesticksDataType = Awaited>; -const getCandlesticksParcel = async ( - { to, count }: { to: number; count: number }, - query: { marketID: number; period: Period } -) => { - const endDate = new Date(to * 1000); +const getCandlesticks = async (params: GetCandlesticksParams) => { + const { marketID, index, period } = params; - const data = await fetchPeriodicEventsTo({ - ...query, - end: endDate, - amount: count, + const start = indexToParcelStartDate(index, period); + + const periodDurationMilliseconds = getPeriodDurationSeconds(period) * 1000; + const timespan = periodDurationMilliseconds * PARCEL_SIZE; + const end = new Date(start.getTime() + timespan); + + // PARCEL_SIZE determines the max number of rows, so we don't need to pass a `LIMIT` value. + // `start` and `end` determine the level of pagination, so no need to specify `offset` either. + const data = await fetchPeriodicEventsSince({ + marketID, + period, + start, + end, }); - return data; + return { + data: stringifyJSON(data), + count: data.length, + }; }; +/** + * Returns the market registration event for a market if it exists. + * + * If it doesn't exist, it throws an error so that the value isn't cached in the + * `unstable_cache` call. + * + * @see {@link getCachedMarketRegistrationMs} + */ +const getMarketRegistrationMs = async (marketID: AnyNumberString) => + fetchMarketRegistration({ marketID }).then((res) => { + if (res) { + return Number(res.market.time / 1000n); + } + throw new Error("Market is not yet registered."); + }); + +const getCachedMarketRegistrationMs = unstable_cache( + getMarketRegistrationMs, + ["market-registrations"], + { + revalidate: HISTORICAL_CACHE_DURATION, + } +); + +/** + * Fetch all of the parcels of candlesticks that have completely ended. + * The only difference between this and {@link getNormalCachedCandlesticks} is the cache tag and + * thus how long the data is cached for. + */ +const getHistoricCachedCandlesticks = unstable_cache(getCandlesticks, ["candlesticks-historic"], { + revalidate: HISTORICAL_CACHE_DURATION, +}); + +/** + * Fetch all candlestick parcels that haven't completed yet. + * The only difference between this and {@link getHistoricCachedCandlesticks} is the cache tag and + * thus how long the data is cached for. + */ +const getNormalCachedCandlesticks = unstable_cache(getCandlesticks, ["candlesticks"], { + revalidate: NORMAL_CACHE_DURATION, +}); + +const getCachedLatestProcessedEmojicoinTimestamp = unstable_cache( + getLatestProcessedEmojicoinTimestamp, + ["processor-timestamp"], + { revalidate: 5 } +); + +/* eslint-disable-next-line import/no-unused-modules */ export async function GET(request: NextRequest) { const searchParams = request.nextUrl.searchParams; const params: CandlesticksSearchParams = { @@ -46,26 +122,70 @@ export async function GET(request: NextRequest) { const to = parseInt(params.to); const period = toPeriod(params.period); const countBack = parseInt(params.countBack); + const numParcels = parseInt(params.amount); - const queryHelper = new Parcel< - CandlesticksDataType[number], - { marketID: number; period: Period } - >({ - parcelSize: 500, - normalRevalidate: NORMAL_CACHE_DURATION, - historicRevalidate: HISTORICAL_CACHE_DURATION, - fetchHistoricThreshold: () => getLatestProcessedEmojicoinTimestamp().then((r) => r.getTime()), - fetchFirst: (query) => tryFetchMarketRegistration(query.marketID), - cacheKey: "candlesticks", - getKey: (s) => Number(s.periodicMetadata.startTime / 1000n / 1000n), - fetchFn: getCandlesticksParcel, - step: getPeriodDurationSeconds(period), - }); + const index = toIndex(to, period); + + // Ensure that the last start date as calculated per the search params is valid. + // This is specifically the last parcel's start date- aka the last parcel's first candlestick's + // start time. + const lastParcelStartDate = indexToParcelStartDate(index + numParcels - 1, period); + if (lastParcelStartDate > new Date()) { + return new Response("The last parcel's start date cannot be later than the current time.", { + status: 400, + }); + } + + let data: string = "[]"; + + const processorTimestamp = new Date(await getCachedLatestProcessedEmojicoinTimestamp()); + let totalCount = 0; + let i = 0; + + let registrationPeriodBoundaryStart: Date; try { - const data = await queryHelper.getUnparsedData(to, countBack, { marketID, period }); - return new Response(data); - } catch (e) { - return new Response(e as string, { status: 400 }); + registrationPeriodBoundaryStart = await getCachedMarketRegistrationMs(marketID).then( + (time) => new Date(Number(getPeriodStartTimeFromTime(time, period))) + ); + } catch { + return new Response("Market has not been registered yet.", { status: 400 }); } + + while (totalCount <= countBack) { + const localIndex = index - i; + const endDate = indexToParcelEndDate(localIndex, period); + let res: GetCandlesticksResponse; + if (endDate < processorTimestamp) { + res = await getHistoricCachedCandlesticks({ + marketID, + index: localIndex, + period, + }); + } else { + res = await getNormalCachedCandlesticks({ + marketID, + index: localIndex, + period, + }); + } + + if (i == 0) { + const parsed = parseJSON(res.data); + const filtered = parsed.filter( + (val) => val.periodicMetadata.startTime < BigInt(to) * 1_000_000n + ); + totalCount += filtered.length; + data = jsonStrAppend(data, stringifyJSON(filtered)); + } else { + totalCount += res.count; + data = jsonStrAppend(data, res.data); + } + if (endDate < registrationPeriodBoundaryStart) { + break; + } + i++; + } + + return new Response(data); } diff --git a/src/typescript/frontend/src/app/candlesticks/utils.ts b/src/typescript/frontend/src/app/candlesticks/utils.ts index b37d89770..f9ec73724 100644 --- a/src/typescript/frontend/src/app/candlesticks/utils.ts +++ b/src/typescript/frontend/src/app/candlesticks/utils.ts @@ -1,8 +1,47 @@ import { isPeriod, type Period, PeriodDuration, periodEnumToRawDuration } from "@sdk/index"; +import { isNumber } from "lib/utils"; + +/** + * Parcel size is the amount of candlestick periods that will be in a single parcel. + * That is, a parcel for 1m candlesticks will be `PARCEL_SIZE` minutes of time. + * + * Note that this is *NOT* the number of candlesticks in the database- as there may be gaps in the + * on-chain data (and thus the database). + * + * More specifically, each parcel will have anywhere from 0 to PARCEL_SIZE number of candlesticks + * and will always span `PARCEL_SIZE` candlesticks/periods worth of time. + */ +export const PARCEL_SIZE = 500; + +export const indexToParcelStartDate = (index: number, period: Period): Date => + new Date((PARCEL_SIZE * (index * periodEnumToRawDuration(period))) / 1000); +export const indexToParcelEndDate = (index: number, period: Period): Date => + new Date((PARCEL_SIZE * ((index + 1) * periodEnumToRawDuration(period))) / 1000); export const getPeriodDurationSeconds = (period: Period) => (periodEnumToRawDuration(period) / PeriodDuration.PERIOD_1M) * 60; +export const toIndex = (end: number, period: Period): number => { + const periodDuration = getPeriodDurationSeconds(period); + const parcelDuration = periodDuration * PARCEL_SIZE; + + const index = Math.floor(end / parcelDuration); + + return index; +}; + +export const jsonStrAppend = (a: string, b: string): string => { + if (a === "[]") return b; + if (b === "[]") return a; + return `${a.substring(0, a.length - 1)},${b.substring(1)}`; +}; + +export type GetCandlesticksParams = { + marketID: number; + index: number; + period: Period; +}; + /** * The search params used in the `GET` request at `candlesticks/api`. * @@ -29,8 +68,6 @@ export type ValidCandlesticksSearchParams = { countBack: string; }; -const isNumber = (s: string) => !isNaN(parseInt(s)); - export const isValidCandlesticksSearchParams = ( params: CandlesticksSearchParams ): params is ValidCandlesticksSearchParams => { diff --git a/src/typescript/frontend/src/app/chats/route.ts b/src/typescript/frontend/src/app/chats/route.ts deleted file mode 100644 index 7af077a61..000000000 --- a/src/typescript/frontend/src/app/chats/route.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { fetchChatEvents, tryFetchFirstChatEvent } from "@/queries/market"; -import { Parcel } from "lib/parcel"; -import type { NextRequest } from "next/server"; -import { isNumber } from "utils"; - -type ChatSearchParams = { - marketID: string | null; - toMarketNonce: string | null; -}; - -export type ValidChatSearchParams = { - marketID: string; - toMarketNonce: string; -}; - -const isValidChatSearchParams = (params: ChatSearchParams): params is ValidChatSearchParams => { - const { marketID, toMarketNonce } = params; - // prettier-ignore - return ( - marketID !== null && isNumber(marketID) && - toMarketNonce !== null && isNumber(toMarketNonce) - ); -}; - -type Chat = Awaited>[number]; - -export async function GET(request: NextRequest) { - const searchParams = request.nextUrl.searchParams; - const params: ChatSearchParams = { - marketID: searchParams.get("marketID"), - toMarketNonce: searchParams.get("toMarketNonce"), - }; - - if (!isValidChatSearchParams(params)) { - return new Response("Invalid chat search params.", { status: 400 }); - } - - const marketID = Number(params.marketID); - const toMarketNonce = Number(params.toMarketNonce); - - const queryHelper = new Parcel({ - parcelSize: 20, - normalRevalidate: 5, - historicRevalidate: 365 * 24 * 60 * 60, - fetchHistoricThreshold: (query) => - fetchChatEvents({ marketID: query.marketID, amount: 1 }).then((r) => - Number(r[0].market.marketNonce) - ), - fetchFirst: (query) => tryFetchFirstChatEvent(query.marketID), - cacheKey: "chats", - getKey: (s) => Number(s.market.marketNonce), - fetchFn: ({ to, count }, { marketID }) => - fetchChatEvents({ marketID, toMarketNonce: to, amount: count }), - }); - - const res = await queryHelper.getUnparsedData(toMarketNonce, 50, { marketID }); - - return new Response(res); -} diff --git a/src/typescript/frontend/src/app/trades/route.ts b/src/typescript/frontend/src/app/trades/route.ts deleted file mode 100644 index b91d06158..000000000 --- a/src/typescript/frontend/src/app/trades/route.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { fetchSwapEvents, tryFetchFirstSwapEvent } from "@/queries/market"; -import { Parcel } from "lib/parcel"; -import type { NextRequest } from "next/server"; -import { isNumber } from "utils"; - -type SwapSearchParams = { - marketID: string | null; - toMarketNonce: string | null; -}; - -export type ValidSwapSearchParams = { - marketID: string; - toMarketNonce: string; -}; - -const isValidSwapSearchParams = (params: SwapSearchParams): params is ValidSwapSearchParams => { - const { marketID, toMarketNonce } = params; - // prettier-ignore - return ( - marketID !== null && isNumber(marketID) && - toMarketNonce !== null && isNumber(toMarketNonce) - ); -}; - -type Swap = Awaited>[number]; - -export async function GET(request: NextRequest) { - const searchParams = request.nextUrl.searchParams; - const params: SwapSearchParams = { - marketID: searchParams.get("marketID"), - toMarketNonce: searchParams.get("toMarketNonce"), - }; - - if (!isValidSwapSearchParams(params)) { - return new Response("Invalid swap search params.", { status: 400 }); - } - - const marketID = Number(params.marketID); - const toMarketNonce = Number(params.toMarketNonce); - - const queryHelper = new Parcel({ - parcelSize: 20, - normalRevalidate: 5, - historicRevalidate: 365 * 24 * 60 * 60, - fetchHistoricThreshold: (query) => - fetchSwapEvents({ marketID: query.marketID, amount: 1 }).then((r) => - Number(r[0].market.marketNonce) - ), - fetchFirst: (query) => tryFetchFirstSwapEvent(query.marketID), - cacheKey: "swaps", - getKey: (s) => Number(s.market.marketNonce), - fetchFn: ({ to, count }, { marketID }) => - fetchSwapEvents({ marketID, toMarketNonce: to, amount: count }), - }); - - const res = await queryHelper.getUnparsedData(toMarketNonce, 20, { marketID }); - - return new Response(res); -} diff --git a/src/typescript/frontend/src/lib/parcel.ts b/src/typescript/frontend/src/lib/parcel.ts deleted file mode 100644 index 9708657af..000000000 --- a/src/typescript/frontend/src/lib/parcel.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { unstable_cache } from "next/cache"; -import { parseJSON, stringifyJSON } from "utils"; - -const jsonStrAppend = (a: string, b: string): string => { - if (a === "[]") return b; - if (b === "[]") return a; - return `${a.substring(0, a.length - 1)},${b.substring(1)}`; -}; - -export type ParcelQueryParameters = { - count: number; - to: number; -}; - -type CachedWrapperReturn = { - stringifiedData: string; - length: number; - first: number; -}; - -const cachedWrapper = async ( - params: ParcelQueryParameters, - query: Q, - fetchFn: (params: ParcelQueryParameters, query: Q) => Promise, - getKey: (s: S) => number -): Promise => { - const data = await fetchFn(params, query); - return { - stringifiedData: stringifyJSON(data), - length: data.length, - first: getKey(data[data.length - 1]), - }; -}; - -// Parcel data query helper. -// -// This class is a query helper to query cached parcels. -// -// The helper separates data in parcels, making data easier to cache and query in batch. -export class Parcel { - private _parcelSize: number; - private _normalFetch: (params: ParcelQueryParameters, query: Q) => Promise; - private _historicFetch: (params: ParcelQueryParameters, query: Q) => Promise; - private _fetchHistoricThreshold: (query: Q) => Promise; - private _fetchFirst: (query: Q) => Promise; - private _getKey: (s: S) => number; - private _step: number; - private _cacheKey: string; - - constructor({ - parcelSize, - cacheKey, - fetchFn, - normalRevalidate, - historicRevalidate, - fetchHistoricThreshold, - fetchFirst, - getKey, - step, - }: { - parcelSize: number; - cacheKey: string; - fetchFn: (params: ParcelQueryParameters, query: Q) => Promise; - normalRevalidate: number; - historicRevalidate: number; - fetchHistoricThreshold: (query: Q) => Promise; - fetchFirst: (query: Q) => Promise; - getKey: (s: S) => number; - step?: number; - }) { - this._parcelSize = parcelSize; - this._normalFetch = unstable_cache( - (params: ParcelQueryParameters, query: Q) => cachedWrapper(params, query, fetchFn, getKey), - ["parcel", cacheKey, "normal", parcelSize.toString()], - { revalidate: normalRevalidate } - ); - this._historicFetch = unstable_cache( - (params: ParcelQueryParameters, query: Q) => cachedWrapper(params, query, fetchFn, getKey), - ["parcel", cacheKey, "historic", parcelSize.toString()], - { revalidate: historicRevalidate } - ); - this._fetchHistoricThreshold = unstable_cache( - (query: Q) => fetchHistoricThreshold(query), - ["parcel", cacheKey, "threshold"], - { revalidate: 2 } - ); - this._fetchFirst = unstable_cache( - (query: Q) => fetchFirst(query), - ["parcel", cacheKey, "first"], - { revalidate: 365 * 24 * 60 * 60 } - ); - this._getKey = getKey; - this._step = step ?? 1; - this._cacheKey = cacheKey; - } - - private parcelize(to: number): number { - return Math.floor(to / this._step / this._parcelSize); - } - - private unparcelize(parcel: number): number { - return parcel * this._step * this._parcelSize; - } - - async getData(to: number, count: number, query: Q): Promise { - return parseJSON(await this.getUnparsedData(to, count, query)); - } - - async getUnparsedData(to: number, count: number, query: Q): Promise { - let first: number; - try { - first = await this._fetchFirst(query); - } catch (e) { - console.warn( - "Could not get first event. This either means that no events have yet been emmited for this data type, or that the fetch first event function is wrong.", - e - ); - return "[]"; - } - if (to < first) { - return "[]"; - } - const lastParcel = this.parcelize(to); - let dataCount = 0; - const historicThreshold = await this._fetchHistoricThreshold(query); - let lastParcelData: CachedWrapperReturn; - const end = this.unparcelize(lastParcel + 1); - if (this.unparcelize(lastParcel + 1) > historicThreshold) { - lastParcelData = await this._normalFetch({ to: end, count: this._parcelSize }, query); - } else { - lastParcelData = await this._historicFetch({ to: end, count: this._parcelSize }, query); - } - const parsedLastParcel = parseJSON(lastParcelData.stringifiedData); - const relevantData = parsedLastParcel.filter((s) => this._getKey(s) < to); - dataCount += relevantData.length; - let dataString = lastParcelData.stringifiedData; - let parcel = this.parcelize(lastParcelData.first) - 1; - for (; dataCount < count && this.unparcelize(parcel) > first; ) { - const start = this.unparcelize(parcel); - const params = { - to: start + this._parcelSize, - count: this._parcelSize, - }; - const parcelData = await this._historicFetch(params, query); - dataCount += parcelData.length; - dataString = jsonStrAppend(dataString, parcelData.stringifiedData); - parcel = this.parcelize(parcelData.first) - 1; - } - return dataString; - } -} diff --git a/src/typescript/sdk/src/indexer-v2/queries/app/market.ts b/src/typescript/sdk/src/indexer-v2/queries/app/market.ts index 8141a6e12..2afd7c107 100644 --- a/src/typescript/sdk/src/indexer-v2/queries/app/market.ts +++ b/src/typescript/sdk/src/indexer-v2/queries/app/market.ts @@ -2,7 +2,7 @@ if (process.env.NODE_ENV !== "test") { require("server-only"); } -import { ORDER_BY } from "../../../queries"; +import { LIMIT, ORDER_BY } from "../../../queries"; import { type AnyNumberString } from "../../../types"; import { TableName } from "../../types/json-types"; import { postgrest, toQueryArray } from "../client"; @@ -14,103 +14,32 @@ import { toPeriodicStateEventModel, toSwapEventModel, } from "../../types"; -import type { - PeriodicStateEventToQueryArgs, - PeriodicStateEventQueryArgs, -} from "../../types/common"; +import { type PeriodicStateEventQueryArgs, type MarketStateQueryArgs } from "../../types/common"; import { type SymbolEmoji } from "../../../emoji_data/types"; const selectSwapsByMarketID = ({ marketID, - toMarketNonce = null, - amount = 20, - order = "DESC", -}: { - marketID: AnyNumberString; - toMarketNonce?: number | null; - amount?: number; - order?: keyof typeof ORDER_BY; -}) => { - if (toMarketNonce !== null) { - return postgrest - .from(TableName.SwapEvents) - .select("*") - .eq("market_id", marketID) - .lte("market_nonce", toMarketNonce) - .order("market_nonce", ORDER_BY[order]) - .limit(amount); - } - return postgrest - .from(TableName.SwapEvents) - .select("*") - .eq("market_id", marketID) - .order("market_nonce", ORDER_BY[order]) - .limit(amount); -}; - -const selectSwapsByNonce = ({ - marketID, - fromMarketNonce, - toMarketNonce, -}: { - marketID: AnyNumberString; - fromMarketNonce: number; - toMarketNonce: number; -}) => { - return postgrest + page = 1, + pageSize = LIMIT, +}: { marketID: AnyNumberString } & MarketStateQueryArgs) => + postgrest .from(TableName.SwapEvents) .select("*") - .lt("market_nonce", toMarketNonce) - .gte("market_nonce", fromMarketNonce) .eq("market_id", marketID) - .order("market_nonce", ORDER_BY.DESC); -}; + .order("market_nonce", ORDER_BY.DESC) + .range((page - 1) * pageSize, page * pageSize - 1); const selectChatsByMarketID = ({ marketID, - toMarketNonce = null, - amount = 20, - order = "DESC", -}: { - marketID: AnyNumberString; - toMarketNonce?: number | null; - amount?: number; - order?: keyof typeof ORDER_BY; -}) => { - if (toMarketNonce !== null) { - return postgrest - .from(TableName.ChatEvents) - .select("*") - .eq("market_id", marketID) - .lte("market_nonce", toMarketNonce) - .order("market_nonce", ORDER_BY[order]) - .limit(amount); - } - return postgrest - .from(TableName.ChatEvents) - .select("*") - .eq("market_id", marketID) - .order("market_nonce", ORDER_BY[order]) - .limit(amount); -}; - -const selectChatsByNonce = ({ - marketID, - fromMarketNonce, - toMarketNonce, -}: { - marketID: AnyNumberString; - fromMarketNonce: number; - toMarketNonce: number; -}) => { - return postgrest + page = 1, + pageSize = LIMIT, +}: { marketID: AnyNumberString } & MarketStateQueryArgs) => + postgrest .from(TableName.ChatEvents) .select("*") - .lt("market_nonce", toMarketNonce) - .gte("market_nonce", fromMarketNonce) .eq("market_id", marketID) - .order("market_nonce", ORDER_BY.DESC); -}; + .order("market_nonce", ORDER_BY.DESC) + .range((page - 1) * pageSize, page * pageSize - 1); // This query uses `offset` instead of `page` because the periodic state events query requires // more granular pagination due to the requirements of the private TradingView charting library. @@ -131,23 +60,6 @@ const selectPeriodicEventsSince = ({ return query; }; -const selectPeriodicEventsTo = ({ - marketID, - period, - end, - amount, -}: PeriodicStateEventToQueryArgs) => { - const query = postgrest - .from(TableName.PeriodicStateEvents) - .select("*") - .eq("market_id", marketID) - .eq("period", period) - .lt("start_time", end.toISOString()) - .limit(amount) - .order("start_time", ORDER_BY.DESC); - return query; -}; - const selectMarketState = ({ searchEmojis }: { searchEmojis: SymbolEmoji[] }) => postgrest .from(TableName.MarketState) @@ -165,40 +77,13 @@ const selectMarketRegistration = ({ marketID }: { marketID: AnyNumberString }) = .single(); export const fetchSwapEvents = queryHelper(selectSwapsByMarketID, toSwapEventModel); -export const fetchSwapEventsByNonce = queryHelper(selectSwapsByNonce, toSwapEventModel); export const fetchChatEvents = queryHelper(selectChatsByMarketID, toChatEventModel); -export const fetchChatEventsByNonce = queryHelper(selectChatsByNonce, toChatEventModel); export const fetchPeriodicEventsSince = queryHelper( selectPeriodicEventsSince, toPeriodicStateEventModel ); -export const fetchPeriodicEventsTo = queryHelper(selectPeriodicEventsTo, toPeriodicStateEventModel); export const fetchMarketState = queryHelperSingle(selectMarketState, toMarketStateModel); export const fetchMarketRegistration = queryHelperSingle( selectMarketRegistration, toMarketRegistrationEventModel ); - -export const tryFetchMarketRegistration = async (marketID: AnyNumberString) => - fetchMarketRegistration({ marketID }).then((res) => { - if (res) { - return Number(res.market.time / 1000n / 1000n); - } - throw new Error("Market is not yet registered."); - }); - -export const tryFetchFirstChatEvent = async (marketID: AnyNumberString) => - fetchChatEvents({ marketID, amount: 1, order: "ASC" }).then((res) => { - if (res && res[0]) { - return Number(res[0].market.marketNonce); - } - throw new Error("Market is not yet registered."); - }); - -export const tryFetchFirstSwapEvent = async (marketID: AnyNumberString) => - fetchSwapEvents({ marketID, amount: 1, order: "ASC" }).then((res) => { - if (res && res[0]) { - return Number(res[0].market.marketNonce); - } - throw new Error("Market is not yet registered."); - }); diff --git a/src/typescript/sdk/src/indexer-v2/types/common.ts b/src/typescript/sdk/src/indexer-v2/types/common.ts index d8a20e567..4f4ed1679 100644 --- a/src/typescript/sdk/src/indexer-v2/types/common.ts +++ b/src/typescript/sdk/src/indexer-v2/types/common.ts @@ -30,10 +30,3 @@ export type PeriodicStateEventQueryArgs = { end: Date; period: Period; } & Omit; - -export type PeriodicStateEventToQueryArgs = { - marketID: AnyNumberString; - amount: number; - end: Date; - period: Period; -} & Omit;