Restful API created with Go and the Gin framework that implements some functions of a bitcoin wallet.
- Make sure you have Go, version 1.21.4 or higher, installed on your device;
- Create a valid .env file following the .env.example template that is in the root of the project;
- Ensure that no application is listening on port :8080.
Before running locally, run the command below to ensure that all dependencies will be installed:
go mod download
Running the API without build:
At the root of the project, run the command:
go run ./main.go
The project includes a Makefile to help you manage common tasks more easily. Here's a list of the available commands and a brief description of what they do:
make run
: Run the application in gin debug mode.make build
: Build the application and create an executable file namedgowallet
.make release
: Run the application in gin release mode.make test
: Run tests for all packages in the project.make test-verbose
: Run tests for all packages in the project in verbose mode.make test-coverage
: Runs tests for all packages and shows coverage.make clean
: Remove thegowallet
executable.
To use these commands, simply type make
followed by the desired command in your terminal. For example:
make run
This project includes a Dockerfile
and docker-compose.yml
file for easy containerization and deployment.
Running application with Docker:
At the root of the project:
docker build -t your-image-name .
: Build a Docker image for the project. Replaceyour-image-name
with a name for your image.docker run -d -p 8080:8080 --name your-container-name your-image-name:latest
: Run a container based on the built image in detached mode. Replaceyour-container-name
with a name for container and replaceyour-image-name
with the name you used when building the image.docker stop your-container-name
: Stop the container running the application.docker start your-container-name
: Restarts the previously initialized container.
Using Docker compose:
If you want to use Docker Compose, follow these commands in the root of the project:
docker compose up -d
: Build and run the services defined in thedocker-compose.yml
file in detached mode.
To stop and remove containers, networks, and volumes defined in the docker-compose.yml
file, run:
docker-compose down
The base url will be: http://localhost:8080/api/v1
Health [GET]: /health
Try with curl: curl -svX GET 'http://localhost:8080/api/v1/health'
Response:
External API response time is calculated by making three simultaneous calls to the external api using goroutines.
HTTP code: 200 OK
{
"status": "healthy",
"timestamp": "2023-12-07T11:58:38-03:00",
"uptime": "0D 0H 15M 9S",
"externalApi": {
"status": "Ok",
"responseTime": "1169ms"
}
}
Details [GET]: /details/19SH3YrkrpWXKtCoMXWfoVpmUF1ZHAi24n
Try with curl: curl -svX GET 'http://localhost:8080/api/v1/details/19SH3YrkrpWXKtCoMXWfoVpmUF1ZHAi24n'
Possible responses:
HTTP code: 200 OK
{
"address": "19SH3YrkrpWXKtCoMXWfoVpmUF1ZHAi24n",
"balance": "12845845",
"totalTx": 642,
"balanceCalc": {
"confirmed": "12845845",
"unconfirmed": "0"
},
"total": {
"sent": "176043318",
"received": "188889163"
}
}
HTTP code: 404 Not Found
{
"message": "Adress <invalid_address> not found"
}
HTTP code: 500 Internal Server Error
{
"message": "Internal server error"
}
HTTP code: 500 Bad Gateway
{
"message": "Failed to request external resource"
}
Balance [GET]: /balance/19SH3YrkrpWXKtCoMXWfoVpmUF1ZHAi24n
Try with curl: curl -svX GET 'http://localhost:8080/api/v1/balance/19SH3YrkrpWXKtCoMXWfoVpmUF1ZHAi24n'
Possible responses:
HTTP code: 200 OK
{
"confirmed": "12845845",
"unconfirmed": "0"
}
HTTP code: 404 Not Found
{
"message": "Adress <invalid_address> not found"
}
HTTP code: 500 Internal Server Error
{
"message": "Internal server error"
}
HTTP code: 500 Bad Gateway
{
"message": "Failed to request external resource"
}
Send [POST]: /send
Request body:
{
"address": "<string> - Bitcoin address",
"amount": "<string> - The amount to send (in Satoshis). Note that this should be a string representation of a number"
}
Try with curl: curl -svX POST "http://localhost:8080/api/v1/send" -H 'Content-Type: application/json' -d '{"address": "19SH3YrkrpWXKtCoMXWfoVpmUF1ZHAi24n", "amount": "1208053"}'
Possible responses:
HTTP code: 200 OK
{
"utxos": [
{
"txid": "3672b48dcb1494a30ad94b2cd092cc380d6bb475b86ca547655a65c0c27941e5",
"amount": "1146600"
},
{
"txid": "4148e2e46000c3a988ae2b7687a40b2bab7f29fb822ecc22912566d7b74330a4",
"amount": "1100593"
}
]
}
HTTP Code 400 Bad Request
{
"message": "Error message will depend on the specific issue with the request body"
}
HTTP code: 404 Not Found
{
"message": "Adress <invalid_address> not found"
}
HTTP code: 500 Internal Server Error
{
"message": "Internal server error"
}
HTTP code: 500 Bad Gateway
{
"message": "Failed to request external resource"
}
Transaction [GET]: /tx/3654d26660dcc05d4cfb25a1641a1e61f06dfeb38ee2279bdb049d018f1830ab
Try with curl curl -svX GET 'http://localhost:8080/api/v1/tx/3654d26660dcc05d4cfb25a1641a1e61f06dfeb38ee2279bdb049d018f1830ab'
Possible responses:
HTTP code: 200 OK
{
"addresses": [
{
"address": "bc1qyzxdu4px4jy8gwhcj82zpv7qzhvc0fvumgnh0r",
"value": "484817655"
},
{
"address": "36iYTpBFVZPbcyUs8pj3BtutZXzN6HPNA6",
"value": "623579"
},
{
"address": "bc1qyzxdu4px4jy8gwhcj82zpv7qzhvc0fvumgnh0r",
"value": "422126277"
}
...
],
"block": 675674,
"txID": "3654d26660dcc05d4cfb25a1641a1e61f06dfeb38ee2279bdb049d018f1830ab"
}
HTTP code: 404 Not Found
{
"message": "Adress <invalid_transaction_id> not found"
}
HTTP code: 500 Internal Server Error
{
"message": "Internal server error"
}
HTTP code: 500 Bad Gateway
{
"message": "Failed to request external resource"
}
The tests were created with built-in Go packages and the testify toolkit.
To run the tests you can use the makefile commands mentioned above or, at the root of the project, run:
go test ./...
For a more verbose result:
go test -v ./...
To see test coverage:
go test -v ./... -coverprofile=cover.out