Knightchaser's Cryptocurrency eXchange
You can try KCX at https://kcx.knightchaser.com/, hosted via AWS Lightsail by the repository owner. Note that the specifications, service status, and other things might be changed depending on the development contexts and situations. (Try only for fun! :D)
The KCX service on the AWS LightSail has been discontinued since Sep. 3, 2024 due to financial issues. During the services with 87 days, 3,566 transactions worth 16.7 trillion KRW(12.525 billion US$) were made(If all money in the services were REAL). Thanks for loving this project, my first attempt to make a modern website!
Currently, there are environment variables to set up the services as you need. Read the next chapter(Deployment
) for complete contextual information.
SQLALCHEMY_DB_SQLITE3_FILENAME="kcx.db"
TEST_ACCOUNT_ID="test"
TEST_ACCOUNT_PW="test"
TEST_ACCOUNT_EMAIL="[email protected]"
COMMON_STARTING_BALANCE_IN_KRW=20000000000 # 20 billion KRW
# An example SECRET KEY for JWT. Change this to a random in production!
JWT_SECRET_KEY="KCXU$3R$3CR3T4JWT_"
JWT_TOKEN_EXPIRES_MINUTES=360 # 6 hours
# A custom API server built with Redis
REDIS_PORT=6379
REDIS_DB=0
REDIS_UDPATE_INTERVAL_IN_SECONDS=1
USER_RANKING_UPDATE_INTERVAL_IN_SECONDS=10
# Service configuration
# - Money balance (Disable(false) this if you want to use a fixed starting balance for all users)
ALLOW_ARBITRARY_BALANCE_DEPOSIT=false
ALLOW_ARBITRARY_BALANCE_WITHDRAW=false
SQLALCHEMY_DB_SQLITE3_FILENAME
to change the filename (if you want).TEST_ACCOUNT_ID
(ID = username), TEST_ACCOUNT_PW
(password), and TEST_ACCOUNT_EMAIL
(email) for the test account.COMMON_STARTING_BALANCE_IN_KRW
defines how much fund will be initially granted to the new user.JWT_SECRET_KEY
for JWT server key(change to another random value or your own) and JWT_TOKEN_EXPIRES_MINUTES
for JWT expiary period.REDIS_UPDATE_INTERVAL_IN_SECONDS
means which second this service refreshes the market data from UpBIT to the REDIS cache periodically. Basically, you can safely request up to 5 requests per second to UpBIT according to the current policy.USER_RANKING_UPDATE_INTERVAL_IN_SECONDS
means which second this service calculate the users' ranking data according to the calculated estimated total asset value periodically (for leaderboard). Note that this ranking calculation relatively takes a lot of computational loads(iterating all users and calculating all types of assets for estimation), so don't make it too short.ALLOW_ARBITRARY_BALANCE_*
configures whether the user controls their virtual balances on their own. If these are set true, then they can unlimitedly deposit(increase) and withdraw(decrease) the wallet, that may impact on the leaderboard. If you run this service for competitions or some rules, set it to false so no one except for the administrator can control the user's balances. (By accessing the SQLite3 database.)Plus, there is a feature of sending verification emails for changing account email address/password, or recoverying password. Get a possible SMTP(Simple Mail Transfer Protocol) account, and create the following environment variable file named <PROJECT_DIR>/backend/.secrets.smtp
, fill the contents like below. If you use Gmail for SMTP, the configuration would like below.
# backend/.secrets.smtp
SMTP_USERNAME="knightchaser_example" # Gmail address without "@gmail.com"
SMTP_PASSWORD="abcd efgh ijkl mnop" # App password
SMTP_SERVER="smtp.gmail.com"
SMTP_PORT=587
https://github.com/KnightChaser/kcx.git
docker-compose
(Or, docker compose
for Docker Compose v2. Not matter which version you use).docker-compose -f docker-compose.yml build
docker-compose -f docker-compose.yml up -d
https://kcx.knightchaser.com
is currently running on this way.), check the prerequisites and operate the docker.*.knightchaser.com
and it's registered on the global DNS server. (i.e. Route53 in AWS)letsencrypt
)Note about TLS/SSL
.). Then, boot up the service with the following commands.docker-compose -f docker-compose-server-deploy.yml build
docker-compose -f docker-compose-server-deploy.yml up -d
<PROJECT_DIR>/data
. Back up this directory periodically in case of deployment!data
┣ database
┃ ┗ (SQLite3 database file)
┗ uploads
┃ ┗ profile_images
┃ ┃ ┣ (user profile pictures)
...
The TLS/SSL extensions are expected to be in /etc/letsencrypt
in general if you use letsencrypt
.
(/etc/letsencrypt)
├── live
│ ├── README
│ └── knightchaser.com
│ ├── README
│ ├── cert.pem -> ../../archive/knightchaser.com/cert1.pem
│ ├── chain.pem -> ../../archive/knightchaser.com/chain1.pem
│ ├── fullchain.pem -> ../../archive/knightchaser.com/fullchain1.pem
│ └── privkey.pem -> ../../archive/knightchaser.com/privkey1.pem
In nginx.conf
, the basic structure will be the below example. (The given example is https://kcx.knightchaser.com
's.) Change server_name
, ssl_certificate
, and ssl_certificate_key
properties to your own.
```nginx
events { }
http { server { listen 80; server_name kcx.knightchaser.com; return 301 https://$host$request_uri; }
server {
listen 443 ssl;
server_name kcx.knightchaser.com;
ssl_certificate /etc/letsencrypt/live/knightchaser.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/knightchaser.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://frontend:5173;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /api/ {
proxy_pass http://backend:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
- In the **Docker compsure file(`docker-compose-server-deploy.yml`)**, adjust the `volumes` part of **`nginx`** to yours(if it's needed). If you follow the standard `letsencrypt`'s TLS/SSL issuing procedure with Certbot, this adjustment won't be necessary.
```yml
...
nginx:
image: nginx:latest
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- /etc/letsencrypt:/etc/letsencrypt
depends_on:
- frontend
- backend
networks:
- kcx-network
<PROJECT_DIR>/frontend/.env
(Vite environment variable file), adjust the backend API URL to your domain. Since the suffix string /api
is the hardcoded value of this project for consistency, you will only have to adjust the URL part. https://kcx.knightchaser.com
part for the example below.VITE_BACKEND_API_URL="https://kcx.knightchaser.com/api"
443
. Allow 80
and 443
ports at least.