- Decentralized Belt System for Brazilian Jiu Jitsu 🥋
- 1. Overview
- 2. Key Features
- 3. Architecture & Components
- 4. Project Structure
- 5. Installation & Setup
- Prerequisites
- 5.1. Clone and Setup
- 6. Usage
- 7. License
- 8. Contributions, Feedback and Support
- 9. Future Milestones
- 10. Acknowledgments
The Decentralized Belt System aims to bring transparency and trust to the Brazilian Jiu Jitsu rank promotion process by recording practitioner profiles, belt lineages, and achievements on the Cardano blockchain. This approach eliminates reliance on siloed or inconsistent records, ensuring that every belt rank is verifiable by anyone in the community.
Product repo. The web frontend, BFF, and LLM agent-service live in a separate (private) repo,
bjj-frontend. That repo pulls this repo's Haskell services as published Docker Hub images (mariusgeorgescu/bjj-{chainsync,interaction-api,query-api,mcp-server}, pinned by aPROTOCOL_TAG). Thedocker-compose.ymlin this repo is a dev/audit stack for running the protocol services standalone — no TLS, no ingress, localhost ports only.
- Immutable Rank Tracking: Every rank promotion is recorded on-chain along with the awarding authority. Profiles are permanent by design, preserving lineage integrity.
- Ensure transparency in rank progression and lineage
- Achievements & Memberships: Practitioners can showcase achievements, and organizational memberships in one place.
- Full Security Model: Two-layer validation with BJJ rule enforcement at mint time and consent verification at acceptance.
- Web Browser
- BJJ-DApp Frontend: The web interface for practitioners, masters, and organizations.
- 3rd Party Browser Wallet (e.g., Eternl, Lace): For signing transactions.
- Backend
- Interaction API Service: Builds and submits transactions for promotions, achievements, membership.
- Query API Service: Provides quick queries for ranks, achievements, profiles, lineage, etc.
- Chain Sync Service: Monitors the Cardano blockchain for updates.
- Cardano Node: Submits signed transactions to the Cardano network.
- Persistence : A database or index for quick lookups of ranks, achievements, memberships (off-chain).
For more details, see Detailed Documentation.
To regenerate diagram images after editing puml/*.puml, run scripts/regenerate_diagrams.sh (requires PlantUML; e.g. brew install plantuml).
.
├── src/
│ ├── lib/ # 📁 All libraries organized here
│ │ ├── onchain-lib/ # 🔗 Onchain logic (Plutus smart contracts)
│ │ │ └── Onchain/ # Validators, minting policies, protocols
│ │ ├── webapi-lib/ # 🌐 Web infrastructure
│ │ │ └── WebAPI/ # Auth, Health, CORS modules
│ │ ├── chainsync-lib/ # ⛓️ Generic chain sync utilities
│ │ │ ├── KupoClient.hs # Kupo API client
│ │ │ └── KupoAtlas.hs # Data conversion utilities
│ │ ├── offchain-lib/ # 🏛️ Domain + infrastructure
│ │ │ ├── DomainTypes/ # Domain-specific types and DTOs
│ │ │ ├── TxBuilding/ # Transaction building utilities
│ │ │ ├── Storage.hs # Database operations
│ │ │ ├── Ingestion.hs # Event projection
│ │ │ ├── Constants.hs # Configuration constants
│ │ │ └── Utils.hs # Common utilities
│ │ └── mcp-server-lib/ # 🤖 MCP (Model Context Protocol) server
│ │ ├── MCPServer/ # Tools, resources, handlers
│ │ └── resources/ # Compile-time-embedded markdown (annex-3, faq)
│ ├── exe/ # 📁 Executable applications
│ │ ├── admin/ # Command-line admin tool
│ │ ├── chain-sync/ # Blockchain synchronization service (binary: chainsync-service)
│ │ ├── interaction-api/ # Transaction building and submission API
│ │ ├── mcp-server/ # MCP server exposing Query + Interaction APIs to LLM clients
│ │ └── query-api/ # Data querying API
│ └── test/ # Test suites
│ ├── TestRuns.hs # Integration tests
│ ├── UnitTests.hs # Unit test entrypoint
│ ├── UnitTests/ # Unit test modules (Achievement, Cleanup, Membership, Oracle, Promotion)
│ ├── Test/ # Fixtures and helpers
│ └── BJJPropertyTests.hs # Property-based tests
├── docs/ # Documentation, specifications, diagrams
├── puml/ # Plantuml diagrams
├── out/ # Images of plantuml diagrams
├── scripts/ # Test and utility scripts
│ ├── test_black_promotes_white_to_blue.sh # Core promotion test
│ ├── populate_testnet.sh # Testnet data population
│ ├── populate_recent_activity.sh # Testnet population with recent (last 12 months) activity
│ ├── regenerate_diagrams.sh # Regenerate PlantUML images (puml/ → out/puml/)
│ ├── test_exunits.sh # Execution units / cost testing
│ └── build-images.sh # Docker/image build
└── README.md # This file
The project is organized into 5 distinct libraries with clear separation of concerns:
- 📦 onchain-lib - Plutus smart contracts and blockchain logic
- 📦 webapi-lib - Web infrastructure (Auth, CORS, ServiceProbe); no project-library deps
- 📦 chainsync-lib - Generic chain synchronization utilities (Kupo client, Atlas adapter)
- 📦 offchain-lib - Domain logic, transaction building, storage, ingestion
- 📦 mcp-server-lib - MCP (Model Context Protocol) server library, consumed by the
mcp-serverexecutable
Dependency layering (inner → outer; deps only point inward):
onchain-lib + chainsync-lib → offchain-lib → webapi-lib
↑
mcp-server-lib
(also depends on offchain-lib + onchain-lib)
onchain-lib must never import off-chain deps (no Aeson, Servant, Swagger). webapi-lib carries HTTP/auth/CORS only and has no project-library dependencies.
This architecture ensures:
- 🔧 Maximum Reusability: Generic components can be used by other projects
- 🏗️ Clean Separation: Domain logic is separate from infrastructure
- 📈 Scalability: Each library can evolve independently
- 🧪 Testability: Components can be tested in isolation
- Unix-like operating system (Linux, macOS, or WSL2)
- Git installed
- Nix package manager
- Direnv
This project uses the The Developer Experience Shell to build a fully-functioning and reproducible Cardano development shell for Haskell quickly and across multiple operating systems (and architectures).
git clone https://github.com/en7angled/Decentralized-Belt-System.git
cd Decentralized-Belt-System- After installing and configuring
nixanddirenv, clone the repo and type:
direnv allow- Build:
cabal build all- The test suite for operations (transactions) can be run with the following command:
cabal test - Building transaction bodies requires gathering suitable information from the blockchain. For this purpose, we'll require a provider. So in config directory a file named "config_atlas.json", which should have the following format
{
"coreProvider": {
"maestroToken": "YOUR_TOKEN_HERE",
"turboSubmit": true
},
"networkId": "preview"
}- More info about the provider config can be found here
Create operation.prv with your private key mnemonic (24 words). Make sure you have enough funds available for covering the validators deployment. For testnet, you can get funds from the Cardano Testnet Faucet.
- This service requires validators to be deployed and to be used as reference UTxOs in the transactions. The validators can be deployed from the TUI.
admin deploy-reference-scripts- After deployment a file named config_bjj_validators.json which contains the validators reference UTxO should be present in the config folder.
admin --helpBJJ Belt System - Decentralized Belt Management
Usage: admin COMMAND
A command-line tool for managing Brazilian Jiu Jitsu profiles, belt
promotions, and achievements on the Cardano blockchain. Supports deploying
reference scripts, writing CIP-57 blueprints, initializing and updating
profiles, handling promotions, and more.
Available options:
-h,--help Show this help text
Available commands:
deploy-reference-scripts Deploy reference scripts for the BJJ belt system
write-blueprint Write the CIP-57 contract blueprint JSON to a file
pause-protocol Pause the protocol (oracle opPaused = True)
unpause-protocol Unpause the protocol
set-fees Set or clear fee configuration in the oracle
set-min-utxo-value Set minimum UTxO value (lovelace) for protocol state outputs
query-oracle Display current oracle parameters (read-only)
init-profile Initialize a new profile (White belt)
update-profile Update profile metadata (description, image)
promote-profile Promote a profile to a new belt
accept-promotion Accept a promotion
create-profile-with-rank Create a profile with initial rank (for masters)
create-membership-history Create a membership history for a practitioner at an organization
get-first-interval-id Get first membership interval ID for a history node
add-membership-interval Add a membership interval to an existing history
accept-membership-interval Accept a membership interval (practitioner acknowledges)
update-end-date Update membership interval end date
award-achievement Award an achievement to a practitioner
accept-achievement Accept an achievement (practitioner acknowledges)
cleanup-dust Sweep dust/griefing UTxOs from validator addresses (permissionless)
Note: Profile deletion is intentionally not supported. BJJ belt records are permanent historical facts that preserve lineage integrity.
Two shell scripts are provided for testnet testing and demonstrations:
A focused test that demonstrates the core promotion flow:
- Creates a master profile with Black belt
- Creates a student profile (White belt)
- Master promotes student to Blue belt
- Student accepts the promotion
./scripts/test_black_promotes_white_to_blue.shA comprehensive script that populates the testnet with realistic sample data:
- 2 Organizations (Gracie Barra Academy, Alliance Jiu-Jitsu)
- 1 Grand Master (Red belt)
- 2 Masters (Black belts)
- 4 Students (White to Purple belts)
- Multiple promotion scenarios
./scripts/populate_testnet.shBoth scripts:
- Automatically deploy reference scripts if needed
- Show clean progress output with colored indicators
- Display detailed summaries with all created IDs
- Handle errors gracefully with clear messages
The system provides four HTTP servers — Interaction API, Query API, MCP Server, and a Chain Sync service with health/readiness probes:
- Build Transaction:
POST /build-tx- Builds transaction for interactions - Submit Transaction:
POST /submit-tx- Submits signed transactions - Swagger UI:
http://localhost:8082/swagger-ui/ - Authentication: All endpoints require HTTP Basic Auth. Defaults:
BASIC_USER=cardano,BASIC_PASS=lovelace(override via env).
- Profiles:
GET /practitioner/{id},GET /organization/{id},GET /profiles,GET /profiles/count,GET /profiles/frequency - Promotions:
GET /promotions,GET /promotions/count - Belts:
GET /belts,GET /belts/count,GET /belts/frequency - Memberships:
GET /memberships,GET /memberships/count,GET /membership-intervals,GET /membership-intervals/count - Achievements:
GET /achievements,GET /achievements/count - Lineage:
GET /lineage?root=...&ancestors=...&descendants=...(direct lineage tree: ancestor chain + descendant subtree; projected DB only) - Protocol:
GET /protocol-status(oracle pause, min UTxO, fee config) - Swagger UI:
http://localhost:8083/swagger-ui/ - Authentication: All endpoints require HTTP Basic Auth (same defaults). Swagger UI is public.
- Projection mode: add
?liveprojection=trueto query live on-chain data; otherwise reads come from the PostgreSQL projection populated by chainsync-service. Standardlimit,offset, filter params are available per Swagger.
- Transport: MCP JSON-RPC over streamable HTTP at
POST /mcp. Reuses the same probe endpoints as the other services (/health,/ready). - Tool surface: read tools wrap Query API endpoints; write tools wrap Interaction API
build-txendpoints and return unsigned tx bodies for wallet signing downstream. - Resources: serves authored markdown (
bjj://rules/annex-3,bjj://docs/faq) and a runtime-generated JSON belt hierarchy (bjj://rules/belt-hierarchy). - Write-tool gating: write tools are absent from
tools/listunlessMCP_ENABLE_WRITE_TX=1. Off by default. - Authentication: the
/mcpendpoint itself has no auth — deploy behind a private network or auth proxy. Upstream API credentials are read fromBASIC_USER/BASIC_PASS. - See docs/architecture/mcp-server.md for the as-built ADR.
Executables produced by the build:
admin— CLI for deploying scripts and managing actionsinteraction-api— HTTP API for building and submitting transactions (port 8082)query-api— HTTP API for reading data and statistics (port 8083)chainsync-service— Chain sync and probe service (port 8084)mcp-server— MCP server exposing Query + Interaction APIs to LLM clients (port 8085)
Run locally:
# Start interaction API (uses ATLAS_CORE_CONFIG, DEPLOYED_VALIDATORS_CONFIG)
cabal run interaction-api
# Start query API (uses ATLAS_CORE_CONFIG, PG_CONN_STR, optional DEPLOYED_VALIDATORS_CONFIG)
cabal run query-api
# Start chain-sync service (uses KUPO_URL, PG_CONN_STR, ATLAS_CORE_CONFIG, DEPLOYED_VALIDATORS_CONFIG)
cabal run chainsync-service
# Start MCP server (proxies Query + Interaction APIs; needs both reachable)
cabal run mcp-serverEnvironment variables:
- Interaction API:
ATLAS_CORE_CONFIG(JSON or default fileconfig/config_atlas.json),DEPLOYED_VALIDATORS_CONFIG(JSON or default fileconfig/config_bjj_validators.json),BASIC_USER,BASIC_PASS,PORT(default 8082) - Query API:
ATLAS_CORE_CONFIG,PG_CONN_STR(defaulthost=postgres user=postgres password=postgres dbname=chainsync port=5432— Docker-oriented; override in.envfor a local Postgres),DEPLOYED_VALIDATORS_CONFIG(JSON or default fileconfig/config_bjj_validators.json; used for deployed-script context e.g. protocol status),BASIC_USER,BASIC_PASS,PORT(default 8083) - Chain Sync:
ATLAS_CORE_CONFIG,DEPLOYED_VALIDATORS_CONFIG,KUPO_URL(default in source is a Demeter preview Kupo URL; set tohttp://localhost:1442or your Kupo when running locally),PG_CONN_STR(defaulthost=localhost user=postgres password=postgres dbname=chainsync port=5432),BATCH_SIZE,FETCH_BATCH_SIZE,PORT(default 8084) - MCP Server:
QUERY_API_URL(defaulthttp://query-api:8083),INTERACTION_API_URL(defaulthttp://interaction-api:8082),BASIC_USER/BASIC_PASS(forwarded to upstream APIs),MCP_ENABLE_WRITE_TX(set to1to surface write tools; off by default),MCP_READINESS_TIMEOUT_MS(default 2000),PORT(default 8085)
- Health:
GET /health- Returns service health and current sync metrics - Readiness:
GET /ready- Indicates readiness (DB/migrations complete)
This project is licensed under the MIT License.
See the LICENSE file for details.
We welcome contributions from the community! Your feedback is invaluable! Use the following channels for support or feedback:
- Report bugs or suggest features via GitHub Issues.
- Join the Conversation: GitHub Discussions
- Submit pull requests (PRs) that align with the project’s goals.
Thanks to the Cardano community for support. This project is funded by F13 - Project Catalyst ID: #1300081

