main.go

Overview

The `main.go` file serves as the entry point for the Thorchain v1 API server within the ShapeShift Unchained project. Its primary responsibility is to initialize and configure the necessary components to run the API server, including loading configuration, setting up Cosmos SDK clients, initializing metrics, and managing lifecycle events such as graceful shutdown on system signals.

This file orchestrates the main runtime environment by:


Detailed Explanation

Package and Imports


Global Variables

var (
	logger = log.WithoutFields()

	envPath     = flag.String("env", "", "path to env file (default: use os env)")
	swaggerPath = flag.String("swagger", "coinstacks/thorchain-v1/api/swagger.json", "path to swagger spec")
)

Config Struct

type Config struct {
	LCDURL string `mapstructure:"LCD_URL"`
	RPCURL string `mapstructure:"RPC_URL"`
	WSURL  string `mapstructure:"WS_URL"`
}

These URLs are used to configure clients that interact with the Thorchain network.


main() Function

The `main` function executes the following sequence:

1. Parse CLI Flags

flag.Parse()

Reads `-env` and `-swagger` flag values.

2. Setup Channels and Signal Handling

errChan := make(chan error, 1)
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)

Supported signals:

3. Load Configuration

conf := &Config{}
if *envPath == "" {
	if err := config.LoadFromEnv(conf, "LCD_URL", "RPC_URL", "WS_URL"); err != nil {
		logger.Panicf("failed to load config from env: %+v", err)
	}
} else {
	if err := config.Load(*envPath, conf); err != nil {
		logger.Panicf("failed to load config: %+v", err)
	}
}

4. Setup Cosmos Encoding and Client Config

encoding := cosmos.NewEncoding(thortypes.RegisterInterfaces)
cfg := cosmos.Config{
	Bech32AddrPrefix:  "thor",
	Bech32PkPrefix:    "thorpub",
	Bech32ValPrefix:   "thorv",
	Bech32PkValPrefix: "thorvpub",
	Denom:             "rune",
	NativeFee:         2000000,
	Encoding:          encoding,
	LCDURL:            conf.LCDURL,
	RPCURL:            conf.RPCURL,
	WSURL:             conf.WSURL,
}

5. Initialize Metrics

prometheus := metrics.NewPrometheus("thorchain-v1")

6. Create Cosmos SDK HTTP Client

httpClient, err := cosmos.NewHTTPClient(cfg)
if err != nil {
	logger.Panicf("failed to create new http client: %+v", err)
}

7. Create Block Service

blockService, err := cosmos.NewBlockService(httpClient)
if err != nil {
	logger.Panicf("failed to create new block service: %+v", err)
}

8. Create WebSocket Client

wsClient, err := cosmos.NewWebsocketClient(cfg, blockService, errChan)
if err != nil {
	logger.Panicf("failed to create new websocket client: %+v", err)
}

9. Initialize and Start API Server

api := api.New(cfg, httpClient, wsClient, blockService, *swaggerPath, prometheus)
defer api.Shutdown()

go api.Serve(errChan)

10. Wait for Errors or OS Signals

select {
case err := <-errChan:
	logger.Panicf("%+v", err)
case <-sigChan:
	api.Shutdown()
	os.Exit(0)
}

Usage Examples

Running with Environment Variables

Set the required environment variables and run:

export LCD_URL=https://thorchain-node.com/lcd
export RPC_URL=https://thorchain-node.com/rpc
export WS_URL=wss://thorchain-node.com/ws

go run main.go

Running with an Env File and Custom Swagger Spec

go run main.go -env ./config/thorchain.env -swagger ./api/swagger.json

Important Implementation Details


Interaction with Other Components


Mermaid Flowchart Diagram

The following flowchart illustrates the startup workflow and interactions between the main components initialized in this file:

flowchart TD
    A[Start main.go] --> B[Parse CLI flags]
    B --> C[Load configuration]
    C --> D[Setup Cosmos encoding & config]
    D --> E[Initialize Prometheus metrics]
    E --> F[Create Cosmos HTTP client]
    F --> G[Create Block Service]
    G --> H[Create WebSocket client]
    H --> I[Initialize API server]
    I --> J[Start API server (goroutine)]
    J --> K[Wait for errors or OS signals]
    K -->|Error received| L[Log and Panic]
    K -->|Signal received| M[Shutdown API server]
    M --> N[Exit process]

Summary

`main.go` is the bootstrap file that sets up the Thorchain v1 API server environment. It handles configuration, client creation, metrics, and lifecycle management to expose Thorchain blockchain data via a RESTful API and WebSocket. The file uses best practices for configuration flexibility, error handling, and graceful shutdown, integrating several internal and external packages to provide a robust server foundation.