Historical context
Currently, importing and using functions from the WASM blob is quite cumbersome.
Our version of CRA depends on webpack 4 which doesn't support asynchronous chunks being loaded as part of the initial request. As a result, we cannot use say:
import { wallet_status } from "./wallet"
Where ./wallet represents the module generated by wasm-bindgen.
Instead we have to use dynamic imports (await import ("./wallet")) to access any function defined in the WASM binary.
Problems
These dynamic imports impose problems:
- Duplicated wallets: If we load the wallet from different endpoints (i.e. not just the background script but say, a new popup window), we effectively get two instances of the wallet and unlocking one will not unlock the other.
- Complexity: We have to write a lot of dumb code to call a function exposed by the WASM blob. To make the developer experience nicer, this integration should be as seamless as possible. This complexity also surfaces in the lack of nice error reporting when something goes wrong.
Ideas to improve the situation
- Experiment with the recent alpha release of
react-scripts: https://www.npmjs.com/package/react-scripts/v/5.0.0-next.31
This release upgrades to webpack5 which supports loading asynchronous modules as part of the initial chunk. In other words, if we get this working, we can just import the wasm-functions like any other functions from the background script, effectively getting rid of wasm_proxy.ts. Note that I think this still doesn't solve the "duplicate wallet" issue if we were to import the wasm from multiple places.
- Register message handlers directly from within Rust.
Once #227 is merged, message handlers for rpc-messages from the content-script are registered independently. We could therefore experiment with registering a handler through browser.runtime.onMessage.addListener directly from within the Rust module. This would cut out on the indirection through the Typescript-based background script.
Vision
If we manage to do (1) and (2), we should be able to:
- Have a single, very simple background script that only imports the wasm-blob, effectively initializing the wallet and acting as the wallet "host". Because the background script lives for the entire duration of the extension, there would only be one wallet.
- Directly response to messages from the content-script and other popups from within Rust, cutting out all pass-through layers like the current background script, background proxy, wasm-proxy, etc. Rust has excellent meta-programming which should allow us to keep the boilerplate of creating such event listener small through the use of proc-macros.
Historical context
Currently, importing and using functions from the WASM blob is quite cumbersome.
Our version of CRA depends on webpack 4 which doesn't support asynchronous chunks being loaded as part of the initial request. As a result, we cannot use say:
Where
./walletrepresents the module generated bywasm-bindgen.Instead we have to use dynamic imports (
await import ("./wallet")) to access any function defined in the WASM binary.Problems
These dynamic imports impose problems:
Ideas to improve the situation
react-scripts: https://www.npmjs.com/package/react-scripts/v/5.0.0-next.31This release upgrades to webpack5 which supports loading asynchronous modules as part of the initial chunk. In other words, if we get this working, we can just import the wasm-functions like any other functions from the background script, effectively getting rid of
wasm_proxy.ts. Note that I think this still doesn't solve the "duplicate wallet" issue if we were to import the wasm from multiple places.Once #227 is merged, message handlers for rpc-messages from the content-script are registered independently. We could therefore experiment with registering a handler through
browser.runtime.onMessage.addListenerdirectly from within the Rust module. This would cut out on the indirection through the Typescript-based background script.Vision
If we manage to do (1) and (2), we should be able to: