@colony/purser-metamask
Version:
A javascript library to interact with a Metamask based Ethereum wallet
257 lines (208 loc) • 6.92 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.setStateEventObserver = exports.getInpageProvider = exports.methodCaller = exports.detect = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _messages = require("./messages");
/*
* @TODO Add isModern() helper method to detect the new version of Metamask
*/
/**
* Detect the Metmask Extensaion
*
* @method detect
*
* @return {boolean} If it's available it will return true, otherwise it will throw
*/
var detect =
/*#__PURE__*/
function () {
var _ref = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee() {
return _regenerator.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
if (!global.ethereum) {
_context.next = 16;
break;
}
_context.t0 = global.ethereum.isUnlocked;
if (!_context.t0) {
_context.next = 6;
break;
}
_context.next = 5;
return global.ethereum.isUnlocked();
case 5:
_context.t0 = !_context.sent;
case 6:
if (!_context.t0) {
_context.next = 8;
break;
}
throw new Error(_messages.helpers.isLocked);
case 8:
_context.t1 = global.ethereum.isEnabled;
if (!_context.t1) {
_context.next = 13;
break;
}
_context.next = 12;
return global.ethereum.isEnabled();
case 12:
_context.t1 = !_context.sent;
case 13:
if (!_context.t1) {
_context.next = 15;
break;
}
throw new Error(_messages.helpers.notEnabled);
case 15:
return _context.abrupt("return", true);
case 16:
if (!(!global.ethereum && global.web3)) {
_context.next = 24;
break;
}
if (!(!global.web3.currentProvider || !global.web3.currentProvider.publicConfigStore)) {
_context.next = 19;
break;
}
throw new Error(_messages.helpers.noInpageProvider);
case 19:
if (global.web3.currentProvider.publicConfigStore._state) {
_context.next = 21;
break;
}
throw new Error(_messages.helpers.noProviderState);
case 21:
if (global.web3.currentProvider.publicConfigStore._state.selectedAddress) {
_context.next = 23;
break;
}
throw new Error(_messages.helpers.notEnabled);
case 23:
return _context.abrupt("return", true);
case 24:
throw new Error(_messages.helpers.noExtension);
case 25:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
return function detect() {
return _ref.apply(this, arguments);
};
}();
/**
* Helper method that wraps a method passed as an argument and first checks
* for Metamask's availablity before calling it.
*
* This is basically a wrapper, so that we can cut down on code repetition, since
* this pattern repeats itself every time we try to access the in-page proxy.
*
* @method methodCaller
*
* @param {Function} callback The method to call, if Metamask is available
* @param {string} errorMessage Optional error message to show to use
* (in case Metamask is not available)
*
* @return {any} It returns the result of the callback execution
*/
exports.detect = detect;
var methodCaller =
/*#__PURE__*/
function () {
var _ref2 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee2(callback) {
var errorMessage,
_args2 = arguments;
return _regenerator.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
errorMessage = _args2.length > 1 && _args2[1] !== undefined ? _args2[1] : '';
_context2.prev = 1;
_context2.next = 4;
return metamaskHelpers.detect();
case 4:
return _context2.abrupt("return", callback());
case 7:
_context2.prev = 7;
_context2.t0 = _context2["catch"](1);
throw new Error("".concat(errorMessage).concat(errorMessage ? ' ' : '', "Error: ").concat(_context2.t0.message));
case 10:
case "end":
return _context2.stop();
}
}
}, _callee2, this, [[1, 7]]);
}));
return function methodCaller(_x) {
return _ref2.apply(this, arguments);
};
}();
/**
* If the Metamask injected instance is available, get the in-page provider
*
* @method getInpageProvider
*
* @return {Object} The `MetamaskInpageProvider` object instance
*/
exports.methodCaller = methodCaller;
var getInpageProvider = function getInpageProvider() {
/*
* We need this little go-around trick to mock just one export of
* the module, while leaving the rest of the module intact so we can test it
*
* See: https://github.com/facebook/jest/issues/936
*/
if (global.ethereum) {
return global.ethereum;
}
return global.web3.currentProvider;
};
/**
* Add a new observer method to Metamask's state update events
*
* @method setStateEventObserver
*
* @param {Function} observer Function to add the state events update array
*
* @return {number} the length of the state events update array
*/
exports.getInpageProvider = getInpageProvider;
var setStateEventObserver = function setStateEventObserver(observer) {
var _metamaskHelpers$getI =
/*
* We need this little go-around trick to mock just one export of
* the module, while leaving the rest of the module intact so we can test it
*
* See: https://github.com/facebook/jest/issues/936
*/
/* eslint-disable-next-line no-use-before-define */
metamaskHelpers.getInpageProvider(),
stateEvents = _metamaskHelpers$getI.publicConfigStore._events;
return stateEvents.update.push(observer);
};
/*
* This default export is only here to help us with testing, otherwise
* it wound't be needed
*/
exports.setStateEventObserver = setStateEventObserver;
var metamaskHelpers = {
detect: detect,
methodCaller: methodCaller,
getInpageProvider: getInpageProvider,
setStateEventObserver: setStateEventObserver
};
var _default = metamaskHelpers;
exports.default = _default;