UNPKG

opnet

Version:

The perfect library for building Bitcoin-based applications.

99 lines (98 loc) 3.18 kB
import getFetcher from '../fetch/fetch.js'; import { jsonThreader } from '../threading/JSONThreader.js'; import { AbstractRpcProvider } from './AbstractRpcProvider.js'; export class JSONRpcProvider extends AbstractRpcProvider { timeout; fetcherConfigurations; useRESTAPI; useThreadedParsing; url; _fetcherWithCleanup; constructor(url, network, timeout = 20_000, fetcherConfigurations = { keepAliveTimeout: 30_000, keepAliveTimeoutThreshold: 30_000, connections: 128, pipelining: 2, }, useRESTAPI = true, useThreadedParsing = true) { super(network); this.timeout = timeout; this.fetcherConfigurations = fetcherConfigurations; this.useRESTAPI = useRESTAPI; this.useThreadedParsing = useThreadedParsing; this.url = this.providerUrl(url); } get fetcher() { if (!this._fetcherWithCleanup) { this._fetcherWithCleanup = getFetcher(this.fetcherConfigurations); } return this._fetcherWithCleanup.fetch; } async close() { if (this._fetcherWithCleanup) { await this._fetcherWithCleanup.close(); this._fetcherWithCleanup = undefined; } } setFetchMode(useRESTAPI) { this.useRESTAPI = useRESTAPI; } async _send(payload) { const controller = new AbortController(); const { signal } = controller; const timeoutId = setTimeout(() => controller.abort(), this.timeout); const params = { method: 'POST', headers: { 'Content-Type': 'application/json', 'User-Agent': 'OPNET/1.0', Accept: 'application/json', 'Accept-Charset': 'utf-8', 'Accept-Language': 'en-US', Connection: 'Keep-Alive', }, body: JSON.stringify(payload), timeout: this.timeout, signal: signal, }; try { const resp = await this.fetcher(this.url, params); if (!resp.ok) { throw new Error(`Failed to fetch: ${resp.statusText}`); } const fetchedData = await this.parseResponse(resp); if (!fetchedData) { throw new Error('No data fetched'); } return [fetchedData]; } catch (e) { const error = e; if (error.name === 'AbortError') { throw new Error(`Request timed out after ${this.timeout}ms`); } throw e; } finally { clearTimeout(timeoutId); } } providerUrl(url) { url = url.trim(); if (url.endsWith('/')) { return url.slice(0, -1); } if (url.includes('api/v1/json-rpc')) { return url; } else { return `${url}/api/v1/json-rpc`; } } async parseResponse(resp) { if (this.useThreadedParsing) { const buffer = await resp.arrayBuffer(); return jsonThreader.parseBuffer(buffer); } return (await resp.json()); } }