This application might end up running in different contexts: It will probably run inside a web-browser(-like) environment, but the method that it will have to use to interact with the Blockchain Environment is through the so-called Web3 Provider.
Now, depending on what context the application is executed in, one of the following things needs to happen:
- If executed in the Mist Etereum wallet, use the provider that Mist injects into its browser window (
web3 = new Web3(window.web3.currentProvider)).
- If executed in a web-browser when MetaMask is installed, use the provider that MetaMask injects into the browser window (
web3 = new Web3(window.web3.currentProvider))
- If executed in a web-browser when no external tools are installed, Web3 needs to be set up with a
web3 = new Web3(web3.providers.HttpProvider(some_url))that links to an RPC-exposing Ethereum Client endpoint.
Side note: There is the elm-ethereum package, which is able to create Tasks by using the Http-library directly, but it does not support other wallets except when the user themselves sets up a lot of ports.
So, now I am looking into ways to make Elm interact with it.
I know of the following approaches:
- Create a special ‘program’ wrapper (Akin to Html.program, Navigation.program and similar) that uses (1) under the hood but hides most of the implementation details.
- Create a Native/Kernel module.
Here’s my thoughts to each of these methods so far.
Also, it is very common for multiple (asynchronous!) calls to Web3 to need to happen after one-another before we have arrived at the final interesting result. Ports create Commands, and Commands do not seem that composable.
This has the same advantages and disatvantages as the former, except that some of the plumbing can be hidden because we can wrap the port back-and-forth in our own program wrapper.
However, the result will still be calls that are not that composable.
It seems like writing native code would be the only way to create e.g. Tasks, which seem a lot more composable than Commands.
However, writing Native code has been discouraged for a long time and in 0.19 this will no longer be possible at all.
Neither of these approaches seem satisfying.
What am I missing?
Help is greatly appreciated!