Skip to content

Add TLSNotary Support#554

Merged
tcsenpai merged 49 commits intocustom_protocolfrom
notary
Jan 6, 2026
Merged

Add TLSNotary Support#554
tcsenpai merged 49 commits intocustom_protocolfrom
notary

Conversation

@tcsenpai
Copy link
Contributor

@tcsenpai tcsenpai commented Jan 4, 2026

PR Type

Enhancement, Tests


Description

  • TLSNotary Integration: Comprehensive support for TLS attestation with dual-mode execution (FFI and Docker), including service lifecycle management, proxy management with port pooling, and token-based access control

  • OmniProtocol Implementation: Complete binary protocol stack with TCP transport, message framing, connection pooling, TLS security, and rate limiting for peer-to-peer communication

  • Protocol Handlers: Full handler implementations for control, transaction, sync, consensus, and GCR operations with binary serialization/deserialization

  • Handler Registry: Centralized opcode registry supporting 60+ handlers with validation and HTTP fallback

  • Test Coverage: Comprehensive test suites for OmniProtocol handlers, transaction operations, consensus, and GCR functionality with fixture-based testing

  • Blockchain Integration: TLSNotary support in GCR with native side-effects processing for tlsn_request operations and token creation

  • Logging Improvements: Enhanced logger with async I/O, persistent stream caching, new categories (TLSN, CMD), and structured logging throughout codebase

  • Adapter Pattern: Base adapter class for OmniProtocol client integration with migration mode support (HTTP_ONLY, OMNI_PREFERRED, OMNI_ONLY)

  • RPC Endpoints: New TLSNotary RPC endpoints for proxy requests, token management, and service information


Diagram Walkthrough

flowchart LR
  A["TLSNotary Service<br/>FFI/Docker Mode"] -->|manages| B["Proxy Manager<br/>Port Pooling"]
  A -->|uses| C["Token Manager<br/>Domain-locked Tokens"]
  D["OmniProtocol Server<br/>TLS + Rate Limiting"] -->|routes to| E["Handler Registry<br/>60+ Opcodes"]
  E -->|handles| F["Control/Transaction/<br/>Sync/Consensus/GCR"]
  D -->|manages| G["Connection Pool<br/>Peer TCP Connections"]
  G -->|uses| H["Message Framer<br/>CRC32 Validation"]
  I["GCR Blockchain<br/>Integration"] -->|stores| J["TLSNotary<br/>Attestations"]
  I -->|creates tokens| C
  K["RPC Endpoints"] -->|request| A
  K -->|manage| C
Loading

File Walkthrough

Relevant files
Tests
4 files
handlers.test.ts
OmniProtocol handlers comprehensive test suite                     

tests/omniprotocol/handlers.test.ts

  • Comprehensive test suite for OmniProtocol message handlers with 917
    lines of test cases
  • Tests cover node calls, protocol negotiation, peer management, mempool
    sync, block sync, and GCR operations
  • Includes extensive mocking of dependencies and fixture-based testing
    for real-world scenarios
  • Validates encoding/decoding of binary protocol messages and response
    serialization
+917/-0 
consensus.test.ts
Consensus protocol round-trip encoding tests                         

tests/omniprotocol/consensus.test.ts

  • Round-trip encoding/decoding tests for consensus opcodes
    (proposeBlockHash, setValidatorPhase, greenlight)
  • Tests load fixtures from JSON files and validate request/response
    serialization
  • Includes helper functions for encoding hex bytes and string maps
  • Verifies data integrity through encode-decode cycles without loss
+345/-0 
transaction.test.ts
Transaction opcode serialization test suite                           

tests/omniprotocol/transaction.test.ts

  • New comprehensive test suite for transaction-related OmniProtocol
    opcodes (0x10, 0x11, 0x12, 0x15, 0x16)
  • Tests cover execute, native bridge, bridge operations, confirm, and
    broadcast requests/responses
  • Validates round-trip encoding/decoding without data loss for complex
    nested structures
  • Tests error handling and edge cases like missing parameters and
    validation errors
+452/-0 
gcr.test.ts
GCR operations and JSON envelope serialization tests         

tests/omniprotocol/gcr.test.ts

  • New test suite for GCR (Global Credential Registry) operations and
    JSON envelope serialization
  • Tests cover getIdentities, getPoints, getReferralInfo,
    validateReferral, getAccountByIdentity, and getTopAccounts operations
  • Validates round-trip encoding/decoding for complex nested objects and
    error responses
  • Includes fixture-based testing for address_info.json with real-world
    data structures
+373/-0 
Enhancement
27 files
TLSNotaryService.ts
TLSNotary service with FFI and Docker mode support             

src/features/tlsnotary/TLSNotaryService.ts

  • High-level service class for TLSNotary with dual-mode support (FFI and
    Docker)
  • Implements lifecycle management (initialize, start, stop, shutdown)
    with environment-based configuration
  • Provides health checks, public key retrieval, and attestation
    verification
  • Includes signing key resolution with priority: environment variable >
    file > auto-generate
+818/-0 
proxyManager.ts
TLSNotary WebSocket proxy manager with port pooling           

src/features/tlsnotary/proxyManager.ts

  • Manages wstcp proxy processes for domain-specific TLS attestation with
    lazy cleanup
  • Implements port allocation pool (55000-57000) with automatic recycling
    of idle proxies
  • Spawns proxies on-demand with activity monitoring and automatic stale
    proxy cleanup
  • Provides public WebSocket URL generation with fallback to EXPOSED_URL
    and localhost
+605/-0 
gcr.ts
GCR protocol handlers for identity and credential operations

src/libs/omniprotocol/protocol/handlers/gcr.ts

  • Implements 9 GCR (Global Credential Registry) handler functions for
    OmniProtocol opcodes
  • Handlers support identity management (assign, get), points tracking,
    referral validation, and account lookup
  • Each handler validates request payloads, delegates to GCR routines,
    and encodes responses
  • Includes error handling with appropriate HTTP status codes and error
    messages
+446/-0 
ffi.ts
TLSNotary Rust FFI bindings with bun:ffi integration         

src/features/tlsnotary/ffi.ts

  • FFI bindings for Rust TLSNotary library using bun:ffi with
    platform-specific library loading
  • Implements TLSNotaryFFI class for server lifecycle (start/stop),
    attestation verification, and public key retrieval
  • Handles memory management for FFI struct marshalling and C string
    conversion
  • Provides health status checks and error handling for library
    initialization and operations
+466/-0 
control.ts
Control protocol message serialization implementation       

src/libs/omniprotocol/serialization/control.ts

  • New file implementing serialization/deserialization for peer list,
    node call, and related control protocol messages
  • Defines interfaces for peerlist entries, sync requests/responses, and
    node call payloads
  • Implements encoding/decoding functions using primitive
    encoders/decoders for binary protocol handling
  • Supports complex nested data types including JSON objects, arrays, and
    metadata
+487/-0 
PeerConnection.ts
Peer TCP connection management with state machine               

src/libs/omniprotocol/transport/PeerConnection.ts

  • New class managing single TCP connection to peer node with state
    machine (UNINITIALIZED → CONNECTING → AUTHENTICATING → READY →
    IDLE_PENDING → CLOSING → CLOSED)
  • Implements request-response correlation via sequence IDs, idle timeout
    handling, and in-flight request tracking
  • Supports both authenticated and unauthenticated message sending with
    Ed25519 signing
  • Handles socket lifecycle, message framing, and graceful disconnection
+475/-0 
CategorizedLogger.ts
Logger enhancements with async I/O and new categories       

src/utilities/tui/CategorizedLogger.ts

  • Added two new log categories: TLSN for TLSNotary operations and CMD
    for command execution
  • Refactored file I/O from synchronous to asynchronous using fs.promises
    for better performance
  • Implemented persistent WriteStream caching for log files instead of
    repeated appendFile calls
  • Added terminal output buffering with setImmediate scheduling for
    improved performance
  • Adjusted log level priority ordering (debug moved to lowest priority)
+157/-54
sync.ts
Data synchronization protocol message serialization           

src/libs/omniprotocol/serialization/sync.ts

  • New file implementing serialization for mempool, block, and
    transaction synchronization protocol messages
  • Defines interfaces for mempool responses, sync requests/responses, and
    block metadata
  • Implements encoding/decoding for block entries, transaction hashes,
    and block sync operations
  • Supports complex metadata structures with string arrays and nested
    block information
+425/-0 
ConnectionPool.ts
Connection pool for peer node management                                 

src/libs/omniprotocol/transport/ConnectionPool.ts

  • New class managing pool of persistent TCP connections to multiple peer
    nodes
  • Implements per-peer connection pooling with global connection limits
    and lazy connection creation
  • Provides automatic idle connection cleanup, health monitoring, and
    connection reuse
  • Includes convenience methods for sending authenticated and
    unauthenticated requests with connection lifecycle management
+415/-0 
consensus.ts
Consensus protocol message serialization                                 

src/libs/omniprotocol/serialization/consensus.ts

  • New file implementing serialization for consensus protocol messages
    (block hash proposals, validator phases, greenlight)
  • Defines interfaces for proposeBlockHash, setValidatorPhase,
    greenlight, and related consensus operations
  • Implements hex-aware encoding/decoding with string map support for
    validation data and signatures
  • Supports metadata fields and complex validator state management
+393/-0 
registry.ts
OmniProtocol opcode handler registry                                         

src/libs/omniprotocol/protocol/registry.ts

  • New file implementing handler registry for all OmniProtocol opcodes
    across control, transaction, sync, consensus, and GCR operations
  • Defines HandlerDescriptor interface with opcode, name, auth
    requirements, and handler function
  • Registers 60+ handlers with validation for duplicate opcode
    registration
  • Provides getHandler() function for opcode lookup with fallback HTTP
    handler support
+164/-0 
handleGCR.ts
TLSNotary integration and native transaction side-effects

src/libs/blockchain/gcr/handleGCR.ts

  • Added TLSNotary support with GCRTLSNotaryRoutines for attestation
    proof storage
  • Implemented processNativeSideEffects() method to handle token creation
    for tlsn_request operations during mempool entry
  • Added new GCREdit types: smartContract, storageProgram, escrow, and
    tlsnotary
  • Replaced console.log/console.error calls with structured logging via
    log utility
  • Added token management imports and domain extraction for TLSNotary URL
    validation
+86/-6   
tokenManager.ts
TLSNotary attestation token manager implementation             

src/features/tlsnotary/tokenManager.ts

  • Implements in-memory token management system for paid TLSNotary
    attestation access
  • Tokens are domain-locked, expire after 30 minutes, and support 3
    retries
  • Provides token lifecycle management (create, validate, consume, mark
    completed/stored)
  • Includes automatic cleanup of expired tokens via periodic timer
+352/-0 
index.ts
OmniProtocol and TLSNotary service integration in main entry point

src/index.ts

  • Adds OmniProtocol TCP server initialization with TLS and rate limiting
    configuration
  • Integrates TLSNotary service startup with port collision detection and
    graceful shutdown
  • Adds log-level command-line parameter for dynamic log level adjustment
  • Implements graceful shutdown handlers for SIGTERM/SIGINT signals
+180/-0 
TLSServer.ts
TLS-enabled OmniProtocol server with rate limiting             

src/libs/omniprotocol/server/TLSServer.ts

  • Implements TLS-enabled TCP server wrapping with certificate validation
    and fingerprint verification
  • Integrates rate limiting for connection and request throttling
  • Handles secure socket connections with TLS protocol negotiation
  • Provides server statistics and trusted peer management
+314/-0 
MessageFramer.ts
OmniProtocol message framing and serialization layer         

src/libs/omniprotocol/transport/MessageFramer.ts

  • Parses TCP byte streams into complete OmniProtocol messages with
    header and checksum validation
  • Supports both legacy messages and messages with authentication blocks
  • Implements CRC32 checksum validation for data integrity
  • Provides message encoding functionality for outbound communication
+303/-0 
manageNodeCall.ts
TLSNotary RPC endpoints and logging improvements                 

src/libs/network/manageNodeCall.ts

  • Adds three new TLSNotary RPC endpoints: requestTLSNproxy,
    tlsnotary.getInfo, tlsnotary.getToken, tlsnotary.getTokenStats
  • Implements token validation and retry consumption for proxy requests
  • Replaces console.log calls with structured logging via log module
  • Improves error handling and response formatting for consistency
+213/-11
RateLimiter.ts
Rate limiting implementation with sliding window algorithm

src/libs/omniprotocol/ratelimit/RateLimiter.ts

  • Implements sliding window rate limiting for both IP-based and
    identity-based limits
  • Tracks connections per IP and requests per second with automatic
    blocking
  • Provides manual block/unblock functionality and statistics reporting
  • Includes periodic cleanup of expired rate limit entries
+331/-0 
consensus.ts
OmniProtocol consensus operation handlers                               

src/libs/omniprotocol/protocol/handlers/consensus.ts

  • Implements binary protocol handlers for consensus operations
    (proposeBlockHash, setValidatorPhase, greenlight, etc.)
  • Wraps existing HTTP consensus handlers with OmniProtocol binary
    encoding/decoding
  • Provides handlers for validator phase management and block timestamp
    queries
  • Includes error handling and response serialization
+297/-0 
InboundConnection.ts
Inbound connection handler for OmniProtocol server             

src/libs/omniprotocol/server/InboundConnection.ts

  • Manages individual inbound peer connections with message parsing and
    dispatching
  • Implements authentication via auth blocks in messages (not just
    hello_peer)
  • Integrates rate limiting checks for both IP and identity-based limits
  • Handles graceful connection closure and error responses
+296/-0 
sync.ts
OmniProtocol blockchain synchronization handlers                 

src/libs/omniprotocol/protocol/handlers/sync.ts

  • Implements binary protocol handlers for blockchain synchronization
    operations
  • Provides handlers for mempool sync, block retrieval, and transaction
    queries
  • Supports block range queries and transaction merging
  • Includes proper error handling and response encoding
+268/-0 
consensusAdapter.ts
OmniProtocol consensus adapter with HTTP fallback               

src/libs/omniprotocol/integration/consensusAdapter.ts

  • Routes consensus RPC calls to dedicated OmniProtocol opcodes for
    binary-efficient communication
  • Implements fallback to HTTP via NODE_CALL for unsupported consensus
    methods
  • Manages encoder/decoder selection based on consensus method type
  • Includes error handling with graceful HTTP fallback
+282/-0 
LegacyLoggerAdapter.ts
Logger adapter improvements for flexible type handling     

src/utilities/tui/LegacyLoggerAdapter.ts

  • Adds stringify() helper function to handle any value type in logging
    (matches console.log behavior)
  • Updates all logging methods to accept unknown type instead of string
  • Supports optional second parameter for additional data logging
  • Adds warn() alias for warning() method for compatibility
+81/-30 
transaction.ts
OmniProtocol transaction operation handlers                           

src/libs/omniprotocol/protocol/handlers/transaction.ts

  • Implements binary protocol handlers for transaction operations
    (execute, broadcast, confirm)
  • Wraps existing HTTP transaction handlers with OmniProtocol binary
    encoding
  • Provides handlers for native bridge and cross-chain bridge operations
  • Includes validation and error handling for transaction flows
+252/-0 
BaseAdapter.ts
Base adapter class for OmniProtocol client integration     

src/libs/omniprotocol/integration/BaseAdapter.ts

  • Provides base class for OmniProtocol adapters with shared utilities
  • Implements migration mode logic (HTTP_ONLY, OMNI_PREFERRED, OMNI_ONLY)
  • Includes HTTP-to-TCP URL conversion and key management utilities
  • Provides fatal error handling and connection pool access
+252/-0 
manageConsensusRoutines.ts
Consensus routines logging improvements                                   

src/libs/network/manageConsensusRoutines.ts

  • Replaces console.log calls with structured logging via log module
  • Removes pretty-printing from JSON.stringify calls for consistency
  • Improves debug logging for consensus message handling
+5/-8     
index.ts
TLS module index and exports                                                         

src/libs/omniprotocol/tls/index.ts

  • Creates new module index file for TLS functionality exports
  • Exports types, certificate utilities, and initialization functions
+3/-0     
Formatting
1 files
getTransactions.ts
Replace console.log with structured logging                           

src/libs/network/routines/nodecalls/getTransactions.ts

  • Replaces console.log with log.debug for consistent logging
  • Adds import of logger utility module
+2/-1     
Additional files
101 files
.local_version +1/-0     
config.yaml +119/-0 
issues.jsonl +77/-0   
metadata.json +4/-0     
.dockerignore +15/-0   
.env.example +35/-2   
.eslintrc.cjs +56/-1   
.prettierrc +1/-2     
_continue_here.md +26/-0   
_index.md +23/-21 
data_structure_robustness_completed.md +0/-44   
devnet_docker_setup.md +53/-0   
genesis_caching_security_dismissed.md +0/-38   
input_validation_improvements_completed.md +0/-80   
omniprotocol_complete_2025_11_11.md +407/-0 
omniprotocol_session_2025-12-01.md +48/-0   
omniprotocol_wave8.1_complete.md +345/-0 
omniprotocol_wave8_tcp_physical_layer.md +485/-0 
pr_review_all_high_priority_completed.md +0/-56   
pr_review_analysis_complete.md +0/-70   
pr_review_corrected_analysis.md +0/-73   
pr_review_import_fix_completed.md +0/-38   
pr_review_json_canonicalization_dismissed.md +0/-31   
pr_review_point_system_fixes_completed.md +0/-70   
project_patterns_telegram_identity_system.md +0/-135 
session_2025_03_web2_dahr_sanitization.md +0/-5     
session_2025_10_10_telegram_group_membership.md +0/-94   
session_checkpoint_2025_01_31.md +0/-53   
session_final_checkpoint_2025_01_31.md +0/-59   
session_pr_review_completion_2025_01_31.md +0/-122 
telegram_identity_system_complete.md +0/-105 
telegram_points_conditional_requirement.md +0/-30   
telegram_points_implementation_decision.md +0/-75   
tlsnotary_integration_context.md +79/-0   
typescript_audit_complete_2025_12_17.md +70/-0   
AGENTS.md +34/-0   
CONSOLE_LOG_AUDIT.md +167/-0 
OMNIPROTOCOL_SETUP.md +294/-0 
OMNIPROTOCOL_TLS_GUIDE.md +455/-0 
01_MESSAGE_FORMAT.md +253/-0 
02_OPCODE_MAPPING.md +385/-0 
03_PEER_DISCOVERY.md +843/-0 
04_CONNECTION_MANAGEMENT.md +1237/-0
05_PAYLOAD_STRUCTURES.md +1350/-0
06_MODULE_STRUCTURE.md +2096/-0
07_PHASED_IMPLEMENTATION.md +141/-0 
08_TCP_SERVER_IMPLEMENTATION.md +932/-0 
09_AUTHENTICATION_IMPLEMENTATION.md +989/-0 
10_TLS_IMPLEMENTATION_PLAN.md +383/-0 
IMPLEMENTATION_SUMMARY.md +381/-0 
SPECIFICATION.md +398/-0 
README.md +30/-0   
.env.example +21/-0   
Dockerfile +36/-0   
README.md +198/-0 
docker-compose.yml +146/-0 
init-databases.sql +11/-0   
run-devnet +170/-0 
attach.sh +30/-0   
build.sh +1/-0     
build_clean.sh +1/-0     
generate-identities.sh +40/-0   
generate-identity-helper.ts +39/-0   
generate-peerlist.sh +56/-0   
logs.sh +37/-0   
setup.sh +39/-0   
watch-all.sh +62/-0   
address_info.json +1/-0     
block_header.json +1/-0     
greenlight_01.json +23/-0   
greenlight_02.json +23/-0   
greenlight_03.json +23/-0   
greenlight_04.json +23/-0   
greenlight_05.json +23/-0   
greenlight_06.json +23/-0   
greenlight_07.json +23/-0   
greenlight_08.json +23/-0   
greenlight_09.json +23/-0   
greenlight_10.json +23/-0   
proposeBlockHash_01.json +31/-0   
proposeBlockHash_02.json +31/-0   
setValidatorPhase_01.json +27/-0   
setValidatorPhase_02.json +27/-0   
setValidatorPhase_03.json +27/-0   
setValidatorPhase_04.json +27/-0   
setValidatorPhase_05.json +27/-0   
setValidatorPhase_06.json +27/-0   
setValidatorPhase_07.json +27/-0   
setValidatorPhase_08.json +27/-0   
setValidatorPhase_09.json +27/-0   
setValidatorPhase_10.json +27/-0   
last_block_number.json +1/-0     
mempool.json +1/-0     
peerlist.json +1/-0     
peerlist_hash.json +1/-0     
git-town.toml +9/-0     
install-deps.sh +11/-0   
jest.config.ts +24/-5   
knip.json +10/-0   
auth_ping_demos.ts +28/-0   
Additional files not shown

Summary by CodeRabbit

  • New Features

    • TLSNotary attestation: FFI & Docker modes, attestation tokens, on-demand WebSocket proxying, HTTP API, SDK integration guidance, and TUI/CLI status surface.
  • Bug Fixes / Security

    • Added payload-size guards to network framing to reduce DoS risk.
  • Chores

    • Added install script and Docker setup, updated environment sample, dependency bumps, and version bumped to 0.43.0.

✏️ Tip: You can customize this high-level summary in your review settings.

tcsenpai and others added 20 commits January 3, 2026 10:11
Implements TLSNotary (MPC-TLS) support in the Demos node for verifiable
HTTPS attestation proofs without compromising user privacy.

Key changes:
- Add libs/tlsn/ with pre-built Rust library (libtlsn_notary.so)
- Create src/features/tlsnotary/ feature module:
  - ffi.ts: Bun FFI bindings to Rust library
  - TLSNotaryService.ts: Service wrapper with lifecycle management
  - routes.ts: HTTP API endpoints (/tlsnotary/health, /info, /verify)
  - index.ts: Feature entry point with exports
- Integrate with node startup in src/index.ts:
  - Add indexState properties for configuration
  - Initialize service in main() with failsafe pattern
  - Add graceful shutdown cleanup
- Register routes in src/libs/network/server_rpc.ts

Configuration via environment variables:
- TLSNOTARY_ENABLED: Enable/disable (default: false)
- TLSNOTARY_PORT: WebSocket port (default: 7047)
- TLSNOTARY_SIGNING_KEY: 32-byte hex secp256k1 key (required if enabled)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add tlsnotary.getInfo nodeCall handler for SDK auto-configuration
- Implement signing key resolution with priority: ENV > file > auto-generate
- Add .tlsnotary-key to gitignore for secure key storage
- Update .env.example with TLSNotary configuration variables

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ution

- Replace all console.log/warn/error with log.info/warning/error
- Fix TypeScript error: use exposedUrl instead of non-existent host property
- Parse URL hostname from exposedUrl for WebSocket notary URLs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add TLSN LogCategory type for TLSNotary HTTPS attestation operations
- Add tag mappings: TLSNOTARY, TLSNotary, TLSN, NOTARY, ATTESTATION
- Add TLSN tab (key: =) to TUI, move CMD to backslash key

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use 'as any' casts for FFI pointer parameters to match the reference
implementation in demos_tlsnotary/node/ts/TLSNotary.ts. This resolves
8 TypeScript errors where 'number' was not assignable to 'Pointer'.

The bun:ffi Pointer type is branded (number & { __pointer__: null })
but at runtime, pointers are plain numbers. The 'as any' pattern is
the pragmatic solution used by the upstream reference implementation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The TLSN and CMD categories were defined in LogCategory type and
tagCategories.ts but were missing from the ALL_CATEGORIES array
that initializes the per-category ring buffers. This caused logs
for these categories to not be stored/displayed in their tabs.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Extended NodeInfo interface with optional tlsnotary field (enabled, port, running)
- Added TLSN status indicator on line 5 of header with visual indicators:
  - 🔐 icon + green "✓ :port" when running
  - 🔐 icon + red "✗ STOPPED" when not running
- Updated index.ts to push TLSNotary info to TUI after initialization
- Fixed lint error: wrapped case block lexical declaration in braces

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@noble/ed25519 v3.x has TypeScript type issues with sha512Sync configuration.
Switched to node-forge's forge.pki.ed25519.sign/verify which is consistent
with the SDK's Cryptography module and doesn't require SHA-512 configuration.

This fixes "hashes.sha512 not set" error during Ed25519 signing/verification.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When OmniProtocol wraps RPC calls in NODE_CALL, the hello_peer method
was falling through to manageNodeCall which lacks a hello_peer case,
resulting in "Received unknown message" warnings.

Added hello_peer routing in handleNodeCall (control.ts) to forward the
request to manageHelloPeer with the authenticated peer identity from
the OmniProtocol auth block.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added environment variables for TLSNotary debugging:
- TLSNOTARY_FATAL: Make errors fatal (exit on failure) for debugging
- TLSNOTARY_DEBUG: Enable verbose debug logging

Also added:
- Port collision warning when both OmniProtocol and TLSNotary are enabled
- More detailed error logging during initialization and start
- Fatal mode support in index.ts for early exit on TLSNotary failure

This helps diagnose issues like the "WebSocket upgrade failed" error
which can occur when OmniProtocol tries to connect to TLSNotary port.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add TLSNOTARY_PROXY environment variable that enables a TCP proxy
to intercept and log all incoming data before forwarding to the Rust
server. This helps debug what's connecting to the TLSNotary port.

When enabled:
- Rust server runs on port+1 (internal)
- Node.js proxy listens on configured port
- All incoming data is logged (text + hex preview)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ation

Adds WebSocket proxy spawning system for domain-specific TLS attestation:

- portAllocator.ts: Port pool management (55000-57000) with sequential
  allocation and recycling
- proxyManager.ts: Proxy lifecycle management with:
  - wstcp binary auto-installation
  - Activity monitoring with 30s idle timeout
  - Lazy cleanup on subsequent requests
  - Status reporting and manual kill controls
- requestTLSNproxy nodeCall: SDK endpoint for dynamic proxy requests
- SDK_INTEGRATION.md: Integration documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Token Manager:
- In-memory token store for paid attestation access
- Domain-locked tokens with 30min expiry, 3 retries
- Full lifecycle: pending → active → completed → stored
- Periodic cleanup of expired tokens

Proxy Manager Fixes:
- Better error detection: catch wstcp panics from stderr
- Detect "Address already in use" errors properly
- Port availability: use actual socket binding test instead of lsof

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@tcsenpai
Copy link
Contributor Author

tcsenpai commented Jan 4, 2026

Your trial has ended! 😢

To keep getting reviews, activate your plan here.

Got questions about plans or want to see if we can extend your trial? Talk to our founders here.😎

@github-actions
Copy link

github-actions bot commented Jan 4, 2026

⚠️ MCP Memory Files Detected

This PR modifies .serena/ files. After merge, these changes will be automatically reverted to preserve branch-specific MCP memories.

Files that will be reverted:

  • .serena/memories/_continue_here.md
  • .serena/memories/_index.md
  • .serena/memories/data_structure_robustness_completed.md
  • .serena/memories/devnet_docker_setup.md
  • .serena/memories/genesis_caching_security_dismissed.md
  • .serena/memories/input_validation_improvements_completed.md
  • .serena/memories/omniprotocol_complete_2025_11_11.md
  • .serena/memories/omniprotocol_session_2025-12-01.md
  • .serena/memories/omniprotocol_wave8.1_complete.md
  • .serena/memories/omniprotocol_wave8_tcp_physical_layer.md
  • .serena/memories/pr_review_all_high_priority_completed.md
  • .serena/memories/pr_review_analysis_complete.md
  • .serena/memories/pr_review_corrected_analysis.md
  • .serena/memories/pr_review_import_fix_completed.md
  • .serena/memories/pr_review_json_canonicalization_dismissed.md
  • .serena/memories/pr_review_point_system_fixes_completed.md
  • .serena/memories/project_patterns_telegram_identity_system.md
  • .serena/memories/session_2025_03_web2_dahr_sanitization.md
  • .serena/memories/session_2025_10_10_telegram_group_membership.md
  • .serena/memories/session_checkpoint_2025_01_31.md
  • .serena/memories/session_final_checkpoint_2025_01_31.md
  • .serena/memories/session_pr_review_completion_2025_01_31.md
  • .serena/memories/telegram_identity_system_complete.md
  • .serena/memories/telegram_points_conditional_requirement.md
  • .serena/memories/telegram_points_implementation_decision.md
  • .serena/memories/tlsnotary_integration_context.md
  • .serena/memories/typescript_audit_complete_2025_12_17.md

@github-actions
Copy link

github-actions bot commented Jan 4, 2026

⚠️ 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.

Files that will be reverted:

  • .beads/issues.jsonl
  • .beads/metadata.json

@tcsenpai tcsenpai changed the base branch from testnet to custom_protocol January 4, 2026 17:00
@kynesyslabs kynesyslabs deleted a comment from coderabbitai bot Jan 4, 2026
@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Jan 4, 2026

PR Compliance Guide 🔍

(Compliance updated until commit 2f0ea12)

Below is a summary of compliance checks for this PR:

Security Compliance
Open proxy / SSRF

Description: The proxy manager can install and execute wstcp at runtime (via execAsync("cargo install
wstcp") and spawn("wstcp", ...)) and binds the proxy on 0.0.0.0, creating a realistic
attack surface for supply-chain/runtime code execution and exposing an externally
reachable TCP→WebSocket proxy that can be abused as an open proxy/SSRF vector to arbitrary
domain:port targets (including internal hosts), subject only to possession of a token.
proxyManager.ts [126-286]

Referred Code
export async function ensureWstcp(): Promise<void> {
  try {
    await execAsync("which wstcp")
    log.debug("[TLSNotary] wstcp binary found")
  } catch {
    log.info("[TLSNotary] wstcp not found, installing via cargo...")
    try {
      await execAsync("cargo install wstcp")
      log.info("[TLSNotary] wstcp installed successfully")
    } catch (installError: any) {
      throw new Error(`Failed to install wstcp: ${installError.message}`)
    }
  }
}

/**
 * Extract domain and port from a target URL
 * @param targetUrl - Full URL like "https://api.example.com:8443/endpoint"
 * @returns Domain and port extracted from URL
 */
export function extractDomainAndPort(targetUrl: string): {


 ... (clipped 140 lines)
Sensitive data logging

Description: When TLSNOTARY_PROXY=true, the debug TCP proxy logs raw incoming client data (both UTF-8
preview and hex) which can include secrets (e.g., HTTP headers, cookies, auth tokens,
session material), risking sensitive information exposure in logs if enabled in any
non-local environment.
TLSNotaryService.ts [503-570]

Referred Code
private async startWithProxy(): Promise<void> {
  const net = await import("net")
  const publicPort = this.config.port
  const rustPort = this.config.port + 1

  // Start Rust server on internal port
  await this.ffi!.startServer(rustPort)
  log.info(`[TLSNotary] Rust server started on internal port ${rustPort}`)

  // Close any previous proxy server (defensive)
  if (this.proxyServer) {
    try {
      this.proxyServer.close()
    } catch {
      // ignore
    }
    this.proxyServer = null
  }

  // Create proxy server on public port
  this.proxyServer = net.createServer((clientSocket) => {


 ... (clipped 47 lines)
Unbounded data storage

Description: The tlsn_store native operation persists the full proof payload into blockchain state
without an explicit maximum size limit, enabling resource exhaustion (disk/state bloat,
memory pressure during processing) even if a fee is charged, since an attacker can pay to
store arbitrarily large data.
handleNativeOperations.ts [83-148]

Referred Code
case "tlsn_store": {
    const [tokenId, proof, storageType] = nativePayload.args
    log.info(`[TLSNotary] Processing tlsn_store for token ${tokenId}, storage: ${storageType}`)

    // Validate token exists and belongs to sender
    const token = getToken(tokenId)
    if (!token) {
        log.error(`[TLSNotary] Token not found: ${tokenId}`)
        break
    }
    if (token.owner !== tx.content.from) {
        log.error(`[TLSNotary] Token owner mismatch: ${token.owner} !== ${tx.content.from}`)
        break
    }
    // Token should be completed (attestation done) or active (in progress)
    if (token.status !== TokenStatus.COMPLETED && token.status !== TokenStatus.ACTIVE) {
        log.error(`[TLSNotary] Token not ready for storage: ${token.status}`)
        break
    }

    // Calculate storage fee: base + per KB (use byte length, not string length)


 ... (clipped 45 lines)
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

🔴
Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Silent failure: The new tlsn_store native operation logs errors and then breaks without throwing or
returning an error, which can silently accept/ignore invalid requests (e.g., missing
token, owner mismatch, invalid status) without clear failure signaling to callers.

Referred Code
case "tlsn_store": {
    const [tokenId, proof, storageType] = nativePayload.args
    log.info(`[TLSNotary] Processing tlsn_store for token ${tokenId}, storage: ${storageType}`)

    // Validate token exists and belongs to sender
    const token = getToken(tokenId)
    if (!token) {
        log.error(`[TLSNotary] Token not found: ${tokenId}`)
        break
    }
    if (token.owner !== tx.content.from) {
        log.error(`[TLSNotary] Token owner mismatch: ${token.owner} !== ${tx.content.from}`)
        break
    }
    // Token should be completed (attestation done) or active (in progress)
    if (token.status !== TokenStatus.COMPLETED && token.status !== TokenStatus.ACTIVE) {
        log.error(`[TLSNotary] Token not ready for storage: ${token.status}`)
        break
    }

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status:
Leaky 500 errors: The /tlsnotary/verify handler returns error.message on 500 responses, which can expose
internal implementation details to end-users instead of a generic user-facing error.

Referred Code
} catch (error) {
  const response: VerifyResponse = {
    success: false,
    error: error instanceof Error ? error.message : "Unknown error during verification",
  }
  return jsonResponse(response, 500)
}

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status:
Logs raw client data: The debug proxy logs plaintext and hex previews of all incoming bytes, which can include
secrets (cookies, auth headers, tokens, PII) and violates the requirement to avoid
sensitive data in logs.

Referred Code
clientSocket.on("data", (data) => {
  const preview = data.slice(0, 500).toString("utf-8")
  const hexPreview = data.slice(0, 100).toString("hex")
  log.info(`[TLSNotary-Proxy] <<< FROM ${clientAddr} (${data.length} bytes):`)
  log.info(`[TLSNotary-Proxy] Text: ${preview}`)
  log.info(`[TLSNotary-Proxy] Hex:  ${hexPreview}`)
  rustSocket.write(data)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Unbounded proof input: The new tlsn_store path accepts and stores proof without any explicit maximum size/format
validation, enabling potential resource exhaustion and unsafe on-chain data handling.

Referred Code
// Calculate storage fee: base + per KB (use byte length, not string length)
const proofBytes =
    typeof proof === "string"
        ? Buffer.byteLength(proof, "utf8")
        : (proof as Uint8Array).byteLength

const proofSizeKB = Math.ceil(proofBytes / 1024)
const storageFee = TLSN_STORE_BASE_FEE + (proofSizeKB * TLSN_STORE_PER_KB_FEE)
log.info(`[TLSNotary] Proof size: ${proofSizeKB}KB, fee: ${storageFee} DEM`)

// Burn the storage fee
const burnStorageFeeEdit: GCREdit = {
    type: "balance",
    operation: "remove",
    isRollback: isRollback,
    account: tx.content.from as string,
    txhash: tx.hash,
    amount: storageFee,
}
edits.push(burnStorageFeeEdit)



 ... (clipped 17 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Audit context unclear: The PR adds logs for token/proxy actions, but it is not verifiable from the diff alone
that logs are emitted for all sensitive read/write actions with consistent user
identifiers and outcomes across all new TLSNotary RPC/native-operation paths.

Referred Code
export function createToken(
  owner: string,
  targetUrl: string,
  txHash: string,
): AttestationToken {
  const store = getTokenStore()
  const now = Date.now()
  const domain = extractDomain(targetUrl)

  const token: AttestationToken = {
    id: generateTokenId(),
    owner,
    domain,
    status: TokenStatus.PENDING,
    createdAt: now,
    expiresAt: now + TOKEN_CONFIG.EXPIRY_MS,
    retriesLeft: TOKEN_CONFIG.MAX_RETRIES,
    txHash,
  }

  store.tokens.set(token.id, token)


 ... (clipped 3 lines)

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

Previous compliance checks

Compliance check up to commit bff37bb
Security Compliance
Open proxy / SSRF

Description: The proxy manager can spawn externally reachable wstcp processes bound to 0.0.0.0 for
arbitrary user-supplied targetUrl domains/ports, which can become an open proxy/SSRF
primitive (e.g., an attacker requests a proxy to internal hosts or scans ports via
requestProxy() and then connects to the returned websocketProxyUrl).
proxyManager.ts [130-515]

Referred Code
export async function ensureWstcp(): Promise<void> {
  try {
    await execAsync("which wstcp")
    log.debug("[TLSNotary] wstcp binary found")
  } catch {
    log.info("[TLSNotary] wstcp not found, installing via cargo...")
    try {
      await execAsync("cargo install wstcp")
      log.info("[TLSNotary] wstcp installed successfully")
    } catch (installError: any) {
      throw new Error(`Failed to install wstcp: ${installError.message}`)
    }
  }
}

/**
 * Extract domain and port from a target URL
 * @param targetUrl - Full URL like "https://api.example.com:8443/endpoint"
 * @returns Domain and port extracted from URL
 */
export function extractDomainAndPort(targetUrl: string): {



 ... (clipped 365 lines)
Private key persistence

Description: The service auto-generates and persists a long-lived TLSNotary signing private key to a
predictable local file .tlsnotary-key in the working directory, which risks secret
exposure via accidental commits, backups, container image layers, or overly-broad
filesystem access (even though it attempts 0o600 permissions).
TLSNotaryService.ts [68-119]

Referred Code
// REVIEW: Key file path for persistent storage of auto-generated keys
const SIGNING_KEY_FILE = ".tlsnotary-key"

/**
 * Resolve the TLSNotary signing key with priority: ENV > file > auto-generate
 *
 * Priority order:
 * 1. TLSNOTARY_SIGNING_KEY environment variable (highest priority)
 * 2. .tlsnotary-key file in project root
 * 3. Auto-generate and save to .tlsnotary-key file
 *
 * @returns 64-character hex string (32-byte key) or null on error
 */
function resolveSigningKey(): string | null {
  // Priority 1: Environment variable
  const envKey = process.env.TLSNOTARY_SIGNING_KEY
  if (envKey && envKey.length === 64) {
    log.info("[TLSNotary] Using signing key from environment variable")
    return envKey
  } else if (envKey && envKey.length !== 64) {
    log.warning("[TLSNotary] TLSNOTARY_SIGNING_KEY must be 64 hex characters (32 bytes)")



 ... (clipped 31 lines)
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

🔴
Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status:
Logs raw traffic: The debug proxy logs plaintext and hex previews of all incoming client data which can
include sensitive headers, cookies, tokens, or credentials.

Referred Code
clientSocket.on("data", (data) => {
  const preview = data.slice(0, 500).toString("utf-8")
  const hexPreview = data.slice(0, 100).toString("hex")
  log.info(`[TLSNotary-Proxy] <<< FROM ${clientAddr} (${data.length} bytes):`)
  log.info(`[TLSNotary-Proxy] Text: ${preview}`)
  log.info(`[TLSNotary-Proxy] Hex:  ${hexPreview}`)
  rustSocket.write(data)
})

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Unrestricted proxy target: requestProxy accepts arbitrary targetUrl and spawns a network proxy to the extracted
domain/port without visible authorization or allowlisting, enabling SSRF-style proxying to
attacker-chosen destinations.

Referred Code
export async function requestProxy(
  targetUrl: string,
  requestOrigin?: string,
): Promise<ProxyRequestSuccess | ProxyRequestError> {
  // 1. Ensure wstcp is available
  try {
    await ensureWstcp()
  } catch (err: any) {
    return {
      error: ProxyError.WSTCP_NOT_AVAILABLE,
      message: err.message,
    }
  }

  // 2. Extract domain and port
  let domain: string
  let targetPort: number
  try {
    const extracted = extractDomainAndPort(targetUrl)
    domain = extracted.domain
    targetPort = extracted.port



 ... (clipped 78 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Missing user context: Proxy creation/termination actions are logged but without any user identifier or request
context, making it unclear whether audit trail requirements are fully met.

Referred Code
export async function requestProxy(
  targetUrl: string,
  requestOrigin?: string,
): Promise<ProxyRequestSuccess | ProxyRequestError> {
  // 1. Ensure wstcp is available
  try {
    await ensureWstcp()
  } catch (err: any) {
    return {
      error: ProxyError.WSTCP_NOT_AVAILABLE,
      message: err.message,
    }
  }

  // 2. Extract domain and port
  let domain: string
  let targetPort: number
  try {
    const extracted = extractDomainAndPort(targetUrl)
    domain = extracted.domain
    targetPort = extracted.port



 ... (clipped 122 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Fatal exits: Multiple failure paths use process.exit(1) under TLSNOTARY_FATAL, which may not provide
graceful degradation and needs confirmation this is acceptable for production.

Referred Code
  if (fatal) {
    log.error("[TLSNotary] FATAL: " + error.message)
    process.exit(1)
  }
  throw error
}

if (signingKeyBytes.length !== 32) {
  const error = new Error("Signing key must be exactly 32 bytes")
  if (fatal) {
    log.error("[TLSNotary] FATAL: " + error.message)
    process.exit(1)
  }
  throw error
}

const ffiConfig: NotaryConfig = {
  signingKey: signingKeyBytes,
  maxSentData: this.config.maxSentData,
  maxRecvData: this.config.maxRecvData,
}



 ... (clipped 134 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status:
Detailed error text: Errors thrown/logged include internal connectivity details (e.g., localhost endpoints and
port values), which may be user-facing depending on how callers surface these errors.

Referred Code
log.info(`[TLSNotary] Docker mode: checking container on port ${this.config.port}...`)

try {
  // Try to fetch /info endpoint to verify container is running
  const infoUrl = `http://localhost:${this.config.port}/info`
  const response = await fetch(infoUrl, { signal: AbortSignal.timeout(5000) })

  if (!response.ok) {
    throw new Error(`Notary server returned ${response.status}`)
  }

  const info = await response.json() as { publicKey?: string; version?: string }
  this.dockerPublicKey = info.publicKey ?? null

  this.running = true
  log.info("[TLSNotary] Docker container is running and accessible")

  if (debug) {
    log.info(`[TLSNotary] Notary info: ${JSON.stringify(info)}`)
  }




 ... (clipped 16 lines)

Learn more about managing compliance generic rules or creating your own custom rules

@tcsenpai
Copy link
Contributor Author

tcsenpai commented Jan 4, 2026

@coderabbitai full review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 4, 2026

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 4, 2026

Caution

Review failed

The pull request is closed.

Walkthrough

Adds a multi-part TLSNotary integration: dual-mode service (FFI & Docker), FFI bindings, proxy manager and port allocator, token lifecycle and GCR wiring, NodeCall and HTTP APIs, wstcp proxy orchestration, CLI/docker helpers, Ed25519 → node-forge migration, and payload-size hardening.

Changes

Cohort / File(s) Summary
TLSNotary Core Service
src/features/tlsnotary/TLSNotaryService.ts, src/features/tlsnotary/ffi.ts, src/features/tlsnotary/index.ts, src/features/tlsnotary/routes.ts
New dual-mode TLSNotary orchestration (FFI & Docker), lifecycle/health APIs, signing-key handling, FFI bindings, verification API, and HTTP routes for health/info/verify.
Proxy & Port Management
src/features/tlsnotary/proxyManager.ts, src/features/tlsnotary/portAllocator.ts, src/features/tlsnotary/PROXY_MANAGER_PLAN.md
New proxy manager to spawn/monitor per-domain wstcp proxies, activity-based cleanup, and a bounded port pool (55000–57000) with allocate/release and availability checks.
Token Lifecycle
src/features/tlsnotary/tokenManager.ts
In-memory attestation token manager: domain-locked tokens, TTL/retries, validate/consume/mark flows, periodic cleanup, and query utilities.
GCR / Blockchain Storage
src/libs/blockchain/gcr/gcr_routines/GCRTLSNotaryRoutines.ts, src/model/entities/GCRv2/GCR_TLSNotary.ts, src/libs/blockchain/gcr/gcr_routines/hashGCR.ts, src/libs/blockchain/gcr/handleGCR.ts
New GCR TLSNotary routines, TypeORM entity for proofs, inclusion in GCR hashing, wiring into GCR apply flow, and native-side effects processing.
NodeCall & Native Ops
src/libs/network/manageNodeCall.ts, src/libs/blockchain/gcr/gcr_routines/handleNativeOperations.ts, src/libs/network/manageNodeCall.ts
Adds NodeCall handlers (requestTLSNproxy, tlsnotary.*) and native ops (tlsn_request, tlsn_store) for token creation, validation, fee burning, and proof storage. (Note: NodeCall cases appear duplicated in the diff.)
FFI & Docker Orchestration / Scripts
tlsnotary/docker-compose.yml, run, install-deps.sh, .beads/.local_version
Docker Compose for notary server, run script lifecycle management (start/stop/healthcheck), install helper script (wstcp via cargo), and version bump file.
API Surface & Server
src/features/tlsnotary/index.ts, src/libs/network/server_rpc.ts, src/index.ts
Conditional startup and route registration for TLSNotary, feature index exposing initialize/shutdown/status/getService accessors, and integration into application startup/shutdown flows.
Networking / Security Hardening
src/libs/omniprotocol/transport/MessageFramer.ts, src/libs/omniprotocol/serialization/control.ts
Add MAX_PAYLOAD_SIZE (16 MB) payload guards and validation; guard metadata JSON parsing with try/catch to avoid crashes.
Ed25519 Migration
src/libs/omniprotocol/auth/verifier.ts, src/libs/omniprotocol/transport/PeerConnection.ts, package.json
Replace @noble/ed25519 usage with node-forge APIs for signing/verification; bump node-forge dependency.
UI / Logging / State
src/utilities/tui/CategorizedLogger.ts, src/utilities/tui/TUIManager.ts, src/utilities/tui/tagCategories.ts, src/utilities/sharedState.ts
Add TLSN log category and tags, TUI tab/status updates to show tlsnotary status, and sharedState slots for TLSNotary state and token store.
Network Routines / Misc
src/libs/network/manageNodeCall.ts, devnet/scripts/generate-identity-helper.ts, .gitignore, .env.example, .serena/memories/tlsnotary_integration_context.md
NodeCall additions, minor dev helper formatting tweak, new env sample keys for TLSNotary, gitignore updates, and integration documentation/memo.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant NodeCall
    participant TokenManager
    participant ProxyManager
    participant PortAllocator
    participant Wstcp as wstcp_Process

    Client->>NodeCall: requestTLSNproxy(targetUrl, auth)
    NodeCall->>TokenManager: extractDomain(targetUrl)
    TokenManager-->>NodeCall: domain
    NodeCall->>TokenManager: createToken(owner, domain)
    TokenManager-->>NodeCall: tokenId (PENDING)

    NodeCall->>ProxyManager: requestProxy(targetUrl)
    ProxyManager->>ProxyManager: extractDomainAndPort(targetUrl)
    ProxyManager->>PortAllocator: allocatePort()
    PortAllocator-->>ProxyManager: port
    ProxyManager->>ProxyManager: ensureWstcp()
    ProxyManager->>Wstcp: spawn wstcp --listen <port> → targetDomain
    Wstcp-->>ProxyManager: proxyId, websocketUrl
    ProxyManager-->>NodeCall: { websocketProxyUrl, proxyId, expiresIn }

    NodeCall->>TokenManager: consumeRetry(tokenId, proxyId)
    TokenManager-->>NodeCall: token (ACTIVE, retriesLeft--)
    NodeCall-->>Client: { tokenId, websocketProxyUrl, expiresIn, proxyId }
Loading
sequenceDiagram
    participant Client
    participant NativeHandler as NodeCall
    participant TokenManager
    participant GCRRoutines
    participant DB

    Client->>NativeHandler: tlsn_request(targetUrl)
    NativeHandler->>TokenManager: extractDomain(targetUrl)
    NativeHandler->>TokenManager: createToken(owner, domain)
    TokenManager-->>NativeHandler: tokenId
    NativeHandler->>NativeHandler: burn fee (1 DEM)

    Client->>NativeHandler: tlsn_store(tokenId, proof)
    NativeHandler->>TokenManager: validateToken(tokenId, owner, targetUrl)
    TokenManager-->>NativeHandler: valid
    NativeHandler->>NativeHandler: compute storage fee
    NativeHandler->>NativeHandler: burn storage fee
    NativeHandler->>GCRRoutines: apply(tlsnotary edit with proof)
    GCRRoutines->>DB: insert GCRTLSNotary entity
    DB-->>GCRRoutines: OK
    GCRRoutines-->>NativeHandler: success
    NativeHandler->>TokenManager: markStored(tokenId)
    TokenManager-->>NativeHandler: token (STORED)
    NativeHandler-->>Client: { success, tokenId, txHash }
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

  • Add TLSNotary Support #554 — Shares the same TLSNotary integration (port allocator, proxy manager, token manager, FFI/Docker service, routes, GCR wiring); likely the primary duplicate or parent PR.
  • Custom Protocol Implementations #501 — Overlaps OmniProtocol transport and Ed25519 changes (node-forge migration and MessageFramer edits).

Suggested reviewers

  • cwilvx

Poem

🐰 I dug a burrow for keys and proof,
I spawned small proxies, kept them aloof,
Tokens hop, attestations sing,
Wstcp bridges — what joy they bring,
A carrot for each verified roof. 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Add TLSNotary Support' directly and clearly summarizes the main change—introducing comprehensive TLSNotary integration including service, proxy management, token management, and related infrastructure.
Docstring Coverage ✅ Passed Docstring coverage is 98.25% which is sufficient. The required threshold is 80.00%.

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5deced6 and 2c1c812.

📒 Files selected for processing (1)
  • src/libs/network/manageNodeCall.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

tcsenpai and others added 4 commits January 5, 2026 15:53
Drop buffered data when an oversized message payload is detected
to release memory holding attacker-controlled bytes and prevent
repeated processing of the invalid frame.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace Math.random()-based UUID generation with cryptographically
secure crypto.randomUUID() to prevent predictable proxy IDs that
could be exploited by attackers.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Dynamically determine WebSocket protocol (ws:// or wss://) based on
the origin URL's protocol. This prevents mixed-content errors for
clients connecting from HTTPS pages.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add proxyServer property to store the debug proxy server instance.
Close any previous instance before creating a new one, and properly
close it during stop() to prevent resource leaks.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions
Copy link

github-actions bot commented Jan 5, 2026

⚠️ MCP Memory Files Detected

This PR modifies .serena/ files. After merge, these changes will be automatically reverted to preserve branch-specific MCP memories.

Files that will be reverted:

  • .serena/memories/tlsnotary_integration_context.md

@github-actions
Copy link

github-actions bot commented Jan 5, 2026

⚠️ 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.

Files that will be reverted:

  • .beads/issues.jsonl

Clear line before rendering TLSNotary status to prevent stale characters
from remaining when status changes or becomes disabled.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Fix all issues with AI Agents 🤖
In @src/features/tlsnotary/proxyManager.ts:
- Around line 107-120: getTLSNotaryState currently assigns the function
reference getSharedState instead of calling it; change the assignment to call
getSharedState() so sharedState is the returned object, then access/initialize
sharedState.tlsnotary as shown; also fix the other occurrence mentioned (line
199) that uses getSharedState without parentheses so it calls getSharedState()
there too; ensure existing uses like initPortPool(), proxies: new Map<string,
ProxyInfo>(), and any logging remain unchanged.
- Around line 126-139: The ensureWstcp function lacks a timeout and a pre-flight
check for cargo; update ensureWstcp to first verify cargo is available by
calling execAsync("which cargo") (similar to the existing "which wstcp" check)
and if missing log a clear message before attempting install, then call
execAsync("cargo install wstcp", { timeout: SPAWN_TIMEOUT_MS || 60000 }) to
guard against hanging installs and surface timeout errors; ensure the install
catch includes the full error info in the thrown Error and add a note to
INSTALL.md that either wstcp or cargo must be present prior to deployment.

In @src/libs/blockchain/gcr/gcr_routines/handleNativeOperations.ts:
- Around line 89-101: The tlsn_store validation uses break which silences
failures and returns an empty edits array; change these to throw explicit errors
so the transaction fails consistently like tlsn_request does: in the tlsn_store
handling within handleNativeOperations.ts replace the break paths after "if
(!token)", "if (token.owner !== tx.content.from)", and "if (token.status !==
TokenStatus.COMPLETED && token.status !== TokenStatus.ACTIVE)" with thrown Error
instances (include informative messages referencing tokenId, token.owner,
tx.content.from, and token.status) so callers receive a clear failure instead of
continuing with an empty edits result.

In @src/libs/blockchain/gcr/gcr_routines/hashGCR.ts:
- Line 84: The proofTimestamp field is converted with String(r.proofTimestamp)
which can call Date.toString() and produce timezone-dependent output; replace
that conversion with a deterministic ISO 8601 string (use
r.proofTimestamp.toISOString() if it's a Date, or coerce/construct a Date and
call .toISOString() otherwise) so it matches the deterministic format used for
createdAt and ensures consistent hashing in the hashGCR routine.
♻️ Duplicate comments (5)
src/utilities/tui/TUIManager.ts (1)

108-109: Backslash key accessibility concern persists.

The CMD tab remains mapped to the backslash key \, which was previously flagged as having accessibility issues on international keyboard layouts (e.g., requires AltGr on European layouts, different positions on UK vs US keyboards). This concern from the previous review still applies.

Based on past review comments, consider using a more universally accessible key or making the keybinding configurable.

src/features/tlsnotary/ffi.ts (1)

213-246: Memory management is correct.

The implementation properly stores strong references before calling ptr():

  • Line 226: this._signingKey = this.config.signingKey
  • Line 237: this._configBuffer = new Uint8Array(configBuffer)

This ensures the garbage collector won't reclaim the buffers while native code holds pointers to them.

src/features/tlsnotary/TLSNotaryService.ts (3)

339-377: process.exit(1) calls prevent graceful shutdown.

Lines 342, 351, and 373 contain process.exit(1) calls that bypass cleanup handlers and prevent graceful shutdown. This matches the concern raised in previous reviews.

Instead of calling process.exit(1), throw errors and let the application entry point decide how to handle fatal conditions. This allows cleanup handlers (e.g., stopping servers, closing connections, releasing resources) to run before process termination.

🔎 Recommended approach

Define a typed fatal error:

class TLSNotaryFatalError extends Error {
  constructor(message: string) {
    super(message)
    this.name = 'TLSNotaryFatalError'
  }
}

Replace process.exit calls with throws:

     } else {
       const error = new Error("Signing key required for FFI mode")
       if (fatal) {
         log.error("[TLSNotary] FATAL: " + error.message)
-        process.exit(1)
+        throw new TLSNotaryFatalError(error.message)
       }
       throw error
     }

Handle at application entry point:

try {
  await service.initialize()
} catch (e) {
  if (e instanceof TLSNotaryFatalError) {
    process.exit(1)
  }
  throw e
}

402-443: Docker connectivity check with process.exit issue.

Line 439 contains another process.exit(1) call with the same graceful shutdown concern.

Line 411 correctly uses AbortSignal.timeout(5000) to prevent the fetch from hanging indefinitely, which is good defensive programming.

Apply the same error-throwing pattern as suggested for initializeFFIMode.


454-496: FFI startup with process.exit issues.

Lines 458 and 492 contain process.exit(1) calls that should be replaced with error throwing for graceful shutdown.

The debug logging (lines 466-467) helpfully documents that TLSNotary only accepts WebSocket connections via HTTP GET, which will help developers troubleshoot connection issues.

🧹 Nitpick comments (2)
src/features/tlsnotary/proxyManager.ts (1)

370-394: Consider adding periodic cleanup in addition to lazy cleanup.

The current implementation only cleans up stale proxies when a new request arrives. If the system is idle for extended periods, stale proxies will remain running and consume resources.

Consider adding a periodic cleanup timer (e.g., every 5 minutes) in addition to the lazy cleanup, especially if the proxy manager will be long-lived:

// In getTLSNotaryState or a separate init function
let cleanupInterval: NodeJS.Timeout | null = null

export function startPeriodicCleanup(intervalMs = 300000) { // 5 minutes
  if (cleanupInterval) return
  cleanupInterval = setInterval(() => {
    cleanupStaleProxies()
  }, intervalMs)
}

export function stopPeriodicCleanup() {
  if (cleanupInterval) {
    clearInterval(cleanupInterval)
    cleanupInterval = null
  }
}
src/features/tlsnotary/TLSNotaryService.ts (1)

503-571: Debug proxy implementation is functional but could be more robust.

The proxy serves its purpose for debugging, but consider these optional improvements:

  1. Lines 539, 544: No error handling if write() fails (e.g., backpressure, closed socket)
  2. Lines 548-556: Error handlers destroy both sockets immediately, which might drop in-flight data
  3. No handling of the 'drain' event for flow control

For a production-quality proxy, consider:

  • Check write() return values and handle backpressure with drain events
  • Use end() instead of destroy() for graceful shutdown when possible
  • Add connection timeout handling

Given this is a debug-only feature (controlled by TLSNOTARY_PROXY), the current implementation is acceptable.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 50c7d5f and 2f0ea12.

📒 Files selected for processing (9)
  • src/features/tlsnotary/TLSNotaryService.ts
  • src/features/tlsnotary/ffi.ts
  • src/features/tlsnotary/portAllocator.ts
  • src/features/tlsnotary/proxyManager.ts
  • src/libs/blockchain/gcr/gcr_routines/handleNativeOperations.ts
  • src/libs/blockchain/gcr/gcr_routines/hashGCR.ts
  • src/libs/omniprotocol/protocol/handlers/control.ts
  • src/libs/omniprotocol/transport/MessageFramer.ts
  • src/utilities/tui/TUIManager.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/libs/omniprotocol/protocol/handlers/control.ts
  • src/features/tlsnotary/portAllocator.ts
🧰 Additional context used
🧬 Code graph analysis (2)
src/libs/blockchain/gcr/gcr_routines/hashGCR.ts (1)
src/libs/crypto/hashing.ts (1)
  • Hashing (15-26)
src/features/tlsnotary/proxyManager.ts (3)
src/features/tlsnotary/portAllocator.ts (5)
  • PortPoolState (28-32)
  • initPortPool (38-44)
  • releasePort (119-128)
  • PORT_CONFIG (17-23)
  • allocatePort (80-112)
src/utilities/sharedState.ts (1)
  • getSharedState (338-340)
src/utilities/tui/CategorizedLogger.ts (1)
  • log (345-376)
🔇 Additional comments (21)
src/libs/blockchain/gcr/gcr_routines/hashGCR.ts (3)

5-5: LGTM: Import added for TLSNotary integration.

The import of GCRTLSNotary is correctly added to support the new TLSNotary proofs hashing functionality.


76-86: Excellent normalization approach for deterministic hashing.

The explicit field mapping with fixed order ensures deterministic JSON.stringify output across all nodes, which is critical for consensus. This approach correctly avoids JavaScript object property ordering issues that could break GCR integrity verification.

Note: Ensure the timestamp conversion issue (Line 84) is addressed for full determinism.


108-113: LGTM: TLSNotary hash correctly integrated into GCR.

The TLSNotary table hash is properly included in the combined GCR integrity hash, following the same pattern as existing tables. The integration maintains the deterministic ordering required for consensus.

src/utilities/tui/TUIManager.ts (3)

27-32: LGTM! Well-structured TLSNotary status extension.

The optional tlsnotary field is properly typed and provides the necessary information for status display in the TUI header. The use of optional property syntax ensures backward compatibility.


523-529: LGTM! Input handling correctly maps to tab indices.

The key bindings for TLSN (tab index 11) and CMD (tab index 12) are consistent with the TABS array definition. The logic is correct.


1083-1094: TLSN category is properly integrated into the logging system.

Verification confirms that the TLSN category is fully defined in the LogCategory type, included in the ALL_CATEGORIES array, and properly mapped in TAG_TO_CATEGORY with multiple tag variants (TLSNOTARY, TLSNotary, TLSN, NOTARY, ATTESTATION). The TLSNotary status rendering logic at lines 1083-1094 is correct and uses safe optional chaining.

src/libs/omniprotocol/transport/MessageFramer.ts (3)

36-37: LGTM! Solid DoS mitigation.

The 16 MB payload limit is a reasonable upper bound that prevents memory exhaustion attacks while accommodating legitimate large messages.


202-209: Excellent security hardening.

The validation placement is optimal—it rejects oversized payloads before buffering or extraction. Clearing the buffer on detection is the correct choice: once a malicious header is seen, all buffered data is suspect and the connection should be terminated.


284-287: Good defensive check on the egress path.

Validating payload size before encoding catches bugs early and maintains symmetry with the ingress validation, ensuring both directions respect the same size limits.

src/features/tlsnotary/proxyManager.ts (2)

288-358: Startup monitoring logic is well-structured.

The Promise-based startup monitoring with timeout, panic detection, and success signal detection is thorough. The cleanup function properly removes listeners to prevent leaks.


416-514: Request proxy flow is well-designed.

The implementation follows a logical flow: validate inputs → cleanup stale proxies → reuse existing → spawn new with retries → proper error handling. The retry logic with port release on failure is correct.

src/features/tlsnotary/ffi.ts (3)

166-207: GC hazard successfully addressed.

The addition of _signingKey and _configBuffer fields (lines 173-174) properly addresses the previous review concern about garbage collection. These strong references ensure the buffers remain live while the native code holds pointers to them.

The constructor also includes good defensive validation of the signing key length.


294-372: Attestation verification is well-implemented.

Key strengths:

  • Line 303: Empty buffer check prevents bun:ffi errors with zero-length buffers
  • Try/finally block ensures native memory is freed even if parsing fails (line 370)
  • Proper null pointer checks for optional C strings

447-465: Resource cleanup follows correct order.

The destroy method properly sequences cleanup:

  1. Stop server if running (lines 450-454)
  2. Destroy native handle (line 457)
  3. Clear buffer references (lines 461-462)
  4. Reset state flags

This ensures native resources are released before the GC can reclaim the buffers.

src/features/tlsnotary/TLSNotaryService.ts (2)

81-120: Signing key resolution is well-designed.

The priority-based resolution (ENV → file → auto-generate) provides good flexibility for different deployment scenarios. Line 113 correctly sets restrictive file permissions (0o600) for the auto-generated key file, protecting the sensitive cryptographic material.


577-635: Shutdown logic is properly structured.

The lifecycle management correctly handles both modes:

  • Docker mode: Marks service as stopped without controlling the external container (lines 584-589, 622-625)
  • FFI mode: Stops server, closes proxy if active, and destroys FFI instance (lines 593-609, 628-632)

The cleanup order is appropriate: stop server → close proxy → destroy FFI → clear references.

src/libs/blockchain/gcr/gcr_routines/handleNativeOperations.ts (5)

6-11: LGTM - TLSNotary imports and pricing constants are well-defined.

The pricing constants are clearly documented. Consider making these configurable via environment variables in the future if pricing needs to change without code deployment.


26-51: LGTM - send case properly refactored with block scoping.

The block scoping with const declarations addresses the previous review feedback correctly.


52-80: LGTM - tlsn_request case addresses previous review concerns.

The refactoring correctly:

  1. Uses block scoping with const declarations.
  2. Throws on invalid URL, preventing fee burn for invalid requests.
  3. Defers token creation to processNativeSideEffects() to avoid duplicates.

This addresses the atomicity concern from the previous review.


150-155: LGTM - Default case correctly handles unknown operations.

The previous exhaustive check issue has been properly addressed. The cast to INativePayload is appropriate since TypeScript doesn't narrow the type through partial switch coverage.


130-139: The flagged code appears to be incomplete/unused and not part of the active codebase flow.

The HandleNativeOperations class in this file is never imported or called anywhere in the codebase. Native operations are actually processed through the manageNative module and HandleGCR.apply() method in the consensus flow (PoRBFT.tsapplyGCREditsFromMergedMempool). The file shows a "TODO Implement this" comment and appears to be work-in-progress code from a refactoring effort rather than production code.

While the Date.now() concern would be valid if this code were executed, it does not apply to the current active system. Remove or properly integrate this file if it's intended for future use, but the current concern does not represent a live issue.

Likely an incorrect or invalid review comment.

tcsenpai and others added 7 commits January 5, 2026 16:07
Replace silent break statements with throw new Error() for token
validation failures to ensure deterministic transaction rejection
across all nodes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…precision loss

- Add TypeORM transformer to handle bigint<->string conversion
- Convert timestamp to string when saving to entity
- Prevents JavaScript number precision loss for large timestamps

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Derive ws/wss scheme from node's exposedUrl protocol instead of
hardcoding wss://, preventing mixed-content errors when node is
accessed via HTTP.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace hardcoded tab indices with TABS.findIndex() for TLSN and CMD
tabs to make navigation more robust and maintainable.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Wrap proxyServer.close() and proxyServer.listen() in Promises with
error event handlers to ensure proper async execution and prevent
unhandled exceptions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Wrap tlsn_notary_stop_server call in try/finally to ensure serverRunning
is always set to false even if the FFI call throws.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add SPAWN_TIMEOUT_MS timeout to port availability check to prevent
indefinite hangs. Also wrap error handler server.close in try/finally.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions
Copy link

github-actions bot commented Jan 5, 2026

⚠️ MCP Memory Files Detected

This PR modifies .serena/ files. After merge, these changes will be automatically reverted to preserve branch-specific MCP memories.

Files that will be reverted:

  • .serena/memories/tlsnotary_integration_context.md

@github-actions
Copy link

github-actions bot commented Jan 5, 2026

⚠️ 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.

Files that will be reverted:

  • .beads/issues.jsonl

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
src/libs/blockchain/gcr/gcr_routines/GCRTLSNotaryRoutines.ts (4)

46-48: Consider including error details in log messages.

The error handling logs the error object directly. Consider extracting error.message and error.stack for more structured logging.

🔎 Suggested improvement
                } catch (error) {
-                   log.error(`[TLSNotary] Failed to rollback proof: ${error}`)
+                   const errorMessage = error instanceof Error ? error.message : String(error)
+                   log.error(`[TLSNotary] Failed to rollback proof for token ${tlsnEdit.data.tokenId}: ${errorMessage}`, error instanceof Error ? error.stack : undefined)
                    return { success: false, message: "Failed to rollback TLSNotary proof" }
                }

83-85: Consider including error details in log messages.

Similar to the rollback error handling, consider extracting structured error information.

🔎 Suggested improvement
                } catch (error) {
-                   log.error(`[TLSNotary] Failed to store proof: ${error}`)
+                   const errorMessage = error instanceof Error ? error.message : String(error)
+                   log.error(`[TLSNotary] Failed to store proof for token ${tlsnEdit.data.tokenId}: ${errorMessage}`, error instanceof Error ? error.stack : undefined)
                    return { success: false, message: "Failed to store TLSNotary proof" }
                }

112-129: Add pagination to prevent memory issues with large result sets.

Both getProofsByOwner and getProofsByDomain could return unbounded result sets if a single owner or domain accumulates many proofs over time. This could lead to memory exhaustion and poor performance.

Consider adding pagination parameters (e.g., limit and offset, or cursor-based pagination).

🔎 Suggested pagination implementation
    /**
     * Get all proofs for an owner
     * @param owner - The account address
     * @param gcrTLSNotaryRepository - TypeORM repository
+    * @param options - Optional pagination { limit, offset }
     */
    static async getProofsByOwner(
        owner: string,
        gcrTLSNotaryRepository: Repository<GCRTLSNotary>,
+       options?: { limit?: number; offset?: number },
    ): Promise<GCRTLSNotary[]> {
-       return gcrTLSNotaryRepository.findBy({ owner })
+       const query = gcrTLSNotaryRepository
+           .createQueryBuilder("proof")
+           .where("proof.owner = :owner", { owner })
+       
+       if (options?.limit) {
+           query.take(options.limit)
+       }
+       if (options?.offset) {
+           query.skip(options.offset)
+       }
+       
+       return query.getMany()
    }

    /**
     * Get all proofs for a domain
     * @param domain - The domain to look up
     * @param gcrTLSNotaryRepository - TypeORM repository
+    * @param options - Optional pagination { limit, offset }
     */
    static async getProofsByDomain(
        domain: string,
        gcrTLSNotaryRepository: Repository<GCRTLSNotary>,
+       options?: { limit?: number; offset?: number },
    ): Promise<GCRTLSNotary[]> {
-       return gcrTLSNotaryRepository.findBy({ domain })
+       const query = gcrTLSNotaryRepository
+           .createQueryBuilder("proof")
+           .where("proof.domain = :domain", { domain })
+       
+       if (options?.limit) {
+           query.take(options.limit)
+       }
+       if (options?.offset) {
+           query.skip(options.offset)
+       }
+       
+       return query.getMany()
    }

57-87: The PRIMARY KEY constraint on tokenId already prevents duplicate entries.

The GCRTLSNotary entity has tokenId declared as @PrimaryColumn, which enforces uniqueness at the database level. This mitigates the actual risk of duplicate entries being stored.

However, the application-level duplicate check (lines 57-64) is still vulnerable to a time-of-check-to-time-of-use race condition. Two concurrent requests could both pass the check and attempt to save. When the second request reaches the database, it will fail with a constraint violation error, which is caught and returned as a generic "Failed to store TLSNotary proof" message.

Consider either removing the redundant application-level check or using atomic database operations (e.g., upsert) if you want to avoid the race condition at the application level as well.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 2f0ea12 and 5deced6.

📒 Files selected for processing (9)
  • package.json
  • src/features/tlsnotary/TLSNotaryService.ts
  • src/features/tlsnotary/ffi.ts
  • src/features/tlsnotary/portAllocator.ts
  • src/libs/blockchain/gcr/gcr_routines/GCRTLSNotaryRoutines.ts
  • src/libs/blockchain/gcr/gcr_routines/handleNativeOperations.ts
  • src/libs/network/manageNodeCall.ts
  • src/model/entities/GCRv2/GCR_TLSNotary.ts
  • src/utilities/tui/TUIManager.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/utilities/tui/TUIManager.ts
  • src/model/entities/GCRv2/GCR_TLSNotary.ts
🧰 Additional context used
🧬 Code graph analysis (5)
src/libs/blockchain/gcr/gcr_routines/GCRTLSNotaryRoutines.ts (1)
src/libs/blockchain/gcr/handleGCR.ts (1)
  • GCRResult (78-82)
src/libs/network/manageNodeCall.ts (5)
src/features/tlsnotary/tokenManager.ts (5)
  • validateToken (158-205)
  • consumeRetry (214-233)
  • getToken (281-284)
  • getTokenByTxHash (292-300)
  • getTokenStats (327-349)
src/features/tlsnotary/proxyManager.ts (1)
  • requestProxy (416-514)
src/features/tlsnotary/TLSNotaryService.ts (1)
  • getTLSNotaryService (817-822)
src/features/tlsnotary/index.ts (1)
  • getTLSNotaryService (63-63)
src/utilities/sharedState.ts (1)
  • getSharedState (338-340)
src/features/tlsnotary/portAllocator.ts (1)
src/utilities/tui/CategorizedLogger.ts (1)
  • log (345-376)
src/libs/blockchain/gcr/gcr_routines/handleNativeOperations.ts (1)
src/features/tlsnotary/tokenManager.ts (3)
  • extractDomain (98-105)
  • getToken (281-284)
  • markStored (261-273)
src/features/tlsnotary/TLSNotaryService.ts (1)
src/features/tlsnotary/ffi.ts (4)
  • NotaryHealthStatus (51-62)
  • TLSNotaryFFI (166-483)
  • NotaryConfig (21-28)
  • VerificationResult (33-46)
🔇 Additional comments (27)
package.json (2)

93-93: Critical security upgrade: fixes three CVEs in earlier versions.

The bump to 1.3.3 addresses three significant vulnerabilities in versions <1.3.2:

  • CVE-2025-12816: ASN.1 validator bypass (signature/certificate verification)
  • CVE-2025-66030: ASN.1 OID integer truncation bypass
  • CVE-2025-66031: Uncontrolled recursion DoS

Version 1.3.3 has no reported security advisories and is safe to deploy.


62-62: Verify SDK upgrade works with the breaking changes in 2.7.10.

This bump crosses two minor versions with confirmed breaking changes: DemosWebAuth decoupling, updated method signatures for transaction signing and payload preparation, and API surface changes to demos.connect and related helpers. While the specific methods like DemosTransactions.sign and Wallet.transfer don't appear in the visible codebase, the extensive SDK usage across the project means the upgrade must be tested to ensure compatibility.

Confirm that existing tests pass with the new SDK version before merging.

src/features/tlsnotary/portAllocator.ts (4)

1-23: LGTM! Module structure and configuration are well-defined.

The module-level net import correctly addresses the previous review feedback. Constants are clearly defined with appropriate timeouts and limits.


25-44: LGTM! Pool initialization is straightforward.

The interface and initialization function are clean and correctly set up the pool state.


51-85: LGTM! Port availability check is robust with timeout protection.

The implementation correctly addresses previous review feedback:

  • Module-level net import
  • settled flag prevents double-resolution
  • Timeout ensures the promise always resolves within 5 seconds
  • Error and timeout handlers use try/finally to guarantee finish() is called

The close callback at line 80 doesn't explicitly handle errors, but the timeout mechanism provides adequate protection against hangs.


93-164: LGTM! Port allocation, release, and statistics are correctly implemented.

The allocation strategy (recycled-first, then sequential) is sound. The includes check on line 136 is O(n) but acceptable given the small size of the recycled pool in typical usage.

src/libs/network/manageNodeCall.ts (4)

457-534: LGTM! Token-based proxy request is well-validated.

The endpoint correctly:

  • Validates all required parameters (tokenId, owner, targetUrl)
  • Enforces HTTPS for TLS attestation
  • Validates token ownership and domain lock
  • Avoids consuming retries on internal errors
  • Links proxy to token only on success

Dynamic imports prevent circular dependencies.


536-595: LGTM! Service discovery endpoint correctly derives WebSocket scheme.

The endpoint properly:

  • Checks service availability (503 if not running)
  • Derives WebSocket scheme from exposedUrl to avoid mixed-content issues
  • Provides fallback defaults
  • Returns notary and proxy URLs for SDK auto-configuration

597-646: LGTM! Token lookup supports both tokenId and txHash.

The endpoint correctly:

  • Supports flexible lookup by either identifier
  • Validates at least one parameter is provided
  • Returns appropriate token fields
  • Uses correct status codes

648-663: LGTM! Token statistics endpoint is straightforward.

Simple monitoring endpoint with proper error handling.

src/libs/blockchain/gcr/gcr_routines/handleNativeOperations.ts (5)

1-11: LGTM! Imports and pricing constants are well-defined.

TLSNotary pricing is simple (1 DEM = 1 unit) with clear per-KB storage fees.


26-51: LGTM! Send case now uses block scoping.

The case is properly wrapped in a block with const declarations, addressing previous review feedback about variable leakage.


52-80: LGTM! URL validation now throws for deterministic failure.

The case correctly:

  • Uses block scoping with const declarations
  • Throws on invalid URL (addressing previous review feedback)
  • Burns the request fee
  • Documents that token creation is a native side-effect

82-148: LGTM! Token validation now uses throw for consistency.

The case correctly addresses previous review feedback:

  • Block scoping with const declarations
  • Throws on validation failures (token not found, owner mismatch, wrong status)
  • Proper proof size calculation handling both string and Uint8Array
  • Storage fee formula is clear: base + (KB × per-KB fee)

The proof size overflow concern from past review is unlikely with current constants (1 DEM/KB would require unrealistic proof sizes).


150-155: LGTM! Default case now correctly handles unknown operations.

The exhaustive check issue from previous review has been resolved. The safe cast with explanatory comment is appropriate.

src/features/tlsnotary/ffi.ts (5)

1-89: LGTM! FFI interfaces and library path resolution are well-structured.

The platform-specific library path resolution correctly handles macOS, Windows, and Linux with appropriate file extensions.


94-175: LGTM! FFI symbols are properly defined.

The class fields _signingKey and _configBuffer (lines 173-174) correctly address the previous review concern about GC hazards by maintaining strong references to buffers passed to native code.


181-246: LGTM! Constructor correctly prevents GC hazards.

The implementation properly addresses the previous review concern:

  • _signingKey is assigned at line 226 before ptr() call (line 227)
  • _configBuffer is assigned at line 237 before ptr() call (line 238)

This ensures buffers remain live while native code uses the pointers.


253-372: LGTM! Server lifecycle and verification are properly managed.

Key correctness aspects:

  • State checks prevent double-start/stop
  • Empty attestation check (line 303) prevents FFI issues
  • Memory cleanup in finally block (line 370) ensures no leaks

380-483: LGTM! Resource cleanup is complete.

The destroy method properly:

  • Stops server in try-finally (lines 450-456)
  • Destroys native handle
  • Clears buffer references (lines 464-465) after native cleanup

This completes the GC protection lifecycle.

src/features/tlsnotary/TLSNotaryService.ts (7)

1-146: LGTM! Service configuration and key resolution are well-designed.

The signing key resolution priority (ENV → file → auto-generate) is clear and well-documented. File permissions (0o600, line 113) are appropriately restrictive.


169-197: LGTM! Environment configuration correctly handles mode-specific requirements.

Docker mode is the default (line 177), and signing key validation only applies to FFI mode (lines 181-187), which is appropriate.


229-296: LGTM! Service initialization correctly delegates to mode-specific handlers.

The dual-mode architecture is clean, with appropriate delegation based on the operational mode.


323-377: Verify fatal mode behavior aligns with operational requirements.

The process.exit(1) calls (lines 342, 351, 372) when TLSNOTARY_FATAL=true prevent graceful shutdown, as noted in previous review feedback. While this may be intentional for debugging, consider whether:

  1. Fatal mode is documented as a debug-only feature
  2. Production deployments should never enable TLSNOTARY_FATAL=true
  3. Throwing typed errors (allowing the caller to decide on exit) would provide better separation of concerns

When fatal=false, errors are thrown normally, which is appropriate.

Alternative approach if graceful shutdown is required
class TLSNotaryFatalError extends Error {
  constructor(message: string) {
    super(message)
    this.name = 'TLSNotaryFatalError'
  }
}

// In FFI init:
if (!signingKeyBytes) {
  const error = new TLSNotaryFatalError("Signing key required for FFI mode")
  log.error("[TLSNotary] FATAL: " + error.message)
  if (fatal) {
    throw error  // Let caller handle process.exit
  }
  throw error
}

// At application entry point:
try {
  await service.initialize()
} catch (e) {
  if (e instanceof TLSNotaryFatalError && isTLSNotaryFatal()) {
    process.exit(1)
  }
  // ... handle other errors
}

383-578: LGTM! Dual-mode startup is well-implemented.

Docker mode correctly verifies container accessibility via HTTP /info endpoint. FFI mode includes an optional debug proxy (lines 503-578) that intercepts and logs data before forwarding—useful for troubleshooting but should be disabled in production.

The process.exit(1) calls follow the same fatal-mode pattern discussed in the previous segment.


584-725: LGTM! Lifecycle management and mode-specific accessors are correct.

The service properly handles:

  • Docker mode leaving container lifecycle to external orchestration
  • FFI mode managing native resources
  • Verification unsupported in Docker mode (client-side verification used instead, line 659)
  • Public key retrieval from cached Docker value or FFI

730-846: LGTM! Status reporting and singleton management are straightforward.

The singleton pattern is correctly implemented with lazy initialization and proper cleanup.

@github-actions
Copy link

github-actions bot commented Jan 6, 2026

⚠️ 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.

Files that will be reverted:

  • .beads/issues.jsonl

@github-actions
Copy link

github-actions bot commented Jan 6, 2026

⚠️ MCP Memory Files Detected

This PR modifies .serena/ files. After merge, these changes will be automatically reverted to preserve branch-specific MCP memories.

Files that will be reverted:

  • .serena/memories/tlsnotary_integration_context.md

@tcsenpai tcsenpai merged commit a504693 into custom_protocol Jan 6, 2026
6 of 7 checks passed
@sonarqubecloud
Copy link

sonarqubecloud bot commented Jan 6, 2026

- INVALID_URL returns 400 (Bad Request)
- PORT_EXHAUSTED returns 503 (Service Unavailable)
- WSTCP_NOT_AVAILABLE/PROXY_SPAWN_FAILED return 500 (Internal Error)

This improves API ergonomics by distinguishing client errors from server errors.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant