Awesome
<p align="center"> Built on <img src="https://user-images.githubusercontent.com/2101767/118615635-3aeb4380-b7c1-11eb-93d9-a46438542020.png" width="200"> </p>OpenAlgoNFT
OpenAlgoNFT is an open-source cloud-native platform for building an NFT Marketplace on top of Algorand blockchain.
Learn more on our official case study.
Getting started with OpenAlgoNFT
There are three components involved in the platform. The frontend, the backend, and the smart contracts. The backend and frontend parts of the application have to be deployed to a server. Smart contracts are automatically deployed by the platform when new NFTs are created.
Follow the instructions below to prepare your development environment or to deploy the application to a public server.
How to deploy to Google Cloud Platform
To deploy OpenAlgoNFT we'll need to create a database, a Kubernetes cluster on the Google Cloud Platform, and install several associated tools. This guide assumes that the user has at least some proficiency in using the Google Cloud Platform.
Prerequisites
- Google Cloud Platform SDK
- Docker
- Kubernetes Tools
- Helm
- SQL Database on Google Cloud Platform
- Container Registry on Google Cloud Platform
Creating a Kubernetes cluster
- Initialize your Google Cloud Platform SDK by running
gcloud init
and following the instructions - Go to Kubernetes Engine
- Click on
Create
- Configure your cluster - for experimenting, we suggest using the
Standard
cluster with the pre-filled configuration and reduced number of nodes (depending on your budget).
- To reduce the number of nodes go to
default-pool
, changeNumber of nodes
to1
.
- Wait for your cluster to be provisioned
- Click on the
Actions
button, selectConnect
and run provided command to connect to your cluster - After that you should be able to access your Kubernetes cluster using
kubectl
command. We suggest reading Overview of kubectl.
Backend deployment
The backend
folder contains helm
folder that contains Helm chart. Helm charts help to manage the complexity of Kubernetes application deployment. Before deploying we'll need to configure our Helm chart and install Kubernetes Nginx Controller
Configuration
- Inside the
values.yaml
file, set thehost_dns
variable to your domain - Inside the
secrets.yaml
file, configure:DATABASE_URL
- URL to access the database compatible with dj-database-urlPURESTAKE_API_KEY
- Purestake API KeyGOOGLE_CREDENTIALS
- Credentials for Google Service Account encoded in base64
Deployment
- Connect your Docker to your Container Registry on Google Cloud Platform - https://cloud.google.com/container-registry/docs/advanced-authentication
- Create Kubernetes namespace using
kubectl create namespace <insert-namespace-name-here>
- Switch to that namespace using
kubectl config set-context --current --namespace=<insert-namespace-name-here>
- Run
make image && make push && make deploy
- Check if the containers are running using
kubectl get pods
- Switch to
nginx-ingress
Kubernetes namespace and get the IP number of the Nginx server usingkubectl get services
- Create a Load Balancer that points to that Nginx server
Frontend deployment
For deploying the frontend we suggest Vercel.com which can be connected to a Github repository and takes care of the deployment for you.
Creating an NFT
- Go to the admin panel in the backend part of the application
- Click on
Users
in theAPI
section of the admin panel - Click on
Add user
- Enter your Algorand address and select
Is Staff
- Click on
Save
- Visit the frontend part of the application
- Connect with your wallet
- Click on the arrow next to your address at the top bar
- Select
Create new NFT
- Proceed according to the instructions displayed on the screen
How to setup the development environment
Backend
By default, the project is configured with an SQLite database, which is embedded into the application and doesn't require any separate installation. We'll only RabbitMQ as a message queue for the background worker. For the application to be fully functional we need both a server and a background worker.
RabbitMQ
Running RabbitMQ with Docker:
- Install and run Docker
- Run
docker run -d -p 5672:5672 rabbitmq:3
- this will run RabbitMQ in the background and forward the5672
port to your computer.
Manual installation:
- Download, install and run RabbitMQ
- By default, RabbitMQ will listen on port 5672 on all available interfaces. Refer to https://www.rabbitmq.com/networking.html if you want to customize your configuration.
By default, OpenNFT is configured to connect to RabbitMQ hosted on localhost at port 5672. If you want to change it you can set the CELERY_BROKER_URL
variable in your command-line environment or inside the backend/settings_dev.py
file.
Example value of CELERY_BROKER_URL
:
amqp://guest:guest@localhost:5672//
For more information refer to Broker Settings
section of Celery documentation.
Alternatively, you can install RabbitMQ yourself and configure it to accept connections on port 5672.
Configuration
You can set the configuration variables both in your shell environment or backend/settings_dev.py
file.
PURESTAKE_API_KEY
should to be equal to your Purestake API key.
USE_TESTNET
should be equal to 0
if you want to use MainNet infrastructure.
Running development server
- Install Python 3.9 and Poetry
- Go to
backend
folder - Run
poetry install
to install the dependencies andpoetry shell
to start using a virtual environment which contains those dependencies - Migrate the database using
python manage.py migrate
command - Create admin account using
python manage.py createsuperuser
command, following the instructions on the screen. - Run the development server with
python manage.py runserver
- You can access the admin panel at http://localhost:8000/admin/
Running background worker
- Follow the section above to install the dependencies and run
poetry shell
insidebackend
folder. - Run
DJANGO_SETTINGS_MODULE=nft_market.settings_dev celery -A nft_market.celery worker --loglevel=DEBUG
and keep it running alongside the development server to test the application
Frontend
Configuration
The frontend configuration can be found in /frontend/src/config/index.js
. It contains the following variables:
ALGORAND_LEDGER
- determines the infrastructure that we want to use. Can beMainNet
orTestNet
.USDC_ID
- Identifier of Algorand Standard Asset which is going to be used as a stablecoinUSDC_DECIMAL_POINTS
- the amount of decimal points for that assetBACKEND_URL
- URL of the backend part of the application. By default, it ishttp://localhost:8000
for the development environment andhttps://nft-be.ulam.io
for the production environment.
Contract
It is necessary to run a contract development environment only if you want to introduce changes to it.
Dependencies
- You'll need to download the algorand-builder repository and link the
algob
andruntime
packages. The latest tested commit foralgorand-builder
is0cf0f338230521197079e292a4963e814fa574f2
.- To link the
algorand-builder
you need to build it usingyarn build
- Issue
yarn link
command in those folders:packages/algob
,packages/runtime
- Run
yarn link "@algorand-builder/algob"
andyarn link "@algorand-builder/runtime"
in the contract directory
- To link the
- To install the rest of the dependencies run:
poetry install
yarn install
Useful commands
Commands should be run inside the poetry shell.
Here are some useful commands:
yarn test
- running testsyarn algob compile
- contract compilationyarn deploy
- contract deployment (requires configuringalgob.config.js
and setting ASA identifiers inscripts/deploy.js
)
Debugging
Algorand has a debugging tool called tealdbg
which allows real-time debugging of the contract execution. To debug a transaction you need to supply a teal file with the contract and a dry-run of the transaction:
tealdbg debug state.teal --dryrun-req tx.dr
-tealdbg
will provide you with an address that you can enter in your browser to run the debugger
Obtaining dry-run
Dry-run can be obtained with the goal command-line tool when issuing a transaction:
goal app call --app-id {appid} --from {ACCOUNT} --out=dumptx.dr --dryrun-dump
Dry-run can be also extracted from the user interface:
- First, you need to extract the transaction which is sent to the Algorand node by the frontend part of the application
- Then you need to convert it from base64 to binary form and save it to a file
- You can use
base64 -d
to convert the base64 text to a binary form in the *nix command-line
- You can use
- At last, you need to convert the binary form to dry-run using
goal clerk dryrun -t tx.bin --dryrun-dump -o tx.dr