A real time cryptocurrency tracker to stay on top of your precious coins. Get lightning fast updates about the 100 most popular cryptocurrencies, and add them to your watchlist to keep a close eye on it. With a sleek UI, you get exactly what you need without having to go through a bajillion numbers and scary graphs.
Client: React (Typescript), Zustand, Websockets, TailwindCSS.
Server: Go, Fiber, GORM, PostgreSQL.
The backend is built with Go for performance and scalability, paired with PostgreSQL to handle large datasets and frequent queries. Fiber is used over Gin due to its native WebSocket support. On the frontend, React with TypeScript ensures type safety, while Zustand manages global state efficiently. TailwindCSS enables rapid and customizable UI development. WebSockets are preferred over Socket.io for better Go compatibility, and JWT handles authentication seamlessly.
- Go (1.23.4 or higher)
- npm and Node.js
- PostgreSQL 17 (or higher)
- Build the backend
go build cmd/crypTracker/main.go
- Install node dependencies in
web
and build the frontend
cd web
npm install
npm run build
- Create a .env file in the
root
directory with the following values. DB_URL must be for PostgreSQL with the following keys.
COINGECKO_API_KEY="your_API_key"
DB_URL="host user password dbname port sslmode"
RUNTIME_ENV="production"
SECRET="JWT Secret"
VITE_SECRET="Same secret as SECRET"
PORT=8080
VITE_PORT=8080
- Go back to the
root
directory and run the build file
cd ..
./main
The app must now be running on http://localhost:PORT
GET /test
Response:
"Testing mount"
GET /crypto/coins
Response:
[
{
"coin_gecko_id": "string",
"symbol": "string",
"name": "string",
"current_price": "number",
"market_cap": "number",
"updated_at": "timestamp",
"image": "string"
}
]
GET /crypto/coins/:coinId
Response:
{
"coin_gecko_id": "string",
"symbol": "string",
"name": "string",
"current_price": "number",
"market_cap": "number",
"updated_at": "timestamp",
"image": "string",
"description": "string",
"graph_data": "array"
}
Error Response:
{
"message": "'coinId' doesn't exist",
"status": 400
}
POST /users/
Request Body:
{
"username": "string",
"password": "string"
}
Response:
{
"message": "201 : Successfully registered user",
"user_data": {
"user_id": "string",
"username": "string"
}
}
POST /users/login
Request Body:
{
"username": "string",
"password": "string"
}
Response:
{
"message": "Successfully logged in user : username!",
"user_id": "string",
"user_data": {
"user_id": "string",
"username": "string"
}
}
GET /users/:userId/signout
Response:
{
"message": "Successfully signed out"
}
GET /users/:userId
Response:
{
"user_id": "string",
"username": "string",
"profile_image": "string",
"created_at": "timestamp"
}
DELETE /users/:userId
Response:
{
"message": "Successfully deleted user : userId"
}
PUT /users/:userId
Request Body:
{
"username": "string",
"password": "string"
}
Response:
{
"user_id": "string",
"username": "string"
}
GET /users/:userId/watchlist
Response:
[
{
"coin_gecko_id": "string",
"symbol": "string",
"name": "string",
"current_price": "number",
"market_cap": "number",
"updated_at": "timestamp",
"image": "string"
}
]
POST /users/:userId/watchlist
Request Body:
{
"coin_id": "string"
}
Response:
{
"user_id": "string",
"coin_gecko_id": "string"
}
DELETE /users/:userId/watchlist
Request Body:
{
"coin_id": "string"
}
Response:
{
"message": "Successfully deleted coin_id from watchlist"
}
GET /ws
Description: Establishes a WebSocket connection for real-time communication.
Headers:
Upgrade: websocket
Connection: Upgrade
Response:
- On success, the client is upgraded to a WebSocket connection.
- On failure, returns:
{
"message": "426 Upgrade Required"
}
I've planned on including the following features in the near future
- Coin price graphs (InfluxDB + Grafana)
- Dockerfile (to make setup easier)
- PFP storage using Amazon S3 buckets