UNPKG

@colony/purser-metamask

Version:

A javascript library to interact with a Metamask based Ethereum wallet

257 lines (208 loc) 6.92 kB
"use strict"; 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;