# Tauri + WASM Setup Guide ## ๐Ÿ› Problem **Symptom:** - โœ… WASM works in browser (`npm run dev`) - โŒ WASM fails in Tauri (`npm run tauri:dev`) - Error: `Cannot assign to read only property 'toString'` **Root Cause:** Tauri webview requires special configuration to load WASM files correctly. --- ## โœ… Solution: Vite Plugins for WASM ### 1. Install Required Plugins ```bash pnpm add -D vite-plugin-wasm vite-plugin-top-level-await ``` **Why these plugins?** - `vite-plugin-wasm`: Handles WASM file loading and initialization - `vite-plugin-top-level-await`: Enables top-level await (required by WASM) ### 2. Update `vite.config.ts` ```typescript import wasm from 'vite-plugin-wasm' import topLevelAwait from 'vite-plugin-top-level-await' export default defineConfig({ plugins: [ vue(), tailwindcss(), wasm(), // โœ… Add WASM support topLevelAwait(), // โœ… Add top-level await support // ... other plugins ], // Rest of config... }) ``` ### 3. Tauri CSP Configuration **File:** `src-tauri/tauri.conf.json` Ensure CSP includes: ```json { "security": { "csp": { "script-src": "'self' 'unsafe-inline' 'unsafe-eval' 'wasm-unsafe-eval'" } } } ``` **Key directive:** `'wasm-unsafe-eval'` is **REQUIRED** for WASM in Tauri 2.x --- ## ๐ŸŽฏ How It Works ### Before (Without Plugins) ``` Tauri loads index.html โ†“ Vite bundles JS (WASM as regular asset) โ†“ Browser tries to load WASM โ†“ ๐Ÿ’ฅ WASM initialization fails โ†“ Error: Cannot assign to read only property ``` **Why it fails:** - Vite doesn't know how to bundle WASM for Tauri - WASM file is treated as regular asset - Tauri webview can't initialize WASM correctly ### After (With Plugins) ``` Tauri loads index.html โ†“ vite-plugin-wasm handles WASM bundling โ†“ WASM file served with correct headers โ†“ vite-plugin-top-level-await enables async init โ†“ โœ… WASM loads successfully ``` **Why it works:** - `vite-plugin-wasm` handles WASM as special asset type - Correct MIME type (`application/wasm`) - Proper initialization order - Compatible with Tauri's security model --- ## ๐Ÿ“Š Comparison | Aspect | Browser (dev) | Tauri (without plugins) | Tauri (with plugins) | |--------|---------------|-------------------------|----------------------| | WASM Loading | โœ… Works | โŒ Fails | โœ… Works | | MIME Type | Auto | โŒ Wrong | โœ… Correct | | Initialization | โœ… Success | โŒ Conflict | โœ… Success | | CSP Compatibility | N/A | โŒ Issues | โœ… Compatible | --- ## ๐Ÿ” Debugging ### Check if WASM is Loading **In Browser DevTools (F12 in Tauri window):** 1. **Network Tab:** ``` Look for: neptune_wasm_bg.wasm Status: 200 OK Type: application/wasm ``` 2. **Console Tab:** ``` Should see: โœ… WASM initialized successfully Should NOT see: โŒ WASM init error ``` 3. **Sources Tab:** ``` Check if WASM file is listed under "webpack://" or "(no domain)" ``` ### Common Issues #### Issue 1: WASM file not found (404) **Cause:** WASM not bundled correctly **Fix:** Ensure `vite-plugin-wasm` is installed and configured #### Issue 2: CSP violation **Cause:** Missing `'wasm-unsafe-eval'` in CSP **Fix:** Add to `script-src` in `tauri.conf.json` #### Issue 3: Module initialization error **Cause:** Top-level await not supported **Fix:** Install `vite-plugin-top-level-await` --- ## ๐Ÿงช Testing Steps ### 1. Test in Browser (Should Work) ```bash npm run dev ``` - Open http://localhost:5173 - Navigate to `/auth` โ†’ Create Wallet - Check console: Should see "โœ… WASM initialized successfully" ### 2. Test in Tauri (Now Should Work) ```bash npm run tauri:dev ``` - Tauri window opens - Navigate to `/auth` โ†’ Create Wallet - Open DevTools (F12) - Check console: Should see "โœ… WASM initialized successfully" - Should NOT see any `toString` errors ### 3. Test Wallet Generation ```typescript // In CreateWalletFlow.vue const { generateWallet } = useNeptuneWallet() // Click "Create Wallet" button const result = await generateWallet() // Should return: { receiver_identifier: "...", seed_phrase: ["word1", "word2", ..., "word18"] } ``` --- ## ๐Ÿ“ฆ Package Versions **Installed:** ```json { "devDependencies": { "vite-plugin-wasm": "^3.5.0", "vite-plugin-top-level-await": "^1.6.0" } } ``` **Compatible with:** - Vite 7.x - Tauri 2.x - Vue 3.x --- ## ๐Ÿ”ง Configuration Files ### `vite.config.ts` ```typescript import wasm from 'vite-plugin-wasm' import topLevelAwait from 'vite-plugin-top-level-await' export default defineConfig({ plugins: [ vue(), wasm(), topLevelAwait(), // ... other plugins ], }) ``` ### `tauri.conf.json` ```json { "app": { "security": { "csp": { "script-src": "'self' 'unsafe-inline' 'unsafe-eval' 'wasm-unsafe-eval'" } } } } ``` ### `package.json` ```json { "dependencies": { "@neptune/wasm": "file:./packages/neptune-wasm" }, "devDependencies": { "vite-plugin-wasm": "^3.5.0", "vite-plugin-top-level-await": "^1.6.0" } } ``` --- ## ๐Ÿ’ก Why Browser Works But Tauri Doesn't ### Browser (Chrome/Firefox) - **Permissive WASM loading:** Browsers automatically handle WASM - **Built-in support:** No special config needed - **Dev server:** Vite dev server serves WASM with correct headers ### Tauri (Webview) - **Strict security:** CSP enforced by default - **Custom protocol:** Assets loaded via `tauri://` protocol - **WASM restrictions:** Requires `'wasm-unsafe-eval'` in CSP - **Asset handling:** Needs proper Vite configuration **Tauri = Embedded Browser + Rust Backend** - More secure (CSP enforced) - More restrictive (needs explicit config) - Different asset loading (custom protocol) --- ## ๐Ÿš€ Result **Before:** ```bash npm run dev # โœ… WASM works npm run tauri:dev # โŒ WASM fails (toString error) ``` **After:** ```bash npm run dev # โœ… WASM works npm run tauri:dev # โœ… WASM works! ๐ŸŽ‰ ``` --- ## ๐Ÿ“š Resources - [vite-plugin-wasm GitHub](https://github.com/Menci/vite-plugin-wasm) - [vite-plugin-top-level-await GitHub](https://github.com/Menci/vite-plugin-top-level-await) - [Tauri Security Documentation](https://tauri.app/v2/reference/config/#securityconfig) - [WebAssembly with Vite](https://vitejs.dev/guide/features.html#webassembly) --- ## ๐ŸŽฏ Summary **Problem:** Tauri can't load WASM without proper Vite configuration **Solution:** Install `vite-plugin-wasm` + `vite-plugin-top-level-await` **Result:** WASM works in both browser AND Tauri! ๐Ÿš€