- Added `NativeClient` for non-WASM environments with automatic reconnection and message handling. - Introduced `WasmClient` for WASM environments, supporting WebSocket communication and reconnection logic. - Created protocol definitions for `SignRequest` and `SignResponse` with serialization and deserialization. - Developed integration tests for the client functionality and sign request handling. - Implemented WASM-specific tests to ensure compatibility and functionality in browser environments.
215 lines
6.3 KiB
Markdown
215 lines
6.3 KiB
Markdown
# SigSocket Client Implementation
|
|
|
|
## Overview
|
|
|
|
This document describes the implementation of the `sigsocket_client` crate, a WebSocket client library designed for connecting to sigsocket servers with **WASM-first support**.
|
|
|
|
## Architecture
|
|
|
|
### Core Design Principles
|
|
|
|
1. **WASM-First**: Designed primarily for browser environments with native support as a secondary target
|
|
2. **No Signing Logic**: The client delegates all signing operations to the application
|
|
3. **User Approval Flow**: Applications are notified about incoming requests and handle user approval
|
|
4. **Protocol Compatibility**: Fully compatible with the sigsocket server protocol
|
|
5. **Async/Await**: Modern async Rust API throughout
|
|
|
|
### Module Structure
|
|
|
|
```
|
|
sigsocket_client/
|
|
├── src/
|
|
│ ├── lib.rs # Main library entry point
|
|
│ ├── error.rs # Error types (native + WASM versions)
|
|
│ ├── protocol.rs # Protocol message definitions
|
|
│ ├── client.rs # Main client interface
|
|
│ ├── native.rs # Native (tokio) implementation
|
|
│ └── wasm.rs # WASM (web-sys) implementation
|
|
├── examples/
|
|
│ ├── basic_usage.rs # Native usage example
|
|
│ └── wasm_usage.rs # WASM usage example
|
|
├── tests/
|
|
│ └── integration_test.rs
|
|
└── README.md
|
|
```
|
|
|
|
## Protocol Implementation
|
|
|
|
The sigsocket protocol is simple and consists of three message types:
|
|
|
|
### 1. Introduction Message
|
|
When connecting, the client sends its public key as a hex-encoded string:
|
|
```
|
|
02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9
|
|
```
|
|
|
|
### 2. Sign Request (Server → Client)
|
|
```json
|
|
{
|
|
"id": "req_123",
|
|
"message": "dGVzdCBtZXNzYWdl" // base64-encoded message
|
|
}
|
|
```
|
|
|
|
### 3. Sign Response (Client → Server)
|
|
```json
|
|
{
|
|
"id": "req_123",
|
|
"message": "dGVzdCBtZXNzYWdl", // original message
|
|
"signature": "c2lnbmF0dXJl" // base64-encoded signature
|
|
}
|
|
```
|
|
|
|
## Key Features Implemented
|
|
|
|
### ✅ Dual Platform Support
|
|
- **Native**: Uses `tokio` and `tokio-tungstenite` for async WebSocket communication
|
|
- **WASM**: Uses `web-sys` and `wasm-bindgen` for browser WebSocket API
|
|
|
|
### ✅ Type-Safe Protocol
|
|
- `SignRequest` and `SignResponse` structs with serde serialization
|
|
- Helper methods for base64 encoding/decoding
|
|
- Comprehensive error handling
|
|
|
|
### ✅ Flexible Sign Handler Interface
|
|
```rust
|
|
trait SignRequestHandler {
|
|
fn handle_sign_request(&self, request: &SignRequest) -> Result<Vec<u8>>;
|
|
}
|
|
```
|
|
|
|
### ✅ Connection Management
|
|
- Automatic connection state tracking
|
|
- Clean disconnect handling
|
|
- Connection status queries
|
|
|
|
### ✅ Error Handling
|
|
- Comprehensive error types for different failure modes
|
|
- Platform-specific error conversions
|
|
- WASM-compatible error handling (no `std::error::Error` dependency)
|
|
|
|
## Platform-Specific Implementations
|
|
|
|
### Native Implementation (`native.rs`)
|
|
- Uses `tokio-tungstenite` for WebSocket communication
|
|
- Spawns separate tasks for reading and writing
|
|
- Thread-safe with `Arc<RwLock<T>>` for shared state
|
|
- Supports `Send + Sync` trait bounds
|
|
|
|
### WASM Implementation (`wasm.rs`)
|
|
- Uses `web-sys::WebSocket` for browser WebSocket API
|
|
- Event-driven with JavaScript closures
|
|
- Single-threaded (no `Send + Sync` requirements)
|
|
- Browser console logging for debugging
|
|
|
|
## Usage Patterns
|
|
|
|
### Native Usage
|
|
```rust
|
|
#[tokio::main]
|
|
async fn main() -> Result<()> {
|
|
let public_key = hex::decode("02f9308a...")?;
|
|
let mut client = SigSocketClient::new("ws://localhost:8080/ws", public_key)?;
|
|
|
|
client.set_sign_handler(MySignHandler);
|
|
client.connect().await?;
|
|
|
|
// Client handles requests automatically
|
|
Ok(())
|
|
}
|
|
```
|
|
|
|
### WASM Usage
|
|
```rust
|
|
#[wasm_bindgen]
|
|
pub async fn connect_to_sigsocket() -> Result<(), JsValue> {
|
|
let public_key = get_user_public_key()?;
|
|
let mut client = SigSocketClient::new("ws://localhost:8080/ws", public_key)?;
|
|
|
|
client.set_sign_handler(WasmSignHandler);
|
|
client.connect().await?;
|
|
|
|
Ok(())
|
|
}
|
|
```
|
|
|
|
## Testing
|
|
|
|
### Unit Tests
|
|
- Protocol message serialization/deserialization
|
|
- Error handling and conversion
|
|
- Client creation and configuration
|
|
|
|
### Integration Tests
|
|
- End-to-end usage patterns
|
|
- Sign request/response cycles
|
|
- Error scenarios
|
|
|
|
### Documentation Tests
|
|
- Example code in documentation is verified to compile
|
|
|
|
## Dependencies
|
|
|
|
### Core Dependencies (Both Platforms)
|
|
- `serde` + `serde_json` - JSON serialization
|
|
- `hex` - Hex encoding/decoding
|
|
- `base64` - Base64 encoding/decoding
|
|
- `url` - URL parsing and validation
|
|
|
|
### Native-Only Dependencies
|
|
- `tokio` - Async runtime
|
|
- `tokio-tungstenite` - WebSocket client
|
|
- `futures-util` - Stream utilities
|
|
- `thiserror` - Error derive macros
|
|
|
|
### WASM-Only Dependencies
|
|
- `wasm-bindgen` - Rust/JavaScript interop
|
|
- `web-sys` - Browser API bindings
|
|
- `js-sys` - JavaScript type bindings
|
|
- `wasm-bindgen-futures` - Async support
|
|
|
|
## Build Targets
|
|
|
|
### Native Build
|
|
```bash
|
|
cargo build --features native
|
|
cargo test --features native
|
|
cargo run --example basic_usage --features native
|
|
```
|
|
|
|
### WASM Build
|
|
```bash
|
|
cargo check --target wasm32-unknown-unknown --features wasm
|
|
wasm-pack build --target web --features wasm
|
|
```
|
|
|
|
## Future Enhancements
|
|
|
|
### Potential Improvements
|
|
1. **Reconnection Logic**: Automatic reconnection with exponential backoff
|
|
2. **Request Queuing**: Queue multiple concurrent sign requests
|
|
3. **Timeout Handling**: Configurable timeouts for requests
|
|
4. **Metrics**: Connection and request metrics
|
|
5. **Logging**: Structured logging with configurable levels
|
|
|
|
### WASM Enhancements
|
|
1. **Better Callback System**: More ergonomic callback handling in WASM
|
|
2. **Browser Wallet Integration**: Direct integration with MetaMask, etc.
|
|
3. **Service Worker Support**: Background request handling
|
|
|
|
## Security Considerations
|
|
|
|
1. **No Private Key Storage**: The client never handles private keys
|
|
2. **User Approval Required**: All signing requires explicit user approval
|
|
3. **Message Validation**: All incoming messages are validated
|
|
4. **Secure Transport**: Requires WebSocket Secure (WSS) in production
|
|
|
|
## Compatibility
|
|
|
|
- **Rust Version**: 1.70+
|
|
- **WASM Target**: `wasm32-unknown-unknown`
|
|
- **Browser Support**: Modern browsers with WebSocket support
|
|
- **Server Compatibility**: Compatible with sigsocket server protocol
|
|
|
|
This implementation provides a solid foundation for applications that need to connect to sigsocket servers while maintaining security and user control over signing operations.
|