A way to access the etherscan.io api using promises. Fetch a diverse set of information about the blockchain.
Written in TypeScript, shipped as an ES module with bundled type declarations. Requires Node.js >= 20.
Mainnet
import{init}from'etherscan-api';constapi=init('YourApiKey');constbalance=awaitapi.account.balance('0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae');console.log(balance);This library has no runtime dependencies — requests use Node's built-in
https module. If you need custom networking (a proxy, retries, a different
agent), pass your own transport as the 4th argument to init. It receives the
fully-qualified URL and must resolve with the parsed JSON body:
import{init}from'etherscan-api';// (url, { timeout, method, body }) => Promise<object>// `method`/`body` are only set for the POST contract-verification endpoints;// for read-only use you can ignore them.asyncfunctionrequest(url,{ timeout, method ='GET', body }){constres=awaitfetch(url,{
method,
body,headers: body ? {'Content-Type': 'application/x-www-form-urlencoded'} : undefined,signal: AbortSignal.timeout(timeout),});returnres.json();}constapi=init('apikey',null,10000,request);- The API key travels in the request URL. Etherscan requires
apikeyas a query parameter, so it is part of every request URL (and of POST request URLs). Treat full request URLs as secrets: do not log them, and be careful with proxies, APM tools, and access logs that capture URLs. A custom transport receives the URL containing the key — never write it to logs verbatim. (The library itself never puts the URL or key into thrown errors.) - The default transport refuses cleartext
http://. Requests go tohttps://api.etherscan.ioover TLS with certificate validation on. If a request somehow targets anhttp://URL, the default transport rejects rather than sending the key unencrypted; pass{ allowInsecure: true }in the transport options only if you deliberately need cleartext (e.g. a local test server). - The default transport caps the response body at 50 MB to guard against a
memory-exhaustion response. Override with
maxResponseBytesin the transport options if you expect larger payloads.
Etherscan deprecated the V1 API on 2025-08-15. This library now talks to a
single base URL — https://api.etherscan.io/v2/api — and selects the network
with a chainid query parameter. One API key works across all chains.
Pass a chain name (or a numeric chainid) as the second argument to init:
import{init}from'etherscan-api';// apikey, chain, timeoutconstapi=init('YourApiKey','sepolia',3000);Supported chain names:
| Name | chainid |
|---|---|
mainnet / homestead / ethereum | 1 |
sepolia | 11155111 |
holesky | 17000 |
arbitrum | 42161 |
optimism | 10 |
base | 8453 |
polygon | 137 |
bsc | 56 |
avalanche | 43114 |
Any other chain is reachable by passing its numeric chainid directly, e.g.
init('YourApiKey', 59144) for Linea.
Retired testnets (ropsten, rinkeby, kovan, goerli, morden,
arbitrum_rinkeby, avalanche_fuji) have been removed and now throw an
error with a helpful message — use sepolia or holesky instead.
npm install etherscan-api --saveSource lives in ./src (TypeScript) and compiles to ./lib (ES modules + .d.ts).
npm run build- compilessrc→libwithtscnpm run typecheck- type-checks without emitting (replaces the old linter)npm test- builds, then runs the fully mocked test suite (no API key required)npm run test:live- runs the tests against the real Etherscan APInpm run docs- generates the API docs with TypeDocnpm run preversion- type-check + changelog before tagging a releasenpm run changelog- generates a changelog and pushes it