UNPKG

openzeppelin-network-test

Version:

An easy to use and reliable library that provides one line access to Web3 API.

123 lines 6.34 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fast_deep_equal_1 = __importDefault(require("fast-deep-equal")); const web3_1 = __importDefault(require("web3")); const events_1 = require("events"); const timeout_1 = __importDefault(require("../util/timeout")); const gsn_provider_1 = require("@openzeppelin/gsn-provider"); const network_1 = __importDefault(require("../util/network")); const providerName_1 = __importDefault(require("../util/providerName")); // TODO: Change event to use types using conditional types class Web3Context extends events_1.EventEmitter { constructor(provider, options) { super(); this.connected = false; this.accounts = []; this.networkId = null; this.networkName = null; const fullOptions = Object.assign({}, { timeout: 3000, pollInterval: 500, gsn: false }, options); if (!provider) throw new Error('A web3 provider has to be defined'); if (fullOptions.gsn) { const gsnOptions = typeof fullOptions.gsn === 'object' ? fullOptions.gsn : { useGSN: true }; provider = !gsnOptions.dev ? new gsn_provider_1.GSNProvider(provider, gsnOptions) : new gsn_provider_1.GSNDevProvider(provider, gsnOptions); } this.providerName = providerName_1.default(provider); this.lib = new web3_1.default(provider); this.timeout = fullOptions.timeout; this.pollInterval = fullOptions.pollInterval; } startPoll() { if (!this.pollHandle) { // TODO: polling interval should depend on kind of web3 provider // We can query local providers often but doing the same for the network providers may create a lot of overhead this.pollHandle = setTimeout(this.poll.bind(this), this.pollInterval); } } stopPoll() { if (this.pollHandle) { clearTimeout(this.pollHandle); this.pollHandle = undefined; } } poll() { return __awaiter(this, void 0, void 0, function* () { // TODO: Fiture out elegant way retrive property name dynamically const networkIdName = 'networkId'; const accountsName = 'accounts'; const connectedName = 'connected'; // getting deep here const networkNameName = 'networkName'; try { // get the current network ID const newNetworkId = yield timeout_1.default(this.lib.eth.net.getId(), this.timeout); const newNetworkName = network_1.default(newNetworkId); this.updateValueAndFireEvent(newNetworkName, networkNameName); this.updateValueAndFireEvent(newNetworkId, networkIdName, Web3Context.NetworkIdChangedEventName, () => [newNetworkName]); // get the accounts const newAccounts = yield timeout_1.default(this.lib.eth.getAccounts(), this.timeout); this.updateValueAndFireEvent(newAccounts, accountsName, Web3Context.AccountsChangedEventName); // if web3 provider calls are success then we are connected this.updateValueAndFireEvent(true, connectedName, Web3Context.ConnectionChangedEventName); } catch (e) { // provider methods fail so we have to update the state and fire the events this.updateValueAndFireEvent(false, connectedName, Web3Context.ConnectionChangedEventName); this.updateValueAndFireEvent(null, networkIdName, Web3Context.NetworkIdChangedEventName, () => [null]); this.updateValueAndFireEvent(null, networkNameName); this.updateValueAndFireEvent(null, accountsName, Web3Context.AccountsChangedEventName); // TODO: Implement throtling so we do not spam console // console.log(e); } finally { this.pollHandle = setTimeout(this.poll.bind(this), this.pollInterval); } }); } updateValueAndFireEvent(newValue, property, eventName, getArgs = () => []) { if (!fast_deep_equal_1.default(newValue, this[property])) { this[property] = newValue; if (eventName) this.emit(eventName, this[property], ...getArgs()); } } // request access according to the EIP // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1102.md requestAuth() { return __awaiter(this, void 0, void 0, function* () { // Request authentication if (this.lib.currentProvider.send !== undefined) { return new Promise((resolve, reject) => { const responseHandler = (error, response) => { if (error || response.error) { reject(error || response.error); } else { resolve(response.result); } }; const send = this.lib.currentProvider.send; send({ method: 'eth_requestAccounts' }, responseHandler); }); } else return Promise.reject(new Error("Web3 provider doesn't support send method")); }); } } Web3Context.NetworkIdChangedEventName = 'NetworkIdChanged'; Web3Context.AccountsChangedEventName = 'AccountsChanged'; Web3Context.ConnectionChangedEventName = 'ConnectionChanged'; exports.default = Web3Context; //# sourceMappingURL=Web3Context.js.map