UNPKG

@iam4x/bsc-scan

Version:

An efficient BNB and token balance scanner

68 lines (57 loc) 1.88 kB
import fetch from 'isomorphic-unfetch'; import type { EthCallJsonRpcPayload, JsonRpcResult, Provider } 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) ); }, call: async (provider: HttpProviderLike, contractAddress: string, data: string): Promise<string> => { const url = typeof provider === 'string' ? provider : provider.url; const options = typeof provider === 'object' ? provider.params : {}; const payload = getPayload(contractAddress, data); 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(`Contract call failed with HTTP error ${response.status}: ${response.statusText}`); } const { error, result }: JsonRpcResult<string> = await response.json(); if (error) { throw new Error(`Contract call failed: ${error.message}`); } return result; } }; export default provider; /** * Get the JSON-RPC payload for the `eth_call` function. */ export const getPayload = (to: string, data: string): EthCallJsonRpcPayload => ({ jsonrpc: '2.0', method: 'eth_call', params: [ { to, data }, 'latest' ], id: 1 });