Skip to main content
In this guide you write a small TypeScript client for BOTScan’s API that pages through an address’s transactions, reads and decodes event logs, and loads a verified contract’s ABI. BOTScan needs no API key. For the full list of endpoints and parameters, see the Explorer API reference. This guide shows how to use them well from code.

When to use the explorer, and when to use the RPC

The explorer is an indexer run by a third party. Treat its answers as convenient, not authoritative, and check anything that moves money against the chain.

What you’ll build

botscan.ts, a script with four parts:
  1. A fetch helper that retries when BOTScan is busy.
  2. Paged reads from the REST API (v2).
  3. Event logs from the Etherscan-style API, decoded with viem.
  4. A verified contract’s ABI, loaded through the Uzo SDK and used to call the contract.

Prerequisites

  • Node.js 22 or later.

Steps

1

Create the project

2

Write the script

botscan.ts
Replace wallet with the address you want to look up.
3

Run it

Verify it worked

Output from a run on testnet on 2026-10-02:
Output
Your numbers will differ.

How each part works

Retries

BOTScan doesn’t publish rate limits. The botscan helper retries on 429 and 5xx responses, waiting 1, 2, then 4 seconds. Other errors, such as 404, fail straight away because retrying won’t help. For anything that runs often, also cache responses: a confirmed transaction never changes.

Pagination

REST list endpoints take page and page_size, and return total_pages so you know when to stop. Loop until page reaches total_pages, or until you’ve found what you need.

Event logs

The Etherscan-style getLogs returns raw logs. parseEventLogs from viem decodes them with an ABI, so you get typed args instead of hex topics. Three details matter:
  • Filtering by more than one topic needs an operator. When you pass both topic0 and topic1, add topic0_1_opr=and (or or). Without it, BOTScan answers Required query parameters missing: topic0_1_opr and result is null. The same applies to other pairs, such as topic0_2_opr.
  • Don’t rely on offset to limit results. On 2026-10-02 the request above returned 6 logs with offset=5 and also with offset=2. Limit the range with fromBlock and toBlock, and slice the results in your code.
  • The raw logs aren’t quite RPC logs. BOTScan pads topics with null and leaves out blockHash, so the script removes the null entries and fills in the missing fields before decoding.
topic1 is the indexed from address, padded to 32 bytes. Use topic2 to filter by to instead.

Contract ABIs

createExplorerClient from @uzolabs/sdk/explorer wraps BOTScan’s contract endpoints. getContract returns the contract’s name, ABI, verified flag and, for proxies, the implementation addresses. With the ABI, viem can call any function by name. Only use ABIs loaded at runtime for reading or display. For code that sends transactions, keep the ABI in your source so a change on the explorer can’t change what you sign.

Troubleshooting

You filtered by two topics without saying how to combine them. Add &topic0_1_opr=and.
Check message in the response. If it says no records were found, check the address, the topics and the block range. Topic addresses must be lowercase and padded to 32 bytes.
You sent too many requests. Raise attempts, add a delay between pages, or cache responses.
The contract isn’t verified on BOTScan. Verify it first. See Verify contracts.
The script uses botChainTestnet. For mainnet, import botChain from @uzolabs/sdk/chains and use it in place of botChainTestnet. Both the explorer URL and the addresses follow the chain.

Next steps

Events without getLogs

Show contract events in a frontend.

Index chain data

Options for larger data needs.
Last modified on October 2, 2026