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
14 changes: 7 additions & 7 deletions core/src/exchanges/rain/fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export interface RainFetcherConfig {
subgraphApiKey?: string;
rpcUrl?: string;
wsRpcUrl?: string;
sdk?: RainSdk;
}

// Re-export raw SDK types as the fetcher's contract surface.
Expand Down Expand Up @@ -60,7 +61,7 @@ export class RainFetcher {

private async getClient(): Promise<RainClient> {
if (!this.client) {
const sdk = await loadSdk();
const sdk = this.config.sdk ?? await loadSdk();
this.client = new sdk.Rain({
environment: this.config.environment ?? 'production',
rpcUrl: this.config.rpcUrl,
Expand Down Expand Up @@ -140,15 +141,14 @@ export class RainFetcher {
}
}

async fetchRawOHLCV(marketId: string, optionIndex: number, interval: string, limit?: number): Promise<RainRawPriceHistory | null> {
async fetchRawOHLCV(marketAddress: string, optionIndex: number, _interval: string, _limit?: number): Promise<RainRawPriceHistory | null> {
if (!this.config.subgraphUrl) return null;
try {
const client = await this.getClient();
return await client.getPriceHistory({
marketId,
optionIndex,
interval: interval as any,
limit,
return await (client as any).getPriceHistory({
marketAddress: marketAddress as `0x${string}`,
interval: _interval,
option: optionIndex,
});
} catch (error: any) {
throw rainErrorMapper.mapError(error);
Expand Down
5 changes: 4 additions & 1 deletion core/src/exchanges/rain/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,10 @@ export class RainExchange extends PredictionMarketExchange {
const marketId = parts[1];
const choiceIndex = Number(parts[2]);
const interval = RainNormalizer.mapInterval(params.resolution);
const raw = await this.fetcher.fetchRawOHLCV(marketId, choiceIndex, interval, params.limit);
const market = await this.fetcher.fetchRawMarket(marketId);
const contractAddress = market?.details?.contractAddress;
if (!contractAddress) return [];
const raw = await this.fetcher.fetchRawOHLCV(contractAddress, choiceIndex, interval, params.limit);
return this.normalizer.normalizeOHLCV(raw, params.limit);
}

Expand Down
42 changes: 42 additions & 0 deletions core/test/exchanges/rain-fetcher.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { RainFetcher } from '../../src/exchanges/rain/fetcher';
import { RainExchange } from '../../src/exchanges/rain';

describe('RainFetcher', () => {
it('passes Rain SDK price-history params using marketAddress and option', async () => {
const getPriceHistory = jest.fn().mockResolvedValue({ candles: [] });
const sdk = {
Rain: jest.fn().mockImplementation(() => ({ getPriceHistory })),
};
const fetcher = new RainFetcher({
subgraphUrl: 'https://subgraph.example.test',
sdk,
} as any);

await fetcher.fetchRawOHLCV('0x1111111111111111111111111111111111111111', 1, '1h', 50);

expect(getPriceHistory).toHaveBeenCalledWith({
marketAddress: '0x1111111111111111111111111111111111111111',
interval: '1h',
option: 1,
});
});

it('resolves Rain market ids to contract addresses before fetching OHLCV', async () => {
const exchange = new RainExchange();
const fetchRawMarket = jest.fn().mockResolvedValue({
details: { contractAddress: '0x2222222222222222222222222222222222222222' },
});
const fetchRawOHLCV = jest.fn().mockResolvedValue({ candles: [] });
(exchange as any).fetcher = { fetchRawMarket, fetchRawOHLCV };

await exchange.fetchOHLCV('rain:rain-market-id:2', { resolution: '1h', limit: 10 });

expect(fetchRawMarket).toHaveBeenCalledWith('rain-market-id');
expect(fetchRawOHLCV).toHaveBeenCalledWith(
'0x2222222222222222222222222222222222222222',
2,
'1h',
10,
);
});
});
Loading