# Etherscan-Compatible API Specification ## Overview This document specifies the Etherscan-compatible API layer that provides an API surface matching Blockscout/Etherscan APIs for tool compatibility and easier migration. **Base URL**: `https://api.explorer.d-bis.org/api` **Note**: This is a compatibility layer that translates Etherscan API calls to our internal API. ## API Surface Mapping ### Account Endpoints #### Get Account Balance **Etherscan**: `GET /api?module=account&action=balance&address={address}&tag=latest` **Our Implementation**: - Maps to: `GET /v1/addresses/{chain_id}/{address}` (extract balance) **Response Format** (matches Etherscan): ```json { "status": "1", "message": "OK", "result": "1000000000000000000" } ``` #### Get Token Balance **Etherscan**: `GET /api?module=account&action=tokenbalance&contractaddress={token}&address={address}&tag=latest` **Our Implementation**: - Maps to: `GET /v1/addresses/{chain_id}/{address}/tokens` (filter by token address) **Response Format**: ```json { "status": "1", "message": "OK", "result": "1000000000000000000" } ``` #### Get Transaction List **Etherscan**: `GET /api?module=account&action=txlist&address={address}&startblock=0&endblock=99999999&page=1&offset=10&sort=desc` **Our Implementation**: - Maps to: `GET /v1/addresses/{chain_id}/{address}/transactions` (with pagination) **Response Format**: ```json { "status": "1", "message": "OK", "result": [ { "blockNumber": "12345", "timeStamp": "1640995200", "hash": "0x...", "from": "0x...", "to": "0x...", "value": "1000000000000000000", "gas": "21000", "gasPrice": "20000000000", "gasUsed": "21000", "isError": "0", "txreceipt_status": "1" } ] } ``` ### Transaction Endpoints #### Get Transaction Status **Etherscan**: `GET /api?module=transaction&action=getstatus&txhash={hash}` **Our Implementation**: - Maps to: `GET /v1/transactions/{chain_id}/{hash}` (extract status) **Response Format**: ```json { "status": "1", "message": "OK", "result": { "isError": "0", "errDescription": "" } } ``` #### Get Transaction Receipt Status **Etherscan**: `GET /api?module=transaction&action=gettxreceiptstatus&txhash={hash}` **Response Format**: ```json { "status": "1", "message": "OK", "result": { "status": "1" } } ``` ### Block Endpoints #### Get Block by Number **Etherscan**: `GET /api?module=proxy&action=eth_getBlockByNumber&tag={number}&boolean=true` **Our Implementation**: - Maps to: `GET /v1/blocks/{chain_id}/{number}` (transform format) **Response Format** (Ethereum JSON-RPC format): ```json { "jsonrpc": "2.0", "result": { "number": "0x3039", "hash": "0x...", "transactions": [...] } } ``` ### Contract Endpoints #### Get Contract ABI **Etherscan**: `GET /api?module=contract&action=getabi&address={address}` **Our Implementation**: - Maps to: `GET /v1/contracts/{chain_id}/{address}/abi` **Response Format**: ```json { "status": "1", "message": "OK", "result": "[{...}]" } ``` #### Verify Contract **Etherscan**: `POST /api?module=contract&action=verifysourcecode` **Our Implementation**: - Maps to: `POST /v1/contracts/{chain_id}/{address}/verify` **Parameter Mapping**: - `sourceCode` → `source_code` - `codeformat` → `verification_method` - `contractaddress` → `address` - `compilerversion` → `compiler_version` ### Token Endpoints #### Get Token Total Supply **Etherscan**: `GET /api?module=stats&action=tokensupply&contractaddress={address}` **Our Implementation**: - Maps to: `GET /v1/tokens/{chain_id}/{address}` (extract total_supply) ### Event Logs #### Get Event Logs **Etherscan**: `GET /api?module=logs&action=getLogs&address={address}&topic0={topic0}&fromBlock={fromBlock}&toBlock={toBlock}` **Our Implementation**: - Maps to: `GET /v1/logs` (with filters) **Response Format**: ```json { "status": "1", "message": "OK", "result": [ { "address": "0x...", "topics": ["0x..."], "data": "0x...", "blockNumber": "0x3039", "transactionHash": "0x...", "logIndex": "0x0" } ] } ``` ## Parameter Translation ### Common Parameters | Etherscan | Our API | Notes | |-----------|---------|-------| | `module` | N/A | Determines endpoint category | | `action` | N/A | Determines specific action | | `address` | `address` | Same | | `tag` | `block_number` | Convert "latest" to current block | | `startblock` | `from_block` | Same | | `endblock` | `to_block` | Same | | `page` | `page` | Same | | `offset` | `page_size` | Same | | `sort` | `order` | Same (asc/desc) | ### Chain ID Handling **Etherscan**: No chain_id parameter (single chain) **Our API**: Require `chain_id` parameter or use default from context **Mapping**: Add `chain_id` parameter to all requests ## Response Format Compatibility ### Status Codes **Etherscan Format**: - `status: "1"` = Success - `status: "0"` = Error **Our Format**: - HTTP 200 = Success (map to status "1") - HTTP 4xx/5xx = Error (map to status "0") ### Error Messages **Etherscan Format**: ```json { "status": "0", "message": "NOTOK", "result": "Error message here" } ``` **Our Mapping**: - Map our error codes to Etherscan error messages - Preserve error details in result field ## Migration Guide ### For Tools Using Etherscan API **Step 1**: Update base URL - Old: `https://api.etherscan.io/api` - New: `https://api.explorer.d-bis.org/api` **Step 2**: Add chain_id parameter (if needed) - Add `&chainid=138` to requests - Or use default chain from connection **Step 3**: Test compatibility - Verify response formats match - Check error handling - Validate data accuracy ### For New Integrations **Recommendation**: Use native REST API instead of Etherscan-compatible API - More features - Better performance - Clearer API design ## Limitations ### Not All Endpoints Supported **Supported**: - Account operations - Transaction queries - Block queries - Contract verification - Token operations - Event logs **Not Supported** (Etherscan-specific): - Gas tracker (use our analytics API) - Historical stats (use our analytics API) - Token list (use our token API) ### Response Format Differences **Some differences may exist**: - Field naming (camelCase vs snake_case) - Data precision - Additional fields in our responses ## Implementation ### Translation Layer **Architecture**: - Request interceptor: Parse Etherscan-style requests - Parameter mapper: Convert to our API format - Response transformer: Convert our responses to Etherscan format **Code Structure**: ``` compatibility/ ├── etherscan/ │ ├── request_parser.py # Parse Etherscan requests │ ├── parameter_mapper.py # Map parameters │ └── response_transformer.py # Transform responses ``` ## References - REST API: See `rest-api.md` - API Gateway: See `api-gateway.md`