Document how to get working on React Native
Copy Nando's instructions below to a place and in a format where devs can set this up on RN themselves.
@fnando Did you write up a guide for the stuff you had to do to get this working? The real mitigation seems like enough work that maybe we should just tell people to do what you did, if the list of steps isn't onerous.
@morleyzhi No, but I can write down the steps. There aren't many, but is kinda tricky to get everything working. I'll add it to my tasks of the week.
@morleyzhi We were dealing with this eventsource logic issue when working with the @pigzbe/react-native-stellar-sdk polyfill and upgrading to v.0.15.0. See #2. The @pigzbe/react-native-stellar-sdk implementation uses react-native-randombytes.
Still, I ended up having to fork js-stellar-sdk to hack the logic for detecting whether we were on RN in call_builder.js#L13.
The combo of @mikeyrf/js-stellar-sdk & @mikeyrf/react-native-stellar-sdk repos has been working in our RN app, although my js-stellar-sdk fork is only on v. 0.15.0.
@mikeyrf I was able to make it work without using forks by using https://github.com/tradle/rn-nodeify. I'm curious if you tried that before going the fork route.
Cool, that's good to know! If there's a real performance gain to making keyPair run async, it sounds like we need to do a hybrid approach, where we fix as many of these bugs as we can (probably through platform detection) AND have a guide to shim the stuff we can't fix.
@fnando I did but I wasn't able to get things running. It might have been because I'm using an ejected version of expo, not sure tho.
@morleyzhi From a UX perspective, the keyPair generation w async isn't a huge problem, since most users expect the initialization of their accounts to take some time within a signup flow. Since Stellar is account based, I really only call that function once during onboarding (then thats it).
I tend to prefer the @pigzbe/react-native-stellar-sdk polyfill approach, where js-stellar-sdk doesn't have anything RN in it.
Ideally, stellar would have an official rn-stellar-sdk polyfill repo that users can simply yarn add, then react-native link react-native-randombytes and you're good. The @pigzbe/react-native-stellar-sdk README.md details this well.
Here are the steps to make stellar-sdk work with react-native:
- Add the following
postinstallscript:
yarn rn-nodeify --install url,events,https,http,util,stream,crypto,vm,buffer --hack --yarn
-
yarn add -D rn-nodeify - Uncomment
require('crypto')on shim.js -
react-native link react-native-randombytes - Create file
rn-cli.config.js
module.exports = {
resolver: {
extraNodeModules: require("node-libs-react-native"),
},
};
- Add
import "./shim";to the top ofindex.js -
yarn add stellar-sdk
I have a sample app configured with these exact steps at https://github.com/fnando/rn-stellar-sdk-sample
Wonder if it's even possible to pass a random number generator and default to Node's crypto module or the Web Crypto API on browsers.
This seems to not blow up (emphasis on seems) on Expo if you:
- Grab a copy of the SDK from the CDN and save to disk
- Edit the SDK like so:
// import `expo-random` a write `global.crypto`
import * as Random from 'expo-random';
global.crypto = {
randombytes: Random.getRandomBytes,
randomBytes: Random.getRandomBytes
}
Then scroll down until you find:
} else if (true) {
// Node.js.
// crypto = __webpack_require__(193); <-- Comment out this line
if (crypto && crypto.randomBytes) {
nacl.setPRNG(function(x, n) {
var i, v = crypto.randomBytes(n);
for (i = 0; i < n; i++) x[i] = v[i];
cleanup(v);
});
}
}
Finally, you need to export the StellarSdk
// at the EOF
export default StellarSdk;
With these changes I can generate keypairs without the need to eject my Expo project.
Here's how you can do it on Expo without the need to edit the SDK as in my previous comment, nor having to eject to add react-native-randombytes. It's almost the same approach as @fnando's, but uses expo-random instead (also, I'm using npm instead of yarn)
-
npm i -D rn-nodeify - Add a new NPM
postinstallscript:rn-nodeify --install process,url,events,https,http,util,stream,vm,buffer --hack - Import the generated
./shim.jsfile at the top of your app's entry — by default, it's located in./App -
npm i stellar-sdk
At this point, the stellar SDK will work, except that StellarSdk.Keypair.random() will throw an error. So to work around this you can create your own method to generate a random keypair like this:
import * as Random from 'expo-random';
import StellarSdk from 'stellar-sdk';
const generateRandomKeypair = () => {
const randomBytes = Random.getRandomBytes(32);
return StellarSdk.Keypair.fromRawEd25519Seed(Buffer.from(randomBytes));
};
I just made a thing that could make Expo users' life a lil' bit easier.
https://github.com/silvestreh/expo-stellar-sdk
It basically is just a wrapper for the Stellar SDK that overrides the Keypair.random method like on my previous comment and shims some node modules so that the SDK works in Expo managed workflows.