A Coinbase clone is a cryptocurrency investment application that enables users to buy and sell cryptocurrencies listed on the Coinbase exchange.
Live: http://coinbase-842009998.ap-southeast-1.elb.amazonaws.com
alternative: http://coinbase-clone.surge.sh
This project was a number of task which involved myself in developing applications using the core technologies of Python, Flask, Redis, PostgreSQL, Tanstack's React-query, Tailwind CSS, React and Typescript with as minimum-number as possible of dependency module. As well as to operating using the core technologies of Docker, bash script, production deployment, Hashicorp Consul, microservices, Nginx and more. The project lasted 120 working days without using any AI tools. This was both a practicing and a learning experience.
Initially, I was interested in building an application related to finance, which is currently trending. The idea was to create a simplified version of an existing app. But why choose Coinbase? Although I’m not a Coinbase user and haven’t actively used similar apps before, especially for crypto transactions, this presented a new challenge for me: understanding the world of cryptocurrency. Another challenge arose when I discovered that Coinbase is inaccessible in my country. While direct access wasn’t crucial, I needed an overview of the app’s functionalities. My solution involved searching for screen captures on Google Images and watching YouTube videos to understand the latest interface and key actions, like transactions. VPNs weren’t very helpful since registration required identity verification and phone number from supported countries. Lastly, I refrained from inspecting any code on the Coinbase website, opting instead to mimic what I observed—similar but not identical. Overall, this project served as both a learning experience and a portfolio piece for me.
The UI/UX design was heavily inspired by Coinbase especially their explore and dashboard pages. The UI has made looking as close as possible to the Coinbase web application by view and navigating their web application. I restricted myself from inspecting any code on their website and still don't know which webfont and color codes they used.
- Secure user authentication
- Dashboard preview asset holdings, transaction history and more
- Personal dashboard, identity, profile and settings
- Real-time and historical price data in USD and a few currencies
- Thousands real world active cryptocurrencies
- Capability to simulate real time cryptocurrency trades with real time market price
- Line charts display price data over time
- Lightweight and fast by using cache in client (browser) and backend server (Redis)
- Highly scalable
- Configurable Rate limiter
- In production, dev-team can change config by execute a single command then the app will reload auatomagicaly with new config
- Idempotency concept to avoid user accidentaly pay twice for same order
- Search any cryptocurrencies by string is optimized
- Heavily responsive design built with Tailwind CSS
- SPA/Single page application (CSR)
- Strongly typed React components with TypeScript
- Cryptocurrencies big-table pagination
- Cryptocurrencies big-table infinity scroll
- Automatically log out users after a period of inactivity
- Flask v2.3
- Flask-JWT-Extended
- Flask-Bcrypt
- Flask-Cors
- Gunicorn
- PostgreSQL
- SQLAlchemy
- Redis
- Celery
- Hashicorp Consul
- Nginx
- SQLite3 Development only
- CoinMarketCap API
- YahooFinance API
- OpenExchangeRates API
- CryptoNews API
The backend is structured using the Application Factory Pattern.
The entry point is the create_app()
method in run.py
(wsgi.py
in production).
- React v18
- TypeScript
- Tanstack React Query v4
- TailwindCSS
- React Router v6
- Vite
- Apache ECharts
- React-sparklines
Entry point is at frontend/src/main.tsx
.
- Python >= 3.11
- PostgreSQL >= 16.1 (Production)
- Redis >= 7.2
- Nginx >= 1.25
- Hashicorp Consul 1.17 (optional)
- SQLite3 (Development)
- Ensure that TLS certification, such as Let's Encrypt, is assigned.
Prerequisites:
Ensure that Docker is installed on your machine.
# Clone the repo
$ git clone https://github.com/saptarian/coinbase-clone.git
$ cd coinbase-clone
# Environtment variable (the defaults are fine enough)
# Api Keys in section 3RD API are required in order to fully functionality
$ edit `.env.example` and save as `.env`
$ edit `frontend/.env.example` and save as `frontend/.env`
# Note: edit .env to swicth FLASK_ENV variable to 'production' instead 'default' in order to use PostgreSQL instead SQLite3
# Configs (the defaults are fine enough)
$ - `app/config.py`
$ - `app/gunicorn.py`
$ - `nginx.conf`
$ - `frontend/nginx.conf`
# Build and start everything:
# - Make sure docker service is running!
# - The first time you run this it's going to take 5-10 minutes depending on your internet connection speed and computer's hardware specs.
# That's because it's going to download a few Docker images and build the Python + dependencies.
$ docker compose up --build
# Once the backend server running:
# Ensure everything are set up correctly by execute this command on new terminal
$ curl -XGET http://localhost:5000/up/
# No result means no error then you are good to go next step
# (init, migrate and upgrade) the database by single command:
$ chmod +x run
$ ./run db_init
# Execute database generator script:
$ python3 script/assets_seed_generator.py
# Use generated sql file to populate the database:
$ ./run db_seed
# To start the frontend in the same host:
# open another terminal then run this command
$ ./run fe:build # OR $ ./run fe:build https://your-backend-base-url.com
$ ./run fe:run
Once it's done building and everything has booted up:
- Access the app at: http://localhost:8080
# To change env variable directly on running backend e.g.
$ ./run putenv RATE_LIMIT 120
# Once success the config on backend app changed, the app will reload and running with new config automatically
Inspect file run
for other useful command such as reup
, rebuild
, etc
Prerequisites:
Python >= 3.11
SQLite3 (for development it's required instead PostgreSQL)
Redis
Nodejs >= v20
# Clone this repo
$ git clone https://github.com/saptarian/coinbase-clone.git
$ cd coinbase-clone
# Create virtual environtment
$ python3 -m venv venv
# [Windows system] Activate virtual environtment
$ `venv\\Scripts\\activate`
# [*uix system] Activate virtual environtment
$ source venv/bin/activate
# On *nix machine before going to the next step ensure you have installed some prerequisites:
# - libpq-dev, python3-dev, gcc. It's depends on your linux machine to install these packages
# [Red Hat-based distributions, Amazon Linux 2023]
$ sudo yum update
$ sudo yum install -y python3-devel postgresql-devel gcc
# [Debian related distributions, Ubuntu]
$ sudo apt-get update
$ sudo apt-get install -y python3-dev libpq-dev gcc
# Install python requirement modules
$ pip install -r requirements.txt
# Environtment variable (the defaults are fine enough)
# Api Keys in section 3RD API is required in order to fully functionality
$ edit `.env.example` and save as `.env`
$ edit `frontend/.env.example` and save as `frontend/.env`
# Configs (the defaults are fine enough)
$ - `app/config.py`
$ - `app/gunicorn.py`
$ - `nginx.conf`
$ - `frontend/nginx.conf`
# Database init
$ flask --app run.py db init
# Run database migrations
$ flask --app run.py db migrate
$ flask --app run.py db upgrade
# Before going to the next step ensure your Redis server has running on it's default port
# Start flask application server
$ flask --app run.py run
# Once the backend server running open new terminal on the same directory 'coinbase-clone'
# Generate database seed by execute script with flask base url e.g. http://localhost:5000
$ python3 script/assets_seed_generator.py http://localhost:5000
# Use generated sql file to populate the database with thousands of active real-world cyptocurrencies
# SQLite3
$ sqlite3 app/coinbase_clone.db < assets_seed.sql
# PostgreSQL
$ psql -U "coinbase" -d "coinbase" < "assets_seed.sql"
# Open new terminal to start frontend in development mode:
$ cd frontend
$ npm install
$ npm run dev
Check the backend services (flask app, redis, database) by command:
$ curl -XGET http://localhost:5000/up/
# No result means no error then everything are set up correctly
Sapta Rianza [email protected] I am a new self taught developer.
Contributions are welcome! If you find a bug or have a suggestion for a new feature, please create an issue or submit a pull request.
This project is licensed under the MIT License.