Contributing Guide

Thank you for your interest in contributing to AstralBeam! This guide covers how to contribute effectively.

Getting Started

Prerequisites

  • Node.js 20+
  • Rust 1.70+
  • Foundry
  • Git
  • MySQL 8.0+ (optional, for API development only)

Fork and Clone

# Fork the repository on GitHub, then:
git clone https://github.com/YOUR_USERNAME/astralbeam-core.git
cd astralbeam-core

# Add upstream remote
git remote add upstream https://github.com/make-software/astralbeam-core.git

Development Setup

Follow the Local Development guide to set up your environment.


Contribution Workflow

1. Create a Branch

# Sync with upstream
git fetch upstream
git checkout main
git merge upstream/main

# Create feature branch
git checkout -b feature/your-feature-name

Branch Naming Convention:

  • feature/ - New features
  • fix/ - Bug fixes
  • docs/ - Documentation changes
  • refactor/ - Code refactoring
  • test/ - Test additions/improvements

2. Make Changes

  • Write clean, readable code
  • Follow existing code style
  • Add tests for new functionality
  • Update documentation as needed

3. Commit Changes

Use Conventional Commits:

# Format: type(scope): description

git commit -m "feat(locker): add batch lock functionality"
git commit -m "fix(worker): handle RPC timeout errors"
git commit -m "docs(api): update transaction endpoint examples"
git commit -m "test(integration): add multi-chain roundtrip tests"

Types:

  • feat - New feature
  • fix - Bug fix
  • docs - Documentation
  • style - Formatting (no code change)
  • refactor - Code restructuring
  • test - Tests
  • chore - Build/tooling

4. Run Tests

# TypeScript tests
cd cli && npm test

# Solidity tests
cd contracts/eth && forge test

# Rust tests
cd contracts/casper && cargo odra test

# Linting
cd cli && npm run lint
cd contracts/eth && forge fmt --check
cd contracts/casper && cargo fmt --check && cargo clippy

5. Push and Create PR

git push origin feature/your-feature-name

Then create a Pull Request on GitHub with:

  • Clear title describing the change
  • Description of what and why
  • Link to related issues
  • Screenshots for UI changes

Code Style Guidelines

TypeScript

// Use explicit types
function processEvent(event: LockEvent): Promise<void> {
  // ...
}

// Prefer const/let over var
const config = loadConfig();
let counter = 0;

// Use async/await over promises
async function fetchData() {
  const result = await api.get('/data');
  return result;
}

// Use descriptive variable names
const transactionReceipt = await provider.getTransactionReceipt(txHash);

// Error handling
try {
  await submitTransaction(tx);
} catch (error) {
  if (error instanceof InsufficientFundsError) {
    logger.warn('Insufficient funds', { balance, required });
  } else {
    throw error;
  }
}

Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

// Use named imports
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

// NatSpec comments for public functions
/// @notice Locks tokens for bridging to Casper
/// @param token The ERC-20 token address
/// @param amount Amount to lock
/// @param recipient Casper recipient public key
function lock(
    address token,
    uint256 amount,
    bytes32 recipient
) external payable nonReentrant {
    // Validate inputs
    require(amount > 0, "Amount must be positive");
    require(recipient != bytes32(0), "Invalid recipient");

    // Effects before interactions
    _nonce++;
    lockedBalances[token] += amount;

    // Interactions last
    IERC20(token).safeTransferFrom(msg.sender, address(this), amount);

    emit Lock(token, msg.sender, recipient, amount, _nonce);
}

Rust

//! Module documentation using //!

use odra::casper_types::{U256, Key};

/// Function documentation using ///
///
/// # Arguments
/// * `chain_id` - The source chain identifier
/// * `block_number` - Block number to query
///
/// # Returns
/// The block hash if known, None otherwise
pub fn get_block_hash(&self, chain_id: u64, block_number: u64) -> Option<H256> {
    let key = (chain_id, block_number);
    self.block_headers.get(&key).map(|h| h.block_hash)
}

// Use Result for fallible operations
fn parse_attestation(data: &[u8]) -> Result<Attestation, ParseError> {
    // ...
}

// Prefer iterators over loops
let valid_signatures: Vec<_> = signatures
    .iter()
    .filter(|sig| verify_signature(sig, &hash))
    .collect();

Testing Requirements

Coverage Expectations

  • New features: 80%+ coverage
  • Bug fixes: Include regression test
  • Critical paths: 100% coverage

Test Types

Unit Tests - Test individual functions:

describe('computeHash', () => {
  it('should produce deterministic output', () => {
    const hash1 = computeHash(data);
    const hash2 = computeHash(data);
    expect(hash1).toEqual(hash2);
  });
});

Integration Tests - Test component interactions:

describe('Lock to Mint Flow', () => {
  it('should complete full bridge flow', async () => {
    // Lock on EVM
    const lockTx = await locker.lock(...);

    // Wait for mint on Casper
    const mintTx = await waitForMint(lockTx.hash);

    expect(mintTx.status).toBe('completed');
  });
});

Security Tests - Test attack vectors:

describe('Replay Protection', () => {
  it('should reject duplicate attestations', async () => {
    await tokenFactory.mint(attestation, signatures);

    await expect(
      tokenFactory.mint(attestation, signatures)
    ).rejects.toThrow('Already processed');
  });
});

Pull Request Guidelines

PR Checklist

  • [ ] Code follows style guidelines
  • [ ] Tests pass locally
  • [ ] New tests added for new functionality
  • [ ] Documentation updated
  • [ ] No console.log or debug statements
  • [ ] No hardcoded values (use config)
  • [ ] Security considerations addressed

PR Template

## Summary
Brief description of changes.

## Changes
- Added feature X
- Fixed bug Y
- Updated documentation Z

## Testing
Describe how you tested this:
- [ ] Unit tests pass
- [ ] Integration tests pass
- [ ] Manual testing on testnet

## Security
- [ ] No new vulnerabilities introduced
- [ ] Input validation added
- [ ] Access control verified

## Related Issues
Closes #123

Review Process

  1. Automated Checks - CI runs tests and linting
  2. Code Review - At least one maintainer review
  3. Security Review - For security-critical changes
  4. Final Approval - Maintainer merges

Security Contributions

Reporting Vulnerabilities

DO NOT open public issues for security vulnerabilities.

Instead, email: security@cspr.rad (or use GitHub Security Advisories)

Include:

  • Description of vulnerability
  • Steps to reproduce
  • Potential impact
  • Suggested fix (if any)

Security Review Areas

When reviewing security-related code:

  1. Input Validation - All external inputs validated
  2. Access Control - Proper authorization checks
  3. Reentrancy - No reentrancy vulnerabilities
  4. Integer Overflow - Safe math operations
  5. Signature Verification - Proper cryptographic checks
  6. Replay Protection - Nonces and event keys used

Documentation Contributions

Updating Documentation

Documentation lives in /gitbook:

# Preview locally
cd gitbook
npx gitbook-cli serve

# Or use GitBook's web editor

Documentation Style

  • Use clear, concise language
  • Include code examples
  • Add diagrams for complex flows
  • Keep formatting consistent
  • Test all code examples

Community

Communication Channels

  • GitHub Issues - Bug reports and feature requests
  • GitHub Discussions - Questions and ideas
  • Telegram - Real-time chat: t.me/astralbeam_io

Code of Conduct

  • Be respectful and inclusive
  • Help others learn
  • Focus on constructive feedback
  • Report inappropriate behavior

Recognition

Contributors are recognized in:

  • CHANGELOG.md for each release
  • GitHub contributors page
  • Release notes

Thank you for contributing to AstralBeam!

results matching ""

    No results matching ""