From c4a6d727fdb4bec2e9891ff4c8605ddf63466829 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 10 Dec 2025 16:29:29 +0000 Subject: [PATCH 1/5] Checkpoint before follow-up message Co-authored-by: hardlydiff --- DEPLOYMENT.md | 520 ++++++++++++++++++++++++++++++++++++ DEVELOPER_GUIDE.md | 486 ++++++++++++++++++++++++++++++++++ TESTING.md | 638 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1644 insertions(+) create mode 100644 DEPLOYMENT.md create mode 100644 DEVELOPER_GUIDE.md create mode 100644 TESTING.md diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 00000000..09edb175 --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,520 @@ +# Deployment Guide + +This guide covers deployment procedures for the Open Cap Table Protocol (OCP) across different environments. + +## Table of Contents + +- [Overview](#overview) +- [Prerequisites](#prerequisites) +- [Local Deployment](#local-deployment) +- [Testnet Deployment](#testnet-deployment) +- [Production Deployment](#production-deployment) +- [Post-Deployment](#post-deployment) +- [Verification](#verification) +- [Rollback Procedures](#rollback-procedures) + +## Overview + +OCP can be deployed to three environments: + +- **Local** - Development environment using Anvil +- **Testnet** - Staging environment (e.g., Base Sepolia) +- **Production** - Mainnet environment (e.g., Base Mainnet) + +Each environment requires: +1. Smart contract deployment +2. Environment configuration +3. Database setup +4. API server deployment + +## Prerequisites + +### Required Tools + +- Foundry (Forge, Anvil, Cast) +- Node.js and Yarn +- Docker and Docker Compose +- Access to blockchain RPC endpoints +- Private key with sufficient funds for gas + +### Environment Files + +Ensure you have the appropriate environment file: + +- `.env.local` - Local development +- `.env.dev` - Testnet deployment +- `.env.prod` - Production deployment + +### Required Environment Variables + +```bash +# Blockchain Configuration +RPC_URL= +CHAIN_ID= +PRIVATE_KEY= + +# Contract Verification (optional) +ETHERSCAN_L2_API_KEY= +ETHERSCAN_L1_API_KEY= + +# Database +DATABASE_URL= + +# Server +PORT=8293 +``` + +## Local Deployment + +### Step 1: Start Local Blockchain + +```bash +# Terminal 1: Start Anvil +anvil +``` + +Anvil will output: +- RPC URL: `http://127.0.0.1:8545` +- Chain ID: `31337` +- Private keys for testing + +### Step 2: Configure Environment + +Copy `.env.example` to `.env.local`: + +```bash +cp .env.example .env.local +``` + +Update `.env.local`: + +```bash +RPC_URL=http://127.0.0.1:8545 +CHAIN_ID=31337 +PRIVATE_KEY= +DATABASE_URL=mongodb://ocp:ocp@localhost:27017/mongo?authSource=admin&retryWrites=true&w=majority +PORT=8293 +``` + +### Step 3: Deploy Contracts + +```bash +yarn deploy:local +``` + +The script will: +1. Check if contracts already exist +2. Deploy factory contract +3. Deploy reference diamond and all facets +4. Output contract addresses + +### Step 4: Update Environment File + +Copy the contract addresses from the deployment output to `.env.local`: + +```bash +FACTORY_ADDRESS=0x... +REFERENCE_DIAMOND=0x... +DIAMOND_CUT_FACET=0x... +ISSUER_FACET=0x... +STAKEHOLDER_FACET=0x... +STOCK_CLASS_FACET=0x... +STOCK_FACET=0x... +CONVERTIBLES_FACET=0x... +EQUITY_COMPENSATION_FACET=0x... +STOCK_PLAN_FACET=0x... +WARRANT_FACET=0x... +STAKEHOLDER_NFT_FACET=0x... +``` + +### Step 5: Start Services + +**Terminal 2: MongoDB** +```bash +docker compose up +``` + +**Terminal 3: API Server** +```bash +yarn local +# or +USE_ENV_FILE=.env.local yarn dev +``` + +### Step 6: Verify Deployment + +```bash +# Check API health +curl http://localhost:8293/health + +# Should return: OK +``` + +## Testnet Deployment + +### Step 1: Prepare Environment + +1. **Get testnet RPC URL:** + - Base Sepolia: Use public RPC or get from [Base](https://docs.base.org/tools/network-faucets) + - Or use services like Alchemy, Infura + +2. **Get testnet tokens:** + - Use faucets to get testnet ETH for gas + - Base Sepolia: [Base Sepolia Faucet](https://docs.base.org/tools/network-faucets) + +3. **Configure `.env.dev`:** + ```bash + RPC_URL=https://sepolia.base.org + CHAIN_ID=84532 + PRIVATE_KEY= + DATABASE_URL= + ETHERSCAN_L2_API_KEY= + ``` + +### Step 2: Deploy Contracts + +```bash +yarn deploy:testnet +``` + +The script will: +1. Prompt for confirmation (non-local environments) +2. Deploy contracts to testnet +3. Output contract addresses and transaction hashes + +**Important:** Save all contract addresses and transaction hashes for verification. + +### Step 3: Verify Contracts (Optional) + +```bash +yarn verify:prod --env=dev +``` + +This verifies contracts on Etherscan/BaseScan for transparency. + +### Step 4: Update Environment + +Update `.env.dev` with deployed contract addresses. + +### Step 5: Deploy API Server + +Deploy to your testnet server: + +```bash +# On server +USE_ENV_FILE=.env.dev yarn start +``` + +Or use your deployment method (Docker, Kubernetes, etc.). + +### Step 6: Sync Blockchain Events + +Start the event listener to sync historical events: + +```bash +yarn sync:testnet +``` + +## Production Deployment + +### Pre-Deployment Checklist + +- [ ] All tests passing +- [ ] Code reviewed and approved +- [ ] Environment variables configured +- [ ] Private key secured (use key management service) +- [ ] Sufficient funds for gas +- [ ] Backup of current deployment +- [ ] Rollback plan prepared + +### Step 1: Final Verification + +```bash +# Run all checks +yarn flightcheck +yarn typecheck +yarn test:chain +yarn test:js +``` + +### Step 2: Prepare Production Environment + +1. **Secure private key:** + - Use environment variable injection + - Or key management service (AWS Secrets Manager, etc.) + - Never commit private keys + +2. **Configure `.env.prod`:** + ```bash + RPC_URL=https://mainnet.base.org + CHAIN_ID=8453 + PRIVATE_KEY= + DATABASE_URL= + ETHERSCAN_L2_API_KEY= + SENTRY_DSN= + ``` + +### Step 3: Deploy Contracts + +```bash +yarn deploy:mainnet +``` + +**Critical:** The script will prompt for confirmation. Verify: +- Correct network +- Correct private key +- Sufficient gas funds +- All addresses are correct + +### Step 4: Verify Contracts + +```bash +yarn verify:prod --env=prod +``` + +Verification is important for: +- Transparency +- Contract interaction tools +- Security audits + +### Step 5: Update Production Environment + +Update production environment variables with contract addresses. + +### Step 6: Deploy API Server + +Deploy using your production deployment method: + +**Docker:** +```bash +docker build -t ocp-api . +docker run -d --env-file .env.prod -p 8293:8293 ocp-api +``` + +**Kubernetes:** +```bash +kubectl apply -f deploy.prod.yaml +``` + +**Other:** Follow your organization's deployment procedures. + +### Step 7: Sync Historical Events + +```bash +yarn sync:mainnet +``` + +This syncs all historical blockchain events to the database. + +### Step 8: Monitor Deployment + +- Check API health endpoints +- Monitor error logs (Sentry) +- Verify WebSocket connections +- Check database sync status + +## Post-Deployment + +### Health Checks + +```bash +# API health +curl https://api.ocp.fairmint.co/health + +# Database connection +# Check MongoDB connection in logs + +# Blockchain connection +# Check RPC connection in logs +``` + +### Event Listener Status + +Verify WebSocket listeners are running: +- Check application logs for "WebSocket connected" messages +- Monitor for event processing logs +- Verify events are being written to database + +### Database Verification + +```bash +# Connect to MongoDB +mongosh + +# Check collections +show collections + +# Verify issuer data +db.issuers.find().count() +``` + +### API Testing + +Test key endpoints: + +```bash +# Health check +curl https://api.ocp.fairmint.co/health + +# Create issuer (test) +curl -X POST https://api.ocp.fairmint.co/issuer \ + -H "Content-Type: application/json" \ + -d '{"chain_id": 8453, ...}' +``` + +## Verification + +### Contract Verification + +Verify contracts are deployed correctly: + +```bash +# Using Cast +cast code --rpc-url + +# Should return bytecode (not 0x) +``` + +### Address Verification + +Verify all contract addresses: + +1. Check factory can create new cap tables +2. Verify diamond proxy points to correct facets +3. Test key functions on deployed contracts + +### Database Verification + +1. Check MongoDB collections exist +2. Verify indexes are created +3. Test read/write operations + +### API Verification + +1. Test all endpoints +2. Verify CORS settings +3. Check authentication (if applicable) +4. Test error handling + +## Rollback Procedures + +### Smart Contract Rollback + +**Note:** Smart contracts are immutable once deployed. Rollback means: +1. Deploying new contracts +2. Updating environment variables +3. Migrating data if necessary + +### API Server Rollback + +**Docker:** +```bash +# Rollback to previous image +docker pull ocp-api: +docker stop ocp-api +docker run -d --env-file .env.prod -p 8293:8293 ocp-api: +``` + +**Kubernetes:** +```bash +kubectl rollout undo deployment/ocp-api +``` + +**Other:** Follow your deployment system's rollback procedures. + +### Database Rollback + +1. Restore from backup +2. Re-sync blockchain events if needed +3. Verify data integrity + +### Emergency Procedures + +If critical issues occur: + +1. **Stop API server** to prevent further issues +2. **Assess impact** - what's affected? +3. **Check logs** for error details +4. **Rollback** if necessary +5. **Document** the issue and resolution + +## Deployment Scripts + +### Available Scripts + +```bash +# Local deployment +yarn deploy:local + +# Testnet deployment +yarn deploy:testnet + +# Mainnet deployment +yarn deploy:mainnet + +# Contract verification +yarn verify:prod --env= + +# Sync blockchain events +yarn sync:local +yarn sync:testnet +yarn sync:mainnet +``` + +### Custom Deployment + +For custom deployments, use the deployment script directly: + +```bash +./scripts/deploy_factory.sh --env= +``` + +## Best Practices + +1. **Always test locally first** before deploying to testnet/production +2. **Use separate private keys** for each environment +3. **Verify contracts** on block explorers +4. **Monitor deployments** closely +5. **Keep backups** of environment files and contract addresses +6. **Document changes** in deployment logs +7. **Use CI/CD** for automated deployments when possible +8. **Implement health checks** and monitoring +9. **Have rollback plans** ready +10. **Secure private keys** using key management services + +## Troubleshooting + +### Deployment Fails + +- Check RPC connection +- Verify private key has sufficient funds +- Check contract compilation errors +- Review deployment script logs + +### Contracts Not Verifying + +- Ensure Etherscan API key is correct +- Check contract bytecode matches source +- Verify constructor arguments +- Wait for block confirmations + +### API Server Won't Start + +- Check environment variables +- Verify database connection +- Check port availability +- Review application logs + +### Events Not Syncing + +- Verify WebSocket RPC URL +- Check event filter configuration +- Review listener logs +- Ensure contracts are deployed + +## Additional Resources + +- [Configuration Guide](./CONFIG.md) - Environment configuration details +- [Developer Guide](./DEVELOPER_GUIDE.md) - Development setup +- [Foundry Documentation](https://book.getfoundry.sh/) - Smart contract deployment +- [Base Documentation](https://docs.base.org/) - Base network information diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md new file mode 100644 index 00000000..1ef77175 --- /dev/null +++ b/DEVELOPER_GUIDE.md @@ -0,0 +1,486 @@ +# Developer Guide + +This guide provides comprehensive information for developers working on the Open Cap Table Protocol (OCP) repository. + +## Table of Contents + +- [Getting Started](#getting-started) +- [Project Structure](#project-structure) +- [Development Setup](#development-setup) +- [Architecture Overview](#architecture-overview) +- [Development Workflow](#development-workflow) +- [Testing](#testing) +- [Code Standards](#code-standards) +- [Common Tasks](#common-tasks) +- [Troubleshooting](#troubleshooting) + +## Getting Started + +### Prerequisites + +Before you begin, ensure you have the following installed: + +- **Node.js** (version as specified in `package.json`) +- **Yarn** package manager +- **Foundry** (Forge, Anvil, Cast) - [Installation Guide](https://book.getfoundry.sh/getting-started/installation) +- **Docker** and **Docker Compose** (for MongoDB) +- **Git** + +### Quick Start + +1. **Clone the repository:** + ```bash + git clone https://github.com/Fairmint/open-captable-protocol.git + cd open-captable-protocol + ``` + +2. **Set up the smart contract dependencies:** + ```bash + ./setup.sh + ``` + +3. **Install Node.js dependencies:** + ```bash + yarn install + ``` + +4. **Configure environment:** + ```bash + cp .env.example .env.local + # Edit .env.local with your configuration + ``` + +5. **Start local development:** + - Terminal 1: Start Anvil (local blockchain) + ```bash + anvil + ``` + - Terminal 2: Deploy contracts + ```bash + yarn deploy:local + ``` + - Terminal 3: Start MongoDB + ```bash + docker compose up + ``` + - Terminal 4: Start the API server + ```bash + yarn dev + ``` + +## Project Structure + +``` +open-captable-protocol/ +├── chain/ # Smart contracts (Solidity) +│ ├── src/ +│ │ ├── facets/ # Diamond pattern facets +│ │ ├── libraries/ # Shared libraries +│ │ ├── core/ # Core contracts +│ │ └── interfaces/ # Contract interfaces +│ └── script/ # Deployment scripts +├── src/ # API server (Node.js/TypeScript) +│ ├── app.js # Express app entry point +│ ├── routes/ # API route handlers +│ ├── controllers/ # Business logic controllers +│ ├── db/ # MongoDB models and operations +│ ├── chain-operations/ # Blockchain interaction utilities +│ ├── utils/ # Utility functions +│ ├── tests/ # Test files +│ └── examples/ # Example scripts +├── docs/ # Documentation +│ ├── DATA_MODEL.md # Data model documentation +│ ├── DIAMOND_PATTERN.md # Diamond pattern explanation +│ └── openapi.yaml # OpenAPI specification +├── scripts/ # Deployment and utility scripts +└── .github/ # GitHub workflows and templates +``` + +## Development Setup + +### Environment Configuration + +The project uses environment-specific configuration files: + +- `.env.local` - Local development +- `.env.dev` - Development/testnet environment +- `.env.prod` - Production/mainnet environment + +Key environment variables: + +```bash +# Database +DATABASE_URL="mongodb://ocp:ocp@localhost:27017/mongo?authSource=admin&retryWrites=true&w=majority" +DATABASE_REPLSET="0" +DATABASE_OVERRIDE="" # Optional database name override + +# Blockchain +RPC_URL="http://127.0.0.1:8545" +CHAIN_ID=31337 # 31337 for Anvil, 84532 for Base Sepolia, 8453 for Base Mainnet +PRIVATE_KEY="your_private_key_here" + +# Server +PORT=8293 + +# Contract Addresses (set after deployment) +FACTORY_ADDRESS= +REFERENCE_DIAMOND= +DIAMOND_CUT_FACET= +ISSUER_FACET= +# ... other facet addresses +``` + +See [CONFIG.md](./CONFIG.md) for detailed configuration information. + +### Smart Contract Setup + +1. **Install Foundry dependencies:** + ```bash + cd chain + forge install + ``` + +2. **Build contracts:** + ```bash + forge build + ``` + +3. **Run tests:** + ```bash + forge test + ``` + +4. **Format code:** + ```bash + forge fmt + ``` + +### Database Setup + +MongoDB runs in Docker. To start: + +```bash +docker compose up -d +``` + +Connect using MongoDB Compass: +``` +mongodb://ocp:ocp@localhost:27017/mongo?authSource=admin&retryWrites=true&w=majority +``` + +### Local Blockchain Setup + +1. **Start Anvil:** + ```bash + anvil + ``` + +2. **Copy a private key from Anvil output** and set it in `.env.local`: + ```bash + PRIVATE_KEY= + ``` + +3. **Deploy contracts:** + ```bash + yarn deploy:local + ``` + +4. **Update `.env.local`** with the deployed contract addresses from the output. + +## Architecture Overview + +### System Components + +OCP consists of two main layers: + +1. **Smart Contract Layer (Chain)** + - Solidity contracts using the Diamond pattern + - On-chain cap table data storage + - Transaction processing for equity movements + - Multi-chain support (Base, Arbitrum, etc.) + +2. **API Server (Web)** + - Express.js REST API + - MongoDB for off-chain data + - WebSocket event listeners + - OCF standard validation + +### Diamond Pattern + +The smart contracts use the Diamond pattern for modularity and upgradability: + +- **Diamond Contract**: Main entry point that delegates to facets +- **Facets**: Modular implementation contracts (Issuer, Stakeholder, StockClass, etc.) +- **Storage**: Shared storage structure accessible by all facets + +See [docs/DIAMOND_PATTERN.md](./docs/DIAMOND_PATTERN.md) for detailed information. + +### Data Flow + +1. **API Request** → Express routes → Controllers +2. **Controllers** → Database operations (MongoDB) + Chain operations (Smart contracts) +3. **Chain Events** → WebSocket listeners → Database updates +4. **Response** → OCF-compliant JSON + +See [docs/DATA_MODEL.md](./docs/DATA_MODEL.md) for data model details. + +## Development Workflow + +### Branch Strategy + +- **`main`** - Production-ready code +- **`dev`** - Development branch (default for PRs) +- **Feature branches** - Created from `dev` for new features + +**Important:** Never commit directly to `main` or `dev`. Always create a feature branch. + +### Creating a Feature Branch + +```bash +# Ensure you're on dev and up to date +git checkout dev +git pull origin dev + +# Create and checkout new branch +git checkout -b feature/your-feature-name + +# Make your changes and commit +git add . +git commit -m "feat(scope): description of changes" +``` + +### Commit Message Format + +Follow [Conventional Commits](https://www.conventionalcommits.org/): + +``` +(): + +[optional body] + +[optional footer] +``` + +Types: +- `feat`: New feature +- `fix`: Bug fix +- `docs`: Documentation changes +- `style`: Code style changes (formatting, etc.) +- `refactor`: Code refactoring +- `test`: Adding or updating tests +- `chore`: Maintenance tasks + +Example: +``` +feat(stakeholder): add support for stakeholder transfers +``` + +### Pull Request Process + +1. **Create PR** from your feature branch to `dev` +2. **PR Title** should follow Conventional Commits format: + ``` + feat(ocf-validation): creates OCF validation helper for routes + ``` +3. **Ensure tests pass** and code is formatted +4. **Request review** from team members +5. **Address feedback** and update PR +6. **Merge** after approval + +### Code Quality Checks + +Before committing, run: + +```bash +# Type checking +yarn typecheck + +# Linting +yarn lint:check + +# Format checking +yarn format:check + +# All checks +yarn flightcheck +``` + +Auto-fix issues: + +```bash +# Fix linting issues +yarn lint + +# Fix formatting +yarn format +``` + +## Testing + +### Running Tests + +**Smart Contract Tests:** +```bash +yarn test:chain +# or +cd chain && forge test +``` + +**JavaScript/TypeScript Tests:** +```bash +yarn test:js +``` + +**Integration Tests:** +```bash +yarn test-js-integration +``` + +### Writing Tests + +**Smart Contract Tests:** +- Located in `chain/test/` +- Use Foundry's testing framework +- Example: + ```solidity + function testExample() public { + // Test code + } + ``` + +**API Tests:** +- Located in `src/tests/` +- Use Jest testing framework +- Example: + ```javascript + describe('Feature', () => { + it('should do something', async () => { + // Test code + }); + }); + ``` + +See [TESTING.md](./TESTING.md) for detailed testing guidelines. + +## Code Standards + +### TypeScript/JavaScript + +- **Type Safety**: Avoid `any` and `unknown`. Use precise, explicit types. +- **Formatting**: Use Prettier (configured in `.prettierrc`) +- **Linting**: Follow ESLint rules (configured in `eslint.config.js`) +- **Imports**: Use ES6 import/export syntax +- **Error Handling**: Use try/catch blocks and proper error messages + +### Solidity + +- **Formatting**: Use `forge fmt` +- **Linting**: Follow Solhint rules (configured in `.solhintrc`) +- **Naming**: Use camelCase for variables, PascalCase for contracts +- **Documentation**: Add NatSpec comments for public functions + +### File Organization + +- Group related functionality together +- Keep files focused and single-purpose +- Use descriptive file and function names +- Add comments for complex logic + +## Common Tasks + +### Adding a New API Endpoint + +1. **Create route handler** in `src/routes/` +2. **Create controller** in `src/controllers/` +3. **Add route** to `src/app.js` +4. **Update OpenAPI spec** in `docs/openapi.yaml` +5. **Add tests** in `src/tests/` + +### Adding a New Smart Contract Facet + +1. **Create facet contract** in `chain/src/facets/` +2. **Define storage** in `chain/src/libraries/Storage.sol` +3. **Add deployment script** in `chain/script/` +4. **Update factory** if needed +5. **Add tests** in `chain/test/` + +### Adding Support for a New Chain + +1. **Add chain config** in `src/utils/chains.js`: + ```javascript + 12345: { + name: "New Chain", + rpcUrl: process.env.NEW_CHAIN_RPC_URL, + wsUrl: (process.env.NEW_CHAIN_RPC_URL || "").replace("https://", "wss://"), + } + ``` +2. **Add RPC URL** to environment files +3. **Deploy contracts** to the new chain +4. **Update documentation** + +### Resetting Local Environment + +To reset your local database: + +```bash +yarn deseed +``` + +This removes all test data from MongoDB. + +### Viewing Logs + +**API Server:** +- Logs are output to console +- Use `console.log()`, `console.error()` for debugging + +**Smart Contracts:** +- Use Foundry's logging: + ```solidity + console.log("Value:", value); + ``` + +## Troubleshooting + +### Common Issues + +**"Cannot connect to MongoDB"** +- Ensure Docker is running: `docker compose up` +- Check `DATABASE_URL` in `.env.local` +- Verify MongoDB container is healthy: `docker ps` + +**"Contract not found"** +- Ensure contracts are deployed: `yarn deploy:local` +- Check contract addresses in `.env.local` +- Verify Anvil is running and on the correct chain ID + +**"Type errors in TypeScript"** +- Run `yarn typecheck` to see all errors +- Ensure types are properly imported +- Check `tsconfig.json` configuration + +**"Tests failing"** +- Ensure all services are running (Anvil, MongoDB) +- Check environment variables are set correctly +- Clear test database: `yarn deseed` + +**"WebSocket connection issues"** +- Verify RPC URL supports WebSocket connections +- Check `WS_RECONNECT_INTERVAL` and `WS_MAX_RECONNECT_ATTEMPTS` in env +- Review logs for connection errors + +### Getting Help + +- Check existing documentation in `docs/` +- Review [CONFIG.md](./CONFIG.md) for configuration issues +- Check [CONTRIBUTING.md](./CONTRIBUTING.md) for contribution guidelines +- Open an issue on GitHub for bugs or feature requests + +## Additional Resources + +- [OpenAPI Specification](./docs/openapi.yaml) - API documentation +- [Data Model Documentation](./docs/DATA_MODEL.md) - Database schema +- [Diamond Pattern Documentation](./docs/DIAMOND_PATTERN.md) - Smart contract architecture +- [Configuration Guide](./CONFIG.md) - Environment configuration +- [Foundry Book](https://book.getfoundry.sh/) - Foundry documentation +- [OCF Standard](https://github.com/Open-Cap-Table-Coalition/Open-Cap-Format-OCF) - Open Cap Table Format specification diff --git a/TESTING.md b/TESTING.md new file mode 100644 index 00000000..660017f9 --- /dev/null +++ b/TESTING.md @@ -0,0 +1,638 @@ +# Testing Guide + +This guide covers testing practices, test structure, and how to write and run tests for the Open Cap Table Protocol (OCP). + +## Table of Contents + +- [Overview](#overview) +- [Test Structure](#test-structure) +- [Running Tests](#running-tests) +- [Smart Contract Testing](#smart-contract-testing) +- [API Testing](#api-testing) +- [Integration Testing](#integration-testing) +- [Writing Tests](#writing-tests) +- [Test Utilities](#test-utilities) +- [Best Practices](#best-practices) +- [Troubleshooting](#troubleshooting) + +## Overview + +OCP uses two testing frameworks: + +- **Foundry (Forge)** - For smart contract testing +- **Jest** - For API and integration testing + +Tests are organized by type: +- **Unit Tests** - Test individual functions/contracts in isolation +- **Integration Tests** - Test interactions between components +- **End-to-End Tests** - Test complete workflows + +## Test Structure + +### Smart Contract Tests + +Location: `chain/test/` + +``` +chain/test/ +├── TestBase.sol # Base test contract with common setup +├── StockIssuance.t.sol # Stock issuance tests +├── StockTransfer.t.sol # Stock transfer tests +├── StakeholderPositions.t.sol +├── AccessControl.t.sol +└── mocks/ # Mock contracts for testing +``` + +### API Tests + +Location: `src/tests/` + +``` +src/tests/ +├── errorHandling.test.js # Error handling tests +├── transactionHash.test.js # Transaction hash tests +└── integration/ # Integration tests + └── utils.ts # Test utilities +``` + +## Running Tests + +### Smart Contract Tests + +**Run all contract tests:** +```bash +yarn test:chain +# or +cd chain && forge test +``` + +**Run specific test file:** +```bash +cd chain +forge test --match-path test/StockIssuance.t.sol +``` + +**Run with verbosity:** +```bash +forge test -vvv # Very verbose output +``` + +**Run specific test function:** +```bash +forge test --match-test testIssueStock +``` + +**Run with gas reporting:** +```bash +forge test --gas-report +``` + +**Run with coverage:** +```bash +forge coverage +``` + +### API Tests + +**Run all JavaScript tests:** +```bash +yarn test:js +``` + +**Run integration tests:** +```bash +yarn test-js-integration +``` + +**Run specific test file:** +```bash +yarn jest src/tests/errorHandling.test.js +``` + +**Run in watch mode:** +```bash +yarn jest --watch +``` + +**Run with coverage:** +```bash +yarn jest --coverage +``` + +### Running Tests in CI/CD + +Tests should pass before merging PRs. The CI pipeline runs: + +```bash +yarn flightcheck # Lint and format checks +yarn typecheck # TypeScript type checking +yarn test:chain # Smart contract tests +yarn test:js # API tests +``` + +## Smart Contract Testing + +### Test Setup + +Smart contract tests extend `DiamondTestBase` which provides: + +- Deployed factory and cap table contracts +- Helper functions for creating stakeholders, stock classes, etc. +- Common test fixtures + +Example: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "./TestBase.sol"; +import { IStockFacet } from "@interfaces/IStockFacet.sol"; + +contract MyTest is DiamondTestBase { + function testMyFeature() public { + // Test code here + } +} +``` + +### Writing Contract Tests + +**Basic Test Structure:** + +```solidity +function testFeatureName() public { + // Arrange - Set up test data + bytes16 stakeholderId = createStakeholder(); + bytes16 stockClassId = createStockClass(0x123...); + + // Act - Execute the function + IStockFacet(address(capTable)).issueStock(params); + + // Assert - Verify results + assertEq(quantity, expectedQuantity); +} +``` + +**Testing Reverts:** + +```solidity +function test_RevertInvalidInput() public { + bytes16 invalidId = 0x00000000000000000000000000000000; + + vm.expectRevert( + abi.encodeWithSignature("NoStakeholder(bytes16)", invalidId) + ); + + IStockFacet(address(capTable)).issueStock(params); +} +``` + +**Testing Events:** + +```solidity +function testEmitsEvent() public { + vm.expectEmit(true, true, false, true, address(capTable)); + emit StockIssued(stakeholderId, stockClassId, quantity, price); + + IStockFacet(address(capTable)).issueStock(params); +} +``` + +**Using Forge's Cheatcodes:** + +```solidity +// Set block timestamp +vm.warp(block.timestamp + 1 days); + +// Set block number +vm.roll(block.number + 100); + +// Impersonate an address +vm.prank(userAddress); +contract.function(); + +// Deal tokens/ETH +vm.deal(address(this), 100 ether); + +// Expect a call +vm.expectCall(address(target), abi.encodeWithSelector(...)); +``` + +### Test Helpers + +The `DiamondTestBase` contract provides helper functions: + +```solidity +// Create a stakeholder +bytes16 stakeholderId = createStakeholder(); + +// Create a stock class +bytes16 stockClassId = createStockClass(0x123..., 100000); + +// Create a stock plan +bytes16 stockPlanId = createStockPlan(stockClassIds); +``` + +## API Testing + +### Test Setup + +API tests use Jest and require: + +- MongoDB connection (test database) +- Local blockchain (Anvil) running +- Contract deployment + +Example setup: + +```javascript +import { describe, test, beforeAll, afterAll, expect } from "@jest/globals"; +import { connectDB } from "../db/config/mongoose"; +import { deseedDatabase } from "../tests/integration/utils"; + +describe("Feature Tests", () => { + beforeAll(async () => { + // Connect to test database + await connectDB(); + + // Deploy contracts + // Set up test data + }); + + afterAll(async () => { + // Clean up + await deseedDatabase(); + await disconnectDB(); + }); + + test("should do something", async () => { + // Test code + }); +}); +``` + +### Writing API Tests + +**Basic Test:** + +```javascript +test("should create issuer", async () => { + const response = await request(app) + .post("/issuer") + .send({ + chain_id: 31337, + legal_name: "Test Company", + // ... other fields + }); + + expect(response.status).toBe(200); + expect(response.body.id).toBeDefined(); +}); +``` + +**Testing Error Cases:** + +```javascript +test("should return 400 for invalid input", async () => { + const response = await request(app) + .post("/issuer") + .send({ + // Missing required fields + }); + + expect(response.status).toBe(400); + expect(response.body.error).toBeDefined(); +}); +``` + +**Testing Database Operations:** + +```javascript +test("should save to database", async () => { + const issuer = await createIssuer(issuerData); + + const found = await Issuer.findById(issuer.id); + expect(found).toBeDefined(); + expect(found.legal_name).toBe("Test Company"); +}); +``` + +**Testing Contract Interactions:** + +```javascript +test("should deploy contract", async () => { + const { contract, address } = await deployCapTable( + issuerIdBytes16, + initialShares, + chainId + ); + + expect(contract).toBeDefined(); + expect(address).toMatch(/^0x[a-fA-F0-9]{40}$/); +}); +``` + +### Test Utilities + +**Database Utilities:** + +```javascript +import { deseedDatabase, deleteIssuerData } from "./integration/utils"; + +// Clear entire database +await deseedDatabase(); + +// Delete specific issuer data +await deleteIssuerData(issuerId); +``` + +**Contract Utilities:** + +```javascript +import { deployCapTable } from "../chain-operations/deployCapTable"; +import { convertUUIDToBytes16 } from "../utils/convertUUID"; +import { toScaledBigNumber } from "../utils/convertToFixedPointDecimals"; + +// Deploy a cap table +const { contract, address } = await deployCapTable( + convertUUIDToBytes16(issuerId), + "1000000", + "31337" +); + +// Convert values for contract calls +const quantity = toScaledBigNumber("1000"); +``` + +**Error Decoding:** + +```javascript +import { decodeError } from "../utils/errorDecoder"; + +try { + await contract.issueStock(params); +} catch (error) { + const decoded = decodeError(error); + expect(decoded.name).toBe("NoStakeholder"); +} +``` + +## Integration Testing + +Integration tests verify interactions between: + +- API endpoints and database +- API endpoints and smart contracts +- Database and blockchain events +- Complete workflows + +### Example Integration Test + +```javascript +describe("Stock Issuance Integration", () => { + let contract; + let issuerId; + let stockClassId; + let stakeholderId; + + beforeAll(async () => { + // Set up complete environment + issuerId = await createIssuer(); + contract = await deployCapTable(issuerId); + stockClassId = await createStockClass(contract); + stakeholderId = await createStakeholder(contract); + }); + + test("should issue stock end-to-end", async () => { + // 1. Create issuance via API + const response = await request(app) + .post("/transactions/issuance") + .send({ + issuerId, + stockClassId, + stakeholderId, + quantity: "1000", + // ... + }); + + expect(response.status).toBe(200); + + // 2. Verify on-chain + const position = await contract.getPosition( + stakeholderId, + stockClassId + ); + expect(position.quantity).toBe(toScaledBigNumber("1000")); + + // 3. Verify in database + const transaction = await Issuance.findById(response.body.id); + expect(transaction).toBeDefined(); + expect(transaction.quantity).toBe("1000"); + }); +}); +``` + +## Writing Tests + +### Test Naming Conventions + +**Smart Contracts:** +- `testFeatureName()` - Happy path tests +- `test_RevertReason()` - Revert tests +- `testFuzz_FeatureName()` - Fuzz tests + +**API Tests:** +- `should do something` - Descriptive test names +- Use `describe` blocks to group related tests + +### Test Organization + +1. **Arrange** - Set up test data and environment +2. **Act** - Execute the code being tested +3. **Assert** - Verify the results + +### Test Isolation + +- Each test should be independent +- Clean up after tests (use `afterEach` or `afterAll`) +- Don't rely on test execution order +- Use unique IDs for test data + +### Mocking + +**Mocking External Services:** + +```javascript +jest.mock("../utils/externalService", () => ({ + callExternalAPI: jest.fn().mockResolvedValue({ data: "test" }) +})); +``` + +**Mocking Contract Calls:** + +```javascript +const mockContract = { + issueStock: jest.fn().mockResolvedValue({ hash: "0x..." }) +}; +``` + +## Test Utilities + +### UUID Conversion + +```javascript +import { convertUUIDToBytes16 } from "../utils/convertUUID"; + +const bytes16 = convertUUIDToBytes16(uuid); +``` + +### Fixed-Point Decimals + +```javascript +import { toScaledBigNumber } from "../utils/convertToFixedPointDecimals"; + +const scaled = toScaledBigNumber("1000.50"); // Returns BigNumber +``` + +### Error Decoding + +```javascript +import { decodeError } from "../utils/errorDecoder"; + +try { + await contract.call(); +} catch (error) { + const decoded = decodeError(error); + console.log(decoded.name, decoded.args); +} +``` + +### Waiting for Transactions + +```javascript +const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms)); + +// Wait for transaction to be mined +await wait(5000); +``` + +## Best Practices + +### 1. Test Coverage + +- Aim for high coverage of critical paths +- Test both happy paths and error cases +- Test edge cases and boundary conditions + +### 2. Test Speed + +- Keep tests fast (use mocks where appropriate) +- Run tests in parallel when possible +- Use separate test databases + +### 3. Test Data + +- Use factories or fixtures for test data +- Clean up test data after tests +- Use unique identifiers to avoid conflicts + +### 4. Assertions + +- Use descriptive assertion messages +- Test one thing per test +- Verify both positive and negative cases + +### 5. Test Maintenance + +- Keep tests up to date with code changes +- Refactor tests when refactoring code +- Remove obsolete tests + +### 6. Documentation + +- Add comments for complex test logic +- Document test setup requirements +- Explain test scenarios + +## Troubleshooting + +### Common Issues + +**Tests Failing Intermittently:** + +- Check for race conditions +- Ensure proper cleanup between tests +- Verify test isolation + +**Contract Tests Failing:** + +- Check Anvil is running (for integration tests) +- Verify contract addresses in test setup +- Check gas limits + +**API Tests Failing:** + +- Verify MongoDB is running +- Check database connection string +- Ensure test database is clean + +**Timeout Errors:** + +- Increase test timeout: + ```javascript + jest.setTimeout(30000); // 30 seconds + ``` +- Check for hanging promises +- Verify async/await usage + +**Type Errors in Tests:** + +- Run `yarn typecheck` to see all errors +- Ensure test files are included in `tsconfig.json` +- Check import paths + +### Debugging Tests + +**Smart Contract Tests:** + +```bash +# Run with verbose output +forge test -vvv + +# Run specific test +forge test --match-test testName -vvv + +# Use console.log in tests +console.log("Value:", value); +``` + +**API Tests:** + +```bash +# Run with verbose output +yarn jest --verbose + +# Run specific test +yarn jest testName --verbose + +# Use debugger +node --inspect-brk node_modules/.bin/jest --runInBand testName +``` + +**Debugging Database Issues:** + +```javascript +// Log database operations +console.log("Issuer:", await Issuer.findById(id)); + +// Check connection +console.log("DB State:", mongoose.connection.readyState); +``` + +## Additional Resources + +- [Foundry Testing Documentation](https://book.getfoundry.sh/forge/tests) +- [Jest Documentation](https://jestjs.io/docs/getting-started) +- [Developer Guide](./DEVELOPER_GUIDE.md) - Development setup +- [Architecture Documentation](./ARCHITECTURE.md) - System architecture From db5ce64b1071494aec1f47391ffcad6bd938f4c9 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 10 Dec 2025 16:33:17 +0000 Subject: [PATCH 2/5] feat: Add documentation for agents and API Co-authored-by: hardlydiff --- AGENTS.md | 55 ++++++ API.md | 486 ++++++++++++++++++++++++++++++++++++++++++++++++ ARCHITECTURE.md | 341 +++++++++++++++++++++++++++++++++ CLAUDE.md | 55 ++++++ GEMINI.md | 55 ++++++ llms.txt | 322 ++++++++++++++++++++++++++++++++ 6 files changed, 1314 insertions(+) create mode 100644 AGENTS.md create mode 100644 API.md create mode 100644 ARCHITECTURE.md create mode 100644 CLAUDE.md create mode 100644 GEMINI.md create mode 100644 llms.txt diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..5d0ceea5 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,55 @@ +# AGENTS.md + +This file provides guidance to AI agents (OpenAI Codex, etc.) when working with this repository. + +## Context + +**Read `llms.txt` first** for complete project context, architecture decisions, and coding conventions. + +## Project Overview + +Open Cap Table Protocol (OCP) is a blockchain-based cap table management system implementing the Open Cap Table Coalition (OCF) standard. It consists of: + +- **Smart Contract Layer**: Solidity contracts using Diamond pattern (Foundry) +- **API Server**: Express.js REST API with MongoDB (Node.js/TypeScript) +- **Event Synchronization**: WebSocket listeners for blockchain event sync + +## Key Commands + +- `yarn dev` - Start development server +- `yarn test:chain` - Run smart contract tests +- `yarn test:js` - Run API tests +- `yarn deploy:local` - Deploy contracts to local Anvil +- `yarn lint` - Run linting +- `yarn typecheck` - TypeScript type checking + +## Important Notes + +- Follow patterns in `llms.txt` - it's the source of truth +- Always validate against OCF schemas before saving data +- Use contract middleware for routes interacting with contracts +- Convert UUIDs to bytes16 for contract calls +- Use scaled BigNumber for quantities/prices +- Check `docs/DIAMOND_PATTERN.md` before modifying smart contracts +- Check `docs/DATA_MODEL.md` before modifying database models + +## Architecture Constraints + +- **Diamond Pattern**: All smart contracts use Diamond pattern with facets +- **OCF Standard**: All data must validate against OCF JSON schemas +- **Multi-Chain**: Support for multiple EVM networks (Base, Arbitrum, etc.) +- **Event Sync**: WebSocket listeners automatically sync blockchain events + +## Testing Requirements + +- Write tests for all new code +- Smart contract tests in `chain/test/` using Foundry +- API tests in `src/tests/` using Jest +- Integration tests verify end-to-end workflows + +## Documentation + +- Update `llms.txt` when adding features or patterns +- Update `docs/openapi.yaml` for API changes +- Create ADRs for architectural decisions +- Keep README and developer docs current diff --git a/API.md b/API.md new file mode 100644 index 00000000..404b3e69 --- /dev/null +++ b/API.md @@ -0,0 +1,486 @@ +# API Reference + +This document provides API usage examples and reference for the Open Cap Table Protocol (OCP) API. + +## Base URL + +- **Local**: `http://localhost:8293` +- **Development**: `https://api.ocp-dev.fairmint.co` +- **Staging**: `https://api.ocp-staging.fairmint.co` +- **Production**: `https://api.ocp.fairmint.co` + +## Authentication + +Currently, the API does not require authentication for most endpoints. Future versions may implement API keys or OAuth. + +## Content Type + +All requests should use `Content-Type: application/json`. + +## Common Response Formats + +### Success Response +```json +{ + "issuer": { ... }, + "id": "uuid-here" +} +``` + +### Error Response +```json +{ + "error": "Error message here" +} +``` + +## Core Endpoints + +### Health Check + +**GET** `/health` + +Check if the API is operational. + +**Response:** +``` +OK +``` + +**Example:** +```bash +curl http://localhost:8293/health +``` + +--- + +### Create Issuer + +**POST** `/issuer/create` + +Create a new issuer (company) and deploy a cap table contract. + +**Request Body:** +```json +{ + "chain_id": 31337, + "legal_name": "Acme Corporation", + "dba": "Acme", + "formation_date": "2020-01-01", + "country_of_formation": "US", + "country_subdivision_of_formation": "DE", + "initial_shares_authorized": "1000000" +} +``` + +**Response:** +```json +{ + "issuer": { + "_id": "uuid-here", + "legal_name": "Acme Corporation", + "deployed_to": "0x...", + "chain_id": 31337, + "tx_hash": "0x...", + ... + } +} +``` + +**Example:** +```bash +curl -X POST http://localhost:8293/issuer/create \ + -H "Content-Type: application/json" \ + -d '{ + "chain_id": 31337, + "legal_name": "Acme Corporation", + "initial_shares_authorized": "1000000" + }' +``` + +**Notes:** +- `chain_id` is required (31337=Anvil, 84532=Base Sepolia, 8453=Base Mainnet) +- Contract is automatically deployed +- WebSocket listener is started automatically + +--- + +### Get Issuer + +**GET** `/issuer/id/:id` + +Get issuer information by ID. + +**Response:** +```json +{ + "issuerId": "uuid-here", + "type": "ISSUER", + "role": "admin" +} +``` + +**Example:** +```bash +curl http://localhost:8293/issuer/id/uuid-here +``` + +--- + +### Create Stakeholder + +**POST** `/stakeholder/create` + +Create a new stakeholder on-chain. + +**Request Body:** +```json +{ + "issuerId": "uuid-here", + "name": { + "legal_name": "John Doe" + }, + "stakeholder_type": "INDIVIDUAL" +} +``` + +**Response:** +```json +{ + "stakeholder": { + "_id": "uuid-here", + "name": { ... }, + ... + } +} +``` + +**Example:** +```bash +curl -X POST http://localhost:8293/stakeholder/create \ + -H "Content-Type: application/json" \ + -d '{ + "issuerId": "issuer-uuid", + "name": { "legal_name": "John Doe" }, + "stakeholder_type": "INDIVIDUAL" + }' +``` + +**Notes:** +- Requires `issuerId` to identify the cap table +- Stakeholder is created both on-chain and in database + +--- + +### Create Stock Class + +**POST** `/stock-class/create` + +Create a new stock class. + +**Request Body:** +```json +{ + "issuerId": "uuid-here", + "class_type": "COMMON", + "price_per_share": { + "amount": "1.00", + "currency": "USD" + }, + "initial_shares_authorized": "100000" +} +``` + +**Response:** +```json +{ + "stockClass": { + "_id": "uuid-here", + "class_type": "COMMON", + ... + } +} +``` + +**Example:** +```bash +curl -X POST http://localhost:8293/stock-class/create \ + -H "Content-Type: application/json" \ + -d '{ + "issuerId": "issuer-uuid", + "class_type": "COMMON", + "price_per_share": { "amount": "1.00", "currency": "USD" }, + "initial_shares_authorized": "100000" + }' +``` + +--- + +## Transaction Endpoints + +### Issue Stock + +**POST** `/transactions/issuance` + +Issue stock to a stakeholder. + +**Request Body:** +```json +{ + "issuerId": "uuid-here", + "stock_class_id": "stock-class-uuid", + "stakeholder_id": "stakeholder-uuid", + "quantity": "1000", + "share_price": { + "amount": "10.00", + "currency": "USD" + } +} +``` + +**Response:** +```json +{ + "transaction": { + "_id": "uuid-here", + "object_type": "TX_STOCK_ISSUANCE", + "quantity": "1000", + ... + } +} +``` + +**Example:** +```bash +curl -X POST http://localhost:8293/transactions/issuance \ + -H "Content-Type: application/json" \ + -d '{ + "issuerId": "issuer-uuid", + "stock_class_id": "stock-class-uuid", + "stakeholder_id": "stakeholder-uuid", + "quantity": "1000", + "share_price": { "amount": "10.00", "currency": "USD" } + }' +``` + +--- + +### Transfer Stock + +**POST** `/transactions/transfer` + +Transfer stock between stakeholders. + +**Request Body:** +```json +{ + "issuerId": "uuid-here", + "from_stakeholder_id": "stakeholder-uuid-1", + "to_stakeholder_id": "stakeholder-uuid-2", + "stock_class_id": "stock-class-uuid", + "quantity": "100", + "share_price": { + "amount": "10.00", + "currency": "USD" + } +} +``` + +**Response:** +```json +{ + "transaction": { + "_id": "uuid-here", + "object_type": "TX_STOCK_TRANSFER", + ... + } +} +``` + +--- + +### Exercise Equity Compensation + +**POST** `/transactions/exercise` + +Exercise equity compensation (options, RSUs, etc.). + +**Request Body:** +```json +{ + "issuerId": "uuid-here", + "equity_compensation_id": "equity-comp-uuid", + "quantity": "500" +} +``` + +--- + +### Cancel Stock + +**POST** `/transactions/cancellation` + +Cancel stock (repurchase, forfeiture, etc.). + +**Request Body:** +```json +{ + "issuerId": "uuid-here", + "stock_class_id": "stock-class-uuid", + "stakeholder_id": "stakeholder-uuid", + "quantity": "100" +} +``` + +--- + +## Statistics Endpoints + +### Get Cap Table Stats + +**GET** `/stats/cap-table/:issuerId` + +Get cap table statistics for an issuer. + +**Response:** +```json +{ + "total_shares": "1000000", + "issued_shares": "500000", + "outstanding_shares": "500000", + "stakeholders": 10, + "stock_classes": 2 +} +``` + +--- + +## Export Endpoints + +### Export Cap Table + +**GET** `/export/cap-table/:issuerId` + +Export cap table data in various formats. + +**Query Parameters:** +- `format` - Export format (json, csv, xlsx, ocf) + +**Example:** +```bash +curl http://localhost:8293/export/cap-table/uuid-here?format=ocf +``` + +--- + +## OCF Endpoints + +### Verify Cap Table + +**POST** `/verify-cap-table` + +Verify cap table data against OCF standard. + +**Request:** +- Multipart form data with OCF manifest file + +**Response:** +```json +{ + "valid": true, + "errors": [] +} +``` + +--- + +## Error Handling + +### Common Error Codes + +- `400` - Bad Request (missing/invalid parameters) +- `404` - Not Found (issuer/stakeholder not found) +- `500` - Internal Server Error + +### Error Response Format + +```json +{ + "error": "Error message here" +} +``` + +### Contract Errors + +When contract calls fail, errors are decoded and returned: + +```json +{ + "error": "NoStakeholder: Stakeholder not found", + "details": { + "name": "NoStakeholder", + "args": { + "stakeholder_id": "0x..." + } + } +} +``` + +## Rate Limiting + +Currently, there are no rate limits. Future versions may implement rate limiting. + +## WebSocket Events + +The API automatically starts WebSocket listeners for deployed contracts. Events are synced to the database automatically. + +**Event Types:** +- `StockIssued` +- `StockTransferred` +- `StakeholderCreated` +- `StockClassCreated` +- And more... + +## Complete API Specification + +For the complete OpenAPI specification, see `docs/openapi.yaml`. + +## Example Workflows + +### Complete Cap Table Setup + +```bash +# 1. Create issuer +ISSUER_ID=$(curl -X POST http://localhost:8293/issuer/create \ + -H "Content-Type: application/json" \ + -d '{"chain_id": 31337, "legal_name": "Acme Corp", "initial_shares_authorized": "1000000"}' \ + | jq -r '.issuer._id') + +# 2. Create stakeholder +STAKEHOLDER_ID=$(curl -X POST http://localhost:8293/stakeholder/create \ + -H "Content-Type: application/json" \ + -d "{\"issuerId\": \"$ISSUER_ID\", \"name\": {\"legal_name\": \"John Doe\"}, \"stakeholder_type\": \"INDIVIDUAL\"}" \ + | jq -r '.stakeholder._id') + +# 3. Create stock class +STOCK_CLASS_ID=$(curl -X POST http://localhost:8293/stock-class/create \ + -H "Content-Type: application/json" \ + -d "{\"issuerId\": \"$ISSUER_ID\", \"class_type\": \"COMMON\", \"price_per_share\": {\"amount\": \"1.00\", \"currency\": \"USD\"}, \"initial_shares_authorized\": \"100000\"}" \ + | jq -r '.stockClass._id') + +# 4. Issue stock +curl -X POST http://localhost:8293/transactions/issuance \ + -H "Content-Type: application/json" \ + -d "{\"issuerId\": \"$ISSUER_ID\", \"stock_class_id\": \"$STOCK_CLASS_ID\", \"stakeholder_id\": \"$STAKEHOLDER_ID\", \"quantity\": \"1000\", \"share_price\": {\"amount\": \"10.00\", \"currency\": \"USD\"}}" +``` + +## Testing + +See `TESTING.md` for testing guidelines and examples. + +## Related Documentation + +- [Developer Guide](DEVELOPER_GUIDE.md) - Development workflow +- [Deployment Guide](DEPLOYMENT.md) - Deployment procedures +- [OpenAPI Specification](docs/openapi.yaml) - Complete API spec +- [Data Model](docs/DATA_MODEL.md) - Database schema diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 00000000..b0eb0512 --- /dev/null +++ b/ARCHITECTURE.md @@ -0,0 +1,341 @@ +# Architecture Overview + +This document consolidates architecture information for the Open Cap Table Protocol (OCP). + +## System Architecture + +OCP follows a **dual-layer architecture**: + +``` +┌─────────────────────────────────────────────────────────────┐ +│ CLIENT APPLICATIONS │ +│ (Fairmint, External Integrations, etc.) │ +└──────────────────────┬──────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ API SERVER LAYER │ +│ Express.js REST API + MongoDB + WebSocket Event Listeners │ +│ │ +│ • Route Handlers (src/routes/) │ +│ • Controllers (src/controllers/) │ +│ • Database Models (src/db/objects/) │ +│ • Event Synchronization (src/utils/websocket.ts) │ +└──────────────────────┬──────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ BLOCKCHAIN LAYER │ +│ Diamond Pattern Smart Contracts (EVM) │ +│ │ +│ • CapTable (Diamond Contract) │ +│ • Facets (Issuer, Stakeholder, StockClass, etc.) │ +│ • Factory (Deployment) │ +└─────────────────────────────────────────────────────────────┘ +``` + +## Smart Contract Architecture + +### Diamond Pattern + +OCP uses the **Diamond pattern** for smart contracts, providing: + +- **Modularity**: Separate facets for different functionality +- **Upgradability**: Add/remove/replace facets without data migration +- **Unlimited Size**: Bypass 24KB contract size limit +- **Shared Storage**: Single storage structure across all facets + +**Core Components:** + +1. **Diamond Contract (CapTable)** + - Main entry point for all function calls + - Delegates to appropriate facets via function selectors + - Created by `CapTableFactory` for each issuer + +2. **Facets** (Implementation Contracts) + - `IssuerFacet` - Issuer data management + - `StakeholderFacet` - Stakeholder operations + - `StockClassFacet` - Stock class definitions + - `StockFacet` - Stock issuance and transfers + - `StockPlanFacet` - Equity compensation plans + - `ConvertiblesFacet` - Convertible securities + - `EquityCompensationFacet` - Equity compensation + - `WarrantFacet` - Warrant management + - `StakeholderNFTFacet` - NFT representation of positions + +3. **Storage Library** + - Shared storage structure in `Storage.sol` + - Accessed via `StorageLib.get()` from all facets + - Contains all cap table data in a single location + +See `docs/DIAMOND_PATTERN.md` for detailed information. + +### Factory Pattern + +- `CapTableFactory` creates new cap table instances +- Uses reference diamond for facet addresses +- Each issuer gets a unique CapTable contract + +## API Server Architecture + +### Express.js Application + +**Entry Point**: `src/app.js` + +**Middleware Stack:** +1. CORS - Cross-origin resource sharing +2. Body parsing (JSON, URL-encoded) +3. Chain middleware - Validates chain ID for issuer creation +4. Contract middleware - Caches contract instances per issuer + +**Route Organization:** +- `/issuer` - Issuer management +- `/stakeholder` - Stakeholder operations +- `/stock-class` - Stock class management +- `/stock-plan` - Equity plan management +- `/transactions/*` - Transaction processing +- `/stats/*` - Analytics and statistics +- `/export/*` - Data export +- `/ocf/*` - OCF format operations + +### Database Architecture + +**MongoDB Collections:** + +- `issuers` - Company/issuer data +- `stakeholders` - Individual/entity stakeholders +- `stockclasses` - Stock class definitions +- `stockplans` - Equity compensation plans +- `stocklegends` - Stock legend templates +- `valuations` - Company valuations +- `vestingterms` - Vesting term definitions +- `transactions/*` - Transaction records (issuance, transfer, exercise, etc.) +- `fairmint` - Fairmint integration tracking + +**Data Model:** +- Follows OCF standard structure +- UUIDs as primary keys +- References between entities +- Timestamps for audit trail + +See `docs/DATA_MODEL.md` for complete schema. + +### Event Synchronization + +**WebSocket Listeners:** +- Monitor blockchain events for all deployed contracts +- Group contracts by chain ID for efficient connection management +- Automatically sync events to MongoDB +- Handle reconnections and error recovery + +**Event Flow:** +``` +Blockchain Event → WebSocket Listener → Event Handler → Database Update +``` + +## Multi-Chain Architecture + +### Chain Configuration + +Supported chains defined in `src/utils/chains.js`: + +```javascript +SUPPORTED_CHAINS = { + 8453: { name: "Base Mainnet", rpcUrl, wsUrl }, + 84532: { name: "Base Sepolia", rpcUrl, wsUrl }, + 31337: { name: "Anvil", rpcUrl, wsUrl }, +} +``` + +### Chain-Agnostic Design + +- Contract instances cached per `chainId + issuerId` +- RPC providers created per chain +- WebSocket listeners grouped by chain +- Chain ID required for issuer creation + +## Data Flow Patterns + +### Creating an Issuer + +``` +1. API Request (POST /issuer/create) + ↓ +2. Validate OCF schema + ↓ +3. Deploy CapTable contract (chain) + ↓ +4. Save issuer to MongoDB (web) + ↓ +5. Start WebSocket listener for contract + ↓ +6. Return issuer data +``` + +### Issuing Stock + +``` +1. API Request (POST /transactions/issuance) + ↓ +2. Validate input + ↓ +3. Call contract.issueStock() (chain) + ↓ +4. Transaction mined + ↓ +5. WebSocket listener catches StockIssued event + ↓ +6. Save transaction to MongoDB (web) + ↓ +7. Return transaction data +``` + +### Event Synchronization + +``` +1. Blockchain event emitted + ↓ +2. WebSocket listener receives event + ↓ +3. Parse event data + ↓ +4. Update MongoDB document + ↓ +5. Log synchronization +``` + +## Security Architecture + +### Access Control + +- **On-Chain**: Role-based access control (RBAC) in smart contracts +- **Off-Chain**: API authentication (if implemented) +- **Admin Roles**: Contract admin, issuer admin, etc. + +### Data Validation + +- **OCF Schema Validation**: All data validated against OCF JSON schemas +- **Input Sanitization**: UUID validation, decimal scaling +- **Error Handling**: Comprehensive error decoding and reporting + +### Contract Security + +- **Diamond Pattern**: Upgradeable but controlled +- **Access Control**: Role-based permissions +- **Input Validation**: Revert on invalid inputs +- **Gas Optimization**: Efficient storage patterns + +## Integration Points + +### Fairmint Integration + +- Bidirectional data reflection between OCP and Fairmint +- Webhook-based synchronization +- Portal/Issuer mapping +- See `docs/DATA_REFLECTION.md` for details + +### OCF Standard + +- Full OCF schema compliance +- Import/export OCF format files +- Validation against OCF schemas +- See `docs/OCX_EXPORT.md` for export details + +## Performance Considerations + +### Caching + +- **Contract Instances**: Cached per `chainId + issuerId` +- **Preprocessor Cache**: Cached processed data +- **TTL Configuration**: Configurable cache expiration + +### Database + +- Indexed fields for fast queries +- Efficient aggregation pipelines +- Connection pooling + +### Blockchain + +- Batch operations where possible +- Gas optimization in contracts +- Efficient event filtering + +## Scalability + +### Horizontal Scaling + +- Stateless API server (can scale horizontally) +- MongoDB replica sets +- Load-balanced RPC endpoints + +### Vertical Scaling + +- Database query optimization +- Contract gas optimization +- Efficient event processing + +## Deployment Architecture + +### Environments + +- **Local**: Anvil + Local MongoDB +- **Testnet**: Base Sepolia + Test MongoDB +- **Production**: Base Mainnet + Production MongoDB + +### Deployment Flow + +``` +1. Deploy Smart Contracts (Foundry) + ↓ +2. Update Environment Variables + ↓ +3. Deploy API Server + ↓ +4. Start WebSocket Listeners + ↓ +5. Sync Historical Events (if needed) +``` + +See `DEPLOYMENT.md` for detailed procedures. + +## Monitoring & Observability + +### Logging + +- Structured logging with emoji prefixes +- Error tracking with Sentry +- Transaction hash logging + +### Health Checks + +- `/health` endpoint for API status +- Database connection monitoring +- WebSocket connection status + +### Metrics + +- Transaction counts +- Event processing rates +- Error rates +- Response times + +## Future Architecture Considerations + +### Potential Enhancements + +- GraphQL API layer +- Event sourcing for audit trail +- Multi-signature support +- Advanced analytics +- Real-time notifications +- API rate limiting +- Authentication/authorization layer + +## Related Documentation + +- [Diamond Pattern](docs/DIAMOND_PATTERN.md) - Smart contract architecture +- [Data Model](docs/DATA_MODEL.md) - Database schema +- [Configuration](CONFIG.md) - Environment setup +- [Deployment](DEPLOYMENT.md) - Deployment procedures +- [Developer Guide](DEVELOPER_GUIDE.md) - Development workflow diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..f569bb73 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,55 @@ +# CLAUDE.md + +This file provides guidance to Claude Code when working with this repository. + +## Context + +**Read `llms.txt` first** for complete project context, architecture decisions, and coding conventions. + +## Project Overview + +Open Cap Table Protocol (OCP) is a blockchain-based cap table management system implementing the Open Cap Table Coalition (OCF) standard. It consists of: + +- **Smart Contract Layer**: Solidity contracts using Diamond pattern (Foundry) +- **API Server**: Express.js REST API with MongoDB (Node.js/TypeScript) +- **Event Synchronization**: WebSocket listeners for blockchain event sync + +## Key Commands + +- `yarn dev` - Start development server +- `yarn test:chain` - Run smart contract tests +- `yarn test:js` - Run API tests +- `yarn deploy:local` - Deploy contracts to local Anvil +- `yarn lint` - Run linting +- `yarn typecheck` - TypeScript type checking + +## Important Notes + +- Follow patterns in `llms.txt` - it's the source of truth +- Always validate against OCF schemas before saving data +- Use contract middleware for routes interacting with contracts +- Convert UUIDs to bytes16 for contract calls +- Use scaled BigNumber for quantities/prices +- Check `docs/DIAMOND_PATTERN.md` before modifying smart contracts +- Check `docs/DATA_MODEL.md` before modifying database models + +## Architecture Constraints + +- **Diamond Pattern**: All smart contracts use Diamond pattern with facets +- **OCF Standard**: All data must validate against OCF JSON schemas +- **Multi-Chain**: Support for multiple EVM networks (Base, Arbitrum, etc.) +- **Event Sync**: WebSocket listeners automatically sync blockchain events + +## Testing Requirements + +- Write tests for all new code +- Smart contract tests in `chain/test/` using Foundry +- API tests in `src/tests/` using Jest +- Integration tests verify end-to-end workflows + +## Documentation + +- Update `llms.txt` when adding features or patterns +- Update `docs/openapi.yaml` for API changes +- Create ADRs for architectural decisions +- Keep README and developer docs current diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 00000000..3b4ed860 --- /dev/null +++ b/GEMINI.md @@ -0,0 +1,55 @@ +# GEMINI.md + +This file provides guidance to Gemini CLI when working with this repository. + +## Context + +**Read `llms.txt` first** for complete project context, architecture decisions, and coding conventions. + +## Project Overview + +Open Cap Table Protocol (OCP) is a blockchain-based cap table management system implementing the Open Cap Table Coalition (OCF) standard. It consists of: + +- **Smart Contract Layer**: Solidity contracts using Diamond pattern (Foundry) +- **API Server**: Express.js REST API with MongoDB (Node.js/TypeScript) +- **Event Synchronization**: WebSocket listeners for blockchain event sync + +## Key Commands + +- `yarn dev` - Start development server +- `yarn test:chain` - Run smart contract tests +- `yarn test:js` - Run API tests +- `yarn deploy:local` - Deploy contracts to local Anvil +- `yarn lint` - Run linting +- `yarn typecheck` - TypeScript type checking + +## Important Notes + +- Follow patterns in `llms.txt` - it's the source of truth +- Always validate against OCF schemas before saving data +- Use contract middleware for routes interacting with contracts +- Convert UUIDs to bytes16 for contract calls +- Use scaled BigNumber for quantities/prices +- Check `docs/DIAMOND_PATTERN.md` before modifying smart contracts +- Check `docs/DATA_MODEL.md` before modifying database models + +## Architecture Constraints + +- **Diamond Pattern**: All smart contracts use Diamond pattern with facets +- **OCF Standard**: All data must validate against OCF JSON schemas +- **Multi-Chain**: Support for multiple EVM networks (Base, Arbitrum, etc.) +- **Event Sync**: WebSocket listeners automatically sync blockchain events + +## Testing Requirements + +- Write tests for all new code +- Smart contract tests in `chain/test/` using Foundry +- API tests in `src/tests/` using Jest +- Integration tests verify end-to-end workflows + +## Documentation + +- Update `llms.txt` when adding features or patterns +- Update `docs/openapi.yaml` for API changes +- Create ADRs for architectural decisions +- Keep README and developer docs current diff --git a/llms.txt b/llms.txt new file mode 100644 index 00000000..5519a77d --- /dev/null +++ b/llms.txt @@ -0,0 +1,322 @@ +# Open Cap Table Protocol (OCP) + +> A comprehensive solution for managing capitalization tables on the blockchain. Implements the Open Cap Table Coalition (OCF) standard, providing secure, transparent, and standardized equity ownership management across multiple EVM-compatible chains. + +## Key Technical Details + +- **Framework**: Express.js (Node.js) + TypeScript +- **Database**: MongoDB (Mongoose ODM) +- **Blockchain**: Solidity (Foundry) with Diamond pattern architecture +- **Runtime**: Node.js v22+ with ES modules +- **Package Manager**: Yarn 4 +- **Testing**: Jest (API) + Forge (Smart Contracts) +- **Validation**: OCF JSON Schema validation (AJV) + +## Architecture Patterns + +### Dual-Layer Architecture +- **Smart Contract Layer (Chain)**: Diamond pattern with facets for on-chain cap table data +- **API Server Layer (Web)**: Express.js REST API with MongoDB for off-chain data +- **Event Synchronization**: WebSocket listeners sync blockchain events to MongoDB + +### Diamond Pattern +- **Diamond Contract**: Main entry point delegating to facets +- **Facets**: Modular implementation contracts (Issuer, Stakeholder, StockClass, StockPlan, etc.) +- **Shared Storage**: Single storage structure accessible by all facets +- See `docs/DIAMOND_PATTERN.md` for details + +### Multi-Chain Support +- Chain-agnostic design supporting multiple EVM networks +- Chain configuration in `src/utils/chains.js` +- Contract instances cached per chain+issuer combination +- WebSocket listeners grouped by chain ID + +### Data Flow +1. API Request → Express routes → Controllers +2. Controllers → Database (MongoDB) + Chain operations (Smart contracts) +3. Chain Events → WebSocket listeners → Database updates +4. Response → OCF-compliant JSON + +## File Structure Overview + +``` +open-captable-protocol/ +├── chain/ # Smart contracts (Solidity/Foundry) +│ ├── src/ +│ │ ├── facets/ # Diamond pattern facets +│ │ ├── libraries/ # Shared libraries (Storage, AccessControl, etc.) +│ │ ├── core/ # Core contracts (CapTable, Factory) +│ │ └── interfaces/ # Contract interfaces +│ ├── test/ # Foundry tests +│ └── script/ # Deployment scripts +│ +├── src/ # API server (Node.js/TypeScript) +│ ├── app.js # Express app entry point +│ ├── routes/ # API route handlers +│ │ ├── issuer.js +│ │ ├── stakeholder/ +│ │ ├── stockClass.js +│ │ ├── transactions/ +│ │ └── ... +│ ├── controllers/ # Business logic controllers +│ │ ├── issuerController.js +│ │ ├── stakeholderController.js +│ │ └── ... +│ ├── db/ # MongoDB models and operations +│ │ ├── objects/ # Mongoose models +│ │ ├── operations/ # CRUD operations (create, read, update, delete) +│ │ └── config/ # Database configuration +│ ├── chain-operations/ # Blockchain interaction utilities +│ │ ├── deployCapTable.js +│ │ └── getContractInstances.js +│ ├── utils/ # Utility functions +│ │ ├── chains.js # Chain configuration +│ │ ├── convertUUID.js # UUID ↔ bytes16 conversion +│ │ ├── websocket.ts # Event listener management +│ │ └── ... +│ ├── fairmint/ # Fairmint integration +│ ├── tests/ # Test files +│ └── examples/ # Example scripts +│ +├── docs/ # Documentation +│ ├── DATA_MODEL.md # Data model documentation +│ ├── DIAMOND_PATTERN.md # Diamond pattern explanation +│ ├── DATA_REFLECTION.md # Fairmint integration +│ └── openapi.yaml # OpenAPI specification +│ +└── scripts/ # Deployment and utility scripts +``` + +## ADR Quick Reference + +| ADR | Decision | What This Means for Development | +|-----|----------|--------------------------------| +| N/A | Diamond Pattern | **All smart contracts use Diamond pattern**. New facets must follow existing facet structure. | +| N/A | OCF Standard | **All data must validate against OCF schemas**. Use `validateInputAgainstOCF()` before saving. | +| N/A | Multi-Chain | **Always pass `chain_id` for issuer creation**. Use `getChainConfig()` for chain-specific operations. | +| N/A | Event Sync | **WebSocket listeners auto-sync events**. Don't manually sync - listeners handle it. | + +## Code Patterns (Do / Don't) + +### UUID Conversion +```javascript +// ✅ DO: Convert UUIDs to bytes16 for contract calls +import { convertUUIDToBytes16 } from "../utils/convertUUID.js"; +const bytes16 = convertUUIDToBytes16(uuid); + +// ❌ DON'T: Pass UUID strings directly to contracts +await contract.createStakeholder(uuid); // Wrong! +``` + +### Fixed-Point Decimals +```javascript +// ✅ DO: Use scaled BigNumber for contract calls +import { toScaledBigNumber } from "../utils/convertToFixedPointDecimals.js"; +const quantity = toScaledBigNumber("1000.50"); // Returns BigNumber + +// ❌ DON'T: Pass decimal strings directly +await contract.issueStock({ quantity: "1000.50" }); // Wrong! +``` + +### Contract Instance Caching +```javascript +// ✅ DO: Use contract middleware or cache +// Middleware automatically caches: req.contract +// Or use: contractCache[`${chainId}-${issuerId}`] + +// ❌ DON'T: Create new contract instances for every call +const contract = await getContractInstance(address, chainId); // Inefficient if called repeatedly +``` + +### OCF Validation +```javascript +// ✅ DO: Validate against OCF schema before saving +import validateInputAgainstOCF from "../utils/validateInputAgainstSchema.js"; +await validateInputAgainstOCF(data, schema); + +// ❌ DON'T: Save data without validation +await createIssuer(data); // Missing validation! +``` + +### Error Handling +```javascript +// ✅ DO: Use error decoder for contract errors +import { decodeError } from "../utils/errorDecoder.js"; +try { + await contract.issueStock(params); +} catch (error) { + const decoded = decodeError(error); + console.log(decoded.name, decoded.args); +} + +// ❌ DON'T: Log raw errors without decoding +catch (error) { + console.log(error); // Not helpful! +} +``` + +### Chain Configuration +```javascript +// ✅ DO: Use getChainConfig for chain-specific operations +import { getChainConfig } from "../utils/chains.js"; +const config = getChainConfig(chainId); +const provider = new ethers.JsonRpcProvider(config.rpcUrl); + +// ❌ DON'T: Hardcode RPC URLs +const provider = new ethers.JsonRpcProvider("http://localhost:8545"); // Wrong! +``` + +### Database Operations +```javascript +// ✅ DO: Use atomic save operations +import { save } from "../db/operations/atomic.ts"; +const issuer = await save(new Issuer(issuerData)); + +// ❌ DON'T: Use model.save() directly (not atomic) +const issuer = new Issuer(issuerData); +await issuer.save(); // Not atomic! +``` + +## API Endpoints + +### Core Entities + +| Method | Path | Purpose | Middleware | +|--------|------|---------|------------| +| POST | `/issuer/create` | Create new issuer and deploy cap table | `chainMiddleware` | +| GET | `/issuer/id/:id` | Get issuer by ID | None | +| POST | `/stakeholder/create` | Create stakeholder on-chain | `contractMiddleware` | +| POST | `/stock-class/create` | Create stock class | `contractMiddleware` | +| POST | `/stock-plan/create` | Create stock plan | `contractMiddleware` | + +### Transactions + +| Method | Path | Purpose | Middleware | +|--------|------|---------|------------| +| POST | `/transactions/issuance` | Issue stock | `contractMiddleware` | +| POST | `/transactions/transfer` | Transfer stock | `contractMiddleware` | +| POST | `/transactions/exercise` | Exercise equity compensation | `contractMiddleware` | +| POST | `/transactions/cancellation` | Cancel stock | `contractMiddleware` | + +### Utilities + +| Method | Path | Purpose | +|--------|------|---------| +| GET | `/health` | Health check | +| GET | `/` | API welcome message | +| POST | `/verify-cap-table` | Verify cap table data | +| GET | `/stats/*` | Cap table statistics | +| GET | `/export/*` | Export cap table data | +| POST | `/ocf/*` | OCF format operations | + +See `docs/openapi.yaml` for complete API specification. + +## Key Utilities + +### UUID Conversion +- `convertUUIDToBytes16(uuid)` - Convert UUID string to bytes16 for contracts +- `convertBytes16ToUUID(bytes16)` - Convert bytes16 back to UUID + +### Fixed-Point Decimals +- `toScaledBigNumber(value)` - Convert decimal string to scaled BigNumber +- Used for all contract calls involving quantities/prices + +### Error Decoding +- `decodeError(error)` - Decode contract revert errors to readable format +- Returns `{ name, args, message }` structure + +### Chain Configuration +- `getChainConfig(chainId)` - Get RPC/WebSocket URLs for chain +- `SUPPORTED_CHAINS` - Map of supported chain IDs + +### Contract Operations +- `deployCapTable(issuerIdBytes16, shares, chainId)` - Deploy new cap table +- `getContractInstance(address, chainId)` - Get contract instance (cached) + +## Testing + +### Smart Contract Tests +- Location: `chain/test/` +- Framework: Foundry (Forge) +- Run: `yarn test:chain` or `cd chain && forge test` +- Base: `DiamondTestBase` provides common setup + +### API Tests +- Location: `src/tests/` +- Framework: Jest +- Run: `yarn test:js` +- Integration: `yarn test-js-integration` +- Uses separate test database: `DATABASE_OVERRIDE=jest-integration` + +See `TESTING.md` for detailed testing guidelines. + +## Environment Configuration + +### Required Variables +- `DATABASE_URL` - MongoDB connection string +- `RPC_URL` - Blockchain RPC endpoint +- `CHAIN_ID` - Target chain ID (31337=Anvil, 84532=Base Sepolia, 8453=Base Mainnet) +- `PRIVATE_KEY` - Deployer private key +- `PORT` - Server port (default: 8293) + +### Environment Files +- `.env.local` - Local development (Anvil) +- `.env.dev` - Testnet deployment +- `.env.prod` - Production deployment + +See `CONFIG.md` for complete configuration details. + +## Development Workflow + +1. **Start services**: Anvil, MongoDB (Docker), API server +2. **Deploy contracts**: `yarn deploy:local` +3. **Update `.env.local`** with contract addresses +4. **Run tests**: `yarn test:chain && yarn test:js` +5. **Create PR**: Follow conventional commits + +See `DEVELOPER_GUIDE.md` for complete workflow. + +## Documentation Links + +- [README](README.md) - Project overview and quick start +- [Developer Guide](DEVELOPER_GUIDE.md) - Complete development guide +- [Deployment Guide](DEPLOYMENT.md) - Deployment procedures +- [Testing Guide](TESTING.md) - Testing practices +- [Configuration Guide](CONFIG.md) - Environment configuration +- [Data Model](docs/DATA_MODEL.md) - Database schema +- [Diamond Pattern](docs/DIAMOND_PATTERN.md) - Smart contract architecture +- [OpenAPI Spec](docs/openapi.yaml) - API specification +- [Contributing](CONTRIBUTING.md) - Contribution guidelines + +## Important Notes + +- **Always validate against OCF schemas** before saving data +- **Use contract middleware** for routes that interact with contracts +- **WebSocket listeners auto-sync** blockchain events - don't manually sync +- **Contract instances are cached** - use middleware or cache directly +- **Multi-chain support** - always pass `chain_id` and use `getChainConfig()` +- **UUIDs must be converted** to bytes16 for all contract calls +- **Quantities/prices must be scaled** using `toScaledBigNumber()` +- **Tests use separate database** - `DATABASE_OVERRIDE=jest-integration` + +## Common Tasks + +### Adding a New API Endpoint +1. Create route handler in `src/routes/` +2. Create controller in `src/controllers/` +3. Add route to `src/app.js` with appropriate middleware +4. Update `docs/openapi.yaml` +5. Add tests in `src/tests/` + +### Adding a New Smart Contract Facet +1. Create facet contract in `chain/src/facets/` +2. Define storage in `chain/src/libraries/Storage.sol` +3. Add deployment script in `chain/script/` +4. Update factory if needed +5. Add tests in `chain/test/` + +### Adding Support for a New Chain +1. Add chain config in `src/utils/chains.js` +2. Add RPC URL to environment files +3. Deploy contracts to new chain +4. Update documentation From a850c2210175c32c5148f0abb0c73479b017932d Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 10 Dec 2025 16:37:08 +0000 Subject: [PATCH 3/5] Refactor AI agent docs and llms.txt for clarity Co-authored-by: hardlydiff --- AGENTS.md | 50 ++----------------- CLAUDE.md | 50 ++----------------- GEMINI.md | 50 ++----------------- llms.txt | 147 +++++++++++++++--------------------------------------- 4 files changed, 52 insertions(+), 245 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 5d0ceea5..5be36b22 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,50 +6,8 @@ This file provides guidance to AI agents (OpenAI Codex, etc.) when working with **Read `llms.txt` first** for complete project context, architecture decisions, and coding conventions. -## Project Overview +The `llms.txt` file references: +- `README.md` - Project overview and quick start +- `DEVELOPER_GUIDE.md` - Complete development workflow and setup -Open Cap Table Protocol (OCP) is a blockchain-based cap table management system implementing the Open Cap Table Coalition (OCF) standard. It consists of: - -- **Smart Contract Layer**: Solidity contracts using Diamond pattern (Foundry) -- **API Server**: Express.js REST API with MongoDB (Node.js/TypeScript) -- **Event Synchronization**: WebSocket listeners for blockchain event sync - -## Key Commands - -- `yarn dev` - Start development server -- `yarn test:chain` - Run smart contract tests -- `yarn test:js` - Run API tests -- `yarn deploy:local` - Deploy contracts to local Anvil -- `yarn lint` - Run linting -- `yarn typecheck` - TypeScript type checking - -## Important Notes - -- Follow patterns in `llms.txt` - it's the source of truth -- Always validate against OCF schemas before saving data -- Use contract middleware for routes interacting with contracts -- Convert UUIDs to bytes16 for contract calls -- Use scaled BigNumber for quantities/prices -- Check `docs/DIAMOND_PATTERN.md` before modifying smart contracts -- Check `docs/DATA_MODEL.md` before modifying database models - -## Architecture Constraints - -- **Diamond Pattern**: All smart contracts use Diamond pattern with facets -- **OCF Standard**: All data must validate against OCF JSON schemas -- **Multi-Chain**: Support for multiple EVM networks (Base, Arbitrum, etc.) -- **Event Sync**: WebSocket listeners automatically sync blockchain events - -## Testing Requirements - -- Write tests for all new code -- Smart contract tests in `chain/test/` using Foundry -- API tests in `src/tests/` using Jest -- Integration tests verify end-to-end workflows - -## Documentation - -- Update `llms.txt` when adding features or patterns -- Update `docs/openapi.yaml` for API changes -- Create ADRs for architectural decisions -- Keep README and developer docs current +Read those files for detailed information. The `llms.txt` file provides a concise summary optimized for AI assistance. diff --git a/CLAUDE.md b/CLAUDE.md index f569bb73..430e9f1d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,50 +6,8 @@ This file provides guidance to Claude Code when working with this repository. **Read `llms.txt` first** for complete project context, architecture decisions, and coding conventions. -## Project Overview +The `llms.txt` file references: +- `README.md` - Project overview and quick start +- `DEVELOPER_GUIDE.md` - Complete development workflow and setup -Open Cap Table Protocol (OCP) is a blockchain-based cap table management system implementing the Open Cap Table Coalition (OCF) standard. It consists of: - -- **Smart Contract Layer**: Solidity contracts using Diamond pattern (Foundry) -- **API Server**: Express.js REST API with MongoDB (Node.js/TypeScript) -- **Event Synchronization**: WebSocket listeners for blockchain event sync - -## Key Commands - -- `yarn dev` - Start development server -- `yarn test:chain` - Run smart contract tests -- `yarn test:js` - Run API tests -- `yarn deploy:local` - Deploy contracts to local Anvil -- `yarn lint` - Run linting -- `yarn typecheck` - TypeScript type checking - -## Important Notes - -- Follow patterns in `llms.txt` - it's the source of truth -- Always validate against OCF schemas before saving data -- Use contract middleware for routes interacting with contracts -- Convert UUIDs to bytes16 for contract calls -- Use scaled BigNumber for quantities/prices -- Check `docs/DIAMOND_PATTERN.md` before modifying smart contracts -- Check `docs/DATA_MODEL.md` before modifying database models - -## Architecture Constraints - -- **Diamond Pattern**: All smart contracts use Diamond pattern with facets -- **OCF Standard**: All data must validate against OCF JSON schemas -- **Multi-Chain**: Support for multiple EVM networks (Base, Arbitrum, etc.) -- **Event Sync**: WebSocket listeners automatically sync blockchain events - -## Testing Requirements - -- Write tests for all new code -- Smart contract tests in `chain/test/` using Foundry -- API tests in `src/tests/` using Jest -- Integration tests verify end-to-end workflows - -## Documentation - -- Update `llms.txt` when adding features or patterns -- Update `docs/openapi.yaml` for API changes -- Create ADRs for architectural decisions -- Keep README and developer docs current +Read those files for detailed information. The `llms.txt` file provides a concise summary optimized for AI assistance. diff --git a/GEMINI.md b/GEMINI.md index 3b4ed860..28d6bcc7 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -6,50 +6,8 @@ This file provides guidance to Gemini CLI when working with this repository. **Read `llms.txt` first** for complete project context, architecture decisions, and coding conventions. -## Project Overview +The `llms.txt` file references: +- `README.md` - Project overview and quick start +- `DEVELOPER_GUIDE.md` - Complete development workflow and setup -Open Cap Table Protocol (OCP) is a blockchain-based cap table management system implementing the Open Cap Table Coalition (OCF) standard. It consists of: - -- **Smart Contract Layer**: Solidity contracts using Diamond pattern (Foundry) -- **API Server**: Express.js REST API with MongoDB (Node.js/TypeScript) -- **Event Synchronization**: WebSocket listeners for blockchain event sync - -## Key Commands - -- `yarn dev` - Start development server -- `yarn test:chain` - Run smart contract tests -- `yarn test:js` - Run API tests -- `yarn deploy:local` - Deploy contracts to local Anvil -- `yarn lint` - Run linting -- `yarn typecheck` - TypeScript type checking - -## Important Notes - -- Follow patterns in `llms.txt` - it's the source of truth -- Always validate against OCF schemas before saving data -- Use contract middleware for routes interacting with contracts -- Convert UUIDs to bytes16 for contract calls -- Use scaled BigNumber for quantities/prices -- Check `docs/DIAMOND_PATTERN.md` before modifying smart contracts -- Check `docs/DATA_MODEL.md` before modifying database models - -## Architecture Constraints - -- **Diamond Pattern**: All smart contracts use Diamond pattern with facets -- **OCF Standard**: All data must validate against OCF JSON schemas -- **Multi-Chain**: Support for multiple EVM networks (Base, Arbitrum, etc.) -- **Event Sync**: WebSocket listeners automatically sync blockchain events - -## Testing Requirements - -- Write tests for all new code -- Smart contract tests in `chain/test/` using Foundry -- API tests in `src/tests/` using Jest -- Integration tests verify end-to-end workflows - -## Documentation - -- Update `llms.txt` when adding features or patterns -- Update `docs/openapi.yaml` for API changes -- Create ADRs for architectural decisions -- Keep README and developer docs current +Read those files for detailed information. The `llms.txt` file provides a concise summary optimized for AI assistance. diff --git a/llms.txt b/llms.txt index 5519a77d..532f4034 100644 --- a/llms.txt +++ b/llms.txt @@ -2,6 +2,9 @@ > A comprehensive solution for managing capitalization tables on the blockchain. Implements the Open Cap Table Coalition (OCF) standard, providing secure, transparent, and standardized equity ownership management across multiple EVM-compatible chains. +**For project overview, setup, and usage, see [README.md](README.md).** +**For development workflow, testing, and code standards, see [DEVELOPER_GUIDE.md](DEVELOPER_GUIDE.md).** + ## Key Technical Details - **Framework**: Express.js (Node.js) + TypeScript @@ -39,53 +42,16 @@ ## File Structure Overview -``` -open-captable-protocol/ -├── chain/ # Smart contracts (Solidity/Foundry) -│ ├── src/ -│ │ ├── facets/ # Diamond pattern facets -│ │ ├── libraries/ # Shared libraries (Storage, AccessControl, etc.) -│ │ ├── core/ # Core contracts (CapTable, Factory) -│ │ └── interfaces/ # Contract interfaces -│ ├── test/ # Foundry tests -│ └── script/ # Deployment scripts -│ -├── src/ # API server (Node.js/TypeScript) -│ ├── app.js # Express app entry point -│ ├── routes/ # API route handlers -│ │ ├── issuer.js -│ │ ├── stakeholder/ -│ │ ├── stockClass.js -│ │ ├── transactions/ -│ │ └── ... -│ ├── controllers/ # Business logic controllers -│ │ ├── issuerController.js -│ │ ├── stakeholderController.js -│ │ └── ... -│ ├── db/ # MongoDB models and operations -│ │ ├── objects/ # Mongoose models -│ │ ├── operations/ # CRUD operations (create, read, update, delete) -│ │ └── config/ # Database configuration -│ ├── chain-operations/ # Blockchain interaction utilities -│ │ ├── deployCapTable.js -│ │ └── getContractInstances.js -│ ├── utils/ # Utility functions -│ │ ├── chains.js # Chain configuration -│ │ ├── convertUUID.js # UUID ↔ bytes16 conversion -│ │ ├── websocket.ts # Event listener management -│ │ └── ... -│ ├── fairmint/ # Fairmint integration -│ ├── tests/ # Test files -│ └── examples/ # Example scripts -│ -├── docs/ # Documentation -│ ├── DATA_MODEL.md # Data model documentation -│ ├── DIAMOND_PATTERN.md # Diamond pattern explanation -│ ├── DATA_REFLECTION.md # Fairmint integration -│ └── openapi.yaml # OpenAPI specification -│ -└── scripts/ # Deployment and utility scripts -``` +See [README.md](README.md) for complete project structure. Key directories: + +- `chain/` - Smart contracts (Diamond pattern with facets) +- `src/` - API server (Express.js + MongoDB) + - `routes/` - API route handlers + - `controllers/` - Business logic + - `db/` - MongoDB models and operations + - `chain-operations/` - Blockchain interaction utilities + - `utils/` - Utility functions +- `docs/` - Documentation (DATA_MODEL.md, DIAMOND_PATTERN.md, etc.) ## ADR Quick Reference @@ -235,58 +201,39 @@ See `docs/openapi.yaml` for complete API specification. ## Testing -### Smart Contract Tests -- Location: `chain/test/` -- Framework: Foundry (Forge) -- Run: `yarn test:chain` or `cd chain && forge test` -- Base: `DiamondTestBase` provides common setup +See [TESTING.md](TESTING.md) for complete testing guidelines. -### API Tests -- Location: `src/tests/` -- Framework: Jest -- Run: `yarn test:js` -- Integration: `yarn test-js-integration` -- Uses separate test database: `DATABASE_OVERRIDE=jest-integration` - -See `TESTING.md` for detailed testing guidelines. +- Smart contracts: `chain/test/` (Foundry/Forge) - Run: `yarn test:chain` +- API: `src/tests/` (Jest) - Run: `yarn test:js` +- Test database: `DATABASE_OVERRIDE=jest-integration` ## Environment Configuration -### Required Variables -- `DATABASE_URL` - MongoDB connection string -- `RPC_URL` - Blockchain RPC endpoint -- `CHAIN_ID` - Target chain ID (31337=Anvil, 84532=Base Sepolia, 8453=Base Mainnet) -- `PRIVATE_KEY` - Deployer private key -- `PORT` - Server port (default: 8293) - -### Environment Files -- `.env.local` - Local development (Anvil) -- `.env.dev` - Testnet deployment -- `.env.prod` - Production deployment +See [CONFIG.md](CONFIG.md) for complete configuration details. -See `CONFIG.md` for complete configuration details. +Required: `DATABASE_URL`, `RPC_URL`, `CHAIN_ID`, `PRIVATE_KEY`, `PORT` +Environment files: `.env.local`, `.env.dev`, `.env.prod` ## Development Workflow -1. **Start services**: Anvil, MongoDB (Docker), API server -2. **Deploy contracts**: `yarn deploy:local` -3. **Update `.env.local`** with contract addresses -4. **Run tests**: `yarn test:chain && yarn test:js` -5. **Create PR**: Follow conventional commits - -See `DEVELOPER_GUIDE.md` for complete workflow. +See [DEVELOPER_GUIDE.md](DEVELOPER_GUIDE.md) for complete development workflow, setup instructions, and common tasks. ## Documentation Links -- [README](README.md) - Project overview and quick start -- [Developer Guide](DEVELOPER_GUIDE.md) - Complete development guide -- [Deployment Guide](DEPLOYMENT.md) - Deployment procedures -- [Testing Guide](TESTING.md) - Testing practices -- [Configuration Guide](CONFIG.md) - Environment configuration -- [Data Model](docs/DATA_MODEL.md) - Database schema -- [Diamond Pattern](docs/DIAMOND_PATTERN.md) - Smart contract architecture -- [OpenAPI Spec](docs/openapi.yaml) - API specification -- [Contributing](CONTRIBUTING.md) - Contribution guidelines +**Human-focused documentation:** +- [README.md](README.md) - Project overview, setup, and usage +- [DEVELOPER_GUIDE.md](DEVELOPER_GUIDE.md) - Complete development guide +- [DEPLOYMENT.md](DEPLOYMENT.md) - Deployment procedures +- [TESTING.md](TESTING.md) - Testing practices +- [API.md](API.md) - API reference and examples +- [ARCHITECTURE.md](ARCHITECTURE.md) - System architecture overview +- [CONFIG.md](CONFIG.md) - Environment configuration + +**Technical documentation:** +- [docs/DATA_MODEL.md](docs/DATA_MODEL.md) - Database schema +- [docs/DIAMOND_PATTERN.md](docs/DIAMOND_PATTERN.md) - Smart contract architecture +- [docs/openapi.yaml](docs/openapi.yaml) - API specification +- [CONTRIBUTING.md](CONTRIBUTING.md) - Contribution guidelines ## Important Notes @@ -301,22 +248,8 @@ See `DEVELOPER_GUIDE.md` for complete workflow. ## Common Tasks -### Adding a New API Endpoint -1. Create route handler in `src/routes/` -2. Create controller in `src/controllers/` -3. Add route to `src/app.js` with appropriate middleware -4. Update `docs/openapi.yaml` -5. Add tests in `src/tests/` - -### Adding a New Smart Contract Facet -1. Create facet contract in `chain/src/facets/` -2. Define storage in `chain/src/libraries/Storage.sol` -3. Add deployment script in `chain/script/` -4. Update factory if needed -5. Add tests in `chain/test/` - -### Adding Support for a New Chain -1. Add chain config in `src/utils/chains.js` -2. Add RPC URL to environment files -3. Deploy contracts to new chain -4. Update documentation +See [DEVELOPER_GUIDE.md](DEVELOPER_GUIDE.md) for detailed common tasks including: +- Adding new API endpoints +- Adding new smart contract facets +- Adding support for new chains +- And more... From 32a40bc3b1fc7f8e381846c14cec437ca48a68ad Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 10 Dec 2025 16:44:48 +0000 Subject: [PATCH 4/5] Refactor: Remove deprecated API and Deployment docs Remove API.md and DEPLOYMENT.md as their content is now integrated into other documentation files. Co-authored-by: hardlydiff --- API.md | 486 ------------------------------------------ ARCHITECTURE.md | 339 ++--------------------------- DEPLOYMENT.md | 520 --------------------------------------------- DEVELOPER_GUIDE.md | 51 +---- llms.txt | 62 +----- 5 files changed, 27 insertions(+), 1431 deletions(-) delete mode 100644 API.md delete mode 100644 DEPLOYMENT.md diff --git a/API.md b/API.md deleted file mode 100644 index 404b3e69..00000000 --- a/API.md +++ /dev/null @@ -1,486 +0,0 @@ -# API Reference - -This document provides API usage examples and reference for the Open Cap Table Protocol (OCP) API. - -## Base URL - -- **Local**: `http://localhost:8293` -- **Development**: `https://api.ocp-dev.fairmint.co` -- **Staging**: `https://api.ocp-staging.fairmint.co` -- **Production**: `https://api.ocp.fairmint.co` - -## Authentication - -Currently, the API does not require authentication for most endpoints. Future versions may implement API keys or OAuth. - -## Content Type - -All requests should use `Content-Type: application/json`. - -## Common Response Formats - -### Success Response -```json -{ - "issuer": { ... }, - "id": "uuid-here" -} -``` - -### Error Response -```json -{ - "error": "Error message here" -} -``` - -## Core Endpoints - -### Health Check - -**GET** `/health` - -Check if the API is operational. - -**Response:** -``` -OK -``` - -**Example:** -```bash -curl http://localhost:8293/health -``` - ---- - -### Create Issuer - -**POST** `/issuer/create` - -Create a new issuer (company) and deploy a cap table contract. - -**Request Body:** -```json -{ - "chain_id": 31337, - "legal_name": "Acme Corporation", - "dba": "Acme", - "formation_date": "2020-01-01", - "country_of_formation": "US", - "country_subdivision_of_formation": "DE", - "initial_shares_authorized": "1000000" -} -``` - -**Response:** -```json -{ - "issuer": { - "_id": "uuid-here", - "legal_name": "Acme Corporation", - "deployed_to": "0x...", - "chain_id": 31337, - "tx_hash": "0x...", - ... - } -} -``` - -**Example:** -```bash -curl -X POST http://localhost:8293/issuer/create \ - -H "Content-Type: application/json" \ - -d '{ - "chain_id": 31337, - "legal_name": "Acme Corporation", - "initial_shares_authorized": "1000000" - }' -``` - -**Notes:** -- `chain_id` is required (31337=Anvil, 84532=Base Sepolia, 8453=Base Mainnet) -- Contract is automatically deployed -- WebSocket listener is started automatically - ---- - -### Get Issuer - -**GET** `/issuer/id/:id` - -Get issuer information by ID. - -**Response:** -```json -{ - "issuerId": "uuid-here", - "type": "ISSUER", - "role": "admin" -} -``` - -**Example:** -```bash -curl http://localhost:8293/issuer/id/uuid-here -``` - ---- - -### Create Stakeholder - -**POST** `/stakeholder/create` - -Create a new stakeholder on-chain. - -**Request Body:** -```json -{ - "issuerId": "uuid-here", - "name": { - "legal_name": "John Doe" - }, - "stakeholder_type": "INDIVIDUAL" -} -``` - -**Response:** -```json -{ - "stakeholder": { - "_id": "uuid-here", - "name": { ... }, - ... - } -} -``` - -**Example:** -```bash -curl -X POST http://localhost:8293/stakeholder/create \ - -H "Content-Type: application/json" \ - -d '{ - "issuerId": "issuer-uuid", - "name": { "legal_name": "John Doe" }, - "stakeholder_type": "INDIVIDUAL" - }' -``` - -**Notes:** -- Requires `issuerId` to identify the cap table -- Stakeholder is created both on-chain and in database - ---- - -### Create Stock Class - -**POST** `/stock-class/create` - -Create a new stock class. - -**Request Body:** -```json -{ - "issuerId": "uuid-here", - "class_type": "COMMON", - "price_per_share": { - "amount": "1.00", - "currency": "USD" - }, - "initial_shares_authorized": "100000" -} -``` - -**Response:** -```json -{ - "stockClass": { - "_id": "uuid-here", - "class_type": "COMMON", - ... - } -} -``` - -**Example:** -```bash -curl -X POST http://localhost:8293/stock-class/create \ - -H "Content-Type: application/json" \ - -d '{ - "issuerId": "issuer-uuid", - "class_type": "COMMON", - "price_per_share": { "amount": "1.00", "currency": "USD" }, - "initial_shares_authorized": "100000" - }' -``` - ---- - -## Transaction Endpoints - -### Issue Stock - -**POST** `/transactions/issuance` - -Issue stock to a stakeholder. - -**Request Body:** -```json -{ - "issuerId": "uuid-here", - "stock_class_id": "stock-class-uuid", - "stakeholder_id": "stakeholder-uuid", - "quantity": "1000", - "share_price": { - "amount": "10.00", - "currency": "USD" - } -} -``` - -**Response:** -```json -{ - "transaction": { - "_id": "uuid-here", - "object_type": "TX_STOCK_ISSUANCE", - "quantity": "1000", - ... - } -} -``` - -**Example:** -```bash -curl -X POST http://localhost:8293/transactions/issuance \ - -H "Content-Type: application/json" \ - -d '{ - "issuerId": "issuer-uuid", - "stock_class_id": "stock-class-uuid", - "stakeholder_id": "stakeholder-uuid", - "quantity": "1000", - "share_price": { "amount": "10.00", "currency": "USD" } - }' -``` - ---- - -### Transfer Stock - -**POST** `/transactions/transfer` - -Transfer stock between stakeholders. - -**Request Body:** -```json -{ - "issuerId": "uuid-here", - "from_stakeholder_id": "stakeholder-uuid-1", - "to_stakeholder_id": "stakeholder-uuid-2", - "stock_class_id": "stock-class-uuid", - "quantity": "100", - "share_price": { - "amount": "10.00", - "currency": "USD" - } -} -``` - -**Response:** -```json -{ - "transaction": { - "_id": "uuid-here", - "object_type": "TX_STOCK_TRANSFER", - ... - } -} -``` - ---- - -### Exercise Equity Compensation - -**POST** `/transactions/exercise` - -Exercise equity compensation (options, RSUs, etc.). - -**Request Body:** -```json -{ - "issuerId": "uuid-here", - "equity_compensation_id": "equity-comp-uuid", - "quantity": "500" -} -``` - ---- - -### Cancel Stock - -**POST** `/transactions/cancellation` - -Cancel stock (repurchase, forfeiture, etc.). - -**Request Body:** -```json -{ - "issuerId": "uuid-here", - "stock_class_id": "stock-class-uuid", - "stakeholder_id": "stakeholder-uuid", - "quantity": "100" -} -``` - ---- - -## Statistics Endpoints - -### Get Cap Table Stats - -**GET** `/stats/cap-table/:issuerId` - -Get cap table statistics for an issuer. - -**Response:** -```json -{ - "total_shares": "1000000", - "issued_shares": "500000", - "outstanding_shares": "500000", - "stakeholders": 10, - "stock_classes": 2 -} -``` - ---- - -## Export Endpoints - -### Export Cap Table - -**GET** `/export/cap-table/:issuerId` - -Export cap table data in various formats. - -**Query Parameters:** -- `format` - Export format (json, csv, xlsx, ocf) - -**Example:** -```bash -curl http://localhost:8293/export/cap-table/uuid-here?format=ocf -``` - ---- - -## OCF Endpoints - -### Verify Cap Table - -**POST** `/verify-cap-table` - -Verify cap table data against OCF standard. - -**Request:** -- Multipart form data with OCF manifest file - -**Response:** -```json -{ - "valid": true, - "errors": [] -} -``` - ---- - -## Error Handling - -### Common Error Codes - -- `400` - Bad Request (missing/invalid parameters) -- `404` - Not Found (issuer/stakeholder not found) -- `500` - Internal Server Error - -### Error Response Format - -```json -{ - "error": "Error message here" -} -``` - -### Contract Errors - -When contract calls fail, errors are decoded and returned: - -```json -{ - "error": "NoStakeholder: Stakeholder not found", - "details": { - "name": "NoStakeholder", - "args": { - "stakeholder_id": "0x..." - } - } -} -``` - -## Rate Limiting - -Currently, there are no rate limits. Future versions may implement rate limiting. - -## WebSocket Events - -The API automatically starts WebSocket listeners for deployed contracts. Events are synced to the database automatically. - -**Event Types:** -- `StockIssued` -- `StockTransferred` -- `StakeholderCreated` -- `StockClassCreated` -- And more... - -## Complete API Specification - -For the complete OpenAPI specification, see `docs/openapi.yaml`. - -## Example Workflows - -### Complete Cap Table Setup - -```bash -# 1. Create issuer -ISSUER_ID=$(curl -X POST http://localhost:8293/issuer/create \ - -H "Content-Type: application/json" \ - -d '{"chain_id": 31337, "legal_name": "Acme Corp", "initial_shares_authorized": "1000000"}' \ - | jq -r '.issuer._id') - -# 2. Create stakeholder -STAKEHOLDER_ID=$(curl -X POST http://localhost:8293/stakeholder/create \ - -H "Content-Type: application/json" \ - -d "{\"issuerId\": \"$ISSUER_ID\", \"name\": {\"legal_name\": \"John Doe\"}, \"stakeholder_type\": \"INDIVIDUAL\"}" \ - | jq -r '.stakeholder._id') - -# 3. Create stock class -STOCK_CLASS_ID=$(curl -X POST http://localhost:8293/stock-class/create \ - -H "Content-Type: application/json" \ - -d "{\"issuerId\": \"$ISSUER_ID\", \"class_type\": \"COMMON\", \"price_per_share\": {\"amount\": \"1.00\", \"currency\": \"USD\"}, \"initial_shares_authorized\": \"100000\"}" \ - | jq -r '.stockClass._id') - -# 4. Issue stock -curl -X POST http://localhost:8293/transactions/issuance \ - -H "Content-Type: application/json" \ - -d "{\"issuerId\": \"$ISSUER_ID\", \"stock_class_id\": \"$STOCK_CLASS_ID\", \"stakeholder_id\": \"$STAKEHOLDER_ID\", \"quantity\": \"1000\", \"share_price\": {\"amount\": \"10.00\", \"currency\": \"USD\"}}" -``` - -## Testing - -See `TESTING.md` for testing guidelines and examples. - -## Related Documentation - -- [Developer Guide](DEVELOPER_GUIDE.md) - Development workflow -- [Deployment Guide](DEPLOYMENT.md) - Deployment procedures -- [OpenAPI Specification](docs/openapi.yaml) - Complete API spec -- [Data Model](docs/DATA_MODEL.md) - Database schema diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index b0eb0512..8b84138e 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -1,341 +1,32 @@ # Architecture Overview -This document consolidates architecture information for the Open Cap Table Protocol (OCP). - -## System Architecture - -OCP follows a **dual-layer architecture**: - -``` -┌─────────────────────────────────────────────────────────────┐ -│ CLIENT APPLICATIONS │ -│ (Fairmint, External Integrations, etc.) │ -└──────────────────────┬──────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────┐ -│ API SERVER LAYER │ -│ Express.js REST API + MongoDB + WebSocket Event Listeners │ -│ │ -│ • Route Handlers (src/routes/) │ -│ • Controllers (src/controllers/) │ -│ • Database Models (src/db/objects/) │ -│ • Event Synchronization (src/utils/websocket.ts) │ -└──────────────────────┬──────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────┐ -│ BLOCKCHAIN LAYER │ -│ Diamond Pattern Smart Contracts (EVM) │ -│ │ -│ • CapTable (Diamond Contract) │ -│ • Facets (Issuer, Stakeholder, StockClass, etc.) │ -│ • Factory (Deployment) │ -└─────────────────────────────────────────────────────────────┘ -``` +This document describes the architecture of the Open Cap Table Protocol (OCP). ## Smart Contract Architecture ### Diamond Pattern -OCP uses the **Diamond pattern** for smart contracts, providing: - -- **Modularity**: Separate facets for different functionality -- **Upgradability**: Add/remove/replace facets without data migration -- **Unlimited Size**: Bypass 24KB contract size limit -- **Shared Storage**: Single storage structure across all facets +OCP uses the Diamond pattern for smart contracts. See `docs/DIAMOND_PATTERN.md` for detailed information. **Core Components:** +- `CapTable` - Main diamond contract +- `CapTableFactory` - Factory for creating cap tables +- Facets - Modular implementation contracts in `chain/src/facets/` +- Storage - Shared storage structure in `chain/src/core/Storage.sol` -1. **Diamond Contract (CapTable)** - - Main entry point for all function calls - - Delegates to appropriate facets via function selectors - - Created by `CapTableFactory` for each issuer - -2. **Facets** (Implementation Contracts) - - `IssuerFacet` - Issuer data management - - `StakeholderFacet` - Stakeholder operations - - `StockClassFacet` - Stock class definitions - - `StockFacet` - Stock issuance and transfers - - `StockPlanFacet` - Equity compensation plans - - `ConvertiblesFacet` - Convertible securities - - `EquityCompensationFacet` - Equity compensation - - `WarrantFacet` - Warrant management - - `StakeholderNFTFacet` - NFT representation of positions - -3. **Storage Library** - - Shared storage structure in `Storage.sol` - - Accessed via `StorageLib.get()` from all facets - - Contains all cap table data in a single location - -See `docs/DIAMOND_PATTERN.md` for detailed information. - -### Factory Pattern - -- `CapTableFactory` creates new cap table instances -- Uses reference diamond for facet addresses -- Each issuer gets a unique CapTable contract - -## API Server Architecture - -### Express.js Application - -**Entry Point**: `src/app.js` - -**Middleware Stack:** -1. CORS - Cross-origin resource sharing -2. Body parsing (JSON, URL-encoded) -3. Chain middleware - Validates chain ID for issuer creation -4. Contract middleware - Caches contract instances per issuer - -**Route Organization:** -- `/issuer` - Issuer management -- `/stakeholder` - Stakeholder operations -- `/stock-class` - Stock class management -- `/stock-plan` - Equity plan management -- `/transactions/*` - Transaction processing -- `/stats/*` - Analytics and statistics -- `/export/*` - Data export -- `/ocf/*` - OCF format operations - -### Database Architecture - -**MongoDB Collections:** - -- `issuers` - Company/issuer data -- `stakeholders` - Individual/entity stakeholders -- `stockclasses` - Stock class definitions -- `stockplans` - Equity compensation plans -- `stocklegends` - Stock legend templates -- `valuations` - Company valuations -- `vestingterms` - Vesting term definitions -- `transactions/*` - Transaction records (issuance, transfer, exercise, etc.) -- `fairmint` - Fairmint integration tracking - -**Data Model:** -- Follows OCF standard structure -- UUIDs as primary keys -- References between entities -- Timestamps for audit trail - -See `docs/DATA_MODEL.md` for complete schema. - -### Event Synchronization - -**WebSocket Listeners:** -- Monitor blockchain events for all deployed contracts -- Group contracts by chain ID for efficient connection management -- Automatically sync events to MongoDB -- Handle reconnections and error recovery - -**Event Flow:** -``` -Blockchain Event → WebSocket Listener → Event Handler → Database Update -``` - -## Multi-Chain Architecture - -### Chain Configuration - -Supported chains defined in `src/utils/chains.js`: - -```javascript -SUPPORTED_CHAINS = { - 8453: { name: "Base Mainnet", rpcUrl, wsUrl }, - 84532: { name: "Base Sepolia", rpcUrl, wsUrl }, - 31337: { name: "Anvil", rpcUrl, wsUrl }, -} -``` - -### Chain-Agnostic Design - -- Contract instances cached per `chainId + issuerId` -- RPC providers created per chain -- WebSocket listeners grouped by chain -- Chain ID required for issuer creation - -## Data Flow Patterns - -### Creating an Issuer - -``` -1. API Request (POST /issuer/create) - ↓ -2. Validate OCF schema - ↓ -3. Deploy CapTable contract (chain) - ↓ -4. Save issuer to MongoDB (web) - ↓ -5. Start WebSocket listener for contract - ↓ -6. Return issuer data -``` - -### Issuing Stock - -``` -1. API Request (POST /transactions/issuance) - ↓ -2. Validate input - ↓ -3. Call contract.issueStock() (chain) - ↓ -4. Transaction mined - ↓ -5. WebSocket listener catches StockIssued event - ↓ -6. Save transaction to MongoDB (web) - ↓ -7. Return transaction data -``` - -### Event Synchronization - -``` -1. Blockchain event emitted - ↓ -2. WebSocket listener receives event - ↓ -3. Parse event data - ↓ -4. Update MongoDB document - ↓ -5. Log synchronization -``` - -## Security Architecture - -### Access Control - -- **On-Chain**: Role-based access control (RBAC) in smart contracts -- **Off-Chain**: API authentication (if implemented) -- **Admin Roles**: Contract admin, issuer admin, etc. - -### Data Validation - -- **OCF Schema Validation**: All data validated against OCF JSON schemas -- **Input Sanitization**: UUID validation, decimal scaling -- **Error Handling**: Comprehensive error decoding and reporting - -### Contract Security - -- **Diamond Pattern**: Upgradeable but controlled -- **Access Control**: Role-based permissions -- **Input Validation**: Revert on invalid inputs -- **Gas Optimization**: Efficient storage patterns - -## Integration Points - -### Fairmint Integration - -- Bidirectional data reflection between OCP and Fairmint -- Webhook-based synchronization -- Portal/Issuer mapping -- See `docs/DATA_REFLECTION.md` for details - -### OCF Standard - -- Full OCF schema compliance -- Import/export OCF format files -- Validation against OCF schemas -- See `docs/OCX_EXPORT.md` for export details - -## Performance Considerations - -### Caching - -- **Contract Instances**: Cached per `chainId + issuerId` -- **Preprocessor Cache**: Cached processed data -- **TTL Configuration**: Configurable cache expiration - -### Database - -- Indexed fields for fast queries -- Efficient aggregation pipelines -- Connection pooling - -### Blockchain - -- Batch operations where possible -- Gas optimization in contracts -- Efficient event filtering - -## Scalability - -### Horizontal Scaling - -- Stateless API server (can scale horizontally) -- MongoDB replica sets -- Load-balanced RPC endpoints - -### Vertical Scaling - -- Database query optimization -- Contract gas optimization -- Efficient event processing - -## Deployment Architecture - -### Environments - -- **Local**: Anvil + Local MongoDB -- **Testnet**: Base Sepolia + Test MongoDB -- **Production**: Base Mainnet + Production MongoDB - -### Deployment Flow - -``` -1. Deploy Smart Contracts (Foundry) - ↓ -2. Update Environment Variables - ↓ -3. Deploy API Server - ↓ -4. Start WebSocket Listeners - ↓ -5. Sync Historical Events (if needed) -``` - -See `DEPLOYMENT.md` for detailed procedures. - -## Monitoring & Observability - -### Logging - -- Structured logging with emoji prefixes -- Error tracking with Sentry -- Transaction hash logging - -### Health Checks - -- `/health` endpoint for API status -- Database connection monitoring -- WebSocket connection status - -### Metrics - -- Transaction counts -- Event processing rates -- Error rates -- Response times - -## Future Architecture Considerations - -### Potential Enhancements +## Codebase Structure -- GraphQL API layer -- Event sourcing for audit trail -- Multi-signature support -- Advanced analytics -- Real-time notifications -- API rate limiting -- Authentication/authorization layer +- `chain/` - Smart contracts (Solidity, Foundry) +- `src/` - Server code (Node.js/TypeScript) + - `routes/` - Route handlers + - `db/` - MongoDB models and operations + - `chain-operations/` - Blockchain interaction utilities + - `utils/` - Utility functions ## Related Documentation -- [Diamond Pattern](docs/DIAMOND_PATTERN.md) - Smart contract architecture +- [Diamond Pattern](docs/DIAMOND_PATTERN.md) - Smart contract architecture details - [Data Model](docs/DATA_MODEL.md) - Database schema - [Configuration](CONFIG.md) - Environment setup -- [Deployment](DEPLOYMENT.md) - Deployment procedures - [Developer Guide](DEVELOPER_GUIDE.md) - Development workflow +- [README](README.md) - Project overview diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md deleted file mode 100644 index 09edb175..00000000 --- a/DEPLOYMENT.md +++ /dev/null @@ -1,520 +0,0 @@ -# Deployment Guide - -This guide covers deployment procedures for the Open Cap Table Protocol (OCP) across different environments. - -## Table of Contents - -- [Overview](#overview) -- [Prerequisites](#prerequisites) -- [Local Deployment](#local-deployment) -- [Testnet Deployment](#testnet-deployment) -- [Production Deployment](#production-deployment) -- [Post-Deployment](#post-deployment) -- [Verification](#verification) -- [Rollback Procedures](#rollback-procedures) - -## Overview - -OCP can be deployed to three environments: - -- **Local** - Development environment using Anvil -- **Testnet** - Staging environment (e.g., Base Sepolia) -- **Production** - Mainnet environment (e.g., Base Mainnet) - -Each environment requires: -1. Smart contract deployment -2. Environment configuration -3. Database setup -4. API server deployment - -## Prerequisites - -### Required Tools - -- Foundry (Forge, Anvil, Cast) -- Node.js and Yarn -- Docker and Docker Compose -- Access to blockchain RPC endpoints -- Private key with sufficient funds for gas - -### Environment Files - -Ensure you have the appropriate environment file: - -- `.env.local` - Local development -- `.env.dev` - Testnet deployment -- `.env.prod` - Production deployment - -### Required Environment Variables - -```bash -# Blockchain Configuration -RPC_URL= -CHAIN_ID= -PRIVATE_KEY= - -# Contract Verification (optional) -ETHERSCAN_L2_API_KEY= -ETHERSCAN_L1_API_KEY= - -# Database -DATABASE_URL= - -# Server -PORT=8293 -``` - -## Local Deployment - -### Step 1: Start Local Blockchain - -```bash -# Terminal 1: Start Anvil -anvil -``` - -Anvil will output: -- RPC URL: `http://127.0.0.1:8545` -- Chain ID: `31337` -- Private keys for testing - -### Step 2: Configure Environment - -Copy `.env.example` to `.env.local`: - -```bash -cp .env.example .env.local -``` - -Update `.env.local`: - -```bash -RPC_URL=http://127.0.0.1:8545 -CHAIN_ID=31337 -PRIVATE_KEY= -DATABASE_URL=mongodb://ocp:ocp@localhost:27017/mongo?authSource=admin&retryWrites=true&w=majority -PORT=8293 -``` - -### Step 3: Deploy Contracts - -```bash -yarn deploy:local -``` - -The script will: -1. Check if contracts already exist -2. Deploy factory contract -3. Deploy reference diamond and all facets -4. Output contract addresses - -### Step 4: Update Environment File - -Copy the contract addresses from the deployment output to `.env.local`: - -```bash -FACTORY_ADDRESS=0x... -REFERENCE_DIAMOND=0x... -DIAMOND_CUT_FACET=0x... -ISSUER_FACET=0x... -STAKEHOLDER_FACET=0x... -STOCK_CLASS_FACET=0x... -STOCK_FACET=0x... -CONVERTIBLES_FACET=0x... -EQUITY_COMPENSATION_FACET=0x... -STOCK_PLAN_FACET=0x... -WARRANT_FACET=0x... -STAKEHOLDER_NFT_FACET=0x... -``` - -### Step 5: Start Services - -**Terminal 2: MongoDB** -```bash -docker compose up -``` - -**Terminal 3: API Server** -```bash -yarn local -# or -USE_ENV_FILE=.env.local yarn dev -``` - -### Step 6: Verify Deployment - -```bash -# Check API health -curl http://localhost:8293/health - -# Should return: OK -``` - -## Testnet Deployment - -### Step 1: Prepare Environment - -1. **Get testnet RPC URL:** - - Base Sepolia: Use public RPC or get from [Base](https://docs.base.org/tools/network-faucets) - - Or use services like Alchemy, Infura - -2. **Get testnet tokens:** - - Use faucets to get testnet ETH for gas - - Base Sepolia: [Base Sepolia Faucet](https://docs.base.org/tools/network-faucets) - -3. **Configure `.env.dev`:** - ```bash - RPC_URL=https://sepolia.base.org - CHAIN_ID=84532 - PRIVATE_KEY= - DATABASE_URL= - ETHERSCAN_L2_API_KEY= - ``` - -### Step 2: Deploy Contracts - -```bash -yarn deploy:testnet -``` - -The script will: -1. Prompt for confirmation (non-local environments) -2. Deploy contracts to testnet -3. Output contract addresses and transaction hashes - -**Important:** Save all contract addresses and transaction hashes for verification. - -### Step 3: Verify Contracts (Optional) - -```bash -yarn verify:prod --env=dev -``` - -This verifies contracts on Etherscan/BaseScan for transparency. - -### Step 4: Update Environment - -Update `.env.dev` with deployed contract addresses. - -### Step 5: Deploy API Server - -Deploy to your testnet server: - -```bash -# On server -USE_ENV_FILE=.env.dev yarn start -``` - -Or use your deployment method (Docker, Kubernetes, etc.). - -### Step 6: Sync Blockchain Events - -Start the event listener to sync historical events: - -```bash -yarn sync:testnet -``` - -## Production Deployment - -### Pre-Deployment Checklist - -- [ ] All tests passing -- [ ] Code reviewed and approved -- [ ] Environment variables configured -- [ ] Private key secured (use key management service) -- [ ] Sufficient funds for gas -- [ ] Backup of current deployment -- [ ] Rollback plan prepared - -### Step 1: Final Verification - -```bash -# Run all checks -yarn flightcheck -yarn typecheck -yarn test:chain -yarn test:js -``` - -### Step 2: Prepare Production Environment - -1. **Secure private key:** - - Use environment variable injection - - Or key management service (AWS Secrets Manager, etc.) - - Never commit private keys - -2. **Configure `.env.prod`:** - ```bash - RPC_URL=https://mainnet.base.org - CHAIN_ID=8453 - PRIVATE_KEY= - DATABASE_URL= - ETHERSCAN_L2_API_KEY= - SENTRY_DSN= - ``` - -### Step 3: Deploy Contracts - -```bash -yarn deploy:mainnet -``` - -**Critical:** The script will prompt for confirmation. Verify: -- Correct network -- Correct private key -- Sufficient gas funds -- All addresses are correct - -### Step 4: Verify Contracts - -```bash -yarn verify:prod --env=prod -``` - -Verification is important for: -- Transparency -- Contract interaction tools -- Security audits - -### Step 5: Update Production Environment - -Update production environment variables with contract addresses. - -### Step 6: Deploy API Server - -Deploy using your production deployment method: - -**Docker:** -```bash -docker build -t ocp-api . -docker run -d --env-file .env.prod -p 8293:8293 ocp-api -``` - -**Kubernetes:** -```bash -kubectl apply -f deploy.prod.yaml -``` - -**Other:** Follow your organization's deployment procedures. - -### Step 7: Sync Historical Events - -```bash -yarn sync:mainnet -``` - -This syncs all historical blockchain events to the database. - -### Step 8: Monitor Deployment - -- Check API health endpoints -- Monitor error logs (Sentry) -- Verify WebSocket connections -- Check database sync status - -## Post-Deployment - -### Health Checks - -```bash -# API health -curl https://api.ocp.fairmint.co/health - -# Database connection -# Check MongoDB connection in logs - -# Blockchain connection -# Check RPC connection in logs -``` - -### Event Listener Status - -Verify WebSocket listeners are running: -- Check application logs for "WebSocket connected" messages -- Monitor for event processing logs -- Verify events are being written to database - -### Database Verification - -```bash -# Connect to MongoDB -mongosh - -# Check collections -show collections - -# Verify issuer data -db.issuers.find().count() -``` - -### API Testing - -Test key endpoints: - -```bash -# Health check -curl https://api.ocp.fairmint.co/health - -# Create issuer (test) -curl -X POST https://api.ocp.fairmint.co/issuer \ - -H "Content-Type: application/json" \ - -d '{"chain_id": 8453, ...}' -``` - -## Verification - -### Contract Verification - -Verify contracts are deployed correctly: - -```bash -# Using Cast -cast code --rpc-url - -# Should return bytecode (not 0x) -``` - -### Address Verification - -Verify all contract addresses: - -1. Check factory can create new cap tables -2. Verify diamond proxy points to correct facets -3. Test key functions on deployed contracts - -### Database Verification - -1. Check MongoDB collections exist -2. Verify indexes are created -3. Test read/write operations - -### API Verification - -1. Test all endpoints -2. Verify CORS settings -3. Check authentication (if applicable) -4. Test error handling - -## Rollback Procedures - -### Smart Contract Rollback - -**Note:** Smart contracts are immutable once deployed. Rollback means: -1. Deploying new contracts -2. Updating environment variables -3. Migrating data if necessary - -### API Server Rollback - -**Docker:** -```bash -# Rollback to previous image -docker pull ocp-api: -docker stop ocp-api -docker run -d --env-file .env.prod -p 8293:8293 ocp-api: -``` - -**Kubernetes:** -```bash -kubectl rollout undo deployment/ocp-api -``` - -**Other:** Follow your deployment system's rollback procedures. - -### Database Rollback - -1. Restore from backup -2. Re-sync blockchain events if needed -3. Verify data integrity - -### Emergency Procedures - -If critical issues occur: - -1. **Stop API server** to prevent further issues -2. **Assess impact** - what's affected? -3. **Check logs** for error details -4. **Rollback** if necessary -5. **Document** the issue and resolution - -## Deployment Scripts - -### Available Scripts - -```bash -# Local deployment -yarn deploy:local - -# Testnet deployment -yarn deploy:testnet - -# Mainnet deployment -yarn deploy:mainnet - -# Contract verification -yarn verify:prod --env= - -# Sync blockchain events -yarn sync:local -yarn sync:testnet -yarn sync:mainnet -``` - -### Custom Deployment - -For custom deployments, use the deployment script directly: - -```bash -./scripts/deploy_factory.sh --env= -``` - -## Best Practices - -1. **Always test locally first** before deploying to testnet/production -2. **Use separate private keys** for each environment -3. **Verify contracts** on block explorers -4. **Monitor deployments** closely -5. **Keep backups** of environment files and contract addresses -6. **Document changes** in deployment logs -7. **Use CI/CD** for automated deployments when possible -8. **Implement health checks** and monitoring -9. **Have rollback plans** ready -10. **Secure private keys** using key management services - -## Troubleshooting - -### Deployment Fails - -- Check RPC connection -- Verify private key has sufficient funds -- Check contract compilation errors -- Review deployment script logs - -### Contracts Not Verifying - -- Ensure Etherscan API key is correct -- Check contract bytecode matches source -- Verify constructor arguments -- Wait for block confirmations - -### API Server Won't Start - -- Check environment variables -- Verify database connection -- Check port availability -- Review application logs - -### Events Not Syncing - -- Verify WebSocket RPC URL -- Check event filter configuration -- Review listener logs -- Ensure contracts are deployed - -## Additional Resources - -- [Configuration Guide](./CONFIG.md) - Environment configuration details -- [Developer Guide](./DEVELOPER_GUIDE.md) - Development setup -- [Foundry Documentation](https://book.getfoundry.sh/) - Smart contract deployment -- [Base Documentation](https://docs.base.org/) - Base network information diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md index 1ef77175..cc0e8e5a 100644 --- a/DEVELOPER_GUIDE.md +++ b/DEVELOPER_GUIDE.md @@ -63,7 +63,7 @@ Before you begin, ensure you have the following installed: ```bash docker compose up ``` - - Terminal 4: Start the API server + - Terminal 4: Start the server ```bash yarn dev ``` @@ -79,9 +79,9 @@ open-captable-protocol/ │ │ ├── core/ # Core contracts │ │ └── interfaces/ # Contract interfaces │ └── script/ # Deployment scripts -├── src/ # API server (Node.js/TypeScript) -│ ├── app.js # Express app entry point -│ ├── routes/ # API route handlers +├── src/ # Server code (Node.js/TypeScript) +│ ├── app.js # Application entry point +│ ├── routes/ # Route handlers │ ├── controllers/ # Business logic controllers │ ├── db/ # MongoDB models and operations │ ├── chain-operations/ # Blockchain interaction utilities @@ -189,40 +189,9 @@ mongodb://ocp:ocp@localhost:27017/mongo?authSource=admin&retryWrites=true&w=majo ## Architecture Overview -### System Components +See [ARCHITECTURE.md](./ARCHITECTURE.md) for architecture details. -OCP consists of two main layers: - -1. **Smart Contract Layer (Chain)** - - Solidity contracts using the Diamond pattern - - On-chain cap table data storage - - Transaction processing for equity movements - - Multi-chain support (Base, Arbitrum, etc.) - -2. **API Server (Web)** - - Express.js REST API - - MongoDB for off-chain data - - WebSocket event listeners - - OCF standard validation - -### Diamond Pattern - -The smart contracts use the Diamond pattern for modularity and upgradability: - -- **Diamond Contract**: Main entry point that delegates to facets -- **Facets**: Modular implementation contracts (Issuer, Stakeholder, StockClass, etc.) -- **Storage**: Shared storage structure accessible by all facets - -See [docs/DIAMOND_PATTERN.md](./docs/DIAMOND_PATTERN.md) for detailed information. - -### Data Flow - -1. **API Request** → Express routes → Controllers -2. **Controllers** → Database operations (MongoDB) + Chain operations (Smart contracts) -3. **Chain Events** → WebSocket listeners → Database updates -4. **Response** → OCF-compliant JSON - -See [docs/DATA_MODEL.md](./docs/DATA_MODEL.md) for data model details. +The smart contracts use the Diamond pattern. See [docs/DIAMOND_PATTERN.md](./docs/DIAMOND_PATTERN.md) for detailed information. ## Development Workflow @@ -348,7 +317,7 @@ yarn test-js-integration } ``` -**API Tests:** +**Server Tests:** - Located in `src/tests/` - Use Jest testing framework - Example: @@ -388,12 +357,12 @@ See [TESTING.md](./TESTING.md) for detailed testing guidelines. ## Common Tasks -### Adding a New API Endpoint +### Adding a New Route 1. **Create route handler** in `src/routes/` 2. **Create controller** in `src/controllers/` 3. **Add route** to `src/app.js` -4. **Update OpenAPI spec** in `docs/openapi.yaml` +4. **Update OpenAPI spec** in `docs/openapi.yaml` if applicable 5. **Add tests** in `src/tests/` ### Adding a New Smart Contract Facet @@ -478,7 +447,7 @@ This removes all test data from MongoDB. ## Additional Resources -- [OpenAPI Specification](./docs/openapi.yaml) - API documentation +- [OpenAPI Specification](./docs/openapi.yaml) - API specification - [Data Model Documentation](./docs/DATA_MODEL.md) - Database schema - [Diamond Pattern Documentation](./docs/DIAMOND_PATTERN.md) - Smart contract architecture - [Configuration Guide](./CONFIG.md) - Environment configuration diff --git a/llms.txt b/llms.txt index 532f4034..3480920a 100644 --- a/llms.txt +++ b/llms.txt @@ -17,28 +17,13 @@ ## Architecture Patterns -### Dual-Layer Architecture -- **Smart Contract Layer (Chain)**: Diamond pattern with facets for on-chain cap table data -- **API Server Layer (Web)**: Express.js REST API with MongoDB for off-chain data -- **Event Synchronization**: WebSocket listeners sync blockchain events to MongoDB - ### Diamond Pattern - **Diamond Contract**: Main entry point delegating to facets - **Facets**: Modular implementation contracts (Issuer, Stakeholder, StockClass, StockPlan, etc.) - **Shared Storage**: Single storage structure accessible by all facets - See `docs/DIAMOND_PATTERN.md` for details -### Multi-Chain Support -- Chain-agnostic design supporting multiple EVM networks -- Chain configuration in `src/utils/chains.js` -- Contract instances cached per chain+issuer combination -- WebSocket listeners grouped by chain ID - -### Data Flow -1. API Request → Express routes → Controllers -2. Controllers → Database (MongoDB) + Chain operations (Smart contracts) -3. Chain Events → WebSocket listeners → Database updates -4. Response → OCF-compliant JSON +See [ARCHITECTURE.md](ARCHITECTURE.md) for architecture overview. ## File Structure Overview @@ -145,36 +130,6 @@ await issuer.save(); // Not atomic! ## API Endpoints -### Core Entities - -| Method | Path | Purpose | Middleware | -|--------|------|---------|------------| -| POST | `/issuer/create` | Create new issuer and deploy cap table | `chainMiddleware` | -| GET | `/issuer/id/:id` | Get issuer by ID | None | -| POST | `/stakeholder/create` | Create stakeholder on-chain | `contractMiddleware` | -| POST | `/stock-class/create` | Create stock class | `contractMiddleware` | -| POST | `/stock-plan/create` | Create stock plan | `contractMiddleware` | - -### Transactions - -| Method | Path | Purpose | Middleware | -|--------|------|---------|------------| -| POST | `/transactions/issuance` | Issue stock | `contractMiddleware` | -| POST | `/transactions/transfer` | Transfer stock | `contractMiddleware` | -| POST | `/transactions/exercise` | Exercise equity compensation | `contractMiddleware` | -| POST | `/transactions/cancellation` | Cancel stock | `contractMiddleware` | - -### Utilities - -| Method | Path | Purpose | -|--------|------|---------| -| GET | `/health` | Health check | -| GET | `/` | API welcome message | -| POST | `/verify-cap-table` | Verify cap table data | -| GET | `/stats/*` | Cap table statistics | -| GET | `/export/*` | Export cap table data | -| POST | `/ocf/*` | OCF format operations | - See `docs/openapi.yaml` for complete API specification. ## Key Utilities @@ -211,9 +166,6 @@ See [TESTING.md](TESTING.md) for complete testing guidelines. See [CONFIG.md](CONFIG.md) for complete configuration details. -Required: `DATABASE_URL`, `RPC_URL`, `CHAIN_ID`, `PRIVATE_KEY`, `PORT` -Environment files: `.env.local`, `.env.dev`, `.env.prod` - ## Development Workflow See [DEVELOPER_GUIDE.md](DEVELOPER_GUIDE.md) for complete development workflow, setup instructions, and common tasks. @@ -223,9 +175,7 @@ See [DEVELOPER_GUIDE.md](DEVELOPER_GUIDE.md) for complete development workflow, **Human-focused documentation:** - [README.md](README.md) - Project overview, setup, and usage - [DEVELOPER_GUIDE.md](DEVELOPER_GUIDE.md) - Complete development guide -- [DEPLOYMENT.md](DEPLOYMENT.md) - Deployment procedures - [TESTING.md](TESTING.md) - Testing practices -- [API.md](API.md) - API reference and examples - [ARCHITECTURE.md](ARCHITECTURE.md) - System architecture overview - [CONFIG.md](CONFIG.md) - Environment configuration @@ -238,18 +188,10 @@ See [DEVELOPER_GUIDE.md](DEVELOPER_GUIDE.md) for complete development workflow, ## Important Notes - **Always validate against OCF schemas** before saving data -- **Use contract middleware** for routes that interact with contracts -- **WebSocket listeners auto-sync** blockchain events - don't manually sync -- **Contract instances are cached** - use middleware or cache directly -- **Multi-chain support** - always pass `chain_id` and use `getChainConfig()` - **UUIDs must be converted** to bytes16 for all contract calls - **Quantities/prices must be scaled** using `toScaledBigNumber()` - **Tests use separate database** - `DATABASE_OVERRIDE=jest-integration` ## Common Tasks -See [DEVELOPER_GUIDE.md](DEVELOPER_GUIDE.md) for detailed common tasks including: -- Adding new API endpoints -- Adding new smart contract facets -- Adding support for new chains -- And more... +See [DEVELOPER_GUIDE.md](DEVELOPER_GUIDE.md) for detailed common tasks. From 988dfabbc7bb7524c60f412de56de9b521c6268c Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 10 Dec 2025 16:49:07 +0000 Subject: [PATCH 5/5] Refactor: Remove diamond pattern documentation and references Co-authored-by: hardlydiff --- ARCHITECTURE.md | 22 +++++++++------------- DEVELOPER_GUIDE.md | 16 +++++----------- TESTING.md | 6 +++--- llms.txt | 14 +++----------- 4 files changed, 20 insertions(+), 38 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 8b84138e..1d38388f 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -2,30 +2,26 @@ This document describes the architecture of the Open Cap Table Protocol (OCP). -## Smart Contract Architecture - -### Diamond Pattern - -OCP uses the Diamond pattern for smart contracts. See `docs/DIAMOND_PATTERN.md` for detailed information. - -**Core Components:** -- `CapTable` - Main diamond contract -- `CapTableFactory` - Factory for creating cap tables -- Facets - Modular implementation contracts in `chain/src/facets/` -- Storage - Shared storage structure in `chain/src/core/Storage.sol` - ## Codebase Structure - `chain/` - Smart contracts (Solidity, Foundry) + - `src/core/` - Core contracts (CapTable, CapTableFactory, Storage) + - `src/facets/` - Facet contracts + - `src/libraries/` - Shared libraries + - `src/interfaces/` - Contract interfaces + - `test/` - Foundry tests + - `src/` - Server code (Node.js/TypeScript) - `routes/` - Route handlers + - `controllers/` - Business logic controllers - `db/` - MongoDB models and operations - `chain-operations/` - Blockchain interaction utilities - `utils/` - Utility functions + - `fairmint/` - Fairmint integration + - `rxjs/` - Reactive data processing ## Related Documentation -- [Diamond Pattern](docs/DIAMOND_PATTERN.md) - Smart contract architecture details - [Data Model](docs/DATA_MODEL.md) - Database schema - [Configuration](CONFIG.md) - Environment setup - [Developer Guide](DEVELOPER_GUIDE.md) - Development workflow diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md index cc0e8e5a..e0f3bd65 100644 --- a/DEVELOPER_GUIDE.md +++ b/DEVELOPER_GUIDE.md @@ -74,7 +74,7 @@ Before you begin, ensure you have the following installed: open-captable-protocol/ ├── chain/ # Smart contracts (Solidity) │ ├── src/ -│ │ ├── facets/ # Diamond pattern facets +│ │ ├── facets/ # Facet contracts │ │ ├── libraries/ # Shared libraries │ │ ├── core/ # Core contracts │ │ └── interfaces/ # Contract interfaces @@ -90,7 +90,6 @@ open-captable-protocol/ │ └── examples/ # Example scripts ├── docs/ # Documentation │ ├── DATA_MODEL.md # Data model documentation -│ ├── DIAMOND_PATTERN.md # Diamond pattern explanation │ └── openapi.yaml # OpenAPI specification ├── scripts/ # Deployment and utility scripts └── .github/ # GitHub workflows and templates @@ -124,8 +123,6 @@ PORT=8293 # Contract Addresses (set after deployment) FACTORY_ADDRESS= -REFERENCE_DIAMOND= -DIAMOND_CUT_FACET= ISSUER_FACET= # ... other facet addresses ``` @@ -191,8 +188,6 @@ mongodb://ocp:ocp@localhost:27017/mongo?authSource=admin&retryWrites=true&w=majo See [ARCHITECTURE.md](./ARCHITECTURE.md) for architecture details. -The smart contracts use the Diamond pattern. See [docs/DIAMOND_PATTERN.md](./docs/DIAMOND_PATTERN.md) for detailed information. - ## Development Workflow ### Branch Strategy @@ -365,11 +360,11 @@ See [TESTING.md](./TESTING.md) for detailed testing guidelines. 4. **Update OpenAPI spec** in `docs/openapi.yaml` if applicable 5. **Add tests** in `src/tests/` -### Adding a New Smart Contract Facet +### Adding a New Smart Contract -1. **Create facet contract** in `chain/src/facets/` -2. **Define storage** in `chain/src/libraries/Storage.sol` -3. **Add deployment script** in `chain/script/` +1. **Create contract** in appropriate directory (`chain/src/core/`, `chain/src/facets/`, etc.) +2. **Define storage** if needed in `chain/src/core/Storage.sol` +3. **Add deployment script** in `chain/script/` if needed 4. **Update factory** if needed 5. **Add tests** in `chain/test/` @@ -449,7 +444,6 @@ This removes all test data from MongoDB. - [OpenAPI Specification](./docs/openapi.yaml) - API specification - [Data Model Documentation](./docs/DATA_MODEL.md) - Database schema -- [Diamond Pattern Documentation](./docs/DIAMOND_PATTERN.md) - Smart contract architecture - [Configuration Guide](./CONFIG.md) - Environment configuration - [Foundry Book](https://book.getfoundry.sh/) - Foundry documentation - [OCF Standard](https://github.com/Open-Cap-Table-Coalition/Open-Cap-Format-OCF) - Open Cap Table Format specification diff --git a/TESTING.md b/TESTING.md index 660017f9..91cd4676 100644 --- a/TESTING.md +++ b/TESTING.md @@ -134,7 +134,7 @@ yarn test:js # API tests ### Test Setup -Smart contract tests extend `DiamondTestBase` which provides: +Smart contract tests extend a base test contract which provides: - Deployed factory and cap table contracts - Helper functions for creating stakeholders, stock classes, etc. @@ -149,7 +149,7 @@ pragma solidity ^0.8.0; import "./TestBase.sol"; import { IStockFacet } from "@interfaces/IStockFacet.sol"; -contract MyTest is DiamondTestBase { +contract MyTest is TestBase { function testMyFeature() public { // Test code here } @@ -221,7 +221,7 @@ vm.expectCall(address(target), abi.encodeWithSelector(...)); ### Test Helpers -The `DiamondTestBase` contract provides helper functions: +The base test contract provides helper functions: ```solidity // Create a stakeholder diff --git a/llms.txt b/llms.txt index 3480920a..f1a39fa7 100644 --- a/llms.txt +++ b/llms.txt @@ -9,7 +9,7 @@ - **Framework**: Express.js (Node.js) + TypeScript - **Database**: MongoDB (Mongoose ODM) -- **Blockchain**: Solidity (Foundry) with Diamond pattern architecture +- **Blockchain**: Solidity (Foundry) - **Runtime**: Node.js v22+ with ES modules - **Package Manager**: Yarn 4 - **Testing**: Jest (API) + Forge (Smart Contracts) @@ -17,32 +17,25 @@ ## Architecture Patterns -### Diamond Pattern -- **Diamond Contract**: Main entry point delegating to facets -- **Facets**: Modular implementation contracts (Issuer, Stakeholder, StockClass, StockPlan, etc.) -- **Shared Storage**: Single storage structure accessible by all facets -- See `docs/DIAMOND_PATTERN.md` for details - See [ARCHITECTURE.md](ARCHITECTURE.md) for architecture overview. ## File Structure Overview See [README.md](README.md) for complete project structure. Key directories: -- `chain/` - Smart contracts (Diamond pattern with facets) +- `chain/` - Smart contracts - `src/` - API server (Express.js + MongoDB) - `routes/` - API route handlers - `controllers/` - Business logic - `db/` - MongoDB models and operations - `chain-operations/` - Blockchain interaction utilities - `utils/` - Utility functions -- `docs/` - Documentation (DATA_MODEL.md, DIAMOND_PATTERN.md, etc.) +- `docs/` - Documentation ## ADR Quick Reference | ADR | Decision | What This Means for Development | |-----|----------|--------------------------------| -| N/A | Diamond Pattern | **All smart contracts use Diamond pattern**. New facets must follow existing facet structure. | | N/A | OCF Standard | **All data must validate against OCF schemas**. Use `validateInputAgainstOCF()` before saving. | | N/A | Multi-Chain | **Always pass `chain_id` for issuer creation**. Use `getChainConfig()` for chain-specific operations. | | N/A | Event Sync | **WebSocket listeners auto-sync events**. Don't manually sync - listeners handle it. | @@ -181,7 +174,6 @@ See [DEVELOPER_GUIDE.md](DEVELOPER_GUIDE.md) for complete development workflow, **Technical documentation:** - [docs/DATA_MODEL.md](docs/DATA_MODEL.md) - Database schema -- [docs/DIAMOND_PATTERN.md](docs/DIAMOND_PATTERN.md) - Smart contract architecture - [docs/openapi.yaml](docs/openapi.yaml) - API specification - [CONTRIBUTING.md](CONTRIBUTING.md) - Contribution guidelines