UNPKG

web3-react-dcent-biometric-connector

Version:

A simple, maximally extensible, dependency minimized framework for building modern Ethereum dApps

612 lines (533 loc) 17.5 kB
'use strict'; function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var abstractConnector = require('@web3-react/abstract-connector'); var Web3ProviderEngine = _interopDefault(require('web3-provider-engine')); var HookedWallet = _interopDefault(require('web3-provider-engine/subproviders/hooked-wallet')); var DcentConnector$1 = _interopDefault(require('dcent-web-connector')); var CacheSubprovider = _interopDefault(require('web3-provider-engine/subproviders/cache.js')); var rpc_subprovider = require('@0x/subproviders/lib/src/subproviders/rpc_subprovider'); function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } // A type of promise-like that resolves synchronously and supports only one observer const _Pact = /*#__PURE__*/(function() { function _Pact() {} _Pact.prototype.then = function(onFulfilled, onRejected) { const result = new _Pact(); const state = this.s; if (state) { const callback = state & 1 ? onFulfilled : onRejected; if (callback) { try { _settle(result, 1, callback(this.v)); } catch (e) { _settle(result, 2, e); } return result; } else { return this; } } this.o = function(_this) { try { const value = _this.v; if (_this.s & 1) { _settle(result, 1, onFulfilled ? onFulfilled(value) : value); } else if (onRejected) { _settle(result, 1, onRejected(value)); } else { _settle(result, 2, value); } } catch (e) { _settle(result, 2, e); } }; return result; }; return _Pact; })(); // Settles a pact synchronously function _settle(pact, state, value) { if (!pact.s) { if (value instanceof _Pact) { if (value.s) { if (state & 1) { state = value.s; } value = value.v; } else { value.o = _settle.bind(null, pact, state); return; } } if (value && value.then) { value.then(_settle.bind(null, pact, state), _settle.bind(null, pact, 2)); return; } pact.s = state; pact.v = value; const observer = pact.o; if (observer) { observer(pact); } } } function _isSettledPact(thenable) { return thenable instanceof _Pact && thenable.s & 1; } // Asynchronously iterate through an object that has a length property, passing the index as the first argument to the callback (even as the length property changes) function _forTo(array, body, check) { var i = -1, pact, reject; function _cycle(result) { try { while (++i < array.length && (!check || !check())) { result = body(i); if (result && result.then) { if (_isSettledPact(result)) { result = result.v; } else { result.then(_cycle, reject || (reject = _settle.bind(null, pact = new _Pact(), 2))); return; } } } if (pact) { _settle(pact, 1, result); } else { pact = result; } } catch (e) { _settle(pact || (pact = new _Pact()), 2, e); } } _cycle(); return pact; } const _iteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.iterator || (Symbol.iterator = Symbol("Symbol.iterator"))) : "@@iterator"; // Asynchronously iterate through an object's values // Uses for...of if the runtime supports it, otherwise iterates until length on a copy function _forOf(target, body, check) { if (typeof target[_iteratorSymbol] === "function") { var iterator = target[_iteratorSymbol](), step, pact, reject; function _cycle(result) { try { while (!(step = iterator.next()).done && (!check || !check())) { result = body(step.value); if (result && result.then) { if (_isSettledPact(result)) { result = result.v; } else { result.then(_cycle, reject || (reject = _settle.bind(null, pact = new _Pact(), 2))); return; } } } if (pact) { _settle(pact, 1, result); } else { pact = result; } } catch (e) { _settle(pact || (pact = new _Pact()), 2, e); } } _cycle(); if (iterator.return) { var _fixup = function(value) { try { if (!step.done) { iterator.return(); } } catch(e) { } return value; }; if (pact && pact.then) { return pact.then(_fixup, function(e) { throw _fixup(e); }); } _fixup(); } return pact; } // No support for Symbol.iterator if (!("length" in target)) { throw new TypeError("Object is not iterable"); } // Handle live collections properly var values = []; for (var i = 0; i < target.length; i++) { values.push(target[i]); } return _forTo(values, function(i) { return body(values[i]); }, check); } const _asyncIteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.asyncIterator || (Symbol.asyncIterator = Symbol("Symbol.asyncIterator"))) : "@@asyncIterator"; // Asynchronously call a function and send errors to recovery continuation function _catch(body, recover) { try { var result = body(); } catch(e) { return recover(e); } if (result && result.then) { return result.then(void 0, recover); } return result; } // Asynchronously await a promise and pass the result to a finally continuation function _finallyRethrows(body, finalizer) { try { var result = body(); } catch (e) { return finalizer(true, e); } if (result && result.then) { return result.then(finalizer.bind(null, false), finalizer.bind(null, true)); } return finalizer(false, result); } var LOG; { LOG = /*#__PURE__*/console.log.bind(console, "[LOG]"); } var LOG$1 = LOG; var pathMap = {}; var networkId; /** * * @param {string} address */ var getPath = function getPath(address) { try { for (var key in pathMap) { if (key.toLowerCase() === address.toLowerCase()) return Promise.resolve(pathMap[key]); } return Promise.resolve(); } catch (e) { return Promise.reject(e); } }; var openPopup = function openPopup() { try { return Promise.resolve(DcentConnector$1.dcentPopupWindow()).then(function (popupResult) { if (popupResult != null && popupResult.header.status === "error") { throw new Error(popupResult.body.error.message); } return popupResult; }); } catch (e) { return Promise.reject(e); } }; // D'CENT Bridge Service window appears and wait for the device to connect. var waitConnectWallet = function waitConnectWallet() { try { if (!DcentConnector$1.popupWindow || DcentConnector$1.popupWindow.closed) { throw new Error("popup_closed"); } return Promise.resolve(DcentConnector$1.info()).then(function (infoResult) { var _temp = function () { if (!infoResult.body.parameter.isUsbAttached) { return Promise.resolve(new Promise(function (resolve, reject) { setTimeout(function () { waitConnectWallet().then(function () { resolve(); })["catch"](function (err) { reject(err); }); }, 500); })).then(function () {}); } }(); if (_temp && _temp.then) return _temp.then(function () {}); }); } catch (e) { return Promise.reject(e); } }; var getAccountsAsync = function getAccountsAsync() { try { if (Object.keys(pathMap).length > 0) { // If has 'pathMap' return Promise.resolve(Object.keys(pathMap)); } return Promise.resolve(openPopup()).then(function () { return Promise.resolve(waitConnectWallet()).then(function () { // Get all accounts list return Promise.resolve(DcentConnector$1.getAccountInfo()).then(function (accountResult) { function _temp3() { LOG$1("dcent addresses: ", addresses); DcentConnector$1.popupWindowClose(); return addresses; } LOG$1("dcent accountInfo result: ", accountResult); var accounts = accountResult.body.parameter.account; LOG$1("dcent accounts: ", accounts); // Get only ethereum accounts var etherAccounts = accounts.filter(function (accountInfo) { return accountInfo.coin_name === DcentConnector$1.coinGroup.ETHEREUM; }); var paths = []; etherAccounts.forEach(function (accountInfo) { paths.push(accountInfo.address_path); }); LOG$1("dcent ethereum path: ", paths); // There is no account if (paths.length === 0) { paths.push("m/44'/60'/0'/0/0"); console.warn("[D'CENT] cannot find exists ethereum accounts. use default path"); } // get address with BIP32 path var addresses = []; var _temp2 = _forOf(paths, function (path) { return Promise.resolve(DcentConnector$1.getAddress(DcentConnector$1.coinType.ETHEREUM, path)).then(function (addressResult) { pathMap[addressResult.body.parameter.address] = path; addresses.push(addressResult.body.parameter.address); }); }); return _temp2 && _temp2.then ? _temp2.then(_temp3) : _temp3(_temp2); }); }); }); } catch (e) { return Promise.reject(e); } }; var signTransaction = function signTransaction(txData, callback) { if (typeof callback === "undefined") { return signTransactionAsync(txData); } else { signTransactionAsync(txData).then(function (transaction) { callback(null, transaction); })["catch"](function (err) { callback(err, null); }); } }; /** * * @param {Object} txData * @param {string} txData.from * @param {string} txData.gas * @param {string} txData.gasPrice * @param {string} txData.nonce * @param {string} txData.to * @param {string} txData.value * @param {string} txData.data */ var signTransactionAsync = function signTransactionAsync(txData) { try { return Promise.resolve(openPopup()).then(function () { return Promise.resolve(waitConnectWallet()).then(function () { LOG$1("dcent signTransactionAsync txData: ", txData); LOG$1("dcent signTransactionAsync pathMap: ", pathMap); return Promise.resolve(getPath(txData.from)).then(function (path) { var _exit = false; function _temp5(_result) { if (_exit) return _result; LOG$1("dcent signTransaction tx: ", txResult); return "0x" + txResult.body.parameter.signed; } if (!path) throw new Error("address unknown '" + txData.from + "'"); LOG$1("dcent signTransactionAsync path: ", path); LOG$1("dcent signTransactionAsync networkId: ", networkId); var txResult; var _temp4 = _finallyRethrows(function () { return _catch(function () { return Promise.resolve(DcentConnector$1.getEthereumSignedTransaction(DcentConnector$1.coinType.ETHEREUM, txData.nonce, txData.gasPrice, txData.gas, txData.to, txData.value || "0", txData.data || "0x", path, networkId)).then(function (_DcentConnector$getEt) { txResult = _DcentConnector$getEt; }); }, function (err) { if (err.header.response_from === "wam") { throw new Error("no_device"); } if (err.body.error.code) { throw new Error(err.body.error.code); // throw new Error('Action cancelled by user') } throw err; }); }, function (_wasThrown, _result) { DcentConnector$1.popupWindowClose(); if (_wasThrown) throw _result; return _result; }); return _temp4 && _temp4.then ? _temp4.then(_temp5) : _temp5(_temp4); }); }); }); } catch (e) { return Promise.reject(e); } }; var signPersonalMessage = function signPersonalMessage(msgData, callback) { if (typeof callback === "undefined") { return signPersonalMessageAsync(msgData); } else { signPersonalMessageAsync(msgData).then(function (transaction) { callback(null, transaction); })["catch"](function (err) { callback(err, null); }); } }; /** * * @param {Object} msgData * @param {string} msgData.data * @param {string} msgData.from */ var signPersonalMessageAsync = function signPersonalMessageAsync(msgData) { try { return Promise.resolve(openPopup()).then(function () { return Promise.resolve(waitConnectWallet()).then(function () { LOG$1("dcent signPersonalMessageAsync msgData= ", msgData); return Promise.resolve(getPath(msgData.from)).then(function (path) { var _exit2 = false; function _temp7(_result2) { if (_exit2) return _result2; LOG$1("dcent signPersonalMessageAsync result: ", txResult); return txResult.body.parameter.sign; } if (!path) throw new Error("address unknown '" + msgData.from + "'"); var txResult; var _temp6 = _finallyRethrows(function () { return _catch(function () { return Promise.resolve(DcentConnector$1.getEthereumSignedMessage(msgData.data, path)).then(function (_DcentConnector$getEt2) { txResult = _DcentConnector$getEt2; }); }, function (err) { if (err.header.response_from === "wam") { throw new Error("no_device"); } if (err.body.error.code) { throw new Error(err.body.error.code); } throw err; }); }, function (_wasThrown2, _result2) { DcentConnector$1.popupWindowClose(); if (_wasThrown2) throw _result2; return _result2; }); return _temp6 && _temp6.then ? _temp6.then(_temp7) : _temp7(_temp6); }); }); }); } catch (e) { return Promise.reject(e); } }; var DcentHookedWalletSubprovider = /*#__PURE__*/function (_HookedWallet) { _inheritsLoose(DcentHookedWalletSubprovider, _HookedWallet); function DcentHookedWalletSubprovider(opts) { if (opts === void 0) { opts = {}; } var extOpts = { signTransaction: signTransaction, signPersonalMessage: signPersonalMessage, signMessage: signPersonalMessage }; var options = Object.assign(opts, extOpts); LOG$1("dcent DcentHookedWalletSubprovider constructor options: ", options); networkId = opts.networkId; return _HookedWallet.call(this, options) || this; } /** * @param {function(Error, string[])} callback * @return {Promise|undefined} */ var _proto = DcentHookedWalletSubprovider.prototype; _proto.getAccounts = function getAccounts(callback) { if (!callback) { return getAccountsAsync(); } else { getAccountsAsync().then(function (accounts) { callback(null, accounts); })["catch"](function (e) { callback(e, null); }); } }; return DcentHookedWalletSubprovider; }(HookedWallet); var DcentConnector = /*#__PURE__*/function (_AbstractConnector) { _inheritsLoose(DcentConnector, _AbstractConnector); function DcentConnector(_ref) { var _this; var chainId = _ref.chainId, url = _ref.url, pollingInterval = _ref.pollingInterval, requestTimeoutMs = _ref.requestTimeoutMs; _this = _AbstractConnector.call(this, { supportedChainIds: [chainId] }) || this; _this.chainId = chainId; _this.url = url; _this.pollingInterval = pollingInterval; _this.requestTimeoutMs = requestTimeoutMs; return _this; } var _proto = DcentConnector.prototype; _proto.activate = function activate() { try { var _this3 = this; if (!_this3.provider) { var engine = new Web3ProviderEngine({ pollingInterval: _this3.pollingInterval }); engine.addProvider(new DcentHookedWalletSubprovider({ networkId: _this3.chainId })); engine.addProvider(new CacheSubprovider()); engine.addProvider(new rpc_subprovider.RPCSubprovider(_this3.url, _this3.requestTimeoutMs)); _this3.provider = engine; } _this3.provider.start(); return Promise.resolve({ provider: _this3.provider, chainId: _this3.chainId }); } catch (e) { return Promise.reject(e); } }; _proto.getProvider = function getProvider() { try { var _this5 = this; return Promise.resolve(_this5.provider); } catch (e) { return Promise.reject(e); } }; _proto.getChainId = function getChainId() { try { var _this7 = this; return Promise.resolve(_this7.chainId); } catch (e) { return Promise.reject(e); } }; _proto.getAccount = function getAccount() { try { var _this9 = this; return Promise.resolve(_this9.provider._providers[0].getAccounts().then(function (accounts) { return accounts[0]; })); } catch (e) { return Promise.reject(e); } }; _proto.deactivate = function deactivate() { this.provider.stop(); }; return DcentConnector; }(abstractConnector.AbstractConnector); exports.DcentConnector = DcentConnector; //# sourceMappingURL=web3-react-dcent-biometric-connector.cjs.development.js.map