@simbachain/hardhat
Version:
Simba Chain plugin for hardhat
445 lines • 17.1 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (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.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.primaryConstructorRequiresArgs = exports.primaryConstructorInputs = exports.getFieldFromPrimaryContractABI = exports.getStorages = exports.getBlockchains = exports.chooseApplicationFromList = exports.getApp = exports.writeAndReturnASTSourceAndCompiler = exports.chooseOrganisationFromInput = exports.chooseOrganisationFromList = void 0;
/*
NOTE:
this file will actually come from the standalone web3 repo
it is just included here for now for testing purposes
*/
const prompts_1 = __importDefault(require("prompts"));
const lib_1 = require("../lib");
const _1 = require("./");
const fs = __importStar(require("fs"));
const chalk_1 = __importDefault(require("chalk"));
const getList = async (config, url) => {
lib_1.log.debug(`:: ENTER :`);
if (!url) {
url = 'v2/organisations/';
}
try {
const res = config.authStore.doGetRequest(url);
lib_1.log.debug(`:: EXIT : ${JSON.stringify(res)}`);
return res;
}
catch (e) {
const err = e;
if (err.message === "Request failed with status code 500") {
lib_1.log.info(`${chalk_1.default.cyanBright('\nsimba: Auth token expired, please log in again')}`);
lib_1.SimbaConfig.authStore.logout();
await lib_1.SimbaConfig.authStore.loginAndGetAuthToken();
}
}
};
exports.chooseOrganisationFromList = async (config, url) => {
lib_1.log.debug(`:: ENTER : ${JSON.stringify(config)}`);
if (!url) {
url = 'organisations/';
}
const orgResponse = await getList(config, url);
if (!orgResponse) {
lib_1.log.error(`${chalk_1.default.redBright('\nsimba: EXIT : no organizations returned. You probably need to log in again')}`);
return;
}
const orgs = {
next: orgResponse.next,
prev: orgResponse.prev,
data: orgResponse.results.reduce((map, obj) => {
const data = Object.assign(Object.assign({}, obj), { id: obj.id });
map[data.name] = data;
return map;
}, {}),
};
const choices = [];
if (orgs.prev) {
choices.push({
title: '<-',
description: 'Previous choices',
value: 'prev'
});
}
if (orgs.next) {
choices.push({ title: '->', description: 'Next choices', value: 'next' });
}
for (const [key, val] of Object.entries(orgs.data)) {
choices.push({ title: key, value: val });
}
const response = await prompts_1.default({
type: 'select',
name: 'organisation',
message: 'Please pick an organisation',
choices,
});
if (response.organisation === 'prev') {
return exports.chooseOrganisationFromList(config, orgs.prev);
}
else if (response.organisation === 'next') {
return exports.chooseOrganisationFromList(config, orgs.next);
}
if (!response.organisation) {
lib_1.log.error(`${chalk_1.default.redBright('\nsimba: EXIT : No Organisation Selected!')}`);
throw new Error('No Organisation Selected!');
}
config.organisation = response.organisation;
lib_1.log.debug(`:: EXIT : ${JSON.stringify(response.organisation)}`);
return response.organisation;
};
async function chooseOrganisationFromInput(config, url) {
console.error("needs to be implemented");
}
exports.chooseOrganisationFromInput = chooseOrganisationFromInput;
function parseBuildInfoJsonName(location) {
lib_1.log.debug(`:: ENTER : ${location}`);
if (location.includes("/")) {
const idArr = location.split("/");
const jsonName = idArr[idArr.length - 1];
lib_1.log.debug(`:: EXIT : ${jsonName}`);
return jsonName;
}
else {
lib_1.log.debug(`:: EXIT : ${location}`);
return location;
}
}
async function buildInfoJsonName(contractName, contractSourceName) {
lib_1.log.debug(`:: ENTER : ${contractName}`);
const buildDir = lib_1.SimbaConfig.buildDirectory;
let files = [];
try {
files = await _1.walkDirForContracts(buildDir, ".json");
}
catch (e) {
const err = e;
if (err.code === 'ENOENT') {
lib_1.log.error(`${chalk_1.default.redBright('\nsimba: EXIT : Simba was not able to find any build info artifacts.\nDid you forget to run: "npx hardhat compile" ?\n')}`);
return "";
}
lib_1.log.error(`:: EXIT : ERROR : ${JSON.stringify(err)}`);
return "";
}
for (const file of files) {
if (!(file.endsWith(`${contractSourceName}/${contractName}.dbg.json`))) {
continue;
}
else {
const buf = await _1.promisifiedReadFile(file, { flag: 'r' });
const parsed = JSON.parse(buf.toString());
const location = parsed.buildInfo;
const jsonName = parseBuildInfoJsonName(location);
lib_1.log.debug(`:: EXIT : ${jsonName}`);
return jsonName;
}
}
lib_1.log.error(`${chalk_1.default.redBright('\nsimba: EXIT : no info found for contract')}`);
return "";
}
async function astSourceAndCompiler(contractName, contractSourceName, _buildInfoJsonName) {
const params = {
contractName,
_buildInfoJsonName,
};
lib_1.log.debug(`:: ENTER : ${JSON.stringify(params)}`);
const buildInfoDir = lib_1.SimbaConfig.buildInfoDirectory;
let files = [];
let astAndSourceAndCompiler = {
"ast": {},
"source": {},
"compiler": "",
};
try {
files = await _1.walkDirForContracts(buildInfoDir, ".json");
lib_1.log.debug(`:: files : ${JSON.stringify(files)}`);
}
catch (e) {
const err = e;
if (err.code === 'ENOENT') {
lib_1.log.error(`${chalk_1.default.redBright('\nsimba: EXIT : Simba was not able to find any build info artifacts.\nDid you forget to run: "npx hardhat compile" ?\n')}`);
return astAndSourceAndCompiler;
}
lib_1.log.error(`${chalk_1.default.redBright(`\nsimba: EXIT : ${JSON.stringify(err)}`)}`);
return astAndSourceAndCompiler;
}
for (const file of files) {
if (!(file.endsWith(_buildInfoJsonName))) {
continue;
}
else {
const buf = await _1.promisifiedReadFile(file, { flag: 'r' });
const parsed = JSON.parse(buf.toString());
const output = parsed.output;
const outputSources = output.sources;
const outputContractSource = outputSources[contractSourceName];
const ast = outputContractSource.ast;
astAndSourceAndCompiler.ast = ast;
const solcVersion = parsed.solcVersion;
astAndSourceAndCompiler.compiler = solcVersion;
const input = parsed.input;
const inputSources = input.sources;
const inputContractSource = inputSources[contractSourceName];
const contractSourceCode = inputContractSource.content;
astAndSourceAndCompiler.source = contractSourceCode;
lib_1.log.debug(`:: EXIT : ${JSON.stringify(astAndSourceAndCompiler)}`);
return astAndSourceAndCompiler;
}
}
lib_1.log.error(`:: EXIT : ERROR : no contract info found`);
return astAndSourceAndCompiler;
}
async function getASTSourceAndCompiler(contractName, contractSourceName) {
const entryParams = {
contractName,
contractSourceName,
};
lib_1.log.debug(`:: ENTER : ${JSON.stringify(entryParams)}`);
const _buildInfoJsonName = await buildInfoJsonName(contractName, contractSourceName);
const _astAndSourceAndCompiler = await astSourceAndCompiler(contractName, contractSourceName, _buildInfoJsonName);
if (_astAndSourceAndCompiler.ast === {}) {
const message = `no ast found for ${contractName}`;
lib_1.log.error(`${chalk_1.default.redBright(`\nsimba: EXIT : ${message}`)}`);
return new Error(`${message}`);
}
lib_1.log.debug(`:: EXIT : ${JSON.stringify(_astAndSourceAndCompiler)}`);
return _astAndSourceAndCompiler;
}
async function writeAndReturnASTSourceAndCompiler(contractName, contractSourceName) {
const entryParams = {
contractName,
contractSourceName,
};
lib_1.log.debug(`:: ENTER : ${JSON.stringify(entryParams)}`);
const _astSourceAndCompiler = await getASTSourceAndCompiler(contractName, contractSourceName);
const buildDir = lib_1.SimbaConfig.buildDirectory;
const sourceFileName = contractSourceName.split("/")[1];
const filePath = `${buildDir}/${sourceFileName}/${contractName}.json`;
const files = await _1.walkDirForContracts(buildDir, ".json");
for (const file of files) {
if (!(file.endsWith(`${contractName}.json`))) {
continue;
}
const buf = await _1.promisifiedReadFile(file, { flag: 'r' });
const parsed = JSON.parse(buf.toString());
parsed.ast = _astSourceAndCompiler.ast;
parsed.source = _astSourceAndCompiler.source;
const data = JSON.stringify(parsed);
lib_1.log.debug(`:: writing to ${filePath}`);
fs.writeFileSync(filePath, data);
lib_1.log.debug(`:: EXIT : ${JSON.stringify(_astSourceAndCompiler)}`);
return _astSourceAndCompiler;
}
return _astSourceAndCompiler;
}
exports.writeAndReturnASTSourceAndCompiler = writeAndReturnASTSourceAndCompiler;
async function getApp(config, id) {
lib_1.log.debug(`:: ENTER : ${id}`);
const url = `organisations/${config.organisation.id}/applications/${id}`;
const response = await config.authStore.doGetRequest(url, 'application/json');
lib_1.log.debug(`:: EXIT : ${JSON.stringify(response)}`);
return response;
}
exports.getApp = getApp;
;
async function chooseApplicationFromList(config, url) {
const entryParams = {
config,
url,
};
lib_1.log.debug(`:: ENTER : ${JSON.stringify(entryParams)}`);
if (!url) {
url = `organisations/${config.organisation.id}/applications/`;
}
const appResponse = await getList(config, url);
if (!appResponse) {
lib_1.log.error(`${chalk_1.default.redBright('\nsimba: EXIT : no applications in list. You probably need to login again.')}`);
return;
}
const apps = {
next: appResponse.next,
prev: appResponse.prev,
data: appResponse.results.reduce((map, obj) => {
const data = Object.assign(Object.assign({}, obj), { id: obj.id });
map[data.display_name] = data;
return map;
}, {}),
};
const choices = [];
if (apps.prev) {
choices.push({
title: '<-',
description: 'Previous choices',
value: 'prev'
});
}
if (apps.next) {
choices.push({ title: '->', description: 'Next choices', value: 'next' });
}
for (const [key, val] of Object.entries(apps.data)) {
choices.push({ title: key, value: val });
}
const response = await prompts_1.default({
type: 'select',
name: 'application',
message: 'Please pick an application',
choices,
});
if (response.application === 'prev') {
return chooseApplicationFromList(config, apps.prev);
}
else if (response.application === 'next') {
return chooseApplicationFromList(config, apps.next);
}
if (!response.application) {
lib_1.log.error(`${chalk_1.default.redBright('\nsimba: EXIT : No Application Selected!')}`);
throw new Error('No Application Selected!');
}
config.application = response.application;
lib_1.log.debug(`:: EXIT : ${JSON.stringify(response.application)}`);
return response.application;
}
exports.chooseApplicationFromList = chooseApplicationFromList;
;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async function getBlockchains(config, url) {
const entryParams = {
config,
url,
};
lib_1.log.debug(`:: ENTER : ${JSON.stringify(entryParams)}`);
if (!url) {
url = `organisations/${config.organisation.id}/blockchains/`;
}
const chains = await getList(config, url);
const choices = [];
chains.results.forEach((chain) => {
choices.push({
title: chain.display_name,
value: chain.name,
});
});
lib_1.log.debug(`:: EXIT : ${JSON.stringify(choices)}`);
return choices;
}
exports.getBlockchains = getBlockchains;
;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async function getStorages(config, url) {
const entryParams = {
config,
url,
};
lib_1.log.debug(`:: ENTER : ${JSON.stringify(entryParams)}`);
if (!url) {
url = `organisations/${config.organisation.id}/storage/`;
}
const storages = await getList(config, url);
const choices = [];
storages.results.forEach((storage) => {
choices.push({
title: storage.display_name,
value: storage.name,
});
});
lib_1.log.debug(`:: EXIT : ${JSON.stringify(choices)}`);
return choices;
}
exports.getStorages = getStorages;
;
// the following code is for merging AST for a contract into build artifact for that contract
async function getABIForPrimaryContract() {
lib_1.log.debug(`:: ENTER :`);
const contractName = lib_1.SimbaConfig.ProjectConfigStore.get("primary");
if (!contractName) {
lib_1.log.error(`${chalk_1.default.redBright('\nsimba: EXIT : no primary contract in simba.json')}`);
return "";
}
const buildDir = lib_1.SimbaConfig.buildDirectory;
const files = await _1.walkDirForContracts(buildDir, ".json");
for (const file of files) {
if (!(file.endsWith(`${contractName}.json`))) {
continue;
}
const buf = await _1.promisifiedReadFile(file, { flag: 'r' });
const parsed = JSON.parse(buf.toString());
const abi = parsed.abi;
lib_1.log.debug(`:: EXIT : ${JSON.stringify(abi)}`);
return abi;
}
}
async function getFieldFromPrimaryContractABI(name) {
lib_1.log.debug(`:: ENTER : ${name}`);
const abi = await getABIForPrimaryContract();
for (let i = 0; i < abi.length; i++) {
const entry = abi[i];
if (entry.name === name) {
lib_1.log.debug(`:: EXIT : ${JSON.stringify(entry)}`);
return entry;
}
}
lib_1.log.debug(`:: EXIT : {}`);
return {};
}
exports.getFieldFromPrimaryContractABI = getFieldFromPrimaryContractABI;
async function primaryContractConstructor() {
lib_1.log.debug(`:: ENTER :`);
const abi = await getABIForPrimaryContract();
for (let i = 0; i < abi.length; i++) {
const entry = abi[i];
if (entry.type === "constructor") {
lib_1.log.debug(`:: EXIT : ${JSON.stringify(entry)}`);
return entry;
}
}
lib_1.log.debug(`:: EXIT : {}`);
return {};
}
async function primaryConstructorInputs() {
lib_1.log.debug(`:: ENTER :`);
const constructor = await primaryContractConstructor();
const constructorInputs = constructor.inputs ? constructor.inputs : [];
const inputs = [];
for (let i = 0; i < constructorInputs.length; i++) {
const input = constructorInputs[i];
const type = input.type;
const name = input.name;
inputs.push({
type,
name,
});
}
lib_1.log.debug(`:: EXIT : ${JSON.stringify(inputs)}`);
return inputs;
}
exports.primaryConstructorInputs = primaryConstructorInputs;
async function primaryConstructorRequiresArgs() {
lib_1.log.debug(`:: ENTER :`);
const constructor = await primaryContractConstructor();
const inputs = constructor.inputs;
let requiresArgs = false;
if (inputs && inputs.length > 0) {
requiresArgs = true;
}
lib_1.log.debug(`:: EXIT : ${requiresArgs}`);
return requiresArgs;
}
exports.primaryConstructorRequiresArgs = primaryConstructorRequiresArgs;
//# sourceMappingURL=api.js.map