Search code examples
javascriptvue.jsnativescript

How to use ripple-lib with nativescript


Dear stackoverflowers,

i'm having troubles with crypto in nativescript. I want to use a NPM package ripple-lib but found no luck with nativescript-nodeify. How can I make this package work with nativescript vuejs. I Need te make use of the crypto package aswell.

EDIT: If i require the package I first get an error -> Error is: Cannot find module '/Websites/repo/tests/FirebaseVuejs/platforms/ios/FirebaseVuejs/app/tns_modules/nativescript-nodeify/patch-npm-packages.js'.

than if i rebuild there is no error and the package is still giving me the same error as i ran it without nativescript-nodeify:

CONSOLE ERROR file:///app/bundle.js:950:22: TypeError: crypto.randomBytes is not a function. (In 'crypto.randomBytes(16)', 'crypto.randomBytes' is undefined)


Solution

  • ripple-lib is using certain dependencies, that use node.js specific or globally available modules and access them via require or directly from global context. In reality, NativeScript environment is different from both node.js and browser, so we have to make sure all dependencies are met and are available to run in {N} environment.

    For many use-cases nativescript-nodeify plugin does the job, but case of using ripple-lib, it does not resolve the issue so we have to take care of compatibilities manually:

    1) ripple-lib's dependency bignumber.js is using native node library crypto. Since it is not available in {N} runtime, we have to use specially designed module nativescript-randombytes and make it accessible globally with webpack's providePlugin:

    1. Add NativeScript plugin to the project:

      tns plugin add nativescript-randombytes
      
    2. Create a file that will be a partial implementation of crypto module:

      // Example path: project/app/shims/crypto.js
      
      module.exports.randomBytes = require('nativescript-randombytes')
      
    3. Add it to webpack.config.js in plugins configuration:

      plugins: [
        ..., // other plugins
        new webpack.ProvidePlugin({
              crypto: resolve(__dirname, 'app/shims/crypto.js')
          })
      ]
      
    4. Add resolve.alias for our version of crypto in webpack.config.js, so child dependencies require our crypto implementation:

      alias: {
        ..., // Other aliases
        'crypto': resolve(__dirname, 'app/shims/crypto.js')
      }
      

    2) There are few required modules that are missing, though we can install them manually, as they are compatible with NativeScript runtime:

    npm i -S lodash bufferutil tls utf-8-validate
    

    3) ripple-lib doesn't seem to work with available websockets implementation, so we have to use cross-platform solution for NativeScript - nativescript-websockets

    1. Add plugin to the project:

      tns plugin add nativescript-websockets
      
    2. And import it before ripple-lib import:

      import 'nativescript-websockets'
      import { RippleAPI } from 'ripple-lib'
      

    4) net node.js module is also required to establish connection, which can be mocked with webpack node mocks configuration. Add the following under node config options in webpack.config.js:

       node: {
            ..., // Other default NativeScript shims 
            "net": 'mock',
        },
    

    5) Some libraries are confused about the environment they are running in and default to Node, which makes them request non-available modules. To fix it set resolve.aliasFields to 'browser', as following:

       resolve: {
         // other options, aliases, etc
         aliasFields: ['browser']
       }
    

    6) Another library that can't run itself, as it depends on crypto module is create-hash. Good thing is that it is shipped with a browser build which we can use to fix it. Add another alias in resolve options for webpack.config.js:

      alias: {
        ..., // Other aliases
        'create-hash': 'create-hash/browser'
      }
    

    7) After all steps are done make sure to clean up project files. Do the following:

    1. Delete folders:

      rm -rf platforms/android # or ios
      rm -rf hooks
      rm -rf node_modules
      
    2. Reinstall packages and add platforms:

      npm i
      tns platform add android # or ios