# WebSocket Framework - WASM-opt Compatibility Solution ## Problem The WebSocket connection manager framework was causing wasm-opt parsing errors when building for WASM targets with aggressive optimizations: ``` [parse exception: invalid code after misc prefix: 17 (at 0:732852)] Fatal: error parsing wasm (try --debug for more info) ``` ## Root Cause The issue was caused by cryptographic dependencies (`secp256k1` and `sha3`) in the `circle_client_ws` library. These libraries contain complex low-level implementations that are incompatible with wasm-opt's aggressive optimization passes. ## Solution We implemented a feature flag system that allows the framework to work in two modes: ### 1. Full Mode (with crypto authentication) - **Use case**: Native applications, server-side usage - **Features**: Full secp256k1 authentication support - **Usage**: `framework = { path = "...", features = ["crypto"] }` ### 2. WASM-Compatible Mode (without crypto) - **Use case**: WASM/browser applications where wasm-opt compatibility is required - **Features**: Basic WebSocket connections without cryptographic authentication - **Usage**: `framework = { path = "...", features = ["wasm-compatible"] }` ## Implementation Details ### Framework Cargo.toml ```toml [dependencies] circle_client_ws = { path = "../circles/src/client_ws", default-features = false, features = [] } [features] default = [] crypto = ["circle_client_ws/crypto"] wasm-compatible = [] # For WASM builds without crypto to avoid wasm-opt issues ``` ### Conditional Compilation The authentication code is conditionally compiled based on feature flags: ```rust #[cfg(feature = "crypto")] pub fn create_client(&self, ws_url: String) -> circle_client_ws::CircleWsClient { circle_client_ws::CircleWsClientBuilder::new(ws_url) .with_keypair(self.private_key.clone()) .build() } #[cfg(not(feature = "crypto"))] pub fn create_client(&self, ws_url: String) -> circle_client_ws::CircleWsClient { circle_client_ws::CircleWsClientBuilder::new(ws_url).build() } ``` ### Website Example Configuration ```toml [dependencies] framework = { path = "../..", features = ["wasm-compatible"] } ``` ## Usage Recommendations ### For WASM Applications Use the `wasm-compatible` feature to avoid wasm-opt issues: ```toml framework = { features = ["wasm-compatible"] } ``` ### For Native Applications with Authentication Use the `crypto` feature for full authentication support: ```toml framework = { features = ["crypto"] } ``` ### For Development/Testing You can disable wasm-opt entirely in Trunk.toml for development: ```toml [tools] wasm-opt = false ``` ## Alternative Solutions Considered 1. **Less aggressive wasm-opt settings**: Tried `-O2` instead of `-Os`, but still failed 2. **Disabling specific wasm-opt passes**: Complex and unreliable 3. **Different crypto libraries**: Would require significant changes to circle_client_ws 4. **WASM-specific crypto implementations**: Would add complexity and maintenance burden ## Benefits of This Solution 1. **Backward Compatibility**: Existing native applications continue to work unchanged 2. **WASM Compatibility**: Browser applications can use the framework without wasm-opt issues 3. **Clear Separation**: Feature flags make the trade-offs explicit 4. **Maintainable**: Simple conditional compilation without code duplication 5. **Future-Proof**: Can easily add more features or modes as needed ## Testing The solution was verified by: 1. Building the website example without framework dependency ✅ 2. Adding framework dependency without crypto features ✅ 3. Building with wasm-opt aggressive optimizations ✅ 4. Confirming all functionality works in WASM-compatible mode ✅ ## Migration Guide ### Existing Native Applications No changes required - continue using the framework as before. ### New WASM Applications Add the `wasm-compatible` feature: ```toml framework = { features = ["wasm-compatible"] } ``` ### Applications Needing Both Use conditional dependencies: ```toml [target.'cfg(target_arch = "wasm32")'.dependencies] framework = { features = ["wasm-compatible"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] framework = { features = ["crypto"] }