Go application used to collect and return information about blockchain headers
Block header service is a go service which connects into BSV P2P network to gather and then serve information about all exisiting and new headers. It is build to work as a standaolne app or a module in bigger system.
The main functionality of the application is synchornization with peers and collecting all headers. After starting the server, it creates default objects and connects to BSV P2P network. Application has defined checkpoints (specific headers) which are used in synchronization. During this process, server is asking peers for headers (from checkpoint to checkpoint) in batches of 2000. Every header received from peers is saved in memory. After full synchronization, server is changing the operating mode and start to listening for new header. After when new block has been mined, this information should be sended from peers to our server.
For in-depth information and guidance, please refer to the SPV Wallet Documentation.
Pull image from docker hub https://hub.docker.com/r/bsvb/block-headers-service
docker pull bsvb/block-headers-service
Starting new instance
docker run bsvb/block-headers-service:latest
For endpoints documentation you can visit swagger which is exposed on port 8080 by default.
http://localhost:8080/swagger/index.html
The default assumes you want to use Authentication. This requires a single environment variable.
BHS_HTTP_AUTH_TOKEN=replace_me_with_token_you_want_to_use_as_admin_token
To disable authentication exposing all endpoints openly, set the following environment variable. This is available if you prefer to use your own authentication in a separate proxy or similar. We do not recommend you expose the server to the internet without authentication, as it would then be possible for anyone to prune your headers at will.
BHS_HTTP_USE_AUTH=false
After the setup of authentication you can use provided token to authenticate. To do it, just add the following header to all the requests to block-headers-service.
Authorization Bearer replace_me_with_token_you_want_to_use_as_admin_token
If you have a need for additional tokens to authenticate in block-headers-service. you can generate such with the following request:
POST https://{{block-headers-service_url}}/api/v1/access
Authorization: Bearer replace_me_with_token_you_want_to_use_as_admin_token
In response you should receive something like
{
"token": "some_token_created_by_server",
"createdAt": "2023-05-11T10:20:16.227582Z",
"isAdmin": false
}
Now you can put a value from "token" property from the response and use it in all requests to server by setting header:
Authorization: Bearer some_token_created_by_server
If at some point you want to revoke this additional token you can make a request:
DELETE https://{{block-headers-service_url}}/api/v1/access/{{some_token_created_by_server}}
Authorization: Bearer replace_me_with_token_you_want_to_use_as_admin_token
After this request succeeded the token can't be used to authenticate in block-headers-service.
Block headers service can notify a client via websockets that new header was received and store by it.
Block headers service use centrifugal/centrifuge to run a server. Therefore, to integrate you need to choose a client library matching a programming language of your choice.
Example how to subscribe using GO lang library centrifugal/centrifuge-go can be found in ./examples/ws-subscribe-to-new-headers/
Creating a new webhook is done via POST request
POST https://{{block-headers-service_url}}/api/v1/webhook
Data which should be sent in body:
{
"url": "<server_url>",
"requiredAuth": {
"type": "BEARER|CUSTOM_HEADER",
"token": "<authorization_token>",
"header": "<custom_header_name>",
}
}
Information:
- If authorization is enabled this request also requires
Authorization
header - url have to include http or https protocol example:
https://test-url.com
- requiredAuth is used to define authorization for webhook
- type
BEARER
- token will be placed inAuthorization: Bearer {{token}}
header - type
CUSTOM_HEADER
- authorization header will be build from given variables{{header}}: {{token}}
- type
Example response:
{
"url": "http://example.com/api/v1/webhook/new-header",
"createdAt": "2023-05-11T13:05:23.297808+02:00",
"lastEmitStatus": "",
"lastEmitTimestamp": "0001-01-01T00:00:00Z",
"errorsCount": 0,
"active": true
}
After that webhook is created and will be informed about new headers.
To check webhook you can use the GET request which will return webhook object (same as when creating new webhook) from which you can get all the information
GET https://{{block-headers-service_url}}/api/v1/webhook?url={{webhook_url}}
If you want to revoke webhook you can use the following request:
DELETE https://{{block-headers-service_url}}/api/v1/webhook?url={{webhook_url}}
This request will delete webhook permanently
If the number of failed requests wil exceed WEBHOOK_MAXTRIES
, webhook will be set to inactive. To refresh webhook you can use this same endpoint as for webhook creation.
- Install Go according to the installation instructions here: http://golang.org/doc/install
Options to run Block Headers Service:
a) Clone the repo
git clone https://github.com/bitcoin-sv/block-headers-service
go run ./cmd/main.go
Or run app with docker
docker compose up --build
b) Get package from pkg.dev.go
go get -u https://pkg.go.dev/github.com/bitcoin-sv/block-headers-service
go build -o block-headers-service
./block-headers-service
Every variable which is used and can be configured is described in config.example.yaml
If you run block headers service without editing anything, it will use the default configuration from file defaults.go. It is set up to use sqlite database with enabled authorization (with default auth key) for http server.
Default config variables can be overridden by (in this order of importance):
- Flags (only the ones below)
- ENV variables
- Config file
Available flags:
-C, --config_file string custom config file path
-h, --help show help
-v, --version show version
-d, --dump_config dump config to file, specified by config_file (-C) flag
-e, --export_headers export headers to file
To generate config file with defaults, use the --dump flag, or:
go run ./cmd/main.go -d
The default config file path is program root, and the default file name is config.yaml. This can be overridden by -C flag.
go run ./cmd/main.go -C /my/config.yaml
To override any config variable with ENV, use the "headers-service_" prefix with mapstructure annotation path with "_" as a delimiter in all uppercase. Example:
Let's take this fragment of AppConfig from config.example.yaml
:
websocket:
# Maximum number of history items
history_max: 300
# History time-to-live
history_ttl: 10
To override history_max in websocket config, use the path with "_" as a path delimiter and bhs_ as prefix. So:
BHS_HISTORY_MAX=300
When you start the application, and synchronization process is long when using prepared database, it's recommended to use the -e
flag to export fresh database with all headers. This will speed up the process of synchronization in the future.
Note:: Export feature works only with SQLite database.
go run ./cmd/main.go -e
This will create a new .csv file with all headers in the same directory as the database file. Commit your changes and create a pull request with the new database file.