Thanks for taking the time to contribute. This is a pnpm + Cargo monorepo with three independently buildable parts — contracts, frontend, and backend — plus a published TypeScript SDK. Pick the section that matches what you're touching.
- Be respectful and constructive in issues, PRs, and reviews.
- Open an issue before starting on anything non-trivial, so we can align on approach before you invest time.
- Keep PRs focused — one logical change per PR is easier to review and easier to revert if something's wrong.
- Found a security issue? Don't open a public issue — see SECURITY.md.
contracts/ Soroban smart contracts (Rust, one Cargo workspace)
apps/web/ Next.js frontend
packages/sdk/ @azable/sdk — TypeScript bindings for the contracts
services/backend/ Rust/Axum backend — indexer, auth, off-chain data API
docs/ Architecture, API, and contract documentation
maintracks what's live — merges here go straight to the deployed app.developis the integration branch. Open PRs againstdevelop, notmain, unless you're fixing something already broken in production.- Branch off
developfor your work (git checkout -b feat/thing develop);developperiodically merges intomainfor a release.
git clone https://github.com/skiboso/Azable.git
cd Azable
git checkout develop
pnpm install
cp .env.example .envSee the root README.md for the full quickstart, including funding a testnet account and running the backend.
cd contracts
cargo build --release
cargo test --all- Each contract is its own crate; add new ones to
contracts/Cargo.toml'smemberslist. - Follow the existing patterns for events: prefer the typed
#[contractevent]macro over rawenv.events().publish(...)tuples where practical — it keeps the backend indexer's job simpler (seeservices/backend/src/indexer/decode.rs). - Run
cargo clippy --all-targets -- -D warningsbefore opening a PR.
pnpm --filter @azable/web dev
pnpm --filter @azable/web test
pnpm --filter @azable/web lint- Components live under
src/components/, grouped by atomic-ish tiers (ui/,molecules/,organisms/,modules/). Match the tier of what's around the thing you're adding. - Tailwind theme tokens (colors, radii) are defined in
src/app/globals.cssunder--azable-*— reuse those instead of hardcoding hex values. - New API routes go under
src/app/api/; most existing ones are still backed by in-memory or mock data (seesrc/services/*) rather than the real backend — that's a known, intentional gap being migrated incrementally ontoservices/backend, not something to silently "fix" in an unrelated PR.
pnpm --filter @azable/sdk build
pnpm --filter @azable/sdk test
pnpm --filter @azable/sdk generate # regenerate bindings from built contract WASMsrc/generated/is auto-generated per-contract; don't hand-edit it — hand-written high-level clients (PaymentStreamClient.ts, etc.) live alongside it insrc/.
cd services/backend
docker compose -f ../../docker-compose.yml up -d postgres
cp .env.example .env
sqlx migrate run
cargo test
cargo clippy --all-targets -- -D warnings
cargo fmt --check- New tables get a new numbered file under
migrations/— never edit an already-merged migration. - Prefer
sqlx::query/query_as(runtime) over thequery!compile-time macros, socargo checkdoesn't require a live database. - See
services/backend/README.mdfor the full route reference and its "Known v1 limitations" section before assuming a gap is a bug.
- Commit messages: short, imperative summary line (
fix(campaigns): ...,feat(backend): ...); reference the issue number when there is one. - PRs: describe what changed and why, and how you verified it (tests run, screenshots for UI changes, curl output for API changes). Link the issue it closes.
- CI must be green:
contracts.yml,backend.yml,frontend.yml,sdk-ci.ymlrun automatically based on which paths your PR touches.
Open a GitHub issue with:
- What you expected to happen vs. what actually happened.
- Steps to reproduce (for bugs) or the use case it unblocks (for features).
- Which part of the repo it affects (contracts / frontend / SDK / backend).
Thanks again for contributing — we read every issue and PR.