Skip to content

Latest commit

 

History

History
631 lines (458 loc) · 14.1 KB

File metadata and controls

631 lines (458 loc) · 14.1 KB

Contributing to Scavenger

Thank you for your interest in contributing to Scavenger — a Rust/Soroban smart contract system with a React/TypeScript frontend built on the Stellar blockchain. This document is the single authoritative reference for code style, the PR workflow, testing expectations, commit conventions, community standards, and environment setup.


Table of Contents

  1. Getting Started / Setup
  2. Code Style Guidelines
  3. Pull Request Process
  4. Testing Requirements
  5. Commit Message Conventions
  6. Development Workflow
  7. Review Process
  8. Contributor Recognition
  9. Code of Conduct

Getting Started / Setup

Prerequisites

Smart Contract (Rust / Soroban)

  • Rust toolchain — stable channel. Install via rustup:
    rustup toolchain install stable
    rustup default stable
    rustup target add wasm32-unknown-unknown
  • Soroban CLI — install the latest release:
    cargo install --locked soroban-cli --features opt

Frontend (React / TypeScript)

  • Node.js — LTS version (18+) recommended. Download from nodejs.org or use a version manager such as nvm.
  • npm — bundled with Node.js; no separate install required.

Clone and Install

# 1. Fork the repository on GitHub, then clone your fork
git clone https://github.com/<your-username>/Scavenger.git
cd Scavenger

# 2. Install Smart Contract dependencies
cargo build

# 3. Install Frontend dependencies
cd frontend
npm install
cd ..

Verify Setup

# Test Rust setup
cargo fmt --check
cargo clippy -- -D warnings
cargo test

# Test Frontend setup
cd frontend
npm run lint
npm run type-check
cd ..

Further Reading

Before diving in, review the existing documentation:


Code Style Guidelines

Consistent style keeps the codebase readable and review cycles short. Run all formatters and linters before pushing.

Rust (Smart Contract)

Formatting

Run cargo fmt before every commit:

cargo fmt

Style rules:

  • Max line length: 100 characters
  • Use 4 spaces for indentation
  • One blank line between functions
  • Two blank lines between modules

Linting

Run cargo clippy and resolve all warnings:

cargo clippy -- -D warnings

Common issues to avoid:

  • Unused imports
  • Unnecessary clones
  • Inefficient patterns
  • Unwrap without justification

Naming Conventions

  • Functions: snake_caseregister_participant, get_waste
  • Types/Structs: PascalCaseParticipantRole, WasteMetadata
  • Constants: SCREAMING_SNAKE_CASEMAX_WEIGHT, DEFAULT_TIMEOUT
  • Module names: snake_caseparticipant_storage, waste_validation

Function Design

  • Keep functions focused on a single responsibility
  • Avoid functions exceeding 50 lines; extract helpers when needed
  • Use descriptive names that explain intent
  • Document public functions with doc comments

Example:

/// Registers a new participant in the system.
///
/// # Arguments
/// * `address` - The participant's Stellar address
/// * `role` - The participant's role (Recycler, Collector, Manufacturer)
/// * `name` - Human-readable name
/// * `lat` - Latitude coordinate
/// * `lon` - Longitude coordinate
///
/// # Returns
/// Returns `Ok(())` on success or an error if validation fails.
pub fn register_participant(
    env: &Env,
    address: Address,
    role: ParticipantRole,
    name: String,
    lat: i32,
    lon: i32,
) -> Result<(), Error> {
    // Implementation
}

TypeScript / React (Frontend)

Formatting

Prettier must pass with no diff:

npx prettier --check .
npx prettier --write .  # Auto-fix

Style rules:

  • Max line length: 100 characters
  • Use 2 spaces for indentation
  • Trailing commas in multi-line objects/arrays
  • Single quotes for strings

Linting

ESLint must pass with no errors or warnings:

npx eslint .
npx eslint . --fix  # Auto-fix

Naming Conventions

  • React components: PascalCaseParticipantForm, WasteCard
  • Types/Interfaces: PascalCaseParticipant, WasteData
  • Variables/functions: camelCaseparticipantId, fetchWaste
  • Constants: SCREAMING_SNAKE_CASEMAX_RETRIES, API_TIMEOUT
  • File names: kebab-case for components — participant-form.tsx

Component Design

  • Keep components focused on a single concern
  • Extract reusable logic into custom hooks
  • Use TypeScript for type safety
  • Avoid prop drilling; use context when appropriate

Example:

interface ParticipantFormProps {
  onSubmit: (data: ParticipantData) => Promise<void>;
  isLoading?: boolean;
}

export const ParticipantForm: React.FC<ParticipantFormProps> = ({
  onSubmit,
  isLoading = false,
}) => {
  const [formData, setFormData] = useState<ParticipantData>({
    name: '',
    role: 'Recycler',
  });

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    await onSubmit(formData);
  };

  return (
    <form onSubmit={handleSubmit}>
      {/* Form fields */}
    </form>
  );
};

Pull Request Process

1. Fork and Branch

Fork the repository and create a dedicated branch:

git checkout -b feature/my-new-feature

2. Branch Naming Convention

Use one of these prefixes with kebab-case description:

Prefix When to use Example
feature/ New functionality feature/add-token-transfer
fix/ Bug fixes fix/null-pointer-crash
docs/ Documentation docs/update-setup-guide
refactor/ Code restructuring refactor/simplify-validation
test/ Test additions test/add-integration-tests

3. PR Description Template

Every PR must include:

## Description
Brief summary of changes.

## Motivation
Why this change is needed.

## Changes
- Bullet point 1
- Bullet point 2

## Testing
How to test these changes.

## Related Issues
Closes #123

## Checklist
- [ ] Code follows style guidelines
- [ ] Tests added/updated
- [ ] Documentation updated
- [ ] No breaking changes

4. Target the Correct Base Branch

Ensure your PR targets main. Check branch protection rules before opening.

5. Review and Approval

  • Minimum one maintainer approval required
  • All CI checks must pass
  • Address all review comments before merge

6. Keep PRs Focused

Address one concern per PR. Split large changes into multiple PRs.


Testing Requirements

Smart Contract Tests

All Smart Contract changes must include tests:

# Run all tests
cargo test

# Run specific test
cargo test test_register_participant

# Run with output
cargo test -- --nocapture

Test structure:

#[test]
fn test_register_participant_success() {
    let env = Env::default();
    // Setup
    // Execute
    // Assert
}

#[test]
#[should_panic(expected = "error message")]
fn test_register_participant_invalid_role() {
    // Test error case
}

Frontend Tests

Frontend tests use Vitest:

# Run all tests
npm test

# Run specific test file
npm test participant-form

# Run with coverage
npm test -- --coverage

Test structure:

import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import { ParticipantForm } from './participant-form';

describe('ParticipantForm', () => {
  it('should render form fields', () => {
    render(<ParticipantForm onSubmit={vi.fn()} />);
    expect(screen.getByLabelText(/name/i)).toBeInTheDocument();
  });

  it('should call onSubmit with form data', async () => {
    const onSubmit = vi.fn();
    render(<ParticipantForm onSubmit={onSubmit} />);
    // User interactions
    expect(onSubmit).toHaveBeenCalledWith(expectedData);
  });
});

Coverage Requirements

  • Minimum coverage: 80% for new code
  • No reduction in overall coverage
  • Critical paths must have 100% coverage

Test Data and Fixtures

Create reusable test fixtures:

// tests/fixtures.rs
pub fn create_test_participant() -> Participant {
    Participant {
        address: Address::random(&env),
        role: ParticipantRole::Recycler,
        name: "Test User".to_string(),
        lat: 0,
        lon: 0,
    }
}

Commit Message Conventions

This project follows Conventional Commits v1.0.0.

Format

<type>(<scope>): <short summary>

<body>

Closes #<issue-number>

Types

Type When to use
feat New feature
fix Bug fix
docs Documentation only
chore Build, tooling, dependencies
refactor Code restructuring
test Adding/updating tests
style Formatting, whitespace

Scopes

Scope Area
contract Rust/Soroban smart contract
frontend React/TypeScript frontend
scripts Build scripts, CI, tooling
docs Documentation files

Summary Rules

  • Imperative mood: "add feature", not "added feature"
  • Lowercase first letter
  • 72 characters or fewer
  • No period at end

Body

  • Separate from subject with blank line
  • Explain why, not what
  • Wrap at 72 characters
  • Reference related issues

Examples

feat(contract): add token transfer function

Implements the transfer entrypoint as specified in the token interface.
Validates sender balance before executing the transfer.

Closes #17
fix(frontend): resolve null pointer on wallet disconnect

The wallet context was not guarded against undefined on disconnect,
causing a crash in the header component.

Closes #23
docs(contract): add participant registration examples

Added code examples showing how to register participants with different
roles and validate their information.

Development Workflow

Local Development

  1. Create feature branch:

    git checkout -b feature/my-feature
  2. Make changes and test:

    # For Rust changes
    cargo fmt
    cargo clippy -- -D warnings
    cargo test
    
    # For Frontend changes
    cd frontend
    npm run lint
    npm run type-check
    npm test
  3. Commit with conventional messages:

    git add .
    git commit -m "feat(contract): add new function"
  4. Push and create PR:

    git push origin feature/my-feature
    # Create PR on GitHub

Pre-commit Hooks

Install pre-commit hooks to catch issues early:

# Install pre-commit framework
pip install pre-commit

# Install hooks
pre-commit install

# Run manually
pre-commit run --all-files

CI/CD Pipeline

All PRs run through automated checks:

  • Rust checks: formatting, linting, tests, WASM build
  • Frontend checks: formatting, linting, type checking, tests
  • Security: dependency audit, secret scanning

All checks must pass before merge.


Review Process

For Contributors

  1. Self-review before requesting review
  2. Respond to feedback promptly
  3. Request re-review after making changes
  4. Be respectful of reviewer time and expertise

For Reviewers

  1. Review within 48 hours when possible
  2. Be constructive in feedback
  3. Approve when satisfied with changes
  4. Merge when approved and CI passes

Review Checklist

  • Code follows style guidelines
  • Tests are adequate
  • Documentation is updated
  • No breaking changes
  • Performance impact acceptable
  • Security concerns addressed

Contributor Recognition

We recognize and appreciate all contributions! Contributors are acknowledged in:

  1. Commit history — visible in git log
  2. GitHub contributors page — automatic
  3. Release notes — for significant contributions
  4. CONTRIBUTORS.md — maintained list (coming soon)

Contribution Levels

  • Documentation: Typo fixes, guide improvements
  • Bug fixes: Small fixes, edge cases
  • Features: New functionality, enhancements
  • Maintenance: Refactoring, optimization, tooling

All levels are valued and appreciated!


Code of Conduct

Our Pledge

This project is committed to providing a welcoming and inclusive environment for everyone. We welcome contributors regardless of experience level, background, or identity.

We follow the Contributor Covenant as our Code of Conduct. All contributors and maintainers are expected to uphold these standards in all project spaces.

Expected Behavior

  • Be respectful and considerate
  • Welcome newcomers and different perspectives
  • Accept constructive feedback gracefully
  • Focus on what's best for the community
  • Use inclusive language

Unacceptable Behavior

  • Harassment or discrimination
  • Offensive comments or language
  • Unwelcome sexual attention
  • Trolling or insulting comments
  • Publishing private information

Reporting Violations

If you experience or witness violations, please report to:

[conduct@example.com]

All reports are reviewed promptly and handled with discretion.

Enforcement

Violations may result in temporary or permanent exclusion from the project.

For the full text, visit Contributor Covenant.


Additional Resources


Questions?

Thank you for contributing to Scavenger! 🚀