diff --git a/templates/solidity-frameworks/foundry/packages/foundry/Makefile b/templates/solidity-frameworks/foundry/packages/foundry/Makefile.template.mjs similarity index 74% rename from templates/solidity-frameworks/foundry/packages/foundry/Makefile rename to templates/solidity-frameworks/foundry/packages/foundry/Makefile.template.mjs index 2e0c8f9a6..8638dbff8 100644 --- a/templates/solidity-frameworks/foundry/packages/foundry/Makefile +++ b/templates/solidity-frameworks/foundry/packages/foundry/Makefile.template.mjs @@ -1,4 +1,7 @@ -.PHONY: build deploy generate-abis verify-keystore account chain compile flatten fork format lint test verify + +import { withDefaults } from "../../../../utils.js"; + +const content = ({ recipes, postDeployRecipeToRun }) => `.PHONY: build deploy generate-abis verify-keystore account chain compile flatten fork format lint test verify DEPLOY_SCRIPT ?= script/Deploy.s.sol @@ -14,7 +17,7 @@ chain: setup-anvil-wallet # Start a fork fork: setup-anvil-wallet - anvil --fork-url ${FORK_URL} --chain-id 31337 + anvil --fork-url \${FORK_URL} --chain-id 31337 # Deploy the contracts deploy: @@ -24,16 +27,16 @@ deploy: fi @if [ "$(RPC_URL)" = "localhost" ]; then \ if [ "$(ETH_KEYSTORE_ACCOUNT)" = "scaffold-eth-default" ]; then \ - forge script $(DEPLOY_SCRIPT) --rpc-url localhost --password localhost --broadcast --legacy --ffi; \ + forge script $(DEPLOY_SCRIPT) --rpc-url localhost --password localhost --broadcast --via-ir --legacy --ffi; \ else \ - forge script $(DEPLOY_SCRIPT) --rpc-url localhost --broadcast --legacy --ffi; \ + forge script $(DEPLOY_SCRIPT) --rpc-url localhost --broadcast --legacy --via-ir --ffi; \ fi \ else \ - forge script $(DEPLOY_SCRIPT) --rpc-url $(RPC_URL) --broadcast --legacy --ffi; \ + forge script $(DEPLOY_SCRIPT) --rpc-url $(RPC_URL) --broadcast --legacy --via-ir --ffi; \ fi # Deploy and generate ABIs -deploy-and-generate-abis: deploy generate-abis +deploy-and-generate-abis: deploy generate-abis ${postDeployRecipeToRun.filter(Boolean).join(" ")} # Generate TypeScript ABIs generate-abis: @@ -57,7 +60,7 @@ account-generate: # Import an existing account account-import: - @cast wallet import ${ACCOUNT_NAME} --interactive + @cast wallet import \${ACCOUNT_NAME} --interactive # Compile contracts compile: @@ -78,3 +81,11 @@ lint: # Verify contracts verify: forge script script/VerifyAll.s.sol --ffi --rpc-url $(RPC_URL) + +${recipes.filter(Boolean).join("\n")}` + + +export default withDefaults(content, { + recipes: ``, + postDeployRecipeToRun: ``, +}); diff --git a/templates/solidity-frameworks/foundry/packages/foundry/scripts-js/generateTsAbis.js b/templates/solidity-frameworks/foundry/packages/foundry/scripts-js/generateTsAbis.js index 0862e875e..dafa0caae 100644 --- a/templates/solidity-frameworks/foundry/packages/foundry/scripts-js/generateTsAbis.js +++ b/templates/solidity-frameworks/foundry/packages/foundry/scripts-js/generateTsAbis.js @@ -1,11 +1,4 @@ -import { - readdirSync, - statSync, - readFileSync, - existsSync, - mkdirSync, - writeFileSync, -} from "fs"; +import { readdirSync, statSync, readFileSync, existsSync, mkdirSync, writeFileSync } from "fs"; import { join, dirname } from "path"; import { fileURLToPath } from "url"; import { format } from "prettier"; @@ -19,6 +12,10 @@ const generatedContractComment = ` */`; function getDirectories(path) { + if (!existsSync(path)) { + return []; + } + return readdirSync(path).filter(function (file) { return statSync(join(path, file)).isDirectory(); }); @@ -47,12 +44,7 @@ function getDeploymentHistory(broadcastPath) { // Sort files to process them in chronological order const runFiles = files - .filter( - (file) => - file.startsWith("run-") && - file.endsWith(".json") && - !file.includes("run-latest") - ) + .filter(file => file.startsWith("run-") && file.endsWith(".json") && !file.includes("run-latest")) .sort((a, b) => { // Extract run numbers and compare them const runA = parseInt(a.match(/run-(\d+)/)?.[1] || "0"); @@ -80,17 +72,11 @@ function getDeploymentHistory(broadcastPath) { } function getArtifactOfContract(contractName) { - const current_path_to_artifacts = join( - __dirname, - "..", - `out/${contractName}.sol` - ); + const current_path_to_artifacts = join(__dirname, "..", `out/${contractName}.sol`); if (!existsSync(current_path_to_artifacts)) return null; - const artifactJson = JSON.parse( - readFileSync(`${current_path_to_artifacts}/${contractName}.json`) - ); + const artifactJson = JSON.parse(readFileSync(`${current_path_to_artifacts}/${contractName}.json`)); return artifactJson; } @@ -101,9 +87,7 @@ function getInheritedFromContracts(artifact) { for (const astNode of artifact.ast.nodes) { if (astNode.nodeType == "ContractDefinition") { if (astNode.baseContracts.length > 0) { - inheritedFromContracts = astNode.baseContracts.map( - ({ baseName }) => baseName.name - ); + inheritedFromContracts = astNode.baseContracts.map(({ baseName }) => baseName.name); } } } @@ -135,25 +119,20 @@ function processAllDeployments(broadcastPath) { const scriptFolders = getDirectories(broadcastPath); const allDeployments = new Map(); - scriptFolders.forEach((scriptFolder) => { + scriptFolders.forEach(scriptFolder => { const scriptPath = join(broadcastPath, scriptFolder); const chainFolders = getDirectories(scriptPath); - chainFolders.forEach((chainId) => { + chainFolders.forEach(chainId => { const chainPath = join(scriptPath, chainId); const deploymentHistory = getDeploymentHistory(chainPath); - deploymentHistory.forEach((deployment) => { - const timestamp = parseInt( - deployment.deploymentFile.match(/run-(\d+)/)?.[1] || "0" - ); + deploymentHistory.forEach(deployment => { + const timestamp = parseInt(deployment.deploymentFile.match(/run-(\d+)/)?.[1] || "0"); const key = `${chainId}-${deployment.contractName}`; // Only update if this deployment is newer - if ( - !allDeployments.has(key) || - timestamp > allDeployments.get(key).timestamp - ) { + if (!allDeployments.has(key) || timestamp > allDeployments.get(key).timestamp) { allDeployments.set(key, { ...deployment, timestamp, @@ -167,7 +146,7 @@ function processAllDeployments(broadcastPath) { const allContracts = {}; - allDeployments.forEach((deployment) => { + allDeployments.forEach(deployment => { const { chainId, contractName } = deployment; const artifact = getArtifactOfContract(contractName); @@ -197,19 +176,15 @@ function main() { const deployments = {}; // Load existing deployments from deployments directory - Deploymentchains.forEach((chain) => { + Deploymentchains.forEach(chain => { if (!chain.endsWith(".json")) return; chain = chain.slice(0, -5); - var deploymentObject = JSON.parse( - readFileSync(`${current_path_to_deployments}/${chain}.json`) - ); + var deploymentObject = JSON.parse(readFileSync(`${current_path_to_deployments}/${chain}.json`)); deployments[chain] = deploymentObject; }); // Process all deployments from all script folders - const allGeneratedContracts = processAllDeployments( - current_path_to_broadcast - ); + const allGeneratedContracts = processAllDeployments(current_path_to_broadcast); // Update contract keys based on deployments if they exist Object.entries(allGeneratedContracts).forEach(([chainId, contracts]) => { @@ -231,19 +206,12 @@ function main() { } // Generate the deployedContracts content - const fileContent = Object.entries(allGeneratedContracts).reduce( - (content, [chainId, chainConfig]) => { - return `${content}${parseInt(chainId).toFixed(0)}:${JSON.stringify( - chainConfig, - null, - 2 - )},`; - }, - "" - ); + const fileContent = Object.entries(allGeneratedContracts).reduce((content, [chainId, chainConfig]) => { + return `${content}${parseInt(chainId).toFixed(0)}:${JSON.stringify(chainConfig, null, 2)},`; + }, ""); // Write the files - const fileTemplate = (importPath) => ` + const fileTemplate = importPath => ` ${generatedContractComment} import { GenericContractsDeclaration } from "${importPath}"; @@ -256,12 +224,10 @@ function main() { `${NEXTJS_TARGET_DIR}deployedContracts.ts`, format(fileTemplate("~~/utils/scaffold-eth/contract"), { parser: "typescript", - }) + }), ); - console.log( - `📝 Updated TypeScript contract definition file on ${NEXTJS_TARGET_DIR}deployedContracts.ts` - ); + console.log(`📝 Updated TypeScript contract definition file on ${NEXTJS_TARGET_DIR}deployedContracts.ts`); } try {