diff --git a/libs/ghaction/.eslintrc b/libs/ghaction-helper/.eslintrc similarity index 100% rename from libs/ghaction/.eslintrc rename to libs/ghaction-helper/.eslintrc diff --git a/libs/ghaction/.npmignore b/libs/ghaction-helper/.npmignore similarity index 100% rename from libs/ghaction/.npmignore rename to libs/ghaction-helper/.npmignore diff --git a/libs/ghaction/README.md b/libs/ghaction-helper/README.md similarity index 100% rename from libs/ghaction/README.md rename to libs/ghaction-helper/README.md diff --git a/libs/ghaction-helper/package.json b/libs/ghaction-helper/package.json new file mode 100644 index 0000000000..a0f55fbb9e --- /dev/null +++ b/libs/ghaction-helper/package.json @@ -0,0 +1,32 @@ +{ + "name": "@remix-project/ghaction-helper", + "version": "0.1.0-dev", + "description": "Solidity Tests GitHub Action Helper", + "main": "dist/index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "build": "tsc" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ethereum/remix-project.git" + }, + "keywords": [], + "author": "@ioedeveloper", + "license": "ISC", + "bugs": { + "url": "https://github.com/ethereum/remix-project/issues" + }, + "homepage": "https://github.com/ethereum/remix-project#readme", + "devDependencies": { + "@remix-project/remix-solidity": "^0.5.6", + "@types/chai": "^4.3.4", + "typescript": "^4.9.3" + }, + "dependencies": { + "@ethereum-waffle/chai": "^3.4.4", + "chai": "^4.3.7", + "ethers": "^5.7.2", + "ganache": "^7.5.0" + } +} \ No newline at end of file diff --git a/libs/ghaction-helper/src/artifacts-helper.ts b/libs/ghaction-helper/src/artifacts-helper.ts new file mode 100644 index 0000000000..6e1b78ad2c --- /dev/null +++ b/libs/ghaction-helper/src/artifacts-helper.ts @@ -0,0 +1,25 @@ +import { CompilationResult } from '@remix-project/remix-solidity' +//@ts-ignore +import * as fs from 'fs/promises' +import * as path from 'path' + +declare global { + const remixContractArtifactsPath: string +} + +export async function getArtifactsByContractName (contractIdentifier: string) { + //@ts-ignore + const contractArtifacts = await fs.readdir(global.remixContractArtifactsPath) + let contract + + for (const artifactFile of contractArtifacts) { + //@ts-ignore + const artifact = await fs.readFile(path.join(global.remixContractArtifactsPath, artifactFile), 'utf-8') + const artifactJSON: CompilationResult = JSON.parse(artifact) + const contractFullPath = (Object.keys(artifactJSON.contracts!)).find((contractName) => artifactJSON.contracts![contractName] && artifactJSON.contracts![contractName][contractIdentifier]) + + contract = contractFullPath ? artifactJSON.contracts![contractFullPath!][contractIdentifier] : undefined + if (contract) break + } + return contract +} diff --git a/libs/ghaction/src/chai.ts b/libs/ghaction-helper/src/chai.ts similarity index 81% rename from libs/ghaction/src/chai.ts rename to libs/ghaction-helper/src/chai.ts index f27c0f0232..1f15ca9ec8 100644 --- a/libs/ghaction/src/chai.ts +++ b/libs/ghaction-helper/src/chai.ts @@ -3,5 +3,6 @@ import { waffleChai } from '@ethereum-waffle/chai' chai.use(waffleChai) +// @ts-ignore export * from 'chai' -export { chai } +export { chai } \ No newline at end of file diff --git a/libs/ghaction-helper/src/ethers.ts b/libs/ghaction-helper/src/ethers.ts new file mode 100644 index 0000000000..d3941e6dd4 --- /dev/null +++ b/libs/ghaction-helper/src/ethers.ts @@ -0,0 +1,8 @@ +// @ts-nocheck +import { ethers } from 'ethers' +import * as hhEtherMethods from './methods' + +for(const method in hhEtherMethods) Object.defineProperty(ethers, method, { value: hhEtherMethods[method]}) + +export * from 'ethers' +export { ethers } \ No newline at end of file diff --git a/libs/ghaction-helper/src/index.ts b/libs/ghaction-helper/src/index.ts new file mode 100644 index 0000000000..2ead5cf605 --- /dev/null +++ b/libs/ghaction-helper/src/index.ts @@ -0,0 +1,2 @@ +export * from './chai' +export * from './ethers' diff --git a/libs/ghaction/src/methods.ts b/libs/ghaction-helper/src/methods.ts similarity index 80% rename from libs/ghaction/src/methods.ts rename to libs/ghaction-helper/src/methods.ts index 9669fea72c..82c420f3f6 100644 --- a/libs/ghaction/src/methods.ts +++ b/libs/ghaction-helper/src/methods.ts @@ -1,16 +1,24 @@ +// @ts-ignore import { ethers } from "ethers" -import { getArtefactsByContractName } from './artefacts-helper' +//@ts-ignore +import * as ganache from "ganache" +import { getArtifactsByContractName } from './artifacts-helper' import { SignerWithAddress } from './signer' declare global { const ganacheProvider: any } -const isFactoryOptions = (signerOrOptions) => { +const initializeProvider = () => { + //@ts-ignore + global.ganacheProvider = ganache.provider({ logging: { quiet: true } }) +} + +const isFactoryOptions = (signerOrOptions: any) => { if (!signerOrOptions || signerOrOptions === undefined || signerOrOptions instanceof ethers.Signer) return false return true } -const isArtifact = (artifact) => { +const isArtifact = (artifact: any) => { const { contractName, sourceName, @@ -32,11 +40,12 @@ const isArtifact = (artifact) => { ) } -function linkBytecode(artifact, libraries) { +function linkBytecode(artifact: any, libraries: any) { let bytecode = artifact.bytecode for (const { sourceName, libraryName, address } of libraries) { const linkReferences = artifact.linkReferences[sourceName][libraryName] + for (const { start, length } of linkReferences) { bytecode = bytecode.substr(0, 2 + start * 2) + @@ -48,9 +57,10 @@ function linkBytecode(artifact, libraries) { return bytecode } -const collectLibrariesAndLink = async (artifact, libraries) => { +const collectLibrariesAndLink = async (artifact: any, libraries: any) => { const neededLibraries = [] for (const [sourceName, sourceLibraries] of Object.entries(artifact.linkReferences)) { + // @ts-ignore for (const libName of Object.keys(sourceLibraries)) { neededLibraries.push({ sourceName, libName }) } @@ -58,6 +68,7 @@ const collectLibrariesAndLink = async (artifact, libraries) => { const linksToApply = new Map() for (const [linkedLibraryName, linkedLibraryAddress] of Object.entries(libraries)) { + // @ts-ignore if (!ethers.utils.isAddress(linkedLibraryAddress)) { throw new Error( `You tried to link the contract ${artifact.contractName} with the library ${linkedLibraryName}, but provided this invalid address: ${linkedLibraryAddress}` @@ -136,11 +147,12 @@ const collectLibrariesAndLink = async (artifact, libraries) => { ) } + // @ts-ignore return linkBytecode(artifact, [...linksToApply.values()]) } // Convert output.contracts.. in Artifact object compatible form -const resultToArtifact = (result) => { +const resultToArtifact = (result: any) => { const { fullyQualifiedName, artefact } = result return { contractName: fullyQualifiedName.split(':')[1], @@ -154,15 +166,17 @@ const resultToArtifact = (result) => { } const getContractFactory = async (contractNameOrABI: ethers.ContractInterface, bytecode?: string, signerOrOptions = null) => { + //@ts-ignore + if (!global.ganacheProvider) initializeProvider() if (bytecode && contractNameOrABI) { return new ethers.ContractFactory(contractNameOrABI, bytecode, signerOrOptions || (new ethers.providers.Web3Provider(ganacheProvider)).getSigner()) } else if (typeof contractNameOrABI === 'string') { - const contract = await getArtefactsByContractName(contractNameOrABI) + const contract = await getArtifactsByContractName(contractNameOrABI) if (contract) { return new ethers.ContractFactory(contract.abi, contract.evm.bytecode.object, signerOrOptions || (new ethers.providers.Web3Provider(ganacheProvider)).getSigner()) } else { - throw new Error('Contract artefacts not found') + throw new Error('Contract artifacts not found') } } else { throw new Error('Invalid contract name or ABI provided') @@ -170,24 +184,26 @@ const getContractFactory = async (contractNameOrABI: ethers.ContractInterface, b } const getContractAt = async (contractNameOrABI: ethers.ContractInterface, address: string, signer = null) => { + //@ts-ignore + if (!global.ganacheProvider) initializeProvider() const provider = new ethers.providers.Web3Provider(ganacheProvider) if(typeof contractNameOrABI === 'string') { - try { - const result = await getArtefactsByContractName(contractNameOrABI) - - if (result) { - return new ethers.Contract(address, result.abi, signer || provider.getSigner()) - } else { - throw new Error('Contract artefacts not found') - } - } catch(e) { throw e } + const result = await getArtifactsByContractName(contractNameOrABI) + + if (result) { + return new ethers.Contract(address, result.abi, signer || provider.getSigner()) + } else { + throw new Error('Contract artifacts not found') + } } else { return new ethers.Contract(address, contractNameOrABI, signer || provider.getSigner()) } } const getSigner = async (address: string) => { + //@ts-ignore + if (!global.ganacheProvider) initializeProvider() const provider = new ethers.providers.Web3Provider(ganacheProvider) const signer = provider.getSigner(address) @@ -195,15 +211,17 @@ const getSigner = async (address: string) => { } const getSigners = async () => { - try { - const provider = new ethers.providers.Web3Provider(ganacheProvider) - const accounts = await provider.listAccounts() + //@ts-ignore + if (!global.ganacheProvider) initializeProvider() + const provider = new ethers.providers.Web3Provider(ganacheProvider) + const accounts = await provider.listAccounts() - return await Promise.all( accounts.map((account) => getSigner(account))) - } catch(err) { throw err } + return await Promise.all( accounts.map((account: any) => getSigner(account))) } -const getContractFactoryFromArtifact = async (artifact, signerOrOptions = null) => { +const getContractFactoryFromArtifact = async (artifact: any, signerOrOptions: { signer: any, libraries: any }) => { + //@ts-ignore + if (!global.ganacheProvider) initializeProvider() let libraries = {} let signer @@ -228,10 +246,10 @@ If you want to call a contract using ${artifact.contractName} as its interface u } const linkedBytecode = await collectLibrariesAndLink(artifact, libraries) - return new ethers.ContractFactory(artifact.abi, linkedBytecode || artifact.bytecode, signer || (new ethers.providers.Web3Provider(web3Provider)).getSigner()) + return new ethers.ContractFactory(artifact.abi, linkedBytecode || artifact.bytecode, signer || (new ethers.providers.Web3Provider(ganacheProvider)).getSigner()) } -const getContractAtFromArtifact = async (artifact, address, signerOrOptions = null) => { +const getContractAtFromArtifact = async (artifact: any, address: string, signerOrOptions = null) => { if (!isArtifact(artifact)) { throw new Error( `You are trying to create a contract factory from an artifact, but you have not passed a valid artifact parameter.` @@ -241,4 +259,4 @@ const getContractAtFromArtifact = async (artifact, address, signerOrOptions = nu return await getContractAt(artifact.abi, address, signerOrOptions) } -export { getContractAtFromArtifact, getContractFactoryFromArtifact, getSigners, getSigner, getContractAt, getContractFactory } \ No newline at end of file +export { getContractAtFromArtifact, getContractFactoryFromArtifact, getSigners, getSigner, getContractAt, getContractFactory } diff --git a/libs/ghaction/src/signer.ts b/libs/ghaction-helper/src/signer.ts similarity index 55% rename from libs/ghaction/src/signer.ts rename to libs/ghaction-helper/src/signer.ts index 61c9ee5b83..c6b6cf9d2a 100644 --- a/libs/ghaction/src/signer.ts +++ b/libs/ghaction-helper/src/signer.ts @@ -1,11 +1,22 @@ +// @ts-ignore import { ethers } from "ethers" export class SignerWithAddress extends ethers.Signer { - static async create(signer) { + address: string + _signer: { + provider: any + signTransaction: (transaction: any) => any, + signMessage: (message: string) => any, + sendTransaction: (transaction: any) => any, + connect: (provider: any) => any, + _signTypedData: (...params: any) => any + } + provider: any + static async create(signer: any) { return new SignerWithAddress(await signer.getAddress(), signer) } - constructor(address, _signer) { + constructor(address: string, _signer: any) { super() this.address = address this._signer = _signer @@ -16,27 +27,27 @@ export class SignerWithAddress extends ethers.Signer { return this.address } - signMessage(message){ + signMessage(message: string){ return this._signer.signMessage(message) } - signTransaction(transaction) { + signTransaction(transaction: any) { return this._signer.signTransaction(transaction) } - sendTransaction(transaction) { + sendTransaction(transaction: any) { return this._signer.sendTransaction(transaction) } - connect(provider) { + connect(provider: any) { return new SignerWithAddress(this.address, this._signer.connect(provider)) } - _signTypedData(...params) { + _signTypedData(...params: any) { return this._signer._signTypedData(...params) } toJSON() { return `` } -} +} \ No newline at end of file diff --git a/libs/ghaction/tsconfig.json b/libs/ghaction-helper/tsconfig.json similarity index 100% rename from libs/ghaction/tsconfig.json rename to libs/ghaction-helper/tsconfig.json diff --git a/libs/ghaction/tsconfig.lib.json b/libs/ghaction-helper/tsconfig.lib.json similarity index 100% rename from libs/ghaction/tsconfig.lib.json rename to libs/ghaction-helper/tsconfig.lib.json diff --git a/libs/ghaction/package.json b/libs/ghaction/package.json deleted file mode 100644 index 36c47cf9f4..0000000000 --- a/libs/ghaction/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "@remix-project/ghaction", - "version": "0.1.0", - "description": "Tools to help with github actions for running solidity tests", - "main": "src/index.js", - "types": "src/index.d.ts", - "contributors": [ - { - "name": "David Disu", - "email": "daviddisu8@gmail.com" - } - ], - "dependencies": { - "ethers": "^5.7.2", - "ganache": "^7.5.0", - "chai": "^4.3.7", - "@remix-project/remix-solidity": "^0.5.5", - "@ethereum-waffle/chai": "^3.4.4" - }, - "devDependencies": { - "typescript": "^3.7.4" - }, - "scripts": { - "build": "tsc" - }, - "publishConfig": { - "access": "public" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/ethereum/remix-project.git" - }, - "author": "Remix Team", - "license": "MIT", - "bugs": { - "url": "https://github.com/ethereum/remix-project/issues" - }, - "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/ghaction#readme", - "typings": "src/index.d.ts" -} \ No newline at end of file diff --git a/libs/ghaction/src/artefacts-helper.ts b/libs/ghaction/src/artefacts-helper.ts deleted file mode 100644 index 357a97dd18..0000000000 --- a/libs/ghaction/src/artefacts-helper.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { CompilationResult } from '@remix-project/remix-solidity' -import * as fs from 'fs/promises' -import * as path from 'path' - -declare global { - const remixContractArtefactsPath: string -} - -export async function getArtefactsByContractName (contractIdentifier: string) { - const contractArtefacts = await fs.readdir(global.remixContractArtefactsPath) - let contract - - for (const artefactFile of contractArtefacts) { - const artefact = await fs.readFile(path.join(global.remixContractArtefactsPath, artefactFile), 'utf-8') - const artefactJSON: CompilationResult = JSON.parse(artefact) - const contractFullPath = (Object.keys(artefactJSON.contracts!)).find((contractName) => artefactJSON.contracts![contractName] && artefactJSON.contracts![contractName][contractIdentifier]) - - contract = contractFullPath ? artefactJSON.contracts![contractFullPath!][contractIdentifier] : undefined - if (contract) break - } - return contract -} \ No newline at end of file diff --git a/libs/ghaction/src/ethers.ts b/libs/ghaction/src/ethers.ts deleted file mode 100644 index 0940523c23..0000000000 --- a/libs/ghaction/src/ethers.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { ethers } from 'ethers' -import * as ganache from 'ganache' -import * as hhEtherMethods from './methods' - -global.ganacheProvider = ganache.provider({ logging: { quiet: true } }) -for(const method in hhEtherMethods) Object.defineProperty(ethers, method, { value: hhEtherMethods[method]}) - -export * from 'ethers' -export { ethers } \ No newline at end of file diff --git a/libs/ghaction/src/index.ts b/libs/ghaction/src/index.ts deleted file mode 100644 index 49dd0864dc..0000000000 --- a/libs/ghaction/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './chai' -export * from './ethers' \ No newline at end of file diff --git a/package.json b/package.json index c7c68afb70..be0925ef80 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "workspace-schematic": "nx workspace-schematic", "dep-graph": "nx dep-graph", "help": "nx help", - "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remix-ws-templates,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-helper,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox,remix-ui-settings,remix-core-plugin,remix-ui-renderer,remix-ui-publish-to-storage,remix-ui-solidity-compiler,solidity-unit-testing,remix-ui-plugin-manager,remix-ui-terminal,remix-ui-editor,remix-ui-app,remix-ui-tabs,remix-ui-panel,remix-ui-run-tab,remix-ui-permission-handler,remix-ui-search,remix-ui-file-decorators,remix-ui-tooltip-popup", + "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remix-ws-templates,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-helper,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox,remix-ui-settings,remix-core-plugin,remix-ui-renderer,remix-ui-publish-to-storage,remix-ui-solidity-compiler,solidity-unit-testing,remix-ui-plugin-manager,remix-ui-terminal,remix-ui-editor,remix-ui-app,remix-ui-tabs,remix-ui-panel,remix-ui-run-tab,remix-ui-permission-handler,remix-ui-search,remix-ui-file-decorators,remix-ui-tooltip-popup,ghaction-helper", "build:libs": "nx run-many --target=build --parallel=false --with-deps=true --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remix-ws-templates,remixd", "test:libs": "nx run-many --target=test --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-tests,remix-url-resolver,remixd", "publish:libs": "yarn run build:libs && lerna publish --skip-git && yarn run bumpVersion:libs",