Xryptt is a full-stack SaaS for tracking Ethereum wallets: portfolio balances, transaction alerts, and wallet analytics, with a subscription billing layer on top.
Internally this project is still named
wallet-monitorinpackage.json.
demo.mp4
- Wallet tracking — add and monitor Ethereum wallet addresses, view balances and transaction history
- Portfolio viewer — aggregated portfolio value across tracked wallets
- Stealth wallets — a dedicated flow for privacy-focused wallet tracking
- AI News — a curated crypto news feed
- Auth & accounts — email/password auth via Supabase, protected routes, user dashboard, settings
- Payments — subscription checkout via Paddle
- Transactional email — via Resend
Frontend — React 18, Vite, React Router, Tailwind CSS, Web3.js, Supabase JS client
Backend — Node.js, Express, Redis-backed sessions, Ethereum data via Etherscan + Moralis + Infura, Paddle Node SDK, Resend
Data — Supabase (Postgres + Auth), with SQL migrations in supabase/migrations
xrypttSaaS/
├── frontend/ # React + Vite web app
│ ├── src/
│ │ ├── components/ # Pages & UI (WalletTracking, PortfolioViewer, StealthWallet, ...)
│ │ ├── services/, hooks/, context/, utils/
│ │ └── App.jsx
│ └── public/
├── backend/ # Express API
│ └── src/
│ ├── routes/ # auth, wallet, balance, user, stealth, email, webhook, sitemap
│ ├── services/
│ ├── middlewares/
│ └── config/
└── supabase/
└── migrations/ # Database schema history
- Node.js 18+
- A Redis instance (local or hosted, e.g. Upstash)
- Accounts/API keys for: Supabase, Etherscan, Moralis, Infura, Paddle, Resend
cd frontend && npm install
cd ../backend && npm installCreate frontend/.env.local:
VITE_SUPABASE_URL=
VITE_SUPABASE_ANON_KEY=
VITE_PADDLE_SANDBOX_CLIENT_TOKEN=
VITE_ETHERSCAN_API_KEY=
VITE_API_BASE_URL=http://localhost:3000
VITE_FRONTEND_URL=http://localhost:5173
Create backend/.env:
PORT=3000
NODE_ENV=development
SUPABASE_URL=
SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
REDIS_URL=
INFURA_PROJECT_ID=
ETHERSCAN_API_KEY=
ETHERSCAN_API_KEY1=
MORALIS_API_KEY_1=
MORALIS_API_KEY_2=
PADDLE_API_KEY=
RESEND_API_KEY=
SESSION_SECRET=
WEBHOOK_SANDBOX_SECRET_KEY=
FRONTEND_URL=http://localhost:5173
Note: both
.env.localand.envare gitignored — never commit real keys.
# backend (Express API on :3000)
cd backend && npm run dev # auto-restarts on file changes (node --watch)
# or: npm start # plain node, no watch
# frontend (Vite dev server on :5173)
cd frontend && npm run devThis repo includes a render.yaml Blueprint that provisions two services:
xryptt-backend— Node web service, rootbackend/, buildnpm install, startnpm startxryptt-frontend— static site, rootfrontend/, buildnpm install && npm run build, publishdist/, with SPA rewrite toindex.html
To deploy:
- In the Render dashboard, choose New → Blueprint and point it at this repo. Render will read
render.yamland create both services. - Fill in the env vars marked
sync: falsein the dashboard (Supabase, Etherscan, Moralis, Infura, Paddle, Resend keys, etc.) — Render never reads secret values from the repo. - Add a Redis instance (Render's Key Value service, or an external one like Upstash) and set
REDIS_URLon the backend. - Once both services are live, set
VITE_API_BASE_URLon the frontend to the backend'shttps://xryptt-backend.onrender.com-style URL, andFRONTEND_URLon the backend to the frontend's URL (needed for CORS) — then redeploy.
If you already have live services under different names (this product has previously been deployed on Render), either reuse those exact names when applying the Blueprint, or update FRONTEND_URL/CORS in backend/src/app.js and VITE_API_BASE_URL in the frontend env to match your real URLs — this Blueprint intentionally doesn't touch any existing deployment.
AI— a fork of this codebase that pivoted into the Lumaya AI companion productfrontend-ai— the further-rebranded standalone web frontend for Lumaya