OpenZeppelin / openzeppelin-sdk

OpenZeppelin SDK repository for CLI and upgrades.js. No longer actively developed.
MIT License
432 stars 200 forks source link

Using zos as library instead of CLI #1131

Open miguelmota opened 5 years ago

miguelmota commented 5 years ago

I'm currently using zos as a library instead of the CLI and ran into some problems.

My primary requirements are to use zos.scripts.querySignedDeployment for generating the deterministic contract address and zos.scripts.create to deploy the contracts.

The first issue was not being able to set a custom truffle.js path for zos config.

In packages/cli/src/models/config/TruffleConfig.ts, needed to add workingDirectory to truffle's detect method:

-      this.config = TruffleConfigModule.detect({ logger: console });
+      this.config = TruffleConfigModule.detect({
+        logger: console,
+        workingDirectory: cwd,
+     });

The second issue was that zos' .session file lookup was hardcoded to check the current directory. This wouldn't work since I'm using zos in a module that module is being imported in a different package.

In packages/cli/src/models/network/Session.ts, added an environment variable check as a quick cheap workaround since I don't know my way around the code but the best way would be to add a method to set the session path.

- const SESSION_PATH = path.join(OPEN_ZEPPELIN_FOLDER, SESSION_FILE);
+ const SESSION_PATH = process.env.ZOS_SESSION_PATH || path.join(OPEN_ZEPPELIN_FOLDER, SESSION_FILE);

The other problem was that truffle's .search() would return null and throw and error. In packages/cli/src/models/config/TruffleConfig.ts, had to change the following:

- const rawConfig = require(require('truffle-config').search()) || {};
+ const truffleFile = require('truffle-config').search();
+ const rawConfig = truffleFile ? require(truffleFile) : {};

The last problem was initializing the configuration which wasn't trivial and there's most likely a better way:

    zos.ConfigManager.setBaseConfig(currentDir)
    const networkConfig = await zos.ConfigManager.initNetworkConfiguration({ network: networkName }, false, currentDir)
    zos.ConfigManager.initStaticConfiguration(currentDir)
    zos.ConfigManager.getBuildDir(`${currentDir}/dist/contracts`)
    Contracts.setLocalBuildDir(`${currentDir}/dist/contracts`)
    zos.ConfigManager.setBaseConfig(currentDir)

    const projectFile = new zos.files.ProjectFile(`${currentDir}/zos.json`)
    const networkFile = new zos.files.NetworkFile(projectFile, networkName,
      `${currentDir}/zos.${networkName}.json`)

    const res = await zos.scripts[query ? 'querySignedDeployment' : 'create']({ ... })

I know that zos wasn't intended to be used as a library just yet but let me know your thoughts and if there's better way of doings things I should be doing instead. Thanks!

spalladino commented 5 years ago

Hey @miguelmota, thanks so much for the comments!! Indeed, the zos CLI programmatic interface needs more love. Our intent was for zos-lib to be the programmatic way to use it, but it does lack integration with the zos.json files that the CLI handles.

We will implement the changes you suggest here, and at the same time go back to the whiteboard to re-think the programmatic API. Expect some news on this in about 1 month from now, when we will probably be sharing a draft and asking for feedback!