Skip to content
This repository has been archived by the owner on Apr 18, 2021. It is now read-only.

Jay/make config file #95

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ package-lock.json
contractApis
state.vvisp.json
service.vvisp.json
vvisp-config.js
example.json
example

Expand Down
1 change: 1 addition & 0 deletions packages/vvisp-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"dependencies": {
"bip39": "^2.5.0",
"chalk": "^2.4.1",
"truffle-provider": "^0.1.4",
"ethereumjs-tx": "^1.3.7",
"ethereumjs-wallet": "^0.6.2",
"find-cache-dir": "^2.0.0",
Expand Down
250 changes: 250 additions & 0 deletions packages/vvisp-utils/src/Config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
// reference: https://github.com/trufflesuite/truffle/blob/40a9c615eee78f14854ced65766ed3d370da07ae/packages/truffle-config/index.js
JhChoy marked this conversation as resolved.
Show resolved Hide resolved
const _ = require('lodash');
const Provider = require('truffle-provider');
const path = require('path');

const DEFAULT_CONFIG_FILE = 'vvisp-config.js';
const DEFAULT_NETWORK = 'development';

const getConfigRoot = require('./getConfigRoot');
const getPrivateKey = require('./getPrivateKey');
const filterPrivateKey = require('./filterPrivateKey');
const forIn = require('./forIn');

function Config() {
const self = this;

const defaultTxOptions = {
gasLimit: 6721975,
gasPrice: 20000000000 // 20 gwei,
};

this._deepCopy = ['networks', 'compilers'];

this._values = {
network: null, // default config is development
networks: {},
verboseRpc: false,
gasLimit: null,
gasPrice: null,
from: null,
compilers: {
solc: {
settings: {
optimizer: {
enabled: false,
runs: 200
},
evmVersion: 'byzantium'
}
},
vyper: {}
}
};

const props = {
network: {},
networks: {},
verboseRpc: {},
compilers: {},

from: {
get: function() {
const value = self._values['from'];
if (typeof value === 'string') {
return value;
} else if (typeof value === 'object' && value !== null) {
return getPrivateKey(value.mnemonic, value.index);
} else {
throw new Error(`from is not set properly, got ${value}`);
}
},
set: function(value) {
if (typeof value === 'string') {
self._values['from'] = filterPrivateKey(value);
return;
} else if (typeof value === 'object' && value !== null) {
if (typeof value.mnemonic === 'string') {
self._values['from'] = value;
return;
}
}
throw new TypeError(`${JSON.stringify(value)} is invalid key format`);
}
},
network_config: {
get: function() {
const network = self.network;

if (network === null || network === undefined) {
throw new Error(
'Network not set. Cannot determine network to use. Set config.network or add option --network <network>'
);
}

return _.extend({}, defaultTxOptions, self.networks[network]);
},
set: function() {
throw new Error(
'Do not set config.network_config. Instead, set config.networks with the desired values.'
);
}
},
network_id: {
get: function() {
try {
return self.network_config.network_id;
} catch (e) {
return null;
}
},
set: function() {
throw new Error(
'Do not set config.network_id. Instead, set config.networks and then config.networks[<network name>].network_id'
);
}
},
gasLimit: {
get: function() {
try {
return self.network_config.gas || self.network_config.gasLimit;
} catch (e) {
return defaultTxOptions.gasLimit;
}
},
set: function() {
throw new Error(
"Don't set config.gas directly. Instead, set config.networks and then config.networks[<network name>].gas"
);
}
},
gasPrice: {
get: function() {
try {
return self.network_config.gasPrice;
} catch (e) {
return defaultTxOptions.gasPrice;
}
},
set: function() {
throw new Error(
"Don't set config.gasPrice directly. Instead, set config.networks and then config.networks[<network name>].gasPrice"
);
}
},
provider: {
get: function() {
if (!self.network) {
return null;
}

const options = self.network_config;
options.verboseRpc = self.verboseRpc;

return Provider.create(options);
},
set: function() {
throw new Error(
"Don't set config.provider directly. Instead, set config.networks and then set config.networks[<network name>].provider"
);
}
}
};

forIn(props, (value, key) => {
self.addProperty(key, value);
});
}

Config.prototype.addProperty = function(propertyName, descriptor = {}) {
Object.defineProperty(this, propertyName, {
get:
descriptor.get ||
function() {
// value is specified
if (propertyName in this._values) {
return this._values[propertyName];
}

// default getter is specified
if (descriptor.default) {
return descriptor.default();
}

// descriptor is a function
return descriptor();
},
set:
descriptor.set ||
function(value) {
this._values[propertyName] = descriptor.transform
? descriptor.transform(value)
: value;
},
configurable: true,
enumerable: true
});
};

Config.prototype.merge = function(obj = {}) {
const self = this;
const clone = _.cloneDeep(obj);

forIn(clone, (value, key) => {
if (self.hasOwnProperty(key)) {
if (typeof clone[key] === 'object' && self._deepCopy.includes(key)) {
self[key] = _.merge(self[key], clone[key]);
} else {
self[key] = clone[key];
}
}
});

return this;
};

Config.search = (options = {}) => {
const configFileName = options.configFile || DEFAULT_CONFIG_FILE;
// if there is no file, getConfigRoot will throw error
return path.join(getConfigRoot(configFileName), configFileName);
};

Config.load = options => {
const file = Config.search(options);

const config = new Config();

const fileConfig = require(file);
// TODO: file 읽지 않고 load/store 할 수 있도록
config.merge(fileConfig);
config.merge(options);

if (!config.network && config.networks.hasOwnProperty(DEFAULT_NETWORK)) {
config.network = DEFAULT_NETWORK;
}

return config;
};

let storedConfig;

Config.get = options => {
if (!storedConfig) {
storedConfig = Config.load(options);
}

return storedConfig;
};

Config.setStore = config => {
if (!(config instanceof Config)) {
throw new TypeError('Should set an instance of Config');
}
storedConfig = config;
};

Config.delete = () => {
storedConfig = undefined;
};

module.exports = Config;
2 changes: 1 addition & 1 deletion packages/vvisp-utils/src/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ module.exports = async function(filePath, options) {
}

async function getSolc() {
const CompilerSupplier = require('./utils/compilerSupplier');
const CompilerSupplier = require('./compilerSupplier');
const supplier = new CompilerSupplier({
version: process.env.SOLC_VERSION
? process.env.SOLC_VERSION
Expand Down
2 changes: 1 addition & 1 deletion packages/vvisp-utils/src/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module.exports = async function(
arguments,
options
) {
const filterPrivateKey = require('./utils/filterPrivateKey');
const filterPrivateKey = require('./filterPrivateKey');
privateKey = filterPrivateKey(privateKey);

if (arguments && arguments.length === undefined) {
Expand Down
4 changes: 2 additions & 2 deletions packages/vvisp-utils/src/getConfigRoot.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module.exports = async function(configFileName) {
module.exports = function(configFileName) {
const findUp = require('find-up');
const path = require('path');

let configPath = await findUp([configFileName]);
let configPath = findUp.sync([configFileName]);
if (!configPath) {
throw new Error(`${configFileName} is not found`);
}
Expand Down
16 changes: 4 additions & 12 deletions packages/vvisp-utils/src/getPrivateKey.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,10 @@ module.exports = function(mnemonic, index) {
.toString('hex');

function checkInputs(mnemonic, index) {
switch (mnemonic) {
case undefined || null:
throw new TypeError(`Input mnemonic is ${mnemonic}`);
default:
if (typeof mnemonic !== 'string') {
throw new TypeError('Input 12 words in string type');
} else {
const wordsNumber = mnemonic.split(' ').length;
if (wordsNumber !== 12) {
throw new TypeError('Input 12 words, not ' + wordsNumber);
}
}
if (typeof mnemonic !== 'string') {
throw new TypeError(
`Input mnemonic is ${mnemonic}, it should be string type`
);
}
switch (index) {
case undefined || null:
Expand Down
6 changes: 6 additions & 0 deletions packages/vvisp-utils/src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
const compile = require('./compile');
const compileAndDeploy = require('./compileAndDeploy');
const compilerSupplier = require('./compilerSupplier');
const Config = require('./Config');
const deploy = require('./deploy');
const filterPrivateKey = require('./filterPrivateKey');
const forIn = require('./forIn');
const forInAsync = require('./forInAsync');
const getAllFiles = require('./getAllFiles');
Expand All @@ -22,7 +25,10 @@ const parseLogs = require('./parseLogs');
module.exports = {
compile,
compileAndDeploy,
compilerSupplier,
Config,
deploy,
filterPrivateKey,
forIn,
forInAsync,
getAllFiles,
Expand Down
2 changes: 1 addition & 1 deletion packages/vvisp-utils/src/privateKeyToAddress.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module.exports = function(privateKey) {
const filterPrivateKey = require('./utils/filterPrivateKey');
const filterPrivateKey = require('./filterPrivateKey');
privateKey = filterPrivateKey(privateKey);
const web3 = require('./getWeb3')();

Expand Down
Loading