Unified API Layer
The Unified API Layer serves as a coherent and consistent interface that abstracts the underlying complexities of interacting with multiple blockchain networks. It provides standardized RESTful and WebSocket APIs that enable clients to efficiently retrieve blockchain data, submit transactions, and subscribe to real-time blockchain events across different blockchain types such as EVM-compatible chains and UTXO-based chains.
Overview and Purpose
Different blockchains have diverse data models, transaction formats, and node interaction protocols. The Unified API Layer exists to mask these differences behind a common set of API endpoints and data structures, enabling clients to interact with any supported blockchain with minimal changes to their code.
The core problems it solves include:
Standardization: Presenting a unified API schema and method set regardless of the underlying blockchain’s architecture (e.g., account-based vs UTXO).
Simplification: Reducing the need for clients to understand blockchain-specific details.
Interoperability: Providing a consistent developer experience across multiple blockchains.
Extensibility: Allowing addition of new blockchain coinstacks without breaking the API contract.
Core Concepts
BaseAPI Interface: Defines the essential API methods that all blockchain coinstacks must implement to conform to the unified interface.
EVM API Controllers and Services: Implementation of the BaseAPI for account-based blockchains compatible with Ethereum Virtual Machine (EVM), including Ethereum mainnet and related Layer 2 solutions.
UTXO API Controllers and Services: Implementation of the BaseAPI for UTXO (Unspent Transaction Output) model blockchains such as Bitcoin and derivatives.
Services: Backend business logic components that interact with blockchain indexers (like Blockbook), node RPC endpoints, and external APIs to fulfill requests.
Controllers: API route handlers exposing the RESTful endpoints decorated with routing and validation metadata.
Error Handling: Standardized error classes and middleware to ensure consistent API error responses.
How It Works: Key Functionalities and Workflows
BaseAPI Interface (node/coinstacks/common/api/src/index.ts)
The `BaseAPI` interface defines the minimal set of methods that each blockchain API must provide:
export interface BaseAPI {
getInfo(): Promise<BaseInfo>;
getAccount(pubkey: string): Promise<BaseAccount>;
getTxHistory(pubkey: string, cursor?: string, pageSize?: number): Promise<BaseTxHistory>;
sendTx(body: SendTxBody): Promise<string>;
}
getInfo: Returns metadata about the running coinstack (e.g., network name).
getAccount: Retrieves account details by address or extended public key.
getTxHistory: Retrieves transaction history for a given account.
sendTx: Broadcasts a raw transaction to the blockchain network.
This interface ensures a baseline uniformity of API capabilities across blockchains.
EVM API Implementation
Controller:
node/coinstacks/common/api/src/evm/controller.ts
TheEVMcontroller class implements theBaseAPIand exposes additional EVM-specific endpoints such as JSON-RPC proxy calls and token metadata retrieval.Example endpoint:
@Get('account/{pubkey}') async getAccount(@Path() pubkey: string): Promise<Account> { return EVM.service.getAccount(pubkey); }Service:
node/coinstacks/common/api/src/evm/service.ts
TheServiceclass encapsulates all business logic and interactions required to fulfill API requests for EVM chains.Key interactions include:
Querying blockchain data via Blockbook indexer.
Fetching and formatting token balances (ERC20, ERC721, ERC1155).
Handling transaction history pagination with cursor-based tokens.
Estimating gas fees and gas limits using Ethereum clients and gas oracles.
Sending raw transactions through node RPC endpoints.
Fetching internal transactions by tracing calls using debug RPC methods or external explorer APIs.
For example, fetching account token balances involves querying Blockbook and processing token arrays:
const tokens = (data.tokens ?? []).reduce<Array<TokenBalance>>((prev, token) => { // Process ERC20, ERC721, ERC1155 tokens into a common TokenBalance structure }, []);The service also maintains a gas oracle for fee estimation and uses `viem` client utilities for low-level Ethereum interactions.
UTXO API Implementation
Controller:
node/coinstacks/common/api/src/utxo/controller.ts
TheUTXOcontroller class implements theBaseAPIand exposes additional UTXO-specific endpoints such as fetching UTXOs and network fees.Service:
node/coinstacks/common/api/src/utxo/service.ts
TheServiceclass implements the business logic for UTXO chains.Key functionalities:
Fetching account details by address or extended public key, including derived addresses.
Retrieving paginated transaction history using page-based cursors.
Fetching raw transaction data directly from the node.
Retrieving all unspent transaction outputs (UTXOs) for an account.
Estimating network fees by querying Blockbook.
Broadcasting raw transactions via RPC endpoints.
The service uses Blockbook’s UTXO APIs extensively and applies address formatting logic to handle extended public keys and address normalization.
Interactions with Other System Components
Blockbook Indexer: Both EVM and UTXO services rely heavily on Blockbook to provide indexed blockchain data such as transactions, addresses, balances, and blocks. The services query Blockbook REST APIs for data retrieval.
Blockchain Node RPC: Raw transactions and some data (e.g., internal transaction traces for EVM) require direct RPC calls to blockchain nodes. The services make JSON-RPC calls to these nodes to send transactions or trace calls.
Gas Oracle (EVM only): The EVM service uses a dedicated gas oracle component to estimate gas fees based on recent network conditions.
API Controllers: Expose REST endpoints defined by the unified interface. Controllers delegate requests to their respective service classes.
Middleware and Error Handling: The API layer uses common middleware for request validation, error formatting, and logging.
WebSocket Event Subscription (Related): Although not directly part of the REST API controllers, the unified API layer integrates with WebSocket subscriptions for real-time updates via a
Registryand connection handlers.
Design Patterns and Approaches
Interface-Based Design: The
BaseAPIinterface enforces a contract that each blockchain-specific API must implement, ensuring uniformity.Separation of Concerns: Controllers handle HTTP routing and response formatting; services contain business logic and external API interactions.
Decorator-Based Routing: API routes and HTTP verbs are declared using decorators (
@Get,@Post,@Route) for clear and maintainable endpoint definitions.Cursor-Based Pagination: Transaction history endpoints use cursor tokens (base64-encoded JSON) to navigate paginated results efficiently, supporting scalable data retrieval.
Error Wrapping and Uniformity: Custom
ApiErrorclass and utility functions ensure consistent error responses across different blockchain implementations.Retry and Backoff Logic: Axios instances with retry mechanisms handle transient failures when calling external APIs or blockchain nodes.
Token Metadata Resolution: The EVM service fetches token metadata from smart contracts and IPFS gateways, handling multiple token standards and data formats.
Summary of File Relationships
api/src/index.ts: Defines theBaseAPIinterface and exports common models, middleware, and utilities used by all coinstack APIs.evm/controller.tsandutxo/controller.ts: Implement the API controllers for respective blockchain types, exposing REST endpoints conforming toBaseAPI.evm/service.tsandutxo/service.ts: Implement the core logic interacting with Blockbook, RPC nodes, and other dependencies to fulfill controller requests.Both services consume the common API utilities and error handling defined in
api/src/index.ts.
Mermaid Sequence Diagram: Unified API Layer Request Flow
sequenceDiagram
participant Client
participant APIController
participant APIService
participant Blockbook
participant NodeRPC
participant GasOracle
Client->>APIController: Send REST API request (e.g., getAccount)
APIController->>APIService: Delegate request
alt EVM Chain
APIService->>Blockbook: Query token balances & tx history
APIService->>GasOracle: Get gas fee estimates (if needed)
APIService->>NodeRPC: Send transaction / trace calls (if needed)
else UTXO Chain
APIService->>Blockbook: Query address info, tx history, UTXOs
APIService->>NodeRPC: Send raw transaction
end
APIService-->>APIController: Return formatted data
APIController-->>Client: Send JSON response
This documentation details the Unified API Layer’s role as a foundational abstraction enabling consistent blockchain interaction through RESTful APIs, supporting both account-based and UTXO-based chains. Its modular design, interface conformity, and comprehensive service implementations facilitate scalable multi-blockchain support.