Thank you for your interest in contributing to Stellar Tipz! This guide will walk you through the process from fork to merged PR.
- Code of Conduct
- Getting Started
- Branch Strategy
- Branch Protection Rules
- Workflow
- Branch Naming
- Commit Messages
- Pull Request Process
- Code Standards
- Review Criteria
We use a trunk-based model with short-lived feature branches:
| Branch | Purpose | Merges into |
|---|---|---|
main |
Production-ready code — always deployable | — |
develop |
Integration branch for in-progress work | main (via PR) |
feature/<short-description> |
New features and enhancements | develop or main |
fix/<short-description> |
Bug fixes | main (hot-fix) or develop |
chore/<short-description> |
Dependency updates, refactors, CI | develop or main |
docs/<short-description> |
Documentation-only changes | main |
Rules:
- Never commit directly to
main— always open a PR. - Keep feature branches short-lived (< 1 week ideally).
- Rebase or squash before merge to keep
mainhistory linear. - Delete the remote branch after it is merged.
The main branch is protected with the following settings (configured in repository Settings → Branches):
| Rule | Setting |
|---|---|
| Require a pull request | ✅ Enabled |
| Required approvals | 1 reviewer minimum |
| Dismiss stale reviews on new push | ✅ Enabled |
| Require status checks to pass | ✅ Enabled — see CI jobs below |
| Require branches to be up to date | ✅ Enabled |
| Require signed commits | ✅ Enabled |
| Allow force pushes | ❌ Disabled |
| Allow deletions | ❌ Disabled |
| Require linear history | ✅ Enabled (rebase or squash merge only) |
Required status checks (must pass before merge):
frontend-ci— lint, type-check, unit testscontract-ci— Soroban contract build and testspr-checks— PR validation (title format, linked issue)security-audit— dependency vulnerability scan
The full branch protection configuration is documented in .github/branch-protection.json.
Be respectful, constructive, and inclusive. We follow the Contributor Covenant.
- Fork this repository to your GitHub account
- Clone your fork locally:
git clone https://github.com/<your-username>/stellar-tipz.git cd stellar-tipz
- Set upstream remote:
git remote add upstream https://github.com/akan_nigeria/stellar-tipz.git
- Follow the Setup Guide to configure your local environment
Stellar Tipz is a monorepo with two halves: a Soroban smart contract (the source of truth) and a React frontend that reads/writes it over RPC.
┌──────────────────────────────┐ ┌──────────────────────────────────┐
│ frontend-scaffold/ │ │ contracts/tipz/ (Soroban, Rust) │
│ React 18 + Vite │ │ │
│ ├─ features/ (UI) │ │ lib.rs ← contract entry │
│ ├─ Zustand store (ADR-005) │ RPC │ ├─ profile / tips / token │
│ └─ contract bindings ──────┼──────► │ ├─ credit.rs (ADR-003) │
│ │ invoke │ ├─ leaderboard.rs │
│ Freighter wallet (signing) │ │ ├─ fees.rs (ADR-006) │
└──────────────────────────────┘ │ ├─ admin.rs / multisig.rs │
│ └─ storage.rs (ADR-004) │
│ │ │
│ ▼ instance/persistent/temp │
│ Soroban storage (TTL-managed) │
└──────────────────────────────────┘
- Frontend holds only light client state in a Zustand store; all durable state lives on-chain. Transactions are signed with the Freighter wallet.
- Contract is module-per-concern;
storage.rsis the single gateway to on-chain state and its TTL discipline.
For the full picture see ARCHITECTURE.md (directory
layout, module boundaries, data flow) and the decision records in
docs/adr/.
We use a fork-and-branch workflow:
1. Fork repo → 2. Create branch → 3. Implement → 4. Test → 5. PR → 6. Review → 7. Merge
-
Sync your fork before starting new work:
git checkout main git pull upstream main git push origin main
-
Create a feature branch from
main:git checkout -b <branch-name>
-
Implement the changes described in the issue
-
Test your changes:
- Contract changes:
cd contracts && cargo test - Frontend changes:
cd frontend-scaffold && npm run build
- Contract changes:
-
Commit with a clear message (see Commit Messages)
-
Push to your fork:
git push origin <branch-name>
-
Open a Pull Request against
mainon the upstream repo
Use this convention:
| Type | Pattern | Example |
|---|---|---|
| Feature | feat/<issue-number>-<short-description> |
feat/12-send-tip-function |
| Bug fix | fix/<issue-number>-<short-description> |
fix/25-withdraw-overflow |
| Test | test/<issue-number>-<short-description> |
test/30-credit-score-tests |
| Docs | docs/<issue-number>-<short-description> |
docs/5-contract-spec-update |
Follow Conventional Commits:
<type>(<scope>): <description>
[optional body]
[optional footer: Closes #<issue-number>]
| Type | Use |
|---|---|
feat |
New feature |
fix |
Bug fix |
test |
Adding or updating tests |
docs |
Documentation changes |
refactor |
Code restructuring (no feature/fix) |
ci |
CI/CD changes |
chore |
Maintenance tasks |
feat(contract): implement send_tip function
- Validate tip amount > 0
- Transfer XLM from tipper to contract
- Update creator balance in storage
- Emit TipSent event
Closes #12
test(contract): add unit tests for credit score calculation
Closes #18
- Code compiles without errors
- All existing tests pass
- New tests are written for new functionality
- Code follows project style guidelines
- Branch is up to date with
main
Use the PR template. Include:
- What — What does this PR do?
- Why — Link to the issue it resolves
- How — Brief technical approach
- Testing — How you verified it works
- Screenshots (for frontend changes)
- PRs are reviewed within 48 hours
- Address review feedback promptly
- Maintainer will merge once approved
- Format: Run
cargo fmtbefore committing - Lint:
cargo clippy -- -D warningsmust pass with zero warnings - Tests: Every public function must have tests
- Documentation: Add
///doc comments to public functions and types - Error handling: Use custom
ContractErrorenum, neverpanic!
- Lint: ESLint must pass (
npm run lint) - Types: No
anytypes — use proper TypeScript types - Components: Functional components with hooks
- Naming: PascalCase for components, camelCase for functions/variables
- Imports: Absolute imports from
src/using tsconfig paths
- No hardcoded secrets or private keys
- No
console.login production code (use proper error handling) - Keep functions focused and under 50 lines where possible
PRs are evaluated on:
| Criteria | Weight |
|---|---|
| Correctness — Does it solve the issue? | High |
| Tests — Are edge cases covered? | High |
| Security — No vulnerabilities introduced? | High |
| Code quality — Clean, readable, idiomatic? | Medium |
| Performance — No unnecessary computation? | Medium |
| Documentation — Clear comments where needed? | Low |
Project docs
- Setup Guide — get running locally in < 30 minutes
- Architecture and ADRs — how & why
- Deployment Guide, Contract Spec, Credit Score, Security
External
- Soroban docs
- Soroban SDK (Rust) reference
- Stellar developer docs
- Freighter wallet
- Rust book · Conventional Commits
Stellar Tipz uses Husky and lint-staged to enforce code quality before every commit. The hooks run automatically once you have installed dependencies.
- Blocks
.envfiles from being staged. Files named exactly.envare rejected..env.exampleand other variant names are permitted. - Scans for secret patterns. Any staged file containing a line that matches
PRIVATE_KEY,SECRET_KEY,API_KEY,ACCESS_TOKEN, orPASSWORDfollowed by a quoted value of 8 or more characters triggers an error. Review and remove the offending line before committing. - Runs lint-staged inside
frontend-scaffold/, applying ESLint auto-fixes and Prettier formatting to all staged TypeScript and JavaScript source files.
The hooks are installed automatically when you run npm install at the repo root (via the prepare script). If you cloned the repository without running install, or if hooks are not firing, run:
npm installTo verify the hook is in place:
ls -la .husky/
# pre-commit should be listed and executableIf you need to make an emergency commit that bypasses the hooks (for example, to commit a work-in-progress without fixing lint errors first), you can use:
git commit --no-verify -m "wip: ..."Use this sparingly. The CI pipeline enforces the same checks, so the branch will not be mergeable until they pass.
- Open a Discussion for general questions
- Comment on the relevant issue for task-specific questions
- Tag
@akan_nigeriafor urgent matters
Thank you for contributing to Stellar Tipz! Every contribution helps empower creators worldwide. 💫