diff --git a/.beads/.local_version b/.beads/.local_version index 36328c43d..76d0ef9d1 100644 --- a/.beads/.local_version +++ b/.beads/.local_version @@ -1 +1 @@ -0.49.1 +0.49.6 diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index e8a438f91..573ebe00a 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -5,6 +5,7 @@ This project is the Demos Network node/RPC implementation. We use **bd (beads)** for all task tracking. **Key Features:** + - Dependency-aware issue tracking - Auto-sync with Git via JSONL - AI-optimized CLI with JSON output diff --git a/.github/workflows/claude-merge-fix.yml b/.github/workflows/claude-merge-fix.yml index e20500f94..379ab3e61 100644 --- a/.github/workflows/claude-merge-fix.yml +++ b/.github/workflows/claude-merge-fix.yml @@ -1,66 +1,66 @@ name: Preserve Claude Memory Files on: - push: - branches: ['**'] + push: + branches: ["**"] jobs: - preserve-claude: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 2 - token: ${{ secrets.GITHUB_TOKEN }} + preserve-claude: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 2 + token: ${{ secrets.GITHUB_TOKEN }} - - name: Check if this was a merge commit - id: check_merge - run: | - if git log -1 --pretty=format:"%P" | grep -q " "; then - echo "is_merge=true" >> $GITHUB_OUTPUT - echo "✅ Detected merge commit" - else - echo "is_merge=false" >> $GITHUB_OUTPUT - exit 0 - fi + - name: Check if this was a merge commit + id: check_merge + run: | + if git log -1 --pretty=format:"%P" | grep -q " "; then + echo "is_merge=true" >> $GITHUB_OUTPUT + echo "✅ Detected merge commit" + else + echo "is_merge=false" >> $GITHUB_OUTPUT + exit 0 + fi - - name: Check for .claude changes in merge - if: steps.check_merge.outputs.is_merge == 'true' - id: check_claude - run: | - if git log -1 --name-only | grep -q "^\.claude/"; then - echo "claude_changed=true" >> $GITHUB_OUTPUT - echo "🚨 .claude files were modified in merge - will revert!" - else - echo "claude_changed=false" >> $GITHUB_OUTPUT - exit 0 - fi + - name: Check for .claude changes in merge + if: steps.check_merge.outputs.is_merge == 'true' + id: check_claude + run: | + if git log -1 --name-only | grep -q "^\.claude/"; then + echo "claude_changed=true" >> $GITHUB_OUTPUT + echo "🚨 .claude files were modified in merge - will revert!" + else + echo "claude_changed=false" >> $GITHUB_OUTPUT + exit 0 + fi - - name: Revert .claude to pre-merge state - if: steps.check_merge.outputs.is_merge == 'true' && steps.check_claude.outputs.claude_changed == 'true' - run: | - CURRENT_BRANCH=$(git branch --show-current) - echo "🔄 Reverting .claude/ to pre-merge state on $CURRENT_BRANCH" - - MERGE_BASE=$(git log -1 --pretty=format:"%P" | cut -d' ' -f1) - git checkout $MERGE_BASE -- .claude/ 2>/dev/null || echo "No .claude in base commit" - - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - - if git diff --staged --quiet; then - git add .claude/ - fi - - if ! git diff --cached --quiet; then - git commit -m "🔒 Preserve branch-specific .claude files + - name: Revert .claude to pre-merge state + if: steps.check_merge.outputs.is_merge == 'true' && steps.check_claude.outputs.claude_changed == 'true' + run: | + CURRENT_BRANCH=$(git branch --show-current) + echo "🔄 Reverting .claude/ to pre-merge state on $CURRENT_BRANCH" - Reverted .claude/ changes from merge to keep $CURRENT_BRANCH version. - [skip ci]" - - git push origin $CURRENT_BRANCH - echo "✅ Successfully preserved $CURRENT_BRANCH .claude files" - else - echo "â„šī¸ No changes to revert" - fi + MERGE_BASE=$(git log -1 --pretty=format:"%P" | cut -d' ' -f1) + git checkout $MERGE_BASE -- .claude/ 2>/dev/null || echo "No .claude in base commit" + + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + if git diff --staged --quiet; then + git add .claude/ + fi + + if ! git diff --cached --quiet; then + git commit -m "🔒 Preserve branch-specific .claude files + + Reverted .claude/ changes from merge to keep $CURRENT_BRANCH version. + [skip ci]" + + git push origin $CURRENT_BRANCH + echo "✅ Successfully preserved $CURRENT_BRANCH .claude files" + else + echo "â„šī¸ No changes to revert" + fi diff --git a/.github/workflows/claude-merge-notify.yml b/.github/workflows/claude-merge-notify.yml index f32480ca7..95949b380 100644 --- a/.github/workflows/claude-merge-notify.yml +++ b/.github/workflows/claude-merge-notify.yml @@ -1,38 +1,38 @@ name: Claude PR Warning on: - pull_request: - branches: ['**'] - types: [opened, synchronize] + pull_request: + branches: ["**"] + types: [opened, synchronize] jobs: - claude-warning: - runs-on: ubuntu-latest - steps: - - name: Checkout PR - uses: actions/checkout@v4 - with: - fetch-depth: 0 + claude-warning: + runs-on: ubuntu-latest + steps: + - name: Checkout PR + uses: actions/checkout@v4 + with: + fetch-depth: 0 - - name: Check for .claude changes - run: | - echo "🔍 Checking if PR touches .claude/ files..." - - if git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -q "^\.claude/"; then - echo "âš ī¸ This PR modifies .claude/ files" - - COMMENT_BODY="âš ī¸ **Claude Memory Files Detected** + - name: Check for .claude changes + run: | + echo "🔍 Checking if PR touches .claude/ files..." - This PR modifies \`.claude/\` files. After merge, these changes will be **automatically reverted** to preserve branch-specific Claude conversation context. + if git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -q "^\.claude/"; then + echo "âš ī¸ This PR modifies .claude/ files" + + COMMENT_BODY="âš ī¸ **Claude Memory Files Detected** - **Files that will be reverted:** - $(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep '^\.claude/' | sed 's/^/- /' | head -10) + This PR modifies \`.claude/\` files. After merge, these changes will be **automatically reverted** to preserve branch-specific Claude conversation context. - This is expected behavior to keep Claude conversation context branch-specific. ✅" - - gh pr comment ${{ github.event.number }} --body "$COMMENT_BODY" || echo "Could not post comment" - else - echo "✅ No .claude files affected" - fi - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + **Files that will be reverted:** + $(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep '^\.claude/' | sed 's/^/- /' | head -10) + + This is expected behavior to keep Claude conversation context branch-specific. ✅" + + gh pr comment ${{ github.event.number }} --body "$COMMENT_BODY" || echo "Could not post comment" + else + echo "✅ No .claude files affected" + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/fix-beads-conflicts.yml b/.github/workflows/fix-beads-conflicts.yml index c71d8fa6f..2d37f5942 100644 --- a/.github/workflows/fix-beads-conflicts.yml +++ b/.github/workflows/fix-beads-conflicts.yml @@ -1,73 +1,73 @@ name: Preserve Branch-Specific Beads Files on: - push: - branches: ['**'] + push: + branches: ["**"] jobs: - preserve-beads: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 2 - token: ${{ secrets.GITHUB_TOKEN }} + preserve-beads: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 2 + token: ${{ secrets.GITHUB_TOKEN }} - - name: Check if this was a merge commit - id: check_merge - run: | - if git log -1 --pretty=format:"%P" | grep -q " "; then - echo "is_merge=true" >> $GITHUB_OUTPUT - echo "✅ Detected merge commit" - else - echo "is_merge=false" >> $GITHUB_OUTPUT - exit 0 - fi + - name: Check if this was a merge commit + id: check_merge + run: | + if git log -1 --pretty=format:"%P" | grep -q " "; then + echo "is_merge=true" >> $GITHUB_OUTPUT + echo "✅ Detected merge commit" + else + echo "is_merge=false" >> $GITHUB_OUTPUT + exit 0 + fi - - name: Check for .beads changes in merge - if: steps.check_merge.outputs.is_merge == 'true' - id: check_beads - run: | - if git log -1 --name-only | grep -qE "^\.beads/(issues\.jsonl|deletions\.jsonl|metadata\.json)$"; then - echo "beads_changed=true" >> $GITHUB_OUTPUT - echo "🚨 .beads files were modified in merge - will revert!" - else - echo "beads_changed=false" >> $GITHUB_OUTPUT - exit 0 - fi + - name: Check for .beads changes in merge + if: steps.check_merge.outputs.is_merge == 'true' + id: check_beads + run: | + if git log -1 --name-only | grep -qE "^\.beads/(issues\.jsonl|deletions\.jsonl|metadata\.json)$"; then + echo "beads_changed=true" >> $GITHUB_OUTPUT + echo "🚨 .beads files were modified in merge - will revert!" + else + echo "beads_changed=false" >> $GITHUB_OUTPUT + exit 0 + fi - - name: Revert .beads to pre-merge state - if: steps.check_merge.outputs.is_merge == 'true' && steps.check_beads.outputs.beads_changed == 'true' - run: | - CURRENT_BRANCH=$(git branch --show-current) - echo "🔄 Reverting .beads/ issue tracking files to pre-merge state on $CURRENT_BRANCH" + - name: Revert .beads to pre-merge state + if: steps.check_merge.outputs.is_merge == 'true' && steps.check_beads.outputs.beads_changed == 'true' + run: | + CURRENT_BRANCH=$(git branch --show-current) + echo "🔄 Reverting .beads/ issue tracking files to pre-merge state on $CURRENT_BRANCH" - # Get the first parent (target branch before merge) - MERGE_BASE=$(git log -1 --pretty=format:"%P" | cut -d' ' -f1) + # Get the first parent (target branch before merge) + MERGE_BASE=$(git log -1 --pretty=format:"%P" | cut -d' ' -f1) - # Restore specific .beads files from the target branch's state before merge - git checkout $MERGE_BASE -- .beads/issues.jsonl 2>/dev/null || echo "No issues.jsonl in base commit" - git checkout $MERGE_BASE -- .beads/deletions.jsonl 2>/dev/null || echo "No deletions.jsonl in base commit" - git checkout $MERGE_BASE -- .beads/metadata.json 2>/dev/null || echo "No metadata.json in base commit" + # Restore specific .beads files from the target branch's state before merge + git checkout $MERGE_BASE -- .beads/issues.jsonl 2>/dev/null || echo "No issues.jsonl in base commit" + git checkout $MERGE_BASE -- .beads/deletions.jsonl 2>/dev/null || echo "No deletions.jsonl in base commit" + git checkout $MERGE_BASE -- .beads/metadata.json 2>/dev/null || echo "No metadata.json in base commit" - # Configure git - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + # Configure git + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - # Commit the reversion - if git diff --staged --quiet; then - git add .beads/issues.jsonl .beads/deletions.jsonl .beads/metadata.json 2>/dev/null || true - fi + # Commit the reversion + if git diff --staged --quiet; then + git add .beads/issues.jsonl .beads/deletions.jsonl .beads/metadata.json 2>/dev/null || true + fi - if ! git diff --cached --quiet; then - git commit -m "🔒 Preserve branch-specific .beads issue tracking files + if ! git diff --cached --quiet; then + git commit -m "🔒 Preserve branch-specific .beads issue tracking files - Reverted .beads/ changes from merge to keep $CURRENT_BRANCH version intact. - [skip ci]" + Reverted .beads/ changes from merge to keep $CURRENT_BRANCH version intact. + [skip ci]" - git push origin $CURRENT_BRANCH - echo "✅ Successfully preserved $CURRENT_BRANCH .beads files" - else - echo "â„šī¸ No changes to revert" - fi + git push origin $CURRENT_BRANCH + echo "✅ Successfully preserved $CURRENT_BRANCH .beads files" + else + echo "â„šī¸ No changes to revert" + fi diff --git a/.github/workflows/fix-serena-conflicts.yml b/.github/workflows/fix-serena-conflicts.yml index 00a4ad53d..81fffa883 100644 --- a/.github/workflows/fix-serena-conflicts.yml +++ b/.github/workflows/fix-serena-conflicts.yml @@ -1,71 +1,71 @@ name: Preserve Branch-Specific Serena Files on: - push: - branches: ['**'] + push: + branches: ["**"] jobs: - preserve-serena: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 2 - token: ${{ secrets.GITHUB_TOKEN }} + preserve-serena: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 2 + token: ${{ secrets.GITHUB_TOKEN }} - - name: Check if this was a merge commit - id: check_merge - run: | - if git log -1 --pretty=format:"%P" | grep -q " "; then - echo "is_merge=true" >> $GITHUB_OUTPUT - echo "✅ Detected merge commit" - else - echo "is_merge=false" >> $GITHUB_OUTPUT - exit 0 - fi + - name: Check if this was a merge commit + id: check_merge + run: | + if git log -1 --pretty=format:"%P" | grep -q " "; then + echo "is_merge=true" >> $GITHUB_OUTPUT + echo "✅ Detected merge commit" + else + echo "is_merge=false" >> $GITHUB_OUTPUT + exit 0 + fi - - name: Check for .serena changes in merge - if: steps.check_merge.outputs.is_merge == 'true' - id: check_serena - run: | - if git log -1 --name-only | grep -q "^\.serena/"; then - echo "serena_changed=true" >> $GITHUB_OUTPUT - echo "🚨 .serena files were modified in merge - will revert!" - else - echo "serena_changed=false" >> $GITHUB_OUTPUT - exit 0 - fi + - name: Check for .serena changes in merge + if: steps.check_merge.outputs.is_merge == 'true' + id: check_serena + run: | + if git log -1 --name-only | grep -q "^\.serena/"; then + echo "serena_changed=true" >> $GITHUB_OUTPUT + echo "🚨 .serena files were modified in merge - will revert!" + else + echo "serena_changed=false" >> $GITHUB_OUTPUT + exit 0 + fi - - name: Revert .serena to pre-merge state - if: steps.check_merge.outputs.is_merge == 'true' && steps.check_serena.outputs.serena_changed == 'true' - run: | - CURRENT_BRANCH=$(git branch --show-current) - echo "🔄 Reverting .serena/ to pre-merge state on $CURRENT_BRANCH" - - # Get the first parent (target branch before merge) - MERGE_BASE=$(git log -1 --pretty=format:"%P" | cut -d' ' -f1) - - # Restore .serena from the target branch's state before merge - git checkout $MERGE_BASE -- .serena/ 2>/dev/null || echo "No .serena in base commit" - - # Configure git - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - - # Commit the reversion - if git diff --staged --quiet; then - git add .serena/ - fi - - if ! git diff --cached --quiet; then - git commit -m "🔒 Preserve branch-specific .serena files + - name: Revert .serena to pre-merge state + if: steps.check_merge.outputs.is_merge == 'true' && steps.check_serena.outputs.serena_changed == 'true' + run: | + CURRENT_BRANCH=$(git branch --show-current) + echo "🔄 Reverting .serena/ to pre-merge state on $CURRENT_BRANCH" - Reverted .serena/ changes from merge to keep $CURRENT_BRANCH version intact. - [skip ci]" - - git push origin $CURRENT_BRANCH - echo "✅ Successfully preserved $CURRENT_BRANCH .serena files" - else - echo "â„šī¸ No changes to revert" - fi + # Get the first parent (target branch before merge) + MERGE_BASE=$(git log -1 --pretty=format:"%P" | cut -d' ' -f1) + + # Restore .serena from the target branch's state before merge + git checkout $MERGE_BASE -- .serena/ 2>/dev/null || echo "No .serena in base commit" + + # Configure git + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + # Commit the reversion + if git diff --staged --quiet; then + git add .serena/ + fi + + if ! git diff --cached --quiet; then + git commit -m "🔒 Preserve branch-specific .serena files + + Reverted .serena/ changes from merge to keep $CURRENT_BRANCH version intact. + [skip ci]" + + git push origin $CURRENT_BRANCH + echo "✅ Successfully preserved $CURRENT_BRANCH .serena files" + else + echo "â„šī¸ No changes to revert" + fi diff --git a/.github/workflows/notify-beads-merging.yml b/.github/workflows/notify-beads-merging.yml index e47ffbaa7..d8472a2a1 100644 --- a/.github/workflows/notify-beads-merging.yml +++ b/.github/workflows/notify-beads-merging.yml @@ -1,37 +1,37 @@ name: Beads Merge Warning on: - pull_request: - branches: ['**'] + pull_request: + branches: ["**"] jobs: - beads-warning: - runs-on: ubuntu-latest - steps: - - name: Check for .beads changes - uses: actions/checkout@v4 - with: - fetch-depth: 0 + beads-warning: + runs-on: ubuntu-latest + steps: + - name: Check for .beads changes + uses: actions/checkout@v4 + with: + fetch-depth: 0 - - name: Warn about .beads files - run: | - # Check if PR touches .beads issue tracking files - if git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -qE "^\.beads/(issues\.jsonl|deletions\.jsonl|metadata\.json)$"; then - echo "âš ī¸ This PR modifies .beads/ issue tracking files" - echo "🤖 After merge, these will be auto-reverted to preserve branch-specific issues" - echo "" - echo "Files affected:" - git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -E "^\.beads/(issues\.jsonl|deletions\.jsonl|metadata\.json)$" | sed 's/^/ - /' + - name: Warn about .beads files + run: | + # Check if PR touches .beads issue tracking files + if git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -qE "^\.beads/(issues\.jsonl|deletions\.jsonl|metadata\.json)$"; then + echo "âš ī¸ This PR modifies .beads/ issue tracking files" + echo "🤖 After merge, these will be auto-reverted to preserve branch-specific issues" + echo "" + echo "Files affected:" + git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -E "^\.beads/(issues\.jsonl|deletions\.jsonl|metadata\.json)$" | sed 's/^/ - /' - # Post comment on PR - gh pr comment ${{ github.event.number }} --body "âš ī¸ **Beads Issue Tracking Files Detected** + # Post comment on PR + gh pr comment ${{ github.event.number }} --body "âš ī¸ **Beads Issue Tracking Files Detected** - This PR modifies \`.beads/\` issue tracking files. After merge, these changes will be **automatically reverted** to preserve branch-specific issue tracking. + This PR modifies \`.beads/\` issue tracking files. After merge, these changes will be **automatically reverted** to preserve branch-specific issue tracking. - Files that will be reverted: - $(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -E '^\.beads/(issues\.jsonl|deletions\.jsonl|metadata\.json)$' | sed 's/^/- /')" || echo "Could not post comment" - else - echo "✅ No .beads issue tracking files affected" - fi - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + Files that will be reverted: + $(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -E '^\.beads/(issues\.jsonl|deletions\.jsonl|metadata\.json)$' | sed 's/^/- /')" || echo "Could not post comment" + else + echo "✅ No .beads issue tracking files affected" + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/notify-serena-merging.yml b/.github/workflows/notify-serena-merging.yml index 8d52a163a..60cf891ee 100644 --- a/.github/workflows/notify-serena-merging.yml +++ b/.github/workflows/notify-serena-merging.yml @@ -1,37 +1,37 @@ name: Serena Merge Warning on: - pull_request: - branches: ['**'] + pull_request: + branches: ["**"] jobs: - serena-warning: - runs-on: ubuntu-latest - steps: - - name: Check for .serena changes - uses: actions/checkout@v4 - with: - fetch-depth: 0 + serena-warning: + runs-on: ubuntu-latest + steps: + - name: Check for .serena changes + uses: actions/checkout@v4 + with: + fetch-depth: 0 - - name: Warn about .serena files - run: | - # Check if PR touches .serena files - if git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -q "^\.serena/"; then - echo "âš ī¸ This PR modifies .serena/ files" - echo "🤖 After merge, these will be auto-reverted to preserve branch-specific memories" - echo "" - echo "Files affected:" - git diff --name-only origin/${{ github.base_ref }}...HEAD | grep "^\.serena/" | sed 's/^/ - /' - - # Post comment on PR - gh pr comment ${{ github.event.number }} --body "âš ī¸ **MCP Memory Files Detected** + - name: Warn about .serena files + run: | + # Check if PR touches .serena files + if git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -q "^\.serena/"; then + echo "âš ī¸ This PR modifies .serena/ files" + echo "🤖 After merge, these will be auto-reverted to preserve branch-specific memories" + echo "" + echo "Files affected:" + git diff --name-only origin/${{ github.base_ref }}...HEAD | grep "^\.serena/" | sed 's/^/ - /' + + # Post comment on PR + gh pr comment ${{ github.event.number }} --body "âš ī¸ **MCP Memory Files Detected** - This PR modifies \`.serena/\` files. After merge, these changes will be **automatically reverted** to preserve branch-specific MCP memories. + This PR modifies \`.serena/\` files. After merge, these changes will be **automatically reverted** to preserve branch-specific MCP memories. - Files that will be reverted: - $(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep '^\.serena/' | sed 's/^/- /')" || echo "Could not post comment" - else - echo "✅ No .serena files affected" - fi - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + Files that will be reverted: + $(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep '^\.serena/' | sed 's/^/- /')" || echo "Could not post comment" + else + echo "✅ No .serena files affected" + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 1372b760c..e461cee70 100644 --- a/.gitignore +++ b/.gitignore @@ -181,8 +181,8 @@ docs/src src/features/bridges/EVMSmartContract/docs src/features/bridges/LiquidityTank_UserGuide.md local_tests +local_tests/ claudedocs -docs/storage_features temp STORAGE_PROGRAMS_SPEC.md omniprotocol_fixtures_scripts @@ -263,4 +263,14 @@ src/features/tlsnotary/SDK_INTEGRATION.md src/features/tlsnotary/SDK_INTEGRATION.md ipfs/data_53550/ipfs nohup.out -*.db +\*.db +/internal-docs +/.beads/beads.db-shm +/.beads/beads.db-shm +/.beads/beads.db-wal +/.beads/daemon.log +/.beads/beads.db + +documentation/Demos_ Technical Design Decisions.pdf +documentation/demos_yp_v5.odt +documentation/demos_yp_v5.pdf diff --git a/.serena/memories/_continue_here.md b/.serena/memories/_continue_here.md index ad70d036c..8ca5cb090 100644 --- a/.serena/memories/_continue_here.md +++ b/.serena/memories/_continue_here.md @@ -1,26 +1,32 @@ # Continue Here - Last Session: 2025-12-17 ## Last Activity + TypeScript type audit completed successfully. ## Status + - **Branch**: custom_protocol - **Type errors**: 0 production, 2 test-only (fhe_test.ts - not planned) - **Epic node-tsaudit**: CLOSED ## Recent Commits + - `c684bb2a` - fix: remove dead crypto code and fix showPubkey type - `20137452` - fix: resolve OmniProtocol type errors - `fc5abb9e` - fix: resolve 22 TypeScript type errors ## Key Memories + - `typescript_audit_complete_2025_12_17` - Full audit details and patterns ## Previous Work (2025-12-16) + - Console.log migration epic COMPLETE (node-7d8) - OmniProtocol 90% complete (node-99g) ## Ready For + - New feature development - Further code quality improvements - Any pending tasks in beads diff --git a/.serena/memories/_index.md b/.serena/memories/_index.md index a8667419e..32c7321bf 100644 --- a/.serena/memories/_index.md +++ b/.serena/memories/_index.md @@ -1,15 +1,18 @@ # Serena Memory Index - Quick Navigation ## Current Work (Start Here) -- **_continue_here** - Active work streams and next actions + +- **\_continue_here** - Active work streams and next actions ## OmniProtocol Implementation + - **omniprotocol_complete_2025_11_11** - Comprehensive status (90% complete) - **omniprotocol_wave8_tcp_physical_layer** - TCP layer implementation - **omniprotocol_wave8.1_complete** - Wave 8.1 completion details - **omniprotocol_session_2025-12-01** - Recent session notes ## UD Integration + - **ud_phases_tracking** - Complete phases 1-6 overview - **ud_phase5_complete** - Detailed Phase 5 implementation - **ud_integration_complete** - Current status, dependencies, next steps @@ -20,12 +23,13 @@ - **session_ud_points_implementation_2025_01_31** - Points system session ## Project Core + - **project_purpose** - Demos Network node software overview -- **Codebase Map** - See `.planning/codebase/` (7 documents, replaces old Serena memories): - - `STACK.md` - Runtime, dependencies, frameworks (was: tech_stack) - - `STRUCTURE.md` - Directory layout, file purposes (was: codebase_structure) - - `CONVENTIONS.md` - Code style, naming, linting (was: code_style_conventions) - - `ARCHITECTURE.md` - System layers, data flows, patterns (was: development_patterns) +- **Codebase Map** - See `.planning/codebase/` (7 documents): + - `STACK.md` - Runtime, dependencies, frameworks + - `STRUCTURE.md` - Directory layout, file purposes + - `CONVENTIONS.md` - Code style, naming, linting + - `ARCHITECTURE.md` - System layers, data flows, patterns - `INTEGRATIONS.md` - External APIs, blockchain networks, protocols - `TESTING.md` - Jest config, mock patterns, coverage - - `CONCERNS.md` - Tech debt, security issues, missing features \ No newline at end of file + - `CONCERNS.md` - Tech debt, security issues, missing features diff --git a/.serena/memories/devnet_docker_setup.md b/.serena/memories/devnet_docker_setup.md index 943843b62..0f52eb34f 100644 --- a/.serena/memories/devnet_docker_setup.md +++ b/.serena/memories/devnet_docker_setup.md @@ -1,14 +1,17 @@ # Devnet Docker Compose Setup ## Overview + A Docker Compose setup for running 4 Demos Network nodes locally, replacing the need for 4 VPSes during development. ## Location + `/devnet/` directory in the main repository. ## Key Components ### Files + - `docker-compose.yml` - Orchestrates postgres + 4 nodes - `Dockerfile` - Bun-based image with native module support - `run-devnet` - Simplified node runner (no git, bun install, postgres management) @@ -18,7 +21,9 @@ A Docker Compose setup for running 4 Demos Network nodes locally, replacing the - `scripts/generate-peerlist.sh` - Creates demos_peerlist.json with Docker hostnames ### Environment Variables for Nodes + Each node requires: + - `PG_HOST` - PostgreSQL hostname (default: postgres) - `PG_PORT` - PostgreSQL port (default: 5432) - `PG_USER`, `PG_PASSWORD`, `PG_DATABASE` @@ -27,23 +32,27 @@ Each node requires: - `EXPOSED_URL` - Self URL for peer discovery (e.g., `http://node-1:53551`) ### Port Mapping + | Node | RPC Port | Omni Port | -|--------|----------|-----------| +| ------ | -------- | --------- | | node-1 | 53551 | 53561 | | node-2 | 53552 | 53562 | | node-3 | 53553 | 53563 | | node-4 | 53554 | 53564 | ## Build Optimization + - Uses BuildKit: `DOCKER_BUILDKIT=1 docker-compose build` - Layer caching: package.json copied first, deps installed, then rest - Native modules: `bufferutil`, `utf-8-validate` compiled with build-essential + python3-setuptools ## Related Changes + - `src/model/datasource.ts` - Added env var support for external DB - `./run` - Added `--external-db` / `-e` flag ## Usage + ```bash cd devnet ./scripts/setup.sh # One-time setup diff --git a/.serena/memories/feature_storage_programs_plan.md b/.serena/memories/feature_storage_programs_plan.md new file mode 100644 index 000000000..8b5189b7f --- /dev/null +++ b/.serena/memories/feature_storage_programs_plan.md @@ -0,0 +1,122 @@ +# StoragePrograms Feature Plan + +## Summary + +Unified storage solution for Demos Network supporting both JSON (structured) and Binary (raw) data with robust ACL and size-based pricing. + +## Design Decision + +Single unified StorageProgram with `encoding: "json" | "binary"` parameter. Both encodings share identical features. + +## Core Specifications + +### Limits & Pricing + +- **Max Size**: 1MB (1,048,576 bytes) for both encodings +- **Pricing**: 1 DEM per 10KB (minimum 1 DEM) +- **JSON Nesting**: Max 64 levels depth + +### Access Control (ACL) + +```typescript +interface StorageProgramACL { + mode: "owner" | "public" | "restricted" + owner: string // Always has full access + allowed?: string[] // Explicitly allowed addresses + blacklisted?: string[] // Blocked (highest priority) + groups?: Record< + string, + { + members: string[] + permissions: ("read" | "write" | "delete")[] + } + > +} +``` + +**ACL Resolution Priority**: + +1. Owner → FULL ACCESS (always) +2. Blacklisted → DENIED (even if in allowed/groups) +3. Allowed → permissions granted +4. Groups → check group permissions +5. Mode fallback: owner/restricted → DENIED, public → READ only + +### Operations + +- CREATE_STORAGE_PROGRAM +- WRITE_STORAGE +- READ_STORAGE +- UPDATE_ACCESS_CONTROL +- DELETE_STORAGE_PROGRAM + +### Storage + +- **Location**: On-chain (PostgreSQL) initially +- **IPFS**: Stubs ready for future hybrid storage +- **Retention**: Permanent, owner/ACL-deletable only +- **Legacy**: Old Storage transactions kept for retrocompatibility + +## Key Files + +### SDK (../sdks) + +- `src/types/blockchain/TransactionSubtypes/StorageProgramTransaction.ts` - Types +- `src/storage/StorageProgram.ts` - Main class + +### Node + +- `src/model/entities/GCRv2/GCR_StorageProgram.ts` - Entity (new) +- `src/libs/blockchain/gcr/handleGCR.ts` - Handler implementation +- Confirm flow validation in transaction handlers + +## Database Schema + +```sql +CREATE TABLE gcr_storage_programs ( + "storageAddress" TEXT PRIMARY KEY, + "owner" TEXT NOT NULL, + "programName" TEXT NOT NULL, + "encoding" TEXT NOT NULL, -- 'json' | 'binary' + "data" TEXT NOT NULL, + "sizeBytes" INTEGER NOT NULL, + "acl" JSONB NOT NULL, + "metadata" JSONB DEFAULT '{}', + "storageLocation" TEXT DEFAULT 'onchain', + "ipfsCid" TEXT, -- STUB for future + "salt" TEXT DEFAULT '', + "createdByTx" TEXT NOT NULL, + "lastModifiedByTx" TEXT NOT NULL, + "totalFeesPaid" BIGINT NOT NULL, + "createdAt" TIMESTAMP, + "updatedAt" TIMESTAMP +); +``` + +## Implementation Guidelines + +- **Elegant**: Clean, readable code following existing patterns +- **Maintainable**: Well-documented, consistent with codebase style +- **No overengineering**: Simple solutions, YAGNI principle +- **Use existing patterns**: Follow TLSNotary, IPFS handler patterns + +## Related + +- feature_ipfs_transactions (similar pricing model) +- arch_gcr_entities (entity patterns) +- Legacy StorageTransaction.ts (retrocompat) + +## SDK Workflow Reminder + +**CRITICAL**: After ANY changes to `../sdks`: + +1. Run `bun run build` in ../sdks +2. Commit changes +3. Push to remote +4. **STOP AND TELL USER TO PUBLISH NEW VERSION** before continuing with node work + +This ensures the node can use the updated SDK types. + +## Last Updated + +2026-01-13 - Initial planning document diff --git a/.serena/memories/omniprotocol_complete_2025_11_11.md b/.serena/memories/omniprotocol_complete_2025_11_11.md index 218c8a1ae..5afeeab68 100644 --- a/.serena/memories/omniprotocol_complete_2025_11_11.md +++ b/.serena/memories/omniprotocol_complete_2025_11_11.md @@ -24,6 +24,7 @@ OmniProtocol replaces HTTP JSON-RPC with a **custom binary TCP protocol** for no ## Architecture Overview ### Message Format + ``` [12-byte header] + [optional auth block] + [payload] + [4-byte CRC32] @@ -34,6 +35,7 @@ Checksum: CRC32 validation ``` ### Connection Flow + ``` Client Server | | @@ -62,6 +64,7 @@ Client Server ### ✅ 100% Complete Components #### 1. Authentication System + - **Ed25519 signature verification** using @noble/ed25519 - **Timestamp-based replay protection** (Âą5 minute window) - **5 signature modes** (SIGN_PUBKEY, SIGN_MESSAGE_ID, SIGN_FULL_PAYLOAD, etc.) @@ -70,11 +73,13 @@ Client Server - **Automatic verification** in dispatcher middleware **Files**: + - `src/libs/omniprotocol/auth/types.ts` (90 lines) - `src/libs/omniprotocol/auth/parser.ts` (120 lines) - `src/libs/omniprotocol/auth/verifier.ts` (150 lines) #### 2. TCP Server Infrastructure + - **OmniProtocolServer** - Main TCP listener with event-driven architecture - **ServerConnectionManager** - Connection lifecycle management - **InboundConnection** - Per-connection handler with state machine @@ -84,11 +89,13 @@ Client Server - **Graceful startup and shutdown** **Files**: + - `src/libs/omniprotocol/server/OmniProtocolServer.ts` (220 lines) - `src/libs/omniprotocol/server/ServerConnectionManager.ts` (180 lines) - `src/libs/omniprotocol/server/InboundConnection.ts` (260 lines) #### 3. TLS/SSL Encryption + - **Certificate generation** using openssl (self-signed) - **Certificate validation** and expiry checking - **TLSServer** - TLS-wrapped TCP server @@ -99,6 +106,7 @@ Client Server - **Connection factory** for tcp:// vs tls:// routing **Files**: + - `src/libs/omniprotocol/tls/types.ts` (70 lines) - `src/libs/omniprotocol/tls/certificates.ts` (210 lines) - `src/libs/omniprotocol/tls/initialize.ts` (95 lines) @@ -107,6 +115,7 @@ Client Server - `src/libs/omniprotocol/transport/ConnectionFactory.ts` (60 lines) #### 4. Rate Limiting (DoS Protection) + - **Per-IP connection limits** (default: 10 concurrent) - **Per-IP request rate limits** (default: 100 req/s) - **Per-identity request rate limits** (default: 200 req/s) @@ -117,10 +126,12 @@ Client Server - **Integrated into both TCP and TLS servers** **Files**: + - `src/libs/omniprotocol/ratelimit/types.ts` (90 lines) - `src/libs/omniprotocol/ratelimit/RateLimiter.ts` (380 lines) #### 5. Message Framing & Transport + - **MessageFramer** - Parse TCP stream into messages - **PeerConnection** - Client-side connection with state machine - **ConnectionPool** - Pool of persistent connections @@ -129,12 +140,14 @@ Client Server - **Automatic reconnection** and error handling **Files**: + - `src/libs/omniprotocol/transport/MessageFramer.ts` (215 lines) - `src/libs/omniprotocol/transport/PeerConnection.ts` (338 lines) - `src/libs/omniprotocol/transport/ConnectionPool.ts` (301 lines) - `src/libs/omniprotocol/transport/types.ts` (162 lines) #### 6. Node Integration + - **Key management** - Integration with getSharedState keypair - **Startup integration** - Server wired into src/index.ts - **Environment variable configuration** @@ -142,6 +155,7 @@ Client Server - **PeerOmniAdapter** - Automatic authentication and HTTP fallback **Files**: + - `src/libs/omniprotocol/integration/keys.ts` (80 lines) - `src/libs/omniprotocol/integration/startup.ts` (180 lines) - `src/libs/omniprotocol/integration/peerAdapter.ts` (modified) @@ -152,22 +166,26 @@ Client Server ### ❌ Not Implemented (10% remaining) #### 1. Testing (0% - CRITICAL GAP) + - ❌ Unit tests (auth, framing, server, TLS, rate limiting) - ❌ Integration tests (client-server roundtrip) - ❌ Load tests (1000+ concurrent connections) #### 2. Metrics & Monitoring + - ❌ Prometheus integration - ❌ Latency tracking - ❌ Throughput monitoring - âš ī¸ Basic stats available via getStats() #### 3. Post-Quantum Cryptography (Optional) + - ❌ Falcon signature verification - ❌ ML-DSA signature verification - âš ī¸ Only Ed25519 supported #### 4. Advanced Features (Optional) + - ❌ Push messages (server-initiated) - ❌ Multiplexing (multiple requests per connection) - ❌ Protocol versioning @@ -177,12 +195,14 @@ Client Server ## Environment Variables ### TCP Server + ```bash OMNI_ENABLED=false # Enable OmniProtocol server OMNI_PORT=3001 # Server port (default: HTTP port + 1) ``` ### TLS/SSL Encryption + ```bash OMNI_TLS_ENABLED=false # Enable TLS OMNI_TLS_MODE=self-signed # self-signed or ca @@ -193,6 +213,7 @@ OMNI_TLS_MIN_VERSION=TLSv1.3 # TLSv1.2 or TLSv1.3 ``` ### Rate Limiting + ```bash OMNI_RATE_LIMIT_ENABLED=true # Default: true OMNI_MAX_CONNECTIONS_PER_IP=10 # Max concurrent per IP @@ -205,16 +226,19 @@ OMNI_MAX_REQUESTS_PER_SECOND_PER_IDENTITY=200 # Max req/s per identity ## Performance Characteristics ### Message Overhead + - **HTTP JSON**: ~500-800 bytes minimum (headers + envelope) - **OmniProtocol**: 12-110 bytes minimum (header + optional auth + checksum) - **Savings**: 60-97% overhead reduction ### Connection Performance + - **HTTP**: New TCP connection per request (~40-120ms handshake) - **OmniProtocol**: Persistent connection (~10-30ms after initial) - **Improvement**: 70-90% latency reduction for subsequent requests ### Scalability Targets + - **1,000 peers**: ~400-800 KB memory - **10,000 peers**: ~4-8 MB memory - **Throughput**: 10,000+ requests/second @@ -224,6 +248,7 @@ OMNI_MAX_REQUESTS_PER_SECOND_PER_IDENTITY=200 # Max req/s per identity ## Security Features ### ✅ Implemented + - Ed25519 signature verification - Timestamp-based replay protection (Âą5 minutes) - Per-handler authentication requirements @@ -238,6 +263,7 @@ OMNI_MAX_REQUESTS_PER_SECOND_PER_IDENTITY=200 # Max req/s per identity - CRC32 checksum validation ### âš ī¸ Gaps + - No nonce tracking (optional additional replay protection) - No comprehensive security audit - No automated testing @@ -253,6 +279,7 @@ OMNI_MAX_REQUESTS_PER_SECOND_PER_IDENTITY=200 # Max req/s per identity **Documentation**: ~8,000 lines ### File Breakdown + - Authentication: 360 lines (3 files) - TCP Server: 660 lines (3 files) - TLS/SSL: 970 lines (6 files) @@ -281,48 +308,52 @@ All commits on branch: `claude/custom-tcp-protocol-011CV1uA6TQDiV9Picft86Y5` ## Next Steps ### P0 - Critical (Before Mainnet) + 1. **Testing Infrastructure** - - Unit tests for all components - - Integration tests (localhost client-server) - - Load tests (1000+ concurrent connections with rate limiting) + - Unit tests for all components + - Integration tests (localhost client-server) + - Load tests (1000+ concurrent connections with rate limiting) 2. **Security Audit** - - Professional security review - - Penetration testing - - Code audit + - Professional security review + - Penetration testing + - Code audit 3. **Monitoring & Observability** - - Prometheus metrics integration - - Latency/throughput tracking - - Error rate monitoring + - Prometheus metrics integration + - Latency/throughput tracking + - Error rate monitoring ### P1 - Important + 4. **Operational Documentation** - - Operator runbook - - Deployment guide - - Troubleshooting guide - - Performance tuning guide + - Operator runbook + - Deployment guide + - Troubleshooting guide + - Performance tuning guide 5. **Connection Health** - - Heartbeat mechanism - - Health check endpoints - - Dead connection detection + - Heartbeat mechanism + - Health check endpoints + - Dead connection detection ### P2 - Optional + 6. **Post-Quantum Cryptography** - - Falcon library integration - - ML-DSA library integration + - Falcon library integration + - ML-DSA library integration 7. **Advanced Features** - - Push messages (server-initiated) - - Protocol versioning - - Connection multiplexing enhancements + - Push messages (server-initiated) + - Protocol versioning + - Connection multiplexing enhancements --- ## Deployment Recommendations ### For Controlled Deployment (Now) + ```bash OMNI_ENABLED=true OMNI_TLS_ENABLED=true # Recommended @@ -330,11 +361,13 @@ OMNI_RATE_LIMIT_ENABLED=true # Default, recommended ``` **Use with**: + - Trusted peer networks - Internal testing environments - Controlled rollout to subset of peers ### For Mainnet Deployment (After Testing) + - ✅ Complete comprehensive testing - ✅ Conduct security audit - ✅ Add Prometheus monitoring @@ -347,15 +380,18 @@ OMNI_RATE_LIMIT_ENABLED=true # Default, recommended ## Documentation Files **Specifications**: + - `OmniProtocol/08_TCP_SERVER_IMPLEMENTATION.md` (1,238 lines) - `OmniProtocol/09_AUTHENTICATION_IMPLEMENTATION.md` (800+ lines) - `OmniProtocol/10_TLS_IMPLEMENTATION_PLAN.md` (383 lines) **Guides**: + - `OMNIPROTOCOL_SETUP.md` (Setup guide) - `OMNIPROTOCOL_TLS_GUIDE.md` (TLS usage guide, 455 lines) **Status Tracking**: + - `src/libs/omniprotocol/IMPLEMENTATION_STATUS.md` (Updated 2025-11-11) - `OmniProtocol/IMPLEMENTATION_SUMMARY.md` (Updated 2025-11-11) @@ -364,22 +400,23 @@ OMNI_RATE_LIMIT_ENABLED=true # Default, recommended ## Known Limitations 1. **JSON Payloads**: Still using JSON envelopes for payload encoding (hybrid format) - - Future: Full binary encoding for 60-70% additional bandwidth savings + - Future: Full binary encoding for 60-70% additional bandwidth savings 2. **Single Connection per Peer**: Default max 1 connection per peer - - Future: Multiple connections for high-traffic peers + - Future: Multiple connections for high-traffic peers 3. **No Push Messages**: Only request-response pattern supported - - Future: Server-initiated push notifications + - Future: Server-initiated push notifications 4. **Limited Observability**: Only basic stats available - - Future: Prometheus metrics, detailed latency tracking + - Future: Prometheus metrics, detailed latency tracking --- ## Success Metrics **Current Achievement**: + - ✅ 90% production-ready - ✅ All critical security features implemented - ✅ DoS protection via rate limiting @@ -388,6 +425,7 @@ OMNI_RATE_LIMIT_ENABLED=true # Default, recommended - ✅ Integrated into node startup **Production Readiness Criteria**: + - [ ] 100% test coverage for critical paths - [ ] Security audit completed - [ ] Load tested with 1000+ connections diff --git a/.serena/memories/omniprotocol_session_2025-12-01.md b/.serena/memories/omniprotocol_session_2025-12-01.md index cd0e5ddb6..a06a3a5c2 100644 --- a/.serena/memories/omniprotocol_session_2025-12-01.md +++ b/.serena/memories/omniprotocol_session_2025-12-01.md @@ -1,48 +1,58 @@ # OmniProtocol Session - December 1, 2025 ## Session Summary + Continued work on OmniProtocol integration, fixing authentication and message routing issues. ## Key Fixes Implemented ### 1. Authentication Fix (c1f642a3) + - **Problem**: Server only extracted peerIdentity after `hello_peer` (opcode 0x01) - **Impact**: NODE_CALL messages with valid auth blocks had `peerIdentity=null` - **Solution**: Extract peerIdentity from auth block for ANY authenticated message at top of `handleMessage()` ### 2. Mempool Routing Fix (59ffd328) + - **Problem**: `mempool` is a top-level RPC method, not a nodeCall message - **Impact**: Mempool merge requests got "Unknown message" error - **Solution**: Added routing in `handleNodeCall` to detect `method === "mempool"` and route to `ServerHandlers.handleMempool()` ### 3. Identity Format Fix (1fe432fd) + - **Problem**: OmniProtocol used `Buffer.toString("hex")` without `0x` prefix - **Impact**: PeerManager couldn't find peers (expects `0x` prefix) - **Solution**: Added `0x` prefix in `InboundConnection.ts` and `verifier.ts` ## Architecture Verification + All peer-to-peer communication now uses OmniProtocol TCP binary transport: + - `peer.call()` → `omniAdapter.adaptCall()` → TCP - `peer.longCall()` → internal `this.call()` → TCP - `consensus_routine` → NODE_CALL opcode → TCP - `mempool` merge → NODE_CALL opcode → TCP HTTP fallback only triggers on: + - OmniProtocol disabled - Node keys unavailable - TCP connection failure ## Commits This Session + 1. `1fe432fd` - Fix 0x prefix for peer identity 2. `c1f642a3` - Authenticate on ANY message with valid auth block 3. `59ffd328` - Route mempool RPC method to ServerHandlers ## Pending Work + - Test transactions with OmniProtocol (XM, native, DAHR) - Consider dedicated opcodes for frequently used methods - Clean up debug logging before production ## Key Files Modified + - `src/libs/omniprotocol/server/InboundConnection.ts` - `src/libs/omniprotocol/protocol/handlers/control.ts` - `src/libs/omniprotocol/auth/verifier.ts` diff --git a/.serena/memories/omniprotocol_wave8.1_complete.md b/.serena/memories/omniprotocol_wave8.1_complete.md index 598cb9207..3cbeff1f8 100644 --- a/.serena/memories/omniprotocol_wave8.1_complete.md +++ b/.serena/memories/omniprotocol_wave8.1_complete.md @@ -11,9 +11,11 @@ Wave 8.1 successfully implements **persistent TCP transport** to replace HTTP JS ## Components Implemented ### 1. MessageFramer.ts (215 lines) + **Purpose**: Parse TCP byte stream into complete OmniProtocol messages **Features**: + - Buffer accumulation from TCP socket - 12-byte header parsing: `[version:2][opcode:1][flags:1][payloadLength:4][sequence:4]` - CRC32 checksum validation @@ -23,9 +25,11 @@ Wave 8.1 successfully implements **persistent TCP transport** to replace HTTP JS **Location**: `src/libs/omniprotocol/transport/MessageFramer.ts` ### 2. PeerConnection.ts (338 lines) + **Purpose**: Wrap TCP socket with state machine and request tracking **Features**: + - Connection state machine: UNINITIALIZED → CONNECTING → AUTHENTICATING → READY → IDLE_PENDING → CLOSING → CLOSED - Request-response correlation via sequence IDs - In-flight request tracking with timeout @@ -36,9 +40,11 @@ Wave 8.1 successfully implements **persistent TCP transport** to replace HTTP JS **Location**: `src/libs/omniprotocol/transport/PeerConnection.ts` ### 3. ConnectionPool.ts (301 lines) + **Purpose**: Manage pool of persistent TCP connections **Features**: + - Per-peer connection pooling (max 1 connection per peer by default) - Global connection limit (max 100 total by default) - Lazy connection creation (create on first use) @@ -50,9 +56,11 @@ Wave 8.1 successfully implements **persistent TCP transport** to replace HTTP JS **Location**: `src/libs/omniprotocol/transport/ConnectionPool.ts` ### 4. types.ts (162 lines) + **Purpose**: Shared type definitions for transport layer **Key Types**: + - `ConnectionState`: State machine states - `ConnectionOptions`: Timeout, retries, priority - `PendingRequest`: Request tracking structure @@ -64,7 +72,9 @@ Wave 8.1 successfully implements **persistent TCP transport** to replace HTTP JS **Location**: `src/libs/omniprotocol/transport/types.ts` ### 5. peerAdapter.ts Integration + **Changes**: + - Added `ConnectionPool` initialization in constructor - Replaced HTTP placeholder in `adaptCall()` with TCP transport - Added `httpToTcpConnectionString()` converter @@ -74,7 +84,9 @@ Wave 8.1 successfully implements **persistent TCP transport** to replace HTTP JS **Location**: `src/libs/omniprotocol/integration/peerAdapter.ts` ### 6. Configuration Updates + **Added to ConnectionPoolConfig**: + - `maxTotalConnections: 100` - Global TCP connection limit **Location**: `src/libs/omniprotocol/types/config.ts` @@ -82,10 +94,11 @@ Wave 8.1 successfully implements **persistent TCP transport** to replace HTTP JS ## Architecture Transformation ### Before (Wave 7.x - HTTP Transport) + ``` peerAdapter.adaptCall() ↓ -peer.call() +peer.call() ↓ axios.post(url, json_payload) ↓ @@ -95,6 +108,7 @@ One TCP connection per request (closed after response) ``` ### After (Wave 8.1 - TCP Transport) + ``` peerAdapter.adaptCall() ↓ @@ -116,16 +130,19 @@ Correlate response via sequence ID ## Performance Benefits ### Connection Efficiency + - **Persistent connections**: Reuse TCP connections across requests (no 3-way handshake overhead) - **Connection pooling**: Efficient resource management - **Multiplexing**: Single TCP connection handles multiple concurrent requests via sequence IDs ### Protocol Efficiency + - **Binary framing**: Fixed-size header vs HTTP text headers - **Direct socket I/O**: No HTTP layer overhead - **CRC32 validation**: Integrity checking at protocol level ### Resource Management + - **Configurable limits**: Global and per-peer connection limits - **Idle cleanup**: Automatic cleanup of unused connections after 10 minutes - **Health monitoring**: Pool statistics for observability @@ -133,11 +150,13 @@ Correlate response via sequence ID ## Current Encoding (Wave 8.1) **Still using JSON payloads** in hybrid format: + - Header: Binary (12 bytes) - Payload: JSON envelope (length-prefixed) - Checksum: Binary (4 bytes CRC32) **Wave 8.2 will replace** JSON with full binary encoding for: + - Request/response payloads - Complex data structures - All handler communication @@ -145,20 +164,22 @@ Correlate response via sequence ID ## Migration Configuration ### Current Default (HTTP Only) + ```typescript DEFAULT_OMNIPROTOCOL_CONFIG = { migration: { - mode: "HTTP_ONLY", // ← TCP transport NOT used + mode: "HTTP_ONLY", // ← TCP transport NOT used omniPeers: new Set(), autoDetect: true, fallbackTimeout: 1000, - } + }, } ``` ### To Enable TCP Transport **Option 1: Global Enable** + ```typescript const adapter = new PeerOmniAdapter({ config: { @@ -168,12 +189,13 @@ const adapter = new PeerOmniAdapter({ omniPeers: new Set(), autoDetect: true, fallbackTimeout: 1000, - } - } + }, + }, }) ``` **Option 2: Per-Peer Enable** + ```typescript adapter.markOmniPeer(peerIdentity) // Mark specific peer for TCP // OR @@ -181,6 +203,7 @@ adapter.markHttpPeer(peerIdentity) // Force HTTP for specific peer ``` ### Migration Modes + - `HTTP_ONLY`: Never use TCP, always HTTP (current default) - `OMNI_PREFERRED`: Try TCP first, fall back to HTTP on failure (recommended) - `OMNI_ONLY`: Force TCP only, error if TCP fails (production after testing) @@ -188,12 +211,14 @@ adapter.markHttpPeer(peerIdentity) // Force HTTP for specific peer ## Testing Status **Not yet tested** - infrastructure is complete but: + 1. No unit tests written yet 2. No integration tests written yet 3. No end-to-end testing with real nodes 4. Migration mode is HTTP_ONLY (TCP not active) **To test**: + 1. Enable `OMNI_PREFERRED` mode 2. Mark test peer with `markOmniPeer()` 3. Make RPC calls and verify TCP connection establishment @@ -225,6 +250,7 @@ adapter.markHttpPeer(peerIdentity) // Force HTTP for specific peer **Goal**: Replace JSON payloads with full binary encoding **Approach**: + 1. Implement binary encoders for common types (string, number, array, object) 2. Create request/response binary serialization 3. Update handlers to use binary encoding @@ -232,6 +258,7 @@ adapter.markHttpPeer(peerIdentity) // Force HTTP for specific peer 5. Maintain backward compatibility during transition **Files to Modify**: + - `src/libs/omniprotocol/serialization/` - Add binary encoders/decoders - Handler files - Update payload encoding - peerAdapter - Switch to binary encoding @@ -239,50 +266,62 @@ adapter.markHttpPeer(peerIdentity) // Force HTTP for specific peer ## Files Created/Modified ### Created + - `src/libs/omniprotocol/transport/types.ts` (162 lines) - `src/libs/omniprotocol/transport/MessageFramer.ts` (215 lines) - `src/libs/omniprotocol/transport/PeerConnection.ts` (338 lines) - `src/libs/omniprotocol/transport/ConnectionPool.ts` (301 lines) ### Modified + - `src/libs/omniprotocol/integration/peerAdapter.ts` - Added ConnectionPool integration - `src/libs/omniprotocol/types/config.ts` - Added maxTotalConnections to pool config ### Total Lines of Code + **~1,016 lines** across 4 new files + integration ## Decision Log ### Why Persistent Connections? + HTTP's connection-per-request model has significant overhead: + - TCP 3-way handshake for every request - TLS handshake for HTTPS - No request multiplexing Persistent connections eliminate this overhead and enable: + - Request-response correlation via sequence IDs - Concurrent requests on single connection - Lower latency for subsequent requests ### Why Connection Pool? + - Prevents connection exhaustion (DoS protection) - Enables resource monitoring and limits - Automatic cleanup of idle connections - Health tracking for observability ### Why Idle Timeout 10 Minutes? + Balance between: + - Connection reuse efficiency (longer is better) - Resource usage (shorter is better) - Standard practice for persistent connections ### Why Sequence IDs vs Connection IDs? + Sequence IDs enable: + - Multiple concurrent requests on same connection - Request-response correlation - Better resource utilization ### Why CRC32? + - Fast computation (hardware acceleration available) - Sufficient for corruption detection - Standard in network protocols @@ -291,41 +330,51 @@ Sequence IDs enable: ## Potential Issues & Mitigations ### Issue: TCP Connection Failures + **Mitigation**: Automatic fallback to HTTP on TCP failure, automatic peer marking ### Issue: Resource Exhaustion + **Mitigation**: Connection pool limits (global and per-peer), idle cleanup ### Issue: Request Timeout + **Mitigation**: Per-request timeout configuration, automatic cleanup of timed-out requests ### Issue: Connection State Management + **Mitigation**: Clear state machine with documented transitions, error state handling ### Issue: Partial Message Handling + **Mitigation**: MessageFramer buffer accumulation, wait for complete messages ## Performance Targets ### Connection Establishment + - Target: <100ms for local connections - Target: <500ms for remote connections ### Request-Response Latency + - Target: <10ms overhead for connection reuse - Target: <100ms for first request (includes connection establishment) ### Connection Pool Efficiency + - Target: >90% connection reuse rate - Target: <1% connection pool capacity usage under normal load ### Resource Usage + - Target: <1MB memory per connection - Target: <100 open connections under normal load ## Monitoring Recommendations ### Metrics to Track + - Connection establishment time - Connection reuse rate - Pool capacity usage @@ -336,10 +385,12 @@ Sequence IDs enable: - TCP vs HTTP request distribution ### Alerts to Configure + - Pool capacity >80% - Connection timeout rate >5% - Fallback rate >10% - Average latency >100ms ## Wave 8.1 Completion Date + **2025-11-02** diff --git a/.serena/memories/omniprotocol_wave8_tcp_physical_layer.md b/.serena/memories/omniprotocol_wave8_tcp_physical_layer.md index bd14ceb0e..12b47cd1e 100644 --- a/.serena/memories/omniprotocol_wave8_tcp_physical_layer.md +++ b/.serena/memories/omniprotocol_wave8_tcp_physical_layer.md @@ -9,7 +9,9 @@ ## Current State Analysis ### What We Have (Wave 7.1-7.4 Complete) + ✅ **40 Binary Handlers Implemented**: + - Control & Infrastructure: 5 opcodes (0x03-0x07) - Data Sync: 8 opcodes (0x20-0x28) - Protocol Meta: 5 opcodes (0xF0-0xF4) @@ -18,6 +20,7 @@ - Transactions: 5 opcodes (0x10-0x12, 0x15-0x16) ✅ **Architecture Components**: + - Complete opcode registry with typed handlers - JSON envelope serialization (intermediate format) - Binary message header structures defined @@ -25,6 +28,7 @@ - Feature flags and migration modes configured ❌ **What We're Missing**: + - TCP socket transport layer - Connection pooling and lifecycle management - Full binary payload encoding (still using JSON envelopes) @@ -32,12 +36,14 @@ - Connection state machine implementation ### What We're Currently Using + ``` Handler → JSON Envelope → HTTP Transport (Wave 7.x) (peerAdapter.ts:78-81) ``` ### What Wave 8 Will Build + ``` Handler → Binary Encoding → TCP Transport (new encoders) (new ConnectionPool) @@ -46,33 +52,36 @@ Handler → Binary Encoding → TCP Transport ## Wave 8 Implementation Plan ### Wave 8.1: TCP Connection Infrastructure (Foundation) + **Duration**: 3-5 days **Priority**: CRITICAL - Core transport layer #### Deliverables + 1. **ConnectionPool Class** (`src/libs/omniprotocol/transport/ConnectionPool.ts`) - - Per-peer connection management - - Connection state machine (UNINITIALIZED → CONNECTING → AUTHENTICATING → READY → IDLE → CLOSED) - - Idle timeout handling (10 minutes) - - Connection limits (1000 total, 1 per peer initially) - - LRU eviction when at capacity + - Per-peer connection management + - Connection state machine (UNINITIALIZED → CONNECTING → AUTHENTICATING → READY → IDLE → CLOSED) + - Idle timeout handling (10 minutes) + - Connection limits (1000 total, 1 per peer initially) + - LRU eviction when at capacity 2. **PeerConnection Class** (`src/libs/omniprotocol/transport/PeerConnection.ts`) - - TCP socket wrapper with Node.js `net` module - - Connection lifecycle (connect, authenticate, ready, close) - - Message ID generation and tracking - - Request-response correlation (Map) - - Idle timer management - - Graceful shutdown with proto_disconnect (0xF4) + - TCP socket wrapper with Node.js `net` module + - Connection lifecycle (connect, authenticate, ready, close) + - Message ID generation and tracking + - Request-response correlation (Map) + - Idle timer management + - Graceful shutdown with proto_disconnect (0xF4) 3. **Message Framing** (`src/libs/omniprotocol/transport/MessageFramer.ts`) - - TCP stream → complete messages parsing - - Buffer accumulation and boundary detection - - Header parsing (12-byte: version, opcode, sequence, payloadLength) - - Checksum validation - - Partial message buffering + - TCP stream → complete messages parsing + - Buffer accumulation and boundary detection + - Header parsing (12-byte: version, opcode, sequence, payloadLength) + - Checksum validation + - Partial message buffering #### Key Technical Decisions + - **One Connection Per Peer**: Sufficient for current traffic patterns, can scale later - **TCP_NODELAY**: Disabled (Nagle's algorithm) for low latency - **SO_KEEPALIVE**: Enabled with 60s interval @@ -81,6 +90,7 @@ Handler → Binary Encoding → TCP Transport - **Idle Timeout**: 10 minutes #### Integration Points + ```typescript // peerAdapter.ts will use ConnectionPool instead of HTTP async adaptCall(peer: Peer, request: RPCRequest): Promise { @@ -97,6 +107,7 @@ async adaptCall(peer: Peer, request: RPCRequest): Promise { ``` #### Tests + - Connection establishment and authentication flow - Message send/receive round-trip - Timeout handling (connect, auth, request) @@ -106,10 +117,12 @@ async adaptCall(peer: Peer, request: RPCRequest): Promise { - Connection pool limits and LRU eviction ### Wave 8.2: Binary Payload Encoding (Performance) + **Duration**: 4-6 days **Priority**: HIGH - Bandwidth savings #### Current JSON Envelope Format + ```typescript // From jsonEnvelope.ts export function encodeJsonRequest(payload: unknown): Buffer { @@ -120,50 +133,54 @@ export function encodeJsonRequest(payload: unknown): Buffer { ``` #### Target Binary Format (from 05_PAYLOAD_STRUCTURES.md) + ```typescript // Example: Transaction structure interface BinaryTransaction { - hash: Buffer // 32 bytes fixed - type: number // 1 byte - from: Buffer // 32 bytes (address) - to: Buffer // 32 bytes (address) - amount: bigint // 8 bytes (uint64) - nonce: bigint // 8 bytes - timestamp: bigint // 8 bytes - fees: bigint // 8 bytes - signature: Buffer // length-prefixed - data: Buffer[] // count-prefixed array - gcrEdits: Buffer[] // count-prefixed array - raw: Buffer // length-prefixed + hash: Buffer // 32 bytes fixed + type: number // 1 byte + from: Buffer // 32 bytes (address) + to: Buffer // 32 bytes (address) + amount: bigint // 8 bytes (uint64) + nonce: bigint // 8 bytes + timestamp: bigint // 8 bytes + fees: bigint // 8 bytes + signature: Buffer // length-prefixed + data: Buffer[] // count-prefixed array + gcrEdits: Buffer[] // count-prefixed array + raw: Buffer // length-prefixed } ``` #### Deliverables + 1. **Binary Encoders** (`src/libs/omniprotocol/serialization/`) - - Update existing `transaction.ts` to use full binary encoding - - Update `gcr.ts` beyond just addressInfo - - Update `consensus.ts` for remaining consensus types - - Update `sync.ts` for block/mempool/peerlist structures - - Keep `primitives.ts` as foundation (already exists) + - Update existing `transaction.ts` to use full binary encoding + - Update `gcr.ts` beyond just addressInfo + - Update `consensus.ts` for remaining consensus types + - Update `sync.ts` for block/mempool/peerlist structures + - Keep `primitives.ts` as foundation (already exists) 2. **Encoder Registry Pattern** - ```typescript - // Map opcode → binary encoder/decoder - interface PayloadCodec { - encode(data: T): Buffer - decode(buffer: Buffer): T - } - - const PAYLOAD_CODECS = new Map>() - ``` + + ```typescript + // Map opcode → binary encoder/decoder + interface PayloadCodec { + encode(data: T): Buffer + decode(buffer: Buffer): T + } + + const PAYLOAD_CODECS = new Map>() + ``` 3. **Gradual Migration Strategy** - - Phase 1: Keep JSON envelope for complex structures (GCR edits, bridge trades) - - Phase 2: Binary encode simple structures (addresses, hashes, numbers) - - Phase 3: Full binary encoding for all payloads - - Always maintain decoder parity with encoder + - Phase 1: Keep JSON envelope for complex structures (GCR edits, bridge trades) + - Phase 2: Binary encode simple structures (addresses, hashes, numbers) + - Phase 3: Full binary encoding for all payloads + - Always maintain decoder parity with encoder #### Bandwidth Savings Analysis + ``` Current (JSON envelope): Simple request (getPeerInfo): ~120 bytes @@ -177,6 +194,7 @@ Target (Binary): ``` #### Tests + - Round-trip encoding/decoding for all opcodes - Edge cases (empty arrays, max values, unicode strings) - Backward compatibility (can still decode JSON envelopes) @@ -184,10 +202,12 @@ Target (Binary): - Malformed data handling ### Wave 8.3: Timeout & Retry Enhancement (Reliability) + **Duration**: 2-3 days **Priority**: MEDIUM - Better than HTTP's fixed delays #### Current HTTP Behavior (from Peer.ts) + ```typescript // Fixed retry logic async longCall(request, isAuthenticated, sleepTime = 250, retries = 3) { @@ -202,34 +222,37 @@ async longCall(request, isAuthenticated, sleepTime = 250, retries = 3) { ``` #### Enhanced Retry Strategy (from 04_CONNECTION_MANAGEMENT.md) + ```typescript interface RetryOptions { - maxRetries: number // Default: 3 - initialDelay: number // Default: 250ms + maxRetries: number // Default: 3 + initialDelay: number // Default: 250ms backoffMultiplier: number // Default: 1.0 (linear), 2.0 (exponential) - maxDelay: number // Default: 1000ms - allowedErrors: number[] // Don't retry for these status codes - retryOnTimeout: boolean // Default: true + maxDelay: number // Default: 1000ms + allowedErrors: number[] // Don't retry for these status codes + retryOnTimeout: boolean // Default: true } ``` #### Deliverables + 1. **RetryManager** (`src/libs/omniprotocol/transport/RetryManager.ts`) - - Exponential backoff support - - Per-operation timeout configuration - - Error classification (transient, degraded, fatal) + - Exponential backoff support + - Per-operation timeout configuration + - Error classification (transient, degraded, fatal) 2. **CircuitBreaker** (`src/libs/omniprotocol/transport/CircuitBreaker.ts`) - - 5 failures → OPEN state - - 30 second timeout → HALF_OPEN - - 2 successes → CLOSED - - Prevents cascading failures when peer is consistently offline + - 5 failures → OPEN state + - 30 second timeout → HALF_OPEN + - 2 successes → CLOSED + - Prevents cascading failures when peer is consistently offline 3. **TimeoutManager** (`src/libs/omniprotocol/transport/TimeoutManager.ts`) - - Adaptive timeouts based on peer latency history - - Per-operation type timeouts (consensus 1s, sync 30s, etc.) + - Adaptive timeouts based on peer latency history + - Per-operation type timeouts (consensus 1s, sync 30s, etc.) #### Integration + ```typescript // Enhanced PeerConnection.sendMessage with circuit breaker async sendMessage(opcode, payload, timeout) { @@ -243,6 +266,7 @@ async sendMessage(opcode, payload, timeout) { ``` #### Tests + - Exponential backoff timing verification - Circuit breaker state transitions - Adaptive timeout calculation from latency history @@ -250,31 +274,34 @@ async sendMessage(opcode, payload, timeout) { - Timeout vs retry interaction ### Wave 8.4: Concurrency & Resource Management (Scalability) + **Duration**: 3-4 days **Priority**: MEDIUM - Handles 1000+ peers #### Deliverables + 1. **Request Slot Management** (PeerConnection enhancement) - - Max 100 concurrent requests per connection - - Backpressure queue when at limit - - Slot acquisition/release pattern + - Max 100 concurrent requests per connection + - Backpressure queue when at limit + - Slot acquisition/release pattern 2. **AsyncMutex** (`src/libs/omniprotocol/transport/AsyncMutex.ts`) - - Thread-safe send operations (one message at a time per connection) - - Lock queue for waiting operations + - Thread-safe send operations (one message at a time per connection) + - Lock queue for waiting operations 3. **BufferPool** (`src/libs/omniprotocol/transport/BufferPool.ts`) - - Reusable buffers for common message sizes (256, 1K, 4K, 16K, 64K) - - Max 100 buffers per size to prevent memory bloat - - Security: Zero-fill buffers on release + - Reusable buffers for common message sizes (256, 1K, 4K, 16K, 64K) + - Max 100 buffers per size to prevent memory bloat + - Security: Zero-fill buffers on release 4. **Connection Metrics** (`src/libs/omniprotocol/transport/MetricsCollector.ts`) - - Per-peer latency tracking (p50, p95, p99) - - Error counts (connection, timeout, auth) - - Resource usage (memory, in-flight requests) - - Connection pool statistics + - Per-peer latency tracking (p50, p95, p99) + - Error counts (connection, timeout, auth) + - Resource usage (memory, in-flight requests) + - Connection pool statistics #### Memory Targets + ``` 1,000 peers: - Active connections: 50-100 (5-10% typical) @@ -289,6 +316,7 @@ async sendMessage(opcode, payload, timeout) { ``` #### Tests + - Concurrent request limiting (100 per connection) - Buffer pool acquire/release cycles - Metrics collection and calculation @@ -296,57 +324,61 @@ async sendMessage(opcode, payload, timeout) { - Connection pool scaling (simulate 1000 peers) ### Wave 8.5: Integration & Migration (Production Readiness) + **Duration**: 3-5 days **Priority**: CRITICAL - Safe rollout #### Deliverables + 1. **PeerAdapter Enhancement** (`src/libs/omniprotocol/integration/peerAdapter.ts`) - - Remove HTTP fallback placeholder (lines 78-81) - - Implement full TCP transport path - - Maintain dual-protocol support (HTTP + TCP based on connection string) + - Remove HTTP fallback placeholder (lines 78-81) + - Implement full TCP transport path + - Maintain dual-protocol support (HTTP + TCP based on connection string) 2. **Peer.ts Integration** - ```typescript - async call(request: RPCRequest, isAuthenticated = true): Promise { - // Detect protocol from connection string - if (this.connection.string.startsWith('tcp://')) { - return await this.callOmniProtocol(request, isAuthenticated) - } else if (this.connection.string.startsWith('http://')) { - return await this.callHTTP(request, isAuthenticated) - } - } - ``` + + ```typescript + async call(request: RPCRequest, isAuthenticated = true): Promise { + // Detect protocol from connection string + if (this.connection.string.startsWith('tcp://')) { + return await this.callOmniProtocol(request, isAuthenticated) + } else if (this.connection.string.startsWith('http://')) { + return await this.callHTTP(request, isAuthenticated) + } + } + ``` 3. **Connection String Format** - - HTTP: `http://ip:port` or `https://ip:port` - - TCP: `tcp://ip:port` or `tcps://ip:port` (TLS) - - Auto-detection based on peer capabilities + - HTTP: `http://ip:port` or `https://ip:port` + - TCP: `tcp://ip:port` or `tcps://ip:port` (TLS) + - Auto-detection based on peer capabilities 4. **Migration Modes** (already defined in config) - - `HTTP_ONLY`: All peers use HTTP (Wave 7.x default) - - `OMNI_PREFERRED`: Use TCP for peers in `omniPeers` set, HTTP fallback - - `OMNI_ONLY`: TCP only, fail if TCP unavailable (production target) + - `HTTP_ONLY`: All peers use HTTP (Wave 7.x default) + - `OMNI_PREFERRED`: Use TCP for peers in `omniPeers` set, HTTP fallback + - `OMNI_ONLY`: TCP only, fail if TCP unavailable (production target) 5. **Error Handling & Fallback** - ```typescript - // Dual protocol with automatic fallback - async call(request) { - if (this.supportsOmni() && config.mode !== 'HTTP_ONLY') { - try { - return await this.callOmniProtocol(request) - } catch (error) { - if (config.mode === 'OMNI_PREFERRED') { - log.warning('TCP failed, falling back to HTTP', error) - return await this.callHTTP(request) - } - throw error // OMNI_ONLY mode - } - } - return await this.callHTTP(request) - } - ``` + ```typescript + // Dual protocol with automatic fallback + async call(request) { + if (this.supportsOmni() && config.mode !== 'HTTP_ONLY') { + try { + return await this.callOmniProtocol(request) + } catch (error) { + if (config.mode === 'OMNI_PREFERRED') { + log.warning('TCP failed, falling back to HTTP', error) + return await this.callHTTP(request) + } + throw error // OMNI_ONLY mode + } + } + return await this.callHTTP(request) + } + ``` #### Tests + - End-to-end flow: handler → binary encoding → TCP → response - HTTP fallback when TCP unavailable - Migration mode switching (HTTP_ONLY → OMNI_PREFERRED → OMNI_ONLY) @@ -355,44 +387,48 @@ async sendMessage(opcode, payload, timeout) { - Performance benchmarking: TCP vs HTTP latency comparison ### Wave 8.6: Monitoring & Debugging (Observability) + **Duration**: 2-3 days **Priority**: LOW - Can be deferred #### Deliverables + 1. **Logging Infrastructure** - - Connection lifecycle events (connect, auth, ready, close) - - Message send/receive with opcodes and sizes - - Error details with classification - - Circuit breaker state changes + - Connection lifecycle events (connect, auth, ready, close) + - Message send/receive with opcodes and sizes + - Error details with classification + - Circuit breaker state changes 2. **Debug Mode** - - Packet-level inspection (hex dumps) - - Message flow tracing (message ID tracking) - - Connection state visualization + - Packet-level inspection (hex dumps) + - Message flow tracing (message ID tracking) + - Connection state visualization 3. **Metrics Dashboard** (future enhancement) - - Real-time connection count - - Latency histograms - - Error rate trends - - Bandwidth savings vs HTTP + - Real-time connection count + - Latency histograms + - Error rate trends + - Bandwidth savings vs HTTP 4. **Health Check Endpoint** - - OmniProtocol status (enabled/disabled) - - Active connections count - - Circuit breaker states - - Recent errors summary + - OmniProtocol status (enabled/disabled) + - Active connections count + - Circuit breaker states + - Recent errors summary ## Pending Handlers (Can Implement in Parallel) While Wave 8 is being built, we can continue implementing remaining handlers using JSON envelope pattern: ### Medium Priority + - `0x13 bridge_getTrade` (likely redundant with 0x12) - `0x14 bridge_executeTrade` (likely redundant with 0x12) - `0x50-0x5F` Browser/client operations (16 opcodes) - `0x60-0x62` Admin operations (3 opcodes) ### Low Priority + - `0x30 consensus_generic` (wrapper opcode) - `0x40 gcr_generic` (wrapper opcode) - `0x32 voteBlockHash` (deprecated in PoRBFTv2) @@ -400,26 +436,29 @@ While Wave 8 is being built, we can continue implementing remaining handlers usi ## Wave 8 Success Criteria ### Technical Validation + ✅ All existing HTTP tests pass with TCP transport ✅ Binary encoding round-trip tests for all 40 opcodes ✅ Connection pool handles 1000 simulated peers ✅ Circuit breaker prevents cascading failures ✅ Graceful fallback from TCP to HTTP works -✅ Memory usage within targets (<1MB for 1000 peers) +✅ Memory usage within targets (<1MB for 1000 peers) ### Performance Targets + ✅ Cold connection: <120ms (TCP handshake + auth) ✅ Warm connection: <30ms (message send + response) ✅ Bandwidth savings: >60% vs HTTP for typical payloads ✅ Throughput: >10,000 req/s with connection reuse -✅ Latency p95: <50ms for warm connections +✅ Latency p95: <50ms for warm connections ### Production Readiness + ✅ Feature flag controls (HTTP_ONLY, OMNI_PREFERRED, OMNI_ONLY) ✅ Dual protocol support (HTTP + TCP) ✅ Error handling and logging comprehensive ✅ No breaking changes to existing Peer class API -✅ Safe rollout strategy documented +✅ Safe rollout strategy documented ## Timeline Estimate @@ -428,6 +467,7 @@ While Wave 8 is being built, we can continue implementing remaining handlers usi **Conservative**: 35-42 days (with buffer for issues) ### Parallel Work Opportunities + - Wave 8.1 (TCP infra) can be built while finishing Wave 7.5 (testing) - Wave 8.2 (binary encoding) can start before 8.1 completes - Remaining handlers (browser/admin ops) can be implemented anytime @@ -436,25 +476,33 @@ While Wave 8 is being built, we can continue implementing remaining handlers usi ## Risk Analysis ### High Risk + 🔴 **TCP Connection Management Complexity** + - Mitigation: Start with single connection per peer, scale later - Fallback: Keep HTTP as safety net during migration 🔴 **Binary Encoding Bugs** + - Mitigation: Extensive round-trip testing, fixture validation - Fallback: JSON envelope mode for complex structures ### Medium Risk + 🟡 **Performance Doesn't Meet Targets** + - Mitigation: Profiling and optimization sprints - Fallback: Hybrid mode (TCP for hot paths, HTTP for bulk) 🟡 **Memory Leaks in Connection Pool** + - Mitigation: Long-running stress tests, memory profiling - Fallback: Aggressive idle timeout, connection limits ### Low Risk + đŸŸĸ **Protocol Versioning** + - Already designed in message header - Backward compatibility maintained @@ -462,12 +510,12 @@ While Wave 8 is being built, we can continue implementing remaining handlers usi 1. **Review this plan** with the team/stakeholders 2. **Start Wave 8.1** (TCP Connection Infrastructure) - - Create `src/libs/omniprotocol/transport/` directory - - Implement ConnectionPool and PeerConnection classes - - Write connection lifecycle tests + - Create `src/libs/omniprotocol/transport/` directory + - Implement ConnectionPool and PeerConnection classes + - Write connection lifecycle tests 3. **Continue Wave 7.5** (Testing & Hardening) in parallel - - Complete remaining handler tests - - Integration test suite for existing opcodes + - Complete remaining handler tests + - Integration test suite for existing opcodes 4. **Document Wave 8.1 progress** in memory updates ## References diff --git a/.serena/memories/project_purpose.md b/.serena/memories/project_purpose.md index 4f30d94d6..8d88fe53d 100644 --- a/.serena/memories/project_purpose.md +++ b/.serena/memories/project_purpose.md @@ -1,21 +1,25 @@ # Demos Network Node Software - Project Purpose ## Overview + The Demos Network Node Software is the official RPC implementation for the Demos Network. This repository contains the core network infrastructure components that allow machines to participate in the Demos Network as nodes. ## Key Components + - **Demos Network RPC**: Core network infrastructure and node functionality - **Demos Network SDK**: Full SDK implementation (`@kynesyslabs/demosdk` package) - **Multi-chain capabilities**: Cross-chain functionality referred to as "XM" or "Crosschain" - **Various features**: Including bridges, FHE, ZK, post-quantum cryptography, incentives, and more ## Target Environment + - Early development stage (not production-ready) - Designed for Linux, macOS, and WSL2 on Windows - Uses TypeScript with modern ES modules - Requires Node.js 20.x+, Bun, and Docker ## Architecture + - Modular feature-based architecture in `src/features/` - Database integration with TypeORM and PostgreSQL - RESTful API endpoints via Fastify @@ -23,6 +27,7 @@ The Demos Network Node Software is the official RPC implementation for the Demos - Identity management with cryptographic keys ## Development Context + - Licensed under CC BY-NC-ND 4.0 by KyneSys Labs - Private repository (not for public distribution) - Active development with frequent updates diff --git a/.serena/memories/session_2026-01-18_storage_program_api.md b/.serena/memories/session_2026-01-18_storage_program_api.md new file mode 100644 index 000000000..45411f504 --- /dev/null +++ b/.serena/memories/session_2026-01-18_storage_program_api.md @@ -0,0 +1,52 @@ +# Session: Storage Program Standard Calls API + +**Date**: 2026-01-18 +**Branch**: storage_v2 + +## Summary + +Implemented granular storage program API - node-side read/write methods and SDK wrappers. + +## Completed Tasks + +### Core Implementation (✅ Done) + +- **node-tytc / DEM-551**: Node read methods in `manageNodeCall.ts` + - getStorageProgramFields, getStorageProgramValue, getStorageProgramItem + - hasStorageProgramField, getStorageProgramFieldType, getStorageProgramAll +- **node-d3bv / DEM-552**: Node write methods in `GCRStorageProgramRoutines.ts` + - SET_FIELD, SET_ITEM, APPEND_ITEM, DELETE_FIELD, DELETE_ITEM + - Fee calculation based on size delta +- **node-ekwj / DEM-553**: SDK wrapper methods in `../sdks/src/storage/StorageProgram.ts` + - 6 read methods: getFields, getValue, getItem, hasField, getFieldType, getAll + - 5 write payload builders: setField, setItem, appendItem, deleteField, deleteItem + - **SDK v2.9.0 published** + +## Remaining Tasks (Epic: node-9idc) + +### NEXT SESSION START HERE: + +- **node-dsbw**: Update `../storage-poc` to demonstrate new standard calls API + +### Also Remaining: + +- **node-22zq**: Testing & edge cases for standard calls +- **node-h5tu**: Update `../documentation-mintlify` public docs +- **node-i8b7**: Update `specs/storageprogram/*.mdx` internal specs + +## Key Files Modified + +- `/home/tcsenpai/kynesys/node/src/libs/network/manageNodeCall.ts` - Read endpoints +- `/home/tcsenpai/kynesys/node/src/libs/blockchain/gcr/gcr_routines/GCRStorageProgramRoutines.ts` - Write handlers +- `/home/tcsenpai/kynesys/sdks/src/storage/StorageProgram.ts` - SDK methods + +## Linear Issues + +- DEM-551: Done +- DEM-552: Done +- DEM-553: Done + +## Notes + +- Beads issues can't be closed while epic (node-9idc) is open - marked with COMPLETED notes instead +- SDK granular methods use nodeCall pattern for reads, payload builders for writes diff --git a/.serena/memories/session_2026-01-19_storage_docs_complete.md b/.serena/memories/session_2026-01-19_storage_docs_complete.md new file mode 100644 index 000000000..d4364a982 --- /dev/null +++ b/.serena/memories/session_2026-01-19_storage_docs_complete.md @@ -0,0 +1,79 @@ +# Session: Storage Program Documentation Completion + +**Date**: 2026-01-19 +**Branch**: storage_v2 + +## Summary + +Completed documentation for Storage Program Granular API across documentation-mintlify and node specs. + +## Work Completed + +### Documentation (../documentation-mintlify) + +Updated `sdk/storage-programs/rpc-queries.md` with: + +- **Granular Read Endpoints table** - 7 endpoints documented +- **Get All Field Names** - `/storage-program/:address/fields` +- **Get Field Value** - `/storage-program/:address/field/:field` +- **Get Array Item** - `/storage-program/:address/field/:field/item/:index` +- **Check Field Exists** - `/storage-program/:address/has/:field` +- **Get Field Type** - `/storage-program/:address/type/:field` +- **Get All Data** - `/storage-program/:address/all` +- **Search by Name** - `/storage-program/search/:name` +- **When to Use comparison table** +- **Practical examples** (data discovery, conditional access, parallel queries) + +### Node Specs (specs/storageprogram/) + +- `03-operations.mdx` - Added GRANULAR_WRITE documentation (132 lines) +- `05-rpc-endpoints.mdx` - Added granular read endpoints (248 lines) + +## Git Commits + +- Documentation: `d5534f7` (rebased from `f21e97d`) +- Node specs: `107f8c8b` + +## Beads Status + +Epic `node-9idc` (Storage Program Standard Calls API): + +- ✓ node-d3bv: Node write methods +- ✓ node-ekwj: SDK wrapper methods +- ✓ node-tytc: Node read methods +- ✓ node-dsbw: storage-poc integration +- ✓ node-h5tu: documentation-mintlify (closed this session) +- ✓ node-i8b7: specs/storageprogram (closed this session) +- ○ node-22zq: Testing & edge cases (remaining) + +## Technical Reference + +### Granular Read Methods (6) + +| Method | Returns | Use Case | +| ----------------------- | ------------------ | ------------------------ | +| `getFields()` | `string[]` | Discover data structure | +| `getValue(field)` | `any` + `type` | Read single field | +| `getItem(field, index)` | `any` | Access array elements | +| `hasField(field)` | `boolean` | Check before accessing | +| `getFieldType(field)` | `StorageFieldType` | Type validation | +| `getAll()` | Full data | When you need everything | + +### Granular Write Operations (5) + +| Type | Required Fields | Description | +| -------------- | ------------------------- | -------------------- | +| `SET_FIELD` | `field`, `value` | Set top-level field | +| `SET_ITEM` | `field`, `index`, `value` | Update array element | +| `APPEND_ITEM` | `field`, `value` | Append to array | +| `DELETE_FIELD` | `field` | Remove field | +| `DELETE_ITEM` | `field`, `index` | Remove array element | + +### StorageFieldType Enum + +`string`, `number`, `boolean`, `array`, `object`, `null`, `undefined` + +## Next Steps + +- Complete testing task `node-22zq` with edge case coverage +- Consider closing epic `node-9idc` once testing is done diff --git a/.serena/memories/session_2026-01-19_storage_poc_granular_api.md b/.serena/memories/session_2026-01-19_storage_poc_granular_api.md new file mode 100644 index 000000000..797c31931 --- /dev/null +++ b/.serena/memories/session_2026-01-19_storage_poc_granular_api.md @@ -0,0 +1,69 @@ +# Session: Storage POC Granular API Update + +## Date + +2026-01-19 + +## Summary + +Updated the storage-poc application to demonstrate the new granular storage program API with a new "Granular API" tab. + +## Completed Work + +### Task: node-dsbw (CLOSED) + +- Added new "Granular API" tab to `/home/tcsenpai/kynesys/storage-poc/src/App.tsx` +- Updated SDK from v2.8.24 to v2.9.0 + +### Read Operations Implemented + +1. `getFields(rpcUrl, address, identity?)` - List all top-level field names +2. `getValue(rpcUrl, address, field, identity?)` - Get specific field value +3. `getItem(rpcUrl, address, field, index, identity?)` - Get array element +4. `hasField(rpcUrl, address, field, identity?)` - Check field existence +5. `getFieldType(rpcUrl, address, field, identity?)` - Get field type + +### Write Operations Implemented + +1. `setField(address, field, value)` - Set/create field +2. `setItem(address, field, index, value)` - Set array element +3. `appendItem(address, field, value)` - Push to array +4. `deleteField(address, field)` - Remove field +5. `deleteItem(address, field, index)` - Remove array element + +### Fee Display + +- Fee extracted from `confirmResult.response?.data?.transaction?.content?.transaction_fee` +- Total fee = `network_fee + rpc_fee + additional_fee` +- Display format: `Fee: ${(totalFee / 1e18).toFixed(6)} DEM` + +## Technical Discoveries + +### SDK Type Structure + +- `TxFee` interface: `{ network_fee: number, rpc_fee: number, additional_fee: number }` +- Fee is NOT on ValidityData.data.fee (doesn't exist) +- Fee is on `ValidityData.data.transaction.content.transaction_fee` + +### UI Architecture + +- Two-column layout: READ operations (left), WRITE operations (right) +- Optional identity field for ACL-protected storage programs +- Proper validation per operation type (field required for getValue, index for getItem, etc.) + +## Git State + +- Branch: `storage_v2` +- Commit: `233984b7 feat(storage): implement granular storage program API` +- Pushed: ✅ to origin/storage_v2 + +## Remaining Epic Tasks (node-9idc) + +- `node-22zq` - Testing & edge cases for standard calls +- `node-h5tu` - SDK integration (if still needed) +- `node-i8b7` - Documentation + +## Related + +- session_2026-01-18_storage_program_api (previous session) +- feature_storage_programs_plan (planning doc) diff --git a/.serena/memories/session_storage_program_queries_2026_01_18.md b/.serena/memories/session_storage_program_queries_2026_01_18.md new file mode 100644 index 000000000..e2f0f38f8 --- /dev/null +++ b/.serena/memories/session_storage_program_queries_2026_01_18.md @@ -0,0 +1,88 @@ +# Session: Storage Program Query Methods - 2026-01-18 + +## Summary + +Fixed SDK storage program query methods to work without authentication and resolved address format normalization issue. + +## Work Completed + +### 1. Unauthenticated Storage Program Queries + +**Problem**: SDK storage program queries (`getByAddress`, `getByOwner`, `searchByName`) were returning null/empty because `gcr_routine` requires authentication headers. + +**Solution**: + +- Added storage program query methods to `manageNodeCall.ts` (unauthenticated endpoint) +- Updated SDK `StorageProgram.ts` to use `nodeCall` instead of `gcr_routine` + +**Files Modified**: + +- `src/libs/network/manageNodeCall.ts` - Added 3 new cases: `getStorageProgram`, `getStorageProgramsByOwner`, `searchStoragePrograms` +- `../sdks/src/storage/StorageProgram.ts` - Changed from `gcr_routine` to `nodeCall` + +### 2. createdByTx Field Population + +**Problem**: `createdByTx` field in `GCRStorageProgram` entity was not being populated during transaction processing. + +**Root Cause**: In `endpointHandlers.ts:109`, `gcredit.txhash = ""` is set during validation for hash comparison, but never restored. + +**Solution**: Added `edit.txhash = tx.hash` in `handleGCR.ts` `applyToTx()` method before applying edits. + +**File Modified**: + +- `src/libs/blockchain/gcr/handleGCR.ts` - Added txhash assignment in applyToTx loop + +### 3. Storage Address Normalization + +**Problem**: `getStorageProgram` endpoint returned null because: + +- DB stores addresses as `stor-{hash}` (with prefix) +- Client was sending `{hash}` (without prefix) + +**Solution**: Added `normalizeStorageAddress()` helper function in `manageNodeCall.ts` that: + +- Strips `0x` prefix if present (legacy addresses) +- Adds `stor-` prefix if missing + +**File Modified**: + +- `src/libs/network/manageNodeCall.ts` - Added normalizeStorageAddress() function + +## Database Observations + +- Table name: `gcr_storageprogram` (no underscore) +- Entity name: `GCRStorageProgram` +- Storage addresses in DB: `stor-{40char_hash}` format +- Some legacy addresses have `0xstor-` prefix + +## Technical Details + +### nodeCall vs gcr_routine + +- `nodeCall`: Public endpoint, no authentication required +- `gcr_routine`: Requires `signature` and `identity` headers + +### Storage Address Formats Observed + +``` +0xstor-53ad58410dfcd0b93c18f0928d84ad43c1bbf5f5 (legacy with 0x) +stor-7e40fde1086c8ed4cf0486ed12c010d30abd715f (current format) +7e40fde1086c8ed4cf0486ed12c010d30abd715f (raw hash, needs normalization) +``` + +## Testing Notes + +- Node needs restart after changes for them to take effect +- Storage POC at `../storage-poc/` can be used for testing +- PostgreSQL container: `postgres_5332` on port 5332 (user: demosuser, db: demos) + +## Related Files + +- `src/libs/network/manageGCRRoutines.ts` - Contains authenticated storage methods (kept for backward compatibility) +- `src/model/entities/GCRv2/GCR_StorageProgram.ts` - Entity definition +- `src/libs/blockchain/gcr/gcr_routines/GCRStorageProgramRoutines.ts` - Shared query routines + +## Next Steps + +- Test the endpoints after node restart +- Consider adding similar normalization to other storage-related endpoints if needed diff --git a/.serena/memories/session_ud_ownership_verification_2025_10_21.md b/.serena/memories/session_ud_ownership_verification_2025_10_21.md index 319da1085..dbb5df736 100644 --- a/.serena/memories/session_ud_ownership_verification_2025_10_21.md +++ b/.serena/memories/session_ud_ownership_verification_2025_10_21.md @@ -1,6 +1,7 @@ # Session: UD Domain Ownership Verification - October 21, 2025 ## Session Overview + **Duration**: ~1 hour **Branch**: `ud_identities` **Commit**: `2ac51f02` - fix(ud): add ownership verification to deductUdDomainPoints and fix import path @@ -8,47 +9,57 @@ ## Work Completed ### 1. Code Review Analysis + **Reviewer Concerns Analyzed**: + 1. UD domain ownership verification missing in `deductUdDomainPoints` (LEGITIMATE) 2. Import path using explicit `node_modules/` path in udIdentityManager.ts (LEGITIMATE) ### 2. Security Implementation + **File**: `src/features/incentive/PointSystem.ts` **Changes**: + - Added UDIdentityManager import for domain resolution - Implemented blockchain-verified ownership check in `deductUdDomainPoints()` - Verification flow: - 1. Get user's linked wallets from GCR via `getUserIdentitiesFromGCR()` - 2. Resolve domain on-chain via `UDIdentityManager.resolveUDDomain()` - 3. Extract wallet addresses from linkedWallets format ("chain:address") - 4. Verify at least one user wallet matches domain's authorized addresses - 5. Handle case-sensitive comparison for Solana, case-insensitive for EVM - 6. Return 400 error if ownership verification fails - 7. Only proceed with point deduction if verified + 1. Get user's linked wallets from GCR via `getUserIdentitiesFromGCR()` + 2. Resolve domain on-chain via `UDIdentityManager.resolveUDDomain()` + 3. Extract wallet addresses from linkedWallets format ("chain:address") + 4. Verify at least one user wallet matches domain's authorized addresses + 5. Handle case-sensitive comparison for Solana, case-insensitive for EVM + 6. Return 400 error if ownership verification fails + 7. Only proceed with point deduction if verified **Security Vulnerability Addressed**: + - **Before**: Users could deduct points for domains they no longer own after transfer - **After**: Blockchain-verified ownership required before point deduction - **Impact**: Prevents points inflation from same domain generating multiple points across accounts ### 3. Infrastructure Fix + **File**: `src/libs/blockchain/gcr/gcr_routines/udIdentityManager.ts` **Changes**: + - Line 3: Fixed import path from `node_modules/@kynesyslabs/demosdk/build/types/abstraction` to `@kynesyslabs/demosdk/build/types/abstraction` - Line 258: Made `resolveUDDomain()` public (was private) to enable ownership verification from PointSystem **Rationale**: + - Explicit node_modules paths break module resolution across different environments - Public visibility required for PointSystem to verify domain ownership on-chain ## Technical Decisions ### Why UD Domains Need Ownership Verification + **Key Insight**: UD domains are NFTs (blockchain assets) that can be transferred/sold **Vulnerability Scenario**: + 1. Alice links `alice.crypto` → earns 3 points ✅ 2. Alice transfers domain to Bob on blockchain 🔄 3. Bob links `alice.crypto` → earns 3 points ✅ @@ -56,20 +67,24 @@ 5. **Result**: Same domain generates 6 points (should be max 3) **Solution**: Match linking security pattern + - Linking: Verifies signature from authorized wallet via `UDIdentityManager.verifyPayload()` - Unlinking: Now verifies current ownership via `UDIdentityManager.resolveUDDomain()` ### Implementation Pattern + **Ownership Verification Strategy**: + ```typescript // 1. Get user's linked wallets from GCR const { linkedWallets } = await this.getUserIdentitiesFromGCR(userId) // 2. Resolve domain to get current on-chain authorized addresses -const domainResolution = await UDIdentityManager.resolveUDDomain(normalizedDomain) +const domainResolution = + await UDIdentityManager.resolveUDDomain(normalizedDomain) // 3. Extract wallet addresses (format: "chain:address" → "address") -const userWalletAddresses = linkedWallets.map(wallet => wallet.split(':')[1]) +const userWalletAddresses = linkedWallets.map(wallet => wallet.split(":")[1]) // 4. Verify ownership with chain-specific comparison const isOwner = domainResolution.authorizedAddresses.some(authAddr => @@ -80,40 +95,46 @@ const isOwner = domainResolution.authorizedAddresses.some(authAddr => } // EVM: case-insensitive hex return authAddr.address.toLowerCase() === userAddr.toLowerCase() - }) + }), ) ``` ## Validation Results + - **ESLint**: ✅ No errors in modified files - **Type Safety**: ✅ All changes type-safe - **Import Verification**: ✅ UDIdentityAssignPayload confirmed exported from SDK - **Pattern Consistency**: ✅ Matches linking flow security architecture ## Files Modified + 1. `src/features/incentive/PointSystem.ts` (+56 lines) - - Added UDIdentityManager import - - Implemented ownership verification in deductUdDomainPoints() + - Added UDIdentityManager import + - Implemented ownership verification in deductUdDomainPoints() 2. `src/libs/blockchain/gcr/gcr_routines/udIdentityManager.ts` (+2, -2 lines) - - Fixed import path (line 3) - - Made resolveUDDomain() public (line 258) + - Fixed import path (line 3) + - Made resolveUDDomain() public (line 258) ## Key Learnings ### UD Domain Resolution Flow + **Multi-Chain Priority**: + 1. Polygon UNS → Base UNS → Sonic UNS → Ethereum UNS → Ethereum CNS 2. Fallback to Solana for .demos and other Solana domains 3. Returns UnifiedDomainResolution with authorizedAddresses array ### Points System Security Principles + 1. **Consistency**: Award and deduct operations must have matching security 2. **Blockchain Truth**: On-chain state is source of truth for ownership 3. **Chain Awareness**: Different signature validation (case-sensitive Solana vs case-insensitive EVM) 4. **Error Clarity**: Return meaningful 400 errors when verification fails ### Import Path Best Practices + - Never use explicit `node_modules/` paths in TypeScript imports - Use package name directly: `@kynesyslabs/demosdk/build/types/abstraction` - Ensures module resolution works across all environments (dev, build, production) @@ -121,17 +142,20 @@ const isOwner = domainResolution.authorizedAddresses.some(authAddr => ## Project Context Updates ### UD Integration Status + - **Phase 5**: Complete (domain linking with multi-chain support) - **Security Enhancement**: Ownership verification now complete for both award and deduct flows - **Points Integrity**: Protected against domain transfer abuse ### Related Memories + - `ud_integration_complete`: Base UD domain integration - `ud_phase5_complete`: Multi-chain UD support completion - `ud_technical_reference`: UD resolution and verification patterns - `ud_architecture_patterns`: UD domain system architecture ## Next Potential Work + 1. Consider adding similar ownership verification for Web3 wallet deduction 2. Review other identity deduction flows for consistency 3. Add integration tests for UD ownership verification edge cases diff --git a/.serena/memories/session_ud_points_implementation_2025_01_31.md b/.serena/memories/session_ud_points_implementation_2025_01_31.md index e6adc7ee3..88036c7bc 100644 --- a/.serena/memories/session_ud_points_implementation_2025_01_31.md +++ b/.serena/memories/session_ud_points_implementation_2025_01_31.md @@ -5,19 +5,23 @@ **Commit**: c833679d ## Task Summary + Implemented missing UD domain points methods in PointSystem to resolve TypeScript errors identified during pre-existing issue analysis. ## Implementation Details ### Point Values Added + - `LINK_UD_DOMAIN_DEMOS: 3` - For .demos TLD domains - `LINK_UD_DOMAIN: 1` - For other UD domains ### Methods Implemented #### 1. awardUdDomainPoints(userId, domain, referralCode?) + **Location**: src/features/incentive/PointSystem.ts:866-934 **Functionality**: + - TLD-based point determination (.demos = 3, others = 1) - Duplicate domain linking detection - Referral code support @@ -25,8 +29,10 @@ Implemented missing UD domain points methods in PointSystem to resolve TypeScrip - Returns RPCResponse with points awarded and total #### 2. deductUdDomainPoints(userId, domain) + **Location**: src/features/incentive/PointSystem.ts:942-1001 **Functionality**: + - TLD-based point determination - Domain-specific point tracking verification - GCR integration for point deduction @@ -35,34 +41,42 @@ Implemented missing UD domain points methods in PointSystem to resolve TypeScrip ### Type System Updates #### 1. GCR_Main Entity (src/model/entities/GCRv2/GCR_Main.ts) + - Added `udDomains: { [domain: string]: number }` to breakdown (line 36) - Added `telegram: number` to socialAccounts (line 34) #### 2. SDK Types (sdks/src/types/abstraction/index.ts) + - Added `udDomains: { [domain: string]: number }` to UserPoints breakdown (line 283) #### 3. Local UserPoints Interface (PointSystem.ts:12-33) + - Created local interface matching GCR entity structure - Includes all fields: web3Wallets, socialAccounts (with telegram), udDomains, referrals, demosFollow ### Infrastructure Updates #### Extended addPointsToGCR() + - Added "udDomains" type support (line 146) - Implemented udDomains breakdown handling (lines 221-228) #### Updated getUserPointsInternal() + - Added udDomains initialization in breakdown return (line 130) - Added telegram to socialAccounts initialization (line 128) ## Integration Points ### IncentiveManager Hooks + The implemented methods are called by existing hooks in IncentiveManager.ts: + - `udDomainLinked()` → calls `awardUdDomainPoints()` - `udDomainUnlinked()` → calls `deductUdDomainPoints()` ## Testing & Validation + - ✅ TypeScript compilation: All UD-related errors resolved - ✅ ESLint: All files pass linting - ✅ Pattern consistency: Follows existing web3Wallets/socialAccounts patterns @@ -71,7 +85,9 @@ The implemented methods are called by existing hooks in IncentiveManager.ts: ## Technical Decisions ### Why Local UserPoints Interface? + Created local interface instead of importing from SDK to: + 1. Avoid circular dependency issues during development 2. Ensure type consistency with GCR entity structure 3. Enable rapid iteration without SDK rebuilds @@ -80,23 +96,28 @@ Created local interface instead of importing from SDK to: Note: Added FIXME comment for future SDK import migration ### Domain Identification Logic + Uses `domain.toLowerCase().endsWith(".demos")` for TLD detection: + - Simple and reliable - Case-insensitive - Minimal processing overhead ## Files Modified + 1. src/features/incentive/PointSystem.ts (+182 lines) 2. src/model/entities/GCRv2/GCR_Main.ts (+2 lines) 3. sdks/src/types/abstraction/index.ts (+1 line) ## Commit Information + ``` feat(ud): implement UD domain points system with TLD-based rewards Commit: c833679d ``` ## Session Metadata + - Duration: ~45 minutes - Complexity: Moderate (extending existing system) - Dependencies: GCR entity, IncentiveManager, SDK types diff --git a/.serena/memories/suggested_commands.md b/.serena/memories/suggested_commands.md index bc22e1f93..8d596960e 100644 --- a/.serena/memories/suggested_commands.md +++ b/.serena/memories/suggested_commands.md @@ -1,7 +1,9 @@ # Demos Network Node Software - Essential Commands ## Development Commands + ### Code Quality & Linting + ```bash bun run lint # Check code style and linting bun run lint:fix # Auto-fix ESLint issues @@ -10,6 +12,7 @@ bun run prettier-format # Format specific modules ``` ### Node Operations + ```bash bun install # Install dependencies bun run start # Start the node with tsx @@ -21,6 +24,7 @@ bun run dev # Development mode with auto-restart ``` ### Database Operations + ```bash bun run migration:generate # Generate TypeORM migration bun run migration:run # Run pending migrations @@ -28,11 +32,13 @@ bun run migration:revert # Revert last migration ``` ### Testing + ```bash bun run test:chains # Run chain-specific tests ``` ### Utilities + ```bash bun run keygen # Generate cryptographic keys bun run restore # Backup and restore utility @@ -41,7 +47,9 @@ bun run upgrade_deps # Interactive dependency updates ``` ## Production Commands + ### Running the Node + ```bash ./run # Start database and node (recommended) ./run -p # Custom node port @@ -52,7 +60,9 @@ bun run upgrade_deps # Interactive dependency updates ``` ## System Commands (macOS/Darwin) + ### Essential Unix Tools + ```bash ls -la # List files with details cd /path/to/dir # Change directory (use /usr/bin/zoxide if available) @@ -61,6 +71,7 @@ find . -name "*.ts" # Find files by pattern ``` ### Process Management + ```bash lsof -i :53550 # Check if node port is in use lsof -i :5332 # Check if database port is in use @@ -69,6 +80,7 @@ kill -9 # Force kill process ``` ### Docker Operations + ```bash docker info # Check Docker status docker ps # List running containers @@ -77,6 +89,7 @@ docker compose down # Stop services ``` ## Git Workflow + ```bash git status # Check current status git branch # List branches @@ -86,6 +99,7 @@ git commit -m "message" # Commit changes ``` ## Troubleshooting Commands + ```bash # Check system requirements node --version # Should be 20.x+ diff --git a/.serena/memories/task_completion_guidelines.md b/.serena/memories/task_completion_guidelines.md index 54de6a6f9..17cf18269 100644 --- a/.serena/memories/task_completion_guidelines.md +++ b/.serena/memories/task_completion_guidelines.md @@ -3,21 +3,26 @@ ## Essential Quality Checks After Code Changes ### 1. Code Quality Validation + ```bash bun run lint:fix # ALWAYS run after code changes ``` + - Fixes ESLint issues automatically - Validates naming conventions (camelCase, PascalCase) - Ensures code style compliance - **CRITICAL**: This is the primary validation method - NEVER skip ### 2. Type Safety Verification + Since this project uses TypeScript with strict settings: + - TypeScript compilation happens during `bun run lint:fix` - Watch for type errors in the output - Address any type-related warnings ### 3. Code Review Preparation + - Add `// REVIEW:` comments before newly added features - Document complex logic with inline comments - Ensure JSDoc comments for new public methods @@ -25,6 +30,7 @@ Since this project uses TypeScript with strict settings: ## Development Workflow Completion ### When Adding New Features + 1. **Implement the feature** following established patterns 2. **Run `bun run lint:fix`** to validate syntax and style 3. **Add review comments** for significant changes @@ -32,12 +38,14 @@ Since this project uses TypeScript with strict settings: 5. **Test manually** if applicable (avoid starting the node directly) ### When Modifying Existing Code + 1. **Understand existing patterns** before making changes 2. **Maintain consistency** with current codebase style 3. **Run `bun run lint:fix`** to catch any issues 4. **Verify imports** use `@/` path aliases instead of relative paths ### When Working with Database Models + 1. **Generate migrations** if schema changes: `bun run migration:generate` 2. **Review generated migrations** before committing 3. **Test migration** in development environment if possible @@ -45,6 +53,7 @@ Since this project uses TypeScript with strict settings: ## Important "DON'Ts" for Task Completion ### ❌ NEVER Do These: + - **Start the node directly** during development (`bun run start`, `./run`) - **Skip linting** - always run `bun run lint:fix` - **Use relative imports** - use `@/` path aliases instead @@ -52,6 +61,7 @@ Since this project uses TypeScript with strict settings: - **Ignore naming conventions** - follow camelCase/PascalCase rules ### ✅ ALWAYS Do These: + - **Run `bun run lint:fix`** after any code changes - **Use established patterns** from existing code - **Follow the license header** format in new files @@ -60,15 +70,17 @@ Since this project uses TypeScript with strict settings: ## Validation Commands Summary -| Task Type | Required Command | Purpose | -|-----------|-----------------|---------| -| Any code change | `bun run lint:fix` | Syntax, style, type checking | -| New features | `// REVIEW:` comments | Mark for code review | -| Database changes | `bun run migration:generate` | Create schema migrations | -| Dependency updates | `bun install` | Ensure deps are current | +| Task Type | Required Command | Purpose | +| ------------------ | ---------------------------- | ---------------------------- | +| Any code change | `bun run lint:fix` | Syntax, style, type checking | +| New features | `// REVIEW:` comments | Mark for code review | +| Database changes | `bun run migration:generate` | Create schema migrations | +| Dependency updates | `bun install` | Ensure deps are current | ## Quality Gates + Before considering any task complete: + 1. ✅ Code passes `bun run lint:fix` without errors 2. ✅ All new code follows established patterns 3. ✅ Path aliases (`@/`) used instead of relative imports @@ -76,7 +88,8 @@ Before considering any task complete: 5. ✅ No unnecessary new files created ## Special Project Considerations + - **Node Testing**: Use ESLint validation instead of starting the node - **SDK Integration**: Reference `@kynesyslabs/demosdk` package, not source - **Bun Preference**: Always use `bun` commands over `npm`/`yarn` -- **License Compliance**: CC BY-NC-ND 4.0 headers in all new source files \ No newline at end of file +- **License Compliance**: CC BY-NC-ND 4.0 headers in all new source files diff --git a/.serena/memories/tlsnotary_integration_context.md b/.serena/memories/tlsnotary_integration_context.md index 25eefa30f..11ff419ba 100644 --- a/.serena/memories/tlsnotary_integration_context.md +++ b/.serena/memories/tlsnotary_integration_context.md @@ -4,36 +4,43 @@ - **Epic**: `node-6lo` - TLSNotary Backend Integration - **Tasks** (in dependency order): - 1. `node-3yq` - Copy pre-built .so library (READY) - 2. `node-ebc` - Create FFI bindings - 3. `node-r72` - Create TLSNotaryService - 4. `node-9kw` - Create Fastify routes - 5. `node-mwm` - Create feature entry point - 6. `node-2fw` - Integrate with node startup - 7. `node-hgf` - Add SDK discovery endpoint - 8. `node-8sq` - Type check and lint + 1. `node-3yq` - Copy pre-built .so library (READY) + 2. `node-ebc` - Create FFI bindings + 3. `node-r72` - Create TLSNotaryService + 4. `node-9kw` - Create Fastify routes + 5. `node-mwm` - Create feature entry point + 6. `node-2fw` - Integrate with node startup + 7. `node-hgf` - Add SDK discovery endpoint + 8. `node-8sq` - Type check and lint ## Reference Code Locations ### Pre-built Binary + ``` /home/tcsenpai/tlsn/demos_tlsnotary/node/rust/target/release/libtlsn_notary.so ``` + Target: `libs/tlsn/libtlsn_notary.so` ### FFI Reference Implementation + ``` /home/tcsenpai/tlsn/demos_tlsnotary/node/ts/TLSNotary.ts ``` + Complete working bun:ffi bindings to adapt for `src/features/tlsnotary/ffi.ts` ### Demo App Reference + ``` /home/tcsenpai/tlsn/demos_tlsnotary/demo/src/app.tsx ``` + Browser-side attestation flow with tlsn-js WASM ### Integration Documentation + ``` /home/tcsenpai/tlsn/demos_tlsnotary/BACKEND_INTEGRATION.md /home/tcsenpai/tlsn/demos_tlsnotary/INTEGRATION.md @@ -43,28 +50,42 @@ Browser-side attestation flow with tlsn-js WASM ```typescript const symbols = { - tlsn_init: { args: [], returns: FFIType.i32 }, - tlsn_notary_create: { args: [FFIType.ptr], returns: FFIType.ptr }, - tlsn_notary_start_server: { args: [FFIType.ptr, FFIType.u16], returns: FFIType.i32 }, - tlsn_notary_stop_server: { args: [FFIType.ptr], returns: FFIType.i32 }, - tlsn_verify_attestation: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.ptr }, - tlsn_notary_get_public_key: { args: [FFIType.ptr, FFIType.ptr, FFIType.u64], returns: FFIType.i32 }, - tlsn_notary_destroy: { args: [FFIType.ptr], returns: FFIType.void }, - tlsn_free_verification_result: { args: [FFIType.ptr], returns: FFIType.void }, - tlsn_free_string: { args: [FFIType.ptr], returns: FFIType.void }, -}; + tlsn_init: { args: [], returns: FFIType.i32 }, + tlsn_notary_create: { args: [FFIType.ptr], returns: FFIType.ptr }, + tlsn_notary_start_server: { + args: [FFIType.ptr, FFIType.u16], + returns: FFIType.i32, + }, + tlsn_notary_stop_server: { args: [FFIType.ptr], returns: FFIType.i32 }, + tlsn_verify_attestation: { + args: [FFIType.ptr, FFIType.u64], + returns: FFIType.ptr, + }, + tlsn_notary_get_public_key: { + args: [FFIType.ptr, FFIType.ptr, FFIType.u64], + returns: FFIType.i32, + }, + tlsn_notary_destroy: { args: [FFIType.ptr], returns: FFIType.void }, + tlsn_free_verification_result: { + args: [FFIType.ptr], + returns: FFIType.void, + }, + tlsn_free_string: { args: [FFIType.ptr], returns: FFIType.void }, +} ``` ## FFI Struct Layouts ### NotaryConfig (40 bytes) + - signing_key ptr (8 bytes) -- signing_key_len (8 bytes) +- signing_key_len (8 bytes) - max_sent_data (8 bytes) - max_recv_data (8 bytes) - server_port (2 bytes + padding) ### VerificationResultFFI (40 bytes) + - status (4 bytes + 4 padding) - server_name ptr (8 bytes) - connection_time (8 bytes) @@ -75,5 +96,6 @@ const symbols = { ## SDK Integration (Already Complete) Package `@kynesyslabs/demosdk` v2.7.2 has `tlsnotary/` module with: + - TLSNotary class: initialize(), attest(), verify(), getTranscript() - Located in `/home/tcsenpai/kynesys/sdks/src/tlsnotary/` diff --git a/.serena/memories/typescript_audit_complete_2025_12_17.md b/.serena/memories/typescript_audit_complete_2025_12_17.md index 58fe8125a..c6a74cf86 100644 --- a/.serena/memories/typescript_audit_complete_2025_12_17.md +++ b/.serena/memories/typescript_audit_complete_2025_12_17.md @@ -3,37 +3,44 @@ ## Date: 2025-12-17 ## Summary + Comprehensive TypeScript type-check audit completed. Reduced errors from 38 to 2 (95% reduction). Remaining 2 errors in fhe_test.ts closed as not planned. Production code has 0 type errors. ## Issues Completed ### Fixed Issues -| Issue | Category | Errors Fixed | Solution | -|-------|----------|--------------|----------| -| node-c98 | UrlValidationResult | 6 | Type imports and interface fixes | -| node-01y | executeNativeTransaction | 2 | Return type fixes | -| node-u9a | IMP Signaling | 2 | log.debug args, signedData→signature | -| node-tus | Network Module | 6 | Named exports, signature type, originChainType | -| node-eph | SDK Missing Exports | 4 | Created local types.ts for EncryptedTransaction, SubnetPayload | -| node-9x8 | OmniProtocol | 11 | Catch blocks, bigint→number, Buffer casts, union types | -| node-clk | Deprecated Crypto | 2 | Removed dead code (saveEncrypted/loadEncrypted) | -| (untracked) | showPubkey.ts | 1 | Uint8Array cast | + +| Issue | Category | Errors Fixed | Solution | +| ----------- | ------------------------ | ------------ | -------------------------------------------------------------- | +| node-c98 | UrlValidationResult | 6 | Type imports and interface fixes | +| node-01y | executeNativeTransaction | 2 | Return type fixes | +| node-u9a | IMP Signaling | 2 | log.debug args, signedData→signature | +| node-tus | Network Module | 6 | Named exports, signature type, originChainType | +| node-eph | SDK Missing Exports | 4 | Created local types.ts for EncryptedTransaction, SubnetPayload | +| node-9x8 | OmniProtocol | 11 | Catch blocks, bigint→number, Buffer casts, union types | +| node-clk | Deprecated Crypto | 2 | Removed dead code (saveEncrypted/loadEncrypted) | +| (untracked) | showPubkey.ts | 1 | Uint8Array cast | ### Excluded/Not Planned -| Issue | Category | Errors | Reason | -|-------|----------|--------|--------| -| node-2e8 | Tests | 4 | Excluded src/tests from tsconfig | -| node-a96 | FHE Test | 2 | Closed as not planned | + +| Issue | Category | Errors | Reason | +| -------- | -------- | ------ | -------------------------------- | +| node-2e8 | Tests | 4 | Excluded src/tests from tsconfig | +| node-a96 | FHE Test | 2 | Closed as not planned | ## Key Patterns Discovered ### SDK Type Gaps + When SDK types exist but aren't exported, create local type definitions: + - Created `src/libs/l2ps/types.ts` with EncryptedTransaction, SubnetPayload - Mirror SDK internal types until SDK exports are updated ### Catch Block Error Handling + Standard pattern for unknown error type in catch blocks: + ```typescript } catch (error) { throw new Error(`Message: ${(error as Error).message}`) @@ -41,30 +48,37 @@ Standard pattern for unknown error type in catch blocks: ``` ### Union Type Narrowing + When TypeScript narrows to `never` in switch defaults: + ```typescript message: `Unsupported: ${(payload as KnownType).property}` ``` ### Dead Code Detection + `createCipher`/`createDecipher` were undefined in Bun but node worked fine = dead code paths never executed. ## Configuration Changes + - Added `"src/tests"` to tsconfig.json exclude list ## Files Modified (Key) + - src/libs/l2ps/types.ts (NEW) - src/libs/crypto/cryptography.ts (removed dead code) -- src/libs/omniprotocol/* (11 fixes) -- src/libs/network/* (multiple fixes) +- src/libs/omniprotocol/\* (11 fixes) +- src/libs/network/\* (multiple fixes) - tsconfig.json (exclude src/tests) ## Commits + 1. `fc5abb9e` - fix: resolve 22 TypeScript type errors (38→16 remaining) 2. `20137452` - fix: resolve OmniProtocol type errors (16→5 remaining) 3. `c684bb2a` - fix: remove dead crypto code and fix showPubkey type (4→2 errors) ## Final State + - Production errors: 0 - Test-only errors: 2 (fhe_test.ts - not planned) - Epic node-tsaudit: CLOSED diff --git a/.serena/memories/ud_architecture_patterns.md b/.serena/memories/ud_architecture_patterns.md index 8689b5b27..cdd8e8324 100644 --- a/.serena/memories/ud_architecture_patterns.md +++ b/.serena/memories/ud_architecture_patterns.md @@ -3,6 +3,7 @@ ## Resolution Flow ### Multi-Chain Cascade (5-Network Fallback) + ``` 1. Try Polygon L2 UNS → Success? Return UnifiedDomainResolution 2. Try Base L2 UNS → Success? Return UnifiedDomainResolution @@ -14,6 +15,7 @@ ``` ### UnifiedDomainResolution Structure + ```typescript { domain: string // "example.crypto" @@ -36,11 +38,12 @@ ## Verification Flow ### Multi-Address Authorization + ```typescript verifyPayload(payload) { // 1. Resolve domain → get all authorized addresses const resolution = await resolveUDDomain(domain) - + // 2. Check signing address is authorized const matchingAddress = resolution.authorizedAddresses.find( auth => auth.address.toLowerCase() === signingAddress.toLowerCase() @@ -48,7 +51,7 @@ verifyPayload(payload) { if (!matchingAddress) { throw `Address ${signingAddress} not authorized for ${domain}` } - + // 3. Verify signature based on type if (matchingAddress.signatureType === "evm") { const recovered = ethers.verifyMessage(signedData, signature) @@ -61,10 +64,10 @@ verifyPayload(payload) { ) if (!isValid) throw "Invalid Solana signature" } - + // 4. Verify challenge contains Demos public key if (!signedData.includes(demosPublicKey)) throw "Invalid challenge" - + // 5. Store in GCR await saveToGCR(demosAddress, { domain, signingAddress, signatureType, ... }) } @@ -73,28 +76,37 @@ verifyPayload(payload) { ## Storage Pattern (JSONB) ### GCR Structure + ```typescript gcr_main.identities = { - xm: { /* cross-chain */ }, - web2: { /* social */ }, - pqc: { /* post-quantum */ }, - ud: [ // Array of UD identities - { - domain: "example.crypto", - signingAddress: "0x...", // Address that signed - signatureType: "evm", - signature: "0x...", - network: "polygon", - registryType: "UNS", - publicKey: "", - timestamp: 1234567890, - signedData: "Link ... to Demos ..." - } - ] + xm: { + /* cross-chain */ + }, + web2: { + /* social */ + }, + pqc: { + /* post-quantum */ + }, + ud: [ + // Array of UD identities + { + domain: "example.crypto", + signingAddress: "0x...", // Address that signed + signatureType: "evm", + signature: "0x...", + network: "polygon", + registryType: "UNS", + publicKey: "", + timestamp: 1234567890, + signedData: "Link ... to Demos ...", + }, + ], } ``` ### Defensive Initialization + ```typescript // New accounts (handleGCR.ts) identities: { xm: {}, web2: {}, pqc: {}, ud: [] } @@ -106,6 +118,7 @@ gcr.identities.ud = gcr.identities.ud || [] ## Helper Methods Pattern ### Conversion Helpers + ```typescript // EVM → Unified evmToUnified(evmResolution): UnifiedDomainResolution @@ -115,6 +128,7 @@ solanaToUnified(solanaResolution): UnifiedDomainResolution ``` ### Signature Detection + ```typescript detectAddressType(address: string): "evm" | "solana" | null validateAddressType(address, expectedType): boolean @@ -122,6 +136,7 @@ isSignableAddress(address): boolean ``` ### Record Extraction + ```typescript fetchDomainRecords(domain, tokenId, provider, registry): Record extractSignableAddresses(records): SignableAddress[] @@ -130,6 +145,7 @@ extractSignableAddresses(records): SignableAddress[] ## Error Messages ### Authorization Failure + ``` Address 0x123... is not authorized for domain example.crypto. Authorized addresses: @@ -138,9 +154,11 @@ Authorized addresses: ``` ### Success Message + ``` Verified ownership of example.crypto via evm signature from crypto.ETH.address ``` ## Future: .demos TLD Support + **Zero code changes required** - domain resolution handles all TLDs automatically via `ethers.namehash()` and registry contracts. diff --git a/.serena/memories/ud_integration_complete.md b/.serena/memories/ud_integration_complete.md index 459300041..20f54b988 100644 --- a/.serena/memories/ud_integration_complete.md +++ b/.serena/memories/ud_integration_complete.md @@ -3,8 +3,10 @@ **Status**: Phase 5 + Points ✅ | **Branch**: `ud_identities` | **Next**: Phase 6 ## âš ī¸ IMPORTANT: Solana Integration Note + The Solana integration uses **UD helper pattern** NOT the reverse engineering/API approach documented in old exploration memories. Current implementation: -- Uses existing `udSolanaResolverHelper.ts` + +- Uses existing `udSolanaResolverHelper.ts` - Fetches records directly via Solana program - NO API key required for resolution - Converts to UnifiedDomainResolution format @@ -13,6 +15,7 @@ The Solana integration uses **UD helper pattern** NOT the reverse engineering/AP ## Current Implementation ### Completed Phases + 1. ✅ Signature detection utility (`signatureDetector.ts`) 2. ✅ EVM records fetching (all 5 networks) 3. ✅ Solana integration + UnifiedDomainResolution (via helper) @@ -22,33 +25,38 @@ The Solana integration uses **UD helper pattern** NOT the reverse engineering/AP 7. â¸ī¸ SDK client updates (pending) ### Phase 5 Breaking Changes + ```typescript // SavedUdIdentity - NEW structure interface SavedUdIdentity { - domain: string - signingAddress: string // CHANGED from resolvedAddress - signatureType: SignatureType // NEW: "evm" | "solana" - signature: string - publicKey: string - timestamp: number - signedData: string - network: "polygon" | "ethereum" | "base" | "sonic" | "solana" // ADDED solana - registryType: "UNS" | "CNS" + domain: string + signingAddress: string // CHANGED from resolvedAddress + signatureType: SignatureType // NEW: "evm" | "solana" + signature: string + publicKey: string + timestamp: number + signedData: string + network: "polygon" | "ethereum" | "base" | "sonic" | "solana" // ADDED solana + registryType: "UNS" | "CNS" } ``` ### Points System Implementation (NEW) + **Commit**: `c833679d` | **Date**: 2025-01-31 **Point Values**: + - `.demos` TLD domains: **3 points** - Other UD domains: **1 point** **Methods**: + - `awardUdDomainPoints(userId, domain, referralCode?)` - Awards points with duplicate detection - `deductUdDomainPoints(userId, domain)` - Deducts points on domain unlink **Type Extensions**: + ```typescript // GCR_Main.ts - points.breakdown udDomains: { [domain: string]: number } // Track points per domain @@ -72,6 +80,7 @@ interface UserPoints { ``` **Integration**: + - IncentiveManager hooks call PointSystem methods automatically - `udDomainLinked()` → `awardUdDomainPoints()` - `udDomainUnlinked()` → `deductUdDomainPoints()` @@ -79,6 +88,7 @@ interface UserPoints { **Details**: See `session_ud_points_implementation_2025_01_31` memory ### Key Capabilities + - **Multi-chain resolution**: Polygon L2 → Base L2 → Sonic → Ethereum L1 UNS → Ethereum L1 CNS → Solana (via helper) - **Multi-address auth**: Sign with ANY address in domain records (not just owner) - **Dual signature types**: EVM (secp256k1) + Solana (ed25519) @@ -88,7 +98,9 @@ interface UserPoints { ## Integration Status ### Node Repository + **Modified**: + - `udIdentityManager.ts`: Resolution + verification logic + Solana integration - `GCRIdentityRoutines.ts`: Field extraction and validation - `IncentiveManager.ts`: Points for domain linking @@ -97,14 +109,17 @@ interface UserPoints { - `GCR_Main.ts`: udDomains breakdown field **Created**: + - `signatureDetector.ts`: Auto-detect signature types - `udSolanaResolverHelper.ts`: Solana resolution (existing, reused) ### SDK Repository + **Current**: v2.4.24 (with UD types from Phase 0-5) **Pending**: Phase 6 client method updates ## Testing Status + - ✅ Type definitions compile - ✅ Field validation functional - ✅ JSONB storage compatible (no migration) @@ -114,6 +129,7 @@ interface UserPoints { ## Next Phase 6 Requirements **SDK Updates** (`../sdks/`):\ + 1. Update `UDIdentityPayload` with `signingAddress` + `signatureType` 2. Remove old `resolvedAddress` field 3. Update `addUnstoppableDomainIdentity()` signature @@ -122,14 +138,17 @@ interface UserPoints { 6. Add `getUDSignableAddresses()` helper method **Files to modify**: + - `src/types/abstraction/index.ts` - `src/abstraction/Identities.ts` ## Dependencies + - Node: `tweetnacl@1.0.3`, `bs58@6.0.0` (for Solana signatures) - SDK: `ethers` (already present) ## Commit History + - `ce3c32a8`: Phase 1 signature detection - `7b9826d8`: Phase 2 EVM records - `10460e41`: Phase 3 & 4 Solana + multi-sig @@ -138,6 +157,7 @@ interface UserPoints { - **Next**: Phase 6 SDK client updates ## Reference + - **Phase 5 details**: See `ud_phase5_complete` memory - **Points implementation**: See `session_ud_points_implementation_2025_01_31` memory - **Phases tracking**: See `ud_phases_tracking` memory for complete timeline diff --git a/.serena/memories/ud_phase5_complete.md b/.serena/memories/ud_phase5_complete.md index e42bfe23a..a5eacb2fd 100644 --- a/.serena/memories/ud_phase5_complete.md +++ b/.serena/memories/ud_phase5_complete.md @@ -15,21 +15,23 @@ Successfully updated identity type definitions to support multi-address verifica **File**: `src/model/entities/types/IdentityTypes.ts` **BREAKING CHANGES from Phase 4**: + ```typescript export interface SavedUdIdentity { - domain: string // Unchanged: "brad.crypto" or "example.demos" - signingAddress: string // ✅ CHANGED from resolvedAddress + domain: string // Unchanged: "brad.crypto" or "example.demos" + signingAddress: string // ✅ CHANGED from resolvedAddress signatureType: SignatureType // ✅ NEW: "evm" | "solana" - signature: string // Unchanged - publicKey: string // Unchanged - timestamp: number // Unchanged - signedData: string // Unchanged + signature: string // Unchanged + publicKey: string // Unchanged + timestamp: number // Unchanged + signedData: string // Unchanged network: "polygon" | "ethereum" | "base" | "sonic" | "solana" // ✅ ADDED "solana" registryType: "UNS" | "CNS" // Unchanged } ``` **Key Changes**: + - `resolvedAddress` → `signingAddress`: More accurate - this is the address that SIGNED, not necessarily the domain owner - Added `signatureType`: Indicates whether to use EVM (ethers.verifyMessage) or Solana (nacl.sign.detached.verify) - Added `"solana"` to network union: Supports .demos domains on Solana @@ -41,6 +43,7 @@ export interface SavedUdIdentity { **Method**: `applyUdIdentityAdd()` (lines 470-560) Updated to extract and validate new fields: + ```typescript const { domain, @@ -75,15 +78,22 @@ const data: SavedUdIdentity = { ### 3. Database Storage **Storage Structure** (JSONB column, no migration needed): + ```typescript gcr_main.identities = { - xm: { /* ... */ }, - web2: { /* ... */ }, - pqc: { /* ... */ }, + xm: { + /* ... */ + }, + web2: { + /* ... */ + }, + pqc: { + /* ... */ + }, ud: [ { domain: "example.crypto", - signingAddress: "0x123...", // Address that signed + signingAddress: "0x123...", // Address that signed signatureType: "evm", signature: "0xabc...", network: "polygon", @@ -91,13 +101,13 @@ gcr_main.identities = { }, { domain: "alice.demos", - signingAddress: "ABCD...xyz", // Solana address + signingAddress: "ABCD...xyz", // Solana address signatureType: "solana", signature: "base58...", network: "solana", // ... - } - ] + }, + ], } ``` @@ -108,6 +118,7 @@ gcr_main.identities = { **Method**: `udDomainLinked()` (line 117+) Awards points for first-time UD domain linking: + ```typescript static async udDomainLinked( demosAddress: string, @@ -122,6 +133,7 @@ static async udDomainLinked( ## Documentation Comments Added Added comprehensive JSDoc comments to `SavedUdIdentity`: + ```typescript /** * The Unstoppable Domains identity saved in the GCR @@ -141,6 +153,7 @@ Added comprehensive JSDoc comments to `SavedUdIdentity`: ## Type Safety Verification ✅ **No type errors** in affected files: + - `src/model/entities/types/IdentityTypes.ts` - `src/libs/blockchain/gcr/gcr_routines/GCRIdentityRoutines.ts` - `src/libs/blockchain/gcr/gcr_routines/udIdentityManager.ts` @@ -153,11 +166,12 @@ Added comprehensive JSDoc comments to `SavedUdIdentity`: **No database migration required** ✅ Why: + - `identities` column is JSONB (flexible JSON storage) - Defensive initialization in `GCRIdentityRoutines.applyUdIdentityAdd()`: - ```typescript - accountGCR.identities.ud = accountGCR.identities.ud || [] - ``` + ```typescript + accountGCR.identities.ud = accountGCR.identities.ud || [] + ``` - New accounts: Include `ud: []` in default initialization (handled by GCR system) - Existing accounts: Key auto-added on first UD link operation @@ -166,10 +180,17 @@ Why: ### With Phase 4 (Multi-Signature Verification) Phase 4's `verifyPayload()` method already expects these fields (with backward compatibility): + ```typescript // Phase 4 comment: "Phase 5 will update SDK to use signingAddress + signatureType" -const { domain, resolvedAddress, signature, signedData, network, registryType } = - payload.payload +const { + domain, + resolvedAddress, + signature, + signedData, + network, + registryType, +} = payload.payload // Phase 5 completed this - now properly uses signingAddress ``` @@ -177,6 +198,7 @@ const { domain, resolvedAddress, signature, signedData, network, registryType } ### With Storage System All UD identities stored in `gcr_main.identities.ud[]` array: + - Each entry is a `SavedUdIdentity` object - Supports mixed signature types (EVM + Solana in same account) - Queried via `GCRIdentityRoutines` methods @@ -184,6 +206,7 @@ All UD identities stored in `gcr_main.identities.ud[]` array: ### With Incentive System First-time domain linking triggers points: + ```typescript const isFirst = await this.isFirstConnection( "ud", @@ -204,27 +227,31 @@ if (isFirst) { ## Files Modified **Node Repository** (this repo): + - `src/model/entities/types/IdentityTypes.ts` - Interface updates - `src/libs/blockchain/gcr/gcr_routines/GCRIdentityRoutines.ts` - Field extraction and validation - Documentation comments added throughout **SDK Repository** (../sdks) - **Phase 6 pending**: + - Still uses old `UDIdentityPayload` format in `src/types/abstraction/index.ts` - Needs update to match node-side changes ## Backward Compatibility **Breaking Changes**: + - `SavedUdIdentity.resolvedAddress` removed (now `signingAddress`) - New required field: `signatureType` - Network type expanded: added `"solana"` **Migration Path for Existing Data**: + - N/A - No existing UD identities in production yet - If there were, would need script to: - 1. Rename `resolvedAddress` → `signingAddress` - 2. Detect and add `signatureType` based on address format - 3. Update network if needed + 1. Rename `resolvedAddress` → `signingAddress` + 2. Detect and add `signatureType` based on address format + 3. Update network if needed ## Testing Checklist @@ -239,6 +266,7 @@ if (isFirst) { **Phase 6: Update SDK Client Methods** (../sdks repository) Required changes: + 1. Update `UDIdentityPayload` in `src/types/abstraction/index.ts` 2. Remove old payload format 3. Use new payload format from `UDResolution.ts` @@ -255,6 +283,6 @@ Required changes: ✅ GCR storage logic updated ✅ Incentive system integration working ✅ No type errors or lint issues -✅ Backward compatibility considered +✅ Backward compatibility considered **Phase 5 Status: COMPLETE** ✅ diff --git a/.serena/memories/ud_phases_tracking.md b/.serena/memories/ud_phases_tracking.md index c4a839a40..f36d17ce1 100644 --- a/.serena/memories/ud_phases_tracking.md +++ b/.serena/memories/ud_phases_tracking.md @@ -4,15 +4,15 @@ ## Phase Status Overview -| Phase | Status | Commit | Description | -|-------|--------|--------|-------------| -| Phase 1 | ✅ Complete | `ce3c32a8` | Signature detection utility | -| Phase 2 | ✅ Complete | `7b9826d8` | EVM records fetching | -| Phase 3 | ✅ Complete | `10460e41` | Solana integration + UnifiedDomainResolution | -| Phase 4 | ✅ Complete | `10460e41` | Multi-signature verification (EVM + Solana) | -| Phase 5 | ✅ Complete | `eff3af6c` | IdentityTypes updates (breaking changes) | -| **Points** | ✅ Complete | `c833679d` | **UD domain points system implementation** | -| Phase 6 | â¸ī¸ Pending | - | SDK client method updates | +| Phase | Status | Commit | Description | +| ---------- | ----------- | ---------- | -------------------------------------------- | +| Phase 1 | ✅ Complete | `ce3c32a8` | Signature detection utility | +| Phase 2 | ✅ Complete | `7b9826d8` | EVM records fetching | +| Phase 3 | ✅ Complete | `10460e41` | Solana integration + UnifiedDomainResolution | +| Phase 4 | ✅ Complete | `10460e41` | Multi-signature verification (EVM + Solana) | +| Phase 5 | ✅ Complete | `eff3af6c` | IdentityTypes updates (breaking changes) | +| **Points** | ✅ Complete | `c833679d` | **UD domain points system implementation** | +| Phase 6 | â¸ī¸ Pending | - | SDK client method updates | --- @@ -22,11 +22,13 @@ **File**: `src/libs/blockchain/gcr/gcr_routines/signatureDetector.ts` **Created**: + - `detectSignatureType(address)` - Auto-detect EVM vs Solana from address format - `validateAddressType(address, expectedType)` - Validate address matches type - `isSignableAddress(address)` - Check if address is recognized format **Patterns**: + - EVM: `/^0x[0-9a-fA-F]{40}$/` (secp256k1) - Solana: `/^[1-9A-HJ-NP-Za-km-z]{32,44}$/` (ed25519) @@ -38,6 +40,7 @@ **File**: `src/libs/blockchain/gcr/gcr_routines/udIdentityManager.ts` **Changes**: + - `resolveUDDomain()` return type: simple object → `EVMDomainResolution` - Added resolver ABI with `get()` method - Defined `UD_RECORD_KEYS` array (8 common crypto address records) @@ -46,6 +49,7 @@ - Applied to all 5 EVM networks: Polygon, Base, Sonic, Ethereum UNS, Ethereum CNS **Record Keys**: + ```typescript const UD_RECORD_KEYS = [ "crypto.ETH.address", @@ -67,6 +71,7 @@ const UD_RECORD_KEYS = [ **File**: `src/libs/blockchain/gcr/gcr_routines/udIdentityManager.ts` **Changes**: + - Added imports: `UnifiedDomainResolution`, `SolanaDomainResolver` - Created `evmToUnified()` - Converts `EVMDomainResolution` → `UnifiedDomainResolution` - Created `solanaToUnified()` - Converts Solana helper result → `UnifiedDomainResolution` @@ -74,6 +79,7 @@ const UD_RECORD_KEYS = [ - Added Solana fallback after all EVM networks fail **Resolution Cascade**: + 1. Polygon L2 UNS → unified format 2. Base L2 UNS → unified format 3. Sonic UNS → unified format @@ -83,6 +89,7 @@ const UD_RECORD_KEYS = [ 7. Throw if domain not found on any network **Temporary Phase 3 Limitation**: + - `verifyPayload()` only supports EVM domains - Solana domains fail with "Phase 3 limitation" message - Phase 4 implements full multi-address verification @@ -95,15 +102,18 @@ const UD_RECORD_KEYS = [ **File**: `src/libs/blockchain/gcr/gcr_routines/udIdentityManager.ts` **Dependencies Added**: + - `tweetnacl@1.0.3` - Solana signature verification - `bs58@6.0.0` - Base58 encoding/decoding **Changes**: + - Completely rewrote `verifyPayload()` for multi-address support - Added `verifySignature()` helper method for dual signature type support - Enhanced error messages with authorized address lists **Verification Flow**: + ```typescript 1. Resolve domain → get UnifiedDomainResolution with authorizedAddresses 2. Check domain has authorized addresses (fail if empty) @@ -114,12 +124,14 @@ const UD_RECORD_KEYS = [ ``` **EVM Signature**: + ```typescript const recoveredAddress = ethers.verifyMessage(signedData, signature) if (recoveredAddress !== authorizedAddress.address) fail ``` **Solana Signature**: + ```typescript const signatureBytes = bs58.decode(signature) const messageBytes = new TextEncoder().encode(signedData) @@ -128,7 +140,7 @@ const publicKeyBytes = bs58.decode(authorizedAddress.address) const isValid = nacl.sign.detached.verify( messageBytes, signatureBytes, - publicKeyBytes + publicKeyBytes, ) ``` @@ -139,22 +151,24 @@ const isValid = nacl.sign.detached.verify( ## Phase 5: Update IdentityTypes ✅ **Commit**: `eff3af6c` -**Files**: +**Files**: + - `src/model/entities/types/IdentityTypes.ts` - `src/libs/blockchain/gcr/gcr_routines/GCRIdentityRoutines.ts` **Breaking Changes**: + ```typescript // OLD (Phase 4) interface SavedUdIdentity { - resolvedAddress: string // ❌ REMOVED + resolvedAddress: string // ❌ REMOVED // ... } // NEW (Phase 5) interface SavedUdIdentity { domain: string - signingAddress: string // ✅ CHANGED from resolvedAddress + signingAddress: string // ✅ CHANGED from resolvedAddress signatureType: SignatureType // ✅ NEW: "evm" | "solana" signature: string publicKey: string @@ -166,6 +180,7 @@ interface SavedUdIdentity { ``` **Changes in GCRIdentityRoutines**: + - Updated `applyUdIdentityAdd()` to extract `signingAddress` and `signatureType` - Added field validation for new required fields - Updated storage logic to use new field names @@ -180,22 +195,26 @@ interface SavedUdIdentity { **Commit**: `c833679d` **Date**: 2025-01-31 -**Files**: +**Files**: + - `src/features/incentive/PointSystem.ts` - `src/model/entities/GCRv2/GCR_Main.ts` **Purpose**: Incentivize UD domain linking with TLD-based rewards ### Point Values + - `.demos` TLD domains: **3 points** - Other UD domains: **1 point** ### Methods Implemented #### awardUdDomainPoints(userId, domain, referralCode?) + **Location**: PointSystem.ts:866-934 **Features**: + - Automatic TLD detection (`domain.toLowerCase().endsWith(".demos")`) - Duplicate domain linking prevention - Referral code support @@ -203,6 +222,7 @@ interface SavedUdIdentity { - Returns `RPCResponse` with points awarded and updated total **Logic Flow**: + ```typescript 1. Determine point value based on TLD 2. Check for duplicate domain in GCR breakdown.udDomains @@ -211,15 +231,18 @@ interface SavedUdIdentity { ``` #### deductUdDomainPoints(userId, domain) + **Location**: PointSystem.ts:942-1001 **Features**: + - TLD-based point calculation (matching award logic) - Domain-specific point tracking verification - Safe deduction (checks if points exist first) - Returns `RPCResponse` with points deducted and updated total **Logic Flow**: + ```typescript 1. Determine point value based on TLD 2. Verify domain exists in GCR breakdown.udDomains @@ -230,6 +253,7 @@ interface SavedUdIdentity { ### Infrastructure Updates #### GCR Entity Extensions (GCR_Main.ts) + ```typescript // Added to points.breakdown udDomains: { [domain: string]: number } // Track points per domain @@ -237,21 +261,23 @@ telegram: number // Added to socialAccounts ``` #### PointSystem Type Updates + ```typescript // Extended addPointsToGCR() type parameter type: "web3Wallets" | "socialAccounts" | "udDomains" // Added udDomains handling in addPointsToGCR() if (type === "udDomains") { - account.points.breakdown.udDomains = + account.points.breakdown.udDomains = account.points.breakdown.udDomains || {} - account.points.breakdown.udDomains[platform] = - oldDomainPoints + points + account.points.breakdown.udDomains[platform] = oldDomainPoints + points } ``` #### Local UserPoints Interface + Created local interface matching GCR structure to avoid SDK circular dependencies: + ```typescript interface UserPoints { // ... existing fields @@ -259,11 +285,11 @@ interface UserPoints { web3Wallets: { [chain: string]: number } socialAccounts: { twitter: number - github: number + github: number discord: number - telegram: number // ✅ NEW + telegram: number // ✅ NEW } - udDomains: { [domain: string]: number } // ✅ NEW + udDomains: { [domain: string]: number } // ✅ NEW referrals: number demosFollow: number } @@ -274,6 +300,7 @@ interface UserPoints { ### Integration with IncentiveManager **Existing Hooks** (IncentiveManager.ts:117-137): + ```typescript static async udDomainLinked( userId: string, @@ -298,6 +325,7 @@ static async udDomainUnlinked( These hooks are called automatically when UD identities are added/removed via `udIdentityManager`. ### Testing & Validation + - ✅ TypeScript compilation: All errors resolved - ✅ ESLint: All files pass linting - ✅ Pattern consistency: Matches web3Wallets/socialAccounts implementation @@ -306,17 +334,20 @@ These hooks are called automatically when UD identities are added/removed via `u ### Design Decisions **Why TLD-based rewards?** + - `.demos` domains directly promote Demos Network branding - Higher reward incentivizes ecosystem adoption - Simple rule: easy for users to understand **Why local UserPoints interface?** + - Avoid SDK circular dependencies during rapid iteration - Ensure type consistency with GCR entity structure - Enable development without rebuilding SDK - FIXME comment added for future SDK migration **Why domain-level tracking in breakdown?** + - Prevents duplicate point awards for same domain - Enables accurate point deduction on unlink - Matches existing pattern (web3Wallets per chain, socialAccounts per platform) @@ -338,11 +369,12 @@ These hooks are called automatically when UD identities are added/removed via `u ### Required Changes #### 1. Update Types (`src/types/abstraction/index.ts`) + ```typescript // REMOVE old format export interface UDIdentityPayload { domain: string - resolvedAddress: string // ❌ DELETE + resolvedAddress: string // ❌ DELETE signature: string publicKey: string signedData: string @@ -351,7 +383,7 @@ export interface UDIdentityPayload { // ADD new format export interface UDIdentityPayload { domain: string - signingAddress: string // ✅ NEW + signingAddress: string // ✅ NEW signatureType: SignatureType // ✅ NEW signature: string publicKey: string @@ -362,6 +394,7 @@ export interface UDIdentityPayload { #### 2. Update Methods (`src/abstraction/Identities.ts`) **Update `generateUDChallenge()`**: + ```typescript // OLD generateUDChallenge(demosPublicKey: string): string @@ -376,6 +409,7 @@ generateUDChallenge( ``` **Update `addUnstoppableDomainIdentity()`**: + ```typescript // OLD async addUnstoppableDomainIdentity( @@ -397,7 +431,7 @@ async addUnstoppableDomainIdentity( ) { // Detect signature type from address format const signatureType = detectAddressType(signingAddress) - + const payload: UDIdentityAssignPayload = { method: "ud_identity_assign", payload: { @@ -414,6 +448,7 @@ async addUnstoppableDomainIdentity( ``` #### 3. Add Helper Method (NEW) + ```typescript /** * Get all signable addresses for a UD domain @@ -430,11 +465,13 @@ async getUDSignableAddresses( ### Phase 6 Testing Requirements **Unit Tests**: + - Challenge generation with signing address - Signature type auto-detection - Multi-address payload creation **Integration Tests**: + - End-to-end UD identity verification flow - EVM domain + EVM signature - Solana domain + Solana signature @@ -449,7 +486,7 @@ async getUDSignableAddresses( **Phase 3 → Phase 4**: UnifiedDomainResolution provides authorizedAddresses **Phase 4 → Phase 5**: Verification logic expects new type structure **Phase 5 → Points**: Identity storage structure enables points tracking -**Points → Phase 6**: SDK must match node implementation for client usage +**Points → Phase 6**: SDK must match node implementation for client usage --- @@ -459,8 +496,9 @@ async getUDSignableAddresses( **Latest Commit**: `c833679d` (UD points system) **Next Action**: Update SDK client methods in `../sdks/` repository **Breaking Changes**: Phases 4, 5, 6 all introduce breaking changes -**Testing**: End-to-end testing blocked until Phase 6 complete +**Testing**: End-to-end testing blocked until Phase 6 complete For detailed implementation sessions: + - Phase 5 details: See `ud_phase5_complete` memory - Points implementation: See `session_ud_points_implementation_2025_01_31` memory diff --git a/.serena/memories/ud_security_patterns.md b/.serena/memories/ud_security_patterns.md index a5fad31aa..2534a94e0 100644 --- a/.serena/memories/ud_security_patterns.md +++ b/.serena/memories/ud_security_patterns.md @@ -3,24 +3,26 @@ ## Ownership Verification Architecture ### Core Principle + **Blockchain State as Source of Truth**: UD domains are NFTs that can be transferred. All ownership decisions must be verified on-chain, not from cached GCR data. ### Verification Flow Pattern + ```typescript // STANDARD PATTERN for UD ownership verification async verifyUdDomainOwnership(userId: string, domain: string): boolean { // 1. Get user's linked wallets from GCR const { linkedWallets } = await getUserIdentitiesFromGCR(userId) - + // 2. Resolve domain on-chain to get current authorized addresses const domainResolution = await UDIdentityManager.resolveUDDomain(domain) - + // 3. Extract wallet addresses (format: "chain:address" → "address") const userWalletAddresses = linkedWallets.map(wallet => { const parts = wallet.split(':') return parts.length > 1 ? parts[1] : wallet }) - + // 4. Check ownership with chain-specific comparison const isOwner = domainResolution.authorizedAddresses.some(authAddr => userWalletAddresses.some(userAddr => { @@ -32,7 +34,7 @@ async verifyUdDomainOwnership(userId: string, domain: string): boolean { return authAddr.address.toLowerCase() === userAddr.toLowerCase() }) ) - + return isOwner } ``` @@ -40,16 +42,20 @@ async verifyUdDomainOwnership(userId: string, domain: string): boolean { ## Security Checkpoints ### Domain Linking (Award Points) + **Location**: `src/features/incentive/PointSystem.ts::awardUdDomainPoints()` **Security**: ✅ Verified via UDIdentityManager.verifyPayload() + - Resolves domain to get authorized addresses - Verifies signature from authorized wallet - Checks Demos public key in challenge message - Only awards points if all verification passes ### Domain Unlinking (Deduct Points) + **Location**: `src/features/incentive/PointSystem.ts::deductUdDomainPoints()` **Security**: ✅ Verified via UDIdentityManager.resolveUDDomain() + - Resolves domain to get current authorized addresses - Compares against user's linked wallets - Blocks deduction if user doesn't own domain @@ -58,7 +64,9 @@ async verifyUdDomainOwnership(userId: string, domain: string): boolean { ## Multi-Chain Considerations ### Domain Resolution Priority + **EVM Networks** (in order): + 1. Polygon UNS Registry 2. Base UNS Registry 3. Sonic UNS Registry @@ -66,16 +74,20 @@ async verifyUdDomainOwnership(userId: string, domain: string): boolean { 5. Ethereum CNS Registry (legacy) **Solana Network**: + - Fallback for .demos and other Solana domains - Uses SolanaDomainResolver for resolution ### Signature Type Handling + **EVM Addresses**: + - Format: 0x-prefixed hex (40 characters) - Comparison: Case-insensitive - Verification: ethers.verifyMessage() **Solana Addresses**: + - Format: Base58-encoded (32 bytes) - Comparison: Case-sensitive - Verification: nacl.sign.detached.verify() @@ -83,6 +95,7 @@ async verifyUdDomainOwnership(userId: string, domain: string): boolean { ## Error Handling Patterns ### Domain Not Resolvable + ```typescript try { domainResolution = await UDIdentityManager.resolveUDDomain(domain) @@ -92,19 +105,20 @@ try { response: { message: `Cannot verify ownership: domain ${domain} is not resolvable`, }, - extra: { error: error.message } + extra: { error: error.message }, } } ``` ### Ownership Verification Failed + ```typescript if (!isOwner) { return { result: 400, response: { message: `Cannot deduct points: domain ${domain} is not owned by any of your linked wallets`, - } + }, } } ``` @@ -112,6 +126,7 @@ if (!isOwner) { ## Testing Considerations ### Test Scenarios + 1. **Happy Path**: User owns domain → deduction succeeds 2. **Transfer Scenario**: User transferred domain → deduction fails with 400 3. **Resolution Failure**: Domain expired/deleted → returns 400 with clear error @@ -123,17 +138,20 @@ if (!isOwner) { ## Integration Points ### UDIdentityManager API + **Public Methods**: + - `resolveUDDomain(domain: string): Promise` - - Returns authorized addresses and network metadata - - Throws if domain not resolvable - + - Returns authorized addresses and network metadata + - Throws if domain not resolvable - `verifyPayload(payload: UDIdentityAssignPayload, sender: string)` - - Full signature verification for domain linking - - Includes ownership + signature validation + - Full signature verification for domain linking + - Includes ownership + signature validation ### PointSystem Integration + **Dependencies**: + - `getUserIdentitiesFromGCR()`: Get user's linked wallets - `UDIdentityManager.resolveUDDomain()`: Get current domain ownership - `addPointsToGCR()`: Execute point changes after verification @@ -141,17 +159,23 @@ if (!isOwner) { ## Security Vulnerability Prevention ### Prevented Attack: Domain Transfer Abuse + **Scenario**: Attacker transfers domain after earning points + - ✅ **Protected**: Ownership verified on-chain before deduction - ✅ **Result**: Attacker loses points when domain transferred ### Prevented Attack: Same Domain Multiple Accounts + **Scenario**: Same domain linked to multiple accounts + - ✅ **Protected**: Duplicate linking check in awardUdDomainPoints() - ✅ **Protected**: Ownership verification in deductUdDomainPoints() - ✅ **Result**: Each domain can only earn points once per account ### Prevented Attack: Expired Domain Points + **Scenario**: Domain expires but points remain + - ✅ **Protected**: Resolution failure prevents deduction - âš ī¸ **Note**: Points remain awarded (acceptable - user earned them legitimately) diff --git a/.serena/memories/ud_technical_reference.md b/.serena/memories/ud_technical_reference.md index 20606c259..c878cabf4 100644 --- a/.serena/memories/ud_technical_reference.md +++ b/.serena/memories/ud_technical_reference.md @@ -3,6 +3,7 @@ ## Network Configuration ### EVM Networks (Priority Order) + 1. **Polygon L2**: `0x0E2846C302E5E05C64d5FaA0365b1C2aE48AD2Ad` | `https://polygon-rpc.com` 2. **Base L2**: `0xF6c1b83977DE3dEffC476f5048A0a84d3375d498` | `https://mainnet.base.org` 3. **Sonic**: `0xDe1DAdcF11a7447C3D093e97FdbD513f488cE3b4` | `https://rpc.soniclabs.com` @@ -10,6 +11,7 @@ 5. **Ethereum CNS**: `0xD1E5b0FF1287aA9f9A268759062E4Ab08b9Dacbe` | `https://eth.llamarpc.com` ### Solana Network + - **UD Program**: `6eLvwb1dwtV5coME517Ki53DojQaRLUctY9qHqAsS9G2` - **RPC**: `https://api.mainnet-beta.solana.com` - **Resolution**: Via `udSolanaResolverHelper.ts` (direct Solana program interaction) @@ -18,6 +20,7 @@ ## Record Keys Priority **Signable Records** (support multi-address verification): + - `crypto.ETH.address` - Primary EVM - `crypto.SOL.address` - Primary Solana - `crypto.MATIC.address` - Polygon native @@ -27,6 +30,7 @@ - `token.SOL.SOL.USDC.address` - Solana USDC **Non-Signable** (skip): + - `crypto.BTC.address` - Bitcoin can't sign Demos challenges - `ipfs.html.value` - Not an address - `dns.*` - Not an address @@ -34,6 +38,7 @@ ## Signature Detection Patterns ### Address Formats + ```typescript // EVM: 0x prefix + 40 hex chars /^0x[0-9a-fA-F]{40}$/ @@ -43,22 +48,26 @@ ``` ### Verification Methods + **EVM**: `ethers.verifyMessage(signedData, signature)` → recoveredAddress **Solana**: `nacl.sign.detached.verify(messageBytes, signatureBytes, publicKeyBytes)` → boolean ## Test Data Examples ### EVM Domain (sir.crypto on Polygon) + - Owner: `0x45238D633D6a1d18ccde5fFD234958ECeA46eB86` - Records: Sparse (2/11 populated) - Signable: 1 EVM address ### Solana Domain (thecookingsenpai.demos) + - Records: Rich (4/11 populated) - Signable: 2 EVM + 2 Solana addresses - Multi-chain from start ## Environment Variables + ```bash ETHEREUM_RPC=https://eth.llamarpc.com # EVM resolution # Solana resolution via helper - no API key needed diff --git a/.serena/project.yml b/.serena/project.yml index 93009accd..91b6d206e 100644 --- a/.serena/project.yml +++ b/.serena/project.yml @@ -21,7 +21,7 @@ read_only: false # list of tool names to exclude. We recommend not excluding any tools, see the readme for more details. # Below is the complete list of tools for convenience. -# To make sure you have the latest list of tools, and to view their descriptions, +# To make sure you have the latest list of tools, and to view their descriptions, # execute `uv run scripts/print_tool_overview.py`. # # * `activate_project`: Activates a project by name. @@ -64,4 +64,4 @@ excluded_tools: [] # (contrary to the memories, which are loaded on demand). initial_prompt: "" -project_name: "node" +project_name: node diff --git a/.trunk/actions b/.trunk/actions new file mode 120000 index 000000000..fd1f40dd8 --- /dev/null +++ b/.trunk/actions @@ -0,0 +1 @@ +/home/tcsenpai/.cache/trunk/repos/5eae8c518fcb07da321f85242c60f1d2/actions \ No newline at end of file diff --git a/.trunk/configs/.hadolint.yaml b/.trunk/configs/.hadolint.yaml new file mode 100644 index 000000000..ea894f49f --- /dev/null +++ b/.trunk/configs/.hadolint.yaml @@ -0,0 +1,4 @@ +# Following source doesn't work in most setups +ignored: + - SC1090 + - SC1091 diff --git a/.trunk/configs/.markdownlint.yaml b/.trunk/configs/.markdownlint.yaml new file mode 100644 index 000000000..b40ee9d7a --- /dev/null +++ b/.trunk/configs/.markdownlint.yaml @@ -0,0 +1,2 @@ +# Prettier friendly markdownlint config (all formatting rules disabled) +extends: markdownlint/style/prettier diff --git a/.trunk/configs/.shellcheckrc b/.trunk/configs/.shellcheckrc new file mode 100644 index 000000000..8c7b1ada8 --- /dev/null +++ b/.trunk/configs/.shellcheckrc @@ -0,0 +1,7 @@ +enable=all +source-path=SCRIPTDIR +disable=SC2154 + +# If you're having issues with shellcheck following source, disable the errors via: +# disable=SC1090 +# disable=SC1091 diff --git a/.trunk/configs/.yamllint.yaml b/.trunk/configs/.yamllint.yaml new file mode 100644 index 000000000..0ce3fd823 --- /dev/null +++ b/.trunk/configs/.yamllint.yaml @@ -0,0 +1,7 @@ +rules: + quoted-strings: + required: only-when-needed + extra-allowed: ["{|}"] + key-duplicates: {} + octal-values: + forbid-implicit-octal: true diff --git a/.trunk/configs/svgo.config.mjs b/.trunk/configs/svgo.config.mjs new file mode 100644 index 000000000..87908149d --- /dev/null +++ b/.trunk/configs/svgo.config.mjs @@ -0,0 +1,14 @@ +export default { + plugins: [ + { + name: "preset-default", + params: { + overrides: { + removeViewBox: false, // https://github.com/svg/svgo/issues/1128 + sortAttrs: true, + removeOffCanvasPaths: true, + }, + }, + }, + ], +} diff --git a/.trunk/logs b/.trunk/logs new file mode 120000 index 000000000..0094e519e --- /dev/null +++ b/.trunk/logs @@ -0,0 +1 @@ +/home/tcsenpai/.cache/trunk/repos/5eae8c518fcb07da321f85242c60f1d2/logs \ No newline at end of file diff --git a/.trunk/notifications b/.trunk/notifications new file mode 120000 index 000000000..bea183e5e --- /dev/null +++ b/.trunk/notifications @@ -0,0 +1 @@ +/home/tcsenpai/.cache/trunk/repos/5eae8c518fcb07da321f85242c60f1d2/notifications \ No newline at end of file diff --git a/.trunk/out b/.trunk/out new file mode 120000 index 000000000..ea0c21c81 --- /dev/null +++ b/.trunk/out @@ -0,0 +1 @@ +/home/tcsenpai/.cache/trunk/repos/5eae8c518fcb07da321f85242c60f1d2/out \ No newline at end of file diff --git a/.trunk/plugins/trunk b/.trunk/plugins/trunk new file mode 120000 index 000000000..d78216056 --- /dev/null +++ b/.trunk/plugins/trunk @@ -0,0 +1 @@ +/home/tcsenpai/.cache/trunk/plugins/https---github-com-trunk-io-plugins/v1.7.4-4ebadccd80b22638 \ No newline at end of file diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml new file mode 100644 index 000000000..fa0465cc4 --- /dev/null +++ b/.trunk/trunk.yaml @@ -0,0 +1,49 @@ +# This file controls the behavior of Trunk: https://docs.trunk.io/cli +# To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml +version: 0.1 +cli: + version: 1.25.0 +# Trunk provides extensibility via plugins. (https://docs.trunk.io/plugins) +plugins: + sources: + - id: trunk + ref: v1.7.4 + uri: https://github.com/trunk-io/plugins +# Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes) +runtimes: + enabled: + - go@1.21.0 + - node@22.16.0 + - python@3.10.8 +# This is the section where you manage your linters. (https://docs.trunk.io/check/configuration) +lint: + ignore: + - linters: [ALL] + paths: + # Ignore markdown-ish fils + - src/**/*.md + - specs/**/* + - .github/workflows/*.yml + - "*/**/*.md" + - "*.md" + enabled: + - actionlint@1.7.10 + - checkov@3.2.497 + - dotenv-linter@4.0.0 + - eslint@8.57.0 + - git-diff-check + - hadolint@2.14.0 + - markdownlint@0.47.0 + - oxipng@10.0.0 + - prettier@3.8.0 + - shellcheck@0.11.0 + - shfmt@3.6.0 + - svgo@4.0.0 + - taplo@0.10.0 + - trufflehog@3.92.5 + - yamllint@1.38.0 +tools: + enabled: + - tsc@5.9.3 + - uv@0.9.26 + - ts-node@10.9.2 diff --git a/CONSOLE_LOG_AUDIT.md b/CONSOLE_LOG_AUDIT.md index 2cdf8a5c0..2bf9ea6a0 100644 --- a/CONSOLE_LOG_AUDIT.md +++ b/CONSOLE_LOG_AUDIT.md @@ -14,58 +14,63 @@ These bypass the async buffering optimization and can block the event loop. These run during normal node operation and should be converted to CategorizedLogger: ### Consensus Module (`src/libs/consensus/`) -| File | Lines | Category | -|------|-------|----------| -| `v2/PoRBFT.ts` | 245, 332-333, 527, 533 | CONSENSUS | -| `v2/types/secretaryManager.ts` | 900 | CONSENSUS | -| `v2/routines/getShard.ts` | 18 | CONSENSUS | -| `routines/proofOfConsensus.ts` | 15-57 (many) | CONSENSUS | + +| File | Lines | Category | +| ------------------------------ | ---------------------- | --------- | +| `v2/PoRBFT.ts` | 245, 332-333, 527, 533 | CONSENSUS | +| `v2/types/secretaryManager.ts` | 900 | CONSENSUS | +| `v2/routines/getShard.ts` | 18 | CONSENSUS | +| `routines/proofOfConsensus.ts` | 15-57 (many) | CONSENSUS | ### Network Module (`src/libs/network/`) -| File | Lines | Category | -|------|-------|----------| -| `endpointHandlers.ts` | 112-642 (many) | NETWORK | -| `server_rpc.ts` | 431-432 | NETWORK | -| `manageExecution.ts` | 19-117 (many) | NETWORK | -| `manageNodeCall.ts` | 47-466 (many) | NETWORK | -| `manageHelloPeer.ts` | 36 | NETWORK | -| `manageConsensusRoutines.ts` | 194-333 | CONSENSUS | -| `routines/timeSync.ts` | 30-84 (many) | NETWORK | -| `routines/nodecalls/*.ts` | Multiple files | NETWORK | + +| File | Lines | Category | +| ---------------------------- | -------------- | --------- | +| `endpointHandlers.ts` | 112-642 (many) | NETWORK | +| `server_rpc.ts` | 431-432 | NETWORK | +| `manageExecution.ts` | 19-117 (many) | NETWORK | +| `manageNodeCall.ts` | 47-466 (many) | NETWORK | +| `manageHelloPeer.ts` | 36 | NETWORK | +| `manageConsensusRoutines.ts` | 194-333 | CONSENSUS | +| `routines/timeSync.ts` | 30-84 (many) | NETWORK | +| `routines/nodecalls/*.ts` | Multiple files | NETWORK | ### Peer Module (`src/libs/peer/`) -| File | Lines | Category | -|------|-------|----------| -| `Peer.ts` | 113, 125 | PEER | -| `PeerManager.ts` | 52-371 (many) | PEER | -| `routines/checkOfflinePeers.ts` | 9-27 | PEER | -| `routines/peerBootstrap.ts` | 31-100 (many) | PEER | -| `routines/peerGossip.ts` | 228 | PEER | -| `routines/getPeerConnectionString.ts` | 35-39 | PEER | -| `routines/getPeerIdentity.ts` | 32-76 (many) | PEER | + +| File | Lines | Category | +| ------------------------------------- | ------------- | -------- | +| `Peer.ts` | 113, 125 | PEER | +| `PeerManager.ts` | 52-371 (many) | PEER | +| `routines/checkOfflinePeers.ts` | 9-27 | PEER | +| `routines/peerBootstrap.ts` | 31-100 (many) | PEER | +| `routines/peerGossip.ts` | 228 | PEER | +| `routines/getPeerConnectionString.ts` | 35-39 | PEER | +| `routines/getPeerIdentity.ts` | 32-76 (many) | PEER | ### Blockchain Module (`src/libs/blockchain/`) -| File | Lines | Category | -|------|-------|----------| -| `transaction.ts` | 115-490 (many) | CHAIN | -| `chain.ts` | 57-666 (many) | CHAIN | -| `routines/Sync.ts` | 283, 368 | SYNC | -| `routines/validateTransaction.ts` | 38-288 (many) | CHAIN | -| `routines/executeOperations.ts` | 51-98 | CHAIN | -| `gcr/gcr.ts` | 212-1052 (many) | CHAIN | -| `gcr/handleGCR.ts` | 280-399 (many) | CHAIN | + +| File | Lines | Category | +| --------------------------------- | --------------- | -------- | +| `transaction.ts` | 115-490 (many) | CHAIN | +| `chain.ts` | 57-666 (many) | CHAIN | +| `routines/Sync.ts` | 283, 368 | SYNC | +| `routines/validateTransaction.ts` | 38-288 (many) | CHAIN | +| `routines/executeOperations.ts` | 51-98 | CHAIN | +| `gcr/gcr.ts` | 212-1052 (many) | CHAIN | +| `gcr/handleGCR.ts` | 280-399 (many) | CHAIN | ### OmniProtocol Module (`src/libs/omniprotocol/`) -| File | Lines | Category | -|------|-------|----------| -| `transport/PeerConnection.ts` | 407, 464 | NETWORK | -| `transport/ConnectionPool.ts` | 409 | NETWORK | -| `transport/TLSConnection.ts` | 104-189 (many) | NETWORK | -| `server/OmniProtocolServer.ts` | 76-181 (many) | NETWORK | -| `server/InboundConnection.ts` | 55-227 (many) | NETWORK | -| `server/TLSServer.ts` | 110-289 (many) | NETWORK | -| `protocol/handlers/*.ts` | Multiple files | NETWORK | -| `integration/*.ts` | Multiple files | NETWORK | + +| File | Lines | Category | +| ------------------------------ | -------------- | -------- | +| `transport/PeerConnection.ts` | 407, 464 | NETWORK | +| `transport/ConnectionPool.ts` | 409 | NETWORK | +| `transport/TLSConnection.ts` | 104-189 (many) | NETWORK | +| `server/OmniProtocolServer.ts` | 76-181 (many) | NETWORK | +| `server/InboundConnection.ts` | 55-227 (many) | NETWORK | +| `server/TLSServer.ts` | 110-289 (many) | NETWORK | +| `protocol/handlers/*.ts` | Multiple files | NETWORK | +| `integration/*.ts` | Multiple files | NETWORK | --- @@ -74,36 +79,41 @@ These run during normal node operation and should be converted to CategorizedLog These run less frequently but still during operation: ### Identity Module (`src/libs/identity/`) -| File | Lines | Category | -|------|-------|----------| + +| File | Lines | Category | +| ------------------ | -------- | -------- | | `tools/twitter.ts` | 456, 572 | IDENTITY | -| `tools/discord.ts` | 106 | IDENTITY | +| `tools/discord.ts` | 106 | IDENTITY | ### Abstraction Module (`src/libs/abstraction/`) -| File | Lines | Category | -|------|-------|----------| -| `index.ts` | 253 | IDENTITY | -| `web2/github.ts` | 25 | IDENTITY | -| `web2/parsers.ts` | 53 | IDENTITY | + +| File | Lines | Category | +| ----------------- | ----- | -------- | +| `index.ts` | 253 | IDENTITY | +| `web2/github.ts` | 25 | IDENTITY | +| `web2/parsers.ts` | 53 | IDENTITY | ### Crypto Module (`src/libs/crypto/`) -| File | Lines | Category | -|------|-------|----------| -| `cryptography.ts` | 28-271 (many) | CORE | -| `forgeUtils.ts` | 8-45 | CORE | -| `pqc/enigma.ts` | 47 | CORE | + +| File | Lines | Category | +| ----------------- | ------------- | -------- | +| `cryptography.ts` | 28-271 (many) | CORE | +| `forgeUtils.ts` | 8-45 | CORE | +| `pqc/enigma.ts` | 47 | CORE | --- ## đŸŸĸ LOW PRIORITY - Cold Paths ### Startup/Shutdown (`src/index.ts`) + - Lines: 387, 477-565 (shutdown handlers, startup logs) - These run once, acceptable as console for visibility ### Feature Modules (Occasional Use) + - `src/features/multichain/*.ts` - XM operations -- `src/features/fhe/*.ts` - FHE operations +- `src/features/fhe/*.ts` - FHE operations - `src/features/bridges/*.ts` - Bridge operations - `src/features/web2/*.ts` - Web2 proxy - `src/features/InstantMessagingProtocol/*.ts` - IM server @@ -129,16 +139,19 @@ These are CLI utilities where console.log is appropriate: ## Recommendations ### Immediate Actions (P0) -1. Convert consensus hot path logs to `log.debug()` + +1. Convert consensus hot path logs to `log.debug()` 2. Convert peer/network hot path logs to `log.debug()` 3. Convert blockchain validation logs to `log.debug()` ### Short Term (P1) + 4. Convert OmniProtocol logs to CategorizedLogger 5. Convert GCR operation logs to CategorizedLogger 6. Add `OMNI` or similar category for OmniProtocol ### Medium Term (P2) + 7. Audit feature modules and convert where needed 8. Consider adding more log categories for better filtering diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6f2c3a16f..f20e961b4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,11 +31,13 @@ Please refer to [INSTALL.md](INSTALL.md) for all the necessary informations on h ### 1. Create a Feature Branch Always create a feature branch for your work: + ```bash git checkout -b feature/your-feature-name ``` Branch naming conventions: + - `feature/` - New features - `fix/` - Bug fixes - `refactor/` - Code refactoring @@ -62,11 +64,13 @@ bun run lint:fix # Auto-fix issues ### 4. Commit Guidelines Write clear, descriptive commit messages: + - Use present tense ("Add feature" not "Added feature") - Keep the first line under 50 characters - Reference issues when applicable (`Fixes #123`) Example: + ``` Add multichain transaction validation @@ -92,14 +96,15 @@ Fixes #456 ### Pull Request Template When opening a PR, please include: + - **Description** - What does this PR do? - **Motivation** - Why is this change needed? - **Testing** - How has this been tested? - **Breaking changes** - Does this break existing functionality? - **Issues** - Link to related issues - ### Key Principles + - **Modularity** - Keep features isolated and reusable - **Type Safety** - Leverage TypeScript for full type coverage - **Error Handling** - Comprehensive error handling and validation @@ -108,7 +113,9 @@ When opening a PR, please include: ## 🐛 Reporting Issues ### Bug Reports + Include: + - Clear description of the bug - Steps to reproduce - Expected vs actual behavior @@ -116,7 +123,9 @@ Include: - Relevant logs or error messages ### Feature Requests + Include: + - Use case and motivation - Proposed solution - Alternative solutions considered @@ -125,11 +134,13 @@ Include: ## 💡 Development Tips ### Using Bun Effectively + - **Always use Bun** for package management (`bun add`, not `npm install`) - Run TypeScript directly with Bun (`bun src/index.ts`) - Leverage Bun's built-in test runner (`bun test`) ### Code Style + - Use double quotes for strings - No semicolons at statement ends - camelCase for variables and functions @@ -137,6 +148,7 @@ Include: - See [GUIDELINES/CODING.md](GUIDELINES/CODING.md) for complete style guide ### Performance Considerations + - Optimize for readability first, then performance - Use async/await for asynchronous operations - Implement proper caching strategies @@ -145,12 +157,14 @@ Include: ## 🤝 Community ### Code of Conduct + - Be respectful and inclusive - Welcome newcomers and help them get started - Focus on constructive feedback - Report unacceptable behavior to maintainers ### Getting Help + - Review existing documentation - Search through existing issues - Ask questions in discussions diff --git a/GUIDELINES/CODING.md b/GUIDELINES/CODING.md index c02086c0f..80209a9fd 100644 --- a/GUIDELINES/CODING.md +++ b/GUIDELINES/CODING.md @@ -5,130 +5,150 @@ This document provides natural language coding guidelines extracted from the pro ## 1. Code Formatting ### 1.1 Quotes and Semicolons + - **Always use double quotes** for string literals - - ✅ `const message = "Hello World"` - - ❌ `const message = 'Hello World'` + - ✅ `const message = "Hello World"` + - ❌ `const message = 'Hello World'` - **Never use semicolons** at the end of statements - - ✅ `const value = 42` - - ❌ `const value = 42;` + - ✅ `const value = 42` + - ❌ `const value = 42;` ### 1.2 Comma Usage + - **Always include trailing commas** in multi-line structures (arrays, objects, function parameters) - - ✅ Multi-line with trailing comma: - ```typescript - const config = { - host: "localhost", - port: 53550, - debug: true, - } - ``` - - ❌ Multi-line without trailing comma: - ```typescript - const config = { - host: "localhost", - port: 53550, - debug: true - } - ``` + - ✅ Multi-line with trailing comma: + + ```typescript + const config = { + host: "localhost", + port: 53550, + debug: true, + } + ``` + + - ❌ Multi-line without trailing comma: + + ```typescript + const config = { + host: "localhost", + port: 53550, + debug: true, + } + ``` ### 1.3 Switch Statements + - **Add space after colon** in switch case statements, but not before - - ✅ `case "test": return value` - - ❌ `case "test" :return value` - - ❌ `case "test":return value` + - ✅ `case "test": return value` + - ❌ `case "test" :return value` + - ❌ `case "test":return value` ## 2. Naming Conventions ### 2.1 Variables and Functions + - **Use camelCase** for all variables and function names - - ✅ `const userName = "Alice"` - - ✅ `function calculateTotal() { }` - - ❌ `const user_name = "Alice"` - - ❌ `function CalculateTotal() { }` + - ✅ `const userName = "Alice"` + - ✅ `function calculateTotal() { }` + - ❌ `const user_name = "Alice"` + - ❌ `function CalculateTotal() { }` - **Leading underscores are allowed** but should be used sparingly (typically for private/internal properties) - - ✅ `const _internalState = {}` - - ✅ `const normalVariable = {}` + - ✅ `const _internalState = {}` + - ✅ `const normalVariable = {}` ### 2.2 Methods + - **Use camelCase** for all class and object methods - - ✅ `class Service { processData() { } }` - - ❌ `class Service { ProcessData() { } }` + - ✅ `class Service { processData() { } }` + - ❌ `class Service { ProcessData() { } }` ### 2.3 Types and Interfaces + - **Use PascalCase** for all type definitions - - ✅ `type UserProfile = { }` - - ✅ `interface Configuration { }` - - ❌ `type userProfile = { }` + - ✅ `type UserProfile = { }` + - ✅ `interface Configuration { }` + - ❌ `type userProfile = { }` - **Don't prefix interfaces with 'I'** - - ✅ `interface UserService { }` - - ❌ `interface IUserService { }` + - ✅ `interface UserService { }` + - ❌ `interface IUserService { }` ### 2.4 Classes + - **Use PascalCase** for all class names - - ✅ `class NetworkManager { }` - - ❌ `class networkManager { }` - - ❌ `class network_manager { }` + - ✅ `class NetworkManager { }` + - ❌ `class networkManager { }` + - ❌ `class network_manager { }` ### 2.5 Type Aliases + - **Use PascalCase** for type aliases - - ✅ `type ResponseStatus = "success" | "error"` - - ❌ `type responseStatus = "success" | "error"` + - ✅ `type ResponseStatus = "success" | "error"` + - ❌ `type responseStatus = "success" | "error"` ## 3. TypeScript Specific Guidelines ### 3.1 Type Safety + - **Using `any` is allowed** when necessary, but should be avoided when possible - - Prefer specific types or `unknown` when the type is truly unknown - - Document why `any` is used when it's necessary + - Prefer specific types or `unknown` when the type is truly unknown + - Document why `any` is used when it's necessary ### 3.2 Empty Functions + - **Empty functions are permitted** (useful for default callbacks, placeholders, or optional handlers) - - ✅ `const noop = () => {}` - - ✅ `onError: () => {} // Default no-op handler` + - ✅ `const noop = () => {}` + - ✅ `onError: () => {} // Default no-op handler` ### 3.3 CommonJS Requires + - **`require()` statements are allowed** when needed for dynamic imports or CommonJS compatibility - - However, prefer ES6 `import` statements when possible + - However, prefer ES6 `import` statements when possible ### 3.4 Variable Declarations + - **`var` keyword is technically allowed** but strongly discouraged - - Always prefer `const` for values that won't be reassigned - - Use `let` for values that will be reassigned - - ✅ `const API_URL = "https://api.example.com"` - - ✅ `let counter = 0` - - âš ī¸ `var oldStyle = "avoid this"` + - Always prefer `const` for values that won't be reassigned + - Use `let` for values that will be reassigned + - ✅ `const API_URL = "https://api.example.com"` + - ✅ `let counter = 0` + - âš ī¸ `var oldStyle = "avoid this"` ## 4. Code Quality ### 4.1 Unused Variables + - **Unused variables are currently not enforced** by the linter - - However, you should still remove unused code for cleanliness - - Consider commenting out code that might be needed later with explanation + - However, you should still remove unused code for cleanliness + - Consider commenting out code that might be needed later with explanation ### 4.2 Console Statements + - **Console statements are allowed** (no warning for console.log, console.error, etc.) - - Use them appropriately for debugging and logging - - Consider using a proper logging system for production code + - Use them appropriately for debugging and logging + - Consider using a proper logging system for production code ### 4.3 Extra Semicolons + - **No extra semicolons allowed** (this is enforced as an error) - - ❌ `const value = 42;;` - - ❌ `function test() { };` + - ❌ `const value = 42;;` + - ❌ `function test() { };` ## 5. Import Guidelines ### 5.1 Import Restrictions + - **Import restrictions are configured as warnings** - - Follow the project's module structure - - Avoid circular dependencies - - Use proper path aliases when configured + - Follow the project's module structure + - Avoid circular dependencies + - Use proper path aliases when configured ## 6. Environment and Compatibility ### 6.1 Target Environment + - Code runs primarily in **Bun runtime** (with Node.js compatibility) - **Bun is the preferred package manager and runtime** - **ES6 modules** are the primary module system (CommonJS supported for compatibility) @@ -137,6 +157,7 @@ This document provides natural language coding guidelines extracted from the pro - TypeScript is executed directly via Bun without compilation step ### 6.2 Global Variables + - `NodeJS` namespace is available (read-only) - `globalThis` is available for global scope access - Bun-specific globals are available when running under Bun runtime @@ -144,21 +165,25 @@ This document provides natural language coding guidelines extracted from the pro ## 7. Best Practices (Beyond ESLint) ### 7.1 File Organization + - Keep files focused on a single responsibility - Group related functionality in feature modules - Use clear, descriptive file names ### 7.2 Error Handling + - Always handle errors appropriately - Use try-catch blocks for async operations - Provide meaningful error messages ### 7.3 Comments and Documentation + - Write self-documenting code when possible - Add comments for complex logic - Use JSDoc comments for public APIs ### 7.4 Testing + - Write tests for new features - Maintain existing test coverage - Follow the established testing patterns in the codebase @@ -168,22 +193,25 @@ This document provides natural language coding guidelines extracted from the pro ## 8. Package Management and Runtime ### 8.1 Package Manager + - **Always use Bun** as the package manager - - ✅ `bun install` - - ✅ `bun add ` - - ❌ `npm install` - - ❌ `yarn add` + - ✅ `bun install` + - ✅ `bun add ` + - ❌ `npm install` + - ❌ `yarn add` ### 8.2 Running Scripts + - **Use Bun to run TypeScript directly** - - ✅ `bun run