app.ts


Overview

`app.ts` is the primary entry point for the Base API server within the ShapeShift Unchained ecosystem. It sets up an Express web server augmented with WebSocket support to handle real-time blockchain data related to Ethereum Virtual Machine (EVM) networks. The file initializes middleware, API routes, and integrates with external services such as a blockchain indexer via WebSocket. It also exposes health, metrics, and Swagger-based API documentation endpoints.

This server processes blockchain transactions by leveraging the `@shapeshiftoss/common-api` and `@shapeshiftoss/blockbook` packages, formats addresses, and maintains metrics via Prometheus. It orchestrates live transaction and block event handling, enabling downstream services or clients to consume processed blockchain data.


Detailed Explanation of Components

Constants and Environment Variables

Name

Description

`PORT`

Server listening port, default to 3000 if not specified.

`INDEXER_WS_URL`

WebSocket URL of the blockchain indexer service. Required.

`INDEXER_API_KEY`

API key for authenticating with the indexer. Optional.

**Important:** The app throws an error and halts startup if `INDEXER_WS_URL` is not set.


Logger

export const logger = new Logger({
  namespace: ['unchained', 'coinstacks', 'base', 'api'],
  level: process.env.LOG_LEVEL,
})

Prometheus Metrics

const prometheus = new Prometheus({ coinstack: 'base' })

Express App Setup

const app = express()

HTTP Routes

Route

Method

Description

`/health`

GET

Returns JSON health status with server status and active WS connections count.

`/metrics`

GET

Exposes Prometheus metrics.

`/public`

Static

Serves static assets related to API docs UI.

`/swagger.json`

Static

Serves Swagger API definition JSON.

`/docs`

GET

Serves Swagger UI documentation for the API.

`/`

GET

Redirects to `/docs` for user convenience.

Example usage:

curl http://localhost:3000/health
# Response: { "status": "up", "asset": "base", "connections": 0 }

Swagger UI Integration


Route Registration

RegisterRoutes(app)

Address Formatter

const addressFormatter: AddressFormatter = (address) => evm.formatAddress(address)

Transaction Handler

const transactionHandler: TransactionHandler<BlockbookTx, evm.Tx> = async (blockbookTx) => {
  const tx = await service.handleTransactionWithInternalTrace(blockbookTx)
  const internalAddresses = (tx.internalTxs ?? []).reduce<Array<string>>((prev, tx) => [...prev, tx.to, tx.from], [])
  const addresses = [...new Set([...getAddresses(blockbookTx), ...internalAddresses])]

  return { addresses, tx }
}

Registry

const registry = new Registry({ addressFormatter, transactionHandler })

WebSocket Client (Blockbook)

const blockbook = new WebsocketClient(`${INDEXER_WS_URL}/api=${INDEXER_API_KEY}`, {
  blockHandler: [gasOracle.onBlock.bind(gasOracle)],
  transactionHandler: registry.onTransaction.bind(registry),
})

HTTP and WebSocket Server Setup

const server = app.listen(PORT, () => logger.info('Server started'))
const wsServer = new Server({ server })

wsServer.on('connection', (connection) => {
  ConnectionHandler.start(connection, registry, blockbook, prometheus, logger)
})

Interaction with Other Parts of the System

The file acts as a coordinator, wiring these modules together to expose a cohesive API server that streams blockchain data in near real-time and serves RESTful endpoints.


Usage Example

Start the server with required environment variables:

export INDEXER_WS_URL=wss://indexer.example.com
export INDEXER_API_KEY=your_api_key
export PORT=3000
node dist/app.js

Then access:

WebSocket clients can connect to the same server's WebSocket endpoint to receive live blockchain updates.


Important Implementation Details


Mermaid Class Diagram

classDiagram
    class App {
        +express app
        +Prometheus prometheus
        +Logger logger
        +Registry registry
        +WebsocketClient blockbook
        +Server httpServer
        +Server wsServer
        +start()
    }

    class Registry {
        +addressFormatter: AddressFormatter
        +transactionHandler: TransactionHandler
        +onTransaction()
    }

    class WebsocketClient {
        +constructor(url, handlers)
        +blockHandler: function[]
        +transactionHandler: function
        +connect()
    }

    class ConnectionHandler {
        +start(connection, registry, blockbook, prometheus, logger)
    }

    class Logger {
        +info()
        +error()
    }

    class Prometheus {
        +register
        +metrics()
    }

    App --> Registry : uses
    App --> WebsocketClient : uses
    App --> ConnectionHandler : manages WS connections
    App --> Prometheus : collects metrics
    App --> Logger : logs events
    Registry ..> AddressFormatter : uses
    Registry ..> TransactionHandler : uses

Summary

`app.ts` is a foundational file that configures and launches the Base API server. It integrates Express HTTP routing, WebSocket real-time blockchain event streaming, transaction processing, and monitoring. The file carefully composes external libraries and internal modules to provide a robust, maintainable, and observable blockchain API service within the ShapeShift ecosystem.