openzeppelin-network-test
Version:
An easy to use and reliable library that provides one line access to Web3 API.
123 lines • 6.34 kB
JavaScript
"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