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
69 changes: 69 additions & 0 deletions sdks/typescript/pmxt/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, any>) => void,
): Promise<Record<string, any>> {
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<Position[]> {
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<string, any>) => void,
): Promise<Record<string, any>> {
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}`);
}
}
}

/**
Expand Down
44 changes: 44 additions & 0 deletions sdks/typescript/tests/limitless-watch-methods.test.ts
Original file line number Diff line number Diff line change
@@ -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);
});
});
Loading