JoinColony/purser

Ledger workaround for projects using babel@7

Opened this issue · 3 comments

rdig commented

The Ledger npm packages of which we use @ledgerhq/hw-app-eth and the u2f transport: @ledgerhq/hw-transport-u2f currently use the old version of babel (pre version 7, with the old name spacing).

If you're running a project with babel version 7 the u2f transport will fail claiming that:

regeneratorRuntime is not defined

screenshot from 2018-11-19 15-49-06

This is a two prong problem:

First, even though the core @ledgerhq/hw-transport imports babel-regenerator and uses it, it's the old version (pre babel version 7)

Second, the @ledgerhq/hw-transport-u2f does not use it, since it's not declared in it's manifest (although the build process make use of it, before pushing the package to npm)

All of the above are brought to the attention of the Ledger team via:
LedgerHQ/ledgerjs#218
LedgerHQ/ledgerjs#211

And there's even a PR hoping to fix this:
LedgerHQ/ledgerjs#241

This issue is here to either track merging of the above PR (and subsequently updating purser), or implementing a patch for purser to overcome this.

rdig commented

If you want to get your hands dirty in a hardcore way, after the the @ledgerhq/hw-transport-u2f package is installed in your node_modules folder go to:

node_modules/@ledgerhq/hw-transport-u2f/lib/TransportU2F.js

And add the following to line 17:

var regeneratorRuntime = require("@babel/runtime/regenerator");

This will tell the built file to import it, so when it makes a call to it on line 122 it will find it in the modules tree

Here's a patch to manually apply it:

diff --git a/TransportU2F.orig.js b/TransportU2F.js
index 61a4233a..e063831a 100644
--- a/TransportU2F.orig.js
+++ b/TransportU2F.js
@@ -14,6 +14,8 @@ var _hwTransport = require("@ledgerhq/hw-transport");
 
 var _hwTransport2 = _interopRequireDefault(_hwTransport);
 
+var regeneratorRuntime = require("@babel/runtime/regenerator");
+
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

I had this problem, ended up locking version to 4.24.0 in my package.json to resolve it. Not ideal since it's been broken for 3 months.

rdig commented

We also saw some success by using webpack's ProvidePlugin to auto import babel 7's runtime regenerator.

Something like this:

const webpack = require('webpack');

const config = {
  ...
  plugins: [
    new webpack.ProvidePlugin({
      regeneratorRuntime: '@babel/runtime/regenerator',
    }),
    ...
  ],
  ...
};

module.exports = () => config;

But of course, this is only in projects that rely on webpack to do the bundling.