district-registry is a ClojureScript project with:
- Smart Contracts: Solidity 0.4.24, deployed via Truffle
- Server: ClojureScript compiled to Node.js, GraphQL API
- UI: ClojureScript with Re-Frame (Redux-like) and Reagent (React wrapper)
- Node.js >= 20.18.1 (check
.tool-versions) - Java JDK >= 18 (for Clojure)
- Babashka (
bb) - ClojureScript task runner - PostgreSQL (for server database)
- Ganache (for local Ethereum testnet)
# Install Node dependencies (root, ui, server)
yarn install
cd ui && yarn install && cd ..
cd server && yarn install && cd ..
# Create database
psql -c "CREATE DATABASE district_registry_dev;"# Start local Ethereum testnet
bb testnet-dev
# Deploy smart contracts (in another terminal)
npx truffle migrate --network ganache --reset
# Start server compilation (watches for changes)
bb watch-server
# Start server (in another terminal)
bb run-server
# Start UI compilation (watches for changes)
bb watch-ui# Smart contract tests
npx truffle test
# Specific contract test
npx truffle test test/council_test.js
# Server tests (if available)
bb run-server-tests# Compile smart contracts
npx truffle compile
# Compile server for production
DISTRICT_REGISTRY_ENV=prod bb compile-server
# Compile UI for production
DISTRICT_REGISTRY_ENV=prod bb compile-ui
# Compile CSS
bb compile-csscontracts/ # Solidity smart contracts
migrations/ # Truffle deployment scripts
src/district_registry/
server/ # ClojureScript server code
db.cljs # Database schema and queries
syncer.cljs # Blockchain event indexer
graphql_resolvers.cljs
ui/ # ClojureScript UI code
components/ # Reagent components
events.cljs # Re-Frame events
subs.cljs # Re-Frame subscriptions
resources/
schema.graphql # GraphQL schema
shared/ # Shared ClojureScript code
- Forwarder Pattern: Contracts deployed as forwarders pointing to single implementation
- DSAuth: Access control (check
auth/DSAuth.sol) - EternalDb: Key-value storage (check
db/EternalDb.sol) - Checkpoint History: For historical queries (see
StakeBank.sol)
- Create contract in
contracts/ - Import necessary dependencies (DSAuth, SafeMath, etc.)
- Follow existing patterns (forwarder, events, modifiers)
- Create migration in
migrations/ - Add tests in
test/
- Add table definition in
src/district_registry/server/db.cljs - Add sync handlers in
src/district_registry/server/syncer.cljs - Add GraphQL types in
resources/schema.graphql - Add resolvers in
src/district_registry/server/graphql_resolvers.cljs
- Create page component in
src/district_registry/ui/<page>/page.cljs - Add route in routing configuration
- Add Re-Frame events in
events.cljs - Add Re-Frame subscriptions in
subs.cljs
- Use
bb(babashka) for all build tasks - Server must be restarted manually after ClojureScript changes
- Contracts use MutableForwarder for upgradability
- Events are indexed by syncer into PostgreSQL for fast queries
DISTRICT_REGISTRY_ENV=dev|qa|prod
ETHLANCE_CONFIG_PATH=/path/to/config.edn
UI_CONFIG_PATH=/path/to/ui-config.ednBefore marking ANY feature as complete:
- Smart contract compiles without errors
- Contract tests pass (
npx truffle test) - Server compiles (
bb watch-serverno errors) - UI compiles (
bb watch-uino errors) - Changes committed with conventional commits
- @fix_plan.md updated
- Documentation updated if needed