6.9 KiB
server
Architecture
This document provides a detailed look into the internal architecture of the server
crate, focusing on its Actix
-based design, the structure of the authentication service, and the request lifecycle.
1. Core Design: The Actix
Actor System
The server
is built around the Actix
actor framework, which allows for highly concurrent and stateful handling of network requests. The key components of this design are:
HttpServer
: The mainActix
server instance that listens for incoming TCP connections.App
: The application factory that defines the routes for the server.CircleWs
Actor: A dedicated actor that is spawned for each individual WebSocket connection. This is the cornerstone of the server's design, as it allows each client session to be managed in an isolated, stateful manner.
When a client connects to the /{circle_pk}
endpoint, the HttpServer
upgrades the connection to a WebSocket and spawns a new CircleWs
actor to handle it. The circle public key is extracted from the URL path to identify which circle the client wants to connect to. All further communication with that client, including the entire authentication flow, is then processed by this specific actor instance.
2. Module Structure
The server
crate is organized into the following key modules:
lib.rs
: The main library file that contains thespawn_circle_server
function, which sets up and runs theActix
server. It also defines theCircleWs
actor and its message handling logic for all JSON-RPC methods.auth/
: This module encapsulates all the logic related to thesecp256k1
authentication system.signature_verifier.rs
: A self-contained utility module that provides theverify_signature
function. This function performs the core cryptographic verification of the client's signed nonce.types.rs
: Defines the data structures used within the authentication service.
webhook/
: This module provides HTTP webhook handling capabilities for external services.mod.rs
: Main webhook module with route configuration and exports.handlers/
: Contains individual webhook handlers for different providers (Stripe, iDenfy).verifiers.rs
: Signature verification utilities for webhook authenticity.types.rs
: Local webhook types (configuration, errors, verification results).
3. Request Lifecycle and Authentication Flow
The diagram below illustrates the flow of a typical client interaction. The entire process, from fetching a nonce to executing a protected command, occurs over the WebSocket connection and is handled by the CircleWs
actor.
sequenceDiagram
participant Client
participant ActixHttpServer as HttpServer
participant CircleWsActor as CircleWs Actor
participant SignatureVerifier as auth::signature_verifier
Client->>+ActixHttpServer: Establishes WebSocket connection
ActixHttpServer->>ActixHttpServer: Spawns a new CircleWsActor
ActixHttpServer-->>-Client: WebSocket connection established
Note over CircleWsActor: Session created, authenticated = false
Client->>+CircleWsActor: Sends "fetch_nonce" JSON-RPC message
CircleWsActor->>CircleWsActor: Generate and store nonce for pubkey
CircleWsActor-->>-Client: Returns nonce in JSON-RPC response
Client->>Client: Signs nonce with private key
Client->>+CircleWsActor: Sends "authenticate" JSON-RPC message
CircleWsActor->>+SignatureVerifier: verify_signature(pubkey, nonce, signature)
SignatureVerifier-->>-CircleWsActor: Returns verification result
alt Signature is Valid
CircleWsActor->>CircleWsActor: Set session state: authenticated = true
CircleWsActor-->>-Client: Returns success response
else Signature is Invalid
CircleWsActor-->>-Client: Returns error response
end
Note over CircleWsActor: Client is now authenticated
Client->>+CircleWsActor: Sends "play" JSON-RPC message
CircleWsActor->>CircleWsActor: Check if authenticated
alt Is Authenticated
CircleWsActor->>CircleWsActor: Get public key from authenticated connections map
CircleWsActor->>CircleWsActor: Execute Rhai script with public key
CircleWsActor-->>-Client: Returns script result
else Is Not Authenticated
CircleWsActor-->>-Client: Returns "Authentication Required" error
end
This architecture ensures a clear separation of concerns and a unified communication protocol:
- The
HttpServer
handles connection management. - The
CircleWs
actor manages the entire session lifecycle, including state and all API logic. - The
auth
module provides a self-contained, reusable signature verification utility.
4. Webhook Integration Architecture
In addition to WebSocket connections, the server supports HTTP webhook endpoints for external services. This integration runs alongside the WebSocket functionality without interference.
Webhook Request Flow
sequenceDiagram
participant WS as Webhook Service
participant HS as HttpServer
participant WH as Webhook Handler
participant WV as Webhook Verifier
participant RC as RhaiDispatcher
participant Redis as Redis
WS->>+HS: POST /webhooks/{provider}/{circle_pk}
HS->>+WH: Route to appropriate handler
WH->>WH: Extract circle_pk and signature
WH->>+WV: Verify webhook signature
WV->>WV: HMAC verification with provider secret
WV-->>-WH: Verification result + caller_id
alt Signature Valid
WH->>WH: Parse webhook payload (heromodels types)
WH->>+RC: Create RhaiDispatcher with caller_id
RC->>+Redis: Execute webhook script
Redis-->>-RC: Script result
RC-->>-WH: Execution result
WH-->>-HS: HTTP 200 OK
else Signature Invalid
WH-->>-HS: HTTP 401 Unauthorized
end
HS-->>-WS: HTTP Response
Key Webhook Components
- Modular Handlers: Separate handlers for each webhook provider (Stripe, iDenfy)
- Signature Verification: HMAC-based verification using provider-specific secrets
- Type Safety: Webhook payload types defined in
heromodels
library for reusability - Script Integration: Uses the same Redis-based Rhai execution system as WebSocket connections
- Isolated Processing: Webhook processing doesn't affect WebSocket connections
Webhook vs WebSocket Comparison
Aspect | WebSocket | Webhook |
---|---|---|
Connection Type | Persistent, bidirectional | HTTP request/response |
Authentication | secp256k1 signature-based | HMAC signature verification |
State Management | Stateful sessions via CircleWs actor | Stateless HTTP requests |
Script Execution | Direct via authenticated session | Via RhaiDispatcher with provider caller_id |
Use Case | Interactive client applications | External service notifications |
Data Types | JSON-RPC messages | Provider-specific webhook payloads (heromodels) |