diff --git a/app/components/PageLayout.tsx b/app/components/PageLayout.tsx index 0f778eb..1b31f27 100644 --- a/app/components/PageLayout.tsx +++ b/app/components/PageLayout.tsx @@ -39,7 +39,7 @@ export default function PageLayout({ children, maxWidth = "max-w-4xl", title, su const envPrefix = import.meta.env.VITE_ENV && import.meta.env.VITE_ENV !== "production" - ? `(${import.meta.env.VITE_ENV} environment) ` + ? `(${import.meta.env.VITE_ENV} environment - ${serverUrl}) ` : ""; return ( diff --git a/app/components/verification/CompilerSelector.tsx b/app/components/verification/CompilerSelector.tsx index 7684d63..ec7d3c6 100644 --- a/app/components/verification/CompilerSelector.tsx +++ b/app/components/verification/CompilerSelector.tsx @@ -1,6 +1,6 @@ import React, { useState } from "react"; import { useCompilerVersions } from "../../contexts/CompilerVersionsContext"; -import type { SolidityVersion, VyperVersion } from "../../contexts/CompilerVersionsContext"; +import type { SolidityVersion, VyperVersion, FeVersion } from "../../contexts/CompilerVersionsContext"; import type { Language, SelectedMethod } from "../../types/verification"; interface CompilerSelectorProps { @@ -21,14 +21,18 @@ export default function CompilerSelector({ officialSolidityVersions, vyperVersions, officialVyperVersions, + feVersions, + officialFeVersions, isSolidityLoading, isVyperLoading, + isFeLoading, solidityError, vyperError, + feError, } = useCompilerVersions(); const [showNightlyBuilds, setShowNightlyBuilds] = useState(false); - const [showPrereleases, setShowPrereleases] = useState(false); + const [showPrereleases, setShowPrereleases] = useState(language === "fe"); // Don't show if language is null or if using metadata/framework methods if (!language || !selectedMethod) { @@ -43,8 +47,8 @@ export default function CompilerSelector({ return null; } - const isLoading = language === "solidity" ? isSolidityLoading : isVyperLoading; - const compilerError = language === "solidity" ? solidityError : vyperError; + const isLoading = language === "solidity" ? isSolidityLoading : language === "vyper" ? isVyperLoading : isFeLoading; + const compilerError = language === "solidity" ? solidityError : language === "vyper" ? vyperError : feError; if (isLoading) { return ( @@ -72,27 +76,32 @@ export default function CompilerSelector({ const getVersionsToShow = () => { if (language === "solidity") { return showNightlyBuilds ? solidityVersions : officialSolidityVersions; - } else { + } else if (language === "vyper") { return showPrereleases ? vyperVersions : officialVyperVersions; + } else { + return feVersions; } }; const versionsToShow = getVersionsToShow(); - const formatVersionForDisplay = (version: SolidityVersion | VyperVersion) => { + const formatVersionForDisplay = (version: SolidityVersion | VyperVersion | FeVersion) => { if (language === "solidity") { return (version as SolidityVersion).version; + } else if (language === "vyper") { + return (version as VyperVersion).longVersion; } else { - const vyperVersion = version as VyperVersion; - return vyperVersion.longVersion; + return (version as FeVersion).version; } }; - const getVersionValue = (version: SolidityVersion | VyperVersion) => { + const getVersionValue = (version: SolidityVersion | VyperVersion | FeVersion) => { if (language === "solidity") { return (version as SolidityVersion).version; - } else { + } else if (language === "vyper") { return (version as VyperVersion).longVersion; + } else { + return (version as FeVersion).version; } }; @@ -129,27 +138,29 @@ export default function CompilerSelector({ -
- { - if (language === "solidity") { - setShowNightlyBuilds(e.target.checked); - } else { - setShowPrereleases(e.target.checked); - } - }} - className="h-4 w-4 text-cerulean-blue-600 focus:ring-cerulean-blue-500 border-gray-300 rounded" - /> - -
+ {language !== "fe" && ( +
+ { + if (language === "solidity") { + setShowNightlyBuilds(e.target.checked); + } else { + setShowPrereleases(e.target.checked); + } + }} + className="h-4 w-4 text-cerulean-blue-600 focus:ring-cerulean-blue-500 border-gray-300 rounded" + /> + +
+ )} ); diff --git a/app/components/verification/CompilerSettings.tsx b/app/components/verification/CompilerSettings.tsx index 6bb631d..c8c45a4 100644 --- a/app/components/verification/CompilerSettings.tsx +++ b/app/components/verification/CompilerSettings.tsx @@ -25,8 +25,11 @@ export default function CompilerSettings({ onOptimizerEnabledChange, onOptimizerRunsChange, }: CompilerSettingsProps) { - // Only show for single-file and multiple-files methods - const shouldShow = !isFrameworkMethod && (selectedMethod === "single-file" || selectedMethod === "multiple-files"); + // Only show for single-file and multiple-files methods, and not for Fe (no compiler settings) + const shouldShow = + !isFrameworkMethod && + selectedLanguage !== "fe" && + (selectedMethod === "single-file" || selectedMethod === "multiple-files"); if (!shouldShow) return null; diff --git a/app/components/verification/ContractIdentifier.tsx b/app/components/verification/ContractIdentifier.tsx index 0e9e3e7..4e68481 100644 --- a/app/components/verification/ContractIdentifier.tsx +++ b/app/components/verification/ContractIdentifier.tsx @@ -91,6 +91,9 @@ export default function ContractIdentifier({ fullIdentifier: `${filePath}:${contractName}`, }); } + } else if (selectedLanguage === "fe" && filePath.endsWith(".fe")) { + const feContracts = parseFeFileContent(filePath, sourceContent); + contracts.push(...feContracts); } } } @@ -110,6 +113,10 @@ export default function ContractIdentifier({ contractName, fullIdentifier: `${file.name}:${contractName}`, }); + } else if (selectedLanguage === "fe" && file.name.endsWith(".fe")) { + const content = await file.text(); + const feContracts = parseFeFileContent(file.name, content); + contracts.push(...feContracts); } } } @@ -158,6 +165,19 @@ export default function ContractIdentifier({ } }, [isDropdownOpen]); + const parseFeFileContent = (fileName: string, content: string): ParsedContract[] => { + const contracts: ParsedContract[] = []; + const matches = content.matchAll(/pub\s+contract\s+(\w+)/g); + for (const match of matches) { + contracts.push({ + fileName, + contractName: match[1], + fullIdentifier: `${fileName}:${match[1]}`, + }); + } + return contracts; + }; + const parseFileContent = async (fileName: string | null, content: string): Promise => { try { const ast = parse(content, { @@ -172,7 +192,7 @@ export default function ContractIdentifier({ for (const child of ast.children) { if (child.type === "ContractDefinition" && child.name) { if (!fileName) { - const extension = selectedLanguage === "solidity" ? ".sol" : ".vy"; + const extension = selectedLanguage === "solidity" ? ".sol" : selectedLanguage === "vyper" ? ".vy" : ".fe"; fileName = `${child.name}${extension}`; } @@ -207,6 +227,9 @@ export default function ContractIdentifier({ if (selectedLanguage === "vyper") { return "contracts/MyContract.vy:MyContract"; } + if (selectedLanguage === "fe") { + return "src/counter.fe:Counter"; + } return "contracts/Storage.sol:Storage"; }; @@ -267,12 +290,12 @@ export default function ContractIdentifier({ {uploadedFiles.length > 0 && parsedContracts.length === 0 && !isParsingFiles && - selectedLanguage === "vyper" && ( + (selectedLanguage === "vyper" || selectedLanguage === "fe") && (
-

Available Vyper files:

+

Available {selectedLanguage === "vyper" ? "Vyper" : "Fe"} files:

); diff --git a/app/contexts/CompilerVersionsContext.tsx b/app/contexts/CompilerVersionsContext.tsx index 7f44e76..7c3f7a1 100644 --- a/app/contexts/CompilerVersionsContext.tsx +++ b/app/contexts/CompilerVersionsContext.tsx @@ -12,6 +12,11 @@ export interface VyperVersion { isPrerelease: boolean; } +export interface FeVersion { + version: string; + isPrerelease: boolean; +} + interface CompilerVersionsContextType { // Solidity versions solidityVersions: SolidityVersion[]; @@ -21,19 +26,26 @@ interface CompilerVersionsContextType { vyperVersions: VyperVersion[]; officialVyperVersions: VyperVersion[]; + // Fe versions + feVersions: FeVersion[]; + officialFeVersions: FeVersion[]; + // Loading states isSolidityLoading: boolean; isVyperLoading: boolean; + isFeLoading: boolean; // Error states solidityError: string | null; vyperError: string | null; + feError: string | null; } const CompilerVersionsContext = createContext(undefined); const SOLC_VERSIONS_LIST_URL = "https://raw.githubusercontent.com/ethereum/solc-bin/gh-pages/bin/list.txt"; const VYPER_VERSIONS_LIST_URL = "https://vyper-releases-mirror.hardhat.org/list.json"; +const FE_VERSIONS_LIST_URL = "https://api.github.com/repos/argotorg/fe/releases"; function formatSolidityVersionName(filename: string): SolidityVersion { // Remove "soljson-v" prefix and ".js" suffix @@ -66,10 +78,15 @@ export function CompilerVersionsProvider({ children }: { children: React.ReactNo const [vyperVersions, setVyperVersions] = useState([]); const [officialVyperVersions, setOfficialVyperVersions] = useState([]); + const [feVersions, setFeVersions] = useState([]); + const [officialFeVersions, setOfficialFeVersions] = useState([]); + const [isSolidityLoading, setIsSolidityLoading] = useState(true); const [isVyperLoading, setIsVyperLoading] = useState(true); + const [isFeLoading, setIsFeLoading] = useState(true); const [solidityError, setSolidityError] = useState(null); const [vyperError, setVyperError] = useState(null); + const [feError, setFeError] = useState(null); // Fetch Solidity versions useEffect(() => { @@ -123,6 +140,30 @@ export function CompilerVersionsProvider({ children }: { children: React.ReactNo }); }, []); + // Fetch Fe versions + useEffect(() => { + fetch(FE_VERSIONS_LIST_URL) + .then((response) => response.json()) + .then((data: { tag_name: string; published_at: string; assets: { name: string }[] }[]) => { + const allVersionsList: FeVersion[] = data + .filter((release) => release.assets.length > 0 && new Date(release.published_at) >= new Date("2026-03-20")) + .map((release) => { + const version = release.tag_name.replace(/^v/, ""); + const isPrerelease = /alpha|beta|rc/i.test(version); + return { version, isPrerelease }; + }); + + setFeVersions(allVersionsList); + setOfficialFeVersions(allVersionsList.filter((v) => !v.isPrerelease)); + setIsFeLoading(false); + }) + .catch((error) => { + console.error("Failed to fetch Fe versions:", error); + setIsFeLoading(false); + setFeError("Failed to fetch Fe compiler versions"); + }); + }, []); + return ( {children} diff --git a/app/data/verificationMethods.tsx b/app/data/verificationMethods.tsx index 56dd28c..921a7e1 100644 --- a/app/data/verificationMethods.tsx +++ b/app/data/verificationMethods.tsx @@ -53,6 +53,7 @@ export const solidityMetadataMethod: VerificationMethodObject = { export const verificationMethods: VerificationMethods = { solidity: [...baseVerificationMethods, solidityMetadataMethod], vyper: baseVerificationMethods, + fe: baseVerificationMethods, }; export const frameworkMethods: FrameworkMethodObject[] = [ diff --git a/app/hooks/useFormValidation.ts b/app/hooks/useFormValidation.ts index 0d532c7..75a8e2a 100644 --- a/app/hooks/useFormValidation.ts +++ b/app/hooks/useFormValidation.ts @@ -87,9 +87,12 @@ export function useFormValidation({ const areFilesRequired = languageString && selectedMethod && ["single-file", "multiple-files", "std-json", "metadata-json", "build-info"].includes(selectedMethod); - // Check if EVM version is required (for all languages, not for metadata-json, hardhat, or foundry methods) + // Check if EVM version is required (not for Fe which has no EVM version setting, or metadata-json/framework methods) const isEvmVersionRequired = - languageString && selectedMethod && ["single-file", "multiple-files"].includes(selectedMethod); + languageString && + selectedLanguage !== "fe" && + selectedMethod && + ["single-file", "multiple-files"].includes(selectedMethod); const validateFiles = () => { if (!areFilesRequired) return true; diff --git a/app/types/verification.ts b/app/types/verification.ts index 8c5d31f..4b606ee 100644 --- a/app/types/verification.ts +++ b/app/types/verification.ts @@ -1,4 +1,4 @@ -export type Language = "solidity" | "vyper"; +export type Language = "solidity" | "vyper" | "fe"; // Verification method IDs export type VerificationMethod = "single-file" | "multiple-files" | "std-json" | "metadata-json" | "build-info"; @@ -27,6 +27,7 @@ export interface FrameworkMethodObject { export interface VerificationMethods { solidity: VerificationMethodObject[]; vyper: VerificationMethodObject[]; + fe: VerificationMethodObject[]; } export interface FrameworkMessages { diff --git a/app/utils/sourcifyApi.ts b/app/utils/sourcifyApi.ts index 9f11223..9e42c76 100644 --- a/app/utils/sourcifyApi.ts +++ b/app/utils/sourcifyApi.ts @@ -95,13 +95,13 @@ async function buildStandardJsonInput( } // For Vyper, no optimization settings are added - // Only include evmVersion if it's not "default" - if (settings.evmVersion?.toLowerCase() !== "default") { + // Only include evmVersion if it's set and not "default" + if (settings.evmVersion && settings.evmVersion.toLowerCase() !== "default") { standardJsonSettings.evmVersion = settings.evmVersion; } return { - language: language === "vyper" ? "Vyper" : "Solidity", + language: language === "vyper" ? "Vyper" : language === "fe" ? "Fe" : "Solidity", sources, settings: standardJsonSettings, }; diff --git a/package-lock.json b/package-lock.json index 26d8968..bb6685a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,33 +5,33 @@ "packages": { "": { "dependencies": { - "@ethereum-sourcify/lib-sourcify": "^2.3.0", - "@headlessui/react": "^2.2.4", + "@ethereum-sourcify/lib-sourcify": "2.3.0", + "@headlessui/react": "2.2.4", "@react-router/node": "^7.5.3", - "@react-router/serve": "^7.5.3", - "@solidity-parser/parser": "^0.20.1", + "@react-router/serve": "7.6.2", + "@solidity-parser/parser": "0.20.1", "diff": "^8.0.2", - "ethers": "^6.14.4", - "fuse.js": "^7.1.0", - "isbot": "^5.1.27", - "react": "^19.1.0", - "react-dom": "^19.1.0", - "react-icons": "^5.5.0", + "ethers": "6.15.0", + "fuse.js": "7.1.0", + "isbot": "5.1.28", + "react": "19.1.0", + "react-dom": "19.1.0", + "react-icons": "5.5.0", "react-router": "^7.5.3", - "react-tooltip": "^5.29.1", - "serve": "^14.2.5" + "react-tooltip": "5.29.1", + "serve": "14.2.5" }, "devDependencies": { - "@ethereum-sourcify/compilers-types": "^1.0.7", - "@react-router/dev": "^7.5.3", - "@tailwindcss/vite": "^4.1.4", - "@types/node": "^20", - "@types/react": "^19.1.2", - "@types/react-dom": "^19.1.2", - "tailwindcss": "^4.1.4", - "typescript": "^5.8.3", + "@ethereum-sourcify/compilers-types": "1.0.7", + "@react-router/dev": "7.6.2", + "@tailwindcss/vite": "4.1.10", + "@types/node": "20.19.1", + "@types/react": "19.1.8", + "@types/react-dom": "19.1.6", + "tailwindcss": "4.1.10", + "typescript": "5.8.3", "vite": "^6.3.3", - "vite-tsconfig-paths": "^5.1.4" + "vite-tsconfig-paths": "5.1.4" } }, "node_modules/@adraffy/ens-normalize": { @@ -1423,6 +1423,7 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-2.2.4.tgz", "integrity": "sha512-lz+OGcAH1dK93rgSMzXmm1qKOJkBUqZf1L4M8TWLNplftQD3IkoEDdUFNfAn4ylsN6WOTVtWaLmvmaHOUk1dTA==", + "license": "MIT", "dependencies": { "@floating-ui/react": "^0.26.16", "@react-aria/focus": "^3.20.2", @@ -2198,7 +2199,8 @@ "node_modules/@solidity-parser/parser": { "version": "0.20.1", "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.20.1.tgz", - "integrity": "sha512-58I2sRpzaQUN+jJmWbHfbWf9AKfzqCI8JAdFB0vbyY+u8tBRcuTt9LxzasvR0LGQpcRv97eyV7l61FQ3Ib7zVw==" + "integrity": "sha512-58I2sRpzaQUN+jJmWbHfbWf9AKfzqCI8JAdFB0vbyY+u8tBRcuTt9LxzasvR0LGQpcRv97eyV7l61FQ3Ib7zVw==", + "license": "MIT" }, "node_modules/@swc/helpers": { "version": "0.5.17", @@ -2436,6 +2438,66 @@ "node": ">=14.0.0" } }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.4.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.0.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.4.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.10", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.9.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { + "version": "0.9.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { + "version": "2.8.0", + "dev": true, + "inBundle": true, + "license": "0BSD", + "optional": true + }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { "version": "4.1.10", "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.10.tgz", @@ -3381,9 +3443,10 @@ } }, "node_modules/diff": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.2.tgz", - "integrity": "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", + "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } @@ -3628,6 +3691,7 @@ "version": "22.7.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", + "license": "MIT", "dependencies": { "undici-types": "~6.19.2" } @@ -3635,12 +3699,14 @@ "node_modules/ethers/node_modules/tslib": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "license": "0BSD" }, "node_modules/ethers/node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" }, "node_modules/execa": { "version": "5.1.1", @@ -3876,6 +3942,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.1.0.tgz", "integrity": "sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ==", + "license": "Apache-2.0", "engines": { "node": ">=10" } @@ -5304,6 +5371,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "license": "MIT", "peerDependencies": { "react": "*" } @@ -5353,6 +5421,7 @@ "version": "5.29.1", "resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.29.1.tgz", "integrity": "sha512-rmJmEb/p99xWhwmVT7F7riLG08wwKykjHiMGbDPloNJk3tdI73oHsVOwzZ4SRjqMdd5/xwb/4nmz0RcoMfY7Bw==", + "license": "MIT", "dependencies": { "@floating-ui/dom": "^1.6.1", "classnames": "^2.3.0" @@ -6342,9 +6411,9 @@ } }, "node_modules/vite": { - "version": "6.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", - "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 965f91a..fc51157 100644 --- a/package.json +++ b/package.json @@ -9,32 +9,32 @@ "typecheck": "react-router typegen && tsc" }, "dependencies": { - "@ethereum-sourcify/lib-sourcify": "^2.3.0", - "@headlessui/react": "^2.2.4", + "@ethereum-sourcify/lib-sourcify": "2.3.0", + "@headlessui/react": "2.2.4", "@react-router/node": "^7.5.3", - "@react-router/serve": "^7.5.3", - "@solidity-parser/parser": "^0.20.1", + "@react-router/serve": "7.6.2", + "@solidity-parser/parser": "0.20.1", "diff": "^8.0.2", - "ethers": "^6.14.4", - "fuse.js": "^7.1.0", - "isbot": "^5.1.27", - "react": "^19.1.0", - "react-dom": "^19.1.0", - "react-icons": "^5.5.0", + "ethers": "6.15.0", + "fuse.js": "7.1.0", + "isbot": "5.1.28", + "react": "19.1.0", + "react-dom": "19.1.0", + "react-icons": "5.5.0", "react-router": "^7.5.3", - "react-tooltip": "^5.29.1", - "serve": "^14.2.5" + "react-tooltip": "5.29.1", + "serve": "14.2.5" }, "devDependencies": { - "@ethereum-sourcify/compilers-types": "^1.0.7", - "@react-router/dev": "^7.5.3", - "@tailwindcss/vite": "^4.1.4", - "@types/node": "^20", - "@types/react": "^19.1.2", - "@types/react-dom": "^19.1.2", - "tailwindcss": "^4.1.4", - "typescript": "^5.8.3", + "@ethereum-sourcify/compilers-types": "1.0.7", + "@react-router/dev": "7.6.2", + "@tailwindcss/vite": "4.1.10", + "@types/node": "20.19.1", + "@types/react": "19.1.8", + "@types/react-dom": "19.1.6", + "tailwindcss": "4.1.10", + "typescript": "5.8.3", "vite": "^6.3.3", - "vite-tsconfig-paths": "^5.1.4" + "vite-tsconfig-paths": "5.1.4" } } diff --git a/public/fe.svg b/public/fe.svg new file mode 100644 index 0000000..05d84dd --- /dev/null +++ b/public/fe.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..9ff60cb --- /dev/null +++ b/renovate.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "configMigration": true, + "extends": ["config:recommended", "schedule:daily"], + "packageRules": [ + { + "matchUpdateTypes": [ + "minor", + "patch", + "pin", + "digest", + "lockFileMaintenance", + "rollback", + "bump" + ], + "groupName": "all patch and minor dependencies", + "groupSlug": "all-patch-and-minor" + } + ], + "ignoreDeps": ["node", "cimg/node"], + "major": { + "dependencyDashboardApproval": true + }, + "rangeStrategy": "pin", + "timezone": "Europe/Berlin", + "schedule": ["before 6am on tuesday"] +}