Closed greynewell closed 4 months ago
Interestingly, I seem to run into the same roadblock with the legacy initCrypto()
after polyfilling crypto
, fs
, and path
with Browserify:
Will try uninstalling cawfree's package to see if I can unblock the legacy path another way.
Sadly, it appears WebAssembly
support is required to load even the legacy Olm
based crypto:
DEBUG Crypto: Starting up crypto store...
DEBUG Crypto: initialising roomlist...
DEBUG Crypto: initialising crypto object...
DEBUG Crypto: initialising Olm...
WARN Aborted(no native wasm support detected)
ERROR no native wasm support detected
Will keep digging to see if I can find a workaround.
Sadly, it appears WebAssembly support is required to load even the legacy Olm based crypto:
Yes, Olm is a C++ library so cannot be loaded without WASM
@greynewell I haven't yet attempted this myself but what if you connected olm on the native side? https://github.com/jitsi/react-native-olm appears to go down that route.
I was able to get https://github.com/jitsi/react-native-olm to compile and run. It only includes the Account
and Session
classes though and merely a subset of the available methods on either. We'd have to add the remaining methods and classes to match https://gitlab.matrix.org/matrix-org/olm/-/blob/master/javascript/index.d.ts. It's not exactly little work but then again it's probably a matter of diligence given that things should largely follow what already exists in the library.
Additionally to the above, the library also needs fixes for both platforms to work with recent React Native versions. I put in issues with details upstream.
Sadly, it appears WebAssembly support is required to load even the legacy Olm based crypto:
Yes, Olm is a C++ library so cannot be loaded without WASM
Actually, seems like there is a legacy-legacy version of Olm that does not depend on WASM.
- Using
olm/olm.js
will use the WebAssembly version of the library. For environments that do not support WebAssembly, useolm/olm_legacy.js
.
https://gitlab.matrix.org/matrix-org/olm/-/blob/master/CHANGELOG.rst#L278-279
Confirming that decryption works in React Native without WASM by using olm_legacy
and https://github.com/margelo/react-native-quick-crypto. 🤩
@Johennes Care to drop a working example?
I only have this set up in a private app at the moment, unfortunately, and only in PoC form. I'm also not using Expo, so I'm not sure if what I've done transfers easily. But, for what it's worth, here are the steps I took:
@matrix-org/olm
& react-native-quick-crypto
as a dependencycrypto
imports to react-native-quick-crypto
via metro.config.js
resolveRequest: (context, moduleName, platform) => {
// Map crypto imports from olm to react-native-quick-crypto
if (moduleName === 'crypto') {
return context.resolveRequest(context, 'react-native-quick-crypto', platform);
}
}
react-native-quick-crypto
and set Olm
global In index.js
import 'react-native-quick-crypto';
global.Olm = require('@matrix-org/olm/olm_legacy'); <<< Note how this is using olm_legacy
client.initCrypto();
inbetween createClient
and client.startClient
client.decryptEventIfNeeded(event)
to decrypt new eventsThere is more work needed to create a crypto store that persists keys and such across app relaunches (the ones that ship with matrix-js-sdk don't work in React Native). But at least, as a puncture, I was able to decrypt events this way.
Unfortunately, it's unlikely we'll support the Rust crypto library in an environment that doesn't support WASM. [I don't know if building it as a native node module or something might work in future, but that's not likely to happen in the short term.]
You might be able to get the legacy library working for now, but we'll be removing it soon (https://github.com/element-hq/element-web/issues/26922). https://github.com/element-hq/element-web/issues/26922#issuecomment-2090068611 discusses ways we might be able to improve this in future.
I only have this set up in a private app at the moment, unfortunately, and only in PoC form. I'm also not using Expo, so I'm not sure if what I've done transfers easily. But, for what it's worth, here are the steps I took:
- Add
@matrix-org/olm
&react-native-quick-crypto
as a dependency- Map
crypto
imports toreact-native-quick-crypto
viametro.config.js
resolveRequest: (context, moduleName, platform) => { // Map crypto imports from olm to react-native-quick-crypto if (moduleName === 'crypto') { return context.resolveRequest(context, 'react-native-quick-crypto', platform); } }
- Import
react-native-quick-crypto
and setOlm
global Inindex.js
import 'react-native-quick-crypto'; global.Olm = require('@matrix-org/olm/olm_legacy'); <<< Note how this is using olm_legacy
- Call
client.initCrypto();
inbetweencreateClient
andclient.startClient
- Try using
client.decryptEventIfNeeded(event)
to decrypt new eventsThere is more work needed to create a crypto store that persists keys and such across app relaunches (the ones that ship with matrix-js-sdk don't work in React Native). But at least, as a puncture, I was able to decrypt events this way.
hi , can you please mention specific version of react-native-quick-crypto which you used. i am also trying to integrate matrix in my react native app. and i am getting error that TypeError: Cannot read property 'getRandomValues' of undefined
if i don’t import it in index.js or anywhere. and if i import it then i get the error TypeError: Cannot read property 'slice' of undefined, js engine: hermes
and i am unable to solve it. thank you in advance.
My RN Version: 0.72.3 "react-native-quick-crypto": "^0.6.1", "@matrix-org/olm": "^3.2.15",
We probably shouldn't be discussing on a closed issue but for lack of a better place and future reference:
0.6.1 should have crypto.getRandomValues
so your problem is likely a case of making crypto
available to your dependencies. I did both, redirect the crypto
import and import react-native-quick-crypto
in index.js
.
That being said, I have since given up on trying to use matrix-js-sdk with React Native as it kept feeling like an uphill battle. There's nothing wrong with matrix-js-sdk. It's just that RN's environment is peculiar enough that trying to use a non-trivial library that wasn't specifically written for RN can be a royal pain in the ****. The further issues I ran into were that https://github.com/matrix-org/matrix-encrypt-attachment doesn't work with RN out of the box and that react-native-quick-crypto has very limited support for crypto.subtle
.
I have started an effort to make matrix-rust-sdk available in RN via a turbo module but it's still very far from being usable.
Howdy! I've been working to enable
initRustCrypto()
inside of Expo: https://github.com/wdym-chat/expo-matrix-js-sdk/issues/5I was able to sideload WASM support inside React Native using Cawfree's package, but ran into an issue: https://github.com/cawfree/react-native-webassembly/issues/28
I wanted to ask, has anyone here successfully initialized Rust crypto (or even the legacy crypto) in React Native, and if so, how did you achieve that?
I've been researching this issue pretty hard, and the working solutions out there seem to rely on extremely dated libs/runtimes and to be exclusive of Expo, so any suggestions would be welcomed.