Skip to content

Browser Extension (Chrome MV3) compatibility: wallet.sync() fails due to CSP restrictions #141

@Kenbak

Description

@Kenbak

Browser Extension (Chrome MV3) Compatibility Issue

🐛 Problem

I'm building a Zcash wallet browser extension using WebZjs, but encountering compatibility issues with Chrome Manifest V3's strict Content Security Policy (CSP).

🔍 Details

Environment:

  • Chrome Extension with Manifest V3
  • @chainsafe/webzjs-wallet (latest version)
  • Zcash testnet
  • CSP: script-src 'self' 'wasm-unsafe-eval'

Issue:

Chrome MV3 disallows eval() and new Function() for security reasons. This breaks WebZjs's sync mechanism:

// ❌ Fails in Chrome MV3
await wallet.sync();
// Error: eval() is not allowed in Chrome extensions

await initThreadPool(8);
// Error: Web Workers cannot use eval()Root cause:

  • wallet.sync() spawns Web Workers using eval() internally
  • initThreadPool() also relies on eval() for multi-threading
  • Chrome MV3 CSP blocks these operations

🔧 Current Workaround

I've implemented a custom sync using CipherScan's WASM for client-side decryption:

// ✅ Works: Custom sync with WASM
const compactBlocks = await fetchCompactBlocks(startHeight, endHeight);
const matches = await batch_filter_compact_outputs(compactBlocks, viewingKey);
const balance = calculateBalance(matches); // 0.02 ZEC ✅However, this creates a critical issue:

// WebZjs's internal database is EMPTY (never synced)
await wallet.propose_transfer(accountId, toAddress, amount);
// ❌ Error: "insufficient balance" (WebZjs DB has no notes!)The problem:

  • Custom sync finds funds ✅
  • WebZjs DB remains empty ❌
  • propose_transfer() can't find notes to spend ❌

❓ Questions

Is there a way to:

  1. Use WebZjs sync in single-threaded mode (without eval/Web Workers)?

    • Does WebZjs have a fallback sync mechanism compatible with MV3?
  2. Manually populate WebZjs database with notes from custom sync?

    • Can we inject notes/nullifiers into WebZjs's internal DB?
  3. Use alternative transaction API (PCZTs?) that doesn't require DB sync?
    // Does this work without wallet.sync()?
    const pczt = await wallet.pczt_create(accountId, toAddress, value);

    💡 Why This Matters

Browser extensions are a common use case for crypto wallets (Metamask, Phantom, Rabby, etc.). Chrome MV3 is now mandatory for all new extensions.

Making WebZjs compatible with MV3 would:

  • ✅ Enable Zcash browser wallet extensions
  • ✅ Improve Zcash ecosystem adoption
  • ✅ Align with industry standards (all major wallets support MV3)

📝 Reproduction Steps

  1. Create Chrome Extension (Manifest V3)
  2. Add CSP: "content_security_policy": { "extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self'" }
  3. Initialize WebZjs: const wallet = new WebWallet("test", lightwalletdUrl, 10);
  4. Try to sync: await wallet.sync();Fails with CSP error

🙏 Request

Any guidance on MV3-compatible sync or transaction building would be greatly appreciated!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions