This project's name aims to poke lighthearted fun at Blockchain and Cryptocurrency enthusiasts. I neither support nor endorse the use of Blockchain technologies as a store of wealth.
Blockchains are an impressive and interesting technology that encompasses some potentially useful applications.
This is a demonstration project in Golang
that provides an API for basic banking of Cryptocurrencies. There are
integrations with quote services to obtain realtime Fiat and Cryptocurrency prices.
This project will be leverage an RDBMS (PostreSQL) because of the need for ACID transactions, rollbacks, and row-level locking across tables. A Redis cache is employed as a session store.
Encryption is vital to help safeguard against theft of login credentials and JSON Web Tokens.
In a production environment, TLS
would be the only HTTP protocol over which the API endpoints would be exposed. Setting
up the TLS
/SSL
certificated for a Dockerized demonstration environment is unnecessary and complicates the tester's
experience.
Other methods like envelope encryption of payloads add an extra layer of security, but these add an excessive overhead for the use case and workloads here.
Credentials have been stored in plaintext within the demonstration files. This poses a security risk and is a technique employed to make testing and deployment of this demonstration application easier. In a production environment, the credentials would be stored in a secure credential store and mounted as environment variables or files in the container. Yet another option would be to encrypt the configuration files as Mozilla Secret OPerationS (SOPS).
The Docker container build script leverages SOPS
and will decrypt the secrets when the application is launched. Please
see the configs readme file for details.
This demonstration environment will launch both the HTTP REST
as well as the GraphQL
over HTTP
endpoints. This is
unsuitable for a production environment.
Ideally, each of these protocol endpoints would be exposed in its own clusters with auto-scaling, load balancing, and across availability zones.
Limitations on GraphQL Query and Mutation complexity have not been employed to make testing of this demonstration application easier.
Price quotes for Crypto and Fiat currencies are obtained through external third-party providers. The API endpoints used
in this project can be accessed with free accounts. Details can be found in the quotes
package.
🪧 When launching the Docker container for local testing the API Keys can be set via environment variable on the CLI. Please see the Docker container section below on how to set these.
Configuration information for the logger can be found in the logger
package.
Information regarding authentication configurations can be found in the auth
package.
Details on the HTTP endpoints can be found in their respective packages below.
The HTTP endpoint details are located in the REST
package. The model used for REST API calls can
be found in the models
package.
To review the REST API request and response formats please see the readme in the REST handlers
package. The REST API server does also provide a Swagger UI to examine and test the API calls with details on request
formats.
The Swagger UI can be accessed using the provided default configurations through http://localhost:33723/swagger/index.html.
GraphQL has been exposed through an HTTP endpoint GraphQL
package. The schema for the GraphQL queries
and mutations can be found in GraphQL package's schema
.
To review the GraphQL API request and response formats please see the readme in the resolvers
directory. The GraphQL server does also provide a Playground to examine and test the API calls with details on request
formats.
The Playground can be accessed using the provided default configurations through http://localhost:47130/api/graphql/v1/playground.
Please provide the ARCH=
variable with linux
or darwin
as needed.
Build
make build ARCH=linux
Clean
make clean
To build the container for deployment in a Kubernetes cluster please run the docker build
command
with the required parameters. Please also review the configuration files in the configs
folder and appropriately adjust the ports exposed in the container.
There are port configurations to expose the HTTP REST and GraphQL endpoints. They can be configured
from inside the Dockerfile
and must match the config .yaml
files. To expose them, please see the
-P
Docker flag.
When testing using docker compose
or running the Docker container built using the Dockerfile
on a local machine, you
may use the ifconfig
command in the net-tools
package to obtain your Host IP:
ifconfig | grep 'inet 192'
To build the Docker container using the Dockerfile
run the following command from the project root
:
docker buildx build --file=docker/Dockerfile -t=ftex .
You may then supply the configurations for the database host addresses, the API keys for the quote services, as well as publish ports using environment variables.
Environment variables can be set using the Kubernetes deployment configurations as well as when launching the container using the Docker CLI.
To supply the environment variables using the Docker CLI, please use the -e
flag. Below is an example of how to supply
the API Keys for the Fiat and Cryptocurrency quote services, database host information, port mappings, and age
secret/private key for SOPS
decryption. Please see the Docker run
documentation for more details.
docker run -d \
-p 33723:33723 \
-p 47130:47130 \
-e POSTGRES_CONNECTION.HOST=192.168.0.211 \
-e REDIS_CONNECTION.ADDR=192.168.0.211:7379 \
-e QUOTES_FIATCURRENCY.APIKEY='some-api-key' \
-e QUOTES_CRYPTOCURRENCY.APIKEY='some-api-key' \
-e SOPS_AGE_KEY='some-SOPS-secret-key' \
ftex
To spin-up the Postgres and Redis containers, please use the commands below from the project root directory.
Create containers:
docker compose -f "docker/docker-compose.yaml" up -d
Destroy containers:
docker compose -f "docker/docker-compose.yaml" down
List Containers and Check Health:
docker ps
docker inspect --format='{{json .State.Health}}' postgres
docker inspect --format='{{json .State.Health}}' redis
Get IP Addresses:
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' postgres
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis
Postgres:
- Username :
postgres
- Password :
postgres
- Port :
6432
- Database :
ftex_db
Redis:
-
Username :
default
-
Password :
v7h0JZq8AZhVcF3NWz9u
-
Username :
ftex_service
-
Password :
ZoF1bncLLyYT1agKfWQY
-
Port :
7379
-
Database:
0