๐ Building a FullโStack Decentralized Marketplace with Node.js, React, MongoDB and Monero
In this guide, Iโll walk you through the complete development and deployment of MyZubster โ a productionโready marketplace where users can tokenize realโworld assets, trade them in a P2P order book, and pay with Monero (XMR). The entire stack runs on a single VPS, with a React frontend, an Express API, MongoDB, and a Monero wallet RPC.
๐ Live demo: https://myzubster.com
๐ฆ Source code: github.com/DanielIoni-creator/MyZubsterGateway
๐ Table of Contents
Why I built this
Architecture overview
Core features
Tech stack
Setup & installation
Environment configuration
Running the project locally
Deploying to production with Nginx
Integrating Monero payments
Challenges & solutions
Whatโs next
Resources
๐ก Why I built this
The idea was simple: create a platform where anyone can tokenise a physical asset (real estate, equity, art, etc.) and trade it in a secure, private marketplace. I wanted real cryptocurrency payments (not just a fiat gateway) and a smooth user experience. Monero was the obvious choice for its privacy and low fees.
The project evolved from a simple API to a fullโstack application with a modern React frontend, a robust orderโbook engine, and a fully automated Monero payment flow.
๐งฑ Architecture overview
text
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Client (Browser) โ
โ https://myzubster.com โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Nginx (reverse proxy) โ
โ โ serves static frontend โ
โ โ proxies /api/* to Node.js โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โผ โผ
โโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ React + Vite โ โ Node.js + Express โ
โ (Frontend) โ โ (Backend API) โ
โ Port 5173 (dev) โ โ Port 3000 โ
โโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ MongoDB โ
โ (Users, Tokens, Holdings, Orders, Payments) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Monero RPC Wallet โ
โ โ Generates subaddress per order โ
โ โ Monitors incoming payments โ
โ โ Autoโcompletes orders on confirmation โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
All services run on a single Ubuntu VPS (Aruba Cloud). The frontend is built with Vite and served statically by Nginx. The Node.js gateway handles all business logic and talks to MongoDB and the Monero wallet RPC.
โจ Core features
Feature Description
JWT Authentication Secure login/register with bcryptโhashed passwords
Asset Tokenisation Create tokens with metadata (name, symbol, supply, asset type, location, description)
Order Book Users can create sell orders (/api/marketplace/sell) and buy from open orders (/api/marketplace/buy/:orderId)
Holdings Track user balances with lockedAmount for tokens currently in active orders
Monero Payments Each order gets a unique subaddress; the system automatically monitors confirmations and completes the order when payment is detected
Admin Dashboard (Work in progress โ but the API already supports user management and transaction logs)
Production Ready Nginx, systemd, firewall, and SSL (optional)
๐ ๏ธ Tech stack
Backend
Node.js (v20) + Express.js
MongoDB + Mongoose ODM
JSON Web Tokens for authentication
Axios for Monero RPC calls
Systemd for service management
Frontend
React (functional components + hooks)
Vite (fast build tool)
React Router for clientโside routing
Axios for API calls (with JWT interceptors)
Infrastructure
Nginx as reverse proxy and static server
UFW for firewall
Certbot (optional) for Letโs Encrypt SSL
Cryptocurrency
Monero stagenet (testnet) โ the RPC wallet runs alongside the gateway.
๐ Setup & installation
- Clone the repository bash
git clone https://github.com/DanielIoni-creator/MyZubsterGateway.git
cd MyZubsterGateway
- Install backend dependencies bash
npm install
- Install frontend dependencies bash
cd ../myzubster-frontend # if you have it in a separate folder
npm install
If you prefer to keep everything in one repo, you can place the frontend inside a frontend/ directory.
๐ง Environment configuration
Create a .env file in the backend root:
env
Server
PORT=3000
JWT_SECRET=your_super_secret_key
MongoDB
MONGODB_URI=mongodb://localhost:27017/myzubster
Monero (stagenet)
MONERO_WALLET_RPC_URL=http://localhost:18083/json_rpc
MONERO_DAEMON_RPC_URL=http://localhost:18081/json_rpc
MONERO_RPC_USER=myzubster
MONERO_RPC_PASSWORD=your_secure_password
MONERO_NETWORK=stagenet
๐ Running the project locally
Start MongoDB
bash
systemctl start mongod
Start the backend (development)
bash
cd ~/MyZubsterGateway
node server.js
or with nodemon: npm run dev
Start the frontend (development)
bash
cd ~/myzubster-frontend
npm run dev -- --host
Now you can access:
Frontend: http://localhost:5173
API: http://localhost:3000/api/health
๐ Deploying to production with Nginx
- Build the frontend bash
cd ~/myzubster-frontend
npm run build
This creates the dist/ folder
- Move the build to a standard location bash
mkdir -p /var/www/myzubster-frontend
cp -r dist/* /var/www/myzubster-frontend/
chown -R www-data:www-data /var/www/myzubster-frontend
chmod -R 755 /var/www/myzubster-frontend
- Configure Nginx
Create /etc/nginx/sites-available/myzubster:
nginx
server {
listen 80;
server_name myzubster.com www.myzubster.com;
root /var/www/myzubster-frontend;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://localhost:3000/api/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Enable the site and reload Nginx:
bash
ln -s /etc/nginx/sites-available/myzubster /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx
- (Optional) Add SSL with Letโs Encrypt bash
apt install certbot python3-certbot-nginx -y
certbot --nginx -d myzubster.com -d www.myzubster.com
๐ช Integrating Monero payments
The gateway communicates with a Monero wallet RPC. Hereโs how it works:
- Start the Monero daemon (stagenet) bash
./monerod --stagenet --detach
- Create or open a wallet bash
./monero-wallet-cli --generate-new-wallet myzubster_wallet --password 'YourPassword' --daemon-address localhost:18081 --stagenet
- Start the wallet RPC bash
nohup ./monero-wallet-rpc \
--rpc-bind-port 18083 \
--daemon-address localhost:18081 \
--wallet-file ./myzubster_wallet \
--password 'YourPassword' \
--disable-rpc-login \
--trusted-daemon \
--stagenet > monero-wallet-rpc.log 2>&1 &
- The backend service
The moneroService.js uses axios to call the RPC methods:
create_address โ generates a unique subaddress per order
get_transfers โ checks incoming payments
get_balance โ verifies wallet balance
When a user initiates a payment, the system creates a MoneroTransaction record with status: pending. A background monitor (paymentMonitor.js) runs every 30 seconds, checks for new transfers, and if the amount matches, it marks the transaction as confirmed and automatically completes the order โ transferring tokens from the seller to the buyer.
๐งฉ Challenges & solutions
๐ Permission denied on /root
Nginx runs as www-data and cannot read files inside /root. The solution: move the frontend build to /var/www and set proper permissions.
๐ Monero RPC connection issues
The wallet RPC failed to connect to stagenet.community:38081. I switched to a local daemon or used node.moneroworld.com:38081. Also, ensure the wallet is not locked (kill any other wallet processes and remove *.lock files).
๐ฆ Missing monero-js package
The package monero-js is not available on npm. Instead, I used axios to call the JSONโRPC endpoints directly โ simpler and more reliable.
๐งต Race conditions in orders
To prevent doubleโspending, the TokenHolding model uses a lockedAmount field. When a sell order is created, the amount is locked. When the order is filled or cancelled, the lock is released atomically using MongoDB updates.
๐ฎ Whatโs next
HTTPS โ already planned with Letโs Encrypt.
Admin dashboard โ realโtime stats, user management, and transaction logs.
Multiple cryptocurrencies โ add Bitcoin and Ethereum support.
Smart contract settlement โ for fully onโchain trades.
Mobile app โ with React Native.
๐ Resources
GitHub Repository: DanielIoni-creator/MyZubsterGateway
Live Demo: https://myzubster.com
DEV.to Profile: @danielioni
Monero RPC Docs: getmonero.org
๐ Conclusion
Building MyZubster was an incredible journey that touched every aspect of fullโstack development โ from database design and API architecture to blockchain integration and production deployment. The system is now live, stable, and ready for realโworld use.
If youโre interested in building something similar or want to contribute, feel free to open an issue or pull request on GitHub.
Happy coding! ๐
Built with โค๏ธ by @danielioni
Top comments (0)