controller.ts
Overview
`controller.ts` serves as the API controller layer for interacting with the Gnosis chain, specifically tailored to the Ethereum-compatible environment (EVM). It exposes RESTful endpoints for gas-related operations such as estimating gas costs for transactions and retrieving recommended gas fees. This file leverages a shared `Service` instance that abstracts the underlying blockchain data sources and logic, including interaction with Blockbook, Etherscan, and a gas oracle.
The controller extends a base `EVM` controller, inheriting common Ethereum JSON-RPC and transaction-related functionalities, while specializing them for the Gnosis network. It uses the `tsoa` framework to define routes, request/response models, validation, and documentation annotations, enabling automatic OpenAPI spec generation.
Detailed Explanation
Imports and Environment Configuration
Imports core dependencies: blockchain clients (
Blockbook,viem), logging, API decorators (tsoa), and shared models/interfaces from a common API package.Validates presence of critical environment variables at startup:
ETHERSCAN_API_KEY: for interacting with the Etherscan API.INDEXER_URL and
INDEXER_WS_URL: URLs of the blockchain indexer service.NETWORK and
RPC_URL: network identifier and RPC endpoint URL.
Throws errors if any required environment variable is missing, enforcing configuration correctness.
Logger Initialization
export const logger = new Logger({
namespace: ['unchained', 'coinstacks', 'gnosis', 'api'],
level: process.env.LOG_LEVEL,
})
Configures a namespaced logger for structured logging scoped to this module and network.
Log level can be set via environment variable.
Blockchain Client and Service Instances
client: A public RPC client for the Gnosis chain created usingviem.blockbook: A Blockbook client instance that handles blockchain data indexing and websocket subscriptions.gasOracle: Provides gas fee recommendations and estimation logic.service: Core service instance combining the above clients and external APIs (like Etherscan) to serve the controller.
export const service = new Service({
blockbook,
gasOracle,
explorerApiUrl: new URL(`https://api.etherscan.io/v2/api?chainid=100&apikey=${ETHERSCAN_API_KEY}`),
client,
logger,
rpcUrl: RPC_URL,
})
The
serviceobject encapsulates all business logic related to gas estimation and fee querying.It is injected into the base
EVMcontroller class, meaning all inherited methods use this specialized service.
Class Gnosis
@Route('api/v1')
@Tags('v1')
export class Gnosis extends EVM implements BaseAPI, API { ... }
Extends the generic
EVMcontroller, specializing it for the Gnosis network.Implements interfaces
BaseAPIandAPIto conform to expected API contracts.Decorated with
tsoaannotations to define the base API route (/api/v1) and tag for grouping.
Methods
estimateGas
@Post('/gas/estimate')
async estimateGas(@Body() body: EstimateGasBody): Promise<GasEstimate>
Purpose: Estimates the gas cost of a transaction based on the provided transaction data.
Parameters:
body(typeEstimateGasBody): Object containing:data: optional transaction calldata (hex string).from: sender address.to: recipient address.value: transaction value in wei (string).
Returns: Promise resolving to a
GasEstimateobject, e.g.,{ gasLimit: '21000' }.Error Responses:
422 for validation errors.
500 for internal server errors.
Usage Example:
{
"data": "0x",
"from": "0x0000000000000000000000000000000000000000",
"to": "0xBA7A4c521DfCD18fEB7cdA4B7CA182d739B7A6a0",
"value": "1337"
}
Implementation Detail: Delegates the actual estimation to
service.estimateGas(body)which likely calls the RPC or indexer to simulate the transaction and calculate gas.
getGasFees
@Get('/gas/fees')
async getGasFees(): Promise<GasFees>
Purpose: Retrieves current recommended gas fees for the network.
Returns: Promise resolving to a
GasFeesobject containing fee tiers (slow,average,fast) with fields:gasPricemaxFeePerGasmaxPriorityFeePerGasbaseFeePerGas
Notes:
For EIP-1559 transactions, use
maxFeePerGasandmaxPriorityFeePerGas.For legacy transactions, use
gasPrice.
Error Responses: 500 for internal server errors.
Example Response:
{
"baseFeePerGas": "7",
"slow": {
"gasPrice": "1967447305",
"maxFeePerGas": "1554947308",
"maxPriorityFeePerGas": "1554947301"
},
"average": {
"gasPrice": "2545383854",
"maxFeePerGas": "2055458056",
"maxPriorityFeePerGas": "2055458049"
},
"fast": {
"gasPrice": "2927445852",
"maxFeePerGas": "2245520056",
"maxPriorityFeePerGas": "2245520049"
}
}
Implementation Detail: Calls
service.getGasFees()which interacts with theGasOracleto retrieve live fee data.
Important Implementation Details
Inheritance & Service Injection:
TheGnosiscontroller class inherits fromEVM, sharing common Ethereum-compatible logic while overriding or extending it for the Gnosis chain. The sharedserviceinstance is assigned statically toEVM.service, ensuring all controller instances use the Gnosis-specific backend.Dependency Injection:
The controller relies on external clients (Blockbook,GasOracle,viemRPC client) encapsulated inside theServiceclass. This design promotes modularity and testability.Environment Validation:
Early validation of environment variables prevents runtime errors related to missing configuration, enhancing robustness.API Documentation:
Usingtsoaannotations (@Route,@Tags,@Example,@Response) allows automatic generation of OpenAPI specs and interactive API docs.Error Handling:
The controller specifies HTTP response codes for validation and server errors, but actual error handling likely occurs in theservicelayer or middleware.
Interaction with Other Parts of the System
Common API Models:
Uses shared models (EstimateGasBody,GasEstimate,GasFees) from the common API package, ensuring consistency across different chain implementations.Base EVM Controller:
ExtendsEVMcontroller, which provides foundational Ethereum JSON-RPC methods and API contracts.Service Layer:
TheServiceinstance acts as the business logic layer, interfacing with blockchain data sources (Blockbook, RPC, Etherscan) and encapsulating gas estimation and fee algorithms.External Dependencies:
Blockbookfor blockchain data indexing.viemfor RPC communication.GasOraclefor live gas fee estimation.
Environmental Configuration:
The controller depends on environment variables for API keys, network configuration, and RPC endpoints, allowing flexibility across deployment environments.
Usage Examples
Estimating Gas
curl -X POST https://api.yourdomain.com/api/v1/gas/estimate \
-H "Content-Type: application/json" \
-d '{
"data": "0x",
"from": "0x0000000000000000000000000000000000000000",
"to": "0xBA7A4c521DfCD18fEB7cdA4B7CA182d739B7A6a0",
"value": "1337"
}'
**Response:**
{
"gasLimit": "21000"
}
Getting Gas Fees
curl https://api.yourdomain.com/api/v1/gas/fees
**Response:**
{
"baseFeePerGas": "7",
"slow": {
"gasPrice": "1967447305",
"maxFeePerGas": "1554947308",
"maxPriorityFeePerGas": "1554947301"
},
"average": {
"gasPrice": "2545383854",
"maxFeePerGas": "2055458056",
"maxPriorityFeePerGas": "2055458049"
},
"fast": {
"gasPrice": "2927445852",
"maxFeePerGas": "2245520056",
"maxPriorityFeePerGas": "2245520049"
}
}
Mermaid Class Diagram
classDiagram
class Gnosis {
+estimateGas(body: EstimateGasBody): Promise~GasEstimate~
+getGasFees(): Promise~GasFees~
}
class EVM {
<<abstract>>
+service: Service
}
class Service {
+estimateGas(body: EstimateGasBody): Promise~GasEstimate~
+getGasFees(): Promise~GasFees~
}
class Blockbook {
+httpURL: string
+wsURL: string
}
class GasOracle {
+getGasFees(): Promise~GasFees~
}
class Logger {
+namespace: string[]
+level: string
}
class Client {
+chain: any
+transport: any
}
Gnosis --|> EVM
EVM --> Service : uses
Service --> Blockbook
Service --> GasOracle
Service --> Client
Service --> Logger
Summary
`controller.ts` is a specialized API controller providing gas estimation and fee retrieval endpoints for the Gnosis network, built on an Ethereum-compatible stack. It integrates multiple blockchain data sources and services behind a clean RESTful interface, leveraging inheritance and modular service design. The file ensures robustness through environment validation and provides well-documented, typed endpoints suitable for automated API generation and client consumption.