diff --git a/packages/config/src/configDefaults.ts b/packages/config/src/configDefaults.ts index 42c5d44810b..502870929ad 100644 --- a/packages/config/src/configDefaults.ts +++ b/packages/config/src/configDefaults.ts @@ -36,10 +36,10 @@ export const getInitialConfig = ({ ipfsHost: "ipfs.infura.io", ipfsProtocol: "https", ipfsPort: "5001", - registry: "erc1319://0x5a5FE036d2557Ef4C85341fe4f9848e38173eFBa:3" + registryUri: "erc1319://0x5a5FE036d2557Ef4C85341fe4f9848e38173eFBa:3" }, ens: { - enabled: true, + enabled: false, // update to true? registryAddress: null }, compilers: { diff --git a/packages/core/lib/package.js b/packages/core/lib/package.js index 7bfb52a1839..37315740386 100644 --- a/packages/core/lib/package.js +++ b/packages/core/lib/package.js @@ -10,7 +10,7 @@ const { isAddress } = require("web3-utils"); const path = require("path"); const fs = require("fs"); const ENSJS = require("ethereum-ens"); -const TruffleContractSchema = require("@truffle/contract-schema"); +//const TruffleContractSchema = require("@truffle/contract-schema"); SUPPORTED_CHAIN_IDS = { 1: "mainnet", @@ -34,6 +34,7 @@ const Package = { expect.options(options, [ "ethpm", // default ethpm settings "ethpmUri", // target uri to install + "ens", "logger", "working_directory", "contracts_build_directory" @@ -91,7 +92,7 @@ const Package = { ); } try { - const ensjs = new ENSJS(provider, options.ens.registry.address); + const ensjs = new ENSJS(provider, options.ens.registryAddress); ethpmUri.address = await ensjs.resolver(ethpmUri.address).addr(); } catch (err) { done(new TruffleError(`Unable to resolve uri: ${err.message}`)); @@ -223,11 +224,11 @@ const Package = { // contract-schema doesn't define devdoc/userdoc but artifacts have it - can we include? }; // seems like abi validation is too strict / outdated? - try { - await TruffleContractSchema.validate(validContractSchema); - } catch (err) { - done(new TruffleError(`ethPM package import error: ${err.message}`)); - } + //try { + //await TruffleContractSchema.validate(validContractSchema); + //} catch (err) { + //done(new TruffleError(`ethPM package import error: ${err.message}`)); + //} await artifactor.save(validContractSchema); } options.logger.log("Saved artifacts."); @@ -249,23 +250,22 @@ const Package = { "ipfsHost", "ipfsPort", "ipfsProtocol", - "registry", + "registryUri", "infuraKey" ]); } catch (err) { done(new TruffleError(err.message)); } - const registryURI = new EthpmURI(options.ethpm.registry); - const registryProviderURI = getInfuraEndpointForChainId( - registryURI.chainId, + const registryUri = new EthpmURI(options.ethpm.registryUri); + const registryProviderUri = getInfuraEndpointForChainId( + registryUri.chainId, options.ethpm.infuraKey ); - registryProvider = new Web3.providers.HttpProvider(registryProviderURI, { + registryProvider = new Web3.providers.HttpProvider(registryProviderUri, { keepAlive: true }); - options.logger.log("Gathering contracts..."); // incorrect place let ethpm; try { ethpm = await EthPM.configure({ @@ -273,8 +273,8 @@ const Package = { storage: "ethpm/storage/ipfs", registries: "ethpm/registries/web3" }).connect({ - provider: registryProvider, // bad hardcoded provider - registryAddress: registryURI.address, + provider: registryProvider, + registryAddress: registryUri.address, ipfs: { host: options.ethpm.ipfsHost, port: options.ethpm.ipfsPort, @@ -332,71 +332,47 @@ const Package = { const targetConfig = Object.assign(ethpmFields, ethpmConfig); const pkg = await ethpm.manifests.read(JSON.stringify(targetConfig)); const manifest = await ethpm.manifests.write(pkg); - const manifestURI = await ethpm.storage.write(manifest); + const manifestUri = await ethpm.storage.write(manifest); - options.logger.log(`Publishing package to ${options.ethpm.registry}`); + options.logger.log(`Publishing package to registry...`); try { const w3 = new Web3(options.provider); - const encoded = ethpm.registries.registry.methods + const encodedTxData = ethpm.registries.registry.methods .release( ethpmConfig.package_name, ethpmConfig.version, - manifestURI.href + manifestUri.href ) .encodeABI(); const tx = await w3.eth.signTransaction({ from: options.provider.addresses[0], - to: registryURI.address, + to: registryUri.address, gas: 4712388, gasPrice: 100000000000, - data: encoded + data: encodedTxData }); await w3.eth.sendSignedTransaction(tx.raw); } catch (err) { - done(new TruffleError(`Error publishing package: ${err}`)); + done( + new TruffleError( + `Error publishing package: ${err}.\nDoes ${ + ethpmConfig.package_name + }@${ethpmConfig.version} already exist on registry: ${ + registryUri.raw + }?` + ) + ); } done( options.logger.log( `Published ${ethpmConfig.package_name}@${ethpmConfig.version} to ${ - options.ethpm.registry - }` // add link to explorer? + registryUri.raw + }` ) ); - //return JSON.parse(manifest); // remove this } }; -function validateSupportedChainId(chainId) { - if (!(chainId in SUPPORTED_CHAIN_IDS)) { - throw new TruffleError( - `Detected chain ID: ${chainId} is not a supported chain id. Supported values include ${Object.keys( - SUPPORTED_CHAIN_IDS - )}` - ); - } -} - -function getInfuraEndpointForChainId(chainId, infuraKey) { - validateSupportedChainId(chainId); - return `https://${SUPPORTED_CHAIN_IDS[chainId]}.infura.io/v3/${infuraKey}`; -} - -async function convertNetworkIdToBlockchainUri(networkId, infuraKey) { - // mock value for ganache dev chains - if (networkId > 100) { - return "blockchain://329ff0a289d0ffba148c495b9cffd078d2f5a272538616b1b412c75f268134a4/block/46ef23590d0c99840621ac95b503ed569f79c65be452acd50478bfe721205ce1"; - } - validateSupportedChainId(networkId); // chain id vs network id - const infuraUri = getInfuraEndpointForChainId(networkId, infuraKey); - const w3 = new Web3(new Web3.providers.HttpProvider(infuraUri)); - const genesisBlock = await w3.eth.getBlock(0); - const latestBlock = await w3.eth.getBlock("latest"); - return `blockchain://${genesisBlock.hash.replace( - "0x", - "" - )}/block/${latestBlock.hash.replace("0x", "")}`; -} - // Returns a list of publishable artifacts // aka contract_types and deployments found in all artifacts async function getPublishableArtifacts(options, ethpm) { @@ -466,23 +442,23 @@ async function getPublishableArtifacts(options, ethpm) { }; } -// handles sources installed via ethpm -async function resolveSources(sourcePaths, contractsDirectory, ethpm) { - const sources = {}; - // TODO! how do we include installed pkgs in the publishing process? - // just add as build dependencies? probably - // flatten and include in pkg? probably not - for (let sourcePath of Object.keys(sourcePaths)) { - if (sourcePath !== "undefined") { - const ipfsHash = await ethpm.storage.write(sourcePaths[sourcePath]); - // resolve all sources (including ethpm) to absolute contracts dir - const absolute = path.resolve(contractsDirectory, sourcePath); - // resolve all sources to relative path - const resolved = path.relative(contractsDirectory, absolute); - sources[`./${resolved}`] = ipfsHash.href; - } +// +// Utils +// + +function validateSupportedChainId(chainId) { + if (!(chainId in SUPPORTED_CHAIN_IDS)) { + throw new TruffleError( + `Detected chain ID: ${chainId} is not a supported chain id. Supported values include ${Object.keys( + SUPPORTED_CHAIN_IDS + )}` + ); } - return sources; +} + +function getInfuraEndpointForChainId(chainId, infuraKey) { + validateSupportedChainId(chainId); + return `https://${SUPPORTED_CHAIN_IDS[chainId]}.infura.io/v3/${infuraKey}`; } function fetchInstalledBuildDependencies(workingDirectory) { @@ -504,4 +480,32 @@ function fetchInstalledBuildDependencies(workingDirectory) { return installedBuildDependencies; } +async function convertNetworkIdToBlockchainUri(networkId, infuraKey) { + validateSupportedChainId(networkId); + const infuraUri = getInfuraEndpointForChainId(networkId, infuraKey); + const w3 = new Web3(new Web3.providers.HttpProvider(infuraUri)); + const genesisBlock = await w3.eth.getBlock(0); + const latestBlock = await w3.eth.getBlock("latest"); + return `blockchain://${genesisBlock.hash.replace( + "0x", + "" + )}/block/${latestBlock.hash.replace("0x", "")}`; +} + +// handles sources installed via ethpm +async function resolveSources(sourcePaths, contractsDirectory, ethpm) { + const sources = {}; + for (let sourcePath of Object.keys(sourcePaths)) { + if (sourcePath !== "undefined") { + const ipfsHash = await ethpm.storage.write(sourcePaths[sourcePath]); + // resolve all sources (including ethpm) to absolute contracts dir + const absolute = path.resolve(contractsDirectory, sourcePath); + // resolve all sources to relative path + const resolved = path.relative(contractsDirectory, absolute); + sources[`./${resolved}`] = ipfsHash.href; + } + } + return sources; +} + module.exports = Package; diff --git a/packages/core/test/ethpm.js b/packages/core/test/ethpm.js index 3d4d0c708eb..7d6d3958187 100644 --- a/packages/core/test/ethpm.js +++ b/packages/core/test/ethpm.js @@ -15,7 +15,6 @@ const Migrate = require("@truffle/migrate"); const INSTALL_PROVIDER_URI = "https://mainnet.infura.io/v3/7707850c2fb7465ebe6f150d67182e22"; -//const INFURA_KEY = "b2679bb624354d1b9a2586154651b51f"; const INFURA_KEY = "7707850c2fb7465ebe6f150d67182e22"; describe("EthPM install", function() { diff --git a/packages/resolver/epm.js b/packages/resolver/epm.js index 58c4132849e..47769fb2d55 100644 --- a/packages/resolver/epm.js +++ b/packages/resolver/epm.js @@ -1,9 +1,13 @@ var path = require("path"); var fs = require("fs"); +var glob = require("glob"); function EPM(working_directory, contracts_build_directory) { this.working_directory = working_directory; this.contracts_build_directory = contracts_build_directory; + this.allEthpmFiles = glob.sync("**/*", { + cwd: path.join(this.working_directory, "_ethpm_packages") + }); } EPM.prototype.require = function(import_path, _search_path) { @@ -70,19 +74,12 @@ EPM.prototype.require = function(import_path, _search_path) { var internal_path = import_path.substring(separator + 1); var installDir = this.working_directory; - // can find build_deps one level deep - let parent_separator; - let parent_name; - - if (imported_from !== null) { - parent_separator = imported_from.indexOf("/"); - parent_name = imported_from.substring(0, parent_separator); - } - // If nothing's found, body returns `undefined` var body; + var matches = this.allEthpmFiles.filter(p => p.includes(import_path)); while (true) { + // check for root level ethpm sources var file_path = path.join( installDir, "_ethpm_packages", @@ -96,20 +93,17 @@ EPM.prototype.require = function(import_path, _search_path) { break; } catch (err) {} - if (parent_name !== undefined) { - file_path = path.join( - installDir, - "_ethpm_packages", - parent_name, - "_ethpm_packages", - package_name, - "_src", - import_path - ); - try { - body = fs.readFileSync(file_path, { encoding: "utf8" }); - break; - } catch (err) {} + // DOES NOT SUPPORT DUPLICATE IMPORT PATHS W/IN AGGREGATED PKGS + if (matches.length > 0) { + if (matches.length === 1) { + try { + body = fs.readFileSync( + path.join(installDir, "_ethpm_packages", matches[0]), + { encoding: "utf8" } + ); + break; + } catch (err) {} + } } // Recurse outwards until impossible