This document outlines the development standards and best practices for contributing to the HavenScience project.
- Blockchain: BNB Smart Chain + EVM-compatible chains
- Smart Contracts: Solidity ^0.8.20
- Frontend: React 19 + Vite + ethers.js v6 + wagmi + RainbowKit
- Development: Hardhat, OpenZeppelin libraries
- Database: Supabase (PostgreSQL)
- Real-time: WebSocket-based indexing with PM2
- Node.js: Version 18.x or higher
- npm: Version 8.x or higher
- Git: Latest version
- Code Editor: VS Code recommended
Never commit .env files to the repository. Always use .env.example as a template. Required variables:
# Network
VITE_BSC_RPC_URL= # Your BSC RPC endpoint
BSC_PRIVATE_KEY= # For contract deployment (keep secure!)
# Contracts
VITE_FACTORY_ADDRESS= # Factory contract address
VITE_XTOKEN_ADDRESS= # HAVEN token address
VITE_ROUTER_V2_ADDRESS= # PancakeSwap V2 router
VITE_WBNB_ADDRESS= # Wrapped BNB address
# Services
VITE_SUPABASE_URL= # Supabase project URL
VITE_SUPABASE_KEY= # Supabase anon key
SUPABASE_SERVICE_ROLE_KEY= # For backend operations
VITE_WALLETCONNECT_PROJECT_ID= # WalletConnect project ID
# APIs
BSCSCAN_API_KEY= # For contract verification- Solidity Version: Always use
^0.8.20 - Imports: Use OpenZeppelin for standard implementations
- Security:
- Add reentrancy guards to all state-changing functions
- Use
SafeERC20for token transfers - Implement access control with OpenZeppelin's
OwnableorAccessControl
- Gas Optimization:
- Use
calldatafor read-only function parameters - Pack storage variables efficiently
- Minimize storage reads/writes
- Use
- Documentation: Add NatSpec comments to all public functions
Example:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
/**
* @title ExampleContract
* @notice This contract does X
* @dev Implementation details
*/
contract ExampleContract is ReentrancyGuard {
/**
* @notice Performs action X
* @param amount The amount to process
* @return success Whether operation succeeded
*/
function doSomething(uint256 amount) external nonReentrant returns (bool success) {
// Implementation
}
}- Modern JavaScript: Use ES6+ features
- React Hooks: Prefer functional components with hooks
- Async/Await: Use instead of promises chains
- Error Handling: Always wrap async calls in try/catch
- Comments: Add comments for complex logic only
Example:
import { useState, useEffect } from 'react';
import { ethers } from 'ethers';
export function TokenPrice({ tokenAddress }) {
const [price, setPrice] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchPrice() {
try {
const response = await fetch(`/api/token-price/${tokenAddress}`);
if (!response.ok) throw new Error('Failed to fetch price');
const data = await response.json();
setPrice(data.price);
} catch (error) {
console.error('Error fetching price:', error);
} finally {
setLoading(false);
}
}
fetchPrice();
}, [tokenAddress]);
if (loading) return <div>Loading...</div>;
return <div>${price}</div>;
}- Components: PascalCase (e.g.,
TokenCard.jsx) - Utilities: camelCase (e.g.,
formatPrice.js) - Contracts: PascalCase (e.g.,
BondingCurveFactory.sol) - Scripts: kebab-case (e.g.,
realtime-indexer.js)
main- Production-ready codedevelop- Development branchfeature/<name>- New featuresfix/<name>- Bug fixeshotfix/<name>- Critical production fixes
Use clear, descriptive commit messages:
✅ Good:
- "Add bonding curve graduation logic"
- "Fix price calculation for BNB pairs"
- "Update token creation fee structure"
❌ Bad:
- "update"
- "fix bug"
- "changes"
- Keep PRs focused on a single feature/fix
- Include description of changes
- Test thoroughly before submitting
- Ensure all tests pass
- Request review from team members
# Run Hardhat tests
npx hardhat test
# Run specific test file
npx hardhat test test/BondingCurve.test.js
# Check coverage
npx hardhat coverage# Run development server
npm run dev
# Build for production
npm run build
# Preview production build
npm run preview- Test on BSC Testnet first
npx hardhat run scripts/deploy.js --network bscTestnet- Verify contract on BSCScan
npx hardhat verify --network bsc <ADDRESS> <CONSTRUCTOR_ARGS>- Update contract addresses in
.env
- Build production bundle
npm run build- Deploy to Vercel
vercel --prod- Set environment variables in Vercel dashboard
- Deploy to production server
scp -r scripts/ user@server:/path/to/scripts- Setup PM2
pm2 start realtime-indexer.js --name realtime-indexer
pm2 startup
pm2 save- ✅ Use latest OpenZeppelin contracts
- ✅ Add reentrancy guards
- ✅ Validate all inputs
- ✅ Use SafeMath (built-in in 0.8+)
- ✅ Implement emergency pause mechanisms
- ❌ Never use
tx.originfor authentication - ❌ Avoid floating pragma versions
- ❌ Don't hardcode addresses
- ✅ Store in environment variables
- ✅ Use different keys for dev/prod
- ✅ Rotate keys regularly
- ✅ Use service role keys only on backend
- ❌ Never commit keys to git
- ❌ Never expose service keys in frontend
- ❌ Never share keys in public channels
- ✅ Validate user inputs
- ✅ Sanitize data before display
- ✅ Use HTTPS only
- ✅ Implement rate limiting
- ❌ Don't trust client-side data
- ❌ Never store private keys
- ❌ Don't execute user-provided code
Key tables:
tokens- Token informationtoken_stats- Real-time statisticstrades- Trade historycreator_fees- Fee collection recordsrobots- AI agent configurations
Always use Row Level Security (RLS) policies on sensitive tables.
- Use kebab-case for URLs
- Use RESTful principles
- Include API version if needed
✅ Good:
/api/tokens/{address}
/api/token-stats/{address}
/api/trade-history/{address}
❌ Bad:
/api/getToken/{address}
/api/TokenStats/{address}
/api/trades_history/{address}
Always return consistent error responses:
{
"error": "Token not found",
"code": "TOKEN_NOT_FOUND",
"status": 404
}- Code Splitting: Use dynamic imports for large components
- Lazy Loading: Load images and heavy components on demand
- Memoization: Use
useMemoanduseCallbackfor expensive operations - Debouncing: Debounce search inputs and API calls
- Gas Optimization: Minimize storage operations
- Batch Operations: Allow bulk operations when possible
- Events: Use events instead of storage for historical data
- Indexes: Add indexes on frequently queried columns
- Caching: Cache frequently accessed data
- Pagination: Always paginate large result sets
- PM2 for process management
- Check logs regularly:
pm2 logs - Monitor gas prices and adjust
- Track failed transactions
Always log errors with context:
try {
await someOperation();
} catch (error) {
console.error('Error in someOperation:', {
error: error.message,
stack: error.stack,
context: { userId, tokenAddress }
});
}For questions about these guidelines, contact the development team on Telegram.
These guidelines are subject to change. Last updated: January 2025