Find Skilled Workers Near You
BlueCollar is a decentralised protocol built on Stellar that connects local skilled workers (plumbers, electricians, carpenters, welders, and more) with users through community-curated listings. The platform creates a trustless ecosystem where workers can be discovered, verified, and compensated securely — without relying on centralised intermediaries.
Many skilled workers lack a platform to help them get noticed. Meanwhile, countless people need quality recommendations for reliable tradespeople. BlueCollar is the bridge connecting both worlds.
- Overview
- Architecture
- Monorepo Structure
- Packages
- API Reference
- Smart Contracts
- Getting Started
- Environment Variables
- Roadmap
- Community
- Contributing
- License
- Quick Start Guide
- API Documentation
- Security Policy
- Contributing Guide
- Code of Conduct
- Frontend Contributing Guide
| Feature | Description |
|---|---|
| Decentralised listings | Worker profiles are anchored on-chain via Stellar Soroban smart contracts |
| Community curation | Curators (verified community members) create and manage worker listings |
| Trustless payments | Tips and payments flow directly between users and workers via the Market contract |
| Google OAuth | Users can sign in with Google in addition to email/password |
| Role-based access | Three roles: user, curator, admin |
| Media uploads | Profile images handled with method-spoofed PUT requests (multipart/form-data) |
User / Browser
│
▼
[Next.js App] ──────────────────────────────────────────────────────────┐
│ │
▼ ▼
[BlueCollar API] (Node.js / Express / TypeScript) [Stellar Network]
│ │
▼ ▼
[PostgreSQL via Prisma] [Soroban Smart Contracts]
├── Registry Contract
└── Market Contract
- The API handles authentication, category management, and worker CRUD. It stores data in PostgreSQL via Prisma ORM.
- The Registry Contract (Rust/Soroban) anchors worker registrations on the Stellar blockchain, providing immutable proof of listing.
- The Market Contract (Rust/Soroban) handles on-chain tip/payment transfers between users and workers using Stellar tokens (XLM or custom assets).
- The App is a Next.js frontend that consumes the API and interacts with Stellar wallets (Freighter, etc.).
bluecollar/
├── packages/
│ ├── api/ # Node.js/Express backend API (TypeScript)
│ │ ├── prisma/
│ │ │ └── schema.prisma
│ │ ├── src/
│ │ │ ├── controllers/ # Route handlers
│ │ │ ├── middleware/ # Auth, validation
│ │ │ ├── routes/ # Express routers
│ │ │ ├── services/ # Business logic
│ │ │ ├── models/ # Type definitions
│ │ │ ├── mailer/ # Email templates & transport
│ │ │ ├── database/ # Seed scripts
│ │ │ ├── utils/ # Helpers
│ │ │ ├── db.ts # Prisma client singleton
│ │ │ └── index.ts # App entry point
│ │ ├── .env.example
│ │ ├── package.json
│ │ └── tsconfig.json
│ │
│ ├── contracts/ # Stellar Soroban smart contracts (Rust)
│ │ ├── contracts/
│ │ │ ├── registry/ # Worker registry contract
│ │ │ │ └── src/lib.rs
│ │ │ └── market/ # Tip/payment contract
│ │ │ └── src/lib.rs
│ │ └── Cargo.toml
│ │
│ └── app/ # Next.js frontend
│ ├── src/
│ └── package.json
│
├── package.json # Root workspace config
├── pnpm-workspace.yaml
└── README.md
The backend REST API built with Node.js, Express, and TypeScript. Uses Prisma as the ORM against a PostgreSQL database.
Key modules:
| Module | Purpose |
|---|---|
controllers/auth.ts |
Login, register, logout, password reset |
controllers/workers.ts |
CRUD for worker listings |
controllers/categories.ts |
Category listing and lookup |
middleware/auth.ts |
JWT authentication + role-based authorization |
prisma/schema.prisma |
Database schema (User, Worker, Category) |
Tech stack: Express · TypeScript · Prisma · PostgreSQL · Argon2 · JWT · Passport (Google OAuth) · Nodemailer · Vitest
Stellar Soroban smart contracts written in Rust.
Manages on-chain worker registrations. Workers are stored in persistent contract storage keyed by a unique Symbol id.
register(id, owner, name, category) → stores Worker on-chain
get_worker(id) → returns Worker struct
toggle(id, caller) → flips is_active (owner only)
list_workers() → returns all worker ids
upgrade(admin, new_wasm_hash) → upgrades contract WASM (admin only)
Handles direct token transfers (tips/payments) between users and workers.
tip(from, to, token_addr, amount) → transfers Stellar tokens from user to worker
upgrade(admin, new_wasm_hash) → upgrades contract WASM (admin only)
Both contracts are compiled to WASM and deployed to the Stellar network (testnet / mainnet).
Next.js 14 frontend. Connects to the BlueCollar API and integrates with Stellar wallets (Freighter) for on-chain interactions.
Base URL: http://localhost:3000/api
| Method | Endpoint | Description |
|---|---|---|
POST |
/auth/login |
Login with email + password |
POST |
/auth/register |
Create a new account |
PUT |
/auth/verify-account |
Verify email address |
DELETE |
/auth/logout |
Logout (requires auth) |
POST |
/auth/forgot-password |
Request password reset email |
PUT |
/auth/reset-password |
Reset password with token |
GET |
/auth/google |
Initiate Google OAuth |
GET |
/auth/google/callback |
Google OAuth callback |
Login response example:
{
"data": {
"id": "clxyz...",
"email": "[email protected]",
"firstName": "Jane",
"lastName": "Doe",
"role": "user",
"verified": true
},
"status": "success",
"message": "Login successful",
"code": 202,
"token": "<jwt>"
}| Method | Endpoint | Description |
|---|---|---|
GET |
/categories |
List all categories |
GET |
/categories/:id |
Get a single category |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
GET |
/workers |
List active workers (paginated) | Public |
GET |
/workers/:id |
Get a single worker | Public |
POST |
/workers |
Create a worker listing | Curator |
POST |
/workers/:id + X-HTTP-Method: PUT |
Update a worker (supports file upload) | Curator |
DELETE |
/workers/:id |
Delete a worker | Curator |
PATCH |
/workers/:id/toggle |
Toggle active status | Curator |
Method spoofing for file uploads: HTML forms and
multipart/form-datarequests only supportGET/POST. To update a worker with a file upload, send aPOSTrequest with the headerX-HTTP-Method: PUT. The API uses themethod-overridemiddleware to rewrite the request method toPUTbefore it reaches the route handler, so the update route behaves identically to a standardPUT.POST /api/workers/:id Content-Type: multipart/form-data X-HTTP-Method: PUT
Admin endpoints mirror the Curator endpoints but are scoped to the admin role and include bulk operations.
- Rust with
wasm32-unknown-unknowntarget - Stellar CLI
rustup target add wasm32-unknown-unknown
cargo install --locked stellar-clicd packages/contracts
cargo build --release --target wasm32-unknown-unknownstellar contract deploy \
--wasm target/wasm32-unknown-unknown/release/bluecollar_registry.wasm \
--source <your-secret-key> \
--network testnetTo upgrade a deployed contract without redeploying (preserving its contract ID and storage):
- Build the new WASM and install it on-chain to get its hash:
stellar contract install \
--wasm target/wasm32-unknown-unknown/release/bluecollar_registry.wasm \
--source <your-secret-key> \
--network testnet
# outputs: <new_wasm_hash>- Invoke the
upgradefunction with the admin address:
stellar contract invoke \
--id <contract-id> \
--source <admin-secret-key> \
--network testnet \
-- upgrade \
--admin <admin-address> \
--new_wasm_hash <new_wasm_hash>The same steps apply to the Market contract. The admin argument must match the signing key (--source), as require_auth() is enforced on-chain.
Soroban persistent storage entries have a TTL (time-to-live) measured in ledgers. Without extension, entries can expire and be pruned from the ledger.
| Constant | Value | Approximate duration |
|---|---|---|
TTL_EXTEND_TO |
535,000 ledgers | ~1 year (at 5s/ledger) |
TTL_THRESHOLD |
267,500 ledgers | ~6 months |
How it works:
- Every write to persistent storage (
register,toggle) automatically callsextend_ttlon the affected key. extend_ttl(key, threshold, extend_to)only extends if the current TTL is belowthreshold, avoiding unnecessary fees.- A public
extend_worker_ttl(id)function is available so anyone (users, bots, the app) can refresh a worker entry's TTL without needing special permissions.
# Extend a worker's TTL via CLI
stellar contract invoke \
--id <contract-id> \
--source <any-account> \
--network testnet \
-- extend_worker_ttl \
--id <worker-id>The quickest way to run the API and database locally is with Docker Compose.
# Copy and fill in the API env file first
cp packages/api/.env.example packages/api/.env
# Start API + PostgreSQL + Adminer
pnpm docker:up
# Stop and remove containers
pnpm docker:down| Service | URL |
|---|---|
| API | http://localhost:3000 |
| Adminer (DB UI) | http://localhost:8080 |
| PostgreSQL | localhost:5432 |
The API container runs
prisma migrate deployautomatically on startup.
- Node.js >= 20
- pnpm >= 9
- PostgreSQL
- Rust (for contracts)
git clone https://github.com/Fidelis900/Blue-Collar.git
cd Blue-Collar
pnpm installcp packages/api/.env.example packages/api/.env
# fill in DATABASE_URL and JWT_SECRET
cd packages/api
pnpm migrate # run prisma migrations
pnpm seed # seed categories
pnpm dev # start dev server on :3000cd packages/app
pnpm dev # start Next.js on :3001All variables for the API live in packages/api/.env (copy from .env.example):
| Variable | Description |
|---|---|
DATABASE_URL |
PostgreSQL connection string |
JWT_SECRET |
Secret key for signing JWTs |
PORT |
API port (default: 3000) |
GOOGLE_CLIENT_ID |
Google OAuth client ID |
GOOGLE_CLIENT_SECRET |
Google OAuth client secret |
MAIL_HOST |
SMTP host |
MAIL_PORT |
SMTP port |
MAIL_USER |
SMTP username |
MAIL_PASS |
SMTP password |
APP_URL |
Public URL of the app (used in emails) |
| Status | Feature |
|---|---|
| ✅ Done | Worker CRUD with curator-gated listings |
| ✅ Done | JWT auth + email verification + password reset |
| ✅ Done | Google OAuth 2.0 |
| ✅ Done | Registry & Market Soroban contracts (testnet) |
| ✅ Done | Escrow payments with time-locked cancellation |
| ✅ Done | Role-based access (user / curator / admin) |
| ✅ Done | Profile image uploads (Multer + Sharp) |
| 🔄 In progress | Next.js frontend (worker discovery, wallet connect) |
| 🔄 In progress | Freighter wallet integration |
| 📋 Planned | Mainnet deployment |
| 📋 Planned | Worker reviews & ratings |
| 📋 Planned | Push notifications |
| 📋 Planned | Mobile app (React Native) |
Join the conversation and stay up to date:
- Telegram: t.me/bluecollar
- GitHub Discussions: github.com/Fidelis900/Blue-Collar/discussions
- Issues: github.com/Fidelis900/Blue-Collar/issues
See CONTRIBUTING.md for the full guide, including commit message conventions and PR process.
- Check the open issues for something to work on
- Fork the repo and create a feature branch
- Make your changes and open a pull request
All PRs require passing CI checks.
MIT © BlueCollar Contributors