Skip to content

About

⚡⚡High-performance Rust Axum API Service for Trustless-OSS ⚡⚡

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation


🌟 Overview

Toss Backend is the orchestration layer for the Trustless OSS platform. It connects GitHub activity with bounty state, contributor wallets, and escrow operations while keeping slow or retryable work in background jobs.

Once a bounty is labelled and assigned, it advances on its own: every step is a BullMQ job that re-checks the live rules, and transient failures retry with backoff. See docs/jobs.md.

Capability What it handles
🐙 GitHub integration GitHub App installations, repository sync, signed webhooks, issues, assignments, labels, and pull requests
🎯 Bounty lifecycle Reward tiers, contributor assignment, milestone creation, automatic payout, and payout status
🔐 Authentication Supabase bearer-token verification with GitHub identity extraction
💸 Escrow operations Unsigned transaction creation, deployment, funding, refunds, closure, and submission through Trustless Work
⚙️ Background processing BullMQ queues for webhooks, the bounty state machine, and scheduled escrow sync — with per-issue deduplication, automatic retries, and queue statistics (docs)
🩺 Operations Toasty migrations, dependency-aware health checks, request tracing, and graceful shutdown

🔄 How it works

flowchart LR
    GH["🐙 GitHub App<br/>events & webhooks"] -->|HMAC verified| API["⚡ Axum API"]
    UI["🖥️ Trustless OSS<br/>frontend"] -->|Supabase bearer token| API

    API --> DB[("🐘 PostgreSQL<br/>repos, issues & assignments")]
    API -->|enqueue only| REDIS[("🔴 Redis<br/>cache & BullMQ")]
    REDIS --> WORKERS["⚙️ BullMQ workers<br/>github-webhook · advance-issue<br/>push-milestone · release-payout"]
    WORKERS -->|re-check rules| DB
    WORKERS --> GH

    WORKERS --> TW["🤝 Trustless Work API"]
    TW --> STELLAR["🌐 Stellar escrow"]
Loading

The common bounty journey is:

  1. A maintainer connects a repository and configures reward tiers.
  2. GitHub sends signed issue, assignment, label, and pull-request events. Routes verify the signature and enqueue; they never move funds themselves.
  3. A contributor connects a payout wallet, and the milestone is pushed to escrow.
  4. A merged PR or closed issue satisfies the release rule, and the payout goes out automatically.
  5. If a step is not ready yet — no wallet, issue still open — the flow parks and resumes by itself when the missing piece arrives. Nobody presses retry.

Every job re-reads Postgres, GitHub, and the escrow contract before acting, so an already-paid bounty is always a no-op. Full job documentation →

🧰 Tech stack

Layer Technology
API Rust 2021, Axum 0.8, Tokio
Data PostgreSQL 16, Toasty 0.10 ORM, Redis 7
Authentication Auth, GitHub identity
Integrations GitHub App API, Trustless Work, Stellar
Observability tracing, dependency-aware health checks
Local infrastructure Docker Compose (PostgreSQL + Redis only)

🚀 Quick start

Prerequisites

  • Rust stable toolchain (MSRV for Toasty is ~1.95+)
  • Docker with Docker Compose
  • GitHub App, Supabase, Stellar, and Trustless Work credentials for the integration flows you want to exercise

1. Configure the environment

cp .env.example .env

Open .env and replace the placeholder credentials. The application validates its required configuration at startup, so all required values must be present. Never commit the populated .env file.

Local defaults match Docker Compose:

Service URL
PostgreSQL postgres://postgres:postgres@localhost:5435/trustless_oss
Redis redis://localhost:6379

2. Start PostgreSQL and Redis

docker compose up -d
docker compose ps

This starts PostgreSQL on localhost:5435 and Redis on localhost:6379.

3. Apply database migrations

On every server start (cargo run / deploy), the app applies pending SQL from toasty/migrations (embedded into the binary). Already-applied migrations are skipped.

Generate new migration files after you change models under src/shared/models/schema/:

cargo run --bin migrate -- migration generate --name describe_your_change

Then restart the server (or run apply manually):

cargo run --bin migrate -- migration apply
# or just:
cargo run

Commit the updated toasty/ folder so deploys include the new SQL.

4. Run the API

cargo run

cargo run starts the toss-backend server (default binary). It listens at http://localhost:5000 by default.

5. Verify the service

curl http://localhost:5000/
curl http://localhost:5000/api/v1/health

The root endpoint confirms that the API is running. The detailed health endpoint also reports PostgreSQL, Redis, environment, and Trustless Work status. Browse the full API (repos, contributor, bounty, escrow, GitHub webhooks, and health) at http://localhost:5000/swagger.

Tip

If port 5000 is already in use, change PORT in .env and use the same port in your health-check URL.

🔑 Environment guide

The complete template lives in .env.example.

Group Variables Purpose
Runtime NODE_ENV, PORT, LOG_LEVEL Server mode, address, and logging
Infrastructure DATABASE_URL, REDIS_URL PostgreSQL, cache, and job queue
Background jobs BULLMQ_PREFIX, BULLMQ_CONCURRENCY, ESCROW_SYNC_INTERVAL_SECS Optional BullMQ tuning (docs)
Authentication SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY Bearer-token verification
GitHub GITHUB_APP_ID, GITHUB_APP_PRIVATE_KEY, GITHUB_WEBHOOK_SECRET App authentication and webhook verification
Stellar STELLAR_NETWORK, platform and dispute-resolver keypairs Transaction signing and network selection
Trustless Work TRUSTLESS_WORK_API_KEY, TRUSTLESS_WORK_BASE_URL Escrow API access
Application APP_URL, WEBHOOK_URL Frontend and public webhook locations
Local webhook relay DEV_WEBHOOK_PROXY_ENABLED, SMEE_SOURCE_URL, SMEE_TARGET_URL Optional development-only GitHub relay

The migrate binary also accepts TOASTY_CONNECTION_URL as an override for DATABASE_URL.

🗺️ API map

Protected application routes use Authorization: Bearer <supabase-access-token>. GitHub webhooks instead require a valid X-Hub-Signature-256 signature. Uploads use a direct-to-storage flow: POST /api/v1/upload with JSON fields contentType, size, and optional folder returns a short-lived upload_url. Then PUT the raw file bytes to that URL with the returned headers. Configure the storage bucket's CORS policy to allow PUT from the frontend origin.

Area Main endpoints
System GET /, GET /health, GET /api/v1/health, GET /api/v1/health/database, GET /api/v1/health/redis, GET /api/v1/health/trustless-work, GET /api/v1/queue/stats
Repositories GET /api/v1/repos, POST /api/v1/repos/connect, POST /api/v1/repos/sync-installation, GET/DELETE /api/v1/repos/{repoId}
Issues and rewards GET /api/v1/repos/{repoId}/issues, PUT /api/v1/repos/{repoId}/rewards, POST /api/v1/issues/{issueId}/retry (emergency override — not part of the happy path)
Contributors POST /api/v1/wallet/connect, GET /api/v1/contributor/me
Milestones POST /api/v1/milestones/push
Escrow POST /api/v1/escrow/create-unsigned, /submit-deploy, /fund-unsigned, /submit-fund, /refund, /close-unsigned, /submit-close
GitHub POST /api/v1/webhooks/github
Docs GET /swagger (full OpenAPI UI), GET /api/v1-doc/openapi.json

Interactive docs for every public endpoint live at /swagger. Request/response schemas and bearer-auth requirements are included in the spec.

🗂️ Project structure

Toss-Backend/
├── src/
│   ├── bin/migrate.rs  # Toasty migration CLI
│   ├── modules/        # Repo, GitHub, bounty, contributor, and escrow domains
│   ├── shared/models/  # Entity DTOs + Toasty schema models
│   ├── infra/          # PostgreSQL (Toasty), Redis, BullMQ queue + jobs, cache, Stellar
│   ├── middleware/     # Authentication and request middleware
│   ├── routes/         # Health and operational routes
│   ├── lib.rs          # Shared library crate
│   ├── config.rs       # Environment configuration
│   ├── app.rs          # Axum router assembly
│   └── main.rs         # Server startup and graceful shutdown
├── docs/jobs.md        # Queues, job names, retry policy, automation rules
├── tests/              # Integration tests (BullMQ against a real Redis)
├── toasty/             # Generated SQL migrations, snapshots, history
├── Toasty.toml         # Toasty migration config
├── docker-compose.yml  # Local PostgreSQL + Redis
└── .env.example        # Safe configuration template

🛠️ Development

Run the same core checks used by the project before opening a pull request:

cargo fmt --check
cargo build
cargo test

Useful local commands:

# API server (default binary)
cargo run

# Migrations
cargo run --bin migrate -- migration generate --name my_change
cargo run --bin migrate -- migration apply

# Follow infrastructure logs
docker compose logs -f postgres redis

# Stop local infrastructure
docker compose down

# Stop and remove local database/cache volumes
docker compose down -v

Warning

docker compose down -v deletes the local PostgreSQL and Redis volumes. migration reset drops all tables in the connected database. Use either only when you intentionally want a clean local data reset.

🤝 Contributing

Issues and pull requests are welcome. Before submitting a change:

  1. Keep changes focused on one concern.
  2. Add or update tests for changed behavior.
  3. Run the formatting, build, and test commands above.
  4. Explain any configuration or migration changes in the pull request.
  5. Commit updated files under toasty/ when you change schema models.

Have an idea or found a bug? Open an issue.


Built for open-source contributors by Trustless OSS.

About

⚡⚡High-performance Rust Axum API Service for Trustless-OSS ⚡⚡

Resources

Stars

1 star

Watchers

0 watching

Forks

Contributors

Languages