diff --git a/.changeset/angry-zoos-kneel.md b/.changeset/angry-zoos-kneel.md new file mode 100644 index 000000000..1dafff23a --- /dev/null +++ b/.changeset/angry-zoos-kneel.md @@ -0,0 +1,5 @@ +--- +"create-eth": patch +--- + +cli: format instance with prettier from cli diff --git a/.changeset/breezy-seahorses-heal.md b/.changeset/breezy-seahorses-heal.md deleted file mode 100644 index 97ad54070..000000000 --- a/.changeset/breezy-seahorses-heal.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-eth": patch ---- - -- Allow developing externalExtensions with --dev diff --git a/.changeset/eleven-masks-compete.md b/.changeset/eleven-masks-compete.md deleted file mode 100644 index 9380db39c..000000000 --- a/.changeset/eleven-masks-compete.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-eth": patch ---- - -remove vercelignore from root dir + clean base package.json diff --git a/.changeset/giant-carpets-poke.md b/.changeset/giant-carpets-poke.md deleted file mode 100644 index d71ff7a41..000000000 --- a/.changeset/giant-carpets-poke.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-eth": patch ---- - -cli: help command diff --git a/.changeset/giant-gifts-turn.md b/.changeset/giant-gifts-turn.md deleted file mode 100644 index a99f6427d..000000000 --- a/.changeset/giant-gifts-turn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-eth": patch ---- - -foundry: use forge to setup libraries + do early check for foundryup diff --git a/.changeset/silver-fishes-marry.md b/.changeset/silver-fishes-marry.md deleted file mode 100644 index ebc6a1e33..000000000 --- a/.changeset/silver-fishes-marry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-eth": patch ---- - -cli: solidity framework options diff --git a/.changeset/sweet-seas-raise.md b/.changeset/sweet-seas-raise.md new file mode 100644 index 000000000..f08b621d4 --- /dev/null +++ b/.changeset/sweet-seas-raise.md @@ -0,0 +1,5 @@ +--- +"create-eth": patch +--- + +up prettier (scaffold-eth#875) diff --git a/.changeset/yellow-ducks-retire.md b/.changeset/yellow-ducks-retire.md deleted file mode 100644 index cc9e5411b..000000000 --- a/.changeset/yellow-ducks-retire.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-eth": patch ---- - -fix bug foundry gh action fails diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d9714107..7ed8c720f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # create-eth +## 0.0.48 + +### Patch Changes + +- Allow developing externalExtensions with --dev +- remove vercelignore from root dir + clean base package.json +- cli: help command +- foundry: use forge to setup libraries + do early check for foundryup +- foundry: fix verification script failing in latest foundry version +- cli: solidity framework options +- Better transaction result formatting in debug page (#853) +- fix: address components copy icon on small screens (#864) +- lock typescript and abitype version (#871) +- rewrite useScaffoldEventHistory hook (#869) +- fix bug foundry gh action fails + ## 0.0.47 ### Patch Changes diff --git a/package.json b/package.json index 5963fa70a..527bf98c3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "create-eth", - "version": "0.0.47", + "version": "0.0.48", "description": "Create a Scaffold-ETH-2 app", "repository": { "type": "git", @@ -39,7 +39,6 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "lefthook": "^1.6.16", - "prettier": "3.2.5", "rollup": "3.21.0", "rollup-plugin-auto-external": "2.0.0", "tslib": "2.5.0", @@ -48,6 +47,7 @@ }, "dependencies": { "@changesets/cli": "^2.26.2", + "@trivago/prettier-plugin-sort-imports": "^4.3.0", "arg": "5.0.2", "chalk": "5.2.0", "execa": "7.1.1", @@ -55,7 +55,9 @@ "listr2": "^8.2.1", "merge-packages": "^0.1.6", "ncp": "2.0.0", - "pkg-install": "1.0.0" + "pkg-install": "1.0.0", + "prettier": "3.3.2", + "prettier-plugin-solidity": "^1.3.1" }, "packageManager": "yarn@3.5.0" } diff --git a/src/main.ts b/src/main.ts index faa7f648d..b506c4ec3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -35,6 +35,10 @@ export async function createProject(options: Options) { )}${options.externalExtension ? ` with the ${chalk.green.bold(options.dev ? options.externalExtension : getArgumentFromExternalExtensionOption(options.externalExtension))} extension` : ""}`, task: () => copyTemplateFiles(options, templateDirectory, targetDirectory), }, + { + title: "🪄 Formatting files", + task: () => prettierFormat(targetDirectory, options), + }, { title: `📦 Installing dependencies with yarn, this could take a while`, task: () => installPackages(targetDirectory), @@ -45,16 +49,6 @@ export async function createProject(options: Options) { return false; }, }, - { - title: "🪄 Formatting files with prettier", - task: () => prettierFormat(targetDirectory), - skip: () => { - if (!options.install) { - return "Skipping because prettier install was skipped"; - } - return false; - }, - }, { title: `📡 Initializing Git repository${options.solidityFramework === SOLIDITY_FRAMEWORKS.FOUNDRY ? " and submodules" : ""}`, task: () => createFirstGitCommit(targetDirectory, options), diff --git a/src/tasks/prettier-format.ts b/src/tasks/prettier-format.ts index 3df6433bd..c81907fe0 100644 --- a/src/tasks/prettier-format.ts +++ b/src/tasks/prettier-format.ts @@ -1,15 +1,54 @@ import { execa } from "execa"; +import path from "path"; +import { Options } from "../types"; +import { SOLIDITY_FRAMEWORKS } from "../utils/consts"; -// TODO: Instead of using execa, use prettier package from cli to format targetDir -export async function prettierFormat(targetDir: string) { +async function runPrettier(targetPath: string[], prettierConfigPath: string, prettierPlugins: string[]) { + console.log("the prettier config path is", prettierConfigPath); + const result = await execa("yarn", [ + "prettier", + "--write", + ...targetPath, + "--config", + prettierConfigPath, + ...prettierPlugins, + "--no-editorconfig", + ]); + if (result.failed) { + throw new Error(`There was a problem running prettier in ${targetPath.join(" ")}`); + } +} + +export async function prettierFormat(targetDir: string, options: Options) { try { - const result = await execa("yarn", ["format"], { cwd: targetDir }); + const nextJsPath = path.join(targetDir, "packages", "nextjs"); + const nextPrettierConfig = path.join(nextJsPath, ".prettierrc.json"); + + await runPrettier([nextJsPath], nextPrettierConfig, ["--plugin=@trivago/prettier-plugin-sort-imports"]); + + if (options.solidityFramework === SOLIDITY_FRAMEWORKS.HARDHAT) { + const hardhatPackagePath = path.join(targetDir, "packages", SOLIDITY_FRAMEWORKS.HARDHAT); + const hardhatPrettierConfig = path.join(hardhatPackagePath, ".prettierrc.json"); + const hardhatPaths = [ + `${hardhatPackagePath}/*.ts`, + `${hardhatPackagePath}/deploy/**/*.ts`, + `${hardhatPackagePath}/scripts/**/*.ts`, + `${hardhatPackagePath}/test/**/*.ts`, + `${hardhatPackagePath}/contracts/**/*.sol`, + ]; + + await runPrettier(hardhatPaths, hardhatPrettierConfig, ["--plugin=prettier-plugin-solidity"]); + } - if (result.failed) { - throw new Error("There was a problem running the format command"); + if (options.solidityFramework === SOLIDITY_FRAMEWORKS.FOUNDRY) { + const foundryPackagePath = path.resolve(targetDir, "packages", SOLIDITY_FRAMEWORKS.FOUNDRY); + const foundryResult = await execa("forge", ["fmt"], { cwd: foundryPackagePath }); + if (foundryResult.failed) { + throw new Error("There was a problem running forge fmt in the foundry package"); + } } } catch (error) { - throw new Error("Failed to format directory", { cause: error }); + throw new Error("Failed to run prettier", { cause: error }); } return true; diff --git a/templates/base/packages/nextjs/.prettierrc.json b/templates/base/packages/nextjs/.prettierrc.json index 36fa5f31e..72781a493 100644 --- a/templates/base/packages/nextjs/.prettierrc.json +++ b/templates/base/packages/nextjs/.prettierrc.json @@ -1,8 +1,10 @@ { + "plugins": ["@trivago/prettier-plugin-sort-imports"], "arrowParens": "avoid", "printWidth": 120, "tabWidth": 2, "trailingComma": "all", "importOrder": ["^react$", "^next/(.*)$", "", "^@heroicons/(.*)$", "^~~/(.*)$"], - "importOrderSortSpecifiers": true + "importOrderSortSpecifiers": true, + "plugins": ["@trivago/prettier-plugin-sort-imports"] } diff --git a/templates/base/packages/nextjs/app/debug/_components/contract/ReadOnlyFunctionForm.tsx b/templates/base/packages/nextjs/app/debug/_components/contract/ReadOnlyFunctionForm.tsx index 9ccc37fed..a0d097a53 100644 --- a/templates/base/packages/nextjs/app/debug/_components/contract/ReadOnlyFunctionForm.tsx +++ b/templates/base/packages/nextjs/app/debug/_components/contract/ReadOnlyFunctionForm.tsx @@ -76,17 +76,17 @@ export const ReadOnlyFunctionForm = ({

{inputElements} -
-
+
+
{result !== null && result !== undefined && ( -
+

Result:

-
{displayTxResult(result)}
+
{displayTxResult(result, "sm")}
)}
diff --git a/templates/base/packages/nextjs/app/debug/_components/contract/utilsDisplay.tsx b/templates/base/packages/nextjs/app/debug/_components/contract/utilsDisplay.tsx index f5d212993..3148affdf 100644 --- a/templates/base/packages/nextjs/app/debug/_components/contract/utilsDisplay.tsx +++ b/templates/base/packages/nextjs/app/debug/_components/contract/utilsDisplay.tsx @@ -1,5 +1,6 @@ -import { ReactElement } from "react"; -import { TransactionBase, TransactionReceipt, formatEther, isAddress } from "viem"; +import { ReactElement, useState } from "react"; +import { TransactionBase, TransactionReceipt, formatEther, isAddress, isHex } from "viem"; +import { ArrowsRightLeftIcon } from "@heroicons/react/24/solid"; import { Address } from "~~/components/scaffold-eth"; import { replacer } from "~~/utils/scaffold-eth/common"; @@ -13,44 +14,101 @@ type DisplayContent = | undefined | unknown; +type ResultFontSize = "sm" | "base" | "xs" | "lg" | "xl" | "2xl" | "3xl"; + export const displayTxResult = ( displayContent: DisplayContent | DisplayContent[], - asText = false, + fontSize: ResultFontSize = "base", ): string | ReactElement | number => { if (displayContent == null) { return ""; } if (typeof displayContent === "bigint") { - try { - const asNumber = Number(displayContent); - if (asNumber <= Number.MAX_SAFE_INTEGER && asNumber >= Number.MIN_SAFE_INTEGER) { - return asNumber; - } else { - return "Ξ" + formatEther(displayContent); - } - } catch (e) { - return "Ξ" + formatEther(displayContent); - } + return ; } - if (typeof displayContent === "string" && isAddress(displayContent)) { - return asText ? displayContent :
; + if (typeof displayContent === "string") { + if (isAddress(displayContent)) { + return
; + } + + if (isHex(displayContent)) { + return displayContent; // don't add quotes + } } if (Array.isArray(displayContent)) { - const mostReadable = (v: DisplayContent) => - ["number", "boolean"].includes(typeof v) ? v : displayTxResultAsText(v); - const displayable = JSON.stringify(displayContent.map(mostReadable), replacer); - - return asText ? ( - displayable - ) : ( - {displayable.replaceAll(",", ",\n")} - ); + return ; + } + + if (typeof displayContent === "object") { + return ; } return JSON.stringify(displayContent, replacer, 2); }; -const displayTxResultAsText = (displayContent: DisplayContent) => displayTxResult(displayContent, true); +const NumberDisplay = ({ value }: { value: bigint }) => { + const [isEther, setIsEther] = useState(false); + + const asNumber = Number(value); + if (asNumber <= Number.MAX_SAFE_INTEGER && asNumber >= Number.MIN_SAFE_INTEGER) { + return String(value); + } + + return ( +
+ {isEther ? "Ξ" + formatEther(value) : String(value)} + + + +
+ ); +}; + +export const ObjectFieldDisplay = ({ + name, + value, + size, + leftPad = true, +}: { + name: string; + value: DisplayContent; + size: ResultFontSize; + leftPad?: boolean; +}) => { + return ( +
+ {name}: + {displayTxResult(value, size)} +
+ ); +}; + +const ArrayDisplay = ({ values, size }: { values: DisplayContent[]; size: ResultFontSize }) => { + return ( +
+ {values.length ? "array" : "[]"} + {values.map((v, i) => ( + + ))} +
+ ); +}; + +const StructDisplay = ({ struct, size }: { struct: Record; size: ResultFontSize }) => { + return ( +
+ struct + {Object.entries(struct).map(([k, v]) => ( + + ))} +
+ ); +}; diff --git a/templates/base/packages/nextjs/app/page.tsx b/templates/base/packages/nextjs/app/page.tsx index fcca994c5..b91c22fe8 100644 --- a/templates/base/packages/nextjs/app/page.tsx +++ b/templates/base/packages/nextjs/app/page.tsx @@ -17,7 +17,7 @@ const Home: NextPage = () => { Welcome to Scaffold-ETH 2 -
+

Connected Address:

diff --git a/templates/base/packages/nextjs/components/scaffold-eth/Address.tsx b/templates/base/packages/nextjs/components/scaffold-eth/Address.tsx index 2241edc89..f24b4597a 100644 --- a/templates/base/packages/nextjs/components/scaffold-eth/Address.tsx +++ b/templates/base/packages/nextjs/components/scaffold-eth/Address.tsx @@ -91,7 +91,7 @@ export const Address = ({ address, disableAddressLink, format, size = "base" }: } return ( -
+