UNPKG

@phiresky/eth-scan

Version:

An efficient Ether and token balance scanner

64 lines (53 loc) 1.86 kB
import fetch from 'isomorphic-unfetch'; import { nanoid } from 'nanoid'; import type { JsonRpcResult, Provider } from '../types'; import { JsonRpcPayload } from '../types'; interface HttpProviderOptions { url: string; params?: Partial<Omit<RequestInit, 'body' | 'method' | 'headers'>>; } export type HttpProviderLike = string | HttpProviderOptions; /** * A raw HTTP provider, which can be used with an Ethereum node endpoint (JSON-RPC), or an `HttpProviderOptions` object. */ const provider: Provider<HttpProviderLike> = { isProvider: (provider: unknown): provider is HttpProviderLike => { return ( typeof provider === 'string' || (typeof provider === 'object' && (provider as HttpProviderOptions).url !== undefined) ); }, send: async <Result>(provider: HttpProviderLike, method: string, params: unknown[]): Promise<Result> => { const url = typeof provider === 'string' ? provider : provider.url; const options = typeof provider === 'object' ? provider.params : {}; const payload = getPayload(method, params); const response = await fetch(url, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify(payload), cache: 'no-cache', ...options }); if (!response.ok) { throw new Error(`Request failed with HTTP error ${response.status}: ${response.statusText}`); } const { error, result }: JsonRpcResult<Result> = await response.json(); if (error) { throw new Error(`Request failed: ${error.message}`); } return result; } }; export default provider; /** * Get the JSON-RPC payload for the `eth_call` function. */ export const getPayload = (method: string, params: unknown[]): JsonRpcPayload => ({ jsonrpc: '2.0', method, params, id: nanoid() });