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
JavaScript
;
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