Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions sdks/typescript/pmxt/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,58 @@ export abstract class Exchange {
return response.json();
}

/**
* Pre-warm the sidecar's internal caches for a market outcome.
*
* @param outcomeId - The CLOB token ID for the outcome.
*/
async preWarmMarket(outcomeId: string): Promise<void> {
await this.initPromise;
try {
const json = await this.sidecarPostRequest("preWarmMarket", [outcomeId]);
this.handleResponse(json);
} catch (error) {
if (error instanceof PmxtError) throw error;
throw new PmxtError(`Failed to preWarmMarket: ${error}`);
}
}

/**
* Fetch a single Probable event by its numeric ID.
*
* @param id - The numeric event ID.
* @returns The event, or null when the venue has no matching event.
*/
async getEventById(id: string): Promise<UnifiedEvent | null> {
await this.initPromise;
try {
const json = await this.sidecarPostRequest("getEventById", [id]);
const data = this.handleResponse(json);
return data == null ? null : convertEvent(data);
} catch (error) {
if (error instanceof PmxtError) throw error;
throw new PmxtError(`Failed to getEventById: ${error}`);
}
}

/**
* Fetch a single Probable event by its URL slug.
*
* @param slug - The event slug.
* @returns The event, or null when the venue has no matching event.
*/
async getEventBySlug(slug: string): Promise<UnifiedEvent | null> {
await this.initPromise;
try {
const json = await this.sidecarPostRequest("getEventBySlug", [slug]);
const data = this.handleResponse(json);
return data == null ? null : convertEvent(data);
} catch (error) {
if (error instanceof PmxtError) throw error;
throw new PmxtError(`Failed to getEventBySlug: ${error}`);
}
}

/**
* Read a hosted catalog endpoint directly.
*
Expand Down
78 changes: 78 additions & 0 deletions sdks/typescript/tests/event-methods.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { Polymarket, Probable } from "../pmxt/client";

interface CapturedFetch {
url: string;
init?: RequestInit;
}

function installFetchSpy(handler: (req: CapturedFetch) => Response): jest.SpyInstance {
const captured: CapturedFetch[] = [];
const spy = jest.spyOn(global, "fetch").mockImplementation(async (input, init) => {
const url = typeof input === "string" ? input : (input as URL | Request).toString();
const rec: CapturedFetch = { url, init };
captured.push(rec);
return handler(rec);
});
(spy as unknown as { captured: CapturedFetch[] }).captured = captured;
return spy;
}

function captured(spy: jest.SpyInstance): CapturedFetch[] {
return (spy as unknown as { captured: CapturedFetch[] }).captured;
}

function jsonResponse(payload: unknown): Response {
return new Response(JSON.stringify(payload), {
status: 200,
headers: { "Content-Type": "application/json" },
});
}

afterEach(() => {
jest.restoreAllMocks();
});

describe("event-specific SDK methods", () => {
it("preWarmMarket dispatches the documented sidecar method", async () => {
const spy = installFetchSpy(() => jsonResponse({ success: true, data: null }));
const api = new Polymarket({ baseUrl: "http://sidecar.test", autoStartServer: false });

await api.preWarmMarket("12345");

const reqs = captured(spy);
expect(reqs).toHaveLength(1);
expect(reqs[0].url).toBe("http://sidecar.test/api/polymarket/preWarmMarket");
expect(reqs[0].init?.method).toBe("POST");
expect(JSON.parse(reqs[0].init?.body as string)).toEqual({
args: ["12345"],
});
});

it("getEventById returns null without conversion when sidecar returns null", async () => {
installFetchSpy(() => jsonResponse({ success: true, data: null }));
const api = new Probable({ baseUrl: "http://sidecar.test", autoStartServer: false });

await expect(api.getEventById("180")).resolves.toBeNull();
});

it("getEventBySlug converts returned event markets", async () => {
const spy = installFetchSpy(() => jsonResponse({
success: true,
data: {
id: "180",
title: "Example event",
markets: [
{ id: "m1", title: "Will it happen?", outcomes: [] },
],
},
}));
const api = new Probable({ baseUrl: "http://sidecar.test", autoStartServer: false });

const event = await api.getEventBySlug("example-event");

expect(event?.title).toBe("Example event");
expect(event?.markets).toHaveLength(1);
expect(captured(spy)[0].url).toBe("http://sidecar.test/api/probable/getEventBySlug");
expect(JSON.parse(captured(spy)[0].init?.body as string).args).toEqual(["example-event"]);
});
});
Loading