diff --git a/core/src/exchanges/rain/fetcher.ts b/core/src/exchanges/rain/fetcher.ts index 62a3cac2..2341fa42 100644 --- a/core/src/exchanges/rain/fetcher.ts +++ b/core/src/exchanges/rain/fetcher.ts @@ -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. @@ -60,7 +61,7 @@ export class RainFetcher { private async getClient(): Promise { 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, @@ -140,15 +141,14 @@ export class RainFetcher { } } - async fetchRawOHLCV(marketId: string, optionIndex: number, interval: string, limit?: number): Promise { + async fetchRawOHLCV(marketAddress: string, optionIndex: number, _interval: string, _limit?: number): Promise { 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); diff --git a/core/src/exchanges/rain/index.ts b/core/src/exchanges/rain/index.ts index 6cef17b3..e957df84 100644 --- a/core/src/exchanges/rain/index.ts +++ b/core/src/exchanges/rain/index.ts @@ -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); } diff --git a/core/test/exchanges/rain-fetcher.test.ts b/core/test/exchanges/rain-fetcher.test.ts new file mode 100644 index 00000000..bd7e5161 --- /dev/null +++ b/core/test/exchanges/rain-fetcher.test.ts @@ -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, + ); + }); +});