@titan-suite/cli
Version:
The complete smart contract development tool
209 lines (208 loc) • 7.96 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const command_1 = require("@oclif/command");
const core_1 = require("@titan-suite/core");
const cli_ux_1 = require("cli-ux");
const fs = require("fs");
const inquirer_1 = require("inquirer");
const mkdirp = require("mkdirp");
const notifier = require("node-notifier");
const path = require("path");
const index_1 = require("../utils/index");
class Deploy extends command_1.Command {
constructor() {
super(...arguments);
this.contractChoicePrompt = [
{
type: 'list',
name: 'selected_contract',
message: 'Choose a contract to deploy',
choices: []
}
];
this.privateKeyPrompt = [
{
type: 'password',
name: 'privateKey',
message: 'private key'
}
];
this.deployToMainnetPrompt = [
{
type: 'list',
name: 'confirm',
message: "You're about to deploy to the mainnet. Would you like to proceed?",
choices: ['Yes', 'No']
}
];
}
generateChoices(arr) {
for (let i of arr) {
this.contractChoicePrompt[0].choices.push(i);
}
}
deploy(boltData) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const { name, abi, bytecode } = boltData;
if (!name || !abi || !bytecode) {
this.error('The required bolt json is incomplete. Try compiling the contract again.');
this.exit(0);
}
const compiledContract = {
[name]: {
info: {
abiDefinition: abi
},
code: bytecode
}
};
return this.handleDeploy(name, compiledContract);
});
}
handleDeploy(name, compiledContract, params, privateKey, targetNetwork) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
cli_ux_1.default.action.start('deploying');
const abi = compiledContract[`${name}`].info.abiDefinition;
const code = compiledContract[`${name}`].code;
const { txReceipt, error } = yield index_1.deploy({
abi,
code,
args: params,
privateKey
}, targetNetwork);
if (error) {
this.error(/Error:\s+(.+)/gi.exec(error)[1]);
}
const timeStamp = new Date();
const deployedAt = timeStamp.getTime();
const currentNetwork = index_1.getCurrentNetwork();
const boltsPath = path.join(process.cwd(), 'build', 'bolts', `${name}.json`);
const exists = fs.existsSync(boltsPath);
let migrations = [];
const newMigration = {
[deployedAt]: {
network: currentNetwork,
address: txReceipt.contractAddress,
transactionHash: txReceipt.transactionHash,
blockNumber: txReceipt.blockNumber
}
};
if (exists) {
const data = index_1.readUtf8(boltsPath);
const bolt = JSON.parse(data);
migrations = 'migrations' in bolt ? bolt.migrations : [];
migrations.push(newMigration);
}
else {
migrations.push(newMigration);
}
mkdirp('build/bolts', err => {
if (err) {
throw err;
}
else {
const bolt = {
name,
abi,
bytecode: code,
migrations,
updated: timeStamp.toString()
};
fs.writeFile(boltsPath, JSON.stringify(bolt, null, 4), err => {
if (err)
throw err;
});
}
});
cli_ux_1.default.action.stop();
notifier.notify({
title: 'Titan',
message: `🚀 Successfully deployed: ${name}!`
});
return txReceipt.contractAddress;
});
}
run() {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const { args, flags } = this.parse(Deploy);
if (flags.network) {
const nodeAddress = index_1.getProvider(flags.network);
const aion = new core_1.Aion(nodeAddress);
const netId = yield aion.getNetworkId();
if ((netId === 256 || netId === 32) && !flags.privateKey) {
this.error('You must set the private key flag to deploy to this network. Run again with -k or run "titan deploy --help"');
}
}
if (flags.network === 'mainnet') {
const answer = yield inquirer_1.prompt(this.deployToMainnetPrompt);
answer.confirm === 'No'
? this.exit(0)
: this.warn('Proceeding to deploy to mainnet');
}
const sol = index_1.readContract(args.file);
const compiledContract = yield index_1.compile(sol, false);
let contractName;
let privateKey;
let targetNetwork = flags.network ? flags.network : '';
const params = flags.params ? flags.params : [];
if (flags.privateKey) {
const answer = yield inquirer_1.prompt(this.privateKeyPrompt);
privateKey = answer.privateKey;
if (privateKey && privateKey.length === 130) {
}
else {
this.error('Please provide a valid private key');
}
}
if (flags.name) {
contractName = flags.name;
}
else if (Object.keys(compiledContract).length === 1) {
contractName = Object.keys(compiledContract)[0];
}
else {
this.generateChoices(Object.keys(compiledContract));
const answer = yield inquirer_1.prompt(this.contractChoicePrompt);
contractName = answer.selected_contract;
}
try {
compiledContract[`${contractName}`].info;
}
catch (_a) {
this.error('The specified contract name does not exist');
}
yield this.handleDeploy(contractName, compiledContract, params, privateKey, targetNetwork);
});
}
}
Deploy.description = 'Deploy a Solidity smart contract to an AION node';
Deploy.examples = [
'$ titan deploy <path/to/Example.sol>',
'$ titan deploy -n SpecificContract <path/to/ManyContracts.sol>',
'$ titan deploy -p 5 <path/to/ContractWithParams.sol>',
'$ titan deploy -k <path/to/ContractWithParams.sol>',
'$ titan deploy -t development <path/to/ContractWithParams.sol>'
];
Deploy.flags = {
help: command_1.flags.help({ char: 'h' }),
name: command_1.flags.string({
char: 'n',
description: 'specify which smart contract to deploy within the file'
}),
params: command_1.flags.string({
char: 'p',
description: 'pass parameters to the smart contract',
multiple: true
}),
privateKey: command_1.flags.boolean({
char: 'k',
description: 'pass parameters to the smart contract'
}),
network: command_1.flags.string({
char: 't',
description: 'specify the network to deploy the smart contract'
})
};
Deploy.args = [{ name: 'file' }];
exports.default = Deploy;