UNPKG

harsta

Version:

Harsta is a contract development tool based on Hardhat, designed to streamline the development, testing, and referencing of contracts, addresses, ABIs, and contract instances.

121 lines (106 loc) 3.85 kB
import path from 'pathe' import fs from 'fs-extra' import { absolutePaths, packRoot, relativePaths, userRoot } from '../../constants' import { findsFilePaths, resolveFileConflicts } from '../../utils' export interface ContractFragment { path: string input: { import: string relative: string typechains: string factory: string exports: string[] file: string } outfile: { dirname: string file: string name: string } } export async function resolveUserAddresses() { const userAddressesPath = path.resolve(userRoot, './config/addresses.ts') const addrFile = path.resolve(userRoot, './config/addresses.ts') const jsonFile = path.resolve(userRoot, './config/addresses.json') if (fs.existsSync(jsonFile)) return `export default ${await fs.readFile(jsonFile, 'utf-8')}` if (fs.existsSync(addrFile)) return fs.readFile(addrFile, 'utf-8') const defaultFileContent = 'export default {\n\n}\n' await fs.ensureDir(path.dirname(userAddressesPath)) await fs.writeFile(userAddressesPath, defaultFileContent) return defaultFileContent } export function resolveFragmentsPaths() { const generateRoot = path.resolve(packRoot, './generated') const fragmentsFactoriesPaths = resolveFileConflicts(findsFilePaths(absolutePaths.generateFactoriesFragments)) const fragmentsContractsPaths = resolveFileConflicts(findsFilePaths(absolutePaths.generateContractsFragments)) return { factories: generateFragmentData( fragmentsFactoriesPaths, generateRoot, relativePaths.generateFactories, relativePaths.generateFactoriesTypechain, ) as ContractFragment[], contracts: generateFragmentData( fragmentsContractsPaths, generateRoot, relativePaths.generateContracts, relativePaths.generateContractsTypechain, ) as ContractFragment[], } } function generateFragmentData(fragments: string[], generateRoot: string, contractsDir: string, typechainsDir: string) { return fragments.map((fPath: string) => { const outDir = path.resolve(generateRoot, contractsDir) const outfile_ = outfile(fPath, outDir) const typechainsPath = path.resolve(generateRoot, typechainsDir) return { path: fPath, input: input(fPath, typechainsPath, outfile_), outfile: outfile_, } }) } function input(p: string, typechainsPath: string, outfile: any) { const relativeFile = getRelativeFilePath(p, typechainsPath) const file = `${path.resolve(typechainsPath, relativeFile)}.ts` const importPath = `${path.relative(outfile.dirname, typechainsPath)}/${relativeFile}` const factoryPath = `${typechainsPath}/factories/${relativeFile}__factory.ts` const content = fs.readFileSync(file, 'utf-8') const exports = extractExports(content, outfile.name) return { import: importPath, relative: relativeFile, typechains: typechainsPath, factory: factoryPath, exports, file, } } function getRelativeFilePath(p: string, typechainsPath: string) { if (p.includes('.sol')) { const file = path.resolve(typechainsPath, `${p.split('.sol')[0]}.sol`) return fs.existsSync(file) ? p.split('.json')[0] : p.split('.sol')[0] } return p.split('.json')[0] } function extractExports(content: string, outfileName: string) { const regExps = [ /export declare namespace (.*?) \{/gs, /export interface (.*?) extends Interface \{/gs, /export namespace (.*?) \{/gs, ] const exports = regExps .flatMap(reg => [...content.matchAll(reg)].map(mat => mat[1])) if (!exports.includes(outfileName)) { exports.push(outfileName) } return exports } function outfile(p: string, outdir: string) { const name = path.basename(p).replace('.json', '') const file = path.resolve(outdir, p).replace('.json', '.ts') const dirname = path.dirname(file) return { dirname, file, name } }