truffle
Version:
Truffle - Simple development framework for Ethereum
1,654 lines (1,426 loc) • 53.6 kB
JavaScript
#!/usr/bin/env node
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ 72047:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
// Packages
var retrier = __webpack_require__(99353);
function retry(fn, opts) {
function run(resolve, reject) {
var options = opts || {};
var op;
// Default `randomize` to true
if (!('randomize' in options)) {
options.randomize = true;
}
op = retrier.operation(options);
// We allow the user to abort retrying
// this makes sense in the cases where
// knowledge is obtained that retrying
// would be futile (e.g.: auth errors)
function bail(err) {
reject(err || new Error('Aborted'));
}
function onError(err, num) {
if (err.bail) {
bail(err);
return;
}
if (!op.retry(err)) {
reject(op.mainError());
} else if (options.onRetry) {
options.onRetry(err, num);
}
}
function runAttempt(num) {
var val;
try {
val = fn(bail, num);
} catch (err) {
onError(err, num);
return;
}
Promise.resolve(val)
.then(resolve)
.catch(function catchIt(err) {
onError(err, num);
});
}
op.attempt(runAttempt);
}
return new Promise(run);
}
module.exports = retry;
/***/ }),
/***/ 18967:
/***/ ((module) => {
function webpackEmptyContext(req) {
var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND';
throw e;
}
webpackEmptyContext.keys = () => ([]);
webpackEmptyContext.resolve = webpackEmptyContext;
webpackEmptyContext.id = 18967;
module.exports = webpackEmptyContext;
/***/ }),
/***/ 57824:
/***/ ((module) => {
/**
* Helpers.
*/
var s = 1000;
var m = s * 60;
var h = m * 60;
var d = h * 24;
var w = d * 7;
var y = d * 365.25;
/**
* Parse or format the given `val`.
*
* Options:
*
* - `long` verbose formatting [false]
*
* @param {String|Number} val
* @param {Object} [options]
* @throws {Error} throw an error if val is not a non-empty string or a number
* @return {String|Number}
* @api public
*/
module.exports = function (val, options) {
options = options || {};
var type = typeof val;
if (type === 'string' && val.length > 0) {
return parse(val);
} else if (type === 'number' && isFinite(val)) {
return options.long ? fmtLong(val) : fmtShort(val);
}
throw new Error(
'val is not a non-empty string or a valid number. val=' +
JSON.stringify(val)
);
};
/**
* Parse the given `str` and return milliseconds.
*
* @param {String} str
* @return {Number}
* @api private
*/
function parse(str) {
str = String(str);
if (str.length > 100) {
return;
}
var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
str
);
if (!match) {
return;
}
var n = parseFloat(match[1]);
var type = (match[2] || 'ms').toLowerCase();
switch (type) {
case 'years':
case 'year':
case 'yrs':
case 'yr':
case 'y':
return n * y;
case 'weeks':
case 'week':
case 'w':
return n * w;
case 'days':
case 'day':
case 'd':
return n * d;
case 'hours':
case 'hour':
case 'hrs':
case 'hr':
case 'h':
return n * h;
case 'minutes':
case 'minute':
case 'mins':
case 'min':
case 'm':
return n * m;
case 'seconds':
case 'second':
case 'secs':
case 'sec':
case 's':
return n * s;
case 'milliseconds':
case 'millisecond':
case 'msecs':
case 'msec':
case 'ms':
return n;
default:
return undefined;
}
}
/**
* Short format for `ms`.
*
* @param {Number} ms
* @return {String}
* @api private
*/
function fmtShort(ms) {
var msAbs = Math.abs(ms);
if (msAbs >= d) {
return Math.round(ms / d) + 'd';
}
if (msAbs >= h) {
return Math.round(ms / h) + 'h';
}
if (msAbs >= m) {
return Math.round(ms / m) + 'm';
}
if (msAbs >= s) {
return Math.round(ms / s) + 's';
}
return ms + 'ms';
}
/**
* Long format for `ms`.
*
* @param {Number} ms
* @return {String}
* @api private
*/
function fmtLong(ms) {
var msAbs = Math.abs(ms);
if (msAbs >= d) {
return plural(ms, msAbs, d, 'day');
}
if (msAbs >= h) {
return plural(ms, msAbs, h, 'hour');
}
if (msAbs >= m) {
return plural(ms, msAbs, m, 'minute');
}
if (msAbs >= s) {
return plural(ms, msAbs, s, 'second');
}
return ms + ' ms';
}
/**
* Pluralization helper.
*/
function plural(ms, msAbs, n, name) {
var isPlural = msAbs >= n * 1.5;
return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
}
/***/ }),
/***/ 99353:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = __webpack_require__(71846);
/***/ }),
/***/ 71846:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
var RetryOperation = __webpack_require__(41960);
exports.operation = function(options) {
var timeouts = exports.timeouts(options);
return new RetryOperation(timeouts, {
forever: options && (options.forever || options.retries === Infinity),
unref: options && options.unref,
maxRetryTime: options && options.maxRetryTime
});
};
exports.timeouts = function(options) {
if (options instanceof Array) {
return [].concat(options);
}
var opts = {
retries: 10,
factor: 2,
minTimeout: 1 * 1000,
maxTimeout: Infinity,
randomize: false
};
for (var key in options) {
opts[key] = options[key];
}
if (opts.minTimeout > opts.maxTimeout) {
throw new Error('minTimeout is greater than maxTimeout');
}
var timeouts = [];
for (var i = 0; i < opts.retries; i++) {
timeouts.push(this.createTimeout(i, opts));
}
if (options && options.forever && !timeouts.length) {
timeouts.push(this.createTimeout(i, opts));
}
// sort the array numerically ascending
timeouts.sort(function(a,b) {
return a - b;
});
return timeouts;
};
exports.createTimeout = function(attempt, opts) {
var random = (opts.randomize)
? (Math.random() + 1)
: 1;
var timeout = Math.round(random * Math.max(opts.minTimeout, 1) * Math.pow(opts.factor, attempt));
timeout = Math.min(timeout, opts.maxTimeout);
return timeout;
};
exports.wrap = function(obj, options, methods) {
if (options instanceof Array) {
methods = options;
options = null;
}
if (!methods) {
methods = [];
for (var key in obj) {
if (typeof obj[key] === 'function') {
methods.push(key);
}
}
}
for (var i = 0; i < methods.length; i++) {
var method = methods[i];
var original = obj[method];
obj[method] = function retryWrapper(original) {
var op = exports.operation(options);
var args = Array.prototype.slice.call(arguments, 1);
var callback = args.pop();
args.push(function(err) {
if (op.retry(err)) {
return;
}
if (err) {
arguments[0] = op.mainError();
}
callback.apply(this, arguments);
});
op.attempt(function() {
original.apply(obj, args);
});
}.bind(obj, original);
obj[method].options = options;
}
};
/***/ }),
/***/ 41960:
/***/ ((module) => {
function RetryOperation(timeouts, options) {
// Compatibility for the old (timeouts, retryForever) signature
if (typeof options === 'boolean') {
options = { forever: options };
}
this._originalTimeouts = JSON.parse(JSON.stringify(timeouts));
this._timeouts = timeouts;
this._options = options || {};
this._maxRetryTime = options && options.maxRetryTime || Infinity;
this._fn = null;
this._errors = [];
this._attempts = 1;
this._operationTimeout = null;
this._operationTimeoutCb = null;
this._timeout = null;
this._operationStart = null;
this._timer = null;
if (this._options.forever) {
this._cachedTimeouts = this._timeouts.slice(0);
}
}
module.exports = RetryOperation;
RetryOperation.prototype.reset = function() {
this._attempts = 1;
this._timeouts = this._originalTimeouts.slice(0);
}
RetryOperation.prototype.stop = function() {
if (this._timeout) {
clearTimeout(this._timeout);
}
if (this._timer) {
clearTimeout(this._timer);
}
this._timeouts = [];
this._cachedTimeouts = null;
};
RetryOperation.prototype.retry = function(err) {
if (this._timeout) {
clearTimeout(this._timeout);
}
if (!err) {
return false;
}
var currentTime = new Date().getTime();
if (err && currentTime - this._operationStart >= this._maxRetryTime) {
this._errors.push(err);
this._errors.unshift(new Error('RetryOperation timeout occurred'));
return false;
}
this._errors.push(err);
var timeout = this._timeouts.shift();
if (timeout === undefined) {
if (this._cachedTimeouts) {
// retry forever, only keep last error
this._errors.splice(0, this._errors.length - 1);
timeout = this._cachedTimeouts.slice(-1);
} else {
return false;
}
}
var self = this;
this._timer = setTimeout(function() {
self._attempts++;
if (self._operationTimeoutCb) {
self._timeout = setTimeout(function() {
self._operationTimeoutCb(self._attempts);
}, self._operationTimeout);
if (self._options.unref) {
self._timeout.unref();
}
}
self._fn(self._attempts);
}, timeout);
if (this._options.unref) {
this._timer.unref();
}
return true;
};
RetryOperation.prototype.attempt = function(fn, timeoutOps) {
this._fn = fn;
if (timeoutOps) {
if (timeoutOps.timeout) {
this._operationTimeout = timeoutOps.timeout;
}
if (timeoutOps.cb) {
this._operationTimeoutCb = timeoutOps.cb;
}
}
var self = this;
if (this._operationTimeoutCb) {
this._timeout = setTimeout(function() {
self._operationTimeoutCb();
}, self._operationTimeout);
}
this._operationStart = new Date().getTime();
this._fn(this._attempts);
};
RetryOperation.prototype.try = function(fn) {
console.log('Using RetryOperation.try() is deprecated');
this.attempt(fn);
};
RetryOperation.prototype.start = function(fn) {
console.log('Using RetryOperation.start() is deprecated');
this.attempt(fn);
};
RetryOperation.prototype.start = RetryOperation.prototype.try;
RetryOperation.prototype.errors = function() {
return this._errors;
};
RetryOperation.prototype.attempts = function() {
return this._attempts;
};
RetryOperation.prototype.mainError = function() {
if (this._errors.length === 0) {
return null;
}
var counts = {};
var mainError = null;
var mainErrorCount = 0;
for (var i = 0; i < this._errors.length; i++) {
var error = this._errors[i];
var message = error.message;
var count = (counts[message] || 0) + 1;
counts[message] = count;
if (count >= mainErrorCount) {
mainError = error;
mainErrorCount = count;
}
}
return mainError;
};
/***/ }),
/***/ 59602:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = {
run: __webpack_require__(44556),
meta: __webpack_require__(99608)
};
/***/ }),
/***/ 99608:
/***/ ((module) => {
module.exports = {
command: "dashboard",
description:
"Start Truffle Dashboard to sign development transactions using browser wallet",
builder: {
"port": {
describe: "Specify the port to start the dashboard and RPC endpoint on",
type: "number"
},
"host": {
describe: "Specify the host to start the dashboard and RPC endpoint on",
type: "string"
},
"no-auto-open": {
describe: "Disable opening dashboard in default browser on start",
type: "boolean"
},
"verbose": {
describe: "Display debug logs for the dashboard server and message bus",
type: "boolean"
}
},
help: {
usage: "truffle dashboard [--port <number>] [--host <string>] [--verbose]",
options: [
{
option: "--port <number>",
description: "Start the dashboard and RPC endpoint on a specific port."
},
{
option: "--host <string>",
description: "Start the dashboard and RPC endpoint on a specific host."
},
{
option: "--no-auto-open",
description: "Disable opening dashboard in default browser on start"
},
{
option: "--verbose",
description:
"Log debug information from the Dashboard server and message bus."
}
],
allowedGlobalOptions: []
}
};
/***/ }),
/***/ 44556:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = async function (options) {
const { detectConfigOrDefault } = __webpack_require__(54708);
const { DashboardServer } = __webpack_require__(97722);
const address = __webpack_require__(94849);
const config = detectConfigOrDefault(options);
const port = options.port || config.dashboard.port;
const host = options.host || config.dashboard.host;
const autoOpen = options.autoOpen ?? config.dashboard.autoOpen;
const verbose = options.verbose || config.dashboard.verbose;
const rpc = true;
const dashboardServerOptions = { port, host, autoOpen, verbose, rpc };
const dashboardServer = new DashboardServer(dashboardServerOptions);
await dashboardServer.start();
if (host === "0.0.0.0") {
// Regex taken from react-scripts to check that the address is a private IP, otherwise we discard it
// https://en.wikipedia.org/wiki/Private_network#Private_IPv4_address_spaces
let lanAddress =
/^10[.]|^172[.](1[6-9]|2[0-9]|3[0-1])[.]|^192[.]168[.]/.test(address.ip())
? address.ip()
: undefined;
console.log(`Truffle Dashboard running at http://localhost:${port}`);
lanAddress &&
console.log(` http://${lanAddress}:${port}`);
console.log(
`DashboardProvider RPC endpoint running at http://localhost:${port}/rpc`
);
lanAddress &&
console.log(
` http://${lanAddress}:${port}/rpc`
);
} else {
console.log(`Truffle Dashboard running at http://${host}:${port}`);
console.log(
`DashboardProvider RPC endpoint running at http://${host}:${port}/rpc`
);
}
// ensure that `await`-ing this method never resolves. (we want to keep
// the console open until it exits on its own)
return new Promise(() => {});
};
/***/ }),
/***/ 54708:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
// Extracts the input flags --option & -option from the arguments of type `--option=value` or `--option value` or `--flag` or -flag
const extractFlags = inputArguments => {
// Get all the args that begins with `--`. This also includes `--option=value`
const inputFlags = inputArguments.filter(flag => {
return flag.startsWith("--") || flag.startsWith("-") ? flag : null;
});
// Extract only the flags i.e `--option` from `--option=value`
inputFlags.map((flag, i) => {
let indexOfEqualsSign = flag.indexOf("=");
if (indexOfEqualsSign > 0) {
flag = flag.slice(0, indexOfEqualsSign);
inputFlags.splice(i, 1, flag);
}
});
return inputFlags;
};
const detectConfigOrDefault = options => {
const Config = __webpack_require__(20553);
try {
return Config.detect(options);
} catch (error) {
// Suppress error when truffle can't find a config
if (error.message === "Could not find suitable configuration file.") {
return Config.default();
} else {
throw error;
}
}
};
module.exports = { extractFlags, detectConfigOrDefault };
/***/ }),
/***/ 96524:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
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) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.DashboardMessageBus = void 0;
const events_1 = __webpack_require__(82361);
const dashboard_message_bus_common_1 = __webpack_require__(75756);
const utils_1 = __webpack_require__(44794);
const util_1 = __webpack_require__(73837);
class DashboardMessageBus extends events_1.EventEmitter {
constructor(publishPort, subscribePort, host = "localhost") {
super();
this.publishPort = publishPort;
this.subscribePort = subscribePort;
this.host = host;
this.publishers = [];
this.subscribers = [];
this.unfulfilledRequests = new Map([]);
this.resetReadyState();
}
/**
* Start the DashboardMessageBus
* @dev This starts separate websocket servers for subscribers/publishers
*/
start() {
return __awaiter(this, void 0, void 0, function* () {
this.subscribeServer = yield (0, utils_1.startWebSocketServer)({
host: this.host,
port: this.subscribePort
});
this.subscribeServer.on("connection", (newSubscriber) => {
newSubscriber.once("close", () => {
this.removeSubscriber(newSubscriber);
});
// Require the subscriber to send a message *first* before being added
newSubscriber.once("message", () => this.addSubscriber(newSubscriber));
});
this.publishServer = yield (0, utils_1.startWebSocketServer)({
host: this.host,
port: this.publishPort
});
this.publishServer.on("connection", (newPublisher) => {
newPublisher.once("close", () => {
this.removePublisher(newPublisher);
});
this.addPublisher(newPublisher);
});
});
}
/**
* A promise that resolves when the message bus is ready to process requests
* (i.e. having any subscribers).
*/
get ready() {
return this.readyPromise;
}
/**
* Close both websocket servers
* @dev Emits a "terminate" event
*/
terminate() {
return __awaiter(this, void 0, void 0, function* () {
yield (0, util_1.promisify)(this.publishServer.close.bind(this.publishServer))();
yield (0, util_1.promisify)(this.subscribeServer.close.bind(this.subscribeServer))();
this.emit("terminate");
});
}
/**
* Process a message `data` coming from `publisher` by sending it to `subscribers`
* and return the first received response to the `publisher`
*/
processRequest(publisher, data, subscribers) {
return __awaiter(this, void 0, void 0, function* () {
// convert to string for uniformity since WebSocket.Data can take other forms
if (typeof data !== "string") {
data = data.toString();
}
yield this.ready;
this.unfulfilledRequests.set(data, { publisher, data });
const message = (0, dashboard_message_bus_common_1.base64ToJson)(data);
try {
this.logToPublishers(`Sending message to ${subscribers.length} subscribers`, "requests");
this.logToPublishers(message, "requests");
const response = yield (0, utils_1.broadcastAndAwaitFirst)(subscribers, message);
this.logToPublishers(`Sending response for message ${message.id}`, "responses");
this.logToPublishers(response, "responses");
const encodedResponse = (0, dashboard_message_bus_common_1.jsonToBase64)(response);
publisher.send(encodedResponse);
this.unfulfilledRequests.delete(data);
this.invalidateMessage(message.id);
}
catch (error) {
this.logToPublishers(`An error occurred while processing message ${message.id}`, "errors");
this.logToPublishers(error, "errors");
}
});
}
invalidateMessage(id) {
const invalidationMessage = (0, dashboard_message_bus_common_1.createMessage)("invalidate", id);
(0, utils_1.broadcastAndDisregard)(this.subscribers, invalidationMessage);
}
logToPublishers(logMessage, namespace) {
this.logTo(logMessage, this.publishers, namespace);
}
logToSubscribers(logMessage, namespace) {
this.logTo(logMessage, this.subscribers, namespace);
}
logToAll(logMessage, namespace) {
this.logToPublishers(logMessage, namespace);
this.logToSubscribers(logMessage, namespace);
}
logTo(logMessage, receivers, namespace) {
const payload = {
namespace: "dashboard-message-bus",
message: logMessage
};
if (namespace) {
payload.namespace += `:${namespace}`;
}
const message = (0, dashboard_message_bus_common_1.createMessage)("log", payload);
(0, utils_1.broadcastAndDisregard)(receivers, message);
}
/**
* Add a publisher so it can be used to send requests to
* @dev Also sends all backlogged (unfulfilled) requests upon connection
*/
addSubscriber(newSubscriber) {
this.unfulfilledRequests.forEach(({ publisher, data }) => this.processRequest(publisher, data, [newSubscriber]));
this.logToPublishers("Subscriber connected", "connections");
this.subscribers.push(newSubscriber);
if (this.subscribers.length == 1) {
this.resolveReadyPromise();
}
}
/**
* Remove a subscriber
* @dev Will cause the server to terminate if this was the last connection
*/
removeSubscriber(subscriberToRemove) {
this.logToPublishers("Subscriber disconnected", "connections");
this.subscribers = this.subscribers.filter(subscriber => subscriber !== subscriberToRemove);
if (this.subscribers.length === 0) {
this.resetReadyState();
}
this.terminateIfNoConnections();
}
/**
* Add a publisher and set up message listeners to process their requests
*/
addPublisher(newPublisher) {
this.logToPublishers("Publisher connected", "connections");
newPublisher.on("message", (data) => {
this.processRequest(newPublisher, data, this.subscribers);
});
this.publishers.push(newPublisher);
}
/**
* Remove a publisher and their corresponding requests
* @dev Will cause the server to terminate if this was the last connection
*/
removePublisher(publisherToRemove) {
this.logToPublishers("Publisher disconnected", "connections");
this.publishers = this.publishers.filter(publisher => publisher !== publisherToRemove);
this.clearRequestsForPublisher(publisherToRemove);
this.terminateIfNoConnections();
}
terminateIfNoConnections() {
if (this.publishers.length === 0 && this.subscribers.length === 0) {
this.terminate();
}
}
clearRequestsForPublisher(publisher) {
this.unfulfilledRequests.forEach(({ publisher: requestPublisher }, key) => {
if (requestPublisher === publisher) {
this.unfulfilledRequests.delete(key);
}
});
}
resetReadyState() {
this.readyPromise = new Promise((resolve => {
this.resolveReadyPromise = resolve;
}).bind(this));
}
}
exports.DashboardMessageBus = DashboardMessageBus;
//# sourceMappingURL=DashboardMessageBus.js.map
/***/ }),
/***/ 37108:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
__exportStar(__webpack_require__(96524), exports);
//# sourceMappingURL=index.js.map
/***/ }),
/***/ 44794:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
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) : adopt(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 }));
exports.sendAndAwait = exports.broadcastAndAwaitFirst = exports.broadcastAndDisregard = exports.startWebSocketServer = void 0;
const isomorphic_ws_1 = __importDefault(__webpack_require__(47030));
const dashboard_message_bus_common_1 = __webpack_require__(75756);
const promise_any_1 = __importDefault(__webpack_require__(25795));
promise_any_1.default.shim();
/**
* Starts a websocket server and waits for it to be opened
* @dev If you need to attach event listeners *before* the server connection opens,
* do not use this function since it resolves *after* the connection is opened
*/
const startWebSocketServer = (options) => {
return new Promise(resolve => {
const server = new isomorphic_ws_1.default.Server(options, () => {
resolve(server);
});
});
};
exports.startWebSocketServer = startWebSocketServer;
/**
* Broadcast a message to multiple websocket connections and disregard them
*/
const broadcastAndDisregard = (sockets, message) => {
const encodedMessage = (0, dashboard_message_bus_common_1.jsonToBase64)(message);
sockets.forEach(socket => {
socket.send(encodedMessage);
});
};
exports.broadcastAndDisregard = broadcastAndDisregard;
/**
* Broadcast a message to multuple websocket connections and return the first response
*/
const broadcastAndAwaitFirst = (sockets, message) => __awaiter(void 0, void 0, void 0, function* () {
const promises = sockets.map(socket => (0, exports.sendAndAwait)(socket, message));
const result = yield Promise.any(promises);
return result;
});
exports.broadcastAndAwaitFirst = broadcastAndAwaitFirst;
/**
* Send a message to a websocket connection and await a matching response
* @dev Responses are matched by looking at received messages that match the ID of the sent message
*/
const sendAndAwait = (socket, message) => {
return new Promise((resolve, reject) => {
socket.addEventListener("message", (event) => {
if (typeof event.data !== "string") {
event.data = event.data.toString();
}
const response = (0, dashboard_message_bus_common_1.base64ToJson)(event.data);
if (response.id !== message.id)
return;
resolve(response);
});
// TODO: Need to check that the error corresponds to the sent message?
socket.addEventListener("error", (event) => {
reject(event.error);
});
socket.addEventListener("close", (event) => {
reject(new Error(`Socket connection closed with code '${event.code}' and reason '${event.reason}'`));
});
const encodedMessage = (0, dashboard_message_bus_common_1.jsonToBase64)(message);
socket.send(encodedMessage);
});
};
exports.sendAndAwait = sendAndAwait;
//# sourceMappingURL=utils.js.map
/***/ }),
/***/ 66205:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
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) : adopt(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 }));
exports.DashboardServer = void 0;
const express_1 = __importDefault(__webpack_require__(99268));
const path_1 = __importDefault(__webpack_require__(71017));
const get_port_1 = __importDefault(__webpack_require__(15959));
const open_1 = __importDefault(__webpack_require__(78318));
const uuid_1 = __webpack_require__(88882);
const fetch_and_compile_1 = __webpack_require__(5523);
const object_hash_1 = __webpack_require__(49807);
const config_1 = __importDefault(__webpack_require__(20553));
const dashboard_message_bus_common_1 = __webpack_require__(75756);
const dashboard_message_bus_1 = __webpack_require__(37108);
const dashboard_message_bus_client_1 = __webpack_require__(19602);
const cors_1 = __importDefault(__webpack_require__(17846));
const debug_1 = __importDefault(__webpack_require__(15158));
class DashboardServer {
get subscribePort() {
var _a;
return (_a = this.messageBus) === null || _a === void 0 ? void 0 : _a.subscribePort;
}
get publishPort() {
var _a;
return (_a = this.messageBus) === null || _a === void 0 ? void 0 : _a.subscribePort;
}
constructor(options) {
var _a, _b, _c, _d;
this.host = (_a = options.host) !== null && _a !== void 0 ? _a : "localhost";
this.port = options.port;
this.configPublishPort = options.publishPort;
this.configSubscribePort = options.subscribePort;
this.rpc = (_b = options.rpc) !== null && _b !== void 0 ? _b : true;
this.verbose = (_c = options.verbose) !== null && _c !== void 0 ? _c : false;
this.autoOpen = (_d = options.autoOpen) !== null && _d !== void 0 ? _d : true;
this.frontendPath = path_1.default.join(__dirname, "dashboard-frontend");
this.boundTerminateListener = () => this.stop();
}
start() {
var _a;
return __awaiter(this, void 0, void 0, function* () {
if ((_a = this.httpServer) === null || _a === void 0 ? void 0 : _a.listening) {
return;
}
this.messageBus = yield this.startMessageBus();
this.expressApp = (0, express_1.default)();
this.expressApp.use((0, cors_1.default)());
this.expressApp.use(express_1.default.json());
this.expressApp.get("/ports", this.getPorts.bind(this));
if (this.rpc) {
yield this.connectToMessageBus();
this.expressApp.post("/rpc", this.postRpc.bind(this));
}
this.expressApp.get("/fetch-and-compile", (req, res) => __awaiter(this, void 0, void 0, function* () {
const { address, networkId, etherscanApiKey } = req.query;
let config;
try {
config = config_1.default.detect();
// we'll ignore errors as we only get the config for the api key
}
catch (_b) { }
// a key provided in the browser takes precedence over on in the config
let etherscanKey;
if (etherscanApiKey) {
etherscanKey = etherscanApiKey;
}
else if (config && config.etherscan !== undefined) {
etherscanKey = config.etherscan.apiKey;
}
config = config_1.default.default().merge({
networks: {
custom: { network_id: networkId }
},
network: "custom",
etherscan: {
apiKey: etherscanKey
}
});
let result;
try {
result = (yield (0, fetch_and_compile_1.fetchAndCompile)(address, config)).compileResult;
}
catch (error) {
if (!error.message.includes("No verified sources")) {
throw error;
}
}
if (result) {
// we calculate hashes on the server because it is at times too
// resource intensive for the browser and causes it to crash
const hashes = result.compilations.map((compilation) => {
return (0, object_hash_1.sha1)(compilation);
});
res.json({
hashes,
compilations: result.compilations
});
}
else {
res.json({ compilations: [] });
}
}));
this.expressApp.get("/analytics", (_req, res) => {
const userConfig = config_1.default.getUserConfig();
res.json({
enableAnalytics: userConfig.get("enableAnalytics"),
analyticsSet: userConfig.get("analyticsSet"),
analyticsMessageDateTime: userConfig.get("analyticsMessageDateTime")
});
});
this.expressApp.put("/analytics", (req, _res) => {
const { value } = req.body;
const userConfig = config_1.default.getUserConfig();
const uid = userConfig.get("uniqueId");
if (!uid)
userConfig.set("uniqueId", (0, uuid_1.v4)());
userConfig.set({
enableAnalytics: !!value,
analyticsSet: true,
analyticsMessageDateTime: Date.now()
});
});
this.expressApp.use(express_1.default.static(this.frontendPath));
this.expressApp.get("*", (_req, res) => {
res.sendFile("index.html", { root: this.frontendPath });
});
yield new Promise(resolve => {
this.httpServer = this.expressApp.listen(this.port, this.host, () => {
if (this.autoOpen) {
const host = this.host === "0.0.0.0" ? "localhost" : this.host;
(0, open_1.default)(`http://${host}:${this.port}`);
}
resolve();
});
});
});
}
stop() {
var _a, _b, _c;
return __awaiter(this, void 0, void 0, function* () {
(_a = this.messageBus) === null || _a === void 0 ? void 0 : _a.off("terminate", this.boundTerminateListener);
yield Promise.all([
(_b = this.client) === null || _b === void 0 ? void 0 : _b.close(),
(_c = this.messageBus) === null || _c === void 0 ? void 0 : _c.terminate(),
new Promise(resolve => {
var _a;
(_a = this.httpServer) === null || _a === void 0 ? void 0 : _a.close(() => resolve());
})
]);
delete this.client;
});
}
getPorts(req, res) {
if (!this.messageBus) {
throw new Error("Message bus has not been started yet");
}
res.json({
dashboardPort: this.port,
subscribePort: this.messageBus.subscribePort,
publishPort: this.messageBus.publishPort
});
}
postRpc(req, res, next) {
if (!this.client) {
throw new Error("Not connected to message bus");
}
this.client
.publish({ type: dashboard_message_bus_common_1.dashboardProviderMessageType, payload: req.body })
.then(lifecycle => lifecycle.response)
.then(response => res.json(response === null || response === void 0 ? void 0 : response.payload))
.catch(next);
}
startMessageBus() {
var _a, _b;
return __awaiter(this, void 0, void 0, function* () {
const subscribePort = (_a = this.configSubscribePort) !== null && _a !== void 0 ? _a : (yield (0, get_port_1.default)({ host: this.host }));
const publishPort = (_b = this.configPublishPort) !== null && _b !== void 0 ? _b : (yield (0, get_port_1.default)({ host: this.host }));
const messageBus = new dashboard_message_bus_1.DashboardMessageBus(publishPort, subscribePort, this.host);
yield messageBus.start();
messageBus.on("terminate", this.boundTerminateListener);
return messageBus;
});
}
connectToMessageBus() {
return __awaiter(this, void 0, void 0, function* () {
if (!this.messageBus) {
throw new Error("Message bus has not been started yet");
}
if (this.client) {
return;
}
this.client = new dashboard_message_bus_client_1.DashboardMessageBusClient({
host: this.host,
subscribePort: this.messageBus.subscribePort,
publishPort: this.messageBus.publishPort
});
yield this.client.ready();
// the promise returned by `setupVerboseLogging` never resolves, so don't
// bother awaiting it.
this.setupVerboseLogging();
});
}
setupVerboseLogging() {
return __awaiter(this, void 0, void 0, function* () {
if (this.verbose && this.client) {
this.client
.subscribe({ type: dashboard_message_bus_common_1.logMessageType })
.on("message", lifecycle => {
if (lifecycle && lifecycle.message.type === "log") {
const logMessage = lifecycle.message;
const debug = (0, debug_1.default)(logMessage.payload.namespace);
debug.enabled = true;
debug(logMessage.payload.message);
}
});
}
});
}
}
exports.DashboardServer = DashboardServer;
//# sourceMappingURL=DashboardServer.js.map
/***/ }),
/***/ 97722:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
__exportStar(__webpack_require__(66205), exports);
__exportStar(__webpack_require__(32550), exports);
//# sourceMappingURL=index.js.map
/***/ }),
/***/ 32550:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.startDashboardInBackground = void 0;
const dashboard_message_bus_common_1 = __webpack_require__(75756);
const child_process_1 = __webpack_require__(32081);
const path_1 = __importDefault(__webpack_require__(71017));
const startDashboardInBackground = (options) => {
const dashboardPath = path_1.default.join(__dirname, "..", "bin", "start-dashboard");
const optionsBase64 = (0, dashboard_message_bus_common_1.jsonToBase64)(options);
const child = (0, child_process_1.spawn)("node", [dashboardPath, optionsBase64], {
detached: true,
stdio: "ignore"
});
return child;
};
exports.startDashboardInBackground = startDashboardInBackground;
//# sourceMappingURL=utils.js.map
/***/ }),
/***/ 44516:
/***/ ((module) => {
"use strict";
module.exports = require("original-require");
/***/ }),
/***/ 39491:
/***/ ((module) => {
"use strict";
module.exports = require("assert");
/***/ }),
/***/ 50852:
/***/ ((module) => {
"use strict";
module.exports = require("async_hooks");
/***/ }),
/***/ 14300:
/***/ ((module) => {
"use strict";
module.exports = require("buffer");
/***/ }),
/***/ 32081:
/***/ ((module) => {
"use strict";
module.exports = require("child_process");
/***/ }),
/***/ 22057:
/***/ ((module) => {
"use strict";
module.exports = require("constants");
/***/ }),
/***/ 6113:
/***/ ((module) => {
"use strict";
module.exports = require("crypto");
/***/ }),
/***/ 82361:
/***/ ((module) => {
"use strict";
module.exports = require("events");
/***/ }),
/***/ 57147:
/***/ ((module) => {
"use strict";
module.exports = require("fs");
/***/ }),
/***/ 73292:
/***/ ((module) => {
"use strict";
module.exports = require("fs/promises");
/***/ }),
/***/ 13685:
/***/ ((module) => {
"use strict";
module.exports = require("http");
/***/ }),
/***/ 95687:
/***/ ((module) => {
"use strict";
module.exports = require("https");
/***/ }),
/***/ 98188:
/***/ ((module) => {
"use strict";
module.exports = require("module");
/***/ }),
/***/ 41808:
/***/ ((module) => {
"use strict";
module.exports = require("net");
/***/ }),
/***/ 22037:
/***/ ((module) => {
"use strict";
module.exports = require("os");
/***/ }),
/***/ 71017:
/***/ ((module) => {
"use strict";
module.exports = require("path");
/***/ }),
/***/ 85477:
/***/ ((module) => {
"use strict";
module.exports = require("punycode");
/***/ }),
/***/ 63477:
/***/ ((module) => {
"use strict";
module.exports = require("querystring");
/***/ }),
/***/ 14521:
/***/ ((module) => {
"use strict";
module.exports = require("readline");
/***/ }),
/***/ 12781:
/***/ ((module) => {
"use strict";
module.exports = require("stream");
/***/ }),
/***/ 71576:
/***/ ((module) => {
"use strict";
module.exports = require("string_decoder");
/***/ }),
/***/ 39512:
/***/ ((module) => {
"use strict";
module.exports = require("timers");
/***/ }),
/***/ 24404:
/***/ ((module) => {
"use strict";
module.exports = require("tls");
/***/ }),
/***/ 76224:
/***/ ((module) => {
"use strict";
module.exports = require("tty");
/***/ }),
/***/ 57310:
/***/ ((module) => {
"use strict";
module.exports = require("url");
/***/ }),
/***/ 73837:
/***/ ((module) => {
"use strict";
module.exports = require("util");
/***/ }),
/***/ 59796:
/***/ ((module) => {
"use strict";
module.exports = require("zlib");
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ id: moduleId,
/******/ loaded: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = __webpack_modules__;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = __webpack_module_cache__;
/******/
/******/ // the startup function
/******/ __webpack_require__.x = () => {
/******/ // Load entry module and return exports
/******/ var __webpack_exports__ = __webpack_require__.O(undefined, [5158,9129,6127,5674,6674,439,7657,4914,794,4957,8299,553,4273,102,5523], () => (__webpack_require__(59602)))
/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__);
/******/ return __webpack_exports__;
/******/ };
/******/
/************************************************************************/
/******/ /* webpack/runtime/amd options */
/******/ (() => {
/******/ __webpack_require__.amdO = {};
/******/ })();
/******/
/******/ /* webpack/runtime/chunk loaded */
/******/ (() => {
/******/ var deferred = [];
/******/ __webpack_require__.O = (result, chunkIds, fn, priority) => {
/******/ if(chunkIds) {
/******/ priority = priority || 0;
/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];
/******/ deferred[i] = [chunkIds, fn, priority];
/******/ return;
/******/ }
/******/ var notFulfilled = Infinity;
/******/ for (var i = 0; i < deferred.length; i++) {
/******/ var [chunkIds, fn, priority] = deferred[i];
/******/ var fulfilled = true;
/******/ for (var j = 0; j < chunkIds.length; j++) {
/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {
/******/ chunkIds.splice(j--, 1);
/******/ } else {
/******/ fulfilled = false;
/******/ if(priority < notFulfilled) notFulfilled = priority;
/******/ }
/******/ }
/******/ if(fulfilled) {
/******/ deferred.splice(i--, 1)
/******/ var r = fn();
/******/ if (r !== undefined) result = r;
/******/ }
/******/ }
/******/ return result;
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/compat get default export */
/******/ (() => {
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = (module) => {
/******/ var getter = module && module.__esModule ?
/******/ () => (module['default']) :
/******/ () => (module);
/******/ __webpack_require__.d(getter, { a: getter });
/******/ return getter;
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/ensure chunk */
/******/ (() => {
/******/ __webpack_require__.f = {};
/******/ // This file contains only the entry chunk.
/******/ // The chunk loading function for additional chunks
/******/ __webpack_require__.e = (chunkId) => {
/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
/******/ __webpack_require__.f[key](chunkId, promises);
/******/ return promises;
/******/ }, []));
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/get javascript chunk filename */
/******/ (() => {
/******/ // This function allow to reference async chunks and sibling chunks for the entrypoint
/******/ __webpack_require__.u = (chunkId) => {
/******/ // return url for filenames based on template
/******/ return "" + chunkId + ".bundled.js";
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/