Skip to content

Latest commit

 

History

History
842 lines (617 loc) · 26.9 KB

File metadata and controls

842 lines (617 loc) · 26.9 KB

Contributor Environment Setup Guide

Goal: A new contributor should be able to set up NotifyChain from scratch on a clean machine without asking maintainers for help.

This guide walks you through setting up a local development environment for NotifyChain. By the end, you will have the listener service, the dashboard, the frontend analytics app, and the smart contracts building and running on your machine. This guide walks you through setting up a local development environment for NotifyChain. By the end, you will have the listener service, the dashboard, and the smart contracts building and running on your machine.


Table of Contents

  1. Required Dependencies
  2. Clone the Repository
  3. Listener Service Setup
  4. Dashboard Setup
  5. Frontend (Next.js Analytics) Setup
  6. Smart Contracts Setup
  7. Environment Variables Reference
  8. Full-Stack Verification Checklist
  9. Running Tests
  10. VS Code Setup (Recommended)
  11. Troubleshooting & FAQ
  12. Smart Contracts Setup
  13. Environment Variables Reference
  14. Running Tests
  15. VS Code Setup (Recommended)
  16. Troubleshooting & FAQ

1. Required Dependencies

Essential Toolchain

Dependency Minimum Version Install Method Used By
Rust stable rustup.rs Smart contracts
wasm32-unknown-unknown rustup target add wasm32-unknown-unknown Soroban contracts
Stellar CLI latest cargo install stellar-cli Contract build/deploy
Node.js 18 (dashboard), 20 (listener) nodejs.org or nvm Listener, Dashboard
npm comes with Node Package management
Git Your package manager or git-scm.com Version control

Platform Notes

  • macOS: Install Xcode Command Line Tools (xcode-select --install) before Rust.
  • Linux: Install build-essential (sudo apt install build-essential) before Rust.
  • Windows: Use Visual Studio Build Tools with "C++ build tools" workload for native sqlite3 bindings.

Node.js Version Management

The project uses two different Node.js versions across its components:

Workspace Node Version CI Reference
listener/ 20 .github/workflows/ci.ymlnode-version: 20
dashboard/ 18 .github/workflows/ci.ymlnode-version: 18

Recommendation: Use nvm (Node Version Manager) to switch between versions:

# Install nvm (macOS/Linux)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash

# Restart your terminal, then install both versions
nvm install 18
nvm install 20

# Use Node 20 for the listener (the more demanding component)
nvm use 20

For most local development, Node 20 is sufficient for both components. If you encounter CI-related issues, test against the specific version used in CI.

Quick Install Commands

# ── Rust + WebAssembly + Stellar CLI ──
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
rustup target add wasm32-unknown-unknown
cargo install --locked stellar-cli --features opt

# Verify
rustc --version && cargo --version && stellar --version

2. Clone the Repository

git clone https://github.com/CollinsC1O/Notify-Chain.git
git clone https://github.com/Core-Foundry/Notify-Chain.git
cd Notify-Chain

If you plan to contribute, fork the repository first, then clone your fork:

git clone https://github.com/YOUR-USERNAME/Notify-Chain.git
cd Notify-Chain
git remote add upstream https://github.com/CollinsC1O/Notify-Chain.git
git remote add upstream https://github.com/Core-Foundry/Notify-Chain.git

3. Listener Service Setup

The listener is the core off-chain service that polls the Stellar network, processes contract events, and delivers notifications.

3.1 Install Dependencies

cd listener
npm install

Note: The sqlite3 package includes native bindings. If the install fails, see the Troubleshooting section.

3.2 Configure Environment

cp .env.example .env

Open listener/.env in your editor. At minimum, set:

STELLAR_RPC_URL=https://soroban-testnet.stellar.org:443
CONTRACT_ADDRESSES=[{"address":"YOUR_CONTRACT_ID","events":["*"]}]

If you plan to use Discord notifications, also set:

DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_TOKEN
DISCORD_WEBHOOK_ID=YOUR_WEBHOOK_ID

Note: Both DISCORD_WEBHOOK_URL and DISCORD_WEBHOOK_ID are required together. If either is missing, Discord notifications are disabled.

For a full reference of every variable, see Environment Variables Reference. For a full reference of every variable, see Environment Variables Reference.

3.3 Initialize the Database

npm run migrate

This creates the SQLite database file (default location: listener/data/notifications.db) and runs all schema migrations.

3.4 Run the Listener

npm run dev

The listener starts and immediately begins polling the configured contracts. You should see log output showing poll cycles.

Verify it's running:

curl http://localhost:8787/health        # Health check
curl http://localhost:8787/api/events    # Event feed (may be empty initially)

3.5 Useful Listener Commands

Command Purpose
npm run dev Start in development mode (ts-node, hot reload)
npm run build Compile TypeScript to JavaScript
npm start Run the compiled production build
npm test Run all tests
npm run typecheck TypeScript type checking (no emit)
npm run migrate Initialize or update the SQLite database schema
npm run lint Alias for typecheck

4. Dashboard Setup

The dashboard is a React + Vite application that visualizes events from the listener's API.

4.1 Install Dependencies

cd dashboard
npm install

4.2 Configure Environment

cp .env.example .env

The default .env.example is pre-configured for local development:

VITE_EVENTS_API_URL=http://localhost:8787/api/events
VITE_STELLAR_NETWORK=TESTNET

Change VITE_EVENTS_API_URL if your listener runs on a different port.

4.3 Run the Dashboard

npm run dev

Open http://localhost:5173 in your browser. The dashboard fetches events from the listener API and displays them in real-time.

4.4 Useful Dashboard Commands

Command Purpose
npm run dev Start Vite dev server with hot module replacement
npm run build TypeScript check + Vite production build
npm test Run all tests
npm run lint ESLint with zero-tolerance for warnings
npm run preview Preview the production build locally
npm run benchmark Run performance rendering benchmarks

5. Frontend (Next.js Analytics) Setup

Note: The frontend is a legacy Next.js app for analytics visualization. Most contributors only need the Dashboard (section 4). Skip this section unless you are working on analytics features.

The frontend is a Next.js 14 application with Chart.js for analytics dashboards and Tailwind CSS for styling.

5.1 Install Dependencies

cd frontend
npm install

5.2 Configure Environment

The frontend reads from the listener's API and does not require its own .env file for basic operation. If you need to override defaults, create:

echo "NEXT_PUBLIC_API_URL=http://localhost:8787" > .env.local

5.3 Run the Frontend

npm run dev

Opens at http://localhost:3000.

5.4 Useful Frontend Commands

Command Purpose
npm run dev Start Next.js dev server
npm run build Production build
npm start Start production server
npm run lint Run Next.js linting

6. Smart Contracts Setup

The project contains two Soroban smart contracts. Building them is optional — you only need to do this if you are modifying contracts or deploying your own instances.

6.1 Build Contracts

5. Smart Contracts Setup

The project contains two Soroban smart contracts. Building them is optional — you only need to do this if you are modifying contracts or deploying your own instances.

5.1 Build Contracts

AutoShare Contract (contract/):

cd contract
stellar contract build

The compiled .wasm file is written to contract/target/wasm32-unknown-unknown/release/.

TaskBounty Contract (Documents/Task Bounty/):

cd Documents/Task\ Bounty
stellar contract build

6.2 Run Contract Tests

5.2 Run Contract Tests

# AutoShare
cd contract/contracts/hello-world
cargo test

# TaskBounty
cd Documents/Task\ Bounty
cargo test

6.3 Deploy to Testnet (Optional)

5.3 Deploy to Testnet (Optional)

This requires a funded Stellar testnet identity:

# Generate and fund a test identity
stellar keys generate my-identity --network testnet
stellar keys fund my-identity --network testnet

# Deploy the AutoShare contract
cd contract
stellar contract deploy \
  --wasm target/wasm32-unknown-unknown/release/hello_world.wasm \
  --source my-identity \
  --network testnet

# The contract ID is printed after successful deployment

6.4 Initialize a Deployed Contract

Most contracts require initialization after deployment. For the AutoShare contract:

# Find your wallet address
stellar keys address my-identity

# Initialize the contract with your admin address
stellar contract invoke \
  --id YOUR_CONTRACT_ID \
  --source my-identity \
  --network testnet \
  -- \
  initialize_admin \
  --admin YOUR_WALLET_ADDRESS

For the TaskBounty contract (see Documents/Task Bounty/SETUP.md for detailed configuration):

stellar contract invoke \
  --id YOUR_CONTRACT_ID \
  --source my-identity \
  --network testnet \
  -- \
  initialize

After initializing, add the contract ID to your listener/.env CONTRACT_ADDRESSES so the listener knows to monitor it.

6.5 Useful Contract Commands

5.4 Useful Contract Commands

Command Purpose
stellar contract build Build all contracts
cargo test Run contract tests
stellar contract deploy --wasm <FILE> --source <ID> --network testnet Deploy to testnet
stellar contract invoke --id <ID> --source <ID> --network testnet -- <FUNCTION> [ARGS] Call a contract function
stellar contract optimize --wasm <FILE> Optimize Wasm for production
stellar contract inspect --wasm <FILE> Inspect contract interface
cargo fmt --all Format Rust code

7. Environment Variables Reference

7.1 Listener (listener/.env)

6. Environment Variables Reference

6.1 Listener (listener/.env)

Variable Required Default Description
Stellar Network
STELLAR_NETWORK No testnet Network passphrase (testnet, pubnet, or custom)
STELLAR_RPC_URL Yes https://soroban-testnet.stellar.org:443 Soroban RPC endpoint to poll for events
Contracts
CONTRACT_ADDRESSES Yes [] JSON array of contract configs. Format: [{"address":"C...","events":["*"]}]. Each entry has address (string, the Stellar contract ID) and events (string array of event names to filter on, or ["*"] for all).
Polling
POLL_INTERVAL_MS No 30000 Time between RPC polls (milliseconds)
MAX_RECONNECT_ATTEMPTS No 5 Max consecutive RPC failures before stopping
RECONNECT_DELAY_MS No 5000 Base delay between reconnection attempts (exponential backoff)
API Server
EVENTS_API_PORT No 8787 HTTP server port for /health and /api/events
EVENTS_API_CORS_ORIGIN No http://localhost:5173 Allowed CORS origin (dashboard URL)
WEBHOOK_SECRETS No [] JSON array of webhook secrets for HMAC verification. Format: [{"id":"default","secret":"whsec_..."}]
Discord Notifications
DISCORD_WEBHOOK_URL No Discord webhook URL for sending notifications
DISCORD_WEBHOOK_ID No Discord webhook ID (required together with webhook URL)
NOTIFICATION_DEDUPLICATION_WINDOW_MS No 60000 In-memory dedup window for Discord notifications (ms)
NOTIFICATION_DEDUPLICATION_MAX_SIZE No 10000 Max entries in in-memory dedup cache
DISCORD_WEBHOOK_ID No Discord webhook ID (required if webhook URL is set)
Retry Queue
RETRY_BASE_DELAY_MS No 5000 Base delay for notification retry exponential backoff
RETRY_MAX_RETRIES No 5 Max retry attempts for failed Discord notifications
Event Processing Queue
EVENT_QUEUE_MAX_CONCURRENCY No 1 Max events to process concurrently (1 = ordered)
EVENT_QUEUE_MAX_RETRIES No 3 Max retry attempts per event before permanent failure
EVENT_QUEUE_BASE_DELAY_MS No 2000 Base delay for event retry exponential backoff
EVENT_QUEUE_POLL_INTERVAL_MS No 1000 How often the queue checks for due events (ms)
Database
DATABASE_PATH No ./data/notifications.db SQLite database file path
Scheduler
SCHEDULER_ENABLED No true Enable the notification scheduler
SCHEDULER_POLL_INTERVAL_MS No 10000 How often the scheduler polls for due notifications
SCHEDULER_LOCK_TIMEOUT_MS No 60000 Distributed lock timeout for scheduler
SCHEDULER_PROCESSOR_ID No auto-generated Unique ID for this scheduler instance (multi-instance setups)
SCHEDULER_BATCH_SIZE No 10 Max notifications to process per poll cycle
SCHEDULER_TIMING_BUFFER_MS No 60000 Buffer to prevent premature notification delivery
Rate Limiting
RATE_LIMIT_ENABLED No true Enable HTTP API rate limiting
RATE_LIMIT_WINDOW_MS No 60000 Rate limit window (milliseconds)
RATE_LIMIT_MAX_REQUESTS No 60 Max requests per window per client
RATE_LIMIT_CLIENT_OVERRIDES No {} JSON object of per-client rate limit overrides
Cleanup
CLEANUP_INTERVAL_MS No 3600000 How often to run cleanup jobs (1 hour)
NOTIFICATION_RETENTION_MS No 604800000 Retain completed notifications (7 days)
RATE_LIMIT_EVENT_RETENTION_MS No 86400000 Retain rate limit audit events (1 day)
EVENT_RETENTION_MS No 86400000 Retain in-memory events (1 day)
Logging
LOG_LEVEL No info Winston log level (error, warn, info, debug)
NODE_ENV No Set to production for newline-delimited JSON log output

7.2 Dashboard (dashboard/.env)

6.2 Dashboard (dashboard/.env)

Variable Required Default Description
VITE_EVENTS_API_URL No http://localhost:8787/api/events Listener API endpoint for fetching events
VITE_STELLAR_NETWORK No TESTNET Stellar network for wallet integration (TESTNET or MAINNET)

7.3 Minimum Viable Configuration

6.3 Minimum Viable Configuration

To run the listener with no optional features:

STELLAR_RPC_URL=https://soroban-testnet.stellar.org:443
CONTRACT_ADDRESSES=[{"address":"C...","events":["*"]}]
EVENTS_API_PORT=8787
EVENTS_API_CORS_ORIGIN=http://localhost:5173
DATABASE_PATH=./data/notifications.db

To add Discord notifications, also set:

DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_TOKEN
DISCORD_WEBHOOK_ID=YOUR_WEBHOOK_ID

8. Full-Stack Verification Checklist

Run these checks to confirm every component is working correctly.

8.1 Listener Health

# Check the health endpoint
curl http://localhost:8787/health

# Expected: {"status":"ok","services":{"stellarRpc":{"status":"ok"},"eventRegistry":{"status":"ok","eventCount":0}}}

8.2 Event Feed

# Check the events API (may be empty if no contracts are active)
curl http://localhost:8787/api/events

# Expected: {"events":[],"total":0} (or populated with events)

8.3 Scheduler Stats

# Check scheduler status
curl http://localhost:8787/api/schedule/stats

# Expected: {"pending":0,"processing":0,"completed":0,"failed":0,"overdue":0}

8.4 Dashboard

Open http://localhost:5173 in your browser and confirm:

  • The page loads without errors
  • The events feed renders (may be empty)
  • No CORS errors in the browser console (F12 → Console)

8.5 Frontend Analytics

If you set up the frontend, open http://localhost:3000 and confirm:

  • The analytics dashboard loads
  • Charts render without errors

8.6 Database Inspection

# Verify the database exists and has the correct schema
sqlite3 listener/data/notifications.db ".tables"

# Expected: notification_execution_log  notification_templates        polling_cursors
#           notification_template_audit_log  processed_events        rate_limit_events
#           scheduled_notifications

8.7 Clean Up and Start Fresh

If you need to reset everything:

# Reset listener database
rm -f listener/data/notifications.db
cd listener && npm run migrate

# Clear listener event registry (restart the process)
# Stop with Ctrl+C, then npm run dev again

9. Running Tests


---

## 7. Running Tests

Always run tests before submitting a pull request.

### Contracts

```bash
# AutoShare
cd contract/contracts/hello-world && cargo test

# TaskBounty
cd Documents/Task\ Bounty && cargo test

Listener

cd listener
npm test

Dashboard

cd dashboard
npm test

CI Validation (What GitHub Actions Runs)

The CI pipeline executes these checks on every pull request:

# Listener
cd listener
npm run typecheck   # TypeScript strict type checking
npm test            # Jest test suite

# Dashboard
cd dashboard
npm run lint        # ESLint (zero warnings)
npm run build       # TypeScript check + Vite build
npm test            # Jest test suite

# Contracts
cd contract
cargo fmt --all -- --check   # Rust formatting check
cargo test --workspace --all-features --verbose

10. VS Code Setup (Recommended)

8. VS Code Setup (Recommended)

Extensions

Install these VS Code extensions:

  1. rust-analyzer — Rust language support
  2. CodeLLDB — Debugger for Rust
  3. Better TOML — TOML file support
  4. ESLint — TypeScript linting
  5. Prettier — Code formatter

Settings

Add this to .vscode/settings.json (already present in the repository):

{
  "rust-analyzer.cargo.target": "wasm32-unknown-unknown",
  "rust-analyzer.checkOnSave.allTargets": false
}

This configures rust-analyzer to use the wasm32 target and avoids false-positive type errors from non-Wasm platform checks.


11. Troubleshooting & FAQ

9. Troubleshooting & FAQ

A more extensive troubleshooting guide is available at TROUBLESHOOTING.md. This section covers the most common setup issues.

Node.js & npm

Q: npm install fails with node-gyp or sqlite3 errors.

Native sqlite3 bindings must be compiled for your platform and Node.js version.

# Rebuild native bindings
npm rebuild sqlite3

# If that fails, reinstall
npm uninstall sqlite3 && npm install

On Windows, ensure you have Visual Studio Build Tools installed with the "C++ build tools" workload. On macOS, install Xcode Command Line Tools: xcode-select --install. On Windows, ensure you have Visual Studio Build Tools installed with the "C++ build tools" workload.


Q: Which Node.js version should I use?

The listener CI runs on Node 20, the dashboard CI runs on Node 18. Use Node 20 for local development (it is forward-compatible with the dashboard). Use nvm to switch if needed.


Stellar RPC & Network

Q: The listener starts but no events appear.

  1. Verify the contract ID in CONTRACT_ADDRESSES is correct and deployed on the same network as STELLAR_RPC_URL.
  2. Confirm the RPC endpoint is reachable:
    curl -X POST https://soroban-testnet.stellar.org:443 -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1,"method":"getHealth"}'
  3. Check listener logs for poll cycle output:
    cd listener && npm run dev
    Look for lines containing "Received events" or "Processing event".
  4. Verify the API is responding:
    curl http://localhost:8787/health
    curl http://localhost:8787/api/events

Q: stellar: command not found

# Ensure cargo's bin directory is in your PATH
source "$HOME/.cargo/env"

# Or reinstall
cargo install --locked stellar-cli --features opt

Database

Q: Error: Database not initialized or SQLITE_ERROR: no such table

cd listener
npm run migrate

If the data directory is missing:

mkdir -p listener/data
npm run migrate

Port Conflicts

Q: EADDRINUSE: address already in use :::8787

# Find the process using the port (macOS/Linux)
lsof -i :8787
kill -9 <PID>

# Or change the port in listener/.env
EVENTS_API_PORT=8788

Dashboard

Q: Dashboard shows a blank page or "Failed to fetch"

  1. Is the listener running? (npm run dev in listener/)
  2. Does VITE_EVENTS_API_URL in dashboard/.env match the listener's port?
  3. Restart the Vite dev server after editing .env.

Contracts

Q: error: toolchain 'stable' does not support target 'wasm32-unknown-unknown'

rustup target add wasm32-unknown-unknown

Q: error[E0463]: can't find crate for 'std'

Build with the correct target:

cargo build --target wasm32-unknown-unknown --release
# Or use Stellar CLI (handles the target automatically):
stellar contract build

After a git pull

If things stop working after pulling latest changes, run the full refresh: If things stop working after pulling latest changes:

# Contracts
cd contract && stellar contract build

# Listener
cd listener && npm install && npm run migrate

# Dashboard
cd dashboard && npm install

# Frontend
cd frontend && npm install

Still Stuck?

  1. Search open issues — your problem may already be reported.
  2. Search open issues — your problem may already be reported.
  3. Read the detailed Troubleshooting Guide.
  4. Open a new issue with:
    • Your OS and version
    • Output of rustc --version, node --version, stellar --version
    • The full error message and stack trace
    • Steps you have already tried

Project Map

Notify-Chain/
├── contract/                          # Soroban smart contract workspace
│   ├── contracts/hello-world/         #  AutoShare contract (active)
│   └── Cargo.toml                     # Workspace configuration
│
├── listener/                          #  Off-chain listener service
│   ├── src/
│   │   ├── api/                       # HTTP API (events, health, templates)
│   │   ├── services/                  # Core: subscriber, dedup, notifier, scheduler
│   │   ├── store/                     # In-memory event registry + preferences
│   │   ├── database/                  # SQLite schema and client
│   │   ├── types/                     # TypeScript type definitions
│   │   ├── utils/                     # Logging, formatting, helpers
│   │   └── index.ts                   # Entry point
│   └── src/__tests__/                 # Integration / E2E tests
│
├── dashboard/                         #  React + Vite event dashboard
│   └── src/
│       ├── components/                # UI components (EventCard, filters, etc.)
│       ├── services/                  # API client
│       ├── store/                     # Zustand state management
│       └── pages/                     # Page components
│
├── Documents/Task Bounty/             #  TaskBounty contract (Soroban)
│
├── frontend/                          #  Next.js analytics dashboard (Chart.js)
│   └── app/
│       ├── analytics/                 # Analytics pages with charts
│       └── page.tsx                   # Landing page
├── frontend/                          # Legacy Next.js frontend (not actively maintained)
│
├── scripts/                           # Helper scripts (health check, etc.)
│
├── CONTRIBUTOR_SETUP.md               #  This file
├── CONTRIBUTING.md                    # Contribution guidelines & PR workflow
├── TROUBLESHOOTING.md                 # Detailed troubleshooting reference
├── ARCHITECTURE_OVERVIEW.md           # High-level architecture walkthrough
├── SYSTEM_ARCHITECTURE.md             # Visual architecture with Mermaid diagrams
└── README.md                          # Project overview and quick start