Trust-based, collateral-free lending on Stellar.
StellarCred lets users borrow without locking up collateral. Instead of assets, creditworthiness is determined by on-chain behaviour, repayment history, and social endorsements β a human-based credit system built natively on Stellar's payment and identity primitives.
- Why Stellar
- How It Works
- Architecture
- Repo Structure
- Tech Stack
- Credit Scoring Model
- Loan Lifecycle
- Getting Started
- Running Tests
- API Reference
- Smart Contracts (Soroban)
- Roadmap
- Contributing
Most DeFi lending protocols require over-collateralisation β you lock up $150 to borrow $100. This excludes the majority of the world who need credit precisely because they don't have assets to lock up.
Stellar is uniquely suited to fix this:
| Stellar Primitive | How StellarCred Uses It |
|---|---|
| Accounts with signers | Identity anchor for borrowers and lenders |
| Trustlines | Native credit relationships between accounts |
| Anchors (USDC, fiat) | Real-money disbursement and repayment |
| Low fees (~0.00001 XLM) | Micro-credit becomes economically viable |
| 5-second finality | Near-instant loan disbursement |
| Soroban smart contracts | On-chain loan validation and debt tracking |
- Join β Connect your Stellar wallet. Your public key is your identity.
- Build reputation β Your credit score (0β1000) is computed from your on-chain history and social endorsements.
- Get endorsed β Existing users vouch for you. Their reputation is at stake if you default.
- Borrow β Request a loan. If your score meets the threshold, USDC is disbursed to your account.
- Repay β Repay on time and your score increases. Default and your score drops β and so do your endorsers'.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Web App (Next.js) β
β Dashboard Β· Loan Form Β· Credit Score Β· Trust Graph β
ββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββ
β REST
ββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββ
β API (Node.js / Express) β
β /loans /reputation /endorsements /users β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Reputation Engine Trust Graph β
β (4-factor scorer) (Neo4j β Phase 4) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Stellar SDK + Soroban β
β Trustlines Β· Asset Issuance Β· Credit Manager β
β Reputation Oracle Β· Debt Token β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β PostgreSQL (loans, users, endorsements) β
β IPFS (score snapshots / audit trail) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Off-chain scoring, on-chain enforcement. The reputation engine runs off-chain (fast, cheap, upgradeable) but writes scores to the on-chain ReputationOracle contract. The CreditManager contract reads from the oracle before approving any loan β so the chain is the source of truth for approvals.
Issuer model for credit. The protocol acts as the USDC issuer. When a loan is approved, USDC is issued to the borrower's account. Repayment burns the corresponding DebtToken balance tracked on-chain.
Social slashing. Endorsers stake their reputation. If a borrower defaults, all endorsers take a proportional score penalty. This creates real skin-in-the-game without requiring token collateral.
stellar-cred/
βββ apps/
β βββ api/ # Node.js REST API
β β βββ src/
β β βββ db/ # SQL migrations
β β βββ middleware/ # Auth (Stellar pubkey validation)
β β βββ models/ # TypeScript types
β β βββ routes/ # loans, reputation, endorsements, users
β β βββ services/ # loanService, reputationService, stellarService, endorsementService
β βββ web/ # Next.js frontend
β βββ src/
β βββ components/ # CreditScore, LoanForm, TrustNetwork
β βββ hooks/ # useStellarWallet
β βββ lib/ # apiFetch helper
β βββ pages/ # index, dashboard, loan
βββ contracts/ # Soroban smart contracts (Rust)
β βββ credit-manager/ # Loan lifecycle + debt cap + oracle check
β βββ reputation-oracle/ # Score store, readable cross-contract
β βββ debt-token/ # Mint/burn outstanding debt balances
βββ packages/
β βββ reputation-engine/ # 4-factor credit scorer (pure TS, tested)
β βββ stellar-client/ # Horizon SDK wrappers (trustlines, asset issuance)
β βββ trust-graph/ # Neo4j endorsement graph (Phase 4)
βββ infra/
β βββ docker-compose.yml # Postgres + Neo4j + IPFS
βββ docs/
β βββ architecture.md
β βββ scoring-model.md
β βββ loan-lifecycle.md
βββ .env.example
βββ turbo.json # Turborepo monorepo config
| Layer | Technology |
|---|---|
| Frontend | Next.js 14, React 18, TypeScript |
| API | Node.js, Express, TypeScript |
| Smart Contracts | Soroban (Rust), Stellar SDK |
| Reputation Engine | TypeScript (pure, no runtime deps) |
| Primary DB | PostgreSQL 16 |
| Graph DB | Neo4j 5 (trust graph β Phase 4) |
| Storage | IPFS (score snapshots) |
| Monorepo | Turborepo + npm workspaces |
| Testing | Jest + ts-jest (TS), Soroban test harness (Rust) |
Scores range from 0 to 1000. A minimum of 500 is required to borrow.
| Factor | Weight | Source | Notes |
|---|---|---|---|
| Repayment history | 40% | On-chain loan records | repaid / (repaid + defaulted) |
| Account age | 20% | Horizon API | Capped at 365 days |
| Transaction volume | 20% | Horizon API | Operation count, capped at 500 |
| Social endorsements | 20% | Trust graph | Endorser count, capped at 10 |
| Score | Band | Max Loan |
|---|---|---|
| 0β499 | Poor β ineligible | β |
| 500β649 | Fair | $100 |
| 650β799 | Good | $500 |
| 800β1000 | Excellent | $1,000 |
When a borrower defaults, each endorser loses:
penalty = default_amount_usd / endorser_count (in score points)
This creates genuine accountability β endorsers only vouch for people they trust.
REQUESTED βββΊ APPROVED βββΊ ACTIVE βββΊ REPAID
β β
REJECTED DEFAULTED
| State | Trigger | Effect |
|---|---|---|
| REQUESTED | Borrower submits request | Score check begins |
| APPROVED | Score β₯ 500 | USDC issued, DebtToken minted |
| REJECTED | Score < 500 | No funds moved |
| ACTIVE | Funds disbursed | Repayment clock starts |
| REPAID | Full repayment received | DebtToken burned, score +boost |
| DEFAULTED | Missed deadline | Score slashed, endorsers penalised |
- Node.js β₯ 20
- Rust +
wasm32-unknown-unknowntarget (for contracts) - Docker (for local Postgres + Neo4j + IPFS)
git clone https://github.com/your-org/stellar-cred
cd stellar-cred
npm installcp .env.example .env
# Fill in STELLAR_ISSUER_SECRET, DATABASE_URL, etc.docker compose -f infra/docker-compose.yml up -dpsql $DATABASE_URL -f apps/api/src/db/001_initial.sqlnpm run dev # starts both API (:3001) and web (:3000) via Turborepo# All TypeScript tests (API + reputation engine)
npm run test --workspaces
# API only
cd apps/api && npx jest
# Reputation engine only
cd packages/reputation-engine && npx jest
# Soroban contracts (Rust)
cd contracts && cargo testCurrent test coverage:
| Suite | Tests | Status |
|---|---|---|
| API (routes, services, auth) | 30 | β passing |
| Reputation engine (factors + scorer) | 19 | β passing |
| Soroban contracts (credit-manager, oracle, debt-token) | 21 | β passing |
| Total | 70 | β |
All endpoints require Authorization: Bearer <stellar-pubkey>.
GET /reputation/:pubkey
β { pubkey, score, eligible, breakdown: { repayment, age, volume, endorsements } }
POST /loans
Body: { amount: number, duration_days: number }
β Loan object (201)
GET /loans
β Loan[] for the authenticated user
GET /loans/:id
β Loan object
PATCH /loans/:id/repay
β Updated Loan object
POST /endorsements
Body: { borrower_pubkey: string }
β Endorsement object (201)
GET /endorsements/:pubkey
β Endorsement[] for the given pubkey
GET /users/me
β { pubkey }
All contracts are in contracts/ and written in Rust for the Soroban VM.
Tracks the full loan lifecycle on-chain.
| Function | Description |
|---|---|
initialize(admin, min_score) |
One-time setup |
set_oracle(oracle_address) |
Register the ReputationOracle contract |
create_loan(borrower, amount, duration_ledgers) |
Validates score via oracle, enforces debt cap, emits event |
repay(loan_id) |
Marks repaid, reduces borrower debt balance |
default_loan(loan_id) |
Marks defaulted, reduces borrower debt balance |
borrower_debt(address) |
Returns total outstanding debt for an address |
Admin-controlled score store. Readable cross-contract by CreditManager.
| Function | Description |
|---|---|
set_score(account, score) |
Write score 0β1000, emits event |
get_score(account) |
Read score (0 if unset) |
is_eligible(account, min_score) |
Returns bool β used by CreditManager |
Tracks outstanding debt balances. Minted on loan creation, burned on repayment/default.
| Function | Description |
|---|---|
mint(to, amount) |
Increase debt balance + total supply |
burn(from, amount) |
Decrease debt balance + total supply |
balance_of(account) |
Outstanding debt for an address |
total_supply() |
Protocol-wide total outstanding debt |
| Phase | Status | Description |
|---|---|---|
| 1 β Foundations | β Done | Monorepo, Stellar SDK setup, account/trustline primitives |
| 2 β Basic Lending MVP | β Done | Loan CRUD, auth middleware, in-memory store, API routes |
| 3 β Reputation System | π In progress (30%) | 4-factor scorer, endorsements, Soroban oracle integration |
| 4 β Trust Graph | β¬ Planned | Neo4j graph, weighted endorsement edges, social slashing |
| 5 β Soroban Integration | β¬ Planned | Cross-contract calls, WASM deployment, Horizon event indexing |
| 6 β UI/UX | β¬ Planned | Freighter wallet, trust network visualisation, full dashboard |
| 7 β Production | β¬ Planned | PostgreSQL persistence, IPFS score snapshots, mainnet deploy |
- Fork the repo and create a feature branch.
- Run
npm installfrom the root. - Make your changes β all tests must pass before opening a PR.
- Run
cargo testincontracts/if you touched Rust. - Open a PR with a clear description of what changed and why.
MIT