truffle
Version:
Truffle - Simple development framework for Ethereum
1,224 lines (1,175 loc) • 57.4 kB
JavaScript
#!/usr/bin/env node
"use strict";
exports.id = 5523;
exports.ids = [5523];
exports.modules = {
/***/ 87440:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
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.DebugRecognizer = void 0;
const debug_1 = __importDefault(__webpack_require__(15158));
const debug = (0, debug_1.default)("fetch-and-compile:debug");
const Codec = __importStar(__webpack_require__(20102));
class DebugRecognizer {
constructor(bugger) {
this.addressesToSkip = new Set();
this.badFetchAddresses = [];
this.badCompileAddresses = [];
this.badFetchers = [];
this.bugger = bugger; //no clone, note!
}
getErrors() {
return {
fetch: this.badFetchAddresses,
compile: this.badCompileAddresses,
fetchers: this.badFetchers
};
}
//helper method
getUnrecognizedAddresses() {
debug("getting unknown addresses");
const instances = this.bugger.view(this.bugger.selectors.session.info.affectedInstances);
debug("got instances");
return Object.entries(instances)
.filter(([_, { contractName }]) => contractName === undefined)
.map(([address, _]) => address);
}
/*
* Interface methods follow
*/
isAddressUnrecognized(address) {
return this.getUnrecognizedAddresses().includes(address);
}
getAnUnrecognizedAddress() {
return this.getUnrecognizedAddresses().find(address => !this.addressesToSkip.has(address));
}
markUnrecognizable(address, reason) {
//debugger does not keep track of detailed errors
if (reason) {
switch (reason) {
case "fetch":
this.badFetchAddresses.push(address);
break;
case "compile":
this.badCompileAddresses.push(address);
break;
default:
//just ignore ones with unsupported language
break;
}
}
this.addressesToSkip.add(address);
}
markBadFetcher(fetcherName) {
this.badFetchers.push(fetcherName);
}
addCompiledInfo(info, address) {
return __awaiter(this, void 0, void 0, function* () {
debug("compileResult: %O", info.compileResult);
const compilations = info.compileResult.compilations;
const shimmedCompilations = Codec.Compilations.Utils.shimCompilations(compilations, `externalFor(${address})Via(${info.fetchedVia})`);
yield this.bugger.addExternalCompilations(shimmedCompilations);
});
}
}
exports.DebugRecognizer = DebugRecognizer;
//# sourceMappingURL=debug.js.map
/***/ }),
/***/ 50588:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
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.getSortedFetcherConstructors = exports.fetchAndCompileForRecognizer = void 0;
const debug_1 = __importDefault(__webpack_require__(15158));
const debug = (0, debug_1.default)("fetch-and-compile:fetch");
const semver_1 = __importDefault(__webpack_require__(81249));
const source_fetcher_1 = __importDefault(__webpack_require__(87031));
const source_fetcher_2 = __webpack_require__(87031);
const config_1 = __importDefault(__webpack_require__(20553));
const { Compile } = __webpack_require__(4273); //sorry for untyped import!
const utils_1 = __webpack_require__(73727);
function fetchAndCompileForRecognizer(recognizer, options) {
return __awaiter(this, void 0, void 0, function* () {
const normalizedOptions = (0, utils_1.normalizeFetchAndCompileOptions)(options);
const fetcherConstructors = getSortedFetcherConstructors((0, utils_1.normalizeFetcherNames)(normalizedOptions));
const fetchers = yield getFetchers(fetcherConstructors, normalizedOptions, recognizer);
//now: the main loop!
let address;
while ((address = recognizer.getAnUnrecognizedAddress()) !== undefined) {
yield tryFetchAndCompileAddress(address, fetchers, recognizer, normalizedOptions);
}
});
}
exports.fetchAndCompileForRecognizer = fetchAndCompileForRecognizer;
//sort/filter fetchers by user's order, if given; otherwise use default order
function getSortedFetcherConstructors(userFetcherNames) {
let sortedFetchers = [];
if (userFetcherNames) {
for (let name of userFetcherNames) {
let Fetcher = source_fetcher_1.default.find(Fetcher => Fetcher.fetcherName === name);
if (Fetcher) {
sortedFetchers.push(Fetcher);
}
else {
throw new Error(`Unknown external source service ${name}.`);
}
}
}
else {
sortedFetchers = source_fetcher_1.default;
}
return sortedFetchers;
}
exports.getSortedFetcherConstructors = getSortedFetcherConstructors;
function getFetchers(fetcherConstructors, options, recognizer) {
return __awaiter(this, void 0, void 0, function* () {
const networkId = options.network.networkId;
//make fetcher instances. we'll filter out ones that don't support this
//network (and note ones that yielded errors)
return (yield Promise.all(fetcherConstructors.map((Fetcher) => __awaiter(this, void 0, void 0, function* () {
try {
return yield Fetcher.forNetworkId(networkId, ((options.fetch || {}).fetcherOptions || {})[Fetcher.fetcherName]);
}
catch (error) {
if (!(error instanceof source_fetcher_2.InvalidNetworkError)) {
//if it's *not* just an invalid network, log the error.
recognizer.markBadFetcher(Fetcher.fetcherName);
}
//either way, filter this fetcher out
return null;
}
})))).filter((fetcher) => fetcher !== null);
});
}
function tryFetchAndCompileAddress(address, fetchers, recognizer, fetchAndCompileOptions) {
return __awaiter(this, void 0, void 0, function* () {
let found = false;
let failureReason; //undefined if no failure
let failureError;
//(this includes if no source is found)
for (const fetcher of fetchers) {
//now comes all the hard parts!
//get our sources
let result;
try {
debug("getting sources for %s via %s", address, fetcher.fetcherName);
result = yield fetcher.fetchSourcesForAddress(address);
}
catch (error) {
debug("error in getting sources! %o", error);
failureReason = "fetch";
failureError = error;
continue;
}
if (result === null) {
debug("no sources found");
//null means they don't have that address
continue;
}
//if we do have it, extract sources & options
debug("got sources!");
const { sources, options } = result; //not same options as above, sorry for name confusion
if (options.language === "Vyper") {
//if it's not Solidity, bail out now
debug("found Vyper, bailing out!");
recognizer.markUnrecognizable(address, "language");
//break out of the fetcher loop, since *no* fetcher will work here
break;
}
//set up the config
let externalConfig = config_1.default.default().with({
compilers: {
solc: options
}
});
//if using docker, transform it (this does nothing if not using docker)
externalConfig = transformIfUsingDocker(externalConfig, fetchAndCompileOptions);
//compile the sources
let compileResult;
try {
compileResult = yield Compile.sources({
options: externalConfig.with({ quiet: true }),
sources
});
}
catch (error) {
debug("compile error: %O", error);
failureReason = "compile";
failureError = error;
continue; //try again with a different fetcher, I guess?
}
//add it!
yield recognizer.addCompiledInfo({
compileResult,
sourceInfo: result,
fetchedVia: fetcher.fetcherName
}, address);
failureReason = undefined; //mark as *not* failed in case a previous fetcher failed
failureError = undefined;
//check: did this actually help?
debug("checking result");
if (!recognizer.isAddressUnrecognized(address)) {
debug("address %s successfully recognized via %s", address, fetcher.fetcherName);
found = true;
//break out of the fetcher loop -- we got what we want
break;
}
debug("address %s still unrecognized", address);
}
if (found === false) {
//if we couldn't find it, add it to the list of addresses to skip
recognizer.markUnrecognizable(address, failureReason, failureError);
}
});
}
function transformIfUsingDocker(externalConfig, fetchAndCompileOptions) {
const useDocker = Boolean((fetchAndCompileOptions.compile || {}).docker);
if (!useDocker) {
//if they're not using docker, no need to transform anything :)
return externalConfig;
}
const givenVersion = externalConfig.compilers.solc.version;
//if they are, we have to ask: are they using a nightly?
if (semver_1.default.prerelease(givenVersion)) {
//we're not going to attempt to make Docker work with nightlies.
//just keep Docker turned off.
return externalConfig;
}
//otherwise, turn on Docker, and reduce the version to its simple form.
const simpleVersion = semver_1.default.valid(givenVersion);
if (simpleVersion === null) {
//this should never happen
throw new Error("Fetched source has unparseable compiler version");
}
return externalConfig.merge({
compilers: {
solc: {
version: simpleVersion,
docker: true
}
}
});
}
//# sourceMappingURL=fetch.js.map
/***/ }),
/***/ 5523:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
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.getSupportedNetworks = exports.fetchAndCompileForDebugger = exports.fetchAndCompileMultiple = exports.fetchAndCompile = exports.fetchAndCompileForRecognizer = void 0;
const debug_1 = __importDefault(__webpack_require__(15158));
const debug = (0, debug_1.default)("fetch-and-compile");
const recognizer_1 = __webpack_require__(36846);
const multiple_1 = __webpack_require__(943);
const debug_2 = __webpack_require__(87440);
const fetch_1 = __webpack_require__(50588);
Object.defineProperty(exports, "fetchAndCompileForRecognizer", ({ enumerable: true, get: function () { return fetch_1.fetchAndCompileForRecognizer; } }));
const utils_1 = __webpack_require__(73727);
function fetchAndCompile(address, options) {
return __awaiter(this, void 0, void 0, function* () {
const normalizedOptions = (0, utils_1.normalizeFetchAndCompileOptions)(options);
const recognizer = new recognizer_1.SingleRecognizer(address);
yield (0, fetch_1.fetchAndCompileForRecognizer)(recognizer, normalizedOptions);
return recognizer.getResult();
});
}
exports.fetchAndCompile = fetchAndCompile;
/**
* warning: while this function deduplicates inputs,
* it does *not* make any further effort to avoid redundant
* fetches (e.g. if multiple addresses share the same source),
* unlike fetchAndCompileForDebugger
*/
function fetchAndCompileMultiple(addresses, options) {
return __awaiter(this, void 0, void 0, function* () {
const normalizedOptions = (0, utils_1.normalizeFetchAndCompileOptions)(options);
const recognizer = new multiple_1.MultipleRecognizer(addresses);
yield (0, fetch_1.fetchAndCompileForRecognizer)(recognizer, normalizedOptions);
return recognizer.getResults();
});
}
exports.fetchAndCompileMultiple = fetchAndCompileMultiple;
//note: this function is called primarily for its side-effects
//(i.e. adding compilations to the debugger), NOT its return value!
function fetchAndCompileForDebugger(bugger, //sorry; this should be a debugger object
options) {
return __awaiter(this, void 0, void 0, function* () {
const normalizedOptions = (0, utils_1.normalizeFetchAndCompileOptions)(options);
const recognizer = new debug_2.DebugRecognizer(bugger);
yield (0, fetch_1.fetchAndCompileForRecognizer)(recognizer, normalizedOptions);
return recognizer.getErrors();
});
}
exports.fetchAndCompileForDebugger = fetchAndCompileForDebugger;
function getSupportedNetworks(optionsOrFetcherNames) {
const fetcherNames = (0, utils_1.normalizeFetcherNames)(optionsOrFetcherNames);
const fetchers = (0, fetch_1.getSortedFetcherConstructors)(fetcherNames);
//strictly speaking these are fetcher constructors, but since we
//won't be using fetcher instances in this function, I'm not going
//to worry about the difference
let supportedNetworks = {};
for (const fetcher of fetchers) {
const fetcherNetworks = fetcher.getSupportedNetworks();
for (const name in fetcherNetworks) {
if (name in supportedNetworks) {
supportedNetworks[name].fetchers.push(fetcher.fetcherName);
}
else {
supportedNetworks[name] = Object.assign(Object.assign({}, fetcherNetworks[name]), { fetchers: [fetcher.fetcherName] });
}
}
}
return supportedNetworks;
}
exports.getSupportedNetworks = getSupportedNetworks;
//# sourceMappingURL=index.js.map
/***/ }),
/***/ 943:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.MultipleRecognizer = void 0;
const debug_1 = __importDefault(__webpack_require__(15158));
const debug = (0, debug_1.default)("fetch-and-compile:multiple");
const web3_utils_1 = __importDefault(__webpack_require__(18269));
class MultipleRecognizer {
constructor(addresses) {
this.addressesToSkip = new Set();
this.results = {};
this.failureLog = {};
this.unrecognizedAddresses = [
...new Set(addresses.map(web3_utils_1.default.toChecksumAddress))
]; //remove duplicates (checksum to make case-insensitive & canonical) and clone
}
getResults() {
return {
results: this.results,
failures: this.failureLog
};
}
/*
* Interface methods follow
*/
isAddressUnrecognized(address) {
return this.unrecognizedAddresses.includes(address);
}
getAnUnrecognizedAddress() {
return this.unrecognizedAddresses.find(address => !this.addressesToSkip.has(address));
}
markUnrecognizable(address, reason, error) {
this.failureLog[address] = { reason, error };
this.addressesToSkip.add(address);
}
markBadFetcher(_fetcherName) {
//do nothing
}
addCompiledInfo(info, address) {
this.results[address] = info;
const index = this.unrecognizedAddresses.indexOf(address);
this.unrecognizedAddresses.splice(index, 1); //delete the address from the array
}
}
exports.MultipleRecognizer = MultipleRecognizer;
//# sourceMappingURL=multiple.js.map
/***/ }),
/***/ 36846:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SingleRecognizer = void 0;
const debug_1 = __importDefault(__webpack_require__(15158));
const debug = (0, debug_1.default)("fetch-and-compile:recognizer");
class SingleRecognizer {
constructor(address) {
this.recognized = false;
this.address = address;
}
getResult() {
return {
compileResult: this.compileResult,
sourceInfo: this.sourceInfo,
fetchedVia: this.fetchedVia
};
}
/*
* Interface methods follow
*/
isAddressUnrecognized(address) {
return !this.recognized || address !== this.address; //I guess?
}
getAnUnrecognizedAddress() {
return this.recognized ? undefined : this.address;
}
markUnrecognizable(address, reason, error) {
//just throw...
if (error) {
throw error;
}
else if (reason) {
switch (reason) {
case "fetch":
throw new Error(`Error in fetching sources for ${address}`);
case "compile":
throw new Error(`Error in compiling sources for ${address}`);
case "language":
throw new Error(`Sources for ${address} were not in a supported language`);
}
}
else {
throw new Error(`No verified sources found for ${address}`);
}
}
markBadFetcher(_fetcherName) {
//do nothing
}
addCompiledInfo(info, address) {
this.compileResult = info.compileResult;
this.sourceInfo = info.sourceInfo;
if (address === this.address) {
//I guess? this should never be false
this.recognized = true;
this.fetchedVia = info.fetchedVia;
}
}
}
exports.SingleRecognizer = SingleRecognizer;
//# sourceMappingURL=recognizer.js.map
/***/ }),
/***/ 73727:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.normalizeFetcherNames = exports.normalizeFetchAndCompileOptions = void 0;
const config_1 = __importDefault(__webpack_require__(20553));
const source_fetcher_1 = __importDefault(__webpack_require__(87031));
function normalizeFetchAndCompileOptions(options) {
if (options instanceof config_1.default) {
let normalizedOptions = {
network: {
networkId: options.network_id
},
compile: {
docker: ((options.compilers || {}).solc || {}).docker
},
fetch: {
precedence: options.sourceFetchers,
fetcherOptions: {}
}
};
for (const fetcher of source_fetcher_1.default) {
const fetcherName = fetcher.fetcherName;
const fetcherOptions = options[fetcherName];
//@ts-ignore TS can't recognize that the objects we just set up are definitely not undefined :-/
normalizedOptions.fetch.fetcherOptions[fetcherName] = fetcherOptions;
}
return normalizedOptions;
}
else {
return options;
}
}
exports.normalizeFetchAndCompileOptions = normalizeFetchAndCompileOptions;
function normalizeFetcherNames(optionsOrFetcherNames) {
if (Array.isArray(optionsOrFetcherNames)) {
return optionsOrFetcherNames;
}
else if (!optionsOrFetcherNames) {
return optionsOrFetcherNames;
}
else {
const options = normalizeFetchAndCompileOptions(optionsOrFetcherNames);
return ((options || {}).fetch || {}).precedence;
}
}
exports.normalizeFetcherNames = normalizeFetcherNames;
//# sourceMappingURL=utils.js.map
/***/ }),
/***/ 71103:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.InvalidNetworkError = exports.removeLibraries = exports.makeTimer = exports.makeFilename = void 0;
//these imports aren't actually necessary, but why not :)
const util_1 = __importDefault(__webpack_require__(73837));
const timers_1 = __webpack_require__(39512);
function makeFilename(name, extension = ".sol") {
if (!name) {
return "Contract" + extension;
}
if (name.endsWith(extension)) {
return name;
}
else {
return name + extension;
}
}
exports.makeFilename = makeFilename;
exports.makeTimer = util_1.default.promisify(timers_1.setTimeout);
function removeLibraries(settings, alsoRemoveCompilationTarget = false) {
let copySettings = Object.assign({}, settings);
delete copySettings.libraries;
if (alsoRemoveCompilationTarget) {
delete copySettings.compilationTarget;
}
return copySettings;
}
exports.removeLibraries = removeLibraries;
class InvalidNetworkError extends Error {
constructor(networkId, fetcherName) {
super(`Invalid network ID ${networkId} for fetcher ${fetcherName}`);
this.networkId = networkId;
this.fetcherName = fetcherName;
this.name = "InvalidNetworkError";
}
}
exports.InvalidNetworkError = InvalidNetworkError;
//# sourceMappingURL=common.js.map
/***/ }),
/***/ 74578:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
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 };
};
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
const debug_1 = __importDefault(__webpack_require__(15158));
const debug = (0, debug_1.default)("source-fetcher:etherscan");
// untyped import since no @types/web3-utils exists
const Web3Utils = __webpack_require__(18269);
const common_1 = __webpack_require__(71103);
const networks_1 = __webpack_require__(367);
// must polyfill AbortController to use axios >=0.20.0, <=0.27.2 on node <= v14.x
__webpack_require__(95084);
const axios_1 = __importDefault(__webpack_require__(43306));
const async_retry_1 = __importDefault(__webpack_require__(72047));
const etherscanCommentHeader = `/**
*Submitted for verification at Etherscan.io on 20XX-XX-XX
*/
`; //note we include that final newline
//this looks awkward but the TS docs actually suggest this :P
const EtherscanFetcher = (_a = class EtherscanFetcher {
static get fetcherName() {
return "etherscan";
}
get fetcherName() {
return EtherscanFetcher.fetcherName;
}
static forNetworkId(id, options) {
return __awaiter(this, void 0, void 0, function* () {
debug("options: %O", options);
debug("id:", id);
return new EtherscanFetcher(id, options ? options.apiKey : "");
});
}
constructor(networkId, apiKey = "") {
const networkName = networks_1.networkNamesById[networkId];
if (networkName === undefined ||
!(networkName in EtherscanFetcher.apiDomainsByNetworkName)) {
throw new common_1.InvalidNetworkError(networkId, "etherscan");
}
this.networkName = networkName;
debug("apiKey: %s", apiKey);
this.apiKey = apiKey;
const baseDelay = this.apiKey ? 200 : 3000; //etherscan permits 5 requests/sec w/a key, 1/3sec w/o
const safetyFactor = 1; //no safety factor atm
this.delay = baseDelay * safetyFactor;
this.ready = (0, common_1.makeTimer)(0); //at start, it's ready to go immediately
}
static getSupportedNetworks() {
return Object.fromEntries(Object.entries(networks_1.networksByName).filter(([name, _]) => name in EtherscanFetcher.apiDomainsByNetworkName));
}
fetchSourcesForAddress(address) {
return __awaiter(this, void 0, void 0, function* () {
const response = yield this.getSuccessfulResponse(address);
return EtherscanFetcher.processResult(response.result[0]);
});
}
getSuccessfulResponse(address) {
return __awaiter(this, void 0, void 0, function* () {
const initialTimeoutFactor = 1.5; //I guess?
return yield (0, async_retry_1.default)(() => __awaiter(this, void 0, void 0, function* () { return yield this.makeRequest(address); }), {
retries: 3,
minTimeout: this.delay * initialTimeoutFactor
});
});
}
determineUrl() {
const domain = EtherscanFetcher.apiDomainsByNetworkName[this.networkName];
return `https://${domain}/api`;
}
makeRequest(address) {
return __awaiter(this, void 0, void 0, function* () {
//not putting a try/catch around this; if it throws, we throw
yield this.ready;
const responsePromise = axios_1.default.get(this.determineUrl(), {
params: {
module: "contract",
action: "getsourcecode",
address,
apikey: this.apiKey
},
responseType: "json",
maxRedirects: 50
});
this.ready = (0, common_1.makeTimer)(this.delay);
const response = (yield responsePromise).data;
if (response.status === "0") {
throw new Error(response.result);
}
return response;
});
}
static processResult(result) {
//we have 5 cases here.
//case 1: the address doesn't exist
if (result.SourceCode === "" &&
result.ABI === "Contract source code not verified") {
return null;
}
//case 2: it's a Vyper contract
if (result.CompilerVersion.startsWith("vyper:")) {
return this.processVyperResult(result);
}
let multifileJson;
try {
//try to parse the source JSON. if it succeeds,
//we're in the multi-file case.
multifileJson = JSON.parse(result.SourceCode);
}
catch (_) {
//otherwise, we could be single-file or we could be full JSON.
//for full JSON input, etherscan will stick an extra pair of braces around it
if (result.SourceCode.startsWith("{") &&
result.SourceCode.endsWith("}")) {
const trimmedSource = result.SourceCode.slice(1).slice(0, -1); //remove braces
let fullJson;
try {
fullJson = JSON.parse(trimmedSource);
}
catch (_) {
//if it still doesn't parse, it's single-source I guess?
//(note: we shouldn't really end up here?)
debug("single-file input??");
return this.processSingleResult(result);
}
//case 5: full JSON input
debug("json input");
return this.processJsonResult(result, fullJson);
}
//case 3 (the way it should happen): single source
debug("single-file input");
return this.processSingleResult(result);
}
//case 4: multiple sources
debug("multi-file input");
return this.processMultiResult(result, multifileJson);
}
static processSingleResult(result) {
const filename = (0, common_1.makeFilename)(result.ContractName);
return {
contractName: result.ContractName,
sources: {
//we prepend this header comment so that line numbers in the debugger
//will match up with what's displayed on the website; note that other
//cases don't display a similar header on the website
[filename]: etherscanCommentHeader + result.SourceCode
},
options: {
language: "Solidity",
version: result.CompilerVersion,
settings: this.extractSettings(result),
specializations: {
libraries: this.processLibraries(result.Library),
constructorArguments: result.ConstructorArguments
}
}
};
}
static processMultiResult(result, sources) {
return {
contractName: result.ContractName,
sources: this.processSources(sources),
options: {
language: "Solidity",
version: result.CompilerVersion,
settings: this.extractSettings(result),
specializations: {
libraries: this.processLibraries(result.Library),
constructorArguments: result.ConstructorArguments
}
}
};
}
static processJsonResult(result, jsonInput) {
if (jsonInput.language === "SolidityAST") {
//I don't know whether this is actually possible on Etherscan,
//but there's no way we can reasonably handle it, so let's
//just be defensive and refuse it
return null;
}
return {
contractName: result.ContractName,
sources: this.processSources(jsonInput.sources),
options: {
language: jsonInput.language,
version: result.CompilerVersion,
settings: (0, common_1.removeLibraries)(jsonInput.settings),
specializations: {
libraries: jsonInput.settings.libraries,
constructorArguments: result.ConstructorArguments
}
}
};
}
static processVyperResult(result) {
const filename = (0, common_1.makeFilename)(result.ContractName, ".vy");
//note: this means filename will always be Vyper_contract.vy
return {
sources: {
[filename]: result.SourceCode
},
options: {
language: "Vyper",
version: result.CompilerVersion.replace(/^vyper:/, ""),
settings: this.extractVyperSettings(result),
specializations: {
constructorArguments: result.ConstructorArguments
}
}
};
}
static processSources(sources) {
return Object.assign({}, ...Object.entries(sources).map(([path, { content: source }]) => ({
[(0, common_1.makeFilename)(path)]: source
})));
}
static extractSettings(result) {
const evmVersion = result.EVMVersion === "Default" ? undefined : result.EVMVersion;
const optimizer = {
enabled: result.OptimizationUsed === "1",
runs: parseInt(result.Runs)
};
//old version got libraries here, but we don't actually want that!
if (evmVersion !== undefined) {
return {
optimizer,
evmVersion
};
}
else {
return {
optimizer
};
}
}
static processLibraries(librariesString) {
let libraries;
if (librariesString === "") {
libraries = {};
}
else {
libraries = Object.assign({}, ...librariesString.split(";").map(pair => {
const [name, address] = pair.split(":");
return { [name]: Web3Utils.toChecksumAddress(address) };
}));
}
return { "": libraries }; //empty string as key means it applies to all contracts
}
static extractVyperSettings(result) {
const evmVersion = result.EVMVersion === "Default" ? undefined : result.EVMVersion;
//the optimize flag is not currently supported by etherscan;
//any Vyper contract currently verified on etherscan necessarily has
//optimize flag left unspecified (and therefore effectively true).
//do NOT look at OptimizationUsed for Vyper contracts; it will always
//be "0" even though in fact optimization *was* used. just leave
//the optimize flag unspecified.
if (evmVersion !== undefined) {
return { evmVersion };
}
else {
return {};
}
}
},
//then, afterwards, start a new timer.
_a.apiDomainsByNetworkName = {
"mainnet": "api.etherscan.io",
"goerli": "api-goerli.etherscan.io",
"sepolia": "api-sepolia.etherscan.io",
"optimistic": "api-optimistic.etherscan.io",
"goerli-optimistic": "api-goerli-optimism.etherscan.io",
"arbitrum": "api.arbiscan.io",
"nova-arbitrum": "api-nova.arbiscan.io",
"goerli-arbitrum": "api-goerli.arbiscan.io",
"polygon": "api.polygonscan.com",
"mumbai-polygon": "api-mumbai.polygonscan.com",
"zkevm-polygon": "api-zkevm.polygonscan.com",
"testnet-zkevm-polygon": "api-testnet-zkevm.polygonscan.com",
"binance": "api.bscscan.com",
"testnet-binance": "api-testnet.bscscan.com",
"testnet-opbnb-binance": "api-opbnb-testnet.bscscan.com",
"fantom": "api.ftmscan.com",
"testnet-fantom": "api-testnet.ftmscan.com",
"avalanche": "api.snowtrace.io",
"fuji-avalanche": "api-testnet.snowtrace.io",
"heco": "api.hecoinfo.com",
"testnet-heco": "api-testnet.hecoinfo.com",
"moonbeam": "api-moonbeam.moonscan.io",
"moonriver": "api-moonriver.moonscan.io",
"moonbase-alpha": "api-moonbase.moonscan.io",
"cronos": "api.cronoscan.com",
"bttc": "api.bttcscan.com",
"donau-bttc": "api-testnet.bttcscan.com",
"celo": "api.celoscan.io",
"alfajores-celo": "api-alfajores.celoscan.io",
"boba": "api.bobascan.com",
"goerli-boba": "api-testnet.bobascan.com",
"gnosis": "api.gnosisscan.io",
"base": "api.basescan.org",
"goerli-base": "api-goerli.basescan.org",
"linea": "api.lineascan.build",
"goerli-linea": "api-goerli.lineascan.build"
},
_a);
exports["default"] = EtherscanFetcher;
//# sourceMappingURL=etherscan.js.map
/***/ }),
/***/ 87031:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.InvalidNetworkError = void 0;
const common_1 = __webpack_require__(71103);
Object.defineProperty(exports, "InvalidNetworkError", ({ enumerable: true, get: function () { return common_1.InvalidNetworkError; } }));
const etherscan_1 = __importDefault(__webpack_require__(74578));
const sourcify_1 = __importDefault(__webpack_require__(11284));
const Fetchers = [etherscan_1.default, sourcify_1.default];
exports["default"] = Fetchers;
//# sourceMappingURL=index.js.map
/***/ }),
/***/ 367:
/***/ ((__unused_webpack_module, exports) => {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.networksByName = exports.networkNamesById = void 0;
exports.networkNamesById = {
1: "mainnet",
3: "ropsten",
4: "rinkeby",
5: "goerli",
42: "kovan",
11155111: "sepolia",
10: "optimistic",
69: "kovan-optimistic",
420: "goerli-optimistic",
28528: "goerli-bedrock-optimistic",
42161: "arbitrum",
42170: "nova-arbitrum",
421611: "rinkeby-arbitrum",
421613: "goerli-arbitrum",
137: "polygon",
80001: "mumbai-polygon",
1101: "zkevm-polygon",
1442: "testnet-zkevm-polygon",
100: "gnosis",
10200: "chiado-gnosis",
300: "optimism-gnosis",
99: "core-poa",
77: "sokol-poa",
56: "binance",
97: "testnet-binance",
5611: "testnet-opbnb-binance",
42220: "celo",
44787: "alfajores-celo",
62320: "baklava-celo",
43114: "avalanche",
43113: "fuji-avalanche",
11111: "wagmi-avalanche",
53935: "dfk-avalanche",
335: "testnet-dfk-avalance",
432204: "dexalot-avalanche",
432201: "testnet-dexalot-avalanche",
4337: "beam-avalanche",
13337: "testnet-beam-avalanche",
2037: "kiwi-avalanche",
78430: "amplify-avalanche",
78431: "bulletin-avalanche",
78432: "conduit-avalanche",
40: "telos",
41: "testnet-telos",
8: "ubiq",
311752642: "oneledger",
4216137055: "frankenstein-oneledger",
57: "syscoin",
5700: "tanenbaum-syscoin",
288: "boba",
28: "rinkeby-boba",
2888: "goerli-boba",
106: "velas",
82: "meter",
83: "testnet-meter",
1313161554: "aurora",
1313161555: "testnet-aurora",
250: "fantom",
4002: "testnet-fantom",
128: "heco",
256: "testnet-heco",
1284: "moonbeam",
1285: "moonriver",
1287: "moonbase-alpha",
122: "fuse",
11297108109: "palm",
11297108099: "testnet-palm",
70: "hoo",
25: "cronos",
338: "testnet-cronos",
199: "bttc",
1029: "donau-bttc",
1024: "clover",
44: "crab-darwinia",
43: "pangolin-darwinia",
9001: "evmos",
9000: "testnet-evmos",
62621: "multivac",
534: "candle",
192837465: "gather",
486217935: "devnet-gather",
356256156: "testnet-gather",
246: "energyweb",
73799: "volta-energyweb",
71402: "godwoken",
71401: "testnet-godwoken",
50: "xinfin",
51: "apothem-xinfin",
7700: "canto",
7701: "testnet-canto",
592: "astar",
336: "shiden-astar",
8217: "cypress-klaytn",
1001: "baobab-klaytn",
7000: "zetachain",
7001: "athens-zetachain",
42262: "emerald-oasis",
42261: "testnet-emerald-oasis",
23294: "sapphire-oasis",
23295: "testnet-sapphire-oasis",
14: "flare",
19: "songbird-flare",
2048: "stratos",
2047: "testnet-stratos",
8453: "base",
84531: "goerli-base",
641230: "bear",
888: "wanchain",
999: "testnet-wanchain",
7668: "root",
7672: "porcini-root",
295: "hedera",
1149: "symplexia",
2000: "dogechain",
1339: "elysium",
167005: "grimsvotn-taiko",
167006: "eldfell-taiko",
96: "bitkub",
25925: "testnet-bitkub",
7777777: "zora",
570: "rollux",
57000: "tanenbaum-rollux",
6119: "uptn",
2222: "kava",
2221: "testnet-kava",
314: "filecoin",
314159: "calibration-filecoin",
32769: "zilliqa",
33101: "testnet-zilliqa",
111111: "siberium",
111000: "testnet-siberium",
59144: "linea",
59140: "goerli-linea",
22776: "map",
212: "makalu-map",
2021: "edgeware",
333000333: "meld",
222000222: "kanazawa-meld"
//I'm not including crystaleum as it has network ID different from chain ID
//not including kekchain for the same reason
//not including ethereum classic for same reason
};
exports.networksByName = Object.fromEntries(Object.entries(exports.networkNamesById).map(([id, name]) => [name, { name, networkId: Number(id), chainId: Number(id) }] //id is a string since it's a key so must use Number()
));
//# sourceMappingURL=networks.js.map
/***/ }),
/***/ 95084:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
Object.defineProperty(exports, "__esModule", ({ value: true }));
// must polyfill AbortController to use axios >=0.20.0, <=0.27.2 on node <= v14.x
const node_abort_controller_1 = __webpack_require__(53357);
if (typeof global.AbortController === "undefined") {
global.AbortController = node_abort_controller_1.AbortController;
global.AbortSignal = node_abort_controller_1.AbortSignal;
}
//# sourceMappingURL=polyfill.js.map
/***/ }),
/***/ 11284:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
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 };
};
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
const debug_1 = __importDefault(__webpack_require__(15158));
const debug = (0, debug_1.default)("source-fetcher:sourcify");
const common_1 = __webpack_require__(71103);
const networks_1 = __webpack_require__(367);
const async_retry_1 = __importDefault(__webpack_require__(72047));
// must polyfill AbortController to use axios >=0.20.0, <=0.27.2 on node <= v14.x
__webpack_require__(95084);
const axios_1 = __importDefault(__webpack_require__(43306));
//this looks awkward but the TS docs actually suggest this :P
const SourcifyFetcher = (_a = class SourcifyFetcher {
static get fetcherName() {
return "sourcify";
}
get fetcherName() {
return SourcifyFetcher.fetcherName;
}
static forNetworkId(id, _options) {
return __awaiter(this, void 0, void 0, function* () {
//in the future, we may add protocol and node options,
//but these don't exist yet
return new SourcifyFetcher(id);
});
}
constructor(networkId) {
//but may be in the future
this.domain = "repo.sourcify.dev";
this.networkId = networkId;
this.networkName = networks_1.networkNamesById[networkId];
//we no longer check if the network is supported; the list is now only
//used for if you explicitly ask
}
static getSupportedNetworks() {
return Object.fromEntries(Object.entries(networks_1.networksByName).filter(([name, _]) => SourcifyFetcher.supportedNetworks.has(name)));
}
fetchSourcesForAddress(address) {
return __awaiter(this, void 0, void 0, function* () {
let result = yield this.fetchSourcesForAddressAndMatchType(address, "full");
if (!result) {
//if we got nothing when trying a full match, try for a partial match
result = yield this.fetchSourcesForAddressAndMatchType(address, "partial");
}
//if partial match also fails, just return null
return result;
});
}
fetchSourcesForAddressAndMatchType(address, matchType) {
return __awaiter(this, void 0, void 0, function* () {
const metadata = yield this.getMetadata(address, matchType);
debug("metadata: %O", metadata);
if (!metadata) {
debug("no metadata");
return null;
}
let sources;
sources = Object.assign({}, ...(yield Promise.all(Object.entries(metadata.sources).map(([sourcePath, { content: source }]) => __awaiter(this, void 0, void 0, function* () {
return ({
[sourcePath]: source !== undefined
? source //sourcify doesn't support this yet but they're planning it
: yield this.getSource(address, sourcePath, matchType)
});
})))));
const constructorArguments = yield this.getConstructorArgs(address, matchType);
debug("compilationTarget: %O", metadata.settings.compilationTarget);
return {
contractName: Object.values(metadata.settings.compilationTarget)[0],
sources,
options: {
language: metadata.language,
version: metadata.compiler.version,
//we also pass the flag to remove compilationTarget, as its
//presence can cause compile errors
settings: (0, common_1.removeLibraries)(metadata.settings, true),