Thank you for your interest in contributing to Navin! We truly appreciate it!! This guide will help you get started and ensure your contributions can be smoothly integrated.
- Getting Started
- Development Setup
- Making Contributions
- Pre-PR Checklist
- CI/CD Requirements
- Code Standards
- Testing Guidelines
- Getting Help
Before contributing, ensure you have the following installed:
Rust (latest stable version)
-
Fork the repository on GitHub by clicking the "Fork" button
-
Clone your fork locally:
git clone https://github.com/YOUR-USERNAME/navin-contracts.git cd navin-contracts -
Add the upstream repository: (So you can pull and sync new updates) NB: This is optional as you can just sync fork through github website
git remote add upstream https://github.com/Navin-xmr/navin-contracts.git
Run these commands to ensure everything is set up correctly:
# Check Rust version
rustc --version
# Check cargo
cargo --version
Always create a new branch for your work. Never commit directly to main or develop.
# Update your local main branch
git checkout main
If you added the upstream branch, pull the changes
(optional - you can just use github to sync your fork)
git pull upstream main
git checkout -b issue#
### Examples of good branch names:
- issue#23
- issue#45
- Write your code following our Code Standards
- Add or update tests for your changes
- Update documentation if needed
- Keep commits focused and precise
Before pushing, always run these commands locally to ensure CI will pass:
# 1. Format your code
cargo fmt
# 2. Run clippy (linter) - must pass with no warnings
cargo clippy --all-targets --all-features -- -D warnings
# 3. Run all tests
cargo test
# 4. Build contracts (WASM target)
cargo build --target wasm32-unknown-unknown --releaseImportant: If any of these commands fail, fix the issues before pushing!
# Stage your changes
git add .
# Commit with a descriptive message
git commit -m "type: brief description
Longer explanation if needed.
- Detail 1
- Detail 2"Commit Message Format we prefer:
feat:- New featurefix:- Bug fixdocs:- Documentation changestest:- Adding or updating testsrefactor:- Code refactoringchore:- Maintenance tasks
Examples:
git commit -m "feat: add delivery status tracking"
git commit -m "fix: resolve timestamp overflow in lock_assets"
git commit -m "docs: update installation instructions"git push origin issue#<number>- Go to your fork on GitHub
- Click "Compare & pull request"
- Fill out the PR template:
- Title: Clear, concise description
- Description: Explain what and why
- Testing: Describe how you tested
- Checklist: Complete all items
Before submitting your PR, ensure you've completed ALL of these steps:
- Code is formatted with
cargo fmt - No clippy warnings:
cargo clippy --all-targets --all-features -- -D warnings - All tests pass:
cargo test - WASM builds successfully:
cargo build --target wasm32-unknown-unknown --release - New tests added for new functionality
- Old tests previously passing before you added changes still pass
- Documentation updated (if applicable)
- Branch is up to date with
mainordev
Our CI pipeline runs the following checks. All must pass before your PR can be merged:
# Command run by CI:
cargo fmt --check
# To fix formatting issues:
cargo fmt# Command run by CI:
cargo clippy --all-targets --all-features -- -D warnings
# This fails on ANY warnings, so fix all clippy suggestions# Command run by CI:
cargo test
# Make sure all tests pass locally# Command run by CI:
cargo build --target wasm32-unknown-unknown --release
# Ensure contracts compile to WASM without errors# Command run by CI:
cargo audit
# Checks for known security vulnerabilities in dependenciesTo ensure our contracts remain deployable on-chain, we enforce strict size limits on the generated WASM files.
# Command run by CI:
./scripts/check_wasm_size.shBudget Update Policy:
- Thresholds: Currently 192KB for
shipmentand 25KB fortoken. - Increases: Budget increases must be justified in the PR description (e.g., due to critical new features) and approved by a maintainer.
- Optimization: Always attempt to optimize the code or reduce dependencies before requesting a budget increase.
- Follow the official Rust Style Guide
- Use
cargo fmtto automatically format code - Use descriptive variable names relevant to the feature
-
Error Handling
- Always use proper error types (don't use
panic!) - Return
Result<T, Error>for fallible operations
// Good pub fn transfer(env: Env, from: Address, to: Address, amount: i128) -> Result<(), Error> { if amount <= 0 { return Err(Error::InvalidAmount); } Ok(()) } // Bad pub fn transfer(env: Env, from: Address, to: Address, amount: i128) { assert!(amount > 0); // Don't use assertions for validation }
- Always use proper error types (don't use
-
Authentication
- Always verify addresses with
require_auth()
pub fn withdraw(env: Env, from: Address, amount: i128) -> Result<(), Error> { from.require_auth(); // Always first! // ... rest of function }
- Always verify addresses with
-
Storage
- Use type-safe storage keys
- Document storage layout
- Consider gas costs
-
Documentation
- Add doc comments to all public functions
- Explain complex logic
- Document error conditions
/// Deposits assets into the vault /// /// # Arguments /// * `from` - The address depositing assets /// * `amount` - Amount to deposit (must be positive) /// /// # Errors /// Returns `InvalidAmount` if amount <= 0 pub fn deposit(env: Env, from: Address, amount: i128) -> Result<(), Error> { // implementation }
-
Test Structure
#[test] fn test_descriptive_name() { // Setup let env = Env::default(); let contract = setup_contract(&env); // Execute let result = contract.function_to_test(); // Assert assert!(result.is_ok()); }
-
Test Coverage
- Test error conditions
- Test edge cases (zero, negative, maximum values)
- Test access control (for scenarios like admin or regular users)
-
Test Organization
- Keep tests in
test.rsor dedicated test modules - Group related tests together
- Use descriptive test names
- Keep tests in
#[test]
fn test_withdraw_insufficient_funds() {
let env = Env::default();
let contract_id = env.register_contract(None, NavinShipment);
let client = NavinShipmentClient::new(&env, &contract_id);
let user = Address::generate(&env);
// Try to withdraw more than deposited
let result = client.try_withdraw(&user, &user, &1000);
// Should fail with InsufficientFunds
assert!(result.is_err());
}// Wrong
Vec::new(&env)
// Correct
Vec::new(env)// Wrong
assert!(true, "Always passes");
// Correct - Remove unnecessary assertions
// Just call the function or use proper assertions- Ensure you've run ALL pre-PR checklist items
- Pull latest changes from upstream
- Clear cargo cache and rebuild:
cargo clean cargo test
- Bugs: Open an Issue
- Security: Email navinxmr@gmail.com
- General: Join our Telegram - Telegram Group Chat
- Automated Checks: CI must pass (typically 5 minutes)
- Code Review: Maintainer reviews code (1-3 days)
- Revisions: Address feedback. fix conflicts and push updates
Please do not just combine both conflicts when trying to resolve merge conflicts then just push. Such PRs will not be merged. Actually check the differences, add and fix issues, ensure your build and tests work then you can push.
# Complete pre-submission checklist
cargo fmt
cargo clippy --all-targets --all-features -- -D warnings
cargo test
cargo build --target wasm32-unknown-unknown --release
# Create and switch to a new branch
git checkout -b issue#<number>
# Stage, commit, and push
git add .
git commit -m "feat: your change description"
git push origin issue#<number>
# Update your branch with latest upstream changes (Optional - Can be done on Website)
git checkout main
git pull upstream main
git checkout issue#<number>
git rebase mainThank you for contributing to Navin! Together, we're building a transparent and secure delivery tracking platform.