Contributing to STRATO¶
Guidelines for contributing to the STRATO platform codebase.
Welcome Contributors!¶
Thank you for your interest in contributing to STRATO! Whether you're fixing a bug, adding a feature, or improving documentation, your contribution is valued.
Before You Start¶
1. Set Up Your Development Environment¶
Follow the Setup Guide to get STRATO running locally.
2. Understand the Architecture¶
Read the Architecture Guide to understand how components work together.
3. Choose Your Area¶
Pick the area you want to work on:
- Blockchain Core - Haskell (
strato/) - Smart Contracts - Solidity (
mercata/contracts/) - Backend API - Node.js/TypeScript (
mercata/backend/) - Frontend UI - React/TypeScript (
mercata/ui/) - Services - Background services (
mercata/services/)
Development Workflow¶
1. Find or Create an Issue¶
Option A: Work on Existing Issue
- Browse GitHub Issues
- Look for issues labeled:
good-first-issue- Great for newcomershelp-wanted- Community contributions welcomebug- Bug fixesenhancement- New features- Comment on the issue to let others know you're working on it
Option B: Propose a New Feature
- Open a new issue
- Describe the feature/bug
- Wait for feedback from maintainers
- Once approved, start working on it
2. Fork and Clone (External Contributors)¶
If you're not a core team member:
# Fork the repo on GitHub first
git clone [email protected]:YOUR-USERNAME/strato-platform.git
cd strato-platform
# Add upstream remote
git remote add upstream [email protected]:blockapps/strato-platform.git
3. Create a Feature Branch¶
# Update main
git checkout main
git pull upstream main
# Create feature branch
git checkout -b feature/your-feature-name
Branch Naming Convention:
feature/description- New featuresfix/description- Bug fixesdocs/description- Documentation changesrefactor/description- Code refactoringtest/description- Test improvements
Examples:
feature/add-liquidation-alertsfix/lending-pool-health-factordocs/update-api-examples
4. Make Your Changes¶
Component-specific guidelines:
See the Architecture Guide for details on each component's structure and technology stack.
General guidelines:
- Write clean, readable code
- Follow existing code style
- Add comments for complex logic
- Update documentation if needed
5. Test Your Changes¶
Run tests:
# Full stack
make test
# Component-specific
cd mercata/contracts && npm test
cd mercata/backend && npm test
cd mercata/ui && npm test
Test locally:
./start test_node
# Manually test your changes
./forceWipe
rm -rf test_node/
Ensure:
- All existing tests pass
- New features have tests
- No regressions introduced
6. Commit Your Changes¶
Commit Message Format:
<type>(<scope>): <subject>
<body>
<footer>
Types:
feat- New featurefix- Bug fixdocs- Documentationstyle- Formatting (no code change)refactor- Code refactoringtest- Adding/updating testschore- Build/tooling changes
Examples:
feat(lending): add liquidation alerts
Add email and webhook notifications when positions approach
liquidation threshold. Users can configure alert levels
in the UI settings.
Closes #123
fix(cdp): correct stability fee calculation
The rate accumulator was not being updated correctly,
causing incorrect interest accrual. Fixed by updating
the accumulator on every state change.
Fixes #456
docs(api): update REST API examples
Update all API examples to use the new authentication
flow with OAuth 2.0 tokens.
Commit Best Practices:
- One logical change per commit
- Write clear, descriptive messages
- Reference issue numbers (
Closes #123,Fixes #456) - Keep commits atomic (easy to revert if needed)
7. Push Your Branch¶
git push origin feature/your-feature-name
8. Open a Pull Request¶
- Go to GitHub
- Click "New Pull Request"
- Select your branch
- Fill out the PR template (see below)
- Submit
PR Title Format:
Same as commit messages: <type>(<scope>): <subject>
PR Description Template:
## Description
Brief description of what this PR does.
## Motivation
Why is this change needed? What problem does it solve?
## Changes
- List of changes made
- Breaking changes (if any)
- New dependencies (if any)
## Testing
How was this tested? Steps to reproduce:
1. Step 1
2. Step 2
3. Expected result
## Checklist
- [ ] Tests pass locally
- [ ] New tests added (if applicable)
- [ ] Documentation updated (if applicable)
- [ ] No breaking changes (or documented)
- [ ] Code follows style guidelines
## Related Issues
Closes #123
Fixes #456
Code Style Guidelines¶
Haskell (Blockchain Core)¶
Style:
- Use
stylish-haskellfor formatting - 2-space indentation
- Max line length: 100 characters
- Explicit type signatures
- Descriptive function names
Example:
-- Good
processBlock :: Block -> StateT BlockchainState IO (Either BlockError ())
processBlock block = do
validateBlock block
executeTransactions (blockTransactions block)
updateState block
-- Bad (no type signature, unclear name)
pb b = do
validateBlock b
executeTransactions (blockTransactions b)
updateState b
Solidity (Smart Contracts)¶
Style:
- Use
prettier-plugin-solidityfor formatting - 4-space indentation
- Follow Solidity Style Guide
- Explicit visibility modifiers
- NatSpec comments for public functions
Example:
// Good
/// @notice Supply collateral to the lending pool
/// @param asset The address of the asset to supply
/// @param amount The amount to supply
/// @return success True if supply was successful
function supplyCollateral(
address asset,
uint256 amount
) external returns (bool success) {
require(amount > 0, "Amount must be greater than 0");
// ... implementation
}
// Bad (no comments, missing validation)
function supply(address a, uint b) public returns (bool) {
// ... implementation
}
TypeScript (Backend & Frontend)¶
Style:
- Use ESLint + Prettier
- 2-space indentation
- Max line length: 100 characters
- Explicit types (avoid
any) - Descriptive names
Example:
// Good
async function borrowUSDST(
user: string,
asset: string,
amount: bigint
): Promise<TransactionResult> {
const healthFactor = await calculateHealthFactor(user);
if (healthFactor < MIN_HEALTH_FACTOR) {
throw new Error("Health factor too low");
}
// ... implementation
}
// Bad (no types, unclear name)
async function borrow(u, a, amt) {
// ... implementation
}
General Guidelines¶
DRY (Don't Repeat Yourself):
- Extract common logic into functions
- Use libraries for shared code
KISS (Keep It Simple, Stupid):
- Simple solutions over clever ones
- Clear code over comments
Error Handling:
- Always handle errors gracefully
- Provide helpful error messages
- Log errors for debugging
Security:
- Never commit secrets (API keys, private keys)
- Validate all inputs
- Follow security best practices for your language
Code Review Process¶
What to Expect¶
- Automated Checks: CI/CD will run tests and linters
- Maintainer Review: A core team member will review your code
- Feedback: You may be asked to make changes
- Approval: Once approved, your PR will be merged
Review Timeline¶
- Simple fixes: 1-2 days
- Features: 3-7 days
- Large changes: 1-2 weeks
Addressing Feedback¶
# Make requested changes
git add .
git commit -m "Address review feedback"
git push origin feature/your-feature-name
Tips:
- Respond to all comments
- Ask questions if unclear
- Be open to feedback
- Iterate quickly
Testing Guidelines¶
Unit Tests¶
What: Test individual functions/components in isolation
When: Every new function/method
Example (TypeScript):
describe('calculateHealthFactor', () => {
it('should return correct health factor for safe position', () => {
const result = calculateHealthFactor(
BigInt('10000'), // collateral
BigInt('5000'), // debt
8500 // liquidation threshold
);
expect(result).toBe(BigInt('17000'));
});
});
Integration Tests¶
What: Test multiple components working together
When: New features involving multiple modules
Example:
describe('Lending Flow', () => {
it('should allow supply, borrow, repay, and withdraw', async () => {
await supplyCollateral(user, 'ETHST', ethers.parseEther('10'));
await borrow(user, 'USDST', ethers.parseEther('5000'));
await repay(user, 'USDST', ethers.parseEther('5000'));
await withdrawCollateral(user, 'ETHST', ethers.parseEther('10'));
});
});
E2E Tests¶
What: Test full user workflows from UI to blockchain
When: Major features, critical flows
Example:
test('User can borrow USDST', async ({ page }) => {
await page.goto('http://localhost:3001/borrow');
await page.click('[data-testid="supply-button"]');
await page.fill('[data-testid="amount-input"]', '10');
await page.click('[data-testid="confirm-button"]');
await expect(page.locator('[data-testid="success-message"]')).toBeVisible();
});
Documentation¶
When to Update Documentation¶
Always update docs when you:
- Add a new feature
- Change existing behavior
- Fix a bug that was documented incorrectly
- Add/remove API endpoints
- Change configuration options
What to Update¶
- User docs:
techdocs/(this site) - API docs: Swagger/OpenAPI specs
- Code comments: In-line comments for complex logic
- README files: Component-specific README files
Troubleshooting¶
Common Issues¶
Build fails:
# Clean and rebuild
make clean
make
Tests fail:
# Wipe and restart
./forceWipe
rm -rf test_node/
./start test_node
make test
Merge conflicts:
# Update from main
git checkout main
git pull upstream main
git checkout feature/your-feature-name
git rebase main
# Resolve conflicts
git rebase --continue
git push origin feature/your-feature-name --force
Getting Help¶
Questions?
- Documentation: docs.strato.nexus
- Support: support.blockapps.net
- Telegram: t.me/strato_net
Stuck on a contribution?
- Comment on the GitHub issue
- Ask in Telegram
- Reach out to maintainers
Thank You!¶
Your contributions make STRATO better for everyone. We appreciate your time and effort!
Next Steps:
- Setup - Get started
- Architecture - Understand the system