Portable credit scoring infrastructure for Stellar DeFi.
ZCore is the credit layer that converts verified on-chain payment events — from escrows, tandas, and DeFi loans — into a portable credit score that any lending protocol on Stellar can query.
"ZCore is the FICO Score for DeFi: built from verified behavior, not wallet activity."
| Service | URL |
|---|---|
| DApp | dapp-zcore.vercel.app |
| API | zcore-api.vercel.app |
| API docs | zcore-api.vercel.app/api-docs |
| Landing | zcore-landing.vercel.app |
- Never commit
.env/.env.local— they are in.gitignoreand.vercelignore. - Front (dapp-zcore): only
NEXT_PUBLIC_*vars belong in Vercel (they are public in the browser bundle). - API (zcore-api): set
DATABASE_URL,ADMIN_SECRET,STELLAR_NETWORKviavercel env addin the Vercel dashboard — do not deploy with a local.envfile in the upload. - After the first API deploy, a local
.envwas accidentally included; that deployment was replaced. ProductionADMIN_SECRETwas rotated in Vercel. If you reuseddev_admin_secret_localelsewhere, change it.
Partner platforms (Trustless Work, Blend Protocol, Vaquita) call POST /api/events/report whenever a user completes a credit-relevant payment. ZCore verifies the transaction on Stellar Horizon, calculates the score impact, and stores an immutable credit event. Lenders query GET /api/user/{wallet}/score to get the score and offer better conditions to creditworthy users.
PARTNER PLATFORMS ZCORE CORE LENDERS
───────────────── ────────── ───────
Trustless Work ──────► verify txHash ──► GET /score
Blend Protocol ──────► calculate impact ──► offer better rates
Vaquita ──────► update score ──► reduce collateral
ZCore does not lend money, custody funds, or decide whether to approve a loan. It answers one question: "Has this person been reliable with money on Stellar?"
Score (0–850) = Stellar Base (0–150) + Verified Events (0–700)
| Component | Max points | Source |
|---|---|---|
| Wallet age | 40 | Stellar Horizon |
| Transaction activity | 60 | Stellar Horizon |
| Success rate | 30 | Stellar Horizon |
| XLM balance | 20 | Stellar Horizon |
| Escrow completed | 60/event | Trustless Work |
| Loan repaid | 80/event | Blend Protocol |
| Tanda round paid | 30/event | Vaquita |
| Tanda cycle completed | 100/event | Vaquita |
| Tier | Score | Typical limit | Typical rate |
|---|---|---|---|
| A | 600–850 | $10,000+ | 8–12% |
| B | 350–599 | $2,000–$10,000 | 12–18% |
| C | 100–349 | $200–$2,000 | 18–25% |
| REJECTED | 0–99 | No access | — |
- Every event requires a Stellar
txHash— real capital must move on-chain. txHashis unique in the DB — the same payment cannot be counted twice.- Repeated interactions with the same counterparty have diminishing returns (decay: 100% → 70% → 40% → 10%).
POST /api/events/report
{
"apiKey": "trustless_work_abc123...",
"eventType": "escrow_completed",
"walletAddress": "GAYR3DY...",
"amount": 500,
"currency": "USDC",
"txHash": "stellar_tx_hash_here",
"counterpartyWallet": "GDEFG...",
"timestamp": "2026-06-17T10:00:00Z"
}Response:
{
"success": true,
"data": {
"eventId": "evt_uuid",
"scoreImpact": 22,
"newScore": 187,
"newTier": "C",
"verified": true
}
}GET /api/user/{wallet}/score
{
"success": true,
"data": {
"walletAddress": "GAYR3DY...",
"score": 387,
"tier": "B",
"breakdown": {
"stellarBase": 67,
"eventsScore": 320,
"totalEvents": 8,
"platforms": ["trustless-work", "blend-protocol"]
},
"lastUpdated": "2026-06-15T08:22:00Z"
}
}| Method | Path | Description |
|---|---|---|
POST |
/api/auth/register |
Register user by Stellar wallet |
POST |
/api/auth/login |
Login (wallet-based, returns score) |
POST |
/api/events/report |
Report credit event (partner platforms) |
GET |
/api/user/{wallet}/score |
Full score with breakdown (lenders) |
GET |
/api/user/{wallet}/history |
Credit event history (users) |
GET |
/api/user/{wallet}/profile |
User profile and tier |
POST |
/api/user/request |
Request scoring evaluation |
POST |
/api/lender/profiles |
Configure lender risk profiles |
POST |
/api/payment/report |
Report payment or default |
POST |
/api/platforms/register |
Register partner platform (admin) |
GET |
/api-docs |
Swagger UI |
ZCore runs as two services: the API (Server/, port 3000) and the DApp (Front/, port 3001).
The marketing landing page is a separate repo: Zcore-Landing.
-
Instala Node.js 20+ y Docker Desktop (debe estar abierto y en ejecución).
-
Clona el repo y, desde la raíz, ejecuta el setup:
# Windows npm run setup# macOS / Linux npm run setup:unix -
Abre dos terminales y levanta los servicios:
npm run dev:server # API → http://localhost:3000 npm run dev:front # DApp → http://localhost:3001
-
Instala Freighter en Testnet, crea una wallet en Stellar Laboratory y regístrate en dapp-zcore.vercel.app/register (producción) o http://localhost:3001/register (local).
Los archivos de entorno se generan solos desde los ejemplos:
| Archivo origen | Se copia a |
|---|---|
Server/.env.example |
Server/.env |
Front/.env.example |
Front/.env.local |
Si Docker no estaba corriendo durante el setup, arráncalo y ejecuta:
npm run db:up && npm run prisma:migrate && npm run prisma:seed| Tool | Version | Notes |
|---|---|---|
| Node.js | 20+ | node --version |
| Docker Desktop | any | MySQL runs in a container — no local MySQL install needed |
| Freighter | browser ext. | freighter.app — wallet for testnet |
Important: Docker Desktop must be running before setup.
From the repo root:
npm run setupThis automatically:
- Copies
Server/.env.example→Server/.env - Copies
Front/.env.example→Front/.env.local - Starts MySQL via Docker
- Installs dependencies (Server + Front)
- Runs Prisma migrations and seeds dev platform API keys
Then open two terminals:
# Terminal 1 — API
npm run dev:server
# Terminal 2 — DApp
npm run dev:front| URL | What |
|---|---|
| dapp-zcore.vercel.app | DApp (production) — register, login, dashboard |
| http://localhost:3001 | DApp (local) |
| zcore-api.vercel.app/api-docs | Swagger API docs (production) |
| http://localhost:3000/api-docs | Swagger API docs (local) |
| zcore-api.vercel.app/health | Health check (production) |
| http://localhost:3000/health | Health check (local) |
- Install Freighter and switch to Testnet
- Create a testnet wallet at Stellar Laboratory
- Open dapp-zcore.vercel.app/register (or http://localhost:3001/register locally)
- Connect Stellar Wallet → Freighter → sign the message (free, no XLM fee)
- Dashboard shows your Stellar Base score
Copy the examples (done automatically by npm run setup):
copy Server\.env.example Server\.env
copy Front\.env.example Front\.env.local| Variable | Default (dev) | Description |
|---|---|---|
DATABASE_URL |
mysql://root:zcore_dev@localhost:3306/zcore |
MySQL (matches docker-compose.yml) |
ADMIN_SECRET |
dev_admin_secret_local |
Key for POST /api/platforms/register |
STELLAR_NETWORK |
testnet |
testnet or mainnet |
PORT |
3000 |
API port |
| Variable | Default (dev) | Description |
|---|---|---|
NEXT_PUBLIC_API_BASE_URL |
http://localhost:3000 |
Backend API URL |
NEXT_PUBLIC_STELLAR_NETWORK |
testnet |
Network for explorer links |
See Server/.env.example and Front/.env.example for optional Soroban variables.
| Platform | API Key |
|---|---|
| Trustless Work | dev_tw_key_local |
| Blend Protocol | dev_blend_key_local |
| Vaquita | dev_vaquita_key_local |
Re-seed anytime: npm run prisma:seed (from repo root).
# From repo root
npm run setup # First-time setup
npm run dev:server # Start API → :3000
npm run dev:front # Start DApp → :3001
npm run db:up # Start MySQL container
npm run db:down # Stop MySQL container
npm run db:reset # Wipe DB and restart MySQL
npm run prisma:migrate # Apply migrations
npm run prisma:seed # Seed partner platforms
# From Server/
npm run prisma:studio # Visual DB browser| Problem | Fix |
|---|---|
| Docker pipe error | Open Docker Desktop, wait until running, then npm run db:up |
npm install fails in Front |
npm install --legacy-peer-deps inside Front/ |
| Prisma can't connect | Run npm run db:up, wait 10s, then npm run prisma:migrate |
| Wallet signature rejected | Approve the sign popup in Freighter |
| Port in use | Change PORT in Server/.env or Front dev port in Front/package.json |
- Backend: Node.js + Express + TypeScript
- DB: MySQL + Prisma ORM
- Blockchain: Stellar Horizon API (transaction verification + wallet scoring)
- Validation: Zod schemas
- API docs: Swagger/OpenAPI 3.0
- Frontend (DApp): Next.js in
Front/— user dashboard (landing page is a separate repo)
- Stellar wallet-based scoring (0–150 pts base)
- Verified credit event system (
POST /api/events/report) - Anti-Sybil: txHash uniqueness + counterparty decay
- Score breakdown endpoint for lenders
- Credit history endpoint for users
- Platform registration (admin API key management)
- Wallet signature authentication (challenge + verify)
- Soroban score-registry smart contract
- On-chain score attestation flow
- Stellar Horizon stats in dapp profile
- Trustless Work integration (testnet)
- Blend Protocol integration (testnet)
- Vaquita integration
- Rate limiting per wallet per month
- Wallet age minimum for anti-Sybil (wallets < 30 days don't count)
- Lender API key auth on score endpoint
- Frontend dashboard with score breakdown
- ZK proof layer for private score verification
See CONTRIBUTING.md for setup, branch conventions, and PR guidelines.
MIT — see LICENSE.