mymonero / mymonero-core-js

The JS library containing the Monero crypto plus lightwallet functions behind the official MyMonero apps
BSD 3-Clause "New" or "Revised" License
101 stars 103 forks source link

Provide a way for MyMoneroCoreBridge functions to be accessed via both old sync and new JS async methods #80

Open paulshapiro opened 5 years ago

paulshapiro commented 5 years ago

Going async-only would require some pretty big changes to the MyMonero app... and it would cut off lots of other websites which rely on the synchronous methods, so I hope this can start a discussion about whether people feel comfortable moving to async-only.

For the async version, we can get rid of the monero_utils interface requirement to wait for module load first, since we can put the async wait on self.Module within each method.

gutenye commented 5 years ago

Do you mean all methods are async? It's going to break a lot of old apps. Is there a way import wasm module synchronously, it's a lot easy to fix in this way.

I use a hack in my code for now

import mymonero from 'mymonero-core-js'
mymonero.monero_utils_promise.then((mymoneroUtils) => {
  global.mymoneroUtils = mymoneroUtils
})
paulshapiro commented 5 years ago

Hey @gutenye I totally agree re: breaking other apps. That's why I think personally we need to find a way to support both sync and async. It doesn't seem to make sense to me to require everyone to upgrade to something like webpack + babel to down-compile.

There isn't a way to load the WASM module synchronously, according to my investigations.

The sort of hack you're using could work but of course it could end up racing. What I do is execute my code within the promise fulfillment. That's either within a particular function which is already expected to execute asynchronously (such as with some callback) or it means wrapping the initialization of the app in the promise resolve and then passing the returned monero_utils instance to the rest of the app via something like dependency injection.

swansontec commented 5 years ago

There is no way to use this library on React Native without an async API.

Basically, the React Native Javascript engine talks to native modules using a local network connection. Every method call into native code gets sent over a WebSocket or similar platform-specific connection. The native thread processes the call and send the results back over the same connection. This means all calls into native code must be async, since they are secretly network calls.

The other option, using asm.js, obviously won't perform as well as native code.

I understand that the existing sync API needs to remain for legacy purposes. Plus, WASM doesn't have the same limitations are React Native. Therefore, it seems like this library will simply have to ship two separate API's.