import { rateLimiter, EndpointCategory } from "./rate-limiter.js";
import { getConfig } from "./config.js";
const cfg = getConfig();
const GAMMA_BASE = cfg.gammaApiUrl;
export interface GammaMarket {
id: string;
question: string;
slug: string;
conditionId: string;
description: string;
outcomes: string;
outcomePrices: string;
volume: string;
volume24hr: string;
liquidity: string;
startDate: string;
endDate: string;
active: boolean;
closed: boolean;
featured: boolean;
archived: boolean;
createdAt: string;
updatedAt: string;
clobTokenIds: string;
tags: Array<{ id: number; label: string; slug: string }>;
events: Array<{ id: string; slug: string; title: string }>;
[key: string]: unknown;
}
export interface GammaEvent {
id: string;
slug: string;
title: string;
description: string;
markets: GammaMarket[];
[key: string]: unknown;
}
export async function gammaFetch<T>(
path: string,
params: Record<string, string | number | boolean | undefined> = {},
): Promise<T> {
await rateLimiter.acquire(EndpointCategory.GAMMA_API);
const url = new URL(path, GAMMA_BASE);
for (const [k, v] of Object.entries(params)) {
if (v !== undefined) url.searchParams.set(k, String(v));
}
const res = await fetch(url.toString());
if (!res.ok) {
throw new Error(`Gamma API error: ${res.status} ${res.statusText}`);
}
return (await res.json()) as T;
}
export async function fetchMarkets(params: {
limit?: number;
offset?: number;
order?: string;
ascending?: boolean;
active?: boolean;
closed?: boolean;
tag_slug?: string;
featured?: boolean;
end_date_min?: string;
end_date_max?: string;
}): Promise<GammaMarket[]> {
return gammaFetch<GammaMarket[]>("/markets", params as Record<string, string | number | boolean>);
}
export async function fetchEvents(params: {
limit?: number;
slug?: string;
id?: string;
}): Promise<GammaEvent[]> {
return gammaFetch<GammaEvent[]>("/events", params as Record<string, string | number | boolean>);
}
export async function fetchMarketById(id: string): Promise<GammaMarket> {
return gammaFetch<GammaMarket>(`/markets/${id}`);
}
export async function fetchEventById(id: string): Promise<GammaEvent> {
return gammaFetch<GammaEvent>(`/events/${id}`);
}
export async function fetchSeries(params: {
limit?: number;
offset?: number;
} = {}): Promise<unknown[]> {
return gammaFetch<unknown[]>("/series", params as Record<string, string | number | boolean>);
}
export async function fetchSeriesById(id: string): Promise<unknown> {
return gammaFetch<unknown>(`/series/${id}`);
}
export async function fetchSportsMetadata(): Promise<unknown> {
return gammaFetch<unknown>("/sports");
}
export async function fetchTeams(params: {
limit?: number;
offset?: number;
} = {}): Promise<unknown[]> {
return gammaFetch<unknown[]>("/teams", params as Record<string, string | number | boolean>);
}
export async function fetchPublicProfile(address: string): Promise<unknown> {
return gammaFetch<unknown>("/public-profile", { address });
}
export async function fetchComments(params: {
limit?: number;
offset?: number;
user?: string;
market?: string;
order?: string;
ascending?: boolean;
parent_entity_type?: "Event" | "Series" | "market";
parent_entity_id?: number;
get_positions?: boolean;
holders_only?: boolean;
} = {}): Promise<unknown[]> {
return gammaFetch<unknown[]>("/comments", params as Record<string, string | number | boolean>);
}
export async function fetchCommentById(id: string): Promise<unknown> {
return gammaFetch<unknown>(`/comments/${id}`);
}
export async function fetchValidSportsMarketTypes(): Promise<unknown> {
return gammaFetch<unknown>("/sports/market-types");
}
export async function checkGammaHealth(): Promise<unknown> {
await rateLimiter.acquire(EndpointCategory.GAMMA_API);
const url = new URL("/status", GAMMA_BASE);
const res = await fetch(url.toString());
if (!res.ok) {
throw new Error(`Gamma API error: ${res.status} ${res.statusText}`);
}
return await res.text();
}