.. | ||
examples | ||
src | ||
tests | ||
Cargo.toml | ||
IMPLEMENTATION.md | ||
README.md |
SigSocket Client
A WebSocket client library for connecting to sigsocket servers with WASM-first support.
Features
- 🌐 WASM-first design: Optimized for browser environments
- 🖥️ Native support: Works in native Rust applications
- 🔐 No signing logic: Delegates signing to the application
- 👤 User approval flow: Notifies applications about incoming requests
- 🔌 sigsocket compatible: Fully compatible with sigsocket server protocol
- 🚀 Async/await: Modern async Rust API
- 🔄 Automatic reconnection: Both platforms support reconnection with exponential backoff
- ⏱️ Connection timeouts: Proper timeout handling and connection management
- 🛡️ Production ready: Comprehensive error handling and reliability features
Quick Start
Native Usage
use sigsocket_client::{SigSocketClient, SignRequestHandler, SignRequest, Result};
struct MySignHandler;
impl SignRequestHandler for MySignHandler {
fn handle_sign_request(&self, request: &SignRequest) -> Result<Vec<u8>> {
// 1. Present request to user
println!("Sign request: {}", request.message);
// 2. Get user approval
// ... your UI logic here ...
// 3. Sign the message (using your signing logic)
let signature = your_signing_function(&request.message_bytes()?)?;
Ok(signature)
}
}
#[tokio::main]
async fn main() -> Result<()> {
// Your public key bytes
let public_key = hex::decode("02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388")?;
// Create and configure client
let mut client = SigSocketClient::new("ws://localhost:8080/ws", public_key)?;
client.set_sign_handler(MySignHandler);
// Connect and handle requests
client.connect().await?;
// Client will automatically handle incoming signature requests
// Keep the connection alive...
Ok(())
}
WASM Usage
use sigsocket_client::{SigSocketClient, SignRequestHandler, SignRequest, Result};
use wasm_bindgen::prelude::*;
struct WasmSignHandler;
impl SignRequestHandler for WasmSignHandler {
fn handle_sign_request(&self, request: &SignRequest) -> Result<Vec<u8>> {
// Show request to user in browser
web_sys::window()
.unwrap()
.alert_with_message(&format!("Sign request: {}", request.id))
.unwrap();
// Your signing logic here...
let signature = sign_with_browser_wallet(&request.message_bytes()?)?;
Ok(signature)
}
}
#[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)
.map_err(|e| JsValue::from_str(&e.to_string()))?;
client.set_sign_handler(WasmSignHandler);
client.connect().await
.map_err(|e| JsValue::from_str(&e.to_string()))?;
Ok(())
}
Protocol
The sigsocket client implements a simple WebSocket protocol:
1. Introduction
Upon connection, the client sends its public key as a hex-encoded string:
02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388
2. Sign Requests
The server sends signature requests as JSON:
{
"id": "req_123",
"message": "dGVzdCBtZXNzYWdl" // base64-encoded message
}
3. Sign Responses
The client responds with signatures as JSON:
{
"id": "req_123",
"message": "dGVzdCBtZXNzYWdl", // original message
"signature": "c2lnbmF0dXJl" // base64-encoded signature
}
API Reference
SigSocketClient
Main client for connecting to sigsocket servers.
Methods
new(url, public_key)
- Create a new clientset_sign_handler(handler)
- Set the signature request handlerconnect()
- Connect to the server with automatic reconnectiondisconnect()
- Disconnect from the serversend_sign_response(response)
- Manually send a signature responsestate()
- Get current connection stateis_connected()
- Check if connected
Reconnection Configuration (WASM only)
set_auto_reconnect(enabled)
- Enable/disable automatic reconnectionset_reconnect_config(max_attempts, initial_delay_ms)
- Configure reconnection parameters
Default settings:
- Max attempts: 5
- Initial delay: 1000ms (with exponential backoff: 1s, 2s, 4s, 8s, 16s)
- Auto-reconnect: enabled
SignRequestHandler
Trait
Implement this trait to handle incoming signature requests.
trait SignRequestHandler {
fn handle_sign_request(&self, request: &SignRequest) -> Result<Vec<u8>>;
}
SignRequest
Represents a signature request from the server.
Fields
id: String
- Unique request identifiermessage: String
- Base64-encoded message to sign
Methods
message_bytes()
- Decode message to bytesmessage_hex()
- Get message as hex string
SignResponse
Represents a signature response to send to the server.
Methods
new(id, message, signature)
- Create a new responsefrom_request_and_signature(request, signature)
- Create from request and signature bytes
Examples
Run the basic example:
cargo run --example basic_usage
Building
Native Build
cargo build
cargo test
cargo run --example basic_usage
WASM Build
wasm-pack build --target web
wasm-pack test --headless --firefox # Run WASM tests
Requirements
Native
- Rust 1.70+
- tokio runtime
WASM
- wasm-pack
- Modern browser with WebSocket support
License
MIT OR Apache-2.0