diff --git a/sdks/typescript/pmxt/client.ts b/sdks/typescript/pmxt/client.ts index 666a71de..9c90e752 100644 --- a/sdks/typescript/pmxt/client.ts +++ b/sdks/typescript/pmxt/client.ts @@ -3162,6 +3162,75 @@ export class Limitless extends Exchange { constructor(options: ExchangeOptions = {}) { super("limitless", options); } + + /** + * Watch real-time AMM price updates via WebSocket. + * + * @param marketAddress - Limitless market contract address + * @param callback - Optional callback invoked with the returned update + * @returns Next price update + */ + async watchPrices( + marketAddress: string, + callback?: (data: Record) => void, + ): Promise> { + await this.initPromise; + try { + const json = await this.sidecarPostRequest("watchPrices", [marketAddress]); + const data = this.handleResponse(json); + callback?.(data); + return data; + } catch (error) { + if (error instanceof PmxtError) throw error; + throw new PmxtError(`Failed to watch prices: ${error}`); + } + } + + /** + * Watch real-time Limitless user position updates. + * + * Requires API key authentication. + * + * @param callback - Optional callback invoked with the returned positions + * @returns Next position update payload + */ + async watchUserPositions( + callback?: (data: Position[]) => void, + ): Promise { + await this.initPromise; + try { + const json = await this.sidecarPostRequest("watchUserPositions", []); + const data = this.handleResponse(json).map(convertPosition); + callback?.(data); + return data; + } catch (error) { + if (error instanceof PmxtError) throw error; + throw new PmxtError(`Failed to watch user positions: ${error}`); + } + } + + /** + * Watch real-time Limitless user transaction updates. + * + * Requires API key authentication. + * + * @param callback - Optional callback invoked with the returned update + * @returns Next transaction update + */ + async watchUserTransactions( + callback?: (data: Record) => void, + ): Promise> { + await this.initPromise; + try { + const json = await this.sidecarPostRequest("watchUserTransactions", []); + const data = this.handleResponse(json); + callback?.(data); + return data; + } catch (error) { + if (error instanceof PmxtError) throw error; + throw new PmxtError(`Failed to watch user transactions: ${error}`); + } + } } /** diff --git a/sdks/typescript/tests/limitless-watch-methods.test.ts b/sdks/typescript/tests/limitless-watch-methods.test.ts new file mode 100644 index 00000000..700a55f9 --- /dev/null +++ b/sdks/typescript/tests/limitless-watch-methods.test.ts @@ -0,0 +1,44 @@ +import { Limitless } from '../pmxt/client'; + +describe('Limitless watch methods', () => { + function makeClient(responseData: unknown) { + const client: any = new Limitless({ autoStartServer: false }); + client.sidecarPostRequest = jest.fn(async (method: string, args: unknown[]) => ({ + success: true, + data: responseData, + _method: method, + _args: args, + })); + return client; + } + + it('forwards watchPrices to the Limitless sidecar endpoint and invokes the callback', async () => { + const payload = { marketAddress: '0xabc', updatedPrices: { YES: '0.42' } }; + const client = makeClient(payload); + const callback = jest.fn(); + + await expect(client.watchPrices('0xabc', callback)).resolves.toEqual(payload); + expect(client.sidecarPostRequest).toHaveBeenCalledWith('watchPrices', ['0xabc']); + expect(callback).toHaveBeenCalledWith(payload); + }); + + it('forwards watchUserPositions with credentials and converts returned positions', async () => { + const positions = [{ marketId: 'm1', outcomeId: 'yes', size: 1 }]; + const client = makeClient(positions); + const callback = jest.fn(); + + await expect(client.watchUserPositions(callback)).resolves.toEqual(positions); + expect(client.sidecarPostRequest).toHaveBeenCalledWith('watchUserPositions', []); + expect(callback).toHaveBeenCalledWith(positions); + }); + + it('forwards watchUserTransactions and invokes the callback', async () => { + const transaction = { hash: '0x123', status: 'confirmed' }; + const client = makeClient(transaction); + const callback = jest.fn(); + + await expect(client.watchUserTransactions(callback)).resolves.toEqual(transaction); + expect(client.sidecarPostRequest).toHaveBeenCalledWith('watchUserTransactions', []); + expect(callback).toHaveBeenCalledWith(transaction); + }); +});