diff --git a/scripts/addConnector.ts b/scripts/addConnector.ts index 06af1c7a..1090132d 100644 --- a/scripts/addConnector.ts +++ b/scripts/addConnector.ts @@ -8,16 +8,22 @@ */ import Web3 from "web3"; -import inquirer from "inquirer" -import {connectorsV1} from '../src/addresses/mainnet/connectorsV1' -import {connectorsV2_M1} from '../src/addresses/mainnet/connectorsV2_M1' -import { Obj, appendFile, checkFile, readFile, writeFile, getAbiDir, getAbiPath, getAbiTemplate, addressV1Path, addressV2Path, getABI } from "./utils"; +import inquirer from "inquirer"; +import { connectorsV1 as mConnectorsV1 } from '../src/addresses/mainnet/connectorsV1'; +import { connectorsV2_M1 as mConnectorsV2_M1 } from '../src/addresses/mainnet/connectorsV2_M1'; +import { connectorsV1 as pConnectorsV1 } from "../src/addresses/polygon/connectorsV1"; +import { connectorsV2_M1 as pConnectorsV2_M1 } from '../src/addresses/polygon/connectorsV2_M1'; +import { Obj, checkFile, getAbiDir, getAbiPath, getAbiTemplate, mainnetAddressV1Path, mainnetAddressV2Path, polygonAddressV1Path, polygonAddressV2Path, getABI } from "./utils"; +import fs from 'fs' -const mainnetConnectorsV1 = connectorsV1 as Obj; -const mainnetConnectorsV2 = connectorsV2_M1 as Obj; +const mainnetConnectorsV1 = mConnectorsV1 as Obj; +const mainnetConnectorsV2 = mConnectorsV2_M1 as Obj; +const polygonConnectorsV1 = pConnectorsV1 as Obj; +const polygonConnectorsV2 = pConnectorsV2_M1 as Obj; let connectorsV1Template = `export const connectorsV1 = `; let connectorsV2Template = `export const connectorsV2_M1 = `; +const abiChoices = ["From Address (Only for Mainnet)", "From JSON File Path", "From JSON (via URL)"] const questions = [ { type: "input", @@ -32,12 +38,12 @@ const questions = [ validate: (name: string) => { try { Function('var ' + name); - } catch(_) { + } catch (_) { return false || "Connector variable name is required!" } - return true; - } - }, + return true; + } + }, { type: "list", name: "version", @@ -48,58 +54,101 @@ const questions = [ type: "input", name: "address", message: "What's the connector address?", - validate: (address: string) => Web3.utils.isAddress(address) || "Enter a valid address!" + validate: (address: string) => Web3.utils.isAddress(address) || "Enter a valid address!" + }, + { + type: "list", + name: "chain", + message: "Which Chain?", + choices: ["Mainnet", "Polygon"] + }, + { + type: "list", + name: "abi_type", + message: "How to get the ABI?", + choices: abiChoices, } ]; (async () => { const answers = await inquirer.prompt(questions); - const abi = await getABI(answers.address); + const abi_idx = abiChoices.indexOf(answers.abi_type) + if (answers.chain === "Polygon" && abi_idx === 0) { + console.log("\n\nāŒ Sorry but Fetching ABI from address only works with Mainnet āŒ\n") + process.exit(0); + } + + const abi = await getABI(abi_idx, answers); await checkFile(getAbiPath(answers)) if (answers.version === 1) { - if (mainnetConnectorsV1[answers.variable_name]) { - throw new Error("Mainnet Connectors V1 already contains " + answers.variable); - } - mainnetConnectorsV1[answers.variable_name] = answers.address; - connectorsV1Template += JSON.stringify(mainnetConnectorsV1, null, 4); + if (answers.chain === "Mainnet") { + if (mainnetConnectorsV1[answers.variable_name]) { + throw new Error("Mainnet Connectors V1 already contains " + answers.variable); + } + mainnetConnectorsV1[answers.variable_name] = answers.address; + connectorsV1Template += JSON.stringify(mainnetConnectorsV1, null, 4); - // save the file - await writeFile(addressV1Path, connectorsV1Template); - console.log(`šŸš€ ${addressV1Path} [updated]`) - } else { - if (mainnetConnectorsV2[answers.name]) { - throw new Error("Mainnet Connectors V2 already contains " + answers.name); + // save the file + fs.writeFileSync(mainnetAddressV1Path, connectorsV1Template); + console.log(`šŸš€ ${mainnetAddressV1Path} [updated]`) + } else { + if (polygonConnectorsV1[answers.variable_name]) { + throw new Error("Polygon Connectors V1 already contains " + answers.variable_name); + } + polygonConnectorsV1[answers.variable_name] = answers.address; + connectorsV1Template += JSON.stringify(polygonConnectorsV1, null, 4); + + // save the file + fs.writeFileSync(polygonAddressV1Path, connectorsV1Template) + console.log(`šŸš€ ${polygonAddressV1Path} [updated]`) } - mainnetConnectorsV2[answers.name] = answers.address; - connectorsV2Template += JSON.stringify(mainnetConnectorsV2, null, 4); + } else { + if (answers.chain === "Mainnet") { + if (mainnetConnectorsV2[answers.name]) { + throw new Error("Mainnet Connectors V2 already contains " + answers.name); + } + mainnetConnectorsV2[answers.name] = answers.address; + connectorsV2Template += JSON.stringify(mainnetConnectorsV2, null, 4); - // save the file - await writeFile(addressV2Path, connectorsV2Template); - console.log(`šŸš€ ${addressV2Path} [updated]`) + // save the file + fs.writeFileSync(mainnetAddressV2Path, connectorsV2Template); + console.log(`šŸš€ ${mainnetAddressV2Path} [updated]`) + + } else { + if (polygonConnectorsV2[answers.name]) { + throw new Error("Polygon Connectors V2 already contains " + answers.name); + } + polygonConnectorsV2[answers.name] = answers.address; + connectorsV2Template += JSON.stringify(polygonConnectorsV2, null, 4); + + // save the file + fs.writeFileSync(polygonAddressV2Path, connectorsV2Template); + console.log(`šŸš€ ${polygonAddressV2Path} [updated]`) + } } const abiFileContent = getAbiTemplate(answers.variable_name, abi); - await writeFile(getAbiPath(answers), abiFileContent); + await fs.writeFileSync(getAbiPath(answers), abiFileContent); console.log(`šŸš€ ${getAbiPath(answers)} [created]`) const abiDir = getAbiDir(answers); if (answers.version === 1) { - await appendFile(`${abiDir}/index.ts`, `export * from './${answers.name}'`); + fs.appendFileSync(`${abiDir}/index.ts`, `export * from './${answers.name}'`); console.log(`šŸš€ ${abiDir}/index.ts [updated]`) } else { - const content = await readFile(`${abiDir}/index.ts`); + const content = fs.readFileSync(`${abiDir}/index.ts`, 'utf-8'); const match = /export/.exec(content)!; let beforeExport = content.slice(0, match.index).trim(); let afterExport = content.slice(match.index, content.length).split(`{\n`); beforeExport += `\nimport {${answers.variable_name}} from './${answers.name}'`; - + const final = `${beforeExport}\n${afterExport[0]}{\n "${answers.name}": ${answers.variable_name},\n${afterExport[1]}`; // save the file - await writeFile(`${abiDir}/index.ts`, final); + await fs.writeFileSync(`${abiDir}/index.ts`, final); console.log(`šŸš€ ${abiDir}/index.ts [updated]`) } })(); \ No newline at end of file diff --git a/scripts/utils.ts b/scripts/utils.ts index 0e6feda1..48deec9f 100644 --- a/scripts/utils.ts +++ b/scripts/utils.ts @@ -1,12 +1,15 @@ import * as fs from 'fs'; +import inquirer from 'inquirer'; import fetch from 'node-fetch'; +import URL from "url"; +import Path from "path" export interface Obj { [key: string]: string; } export const checkFile = (fileName: string) => { - return new Promise((resolve ,reject) => { + return new Promise((resolve, reject) => { fs.access(fileName, (err) => { if (err) return resolve(null); @@ -15,50 +18,58 @@ export const checkFile = (fileName: string) => { }) } -export const writeFile = (filePath: string, fileContent: string) => { - return new Promise((resolve, reject) => { - fs.writeFile(filePath, fileContent, (err) => { - if (err) return reject(err); - - return resolve(null); - }) - }) -} - -export const appendFile = (filePath: string, fileContent: string) => { - return new Promise((resolve, reject) => { - fs.appendFile(filePath, fileContent, (err) => { - if (err) return reject(err); - - return resolve(null); - }); - }); -} - -export const readFile = (filePath: string): Promise => { - return new Promise((resolve, reject) => { - fs.readFile(filePath, 'utf-8', (err, content) => { - if (err) return reject(err); - - return resolve(content); - }) - }) -} - - export const getAbiPath = (answers: Obj) => `src/abi/connectors/v${answers.version}/${answers.name}.ts`; export const getAbiDir = (answers: Obj) => `src/abi/connectors/v${answers.version}`; -export const addressV1Path = `src/addresses/mainnet/connectorsV1.ts`; -export const addressV2Path = `src/addresses/mainnet/connectorsV2_M1.ts`; +export const mainnetAddressV1Path = `src/addresses/mainnet/connectorsV1.ts`; +export const mainnetAddressV2Path = `src/addresses/mainnet/connectorsV2_M1.ts`; +export const polygonAddressV1Path = `src/addresses/polygon/connectorsV1.ts`; +export const polygonAddressV2Path = `src/addresses/polygon/connectorsV2_M1.ts`; export const getAbiTemplate = (varName: string, abi: string) => ` import { AbiItem } from 'web3-utils' export const ${varName}: AbiItem[] = ${abi} `.trim(); -export const getABI = async (address: string): Promise => { +export const getABI = async (abi_idx: number, answers: Obj): Promise => { console.log('šŸ”® Fetching ABI') - const res = await fetch(`https://api.etherscan.io/api?module=contract&action=getabi&address=${address}&apikey=${process.env.API_KEY_TOKEN}`); - const {result} = await res.json(); - return result; + + if (abi_idx === 0) { + const res = await fetch(`https://api.etherscan.io/api?module=contract&action=getabi&address=${answers.address}&apikey=${process.env.API_KEY_TOKEN}`); + const { result } = await res.json(); + return result; + } else if (abi_idx === 1) { + const data = await inquirer.prompt([ + { + type: "input", + name: "path", + message: "Enter the JSON File Path:", + validate: (value: string) => !!value || "File Path is required." + } + ]); + + + + return JSON.stringify(fs.readFileSync(Path.resolve(data.path), 'utf-8')); + } else { + const data = await inquirer.prompt([ + { + type: "input", + name: "url", + message: "Enter the URL:", + validate: (value: string) => { + try { + new URL.URL(value) + return true; + } catch (e) { + return "Wrong URL Entered." + } + } + } + ]) + + const res = await fetch(data.url); + const json = res.json(); + + return JSON.stringify(json); + } } \ No newline at end of file