UNPKG

@colony/purser-metamask

Version:

A javascript library to interact with a Metamask based Ethereum wallet

212 lines (189 loc) 6.28 kB
import _regeneratorRuntime from "@babel/runtime/regenerator"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator"; import Web3Instance from 'web3'; import { warning } from '@colony/purser-core/utils'; import MetamaskWallet from './class'; import { methodCaller, getInpageProvider, detect as detectHelper, setStateEventObserver } from './helpers'; import { staticMethods as messages } from './messages'; /** * Open the Metamask Wallet instance * * @method open * * @return {WalletType} The wallet object resulted by instantiating the class * (Object is wrapped in a promise). */ export var open = /*#__PURE__*/ function () { var _ref = _asyncToGenerator( /*#__PURE__*/ _regeneratorRuntime.mark(function _callee() { var addressAfterEnable, _ref2, _ref3, legacyProvider; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.prev = 0; if (!global.ethereum) { _context.next = 8; break; } /* * Inject the web3 provider */ global.web3 = new Web3Instance(global.ethereum); /* * Enable it */ _context.next = 5; return global.ethereum.enable(); case 5: _ref2 = _context.sent; _ref3 = _slicedToArray(_ref2, 1); addressAfterEnable = _ref3[0]; case 8: /* * We're on the legacy version of Metamask */ if (!global.ethereum && global.web3) { /* * Warn the user about legacy mode * * @TODO Remove legacy metmask version messages * After an adequate amount of time has passed */ warning(messages.legacyMode); /* * Enable it * * @NOTE There's an argument to be made here that it's dangerous to use * the `getInpageProvider()` helper before using `detect()` */ legacyProvider = getInpageProvider(); legacyProvider.enable(); /* * Inject the web3 provider (overwrite the current one) */ global.web3 = new Web3Instance(legacyProvider); } /* * Everything functions the same since the Web3 instance is now in place * (Granted, it's now using the 1.x.x version) */ return _context.abrupt("return", methodCaller(function () { var _getInpageProvider = getInpageProvider(), state = _getInpageProvider.publicConfigStore._state; return new MetamaskWallet({ /* * The EIP-1102 mode uses the address we got after enabling (and getting * the users's permission), while the legacy mode get the address from * the state */ address: addressAfterEnable || state.selectedAddress }); }, messages.metamaskNotAvailable)); case 12: _context.prev = 12; _context.t0 = _context["catch"](0); throw new Error(messages.didNotAuthorize); case 15: case "end": return _context.stop(); } } }, _callee, this, [[0, 12]]); })); return function open() { return _ref.apply(this, arguments); }; }(); /** * Check if Metamask's injected web3 proxy instance is available in the * global object. * * Makes use of the `detect()` helper, basically it's a wrapper * that exposes it from the module. * * @method detect * * @return {boolean} Only returns true if it's available, otherwise it will throw. */ export var detect = /*#__PURE__*/ function () { var _ref4 = _asyncToGenerator( /*#__PURE__*/ _regeneratorRuntime.mark(function _callee2() { return _regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: return _context2.abrupt("return", detectHelper()); case 1: case "end": return _context2.stop(); } } }, _callee2, this); })); return function detect() { return _ref4.apply(this, arguments); }; }(); /** * Hook into Metamask's state events observers array to be able to act on account * changes from the UI * * It's a wrapper around the `setStateEventObserver()` helper method * * @method accountChangeHook * * @param {Function} callback Function to add the state events update array * It receives the state object as an only argument * * @return {Promise<void>} Does not return noting */ export var accountChangeHook = /*#__PURE__*/ function () { var _ref5 = _asyncToGenerator( /*#__PURE__*/ _regeneratorRuntime.mark(function _callee3(callback) { return _regeneratorRuntime.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: /* * If detect fails, it will throw, with a message explaining the problem * (Most likely Metamask will be locked, so we won't be able to get to * the state observer via the in-page provider) */ detectHelper(); _context3.prev = 1; return _context3.abrupt("return", setStateEventObserver(callback)); case 5: _context3.prev = 5; _context3.t0 = _context3["catch"](1); throw new Error(messages.cannotAddHook); case 8: case "end": return _context3.stop(); } } }, _callee3, this, [[1, 5]]); })); return function accountChangeHook(_x) { return _ref5.apply(this, arguments); }; }(); /* * @NOTE There's an argument to be made here to expose the new version */ var metamaskWallet = { open: open, detect: detect, accountChangeHook: accountChangeHook }; export default metamaskWallet;