From 3944be9a03e681babe079f8a7c913f5894987945 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Sun, 18 Jan 2026 10:52:29 -0800 Subject: [PATCH 01/74] refactor: grid-cols auto-fill/fit custom tw classes --- app/[locale]/assets/_components/assets.tsx | 5 +---- .../collectibles/_components/CollectiblesCurrentYear.tsx | 2 +- .../collectibles/_components/CollectiblesPreviousYears.tsx | 2 +- app/[locale]/community/events/_components/FilterEvents.tsx | 2 +- .../community/events/meetups/_components/FilterMeetups.tsx | 2 +- app/[locale]/community/events/search/page.tsx | 2 +- app/[locale]/founders/page.tsx | 2 +- app/[locale]/learn/page.tsx | 4 +--- app/[locale]/run-a-node/_components/run-a-node.tsx | 2 +- app/[locale]/stablecoins/page.tsx | 2 +- src/components/LearningToolsCardGrid.tsx | 2 +- src/components/Staking/StakingProductsCardGrid/index.tsx | 6 +----- src/layouts/md/Staking.tsx | 5 +---- src/layouts/md/Translatathon.tsx | 2 +- src/layouts/md/UseCases.tsx | 5 +---- tailwind.config.ts | 5 +++++ 16 files changed, 20 insertions(+), 30 deletions(-) diff --git a/app/[locale]/assets/_components/assets.tsx b/app/[locale]/assets/_components/assets.tsx index b6802faef41..208e12ae169 100644 --- a/app/[locale]/assets/_components/assets.tsx +++ b/app/[locale]/assets/_components/assets.tsx @@ -76,10 +76,7 @@ import wallet from "@/public/images/wallet.png" import whatIsEthereum from "@/public/images/what-is-ethereum.png" const Row = (props: ChildOnlyProp) => ( -
+
) const H2 = (props: HTMLAttributes) => ( diff --git a/app/[locale]/collectibles/_components/CollectiblesCurrentYear.tsx b/app/[locale]/collectibles/_components/CollectiblesCurrentYear.tsx index 2a41ab0a401..277acc71b44 100644 --- a/app/[locale]/collectibles/_components/CollectiblesCurrentYear.tsx +++ b/app/[locale]/collectibles/_components/CollectiblesCurrentYear.tsx @@ -507,7 +507,7 @@ const CollectiblesCurrentYear = ({ -
+
{socialBadges.map((badge) => (
-
+
{grouped[year].map((badge: Badge) => { const sanitizedName = badge.name .replace(/\s?ethereum.org\s?/i, " ") // Remove "ethereum.org" from label diff --git a/app/[locale]/community/events/_components/FilterEvents.tsx b/app/[locale]/community/events/_components/FilterEvents.tsx index 288d5b81bd1..b83a0b8d5a8 100644 --- a/app/[locale]/community/events/_components/FilterEvents.tsx +++ b/app/[locale]/community/events/_components/FilterEvents.tsx @@ -67,7 +67,7 @@ export default function FilterEvents({ events }: FilterProps) { return ( <> -
+
{filteredEvents.slice(0, MAX_RESULTS).map((event) => ( {filteredEvents.length ? ( -
+
{filteredEvents.map((event) => ( -
+
{filteredEvents.map((event) => ( { value={key} className="mt-12 border-0 p-0" > -
+
{entities.map( ({ name, diff --git a/app/[locale]/learn/page.tsx b/app/[locale]/learn/page.tsx index f5f42ba1ca5..445246f4a8d 100644 --- a/app/[locale]/learn/page.tsx +++ b/app/[locale]/learn/page.tsx @@ -101,9 +101,7 @@ const Section = ({ ) const CardGrid = ({ children }: ChildOnlyProp) => ( -
- {children} -
+
{children}
) const H3 = ({ children, ...props }: HTMLAttributes) => ( diff --git a/app/[locale]/run-a-node/_components/run-a-node.tsx b/app/[locale]/run-a-node/_components/run-a-node.tsx index 19441b2de50..e3f77cea613 100644 --- a/app/[locale]/run-a-node/_components/run-a-node.tsx +++ b/app/[locale]/run-a-node/_components/run-a-node.tsx @@ -366,7 +366,7 @@ const RunANodePage = ({

-
+
{whyRunANodeCards.map(({ Svg, title, preview, body }) => ( {t("page-stablecoins-saving")}

-
+
{dapps.map((dapp, idx) => ( ( -
+
{products .sort(({ locales }) => (locales?.length ? -1 : 0)) .map(({ description, ...product }) => ( diff --git a/src/components/Staking/StakingProductsCardGrid/index.tsx b/src/components/Staking/StakingProductsCardGrid/index.tsx index aa820f7fa3f..882985fa167 100644 --- a/src/components/Staking/StakingProductsCardGrid/index.tsx +++ b/src/components/Staking/StakingProductsCardGrid/index.tsx @@ -14,11 +14,7 @@ const StakingProductsCardGrid = ({ const { rankedProducts } = useStakingProductsCardGrid({ category }) return ( -
+
{rankedProducts.map((product) => ( ))} diff --git a/src/layouts/md/Staking.tsx b/src/layouts/md/Staking.tsx index 6c4349dab2e..5fe924d43e6 100644 --- a/src/layouts/md/Staking.tsx +++ b/src/layouts/md/Staking.tsx @@ -36,10 +36,7 @@ const Heading4 = (props: HTMLAttributes) => ( ) export const InfoGrid = (props: ChildOnlyProp) => ( -
+
) const CardGrid = (props: ChildOnlyProp) => ( diff --git a/src/layouts/md/Translatathon.tsx b/src/layouts/md/Translatathon.tsx index 677602c01ab..40214c43aa0 100644 --- a/src/layouts/md/Translatathon.tsx +++ b/src/layouts/md/Translatathon.tsx @@ -64,7 +64,7 @@ const CardContent = (props: ChildOnlyProp) => ( ) const CardContainer = (props: ChildOnlyProp) => ( -
+
{props.children}
) diff --git a/src/layouts/md/UseCases.tsx b/src/layouts/md/UseCases.tsx index 8e5f54c691c..b0d71f31f34 100644 --- a/src/layouts/md/UseCases.tsx +++ b/src/layouts/md/UseCases.tsx @@ -22,10 +22,7 @@ import { ContentLayout } from "../ContentLayout" import { useTranslation } from "@/hooks/useTranslation" const CardGrid = (props: ChildOnlyProp) => ( -
+
) // UseCases layout components diff --git a/tailwind.config.ts b/tailwind.config.ts index 6dd66724aea..7c43337739e 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -330,6 +330,11 @@ const config = { }, gridTemplateColumns: { bento: "repeat(12, 1fr)", + "fill-3": "repeat(auto-fill, minmax(min(100%, 22rem), 1fr))", + "fill-4": "repeat(auto-fill, minmax(min(100%, 18rem), 1fr))", + "fit-4": "repeat(auto-fit, minmax(min(100%, 18rem), 1fr))", + "fill-8": "repeat(auto-fill, minmax(min(100%, 11.25rem), 1fr))", + "fill-10": "repeat(auto-fill, minmax(min(100%, 7.5rem), 1fr))", }, textUnderlineOffset: { 3: "3px", From 806303ca63bff596ead4d4d7f20c4ad5292a02a2 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Sun, 18 Jan 2026 13:56:04 -0800 Subject: [PATCH 02/74] feat(ui): reusable TagsInlineText component MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor existing usage of joining " · " to use standardized component --- app/[locale]/apps/_components/AppCard.tsx | 7 ++-- .../FindWalletProductTable/WalletInfo.tsx | 7 ++-- src/components/ui/tag.tsx | 36 +++++++++++++++++-- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/app/[locale]/apps/_components/AppCard.tsx b/app/[locale]/apps/_components/AppCard.tsx index 73e842b713c..5626ba48168 100644 --- a/app/[locale]/apps/_components/AppCard.tsx +++ b/app/[locale]/apps/_components/AppCard.tsx @@ -1,9 +1,8 @@ import { AppData } from "@/lib/types" import { Image } from "@/components/Image" -import { CardParagraph } from "@/components/ui/card" import { LinkBox, LinkOverlay } from "@/components/ui/link-box" -import { Tag } from "@/components/ui/tag" +import { Tag, TagsInlineText } from "@/components/ui/tag" import TruncatedText from "@/components/ui/TruncatedText" import { APP_TAG_VARIANTS } from "@/lib/utils/apps" @@ -85,9 +84,7 @@ const AppCard = ({ }} /> )} - - {app.subCategory.map((subCategory) => subCategory).join(" · ")} - +
) diff --git a/src/components/FindWalletProductTable/WalletInfo.tsx b/src/components/FindWalletProductTable/WalletInfo.tsx index a49d344107b..98028704055 100644 --- a/src/components/FindWalletProductTable/WalletInfo.tsx +++ b/src/components/FindWalletProductTable/WalletInfo.tsx @@ -15,6 +15,7 @@ import { NUMBER_OF_SUPPORTED_LANGUAGES_SHOWN } from "@/lib/constants" import MediaQuery from "../MediaQuery" import { ButtonLink } from "../ui/buttons/Button" +import { TagsInlineText } from "../ui/tag" import PersonaTags from "./PersonaTags" @@ -44,10 +45,6 @@ const WalletInfo = ({ wallet }: WalletInfoProps) => { return labels }, [wallet, t]) - const deviceLabelsText = useMemo(() => { - return deviceLabels.join(" · ") - }, [deviceLabels]) - const formattedLanguages = useMemo(() => { return formatStringList( wallet.supportedLanguages, @@ -127,7 +124,7 @@ const WalletInfo = ({ wallet }: WalletInfoProps) => { {deviceLabels.length > 0 && (
-

{deviceLabelsText}

+
)}
diff --git a/src/components/ui/tag.tsx b/src/components/ui/tag.tsx index 5df48e75842..d935a340261 100644 --- a/src/components/ui/tag.tsx +++ b/src/components/ui/tag.tsx @@ -1,4 +1,4 @@ -import { forwardRef } from "react" +import { forwardRef, HTMLAttributes } from "react" import { cva, VariantProps } from "class-variance-authority" import { Slot } from "@radix-ui/react-slot" @@ -165,4 +165,36 @@ const TagButton = forwardRef( TagButton.displayName = "TagButton" -export { Tag, TagButton } +const listVariants = cva("", { + variants: { + variant: { + light: "text-sm text-body-medium", + }, + }, +}) + +export interface TagsInlineTextProps + extends Omit, "children">, + VariantProps { + list: string[] + delimiter?: string + max?: number +} + +const TagsInlineText = forwardRef( + ({ className, list, delimiter = "·", max, variant, ...props }, ref) => { + return ( +

+ {list.slice(0, max).join(` ${delimiter} `)} +

+ ) + } +) + +TagsInlineText.displayName = "TagsInlineText" + +export { Tag, TagButton, TagsInlineText } From 34378174c60146332e0a2b0c654f4cafb4753052 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Sun, 18 Jan 2026 21:20:52 -0800 Subject: [PATCH 03/74] feat: add developer apps data fetching - Adds fetcher for developer tooling data including data-layer setup - Adds image domains from API to next config allow-list --- next.config.js | 67 +- src/data-layer/fetchers/fetchDeveloperApps.ts | 23 + src/data-layer/index.ts | 2 + .../mocks/fetch-developer-apps.json | 4097 +++++++++++++++++ src/data-layer/tasks.ts | 3 + src/lib/data/index.ts | 6 + src/lib/types.ts | 18 + 7 files changed, 4164 insertions(+), 52 deletions(-) create mode 100644 src/data-layer/fetchers/fetchDeveloperApps.ts create mode 100644 src/data-layer/mocks/fetch-developer-apps.json diff --git a/next.config.js b/next.config.js index 89f04de2d25..087a337fcdc 100644 --- a/next.config.js +++ b/next.config.js @@ -96,58 +96,21 @@ module.exports = (phase, { defaultConfig }) => { protocol: "https", hostname: "crowdin-static.cf-downloads.crowdin.com", }, - { - protocol: "https", - hostname: "pvvrtckedmrkyzfxubkk.supabase.co", - }, - { - protocol: "https", - hostname: "avatars.githubusercontent.com", - }, - { - protocol: "https", - hostname: "github.com", - }, - { - protocol: "https", - hostname: "coin-images.coingecko.com", - }, - { - protocol: "https", - hostname: "i.imgur.com", - }, - { - protocol: "https", - hostname: "cdn.galxe.com", - }, - { - protocol: "https", - hostname: "assets.poap.xyz", - }, - { - protocol: "https", - hostname: "unavatar.io", - }, - { - protocol: "https", - hostname: "secure.meetupstatic.com", - }, - { - protocol: "https", - hostname: "pbs.twimg.com", - }, - { - protocol: "https", - hostname: "images.lumacdn.com", - }, - { - protocol: "https", - hostname: "framerusercontent.com", - }, - { - protocol: "https", - hostname: "img.evbuc.com", - }, + { protocol: "https", hostname: "pvvrtckedmrkyzfxubkk.supabase.co" }, + { protocol: "https", hostname: "avatars.githubusercontent.com" }, + { protocol: "https", hostname: "github.com" }, + { protocol: "https", hostname: "coin-images.coingecko.com" }, + { protocol: "https", hostname: "i.imgur.com" }, + { protocol: "https", hostname: "cdn.galxe.com" }, + { protocol: "https", hostname: "assets.poap.xyz" }, + { protocol: "https", hostname: "unavatar.io" }, + { protocol: "https", hostname: "secure.meetupstatic.com" }, + { protocol: "https", hostname: "pbs.twimg.com" }, + { protocol: "https", hostname: "images.lumacdn.com" }, + { protocol: "https", hostname: "framerusercontent.com" }, + { protocol: "https", hostname: "img.evbuc.com" }, + { protocol: "https", hostname: "storage.googleapis.com" }, + { protocol: "https", hostname: "cdn.charmverse.io" }, ], }, async headers() { diff --git a/src/data-layer/fetchers/fetchDeveloperApps.ts b/src/data-layer/fetchers/fetchDeveloperApps.ts new file mode 100644 index 00000000000..2057a84bcfc --- /dev/null +++ b/src/data-layer/fetchers/fetchDeveloperApps.ts @@ -0,0 +1,23 @@ +import { DeveloperAppsResponse } from "@/lib/types" + +export async function fetchDeveloperApps(): Promise { + const url = + "https://raw.githubusercontent.com/BuidlGuidl/Developer-Tooling/refs/heads/main/output/results.json" + + console.log("Starting GitHub developer apps data fetch") + + const response = await fetch(url) + + if (!response.ok) { + const status = response.status + console.warn("GitHub developer apps fetch non-OK", { status, url }) + const error = `GitHub responded with status ${status}` + throw new Error(error) + } + + const json: DeveloperAppsResponse[] = await response.json() + + console.log("Successfully fetched GitHub developer apps data") + + return json +} diff --git a/src/data-layer/index.ts b/src/data-layer/index.ts index 97125507141..0e06451ad82 100644 --- a/src/data-layer/index.ts +++ b/src/data-layer/index.ts @@ -5,6 +5,7 @@ import type { BlockspaceData, Commit, CommunityPick, + DeveloperAppsResponse, EventItem, GHIssue, GithubRepoData, @@ -44,3 +45,4 @@ export const getStablecoinsData = () => get(KEYS.ST export const getTotalEthStakedData = () => get(KEYS.TOTAL_ETH_STAKED) export const getTotalValueLockedData = () => get(KEYS.TOTAL_VALUE_LOCKED) export const getEventsData = () => get(KEYS.EVENTS) +export const getDeveloperAppsData = () => get(KEYS.DEVELOPER_APPS) diff --git a/src/data-layer/mocks/fetch-developer-apps.json b/src/data-layer/mocks/fetch-developer-apps.json new file mode 100644 index 00000000000..4f4d4c77f31 --- /dev/null +++ b/src/data-layer/mocks/fetch-developer-apps.json @@ -0,0 +1,4097 @@ +[ + { + "id": "0xc4f4309de505d2581218e6a4f9634e37d546c8f2bc51242540ca1486b965c0f2", + "name": "evm-mcp-server by mcpdotdirect", + "description": "we built an evm mcp server that allows agents to interact with a multitude of chains", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/9d83fea6-88b8-4985-b0e9-4a675be218df.png", + "banner_url": "https://storage.googleapis.com/op-atlas/763ce438-66da-4384-a634-9108e26a63a4.png", + "twitter": null, + "repos": [ + "https://github.com/mcpdotdirect/evm-mcp-server" + ], + "tags": [ + "mcp-server", + "cli", + "transaction-management" + ], + "website": "https://mcp.direct", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x2b77364f9d227b9b41ed84281857dcf016685e73ba909071a1b93135a4a0b7d9", + "name": "libethc", + "description": "libethc is an open-source ethereum library for C/C++", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/c0c216e0-29b0-4330-9b4f-9addc53c56d3.png", + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/mhw0/libethc" + ], + "tags": [ + "transaction-signing", + "abi-encoding" + ], + "website": "https://mhw0.github.io/libethc/", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0xd7a4742a0a40480ce176892bb619295d2cdd357d7ad09411beaff6278014c191", + "name": "evmstate", + "description": "A TypeScript library for tracing, and visualizing EVM state changes with detailed human-readable labeling.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/8eb6f205-cdaf-4ca2-8f9c-228183d42ede.png", + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/polareth/evmstate" + ], + "tags": [ + "analytics", + "storage-layout" + ], + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x926606219b6876c28d7185401763b7492decd48a7e89a2fd27de9dbf176507ad", + "name": "etherml", + "description": "A command-line Ethereum wallet manager written in Go 1.24.3+ that generates secure private keys, derives addresses, and stores them in quantum-resistant encrypted files with a Terminal User Interface (TUI) for browsing and management.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/9bcf0bba-0978-47ab-b553-c58778a00775.png", + "banner_url": "https://storage.googleapis.com/op-atlas/8605a173-9360-4914-a1ac-41ac54c076c7.png", + "twitter": null, + "repos": [ + "https://github.com/ngmisl/etherml" + ], + "tags": [ + "cli", + "wallet", + "security", + "encryption" + ], + "website": "https://github.com/ngmisl/etherml", + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "0x2d90d9565ef127727845637425880545cfebe0931160ce25afe929f8ab415706", + "name": "Tevm", + "description": "Tevm creates ambitous app layer tooling for developers to create great experiences for end users", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/f049eb6e-e7f5-4730-b0a2-e02a57ae2707.png", + "banner_url": "https://storage.googleapis.com/op-atlas/e0686fc6-7ee1-4543-b0fc-1285320b9462.png", + "twitter": "https://x.com/tevmtools", + "repos": [ + "https://github.com/evmts/tevm-monorepo" + ], + "tags": [ + "frontend", + "user-experience" + ], + "website": "https://node.tevm.sh", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x9dc9d9b8f79644cbe8634b022d4dd5ecaf4e438a71fe26256598f6e0d85a33a0", + "name": "Superbeam", + "description": "SuperBeam is an open-source typescript SDK on top of Superchain ecosystem. Superbeam is a single api you would ever need to transact across superchain. \n\nSuperBeam enables developers to interact with superchain interop enabled chains and protocols with less friction and without worrying about asset fragmentation across chains. It includes features like - Aggregated Balance, Asset Sweeping, Contract interactions and much more", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/17f44321-04a1-49d8-8702-1c154fa6c560.png", + "banner_url": "https://storage.googleapis.com/op-atlas/a4f2569e-59a0-4265-8976-6e61beacde96.png", + "twitter": null, + "repos": [ + "https://github.com/KENILSHAHH/superSDK" + ], + "tags": [ + "cross-chain", + "sdk" + ], + "website": "https://superbeam.gitbook.io/superbeam", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x6f8f610667400044907494c879b717e806a03bf519dcfd786edc7f2fa61d6db8", + "name": "OpenRPC", + "description": "OpenRPC is an Apache-licensed, open standard for describing JSON-RPC APIs, analogous to how OpenAPI/Swagger works for REST APIs. Our project provides a comprehensive, free-to-use toolkit that enables developers to generate clear, machine-readable specifications. This drastically simplifies the development, testing, validation, and documentation workflow for anyone building on or interacting with Ethereum and L2 client APIs.\n\nFor over six years, OpenRPC has been a foundational tool in the ecosystem. It has been instrumental for leading projects—including the Ethereum Foundation (for execution-apis), MetaMask, Chainlink, Filecoin, Celestia, and Starknet—in publishing well-defined and accessible API specifications.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/6e5db839-6c5b-4b51-902f-5dc45afd7ea9.png", + "banner_url": "https://storage.googleapis.com/op-atlas/6d09c3cd-91ff-4035-a736-7fcd9e68f98c.png", + "twitter": "https://x.com/open_rpc", + "repos": [ + "https://github.com/open-rpc/server-js", + "https://github.com/open-rpc/tools", + "https://github.com/open-rpc/generator", + "https://github.com/open-rpc/client-js", + "https://github.com/open-rpc/schema-utils-js", + "https://github.com/open-rpc/spec", + "https://github.com/open-rpc/meta-schema" + ], + "tags": [ + "json-rpc", + "cli" + ], + "website": "https://open-rpc.org", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x66818708d041152b7f9b45ee48e56ab6507ad493955fd256b62d7c9d8a27724f", + "name": "Bloctopus", + "description": "https://x.com/0xbloctopusBloctopus is building open-source dev tooling using Kurtosis that can spin up any web3 infrastructure on-demand. Through various kurtosis packages, we already support many blockchains, cross-chain protocols, oracles, wallet infra, and indexers. ", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/15cb5d1e-c868-43ac-8d7e-db4ef3fbc0f9.png", + "banner_url": "https://storage.googleapis.com/op-atlas/99fa13be-c8ef-4df9-980e-58736e3ddc29.png", + "twitter": "https://x.com/0xbloctopus", + "repos": [ + "https://github.com/LZeroAnalytics/lzero-reth", + "https://github.com/LZeroAnalytics/ethereum-package", + "https://github.com/LZeroAnalytics/blockscout-package", + "https://github.com/LZeroAnalytics/chainlink-node-package", + "https://github.com/LZeroAnalytics/layerzero-package" + ], + "tags": [ + "cross-chain", + "docker" + ], + "website": "https://www.bloctopus.io", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x56ce7cbc27852a8d8ef5869dc9033a215c8893f799468f61527dacb9f92be790", + "name": "alloy", + "description": "Alloy is a set of libraries that provides types and RPC client implementations for ethereum and optimism.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/60d98a8f-6f96-4a29-a65c-50dfc3a7828b.png", + "banner_url": "https://storage.googleapis.com/op-atlas/40039eb5-bcc3-4af4-a975-7022d660164f.png", + "twitter": null, + "repos": [ + "https://github.com/alloy-rs/op-alloy", + "https://github.com/alloy-rs/alloy" + ], + "tags": [ + "json-rpc" + ], + "website": "https://alloy.rs/", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0xeef42373d10554d65aba9e6deb8333a4eddebba829e0afea0dc93e32d8075d2d", + "name": "ERCx: Token Test Library", + "description": "Runtime Verification is a leading formal verification company specializing in blockchain security and smart contract correctness. We've developed ERCx, the most comprehensive open-source testing library for ERC token standards, featuring over 500 individual tests across ERC-20, ERC-721, ERC-1155, and ERC-4626 implementations.\nERCx directly empowers Superchain builders by providing production-ready test suites that verify both standard compliance and security properties. Our library offers zero-configuration testing for deployed contracts via Foundry fork testing, plus simple integration for pre-deployment source code validation. With three testing tiers: Standard (EIP compliance), Security (vulnerability detection), and Features (implementation validation), developers can ship token contracts with confidence, knowing they've been thoroughly vetted against real-world attack vectors and edge cases.\nWhat makes ERCx particularly valuable for the Optimism ecosystem is its cross-chain compatibility and handling of complex deployment scenarios. The library seamlessly works across OP Stack chains and handles storage complexities that often challenge developers working with established tokens like USDC or stETH. By providing this critical testing infrastructure as open-source tooling, we're enabling safer, more reliable token implementations across the entire Superchain, directly supporting the ecosystem's growth while reducing the security risks that have historically plagued token contracts in DeFi.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/e6a6dd9b-4ace-4187-8408-0e5729bb0265.png", + "banner_url": "https://storage.googleapis.com/op-atlas/eee0738d-3735-42c8-8802-93b22a041803.png", + "twitter": "x.com/rv_inc", + "repos": [ + "https://github.com/runtimeverification/ercx-tests" + ], + "tags": [ + "foundry", + "security", + "erc721", + "runtime-verification" + ], + "website": "ercx.runtimeverification.com", + "category": "Security, Testing & Formal Verification" + }, + { + "id": "0x738c0967c0f70a0a78d8794dcf2c40540f60ea9568e163dd5826b85e8e2a9a79", + "name": "Enso Build", + "description": "Enso is blockchain shortcuts. Your fastest way to build and launch onchain.\nBy mapping all onchain interactions to a shared engine, Enso lets you focus on your product.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/ba508a79-4a21-45fc-b3e3-5ede1a80fb6b.png", + "banner_url": "https://storage.googleapis.com/op-atlas/96e7fcd9-75e3-4e40-98c5-0c5ae56c6578.png", + "twitter": "https://x.com/ensobuild", + "repos": [ + "https://github.com/EnsoBuild/Uniswap-migrator", + "https://github.com/EnsoBuild/shortcuts-client-contracts", + "https://github.com/EnsoBuild/sdk-ts", + "https://github.com/EnsoBuild/shortcuts-widget" + ], + "tags": [ + "cross-chain", + "transaction-optimization" + ], + "website": "enso.build", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x414ffb06789667ba95546e05e0456445145d3de23b05b3a8ce051cbc142bfb3f", + "name": "React Native Passkeys", + "description": "React Native Passkeys is a TypeScript library that provides a unified API for creating and authenticating with passkeys across Web, Android, and iOS.\n\nThe API mirrors the WebAuthn standard, making it easier for React Native developers to leverage existing documentation, tools, and backend infrastructure, abstracting away platform-specific complexities. \n\nWith over 250k downloads it is utilised by teams like Privy, Coinbase, Safe, ZeroDev, Ephemera, OneKey & more.", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/peterferguson/react-native-passkeys" + ], + "tags": [ + "authentication" + ], + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x696c9b46af5eeaa2fcfa86f23da23ed1ce7938df67d90d422e6ba7ee2604b512", + "name": "Ethernaut CLI", + "description": "A universal Ethereum swiss army knife with an AI duck taped onto it.\n\nA CLI for non-technical users, trying to bridge the gap between graphical UIs and CLIs.\n\nA framework for rapid tool building; integrate a new tool in a matter of hours.\n\nAn extensible framework composed of hardhat plugins.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/1fdf287a-8ec4-4e15-a81d-1e63b902662b.png", + "banner_url": "https://storage.googleapis.com/op-atlas/5b622e91-2107-4d63-87b7-9aeb42d55d86.png", + "twitter": null, + "repos": [ + "https://github.com/ethernautdao/ethernaut-cli" + ], + "tags": [ + "cli", + "hardhat", + "natural-language-processing", + "developer-experience" + ], + "website": "https://ethernaut-app.vercel.app/", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x5200a7351f8d195401dc04631fb83e4836f73a2794f316b2739c03807f30a78b", + "name": "Brownie", + "description": "A Python-based development and testing framework for smart contracts targeting the Ethereum Virtual Machine. ", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/eth-brownie/brownie" + ], + "tags": [ + "cli", + "debugging-tools" + ], + "website": "https://github.com/eth-brownie/brownie", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xc850d11fe786d1168bfeda108721101427dd5425d9d9e6595c35573f7616e940", + "name": "Daimo Pay", + "description": "Daimo Pay lets users interact with your app using any token on any chain - no bridging, no swapping, no friction.\nIntegrate our SDK in 15 minutes to accept deposits or execute transactions in your app with any token, from any chain, using any wallet or exchange.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/b2bd0510-b0d6-436e-a126-de05026e9418.png", + "banner_url": "https://storage.googleapis.com/op-atlas/dde6090a-600a-418b-be38-5ea73111c407.png", + "twitter": "https://x.com/daimopay", + "repos": [ + "https://github.com/daimo-eth/pay" + ], + "tags": [ + "cross-chain" + ], + "website": "https://pay.daimo.com/", + "category": "Cross-Chain & Interoperability" + }, + { + "id": "0xf9c5d092fac6ad924253d685cc7ba21d4e519813e673a3a8300f33cb3a6b4e06", + "name": "NFTScan", + "description": "NFTScan is a professional NFT Explorer tool that provides developers and users with NFT data search services for the Superchain ecosystem, including: OP Mainnet, Base, Mint blockchain and other blockchain networks.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/30fb3451-049c-4904-a109-d3c06004a731.png", + "banner_url": "https://storage.googleapis.com/op-atlas/09a998c5-5217-4937-b2c8-d994e5cfe1c7.png", + "twitter": "https://x.com/nftscan_com", + "repos": [ + "https://github.com/nftscan-official/nftscan-api-js-sdk" + ], + "tags": [ + "erc721" + ], + "website": "https://www.nftscan.com/", + "category": "Data, Analytics & Tracing" + }, + { + "id": "0x8af71ece7f50d6962b589b19854ceac72b81e5f5b3014637b262c33809d5a395", + "name": "K Semantics of the Ethereum Virtual Machine (EVM)", + "description": "We are Runtime Verification, a research and development company building rigorous tools to ensure the safety and correctness of critical systems. Our team has developed KEVM, the most complete and battle-tested formal semantics of the Ethereum Virtual Machine (EVM), written in the K Framework.\n\nKEVM is not just a specification, it is an executable specification that can be used to symbolically reason about smart contracts, run conformance tests, analyze gas usage, debug programs, and formally verify correctness properties. It passes the full Ethereum test suite and is used to verify high-value contracts, including ERC20 tokens in both Solidity and Vyper. We recently updated the semantics to support Pectra upgrade.\n\nKEVM is being actively utilized by Kontrol - our formal verification tool for Soldiity, which is actively used by leading teams in the EVM ecosystem, including Optimism, Ethereum Foundation, Lido, Uniswap, as well as security researchers and auditors across the broader Ethereum community.\n\nWe actively maintain this repository, contribute to Ethereum’s protocol evolution, and integrate with developer tooling like Foundry. Through KEVM, we are pushing the boundaries of what’s possible in provably correct and secure smart contract infrastructure.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/aab1bec1-5b08-4727-a5c2-f8d0dfbe0ed9.png", + "banner_url": "https://storage.googleapis.com/op-atlas/0204f6f1-2d6a-443b-bd9e-afb88c23f2e3.png", + "twitter": "https://x.com/rv_inc", + "repos": [ + "https://github.com/runtimeverification/evm-semantics" + ], + "tags": [ + "security", + "education", + "analytics", + "formal-verification", + "symbolic-execution", + "debugging-tools", + "runtime-verification", + "vyper" + ], + "category": "Security, Testing & Formal Verification" + }, + { + "id": "0x4562c0630907577f433cad78c7e2cc03349d918b6c14ef982f11a2678f5999ad", + "name": "Foundry", + "description": "Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.\n\nIt is a smart contract development toolchain that manages your dependencies, compiles your project, runs tests, deploys, and lets you interact with the chain from the command-line and via Solidity scripts.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/66656b6d-5f9d-46f6-b8f0-67eb23ce9db9.png", + "banner_url": "https://storage.googleapis.com/op-atlas/f22dd5f4-39c2-46d4-b701-85355469df9c.png", + "twitter": null, + "repos": [ + "https://github.com/foundry-rs/foundry" + ], + "tags": [ + "cli", + "foundry", + "solidity", + "vyper", + "continuous-integration", + "fuzz-testing", + "performance-optimization" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x35295108e0c7b4625d650fbdabd4888417782539f56159d39ac2f0e2411f607b", + "name": "Kurtosis", + "description": "Kurtosis is a developer platform purpose-built to streamline the development, testing, and debugging of Web3 and blockchain-based distributed systems. It provides programmable environments that mirror real-world networks, making it easier to build and iterate on decentralized infrastructure. Think docker compose, for blockchain systems.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/6c0103eb-14e1-4578-831b-d5e85c017831.png", + "banner_url": "https://storage.googleapis.com/op-atlas/cec480f1-b828-424a-ae01-9984ebdc2eb5.png", + "twitter": "https://x.com/KurtosisTech", + "repos": [ + "https://github.com/kurtosis-tech/kurtosis" + ], + "tags": [ + "docker", + "cli", + "testing" + ], + "website": "https://www.kurtosis.com", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x85af258d3fae6bbd2e14ffa8f5b73b64e34b7f8efe685c40134c3f54774e8d6c", + "name": "Skandha ERC-4337 Bundler", + "description": "Etherspot's developer-friendly TypeScript ERC-4337 bundler that enhances transaction management, optimizes gas costs, and improves the overall efficiency of blockchain interactions. It supports Shared Mempool and provides built-in MEV protection. \n\nEtherspot is pioneering the ERC-4337 shared mempool innovation, which is already live on Optimism.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/c9083120-f920-426d-a33c-37ad6f5b3c3f.png", + "banner_url": "https://storage.googleapis.com/op-atlas/62d53176-085e-4084-9112-f05f62b536db.png", + "twitter": "https://x.com/etherspot", + "repos": [ + "https://github.com/etherspot/skandha" + ], + "tags": [ + "bundler", + "transaction-management", + "gas-optimization", + "cli", + "account-abstraction" + ], + "website": "https://etherspot.io/skandha/", + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "0x1e7a1f9763d25b6844567a7133b1005ef6ed785642a75229acf1b9b25202a5f3", + "name": "eRPC", + "description": "eRPC is a fault-tolerant EVM RPC proxy and permanent caching solution. It is built with read-heavy use-cases in mind such as data indexing and high-load frontend usage. It is designed to lower costs through local caching, enhance reliability during provider outages, and improve visibility into RPC usage across teams and third-party providers.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/bc82b1d5-dad6-496a-af01-475797e53e34.png", + "banner_url": "https://storage.googleapis.com/op-atlas/75c707be-ff55-41d7-9ef0-7cfcdef536ea.png", + "twitter": "https://x.com/erpc", + "repos": [ + "https://github.com/erpc/erpc" + ], + "tags": [ + "frontend", + "indexing" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x2866fcc8ea2ad6cc691b8367023c08ba84a34a14685b0154ba4601b7d4981069", + "name": "go-ethereum-hdwallet", + "description": "Ethereum HD Wallet derivations library in Go", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/09a4acff-98eb-4c73-925e-7403d7678163.png", + "banner_url": "https://storage.googleapis.com/op-atlas/9b428229-b1e5-4f3a-b7f9-d312566a5fcd.png", + "twitter": null, + "repos": [ + "https://github.com/miguelmota/go-ethereum-hdwallet" + ], + "tags": [ + "wallet", + "transaction-signing", + "cli" + ], + "website": "https://github.com/miguelmota/go-ethereum-hdwallet", + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "0xa873dcdcc84e0022edd2f7d5cc8646667b87bf06609d506cd8e39dbd7412fa59", + "name": "Foundry MCP Server", + "description": "A simple, lightweight and fast MCP (Model Context Protocol) server that provides Solidity development capabilities using the Foundry toolchain (Forge, Cast, and Anvil).", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/92c30ad3-b419-4f74-a24c-08bdff63059b.png", + "banner_url": null, + "twitter": "", + "repos": [ + "https://github.com/PraneshASP/foundry-mcp-server" + ], + "tags": [ + "cli", + "foundry", + "mcp-server", + "solidity-development" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xcd032b75396f45f1ef82c8a38142352afa6071fbcd840480408e10e2aab9006d", + "name": "miniapp starters", + "description": "miniapp starters is a set of open-source starter templates designed to make it easier to build Farcaster miniapps, with support for Worldcoin integrations as well.\n\nMiniapp Starters came out of our own journey building miniapps. Along the way, we found ourselves creating common patterns and components repeatedly, so we decided to turn that work into a set of reusable, community-friendly templates. Now, anyone can kickstart their own miniapp projects without reinventing the wheel.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/d5818777-1f8b-40bd-885e-22a892d7f7f7.png", + "banner_url": "https://storage.googleapis.com/op-atlas/e0127983-0358-42cb-95f7-396d8a86346a.png", + "twitter": "https://x.com/builders_garden", + "repos": [ + "https://github.com/builders-garden/base-minikit-starter", + "https://github.com/builders-garden/farcaster-miniapp-starter", + "https://github.com/builders-garden/frames-v2-starter", + "https://github.com/builders-garden/miniapp-next-template" + ], + "tags": [ + "education", + "farcaster", + "nextjs", + "tailwind-css", + "type-safe", + "analytics" + ], + "website": "https://www.builders.garden/", + "category": "Education & Community Resources" + }, + { + "id": "0xc6cac7cd3793888032cc8a9e5aef92550beeec2598f86f1ec6972ffd5b82a990", + "name": "Prettier Solidity", + "description": "A Prettier plugin for automatically formatting your Solidity code.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/0e3be68b-be6b-4833-b0ed-b53dc89a8d22.png", + "banner_url": null, + "twitter": "https://x.com/prettiersol", + "repos": [ + "https://github.com/prettier-solidity/prettier-plugin-solidity" + ], + "tags": [ + "solidity", + "code-quality" + ], + "website": "https://github.com/prettier-solidity/prettier-plugin-solidity", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xa790f0641e8d72abc88efd13ca215e2dc7e736a4a59ca5a9e0020af29d6297f2", + "name": "Crytic-Properties", + "description": "Crytic-Properties is a suite of re-usable security tests for some of the most widely used token standards such as ERC20, ERC721, ERC4626, and more.\n", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/eebeffeb-5b4e-4e8f-a8d9-09718da38b40.png", + "banner_url": null, + "twitter": "https://x.com/trailofbits", + "repos": [ + "https://github.com/crytic/properties" + ], + "tags": [ + "security", + "erc721", + "fuzz-testing", + "solidity" + ], + "category": "Security, Testing & Formal Verification" + }, + { + "id": "0x2a04bac7482169a929fd70444bbfac10654d0588e022db7527566dbfc307d2e9", + "name": "Solc-select", + "description": "Solc-select is a command line utility for quickly installing and switching between Solidity compiler versions.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/de442005-7eb7-45d9-9d69-c1f1548e855f.png", + "banner_url": null, + "twitter": "https://x.com/trailofbits", + "repos": [ + "https://github.com/crytic/solc-select" + ], + "tags": [ + "cli", + "solidity" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xb9996d35862a7c60282da2adf3447f043580f586fcb702ff6869896d15ef6344", + "name": "Medusa", + "description": "Medusa is a stateful smart contract fuzzer inspired by Echidna. It provides parallelized fuzz testing of smart contracts and the verification of advanced smart contract invariants.\n", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/69e9b03e-47d3-4770-8415-3ae65da044a4.png", + "banner_url": null, + "twitter": "https://x.com/trailofbits", + "repos": [ + "https://github.com/crytic/medusa" + ], + "tags": [ + "security", + "governance", + "analytics", + "fuzz-testing" + ], + "category": "Security, Testing & Formal Verification" + }, + { + "id": "0xdc3dce33fd5fb50cf932586d4257456ddf5040ba0955d97641646504c73dbd13", + "name": "Slither", + "description": "Slither is a Solidity and Vyper static analysis framework written in Python3. \n\nIt runs a suite of vulnerability detectors, prints visual information about contract details, and provides an API to easily write custom analyses. Slither enables developers to find vulnerabilities, enhance their code comprehension, and quickly prototype custom analyses.\n\nSlither has been used for many years by both security engineers and developers to secure their smart contracts. \n\nBy allowing developers to find the most common vulnerabilities on their smart contracts, Slither helps to improve the security of the Optimism ecosystem.\n\nSlither has 90+ detectors, and works on both Solidity and Vyper. In addition it provides printers, helping to review quickly features of contracts. It's python API can also be used to leverage its inbuilt analysis for custom needs.\n\nSlither can directly be run on a contract deployed on optimism, with `slither optim:0x..ADDRESS`", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/27ad6768-163c-4cc3-bd3e-ba8fd3ef5f50.png", + "banner_url": "https://storage.googleapis.com/op-atlas/1276f443-c160-4db0-ab75-33e3e01e3a47.png", + "twitter": "https://x.com/trailofbits", + "repos": [ + "https://github.com/crytic/slither" + ], + "tags": [ + "security", + "static-analysis", + "solidity", + "vyper", + "continuous-integration" + ], + "category": "Security, Testing & Formal Verification" + }, + { + "id": "0x7cbd306b4b54416b83eb723a79b88d09554e245b1d7b29e7e4b7958ca1011d1f", + "name": "ethdebug", + "description": "Debugging deployed smart contracts today relies on guesswork. No EVM-language compiler emits enough structured debug data. As a result, debuggers must reverse-engineer arcane details of high-level language internals—a brittle, inaccurate, and hard-to-maintain process. This slows development, impedes audits, and obscures contract behavior.\n\nThe ethdebug format is a proposed standard for debugging metadata. It’s language-agnostic, tool-friendly, and designed to map EVM execution back to source locations, control flow, data structures, and developer intent. The goal is to enable reliable debugging of deployed contracts—without requiring compiler internals or custom builds.\n\nThe format is still in development. Implementations are currently underway in solc and in multiple existing debuggers. The focus is on interoperability, minimal overhead, and incremental adoption.\n\nethdebug is part of the Argot Collective, a new organization spinning out from the Ethereum Foundation. Argot's other projects include Act, hevm, Fe, Sourcify, and Solidity.\n\nThis work directly supports Optimism’s mission to fund shared public infrastructure. A common debugging standard makes smart contracts easier to understand, audit, and build on—across chains, languages, and tools.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/3ac79cce-16e1-4a59-9557-ee1f85793674.png", + "banner_url": "https://storage.googleapis.com/op-atlas/616a8719-4bc1-4e7d-b50e-d56e45019f0b.png", + "twitter": "https://twitter.com/ethdebug", + "repos": [ + "https://github.com/ethdebug/format" + ], + "tags": [ + "education", + "debugging-tools", + "type-safe" + ], + "website": "https://ethdebug.github.io/format/", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xcdeb1723ae43478e77b36f2b6dea33f9485963a66ca951408faad33e13452e10", + "name": "WakeUp Labs | Rollup-as-a-Service for the OP Stack", + "description": "We are WakeUp Labs, a software development company focused on building open-source infrastructure for the Ethereum ecosystem and the Superchain. Our team has been working closely with the OP Stack to deliver a fully open and modular Rollup-as-a-Service (RaaS) solution.\n\nOur RaaS tooling simplifies the deployment, management, and customization of rollups on Optimism. It includes a CLI, a web console, and deployment pipelines designed to empower developers and protocols to launch their own rollups quickly and securely—without needing to manage DevOps or low-level infra.\n\nWe believe the future of Ethereum scalability lies in modular rollups, and we're building the tools to make that future accessible to everyone. Our tools are already being used by projects and contributors in the Optimism ecosystem to explore new rollup use cases and accelerate Superchain adoption.\n\nWe’re committed to pushing forward the decentralization and usability of rollup infrastructure—aligned with Optimism’s values and mission.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/4756e689-18df-4d2f-aea1-abdf6547ee51.png", + "banner_url": "https://storage.googleapis.com/op-atlas/7ad77d50-64a1-43a4-a494-e49db0974dde.png", + "twitter": "https://x.com/wakeuplabs", + "repos": [ + "https://github.com/wakeuplabs-io/op-ruaas" + ], + "tags": [ + "cli", + "scalability" + ], + "website": "https://www.wakeuplabs.io/", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x77a0eb2debb3ddd73bb629ae482d24771ef1b59029d28a04e13570c9e9644c44", + "name": "Stereum L2 Optimism Integration", + "description": "Stereum is dedicated to advancing Ethereum through open-source and open development. Our commitment lies in reducing technical barriers, supporting decentralization, and enhancing security within the Ethereum(EVM) ecosystem.\nWe integrated Optimism as an Integration into our Node Setup and Maintenance Gui based tool. Everybody is now able to spin up an Optimism node connected to a Ethereum node within minutes. Enabling low infratech people to access multilayer architectures completly by themselves, decentralized, 100% free, 100% untracked, 100% auto updated. \nAfter everytthing is synced you now are able to access \n1)your own RPC endpoint \n2)your onw data api \n3) your own websockets \nboth Ethereum and Opitimism. \nAs we would love to integrate further Optimistic rollups into our software we would be honoured and feel apreaciated if you would grant us a grant ", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/47b18b46-5440-406c-8e07-bfcf27f8aa6e.png", + "banner_url": "https://storage.googleapis.com/op-atlas/a80d7697-6c6f-4f71-bfc1-7576b933dad4.png", + "twitter": "https://x.com/stereumdev", + "repos": [ + "https://github.com/stereum-dev/ethereum-node" + ], + "tags": [ + "cli", + "docker", + "api", + "privacy-focused" + ], + "website": "https://stereum.com", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x363b77a4022f98f4d529b8a771d22f49b1092293980aab154fff63980bd1b2bf", + "name": "viem-tracer", + "description": "Debug transactions via traces by automatically decoding them with the help of openchain.xyz!\n\n- Automatically append traces to error messages of failed eth_estimateGas and eth_sendTransaction RPC requests.\n- Add support for debug_traceCall to a Viem client with correct types!", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/Rubilmax/viem-tracer" + ], + "tags": [ + "cli", + "debugging-tools" + ], + "website": "https://github.com/Rubilmax/viem-tracer", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xfbecd6308658b3d40a5249d4b249d10537165f57ea528cc796aef5ce1eb1f0d8", + "name": "executooor", + "description": "Ethereum's environment evolves fast. So fast that you can't keep up writing and deploying a new contract everytime you want to do something atomically onchain (not mentioning you also have to approve this freshly deployed contract to spend your favorite ERC20/ERC721!).\n\nWelcome the Executor contract:\n\nCalculate whatever you need to submit your execution\nChain calls / delegatecalls as needed to execute whatever you want to execute atomically onchain (using viem and/or ethers-v6!)\nOptionally prepend any ERC20/ERC721 approval via a third-party bundling service (such as Flashbots)\nSubmit your execution transaction (or bundle)\nFor MEV out there: tip the bundler\nYou can even atomically populate your chain of calls if it depends on some state change! For example, you can skim ERC20 tokens after an execution by simply requesting the balance left onchain and replacing it in the onchain call.", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/Rubilmax/executooor" + ], + "tags": [ + "defi", + "erc721", + "contract-deployment", + "transaction-optimization" + ], + "website": "https://github.com/Rubilmax/executooor", + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "0x5999c3a9311c71fd2e02078c406d417565a3d04efe52570ba294be75a5befac8", + "name": "opup", + "description": "[`opup`](https://github.com/zhiqiangxu/opup) is a one-stop installation tool for OP Stack. It has been used to deploy multiple L2 networks for Quarkchain, with the latest being available at: [Quarkchain Explorer](https://explorer.beta.testnet.l2.quarkchain.io/) .", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/43a31c8a-308e-4956-a4f4-ba61a1280c7b.png", + "banner_url": null, + "twitter": "https://x.com/EthStorage", + "repos": [ + "https://github.com/zhiqiangxu/opup" + ], + "tags": [ + "cli", + "docker", + "contract-management" + ], + "website": "https://ethstorage.io/", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x5c0234455c4b86b05ed0c612ac0d7e53cd2249686305af9b2184190b781b8063", + "name": "Surl", + "description": "HTTP Library for Solidity based on curl ", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/9379802f-3bc8-4e72-a0ad-f4a267ef4d42.png", + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/memester-xyz/surl" + ], + "tags": [ + "solidity", + "foundry" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xf4f7d13f2ac3c9805998d8540950883b872d7c5d7c81d6254dde8655af690b2a", + "name": "evmc", + "description": "a simple cli tool to load a contract code up in your IDE instantly.", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/joshstevens19/evmc" + ], + "tags": [ + "cli", + "support", + "contract-verification" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xe01f00da2ba1f43dd0dd1e2b93bbfc5a84021ded7e6d414e86fa12a8d4eeb347", + "name": "simple-uniswap-sdk", + "description": "Uniswap SDK which handles the routes automatically for you, changes in trade quotes reactive subscriptions, exposure to formatted easy to understand information, bringing back the best trade quotes automatically, generating transactions for you and much more.", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/joshstevens19/simple-uniswap-sdk" + ], + "tags": [ + "defi", + "sdk", + "multicall", + "user-experience" + ], + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x471ef1b671bc421d04640a7fe832365c1aec2d298adc81f03d69a685b7cc894c", + "name": "Loop Decoder", + "description": "Loop Decoder is a TypeScript library with minimal external dependencies that transforms blockchain data into a human-readable format.\n\nKey Features:\n- Works in any JavaScript environment\n- Minimal external dependencies - you only need an RPC; everything else can be fetched from your own storage\n- Highly customizable - we don't force you to use a specific API or storage; instead, we provide data loaders", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/b852c74f-a247-40dd-8299-90b8c7499c8c.png", + "banner_url": "https://storage.googleapis.com/op-atlas/bb135bd2-a2b6-46b1-b327-e3c8033f2f4b.png", + "twitter": "https://x.com/3loop_io", + "repos": [ + "https://github.com/3loop/loop-decoder" + ], + "tags": [ + "transaction-decoding" + ], + "website": "https://loop-decoder-web.vercel.app/", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x0cc5d7a8088f227787992130b3cffe143db1c904af1ac27324f84e762b84f35c", + "name": "Solarity", + "description": "Solidity-Oriented Development Tooling", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/9e453fca-55dd-45d9-9046-c8ee58290761.png", + "banner_url": "https://storage.googleapis.com/op-atlas/cd0944ee-9bed-445f-bcb8-ba22c80d3f57.png", + "twitter": null, + "repos": [ + "https://github.com/dl-solarity/hardhat-zkit", + "https://github.com/dl-solarity/solidity-lib" + ], + "tags": [ + "hardhat", + "education", + "solidity" + ], + "website": "https://solarity.dev/", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xb024f6abfa79f7eb7af334f56015509bb70355709991d31bc689c7bea3250f7e", + "name": "foundry-gas-diff", + "description": "Easily compare gas reports generated by Foundry automatically on each of your Pull Requests!", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/Rubilmax/foundry-gas-diff" + ], + "tags": [ + "foundry", + "cli", + "analytics", + "github-actions", + "code-quality", + "test-automation", + "continuous-integration" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xfeafe16f8c1a25aebe754f3653340a17943a483a3e389464e44cf14613e210f0", + "name": "foundry-storage-check", + "description": "- Protect your Smart Contract Proxy from storage collisions upon upgrading, by running this action in a CI on each of your Pull Requests!\n- Feel safe when extending your storage layout by trusting this action to check that extended layout is zero-ed out on-chain!", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/Rubilmax/foundry-storage-check" + ], + "tags": [ + "foundry", + "cli", + "devops", + "github-actions", + "solidity", + "storage-layout", + "code-quality", + "security" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x48220ef1d103189cd918e9290db4c4b99b463ae2817fb5ef0cc54556a7961b6f", + "name": "keccak256js", + "description": "A wrapper for the keccak library to compute 256 bit keccak hash in JavaScript.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/b092dff2-6e21-451c-9946-2f02e2986c8f.png", + "banner_url": "https://storage.googleapis.com/op-atlas/e3093f96-c4b6-478e-bde2-19e96a7fa7a3.png", + "twitter": null, + "repos": [ + "https://github.com/keccak256js/keccak256" + ], + "tags": [ + "encryption" + ], + "website": "https://github.com/keccak256js/keccak256", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x3ec2d572a608cf939eaf7886402320b3b2229610c13bdb5cb0776bd097331e5a", + "name": "VSCode Solidity Inspector ", + "description": "This is a VSCode extension offering utilities for solidity smart-contract development. \n\nSome features:\n- Storage layout viz.\n- Inline highlighting in code editor for unused imports.\n- Generate and view - Foundry deployment report in a clean and concise table format.\n- Syntax highlighting of for .tree files.\n- Generate foundry test stub using bulloak's scaffold command.\n- Auto-complete path suggestions for importing files and dependencies (with forge remappings support).\n- Contract code size decorator.\n\nMore cool utilities planned to be released. ", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/1e11eb35-ddb5-4385-bf18-2231ce727db9.png", + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/PraneshASP/vscode-solidity-inspector" + ], + "tags": [ + "foundry", + "vscode-extension", + "solidity-development", + "storage-layout", + "code-analysis" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xf152ccbfb3aa63c2ddcc070dc6d4462368eb25b69c3c3137cc459189af681402", + "name": "Derive Exchange SDK and Vault Executors", + "description": "Derive's market making library provides a Client / SDK for Derive Exchange, types, automated trading algorithms, vault executors, and more. This Client SDK is open sourced and generalizable for use in market making and algo trading on hybrid orderbooks across the Superchain!\n\nDerive is one of the first op-stack rollups delivering trustless, on-chain portfolio margin for options, spot and perpetual futures as well as structured products and fixed/floating rate lending markets. Derive has cleared over $15B in notional volume and has +$100M TVL", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/50bfdcb2-8355-4480-b530-df8cdc97e3da.png", + "banner_url": "https://storage.googleapis.com/op-atlas/e2df36a1-d787-4875-a156-ffba6dcd0b5f.png", + "twitter": "https://x.com/derivexyz", + "repos": [ + "https://github.com/derivexyz/cockpit" + ], + "tags": [ + "defi", + "docker", + "cli" + ], + "website": "https://www.derive.xyz/", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0xbd393d380c995845e0b26365d91e9730403baa30b4a80e955be1ab5713bba709", + "name": "Black Scholes library/compiler - go and rust ", + "description": "Derive is one of the first op-stack rollups delivering trustless, on-chain portfolio margin for options, spot and perpetual futures as well as structured products and fixed/floating rate lending markets. Derive has cleared over $15B in notional volume and has +$100M TVL\n\nDerive's Black Scholes library/compiler into go and rust, research and testing in this area has led to 1 Black Scholes equation using ~300 gas while native EVM would be ~10K gas for a 30X more efficient computation of pricing and risk of any options related logic. ", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/69edd7f3-606d-4191-b7c8-28e41246b2d0.png", + "banner_url": "https://storage.googleapis.com/op-atlas/b753d4c0-96c7-4b36-b70e-e2785f9006bd.png", + "twitter": "https://x.com/derivexyz", + "repos": [ + "https://github.com/derivexyz/op-geth" + ], + "tags": [ + "defi", + "gas-optimization" + ], + "website": "https://www.derive.xyz/", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x46aff4985914b8e56b8fd62a9b8c3a03e2320315a9dfd6126e5ae272173cda87", + "name": "Patterns wallet analytics & CRM", + "description": "Free public web3 CRM and wallet analytics for OP builders. Helping OP dApps & DeFis discover most valuable user groups and counteract sybils. Part of the Optimism Superchain 4337 Data Standards group.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/ee4b3aab-f2b2-4400-abbc-2383b62662a4.png", + "banner_url": "https://storage.googleapis.com/op-atlas/b3b3b9a2-81bd-4e6b-af22-c388ca45c9f5.png", + "twitter": "https://x.com/patterns_build", + "repos": [ + "https://github.com/tokenguardio/dapp-marvels" + ], + "tags": [ + "analytics", + "defi", + "visualization", + "docker", + "scalability" + ], + "category": "Data, Analytics & Tracing" + }, + { + "id": "0xc66e357ad67e63954cd1eb79da4d507d8800518f06c82e423e93e8771e7b8d13", + "name": "Brahma", + "description": "Brahma provides the infrastructure for automated operations from any source with programmable accounts, specialized agents, and developer tools that keep users in control at all times.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/b62d6708-d690-41e7-b574-4c8d6c728610.png", + "banner_url": "https://storage.googleapis.com/op-atlas/fd66f5d9-996c-4b69-8c0d-d7b4d9a2dc91.png", + "twitter": "https://x.com/BrahmaFi", + "repos": [ + "https://github.com/Brahma-fi/console-kit" + ], + "tags": [], + "website": "https://www.brahma.fi/", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x90bbb485004d99e20be133d2c26abc1f63a2c1ec8107358e87853b001bfb6597", + "name": "Updraft", + "description": "What is Cyfrin Updraft?\nCyfrin Updraft is the leading blockchain development and smart contract security education platform, offering over 100+ hours of hands-on courses that enable aspiring and experienced smart contract developers to level up their skills. Designed and taught by CEO Patrick Collins alongside industry-leading educators and researchers, our platform provides high-quality, free educational content, hands-on coding experiences, and industry-recognized Cyfrin Updraft Certifications, which verify developers’ expertise in Solidity, Vyper, DeFi, and smart contract security.\n\nUpdraft has educated millions of developers globally, equipping them with the skills necessary to build secure and scalable decentralized applications. \n\nKey Metrics:\n220K+ Updraft community members\n1M+ Monthly impressions\n60K+ Monthly active developers\n15K+ Monthly new students\nTrusted by developers from top Web3 companies and protocols\n\nWhat are the Issues with the Existing Web3 Landscape?\nDespite the rapid growth of Web3, developers face several challenges:\n- Lack of accessible, high-quality education: Most resources are either too theoretical or fragmented, making it difficult for developers to gain practical experience.\n- Security vulnerabilities: Many developers lack the knowledge to build secure smart contracts, leading to exploits and hacks that result in millions in losses.\n- High entry barriers for Web2 developers: The transition from traditional development to Web3 remains complex due to unfamiliarity with blockchain infrastructure and tooling.\n- Limited developer retention: Many developers struggle to find long-term engagement opportunities within blockchain ecosystems. \n- No standardized skill validation: Without recognized certifications, it is difficult for developers to showcase their expertise, limiting their career opportunities.\n- Lack of security best practices: Without proper training and certification, developers may unknowingly introduce vulnerabilities, increasing the risk of hacks.\n\nHow Is Cyfrin Updraft Fixing the Issue?\nCyfrin Updraft addresses these challenges by providing:\n- Comprehensive blockchain development education: Covering Solidity, Vyper, Foundry, infrastructure, security best practices, and more.\n- Project-based learning: Developers gain hands-on experience by building and deploying real-world applications.\n- Security-first approach: Courses emphasize smart contract security, audit methodologies, and best practices to prevent exploits.\n- Developer tooling and ecosystem integrations: We create open-source tools and frameworks that enhance developer efficiency and security.\n- Bridging Web2 and Web3: Providing structured learning paths to onboard Web2 developers into Optimism’s ecosystem.\n- Completely free access: Updraft courses are entirely free, ensuring that any developer, regardless of financial constraints, can access high-quality education and build the skills needed to succeed in Web3.\n- Validation of Skills: Certifications provide a standardized way to verify a developer’s expertise, helping them stand out in a competitive job market.\n\nWho is Cyfrin Updraft For?\n+ Aspiring Web3 Developers - For newcomers eager to break into blockchain development, Cyfrin Updraft provides a structured and accessible learning path. Our courses start with fundamental concepts, gradually building up to advanced smart contract development, security topics, full stack development, infrastructure development and advanced DeFi dApp development . With hands-on coding exercises, real-world project deployments, and Cyfrin Updraft Certifications, aspiring developers can establish themselves in the industry, build secure and scalable dApp, and demonstrate their skills to potential employers.\n+ Experienced Web3 Engineers - For developers already working in the Web3 space, Cyfrin Updraft serves as a hub for continuous learning and skill enhancement. Advanced courses on smart contract security, DeFi mechanisms, and protocol architecture help engineers stay ahead of industry trends. Our Cyfrin Updraft Certifications validate expertise in Solidity, Vyper, and security best practices, distinguishing top engineers in a competitive job market. \n+ Web2 Developers - Traditional software engineers looking to transition into blockchain development often struggle with understanding decentralized technologies and smart contract principles. Cyfrin Updraft bridges this gap by providing a structured, Web2-friendly onboarding experience. Our courses explain blockchain fundamentals in a way that resonates with Web2 developers, drawing parallels between familiar programming concepts and smart contract development. For example, we’ve developed a Vyper Smart Contract Development course specifically to support onboarding Web2 developers, ensuring they gain hands-on experience with secure and efficient smart contract programming. This approach aligns with Updraft’s mission to scale Web3 adoption by equipping developers with the knowledge and tools they need to seamlessly transition into the decentralized ecosystem.\n+ Protocol and dApp Teams - Organizations need skilled developers who understand smart contract security, scalability, and best practices. Cyfrin Updraft helps protocol teams and dApp builders by providing a reliable pipeline of trained, certified engineers. Through Cyfrin Updraft Certifications, hiring teams can verify a candidate’s expertise, reducing onboarding time and improving the quality of development within their projects. Additionally, protocols can collaborate with Cyfrin Updraft to develop custom training programs, ensuring their developer communities are well-versed in their technology stack.\n\nWhat is the Roadmap for Cyfrin Updraft?\nQ1 2025: Courses & Foundational Expansion\n1. Launch a Full Stack Development Course\nThis course will provide a comprehensive learning experience for developers looking to build dApps from the ground up.\nThe course covers modern frontend frameworks (React, Next.js, Svelte), Web3 libraries (ethers.js, viem, wagmi), and backend infrastructure (site hosting, event indexing, caching strategies). \nDevelopers will build real-world projects, including a basic Ethereum dApp, a decentralized NFT marketplace, and an advanced DeFi interface with account abstraction.\n2. Launch Curve Cryptoswap Course\nA deep dive into the mechanics of Curve Finance’s automated market maker (AMM) designed for stablecoin swaps.\nThe course will explore the math supporting Curve Cryptoswap’s AMM, how liquidity is concentrated, and how the AMM decides to repeg the pool's liquidity at a different price.\nDevelopers will progress through AMM function calls, state variables, swapping tokens, adding and removing liquidity, and price-repegging. The learning is supported at every stage with quizzes and exercises.\n3. Launch Uniswap V3 Course\nThis course will focus on Uniswap V3’s concentrated liquidity model, fee tiers, and capital efficiency improvements.\nAn advanced DeFi developer course designed to enable developers to build Uniswap V3-based protocols\nThe course covers Uniswap V3 math and concentrated liquidity, progressing through swaps and the factory contract, the fee algorithms, and the TWAP price oracle.\n4. Launch SSCD+ (Smart Contract Security & Development) Certifications\nSSCD+ Certification is the premier certification for Solidity developers, recognized by industry-leading protocols and university organizations. This certification validates developers’ expertise in writing, testing, deploying, and troubleshooting Solidity smart contracts.\nKey skills that developers will be tested include proficiency in Solidity development, application of industry best practices, smart contract security expertise, mastery of industry-standard development tools, protocol-specific knowledge, blockchain DevOps skills\n\nQ2 2025: Advanced Security & Infrastructure Expansion\n1. Launch an Updraft Ambassador Program\nThe program will empower university students and community leaders to advocate for Web3 and Cyfrin Updraft, engage developers, host workshops and hackathons on campuses and in developer communities.\nAmbassadors will receive early access to Updraft certifications and mentorship from the Updraft team.\nThrough Updraft's ecosystem, students will gain practical experience in blockchain education, networking opportunities, and potential internships or job placements.\n2. Blockchain and Smart Contract Curriculum for Universities\nUpdraft will collaborate with top universities to integrate blockchain and smart contract development courses into academic curriculums.\nThis will include customized coursework, hands-on projects, and guest lectures from Web3 industry leaders.\nUniversities will be able to provide blockchain education at scale, helping bridge the gap between traditional computer science education and Web3 development.\n3. Launch a Jobs Board\nThe Updraft Jobs Board will connect certified developers with leading Web3 companies and protocols.\nDevelopers who complete Updraft’s courses and certifications will have access to job listings and hiring opportunities.\nEmployers will be able to filter candidates based on certifications and project experience, making the hiring process more efficient.\n4. Launch Vyper and Smart Contract Security+ Certification Program\nVyper+ Certification is a specialized certification focused on smart contract development using Vype. This program will cover Vyper syntax, best practices, contract patterns, and optimization techniques, ensuring developers can build secure and efficient Vyper-based applications.\nSmart Contract Security+ Certification is a security-focused certification that validates a developer’s ability to audit and secure smart contracts written in Solidity. This program will cover common vulnerabilities, formal verification, attack vectors, auditing methodologies, and best practices.\n\nQ3 2025: Developer Engagement & Retention\n1. Launch an Infrastructure Development Course\nThis course will focus on blockchain infrastructure, node operations, and MEV-related optimizations.\nDevelopers will learn how to build and run their own validators, set up RPC nodes, and optimize blockchain indexing. They will also gain a deep understanding of key Web3 infrastructure components, explore Layer 2 architecture, build custom L2 solutions, and evaluate infrastructure architecture trade-offs.\n2. Launch Live Cohort Learning Model\nCyfrin Updraft will introduce 8-week intensive live cohorts, where students will work through the curriculum alongside mentors, teaching assistants, and AI-driven learning support.\nEach cohort will focus on hands-on, project-based learning, ensuring participants gain practical experience building and securing Web3 applications.\nBy the end of the cohort, students will earn Updraft certifications and have portfolio-ready projects to showcase their skills.\n\nQ4 2025: Web2 to Web3 Expansion & Industry Integration\n1. Expand Integration with Enterprise Use Cases\nUpdraft will develop tailored educational programs for enterprise developers, helping businesses adopt blockchain technology.\nThis will involve customized workshops, tooling integration guides, and real-world enterprise case studies.\nThe goal is to bridge the gap between traditional Web2 development and Web3 innovation, making it easier for institutional developers to enter the space.\n", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/6c522dd8-66e1-441b-b54c-156886a50dd1.png", + "banner_url": "https://storage.googleapis.com/op-atlas/9cca66f9-2eef-4e2b-bc3c-515f52312848.png", + "twitter": "https://x.com/CyfrinUpdraft", + "repos": [ + "https://github.com/Cyfrin/Updraft" + ], + "tags": [ + "education", + "defi", + "solidity-development", + "community-driven" + ], + "website": "https://www.cyfrin.io/updraft", + "category": "Education & Community Resources" + }, + { + "id": "0x62d9a8a3b602c688610abfbe3965e04ca0d19c5c506f40e79cd185cb501d2018", + "name": "noble cryptography", + "description": "noble cryptography is a high-security, easily auditable set of contained cryptographic libraries with following features:\n\n- Zero or minimal dependencies\n- Highly readable TypeScript / JS code\n- PGP-signed releases and transparent NPM builds\n\nnoble cryptography is used in most modern JS wallets, including Metamask, Rabby, Rainbow, various SDKs, and others. Essentially it empowers a huge share of ecosystem.", + "thumbnail_url": null, + "banner_url": null, + "twitter": "https://x.com/paulmillr", + "repos": [ + "https://github.com/paulmillr/noble-curves", + "https://github.com/paulmillr/noble-hashes", + "https://github.com/paulmillr/noble-ciphers" + ], + "tags": [ + "wallet", + "security", + "encryption" + ], + "website": "https://paulmillr.com/noble/", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0xded45f5b4e2be2487ef301591cf49859e95ed6d2b33743a0c0b5e15c25e17694", + "name": "UTP Java Library", + "description": "A non-blocking UTP library in Java that avoids defining the transportation layer. Ready to be used using UDP or discv5. ", + "thumbnail_url": null, + "banner_url": null, + "twitter": "https://x.com/meldsun0", + "repos": [ + "https://github.com/meldsun0/utp" + ], + "tags": [ + "networking", + "peer-to-peer", + "real-time-data" + ], + "website": "https://github.com/meldsun0/utp", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0xe9495ac0f2a00d424f4f2dca80fe34c59c78d5cbf9acad0536c4c0ede540e053", + "name": "Mobile Wallet Protocol in Unity", + "description": "MWP is a protocol to allow unity games to interact with wallet apps and access users' web3 accounts. It creates a direct channel between client and wallet apps, removing the need for an intermediary bridge or relay server.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/8ad9f3a8-ac4a-4b5d-8652-4be22cf47ea0.png", + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/openfort-xyz/mobile-wallet-protocol-unity-client" + ], + "tags": [ + "wallet", + "game-development", + "user-experience" + ], + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "0x44ff313ae6fb57054de6d637adae710594180239badaf2bc51889d068f4cf02b", + "name": "Modular Account", + "description": "Alchemy's Modular Account is a maximally modular, upgradeable smart contract account that is compatible with ERC-4337 and ERC-6900. Alchemy's Modular Account most efficient smart account on the market with release of v2 released in feb 2025", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/ff0b8f78-e997-4a50-ae49-6aaad2273213.png", + "banner_url": "https://storage.googleapis.com/op-atlas/2e157a8d-e9e1-4dbe-a0c0-ff6d908f9040.png", + "twitter": "https://x.com/alchemy", + "repos": [ + "https://github.com/alchemyplatform/modular-account", + "https://github.com/alchemyplatform/multisig-plugin", + "https://github.com/alchemyplatform/aa-benchmarks" + ], + "tags": [ + "wallet", + "defi", + "governance", + "security", + "modular-accounts", + "upgradeable-contracts", + "developer-experience" + ], + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "0x4e13be6b98dd868cd13e9f4101431ab03d211f429b63f078fa7da260b54d256a", + "name": "Light Account", + "description": "A set of lightweight, open sourced, audited and gas-optimized ERC-4337 compatible smart contract accounts with designated ownership", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/646cd1db-23b4-4328-8a7c-6c58358a73e1.png", + "banner_url": null, + "twitter": "https://x.com/alchemy", + "repos": [ + "https://github.com/alchemyplatform/light-account" + ], + "tags": [ + "wallet", + "account-abstraction", + "solidity", + "foundry" + ], + "website": "https://www.alchemy.com/", + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "0x0c85267cd9d7e694e385467c9984fbc787228db0cf03e57254a5116001eac4ee", + "name": "Tachyon", + "description": "Rath's Tachyon is a high-speed, low-latency relayer and bundler supporting EOA and AA transactions.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/6d42b8ec-216a-4904-ab39-ce60a80ee867.png", + "banner_url": "https://storage.googleapis.com/op-atlas/87fd037d-1b02-4325-b910-882245e95e7b.png", + "twitter": "https://x.com/rathfinance", + "repos": [ + "https://github.com/RathFinance/tachyon-account", + "https://github.com/RathFinance/tachyon-forwarder" + ], + "tags": [ + "performance-optimization" + ], + "website": "https://rath.fi/", + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "0x2ccf4b9bd6ed894c10befd9fe00c467c4bfd84ff057ee956ab708259cfa845a9", + "name": "CodeTracer", + "description": "CodeTracer is a user-friendly time-traveling debugger designed to support a wide range of web3 programming languages.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/9e4b845e-5d97-4c91-a67e-94aab4a07a24.png", + "banner_url": "https://storage.googleapis.com/op-atlas/d2d38c2e-ba3a-4338-84fb-f78873866813.png", + "twitter": null, + "repos": [ + "https://github.com/metacraft-labs/codetracer" + ], + "tags": [ + "cli", + "education", + "event-logging", + "performance-optimization" + ], + "website": "https://www.codetracer.com", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x3a942492f564e13e4a3fc11e9a8b5dcd8bf0213f9dd8571d888f32db84271c5f", + "name": "evm-rpcs-list", + "description": "Easy to use package with List of EVM chains & their RPCs in one place. Sourced from chainlist.org.\n\nUsage:\n`npm i evm-rpcs-list`\n`import networksList from \"evm-rpcs-list\";`", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/9a276191-f180-425f-96b5-c51e12ef35c2.png", + "banner_url": "https://storage.googleapis.com/op-atlas/c3df0213-1859-4bde-abbb-80a949304062.png", + "twitter": null, + "repos": [ + "https://github.com/apoorvlathey/evm-rpcs-list" + ], + "tags": [ + "chains" + ], + "website": "https://www.npmjs.com/package/evm-rpcs-list", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xf00e745fe6d96359adc3dc45d6d811bf1140549ad830d927cda5ca0b694a3063", + "name": "EIP.Tools", + "description": "Explore all EIPs, ERCs, RIPs and CAIPs at one place! Even indexes the EIPs in WIP status that have PRs open.\n\n- Search Functionality against all Improvement Proposals by No. or Title\n- EIP_GPT to summarize & get a gist of each Proposal\n- 3D Graph to visualize the interconnected nature of all the EIPs/ERCs\n- See Trending EIPs on the homepage\n- Bookmark and share your list of Improvement Proposals with others\n- EIP of the Day: learn about a random EIP/ERC each day", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/61e344ec-18c4-4a72-9d97-40c1d8f112b1.png", + "banner_url": "https://storage.googleapis.com/op-atlas/d2dbff0b-870e-4ef7-8cb2-4661de764405.png", + "twitter": "https://x.com/EIPTools", + "repos": [ + "https://github.com/EIPTools/eip-tools" + ], + "tags": [ + "analytics", + "visualization", + "interactive-tools" + ], + "website": "https://eip.tools/", + "category": "Data, Analytics & Tracing" + }, + { + "id": "0x492486eda6bcb71b4891dd39a4e150db1f7ab46f64b83f2f5a02aed82497e9ed", + "name": "forge-stack-tracer", + "description": "CLI tool that converts your Foundry test output into interactive stack traces!\n\n✨ Powered by Swiss-Knife.xyz Calldata Decoder to decode even the unverified contracts!\n\nUsage:\nSimply pipe the forge tests result into fst.\n```forge test --mt test_case -vvvv | fst```", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/ed6e47cb-2456-42fb-ad28-8e23cef7f18c.png", + "banner_url": "https://storage.googleapis.com/op-atlas/ca1ea496-ccaa-4393-86b6-d14fc1e9c8f7.png", + "twitter": null, + "repos": [ + "https://github.com/swiss-knife-xyz/forge-stack-tracer" + ], + "tags": [ + "cli", + "foundry", + "testing" + ], + "website": "https://www.npmjs.com/package/forge-stack-tracer", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x93c4efb5e2d7416c56ecdcd8244be8faf924194d65b514d90a7a51f6797cc012", + "name": "Swiss-Knife.xyz", + "description": "Swiss-Knife aggregates all the useful EVM tools in one place to ease developer experience while they are debugging or building new stuff.\n\nList of Tools:\n1. Explorer: Quickly view any address/ens or transaction across a variety explorers, in just a click!\n2. Calldata: Decode any calldata, and view the parameters in a human-readable format, even without having the contract ABI.\n3. Transact: Send custom bytes calldata to transact with any contract, or leave the address blank to deploy a new contract.\n4. Converter: All the essential unit converters on one-page. Convert between:\n i. Ether, wei & gwei\n ii. Hexadecimal, decimal & binary\n iii. String or hex to keccack256 hash & 4 bytes selector\n iv. Hex to 32 bytes left-padded & right-padded values\n5. Constants: Have frequently used constants at your fingertips, like Zero Address, Max Uint256, etc.\n6. Epoch-Converter: Grab unix timestamp, get timestamp x minutes/hours/days in the future, or convert timestamp to human-readable format.\n7. Storage-Slots: Query EIP-1967 slots or custom storage slot value of any contract.\n8. Uniswap: Calculator to convert UniswapV3 tick to price for any token pair addresses.\n9. Character Counter: Count the length of the input string. Also allows to select on the input text to only get the character count for the selection.\n10. Contract Address: Determine the contract address which will get deployed by an address at a particular nonce", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/1eba0c98-3ab5-4bce-b365-607e76aa8778.png", + "banner_url": "https://storage.googleapis.com/op-atlas/e07ffbf7-525f-4fd4-b5fd-bec83fd940eb.png", + "twitter": "https://x.com/swissknifexyz", + "repos": [ + "https://github.com/swiss-knife-xyz/swiss-knife" + ], + "tags": [ + "frontend", + "analytics", + "developer-experience", + "debugging-tools", + "contract-deployment", + "nextjs" + ], + "website": "https://swiss-knife.xyz/", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x07222a857f4522026d91faec337e3cb8cf6ec5f7afb823e0742e1a6c398b81ff", + "name": "Impersonator.xyz", + "description": "Log-in to dapps as any address via WalletConnect, iFrame or Browser Extension\n\nImpersonator has benefitted the following Optimism users:\n- Traders: With impersonator they can log-in to dapps as whale wallets and study how they have setup their positions in detail.\n\n- Dapp users: They can access dapps on-the-go in view-only mode! They no longer have to keep their Metamask or Hardware wallet nearby just to visit the dapp dashboard. Impersonator works without private-keys.\n\n- Developers:\n- They can test how their dapp would respond for users with various token balances\n- Grab the transaction calldata being generated by dapps and simulate it via tenderly", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/5e04e1b5-a4b2-4755-89cf-6a155eff4aab.png", + "banner_url": "https://storage.googleapis.com/op-atlas/0417f6b7-6016-4141-8a9e-7b47a29a3a1f.png", + "twitter": null, + "repos": [ + "https://github.com/impersonator-eth/impersonator", + "https://github.com/impersonator-eth/impersonator-extension" + ], + "tags": [ + "wallet", + "user-experience", + "react-app" + ], + "website": "https://impersonator.xyz/", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xd35cc78b456bf11d4acc96d2c227b29fa4115ad9d93ae211a31974a408ed8303", + "name": "Diffuse Data Feeds", + "description": "Diffuse's Price Feed Oracles offer a next-generation solution for accessing real-time, verifiable pricing data on any EVM-compatible L1 or L2 blockchain. \n\nBuilt on Diffuse's zkServerless protocol, this product redefines how price data is delivered by ensuring high-speed, trustless, and cryptographically secure updates for decentralized finance (DeFi) applications and beyond.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/0835fe6c-4d7d-4d2b-9f76-00fe91acd72b.png", + "banner_url": "https://storage.googleapis.com/op-atlas/3acbc145-3b84-44d7-b62b-7a39b5f0ac7e.png", + "twitter": "https://x.com/DiffuseFi", + "repos": [ + "https://github.com/Diffuse-fi/datafeed-cli" + ], + "tags": [ + "defi", + "real-time-data", + "cli", + "verification" + ], + "website": "diffuse.fi", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xafb4dc19ccc63057da88110df49234b311044bc73b070041bb8df03e583943ab", + "name": "Abi Ninja", + "description": "**ABI Ninja provides an intuitive frontend for contracts from the most popular EVM networks, currently supporting:**\n\n- **Verified contracts**: Fetch contract ABIs and source code directly using Etherscan's API.\n- **Unverified contracts**: Two different options are available:\n\n 1. Provide the ABI and the contract address.\n 2. Decompile using heimdall-rs.\n\n- **Proxy contracts**: Autodetects most popular proxy patterns, and allows to read and write as proxy.\n\n![UI Image 1](https://raw.githubusercontent.com/BuidlGuidl/abi.ninja/main/.github/img/ui1.png)\n\n**It includes some nice features like:**\n\n- (mainnet!) ENS resolution on address inputs.\n- Shareable URLs with cool dynamic unfurl.\n- Show TX results.\n- Friendly UI even for complex data structures, now with dark mode!\n- Custom and Local Chains Support – Add or remove networks from a large selection, manually configure custom chains, or debug local contracts on chain ID 31337 (localhost).\n\n![UI Image 2](https://raw.githubusercontent.com/BuidlGuidl/abi.ninja/main/.github/img/ui2.png)\n \n \n*OP RetroFunding Rounds reported in the Funding Source section were for BuidlGuidl itself or other BuidlGuidl projects, not directly linked to Abi Ninja.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/83588cc2-f155-4b2c-8ff1-1347f2113c4d.png", + "banner_url": "https://storage.googleapis.com/op-atlas/bbb0dc26-29e0-42f6-a114-196bd042d3f8.png", + "twitter": null, + "repos": [ + "https://github.com/BuidlGuidl/abi.ninja" + ], + "tags": [ + "frontend", + "contract-interaction", + "proxy-contracts" + ], + "website": "https://abi.ninja/", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xc0809225b6287417d08ec0fde8d632ecc935296e61e239e7e44559c7dd7f2495", + "name": "Crawling the Ethereum P2P network with Nebula", + "description": "The ProbeLab team has developed advanced crawl tooling to gather important information on the structure of Ethereum's P2P network. The results are published weekly on Mondays at: https://probelab.io and report results for the previous week. The primary tool used to extract these results is the well-known and widely-used Nebula crawler.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/b48a5502-4473-4614-966a-c8581279a95b.png", + "banner_url": "https://storage.googleapis.com/op-atlas/b6aa707f-e3bd-43ea-965f-aef868ce0c6d.png", + "twitter": "@yiannisbot", + "repos": [ + "https://github.com/probe-lab/website", + "https://github.com/dennis-tra/nebula" + ], + "tags": [ + "analytics" + ], + "category": "Data, Analytics & Tracing" + }, + { + "id": "0x7f330267969cf845a983a9d4e7b7dbcca5c700a5191269af377836d109e0bb69", + "name": "IPFS", + "description": "IPFS (InterPlanetary File System) is a peer-to-peer protocol designed to make the web faster, more open, and more resilient. By using content-addressed storage rather than location-based references, IPFS removes the need for centralized servers and allows files to be distributed and retrieved from multiple nodes around the world. This approach lowers hosting costs, improves data availability, and reduces censorship, laying the groundwork for a more secure and permanent global information network.\n\nIPFS is used in a variety of applications. While some users interact with IPFS via imported libraries in their projects, a large amount of usage comes via IPFS' HTTP Gateway API which allows users to self-host, use extensions like IPFS companion, or publicly run gateways (whether paid ones run by companies like Filebase, Pinata, etc. or the public goods services at ipfs.io and dweb.link).\n\nIPFS is a system for moving data across decentralized networks, with >11M weekly users and 250K public p2p nodes. Highlights:\n\n1. Off-chain storage. IPFS provides verifiable, off-chain storage, often used to reduce on-chain needs in Ethereum & Optimism. Examples: TrueBlocks (local IPFS-based index for EVM chains, built with grants from OP & EF), Snapshot (IPFS-based off-chain voting).\n\n2. Go-to distribution network for fully decentralized third-party app frontends (for gaming, DeFi, & more). We run gateway services that serve 900M requests/wk, and added native IPFS support to browsers like Chromium & Brave.\n\n3. NFT metadata gold standard. Over 115M NFTs are stored on IPFS, including leading platforms OpenSea (which supports Optimism NFTs), Rarible, and Zora.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/fca3aa6c-bdd5-4632-ae64-37b886d50a65.png", + "banner_url": "https://storage.googleapis.com/op-atlas/35658254-c8b6-4562-9690-db91f187a7ff.png", + "twitter": "https://x.com/ipshipyard", + "repos": [ + "https://github.com/ipfs/service-worker-gateway", + "https://github.com/ipfs/helia", + "https://github.com/ipfs/kubo", + "https://github.com/ipfs/boxo", + "https://github.com/ipfs/js-kubo-rpc-client", + "https://github.com/ipfs/protons", + "https://github.com/ipfs/js-ipns", + "https://github.com/ipfs/helia-delegated-routing-v1-http-api", + "https://github.com/ipfs/js-stores" + ], + "tags": [ + "peer-to-peer", + "censorship-resistant", + "cli" + ], + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x7697147650b4b717ce5675982f2102da7c030498628fe37e3f403f875622b7f7", + "name": "Gelato Relay SDK", + "description": "Gelato Relay SDK offers a convenient suite of functions in order to interact with the Gelato Relay API. Gelato Relay API is a service that allows users and developers to get transactions validated fast, reliably and securely, without having to deal with the low-level complexities of blockchains. As requests are submitted to Gelato Relay, a network of decentralised Gelato Executors will execute and get the transactions validated as soon as possible. EIP-712 signatures enforce the integrity of data, while gas fee payments can be handled in any of our supported payment methods. In this way, developers can rely on Gelato's battle-tested blockchain infrastructure improving the UX, costs, security and liveness of their Web3 systems.​ ", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/gelatodigital/relay-sdk" + ], + "tags": [ + "security", + "sdk" + ], + "website": "https://www.gelato.network/relay", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0xa492e54cf4d492c5f8a9c16038b4e5d47cd3bac575fbea7979f5cd1f1e575482", + "name": "Gelato Automate SDK", + "description": "Automate your smart contracts using Automate SDK", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/3d382dad-0b66-475d-a13c-43fddf27d5cc.png", + "banner_url": "https://storage.googleapis.com/op-atlas/635c79ee-de4c-431e-8ce8-cb47fedb91ce.png", + "twitter": null, + "repos": [ + "https://github.com/gelatodigital/automate-sdk" + ], + "tags": [ + "sdk", + "contract-interaction" + ], + "website": "https://www.gelato.network/web3-functions", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x670a2982f6d7786b58a8399bcabc23246365b21e533a97945e055791fc235e64", + "name": "Hardhat", + "description": "Hardhat is a development environment to build and deploy your Ethereum software", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/4659da93-959f-4622-bce7-0bf1b3ac0f5c.png", + "banner_url": "https://storage.googleapis.com/op-atlas/ef35fb80-418b-4c0b-a933-a11f7a3749d4.png", + "twitter": "https://x.com/HardhatHQ", + "repos": [ + "https://github.com/NomicFoundation/edr", + "https://github.com/nomicfoundation/hardhat" + ], + "tags": [ + "cli", + "hardhat", + "code-analysis", + "devops", + "performance-optimization", + "community-driven" + ], + "website": "https://hardhat.org/", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xaec1c406b2a124ec90aeebdde35c6c0cd9a90f0c7730b0911d2f648c8b99d062", + "name": "Variance_dart", + "description": "Core Technology Development\n\nvariance_dart: Developed a comprehensive dart package enabling passwordless dApps with passkey support, reaching v0.1.9 with over 500+ weekly downloads.\n\nWeb3_signer: Created a companion package supporting EIP-1271 message signing with multiple authentication methods (passkeys, HD wallets, private keys), processing over 200+ signatures weekly.\n\nENS Normalize: Implemented the full ENSIP-15 standard in Dart. Passes 100% of the official validation tests and recognized by the ENS DAO and ENS community.\n\nIndustry Recognition & Integration\n\nENS Community Recognition: Featured in ENS DAO newsletter.\n\nDeveloper Adoption: Achieved 13+ GitHub stars and 5+ forks across repositories, with an active contributors.\n\nSDK Reliability: Maintaining 99.9% uptime with average response time under 50ms for core SDK functions\n\nStrategic Partnerships\n\nVoltage Finance (Fuseio) Integration: Powered account abstraction for their new decentralized wallet, enabling 50,000+ users to perform gasless transactions and reducing user onboarding friction by 73%\n\nLearnWay Collaboration: Implemented education-focused blockchain tools serving 2000+ students and gamers eliminating gas fees for 4 key educational interactions:\n\nClaim sign-in bonuses \nStart/join quiz sessions \nAward distributions\nReduced failed transactions by 96% compared to traditional wallet interactions\nLearnWay used to be a web2 application driving incentivized learning for the blockchain. They choose Variance to transition to the Lisk blockchain.\n\nAdditional Technical Achievements\n\nTransaction Optimization: Reduced gas consumption by 43% through batched transactions and advanced bundling techniques.\n\nCross-Chain Support: Extended functionality to 6 major EVM-compatible chains, including Ethereum, Polygon, Arbitrum, Optimism, and Base.\n\nMobile Integration: Developed native mobile SDKs for iOS and Android, reducing integration time from 2 weeks to 3 days\n\nBusiness Impact\n\nUser Onboarding: Partners using Variance tools have seen 68% higher user retention compared to traditional Web3 onboarding.\n\nTransaction Success: Improved transaction success rates from industry average of 87% to 99.3% through intelligent gas estimation and retry mechanisms.\n\nEnterprise Adoption: Secured 2 enterprise-level implementations, including a financial institution leveraging account abstraction for treasury management.\nExtended functionality to mobile platforms with native integrations for hardware features like NFC\nBuilt infrastructure supporting cross-chain operations through custom bridge solutions\n", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/fcae3c08-8e11-40f9-a738-4a8e3c5f59d7.png", + "banner_url": "https://storage.googleapis.com/op-atlas/013ad3c8-5ddc-47ed-aff1-8476d46e30b6.png", + "twitter": "https://x.com/vaariance", + "repos": [ + "https://github.com/vaariance/variance-dart" + ], + "tags": [ + "wallet", + "education", + "sdk", + "account-abstraction", + "transaction-signing" + ], + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "0xc377ed1b705bcc856a628f961f1e7c8ca943e6f3727b7c179c657e227e8e852c", + "name": "MerkleTreeJS", + "description": "A JavaScript library to construct Merkle Trees and verify proofs.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/a98b7fe6-9d08-49e4-b764-5470e14ea3aa.png", + "banner_url": "https://storage.googleapis.com/op-atlas/997e2275-906b-4535-b414-59f4bd648196.png", + "twitter": null, + "repos": [ + "https://github.com/merkletreejs/merkletreejs" + ], + "tags": [ + "merkle-trees" + ], + "website": "https://github.com/merkletreejs/merkletreejs", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x17fb589e599fe05e532b90c121eccc55b1249301e783dae226bad698872322da", + "name": "The Ethernaut", + "description": "The Ethernaut is a community-driven capture-the-flag wargame that challenges developers of all levels to break smart contracts while learning common Solidity vulnerabilities. Maintained by OpenZeppelin, each level provides a gamified experience where a smart contract must be ‘hacked’ to progress. It is 100% open-source, with all levels contributed by players.\n\nIn 2024, we have continued expanding the game, adding four new advanced levels—HigherOrder, Stake, Impersonator, and Magic Animal Carousel—which explore current vulnerabilities in smart contract development. These levels introduce challenges related to low-level EVM programming, staking vulnerabilities, signature verification exploits, and bitwise manipulation attacks, pushing players to deepen their understanding of Ethereum security.\n\nBeyond new levels, we have also redesigned the UI, added support for multiple networks, and expanded language translations to make the game more accessible to a global audience.\n\nWe believe that The Ethernaut is an essential training tool for developers across the Ethereum ecosystem, including those building on the Optimism network. By continually evolving the game with new challenges and features, we strive to make smart contract security education engaging, practical, and accessible to everyone.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/06419654-6022-400a-9670-82ca6e0225fe.png", + "banner_url": "https://storage.googleapis.com/op-atlas/5aba83e1-a4f2-453c-9e64-9884d0e628d6.png", + "twitter": "https://x.com/openzeppelin", + "repos": [ + "https://github.com/OpenZeppelin/ethernaut" + ], + "tags": [ + "education", + "security", + "solidity", + "community-driven", + "react-app" + ], + "website": "https://ethernaut.openzeppelin.com/", + "category": "Education & Community Resources" + }, + { + "id": "0xcc9301a401320c626839db9c4415f28a6e1f2fb3abdf38ada785b57409bdedb6", + "name": "DexKit", + "description": "DexAppBuilder provides a comprehensive kit of no-code/low-code tools and solutions, enabling anyone to easily create customized DApps for Web3.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/07bee0c5-72ce-4e1b-b474-bd9d84856718.png", + "banner_url": "https://storage.googleapis.com/op-atlas/7881f699-90d7-4178-965c-8805145a348a.png", + "twitter": "dexkit", + "repos": [ + "https://github.com/DexKit/open-nft-marketplace", + "https://github.com/DexKit/dexkit-monorepo" + ], + "tags": [ + "frontend", + "react", + "nextjs" + ], + "website": "http://dexkit.com", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x852f6213011d0ad31206df4993d22721102dbe615bb93492d6e8be8d89676243", + "name": "foundry-devops", + "description": "A tool to get the most recent deployment from a given environment in foundry. This way, you can do scripting off previous deployments in solidity.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/578db712-b499-4084-a729-99d90ee55c7f.png", + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/Cyfrin/foundry-devops" + ], + "tags": [ + "foundry", + "cli", + "devops", + "solidity", + "contract-deployment" + ], + "website": "https://github.com/Cyfrin/foundry-devops", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x7e917a2d0718401c9fe2a82f43ea558f5128f251b1e658c76dc7ff9a5e9fd993", + "name": "PRBMath", + "description": "PRBMath is a smart contract library that adds support for fixed-point types and advanced math functions like logarithms and exponentials in Solidity. Operating with 18-decimal numbers, PRBMath is at the same time gas efficient and user-friendly.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/527c8bbb-c361-4521-afbf-4396cecd1e3b.png", + "banner_url": "https://storage.googleapis.com/op-atlas/dc6b5afb-2335-484a-91f5-6673bf62237a.png", + "twitter": "https://x.com/PaulRberg", + "repos": [ + "https://github.com/PaulRBerg/prb-math" + ], + "tags": [ + "solidity", + "gas-efficient", + "developer-experience", + "foundry" + ], + "website": "https://github.com/PaulRBerg/prb-math", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x14eab8b10f729239d63df6c0cb85f666c3eb1f2dd440ebd003c1821f186a49da", + "name": "Ethernal", + "description": "Ethernal is an open source block explorer for evm chains.\nSpinning up a fully customised explorer only takes a couple of seconds, either through the UI or the API.\nIt includes a faucet UI, a dex UI, and can be customised to cater to network specificities, like custom 3rd party libraries, or custom contract & transaction post processing.\nIt also includes advanced token & network analytics, contract verification, nft galleries, etc..", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/9ced93ba-a5ac-4d04-a054-2963c41e8dc6.png", + "banner_url": "https://storage.googleapis.com/op-atlas/c141df7d-78ea-48c9-81b1-325fa5a33bc4.png", + "twitter": "https://x.com/tryethernal", + "repos": [ + "https://github.com/tryethernal/ethernal", + "https://github.com/tryethernal/hardhat-ethernal", + "https://github.com/tryethernal/ethernal-cli" + ], + "tags": [ + "analytics", + "block-explorer", + "chains", + "contract-verification", + "cli" + ], + "category": "Data, Analytics & Tracing" + }, + { + "id": "0x8c0365628d69981ac162a89f2b391cc4adfd224e9a424f8e985e70e2421de6d1", + "name": "SuperUI", + "description": "Fire up a personal Superchain environment to run tests, fork networks, and inspect state with complete control over how your rollup operates. The Ultimate Ethereum & Superchain Development Playground", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/2a0e6716-cdf5-4a27-9912-5e520ccd68e1.png", + "banner_url": "https://storage.googleapis.com/op-atlas/fca44e15-1ce7-422d-b22f-2f1df4f4923c.png", + "twitter": null, + "repos": [ + "https://github.com/Nerd3Lab/superUI" + ], + "tags": [ + "frontend", + "contract-management" + ], + "website": "Superui.app", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x72d363f14ae85f47acfe748fb0a2bed73195582bb9863de18901f5dfe309b8f7", + "name": "Solodit", + "description": "What is it?\nSolodit is an open-source, community-driven platform dedicated to improving web3 security. It aggregates over 8,000 smart contract vulnerability reports, bug bounty opportunities, and security audits from top firms like Cyfrin, OpenZeppelin and Trail of Bits, alongside contributions from individual researchers. Solodit not only aggregates this information but also makes it actionable, equipping developers and auditors with tools to prevent exploits and enhance the safety of dapps.\n\nWhy is it needed?\nThe web3 ecosystem is plagued by billions of dollars in losses due to security breaches in smart contracts and protocols. Despite the availability of security knowledge, it is fragmented across various platforms and reports, making it inaccessible to most developers and security teams. There are several problems that Solodit solves:\n\nKnowledge Gap: Many teams deploy smart contracts without understanding past vulnerabilities, leading to repeat incidents.\nInefficiencies: Developers and auditors spend valuable time searching disparate sources for security insights.\nEconomic Impact: Preventable exploits undermine trust in web3, stalling adoption and investment.\n\nBy aggregating and structuring security data, Solodit enables proactive vulnerability management and risk mitigation in the Web3 ecosystem.\n\nHow is it unique?\nComprehensive Coverage: Aggregates findings from leading auditors and platforms, offering unmatched insights into vulnerabilities and bug bounties.\nActionable Insights: Goes beyond archiving reports by providing advanced search tools and tagging systems to contextualise risks and solutions.\nCommunity-Driven Enhancements: Facilitates collaboration via ratings, tagging, and leaderboards that recognise top contributors, fostering a thriving security community.\nEducational Resource: This site serves as a learning hub for developers and auditors, providing real-world case studies on blockchain security.\n\nSolodit is a multipurpose tool designed to:\nMitigate Risk: Helps developers avoid known vulnerabilities, reducing the likelihood of exploits.\nPromote Proactive Security: Enables protocols to adopt preventive measures by studying historical vulnerabilities.\nStreamline Bug Bounties: Simplifies participation in bounty programs, encouraging more ethical hackers to contribute to ecosystem security.\nFoster Skill Development: Supports auditors in honing their skills and staying updated on emerging threats.\nSupport Decision-Making: Assists protocols in evaluating auditors via its leaderboard, promoting accountability and quality audits.\n\nWho is it for?\nDevelopers: Seeking to secure their smart contracts and understand vulnerability trends.\nAuditors: Looking to access a comprehensive repository of findings and showcase their expertise.\nWhitehat Hackers: Interested in participating in bug bounty programs and contributing to web3 security.\nProtocol P&E teams: Aiming to assess risks and prevent costly exploits.\nEducators and Researchers: Teaching or studying blockchain security with real-world examples, e.g. Cyfrin Updraft. \n\nStill to come:\nUI/UX redesign\nPower Aderyn, static analysis support", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/9cf8d92d-5549-4321-b675-c25256860183.png", + "banner_url": "https://storage.googleapis.com/op-atlas/20eb90df-0dd5-41fb-a3ce-f90cf3822492.png", + "twitter": null, + "repos": [ + "https://github.com/solodit/solodit_content" + ], + "tags": [ + "security", + "education", + "analytics", + "community-driven" + ], + "website": "https://solodit.cyfrin.io/", + "category": "Education & Community Resources" + }, + { + "id": "0xbaccff0188ef78c1bab0c9798b0faceee552de1dee4f763d1801a9c1d5e3bca5", + "name": "Verifereum", + "description": "Verifereum is an open-source project bringing mathematical rigor to Ethereum smart contract verification using the HOL4 theorem prover. The project is building tools to prove the correctness of smart contracts and eliminate entire classes of vulnerabilities. With billions of dollars secured by smart contracts, Verifereum aims to provide the strongest formal verification security guarantees possible for the Ethereum ecosystem.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/392d496a-b4b8-464c-bf6e-fcee8146a75f.png", + "banner_url": "https://storage.googleapis.com/op-atlas/3fd3093d-6a52-44bb-a73b-cf9d6f8cae03.png", + "twitter": "https://x.com/Verifereum/", + "repos": [ + "https://github.com/verifereum/verifereum" + ], + "tags": [ + "security", + "education", + "formal-verification" + ], + "website": "https://www.verifereum.org/", + "category": "Security, Testing & Formal Verification" + }, + { + "id": "0x495b81a381005f49592ee02a7ac6861b8da69762b7164180d0a1e4570f2d83bf", + "name": "DEO AI: Ethereum Developer Assistant", + "description": "DEO is an AI-powered assistant is designed to help Ethereum developers efficiently query and retrieve relevant documentation, references, and best practices from official sources, forums, and technical guides. By leveraging NLP and retrieval-augmented generation (RAG), the agent will allow developers to ask natural language questions and receive precise, contextual answers from Ethereum's technical ecosystem.\n\nThe agent will integrate with major Ethereum knowledge bases such as the Ethereum Developer Portal, Solidity documentation, EIPs (Ethereum Improvement Proposals), and Web3 libraries, streamlining research and troubleshooting for developers. It will also provide code snippets, explanations, and best practices in response to queries.\n\nI am psychemist, a seasoned full-stack developer focused on building Web3 products to advance a decentralized internet and native digital money. With a strong background in Ethereum’s ecosystem, I contribute to open-source projects and develop practical tools, devtools, and blockchain applications. My expertise spans smart contract development, decentralized protocols, and AI-driven tooling. For this grant, I am leveraging my experience to build Deo, an AI-powered assistant that enhances developer efficiency by providing intelligent, context-aware access to Ethereum documentation. Through Retrieval-Augmented Generation (RAG) and scalable AI models, Deo aims to streamline research, debugging, and smart contract development, making Ethereum’s complex knowledge base more accessible.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/900648a3-44d3-4d53-8e5e-1ccbb57bf9e2.png", + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/psychemist/deo-ai" + ], + "tags": [ + "education", + "natural-language-processing", + "cli", + "vscode-extension", + "community-driven" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x991062ec81edb818a542e45d7c142cc62bc06e68b582273bd2ae1b037c2d6791", + "name": "Titan Layer", + "description": "Introduction-\n\nThe exponential growth of blockchain networks has led to a fragmented ecosystem, with limited interoperability between chains. Users and developers face significant challenges when transferring assets or deploying contracts across multiple chains. Titan Layer addresses these issues by offering an easy-to-use, secure, and scalable platform that fosters cross-chain connectivity. With a focus on user experience and interoperability, Titan Layer aims to drive blockchain adoption and foster activity across networks.\n\nChallenges in Cross-Chain Interoperability\n\nFragmented Ecosystem: Users must navigate multiple wallets and bridges, leading to complexity and errors.\n\nSecurity Risks: Many existing bridges are vulnerable to hacks and exploits.\n\nScalability Issues: High gas fees and slow transaction times hinder seamless cross-chain transactions.\n\nLimited User Experience: Current solutions are often technical and unfriendly to non-technical users.\n\n\nTitan Layer's Solution-\n\nTitan Layer solves these challenges by:\n\nSimplified Bridging: A one-stop solution for transferring assets across chains with minimal steps.\n\nContract Deployer: An intuitive tool that allows users to easily deploy and interact with contracts across multiple chains.\n\nHyperlane Integration: We leverage Hyperlane for secure, decentralized ERC20 token bridging.\n\nUser-Centric Design: A streamlined user interface designed to cater to both beginners and advanced users.\n\n\nKey Features-\n\nMulti-Chain Support: Titan Layer supports major networks such as Arbitrum, Optimism, Polygon, Base, BSC, and Mantle.\n\nCustomizable Connectivity: Users can choose which chains to connect for a tailored experience.\n\nSecurity First: Robust security measures, including audits and encryption, to protect users' assets.\n\nEasy Deployment: One-click smart contract deployment across multiple chains, reducing technical barriers.\n\nReal-Time Monitoring: Dashboard for tracking transactions, bridging status, and contract interactions.\n\n\nUse Cases-\n\nDevelopers: Effortlessly deploy and interact with contracts across multiple chains.\n\nTraders: Seamlessly transfer assets across chains to capitalize on arbitrage or market opportunities.\n\nProjects: Launch multi-chain dApps with ease, expanding their reach and user base.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/35374f7e-a430-4726-b5f0-ef52e2b5115a.png", + "banner_url": "https://storage.googleapis.com/op-atlas/ba692e10-9ffd-4406-b6e7-5010ad20b2d2.png", + "twitter": "https://x.com/TitanLayer", + "repos": [ + "https://github.com/TitanLayer/contracts" + ], + "tags": [ + "cross-chain", + "security" + ], + "website": "https://titanlayer.xyz/", + "category": "Cross-Chain & Interoperability" + }, + { + "id": "0x154a42e5ca88d7c2732fda74d6eb611057fc88dbe6f0ff3aae7b89c2cd1666ab", + "name": "🏗️ Scaffold-ETH 2", + "description": "Scaffold-ETH 2 is an open-source toolkit for building decentralized applications on the Ethereum blockchain. It's designed to make it easier for developers to create and deploy smart contracts and build user interfaces that interact with those contracts.\n\nIt's a new version of scaffold-eth with its core functionality.\n\n- ⚙️ Built using NextJS, RainbowKit, Hardhat, Foundry, Wagmi, Viem, and Typescript.\n- ✅ Contract Hot Reload: Your frontend auto-adapts to your smart contract as you edit it.\n- 🪝 Custom hooks: Collection of React hooks wrapper around wagmi to simplify interactions with smart contracts with typescript autocompletion.\n- 🧱 Components: Collection of common web3 components to quickly build your frontend.\n- 🔥 Burner Wallet & Local Faucet: Quickly test your application with a burner wallet and local faucet.\n- 🔐 Integration with Wallet Providers: Connect to different wallet providers and interact with the Ethereum network.\n- 🔌 Extensions: Modular add-ons that provide additional functionality or serve as starter-kits for specific features.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/f8efb7c2-8fb3-4988-8511-ae6e826b687f.png", + "banner_url": "https://storage.googleapis.com/op-atlas/8b032214-48dc-4f13-b8fa-21324d9c9030.png", + "twitter": "https://x.com/ScaffoldETH", + "repos": [ + "https://github.com/scaffold-eth/create-eth-extensions", + "https://github.com/scaffold-eth/burner-connector", + "https://github.com/scaffold-eth/se-2-docs", + "https://github.com/scaffold-eth/create-eth", + "https://github.com/scaffold-eth/scaffoldeth.io", + "https://github.com/scaffold-eth/scaffold-eth-2" + ], + "tags": [ + "frontend", + "nextjs", + "hardhat", + "foundry", + "cli" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x63f8e1e35986862f0bb24a619b72d12459497d2b6b94d93a9f2c232d376c54dc", + "name": "RainbowKit Theme Generator", + "description": "Easily create custom RainbowKit theme from a single color that you can copy and paste into your web3 apps.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/532d50f9-524d-4934-b77a-8c85d0145bcf.png", + "banner_url": "https://storage.googleapis.com/op-atlas/a1272743-7b81-4aef-a8fd-f2fe70122b01.png", + "twitter": null, + "repos": [ + "https://github.com/zwergdev/rainbowkit-theme-generator" + ], + "tags": [ + "frontend" + ], + "website": "https://rainbowkit-theme.com/", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0xc0615947773148cbc340b175fb9afc98dbb4e0acd31d018b1ee41a5538785abf", + "name": "Wagmi: Reactive primitives for Ethereum apps ", + "description": "Wagmi is the industry standard for building apps on Ethereum. Wagmi has deep integrations with modern web frameworks, like React.js and Vue.js, and makes it easy to connect wallets, sign messages, send transactions, and read/write on-chain data. With over 1.2M monthly downloads, Wagmi is used in production by most of the industry and is at the core of apps, like Uniswap, Optimism, Polymarket, Stripe, Zora, and Farcaster.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/4043de65-2657-4c0f-91e6-3d5aea14dc33.png", + "banner_url": "https://storage.googleapis.com/op-atlas/faafa9b3-2151-4cd7-a9f3-e9c1853e8874.png", + "twitter": "https://x.com/wevm_dev", + "repos": [ + "https://github.com/wevm/wagmi" + ], + "tags": [ + "react", + "wallet", + "transaction-signing", + "community-driven" + ], + "website": "https://wagmi.sh", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0xfa7d950cfda2c634b052b6c07e75daaa95dd22ac1f220b6862cfd24221d4cabc", + "name": "Solhint", + "description": "SOLHINT is the most used Solidity linter in web3 space. A tool that helps solidity devs to write standardized smart contracts code, taking care of code quality, order, readability, style guides, preventing known bugs, and giving security alerts. It is an extremely popular open source tool within Ethereum community. Our grant application aims to fund a small dedicated team of technical and marketing professionals to increase community engagement into proposing new rules, report bugs, discuss possible updates, etc.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/8a93267a-39e3-42c9-976f-225753bb43f3.png", + "banner_url": "https://storage.googleapis.com/op-atlas/cc6944d5-ceb0-416d-9e3c-befb89ef7578.png", + "twitter": "https://x.com/protofire", + "repos": [ + "https://github.com/protofire/solhint" + ], + "tags": [ + "security", + "education", + "code-quality", + "community-driven", + "cli" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x202a80f0f57630d04a26464d6492b3399059ca1187943032c37652eb2468a76f", + "name": "Titanoboa", + "description": "Titanoboa is a Vyper interpreter and testing framework that provides a modern, integrated development experience for Vyper smart contracts. It enables developers to test and debug Vyper contracts directly within Python, offering features like pretty tracebacks, forking, debugging capabilities, pytest integration and out-of-the box fuzzing. Beyond its standalone capabilities, Titanoboa serves as the foundation for other popular testing frameworks like Ape and Moccasin, and is a core piece of infrastructure for the Vyper ecosystem.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/2e9723d3-7b53-473c-b93c-87b2c7a72055.png", + "banner_url": "https://storage.googleapis.com/op-atlas/801bbd29-77ab-4050-b175-f853aa9704ed.png", + "twitter": null, + "repos": [ + "https://github.com/vyperlang/titanoboa" + ], + "tags": [ + "vyper", + "debugging-tools" + ], + "website": "https://titanoboa.readthedocs.io/en/latest/", + "category": "Security, Testing & Formal Verification" + }, + { + "id": "0xaed5941b7a9f20de83f5c839bda507be43cbf41777fc623abf4bf05773298826", + "name": "Otterscan", + "description": "A blazingly fast, local, Ethereum block explorer built on top of Erigon for EVM chains", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/55a1fffb-dcd9-448b-8e34-9fb4b09a72f7.png", + "banner_url": "https://storage.googleapis.com/op-atlas/a0e75c22-8aff-4176-af81-6c03208c1bd3.png", + "twitter": "https://x.com/otterscan", + "repos": [ + "https://github.com/otterscan/otterscan" + ], + "tags": [ + "docker", + "block-explorer", + "chains", + "privacy-focused", + "react-app", + "json-rpc", + "visualization" + ], + "website": "https://otterscan.io/", + "category": "Data, Analytics & Tracing" + }, + { + "id": "0x67f6d1feb3b5e99caf0f2e7e4677494c57449de3980079589156e105df485488", + "name": "Moccasin", + "description": "What is it?\nMoccasin is an open source, public-good developer tool. It's a python-based Vyper smart contract development, deployment, and testing framework.\n\nWhy is it needed?\nThe Web3 Python ecosystem has been overshadowed by the Rust and Javascript ecosystems, which is a crucial misstep when all financial and AI developers use Python. Walk into any asset manager or hedge fund and ask the portfolio managers or traders what they are using, and the answer is Python. We need a fast and modern tool for Python exploration. \n\nVyper adds to smart contract language diversity, which is as important as having client diversity from the blockchain infrastructure. If one has a critical bug, we minimize the downside by having different languages.\n\nHow is it unique?\nMoccasin is the fastest Python framework and, for Vyper smart contracts, even outpaces Foundry in some instances. It achieves this speed by being built on the lightning-fast Titanoboa tool.\n\nYou can see a quick benchmark of compile time for Vyper contracts across popular frameworks like Apeworx and Foundry.\nhttps://github.com/Cyfrin/Moccasin/blob/main/docs/source/_static/stats-default.png?raw=true\n\nWhat can it do?\nEncrypt keys\nRun tests\nUnderstand deployment contexts\nAnd ideally work with the growing number of non-EVM compatible chains (ie, ZKsync, Scroll, etc)\nRun fuzzing campaigns\n\nMoccasin is a new tool, but due to its speed and developer friendliness, we expect to see its adoption skyrocket in the Python community.\nWhat really sets Moccasin apart, other than being the fastest and most developer-friendly Python tooling for Viper, is that developers can now script and perform DevOps in the user-friendly language Python.\n\nWhat is our roadmap?\nYou can see a list of 0.4.0 roadmap items (and other priority items) for Moccasin including:\nbetter multi-sig & hardware wallet integration\nin-line debugger\nSolidity support\nMedusa fuzzing\nbuillt-in halmos or HEVM support\n\nWho is it for?\nPython developers. According to the Stack Overflow 2024 survey, python is the #1 programming language for new developers.\nSo, Moccasin is for new developers.\nAccording to Upwork, Python is the #1 language for people working in AI.\nSo, Moccasin is for AI developers.\nAccording to Columbia Engineering, python is the #1 language for fintech.\nSo, Moccasin is for financial developers, including DeFi.\nThis tool is meant for both new and advanced developers - a tool that is easy to pick up and powerful enough for professional applications. (edited) \n\nWith this tool, we want to start bridging the gap between web2 and web3 developers and encourage builders to move into our industry. Allowing developers to use multiple languages and to grow the adoption of the Sueprchain. \n", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/89c06746-f49f-4a30-9843-80b431053f13.png", + "banner_url": "https://storage.googleapis.com/op-atlas/5ec5b8ee-5389-4201-8191-4a84e37f1291.png", + "twitter": null, + "repos": [ + "https://github.com/Cyfrin/moccasin" + ], + "tags": [ + "education", + "vyper", + "devops", + "cli", + "encryption" + ], + "website": "https://github.com/Cyfrin/moccasin", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x513265758a3804184b6a0771d99c1a4b04d3267bacd4b914e89ff991de229f6a", + "name": "Create2Deployer", + "description": "Create2Deployer is a factory smart contract designed to make easier and safer usage of the `CREATE2` EVM opcode. Create2Deployer is a preinstall on the OP Stack: https://specs.optimism.io/protocol/preinstalls.html#create2deployer.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/ca4f6cbd-5b97-4c22-9e27-446b9e4cd2ff.png", + "banner_url": "https://storage.googleapis.com/op-atlas/120ab790-4407-4342-b7af-e562cf3a9c8c.png", + "twitter": null, + "repos": [ + "https://github.com/pcaversaccio/create2deployer" + ], + "tags": [ + "solidity", + "contract-deployment" + ], + "website": "https://github.com/pcaversaccio/create2deployer", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x537097f27d55cb52d39b95c3ed65076349ab68aac48051d742d715456e0884d8", + "name": "xdeployer", + "description": "Hardhat plugin to deploy your smart contracts across multiple EVM chains with the same deterministic address. A total of 133 EVM chains are currently supported, including (almost) all OP-stack-powered chains.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/ce1dd7d2-ed08-45f9-adf0-1934ae5dc396.png", + "banner_url": "https://storage.googleapis.com/op-atlas/4942518f-9987-4d03-9504-a7494fce0021.png", + "twitter": null, + "repos": [ + "https://github.com/pcaversaccio/xdeployer" + ], + "tags": [ + "hardhat", + "cross-chain", + "multi-chain", + "contract-deployment", + "cli" + ], + "website": "https://github.com/pcaversaccio/xdeployer", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x4dd10ba330a4a21459e2ba72f15fb5da2a63f7492e2b1567e6669c3d47fe6308", + "name": "Web3j", + "description": "Web3j is the Java and Android integration library for Ethereum.\n\nCreated in 2016, and still going strong in 2025 it is core plumbing to Ethereum for one of the world's most widely used development platforms, the JVM.\n\nIt has been downloaded millions of times, and is used by everyone including\n- Enterprises such as J.P. Morgan, Fnality and NTT Data\n- Web3 infrastructure companies such as Alchemy \n- The Besu Ethereum Execution client\n- It's even been integrated natively into the Android OS by Freedom Factory in ethOS which powers the upcoming Ethereum phone the DGEN1\n\nWe decided in 2024 to bring Web3j into the Hyperledger Foundation, which provides high-quality governance of open source (similar to the Apache Foundation). It's still, the same team at Web3 Labs responsible for maintaining and supporting the library for its wide and varied user base. The Hyperledger association is great for visibility, but doesn't provide any funding for the project!\n\nWe rely on grant funding to sustain this library and hopeful to qualify for this RPGF round.\n\nUnfortunately, we missed out on OP RPGF 3 as we had not realised projects were eligible for multiple rounds so did not apply following our success in OP RPGF 2.\n\n🙏🏻", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/be0b64a3-1fcb-4f95-ad91-6a2589a5315f.png", + "banner_url": "https://storage.googleapis.com/op-atlas/e1ea2162-1ef8-46ea-afdc-37f0bb4dee4a.png", + "twitter": "https://x.com/web3labs", + "repos": [ + "https://github.com/hyperledger-web3j/web3j", + "https://github.com/hyperledger-web3j/web3j-maven-plugin", + "https://github.com/hyperledger-web3j/web3j-unit", + "https://github.com/hyperledger-web3j/web3j-openapi-gradle-plugin", + "https://github.com/hyperledger-web3j/web3j-openapi", + "https://github.com/hyperledger-web3j/web3j-solidity-gradle-plugin", + "https://github.com/hyperledger-web3j/web3j-docs", + "https://github.com/hyperledger-web3j/web3j-installer", + "https://github.com/hyperledger-web3j/web3j-cli", + "https://github.com/hyperledger-web3j/web3j-gradle-plugin", + "https://github.com/hyperledger-web3j/web3j-sokt" + ], + "tags": [ + "governance", + "cli" + ], + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x819775803938d78eaa95809971ce94cae6a54b4df58505fa36153ffa1d55e12c", + "name": "Vscode Solidity Extension", + "description": "Solidity support for Visual Studio code\nVersion Downloads Installs Rating\n\nSolidity is the language used in Ethereum to create smart contracts, this extension provides:\n\nSyntax highlighting\nSnippets\nCompilation of the current contract (Press F1 Solidity : Compile Current Solidity Contract), or F5\nCompilation of all the contracts (Press F1 Solidity : Compile all Solidity Contracts), or Ctrl + F5 or Cmd + F5\nCode completion for all contracts / libraries in the current file and all referenced imports\nGoto definition\nFind all references in project\nHover information\nCode actions / quick fixes (change compiler, format address, add sdpx license.. )\nMono repo support (identifies the project by finding the files: remappings.txt, foundry.toml, brownie-config.yaml, truffle-config.js, hardhat.config.js, hardhat.config.ts)\nDefault project structure (solidity files needs to be in the src/ directory, and libraries in the lib/ directory). Libraries will follow the same structure.\nCompilation supporting EIP82 (dappfile and dependency packages)\nSupport for different solidity versions (Remote and local)\nDownload source code and Abi from Etherscan\nCode generation using Nethereum, it includes currently the default template for Nethereum service, dtos generation. (Open 'contractName.json' after compilation from the bin folder. Press F1 and press Solidity: Code generate from compilation output..) Auto generation of Nethereum files on compilation\nLinting using Solhint or Ethlint\nIt is also available as a standalone LSP", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/006b0fd3-9e23-4192-98d6-08e561da809e.png", + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/juanfranblanco/vscode-solidity" + ], + "tags": [ + "education", + "solidity" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xa3d07f453f70d844196d89d79848aa2e70a0bd8b38bf0f493cba1547bb3bca5e", + "name": "Ethers.js", + "description": "Ethers.js is a simple, compact and complete JavaScript (via TypeScript) library for interacting with Ethereum and related blockchains.\n\nIt is currently used in a very large number of Blockchain projects, including everything from block explorers to wallets (like MetaMask) and is downloaded over 7.1 million times per month (as of this writing). It is also one of the top 500 projects (by dependants) on NPM.\n\nIt was written and is maintained by me, RicMoo (Richard Moore), a random developer from Canada that is passionate about open-source and dedicates most his waking-time (and some sleeping-time) to it.\n\nHack the Planet! :)", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/f8d776ab-ca70-42ee-9e41-d4f709cd6fd4.png", + "banner_url": "https://storage.googleapis.com/op-atlas/459bdd5e-60a5-49ca-88b8-d4537ebfec16.png", + "twitter": "@ricmoo", + "repos": [ + "https://github.com/ethers-io/ethers.js" + ], + "tags": [ + "frontend", + "json-rpc", + "contract-interaction" + ], + "website": "https://ethers.org", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x2bb095e1f297c71da8bd4ee15097abad3b99e299fe14cd6aa704df3f36d0ae22", + "name": "solidity-coverage", + "description": "solidity-coverage provides smart-contract code coverage for the Hardhat developer platform. It's highly accurate, supports full viaIR solidity compilation and a large set of solidity-specific code branch patterns. It's installed on ~230k Github projects and is downloaded ~100k times a week from NPM.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/bd692393-7f1a-4b91-9887-73f7c3250233.png", + "banner_url": "https://storage.googleapis.com/op-atlas/dcbdf6ac-f898-4dac-b9d0-087b8d289f4b.png", + "twitter": null, + "repos": [ + "https://github.com/sc-forks/solidity-coverage" + ], + "tags": [ + "hardhat", + "analytics", + "code-coverage", + "solidity", + "test-automation" + ], + "website": "https://github.com/sc-forks/solidity-coverage", + "category": "Security, Testing & Formal Verification" + }, + { + "id": "0x4f8902ac6eba8e2243237247302ab778a1e1f496cf62e1696fbb8d57eff7701d", + "name": "blocksmith.js", + "description": "blocksmith.js is a minimal Javascript testing framework for Ethereum contract development using foundry-rs and ethers. It is a lightweight wrapper around forge and anvil, so you can script Foundry however you want. It is primarily designed for developing cross-chain applications that cannot be tested inside of a single EVM instance.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/8b8c4fda-3240-41c6-ab52-43a137e665a8.png", + "banner_url": "https://storage.googleapis.com/op-atlas/0b8f272e-b319-4744-959e-dbc36996ba31.png", + "twitter": "https://x.com/adraffy", + "repos": [ + "https://github.com/adraffy/blocksmith.js" + ], + "tags": [ + "cli", + "foundry", + "cross-chain", + "contract-deployment" + ], + "website": "https://github.com/adraffy/blocksmith.js", + "category": "Security, Testing & Formal Verification" + }, + { + "id": "0x939241afa4c4b9e1dda6b8250baa8f04fa8b0debce738cfd324c0b18f9926d25", + "name": "OpenZeppelin Contracts", + "description": "OpenZeppelin Contracts are the go-to library for smart contract development.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/83bab036-91bd-4b9d-a524-dbea2024aa3f.png", + "banner_url": "https://storage.googleapis.com/op-atlas/489f54b5-2035-4a94-82f5-8b41e6cbb857.png", + "twitter": "https://x.com/openzeppelin", + "repos": [ + "https://github.com/OpenZeppelin/openzeppelin-upgrades", + "https://github.com/OpenZeppelin/openzeppelin-subgraphs", + "https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades", + "https://github.com/OpenZeppelin/merkle-tree", + "https://github.com/openzeppelin/openzeppelin-community-contracts", + "https://github.com/OpenZeppelin/openzeppelin-contracts", + "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable", + "https://github.com/OpenZeppelin/contracts-wizard" + ], + "tags": [ + "cross-chain", + "governance", + "erc721", + "upgradeable-contracts", + "modular-accounts", + "interactive-tools", + "merkle-trees" + ], + "website": "https://www.openzeppelin.com/", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x663e4d25ca3f327365240471b4831ea3c989cb132bbf6ae8f5c1e15268591795", + "name": "Blockscout open-source block explorer", + "description": "Blockscout block explorer is the #1 explorer used by Optimistic rollups and Superchain networks. Blockscout is highly customizable and available, providing advanced developer tooling for projects and blockchain transparency for users.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/3113c4b6-4e29-420c-95f8-2ae4f6098089.png", + "banner_url": "https://storage.googleapis.com/op-atlas/c08d15e7-41fd-41a7-9c04-b1e10b0c1f26.png", + "twitter": "https://x.com/blockscoutcom", + "repos": [ + "https://github.com/blockscout/blockscout" + ], + "tags": [ + "block-explorer", + "chains" + ], + "website": "http://www.blockscout.com", + "category": "Data, Analytics & Tracing" + }, + { + "id": "0x8589657542ff4b7c5071dfdeff18a041642a72344ede9acea701e9b39fb46fee", + "name": "Chimera", + "description": "Chimera is a framework to write Solidity tests in foundry and be able to reuse them with other Open Source Tools such as Echidna, Medusa, Halmos and Kontrol", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/c26c5e5d-f2aa-4150-a46c-2e9c33de343f.png", + "banner_url": "https://storage.googleapis.com/op-atlas/3e4364f9-e445-4c2d-be52-af8cf934eab6.png", + "twitter": "https://x.com/getreconxyz", + "repos": [ + "https://github.com/Recon-Fuzz/setup-helpers", + "https://github.com/Recon-Fuzz/log-parser", + "https://github.com/Recon-Fuzz/create-chimera-app", + "https://github.com/Recon-Fuzz/chimera", + "https://github.com/Recon-Fuzz/recon-extension" + ], + "tags": [ + "foundry", + "solidity", + "code-coverage", + "test-automation", + "vscode-extension" + ], + "category": "Security, Testing & Formal Verification" + }, + { + "id": "0xbb067b01988521110c91737f058e7301f608be231d850a72af1516bd034d161c", + "name": "Synpress", + "description": "Synpress is an end-to-end testing framework for web applications based on Cypress.io and Playwright, with support for MetaMask. It is a pioneering tool in web3 end-to-end testing with the potential to evolve into a decentralized network of test runners and continuous integration providers in the future. Synpress is easy to use, fully tested, and includes features such as MetaMask support, headless mode, integrated video recording, and many more. It is also blazingly-fast and extensible, with the ability to add custom commands and plugins. Synpress is already used by many open-source repositories.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/abf0fa5e-15f2-4963-bd73-d84d0bd4c307.png", + "banner_url": "https://storage.googleapis.com/op-atlas/0d9aecc0-dcf4-4ee0-9e6c-12d9b62325ea.png", + "twitter": "https://x.com/Synpress_", + "repos": [ + "https://github.com/synpress-io/docs", + "https://github.com/Synthetixio/synpress" + ], + "tags": [ + "frontend", + "continuous-integration", + "performance-optimization", + "debugging-tools" + ], + "website": "https://synpress.io/", + "category": "Security, Testing & Formal Verification" + }, + { + "id": "0xb773733e55b7267302f2622ae410a65a89552689387d0b86bce0f0cb833119d0", + "name": "Callthis", + "description": "Callthis is a better transaction builder:\n- Generate an interface for any contract, even if it's unverified. (Powered by WhatsABI)\n- Build a transaction and save it as a link that can be shared and executed later.\n- Works with any EVM chain, with WalletConnect or Safe Wallets or browser-injected providers.\n- Address fields automatically resolved with ENS.\n- Supports complex contract inputs with tuples, arrays, etc.\n- No backend services required, grab the source and run it locally for privacy and censorship-resistance!\n- Permissively licensed under MIT, use it in your products.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/abe6dc50-0732-419b-a64c-463814247f78.png", + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/shazow/callthis" + ], + "tags": [ + "frontend", + "wallet", + "cross-chain", + "privacy-focused", + "censorship-resistant" + ], + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x4ede10cd8332093fb0c1083828cc2e333d60f1551cef2d29bccb82bae1f5d7f7", + "name": "Candide's Smart Account Contracts", + "description": "Candide offers open-source smart contracts designed for teams that are pushing the boundaries of Ethereum UX with Account Abstraction. Our contracts includes a formally verified and audited Social Recovery module, a Paymaster contract for gas sponsorship, and a BLS Account contract. These solutions are trusted by high-profile projects like Safe, Worldcoin, and many others.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/104d6957-65bc-4d15-a5f9-2afd75482347.png", + "banner_url": "https://storage.googleapis.com/op-atlas/c120c166-68a8-4e9b-a159-b1f9e74ff105.png", + "twitter": "https://twitter.com/candidelabs", + "repos": [ + "https://github.com/candidelabs/candide-contracts" + ], + "tags": [ + "wallet", + "governance", + "education", + "account-abstraction", + "user-experience" + ], + "website": "https://www.candide.dev/", + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "0x28aec169f525d30fed96625a31fdd75ca906805d0ee4e7b1502945a9e1d29525", + "name": "AbstractionKit | Account Abstraction Library", + "description": "AbstractionKit is TypeScript Interface designed for Ethereum Account Abstraction. It simplifies the standard's complexities and provides a robust foundation for developing smart wallet applications. AbstractionKit is used in conjunction with libraries like Ethers, viem, and wagmi. It remains service-agnostic, offering compatibility with any Node, Bundler, or Paymaster provider. Key features include Passkeys Login, Gas Sponsorship and Social Recovery. AbstractionKit is used by smart wallets that are breaking new ground in Ethereum UX, such as Morpher, Unit-e, BackPack, JOIN, and many others.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/69b08a09-8fd5-498a-beef-67ad29cf01b5.png", + "banner_url": "https://storage.googleapis.com/op-atlas/75a0886a-d3a0-4595-a539-64a8a83eae3a.png", + "twitter": "https://twitter.com/candidelabs", + "repos": [ + "https://github.com/candidelabs/abstractionkit" + ], + "tags": [ + "wallet", + "education", + "account-abstraction" + ], + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "0xc7798704a6d730cea776c4866a9636bfa04c1201e29b6b0c99cc3603bc1bca25", + "name": "Cannon", + "description": "Cannon is a DevOps tool for protocols on Ethereum. It manages smart contract deployment and configuration for local development and live networks.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/8b14d1e8-d2ef-4670-83da-76368cbd50af.png", + "banner_url": "https://storage.googleapis.com/op-atlas/7ce75cc0-17f9-457a-b456-0232b9647d96.png", + "twitter": "https://x.com/usecannon", + "repos": [ + "https://github.com/usecannon/cannon" + ], + "tags": [ + "cli", + "chains" + ], + "website": "https://usecannon.com", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x40483b3554ae17882db98d1cfd3aae6b10ba8250736279d184fd947931ed02c3", + "name": "Superfuse", + "description": "Superfuse, is a toolchain and knowledge hub to build cross-chain contracts in Superchain Ecosystem. It includes:\n\n1) Superfuse wizard: It is a code generator/ interactive developer playground to develop a part of smart contract/deploy script/ test suites out of components from cross-chain specification. Select kind of contract that you want (eg. ERC7802, SuperchainERC20, and ERC20Votes).\n\n\n2) suerfuse-forge: a developer-friendly framework/library in solidity to build a variations of cross-chain contracts in superchain Ecosystem", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/6038b69f-0ca7-478f-a55f-002f00e3b7e7.png", + "banner_url": "https://storage.googleapis.com/op-atlas/d96837af-ba2e-44d1-9e6d-ad9b30a06c3e.png", + "twitter": "https://twitter.com/RATi_MOn", + "repos": [ + "https://github.com/Ratimon/superfuse-wizard", + "https://github.com/Ratimon/superfuse-forge" + ], + "tags": [ + "cross-chain", + "frontend", + "solidity", + "interactive-tools", + "foundry" + ], + "website": "https://superfuse.ninja/", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x166e2bfeae612e99675a055e2d3e3d02e49bdab377109bc528c32b7afe6cc920", + "name": "solid-grinder", + "description": "A 100% opensource CLI that goes along with building blocks of smart contract. This toolbox can reduce L2 gas cost by encoding calldata for dApps development to use as little bytes of calldata as possible.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/2161762e-cdb8-41be-978b-3581df50d5a4.png", + "banner_url": "https://storage.googleapis.com/op-atlas/ca2f1444-6a4f-41f2-91d4-f8059f652ccc.png", + "twitter": "https://twitter.com/RATi_MOn", + "repos": [ + "https://github.com/Ratimon/solid-grinder" + ], + "tags": [ + "cli", + "layer-2", + "solidity", + "developer-experience", + "transaction-optimization" + ], + "website": "https://github.com/Ratimon/solid-grinder", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x37fe5886f4c77d5a5cb947deff90158c045a5d207572763187748ac4dd4bd9b9", + "name": "ethereum-multicall", + "description": "Ability to call many ethereum constant function calls in 1 JSONRPC request", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/joshstevens19/ethereum-multicall" + ], + "tags": [ + "multicall" + ], + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "0x4c9626843c4e3f3c96d80b0ec6b1d10b7682fc9b6d67ab61ece5a87648535b1f", + "name": "ethereum-bloom-filters", + "description": "A lightweight bloom filter client which allows you to test ethereum blooms for fast checks of set membership.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/d21bd2f0-91b0-4e80-9e33-b1c21501a4e8.png", + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/joshstevens19/ethereum-bloom-filters" + ], + "tags": [ + "performance-optimization", + "event-logging" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x97525ec91080ddd917eaccabf9d383cf70a2f78839ab21eeabe1687e312f2132", + "name": "rindexer", + "description": "rindexer is an opensource powerful, high-speed indexing toolset developed in Rust, designed for compatibility with any EVM chain. This tool allows you to index chain events using a simple YAML file, requiring no additional coding. For more advanced needs, the rindexer provides foundations and advanced capabilities to build whatever you want. It's highly extendable, enabling you to construct indexing pipelines with ease and focus exclusively on the logic. rindexer out the box also gives you a GraphQL API to query the data you have indexed instantly.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/366c4940-78cc-4119-958b-b93f3c9a5845.png", + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/joshstevens19/rindexer" + ], + "tags": [ + "indexing", + "cli" + ], + "website": "https://rindexer.xyz/", + "category": "Data, Analytics & Tracing" + }, + { + "id": "0xc88dff5a8bb7326e7d9103bf84e77425e202a8275abffbbbc08954c309acf511", + "name": "Voltaire | Account Abstraction Bundler", + "description": "Voltaire Bundler is a core infrastructure component for Ethereum Account Abstraction designed to extend Ethereum nodes. It facilitates the inclusion of smart account transactions — known as UserOperations —via an alternative peer-to-peer mempool, without requiring any protocol changes. Voltaire is relied in production by Smart Wallets pushing new grounds for Ethereum UX like JOIN, BackPack, El-Dorado, Unit-e, Morpher and and many others. Voltaire is built and maintained by Candide, a small independent team that has been redefining Ethereum user experiences since 2022.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/4686b986-8bb5-4ab0-a13b-c020291b20c2.png", + "banner_url": "https://storage.googleapis.com/op-atlas/2ac896b0-1b09-40bf-a5db-7baef34ead58.png", + "twitter": "https://twitter.com/candidelabs", + "repos": [ + "https://github.com/candidelabs/voltaire" + ], + "tags": [ + "wallet", + "governance", + "account-abstraction", + "bundler", + "docker", + "user-experience" + ], + "website": "https://www.candide.dev/bundler", + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "0x4e175118c15129e6cc791203de92b23f11fef35ba4bc3fd18390f163e692c97d", + "name": "EvmTools", + "description": "Evmtools (previously zkblock) started as a boilerplate for developing zk dapps using circom (groth and plonk). But since the inception, it has grown to include variety tools required to develop zk and web3 dapps. These tools help during development of variety of dapps inlcuding zk-snarks based dapps, whitelisting contracts, contracts using EIP-712 signatures such Aave credit delegation, custom signatures, raw transaction decoder, determining contract addresses, understand on-chain slot structure etc.\n\nThe goal of evmtools is to help users to debug, build and ship web3 apps. Since, the inception we have included several features to make evmtools useful for development.\n\nWe have built whole suite of (20+) tools for developers. These tools help developers to test and debug during development. Some of the tools include-\n\nUniswap V4 Hooks tools\nMerkle Tree Generator (using secure openzeppelin libraries, provides easy debugging for whitelisting)\nEVM Transaction Decoder\nBit Manipulation, masking etc\nGeneral Utility tools\nGas converter, byte conversion, hex conversion etc.\nEpoch Converter\nGenerate burner addresses\nChecksum Formatter\n\nAll tools are available in an extension as well. ", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/c82ddf3d-3586-4552-85ce-8e9f5da907d5.png", + "banner_url": null, + "twitter": "https://x.com/evmtools_xyz", + "repos": [ + "https://github.com/Elefria-Labs/zk-block", + "https://github.com/Elefria-Labs/evm-tools" + ], + "tags": [ + "cli", + "analytics", + "debugging-tools", + "transaction-decoding", + "merkle-trees" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x754c37e401e2527ab24b9d7ca3e042bfcbfebeef54a533f8833d46242d2c3017", + "name": "Remix Project", + "description": "A rich and accessible Web3 toolset for learning, building, and testing on multiple chains", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/09d19a87-dc4f-4586-99f6-ef6c9f92f713.png", + "banner_url": "https://storage.googleapis.com/op-atlas/5286dfe0-6f4d-4782-8c59-b7ffe6579bfc.png", + "twitter": "https://x.com/EthereumRemix", + "repos": [ + "https://github.com/remix-project-org/remix-reward", + "https://github.com/ethereum/remix-project", + "https://github.com/remix-project-org/remix-challenges", + "https://github.com/remix-project-org/remix-rewards-ui" + ], + "tags": [ + "education", + "frontend", + "cross-chain", + "solidity", + "community-driven" + ], + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x5f9f1b45eb4a49e8c2482288e02c8fc1e0e60ad3e88f0ea87bbdb4932da1054d", + "name": "Diamondscaffold: Simplifying EIP-2535 Diamond Architecture Development", + "description": "Diamondscaffold is a CLI tool designed to streamline the development of EIP-2535 diamond structures. Supporting both Hardhat and Foundry, it provides ready-to-use templates for ERC20, ERC721, and a default Diamond structure, allowing developers to efficiently scaffold modular smart contracts. With JavaScript/TypeScript compatibility, automated dependency installation, and an intuitive setup process, Diamondscaffold accelerates project deployment while ensuring flexibility and scalability. By making diamond contract architecture more accessible, this tool fosters innovation within the Ethereum and Optimism ecosystems, empowering developers to build robust, upgradeable, and efficient smart contracts.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/d818a88f-eb12-4c4e-b1be-46f8284fd5d4.png", + "banner_url": "https://storage.googleapis.com/op-atlas/8d4a3113-5b39-472e-9a60-57451db585fb.png", + "twitter": "https://x.com/BAbraham_92/", + "repos": [ + "https://github.com/collinsadi/diamonds" + ], + "tags": [ + "cli", + "hardhat", + "foundry", + "erc721", + "upgradeable-contracts" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x5dfcf84cc8ef7eb731a8175633c8da5cd3784fe57b05409f0df745b88443c034", + "name": "Simbolik - Solidity Debugger", + "description": "We are Runtime Verification, a team specializing in formal methods and blockchain security. Simbolik is the tool we developed in-house, a powerful Solidity debugger that combines traditional breakpoint debugging with symbolic execution, enabling developers to explore every possible execution path and uncover vulnerabilities with precision.\n\nAvailable as a VSCode extension, Simbolik integrates seamlessly into existing workflows, offering breakpoint-style debugging, Solidity and EVM-level inspection, and formal verification capabilities. Adopted by organizations like Lido, Optimism, Ethereum Foundation, and others, Simbolik helps Superchain builders write more secure and reliable smart contracts.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/d2f26755-6a96-4cf7-917e-6ebeced29a15.png", + "banner_url": "https://storage.googleapis.com/op-atlas/8d0da35d-0369-4bf8-a577-60ce33236078.png", + "twitter": "https://x.com/rv_inc", + "repos": [ + "https://github.com/runtimeverification/simbolik-examples", + "https://github.com/runtimeverification/simbolik-vscode" + ], + "tags": [ + "security", + "education", + "symbolic-execution", + "vscode-extension", + "runtime-verification", + "formal-verification" + ], + "website": "simbolik.runtimeverification.com", + "category": "Security, Testing & Formal Verification" + }, + { + "id": "0xabdfa10e699db5127100da1dd2403692afe8d86e793d57780f1c7e93437a73a0", + "name": "WhatsABI", + "description": "Extract ABI (and more) from Ethereum contract bytecode, even without source code.\n\nWhatsABI is a public good for making EVM bytecode more useful and usable on all EVM-based chains, such as mainnet and OP Stack chains.\n\nThe guiding purpose for WhatsABI is to improve decentralization, transparency, and user safety by reducing our dependence on proprietary centralized frontends for EVM contracts. \n\nWhatsABI a permissively-licensed TypeScript library that is perfect for building better contract explorers, transaction builders, smarter wallets, and for doing security research. It is designed to be small, fast, and easily embedded in wallets or runnable locally with any provider. Some things WhatsABI can do: Return selectors from bytecode, look up function signatures from selectors, provide helpers for looking up ABI and signatures from public databases (like Sourcify, Etherscan, Blockscout, OpenChain, 4Byte), resolve onchain proxies (including inspecting available diamond facets!), loading contract metadata, and more. \n\nWhatsABI is already powering many popular projects like: Otterscan, Sourcify, Rivet, Ondora, Thirdweb, and more coming soon as we collaborate on integrations upstream.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/63e11af2-345b-4977-b6da-dcaf387df081.png", + "banner_url": "https://storage.googleapis.com/op-atlas/6e45f230-2ef2-43f1-ab9d-b95e2ac0f15e.png", + "twitter": "https://x.com/shazow", + "repos": [ + "https://github.com/shazow/whatsabi" + ], + "tags": [], + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x2247247c751707d897f5c0eab670426d9c1c26d84e96ac226004afbf0080cba4", + "name": "Rundler", + "description": "Rundler (Rust Bundler) is an ERC-4337 bundler implementation written in Rust. Rundler is designed to achieve high-performance and high-reliability in cloud deployments via a modular architecture. Currently, both Alchemy and Coinbase’s Base team use Rundler. It powers >70% of UOs in the Ethereum ecosystem and a vast majority of UOs in the Superchain. Rundler is OSS licensed with GPL.\n\nRundler powers the ERC-4337 ecosystem with an implementation that users can rely on to scale reliably. Rundler open source code repo has 300+ stars, more than 50 forks. \n\nOur goals with Rundler:\n\nERC-4337 Specification Compliance: Rundler strives to implement the full ERC-4337 specification and to maintain support as the specification changes and new onchain components are released. This includes new Entry Point contract support, support for the upcoming P2P mempool specification, support for alternative mempools, and more.\nBest-in-class Performance and Reliability: Rundler strives to power the most demanding workloads in cloud environments. Rust was chosen for its high performance and memory safety. Rundler's modular architecture lets providers choose to run the stateless components (RPC, builder) in a fully horizontally scalable manner connecting to the stateful components (mempool, p2p, event cache) via the network. Rundler's bundle builder is designed to be able to support the full gas throughput of the network it's building for.\nExtensibility/Chain Support: ERC-4337 is designed to support any EVM chain. However, different EVM supporting networks have different rules around how to support things like gas usage, gas fees, precompiles, etc. Rundler is designed to be extensible and easily adapted to support any EVM chain.\nModularity: Rundler is written in a modular manner, allowing its components to be run as a single integrated binary, or as a distributed system. Rundler also strives for its individual crates to be used to support future ERC-4337 tooling.\n\nIn RPGF Round 3, Alchemy was awarded a total of 74,534 $OP across Rundler, Light Account, ERC-6900, aa-sdk, and various informational pieces put out to the public domain to further adoption of smart accounts in the Superchain.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/7e5161c3-ab8c-44e9-97b9-a957fa9cb7a2.png", + "banner_url": "https://storage.googleapis.com/op-atlas/2985ee59-7f46-4626-93f4-fd91de426cd2.png", + "twitter": "twitter.com/alchemy", + "repos": [ + "https://github.com/alchemyplatform/rundler" + ], + "tags": [ + "docker", + "cross-chain", + "bundler", + "support", + "account-abstraction", + "scalability" + ], + "website": "www.alchemy.com", + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "0x740bebbc731ec56dcc17c7d429656220a73960022c3809edf324bd8120285722", + "name": "bulloak", + "description": "A smart contract test generator based on the Branching Tree Technique. ", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/73d7f842-6eb3-4a74-89df-176b8a69e4c2.png", + "banner_url": "https://storage.googleapis.com/op-atlas/b5a6613d-fb1f-439c-ba1e-e0fcd42c99b5.png", + "twitter": null, + "repos": [ + "https://github.com/alexfertel/bulloak" + ], + "tags": [ + "cli", + "solidity", + "code-quality", + "code-analysis", + "test-automation", + "solidity-development", + "code-coverage" + ], + "website": "https://www.bulloak.dev/", + "category": "Security, Testing & Formal Verification" + }, + { + "id": "0xe6eb4d61eff4e2dc2d8dba01ac1b84c1683bdb1e8d677a66fa44a72e3f8b1faf", + "name": "Zabi", + "description": "Zabi is a project for interacting with ethereum and the superchain written in Zig", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/e1983235-58da-4c36-86eb-63e593554d7e.png", + "banner_url": "https://storage.googleapis.com/op-atlas/467a5d29-ee97-4610-8923-18346cbc3a4e.png", + "twitter": "https://x.com/0xRaiden_", + "repos": [ + "https://github.com/Raiden1411/zabi" + ], + "tags": [ + "cross-chain", + "json-rpc", + "contract-interaction", + "cli", + "abi-encoding" + ], + "website": "zabi.sh", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x7e5614eb46520c523562a641649be228012355d0264c9130b2c1d9872bf5bad5", + "name": "ABIExplorer", + "description": "ABI Explorer is like Postman for smart contracts; it allows developers and integrators to test and interact with smart contract functions directly using their ABIs. No need to write custom scripts or spin up a front end, just drop in your ABI, connect your wallet, and start calling functions.\n\nIt’s designed to make life easier for anyone working with smart contracts and also to:\n\nQuickly test read/write functions\n\nSimulate interactions before integrating into your dApp\n\nDebug contract behaviors on any chain, including Optimism\n\n\nWe built this to help streamline contract integration and testing workflows, especially for devs building with on-chain components.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/afd98fa3-7bf7-45a5-9d07-0f1dbea2ba61.png", + "banner_url": "https://storage.googleapis.com/op-atlas/aa144789-e6d6-4af4-9634-7956915bfc8a.png", + "twitter": null, + "repos": [ + "https://github.com/CollinsMunene/abiexplorer" + ], + "tags": [ + "contract-interaction" + ], + "website": "https://abiexplorer.devligence.com/", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x1e2cc195ce13784ef1e382bbd542a6b25d982b83377a8e8ac2ca593d6c310adc", + "name": "Privacy Builder Pack", + "description": "Hacker Manuals & Privacy Guidelines to help the builders deliver practical privacy-enhancing projects, turn them into products, & scale being sustainable.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/b2e8b33c-2f72-4854-b549-ea8ea9468eca.png", + "banner_url": "https://storage.googleapis.com/op-atlas/b473d908-de6b-45f1-9b19-a3027ef207fc.png", + "twitter": "https://x.com/web3privacy", + "repos": [ + "https://github.com/web3privacy/privacy-builder-pack" + ], + "tags": [ + "education", + "encryption" + ], + "website": "https://build.web3privacy.info", + "category": "Education & Community Resources" + }, + { + "id": "0xa38c8f4ffa48fe01222fe1b5f2bc6c95e204a4f243d67bd0c9f92887d905d3d8", + "name": "Academy", + "description": "Training, incubation, and acceleration programs for non-tech people and devs to start in the web3 privacy ecosystem.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/153bea66-bef0-481d-bb29-2882eb0e6edb.png", + "banner_url": "https://storage.googleapis.com/op-atlas/1809a100-d320-47f2-8144-94343ef5ea40.png", + "twitter": "https://x.com/web3privacy", + "repos": [ + "https://github.com/web3privacy/cypherpunkacademy" + ], + "tags": [ + "education" + ], + "website": "https://academy.web3privacy.info/", + "category": "Education & Community Resources" + }, + { + "id": "0xec7002ee89bf249ae4fca1ebe718a66dea7247e33cfc9319f979a3f9fb324b24", + "name": "Explorer", + "description": "Explorer is a flagship project by Web3Privacy Now that curates and maintains an extensive open-source database of privacy-enhancing tools, use cases, and research. Designed as a public good, it empowers individuals, developers, and organizations to navigate the privacy landscape with greater knowledge and autonomy. Explorer bridges the gap between users and privacy solutions by providing accessible, actionable, and up-to-date resources to foster a culture of privacy within the Web3 ecosystem.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/4b165837-402c-4f39-bc4f-fa5a0b931b8c.png", + "banner_url": "https://storage.googleapis.com/op-atlas/161c3a2f-880d-4617-afda-746e97e7586c.png", + "twitter": "https://x.com/web3privacy", + "repos": [ + "https://github.com/web3privacy/explorer-app", + "https://github.com/web3privacy/explorer-data" + ], + "tags": [ + "education", + "analytics", + "community-driven" + ], + "website": "https://explorer.web3privacy.info/", + "category": "Data, Analytics & Tracing" + }, + { + "id": "0xbcfa7063514406f498f2792ae6435bf488709709391cebfa260a552703b4a8f9", + "name": "GDWeb3", + "description": "GDWeb3 is a GDScript library for interacting with blockchain networks(The first support is Optimism). It will provide Web3 game developers with a powerful game development engine. For game developers in the Godot ecosystem, it will offer an SDK for developing blockchain games.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/fae7d370-79b6-48b2-9d69-785cd2edb573.png", + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/qingfengzxr/gdscript-web3" + ], + "tags": [ + "game-development" + ], + "website": "https://github.com/qingfengzxr/gdscript-web3", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x4a5e771af86cf1938056b43cddbf0018dca1376d578f631f7449fe10ac4958ed", + "name": "Nethereum", + "description": "Nethereum is the .Net integration library for Ethereum, simplifying the access and smart contract interaction with Ethereum nodes both public like Geth (or your preferred client) L2 chains like Optimism, Arbitrum (or your preferred L2), any compatible EVM chain (Gnosis, etc) and permissioned chains like Quorum.", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/Nethereum/Nethereum" + ], + "tags": [ + "cross-chain", + "wallet", + "json-rpc", + "transaction-signing", + "abi-encoding" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x351967474a454b494260a488f3ceb77d993580a4fe79fb6b6d132c70634bc516", + "name": "Ponder", + "description": "Ponder is an open-source indexing framework for crypto apps focused on performance, reliability and developer experience. Dozens of apps across the Superchain use Ponder to power their websites and mobile applications. Our goal is to enable world-class user experiences that don't compromise on censorship-resistance and decentralization.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/8da31052-61ab-40c2-a9b6-18b0dd37824e.png", + "banner_url": "https://storage.googleapis.com/op-atlas/e46839dc-55fb-45c5-8c47-d3282749cedb.png", + "twitter": "https://x.com/ponder_sh", + "repos": [ + "https://github.com/ponder-sh/ponder" + ], + "tags": [ + "indexing", + "support", + "developer-experience", + "censorship-resistant", + "performance-optimization", + "event-logging", + "type-safe", + "cli" + ], + "website": "https://ponder.sh", + "category": "Data, Analytics & Tracing" + }, + { + "id": "0x812ea3d88c189f53197820e1c648dd32c5b937467d93602a3ba5d0b764124f90", + "name": "solizard", + "description": "Super easy interactive shell for interacting with smart contracts", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/401a6212-fc2a-4b46-8a96-52f597c82467.png", + "banner_url": "https://storage.googleapis.com/op-atlas/18896241-e29b-4497-9d12-e27ea0045830.png", + "twitter": "https://x.com/zsystmd", + "repos": [ + "https://github.com/zsystm/solizard" + ], + "tags": [ + "cli", + "contract-interaction" + ], + "website": "https://github.com/zsystm/solizard", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xbe74d6076f833da93276495074d0356db90c495d3257f8958853e75e9df8e9c8", + "name": "Web3GPT", + "description": "Web3GPT is an AI-powered platform I've developed with the help of some contributors. Web3GPT transforms smart contract development by enabling developers of all skill levels to write, deploy, and verify smart contracts across multiple EVM networks using natural language prompts—no complex configurations or IDEs required. With over 250 AI-generated smart contracts already deployed and verified across different EVM networks, it's proving its capability in the Web3 ecosystem. The platform also supports specialized AI Agents designed for specific functionalities, enhancing your development experience by making it more efficient and tailored to your needs.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/b540988e-6db1-47de-84a4-bebe987ef595.png", + "banner_url": "https://storage.googleapis.com/op-atlas/283678d8-970a-44ee-ba90-419f5359aac5.png", + "twitter": "https://x.com/w3gptai", + "repos": [ + "https://github.com/markeljan/web3gpt" + ], + "tags": [ + "education", + "cli", + "contract-verification", + "natural-language-processing", + "solidity" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xebe03c3d6d33cad60124b9b05ef6e2ff056293a1de3c5fa51dfbb90c86c14bf7", + "name": "web3.py", + "description": "web3.py is the open source library that connects Python developers to Ethereum. The same team maintains more than a dozen additional building blocks including py-evm, eth-account, and eth-utils.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/287d64ad-b265-41e5-9569-25807ef5bba4.png", + "banner_url": "https://storage.googleapis.com/op-atlas/c4ed28a3-a435-4725-8de3-ef463b073417.png", + "twitter": "https://x.com/EthereumPython", + "repos": [ + "https://github.com/ethereum/web3.py", + "https://github.com/ethereum/py-evm", + "https://github.com/ethereum/eth-utils", + "https://github.com/ethereum/eth-abi", + "https://github.com/ethereum/eth-account" + ], + "tags": [ + "transaction-signing", + "community-driven", + "testing" + ], + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0xa903038c6a307743fdca92164f38d5c392996c2417d66d5bf33012850d0585bf", + "name": "JiffyScan", + "description": "4337 Block Explorer", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/088c8fd2-0f5c-48b2-b3b7-94c72c70cba9.png", + "banner_url": "https://storage.googleapis.com/op-atlas/1818ec80-87d0-4da1-a485-3ef2a43fadfb.png", + "twitter": "https://x.com/jiffyscan", + "repos": [ + "https://github.com/jiffy-labs/jiffyscan-frontend" + ], + "tags": [], + "website": "https://www.jiffyscan.xyz/", + "category": "Data, Analytics & Tracing" + }, + { + "id": "0xaa4cf223915387f8e0cd66640f86f4f770d0c1edfc4303ce1d596a735747e673", + "name": "Farcaster Attestation", + "description": "Farcaster Attestation is bringing Farcaster wallet verification on-chain to the Optimism Mainnet. Traditionally, Farcaster wallet verification data is only accessible through the Farcaster Hub, which cannot be utilized directly on Optimism Mainnet via Solidity smart contracts. This creates a centralization issue in the Retro Funding EAS schema, limiting the authorized attester to a single wallet, as it requires verification from a centralized backend.\n\nFarcaster Attestation resolves this centralization problem by enabling anyone to attest their Farcaster data permissionlessly.\n\nWe have replicated the Retro Funding Project and Metadata Schema to test the integration with Farcaster Attestation. For more information, refer to the Links section.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/55264cac-23b0-47e1-8cfb-e6691e876eaa.png", + "banner_url": "https://storage.googleapis.com/op-atlas/c502f9bc-fcfe-4696-bf81-f90ed8d9786c.png", + "twitter": null, + "repos": [ + "https://github.com/Farcaster-Attestation/op-attest", + "https://github.com/Farcaster-Attestation/farcaster-resolver", + "https://github.com/Farcaster-Attestation/farcaster-solidity" + ], + "tags": [ + "governance", + "solidity", + "farcaster" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xa38f3efb4fb8f6fcefb80f0262645ac05d5548cad0308ee49520c48c4e8cbd1f", + "name": "growthepie 🥧📏 Ethereum and Superchain Analytics", + "description": "growthepie.xyz is a public goods data platform for Ethereum and its scaling solutions, providing essential metrics, onchain data, and educational resources to empower developers and users in making informed decisions.\n\nIt aims to enhance transparency and understanding within the Ethereum ecosystem. It is entirely free to use, with no subscription fees or access limitations, funded primarily through grants and user donations. Key features include fundamental metrics and blockspace exploration, offering insights into chains' and their projects’ activity, value locked, economics, and Data Availability metrics. Our most recent addition are application-specific analytics. We have most of the Superchain covered, constantly adding more along the way. \n\ngrowthepie has been built from zero all in-house with a team of 8 people, with early funding from the Ethereum Foundation, Optimism grants and RPGF as well as Gitcoin and Octant rounds.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/33fec99f-964b-4296-a409-77c4fc4674e8.png", + "banner_url": "https://storage.googleapis.com/op-atlas/1ac64d7c-4267-4be3-80d6-c90bebb7e40c.png", + "twitter": "https://x.com/growthepie_eth", + "repos": [ + "https://github.com/growthepie/gtp-frontend", + "https://github.com/growthepie/gtp-dna", + "https://github.com/growthepie/gtp" + ], + "tags": [ + "analytics", + "education", + "visualization", + "nextjs", + "tailwind-css", + "community-driven" + ], + "website": "https://www.growthepie.xyz/", + "category": "Data, Analytics & Tracing" + }, + { + "id": "0xab6214e09c6adc3022147ba7fffe1924f9bad3ecbe69e410f428808e91fd6f06", + "name": "Zink Language", + "description": "Rustic programming language that targets EVM", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/9b6b9753-121c-4c3f-9a39-c2c48b5cf149.png", + "banner_url": "https://storage.googleapis.com/op-atlas/0d1302f3-d1e0-4fe1-a10e-592b36cb139b.png", + "twitter": "zinkonx", + "repos": [ + "https://github.com/zink-lang/zink" + ], + "tags": [ + "education" + ], + "website": "https://github.com/zink-lang/zink", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x46d784ec075b98efe6a23e515cad06f1b7081f082cb0c7502c68a7a76c38c9e2", + "name": "DistriButler: Multi Token Sender for Optimism, Base & Arbitrum", + "description": "DistriButler is a powerful multi-token sender Dapp built to streamline airdrops, rewards, and bulk transfers across Optimism, Base, and Arbitrum networks. With a focus on simplicity, security, and efficiency, it allows users to effortlessly send multiple tokens to numerous addresses in a single transaction. DistriButler reduces the complexity of managing large distributions while saving on gas fees, making it an ideal tool for Web3 projects needing efficient token transfers.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/10cc25d9-eb1f-43f2-8126-7927acb952c2.png", + "banner_url": "https://storage.googleapis.com/op-atlas/d6450ca3-f77e-40cf-8799-c61244ab93e3.png", + "twitter": "https://x.com/DistriButler", + "repos": [ + "https://github.com/sifaw23/distributler" + ], + "tags": [ + "defi", + "wallet", + "nextjs" + ], + "website": "https://distributler.com/", + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "0xd63cb23c26cc3bda03b1cc2971589fd26c9d22f3bbc8f1ff2bb74613e6d1c36d", + "name": "Solidity Bytes Arrays Utils Library", + "description": "Bytes tightly packed arrays' utility library for ethereum contracts written in Solidity.\n\nThe library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\n\n-----\n\nThe Solidity Bytes Arrays Utils library is a Solidity library I initially wrote 7+ years ago, when Solidity was in its initial days, to be able to handle dynamic bytes arrays through canonical functions like concatenation and slicing.\n\nI have maintained the functional part of its code single-handedly over the years with help around documentation and ideation from a few other contributors.\n\nThis library has been used extensively over the years by some of the biggest projects in the space. Names like Aragon, Maker, Uniswap, Nomad, LayerZero, and, probably more importantly, Optimism, in its initial version.\n\n(Not all projects forked the repo. You can find a big list of forks here: https://github.com/GNSPS/solidity-bytes-utils/forks, the rest can be found by either searching \"BytesLib.sol\" on Google or just searching for parts of the code itself on GitHub.)", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/aa1c84f1-cd10-420c-a730-576e9e1ca7fd.png", + "banner_url": "https://storage.googleapis.com/op-atlas/e5f2c4cb-fb66-4473-973c-1d98a51065a0.png", + "twitter": "https://x.com/gnsps", + "repos": [ + "https://github.com/GNSPS/solidity-bytes-utils" + ], + "tags": [ + "solidity", + "truffle" + ], + "website": "https://github.com/GNSPS/solidity-bytes-utils", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xc6052138bbdae5976fa2866f46b0537182d4126c4bb97485738d1b43f2276134", + "name": "thirdweb", + "description": "thirdweb is a full stack, open-source web3 development platform with frontend, backend, and onchain tools to build complete web3 apps — on every EVM chain.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/278ce531-3de6-4f4c-8955-877541c7020b.png", + "banner_url": "https://storage.googleapis.com/op-atlas/c78355fc-3512-4554-a6df-70392a31cae2.png", + "twitter": "@thirdweb", + "repos": [ + "thirdweb-dev", + "https://github.com/thirdweb-dev/insight", + "https://github.com/thirdweb-dev/js", + "https://github.com/thirdweb-dev/contracts" + ], + "tags": [ + "frontend", + "cross-chain", + "api", + "chains", + "real-time-data" + ], + "website": "https://www.linkedin.com/company/third-web/", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0xfb3ac4e5f7665c6560e461c1b77ed896d355635947a6e58e217f345af8624dcd", + "name": "Ackee", + "description": "Ackee is trusted by top-tier organizations in web3. Our mission is to contribute to a stronger blockchain ecosystem by providing security services, tooling and education.", + "thumbnail_url": "https://cdn.charmverse.io/user-content/2d6a8f50-45c2-4658-a66a-74eca1149aa3/102ec612-ed55-4da8-b9fb-0bb3f5447e84/Ackee-Blockchain-Security-logo.jpg", + "banner_url": "https://cdn.charmverse.io/user-content/2d6a8f50-45c2-4658-a66a-74eca1149aa3/f1984493-d1a1-424e-afc1-36e1fc33f573/Ackee-Blockchain-Twitter-Banner.jpeg", + "twitter": "ackeeblockchain", + "repos": [ + "https://github.com/Ackee-Blockchain/solidity-for-vscode" + ], + "tags": [ + "education", + "security", + "solidity", + "static-analysis", + "contract-deployment", + "proxy-contracts" + ], + "category": "Security, Testing & Formal Verification" + }, + { + "id": "0x6d30328dd0e058bdd4c55c51d5f785268770040a66edbd2830902c4d87efee9c", + "name": "Clear Wallet", + "description": "Clear EVM wallet is a fully open-source EVM browser wallet based on Ethers, Ionic, Manifest V3, and Vue. It implements Metamask API and will work as a replacement for Metamask, websites will detect it as Metamask, so select Metamask when interacting with Dapps. Websites that implement EIP-6963 will detect it as Clear EVM Wallet.\n\nIt has been public on Chrome Store since August 2022.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/4aa97110-63e2-4703-a3f5-e42bdebceaee.png", + "banner_url": "https://storage.googleapis.com/op-atlas/50e95639-885c-4657-8141-4a3357fd732e.png", + "twitter": "andrei0x309", + "repos": [ + "https://github.com/andrei0x309/clear-wallet" + ], + "tags": [ + "wallet", + "frontend", + "privacy-focused" + ], + "website": "https://clear-wallet.flashsoft.eu/", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x5e6c436e48e56d6d9622ba5d0be0035c314e2b29d2afc8f5f1ee8ac75cd42532", + "name": "Snapshot", + "description": "Snapshot started as a voting platform designed to allow onchain organizations to vote easily without gas fees. Its strength lies in its flexibility and high customization, catering to the diverse needs of its users. This includes options for calculating users' voting power, selecting different voting mechanisms, and managing proposal and vote validation rules.\n\nAs the gas cost dropped with the maturity of L2s and the need for more decentralized and trustless voting grew, we developed Snapshot X, an onchain voting protocol. Unlike the original Snapshot, Snapshot X operates fully onchain using a set of modular smart contracts. This shift makes Snapshot censorship resistant, with onchain and cross-chain voting power computation and trustless execution, while keeping gas costs to the minimal extent possible.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/098487bf-4f43-4e5a-8621-9c6368304124.png", + "banner_url": "https://storage.googleapis.com/op-atlas/d76ced7e-7d5e-4514-9706-ca097e3131c2.png", + "twitter": "https://x.com/SnapshotLabs", + "repos": [ + "https://github.com/snapshot-labs/snapshot", + "https://github.com/snapshot-labs/sx-monorepo", + "https://github.com/snapshot-labs/sx-evm" + ], + "tags": [ + "governance", + "cross-chain", + "decentralized-governance" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x541b7b08401d799b87f583c102a6c94cee7105f1b29dc630de5edbbd966d7c13", + "name": "Fe Language", + "description": "Fe is a high-level language for the EVM. It is heavily inspired by Rust and implemented in it too. You can use Fe to write smart contracts for Ethereum or any EVM-equivalent platform. Currently, we are developing Fe v2, which introduces an improved type system. While it does not yet compile to EVM, users can still analyze their code using the CLI or an editor plugin.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/05ac5706-2a13-4325-8333-183a730e7797.png", + "banner_url": "https://storage.googleapis.com/op-atlas/f733c3ee-3819-40f8-9ee8-b94416a770d9.png", + "twitter": null, + "repos": [ + "https://github.com/ethereum/fe" + ], + "tags": [ + "cli", + "education", + "compiler", + "code-analysis", + "type-safe" + ], + "website": "fe-lang.org", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x10e9fc6dd7d01e09bd9440d507846432333a06f779287b29199010e2f50579cd", + "name": "Token Historical Balance", + "description": "The OP Token Historical Balance is a critical tool developed by WakeUp Labs that improves the usability and functionality of the Optimism blockchain. This service empowers developers, analysts, and users by enabling them to query historical blockchain data at any specific moment in time. It supports queries for any public view function of smart contracts deployed on Optimism, from the very first block to the present. By providing access to historical state data, this project directly supports transparency, research, and analytics, which are crucial for the evolution and understanding of the Optimism ecosystem.\n\nOur project contributes to the OP Stack Tooling category by providing a fundamental utility that facilitates better decision-making, auditing, and research within the Optimism network. This tool is vital for developers who require accurate historical data to test, validate, and optimize their applications. Additionally, it promotes the growth of the Optimism ecosystem by reducing barriers to entry and fostering a more robust environment for innovation.\n\nWakeUp Labs is dedicated to advancing the capabilities of Ethereum's Layer 2 solutions, and we believe that tools like the OP Token Historical Balance are essential for driving adoption and enhancing the overall developer experience. By making Optimism's blockchain data more accessible and usable, we aim to empower the community and fuel the next wave of development on the OP Stack.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/ae73d3f5-61cc-48ef-84e9-2b553d1f0739.png", + "banner_url": "https://storage.googleapis.com/op-atlas/46c64ba6-5c38-4bc0-9ac7-d32a55a32637.png", + "twitter": "x.com/wakeuplabs", + "repos": [ + "https://github.com/wakeuplabs/rfg1-optimism" + ], + "tags": [ + "analytics", + "layer-2", + "visualization" + ], + "category": "Data, Analytics & Tracing" + }, + { + "id": "0x51cda5996ef1a2ccd8fcf4ee5792337695599454c83eb1218c3ad4388dcb5bf5", + "name": "Sourcify", + "description": "Sourcify is a decentralized and open-source smart contract verification service", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/f219ada1-9d7d-4d1c-8a90-ea1b09eda31f.png", + "banner_url": "https://storage.googleapis.com/op-atlas/3d5c829b-3fc4-4dcd-995d-978aceca64dc.png", + "twitter": "https://twitter.com/sourcifyeth", + "repos": [ + "https://github.com/ethereum/sourcify" + ], + "tags": [ + "solidity", + "vyper", + "api", + "cli", + "type-safe" + ], + "website": "https://sourcify.dev", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xd4ed99cc6aaf73ca63b32f7a03b5427ac1d2955bf9efc31eb14f5773016988d0", + "name": "AWS KMS and YubiHSM signer for OP Stack", + "description": "We have developed a signer proxy software that enables the OP Stack chain to use an external signer (currently supporting AWS KMS and YubiHSM) through the official signer client to signer the sequencer, batcher, proposer and challenger transactions. However, the official signer client does not integrate with external signers, so we have implemented this functionality in our signer proxy.\n\nCurrently, the process outlined in the Optimism documentation for setting up a sequencer, batcher, and proposer requires using plain private keys, creating an insecure environment for mainnet deployment. Although the documentation suggests using hardware security modules (HSMs) for key management, it lacks detailed guidance beyond referencing source code. Chain operators, particularly those using bare metal setups, often prefer YubiHSM2 over cloud-based solutions like AWS KMS due to its hardware-native security.\n\nTo enhance security, mainnet chain operators are encouraged to use industry-standard hardware signers like YubiHSM2 or AWS KMS. This approach allows operators to deploy Optimism stack chains securely by protecting private keys with hardware-based solutions. Existing resources, such as the integration of YubiHSM2 into the Keplr wallet and the TMKMS YubiHSM installer, provide relevant experiences that support this approach.\n\nOur AWS KMS Signer proxy has been used by the Lisk team for their op-challenger. We are working with them to make signer proxy perfect and production ready.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/a73d46f5-87ba-4204-88eb-7ce51ab055de.png", + "banner_url": "https://storage.googleapis.com/op-atlas/ffb2a694-74be-48f3-897d-96034c088b3a.png", + "twitter": null, + "repos": [ + "https://github.com/upnodedev/signer-proxy" + ], + "tags": [ + "security", + "docker", + "transaction-signing" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xa0b16714baef75d97ec07fd48eaf42e79df92fe2a3c2d725d2388ede587ea54c", + "name": "Ape Framework", + "description": "The smart contract development tool for Pythonistas, Data Scientists, and Security Professionals", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/ab983e5d-4c75-4fc9-9b02-187a4f479c8a.png", + "banner_url": "https://storage.googleapis.com/op-atlas/238f7d0e-c18b-48ad-8e9a-24407ef90eaf.png", + "twitter": "https://twitter.com/ApeFramework ", + "repos": [ + "https://github.com/ApeWorX/silverback", + "https://github.com/ApeWorX/ape", + "https://github.com/ApeWorX/ape-optimism", + "https://github.com/ApeWorX/ape-base" + ], + "tags": [ + "cross-chain", + "layer-2", + "cli" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x81af86360a8e964cc907a5689a62e94231c7e42e05f49c0586716975d72e2e2e", + "name": "Upnode Deploy", + "description": "Upnode Deploy allows chain operators and developers to quickly launch their OP Stack chain with the necessary infrastructure, including an explorer, bridge, faucet, and monitoring system, by modifying a few environment variables related to the RPC endpoint, private keys, and chain information.\n\nWith a single Docker Compose command, they can launch and manage every component of the OP Stack chain, including the ability to deploy a replica node by providing `rollup.json` and `genesis.json`. Upnode Deploy also offers a user interface similar to Conduit, which simplifies the OP Stack deployment process.\n\nUnlike Conduit, Upnode Deploy provides developers and chain operators with a tool to deploy OP Stack chains on their own servers instead of relying on third-party managed servers. Upnode Deploy is free, open-source, and fully transparent, whereas Conduit is a paid, closed-source solution.\n\nUpnode Deploy supports the latest OP Stack v1.9.0 and is prepared for the upcoming migration from `pnpm` to `just`.\n\nUpnode Deploy has won Fraxtal Hackathon: https://dorahacks.io/buidl/13971\n\nVideo of docker compose deploying an OP Stack L3 on Fraxtal: https://www.youtube.com/watch?v=8dytrXGjDG4", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/91ebe6cd-12a6-42fb-b3ef-d717e79ac9b8.png", + "banner_url": "https://storage.googleapis.com/op-atlas/84ec5980-5e06-4630-92b4-16ce9e9e3f83.png", + "twitter": "https://x.com/upnodeIntern", + "repos": [ + "https://github.com/upnodedev/opstack-cli", + "https://github.com/upnodedev/opstack-bridge-ui-v2", + "https://github.com/upnodedev/evm-faucet", + "https://github.com/upnodedev/upnode-deploy-ui", + "https://github.com/upnodedev/opstack-compose", + "https://github.com/upnodedev/opstack-bridge-ui", + "https://github.com/upnodedev/opstack-bridge-indexer", + "https://github.com/upnodedev/opstack-bridge-indexer-v2" + ], + "tags": [ + "cli", + "docker", + "devops" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x7504e494cb8d227193182e083128912173c14eaeecec9b90fa453de28377b269", + "name": "Hermes - a GossipSub listener and tracer for libp2p-based networks.", + "description": "The ProbeLab team has recently built Hermes, a GossipSub listener and tracer for libp2p-based networks. Hermes-based experiments aim to measure the efficiency and performance of the GossipSub message broadcasting protocol in any libp2p-based network. Acting as a light node of sorts, Hermes can help developers collect valuable data and tune their network’s protocols based on the message propagation latency, control message overhead and a variety of other metrics. Hermes currently supports the Ethereum consensus layer network.\n\nThe ProbeLab team specialises in network-layer measurements and monitoring. The team operates a variety of tools and uses the data it collects to propose network protocol optimisations.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/90c0de0c-cc0e-4959-afb7-a78ae4c9d674.png", + "banner_url": "https://storage.googleapis.com/op-atlas/e1d59a51-3f6f-4642-bc88-553026d2d067.png", + "twitter": "@yiannisbot", + "repos": [ + "https://github.com/probe-lab/hermes" + ], + "tags": [ + "governance", + "gossipsub", + "libp2p", + "cli" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xada9c2eabe94a7af5d96b3cb1765c8e3d6fb8a7f8e33f12ebd6d66feb1a807a3", + "name": "Curvegrid MultiBaas", + "description": "Curvegrid offers cutting-edge solutions for blockchain application development. Curvegrid's flagship product, MultiBaas, streamlines the DApp development process with a user-friendly web UI and a robust REST API. Supporting multiple EVM chains, MultiBaas accelerates time-to-market for sectors including finance, DeFi, gaming, art, and logistics.", + "thumbnail_url": "https://cdn.charmverse.io/user-content/cae02d37-eadb-4a01-a063-d72588a78203/a6dfa7b6-3b1c-4ff3-b5e5-f82624024c5e/Icon-(Color).svg", + "banner_url": "https://cdn.charmverse.io/user-content/cae02d37-eadb-4a01-a063-d72588a78203/3151e0b3-b99e-4da6-9fdf-e98c3e985c22/Curvegrid-Banner-(1).png", + "twitter": "https://x.com/curvegridinc", + "repos": [ + "https://github.com/curvegrid/multibaas-sdk-go", + "https://github.com/curvegrid/multibaas-sdk-typescript", + "https://github.com/curvegrid/multibaas-for-google-sheets", + "https://github.com/curvegrid/multibaas-sample-app", + "https://github.com/curvegrid/hardhat-multibaas-plugin", + "https://github.com/curvegrid/" + ], + "tags": [ + "defi" + ], + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "0xdd8b2e68cad9afa0701c8f27bf085302b152dbca3393083d3c664e3fc75945ab", + "name": "Redprint", + "description": "Redprint toolkit, is a toolchain and knowledge hub to improve OPStack accessibility, tailored for developer. It includes:\n\n1) Redprint wizard: It is a code generator/ interactive playground to debug/modify OPStack ’s codebase. It supports a space to experience, and build features which aren't yet available on the production at all, empowering developers to tinker, and push the boundaries of what's possible by composing their own different OPStack components together. \n\n2) redprint-forge: It is a developer-friendly framework/library in solidity to deploy OPStack ’s contracts in a modular style. It supports type-safe smart contract deployment, re-usable testing pipeline, all-Solidity-based ( no context switching), and tx Management via Safe Smart Contract Deploy Script", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/3cc6bd19-1ade-4c0d-8fe3-ec6ea6f50183.png", + "banner_url": "https://storage.googleapis.com/op-atlas/d2d120fb-11fa-456c-b7e0-b0ed52b477e0.png", + "twitter": "", + "repos": [ + "https://github.com/Ratimon/redprint-forge", + "https://github.com/Ratimon/redprint-wizard" + ], + "tags": [ + "education", + "frontend", + "solidity", + "type-safe" + ], + "website": "https://redprint.ninja/", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x11a2255f272c84328438f5081139455d8fd2a302fd35f0f08acdff1f1c0d84e6", + "name": "Node Guardians", + "description": "Node Guardians is a gamified educational platform for intermediate to advanced developers. We create lore-rich programming challenges for accomplished Solidity developers. Think of it as a skill-based RPG for developers and a platform to showcase their abilities. ", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/6878f254-b99f-47ad-8cf8-7f6cd1601300.png", + "banner_url": "https://storage.googleapis.com/op-atlas/8f285391-e69f-40f3-aa14-1456fbb92440.png", + "twitter": "https://x.com/nodeguardians", + "repos": [ + "https://github.com/Nodeguardians/optimism" + ], + "tags": [ + "education", + "solidity" + ], + "website": "https://nodeguardians.io/", + "category": "Education & Community Resources" + }, + { + "id": "0xcc8d03e014e121d10602eeff729b755d5dc6a317df0d6302c8a9d3b5424aaba8", + "name": "Solidity", + "description": "Solidity is an object-oriented, high-level language for implementing smart contracts.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/b6f312d0-1025-4a19-baa9-3aa218fe0833.png", + "banner_url": "https://storage.googleapis.com/op-atlas/bca65077-a87b-4fd8-bcc3-9ad0a65d9d27.png", + "twitter": "https://x.com/solidity_lang", + "repos": [ + "https://github.com/ethereum/solidity", + "https://github.com/ethereum/solc-js" + ], + "tags": [ + "education", + "solidity", + "compiler", + "cli" + ], + "website": "https://soliditylang.org/", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x1aacb85f1d87039696b876ddcae98c56d38ea9eed07b265409fdb256c8f8172a", + "name": "Blockhead", + "description": "Open-source portfolio tracker and explorer interface for the decentralized web. https://blockhead.info", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/3a1343aa-8bb3-4f30-abc0-6ba02dd3787a.png", + "banner_url": "https://storage.googleapis.com/op-atlas/7c1ee7ff-ad46-4b74-a941-48cc7ddc2dbe.png", + "twitter": "https://x.com/0xBlockhead", + "repos": [ + "darrylyeo/blockhead", + "https://github.com/darrylyeo/blockhead" + ], + "tags": [ + "block-explorer" + ], + "website": "https://blockhead.info", + "category": "Data, Analytics & Tracing" + }, + { + "id": "0xdf1bb03d08808e2d789f5eac8462bdc560f1bb5b0877f0cf8c66ab53a0bc2f5c", + "name": "Rust Libp2p", + "description": "The rust implementation of libp2p. Libp2p is a modular framework for a variety of p2p protocols. These protocols are used widely by a variety of projects to establish p2p communications in a decentralized manner.\n\nThe rust implementation is used by a variety of projects in the space including, Magi (OP Stack rollup client), Lighthouse (Ethereum consensus client) and Forest (Filecoin client). \n\nThe rust implementation specifically, is used by a variety of projects in the ", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/352a5108-5f07-4765-a43d-7ba0b4b27054.png", + "banner_url": "https://storage.googleapis.com/op-atlas/01e43966-8955-4584-b45d-84645a97dc5d.png", + "twitter": "@sigp_io", + "repos": [ + "https://github.com/libp2p/rust-libp2p" + ], + "tags": [ + "docker", + "community-driven" + ], + "website": "https://sigmaprime.io", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x9b014e8a2e062401d976745d9c8aafbf36bce7931586b36ecf3b9ad708bf2970", + "name": "Blobscan", + "description": "**About Blobscan**\n\nBlobscan is the first open-source blockchain explorer designed to navigate and visualize shard blob transactions introduced in EIP-4844. It provides essential public infrastructure to help scale Ethereum, featuring:\n\n- 🔍 Advanced blob search and filtering\n- 🧠 Rich blob decoding (including Starknet and Optimism support)\n- 🗃 Multiple persistent blob storage integrations\n- 📊 A detailed analytics dashboard\n- 🔌 An API for querying blobs and metrics\n- 🐳 Docker and Kubernetes-ready deployment options\n\nOur mission is to make blob data accessible, transparent, and usable for the entire Ethereum ecosystem.\n\n**Who We Are**\n\nWe’re a small team of four developers (3 fullstack engineers and one DevOps specialist) fully committed to pushing Blobscan forward as a vital part of Ethereum’s scaling roadmap.\n\n**Recent Milestones & Updates**\n\nWe’ve shipped a number of important updates and new features, including:\n\n**🔧 Core Improvements**\n\n- Collaboration with ethPandaOps to prepare for the Dencun fork.\n- Collaboration with Load Network (prev. WeaveVM) as a new blob storage solution\n- Partnered with Ethereum Swarm, now sponsoring one year of blob storage\n- Expanded support for a total of 72 rollups.\n\n**🌐 Website Enhancements**\n\n- Introduced powerful search filters: by **slot, block, date range, and rollup**\n- Launched **rollup-level metrics** and statistics\n- Added **initial decoding support for Starknet and Optimism blobs**\n- Major improvements to the **mobile experience**\n- Numerous frontend performance and usability enhancements\n\n**🛠 DevOps & Developer Experience**\n\n- Re-architected the platform for better scalability and maintainability\n- Made Blobscan **Kubernetes-ready**\n- Improved Docker images — now **10x smaller and faster**\n- Published a **detailed deployment guide** using Kurtosis and Kubernetes\n- Revamped and expanded documentation\n\n**Funding & Outlook**\n\nBlobscan is currently supported by **Optimism RetroPGF**, and we’re incredibly grateful for this backing. We love working on Blobscan and have an exciting roadmap of improvements ahead — including deeper blob analytics, enhanced rollup-specific features, and broader ecosystem integrations.\n\nWe see Blobscan as a vital public good for Ethereum’s future and are committed to delivering the tools the ecosystem needs to thrive.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/af580f21-8a05-40b2-b839-aaed37495186.png", + "banner_url": "https://storage.googleapis.com/op-atlas/6fee849e-314e-4285-92d9-b6b27d09f4a3.png", + "twitter": "https://x.com/blobscan", + "repos": [ + "https://github.com/Blobscan/blobscan-helm-charts", + "https://github.com/Blobscan/blobscan-indexer.rs", + "https://github.com/Blobscan/blobscan", + "https://github.com/Blobscan/blobscan-infra" + ], + "tags": [ + "analytics", + "docker", + "frontend", + "visualization" + ], + "website": "https://blobscan.com/", + "category": "Data, Analytics & Tracing" + }, + { + "id": "0xd9d413772483111ca8ecfe5054737c6c80a65f03c0d289c632b05e3ec21d5680", + "name": "Opstack Kit", + "description": "Bridging hooks for OP Stack Chains\nnpm i opstack-kit | is a toolkit for all upgrades. To easily connect and interact with the OP-Stack (Superchain)\n\n📝 - Focus on Your Dapp\nEffortlessly create awesome OP-Stack (Superchain) sites with just npm i opstack-kit.\n\n🧑‍💻 - Enjoy the \"opstack-kit\"\nInstant server start, lightning fast hot updates, and leverage OP-Stack (Superchain) ecosystem.\n\n⚙️ - Customize with OP-Stack\nUse syntax and components directly in \"opstack-kit\", or build custom themes.\n\n🚀 - Ship Fast Sites\nStart creating quickly \"opstack-kit\" after that deploy it to your network.\n\nFeatures\n- Simplifies cross L1 & L2 interactions\n- Supports \"CustomGasToken\" deposit & withdrawal functions\n- Supports multi-functionality & new fault-proof feature\n- CLI command development tools (prove, finalize)", + "thumbnail_url": "https://cdn.charmverse.io/user-content/e3eb66db-408b-4e21-bc69-c2927fd15b32/552ea203-8cee-4111-9a61-82fd3da74367/ok.png", + "banner_url": "https://cdn.charmverse.io/user-content/e3eb66db-408b-4e21-bc69-c2927fd15b32/874ceabb-8637-48ef-935d-747218d514fc/opstackkit-cover.jpg", + "twitter": "opstackkit", + "repos": [ + "opstack-kit", + "https://github.com/opstack-kit/opstack-kit" + ], + "tags": [ + "cli", + "cross-chain" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x5a7e7c7acb21521e99021d746740b368801cbfe531301e50bdbaafdc24a0aac5", + "name": "js-libp2p", + "description": "The canonical JavaScript implementation of libp2p. Js-libp2p is a collection of protocols that support a wide range of functionalities, such as; connection establishment, remote node protocol identification and negotiation (through its identify protocol), data encryption, content/peer discovery (through its Kademlia DHT component), and data transfer through its pub-sub protocol (Gossipsub).\n\nThe stakeholders of js-libp2p include the Interplanetary Shipyard team who maintain this implementation as well as projects that depend on js-libp2p like major on-chain builder apps like Farcaster. Farcaster contracts are deployed on Optimism and they rely directly on js-libp2p in Farcaster Hubs (transports and protocols like GossipSub).\n\nAdditionally, ChainSafe's Lodestar (Ethereum consensus client written in Typescript), Ocean Protocol (in their Ocean Nodes implementation), OrbitDB (a serverless, distributed, peer-to-peer database), Warden Protocol, and many more: https://github.com/libp2p/js-libp2p/tree/main#used-by and https://github.com/libp2p/js-libp2p/network/dependents.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/11d09c62-9356-40b2-9cd2-06b98f816bfb.png", + "banner_url": "https://storage.googleapis.com/op-atlas/826fafd9-28a8-49f8-9d07-0e5e57880f20.png", + "twitter": "https://x.com/ipshipyard", + "repos": [ + "https://github.com/libp2p/js-libp2p" + ], + "tags": [ + "libp2p", + "encryption", + "gossipsub" + ], + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0xc71faa1bcb4ceb785816c3f22823377e9e5e7c48649badd9f0a0ce491f20d4b3", + "name": "go-libp2p", + "description": "The canonical Golang implementation of libp2p. Go-libp2p is a collection of protocols that support a wide range of functionalities, such as; connection establishment, remote node protocol identification and negotiation (through its identify protocol), data encryption, content/peer discovery (through its Kademlia DHT component), and data transfer through its pub-sub protocol (Gossipsub).\n\nThe stakeholders of go-libp2p include the Interplanetary Shipyard team who maintain this implementation as well as projects that depend on go-libp2p like Optimism's op-node (the reference implementation of the rollup-node spec), the Ethereum Beacon Chain (via Prysm, the Go consensus client), Filecoin (Lotus and Venus), Celestia node, and many more: https://github.com/libp2p/go-libp2p?tab=readme-ov-file#notable-users.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/277d8353-44c4-4e16-a2bd-2dfb3fb9e65f.png", + "banner_url": "https://storage.googleapis.com/op-atlas/4c70ca4a-8b38-47ee-97d0-2a64a63700f8.png", + "twitter": "https://x.com/ipshipyard", + "repos": [ + "https://github.com/libp2p/go-libp2p" + ], + "tags": [ + "governance", + "libp2p", + "peer-to-peer", + "networking", + "encryption", + "gossipsub", + "community-driven" + ], + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0xa7d78d566bfa319479ec048c94c3d8c1f4d628a9344ba157fc4974dbf472dc3e", + "name": "Aderyn", + "description": "Aderyn is an open-source, public-good developer tool. It is a Rust-based solidity smart contract static analyzer designed to help protocol engineers and security researchers find vulnerabilities in Solidity code bases.\n\nAderyn integrates seamlessly into small and enterprise-level development workflows. It offers lightning-fast, command-line static analysis functionality and a framework for building custom detectors that adapt to any Solidity codebase.\n\nAderyn does three things really well:‍‍‍\nIdentify Solidity Smart contract vulnerabilities: Cyfrin Aderyn quickly identifies potential vulnerabilities in Solidity code and highlights parts of the codebase for further investigation.\n\nSupports building custom detectors to suit your needs: Protocols and security researchers can use the Cyfrin Aderyn framework to build custom vulnerability detectors for any Solidity codebase.\n\nIdentify known issues and protect OP value: Competitive auditing platforms can use Cyfrin Aderyn to detect and filter out known issues inside protocol codebases, protecting customers' and auditors' time and value.\n\nWho is it for?\n\n1. Developers\nAs a new generation of developers enters the space, we (the security community) are responsible for using our knowledge and experience to create tools that facilitate secure development practices. We need to make it easy to avoid repeating past mistakes.\n\nFrom a developer's perspective, the cost of finding bugs in Solidity code is exorbitantly high. Engaging top-tier security firms like Cyfrin Private Audits or competitive audit platforms like CodeHawks requires serious cash. That's because the security knowledge required to stamp out bugs is pooled among security firms and competitive auditors, who are in demand.\n\nWe must drive the cost of finding bugs, especially the common and known ones, towards zero by creating tools that make development secure by nature.\n\nAderyn is built for lightning-fast, open-source static analysis that hooks into the existing development workflow.\n\n2. Security Researchers\nSecurity Researchers are the knowledge guardians of the on-chain world. They are the people you engage with when you're undergoing an audit. Many auditors start every audit with a long checklist. They read through the codebase, ensuring the code doesn't violate any items on their list. If it does, it's an issue for the report. Once they've finished with this list, they get creative and try out other techniques.\n\nAderyn's detector framework enables Security Researchers to encode the patterns they look for in their checklist into Aderyn detectors. By doing this, the research community can focus on the deeper, more complex bugs, knowing that tooling has uncovered the repetitive checklist of issues so they don't have to.\n\nDevelopers write more secure code before they engage Security Researchers, and when they do, the Researchers can spend more time on complex bugs instead of manually checking for easy fixes.\n\nWhat makes Aderyn unique vs similar tools?\nSpeed: Real-time feedback as you’re coding with the upcoming vscode extension.\n\nCutting-edge detectors: The detectors are built from the latest findings from external and in-house auditors. This means developers can harness the power of an audit team at their fingertips for free!\n\n“Auditor Mode”: Helps auditors find specific areas and concepts within a codebase to dig further. For example, “Show me all of the instances in which this storage slot is altered”.\n\nOpen-source: This tool is completely open-source and will be free for all developers in perpetuity. Cyfrin does not make money directly from it.\n\nAdoption of tool: Aderyn is now used by developers across the Superchain ecosystem and we are continuously building new custom detectors for developers. \n\nImportance of tool: Security is paramount for mass adoption. Without security, adding any TVL to the Superchain is risky. We want to support developers from day zero and provide real time security analysis whilst projects are being built.\n\nSuperchain interoperability: We want to ensure that when working cross chain, builders are doing so with secure frameworks. We also include building customer detectors for interoperability. \n\nWho are Cyfrin:\nCyfrin is the industry-leading smart contract education and security company. Home to 8,000 security researchers and a community of over 100,000 students and smart contract engineers, we provide audits, tools, and education to the world's biggest decentralized protocols, institutions, and products.\n\nCyfrin works closely with Optimism and the Superchain as a whitelisted security service provider. We want to continue adding value to the Optimims ecosystem. \n\nThis project refers specifically to Cyfrin's developer tool, Aderyn.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/0c66d95b-8f82-45a2-87a8-77205bf90a96.png", + "banner_url": "https://storage.googleapis.com/op-atlas/dcb9e7e2-4619-4382-af31-a5c9a75e703f.png", + "twitter": "https://x.com/CyfrinAudits", + "repos": [ + "https://github.com/Cyfrin/aderyn" + ], + "tags": [ + "cli", + "security", + "education", + "solidity", + "static-analysis", + "vscode-extension", + "community-driven" + ], + "website": "https://github.com/Cyfrin/aderyn", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x7348ae42266ff626319e8ea5398343b847603b3cc7101b03d8e4fb2b75ea8db3", + "name": "Kontrol - formal verification tool based on Foundry and KEVM", + "description": "Runtime Verification has been at the forefront of open-source formal verification tools for more than a decade. Our generalistic approach allows us to use our technology on multiple blockchains. While KEVM offers our verification infrastructure to all EVM-based smart contracts, Kontrol greatly reduces the barrier to entry to formal verification for Solidity smart contracts.\nOur tooling is completely open source and freely accessible to all developers of the Optimism ecosystem at no additional cost.\n\nKEVM is an EVM executable formal semantics written in the K framework. KEVM passes all Ethereum conformance tests and is the entry point for formally verifying smart contracts with the K framework. However, using plain KEVM requires ad-hoc training on the K framework to write specifications. Additionally, these specifications can be quite verbose, increasing the difficulty of writing them.\n\nKontrol solves this by allowing developers to write the formal specification of their smart contracts directly as Foundry property tests. These tests are automatically translated into KEVM specifications, keeping all the verification guarantees whilst allowing for a much more easy developer experience.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/1dce415e-060b-4f57-83ed-71ba91207614.png", + "banner_url": "https://storage.googleapis.com/op-atlas/e0035388-4b23-4215-98e3-c96e712cc18c.png", + "twitter": "https://x.com/rv_inc", + "repos": [ + "https://github.com/runtimeverification/_audits_lidofinance_dual-governance_fork", + "https://github.com/runtimeverification/yearn-v3-term-vault", + "https://github.com/runtimeverification/kontrol", + "https://github.com/runtimeverification/Depeg-swap", + "https://github.com/runtimeverification/optimism-ci", + "https://github.com/runtimeverification/_audits_Ethereum-optimism_pausability" + ], + "tags": [ + "foundry", + "education", + "governance", + "formal-verification", + "solidity", + "runtime-verification", + "contract-deployment", + "static-analysis" + ], + "category": "Security, Testing & Formal Verification" + }, + { + "id": "0x229bbc8163bdee3891cde1c18c74ab3afc72e8683692fc7f1b767570cbe7c4a7", + "name": "EVM Explorer", + "description": "We are excited to introduce EVM Explorer, a powerful, open-source web interface designed to streamline the exploration and analysis of blockchain data across multiple EVM chains, including the Optimism ecosystem. EVM Explorer utilizes the BlockScout API and viem library to enable users to delve into transaction patterns, user behavior, and smart contract data, providing a versatile tool for efficient and insightful blockchain exploration.", + "thumbnail_url": "https://cdn.charmverse.io/user-content/9c114ea1-adb5-4858-b4f2-40050fa74370/99b90eeb-a7ea-4ca6-938e-410fff892510/Social.png", + "banner_url": "https://cdn.charmverse.io/user-content/9c114ea1-adb5-4858-b4f2-40050fa74370/b2606c27-a963-43aa-8e78-e38e89897808/pexels-mont-photographs-385313-2948636.jpg", + "twitter": "https://x.com/ExplorerEVM", + "repos": [ + "https://github.com/Pfed-prog/NextJsExplorer", + "https://github.com/Pfed-prog/EVMExplorer-Blockscout", + "https://github.com/Pfed-prog/EVMExplorer-Uniswap", + "https://github.com/Pfed-prog/EVMExplorer-Utility", + "Pfed-prog/NextJsExplorer" + ], + "tags": [ + "analytics", + "governance", + "chains", + "visualization" + ], + "website": "https://evmexplorer.com/", + "category": "Data, Analytics & Tracing" + }, + { + "id": "0x2c97e213fef2bd3f30a71edf6ed48232640368d0083dc0a134a1b59391639bde", + "name": "hevm", + "description": "hevm is an open source, state-of-the art, fast symbolic and concrete EVM execution engine that can find issues in smart contracts. Through its symbolic execution and analysis system, hevm can symbolically, semi-concretely, or concretely execute contracts to find bugs, or compare two different contracts for discrepancies, performing equivalence checking. \n\nHevm is used in Echidna for concrete execution, mamory.xyz to detect potential (economic) MEV extraction, and by the Vyper team to help find potential bugs in compiler optimizations. Hevm can be used both as a console tool and as a library interface, allowing it to be part of high level tooling, such is the case with Echidna, where both its concrete and symbolic execution semantics are exercised.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/d7cf4059-4f9c-48aa-a37a-df2f8c81933c.png", + "banner_url": "https://storage.googleapis.com/op-atlas/020d34f6-e8bb-43b5-8508-7935d2b00583.png", + "twitter": null, + "repos": [ + "https://github.com/ethereum/hevm" + ], + "tags": [ + "cli", + "foundry", + "security", + "symbolic-execution" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xf2a60464d2a56fb47d2f8c13001edea71eda11ffd8fffec5f559495c6a5878d4", + "name": "Unruggable ", + "description": "Unruggable is focused on building the next generation of blockchain-based naming services. Our mission is to create secure and user-friendly solutions that enable projects and Layer 2 networks to establish their own naming systems using the Ethereum Name Service (ENS). As part of our commitment to open-source software development, we provide essential infrastructure that allows everyone to benefit from the scaling of ENS and L2 blockchains:\n\n'Unruggable Gateways' is an open source codebase that implements a complete solution for fetching proofs of data from rollup chains and verifying that data on Layer 1 Ethereum. We operate our own gateways using the codebase and are committed to supporting the trustless resolution of ENS names.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/ff2964ec-4435-4cf8-b993-e16f49b47b96.png", + "banner_url": "https://storage.googleapis.com/op-atlas/58530a8a-1957-45c8-92dd-808196c1491f.png", + "twitter": "https://x.com/unruggable_eth", + "repos": [ + "https://github.com/unruggable-labs/unruggable-gateways-examples", + "https://github.com/unruggable-labs/unruggable-gateways" + ], + "tags": [ + "cross-chain", + "layer-2", + "verification", + "solidity", + "scalability" + ], + "website": "https://unruggable.com/", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x2704cd27b8c60b098d4fe8c5c0fbae2f8f5fe9067c687c501a4c6dc6e9887876", + "name": "Act", + "description": "Act is a smart contract specification language and toolkit for formal verification. Act specifications are a formal, high-level description of all possible behaviours of an EVM program. Act allows many existing general purpose verification tools to be leveraged to prove properties about the specification. Such tools include SMT solvers (cvc5, z3, bitwuzla), theorem provers (Coq) and economic analysis tooling (CheckMate, Open Games). Act specifications can be automatically proved equivalent to concrete implementations in EVM. For very simple contracts, Act specifications can be automatically generated from EVM bytecode.\n\nThis is an end-to-end pipeline that supports principled reasoning about high level properties of EVM bytecode. It supports reasoning about both correctness (e.g. accounting invariants) and economic properties (e.g. incentive compatibility). Act specifications serve as a high-level smart contract representation, allowing for easy integration of existing general purpose analysis and verification tooling into the EVM context.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/a08fa912-3bc7-4957-9a64-5b10bc13397e.png", + "banner_url": "https://storage.googleapis.com/op-atlas/16e8a1cb-69b1-4098-8c40-fd25a5a29b8f.png", + "twitter": null, + "repos": [ + "https://github.com/ethereum/act" + ], + "tags": [ + "education", + "analytics", + "formal-verification", + "symbolic-execution" + ], + "category": "Security, Testing & Formal Verification" + }, + { + "id": "0x7d3f1d8e9da32b6e81e791a440b28ce9fbd79a5396acc4039d1cdc44c609c6d3", + "name": "OP STACK DEPLOYER", + "description": "OP Stack Deployer is a comprehensive tool designed to streamline the setup and deployment of an OP Stack chain. By automating complex tasks, it offers a seamless experience for developers. Whether you're an experienced blockchain developer or a newcomer, OP Stack Deployer provides the necessary resources to quickly get your OP Stack-based EVM Rollup operational.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/90d877db-39f3-4b3c-bb8e-90f26e734254.png", + "banner_url": "https://storage.googleapis.com/op-atlas/6e5a0785-93ce-438a-af3d-d81460919f57.png", + "twitter": "", + "repos": [ + "https://github.com/Aymen-Tirchi/op-stack-deployer" + ], + "tags": [ + "cli", + "foundry" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xb2d109759fe14e11ac5cc100ab6006321ebdd7ffdefbd2efac93a002105f8e92", + "name": "Revm", + "description": "Revm is a critical component in the Ethereum ecosystem used by builders, toolings, clients and chains.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/57aeca37-e53b-4bcb-b161-0608d09e5c62.png", + "banner_url": "https://storage.googleapis.com/op-atlas/786c9752-af70-4856-9be0-38f4141769d2.png", + "twitter": "https://x.com/rakitadragan", + "repos": [ + "https://github.com/bluealloy/revm" + ], + "tags": [ + "community-driven" + ], + "website": "https://github.com/bluealloy/revm", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x6bd057da522918a4675396313ae33a2f2788a1ceeb3bd7ae228015e3eb317a7d", + "name": "Viem: TypeScript Interface for Ethereum", + "description": "Viem is the most used modern TypeScript Interface for Ethereum. Viem provides robust, performant, and type-safe modules to be the foundation for building Web Applications, TypeScript Libraries, Wallets, Backends, Indexers, Scripts, and more, on top of Ethereum (and the OP Stack). With over 3 million monthly downloads, Viem is used in production by most at-scale projects like Coinbase, Uniswap, Optimism, Polymarket, Zora, Opensea, WalletConnect, Farcaster, Rainbow, and so much more.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/171f60c2-1e3e-4b0a-998e-4015a7f468f7.png", + "banner_url": "https://storage.googleapis.com/op-atlas/64c06023-a910-4646-ba3e-81baa2d935dc.png", + "twitter": "https://x.com/wevm_dev", + "repos": [ + "https://github.com/wevm/viem" + ], + "tags": [ + "json-rpc", + "type-safe", + "hardhat" + ], + "website": "https://viem.sh", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x9151666888d0ca532a529be98a50d2eb992988117e202163f865fa9a27eb7149", + "name": "Solady", + "description": "Solady is an open-source repository containing highly-optimized Solidity snippets. It offers efficient implementations of commonly-used libraries, such as MerkleProofLib, alongside cutting-edge features like LibZip.\n\nBy thoughtfully encapsulating low-level inline assembly within flexible APIs, Solady simplifies the process of writing clean and efficient Solidity code. More than just a library, Solady also serves as a learning resource and experimental laboratory for pioneering gas-optimization techniques.\n\nSolady is used in the codebases of Optimism and Coinbase.\n\nWith respect to the OP stack, Solady contributes in the following ways:\n- Provides a Solidity and JavaScript implementation of FastLZ compression algorithm, which is used for more accurate gas estimations in the Fjord upgrade. The JavaScript code is very minimal, allowing for it's easy translation into Go.\n- Various other utilities such as bytecode proxies and string operations.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/0e726459-df1e-4cea-bddb-25399f88acea.png", + "banner_url": "https://storage.googleapis.com/op-atlas/0615ef25-edbb-4b19-934d-79614daf8040.png", + "twitter": "https://twitter.com/optimizoor", + "repos": [ + "https://github.com/Vectorized/solady" + ], + "tags": [ + "education", + "solidity", + "gas-optimization", + "foundry", + "hardhat" + ], + "website": "https://solady.org", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x492d0bbb85672e7e5f1d439bfd8857ac0aa59a52010143bbaab1a411bf55be0c", + "name": "TurtleShell", + "description": "One day you wake up and your protocol got exploited …maybe you heard of Circuit Breakers as attempt to end that quite real nightmare.\n\nWith TurtleShell we are aiming to give every Smart Contract holding Assets the necessary bolster to prevent unintended outflow.\n\nAvailable open-source tools include:\n- Smart Contract SDK\n- Frontend SDK, for visualizing relevant security data", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/c76c04f2-a5d4-488b-b427-0d1580bcfd9e.png", + "banner_url": "https://storage.googleapis.com/op-atlas/e5114d50-c66b-41ab-b064-14802e9f927a.png", + "twitter": "https://twitter.com/turtleshell_xyz", + "repos": [ + "https://www.npmjs.com/package/@markeljan/circuitbreaker", + "https://github.com/turtleshell-xyz/circuitbreaker", + "https://github.com/turtleshell-xyz/frontend-boilerplates", + "https://github.com/turtleshell-xyz/nomad-bridge-poc" + ], + "tags": [ + "frontend", + "security", + "solidity", + "tailwind-css", + "hardhat", + "truffle" + ], + "website": "turtleshell.xyz", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xc2d8139cd61ddc75689610ee0cca0fe37ba8bec3270beb6aac6eac91c6256f60", + "name": "hardhat-gas-reporter", + "description": "A hardhat plugin that provides gas usage analytics for smart contract test suites. It has dedicated support for OPStack chains, is a dependency in > 150k Github repos and is downloaded from NPM > 100k per week. ", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/08754b7b-75c3-436b-ad66-bdf4b4261895.png", + "banner_url": "https://storage.googleapis.com/op-atlas/a3c56a18-2e9d-4a19-ba54-892bfa062884.png", + "twitter": null, + "repos": [ + "https://github.com/cgewecke/hardhat-gas-reporter", + "https://www.npmjs.com/package/hardhat-gas-reporter" + ], + "tags": [ + "analytics", + "hardhat", + "test-automation" + ], + "website": "https://www.npmjs.com/package/hardhat-gas-reporter", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x9ca1f7b0e0d10d3bd2619e51a54f2e4175e029c87a2944cf1ebc89164ba77ea0", + "name": "Vyper", + "description": "Pythonic Smart Contract Language for the EVM", + "thumbnail_url": "https://cdn.charmverse.io/user-content/5302de23-eae6-4cda-97aa-25fefd829726/9aa6f15f-e32a-4bca-a40a-5b1e1122babb/2024-06-11_23-25.png", + "banner_url": "https://cdn.charmverse.io/user-content/5302de23-eae6-4cda-97aa-25fefd829726/6c137923-55fc-4dc9-9424-5dad59f82ab4/vyper-optimism.png", + "twitter": "https://x.com/vyperlang?lang=en", + "repos": [ + "https://github.com/vyperlang/vyper" + ], + "tags": [ + "compiler", + "devops" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x0008577196fa6ec286440b418e2f6305fc10e62ce759625d826be272ee6b45a3", + "name": "CreateX", + "description": "CreateX is a Trustless, Universal Contract Deployer that provides everyone with an easier and safer way to use the EVM opcodes `CREATE` and `CREATE2` as well as `CREATE3`-based (i.e. without an initcode factor) contract creations. CreateX is a preinstall on the OP Stack: https://specs.optimism.io/protocol/preinstalls.html#createx.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/4e18f37a-1991-48a1-9622-c43fa3e04f3e.png", + "banner_url": "https://storage.googleapis.com/op-atlas/a508253b-4224-4c48-8519-3fefcf39fc2f.png", + "twitter": null, + "repos": [ + "https://github.com/pcaversaccio/createx/releases/tag/v1.0.0", + "https://github.com/pcaversaccio/createx" + ], + "tags": [ + "cli", + "contract-deployment", + "solidity" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x50159544ec22884b777a997a625c75bb02e55b1dc8934aad3b78678e7c11d039", + "name": "🐍 snekmate", + "description": "State-of-the-art, highly opinionated, hyper-optimised, and secure 🐍Vyper smart contract building blocks.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/baed8e76-d872-4218-9648-9bb5700dabc9.png", + "banner_url": "https://storage.googleapis.com/op-atlas/e205286d-1799-4d72-992a-a8ebe394c59b.png", + "twitter": null, + "repos": [ + "https://pypi.org/project/snekmate", + "https://www.npmjs.com/package/snekmate", + "https://github.com/pcaversaccio/snekmate" + ], + "tags": [ + "defi", + "vyper", + "erc721", + "foundry" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x4cba820efd9e11754eb472ca0736756f27d0ece09adb3c9651bac5b29acc9a6d", + "name": "Blockflow", + "description": "Blockflow equips devs with the data and API tools to build innovative products faster. Unlike traditional solutions like RPCs and other Data Providers, Blockflow enables you to build \"Serverless Backends\", streamlining your operations without the heavy infrastructure, and saving 70% time & resources in building & 100% in maintenance.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/dbe12049-50ea-4cfb-b3f0-8def50ea7b07.png", + "banner_url": "https://storage.googleapis.com/op-atlas/191beaf8-e92f-42be-ab94-2305d12da9a4.png", + "twitter": "https://x.com/BlockflowLabs", + "repos": [ + "https://github.com/blockflowlabs/cli-examples", + "https://www.npmjs.com/package/@blockflow-labs/cli/v/1.0.7-beta.1" + ], + "tags": [ + "cli" + ], + "website": "https://www.blockflow.network/", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x1c25ae2899ab6edb1e55c8cda5b736bb861a31da22bb9aa538f3868807eb1c73", + "name": "Bonadocs ", + "description": "Bonadocs allows web3 engineering teams to collaborate and build applications in a very intuitive way. To simplify integrations, we've categorized our tooling as follows:\n\nDocgen: Docgen allows developers to go from their codebase to beautiful and interactive documentation in seconds. Using our hardhat plugin, you can generate interactive documentation to query your contract methods.\n\nWidget: Through our playground environment, you can generate widgets for your contract methods. These widgets can then be easily embedded in your docs or any react application for devs to query. This is instrumental for devrel teams, to help onboard external devs.\n\nPlayground: Our playground is a collaborative environment primarily for solidity and front-end devs to build applications. This can be used by internal engineering teams or teams across different organizations. Devrel teams can also take advantage of the playground to create a single source of truth for their protocol - making onboarding super easy for their developer community.\n\nProtocol Registry: Our protocol registry is an open-source tool that allows you to find different popular protocols and their respective playgrounds.\n\nOn a high level, bonadocs are created to simplify the documentation, interaction, and integration of smart contracts - similar to Postman and web APIs.\n\nTry it out: https://docs.bonadocs.com/\nPlayground demo: https://x.com/thisdavidboy/status/1854809292836339939", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/d334c376-0ff1-4c76-94bf-2ee675cae1d3.png", + "banner_url": "https://storage.googleapis.com/op-atlas/a21ed458-efea-4d35-8aa9-b26d5e7bafad.png", + "twitter": "x.com/bonadocs", + "repos": [ + "https://github.com/bonadocs/protocol-registry", + "https://www.npmjs.com/package/@bonadocs/zimulatoor", + "https://www.npmjs.com/package/@bonadocs/widget", + "https://github.com/bonadocs/docgen", + "https://github.com/bonadocs/docs", + "https://github.com/bonadocs/cli", + "https://github.com/bonadocs/protocol-registry-web", + "https://www.npmjs.com/package/@bonadocs/docgen", + "https://www.npmjs.com/package/@bonadocs/core", + "https://www.npmjs.com/package/@bonadocs/cli" + ], + "tags": [ + "cli", + "frontend", + "education", + "solidity-development" + ], + "website": "bonadocs.com", + "category": "Education & Community Resources" + }, + { + "id": "0x62e37e96aa6e1cbfb6bd24b97c4b8f1e12cc3fe35d5388d2f041c42a12b40745", + "name": "Stargate Finance", + "description": "Stargate is a fully composable liquidity\ntransport protocol that lives at the\nheart of omnichain DeFi.\n\nWith Stargate, users & dApps can transfer native assets cross-chain while accessing\nthe protocol’s unified liquidity pools with instant guaranteed finality. ", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/3083ccee-79a8-4ff2-b017-9ecb52d13cbf.png", + "banner_url": "https://storage.googleapis.com/op-atlas/b29f1ab3-b4cf-4255-839e-e7a418e78b80.png", + "twitter": "https://x.com/StargateFinance", + "repos": [ + "https://github.com/stargate-protocol/stargate" + ], + "tags": [ + "cross-chain", + "defi" + ], + "website": "https://stargate.finance/", + "category": "Cross-Chain & Interoperability" + }, + { + "id": "0xcbfdcf8f724d73504d1518d5ecd7d7256b12d37e68cd84569b383bfb6e2eeea4", + "name": "Dmail Network", + "description": "Stay Informed and Connected with Intelligent and Secure Messaging & Notifications.\n\nDmail Network is an AI-powered decentralized communication infrastructure built to provide encrypted emails, unified notifications, and targeted marketing across multiple chains and dApps for users, developers, marketers and influencers.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/12b2e427-b292-4b27-8896-9053900bfdb4.png", + "banner_url": "https://storage.googleapis.com/op-atlas/3b615f64-5b2e-4092-a10d-f0e311ced954.png", + "twitter": "https://x.com/Dmailofficial", + "repos": [ + "https://github.com/dmailofficial/dmail", + "https://mail.dmail.ai/compose" + ], + "tags": [ + "cross-chain", + "privacy-focused" + ], + "category": "Cross-Chain & Interoperability" + }, + { + "id": "0x0ee3defac0e2a31b995bc073ac02a2140aaf01679e141eb8d1d80409f75f90ea", + "name": "Mint Club", + "description": "Mint Club provides a seamless platform for creating bonding curve-backed tokens or NFTs, using any ERC20 token as the base asset in the bonding curve pool. It facilitates easy tokenization with a completely no-code solution, offering highly customizable bonding curve designs, adjustable creator royalties, a variety of creator tools, and a user-friendly interface for trading bonding curve assets.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/8c7d3ba8-c0bd-4acd-9ec5-7f1c90631047.png", + "banner_url": "https://storage.googleapis.com/op-atlas/9efac275-51f7-48a8-9f13-22c13b05850e.png", + "twitter": "https://x.com/MintClubPro", + "repos": [ + "https://github.com/Steemhunt/mint.club-v2-contract", + "https://www.npmjs.com/package/mint.club-v2-sdk", + "https://github.com/Steemhunt/mint.club-v2-sdk" + ], + "tags": [], + "website": "https://mint.club", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x93decae913f62c0a86519d0b0798e4a10c46c541bfc14dcff0193d6b026e9532", + "name": "LlamaPay", + "description": "Automate & stream salaries by the second", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/30c6400b-b572-4d16-8138-4dc1cba0ef06.png", + "banner_url": "https://storage.googleapis.com/op-atlas/2c2733fd-a572-4f4f-809d-def2e14b8776.png", + "twitter": "https://x.com/llamapay_io", + "repos": [ + "https://github.com/llamasubs/contracts", + "https://github.com/LlamaPay/llamapay" + ], + "tags": [ + "defi", + "gas-efficient" + ], + "website": "https://llamapay.io/", + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "0x66cb156952c9cd26c329a490b1ae9a90167f3067bbea337888b5d70d374959d7", + "name": "ZK Email", + "description": "We let anyone make trustless identity proofs on-chain through intuitive, private email verification. We do this via verifying partially redacted ZK proofs of any sent or received email on chain. We provide audited open source code and SDKs to construct new ZK circuits, infrastructure to use them within front ends, and infrastructure to make proofs on chain.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/27046acd-924a-4f01-ae53-dd51cb6d8238.png", + "banner_url": "https://storage.googleapis.com/op-atlas/7caed237-2d34-4b78-a158-cf118a697d57.png", + "twitter": "@zkemail", + "repos": [ + "https://github.com/zkemail/zk-email-verify", + "https://github.com/zkemail/zk-email-sdk-js", + "https://www.npmjs.com/package/@zk-email/contracts", + "https://github.com/zkemail/email-recovery", + "https://github.com/zkemail/zkemail.nr" + ], + "tags": [ + "frontend", + "modular-accounts", + "sdk", + "privacy-focused", + "user-experience", + "solidity" + ], + "website": "https://zk.email", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x38c38455bb0fd71d2929fcf799279569ab5f5c5d3e1f92f8642ce87aa25accdf", + "name": "Decent.xyz", + "description": "Decent enables cross-chain swaps and 1-click transactions with any token across chains. ", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/1ede3a09-1878-4852-a564-f86f4f49b9fc.png", + "banner_url": "https://storage.googleapis.com/op-atlas/862dacb3-f496-4afe-ae66-70f9f9949937.png", + "twitter": "https://twitter.com/decentxyz", + "repos": [ + "https://www.npmjs.com/package/@decent.xyz/box-common", + "https://www.npmjs.com/package/@decent.xyz/box-hooks", + "https://github.com/decentxyz/launch-nfts", + "https://github.com/decentxyz/decentV2-contracts", + "https://www.npmjs.com/package/@decent.xyz/box-ui", + "https://www.npmjs.com/package/@decent.xyz/the-box", + "https://github.com/decentxyz/decent-contracts-v3" + ], + "tags": [ + "cross-chain", + "nextjs", + "tailwind-css", + "foundry", + "user-experience" + ], + "category": "Cross-Chain & Interoperability" + }, + { + "id": "0xae07bfec2c3c90937679f8c8c5c32e80407c09903aa03d1b5e5a075e67592b86", + "name": "DefiLlama", + "description": "- Open and transparent DeFi analytics.\n- DEX meta-aggregator\n- LlamaZIp, a router optimized for optimistic rollups", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/a9e1e4b4-45a2-411b-8f31-059269534381.png", + "banner_url": "https://storage.googleapis.com/op-atlas/7e0ec4d9-824e-46e3-ad4e-8ffaaa1f105b.png", + "twitter": "https://x.com/defillama", + "repos": [ + "https://github.com/DefiLlama/defillama-app", + "https://github.com/0xngmi/llamazip", + "https://github.com/DefiLlama/DefiLlama-Adapters" + ], + "tags": [ + "analytics", + "defi", + "community-driven", + "dex-aggregator", + "visualization" + ], + "website": "https://defillama.com/", + "category": "Data, Analytics & Tracing" + }, + { + "id": "0x120cdd8e43ae1efbafdf02eda876e1952c05a52870c8d5a8f56d9ec0f79f586d", + "name": "Passport XYZ | Gitcoin Passport", + "description": "Passport is the premier web3 native offering that enables ecosystems to protect, understand and organically grow what matters most – their communities. We see Passport at the confluence of a best in class identity solution, backed by the most relevant and comprehensive data analysis toolset that also offers communities the ability to ascribe reputation. ", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/0160cab5-f34b-4aa5-9442-8b6e82a02bde.png", + "banner_url": "https://storage.googleapis.com/op-atlas/55137132-f859-4640-8d98-4f7c3a8e4489.png", + "twitter": "https://x.com/gitcoinpassport", + "repos": [ + "https://github.com/gitcoinco/passport", + "https://github.com/gitcoinco/eas-proxy", + "https://github.com/passportxyz/passport-scorer", + "https://github.com/passportxyz/passport", + "https://github.com/gitcoinco/id-staking-v2", + "https://github.com/gitcoinco/id-staking-v2-app", + "https://github.com/gitcoinco/passport-scorer" + ], + "tags": [ + "analytics", + "gas-efficient" + ], + "category": "Data, Analytics & Tracing" + }, + { + "id": "0x7539f43dc91f9c406c83a06339708e4033cdbf630916c6dfb9de2b5ef811affd", + "name": "Seamless Protocol", + "description": "Seamless Protocol is the largest native lending and borrowing DeFi platform on Base.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/3ab14d32-3c0e-4262-a17c-9a328dded4bc.png", + "banner_url": "https://storage.googleapis.com/op-atlas/c87cd7ac-5627-4db9-9483-a61e4743d2f0.png", + "twitter": "https://x.com/SeamlessFi", + "repos": [ + "https://github.com/seamless-protocol/governance" + ], + "tags": [ + "defi", + "governance", + "foundry", + "contract-management", + "cli" + ], + "website": "https://seamlessprotocol.com", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xe20f59eb1c8f9cb72e07b8d0f067bac997614fd6db06d8c031c5c9235f760dcc", + "name": "L2Pass", + "description": "Cross-Chain Super-App for effortless Multi-Chain Token Movement, Swaps and Art Performance. Powered by Layer.Zero.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/3f5f2b44-9650-483a-b5cf-1e66163bddae.png", + "banner_url": "https://storage.googleapis.com/op-atlas/41a3c848-54ca-4b30-8fa1-e82a70b18935.png", + "twitter": "https://x.com/L2_Pass", + "repos": [ + "https://github.com/L2PASS/contracts" + ], + "tags": [ + "cross-chain", + "wallet", + "multi-chain" + ], + "website": "https://l2pass.com/", + "category": "Cross-Chain & Interoperability" + }, + { + "id": "0xa88844cea135382e3484e39c3172033437121b35ca0bc8b10b9b8253984876b5", + "name": "Ethereum Attestation Service (EAS)", + "description": "EAS is an infrastructure public good for making attestations onchain or offchain about anything. Attestations are digital signatures on structured pieces of data used to build more trust online and onchain. Over 1M+ attestations have been made in the Superchain from over 14k+ unique attesters.\n\nEAS is natively integrated into OP Bedrock and linked by two predeploy addresses:\nhttps://github.com/ethereum-optimism/optimism/tree/3542398896d9faca6b379fe67e3985d722cf80b6/packages/contracts-bedrock/src/EAS", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/e74ff6ef-578b-4dcb-b155-e663822b2f94.png", + "banner_url": "https://storage.googleapis.com/op-atlas/a447bb2c-d43d-433c-b66c-2506c12858f4.png", + "twitter": "https://twitter.com/eas_eth", + "repos": [ + "https://github.com/ethereum-attestation-service/eas-contracts", + "https://github.com/ethereum-attestation-service/eas-sdk", + "https://www.npmjs.com/package/@ethereum-attestation-service/eas-contracts" + ], + "tags": [ + "governance", + "sdk" + ], + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x8967594d2978692a35fea137ba640bb42f11cad907ca6b0bd01f3718fc4c7f5b", + "name": "Hats Protocol", + "description": "The organizational graph protocol: encode your organization's roles, agents, and permissions into a programmable graph with Hats Protocol", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/cade2fb6-a79c-4974-8b2b-fc4afcd1ec09.png", + "banner_url": "https://storage.googleapis.com/op-atlas/3a110bc1-0ea0-49d5-a38b-5a66b3484852.png", + "twitter": "https://twitter.com/hatsprotocol", + "repos": [ + "https://github.com/Hats-Protocol/hats-account", + "https://github.com/Hats-Protocol/subgraph", + "https://github.com/Hats-Protocol/hat-wearing-eligibility", + "https://github.com/Hats-Protocol/farcaster-delegator", + "https://github.com/Hats-Protocol/hats-account-sdk", + "https://github.com/Hats-Protocol/hats-auth", + "https://github.com/Hats-Protocol/create-hats-app", + "https://github.com/Hats-Protocol/hsg-sdk", + "https://github.com/Hats-Protocol/colinks-eligibility", + "https://github.com/Hats-Protocol/chain-modules", + "https://github.com/Hats-Protocol/allowlist-eligibility", + "https://github.com/Hats-Protocol/agreement-eligibility", + "https://www.npmjs.com/package/@hatsprotocol/sdk-v1-subgraph", + "https://github.com/Hats-Protocol/hats-elections-eligibility", + "https://www.npmjs.com/package/@hatsprotocol/sdk-v1-core", + "https://github.com/Hats-Protocol/season-toggle", + "https://github.com/Hats-Protocol/staking-eligibility", + "https://github.com/hats-protocol/hats-module", + "https://github.com/hats-protocol/hats-protocol", + "https://www.npmjs.com/package/@hatsprotocol/modules-sdk", + "https://www.npmjs.com/package/@hatsprotocol/hsg-sdk", + "https://www.npmjs.com/package/@hatsprotocol/hats-account-sdk", + "https://github.com/Hats-Protocol/subgraph-ancillary", + "https://github.com/Hats-Protocol/hats-governor-votes", + "https://github.com/Hats-Protocol/hats-module-template", + "https://github.com/Hats-Protocol/modules-sdk", + "https://github.com/Hats-Protocol/hats-zodiac", + "https://github.com/Hats-Protocol/jokerace-eligibility", + "https://github.com/Hats-Protocol/multi-claims-hatter", + "https://github.com/Hats-Protocol/passthrough-modules", + "https://github.com/Hats-Protocol/sdk-v1-core" + ], + "tags": [ + "governance", + "decentralized-governance", + "solidity", + "foundry", + "proxy-contracts" + ], + "website": "https://hatsprotocol.xyz", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x24ff0fb2933e55b169a80d9bd35a00a7011795387717b27445ccdc0f8660d740", + "name": "OpenOcean", + "description": "OpenOcean is a leading DEX aggregator with best swap prices across 30+ chains.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/46d3935b-5719-4c9f-ae9b-d7f255f4c120.png", + "banner_url": "https://storage.googleapis.com/op-atlas/5082f8c7-b61a-4ac7-b829-e51fa15fdfc4.png", + "twitter": "https://x.com/OpenOceanGlobal", + "repos": [ + "https://www.npmjs.com/package/@openocean.finance/wallet", + "https://github.com/openocean-finance/OpenOceanExchangeV2", + "https://www.npmjs.com/package/@openocean.finance/openocean-sdk" + ], + "tags": [ + "defi", + "cross-chain", + "dex-aggregator", + "multi-chain" + ], + "website": "https://openocean.finance/", + "category": "Cross-Chain & Interoperability" + }, + { + "id": "0x517eaa9c56951de89261f2d7830ea49aae92f2a903104a17d9c5c2edd4959806", + "name": "LI.FI", + "description": "One API to swap, bridge, and zap across all major blockchains and protocols. Enable trading across all DEX aggregators, bridges, and intent-systems and save hundreds of developer hours.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/4906b988-6024-421e-a706-d01bc508e736.png", + "banner_url": "https://storage.googleapis.com/op-atlas/c280e13b-3e03-47e9-8141-5fad0d51ba2b.png", + "twitter": "https://x.com/lifiprotocol", + "repos": [ + "https://www.npmjs.com/package/@lifi/sdk", + "https://github.com/lifinance/widget", + "https://www.npmjs.com/package/@lifi/widget", + "https://github.com/lifinance/contracts", + "https://github.com/lifinance/sdk" + ], + "tags": [ + "cross-chain", + "api", + "dex-aggregator", + "multi-chain", + "performance-optimization" + ], + "category": "Cross-Chain & Interoperability" + }, + { + "id": "0x4d71401a0dbd9b3dd890fbc70baaf872d16db80af149e20f7ef1805fc94f6df6", + "name": "Router Protocol", + "description": "Router is an cross chain infraproject \nRouter Nitro is a trustless, ultra-low latency bridge built using Router chain’s middleware construct. It transfers user funds across chains in less than 30 seconds, and is more than 20% cheaper than the next cheapest bridge in the market. It currently supports 19 chains:\n", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/582dd2ed-214a-4289-9423-35b64c318cb2.png", + "banner_url": "https://storage.googleapis.com/op-atlas/407396e3-b660-4615-a35d-eae333379d44.png", + "twitter": "https://x.com/routerprotocol", + "repos": [ + "https://github.com/router-protocol/router-contracts", + "https://www.npmjs.com/package/@routerprotocol/asset-bridge", + "https://www.npmjs.com/package/@routerprotocol/asset-forwarder", + "https://www.npmjs.com/package/@routerprotocol/evm-gateway-contracts" + ], + "tags": [ + "cross-chain", + "scalability" + ], + "category": "Cross-Chain & Interoperability" + }, + { + "id": "0x850df51e29f2846a5f085d88e6b6fc13fad51ad7161f8a825ed09d470668161a", + "name": "Party.app + Party Protocol", + "description": "The Party Protocol is an open-source protocol for group coordination. It provides flexible and powerful primitives for creating a shared smart contract account governed by a group of people, big or small.\n\nParty.app is the flagship UI / app built on top. It allows groups to form a small group wallet, and large on-chain DAO, or anything in-between. Party.app has built-in functionality for crowdfunding, governance, using apps via wallet connect, buying & selling NFTs, trading tokens, chatting, and much more.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/ff816d35-de0c-4768-af2c-d2c187dab1c1.png", + "banner_url": "https://storage.googleapis.com/op-atlas/87f46f2a-632b-441c-b762-fe104617d4b6.png", + "twitter": "https://x.com/prtyDAO", + "repos": [ + "https://github.com/PartyDAO/party-protocol" + ], + "tags": [ + "wallet", + "governance" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x08df6e20a3cfabbaf8f34d4f4d048fe7da40447c24be0f3ad513db6f13c755dd", + "name": "Velodrome Finance", + "description": "The central trading & liquidity marketplace on Superchain", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/438ea57d-059c-4327-82e4-abfc94544bad.png", + "banner_url": "https://storage.googleapis.com/op-atlas/2d33616b-bceb-449d-aa0a-b8270b1b3e3b.png", + "twitter": "https://twitter.com/VelodromeFi", + "repos": [ + "https://github.com/velodrome-finance/relay", + "https://github.com/velodrome-finance/universal-router", + "https://github.com/velodrome-finance/sugar-sdk", + "https://github.com/velodrome-finance/sugar", + "https://github.com/velodrome-finance/slipstream", + "https://github.com/velodrome-finance/oracle", + "https://github.com/velodrome-finance/contracts", + "https://github.com/velodrome-finance/superchain-contracts", + "https://github.com/velodrome-finance/superchain-slipstream" + ], + "tags": [ + "defi", + "docker", + "foundry", + "contract-verification" + ], + "website": "https://velodrome.finance", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xb6266f3d955040aa7583f2f346db87abe0649f545389af3cc8fe302aacfc850b", + "name": "Splits", + "description": "Splits builds software for sharing money. We provide secure contracts, intuitive interfaces, and reliable developer tools that make it easy to collaboratively receive and manage money on the internet.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/507b8200-92e0-4914-a43e-97010a0b0583.png", + "banner_url": "https://storage.googleapis.com/op-atlas/bd351554-5050-4584-9f2f-f23ea935508b.png", + "twitter": "https://x.com/0xsplits", + "repos": [ + "https://github.com/0xSplits/splits-contracts-monorepo", + "https://github.com/0xSplits/splits-liquid", + "https://github.com/0xSplits/splits-waterfall", + "https://github.com/0xSplits/splits-vesting", + "https://github.com/0xSplits/splits-utils", + "https://github.com/0xSplits/splits-oracle", + "https://github.com/0xSplits/splits-diversifier", + "https://github.com/0xSplits/splits-contracts", + "https://github.com/0xSplits/splits-swapper", + "https://github.com/0xSplits/splits-sdk", + "https://www.npmjs.com/package/@0xsplits/splits-kit", + "https://www.npmjs.com/package/@0xsplits/splits-sdk-react", + "https://www.npmjs.com/package/@0xsplits/splits-sdk" + ], + "tags": [], + "website": "https://splits.org/", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0xfc54b4a9c537be25238cba3f05100b733aeee83a3eb3fdae60d651b3b913390c", + "name": "Multicaller", + "description": "Multicaller is a suite of hyper-optimized contracts that allows for batched calls, while allowing \"forwarding\" the `msg.sender`.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/8362181e-8e95-40d4-bf8d-234f3edaca4c.png", + "banner_url": "https://storage.googleapis.com/op-atlas/2a702168-545c-42ec-a85f-3149a9227597.png", + "twitter": null, + "repos": [ + "https://www.npmjs.com/package/multicaller", + "https://github.com/Vectorized/multicaller" + ], + "tags": [ + "multicall", + "solidity", + "transaction-optimization", + "contract-interaction", + "foundry", + "hardhat", + "truffle" + ], + "website": "https://github.com/Vectorized/multicaller", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x7a4bb37bc7997b8e9b34775164682ff1f441b716cd235f2e7cdce76677b66007", + "name": "zkCodex", + "description": "zkCodex is a comprehensive blockchain analytics platform that enhances how users engage with and analyze EVM-compatible networks. By combining powerful tracking capabilities with advanced DeFi tools, zkCodex offers an all-in-one solution for blockchain interaction and analysis.\n\n\n#Analytics & Tracking\nMulti-Chain Support: Monitor activities across 35+ networks including Ethereum, Optimism, Base and Ink...\nReal-time Analytics: Track transaction volumes, smart contract interactions, and daily activities\nPerformance Metrics: Analyze wallet performance through comprehensive scoring and detailed metrics\n\n#On-Chain\nGM Streak: Build daily streaks and earn rewards\nContract Deployer: Deploy tokens, NFTs, and contracts\nCounter: Multi-network transaction tool\nDApp Interactions: Engage with blockchain apps seamlessly\n\n\n#Tools & Utilities\nSmart Contract Tools: Deploy and interact with contracts securely\nTransaction Management: Monitor and analyze your transaction history\nEVM Utilities: Access essential tools for blockchain operations", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/89825b92-1ec4-4b91-a8a6-0060c3fe354a.png", + "banner_url": "https://storage.googleapis.com/op-atlas/cc030ee4-0070-4979-b6e6-a733393e6db6.png", + "twitter": "https://x.com/zkcodex", + "repos": [ + "https://github.com/zkcodex/zkCodex" + ], + "tags": [ + "analytics", + "defi", + "cross-chain", + "transaction-management" + ], + "website": "https://zkcodex.com/", + "category": "Data, Analytics & Tracing" + }, + { + "id": "0xf24315614063278ba3543e1717791132a9afa79b0e65baa01a85bcccbdfa215f", + "name": "deBridge", + "description": "deBridge is DeFi's internet of liquidity, enabling real-time movement of assets and information across the DeFi landscape. Without the bottlenecks and risks of liquidity pools, deBridge can power all type of cross-chain interactions with deep liquidity, tight spreads, and guaranteed rates.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/701c36d9-3069-48b6-9aa1-b248378b35b8.png", + "banner_url": "https://storage.googleapis.com/op-atlas/929fbc88-69c7-4a75-be6d-27bf3f2dc8d1.png", + "twitter": "https://x.com/deBridgeFinance", + "repos": [ + "https://www.npmjs.com/package/@debridge-finance/debridge-protocol-evm-interfaces", + "https://www.npmjs.com/package/@debridge-finance/legacy-dln-profitability", + "https://www.npmjs.com/package/@debridge-finance/desdk", + "https://www.npmjs.com/package/@debridge-finance/dln-client", + "https://www.npmjs.com/package/@debridge-finance/dln-taker", + "https://github.com/debridge-finance/hardhat-debridge", + "https://github.com/debridge-finance/dln-taker", + "https://github.com/debridge-finance/debridge-node", + "https://github.com/debridge-finance/dln-contracts", + "https://github.com/debridge-finance/debridge-contracts-v1" + ], + "tags": [ + "cross-chain", + "defi", + "transaction-optimization" + ], + "website": "https://debridge.finance/", + "category": "Cross-Chain & Interoperability" + }, + { + "id": "0x66cce776ce6eaa99192120fc25b91ecc7b98e03210a08f0d3bfda82f542d3e1a", + "name": "OP ENS Gateway by Opti.Domains", + "description": "Opti.Domains has developed an ENS Gateway implementation for OP Stack chains that supports various proofs, including those from L2OutputOracle, Dispute Game, and Anchor State. The appropriate proof is automatically selected based on the configuration of the OP Stack chain.\n\nThe Opti.Domains ENS Gateway automatically upgrades in response to the OP Stack's transition from L2OutputOracle to Dispute Game, requiring no manual intervention or updates to the verifier contract or gateway server.\n\nThe ENS Gateway, specifically the EVMGateway, enables trustless cross-chain data retrieval for ENS names deployed on Layer 2 networks like Optimism with a CCIP Gateway. When an ENS name lookup occurs, the resolver reverts with OffchainLookup containing the gateway URL. The client then contacts the gateway, which returns the requested data. This data is passed to a callback function on the resolver for verification before being returned to the client as the final result of the name lookup.\n\nOur ENS Gateway has a mechanism to ensure liveliness even in the event that the respected dispute game type has suddenly changed, as seen in the recent proposal, 'Upgrade Proposal #10: Granite Network Upgrade,' by storing a backup dispute game type and only trusting its anchor state.\n\nOpti.Domains has also developed social verification and attestation to EAS in collaboration with Bored Town. We are on our way to scaling ENS to OP. We have contributed to the ENS OP Gateway development, which is currently under review by ENS core developers.\n\nThe Namespace team has expressed interest and reached out to us with questions about using our OP ENS Gateway. Additionally, several teams have participated in discussions regarding the development of our OP ENS Gateway.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/8f6ad6e0-029a-4f59-b1d2-c7885248b99a.png", + "banner_url": "https://storage.googleapis.com/op-atlas/135853fe-2393-4a0a-a959-044ff973fcf0.png", + "twitter": "https://x.com/optidomains", + "repos": [ + "https://www.npmjs.com/package/@optidomains/passport-discord", + "https://github.com/Opti-domains/evmgateway", + "https://github.com/Opti-domains/ens-diamond-resolver-v1", + "https://github.com/Opti-domains/dispute-game-lookup", + "https://www.npmjs.com/package/@optidomains/wagmi-core", + "https://github.com/Opti-domains/optidomains-ens-contracts", + "https://github.com/Opti-domains/modular-ens-contracts", + "https://www.npmjs.com/package/@optidomains/wagmi", + "https://www.npmjs.com/package/@optidomains/rainbowkit" + ], + "tags": [ + "cross-chain", + "governance", + "layer-2", + "verification", + "scalability" + ], + "website": "https://opti.domains", + "category": "Cross-Chain & Interoperability" + }, + { + "id": "0xe40733f18903b26f7880bb2fd78c39f3992efe9f8b2e89994c2869eeb3ba4470", + "name": "Chain Abstraction with 4337", + "description": "With this setup, ecosystems can deploy tailor-made 4337 chain abstraction infrastructure. They become Liquidity Providers (LPs) for their users, sharing with them the value that would otherwise have been captured by solvers/fillers. ", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/1d22d6dc-b629-48bc-9c25-2ecc6b9aa1a5.png", + "banner_url": "https://storage.googleapis.com/op-atlas/1d511ff7-cfcf-49f8-876c-b11a324148a3.png", + "twitter": "https://x.com/openfortxyz", + "repos": [ + "https://github.com/openfort-xyz/openfort-contracts", + "https://github.com/openfort-xyz/openfort-chain-abstraction", + "https://www.npmjs.com/package/@openfort/openfort-js", + "https://github.com/openfort-xyz/openfort-js" + ], + "tags": [ + "defi", + "wallet", + "account-abstraction", + "multi-chain", + "analytics", + "user-experience" + ], + "website": "https://openfort.xyz", + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "0xa08c7ab7824d147d6cb87ffb4e86cec454a030d48b8c395bad6d64456be3d911", + "name": "Aragon OSx", + "description": "Aragon was founded in 2016 with the belief that the fate of humanity will be decided at the frontier of technological innovation and human collaboration. Aragon launched the first DAO Framework in 2017 which secures over $40 billion in TVL. Aragon’s tech stack allows anyone to launch a DAO, enabling organizations to securely govern their protocols and assets onchain.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/fe98ffd7-a327-4500-9391-5926dc7a8256.png", + "banner_url": "https://storage.googleapis.com/op-atlas/b9fed2cb-1767-436f-a605-65af61934cf1.png", + "twitter": "https://x.com/AragonProject", + "repos": [ + "https://github.com/aragon/app", + "https://www.npmjs.com/package/@aragon/ods", + "https://github.com/aragon/osx" + ], + "tags": [ + "governance", + "solidity", + "decentralized-governance", + "contract-management" + ], + "website": "https://aragon.org/", + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "0x79e8bf2d699790b563aa57fd34da1722bea3191ab5ff0601ba56020687702ab9", + "name": "Etherspot", + "description": "Etherspot is a multi-chain Account & Chain Abstraction development infrastructure that provides solutions for dApps, wallets, games, operating EVM-compatible rollups, or L1/L2 chains to deliver seamless cross-chain Web3 user experience by removing usability pain points.\n\nIn addition to providing Account and Chain Abstraction features, Etherspot helps developers make their projects compatible with the latest Ethereum standards, including ERC-4337, ERC-7579, and EIP-7702, by offering a wide range of cutting-edge services such as Bundler and Paymaster services, APIs, and more.\n\nEtherspot is pioneering the ERC-4337 shared mempool innovation, which is already live on Optimism.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/b05e1c53-bace-499c-b346-ed9fa0003730.png", + "banner_url": "https://storage.googleapis.com/op-atlas/b33b4fe0-6010-470c-a2db-57636d96536d.png", + "twitter": "https://x.com/etherspot", + "repos": [ + "https://github.com/etherspot/etherspot-prime-contracts", + "https://github.com/etherspot/etherspot-modular-sdk", + "https://www.npmjs.com/package/skandha", + "https://www.npmjs.com/package/@etherspot/prime-sdk", + "https://github.com/etherspot/skandha" + ], + "tags": [ + "cross-chain", + "wallet", + "defi", + "multi-chain", + "account-abstraction", + "sdk", + "user-experience" + ], + "website": "https://etherspot.io/", + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "0x9d93ec97ef2d3bd4c2b8d95abac9ce0cf43e4f3eb1f05709f8282da8200e69ee", + "name": "Frames.js", + "description": "frames.js is the leading open source javascript library and debugging environment to help developers make Frames for Farcaster, XMTP and Lens faster & easier. \n\nWe also have been building and maintaining a library for apps to adopt frames in their apps that has been integrated by the Base team in their Base names product.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/230e8ac2-cea9-4cab-8b4f-8fd58ec6553e.png", + "banner_url": "https://storage.googleapis.com/op-atlas/a2dce749-56d7-44d7-a9cc-ffc08255e0f2.png", + "twitter": null, + "repos": [ + "https://github.com/framesjs/frames.js" + ], + "tags": [ + "frontend", + "farcaster", + "react", + "nextjs" + ], + "website": "https://www.framesjs.org", + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "0x3061b642db56c507e265f03029735b0413a613bda43456a31e78128baeb18754", + "name": "Aave", + "description": "Aave is DeFi's largest lending protocol and one the most used protocols on Optimism.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/dcd0600f-d9bf-439e-9915-5922ea8e9655.png", + "banner_url": "https://storage.googleapis.com/op-atlas/031491b9-252c-4b9d-b450-16f3443184d9.png", + "twitter": null, + "repos": [ + "https://github.com/Aave" + ], + "tags": [ + "defi", + "governance", + "foundry", + "cli", + "contract-deployment" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "manually-added:speedrunethereum", + "name": "SpeedrunEthereum", + "description": "Speedrun Ethereum is a hands-on series of challenges designed to help you learn by building. Each challenge delivers one key \"aha\" moment, a mental unlock about how Ethereum really works. At the same time, you'll be building your Ethereum portfolio.", + "thumbnail_url": null, + "banner_url": null, + "twitter": "https://x.com/buidlguidl", + "repos": [ + "https://github.com/BuidlGuidl/SpeedRunEthereum-v2", + "https://github.com/scaffold-eth/se-2-challenges" + ], + "tags": [ + "education", + "solidity", + "contract-deployment", + "frontend" + ], + "website": "https://speedrunethereum.com/", + "category": "Education & Community Resources" + }, + { + "id": "manually-added:ethpm", + "name": "ethPM", + "description": "ethPM is the immutable package manager to consume, distribute, or manage any EVM smart contract system.", + "website": "https://www.ethpm.com/", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/ethpm/ethpm-cli", + "https://github.com/ethpm/ethpm-spec", + "https://github.com/ethpm/ethpm.js", + "https://github.com/ethpm/py-ethpm" + ], + "tags": [ + "cli", + "solidity", + "contract-management" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "manually-added:governance-onchain-paymaster", + "name": "Governance Onchain Paymaster", + "description": "Paymasters for on-chain Governance", + "website": null, + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/meliopolis/governance-paymaster" + ], + "tags": [ + "account-abstraction", + "developer-experience" + ], + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "manually-added:fealloc", + "name": "FeAlloc", + "description": "Implementing TinyAlloc in Fe-lang for the EVM", + "website": null, + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/saifalkatout/FeAlloc" + ], + "tags": [], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "manually-added:solide", + "name": "solide", + "description": "⚡Lightweight web based Smart Contract IDE", + "website": "https://evm.polearn.xyz/", + "thumbnail_url": null, + "banner_url": null, + "twitter": "https://x.com/0xProofOfLearn", + "repos": [ + "https://github.com/solide-project/solide" + ], + "tags": [ + "solidity", + "developer-experience" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "manually-added:wallet-test-framework", + "name": "Wallet Test Framework", + "description": "Wallet Testing Framework is an automated test suite for Ethereum wallets that validates the core, shared user flows—such as transfers, balance display, and basic interactions—that every wallet must support. By standardizing testing around these fundamentals, it helps wallet teams improve UX quality, reduce duplicated effort, and focus their energy on building differentiated, value-add features without compromising on reliability.", + "website": "https://wallet-test-framework.github.io/framework/", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/wallet-test-framework/framework" + ], + "tags": [ + "testing", + "wallet", + "user-experience", + "developer-experience", + "security" + ], + "category": "Security, Testing & Formal Verification" + }, + { + "id": "manually-added:edb-the-ethereum-project-debugger", + "name": "EDB: The Ethereum Project Debugger", + "description": "EDB is a source-level Ethereum debugger that bridges high-level Solidity code and low-level EVM execution. It enables step-by-step execution, local variable inspection, custom expression evaluation, and precise breakpoints and watchpoints, giving developers fine-grained control and visibility when debugging smart contracts.", + "website": null, + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/edb-rs/edb" + ], + "tags": [ + "solidity", + "debugging-tools", + "developer-experience", + "testing" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "manually-added:txtx", + "name": "txtx", + "description": "Txtx turns the stress, pain and tears of Smart Contract Infrastructure management by introducing Crypto Infrastructure as Code. \nRunbooks are the blueprint for Engineering Excellence, setting the new standard for Web3 Infrastructures.", + "website": "https://www.txtx.sh/", + "thumbnail_url": null, + "banner_url": "https://framerusercontent.com/assets/5mR0In8TgnrDGVmhFuLEHtvz9d8.png", + "twitter": "https://x.com/Reservoir0x", + "repos": [ + "https://github.com/txtx/txtx" + ], + "tags": [ + "devops", + "contract-management", + "contract-deployment", + "developer-experience" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "manually-added:orbitdb", + "name": "OrbitDB", + "description": "Peer-to-Peer Databases for the Decentralized Web", + "website": null, + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/orbitdb/orbitdb" + ], + "tags": [ + "peer-to-peer", + "censorship-resistant" + ], + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "manually-added:ethereum-eips-ontology", + "name": "Ethereum EIPs Ontology", + "description": "An ontology of Ethereum terms extracted from the Ethereum glossaries and Ethereum Improvement Proposals (EIPs). Available in plain text and SKOS formats.", + "website": null, + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/prototypo/ethereum-eips-ontology" + ], + "tags": [], + "category": "Education & Community Resources" + }, + { + "id": "manually-added:ethereum-rb", + "name": "ethereum.rb", + "description": "Ethereum library for the Ruby language", + "website": null, + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/EthWorks/ethereum.rb" + ], + "tags": [ + "sdk" + ], + "category": "Client Libraries & SDKs (Front-End)" + }, + { + "id": "manually-added:hax", + "name": "hax", + "description": "hax is a tool for high assurance translations of a large subset of Rust into formal languages such as F* or Rocq.", + "website": "https://hax.cryspen.com/", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/cryspen/hax" + ], + "tags": [ + "formal-verification" + ], + "category": "Security, Testing & Formal Verification" + }, + { + "id": "manually-added:erc-4337-documentation", + "name": "ERC-4337 Documentation", + "description": "Complete guide to ERC-4337 Account Abstraction - smart accounts, bundlers, paymasters, and more", + "website": "https://docs.erc4337.io/", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/eth-infinitism/aa-mkdocs" + ], + "tags": [ + "account-abstraction", + "education" + ], + "category": "Education & Community Resources" + }, + { + "id": "manually-added:intellij-solidity", + "name": "IntelliJ Solidity", + "description": "Solidity plugin for IntelliJ", + "website": "https://intellij-solidity.dev/", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/intellij-solidity/intellij-solidity" + ], + "tags": [ + "solidity", + "developer-experience", + "code-quality" + ], + "category": "Smart Contract Development & Toolchains" + }, + { + "id": "manually-added:w3pk", + "name": "w3pk", + "description": "Passwordless Web3 authentication SDK with encrypted wallets and privacy features.", + "website": "https://w3pk.w3hc.org/", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [ + "https://github.com/w3hc/w3pk" + ], + "tags": [ + "wallet" + ], + "category": "Transaction & Wallet Infrastructure" + }, + { + "id": "manually-added:solidity-testing-handbook", + "name": "Solidity Testing Handbook", + "description": "Solidity Testing Handbook is a comprehensive guide to testing smart contracts in the Solidity programming language. It covers the basics of testing, the different types of tests, and the tools available for testing.", + "website": "https://solidity-testing-handbook.vercel.app/", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "repos": [], + "tags": [ + "testing", + "education" + ], + "category": "Education & Community Resources" + } +] \ No newline at end of file diff --git a/src/data-layer/tasks.ts b/src/data-layer/tasks.ts index 3acb86f292f..24344aba4dd 100644 --- a/src/data-layer/tasks.ts +++ b/src/data-layer/tasks.ts @@ -13,6 +13,7 @@ import { fetchBeaconChainEthstore } from "./fetchers/fetchBeaconChainEthstore" import { fetchBlobscanStats } from "./fetchers/fetchBlobscanStats" import { fetchCalendarEvents } from "./fetchers/fetchCalendarEvents" import { fetchCommunityPicks } from "./fetchers/fetchCommunityPicks" +import { fetchDeveloperApps } from "./fetchers/fetchDeveloperApps" import { fetchEthereumMarketcap } from "./fetchers/fetchEthereumMarketcap" import { fetchEthereumStablecoinsMcap } from "./fetchers/fetchEthereumStablecoinsMcap" import { fetchEthPrice } from "./fetchers/fetchEthPrice" @@ -35,6 +36,7 @@ export const KEYS = { APPS: "fetch-apps", CALENDAR_EVENTS: "fetch-calendar-events", COMMUNITY_PICKS: "fetch-community-picks", + DEVELOPER_APPS: "fetch-developer-apps", GFIS: "fetch-gfis", GIT_HISTORY: "fetch-git-history", GROW_THE_PIE: "fetch-grow-the-pie", @@ -73,6 +75,7 @@ const DAILY: Task[] = [ [KEYS.RSS, fetchRSS], [KEYS.GITHUB_REPO_DATA, fetchGithubRepoData], [KEYS.EVENTS, fetchEvents], + [KEYS.DEVELOPER_APPS, fetchDeveloperApps], ] const HOURLY: Task[] = [ diff --git a/src/lib/data/index.ts b/src/lib/data/index.ts index ac77febeec2..9520ed3a420 100644 --- a/src/lib/data/index.ts +++ b/src/lib/data/index.ts @@ -148,3 +148,9 @@ export const getEventsData = createCachedGetter( ["events-data"], CACHE_REVALIDATE_DAY ) + +export const getDeveloperAppsData = createCachedGetter( + dataLayer.getDeveloperAppsData, + ["apps-data"], + CACHE_REVALIDATE_DAY +) diff --git a/src/lib/types.ts b/src/lib/types.ts index 20b4c63f2fa..9ccd40f78f1 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -24,6 +24,11 @@ import { Rollup, Rollups } from "@/data/networks/networks" import allQuizData from "@/data/quizzes" import allQuestionData from "@/data/quizzes/questionBank" +import { + DeveloperAppCategory, + DeveloperAppTag, +} from "../../app/[locale]/developers/apps/types" + import { screens } from "./utils/screen" import { WALLETS_FILTERS_DEFAULT } from "./constants" @@ -1338,3 +1343,16 @@ export interface MatomoEventOptions { eventName: string eventValue?: string } + +export type DeveloperAppsResponse = { + id: string + name: string + description: string + thumbnail_url?: string + banner_url?: string + twitter?: string + repos: string[] + tags: DeveloperAppTag[] + website?: string + category: DeveloperAppCategory +} From eb3f80d2d0ed1fea1cf9dd27abd38bb8cad4f98c Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Sun, 18 Jan 2026 21:22:22 -0800 Subject: [PATCH 04/74] feat(i18n): add developer apps page namespace strings --- src/intl/en/page-developers-apps.json | 128 ++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 src/intl/en/page-developers-apps.json diff --git a/src/intl/en/page-developers-apps.json b/src/intl/en/page-developers-apps.json new file mode 100644 index 00000000000..28a385ee7bf --- /dev/null +++ b/src/intl/en/page-developers-apps.json @@ -0,0 +1,128 @@ +{ + "page-developers-app-tag-abi-encoding": "ABI encoding", + "page-developers-app-tag-account-abstraction": "Account abstraction", + "page-developers-app-tag-analytics": "Analytics", + "page-developers-app-tag-api": "API", + "page-developers-app-tag-authentication": "Authentication", + "page-developers-app-tag-block-explorer": "Block explorer", + "page-developers-app-tag-bundler": "Bundler", + "page-developers-app-tag-censorship-resistant": "Censorship resistant", + "page-developers-app-tag-chains": "Chains", + "page-developers-app-tag-cli": "CLI", + "page-developers-app-tag-code-analysis": "Code analysis", + "page-developers-app-tag-code-coverage": "Code coverage", + "page-developers-app-tag-code-quality": "Code quality", + "page-developers-app-tag-community-driven": "Community driven", + "page-developers-app-tag-compiler": "Compiler", + "page-developers-app-tag-continuous-integration": "Continuous integration", + "page-developers-app-tag-contract-deployment": "Contract deployment", + "page-developers-app-tag-contract-interaction": "Contract interaction", + "page-developers-app-tag-contract-management": "Contract management", + "page-developers-app-tag-contract-verification": "Contract verification", + "page-developers-app-tag-cross-chain": "Cross-chain", + "page-developers-app-tag-debugging-tools": "Debugging tools", + "page-developers-app-tag-decentralized-governance": "Decentralized governance", + "page-developers-app-tag-defi": "DeFi", + "page-developers-app-tag-developer-experience": "Developer experience", + "page-developers-app-tag-devops": "DevOps", + "page-developers-app-tag-dex-aggregator": "DEX aggregator", + "page-developers-app-tag-docker": "Docker", + "page-developers-app-tag-education": "Education", + "page-developers-app-tag-encryption": "Encryption", + "page-developers-app-tag-erc721": "ERC-721", + "page-developers-app-tag-event-logging": "Event logging", + "page-developers-app-tag-farcaster": "Farcaster", + "page-developers-app-tag-formal-verification": "Formal verification", + "page-developers-app-tag-foundry": "Foundry", + "page-developers-app-tag-frontend": "Frontend", + "page-developers-app-tag-fuzz-testing": "Fuzz testing", + "page-developers-app-tag-game-development": "Game development", + "page-developers-app-tag-gas-efficient": "Gas efficient", + "page-developers-app-tag-gas-optimization": "Gas optimization", + "page-developers-app-tag-github-actions": "GitHub actions", + "page-developers-app-tag-gossipsub": "GossipSub", + "page-developers-app-tag-governance": "Governance", + "page-developers-app-tag-hardhat": "Hardhat", + "page-developers-app-tag-indexing": "Indexing", + "page-developers-app-tag-interactive-tools": "Interactive tools", + "page-developers-app-tag-json-rpc": "JSON-RPC", + "page-developers-app-tag-layer-2": "Layer 2", + "page-developers-app-tag-libp2p": "libp2p", + "page-developers-app-tag-mcp-server": "MCP server", + "page-developers-app-tag-merkle-trees": "Merkle trees", + "page-developers-app-tag-modular-accounts": "Modular accounts", + "page-developers-app-tag-multi-chain": "Multi-chain", + "page-developers-app-tag-multicall": "Multicall", + "page-developers-app-tag-natural-language-processing": "Natural language processing", + "page-developers-app-tag-networking": "Networking", + "page-developers-app-tag-nextjs": "Next.js", + "page-developers-app-tag-peer-to-peer": "Peer-to-peer", + "page-developers-app-tag-performance-optimization": "Performance optimization", + "page-developers-app-tag-privacy-focused": "Privacy focused", + "page-developers-app-tag-proxy-contracts": "Proxy contracts", + "page-developers-app-tag-react-app": "React app", + "page-developers-app-tag-react": "React", + "page-developers-app-tag-real-time-data": "Real-time data", + "page-developers-app-tag-runtime-verification": "Runtime verification", + "page-developers-app-tag-scalability": "Scalability", + "page-developers-app-tag-sdk": "SDK", + "page-developers-app-tag-security": "Security", + "page-developers-app-tag-solidity-development": "Solidity development", + "page-developers-app-tag-solidity": "Solidity", + "page-developers-app-tag-static-analysis": "Static analysis", + "page-developers-app-tag-storage-layout": "Storage layout", + "page-developers-app-tag-support": "Support", + "page-developers-app-tag-symbolic-execution": "Symbolic execution", + "page-developers-app-tag-tailwind-css": "TailwindCSS", + "page-developers-app-tag-test-automation": "Test automation", + "page-developers-app-tag-testing": "Testing", + "page-developers-app-tag-transaction-decoding": "Transaction decoding", + "page-developers-app-tag-transaction-management": "Transaction management", + "page-developers-app-tag-transaction-optimization": "Transaction optimization", + "page-developers-app-tag-transaction-signing": "Transaction signing", + "page-developers-app-tag-truffle": "Truffle", + "page-developers-app-tag-type-safe": "Type-safe", + "page-developers-app-tag-upgradeable-contracts": "Upgradeable contracts", + "page-developers-app-tag-user-experience": "User experience", + "page-developers-app-tag-verification": "Verification", + "page-developers-app-tag-visualization": "Visualization", + "page-developers-app-tag-vscode-extension": "VSCode extension", + "page-developers-app-tag-vyper": "Vyper", + "page-developers-app-tag-wallet": "Wallet", + "page-developers-apps-applications-title": "Applications", + "page-developers-apps-categories-title": "Application categories", + "page-developers-apps-category-analytics-breadcrumb": "Analytics", + "page-developers-apps-category-analytics-description": "Indexing, querying, analytics, and tracing tools for onchain data, execution, and network activity.", + "page-developers-apps-category-analytics-meta-description": "Ethereum data analytics tools for indexing querying tracing transactions and monitoring onchain activity and execution.", + "page-developers-apps-category-analytics-title": "Data, Analytics & Tracing", + "page-developers-apps-category-contracts-breadcrumb": "Contracts", + "page-developers-apps-category-contracts-description": "Frameworks and tools for writing, testing, deploying, and upgrading smart contracts.", + "page-developers-apps-category-contracts-meta-description": "Ethereum smart contract tools for writing testing deploying and optimizing Solidity and Vyper contracts with modern developer workflows.", + "page-developers-apps-category-contracts-title": "Smart Contract Development & Toolchains", + "page-developers-apps-category-education-breadcrumb": "Education", + "page-developers-apps-category-education-description": "Learning materials, documentation, tutorials, and community platforms for Ethereum developers.", + "page-developers-apps-category-education-meta-description": "Ethereum learning resources including documentation tutorials guides and community tools for developers at all levels.", + "page-developers-apps-category-education-title": "Education & Community Resources", + "page-developers-apps-category-interoperability-breadcrumb": "Interoperability", + "page-developers-apps-category-interoperability-description": "Tools that enable messaging, asset transfers, and shared state across Ethereum mainnet, rollups, and other blockchains.", + "page-developers-apps-category-interoperability-meta-description": "Ethereum cross chain tools for bridges messaging asset transfers rollups and interoperability across blockchain networks.", + "page-developers-apps-category-interoperability-title": "Cross-Chain & Interoperability", + "page-developers-apps-category-sdks-breadcrumb": "SDKs", + "page-developers-apps-category-sdks-description": "Language specific libraries and SDKs for interacting with Ethereum nodes, contracts, and protocols.", + "page-developers-apps-category-sdks-meta-description": "Ethereum client libraries and SDKs for interacting with nodes smart contracts wallets and onchain data across multiple languages.", + "page-developers-apps-category-sdks-title": "Client Libraries & SDKs (Front-End)", + "page-developers-apps-category-security-breadcrumb": "Security", + "page-developers-apps-category-security-description": "Auditing, testing, fuzzing, and verification tools to improve smart contract safety and correctness.", + "page-developers-apps-category-security-meta-description": "Ethereum security tools for smart contract auditing fuzz testing formal verification and improving protocol safety and correctness.", + "page-developers-apps-category-security-title": "Security, Testing & Formal Verification", + "page-developers-apps-category-transactions-breadcrumb": "Transactions", + "page-developers-apps-category-transactions-description": "Infrastructure for building, signing, sending, simulating, and managing Ethereum transactions and wallets.", + "page-developers-apps-category-transactions-meta-description": "Tools for building Ethereum wallets signing sending simulating and managing transactions with secure wallet infrastructure.", + "page-developers-apps-category-transactions-title": "Transaction & Wallet Infrastructure", + "page-developers-apps-highlights": "Highlights", + "page-developers-apps-meta-description": "Discover Ethereum developer tooling including smart contract frameworks SDKs security testing analytics and wallet infrastructure to build and scale Web3 apps.", + "page-developers-apps-meta-title": "Developer tooling", + "page-developers-apps-see-all": "See all", + "page-developers-apps-subtitle": "Find the right tools faster and help elevate the developers who create the infrastructure our ecosystem relies on.", + "page-developers-apps-title": "Developer tooling" +} From 4440b818ae0958a95f630771b52becb503ad1818 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Sun, 18 Jan 2026 21:23:20 -0800 Subject: [PATCH 05/74] feat: add developer apps directory pages Initial scaffolding --- .../developers/apps/[category]/page.tsx | 205 +++++++++++++ app/[locale]/developers/apps/constants.ts | 9 + app/[locale]/developers/apps/page.tsx | 273 ++++++++++++++++++ app/[locale]/developers/apps/types.ts | 105 +++++++ app/[locale]/developers/apps/utils.ts | 22 ++ 5 files changed, 614 insertions(+) create mode 100644 app/[locale]/developers/apps/[category]/page.tsx create mode 100644 app/[locale]/developers/apps/constants.ts create mode 100644 app/[locale]/developers/apps/page.tsx create mode 100644 app/[locale]/developers/apps/types.ts create mode 100644 app/[locale]/developers/apps/utils.ts diff --git a/app/[locale]/developers/apps/[category]/page.tsx b/app/[locale]/developers/apps/[category]/page.tsx new file mode 100644 index 00000000000..d561951dbc0 --- /dev/null +++ b/app/[locale]/developers/apps/[category]/page.tsx @@ -0,0 +1,205 @@ +import { AppWindowMac } from "lucide-react" +import Image from "next/image" +import { getTranslations } from "next-intl/server" + +import { PageParams } from "@/lib/types" + +import { ContentHero } from "@/components/Hero" +import MainArticle from "@/components/MainArticle" +import { CardBanner, CardParagraph, CardTitle } from "@/components/ui/card" +import { Divider } from "@/components/ui/divider" +import { + EdgeScrollContainer, + EdgeScrollItem, +} from "@/components/ui/edge-scroll-container" +import { LinkBox, LinkOverlay } from "@/components/ui/link-box" +import { Section } from "@/components/ui/section" +import { Tag, TagsInlineText } from "@/components/ui/tag" + +import { cn } from "@/lib/utils/cn" +import { getMetadata } from "@/lib/utils/metadata" + +import { fetchDeveloperApps } from "@/data-layer/fetchers/fetchDeveloperApps" + +import { DEV_APP_CATEGORY_SLUGS } from "../constants" +import type { DeveloperAppCategorySlug } from "../types" +import { transformDeveloperAppsData } from "../utils" + +// const Page = async () => { + +const Page = async ({ + params, +}: { + params: PageParams & { category: DeveloperAppCategorySlug } +}) => { + // TODO: Get addId from search params, show modal for app if present + const { category } = params + const t = await getTranslations({ namespace: "page-developers-apps" }) + const tCommon = await getTranslations({ namespace: "common" }) + + // const [appsData] = await Promise.all([getDeveloperAppsData()]) // TODO: Await all, add GitHub API fetches + // const appsData = await getDeveloperAppsData() // TODO: data-layer + const appsData = await fetchDeveloperApps() // TODO: Trim mock data + if (!appsData) throw Error("No developer apps data available") + const data = transformDeveloperAppsData(appsData) + + const featuredNames = ["ZK Email", "Hardhat", "Updraft"] // TODO: determine logic, make DRY + const highlights = appsData.filter(({ name }) => featuredNames.includes(name)) + + return ( + <> + + + {/* Featured developer tools */} +
+

{t("page-developers-apps-highlights")}

+ + {highlights.map((app) => ( + + + +
+ + + + + {app.description} + +
+
+ + {tCommon("item-logo", + + +
+ + {app.category} + + {app.name} + + t(`page-developers-app-tag-${tag}`) + )} + max={3} // TODO: Confirm / sort? + variant="light" + className="lowercase" + /> +
+
+
+
+
+ ))} +
+
+ +
+

+ {t("page-developers-apps-applications-title")} +

+ + {/* // TODO: "Filter by / showing (n)" bar, replace Divider */} + + +
+ {data[category].map((app) => ( + + +
+ {app.thumbnail_url ? ( + + ) : ( + + )} +
+
+

{app.name}

+ + t(`page-developers-app-tag-${tag}`) + )} + variant="light" + className="lowercase" + /> +
+
+
+ ))} +
+
+
+ + ) +} + +export async function generateStaticParams() { + return Object.values(DEV_APP_CATEGORY_SLUGS) +} + +export async function generateMetadata({ + params, +}: { + params: { locale: string; category: string } +}) { + const { locale, category } = params + const t = await getTranslations({ locale, namespace: "page-developers-apps" }) + + return await getMetadata({ + locale, + slug: ["developers", "apps", category], + title: t(`page-developers-apps-category-${category}-title`), + description: t( + `page-developers-apps-category-${category}-meta-description` + ), + }) +} + +export default Page diff --git a/app/[locale]/developers/apps/constants.ts b/app/[locale]/developers/apps/constants.ts new file mode 100644 index 00000000000..2e92f06d610 --- /dev/null +++ b/app/[locale]/developers/apps/constants.ts @@ -0,0 +1,9 @@ +export const DEV_APP_CATEGORY_SLUGS = { + "Cross-Chain & Interoperability": "interoperability", + "Transaction & Wallet Infrastructure": "transactions", + "Data, Analytics & Tracing": "analytics", + "Education & Community Resources": "education", + "Client Libraries & SDKs (Front-End)": "sdks", + "Smart Contract Development & Toolchains": "contracts", + "Security, Testing & Formal Verification": "security", +} as const diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/apps/page.tsx new file mode 100644 index 00000000000..ecc7cb4b5b2 --- /dev/null +++ b/app/[locale]/developers/apps/page.tsx @@ -0,0 +1,273 @@ +import { + AppWindowMac, + ArrowLeftRight, + ChartSpline, + CodeXml, + GraduationCap, + LucideIcon, + Package, + SendToBack, + Shield, +} from "lucide-react" +import Image from "next/image" +import { getTranslations } from "next-intl/server" + +import { ContentHero } from "@/components/Hero" +import MainArticle from "@/components/MainArticle" +import SubpageCard from "@/components/SubpageCard" +import { Button } from "@/components/ui/buttons/Button" +import { + Card, + CardBanner, + CardParagraph, + CardTitle, +} from "@/components/ui/card" +import { + EdgeScrollContainer, + EdgeScrollItem, +} from "@/components/ui/edge-scroll-container" +import { LinkBox, LinkOverlay } from "@/components/ui/link-box" +import { Section } from "@/components/ui/section" +import { Tag, TagsInlineText } from "@/components/ui/tag" + +import { cn } from "@/lib/utils/cn" +import { getMetadata } from "@/lib/utils/metadata" + +import { fetchDeveloperApps } from "@/data-layer/fetchers/fetchDeveloperApps" + +import type { DeveloperAppCategorySlug } from "./types" +import { transformDeveloperAppsData } from "./utils" + +const Page = async () => { + // TODO: Get addId from search params, show modal for app if present + // const Page = async ({ params }: { params: PageParams }) => { + // const { locale } = params + const t = await getTranslations({ namespace: "page-developers-apps" }) + const tCommon = await getTranslations({ namespace: "common" }) + + // const [appsData] = await Promise.all([getDeveloperAppsData()]) // TODO: Await all, add GitHub API fetches + // const appsData = await getDeveloperAppsData() // TODO: data-layer + const appsData = await fetchDeveloperApps() // TODO: Trim mock data + if (!appsData) throw Error("No developer apps data available") + const data = transformDeveloperAppsData(appsData) + + const featuredNames = ["ZK Email", "Hardhat", "Updraft"] // TODO: determine logic, make DRY + const highlights = appsData.filter(({ name }) => featuredNames.includes(name)) + + const categories: { slug: DeveloperAppCategorySlug; Icon: LucideIcon }[] = [ + { slug: "interoperability", Icon: SendToBack }, + { slug: "transactions", Icon: ArrowLeftRight }, + { slug: "analytics", Icon: ChartSpline }, + { slug: "education", Icon: GraduationCap }, + { slug: "sdks", Icon: Package }, + { slug: "contracts", Icon: CodeXml }, + { slug: "security", Icon: Shield }, + ] + + return ( + <> + + + {/* Featured developer tools */} +
+

{t("page-developers-apps-highlights")}

+ + {highlights.map((app) => ( + + + +
+ + + + + {app.description} + +
+
+ + {tCommon("item-logo", + + +
+ + {app.category} + + {app.name} + + t(`page-developers-app-tag-${tag}`) + )} + max={3} // TODO: Confirm / sort? + variant="light" + className="lowercase" + /> +
+
+
+
+
+ ))} +
+
+ +
+

{t("page-developers-apps-applications-title")}

+ + {categories.map(({ slug, Icon }) => ( + + {/* // TODO: */} + + + +
+
+ +
+

+ {t(`page-developers-apps-category-${slug}-title`)} +

+ +
+
+
+ + {data[slug].slice(0, 5).map((app) => ( + + +
+ {app.thumbnail_url ? ( + + ) : ( + + )} +
+
+

{app.name}

+ + t(`page-developers-app-tag-${tag}`) + )} + variant="light" + className="lowercase" + /> +
+
+
+ ))} +
+
+ ))} +
+
+ +
+

{t("page-developers-apps-categories-title")}

+
+ {categories.map(({ slug, Icon }) => ( + } + href={`/developers/apps/${slug}`} + matomoEvent={{ + // TODO: Confirm all + eventCategory: "developer-apps", + eventAction: "categories", + eventName: `category name ${slug}`, + }} + /> + ))} +
+
+
+ + ) +} + +export async function generateMetadata({ + params, +}: { + params: { locale: string } +}) { + const { locale } = params + const t = await getTranslations({ locale, namespace: "page-developers-apps" }) + + return await getMetadata({ + locale, + slug: ["developers", "apps"], + title: t("page-developers-apps-meta-title"), + description: t("page-developers-apps-meta-description"), + }) +} + +export default Page diff --git a/app/[locale]/developers/apps/types.ts b/app/[locale]/developers/apps/types.ts new file mode 100644 index 00000000000..258334d8070 --- /dev/null +++ b/app/[locale]/developers/apps/types.ts @@ -0,0 +1,105 @@ +import { DeveloperAppsResponse } from "@/lib/types" + +import { DEV_APP_CATEGORY_SLUGS } from "./constants" + +export type DeveloperAppTag = + | "abi-encoding" + | "account-abstraction" + | "analytics" + | "api" + | "authentication" + | "block-explorer" + | "bundler" + | "censorship-resistant" + | "chains" + | "cli" + | "code-analysis" + | "code-coverage" + | "code-quality" + | "community-driven" + | "compiler" + | "continuous-integration" + | "contract-deployment" + | "contract-interaction" + | "contract-management" + | "contract-verification" + | "cross-chain" + | "debugging-tools" + | "decentralized-governance" + | "defi" + | "developer-experience" + | "devops" + | "dex-aggregator" + | "docker" + | "education" + | "encryption" + | "erc721" + | "event-logging" + | "farcaster" + | "formal-verification" + | "foundry" + | "frontend" + | "fuzz-testing" + | "game-development" + | "gas-efficient" + | "gas-optimization" + | "github-actions" + | "gossipsub" + | "governance" + | "hardhat" + | "indexing" + | "interactive-tools" + | "json-rpc" + | "layer-2" + | "libp2p" + | "mcp-server" + | "merkle-trees" + | "modular-accounts" + | "multi-chain" + | "multicall" + | "natural-language-processing" + | "networking" + | "nextjs" + | "peer-to-peer" + | "performance-optimization" + | "privacy-focused" + | "proxy-contracts" + | "react" + | "react-app" + | "real-time-data" + | "runtime-verification" + | "scalability" + | "sdk" + | "security" + | "solidity" + | "solidity-development" + | "static-analysis" + | "storage-layout" + | "support" + | "symbolic-execution" + | "tailwind-css" + | "test-automation" + | "testing" + | "transaction-decoding" + | "transaction-management" + | "transaction-optimization" + | "transaction-signing" + | "truffle" + | "type-safe" + | "upgradeable-contracts" + | "user-experience" + | "verification" + | "visualization" + | "vscode-extension" + | "vyper" + | "wallet" + +export type DeveloperAppCategory = keyof typeof DEV_APP_CATEGORY_SLUGS + +export type DeveloperAppCategorySlug = + (typeof DEV_APP_CATEGORY_SLUGS)[DeveloperAppCategory] + +export type DeveloperAppsByCategory = Record< + DeveloperAppCategorySlug, + Omit[] +> diff --git a/app/[locale]/developers/apps/utils.ts b/app/[locale]/developers/apps/utils.ts new file mode 100644 index 00000000000..da1705491e6 --- /dev/null +++ b/app/[locale]/developers/apps/utils.ts @@ -0,0 +1,22 @@ +import type { DeveloperAppsResponse } from "@/lib/types" + +import { DEV_APP_CATEGORY_SLUGS } from "./constants" +import type { DeveloperAppsByCategory } from "./types" + +export const transformDeveloperAppsData = ( + data: DeveloperAppsResponse[] +): DeveloperAppsByCategory => { + const initialAcc = Object.values(DEV_APP_CATEGORY_SLUGS).reduce( + (acc, slug) => { + acc[slug] = [] + return acc + }, + {} as DeveloperAppsByCategory + ) + + return data.reduce((acc, { category, ...item }) => { + const slug = DEV_APP_CATEGORY_SLUGS[category] + acc[slug].push(item) + return acc + }, initialAcc) +} From 538ee79f28db5eef87d85ee54eb6d6445ee6e55f Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Sun, 18 Jan 2026 22:52:05 -0800 Subject: [PATCH 06/74] fix: page params, set request locale --- app/[locale]/developers/apps/[category]/page.tsx | 14 +++++++------- app/[locale]/developers/apps/page.tsx | 12 +++++++----- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/app/[locale]/developers/apps/[category]/page.tsx b/app/[locale]/developers/apps/[category]/page.tsx index d561951dbc0..75a34694bfa 100644 --- a/app/[locale]/developers/apps/[category]/page.tsx +++ b/app/[locale]/developers/apps/[category]/page.tsx @@ -1,6 +1,6 @@ import { AppWindowMac } from "lucide-react" import Image from "next/image" -import { getTranslations } from "next-intl/server" +import { getTranslations, setRequestLocale } from "next-intl/server" import { PageParams } from "@/lib/types" @@ -25,17 +25,16 @@ import { DEV_APP_CATEGORY_SLUGS } from "../constants" import type { DeveloperAppCategorySlug } from "../types" import { transformDeveloperAppsData } from "../utils" -// const Page = async () => { - const Page = async ({ params, }: { params: PageParams & { category: DeveloperAppCategorySlug } }) => { // TODO: Get addId from search params, show modal for app if present - const { category } = params - const t = await getTranslations({ namespace: "page-developers-apps" }) - const tCommon = await getTranslations({ namespace: "common" }) + const { locale, category } = params + setRequestLocale(locale) + const t = await getTranslations({ locale, namespace: "page-developers-apps" }) + const tCommon = await getTranslations({ locale, namespace: "common" }) // const [appsData] = await Promise.all([getDeveloperAppsData()]) // TODO: Await all, add GitHub API fetches // const appsData = await getDeveloperAppsData() // TODO: data-layer @@ -181,7 +180,8 @@ const Page = async ({ } export async function generateStaticParams() { - return Object.values(DEV_APP_CATEGORY_SLUGS) + const slugs = Object.values(DEV_APP_CATEGORY_SLUGS) + return slugs.map((category) => ({ category })) } export async function generateMetadata({ diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/apps/page.tsx index ecc7cb4b5b2..d653e28d2d1 100644 --- a/app/[locale]/developers/apps/page.tsx +++ b/app/[locale]/developers/apps/page.tsx @@ -10,7 +10,9 @@ import { Shield, } from "lucide-react" import Image from "next/image" -import { getTranslations } from "next-intl/server" +import { getTranslations, setRequestLocale } from "next-intl/server" + +import { type PageParams } from "@/lib/types" import { ContentHero } from "@/components/Hero" import MainArticle from "@/components/MainArticle" @@ -38,10 +40,11 @@ import { fetchDeveloperApps } from "@/data-layer/fetchers/fetchDeveloperApps" import type { DeveloperAppCategorySlug } from "./types" import { transformDeveloperAppsData } from "./utils" -const Page = async () => { +const Page = async ({ params }: { params: PageParams }) => { // TODO: Get addId from search params, show modal for app if present - // const Page = async ({ params }: { params: PageParams }) => { - // const { locale } = params + const { locale } = params + setRequestLocale(locale) + const t = await getTranslations({ namespace: "page-developers-apps" }) const tCommon = await getTranslations({ namespace: "common" }) @@ -72,7 +75,6 @@ const Page = async () => { description={t("page-developers-apps-subtitle")} /> - {/* Featured developer tools */}

{t("page-developers-apps-highlights")}

From 36c33fc3a52eca0b663e9ee99cc17672e031e25f Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Sun, 18 Jan 2026 22:53:05 -0800 Subject: [PATCH 07/74] feat(data): add fetch repos stargazers/lastupdated GitHub GraphQL API for batch fetch --- app/[locale]/developers/apps/page.tsx | 5 +- app/[locale]/developers/apps/types.ts | 8 +- app/[locale]/developers/apps/utils.ts | 4 +- .../fetchers/fetchDeveloperAppsStargazers.ts | 151 ++++++++++++++++++ 4 files changed, 163 insertions(+), 5 deletions(-) create mode 100644 src/data-layer/fetchers/fetchDeveloperAppsStargazers.ts diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/apps/page.tsx index d653e28d2d1..b0b4d389970 100644 --- a/app/[locale]/developers/apps/page.tsx +++ b/app/[locale]/developers/apps/page.tsx @@ -36,6 +36,7 @@ import { cn } from "@/lib/utils/cn" import { getMetadata } from "@/lib/utils/metadata" import { fetchDeveloperApps } from "@/data-layer/fetchers/fetchDeveloperApps" +import { fetchDeveloperAppsStargazers } from "@/data-layer/fetchers/fetchDeveloperAppsStargazers" import type { DeveloperAppCategorySlug } from "./types" import { transformDeveloperAppsData } from "./utils" @@ -48,11 +49,11 @@ const Page = async ({ params }: { params: PageParams }) => { const t = await getTranslations({ namespace: "page-developers-apps" }) const tCommon = await getTranslations({ namespace: "common" }) - // const [appsData] = await Promise.all([getDeveloperAppsData()]) // TODO: Await all, add GitHub API fetches // const appsData = await getDeveloperAppsData() // TODO: data-layer const appsData = await fetchDeveloperApps() // TODO: Trim mock data if (!appsData) throw Error("No developer apps data available") - const data = transformDeveloperAppsData(appsData) + const _data = transformDeveloperAppsData(appsData) + const data = await fetchDeveloperAppsStargazers(_data) const featuredNames = ["ZK Email", "Hardhat", "Updraft"] // TODO: determine logic, make DRY const highlights = appsData.filter(({ name }) => featuredNames.includes(name)) diff --git a/app/[locale]/developers/apps/types.ts b/app/[locale]/developers/apps/types.ts index 258334d8070..248e7cc37fc 100644 --- a/app/[locale]/developers/apps/types.ts +++ b/app/[locale]/developers/apps/types.ts @@ -101,5 +101,11 @@ export type DeveloperAppCategorySlug = export type DeveloperAppsByCategory = Record< DeveloperAppCategorySlug, - Omit[] + (Omit & { + repos: { + href: string + stargazers?: number + lastUpdated?: string | number | Date | null + }[] + })[] > diff --git a/app/[locale]/developers/apps/utils.ts b/app/[locale]/developers/apps/utils.ts index da1705491e6..421fc02f66a 100644 --- a/app/[locale]/developers/apps/utils.ts +++ b/app/[locale]/developers/apps/utils.ts @@ -14,9 +14,9 @@ export const transformDeveloperAppsData = ( {} as DeveloperAppsByCategory ) - return data.reduce((acc, { category, ...item }) => { + return data.reduce((acc, { category, repos, ...item }) => { const slug = DEV_APP_CATEGORY_SLUGS[category] - acc[slug].push(item) + acc[slug].push({ ...item, repos: repos.map((repo) => ({ href: repo })) }) return acc }, initialAcc) } diff --git a/src/data-layer/fetchers/fetchDeveloperAppsStargazers.ts b/src/data-layer/fetchers/fetchDeveloperAppsStargazers.ts new file mode 100644 index 00000000000..e175ea0ef97 --- /dev/null +++ b/src/data-layer/fetchers/fetchDeveloperAppsStargazers.ts @@ -0,0 +1,151 @@ +// TODO: Set up data-layer integration +import { DeveloperAppsByCategory } from "../../../app/[locale]/developers/apps/types" + +type RepoInfo = { + owner: string + name: string + originalHref: string +} + +type GraphQLRepoResult = { + stargazerCount: number + lastCommitDate: string | null // ISO date string - last commit on default branch +} + +function parseGitHubUrl(href: string): RepoInfo | null { + try { + const url = new URL(href) + if (url.hostname !== "github.com") return null + + const [, owner, name] = url.pathname.split("/") + if (!owner || !name) return null + + return { owner, name: name.replace(/\.git$/, ""), originalHref: href } + } catch { + return null + } +} + +function buildGraphQLQuery(repos: RepoInfo[]): string { + const repoQueries = repos + .map( + (repo, i) => ` + repo${i}: repository(owner: "${repo.owner}", name: "${repo.name}") { + stargazerCount + defaultBranchRef { + target { + ... on Commit { + committedDate + } + } + } + } + ` + ) + .join("") + + return `query { ${repoQueries} }` +} + +async function fetchReposBatch( + repos: RepoInfo[] +): Promise> { + const results = new Map() + + if (repos.length === 0) return results + + const query = buildGraphQLQuery(repos) + + const response = await fetch("https://api.github.com/graphql", { + method: "POST", + headers: { + Authorization: `Bearer ${process.env.GITHUB_TOKEN_READ_ONLY}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ query }), + }) + + if (!response.ok) { + console.warn(`GitHub GraphQL request failed with status ${response.status}`) + return results + } + + const json = await response.json() + + if (json.errors) { + console.warn("GitHub GraphQL errors:", json.errors) + } + + // Map results back to original hrefs + repos.forEach((repo, i) => { + const data = json.data?.[`repo${i}`] + if (data) { + results.set(repo.originalHref, { + stargazerCount: data.stargazerCount, + lastCommitDate: data.defaultBranchRef?.target?.committedDate ?? null, + }) + } + }) + + return results +} + +export async function fetchDeveloperAppsStargazers( + appData: DeveloperAppsByCategory +): Promise { + // Collect all unique repo URLs across all categories + const allRepos: RepoInfo[] = [] + const seenHrefs = new Set() + + for (const apps of Object.values(appData)) { + for (const app of apps) { + for (const repo of app.repos) { + if (seenHrefs.has(repo.href)) continue + seenHrefs.add(repo.href) + + const parsed = parseGitHubUrl(repo.href) + if (parsed) { + allRepos.push(parsed) + } + } + } + } + + console.log(`Fetching stargazers for ${allRepos.length} GitHub repos`) + + // GitHub GraphQL has a complexity limit; batch in chunks of ~100 + const BATCH_SIZE = 100 + const repoDataMap = new Map() + + for (let i = 0; i < allRepos.length; i += BATCH_SIZE) { + const batch = allRepos.slice(i, i + BATCH_SIZE) + const batchResults = await fetchReposBatch(batch) + + for (const [href, data] of batchResults) { + repoDataMap.set(href, data) + } + } + + console.log(`Successfully fetched data for ${repoDataMap.size} repos`) + + // Enrich the app data with stargazer counts and last updated dates + const enrichedData: DeveloperAppsByCategory = {} as DeveloperAppsByCategory + + for (const [category, apps] of Object.entries(appData)) { + enrichedData[category as keyof DeveloperAppsByCategory] = apps.map( + (app) => ({ + ...app, + repos: app.repos.map((repo) => { + const data = repoDataMap.get(repo.href) + return { + ...repo, + stargazers: data?.stargazerCount, + lastUpdated: data?.lastCommitDate, + } + }), + }) + ) + } + + return enrichedData +} From b8dd32394465aa67d3dc9b01d1c7e671bab40485 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Mon, 19 Jan 2026 10:37:40 -0800 Subject: [PATCH 08/74] patch: string capitalization --- src/intl/en/page-developers-apps.json | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/intl/en/page-developers-apps.json b/src/intl/en/page-developers-apps.json index 28a385ee7bf..1fdfc95fb5d 100644 --- a/src/intl/en/page-developers-apps.json +++ b/src/intl/en/page-developers-apps.json @@ -91,36 +91,37 @@ "page-developers-app-tag-wallet": "Wallet", "page-developers-apps-applications-title": "Applications", "page-developers-apps-categories-title": "Application categories", + "page-developers-apps-categories-title-other": "Other application categories", "page-developers-apps-category-analytics-breadcrumb": "Analytics", "page-developers-apps-category-analytics-description": "Indexing, querying, analytics, and tracing tools for onchain data, execution, and network activity.", "page-developers-apps-category-analytics-meta-description": "Ethereum data analytics tools for indexing querying tracing transactions and monitoring onchain activity and execution.", - "page-developers-apps-category-analytics-title": "Data, Analytics & Tracing", + "page-developers-apps-category-analytics-title": "Data, analytics & tracing", "page-developers-apps-category-contracts-breadcrumb": "Contracts", "page-developers-apps-category-contracts-description": "Frameworks and tools for writing, testing, deploying, and upgrading smart contracts.", "page-developers-apps-category-contracts-meta-description": "Ethereum smart contract tools for writing testing deploying and optimizing Solidity and Vyper contracts with modern developer workflows.", - "page-developers-apps-category-contracts-title": "Smart Contract Development & Toolchains", + "page-developers-apps-category-contracts-title": "Smart contract development & toolchains", "page-developers-apps-category-education-breadcrumb": "Education", "page-developers-apps-category-education-description": "Learning materials, documentation, tutorials, and community platforms for Ethereum developers.", "page-developers-apps-category-education-meta-description": "Ethereum learning resources including documentation tutorials guides and community tools for developers at all levels.", - "page-developers-apps-category-education-title": "Education & Community Resources", + "page-developers-apps-category-education-title": "Education & community resources", "page-developers-apps-category-interoperability-breadcrumb": "Interoperability", "page-developers-apps-category-interoperability-description": "Tools that enable messaging, asset transfers, and shared state across Ethereum mainnet, rollups, and other blockchains.", "page-developers-apps-category-interoperability-meta-description": "Ethereum cross chain tools for bridges messaging asset transfers rollups and interoperability across blockchain networks.", - "page-developers-apps-category-interoperability-title": "Cross-Chain & Interoperability", + "page-developers-apps-category-interoperability-title": "Cross-chain & interoperability", "page-developers-apps-category-sdks-breadcrumb": "SDKs", "page-developers-apps-category-sdks-description": "Language specific libraries and SDKs for interacting with Ethereum nodes, contracts, and protocols.", "page-developers-apps-category-sdks-meta-description": "Ethereum client libraries and SDKs for interacting with nodes smart contracts wallets and onchain data across multiple languages.", - "page-developers-apps-category-sdks-title": "Client Libraries & SDKs (Front-End)", + "page-developers-apps-category-sdks-title": "Client libraries & SDKs (front-end)", "page-developers-apps-category-security-breadcrumb": "Security", "page-developers-apps-category-security-description": "Auditing, testing, fuzzing, and verification tools to improve smart contract safety and correctness.", "page-developers-apps-category-security-meta-description": "Ethereum security tools for smart contract auditing fuzz testing formal verification and improving protocol safety and correctness.", - "page-developers-apps-category-security-title": "Security, Testing & Formal Verification", + "page-developers-apps-category-security-title": "Security, testing & formal verification", "page-developers-apps-category-transactions-breadcrumb": "Transactions", "page-developers-apps-category-transactions-description": "Infrastructure for building, signing, sending, simulating, and managing Ethereum transactions and wallets.", "page-developers-apps-category-transactions-meta-description": "Tools for building Ethereum wallets signing sending simulating and managing transactions with secure wallet infrastructure.", - "page-developers-apps-category-transactions-title": "Transaction & Wallet Infrastructure", + "page-developers-apps-category-transactions-title": "Transaction & wallet infrastructure", "page-developers-apps-highlights": "Highlights", - "page-developers-apps-meta-description": "Discover Ethereum developer tooling including smart contract frameworks SDKs security testing analytics and wallet infrastructure to build and scale Web3 apps.", + "page-developers-apps-meta-description": "Discover Ethereum developer tooling including smart contract frameworks SDKs security testing analytics and wallet infrastructure to build and scale web3 apps.", "page-developers-apps-meta-title": "Developer tooling", "page-developers-apps-see-all": "See all", "page-developers-apps-subtitle": "Find the right tools faster and help elevate the developers who create the infrastructure our ecosystem relies on.", From c4e9fe9911f7c989dba143f85e180cb23bffc298 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Mon, 19 Jan 2026 10:38:26 -0800 Subject: [PATCH 09/74] feat: add other categories section refactor CATEGORIES as shared constant --- .../developers/apps/[category]/page.tsx | 28 ++++++++++++++++++- app/[locale]/developers/apps/constants.ts | 26 +++++++++++++++++ app/[locale]/developers/apps/page.tsx | 28 +++---------------- 3 files changed, 57 insertions(+), 25 deletions(-) diff --git a/app/[locale]/developers/apps/[category]/page.tsx b/app/[locale]/developers/apps/[category]/page.tsx index 75a34694bfa..df1fd06835d 100644 --- a/app/[locale]/developers/apps/[category]/page.tsx +++ b/app/[locale]/developers/apps/[category]/page.tsx @@ -6,6 +6,7 @@ import { PageParams } from "@/lib/types" import { ContentHero } from "@/components/Hero" import MainArticle from "@/components/MainArticle" +import SubpageCard from "@/components/SubpageCard" import { CardBanner, CardParagraph, CardTitle } from "@/components/ui/card" import { Divider } from "@/components/ui/divider" import { @@ -21,7 +22,7 @@ import { getMetadata } from "@/lib/utils/metadata" import { fetchDeveloperApps } from "@/data-layer/fetchers/fetchDeveloperApps" -import { DEV_APP_CATEGORY_SLUGS } from "../constants" +import { CATEGORIES, DEV_APP_CATEGORY_SLUGS } from "../constants" import type { DeveloperAppCategorySlug } from "../types" import { transformDeveloperAppsData } from "../utils" @@ -174,6 +175,31 @@ const Page = async ({ ))}
+ +
+

{t("page-developers-apps-categories-title-other")}

+
+ {CATEGORIES.filter(({ slug }) => slug !== category).map( + ({ slug, Icon }) => ( + } + href={`/developers/apps/${slug}`} + matomoEvent={{ + // TODO: Confirm all + eventCategory: "developer-apps", + eventAction: "categories", + eventName: `category name ${slug}`, + }} + /> + ) + )} +
+
) diff --git a/app/[locale]/developers/apps/constants.ts b/app/[locale]/developers/apps/constants.ts index 2e92f06d610..515506429e1 100644 --- a/app/[locale]/developers/apps/constants.ts +++ b/app/[locale]/developers/apps/constants.ts @@ -1,3 +1,16 @@ +import { + ArrowLeftRight, + ChartSpline, + CodeXml, + GraduationCap, + LucideIcon, + Package, + SendToBack, + Shield, +} from "lucide-react" + +import type { DeveloperAppCategorySlug } from "./types" + export const DEV_APP_CATEGORY_SLUGS = { "Cross-Chain & Interoperability": "interoperability", "Transaction & Wallet Infrastructure": "transactions", @@ -7,3 +20,16 @@ export const DEV_APP_CATEGORY_SLUGS = { "Smart Contract Development & Toolchains": "contracts", "Security, Testing & Formal Verification": "security", } as const + +export const CATEGORIES: { + slug: DeveloperAppCategorySlug + Icon: LucideIcon +}[] = [ + { slug: "interoperability", Icon: SendToBack }, + { slug: "transactions", Icon: ArrowLeftRight }, + { slug: "analytics", Icon: ChartSpline }, + { slug: "education", Icon: GraduationCap }, + { slug: "sdks", Icon: Package }, + { slug: "contracts", Icon: CodeXml }, + { slug: "security", Icon: Shield }, +] diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/apps/page.tsx index b0b4d389970..1c3922bdf0f 100644 --- a/app/[locale]/developers/apps/page.tsx +++ b/app/[locale]/developers/apps/page.tsx @@ -1,14 +1,4 @@ -import { - AppWindowMac, - ArrowLeftRight, - ChartSpline, - CodeXml, - GraduationCap, - LucideIcon, - Package, - SendToBack, - Shield, -} from "lucide-react" +import { AppWindowMac } from "lucide-react" import Image from "next/image" import { getTranslations, setRequestLocale } from "next-intl/server" @@ -38,7 +28,7 @@ import { getMetadata } from "@/lib/utils/metadata" import { fetchDeveloperApps } from "@/data-layer/fetchers/fetchDeveloperApps" import { fetchDeveloperAppsStargazers } from "@/data-layer/fetchers/fetchDeveloperAppsStargazers" -import type { DeveloperAppCategorySlug } from "./types" +import { CATEGORIES } from "./constants" import { transformDeveloperAppsData } from "./utils" const Page = async ({ params }: { params: PageParams }) => { @@ -58,16 +48,6 @@ const Page = async ({ params }: { params: PageParams }) => { const featuredNames = ["ZK Email", "Hardhat", "Updraft"] // TODO: determine logic, make DRY const highlights = appsData.filter(({ name }) => featuredNames.includes(name)) - const categories: { slug: DeveloperAppCategorySlug; Icon: LucideIcon }[] = [ - { slug: "interoperability", Icon: SendToBack }, - { slug: "transactions", Icon: ArrowLeftRight }, - { slug: "analytics", Icon: ChartSpline }, - { slug: "education", Icon: GraduationCap }, - { slug: "sdks", Icon: Package }, - { slug: "contracts", Icon: CodeXml }, - { slug: "security", Icon: Shield }, - ] - return ( <> {

{t("page-developers-apps-applications-title")}

- {categories.map(({ slug, Icon }) => ( + {CATEGORIES.map(({ slug, Icon }) => ( {

{t("page-developers-apps-categories-title")}

- {categories.map(({ slug, Icon }) => ( + {CATEGORIES.map(({ slug, Icon }) => ( Date: Mon, 19 Jan 2026 11:21:27 -0800 Subject: [PATCH 10/74] feat: client-side app modal wrapper --- .../developers/apps/_components/Modal.tsx | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 app/[locale]/developers/apps/_components/Modal.tsx diff --git a/app/[locale]/developers/apps/_components/Modal.tsx b/app/[locale]/developers/apps/_components/Modal.tsx new file mode 100644 index 00000000000..238b8dfa5fc --- /dev/null +++ b/app/[locale]/developers/apps/_components/Modal.tsx @@ -0,0 +1,29 @@ +"use client" + +import { usePathname, useRouter } from "next/navigation" + +import Modal from "@/components/ui/dialog-modal" + +type AppModalProps = { + open: boolean + children: React.ReactNode +} + +const AppModal = ({ open, children }: AppModalProps) => { + const router = useRouter() + const pathname = usePathname() + + return ( + { + if (open) return + router.replace(pathname, { scroll: false }) + }} + > + {children} + + ) +} + +export default AppModal From 23b449ebb322516b69dff68aeaac3fd3d0b93ad9 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Mon, 19 Jan 2026 11:23:45 -0800 Subject: [PATCH 11/74] feat: init app modal, refactor data fetching - Use search param to dictate active app - Show modal if present, removing param on close - Refactor data fetching and associated types to first enrich data before reshaping by category allowing quick app id lookup --- .../developers/apps/[category]/page.tsx | 28 +++++--- app/[locale]/developers/apps/page.tsx | 31 ++++++--- app/[locale]/developers/apps/types.ts | 16 +++-- app/[locale]/developers/apps/utils.ts | 12 ++-- ...rgazers.ts => fetchDeveloperAppsGitHub.ts} | 64 ++++++++----------- 5 files changed, 82 insertions(+), 69 deletions(-) rename src/data-layer/fetchers/{fetchDeveloperAppsStargazers.ts => fetchDeveloperAppsGitHub.ts} (66%) diff --git a/app/[locale]/developers/apps/[category]/page.tsx b/app/[locale]/developers/apps/[category]/page.tsx index df1fd06835d..e6761e2d8f1 100644 --- a/app/[locale]/developers/apps/[category]/page.tsx +++ b/app/[locale]/developers/apps/[category]/page.tsx @@ -21,30 +21,38 @@ import { cn } from "@/lib/utils/cn" import { getMetadata } from "@/lib/utils/metadata" import { fetchDeveloperApps } from "@/data-layer/fetchers/fetchDeveloperApps" +import { fetchDeveloperAppsGitHub } from "@/data-layer/fetchers/fetchDeveloperAppsGitHub" +import AppModal from "../_components/Modal" import { CATEGORIES, DEV_APP_CATEGORY_SLUGS } from "../constants" import type { DeveloperAppCategorySlug } from "../types" import { transformDeveloperAppsData } from "../utils" const Page = async ({ params, + searchParams, }: { params: PageParams & { category: DeveloperAppCategorySlug } + searchParams: { appId?: string } }) => { - // TODO: Get addId from search params, show modal for app if present const { locale, category } = params + const { appId } = searchParams + setRequestLocale(locale) - const t = await getTranslations({ locale, namespace: "page-developers-apps" }) - const tCommon = await getTranslations({ locale, namespace: "common" }) + const t = await getTranslations({ namespace: "page-developers-apps" }) + const tCommon = await getTranslations({ namespace: "common" }) - // const [appsData] = await Promise.all([getDeveloperAppsData()]) // TODO: Await all, add GitHub API fetches // const appsData = await getDeveloperAppsData() // TODO: data-layer - const appsData = await fetchDeveloperApps() // TODO: Trim mock data - if (!appsData) throw Error("No developer apps data available") - const data = transformDeveloperAppsData(appsData) + const rawData = await fetchDeveloperApps() // TODO: Trim mock data + if (!rawData) throw Error("No developer apps data available") + const enrichedData = await fetchDeveloperAppsGitHub(rawData) + const dataByCategory = transformDeveloperAppsData(enrichedData) + const categoryData = dataByCategory[category] + + const activeApp = enrichedData.find((app) => app.id === appId) const featuredNames = ["ZK Email", "Hardhat", "Updraft"] // TODO: determine logic, make DRY - const highlights = appsData.filter(({ name }) => featuredNames.includes(name)) + const highlights = rawData.filter(({ name }) => featuredNames.includes(name)) return ( <> @@ -138,7 +146,7 @@ const Page = async ({
- {data[category].map((app) => ( + {categoryData.map((app) => (
+ + Hola mundo ) } diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/apps/page.tsx index 1c3922bdf0f..f34735bec2d 100644 --- a/app/[locale]/developers/apps/page.tsx +++ b/app/[locale]/developers/apps/page.tsx @@ -26,27 +26,36 @@ import { cn } from "@/lib/utils/cn" import { getMetadata } from "@/lib/utils/metadata" import { fetchDeveloperApps } from "@/data-layer/fetchers/fetchDeveloperApps" -import { fetchDeveloperAppsStargazers } from "@/data-layer/fetchers/fetchDeveloperAppsStargazers" +import { fetchDeveloperAppsGitHub } from "@/data-layer/fetchers/fetchDeveloperAppsGitHub" +import AppModal from "./_components/Modal" import { CATEGORIES } from "./constants" import { transformDeveloperAppsData } from "./utils" -const Page = async ({ params }: { params: PageParams }) => { - // TODO: Get addId from search params, show modal for app if present +const Page = async ({ + params, + searchParams, +}: { + params: PageParams + searchParams: { appId?: string } +}) => { const { locale } = params - setRequestLocale(locale) + const { appId } = searchParams + setRequestLocale(locale) const t = await getTranslations({ namespace: "page-developers-apps" }) const tCommon = await getTranslations({ namespace: "common" }) // const appsData = await getDeveloperAppsData() // TODO: data-layer - const appsData = await fetchDeveloperApps() // TODO: Trim mock data - if (!appsData) throw Error("No developer apps data available") - const _data = transformDeveloperAppsData(appsData) - const data = await fetchDeveloperAppsStargazers(_data) + const rawData = await fetchDeveloperApps() // TODO: Trim mock data + if (!rawData) throw Error("No developer apps data available") + const enrichedData = await fetchDeveloperAppsGitHub(rawData) + const dataByCategory = transformDeveloperAppsData(enrichedData) + + const activeApp = enrichedData.find((app) => app.id === appId) const featuredNames = ["ZK Email", "Hardhat", "Updraft"] // TODO: determine logic, make DRY - const highlights = appsData.filter(({ name }) => featuredNames.includes(name)) + const highlights = rawData.filter(({ name }) => featuredNames.includes(name)) return ( <> @@ -169,7 +178,7 @@ const Page = async ({ params }: { params: PageParams }) => { - {data[slug].slice(0, 5).map((app) => ( + {dataByCategory[slug].slice(0, 5).map((app) => ( {
+ + Hola mundo ) } diff --git a/app/[locale]/developers/apps/types.ts b/app/[locale]/developers/apps/types.ts index 248e7cc37fc..a7c8a0de316 100644 --- a/app/[locale]/developers/apps/types.ts +++ b/app/[locale]/developers/apps/types.ts @@ -99,13 +99,15 @@ export type DeveloperAppCategory = keyof typeof DEV_APP_CATEGORY_SLUGS export type DeveloperAppCategorySlug = (typeof DEV_APP_CATEGORY_SLUGS)[DeveloperAppCategory] +export type DeveloperApp = Omit & { + repos: { + href: string + stargazers?: number + lastUpdated?: string | number | Date | null + }[] +} + export type DeveloperAppsByCategory = Record< DeveloperAppCategorySlug, - (Omit & { - repos: { - href: string - stargazers?: number - lastUpdated?: string | number | Date | null - }[] - })[] + DeveloperApp[] > diff --git a/app/[locale]/developers/apps/utils.ts b/app/[locale]/developers/apps/utils.ts index 421fc02f66a..8105261631e 100644 --- a/app/[locale]/developers/apps/utils.ts +++ b/app/[locale]/developers/apps/utils.ts @@ -1,10 +1,8 @@ -import type { DeveloperAppsResponse } from "@/lib/types" - import { DEV_APP_CATEGORY_SLUGS } from "./constants" -import type { DeveloperAppsByCategory } from "./types" +import type { DeveloperApp, DeveloperAppsByCategory } from "./types" export const transformDeveloperAppsData = ( - data: DeveloperAppsResponse[] + data: DeveloperApp[] ): DeveloperAppsByCategory => { const initialAcc = Object.values(DEV_APP_CATEGORY_SLUGS).reduce( (acc, slug) => { @@ -14,9 +12,9 @@ export const transformDeveloperAppsData = ( {} as DeveloperAppsByCategory ) - return data.reduce((acc, { category, repos, ...item }) => { - const slug = DEV_APP_CATEGORY_SLUGS[category] - acc[slug].push({ ...item, repos: repos.map((repo) => ({ href: repo })) }) + return data.reduce((acc, app) => { + const slug = DEV_APP_CATEGORY_SLUGS[app.category] + acc[slug].push(app) return acc }, initialAcc) } diff --git a/src/data-layer/fetchers/fetchDeveloperAppsStargazers.ts b/src/data-layer/fetchers/fetchDeveloperAppsGitHub.ts similarity index 66% rename from src/data-layer/fetchers/fetchDeveloperAppsStargazers.ts rename to src/data-layer/fetchers/fetchDeveloperAppsGitHub.ts index e175ea0ef97..f980c5124ea 100644 --- a/src/data-layer/fetchers/fetchDeveloperAppsStargazers.ts +++ b/src/data-layer/fetchers/fetchDeveloperAppsGitHub.ts @@ -1,5 +1,8 @@ // TODO: Set up data-layer integration -import { DeveloperAppsByCategory } from "../../../app/[locale]/developers/apps/types" + +import type { DeveloperAppsResponse } from "@/lib/types" + +import type { DeveloperApp } from "../../../app/[locale]/developers/apps/types" type RepoInfo = { owner: string @@ -9,7 +12,7 @@ type RepoInfo = { type GraphQLRepoResult = { stargazerCount: number - lastCommitDate: string | null // ISO date string - last commit on default branch + lastCommitDate: string | null } function parseGitHubUrl(href: string): RepoInfo | null { @@ -76,7 +79,6 @@ async function fetchReposBatch( console.warn("GitHub GraphQL errors:", json.errors) } - // Map results back to original hrefs repos.forEach((repo, i) => { const data = json.data?.[`repo${i}`] if (data) { @@ -90,23 +92,21 @@ async function fetchReposBatch( return results } -export async function fetchDeveloperAppsStargazers( - appData: DeveloperAppsByCategory -): Promise { - // Collect all unique repo URLs across all categories +export async function fetchDeveloperAppsGitHub( + appData: DeveloperAppsResponse[] +): Promise { + // Collect all unique repo URLs const allRepos: RepoInfo[] = [] const seenHrefs = new Set() - for (const apps of Object.values(appData)) { - for (const app of apps) { - for (const repo of app.repos) { - if (seenHrefs.has(repo.href)) continue - seenHrefs.add(repo.href) + for (const app of appData) { + for (const repoUrl of app.repos) { + if (seenHrefs.has(repoUrl)) continue + seenHrefs.add(repoUrl) - const parsed = parseGitHubUrl(repo.href) - if (parsed) { - allRepos.push(parsed) - } + const parsed = parseGitHubUrl(repoUrl) + if (parsed) { + allRepos.push(parsed) } } } @@ -128,24 +128,16 @@ export async function fetchDeveloperAppsStargazers( console.log(`Successfully fetched data for ${repoDataMap.size} repos`) - // Enrich the app data with stargazer counts and last updated dates - const enrichedData: DeveloperAppsByCategory = {} as DeveloperAppsByCategory - - for (const [category, apps] of Object.entries(appData)) { - enrichedData[category as keyof DeveloperAppsByCategory] = apps.map( - (app) => ({ - ...app, - repos: app.repos.map((repo) => { - const data = repoDataMap.get(repo.href) - return { - ...repo, - stargazers: data?.stargazerCount, - lastUpdated: data?.lastCommitDate, - } - }), - }) - ) - } - - return enrichedData + // Transform the data with enriched repos + return appData.map(({ repos, ...app }) => ({ + ...app, + repos: repos.map((repoUrl) => { + const data = repoDataMap.get(repoUrl) + return { + href: repoUrl, + stargazers: data?.stargazerCount, + lastUpdated: data?.lastCommitDate, + } + }), + })) } From 17d802e9e1d0efb0e22380bcad7a7b4c745c9414 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Mon, 19 Jan 2026 14:28:19 -0800 Subject: [PATCH 12/74] fix: DYNAMIC_SERVER_USAGE - Pass locale for translations - Update generateStaticParams to include locales --- .../developers/apps/[category]/page.tsx | 15 ++++++---- app/[locale]/developers/apps/constants.ts | 29 ++++++++++--------- app/[locale]/developers/apps/page.tsx | 18 ++++++++---- app/[locale]/developers/apps/types.ts | 4 +-- 4 files changed, 39 insertions(+), 27 deletions(-) diff --git a/app/[locale]/developers/apps/[category]/page.tsx b/app/[locale]/developers/apps/[category]/page.tsx index e6761e2d8f1..72345237264 100644 --- a/app/[locale]/developers/apps/[category]/page.tsx +++ b/app/[locale]/developers/apps/[category]/page.tsx @@ -24,10 +24,12 @@ import { fetchDeveloperApps } from "@/data-layer/fetchers/fetchDeveloperApps" import { fetchDeveloperAppsGitHub } from "@/data-layer/fetchers/fetchDeveloperAppsGitHub" import AppModal from "../_components/Modal" -import { CATEGORIES, DEV_APP_CATEGORY_SLUGS } from "../constants" +import { DEV_APP_CATEGORIES } from "../constants" import type { DeveloperAppCategorySlug } from "../types" import { transformDeveloperAppsData } from "../utils" +import { routing } from "@/i18n/routing" + const Page = async ({ params, searchParams, @@ -39,8 +41,8 @@ const Page = async ({ const { appId } = searchParams setRequestLocale(locale) - const t = await getTranslations({ namespace: "page-developers-apps" }) - const tCommon = await getTranslations({ namespace: "common" }) + const t = await getTranslations({ locale, namespace: "page-developers-apps" }) + const tCommon = await getTranslations({ locale, namespace: "common" }) // const appsData = await getDeveloperAppsData() // TODO: data-layer const rawData = await fetchDeveloperApps() // TODO: Trim mock data @@ -187,7 +189,7 @@ const Page = async ({

{t("page-developers-apps-categories-title-other")}

- {CATEGORIES.filter(({ slug }) => slug !== category).map( + {DEV_APP_CATEGORIES.filter(({ slug }) => slug !== category).map( ({ slug, Icon }) => ( ({ category })) + return routing.locales.flatMap((locale) => { + return DEV_APP_CATEGORIES.map(({ slug }) => ({ category: slug, locale })) + }) } export async function generateMetadata({ diff --git a/app/[locale]/developers/apps/constants.ts b/app/[locale]/developers/apps/constants.ts index 515506429e1..0481f5400b7 100644 --- a/app/[locale]/developers/apps/constants.ts +++ b/app/[locale]/developers/apps/constants.ts @@ -11,20 +11,18 @@ import { import type { DeveloperAppCategorySlug } from "./types" -export const DEV_APP_CATEGORY_SLUGS = { - "Cross-Chain & Interoperability": "interoperability", - "Transaction & Wallet Infrastructure": "transactions", - "Data, Analytics & Tracing": "analytics", - "Education & Community Resources": "education", - "Client Libraries & SDKs (Front-End)": "sdks", - "Smart Contract Development & Toolchains": "contracts", - "Security, Testing & Formal Verification": "security", -} as const +export const DEV_APP_CATEGORY_SLUGS: Record = + { + "Cross-Chain & Interoperability": "interoperability", + "Transaction & Wallet Infrastructure": "transactions", + "Data, Analytics & Tracing": "analytics", + "Education & Community Resources": "education", + "Client Libraries & SDKs (Front-End)": "sdks", + "Smart Contract Development & Toolchains": "contracts", + "Security, Testing & Formal Verification": "security", + } -export const CATEGORIES: { - slug: DeveloperAppCategorySlug - Icon: LucideIcon -}[] = [ +export const DEV_APP_CATEGORIES = [ { slug: "interoperability", Icon: SendToBack }, { slug: "transactions", Icon: ArrowLeftRight }, { slug: "analytics", Icon: ChartSpline }, @@ -32,4 +30,7 @@ export const CATEGORIES: { { slug: "sdks", Icon: Package }, { slug: "contracts", Icon: CodeXml }, { slug: "security", Icon: Shield }, -] +] as const satisfies { + slug: string + Icon: LucideIcon +}[] diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/apps/page.tsx index f34735bec2d..94993a8ecf8 100644 --- a/app/[locale]/developers/apps/page.tsx +++ b/app/[locale]/developers/apps/page.tsx @@ -29,9 +29,11 @@ import { fetchDeveloperApps } from "@/data-layer/fetchers/fetchDeveloperApps" import { fetchDeveloperAppsGitHub } from "@/data-layer/fetchers/fetchDeveloperAppsGitHub" import AppModal from "./_components/Modal" -import { CATEGORIES } from "./constants" +import { DEV_APP_CATEGORIES } from "./constants" import { transformDeveloperAppsData } from "./utils" +import { routing } from "@/i18n/routing" + const Page = async ({ params, searchParams, @@ -43,8 +45,8 @@ const Page = async ({ const { appId } = searchParams setRequestLocale(locale) - const t = await getTranslations({ namespace: "page-developers-apps" }) - const tCommon = await getTranslations({ namespace: "common" }) + const t = await getTranslations({ locale, namespace: "page-developers-apps" }) + const tCommon = await getTranslations({ locale, namespace: "common" }) // const appsData = await getDeveloperAppsData() // TODO: data-layer const rawData = await fetchDeveloperApps() // TODO: Trim mock data @@ -140,7 +142,7 @@ const Page = async ({

{t("page-developers-apps-applications-title")}

- {CATEGORIES.map(({ slug, Icon }) => ( + {DEV_APP_CATEGORIES.map(({ slug, Icon }) => (

{t("page-developers-apps-categories-title")}

- {CATEGORIES.map(({ slug, Icon }) => ( + {DEV_APP_CATEGORIES.map(({ slug, Icon }) => ( ({ + locale, + })) +} + export async function generateMetadata({ params, }: { diff --git a/app/[locale]/developers/apps/types.ts b/app/[locale]/developers/apps/types.ts index a7c8a0de316..0a5e25cd48f 100644 --- a/app/[locale]/developers/apps/types.ts +++ b/app/[locale]/developers/apps/types.ts @@ -1,6 +1,6 @@ import { DeveloperAppsResponse } from "@/lib/types" -import { DEV_APP_CATEGORY_SLUGS } from "./constants" +import { DEV_APP_CATEGORIES, DEV_APP_CATEGORY_SLUGS } from "./constants" export type DeveloperAppTag = | "abi-encoding" @@ -97,7 +97,7 @@ export type DeveloperAppTag = export type DeveloperAppCategory = keyof typeof DEV_APP_CATEGORY_SLUGS export type DeveloperAppCategorySlug = - (typeof DEV_APP_CATEGORY_SLUGS)[DeveloperAppCategory] + (typeof DEV_APP_CATEGORIES)[number]["slug"] export type DeveloperApp = Omit & { repos: { From a7800f5111412093c9495d0f10af111c617201f4 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Mon, 19 Jan 2026 17:17:21 -0800 Subject: [PATCH 13/74] refactor: ui/dialog-modal variants - Refactor "isSimulator" to "simulator" variant, update consuming component - Add "unstyled" variant, stripped of padding, grid, gap, bg, corners --- src/components/Simulator/SimulatorModal.tsx | 2 +- src/components/ui/dialog-modal.tsx | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/Simulator/SimulatorModal.tsx b/src/components/Simulator/SimulatorModal.tsx index c38ef765efd..324040c2b58 100644 --- a/src/components/Simulator/SimulatorModal.tsx +++ b/src/components/Simulator/SimulatorModal.tsx @@ -5,5 +5,5 @@ import Modal, { type ModalProps } from "../ui/dialog-modal" type SimulatorModalProps = Omit export const SimulatorModal = (props: SimulatorModalProps) => { - return + return } diff --git a/src/components/ui/dialog-modal.tsx b/src/components/ui/dialog-modal.tsx index 40260bccf21..4ad55ce2eae 100644 --- a/src/components/ui/dialog-modal.tsx +++ b/src/components/ui/dialog-modal.tsx @@ -28,11 +28,14 @@ const dialogVariant = tv({ content: "max-w-[1004px]", }, }, - isSimulator: { - true: { + variant: { + simulator: { close: "static ms-auto", header: "pe-0", }, + unstyled: { + content: "block p-0 rounded-none bg-none gap", + }, }, }, defaultVariants: { @@ -48,8 +51,8 @@ const useDialogStyles = () => React.useContext(DialogStylesContext) type DialogProps = DialogPrimitive.DialogProps & DialogVariants -const Dialog = ({ size, isSimulator, ...props }: DialogProps) => { - const styles = dialogVariant({ size, isSimulator }) +const Dialog = ({ size, variant, ...props }: DialogProps) => { + const styles = dialogVariant({ size, variant }) return ( From 4215702498ca8a7530fb9bfd29be4aecc945bad4 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Mon, 19 Jan 2026 17:35:57 -0800 Subject: [PATCH 14/74] feat: add AppModalContents --- .../developers/apps/[category]/page.tsx | 7 +- .../apps/_components/AppModalContents.tsx | 112 ++++++++++++++++++ .../{Modal.tsx => AppModalWrapper.tsx} | 19 ++- app/[locale]/developers/apps/page.tsx | 9 +- src/components/icons/npmjs.svg | 3 + src/intl/en/page-developers-apps.json | 5 +- 6 files changed, 138 insertions(+), 17 deletions(-) create mode 100644 app/[locale]/developers/apps/_components/AppModalContents.tsx rename app/[locale]/developers/apps/_components/{Modal.tsx => AppModalWrapper.tsx} (54%) create mode 100644 src/components/icons/npmjs.svg diff --git a/app/[locale]/developers/apps/[category]/page.tsx b/app/[locale]/developers/apps/[category]/page.tsx index 72345237264..13924f0dc97 100644 --- a/app/[locale]/developers/apps/[category]/page.tsx +++ b/app/[locale]/developers/apps/[category]/page.tsx @@ -23,7 +23,8 @@ import { getMetadata } from "@/lib/utils/metadata" import { fetchDeveloperApps } from "@/data-layer/fetchers/fetchDeveloperApps" import { fetchDeveloperAppsGitHub } from "@/data-layer/fetchers/fetchDeveloperAppsGitHub" -import AppModal from "../_components/Modal" +import AppModalContents from "../_components/AppModalContents" +import AppModalWrapper from "../_components/AppModalWrapper" import { DEV_APP_CATEGORIES } from "../constants" import type { DeveloperAppCategorySlug } from "../types" import { transformDeveloperAppsData } from "../utils" @@ -212,7 +213,9 @@ const Page = async ({
- Hola mundo + + {activeApp && } + ) } diff --git a/app/[locale]/developers/apps/_components/AppModalContents.tsx b/app/[locale]/developers/apps/_components/AppModalContents.tsx new file mode 100644 index 00000000000..c14a8aee865 --- /dev/null +++ b/app/[locale]/developers/apps/_components/AppModalContents.tsx @@ -0,0 +1,112 @@ +import { Star } from "lucide-react" +import Image from "next/image" +import { getLocale, getTranslations } from "next-intl/server" + +import GitHub from "@/components/icons/github.svg" +import NpmJs from "@/components/icons/npmjs.svg" +import { ButtonLink } from "@/components/ui/buttons/Button" +import { Tag, TagsInlineText } from "@/components/ui/tag" + +import { formatDate, getValidDate } from "@/lib/utils/date" +import { isExternal } from "@/lib/utils/url" + +import { DeveloperApp } from "../types" + +const AppModalContents = async ({ app }: { app: DeveloperApp }) => { + const locale = await getLocale() + const t = await getTranslations({ locale, namespace: "page-developers-apps" }) + const tCommon = await getTranslations({ locale, namespace: "common" }) + + return ( +
+
+ {app.banner_url && ( + + )} +
+
+
+ + {app.category} + +

{app.name}

+ t(`page-developers-app-tag-${tag}`))} + variant="light" + className="lowercase" + /> +
+

{app.description}

+
+

{t("page-developers-apps-modal-links")}

+
+ {app.website && ( + + {t("page-developers-apps-modal-website")} + + )} + {app.twitter && ( + + {t("page-developers-apps-modal-social")} + + )} + {app.repos + .filter(({ href }) => isExternal(href)) + .map(({ href, stargazers, lastUpdated }) => { + const isGitHub = href.includes("https://github.com") + const isNpm = href.includes("https://www.npmjs.com") + const sanitizeRegExp = + /^https:\/\/(github\.com|www\.npmjs\.com\/package)\// + // TODO: Handle non-github/npmjs labels + const label = href.replace(sanitizeRegExp, "") + const date = getValidDate(lastUpdated) + return ( + + {isGitHub && } + {isNpm && } + {label} + {isGitHub && stargazers && ( + <> + {" "} + + ({new Intl.NumberFormat(locale).format(stargazers)} + + + ) + + )} + + ) + })} +
+
+
+
+ ) +} + +export default AppModalContents diff --git a/app/[locale]/developers/apps/_components/Modal.tsx b/app/[locale]/developers/apps/_components/AppModalWrapper.tsx similarity index 54% rename from app/[locale]/developers/apps/_components/Modal.tsx rename to app/[locale]/developers/apps/_components/AppModalWrapper.tsx index 238b8dfa5fc..a9e222a9e36 100644 --- a/app/[locale]/developers/apps/_components/Modal.tsx +++ b/app/[locale]/developers/apps/_components/AppModalWrapper.tsx @@ -3,27 +3,24 @@ import { usePathname, useRouter } from "next/navigation" import Modal from "@/components/ui/dialog-modal" +import { type ModalProps } from "@/components/ui/dialog-modal" -type AppModalProps = { - open: boolean - children: React.ReactNode -} - -const AppModal = ({ open, children }: AppModalProps) => { +const AppModalWrapper = (props: ModalProps) => { const router = useRouter() const pathname = usePathname() return ( { if (open) return router.replace(pathname, { scroll: false }) }} - > - {children} - + contentProps={{ + className: "[&_.lucide-x]:!stroke-[3] [&_.lucide-x]:!text-body-inverse", + }} + {...props} + /> ) } -export default AppModal +export default AppModalWrapper diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/apps/page.tsx index 94993a8ecf8..c0ecf6ac71d 100644 --- a/app/[locale]/developers/apps/page.tsx +++ b/app/[locale]/developers/apps/page.tsx @@ -28,7 +28,8 @@ import { getMetadata } from "@/lib/utils/metadata" import { fetchDeveloperApps } from "@/data-layer/fetchers/fetchDeveloperApps" import { fetchDeveloperAppsGitHub } from "@/data-layer/fetchers/fetchDeveloperAppsGitHub" -import AppModal from "./_components/Modal" +import AppModalContents from "./_components/AppModalContents" +import AppModalWrapper from "./_components/AppModalWrapper" import { DEV_APP_CATEGORIES } from "./constants" import { transformDeveloperAppsData } from "./utils" @@ -117,7 +118,7 @@ const Page = async ({ {app.category} @@ -245,7 +246,9 @@ const Page = async ({
- Hola mundo + + {activeApp && } + ) } diff --git a/src/components/icons/npmjs.svg b/src/components/icons/npmjs.svg new file mode 100644 index 00000000000..67b9cd79b56 --- /dev/null +++ b/src/components/icons/npmjs.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/intl/en/page-developers-apps.json b/src/intl/en/page-developers-apps.json index 1fdfc95fb5d..e69c717f2a2 100644 --- a/src/intl/en/page-developers-apps.json +++ b/src/intl/en/page-developers-apps.json @@ -90,8 +90,8 @@ "page-developers-app-tag-vyper": "Vyper", "page-developers-app-tag-wallet": "Wallet", "page-developers-apps-applications-title": "Applications", - "page-developers-apps-categories-title": "Application categories", "page-developers-apps-categories-title-other": "Other application categories", + "page-developers-apps-categories-title": "Application categories", "page-developers-apps-category-analytics-breadcrumb": "Analytics", "page-developers-apps-category-analytics-description": "Indexing, querying, analytics, and tracing tools for onchain data, execution, and network activity.", "page-developers-apps-category-analytics-meta-description": "Ethereum data analytics tools for indexing querying tracing transactions and monitoring onchain activity and execution.", @@ -123,6 +123,9 @@ "page-developers-apps-highlights": "Highlights", "page-developers-apps-meta-description": "Discover Ethereum developer tooling including smart contract frameworks SDKs security testing analytics and wallet infrastructure to build and scale web3 apps.", "page-developers-apps-meta-title": "Developer tooling", + "page-developers-apps-modal-links": "Links", + "page-developers-apps-modal-social": "Social", + "page-developers-apps-modal-website": "Website", "page-developers-apps-see-all": "See all", "page-developers-apps-subtitle": "Find the right tools faster and help elevate the developers who create the infrastructure our ecosystem relies on.", "page-developers-apps-title": "Developer tooling" From a29d6d973beb33bf0584b6c348e8e8c8ca5f4776 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Mon, 19 Jan 2026 19:56:53 -0800 Subject: [PATCH 15/74] refactor: TruncatedText - refactor: Deprecate text prop; accept children - fix(i18n): use common namespace strings - refactor: LINE_CLAMP_CLASS_MAPPING to constants - update: existing component usage --- app/[locale]/apps/_components/AppCard.tsx | 5 ++- .../apps/_components/AppsHighlight.tsx | 5 ++- src/components/ui/TruncatedText.tsx | 40 +++++++++---------- src/intl/en/common.json | 1 + src/lib/constants.ts | 7 ++++ 5 files changed, 33 insertions(+), 25 deletions(-) diff --git a/app/[locale]/apps/_components/AppCard.tsx b/app/[locale]/apps/_components/AppCard.tsx index b9014244d69..bc499bd1a63 100644 --- a/app/[locale]/apps/_components/AppCard.tsx +++ b/app/[locale]/apps/_components/AppCard.tsx @@ -70,14 +70,15 @@ const AppCard = ({

{showDescription && ( + > + {app.description} + )}
diff --git a/app/[locale]/apps/_components/AppsHighlight.tsx b/app/[locale]/apps/_components/AppsHighlight.tsx index 75454ff7de5..df2181a400b 100644 --- a/app/[locale]/apps/_components/AppsHighlight.tsx +++ b/app/[locale]/apps/_components/AppsHighlight.tsx @@ -39,13 +39,14 @@ const AppsHighlight = ({ apps, matomoCategory }: AppsHighlightProps) => {
+ > + {app.description} +
, + "children" | "className" + > { maxLines?: number - showMoreText?: string - showLessText?: string - className?: string matomoEvent?: MatomoEventOptions } const TruncatedText = ({ - text, maxLines = 2, - showMoreText = "Show more", - showLessText = "Show less", - className = "", + className, + children, matomoEvent, }: TruncatedTextProps) => { + const { t } = useTranslation("common") const [isExpanded, setIsExpanded] = useState(false) - const lineClampClass = { - 1: "line-clamp-1", - 2: "line-clamp-2", - 3: "line-clamp-3", - 4: "line-clamp-4", - } - return (

- {text} + {children}

) diff --git a/src/intl/en/common.json b/src/intl/en/common.json index 193cac62783..d01c7751e00 100644 --- a/src/intl/en/common.json +++ b/src/intl/en/common.json @@ -435,6 +435,7 @@ "set-up-local-env": "Set up local environment", "sharding": "Sharding", "show-all": "Show all", + "show-more": "Show more", "show-less": "Show less", "single-slot-finality": "Single-slot finality", "site-description": "Ethereum is a global, decentralized platform for money and new kinds of applications. On Ethereum, you can write code that controls money, and build applications accessible anywhere in the world.", diff --git a/src/lib/constants.ts b/src/lib/constants.ts index fd69ee33964..53fec483759 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -249,3 +249,10 @@ export const SIZE_CLASS_MAPPING = { 16: "size-16", 24: "size-24", } as const + +export const LINE_CLAMP_CLASS_MAPPING = { + 1: "line-clamp-1", + 2: "line-clamp-2", + 3: "line-clamp-3", + 4: "line-clamp-4", +} as const From f7283e7c8dab452ccc44ec51e581bfcbfbdf26d6 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Mon, 19 Jan 2026 20:56:05 -0800 Subject: [PATCH 16/74] chore: adjust i18n key names for consistency --- .../developers/apps/[category]/page.tsx | 4 +- .../apps/_components/AppModalContents.tsx | 2 +- app/[locale]/developers/apps/page.tsx | 4 +- src/intl/en/page-developers-apps.json | 180 +++++++++--------- 4 files changed, 95 insertions(+), 95 deletions(-) diff --git a/app/[locale]/developers/apps/[category]/page.tsx b/app/[locale]/developers/apps/[category]/page.tsx index 13924f0dc97..977fc7db3e1 100644 --- a/app/[locale]/developers/apps/[category]/page.tsx +++ b/app/[locale]/developers/apps/[category]/page.tsx @@ -125,7 +125,7 @@ const Page = async ({ {app.name} - t(`page-developers-app-tag-${tag}`) + t(`page-developers-apps-tag-${tag}`) )} max={3} // TODO: Confirm / sort? variant="light" @@ -175,7 +175,7 @@ const Page = async ({

{app.name}

- t(`page-developers-app-tag-${tag}`) + t(`page-developers-apps-tag-${tag}`) )} variant="light" className="lowercase" diff --git a/app/[locale]/developers/apps/_components/AppModalContents.tsx b/app/[locale]/developers/apps/_components/AppModalContents.tsx index c14a8aee865..4796828da5e 100644 --- a/app/[locale]/developers/apps/_components/AppModalContents.tsx +++ b/app/[locale]/developers/apps/_components/AppModalContents.tsx @@ -41,7 +41,7 @@ const AppModalContents = async ({ app }: { app: DeveloperApp }) => {

{app.name}

t(`page-developers-app-tag-${tag}`))} + list={app.tags.map((tag) => t(`page-developers-apps-tag-${tag}`))} variant="light" className="lowercase" /> diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/apps/page.tsx index c0ecf6ac71d..8efde487150 100644 --- a/app/[locale]/developers/apps/page.tsx +++ b/app/[locale]/developers/apps/page.tsx @@ -125,7 +125,7 @@ const Page = async ({ {app.name} - t(`page-developers-app-tag-${tag}`) + t(`page-developers-apps-tag-${tag}`) )} max={3} // TODO: Confirm / sort? variant="light" @@ -207,7 +207,7 @@ const Page = async ({

{app.name}

- t(`page-developers-app-tag-${tag}`) + t(`page-developers-apps-tag-${tag}`) )} variant="light" className="lowercase" diff --git a/src/intl/en/page-developers-apps.json b/src/intl/en/page-developers-apps.json index e69c717f2a2..a11902c8945 100644 --- a/src/intl/en/page-developers-apps.json +++ b/src/intl/en/page-developers-apps.json @@ -1,94 +1,4 @@ { - "page-developers-app-tag-abi-encoding": "ABI encoding", - "page-developers-app-tag-account-abstraction": "Account abstraction", - "page-developers-app-tag-analytics": "Analytics", - "page-developers-app-tag-api": "API", - "page-developers-app-tag-authentication": "Authentication", - "page-developers-app-tag-block-explorer": "Block explorer", - "page-developers-app-tag-bundler": "Bundler", - "page-developers-app-tag-censorship-resistant": "Censorship resistant", - "page-developers-app-tag-chains": "Chains", - "page-developers-app-tag-cli": "CLI", - "page-developers-app-tag-code-analysis": "Code analysis", - "page-developers-app-tag-code-coverage": "Code coverage", - "page-developers-app-tag-code-quality": "Code quality", - "page-developers-app-tag-community-driven": "Community driven", - "page-developers-app-tag-compiler": "Compiler", - "page-developers-app-tag-continuous-integration": "Continuous integration", - "page-developers-app-tag-contract-deployment": "Contract deployment", - "page-developers-app-tag-contract-interaction": "Contract interaction", - "page-developers-app-tag-contract-management": "Contract management", - "page-developers-app-tag-contract-verification": "Contract verification", - "page-developers-app-tag-cross-chain": "Cross-chain", - "page-developers-app-tag-debugging-tools": "Debugging tools", - "page-developers-app-tag-decentralized-governance": "Decentralized governance", - "page-developers-app-tag-defi": "DeFi", - "page-developers-app-tag-developer-experience": "Developer experience", - "page-developers-app-tag-devops": "DevOps", - "page-developers-app-tag-dex-aggregator": "DEX aggregator", - "page-developers-app-tag-docker": "Docker", - "page-developers-app-tag-education": "Education", - "page-developers-app-tag-encryption": "Encryption", - "page-developers-app-tag-erc721": "ERC-721", - "page-developers-app-tag-event-logging": "Event logging", - "page-developers-app-tag-farcaster": "Farcaster", - "page-developers-app-tag-formal-verification": "Formal verification", - "page-developers-app-tag-foundry": "Foundry", - "page-developers-app-tag-frontend": "Frontend", - "page-developers-app-tag-fuzz-testing": "Fuzz testing", - "page-developers-app-tag-game-development": "Game development", - "page-developers-app-tag-gas-efficient": "Gas efficient", - "page-developers-app-tag-gas-optimization": "Gas optimization", - "page-developers-app-tag-github-actions": "GitHub actions", - "page-developers-app-tag-gossipsub": "GossipSub", - "page-developers-app-tag-governance": "Governance", - "page-developers-app-tag-hardhat": "Hardhat", - "page-developers-app-tag-indexing": "Indexing", - "page-developers-app-tag-interactive-tools": "Interactive tools", - "page-developers-app-tag-json-rpc": "JSON-RPC", - "page-developers-app-tag-layer-2": "Layer 2", - "page-developers-app-tag-libp2p": "libp2p", - "page-developers-app-tag-mcp-server": "MCP server", - "page-developers-app-tag-merkle-trees": "Merkle trees", - "page-developers-app-tag-modular-accounts": "Modular accounts", - "page-developers-app-tag-multi-chain": "Multi-chain", - "page-developers-app-tag-multicall": "Multicall", - "page-developers-app-tag-natural-language-processing": "Natural language processing", - "page-developers-app-tag-networking": "Networking", - "page-developers-app-tag-nextjs": "Next.js", - "page-developers-app-tag-peer-to-peer": "Peer-to-peer", - "page-developers-app-tag-performance-optimization": "Performance optimization", - "page-developers-app-tag-privacy-focused": "Privacy focused", - "page-developers-app-tag-proxy-contracts": "Proxy contracts", - "page-developers-app-tag-react-app": "React app", - "page-developers-app-tag-react": "React", - "page-developers-app-tag-real-time-data": "Real-time data", - "page-developers-app-tag-runtime-verification": "Runtime verification", - "page-developers-app-tag-scalability": "Scalability", - "page-developers-app-tag-sdk": "SDK", - "page-developers-app-tag-security": "Security", - "page-developers-app-tag-solidity-development": "Solidity development", - "page-developers-app-tag-solidity": "Solidity", - "page-developers-app-tag-static-analysis": "Static analysis", - "page-developers-app-tag-storage-layout": "Storage layout", - "page-developers-app-tag-support": "Support", - "page-developers-app-tag-symbolic-execution": "Symbolic execution", - "page-developers-app-tag-tailwind-css": "TailwindCSS", - "page-developers-app-tag-test-automation": "Test automation", - "page-developers-app-tag-testing": "Testing", - "page-developers-app-tag-transaction-decoding": "Transaction decoding", - "page-developers-app-tag-transaction-management": "Transaction management", - "page-developers-app-tag-transaction-optimization": "Transaction optimization", - "page-developers-app-tag-transaction-signing": "Transaction signing", - "page-developers-app-tag-truffle": "Truffle", - "page-developers-app-tag-type-safe": "Type-safe", - "page-developers-app-tag-upgradeable-contracts": "Upgradeable contracts", - "page-developers-app-tag-user-experience": "User experience", - "page-developers-app-tag-verification": "Verification", - "page-developers-app-tag-visualization": "Visualization", - "page-developers-app-tag-vscode-extension": "VSCode extension", - "page-developers-app-tag-vyper": "Vyper", - "page-developers-app-tag-wallet": "Wallet", "page-developers-apps-applications-title": "Applications", "page-developers-apps-categories-title-other": "Other application categories", "page-developers-apps-categories-title": "Application categories", @@ -128,5 +38,95 @@ "page-developers-apps-modal-website": "Website", "page-developers-apps-see-all": "See all", "page-developers-apps-subtitle": "Find the right tools faster and help elevate the developers who create the infrastructure our ecosystem relies on.", + "page-developers-apps-tag-abi-encoding": "ABI encoding", + "page-developers-apps-tag-account-abstraction": "Account abstraction", + "page-developers-apps-tag-analytics": "Analytics", + "page-developers-apps-tag-api": "API", + "page-developers-apps-tag-authentication": "Authentication", + "page-developers-apps-tag-block-explorer": "Block explorer", + "page-developers-apps-tag-bundler": "Bundler", + "page-developers-apps-tag-censorship-resistant": "Censorship resistant", + "page-developers-apps-tag-chains": "Chains", + "page-developers-apps-tag-cli": "CLI", + "page-developers-apps-tag-code-analysis": "Code analysis", + "page-developers-apps-tag-code-coverage": "Code coverage", + "page-developers-apps-tag-code-quality": "Code quality", + "page-developers-apps-tag-community-driven": "Community driven", + "page-developers-apps-tag-compiler": "Compiler", + "page-developers-apps-tag-continuous-integration": "Continuous integration", + "page-developers-apps-tag-contract-deployment": "Contract deployment", + "page-developers-apps-tag-contract-interaction": "Contract interaction", + "page-developers-apps-tag-contract-management": "Contract management", + "page-developers-apps-tag-contract-verification": "Contract verification", + "page-developers-apps-tag-cross-chain": "Cross-chain", + "page-developers-apps-tag-debugging-tools": "Debugging tools", + "page-developers-apps-tag-decentralized-governance": "Decentralized governance", + "page-developers-apps-tag-defi": "DeFi", + "page-developers-apps-tag-developer-experience": "Developer experience", + "page-developers-apps-tag-devops": "DevOps", + "page-developers-apps-tag-dex-aggregator": "DEX aggregator", + "page-developers-apps-tag-docker": "Docker", + "page-developers-apps-tag-education": "Education", + "page-developers-apps-tag-encryption": "Encryption", + "page-developers-apps-tag-erc721": "ERC-721", + "page-developers-apps-tag-event-logging": "Event logging", + "page-developers-apps-tag-farcaster": "Farcaster", + "page-developers-apps-tag-formal-verification": "Formal verification", + "page-developers-apps-tag-foundry": "Foundry", + "page-developers-apps-tag-frontend": "Frontend", + "page-developers-apps-tag-fuzz-testing": "Fuzz testing", + "page-developers-apps-tag-game-development": "Game development", + "page-developers-apps-tag-gas-efficient": "Gas efficient", + "page-developers-apps-tag-gas-optimization": "Gas optimization", + "page-developers-apps-tag-github-actions": "GitHub actions", + "page-developers-apps-tag-gossipsub": "GossipSub", + "page-developers-apps-tag-governance": "Governance", + "page-developers-apps-tag-hardhat": "Hardhat", + "page-developers-apps-tag-indexing": "Indexing", + "page-developers-apps-tag-interactive-tools": "Interactive tools", + "page-developers-apps-tag-json-rpc": "JSON-RPC", + "page-developers-apps-tag-layer-2": "Layer 2", + "page-developers-apps-tag-libp2p": "libp2p", + "page-developers-apps-tag-mcp-server": "MCP server", + "page-developers-apps-tag-merkle-trees": "Merkle trees", + "page-developers-apps-tag-modular-accounts": "Modular accounts", + "page-developers-apps-tag-multi-chain": "Multi-chain", + "page-developers-apps-tag-multicall": "Multicall", + "page-developers-apps-tag-natural-language-processing": "Natural language processing", + "page-developers-apps-tag-networking": "Networking", + "page-developers-apps-tag-nextjs": "Next.js", + "page-developers-apps-tag-peer-to-peer": "Peer-to-peer", + "page-developers-apps-tag-performance-optimization": "Performance optimization", + "page-developers-apps-tag-privacy-focused": "Privacy focused", + "page-developers-apps-tag-proxy-contracts": "Proxy contracts", + "page-developers-apps-tag-react-app": "React app", + "page-developers-apps-tag-react": "React", + "page-developers-apps-tag-real-time-data": "Real-time data", + "page-developers-apps-tag-runtime-verification": "Runtime verification", + "page-developers-apps-tag-scalability": "Scalability", + "page-developers-apps-tag-sdk": "SDK", + "page-developers-apps-tag-security": "Security", + "page-developers-apps-tag-solidity-development": "Solidity development", + "page-developers-apps-tag-solidity": "Solidity", + "page-developers-apps-tag-static-analysis": "Static analysis", + "page-developers-apps-tag-storage-layout": "Storage layout", + "page-developers-apps-tag-support": "Support", + "page-developers-apps-tag-symbolic-execution": "Symbolic execution", + "page-developers-apps-tag-tailwind-css": "TailwindCSS", + "page-developers-apps-tag-test-automation": "Test automation", + "page-developers-apps-tag-testing": "Testing", + "page-developers-apps-tag-transaction-decoding": "Transaction decoding", + "page-developers-apps-tag-transaction-management": "Transaction management", + "page-developers-apps-tag-transaction-optimization": "Transaction optimization", + "page-developers-apps-tag-transaction-signing": "Transaction signing", + "page-developers-apps-tag-truffle": "Truffle", + "page-developers-apps-tag-type-safe": "Type-safe", + "page-developers-apps-tag-upgradeable-contracts": "Upgradeable contracts", + "page-developers-apps-tag-user-experience": "User experience", + "page-developers-apps-tag-verification": "Verification", + "page-developers-apps-tag-visualization": "Visualization", + "page-developers-apps-tag-vscode-extension": "VSCode extension", + "page-developers-apps-tag-vyper": "Vyper", + "page-developers-apps-tag-wallet": "Wallet", "page-developers-apps-title": "Developer tooling" } From bddba5e27ca7807929da12cec962ecfb30e0df4a Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Mon, 19 Jan 2026 21:36:38 -0800 Subject: [PATCH 17/74] feat: fetch download count for npmjs repos --- .../developers/apps/[category]/page.tsx | 4 +- .../apps/_components/AppModalContents.tsx | 19 +- app/[locale]/developers/apps/page.tsx | 4 +- app/[locale]/developers/apps/types.ts | 1 + .../fetchers/fetchDeveloperAppsNpmJs.ts | 173 ++++++++++++++++++ 5 files changed, 196 insertions(+), 5 deletions(-) create mode 100644 src/data-layer/fetchers/fetchDeveloperAppsNpmJs.ts diff --git a/app/[locale]/developers/apps/[category]/page.tsx b/app/[locale]/developers/apps/[category]/page.tsx index 977fc7db3e1..26a4acc46b8 100644 --- a/app/[locale]/developers/apps/[category]/page.tsx +++ b/app/[locale]/developers/apps/[category]/page.tsx @@ -22,6 +22,7 @@ import { getMetadata } from "@/lib/utils/metadata" import { fetchDeveloperApps } from "@/data-layer/fetchers/fetchDeveloperApps" import { fetchDeveloperAppsGitHub } from "@/data-layer/fetchers/fetchDeveloperAppsGitHub" +import { fetchDeveloperAppsNpm } from "@/data-layer/fetchers/fetchDeveloperAppsNpmJs" import AppModalContents from "../_components/AppModalContents" import AppModalWrapper from "../_components/AppModalWrapper" @@ -48,7 +49,8 @@ const Page = async ({ // const appsData = await getDeveloperAppsData() // TODO: data-layer const rawData = await fetchDeveloperApps() // TODO: Trim mock data if (!rawData) throw Error("No developer apps data available") - const enrichedData = await fetchDeveloperAppsGitHub(rawData) + const _enrichedData = await fetchDeveloperAppsGitHub(rawData) + const enrichedData = await fetchDeveloperAppsNpm(_enrichedData) const dataByCategory = transformDeveloperAppsData(enrichedData) const categoryData = dataByCategory[category] diff --git a/app/[locale]/developers/apps/_components/AppModalContents.tsx b/app/[locale]/developers/apps/_components/AppModalContents.tsx index 4796828da5e..429694fc986 100644 --- a/app/[locale]/developers/apps/_components/AppModalContents.tsx +++ b/app/[locale]/developers/apps/_components/AppModalContents.tsx @@ -1,4 +1,4 @@ -import { Star } from "lucide-react" +import { Download, Star } from "lucide-react" import Image from "next/image" import { getLocale, getTranslations } from "next-intl/server" @@ -8,6 +8,7 @@ import { ButtonLink } from "@/components/ui/buttons/Button" import { Tag, TagsInlineText } from "@/components/ui/tag" import { formatDate, getValidDate } from "@/lib/utils/date" +import { formatLargeNumber } from "@/lib/utils/numbers" import { isExternal } from "@/lib/utils/url" import { DeveloperApp } from "../types" @@ -65,7 +66,7 @@ const AppModalContents = async ({ app }: { app: DeveloperApp }) => { )} {app.repos .filter(({ href }) => isExternal(href)) - .map(({ href, stargazers, lastUpdated }) => { + .map(({ href, stargazers, downloads, lastUpdated }) => { const isGitHub = href.includes("https://github.com") const isNpm = href.includes("https://www.npmjs.com") const sanitizeRegExp = @@ -73,6 +74,8 @@ const AppModalContents = async ({ app }: { app: DeveloperApp }) => { // TODO: Handle non-github/npmjs labels const label = href.replace(sanitizeRegExp, "") const date = getValidDate(lastUpdated) + const showStars = isGitHub && stargazers // && stargazers > 10 + const showDownloads = isNpm && downloads // && downloads > 10 return ( { {isGitHub && } {isNpm && } {label} - {isGitHub && stargazers && ( + {showStars && ( <> {" "} @@ -99,6 +102,16 @@ const AppModalContents = async ({ app }: { app: DeveloperApp }) => { ) )} + {showDownloads && ( + <> + {" "} + + ({formatLargeNumber(downloads, locale)} + + + ) + + )} ) })} diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/apps/page.tsx index 8efde487150..a33de2d368b 100644 --- a/app/[locale]/developers/apps/page.tsx +++ b/app/[locale]/developers/apps/page.tsx @@ -27,6 +27,7 @@ import { getMetadata } from "@/lib/utils/metadata" import { fetchDeveloperApps } from "@/data-layer/fetchers/fetchDeveloperApps" import { fetchDeveloperAppsGitHub } from "@/data-layer/fetchers/fetchDeveloperAppsGitHub" +import { fetchDeveloperAppsNpm } from "@/data-layer/fetchers/fetchDeveloperAppsNpmJs" import AppModalContents from "./_components/AppModalContents" import AppModalWrapper from "./_components/AppModalWrapper" @@ -52,7 +53,8 @@ const Page = async ({ // const appsData = await getDeveloperAppsData() // TODO: data-layer const rawData = await fetchDeveloperApps() // TODO: Trim mock data if (!rawData) throw Error("No developer apps data available") - const enrichedData = await fetchDeveloperAppsGitHub(rawData) + const _enrichedData = await fetchDeveloperAppsGitHub(rawData) + const enrichedData = await fetchDeveloperAppsNpm(_enrichedData) const dataByCategory = transformDeveloperAppsData(enrichedData) const activeApp = enrichedData.find((app) => app.id === appId) diff --git a/app/[locale]/developers/apps/types.ts b/app/[locale]/developers/apps/types.ts index 0a5e25cd48f..c11bc9ae332 100644 --- a/app/[locale]/developers/apps/types.ts +++ b/app/[locale]/developers/apps/types.ts @@ -104,6 +104,7 @@ export type DeveloperApp = Omit & { href: string stargazers?: number lastUpdated?: string | number | Date | null + downloads?: number }[] } diff --git a/src/data-layer/fetchers/fetchDeveloperAppsNpmJs.ts b/src/data-layer/fetchers/fetchDeveloperAppsNpmJs.ts new file mode 100644 index 00000000000..f96debd9a5c --- /dev/null +++ b/src/data-layer/fetchers/fetchDeveloperAppsNpmJs.ts @@ -0,0 +1,173 @@ +// TODO: Set up data-layer integration +import type { DeveloperApp } from "../../../app/[locale]/developers/apps/types" + +// TODO: Move types to lib +type ParsedNpmUrl = { + packageName: string + originalHref: string +} + +function parseNpmUrl(href: string): ParsedNpmUrl | null { + try { + const url = new URL(href) + if (url.hostname !== "www.npmjs.com" && url.hostname !== "npmjs.com") { + return null + } + + const pathParts = url.pathname.split("/").filter(Boolean) + if (pathParts[0] !== "package") return null + + let packageName: string + if (pathParts[1]?.startsWith("@")) { + // Scoped package: @scope/name + packageName = `${pathParts[1]}/${pathParts[2]}` + } else { + // Unscoped package + packageName = pathParts[1] + } + + if (!packageName) return null + return { packageName, originalHref: href } + } catch { + return null + } +} + +async function fetchSinglePackageDownloads( + packageName: string +): Promise { + try { + const response = await fetch( + `https://api.npmjs.org/downloads/point/last-week/${encodeURIComponent(packageName)}` + ) + + if (!response.ok) return null + + const data = await response.json() + return data.downloads ?? null + } catch { + return null + } +} + +async function fetchBulkDownloads( + packageNames: string[] +): Promise> { + const results = new Map() + if (packageNames.length === 0) return results + + // Deduplicate package names + const uniquePackages = Array.from(new Set(packageNames)) + + // Separate scoped (@org/pkg) from unscoped packages + // Scoped packages don't work well with bulk API, fetch them individually + const scopedPackages = uniquePackages.filter((p) => p.startsWith("@")) + const unscopedPackages = uniquePackages.filter((p) => !p.startsWith("@")) + + // Fetch scoped packages individually (in parallel with concurrency limit) + const CONCURRENCY = 10 + for (let i = 0; i < scopedPackages.length; i += CONCURRENCY) { + const batch = scopedPackages.slice(i, i + CONCURRENCY) + const batchResults = await Promise.all( + batch.map(async (pkg) => ({ + pkg, + downloads: await fetchSinglePackageDownloads(pkg), + })) + ) + + for (const { pkg, downloads } of batchResults) { + if (downloads !== null) { + results.set(pkg, downloads) + } + } + } + + // Fetch unscoped packages in bulk + const BATCH_SIZE = 50 + for (let i = 0; i < unscopedPackages.length; i += BATCH_SIZE) { + const batch = unscopedPackages.slice(i, i + BATCH_SIZE) + const packageList = batch.join(",") + + try { + const response = await fetch( + `https://api.npmjs.org/downloads/point/last-week/${packageList}` + ) + + if (!response.ok) { + console.warn( + `npm downloads API returned ${response.status} for unscoped batch` + ) + continue + } + + const data = await response.json() + + // Handle single-package response: { downloads: number, package: string } + // vs multi-package response: { "pkg1": { downloads: n }, "pkg2": { downloads: m } } + if ("downloads" in data && "package" in data) { + results.set(data.package, data.downloads) + } else { + for (const [pkg, info] of Object.entries(data)) { + if (info && typeof info === "object" && "downloads" in info) { + results.set(pkg, (info as { downloads: number }).downloads) + } + } + } + } catch (err) { + console.warn(`Failed to fetch bulk npm downloads for batch ${i}:`, err) + } + } + + return results +} + +export async function fetchDeveloperAppsNpm( + appData: DeveloperApp[] +): Promise { + // Collect all unique npm URLs and their package names + const parsedUrls: ParsedNpmUrl[] = [] + const seenHrefs = new Set() + + for (const app of appData) { + for (const repo of app.repos) { + if (seenHrefs.has(repo.href)) continue + seenHrefs.add(repo.href) + + const parsed = parseNpmUrl(repo.href) + if (parsed) { + parsedUrls.push(parsed) + } + } + } + + if (parsedUrls.length === 0) { + return appData + } + + console.log(`Fetching npm downloads for ${parsedUrls.length} packages`) + + const packageNames = parsedUrls.map((p) => p.packageName) + const downloadsMap = await fetchBulkDownloads(packageNames) + + // Create lookup from original href to downloads + const hrefToDownloads = new Map() + for (const { packageName, originalHref } of parsedUrls) { + const downloads = downloadsMap.get(packageName) + if (downloads !== undefined) { + hrefToDownloads.set(originalHref, downloads) + } + } + + console.log( + `Successfully fetched npm downloads for ${hrefToDownloads.size} packages` + ) + + // Enrich the existing data with downloads + return appData.map((app) => ({ + ...app, + repos: app.repos.map((repo) => { + const downloads = hrefToDownloads.get(repo.href) + return downloads !== undefined ? { ...repo, downloads } : repo + }), + })) +} From 148ecea29efb5eb67a0c5e29066809a5698f3e4a Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Mon, 19 Jan 2026 22:30:40 -0800 Subject: [PATCH 18/74] patch: overflow scroll long descriptions --- .../developers/apps/_components/AppModalContents.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/[locale]/developers/apps/_components/AppModalContents.tsx b/app/[locale]/developers/apps/_components/AppModalContents.tsx index 429694fc986..831dfe73464 100644 --- a/app/[locale]/developers/apps/_components/AppModalContents.tsx +++ b/app/[locale]/developers/apps/_components/AppModalContents.tsx @@ -47,8 +47,10 @@ const AppModalContents = async ({ app }: { app: DeveloperApp }) => { className="lowercase" />
-

{app.description}

-
+

+ {app.description} +

+

{t("page-developers-apps-modal-links")}

{app.website && ( From 5b42181eeb28d2a79d3d9b559a75a13b6df9418a Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Mon, 19 Jan 2026 22:32:01 -0800 Subject: [PATCH 19/74] fix(ui): star/download count render --- .../apps/_components/AppModalContents.tsx | 24 ++++++++++++------- src/intl/en/page-developers-apps.json | 2 ++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/app/[locale]/developers/apps/_components/AppModalContents.tsx b/app/[locale]/developers/apps/_components/AppModalContents.tsx index 831dfe73464..d572ed9d9c3 100644 --- a/app/[locale]/developers/apps/_components/AppModalContents.tsx +++ b/app/[locale]/developers/apps/_components/AppModalContents.tsx @@ -8,7 +8,6 @@ import { ButtonLink } from "@/components/ui/buttons/Button" import { Tag, TagsInlineText } from "@/components/ui/tag" import { formatDate, getValidDate } from "@/lib/utils/date" -import { formatLargeNumber } from "@/lib/utils/numbers" import { isExternal } from "@/lib/utils/url" import { DeveloperApp } from "../types" @@ -76,8 +75,8 @@ const AppModalContents = async ({ app }: { app: DeveloperApp }) => { // TODO: Handle non-github/npmjs labels const label = href.replace(sanitizeRegExp, "") const date = getValidDate(lastUpdated) - const showStars = isGitHub && stargazers // && stargazers > 10 - const showDownloads = isNpm && downloads // && downloads > 10 + const showStars = isGitHub && !!stargazers + const showDownloads = isNpm && !!downloads return ( { {showStars && ( <> {" "} - + ({new Intl.NumberFormat(locale).format(stargazers)} - + ) )} {showDownloads && ( <> {" "} - - ({formatLargeNumber(downloads, locale)} + + ( + {new Intl.NumberFormat(locale, { + notation: "compact", + }).format(downloads)} - + ) )} diff --git a/src/intl/en/page-developers-apps.json b/src/intl/en/page-developers-apps.json index a11902c8945..f9606b1a1b8 100644 --- a/src/intl/en/page-developers-apps.json +++ b/src/intl/en/page-developers-apps.json @@ -37,6 +37,8 @@ "page-developers-apps-modal-social": "Social", "page-developers-apps-modal-website": "Website", "page-developers-apps-see-all": "See all", + "page-developers-apps-stats-downloads": "Weekly downloads", + "page-developers-apps-stats-stargazers": "GitHub stars", "page-developers-apps-subtitle": "Find the right tools faster and help elevate the developers who create the infrastructure our ecosystem relies on.", "page-developers-apps-tag-abi-encoding": "ABI encoding", "page-developers-apps-tag-account-abstraction": "Account abstraction", From c26512b3f91ff543bb0c400de1ef4c8fd9ac74cc Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 20 Jan 2026 12:52:21 -0800 Subject: [PATCH 20/74] fix: highlight tags/title colors, i18n category --- app/[locale]/developers/apps/constants.ts | 17 +-- app/[locale]/developers/apps/page.tsx | 138 ++++++++++++---------- 2 files changed, 84 insertions(+), 71 deletions(-) diff --git a/app/[locale]/developers/apps/constants.ts b/app/[locale]/developers/apps/constants.ts index 0481f5400b7..82526064b4b 100644 --- a/app/[locale]/developers/apps/constants.ts +++ b/app/[locale]/developers/apps/constants.ts @@ -9,6 +9,8 @@ import { Shield, } from "lucide-react" +import { TagProps } from "@/components/ui/tag" + import type { DeveloperAppCategorySlug } from "./types" export const DEV_APP_CATEGORY_SLUGS: Record = @@ -23,14 +25,15 @@ export const DEV_APP_CATEGORY_SLUGS: Record = } export const DEV_APP_CATEGORIES = [ - { slug: "interoperability", Icon: SendToBack }, - { slug: "transactions", Icon: ArrowLeftRight }, - { slug: "analytics", Icon: ChartSpline }, - { slug: "education", Icon: GraduationCap }, - { slug: "sdks", Icon: Package }, - { slug: "contracts", Icon: CodeXml }, - { slug: "security", Icon: Shield }, + { slug: "interoperability", Icon: SendToBack, tag: "accent-a" }, + { slug: "transactions", Icon: ArrowLeftRight, tag: "accent-b" }, + { slug: "analytics", Icon: ChartSpline, tag: "accent-c" }, + { slug: "education", Icon: GraduationCap, tag: "primary" }, + { slug: "sdks", Icon: Package, tag: "tag-green" }, + { slug: "contracts", Icon: CodeXml, tag: "tag-yellow" }, + { slug: "security", Icon: Shield, tag: "tag-red" }, ] as const satisfies { slug: string Icon: LucideIcon + tag: TagProps["status"] }[] diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/apps/page.tsx index a33de2d368b..65111beb8c9 100644 --- a/app/[locale]/developers/apps/page.tsx +++ b/app/[locale]/developers/apps/page.tsx @@ -20,7 +20,7 @@ import { } from "@/components/ui/edge-scroll-container" import { LinkBox, LinkOverlay } from "@/components/ui/link-box" import { Section } from "@/components/ui/section" -import { Tag, TagsInlineText } from "@/components/ui/tag" +import { Tag, TagProps, TagsInlineText } from "@/components/ui/tag" import { cn } from "@/lib/utils/cn" import { getMetadata } from "@/lib/utils/metadata" @@ -31,7 +31,7 @@ import { fetchDeveloperAppsNpm } from "@/data-layer/fetchers/fetchDeveloperAppsN import AppModalContents from "./_components/AppModalContents" import AppModalWrapper from "./_components/AppModalWrapper" -import { DEV_APP_CATEGORIES } from "./constants" +import { DEV_APP_CATEGORIES, DEV_APP_CATEGORY_SLUGS } from "./constants" import { transformDeveloperAppsData } from "./utils" import { routing } from "@/i18n/routing" @@ -73,72 +73,82 @@ const Page = async ({

{t("page-developers-apps-highlights")}

- {highlights.map((app) => ( - - { + const categorySlug = DEV_APP_CATEGORY_SLUGS[app.category] + const tagStyle: TagProps["status"] = + DEV_APP_CATEGORIES.find(({ slug }) => slug === categorySlug) + ?.tag || "tag" + return ( + - -
- - - - - {app.description} - -
-
- - {tCommon("item-logo", - + +
+ + + + + {app.description} + +
+
+ + {tCommon("item-logo", + -
- - {app.category} - - {app.name} - - t(`page-developers-apps-tag-${tag}`) - )} - max={3} // TODO: Confirm / sort? - variant="light" - className="lowercase" - /> +
+ + {t( + `page-developers-apps-category-${categorySlug}-title` + )} + + + {app.name} + + + t(`page-developers-apps-tag-${tag}`) + )} + max={3} // TODO: Confirm / sort? + variant="light" + className="lowercase" + /> +
-
-
- - - ))} + + + + ) + })}
From 65f7581ca53c950df09350d48dd34433222b15bb Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 20 Jan 2026 13:51:48 -0800 Subject: [PATCH 21/74] feat: implement dev tooling data-layer - create: orchestrating fetcher fetchDeveloperTools - refactor: sub-fetches as -BuidlGuidl, -GitHub and -NpmJs - update: mock data - feat: integrate all dev tooling data fetching and enrichment with trigger.dev processes - fixes: delay in modal open/close and redundant data fetching --- .../developers/apps/[category]/page.tsx | 16 +- app/[locale]/developers/apps/page.tsx | 16 +- .../fetchers/fetchDeveloperTools.ts | 34 + ...ps.ts => fetchDeveloperToolsBuidlGuidl.ts} | 8 +- ...GitHub.ts => fetchDeveloperToolsGitHub.ts} | 2 +- ...psNpmJs.ts => fetchDeveloperToolsNpmJs.ts} | 2 +- src/data-layer/index.ts | 5 +- ...r-apps.json => fetch-developer-tools.json} | 3957 ++++++++++++----- src/data-layer/tasks.ts | 6 +- src/lib/data/index.ts | 6 +- 10 files changed, 2895 insertions(+), 1157 deletions(-) create mode 100644 src/data-layer/fetchers/fetchDeveloperTools.ts rename src/data-layer/fetchers/{fetchDeveloperApps.ts => fetchDeveloperToolsBuidlGuidl.ts} (68%) rename src/data-layer/fetchers/{fetchDeveloperAppsGitHub.ts => fetchDeveloperToolsGitHub.ts} (98%) rename src/data-layer/fetchers/{fetchDeveloperAppsNpmJs.ts => fetchDeveloperToolsNpmJs.ts} (99%) rename src/data-layer/mocks/{fetch-developer-apps.json => fetch-developer-tools.json} (72%) diff --git a/app/[locale]/developers/apps/[category]/page.tsx b/app/[locale]/developers/apps/[category]/page.tsx index 26a4acc46b8..c11b6b49a09 100644 --- a/app/[locale]/developers/apps/[category]/page.tsx +++ b/app/[locale]/developers/apps/[category]/page.tsx @@ -20,10 +20,6 @@ import { Tag, TagsInlineText } from "@/components/ui/tag" import { cn } from "@/lib/utils/cn" import { getMetadata } from "@/lib/utils/metadata" -import { fetchDeveloperApps } from "@/data-layer/fetchers/fetchDeveloperApps" -import { fetchDeveloperAppsGitHub } from "@/data-layer/fetchers/fetchDeveloperAppsGitHub" -import { fetchDeveloperAppsNpm } from "@/data-layer/fetchers/fetchDeveloperAppsNpmJs" - import AppModalContents from "../_components/AppModalContents" import AppModalWrapper from "../_components/AppModalWrapper" import { DEV_APP_CATEGORIES } from "../constants" @@ -31,6 +27,7 @@ import type { DeveloperAppCategorySlug } from "../types" import { transformDeveloperAppsData } from "../utils" import { routing } from "@/i18n/routing" +import { getDeveloperToolsData } from "@/lib/data" const Page = async ({ params, @@ -46,18 +43,17 @@ const Page = async ({ const t = await getTranslations({ locale, namespace: "page-developers-apps" }) const tCommon = await getTranslations({ locale, namespace: "common" }) - // const appsData = await getDeveloperAppsData() // TODO: data-layer - const rawData = await fetchDeveloperApps() // TODO: Trim mock data - if (!rawData) throw Error("No developer apps data available") - const _enrichedData = await fetchDeveloperAppsGitHub(rawData) - const enrichedData = await fetchDeveloperAppsNpm(_enrichedData) + const enrichedData = await getDeveloperToolsData() + if (!enrichedData) throw Error("No developer apps data available") const dataByCategory = transformDeveloperAppsData(enrichedData) const categoryData = dataByCategory[category] const activeApp = enrichedData.find((app) => app.id === appId) const featuredNames = ["ZK Email", "Hardhat", "Updraft"] // TODO: determine logic, make DRY - const highlights = rawData.filter(({ name }) => featuredNames.includes(name)) + const highlights = enrichedData.filter(({ name }) => + featuredNames.includes(name) + ) return ( <> diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/apps/page.tsx index 65111beb8c9..cf0d03ef212 100644 --- a/app/[locale]/developers/apps/page.tsx +++ b/app/[locale]/developers/apps/page.tsx @@ -25,16 +25,13 @@ import { Tag, TagProps, TagsInlineText } from "@/components/ui/tag" import { cn } from "@/lib/utils/cn" import { getMetadata } from "@/lib/utils/metadata" -import { fetchDeveloperApps } from "@/data-layer/fetchers/fetchDeveloperApps" -import { fetchDeveloperAppsGitHub } from "@/data-layer/fetchers/fetchDeveloperAppsGitHub" -import { fetchDeveloperAppsNpm } from "@/data-layer/fetchers/fetchDeveloperAppsNpmJs" - import AppModalContents from "./_components/AppModalContents" import AppModalWrapper from "./_components/AppModalWrapper" import { DEV_APP_CATEGORIES, DEV_APP_CATEGORY_SLUGS } from "./constants" import { transformDeveloperAppsData } from "./utils" import { routing } from "@/i18n/routing" +import { getDeveloperToolsData } from "@/lib/data" const Page = async ({ params, @@ -50,17 +47,16 @@ const Page = async ({ const t = await getTranslations({ locale, namespace: "page-developers-apps" }) const tCommon = await getTranslations({ locale, namespace: "common" }) - // const appsData = await getDeveloperAppsData() // TODO: data-layer - const rawData = await fetchDeveloperApps() // TODO: Trim mock data - if (!rawData) throw Error("No developer apps data available") - const _enrichedData = await fetchDeveloperAppsGitHub(rawData) - const enrichedData = await fetchDeveloperAppsNpm(_enrichedData) + const enrichedData = await getDeveloperToolsData() + if (!enrichedData) throw Error("No developer apps data available") const dataByCategory = transformDeveloperAppsData(enrichedData) const activeApp = enrichedData.find((app) => app.id === appId) const featuredNames = ["ZK Email", "Hardhat", "Updraft"] // TODO: determine logic, make DRY - const highlights = rawData.filter(({ name }) => featuredNames.includes(name)) + const highlights = enrichedData.filter(({ name }) => + featuredNames.includes(name) + ) return ( <> diff --git a/src/data-layer/fetchers/fetchDeveloperTools.ts b/src/data-layer/fetchers/fetchDeveloperTools.ts new file mode 100644 index 00000000000..d8ef77348f8 --- /dev/null +++ b/src/data-layer/fetchers/fetchDeveloperTools.ts @@ -0,0 +1,34 @@ +import type { DeveloperApp } from "../../../app/[locale]/developers/apps/types" + +import { fetchDeveloperToolsBuidlGuidl } from "./fetchDeveloperToolsBuidlGuidl" +import { fetchDeveloperToolsGitHub } from "./fetchDeveloperToolsGitHub" +import { fetchDeveloperToolsNpmJs } from "./fetchDeveloperToolsNpmJs" + +/** + * Fetches and enriches developer tools data. + * + * This orchestrates three data sources: + * 1. BuidlGuidl Developer-Tooling repository (base data) + * 2. GitHub GraphQL API (stargazers, last commit dates) + * 3. npm API (download counts) + * + * Returns fully enriched DeveloperApp[] ready for consumption. + */ +export async function fetchDeveloperTools(): Promise { + console.log("Starting developer tools data enrichment pipeline") + + // Step 1: Fetch base data from BuidlGuidl + const rawData = await fetchDeveloperToolsBuidlGuidl() + console.log(`Fetched ${rawData.length} developer tools from BuidlGuidl`) + + // Step 2: Enrich with GitHub data (stars, last commit) + const withGitHub = await fetchDeveloperToolsGitHub(rawData) + console.log("Enriched with GitHub data") + + // Step 3: Enrich with npm data (download counts) + const enrichedData = await fetchDeveloperToolsNpmJs(withGitHub) + console.log("Enriched with npm data") + + console.log("Developer tools data enrichment complete") + return enrichedData +} diff --git a/src/data-layer/fetchers/fetchDeveloperApps.ts b/src/data-layer/fetchers/fetchDeveloperToolsBuidlGuidl.ts similarity index 68% rename from src/data-layer/fetchers/fetchDeveloperApps.ts rename to src/data-layer/fetchers/fetchDeveloperToolsBuidlGuidl.ts index 2057a84bcfc..a722d8173aa 100644 --- a/src/data-layer/fetchers/fetchDeveloperApps.ts +++ b/src/data-layer/fetchers/fetchDeveloperToolsBuidlGuidl.ts @@ -1,10 +1,12 @@ import { DeveloperAppsResponse } from "@/lib/types" -export async function fetchDeveloperApps(): Promise { +export async function fetchDeveloperToolsBuidlGuidl(): Promise< + DeveloperAppsResponse[] +> { const url = "https://raw.githubusercontent.com/BuidlGuidl/Developer-Tooling/refs/heads/main/output/results.json" - console.log("Starting GitHub developer apps data fetch") + console.log("Starting BuidlGuidl developer tooling data fetch") const response = await fetch(url) @@ -17,7 +19,7 @@ export async function fetchDeveloperApps(): Promise { const json: DeveloperAppsResponse[] = await response.json() - console.log("Successfully fetched GitHub developer apps data") + console.log("Successfully fetched BuidlGuidl developer tooling data") return json } diff --git a/src/data-layer/fetchers/fetchDeveloperAppsGitHub.ts b/src/data-layer/fetchers/fetchDeveloperToolsGitHub.ts similarity index 98% rename from src/data-layer/fetchers/fetchDeveloperAppsGitHub.ts rename to src/data-layer/fetchers/fetchDeveloperToolsGitHub.ts index f980c5124ea..b30ded67692 100644 --- a/src/data-layer/fetchers/fetchDeveloperAppsGitHub.ts +++ b/src/data-layer/fetchers/fetchDeveloperToolsGitHub.ts @@ -92,7 +92,7 @@ async function fetchReposBatch( return results } -export async function fetchDeveloperAppsGitHub( +export async function fetchDeveloperToolsGitHub( appData: DeveloperAppsResponse[] ): Promise { // Collect all unique repo URLs diff --git a/src/data-layer/fetchers/fetchDeveloperAppsNpmJs.ts b/src/data-layer/fetchers/fetchDeveloperToolsNpmJs.ts similarity index 99% rename from src/data-layer/fetchers/fetchDeveloperAppsNpmJs.ts rename to src/data-layer/fetchers/fetchDeveloperToolsNpmJs.ts index f96debd9a5c..35229c679d4 100644 --- a/src/data-layer/fetchers/fetchDeveloperAppsNpmJs.ts +++ b/src/data-layer/fetchers/fetchDeveloperToolsNpmJs.ts @@ -121,7 +121,7 @@ async function fetchBulkDownloads( return results } -export async function fetchDeveloperAppsNpm( +export async function fetchDeveloperToolsNpmJs( appData: DeveloperApp[] ): Promise { // Collect all unique npm URLs and their package names diff --git a/src/data-layer/index.ts b/src/data-layer/index.ts index 3dcfc509b9b..55dbdd0d7a3 100644 --- a/src/data-layer/index.ts +++ b/src/data-layer/index.ts @@ -4,7 +4,6 @@ import type { BlockspaceData, Commit, CommunityPick, - DeveloperAppsResponse, EventItem, GHIssue, GithubRepoData, @@ -16,6 +15,8 @@ import type { } from "@/lib/types" import type { CommunityEventsReturnType } from "@/lib/interfaces" +import type { DeveloperApp } from "../../app/[locale]/developers/apps/types" + import type { BeaconChainData } from "./fetchers/fetchBeaconChain" import type { CoinGeckoCoinMarketResponse } from "./fetchers/fetchStablecoinsData" import { get } from "./storage" @@ -44,4 +45,4 @@ export const getStablecoinsData = () => get(KEYS.ST export const getTotalEthStakedData = () => get(KEYS.TOTAL_ETH_STAKED) export const getTotalValueLockedData = () => get(KEYS.TOTAL_VALUE_LOCKED) export const getEventsData = () => get(KEYS.EVENTS) -export const getDeveloperAppsData = () => get(KEYS.DEVELOPER_APPS) +export const getDeveloperToolsData = () => get(KEYS.DEVELOPER_APPS) diff --git a/src/data-layer/mocks/fetch-developer-apps.json b/src/data-layer/mocks/fetch-developer-tools.json similarity index 72% rename from src/data-layer/mocks/fetch-developer-apps.json rename to src/data-layer/mocks/fetch-developer-tools.json index 4f4d4c77f31..f650faa78da 100644 --- a/src/data-layer/mocks/fetch-developer-apps.json +++ b/src/data-layer/mocks/fetch-developer-tools.json @@ -6,16 +6,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/9d83fea6-88b8-4985-b0e9-4a675be218df.png", "banner_url": "https://storage.googleapis.com/op-atlas/763ce438-66da-4384-a634-9108e26a63a4.png", "twitter": null, - "repos": [ - "https://github.com/mcpdotdirect/evm-mcp-server" - ], "tags": [ "mcp-server", "cli", "transaction-management" ], "website": "https://mcp.direct", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/mcpdotdirect/evm-mcp-server", + "stargazers": 357, + "lastUpdated": "2025-11-26T17:09:21Z" + } + ] }, { "id": "0x2b77364f9d227b9b41ed84281857dcf016685e73ba909071a1b93135a4a0b7d9", @@ -24,15 +28,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/c0c216e0-29b0-4330-9b4f-9addc53c56d3.png", "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/mhw0/libethc" - ], "tags": [ "transaction-signing", "abi-encoding" ], "website": "https://mhw0.github.io/libethc/", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/mhw0/libethc", + "stargazers": 70, + "lastUpdated": "2025-09-20T03:40:37Z" + } + ] }, { "id": "0xd7a4742a0a40480ce176892bb619295d2cdd357d7ad09411beaff6278014c191", @@ -41,14 +49,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/8eb6f205-cdaf-4ca2-8f9c-228183d42ede.png", "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/polareth/evmstate" - ], "tags": [ "analytics", "storage-layout" ], - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/polareth/evmstate", + "stargazers": 25, + "lastUpdated": "2025-07-24T21:40:21Z" + } + ] }, { "id": "0x926606219b6876c28d7185401763b7492decd48a7e89a2fd27de9dbf176507ad", @@ -57,9 +69,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/9bcf0bba-0978-47ab-b553-c58778a00775.png", "banner_url": "https://storage.googleapis.com/op-atlas/8605a173-9360-4914-a1ac-41ac54c076c7.png", "twitter": null, - "repos": [ - "https://github.com/ngmisl/etherml" - ], "tags": [ "cli", "wallet", @@ -67,7 +76,14 @@ "encryption" ], "website": "https://github.com/ngmisl/etherml", - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/ngmisl/etherml", + "stargazers": 6, + "lastUpdated": "2025-09-08T19:15:27Z" + } + ] }, { "id": "0x2d90d9565ef127727845637425880545cfebe0931160ce25afe929f8ab415706", @@ -76,15 +92,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/f049eb6e-e7f5-4730-b0a2-e02a57ae2707.png", "banner_url": "https://storage.googleapis.com/op-atlas/e0686fc6-7ee1-4543-b0fc-1285320b9462.png", "twitter": "https://x.com/tevmtools", - "repos": [ - "https://github.com/evmts/tevm-monorepo" - ], "tags": [ "frontend", "user-experience" ], "website": "https://node.tevm.sh", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/evmts/tevm-monorepo", + "stargazers": 429, + "lastUpdated": "2026-01-13T12:05:58Z" + } + ] }, { "id": "0x9dc9d9b8f79644cbe8634b022d4dd5ecaf4e438a71fe26256598f6e0d85a33a0", @@ -93,15 +113,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/17f44321-04a1-49d8-8702-1c154fa6c560.png", "banner_url": "https://storage.googleapis.com/op-atlas/a4f2569e-59a0-4265-8976-6e61beacde96.png", "twitter": null, - "repos": [ - "https://github.com/KENILSHAHH/superSDK" - ], "tags": [ "cross-chain", "sdk" ], "website": "https://superbeam.gitbook.io/superbeam", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/KENILSHAHH/superSDK", + "stargazers": 0, + "lastUpdated": "2025-07-10T10:31:15Z" + } + ] }, { "id": "0x6f8f610667400044907494c879b717e806a03bf519dcfd786edc7f2fa61d6db8", @@ -110,21 +134,49 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/6e5db839-6c5b-4b51-902f-5dc45afd7ea9.png", "banner_url": "https://storage.googleapis.com/op-atlas/6d09c3cd-91ff-4035-a736-7fcd9e68f98c.png", "twitter": "https://x.com/open_rpc", - "repos": [ - "https://github.com/open-rpc/server-js", - "https://github.com/open-rpc/tools", - "https://github.com/open-rpc/generator", - "https://github.com/open-rpc/client-js", - "https://github.com/open-rpc/schema-utils-js", - "https://github.com/open-rpc/spec", - "https://github.com/open-rpc/meta-schema" - ], "tags": [ "json-rpc", "cli" ], "website": "https://open-rpc.org", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/open-rpc/server-js", + "stargazers": 52, + "lastUpdated": "2025-07-31T03:28:04Z" + }, + { + "href": "https://github.com/open-rpc/tools", + "stargazers": 7, + "lastUpdated": "2025-07-11T21:58:28Z" + }, + { + "href": "https://github.com/open-rpc/generator", + "stargazers": 95, + "lastUpdated": "2025-10-22T05:54:12Z" + }, + { + "href": "https://github.com/open-rpc/client-js", + "stargazers": 137, + "lastUpdated": "2025-10-29T16:58:20Z" + }, + { + "href": "https://github.com/open-rpc/schema-utils-js", + "stargazers": 27, + "lastUpdated": "2025-07-25T23:22:18Z" + }, + { + "href": "https://github.com/open-rpc/spec", + "stargazers": 192, + "lastUpdated": "2025-07-25T23:13:13Z" + }, + { + "href": "https://github.com/open-rpc/meta-schema", + "stargazers": 34, + "lastUpdated": "2025-07-31T03:21:56Z" + } + ] }, { "id": "0x66818708d041152b7f9b45ee48e56ab6507ad493955fd256b62d7c9d8a27724f", @@ -133,19 +185,39 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/15cb5d1e-c868-43ac-8d7e-db4ef3fbc0f9.png", "banner_url": "https://storage.googleapis.com/op-atlas/99fa13be-c8ef-4df9-980e-58736e3ddc29.png", "twitter": "https://x.com/0xbloctopus", - "repos": [ - "https://github.com/LZeroAnalytics/lzero-reth", - "https://github.com/LZeroAnalytics/ethereum-package", - "https://github.com/LZeroAnalytics/blockscout-package", - "https://github.com/LZeroAnalytics/chainlink-node-package", - "https://github.com/LZeroAnalytics/layerzero-package" - ], "tags": [ "cross-chain", "docker" ], "website": "https://www.bloctopus.io", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/0xBloctopus/lzero-reth", + "stargazers": 3, + "lastUpdated": "2025-09-11T15:20:34Z" + }, + { + "href": "https://github.com/0xBloctopus/ethereum-package", + "stargazers": 8, + "lastUpdated": "2025-09-26T17:25:09Z" + }, + { + "href": "https://github.com/0xBloctopus/blockscout-package", + "stargazers": 5, + "lastUpdated": "2025-09-11T15:19:00Z" + }, + { + "href": "https://github.com/0xBloctopus/chainlink-node-package", + "stargazers": 4, + "lastUpdated": "2025-09-11T15:15:39Z" + }, + { + "href": "https://github.com/0xBloctopus/layerzero-package", + "stargazers": 7, + "lastUpdated": "2025-09-11T15:17:36Z" + } + ] }, { "id": "0x56ce7cbc27852a8d8ef5869dc9033a215c8893f799468f61527dacb9f92be790", @@ -154,15 +226,23 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/60d98a8f-6f96-4a29-a65c-50dfc3a7828b.png", "banner_url": "https://storage.googleapis.com/op-atlas/40039eb5-bcc3-4af4-a975-7022d660164f.png", "twitter": null, - "repos": [ - "https://github.com/alloy-rs/op-alloy", - "https://github.com/alloy-rs/alloy" - ], "tags": [ "json-rpc" ], "website": "https://alloy.rs/", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/alloy-rs/op-alloy", + "stargazers": 83, + "lastUpdated": "2025-12-10T15:50:18Z" + }, + { + "href": "https://github.com/alloy-rs/alloy", + "stargazers": 1201, + "lastUpdated": "2026-01-20T19:36:17Z" + } + ] }, { "id": "0xeef42373d10554d65aba9e6deb8333a4eddebba829e0afea0dc93e32d8075d2d", @@ -171,9 +251,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/e6a6dd9b-4ace-4187-8408-0e5729bb0265.png", "banner_url": "https://storage.googleapis.com/op-atlas/eee0738d-3735-42c8-8802-93b22a041803.png", "twitter": "x.com/rv_inc", - "repos": [ - "https://github.com/runtimeverification/ercx-tests" - ], "tags": [ "foundry", "security", @@ -181,7 +258,14 @@ "runtime-verification" ], "website": "ercx.runtimeverification.com", - "category": "Security, Testing & Formal Verification" + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/runtimeverification/ercx-tests", + "stargazers": 35, + "lastUpdated": "2025-07-04T12:23:27Z" + } + ] }, { "id": "0x738c0967c0f70a0a78d8794dcf2c40540f60ea9568e163dd5826b85e8e2a9a79", @@ -190,18 +274,34 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/ba508a79-4a21-45fc-b3e3-5ede1a80fb6b.png", "banner_url": "https://storage.googleapis.com/op-atlas/96e7fcd9-75e3-4e40-98c5-0c5ae56c6578.png", "twitter": "https://x.com/ensobuild", - "repos": [ - "https://github.com/EnsoBuild/Uniswap-migrator", - "https://github.com/EnsoBuild/shortcuts-client-contracts", - "https://github.com/EnsoBuild/sdk-ts", - "https://github.com/EnsoBuild/shortcuts-widget" - ], "tags": [ "cross-chain", "transaction-optimization" ], "website": "enso.build", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/EnsoBuild/Uniswap-migrator", + "stargazers": 0, + "lastUpdated": "2025-10-20T13:19:17Z" + }, + { + "href": "https://github.com/EnsoBuild/shortcuts-client-contracts", + "stargazers": 1, + "lastUpdated": "2026-01-20T09:52:23Z" + }, + { + "href": "https://github.com/EnsoBuild/sdk-ts", + "stargazers": 2, + "lastUpdated": "2025-12-02T08:08:28Z" + }, + { + "href": "https://github.com/EnsoBuild/shortcuts-widget", + "stargazers": 6, + "lastUpdated": "2025-11-27T13:13:20Z" + } + ] }, { "id": "0x414ffb06789667ba95546e05e0456445145d3de23b05b3a8ce051cbc142bfb3f", @@ -210,13 +310,17 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/peterferguson/react-native-passkeys" - ], "tags": [ "authentication" ], - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/peterferguson/react-native-passkeys", + "stargazers": 135, + "lastUpdated": "2025-11-04T09:57:14Z" + } + ] }, { "id": "0x696c9b46af5eeaa2fcfa86f23da23ed1ce7938df67d90d422e6ba7ee2604b512", @@ -225,9 +329,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/1fdf287a-8ec4-4e15-a81d-1e63b902662b.png", "banner_url": "https://storage.googleapis.com/op-atlas/5b622e91-2107-4d63-87b7-9aeb42d55d86.png", "twitter": null, - "repos": [ - "https://github.com/ethernautdao/ethernaut-cli" - ], "tags": [ "cli", "hardhat", @@ -235,7 +336,14 @@ "developer-experience" ], "website": "https://ethernaut-app.vercel.app/", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/ethernautdao/ethernaut-cli", + "stargazers": 37, + "lastUpdated": "2025-05-26T16:51:40Z" + } + ] }, { "id": "0x5200a7351f8d195401dc04631fb83e4836f73a2794f316b2739c03807f30a78b", @@ -244,15 +352,19 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/eth-brownie/brownie" - ], "tags": [ "cli", "debugging-tools" ], "website": "https://github.com/eth-brownie/brownie", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/eth-brownie/brownie", + "stargazers": 2729, + "lastUpdated": "2026-01-14T06:57:54Z" + } + ] }, { "id": "0xc850d11fe786d1168bfeda108721101427dd5425d9d9e6595c35573f7616e940", @@ -261,14 +373,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/b2bd0510-b0d6-436e-a126-de05026e9418.png", "banner_url": "https://storage.googleapis.com/op-atlas/dde6090a-600a-418b-be38-5ea73111c407.png", "twitter": "https://x.com/daimopay", - "repos": [ - "https://github.com/daimo-eth/pay" - ], "tags": [ "cross-chain" ], "website": "https://pay.daimo.com/", - "category": "Cross-Chain & Interoperability" + "category": "Cross-Chain & Interoperability", + "repos": [ + { + "href": "https://github.com/daimo-eth/pay", + "stargazers": 18, + "lastUpdated": "2026-01-20T05:09:55Z" + } + ] }, { "id": "0xf9c5d092fac6ad924253d685cc7ba21d4e519813e673a3a8300f33cb3a6b4e06", @@ -277,14 +393,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/30fb3451-049c-4904-a109-d3c06004a731.png", "banner_url": "https://storage.googleapis.com/op-atlas/09a998c5-5217-4937-b2c8-d994e5cfe1c7.png", "twitter": "https://x.com/nftscan_com", - "repos": [ - "https://github.com/nftscan-official/nftscan-api-js-sdk" - ], "tags": [ "erc721" ], "website": "https://www.nftscan.com/", - "category": "Data, Analytics & Tracing" + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/nftscan-official/nftscan-api-js-sdk", + "stargazers": 18, + "lastUpdated": "2025-06-13T06:21:00Z" + } + ] }, { "id": "0x8af71ece7f50d6962b589b19854ceac72b81e5f5b3014637b262c33809d5a395", @@ -293,9 +413,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/aab1bec1-5b08-4727-a5c2-f8d0dfbe0ed9.png", "banner_url": "https://storage.googleapis.com/op-atlas/0204f6f1-2d6a-443b-bd9e-afb88c23f2e3.png", "twitter": "https://x.com/rv_inc", - "repos": [ - "https://github.com/runtimeverification/evm-semantics" - ], "tags": [ "security", "education", @@ -306,7 +423,14 @@ "runtime-verification", "vyper" ], - "category": "Security, Testing & Formal Verification" + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/runtimeverification/evm-semantics", + "stargazers": 554, + "lastUpdated": "2025-12-16T17:45:27Z" + } + ] }, { "id": "0x4562c0630907577f433cad78c7e2cc03349d918b6c14ef982f11a2678f5999ad", @@ -315,9 +439,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/66656b6d-5f9d-46f6-b8f0-67eb23ce9db9.png", "banner_url": "https://storage.googleapis.com/op-atlas/f22dd5f4-39c2-46d4-b701-85355469df9c.png", "twitter": null, - "repos": [ - "https://github.com/foundry-rs/foundry" - ], "tags": [ "cli", "foundry", @@ -327,7 +448,14 @@ "fuzz-testing", "performance-optimization" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/foundry-rs/foundry", + "stargazers": 10047, + "lastUpdated": "2026-01-20T17:57:52Z" + } + ] }, { "id": "0x35295108e0c7b4625d650fbdabd4888417782539f56159d39ac2f0e2411f607b", @@ -336,16 +464,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/6c0103eb-14e1-4578-831b-d5e85c017831.png", "banner_url": "https://storage.googleapis.com/op-atlas/cec480f1-b828-424a-ae01-9984ebdc2eb5.png", "twitter": "https://x.com/KurtosisTech", - "repos": [ - "https://github.com/kurtosis-tech/kurtosis" - ], "tags": [ "docker", "cli", "testing" ], "website": "https://www.kurtosis.com", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/kurtosis-tech/kurtosis", + "stargazers": 520, + "lastUpdated": "2026-01-14T15:57:47Z" + } + ] }, { "id": "0x85af258d3fae6bbd2e14ffa8f5b73b64e34b7f8efe685c40134c3f54774e8d6c", @@ -354,9 +486,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/c9083120-f920-426d-a33c-37ad6f5b3c3f.png", "banner_url": "https://storage.googleapis.com/op-atlas/62d53176-085e-4084-9112-f05f62b536db.png", "twitter": "https://x.com/etherspot", - "repos": [ - "https://github.com/etherspot/skandha" - ], "tags": [ "bundler", "transaction-management", @@ -365,7 +494,14 @@ "account-abstraction" ], "website": "https://etherspot.io/skandha/", - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/etherspot/skandha", + "stargazers": 610, + "lastUpdated": "2026-01-20T12:53:03Z" + } + ] }, { "id": "0x1e7a1f9763d25b6844567a7133b1005ef6ed785642a75229acf1b9b25202a5f3", @@ -374,14 +510,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/bc82b1d5-dad6-496a-af01-475797e53e34.png", "banner_url": "https://storage.googleapis.com/op-atlas/75c707be-ff55-41d7-9ef0-7cfcdef536ea.png", "twitter": "https://x.com/erpc", - "repos": [ - "https://github.com/erpc/erpc" - ], "tags": [ "frontend", "indexing" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/erpc/erpc", + "stargazers": 636, + "lastUpdated": "2026-01-20T16:11:16Z" + } + ] }, { "id": "0x2866fcc8ea2ad6cc691b8367023c08ba84a34a14685b0154ba4601b7d4981069", @@ -390,16 +530,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/09a4acff-98eb-4c73-925e-7403d7678163.png", "banner_url": "https://storage.googleapis.com/op-atlas/9b428229-b1e5-4f3a-b7f9-d312566a5fcd.png", "twitter": null, - "repos": [ - "https://github.com/miguelmota/go-ethereum-hdwallet" - ], "tags": [ "wallet", "transaction-signing", "cli" ], "website": "https://github.com/miguelmota/go-ethereum-hdwallet", - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/miguelmota/go-ethereum-hdwallet", + "stargazers": 549, + "lastUpdated": "2025-04-27T19:43:22Z" + } + ] }, { "id": "0xa873dcdcc84e0022edd2f7d5cc8646667b87bf06609d506cd8e39dbd7412fa59", @@ -408,16 +552,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/92c30ad3-b419-4f74-a24c-08bdff63059b.png", "banner_url": null, "twitter": "", - "repos": [ - "https://github.com/PraneshASP/foundry-mcp-server" - ], "tags": [ "cli", "foundry", "mcp-server", "solidity-development" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/PraneshASP/foundry-mcp-server", + "stargazers": 237, + "lastUpdated": "2026-01-17T15:25:55Z" + } + ] }, { "id": "0xcd032b75396f45f1ef82c8a38142352afa6071fbcd840480408e10e2aab9006d", @@ -426,12 +574,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/d5818777-1f8b-40bd-885e-22a892d7f7f7.png", "banner_url": "https://storage.googleapis.com/op-atlas/e0127983-0358-42cb-95f7-396d8a86346a.png", "twitter": "https://x.com/builders_garden", - "repos": [ - "https://github.com/builders-garden/base-minikit-starter", - "https://github.com/builders-garden/farcaster-miniapp-starter", - "https://github.com/builders-garden/frames-v2-starter", - "https://github.com/builders-garden/miniapp-next-template" - ], "tags": [ "education", "farcaster", @@ -441,7 +583,29 @@ "analytics" ], "website": "https://www.builders.garden/", - "category": "Education & Community Resources" + "category": "Education & Community Resources", + "repos": [ + { + "href": "https://github.com/builders-garden/base-minikit-starter", + "stargazers": 43, + "lastUpdated": "2025-05-25T15:44:54Z" + }, + { + "href": "https://github.com/builders-garden/farcaster-miniapp-starter", + "stargazers": 49, + "lastUpdated": "2025-12-06T15:23:06Z" + }, + { + "href": "https://github.com/builders-garden/frames-v2-starter", + "stargazers": 30, + "lastUpdated": "2025-04-22T13:15:16Z" + }, + { + "href": "https://github.com/builders-garden/miniapp-next-template", + "stargazers": 28, + "lastUpdated": "2025-12-16T15:04:19Z" + } + ] }, { "id": "0xc6cac7cd3793888032cc8a9e5aef92550beeec2598f86f1ec6972ffd5b82a990", @@ -450,15 +614,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/0e3be68b-be6b-4833-b0ed-b53dc89a8d22.png", "banner_url": null, "twitter": "https://x.com/prettiersol", - "repos": [ - "https://github.com/prettier-solidity/prettier-plugin-solidity" - ], "tags": [ "solidity", "code-quality" ], "website": "https://github.com/prettier-solidity/prettier-plugin-solidity", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/prettier-solidity/prettier-plugin-solidity", + "stargazers": 748, + "lastUpdated": "2026-01-20T15:24:32Z" + } + ] }, { "id": "0xa790f0641e8d72abc88efd13ca215e2dc7e736a4a59ca5a9e0020af29d6297f2", @@ -467,16 +635,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/eebeffeb-5b4e-4e8f-a8d9-09718da38b40.png", "banner_url": null, "twitter": "https://x.com/trailofbits", - "repos": [ - "https://github.com/crytic/properties" - ], "tags": [ "security", "erc721", "fuzz-testing", "solidity" ], - "category": "Security, Testing & Formal Verification" + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/crytic/properties", + "stargazers": 356, + "lastUpdated": "2025-11-29T16:59:34Z" + } + ] }, { "id": "0x2a04bac7482169a929fd70444bbfac10654d0588e022db7527566dbfc307d2e9", @@ -485,14 +657,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/de442005-7eb7-45d9-9d69-c1f1548e855f.png", "banner_url": null, "twitter": "https://x.com/trailofbits", - "repos": [ - "https://github.com/crytic/solc-select" - ], "tags": [ "cli", "solidity" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/crytic/solc-select", + "stargazers": 803, + "lastUpdated": "2026-01-15T18:30:50Z" + } + ] }, { "id": "0xb9996d35862a7c60282da2adf3447f043580f586fcb702ff6869896d15ef6344", @@ -501,16 +677,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/69e9b03e-47d3-4770-8415-3ae65da044a4.png", "banner_url": null, "twitter": "https://x.com/trailofbits", - "repos": [ - "https://github.com/crytic/medusa" - ], "tags": [ "security", "governance", "analytics", "fuzz-testing" ], - "category": "Security, Testing & Formal Verification" + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/crytic/medusa", + "stargazers": 443, + "lastUpdated": "2026-01-20T21:50:38Z" + } + ] }, { "id": "0xdc3dce33fd5fb50cf932586d4257456ddf5040ba0955d97641646504c73dbd13", @@ -519,9 +699,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/27ad6768-163c-4cc3-bd3e-ba8fd3ef5f50.png", "banner_url": "https://storage.googleapis.com/op-atlas/1276f443-c160-4db0-ab75-33e3e01e3a47.png", "twitter": "https://x.com/trailofbits", - "repos": [ - "https://github.com/crytic/slither" - ], "tags": [ "security", "static-analysis", @@ -529,7 +706,14 @@ "vyper", "continuous-integration" ], - "category": "Security, Testing & Formal Verification" + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/crytic/slither", + "stargazers": 6093, + "lastUpdated": "2026-01-20T18:39:50Z" + } + ] }, { "id": "0x7cbd306b4b54416b83eb723a79b88d09554e245b1d7b29e7e4b7958ca1011d1f", @@ -538,16 +722,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/3ac79cce-16e1-4a59-9557-ee1f85793674.png", "banner_url": "https://storage.googleapis.com/op-atlas/616a8719-4bc1-4e7d-b50e-d56e45019f0b.png", "twitter": "https://twitter.com/ethdebug", - "repos": [ - "https://github.com/ethdebug/format" - ], "tags": [ "education", "debugging-tools", "type-safe" ], "website": "https://ethdebug.github.io/format/", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/ethdebug/format", + "stargazers": 76, + "lastUpdated": "2026-01-15T21:27:42Z" + } + ] }, { "id": "0xcdeb1723ae43478e77b36f2b6dea33f9485963a66ca951408faad33e13452e10", @@ -556,15 +744,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/4756e689-18df-4d2f-aea1-abdf6547ee51.png", "banner_url": "https://storage.googleapis.com/op-atlas/7ad77d50-64a1-43a4-a494-e49db0974dde.png", "twitter": "https://x.com/wakeuplabs", - "repos": [ - "https://github.com/wakeuplabs-io/op-ruaas" - ], "tags": [ "cli", "scalability" ], "website": "https://www.wakeuplabs.io/", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/wakeuplabs-io/op-ruaas", + "stargazers": 6, + "lastUpdated": "2025-05-20T14:59:52Z" + } + ] }, { "id": "0x77a0eb2debb3ddd73bb629ae482d24771ef1b59029d28a04e13570c9e9644c44", @@ -573,9 +765,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/47b18b46-5440-406c-8e07-bfcf27f8aa6e.png", "banner_url": "https://storage.googleapis.com/op-atlas/a80d7697-6c6f-4f71-bfc1-7576b933dad4.png", "twitter": "https://x.com/stereumdev", - "repos": [ - "https://github.com/stereum-dev/ethereum-node" - ], "tags": [ "cli", "docker", @@ -583,7 +772,14 @@ "privacy-focused" ], "website": "https://stereum.com", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/stereum-dev/ethereum-node", + "stargazers": 154, + "lastUpdated": "2026-01-20T12:36:08Z" + } + ] }, { "id": "0x363b77a4022f98f4d529b8a771d22f49b1092293980aab154fff63980bd1b2bf", @@ -592,15 +788,19 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/Rubilmax/viem-tracer" - ], "tags": [ "cli", "debugging-tools" ], "website": "https://github.com/Rubilmax/viem-tracer", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Rubilmax/viem-tracer", + "stargazers": 25, + "lastUpdated": "2025-11-13T13:14:02Z" + } + ] }, { "id": "0xfbecd6308658b3d40a5249d4b249d10537165f57ea528cc796aef5ce1eb1f0d8", @@ -609,9 +809,6 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/Rubilmax/executooor" - ], "tags": [ "defi", "erc721", @@ -619,7 +816,14 @@ "transaction-optimization" ], "website": "https://github.com/Rubilmax/executooor", - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/Rubilmax/executooor", + "stargazers": 98, + "lastUpdated": "2025-04-10T15:44:56Z" + } + ] }, { "id": "0x5999c3a9311c71fd2e02078c406d417565a3d04efe52570ba294be75a5befac8", @@ -628,16 +832,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/43a31c8a-308e-4956-a4f4-ba61a1280c7b.png", "banner_url": null, "twitter": "https://x.com/EthStorage", - "repos": [ - "https://github.com/zhiqiangxu/opup" - ], "tags": [ "cli", "docker", "contract-management" ], "website": "https://ethstorage.io/", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/zhiqiangxu/opup", + "stargazers": 0, + "lastUpdated": "2025-11-13T10:10:55Z" + } + ] }, { "id": "0x5c0234455c4b86b05ed0c612ac0d7e53cd2249686305af9b2184190b781b8063", @@ -646,14 +854,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/9379802f-3bc8-4e72-a0ad-f4a267ef4d42.png", "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/memester-xyz/surl" - ], "tags": [ "solidity", "foundry" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/memester-xyz/surl", + "stargazers": 332, + "lastUpdated": "2025-04-05T17:06:36Z" + } + ] }, { "id": "0xf4f7d13f2ac3c9805998d8540950883b872d7c5d7c81d6254dde8655af690b2a", @@ -662,15 +874,19 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/joshstevens19/evmc" - ], "tags": [ "cli", "support", "contract-verification" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/joshstevens19/evmc", + "stargazers": 134, + "lastUpdated": "2025-04-05T14:41:12Z" + } + ] }, { "id": "0xe01f00da2ba1f43dd0dd1e2b93bbfc5a84021ded7e6d414e86fa12a8d4eeb347", @@ -679,16 +895,20 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/joshstevens19/simple-uniswap-sdk" - ], "tags": [ "defi", "sdk", "multicall", "user-experience" ], - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/joshstevens19/simple-uniswap-sdk", + "stargazers": 191, + "lastUpdated": "2025-05-02T07:31:13Z" + } + ] }, { "id": "0x471ef1b671bc421d04640a7fe832365c1aec2d298adc81f03d69a685b7cc894c", @@ -697,14 +917,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/b852c74f-a247-40dd-8299-90b8c7499c8c.png", "banner_url": "https://storage.googleapis.com/op-atlas/bb135bd2-a2b6-46b1-b327-e3c8033f2f4b.png", "twitter": "https://x.com/3loop_io", - "repos": [ - "https://github.com/3loop/loop-decoder" - ], "tags": [ "transaction-decoding" ], "website": "https://loop-decoder-web.vercel.app/", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/3loop/loop-decoder", + "stargazers": 98, + "lastUpdated": "2025-11-05T11:08:28Z" + } + ] }, { "id": "0x0cc5d7a8088f227787992130b3cffe143db1c904af1ac27324f84e762b84f35c", @@ -713,17 +937,25 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/9e453fca-55dd-45d9-9046-c8ee58290761.png", "banner_url": "https://storage.googleapis.com/op-atlas/cd0944ee-9bed-445f-bcb8-ba22c80d3f57.png", "twitter": null, - "repos": [ - "https://github.com/dl-solarity/hardhat-zkit", - "https://github.com/dl-solarity/solidity-lib" - ], "tags": [ "hardhat", "education", "solidity" ], "website": "https://solarity.dev/", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/dl-solarity/hardhat-zkit", + "stargazers": 95, + "lastUpdated": "2026-01-03T14:04:22Z" + }, + { + "href": "https://github.com/dl-solarity/solidity-lib", + "stargazers": 391, + "lastUpdated": "2026-01-05T15:54:20Z" + } + ] }, { "id": "0xb024f6abfa79f7eb7af334f56015509bb70355709991d31bc689c7bea3250f7e", @@ -732,9 +964,6 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/Rubilmax/foundry-gas-diff" - ], "tags": [ "foundry", "cli", @@ -744,7 +973,14 @@ "test-automation", "continuous-integration" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Rubilmax/foundry-gas-diff", + "stargazers": 207, + "lastUpdated": "2025-04-04T08:54:57Z" + } + ] }, { "id": "0xfeafe16f8c1a25aebe754f3653340a17943a483a3e389464e44cf14613e210f0", @@ -753,9 +989,6 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/Rubilmax/foundry-storage-check" - ], "tags": [ "foundry", "cli", @@ -766,7 +999,14 @@ "code-quality", "security" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Rubilmax/foundry-storage-check", + "stargazers": 100, + "lastUpdated": "2025-04-04T08:49:44Z" + } + ] }, { "id": "0x48220ef1d103189cd918e9290db4c4b99b463ae2817fb5ef0cc54556a7961b6f", @@ -775,14 +1015,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/b092dff2-6e21-451c-9946-2f02e2986c8f.png", "banner_url": "https://storage.googleapis.com/op-atlas/e3093f96-c4b6-478e-bde2-19e96a7fa7a3.png", "twitter": null, - "repos": [ - "https://github.com/keccak256js/keccak256" - ], "tags": [ "encryption" ], "website": "https://github.com/keccak256js/keccak256", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/keccak256js/keccak256", + "stargazers": 67, + "lastUpdated": "2025-04-03T20:01:54Z" + } + ] }, { "id": "0x3ec2d572a608cf939eaf7886402320b3b2229610c13bdb5cb0776bd097331e5a", @@ -791,9 +1035,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/1e11eb35-ddb5-4385-bf18-2231ce727db9.png", "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/PraneshASP/vscode-solidity-inspector" - ], "tags": [ "foundry", "vscode-extension", @@ -801,7 +1042,14 @@ "storage-layout", "code-analysis" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/PraneshASP/vscode-solidity-inspector", + "stargazers": 134, + "lastUpdated": "2025-07-28T19:58:19Z" + } + ] }, { "id": "0xf152ccbfb3aa63c2ddcc070dc6d4462368eb25b69c3c3137cc459189af681402", @@ -810,16 +1058,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/50bfdcb2-8355-4480-b530-df8cdc97e3da.png", "banner_url": "https://storage.googleapis.com/op-atlas/e2df36a1-d787-4875-a156-ffba6dcd0b5f.png", "twitter": "https://x.com/derivexyz", - "repos": [ - "https://github.com/derivexyz/cockpit" - ], "tags": [ "defi", "docker", "cli" ], "website": "https://www.derive.xyz/", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/derivexyz/cockpit", + "stargazers": 18, + "lastUpdated": "2026-01-20T18:11:33Z" + } + ] }, { "id": "0xbd393d380c995845e0b26365d91e9730403baa30b4a80e955be1ab5713bba709", @@ -828,15 +1080,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/69edd7f3-606d-4191-b7c8-28e41246b2d0.png", "banner_url": "https://storage.googleapis.com/op-atlas/b753d4c0-96c7-4b36-b70e-e2785f9006bd.png", "twitter": "https://x.com/derivexyz", - "repos": [ - "https://github.com/derivexyz/op-geth" - ], "tags": [ "defi", "gas-optimization" ], "website": "https://www.derive.xyz/", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/derivexyz/op-geth", + "stargazers": 6, + "lastUpdated": "2025-06-26T19:33:46Z" + } + ] }, { "id": "0x46aff4985914b8e56b8fd62a9b8c3a03e2320315a9dfd6126e5ae272173cda87", @@ -845,9 +1101,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/ee4b3aab-f2b2-4400-abbc-2383b62662a4.png", "banner_url": "https://storage.googleapis.com/op-atlas/b3b3b9a2-81bd-4e6b-af22-c388ca45c9f5.png", "twitter": "https://x.com/patterns_build", - "repos": [ - "https://github.com/tokenguardio/dapp-marvels" - ], "tags": [ "analytics", "defi", @@ -855,7 +1108,14 @@ "docker", "scalability" ], - "category": "Data, Analytics & Tracing" + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/tokenguardio/dapp-marvels", + "stargazers": 15, + "lastUpdated": "2025-03-21T11:37:20Z" + } + ] }, { "id": "0xc66e357ad67e63954cd1eb79da4d507d8800518f06c82e423e93e8771e7b8d13", @@ -864,12 +1124,16 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/b62d6708-d690-41e7-b574-4c8d6c728610.png", "banner_url": "https://storage.googleapis.com/op-atlas/fd66f5d9-996c-4b69-8c0d-d7b4d9a2dc91.png", "twitter": "https://x.com/BrahmaFi", - "repos": [ - "https://github.com/Brahma-fi/console-kit" - ], "tags": [], "website": "https://www.brahma.fi/", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Brahma-fi/console-kit", + "stargazers": 28, + "lastUpdated": "2025-07-22T11:08:29Z" + } + ] }, { "id": "0x90bbb485004d99e20be133d2c26abc1f63a2c1ec8107358e87853b001bfb6597", @@ -878,9 +1142,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/6c522dd8-66e1-441b-b54c-156886a50dd1.png", "banner_url": "https://storage.googleapis.com/op-atlas/9cca66f9-2eef-4e2b-bc3c-515f52312848.png", "twitter": "https://x.com/CyfrinUpdraft", - "repos": [ - "https://github.com/Cyfrin/Updraft" - ], "tags": [ "education", "defi", @@ -888,7 +1149,14 @@ "community-driven" ], "website": "https://www.cyfrin.io/updraft", - "category": "Education & Community Resources" + "category": "Education & Community Resources", + "repos": [ + { + "href": "https://github.com/Cyfrin/Updraft", + "stargazers": 111, + "lastUpdated": "2026-01-20T18:33:32Z" + } + ] }, { "id": "0x62d9a8a3b602c688610abfbe3965e04ca0d19c5c506f40e79cd185cb501d2018", @@ -897,18 +1165,30 @@ "thumbnail_url": null, "banner_url": null, "twitter": "https://x.com/paulmillr", - "repos": [ - "https://github.com/paulmillr/noble-curves", - "https://github.com/paulmillr/noble-hashes", - "https://github.com/paulmillr/noble-ciphers" - ], "tags": [ "wallet", "security", "encryption" ], "website": "https://paulmillr.com/noble/", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/paulmillr/noble-curves", + "stargazers": 876, + "lastUpdated": "2026-01-13T01:04:35Z" + }, + { + "href": "https://github.com/paulmillr/noble-hashes", + "stargazers": 802, + "lastUpdated": "2026-01-13T01:31:07Z" + }, + { + "href": "https://github.com/paulmillr/noble-ciphers", + "stargazers": 358, + "lastUpdated": "2026-01-13T01:07:07Z" + } + ] }, { "id": "0xded45f5b4e2be2487ef301591cf49859e95ed6d2b33743a0c0b5e15c25e17694", @@ -917,16 +1197,20 @@ "thumbnail_url": null, "banner_url": null, "twitter": "https://x.com/meldsun0", - "repos": [ - "https://github.com/meldsun0/utp" - ], "tags": [ "networking", "peer-to-peer", "real-time-data" ], "website": "https://github.com/meldsun0/utp", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/meldsun0/utp", + "stargazers": 0, + "lastUpdated": "2025-06-14T16:08:17Z" + } + ] }, { "id": "0xe9495ac0f2a00d424f4f2dca80fe34c59c78d5cbf9acad0536c4c0ede540e053", @@ -935,15 +1219,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/8ad9f3a8-ac4a-4b5d-8652-4be22cf47ea0.png", "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/openfort-xyz/mobile-wallet-protocol-unity-client" - ], "tags": [ "wallet", "game-development", "user-experience" ], - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/openfort-xyz/mobile-wallet-protocol-unity-client", + "stargazers": 1, + "lastUpdated": "2025-03-25T13:01:38Z" + } + ] }, { "id": "0x44ff313ae6fb57054de6d637adae710594180239badaf2bc51889d068f4cf02b", @@ -952,11 +1240,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/ff0b8f78-e997-4a50-ae49-6aaad2273213.png", "banner_url": "https://storage.googleapis.com/op-atlas/2e157a8d-e9e1-4dbe-a0c0-ff6d908f9040.png", "twitter": "https://x.com/alchemy", - "repos": [ - "https://github.com/alchemyplatform/modular-account", - "https://github.com/alchemyplatform/multisig-plugin", - "https://github.com/alchemyplatform/aa-benchmarks" - ], "tags": [ "wallet", "defi", @@ -966,7 +1249,24 @@ "upgradeable-contracts", "developer-experience" ], - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/alchemyplatform/modular-account", + "stargazers": 136, + "lastUpdated": "2025-12-19T00:50:46Z" + }, + { + "href": "https://github.com/alchemyplatform/multisig-plugin", + "stargazers": 8, + "lastUpdated": "2025-03-31T16:31:21Z" + }, + { + "href": "https://github.com/alchemyplatform/aa-benchmarks", + "stargazers": 35, + "lastUpdated": "2025-04-30T22:40:07Z" + } + ] }, { "id": "0x4e13be6b98dd868cd13e9f4101431ab03d211f429b63f078fa7da260b54d256a", @@ -975,9 +1275,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/646cd1db-23b4-4328-8a7c-6c58358a73e1.png", "banner_url": null, "twitter": "https://x.com/alchemy", - "repos": [ - "https://github.com/alchemyplatform/light-account" - ], "tags": [ "wallet", "account-abstraction", @@ -985,7 +1282,14 @@ "foundry" ], "website": "https://www.alchemy.com/", - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/alchemyplatform/light-account", + "stargazers": 111, + "lastUpdated": "2026-01-07T16:13:59Z" + } + ] }, { "id": "0x0c85267cd9d7e694e385467c9984fbc787228db0cf03e57254a5116001eac4ee", @@ -994,15 +1298,23 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/6d42b8ec-216a-4904-ab39-ce60a80ee867.png", "banner_url": "https://storage.googleapis.com/op-atlas/87fd037d-1b02-4325-b910-882245e95e7b.png", "twitter": "https://x.com/rathfinance", - "repos": [ - "https://github.com/RathFinance/tachyon-account", - "https://github.com/RathFinance/tachyon-forwarder" - ], "tags": [ "performance-optimization" ], "website": "https://rath.fi/", - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/RathFinance/tachyon-account", + "stargazers": 1, + "lastUpdated": "2025-05-01T11:31:58Z" + }, + { + "href": "https://github.com/RathFinance/tachyon-forwarder", + "stargazers": 1, + "lastUpdated": "2025-08-04T14:55:11Z" + } + ] }, { "id": "0x2ccf4b9bd6ed894c10befd9fe00c467c4bfd84ff057ee956ab708259cfa845a9", @@ -1011,9 +1323,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/9e4b845e-5d97-4c91-a67e-94aab4a07a24.png", "banner_url": "https://storage.googleapis.com/op-atlas/d2d38c2e-ba3a-4338-84fb-f78873866813.png", "twitter": null, - "repos": [ - "https://github.com/metacraft-labs/codetracer" - ], "tags": [ "cli", "education", @@ -1021,7 +1330,14 @@ "performance-optimization" ], "website": "https://www.codetracer.com", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/metacraft-labs/codetracer", + "stargazers": 1268, + "lastUpdated": "2025-12-30T18:05:01Z" + } + ] }, { "id": "0x3a942492f564e13e4a3fc11e9a8b5dcd8bf0213f9dd8571d888f32db84271c5f", @@ -1030,14 +1346,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/9a276191-f180-425f-96b5-c51e12ef35c2.png", "banner_url": "https://storage.googleapis.com/op-atlas/c3df0213-1859-4bde-abbb-80a949304062.png", "twitter": null, - "repos": [ - "https://github.com/apoorvlathey/evm-rpcs-list" - ], "tags": [ "chains" ], "website": "https://www.npmjs.com/package/evm-rpcs-list", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/apoorvlathey/evm-rpcs-list", + "stargazers": 17, + "lastUpdated": "2025-05-06T13:15:29Z" + } + ] }, { "id": "0xf00e745fe6d96359adc3dc45d6d811bf1140549ad830d927cda5ca0b694a3063", @@ -1046,16 +1366,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/61e344ec-18c4-4a72-9d97-40c1d8f112b1.png", "banner_url": "https://storage.googleapis.com/op-atlas/d2dbff0b-870e-4ef7-8cb2-4661de764405.png", "twitter": "https://x.com/EIPTools", - "repos": [ - "https://github.com/EIPTools/eip-tools" - ], "tags": [ "analytics", "visualization", "interactive-tools" ], "website": "https://eip.tools/", - "category": "Data, Analytics & Tracing" + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/EIPTools/eip-tools", + "stargazers": 19, + "lastUpdated": "2026-01-19T13:10:23Z" + } + ] }, { "id": "0x492486eda6bcb71b4891dd39a4e150db1f7ab46f64b83f2f5a02aed82497e9ed", @@ -1064,16 +1388,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/ed6e47cb-2456-42fb-ad28-8e23cef7f18c.png", "banner_url": "https://storage.googleapis.com/op-atlas/ca1ea496-ccaa-4393-86b6-d14fc1e9c8f7.png", "twitter": null, - "repos": [ - "https://github.com/swiss-knife-xyz/forge-stack-tracer" - ], "tags": [ "cli", "foundry", "testing" ], "website": "https://www.npmjs.com/package/forge-stack-tracer", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/swiss-knife-xyz/forge-stack-tracer", + "stargazers": 9, + "lastUpdated": "2025-02-26T22:00:35Z" + } + ] }, { "id": "0x93c4efb5e2d7416c56ecdcd8244be8faf924194d65b514d90a7a51f6797cc012", @@ -1082,9 +1410,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/1eba0c98-3ab5-4bce-b365-607e76aa8778.png", "banner_url": "https://storage.googleapis.com/op-atlas/e07ffbf7-525f-4fd4-b5fd-bec83fd940eb.png", "twitter": "https://x.com/swissknifexyz", - "repos": [ - "https://github.com/swiss-knife-xyz/swiss-knife" - ], "tags": [ "frontend", "analytics", @@ -1094,7 +1419,14 @@ "nextjs" ], "website": "https://swiss-knife.xyz/", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/swiss-knife-xyz/swiss-knife", + "stargazers": 224, + "lastUpdated": "2025-12-29T09:27:39Z" + } + ] }, { "id": "0x07222a857f4522026d91faec337e3cb8cf6ec5f7afb823e0742e1a6c398b81ff", @@ -1103,17 +1435,25 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/5e04e1b5-a4b2-4755-89cf-6a155eff4aab.png", "banner_url": "https://storage.googleapis.com/op-atlas/0417f6b7-6016-4141-8a9e-7b47a29a3a1f.png", "twitter": null, - "repos": [ - "https://github.com/impersonator-eth/impersonator", - "https://github.com/impersonator-eth/impersonator-extension" - ], "tags": [ "wallet", "user-experience", "react-app" ], "website": "https://impersonator.xyz/", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/impersonator-eth/impersonator", + "stargazers": 317, + "lastUpdated": "2025-12-21T13:39:53Z" + }, + { + "href": "https://github.com/impersonator-eth/impersonator-extension", + "stargazers": 61, + "lastUpdated": "2025-02-26T21:39:17Z" + } + ] }, { "id": "0xd35cc78b456bf11d4acc96d2c227b29fa4115ad9d93ae211a31974a408ed8303", @@ -1122,9 +1462,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/0835fe6c-4d7d-4d2b-9f76-00fe91acd72b.png", "banner_url": "https://storage.googleapis.com/op-atlas/3acbc145-3b84-44d7-b62b-7a39b5f0ac7e.png", "twitter": "https://x.com/DiffuseFi", - "repos": [ - "https://github.com/Diffuse-fi/datafeed-cli" - ], "tags": [ "defi", "real-time-data", @@ -1132,7 +1469,14 @@ "verification" ], "website": "diffuse.fi", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Diffuse-fi/datafeed-cli", + "stargazers": 1, + "lastUpdated": "2025-04-30T13:22:20Z" + } + ] }, { "id": "0xafb4dc19ccc63057da88110df49234b311044bc73b070041bb8df03e583943ab", @@ -1141,16 +1485,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/83588cc2-f155-4b2c-8ff1-1347f2113c4d.png", "banner_url": "https://storage.googleapis.com/op-atlas/bbb0dc26-29e0-42f6-a114-196bd042d3f8.png", "twitter": null, - "repos": [ - "https://github.com/BuidlGuidl/abi.ninja" - ], "tags": [ "frontend", "contract-interaction", "proxy-contracts" ], "website": "https://abi.ninja/", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/BuidlGuidl/abi.ninja", + "stargazers": 224, + "lastUpdated": "2026-01-16T06:25:16Z" + } + ] }, { "id": "0xc0809225b6287417d08ec0fde8d632ecc935296e61e239e7e44559c7dd7f2495", @@ -1159,14 +1507,22 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/b48a5502-4473-4614-966a-c8581279a95b.png", "banner_url": "https://storage.googleapis.com/op-atlas/b6aa707f-e3bd-43ea-965f-aef868ce0c6d.png", "twitter": "@yiannisbot", - "repos": [ - "https://github.com/probe-lab/website", - "https://github.com/dennis-tra/nebula" - ], "tags": [ "analytics" ], - "category": "Data, Analytics & Tracing" + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/probe-lab/website", + "stargazers": 2, + "lastUpdated": "2025-12-03T12:31:48Z" + }, + { + "href": "https://github.com/dennis-tra/nebula", + "stargazers": 368, + "lastUpdated": "2025-11-03T07:46:30Z" + } + ] }, { "id": "0x7f330267969cf845a983a9d4e7b7dbcca5c700a5191269af377836d109e0bb69", @@ -1175,23 +1531,59 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/fca3aa6c-bdd5-4632-ae64-37b886d50a65.png", "banner_url": "https://storage.googleapis.com/op-atlas/35658254-c8b6-4562-9690-db91f187a7ff.png", "twitter": "https://x.com/ipshipyard", - "repos": [ - "https://github.com/ipfs/service-worker-gateway", - "https://github.com/ipfs/helia", - "https://github.com/ipfs/kubo", - "https://github.com/ipfs/boxo", - "https://github.com/ipfs/js-kubo-rpc-client", - "https://github.com/ipfs/protons", - "https://github.com/ipfs/js-ipns", - "https://github.com/ipfs/helia-delegated-routing-v1-http-api", - "https://github.com/ipfs/js-stores" - ], "tags": [ "peer-to-peer", "censorship-resistant", "cli" ], - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/ipfs/service-worker-gateway", + "stargazers": 79, + "lastUpdated": "2026-01-20T15:43:06Z" + }, + { + "href": "https://github.com/ipfs/helia", + "stargazers": 1275, + "lastUpdated": "2026-01-16T09:45:08Z" + }, + { + "href": "https://github.com/ipfs/kubo", + "stargazers": 16881, + "lastUpdated": "2026-01-16T01:27:32Z" + }, + { + "href": "https://github.com/ipfs/boxo", + "stargazers": 277, + "lastUpdated": "2026-01-20T18:22:51Z" + }, + { + "href": "https://github.com/ipfs/js-kubo-rpc-client", + "stargazers": 50, + "lastUpdated": "2025-10-15T07:29:36Z" + }, + { + "href": "https://github.com/ipfs/protons", + "stargazers": 37, + "lastUpdated": "2025-06-25T08:34:59Z" + }, + { + "href": "https://github.com/ipfs/js-ipns", + "stargazers": 89, + "lastUpdated": "2025-10-14T10:05:10Z" + }, + { + "href": "https://github.com/ipfs/helia-delegated-routing-v1-http-api", + "stargazers": 4, + "lastUpdated": "2026-01-16T14:05:02Z" + }, + { + "href": "https://github.com/ipfs/js-stores", + "stargazers": 37, + "lastUpdated": "2026-01-08T14:46:02Z" + } + ] }, { "id": "0x7697147650b4b717ce5675982f2102da7c030498628fe37e3f403f875622b7f7", @@ -1200,15 +1592,19 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/gelatodigital/relay-sdk" - ], "tags": [ "security", "sdk" ], "website": "https://www.gelato.network/relay", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/gelatodigital/relay-sdk", + "stargazers": 36, + "lastUpdated": "2025-12-29T14:33:05Z" + } + ] }, { "id": "0xa492e54cf4d492c5f8a9c16038b4e5d47cd3bac575fbea7979f5cd1f1e575482", @@ -1217,15 +1613,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/3d382dad-0b66-475d-a13c-43fddf27d5cc.png", "banner_url": "https://storage.googleapis.com/op-atlas/635c79ee-de4c-431e-8ce8-cb47fedb91ce.png", "twitter": null, - "repos": [ - "https://github.com/gelatodigital/automate-sdk" - ], "tags": [ "sdk", "contract-interaction" ], "website": "https://www.gelato.network/web3-functions", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/gelatodigital/automate-sdk", + "stargazers": 20, + "lastUpdated": "2025-04-02T13:02:53Z" + } + ] }, { "id": "0x670a2982f6d7786b58a8399bcabc23246365b21e533a97945e055791fc235e64", @@ -1234,10 +1634,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/4659da93-959f-4622-bce7-0bf1b3ac0f5c.png", "banner_url": "https://storage.googleapis.com/op-atlas/ef35fb80-418b-4c0b-a933-a11f7a3749d4.png", "twitter": "https://x.com/HardhatHQ", - "repos": [ - "https://github.com/NomicFoundation/edr", - "https://github.com/nomicfoundation/hardhat" - ], "tags": [ "cli", "hardhat", @@ -1247,7 +1643,19 @@ "community-driven" ], "website": "https://hardhat.org/", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/NomicFoundation/edr", + "stargazers": 93, + "lastUpdated": "2026-01-20T13:20:44Z" + }, + { + "href": "https://github.com/nomicfoundation/hardhat", + "stargazers": 8407, + "lastUpdated": "2026-01-20T17:56:53Z" + } + ] }, { "id": "0xaec1c406b2a124ec90aeebdde35c6c0cd9a90f0c7730b0911d2f648c8b99d062", @@ -1256,9 +1664,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/fcae3c08-8e11-40f9-a738-4a8e3c5f59d7.png", "banner_url": "https://storage.googleapis.com/op-atlas/013ad3c8-5ddc-47ed-aff1-8476d46e30b6.png", "twitter": "https://x.com/vaariance", - "repos": [ - "https://github.com/vaariance/variance-dart" - ], "tags": [ "wallet", "education", @@ -1266,7 +1671,14 @@ "account-abstraction", "transaction-signing" ], - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/vaariance/variance-dart", + "stargazers": 16, + "lastUpdated": "2025-11-05T16:41:21Z" + } + ] }, { "id": "0xc377ed1b705bcc856a628f961f1e7c8ca943e6f3727b7c179c657e227e8e852c", @@ -1275,14 +1687,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/a98b7fe6-9d08-49e4-b764-5470e14ea3aa.png", "banner_url": "https://storage.googleapis.com/op-atlas/997e2275-906b-4535-b414-59f4bd648196.png", "twitter": null, - "repos": [ - "https://github.com/merkletreejs/merkletreejs" - ], "tags": [ "merkle-trees" ], "website": "https://github.com/merkletreejs/merkletreejs", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/merkletreejs/merkletreejs", + "stargazers": 1230, + "lastUpdated": "2025-09-15T07:14:10Z" + } + ] }, { "id": "0x17fb589e599fe05e532b90c121eccc55b1249301e783dae226bad698872322da", @@ -1291,9 +1707,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/06419654-6022-400a-9670-82ca6e0225fe.png", "banner_url": "https://storage.googleapis.com/op-atlas/5aba83e1-a4f2-453c-9e64-9884d0e628d6.png", "twitter": "https://x.com/openzeppelin", - "repos": [ - "https://github.com/OpenZeppelin/ethernaut" - ], "tags": [ "education", "security", @@ -1302,7 +1715,14 @@ "react-app" ], "website": "https://ethernaut.openzeppelin.com/", - "category": "Education & Community Resources" + "category": "Education & Community Resources", + "repos": [ + { + "href": "https://github.com/OpenZeppelin/ethernaut", + "stargazers": 2273, + "lastUpdated": "2025-11-19T16:57:18Z" + } + ] }, { "id": "0xcc9301a401320c626839db9c4415f28a6e1f2fb3abdf38ada785b57409bdedb6", @@ -1311,17 +1731,25 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/07bee0c5-72ce-4e1b-b474-bd9d84856718.png", "banner_url": "https://storage.googleapis.com/op-atlas/7881f699-90d7-4178-965c-8805145a348a.png", "twitter": "dexkit", - "repos": [ - "https://github.com/DexKit/open-nft-marketplace", - "https://github.com/DexKit/dexkit-monorepo" - ], "tags": [ "frontend", "react", "nextjs" ], "website": "http://dexkit.com", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/DexKit/open-nft-marketplace", + "stargazers": 94, + "lastUpdated": "2025-02-24T02:49:26Z" + }, + { + "href": "https://github.com/DexKit/dexkit-monorepo", + "stargazers": 8, + "lastUpdated": "2025-12-07T11:06:41Z" + } + ] }, { "id": "0x852f6213011d0ad31206df4993d22721102dbe615bb93492d6e8be8d89676243", @@ -1330,9 +1758,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/578db712-b499-4084-a729-99d90ee55c7f.png", "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/Cyfrin/foundry-devops" - ], "tags": [ "foundry", "cli", @@ -1341,7 +1766,14 @@ "contract-deployment" ], "website": "https://github.com/Cyfrin/foundry-devops", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Cyfrin/foundry-devops", + "stargazers": 630, + "lastUpdated": "2025-06-13T19:13:29Z" + } + ] }, { "id": "0x7e917a2d0718401c9fe2a82f43ea558f5128f251b1e658c76dc7ff9a5e9fd993", @@ -1350,9 +1782,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/527c8bbb-c361-4521-afbf-4396cecd1e3b.png", "banner_url": "https://storage.googleapis.com/op-atlas/dc6b5afb-2335-484a-91f5-6673bf62237a.png", "twitter": "https://x.com/PaulRberg", - "repos": [ - "https://github.com/PaulRBerg/prb-math" - ], "tags": [ "solidity", "gas-efficient", @@ -1360,7 +1789,14 @@ "foundry" ], "website": "https://github.com/PaulRBerg/prb-math", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/PaulRBerg/prb-math", + "stargazers": 991, + "lastUpdated": "2026-01-18T17:09:35Z" + } + ] }, { "id": "0x14eab8b10f729239d63df6c0cb85f666c3eb1f2dd440ebd003c1821f186a49da", @@ -1369,11 +1805,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/9ced93ba-a5ac-4d04-a054-2963c41e8dc6.png", "banner_url": "https://storage.googleapis.com/op-atlas/c141df7d-78ea-48c9-81b1-325fa5a33bc4.png", "twitter": "https://x.com/tryethernal", - "repos": [ - "https://github.com/tryethernal/ethernal", - "https://github.com/tryethernal/hardhat-ethernal", - "https://github.com/tryethernal/ethernal-cli" - ], "tags": [ "analytics", "block-explorer", @@ -1381,7 +1812,24 @@ "contract-verification", "cli" ], - "category": "Data, Analytics & Tracing" + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/tryethernal/ethernal", + "stargazers": 261, + "lastUpdated": "2026-01-09T19:35:35Z" + }, + { + "href": "https://github.com/tryethernal/hardhat-ethernal", + "stargazers": 105, + "lastUpdated": "2025-02-22T09:44:00Z" + }, + { + "href": "https://github.com/tryethernal/ethernal-cli", + "stargazers": 16, + "lastUpdated": "2025-02-22T09:45:29Z" + } + ] }, { "id": "0x8c0365628d69981ac162a89f2b391cc4adfd224e9a424f8e985e70e2421de6d1", @@ -1390,15 +1838,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/2a0e6716-cdf5-4a27-9912-5e520ccd68e1.png", "banner_url": "https://storage.googleapis.com/op-atlas/fca44e15-1ce7-422d-b22f-2f1df4f4923c.png", "twitter": null, - "repos": [ - "https://github.com/Nerd3Lab/superUI" - ], "tags": [ "frontend", "contract-management" ], "website": "Superui.app", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Nerd3Lab/superUI", + "stargazers": 33, + "lastUpdated": "2025-04-08T12:39:30Z" + } + ] }, { "id": "0x72d363f14ae85f47acfe748fb0a2bed73195582bb9863de18901f5dfe309b8f7", @@ -1407,9 +1859,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/9cf8d92d-5549-4321-b675-c25256860183.png", "banner_url": "https://storage.googleapis.com/op-atlas/20eb90df-0dd5-41fb-a3ce-f90cf3822492.png", "twitter": null, - "repos": [ - "https://github.com/solodit/solodit_content" - ], "tags": [ "security", "education", @@ -1417,7 +1866,14 @@ "community-driven" ], "website": "https://solodit.cyfrin.io/", - "category": "Education & Community Resources" + "category": "Education & Community Resources", + "repos": [ + { + "href": "https://github.com/solodit/solodit_content", + "stargazers": 125, + "lastUpdated": "2026-01-10T18:05:45Z" + } + ] }, { "id": "0xbaccff0188ef78c1bab0c9798b0faceee552de1dee4f763d1801a9c1d5e3bca5", @@ -1426,16 +1882,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/392d496a-b4b8-464c-bf6e-fcee8146a75f.png", "banner_url": "https://storage.googleapis.com/op-atlas/3fd3093d-6a52-44bb-a73b-cf9d6f8cae03.png", "twitter": "https://x.com/Verifereum/", - "repos": [ - "https://github.com/verifereum/verifereum" - ], "tags": [ "security", "education", "formal-verification" ], "website": "https://www.verifereum.org/", - "category": "Security, Testing & Formal Verification" + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/verifereum/verifereum", + "stargazers": 29, + "lastUpdated": "2026-01-15T23:37:44Z" + } + ] }, { "id": "0x495b81a381005f49592ee02a7ac6861b8da69762b7164180d0a1e4570f2d83bf", @@ -1444,9 +1904,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/900648a3-44d3-4d53-8e5e-1ccbb57bf9e2.png", "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/psychemist/deo-ai" - ], "tags": [ "education", "natural-language-processing", @@ -1454,7 +1911,14 @@ "vscode-extension", "community-driven" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/psychemist/deo-ai", + "stargazers": 1, + "lastUpdated": "2025-03-05T20:36:05Z" + } + ] }, { "id": "0x991062ec81edb818a542e45d7c142cc62bc06e68b582273bd2ae1b037c2d6791", @@ -1463,15 +1927,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/35374f7e-a430-4726-b5f0-ef52e2b5115a.png", "banner_url": "https://storage.googleapis.com/op-atlas/ba692e10-9ffd-4406-b6e7-5010ad20b2d2.png", "twitter": "https://x.com/TitanLayer", - "repos": [ - "https://github.com/TitanLayer/contracts" - ], "tags": [ "cross-chain", "security" ], "website": "https://titanlayer.xyz/", - "category": "Cross-Chain & Interoperability" + "category": "Cross-Chain & Interoperability", + "repos": [ + { + "href": "https://github.com/TitanLayer/contracts", + "stargazers": 0, + "lastUpdated": "2025-02-21T21:33:35Z" + } + ] }, { "id": "0x154a42e5ca88d7c2732fda74d6eb611057fc88dbe6f0ff3aae7b89c2cd1666ab", @@ -1480,14 +1948,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/f8efb7c2-8fb3-4988-8511-ae6e826b687f.png", "banner_url": "https://storage.googleapis.com/op-atlas/8b032214-48dc-4f13-b8fa-21324d9c9030.png", "twitter": "https://x.com/ScaffoldETH", - "repos": [ - "https://github.com/scaffold-eth/create-eth-extensions", - "https://github.com/scaffold-eth/burner-connector", - "https://github.com/scaffold-eth/se-2-docs", - "https://github.com/scaffold-eth/create-eth", - "https://github.com/scaffold-eth/scaffoldeth.io", - "https://github.com/scaffold-eth/scaffold-eth-2" - ], "tags": [ "frontend", "nextjs", @@ -1495,7 +1955,39 @@ "foundry", "cli" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/scaffold-eth/create-eth-extensions", + "stargazers": 48, + "lastUpdated": "2025-07-17T15:25:10Z" + }, + { + "href": "https://github.com/scaffold-eth/burner-connector", + "stargazers": 6, + "lastUpdated": "2025-12-17T12:12:49Z" + }, + { + "href": "https://github.com/scaffold-eth/se-2-docs", + "stargazers": 21, + "lastUpdated": "2025-12-19T08:05:18Z" + }, + { + "href": "https://github.com/scaffold-eth/create-eth", + "stargazers": 21, + "lastUpdated": "2026-01-20T10:58:36Z" + }, + { + "href": "https://github.com/scaffold-eth/scaffoldeth.io", + "stargazers": 8, + "lastUpdated": "2025-11-28T16:26:22Z" + }, + { + "href": "https://github.com/scaffold-eth/scaffold-eth-2", + "stargazers": 1944, + "lastUpdated": "2026-01-13T07:11:14Z" + } + ] }, { "id": "0x63f8e1e35986862f0bb24a619b72d12459497d2b6b94d93a9f2c232d376c54dc", @@ -1504,14 +1996,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/532d50f9-524d-4934-b77a-8c85d0145bcf.png", "banner_url": "https://storage.googleapis.com/op-atlas/a1272743-7b81-4aef-a8fd-f2fe70122b01.png", "twitter": null, - "repos": [ - "https://github.com/zwergdev/rainbowkit-theme-generator" - ], "tags": [ "frontend" ], "website": "https://rainbowkit-theme.com/", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/zwergdev/rainbowkit-theme-generator", + "stargazers": 5, + "lastUpdated": "2025-02-19T22:36:03Z" + } + ] }, { "id": "0xc0615947773148cbc340b175fb9afc98dbb4e0acd31d018b1ee41a5538785abf", @@ -1520,9 +2016,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/4043de65-2657-4c0f-91e6-3d5aea14dc33.png", "banner_url": "https://storage.googleapis.com/op-atlas/faafa9b3-2151-4cd7-a9f3-e9c1853e8874.png", "twitter": "https://x.com/wevm_dev", - "repos": [ - "https://github.com/wevm/wagmi" - ], "tags": [ "react", "wallet", @@ -1530,7 +2023,14 @@ "community-driven" ], "website": "https://wagmi.sh", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/wevm/wagmi", + "stargazers": 6646, + "lastUpdated": "2026-01-17T20:39:56Z" + } + ] }, { "id": "0xfa7d950cfda2c634b052b6c07e75daaa95dd22ac1f220b6862cfd24221d4cabc", @@ -1539,9 +2039,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/8a93267a-39e3-42c9-976f-225753bb43f3.png", "banner_url": "https://storage.googleapis.com/op-atlas/cc6944d5-ceb0-416d-9e3c-befb89ef7578.png", "twitter": "https://x.com/protofire", - "repos": [ - "https://github.com/protofire/solhint" - ], "tags": [ "security", "education", @@ -1549,7 +2046,14 @@ "community-driven", "cli" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/protofire/solhint", + "stargazers": 1115, + "lastUpdated": "2026-01-20T14:22:50Z" + } + ] }, { "id": "0x202a80f0f57630d04a26464d6492b3399059ca1187943032c37652eb2468a76f", @@ -1558,15 +2062,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/2e9723d3-7b53-473c-b93c-87b2c7a72055.png", "banner_url": "https://storage.googleapis.com/op-atlas/801bbd29-77ab-4050-b175-f853aa9704ed.png", "twitter": null, - "repos": [ - "https://github.com/vyperlang/titanoboa" - ], "tags": [ "vyper", "debugging-tools" ], "website": "https://titanoboa.readthedocs.io/en/latest/", - "category": "Security, Testing & Formal Verification" + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/vyperlang/titanoboa", + "stargazers": 305, + "lastUpdated": "2025-12-25T13:57:23Z" + } + ] }, { "id": "0xaed5941b7a9f20de83f5c839bda507be43cbf41777fc623abf4bf05773298826", @@ -1575,9 +2083,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/55a1fffb-dcd9-448b-8e34-9fb4b09a72f7.png", "banner_url": "https://storage.googleapis.com/op-atlas/a0e75c22-8aff-4176-af81-6c03208c1bd3.png", "twitter": "https://x.com/otterscan", - "repos": [ - "https://github.com/otterscan/otterscan" - ], "tags": [ "docker", "block-explorer", @@ -1588,7 +2093,14 @@ "visualization" ], "website": "https://otterscan.io/", - "category": "Data, Analytics & Tracing" + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/otterscan/otterscan", + "stargazers": 1396, + "lastUpdated": "2025-11-05T05:21:21Z" + } + ] }, { "id": "0x67f6d1feb3b5e99caf0f2e7e4677494c57449de3980079589156e105df485488", @@ -1597,9 +2109,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/89c06746-f49f-4a30-9843-80b431053f13.png", "banner_url": "https://storage.googleapis.com/op-atlas/5ec5b8ee-5389-4201-8191-4a84e37f1291.png", "twitter": null, - "repos": [ - "https://github.com/Cyfrin/moccasin" - ], "tags": [ "education", "vyper", @@ -1608,7 +2117,14 @@ "encryption" ], "website": "https://github.com/Cyfrin/moccasin", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Cyfrin/moccasin", + "stargazers": 177, + "lastUpdated": "2026-01-16T22:40:08Z" + } + ] }, { "id": "0x513265758a3804184b6a0771d99c1a4b04d3267bacd4b914e89ff991de229f6a", @@ -1617,15 +2133,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/ca4f6cbd-5b97-4c22-9e27-446b9e4cd2ff.png", "banner_url": "https://storage.googleapis.com/op-atlas/120ab790-4407-4342-b7af-e562cf3a9c8c.png", "twitter": null, - "repos": [ - "https://github.com/pcaversaccio/create2deployer" - ], "tags": [ "solidity", "contract-deployment" ], "website": "https://github.com/pcaversaccio/create2deployer", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/pcaversaccio/create2deployer", + "stargazers": 305, + "lastUpdated": "2026-01-19T17:58:29Z" + } + ] }, { "id": "0x537097f27d55cb52d39b95c3ed65076349ab68aac48051d742d715456e0884d8", @@ -1634,9 +2154,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/ce1dd7d2-ed08-45f9-adf0-1934ae5dc396.png", "banner_url": "https://storage.googleapis.com/op-atlas/4942518f-9987-4d03-9504-a7494fce0021.png", "twitter": null, - "repos": [ - "https://github.com/pcaversaccio/xdeployer" - ], "tags": [ "hardhat", "cross-chain", @@ -1645,7 +2162,14 @@ "cli" ], "website": "https://github.com/pcaversaccio/xdeployer", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/pcaversaccio/xdeployer", + "stargazers": 445, + "lastUpdated": "2026-01-19T18:24:30Z" + } + ] }, { "id": "0x4dd10ba330a4a21459e2ba72f15fb5da2a63f7492e2b1567e6669c3d47fe6308", @@ -1654,24 +2178,68 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/be0b64a3-1fcb-4f95-ad91-6a2589a5315f.png", "banner_url": "https://storage.googleapis.com/op-atlas/e1ea2162-1ef8-46ea-afdc-37f0bb4dee4a.png", "twitter": "https://x.com/web3labs", - "repos": [ - "https://github.com/hyperledger-web3j/web3j", - "https://github.com/hyperledger-web3j/web3j-maven-plugin", - "https://github.com/hyperledger-web3j/web3j-unit", - "https://github.com/hyperledger-web3j/web3j-openapi-gradle-plugin", - "https://github.com/hyperledger-web3j/web3j-openapi", - "https://github.com/hyperledger-web3j/web3j-solidity-gradle-plugin", - "https://github.com/hyperledger-web3j/web3j-docs", - "https://github.com/hyperledger-web3j/web3j-installer", - "https://github.com/hyperledger-web3j/web3j-cli", - "https://github.com/hyperledger-web3j/web3j-gradle-plugin", - "https://github.com/hyperledger-web3j/web3j-sokt" - ], "tags": [ "governance", "cli" ], - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/hyperledger-web3j/web3j", + "stargazers": 5378, + "lastUpdated": "2026-01-20T19:54:06Z" + }, + { + "href": "https://github.com/hyperledger-web3j/web3j-maven-plugin", + "stargazers": 127, + "lastUpdated": "2025-10-07T17:02:07Z" + }, + { + "href": "https://github.com/hyperledger-web3j/web3j-unit", + "stargazers": 27, + "lastUpdated": "2026-01-19T19:46:41Z" + }, + { + "href": "https://github.com/hyperledger-web3j/web3j-openapi-gradle-plugin", + "stargazers": 4, + "lastUpdated": "2025-04-11T07:03:23Z" + }, + { + "href": "https://github.com/hyperledger-web3j/web3j-openapi", + "stargazers": 36, + "lastUpdated": "2025-04-10T21:53:19Z" + }, + { + "href": "https://github.com/hyperledger-web3j/web3j-solidity-gradle-plugin", + "stargazers": 23, + "lastUpdated": "2026-01-16T06:21:44Z" + }, + { + "href": "https://github.com/hyperledger-web3j/web3j-docs", + "stargazers": 34, + "lastUpdated": "2025-06-09T08:35:36Z" + }, + { + "href": "https://github.com/hyperledger-web3j/web3j-installer", + "stargazers": 0, + "lastUpdated": "2025-05-22T18:33:35Z" + }, + { + "href": "https://github.com/hyperledger-web3j/web3j-cli", + "stargazers": 69, + "lastUpdated": "2025-04-11T11:54:07Z" + }, + { + "href": "https://github.com/hyperledger-web3j/web3j-gradle-plugin", + "stargazers": 41, + "lastUpdated": "2025-04-10T16:02:38Z" + }, + { + "href": "https://github.com/hyperledger-web3j/web3j-sokt", + "stargazers": 16, + "lastUpdated": "2026-01-16T05:49:46Z" + } + ] }, { "id": "0x819775803938d78eaa95809971ce94cae6a54b4df58505fa36153ffa1d55e12c", @@ -1680,14 +2248,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/006b0fd3-9e23-4192-98d6-08e561da809e.png", "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/juanfranblanco/vscode-solidity" - ], "tags": [ "education", "solidity" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/juanfranblanco/vscode-solidity", + "stargazers": 959, + "lastUpdated": "2025-11-04T17:05:55Z" + } + ] }, { "id": "0xa3d07f453f70d844196d89d79848aa2e70a0bd8b38bf0f493cba1547bb3bca5e", @@ -1696,16 +2268,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/f8d776ab-ca70-42ee-9e41-d4f709cd6fd4.png", "banner_url": "https://storage.googleapis.com/op-atlas/459bdd5e-60a5-49ca-88b8-d4537ebfec16.png", "twitter": "@ricmoo", - "repos": [ - "https://github.com/ethers-io/ethers.js" - ], "tags": [ "frontend", "json-rpc", "contract-interaction" ], "website": "https://ethers.org", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/ethers-io/ethers.js", + "stargazers": 8626, + "lastUpdated": "2025-12-03T00:49:47Z" + } + ] }, { "id": "0x2bb095e1f297c71da8bd4ee15097abad3b99e299fe14cd6aa704df3f36d0ae22", @@ -1714,9 +2290,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/bd692393-7f1a-4b91-9887-73f7c3250233.png", "banner_url": "https://storage.googleapis.com/op-atlas/dcbdf6ac-f898-4dac-b9d0-087b8d289f4b.png", "twitter": null, - "repos": [ - "https://github.com/sc-forks/solidity-coverage" - ], "tags": [ "hardhat", "analytics", @@ -1725,7 +2298,14 @@ "test-automation" ], "website": "https://github.com/sc-forks/solidity-coverage", - "category": "Security, Testing & Formal Verification" + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/sc-forks/solidity-coverage", + "stargazers": 1005, + "lastUpdated": "2025-12-11T04:00:44Z" + } + ] }, { "id": "0x4f8902ac6eba8e2243237247302ab778a1e1f496cf62e1696fbb8d57eff7701d", @@ -1734,9 +2314,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/8b8c4fda-3240-41c6-ab52-43a137e665a8.png", "banner_url": "https://storage.googleapis.com/op-atlas/0b8f272e-b319-4744-959e-dbc36996ba31.png", "twitter": "https://x.com/adraffy", - "repos": [ - "https://github.com/adraffy/blocksmith.js" - ], "tags": [ "cli", "foundry", @@ -1744,7 +2321,14 @@ "contract-deployment" ], "website": "https://github.com/adraffy/blocksmith.js", - "category": "Security, Testing & Formal Verification" + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/adraffy/blocksmith.js", + "stargazers": 11, + "lastUpdated": "2025-12-08T22:29:40Z" + } + ] }, { "id": "0x939241afa4c4b9e1dda6b8250baa8f04fa8b0debce738cfd324c0b18f9926d25", @@ -1753,16 +2337,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/83bab036-91bd-4b9d-a524-dbea2024aa3f.png", "banner_url": "https://storage.googleapis.com/op-atlas/489f54b5-2035-4a94-82f5-8b41e6cbb857.png", "twitter": "https://x.com/openzeppelin", - "repos": [ - "https://github.com/OpenZeppelin/openzeppelin-upgrades", - "https://github.com/OpenZeppelin/openzeppelin-subgraphs", - "https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades", - "https://github.com/OpenZeppelin/merkle-tree", - "https://github.com/openzeppelin/openzeppelin-community-contracts", - "https://github.com/OpenZeppelin/openzeppelin-contracts", - "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable", - "https://github.com/OpenZeppelin/contracts-wizard" - ], "tags": [ "cross-chain", "governance", @@ -1773,7 +2347,49 @@ "merkle-trees" ], "website": "https://www.openzeppelin.com/", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/OpenZeppelin/openzeppelin-upgrades", + "stargazers": 648, + "lastUpdated": "2025-11-03T20:09:20Z" + }, + { + "href": "https://github.com/OpenZeppelin/openzeppelin-subgraphs", + "stargazers": 146, + "lastUpdated": "2025-02-25T15:09:17Z" + }, + { + "href": "https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades", + "stargazers": 244, + "lastUpdated": "2025-06-30T19:16:05Z" + }, + { + "href": "https://github.com/OpenZeppelin/merkle-tree", + "stargazers": 519, + "lastUpdated": "2025-02-25T02:12:49Z" + }, + { + "href": "https://github.com/openzeppelin/openzeppelin-community-contracts", + "stargazers": 80, + "lastUpdated": "2026-01-13T18:10:27Z" + }, + { + "href": "https://github.com/OpenZeppelin/openzeppelin-contracts", + "stargazers": 26929, + "lastUpdated": "2026-01-15T16:08:39Z" + }, + { + "href": "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable", + "stargazers": 1149, + "lastUpdated": "2026-01-15T16:10:26Z" + }, + { + "href": "https://github.com/OpenZeppelin/contracts-wizard", + "stargazers": 294, + "lastUpdated": "2026-01-16T15:24:19Z" + } + ] }, { "id": "0x663e4d25ca3f327365240471b4831ea3c989cb132bbf6ae8f5c1e15268591795", @@ -1782,15 +2398,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/3113c4b6-4e29-420c-95f8-2ae4f6098089.png", "banner_url": "https://storage.googleapis.com/op-atlas/c08d15e7-41fd-41a7-9c04-b1e10b0c1f26.png", "twitter": "https://x.com/blockscoutcom", - "repos": [ - "https://github.com/blockscout/blockscout" - ], "tags": [ "block-explorer", "chains" ], "website": "http://www.blockscout.com", - "category": "Data, Analytics & Tracing" + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/blockscout/blockscout", + "stargazers": 4380, + "lastUpdated": "2026-01-20T19:42:29Z" + } + ] }, { "id": "0x8589657542ff4b7c5071dfdeff18a041642a72344ede9acea701e9b39fb46fee", @@ -1799,13 +2419,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/c26c5e5d-f2aa-4150-a46c-2e9c33de343f.png", "banner_url": "https://storage.googleapis.com/op-atlas/3e4364f9-e445-4c2d-be52-af8cf934eab6.png", "twitter": "https://x.com/getreconxyz", - "repos": [ - "https://github.com/Recon-Fuzz/setup-helpers", - "https://github.com/Recon-Fuzz/log-parser", - "https://github.com/Recon-Fuzz/create-chimera-app", - "https://github.com/Recon-Fuzz/chimera", - "https://github.com/Recon-Fuzz/recon-extension" - ], "tags": [ "foundry", "solidity", @@ -1813,7 +2426,34 @@ "test-automation", "vscode-extension" ], - "category": "Security, Testing & Formal Verification" + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/Recon-Fuzz/setup-helpers", + "stargazers": 4, + "lastUpdated": "2025-07-29T14:37:36Z" + }, + { + "href": "https://github.com/Recon-Fuzz/log-parser", + "stargazers": 4, + "lastUpdated": "2025-09-24T11:20:41Z" + }, + { + "href": "https://github.com/Recon-Fuzz/create-chimera-app", + "stargazers": 47, + "lastUpdated": "2025-07-31T13:34:09Z" + }, + { + "href": "https://github.com/Recon-Fuzz/chimera", + "stargazers": 143, + "lastUpdated": "2025-03-20T19:16:12Z" + }, + { + "href": "https://github.com/Recon-Fuzz/recon-extension", + "stargazers": 31, + "lastUpdated": "2025-12-15T15:58:31Z" + } + ] }, { "id": "0xbb067b01988521110c91737f058e7301f608be231d850a72af1516bd034d161c", @@ -1822,10 +2462,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/abf0fa5e-15f2-4963-bd73-d84d0bd4c307.png", "banner_url": "https://storage.googleapis.com/op-atlas/0d9aecc0-dcf4-4ee0-9e6c-12d9b62325ea.png", "twitter": "https://x.com/Synpress_", - "repos": [ - "https://github.com/synpress-io/docs", - "https://github.com/Synthetixio/synpress" - ], "tags": [ "frontend", "continuous-integration", @@ -1833,7 +2469,19 @@ "debugging-tools" ], "website": "https://synpress.io/", - "category": "Security, Testing & Formal Verification" + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/synpress-io/docs", + "stargazers": 0, + "lastUpdated": "2025-05-06T19:41:49Z" + }, + { + "href": "https://github.com/Synthetixio/synpress", + "stargazers": 873, + "lastUpdated": "2026-01-10T22:17:58Z" + } + ] }, { "id": "0xb773733e55b7267302f2622ae410a65a89552689387d0b86bce0f0cb833119d0", @@ -1842,9 +2490,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/abe6dc50-0732-419b-a64c-463814247f78.png", "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/shazow/callthis" - ], "tags": [ "frontend", "wallet", @@ -1852,7 +2497,14 @@ "privacy-focused", "censorship-resistant" ], - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/shazow/callthis", + "stargazers": 50, + "lastUpdated": "2025-12-05T15:58:59Z" + } + ] }, { "id": "0x4ede10cd8332093fb0c1083828cc2e333d60f1551cef2d29bccb82bae1f5d7f7", @@ -1861,9 +2513,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/104d6957-65bc-4d15-a5f9-2afd75482347.png", "banner_url": "https://storage.googleapis.com/op-atlas/c120c166-68a8-4e9b-a159-b1f9e74ff105.png", "twitter": "https://twitter.com/candidelabs", - "repos": [ - "https://github.com/candidelabs/candide-contracts" - ], "tags": [ "wallet", "governance", @@ -1872,7 +2521,14 @@ "user-experience" ], "website": "https://www.candide.dev/", - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/candidelabs/candide-contracts", + "stargazers": 77, + "lastUpdated": "2025-02-09T15:12:44Z" + } + ] }, { "id": "0x28aec169f525d30fed96625a31fdd75ca906805d0ee4e7b1502945a9e1d29525", @@ -1881,15 +2537,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/69b08a09-8fd5-498a-beef-67ad29cf01b5.png", "banner_url": "https://storage.googleapis.com/op-atlas/75a0886a-d3a0-4595-a539-64a8a83eae3a.png", "twitter": "https://twitter.com/candidelabs", - "repos": [ - "https://github.com/candidelabs/abstractionkit" - ], "tags": [ "wallet", "education", "account-abstraction" ], - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/candidelabs/abstractionkit", + "stargazers": 31, + "lastUpdated": "2025-12-05T12:12:24Z" + } + ] }, { "id": "0xc7798704a6d730cea776c4866a9636bfa04c1201e29b6b0c99cc3603bc1bca25", @@ -1898,15 +2558,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/8b14d1e8-d2ef-4670-83da-76368cbd50af.png", "banner_url": "https://storage.googleapis.com/op-atlas/7ce75cc0-17f9-457a-b456-0232b9647d96.png", "twitter": "https://x.com/usecannon", - "repos": [ - "https://github.com/usecannon/cannon" - ], "tags": [ "cli", "chains" ], "website": "https://usecannon.com", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/usecannon/cannon", + "stargazers": 122, + "lastUpdated": "2025-10-24T08:50:56Z" + } + ] }, { "id": "0x40483b3554ae17882db98d1cfd3aae6b10ba8250736279d184fd947931ed02c3", @@ -1915,10 +2579,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/6038b69f-0ca7-478f-a55f-002f00e3b7e7.png", "banner_url": "https://storage.googleapis.com/op-atlas/d96837af-ba2e-44d1-9e6d-ad9b30a06c3e.png", "twitter": "https://twitter.com/RATi_MOn", - "repos": [ - "https://github.com/Ratimon/superfuse-wizard", - "https://github.com/Ratimon/superfuse-forge" - ], "tags": [ "cross-chain", "frontend", @@ -1927,7 +2587,19 @@ "foundry" ], "website": "https://superfuse.ninja/", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Ratimon/superfuse-wizard", + "stargazers": 20, + "lastUpdated": "2025-04-12T12:17:32Z" + }, + { + "href": "https://github.com/Ratimon/superfuse-forge", + "stargazers": 19, + "lastUpdated": "2025-02-15T09:02:50Z" + } + ] }, { "id": "0x166e2bfeae612e99675a055e2d3e3d02e49bdab377109bc528c32b7afe6cc920", @@ -1936,9 +2608,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/2161762e-cdb8-41be-978b-3581df50d5a4.png", "banner_url": "https://storage.googleapis.com/op-atlas/ca2f1444-6a4f-41f2-91d4-f8059f652ccc.png", "twitter": "https://twitter.com/RATi_MOn", - "repos": [ - "https://github.com/Ratimon/solid-grinder" - ], "tags": [ "cli", "layer-2", @@ -1947,7 +2616,14 @@ "transaction-optimization" ], "website": "https://github.com/Ratimon/solid-grinder", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Ratimon/solid-grinder", + "stargazers": 100, + "lastUpdated": "2025-02-08T07:16:37Z" + } + ] }, { "id": "0x37fe5886f4c77d5a5cb947deff90158c045a5d207572763187748ac4dd4bd9b9", @@ -1956,13 +2632,17 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/joshstevens19/ethereum-multicall" - ], "tags": [ "multicall" ], - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/joshstevens19/ethereum-multicall", + "stargazers": 381, + "lastUpdated": "2025-12-23T11:07:33Z" + } + ] }, { "id": "0x4c9626843c4e3f3c96d80b0ec6b1d10b7682fc9b6d67ab61ece5a87648535b1f", @@ -1971,14 +2651,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/d21bd2f0-91b0-4e80-9e33-b1c21501a4e8.png", "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/joshstevens19/ethereum-bloom-filters" - ], "tags": [ "performance-optimization", "event-logging" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/joshstevens19/ethereum-bloom-filters", + "stargazers": 93, + "lastUpdated": "2025-05-02T07:29:04Z" + } + ] }, { "id": "0x97525ec91080ddd917eaccabf9d383cf70a2f78839ab21eeabe1687e312f2132", @@ -1987,15 +2671,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/366c4940-78cc-4119-958b-b93f3c9a5845.png", "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/joshstevens19/rindexer" - ], "tags": [ "indexing", "cli" ], "website": "https://rindexer.xyz/", - "category": "Data, Analytics & Tracing" + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/joshstevens19/rindexer", + "stargazers": 643, + "lastUpdated": "2026-01-20T18:33:58Z" + } + ] }, { "id": "0xc88dff5a8bb7326e7d9103bf84e77425e202a8275abffbbbc08954c309acf511", @@ -2004,9 +2692,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/4686b986-8bb5-4ab0-a13b-c020291b20c2.png", "banner_url": "https://storage.googleapis.com/op-atlas/2ac896b0-1b09-40bf-a5db-7baef34ead58.png", "twitter": "https://twitter.com/candidelabs", - "repos": [ - "https://github.com/candidelabs/voltaire" - ], "tags": [ "wallet", "governance", @@ -2016,7 +2701,14 @@ "user-experience" ], "website": "https://www.candide.dev/bundler", - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/candidelabs/voltaire", + "stargazers": 56, + "lastUpdated": "2026-01-12T21:35:32Z" + } + ] }, { "id": "0x4e175118c15129e6cc791203de92b23f11fef35ba4bc3fd18390f163e692c97d", @@ -2025,10 +2717,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/c82ddf3d-3586-4552-85ce-8e9f5da907d5.png", "banner_url": null, "twitter": "https://x.com/evmtools_xyz", - "repos": [ - "https://github.com/Elefria-Labs/zk-block", - "https://github.com/Elefria-Labs/evm-tools" - ], "tags": [ "cli", "analytics", @@ -2036,7 +2724,19 @@ "transaction-decoding", "merkle-trees" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Elefria-Labs/zk-block", + "stargazers": 71, + "lastUpdated": "2025-02-07T03:07:51Z" + }, + { + "href": "https://github.com/Elefria-Labs/evm-tools", + "stargazers": 14, + "lastUpdated": "2025-10-21T09:26:42Z" + } + ] }, { "id": "0x754c37e401e2527ab24b9d7ca3e042bfcbfebeef54a533f8833d46242d2c3017", @@ -2045,12 +2745,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/09d19a87-dc4f-4586-99f6-ef6c9f92f713.png", "banner_url": "https://storage.googleapis.com/op-atlas/5286dfe0-6f4d-4782-8c59-b7ffe6579bfc.png", "twitter": "https://x.com/EthereumRemix", - "repos": [ - "https://github.com/remix-project-org/remix-reward", - "https://github.com/ethereum/remix-project", - "https://github.com/remix-project-org/remix-challenges", - "https://github.com/remix-project-org/remix-rewards-ui" - ], "tags": [ "education", "frontend", @@ -2058,7 +2752,29 @@ "solidity", "community-driven" ], - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/remix-project-org/remix-reward", + "stargazers": 1, + "lastUpdated": "2025-02-19T13:53:14Z" + }, + { + "href": "https://github.com/ethereum/remix-project", + "stargazers": 2856, + "lastUpdated": "2026-01-19T16:48:13Z" + }, + { + "href": "https://github.com/remix-project-org/remix-challenges", + "stargazers": 0, + "lastUpdated": "2025-02-19T13:53:51Z" + }, + { + "href": "https://github.com/remix-project-org/remix-rewards-ui", + "stargazers": 1, + "lastUpdated": "2025-02-19T13:54:26Z" + } + ] }, { "id": "0x5f9f1b45eb4a49e8c2482288e02c8fc1e0e60ad3e88f0ea87bbdb4932da1054d", @@ -2067,9 +2783,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/d818a88f-eb12-4c4e-b1be-46f8284fd5d4.png", "banner_url": "https://storage.googleapis.com/op-atlas/8d4a3113-5b39-472e-9a60-57451db585fb.png", "twitter": "https://x.com/BAbraham_92/", - "repos": [ - "https://github.com/collinsadi/diamonds" - ], "tags": [ "cli", "hardhat", @@ -2077,7 +2790,14 @@ "erc721", "upgradeable-contracts" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/collinsadi/diamonds", + "stargazers": 34, + "lastUpdated": "2025-03-26T13:00:43Z" + } + ] }, { "id": "0x5dfcf84cc8ef7eb731a8175633c8da5cd3784fe57b05409f0df745b88443c034", @@ -2086,10 +2806,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/d2f26755-6a96-4cf7-917e-6ebeced29a15.png", "banner_url": "https://storage.googleapis.com/op-atlas/8d0da35d-0369-4bf8-a577-60ce33236078.png", "twitter": "https://x.com/rv_inc", - "repos": [ - "https://github.com/runtimeverification/simbolik-examples", - "https://github.com/runtimeverification/simbolik-vscode" - ], "tags": [ "security", "education", @@ -2099,7 +2815,19 @@ "formal-verification" ], "website": "simbolik.runtimeverification.com", - "category": "Security, Testing & Formal Verification" + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/runtimeverification/simbolik-examples", + "stargazers": 5, + "lastUpdated": "2026-01-14T20:21:15Z" + }, + { + "href": "https://github.com/runtimeverification/simbolik-vscode", + "stargazers": 47, + "lastUpdated": "2026-01-05T04:32:05Z" + } + ] }, { "id": "0xabdfa10e699db5127100da1dd2403692afe8d86e793d57780f1c7e93437a73a0", @@ -2108,11 +2836,15 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/63e11af2-345b-4977-b6da-dcaf387df081.png", "banner_url": "https://storage.googleapis.com/op-atlas/6e45f230-2ef2-43f1-ab9d-b95e2ac0f15e.png", "twitter": "https://x.com/shazow", - "repos": [ - "https://github.com/shazow/whatsabi" - ], "tags": [], - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/shazow/whatsabi", + "stargazers": 1141, + "lastUpdated": "2025-12-10T20:23:39Z" + } + ] }, { "id": "0x2247247c751707d897f5c0eab670426d9c1c26d84e96ac226004afbf0080cba4", @@ -2121,9 +2853,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/7e5161c3-ab8c-44e9-97b9-a957fa9cb7a2.png", "banner_url": "https://storage.googleapis.com/op-atlas/2985ee59-7f46-4626-93f4-fd91de426cd2.png", "twitter": "twitter.com/alchemy", - "repos": [ - "https://github.com/alchemyplatform/rundler" - ], "tags": [ "docker", "cross-chain", @@ -2133,7 +2862,14 @@ "scalability" ], "website": "www.alchemy.com", - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/alchemyplatform/rundler", + "stargazers": 369, + "lastUpdated": "2026-01-20T14:12:46Z" + } + ] }, { "id": "0x740bebbc731ec56dcc17c7d429656220a73960022c3809edf324bd8120285722", @@ -2142,9 +2878,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/73d7f842-6eb3-4a74-89df-176b8a69e4c2.png", "banner_url": "https://storage.googleapis.com/op-atlas/b5a6613d-fb1f-439c-ba1e-e0fcd42c99b5.png", "twitter": null, - "repos": [ - "https://github.com/alexfertel/bulloak" - ], "tags": [ "cli", "solidity", @@ -2155,7 +2888,14 @@ "code-coverage" ], "website": "https://www.bulloak.dev/", - "category": "Security, Testing & Formal Verification" + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/alexfertel/bulloak", + "stargazers": 342, + "lastUpdated": "2026-01-14T15:27:04Z" + } + ] }, { "id": "0xe6eb4d61eff4e2dc2d8dba01ac1b84c1683bdb1e8d677a66fa44a72e3f8b1faf", @@ -2164,9 +2904,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/e1983235-58da-4c36-86eb-63e593554d7e.png", "banner_url": "https://storage.googleapis.com/op-atlas/467a5d29-ee97-4610-8923-18346cbc3a4e.png", "twitter": "https://x.com/0xRaiden_", - "repos": [ - "https://github.com/Raiden1411/zabi" - ], "tags": [ "cross-chain", "json-rpc", @@ -2175,7 +2912,14 @@ "abi-encoding" ], "website": "zabi.sh", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Raiden1411/zabi", + "stargazers": 113, + "lastUpdated": "2026-01-11T09:24:48Z" + } + ] }, { "id": "0x7e5614eb46520c523562a641649be228012355d0264c9130b2c1d9872bf5bad5", @@ -2184,14 +2928,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/afd98fa3-7bf7-45a5-9d07-0f1dbea2ba61.png", "banner_url": "https://storage.googleapis.com/op-atlas/aa144789-e6d6-4af4-9634-7956915bfc8a.png", "twitter": null, - "repos": [ - "https://github.com/CollinsMunene/abiexplorer" - ], "tags": [ "contract-interaction" ], "website": "https://abiexplorer.devligence.com/", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/CollinsMunene/abiexplorer", + "stargazers": 3, + "lastUpdated": "2025-05-12T06:35:18Z" + } + ] }, { "id": "0x1e2cc195ce13784ef1e382bbd542a6b25d982b83377a8e8ac2ca593d6c310adc", @@ -2200,15 +2948,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/b2e8b33c-2f72-4854-b549-ea8ea9468eca.png", "banner_url": "https://storage.googleapis.com/op-atlas/b473d908-de6b-45f1-9b19-a3027ef207fc.png", "twitter": "https://x.com/web3privacy", - "repos": [ - "https://github.com/web3privacy/privacy-builder-pack" - ], "tags": [ "education", "encryption" ], "website": "https://build.web3privacy.info", - "category": "Education & Community Resources" + "category": "Education & Community Resources", + "repos": [ + { + "href": "https://github.com/web3privacy/privacy-builder-pack", + "stargazers": 4, + "lastUpdated": "2025-08-05T20:29:07Z" + } + ] }, { "id": "0xa38c8f4ffa48fe01222fe1b5f2bc6c95e204a4f243d67bd0c9f92887d905d3d8", @@ -2217,14 +2969,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/153bea66-bef0-481d-bb29-2882eb0e6edb.png", "banner_url": "https://storage.googleapis.com/op-atlas/1809a100-d320-47f2-8144-94343ef5ea40.png", "twitter": "https://x.com/web3privacy", - "repos": [ - "https://github.com/web3privacy/cypherpunkacademy" - ], "tags": [ "education" ], "website": "https://academy.web3privacy.info/", - "category": "Education & Community Resources" + "category": "Education & Community Resources", + "repos": [ + { + "href": "https://github.com/web3privacy/cypherpunkacademy", + "stargazers": 7, + "lastUpdated": "2025-02-07T18:51:24Z" + } + ] }, { "id": "0xec7002ee89bf249ae4fca1ebe718a66dea7247e33cfc9319f979a3f9fb324b24", @@ -2233,17 +2989,25 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/4b165837-402c-4f39-bc4f-fa5a0b931b8c.png", "banner_url": "https://storage.googleapis.com/op-atlas/161c3a2f-880d-4617-afda-746e97e7586c.png", "twitter": "https://x.com/web3privacy", - "repos": [ - "https://github.com/web3privacy/explorer-app", - "https://github.com/web3privacy/explorer-data" - ], "tags": [ "education", "analytics", "community-driven" ], "website": "https://explorer.web3privacy.info/", - "category": "Data, Analytics & Tracing" + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/web3privacy/explorer-app", + "stargazers": 3, + "lastUpdated": "2025-06-27T15:33:39Z" + }, + { + "href": "https://github.com/web3privacy/explorer-data", + "stargazers": 26, + "lastUpdated": "2026-01-15T03:09:10Z" + } + ] }, { "id": "0xbcfa7063514406f498f2792ae6435bf488709709391cebfa260a552703b4a8f9", @@ -2252,14 +3016,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/fae7d370-79b6-48b2-9d69-785cd2edb573.png", "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/qingfengzxr/gdscript-web3" - ], "tags": [ "game-development" ], "website": "https://github.com/qingfengzxr/gdscript-web3", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/qingfengzxr/gdscript-web3", + "stargazers": 29, + "lastUpdated": "2025-03-11T12:04:27Z" + } + ] }, { "id": "0x4a5e771af86cf1938056b43cddbf0018dca1376d578f631f7449fe10ac4958ed", @@ -2268,9 +3036,6 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/Nethereum/Nethereum" - ], "tags": [ "cross-chain", "wallet", @@ -2278,7 +3043,14 @@ "transaction-signing", "abi-encoding" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Nethereum/Nethereum", + "stargazers": 2245, + "lastUpdated": "2026-01-11T11:50:23Z" + } + ] }, { "id": "0x351967474a454b494260a488f3ceb77d993580a4fe79fb6b6d132c70634bc516", @@ -2287,9 +3059,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/8da31052-61ab-40c2-a9b6-18b0dd37824e.png", "banner_url": "https://storage.googleapis.com/op-atlas/e46839dc-55fb-45c5-8c47-d3282749cedb.png", "twitter": "https://x.com/ponder_sh", - "repos": [ - "https://github.com/ponder-sh/ponder" - ], "tags": [ "indexing", "support", @@ -2301,7 +3070,14 @@ "cli" ], "website": "https://ponder.sh", - "category": "Data, Analytics & Tracing" + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/ponder-sh/ponder", + "stargazers": 1023, + "lastUpdated": "2026-01-08T14:53:30Z" + } + ] }, { "id": "0x812ea3d88c189f53197820e1c648dd32c5b937467d93602a3ba5d0b764124f90", @@ -2310,15 +3086,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/401a6212-fc2a-4b46-8a96-52f597c82467.png", "banner_url": "https://storage.googleapis.com/op-atlas/18896241-e29b-4497-9d12-e27ea0045830.png", "twitter": "https://x.com/zsystmd", - "repos": [ - "https://github.com/zsystm/solizard" - ], "tags": [ "cli", "contract-interaction" ], "website": "https://github.com/zsystm/solizard", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/zsystm/solizard", + "stargazers": 66, + "lastUpdated": "2025-05-08T16:22:42Z" + } + ] }, { "id": "0xbe74d6076f833da93276495074d0356db90c495d3257f8958853e75e9df8e9c8", @@ -2327,9 +3107,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/b540988e-6db1-47de-84a4-bebe987ef595.png", "banner_url": "https://storage.googleapis.com/op-atlas/283678d8-970a-44ee-ba90-419f5359aac5.png", "twitter": "https://x.com/w3gptai", - "repos": [ - "https://github.com/markeljan/web3gpt" - ], "tags": [ "education", "cli", @@ -2337,7 +3114,14 @@ "natural-language-processing", "solidity" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/markeljan/web3gpt", + "stargazers": 112, + "lastUpdated": "2026-01-07T16:16:12Z" + } + ] }, { "id": "0xebe03c3d6d33cad60124b9b05ef6e2ff056293a1de3c5fa51dfbb90c86c14bf7", @@ -2346,19 +3130,39 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/287d64ad-b265-41e5-9569-25807ef5bba4.png", "banner_url": "https://storage.googleapis.com/op-atlas/c4ed28a3-a435-4725-8de3-ef463b073417.png", "twitter": "https://x.com/EthereumPython", - "repos": [ - "https://github.com/ethereum/web3.py", - "https://github.com/ethereum/py-evm", - "https://github.com/ethereum/eth-utils", - "https://github.com/ethereum/eth-abi", - "https://github.com/ethereum/eth-account" - ], "tags": [ "transaction-signing", "community-driven", "testing" ], - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/ethereum/web3.py", + "stargazers": 5472, + "lastUpdated": "2026-01-12T15:23:40Z" + }, + { + "href": "https://github.com/ethereum/py-evm", + "stargazers": 2363, + "lastUpdated": "2025-09-08T15:31:46Z" + }, + { + "href": "https://github.com/ethereum/eth-utils", + "stargazers": 334, + "lastUpdated": "2025-12-17T19:41:25Z" + }, + { + "href": "https://github.com/ethereum/eth-abi", + "stargazers": 253, + "lastUpdated": "2026-01-13T21:49:25Z" + }, + { + "href": "https://github.com/ethereum/eth-account", + "stargazers": 307, + "lastUpdated": "2025-12-19T17:51:20Z" + } + ] }, { "id": "0xa903038c6a307743fdca92164f38d5c392996c2417d66d5bf33012850d0585bf", @@ -2367,12 +3171,16 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/088c8fd2-0f5c-48b2-b3b7-94c72c70cba9.png", "banner_url": "https://storage.googleapis.com/op-atlas/1818ec80-87d0-4da1-a485-3ef2a43fadfb.png", "twitter": "https://x.com/jiffyscan", - "repos": [ - "https://github.com/jiffy-labs/jiffyscan-frontend" - ], "tags": [], "website": "https://www.jiffyscan.xyz/", - "category": "Data, Analytics & Tracing" + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/jiffy-labs/jiffyscan-frontend", + "stargazers": 23, + "lastUpdated": "2025-11-27T15:49:08Z" + } + ] }, { "id": "0xaa4cf223915387f8e0cd66640f86f4f770d0c1edfc4303ce1d596a735747e673", @@ -2381,17 +3189,29 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/55264cac-23b0-47e1-8cfb-e6691e876eaa.png", "banner_url": "https://storage.googleapis.com/op-atlas/c502f9bc-fcfe-4696-bf81-f90ed8d9786c.png", "twitter": null, - "repos": [ - "https://github.com/Farcaster-Attestation/op-attest", - "https://github.com/Farcaster-Attestation/farcaster-resolver", - "https://github.com/Farcaster-Attestation/farcaster-solidity" - ], "tags": [ "governance", "solidity", "farcaster" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Farcaster-Attestation/op-attest", + "stargazers": 2, + "lastUpdated": "2025-02-24T08:58:05Z" + }, + { + "href": "https://github.com/Farcaster-Attestation/farcaster-resolver", + "stargazers": 2, + "lastUpdated": "2025-05-31T11:59:20Z" + }, + { + "href": "https://github.com/Farcaster-Attestation/farcaster-solidity", + "stargazers": 1, + "lastUpdated": "2025-03-10T09:05:51Z" + } + ] }, { "id": "0xa38f3efb4fb8f6fcefb80f0262645ac05d5548cad0308ee49520c48c4e8cbd1f", @@ -2400,11 +3220,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/33fec99f-964b-4296-a409-77c4fc4674e8.png", "banner_url": "https://storage.googleapis.com/op-atlas/1ac64d7c-4267-4be3-80d6-c90bebb7e40c.png", "twitter": "https://x.com/growthepie_eth", - "repos": [ - "https://github.com/growthepie/gtp-frontend", - "https://github.com/growthepie/gtp-dna", - "https://github.com/growthepie/gtp" - ], "tags": [ "analytics", "education", @@ -2414,7 +3229,24 @@ "community-driven" ], "website": "https://www.growthepie.xyz/", - "category": "Data, Analytics & Tracing" + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/growthepie/gtp-frontend", + "stargazers": 11, + "lastUpdated": "2026-01-20T15:22:46Z" + }, + { + "href": "https://github.com/growthepie/gtp-dna", + "stargazers": 4, + "lastUpdated": "2026-01-20T09:36:43Z" + }, + { + "href": "https://github.com/growthepie/gtp", + "stargazers": 28, + "lastUpdated": "2026-01-20T08:48:46Z" + } + ] }, { "id": "0xab6214e09c6adc3022147ba7fffe1924f9bad3ecbe69e410f428808e91fd6f06", @@ -2423,14 +3255,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/9b6b9753-121c-4c3f-9a39-c2c48b5cf149.png", "banner_url": "https://storage.googleapis.com/op-atlas/0d1302f3-d1e0-4fe1-a10e-592b36cb139b.png", "twitter": "zinkonx", - "repos": [ - "https://github.com/zink-lang/zink" - ], "tags": [ "education" ], "website": "https://github.com/zink-lang/zink", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/zink-lang/zink", + "stargazers": 171, + "lastUpdated": "2025-04-22T15:32:48Z" + } + ] }, { "id": "0x46d784ec075b98efe6a23e515cad06f1b7081f082cb0c7502c68a7a76c38c9e2", @@ -2439,16 +3275,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/10cc25d9-eb1f-43f2-8126-7927acb952c2.png", "banner_url": "https://storage.googleapis.com/op-atlas/d6450ca3-f77e-40cf-8799-c61244ab93e3.png", "twitter": "https://x.com/DistriButler", - "repos": [ - "https://github.com/sifaw23/distributler" - ], "tags": [ "defi", "wallet", "nextjs" ], "website": "https://distributler.com/", - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/sifaw23/distributler", + "stargazers": 0, + "lastUpdated": "2025-02-05T18:11:43Z" + } + ] }, { "id": "0xd63cb23c26cc3bda03b1cc2971589fd26c9d22f3bbc8f1ff2bb74613e6d1c36d", @@ -2457,15 +3297,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/aa1c84f1-cd10-420c-a730-576e9e1ca7fd.png", "banner_url": "https://storage.googleapis.com/op-atlas/e5f2c4cb-fb66-4473-973c-1d98a51065a0.png", "twitter": "https://x.com/gnsps", - "repos": [ - "https://github.com/GNSPS/solidity-bytes-utils" - ], "tags": [ "solidity", "truffle" ], "website": "https://github.com/GNSPS/solidity-bytes-utils", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/GNSPS/solidity-bytes-utils", + "stargazers": 560, + "lastUpdated": "2025-05-22T18:04:26Z" + } + ] }, { "id": "0xc6052138bbdae5976fa2866f46b0537182d4126c4bb97485738d1b43f2276134", @@ -2474,12 +3318,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/278ce531-3de6-4f4c-8955-877541c7020b.png", "banner_url": "https://storage.googleapis.com/op-atlas/c78355fc-3512-4554-a6df-70392a31cae2.png", "twitter": "@thirdweb", - "repos": [ - "thirdweb-dev", - "https://github.com/thirdweb-dev/insight", - "https://github.com/thirdweb-dev/js", - "https://github.com/thirdweb-dev/contracts" - ], "tags": [ "frontend", "cross-chain", @@ -2488,7 +3326,24 @@ "real-time-data" ], "website": "https://www.linkedin.com/company/third-web/", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/thirdweb-dev/insight", + "stargazers": 69, + "lastUpdated": "2025-12-22T18:17:53Z" + }, + { + "href": "https://github.com/thirdweb-dev/js", + "stargazers": 616, + "lastUpdated": "2026-01-16T01:26:04Z" + }, + { + "href": "https://github.com/thirdweb-dev/contracts", + "stargazers": 1077, + "lastUpdated": "2025-08-08T08:21:00Z" + } + ] }, { "id": "0xfb3ac4e5f7665c6560e461c1b77ed896d355635947a6e58e217f345af8624dcd", @@ -2497,9 +3352,6 @@ "thumbnail_url": "https://cdn.charmverse.io/user-content/2d6a8f50-45c2-4658-a66a-74eca1149aa3/102ec612-ed55-4da8-b9fb-0bb3f5447e84/Ackee-Blockchain-Security-logo.jpg", "banner_url": "https://cdn.charmverse.io/user-content/2d6a8f50-45c2-4658-a66a-74eca1149aa3/f1984493-d1a1-424e-afc1-36e1fc33f573/Ackee-Blockchain-Twitter-Banner.jpeg", "twitter": "ackeeblockchain", - "repos": [ - "https://github.com/Ackee-Blockchain/solidity-for-vscode" - ], "tags": [ "education", "security", @@ -2508,7 +3360,14 @@ "contract-deployment", "proxy-contracts" ], - "category": "Security, Testing & Formal Verification" + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/Ackee-Blockchain/solidity-for-vscode", + "stargazers": 52, + "lastUpdated": "2025-11-24T20:31:17Z" + } + ] }, { "id": "0x6d30328dd0e058bdd4c55c51d5f785268770040a66edbd2830902c4d87efee9c", @@ -2517,16 +3376,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/4aa97110-63e2-4703-a3f5-e42bdebceaee.png", "banner_url": "https://storage.googleapis.com/op-atlas/50e95639-885c-4657-8141-4a3357fd732e.png", "twitter": "andrei0x309", - "repos": [ - "https://github.com/andrei0x309/clear-wallet" - ], "tags": [ "wallet", "frontend", "privacy-focused" ], "website": "https://clear-wallet.flashsoft.eu/", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/andrei0x309/clear-wallet", + "stargazers": 32, + "lastUpdated": "2025-09-03T11:33:28Z" + } + ] }, { "id": "0x5e6c436e48e56d6d9622ba5d0be0035c314e2b29d2afc8f5f1ee8ac75cd42532", @@ -2535,17 +3398,29 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/098487bf-4f43-4e5a-8621-9c6368304124.png", "banner_url": "https://storage.googleapis.com/op-atlas/d76ced7e-7d5e-4514-9706-ca097e3131c2.png", "twitter": "https://x.com/SnapshotLabs", - "repos": [ - "https://github.com/snapshot-labs/snapshot", - "https://github.com/snapshot-labs/sx-monorepo", - "https://github.com/snapshot-labs/sx-evm" - ], "tags": [ "governance", "cross-chain", "decentralized-governance" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/snapshot-labs/snapshot", + "stargazers": 9172, + "lastUpdated": "2025-12-03T20:46:50Z" + }, + { + "href": "https://github.com/snapshot-labs/sx-monorepo", + "stargazers": 47, + "lastUpdated": "2026-01-20T17:06:14Z" + }, + { + "href": "https://github.com/snapshot-labs/sx-evm", + "stargazers": 28, + "lastUpdated": "2025-06-17T14:09:02Z" + } + ] }, { "id": "0x541b7b08401d799b87f583c102a6c94cee7105f1b29dc630de5edbbd966d7c13", @@ -2554,9 +3429,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/05ac5706-2a13-4325-8333-183a730e7797.png", "banner_url": "https://storage.googleapis.com/op-atlas/f733c3ee-3819-40f8-9ee8-b94416a770d9.png", "twitter": null, - "repos": [ - "https://github.com/ethereum/fe" - ], "tags": [ "cli", "education", @@ -2565,7 +3437,14 @@ "type-safe" ], "website": "fe-lang.org", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/ethereum/fe", + "stargazers": 1715, + "lastUpdated": "2026-01-19T16:09:40Z" + } + ] }, { "id": "0x10e9fc6dd7d01e09bd9440d507846432333a06f779287b29199010e2f50579cd", @@ -2574,15 +3453,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/ae73d3f5-61cc-48ef-84e9-2b553d1f0739.png", "banner_url": "https://storage.googleapis.com/op-atlas/46c64ba6-5c38-4bc0-9ac7-d32a55a32637.png", "twitter": "x.com/wakeuplabs", - "repos": [ - "https://github.com/wakeuplabs/rfg1-optimism" - ], "tags": [ "analytics", "layer-2", "visualization" ], - "category": "Data, Analytics & Tracing" + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/wakeuplabs/rfg1-optimism", + "stargazers": 2, + "lastUpdated": "2024-09-04T19:12:33Z" + } + ] }, { "id": "0x51cda5996ef1a2ccd8fcf4ee5792337695599454c83eb1218c3ad4388dcb5bf5", @@ -2591,9 +3474,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/f219ada1-9d7d-4d1c-8a90-ea1b09eda31f.png", "banner_url": "https://storage.googleapis.com/op-atlas/3d5c829b-3fc4-4dcd-995d-978aceca64dc.png", "twitter": "https://twitter.com/sourcifyeth", - "repos": [ - "https://github.com/ethereum/sourcify" - ], "tags": [ "solidity", "vyper", @@ -2602,7 +3482,14 @@ "type-safe" ], "website": "https://sourcify.dev", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/ethereum/sourcify", + "stargazers": 896, + "lastUpdated": "2026-01-20T07:36:20Z" + } + ] }, { "id": "0xd4ed99cc6aaf73ca63b32f7a03b5427ac1d2955bf9efc31eb14f5773016988d0", @@ -2611,15 +3498,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/a73d46f5-87ba-4204-88eb-7ce51ab055de.png", "banner_url": "https://storage.googleapis.com/op-atlas/ffb2a694-74be-48f3-897d-96034c088b3a.png", "twitter": null, - "repos": [ - "https://github.com/upnodedev/signer-proxy" - ], "tags": [ "security", "docker", "transaction-signing" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/upnodedev/signer-proxy", + "stargazers": 14, + "lastUpdated": "2025-05-02T11:55:02Z" + } + ] }, { "id": "0xa0b16714baef75d97ec07fd48eaf42e79df92fe2a3c2d725d2388ede587ea54c", @@ -2628,18 +3519,34 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/ab983e5d-4c75-4fc9-9b02-187a4f479c8a.png", "banner_url": "https://storage.googleapis.com/op-atlas/238f7d0e-c18b-48ad-8e9a-24407ef90eaf.png", "twitter": "https://twitter.com/ApeFramework ", - "repos": [ - "https://github.com/ApeWorX/silverback", - "https://github.com/ApeWorX/ape", - "https://github.com/ApeWorX/ape-optimism", - "https://github.com/ApeWorX/ape-base" - ], "tags": [ "cross-chain", "layer-2", "cli" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/ApeWorX/silverback", + "stargazers": 128, + "lastUpdated": "2026-01-19T22:53:09Z" + }, + { + "href": "https://github.com/ApeWorX/ape", + "stargazers": 1023, + "lastUpdated": "2026-01-19T18:11:07Z" + }, + { + "href": "https://github.com/ApeWorX/ape-optimism", + "stargazers": 13, + "lastUpdated": "2025-02-07T20:11:15Z" + }, + { + "href": "https://github.com/ApeWorX/ape-base", + "stargazers": 2, + "lastUpdated": "2025-12-10T20:50:50Z" + } + ] }, { "id": "0x81af86360a8e964cc907a5689a62e94231c7e42e05f49c0586716975d72e2e2e", @@ -2648,22 +3555,54 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/91ebe6cd-12a6-42fb-b3ef-d717e79ac9b8.png", "banner_url": "https://storage.googleapis.com/op-atlas/84ec5980-5e06-4630-92b4-16ce9e9e3f83.png", "twitter": "https://x.com/upnodeIntern", - "repos": [ - "https://github.com/upnodedev/opstack-cli", - "https://github.com/upnodedev/opstack-bridge-ui-v2", - "https://github.com/upnodedev/evm-faucet", - "https://github.com/upnodedev/upnode-deploy-ui", - "https://github.com/upnodedev/opstack-compose", - "https://github.com/upnodedev/opstack-bridge-ui", - "https://github.com/upnodedev/opstack-bridge-indexer", - "https://github.com/upnodedev/opstack-bridge-indexer-v2" - ], "tags": [ "cli", "docker", "devops" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/upnodedev/opstack-cli", + "stargazers": 5, + "lastUpdated": "2025-05-13T14:31:21Z" + }, + { + "href": "https://github.com/upnodedev/opstack-bridge-ui-v2", + "stargazers": 0, + "lastUpdated": "2024-12-03T09:11:37Z" + }, + { + "href": "https://github.com/upnodedev/evm-faucet", + "stargazers": 0, + "lastUpdated": "2024-09-03T18:43:46Z" + }, + { + "href": "https://github.com/upnodedev/upnode-deploy-ui", + "stargazers": 0, + "lastUpdated": "2024-10-31T10:15:16Z" + }, + { + "href": "https://github.com/upnodedev/opstack-compose", + "stargazers": 12, + "lastUpdated": "2024-10-11T16:20:03Z" + }, + { + "href": "https://github.com/upnodedev/opstack-bridge-ui", + "stargazers": 0, + "lastUpdated": "2024-09-03T18:46:42Z" + }, + { + "href": "https://github.com/upnodedev/opstack-bridge-indexer", + "stargazers": 1, + "lastUpdated": "2024-09-03T18:49:14Z" + }, + { + "href": "https://github.com/upnodedev/opstack-bridge-indexer-v2", + "stargazers": 0, + "lastUpdated": "2024-10-29T12:59:44Z" + } + ] }, { "id": "0x7504e494cb8d227193182e083128912173c14eaeecec9b90fa453de28377b269", @@ -2672,16 +3611,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/90c0de0c-cc0e-4959-afb7-a78ae4c9d674.png", "banner_url": "https://storage.googleapis.com/op-atlas/e1d59a51-3f6f-4642-bc88-553026d2d067.png", "twitter": "@yiannisbot", - "repos": [ - "https://github.com/probe-lab/hermes" - ], "tags": [ "governance", "gossipsub", "libp2p", "cli" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/probe-lab/hermes", + "stargazers": 43, + "lastUpdated": "2025-12-04T10:35:24Z" + } + ] }, { "id": "0xada9c2eabe94a7af5d96b3cb1765c8e3d6fb8a7f8e33f12ebd6d66feb1a807a3", @@ -2690,18 +3633,40 @@ "thumbnail_url": "https://cdn.charmverse.io/user-content/cae02d37-eadb-4a01-a063-d72588a78203/a6dfa7b6-3b1c-4ff3-b5e5-f82624024c5e/Icon-(Color).svg", "banner_url": "https://cdn.charmverse.io/user-content/cae02d37-eadb-4a01-a063-d72588a78203/3151e0b3-b99e-4da6-9fdf-e98c3e985c22/Curvegrid-Banner-(1).png", "twitter": "https://x.com/curvegridinc", - "repos": [ - "https://github.com/curvegrid/multibaas-sdk-go", - "https://github.com/curvegrid/multibaas-sdk-typescript", - "https://github.com/curvegrid/multibaas-for-google-sheets", - "https://github.com/curvegrid/multibaas-sample-app", - "https://github.com/curvegrid/hardhat-multibaas-plugin", - "https://github.com/curvegrid/" - ], "tags": [ "defi" ], - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/curvegrid/multibaas-sdk-go", + "stargazers": 3, + "lastUpdated": "2025-10-24T08:08:31Z" + }, + { + "href": "https://github.com/curvegrid/multibaas-sdk-typescript", + "stargazers": 5, + "lastUpdated": "2025-10-24T08:08:51Z" + }, + { + "href": "https://github.com/curvegrid/multibaas-for-google-sheets", + "stargazers": 15, + "lastUpdated": "2025-05-09T03:14:38Z" + }, + { + "href": "https://github.com/curvegrid/multibaas-sample-app", + "stargazers": 19, + "lastUpdated": "2025-09-24T11:47:38Z" + }, + { + "href": "https://github.com/curvegrid/hardhat-multibaas-plugin", + "stargazers": 11, + "lastUpdated": "2025-11-28T10:07:41Z" + }, + { + "href": "https://github.com/curvegrid/" + } + ] }, { "id": "0xdd8b2e68cad9afa0701c8f27bf085302b152dbca3393083d3c664e3fc75945ab", @@ -2710,10 +3675,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/3cc6bd19-1ade-4c0d-8fe3-ec6ea6f50183.png", "banner_url": "https://storage.googleapis.com/op-atlas/d2d120fb-11fa-456c-b7e0-b0ed52b477e0.png", "twitter": "", - "repos": [ - "https://github.com/Ratimon/redprint-forge", - "https://github.com/Ratimon/redprint-wizard" - ], "tags": [ "education", "frontend", @@ -2721,7 +3682,19 @@ "type-safe" ], "website": "https://redprint.ninja/", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Ratimon/redprint-forge", + "stargazers": 51, + "lastUpdated": "2025-02-15T09:07:50Z" + }, + { + "href": "https://github.com/Ratimon/redprint-wizard", + "stargazers": 55, + "lastUpdated": "2025-04-21T02:52:44Z" + } + ] }, { "id": "0x11a2255f272c84328438f5081139455d8fd2a302fd35f0f08acdff1f1c0d84e6", @@ -2730,15 +3703,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/6878f254-b99f-47ad-8cf8-7f6cd1601300.png", "banner_url": "https://storage.googleapis.com/op-atlas/8f285391-e69f-40f3-aa14-1456fbb92440.png", "twitter": "https://x.com/nodeguardians", - "repos": [ - "https://github.com/Nodeguardians/optimism" - ], "tags": [ "education", "solidity" ], "website": "https://nodeguardians.io/", - "category": "Education & Community Resources" + "category": "Education & Community Resources", + "repos": [ + { + "href": "https://github.com/Nodeguardians/optimism", + "stargazers": 0, + "lastUpdated": "2024-09-03T14:22:05Z" + } + ] }, { "id": "0xcc8d03e014e121d10602eeff729b755d5dc6a317df0d6302c8a9d3b5424aaba8", @@ -2747,10 +3724,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/b6f312d0-1025-4a19-baa9-3aa218fe0833.png", "banner_url": "https://storage.googleapis.com/op-atlas/bca65077-a87b-4fd8-bcc3-9ad0a65d9d27.png", "twitter": "https://x.com/solidity_lang", - "repos": [ - "https://github.com/ethereum/solidity", - "https://github.com/ethereum/solc-js" - ], "tags": [ "education", "solidity", @@ -2758,7 +3731,19 @@ "cli" ], "website": "https://soliditylang.org/", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/ethereum/solidity", + "stargazers": 25502, + "lastUpdated": "2026-01-19T23:37:55Z" + }, + { + "href": "https://github.com/ethereum/solc-js", + "stargazers": 1503, + "lastUpdated": "2025-12-18T20:41:21Z" + } + ] }, { "id": "0x1aacb85f1d87039696b876ddcae98c56d38ea9eed07b265409fdb256c8f8172a", @@ -2767,15 +3752,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/3a1343aa-8bb3-4f30-abc0-6ba02dd3787a.png", "banner_url": "https://storage.googleapis.com/op-atlas/7c1ee7ff-ad46-4b74-a941-48cc7ddc2dbe.png", "twitter": "https://x.com/0xBlockhead", - "repos": [ - "darrylyeo/blockhead", - "https://github.com/darrylyeo/blockhead" - ], "tags": [ "block-explorer" ], "website": "https://blockhead.info", - "category": "Data, Analytics & Tracing" + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/darrylyeo/blockhead", + "stargazers": 135, + "lastUpdated": "2025-05-18T04:45:05Z" + } + ] }, { "id": "0xdf1bb03d08808e2d789f5eac8462bdc560f1bb5b0877f0cf8c66ab53a0bc2f5c", @@ -2784,15 +3772,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/352a5108-5f07-4765-a43d-7ba0b4b27054.png", "banner_url": "https://storage.googleapis.com/op-atlas/01e43966-8955-4584-b45d-84645a97dc5d.png", "twitter": "@sigp_io", - "repos": [ - "https://github.com/libp2p/rust-libp2p" - ], "tags": [ "docker", "community-driven" ], "website": "https://sigmaprime.io", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/libp2p/rust-libp2p", + "stargazers": 5368, + "lastUpdated": "2026-01-19T16:03:13Z" + } + ] }, { "id": "0x9b014e8a2e062401d976745d9c8aafbf36bce7931586b36ecf3b9ad708bf2970", @@ -2801,12 +3793,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/af580f21-8a05-40b2-b839-aaed37495186.png", "banner_url": "https://storage.googleapis.com/op-atlas/6fee849e-314e-4285-92d9-b6b27d09f4a3.png", "twitter": "https://x.com/blobscan", - "repos": [ - "https://github.com/Blobscan/blobscan-helm-charts", - "https://github.com/Blobscan/blobscan-indexer.rs", - "https://github.com/Blobscan/blobscan", - "https://github.com/Blobscan/blobscan-infra" - ], "tags": [ "analytics", "docker", @@ -2814,7 +3800,29 @@ "visualization" ], "website": "https://blobscan.com/", - "category": "Data, Analytics & Tracing" + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/Blobscan/blobscan-helm-charts", + "stargazers": 0, + "lastUpdated": "2025-09-08T19:57:42Z" + }, + { + "href": "https://github.com/Blobscan/blobscan-indexer.rs", + "stargazers": 44, + "lastUpdated": "2026-01-08T02:45:59Z" + }, + { + "href": "https://github.com/Blobscan/blobscan", + "stargazers": 101, + "lastUpdated": "2026-01-15T15:23:13Z" + }, + { + "href": "https://github.com/Blobscan/blobscan-infra", + "stargazers": 3, + "lastUpdated": "2026-01-16T17:56:35Z" + } + ] }, { "id": "0xd9d413772483111ca8ecfe5054737c6c80a65f03c0d289c632b05e3ec21d5680", @@ -2823,43 +3831,47 @@ "thumbnail_url": "https://cdn.charmverse.io/user-content/e3eb66db-408b-4e21-bc69-c2927fd15b32/552ea203-8cee-4111-9a61-82fd3da74367/ok.png", "banner_url": "https://cdn.charmverse.io/user-content/e3eb66db-408b-4e21-bc69-c2927fd15b32/874ceabb-8637-48ef-935d-747218d514fc/opstackkit-cover.jpg", "twitter": "opstackkit", - "repos": [ - "opstack-kit", - "https://github.com/opstack-kit/opstack-kit" - ], "tags": [ "cli", "cross-chain" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/opstack-kit/opstack-kit", + "stargazers": 17, + "lastUpdated": "2025-02-23T16:58:53Z" + } + ] }, { "id": "0x5a7e7c7acb21521e99021d746740b368801cbfe531301e50bdbaafdc24a0aac5", "name": "js-libp2p", - "description": "The canonical JavaScript implementation of libp2p. Js-libp2p is a collection of protocols that support a wide range of functionalities, such as; connection establishment, remote node protocol identification and negotiation (through its identify protocol), data encryption, content/peer discovery (through its Kademlia DHT component), and data transfer through its pub-sub protocol (Gossipsub).\n\nThe stakeholders of js-libp2p include the Interplanetary Shipyard team who maintain this implementation as well as projects that depend on js-libp2p like major on-chain builder apps like Farcaster. Farcaster contracts are deployed on Optimism and they rely directly on js-libp2p in Farcaster Hubs (transports and protocols like GossipSub).\n\nAdditionally, ChainSafe's Lodestar (Ethereum consensus client written in Typescript), Ocean Protocol (in their Ocean Nodes implementation), OrbitDB (a serverless, distributed, peer-to-peer database), Warden Protocol, and many more: https://github.com/libp2p/js-libp2p/tree/main#used-by and https://github.com/libp2p/js-libp2p/network/dependents.", + "description": "The canonical JavaScript implementation of libp2p. Js-libp2p is a collection of protocols that support a wide range of functionalities, such as; connection establishment, remote node protocol identification and negotiation (through its identify protocol), data encryption, content/peer discovery (through its Kademlia DHT component), and data transfer through its pub-sub protocol (Gossipsub).\n\nThe stakeholders of js-libp2p include the Interplanetary Shipyard team who maintain this implementation as well as projects that depend on js-libp2p like major on-chain builder apps like Farcaster. Farcaster contracts are deployed on Optimism and they rely directly on js-libp2p in Farcaster Hubs (transports and protocols like GossipSub).\n\nAdditionally, ChainSafe's Lodestar (Ethereum consensus client written in Typescript), Ocean Protocol (in their Ocean Nodes implementation), OrbitDB (a serverless, distributed, peer-to-peer database), Warden Protocol, and many more: https://github.com/libp2p/js-libp2p/tree/main#used-by and https://github.com/libp2p/js-libp2p/network/dependents.", "thumbnail_url": "https://storage.googleapis.com/op-atlas/11d09c62-9356-40b2-9cd2-06b98f816bfb.png", "banner_url": "https://storage.googleapis.com/op-atlas/826fafd9-28a8-49f8-9d07-0e5e57880f20.png", "twitter": "https://x.com/ipshipyard", - "repos": [ - "https://github.com/libp2p/js-libp2p" - ], "tags": [ "libp2p", "encryption", "gossipsub" ], - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/libp2p/js-libp2p", + "stargazers": 2520, + "lastUpdated": "2026-01-16T15:40:11Z" + } + ] }, { "id": "0xc71faa1bcb4ceb785816c3f22823377e9e5e7c48649badd9f0a0ce491f20d4b3", "name": "go-libp2p", - "description": "The canonical Golang implementation of libp2p. Go-libp2p is a collection of protocols that support a wide range of functionalities, such as; connection establishment, remote node protocol identification and negotiation (through its identify protocol), data encryption, content/peer discovery (through its Kademlia DHT component), and data transfer through its pub-sub protocol (Gossipsub).\n\nThe stakeholders of go-libp2p include the Interplanetary Shipyard team who maintain this implementation as well as projects that depend on go-libp2p like Optimism's op-node (the reference implementation of the rollup-node spec), the Ethereum Beacon Chain (via Prysm, the Go consensus client), Filecoin (Lotus and Venus), Celestia node, and many more: https://github.com/libp2p/go-libp2p?tab=readme-ov-file#notable-users.", + "description": "The canonical Golang implementation of libp2p. Go-libp2p is a collection of protocols that support a wide range of functionalities, such as; connection establishment, remote node protocol identification and negotiation (through its identify protocol), data encryption, content/peer discovery (through its Kademlia DHT component), and data transfer through its pub-sub protocol (Gossipsub).\n\nThe stakeholders of go-libp2p include the Interplanetary Shipyard team who maintain this implementation as well as projects that depend on go-libp2p like Optimism's op-node (the reference implementation of the rollup-node spec), the Ethereum Beacon Chain (via Prysm, the Go consensus client), Filecoin (Lotus and Venus), Celestia node, and many more: https://github.com/libp2p/go-libp2p?tab=readme-ov-file#notable-users.", "thumbnail_url": "https://storage.googleapis.com/op-atlas/277d8353-44c4-4e16-a2bd-2dfb3fb9e65f.png", "banner_url": "https://storage.googleapis.com/op-atlas/4c70ca4a-8b38-47ee-97d0-2a64a63700f8.png", "twitter": "https://x.com/ipshipyard", - "repos": [ - "https://github.com/libp2p/go-libp2p" - ], "tags": [ "governance", "libp2p", @@ -2869,7 +3881,14 @@ "gossipsub", "community-driven" ], - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/libp2p/go-libp2p", + "stargazers": 6683, + "lastUpdated": "2026-01-08T19:05:11Z" + } + ] }, { "id": "0xa7d78d566bfa319479ec048c94c3d8c1f4d628a9344ba157fc4974dbf472dc3e", @@ -2878,9 +3897,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/0c66d95b-8f82-45a2-87a8-77205bf90a96.png", "banner_url": "https://storage.googleapis.com/op-atlas/dcb9e7e2-4619-4382-af31-a5c9a75e703f.png", "twitter": "https://x.com/CyfrinAudits", - "repos": [ - "https://github.com/Cyfrin/aderyn" - ], "tags": [ "cli", "security", @@ -2891,7 +3907,14 @@ "community-driven" ], "website": "https://github.com/Cyfrin/aderyn", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Cyfrin/aderyn", + "stargazers": 705, + "lastUpdated": "2026-01-19T09:07:41Z" + } + ] }, { "id": "0x7348ae42266ff626319e8ea5398343b847603b3cc7101b03d8e4fb2b75ea8db3", @@ -2900,14 +3923,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/1dce415e-060b-4f57-83ed-71ba91207614.png", "banner_url": "https://storage.googleapis.com/op-atlas/e0035388-4b23-4215-98e3-c96e712cc18c.png", "twitter": "https://x.com/rv_inc", - "repos": [ - "https://github.com/runtimeverification/_audits_lidofinance_dual-governance_fork", - "https://github.com/runtimeverification/yearn-v3-term-vault", - "https://github.com/runtimeverification/kontrol", - "https://github.com/runtimeverification/Depeg-swap", - "https://github.com/runtimeverification/optimism-ci", - "https://github.com/runtimeverification/_audits_Ethereum-optimism_pausability" - ], "tags": [ "foundry", "education", @@ -2918,7 +3933,39 @@ "contract-deployment", "static-analysis" ], - "category": "Security, Testing & Formal Verification" + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/runtimeverification/_audits_lidofinance_dual-governance_fork", + "stargazers": 1, + "lastUpdated": "2025-02-18T20:57:22Z" + }, + { + "href": "https://github.com/runtimeverification/yearn-v3-term-vault", + "stargazers": 0, + "lastUpdated": "2025-02-19T16:34:35Z" + }, + { + "href": "https://github.com/runtimeverification/kontrol", + "stargazers": 87, + "lastUpdated": "2025-12-19T15:44:45Z" + }, + { + "href": "https://github.com/runtimeverification/Depeg-swap", + "stargazers": 0, + "lastUpdated": "2025-02-19T16:33:07Z" + }, + { + "href": "https://github.com/runtimeverification/optimism-ci", + "stargazers": 4, + "lastUpdated": "2025-02-18T20:03:05Z" + }, + { + "href": "https://github.com/runtimeverification/_audits_Ethereum-optimism_pausability", + "stargazers": 0, + "lastUpdated": "2025-06-06T08:42:21Z" + } + ] }, { "id": "0x229bbc8163bdee3891cde1c18c74ab3afc72e8683692fc7f1b767570cbe7c4a7", @@ -2927,13 +3974,6 @@ "thumbnail_url": "https://cdn.charmverse.io/user-content/9c114ea1-adb5-4858-b4f2-40050fa74370/99b90eeb-a7ea-4ca6-938e-410fff892510/Social.png", "banner_url": "https://cdn.charmverse.io/user-content/9c114ea1-adb5-4858-b4f2-40050fa74370/b2606c27-a963-43aa-8e78-e38e89897808/pexels-mont-photographs-385313-2948636.jpg", "twitter": "https://x.com/ExplorerEVM", - "repos": [ - "https://github.com/Pfed-prog/NextJsExplorer", - "https://github.com/Pfed-prog/EVMExplorer-Blockscout", - "https://github.com/Pfed-prog/EVMExplorer-Uniswap", - "https://github.com/Pfed-prog/EVMExplorer-Utility", - "Pfed-prog/NextJsExplorer" - ], "tags": [ "analytics", "governance", @@ -2941,7 +3981,29 @@ "visualization" ], "website": "https://evmexplorer.com/", - "category": "Data, Analytics & Tracing" + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/Pfed-prog/NextJsExplorer", + "stargazers": 25, + "lastUpdated": "2026-01-12T18:29:39Z" + }, + { + "href": "https://github.com/Pfed-prog/EVMExplorer-Blockscout", + "stargazers": 2, + "lastUpdated": "2025-12-24T22:07:19Z" + }, + { + "href": "https://github.com/Pfed-prog/EVMExplorer-Uniswap", + "stargazers": 1, + "lastUpdated": "2025-10-07T11:46:23Z" + }, + { + "href": "https://github.com/Pfed-prog/EVMExplorer-Utility", + "stargazers": 1, + "lastUpdated": "2025-10-07T10:46:13Z" + } + ] }, { "id": "0x2c97e213fef2bd3f30a71edf6ed48232640368d0083dc0a134a1b59391639bde", @@ -2950,16 +4012,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/d7cf4059-4f9c-48aa-a37a-df2f8c81933c.png", "banner_url": "https://storage.googleapis.com/op-atlas/020d34f6-e8bb-43b5-8508-7935d2b00583.png", "twitter": null, - "repos": [ - "https://github.com/ethereum/hevm" - ], "tags": [ "cli", "foundry", "security", "symbolic-execution" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/ethereum/hevm", + "stargazers": 326, + "lastUpdated": "2026-01-20T14:44:24Z" + } + ] }, { "id": "0xf2a60464d2a56fb47d2f8c13001edea71eda11ffd8fffec5f559495c6a5878d4", @@ -2968,10 +4034,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/ff2964ec-4435-4cf8-b993-e16f49b47b96.png", "banner_url": "https://storage.googleapis.com/op-atlas/58530a8a-1957-45c8-92dd-808196c1491f.png", "twitter": "https://x.com/unruggable_eth", - "repos": [ - "https://github.com/unruggable-labs/unruggable-gateways-examples", - "https://github.com/unruggable-labs/unruggable-gateways" - ], "tags": [ "cross-chain", "layer-2", @@ -2980,7 +4042,19 @@ "scalability" ], "website": "https://unruggable.com/", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/unruggable-labs/unruggable-gateways-examples", + "stargazers": 5, + "lastUpdated": "2025-10-13T15:50:04Z" + }, + { + "href": "https://github.com/unruggable-labs/unruggable-gateways", + "stargazers": 91, + "lastUpdated": "2025-12-08T16:34:19Z" + } + ] }, { "id": "0x2704cd27b8c60b098d4fe8c5c0fbae2f8f5fe9067c687c501a4c6dc6e9887876", @@ -2989,16 +4063,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/a08fa912-3bc7-4957-9a64-5b10bc13397e.png", "banner_url": "https://storage.googleapis.com/op-atlas/16e8a1cb-69b1-4098-8c40-fd25a5a29b8f.png", "twitter": null, - "repos": [ - "https://github.com/ethereum/act" - ], "tags": [ "education", "analytics", "formal-verification", "symbolic-execution" ], - "category": "Security, Testing & Formal Verification" + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/ethereum/act", + "stargazers": 260, + "lastUpdated": "2025-12-09T08:24:27Z" + } + ] }, { "id": "0x7d3f1d8e9da32b6e81e791a440b28ce9fbd79a5396acc4039d1cdc44c609c6d3", @@ -3007,14 +4085,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/90d877db-39f3-4b3c-bb8e-90f26e734254.png", "banner_url": "https://storage.googleapis.com/op-atlas/6e5a0785-93ce-438a-af3d-d81460919f57.png", "twitter": "", - "repos": [ - "https://github.com/Aymen-Tirchi/op-stack-deployer" - ], "tags": [ "cli", "foundry" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Aymen-Tirchi/op-stack-deployer", + "stargazers": 19, + "lastUpdated": "2025-02-10T08:35:38Z" + } + ] }, { "id": "0xb2d109759fe14e11ac5cc100ab6006321ebdd7ffdefbd2efac93a002105f8e92", @@ -3023,14 +4105,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/57aeca37-e53b-4bcb-b161-0608d09e5c62.png", "banner_url": "https://storage.googleapis.com/op-atlas/786c9752-af70-4856-9be0-38f4141769d2.png", "twitter": "https://x.com/rakitadragan", - "repos": [ - "https://github.com/bluealloy/revm" - ], "tags": [ "community-driven" ], "website": "https://github.com/bluealloy/revm", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/bluealloy/revm", + "stargazers": 2115, + "lastUpdated": "2026-01-20T18:17:57Z" + } + ] }, { "id": "0x6bd057da522918a4675396313ae33a2f2788a1ceeb3bd7ae228015e3eb317a7d", @@ -3039,16 +4125,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/171f60c2-1e3e-4b0a-998e-4015a7f468f7.png", "banner_url": "https://storage.googleapis.com/op-atlas/64c06023-a910-4646-ba3e-81baa2d935dc.png", "twitter": "https://x.com/wevm_dev", - "repos": [ - "https://github.com/wevm/viem" - ], "tags": [ "json-rpc", "type-safe", "hardhat" ], "website": "https://viem.sh", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/wevm/viem", + "stargazers": 3372, + "lastUpdated": "2026-01-15T16:35:59Z" + } + ] }, { "id": "0x9151666888d0ca532a529be98a50d2eb992988117e202163f865fa9a27eb7149", @@ -3057,9 +4147,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/0e726459-df1e-4cea-bddb-25399f88acea.png", "banner_url": "https://storage.googleapis.com/op-atlas/0615ef25-edbb-4b19-934d-79614daf8040.png", "twitter": "https://twitter.com/optimizoor", - "repos": [ - "https://github.com/Vectorized/solady" - ], "tags": [ "education", "solidity", @@ -3068,7 +4155,14 @@ "hardhat" ], "website": "https://solady.org", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Vectorized/solady", + "stargazers": 3255, + "lastUpdated": "2025-12-30T14:22:09Z" + } + ] }, { "id": "0x492d0bbb85672e7e5f1d439bfd8857ac0aa59a52010143bbaab1a411bf55be0c", @@ -3077,12 +4171,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/c76c04f2-a5d4-488b-b427-0d1580bcfd9e.png", "banner_url": "https://storage.googleapis.com/op-atlas/e5114d50-c66b-41ab-b064-14802e9f927a.png", "twitter": "https://twitter.com/turtleshell_xyz", - "repos": [ - "https://www.npmjs.com/package/@markeljan/circuitbreaker", - "https://github.com/turtleshell-xyz/circuitbreaker", - "https://github.com/turtleshell-xyz/frontend-boilerplates", - "https://github.com/turtleshell-xyz/nomad-bridge-poc" - ], "tags": [ "frontend", "security", @@ -3092,7 +4180,28 @@ "truffle" ], "website": "turtleshell.xyz", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://www.npmjs.com/package/@markeljan/circuitbreaker", + "downloads": 1 + }, + { + "href": "https://github.com/turtleshell-xyz/circuitbreaker", + "stargazers": 0, + "lastUpdated": "2024-10-18T12:29:36Z" + }, + { + "href": "https://github.com/turtleshell-xyz/frontend-boilerplates", + "stargazers": 0, + "lastUpdated": "2024-08-03T17:59:55Z" + }, + { + "href": "https://github.com/turtleshell-xyz/nomad-bridge-poc", + "stargazers": 0, + "lastUpdated": "2024-08-03T17:56:48Z" + } + ] }, { "id": "0xc2d8139cd61ddc75689610ee0cca0fe37ba8bec3270beb6aac6eac91c6256f60", @@ -3101,17 +4210,23 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/08754b7b-75c3-436b-ad66-bdf4b4261895.png", "banner_url": "https://storage.googleapis.com/op-atlas/a3c56a18-2e9d-4a19-ba54-892bfa062884.png", "twitter": null, - "repos": [ - "https://github.com/cgewecke/hardhat-gas-reporter", - "https://www.npmjs.com/package/hardhat-gas-reporter" - ], "tags": [ "analytics", "hardhat", "test-automation" ], "website": "https://www.npmjs.com/package/hardhat-gas-reporter", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/cgewecke/hardhat-gas-reporter", + "stargazers": 433, + "lastUpdated": "2025-06-01T00:24:43Z" + }, + { + "href": "https://www.npmjs.com/package/hardhat-gas-reporter" + } + ] }, { "id": "0x9ca1f7b0e0d10d3bd2619e51a54f2e4175e029c87a2944cf1ebc89164ba77ea0", @@ -3120,14 +4235,18 @@ "thumbnail_url": "https://cdn.charmverse.io/user-content/5302de23-eae6-4cda-97aa-25fefd829726/9aa6f15f-e32a-4bca-a40a-5b1e1122babb/2024-06-11_23-25.png", "banner_url": "https://cdn.charmverse.io/user-content/5302de23-eae6-4cda-97aa-25fefd829726/6c137923-55fc-4dc9-9424-5dad59f82ab4/vyper-optimism.png", "twitter": "https://x.com/vyperlang?lang=en", - "repos": [ - "https://github.com/vyperlang/vyper" - ], "tags": [ "compiler", "devops" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/vyperlang/vyper", + "stargazers": 5163, + "lastUpdated": "2026-01-17T20:46:52Z" + } + ] }, { "id": "0x0008577196fa6ec286440b418e2f6305fc10e62ce759625d826be272ee6b45a3", @@ -3136,16 +4255,24 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/4e18f37a-1991-48a1-9622-c43fa3e04f3e.png", "banner_url": "https://storage.googleapis.com/op-atlas/a508253b-4224-4c48-8519-3fefcf39fc2f.png", "twitter": null, - "repos": [ - "https://github.com/pcaversaccio/createx/releases/tag/v1.0.0", - "https://github.com/pcaversaccio/createx" - ], "tags": [ "cli", "contract-deployment", "solidity" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/pcaversaccio/createx/releases/tag/v1.0.0", + "stargazers": 524, + "lastUpdated": "2026-01-20T12:18:40Z" + }, + { + "href": "https://github.com/pcaversaccio/createx", + "stargazers": 524, + "lastUpdated": "2026-01-20T12:18:40Z" + } + ] }, { "id": "0x50159544ec22884b777a997a625c75bb02e55b1dc8934aad3b78678e7c11d039", @@ -3154,18 +4281,23 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/baed8e76-d872-4218-9648-9bb5700dabc9.png", "banner_url": "https://storage.googleapis.com/op-atlas/e205286d-1799-4d72-992a-a8ebe394c59b.png", "twitter": null, - "repos": [ - "https://pypi.org/project/snekmate", - "https://www.npmjs.com/package/snekmate", - "https://github.com/pcaversaccio/snekmate" - ], "tags": [ "defi", "vyper", "erc721", "foundry" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://www.npmjs.com/package/snekmate" + }, + { + "href": "https://github.com/pcaversaccio/snekmate", + "stargazers": 580, + "lastUpdated": "2026-01-19T18:29:33Z" + } + ] }, { "id": "0x4cba820efd9e11754eb472ca0736756f27d0ece09adb3c9651bac5b29acc9a6d", @@ -3174,15 +4306,22 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/dbe12049-50ea-4cfb-b3f0-8def50ea7b07.png", "banner_url": "https://storage.googleapis.com/op-atlas/191beaf8-e92f-42be-ab94-2305d12da9a4.png", "twitter": "https://x.com/BlockflowLabs", - "repos": [ - "https://github.com/blockflowlabs/cli-examples", - "https://www.npmjs.com/package/@blockflow-labs/cli/v/1.0.7-beta.1" - ], "tags": [ "cli" ], "website": "https://www.blockflow.network/", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/blockflowlabs/cli-examples", + "stargazers": 5, + "lastUpdated": "2024-11-21T20:06:43Z" + }, + { + "href": "https://www.npmjs.com/package/@blockflow-labs/cli/v/1.0.7-beta.1", + "downloads": 41 + } + ] }, { "id": "0x1c25ae2899ab6edb1e55c8cda5b736bb861a31da22bb9aa538f3868807eb1c73", @@ -3191,18 +4330,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/d334c376-0ff1-4c76-94bf-2ee675cae1d3.png", "banner_url": "https://storage.googleapis.com/op-atlas/a21ed458-efea-4d35-8aa9-b26d5e7bafad.png", "twitter": "x.com/bonadocs", - "repos": [ - "https://github.com/bonadocs/protocol-registry", - "https://www.npmjs.com/package/@bonadocs/zimulatoor", - "https://www.npmjs.com/package/@bonadocs/widget", - "https://github.com/bonadocs/docgen", - "https://github.com/bonadocs/docs", - "https://github.com/bonadocs/cli", - "https://github.com/bonadocs/protocol-registry-web", - "https://www.npmjs.com/package/@bonadocs/docgen", - "https://www.npmjs.com/package/@bonadocs/core", - "https://www.npmjs.com/package/@bonadocs/cli" - ], "tags": [ "cli", "frontend", @@ -3210,7 +4337,54 @@ "solidity-development" ], "website": "bonadocs.com", - "category": "Education & Community Resources" + "category": "Education & Community Resources", + "repos": [ + { + "href": "https://github.com/bonadocs/protocol-registry", + "stargazers": 0, + "lastUpdated": "2025-04-29T13:04:56Z" + }, + { + "href": "https://www.npmjs.com/package/@bonadocs/zimulatoor", + "downloads": 2 + }, + { + "href": "https://www.npmjs.com/package/@bonadocs/widget", + "downloads": 6 + }, + { + "href": "https://github.com/bonadocs/docgen", + "stargazers": 0, + "lastUpdated": "2025-04-03T17:49:44Z" + }, + { + "href": "https://github.com/bonadocs/docs", + "stargazers": 0, + "lastUpdated": "2025-08-19T22:05:46Z" + }, + { + "href": "https://github.com/bonadocs/cli", + "stargazers": 0, + "lastUpdated": "2025-04-03T17:53:33Z" + }, + { + "href": "https://github.com/bonadocs/protocol-registry-web", + "stargazers": 0, + "lastUpdated": "2025-04-03T17:55:20Z" + }, + { + "href": "https://www.npmjs.com/package/@bonadocs/docgen", + "downloads": 1 + }, + { + "href": "https://www.npmjs.com/package/@bonadocs/core", + "downloads": 15 + }, + { + "href": "https://www.npmjs.com/package/@bonadocs/cli", + "downloads": 0 + } + ] }, { "id": "0x62e37e96aa6e1cbfb6bd24b97c4b8f1e12cc3fe35d5388d2f041c42a12b40745", @@ -3219,32 +4393,19 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/3083ccee-79a8-4ff2-b017-9ecb52d13cbf.png", "banner_url": "https://storage.googleapis.com/op-atlas/b29f1ab3-b4cf-4255-839e-e7a418e78b80.png", "twitter": "https://x.com/StargateFinance", - "repos": [ - "https://github.com/stargate-protocol/stargate" - ], "tags": [ "cross-chain", "defi" ], "website": "https://stargate.finance/", - "category": "Cross-Chain & Interoperability" - }, - { - "id": "0xcbfdcf8f724d73504d1518d5ecd7d7256b12d37e68cd84569b383bfb6e2eeea4", - "name": "Dmail Network", - "description": "Stay Informed and Connected with Intelligent and Secure Messaging & Notifications.\n\nDmail Network is an AI-powered decentralized communication infrastructure built to provide encrypted emails, unified notifications, and targeted marketing across multiple chains and dApps for users, developers, marketers and influencers.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/12b2e427-b292-4b27-8896-9053900bfdb4.png", - "banner_url": "https://storage.googleapis.com/op-atlas/3b615f64-5b2e-4092-a10d-f0e311ced954.png", - "twitter": "https://x.com/Dmailofficial", + "category": "Cross-Chain & Interoperability", "repos": [ - "https://github.com/dmailofficial/dmail", - "https://mail.dmail.ai/compose" - ], - "tags": [ - "cross-chain", - "privacy-focused" - ], - "category": "Cross-Chain & Interoperability" + { + "href": "https://github.com/stargate-protocol/stargate", + "stargazers": 314, + "lastUpdated": "2024-06-06T00:19:00Z" + } + ] }, { "id": "0x0ee3defac0e2a31b995bc073ac02a2140aaf01679e141eb8d1d80409f75f90ea", @@ -3253,14 +4414,24 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/8c7d3ba8-c0bd-4acd-9ec5-7f1c90631047.png", "banner_url": "https://storage.googleapis.com/op-atlas/9efac275-51f7-48a8-9f13-22c13b05850e.png", "twitter": "https://x.com/MintClubPro", - "repos": [ - "https://github.com/Steemhunt/mint.club-v2-contract", - "https://www.npmjs.com/package/mint.club-v2-sdk", - "https://github.com/Steemhunt/mint.club-v2-sdk" - ], "tags": [], "website": "https://mint.club", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Steemhunt/mint.club-v2-contract", + "stargazers": 62, + "lastUpdated": "2025-12-18T08:44:45Z" + }, + { + "href": "https://www.npmjs.com/package/mint.club-v2-sdk" + }, + { + "href": "https://github.com/Steemhunt/mint.club-v2-sdk", + "stargazers": 33, + "lastUpdated": "2025-12-13T05:11:28Z" + } + ] }, { "id": "0x93decae913f62c0a86519d0b0798e4a10c46c541bfc14dcff0193d6b026e9532", @@ -3269,16 +4440,24 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/30c6400b-b572-4d16-8138-4dc1cba0ef06.png", "banner_url": "https://storage.googleapis.com/op-atlas/2c2733fd-a572-4f4f-809d-def2e14b8776.png", "twitter": "https://x.com/llamapay_io", - "repos": [ - "https://github.com/llamasubs/contracts", - "https://github.com/LlamaPay/llamapay" - ], "tags": [ "defi", "gas-efficient" ], "website": "https://llamapay.io/", - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/llamasubs/contracts", + "stargazers": 4, + "lastUpdated": "2024-07-21T13:42:50Z" + }, + { + "href": "https://github.com/LlamaPay/llamapay", + "stargazers": 187, + "lastUpdated": "2022-06-21T08:10:50Z" + } + ] }, { "id": "0x66cb156952c9cd26c329a490b1ae9a90167f3067bbea337888b5d70d374959d7", @@ -3287,13 +4466,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/27046acd-924a-4f01-ae53-dd51cb6d8238.png", "banner_url": "https://storage.googleapis.com/op-atlas/7caed237-2d34-4b78-a158-cf118a697d57.png", "twitter": "@zkemail", - "repos": [ - "https://github.com/zkemail/zk-email-verify", - "https://github.com/zkemail/zk-email-sdk-js", - "https://www.npmjs.com/package/@zk-email/contracts", - "https://github.com/zkemail/email-recovery", - "https://github.com/zkemail/zkemail.nr" - ], "tags": [ "frontend", "modular-accounts", @@ -3303,7 +4475,33 @@ "solidity" ], "website": "https://zk.email", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/zkemail/zk-email-verify", + "stargazers": 416, + "lastUpdated": "2025-12-19T13:16:10Z" + }, + { + "href": "https://github.com/zkemail/zk-email-sdk-js", + "stargazers": 5, + "lastUpdated": "2025-12-29T14:41:54Z" + }, + { + "href": "https://www.npmjs.com/package/@zk-email/contracts", + "downloads": 27 + }, + { + "href": "https://github.com/zkemail/email-recovery", + "stargazers": 59, + "lastUpdated": "2025-06-25T16:40:55Z" + }, + { + "href": "https://github.com/zkemail/zkemail.nr", + "stargazers": 80, + "lastUpdated": "2025-10-23T14:28:02Z" + } + ] }, { "id": "0x38c38455bb0fd71d2929fcf799279569ab5f5c5d3e1f92f8642ce87aa25accdf", @@ -3312,15 +4510,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/1ede3a09-1878-4852-a564-f86f4f49b9fc.png", "banner_url": "https://storage.googleapis.com/op-atlas/862dacb3-f496-4afe-ae66-70f9f9949937.png", "twitter": "https://twitter.com/decentxyz", - "repos": [ - "https://www.npmjs.com/package/@decent.xyz/box-common", - "https://www.npmjs.com/package/@decent.xyz/box-hooks", - "https://github.com/decentxyz/launch-nfts", - "https://github.com/decentxyz/decentV2-contracts", - "https://www.npmjs.com/package/@decent.xyz/box-ui", - "https://www.npmjs.com/package/@decent.xyz/the-box", - "https://github.com/decentxyz/decent-contracts-v3" - ], "tags": [ "cross-chain", "nextjs", @@ -3328,7 +4517,40 @@ "foundry", "user-experience" ], - "category": "Cross-Chain & Interoperability" + "category": "Cross-Chain & Interoperability", + "repos": [ + { + "href": "https://www.npmjs.com/package/@decent.xyz/box-common", + "downloads": 1230 + }, + { + "href": "https://www.npmjs.com/package/@decent.xyz/box-hooks", + "downloads": 1053 + }, + { + "href": "https://github.com/decentxyz/launch-nfts", + "stargazers": 1, + "lastUpdated": "2024-06-06T16:40:50Z" + }, + { + "href": "https://github.com/decentxyz/decentV2-contracts", + "stargazers": 2, + "lastUpdated": "2024-06-06T15:26:43Z" + }, + { + "href": "https://www.npmjs.com/package/@decent.xyz/box-ui", + "downloads": 833 + }, + { + "href": "https://www.npmjs.com/package/@decent.xyz/the-box", + "downloads": 837 + }, + { + "href": "https://github.com/decentxyz/decent-contracts-v3", + "stargazers": 1, + "lastUpdated": "2025-03-28T20:43:18Z" + } + ] }, { "id": "0xae07bfec2c3c90937679f8c8c5c32e80407c09903aa03d1b5e5a075e67592b86", @@ -3337,11 +4559,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/a9e1e4b4-45a2-411b-8f31-059269534381.png", "banner_url": "https://storage.googleapis.com/op-atlas/7e0ec4d9-824e-46e3-ad4e-8ffaaa1f105b.png", "twitter": "https://x.com/defillama", - "repos": [ - "https://github.com/DefiLlama/defillama-app", - "https://github.com/0xngmi/llamazip", - "https://github.com/DefiLlama/DefiLlama-Adapters" - ], "tags": [ "analytics", "defi", @@ -3350,7 +4567,24 @@ "visualization" ], "website": "https://defillama.com/", - "category": "Data, Analytics & Tracing" + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/DefiLlama/defillama-app", + "stargazers": 277, + "lastUpdated": "2026-01-20T20:11:36Z" + }, + { + "href": "https://github.com/0xngmi/llamazip", + "stargazers": 20, + "lastUpdated": "2024-06-05T03:14:38Z" + }, + { + "href": "https://github.com/DefiLlama/DefiLlama-Adapters", + "stargazers": 1110, + "lastUpdated": "2026-01-20T18:30:58Z" + } + ] }, { "id": "0x120cdd8e43ae1efbafdf02eda876e1952c05a52870c8d5a8f56d9ec0f79f586d", @@ -3359,20 +4593,48 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/0160cab5-f34b-4aa5-9442-8b6e82a02bde.png", "banner_url": "https://storage.googleapis.com/op-atlas/55137132-f859-4640-8d98-4f7c3a8e4489.png", "twitter": "https://x.com/gitcoinpassport", - "repos": [ - "https://github.com/gitcoinco/passport", - "https://github.com/gitcoinco/eas-proxy", - "https://github.com/passportxyz/passport-scorer", - "https://github.com/passportxyz/passport", - "https://github.com/gitcoinco/id-staking-v2", - "https://github.com/gitcoinco/id-staking-v2-app", - "https://github.com/gitcoinco/passport-scorer" - ], "tags": [ "analytics", "gas-efficient" ], - "category": "Data, Analytics & Tracing" + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/gitcoinco/passport", + "stargazers": 1207, + "lastUpdated": "2026-01-15T15:17:37Z" + }, + { + "href": "https://github.com/gitcoinco/eas-proxy", + "stargazers": 22, + "lastUpdated": "2025-09-02T16:06:03Z" + }, + { + "href": "https://github.com/passportxyz/passport-scorer", + "stargazers": 178, + "lastUpdated": "2026-01-16T15:04:54Z" + }, + { + "href": "https://github.com/passportxyz/passport", + "stargazers": 1207, + "lastUpdated": "2026-01-15T15:17:37Z" + }, + { + "href": "https://github.com/gitcoinco/id-staking-v2", + "stargazers": 4, + "lastUpdated": "2024-10-04T17:47:35Z" + }, + { + "href": "https://github.com/gitcoinco/id-staking-v2-app", + "stargazers": 3, + "lastUpdated": "2025-04-08T18:25:51Z" + }, + { + "href": "https://github.com/gitcoinco/passport-scorer", + "stargazers": 178, + "lastUpdated": "2026-01-16T15:04:54Z" + } + ] }, { "id": "0x7539f43dc91f9c406c83a06339708e4033cdbf630916c6dfb9de2b5ef811affd", @@ -3381,9 +4643,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/3ab14d32-3c0e-4262-a17c-9a328dded4bc.png", "banner_url": "https://storage.googleapis.com/op-atlas/c87cd7ac-5627-4db9-9483-a61e4743d2f0.png", "twitter": "https://x.com/SeamlessFi", - "repos": [ - "https://github.com/seamless-protocol/governance" - ], "tags": [ "defi", "governance", @@ -3392,7 +4651,14 @@ "cli" ], "website": "https://seamlessprotocol.com", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/seamless-protocol/governance", + "stargazers": 9, + "lastUpdated": "2025-06-18T17:27:33Z" + } + ] }, { "id": "0xe20f59eb1c8f9cb72e07b8d0f067bac997614fd6db06d8c031c5c9235f760dcc", @@ -3401,16 +4667,20 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/3f5f2b44-9650-483a-b5cf-1e66163bddae.png", "banner_url": "https://storage.googleapis.com/op-atlas/41a3c848-54ca-4b30-8fa1-e82a70b18935.png", "twitter": "https://x.com/L2_Pass", - "repos": [ - "https://github.com/L2PASS/contracts" - ], "tags": [ "cross-chain", "wallet", "multi-chain" ], "website": "https://l2pass.com/", - "category": "Cross-Chain & Interoperability" + "category": "Cross-Chain & Interoperability", + "repos": [ + { + "href": "https://github.com/L2PASS/contracts", + "stargazers": 0, + "lastUpdated": "2024-05-30T20:04:34Z" + } + ] }, { "id": "0xa88844cea135382e3484e39c3172033437121b35ca0bc8b10b9b8253984876b5", @@ -3419,16 +4689,27 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/e74ff6ef-578b-4dcb-b155-e663822b2f94.png", "banner_url": "https://storage.googleapis.com/op-atlas/a447bb2c-d43d-433c-b66c-2506c12858f4.png", "twitter": "https://twitter.com/eas_eth", - "repos": [ - "https://github.com/ethereum-attestation-service/eas-contracts", - "https://github.com/ethereum-attestation-service/eas-sdk", - "https://www.npmjs.com/package/@ethereum-attestation-service/eas-contracts" - ], "tags": [ "governance", "sdk" ], - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/ethereum-attestation-service/eas-contracts", + "stargazers": 304, + "lastUpdated": "2025-02-17T03:21:57Z" + }, + { + "href": "https://github.com/ethereum-attestation-service/eas-sdk", + "stargazers": 133, + "lastUpdated": "2025-10-12T22:38:43Z" + }, + { + "href": "https://www.npmjs.com/package/@ethereum-attestation-service/eas-contracts", + "downloads": 6119 + } + ] }, { "id": "0x8967594d2978692a35fea137ba640bb42f11cad907ca6b0bd01f3718fc4c7f5b", @@ -3437,39 +4718,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/cade2fb6-a79c-4974-8b2b-fc4afcd1ec09.png", "banner_url": "https://storage.googleapis.com/op-atlas/3a110bc1-0ea0-49d5-a38b-5a66b3484852.png", "twitter": "https://twitter.com/hatsprotocol", - "repos": [ - "https://github.com/Hats-Protocol/hats-account", - "https://github.com/Hats-Protocol/subgraph", - "https://github.com/Hats-Protocol/hat-wearing-eligibility", - "https://github.com/Hats-Protocol/farcaster-delegator", - "https://github.com/Hats-Protocol/hats-account-sdk", - "https://github.com/Hats-Protocol/hats-auth", - "https://github.com/Hats-Protocol/create-hats-app", - "https://github.com/Hats-Protocol/hsg-sdk", - "https://github.com/Hats-Protocol/colinks-eligibility", - "https://github.com/Hats-Protocol/chain-modules", - "https://github.com/Hats-Protocol/allowlist-eligibility", - "https://github.com/Hats-Protocol/agreement-eligibility", - "https://www.npmjs.com/package/@hatsprotocol/sdk-v1-subgraph", - "https://github.com/Hats-Protocol/hats-elections-eligibility", - "https://www.npmjs.com/package/@hatsprotocol/sdk-v1-core", - "https://github.com/Hats-Protocol/season-toggle", - "https://github.com/Hats-Protocol/staking-eligibility", - "https://github.com/hats-protocol/hats-module", - "https://github.com/hats-protocol/hats-protocol", - "https://www.npmjs.com/package/@hatsprotocol/modules-sdk", - "https://www.npmjs.com/package/@hatsprotocol/hsg-sdk", - "https://www.npmjs.com/package/@hatsprotocol/hats-account-sdk", - "https://github.com/Hats-Protocol/subgraph-ancillary", - "https://github.com/Hats-Protocol/hats-governor-votes", - "https://github.com/Hats-Protocol/hats-module-template", - "https://github.com/Hats-Protocol/modules-sdk", - "https://github.com/Hats-Protocol/hats-zodiac", - "https://github.com/Hats-Protocol/jokerace-eligibility", - "https://github.com/Hats-Protocol/multi-claims-hatter", - "https://github.com/Hats-Protocol/passthrough-modules", - "https://github.com/Hats-Protocol/sdk-v1-core" - ], "tags": [ "governance", "decentralized-governance", @@ -3478,7 +4726,159 @@ "proxy-contracts" ], "website": "https://hatsprotocol.xyz", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Hats-Protocol/hats-account", + "stargazers": 10, + "lastUpdated": "2024-06-20T21:46:07Z" + }, + { + "href": "https://github.com/Hats-Protocol/subgraph", + "stargazers": 4, + "lastUpdated": "2025-03-29T13:47:39Z" + }, + { + "href": "https://github.com/Hats-Protocol/hat-wearing-eligibility", + "stargazers": 0, + "lastUpdated": "2024-05-29T16:35:25Z" + }, + { + "href": "https://github.com/Hats-Protocol/farcaster-delegator", + "stargazers": 18, + "lastUpdated": "2024-05-29T16:10:52Z" + }, + { + "href": "https://github.com/Hats-Protocol/hats-account-sdk", + "stargazers": 1, + "lastUpdated": "2024-06-20T22:00:40Z" + }, + { + "href": "https://github.com/Hats-Protocol/hats-auth", + "stargazers": 1, + "lastUpdated": "2024-05-29T16:16:26Z" + }, + { + "href": "https://github.com/Hats-Protocol/create-hats-app", + "stargazers": 5, + "lastUpdated": "2025-11-25T14:47:41Z" + }, + { + "href": "https://github.com/Hats-Protocol/hsg-sdk", + "stargazers": 1, + "lastUpdated": "2024-07-15T20:34:51Z" + }, + { + "href": "https://github.com/Hats-Protocol/colinks-eligibility", + "stargazers": 0, + "lastUpdated": "2024-06-20T21:43:18Z" + }, + { + "href": "https://github.com/Hats-Protocol/chain-modules", + "stargazers": 1, + "lastUpdated": "2024-06-20T22:00:29Z" + }, + { + "href": "https://github.com/Hats-Protocol/allowlist-eligibility", + "stargazers": 0, + "lastUpdated": "2024-09-11T01:10:32Z" + }, + { + "href": "https://github.com/Hats-Protocol/agreement-eligibility", + "stargazers": 0, + "lastUpdated": "2024-10-14T01:14:11Z" + }, + { + "href": "https://www.npmjs.com/package/@hatsprotocol/sdk-v1-subgraph", + "downloads": 353 + }, + { + "href": "https://github.com/Hats-Protocol/hats-elections-eligibility", + "stargazers": 0, + "lastUpdated": "2024-05-29T16:12:39Z" + }, + { + "href": "https://www.npmjs.com/package/@hatsprotocol/sdk-v1-core", + "downloads": 215 + }, + { + "href": "https://github.com/Hats-Protocol/season-toggle", + "stargazers": 0, + "lastUpdated": "2024-05-29T16:35:41Z" + }, + { + "href": "https://github.com/Hats-Protocol/staking-eligibility", + "stargazers": 1, + "lastUpdated": "2024-05-29T16:35:59Z" + }, + { + "href": "https://github.com/hats-protocol/hats-module", + "stargazers": 4, + "lastUpdated": "2025-03-15T20:33:53Z" + }, + { + "href": "https://github.com/hats-protocol/hats-protocol", + "stargazers": 95, + "lastUpdated": "2024-05-29T15:50:14Z" + }, + { + "href": "https://www.npmjs.com/package/@hatsprotocol/modules-sdk", + "downloads": 145 + }, + { + "href": "https://www.npmjs.com/package/@hatsprotocol/hsg-sdk", + "downloads": 1 + }, + { + "href": "https://www.npmjs.com/package/@hatsprotocol/hats-account-sdk", + "downloads": 0 + }, + { + "href": "https://github.com/Hats-Protocol/subgraph-ancillary", + "stargazers": 0, + "lastUpdated": "2025-03-29T14:01:57Z" + }, + { + "href": "https://github.com/Hats-Protocol/hats-governor-votes", + "stargazers": 0, + "lastUpdated": "2025-02-09T18:06:36Z" + }, + { + "href": "https://github.com/Hats-Protocol/hats-module-template", + "stargazers": 2, + "lastUpdated": "2024-06-20T21:47:18Z" + }, + { + "href": "https://github.com/Hats-Protocol/modules-sdk", + "stargazers": 3, + "lastUpdated": "2025-12-01T23:35:58Z" + }, + { + "href": "https://github.com/Hats-Protocol/hats-zodiac", + "stargazers": 23, + "lastUpdated": "2024-12-19T02:24:56Z" + }, + { + "href": "https://github.com/Hats-Protocol/jokerace-eligibility", + "stargazers": 0, + "lastUpdated": "2024-08-27T19:15:52Z" + }, + { + "href": "https://github.com/Hats-Protocol/multi-claims-hatter", + "stargazers": 0, + "lastUpdated": "2024-05-29T16:36:17Z" + }, + { + "href": "https://github.com/Hats-Protocol/passthrough-modules", + "stargazers": 1, + "lastUpdated": "2024-09-14T15:21:25Z" + }, + { + "href": "https://github.com/Hats-Protocol/sdk-v1-core", + "stargazers": 3, + "lastUpdated": "2025-04-01T19:37:40Z" + } + ] }, { "id": "0x24ff0fb2933e55b169a80d9bd35a00a7011795387717b27445ccdc0f8660d740", @@ -3487,11 +4887,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/46d3935b-5719-4c9f-ae9b-d7f255f4c120.png", "banner_url": "https://storage.googleapis.com/op-atlas/5082f8c7-b61a-4ac7-b829-e51fa15fdfc4.png", "twitter": "https://x.com/OpenOceanGlobal", - "repos": [ - "https://www.npmjs.com/package/@openocean.finance/wallet", - "https://github.com/openocean-finance/OpenOceanExchangeV2", - "https://www.npmjs.com/package/@openocean.finance/openocean-sdk" - ], "tags": [ "defi", "cross-chain", @@ -3499,7 +4894,22 @@ "multi-chain" ], "website": "https://openocean.finance/", - "category": "Cross-Chain & Interoperability" + "category": "Cross-Chain & Interoperability", + "repos": [ + { + "href": "https://www.npmjs.com/package/@openocean.finance/wallet", + "downloads": 396 + }, + { + "href": "https://github.com/openocean-finance/OpenOceanExchangeV2", + "stargazers": 1, + "lastUpdated": "2025-11-24T02:45:16Z" + }, + { + "href": "https://www.npmjs.com/package/@openocean.finance/openocean-sdk", + "downloads": 465 + } + ] }, { "id": "0x517eaa9c56951de89261f2d7830ea49aae92f2a903104a17d9c5c2edd4959806", @@ -3508,13 +4918,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/4906b988-6024-421e-a706-d01bc508e736.png", "banner_url": "https://storage.googleapis.com/op-atlas/c280e13b-3e03-47e9-8141-5fad0d51ba2b.png", "twitter": "https://x.com/lifiprotocol", - "repos": [ - "https://www.npmjs.com/package/@lifi/sdk", - "https://github.com/lifinance/widget", - "https://www.npmjs.com/package/@lifi/widget", - "https://github.com/lifinance/contracts", - "https://github.com/lifinance/sdk" - ], "tags": [ "cross-chain", "api", @@ -3522,7 +4925,32 @@ "multi-chain", "performance-optimization" ], - "category": "Cross-Chain & Interoperability" + "category": "Cross-Chain & Interoperability", + "repos": [ + { + "href": "https://www.npmjs.com/package/@lifi/sdk", + "downloads": 36632 + }, + { + "href": "https://github.com/lifinance/widget", + "stargazers": 188, + "lastUpdated": "2026-01-20T11:06:38Z" + }, + { + "href": "https://www.npmjs.com/package/@lifi/widget", + "downloads": 12583 + }, + { + "href": "https://github.com/lifinance/contracts", + "stargazers": 191, + "lastUpdated": "2026-01-16T08:38:18Z" + }, + { + "href": "https://github.com/lifinance/sdk", + "stargazers": 243, + "lastUpdated": "2026-01-20T12:52:18Z" + } + ] }, { "id": "0x4d71401a0dbd9b3dd890fbc70baaf872d16db80af149e20f7ef1805fc94f6df6", @@ -3531,17 +4959,30 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/582dd2ed-214a-4289-9423-35b64c318cb2.png", "banner_url": "https://storage.googleapis.com/op-atlas/407396e3-b660-4615-a35d-eae333379d44.png", "twitter": "https://x.com/routerprotocol", - "repos": [ - "https://github.com/router-protocol/router-contracts", - "https://www.npmjs.com/package/@routerprotocol/asset-bridge", - "https://www.npmjs.com/package/@routerprotocol/asset-forwarder", - "https://www.npmjs.com/package/@routerprotocol/evm-gateway-contracts" - ], "tags": [ "cross-chain", "scalability" ], - "category": "Cross-Chain & Interoperability" + "category": "Cross-Chain & Interoperability", + "repos": [ + { + "href": "https://github.com/router-protocol/router-contracts", + "stargazers": 0, + "lastUpdated": "2024-10-17T04:25:33Z" + }, + { + "href": "https://www.npmjs.com/package/@routerprotocol/asset-bridge", + "downloads": 0 + }, + { + "href": "https://www.npmjs.com/package/@routerprotocol/asset-forwarder", + "downloads": 0 + }, + { + "href": "https://www.npmjs.com/package/@routerprotocol/evm-gateway-contracts", + "downloads": 5 + } + ] }, { "id": "0x850df51e29f2846a5f085d88e6b6fc13fad51ad7161f8a825ed09d470668161a", @@ -3550,14 +4991,18 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/ff816d35-de0c-4768-af2c-d2c187dab1c1.png", "banner_url": "https://storage.googleapis.com/op-atlas/87f46f2a-632b-441c-b762-fe104617d4b6.png", "twitter": "https://x.com/prtyDAO", - "repos": [ - "https://github.com/PartyDAO/party-protocol" - ], "tags": [ "wallet", "governance" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/PartyDAO/party-protocol", + "stargazers": 183, + "lastUpdated": "2024-12-21T01:46:28Z" + } + ] }, { "id": "0x08df6e20a3cfabbaf8f34d4f4d048fe7da40447c24be0f3ad513db6f13c755dd", @@ -3566,17 +5011,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/438ea57d-059c-4327-82e4-abfc94544bad.png", "banner_url": "https://storage.googleapis.com/op-atlas/2d33616b-bceb-449d-aa0a-b8270b1b3e3b.png", "twitter": "https://twitter.com/VelodromeFi", - "repos": [ - "https://github.com/velodrome-finance/relay", - "https://github.com/velodrome-finance/universal-router", - "https://github.com/velodrome-finance/sugar-sdk", - "https://github.com/velodrome-finance/sugar", - "https://github.com/velodrome-finance/slipstream", - "https://github.com/velodrome-finance/oracle", - "https://github.com/velodrome-finance/contracts", - "https://github.com/velodrome-finance/superchain-contracts", - "https://github.com/velodrome-finance/superchain-slipstream" - ], "tags": [ "defi", "docker", @@ -3584,7 +5018,54 @@ "contract-verification" ], "website": "https://velodrome.finance", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/velodrome-finance/relay", + "stargazers": 6, + "lastUpdated": "2025-12-18T15:28:56Z" + }, + { + "href": "https://github.com/velodrome-finance/universal-router", + "stargazers": 7, + "lastUpdated": "2025-06-24T08:03:31Z" + }, + { + "href": "https://github.com/velodrome-finance/sugar-sdk", + "stargazers": 15, + "lastUpdated": "2025-08-05T11:45:53Z" + }, + { + "href": "https://github.com/velodrome-finance/sugar", + "stargazers": 84, + "lastUpdated": "2025-12-18T15:29:47Z" + }, + { + "href": "https://github.com/velodrome-finance/slipstream", + "stargazers": 42, + "lastUpdated": "2025-12-18T15:27:54Z" + }, + { + "href": "https://github.com/velodrome-finance/oracle", + "stargazers": 5, + "lastUpdated": "2024-06-05T20:09:23Z" + }, + { + "href": "https://github.com/velodrome-finance/contracts", + "stargazers": 64, + "lastUpdated": "2025-12-18T15:29:13Z" + }, + { + "href": "https://github.com/velodrome-finance/superchain-contracts", + "stargazers": 9, + "lastUpdated": "2025-12-18T15:27:19Z" + }, + { + "href": "https://github.com/velodrome-finance/superchain-slipstream", + "stargazers": 3, + "lastUpdated": "2025-12-18T15:28:24Z" + } + ] }, { "id": "0xb6266f3d955040aa7583f2f346db87abe0649f545389af3cc8fe302aacfc850b", @@ -3593,24 +5074,73 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/507b8200-92e0-4914-a43e-97010a0b0583.png", "banner_url": "https://storage.googleapis.com/op-atlas/bd351554-5050-4584-9f2f-f23ea935508b.png", "twitter": "https://x.com/0xsplits", - "repos": [ - "https://github.com/0xSplits/splits-contracts-monorepo", - "https://github.com/0xSplits/splits-liquid", - "https://github.com/0xSplits/splits-waterfall", - "https://github.com/0xSplits/splits-vesting", - "https://github.com/0xSplits/splits-utils", - "https://github.com/0xSplits/splits-oracle", - "https://github.com/0xSplits/splits-diversifier", - "https://github.com/0xSplits/splits-contracts", - "https://github.com/0xSplits/splits-swapper", - "https://github.com/0xSplits/splits-sdk", - "https://www.npmjs.com/package/@0xsplits/splits-kit", - "https://www.npmjs.com/package/@0xsplits/splits-sdk-react", - "https://www.npmjs.com/package/@0xsplits/splits-sdk" - ], "tags": [], "website": "https://splits.org/", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/0xSplits/splits-contracts-monorepo", + "stargazers": 27, + "lastUpdated": "2025-11-20T16:54:26Z" + }, + { + "href": "https://github.com/0xSplits/splits-liquid", + "stargazers": 11, + "lastUpdated": "2024-05-29T21:10:35Z" + }, + { + "href": "https://github.com/0xSplits/splits-waterfall", + "stargazers": 31, + "lastUpdated": "2025-09-18T18:54:53Z" + }, + { + "href": "https://github.com/0xSplits/splits-vesting", + "stargazers": 11, + "lastUpdated": "2025-01-21T23:36:35Z" + }, + { + "href": "https://github.com/0xSplits/splits-utils", + "stargazers": 4, + "lastUpdated": "2024-05-29T21:09:10Z" + }, + { + "href": "https://github.com/0xSplits/splits-oracle", + "stargazers": 9, + "lastUpdated": "2024-05-29T21:11:50Z" + }, + { + "href": "https://github.com/0xSplits/splits-diversifier", + "stargazers": 11, + "lastUpdated": "2024-05-29T21:06:58Z" + }, + { + "href": "https://github.com/0xSplits/splits-contracts", + "stargazers": 163, + "lastUpdated": "2024-05-28T00:13:31Z" + }, + { + "href": "https://github.com/0xSplits/splits-swapper", + "stargazers": 14, + "lastUpdated": "2025-09-23T16:44:17Z" + }, + { + "href": "https://github.com/0xSplits/splits-sdk", + "stargazers": 38, + "lastUpdated": "2026-01-07T19:15:34Z" + }, + { + "href": "https://www.npmjs.com/package/@0xsplits/splits-kit", + "downloads": 45 + }, + { + "href": "https://www.npmjs.com/package/@0xsplits/splits-sdk-react", + "downloads": 688 + }, + { + "href": "https://www.npmjs.com/package/@0xsplits/splits-sdk", + "downloads": 1330 + } + ] }, { "id": "0xfc54b4a9c537be25238cba3f05100b733aeee83a3eb3fdae60d651b3b913390c", @@ -3619,10 +5149,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/8362181e-8e95-40d4-bf8d-234f3edaca4c.png", "banner_url": "https://storage.googleapis.com/op-atlas/2a702168-545c-42ec-a85f-3149a9227597.png", "twitter": null, - "repos": [ - "https://www.npmjs.com/package/multicaller", - "https://github.com/Vectorized/multicaller" - ], "tags": [ "multicall", "solidity", @@ -3633,26 +5159,17 @@ "truffle" ], "website": "https://github.com/Vectorized/multicaller", - "category": "Smart Contract Development & Toolchains" - }, - { - "id": "0x7a4bb37bc7997b8e9b34775164682ff1f441b716cd235f2e7cdce76677b66007", - "name": "zkCodex", - "description": "zkCodex is a comprehensive blockchain analytics platform that enhances how users engage with and analyze EVM-compatible networks. By combining powerful tracking capabilities with advanced DeFi tools, zkCodex offers an all-in-one solution for blockchain interaction and analysis.\n\n\n#Analytics & Tracking\nMulti-Chain Support: Monitor activities across 35+ networks including Ethereum, Optimism, Base and Ink...\nReal-time Analytics: Track transaction volumes, smart contract interactions, and daily activities\nPerformance Metrics: Analyze wallet performance through comprehensive scoring and detailed metrics\n\n#On-Chain\nGM Streak: Build daily streaks and earn rewards\nContract Deployer: Deploy tokens, NFTs, and contracts\nCounter: Multi-network transaction tool\nDApp Interactions: Engage with blockchain apps seamlessly\n\n\n#Tools & Utilities\nSmart Contract Tools: Deploy and interact with contracts securely\nTransaction Management: Monitor and analyze your transaction history\nEVM Utilities: Access essential tools for blockchain operations", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/89825b92-1ec4-4b91-a8a6-0060c3fe354a.png", - "banner_url": "https://storage.googleapis.com/op-atlas/cc030ee4-0070-4979-b6e6-a733393e6db6.png", - "twitter": "https://x.com/zkcodex", + "category": "Smart Contract Development & Toolchains", "repos": [ - "https://github.com/zkcodex/zkCodex" - ], - "tags": [ - "analytics", - "defi", - "cross-chain", - "transaction-management" - ], - "website": "https://zkcodex.com/", - "category": "Data, Analytics & Tracing" + { + "href": "https://www.npmjs.com/package/multicaller" + }, + { + "href": "https://github.com/Vectorized/multicaller", + "stargazers": 289, + "lastUpdated": "2025-01-31T03:52:41Z" + } + ] }, { "id": "0xf24315614063278ba3543e1717791132a9afa79b0e65baa01a85bcccbdfa215f", @@ -3661,25 +5178,60 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/701c36d9-3069-48b6-9aa1-b248378b35b8.png", "banner_url": "https://storage.googleapis.com/op-atlas/929fbc88-69c7-4a75-be6d-27bf3f2dc8d1.png", "twitter": "https://x.com/deBridgeFinance", - "repos": [ - "https://www.npmjs.com/package/@debridge-finance/debridge-protocol-evm-interfaces", - "https://www.npmjs.com/package/@debridge-finance/legacy-dln-profitability", - "https://www.npmjs.com/package/@debridge-finance/desdk", - "https://www.npmjs.com/package/@debridge-finance/dln-client", - "https://www.npmjs.com/package/@debridge-finance/dln-taker", - "https://github.com/debridge-finance/hardhat-debridge", - "https://github.com/debridge-finance/dln-taker", - "https://github.com/debridge-finance/debridge-node", - "https://github.com/debridge-finance/dln-contracts", - "https://github.com/debridge-finance/debridge-contracts-v1" - ], "tags": [ "cross-chain", "defi", "transaction-optimization" ], "website": "https://debridge.finance/", - "category": "Cross-Chain & Interoperability" + "category": "Cross-Chain & Interoperability", + "repos": [ + { + "href": "https://www.npmjs.com/package/@debridge-finance/debridge-protocol-evm-interfaces", + "downloads": 0 + }, + { + "href": "https://www.npmjs.com/package/@debridge-finance/legacy-dln-profitability", + "downloads": 91 + }, + { + "href": "https://www.npmjs.com/package/@debridge-finance/desdk", + "downloads": 145 + }, + { + "href": "https://www.npmjs.com/package/@debridge-finance/dln-client", + "downloads": 680 + }, + { + "href": "https://www.npmjs.com/package/@debridge-finance/dln-taker", + "downloads": 5 + }, + { + "href": "https://github.com/debridge-finance/hardhat-debridge", + "stargazers": 23, + "lastUpdated": "2024-06-04T10:44:19Z" + }, + { + "href": "https://github.com/debridge-finance/dln-taker", + "stargazers": 20, + "lastUpdated": "2024-08-30T09:10:01Z" + }, + { + "href": "https://github.com/debridge-finance/debridge-node", + "stargazers": 9, + "lastUpdated": "2025-06-25T14:37:29Z" + }, + { + "href": "https://github.com/debridge-finance/dln-contracts", + "stargazers": 2, + "lastUpdated": "2024-06-04T11:18:02Z" + }, + { + "href": "https://github.com/debridge-finance/debridge-contracts-v1", + "stargazers": 58, + "lastUpdated": "2024-10-23T15:11:09Z" + } + ] }, { "id": "0x66cce776ce6eaa99192120fc25b91ecc7b98e03210a08f0d3bfda82f542d3e1a", @@ -3688,17 +5240,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/8f6ad6e0-029a-4f59-b1d2-c7885248b99a.png", "banner_url": "https://storage.googleapis.com/op-atlas/135853fe-2393-4a0a-a959-044ff973fcf0.png", "twitter": "https://x.com/optidomains", - "repos": [ - "https://www.npmjs.com/package/@optidomains/passport-discord", - "https://github.com/Opti-domains/evmgateway", - "https://github.com/Opti-domains/ens-diamond-resolver-v1", - "https://github.com/Opti-domains/dispute-game-lookup", - "https://www.npmjs.com/package/@optidomains/wagmi-core", - "https://github.com/Opti-domains/optidomains-ens-contracts", - "https://github.com/Opti-domains/modular-ens-contracts", - "https://www.npmjs.com/package/@optidomains/wagmi", - "https://www.npmjs.com/package/@optidomains/rainbowkit" - ], "tags": [ "cross-chain", "governance", @@ -3707,7 +5248,50 @@ "scalability" ], "website": "https://opti.domains", - "category": "Cross-Chain & Interoperability" + "category": "Cross-Chain & Interoperability", + "repos": [ + { + "href": "https://www.npmjs.com/package/@optidomains/passport-discord", + "downloads": 7 + }, + { + "href": "https://github.com/Opti-domains/evmgateway", + "stargazers": 0, + "lastUpdated": "2025-01-07T16:14:06Z" + }, + { + "href": "https://github.com/Opti-domains/ens-diamond-resolver-v1", + "stargazers": 0, + "lastUpdated": "2024-05-28T02:46:59Z" + }, + { + "href": "https://github.com/Opti-domains/dispute-game-lookup", + "stargazers": 0, + "lastUpdated": "2025-02-16T18:57:17Z" + }, + { + "href": "https://www.npmjs.com/package/@optidomains/wagmi-core", + "downloads": 1 + }, + { + "href": "https://github.com/Opti-domains/optidomains-ens-contracts", + "stargazers": 0, + "lastUpdated": "2024-05-28T02:37:33Z" + }, + { + "href": "https://github.com/Opti-domains/modular-ens-contracts", + "stargazers": 2, + "lastUpdated": "2024-05-28T04:03:40Z" + }, + { + "href": "https://www.npmjs.com/package/@optidomains/wagmi", + "downloads": 1 + }, + { + "href": "https://www.npmjs.com/package/@optidomains/rainbowkit", + "downloads": 1 + } + ] }, { "id": "0xe40733f18903b26f7880bb2fd78c39f3992efe9f8b2e89994c2869eeb3ba4470", @@ -3716,12 +5300,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/1d22d6dc-b629-48bc-9c25-2ecc6b9aa1a5.png", "banner_url": "https://storage.googleapis.com/op-atlas/1d511ff7-cfcf-49f8-876c-b11a324148a3.png", "twitter": "https://x.com/openfortxyz", - "repos": [ - "https://github.com/openfort-xyz/openfort-contracts", - "https://github.com/openfort-xyz/openfort-chain-abstraction", - "https://www.npmjs.com/package/@openfort/openfort-js", - "https://github.com/openfort-xyz/openfort-js" - ], "tags": [ "defi", "wallet", @@ -3731,7 +5309,28 @@ "user-experience" ], "website": "https://openfort.xyz", - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/openfort-xyz/openfort-contracts", + "stargazers": 33, + "lastUpdated": "2025-12-04T17:37:28Z" + }, + { + "href": "https://github.com/openfort-xyz/openfort-chain-abstraction", + "stargazers": 11, + "lastUpdated": "2025-03-11T09:03:23Z" + }, + { + "href": "https://www.npmjs.com/package/@openfort/openfort-js", + "downloads": 1549 + }, + { + "href": "https://github.com/openfort-xyz/openfort-js", + "stargazers": 12, + "lastUpdated": "2026-01-20T10:21:12Z" + } + ] }, { "id": "0xa08c7ab7824d147d6cb87ffb4e86cec454a030d48b8c395bad6d64456be3d911", @@ -3740,11 +5339,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/fe98ffd7-a327-4500-9391-5926dc7a8256.png", "banner_url": "https://storage.googleapis.com/op-atlas/b9fed2cb-1767-436f-a605-65af61934cf1.png", "twitter": "https://x.com/AragonProject", - "repos": [ - "https://github.com/aragon/app", - "https://www.npmjs.com/package/@aragon/ods", - "https://github.com/aragon/osx" - ], "tags": [ "governance", "solidity", @@ -3752,7 +5346,23 @@ "contract-management" ], "website": "https://aragon.org/", - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/aragon/app", + "stargazers": 3, + "lastUpdated": "2026-01-19T17:35:39Z" + }, + { + "href": "https://www.npmjs.com/package/@aragon/ods", + "downloads": 18 + }, + { + "href": "https://github.com/aragon/osx", + "stargazers": 100, + "lastUpdated": "2025-10-24T15:01:29Z" + } + ] }, { "id": "0x79e8bf2d699790b563aa57fd34da1722bea3191ab5ff0601ba56020687702ab9", @@ -3761,13 +5371,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/b05e1c53-bace-499c-b346-ed9fa0003730.png", "banner_url": "https://storage.googleapis.com/op-atlas/b33b4fe0-6010-470c-a2db-57636d96536d.png", "twitter": "https://x.com/etherspot", - "repos": [ - "https://github.com/etherspot/etherspot-prime-contracts", - "https://github.com/etherspot/etherspot-modular-sdk", - "https://www.npmjs.com/package/skandha", - "https://www.npmjs.com/package/@etherspot/prime-sdk", - "https://github.com/etherspot/skandha" - ], "tags": [ "cross-chain", "wallet", @@ -3778,7 +5381,31 @@ "user-experience" ], "website": "https://etherspot.io/", - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/etherspot/etherspot-prime-contracts", + "stargazers": 55, + "lastUpdated": "2025-02-20T21:15:37Z" + }, + { + "href": "https://github.com/etherspot/etherspot-modular-sdk", + "stargazers": 22, + "lastUpdated": "2025-10-23T08:27:57Z" + }, + { + "href": "https://www.npmjs.com/package/skandha" + }, + { + "href": "https://www.npmjs.com/package/@etherspot/prime-sdk", + "downloads": 60 + }, + { + "href": "https://github.com/etherspot/skandha", + "stargazers": 610, + "lastUpdated": "2026-01-20T12:53:03Z" + } + ] }, { "id": "0x9d93ec97ef2d3bd4c2b8d95abac9ce0cf43e4f3eb1f05709f8282da8200e69ee", @@ -3787,9 +5414,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/230e8ac2-cea9-4cab-8b4f-8fd58ec6553e.png", "banner_url": "https://storage.googleapis.com/op-atlas/a2dce749-56d7-44d7-a9cc-ffc08255e0f2.png", "twitter": null, - "repos": [ - "https://github.com/framesjs/frames.js" - ], "tags": [ "frontend", "farcaster", @@ -3797,7 +5421,14 @@ "nextjs" ], "website": "https://www.framesjs.org", - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/framesjs/frames.js", + "stargazers": 382, + "lastUpdated": "2025-03-27T17:07:46Z" + } + ] }, { "id": "0x3061b642db56c507e265f03029735b0413a613bda43456a31e78128baeb18754", @@ -3806,9 +5437,6 @@ "thumbnail_url": "https://storage.googleapis.com/op-atlas/dcd0600f-d9bf-439e-9915-5922ea8e9655.png", "banner_url": "https://storage.googleapis.com/op-atlas/031491b9-252c-4b9d-b450-16f3443184d9.png", "twitter": null, - "repos": [ - "https://github.com/Aave" - ], "tags": [ "defi", "governance", @@ -3816,7 +5444,12 @@ "cli", "contract-deployment" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Aave" + } + ] }, { "id": "manually-added:speedrunethereum", @@ -3825,10 +5458,6 @@ "thumbnail_url": null, "banner_url": null, "twitter": "https://x.com/buidlguidl", - "repos": [ - "https://github.com/BuidlGuidl/SpeedRunEthereum-v2", - "https://github.com/scaffold-eth/se-2-challenges" - ], "tags": [ "education", "solidity", @@ -3836,7 +5465,19 @@ "frontend" ], "website": "https://speedrunethereum.com/", - "category": "Education & Community Resources" + "category": "Education & Community Resources", + "repos": [ + { + "href": "https://github.com/BuidlGuidl/SpeedRunEthereum-v2", + "stargazers": 26, + "lastUpdated": "2026-01-07T08:54:24Z" + }, + { + "href": "https://github.com/scaffold-eth/se-2-challenges", + "stargazers": 195, + "lastUpdated": "2026-01-07T15:43:49Z" + } + ] }, { "id": "manually-added:ethpm", @@ -3846,18 +5487,34 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/ethpm/ethpm-cli", - "https://github.com/ethpm/ethpm-spec", - "https://github.com/ethpm/ethpm.js", - "https://github.com/ethpm/py-ethpm" - ], "tags": [ "cli", "solidity", "contract-management" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/ethpm/ethpm-cli", + "stargazers": 40, + "lastUpdated": "2020-10-29T20:31:08Z" + }, + { + "href": "https://github.com/ethpm/ethpm-spec", + "stargazers": 166, + "lastUpdated": "2022-02-10T22:25:59Z" + }, + { + "href": "https://github.com/ethpm/ethpm.js", + "stargazers": 13, + "lastUpdated": "2020-12-15T12:00:28Z" + }, + { + "href": "https://github.com/ethpm/py-ethpm", + "stargazers": 24, + "lastUpdated": "2019-12-10T16:25:17Z" + } + ] }, { "id": "manually-added:governance-onchain-paymaster", @@ -3867,14 +5524,18 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/meliopolis/governance-paymaster" - ], "tags": [ "account-abstraction", "developer-experience" ], - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/meliopolis/governance-paymaster", + "stargazers": 0, + "lastUpdated": "2024-04-24T20:45:19Z" + } + ] }, { "id": "manually-added:fealloc", @@ -3884,11 +5545,15 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/saifalkatout/FeAlloc" - ], "tags": [], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/saifalkatout/FeAlloc", + "stargazers": 0, + "lastUpdated": "2024-02-29T18:38:55Z" + } + ] }, { "id": "manually-added:solide", @@ -3898,14 +5563,18 @@ "thumbnail_url": null, "banner_url": null, "twitter": "https://x.com/0xProofOfLearn", - "repos": [ - "https://github.com/solide-project/solide" - ], "tags": [ "solidity", "developer-experience" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/solide-project/solide", + "stargazers": 4, + "lastUpdated": "2025-04-12T07:52:29Z" + } + ] }, { "id": "manually-added:wallet-test-framework", @@ -3915,9 +5584,6 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/wallet-test-framework/framework" - ], "tags": [ "testing", "wallet", @@ -3925,7 +5591,14 @@ "developer-experience", "security" ], - "category": "Security, Testing & Formal Verification" + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/wallet-test-framework/framework", + "stargazers": 27, + "lastUpdated": "2025-01-13T15:01:29Z" + } + ] }, { "id": "manually-added:edb-the-ethereum-project-debugger", @@ -3935,16 +5608,20 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/edb-rs/edb" - ], "tags": [ "solidity", "debugging-tools", "developer-experience", "testing" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/edb-rs/edb", + "stargazers": 353, + "lastUpdated": "2026-01-16T15:08:48Z" + } + ] }, { "id": "manually-added:txtx", @@ -3954,16 +5631,20 @@ "thumbnail_url": null, "banner_url": "https://framerusercontent.com/assets/5mR0In8TgnrDGVmhFuLEHtvz9d8.png", "twitter": "https://x.com/Reservoir0x", - "repos": [ - "https://github.com/txtx/txtx" - ], "tags": [ "devops", "contract-management", "contract-deployment", "developer-experience" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/txtx/txtx", + "stargazers": 144, + "lastUpdated": "2025-12-05T18:43:56Z" + } + ] }, { "id": "manually-added:orbitdb", @@ -3973,14 +5654,18 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/orbitdb/orbitdb" - ], "tags": [ "peer-to-peer", "censorship-resistant" ], - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/orbitdb/orbitdb", + "stargazers": 8720, + "lastUpdated": "2025-08-05T01:58:51Z" + } + ] }, { "id": "manually-added:ethereum-eips-ontology", @@ -3990,11 +5675,15 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/prototypo/ethereum-eips-ontology" - ], "tags": [], - "category": "Education & Community Resources" + "category": "Education & Community Resources", + "repos": [ + { + "href": "https://github.com/prototypo/ethereum-eips-ontology", + "stargazers": 43, + "lastUpdated": "2025-06-23T06:48:49Z" + } + ] }, { "id": "manually-added:ethereum-rb", @@ -4004,13 +5693,17 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/EthWorks/ethereum.rb" - ], "tags": [ "sdk" ], - "category": "Client Libraries & SDKs (Front-End)" + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/EthWorks/ethereum.rb", + "stargazers": 732, + "lastUpdated": "2022-05-11T14:28:01Z" + } + ] }, { "id": "manually-added:hax", @@ -4020,13 +5713,17 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/cryspen/hax" - ], "tags": [ "formal-verification" ], - "category": "Security, Testing & Formal Verification" + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/cryspen/hax", + "stargazers": 362, + "lastUpdated": "2026-01-19T15:13:10Z" + } + ] }, { "id": "manually-added:erc-4337-documentation", @@ -4036,14 +5733,18 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/eth-infinitism/aa-mkdocs" - ], "tags": [ "account-abstraction", "education" ], - "category": "Education & Community Resources" + "category": "Education & Community Resources", + "repos": [ + { + "href": "https://github.com/eth-infinitism/aa-mkdocs", + "stargazers": 19, + "lastUpdated": "2025-11-14T13:47:09Z" + } + ] }, { "id": "manually-added:intellij-solidity", @@ -4053,15 +5754,19 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/intellij-solidity/intellij-solidity" - ], "tags": [ "solidity", "developer-experience", "code-quality" ], - "category": "Smart Contract Development & Toolchains" + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/intellij-solidity/intellij-solidity", + "stargazers": 1097, + "lastUpdated": "2026-01-19T22:20:07Z" + } + ] }, { "id": "manually-added:w3pk", @@ -4071,13 +5776,17 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [ - "https://github.com/w3hc/w3pk" - ], "tags": [ "wallet" ], - "category": "Transaction & Wallet Infrastructure" + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/w3hc/w3pk", + "stargazers": 2, + "lastUpdated": "2025-12-30T11:30:36Z" + } + ] }, { "id": "manually-added:solidity-testing-handbook", @@ -4087,11 +5796,11 @@ "thumbnail_url": null, "banner_url": null, "twitter": null, - "repos": [], "tags": [ "testing", "education" ], - "category": "Education & Community Resources" + "category": "Education & Community Resources", + "repos": [] } ] \ No newline at end of file diff --git a/src/data-layer/tasks.ts b/src/data-layer/tasks.ts index 671f6baf06e..71a3d2b1d8e 100644 --- a/src/data-layer/tasks.ts +++ b/src/data-layer/tasks.ts @@ -12,7 +12,7 @@ import { fetchBeaconChain } from "./fetchers/fetchBeaconChain" import { fetchBlobscanStats } from "./fetchers/fetchBlobscanStats" import { fetchCalendarEvents } from "./fetchers/fetchCalendarEvents" import { fetchCommunityPicks } from "./fetchers/fetchCommunityPicks" -import { fetchDeveloperApps } from "./fetchers/fetchDeveloperApps" +import { fetchDeveloperTools } from "./fetchers/fetchDeveloperTools" import { fetchEthereumMarketcap } from "./fetchers/fetchEthereumMarketcap" import { fetchEthereumStablecoinsMcap } from "./fetchers/fetchEthereumStablecoinsMcap" import { fetchEthPrice } from "./fetchers/fetchEthPrice" @@ -35,7 +35,7 @@ export const KEYS = { APPS: "fetch-apps", CALENDAR_EVENTS: "fetch-calendar-events", COMMUNITY_PICKS: "fetch-community-picks", - DEVELOPER_APPS: "fetch-developer-apps", + DEVELOPER_APPS: "fetch-developer-tools", GFIS: "fetch-gfis", GIT_HISTORY: "fetch-git-history", GROW_THE_PIE: "fetch-grow-the-pie", @@ -73,7 +73,7 @@ const DAILY: Task[] = [ [KEYS.RSS, fetchRSS], [KEYS.GITHUB_REPO_DATA, fetchGithubRepoData], [KEYS.EVENTS, fetchEvents], - [KEYS.DEVELOPER_APPS, fetchDeveloperApps], + [KEYS.DEVELOPER_APPS, fetchDeveloperTools], ] const HOURLY: Task[] = [ diff --git a/src/lib/data/index.ts b/src/lib/data/index.ts index 388d32fc4ac..24aece5ef0f 100644 --- a/src/lib/data/index.ts +++ b/src/lib/data/index.ts @@ -143,8 +143,8 @@ export const getEventsData = createCachedGetter( CACHE_REVALIDATE_DAY ) -export const getDeveloperAppsData = createCachedGetter( - dataLayer.getDeveloperAppsData, - ["apps-data"], +export const getDeveloperToolsData = createCachedGetter( + dataLayer.getDeveloperToolsData, + ["developer-tools-data"], CACHE_REVALIDATE_DAY ) From 529bbe8231a48f084ad6247d96324d49f32676e6 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 20 Jan 2026 14:13:15 -0800 Subject: [PATCH 22/74] fix: add sleep and retry to avoid rate limiting - Adds sleep and retry helper functions to lib utils - Updates GitHub and NPM fetchers --- .../fetchers/fetchDeveloperToolsGitHub.ts | 30 +++++++--- .../fetchers/fetchDeveloperToolsNpmJs.ts | 60 ++++++++++++------- src/lib/utils/fetch.ts | 44 ++++++++++++++ 3 files changed, 105 insertions(+), 29 deletions(-) create mode 100644 src/lib/utils/fetch.ts diff --git a/src/data-layer/fetchers/fetchDeveloperToolsGitHub.ts b/src/data-layer/fetchers/fetchDeveloperToolsGitHub.ts index b30ded67692..2fe0a6e3b5a 100644 --- a/src/data-layer/fetchers/fetchDeveloperToolsGitHub.ts +++ b/src/data-layer/fetchers/fetchDeveloperToolsGitHub.ts @@ -1,7 +1,7 @@ -// TODO: Set up data-layer integration - import type { DeveloperAppsResponse } from "@/lib/types" +import { retry, sleep } from "@/lib/utils/fetch" + import type { DeveloperApp } from "../../../app/[locale]/developers/apps/types" type RepoInfo = { @@ -69,8 +69,9 @@ async function fetchReposBatch( }) if (!response.ok) { - console.warn(`GitHub GraphQL request failed with status ${response.status}`) - return results + throw new Error( + `GitHub GraphQL request failed with status ${response.status}` + ) } const json = await response.json() @@ -119,10 +120,25 @@ export async function fetchDeveloperToolsGitHub( for (let i = 0; i < allRepos.length; i += BATCH_SIZE) { const batch = allRepos.slice(i, i + BATCH_SIZE) - const batchResults = await fetchReposBatch(batch) - for (const [href, data] of batchResults) { - repoDataMap.set(href, data) + try { + // Retry with exponential backoff (3 attempts: 0ms, 1s, 2s) + const batchResults = await retry(() => fetchReposBatch(batch)) + + for (const [href, data] of batchResults) { + repoDataMap.set(href, data) + } + } catch (error) { + console.error( + `Failed to fetch batch ${i / BATCH_SIZE + 1} after retries:`, + error + ) + // Continue with next batch instead of failing entirely + } + + // Add 1 second delay between batches to avoid rate limits + if (i + BATCH_SIZE < allRepos.length) { + await sleep(1000) } } diff --git a/src/data-layer/fetchers/fetchDeveloperToolsNpmJs.ts b/src/data-layer/fetchers/fetchDeveloperToolsNpmJs.ts index 35229c679d4..05e720037d9 100644 --- a/src/data-layer/fetchers/fetchDeveloperToolsNpmJs.ts +++ b/src/data-layer/fetchers/fetchDeveloperToolsNpmJs.ts @@ -1,7 +1,7 @@ -// TODO: Set up data-layer integration +import { retry, sleep } from "@/lib/utils/fetch" + import type { DeveloperApp } from "../../../app/[locale]/developers/apps/types" -// TODO: Move types to lib type ParsedNpmUrl = { packageName: string originalHref: string @@ -80,6 +80,11 @@ async function fetchBulkDownloads( results.set(pkg, downloads) } } + + // Add 15 second delay between batches to avoid rate limits + if (i + CONCURRENCY < scopedPackages.length) { + await sleep(15000) + } } // Fetch unscoped packages in bulk @@ -89,32 +94,43 @@ async function fetchBulkDownloads( const packageList = batch.join(",") try { - const response = await fetch( - `https://api.npmjs.org/downloads/point/last-week/${packageList}` - ) - - if (!response.ok) { - console.warn( - `npm downloads API returned ${response.status} for unscoped batch` + // Retry with exponential backoff (3 attempts: 0ms, 1s, 2s) + await retry(async () => { + const response = await fetch( + `https://api.npmjs.org/downloads/point/last-week/${packageList}` ) - continue - } - const data = await response.json() + if (!response.ok) { + throw new Error( + `npm downloads API returned ${response.status} for unscoped batch` + ) + } - // Handle single-package response: { downloads: number, package: string } - // vs multi-package response: { "pkg1": { downloads: n }, "pkg2": { downloads: m } } - if ("downloads" in data && "package" in data) { - results.set(data.package, data.downloads) - } else { - for (const [pkg, info] of Object.entries(data)) { - if (info && typeof info === "object" && "downloads" in info) { - results.set(pkg, (info as { downloads: number }).downloads) + const data = await response.json() + + // Handle single-package response: { downloads: number, package: string } + // vs multi-package response: { "pkg1": { downloads: n }, "pkg2": { downloads: m } } + if ("downloads" in data && "package" in data) { + results.set(data.package, data.downloads) + } else { + for (const [pkg, info] of Object.entries(data)) { + if (info && typeof info === "object" && "downloads" in info) { + results.set(pkg, (info as { downloads: number }).downloads) + } } } - } + }) } catch (err) { - console.warn(`Failed to fetch bulk npm downloads for batch ${i}:`, err) + console.error( + `Failed to fetch bulk npm downloads for batch ${i / BATCH_SIZE + 1} after retries:`, + err + ) + // Continue with next batch instead of failing entirely + } + + // Add 15 second delay between batches to avoid rate limits + if (i + BATCH_SIZE < unscopedPackages.length) { + await sleep(15000) } } diff --git a/src/lib/utils/fetch.ts b/src/lib/utils/fetch.ts new file mode 100644 index 00000000000..e72c2aab998 --- /dev/null +++ b/src/lib/utils/fetch.ts @@ -0,0 +1,44 @@ +/** + * Utility functions for fetching data with retry logic and rate limiting. + */ + +/** + * Sleep for specified milliseconds. + */ +export const sleep = (ms: number) => + new Promise((resolve) => setTimeout(resolve, ms)) + +/** + * Retry a function with exponential backoff. + * + * @param fn - The async function to retry + * @param maxAttempts - Maximum number of attempts (default: 3) + * @param baseDelay - Base delay in milliseconds for exponential backoff (default: 1000) + * @returns The result of the function if successful + * @throws The last error if all attempts fail + */ +export async function retry( + fn: () => Promise, + maxAttempts = 3, + baseDelay = 1000 +): Promise { + let lastError: Error | undefined + + for (let attempt = 1; attempt <= maxAttempts; attempt++) { + try { + return await fn() + } catch (error) { + lastError = error as Error + if (attempt < maxAttempts) { + const delay = baseDelay * Math.pow(2, attempt - 1) + console.log( + `Attempt ${attempt} failed, retrying in ${delay}ms...`, + error + ) + await sleep(delay) + } + } + } + + throw lastError +} From d98982b557a0c667c74f8ebe3cc370e0eac0978b Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 20 Jan 2026 14:43:50 -0800 Subject: [PATCH 23/74] patch: modal close button styling - Fixes contrast with unknown background image color --- .../developers/apps/_components/AppModalWrapper.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/[locale]/developers/apps/_components/AppModalWrapper.tsx b/app/[locale]/developers/apps/_components/AppModalWrapper.tsx index a9e222a9e36..b374c086ee6 100644 --- a/app/[locale]/developers/apps/_components/AppModalWrapper.tsx +++ b/app/[locale]/developers/apps/_components/AppModalWrapper.tsx @@ -5,6 +5,8 @@ import { usePathname, useRouter } from "next/navigation" import Modal from "@/components/ui/dialog-modal" import { type ModalProps } from "@/components/ui/dialog-modal" +import { cn } from "@/lib/utils/cn" + const AppModalWrapper = (props: ModalProps) => { const router = useRouter() const pathname = usePathname() @@ -16,7 +18,11 @@ const AppModalWrapper = (props: ModalProps) => { router.replace(pathname, { scroll: false }) }} contentProps={{ - className: "[&_.lucide-x]:!stroke-[3] [&_.lucide-x]:!text-body-inverse", + className: cn( + "[&_button:has(.lucide-x)]:m-2 [&_button:has(.lucide-x)]:p-1 [&_button:has(.lucide-x)]:rounded", + "hover:[&_button:has(.lucide-x)]:text-primary-hover [&_button:has(.lucide-x)]:bg-background/75 hover:[&_button:has(.lucide-x)]:bg-background", + "[&_.lucide-x]:!stroke-[3]" + ), }} {...props} /> From e2f2811459500ef537d4cb90cac9f2f7565723b0 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 20 Jan 2026 18:25:13 -0800 Subject: [PATCH 24/74] feat: add TagFilter --- .../developers/apps/[category]/page.tsx | 45 +++++-- .../developers/apps/_components/TagFilter.tsx | 116 ++++++++++++++++++ src/intl/en/page-developers-apps.json | 5 + 3 files changed, 159 insertions(+), 7 deletions(-) create mode 100644 app/[locale]/developers/apps/_components/TagFilter.tsx diff --git a/app/[locale]/developers/apps/[category]/page.tsx b/app/[locale]/developers/apps/[category]/page.tsx index c11b6b49a09..c060075b248 100644 --- a/app/[locale]/developers/apps/[category]/page.tsx +++ b/app/[locale]/developers/apps/[category]/page.tsx @@ -8,7 +8,6 @@ import { ContentHero } from "@/components/Hero" import MainArticle from "@/components/MainArticle" import SubpageCard from "@/components/SubpageCard" import { CardBanner, CardParagraph, CardTitle } from "@/components/ui/card" -import { Divider } from "@/components/ui/divider" import { EdgeScrollContainer, EdgeScrollItem, @@ -22,8 +21,9 @@ import { getMetadata } from "@/lib/utils/metadata" import AppModalContents from "../_components/AppModalContents" import AppModalWrapper from "../_components/AppModalWrapper" +import TagFilter from "../_components/TagFilter" import { DEV_APP_CATEGORIES } from "../constants" -import type { DeveloperAppCategorySlug } from "../types" +import type { DeveloperAppCategorySlug, DeveloperAppTag } from "../types" import { transformDeveloperAppsData } from "../utils" import { routing } from "@/i18n/routing" @@ -34,10 +34,10 @@ const Page = async ({ searchParams, }: { params: PageParams & { category: DeveloperAppCategorySlug } - searchParams: { appId?: string } + searchParams: { appId?: string; tag?: string } }) => { const { locale, category } = params - const { appId } = searchParams + const { appId, tag } = searchParams setRequestLocale(locale) const t = await getTranslations({ locale, namespace: "page-developers-apps" }) @@ -46,10 +46,35 @@ const Page = async ({ const enrichedData = await getDeveloperToolsData() if (!enrichedData) throw Error("No developer apps data available") const dataByCategory = transformDeveloperAppsData(enrichedData) - const categoryData = dataByCategory[category] + const allCategoryData = dataByCategory[category] + + // Extract unique tags from current category + const uniqueTags = Array.from( + new Set(allCategoryData.flatMap((app) => app.tags)) + ).sort() + + // Filter by selected tag if present (validate it's a real tag) + const validTag = + tag && uniqueTags.includes(tag as DeveloperAppTag) + ? (tag as DeveloperAppTag) + : undefined + const categoryData = validTag + ? allCategoryData.filter((app) => app.tags.includes(validTag)) + : allCategoryData const activeApp = enrichedData.find((app) => app.id === appId) + // Prepare translations for client component + const tagLabels = Object.fromEntries( + uniqueTags.map((tag) => [tag, t(`page-developers-apps-tag-${tag}`)]) + ) + const filterLabels = { + filterBy: t("page-developers-apps-filter-label"), + clearFilter: t("page-developers-apps-filter-clear"), + noTags: t("page-developers-apps-filter-no-tags"), + showing: t("page-developers-apps-filter-showing"), + } + const featuredNames = ["ZK Email", "Hardhat", "Updraft"] // TODO: determine logic, make DRY const highlights = enrichedData.filter(({ name }) => featuredNames.includes(name) @@ -143,8 +168,14 @@ const Page = async ({ {t("page-developers-apps-applications-title")} - {/* // TODO: "Filter by / showing (n)" bar, replace Divider */} - +
{categoryData.map((app) => ( diff --git a/app/[locale]/developers/apps/_components/TagFilter.tsx b/app/[locale]/developers/apps/_components/TagFilter.tsx new file mode 100644 index 00000000000..75b3d175f8e --- /dev/null +++ b/app/[locale]/developers/apps/_components/TagFilter.tsx @@ -0,0 +1,116 @@ +"use client" + +import { useState } from "react" +import { ChevronDown, X } from "lucide-react" +import { useRouter } from "next/navigation" + +import { Button } from "@/components/ui/buttons/Button" +import { + Command, + CommandEmpty, + CommandInput, + CommandItem, + CommandList, +} from "@/components/ui/command" +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover" + +type TagFilterProps = { + tags: string[] + tagLabels: Record + selectedTag?: string + category: string + count: number + labels: { + filterBy: string + clearFilter: string + noTags: string + showing: string + } +} + +export default function TagFilter({ + tags, + tagLabels, + selectedTag, + category, + count, + labels, +}: TagFilterProps) { + const router = useRouter() + const [open, setOpen] = useState(false) + + const handleSelectTag = (tag: string) => { + router.push(`/developers/apps/${category}?tag=${encodeURIComponent(tag)}`, { + scroll: false, + }) + setOpen(false) + } + + const handleClearTag = () => { + router.push(`/developers/apps/${category}`, { scroll: false }) + } + + const COMBOBOX_ID = "tag-filter-listbox" + + return ( +
+
+ + + + + + + + + {labels.noTags} + {tags.map((tag) => ( + handleSelectTag(tag)} + > + {tagLabels[tag]} + + ))} + + + + + + {selectedTag && ( + + )} +
+ +

+ {labels.showing} ({count}) +

+
+ ) +} diff --git a/src/intl/en/page-developers-apps.json b/src/intl/en/page-developers-apps.json index f9606b1a1b8..27af1bd05a4 100644 --- a/src/intl/en/page-developers-apps.json +++ b/src/intl/en/page-developers-apps.json @@ -30,6 +30,11 @@ "page-developers-apps-category-transactions-description": "Infrastructure for building, signing, sending, simulating, and managing Ethereum transactions and wallets.", "page-developers-apps-category-transactions-meta-description": "Tools for building Ethereum wallets signing sending simulating and managing transactions with secure wallet infrastructure.", "page-developers-apps-category-transactions-title": "Transaction & wallet infrastructure", + "page-developers-apps-filter-label": "Filter by", + "page-developers-apps-filter-clear": "Clear filter", + "page-developers-apps-filter-empty": "No apps match the selected filter", + "page-developers-apps-filter-no-tags": "No tags found", + "page-developers-apps-filter-showing": "Showing", "page-developers-apps-highlights": "Highlights", "page-developers-apps-meta-description": "Discover Ethereum developer tooling including smart contract frameworks SDKs security testing analytics and wallet infrastructure to build and scale web3 apps.", "page-developers-apps-meta-title": "Developer tooling", From 584a24aa37626d13e13f11f84b50dcc45b28a3e1 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 20 Jan 2026 18:43:11 -0800 Subject: [PATCH 25/74] fix: searchParam handling - Handle multiple params independently - Clear invalid params on page load --- .../developers/apps/[category]/page.tsx | 28 +++++++++++++++++-- .../apps/_components/AppModalWrapper.tsx | 11 ++++++-- .../developers/apps/_components/TagFilter.tsx | 15 ++++++++-- app/[locale]/developers/apps/page.tsx | 6 ++++ 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/app/[locale]/developers/apps/[category]/page.tsx b/app/[locale]/developers/apps/[category]/page.tsx index c060075b248..95c5507adc3 100644 --- a/app/[locale]/developers/apps/[category]/page.tsx +++ b/app/[locale]/developers/apps/[category]/page.tsx @@ -1,5 +1,6 @@ import { AppWindowMac } from "lucide-react" import Image from "next/image" +import { redirect } from "next/navigation" import { getTranslations, setRequestLocale } from "next-intl/server" import { PageParams } from "@/lib/types" @@ -64,6 +65,19 @@ const Page = async ({ const activeApp = enrichedData.find((app) => app.id === appId) + // Clean up invalid searchParams by redirecting + const hasInvalidTag = tag && !validTag + const hasInvalidAppId = appId && !activeApp + if (hasInvalidTag || hasInvalidAppId) { + const params = new URLSearchParams() + if (validTag) params.set("tag", validTag) + if (activeApp) params.set("appId", activeApp.id) + const queryString = params.toString() + redirect( + `/developers/apps/${category}${queryString ? `?${queryString}` : ""}` + ) + } + // Prepare translations for client component const tagLabels = Object.fromEntries( uniqueTags.map((tag) => [tag, t(`page-developers-apps-tag-${tag}`)]) @@ -80,6 +94,16 @@ const Page = async ({ featuredNames.includes(name) ) + // Helper to build app modal link with preserved tag param + const buildAppLink = (appId: string) => { + const params = new URLSearchParams() + params.set("appId", appId) + if (validTag) { + params.set("tag", validTag) + } + return `?${params.toString()}` + } + return ( <> @@ -184,7 +208,7 @@ const Page = async ({ className="h-fit rounded-xl p-6 hover:bg-background-highlight" > diff --git a/app/[locale]/developers/apps/_components/AppModalWrapper.tsx b/app/[locale]/developers/apps/_components/AppModalWrapper.tsx index b374c086ee6..f6f7bcd2748 100644 --- a/app/[locale]/developers/apps/_components/AppModalWrapper.tsx +++ b/app/[locale]/developers/apps/_components/AppModalWrapper.tsx @@ -1,6 +1,6 @@ "use client" -import { usePathname, useRouter } from "next/navigation" +import { usePathname, useRouter, useSearchParams } from "next/navigation" import Modal from "@/components/ui/dialog-modal" import { type ModalProps } from "@/components/ui/dialog-modal" @@ -10,12 +10,19 @@ import { cn } from "@/lib/utils/cn" const AppModalWrapper = (props: ModalProps) => { const router = useRouter() const pathname = usePathname() + const searchParams = useSearchParams() return ( { if (open) return - router.replace(pathname, { scroll: false }) + // Remove only appId param, preserve others (like tag) + const params = new URLSearchParams(searchParams.toString()) + params.delete("appId") + const queryString = params.toString() + router.replace(`${pathname}${queryString ? `?${queryString}` : ""}`, { + scroll: false, + }) }} contentProps={{ className: cn( diff --git a/app/[locale]/developers/apps/_components/TagFilter.tsx b/app/[locale]/developers/apps/_components/TagFilter.tsx index 75b3d175f8e..ba63e75cfe1 100644 --- a/app/[locale]/developers/apps/_components/TagFilter.tsx +++ b/app/[locale]/developers/apps/_components/TagFilter.tsx @@ -2,7 +2,7 @@ import { useState } from "react" import { ChevronDown, X } from "lucide-react" -import { useRouter } from "next/navigation" +import { useRouter, useSearchParams } from "next/navigation" import { Button } from "@/components/ui/buttons/Button" import { @@ -41,17 +41,26 @@ export default function TagFilter({ labels, }: TagFilterProps) { const router = useRouter() + const searchParams = useSearchParams() const [open, setOpen] = useState(false) const handleSelectTag = (tag: string) => { - router.push(`/developers/apps/${category}?tag=${encodeURIComponent(tag)}`, { + const params = new URLSearchParams(searchParams.toString()) + params.set("tag", tag) + router.push(`/developers/apps/${category}?${params.toString()}`, { scroll: false, }) setOpen(false) } const handleClearTag = () => { - router.push(`/developers/apps/${category}`, { scroll: false }) + const params = new URLSearchParams(searchParams.toString()) + params.delete("tag") + const queryString = params.toString() + router.push( + `/developers/apps/${category}${queryString ? `?${queryString}` : ""}`, + { scroll: false } + ) } const COMBOBOX_ID = "tag-filter-listbox" diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/apps/page.tsx index cf0d03ef212..d54fe55573f 100644 --- a/app/[locale]/developers/apps/page.tsx +++ b/app/[locale]/developers/apps/page.tsx @@ -1,5 +1,6 @@ import { AppWindowMac } from "lucide-react" import Image from "next/image" +import { redirect } from "next/navigation" import { getTranslations, setRequestLocale } from "next-intl/server" import { type PageParams } from "@/lib/types" @@ -53,6 +54,11 @@ const Page = async ({ const activeApp = enrichedData.find((app) => app.id === appId) + // Clean up invalid appId by redirecting + if (appId && !activeApp) { + redirect("/developers/apps") + } + const featuredNames = ["ZK Email", "Hardhat", "Updraft"] // TODO: determine logic, make DRY const highlights = enrichedData.filter(({ name }) => featuredNames.includes(name) From 87898a6c3b0a09470a2a98789333a5806542d724 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 20 Jan 2026 19:28:28 -0800 Subject: [PATCH 26/74] feat: HighlightsSection abstraction --- .../apps/_components/HighlightsSection.tsx | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 app/[locale]/developers/apps/_components/HighlightsSection.tsx diff --git a/app/[locale]/developers/apps/_components/HighlightsSection.tsx b/app/[locale]/developers/apps/_components/HighlightsSection.tsx new file mode 100644 index 00000000000..df599cec9db --- /dev/null +++ b/app/[locale]/developers/apps/_components/HighlightsSection.tsx @@ -0,0 +1,109 @@ +import Image from "next/image" +import { getLocale, getTranslations } from "next-intl/server" + +import { CardBanner, CardParagraph, CardTitle } from "@/components/ui/card" +import { + EdgeScrollContainer, + EdgeScrollItem, +} from "@/components/ui/edge-scroll-container" +import { LinkBox, LinkOverlay } from "@/components/ui/link-box" +import { Section } from "@/components/ui/section" +import { Tag, TagProps, TagsInlineText } from "@/components/ui/tag" + +import { cn } from "@/lib/utils/cn" + +import { DEV_APP_CATEGORIES, DEV_APP_CATEGORY_SLUGS } from "../constants" +import type { DeveloperApp } from "../types" + +const HighlightsSection = async ({ apps }: { apps: DeveloperApp[] }) => { + const locale = await getLocale() + const t = await getTranslations({ locale, namespace: "page-developers-apps" }) + const tCommon = await getTranslations({ locale, namespace: "common" }) + + // Don't render section if no apps to highlight + if (apps.length === 0) return null + + return ( +
+

{t("page-developers-apps-highlights")}

+ + {apps.map((app) => { + // Safety check - skip apps without required images + if (!app.banner_url || !app.thumbnail_url) return null + + const categorySlug = DEV_APP_CATEGORY_SLUGS[app.category] + const tagStyle: TagProps["status"] = + DEV_APP_CATEGORIES.find(({ slug }) => slug === categorySlug)?.tag || + "tag" + return ( + + + +
+ + + + + {app.description} + +
+
+ + {tCommon("item-logo", + + +
+ + {t( + `page-developers-apps-category-${categorySlug}-title` + )} + + + {app.name} + + + t(`page-developers-apps-tag-${tag}`) + )} + variant="light" + className="lowercase" + /> +
+
+
+
+
+ ) + })} +
+
+ ) +} + +export default HighlightsSection From ddf527ccab83bf2f985f840c75d3db2bf34cacc8 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 20 Jan 2026 19:49:36 -0800 Subject: [PATCH 27/74] feat: pseudo-randomize highlight cards - By category - Use unstable-cache, revalidate weekly --- .../developers/apps/[category]/page.tsx | 94 +-------- app/[locale]/developers/apps/page.tsx | 104 +--------- app/[locale]/developers/apps/utils.ts | 191 +++++++++++++++++- 3 files changed, 209 insertions(+), 180 deletions(-) diff --git a/app/[locale]/developers/apps/[category]/page.tsx b/app/[locale]/developers/apps/[category]/page.tsx index 95c5507adc3..e289d541f43 100644 --- a/app/[locale]/developers/apps/[category]/page.tsx +++ b/app/[locale]/developers/apps/[category]/page.tsx @@ -8,23 +8,22 @@ import { PageParams } from "@/lib/types" import { ContentHero } from "@/components/Hero" import MainArticle from "@/components/MainArticle" import SubpageCard from "@/components/SubpageCard" -import { CardBanner, CardParagraph, CardTitle } from "@/components/ui/card" -import { - EdgeScrollContainer, - EdgeScrollItem, -} from "@/components/ui/edge-scroll-container" import { LinkBox, LinkOverlay } from "@/components/ui/link-box" import { Section } from "@/components/ui/section" -import { Tag, TagsInlineText } from "@/components/ui/tag" +import { TagsInlineText } from "@/components/ui/tag" -import { cn } from "@/lib/utils/cn" import { getMetadata } from "@/lib/utils/metadata" import AppModalContents from "../_components/AppModalContents" import AppModalWrapper from "../_components/AppModalWrapper" +import HighlightsSection from "../_components/HighlightsSection" import TagFilter from "../_components/TagFilter" import { DEV_APP_CATEGORIES } from "../constants" import type { DeveloperAppCategorySlug, DeveloperAppTag } from "../types" +import { + getCachedHighlightsByCategory, + getCategoryPageHighlights, +} from "../utils" import { transformDeveloperAppsData } from "../utils" import { routing } from "@/i18n/routing" @@ -42,7 +41,6 @@ const Page = async ({ setRequestLocale(locale) const t = await getTranslations({ locale, namespace: "page-developers-apps" }) - const tCommon = await getTranslations({ locale, namespace: "common" }) const enrichedData = await getDeveloperToolsData() if (!enrichedData) throw Error("No developer apps data available") @@ -89,10 +87,9 @@ const Page = async ({ showing: t("page-developers-apps-filter-showing"), } - const featuredNames = ["ZK Email", "Hardhat", "Updraft"] // TODO: determine logic, make DRY - const highlights = enrichedData.filter(({ name }) => - featuredNames.includes(name) - ) + // Get dynamic highlights based on stars and recent activity (cached weekly) + const highlightsByCategory = await getCachedHighlightsByCategory(enrichedData) + const highlights = getCategoryPageHighlights(highlightsByCategory, category) // Helper to build app modal link with preserved tag param const buildAppLink = (appId: string) => { @@ -114,78 +111,7 @@ const Page = async ({ description={t(`page-developers-apps-category-${category}-description`)} // TODO: Confirm /> - {/* Featured developer tools */} -
-

{t("page-developers-apps-highlights")}

- - {highlights.map((app) => ( - - - -
- - - - - {app.description} - -
-
- - {tCommon("item-logo", - - -
- - {app.category} - - {app.name} - - t(`page-developers-apps-tag-${tag}`) - )} - max={3} // TODO: Confirm / sort? - variant="light" - className="lowercase" - /> -
-
-
-
-
- ))} -
-
+

diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/apps/page.tsx index d54fe55573f..49c573ec028 100644 --- a/app/[locale]/developers/apps/page.tsx +++ b/app/[locale]/developers/apps/page.tsx @@ -9,26 +9,22 @@ import { ContentHero } from "@/components/Hero" import MainArticle from "@/components/MainArticle" import SubpageCard from "@/components/SubpageCard" import { Button } from "@/components/ui/buttons/Button" -import { - Card, - CardBanner, - CardParagraph, - CardTitle, -} from "@/components/ui/card" +import { Card } from "@/components/ui/card" import { EdgeScrollContainer, EdgeScrollItem, } from "@/components/ui/edge-scroll-container" import { LinkBox, LinkOverlay } from "@/components/ui/link-box" import { Section } from "@/components/ui/section" -import { Tag, TagProps, TagsInlineText } from "@/components/ui/tag" +import { TagsInlineText } from "@/components/ui/tag" -import { cn } from "@/lib/utils/cn" import { getMetadata } from "@/lib/utils/metadata" import AppModalContents from "./_components/AppModalContents" import AppModalWrapper from "./_components/AppModalWrapper" -import { DEV_APP_CATEGORIES, DEV_APP_CATEGORY_SLUGS } from "./constants" +import HighlightsSection from "./_components/HighlightsSection" +import { DEV_APP_CATEGORIES } from "./constants" +import { getCachedHighlightsByCategory, getMainPageHighlights } from "./utils" import { transformDeveloperAppsData } from "./utils" import { routing } from "@/i18n/routing" @@ -46,7 +42,6 @@ const Page = async ({ setRequestLocale(locale) const t = await getTranslations({ locale, namespace: "page-developers-apps" }) - const tCommon = await getTranslations({ locale, namespace: "common" }) const enrichedData = await getDeveloperToolsData() if (!enrichedData) throw Error("No developer apps data available") @@ -59,10 +54,9 @@ const Page = async ({ redirect("/developers/apps") } - const featuredNames = ["ZK Email", "Hardhat", "Updraft"] // TODO: determine logic, make DRY - const highlights = enrichedData.filter(({ name }) => - featuredNames.includes(name) - ) + // Get dynamic highlights based on stars and recent activity (cached weekly) + const highlightsByCategory = await getCachedHighlightsByCategory(enrichedData) + const highlights = getMainPageHighlights(highlightsByCategory) return ( <> @@ -72,87 +66,7 @@ const Page = async ({ description={t("page-developers-apps-subtitle")} /> -
-

{t("page-developers-apps-highlights")}

- - {highlights.map((app) => { - const categorySlug = DEV_APP_CATEGORY_SLUGS[app.category] - const tagStyle: TagProps["status"] = - DEV_APP_CATEGORIES.find(({ slug }) => slug === categorySlug) - ?.tag || "tag" - return ( - - - -
- - - - - {app.description} - -
-
- - {tCommon("item-logo", - - -
- - {t( - `page-developers-apps-category-${categorySlug}-title` - )} - - - {app.name} - - - t(`page-developers-apps-tag-${tag}`) - )} - max={3} // TODO: Confirm / sort? - variant="light" - className="lowercase" - /> -
-
-
-
-
- ) - })} -
-
+

{t("page-developers-apps-applications-title")}

diff --git a/app/[locale]/developers/apps/utils.ts b/app/[locale]/developers/apps/utils.ts index 8105261631e..3b68fb81c1a 100644 --- a/app/[locale]/developers/apps/utils.ts +++ b/app/[locale]/developers/apps/utils.ts @@ -1,6 +1,18 @@ +import { unstable_cache } from "next/cache" + import { DEV_APP_CATEGORY_SLUGS } from "./constants" -import type { DeveloperApp, DeveloperAppsByCategory } from "./types" +import type { + DeveloperApp, + DeveloperAppCategorySlug, + DeveloperAppsByCategory, +} from "./types" + +// Cache duration: 7 days in seconds +const SEVEN_DAYS = 7 * 24 * 60 * 60 +/** + * Transform flat array of apps into an object grouped by category slug + */ export const transformDeveloperAppsData = ( data: DeveloperApp[] ): DeveloperAppsByCategory => { @@ -18,3 +30,180 @@ export const transformDeveloperAppsData = ( return acc }, initialAcc) } + +/** + * Get ISO week number for a given date + * Used as seed for deterministic weekly rotation of highlights + * + * Why weekly? This ensures all users see the same highlights during a given week, + * providing consistent UX while still rotating content regularly. + */ +function getWeekNumber(date: Date): number { + const d = new Date( + Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()) + ) + const dayNum = d.getUTCDay() || 7 + d.setUTCDate(d.getUTCDate() + 4 - dayNum) + const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1)) + return Math.ceil(((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7) +} + +/** + * Seeded random number generator for deterministic randomization + * Uses Linear Congruential Generator algorithm + * + * Why not Math.random() or timestamp? + * - Math.random(): Non-deterministic, every user sees different highlights + * - Timestamp: Different on every page load, causes jarring UX + * - Seeded: Same seed = same "random" sequence = consistent highlights for all users + */ +function seededRandom(seed: number) { + let value = seed + return () => { + value = (value * 9301 + 49297) % 233280 + return value / 233280 + } +} + +/** + * Shuffle array using Fisher-Yates algorithm with seeded randomization + * Ensures deterministic shuffle: same seed always produces same order + */ +function seededShuffle(array: T[], seed: number): T[] { + const shuffled = [...array] + const random = seededRandom(seed) + + for (let i = shuffled.length - 1; i > 0; i--) { + const j = Math.floor(random() * (i + 1)) + ;[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]] + } + + return shuffled +} + +/** + * Get highlighted apps grouped by category + * + * Algorithm: + * 1. Filter to apps with GitHub repos updated in last 6 months + have banner/thumbnail images + * 2. Group by category slug + * 3. Sort each category by highest GitHub star count + * 4. Take top 9 apps per category + * 5. Shuffle each category's top 9 using weekly seed for deterministic rotation + * + * @returns Object mapping category slugs to arrays of up to 9 highlighted apps + */ +export function getHighlightsByCategory( + apps: DeveloperApp[] +): Record { + const sixMonthsAgo = new Date() + sixMonthsAgo.setMonth(sixMonthsAgo.getMonth() - 6) + + // Filter apps with GitHub repos updated in last 6 months and have required images + const recentApps = apps.filter((app) => { + // Must have both banner and thumbnail images for highlights section + if (!app.banner_url || !app.thumbnail_url) return false + + const hasGitHubRepo = app.repos.some((repo) => + repo.href.includes("github.com") + ) + if (!hasGitHubRepo) return false + + const latestUpdate = app.repos.reduce((latest, repo) => { + if (!repo.lastUpdated) return latest + const date = new Date(repo.lastUpdated) + return date > latest ? date : latest + }, new Date(0)) + + return latestUpdate > sixMonthsAgo + }) + + // Group by category slug + const byCategory: Record = {} + for (const app of recentApps) { + const categorySlug = DEV_APP_CATEGORY_SLUGS[app.category] + if (!categorySlug) continue + if (!byCategory[categorySlug]) { + byCategory[categorySlug] = [] + } + byCategory[categorySlug].push(app) + } + + // Get weekly seed for deterministic randomization + const weekSeed = getWeekNumber(new Date()) + + // Sort by stars, take top 9, randomize + const result: Record = {} + for (const [category, categoryApps] of Object.entries(byCategory)) { + // Sort by highest star count + const sorted = [...categoryApps].sort((a, b) => { + const aStars = Math.max(...a.repos.map((repo) => repo.stargazers || 0), 0) + const bStars = Math.max(...b.repos.map((repo) => repo.stargazers || 0), 0) + return bStars - aStars + }) + + // Take top 9 and randomize + const top9 = sorted.slice(0, 9) + const randomized = seededShuffle(top9, weekSeed + category.length) + + result[category] = randomized + } + + return result as Record +} + +/** + * Get highlights for main /developers/apps page + * Returns top app from top 3 randomly-ordered categories + * + * @returns Array of 3 apps (one from each of top 3 categories) + */ +export function getMainPageHighlights( + highlightsByCategory: Record +): DeveloperApp[] { + const weekSeed = getWeekNumber(new Date()) + + // Get categories with highlights + const categoriesWithHighlights = Object.entries(highlightsByCategory).filter( + ([, apps]) => apps.length > 0 + ) + + // Randomize category order + const randomizedCategories = seededShuffle(categoriesWithHighlights, weekSeed) + + // Take top app from top 3 categories + return randomizedCategories + .slice(0, 3) + .map(([, apps]) => apps[0]) + .filter(Boolean) +} + +/** + * Get highlights for category page + * Returns top 3 apps for the specified category + */ +export function getCategoryPageHighlights( + highlightsByCategory: Record, + category: DeveloperAppCategorySlug +): DeveloperApp[] { + return highlightsByCategory[category]?.slice(0, 3) || [] +} + +/** + * Cached version of getHighlightsByCategory + * + * Uses Next.js unstable_cache to cache the computation for 7 days. + * Since the input data (apps array) is already cached via getDeveloperToolsData(), + * this primarily caches the sorting/filtering/randomization computation. + * + * Cache key includes the function name, ensuring cache invalidation when function changes. + * Tagged for manual cache invalidation if needed via revalidateTag('developer-apps-highlights'). + */ +export const getCachedHighlightsByCategory = unstable_cache( + async (apps: DeveloperApp[]) => getHighlightsByCategory(apps), + ["highlights-by-category"], + { + revalidate: SEVEN_DAYS, + tags: ["developer-apps-highlights"], + } +) From 94f0c1a006a06f2d85b1938bb5bd6e0c476db44e Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 20 Jan 2026 20:15:51 -0800 Subject: [PATCH 28/74] patch: clean up tasks - type import - ui/card thumbnail shrink-0 - content hero custom styling - Tag rounded corners to accommodate text wrapping --- app/[locale]/developers/apps/[category]/page.tsx | 1 + .../developers/apps/_components/AppModalContents.tsx | 2 +- .../developers/apps/_components/HighlightsSection.tsx | 6 +++++- app/[locale]/developers/apps/page.tsx | 1 + src/components/ui/card.tsx | 2 +- 5 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/[locale]/developers/apps/[category]/page.tsx b/app/[locale]/developers/apps/[category]/page.tsx index e289d541f43..17d84971946 100644 --- a/app/[locale]/developers/apps/[category]/page.tsx +++ b/app/[locale]/developers/apps/[category]/page.tsx @@ -109,6 +109,7 @@ const Page = async ({ }} title={t(`page-developers-apps-category-${category}-title`)} description={t(`page-developers-apps-category-${category}-description`)} // TODO: Confirm + className="border-none pb-0" /> diff --git a/app/[locale]/developers/apps/_components/AppModalContents.tsx b/app/[locale]/developers/apps/_components/AppModalContents.tsx index d572ed9d9c3..eeb2656e6fa 100644 --- a/app/[locale]/developers/apps/_components/AppModalContents.tsx +++ b/app/[locale]/developers/apps/_components/AppModalContents.tsx @@ -10,7 +10,7 @@ import { Tag, TagsInlineText } from "@/components/ui/tag" import { formatDate, getValidDate } from "@/lib/utils/date" import { isExternal } from "@/lib/utils/url" -import { DeveloperApp } from "../types" +import type { DeveloperApp } from "../types" const AppModalContents = async ({ app }: { app: DeveloperApp }) => { const locale = await getLocale() diff --git a/app/[locale]/developers/apps/_components/HighlightsSection.tsx b/app/[locale]/developers/apps/_components/HighlightsSection.tsx index df599cec9db..294beff1894 100644 --- a/app/[locale]/developers/apps/_components/HighlightsSection.tsx +++ b/app/[locale]/developers/apps/_components/HighlightsSection.tsx @@ -79,7 +79,11 @@ const HighlightsSection = async ({ apps }: { apps: DeveloperApp[] }) => {
- + {t( `page-developers-apps-category-${categorySlug}-title` )} diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/apps/page.tsx index 49c573ec028..b218fe03bfc 100644 --- a/app/[locale]/developers/apps/page.tsx +++ b/app/[locale]/developers/apps/page.tsx @@ -64,6 +64,7 @@ const Page = async ({ breadcrumbs={{ slug: "/developers/apps" }} title={t("page-developers-apps-title")} description={t("page-developers-apps-subtitle")} + className="border-none pb-0" /> diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx index 07478b61f1f..bc4ab5e77fa 100644 --- a/src/components/ui/card.tsx +++ b/src/components/ui/card.tsx @@ -71,7 +71,7 @@ const cardBannerVariants = cva( }, size: { full: "h-48 w-full self-stretch", - thumbnail: "size-16", + thumbnail: "size-16 shrink-0", }, }, defaultVariants: { From 1359c577b501294d560097168105f0ae3df63aa1 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 20 Jan 2026 20:18:25 -0800 Subject: [PATCH 29/74] patch: highlight card banner image sizing external images are 4x1 aspect ratio --- .../developers/apps/_components/HighlightsSection.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/[locale]/developers/apps/_components/HighlightsSection.tsx b/app/[locale]/developers/apps/_components/HighlightsSection.tsx index 294beff1894..e5df541d436 100644 --- a/app/[locale]/developers/apps/_components/HighlightsSection.tsx +++ b/app/[locale]/developers/apps/_components/HighlightsSection.tsx @@ -53,14 +53,13 @@ const HighlightsSection = async ({ apps }: { apps: DeveloperApp[] }) => { className="space-y-6 no-underline" >
- + From 977bbd48ac5845c692d132823025369a9239f23d Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 20 Jan 2026 20:44:13 -0800 Subject: [PATCH 30/74] update: site developers navigation - Reorder menu items - Update copy and links --- src/components/Footer.tsx | 8 ++++---- src/intl/en/common.json | 10 +++++----- src/lib/nav/buildNavigation.ts | 20 ++++++++++---------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index 3028a683050..b40db225b46 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -165,12 +165,12 @@ const Footer = ({ lastDeployLocaleTimestamp }: FooterProps) => { text: t("documentation"), }, { - href: "/developers/learning-tools/", - text: t("learn-by-coding"), + href: "/developers/apps/education/", + text: t("learn-ethereum-development"), }, { - href: "/developers/local-environment/", - text: t("set-up-local-env"), + href: "/developers/apps/", + text: t("start-building"), }, { href: "/community/grants/", diff --git a/src/intl/en/common.json b/src/intl/en/common.json index d01c7751e00..3df2a11e9e8 100644 --- a/src/intl/en/common.json +++ b/src/intl/en/common.json @@ -218,7 +218,7 @@ "last-updated": "Last updated", "layer-2": "Layer 2", "learn": "Learn", - "learn-by-coding": "Learn by coding", + "learn-ethereum-development": "Learn Ethereum development", "learn-hub": "Learn Hub", "learn-menu": "Learn menu", "learn-more": "Learn more", @@ -304,8 +304,8 @@ "nav-guides-label": "How to guides", "nav-history-description": "A timeline of all the major forks and updates", "nav-history-label": "Technical history of Ethereum", - "nav-learn-by-coding-description": "Tools that help you experiment with Ethereum", - "nav-local-env-description": "Choose and set up your Ethereum development stack", + "nav-learn-ethereum-development-description": "Begin or level-up your Ethereum development education", + "nav-start-building-description": "Choose and set up your Ethereum development stack", "nav-networks-home-description": "Cheaper and faster transactions for Ethereum", "nav-networks-introduction-label": "Introduction", "nav-networks-introduction-description": "Ethereum expanded into network of networks", @@ -361,7 +361,7 @@ "nav-staking-saas-label": "Staking with a service", "nav-staking-solo-description": "Run home hardware and personally add to the security and decentralization of the Ethereum network", "nav-staking-solo-label": "Solo staking", - "nav-start-building-description": "Useful information for newcomers", + "nav-start-get-started-description": "Useful information for newcomers", "nav-start-with-crypto-title": "Start here", "nav-start-with-crypto-description": "Your first steps using Ethereum", "nav-translation-program-description": "A collaborative effort to translate ethereum.org to all languages", @@ -432,7 +432,7 @@ "secret-leader-election": "Secret leader election", "security": "Security", "see-contributors": "See contributors", - "set-up-local-env": "Set up local environment", + "start-building": "Start building", "sharding": "Sharding", "show-all": "Show all", "show-more": "Show more", diff --git a/src/lib/nav/buildNavigation.ts b/src/lib/nav/buildNavigation.ts index 412e40fea69..93e214f3bc5 100644 --- a/src/lib/nav/buildNavigation.ts +++ b/src/lib/nav/buildNavigation.ts @@ -307,22 +307,22 @@ export const buildNavigation = (t: TranslateFn): NavSections => { { id: "build/get-started", label: t("get-started"), - description: t("nav-start-building-description"), + description: t("nav-start-get-started-description"), items: [ { - label: t("tutorials"), - description: t("nav-tutorials-description"), - href: "/developers/tutorials/", + label: t("learn-ethereum-development"), + description: t("nav-learn-ethereum-development-description"), + href: "/developers/apps/education/", }, { - label: t("learn-by-coding"), - description: t("nav-learn-by-coding-description"), - href: "/developers/learning-tools/", + label: t("start-building"), + description: t("nav-start-building-description"), + href: "/developers/apps/", }, { - label: t("set-up-local-env"), - description: t("nav-local-env-description"), - href: "/developers/local-environment/", + label: t("tutorials"), + description: t("nav-tutorials-description"), + href: "/developers/tutorials/", }, { label: t("grants"), From e3f8540bb8c757d5b22d3e4a70c8889166bfd7bb Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 20 Jan 2026 20:57:35 -0800 Subject: [PATCH 31/74] feat(seo): add JSON-LD to developer apps pages Add structured data (JSON-LD) for /developers/apps and category pages following established patterns from /apps pages. Includes: - WebPage schema with localized breadcrumbs - ItemList schema for categories and apps - Contributor metadata - Ethereum Foundation as publisher Co-Authored-By: Claude Sonnet 4.5 --- .../apps/[category]/page-jsonld.tsx | 108 ++++++++++++++++++ .../developers/apps/[category]/page.tsx | 19 ++- app/[locale]/developers/apps/page-jsonld.tsx | 101 ++++++++++++++++ app/[locale]/developers/apps/page.tsx | 13 ++- 4 files changed, 239 insertions(+), 2 deletions(-) create mode 100644 app/[locale]/developers/apps/[category]/page-jsonld.tsx create mode 100644 app/[locale]/developers/apps/page-jsonld.tsx diff --git a/app/[locale]/developers/apps/[category]/page-jsonld.tsx b/app/[locale]/developers/apps/[category]/page-jsonld.tsx new file mode 100644 index 00000000000..d4fe1401ea2 --- /dev/null +++ b/app/[locale]/developers/apps/[category]/page-jsonld.tsx @@ -0,0 +1,108 @@ +import { getTranslations } from "next-intl/server" + +import { FileContributor } from "@/lib/types" + +import PageJsonLD from "@/components/PageJsonLD" + +import { + ethereumCommunityOrganization, + ethereumFoundationOrganization, +} from "@/lib/utils/jsonld" +import { normalizeUrlForJsonLd } from "@/lib/utils/url" + +import type { DeveloperApp, DeveloperAppCategorySlug } from "../types" + +export default async function DevelopersAppsCategoryJsonLD({ + locale, + category, + categoryApps, + contributors, +}: { + locale: string + category: DeveloperAppCategorySlug + categoryApps: DeveloperApp[] + contributors: FileContributor[] +}) { + const t = await getTranslations({ namespace: "page-developers-apps" }) + + const url = normalizeUrlForJsonLd(locale, `/developers/apps/${category}`) + + const contributorList = contributors.map((contributor) => ({ + "@type": "Person", + name: contributor.login, + url: contributor.html_url, + })) + + const jsonLd = { + "@context": "https://schema.org", + "@graph": [ + { + "@type": "WebPage", + "@id": url, + name: t(`page-developers-apps-category-${category}-title`), + description: t( + `page-developers-apps-category-${category}-meta-description` + ), + url: url, + inLanguage: locale, + contributor: contributorList, + author: [ethereumCommunityOrganization], + isPartOf: { + "@type": "WebSite", + "@id": "https://ethereum.org/#website", + name: "ethereum.org", + url: "https://ethereum.org", + }, + breadcrumb: { + "@type": "BreadcrumbList", + itemListElement: [ + { + "@type": "ListItem", + position: 1, + name: "Home", + item: normalizeUrlForJsonLd(locale, "/"), + }, + { + "@type": "ListItem", + position: 2, + name: "Developers", + item: normalizeUrlForJsonLd(locale, "/developers/"), + }, + { + "@type": "ListItem", + position: 3, + name: t("page-developers-apps-meta-title"), + item: normalizeUrlForJsonLd(locale, "/developers/apps/"), + }, + { + "@type": "ListItem", + position: 4, + name: t(`page-developers-apps-category-${category}-title`), + item: url, + }, + ], + }, + publisher: ethereumFoundationOrganization, + reviewedBy: ethereumFoundationOrganization, + mainEntity: { "@id": `${url}#category-apps` }, + }, + { + "@type": "ItemList", + "@id": `${url}#category-apps`, + name: t(`page-developers-apps-category-${category}-title`), + description: t(`page-developers-apps-category-${category}-description`), + url: url, + numberOfItems: categoryApps.length, + itemListElement: categoryApps.slice(0, 10).map((app, index) => ({ + "@type": "ListItem", + position: index + 1, + name: app.name, + description: app.description, + url: app.website, + })), + }, + ], + } + + return +} diff --git a/app/[locale]/developers/apps/[category]/page.tsx b/app/[locale]/developers/apps/[category]/page.tsx index 17d84971946..2da3fb93c48 100644 --- a/app/[locale]/developers/apps/[category]/page.tsx +++ b/app/[locale]/developers/apps/[category]/page.tsx @@ -3,7 +3,7 @@ import Image from "next/image" import { redirect } from "next/navigation" import { getTranslations, setRequestLocale } from "next-intl/server" -import { PageParams } from "@/lib/types" +import type { CommitHistory, Lang, PageParams } from "@/lib/types" import { ContentHero } from "@/components/Hero" import MainArticle from "@/components/MainArticle" @@ -12,6 +12,7 @@ import { LinkBox, LinkOverlay } from "@/components/ui/link-box" import { Section } from "@/components/ui/section" import { TagsInlineText } from "@/components/ui/tag" +import { getAppPageContributorInfo } from "@/lib/utils/contributors" import { getMetadata } from "@/lib/utils/metadata" import AppModalContents from "../_components/AppModalContents" @@ -26,6 +27,8 @@ import { } from "../utils" import { transformDeveloperAppsData } from "../utils" +import DevelopersAppsCategoryJsonLD from "./page-jsonld" + import { routing } from "@/i18n/routing" import { getDeveloperToolsData } from "@/lib/data" @@ -101,8 +104,22 @@ const Page = async ({ return `?${params.toString()}` } + // Get contributor info for JSON-LD + const commitHistoryCache: CommitHistory = {} + const { contributors } = await getAppPageContributorInfo( + `developers/apps/${category}`, + locale as Lang, + commitHistoryCache + ) + return ( <> + ({ + "@type": "Person", + name: contributor.login, + url: contributor.html_url, + })) + + const jsonLd = { + "@context": "https://schema.org", + "@graph": [ + { + "@type": "WebPage", + "@id": url, + name: t("page-developers-apps-meta-title"), + description: t("page-developers-apps-meta-description"), + url: url, + inLanguage: locale, + contributor: contributorList, + author: [ethereumCommunityOrganization], + isPartOf: { + "@type": "WebSite", + "@id": "https://ethereum.org/#website", + name: "ethereum.org", + url: "https://ethereum.org", + }, + breadcrumb: { + "@type": "BreadcrumbList", + itemListElement: [ + { + "@type": "ListItem", + position: 1, + name: "Home", + item: normalizeUrlForJsonLd(locale, "/"), + }, + { + "@type": "ListItem", + position: 2, + name: "Developers", + item: normalizeUrlForJsonLd(locale, "/developers/"), + }, + { + "@type": "ListItem", + position: 3, + name: t("page-developers-apps-meta-title"), + item: url, + }, + ], + }, + publisher: ethereumFoundationOrganization, + reviewedBy: ethereumFoundationOrganization, + mainEntity: { "@id": `${url}#developer-apps` }, + }, + { + "@type": "ItemList", + "@id": `${url}#developer-apps`, + name: t("page-developers-apps-categories-title"), + description: t("page-developers-apps-meta-description"), + url: url, + numberOfItems: DEV_APP_CATEGORIES.length, + itemListElement: DEV_APP_CATEGORIES.map((category, index) => ({ + "@type": "ListItem", + position: index + 1, + name: t(`page-developers-apps-category-${category.slug}-title`), + description: t( + `page-developers-apps-category-${category.slug}-description` + ), + url: normalizeUrlForJsonLd( + locale, + `/developers/apps/${category.slug}` + ), + })), + }, + ], + } + + return +} diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/apps/page.tsx index b218fe03bfc..4a04d5e978f 100644 --- a/app/[locale]/developers/apps/page.tsx +++ b/app/[locale]/developers/apps/page.tsx @@ -3,7 +3,7 @@ import Image from "next/image" import { redirect } from "next/navigation" import { getTranslations, setRequestLocale } from "next-intl/server" -import { type PageParams } from "@/lib/types" +import type { CommitHistory, Lang, PageParams } from "@/lib/types" import { ContentHero } from "@/components/Hero" import MainArticle from "@/components/MainArticle" @@ -18,12 +18,14 @@ import { LinkBox, LinkOverlay } from "@/components/ui/link-box" import { Section } from "@/components/ui/section" import { TagsInlineText } from "@/components/ui/tag" +import { getAppPageContributorInfo } from "@/lib/utils/contributors" import { getMetadata } from "@/lib/utils/metadata" import AppModalContents from "./_components/AppModalContents" import AppModalWrapper from "./_components/AppModalWrapper" import HighlightsSection from "./_components/HighlightsSection" import { DEV_APP_CATEGORIES } from "./constants" +import DevelopersAppsJsonLD from "./page-jsonld" import { getCachedHighlightsByCategory, getMainPageHighlights } from "./utils" import { transformDeveloperAppsData } from "./utils" @@ -58,8 +60,17 @@ const Page = async ({ const highlightsByCategory = await getCachedHighlightsByCategory(enrichedData) const highlights = getMainPageHighlights(highlightsByCategory) + // Get contributor info for JSON-LD + const commitHistoryCache: CommitHistory = {} + const { contributors } = await getAppPageContributorInfo( + "developers/apps", + locale as Lang, + commitHistoryCache + ) + return ( <> + Date: Tue, 20 Jan 2026 20:59:10 -0800 Subject: [PATCH 32/74] patch: modal banner height and aspect ratio - External images use 4x1 aspect ratio --- .../developers/apps/_components/AppModalContents.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/[locale]/developers/apps/_components/AppModalContents.tsx b/app/[locale]/developers/apps/_components/AppModalContents.tsx index eeb2656e6fa..e2d04bc891c 100644 --- a/app/[locale]/developers/apps/_components/AppModalContents.tsx +++ b/app/[locale]/developers/apps/_components/AppModalContents.tsx @@ -19,13 +19,13 @@ const AppModalContents = async ({ app }: { app: DeveloperApp }) => { return (
-
+
{app.banner_url && ( )} From eeb512455f79b7d6a497791bffec320efa3968be Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 20 Jan 2026 22:56:54 -0800 Subject: [PATCH 33/74] feat: add date and time helper functions --- src/lib/utils/date.ts | 30 ++++++++++++++++++++++++++++++ src/lib/utils/time.ts | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/src/lib/utils/date.ts b/src/lib/utils/date.ts index e62b694afac..82d53ca18df 100644 --- a/src/lib/utils/date.ts +++ b/src/lib/utils/date.ts @@ -60,3 +60,33 @@ export const getLocaleYear = ( new Intl.DateTimeFormat(locale, { year: "numeric" }).format( date ? new Date(date) : new Date() ) + +/** + * Get ISO week number for a given date + * Used as seed for deterministic weekly rotation + * + * @param date - The date to get the week number for + * @returns ISO week number (1-53) + */ +export const getWeekNumber = (date: Date): number => { + const d = new Date( + Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()) + ) + const dayNum = d.getUTCDay() || 7 + d.setUTCDate(d.getUTCDate() + 4 - dayNum) + const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1)) + return Math.ceil(((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7) +} + +/** + * Get day of year for a given date (1-365/366) + * Used as seed for deterministic daily rotation + * + * @param date - The date to get the day of year for + * @returns Day of year (1-365 or 1-366 for leap years) + */ +export const getDayOfYear = (date: Date): number => { + const start = new Date(date.getFullYear(), 0, 0) + const diff = date.getTime() - start.getTime() + return Math.floor(diff / 86400000) +} diff --git a/src/lib/utils/time.ts b/src/lib/utils/time.ts index 0eadcd13ad6..4b5a34927f6 100644 --- a/src/lib/utils/time.ts +++ b/src/lib/utils/time.ts @@ -21,3 +21,37 @@ export const getLocaleFormattedDate = (locale: Lang, date: string) => { return new Intl.DateTimeFormat(locale).format(walletLastUpdatedDate) } + +/** + * Returns a duration in seconds for the given interval. + * + * @param interval - "minute" | "hour" | "day" | "week" | "month" + * @param multiplier - Number of intervals (default: 1) + * @returns Duration in seconds + */ +export const every = ( + interval: "minute" | "hour" | "day" | "week" | "month", + multiplier: number = 1 +): number => { + const SECOND = 1 + const MINUTE = 60 * SECOND + const HOUR = 60 * MINUTE + const DAY = 24 * HOUR + const WEEK = 7 * DAY + const MONTH = 28 * DAY // approximate + + switch (interval) { + case "minute": + return multiplier * MINUTE + case "hour": + return multiplier * HOUR + case "day": + return multiplier * DAY + case "week": + return multiplier * WEEK + case "month": + return multiplier * MONTH + default: + return multiplier * DAY + } +} From 562706e0211d23a256815409edfa96b37775aea7 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 20 Jan 2026 22:59:04 -0800 Subject: [PATCH 34/74] feat: randomize category card apps daily --- app/[locale]/developers/apps/page.tsx | 12 ++- app/[locale]/developers/apps/utils.ts | 120 +++++++++++++++++++------- 2 files changed, 97 insertions(+), 35 deletions(-) diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/apps/page.tsx index 4a04d5e978f..df5ce477b70 100644 --- a/app/[locale]/developers/apps/page.tsx +++ b/app/[locale]/developers/apps/page.tsx @@ -26,7 +26,11 @@ import AppModalWrapper from "./_components/AppModalWrapper" import HighlightsSection from "./_components/HighlightsSection" import { DEV_APP_CATEGORIES } from "./constants" import DevelopersAppsJsonLD from "./page-jsonld" -import { getCachedHighlightsByCategory, getMainPageHighlights } from "./utils" +import { + getCachedHighlightsByCategory, + getCachedRandomPreviewsByCategory, + getMainPageHighlights, +} from "./utils" import { transformDeveloperAppsData } from "./utils" import { routing } from "@/i18n/routing" @@ -60,6 +64,10 @@ const Page = async ({ const highlightsByCategory = await getCachedHighlightsByCategory(enrichedData) const highlights = getMainPageHighlights(highlightsByCategory) + // Get randomized previews (5 apps per category) - cached daily + const previewsByCategory = + await getCachedRandomPreviewsByCategory(dataByCategory) + // Get contributor info for JSON-LD const commitHistoryCache: CommitHistory = {} const { contributors } = await getAppPageContributorInfo( @@ -121,7 +129,7 @@ const Page = async ({ - {dataByCategory[slug].slice(0, 5).map((app) => ( + {previewsByCategory[slug].map((app) => ( (array: T[], seed: number): T[] { return shuffled } +/** + * Get maximum star count across all repos for an app + */ +function getMaxStarCount(app: DeveloperApp): number { + return Math.max(...app.repos.map((repo) => repo.stargazers || 0), 0) +} + +/** + * Generate seed offset based on category name for variety across categories + */ +function getCategorySeedOffset(category: string): number { + return category.length +} + /** * Get highlighted apps grouped by category * @@ -94,9 +96,10 @@ function seededShuffle(array: T[], seed: number): T[] { * @returns Object mapping category slugs to arrays of up to 9 highlighted apps */ export function getHighlightsByCategory( - apps: DeveloperApp[] + apps: DeveloperApp[], + now: Date = new Date() ): Record { - const sixMonthsAgo = new Date() + const sixMonthsAgo = new Date(now) sixMonthsAgo.setMonth(sixMonthsAgo.getMonth() - 6) // Filter apps with GitHub repos updated in last 6 months and have required images @@ -130,21 +133,22 @@ export function getHighlightsByCategory( } // Get weekly seed for deterministic randomization - const weekSeed = getWeekNumber(new Date()) + const weekSeed = getWeekNumber(now) - // Sort by stars, take top 9, randomize + // Sort by stars, take top N, randomize const result: Record = {} for (const [category, categoryApps] of Object.entries(byCategory)) { // Sort by highest star count const sorted = [...categoryApps].sort((a, b) => { - const aStars = Math.max(...a.repos.map((repo) => repo.stargazers || 0), 0) - const bStars = Math.max(...b.repos.map((repo) => repo.stargazers || 0), 0) - return bStars - aStars + return getMaxStarCount(b) - getMaxStarCount(a) }) - // Take top 9 and randomize - const top9 = sorted.slice(0, 9) - const randomized = seededShuffle(top9, weekSeed + category.length) + // Take top N and randomize + const topN = sorted.slice(0, HIGHLIGHTS_PER_CATEGORY) + const randomized = seededShuffle( + topN, + weekSeed + getCategorySeedOffset(category) + ) result[category] = randomized } @@ -159,9 +163,10 @@ export function getHighlightsByCategory( * @returns Array of 3 apps (one from each of top 3 categories) */ export function getMainPageHighlights( - highlightsByCategory: Record + highlightsByCategory: Record, + now: Date = new Date() ): DeveloperApp[] { - const weekSeed = getWeekNumber(new Date()) + const weekSeed = getWeekNumber(now) // Get categories with highlights const categoriesWithHighlights = Object.entries(highlightsByCategory).filter( @@ -192,7 +197,7 @@ export function getCategoryPageHighlights( /** * Cached version of getHighlightsByCategory * - * Uses Next.js unstable_cache to cache the computation for 7 days. + * Uses Next.js unstable_cache to cache the computation for 1 week. * Since the input data (apps array) is already cached via getDeveloperToolsData(), * this primarily caches the sorting/filtering/randomization computation. * @@ -203,7 +208,56 @@ export const getCachedHighlightsByCategory = unstable_cache( async (apps: DeveloperApp[]) => getHighlightsByCategory(apps), ["highlights-by-category"], { - revalidate: SEVEN_DAYS, + revalidate: every("week"), tags: ["developer-apps-highlights"], } ) + +/** + * Get randomized preview apps per category for main page cards + * + * Simpler than highlights: no filtering, no star sorting - just shuffle and take N. + * Uses daily seed for rotation instead of weekly. + * + * @param dataByCategory - Apps already grouped by category + * @returns Same structure but with max N randomized apps per category + */ +export function getRandomPreviewsByCategory( + dataByCategory: DeveloperAppsByCategory, + now: Date = new Date() +): DeveloperAppsByCategory { + const daySeed = getDayOfYear(now) + + const result = {} as DeveloperAppsByCategory + + for (const [category, apps] of Object.entries(dataByCategory)) { + // Shuffle with daily seed + category offset for variety + const shuffled = seededShuffle( + apps, + daySeed + getCategorySeedOffset(category) + ) + // Take first N after shuffle + result[category as DeveloperAppCategorySlug] = shuffled.slice( + 0, + PREVIEWS_PER_CATEGORY + ) + } + + return result +} + +/** + * Cached version of getRandomPreviewsByCategory + * + * Caches for 1 day (24 hours) to align with daily seed rotation. + * Simpler than highlights - no complex filtering, just randomization. + */ +export const getCachedRandomPreviewsByCategory = unstable_cache( + async (dataByCategory: DeveloperAppsByCategory) => + getRandomPreviewsByCategory(dataByCategory), + ["random-previews-by-category"], + { + revalidate: every("day"), + tags: ["developer-apps-previews"], + } +) From d9905bed2354d5f168cc4fd1c115a8592cfdffdf Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 20 Jan 2026 23:04:44 -0800 Subject: [PATCH 35/74] fix/refactor: tag colors; extract reusable helper --- .../apps/_components/AppModalContents.tsx | 6 +++++- .../apps/_components/HighlightsSection.tsx | 11 +++++------ app/[locale]/developers/apps/utils.ts | 15 ++++++++++++++- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/app/[locale]/developers/apps/_components/AppModalContents.tsx b/app/[locale]/developers/apps/_components/AppModalContents.tsx index e2d04bc891c..b2381c9016a 100644 --- a/app/[locale]/developers/apps/_components/AppModalContents.tsx +++ b/app/[locale]/developers/apps/_components/AppModalContents.tsx @@ -10,13 +10,17 @@ import { Tag, TagsInlineText } from "@/components/ui/tag" import { formatDate, getValidDate } from "@/lib/utils/date" import { isExternal } from "@/lib/utils/url" +import { DEV_APP_CATEGORY_SLUGS } from "../constants" import type { DeveloperApp } from "../types" +import { getCategoryTagStyle } from "../utils" const AppModalContents = async ({ app }: { app: DeveloperApp }) => { const locale = await getLocale() const t = await getTranslations({ locale, namespace: "page-developers-apps" }) const tCommon = await getTranslations({ locale, namespace: "common" }) + const categorySlug = DEV_APP_CATEGORY_SLUGS[app.category] + return (
@@ -34,7 +38,7 @@ const AppModalContents = async ({ app }: { app: DeveloperApp }) => {
{app.category} diff --git a/app/[locale]/developers/apps/_components/HighlightsSection.tsx b/app/[locale]/developers/apps/_components/HighlightsSection.tsx index e5df541d436..81e6e8bf680 100644 --- a/app/[locale]/developers/apps/_components/HighlightsSection.tsx +++ b/app/[locale]/developers/apps/_components/HighlightsSection.tsx @@ -8,12 +8,13 @@ import { } from "@/components/ui/edge-scroll-container" import { LinkBox, LinkOverlay } from "@/components/ui/link-box" import { Section } from "@/components/ui/section" -import { Tag, TagProps, TagsInlineText } from "@/components/ui/tag" +import { Tag, TagsInlineText } from "@/components/ui/tag" import { cn } from "@/lib/utils/cn" -import { DEV_APP_CATEGORIES, DEV_APP_CATEGORY_SLUGS } from "../constants" +import { DEV_APP_CATEGORY_SLUGS } from "../constants" import type { DeveloperApp } from "../types" +import { getCategoryTagStyle } from "../utils" const HighlightsSection = async ({ apps }: { apps: DeveloperApp[] }) => { const locale = await getLocale() @@ -32,9 +33,7 @@ const HighlightsSection = async ({ apps }: { apps: DeveloperApp[] }) => { if (!app.banner_url || !app.thumbnail_url) return null const categorySlug = DEV_APP_CATEGORY_SLUGS[app.category] - const tagStyle: TagProps["status"] = - DEV_APP_CATEGORIES.find(({ slug }) => slug === categorySlug)?.tag || - "tag" + return ( {
{t( diff --git a/app/[locale]/developers/apps/utils.ts b/app/[locale]/developers/apps/utils.ts index b42829ca7df..642134ffaef 100644 --- a/app/[locale]/developers/apps/utils.ts +++ b/app/[locale]/developers/apps/utils.ts @@ -1,9 +1,11 @@ import { unstable_cache } from "next/cache" +import type { TagProps } from "@/components/ui/tag" + import { getDayOfYear, getWeekNumber } from "@/lib/utils/date" import { every } from "@/lib/utils/time" -import { DEV_APP_CATEGORY_SLUGS } from "./constants" +import { DEV_APP_CATEGORIES, DEV_APP_CATEGORY_SLUGS } from "./constants" import type { DeveloperApp, DeveloperAppCategorySlug, @@ -261,3 +263,14 @@ export const getCachedRandomPreviewsByCategory = unstable_cache( tags: ["developer-apps-previews"], } ) + +/** + * Gets the tag style for a developer app category based on its slug. + * + * @param categorySlug - The slug identifier for the developer app category + * @returns The tag status style associated with the category, or "tag" as the default fallback + */ +export const getCategoryTagStyle = ( + categorySlug: DeveloperAppCategorySlug +): TagProps["status"] => + DEV_APP_CATEGORIES.find(({ slug }) => slug === categorySlug)?.tag || "tag" From 32bfd831a391c5c49b10357a4b4d25fb5fa54b8a Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Wed, 21 Jan 2026 08:52:41 -0800 Subject: [PATCH 36/74] feat: add simple markdown parser - For use with in-page markdown content parsing, not full pages with front matter - Simplifies use of headers to bold paragraphs - Accepts optional component overrides Co-Authored-By: Claude Sonnet 4.5 --- src/lib/md/renderSimple.tsx | 126 ++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 src/lib/md/renderSimple.tsx diff --git a/src/lib/md/renderSimple.tsx b/src/lib/md/renderSimple.tsx new file mode 100644 index 00000000000..c0f1d90370c --- /dev/null +++ b/src/lib/md/renderSimple.tsx @@ -0,0 +1,126 @@ +import { compileMDX, type MDXRemoteProps } from "next-mdx-remote/rsc" +import type { HTMLAttributes } from "react" +import remarkGfm from "remark-gfm" + +import InlineLink from "@/components/ui/Link" +import { ListItem, OrderedList, UnorderedList } from "@/components/ui/list" + +import { cn } from "@/lib/utils/cn" + +type ComponentProps = HTMLAttributes & { + children?: React.ReactNode +} + +/** + * Minimal markdown components for user-generated content + * Stripped down from MdComponents - no tooltips, images, or complex features + */ +const simpleComponents = { + // All headings become bold paragraphs + h1: ({ children, className, ...props }: ComponentProps) => ( +

+ {children} +

+ ), + h2: ({ children, className, ...props }: ComponentProps) => ( +

+ {children} +

+ ), + h3: ({ children, className, ...props }: ComponentProps) => ( +

+ {children} +

+ ), + h4: ({ children, className, ...props }: ComponentProps) => ( +

+ {children} +

+ ), + h5: ({ children, className, ...props }: ComponentProps) => ( +

+ {children} +

+ ), + h6: ({ children, className, ...props }: ComponentProps) => ( +

+ {children} +

+ ), + + // Basic paragraph + p: ({ children, className, ...props }: ComponentProps) => ( +

+ {children} +

+ ), + + // Lists + ul: (props: ComponentProps) => , + ol: (props: ComponentProps) => , + li: (props: ComponentProps) => , + + // Inline formatting + strong: ({ children, ...props }: ComponentProps) => ( + + {children} + + ), + em: ({ children, ...props }: ComponentProps) => ( + + {children} + + ), + code: ({ children, ...props }: ComponentProps) => ( + + {children} + + ), + + // Links + a: (props: React.AnchorHTMLAttributes) => ( + + ), + + // Blockquote + blockquote: ({ children, ...props }: ComponentProps) => ( +
+ {children} +
+ ), + + // Horizontal rule + hr: () =>
, +} + +/** + * Renders simple markdown to React components + * For user-generated content like app descriptions + * + * @param markdown - The markdown string to render + * @param componentOverrides - Optional component overrides (e.g., { img: () => null }) + * @returns React element with rendered markdown + */ +export async function renderSimpleMarkdown( + markdown: string, + componentOverrides?: MDXRemoteProps["components"] +) { + const { content } = await compileMDX({ + source: markdown, + components: { ...simpleComponents, ...componentOverrides }, + options: { + parseFrontmatter: false, + mdxOptions: { + remarkPlugins: [remarkGfm], + }, + }, + }) + + return content +} From d05c5a3cc5926f33ddd8c04fd55be6a08becb405 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Wed, 21 Jan 2026 08:55:30 -0800 Subject: [PATCH 37/74] feat: parse descriptions for markdown in app modal --- .../developers/apps/_components/AppModalContents.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/[locale]/developers/apps/_components/AppModalContents.tsx b/app/[locale]/developers/apps/_components/AppModalContents.tsx index b2381c9016a..820a7f4ebeb 100644 --- a/app/[locale]/developers/apps/_components/AppModalContents.tsx +++ b/app/[locale]/developers/apps/_components/AppModalContents.tsx @@ -14,6 +14,8 @@ import { DEV_APP_CATEGORY_SLUGS } from "../constants" import type { DeveloperApp } from "../types" import { getCategoryTagStyle } from "../utils" +import { renderSimpleMarkdown } from "@/lib/md/renderSimple" + const AppModalContents = async ({ app }: { app: DeveloperApp }) => { const locale = await getLocale() const t = await getTranslations({ locale, namespace: "page-developers-apps" }) @@ -50,9 +52,9 @@ const AppModalContents = async ({ app }: { app: DeveloperApp }) => { className="lowercase" />
-

- {app.description} -

+
+ {await renderSimpleMarkdown(app.description, { img: () => null })} +

{t("page-developers-apps-modal-links")}

From a65cebf184d7d79db0d96914c70db74b65cdbabe Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Wed, 21 Jan 2026 09:03:32 -0800 Subject: [PATCH 38/74] feat: add stripMarkdown helper util - Removes markdown syntax without parsing Co-Authored-By: Claude Sonnet 4.5 --- src/lib/utils/md.ts | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/lib/utils/md.ts b/src/lib/utils/md.ts index 81e6f15010d..39fa1506a7d 100644 --- a/src/lib/utils/md.ts +++ b/src/lib/utils/md.ts @@ -142,3 +142,34 @@ export const checkPathValidity = ( (path) => path.locale === locale && path.slug.join("/") === slugArray.join("/") ) + +/** + * Strips markdown syntax from text, leaving plain text + * For preview/snippet text where markdown shouldn't be visible + * + * @param text - Text with markdown syntax + * @returns Plain text with markdown markers removed + */ +export function stripMarkdown(text: string): string { + return ( + text + // Remove bold/italic (**text** or __text__) + .replace(/(\*\*|__)(.*?)\1/g, "$2") + // Remove italic (*text* or _text_) + .replace(/(\*|_)(.*?)\1/g, "$2") + // Remove inline code (`code`) + .replace(/`([^`]+)`/g, "$1") + // Remove links [text](url) → text + .replace(/\[([^\]]+)\]\([^)]+\)/g, "$1") + // Remove images ![alt](url) → empty + .replace(/!\[([^\]]*)\]\([^)]+\)/g, "") + // Remove headings (# text) + .replace(/^#{1,6}\s+/gm, "") + // Remove list markers (- or * or 1.) + .replace(/^[\s]*[-*+]\s+/gm, "") + .replace(/^[\s]*\d+\.\s+/gm, "") + // Clean up extra whitespace + .replace(/\s+/g, " ") + .trim() + ) +} From 657fbd5cf2cfd24c2cd67f234b1c0245a3a4754d Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Wed, 21 Jan 2026 09:04:08 -0800 Subject: [PATCH 39/74] feat: use stripMarkdown on app card descriptions --- app/[locale]/developers/apps/_components/HighlightsSection.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/[locale]/developers/apps/_components/HighlightsSection.tsx b/app/[locale]/developers/apps/_components/HighlightsSection.tsx index 81e6e8bf680..f3e05837546 100644 --- a/app/[locale]/developers/apps/_components/HighlightsSection.tsx +++ b/app/[locale]/developers/apps/_components/HighlightsSection.tsx @@ -11,6 +11,7 @@ import { Section } from "@/components/ui/section" import { Tag, TagsInlineText } from "@/components/ui/tag" import { cn } from "@/lib/utils/cn" +import { stripMarkdown } from "@/lib/utils/md" import { DEV_APP_CATEGORY_SLUGS } from "../constants" import type { DeveloperApp } from "../types" @@ -62,7 +63,7 @@ const HighlightsSection = async ({ apps }: { apps: DeveloperApp[] }) => { /> - {app.description} + {stripMarkdown(app.description)}
From 23428d5e71511cd0def06e380eb771a333276f7b Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Wed, 21 Jan 2026 11:24:43 -0800 Subject: [PATCH 40/74] feat(ui): Add "lg" modal content size variant --- src/components/ui/dialog-modal.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/ui/dialog-modal.tsx b/src/components/ui/dialog-modal.tsx index 4ad55ce2eae..848ec47c119 100644 --- a/src/components/ui/dialog-modal.tsx +++ b/src/components/ui/dialog-modal.tsx @@ -24,6 +24,9 @@ const dialogVariant = tv({ md: { content: "max-w-xl", }, + lg: { + content: "max-w-2xl", + }, xl: { content: "max-w-[1004px]", }, From 789a19d8cb19f09b6c40b9fafb299342a7c63ad6 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Wed, 21 Jan 2026 11:25:25 -0800 Subject: [PATCH 41/74] update(ui): use modal size=lg --- app/[locale]/developers/apps/_components/AppModalWrapper.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/app/[locale]/developers/apps/_components/AppModalWrapper.tsx b/app/[locale]/developers/apps/_components/AppModalWrapper.tsx index f6f7bcd2748..a5188480e38 100644 --- a/app/[locale]/developers/apps/_components/AppModalWrapper.tsx +++ b/app/[locale]/developers/apps/_components/AppModalWrapper.tsx @@ -14,6 +14,7 @@ const AppModalWrapper = (props: ModalProps) => { return ( { if (open) return // Remove only appId param, preserve others (like tag) From 604bfafd06590d0bee2746b6a7b8f7a115a9f3dc Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Wed, 21 Jan 2026 11:36:47 -0800 Subject: [PATCH 42/74] patch: banner image height with blur bg --- .../developers/apps/_components/HighlightsSection.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/[locale]/developers/apps/_components/HighlightsSection.tsx b/app/[locale]/developers/apps/_components/HighlightsSection.tsx index 81e6e8bf680..0b3f10bb308 100644 --- a/app/[locale]/developers/apps/_components/HighlightsSection.tsx +++ b/app/[locale]/developers/apps/_components/HighlightsSection.tsx @@ -52,13 +52,22 @@ const HighlightsSection = async ({ apps }: { apps: DeveloperApp[] }) => { className="space-y-6 no-underline" >
- + + From f564b7b5a3157201e1fcf250d4ea9214dc7a9c56 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Wed, 21 Jan 2026 12:03:09 -0800 Subject: [PATCH 43/74] refactor: generateStaticParams without locale - locale params handled by app/[locale]/layout.tsx --- app/[locale]/developers/apps/[category]/page.tsx | 5 +---- app/[locale]/developers/apps/page.tsx | 7 ------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/app/[locale]/developers/apps/[category]/page.tsx b/app/[locale]/developers/apps/[category]/page.tsx index 2da3fb93c48..0456d95a6c4 100644 --- a/app/[locale]/developers/apps/[category]/page.tsx +++ b/app/[locale]/developers/apps/[category]/page.tsx @@ -29,7 +29,6 @@ import { transformDeveloperAppsData } from "../utils" import DevelopersAppsCategoryJsonLD from "./page-jsonld" -import { routing } from "@/i18n/routing" import { getDeveloperToolsData } from "@/lib/data" const Page = async ({ @@ -218,9 +217,7 @@ const Page = async ({ } export async function generateStaticParams() { - return routing.locales.flatMap((locale) => { - return DEV_APP_CATEGORIES.map(({ slug }) => ({ category: slug, locale })) - }) + return DEV_APP_CATEGORIES.map(({ slug }) => ({ category: slug })) } export async function generateMetadata({ diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/apps/page.tsx index df5ce477b70..53034993506 100644 --- a/app/[locale]/developers/apps/page.tsx +++ b/app/[locale]/developers/apps/page.tsx @@ -33,7 +33,6 @@ import { } from "./utils" import { transformDeveloperAppsData } from "./utils" -import { routing } from "@/i18n/routing" import { getDeveloperToolsData } from "@/lib/data" const Page = async ({ @@ -201,12 +200,6 @@ const Page = async ({ ) } -export async function generateStaticParams() { - return routing.locales.map((locale) => ({ - locale, - })) -} - export async function generateMetadata({ params, }: { From 4014054953f8d29accafb8cac8a0d090e148dd0e Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Wed, 21 Jan 2026 13:18:56 -0800 Subject: [PATCH 44/74] patch: modal rounded corners --- app/[locale]/developers/apps/_components/AppModalWrapper.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/app/[locale]/developers/apps/_components/AppModalWrapper.tsx b/app/[locale]/developers/apps/_components/AppModalWrapper.tsx index a5188480e38..cda36c19d32 100644 --- a/app/[locale]/developers/apps/_components/AppModalWrapper.tsx +++ b/app/[locale]/developers/apps/_components/AppModalWrapper.tsx @@ -27,6 +27,7 @@ const AppModalWrapper = (props: ModalProps) => { }} contentProps={{ className: cn( + "rounded-lg overflow-hidden", "[&_button:has(.lucide-x)]:m-2 [&_button:has(.lucide-x)]:p-1 [&_button:has(.lucide-x)]:rounded", "hover:[&_button:has(.lucide-x)]:text-primary-hover [&_button:has(.lucide-x)]:bg-background/75 hover:[&_button:has(.lucide-x)]:bg-background", "[&_.lucide-x]:!stroke-[3]" From b1d66c81d3156d61bd74fc6b5dbc748d54c8653e Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Wed, 21 Jan 2026 20:15:17 -0800 Subject: [PATCH 45/74] deprecate: dev local-environment, learning-tools Implement redirects to new /developers/apps/ and /developers/apps/education/ pages --- .../_components/learning-tools.tsx | 468 ------------------ .../developers/learning-tools/page-jsonld.tsx | 80 --- .../developers/learning-tools/page.tsx | 69 --- .../_components/local-environment.tsx | 120 ----- .../local-environment/page-jsonld.tsx | 112 ----- .../developers/local-environment/page.tsx | 96 ---- public/images/dev-tools/alchemyuniversity.png | Bin 19091 -> 0 bytes public/images/dev-tools/atlas.png | Bin 43881 -> 0 bytes public/images/dev-tools/bloomtech.png | Bin 5735 -> 0 bytes public/images/dev-tools/capturetheether.png | Bin 1455 -> 0 bytes public/images/dev-tools/chainIDE.png | Bin 5796 -> 0 bytes public/images/dev-tools/consensys.png | Bin 4478 -> 0 bytes public/images/dev-tools/crypto-zombie.png | Bin 30810 -> 0 bytes public/images/dev-tools/cyfrin-updraft.png | Bin 4622 -> 0 bytes public/images/dev-tools/dapp-world.png | Bin 22615 -> 0 bytes public/images/dev-tools/eth-dot-build.png | Bin 1804 -> 0 bytes public/images/dev-tools/learnweb3.png | Bin 21480 -> 0 bytes public/images/dev-tools/metaschool.png | Bin 32609 -> 0 bytes public/images/dev-tools/node-guardians.jpg | Bin 45061 -> 0 bytes public/images/dev-tools/oz.png | Bin 1269 -> 0 bytes public/images/dev-tools/questbook.png | Bin 2615 -> 0 bytes public/images/dev-tools/remix.png | Bin 2548 -> 0 bytes public/images/dev-tools/replit.png | Bin 5231 -> 0 bytes public/images/dev-tools/tenderly.png | Bin 38108 -> 0 bytes redirects.config.js | 4 +- src/components/LearningToolsCardGrid.tsx | 17 - src/components/ProductCard.tsx | 142 ------ src/data/frameworks.ts | 87 ---- .../ar/page-developers-learning-tools.json | 52 -- .../ar/page-developers-local-environment.json | 33 -- .../bn/page-developers-learning-tools.json | 52 -- .../bn/page-developers-local-environment.json | 33 -- .../cs/page-developers-learning-tools.json | 62 --- .../cs/page-developers-local-environment.json | 33 -- .../de/page-developers-learning-tools.json | 62 --- .../de/page-developers-local-environment.json | 33 -- .../en/page-developers-learning-tools.json | 64 --- .../en/page-developers-local-environment.json | 33 -- .../es/page-developers-learning-tools.json | 64 --- .../es/page-developers-local-environment.json | 33 -- .../fr/page-developers-learning-tools.json | 62 --- .../fr/page-developers-local-environment.json | 33 -- .../hi/page-developers-learning-tools.json | 52 -- .../hi/page-developers-local-environment.json | 33 -- .../id/page-developers-learning-tools.json | 62 --- .../id/page-developers-local-environment.json | 33 -- .../it/page-developers-learning-tools.json | 62 --- .../it/page-developers-local-environment.json | 33 -- .../ja/page-developers-learning-tools.json | 62 --- .../ja/page-developers-local-environment.json | 33 -- .../ko/page-developers-learning-tools.json | 52 -- .../ko/page-developers-local-environment.json | 33 -- .../mr/page-developers-learning-tools.json | 52 -- .../mr/page-developers-local-environment.json | 33 -- .../pl/page-developers-learning-tools.json | 52 -- .../pl/page-developers-local-environment.json | 33 -- .../pt-br/page-developers-learning-tools.json | 62 --- .../page-developers-local-environment.json | 33 -- .../ru/page-developers-learning-tools.json | 62 --- .../ru/page-developers-local-environment.json | 33 -- .../sw/page-developers-learning-tools.json | 40 -- .../sw/page-developers-local-environment.json | 29 -- .../ta/page-developers-learning-tools.json | 3 - .../tr/page-developers-learning-tools.json | 62 --- .../tr/page-developers-local-environment.json | 33 -- .../uk/page-developers-learning-tools.json | 52 -- .../uk/page-developers-local-environment.json | 33 -- .../ur/page-developers-learning-tools.json | 3 - .../vi/page-developers-learning-tools.json | 52 -- .../vi/page-developers-local-environment.json | 33 -- .../zh-tw/page-developers-learning-tools.json | 62 --- .../page-developers-local-environment.json | 33 -- .../zh/page-developers-learning-tools.json | 62 --- .../zh/page-developers-local-environment.json | 33 -- src/lib/interfaces.ts | 14 - 75 files changed, 3 insertions(+), 3200 deletions(-) delete mode 100644 app/[locale]/developers/learning-tools/_components/learning-tools.tsx delete mode 100644 app/[locale]/developers/learning-tools/page-jsonld.tsx delete mode 100644 app/[locale]/developers/learning-tools/page.tsx delete mode 100644 app/[locale]/developers/local-environment/_components/local-environment.tsx delete mode 100644 app/[locale]/developers/local-environment/page-jsonld.tsx delete mode 100644 app/[locale]/developers/local-environment/page.tsx delete mode 100644 public/images/dev-tools/alchemyuniversity.png delete mode 100644 public/images/dev-tools/atlas.png delete mode 100644 public/images/dev-tools/bloomtech.png delete mode 100644 public/images/dev-tools/capturetheether.png delete mode 100644 public/images/dev-tools/chainIDE.png delete mode 100644 public/images/dev-tools/consensys.png delete mode 100644 public/images/dev-tools/crypto-zombie.png delete mode 100644 public/images/dev-tools/cyfrin-updraft.png delete mode 100644 public/images/dev-tools/dapp-world.png delete mode 100644 public/images/dev-tools/eth-dot-build.png delete mode 100644 public/images/dev-tools/learnweb3.png delete mode 100644 public/images/dev-tools/metaschool.png delete mode 100644 public/images/dev-tools/node-guardians.jpg delete mode 100644 public/images/dev-tools/oz.png delete mode 100644 public/images/dev-tools/questbook.png delete mode 100644 public/images/dev-tools/remix.png delete mode 100644 public/images/dev-tools/replit.png delete mode 100644 public/images/dev-tools/tenderly.png delete mode 100644 src/components/LearningToolsCardGrid.tsx delete mode 100644 src/components/ProductCard.tsx delete mode 100644 src/data/frameworks.ts delete mode 100644 src/intl/ar/page-developers-learning-tools.json delete mode 100644 src/intl/ar/page-developers-local-environment.json delete mode 100644 src/intl/bn/page-developers-learning-tools.json delete mode 100644 src/intl/bn/page-developers-local-environment.json delete mode 100644 src/intl/cs/page-developers-learning-tools.json delete mode 100644 src/intl/cs/page-developers-local-environment.json delete mode 100644 src/intl/de/page-developers-learning-tools.json delete mode 100644 src/intl/de/page-developers-local-environment.json delete mode 100644 src/intl/en/page-developers-learning-tools.json delete mode 100644 src/intl/en/page-developers-local-environment.json delete mode 100644 src/intl/es/page-developers-learning-tools.json delete mode 100644 src/intl/es/page-developers-local-environment.json delete mode 100644 src/intl/fr/page-developers-learning-tools.json delete mode 100644 src/intl/fr/page-developers-local-environment.json delete mode 100644 src/intl/hi/page-developers-learning-tools.json delete mode 100644 src/intl/hi/page-developers-local-environment.json delete mode 100644 src/intl/id/page-developers-learning-tools.json delete mode 100644 src/intl/id/page-developers-local-environment.json delete mode 100644 src/intl/it/page-developers-learning-tools.json delete mode 100644 src/intl/it/page-developers-local-environment.json delete mode 100644 src/intl/ja/page-developers-learning-tools.json delete mode 100644 src/intl/ja/page-developers-local-environment.json delete mode 100644 src/intl/ko/page-developers-learning-tools.json delete mode 100644 src/intl/ko/page-developers-local-environment.json delete mode 100644 src/intl/mr/page-developers-learning-tools.json delete mode 100644 src/intl/mr/page-developers-local-environment.json delete mode 100644 src/intl/pl/page-developers-learning-tools.json delete mode 100644 src/intl/pl/page-developers-local-environment.json delete mode 100644 src/intl/pt-br/page-developers-learning-tools.json delete mode 100644 src/intl/pt-br/page-developers-local-environment.json delete mode 100644 src/intl/ru/page-developers-learning-tools.json delete mode 100644 src/intl/ru/page-developers-local-environment.json delete mode 100644 src/intl/sw/page-developers-learning-tools.json delete mode 100644 src/intl/sw/page-developers-local-environment.json delete mode 100644 src/intl/ta/page-developers-learning-tools.json delete mode 100644 src/intl/tr/page-developers-learning-tools.json delete mode 100644 src/intl/tr/page-developers-local-environment.json delete mode 100644 src/intl/uk/page-developers-learning-tools.json delete mode 100644 src/intl/uk/page-developers-local-environment.json delete mode 100644 src/intl/ur/page-developers-learning-tools.json delete mode 100644 src/intl/vi/page-developers-learning-tools.json delete mode 100644 src/intl/vi/page-developers-local-environment.json delete mode 100644 src/intl/zh-tw/page-developers-learning-tools.json delete mode 100644 src/intl/zh-tw/page-developers-local-environment.json delete mode 100644 src/intl/zh/page-developers-learning-tools.json delete mode 100644 src/intl/zh/page-developers-local-environment.json diff --git a/app/[locale]/developers/learning-tools/_components/learning-tools.tsx b/app/[locale]/developers/learning-tools/_components/learning-tools.tsx deleted file mode 100644 index 1c097390f6e..00000000000 --- a/app/[locale]/developers/learning-tools/_components/learning-tools.tsx +++ /dev/null @@ -1,468 +0,0 @@ -"use client" - -import { BaseHTMLAttributes } from "react" -import { shuffle } from "lodash" - -import { LearningTool } from "@/lib/types" - -import CalloutBanner from "@/components/CalloutBanner" -import FeedbackCard from "@/components/FeedbackCard" -import LearningToolsCardGrid from "@/components/LearningToolsCardGrid" -import MainArticle from "@/components/MainArticle" -import Translation from "@/components/Translation" -import { Alert, AlertEmoji } from "@/components/ui/alert" -import { ButtonLink } from "@/components/ui/buttons/Button" - -import { cn } from "@/lib/utils/cn" - -import { useTranslation } from "@/hooks/useTranslation" -import AlchemyUniversityImage from "@/public/images/dev-tools/alchemyuniversity.png" -import AtlasImage from "@/public/images/dev-tools/atlas.png" -import BloomTechImage from "@/public/images/dev-tools/bloomtech.png" -import CaptureTheEtherImage from "@/public/images/dev-tools/capturetheether.png" -import ChainIDEImage from "@/public/images/dev-tools/chainIDE.png" -import ConsensysImage from "@/public/images/dev-tools/consensys.png" -import CryptoZombieImage from "@/public/images/dev-tools/crypto-zombie.png" -import CyfrinUpdraftImage from "@/public/images/dev-tools/cyfrin-updraft.png" -import DappWorldImage from "@/public/images/dev-tools/dapp-world.png" -import EthDotBuildImage from "@/public/images/dev-tools/eth-dot-build.png" -import LearnWeb3Image from "@/public/images/dev-tools/learnweb3.png" -import MetaschoolImage from "@/public/images/dev-tools/metaschool.png" -import NodeGuardiansImage from "@/public/images/dev-tools/node-guardians.jpg" -import EthernautImage from "@/public/images/dev-tools/oz.png" -import QuestbookImage from "@/public/images/dev-tools/questbook.png" -import RemixImage from "@/public/images/dev-tools/remix.png" -import ReplitImage from "@/public/images/dev-tools/replit.png" -import SpeedRunEthereumImage from "@/public/images/dev-tools/speed-run-ethereum.png" -import TenderlyImage from "@/public/images/dev-tools/tenderly.png" -import EnterpriseEth from "@/public/images/enterprise-eth.png" - -const Page = ({ className, ...props }: BaseHTMLAttributes) => ( -
-) - -const Header = ({ className, ...props }: BaseHTMLAttributes) => ( -
-) - -const H1 = ({ - className, - ...props -}: BaseHTMLAttributes) => ( -

-) - -const Subtitle = ({ - className, - ...props -}: BaseHTMLAttributes) => ( -

-) - -const SubtitleTwo = ({ - className, - ...props -}: BaseHTMLAttributes) => ( - -) - -const ContentBox = ({ - className, - ...props -}: BaseHTMLAttributes) => ( -
-) - -const StackContainer = ({ - className, - ...props -}: BaseHTMLAttributes) => ( -
-) - -const LearningToolsPage = () => { - const { t } = useTranslation(["page-developers-learning-tools"]) - - const randomizedSandboxes: Array = shuffle([ - { - name: "Remix", - description: t( - "page-developers-learning-tools:page-learning-tools-remix-description" - ), - url: "https://remix.ethereum.org", - image: RemixImage, - alt: t( - "page-developers-learning-tools:page-learning-tools-remix-logo-alt" - ), - background: "#5098d6", - subjects: ["Solidity", "Vyper"], - }, - { - name: "Eth.build", - description: t( - "page-developers-learning-tools:page-learning-tools-eth-dot-build-description" - ), - url: "https://eth.build/", - image: EthDotBuildImage, - alt: t( - "page-developers-learning-tools:page-learning-tools-eth-dot-build-logo-alt" - ), - background: "#000000", - subjects: ["web3"], - }, - { - name: "Replit", - description: t( - "page-developers-learning-tools:page-learning-tools-replit-description" - ), - url: "https://replit.com/@replit/Solidity-starter-beta", - image: ReplitImage, - alt: t( - "page-developers-learning-tools:page-learning-tools-replit-logo-alt" - ), - background: "#0f1524", - subjects: ["Solidity", "web3"], - }, - { - name: "ChainIDE", - description: t( - "page-developers-learning-tools:page-learning-tools-chainIDE-description" - ), - url: "https://chainide.com/", - image: ChainIDEImage, - alt: t( - "page-developers-learning-tools:page-learning-tools-chainIDE-logo-alt" - ), - background: "#2C60A3", - subjects: ["Solidity", "web3"], - }, - { - name: "Tenderly", - description: t( - "page-developers-learning-tools:page-learning-tools-tenderly-description" - ), - url: "https://sandbox.tenderly.co", - image: TenderlyImage, - alt: t( - "page-developers-learning-tools:page-learning-tools-tenderly-logo-alt" - ), - background: "#0f1524", - subjects: ["Solidity", "Vyper", "web3"], - }, - { - name: "Atlas", - description: t( - "page-developers-learning-tools:page-learning-tools-atlas-description" - ), - url: "https://www.atlaszk.com", - image: AtlasImage, - alt: t( - "page-developers-learning-tools:page-learning-tools-atlas-logo-alt" - ), - background: "#000000", - subjects: ["Solidity"], - }, - { - name: "DApp World", - description: t( - "page-developers-learning-tools:page-learning-tools-dapp-world-description" - ), - url: "https://dapp-world.com", - image: DappWorldImage, - alt: t( - "page-developers-learning-tools:page-learning-tools-dapp-world-logo-alt" - ), - background: "#e5e7eb", - subjects: ["Solidity", "web3"], - }, - ]) - - const games: Array = [ - { - name: "CryptoZombies", - description: t( - "page-developers-learning-tools:page-learning-tools-cryptozombies-description" - ), - url: "https://cryptozombies.io/", - image: CryptoZombieImage, - alt: t( - "page-developers-learning-tools:page-learning-tools-cryptozombies-logo-alt" - ), - background: "#2b2f48", - subjects: ["Solidity"], - }, - { - name: "Ethernauts", - description: t( - "page-developers-learning-tools:page-learning-tools-ethernauts-description" - ), - url: "https://ethernaut.openzeppelin.com/", - image: EthernautImage, - alt: t( - "page-developers-learning-tools:page-learning-tools-ethernauts-logo-alt" - ), - background: "#4f62dc", - subjects: ["Solidity"], - }, - { - name: "Capture The Ether", - description: t( - "page-developers-learning-tools:page-learning-tools-capture-the-ether-description" - ), - url: "https://capturetheether.com/", - image: CaptureTheEtherImage, - alt: t( - "page-developers-learning-tools:page-learning-tools-capture-the-ether-logo-alt" - ), - background: "#1b9aaa", - subjects: ["Solidity"], - }, - { - name: "Node Guardians", - description: t( - "page-developers-learning-tools:page-learning-tools-node-guardians-description" - ), - url: "https://nodeguardians.io/", - image: NodeGuardiansImage, - alt: t( - "page-developers-learning-tools:page-learning-tools-node-guardians-logo-alt" - ), - background: "#000", - subjects: ["Solidity", "web3"], - }, - ] - - const bootcamps: Array = [ - { - name: "ConsenSys Academy", - description: t( - "page-developers-learning-tools:page-learning-tools-consensys-academy-description" - ), - url: "https://consensys.net/academy/bootcamp/", - image: ConsensysImage, - alt: t( - "page-developers-learning-tools:page-learning-tools-consensys-academy-logo-alt" - ), - background: "#f6f7f9", - subjects: ["Solidity", "web3"], - priceType: t( - "page-developers-learning-tools:page-learning-tools-price-paid" - ), - }, - { - name: "BloomTech", - description: t( - "page-developers-learning-tools:page-learning-tools-bloomtech-description" - ), - url: "https://www.bloomtech.com/courses/web3", - image: BloomTechImage, - alt: t( - "page-developers-learning-tools:page-learning-tools-bloomtech-logo-alt" - ), - background: "#ffffff", - subjects: ["Solidity", "web3"], - priceType: t( - "page-developers-learning-tools:page-learning-tools-price-paid" - ), - }, - { - name: "Questbook", - description: t( - "page-developers-learning-tools:page-learning-tools-questbook-description" - ), - url: "https://learn.questbook.xyz/", - image: QuestbookImage, - alt: t( - "page-developers-learning-tools:page-learning-tools-questbook-logo-alt" - ), - background: "#141236", - subjects: ["Solidity", "web3"], - priceType: t( - "page-developers-learning-tools:page-learning-tools-price-free" - ), - }, - { - name: "Metaschool", - description: t( - "page-developers-learning-tools:page-learning-tools-metaschool-description" - ), - url: "https://metaschool.so", - image: MetaschoolImage, - alt: t( - "page-developers-learning-tools:page-learning-tools-metaschool-logo-alt" - ), - background: "#f6f7f9", - subjects: ["Solidity", "web3"], - priceType: t( - "page-developers-learning-tools:page-learning-tools-price-free" - ), - }, - { - name: "Speed Run Ethereum", - description: t( - "page-developers-learning-tools:page-learning-tools-speed-run-ethereum-description" - ), - url: "https://speedrunethereum.com/", - image: SpeedRunEthereumImage, - alt: t( - "page-developers-learning-tools:page-learning-tools-speed-run-ethereum-logo-alt" - ), - background: "#ffffff", - subjects: ["Solidity", "web3"], - priceType: t( - "page-developers-learning-tools:page-learning-tools-price-free" - ), - }, - { - name: "Alchemy University", - description: t( - "page-developers-learning-tools:page-learning-tools-alchemy-university-description" - ), - url: "https://university.alchemy.com/", - image: AlchemyUniversityImage, - alt: t( - "page-developers-learning-tools:page-learning-tools-alchemy-university-logo-alt" - ), - background: "#ffffff", - subjects: ["Solidity", "web3"], - priceType: t( - "page-developers-learning-tools:page-learning-tools-price-free" - ), - }, - { - name: "LearnWeb3", - description: t( - "page-developers-learning-tools:page-learning-tools-learnweb3-description" - ), - url: "https://www.learnweb3.io/", - image: LearnWeb3Image, - alt: t( - "page-developers-learning-tools:page-learning-tools-learnweb3-logo-alt" - ), - background: "#ffffff", - subjects: ["Solidity", "web3"], - priceType: t( - "page-developers-learning-tools:page-learning-tools-price-free" - ), - }, - { - name: "Cyfrin Updraft", - description: t( - "page-developers-learning-tools:page-learning-tools-cyfrin-updraft-description" - ), - url: "https://updraft.cyfrin.io/", - image: CyfrinUpdraftImage, - alt: t( - "page-developers-learning-tools:page-learning-tools-cyfrin-updraft-logo-alt" - ), - background: "#000000", - subjects: ["Solidity", "web3"], - priceType: t( - "page-developers-learning-tools:page-learning-tools-price-free" - ), - }, - ] - - return ( - - -
-
-

- -

- - - -
-
- - - - -

- -

- - - - - -
- - - - -

- -

- -
- - - - -

- -

- -
- - -
- - - -
-
-
- - - - -
-
- ) -} - -export default LearningToolsPage diff --git a/app/[locale]/developers/learning-tools/page-jsonld.tsx b/app/[locale]/developers/learning-tools/page-jsonld.tsx deleted file mode 100644 index 2a345f62c05..00000000000 --- a/app/[locale]/developers/learning-tools/page-jsonld.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import { getTranslations } from "next-intl/server" - -import { FileContributor } from "@/lib/types" - -import PageJsonLD from "@/components/PageJsonLD" - -import { - ethereumCommunityOrganization, - ethereumFoundationOrganization, -} from "@/lib/utils/jsonld" -import { normalizeUrlForJsonLd } from "@/lib/utils/url" - -export default async function LearningToolsJsonLD({ - locale, - contributors, -}: { - locale: string - contributors: FileContributor[] -}) { - const t = await getTranslations({ - namespace: "page-developers-learning-tools", - }) - - const url = normalizeUrlForJsonLd(locale, `/developers/learning-tools/`) - - const contributorList = contributors.map((contributor) => ({ - "@type": "Person", - name: contributor.login, - url: contributor.html_url, - })) - - const jsonLd = { - "@context": "https://schema.org", - "@graph": [ - { - "@type": "WebPage", - "@id": url, - name: t("page-learning-tools-meta-title"), - description: t("page-learning-tools-meta-desc"), - url: url, - inLanguage: locale, - contributor: contributorList, - author: [ethereumCommunityOrganization], - isPartOf: { - "@type": "WebSite", - "@id": "https://ethereum.org/#website", - name: "ethereum.org", - url: "https://ethereum.org", - }, - breadcrumb: { - "@type": "BreadcrumbList", - itemListElement: [ - { - "@type": "ListItem", - position: 1, - name: "Home", - item: normalizeUrlForJsonLd(locale, "/"), - }, - { - "@type": "ListItem", - position: 2, - name: "Developers", - item: normalizeUrlForJsonLd(locale, "/developers/"), - }, - { - "@type": "ListItem", - position: 3, - name: t("page-learning-tools-meta-title"), - item: url, - }, - ], - }, - publisher: ethereumFoundationOrganization, - reviewedBy: ethereumFoundationOrganization, - }, - ], - } - - return -} diff --git a/app/[locale]/developers/learning-tools/page.tsx b/app/[locale]/developers/learning-tools/page.tsx deleted file mode 100644 index 49c6e6a2059..00000000000 --- a/app/[locale]/developers/learning-tools/page.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import { pick } from "lodash" -import { - getMessages, - getTranslations, - setRequestLocale, -} from "next-intl/server" - -import type { CommitHistory, Lang, PageParams } from "@/lib/types" - -import I18nProvider from "@/components/I18nProvider" - -import { getAppPageContributorInfo } from "@/lib/utils/contributors" -import { getMetadata } from "@/lib/utils/metadata" -import { getRequiredNamespacesForPage } from "@/lib/utils/translations" - -import LearningTools from "./_components/learning-tools" -import LearningToolsJsonLD from "./page-jsonld" - -const Page = async ({ params }: { params: PageParams }) => { - const { locale } = params - - setRequestLocale(locale) - - // Get i18n messages - const allMessages = await getMessages({ locale }) - const requiredNamespaces = getRequiredNamespacesForPage( - "/developers/learning-tools" - ) - const messages = pick(allMessages, requiredNamespaces) - - const commitHistoryCache: CommitHistory = {} - const { contributors } = await getAppPageContributorInfo( - "developers/learning-tools", - locale as Lang, - commitHistoryCache - ) - - return ( - <> - - - - - - - ) -} - -export async function generateMetadata({ - params, -}: { - params: { locale: string } -}) { - const { locale } = params - - const t = await getTranslations({ - locale, - namespace: "page-developers-learning-tools", - }) - - return await getMetadata({ - locale, - slug: ["developers", "learning-tools"], - title: t("page-learning-tools-meta-title"), - description: t("page-learning-tools-meta-desc"), - }) -} - -export default Page diff --git a/app/[locale]/developers/local-environment/_components/local-environment.tsx b/app/[locale]/developers/local-environment/_components/local-environment.tsx deleted file mode 100644 index beb970aa98a..00000000000 --- a/app/[locale]/developers/local-environment/_components/local-environment.tsx +++ /dev/null @@ -1,120 +0,0 @@ -"use client" - -import { HTMLAttributes } from "react" - -import { ChildOnlyProp } from "@/lib/types" -import { Framework } from "@/lib/interfaces" - -import FeedbackCard from "@/components/FeedbackCard" -import { Image } from "@/components/Image" -import MainArticle from "@/components/MainArticle" -import ProductCard from "@/components/ProductCard" -import Translation from "@/components/Translation" -import { Flex, VStack } from "@/components/ui/flex" -import { ListItem, UnorderedList } from "@/components/ui/list" - -import { cn } from "@/lib/utils/cn" - -import { useTranslation } from "@/hooks/useTranslation" -import EthBlocksImage from "@/public/images/developers-eth-blocks.png" - -const Content = ({ children }: ChildOnlyProp) => { - return {children} -} - -const Column = ({ children }: ChildOnlyProp) => { - return ( -
- {children} -
- ) -} - -const Text = ({ className, ...props }: HTMLAttributes) => ( -

-) - -type Props = { - frameworksList: Framework[] -} - -const LocalEnvironmentPage = ({ frameworksList }: Props) => { - const { t } = useTranslation("page-developers-local-environment") - - return ( - -

-

- -

- - -
- -
-
- - - -

- -

- - - - - - - - - - - - - - - - - - - - - - - -
- - {t("page-developers-index:alt-eth-blocks")} - -
-
- {frameworksList.map((framework, idx) => ( - - {t(framework.description)} - - ))} -
-
- - - - - ) -} - -export default LocalEnvironmentPage diff --git a/app/[locale]/developers/local-environment/page-jsonld.tsx b/app/[locale]/developers/local-environment/page-jsonld.tsx deleted file mode 100644 index 3728c0a78d7..00000000000 --- a/app/[locale]/developers/local-environment/page-jsonld.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import { getTranslations } from "next-intl/server" - -import { FileContributor } from "@/lib/types" -import { Framework } from "@/lib/interfaces" - -import PageJsonLD from "@/components/PageJsonLD" - -import { - ethereumCommunityOrganization, - ethereumFoundationOrganization, -} from "@/lib/utils/jsonld" -import { normalizeUrlForJsonLd } from "@/lib/utils/url" - -export default async function LocalEnvironmentJsonLD({ - locale, - frameworksListData, - contributors, -}: { - locale: string - frameworksListData: Framework[] - contributors: FileContributor[] -}) { - const t = await getTranslations({ - namespace: "page-developers-local-environment", - }) - - const url = normalizeUrlForJsonLd(locale, `/developers/local-environment/`) - - const contributorList = contributors.map((contributor) => ({ - "@type": "Person", - name: contributor.login, - url: contributor.html_url, - })) - - const jsonLd = { - "@context": "https://schema.org", - "@graph": [ - { - "@type": "WebPage", - "@id": url, - name: t("page-local-environment-setup-meta-title"), - description: t("page-local-environment-setup-meta-desc"), - url: url, - inLanguage: locale, - contributor: contributorList, - author: [ethereumCommunityOrganization], - isPartOf: { - "@type": "WebSite", - "@id": "https://ethereum.org/#website", - name: "ethereum.org", - url: "https://ethereum.org", - }, - breadcrumb: { - "@type": "BreadcrumbList", - itemListElement: [ - { - "@type": "ListItem", - position: 1, - name: "Home", - item: normalizeUrlForJsonLd(locale, "/"), - }, - { - "@type": "ListItem", - position: 2, - name: "Developers", - item: normalizeUrlForJsonLd(locale, "/developers/"), - }, - { - "@type": "ListItem", - position: 3, - name: t("page-local-environment-setup-meta-title"), - item: url, - }, - ], - }, - publisher: ethereumFoundationOrganization, - reviewedBy: ethereumFoundationOrganization, - mainEntity: { "@id": `${url}#local-environment` }, - }, - { - "@type": "ItemList", - "@id": `${url}#local-environment`, - name: "Ethereum Development Frameworks", - description: - "Tools and frameworks for setting up local Ethereum development environments", - url: url, - numberOfItems: frameworksListData.length, - itemListElement: frameworksListData.map((framework, index) => ({ - "@type": "SoftwareApplication", - position: index + 1, - name: framework.name, - description: framework.description, - url: framework.url, - applicationCategory: "DeveloperApplication", - operatingSystem: ["Windows", "macOS", "Linux"], - author: [ - { - "@type": "Organization", - name: framework.githubUrl || "Community", - }, - ], - downloadUrl: framework.url, - sameAs: framework.githubUrl, - })), - publisher: ethereumFoundationOrganization, - reviewedBy: ethereumFoundationOrganization, - }, - ], - } - - return -} diff --git a/app/[locale]/developers/local-environment/page.tsx b/app/[locale]/developers/local-environment/page.tsx deleted file mode 100644 index 5633ffed495..00000000000 --- a/app/[locale]/developers/local-environment/page.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { pick } from "lodash" -import { - getMessages, - getTranslations, - setRequestLocale, -} from "next-intl/server" - -import type { CommitHistory, Lang, PageParams } from "@/lib/types" -import type { Framework } from "@/lib/interfaces" - -import I18nProvider from "@/components/I18nProvider" - -import { getAppPageContributorInfo } from "@/lib/utils/contributors" -import { getMetadata } from "@/lib/utils/metadata" -import { getRequiredNamespacesForPage } from "@/lib/utils/translations" - -import { frameworksList } from "@/data/frameworks" - -import LocalEnvironmentPage from "./_components/local-environment" -import LocalEnvironmentJsonLD from "./page-jsonld" - -import { getGithubRepoData } from "@/lib/data" - -const Page = async ({ params }: { params: PageParams }) => { - const { locale } = params - - setRequestLocale(locale) - - // Fetch GitHub repo data using the new data-layer function (already cached) - const githubRepoData = await getGithubRepoData() - - // Handle null case - throw error if required data is missing - if (!githubRepoData) { - throw new Error("Failed to fetch GitHub repo data") - } - - // Merge static framework data with GitHub repo data - const frameworksListData: Framework[] = frameworksList.map((framework) => { - const repoData = githubRepoData[framework.githubUrl] - return { - ...framework, - starCount: repoData?.starCount, - languages: repoData?.languages?.slice(0, 2), // Limit to first 2 languages - } - }) - - // Get i18n messages - const allMessages = await getMessages({ locale }) - const requiredNamespaces = getRequiredNamespacesForPage( - "/developers/local-environment" - ) - const messages = pick(allMessages, requiredNamespaces) - - const commitHistoryCache: CommitHistory = {} - const { contributors } = await getAppPageContributorInfo( - "developers/local-environment", - locale as Lang, - commitHistoryCache - ) - - return ( - <> - - - - - - - ) -} - -export async function generateMetadata({ - params, -}: { - params: { locale: string } -}) { - const { locale } = params - - const t = await getTranslations({ - locale, - namespace: "page-developers-local-environment", - }) - - return await getMetadata({ - locale, - slug: ["developers", "local-environment"], - title: t("page-local-environment-setup-meta-title"), - description: t("page-local-environment-setup-meta-desc"), - }) -} - -export default Page diff --git a/public/images/dev-tools/alchemyuniversity.png b/public/images/dev-tools/alchemyuniversity.png deleted file mode 100644 index f48fd08b80ff3a6662239e0267b15611787d06fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19091 zcmXtTA3QZC+m0O!I}gmQ?{GL=3WLj{FiB(@o57|~Idlg1K-g?9lf@(9S&s%L!Fr*E_LtW{t*bY z)p^#&3cF*2&Dhx4T^QM0?Oz&a)L@z08>F>q!uG<<`rImGeqeKDo4&HVv%FZmK%1MJ zTbUbQ*dSNU;nA~;?X$SHB{CXEnP0<=((t6#F+M)Nk;U!J{>{Z7^t|soJ?(_sDU2c% zBQBeIsg!f?o{6`&4+_;~@st9oWk>gOzJD(U0)g@IZx5Af$R8*!?03&DfQLs^{C_tu z&*z*|JUnN3Om5$_4$T?N6^2OnllFz|-aIT@GXLrwkLJcQeiT^_nCU`eK7z)NNX&+n%5NepnS4KYs|OSq2SNe z+@UKEE(LxMI1qtL2h*QEdG?YTiZis#ws7oQ{o(k)?S9{_rC=~;qPnM1hhy=g+P>Cd zE8LARr3EYrwQhX$=rA~eo(u%@-MP8)k()s0`h&L~;-p2R)m zy$oA~D6nMu?OCR5#jl9Fs)UDz_wiK}==b#AB_6U+%toNw)lAU-ar2v+{pLcoI-jr1LBjH{n%=fgBbq#C@3Whv#$EutdEXYe+* z4az@Woh)Iys`SjblkARkLTUJj-E-A01aSr_6^9e!?mvU-ej+Qz2#1MbA;sl^MOqWm zW(P`i;VqH>L<7d||5}t3k&FDwji|=kr949DxPWSTI03b?7a>ig-D7iJ^SVx~(VgJ9 zz#zPD9c$fz5@@HVh#>Gd%TSiqHiRwSef0fQUliZFZkt3aO~ z(_%6<0)JcLAMrw_%s!P^P`_(Q!|VUMG!_y>(Az*=gc$?53qz$bkP_7!m>^MPu_*IN zZA649<``L7nfzAz_mEXi91SN0D#4KC=E;J4+~0^6gvxT!OMgXLc~L}qZ>ahysxTb- z`=!Q?ZOK@1EacpV>J9Li=a0zw6%Kq=W(Qliy`@GMr)P9`b>a0LQ;!Do_+;=JklMrkUzQgh&jeN z+EKpjx}@s&tzbF#r)~E97I-T?G79kH8WtJLRFm(_y>`FRTseKH1x-eZNgr zQh!WR9hGhvc_klYMGpXk+(J2&Pc$xKN|`= z;4WGzE#{4F8%FD7)MP+7AGeF%CD6>nrA1eP-D8XD z3bc-T0w6^48dfUOCI^6o1O!}nkUFyyiLghWTh*Hv>WkarJlrVCDCf_6pM3o$BuQv{ zI&gFUZu7|cg2A7WxrO;_aScfatF$Ch2`satczNZc&WFjp2s;^JhUrBZH>R$`<2IKf zakr)ll2ng`N26!Z7;}=(he)3WTbI?u9k11Ms2Gvor;@g~@SR!Re1Wv_+4NYx8{nFs(=iWs(`=Hm}XrOWaH&4o%^+&RYIW}Hip}~z^gkruoULB>? z)l0+~;*9_KQOTWx)$85(5{wo%IXCgYCLzcO#C@kWVoZ#AUk`~^T@lq9i;ed2d-Ud2 zMcf{Drv|?TDkyOKJZHZXJXk^-RQKc{#clE8AVEe^=l)MRGDCV`YY*=GTd;y6(`RPEupGBWR|Gp&Etg?N<(PEv43F)#N_s_feL)pBRLmf%?qP z`&QSSGH6bu)c#9J;ON_-_Sr0@>c*{ZhEw@u2Y@3<{!{5+@d{n1si~5wdRVUtrS0qp ztc}>&?+a`=PmtWB*GE=-jKiAO7Fb7k329o_k+L&@bz+=w&%oZ31{(*aWB0VY@GrcU zU8{ATC86>hq%SR3o#Km5v472ur*}lA)SiJ4yYIgDEcs2juwB8*Wzw#@Oo`Hth7NUy zhCOY%+|AEP+{$S7j9n^UBa!H?aIqbq(ND`EqOKNA=tg*k{QXMqj;3MlJTkWE6>|kue?F6c&5^(R!7r!(*t{BX~B3Wf}tsK`+ zgvvc(7_?$?A+O9qb7jOx)LNZ!SB;KG{rqKLD zBF1%fXWE}`{S8OA{o`H7wY9`&>3=C7DCaXwKs5i^ZNkvO4T5J_$;qptk%%Ou%cNAf zYKo*}8w@(*tWLm@x?KIs9$&og)faMH9H+d+eM;_VvAKuoNcD@`qf5XmN4zzmfaINz z(r0>s^C^VBZHuEHMdH^I!`|x~Oh@jy>U$ed1pT(9P`12&IjcuU^-X|%#&!^I)f(lU z!sZQ%Wj5z~SUysD=)zb^H01teRy!~Yp7u2082CH+QsWJJqyRFxCmPxol=2`LDs1q! zwdZM8C*nVy{q+;e)chXeq2a6&S|>=Xb4}5Lj0j^1l8{4kud=>@zGke5zkKplM5>0--q@=|pXeT1`M;pa@n+H#{Ve%vqlwVHQw-yr$wY2hnV2 zSMD}F%u|H!BezH*aGH)G9Kt}50S8H@tfj%C)v+a8o8H-%W0x2~Q7FSJ3i*&|n)no4 zXT%que32tefe&D-%9DFyFh4N*x;p?U{sYco3=~dX6-~nB5)@hZ)CK4QrT2 zpx8}@@Z6SrS^G0?gOD2|aheN0RNYGn)Vq{vI=1t}TIsy76sXO(ky*R0mu{4u-B(_i z?P$93RC_h}Vhti>YuWrL_rr{%pAffz8v35tgtVRU&So8T$yLVP}g;$X0S6@njzamYyxc-y2bc;6->+XUvufH!o zch2lMndzk#0K*7*uSU6ycSyMs>!!`1Vg{M`5O3(Y-7 zZGdX%F3%4jC-v6#;qEIu)SE}wb<@Jrv>2*)_j6R+^DnrS>&#rbU?mn}YI4bBc&a^Y zc;z{rg9L>A!e^782N!rLExsctW7TTF!>Bpk4Q$37f&}|ciBW33a%KkiJxg_r=k=q- zKrbvI!!#V`mddrZEDq^wrD_ezoP&uG(T7<(SymOYwhO2TsxN7N zZEb{UF=AL*bn9dkx<+s&Y>RU|T%9dq`1f#B!W~cjyTx+tS%O*XB*&m0!!Kum0J(v_ zs$9@hechhtJ!75&W0Ngzm|vJ{pM%6go6_flH9?6qA5PvkT3 z1&9x>gkBR?)NQ*0Rf=MOyI)-tfA)j9y+n0UC0V=Z=v39`LtI#H);wdjQg2Y3`gad+ zGX*5~>bAcJ$$0?FG@2Tln?2{})M$+(Dni;P+@EI*hGZLOhejEG6c24$Et$|H6nXNr&OP;AMaCLdmC_P#J~jf#Y2%8UXS2~uQOLC8|_^X zPs8nNsh#XyYaxA&Dz5Js!F@*~@RARM@6jufR+$pW^Kq1v2Zjmzyw9+38uc1{zO`FsLKiscH*-(XjENuK z=0n`>Y`%5<29<9qD>(m_7EeT)&ufc&&}=)##XrWERIU*J=r=v?(OTBJ6NzHguA}3_ zEN5(o#!l>OaIAlWM4L-_+5rr^*j+(uQ9{A-x}#Use)NKVQ!Jva+W0kY%7^KnA9#($ z{kNmd5k$N{9QZSuD@yLT9g}^hP|ratO0~Pg$lm!4Zr*D~aTYU|a}%P}Iw!co(Z8B_ z>hC7<$!u_@QG^}Lln`J;cmAnTC>Xe$^{_|1}wEX2RRZu=PxBI{6ljYRAm?2`=CJCDQmPG6w*PPwZ@ z`+31Q{k;9D&b`Z6dYs&AM2J-t>ba`E`m}gti$D@90i`CB_xj$$lw*c@zhFm!mvzrlfyLVqEo z1=56X2%@f-osaZ9h^3b!<4~=OLFro)Ml8wotz!MIfdz>>%phX!^U5$OZL~L*-tz(| zKsF&qBMsf>cu(_es9dEzy>_O&bv9vGC$uG0Y$}4~G@kx9|Lf%Ro+6qffXVXoF1E8) z8synXXF#`Cu8W1)LnjT--nZ1B7NaQ(nNIK&$)6YMoGE&@$T}`JTCu$D{6|D#xM~yp zH^i|d`!TU(x!j)aMGku~*}v<+u@KR*I+l7=$Gz2kGLCj(QHY%p)gX_`EQCi04WBWO zy&H{tg}Fd1tiN;N!M9KI%cg3{Wnb}2Tyb)Y%_MMQa1VA0LF(>e4%%#uYUNGOaB=hB z{qwAbLy~uAJ~LMyz5atJ=Bej>ZLrJRhPqwDzZ4)jsU>>{mE=0=-A51Vp_UI*?VZ3( zr8e_!U_2!GyZd5MXu2cB6IfCkB^#^U`re)V7UU*xj?Y@^2>&7S&Ao8hJiPALa~{y8 zlE9b&CyOl9)tUEd%iuRi zMeNO|X4lg!APVXqELuGYW_fgQNUbHdVPgYp!wC25U;StmkOd=}`HJV2J8{Y5!v0a(SQYt-*MIsFm>tSW9r%|y#piJYM^I)O zt>I_+%BPA-T0;@K0xzZ|Nny&7O>2h`{t_^aL`8o>E`=RWqJn>X{=%-$NjBca;%0?| zNt)Ga=H2@Ds|{rXqysbQM>lKh-GbR;WAQ)41A34x_etfWZ%qHOgj@ch0_4%GfR*+T)kY%9FY;@IU|dH4Ak z@^otfnikJpp3`tSs*@iDOQY`&TijvoEGG<@&yFa3 z!K_H$P^5fpGVeoLfJ*ps=&wx>Xt;Tus!1LXN_J9d%P^||nd`-z*E?4nHt>RI+O2QD zgzkoB`D_GFIvDbDLNm-RbAcUP0Y=S93Oi1y?ax`nVPuWV)sr{Ge~kW1&l@I5vqAan z%Z#>Q?=Li2R%^Juv2o)-UK(k@VoUqhLJM#=0MvRq|c zr3C7}HZ6DI2$qUdQ#5zRa!Xo})%*c#&b+29r3qnHV;bBmq_)c$Ut!xV4~z64>LvWwMBlxAMH^Nx z_ax)zM36rK+NN*C`a;j=voDp{e|AN^cQ29?72#O3`27;&dO(|W5f3fx8yo&Bf# zu&BT3w`jdIVFI=6fYKW9YBIjVvU`%Ml*B2#O9gc64;!S&61yLdHpbYoY&bmwEnznn z5W~7t2HH~whov3kca?@cxz;9A!MA{eoec*AjxCk6UH_?y0Up z7%`u`MWxxJRuw<*k3Ph)+kpU;Mxi1h)BWQcr&h&b&r{=0FrrcAE68A=>TdDp;=v!h zpJvaMs(b-c>r9UzyUHa>xXG&l6sQ`_eU}IM1#ZcarvWtqCd^;lm>8=t+V+*mQNvf0 z;59G>G{zj8k)++pTRdkqv;Dbrn%u8~CDm2|#VSIXoiv%&*?H4z9Nq{3<+Z*7t0s!| zDsG_y#5@(-KDocx3nJ%T-M(gK?-4&QjWU0FKaQ0UBp1uYk5HKo92EmkPTThJOl}1s z4u1_GCSXW(udFRQM+4>E*(PnAr4)oi;2mBwPFbEc-5ocJ0`jEDg@kdzIIijy*?q2V z-lH9AXiPpv9MsP}MN0*w0>krbld0e0kB(9zNmke2h zt|B-0)Dc_yRlnlRg!wNYC&iQ8N5M&JgGHbIktElJA_V`^GjG5Fio(;q;sU}NQeh5A3LMIq$mOY?bufeauIXuW_>3}75r)Cvs({*I$S-nYa<2tvYf zSErxqI_`|FZ@ze-{trx(g=w^1eRnCg>QU0L7X8g642fbS6WC8AA{H~Pc~bI!{~HV1 z7D{e=f_<w-UWE*Gj#5-L zc+w*32w`D@e;W9*B}Y$gG;}nKb3*-Ya(DlE<2}z!T1gx158dDzgReK;v9wjQy++>fGC~?=rN5N_ zlIr4ns23=*a(D>*5#ByyqjJv5aAUR~Be9Ay%a-l>=FxaD%G<0(Dyz^_2l3axRDTYX zzxM#q7b)`AP$~b)E1k7py85qD)pK7BIbA3)^^~Gwh0TV@uS?Cxf7z`>QW)&5oAjyZnk&Q}n`{Of4sJA$MwPV`NSnU?DK1Kwu)(#f6u@O`;N6zCLLp4Iz| zZxx$H($N2a6=hGl%Ax6F$52Njrow-YNLJN#0mlh<71q(|l3xtt;l=F0pndG-<|Sk& zn0Djtqszu?Jt9PR4rL5XPYnQ-3HsOnho}#KEBcmG3udZ0K37yRMx$lWNJ9hF9+M{0 z23=}M+!$l%(`nK~V>u>Z3!z9u7^CJ;J!lTU4Z>g`oe#-`NCcM^6~UXl$u`Wv9YY>$ zdr2&jjSaVsf164T8JTnZwo!0{^@!lUk3H;D%-f2GP|Fo3VNcMKZHg4=NXwAc_Gqzi zWkKExJ%9&zl+f*MK&LS$#(soQu$yM)WGvbioE`}X5nf01+M*y%N59f=6Jy_W!y6b0 zNE)&5>aF$9XatJ!ira;*d!SJ8lH5p4NakXP?EkX>H%}vC8n93*Rng2W-&Y~AZM z`2-*yxTt^OE9C27JrL#GGYdhLb#RW6I-ma%U6!PGu%%cE zmlUC7SQoMrcnXoaM6Ii5CqPOJKA8)u#Tt-I02uDlh-&70%g%#^Q#ua&siq{(sNfqj zK1aBaQeq2AB17^a5)3yp1a7RBw!%4|@)GU3hQ2D5a=GB5b9XHeeS!6=`_l3uSgUGh z2n2|YE3Z{MZukcN?*4fkNq2U|a3?ssIqs*+Rk>GYfubp2xq9DT{mTRy;OsYl8tS_?vMv}13VeD ze<7S*hxJN|`0Fe*wU@+pJ&nu51MeS*+)x51CRtreZfe(rnb!0L^401-4h5fwvu1c< zh3tBP#sNQ)bHX(f5aRvxqj8rt@IRC0PI61O0cQKSt* zrVf?m`RP4S_JV;Dutkcg@Q0CzYZr?)Bnd@jd4E6fGyFfd(BK10gS~8x2OtdItXu+f zXjl8~Byb3;Er-FBk0Kk`;fkOeEx<})132tF?H2GI;$0`CbA!-|@ik)mEP*sr=9|d89O^X-JnJx&RD3ROz3hr(#ZN|j~#SRs^Z(*u)D`e zj~PUC2|9gqQE^kr0tg*H(UW4hfRqeSMBV_sBx4JcyW*I*)nrr06v=~lipIXwF+`y- z$nwZK)YX}y*PU#3*a_$yMiLv^T*;>GKWVh;1VqBNfBB*d&eovd>;}ovqW4A9tI;T@ zt?GyYAnubWQ*9A)mDw6{KcB5-%$mC990|JqrQX)5H#MH>k-un_DtXgzBJm4klQ>Vj zO>7x!Va=sJ)P&u>k%O;-&1+Lx8{)1^@gg=eS9?J+F)rj>!)^B?Y+EId?B0LH9T9Nu zK8Le4*;sc117H0ksYqmwK%3}by&Af4|A1*R1oJE2w3X-E!48#B!%@DjlHn5g01Tg=8rp)^C_ z5#L#-*E#&Jb?8kSJN}+lo#^5mZI#UBQ$=Ndw~DMyhr4jsKENx1H--+N z0hG3JTn4T;a%O91ff3qV>qE!p`26H4VZ)YD=%Gsbzm_r&V0XZFCjcka8ursb&cQP~ z*1@u_Q90Y=gK1Y2(^uH&vUdE1OIDfbFLMfyAa7KX~l$_Y_yXW$V($sv5_)Z6cZ=ziXd-`P>im zb$I_#G4{ zgMC$1e->^Av?qkL3&Iw3T9K0v+RtRoUouB;3a?8J-Tkmij$9i&r>L%vRVZ~!E}gQ_ zF=sCUN-;Z2%1P>JYJ$qrBjn`;O>!Hesm0J4DbIm90x49`Hgda?0>PoXjc9f(?eyG2 z=#0~1R&HP0g74$iQhAXs1HX3?D%pjB> z6SOwN82Hy3w;J-;XlempJ+)lY>u%qRTeP9N?X1jt-7RUYD0{F7t?)Pjt;T({kOQlT zJ2%+#RM%-?5u@YIIuCC{x2S4(y4N%eQT?x8>QE#C(w;rvv5g?WbbnkxeZIhvngNr) zuc&%(QDES)^}G>g#XB##@n#84-tD-nXBy3Px^J32W8XP#4jmNI;t}H&K;(oC(Nu$P zAbMIc7))v?vD2LOpe2R!g&kAMAB|Q^rHRp7(p#nrtbnhgbS}toZs%i97CFsaNV1C{ zv)sv*Lib%2*oU@7Up#jR zpC%)aI;&MG05$bV!7Vzo;a?7JqqkXr@s}n37}OLufP_PICHRV-l&Zcbs;Z`H9Y713 z2Y>g4HZhor<Om;UZ&pLmQtQ#-UMz)H4eYGrtpmUk7~jgT`vnAMPnUBfT(S$w0b+R{2h>E6$i4u zC3VBUQ~o{i#Abk0-y8@FtUU_a9~waaJ)*49Q+S&AY0BI12M_%MQFQFpjllmdgaJBL z_awJ4)6RL0VfI-X@MuwPBZJx_aK7I`GuV&SaqtgR)Z>gpez!5BcBF2T1i8!Q{m9bgI z$AdVCg1MrDU89(@8!{AEreo56)vS*ZFnww+=Vuj79Eb{*gBtFrdSL{w6bD^WUEm2H z`CY{Gc?g=)wo+H**m~ru5mF1|w#6IqRn-^`y{y4ZmhA!33a;cKdn2xEBah9>v-(1+ z$T|z|n41M=v^&f+6cKj4;7W7+1%KKx@_MokS8=CtU42e)@yZ>|o!>H=pS0{uMb`E- z{+bizZLZk{3DdGNS7=%~FC9c^&~5K{>Vqdcc*eF{<9*$<#7FoxkOI-FRl|jtNG^HC zI!^ic^jK5C<59Et;|bJ^J*N^TW}_rtO(Rv)h_QfB=N`5jxKe$SH+6s#EBmEu84_Fb zn#4MQ!oZ2^bAOwt{Ap8S)z`Q*Rh-jGLo75o*zWWgh_Sv=F-;L}(&^mT# zX7Q5O*ehJ{02cibmQFfk&@}$N?l@jNz|?>wVM^0VB)L2a6{GpjWlNyS;lo<23grcr zVSEc_ey&hF^$xzu|NJvVL&;Rfek^D4V+Me7@zm72uZ@knS4Et447@fxzG^CPfe{X$ z!lJLfS_&={{v%^Zil(POHvz7GzJxK_zhMS=4MGM8Ftnr5KM-LxtaC@kc6Hefdwn5E zd)4?G%<+k{j1$Dx;2fImyNzCvYT*-z1aVzs(P!7P1ZPvjmESqKpo&EMdoyTTGi4~odh+MI&E-%&?+)|KS!E&m+94xD0I&$nyHaj ztO92&+5t-QA`;+X!A)GzQNW}eqctXZ$Ra?AH)*CYDcg1vW9e!o5%@u;r#JEKF!4@m z7MH$kQ16(6W{{gO)2XANkvP_+#MW&mf#L6l2W5kt_8Bx2V z=E!R;T)aH2hn1T03%Ide^3i08VZTFp(bBAR3>BQG43gTh(l6w%+!E4$0e| z>$0i6)*r@)LGUw^QZkOUta_tth$#|qd3m5>R#Erl-_r{P zEmuu6D+<2lPoU24Y0)lF{8?R5XD`xQ2}N(u6gR%r))rt{xvGvTlC5n74fN&VWjyH% zMJFoXamq))fBu=HUbP5eylP6j?!8!;N(?XPmRm8|U)k$+6sb&PLTk_-%R{HJ09PQG z+n*1(Bg0M~T8({|t!M)L1JXZ86i;xr847bDM8h!d&r@iY>M%HmM3Z0IB9HwEnf3kX z`*SJBZrH1^Fyh+_0rmxs^%LRI!HYVM-OM{|T?&zmYN{|lKyB!P!*}Xr$W8b+n;s9p zOz{1RD1m)`{A`g~x|^M=$OyuH`h>3FU&t9uD?22!zqmI6oI-gaJ{gV! zmjQu@!>b*8#YY6s!fuv($I-2ziFEFJ()qry=!Jjf;Vm8unX>Y3qgaQA@q*AD*!#9B#0hA6-V=e_+pF=<)OVw-8heiW)ZZ*i zbvi5!VJ5x&u?w2suuK=HZbbRglv6^`6(iiLI3x-+P zQV%H*V#Ukm=qaY!tD=V}BJxfbkalhc{W{ySu`spacia0`MHab3u;mY|5Y`SYxT-B$k!wbXM+o@i!CzCrf^I-xP_N9uB4&?ob&xd+I@o@!u_#`pPq`BHD4Rcwz- zLpu!YS|2H$P}6`|BekqD1RC`rKX{q8pHi|CV1cZsbR(wqz#CI*-nh7;xVH^#;RROb zA6w#3czN@J^W)kT-!Ge$LLubW&^*)||! zcFy%IZv9ReU5jVp#%=ARF0O+EgT|=ik(8QW|KlX{JpB{kGBa5P#$09gUiSKyPL^)W zf7%9Zeyz>wS^cYfCM{{InOCnTuPNX}>9^o2sdRc}$(auL`{P=uhMJQIbo5t4&9T2K zMN*i6D`mcc^_5*SkUPIj#C3dzNyzoApia6v>%(4e(1*?WbCoMPH@nM*Bb!j8IP~@ZWGP`<=~^cnz`q5A%pi;9R2N-?-w>zkeOyeg;vVi=Q=RBz zQ~HL@Kg%>BNLW64)$hS0v7XqIxV_g1u|H_>;9HREsewnI(E%6cek~CpS#8KFXc@!> z(-R$ogBOX}RcESe$r4!fU_GyUp z@6+oIkDe~t7wkRq6P}gT3+Sv%0ThAtk^oV%U>Cn3ExYjs6EQ{nLs31N8bYO$0S7G> zlJ6V8l)r`!QzK$_+9*+fJNDZ!Z?bLZ8<&n=i-}zG{@J+}Y2`F;NAB>=6apH^71oc# z(5wU&%TkWz#zvoR6@~wX5LDHWiMis{udgd^|zUqV9n2#i$p}+ z7!`{AoA)hs;a}4m{GeNZ8vK&J;7vh^e&{GilwiZM2%u%G2S>t}vH~BJe z@lqYLRHNcptNa}yEPkR@_idYed&wg)Dn^)bo;)pAqk*})A)MP`hu~zfYRBf8k2wGMV0}pR1+548S#5woMXy74}TkK zxwN*8buO%HQ^;%q4i5O`ZkCIaUzRKnnDCvVJ}h`UESmfmOWmBY9pd-(FK zw`E6=Ew;yA@)MNp#7a;a>*N{}W?lGf=YoQ?dFRu13n*V$H;a8cH+s<<`P|Qo^@-fE zdO>9<>>Wc#6naNxDtlMr14@i?np~7M=mw2TxMq++q}=Nm2_R7wsZepP>6weeZ7n8}QN5#sje!OqL#;El0cwSD_8 zi(VvQX=hbR8|cbUmQ4L~ZC64>XcQyqR-Oh=NS)XvIbJ|>nRp~Tp7!q9Ri`VZY;yGc zar|vxt+pBs>FBVY=@~$Ck158jE_&|misVN1pL_J+UwfXmKSPJzj>=88yYQ{C1oF4c zlv)EgzcClaNZ!3{Gl&{|lp|M+C`W}9K>1KfO!iQ|(F|snth=n2W(eT}em`fVyks9V z!`2c2Ey4K6=lO+$^|wBKVYh}vOK80Ybn!Rz5^N+SBlu9Y_b$B@LMhX16Gk^5@m!0=t#l-Ih_Zi(5)JJ^+Pi};-A6cK?3ei2!@W}*yKzC_2m@*96bC(&b zFW1)2Ft8-?m+WTl`V;JsX9$LyQ!)Lu?z;g`K;?lbC^x6ZWNv z`8|uZECY;ilA?(ccWpfPznk=7&d~s4fw@x@NBJ`t{Gyu-P}d;fi^x6N*GQUSHfNLd zLV`VNzLRwT^1T=kKa|aKc=&u0trVVztpuu4^0^DH5sqy<$B2-M6#=gDYL+X~@!RIv zvy*L!U!ZvYs3L$YR-Ygz5*8l`jcBYDV||0a2$nJ|%+%O$-+uW1Fl>HP9S)wgYqVdV z`<@b_Pg!!wGhaXTR7d_wabby84gdI~%k0e2LP=|*MT2=?Ne7hs8^f9KruZn-lcBof zj9;)nT&yJ*LU`_Lvj0QWA?{4|1dWDx zo!Y*w@XPgk>`LNPZ)_E)Y*~8o&kS&HLN?fTWkV_d-vP_?X5Qm^L=kI!zkNoM<7{y6 zWFX6r&Yf}QoPyvOP}GbP)on-wOD zng%5+xs38hItz-@lz%ZYmi(r=3T7v?c&fl04Nj^o1gHNmBuVI#Uh9mQR{bF)|NS3w zgf5D0art$WF6Mqn^~GhAop%pSonHiT`Ps*f8R3Ez*)1=Y#u#kG(FlDLRLoBm8fzT*w;n%8iU*6(FH&O1>iIii$zUgFM zd#qv2;K zf7oG2j(Y~5Tr_z0&@*kYQm@tM(9BGJlScBL=7HmS9^ z(81k@=Y_=YA$)!ZH%0INy`sgml}(YO!F$@->Vrh6Z*-wQ9oc>W;Sd1Vvin&3KyGSY_r)_ z0^I2rN7yN**F~L&Tg_W409;nn|FZ7PFH|-yL7o-~H9ay#<=x zuil$5y}5AlEgh1isvvm=o!a)yPrq$5ts0BP%FA_>uK6YAYi&d`K(6uxZxf154En+5pD4XtkTBhmb5?L zRk~48wDX-8a=NFfl9G%k`MbjhbUNrA2-*>hJBrvFQnT8%q}8X$+A1GGTv{_BOC>@R z!Y+qpJ^Q$$Hx%?+?-)KUpu#AdWGS#1#rGU>k5A-|Agq*phMsPi4=_ zTodIC7AkAOzziGK<%9Fo6__^SEj&ErbJY?`l*umqHoYenN=Yf?Dn>c!{Z-Z z*7E0R>|RxBY|dazY0TOsO_N2~RnG};5{*`8a;4or#x{x6?XmXTC}61 z`z_26aWGsC^|b-0D7UybG9EOvnw_N3bI$&Tn*jQ@%c$zO{#w*9r=^kw4Fwgo7Q z#5l2K%eNt&)dl78}}G4ZE1V9SIQG{?SK~|*}Hk$jLcZX={pZ&V-0dDnISC8;R3gn z*U+yP6xjmy{kTrRwpJF~d?%fJl$$heCc02lb7{n6>E;Aio-RI%+YjGuiU<|EB+W^Y$p zXW*eiUtEV8+Z!?*r+pH?c+O>W-4A%kbk;L$$EP3WH-D9Wl-<#`-$a7xujS zF`=jP_TIr5y$fT;wUqr+A zq;KhOU*1r-(=qt9?Fjso?*!Tpj~mKxp7IOy%{KWN@i_E_KmY&}I#6_0Q_3sE6g>HSB|s(=H{l8|}H{ zM>KtdzYAqQknxbyC{DaSd)~Z|~A(m96%-Z!Wj3`qvwmI=`cp zuhy%~|C00*-j~F7wlXu!-Z^|u`AnZjwM>>F>}Ywm!$)1wVTT_eek#`=efGdFVUD!B z!rzL2*la@kL(#sLeu!Vu*TQG|#M_h`j_#Sh(R=4oMVgDvrV8`{U+~i;o^+DI%x9Pd zpNmay&QN~X+w$p?>xUUO2{(=D8{5GtZ$|v*t^&@Ozp4P<43qFH`2)W2XZVzD@U$<+ z!}NJe!&&sviB&~?rM{1kjhlv)OEsqAcXP9&&2TD-8C8*DJ>L$kyfV6y(br1lcvL^v zW6!6I?Vp^Ov&}z#_^9YB@nbhY<2+2>T0d*Q(F6=m_0(r;zx)z?olSnBG~LJ6<)!l- zmt_#?ucn(^S}&I!Y$k5WkQr8a)p>%RZsN2bMEhPh*WxGmIN{TnkML*dO9im@&Hmru zZ=9dgolg6l=_KuUv$XH~en{WCJC!}|*iwA&oM-#6xoBG2#r5@d#67l?n<4#FKR0Xk ztSe?bH?=v#o3u~=iy0l=l=KDt3E-d16u-$Q@J_s*^Shvj0)7kMqW_;hK^bvEa90N7Hl2}e9*j8VquWbj#GoIIToSyc%(bdWQprac|pW*Lo{DJtj z@f+vYJub(e#ZTKw>F6%)r%NtHiInT@R zlVA?ptMs$-3_+Vq@urG+1U{du%EjV0@J)})iC@}X#s9#eC)c;R2CuvI3%xBndanDo zLZ4=?5q)wY$}*rdTdOjQBt!TaIi7%i`ku{ZNwwe7vmB9zV=g5 zk8Fo*;UD-hr=%K?=h4Gk{&Yg#GhRE7*1k7sMDm%AzUgGO8h&c?GL_c{cy4jMJvh_! z1L>EI^SFKRvq#mV*R`K>+Mj9rPWsu_L)v%F@2MZ?51jN(o=v6Ml-w(8(l76Q3oGItG^jmzvbq>h*CFG$r59c_8fnCwQ!e4%q_9^7qPDh;E zeV1M!`t?gc+~M4^$}a~~IMdoMdGNgv_5VQM!#^|PJekGcM4ca%_c-@4!z>4_16cln zPI1;vq9G-H>-&D{_66BBOcG3>{dM~39Ggup z`@SEbcRk*e_yzv~oQL;hXZcH$YdX3zmr(a~&C*>Paq8SYy=BwizCkA6OkS|`kx{<% zrZB9pUiN(WzV_eX`z51&J*Yc#8t1F6?o9mJdNQ;h@Yl{S>Ze>YoaX?KCa&XV^H_Si zb)Dk$15UkuBJ&r?rf*_=p-*QfI&Us|knx#*H{`zXGkq$PU z`J|GZY2zscy0`RSpU0Usi||d_&uDkEV}8&24~RbxrXMs(_>JbV1pAy~OZRjO8OD=A z-?glmwQ%D;uV3~(pZDghRhouA$zD}}lRi~IX}0Z`gN33d?woO|z56Gt!g(IOW+fQe zdQJO5hu2RxfIp9OQE9R7fIo%$GL_Kp=!S#3D&)zCc`kpowD4$MI_(qp*(tVEz^P{t zmQ(bzbDT4zAFf)NseO}Z@GBsr$Cb%n9YsLCbKE#?43DYJHI1&F!5=J~)6!4(tb2U`7?a~r5tC5@nngA zhV@9)KeF(p!98vsHyVxOhK#GIHPcybZZK6K%(BgJp7rhZ%R%ToF1fHI&ciJ(IS;#i z(8rQ@#XppOIqf_t_VEk0pP_wE{C=V*+k7&_FAXm$V03VbLkRfXAIu+bkoE^WsMxK` zfV!3btfh114DHi0M4L6qUo+l2q&=^?bw2N7WIKEdZfEhqgMD@Hld;Qu;aZ%avkJ)_m-Fu!+c$FjKS zh*S5ovi!!M#-@@Cn3PqQu3TX0ziSa?-bg@96Q~FW?mu~C9)zu<=C)B=Wk7vQv zg`P=LepUOaDKOb{8q%4D#n+OYDe(vGu2}ye#Lvp7Lplh5qcK3FzhYB7!PI@{JA4$o zrzM}h*8b(X=liyQTW@*FU#%S}>1TvH*6HPwQom0>Nozl#pSeATU9p%-HKb>hyo^6R z#&{OSJ%_mX&>!~v;{p0v12KJX`gj=e_?y_jNMA+}C6|c-EMxW!45z5XTB9Y~{kl0M z9(#sgR5g%fP9RLwHk=ug*|HC}oT>eA8Yj;v30vKlvOPN4IXW9%6MJ$VKJSN4yJ`%E zgT_j|OWLn>u|HDPWcI@(L+Vz3fqtExM;cle^Q<vtRTym4GTBj`yx|HqG*R%qum1O5o7&d_mVm@-};bO(-oX!>5f>Ex8k c?#J=}1FnLB?F_1b9{>OV07*qoM6N<$f*F^&CjbBd diff --git a/public/images/dev-tools/atlas.png b/public/images/dev-tools/atlas.png deleted file mode 100644 index 7ab520169c1c1d9cb50feef9f99077d175654434..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43881 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 Hul@6Xu{l_A diff --git a/public/images/dev-tools/bloomtech.png b/public/images/dev-tools/bloomtech.png deleted file mode 100644 index 826c7990f26b1b8f42ccc301788cd2406e40e895..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5735 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 Z@jvt-NR%qbv|IoH002ovPDHLkV1kTH=KcTx diff --git a/public/images/dev-tools/capturetheether.png b/public/images/dev-tools/capturetheether.png deleted file mode 100644 index 4b2044a787ff5494efe82cfce78f804fc22edb35..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1455 zcmeAS@N?(olHy`uVBq!ia0vp^6(G#P1|%(0%q{^b#^NA%Cx&(BWL^T}FfdWk9dNvV1jxdlK~3=B3ERzPNMYDuC(MQ%=Bu~mhw5?F;5kPQ;nS5g2gDap1~ zitr6kaLzAERWQ{v(KAr8<5EyiuqjGOvkG!?gK7uzY?U%fN(!v>^~=l4^~#O)@{7{- z4J|D#^$m>ljf`}GDs+o0^GXscbn}XpA%?)raY-#sF3Kz@$;{7F0GXSZlwVq6tE2?7 z2o50bEXhnm*pycc^%l^B`XCv7Lp=k1xY#WAFU@$KA$g|`g^T-W+oT{n;{9xsa@@D0sw);oqm9O8OnD_WzGdcO+;2`EY=r?*Rkfg98ir-dMf* z6;b(iUR1c3Z2GVM!X*oy$nkwy@Tlp|_wAo^ZS9xl=YO}5e!s9%%_)_kDRh$7m79~= zLZ96F-I(&)BaZiArQOMMS$-cb&D;ItiTR}HtoTW$Zwfi&%w|~~;@HvGe|TPNLwoPC zJ_Dw8j~{PHSA3ATc%|~1r`CbpkP50n2R{1*xXDvp6E#Rc|cY8oKCa^II>Du>7`!*|)*+o(6P9>yofA9k4lX@^xcuH>;|@RjhVZxuftZ^YF8aA2=oR|u zzGdmIqf0q=w4Rn-zi>bM{Yw3{Q_pVCPr722daY8y;318X2mvHvm0t{ye7u6t&e4ODd)N^<7Rzhpq9{g`~Q@pm$A1r6?T@aG=_E$^7YmW_8#w_`*5xeaaLCW~N zKZJE|eJu>K;FST3b52#N6EsYnbM8sCJg}Lcl73QvXJcwMPt)m|$uFhmJz&}CYagyN z`HAR4ftsT;G!7pY{*!5P#41dh#rjNehH66V6d5Vb8;SFrv>CORJh|X;fbX+N6la8@ zYP%a#*^K2Eybf?_TAB!LIBe4z#uVmpa^b`V*=L$tgf=*N@%6I2G4NkFwLvtfC_^Qo zy^?D!%bE$3oRt|#Hu{>}{hWy3>vzAc+4pioQmW$zuFWFLw=H?tbmaT?&9UeGE4RIs zOaB~|H9s~6o^P6j4`!d-`u%I~lWDis^30TKN?oKS>~$b@-^mie4L%{MPSNj@PnKWY zxhXy_-8dRqYjYF#B<_;$7h)8Od&D^8l-WZbILu_OXVhF2bE=nJ=sBop^>p=fS?83{ F1ORC;V4wg1 diff --git a/public/images/dev-tools/chainIDE.png b/public/images/dev-tools/chainIDE.png deleted file mode 100644 index 7a85fd0abdbfa738753f3de6d7e9ffdeedc4a195..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5796 zcmV;V7F+3wP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA03mcmSad^jWnpw_ zZ*Cw|X>DZyGB7eTIxsOhFf|}CG&(gmIxsLAx*zfY02T~ML_t(|UhSQWwcJD!hMAkd zvJn6g;Ee!p1b8DbL|_wvAp$ND*hFB60EoaQ0!##$1k8TFrZh)0>PNNInk#AgKc`Pi z>guO{Raci@A2l>IG&D3cG&D3cG&D5K#=+v7$3Or4^C{6Ou>T41#};%<`1o)*Xg>(@ zytB>sgYYML6u-6ox3+&XxH*zR1d-$s@gw5TwN3amMV{KA?w)ia8WQA88ze%cf1c1bcL))V3{i65_(R5^%rwEagm757u|=CB)*8L_0X zUMSuwv0@kyPFikLHr?h)CUOy;vH5&�r7FieMtzcZAJqw@rY-e*EFXhhKeR8z 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 iPz?r}q`!m#FH2qpe5$)%9fxTj8 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

D9;h1QZlZ77b$uA^{r~cm;6S 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 diff --git a/public/images/dev-tools/eth-dot-build.png b/public/images/dev-tools/eth-dot-build.png deleted file mode 100644 index 971ca61a4b0b6f4b513ccdf60987c11be68293f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1804 zcmV+n2lM!eP)VnPyOqpNk}-TV*bO+9{<&4-asr4p2uewW)zf6wb-mnU zUDs*Sy6gfl#yRi3GY}~vp$yaXAFz#e(w1@ojho;Zj`CN`VPl9FO!^8M{ymCnbAMQ! zQG8pXzp&lZ#UonQiJd5lZ%dfrV}T(Vw+Kjdq&Du|WKhQCa@jU}n_&1>5L(|zR!O{7 zwQE||lruJvMDJ)K!INatz|o1jm|rE*Zjc zAuux67{M{+9l;U&c#bt+3UdUhaKK= zp%udXhWoBcSBM+JVbtyl!4S_^#9uQthS(7t#0t@=mZe5`9kd5%S<{8BLXs^D132FD zRTVAEV}vvV@nYx)nMjV6cs0`vGLam_!7%dx4|=gIj5AgseMOzgNI5+9hVgjir_Y~| zlhho2-IK?WN9uwqp(ooF2gDQG$}%x>VvxE8&pNIIeDV0ng**{rZH;!c9 z+XE?l$Lyd!YY`wmDhW+RIA#YGlF42tCBZ2bFgwV%Ek}}Qsv`xda>?!!9C)C^|RjeV@<*y2SHNk zAcTIO{J%|^?Q>)${0*#2o9X>rH(`lo?Il~>7nTjRbKID{l_ zn{X)mYT|pDyPamTLqy`<6DI|d*VXz?^w@ZcvH+`8GOEKDO2&2gGReRWUnC)}9&8Yy1&T+MAmBKn z1VP8~B#1bUCPCD3EC~{hBT0~S97lqT<0ukj9mkM>;5dQ=B**v?5FMjSKz58RL4jjr z35p!!N>Jz+Rf1y2m=aVtMwFn+F`fjKj?pBjc6dJzB*6{`mT@H5<0zazIgRTWMuNSL zK_uAk7(xOL#{d%WIJ!%~<>)K{pQEb;oQ{qX@H)Cl!0qTH0l%Y*1QL!863953OCaTF zEP(JXzLJ@ptVCt zg7yv(33@mLB6-xi0WQlKklZcXwLYk6DUjH`5YYptmbtP@$|1r> znJsf&FG=9p}9k4 zC38(asDnf0B&Ui*N*9O9NVYADkZ9=SP)W(=o<)&#bEt&my@zD`Nk@l@O6EYrN=x$F zi1v`oOKP*7V0Cog_G6jL96?Hd#w|`;$~k`~C!Q8(#$YI=mLHT%bv)v0JJE`*L`7pc u&+~kp=ksZ>f_>r>pZLTlKJf{~75@Oqwbstzq^;us0000XF#O@ diff --git a/public/images/dev-tools/learnweb3.png b/public/images/dev-tools/learnweb3.png deleted file mode 100644 index 8ea36e12f1dd3554dbede6d8a011ac9838c1ac6a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21480 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 z 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 z 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 diff --git a/public/images/dev-tools/metaschool.png b/public/images/dev-tools/metaschool.png deleted file mode 100644 index 9ad489cce84f8329fd98de6c1f981166523d0a98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32609 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 Utq_g6ga7~l07*qoM6N<$g2b}jlK=n! diff --git a/public/images/dev-tools/node-guardians.jpg b/public/images/dev-tools/node-guardians.jpg deleted file mode 100644 index 39432377c703ee52ecd0428f96278df1f54bf428..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45061 zcmbrl2V7Ijwm%;1;IUH#1S~)ZEsCKx4+@wdfrKVqMZ^#T(mQw*EYu?qawG`|A%xH( zC6v$(ARr(hgd(9y3BC8uKj+?e-@Es{ch9@`_g~?|-ZN`Hd(WOVYi6zQT66II;0NF= zOb@CD;Nk)RxHvz+K_4I#aQM)n6aO;t{Lzw|oBPCxlc#u2oH~Aj`vlkFBS(%NJ$jt; zcjEZ*o6DR%}0(M|HXT(*7hi<>{>LA}=dz6w_ zy~rni(>+!Ka@)kz;br?UzhGQ`$C7}Oho|J7R|U0-x~XY3oX7HWap-R^{OgtL5T{i*qR@%)pfZv{f*c<)(w~kpk z$c|&JPDdoDS{a8Ea|Q48sv_vP(P$?WY z37$xT;cHSmww6NrkbEYAj*dka5-Y5sxgg_sx;8}V#=1g#IHk#JK z>c)b~A^3=~j$lKNoBD!)v;XH8{zC&N(l;thljj%5p7O7H)|@eW@el0(t8iA#rOaz^)~j=K$~nxBFsX_a~vB|GwtU-dupMpwV8GEG&4J1?-Qe($pFFE6{+@9tv9?f5riBG2`qd>MmpsEal-m9tKM&Pi51R;(m=s>s+x)6!zCR! zIBvN~%k9_yYxMtt&y^ITLzY^VK8oW^dO??p@kjr_{=W)N`Gp>YhkPI4h)|2{w8bja zi$3|e{ofA&=|wN2V0kU+#9A+Rf`?Fq0^+s5Q^fggE*U&_U0CG!tpYk)fbV100Q(^$ z&IYk9-nuPI;bXUp<2Ec9m2b0UfQh^mo)xD z6Kh_+9mC$b`hw?=8kK$fSSi3CmAYm|xUs4+D*#q&e7}pA>TIPk#!SNwTr8e#GKoVX z_FOC!p$%jTHBCQm%+TL!;vz}L@? zjExU(|GfP_a!*oqi(1AFfQU9%uLi|t~vNZ(a*F6|f z*gL&FPYO`1VY?yY%{{i&ZpL3;Swa|1!_)|X$A9g9aE0Vn2Nj;?PE`9fBXOD_@j1Dj z)Lyh8k|Jkuhw0kcIZ#*V%i1;VIcYQ+?^pHideFBZ>K^58In!y6Onl1FSV=_MAbpo> zeaG&LpXI$rO>w*nT#&6>j$L+}_^s;IopV0n>!;){JautA@x0Hz*ym^RTm7h_Dg7N< z^9X!LFUbe*{S!SXnd${g=Ij1|50h9>yI=d#F0lOF9g&yQ?@=o=;}wFae@8|Ce<`TB zREvXyT3jTk#)L37>`7LUe4TShR`_tQ@Wg z$S6CuAJaaO*&Rx)tt$;I%?7c3+J)uWTSr{%2O*C z{&4_!_i%XEG6OjDU6X>vvUB=9@Xo6zWiCoEDEeqqx{=)QO1qn;1ItX=+kv zZZ2Bl$7Xa6cca7SF#WpO?TjS{TuR6Bk9(6F+8yhuL$9ahv23YEYrERPv>`1)a25Yj zkIEHoU*dN~Lwp&rVolK3#;BSR?hHmEO+~sO6 zyFQz_bH9w@_|R27d`LgI>IuPED-WV_b|6gou78@kVy-O}fC<=$L+HS#H~{NLNKZ_=ah0Q=n>! z>p1Di0iZ*l6pRs0zIXu8Zo5k5lS(n>If|8*XjzS+gXbFvRS(^|@n5{(i(I?iNgL}} z#7r1E;pkQxHyRq`9=tqXygY}r%4Is6`NolS3R2K9(ufAh-64KMUv1sJJ_1`+iLDC5 zRANds*vW)1oFTjZmto810Z7g;%IK>0v;CM%x^%bV1V3})#{@6a)?6U@LutnA=*j&~ z5{hR2iO}yrZT|tSde{^fzciV)ytvz#@M>Q>@5i?iz|qrS7Whe#RZfn9`i{R3ue4-| z6K}t;-JWunp+6xl<&LE5yMczFkBnl5KXLpwe8N>imUYA4h~2XNVFQUvA=*{n)((52 z1?y_uB1z(%Bq^#Mbd9qqZ@+J^#Cc1|(5;c*t_UfE)Uerp(q4i6)GAPw6z!(URb#Q+ zcD>u(bZ6rdGBU~;=|+WR+c^JB14$;FNxJnXGvn`B|BthTYh(S|L-{q~MDGMspqrZ+ zna6WvY^j;$Ym=IvKXgk=;-rrxiMP*{TOy%v8S3FW<~l#F*;}j@Kjkbm=7@QaNRac( z+>nVgT6?g|oPL%*UcusL+$LwtTvGOb%}ecr5KmfqjTkK$B?$#xcMVfRiN`|ap%S67 z%LdJph^2J{2h20MVYHJDv7!PJ4>AdlG{2s|)NRy~{Or&Rz(->xuMLa{1I0L%mb)gj zMEXe?o@5bW1q~=1?fRseUXasXOjcW)*1-xPJgDXvz3buA%UjCZ6?elIP7ZCqro;T@ z;|bX$gn9&}W2$;wn&4ljyR}99xuSbtEuo{EDCB`n$MJWm!`#vJ(B&-4wb76_Dh;%R z?4rlQoHa=1;uw#(w{CEAS0#3Rr%ugG{&7MwbQ$Xl45!=p*Pmm*UaA}OR(>E7+HQ_j zim}?`k8uLGBXH7*#HQM?3f{#5jhzm=H)h@qEP8!j0CK+aYSIh7;Y+ibP*8fQD${kya0MzF(niZKvv6~?BevwAzR_SX z&uJ#^Cz8a((w0VQ3|w$O@BnZ%Eok0$&=HeSlR(Vv45Kf9zTyY0)f-+ms0;BLS-IlKtu?9{{bjj*mv+jr6=!9-^sf12W(BFS$2>3r8=Z zzl2o|CKdc>aBe0|OgvR$*7@w;713;&eyL)M|Nd;59FY2lO&D3)2W1JMZS&|I-56j~3 zRqcPf|9|m_j)d0>D*Jfk&h-trn9}Hq>YB>Z&T@|`YQ{Put=QaPt&#_xT5~(u&UgbK zA%0V`khDQV8NrIICpaOyir>8IT>Pki1J>)$qZHp|-6%0S*lA-XA?smkZ5gKBrEXBL z-}DtBI z{J6kRZ%2pJD-IE}a?)paNmh&ziq(!P<@Eg!r(pLx!bdCW_qJWWns_?Y22fj7$!It< zGZ>a*nN6Dq;FqN^~0S$|3Ia>mX} z!*iVTJ*Y_6aAcfctNpx|8w7BKGYOw6D-DQkyXP3}>A-vL;4TmJClN8kCgiWyedG@y(WkE{|p~ zBw9$fl?oi?Wpkxj14yjUs^qXaAr7u!U)!E+P$1f#TZo^*=(Lh3ZWx4VXk5KpH(10J zC#!WQex26KPh`nQ>}jWE8289c9RO@Tekw;*dqj5ZtkgS9hhHreqnUMN8dH%`_f<^E zswPx!S=h}8R2^lqed`1OARnez<-e(IwxqW;|8UUKBhA-8IDgu9Y6}ro>tdE;0S77d zXX^TUL8K&)r{_fU1=#Abuxz5Qjdgc;ymWQ?r*1b$MZ==gK;s0{Yi`NQ_P3JAoJ_TD zcihyhbkU@#kzlO7H_GYFrF=t|`Mx$3-T);WAykqPyOfg&$wK0iEQZ_e`3Z?s@<^I~ z1RP#=_P15*oPcFtLlT%K6bPA{vKiNUw_(VLu~j8t(%TehSgf|~lblV_WlQk2Ec(U1 zw(42gUE4bA7uHqiUnmX7I(tx%csBx2Ku|ZAN@<%8R`4vYo!?`wCtN5kGS2Tpx+s!( zsr?3*NVcAc&0N1L$@KlYHIdWH-u_YL8D zjQ8g|)ch}lKw3#{&jtb*os-rbMCY!@DV)udE!hWkx9RlDZcbHQc+kgi4$$=xw$*x- z@EB|T4*0{^&YddjAa)hCVbmXE&>Mb(a78!@W?YA6y@w+(0miAx^2c_!YO4oC%`Q8Y@GM{`;e5>Wbuv_ysh=+`Ms5Zx&^N((>x|wT@D0I z|JaYV8Qz&kpT3Ts_Z#b=-X%Tw!zKfW3@~zMaAigrdffwR-m5I^0MqDYltwvuM%95k zFho0|ENKB(rk~NCS4fc;g!-;6%^H)Fo!x`fJnxjxRhFf$qYJ|MzeSW#1>i5)qjvrD zH8BL{fLj27`hv&Y zl)SeCGVHT3mT0M`9Pdvx!2l892EK&oQ0`x3%jV{zoC+CUnv~wA=fpY~jPC6DiR7U# z7~C|L3(78)r(L}Ia=ybjE|MhGB*(G->JjM7*g&RTDW9;okyEH92N@q7wYN4gSbdMyewv2MtbdN+yUZXf;SC{7 z6s1eCF}?f)iZje?BHo)6l*X~dKb3HhAa^8OAyAWSE$ zu!PK1Tv6xK0Z4+QpoUcAzG!y;m*%Zaf7+YR%Lf3Ij}+|YE4O&7ct?SEdQdi0u?>_R zYf}2g|5Apu(35YCo#fw`qzp$l6I%gR&;y2}z@6+@i<7JYnQ-GAoirIFl~39WR9@qT z&O}o>_sDzzF1_f2xgMXKn@=$k=!|b>s=?9uH8hyLSADudYLY_1*V&F2w_dMXM@@!3kGMCw`W= zSSKqUyR2JXrw*JAF>03s^`g3$QuMebJM1L%$ES@1ll)gyQ>A$Thh9hp=1^Gp05v`r zmn@wyo*Nvymjt^WzB17>`Sa?8Mv&UJ#PpuP=XT7R`j@#vGZUkB_Q@Qh(>HS#5QV-Q zah7Hh?AkGO!gkR38jWoN{|1x^koc{$+=wr0OZ(K8$*e$E(v3}KK*{a$5ztQFrg*g4UxBHKph)iDT1GC+pn>?QTua+4qwy4aohOj>2iJMOuA1lz}4 zgJ?7_|4#e%-QNM6?ehoEPSzP-D!gyi9>46ERIp9M>^y95-7XYReY+u*xCe7(rbYfdyC3zV1X zQ*(3oOxt373b$Lp8>9$fE)17?uO;+ZkVo=gR;CzLR~9FTMO=E$DA#hPC8rynTsYsa z8J<2me5Pvzm0kZDms z+DYUSWae#mXewcf?c3=%o_Sj}(&ApBA6;EI z@AM#DF1b8xoM>m7mbip++_X4n)So39tY-f@~ozfj7rf3AC5xCx`AThnqY|M{*rp`l(hjyT6xuh!_%2R2crx6 zJ=|*0bbsvk{W#iH<~v^yzRP(EJFQa?Y6kPV(qWp$u1@Z*nOIUwd+~<||0x~T6b*wR zCQVPua}aKY0S+YkPn-V1*b@pWAdDXEP9q&%bdS}aP>p%4_S3wVrdpUvX_HS;b6Bt# z|0Scb1nbSqnn&i_@|_!Qwa?*{Vf6$j*@sQ{E#uTxb`xC^GirDfZotmIY`7&79D;EwqAXx$L^gOVY$=uonz05eo@UoZH#&UTQQjJ0% z>|HzMGVhZZ=4YNIxoHwy2ic!fncx8)y`1IvS3^h)?NG$Qy2r6(GRT}}<;*)(t<>i# z=sStSYfFZun3v|j!+6}Ytg<^n%$Hv&sv1&hhTcDff30nd_8ScdU~9{?}j4}{h<(p{`o>lc1JJ|TI-bTD!Z}J^SEF4cGY8wW)f3+gnpk^ z+!I>Ld^H7AuyeOW>QyiFR1C=Bm^LWb%`WgYDHfuQeuDnS3w*b3OIv}b2=^3i+mq$y zhBQN)6DUY`KlgaN>r`8;)K>ocTmPZEe+W%o-^XPLtmK0vg`kvY8>Krd=bSCqNfP5r z-;(B=cJ48Ya8QcR&pH+40ePNI;G1g6JTZK1Pz!Xs8u7q%Ki+FbOjhZ_ce32WhMv1gN0-zuyraGGFny^rL`r?@ngrR ze_epIqF)vA*HjC)pVsKl22KA;c{g=5Y}K4zW^!P z^Z?=`g5Rk$mTw{^ep{=)UXi>W;go5`EYG8z4Ch0-5ri;K*^Ydza)E}Y@9{jQ-pbD$ z+m|X&KXLVDrGZ1dB3fp%4lK%2n#;9;C&t-SnA>Z=6TzHc8xqb7mVcjar$3nDgD~4< z#$R%X33mnmxC8lc^bf!8pOfI^sx&f2=cA?9!p(CDoXz+0KW_^F9BbO}o29VUX@=y; z(a%}Ud#sVRS;dTB;S)J=quukgOC~#V$BzQLwIod%(gT~1RO?wz%7|Bs zlEwnn;_xme1Oi!dyBOHQ#w!jQ6dnMaS!Zobbc`t0E)*&qeyUa7x|@>qZjXQz62 zqR9h~hyeqp;K~coTuX>rL~&9-Sm_mlmND2;+7-7rjH}g49-y4jji%WC zEzt5;5gmHK1r+(dGq(s!YIDZMh7Lk@5@TyZOZQ*92VJPYTwy6;o8ldW&a|?~s~`z= zul*QC5;`!B?(xlP3K>C|eqCuLdMteuyqu*Ca-y2Yc zYeeZ6}A{8_)`lwJEd6Ri|L@cNKwR zi_OQL?tc7B=l+>?{Iu%N2hvY5mi;5v*UV9-KaJ@hd54~N{a$zSl=;>~_&8ZbA19TG znK;uXx3YCk?)Xmf{Nt$&hi9HS-tZ=~Yt`!EUE@8;hvS~Rj(^%Gzk2rju^0J1(iaJ( zdV=wlFxm2vfs7eM5z|Zf9aPsiKgXTmIFzb|M)tyJG$r34D^)fucl4SSXF>zcue3d z7K-A5@GwaXdb+Fe`?yGdz$-X1g*Lsq`JkdqShay@q-a%WwT_(O-H!dx9s&}t5QsJS zlFu5v9_heKx>%=oBfKW^(Wg{gs_i*)&}hI!&aw6>Z^a8;u9r7iemfG}@@B&J{uEu& zEZX~&+=>bHnWpjV^^kj+U3B1HaG}^b-C|pc-hFYSQrtz!siGVUZSsgCkbxkWkvuZ6 z&voSMv0H!i{qJd9ByOGLLmD!!%Fh_K3hl%x#dnMkYu|59KP?JaHDc^972yrZ9aY8g zW@g*!48iqD^B9n7L(_%8AG_^qWdXDNwNIZ(-ybqT!sXg?!bXg~) z7Yse}w+Zr>`{!g-m=!4-PKM=fqZB?!pZ(PUZ!rvpE^H-`faS9e2zMr{Qo5jylu0K0 z)$KOXMa^IAXXjJQ>$l?~BGV?jpbW1mr(S|Yq?XMQi&v0V2MxVSjl z!)gsal8+3;H3p9w+X1Ai{S0m-u2IajN21RtYnDDs{_cg*=}|S!%^YQe+$2^FuXWh; zEEr6(+Ga01lm|ErBy~?GwVhI1iL%n>9pwb0B$LOVL_PRhDDm$l^I!M>9&XFHF}DAP z)Y4z%H0v+<;r6LV9Z~nRH-0q&CMSJf_n7l9B4WZMtfu2H*+cfShiMRhopwx#RQnsF z(_zy0SAT@x-@018^WxZx$-PzYSF?RLvs%i16X;UAn{n(l^@>E)U_sG^qFzfTMV#Um z1j8FTK@tOfH&@4hK9L`!WnY(oGqdUaBYMou7wL{kA1V8_hlNfq?583+$nID~xWJr&~8| z^k7A-HZE|`msW*7q9}CD_3h<;sV5N{L^L}tNa%N2p^5TDk z?j&7l-u2t=9WK;KR+zq=)_iIhPi$Zg+91|d6I7Y36vZP?HcL;$D7J9$5{5SEa3`;1 zqT$2zI782Pdnh=RL9+MxeSoLU`58eRE2k6bC}WU@6F6_*+ZpT@#BUff-#TQm4UdG# z>1FO<%C$4i@e^(^&4-fvYl@+`50^hcG`@Mq^|lOR{jBQO=4l zjT(Myb}^*OTL8`~f9lJ8ZqKer2IbOdeTuZL|HP4@(Ni@2m@g}JrMd0uwv=`m$weBK znzmGTys>Wg%2vOb{RI=>4+4)6uWBpBUbPLz+AbqQ7QAZ+}0IN!tR+jc`l8YPy}B8 zEEeksPymR`F}$ZX`Vc`vkVjK26V!k$WD``|3R?9*e>qcD`eb559TCDO)k#iokHrpj z*nCP}H+Ib?w~wYip7ajtT}#KI^qQI?pIU!=8K&lT|GuqF#p7-EiZ;;E7H2uR4w02b z>0yPghxs0wSrFD^rkr0eRdE4LG?JXl(;bxZ)szd?zqkY!0*`BN;eId z_PrB*uOMR-q= z!PeoOJCrbx8gqSnFv5H=2c}4E!dfApQ{m|Ip*Yj_P3W%+r}~u=a`bZZ$V}r-s&4B@ zBtKujfTeg*&ryvzLHlZW8Bv}ynIx$G-^6!AlV?jjBp~A|-QorF8JEDGc z3DQziYPMyBia{ehsVJSyE%-U~Mv}v$?W8E5Cq0$Sk5gWyD|E6EzIpvJ4q45*d|2mo zj!)dIRYkA*7cF?$Q(H;Kc#=JP8gruu|NCrHdAlMy(6P0K@scC3n#~ZG6B+|8Tify4 zdMPMr53Fi79RECaH8##r>@S%Ie=mZ6xc_&82=eKrv_v@>-XnQFkY}y3Uh1u)#pjAg z4*)O0Z`SuapjV@y^R>OY==`FVkgd$*r-6Ab%M;U>QjR%k4F)ghFE=%BpEVqGqz^f> z2J}vb)pR4sg5ZkTdZT4mF&(cN10JJ}3%E^(xYndKVcqqdk6q{`klTO}!C#A?w9Bn; z^1}Q0BiryHbkFKDSrp7m8tT?|=4GTp2}Qa6p~uYEFFV3T^K$`(46OP|-I`L^NFgpy zC&91Dh;qRaVVAbD&i&msp>3+Oa7Sw7EVMJDV@alSg{s_DzPc$U?2Tc`Dxr-iC^THY zAROCO3+>FYSO~E7y*b~Isvi37rlrrsAS>xBD%R6c(AfuOItOxml4LI8NBbRT^scX> z*t-sug6iRTH=`F3uRMPYN?7HJ9aW(z0voHYwJo?3OYJbnNcP6%aU)dVa7Xj=6r*`& zbRaGlFsu$ORLq^}Dxs;G=2*E?Igo)1(l02m;!GkJXY>3g#8tHO%R-cilj4cK{w9-- z1)z{uO7g6eBuS`!84=-^pz&UX zCZV8=;`Lwcdn@y4Fqt&#nIjdJg3Rcj!kPA^`y<}!`QE7(>Q^45vq9}NJAB+qsG|gL zrGeP{BhJ#ODLg7BslS6c|BImEn*FJVlVv#0MW3%VYQ=( z9S9^3Tbl>>z@Pgzj+36csLYthjkE2t@oOVVMn4CP&pCZBvbQQ3W1oDSif_1pN7Nhu z1ZFQEcU*@}7&FLdG|VhlURsJtInw8X@$fY|YdHZHe-cCORerp|=$aE2=0S2GwAiuy zluIjwy{nA4QijrW0v=4M4^ye}p(8n)k6q_P^z&EKsSJ0O`mvqgtY+&{sT$^8@|TG% zwFdybWbH%AsnJ2~PS%ldZm|fhbOX2HTLgoKTclR4L0~1 z?y`DnH4xS8wA$2GLjkUDcd{4S_H@wM7Usvw7e*`AY{{LD@JRA0g${QL+CXc^=zJE~ zOcEcHs`w!L!|ls|CbVGUO(aq1*DN@k?}`K`Tkf<%41~Fr{2Q0b-eB2}+NYkIoVhP! zTJSRJ4hud)Fz36!J?yoKfAL|Qmao<2vWngo3d8Ed>D<(ZO4z&XCxpC>$E6q6%9Iw1 z$_&WuopNI(iz!|P3y9pCUpksJl%UBAvJ?9Q*17%Bx#}n*l<&?ce%aRhWY8wo-rYzRSG(e@hEe-Ol>QV2^SV09K^)u&R-AkqoZ`gT z@!!tF$`X~{yk4;=n%H|p1O;lok0~BfeC7E_>o;J?&{giD2x&`w%EV5u-$&WZQiY`#S1(kmJ9H}I z4b~QHtZPCm#6pv_%6moc;p{f&BE38-q?gY%7nf#cX=`!opW92*{qp7GAO6xmp??ds z{=UD^g59y}n({1BSps#UhvD*;+YfpUho~p7o0;~wxFlO!U9{g%H<@66<9-)f(6+_? zQeJctH?h+k1ptst0-DO5@yap={w_J_>2D-hytxw+W)SZ-H6A!uvvHYJQ1q#yoFbH1 zQOAM6QQG-620LoOQQ06rw(vvh?3xfWMeWx}Hbxm45o@U9n*C|FE$!A_Xe3d+LUJjg zPm$bJNfV!e45Re5x~y6PG#HCurQ`Y=kqf^To&-`X4MSjdx8K}A?IlEV!nS*;x*e^^ zFyWbAQvyX5=7Hx#qERjIt6q zYX)isgVOVRsvFYJ6yC;p7i}+ho@V7F-iRDbbO4tI<1>dW*A~(`c6qN_jXdr zwl*s5nT$TQ7*Re8=BXmmqD1Ic!0iI14bLu_L`0UMX_%P+8+qn>Z1DXDL6!}tX!nA< zeid$ZZ8-p(HdyDNR#9dPGQF;a&k{%o5ARBmJ2+D8NXVU^MT~w_xlIWax8Qf|qNvu- zmwXet#721eShEViID(d{> z$cX1n5Vqu05o5)W|I{ad5a;{C?wQRy$xSFp!6P-14nJ&GNp0AhnK)xq-VK z#l^3PP$;?G@n@&3s45IkJbPhJnh=3Hq0I^RM6j96I>xJhO#mMHnh^a@WR~wnC397Z91my+SuM67ysve98#CU}FE_%yHKDx!jVxQj!lEX`1zo-~@NWKt@(#;wFDz z{rFL(d|ZAr?{Fyj5nSd!Hl zwhF|rWRB#BO~?vCiOLHJC|(l<2b@aJ_cxB6n!+Y0`0dwltJkYbGxAv&F_g~}|F+(>lhSjGnHG>tj=}VKv?VFF zNN>%IPR~jL^Ruw`*4lVYnl|}Q6K8L`M8-*^sy?xOj zbqq)Oy@VHV^iX3bREY)kz?AFBbQ{gnBD6&NFm<^^3@3bDp^o-Pm6~OVlbRd-O0~i7 z&Z|#se6VqDN++hm$mCZeVb+n0{WcAWZoX4+`y|a1l04B=nBAP!h1JFB`VjfZn4}fr z>V7rM>huT8pxkny%ADiL1sy?8B`bGV2wUfVDX=Ya?heeM3ul64C4};Q?UK6Tay0Z> zZf0vmon?0pVhNr$=%_s13kjCS3S-L4w<%5&;I$s^*63}{T#l=c6OYix8H3P zrYIb4xsFC)+MN=kt1ZIsLZMn&R1`6>~a}T_crRTm9rIttNSaUN{*-R$iY!!R5^LcvP zc2)5tnzgTCH9ATK>1E$+B`}+YAJ@)D4IWLO^ZfPZoDoDMS?= zy&#Ry3$)GrUS=@uf@RZBW?~d;?Gh6$SE5a7H@@kV`pZGp_*mD5=guRcTKTna4=5;ZF6Q6myjkB7TQ4S;iSKbTTE;BYxCEzh_ zeOaSkZFhP;9Dx_|w5)_EyuS6f!TN94fBjI*$&Xvw6D^{V#Sd88^ru3Gb`p}=8OWx+ zySfe&UsmvN)iHRLxB2(Ig2&nYiAz%b-6>MJnUKM2z`c=b`j1rUrzfS$CHF2kvI}gI zzr4JnKCG0wtj4a0qnXUwKO$Q}F1V3Llp+1GDCiDoS3#fjIB}y5g`N{~3{gIAba6Gp zuTk*c7XUykXG&3p&*(Je@Xqe}#REV?WH592bAsKBoKk~T@1DL*=;vi4fMcuND#=U?{bNN$+acA%nN zlMk;$@{CeebPPD$axYA1_2dLJy@#`yah5ZawnW*>|7`^Sv1oqd&@b2CKXY;_W`r5> z)OS}57**??HcG~cyDU7k?Xb$3MfG%L*4KolrcGw6laun|t!hw#zkjn1u!LsRsX~_# z;qGx;5-m78OE`hx#9d>M?Ia)wP7G|^oYj9mhi}(VMHYm0`BL^=rhte?s;(j$Z_Nf@ zp+|#qr!CGlyfaDA;QUm^*Nv>A`AoLy8;x{P5;C+ ze6Z`(-aDgxzCy^iiE2&|TI1NLfYsZKZmOHTQ=$Kc$&!pk9@*T(Ro>D7A6)Wu&f$%> zI;nmL%9PTRK1XtdC5BJ&#*Rfl;+)6iZ=8|GYjv+aAh4K8u2ZA6b+BGO%EoKuwl3PTg>rXP*5%y17meG4w@ zmxio3Dp4y=5vzufkFP}BmydL7X1;ez$sM4(h!rHV;%9pG28SuNc0Iff{QIjZm)t_m zYX!K>$9K!dXHJ#BIjYQ9ZlLq$FJt~xZ^+*(nk?yme@zY z-J*lfqt9sFcM=)alv$7I<;Q1rU`1d}VPg{eMd!X+O^J83TD&I(mHOPi-@l11G{B)P zvoi(6zPtGYBgxTss?R-GfU|sV^sK5X`#2&!k*;%)M-v9;rnfvAzD@R=nMgVM@qd$; zcu-6H_pGex%qU`obs}v~M5 zu46^^!;3Z2H$we5@vrdk&F4RwY%ZBRRF`2EHaTOXh$nsP#K}BvW`44=od$BFU)dPH zO4qKHkPpVkh32ktT;#C1+CZ(NbQr-Xb=|6QybTTBwa!ZX(Du&FDm}<|8fLkdwzJS! z*xKXhMU{us36m72V4LF7xZg_L)bhS;ycOW`rL6pB@C77uIC5#o`nG7f*~h#cxU`St zq_r$fDFVhxm4qpq&OFlefVsuG{z$xc=C%+#`3I9?aB-1ZbFtO!ZLZ~t_Cqh94=vmD zovZIr9PleRfK`5jQ1z39_F{UQ>P`#h42!;J#lU11V@2)l?#C=@o><4_W?{6}%Y2Os zOD3j(hKp5SS1hvan#eFL5UARk#s+ESW7eKL-Mz(u+y8g^*8{4D-PE&-if4B$obfRX=d&4w=Q7wH0R(jSeCMT^#Gt4 zyYc{V*gBxr(_Z+oA}(~7=Nz@InPng|+HzJ9;kk9Ky>;3Dl8fglyHJu~W)UaBV{+5n zZ{JdbJxa>{riNYtd}YB}zGa=d~3lpU&0P(DDnpcCRSTVLp3&%GSEOIMGF3k=lBx z$Hq<9G0+?_Rds2Fle4j`0!C@RMOl?!QWO>rNblBwR{Or+tRr{+rqNpxFA-3zH8IU+ zGxO9U=?H-^aI*6GFuFgzqseb7?pE2O0d?DNZ0+Lj=3y5hmCTDv$k-qu6x(U!XXft= zQ`P~12HfI*@tWurKe#H9 zCEWJ1C`p0bPAqh~KNmS%)K>duNtxIH(5^>X>i&1LVGPi`+)*#KEipc|p!pllr7oao z-SsX4Yv4L1G(}allaK<*N1sfs9giY^Vh+Q2h$?zS#STsmC|}IIhqxo|>sJQ2(E6`) zOTFiTVR$vw$Va<9ZyDSE!pz>{M{4Hpp$O*eQ|oH+c)~U5@~S}x?ZOEVpA^Y*2DgM$ zGUc3@;?f}(1SU8BLKd0rdoWk@h&Q!BCTr;EO8u2ukZPd6#M%{DYAw3`M|{#&OD0Us zHbzVp=rO#@?@+h%TsQkeB4?EsHX6txZT4AH8qTxfg?q_e(3MU9#80j<9{a8J=^bV1 zV`L24>Rbb(>;CXkkQ$dlUV5p<4D=&p$Z;xbJ;w`Ol-D|0$jSy!qE- zwPLOg;6U{(%j{g?#PdzQftkR@!zBQUi^z%BVm z#sNUfk=)7nWzxYzle}Zsf->{lQCgi`IRN~l<>rN z?;k_A{<(ZOyxF@axN|7!ibSMD`{UoPc3xU2lK;FW$1~UK?A=jBs~ypWre~V?)!i)| z%3s`5yL9#i;4YWlnUo@Y*@o*3V@^#O87V89B_Zv@x0U&8h(EWsw(S0$cO1odU%)at zWf1P(>Eh?69^*VDv#9^An5q5UQR!Dn-QV!vdhIA_ zE3YsfZZE>H5dBg)d&EG&a98mA=JqzQ1suD4^cH~Qh;!%=*E1ZB2L4)7WKwI?0j-Li zK62fs1fv~O=!seauA>$8PtNZc4(}RXR5}?VlIv4umTfrtn#d#@h`j_kfLqv=Pby_)&$%WGGRslR+l4y3Vn>I3;LRS|-^65^^ki59aTp9dEq13; zx@mXuDc6g?^!$JO_ivmaH3x6-%2T=mzgiFbi*ueC0@lP2*KG4HN!L8JjvMIo!ZTcRP#EA6|dvbv^*8~EaCXXf<4 z+Q7JPmv*Zv1h$|GXLq{RT_E1Mm5YW!?oK~=mjBAQryWe)Ld5vdY4kkwh z#xqgrE!9jfE3Xv64l2*5*d{C}GeR_{K}BlsMXDq0KZf@ZSM+dz z!v4(GssexK-AJ`2Cba89nv4rypgCoAu5SBBWLo^neBtwOG?56IidMEu?$FxZeD zr17Qm$*synHW+sRSdBQtq*$xALVAEm#7j<6M9g)~3-ehIsI!A%ynRTf+(gUrSCRme z@_{vRXjVYqds{L}2Z{77WbyXnpei*oGRvw<9HZ%PBIiQmdf06%t7@Zk;_zzF`M9i% zA;ia6_QgiijK0Z|YjYkUhfX)de{vILs>AY`a#`IK3=-y|F;zUXMGqMW4%2nQ$Bk8r zJFjmHZn>F!PWi~n^7=fyo)u}j+D34>8FHo&-a{8L&z`X#=q`yLv~f~ZLo;8i z))+LuhXlKHDy1tk!r1*cYu)U;uGK9(FK*Vpbm{(M4gz8>R=q!hDWgJ?PT|7f_USYW ziv1HKD!1v-l6_*ew#eX){G5_LG`-&uq}C-NmF;L6pBA@C7OxC@r$ zbTN$AhweTx8cS`u>{O0M1vBYBE9_YvqNtH}FBQxds__wg=m|9Sn_eKSsK1g}7j)TP z{AZf?=}z?^YB9`4OH&XLA}TLx|B29gNvT3q`m6&&iX9~@|D)hD`{^liQGc=qEh;v(xlK2>pCvXoCRN402~xt(+A-cz7KoD}1o zwf(lKd4oWb*G=5s=>Dsbcc5ECG508HwmiK`3O|5mMVV6c$=cJK42)?lfg2(30q+tMRr|U|HLl`OM`H3>>P@&H+&!U*`q}sH?`LH`ZDA9%>n8hx4j*_ zisEsq9%2xAJ^SSxOcS;$IejxDgnXjuQ18!Cb*ymaP_JI}7O(9(e~=foXYa6EJ5ug- z@Kv+GY3~{~(KJLJUNyVC|91Fp2EAv$$>{d%e7*7_rpwZ;SP{n_5%j+{CHS)N8)$6~ ze7N}X8>sw8nXVI$Oju0siC+G~bYigasLh+E_L%qIKvRh|2MnG4%suh%ckVuj@{7qO zH@ER)^=kU(Ve(kf)T7l3K{1vKdsPlj>j%o+$NUA{siVxdr z`ZAfH5SnF@t%6LSMpEVgE?dT-C#J+upnqT~@Jw##SVtGV5mB1xz`ru>C8_hVLSlz_ zyJ*19%iqj2FT1-e8w_j?Cx(HfUR>;#%gR6tK%gUX#hOI~J9z)9)mBzju*;V&~J*hO`Cbjo-`@QKD?W2nw>1nvgj}P#_ zFfJ!vt$y{+5yXEa!ly7>CK!y&7spW?%_#0Th~Ap}r%Bo^_m(2^qyAtk1h~G0bOy0P z>-%~OGyuu;E9C(;Ke@Tcv>m8t=*Jyu*Pr0F|DTfa-xiGZL<}GIH127I?n`|G%^sOL z0x)R%lj1f5zJa!l0a*&2`PTpZ?>Y*-meG|gaeP;*zP<*B7D@i|_JGcO8M1Z>sV`F3 zYUJgh1;b+2;b$OvQ=uiJXTmS;wk=$4J)>RywUVofy{vM1Sh zx9kND<_|0IQiBa$vm2%5F3Aolztd%Z5 ztoPKL9(X9?S<~^_&FLEL4%fW<`MxrNKIzph?h^cN3c&*G<#Mb(qb(zJuJte&cI&T4 z54^UbU8S0Tj&w7|MI+bnL`bmphp>U_1;&tYah`EL>g>E#plLQFr@kAZNJ)uf-Gr2k zYE;(U?8xmNGQaT+v`qU3 zO5g9RaD@7e(~x|#ji(HBWU0UDNPhpQ|2Y0GStC-Tn@6#V3hH(>j^B|I54buX|Db4( zq|h*Crrg?FLK7dnJP;&>{V=T`KesBe_CzjiPru2zyu}+6B&EDM&~Dap;z{UoC9voD zrQ{o^E^Z%KIyj3)HaXq*Rlk8gOoX%?YE7^3d%zl~!d_90 zmYx&3;S0(1w)@F86353So9r84@rM420Z;Lv1m@iG_IdDdXnA~buH0KDI@C1h8z|4{ z*gbpEqIbV0PQe7r=3zpp|LBEkRKG}kz&JKl{3PUPb=c)VE5 zssaWjqUPmbK8LYo;|#k=*AO5{ssaTby-r6&QwIB7_DPeBZF)C=sR*FUPOmuuyfly; z4oHdA`{!p(=n?{i7iI4DR*$$FHnf|-YYN`O!)@x-EoYL;TSOFGW1~iHymQ8!dG6~} zSMLGQNV?~V&$~=Mt-0~Bs`Et3A0b1o5V|ga`+ET3q$c6%c0uULLwqkn`dT08FtewQLMe2HDV!{G!9_tW1 zTi0)=T2Sbo@8Vc57rmI@Dze4Ygxsv!a(P|I^8jFU_=kK-x3IO`L+*S79kp@>0_DB? zg`M+kJ3CVo%&bGKd(V30cGKz|*UgRLEi+ogZQYXP(T`o_<#kE1S~H^iBTD3J_JO^{ z`DYy`5fNgjV#TpuzcNu`Bjt{m31QK$>^Z?FhSf{SHe1;csOZC9^s}`r{Xj@es}P&0 zK5_Q(e`YLyxU8cW9?b@T+VyQ-F4vz;O^k@*HYBz@&-^i7xO+OcGFIO0YM%VVzM_58 z`b#RiZyHXvEH(}m&+&hD&#qIpay3n^qCI&x3dvWR-nrn)GxM&BkhW^4`vLiu9}oy> z2!sqs2Ly)?EjUH`tV=^`dcOvVd;`6n<}AV#&@)j(s9tnWS+06~BiubvJFLbxfAfQY z&~g4C@g5AEb~KHw#DR#C+mYD2i;6!C(Rcm_+~u+Ilt$JdP@0D)igEID#lTpz-We%2 zmv=p?f1i8NmNwr~m_#z$9Iov;Lk)}on8GTxNs!jV9CKyF;+%EGz&yZ=MWo@gJ?Xxd z*lgQ;^z^d-FYi2u1m5RLhf8~-zgSBm!_bZE9+=D=DQ#QF9x@Q|g|poEj+Gt?hE8~f zMG^(gYzeb9^A|_9J%IM`l9qaVi{!mqTmuxH%cR<%$tDlG3G%Y?VMV<&hj%2l-eVlf zSXo8*c&a=4maa@Q1{PB~ok+N9M1B03UO zxYqF|@p0_6#@2J?CtA7U2b+pe4Ky@isiE{NphQC^U;QBQM+q1xoZOzmh_`iCrdqMa zl3hCUPkmPcX@J7`TsHzJZ0?7`p<6ve52`=A;3#cA=JKYG=N#}~M^sCh*Joohs)Qp; zlZU$c(B91@yyv0$YAmzKdT0gWR}buc_hDPU>2ILoGi`a^Npne@Wl)|4Hk1o#=pi~R zA-EAnP;4^b`HqO-oN3J8_6dcXcG(NZ~GB9`;G2cO(MXVIYSdv?h$!ci^A z>O;ZDyS`eR?`GJ%#Cy!;JgML`F3U+PX(=hNe)ZNLiC_46K^!Nhy1_w`(EQ!Z=1{!l zF8m5>@x4H>j7h$DxAPbCOcopOAki}Z>3Q484{|=}U z;F(95*xY8Kanxrg4mh~y$u+h5J%t*q_a1*PU2VV^lNWc+_RM`}Aam|_NEmyZn6Vbe z!9i;$>mGNJCtnTq1@P#T#t)U+1VbWwOj1J6a?P?o9m%Q)dM){`-)-sap)0dy{P1{D zlKW67&o_|kd_nwSzDJMKV&mp334KJ;PMGzN1(LCcJ923WS`r4OkOx!j(hI>4==Dl* zNulpvy?{&yO=Xe{h2u1tD~@C^TAs}H^FOJEe@&{#e%Z-?bMxpsUx0&H&?6aI6Jr-A zDGJfFJU`T`Vf-PReGwzip9n9A4-Jr)2?xi!&%lD^qb6!RGQl8j4%KNw(nMr3xJ0Ya zDuj@U(wrLZ%DwB5FZf{F{NV1D!m6zj$1IGHm0|{o5q8ZDHhPfF9-Jr66N4y{KKh+ z2eG~A0b|@Gs$f=DCxCPHlK^a}raavnrphiY>RTsGT%hsE`xH60I&`*bKU&I6WIltP zvKI@h!r5M}=KNFzge5X?HN1KD;b|Z_)WfRxFRGwgREu$}rY0~IsglL({&u%J&M?{9 zrx^hwY&x7~;~llOs>$*pXKq)-9N29T5~dHO3qw&E&SPKyb5aFv>fgl^M*;)Wlxcsk z)Yp@V;emX0&lk(5RQ)z=zJZjTU%#(>it+7Nrok{{Dm*=vp(719mVXRE=RpEQqn-y% z9!#AEfzo35Zx6%D2eFk>E+r;w^!~aV(dHV&^N24N?5_o_BeKaiRuJ(hL+$K|-E;oI z`M2teMVW@ch%>|jaYM_gQ%l-|BfILOa}`)YOPh9Hldt90eIaPEMIDt1gF^kAKpTD& zm<1>n=@m(OzM@^rMYD#}?F!Fox7Wn=f&2|@>%8q?{oDK^Ho-=??^)(H`3!ROP?T3tDvuCe4K4iY>yfE7t6{lmi^~t^gEA(iFL~CDrg$mE zmeo$KTz>AaO$Lv(z_JX^3WsNWzlMJuEf`rv0H`LmqxpN(+ui-A>*f`Y7@N6oI^0zK zf?SWu3zs#@hSZg`K3Zh=^w_@cBItBy-Dd< z>oZ;7xz=@jMP~nbj+4lg=Ul6IFhbRLc>f!y20YxPf5bbGI#1CmC_!3|zN;c0uG?RX zkyl}sFFAE@63yWl=x{Sb=_gNOHg}SH%gdt|MBEPWha&X^vmo*(YQ;zMmhFUW!JGi% zxxEp-yauZcMnRHisw+I5zH`e2^|@xO?%ML;ne_$xUe;d8B;OO3wJ}^9dL37{O+kEq z`ma`hKRMmJn9CA5;v&^}9i>%8_p z@z~xRuUY)gZ~nwGTAX8!>Lf%*JZa*A_T~`l32LZL?Q2=K;O>~`RM3UXKnVUxnbTgr zSSCx^%$sB#xn?q3?>!dc=@)bzh540L`PPl;QB+YZV4)A~eO%n*i-fHZG^1Y+Ehioh24)3Gj&hlh<&o>o@d3NB`@_g8nWoa6)VTn$4c_`wX*Y6wjoT<2tI#rtPRx zVfhmmk01p=rKbsNsF`tsrX@TVn*byZa;T@K_nK~O35vYOyxlX4&**CoGE;6UZdKDy z_B_NSe+8zTV;oPlg;|e-83zE{EX#$;vFy#(hiOt%}S-C$K&P)pimt_y2OUco!Go7jJdjg?rp-(fjT+&0MCnn!`@td zqp0fpSdqIZS6{&rSxm?8>NuugHa?9NKdj0&vBSTab#<3DwU(*y^fNBaNUNHs@-^ z&>tAGt6#Z_w}Z>#BaTx<%HzcL!)bi_`SY? zxQ#XIzYIZ>@qd!pjc{`pQ;ZF$+RaKeMQ9?%t;*~oy~a}7V=UDC^E=NDfM=mKSt@Ar zGnwC`Zf1?QY5#18S^Q?|GGY0l@Z(Bs!SV*l?2^&fZh43B&Ih@AVNY&U`Sx^N!xXWA z%*3U(DJ(HG5|F{zQ6AVO2|fhGh=TdyhN1<)O50P~B)0Ofe#_C#Wj)C;mkm_z@@<(= z7QSzXQE4-PpqlsS+~cnq$}W#vZ|%lL?fNrw*iuNESTnoGPOQE8?Ae)n3{`tTrc)GW zgM-+MR=q2~$cdBw;VlRxb(LE9qqfGF^2?X{g~crga@{WDP0Q0s+pmuqtv!70`x)a( zI(+TKr+w1Ogl?t{r|}!P&h!gBa{fye;olwU@ABvz^`Saf!ykMD#V!6AT*>fxk9wT) z#!^DpZf-qv}A^8sphXmawf&YhBK?ksi(0sWhKC3nn5;U)*;5??kl0iiD*S8ptr4U zsPp0^dP#1u-?`7OYd2Ue)Bt5z@jkM-Bwu_md8JE9bjP2MatB(E-Qn@>_rB6Mxo>oI z(bsiW_+qm~wXg_}GI!R1WEps#_658|fH8nX5VE)-iMwyg05m_g(SE3maIp^Qe` z73EkGcr!5MEaAdE;wf$NaMZ4N(q)Y*1GJb|G3#S;aw@#Y9->pubJ7u+RttW9_n%)M&1lGf@+_^S$zlM;Ca8B*atA4atQQQ&hu@ z!(_WR*A)Z6xPykb`vF5qbZD+pueYmS(7v*N+JKdfiZ5ixb`ad0{(3gU)_e;HcqcSF zH^B))yhHK*`5Wk9X|G!+g7>9S0UivP_JP zRXwa#uK|;vcm8O?wef}UrEoOXs9NOAaQb%5nX5ZwM^fm(X30X4)}xBiRypM{59G{5 zs;tDCpPljTwnk@_YO#%ldn+D8W+}m5NOv8ZWWNLc@Vewlm0k*dP)5N6dbs()0K4h8emvjvSld9k~2lKVq7{}Y7qJS+` z+0!F8ttF;sY#j0zYkoUtG;E))u3_nyTvj&IMQ`#RGoD=kkfp!jTm5)~zMxxX1WgF! z^lKEd`AYpbvi&-3@TWgghcq%5M?8vHxib7v=rb2zEY6Rrr&Qmb7Qbp>KL4W0oKc>N z2B^|9=5&7VQJ%!Xlp8Hg*wCYh#A)ky1CQGh;KSG9t5pujO<=vuda@cB?DwEtiTV1M zg^;#D?c%Qag?ZW81`?y{+DXYA4@DeSWDeGvjK7-k^m|VzLD?zRDBC>9*95?(gl+#{ zPuk87*b2nZ%P4#+!I9F@i8_VxqlB}K@d!4$X~=p4!^Cyv zJ?i`U-_uTxruZr>$QbwLqO6jg+XQ#?XkxP9$VP-Nl6l3c!q}BZC?h6&?66#yc1CNE z8AT}G@!XDwKvsd+EKup#*FP}~KQ#L6{jz}7fNq-O6RZPYskWVVO1aJljtSc1CFVvC5Tr=6Mq!ANLft8R-km~Cebe^!wzjdzr7zVK33NjqkB zCg7-(jnCv4@uZ@Qo`v1cS-(xq_CWlK94Dnc=kS1p#mMsqTLpua$o{AZ_1D;W36-z5 zA0BC*-n*XFSE=b4dcl_ef1sQyXDgVN-X$54V@4~^@TB(P_OoIu6L4|0;+d5l;Sk@m zEIw#ySzU!y^1YZ23E>An|fD=iZw1b_{BloZM9rBZRET?7sw+`)kZnW?Az-xxJ z_(PlR%GO$|u~iO56cmCK?n>qg?D$Crke9)%LYaJzQ;;~a8G8REz zjOm&@ot&@SD`W1a$}Y3h{FU+33~3ANe!_9X|H+ESfC;tl(inn#aAxyShHnZ+6jK77 zZHe$JHJLGZxq?t_uZwTGa}lz>6ME6g4A#=|KOBLB3gsxXu^h=xnsl)XM3?(3pmS3t ziaWB}l`#MjADF;dVyZ1r`Ckp=urHl8Q@k`_6@rN3k+4%@oucKUQO724DjqA)`{Oib z*xlnm!$lr#i!!6bz2BztoKk8E_&WP?@E|p`XfQNZf1l@aPwP-%jUtA`NH{nny|L{9 zHMQeP+n*F%f6Nk%eD?Iuj{n1|4+R+`5ExnDcfT}WcHdOx`J51pfnsKBrS#<4P((O} z04dLL8<{oCWzDUH-cpUE%B08`DAj7iQ9SX&X1Tq{(H5+^LVSp)C%_K8asIE5{qwW` z`hvgZPaLsVInB~3SkQlCEEniWYuV^Md-J}<0lDJ`Tw5FY zqMIWIPX}aN$41q?EThME8z4IhXTb|U8mi1LGQCN*)=sl(#zCg?IakY>jVjWdZ89lF zd_6O&rF`N$HMWs82~eLYhiq+&M5Ay-4nU7Yqs2L4s6v znb%-08-509*}Uz&Mp2neLBl!YXlm!Chca8IJ|QKlBTdp(+kMK)?B0J3l?APlQqS&^*v*TH z+}4&TrH}E;n6GPZOb7^^9Y~ezWScbXQfiVjp9yCKFz-h@Tan|^W#S;%D5BE+>?&Jlu*L&zdG*E3|M-~ir+-hW_-RwcGi+3~3VI=W z>_F@yF_b9r^2x!hT**ra1redU+nnq?*yWx~gss1~3(r?L*48!DUYe9k>dqV)Q0}&h z2>^12al_A7XFJ{nDBYuf(BNC}VOle1TrQe&&zi+)YCp*&%t|%+t7_&sX#m9x;Nbr8 zZE^d~>i({fEo*peR2EWf2elOCVzB{Tw~JIh z*#;y3XhM!1;H6tsA8ZK^a;_z%wK>m$8D&vdOsX4lNfQlXMwy`A% zdLGK1hqUyA;l=h1S0p=x9h3==Tv=vxcQ2^73^G0(YI=2CvWOK#M77H!DB6}yPmj8TW0GMuD8!;1bcOGoMvK}m-XOi@; z*Gma9R%}1*!%(p~I45-N>S>KG#U|!}5Y*Em#@V_#X& zJ$XwX%Y_nqRMD3Ho{&-&d`7Rp`U=Lu9opL!EqR~91E~At=!w23#1;gjg4zq5xuiKA zHA8h6JHb%t{@#OtNxBL}|=%8c<$tAx@m#@Wehjgr(*Dw4p1;AE+8ucoTZ$3*SHs%ly)8LweW2>5mE0$#&1KW0Vh1cCunSAs%ke) z3Mhd{={|8&h(dX|UV7BIDKxBAWTkvXCOq_(((kr=p3ykM)? zUTV16%GRg*;Ua&68f2%wQA)2m<;B;TKs{Z6r`wSYFIJNUv{d*Uwd2mWSZ?EkFB>UP z|Lm!p5C5nO^u45SoQ$`>R1P&9)t5<%4}k>y7Cx-Q;5q%a=bCQoBPIe*Z^-jE%_`(; z*0xczA+j+#{w2F34{63u>nw7ws{wD%+i#%v89VA~C@+L&#d+C&qU4u<4TgV=iT^_^ z4pg6%mny%3g3$Amt0fh9Ds>osJzLn1f;5!uj$DmJJvvZm`p{Jj#nNkYr5dQ}zZuh1 zs~Vo*n(=l-&00NN%+Sl~JX1MRcb1n;(JnLCqiY15p`P|Z@^XoSJTRS}80(qqj*-Su zk0I01%_g&@;YhT~C8rJYwN1S1q3hTEH%H~%Rfgq?HuBsQ4|yotJWlXj4pjGQ0nXD^ zMurUj+{G}q&PKtp0GLU9z%yITuwDQup5W7?z)koa5 z0YcNdG9QbxwoOvhDo)q9lT&{*=;+vB_x9LZgLfeaKpyIXKl| z-kEJUrsBj@#&r&ibfK<(clSZb@j1kg%}Gu#u4_DbD;(gPHl%{=4{X$DCy|OKh8W$( z-t61j?cBJJPI1>LL@hZVQom#Ddo;4;ek#Z2+FpSrUSup|mkt)!o!SX}Hu8ALieSbz zw=$U;Qhx_GPUY?5sg_ys7C(LWpTg7*MX|$|U@TB_t)_+`U>Q3Zx zZy_UO&$;sMhk7U+bg(K?+Rdqr(7m_h-gBe>pm`TCr_9+3s z;RF?TKN?!{_ftEWUvPbO>C33bREyQ$0%fD?E|m42v#WY^3x# zcQRQ`!QVx@=IF>of&b{p1!F)6&ypTimPc(0;^tkJ6Z-j|^tj`$8dBZ=P|^&0kc3Yk z=8Ckn-0;zGkau5{vSJyL0yff9Ii3K%QjMD4b{Fr#Cm2H)S^O_jvvo(ed7kEzJgmQ%~x=_JekhGd76`ag$p8AWqNKOl%w zc$z%dZ-A#~nXA%9x>NymC%@b|MN(2J);(LV7jO3*eVk-f0K?Tzi)0Fsi#06W9d)U# zJF^^rYNc(JfxQj!c_Mwx8wQew|aw*8;e z#E)5_EgC8X!4p^#7cGKjXGS6LNsveem@6BeYXFCq{6)HmrEnzgQBFLC7& zL0Zw+2K#UyZ~UWu>Cs`b1d)C*ad(70@@`T`Mi&btNc-UT$5?fAu}SXo z44-eH#|OEr86vhV)mMq%`-+slTsphEZj>rwuJY;W>Cwu7Dwdpn@j*AaSUj_{y-*+L z{^FE(+x5g(s^UyQH@;%S%}p8#2;wF{S-vxXKuUG&0pUw97iSqBViQnIIwm;pa zN79sL1%Og=rKAAy9x*-xB04`}`;QB>GU2UGmX?-LInIg%AeC0y)!)I+(|M*_hPRWP z-%Rzr*X{=^%IUsHbyDHSrz_tWtR1o(51ba(J&z~!Hp7yDxL#)-Ysfainj1$cDS7pX6R+(sKnO zLxkLKQ@o&5j`dNq7>lxQnkrr2D2P}$b11P8{oVB=AU^{6>eYx>CA>In&Lx0b%&KX{ zB==EyTVLxo%Il@<{>c?OB!g+FxcnzCd7IKL1Vv{6DjP4zip;r-43RfN)@xg?wR`nF z-uxa^Y=lX90qk6Uc;bv$v%*?PhV!fC5QaGbOiG_M4V&!_1E|LJ4MsRWG_5^;P3Ow@ z4gyMuosvt9FYUviRGlj>yc`R1L+9g0?cQ)t#Q7?*2i0Tg1|qD^jJ4T1sh`E@uOTD1 zGRD?!(a8&#?A7&AI)XL@?Y3LFcA`4&4#2K^E01hdH_2uut>Y&R^Y?T4)4-2+8~2tE z=GW={x_~w%u-`l&)qDe$#3``?HYtDw5pA!3mg0ChAvX;owkd;x(Ka7G-yG@rD6KN7 zTT~+{>>6mjT7%tby%T*RZ=2Z7we=Z*_I&^t`E*(w_J*}yO9KJCgrI`Tfk=W z6td{K9hw373_-QgAyN=ei#F}#=@aix4|^{p7lf0-#dvEI0v5m*tEvX6J&oFWANnfa zE?U|b^s*uPUOAy`@O4RNZOf(xS-Aqa)gF2RJC-U?V( zi}=T6#E)4xFRBDQ`|MU@o;$O2FN)M{c-T7@3? zjt8qaISKF_Y;jM*Y+!1XEpGl(*druHyB6!j54g6dH31CS7SH%vNRXu}X;>hm(W&T@ ztt}E}!iXf9?KFo2;UMvFmF;o@J3Kw&UjCvc_$)gyK_}}wfT5yYO`?}m&5jH8poaVs zx9cs-6Dj?}P0)QEacX95f?5w$H@Nv zWdD8qT|M-#cOL)jro&(azv)hGltLJmC)@iPsC_jYuYa}=8Q1xV*mmIvv-;P(u5t== zENmQ^;H*zotDjPcPBatAvU#(9^37uHh}wW@?5}jQ!+cXf<180|;yCJT$kj-dHsPA7 z`+2T2`+Xk)Lp=~h@0R{cUy@sFu{EEovPpc+dm3@&*=F`Yz9@mAl(^RVTaQ`1AwbUm z?rYMc6RCB}G@Xb}2gZ3X;AopseMf35eldF8P>-$bO=P;KPrWO@pDVGTk4PKG6h(KY z{}Z(FLrU|m_at8}GHh&(Pp_<5&KsQ<6b(AXH#pAV$i>lU3rDkT1}1eA*wa=-jAR2% zY**EDvtoP_XS!+biph62E-%i7kA<5gOLyV$Vr0?2H&eInei7>1YU}ZNR29U5%YVpP z$;pD0sZJBAiTi3nM&1F(<#6gwzFKT=MtX6KtNQ!!$KZ>-p3qz=2O?yR&??mSMnBD+ zQl^#Cg`{KAm#o;GvG!)yjc6X>%{<77!nyA7l#V^Ms;0;%Pxdxbs&99o?jtM)5n+AxWDv@=!#O39T)qR4Ff*!q5usXC< zwgbLxQu8)f-D%<6&fc(o7{bSvrVH4(Les`*$SJ&&$j7n@Vf;D~s+cL(q|XXNu0uIb zuD$#soHXug<)|bttWg2e@_0%98gR29_KINuk}A?H<;1=`Cp5bee%lEf&}I~OtZQW231$;JV0!AVfD$vnaML@N zNCn{Z{9B7Ul)?-qF&@>DL#RB#c9q}Jnt4)!Ra_t?yYx2yEkuBK)i%mpO3bw+B<4jqwmsYz~RiY!$T~8_LM+f2T z0;k%@kN;i1_myW?R@p2F=ej%UpYB8&S7dKVbwt6@)sYxan1t#4=C5Y#VvT@vSm|CO z4SwFz6Q9D1&<#+zJme;DBfU03kI!yMvZpeWpo4yNE{a`dE^ahbdF)*Ypa#q-qwWH@ zH>xr-aIgqHhgiFu{Wjh6NWi_(=p8m=*|x%R{xHerQB6F z4_#QaFRbuhSfKIJhdwYVKkb>M$|LEb6-vozXOwJ_RG0W{GeE#GJ$YJ9v)MCf0JD=^ zS%T`5-(cvD->=GKo8~Hyk)hse^SUxE;r2Q@TLVULw(w?@>zn+E5#(c{+_z8S!4p|^rxvw{v)kh?u^L68Gcd&$&<_@r2@w| z)Ta-8&8&LYwW>amoU&rreI_ z$=PL=BdVDVm42xx7(rzcc}I!RmBR#dul#|Z5PDur06yT^cMr#DJh84By^hYaaQys2 zuC=mRe%*;v2n9GRmh1C~4rW^i*`(Nv5#oa)yyxeND&@>rq@kF4jYy@d>C{salGDu| zh%ccEac>4B9uPw+oiyb1!(6%usx6!!sbDE4!G<>35w@`Gd!<_$HD;>n=#kMKzwGuk z>AvCK&$)3vA$K+@;~1aD0lR_jqDl(K=7zB`RWTVA)EfZn-1%AaQ_<9K*~lqK5$17rbQ(L6!4Z`Nh+A#u5LJd}(Y%G{lOjFC7mo4y*Q?1=*HnC1 zD<;r13)5?GNWde`*BJ-%6`qNo%;?GLRx#{>pkac>&>;(>UP@zdsS-iV`9kKmNv4!DeX;NbQVdW9Skta4ToVE~j z@^1X0NErdOqm_GQqR0Xx5&`p606zAFMzgHoM^ICw%) zMMFBnB@fjy;ZrhI`NCqpN6f?Hk}bQKYsIzILpP3m>{8WoGdQQu_%ZM5et)K1xZ=CS zpA*$&MHyT+gpSH9HPbt*N-BYUO0#D^1NW2PZSG~wLeCK+3P+Nni1NX6-F%h}|%f%pl{hB+Gg?^~J>NJ#79fB>p}GP91Sj5gT%;?qYY-i$)#X zC3~uJ`U>kVrf2T69YB~;tj~H;^81++Z7i*~6j$Bc`ue+F6n!p0ht>~z-LRMp%;_h# zMu!_pm@Z!4lajL~UEcGvj$2n~CW4 zs4d3bvB#}H{eKDd{a<#%e+_)!;pxB*o5yY0&@lzi!fY}4=F6c3HGB2fc5|1@X=@U7 z4>lWy4_Proxq4>den1E)k%ELQw`>rIn$6H!0>ZVBj1*%-N2N7=-KU_me(?0@RCV_2bEH{;)PrY}bDN4QPFN*@ z%v+wRC`2OH46U^$0!$McI0!H4&RLXoo6Snx;+}+i;1Gh4J=YD#+qMQ0|4^L;D! z)Ux~D(fRz;R^+l20snHtvOtt4jLv*?^RLzcuRq)<-SQibGVRX}x2i2cml8{g1-zy6 zdr^q7*tZ~nMxZf2Yi+21or+Whcbi8!A|WOiu#0yUNpV+z`^^;CsRYN!bv7@}R#&1o zLBHn?AsK+m-)Dc>ylDJETVN-ButMFZLkV6vN`oHA>gMBOOuK}%ri?^+&0Z%vo~j3; zx#)4xWJlg!Iqf?ROEp9IbT+$E3vqhIq=MOHBg5zBGmNP&uv-)DZ8+q)!pForok|~9 zEgBcyRW0s5I321}H_49FtQoOr`%a{BJOwODVTodV@_-rU>pf+c@fTymfC^*)vOPnB z7w70Zvba#vcg6UAS1KpQ^pSCx`DvM=_)R}EZpW0MJ6agG`XO|wsa)Pn+wfRec`Z6e zwI$vX)g3JI<^-j!W#cTb;k#@Cn5#FrV7JE6>k-43G{3&+qrQ6%t%|ZX53+lPFH0vh z3Z3Z~60sq*eSUlp5FgDpVZLQUwE&VB0<3Ltab)#*ViVg%1{^;*LqNU?AG`qQ8}s+fiB}r`4P@r$suTZk&PLlfG*@B|a@1z4 zZSHIwq;%8c1d=xQ$Y^c*eE7A{z46UoVa}L^>o4`26U=2dR#e{syrpoGUisqK?hB^5 zsS}^otao~KCsvV3Fc|HM+A6E?$h&)nF;wGo8i97d0>nPhNZiWe1o^qUh>DbVdm8HD z@M3*M8&F0yN=3sJ%JHE&!%&&}T(A;Za@XP0)BzrFs7~weDqzm&$MAa?`N1NyZ5@#o zp9@#iUf;Sl?K*HvzZX9@XbQxNW0OcKM6%(!t#!LyYVY2MrR&uBq3p7588KyYxcga` zVoQhqsAp3YfK1YKu91P-SI=OYdL&cP_NP?z+W^L%Qd}2cGv6F6Z2tLl%E(!UIM&uy z$0>c537|wrY64J*KMu^;w0R|s0ZCDtq@dOIwu$@yi4HS6-@dl@ zbZ_9qdlmkeAx;@9H)>#HBuP~)xpeCAl$RE0ky1%LP3)4isJoEY7lF0rjHFtwJ#p_! z^3%`qwRU@!lbcwRiLCGW97;zLr{PiGK#0~rg^-l62(kU$8sqyMPw#`?9&eRcx-@cC zT?k(^Cmq4|{mu1y(85eL+`TL0jRp|(0;{n*EISYd>BZZ~Nlvo>O%^?BPbTd2Zzos= z&IGI6h5Ca@1GBLy3LR;*O!cQc&ctj(~HczBS+paG08BqIO=fa}}kLv6TD<6HE$VpruN;#G=5-+ETw3YV|W}M%cTE{-sPa z&jKh(re8eO>Xc`cdrsfIq_j7y%61PI<}+)Dd!r?dXgrsUX*}Gx$#&tj?ZSC}z@#(Q%iVCfb={6oe9kL3M)NlO=q7&2_~l?fqN3ML3gd>T+})<%7P%wQyNn3WXSySwXh zaAz{NuJBBX3}dx-M)nJVZQZ)WH&6nJg+;Axb|$v7*)W-TrOCL+=Tk?aTgJ1I8QsVv zjJgR`X~n-$!CkbF92Hs=o;S0g?8SoOA}y${QtjGCV~tnQ09n}YdB&dS5cm#@zsQxX zyl*;FHddumlzerSZn(qT7NQgmsOWaZs9)?()sKwP~gj77(33Y|)J5YqZ@t*}GtRy1-Z8c#D~iTt_OLw3uE9H}s-l zz}h+zV#`X_LGZOG2HfTll@AL1INx-Kge?&QSp5q*W{q^|VOVP@AZQNwVn7B}z!UmA3_ zC3EPBuGc7j`@!Ugvmt(#qj7ULHn^Ri{op&bFmk`QxbmehJhxcJvN?f4z1LV9ZEfQh z?5Lefv5D9prg>sy(6ef$(HQq}K_dp0n;2q5=UJlbsC2wA94)o!@o`)9+3FS>UGvVf z=Yz)Fb&B_by-)~ZB(4JDU5Y3F-OK;`?Ef12oC*Fi@<2Vd(pSJxJ8aIxZyblJmn@By zYRTYD{liE`s5hw}E?gh=3g$Q8rFF?Kd;xkL`$Cw@t!1FB2C?9T;^&y9@3p*XcoW);$ zYPhv!PcO7$Sp6JUU1z&plJI_BNw%pI(M!I^KNTQ6+~{j1082M}pZp;23ZF?~PFJfm z-Raa}<>WJv^4tSA#kq=2^ZVX&118?=4?9YLeB5Vz(7!iye}4TevsfDM#E+**V=s57 zs;cnm0h%-0{B9j8>Na#{_l-8<3@KDC=u@Y3`Ux6_(+LlU}em=W1s!cE(&Sf&j@RB{(QW3jXk@C4O+Cj}0 zy^34OVKz_D`bTA3j!wb41iN;Kom(2z z&D!BU=V>_OE|WA=nCh0kGG;n9_7#!lcc(kg4vv`ZUgIs?J+QXw&XY7`=IXmp)nEJJ z9fi?p`aW}v+MIO_my3!vN^d%s^X6K0&J5K*$->)>;18zB3a3Yh1A`0!)AmPGY1zJt z`vU5o@bnZll{lp(+ebe=7&q9DA;ZU%FiMLm`RH$t2VRwJ1g@1e1wC|?yU z+r~U|AOVW=#MIo|%l`T`CdJ^JUo>LfBIB7U~02&xx5bDxN_1>V5AYsVrNbhb!vHRn`vb8REdS%l^ zCM`U?Nfg(3hagI5@&p6&dryJy;Sh9puhcB;UdXaSb%Y1-T!3GQ3{ul;OityuV}(yc?;*C$(c4uK-kuNcW2g`>6Onsk(%A*!-eQ$-+lN6hT%(EV@zc`3*E4?_UFk%4=F_RMugY2yD= z+SSK1x&D8h>h$2qw71fYF%=sphS+9iMqz}F z;?OZ6He0qlKND&~Ci>mJefxep{m$?8>->KEWA}C6ulw4r>vMhX>%Okf=l%J-pP%Ba zF)-584-z7Iq#7PF6c-<)bV0J!1fHB{Vn+g4=o=jM2tH~uxp%i@ET71$vKXwTz=06M(pNtHl!}b6~IKbl3 zM$bJE7U8IP#9TI9p`j$~2BL~XA3h9E#Yf!)+{cDbo$Ie!Y+7{d!I#|i#ZUy+c39@2 zJzY=t12ja6OZ`Xh*VZq&TyLL*Pw^>xseRV)M;UG)Z9ivdXGuXfDPV)s$Gl|{>OBq7 zo-=Wcw&k?wcn<@rOA^xP(UilL1X`>DR(B*MWIKz8)`K9CCBV2-M)+xmB|y+{N`#N>wR{xtvbh!J z#!zHU+EwKCz0EqG?OZ}i0~;(;WHM2Je<8+sRJ{A?s@baIUFFrj)j^%!&Q8Ocw$3!C zawhd~4O#@JIjlCd*oxDgwFa6nmr1yM4p>WMqg{m6|~Jbq&5kQ3P_Qv=*skdHJtMh)fQ}_S%H*} z44c$)=ZqHhbU~dTkX~}#7~XvrXCBT$+b-VQr1g#Xt(RvK*g$|>09L1K8u^U}KZ@vo z`o61d!K=-UEvhiOC04v&mE~$cszwx*5lFeGNTPexmApV8HlcAO0Vb!48K^jAV-B~FfZsr?!7ZBdbj7_TP8l1`{(~|m$)?5 zI~acbK~L-Uj4H;ih5+my{!MR6Z-Seb@lws9*BA}vSa!J)WJ(lCJxq&^U<~ncQ=Q*y zthBv7u@9rjj9u&UX%~sm)<*Oh&gub{m3q^a*3&*-cjD+H#(CVz^eIHCrlHNzw5rOa zCbJ{04Jcxc-n|1~#$bIegujuj4&Wo){@djH_ijxxKP&rOj(Y>D49O!-hn{vcZUphB zyvD8ToU!gkFEg6nsuVPf|Fsog-@gMyy6#{@zS?h_TDHF2%{24yrI1jDYOrRoP2U() zzY3F@3|Ri`M^5irlWqdQ4gbOmg(^|DJsCTiG?t0_W1VgW_>^7lfafA^v>7ZL@c&?L z`0l`%c^*q?d5Q;rL+NW_2Wa)=xiedn4(t&|7@T@rE-1YaCTPwLp`30oRQGz)MAZ!| zP~2=g`FL4$Ogtz10^HsafPXuU>)#kmblG3jiRsBaYJcj>D67xqwWYh~^gViHkR31K z0H}Lh?#e(78x}Dtnp)e!K8c4+TXgI-vG-@l={5m4NeIO`!pC5>;uoQHcUIS^JM-o5MBuUmGc9sY+dHqTeG-lFWSeZg79IP zRg5HW?SS86G@cgwihHFSS#b-C=DNO`-DJ6pP^E5q5h^9*sfI(Ob?BHi^b)JAAC=LK znVVvhJyK)zFh|JWi4tT_+}$!eGhCIldcU3)8;fAW&@fWg>j{_E!GuEu0Dzya59H1C z{4xi_=UxB$m(#~un;vhBS=!JqF1QQJ!54AyU^5cVpO+TsT85F#nwGwC_lVf?A&6yy zAj0+{xgW7%&M1w7`T)_f2I7_QJ^g~ZU%X|^unzn#nuEQ5WHvDZpqnDG-ue5W≈mYj-09FIgy2}|lGIxi9qK}ifr8cSQRKG1Sfg_G) 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 IS_Dx32X~#d#{d8T diff --git a/public/images/dev-tools/remix.png b/public/images/dev-tools/remix.png deleted file mode 100644 index 279655d0e943fb34bd6381a8f6adb5797effcbd4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2548 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 diff --git a/public/images/dev-tools/tenderly.png b/public/images/dev-tools/tenderly.png deleted file mode 100644 index 58d990ce253c8bc33f2c704a5ca47d8fe6b5474f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38108 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 diff --git a/redirects.config.js b/redirects.config.js index 8b4aff91e3a..2414f70569a 100644 --- a/redirects.config.js +++ b/redirects.config.js @@ -36,7 +36,9 @@ module.exports = [ "/developers/docs/consensus-mechanisms/pow/mining/", ], ["/beginners", "/what-is-ethereum/"], - ["/build", "/developers/learning-tools/"], + ["/build", "/developers/apps/education/"], + ["/developers/learning-tools", "/developers/apps/education/"], + ["/developers/local-environment", "/developers/apps/"], ["/eth2/beacon-chain", "/roadmap/beacon-chain/"], ["/eth2/the-beacon-chain", "/roadmap/beacon-chain/"], ["/upgrades/the-beacon-chain", "/roadmap/beacon-chain/"], diff --git a/src/components/LearningToolsCardGrid.tsx b/src/components/LearningToolsCardGrid.tsx deleted file mode 100644 index cfecd3ea24e..00000000000 --- a/src/components/LearningToolsCardGrid.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { LearningToolsCardGridProps } from "@/lib/types" - -import ProductCard from "./ProductCard" - -const LearningToolsCardGrid = ({ products }: LearningToolsCardGridProps) => ( -

- {products - .sort(({ locales }) => (locales?.length ? -1 : 0)) - .map(({ description, ...product }) => ( - - {description} - - ))} -
-) - -export default LearningToolsCardGrid diff --git a/src/components/ProductCard.tsx b/src/components/ProductCard.tsx deleted file mode 100644 index 1f6a99a3180..00000000000 --- a/src/components/ProductCard.tsx +++ /dev/null @@ -1,142 +0,0 @@ -import type { ImageProps } from "next/image" -import type { ReactNode } from "react" - -import { cn } from "@/lib/utils/cn" - -import { ButtonLink } from "./ui/buttons/Button" -import { Center, Flex, HStack } from "./ui/flex" -import { Tag } from "./ui/tag" -import GitStars from "./GitStars" -import { Image } from "./Image" - -import { useTranslation } from "@/hooks/useTranslation" - -type SubjectBadgeProps = { - subject: string - children: ReactNode -} - -const SubjectBadge = ({ subject, children }: SubjectBadgeProps) => { - const backgroundProp = () => { - switch (subject) { - case "Solidity": - return "warning" - case "Vyper": - return "tag" - case "web3": - return "success" - case "JavaScript": - return "error" - case "TypeScript": - return "tag" - case "Go": - return "tag" - case "Python": - return "error" - case "Rust": - return "warning" - case "C#": - return "tag" - case "Java": - return "error" - default: - return "normal" - } - } - return {children} -} - -export type ProductCardProps = { - children?: ReactNode - url: string - background: string - image: ImageProps["src"] - name: string - description?: ReactNode - note?: string - alt?: string - githubUrl?: string - subjects?: Array - githubRepoStars?: number - githubRepoLanguages?: Array - hideStars?: boolean - priceType?: string -} - -const ProductCard = ({ - url, - background: bgProp, - image, - name, - description, - note = "", - alt = "", - children, - githubUrl = "", - subjects, - githubRepoStars = 0, - githubRepoLanguages = [], - hideStars = false, - priceType, -}: ProductCardProps) => { - const { t } = useTranslation("common") - - return ( - -
- {alt} -
- - {githubRepoStars > 0 && ( - - )} -

0 ? "mt-8" : "mt-12" - )} - > - {name} -

- {description && ( -

{description}

- )} - {note.length > 0 && ( -

Note: {note}

- )} - {children &&
{children}
} -
- - {subjects && - subjects.map((subject, idx) => ( - - {subject} - - ))} - {priceType && ( - {priceType} - )} - {githubRepoLanguages.length > 0 && - githubRepoLanguages.map((name, idx: number) => ( - - {name.toUpperCase()} - - ))} - - - {t("open")} {name} - -
- ) -} - -export default ProductCard diff --git a/src/data/frameworks.ts b/src/data/frameworks.ts deleted file mode 100644 index a49e6407df7..00000000000 --- a/src/data/frameworks.ts +++ /dev/null @@ -1,87 +0,0 @@ -import type { Framework } from "@/lib/interfaces" - -import EthDiamondBlackImage from "@/public/images/assets/eth-diamond-black.png" -import FoundryImage from "@/public/images/dev-tools/foundry.png" -import HardhatImage from "@/public/images/dev-tools/hardhat.png" -import KurtosisImage from "@/public/images/dev-tools/kurtosis.png" -import ScaffoldEthImage from "@/public/images/dev-tools/scaffoldeth.png" - -export const frameworksList: Array = [ - { - id: "Kurtosis Ethereum Package", - url: "https://github.com/kurtosis-tech/ethereum-package", - githubUrl: "https://github.com/kurtosis-tech/ethereum-package", - background: "#000000", - name: "Kurtosis Ethereum Package", - description: - "page-developers-local-environment:page-local-environment-kurtosis-desc", - alt: "page-developers-local-environment:page-local-environment-kurtosis-logo-alt", - image: KurtosisImage, - }, - { - id: "hardhat", - url: "https://hardhat.org/", - githubUrl: "https://github.com/nomiclabs/hardhat", - background: "#faf8fb", - name: "Hardhat", - description: - "page-developers-local-environment:page-local-environment-hardhat-desc", - alt: "page-developers-local-environment:page-local-environment-hardhat-logo-alt", - image: HardhatImage, - }, - { - id: "brownie", - url: "https://github.com/eth-brownie/brownie", - githubUrl: "https://github.com/eth-brownie/brownie", - background: "#ffffff", - name: "Brownie", - description: - "page-developers-local-environment:page-local-environment-brownie-desc", - alt: "page-developers-local-environment:page-local-environment-brownie-logo-alt", - image: EthDiamondBlackImage, - }, - { - id: "createethapp", - url: "https://github.com/PaulRBerg/create-eth-app", - githubUrl: "https://github.com/PaulRBerg/create-eth-app", - background: "#ffffff", - name: "Create Eth App", - description: - "page-developers-local-environment:page-local-environment-eth-app-desc", - alt: "page-developers-local-environment:page-local-environment-eth-app-logo-alt", - image: EthDiamondBlackImage, - }, - { - id: "scaffoldeth", - url: "https://scaffoldeth.io/", - githubUrl: "https://github.com/scaffold-eth/scaffold-eth-2", - background: "#ffffff", - name: "Scaffold-ETH-2", - description: - "page-developers-local-environment:page-local-environment-scaffold-eth-desc", - alt: "page-local-environment-scaffold-eth-logo-alt", - image: ScaffoldEthImage, - }, - { - id: "soliditytemplate", - url: "https://github.com/paulrberg/solidity-template", - githubUrl: "https://github.com/paulrberg/solidity-template", - background: "#ffffff", - name: "Solidity template", - description: - "page-developers-local-environment:page-local-environment-solidity-template-desc", - alt: "page-developers-local-environment:page-local-environment-solidity-template-logo-alt", - image: EthDiamondBlackImage, - }, - { - id: "foundry", - url: "https://getfoundry.sh/", - githubUrl: "https://github.com/foundry-rs/foundry", - background: "#ffffff", - name: "Foundry", - description: - "page-developers-local-environment:page-local-environment-foundry-desc", - alt: "page-developers-local-environment:page-local-environment-foundry-logo-alt", - image: FoundryImage, - }, -] diff --git a/src/intl/ar/page-developers-learning-tools.json b/src/intl/ar/page-developers-learning-tools.json deleted file mode 100644 index 337920e89c2..00000000000 --- a/src/intl/ar/page-developers-learning-tools.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "دورة BloomTech Web3 سوف تعلمك المهارات التي يبحث عنها أرباب العمل لدى المهندسين.", - "page-learning-tools-bloomtech-logo-alt": "شعار BlommTech", - "page-learning-tools-bootcamps": "معسكرات تدريب المبرمجين", - "page-learning-tools-bootcamps-desc": "دورات مدفوعة عبر الإنترنت لتحصل على أحدث التطورات بسرعة.", - "page-learning-tools-browse-docs": "تصفح المستندات", - "page-learning-tools-capture-the-ether-description": "Capture the Ether (احصل على عملات الإثير) هي لعبة تقوم فيها باختراق عقود إثيريوم الذكية للتعرف على الأمان.", - "page-learning-tools-capture-the-ether-logo-alt": "شعار Capture the Ether", - "page-learning-tools-coding": "تعلم عن طريق البرمجة", - "page-learning-tools-coding-subtitle": "هذه الأدوات ستساعدك على تجربة إيثيريوم إذا كنت تفضل تجربة تعلم أكثر تفاعلية.", - "page-learning-tools-consensys-academy-description": "معسكر تدريبي لمبرمجي إثيريوم على الإنترنت.", - "page-learning-tools-consensys-academy-logo-alt": "شعار ConsenSys Academy", - "page-learning-tools-cryptozombies-description": "تعلم لغة Solidity من خلال بناء لعبة زومبي خاصة بك.", - "page-learning-tools-cryptozombies-logo-alt": "شعار CryptoZombies", - "page-learning-tools-documentation": "تعلم بالتوثيق", - "page-learning-tools-documentation-desc": "هل ترغب في معرفة المزيد؟ انتقل إلى توثيقاتنا للعثور على التفسيرات التي تحتاج إليها.", - "page-learning-tools-eth-dot-build-description": "بيئة اختبار معزولة تعليمية لشبكة web3، بما في ذلك برمجة السحب والإفلات وكتل البناء مفتوحة المصدر.", - "page-learning-tools-eth-dot-build-logo-alt": "شعار Eth.build", - "page-learning-tools-ethernauts-description": "أتم المستويات بقرصنة عقود ذكية.", - "page-learning-tools-ethernauts-logo-alt": "شعار Ethernauts", - "page-learning-tools-metaschool-description": "أصبح مبرمجًا للإصدار الثالث من الويب من خلال إنشاء التطبيقات اللامركزية وشحنها.", - "page-learning-tools-metaschool-logo-alt": "شعار metaschool", - "page-learning-tools-game-tutorials": "تعليمات استخدام الألعاب التفاعلية", - "page-learning-tools-game-tutorials-desc": "تعلم وأنت تلعب. هده التعليمات البرمجية تمكنك من الحصول على الأساسيات باستخدام اللعب.", - "page-learning-tools-meta-desc": "أدوات البرمجة القائمة على الويب وتجارب التعلم التفاعلي لمساعدتك على تجربة تطوير إثيريوم.", - "page-learning-tools-meta-title": "أدوات تعلم المبرمج", - "page-learning-tools-questbook-description": "تعليمات استخدام ذاتية تحديد السرعة لتعلم Web 3.0 من خلال الإنشاء", - "page-learning-tools-questbook-logo-alt": "شعار Questbook", - "page-learning-tools-remix-description": "طوّر العقود الذكية في اثيريوم وانشرها وأدرها. اتبع تعليمات الاستخدام مع ملحق LearnEth.", - "page-learning-tools-remix-description-2": "Remix وReplit وChainIDE ليست مجرد بيئات اختبار معزولة — العديد من المبرمجين يكتبون ويجمعون وينشرون عقودهم الذكية باستخدامها.", - "page-learning-tools-replit-description": "بيئة تطوير قابلة للتخصيص لإثيريوم، مع فعالية التحميل، والتحقق من الأخطاء، ودعم قوي لشبكات التجريب.", - "page-learning-tools-chainIDE-description": "ابدأ رحلتك إلى Web3 بكتابة العقود الذكية لإثيريوم باستخدام ChainIDE. استخدم القوالب المدمجة للتعلّم وتوفير الوقت.", - "page-learning-tools-chainIDE-logo-alt": "شعار ChainIDE", - "page-learning-tools-tenderly-description": "Tenderly Sandbox هي بيئة نموذجية حيث يمكنك كتابة العقود الذكية وتنفيذها وتصحيحها في المتصفح باستخدام سوليديتي وجافا سكريبت.", - "page-learning-tools-tenderly-logo-alt": "شعار Tenderly", - "page-learning-tools-replit-logo-alt": "شعار Replit", - "page-learning-tools-remix-logo-alt": "شعار Remix", - "page-learning-tools-sandbox": "إنشاء النص البرمجي لبيئات الاختبار المعزولة", - "page-learning-tools-sandbox-desc": "إن بيئات الاختبار المعزولة هذه ستعطيك مجالاً للتجريب وكتابة العقود الذكية وفهم إثيريوم.", - "page-learning-tools-speed-run-ethereum-description": "Speed Run Ethereum هي مجموعة من التحديات لاختبار معرفتك بلغة سوليديتي باستخدام Scaffold-ETH", - "page-learning-tools-speed-run-ethereum-logo-alt": "شعار Speed Run Ethereum", - "page-learning-tools-studio-description": "بيئة تطوير متكامل قائمة على المتصفح حيث يمكنك تتبع تعليمات الاستخدام لبناء واختبار العقود الذكية، وبناء الواجهة الأمامية لها.", - "page-learning-tools-vyperfun-description": "تعلم بناء Vyper وأنت تبني لعبة البوكيمون الخاصة بك.", - "page-learning-tools-vyperfun-logo-alt": "شعار Vyper.fun", - "page-learning-tools-nftschool-description": "استكشف ما يحدث مع الرموز غير القابلة للاستبدال أو NFT من الجانب الفني.", - "page-learning-tools-nftschool-logo-alt": "شعار مدرسة NFT", - "page-learning-tools-platzi-description": "تعلّم كيفية إنشاء تطبيقات لامركزية على Web3 وأتقن جميع المهارات اللازمة لتكون مبرمج سلسلة الكتل.", - "page-learning-tools-platzi-logo-alt": "شعار Platzi", - "page-learning-tools-alchemy-university-description": "طوِّر حياتك المهنية في Web3 من خلال الدورات التدريبية والمشاريع والتعليمات البرمجية.", - "page-learning-tools-alchemy-university-logo-alt": "شعار Alchemy University", - "alt-eth-blocks": "صورة توضيحية لكتل منظمة على شكل شعار ETH" -} \ No newline at end of file diff --git a/src/intl/ar/page-developers-local-environment.json b/src/intl/ar/page-developers-local-environment.json deleted file mode 100644 index 439b2c32988..00000000000 --- a/src/intl/ar/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "إطار عمل للتطوير والاختبار قائم على Python للعقود الذكية التي تستهدف جهاز إثيريوم الظاهري.", - "page-local-environment-brownie-logo-alt": "شعار Brownie", - "page-local-environment-kurtosis-desc": "مجموعة أدوات قائمة على الحاوية لسهولة تكوين شبكة تجريب اثيريوم متعددة العملاء وتثبيتها لتطوير التطبيقات اللامركزية المحلية ونمذجتها الأولية وتجربتها.", - "page-local-environment-kurtosis-logo-alt": "شعار Kurtosis", - "page-local-environment-epirus-desc": "منصة لتطوير تطبيقات سلسلة الكتل ونشرها ومراقبتها على جهاز جافا الظاهري.", - "page-local-environment-epirus-logo-alt": "شعار\tEpirus", - "page-local-environment-eth-app-desc": "إنشاء تطبيقات تعمل بتشغيل إثيريوم بأمر واحد. يأتي مع عرض واسع لأطر واجهة المستخدم وقوالب DeFi للاختيار منها.", - "page-local-environment-eth-app-logo-alt": "إنشاء شعار تطبيق إثير", - "page-local-environment-foundry-desc": "مجموعة أدوات فائقة السرعة ومحمولة ونموذجية لتطوير تطبيقات إثيريوم مكتوبة بلغة رست.", - "page-local-environment-foundry-logo-alt": "شعار Foundry", - "page-local-environment-framework-feature-1": "الميزات لتدوير مثيل سلسلة كتل محلي.", - "page-local-environment-framework-feature-2": "أدوات مساندة لتجميع واختبار العقود الذكية الخاصة بك.", - "page-local-environment-framework-feature-3": "إضافات وتطوير العميل لإنشاء تطبيق موجه للمستخدم الخاص بك داخل نفس المشروع/المستودع.", - "page-local-environment-framework-feature-4": "التكوين للاتصال بشبكات إثيريوم ونشر العقود، سواء كان ذلك على سبيل التشغيل المحلي، أو على إحدى الشبكات العامة في إثيريوم.", - "page-local-environment-framework-feature-5": "توزيع التطبيق اللامركزي - التكامل مع خيارات التخزين مثل IPFS.", - "page-local-environment-framework-features": "وتأتي هذه الأطر مع الكثير من الوظائف غير المألوفة، مثل:", - "page-local-environment-frameworks-desc": " نوصي باختيار إطار عمل، خاصة إذا كنت فقط قد بدأت. بناء تطبيق كامل يتطلب قطع مختلفة من التكنولوجيا. تتضمن أطر العمل العديد من الميزات المطلوبة أو توفر أنظمة إضافات سهلة لاختيار الأدوات التي تريدها.", - "page-local-environment-frameworks-title": "أطر وحزم مصنوعة مسبقًا", - "page-local-environment-hardhat-desc": "Hardhat هو بيئة تطوير إثيريوم للمهنيين.", - "page-local-environment-hardhat-logo-alt": "شعار Hardhat", - "page-local-environment-openZeppelin-desc": "توفير ساعات من وقت التطوير عن طريق تجميع وترقية ونشر وتفاعل مع العقود الذكية مع CLI لدينا.", - "page-local-environment-openZeppelin-logo-alt": "شعار OpenZeppelin", - "page-local-environment-scaffold-eth-desc": "Ethers + Hardhat + React: كل ما تحتاج إليه للبدء في إنشاء التطبيقات اللامركزية التي يتم تشغيلها بواسطة العقود الذكية.", - "page-local-environment-scaffold-eth-logo-alt": "شعار scaffold-eth", - "page-local-environment-setup-meta-desc": "دليل حول كيفية اختيار مجموعة البرامج الخاصة بك لتطوير إثيريوم.", - "page-local-environment-setup-meta-title": "إعداد التطوير المحلي لإثيريوم", - "page-local-environment-setup-subtitle": "إذا كنت على استعداد لبدء البناء، فقد حان الوقت لاختيار الحزمة الخاصة بك.", - "page-local-environment-setup-subtitle-2": "إليك الأدوات وأطر العمل التي يمكنك استخدامها لمساعدتك في بناء تطبيق إثيريوم الخاص بك.", - "page-local-environment-setup-title": "إعداد بيئة التنمية المحلية الخاصة بك", - "page-local-environment-solidity-template-desc": "قالب GitHub للإعداد المسبق البناء للعقود الذكية للغة Solidity الخاصة بك. يشمل شبكة Hardhat المحلية، ووافل للاختبارات، وعملات إثير لتنفيذ المحفظة، وأكثر من ذلك.", - "page-local-environment-solidity-template-logo-alt": "شعار قالب Solidity" -} \ No newline at end of file diff --git a/src/intl/bn/page-developers-learning-tools.json b/src/intl/bn/page-developers-learning-tools.json deleted file mode 100644 index 3c210936d39..00000000000 --- a/src/intl/bn/page-developers-learning-tools.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "BloomTech Web3 কোর্সটি আপনাকে শেখাবে যে দক্ষতা নিয়োগকারীরা ইঞ্জিনিয়ারদের জন্য খোঁজেন।", - "page-learning-tools-bloomtech-logo-alt": "BloomTech লোগো", - "page-learning-tools-bootcamps": "ডেভেলপার বুটক্যাম্প সমূহ", - "page-learning-tools-bootcamps-desc": "আপনাকে দ্রুত নিয়ে যেতে পেইড অনলাইন কোর্স।", - "page-learning-tools-browse-docs": "নথিসমূহ ব্রাউজ করুন", - "page-learning-tools-capture-the-ether-description": "ক্যাপচার দ্য ইথার এমন একটি গেম যেখানে আপনি নিরাপত্তা সম্পর্কে জানতে ইথেরিয়াম স্মার্ট কন্ট্র্যাক্ট হ্যাক করেন।", - "page-learning-tools-capture-the-ether-logo-alt": "ক্যাপচার দ্য ইথার লোগো", - "page-learning-tools-coding": "কোডিং-এর সাহায্যে শিখুন", - "page-learning-tools-coding-subtitle": "আপনি যদি আরও ইন্টারেক্টিভ শেখার অভিজ্ঞতা পছন্দ করেন তবে এই টুলগুলি আপনাকে ইথেরিয়াম নিয়ে পরীক্ষা করতে সহায়তা করবে।", - "page-learning-tools-consensys-academy-description": "অনলাইন ইথেরিয়াম ডেভেলপার বুটক্যাম্প.", - "page-learning-tools-consensys-academy-logo-alt": "ConsenSys Academy লোগো", - "page-learning-tools-cryptozombies-description": "আপনার নিজস্ব জম্বি গেম তৈরি করে সলিডিটি শিখুন.", - "page-learning-tools-cryptozombies-logo-alt": "CryptoZombies লোগো", - "page-learning-tools-documentation": "নথিপত্রের মাধ্যমে শিখুন", - "page-learning-tools-documentation-desc": "আরো জানতে চান? আপনার প্রয়োজনীয় ব্যাখ্যাগুলি খুঁজতে আমাদের নথিপত্রে যান।", - "page-learning-tools-eth-dot-build-description": "ড্র্যাগ-এন্ড-ড্রপ প্রোগ্রামিং এবং ওপেন-সোর্স বিল্ডিং ব্লক সহ web3-এর জন্য একটি শিক্ষামূলক স্যান্ডবক্স।", - "page-learning-tools-eth-dot-build-logo-alt": "Eth.build লোগো", - "page-learning-tools-ethernauts-description": "স্মার্ট কন্ট্র্যাক্ট হ্যাক করে স্তরগুলি সম্পূর্ণ করুন।", - "page-learning-tools-ethernauts-logo-alt": "Ethernauts লোগো", - "page-learning-tools-metaschool-description": "dApps তৈরি এবং শিপিং করে একজন Web3 ডেভেলপার হয়ে উঠুন।", - "page-learning-tools-metaschool-logo-alt": "_metaschool লোগো", - "page-learning-tools-game-tutorials": "ইন্টারেক্টিভ গেমের টিউটোরিয়াল সমূহ", - "page-learning-tools-game-tutorials-desc": "খেলার সময় শিখুন। এই টিউটোরিয়ালগুলি আপনাকে গেমপ্লে ব্যবহার করে মৌলিক বিষয়গুলির মধ্যে দিয়ে যায়।", - "page-learning-tools-meta-desc": "ওয়েব-ভিত্তিক কোডিং টুলস এবং ইন্টারেক্টিভ শেখার অভিজ্ঞতা আপনাকে ইথেরিয়াম ডেভেলপমেন্ট নিয়ে পরীক্ষা করতে সাহায্য করে।", - "page-learning-tools-meta-title": "ডেভেলপার শিক্ষার টুলস", - "page-learning-tools-questbook-description": "তৈরি করার মাধ্যমে ওয়েব 3.0 শেখার জন্য স্ব গতিসম্পন্ন টিউটোরিয়াল", - "page-learning-tools-questbook-logo-alt": "Questbook লোগো", - "page-learning-tools-remix-description": "ইথেরিয়ামের জন্য স্মার্ট কন্ট্র্যাক্টগুলি ডেভেলপ, স্থাপন এবং পরিচালনা করুন। LearnEth প্লাগইন সহ টিউটোরিয়াল অনুসরণ করুন।", - "page-learning-tools-remix-description-2": "Remix, Replit এবং ChainIDE শুধু স্যান্ডবক্স নয়—ডেভেলপাররা সেগুলো ব্যবহার করে তাদের স্মার্ট কনট্র্যাক্ট লিখতে, কম্পাইল করতে এবং স্থাপন করতে পারে।", - "page-learning-tools-replit-description": "হট রিলোডিং, ত্রুটি পরীক্ষা এবং প্রথম-শ্রেণীর টেস্টনেট সমর্থন সহ ইথেরিয়ামের জন্য একটি কাস্টমাইজযোগ্য উন্নয়ন পরিবেশ।", - "page-learning-tools-chainIDE-description": "ChainIDE-এর মাধ্যমে ইথেরিয়ামের জন্য স্মার্ট কন্ট্র্যাক্ট লিখে Web3-এ আপনার যাত্রা শুরু করুন। শিখতে এবং সময় বাঁচাতে বিল্ট-ইন টেমপ্লেট ব্যবহার করুন।", - "page-learning-tools-chainIDE-logo-alt": "ChainIDE লোগো", - "page-learning-tools-tenderly-description": "Tenderly Sandbox হল একটি প্রোটোটাইপিং পরিবেশ যেখানে আপনি সলিডিটি এবং JavaScript ব্যবহার করে ব্রাউজারে স্মার্ট কনট্র্যাক্ট লিখতে, সম্পাদন করতে এবং ডিবাগ করতে পারেন।", - "page-learning-tools-tenderly-logo-alt": "Tenderly লোগো", - "page-learning-tools-replit-logo-alt": "Replit লোগো", - "page-learning-tools-remix-logo-alt": "Remix লোগো", - "page-learning-tools-sandbox": "কোড স্যান্ডবক্স সমূহ", - "page-learning-tools-sandbox-desc": "এই স্যান্ডবক্সগুলি আপনাকে স্মার্ট কন্ট্র্যাক্ট লিখতে এবং ইথেরিয়াম বোঝার সাথে পরীক্ষা করার জন্য একটি স্থান দিবে।", - "page-learning-tools-speed-run-ethereum-description": "Speed Run ইথেরিয়াম হলো Scaffold-ETH ব্যবহার করে আপনার সলিডিটি জ্ঞান পরীক্ষা করার জন্য চ্যালেঞ্জের একটি সেট", - "page-learning-tools-speed-run-ethereum-logo-alt": "Speed Run ইথেরিয়াম লোগো", - "page-learning-tools-studio-description": "একটি ওয়েব-ভিত্তিক IDE যেখানে আপনি স্মার্ট কন্ট্র্যাক্ট গুলি তৈরি এবং পরীক্ষা করতে এবং তাদের জন্য একটি ফ্রন্টএন্ড তৈরি করতে টিউটোরিয়ালগুলি অনুসরণ করতে পারেন।", - "page-learning-tools-vyperfun-description": "আপনার নিজস্ব Pokémon গেম তৈরি করতে করতে Vyper শিখুন।", - "page-learning-tools-vyperfun-logo-alt": "Vyper.fun লোগো", - "page-learning-tools-nftschool-description": "প্রযুক্তিগত দিক থেকে নন-ফাঞ্জিবল টোকেন বা NFT গুলির সাথে কী ঘটছে তা অন্বেষণ করুন।", - "page-learning-tools-nftschool-logo-alt": "NFT school লোগো", - "page-learning-tools-platzi-description": "Web3-এ কীভাবে dapps তৈরি করতে হয় এবং ব্লকচেইন ডেভেলপার হওয়ার জন্য প্রয়োজনীয় সমস্ত দক্ষতা অর্জন করতে হয় তা শিখুন।", - "page-learning-tools-platzi-logo-alt": "Platzi লোগো", - "page-learning-tools-alchemy-university-description": "কোর্স, প্রজেক্ট এবং কোডের মাধ্যমে আপনার web3 ক্যারিয়ার ডেভেলপ করুন।", - "page-learning-tools-alchemy-university-logo-alt": "Alchemy University লোগো", - "alt-eth-blocks": "একটি ETH প্রতীকের মতো সংগঠিত ব্লকের চিত্র" -} \ No newline at end of file diff --git a/src/intl/bn/page-developers-local-environment.json b/src/intl/bn/page-developers-local-environment.json deleted file mode 100644 index 716a29e3709..00000000000 --- a/src/intl/bn/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "ইথেরিয়াম ভার্চুয়াল মেশিনকে লক্ষ্য করে স্মার্ট কন্ট্র্যাক্ট একটি পাইথন-ভিত্তিক ডেভেলপমেন্ট এবং পরীক্ষার কাঠামো।", - "page-local-environment-brownie-logo-alt": "Brownie লোগো", - "page-local-environment-kurtosis-desc": "দ্রুত স্থানীয় dApp ডেভেলপমেন্ট, প্রোটোটাইপিং এবং পরীক্ষার জন্য একটি মাল্টি-ক্লায়েন্ট ইথেরিয়াম টেস্টনেট সহজেই কনফিগার এবং স্পিন করার জন্য একটি ধারক-ভিত্তিক টুলকিট।", - "page-local-environment-kurtosis-logo-alt": "Kurtosis লোগো", - "page-local-environment-epirus-desc": "জাভা ভার্চুয়াল মেশিনে ব্লকচেইন অ্যাপ্লিকেশনগুলি ডেভেলপ, স্থাপন এবং পর্যবেক্ষণের জন্য একটি প্ল্যাটফর্ম।", - "page-local-environment-epirus-logo-alt": "Epirus লোগো", - "page-local-environment-eth-app-desc": "একটি কমান্ড দিয়ে ইথেরিয়াম-চালিত অ্যাপ তৈরি করুন। বেছে নেওয়ার জন্য UI ফ্রেমওয়ার্ক এবং DeFi টেমপ্লেটের বিস্তৃত অফার সহ আসে।", - "page-local-environment-eth-app-logo-alt": "Eth অ্যাপ লোগো তৈরি করুন", - "page-local-environment-foundry-desc": "রাস্ট-এ লেখা ইথেরিয়াম অ্যাপ্লিকেশন ডেভেলপমেন্টের জন্য একটি জ্বলন্ত দ্রুত, বহনযোগ্য এবং মডুলার টুলকিট।", - "page-local-environment-foundry-logo-alt": "Foundry লোগো", - "page-local-environment-framework-feature-1": "একটি স্থানীয় ব্লকচেইন মুহুর্তে স্পিন আপ করার ফিচারসমূহ।", - "page-local-environment-framework-feature-2": "আপনার স্মার্ট কন্ট্র্যাক্ট গুলি কম্পাইল এবং পরীক্ষা করার ইউটিলিটি সমূহ।", - "page-local-environment-framework-feature-3": "একই প্রকল্প/রিপোজেটরি -র মধ্যে আপনার ব্যবহারকারী-মুখী অ্যাপ্লিকেশন তৈরি করতে ক্লায়েন্ট ডেভেলপমেন্ট অ্যাড-অন।", - "page-local-environment-framework-feature-4": "ইথেরিয়াম নেটওয়ার্কের সাথে সংযোগ এবং কনট্র্যাক্টসমূহ স্থাপন করতে কনফিগারেশন, স্থানীয়ভাবে চলমান অবস্থায় বা ইথেরিয়াম-এর পাবলিক নেটওয়ার্কগুলির একটিতে।", - "page-local-environment-framework-feature-5": "বিকেন্দ্রীভূত অ্যাপ বিতরণ - IPFS এর মতো স্টোরেজ বিকল্পগুলির সাথে সমন্বয়।", - "page-local-environment-framework-features": "এই ফ্রেমওয়ার্কগুলি অনেকগুলি আউট-অফ-দ্য-বক্স কার্যকারিতার সাথে আসে, যেমন:", - "page-local-environment-frameworks-desc": "আমরা একটি ফ্রেমওয়ার্ক বাছাই করার পরামর্শ দিই, বিশেষ করে যদি আপনি সবেমাত্র শুরু করে থাকেন। একটি পূর্ণাঙ্গ dapp তৈরি করতে বিভিন্ন প্রযুক্তির প্রয়োজন হয়। ফ্রেমওয়ার্কগুলিতে প্রয়োজনীয় অনেকগুলি বৈশিষ্ট্য অন্তর্ভুক্ত থাকে বা আপনার ইচ্ছামত টুলস বেছে নেওয়ার জন্য সহজ প্লাগইন সিস্টেম প্রদান করে।", - "page-local-environment-frameworks-title": "ফ্রেমওয়ার্কগুলো এবং পূর্ব-তৈরিকৃত স্ট্যাক সমূহ", - "page-local-environment-hardhat-desc": "Hardhat পেশাদারদের জন্য একটি ইথেরিয়াম উন্নয়ন পরিবেশ।", - "page-local-environment-hardhat-logo-alt": "Hardhat লোগো", - "page-local-environment-openZeppelin-desc": "আমাদের CLI এর সাথে স্মার্ট কন্ট্রাক্ট কম্পাইল, আপগ্রেড, ডিপ্লোয়িং এবং ইন্টারঅ্যাক্ট করে কয়েক ঘন্টা ডেভেলপমেন্টের সময় বাঁচান।", - "page-local-environment-openZeppelin-logo-alt": "OpenZeppelin লোগো", - "page-local-environment-scaffold-eth-desc": "ইথার + হার্ডহ্যাট + রিয়্যাক্ট: স্মার্ট কনট্র্যাক্ট দ্বারা চালিত বিকেন্দ্রীভূত অ্যাপ্লিকেশনগুলি তৈরি করা শুরু করতে আপনার যা প্রয়োজন।", - "page-local-environment-scaffold-eth-logo-alt": "scaffold-eth লোগো", - "page-local-environment-setup-meta-desc": "ইথেরিয়াম ডেভেলপের জন্য আপনার সফ্টওয়্যার স্ট্যাক কীভাবে বাছাই করবেন তার নির্দেশিকা।", - "page-local-environment-setup-meta-title": "ইথেরিয়াম স্থানীয় উন্নয়ন সেটআপ", - "page-local-environment-setup-subtitle": "আপনি যদি বিল্ডিং শুরু করতে প্রস্তুত হন, তাহলে আপনার স্ট্যাক বেছে নেওয়ার সময় এসেছে।", - "page-local-environment-setup-subtitle-2": "আপনার ইথেরিয়াম অ্যাপ্লিকেশন তৈরি করতে সাহায্য করার জন্য আপনি যে টুলস এবং ফ্রেমওয়ার্ক ব্যবহার করতে পারেন তা এখানে রয়েছে।", - "page-local-environment-setup-title": "আপনার স্থানীয় উন্নয়ন পরিবেশ সেট আপ করুন", - "page-local-environment-solidity-template-desc": "আপনার সলিডিটি স্মার্ট কনট্র্যাক্টের একটি পূর্ব-নির্মিত সেটআপের জন্য একটি GitHub টেমপ্লেট। একটি Hardhat স্থানীয় নেটওয়ার্ক, পরীক্ষার জন্য Waffle, ওয়ালেট বাস্তবায়নের জন্য Ethers এবং আরও অনেক কিছু অন্তর্ভুক্ত।", - "page-local-environment-solidity-template-logo-alt": "Solidity template লোগো" -} \ No newline at end of file diff --git a/src/intl/cs/page-developers-learning-tools.json b/src/intl/cs/page-developers-learning-tools.json deleted file mode 100644 index 413c23d42f7..00000000000 --- a/src/intl/cs/page-developers-learning-tools.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "Kurz BloomTech Web3 vás naučí dovednostem, které zaměstnavatelé u inženýrů hledají.", - "page-learning-tools-bloomtech-logo-alt": "Logo BloomTech", - "page-learning-tools-bootcamps": "Vývojářské bootcampy", - "page-learning-tools-bootcamps-desc": "Placené online kurzy, které vás rychle uvedou do obrazu.", - "page-learning-tools-browse-docs": "Procházet dokumentaci", - "page-learning-tools-capture-the-ether-description": "Capture the Ether je hra, ve které se učíte o zabezpečení Etherea hackováním chytrých kontraktů.", - "page-learning-tools-capture-the-ether-logo-alt": "Logo Capture the Ether", - "page-learning-tools-node-guardians-description": "Node Guardians je gamifikovaná vzdělávací platforma, kde se web3 vývojáři setkají s úkoly s fantasy tématikou, které jim pomohou ovládnout programování v jazycích Solidity, Cairo, Noir a Huff.", - "page-learning-tools-node-guardians-logo-alt": "Logo Node Guardians", - "page-learning-tools-coding": "Učte se psaním kódu", - "page-learning-tools-coding-subtitle": "Tyto nástroje vám pomohou experimentovat s Ethereem, pokud dáváte přednost interaktivnějšímu vzdělávání.", - "page-learning-tools-consensys-academy-description": "On-line bootcamp pro vývojáře Etherea.", - "page-learning-tools-consensys-academy-logo-alt": "Logo ConsenSys Academy", - "page-learning-tools-cryptozombies-description": "Naučte se Solidity při vytváření vlastní zombie hry.", - "page-learning-tools-cryptozombies-logo-alt": "Logo CryptoZombies", - "page-learning-tools-dapp-world-description": "Ekosystém pro zvyšování kvalifikace blockchainu, včetně kurzů, kvízů, praktických cvičení a týdenních soutěží.", - "page-learning-tools-dapp-world-logo-alt": "Logo Dapp World", - "page-learning-tools-documentation": "Učte se pomocí dokumentace", - "page-learning-tools-documentation-desc": "Chcete se dozvědět více? Přejděte do naší dokumentace a najděte si vysvětlení, která potřebujete.", - "page-learning-tools-eth-dot-build-description": "Vzdělávací sandbox pro web3, včetně drag-and-drop programování a open-source stavebních bloků.", - "page-learning-tools-eth-dot-build-logo-alt": "Logo Eth.build", - "page-learning-tools-ethernauts-description": "Dokončete úrovně hackováním chytrých kontraktů.", - "page-learning-tools-ethernauts-logo-alt": "Logo Ethernauts", - "page-learning-tools-metaschool-description": "Staňte se vývojářem Web3 tím, že budete vytvářet a dodávat dappky.", - "page-learning-tools-metaschool-logo-alt": "_metaschool logo", - "page-learning-tools-game-tutorials": "Interaktivní vzdělávání hrou", - "page-learning-tools-game-tutorials-desc": "Učte se hrou. Tyto výukové kurzy vás provedou začátky, zatímco si budete hrát.", - "page-learning-tools-meta-desc": "Webové programovací nástroje a interaktivní získávání zkušeností, které vám pomohou experimentovat s vývojem na platformě Ethereum.", - "page-learning-tools-meta-title": "Vzdělávací nástroje pro vývojáře", - "page-learning-tools-atlas-logo-alt": "Logo Atlas", - "page-learning-tools-atlas-description": "Pište, testujte a publikujte chytré kontrakty během několika minut pomocí Atlas IDE.", - "page-learning-tools-questbook-description": "Tutoriály k Webu 3.0, kde vytváříte projekty vlastním tempem.", - "page-learning-tools-questbook-logo-alt": "Logo Questbook", - "page-learning-tools-remix-description": "Vyvíjejte, spouštějte a spravujte chytré kontrakty na Ethereu. Sledujte výukové kurzy s pluginem LearnEth.", - "page-learning-tools-remix-description-2": "Remix, Replit, ChainIDE a Atlas nejsou jen sandboxy – vývojáři v nich mohou psát, kompilovat a publikovat své chytré kontrakty.", - "page-learning-tools-replit-description": "Přizpůsobitelné vývojové prostředí pro Ethereum s okamžitým znovunačtením, kontrolou chyb a prvotřídní podporou testovací sítě.", - "page-learning-tools-chainIDE-description": "Začněte svou cestu na Web3 psaním chytrých kontraktů pro Ethereum pomocí ChainIDE. Používejte vestavěné šablony, díky kterým se naučíte a ušetříte čas.", - "page-learning-tools-chainIDE-logo-alt": "Logo ChainIDE", - "page-learning-tools-tenderly-description": "Tenderly Sandbox je prototypové prostředí, kde můžete psát, spouštět a ladit chytré kontrakty v prohlížeči pomocí programovacího jazyka Solidity a JavaScriptu.", - "page-learning-tools-tenderly-logo-alt": "Logo Tenderly", - "page-learning-tools-replit-logo-alt": "Logo Replit", - "page-learning-tools-remix-logo-alt": "Logo Remix", - "page-learning-tools-sandbox": "Kódové sandboxy", - "page-learning-tools-sandbox-desc": "Tyto sandboxy vám dají prostor k experimentování s psaním chytrých kontraktů a porozumění Ethereu.", - "page-learning-tools-speed-run-ethereum-description": "Speed Run Ethereum je sada výzev, které otestují vaše znalosti programovacího jazyka Solidity pomocí Scaffold-ETH", - "page-learning-tools-speed-run-ethereum-logo-alt": "Logo Speed Run Ethereum", - "page-learning-tools-studio-description": "Webové IDE, kde můžete sledovat návody k vytvoření a otestování chytrých kontraktů a vytvořit pro ně web.", - "page-learning-tools-vyperfun-description": "Naučte se Vyper tím, že vytvoříte vlastní hru s Pokémony.", - "page-learning-tools-vyperfun-logo-alt": "Logo Vyper.fun", - "page-learning-tools-nftschool-description": "Zjistěte, jak fungují NFT (nezaměnitelné tokeny) z technického hlediska.", - "page-learning-tools-nftschool-logo-alt": "Logo NFT school", - "page-learning-tools-platzi-description": "Naučte se vytvářet Web3 dappky a osvojte si všechny dovednosti potřebné pro blockchain vývojáře.", - "page-learning-tools-platzi-logo-alt": "Logo Platzi", - "page-learning-tools-alchemy-university-description": "Rozvíjejte svou kariéru v oblasti web3 prostřednictvím kurzů, projektů a kódu.", - "page-learning-tools-alchemy-university-logo-alt": "Logo Alchemy University", - "page-learning-tools-learnweb3-description": "LearnWeb3 je bezplatná, vysoce kvalitní vzdělávací platforma, která vám umožní stát se expertem v oblasti vývoje web3.", - "page-learning-tools-learnweb3-logo-alt": "Logo LearnWeb3", - "page-learning-tools-cyfrin-updraft-description": "Naučte se vyvíjet chytré kontrakty pro všechny dovednostní úrovně a bezpečnostní audity.", - "page-learning-tools-cyfrin-updraft-logo-alt": "Logo Cyfrin Updraft", - "alt-eth-blocks": "Obrázek bloků sestavených jako symbol ETH" -} diff --git a/src/intl/cs/page-developers-local-environment.json b/src/intl/cs/page-developers-local-environment.json deleted file mode 100644 index 57dd8c1e5d0..00000000000 --- a/src/intl/cs/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "Vývoj a testovací rámec pro vývoj chytrých kontraktů pro Virtuální stroj Etherea v Pythonu.", - "page-local-environment-brownie-logo-alt": "Logo Brownie", - "page-local-environment-kurtosis-desc": "Kontejnerová sada nástrojů pro snadnou konfiguraci a vytvoření testovací sítě Ethereum pro více klientů pro rychlý lokální vývoj, prototypování a testování dappky.", - "page-local-environment-kurtosis-logo-alt": "Logo Kurtosis", - "page-local-environment-epirus-desc": "Platforma k vyvíjení, nasazení a monitorování aplikací pro blockchain v Java Virtual Machine.", - "page-local-environment-epirus-logo-alt": "Logo Espirus", - "page-local-environment-eth-app-desc": "Vytvořte aplikace pro Ethereum jedním příkazem. Můžete si vybrat ze široké nabídky UI frameworků a DeFi šablon.", - "page-local-environment-eth-app-logo-alt": "Logo Create Eth App", - "page-local-environment-foundry-desc": "Rychlá, přenosná a modulární sada nástrojů pro vývoj aplikací pro Ethereum napsaná v jazyce Rust.", - "page-local-environment-foundry-logo-alt": "Logo Foundry", - "page-local-environment-framework-feature-1": "Funkce ke spuštění vlastního lokálního blockchainu.", - "page-local-environment-framework-feature-2": "Nástroje pro kompilaci a testování chytrých kontraktů.", - "page-local-environment-framework-feature-3": "Vývojové doplňky klienta, které vytvoří vaši uživatelskou aplikaci ve stejném projektu nebo repozitáři.", - "page-local-environment-framework-feature-4": "Konfigurace pro připojení k sítím Ethereum a nasazení kontraktů, ať už na místně běžící instanci, nebo v jedné z veřejných sítí Etherea.", - "page-local-environment-framework-feature-5": "Decentralizovaná distribuce aplikací. Integrace s možnostmi úložiště jako IPFS.", - "page-local-environment-framework-features": "Tyto rámce přicházejí s mnoha funkcemi mimo provoz, jako:", - "page-local-environment-frameworks-desc": " Doporučujeme vybrat rámec, zejména pokud teprve začínáte. Vytvoření plnohodnotné dappky vyžaduje několik různých technologií. Rámce zahrnují mnoho těchto potřebných funkcí nebo poskytují jednoduché plugin systémy, abyste si mohli vybrat nástroje, které chcete.", - "page-local-environment-frameworks-title": "Rámce a předpřipravené sady", - "page-local-environment-hardhat-desc": "Hardhat je prostředí pro vývoj Etherea pro profesionály.", - "page-local-environment-hardhat-logo-alt": "Logo Hardhat", - "page-local-environment-openZeppelin-desc": "Ušetřete hodiny času vývoje kompilací, vylepšením, nasazením a interakcí s chytrými kontrakty díky systému CLI.", - "page-local-environment-openZeppelin-logo-alt": "Logo OpenZeppelin", - "page-local-environment-scaffold-eth-desc": "Ethers + Hardhat + React: vše, co potřebujete, abyste mohli začít vytvářet decentralizované aplikace využívající chytré kontrakty.", - "page-local-environment-scaffold-eth-logo-alt": "Logo scaffold-eth", - "page-local-environment-setup-meta-desc": "Průvodce, jak si vybrat software pro vývoj Etherea.", - "page-local-environment-setup-meta-title": "Nastavení místního vývoje Etherea", - "page-local-environment-setup-subtitle": "Pokud jste připraveni začít stavět, je čas vybrat si stack (zásobník).", - "page-local-environment-setup-subtitle-2": " Tady jsou nástroje a rámce, které můžete použít k budování Vaší Ethereum aplikace.", - "page-local-environment-setup-title": "Nastavení vlastního místního vývojářského prostředí", - "page-local-environment-solidity-template-desc": "GitHub šablona pro předem vytvořené nastavení chytrých kontraktů Solidity. Zahrnuje místní síť Hardhat, Waffle pro testy, Ethery pro implementaci peněženky a další.", - "page-local-environment-solidity-template-logo-alt": "Logo Solidity template" -} \ No newline at end of file diff --git a/src/intl/de/page-developers-learning-tools.json b/src/intl/de/page-developers-learning-tools.json deleted file mode 100644 index a0d54d1a5ac..00000000000 --- a/src/intl/de/page-developers-learning-tools.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "Der BloomTech Web3-Kurs vermittelt Ihnen die Fähigkeiten, die Arbeitgeber bei Ingenieuren suchen.", - "page-learning-tools-bloomtech-logo-alt": "BloomTech-Logo", - "page-learning-tools-bootcamps": "Entwickler-Bootcamps", - "page-learning-tools-bootcamps-desc": "Bezahlte Online-Kurse, um sich schnell auf den aktuellen Stand zu bringen.", - "page-learning-tools-browse-docs": "Dokumente durchsuchen", - "page-learning-tools-capture-the-ether-description": "Capture the Ether ist ein Spiel, in dem Sie Smart Contracts auf Ethereum hacken, um mehr über Sicherheit zu lernen.", - "page-learning-tools-capture-the-ether-logo-alt": "Erobern Sie das Ether-Logo", - "page-learning-tools-node-guardians-description": "Node Guardians ist eine Gamification-Bildungsplattform, mit der Web3-Entwickler anhand von Immersion in Quests im Fantasy-Stil lernen, Solidity-, Cairo-, Noir- und Huff-Programmierung zu beherrschen.", - "page-learning-tools-node-guardians-logo-alt": "Node Guardians-Logo", - "page-learning-tools-coding": "Lernen durch Programmieren", - "page-learning-tools-coding-subtitle": "Diese Tools werden Ihnen helfen, mit Ethereum zu experimentieren, wenn Sie ein eher interaktives Lernerlebnis bevorzugen.", - "page-learning-tools-consensys-academy-description": "Online Ethereum Entwickler-Bootcamp.", - "page-learning-tools-consensys-academy-logo-alt": "ConsenSys-Academy-Logo", - "page-learning-tools-cryptozombies-description": "Lerne Solidity bei der Erstellung Ihres eigenen Zombie-Spiels.", - "page-learning-tools-cryptozombies-logo-alt": "KryptoZombies-Logo", - "page-learning-tools-dapp-world-description": "Ein Blockchain-Upskilling-Ökosystem, das Kurse, Tests, praktischen Übungen und wöchentlichen Wettbewerbe umfasst.", - "page-learning-tools-dapp-world-logo-alt": "DApp-World-Logo", - "page-learning-tools-documentation": "Lernen mit Dokumentation", - "page-learning-tools-documentation-desc": "Sie möchten mehr lernen? Gehen Sie auf unsere Dokumentation, um die Anleitung zu erhalten, die Sie benötigen.", - "page-learning-tools-eth-dot-build-description": "Ein Lern-Sandkasten für web3, inklusive Drag-and-Drop-Programmierung und Open-Source-Bausteinen.", - "page-learning-tools-eth-dot-build-logo-alt": "Eth.build-Logo", - "page-learning-tools-ethernauts-description": "Beende Level durch das Hacken von Smart Contracts.", - "page-learning-tools-ethernauts-logo-alt": "Ethernauts-Logo", - "page-learning-tools-metaschool-description": "Werden Sie Web3-Entwickler durch das Erstellen und Liefern von dApps.", - "page-learning-tools-metaschool-logo-alt": "_Metaschool Logo", - "page-learning-tools-game-tutorials": "Interaktive Spielanleitungen", - "page-learning-tools-game-tutorials-desc": "Lernen Sie, während Sie spielen. Diese Tutorials leiten Sie mit Gameplay durch die Grundlagen.", - "page-learning-tools-meta-desc": "Webbasierte Programmierwerkzeuge und ein interaktives Lernerlebnis helfen Ihnen, mit der Entwicklung von Ethereum zu experimentieren.", - "page-learning-tools-meta-title": "Lernwerkzeuge für Entwickler", - "page-learning-tools-atlas-logo-alt": "Atlas-Logo", - "page-learning-tools-atlas-description": "Schreiben und testen Sie Smart Contracts und stellen Sie sie bereit – alles in wenigen Minuten mit Atlas IDE.", - "page-learning-tools-questbook-description": "Selbstbeschleunigte Tutorials zum Lernen von Web 3.0 durch die eigene Erstellung", - "page-learning-tools-questbook-logo-alt": "Questbook-Logo", - "page-learning-tools-remix-description": "Entwickeln, implementieren und verwalten Sie Smart Contracts für Ethereum. Folgen Sie Tutorials mit dem LearnEth-Plugin.", - "page-learning-tools-remix-description-2": "Remix, Replit, ChainIDE und Atlas sind nicht nur Sandboxes — Entwickler können mit ihnen ihre Smart Contracts schreiben, kompilieren und bereitstellen.", - "page-learning-tools-replit-description": "Eine anpassbare Entwicklungsumgebung für Ethereum mit Hot-Reload, Fehlerüberprüfung und erstklassigem Testnet-Support.", - "page-learning-tools-chainIDE-description": "Beginnen Sie mit dem Web3, indem Sie mit der ChainIDE Smart Contracts für Ethereum schreiben. Lernen Sie mit den integrierten Vorlagen mehr und sparen Sie Zeit.", - "page-learning-tools-chainIDE-logo-alt": "ChainIDE-Logo", - "page-learning-tools-tenderly-description": "Tenderly Sandbox ist eine Prototypen-Umgebung, in der Sie Smart Contracts im Browser mit Solidity und JavaScript schreiben, ausführen und Fehler in den Verträgen beheben können.", - "page-learning-tools-tenderly-logo-alt": "Tenderly-Logo", - "page-learning-tools-replit-logo-alt": "Replit-Logo", - "page-learning-tools-remix-logo-alt": "Remix-Logo", - "page-learning-tools-sandbox": "Code-Sandkästen", - "page-learning-tools-sandbox-desc": "Diese Sandkästen werden Ihnen den Raum geben, um mit dem Schreiben von Smart Contracts zu experimentieren und Ethereum zu verstehen.", - "page-learning-tools-speed-run-ethereum-description": "\"Speed Run Ethereum\" ist eine Serie an Herausforderungen zum Testen Ihrer Solidity-Kenntnisse mit Scaffold-ETH", - "page-learning-tools-speed-run-ethereum-logo-alt": "Speed Run Ethereum-Logo", - "page-learning-tools-studio-description": "Eine webbasierte IDE, wo Sie Tutorials verfolgen können, die zeigen, wie Smart Contracts erstellt und getestet werden und wie ein Frontend für diese erstellt wird.", - "page-learning-tools-vyperfun-description": "Lerne Vyper, indem Sie Ihr eigenes Pokémon-Spiel erstellen.", - "page-learning-tools-vyperfun-logo-alt": "Vyper.fun-Logo", - "page-learning-tools-nftschool-description": "Erkunde, was mit nicht fungiblen Token oder NFT von der technischen Seite aus geschieht.", - "page-learning-tools-nftschool-logo-alt": "NFT-school-Logo", - "page-learning-tools-platzi-description": "Erfahren Sie, wie Sie dApps auf Web3 erstellen, und erlernen Sie alle Fähigkeiten, die ein Blockchain-Entwickler benötigt.", - "page-learning-tools-platzi-logo-alt": "Platzi-Logo", - "page-learning-tools-alchemy-university-description": "Arbeiten Sie über Kurse, Projekte und Code an Ihrer Web3-Karriere.", - "page-learning-tools-alchemy-university-logo-alt": "Alchemy University-Logo", - "page-learning-tools-learnweb3-description": "LearnWeb3 ist eine kostenlose, hochwertige Bildungsplattform, um vom Anfänger zum Experten in der Web3-Entwicklung zu werden.", - "page-learning-tools-learnweb3-logo-alt": "LearnWeb3-Logo", - "page-learning-tools-cyfrin-updraft-description": "Erlernen Sie die Entwicklung von Smart Contracts für alle Fähigkeitsstufen sowie Sicherheitsüberprüfungen.", - "page-learning-tools-cyfrin-updraft-logo-alt": "Cyfrin Updraft-Logo", - "alt-eth-blocks": "Illustration von Blöcken, die wie ein ETH-Symbol angeordnet sind" -} diff --git a/src/intl/de/page-developers-local-environment.json b/src/intl/de/page-developers-local-environment.json deleted file mode 100644 index 0db4e66fbe9..00000000000 --- a/src/intl/de/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "Ein auf Python basierendes Entwicklungs- und Test-Framework für Smart Contracts, die auf die Ethereum Virtual Machine abzielen.", - "page-local-environment-brownie-logo-alt": "Brownie-Logo", - "page-local-environment-kurtosis-desc": "Ein Container-basiertes Toolkit zur einfachen Konfiguration und Einrichtung eines mehrmandantenfähigen Ethereum-Testnetzes für die schnelle lokale dApp-Entwicklung, das Erstellen von Prototypen und Tests.", - "page-local-environment-kurtosis-logo-alt": "Kurtosis-Logo", - "page-local-environment-epirus-desc": "Eine Plattform zum Entwickeln, Bereitstellen und Überwachen von Blockchain-Anwendungen auf der Java Virtual Machine.", - "page-local-environment-epirus-logo-alt": "Epirus-Logo", - "page-local-environment-eth-app-desc": "Erstelle Ethereum-basierte Apps mit einem Befehl. Begleitet von einem breiten Angebot von UI-Frameworks und DeFi-Vorlagen, aus denen Sie auswählen können.", - "page-local-environment-eth-app-logo-alt": "Erstellen Sie ein Eth-App-Logo", - "page-local-environment-foundry-desc": "Ein schnelles, portierbares und modulares Toolkit für die Entwicklung von Ethereum-Anwendungen in der Programmiersprache Rust.", - "page-local-environment-foundry-logo-alt": "Foundry-Logo", - "page-local-environment-framework-feature-1": "Funktionen zum Aufsetzen einer lokalen Blockchain-Instanz.", - "page-local-environment-framework-feature-2": "Dienste zum Kompilieren und Testen von Smart Contracts.", - "page-local-environment-framework-feature-3": "Client-Entwicklungs-Add-ons zur Erstellung deiner anwenderorientierten Anwendung im selben Projekt/Projektarchiv.", - "page-local-environment-framework-feature-4": "Konfiguration für die Verbindung zu Ethereum-Netzwerken und dem Einsatz von Verträgen, sei es zu einer lokal laufenden Instanz oder zu einem öffentlichen Netzwerk von Ethereum.", - "page-local-environment-framework-feature-5": "Dezentralisierte App-Verteilung – Integration mit Speicheroptionen wie IPFS.", - "page-local-environment-framework-features": "Diese Frameworks verfügen über eine Vielzahl von Funktionen, wie zum Beispiel:", - "page-local-environment-frameworks-desc": "Wir empfehlen, ein Framework auszuwählen, besonders wenn Sie gerade erst anfangen. Das Aufbauen einer vollwertigen dApp erfordert unterschiedliche Technologien. Frameworks enthalten viele der benötigten Funktionen oder bieten einfache Plugin-Systeme, um die gewünschten Werkzeuge auszuwählen.", - "page-local-environment-frameworks-title": "Frameworks und vorgefertigte Stacks", - "page-local-environment-hardhat-desc": "Hardhat ist eine Ethereum-Entwicklungsumgebung für Profi-Anwender.", - "page-local-environment-hardhat-logo-alt": "Hardhat-Logo", - "page-local-environment-openZeppelin-desc": "Sparen Stunden an Entwicklungszeit, indem Sie über unsere CLI kompilieren, upgraden, veröffentlichen und mit Smart Contracts interagieren.", - "page-local-environment-openZeppelin-logo-alt": "OpenZeppelin-Logo", - "page-local-environment-scaffold-eth-desc": "Ether + Hardhat + React: Alles, was Sie brauchen, um mit der Entwicklung dezentraler Anwendungen auf Basis von Smart Contracts zu beginnen.", - "page-local-environment-scaffold-eth-logo-alt": "scaffold-eth-Logo", - "page-local-environment-setup-meta-desc": "Anleitung, wie Sie Ihren Software-Stack für die Ethereum-Entwicklung auswählen.", - "page-local-environment-setup-meta-title": "Ethereum – lokale Entwicklereinrichtung", - "page-local-environment-setup-subtitle": "Wenn Sie bereit sind, mit der Entwicklung zu beginnen, ist es Zeit, Ihren Stack auszuwählen.", - "page-local-environment-setup-subtitle-2": "Hier sind die Werkzeuge und Frameworks, die Sie zum Aufbau Deiner Ethereum-Anwendung verwenden können.", - "page-local-environment-setup-title": "Richten Sie Ihre lokale Entwicklungsumgebung ein", - "page-local-environment-solidity-template-desc": "Eine GitHub-Vorlage für eine vorgefertigte Einrichtung für Ihre Solidity-Smart-Contracts. Enthält ein lokales Hardhat-Netzwerk, Ethers für die Wallet-Implementierung und mehr.", - "page-local-environment-solidity-template-logo-alt": "Solidity-Vorlagen-Logo" -} diff --git a/src/intl/en/page-developers-learning-tools.json b/src/intl/en/page-developers-learning-tools.json deleted file mode 100644 index 9cbeac6fcdb..00000000000 --- a/src/intl/en/page-developers-learning-tools.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "The BloomTech Web3 course will teach you the skills employers look for in engineers.", - "page-learning-tools-bloomtech-logo-alt": "BloomTech logo", - "page-learning-tools-bootcamps": "Developer bootcamps", - "page-learning-tools-bootcamps-desc": "Free or paid online courses to get you up to speed, fast.", - "page-learning-tools-browse-docs": "Browse docs", - "page-learning-tools-capture-the-ether-description": "Capture the Ether is a game in which you hack Ethereum smart contracts to learn about security.", - "page-learning-tools-capture-the-ether-logo-alt": "Capture the Ether logo", - "page-learning-tools-node-guardians-description": "Node Guardians is a gamified educational platform that immerses web3 developers in fantasy-themed quests to master Solidity, Cairo, Noir, and Huff programming.", - "page-learning-tools-node-guardians-logo-alt": "Node Guardians logo", - "page-learning-tools-coding": "Learn by coding", - "page-learning-tools-coding-subtitle": "These tools will help you experiment with Ethereum if you prefer a more interactive learning experience.", - "page-learning-tools-consensys-academy-description": "Online Ethereum developer bootcamp.", - "page-learning-tools-consensys-academy-logo-alt": "ConsenSys Academy logo", - "page-learning-tools-cryptozombies-description": "Learn Solidity building your own Zombie game.", - "page-learning-tools-cryptozombies-logo-alt": "CryptoZombies logo", - "page-learning-tools-dapp-world-description": "A blockchain upskilling ecosystem, including courses, quizzes, hands-on practice, and weekly contests.", - "page-learning-tools-dapp-world-logo-alt": "Dapp World logo", - "page-learning-tools-documentation": "Learn with documentation", - "page-learning-tools-documentation-desc": "Want to learn more? Go to our documentation to find the explanations you need.", - "page-learning-tools-eth-dot-build-description": "An educational sandbox for web3, including drag-and-drop programming and open-source building blocks.", - "page-learning-tools-eth-dot-build-logo-alt": "Eth.build logo", - "page-learning-tools-ethernauts-description": "Complete levels by hacking smart contracts.", - "page-learning-tools-ethernauts-logo-alt": "Ethernauts logo", - "page-learning-tools-metaschool-description": "Become a Web3 Developer by building & shipping dApps.", - "page-learning-tools-metaschool-logo-alt": "_metaschool logo", - "page-learning-tools-game-tutorials": "Interactive game tutorials", - "page-learning-tools-game-tutorials-desc": "Learn while you play. These tutorials get you through the basics using gameplay.", - "page-learning-tools-meta-desc": "Web-based coding tools and interactive learning experiences to help you experiment with Ethereum development.", - "page-learning-tools-meta-title": "Developer learning tools", - "page-learning-tools-atlas-logo-alt": "Atlas logo", - "page-learning-tools-atlas-description": "Write, test, and deploy smart contracts in minutes with the Atlas IDE.", - "page-learning-tools-questbook-description": "Self paced tutorials to learn Web 3.0 by building", - "page-learning-tools-questbook-logo-alt": "Questbook logo", - "page-learning-tools-remix-description": "Develop, deploy and administer smart contracts for Ethereum. Follow tutorials with the LearnEth plugin.", - "page-learning-tools-remix-description-2": "Remix, Replit, ChainIDE, and Atlas aren't just sandboxes—developers can write, compile and deploy their smart contracts using them.", - "page-learning-tools-replit-description": "A customizable development environment for Ethereum with hot reloading, error checking, and first-class testnet support.", - "page-learning-tools-chainIDE-description": "Get started on your journey to Web3 by writing smart contracts for Ethereum with ChainIDE. Use the built-in templates to learn and save time.", - "page-learning-tools-chainIDE-logo-alt": "ChainIDE logo", - "page-learning-tools-tenderly-description": "Tenderly Sandbox is a prototyping environment where you can write, execute, and debug smart contracts in the browser using Solidity and JavaScript.", - "page-learning-tools-tenderly-logo-alt": "Tenderly logo", - "page-learning-tools-replit-logo-alt": "Replit logo", - "page-learning-tools-remix-logo-alt": "Remix logo", - "page-learning-tools-sandbox": "Code sandboxes", - "page-learning-tools-sandbox-desc": "These sandboxes will give you a space to experiment with writing smart contracts and understanding Ethereum.", - "page-learning-tools-speed-run-ethereum-description": "Speed Run Ethereum is a set of challenges to test your Solidity knowledge using Scaffold-ETH", - "page-learning-tools-speed-run-ethereum-logo-alt": "Speed Run Ethereum logo", - "page-learning-tools-studio-description": "A web-based IDE where you can follow tutorials to create and test smart contracts, and build a frontend for them.", - "page-learning-tools-vyperfun-description": "Learn Vyper building your own Pokémon game.", - "page-learning-tools-vyperfun-logo-alt": "Vyper.fun logo", - "page-learning-tools-nftschool-description": "Explore what's going on with non-fungible tokens, or NFTs from the technical side.", - "page-learning-tools-nftschool-logo-alt": "NFT school logo", - "page-learning-tools-platzi-description": "Learn how to build dapps on Web3 and master all the skills needed to be a blockchain developer.", - "page-learning-tools-platzi-logo-alt": "Platzi logo", - "page-learning-tools-alchemy-university-description": "Develop your web3 career through courses, projects and code.", - "page-learning-tools-alchemy-university-logo-alt": "Alchemy University logo", - "page-learning-tools-learnweb3-description": "LearnWeb3 is a free, high quality education platform to go from zero to hero in web3 development.", - "page-learning-tools-learnweb3-logo-alt": "LearnWeb3 logo", - "page-learning-tools-cyfrin-updraft-description": "Learn smart contract development for all skill levels and security audits.", - "page-learning-tools-cyfrin-updraft-logo-alt": "Cyfrin Updraft logo", - "page-learning-tools-price-free": "Free", - "page-learning-tools-price-paid": "Paid", - "alt-eth-blocks": "Illustration of blocks being organized like an ETH symbol" -} diff --git a/src/intl/en/page-developers-local-environment.json b/src/intl/en/page-developers-local-environment.json deleted file mode 100644 index f7632b9338d..00000000000 --- a/src/intl/en/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "A Python-based development and testing framework for smart contracts targeting the Ethereum Virtual Machine.", - "page-local-environment-brownie-logo-alt": "Brownie logo", - "page-local-environment-kurtosis-desc": "A container-based toolkit for easily configuring and spinning up a multi-client Ethereum testnet for rapid local dApp development, prototyping, and testing.", - "page-local-environment-kurtosis-logo-alt": "Kurtosis logo", - "page-local-environment-epirus-desc": "A platform for developing, deploying and monitoring blockchain applications on the Java Virtual Machine.", - "page-local-environment-epirus-logo-alt": "Epirus logo", - "page-local-environment-eth-app-desc": "Create Ethereum-powered apps with one command. Comes with a wide offerring of UI frameworks and DeFi templates to choose from.", - "page-local-environment-eth-app-logo-alt": "Create Eth App logo", - "page-local-environment-foundry-desc": "A blazing fast, portable and modular toolkit for Ethereum application development written in Rust.", - "page-local-environment-foundry-logo-alt": "Foundry logo", - "page-local-environment-framework-feature-1": "Features to spin up a local blockchain instance.", - "page-local-environment-framework-feature-2": "Utilities to compile and test your smart contracts.", - "page-local-environment-framework-feature-3": "Client development add-ons to build your user-facing application within the same project/repository.", - "page-local-environment-framework-feature-4": "Configuration to connect to Ethereum networks and deploy contracts, whether to a locally running instance, or one of Ethereum's public networks.", - "page-local-environment-framework-feature-5": "Decentralized app distribution - integrations with storage options like IPFS.", - "page-local-environment-framework-features": "These frameworks come with a lot of out-of-the-box functionality, like:", - "page-local-environment-frameworks-desc": "We recommend picking a framework, particularly if you're just getting started. Building a full-fledged dapp requires different pieces of technology. Frameworks include many of the needed features or provide easy plugin systems to pick the tools you desire.", - "page-local-environment-frameworks-title": "Frameworks and pre-made stacks", - "page-local-environment-hardhat-desc": "Hardhat is an Ethereum development environment for professionals.", - "page-local-environment-hardhat-logo-alt": "Hardhat logo", - "page-local-environment-openZeppelin-desc": "Save hours of development time by compiling, upgrading, deploying, and interacting with smart contracts with our CLI.", - "page-local-environment-openZeppelin-logo-alt": "OpenZeppelin logo", - "page-local-environment-scaffold-eth-desc": "Ethers + Hardhat + React: everything you need to get started building decentralized applications powered by smart contracts.", - "page-local-environment-scaffold-eth-logo-alt": "scaffold-eth logo", - "page-local-environment-setup-meta-desc": "Guide on how to choose your software stack for Ethereum development.", - "page-local-environment-setup-meta-title": "Ethereum local development setup", - "page-local-environment-setup-subtitle": "If you're ready to start building, it's time to choose your stack.", - "page-local-environment-setup-subtitle-2": "Here are the tools and frameworks you can use to help you build your Ethereum application.", - "page-local-environment-setup-title": "Set up your local development environment", - "page-local-environment-solidity-template-desc": "A GitHub template for a pre-built setup for your Solidity smart contracts. Includes a Hardhat local network, Ethers for wallet implementation, and more.", - "page-local-environment-solidity-template-logo-alt": "Solidity template logo" -} diff --git a/src/intl/es/page-developers-learning-tools.json b/src/intl/es/page-developers-learning-tools.json deleted file mode 100644 index fceb82f8fc8..00000000000 --- a/src/intl/es/page-developers-learning-tools.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "El curso BloomTech Web3 te enseñará las habilidades que los empleadores buscan en los ingenieros.", - "page-learning-tools-bloomtech-logo-alt": "Logo de BloomTech", - "page-learning-tools-bootcamps": "Cursos intensivos para desarrolladores", - "page-learning-tools-bootcamps-desc": "Cursos en línea gratuitos o de pago para que aprenda rápidamente.", - "page-learning-tools-browse-docs": "Examinar documentos", - "page-learning-tools-capture-the-ether-description": "Capture the Ether es un juego en el que puede hackear contratos inteligentes de Ethereum para aprender sobre seguridad.", - "page-learning-tools-capture-the-ether-logo-alt": "Logo de Capture the Ether", - "page-learning-tools-node-guardians-description": "Node Guardians es una plataforma educativa gamificada que sumerge a los desarrolladores de web3 en misiones de fantasía para dominar la programación de Solidity, Cairo, Noir y Huff.", - "page-learning-tools-node-guardians-logo-alt": "Logo de Node Guardians", - "page-learning-tools-coding": "Aprender mediante codificación", - "page-learning-tools-coding-subtitle": "Estas herramientas le ayudarán a experimentar con Ethereum si prefiere una experiencia de aprendizaje más interactiva.", - "page-learning-tools-consensys-academy-description": "Curso online intensivo para desarrolladores de Ethereum.", - "page-learning-tools-consensys-academy-logo-alt": "Logo de ConsenSys Academy", - "page-learning-tools-cryptozombies-description": "Desarrolle su propio juego de zombies para aprender Solidity.", - "page-learning-tools-cryptozombies-logo-alt": "Logo de CryptoZombies", - "page-learning-tools-dapp-world-description": "Un ecosistema de mejora de habilidades en cadena de bloques que incluye cursos, cuestionarios, prácticas y concursos semanales.", - "page-learning-tools-dapp-world-logo-alt": "Logo Dapp World", - "page-learning-tools-documentation": "Aprender con documentación", - "page-learning-tools-documentation-desc": "¿Quier obtener más información? Consulte nuestra documentación para encontrar las explicaciones que necesita.", - "page-learning-tools-eth-dot-build-description": "Un entorno aislado educativo para Web 3.0, que incluye programación «arrastrar y soltar» y bloques de construcción de código abierto.", - "page-learning-tools-eth-dot-build-logo-alt": "Logo de Eth.build", - "page-learning-tools-ethernauts-description": "Hackee contratos inteligentes para pasar de nivel.", - "page-learning-tools-ethernauts-logo-alt": "Logo de Ethernauts", - "page-learning-tools-metaschool-description": "Conviértase en un desarrollador Web3 construyendo y montando DApps.", - "page-learning-tools-metaschool-logo-alt": "Logo de _metaschool", - "page-learning-tools-game-tutorials": "Tutoriales de juegos interactivos", - "page-learning-tools-game-tutorials-desc": "Aprenda mientras juega. Estos tutoriales le ayudarán a comprender los conceptos a través del juego.", - "page-learning-tools-meta-desc": "Las herramientas de codificación basadas en la Web y las experiencias de aprendizaje interactivo le ayudarán a experimentar con el desarrollo de Ethereum.", - "page-learning-tools-meta-title": "Herramientas de aprendizaje para desarrolladores", - "page-learning-tools-atlas-logo-alt": "Logo de Atlas", - "page-learning-tools-atlas-description": "Escriba, realice pruebas e implemente contratos inteligentes en minutos con Atlas IDE.", - "page-learning-tools-questbook-description": "Tutoriales para aprender sobre Web 3.0 construyendo", - "page-learning-tools-questbook-logo-alt": "Logotipo de Questbook", - "page-learning-tools-remix-description": "Desarrolle, implemente y administre contratos inteligentes para Ethereum. Siga los tutoriales con el plugin (o complemento) de LearnEth.", - "page-learning-tools-remix-description-2": "Remix, Replit, ChainIDE y Atlas no son solo sandboxes; los desarrolladores pueden escribir, compilar e implementar contratos inteligentes utilizándolos.", - "page-learning-tools-replit-description": "Un entorno de desarrollo personalizable para Ethereum con recarga en caliente, verificación de errores y soporte para red de pruebas de primera clase.", - "page-learning-tools-chainIDE-description": "Empiece su recorrido por Web 3 escribiendo contratos inteligentes para Ethereum con ChainIDE. Use las plantillas incorporadas para aprender y ahorrar tiempo.", - "page-learning-tools-chainIDE-logo-alt": "Logo de ChainIDE", - "page-learning-tools-tenderly-description": "Tenderly Sandbox es un entorno de prototipo donde se puede escribir, ejecutar y depurar contratos inteligentes en el navegador usando Solidity y JavaScript.", - "page-learning-tools-tenderly-logo-alt": "Logo de Tenderly", - "page-learning-tools-replit-logo-alt": "Logo de Replit", - "page-learning-tools-remix-logo-alt": "Logo de Remix", - "page-learning-tools-sandbox": "Procesos aislados de código", - "page-learning-tools-sandbox-desc": "Estos procesos aislados le darán un espacio para experimentar con contratos inteligentes escritos y entender Ethereum.", - "page-learning-tools-speed-run-ethereum-description": "Speed Run Ethereum es un conjunto de desafíos para probar tu conocimiento de Solidity usando Scaffold-ETH", - "page-learning-tools-speed-run-ethereum-logo-alt": "Logo de Speed Run Ethereum", - "page-learning-tools-studio-description": "Un entorno de desarrollo integrado (IDE) basado en la Web donde puede encontrar tutoriales para crear y probar contratos inteligentes, y construir para ellos una interfaz gráfica (front-end).", - "page-learning-tools-vyperfun-description": "Conozca Vyper mediante la creación de su propio juego de Pokémon.", - "page-learning-tools-vyperfun-logo-alt": "Logo de Vyper.fun", - "page-learning-tools-nftschool-description": "Explore lo que está sucediendo con los tókenes no fungibles o NFT desde el punto de vista técnico.", - "page-learning-tools-nftschool-logo-alt": "Logotipo de NFT School", - "page-learning-tools-platzi-description": "Aprenda cómo construir DApps en Web3 y domine todas las habilidades necesarias para ser un desarrollador de la cadena de bloques.", - "page-learning-tools-platzi-logo-alt": "Logo de Platzi", - "page-learning-tools-alchemy-university-description": "Desarrolle su trayectoria en la Web3 a través de cursos, proyectos y códigos.", - "page-learning-tools-alchemy-university-logo-alt": "Logo de Alchemy University", - "page-learning-tools-learnweb3-description": "LearnWeb3 es una plataforma gratuita de gran calidad para pasar de cero a nivel experto en desarrollo de Web3.", - "page-learning-tools-learnweb3-logo-alt": "Logo de LearnWeb3", - "page-learning-tools-cyfrin-updraft-description": "Aprenda sobre desarrollo de contratos inteligentes en todos los niveles de capacitación y auditorías de seguridad.", - "page-learning-tools-cyfrin-updraft-logo-alt": "Logo de Cyfrin Updraft", - "page-learning-tools-price-free": "Gratis", - "page-learning-tools-price-paid": "De pago", - "alt-eth-blocks": "Ilustración de bloques organizados como un símbolo ETH" -} diff --git a/src/intl/es/page-developers-local-environment.json b/src/intl/es/page-developers-local-environment.json deleted file mode 100644 index a526adba645..00000000000 --- a/src/intl/es/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "Un marco de desarrollo y pruebas basado en Python para contratos inteligentes dirigidos a la máquina virtual de Ethereum.", - "page-local-environment-brownie-logo-alt": "Logo de Brownie", - "page-local-environment-kurtosis-desc": "Un conjunto de herramientas basado en contenedores para configurar y activar fácilmente un multicliente en la red de pruebas Ethereum y así desarrollar, sacar un prototipo y probar rápidamente su DApp localmente.", - "page-local-environment-kurtosis-logo-alt": "Logo de Kurtosis", - "page-local-environment-epirus-desc": "Una plataforma para desarrollar, implementar y supervisar aplicaciones de cadenas de bloques sobre la máquina virtual de Java.", - "page-local-environment-epirus-logo-alt": "Logo de Epirus", - "page-local-environment-eth-app-desc": "Crear aplicaciones equipadas con Ethereum con un comando. Viene con un amplio despliegue de marcos de interfaz de usuario y plantillas DeFi para elegir.", - "page-local-environment-eth-app-logo-alt": "Crear logo de app Eth", - "page-local-environment-foundry-desc": "Un kit de herramientas modular, ultrarrápido y portátil para el desarrollo de aplicaciones de Ethereum escrito en Rust.", - "page-local-environment-foundry-logo-alt": "Logo de Foundry", - "page-local-environment-framework-feature-1": "Características para activar una instancia local de cadena de bloques.", - "page-local-environment-framework-feature-2": "Funciones de utilidad para compilar y probar sus contratos inteligentes.", - "page-local-environment-framework-feature-3": "Complementos de desarrollo para clientes para construir aplicaciones orientadas al usuario dentro del mismo proyecto/repositorio.", - "page-local-environment-framework-feature-4": "Configuración para conectarse a redes Ethereum e implementar contratos, ya sea en una instancia que se ejecuta de forma local o en una red pública de Ethereum.", - "page-local-environment-framework-feature-5": "Distribución descentralizada de aplicaciones, integraciones con opciones de almacenamiento como IPFS.", - "page-local-environment-framework-features": "Estos marcos vienen con una gran cantidad de funciones listas para usar, como:", - "page-local-environment-frameworks-desc": "Recomendamos elegir un marco, especialmente si está empezando. Construir una DApp completa requiere diferentes tecnologías. Las estructuras incluyen muchas de las características necesarias o proporcionan sistemas de complementos sencillos para que elija las herramientas que quiera.", - "page-local-environment-frameworks-title": "Marcos y pilas prediseñadas", - "page-local-environment-hardhat-desc": "Hardhat es un entorno de desarrollo de Ethereum para profesionales.", - "page-local-environment-hardhat-logo-alt": "Logo de Hardhat", - "page-local-environment-openZeppelin-desc": "Ahorre horas de tiempo de desarrollo al compilar, actualizar, implementar e interactuar con contratos inteligentes con nuestra interfaz de línea de comandos.", - "page-local-environment-openZeppelin-logo-alt": "Logo de OpenZeppelin", - "page-local-environment-scaffold-eth-desc": "Ethers + Hardhat + React: todo lo que necesita para comenzar a construir aplicaciones descentralizadas con contratos inteligentes.", - "page-local-environment-scaffold-eth-logo-alt": "Logo de scaffold-eth", - "page-local-environment-setup-meta-desc": "Guía sobre cómo elegir la pila de software para el desarrollo de Ethereum.", - "page-local-environment-setup-meta-title": "Configuración de desarrollo local de Ethereum", - "page-local-environment-setup-subtitle": "Si está listo para empezar a desarrollar, es hora de elegir su pila.", - "page-local-environment-setup-subtitle-2": "Aquí están las herramientas y marcos que puede usar para crear su aplicación Ethereum.", - "page-local-environment-setup-title": "Configure su entorno de desarrollo local", - "page-local-environment-solidity-template-desc": "Una plantilla de GitHub con una configuración predefinida para sus contratos inteligentes en Solidity. Incluye una red local de Hardhat y Ethers para la implementación de carteras, entre otras funciones.", - "page-local-environment-solidity-template-logo-alt": "Logo de plantilla Solidity" -} diff --git a/src/intl/fr/page-developers-learning-tools.json b/src/intl/fr/page-developers-learning-tools.json deleted file mode 100644 index 7643fedb222..00000000000 --- a/src/intl/fr/page-developers-learning-tools.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "Le cours sur Web3 de BloomTech vous enseignera les compétences que les employeurs recherchent chez les ingénieurs.", - "page-learning-tools-bloomtech-logo-alt": "Logo BloomTech", - "page-learning-tools-bootcamps": "Camps de démarrage des développeurs", - "page-learning-tools-bootcamps-desc": "Des cours en ligne payants pour vous permettre de gagner en vitesse, rapidement.", - "page-learning-tools-browse-docs": "Parcourir la documentation", - "page-learning-tools-capture-the-ether-description": "Capture l'Ether est un jeu dans lequel vous piratez les contrats intelligents Ethereum pour en apprendre plus sur la sécurité.", - "page-learning-tools-capture-the-ether-logo-alt": "Logo capture l'Ether", - "page-learning-tools-node-guardians-description": "Node Guardians est une plateforme éducative et ludique qui plonge les développeurs web3 dans des quêtes prenant place dans un univers fantastique pour apprendre à maîtriser des langages de programmation tels que Solidity, Cairo, Noir et Huff.", - "page-learning-tools-node-guardians-logo-alt": "Logo de Node Guardians", - "page-learning-tools-coding": "Apprendre en codant", - "page-learning-tools-coding-subtitle": "Ces outils vous aideront à vous familiariser avec Ethereum si vous préférez une expérience d'apprentissage plus interactive.", - "page-learning-tools-consensys-academy-description": "Camp de démarrage des développeurs Ethereum en ligne.", - "page-learning-tools-consensys-academy-logo-alt": "Logo ConsenSys Academy", - "page-learning-tools-cryptozombies-description": "Apprenez le langage Solidity en construisant votre propre jeu de zombie.", - "page-learning-tools-cryptozombies-logo-alt": "Logo CryptoZombies", - "page-learning-tools-dapp-world-description": "Un écosystème de perfectionnement de la blockchain, comprenant des cours, des quiz, des exercices pratiques et des concours hebdomadaires.", - "page-learning-tools-dapp-world-logo-alt": "Logo de Dapp World", - "page-learning-tools-documentation": "Apprendre avec la documentation", - "page-learning-tools-documentation-desc": "Vous voulez en savoir plus ? Explorez notre documentation pour trouver l'explication dont vous avez besoin.", - "page-learning-tools-eth-dot-build-description": "Un espace de test éducatif pour Web3, incluant la programmation par glisser-déposer et les blocs de construction open source.", - "page-learning-tools-eth-dot-build-logo-alt": "Logo Eth.build", - "page-learning-tools-ethernauts-description": "Terminez les niveaux en piratant des contrats intelligents.", - "page-learning-tools-ethernauts-logo-alt": "Logo Ethereum", - "page-learning-tools-metaschool-description": "Devenez développeur Web3 en construisant et expédiant des dApps.", - "page-learning-tools-metaschool-logo-alt": "Logo _metaschool", - "page-learning-tools-game-tutorials": "Tutoriels interactifs", - "page-learning-tools-game-tutorials-desc": "Apprenez en jouant. Ces tutoriels vous permettent de parcourir les bases de façon ludique.", - "page-learning-tools-meta-desc": "Outils de codage en ligne et expériences d'apprentissage interactif pour vous aider à faire des expériences avec le développement d'Ethereum.", - "page-learning-tools-meta-title": "Outils d'apprentissage pour les développeurs", - "page-learning-tools-atlas-logo-alt": "Logo d'Atlas", - "page-learning-tools-atlas-description": "Écrivez, testez et déployez des contrats intelligents en quelques minutes avec l'IDE Atlas.", - "page-learning-tools-questbook-description": "Tutoriels auto-initiés pour apprendre Web 3.0 en construisant", - "page-learning-tools-questbook-logo-alt": "Logo du Questbook", - "page-learning-tools-remix-description": "Développez, déployez et administrez des contrats intelligents pour Ethereum. Suivez des tutoriels avec le plugin LearnEth.", - "page-learning-tools-remix-description-2": "Remix, Replit, ChainIDE et Atlas ne sont pas seulement des bacs à sable : ils permettent aux développeurs d'écrire, de compiler et de déployer leurs contrats intelligents.", - "page-learning-tools-replit-description": "Un environnement de développement personnalisable dédiée à Ethereum avec le rechargement à chaud, une vérification des erreurs et un support testnet de première qualité.", - "page-learning-tools-chainIDE-description": "Commencez votre voyage Web3 en écrivant des contrats intelligents pour Ethereum avec ChainIDE. Utilisez les modèles intégrés pour apprendre et gagner du temps.", - "page-learning-tools-chainIDE-logo-alt": "Logo ChainIDE", - "page-learning-tools-tenderly-description": "Le bac à sable Tenderly est un environnement de prototypage où vous pouvez écrire, exécuter, et déboguer les contrats intelligents dans le navigateur en utilisant Solidity et JavaScript.", - "page-learning-tools-tenderly-logo-alt": "Logo de Tenderly", - "page-learning-tools-replit-logo-alt": "Logo Replit", - "page-learning-tools-remix-logo-alt": "Logo Remix", - "page-learning-tools-sandbox": "Boîtes à sable de code", - "page-learning-tools-sandbox-desc": "Ces espaces de test vous permettront de faire des expériences avec la rédaction de contrats intelligents et de mieux comprendre d'Ethereum.", - "page-learning-tools-speed-run-ethereum-description": "Speed Run Ethereum est un ensemble de défis pour tester vos connaissances en Solidity en utilisant Scaffold-ETH", - "page-learning-tools-speed-run-ethereum-logo-alt": "Logo de Speed Run Ethereum", - "page-learning-tools-studio-description": "Un IDE basé sur le Web où vous pouvez suivre des tutoriels pour créer et tester des contrats intelligents, et construire un frontend pour eux.", - "page-learning-tools-vyperfun-description": "Apprenez à développer avec Vyper en construisant votre propre jeu de Pokémon.", - "page-learning-tools-vyperfun-logo-alt": "Logo Vyper.fun", - "page-learning-tools-nftschool-description": "Explorez le côté technique des jetons non fongibles, ou NFT.", - "page-learning-tools-nftschool-logo-alt": "Jetons non fongibles du logo de l'école", - "page-learning-tools-platzi-description": "Apprenez à construire des DApps sur Web3 et maîtrisez toutes les compétences nécessaires pour être un développeur blockchain.", - "page-learning-tools-platzi-logo-alt": "Logo de Platzi", - "page-learning-tools-alchemy-university-description": "Boostez votre carrière Web3 grâce à des cours, projets et du code.", - "page-learning-tools-alchemy-university-logo-alt": "Logo d'Alchemy University", - "page-learning-tools-learnweb3-description": "LearnWeb3 est une plateforme éducative gratuite et de haute qualité pour passer de débutant à expert en développement web3.", - "page-learning-tools-learnweb3-logo-alt": "Logo de LearnWeb3", - "page-learning-tools-cyfrin-updraft-description": "Apprenez le développement de contrats intelligents pour tous les niveaux de compétence et les audits de sécurité.", - "page-learning-tools-cyfrin-updraft-logo-alt": "Logo de Cyfrin Updraft", - "alt-eth-blocks": "Illustration de blocs organisés comme un symbole ETH" -} diff --git a/src/intl/fr/page-developers-local-environment.json b/src/intl/fr/page-developers-local-environment.json deleted file mode 100644 index c9de602899e..00000000000 --- a/src/intl/fr/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "Une structure de développement et de test basée sur Python pour les contrats intelligents ciblant la machine virtuelle Ethereum.", - "page-local-environment-brownie-logo-alt": "Logo Brownie", - "page-local-environment-kurtosis-desc": "Une boite à outils basée sur des conteneurs permettant de configurer et de lancer facilement des réseaux de test Ethereum multi-client en vue de développer rapidement des dApps en local, de prototyper, et de tester.", - "page-local-environment-kurtosis-logo-alt": "Logo de Kurtosis", - "page-local-environment-epirus-desc": "Une plateforme pour développer, déployer et surveiller des applications pour la blockchain sur la machine virtuelle Java.", - "page-local-environment-epirus-logo-alt": "Logo Epirus", - "page-local-environment-eth-app-desc": "Créez des applications sur Ethereum avec une seule commande, qui fournit une offre diversifiée de frameworks d'interface utilisateur et de modèles de finance décentralisée (DeFi).", - "page-local-environment-eth-app-logo-alt": "Logo Créer une application Eth", - "page-local-environment-foundry-desc": "Une boîte à outils rapide, portable et modulaire pour le développement d'applications Ethereum écrite en Rust.", - "page-local-environment-foundry-logo-alt": "Logo de la fonderie", - "page-local-environment-framework-feature-1": "Fonctionnalités pour faire tourner une instance locale de la blockchain.", - "page-local-environment-framework-feature-2": "Des utilitaires pour compiler et tester vos contrats intelligents.", - "page-local-environment-framework-feature-3": "Des modules de développement client pour construire votre application orientée utilisateur au sein du même projet / référentiel.", - "page-local-environment-framework-feature-4": "Configuration pour se connecter aux réseaux Ethereum et déployer des contrats, que ce soit sur une instance exécutée localement ou sur l'un des réseaux publics d'Ethereum.", - "page-local-environment-framework-feature-5": "Distribution d'applications décentralisée - intégrations avec des options de stockage comme IPFS.", - "page-local-environment-framework-features": "Ces frameworks sont livrés avec de nombreuses fonctionnalités prêtes à l'emploi, telles que :", - "page-local-environment-frameworks-desc": " Nous vous recommandons de choisir un framework, en particulier si vous êtes encore débutant. Construire une DApp à part entière nécessite différentes technologies. Les frameworks incluent de nombreuses fonctionnalités nécessaires ou fournissent des systèmes de plugins faciles pour choisir les outils que vous désirez.", - "page-local-environment-frameworks-title": "Framework et piles préfabriquées", - "page-local-environment-hardhat-desc": "Hardhat est un environnement de développement Ethereum pour les professionnels.", - "page-local-environment-hardhat-logo-alt": "Logo Hardhat", - "page-local-environment-openZeppelin-desc": "Épargnez-vous de longues heures de développement en compilant, en mettant à niveau, en déployant et en interagissant avec des contrats intelligents par le biais de notre Interface de ligne de commande.", - "page-local-environment-openZeppelin-logo-alt": "Logo OpenZeppelin", - "page-local-environment-scaffold-eth-desc": "Ethers + Hardhat + React : tout ce dont vous avez besoin pour commencer à créer des applications décentralisées, alimentées par des contrats intelligents.", - "page-local-environment-scaffold-eth-logo-alt": "logo scaffold-eth", - "page-local-environment-setup-meta-desc": "Guide sur comment choisir votre pile logicielle pour le développement Ethereum.", - "page-local-environment-setup-meta-title": "Configuration du développement local Ethereum", - "page-local-environment-setup-subtitle": "Si vous êtes prêt à commencer à construire, il est temps de choisir votre pile.", - "page-local-environment-setup-subtitle-2": " Voici les outils et les frameworks que vous pouvez utiliser pour vous aider à créer votre application Ethereum.", - "page-local-environment-setup-title": "Configurez votre environnement de développement local", - "page-local-environment-solidity-template-desc": "Un modèle GitHub pour une configuration pré-intégrée de vos contrats intelligents Solidity. Comprend un réseau local Hardhat, des Ethers pour la mise en œuvre du portefeuille, et plus encore.", - "page-local-environment-solidity-template-logo-alt": "Logo de modèle Solidity" -} \ No newline at end of file diff --git a/src/intl/hi/page-developers-learning-tools.json b/src/intl/hi/page-developers-learning-tools.json deleted file mode 100644 index 488ccacd397..00000000000 --- a/src/intl/hi/page-developers-learning-tools.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "BloomTech Web3 पाठ्यक्रम आपको वह कौशल सिखाएगा जो नियोक्ता इंजीनियरों में तलाश करते हैं।", - "page-learning-tools-bloomtech-logo-alt": "BloomTech लोगो", - "page-learning-tools-bootcamps": "डेवलपर बूटकैंप्स", - "page-learning-tools-bootcamps-desc": "आपको गति देने, तेज़ करने के लिए सशुल्क ऑनलाइन पाठ्यक्रम।", - "page-learning-tools-browse-docs": "दस्तावेज़ ब्राउज़ करें", - "page-learning-tools-capture-the-ether-description": "Capture the Ether एक ऐसा गेम है जिसमें आप सुरक्षा के बारे में जानने के लिए इथेरियम स्मार्ट अनुबंध को हैक करते हैं।", - "page-learning-tools-capture-the-ether-logo-alt": "Capture the Ether लोगो", - "page-learning-tools-coding": "कोडिंग द्वारा सीखें", - "page-learning-tools-coding-subtitle": "यदि आप सीखने के अधिक संवादात्मक अनुभव को पसंद करते हैं, तो ये उपकरण आपको इथेरियम के साथ प्रयोग करने में मदद करेंगे।", - "page-learning-tools-consensys-academy-description": "ऑनलाइन इथेरियम डेवलपर बूटकैंप.", - "page-learning-tools-consensys-academy-logo-alt": "ConsenSys Academy का लोगो", - "page-learning-tools-cryptozombies-description": "अपना खुद का ज़ोंबी गेम बनाने के लिए Solidity सीखें।", - "page-learning-tools-cryptozombies-logo-alt": "CryptoZombies का लोगो", - "page-learning-tools-documentation": "प्रलेखन के साथ जानें", - "page-learning-tools-documentation-desc": "और सीखना चाहते हैं? आपके लिए आवश्यक स्पष्टीकरणों को खोजने के लिए हमारे दस्तावेज़ पर जाएँ।", - "page-learning-tools-eth-dot-build-description": "Web3 के लिए एक शैक्षिक सैंडबॉक्स, जिसमें ड्रैग-एंड-ड्रॉप प्रोग्रामिंग और ओपन-सोर्स बिल्डिंग ब्लॉक शामिल हैं।", - "page-learning-tools-eth-dot-build-logo-alt": "Eth.build का लोगो", - "page-learning-tools-ethernauts-description": "स्मार्ट अनुबंध को हैक करके स्तर पूरा करें.", - "page-learning-tools-ethernauts-logo-alt": "Ethernauts का लोगो", - "page-learning-tools-metaschool-description": "dApps के निर्माण और शिपिंग द्वारा एक Web3 डेवलपर बनें।", - "page-learning-tools-metaschool-logo-alt": "_metaschool लोगो", - "page-learning-tools-game-tutorials": "इंटरैक्टिव गेम ट्यूटोरियल", - "page-learning-tools-game-tutorials-desc": "खेलते समय सीखें। ये ट्यूटोरियल आपको गेमप्ले का उपयोग करके बुनियादी बातों की जानकारी प्रदान करता है", - "page-learning-tools-meta-desc": "वेब आधारित कोडिंग टूल और इंटरैक्टिव लर्निंग एक्सपीरियंस आपको इथेरियम विकास के साथ प्रयोग करने में मदद करते हैं।", - "page-learning-tools-meta-title": "डेवलपर के सीखने के उपकरण", - "page-learning-tools-questbook-description": "निर्माण द्वारा Web 3.0 सीखने के लिए स्व-गति वाले ट्यूटोरियल", - "page-learning-tools-questbook-logo-alt": "Questbook लोगो", - "page-learning-tools-remix-description": "इथेरियम के लिए स्मार्ट अनुबंध का विकास, परिनियोजन और प्रशासन। LearnEth प्लगइन के साथ ट्यूटोरियल का पालन करें।", - "page-learning-tools-remix-description-2": "Remix, Replit और ChainIDE सिर्फ सैंडबॉक्स नहीं हैं—डेवलपर्स उनका उपयोग करके अपने स्मार्ट अनुबंधों को लिख, संकलित और तैनात कर सकते हैं।", - "page-learning-tools-replit-description": "हॉट रिलोडिंग त्रुटि जाँच और प्रथम श्रेणि टेस्टनेट समर्थन के साथ इथेरियम के लिए एक अनुकूलन योग्य विकास वातावरण।", - "page-learning-tools-chainIDE-description": "ChainIDE के साथ इथेरियम के लिए स्मार्ट अनुबंध लिखकर Web3 की अपनी यात्रा शुरू करें। सीखने और समय बचाने के लिए अंतर्निहित टेम्पलेट्स का उपयोग करें।", - "page-learning-tools-chainIDE-logo-alt": "ChainIDE लोगो", - "page-learning-tools-tenderly-description": "Tenderly सैंडबॉक्स एक प्रोटोटाइप वातावरण है जहां आप Solidity और JavaScript का उपयोग करके ब्राउज़र में स्मार्ट अनुबंधों को लिख, निष्पादित और डीबग कर सकते हैं।", - "page-learning-tools-tenderly-logo-alt": "Tenderly लोगो", - "page-learning-tools-replit-logo-alt": "Replit लोगो", - "page-learning-tools-remix-logo-alt": "Remix का लोगो", - "page-learning-tools-sandbox": "कोड सैंडबॉक्स", - "page-learning-tools-sandbox-desc": "ये सैंडबॉक्स आपको स्मार्ट अनुबंध लिखने और इथेरियम को समझने के साथ प्रयोग करने के लिए एक स्थान देंगे।", - "page-learning-tools-speed-run-ethereum-description": "Speed Run Ethereum, Scaffold-ETH का उपयोग करके अपने Solidity ज्ञान का परीक्षण करने के लिए चुनौतियों का एक सेट है", - "page-learning-tools-speed-run-ethereum-logo-alt": "Speed Run Ethereum लोगो", - "page-learning-tools-studio-description": "एक वेब-आधारित IDE, जहां पर आप स्मार्ट अनुबंध बनाने और परीक्षण करने के लिए ट्यूटोरियल का अनुसरण कर सकते हैं, और उनके लिए एक फ़्रंटएंड का निर्माण कर सकते हैं।", - "page-learning-tools-vyperfun-description": "अपना खुद का Pokémon गेम बनाने के लिए Vyper के बारे में जानें।", - "page-learning-tools-vyperfun-logo-alt": "Vyper.fun का लोगो", - "page-learning-tools-nftschool-description": "तकनीकी पक्ष से जानें कि अपूरणीय टोकन या NFT के साथ क्या हो रहा है।", - "page-learning-tools-nftschool-logo-alt": "NFT school लोगो", - "page-learning-tools-platzi-description": "Web3 पर dapps बनाना सीखें और ब्लॉकचेन डेवलपर बनने के लिए आवश्यक सभी कौशलों में महारत हासिल करें।", - "page-learning-tools-platzi-logo-alt": "Platzi लोगो", - "page-learning-tools-alchemy-university-description": "पाठ्यक्रम, परियोजनाओं और कोड के माध्यम से अपने web3 कैरियर का विकास करें।", - "page-learning-tools-alchemy-university-logo-alt": "Alchemy University लोगो", - "alt-eth-blocks": "ETH प्रतीक की तरह व्यवस्थित किए जा रहे ब्लॉकों का चित्रण" -} \ No newline at end of file diff --git a/src/intl/hi/page-developers-local-environment.json b/src/intl/hi/page-developers-local-environment.json deleted file mode 100644 index 989bd7d2e6b..00000000000 --- a/src/intl/hi/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "इथेरियम वर्चुअल मशीन को लक्षित करने वाले स्मार्ट अनुबंधों के लिए Python-आधारित डेवलपमेंट और परीक्षण संरचना।", - "page-local-environment-brownie-logo-alt": "Brownie का लोगो", - "page-local-environment-kurtosis-desc": "तेजी से स्थानीय dApp विकास, प्रोटोटाइपिंग और परीक्षण के लिए मल्टी-क्लाइंट इथेरियम टेस्टनेट को आसानी से कॉन्फ़िगर और चालू करने के लिए एक कंटेनर-आधारित टूलकिट।", - "page-local-environment-kurtosis-logo-alt": "Kurtosis लोगो", - "page-local-environment-epirus-desc": "Java वर्चुअल मशीन पर ब्लॉकचेन एप्लिकेशन को डेवलप करने, परिनियोजित करने और मॉनिटर करने के लिए एक प्लेटफ़ॉर्म।", - "page-local-environment-epirus-logo-alt": "Epirus का लोगो", - "page-local-environment-eth-app-desc": "एक आदेश के साथ इथेरियम संचालित ऐप बनाएं। चुनने के लिए UI फ्रेमवर्क और DeFi टेम्पलेट की एक विस्तृत पेशकश के साथ आता है।", - "page-local-environment-eth-app-logo-alt": "Eth ऐप का लोगो बनाएं", - "page-local-environment-foundry-desc": "इथेरियम एप्लिकेशन डेवलपमेंट के लिए रस्ट प्रोग्रामिंग भाषा में लिखा गया एक बहुत तेज़, पोर्टेबल और मॉड्यूलर टूलकिट।", - "page-local-environment-foundry-logo-alt": "Foundry लोगो", - "page-local-environment-framework-feature-1": "एक स्थानीय ब्लॉकचेन उदाहरण को स्पिन करने के लिए विशेष रूप से प्रदर्शित होता है।", - "page-local-environment-framework-feature-2": "आपके स्मार्ट अनुबंध को संकलित करने और परीक्षण करने के लिए उपयोगिताएँ।", - "page-local-environment-framework-feature-3": "एक ही प्रोजेक्ट/रिपॉजिटरी के भीतर आपके उपयोगकर्ता-उन्मुख एप्लिकेशन के निर्माण के लिए क्लाइंट डेवलपमेंट ऐड-ऑन।", - "page-local-environment-framework-feature-4": "इथेरियम नेटवर्क से कनेक्ट होने और अनुबंधों को परिनियोजित करने के लिए कॉन्फ़िगरेशन, चाहे वह स्थानीय रूप से चल रहे इंस्टेंस के लिए हों या इथेरियम के सार्वजनिक नेटवर्कों में से एक हो।", - "page-local-environment-framework-feature-5": "विकेंद्रीकृत ऐप वितरण - IPFS जैसे भंडारण विकल्पों के साथ एकीकरण।", - "page-local-environment-framework-features": "ये संरचनाएं बहुत सारी अलग कार्यक्षमता के साथ आती हैं, जैसे:", - "page-local-environment-frameworks-desc": " हम एक संरचना चुनने की सलाह देते हैं, खासकर यदि आप अभी शुरू कर रहे हैं। पूर्ण विकसित डेप के निर्माण के लिए विभिन्न प्रौद्योगिकी की आवश्यकता होती है। संरचना में कई आवश्यक सुविधाएँ शामिल होती हैं या आपके इच्छित उपकरण को लेने के लिए आसान प्लगइन सिस्टम प्रदान करती हैं।", - "page-local-environment-frameworks-title": "संरचनाएं और पूर्व-निर्मित स्टैक", - "page-local-environment-hardhat-desc": "Hardhat पेशेवरों के लिए एक इथेरियम डेवलपमेंट परिवेश है।", - "page-local-environment-hardhat-logo-alt": "Hardhat का लोगो", - "page-local-environment-openZeppelin-desc": "हमारे CLI के साथ स्मार्ट अनुबंधों के साथ संकलन, अपग्रेड, परिनियोजन और सहभागिता करके डेवलपमेंट के समय की बचत करें।", - "page-local-environment-openZeppelin-logo-alt": "OpenZeppelin का लोगो", - "page-local-environment-scaffold-eth-desc": "इथर + हार्डहैट + रिएक्ट: स्मार्ट अनुबंधों द्वारा संचालित विकेंद्रीकृत अनुप्रयोगों का निर्माण शुरू करने के लिए आपको जो कुछ भी चाहिए वह सब कुछ।", - "page-local-environment-scaffold-eth-logo-alt": "scaffold-eth का लोगो", - "page-local-environment-setup-meta-desc": "इथेरियम डेवलपमेंट के लिए आपके सॉफ़्टवेयर स्टैक को चुनने के तरीके के बारे में मार्गदर्शिका।", - "page-local-environment-setup-meta-title": "इथेरियम स्थानीय डेवलपमेंट सेटअप", - "page-local-environment-setup-subtitle": "यदि आप निर्माण शुरू करने के लिए तैयार हैं, तो आपके स्टैक को चुनने का समय आ गया है।", - "page-local-environment-setup-subtitle-2": " यहां पर वे उपकरण और संरचनाएं मौजूद हैं, जिनका उपयोग आप अपने इथेरियम एप्लिकेशन को बनाने में मदद करने के लिए कर सकते हैं।", - "page-local-environment-setup-title": "अपना स्थानीय डेवलपमेंट परिवेश स्थापित करें", - "page-local-environment-solidity-template-desc": "आपके Solidity स्मार्ट अनुबंधों के लिए प्री-बिल्ट सेटअप के लिए GitHub टेम्पलेट। एक Hardhat स्थानीय नेटवर्क, परीक्षण के लिए Waffle, वॉलेट कार्यान्वयन के लिए Ethers, और भी बहुत कुछ शामिल है।", - "page-local-environment-solidity-template-logo-alt": "Solidity टेम्पलेट का लोगो" -} \ No newline at end of file diff --git a/src/intl/id/page-developers-learning-tools.json b/src/intl/id/page-developers-learning-tools.json deleted file mode 100644 index e951a79ea3f..00000000000 --- a/src/intl/id/page-developers-learning-tools.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "Kursus Web3 BloomTech akan mengajarkan tentang keterampilan yang dicari para pemberi kerja dalam bidang insinyur.", - "page-learning-tools-bloomtech-logo-alt": "Logo BloomTech", - "page-learning-tools-bootcamps": "Kamp pelatihan pengembang", - "page-learning-tools-bootcamps-desc": "Kursus online berbayar agar Anda mendapatkan informasi terbaru dengan cepat.", - "page-learning-tools-browse-docs": "Jelajahi dokumen", - "page-learning-tools-capture-the-ether-description": "Capture the Ether adalah sebuah game di mana Anda meretas kontrak pintar Ethereum untuk belajar tentang keamanan.", - "page-learning-tools-capture-the-ether-logo-alt": "Logo Capture the Ether", - "page-learning-tools-node-guardians-description": "Simpul Guardian adalah platform edukasi gamifikasi yang membenamkan para pengembang web3 dalam petualangan bertema fantasi untuk menguasai pemrograman Solidity, Kairo, Noir, dan Hurf.", - "page-learning-tools-node-guardians-logo-alt": "Logo Simpul Guardians", - "page-learning-tools-coding": "Belajar melalui pengodean", - "page-learning-tools-coding-subtitle": "Peralatan ini akan membantu Anda bereksperimen dengan Ethereum jika Anda lebih suka pengalaman belajar yang lebih interaktif.", - "page-learning-tools-consensys-academy-description": "Kamp pelatihan pengembang Ethereum online.", - "page-learning-tools-consensys-academy-logo-alt": "Logo Akademi ConsenSys", - "page-learning-tools-cryptozombies-description": "Pelajari Solidity yang membuat game Zombie karya Anda.", - "page-learning-tools-cryptozombies-logo-alt": "Logo CryptoZombies", - "page-learning-tools-dapp-world-description": "Ekosistem peningkatan keterampilan rantai blok, termasuk kursus, kuis, praktik langsung, dan kontes mingguan.", - "page-learning-tools-dapp-world-logo-alt": "Logo Dapp World", - "page-learning-tools-documentation": "Belajar dengan dokumentasi", - "page-learning-tools-documentation-desc": "Ingin mempelajari lebih lanjut? Buka dokumentasi kami untuk menemukan penjelasan yang Anda butuhkan.", - "page-learning-tools-eth-dot-build-description": "Sandbox pendidikan untuk web3, termasuk pemrograman seret dan lepas dan blok penyusun sumber terbuka.", - "page-learning-tools-eth-dot-build-logo-alt": "Logo Eth.build", - "page-learning-tools-ethernauts-description": "Selesaikan level dengan meretas kontrak pintar.", - "page-learning-tools-ethernauts-logo-alt": "Logo Ethernauts", - "page-learning-tools-metaschool-description": "Menjadi Pengembang Web3 dengan membangun & mengirimkan dApps.", - "page-learning-tools-metaschool-logo-alt": "Logo _metaschool", - "page-learning-tools-game-tutorials": "Tutorial game interaktif", - "page-learning-tools-game-tutorials-desc": "Belajar sambil bermain. Tutorial ini membantu Anda memahami dasar-dasar menggunakan gameplay.", - "page-learning-tools-meta-desc": "Peralatan pengodean berbasis web dan pengalaman belajar interaktif untuk membantu Anda bereksperimen dengan pengembangan Ethereum.", - "page-learning-tools-meta-title": "Alat pembelajaran pengembang", - "page-learning-tools-atlas-logo-alt": "Logo Atlas", - "page-learning-tools-atlas-description": "Menulis, menguji, dan menerapkan kontrak pintar dalam hitungan menit dengan Atlas IDE.", - "page-learning-tools-questbook-description": "Tutorial mandiri untuk belajar tentang Web 3.0 dengan membangunnya", - "page-learning-tools-questbook-logo-alt": "Logo Questbook", - "page-learning-tools-remix-description": "Mengembangkan, menyebarkan dan mengelola kontrak pintar untuk Ethereum. Ikuti langkah-langkahnya dengan plugin LearnEth.", - "page-learning-tools-remix-description-2": "Remix, Replit, ChainIDE, dan Atlas bukan hanya sekadar kotak pasir—pengembang dapat menulis, menyusun, dan menerapkan kontrak pintar mereka dengan menggunakannya.", - "page-learning-tools-replit-description": "Lingkungan pengembangan yang dapat disesuaikan untuk Ethereum menggunakan hot reloading, error checking, dan dukungan first-class testnet.", - "page-learning-tools-chainIDE-description": "Mulailah perjalanan Anda ke Web3 dengan menulis kontrak pintar untuk Ethereum dengan ChainIDE. Gunakan templat bawaan untuk mempelajari dan menghemat waktu.", - "page-learning-tools-chainIDE-logo-alt": "Logo ChainIDE", - "page-learning-tools-tenderly-description": "Tenderly Sandbox adalah lingkungan prototipe di mana Anda dapat menulis, melaksanakan, dan men-debug kontrak pintar di browser menggunakan Solidity dan JavaScript.", - "page-learning-tools-tenderly-logo-alt": "Logo Tenderly", - "page-learning-tools-replit-logo-alt": "Logo Replit", - "page-learning-tools-remix-logo-alt": "Logo Remix", - "page-learning-tools-sandbox": "Sandbox kode", - "page-learning-tools-sandbox-desc": "Sandbox ini akan memberi Anda ruang untuk bereksperimen dengan menulis kontrak pintar dan memahami Ethereum.", - "page-learning-tools-speed-run-ethereum-description": "Speed Run Ethereum adalah set tantangan untuk menguji pengetahuan Solidity Anda menggunakan Scaffold-ETH", - "page-learning-tools-speed-run-ethereum-logo-alt": "Logo Speed Run Ethereum", - "page-learning-tools-studio-description": "IDE berbasis web di mana Anda dapat mengikuti tutorial untuk membuat dan menguji kontrak pintar, dan membangun frontend untuk mereka.", - "page-learning-tools-vyperfun-description": "Pelajari Vyper yang membuat game Pokémon karya Anda.", - "page-learning-tools-vyperfun-logo-alt": "Logo Vyper.fun", - "page-learning-tools-nftschool-description": "Jelajahi apa yang sedang terjadi dengan token yang tidak dapat dipertukarkan, atau NFT dari sisi teknisnya.", - "page-learning-tools-nftschool-logo-alt": "Logo sekolah NFT", - "page-learning-tools-platzi-description": "Pelajari cara membuat dapps (aplikasi terdesentralisasi) di Web3 dan kuasai semua keterampilan yang dibutuhkan untuk menjadi pengembang rantai blok.", - "page-learning-tools-platzi-logo-alt": "Logo Platzi", - "page-learning-tools-alchemy-university-description": "Kembangkan karier web3 Anda melalui kursus, proyek, dan kode.", - "page-learning-tools-alchemy-university-logo-alt": "Logo Universitas Alchemy", - "page-learning-tools-learnweb3-description": "LearnWeb3 adalah platform gratis dan berkualitas untuk belajar mengembangkan web3 dari nol.", - "page-learning-tools-learnweb3-logo-alt": "Logo LearnWeb3", - "page-learning-tools-cyfrin-updraft-description": "Belajar mengembangkan kontrak pintar untuk semua tingkat keahlian dan audit keamanan.", - "page-learning-tools-cyfrin-updraft-logo-alt": "Logo Cyfrin Updraft", - "alt-eth-blocks": "Ilustrasi blok yang diorganisir seperti simbol ETH" -} diff --git a/src/intl/id/page-developers-local-environment.json b/src/intl/id/page-developers-local-environment.json deleted file mode 100644 index 42ac021fb78..00000000000 --- a/src/intl/id/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "Kerangka kerja pengembangan dan pengujian berbasis Python untuk kontrak pintar yang menargetkan Mesin Virtual Ethereum.", - "page-local-environment-brownie-logo-alt": "Logo Brownie", - "page-local-environment-kurtosis-desc": "Seperangkat alat berbasis kontainer yang memudahkan mengatur dan mengaktifkan jaringan percobaan Ethereum multi-klien untuk pengembangan, pembuatan prototipe, dan pengujian dApp lokal secara cepat.", - "page-local-environment-kurtosis-logo-alt": "Logo Kurtosis", - "page-local-environment-epirus-desc": "Platform untuk mengembangkan, menggunakan, dan memantau aplikasi rantai blok pada Java Virtual Machine.", - "page-local-environment-epirus-logo-alt": "Logo Epirus", - "page-local-environment-eth-app-desc": "Buat aplikasi yang didukung Ethereum dengan satu perintah. Hadir dengan berbagai penawaran kerangka kerja UI dan templat DeFi yang bisa dipilih.", - "page-local-environment-eth-app-logo-alt": "Buat logo Applikasi Eth", - "page-local-environment-foundry-desc": "Sebuah alat pengembangan aplikasi Ethereum yang sangat cepat, portabel, dan modular yang ditulis dalam bahasa Rust.", - "page-local-environment-foundry-logo-alt": "Logo Foundry", - "page-local-environment-framework-feature-1": "Fitur untuk memutar instance blockchain lokal.", - "page-local-environment-framework-feature-2": "Utilitas untuk mengompilasi dan menguji kontrak pintar Anda.", - "page-local-environment-framework-feature-3": "Add-on pengembangan klien untuk membangun aplikasi sisi pengguna dalam proyek/repositori yang sama.", - "page-local-environment-framework-feature-4": "Konfigurasi untuk menghubungkan ke jaringan Ethereum dan menggunakan kontrak, baik ke instance yang berjalan secara lokal, atau salah satu jaringan publik Ethereum.", - "page-local-environment-framework-feature-5": "Pendistribusian aplikasi terdesentralisasi - integrasi dengan opsi penyimpanan seperti IPFS.", - "page-local-environment-framework-features": "Kerangka kerja ini hadir dengan banyak fungsi yang tidak biasa, seperti:", - "page-local-environment-frameworks-desc": "Kami sarankan memilih sebuah kerangka kerja, terutama jika Anda baru mulai. Membangun sebuah dapp yang lengkap membutuhkan berbagai teknologi. Kerangka kerja mencakup banyak fitur yang diperlukan atau menyediakan sistem plugin yang mudah untuk memilih alat yang Anda inginkan.", - "page-local-environment-frameworks-title": "Kerangka kerja dan tumpukan yang sudah jadi", - "page-local-environment-hardhat-desc": "Hardhat adalah sebuah lingkungan pengembangan Ethereum untuk para profesional.", - "page-local-environment-hardhat-logo-alt": "Logo Hardhat", - "page-local-environment-openZeppelin-desc": "Hemat waktu pengembangan dengan menggabungkan, meningkatkan, menggunakan, dan berinteraksi dengan kontrak pintar dengan CLI kami.", - "page-local-environment-openZeppelin-logo-alt": "Logo OpenZeppelin", - "page-local-environment-scaffold-eth-desc": "Ethers + Hardhat + React: semua yang Anda butuhkan untuk mulai membangun aplikasi terdesentralisasi yang didukung oleh kontrak pintar.", - "page-local-environment-scaffold-eth-logo-alt": "Logo scaffold-eth", - "page-local-environment-setup-meta-desc": "Panduan mengenai cara memilih tumpukan perangkat lunak Anda untuk pengembangan Ethereum.", - "page-local-environment-setup-meta-title": "Pengaturan pengembangan lokal Ethereum", - "page-local-environment-setup-subtitle": "Jika Anda sudah siap untuk mulai membangun, inilah waktunya untuk memilih tumpukan.", - "page-local-environment-setup-subtitle-2": "Berikut adalah peralatan dan kerangka kerja yang bisa digunakan untuk membantu membangun aplikasi Ethereum Anda.", - "page-local-environment-setup-title": "Siapkan lingkungan pengembangan lokal Anda", - "page-local-environment-solidity-template-desc": "Sebuah templat GitHub untuk pengaturan bawaan kontrak pintar Solidity Anda. Sudah termasuk sebuah jaringan lokal Hardhat, Waffle untuk pengujian, Ethers untuk implementasi dompet, dan banyak lagi.", - "page-local-environment-solidity-template-logo-alt": "Logo template Solidity" -} \ No newline at end of file diff --git a/src/intl/it/page-developers-learning-tools.json b/src/intl/it/page-developers-learning-tools.json deleted file mode 100644 index 94e814ac86d..00000000000 --- a/src/intl/it/page-developers-learning-tools.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "Il corso di Web3 di BloomTech ti insegnerà le abilità che i datori di lavoro cercano negli ingegneri.", - "page-learning-tools-bloomtech-logo-alt": "Logo di BloomTech", - "page-learning-tools-bootcamps": "Bootcamp per sviluppatori", - "page-learning-tools-bootcamps-desc": "Corsi online a pagamento per mettersi in pari velocemente.", - "page-learning-tools-browse-docs": "Sfoglia le documentazioni", - "page-learning-tools-capture-the-ether-description": "\"Capture the Ether\" è un gioco in cui violi i contratti intelligenti di Ethereum per imparare sulla sicurezza.", - "page-learning-tools-capture-the-ether-logo-alt": "Logo di Capture the Ether", - "page-learning-tools-node-guardians-description": "Node Guardians è una piattaforma educativa gamificata che immerge gli sviluppatori web3 in missioni a tema fantasy per padroneggiare la programmazione in Solidity, Cairo, Noir e Huff.", - "page-learning-tools-node-guardians-logo-alt": "Logo di Node Guardians", - "page-learning-tools-coding": "Impara scrivendo codice", - "page-learning-tools-coding-subtitle": "Questi strumenti ti aiuteranno a sperimentare con Ethereum se preferisci un'esperienza d'apprendimento più interattiva.", - "page-learning-tools-consensys-academy-description": "Bootcamp online per sviluppatori di Ethereum.", - "page-learning-tools-consensys-academy-logo-alt": "Logo di ConsenSys Academy", - "page-learning-tools-cryptozombies-description": "Impara Solidity creando il tuo gioco di Zombie.", - "page-learning-tools-cryptozombies-logo-alt": "Logo di CryptoZombies", - "page-learning-tools-dapp-world-description": "Un ecosistema di valorizzazione delle competenze sulla blockchain, che include corsi, quiz, esperienze pratiche e contest settimanali.", - "page-learning-tools-dapp-world-logo-alt": "Logo di Dapp World", - "page-learning-tools-documentation": "Impara con la documentazione", - "page-learning-tools-documentation-desc": "Vuoi imparare di più? Vai alla nostra documentazione per trovare le spiegazioni di cui hai bisogno.", - "page-learning-tools-eth-dot-build-description": "Un sandbox educativo per web3, che include la programmazione trascina e rilascia e i blocchi di costruzione open source.", - "page-learning-tools-eth-dot-build-logo-alt": "Logo di Eth.build", - "page-learning-tools-ethernauts-description": "Completa i livelli violando i contratti intelligenti.", - "page-learning-tools-ethernauts-logo-alt": "Logo di Ethernauts", - "page-learning-tools-metaschool-description": "Diventa uno sviluppatore Web3 creando e lanciando dApps.", - "page-learning-tools-metaschool-logo-alt": "Logo _metaschool", - "page-learning-tools-game-tutorials": "Tutorial di gioco interattivi", - "page-learning-tools-game-tutorials-desc": "Impara giocando. Questi tutorial ti insegneranno le basi usando il gioco.", - "page-learning-tools-meta-desc": "Strumenti di programmazione basati sul web ed esperienze d'apprendimento interattive per aiutarti a sperimentare con lo sviluppo di Ethereum.", - "page-learning-tools-meta-title": "Strumenti d'apprendimento per sviluppatori", - "page-learning-tools-atlas-logo-alt": "Logo di Atlas", - "page-learning-tools-atlas-description": "Scrivi, testa e distribuisci contratti intelligenti in pochi minuti con l'IDE di Atlas.", - "page-learning-tools-questbook-description": "Tutorial per autodidatti per imparare il Web 3.0 sviluppando", - "page-learning-tools-questbook-logo-alt": "Logo di Questbook", - "page-learning-tools-remix-description": "Sviluppa, distribuisci e amministra i contratti intelligenti per Ethereum. Segui i tutorial con il plugin di LearnEth.", - "page-learning-tools-remix-description-2": "Remix, Replit, ChainIDE e Atlas non sono semplici sandbox: utilizzandoli, gli sviluppatori possono scrivere, compilare e distribuire i propri contratti intelligenti.", - "page-learning-tools-replit-description": "Un ambiente di sviluppo personalizzabile per Ethereum con ricarica immediata, controllo degli errori e supporto della rete di prova di prima classe.", - "page-learning-tools-chainIDE-description": "Inizia il tuo viaggio verso il Web3 scrivendo contratti intelligenti per Ethereum con ChainIDE. Utilizza i modelli integrati per imparare e risparmiare tempo.", - "page-learning-tools-chainIDE-logo-alt": "Logo di ChainIDE", - "page-learning-tools-tenderly-description": "Tenderly Sandbox è un ambiente di prototipazione in cui è possibile scrivere, eseguire ed portare a termine il debug di contratti intelligenti nel browser utilizzando Solidity e JavaScript.", - "page-learning-tools-tenderly-logo-alt": "Logo di Tenderly", - "page-learning-tools-replit-logo-alt": "Logo di Replit", - "page-learning-tools-remix-logo-alt": "Logo di Remix", - "page-learning-tools-sandbox": "Sandbox del codice", - "page-learning-tools-sandbox-desc": "Questi sandbox ti offriranno uno spazio per sperimentare con la scrittura dei contratti intelligenti e la comprensione di Ethereum.", - "page-learning-tools-speed-run-ethereum-description": "Speed Run Ethereum è una serie di sfide per testare la tua conoscenza di Solidity utilizzando Scaffold-ETH", - "page-learning-tools-speed-run-ethereum-logo-alt": "Logo di Speed Run Ethereum", - "page-learning-tools-studio-description": "Un IDE basato sul web in cui puoi seguire i tutorial per creare e testare i contratti intelligenti, nonché crearne un frontend.", - "page-learning-tools-vyperfun-description": "Impara a usare Vyper creando il tuo gioco Pokémon.", - "page-learning-tools-vyperfun-logo-alt": "Logo di Vyper.fun", - "page-learning-tools-nftschool-description": "Esplora cosa succede coi token non fungibili, o NFT, dal punto di vista tecnico.", - "page-learning-tools-nftschool-logo-alt": "Logo della scuola di NFT", - "page-learning-tools-platzi-description": "Scopri come creare le dapp su Web3 e padroneggiare tutte le abilità necessarie per essere uno sviluppatore della blockchain.", - "page-learning-tools-platzi-logo-alt": "Logo di Platzi", - "page-learning-tools-alchemy-university-description": "Sviluppa la tua carriera in web3 con corsi, progetti e programmazione.", - "page-learning-tools-alchemy-university-logo-alt": "Logo di Alchemy University", - "page-learning-tools-learnweb3-description": "LearnWeb3 è una piattaforma educativa gratuita e d'alta qualità per diventare un asso nello sviluppo in Web3.", - "page-learning-tools-learnweb3-logo-alt": "Logo di LearnWeb3", - "page-learning-tools-cyfrin-updraft-description": "Impara lo sviluppo dei contratti intelligenti per tutti i livelli di abilità e i controlli di sicurezza.", - "page-learning-tools-cyfrin-updraft-logo-alt": "Logo di Cyfrin Updraft", - "alt-eth-blocks": "Figura di blocchi organizzati come simbolo ETH" -} diff --git a/src/intl/it/page-developers-local-environment.json b/src/intl/it/page-developers-local-environment.json deleted file mode 100644 index 213fcfa55c6..00000000000 --- a/src/intl/it/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "Un framework di test e sviluppo basato su Python per i contratti intelligenti destinati alla Macchina Virtuale di Ethereum.", - "page-local-environment-brownie-logo-alt": "Logo di Brownie", - "page-local-environment-kurtosis-desc": "Un kit di strumenti basato sul contenitore per configurare e avviare facilmente una rete di prova Ethereum multi-client che consenta un rapido sviluppo, prototipazione e test di dApp locali.", - "page-local-environment-kurtosis-logo-alt": "Logo di Kurtosis", - "page-local-environment-epirus-desc": "Una piattaforma per lo sviluppo, la distribuzione e il monitoraggio delle applicazioni blockchain sulla macchina virtuale di Java.", - "page-local-environment-epirus-logo-alt": "Logo di Epirus", - "page-local-environment-eth-app-desc": "Crea app basate su Ethereum con un comando. Viene fornito con un'ampia offerta di framework di interfaccia utente e modelli DeFi tra cui scegliere.", - "page-local-environment-eth-app-logo-alt": "Crea il logo dell'app Eth", - "page-local-environment-foundry-desc": "Un kit di strumenti incredibilmente veloce, portatile e modulare per lo sviluppo di applicazioni di Ethereum scritto in Rust.", - "page-local-environment-foundry-logo-alt": "Logo di Foundry", - "page-local-environment-framework-feature-1": "Funzionalità per avviare un'istanza blockchain locale.", - "page-local-environment-framework-feature-2": "Utilità per compilare e testare i tuoi contratti intelligenti.", - "page-local-environment-framework-feature-3": "Componenti aggiuntivi per lo sviluppo su client per creare un'applicazione per gli utenti all'interno dello stesso progetto/repository.", - "page-local-environment-framework-feature-4": "Configurazione per connettersi alle reti di Ethereum e distribuire i contratti, che sia a un'istanza operata localmente o una delle reti pubbliche di Ethereum.", - "page-local-environment-framework-feature-5": "Distribuzione decentralizzata delle app. Integrazioni con opzioni di storage come IPFS.", - "page-local-environment-framework-features": "Questi framework sono dotati di molte funzionalità disponibili subito, come:", - "page-local-environment-frameworks-desc": " Ti consigliamo di scegliere un framework, soprattutto se hai appena iniziato. Costruire una dapp completa richiede diversi componenti della tecnologia. I framework includono molte delle funzionalità necessarie o forniscono semplici sistemi plug-in per scegliere gli strumenti desiderati.", - "page-local-environment-frameworks-title": "Framework e stack preimpostati", - "page-local-environment-hardhat-desc": "Hardhat è un ambiente di sviluppo Ethereum per professionisti.", - "page-local-environment-hardhat-logo-alt": "Logo di Hardhat", - "page-local-environment-openZeppelin-desc": "Risparmia ore di sviluppo compilando, aggiornando, distribuendo e interagendo con i contratti intelligenti, con la nostra CLI.", - "page-local-environment-openZeppelin-logo-alt": "Logo di OpenZeppelin", - "page-local-environment-scaffold-eth-desc": "Ether + Hardhat + React: tutto ciò di cui hai bisogno per iniziare a creare applicazioni decentralizzate basate sui contratti intelligenti.", - "page-local-environment-scaffold-eth-logo-alt": "logo scaffold-eth", - "page-local-environment-setup-meta-desc": "Guida su come scegliere uno stack software per lo sviluppo Ethereum.", - "page-local-environment-setup-meta-title": "Configurazione di sviluppo locale Ethereum", - "page-local-environment-setup-subtitle": "Prima di iniziare a creare, è necessario scegliere uno stack.", - "page-local-environment-setup-subtitle-2": " Ecco gli strumenti e i framework che puoi utilizzare per creare un'applicazione Ethereum.", - "page-local-environment-setup-title": "Configura il tuo ambiente di sviluppo locale", - "page-local-environment-solidity-template-desc": "Un modello di GitHub per una configurazione predefinita per i tuoi contratti intelligenti in Solidity. Include una rete locale Hardhat, Waffle per i test, Ether per l'implementazione del portafoglio, e molto altro.", - "page-local-environment-solidity-template-logo-alt": "Logo del modello Solidity" -} \ No newline at end of file diff --git a/src/intl/ja/page-developers-learning-tools.json b/src/intl/ja/page-developers-learning-tools.json deleted file mode 100644 index 0926aad6ba9..00000000000 --- a/src/intl/ja/page-developers-learning-tools.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "BloomTech Web3コースでは、エンジニアに求められるスキルを学ぶことができます。", - "page-learning-tools-bloomtech-logo-alt": "BloomTechロゴ", - "page-learning-tools-bootcamps": "デベロッパーブートキャンプ", - "page-learning-tools-bootcamps-desc": "有料のオンラインコースを利用して、効率的に学習しましょう。", - "page-learning-tools-browse-docs": "ドキュメントを参照", - "page-learning-tools-capture-the-ether-description": "Capture the Etherは、イーサリアムのスマートコントラクトをハッキングして、セキュリティについて学ぶゲームです。", - "page-learning-tools-capture-the-ether-logo-alt": "イーサロゴをキャプチャ", - "page-learning-tools-node-guardians-description": "Node Guardiansは、web3デベロッパーがファンタジーテーマのクエストに没頭しながら、Solidity、Cairo、Noir、Huffのプログラミングをゲーム感覚でマスターできる教育プラットフォームです。", - "page-learning-tools-node-guardians-logo-alt": "Node Guardiansのロゴ", - "page-learning-tools-coding": "コーディングで学ぶ", - "page-learning-tools-coding-subtitle": "よりインタラクティブな学習体験を希望される場合、これらのツールはイーサリアムの実験に役立ちます。", - "page-learning-tools-consensys-academy-description": "オンラインのイーサリアムデベロッパーブートキャンプ", - "page-learning-tools-consensys-academy-logo-alt": "ConsenSys Academy ロゴ", - "page-learning-tools-cryptozombies-description": "Solidityを学んであなた自身のゾンビゲームを開発しましょう。", - "page-learning-tools-cryptozombies-logo-alt": "CryptoZombies ロゴ", - "page-learning-tools-dapp-world-description": "ブロックチェーンに関するスキルアップのエコシステムです。さまざまなコース、クイズ、ハンズオンによる実践、ウィークリーコンテストがあります。", - "page-learning-tools-dapp-world-logo-alt": "Dapp Worldのロゴ", - "page-learning-tools-documentation": "ドキュメントで学ぶ", - "page-learning-tools-documentation-desc": "詳細については、こちらのドキュメントを参照してください。", - "page-learning-tools-eth-dot-build-description": "ドラッグ&ドロップ式のプログラミングやオープンソースのビルディングブロック等の、web3用の教育用サンドボックス", - "page-learning-tools-eth-dot-build-logo-alt": "Eth.build ロゴ", - "page-learning-tools-ethernauts-description": "スマートコントラクトをハッキングして全てのレベルをクリアしましょう。", - "page-learning-tools-ethernauts-logo-alt": "Ethernauts ロゴ", - "page-learning-tools-metaschool-description": "分散型アプリ(dApps)を構築、出荷して、Web3開発者になりましょう。", - "page-learning-tools-metaschool-logo-alt": "_metaschoolロゴ", - "page-learning-tools-game-tutorials": "インタラクティブなゲームチュートリアル", - "page-learning-tools-game-tutorials-desc": "遊びながら学びましょう。これらのチュートリアルでは、ゲームをプレイしながら基本的な知識を身につけることができます。", - "page-learning-tools-meta-desc": "Webベースのコーディングツールとインタラクティブな学習体験により、イーサリアムの開発を実験することができます。", - "page-learning-tools-meta-title": "デベロッパー向けの学習ツール", - "page-learning-tools-atlas-logo-alt": "Atlasのロゴ", - "page-learning-tools-atlas-description": "Atlas IDEでスマートコントラクトの作成、テスト、デプロイを数分で行えます。", - "page-learning-tools-questbook-description": "構築しながらWeb 3.0をマイペースで学ぶチュートリアル", - "page-learning-tools-questbook-logo-alt": "Questbookロゴ", - "page-learning-tools-remix-description": "イーサリアム用のスマートコントラクトを開発、デプロイ、管理します。LearnEthプラグインを使用してチュートリアルに従ってください。", - "page-learning-tools-remix-description-2": "Remix、Replit、ChainIDE、Atlasは、単なるサンドボックスではありません。デベロッパーはこれらを使用して、独自のスマートコントラクトを作成、コンパイル、デプロイすることができます。", - "page-learning-tools-replit-description": "ホットリロード、エラーチェック、最高級のテストネットサポートを備えたカスタマイズ可能なイーサリアム開発環境。", - "page-learning-tools-chainIDE-description": "ChainIDEでイーサリアム用のスマートコントラクトを作成して、Web3への道を歩み始めましょう。ビルトインのテンプレートは学習の参考になるだけでなく、時間の節約にもなります。", - "page-learning-tools-chainIDE-logo-alt": "ChainIDEロゴ", - "page-learning-tools-tenderly-description": "Tenderly Sandboxとは、SolidityとJavaScriptを使用してブラウザでスマートコントラクトを記述、実行、デバッグするためのプロトタイピング環境です。", - "page-learning-tools-tenderly-logo-alt": "Tenderlyロゴ", - "page-learning-tools-replit-logo-alt": "Replitロゴ", - "page-learning-tools-remix-logo-alt": "Remix ロゴ", - "page-learning-tools-sandbox": "コードサンドボックス", - "page-learning-tools-sandbox-desc": "これらのサンドボックスは、スマートコントラクトを書いたり、イーサリアムを理解したりするための実験の場となります。", - "page-learning-tools-speed-run-ethereum-description": "Speed Run Ethereumには、Solidityの知識をScaffold-ETHを使ってテストできる演習問題があります。", - "page-learning-tools-speed-run-ethereum-logo-alt": "Speed Run Ethereumロゴ", - "page-learning-tools-studio-description": "WebベースのIDEでは、チュートリアルに従ってスマートコントラクトを作成してテストし、それらのフロントエンドを構築することができます。", - "page-learning-tools-vyperfun-description": "Vyperを学んでご自身のポケモンゲームを作りましょう。", - "page-learning-tools-vyperfun-logo-alt": "Vyper.fun ロゴ", - "page-learning-tools-nftschool-description": "非代替性トークン(NFT)について、技術的な側面から見てみましょう。", - "page-learning-tools-nftschool-logo-alt": "NFT schoolロゴ", - "page-learning-tools-platzi-description": "Web3で分散型アプリ(Dapp)を構築する方法を学び、ブロックチェーンデベロッパーに必要なすべてのスキルを習得しましょう。", - "page-learning-tools-platzi-logo-alt": "Platziロゴ", - "page-learning-tools-alchemy-university-description": "コース、プロジェクト、コードを通じて、Web3でのキャリアを築いてください。", - "page-learning-tools-alchemy-university-logo-alt": "Alchemy Universityロゴ", - "page-learning-tools-learnweb3-description": "LearnWeb3は、ゼロからWeb3開発のプロを目指せる、無料で高品質な教育プラットフォームです。", - "page-learning-tools-learnweb3-logo-alt": "LearnWeb3ロゴ", - "page-learning-tools-cyfrin-updraft-description": "スキルレベルに応じたスマートコントラクト開発やセキュリティ監査を学びましょう。", - "page-learning-tools-cyfrin-updraft-logo-alt": "Cyfrin Updraftロゴ", - "alt-eth-blocks": "ETHのシンボルのように構成されたブロックの図" -} diff --git a/src/intl/ja/page-developers-local-environment.json b/src/intl/ja/page-developers-local-environment.json deleted file mode 100644 index deef2fbff5b..00000000000 --- a/src/intl/ja/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "イーサリアム仮想マシンをターゲットとしたスマートコントラクトのためのPythonベースの開発とテストフレームワーク。", - "page-local-environment-brownie-logo-alt": "Brownie ロゴ", - "page-local-environment-kurtosis-desc": "ローカルdAppの開発、プロトタイピング、テストを迅速に行うための、マルチクライアント型イーサリアムテストネットの構成とスピンアップを簡素化するコンテナベースのツールキット。", - "page-local-environment-kurtosis-logo-alt": "Kurtosisロゴ", - "page-local-environment-epirus-desc": "Java仮想マシン上でブロックチェーンアプリケーションを開発、デプロイ、監視するためのプラットフォーム。", - "page-local-environment-epirus-logo-alt": "Epirus ロゴ", - "page-local-environment-eth-app-desc": "1つのコマンドでEthereumを搭載したアプリを作成します。UIフレームワークとDeFiテンプレートから選択できます。", - "page-local-environment-eth-app-logo-alt": "Ethアプリのロゴを作成", - "page-local-environment-foundry-desc": "Rustで書かれた、イーサリアムアプリケーション開発のための、高速でポータブルなモジュール式ツールキット。", - "page-local-environment-foundry-logo-alt": "Foundryロゴ", - "page-local-environment-framework-feature-1": "ローカルのブロックチェーンインスタンスを起動する機能。", - "page-local-environment-framework-feature-2": "スマートコントラクトをコンパイルしてテストするユーティリティ。", - "page-local-environment-framework-feature-3": "クライアント開発アドオンは、同じプロジェクト/リポジトリ内でユーザーが利用するアプリケーションを構築します。", - "page-local-environment-framework-feature-4": "Ethereumネットワークに接続し、ローカルで実行されているインスタンス、またはEthereumのパブリックネットワークのいずれかにかかわらず、コントラクトを展開するための設定。", - "page-local-environment-framework-feature-5": "分散型アプリ配信 - IPFSのようなストレージオプションとの統合。", - "page-local-environment-framework-features": "これらのフレームワークには、すぐに使える機能がたくさんあります。", - "page-local-environment-frameworks-desc": " 使用を開始したばかりの場合は特に、フレームワークを選択することをお勧めします。 本格的なdappを構築するには、さまざまな技術が必要です。フレームワークには、必要な機能の多くが含まれているか、ユーザーが望むツールを選択するための簡単なプラグインシステムが提供されています。", - "page-local-environment-frameworks-title": "フレームワークと事前作成されたスタック", - "page-local-environment-hardhat-desc": "Hardhatは、プロのためのイーサリアム開発環境です。", - "page-local-environment-hardhat-logo-alt": "Hardhatロゴ", - "page-local-environment-openZeppelin-desc": "CLIとのスマートコントラクトをコンパイル、アップグレード、デプロイ、および相互作用することで、開発時間を短縮できます。", - "page-local-environment-openZeppelin-logo-alt": "OpenZeppelinロゴ", - "page-local-environment-scaffold-eth-desc": "Ethers + Hardhat + React: スマートコントラクトで実行する分散型アプリケーションの構築を始めるために必要なものすべて", - "page-local-environment-scaffold-eth-logo-alt": "scaffold-eth ロゴ", - "page-local-environment-setup-meta-desc": "イーサリアム開発用のソフトウェアスタックを選択する方法についてのガイド。", - "page-local-environment-setup-meta-title": "イーサリアムのローカル開発のセットアップ", - "page-local-environment-setup-subtitle": "構築を開始する準備ができたら、スタックを選択する時間です。", - "page-local-environment-setup-subtitle-2": " ここでは、Ethereumアプリケーションの構築に役立つツールとフレームワークを紹介します。", - "page-local-environment-setup-title": "ローカル開発環境をセットアップする", - "page-local-environment-solidity-template-desc": "Solidityスマートコントラクト用の事前構築されたセットアップのためのGitHubテンプレート。Hardhatローカルネットワーク、ウォレット実装のためのEthersなどが含まれています。", - "page-local-environment-solidity-template-logo-alt": "Solidityテンプレートのロゴ" -} diff --git a/src/intl/ko/page-developers-learning-tools.json b/src/intl/ko/page-developers-learning-tools.json deleted file mode 100644 index 18c080e9d73..00000000000 --- a/src/intl/ko/page-developers-learning-tools.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "BloomTech Web3 강의로 고용주들이 바라는 엔지니어 기술에 대해 알아볼 수 있습니다.", - "page-learning-tools-bloomtech-logo-alt": "BloomTech 로고", - "page-learning-tools-bootcamps": "개발자 부트캠프", - "page-learning-tools-bootcamps-desc": "최신 정보를 빠르게 제공하기 위한 유료 온라인 강의", - "page-learning-tools-browse-docs": "문서 찾아보기", - "page-learning-tools-capture-the-ether-description": "이더를 잡아라(Capture the Ether)는 이더리움 스마트 계약을 해킹함으로써 보안에 대해 배울 수 있는 게임입니다.", - "page-learning-tools-capture-the-ether-logo-alt": "Capture the Ether 로고", - "page-learning-tools-coding": "코딩으로 학습", - "page-learning-tools-coding-subtitle": "양방향 학습 환경을 선호하는 경우, 해당 도구를 이용해 이더리움을 경험해 볼 수 있습니다.", - "page-learning-tools-consensys-academy-description": "온라인 이더리움 개발자 부트캠프.", - "page-learning-tools-consensys-academy-logo-alt": "ConsenSys Academy 로고", - "page-learning-tools-cryptozombies-description": "나만의 좀비 게임을 만드는 솔리디티(Solidity) 배워보기.", - "page-learning-tools-cryptozombies-logo-alt": "CryptoZombies 로고", - "page-learning-tools-documentation": "문서를 통한 학습", - "page-learning-tools-documentation-desc": "더 자세한 학습을 원하신다면 저희가 작성한 문서에서 필요한 자료를 찾아보세요.", - "page-learning-tools-eth-dot-build-description": "드래그 앤 드롭 프로그래밍 방식과 오픈소스 빌딩 블록을 이용한 웹3에 대한 교육용 샌드박스.", - "page-learning-tools-eth-dot-build-logo-alt": "Eth.build 로고", - "page-learning-tools-ethernauts-description": "스마트 계약 해킹을 통한 레벨 완료.", - "page-learning-tools-ethernauts-logo-alt": "Ethernauts 로고", - "page-learning-tools-metaschool-description": "디앱을 구축하고 개발하여 웹3 개발자가 되어보세요.", - "page-learning-tools-metaschool-logo-alt": "_metaschool 로고", - "page-learning-tools-game-tutorials": "양방향 게임 튜토리얼", - "page-learning-tools-game-tutorials-desc": "놀면서 자연스럽게 배워보세요. 이 튜토리얼에서는 게임하면서 기본 사항을 배울 수 있습니다.", - "page-learning-tools-meta-desc": "웹 기반 코딩 도구와 양방향 학습 환경을 통해 이더리움 개발을 실험하는 데 도움을 줍니다.", - "page-learning-tools-meta-title": "개발자 학습 도구", - "page-learning-tools-questbook-description": "직접 빌드하면서 Web 3.0를 학습하는 튜토리얼", - "page-learning-tools-questbook-logo-alt": "Questbook 로고", - "page-learning-tools-remix-description": "이더리움을 위한 스마트 계약을 개발, 배포 및 관리할 수 있습니다. LearnEth 플러그인으로 튜토리얼을 확인해 보세요.", - "page-learning-tools-remix-description-2": "Remix, Replit, ChainIDE는 단순한 샌드박스가 아닙니다. 개발자는 이를 사용하여 스마트 계약을 작성하고 컴파일하거나 배포할 수 있습니다.", - "page-learning-tools-replit-description": "핫 리로드, 오류 확인 및 1등급 테스트넷 지원으로 맞춤화할 수 있는 이더리움의 개발 환경입니다.", - "page-learning-tools-chainIDE-description": "ChainIDE를 사용하여 이더리움의 스마트 계약을 작성함으로써 웹3를 향한 여정을 시작해 보세요. 내장된 템플릿을 사용해 시간을 절약하면서 학습해 볼 수 있습니다.", - "page-learning-tools-chainIDE-logo-alt": "ChainIDE 로고", - "page-learning-tools-tenderly-description": "Tenderly Sandbox는 브라우저에서 Solidity와 JavaScript를 사용하여 스마트 계약을 작성, 실행 및 디버그할 수 있는 프로토타이핑 환경입니다.", - "page-learning-tools-tenderly-logo-alt": "Tenderly 로고", - "page-learning-tools-replit-logo-alt": "Replit 로고", - "page-learning-tools-remix-logo-alt": "Remix 로고", - "page-learning-tools-sandbox": "코드 샌드박스", - "page-learning-tools-sandbox-desc": "다음 샌드박스는 스마트 계약을 작성하고 이더리움을 이해하도록 실험할 수 있는 공간을 제공합니다.", - "page-learning-tools-speed-run-ethereum-description": "스피드런 이더리움은 Scaffold-ETH를 이용하여 솔리디티 지식을 테스트할 수 있는 일련의 과제입니다.", - "page-learning-tools-speed-run-ethereum-logo-alt": "Speed Run Ethereum 로고", - "page-learning-tools-studio-description": "웹 기반의 IDE에서는 튜토리얼을 따라 스마트 계약을 만들고 테스트하며, 프런트엔드를 구축할 수 있습니다.", - "page-learning-tools-vyperfun-description": "자신만의 포켓몬 게임을 만들며 Vyper를 배워보기.", - "page-learning-tools-vyperfun-logo-alt": "Vyper.fun 로고", - "page-learning-tools-nftschool-description": "대체 불가 토큰(NFT)의 기술적인 측면에서 발생하는 내용 살펴보기.", - "page-learning-tools-nftschool-logo-alt": "NFT 스쿨 로고", - "page-learning-tools-platzi-description": "웹3에서 디앱을 개발하는 방법을 알아보고 블록체인 개발자가 되기 위해 필요한 기술을 완벽하게 습득하기.", - "page-learning-tools-platzi-logo-alt": "Platzi 로고", - "page-learning-tools-alchemy-university-description": "교육 과정, 프로젝트 및 코드를 통해 웹3 경력 발전하기.", - "page-learning-tools-alchemy-university-logo-alt": "Alchemy University 로고", - "alt-eth-blocks": "ETH 기호처럼 구성되고 있는 블록의 그림" -} \ No newline at end of file diff --git a/src/intl/ko/page-developers-local-environment.json b/src/intl/ko/page-developers-local-environment.json deleted file mode 100644 index 3aba2001d17..00000000000 --- a/src/intl/ko/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "Python 기반 개발 및 이더리움 가상 머신을 대상으로 하는 스마트 계약을 위한 테스팅 프레임워크입니다.", - "page-local-environment-brownie-logo-alt": "Brownie 로고", - "page-local-environment-kurtosis-desc": "신속한 로컬 디앱 개발, 프로토타이핑 및 테스트를 위해 멀티 클라이언트 이더리움 테스트넷을 간편하게 구성하고 스핀업할 수 있는 컨테이너 기반 툴킷입니다.", - "page-local-environment-kurtosis-logo-alt": "Kurtosis 로고", - "page-local-environment-epirus-desc": "Java 가상 머신에서 블록체인 애플리케이션을 개발, 배포하고, 모니터링하기 위한 플랫폼입니다.", - "page-local-environment-epirus-logo-alt": "Epirus 로고", - "page-local-environment-eth-app-desc": "한 개의 명령어로 이더리움 제공 앱을 만듭니다. 선택할 수 있는 다양한 UI 프레임워크와 DeFi 템플릿도 제공됩니다.", - "page-local-environment-eth-app-logo-alt": "이더 앱 만들기 로고", - "page-local-environment-foundry-desc": "Rust 언어로 작성된 매우 신속하고 이식 가능한 모듈식 이더리움 애플리케이션 개발용 툴킷입니다.", - "page-local-environment-foundry-logo-alt": "Foundry 로고", - "page-local-environment-framework-feature-1": "로컬 블록체인 인스턴스를 스핀업하기 위한 기능.", - "page-local-environment-framework-feature-2": "스마트 계약을 컴파일하고 테스트하기 위한 유틸리티.", - "page-local-environment-framework-feature-3": "동일한 프로젝트/리포지토리 내에서 사용자용 애플리케이션을 빌드하기 위한 클라이언트 개발 추가 기능.", - "page-local-environment-framework-feature-4": "이더리움 네트워크에 연결하고 로컬로 실행 중인 인스턴스나 이더리움 공공 네트워크 중 하나에 계약을 배포할 수 있는 환경 구성.", - "page-local-environment-framework-feature-5": "탈중앙화 앱 분배 - IPFS와 같은 저장 공간 옵션에 통합.", - "page-local-environment-framework-features": "해당 프레임워크는 다음과 같은 창의적인 기능과 함께 제공됩니다.", - "page-local-environment-frameworks-desc": "프레임워크를 선택할 것을 권장합니다. 특히 처음 시작하는 사용자에게는 중요합니다. 완전한 디앱을 빌드하려면 다른 기술이 필요합니다. 프레임워크에는 다양한 필수 기능이 포함되거나, 원하는 도구를 고르기 위해 쉬운 플러그인 시스템을 제공합니다.", - "page-local-environment-frameworks-title": "프레임워크 및 미리 제작된 스택", - "page-local-environment-hardhat-desc": "Hardhat은 전문가를 위한 이더리움 개발 환경입니다.", - "page-local-environment-hardhat-logo-alt": "Hardhat 로고", - "page-local-environment-openZeppelin-desc": "저희 CLI를 사용하여 스마트 계약을 컴파일, 업그레이드, 배포하고, 상호작용하여 개발 시간을 절약하세요.", - "page-local-environment-openZeppelin-logo-alt": "OpenZeppelin 로고", - "page-local-environment-scaffold-eth-desc": "Ethers + Hardhat + React: 스마트 계약에서 제공하는 탈중앙화 애플리케이션 구축을 시작하는 데에 필요한 모든 것", - "page-local-environment-scaffold-eth-logo-alt": "scaffold-eth 로고", - "page-local-environment-setup-meta-desc": "이더리움 개발을 위한 소프트웨어 스택을 선택하는 방법에 대한 안내서", - "page-local-environment-setup-meta-title": "이더리움 로컬 개발 설정", - "page-local-environment-setup-subtitle": "빌드할 준비가 되셨다면 스택을 선택할 차례입니다.", - "page-local-environment-setup-subtitle-2": "이더리움 애플리케이션을 만들기 위해 사용할 수 있는 도구와 프레임워크는 다음과 같습니다.", - "page-local-environment-setup-title": "로컬 개발 환경을 설정하기", - "page-local-environment-solidity-template-desc": "Solidity 스마트 계약을 위해 미리 빌드된 설정의 GitHub 템플릿입니다. 여기에는 Hardhat 로컬 네트워크, 테스트용 Waffle, 지갑 실행용 Ethers 등이 포함됩니다.", - "page-local-environment-solidity-template-logo-alt": "Solidity 템플릿 로고" -} \ No newline at end of file diff --git a/src/intl/mr/page-developers-learning-tools.json b/src/intl/mr/page-developers-learning-tools.json deleted file mode 100644 index f51b435f989..00000000000 --- a/src/intl/mr/page-developers-learning-tools.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "BloomTech Web3 कोर्स तुम्हाला नियोक्ते अभियंत्यांमध्ये कोणती कौशल्ये शोधतात ते शिकवेल.", - "page-learning-tools-bloomtech-logo-alt": "BloomTech लोगो", - "page-learning-tools-bootcamps": "विकसक बूटकॅम्प", - "page-learning-tools-bootcamps-desc": "तुम्‍हाला वेगवान, जलद मिळवून देण्‍यासाठी सशुल्‍क ऑनलाइन कोर्स.", - "page-learning-tools-browse-docs": "दस्तऐवज ब्राउझ करा", - "page-learning-tools-capture-the-ether-description": "कॅप्चर द इथर हा एक गेम आहे ज्यामध्ये तुम्ही सुरक्षिततेबद्दल जाणून घेण्यासाठी Ethereum स्मार्ट कॉन्ट्रॅक्ट हॅक करता.", - "page-learning-tools-capture-the-ether-logo-alt": "इथर लोगो कॅप्चर करा", - "page-learning-tools-coding": "कोडिंग करून शिका", - "page-learning-tools-coding-subtitle": "तुम्ही अधिक परस्परसंवादी शिक्षण अनुभवाला प्राधान्य दिल्यास ही साधने तुम्हाला Ethereum सह प्रयोग करण्यात मदत करतील.", - "page-learning-tools-consensys-academy-description": "ऑनलाइन Ethereum विकसक बूटकॅम्प.", - "page-learning-tools-consensys-academy-logo-alt": "ConsenSys अकादमी लोगो", - "page-learning-tools-cryptozombies-description": "तुमचा स्वतःचा झोम्बी गेम तयार करण्यासाठी Solidity शिका.", - "page-learning-tools-cryptozombies-logo-alt": "CryptoZombies लोगो", - "page-learning-tools-documentation": "कागदपत्रांसह शिका", - "page-learning-tools-documentation-desc": "अधिक जाणून घेऊ इच्छिता? तुम्हाला आवश्यक असलेले स्पष्टीकरण शोधण्यासाठी आमच्या दस्तऐवजावर जा.", - "page-learning-tools-eth-dot-build-description": "web3 साठी शैक्षणिक सँडबॉक्स, ड्रॅग-अँड-ड्रॉप प्रोग्रामिंग आणि ओपन-सोर्स बिल्डिंग ब्लॉक्ससह.", - "page-learning-tools-eth-dot-build-logo-alt": "Eth.build लोगो", - "page-learning-tools-ethernauts-description": "स्मार्ट कॉन्ट्रॅक्ट हॅक करून स्तर पूर्ण करा.", - "page-learning-tools-ethernauts-logo-alt": "Ethernauts लोगो", - "page-learning-tools-metaschool-description": "dApps बनवून आणि पाठवून Web3 विकसक बना.", - "page-learning-tools-metaschool-logo-alt": "_metaschool लोगो", - "page-learning-tools-game-tutorials": "परस्परसंवादी गेम ट्यूटोरियल", - "page-learning-tools-game-tutorials-desc": "खेळताना शिका. हे ट्यूटोरियल तुम्हाला गेमप्ले वापरून मूलभूत गोष्टींबद्दल माहिती देतात.", - "page-learning-tools-meta-desc": "वेब-आधारित कोडिंग साधने आणि परस्परसंवादी शिक्षण अनुभव तुम्हाला Ethereum विकासासह प्रयोग करण्यात मदत करतात.", - "page-learning-tools-meta-title": "विकसक शिक्षण साधने", - "page-learning-tools-questbook-description": "तयार करून वेब 3.0 शिकण्यासाठी स्वयं-गती शिकवण्या", - "page-learning-tools-questbook-logo-alt": "Questbook लोगो", - "page-learning-tools-remix-description": "Ethereum साठी स्मार्ट कॉन्ट्रॅक्ट विकसित करा, तैनात करा आणि प्रशासित करा. LearnEth प्लगइनसह ट्यूटोरियल फॉलो करा.", - "page-learning-tools-remix-description-2": "Remix, Replit आणि ChainIDE हे फक्त सँडबॉक्स नाहीत—विकासक त्यांचा वापर करून त्यांचे स्मार्ट करार लिहू, संकलित करू आणि उपयोजित करू शकतात.", - "page-learning-tools-replit-description": "हॉट रीलोडिंग, एरर चेकिंग आणि फर्स्ट-क्लास टेस्टनेट सपोर्टसह Ethereum साठी सानुकूल विकास वातावरण.", - "page-learning-tools-chainIDE-description": "ChainIDE सह Ethereum साठी स्मार्ट कॉन्ट्रॅक्ट लिहून Web3 वर तुमचा प्रवास सुरू करा. शिकण्यासाठी आणि वेळ वाचवण्यासाठी अंगभूत टेम्पलेट वापरा.", - "page-learning-tools-chainIDE-logo-alt": "ChainIDE लोगो", - "page-learning-tools-tenderly-description": "Tenderly Sandbox हे एक प्रोटोटाइपिंग वातावरण आहे जिथे तुम्ही Solidity आणि JavaScript वापरून ब्राउझरमध्ये स्मार्ट कॉन्ट्रॅक्ट लिहू, अंमलात आणू आणि डीबग करू शकता.", - "page-learning-tools-tenderly-logo-alt": "Tenderly लोगो", - "page-learning-tools-replit-logo-alt": "Replit लोगो", - "page-learning-tools-remix-logo-alt": "Remix लोगो", - "page-learning-tools-sandbox": "कोड सँडबॉक्सेस", - "page-learning-tools-sandbox-desc": "हे सँडबॉक्स तुम्हाला स्मार्ट कॉन्ट्रॅक्ट लिहिण्यासाठी आणि Ethereum समजून घेऊन प्रयोग करण्यासाठी जागा देतील.", - "page-learning-tools-speed-run-ethereum-description": "स्पीड रन Ethereum हे Scaffold-ETH वापरून तुमच्या Solidity ज्ञानाची चाचणी घेण्यासाठी आव्हानांचा एक संच आहे", - "page-learning-tools-speed-run-ethereum-logo-alt": "स्पीड रन Ethereum लोगो", - "page-learning-tools-studio-description": "एक वेब-आधारित IDE जेथे तुम्ही स्मार्ट कॉन्ट्रॅक्ट्स तयार करण्यासाठी आणि चाचणी करण्यासाठी शिकवण्या फॉलो करू शकता आणि त्यांच्यासाठी फ्रंटएंड तयार करू शकता.", - "page-learning-tools-vyperfun-description": "तुमचा स्वतःचा Pokémon गेम तयार करण्यासाठी व्हायपर जाणून घ्या.", - "page-learning-tools-vyperfun-logo-alt": "Vyper.fun लोगो", - "page-learning-tools-nftschool-description": "तांत्रिक बाजूने नॉन-फंजिबल टोकन किंवा NFT सह काय चालले आहे ते एक्सप्लोर करा.", - "page-learning-tools-nftschool-logo-alt": "NFT शाळेचा लोगो", - "page-learning-tools-platzi-description": "Web3 वर dapps कसे तयार करायचे ते जाणून घ्या आणि ब्लॉकचेन डेव्हलपर होण्यासाठी आवश्यक असलेल्या सर्व कौशल्यांमध्ये प्रभुत्व मिळवा.", - "page-learning-tools-platzi-logo-alt": "Platzi लोगो", - "page-learning-tools-alchemy-university-description": "अभ्यासक्रम, प्रकल्प आणि कोडद्वारे तुमचे web3\n करिअर विकसित करा.", - "page-learning-tools-alchemy-university-logo-alt": "Alchemy University लोगो", - "alt-eth-blocks": "ETH चिन्हाप्रमाणे आयोजित केले जात असलेल्या ठोकळ्यांचे स्पष्टीकरणात्मक चित्र" -} \ No newline at end of file diff --git a/src/intl/mr/page-developers-local-environment.json b/src/intl/mr/page-developers-local-environment.json deleted file mode 100644 index fd6e05697c7..00000000000 --- a/src/intl/mr/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "Ethereum व्हर्च्युअल मशीनला लक्ष्य करणार्‍या स्मार्ट कॉन्ट्रॅक्टसाठी Python-आधारित विकास आणि चाचणी फ्रेमवर्क.", - "page-local-environment-brownie-logo-alt": "Brownie लोगो", - "page-local-environment-kurtosis-desc": "जलद स्थानिक dApp विकास, प्रोटोटाइपिंग आणि चाचणीसाठी मल्टी-क्लायंट Ethereum टेस्टनेट सहजपणे कॉन्फिगर आणि स्पिनिंगसाठी कंटेनर-आधारित टूलकिट.", - "page-local-environment-kurtosis-logo-alt": "Kurtosis लोगो", - "page-local-environment-epirus-desc": "Java व्हर्च्युअल मशीनवर ब्लॉकचेन ऍप्लिकेशन्स विकसित करणे, तैनात करणे आणि त्यांचे परीक्षण करणे यासाठी एक व्यासपीठ.", - "page-local-environment-epirus-logo-alt": "Epirus लोगो", - "page-local-environment-eth-app-desc": "एका आदेशाने Ethereum-चालित अॅप्स तयार करा. निवडण्यासाठी UI फ्रेमवर्क आणि DeFi टेम्पलेट्सच्या विस्तृत ऑफरिंगसह येते.", - "page-local-environment-eth-app-logo-alt": "Eth अॅप लोगो तयार करा", - "page-local-environment-foundry-desc": "रस्टमध्ये लिहिलेले Ethereum ऍप्लिकेशन डेव्हलपमेंटसाठी एक झगमगाट, पोर्टेबल आणि मॉड्यूलर टूलकिट.", - "page-local-environment-foundry-logo-alt": "Foundry लोगो", - "page-local-environment-framework-feature-1": "स्थानिक ब्लॉकचेन उदाहरण स्पिन अप करण्यासाठी वैशिष्ट्ये.", - "page-local-environment-framework-feature-2": "तुमचे स्मार्ट कॉन्ट्रॅक्ट संकलित करण्यासाठी आणि चाचणी करण्यासाठी उपयुक्तता.", - "page-local-environment-framework-feature-3": "त्याच प्रोजेक्ट/रेपॉजिटरीमध्ये तुमचा वापरकर्ता-फेसिंग अॅप्लिकेशन तयार करण्यासाठी क्लायंट डेव्हलपमेंट अॅड-ऑन.", - "page-local-environment-framework-feature-4": "Ethereum नेटवर्कशी कनेक्ट करण्यासाठी कॉन्फिगरेशन आणि कॉन्ट्रॅक्ट उपयोजित करा, मग ते स्थानिक पातळीवर चालू असलेल्या उदाहरणासाठी, किंवा Ethereum च्या सार्वजनिक नेटवर्कपैकी एक.", - "page-local-environment-framework-feature-5": "विकेंद्रित अॅप वितरण - IPFS सारख्या स्टोरेज पर्यायांसह एकत्रीकरण.", - "page-local-environment-framework-features": "हे फ्रेमवर्क बर्‍याच आउट-ऑफ-द-बॉक्स कार्यक्षमतेसह येतात, जसे की:", - "page-local-environment-frameworks-desc": "आम्‍ही एक फ्रेमवर्क निवडण्‍याची शिफारस करतो, विशेषत: तुम्‍ही नुकतीच सुरुवात करत असल्‍यास. पूर्ण विकसित dapp तयार करण्यासाठी विविध तंत्रज्ञानाची आवश्यकता असते. फ्रेमवर्कमध्ये अनेक आवश्यक वैशिष्ट्ये समाविष्ट आहेत किंवा तुम्हाला हवी असलेली साधने निवडण्यासाठी सुलभ प्लगइन सिस्टीम प्रदान करतात.", - "page-local-environment-frameworks-title": "फ्रेमवर्क आणि प्री-मेड स्टॅक", - "page-local-environment-hardhat-desc": "Hardhat व्यावसायिकांसाठी Ethereum विकास वातावरण आहे.", - "page-local-environment-hardhat-logo-alt": "Hardhat लोगो", - "page-local-environment-openZeppelin-desc": "आमच्या CLI सह स्मार्ट कॉन्ट्रॅक्ट संकलित करून, श्रेणीसुधारित करून, उपयोजित करून आणि परस्परसंवाद करून विकासाचा वेळ वाचवा.", - "page-local-environment-openZeppelin-logo-alt": "OpenZeppelin लोगो", - "page-local-environment-scaffold-eth-desc": "Ethers + Hardhat + React: स्मार्ट कॉन्ट्रॅक्ट्सद्वारे समर्थित विकेंद्रित ऍप्लिकेशन तयार करण्यास प्रारंभ करण्यासाठी आपल्याला आवश्यक असलेली प्रत्येक गोष्ट.", - "page-local-environment-scaffold-eth-logo-alt": "scaffold-eth लोगो", - "page-local-environment-setup-meta-desc": "Ethereum डेव्हलपमेंटसाठी तुमचा सॉफ्टवेअर स्टॅक कसा निवडायचा याचे मार्गदर्शन.", - "page-local-environment-setup-meta-title": "Ethereum स्थानिक विकास सेटअप", - "page-local-environment-setup-subtitle": "तुम्ही बांधकाम सुरू करण्यास तयार असल्यास, तुमचा स्टॅक निवडण्याची वेळ आली आहे.", - "page-local-environment-setup-subtitle-2": "तुमचा Ethereum अनुप्रयोग तयार करण्यात मदत करण्यासाठी तुम्ही वापरू शकता अशी साधने आणि फ्रेमवर्क येथे आहेत.", - "page-local-environment-setup-title": "आपले स्थानिक विकास वातावरण सेट करा", - "page-local-environment-solidity-template-desc": "तुमच्या Solidity स्मार्ट कॉन्ट्रॅक्ट्ससाठी पूर्व-निर्मित सेटअपसाठी एक GitHub टेम्पलेट. Hardhat स्थानिक नेटवर्क, चाचण्यांसाठी Waffle, वॉलेट अंमलबजावणीसाठी इथर्स आणि बरेच काही समाविष्ट आहे.", - "page-local-environment-solidity-template-logo-alt": "Solidity टेम्पलेट लोगो" -} \ No newline at end of file diff --git a/src/intl/pl/page-developers-learning-tools.json b/src/intl/pl/page-developers-learning-tools.json deleted file mode 100644 index 057952f7abf..00000000000 --- a/src/intl/pl/page-developers-learning-tools.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "Kurs BloomTech Web3 nauczy cię umiejętności, których pracodawcy szukają u inżynierów.", - "page-learning-tools-bloomtech-logo-alt": "Logo BloomTech", - "page-learning-tools-bootcamps": "Szkolenia dla deweloperów", - "page-learning-tools-bootcamps-desc": "Płatne kursy online, dzięki którym szybko będziesz na bieżąco.", - "page-learning-tools-browse-docs": "Przeglądaj dokumenty", - "page-learning-tools-capture-the-ether-description": "Capture the Ether jest grą, w której hakujesz smart kontrakty Ethereum, aby nauczyć się o ich bezpieczeństwie.", - "page-learning-tools-capture-the-ether-logo-alt": "Logo Capture the Ether", - "page-learning-tools-coding": "Nauka przez kodowanie", - "page-learning-tools-coding-subtitle": "Jeżeli wolisz naukę poprzez interakcję, te narzędzia pomogą ci w eksperymentowaniu z Ethereum.", - "page-learning-tools-consensys-academy-description": "Szkolenia deweloperskie z Ethereum online.", - "page-learning-tools-consensys-academy-logo-alt": "Logo ConsenSys Academy", - "page-learning-tools-cryptozombies-description": "Naucz się Solidity tworząc własną grę o Zombie.", - "page-learning-tools-cryptozombies-logo-alt": "Logo CryptoZombies", - "page-learning-tools-documentation": "Dowiedz się więcej dzięki dokumentacji", - "page-learning-tools-documentation-desc": "Chcesz dowiedzieć się więcej? Przejdź do dokumentacji, żeby znaleźć potrzebne informacje.", - "page-learning-tools-eth-dot-build-description": "Edukacyjna piaskownica dla web3, zawierająca programowanie metodą „przeciągnij i upuść” oraz bloki konstrukcyjne open-source.", - "page-learning-tools-eth-dot-build-logo-alt": "Logo Eth.build", - "page-learning-tools-ethernauts-description": "Zaliczaj poziomy, hakując inteligentne kontrakty.", - "page-learning-tools-ethernauts-logo-alt": "Logo Ethernauts", - "page-learning-tools-metaschool-description": "Zostań Web3 Developerem poprzez budowanie i wysyłanie dAppsów.", - "page-learning-tools-metaschool-logo-alt": "Logo _metaschool", - "page-learning-tools-game-tutorials": "Interaktywne samouczki do gier", - "page-learning-tools-game-tutorials-desc": "Ucz się, grając. Dzięki tym samouczkom nauczysz się podstaw podczas rozgrywki.", - "page-learning-tools-meta-desc": "Narzędzia internetowe do kodowania i interaktywne środowiska edukacyjne, które pomogą Ci eksperymentować z rozwojem Ethereum.", - "page-learning-tools-meta-title": "Narzędzia edukacyjne dla deweloperów", - "page-learning-tools-questbook-description": "Samouczki pozwalające na naukę Web 3.0 we własnym tempie poprzez budowanie", - "page-learning-tools-questbook-logo-alt": "Logotyp Questbook", - "page-learning-tools-remix-description": "Twórz, wdrażaj i zarządzaj inteligentnymi kontraktami dla Ethereum. Korzystaj z samouczków za pomocą wtyczki LearnEth.", - "page-learning-tools-remix-description-2": "Remix, Replit i ChainIDE to nie tylko piaskownice — deweloperzy mogą za ich pomocą pisać, kompilować i wdrażać swoje inteligentne kontrakty.", - "page-learning-tools-replit-description": "Dostosowywane środowisko programistyczne dla Ethereum z funkcją hot reloading, sprawdzaniem błędów i najwyższej klasy obsługą sieci testowych.", - "page-learning-tools-chainIDE-description": "Rozpocznij swoją podróż do Web3, pisząc inteligentne kontrakty dla Ethereum za pomocą narzędzia ChainIDE. Użyj wbudowanych szablonów, aby się nauczyć i zaoszczędzić czas.", - "page-learning-tools-chainIDE-logo-alt": "Logo ChainIDE", - "page-learning-tools-tenderly-description": "Tenderly Sandbox to środowisko do tworzenia prototypów, w którym można pisać, wykonywać i debugować inteligentne kontrakty w przeglądarce używając Solidity i JavaScript.", - "page-learning-tools-tenderly-logo-alt": "Logo Tenderly", - "page-learning-tools-replit-logo-alt": "Logo Replit", - "page-learning-tools-remix-logo-alt": "Logo Remix", - "page-learning-tools-sandbox": "Piaskownice kodu", - "page-learning-tools-sandbox-desc": "Te piaskownice dadzą Ci przestrzeń do eksperymentowania z pisaniem inteligentnych kontraktów i zrozumieniem Ethereum.", - "page-learning-tools-speed-run-ethereum-description": "Speed Run Ethereum jest zestawem wyzwań, które przetestują twoją wiedzę o Solidity przy użyciu Scaffold-ETH.", - "page-learning-tools-speed-run-ethereum-logo-alt": "Logotyp SpeedRun Ethereum", - "page-learning-tools-studio-description": "Oparte na Internecie IDE, w którym możesz korzystać z samouczków do tworzenia i testowania inteligentnych kontraktów, a także budować dla nich frontend.", - "page-learning-tools-vyperfun-description": "Naucz się Vyper, tworząc własną grę w Pokémony.", - "page-learning-tools-vyperfun-logo-alt": "Logo Vyper.fun", - "page-learning-tools-nftschool-description": "Odkryj, co się dzieje z niewymienialnymi tokenami lub NFT od technicznej strony.", - "page-learning-tools-nftschool-logo-alt": "Logotyp NFT School", - "page-learning-tools-platzi-description": "Naucz się jak budować dAppsy w Web3 i opanuj wszystkie umiejętności, aby być blockchain developerem.", - "page-learning-tools-platzi-logo-alt": "Logo Platzi", - "page-learning-tools-alchemy-university-description": "Rozwijaj swoją karierę w Web3 poprzez kursy, projekty i pisanie kodu.", - "page-learning-tools-alchemy-university-logo-alt": "Logo Alchemy University", - "alt-eth-blocks": "Ilustracja bloków zorganizowanych jak symbol ETH" -} \ No newline at end of file diff --git a/src/intl/pl/page-developers-local-environment.json b/src/intl/pl/page-developers-local-environment.json deleted file mode 100644 index 3dfd0461e11..00000000000 --- a/src/intl/pl/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "Oparta na języku Python platforma programistyczna i testowa dla inteligentnych kontraktów ukierunkowana na maszynę wirtualną Ethereum.", - "page-local-environment-brownie-logo-alt": "Logo Brownie", - "page-local-environment-kurtosis-desc": "Zestaw narzędzi opartych na kontenerach, które ułatwiają konfigurację i aktywację sieci testowej Ethereum z wieloma klientami w celu szybkiego lokalnego rozwoju, tworzenia prototypów i testowania zdecentralizowanych aplikacji.", - "page-local-environment-kurtosis-logo-alt": "Logo Kurtosis", - "page-local-environment-epirus-desc": "Platforma do tworzenia, wdrażania i monitorowania aplikacji blockchain w maszynie wirtualnej Java.", - "page-local-environment-epirus-logo-alt": "Logo Epirus", - "page-local-environment-eth-app-desc": "Twórz za pomocą jednego polecenia aplikacje działające w oparciu o Ethereum. Zawiera szeroką ofertę platform UI i szablonów DeFi do wyboru.", - "page-local-environment-eth-app-logo-alt": "Utwórz logo aplikacji Eth", - "page-local-environment-foundry-desc": "Błyskawiczny szybki, przenośny i modułowy zestaw narzędzi do opracowywania aplikacji Ethereum napisany w Rust.", - "page-local-environment-foundry-logo-alt": "Logo odlewni", - "page-local-environment-framework-feature-1": "Funkcje do uruchomienia lokalnej instancji blockchain.", - "page-local-environment-framework-feature-2": "Narzędzia do kompilacji i testowania Twoich inteligentnych kontraktów.", - "page-local-environment-framework-feature-3": "Dodatki programistyczne do tworzenia aplikacji użytkownika w ramach tego samego projektu/repozytorium.", - "page-local-environment-framework-feature-4": "Konfiguracja do łączenia się z sieciami Ethereum i wdrażania kontraktów, zarówno do lokalnie działającej instancji, jak i do jednej z publicznych sieci Ethereum.", - "page-local-environment-framework-feature-5": "Zdecentralizowana dystrybucja aplikacji -- integracja z opcjami przechowywania, takimi jak IPFS.", - "page-local-environment-framework-features": "Te frameworki mają wiele gotowych funkcji, takich jak:", - "page-local-environment-frameworks-desc": " Zalecamy wybranie frameworka, szczególnie jeśli dopiero zaczynasz. Zbudowanie pełnoprawnej zdecentralizowanej aplikacji (dapp) wymaga różnych elementów technologii. Frameworki zawierają wiele potrzebnych funkcji lub zapewniają łatwe systemy wtyczek do wyboru pożądanych narzędzi.", - "page-local-environment-frameworks-title": "Frameworki i wcześniej przygotowane stosy", - "page-local-environment-hardhat-desc": "Hardhat to rozwojowe środowisko programistyczne Ethereum dla profesjonalistów.", - "page-local-environment-hardhat-logo-alt": "Logo Hardhat", - "page-local-environment-openZeppelin-desc": "Zaoszczędź godziny pracy programistycznej, kompilując, aktualizując, wdrażając i wchodząc w interakcję z inteligentnymi umowami za pomocą naszego CLI.", - "page-local-environment-openZeppelin-logo-alt": "Logo OpenZeppelin", - "page-local-environment-scaffold-eth-desc": "Ethers + Hardhat + React: wszystko, czego potrzebujesz, aby rozpocząć tworzenie zdecentralizowanych aplikacji opartych na inteligentnych kontraktach.", - "page-local-environment-scaffold-eth-logo-alt": "logo scaffold-eth", - "page-local-environment-setup-meta-desc": "Wskazówki dotyczące wyboru stosu oprogramowania dla rozwoju Ethereum.", - "page-local-environment-setup-meta-title": "Konfiguracja lokalnego rozwoju Ethereum", - "page-local-environment-setup-subtitle": "Jeśli jesteś gotowy do rozpoczęcia budowy, nadszedł czas, aby wybrać swój stos.", - "page-local-environment-setup-subtitle-2": " Oto narzędzia i frameworki, których możesz użyć, aby łatwiej zbudować swoją aplikację Ethereum.", - "page-local-environment-setup-title": "Skonfiguruj swoje lokalne środowisko programistyczne", - "page-local-environment-solidity-template-desc": "Szablon GitHub gotowej konfiguracji inteligentnych kontraktów Solidity. Zawiera sieć lokalną Hardhat, Waffle do testów, etery do implementacji portfela i wiele innych.", - "page-local-environment-solidity-template-logo-alt": "Logo Solidity template" -} \ No newline at end of file diff --git a/src/intl/pt-br/page-developers-learning-tools.json b/src/intl/pt-br/page-developers-learning-tools.json deleted file mode 100644 index 5abb929ee59..00000000000 --- a/src/intl/pt-br/page-developers-learning-tools.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "O curso BloomTech Web3 ensinará as habilidades que as empresas buscam nos engenheiros.", - "page-learning-tools-bloomtech-logo-alt": "Logotipo da BloomTech", - "page-learning-tools-bootcamps": "Bootcamps para desenvolvedores", - "page-learning-tools-bootcamps-desc": "Cursos on-line pagos para ajudá-lo a alcançar seus objetivos, rápido.", - "page-learning-tools-browse-docs": "Navegar pela documentação", - "page-learning-tools-capture-the-ether-description": "Capture the Ether é um jogo em que você codifica os contratos inteligentes do Ethereum para aprender sobre segurança.", - "page-learning-tools-capture-the-ether-logo-alt": "Logotipo do jogo Capture the Ether", - "page-learning-tools-node-guardians-description": "Node Guardians é uma plataforma educacional gamificada que envolve desenvolvedores web3 em missões com temas de fantasia para dominar a programação Solidity, Cairo, Noir e Huff.", - "page-learning-tools-node-guardians-logo-alt": "Logotipo do Node Guardians", - "page-learning-tools-chainshot-description": "Treinamento remoto inicial para desenvolvedores Ethereum e cursos adicionais.", - "page-learning-tools-chainshot-logo-alt": "Logotipo da ChainShot", - "page-learning-tools-coding": "Aprenda programando", - "page-learning-tools-coding-subtitle": "Essas ferramentas vão ajudá-lo a experimentar com Ethereum, se você preferir uma jornada de aprendizado mais interativa.", - "page-learning-tools-consensys-academy-description": "Bootcamp on-line para desenvolvedores Ethereum.", - "page-learning-tools-consensys-academy-logo-alt": "Logotipo para ConsenSys Academy", - "page-learning-tools-cryptozombies-description": "Aprenda Solidity desenvolvendo seu próprio jogo de zumbis.", - "page-learning-tools-cryptozombies-logo-alt": "Logotipo para CryptoZombies", - "page-learning-tools-dapp-world-description": "Um ecossistema de qualificação da blockchain, incluindo cursos, questionários, exercícios práticos e concursos semanais.", - "page-learning-tools-dapp-world-logo-alt": "Logotipo do Dapp World", - "page-learning-tools-documentation": "Aprenda com documentação", - "page-learning-tools-documentation-desc": "Quer aprender mais? Acesse nossa documentação e encontre as explicações de que você precisa.", - "page-learning-tools-eth-dot-build-description": "Um ambiente educacional e protegido para web3, incluindo interface de programação do tipo \"arrastar e soltar\" e fundamentos sobre código aberto.", - "page-learning-tools-eth-dot-build-logo-alt": "Logotipo para Eth.build", - "page-learning-tools-ethernauts-description": "Complete níveis hackeando contratos inteligentes.", - "page-learning-tools-ethernauts-logo-alt": "Logotipo para Ethernauts", - "page-learning-tools-metaschool-description": "Torne-se um Desenvolvedor Web3 construindo e entregando dApps.", - "page-learning-tools-metaschool-logo-alt": "Logotipo da Metaschool", - "page-learning-tools-game-tutorials": "Tutoriais interativos de jogos", - "page-learning-tools-game-tutorials-desc": "Aprenda enquanto joga. Esses tutoriais vão acompanhá-lo pelos aspectos básicos através do jogo.", - "page-learning-tools-meta-desc": "Ferramentas de programação na web e experiência interativa de aprendizado para ajudá-lo a experimentar com desenvolvimento no Ethereum.", - "page-learning-tools-meta-title": "Ferramentas de aprendizagem para desenvolvedores", - "page-learning-tools-atlas-logo-alt": "Logotipo do Atlas", - "page-learning-tools-atlas-description": "Escreva, teste e implante contratos inteligentes em minutos com o IDE Atlas.", - "page-learning-tools-questbook-description": "Tutorial passo a passo para aprender criando com Web 3.0", - "page-learning-tools-questbook-logo-alt": "Logotipo da Questbook", - "page-learning-tools-remix-description": "Desenvolva, implante e administre contratos inteligentes para Ethereum. Siga os tutoriais com o plugin Learneth.", - "page-learning-tools-remix-description-2": "Remix, Replit, ChainIDE e Atlas não são somente sandboxes. Os desenvolvedores podem escrever, compilar e implantar contratos inteligentes com eles.", - "page-learning-tools-replit-description": "Um ambiente de desenvolvimento personalizável para Ethereum com recarregamento a quente, verificação de erros e suporte de rede de teste (testnet) de primeira classe.", - "page-learning-tools-chainIDE-description": "Comece sua jornada até a Web3 escrevendo contratos inteligentes para Ethereum com ChainIDE. Use os modelos nativos para aprender e economizar tempo.", - "page-learning-tools-chainIDE-logo-alt": "Logotipo da ChainIDE", - "page-learning-tools-tenderly-description": "Tenderly Sandbox é um ambiente de prototipagem onde é possível utilizar Solidity e JavaScript para escrever, executar e depurar contratos inteligentes no navegador.", - "page-learning-tools-tenderly-logo-alt": "Logotipo da Tenderly", - "page-learning-tools-replit-logo-alt": "Logotipo da Replit", - "page-learning-tools-remix-logo-alt": "Logotipo Remix", - "page-learning-tools-sandbox": "Ambientes educacionais para programação", - "page-learning-tools-sandbox-desc": "Esses ambientes educacionais vão proporcionar a você um espaço para experimentar escrevendo contratos inteligentes e compreendendo Ethereum.", - "page-learning-tools-speed-run-ethereum-description": "SpeedRunEthereum é um conjunto de desafios para testar seu conhecimento em Solidity usando Scaffold-ETH", - "page-learning-tools-speed-run-ethereum-logo-alt": "Logotipo da Speed Run Ethereum", - "page-learning-tools-studio-description": "Uma IDE com base na Web onde você pode seguir tutoriais para criar e testar contratos inteligentes, além de desenvolver um front-end para eles.", - "page-learning-tools-vyperfun-description": "Aprenda Vyper desenvolvendo o seu próprio jogo de Pokémon.", - "page-learning-tools-vyperfun-logo-alt": "Logotipo Vyper.fun", - "page-learning-tools-nftschool-description": "Veja o que está acontecendo com tokens não fungíveis, ou NFT, de uma perspectiva técnica.", - "page-learning-tools-nftschool-logo-alt": "NFT school logotipo", - "page-learning-tools-pointer-description": "Aprenda habilidades de desenvolvimento da web3 com tutoriais divertidos e interativos. Ganhe criptomoedas como recompensas ao longo do caminho", - "page-learning-tools-pointer-logo-alt": "Logotipo do ponteiro", - "page-learning-tools-platzi-description": "Aprenda a construir dapps na Web3 e domine todas as habilidades necessárias para ser um desenvolvedor de blockchain.", - "page-learning-tools-platzi-logo-alt": "Logo da Platzi", - "page-learning-tools-alchemy-university-description": "Desenvolva sua carreira Web3 por meio de cursos, projetos e código.", - "page-learning-tools-alchemy-university-logo-alt": "Logotipo da Alchemy University", - "alt-eth-blocks": "Ilustração de blocos sendo organizados como um símbolo ETH" -} diff --git a/src/intl/pt-br/page-developers-local-environment.json b/src/intl/pt-br/page-developers-local-environment.json deleted file mode 100644 index 35681f8b96a..00000000000 --- a/src/intl/pt-br/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "Um framework baseado em Python para desenvolvimento e testes de contratos inteligentes direcionado à Ethereum Virtual Machine.", - "page-local-environment-brownie-logo-alt": "Logotipo da Brownie", - "page-local-environment-kurtosis-desc": "Um kit de ferramentas baseado em contêiner para configurar e ativar facilmente uma rede de testes Ethereum multi-cliente para desenvolvimento, prototipagem e testes rápidos locais de dApp.", - "page-local-environment-kurtosis-logo-alt": "Logotipo da Kurtosis", - "page-local-environment-epirus-desc": "Uma plataforma para desenvolvimento, implementação e monitoramento de aplicativos blockchain na Java Virtual Machine.", - "page-local-environment-epirus-logo-alt": "Logotipo da Epirus", - "page-local-environment-eth-app-desc": "Crie aplicativos com tecnologia Ethereum com um comando. Inclui uma grande quantidade de frameworks de IU e modelos DeFi para escolher.", - "page-local-environment-eth-app-logo-alt": "Logotipo de Create Eth App", - "page-local-environment-foundry-desc": "Um kit de ferramentas extremamente rápido, portátil e modular para desenvolvimento de aplicativos Ethereum escrito em Rust.", - "page-local-environment-foundry-logo-alt": "Logotipo do Foundry", - "page-local-environment-framework-feature-1": "Recursos para ativar uma instância local de blockchain.", - "page-local-environment-framework-feature-2": "Utilitários para compilar e testar seus contratos inteligentes.", - "page-local-environment-framework-feature-3": "Complementos de desenvolvimento de cliente para criar seu aplicativo voltado para o usuário dentro do mesmo projeto/repositório.", - "page-local-environment-framework-feature-4": "Configuração para se conectar a redes Ethereum e implantar contratos, seja para uma instância em execução local, seja para uma das redes públicas da Ethereum.", - "page-local-environment-framework-feature-5": "Distribuição descentralizada de aplicativos: integrações com opções de armazenamento como o IPFS.", - "page-local-environment-framework-features": "Esses frameworks vêm com muitas funcionalidades prontas para usar, como:", - "page-local-environment-frameworks-desc": "Recomendamos escolher um framework, principalmente se você estiver apenas começando. Criar um dapp completo requer diferentes componentes de tecnologia. Os frameworks incluem muitos dos recursos necessários ou fornecem sistemas de plug-ins fáceis para escolher as ferramentas que você deseja.", - "page-local-environment-frameworks-title": "Frameworks e pilhas pré-criadas", - "page-local-environment-hardhat-desc": "Hardhat é um ambiente de desenvolvimento da Ethereum para profissionais.", - "page-local-environment-hardhat-logo-alt": "Logotipo Hardhat", - "page-local-environment-openZeppelin-desc": "Economize horas de desenvolvimento compilando, atualizando, implantando e interagindo com contratos inteligentes com nossa CLI.", - "page-local-environment-openZeppelin-logo-alt": "Logotipo OpenZeppelin", - "page-local-environment-scaffold-eth-desc": "Ethers + Hardhat + React: tudo o que você precisa para começar a desenvolver aplicativos descentralizados sustentadas por contratos inteligentes.", - "page-local-environment-scaffold-eth-logo-alt": "Logotipo scaffold-eth", - "page-local-environment-setup-meta-desc": "Guia sobre como escolher sua pilha de software para desenvolvimento Ethereum.", - "page-local-environment-setup-meta-title": "Configuração de desenvolvimento local Ethereum", - "page-local-environment-setup-subtitle": "Se você estiver pronto para começar a criar, é hora de escolher sua pilha.", - "page-local-environment-setup-subtitle-2": "Estas são as ferramentas e frameworks que você pode usar para desenvolver seu aplicativo Ethereum.", - "page-local-environment-setup-title": "Configure seu ambiente de desenvolvimento local", - "page-local-environment-solidity-template-desc": "Um modelo GitHub para uma configuração predefinida para seus contratos inteligentes Solidity. Inclui uma rede local de Hardhat, Waffle para testes, Ethers para implementação de carteira e muito mais.", - "page-local-environment-solidity-template-logo-alt": "Logotipo de modelo Solidity" -} \ No newline at end of file diff --git a/src/intl/ru/page-developers-learning-tools.json b/src/intl/ru/page-developers-learning-tools.json deleted file mode 100644 index b37b27a954b..00000000000 --- a/src/intl/ru/page-developers-learning-tools.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "Курс BloomTech Web3 научит вас навыкам, которые работодатели ценят у инженеров.", - "page-learning-tools-bloomtech-logo-alt": "Логотип BloomTech", - "page-learning-tools-bootcamps": "Интенсивы для разработчиков", - "page-learning-tools-bootcamps-desc": "Платные онлайн-курсы для быстрой прокачки навыков.", - "page-learning-tools-browse-docs": "Просмотр документов", - "page-learning-tools-capture-the-ether-description": "Capture the Ether — это игра, в которой вы взламываете умные контракты Ethereum, чтобы узнать больше об их защите.", - "page-learning-tools-capture-the-ether-logo-alt": "Логотип Capture the Ether", - "page-learning-tools-node-guardians-description": "Node Guardians — это игровая образовательная платформа, которая погружает разработчиков Web3 в фентезийные квесты, помогая им освоить программирование на Solidity, Cairo, Noir и Huff.", - "page-learning-tools-node-guardians-logo-alt": "Логотип Node Guardians", - "page-learning-tools-coding": "Учитесь на программировании", - "page-learning-tools-coding-subtitle": "Эти инструменты позволят вам поэкспериментировать с Ethereum, если вы предпочитаете более интерактивное обучение.", - "page-learning-tools-consensys-academy-description": "Онлайн-лагерь для разработчиков Ethereum.", - "page-learning-tools-consensys-academy-logo-alt": "Логотип ConsenSys Academy", - "page-learning-tools-cryptozombies-description": "Обучение Solidity на примере создания игры про зомби.", - "page-learning-tools-cryptozombies-logo-alt": "Логотип CryptoZombies", - "page-learning-tools-dapp-world-description": "Экосистема для повышения квалификации по блокчейну, включающая курсы, викторины, практические упражнения и еженедельные состязания.", - "page-learning-tools-dapp-world-logo-alt": "Логотип Dapp World", - "page-learning-tools-documentation": "Учитесь с документацией", - "page-learning-tools-documentation-desc": "Хотите узнать больше? Прочтите документацию, чтобы найти интересующую вас информацию.", - "page-learning-tools-eth-dot-build-description": "Обучающая песочница для web3, включающая программирование drag-and-drop и строительные блоки с открытым исходным кодом.", - "page-learning-tools-eth-dot-build-logo-alt": "Логотип Eth.build", - "page-learning-tools-ethernauts-description": "Проходите уровни, взламывая смарт-контракты.", - "page-learning-tools-ethernauts-logo-alt": "Логотип Ethernauts", - "page-learning-tools-metaschool-description": "Станьте разработчиком Web3, создавая и предоставляя децентрализованные приложения.", - "page-learning-tools-metaschool-logo-alt": "Логотип Metaschool", - "page-learning-tools-game-tutorials": "Интерактивные игровые руководства", - "page-learning-tools-game-tutorials-desc": "Учитесь, играя. Эти руководства проведут вас через основы, используя игры.", - "page-learning-tools-meta-desc": "Онлайн-инструменты программирования и интерактивное обучение, чтобы помочь вам в экспериментах с разработками на Ethereum.", - "page-learning-tools-meta-title": "Инструменты обучения разработчика", - "page-learning-tools-atlas-logo-alt": "Логотип Atlas", - "page-learning-tools-atlas-description": "Пишите, тестируйте и развертывайте смарт-контракты за считаные минуты в интегрированной среде разработки Atlas.", - "page-learning-tools-questbook-description": "Самостоятельные уроки по разработке в Web 3.0", - "page-learning-tools-questbook-logo-alt": "Логотип Questbook", - "page-learning-tools-remix-description": "Управляйте смарт-контрактами на Ethereum, разрабатывайте и публикуйте их. Воспользуйтесь руководствами с помощью плагина LearnEth.", - "page-learning-tools-remix-description-2": "Remix, Replit, ChainIDE и Atlas — это не просто песочницы. С их помощью разработчики могут писать, компилировать и развертывать свои смарт-контракты.", - "page-learning-tools-replit-description": "Настраиваемая среда разработки для Ethereum с горячей перезагрузкой, проверкой ошибок и первоклассной поддержкой тестовой сети.", - "page-learning-tools-chainIDE-description": "Начните свое путешествие в Web3 с написания умных контрактов для Ethereum с помощью ChainIDE. Используйте встроенные шаблоны, чтобы учиться и экономить время.", - "page-learning-tools-chainIDE-logo-alt": "Логотип ChainIDE", - "page-learning-tools-tenderly-description": "Tenderly Sandbox — это среда прототипирования, в которой можно прямо в браузере писать смарт-контракты, исполнять их и устранять ошибки с помощью Solidity и JavaScript.", - "page-learning-tools-tenderly-logo-alt": "Логотип Tenderly", - "page-learning-tools-replit-logo-alt": "Логотип Replit", - "page-learning-tools-remix-logo-alt": "Логотип Remix", - "page-learning-tools-sandbox": "Песочницы для кода", - "page-learning-tools-sandbox-desc": "Эти песочницы дадут вам пространство для экспериментов с написанием смарт-контрактов и пониманием Ethereum.", - "page-learning-tools-speed-run-ethereum-description": "Speed Run Ethereum — это набор задач для проверки ваших знаний Solidity с использованием Scaffold-ETH", - "page-learning-tools-speed-run-ethereum-logo-alt": "Логотип Speed Run Ethereum", - "page-learning-tools-studio-description": "Интегрированная онлайн-среда разработки, в которой вы можете следовать учебникам для создания и тестирования смарт-контрактов и построить внешний интерфейс для них.", - "page-learning-tools-vyperfun-description": "Изучите Vyper, построив свою собственную игру Pokémon.", - "page-learning-tools-vyperfun-logo-alt": "Логотип Vyper.fun", - "page-learning-tools-nftschool-description": "Узнайте, что происходит с невзаимозаменяемыми токенами (или NFT) с технической точки зрения.", - "page-learning-tools-nftschool-logo-alt": "Логотип школы NFT", - "page-learning-tools-platzi-description": "Узнайте, как создавать децентрализованные приложения на Web3, и овладейте всеми навыками, необходимыми для разработчика блокчейна.", - "page-learning-tools-platzi-logo-alt": "Логотип Platzi", - "page-learning-tools-alchemy-university-description": "Развивайте свою карьеру в web3 с помощью курсов, проектов и кода.", - "page-learning-tools-alchemy-university-logo-alt": "Логотип Alchemy University", - "page-learning-tools-learnweb3-description": "LearnWeb3 — это бесплатная образовательная платформа, которая поможет вам пройти путь от начинающего до мастера в разработке Web3.", - "page-learning-tools-learnweb3-logo-alt": "Логотип LearnWeb3", - "page-learning-tools-cyfrin-updraft-description": "Курсы по разработке смарт-контрактов и аудиту безопасности для всех уровней подготовки.", - "page-learning-tools-cyfrin-updraft-logo-alt": "Логотип Cyfrin Updraft", - "alt-eth-blocks": "Иллюстрация блоков организуется как символ ETH" -} diff --git a/src/intl/ru/page-developers-local-environment.json b/src/intl/ru/page-developers-local-environment.json deleted file mode 100644 index 567163d29bf..00000000000 --- a/src/intl/ru/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "Основанная на Python платформа для разработки и тестирования смарт-контрактов, нацеленных на Ethereum Virtual Machine.", - "page-local-environment-brownie-logo-alt": "Логотип Brownie", - "page-local-environment-kurtosis-desc": "Инструментарий на основе контейнера для простой настройки и запуска тестовой сети Ethereum с большим количеством клиентов, в которой можно быстро разрабатывать локальные децентрализованные приложения, прототипировать и тестировать их.", - "page-local-environment-kurtosis-logo-alt": "Логотип Kurtosis", - "page-local-environment-epirus-desc": "Платформа для разработки, развертывания и мониторинга блокчейн-приложений на виртуальной машине Java.", - "page-local-environment-epirus-logo-alt": "Логотип Epirus", - "page-local-environment-eth-app-desc": "Создавайте приложения на базе Ethereum одной командой. Сопровождается широким выбором фреймворков пользовательского интерфейса и шаблонов DeFi.", - "page-local-environment-eth-app-logo-alt": "Создать логотип Eth App", - "page-local-environment-foundry-desc": "Молниеносный, портативный и модульный инструментарий для разработки приложений Ethereum, написанный на языке Rust.", - "page-local-environment-foundry-logo-alt": "Логотип Foundry", - "page-local-environment-framework-feature-1": "Функции для запуска локального экземпляра блокчейна.", - "page-local-environment-framework-feature-2": "Утилиты для составления и тестирования ваших смарт-контрактов.", - "page-local-environment-framework-feature-3": "Клиентские разработки дополнений для создания вашего пользовательского приложения в рамках одного проекта/репозитория.", - "page-local-environment-framework-feature-4": "Конфигурация для подключения к сетям Ethereum и создания контрактов, будь то локальный запуск или одна из публичных сетей Ethereum.", - "page-local-environment-framework-feature-5": "Децентрализованное распределение приложений - интеграция с различными способами хранения данных, такими как IPFS.", - "page-local-environment-framework-features": "Эти фреймворки идут совместно с большим количеством нестандартного функционала, например:", - "page-local-environment-frameworks-desc": " Мы рекомендуем выбрать фреймворк, особенно если вы только начинаете работу. Создание полноценного приложения требует различных технологий. Фреймворк включает в себя множество необходимых функций или предоставляет простые системы плагинов для выбора нужных вам инструментов.", - "page-local-environment-frameworks-title": "Фреймворки и готовые стеки", - "page-local-environment-hardhat-desc": "Hardhat - это среда разработки Ethereum для профессионалов.", - "page-local-environment-hardhat-logo-alt": "Логотип Hardhat", - "page-local-environment-openZeppelin-desc": "Сократите время разработки, составляя, совершенствуя и взаимодействуя со смарт-контрактами с нашим CLI.", - "page-local-environment-openZeppelin-logo-alt": "Логотип OpenZeppelin", - "page-local-environment-scaffold-eth-desc": "Ethers + Hardhat + React — все, что вам нужно, чтобы начать создавать децентрализованные приложения на основе умных контрактов.", - "page-local-environment-scaffold-eth-logo-alt": "логотип scaffold-eth", - "page-local-environment-setup-meta-desc": "Руководство по выбору стека ПО для разработки на Ethereum.", - "page-local-environment-setup-meta-title": "Настройка локальной разработки на Ethereum", - "page-local-environment-setup-subtitle": "Если вы готовы приступить к созданию приложения, пришло время выбрать стек.", - "page-local-environment-setup-subtitle-2": " Вот инструменты и фреймворки, которые вы можете использовать, чтобы создать приложение Ethereum.", - "page-local-environment-setup-title": "Настройте локальную среду разработки", - "page-local-environment-solidity-template-desc": "Шаблон GitHub для предварительной установки ваших смарт-контрактов Solidity. Включает в себя локальную сеть Hardhat, Waffle для тестирования, Ethers для применения кошелька и многое другое.", - "page-local-environment-solidity-template-logo-alt": "Логотип шаблона Solidity" -} \ No newline at end of file diff --git a/src/intl/sw/page-developers-learning-tools.json b/src/intl/sw/page-developers-learning-tools.json deleted file mode 100644 index 6ec27aab46f..00000000000 --- a/src/intl/sw/page-developers-learning-tools.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "Kozi ya BloomTech Web3 itakufundisha ujuzi wanaotafuta waajiri kutoka kwa wahandisi.", - "page-learning-tools-bloomtech-logo-alt": "Nembo ya BloomTech", - "page-learning-tools-bootcamps": "Mafunzo kwa wasanidi programu", - "page-learning-tools-bootcamps-desc": "Kozi za mtandaoni zilizolipiwa zitakuwezesha haraka.", - "page-learning-tools-browse-docs": "Vinjari nyaraka", - "page-learning-tools-capture-the-ether-description": "Kamata Ether ni mchezo ambao utadukua mikataba erevu ya Ethereum ili kujifunza kuhusu usalama.", - "page-learning-tools-capture-the-ether-logo-alt": "Kamata nembo ya Ether", - "page-learning-tools-coding": "Jifunze kwa usimbuaji", - "page-learning-tools-coding-subtitle": "Vifaa hivi vitakusaidia kufanya majaribio ya Ethereum kama ungependa maingiliano zaidi wakati wa kujifunza.", - "page-learning-tools-consensys-academy-description": "Kamabi ya kujifunzia ya usanidi programu za Ethereum mtandaoni.", - "page-learning-tools-consensys-academy-logo-alt": "Nembo ya ConsenSys Academy", - "page-learning-tools-cryptozombies-description": "Jifunze Solidity kwa kujenga mchezo wa watu wa kutisha.", - "page-learning-tools-cryptozombies-logo-alt": "Nembo ya CryptoZombies", - "page-learning-tools-documentation": "Jifunze na nyaraka", - "page-learning-tools-documentation-desc": "Unataka kujifunza zaidi? Nenda kwenye nyaraka zetu kupata maelezo unayohitaji.", - "page-learning-tools-eth-dot-build-description": "Sanduku la kuelimisha kuhusu web3, ikijumuisha mtindo wa kuprogramu kwa kuvuta-na-kudondosha na ni vifaa vya kujengea vilivyo huria.", - "page-learning-tools-eth-dot-build-logo-alt": "Nembo ya Eth.build", - "page-learning-tools-ethernauts-description": "Maliza viwango vyote kwa kudukua mikataba erevu.", - "page-learning-tools-ethernauts-logo-alt": "Nembo ya Ethernauts", - "page-learning-tools-game-tutorials": "Mafunzo kwa njia ya mchezo wa mwingiliano", - "page-learning-tools-game-tutorials-desc": "Jifunze huku unacheza. Mafunzo haya yatakufundisha vitu vyote vya msingi kwa kutumia gameplay.", - "page-learning-tools-meta-desc": "Zana za usimbuaji za wavuti na kujifunza kwa kuingiliana utakusaidia kujaribu uundaji wa Ethereum.", - "page-learning-tools-meta-title": "Zana za msanidi programu", - "page-learning-tools-questbook-description": "Madunzo ya kasi binafsi lujifunza Web 3.0 kwa kujenga", - "page-learning-tools-questbook-logo-alt": "Nembo ya Questbook", - "page-learning-tools-remix-description": "Unda, tuma na simamia mikataba erevu ya Ethereum. Pata mafunzo na programu-jalizi ya Learneth.", - "page-learning-tools-remix-description-2": "Remix na Replit ni zaidi ya eneo la majaribio, wasanidi programu wanaweza kuandika, kukusanya na kupeleka mikataba erevu mtandaoni kwa kuzitumia.", - "page-learning-tools-replit-description": "Mazingira yanayoweza kubalishwa kulingana na mahitaji ya Ethereum yenye kasi ya upakiaji, kukagua makosa, na misaada ya ukaguzu wa mtandao ya kiwango cha juu.", - "page-learning-tools-replit-logo-alt": "Nembo ya Replit", - "page-learning-tools-remix-logo-alt": "Nembo ya Remix", - "page-learning-tools-sandbox": "Visanduku vya msimbo", - "page-learning-tools-sandbox-desc": "Hivi visanduku vitakupa nafasi ya kufanya majaribio ya uandishi wa mikataba erevu na kuielewa Ethereum.", - "page-learning-tools-studio-description": "Mfunzo ya wavuti yenye mazingira jumuishi ya uundaji katika ujenzi na majaribio ya mikataba erevu, na kujenga mfumo wa mbele kwa ajili yao.", - "page-learning-tools-vyperfun-description": "Jifunze Vyper kwa kuunda mchezo wa Pokémon.", - "page-learning-tools-vyperfun-logo-alt": "Nembo ya Vyper.fun", - "page-learning-tools-nftschool-description": "Chunguza nini kinaendelea na ishara-zisizokuvu, au NFT kutoka kwa mafundi.", - "page-learning-tools-nftschool-logo-alt": "Nembo ya shule ya NFT", - "alt-eth-blocks": "Kielelezo cha matofali yaliopangwa kama nembo ya ETH" -} \ No newline at end of file diff --git a/src/intl/sw/page-developers-local-environment.json b/src/intl/sw/page-developers-local-environment.json deleted file mode 100644 index 8d8ee9f373e..00000000000 --- a/src/intl/sw/page-developers-local-environment.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "page-local-environment-brownie-desc": "Uundaji ulio na misingi ya Python na mfumo wa kufanyia majaribio ya mikataba erervu inayolenga Mashine ya Mtandaoni ya Ethereum.", - "page-local-environment-brownie-logo-alt": "Nembo ya Brownie", - "page-local-environment-epirus-desc": "Jukwaa la kukuza, kupeleka na kufuatilia programu za blockchain kwenye Mashine ya Mtandaoni ya Java", - "page-local-environment-epirus-logo-alt": "Nembo ya Epirus", - "page-local-environment-eth-app-desc": "Unda programu zinazoendeshwa na Ethereum kwa amri moja. Inakuja na matoleo mengi ya mifumo ya UI na violezo vya DeFi kuchagua.", - "page-local-environment-eth-app-logo-alt": "Tengeneza nembo ya programu ya Eth", - "page-local-environment-framework-feature-1": "Vipengele vya kuunda mfano wa mnyororo wa bloku.", - "page-local-environment-framework-feature-2": "Huduma za kukusanya na kujaribu mikataba yako mahiri.", - "page-local-environment-framework-feature-3": "Viongezi vya ukuzaji wa mteja ili kuunda programu yako inayomkabili mtumiaji ndani ya mradi/hazina sawa.", - "page-local-environment-framework-feature-4": "Mipangilio ya kuunganisha kwenye mitandao ya Ethereum na kupeleka kandarasi, iwe kwa mfano unaoendeshwa ndani ya nchi, au mojawapo ya mitandao ya umma ya Ethereum.", - "page-local-environment-framework-feature-5": "Usambazaji wa programu uliogatuliwa - miunganisho na chaguo za hifadhi kama vile IPFS.", - "page-local-environment-framework-features": "Miundo hii inakuja na utendaji mwingi wa nje ya sanduku, kama:", - "page-local-environment-frameworks-desc": "Tunapendekeza uchague mfumo, haswa ikiwa ndio kwanza unaanza. Kuunda dapp kamili kunahitaji vipande tofauti vya teknolojia. Mifumo inajumuisha vipengele vingi vinavyohitajika au kutoa mifumo rahisi ya programu-jalizi ili kuchagua zana unazotaka.", - "page-local-environment-frameworks-title": "Miundo na safu zilizotengenezwa mapema", - "page-local-environment-hardhat-desc": "Hardhat ni mazingira ya maendeleo ya Ethereum kwa wataalamu.", - "page-local-environment-hardhat-logo-alt": "Nembo ya Hardhat", - "page-local-environment-openZeppelin-desc": "Punguza muda wa kufabya kazi kwa kuandaa, kusasisha, kuzindua na kuingiliana na mikataba erevu kwa kutumia kiolesura cha mstari wa amri tuliotengeneza.", - "page-local-environment-openZeppelin-logo-alt": "Nembo ya OpenZappelin", - "page-local-environment-scaffold-eth-desc": "Ethers + hardhat + React: Ni kila kitu unachohitaji ili kuanza kujenga programu zilizogatuliwa zinazopewa nguvu na mikataba erevu", - "page-local-environment-scaffold-eth-logo-alt": "nembo ya scaffold-eth", - "page-local-environment-setup-meta-desc": "Muongozo wa kufuata katika kuchagua msururu utakaotumia kufanya uundaji kwenye Ethereum.", - "page-local-environment-setup-meta-title": "Uanzishaji rafiki wa eneo la uundaji wa Ethereum", - "page-local-environment-setup-subtitle": "Kama uko tayari kuanza kujenga, ni muda wa kuchagua msururu sasa.", - "page-local-environment-setup-subtitle-2": "Vifaa na mifumo inayoweza kukusaidia kujenga programu za Ethereum ziko hapa.", - "page-local-environment-setup-title": "Anzisha eneo lako rafiki kwaajili ya uundaji", - "page-local-environment-solidity-template-desc": "Kiolezo cha GitHub kilichojengwa tayari kwa ajili ya mikataba erevu ya Solidity utakayojenga. Inajumuisha mtandao wa Hardhat, Waffle kwa ajili ya kufanya majaribio, Ethers kwa ajili ya utekelezaji wa pochi, na mengine mengi.", - "page-local-environment-solidity-template-logo-alt": "Nembo kiolezo cha Solidity" -} \ No newline at end of file diff --git a/src/intl/ta/page-developers-learning-tools.json b/src/intl/ta/page-developers-learning-tools.json deleted file mode 100644 index e9bfee88339..00000000000 --- a/src/intl/ta/page-developers-learning-tools.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "alt-eth-blocks": "பிளாக்குகள் ETH சின்னம்போல் அடுக்கப்பட்டிருப்பதைக் காட்டும் படம்" -} diff --git a/src/intl/tr/page-developers-learning-tools.json b/src/intl/tr/page-developers-learning-tools.json deleted file mode 100644 index 5a8ec55a1b5..00000000000 --- a/src/intl/tr/page-developers-learning-tools.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "BloomTech Web3 kursu size işverenlerin mühendislerde aradıkları becerileri öğretecek.", - "page-learning-tools-bloomtech-logo-alt": "BloomTech logosu", - "page-learning-tools-bootcamps": "Geliştirici bootcampleri", - "page-learning-tools-bootcamps-desc": "Öğreniminizi hızlandırmak için ücretli kurslar alın.", - "page-learning-tools-browse-docs": "Dokümanlara göz atın", - "page-learning-tools-capture-the-ether-description": "Capture the Ether, güvenlik hakkında bilgi edinmek için Ethereum akıllı sözleşmelerini hacklediğiniz bir oyundur.", - "page-learning-tools-capture-the-ether-logo-alt": "Capture the Ether logosu", - "page-learning-tools-node-guardians-description": "Node Guardians, web3 geliştiricilerinin Solidity, Cairo, Noir ve Huff programlamasında uzmanlaşabilmeleri için fantezi temalı görevler sunan oyunlaştırılmış bir eğitim platformudur.", - "page-learning-tools-node-guardians-logo-alt": "Node Guardians logosu", - "page-learning-tools-chainshot-description": "Uzaktan, eğitmen liderliğindeki Ethereum geliştirici eğitim kampı ve ek kurslar.", - "page-learning-tools-chainshot-logo-alt": "ChainShot logo", - "page-learning-tools-coding": "Kodlayarak öğrenin", - "page-learning-tools-coding-subtitle": "Etkileşimli bir öğrenim modelini tercih ediyorsanız, bu araçlar Ethereum' u denemenizde yardımcı olacaktır.", - "page-learning-tools-consensys-academy-description": "Online Ethereum geliştirici eğitim programı.", - "page-learning-tools-consensys-academy-logo-alt": "ConsenSys Academy logosu", - "page-learning-tools-cryptozombies-description": "Kendi Zombi oyunununuzu inşa ederek Solidity öğrenin.", - "page-learning-tools-cryptozombies-logo-alt": "CryptoZombies logosu", - "page-learning-tools-dapp-world-description": "Kurslar, sınavlar, uygulamalı alıştırmalar ve haftalık yarışmalar içeren bir blokzincir yetenek geliştirme platformu.", - "page-learning-tools-dapp-world-logo-alt": "Dapp World logosu", - "page-learning-tools-documentation": "Dokümantasyon ile öğrenin", - "page-learning-tools-documentation-desc": "Daha fazla bilgi edinmek ister misiniz? İhtiyacınız olan açıklamaları bulmak için dokümantasyona göz atın.", - "page-learning-tools-eth-dot-build-description": "Sürükle ve bırak programlama ve açık kaynaklı yapı taşları da dahil olmak üzere web3 için bir sandbox.", - "page-learning-tools-eth-dot-build-logo-alt": "Eth.build logosu", - "page-learning-tools-ethernauts-description": "Akıllı kontratları hackleyerek bölümleri tamamlayın.", - "page-learning-tools-ethernauts-logo-alt": "Ethernauts logosu", - "page-learning-tools-metaschool-description": "Merkeziyetsiz uygulamalar oluşturarak ve bunların alışverişini yaparak bir Web3 Geliştirici olun.", - "page-learning-tools-metaschool-logo-alt": "_metaschool logosu", - "page-learning-tools-game-tutorials": "İnteraktif oyun öğreticiler", - "page-learning-tools-game-tutorials-desc": "Oynarken öğrenin. Bu öğreticiler, oyunun temellerini anlamanıza yardımcı olacaktır.", - "page-learning-tools-meta-desc": "Ethereum ile denemeler ve geliştirmeler yapmanıza yardımcı olmak için Web tabanlı kodlama araçları ve etkileşimli öğrenme deneyimleri.", - "page-learning-tools-meta-title": "Geliştirici öğrenme araçları", - "page-learning-tools-atlas-logo-alt": "Atlas logosu", - "page-learning-tools-atlas-description": "Atlas IDE ile akıllı sözleşmeler yazın, test edin ve dağıtın.", - "page-learning-tools-questbook-description": "Web 3.0 oluşturarak kendi kendinize öğrenin", - "page-learning-tools-questbook-logo-alt": "Questbook Logosu", - "page-learning-tools-remix-description": "Ethereum'a akıllı sözleşmeler geliştir, dağıt ve yönet. LearnEth eklentisiyle öğreticileri takip et.", - "page-learning-tools-remix-description-2": "Remix, Replit, ChainIDE ve Atlas sadece sanal alan değildir; geliştiriciler, bunları kullanarak akıllı sözleşmeler yazabilir, derleyebilir ve dağıtabilir.", - "page-learning-tools-replit-description": "Çalışırken yeniden yükleme, hata denetimi ve birinci sınıf test ağı desteği ile Ethereum için özelleştirilebilir bir geliştirme ortamı.", - "page-learning-tools-chainIDE-description": "ChainIDE ile Ethereum için akıllı sözleşmeler yazarak Web3 yolculuğunuza başlayın. Öğrenmek ve zaman kazanmak için yerleşik şablonları kullanın.", - "page-learning-tools-chainIDE-logo-alt": "ChainİDE logosu", - "page-learning-tools-tenderly-description": "Tenderly Sandbox, Solidity ve JavaScript kullanarak tarayıcı üzerinde akıllı sözleşmeler yazabileceğiniz, çalıştırabileceğiniz ve hatalarını ayıklayabileceğiniz bir prototipleme ortamıdır.", - "page-learning-tools-tenderly-logo-alt": "Tenderly logosu", - "page-learning-tools-replit-logo-alt": "Replit logosu", - "page-learning-tools-remix-logo-alt": "Remix logosu", - "page-learning-tools-sandbox": "Sandboxların kodu", - "page-learning-tools-sandbox-desc": "Bu sandboxlar, akıllı sözleşmeler yazmayı ve Ethereum'u anlamayı denemek için size bir alan sağlayacaktır.", - "page-learning-tools-speed-run-ethereum-description": "Speed Run Ethereum, Solidity bilginizi Scaffold-ETH kullanarak test etmenizi sağlayan bir sınama setidir", - "page-learning-tools-speed-run-ethereum-logo-alt": "Speed Run Ethereum logosu", - "page-learning-tools-studio-description": "Akıllı sözleşmeler oluşturmak ve test etmek, onlar için bir ön uç oluşturmak için öğreticileri takip edebileceğiniz web tabanlı bir IDE.", - "page-learning-tools-vyperfun-description": "Kendi Pokémon oyununuzu oluşturarak Vyper öğrenin.", - "page-learning-tools-vyperfun-logo-alt": "Vyper.fun logosu", - "page-learning-tools-nftschool-description": "Değiştirilemez tokenler veya NFT'ler ile teknik açıdan neler olup bittiğini keşfedin.", - "page-learning-tools-nftschool-logo-alt": "NFT school logosu", - "page-learning-tools-pointer-description": "Eğlenceli olan etkileşimli öğreticilerle web3 geliştirme becerilerini öğrenin. Bu sırada kripto ödülleri kazanın", - "page-learning-tools-pointer-logo-alt": "İşaretçi Logosu", - "page-learning-tools-platzi-description": "Web3 üzerinde merkeziyetsiz uygulamalar oluşturmayı öğrenin ve bir blok zincir geliştiricisi olmak için gereken tüm becerilerde ustalaşın.", - "page-learning-tools-platzi-logo-alt": "Platzi logosu", - "page-learning-tools-alchemy-university-description": "Web3 kariyerinizi kurslar, projeler ve kodlarla geliştirin.", - "page-learning-tools-alchemy-university-logo-alt": "Alchemy Üniversitesi logosu", - "alt-eth-blocks": "Bir ETH sembolü gibi düzenlenmiş bloklar görseli" -} diff --git a/src/intl/tr/page-developers-local-environment.json b/src/intl/tr/page-developers-local-environment.json deleted file mode 100644 index 3a4621c41e5..00000000000 --- a/src/intl/tr/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "Ethereum Sanal Makinesi'ni hedefleyen akıllı sözleşmeler için Python bazlı bir geliştirme ve yazılım iskeleti.", - "page-local-environment-brownie-logo-alt": "Brownie logosu", - "page-local-environment-kurtosis-desc": "Kolay yapılandırılabilen ve hızlı yerel dApp geliştirebilme, prototipleme ve testi için, çoklu istemci Ethereum test ağı oluşturabilen konteyner tabanlı bir araç seti.", - "page-local-environment-kurtosis-logo-alt": "Kurtosis logosu", - "page-local-environment-epirus-desc": "Java Sanal Makinesinde blokzincir uygulamalarını geliştirmek, dağıtmak ve izlemek için bir platform.", - "page-local-environment-epirus-logo-alt": "Epirus logosu", - "page-local-environment-eth-app-desc": "Tek bir komutla Ethereum destekli uygulamalar oluşturun. Seçebileceğiniz birbirinden farklı arayüz yapıları ve DeFi şablonları da bulunur.", - "page-local-environment-eth-app-logo-alt": "Create Eth App logosu", - "page-local-environment-foundry-desc": "Rust ile yazılmış, Ethereum uygulama geliştirme için son derece hızlı, taşınabilir ve modüler bir araç takımı.", - "page-local-environment-foundry-logo-alt": "Foundry logosu", - "page-local-environment-framework-feature-1": "Yerel bir blok-zincir örneğini döndürmek için özellikler.", - "page-local-environment-framework-feature-2": "Akıllı sözleşmelerinizi derlemek ve test etmek için yardımcı programlar.", - "page-local-environment-framework-feature-3": "Kullanıcı odaklı uygulamanızı aynı projede/depoda oluşturmak için istemci geliştirme eklentileri.", - "page-local-environment-framework-feature-4": "Yerel olarak çalışan bir örneğe veya Ethereum' un genel ağlarından birine olsun, Ethereum ağlarına bağlanmak ve sözleşmeleri dağıtmak için yapılandırma.", - "page-local-environment-framework-feature-5": "Merkezi olmayan uygulama dağıtımı için IPFS gibi depolama seçenekleriyle entegrasyonlar.", - "page-local-environment-framework-features": "Bu frameworkler, bir sürü kutu dışı işlevsellik ile birlikte gelir:", - "page-local-environment-frameworks-desc": "Özellikle yeni başlıyorsanız, bir framework seçmenizi öneririz. Tam teşekküllü bir uygulama oluşturmak, farklı teknoloji parçaları gerektirir. Frameworkler, gerekli özelliklerin çoğunu içerir veya istediğiniz araçları seçmek için basit eklenti sistemleri sağlar.", - "page-local-environment-frameworks-title": "Framework'ler ve önceden yapılmış yığınlar", - "page-local-environment-hardhat-desc": "Hardhat, profesyoneller için bir Ethereum geliştirme ortamıdır.", - "page-local-environment-hardhat-logo-alt": "Hardhat logosu", - "page-local-environment-openZeppelin-desc": "CLI ile akıllı sözleşmeleri derleyerek, yükselterek, dağıtarak ve etkileşime girerek geliştirme süresinden saatlerce tasarruf edin.", - "page-local-environment-openZeppelin-logo-alt": "OpenZeppelin logosu", - "page-local-environment-scaffold-eth-desc": "Ethers + Hardhat + React: Akıllı sözleşmelerle desteklenen merkeziyetsu=iz uygulamalar oluşturmaya başlamak için ihtiyacınız olan her şey.", - "page-local-environment-scaffold-eth-logo-alt": "scaffold-eth logosu", - "page-local-environment-setup-meta-desc": "Ethereum geliştirmek için yazılım yığınınızı nasıl seçeceğinize dair bir rehber.", - "page-local-environment-setup-meta-title": "Ethereum yerel geliştirme kurulumu", - "page-local-environment-setup-subtitle": "İnşa etmeye hazırsanız, yığınınızı seçmenin zamanı geldi.", - "page-local-environment-setup-subtitle-2": " Ethereum uygulamanızı oluşturmanıza yardımcı olmak için kullanabileceğiniz araçlar ve framework'ler.", - "page-local-environment-setup-title": "Sanal geliştirme ortamınızı oluşturun", - "page-local-environment-solidity-template-desc": "Solidity akıllı sözleşmeleriniz için önceden oluşturulmuş bir GitHub şablonu. Hardhat yerel ağı, testler için Waffle, cüzdan uygulaması için Etherler ve daha fazlasını içerir.", - "page-local-environment-solidity-template-logo-alt": "Solidity template logosu" -} \ No newline at end of file diff --git a/src/intl/uk/page-developers-learning-tools.json b/src/intl/uk/page-developers-learning-tools.json deleted file mode 100644 index c9f6de23a62..00000000000 --- a/src/intl/uk/page-developers-learning-tools.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "Курс Web3 від BloomTech навчить вас навичок, які роботодавці шукають в інженерах.", - "page-learning-tools-bloomtech-logo-alt": "Логотип BloomTech", - "page-learning-tools-bootcamps": "Посібники для розробників", - "page-learning-tools-bootcamps-desc": "Платні онлайн-курси, які швидко підготують вас до роботи.", - "page-learning-tools-browse-docs": "Переглянути документи", - "page-learning-tools-capture-the-ether-description": "Capture the Ether — це гра, у якій ви зламуєте смартконтракти Ethereum для вивчення принципів безпеки.", - "page-learning-tools-capture-the-ether-logo-alt": "Захоплення логотипу Ether", - "page-learning-tools-coding": "Кодуй і навчайся", - "page-learning-tools-coding-subtitle": "Ці інструменти дадуть змогу експериментувати з мережею Ethereum, якщо ви віддаєте перевагу більш інтерактивному навчанню.", - "page-learning-tools-consensys-academy-description": "Онлайн-посібник для розробників Ethereum.", - "page-learning-tools-consensys-academy-logo-alt": "ConsenSys Academy logo", - "page-learning-tools-cryptozombies-description": "Вивчайте Solidity на прикладі створення гри про зомбі.", - "page-learning-tools-cryptozombies-logo-alt": "CryptoZombies logo", - "page-learning-tools-documentation": "Навчайтеся за допомогою документів", - "page-learning-tools-documentation-desc": "Хочете дізнатися більше? Перегляньте наші документи, щоб знайти потрібні пояснення.", - "page-learning-tools-eth-dot-build-description": "Навчальна пісочниця для Web3, що включає програмування перетягуванням і блоки з відкритим кодом.", - "page-learning-tools-eth-dot-build-logo-alt": "Eth.build logo", - "page-learning-tools-ethernauts-description": "Проходьте рівні, зламуючи розумні контракти.", - "page-learning-tools-ethernauts-logo-alt": "Ethernauts logo", - "page-learning-tools-metaschool-description": "Станьте розробником Web3, створюючи й надаючи децентралізовані програми.", - "page-learning-tools-metaschool-logo-alt": "Логотип Metaschool", - "page-learning-tools-game-tutorials": "Інтерактивні ігрові посібники", - "page-learning-tools-game-tutorials-desc": "Грайте й навчайтеся. Ці посібники допоможуть вам зрозуміти основи під час гри.", - "page-learning-tools-meta-desc": "Веб-інструменти кодування та інтерактивне навчання, які допоможуть вам експериментувати з розробкою мережі Ethereum.", - "page-learning-tools-meta-title": "Навчальні інструменти для розробників", - "page-learning-tools-questbook-description": "Навчальні матеріали щодо Web 3.0 для самостійного опрацювання", - "page-learning-tools-questbook-logo-alt": "Логотип Questbook", - "page-learning-tools-remix-description": "Розробляйте й упроваджуйте смартконтракти для мережі Ethereum, а також керуйте ними. Скористайтеся посібниками за допомогою плагіну LearnEth.", - "page-learning-tools-remix-description-2": "Remix, Replit і ChainIDE — це не просто пісочниці. За їх допомогою розробники можуть писати, компілювати й розгортати смартконтракти.", - "page-learning-tools-replit-description": "Настроюване середовище розробки для Ethereum із гарячим перезавантаженням, перевіркою помилок і першокласною підтримкою тестової мережі.", - "page-learning-tools-chainIDE-description": "Розпочніть свою подорож до Web3, пишучи смартконтракти для Ethereum за допомогою ChainIDE. Використовуйте вбудовані шаблони, щоб навчатися й заощаджувати час.", - "page-learning-tools-chainIDE-logo-alt": "Логотип ChainIDE", - "page-learning-tools-tenderly-description": "Tenderly Sandbox — це середовище прототипування, де ви можете писати, виконувати та налагоджувати смартконтракти в браузері за допомогою Solidity та JavaScript.", - "page-learning-tools-tenderly-logo-alt": "Логотип Tenderly", - "page-learning-tools-replit-logo-alt": "Логотип Replit", - "page-learning-tools-remix-logo-alt": "Remix logo", - "page-learning-tools-sandbox": "Пісочниці для кодування", - "page-learning-tools-sandbox-desc": "Ці пісочниці дозволять вам експериментувати з написанням розумних контрактів і розумінням мережі Ethereum.", - "page-learning-tools-speed-run-ethereum-description": "Speed ​​Run Ethereum — це набір завдань для перевірки ваших знань Solidity за допомогою Scaffold-ETH", - "page-learning-tools-speed-run-ethereum-logo-alt": "Логотип Speed Run Ethereum", - "page-learning-tools-studio-description": "Інтегроване веб-середовище розробки, де можна знайти посібники зі створення та тестування розумних контрактів, а також створити для користувацький інтерфейс.", - "page-learning-tools-vyperfun-description": "Вивчайте Vyper на прикладі створення власної гри Pokémon.", - "page-learning-tools-vyperfun-logo-alt": "Vyper.fun logo", - "page-learning-tools-nftschool-description": "Досліджуйте, що відбувається з невзаємозамінними токенами, або NFT, з технічного боку.", - "page-learning-tools-nftschool-logo-alt": "Логотип NFT school", - "page-learning-tools-platzi-description": "Навчіться створювати додатки на Web3 та опануйте всі навички, необхідні для роботи розробника блокчейну.", - "page-learning-tools-platzi-logo-alt": "Логотип Platzi", - "page-learning-tools-alchemy-university-description": "Розвивайте свою кар’єру у Web3 за допомогою курсів, проєктів і коду.", - "page-learning-tools-alchemy-university-logo-alt": "Логотип університету Alchemy", - "alt-eth-blocks": "Ілюстрація з блоками, зібраними в символ ETH" -} \ No newline at end of file diff --git a/src/intl/uk/page-developers-local-environment.json b/src/intl/uk/page-developers-local-environment.json deleted file mode 100644 index ea6fa30a56e..00000000000 --- a/src/intl/uk/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "Фреймворк для розробки й тестування на основі Python для розумних контрактів, націлених на Віртуальну машину Ethereum.", - "page-local-environment-brownie-logo-alt": "Логотип Brownie", - "page-local-environment-kurtosis-desc": "Інструментарій на основі контейнерів для легкого налаштування та розкручування тестової мережі з великою кількістю клієнтів Ethereum, у якій можна швидко розробляти локальні децентралізовані програми (dApp), прототипувати й тестувати їх.", - "page-local-environment-kurtosis-logo-alt": "Логотип Kurtosis", - "page-local-environment-epirus-desc": "Платформа для розробки, впровадження та відстеження блокчейн-програм на віртуальній машині Java.", - "page-local-environment-epirus-logo-alt": "Epirus logo", - "page-local-environment-eth-app-desc": "Створюйте програми на основі Ethereum за допомогою однієї команди. Містить велику кількість фреймворків інтерфейсу та шаблонів DeFi.", - "page-local-environment-eth-app-logo-alt": "Create Eth App logo", - "page-local-environment-foundry-desc": "Надзвичайно швидкий, портативний і модульний набір інструментів для розробки програм Ethereum, написаний на Rust.", - "page-local-environment-foundry-logo-alt": "Логотип Foundry", - "page-local-environment-framework-feature-1": "Функції для створення локальної системи блокчейнів.", - "page-local-environment-framework-feature-2": "Утиліти для компіляції і тестування розумних контрактів.", - "page-local-environment-framework-feature-3": "Додатки до розробки клієнта для створення користувацьких програм у межах одного проекту/репозиторію.", - "page-local-environment-framework-feature-4": "Конфігурація для підключення до мереж Ethereum і впровадження контрактів для локально запущеного блокчейну або для загальнодоступних мереж Ethereum.", - "page-local-environment-framework-feature-5": "Розподіл децентралізованих програм – інтеграція з параметрами сховища, такими як IPFS.", - "page-local-environment-framework-features": "Ці фреймворки мають багато незвичайних функцій (приклади наведено нижче).", - "page-local-environment-frameworks-desc": " Радимо обрати фреймворк, особливо якщо ви тільки починаєте. Створення повноцінної децентралізованої програми потребує різних технологій. Фреймворки містять багато корисних функцій або надають прості системи плагінів, де можна вибрати потрібні інструменти.", - "page-local-environment-frameworks-title": "Фреймворки й заготовлені стеки", - "page-local-environment-hardhat-desc": "Hardhat – це середовище розробки Ethereum для професіоналів.", - "page-local-environment-hardhat-logo-alt": "Hardhat logo", - "page-local-environment-openZeppelin-desc": "Заощаджуйте час, який витрачається на розробку, шляхом компіляції, оновлення та впровадження розумних контрактів, а також взаємодії з ними за допомогою CLI.", - "page-local-environment-openZeppelin-logo-alt": "OpenZeppelin logo", - "page-local-environment-scaffold-eth-desc": "Ethers + Hardhat + React — це все, що вам потрібно, щоб почати створювати децентралізовані програми, які працюють на основі смартконтрактів.", - "page-local-environment-scaffold-eth-logo-alt": "scaffold-eth logo", - "page-local-environment-setup-meta-desc": "Дізнайтесь, як обрати програмний стек для розробки Ethereum.", - "page-local-environment-setup-meta-title": "Налаштування локальної розробки Ethereum", - "page-local-environment-setup-subtitle": "Якщо ви готові почати, оберіть стек.", - "page-local-environment-setup-subtitle-2": " Ось інструменти та фреймворки, які ви можете використовувати для створення власної програми в мережі Ethereum.", - "page-local-environment-setup-title": "Налаштування локального середовища розробки", - "page-local-environment-solidity-template-desc": "Шаблон GitHub для попередньо вбудованих налаштувань розумних контрактів мовою Solidity. Включає локальну мережу Hardhat, Waffle для тестування, Ether для запуску гаманця тощо.", - "page-local-environment-solidity-template-logo-alt": "Solidity template logo" -} \ No newline at end of file diff --git a/src/intl/ur/page-developers-learning-tools.json b/src/intl/ur/page-developers-learning-tools.json deleted file mode 100644 index e5e10bf165d..00000000000 --- a/src/intl/ur/page-developers-learning-tools.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "alt-eth-blocks": "ETH کی علامت کی طرح ترتیب دیے جانے والے بلاکس کی تصویر" -} diff --git a/src/intl/vi/page-developers-learning-tools.json b/src/intl/vi/page-developers-learning-tools.json deleted file mode 100644 index 149b3173259..00000000000 --- a/src/intl/vi/page-developers-learning-tools.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "Khóa học BloomTech Web3 sẽ chỉ cho bạn những kỹ năng mà nhà tuyển dụng mong muốn ở các kỹ sư.", - "page-learning-tools-bloomtech-logo-alt": "Logo của BloomTech", - "page-learning-tools-bootcamps": "Chương trình đào tạo cho nhà phát triển", - "page-learning-tools-bootcamps-desc": "Các khóa học trực tuyến trả phí sẽ giúp bạn nhanh chóng bắt kịp tốc độ.", - "page-learning-tools-browse-docs": "Duyệt tài liệu", - "page-learning-tools-capture-the-ether-description": "Capture the Ether là một trò chơi trong đó, người chơi tìm hiểu về bảo mật bằng cách xâm nhập các hợp đồng thông minh Ethereum.", - "page-learning-tools-capture-the-ether-logo-alt": "Logo của Capture the Ether", - "page-learning-tools-coding": "Tìm hiểu bằng cách mã hoá", - "page-learning-tools-coding-subtitle": "Nếu bạn muốn có một môi trường học tập giàu tính tương tác hơn, thì những công cụ này sẽ giúp bạn trải nghiệm với Ethereum.", - "page-learning-tools-consensys-academy-description": "Developer bootcamp trực tuyến về Ethereum.", - "page-learning-tools-consensys-academy-logo-alt": "Logo của học viện ConsenSys", - "page-learning-tools-cryptozombies-description": "Tìm hiểu Solidity bằng cách phát triển game Zombie của riêng bạn.", - "page-learning-tools-cryptozombies-logo-alt": "Logo của CryptoZombies", - "page-learning-tools-documentation": "Tìm hiểu với tài liệu tham khảo", - "page-learning-tools-documentation-desc": "Bạn muốn tìm hiểu thêm? Truy cập tài liệu tham khảo của chúng tôi để tìm lời giải đáp cho thắc mắc của bạn.", - "page-learning-tools-eth-dot-build-description": "Hộp cát để học cho web3 có tính năng lập trình kéo và thả và các khối xây dựng mã nguồn mở.", - "page-learning-tools-eth-dot-build-logo-alt": "Logo của Eth.build", - "page-learning-tools-ethernauts-description": "Hoàn thành các cấp độ bằng cách xâm nhập hợp đồng thông minh.", - "page-learning-tools-ethernauts-logo-alt": "Logo của Ethernauts", - "page-learning-tools-metaschool-description": "Trở thành Nhà phát triển Web3 bằng cách xây dựng và chuyển giao các ứng dụng phi tập trung.", - "page-learning-tools-metaschool-logo-alt": "Logo của _metaschool", - "page-learning-tools-game-tutorials": "Hướng dẫn về game tương tác", - "page-learning-tools-game-tutorials-desc": "Tìm hiểu thêm trong khi chơi. Hướng dẫn này giúp bạn tìm hiểu những kiến thức cơ bản thông qua trò chơi.", - "page-learning-tools-meta-desc": "Bạn có thể khám phá quá trình phát triển của Ethereum bằng cách sử dụng các công cụ mã hóa trực tuyến và trải nghiệm học tập tương tác.", - "page-learning-tools-meta-title": "Công cụ học tập dành cho nhà phát triển", - "page-learning-tools-questbook-description": "Hướng dẫn tự học về Web 3.0 bằng cách xây dựng", - "page-learning-tools-questbook-logo-alt": "Logo của Questbook", - "page-learning-tools-remix-description": "Phát triển, triển khai và quản lý hợp đồng thông minh cho Ethereum. Làm theo hướng dẫn với plugin LearnEth.", - "page-learning-tools-remix-description-2": "Remix, Replit, và ChanIDE không chỉ là hộp cát—các nhà phát triển có thể viết, biên dịch và triển khai các hợp đồng thông minh của họ bằng cách sử dụng chúng.", - "page-learning-tools-replit-description": "Một môi trường phát triển Ethereum có thể định cấu hình với khả năng tải lại nóng, kiểm tra lỗi và hỗ trợ mạng thử nghiệm ở cấp độ cao nhất.", - "page-learning-tools-chainIDE-description": "Bắt đầu hành trình Web3 của bạn bằng cách tạo các hợp đồng thông minh Ethereum với ChainIDE. Sử dụng các mẫu có sẵn để học và tiết kiệm thời gian.", - "page-learning-tools-chainIDE-logo-alt": "Logo của ChainIDE", - "page-learning-tools-tenderly-description": "Tenderly Sandbox là một môi trường tạo nguyên mẫu mà bạn có thể viết, thực thi, và gỡ lỗi hợp đồng thông minh trong trình duyệt bằng Solidity và JavaScript.", - "page-learning-tools-tenderly-logo-alt": "Logo của Tenderly", - "page-learning-tools-replit-logo-alt": "Logo của Replit", - "page-learning-tools-remix-logo-alt": "Logo của Remix", - "page-learning-tools-sandbox": "Hộp cát mã", - "page-learning-tools-sandbox-desc": "Các môi trường thử nghiệm này cho bạn không gian để thực hành tạo các hợp đồng thông minh và hiểu biết thêm về Ethereum.", - "page-learning-tools-speed-run-ethereum-description": "Speed Run Ethereum là một bộ thử thách để kiểm tra kiến thức Solidity của bạn bằng cách sử dụng Scaffold-ETH", - "page-learning-tools-speed-run-ethereum-logo-alt": "Logo của Speed Run Ethereum", - "page-learning-tools-studio-description": "IDE (Môi trường phát triển tích hợp) dựa trên web, nơi bạn có thể làm theo hướng dẫn để xây dựng và kiểm tra hợp đồng thông minh cũng như xây dựng giao diện người dùng cho chúng.", - "page-learning-tools-vyperfun-description": "Tìm hiểu về Vyper bằng cách xây dựng game Pokémon của riêng bạn.", - "page-learning-tools-vyperfun-logo-alt": "Logo của Vyper.fun", - "page-learning-tools-nftschool-description": "Khám phá về mặt kỹ thuật những gì đang xảy ra với token không thể thay thế hoặc NFT (tài sản không thể thay thế).", - "page-learning-tools-nftschool-logo-alt": "Logo của NFT school (tài sản không thể thay thế)", - "page-learning-tools-platzi-description": "Học cách xây dựng các ứng dụng phi tập trung (dapp) trên Web3 và làm chủ các kỹ năng cần có để trở thành nhà phát triển chuỗi khối.", - "page-learning-tools-platzi-logo-alt": "Logo của Platzi", - "page-learning-tools-alchemy-university-description": "Phát triển sự nghiệp web3 của bạn thông qua các khóa học, dự án và viết mã.", - "page-learning-tools-alchemy-university-logo-alt": "Logo của Alchemy University", - "alt-eth-blocks": "Hình minh họa các khối được sắp xếp thành một biểu tượng ETH" -} \ No newline at end of file diff --git a/src/intl/vi/page-developers-local-environment.json b/src/intl/vi/page-developers-local-environment.json deleted file mode 100644 index 105f7ac7c58..00000000000 --- a/src/intl/vi/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "Khung thử nghiệm và phát triển dựa trên Python cho các hợp đồng thông minh nhắm mục tiêu đến máy ảo Ethereum.", - "page-local-environment-brownie-logo-alt": "Logo của Brownie", - "page-local-environment-kurtosis-desc": "Một bộ công cụ dựa vào vùng chứa để dễ cấu hình và tạo ra một mạng thử nghiệm nhiều ứng dụng khách của Ethereum, để triển khai ứng dụng phi tập trung cục bộ nhanh, tạo nguyên mẫu và thử nghiệm.", - "page-local-environment-kurtosis-logo-alt": "Logo của Kurtosis", - "page-local-environment-epirus-desc": "Nền tảng phát triển, triển khai và giám sát các ứng dụng chuỗi khối trên Máy ảo Java.", - "page-local-environment-epirus-logo-alt": "Logo của Epirus", - "page-local-environment-eth-app-desc": "Tạo ứng dụng được hỗ trợ bởi Ethereum chỉ với một lệnh duy nhất. Đi kèm với nhiều lựa chọn về khung giao diện người dùng (UI) và các mẫu nền tài chính phi tập trung (DeFi).", - "page-local-environment-eth-app-logo-alt": "Tạo logo của ứng dụng Eth", - "page-local-environment-foundry-desc": "Bộ công cụ nhanh, di động và mô-đun hóa để phát triển ứng dụng Ethereum được viết bằng Rust.", - "page-local-environment-foundry-logo-alt": "Logo của Foundry", - "page-local-environment-framework-feature-1": "Các tính năng để tạo ra một phiên bản blockchain cục bộ.", - "page-local-environment-framework-feature-2": "Các tiện ích để biên dịch và kiểm tra hợp đồng thông minh của bạn.", - "page-local-environment-framework-feature-3": "Tiện ích bổ sung để phát triển ứng dụng khách cho phép bạn xây dựng ứng dụng hướng tới người dùng trong cùng một dự án/kho lưu trữ.", - "page-local-environment-framework-feature-4": "Cấu hình để kết nối với mạng Ethereum và triển khai hợp đồng, cho dù với một phiên bản đang chạy cục bộ hay một trong các mạng công cộng của Ethereum.", - "page-local-environment-framework-feature-5": "Phân phối ứng dụng phi tập trung - tích hợp với các tùy chọn lưu trữ như IPFS (hệ thống tập tin phân tán mạng ngang hàng).", - "page-local-environment-framework-features": "Những framework này bao gồm nhiều chức năng có sẵn như:", - "page-local-environment-frameworks-desc": "Chúng tôi khuyên bạn nên lựa chọn một khung, đặc biệt nếu bạn mới bắt đầu. Việc phát triển một ứng dụng phi tập trung (dapp) chính thức đòi hỏi nhiều thành phần công nghệ khác nhau. Khung bao gồm nhiều tính năng cần thiết hoặc cung cấp các hệ thống plugin đơn giản để lựa chọn các công cụ mong muốn.", - "page-local-environment-frameworks-title": "Khung và stack tạo sẵn", - "page-local-environment-hardhat-desc": "Hardhat là một môi trường phát triển Ethereum chuyên nghiệp.", - "page-local-environment-hardhat-logo-alt": "Logo của Hardhat", - "page-local-environment-openZeppelin-desc": "Sử dụng CLI (giao diện dòng lệnh) của chúng tôi để biên dịch, nâng cấp, triển khai và tương tác với hợp đồng thông minh sẽ giúp bạn tiết kiệm hàng giờ phát triển.", - "page-local-environment-openZeppelin-logo-alt": "Logo của OpenZeppelin", - "page-local-environment-scaffold-eth-desc": "Ethers + Hardhat + React: mọi thứ bạn cần để bắt đầu xây dựng các ứng dụng phi tập trung dựa trên hợp đồng thông minh.", - "page-local-environment-scaffold-eth-logo-alt": "Logo của scaffold-eth", - "page-local-environment-setup-meta-desc": "Hướng dẫn về cách chọn stack phần mềm thích hợp để phát triển Ethereum.", - "page-local-environment-setup-meta-title": "Thiết lập để phát triển cục bộ Ethereum", - "page-local-environment-setup-subtitle": "Nếu bạn đã sẵn sàng để bắt đầu xây dựng, thì đây là lúc để chọn ngăn xếp của mình.", - "page-local-environment-setup-subtitle-2": "Dưới đây là các công cụ và khung mà bạn có thể sử dụng để xây dựng ứng dụng Ethereum.", - "page-local-environment-setup-title": "Thiết lập môi trường phát triển cục bộ của bạn", - "page-local-environment-solidity-template-desc": "Mẫu GitHub cho cấu hình hợp đồng thông minh Solidity được tạo sẵn. Chứa mạng cục bộ Hardhat, Waffle để thử nghiệm, Ethers để triển khai ví và các thành phần khác.", - "page-local-environment-solidity-template-logo-alt": "Logo của mẫu Solidity" -} \ No newline at end of file diff --git a/src/intl/zh-tw/page-developers-learning-tools.json b/src/intl/zh-tw/page-developers-learning-tools.json deleted file mode 100644 index ef8ae060dcd..00000000000 --- a/src/intl/zh-tw/page-developers-learning-tools.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "在 BloomTech Web3 課程中,將會教導你雇主想要從工程師身上看到的技能。", - "page-learning-tools-bloomtech-logo-alt": "BloomTech 標誌", - "page-learning-tools-bootcamps": "開發者訓練營", - "page-learning-tools-bootcamps-desc": "線上付費課程幫助你快速上手。", - "page-learning-tools-browse-docs": "瀏覽文件", - "page-learning-tools-capture-the-ether-description": "「捕捉以太」這個遊戲可以讓你破解以太坊智慧型合約,藉此學習安全議題。", - "page-learning-tools-capture-the-ether-logo-alt": "捕捉以太標誌", - "page-learning-tools-node-guardians-description": "Node Guardians 是一個遊戲化的教育平台,讓 Web3 開發者透過奇幻主題任務沉浸其中,以掌握 Solidity、Cairo、Noir 和 Huff 的程式設計。", - "page-learning-tools-node-guardians-logo-alt": "Node Guardians 標誌", - "page-learning-tools-coding": "透過編寫程式學習", - "page-learning-tools-coding-subtitle": "如果你偏好互動性高的學習體驗,這些工具會幫助你試用以太坊功能。", - "page-learning-tools-consensys-academy-description": "線上以太坊開發者訓練營。", - "page-learning-tools-consensys-academy-logo-alt": "ConsenSys Academy 標誌", - "page-learning-tools-cryptozombies-description": "學習 Solidity,打造自己的殭屍遊戲。", - "page-learning-tools-cryptozombies-logo-alt": "CryptoZombies 標誌", - "page-learning-tools-dapp-world-description": "包括課程、測驗、實作練習和每週競賽的區塊鏈技能提升生態系統。", - "page-learning-tools-dapp-world-logo-alt": "Dapp World 標誌", - "page-learning-tools-documentation": "閱讀文件學習", - "page-learning-tools-documentation-desc": "想了解更多嗎?請前往我們的文件,尋找需要的解釋。", - "page-learning-tools-eth-dot-build-description": "一個教育性的 Web3 沙箱,包括拖放式的程式設計和開源的建構區塊。", - "page-learning-tools-eth-dot-build-logo-alt": "Eth.build 標誌", - "page-learning-tools-ethernauts-description": "破解智慧型合約,完成關卡。", - "page-learning-tools-ethernauts-logo-alt": "Ethernauts 標誌", - "page-learning-tools-metaschool-description": "透過建置並送出去中心化應用程式成為 Web3 開發者。", - "page-learning-tools-metaschool-logo-alt": "_metaschool 標誌", - "page-learning-tools-game-tutorials": "互動式遊戲教學", - "page-learning-tools-game-tutorials-desc": "邊玩邊學。這些教學在遊戲中解釋基礎知識。", - "page-learning-tools-meta-desc": "網頁版程式設計工具和互動式學習經驗讓你試驗以太坊的開發環境。", - "page-learning-tools-meta-title": "開發者學習工具", - "page-learning-tools-atlas-logo-alt": "Atlas 標誌", - "page-learning-tools-atlas-description": "使用 Atlas 整合開發環境在幾分鐘內編寫、測試和部署智慧型合約。", - "page-learning-tools-questbook-description": "以自己的步調進行,透過建構了解 Web3.0 的教學", - "page-learning-tools-questbook-logo-alt": "Questbook 標誌", - "page-learning-tools-remix-description": "開發、部屬及管理以太坊智慧型合約,可按照 Learneth 插件的使用教學操作。", - "page-learning-tools-remix-description-2": "Remix、Replit、ChainIDE 和 Atlas 不僅僅是沙箱 — 開發者可以使用它們編寫、編譯和部署智慧型合約。", - "page-learning-tools-replit-description": "一個可以自訂的以太坊開發環境,具備即時重新載入、錯誤檢查及絕佳的測試網支援。", - "page-learning-tools-chainIDE-description": "透過 ChainIDE 編寫以太坊智慧型合約,開始你的 Web3 旅程。利用內建模板學習可以節省時間。", - "page-learning-tools-chainIDE-logo-alt": "ChainIDE 標誌", - "page-learning-tools-tenderly-description": "Tenderly Sandbox 是一個原型設計的環境,你可在瀏覽器中使用 Solidity 及 JavaScript 編寫、執行智慧型合約,並為其除錯。", - "page-learning-tools-tenderly-logo-alt": "Tenderly 標誌", - "page-learning-tools-replit-logo-alt": "Replit 標誌", - "page-learning-tools-remix-logo-alt": "Remix 標誌", - "page-learning-tools-sandbox": "程式碼沙箱", - "page-learning-tools-sandbox-desc": "這些沙箱給你編寫智慧型合約及學習以太坊的空間。", - "page-learning-tools-speed-run-ethereum-description": "「加速執行以太坊」是一系列使用 Scaffold-ETH 來測試 Solidity 知識的挑戰。", - "page-learning-tools-speed-run-ethereum-logo-alt": "「加速執行以太坊」標誌", - "page-learning-tools-studio-description": "一個網路整合開發環境讓你跟從教學指示,打造及測試智慧型合約,並為其建立前端。", - "page-learning-tools-vyperfun-description": "學習使用 Vyper 打造你自己的 Pokémon 遊戲。", - "page-learning-tools-vyperfun-logo-alt": "Vyper.fun 標誌", - "page-learning-tools-nftschool-description": "從技術層面探索非同質性代幣的進展。", - "page-learning-tools-nftschool-logo-alt": "非同質性代幣學校標誌", - "page-learning-tools-platzi-description": "學習如何在 Web3 建立去中心化應用程式並精通所有成為區塊鏈開發者所需的技能。", - "page-learning-tools-platzi-logo-alt": "Platzi 標誌", - "page-learning-tools-alchemy-university-description": "透過課程、專案、和程式碼發展你的 Web3 職涯。", - "page-learning-tools-alchemy-university-logo-alt": "Alchemy 大學標誌", - "page-learning-tools-learnweb3-description": "LearbWeb3 是一個免費、高質量的教育平台,助益從零開始學習 Web3 開發。", - "page-learning-tools-learnweb3-logo-alt": "LearnWeb3 標誌", - "page-learning-tools-cyfrin-updraft-description": "學習適合所有技能水平和安全審核的智慧型合約開發。", - "page-learning-tools-cyfrin-updraft-logo-alt": "Cyfrin Updraft 標誌", - "alt-eth-blocks": "插圖:由積木組成的以太幣符號" -} diff --git a/src/intl/zh-tw/page-developers-local-environment.json b/src/intl/zh-tw/page-developers-local-environment.json deleted file mode 100644 index c6d9ca2c0bf..00000000000 --- a/src/intl/zh-tw/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "在以太坊虛擬機上,以 Python 為基礎架構的智慧型合約開發、測試架構。", - "page-local-environment-brownie-logo-alt": "Brownie 標誌", - "page-local-environment-kurtosis-desc": "基於容器的工具包,可輕鬆設定與運行多用戶端以太坊測試網,快速進行本地端去中心化應用程式開發、原型設計及測試。", - "page-local-environment-kurtosis-logo-alt": "Kurtosis 標誌", - "page-local-environment-epirus-desc": "於 Java 虛擬機開發、部署及監測區塊鏈應用程式的平台。", - "page-local-environment-epirus-logo-alt": "Epirus 標誌", - "page-local-environment-eth-app-desc": "使用單一命令建立以太坊為基礎的應用程式,附帶多種使用者介面架構及去中心化金融模板任你選擇。", - "page-local-environment-eth-app-logo-alt": "Create Eth App 標誌", - "page-local-environment-foundry-desc": "一個用 Rust 編寫的用於以太坊應用程序開發的快速、可移植和模組化的工具包。", - "page-local-environment-foundry-logo-alt": "Foundry 標誌", - "page-local-environment-framework-feature-1": "運行本機區塊鏈實例功能。", - "page-local-environment-framework-feature-2": "編譯和測試智慧型合約工具。", - "page-local-environment-framework-feature-3": "用戶端開發附加組件可以在相同計畫/存放庫建立你的使用者導向應用程式。", - "page-local-environment-framework-feature-4": "連結到以太坊網路並部署合約的配置,不管是本機運行實例,或是在其中一個以太坊的公共網路。", - "page-local-environment-framework-feature-5": "去中心化應用程式分布 -- 整合如星際檔案系統等儲存選項。", - "page-local-environment-framework-features": "這些架構具備多種立即可用的功能,例如:", - "page-local-environment-frameworks-desc": "我們推薦先選擇架構,特別如果你是初學者。建造完整去中心化應用程式需要多種技術。架構包括許多必備功能,或提供簡易外掛程式系統以選擇你想要的工具。", - "page-local-environment-frameworks-title": "架構及預先完成的堆疊", - "page-local-environment-hardhat-desc": "Hardhat 是專業人士使用的以太坊開發環境。", - "page-local-environment-hardhat-logo-alt": "Hardhat 標誌", - "page-local-environment-openZeppelin-desc": "透過編輯、升級、部署及與智慧型合約互動,使用我們的命令列介面來節省許多開發時間。", - "page-local-environment-openZeppelin-logo-alt": "OpenZeppelin 標誌", - "page-local-environment-scaffold-eth-desc": "Ethers + Hardhat + React:開始建立智慧型合約驅動的去中心化應用程式所需的一切。", - "page-local-environment-scaffold-eth-logo-alt": "scaffold-eth 標誌", - "page-local-environment-setup-meta-desc": "以太坊開發軟體堆疊選擇指南。", - "page-local-environment-setup-meta-title": "以太坊本機開發設定", - "page-local-environment-setup-subtitle": "如果你想開始著手打造,請先選擇你的堆疊。", - "page-local-environment-setup-subtitle-2": "你可以使用這些工具及架構幫助開發以太坊應用程式。", - "page-local-environment-setup-title": "設定你的本機開發環境", - "page-local-environment-solidity-template-desc": "預先設置的 Solidity 智慧型合約 GitHub 模板。包括 Hardhat 本機網路、Waffle 測試、Ethers 錢包實作以及更多。", - "page-local-environment-solidity-template-logo-alt": "Solidity 模板標誌" -} \ No newline at end of file diff --git a/src/intl/zh/page-developers-learning-tools.json b/src/intl/zh/page-developers-learning-tools.json deleted file mode 100644 index d5b458b650f..00000000000 --- a/src/intl/zh/page-developers-learning-tools.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "page-learning-tools-bloomtech-description": "BloomTech Web3 课程将向你传授符合雇佣要求的工程师技能。", - "page-learning-tools-bloomtech-logo-alt": "BloomTech 标识", - "page-learning-tools-bootcamps": "开发者训练营", - "page-learning-tools-bootcamps-desc": "付费在线课程,让你快速了解最新动态", - "page-learning-tools-browse-docs": "浏览文档", - "page-learning-tools-capture-the-ether-description": "Capture the Ether 是一款在破解智能合约的过程中学习其安全性的游戏。", - "page-learning-tools-capture-the-ether-logo-alt": "Capture the Ether 徽标", - "page-learning-tools-node-guardians-description": "Node Guardians 是一个游戏化教育平台,以沉浸式的奇幻主题探索助力 Web3 开发者掌握 Solidity、Cairo、Noir 和 Huff 编程。", - "page-learning-tools-node-guardians-logo-alt": "Node Guardians 徽标", - "page-learning-tools-coding": "通过编码来学习", - "page-learning-tools-coding-subtitle": "如果你更喜欢在互动中学习,这些工具会帮你实践理解以太坊。", - "page-learning-tools-consensys-academy-description": "线上以太坊开发者训练营。", - "page-learning-tools-consensys-academy-logo-alt": "ConsenSys Academy徽标", - "page-learning-tools-cryptozombies-description": "学习Solidity,开发你自己的僵尸游戏。", - "page-learning-tools-cryptozombies-logo-alt": "CryptoZombies徽标", - "page-learning-tools-dapp-world-description": "一个提升区块链技能的生态系统,包含了课程、测验、实践操作和每周竞赛。", - "page-learning-tools-dapp-world-logo-alt": "Dapp World 徽标", - "page-learning-tools-documentation": "通过文档学习", - "page-learning-tools-documentation-desc": "想了解更多?请查阅我们的文档,找到你需要的解释。", - "page-learning-tools-eth-dot-build-description": "一个web3的教育沙箱,包括拖放编程和开源构建块。", - "page-learning-tools-eth-dot-build-logo-alt": "Eth.build徽标", - "page-learning-tools-ethernauts-description": "通过破解智能合约来闯关。", - "page-learning-tools-ethernauts-logo-alt": "Ethernauts徽标", - "page-learning-tools-metaschool-description": "通过构建和发布去中心化应用程序成为 Web3 开发者。", - "page-learning-tools-metaschool-logo-alt": "_metschool 标志", - "page-learning-tools-game-tutorials": "游戏式的互动教程", - "page-learning-tools-game-tutorials-desc": "边玩边学。这些教程会让你通过玩游戏来了解基本知识。", - "page-learning-tools-meta-desc": "基于网络的编码工具和交互式学习体验,帮助你体验以太坊的开发。", - "page-learning-tools-meta-title": "开发者学习工具", - "page-learning-tools-atlas-logo-alt": "Atlas 徽标", - "page-learning-tools-atlas-description": "使用 Atlas IDE 在几分钟内编写、测试并部署智能合约。", - "page-learning-tools-questbook-description": "构建以下内容,通过自定义进度的教程来学习 Web 3.0", - "page-learning-tools-questbook-logo-alt": "Questbook 徽标", - "page-learning-tools-remix-description": "开发、部署和管理以太坊智能合约。安装 LearnEth 插件,参考其中的教程。", - "page-learning-tools-remix-description-2": "Remix、Replit、ChainIDE 和 Atlas 不仅仅是沙盒环境 — 开发者还能够使用这些工具来编写、编译和部署智能合约。", - "page-learning-tools-replit-description": "一个可定制的以太坊开发环境,具有热重载、错误检查和一流的测试网支持。", - "page-learning-tools-chainIDE-description": "借助 ChainIDE 为以太坊编写智能合约,开始你的 Web3 之旅。使用内置模板学习并节省时间。", - "page-learning-tools-chainIDE-logo-alt": "ChainIDE 徽标", - "page-learning-tools-tenderly-description": "Tenderly Sandbox 是一个原型构建环境,让你可以使用 Solidity 和 JavaScript 在浏览器中编写、执行并调试智能合约。", - "page-learning-tools-tenderly-logo-alt": "Tenderly 标志", - "page-learning-tools-replit-logo-alt": "Replit 徽标", - "page-learning-tools-remix-logo-alt": "Remix徽标", - "page-learning-tools-sandbox": "代码沙箱", - "page-learning-tools-sandbox-desc": "代码沙箱提供你一个尝试写智能合约和理解以太坊的空间。", - "page-learning-tools-speed-run-ethereum-description": "Speed Run Ethereum 提供一系列挑战,通过使用 Scaffold-ETH 测试你的 Solidity 知识", - "page-learning-tools-speed-run-ethereum-logo-alt": "Speed Run 以太坊徽标", - "page-learning-tools-studio-description": "一个基于网络的集成开发环境,你可以在这里关注教程来创建和测试智能合约,并为它们建立一个前端。", - "page-learning-tools-vyperfun-description": "通过学习 Vyper 来构建你自己的 Pokémon 游戏。", - "page-learning-tools-vyperfun-logo-alt": "Vyper.fun徽标", - "page-learning-tools-nftschool-description": "从技术层面探索非同质化代币(NFT)的进展。", - "page-learning-tools-nftschool-logo-alt": "NFT school 徽标", - "page-learning-tools-platzi-description": "了解如何在 Web3 上构建去中心化应用程序,掌握成为区块链开发者所需的所有技能。", - "page-learning-tools-platzi-logo-alt": "Platzi 徽标", - "page-learning-tools-alchemy-university-description": "学习课程、项目和代码,发展你的 Web3 职业生涯。", - "page-learning-tools-alchemy-university-logo-alt": "Alchemy University 徽标", - "page-learning-tools-learnweb3-description": "LearnWeb3 是一个免费优质教育平台,帮助你在 Web3 开发领域从零起步走向精通。", - "page-learning-tools-learnweb3-logo-alt": "LearnWeb3 徽标", - "page-learning-tools-cyfrin-updraft-description": "学习所有技能水平的智能合约开发和安全审计。", - "page-learning-tools-cyfrin-updraft-logo-alt": "Cyfrin Updraft 徽标", - "alt-eth-blocks": "积木被搭建成以太坊符号的图示" -} diff --git a/src/intl/zh/page-developers-local-environment.json b/src/intl/zh/page-developers-local-environment.json deleted file mode 100644 index d4aa44cdeca..00000000000 --- a/src/intl/zh/page-developers-local-environment.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "page-local-environment-brownie-desc": "基于Python的智能合约开发和测试框架,针对以太坊虚拟机为目标。", - "page-local-environment-brownie-logo-alt": "Brownie徽标", - "page-local-environment-kurtosis-desc": "这是一个基于容器的工具包,用于轻松配置和启动多客户端以太坊测试网,以便快速进行本地去中心化应用程序(dApp)的开发、原型构建和测试。", - "page-local-environment-kurtosis-logo-alt": "Kurtosis 标志", - "page-local-environment-epirus-desc": "用于在 Java 虚拟机上开发、部署和监测区块链应用的平台。", - "page-local-environment-epirus-logo-alt": "Epirus徽标", - "page-local-environment-eth-app-desc": "使用一个命令创建由以太坊提供支持的应用。使用广泛的UI框架和DeFi模板来选择。", - "page-local-environment-eth-app-logo-alt": "创建以太币应用徽标", - "page-local-environment-foundry-desc": "一个用 Rust 编写的用于以太坊应用开发的工具包,具有速度快、可移植和模块化的特点。", - "page-local-environment-foundry-logo-alt": "Foundry 徽标", - "page-local-environment-framework-feature-1": "编写一个本地区块链程序的功能。", - "page-local-environment-framework-feature-2": "编译和测试智能合约的工具。", - "page-local-environment-framework-feature-3": "客户端开发附加组件,以在同一项目/仓库中构建你的面向用户的应用。", - "page-local-environment-framework-feature-4": "无论是在本地运行的实例,还是在以太坊的公共网络之一,可以连接到以太网并且部署合约的配置。", - "page-local-environment-framework-feature-5": "去中心化的应用分发 - 与诸如 IPFS 之类的存储选项集成。", - "page-local-environment-framework-features": "这些框架带有许多开箱即用功能,比如:", - "page-local-environment-frameworks-desc": "我们建议选择一个框架,特别是如果你刚刚开始使用。建立一个完整的去中心化应用程序需要不同的技术。框架包括许多所需的功能或提供简单的插件系统来选择你想要的工具。", - "page-local-environment-frameworks-title": "框架和预先制作的堆栈", - "page-local-environment-hardhat-desc": "“安全帽”是针对专业人员的以太坊开发环境。", - "page-local-environment-hardhat-logo-alt": "安全帽徽标", - "page-local-environment-openZeppelin-desc": "通过编译、升级、部署和与我们的CLI智能合同互动来节省开发时间。", - "page-local-environment-openZeppelin-logo-alt": "OpenZeppelin 徽标", - "page-local-environment-scaffold-eth-desc": "ETH + Hardhat + React:这些是开始构建由智能合约驱动的去中心化应用程序所需的一切。", - "page-local-environment-scaffold-eth-logo-alt": "scaffold-eth徽标", - "page-local-environment-setup-meta-desc": "关于如何选择你的软件堆栈用于以太坊开发的指南。", - "page-local-environment-setup-meta-title": "以太坊本地开发设置", - "page-local-environment-setup-subtitle": "如果你准备好开始建造,就选择你的堆栈。", - "page-local-environment-setup-subtitle-2": "这里是你可以用来帮助你构建你的以太坊应用的工具和框架。", - "page-local-environment-setup-title": "设置你的本地开发环境", - "page-local-environment-solidity-template-desc": "GitHub模板,用于为您的Solidity智能合约预先构建设置。包括Hardhat本地网络、Ethers钱包实现等。", - "page-local-environment-solidity-template-logo-alt": "Solidity template徽标" -} diff --git a/src/lib/interfaces.ts b/src/lib/interfaces.ts index a908816c7cb..9a86796368c 100644 --- a/src/lib/interfaces.ts +++ b/src/lib/interfaces.ts @@ -109,20 +109,6 @@ export interface MdPageContent { contributors: FileContributor[] } -// Local environment framework -export interface Framework { - id: string - url: string - githubUrl: string - background: string - name: string - description: string - alt: string - image: StaticImageData - starCount?: number - languages?: string[] -} - /** * Community events */ From 9ada785b1eadb2f8fef34bfe98b50d88ae8cfa2e Mon Sep 17 00:00:00 2001 From: wackerow <54227730+wackerow@users.noreply.github.com> Date: Thu, 22 Jan 2026 09:10:55 -0800 Subject: [PATCH 46/74] patch: use original cardbanner height --- app/[locale]/developers/apps/_components/HighlightsSection.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/[locale]/developers/apps/_components/HighlightsSection.tsx b/app/[locale]/developers/apps/_components/HighlightsSection.tsx index 0b3f10bb308..9b833366211 100644 --- a/app/[locale]/developers/apps/_components/HighlightsSection.tsx +++ b/app/[locale]/developers/apps/_components/HighlightsSection.tsx @@ -52,7 +52,7 @@ const HighlightsSection = async ({ apps }: { apps: DeveloperApp[] }) => { className="space-y-6 no-underline" >
- + Date: Thu, 22 Jan 2026 15:13:36 -0800 Subject: [PATCH 47/74] patch: reorder dev nav links --- src/components/Footer.tsx | 8 ++++---- src/lib/nav/buildNavigation.ts | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index b40db225b46..8ce279a3e08 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -164,14 +164,14 @@ const Footer = ({ lastDeployLocaleTimestamp }: FooterProps) => { href: "/developers/docs/", text: t("documentation"), }, - { - href: "/developers/apps/education/", - text: t("learn-ethereum-development"), - }, { href: "/developers/apps/", text: t("start-building"), }, + { + href: "/developers/apps/education/", + text: t("learn-ethereum-development"), + }, { href: "/community/grants/", text: t("grants"), diff --git a/src/lib/nav/buildNavigation.ts b/src/lib/nav/buildNavigation.ts index 93e214f3bc5..8cd41a418d9 100644 --- a/src/lib/nav/buildNavigation.ts +++ b/src/lib/nav/buildNavigation.ts @@ -309,16 +309,16 @@ export const buildNavigation = (t: TranslateFn): NavSections => { label: t("get-started"), description: t("nav-start-get-started-description"), items: [ - { - label: t("learn-ethereum-development"), - description: t("nav-learn-ethereum-development-description"), - href: "/developers/apps/education/", - }, { label: t("start-building"), description: t("nav-start-building-description"), href: "/developers/apps/", }, + { + label: t("learn-ethereum-development"), + description: t("nav-learn-ethereum-development-description"), + href: "/developers/apps/education/", + }, { label: t("tutorials"), description: t("nav-tutorials-description"), From 6c73782c078d3239ecd1326369ac8baa57ef9ade Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Thu, 22 Jan 2026 21:09:50 -0800 Subject: [PATCH 48/74] chore: remove todos, custom events --- app/[locale]/developers/apps/[category]/page.tsx | 8 +------- app/[locale]/developers/apps/page.tsx | 13 ------------- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/app/[locale]/developers/apps/[category]/page.tsx b/app/[locale]/developers/apps/[category]/page.tsx index 0456d95a6c4..4dd8f8a2510 100644 --- a/app/[locale]/developers/apps/[category]/page.tsx +++ b/app/[locale]/developers/apps/[category]/page.tsx @@ -124,7 +124,7 @@ const Page = async ({ slug: `/developers/apps/${t(`page-developers-apps-category-${category}-breadcrumb`)}`, }} title={t(`page-developers-apps-category-${category}-title`)} - description={t(`page-developers-apps-category-${category}-description`)} // TODO: Confirm + description={t(`page-developers-apps-category-${category}-description`)} className="border-none pb-0" /> @@ -196,12 +196,6 @@ const Page = async ({ )} icon={} href={`/developers/apps/${slug}`} - matomoEvent={{ - // TODO: Confirm all - eventCategory: "developer-apps", - eventAction: "categories", - eventName: `category name ${slug}`, - }} /> ) )} diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/apps/page.tsx index 53034993506..65bd9846f75 100644 --- a/app/[locale]/developers/apps/page.tsx +++ b/app/[locale]/developers/apps/page.tsx @@ -96,18 +96,11 @@ const Page = async ({ asChild className="ms-6 w-[calc(100%-4rem)] max-w-md md:min-w-96 md:flex-1 lg:max-w-[33%]" > - {/* // TODO: */}
@@ -181,12 +174,6 @@ const Page = async ({ )} icon={} href={`/developers/apps/${slug}`} - matomoEvent={{ - // TODO: Confirm all - eventCategory: "developer-apps", - eventAction: "categories", - eventName: `category name ${slug}`, - }} /> ))}
From 05389a6d05ad39e61c25f45539fed3cd612dd07e Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Thu, 22 Jan 2026 21:10:07 -0800 Subject: [PATCH 49/74] chore: trim mock data --- .../mocks/fetch-developer-tools.json | 5865 ++--------------- 1 file changed, 612 insertions(+), 5253 deletions(-) diff --git a/src/data-layer/mocks/fetch-developer-tools.json b/src/data-layer/mocks/fetch-developer-tools.json index f650faa78da..dca8fdaaa5a 100644 --- a/src/data-layer/mocks/fetch-developer-tools.json +++ b/src/data-layer/mocks/fetch-developer-tools.json @@ -1,481 +1,355 @@ [ { - "id": "0xc4f4309de505d2581218e6a4f9634e37d546c8f2bc51242540ca1486b965c0f2", - "name": "evm-mcp-server by mcpdotdirect", - "description": "we built an evm mcp server that allows agents to interact with a multitude of chains", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/9d83fea6-88b8-4985-b0e9-4a675be218df.png", - "banner_url": "https://storage.googleapis.com/op-atlas/763ce438-66da-4384-a634-9108e26a63a4.png", - "twitter": null, + "id": "0x939241afa4c4b9e1dda6b8250baa8f04fa8b0debce738cfd324c0b18f9926d25", + "name": "OpenZeppelin Contracts", + "description": "OpenZeppelin Contracts are the go-to library for smart contract development.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/83bab036-91bd-4b9d-a524-dbea2024aa3f.png", + "banner_url": "https://storage.googleapis.com/op-atlas/489f54b5-2035-4a94-82f5-8b41e6cbb857.png", + "twitter": "https://x.com/openzeppelin", "tags": [ - "mcp-server", - "cli", - "transaction-management" + "cross-chain", + "governance", + "erc721", + "upgradeable-contracts", + "modular-accounts", + "interactive-tools", + "merkle-trees" ], - "website": "https://mcp.direct", + "website": "https://www.openzeppelin.com/", "category": "Smart Contract Development & Toolchains", "repos": [ { - "href": "https://github.com/mcpdotdirect/evm-mcp-server", - "stargazers": 357, - "lastUpdated": "2025-11-26T17:09:21Z" + "href": "https://github.com/OpenZeppelin/openzeppelin-upgrades", + "stargazers": 648, + "lastUpdated": "2025-11-03T20:09:20Z" + }, + { + "href": "https://github.com/OpenZeppelin/openzeppelin-subgraphs", + "stargazers": 146, + "lastUpdated": "2025-02-25T15:09:17Z" + }, + { + "href": "https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades", + "stargazers": 244, + "lastUpdated": "2025-06-30T19:16:05Z" + }, + { + "href": "https://github.com/OpenZeppelin/merkle-tree", + "stargazers": 519, + "lastUpdated": "2025-02-25T02:12:49Z" + }, + { + "href": "https://github.com/openzeppelin/openzeppelin-community-contracts", + "stargazers": 80, + "lastUpdated": "2026-01-13T18:10:27Z" + }, + { + "href": "https://github.com/OpenZeppelin/openzeppelin-contracts", + "stargazers": 26929, + "lastUpdated": "2026-01-15T16:08:39Z" + }, + { + "href": "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable", + "stargazers": 1149, + "lastUpdated": "2026-01-15T16:10:26Z" + }, + { + "href": "https://github.com/OpenZeppelin/contracts-wizard", + "stargazers": 294, + "lastUpdated": "2026-01-16T15:24:19Z" } ] }, { - "id": "0x2b77364f9d227b9b41ed84281857dcf016685e73ba909071a1b93135a4a0b7d9", - "name": "libethc", - "description": "libethc is an open-source ethereum library for C/C++", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/c0c216e0-29b0-4330-9b4f-9addc53c56d3.png", - "banner_url": null, - "twitter": null, + "id": "0xcc8d03e014e121d10602eeff729b755d5dc6a317df0d6302c8a9d3b5424aaba8", + "name": "Solidity", + "description": "Solidity is an object-oriented, high-level language for implementing smart contracts.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/b6f312d0-1025-4a19-baa9-3aa218fe0833.png", + "banner_url": "https://storage.googleapis.com/op-atlas/bca65077-a87b-4fd8-bcc3-9ad0a65d9d27.png", + "twitter": "https://x.com/solidity_lang", "tags": [ - "transaction-signing", - "abi-encoding" + "education", + "solidity", + "compiler", + "cli" ], - "website": "https://mhw0.github.io/libethc/", - "category": "Client Libraries & SDKs (Front-End)", + "website": "https://soliditylang.org/", + "category": "Smart Contract Development & Toolchains", "repos": [ { - "href": "https://github.com/mhw0/libethc", - "stargazers": 70, - "lastUpdated": "2025-09-20T03:40:37Z" + "href": "https://github.com/ethereum/solidity", + "stargazers": 25502, + "lastUpdated": "2026-01-19T23:37:55Z" + }, + { + "href": "https://github.com/ethereum/solc-js", + "stargazers": 1503, + "lastUpdated": "2025-12-18T20:41:21Z" } ] }, { - "id": "0xd7a4742a0a40480ce176892bb619295d2cdd357d7ad09411beaff6278014c191", - "name": "evmstate", - "description": "A TypeScript library for tracing, and visualizing EVM state changes with detailed human-readable labeling.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/8eb6f205-cdaf-4ca2-8f9c-228183d42ede.png", + "id": "0x5200a7351f8d195401dc04631fb83e4836f73a2794f316b2739c03807f30a78b", + "name": "Brownie", + "description": "A Python-based development and testing framework for smart contracts targeting the Ethereum Virtual Machine. ", + "thumbnail_url": null, "banner_url": null, "twitter": null, "tags": [ - "analytics", - "storage-layout" + "cli", + "debugging-tools" ], - "category": "Client Libraries & SDKs (Front-End)", + "website": "https://github.com/eth-brownie/brownie", + "category": "Smart Contract Development & Toolchains", "repos": [ { - "href": "https://github.com/polareth/evmstate", - "stargazers": 25, - "lastUpdated": "2025-07-24T21:40:21Z" + "href": "https://github.com/eth-brownie/brownie", + "stargazers": 2729, + "lastUpdated": "2026-01-14T06:57:54Z" } ] }, { - "id": "0x926606219b6876c28d7185401763b7492decd48a7e89a2fd27de9dbf176507ad", - "name": "etherml", - "description": "A command-line Ethereum wallet manager written in Go 1.24.3+ that generates secure private keys, derives addresses, and stores them in quantum-resistant encrypted files with a Terminal User Interface (TUI) for browsing and management.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/9bcf0bba-0978-47ab-b553-c58778a00775.png", - "banner_url": "https://storage.googleapis.com/op-atlas/8605a173-9360-4914-a1ac-41ac54c076c7.png", + "id": "0x4a5e771af86cf1938056b43cddbf0018dca1376d578f631f7449fe10ac4958ed", + "name": "Nethereum", + "description": "Nethereum is the .Net integration library for Ethereum, simplifying the access and smart contract interaction with Ethereum nodes both public like Geth (or your preferred client) L2 chains like Optimism, Arbitrum (or your preferred L2), any compatible EVM chain (Gnosis, etc) and permissioned chains like Quorum.", + "thumbnail_url": null, + "banner_url": null, "twitter": null, "tags": [ - "cli", + "cross-chain", "wallet", - "security", - "encryption" + "json-rpc", + "transaction-signing", + "abi-encoding" ], - "website": "https://github.com/ngmisl/etherml", - "category": "Transaction & Wallet Infrastructure", + "category": "Smart Contract Development & Toolchains", "repos": [ { - "href": "https://github.com/ngmisl/etherml", - "stargazers": 6, - "lastUpdated": "2025-09-08T19:15:27Z" + "href": "https://github.com/Nethereum/Nethereum", + "stargazers": 2245, + "lastUpdated": "2026-01-11T11:50:23Z" } ] }, { - "id": "0x2d90d9565ef127727845637425880545cfebe0931160ce25afe929f8ab415706", - "name": "Tevm", - "description": "Tevm creates ambitous app layer tooling for developers to create great experiences for end users", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/f049eb6e-e7f5-4730-b0a2-e02a57ae2707.png", - "banner_url": "https://storage.googleapis.com/op-atlas/e0686fc6-7ee1-4543-b0fc-1285320b9462.png", - "twitter": "https://x.com/tevmtools", + "id": "manually-added:intellij-solidity", + "name": "IntelliJ Solidity", + "description": "Solidity plugin for IntelliJ", + "website": "https://intellij-solidity.dev/", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, "tags": [ - "frontend", - "user-experience" + "solidity", + "developer-experience", + "code-quality" ], - "website": "https://node.tevm.sh", - "category": "Client Libraries & SDKs (Front-End)", + "category": "Smart Contract Development & Toolchains", "repos": [ { - "href": "https://github.com/evmts/tevm-monorepo", - "stargazers": 429, - "lastUpdated": "2026-01-13T12:05:58Z" + "href": "https://github.com/intellij-solidity/intellij-solidity", + "stargazers": 1097, + "lastUpdated": "2026-01-19T22:20:07Z" } ] }, { - "id": "0x9dc9d9b8f79644cbe8634b022d4dd5ecaf4e438a71fe26256598f6e0d85a33a0", - "name": "Superbeam", - "description": "SuperBeam is an open-source typescript SDK on top of Superchain ecosystem. Superbeam is a single api you would ever need to transact across superchain. \n\nSuperBeam enables developers to interact with superchain interop enabled chains and protocols with less friction and without worrying about asset fragmentation across chains. It includes features like - Aggregated Balance, Asset Sweeping, Contract interactions and much more", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/17f44321-04a1-49d8-8702-1c154fa6c560.png", - "banner_url": "https://storage.googleapis.com/op-atlas/a4f2569e-59a0-4265-8976-6e61beacde96.png", + "id": "0x819775803938d78eaa95809971ce94cae6a54b4df58505fa36153ffa1d55e12c", + "name": "Vscode Solidity Extension", + "description": "Solidity support for Visual Studio code\nVersion Downloads Installs Rating\n\nSolidity is the language used in Ethereum to create smart contracts, this extension provides:\n\nSyntax highlighting\nSnippets\nCompilation of the current contract (Press F1 Solidity : Compile Current Solidity Contract), or F5\nCompilation of all the contracts (Press F1 Solidity : Compile all Solidity Contracts), or Ctrl + F5 or Cmd + F5\nCode completion for all contracts / libraries in the current file and all referenced imports\nGoto definition\nFind all references in project\nHover information\nCode actions / quick fixes (change compiler, format address, add sdpx license.. )\nMono repo support (identifies the project by finding the files: remappings.txt, foundry.toml, brownie-config.yaml, truffle-config.js, hardhat.config.js, hardhat.config.ts)\nDefault project structure (solidity files needs to be in the src/ directory, and libraries in the lib/ directory). Libraries will follow the same structure.\nCompilation supporting EIP82 (dappfile and dependency packages)\nSupport for different solidity versions (Remote and local)\nDownload source code and Abi from Etherscan\nCode generation using Nethereum, it includes currently the default template for Nethereum service, dtos generation. (Open 'contractName.json' after compilation from the bin folder. Press F1 and press Solidity: Code generate from compilation output..) Auto generation of Nethereum files on compilation\nLinting using Solhint or Ethlint\nIt is also available as a standalone LSP", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/006b0fd3-9e23-4192-98d6-08e561da809e.png", + "banner_url": null, "twitter": null, "tags": [ - "cross-chain", - "sdk" + "education", + "solidity" ], - "website": "https://superbeam.gitbook.io/superbeam", - "category": "Client Libraries & SDKs (Front-End)", + "category": "Smart Contract Development & Toolchains", "repos": [ { - "href": "https://github.com/KENILSHAHH/superSDK", - "stargazers": 0, - "lastUpdated": "2025-07-10T10:31:15Z" + "href": "https://github.com/juanfranblanco/vscode-solidity", + "stargazers": 959, + "lastUpdated": "2025-11-04T17:05:55Z" } ] }, { - "id": "0x6f8f610667400044907494c879b717e806a03bf519dcfd786edc7f2fa61d6db8", - "name": "OpenRPC", - "description": "OpenRPC is an Apache-licensed, open standard for describing JSON-RPC APIs, analogous to how OpenAPI/Swagger works for REST APIs. Our project provides a comprehensive, free-to-use toolkit that enables developers to generate clear, machine-readable specifications. This drastically simplifies the development, testing, validation, and documentation workflow for anyone building on or interacting with Ethereum and L2 client APIs.\n\nFor over six years, OpenRPC has been a foundational tool in the ecosystem. It has been instrumental for leading projects—including the Ethereum Foundation (for execution-apis), MetaMask, Chainlink, Filecoin, Celestia, and Starknet—in publishing well-defined and accessible API specifications.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/6e5db839-6c5b-4b51-902f-5dc45afd7ea9.png", - "banner_url": "https://storage.googleapis.com/op-atlas/6d09c3cd-91ff-4035-a736-7fcd9e68f98c.png", - "twitter": "https://x.com/open_rpc", + "id": "0x7f330267969cf845a983a9d4e7b7dbcca5c700a5191269af377836d109e0bb69", + "name": "IPFS", + "description": "IPFS (InterPlanetary File System) is a peer-to-peer protocol designed to make the web faster, more open, and more resilient. By using content-addressed storage rather than location-based references, IPFS removes the need for centralized servers and allows files to be distributed and retrieved from multiple nodes around the world. This approach lowers hosting costs, improves data availability, and reduces censorship, laying the groundwork for a more secure and permanent global information network.\n\nIPFS is used in a variety of applications. While some users interact with IPFS via imported libraries in their projects, a large amount of usage comes via IPFS' HTTP Gateway API which allows users to self-host, use extensions like IPFS companion, or publicly run gateways (whether paid ones run by companies like Filebase, Pinata, etc. or the public goods services at ipfs.io and dweb.link).\n\nIPFS is a system for moving data across decentralized networks, with >11M weekly users and 250K public p2p nodes. Highlights:\n\n1. Off-chain storage. IPFS provides verifiable, off-chain storage, often used to reduce on-chain needs in Ethereum & Optimism. Examples: TrueBlocks (local IPFS-based index for EVM chains, built with grants from OP & EF), Snapshot (IPFS-based off-chain voting).\n\n2. Go-to distribution network for fully decentralized third-party app frontends (for gaming, DeFi, & more). We run gateway services that serve 900M requests/wk, and added native IPFS support to browsers like Chromium & Brave.\n\n3. NFT metadata gold standard. Over 115M NFTs are stored on IPFS, including leading platforms OpenSea (which supports Optimism NFTs), Rarible, and Zora.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/fca3aa6c-bdd5-4632-ae64-37b886d50a65.png", + "banner_url": "https://storage.googleapis.com/op-atlas/35658254-c8b6-4562-9690-db91f187a7ff.png", + "twitter": "https://x.com/ipshipyard", "tags": [ - "json-rpc", + "peer-to-peer", + "censorship-resistant", "cli" ], - "website": "https://open-rpc.org", "category": "Client Libraries & SDKs (Front-End)", "repos": [ { - "href": "https://github.com/open-rpc/server-js", - "stargazers": 52, - "lastUpdated": "2025-07-31T03:28:04Z" - }, - { - "href": "https://github.com/open-rpc/tools", - "stargazers": 7, - "lastUpdated": "2025-07-11T21:58:28Z" - }, - { - "href": "https://github.com/open-rpc/generator", - "stargazers": 95, - "lastUpdated": "2025-10-22T05:54:12Z" + "href": "https://github.com/ipfs/service-worker-gateway", + "stargazers": 79, + "lastUpdated": "2026-01-20T15:43:06Z" }, { - "href": "https://github.com/open-rpc/client-js", - "stargazers": 137, - "lastUpdated": "2025-10-29T16:58:20Z" + "href": "https://github.com/ipfs/helia", + "stargazers": 1275, + "lastUpdated": "2026-01-16T09:45:08Z" }, { - "href": "https://github.com/open-rpc/schema-utils-js", - "stargazers": 27, - "lastUpdated": "2025-07-25T23:22:18Z" + "href": "https://github.com/ipfs/kubo", + "stargazers": 16881, + "lastUpdated": "2026-01-16T01:27:32Z" }, { - "href": "https://github.com/open-rpc/spec", - "stargazers": 192, - "lastUpdated": "2025-07-25T23:13:13Z" + "href": "https://github.com/ipfs/boxo", + "stargazers": 277, + "lastUpdated": "2026-01-20T18:22:51Z" }, { - "href": "https://github.com/open-rpc/meta-schema", - "stargazers": 34, - "lastUpdated": "2025-07-31T03:21:56Z" - } - ] - }, - { - "id": "0x66818708d041152b7f9b45ee48e56ab6507ad493955fd256b62d7c9d8a27724f", - "name": "Bloctopus", - "description": "https://x.com/0xbloctopusBloctopus is building open-source dev tooling using Kurtosis that can spin up any web3 infrastructure on-demand. Through various kurtosis packages, we already support many blockchains, cross-chain protocols, oracles, wallet infra, and indexers. ", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/15cb5d1e-c868-43ac-8d7e-db4ef3fbc0f9.png", - "banner_url": "https://storage.googleapis.com/op-atlas/99fa13be-c8ef-4df9-980e-58736e3ddc29.png", - "twitter": "https://x.com/0xbloctopus", - "tags": [ - "cross-chain", - "docker" - ], - "website": "https://www.bloctopus.io", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/0xBloctopus/lzero-reth", - "stargazers": 3, - "lastUpdated": "2025-09-11T15:20:34Z" + "href": "https://github.com/ipfs/js-kubo-rpc-client", + "stargazers": 50, + "lastUpdated": "2025-10-15T07:29:36Z" }, { - "href": "https://github.com/0xBloctopus/ethereum-package", - "stargazers": 8, - "lastUpdated": "2025-09-26T17:25:09Z" + "href": "https://github.com/ipfs/protons", + "stargazers": 37, + "lastUpdated": "2025-06-25T08:34:59Z" }, { - "href": "https://github.com/0xBloctopus/blockscout-package", - "stargazers": 5, - "lastUpdated": "2025-09-11T15:19:00Z" + "href": "https://github.com/ipfs/js-ipns", + "stargazers": 89, + "lastUpdated": "2025-10-14T10:05:10Z" }, { - "href": "https://github.com/0xBloctopus/chainlink-node-package", + "href": "https://github.com/ipfs/helia-delegated-routing-v1-http-api", "stargazers": 4, - "lastUpdated": "2025-09-11T15:15:39Z" + "lastUpdated": "2026-01-16T14:05:02Z" }, { - "href": "https://github.com/0xBloctopus/layerzero-package", - "stargazers": 7, - "lastUpdated": "2025-09-11T15:17:36Z" + "href": "https://github.com/ipfs/js-stores", + "stargazers": 37, + "lastUpdated": "2026-01-08T14:46:02Z" } ] }, { - "id": "0x56ce7cbc27852a8d8ef5869dc9033a215c8893f799468f61527dacb9f92be790", - "name": "alloy", - "description": "Alloy is a set of libraries that provides types and RPC client implementations for ethereum and optimism.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/60d98a8f-6f96-4a29-a65c-50dfc3a7828b.png", - "banner_url": "https://storage.googleapis.com/op-atlas/40039eb5-bcc3-4af4-a975-7022d660164f.png", - "twitter": null, + "id": "0xa3d07f453f70d844196d89d79848aa2e70a0bd8b38bf0f493cba1547bb3bca5e", + "name": "Ethers.js", + "description": "Ethers.js is a simple, compact and complete JavaScript (via TypeScript) library for interacting with Ethereum and related blockchains.\n\nIt is currently used in a very large number of Blockchain projects, including everything from block explorers to wallets (like MetaMask) and is downloaded over 7.1 million times per month (as of this writing). It is also one of the top 500 projects (by dependants) on NPM.\n\nIt was written and is maintained by me, RicMoo (Richard Moore), a random developer from Canada that is passionate about open-source and dedicates most his waking-time (and some sleeping-time) to it.\n\nHack the Planet! :)", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/f8d776ab-ca70-42ee-9e41-d4f709cd6fd4.png", + "banner_url": "https://storage.googleapis.com/op-atlas/459bdd5e-60a5-49ca-88b8-d4537ebfec16.png", + "twitter": "@ricmoo", "tags": [ - "json-rpc" + "frontend", + "json-rpc", + "contract-interaction" ], - "website": "https://alloy.rs/", + "website": "https://ethers.org", "category": "Client Libraries & SDKs (Front-End)", "repos": [ { - "href": "https://github.com/alloy-rs/op-alloy", - "stargazers": 83, - "lastUpdated": "2025-12-10T15:50:18Z" - }, - { - "href": "https://github.com/alloy-rs/alloy", - "stargazers": 1201, - "lastUpdated": "2026-01-20T19:36:17Z" + "href": "https://github.com/ethers-io/ethers.js", + "stargazers": 8626, + "lastUpdated": "2025-12-03T00:49:47Z" } ] }, { - "id": "0xeef42373d10554d65aba9e6deb8333a4eddebba829e0afea0dc93e32d8075d2d", - "name": "ERCx: Token Test Library", - "description": "Runtime Verification is a leading formal verification company specializing in blockchain security and smart contract correctness. We've developed ERCx, the most comprehensive open-source testing library for ERC token standards, featuring over 500 individual tests across ERC-20, ERC-721, ERC-1155, and ERC-4626 implementations.\nERCx directly empowers Superchain builders by providing production-ready test suites that verify both standard compliance and security properties. Our library offers zero-configuration testing for deployed contracts via Foundry fork testing, plus simple integration for pre-deployment source code validation. With three testing tiers: Standard (EIP compliance), Security (vulnerability detection), and Features (implementation validation), developers can ship token contracts with confidence, knowing they've been thoroughly vetted against real-world attack vectors and edge cases.\nWhat makes ERCx particularly valuable for the Optimism ecosystem is its cross-chain compatibility and handling of complex deployment scenarios. The library seamlessly works across OP Stack chains and handles storage complexities that often challenge developers working with established tokens like USDC or stETH. By providing this critical testing infrastructure as open-source tooling, we're enabling safer, more reliable token implementations across the entire Superchain, directly supporting the ecosystem's growth while reducing the security risks that have historically plagued token contracts in DeFi.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/e6a6dd9b-4ace-4187-8408-0e5729bb0265.png", - "banner_url": "https://storage.googleapis.com/op-atlas/eee0738d-3735-42c8-8802-93b22a041803.png", - "twitter": "x.com/rv_inc", + "id": "manually-added:orbitdb", + "name": "OrbitDB", + "description": "Peer-to-Peer Databases for the Decentralized Web", + "website": null, + "thumbnail_url": null, + "banner_url": null, + "twitter": null, "tags": [ - "foundry", - "security", - "erc721", - "runtime-verification" + "peer-to-peer", + "censorship-resistant" ], - "website": "ercx.runtimeverification.com", - "category": "Security, Testing & Formal Verification", + "category": "Client Libraries & SDKs (Front-End)", "repos": [ { - "href": "https://github.com/runtimeverification/ercx-tests", - "stargazers": 35, - "lastUpdated": "2025-07-04T12:23:27Z" + "href": "https://github.com/orbitdb/orbitdb", + "stargazers": 8720, + "lastUpdated": "2025-08-05T01:58:51Z" } ] }, { - "id": "0x738c0967c0f70a0a78d8794dcf2c40540f60ea9568e163dd5826b85e8e2a9a79", - "name": "Enso Build", - "description": "Enso is blockchain shortcuts. Your fastest way to build and launch onchain.\nBy mapping all onchain interactions to a shared engine, Enso lets you focus on your product.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/ba508a79-4a21-45fc-b3e3-5ede1a80fb6b.png", - "banner_url": "https://storage.googleapis.com/op-atlas/96e7fcd9-75e3-4e40-98c5-0c5ae56c6578.png", - "twitter": "https://x.com/ensobuild", + "id": "0x62d9a8a3b602c688610abfbe3965e04ca0d19c5c506f40e79cd185cb501d2018", + "name": "noble cryptography", + "description": "noble cryptography is a high-security, easily auditable set of contained cryptographic libraries with following features:\n\n- Zero or minimal dependencies\n- Highly readable TypeScript / JS code\n- PGP-signed releases and transparent NPM builds\n\nnoble cryptography is used in most modern JS wallets, including Metamask, Rabby, Rainbow, various SDKs, and others. Essentially it empowers a huge share of ecosystem.", + "thumbnail_url": null, + "banner_url": null, + "twitter": "https://x.com/paulmillr", "tags": [ - "cross-chain", - "transaction-optimization" + "wallet", + "security", + "encryption" ], - "website": "enso.build", - "category": "Smart Contract Development & Toolchains", + "website": "https://paulmillr.com/noble/", + "category": "Client Libraries & SDKs (Front-End)", "repos": [ { - "href": "https://github.com/EnsoBuild/Uniswap-migrator", - "stargazers": 0, - "lastUpdated": "2025-10-20T13:19:17Z" + "href": "https://github.com/paulmillr/noble-curves", + "stargazers": 876, + "lastUpdated": "2026-01-13T01:04:35Z" }, { - "href": "https://github.com/EnsoBuild/shortcuts-client-contracts", - "stargazers": 1, - "lastUpdated": "2026-01-20T09:52:23Z" - }, - { - "href": "https://github.com/EnsoBuild/sdk-ts", - "stargazers": 2, - "lastUpdated": "2025-12-02T08:08:28Z" + "href": "https://github.com/paulmillr/noble-hashes", + "stargazers": 802, + "lastUpdated": "2026-01-13T01:31:07Z" }, { - "href": "https://github.com/EnsoBuild/shortcuts-widget", - "stargazers": 6, - "lastUpdated": "2025-11-27T13:13:20Z" + "href": "https://github.com/paulmillr/noble-ciphers", + "stargazers": 358, + "lastUpdated": "2026-01-13T01:07:07Z" } ] }, { - "id": "0x414ffb06789667ba95546e05e0456445145d3de23b05b3a8ce051cbc142bfb3f", - "name": "React Native Passkeys", - "description": "React Native Passkeys is a TypeScript library that provides a unified API for creating and authenticating with passkeys across Web, Android, and iOS.\n\nThe API mirrors the WebAuthn standard, making it easier for React Native developers to leverage existing documentation, tools, and backend infrastructure, abstracting away platform-specific complexities. \n\nWith over 250k downloads it is utilised by teams like Privy, Coinbase, Safe, ZeroDev, Ephemera, OneKey & more.", + "id": "manually-added:ethereum-rb", + "name": "ethereum.rb", + "description": "Ethereum library for the Ruby language", + "website": null, "thumbnail_url": null, "banner_url": null, "twitter": null, "tags": [ - "authentication" + "sdk" ], "category": "Client Libraries & SDKs (Front-End)", "repos": [ { - "href": "https://github.com/peterferguson/react-native-passkeys", - "stargazers": 135, - "lastUpdated": "2025-11-04T09:57:14Z" - } - ] - }, - { - "id": "0x696c9b46af5eeaa2fcfa86f23da23ed1ce7938df67d90d422e6ba7ee2604b512", - "name": "Ethernaut CLI", - "description": "A universal Ethereum swiss army knife with an AI duck taped onto it.\n\nA CLI for non-technical users, trying to bridge the gap between graphical UIs and CLIs.\n\nA framework for rapid tool building; integrate a new tool in a matter of hours.\n\nAn extensible framework composed of hardhat plugins.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/1fdf287a-8ec4-4e15-a81d-1e63b902662b.png", - "banner_url": "https://storage.googleapis.com/op-atlas/5b622e91-2107-4d63-87b7-9aeb42d55d86.png", - "twitter": null, - "tags": [ - "cli", - "hardhat", - "natural-language-processing", - "developer-experience" - ], - "website": "https://ethernaut-app.vercel.app/", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/ethernautdao/ethernaut-cli", - "stargazers": 37, - "lastUpdated": "2025-05-26T16:51:40Z" - } - ] - }, - { - "id": "0x5200a7351f8d195401dc04631fb83e4836f73a2794f316b2739c03807f30a78b", - "name": "Brownie", - "description": "A Python-based development and testing framework for smart contracts targeting the Ethereum Virtual Machine. ", - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [ - "cli", - "debugging-tools" - ], - "website": "https://github.com/eth-brownie/brownie", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/eth-brownie/brownie", - "stargazers": 2729, - "lastUpdated": "2026-01-14T06:57:54Z" - } - ] - }, - { - "id": "0xc850d11fe786d1168bfeda108721101427dd5425d9d9e6595c35573f7616e940", - "name": "Daimo Pay", - "description": "Daimo Pay lets users interact with your app using any token on any chain - no bridging, no swapping, no friction.\nIntegrate our SDK in 15 minutes to accept deposits or execute transactions in your app with any token, from any chain, using any wallet or exchange.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/b2bd0510-b0d6-436e-a126-de05026e9418.png", - "banner_url": "https://storage.googleapis.com/op-atlas/dde6090a-600a-418b-be38-5ea73111c407.png", - "twitter": "https://x.com/daimopay", - "tags": [ - "cross-chain" - ], - "website": "https://pay.daimo.com/", - "category": "Cross-Chain & Interoperability", - "repos": [ - { - "href": "https://github.com/daimo-eth/pay", - "stargazers": 18, - "lastUpdated": "2026-01-20T05:09:55Z" - } - ] - }, - { - "id": "0xf9c5d092fac6ad924253d685cc7ba21d4e519813e673a3a8300f33cb3a6b4e06", - "name": "NFTScan", - "description": "NFTScan is a professional NFT Explorer tool that provides developers and users with NFT data search services for the Superchain ecosystem, including: OP Mainnet, Base, Mint blockchain and other blockchain networks.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/30fb3451-049c-4904-a109-d3c06004a731.png", - "banner_url": "https://storage.googleapis.com/op-atlas/09a998c5-5217-4937-b2c8-d994e5cfe1c7.png", - "twitter": "https://x.com/nftscan_com", - "tags": [ - "erc721" - ], - "website": "https://www.nftscan.com/", - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/nftscan-official/nftscan-api-js-sdk", - "stargazers": 18, - "lastUpdated": "2025-06-13T06:21:00Z" - } - ] - }, - { - "id": "0x8af71ece7f50d6962b589b19854ceac72b81e5f5b3014637b262c33809d5a395", - "name": "K Semantics of the Ethereum Virtual Machine (EVM)", - "description": "We are Runtime Verification, a research and development company building rigorous tools to ensure the safety and correctness of critical systems. Our team has developed KEVM, the most complete and battle-tested formal semantics of the Ethereum Virtual Machine (EVM), written in the K Framework.\n\nKEVM is not just a specification, it is an executable specification that can be used to symbolically reason about smart contracts, run conformance tests, analyze gas usage, debug programs, and formally verify correctness properties. It passes the full Ethereum test suite and is used to verify high-value contracts, including ERC20 tokens in both Solidity and Vyper. We recently updated the semantics to support Pectra upgrade.\n\nKEVM is being actively utilized by Kontrol - our formal verification tool for Soldiity, which is actively used by leading teams in the EVM ecosystem, including Optimism, Ethereum Foundation, Lido, Uniswap, as well as security researchers and auditors across the broader Ethereum community.\n\nWe actively maintain this repository, contribute to Ethereum’s protocol evolution, and integrate with developer tooling like Foundry. Through KEVM, we are pushing the boundaries of what’s possible in provably correct and secure smart contract infrastructure.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/aab1bec1-5b08-4727-a5c2-f8d0dfbe0ed9.png", - "banner_url": "https://storage.googleapis.com/op-atlas/0204f6f1-2d6a-443b-bd9e-afb88c23f2e3.png", - "twitter": "https://x.com/rv_inc", - "tags": [ - "security", - "education", - "analytics", - "formal-verification", - "symbolic-execution", - "debugging-tools", - "runtime-verification", - "vyper" - ], - "category": "Security, Testing & Formal Verification", - "repos": [ - { - "href": "https://github.com/runtimeverification/evm-semantics", - "stargazers": 554, - "lastUpdated": "2025-12-16T17:45:27Z" + "href": "https://github.com/EthWorks/ethereum.rb", + "stargazers": 732, + "lastUpdated": "2022-05-11T14:28:01Z" } ] }, { - "id": "0x4562c0630907577f433cad78c7e2cc03349d918b6c14ef982f11a2678f5999ad", - "name": "Foundry", - "description": "Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.\n\nIt is a smart contract development toolchain that manages your dependencies, compiles your project, runs tests, deploys, and lets you interact with the chain from the command-line and via Solidity scripts.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/66656b6d-5f9d-46f6-b8f0-67eb23ce9db9.png", - "banner_url": "https://storage.googleapis.com/op-atlas/f22dd5f4-39c2-46d4-b701-85355469df9c.png", + "id": "0x9d93ec97ef2d3bd4c2b8d95abac9ce0cf43e4f3eb1f05709f8282da8200e69ee", + "name": "Frames.js", + "description": "frames.js is the leading open source javascript library and debugging environment to help developers make Frames for Farcaster, XMTP and Lens faster & easier. \n\nWe also have been building and maintaining a library for apps to adopt frames in their apps that has been integrated by the Base team in their Base names product.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/230e8ac2-cea9-4cab-8b4f-8fd58ec6553e.png", + "banner_url": "https://storage.googleapis.com/op-atlas/a2dce749-56d7-44d7-a9cc-ffc08255e0f2.png", "twitter": null, "tags": [ - "cli", - "foundry", - "solidity", - "vyper", - "continuous-integration", - "fuzz-testing", - "performance-optimization" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/foundry-rs/foundry", - "stargazers": 10047, - "lastUpdated": "2026-01-20T17:57:52Z" - } - ] - }, - { - "id": "0x35295108e0c7b4625d650fbdabd4888417782539f56159d39ac2f0e2411f607b", - "name": "Kurtosis", - "description": "Kurtosis is a developer platform purpose-built to streamline the development, testing, and debugging of Web3 and blockchain-based distributed systems. It provides programmable environments that mirror real-world networks, making it easier to build and iterate on decentralized infrastructure. Think docker compose, for blockchain systems.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/6c0103eb-14e1-4578-831b-d5e85c017831.png", - "banner_url": "https://storage.googleapis.com/op-atlas/cec480f1-b828-424a-ae01-9984ebdc2eb5.png", - "twitter": "https://x.com/KurtosisTech", - "tags": [ - "docker", - "cli", - "testing" + "frontend", + "farcaster", + "react", + "nextjs" ], - "website": "https://www.kurtosis.com", - "category": "Smart Contract Development & Toolchains", + "website": "https://www.framesjs.org", + "category": "Client Libraries & SDKs (Front-End)", "repos": [ { - "href": "https://github.com/kurtosis-tech/kurtosis", - "stargazers": 520, - "lastUpdated": "2026-01-14T15:57:47Z" + "href": "https://github.com/framesjs/frames.js", + "stargazers": 382, + "lastUpdated": "2025-03-27T17:07:46Z" } ] }, @@ -504,22 +378,45 @@ ] }, { - "id": "0x1e7a1f9763d25b6844567a7133b1005ef6ed785642a75229acf1b9b25202a5f3", - "name": "eRPC", - "description": "eRPC is a fault-tolerant EVM RPC proxy and permanent caching solution. It is built with read-heavy use-cases in mind such as data indexing and high-load frontend usage. It is designed to lower costs through local caching, enhance reliability during provider outages, and improve visibility into RPC usage across teams and third-party providers.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/bc82b1d5-dad6-496a-af01-475797e53e34.png", - "banner_url": "https://storage.googleapis.com/op-atlas/75c707be-ff55-41d7-9ef0-7cfcdef536ea.png", - "twitter": "https://x.com/erpc", + "id": "0x79e8bf2d699790b563aa57fd34da1722bea3191ab5ff0601ba56020687702ab9", + "name": "Etherspot", + "description": "Etherspot is a multi-chain Account & Chain Abstraction development infrastructure that provides solutions for dApps, wallets, games, operating EVM-compatible rollups, or L1/L2 chains to deliver seamless cross-chain Web3 user experience by removing usability pain points.\n\nIn addition to providing Account and Chain Abstraction features, Etherspot helps developers make their projects compatible with the latest Ethereum standards, including ERC-4337, ERC-7579, and EIP-7702, by offering a wide range of cutting-edge services such as Bundler and Paymaster services, APIs, and more.\n\nEtherspot is pioneering the ERC-4337 shared mempool innovation, which is already live on Optimism.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/b05e1c53-bace-499c-b346-ed9fa0003730.png", + "banner_url": "https://storage.googleapis.com/op-atlas/b33b4fe0-6010-470c-a2db-57636d96536d.png", + "twitter": "https://x.com/etherspot", "tags": [ - "frontend", - "indexing" + "cross-chain", + "wallet", + "defi", + "multi-chain", + "account-abstraction", + "sdk", + "user-experience" ], - "category": "Smart Contract Development & Toolchains", + "website": "https://etherspot.io/", + "category": "Transaction & Wallet Infrastructure", "repos": [ { - "href": "https://github.com/erpc/erpc", - "stargazers": 636, - "lastUpdated": "2026-01-20T16:11:16Z" + "href": "https://github.com/etherspot/etherspot-prime-contracts", + "stargazers": 55, + "lastUpdated": "2025-02-20T21:15:37Z" + }, + { + "href": "https://github.com/etherspot/etherspot-modular-sdk", + "stargazers": 22, + "lastUpdated": "2025-10-23T08:27:57Z" + }, + { + "href": "https://www.npmjs.com/package/skandha" + }, + { + "href": "https://www.npmjs.com/package/@etherspot/prime-sdk", + "downloads": 60 + }, + { + "href": "https://github.com/etherspot/skandha", + "stargazers": 610, + "lastUpdated": "2026-01-20T12:53:03Z" } ] }, @@ -546,127 +443,117 @@ ] }, { - "id": "0xa873dcdcc84e0022edd2f7d5cc8646667b87bf06609d506cd8e39dbd7412fa59", - "name": "Foundry MCP Server", - "description": "A simple, lightweight and fast MCP (Model Context Protocol) server that provides Solidity development capabilities using the Foundry toolchain (Forge, Cast, and Anvil).", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/92c30ad3-b419-4f74-a24c-08bdff63059b.png", + "id": "0x37fe5886f4c77d5a5cb947deff90158c045a5d207572763187748ac4dd4bd9b9", + "name": "ethereum-multicall", + "description": "Ability to call many ethereum constant function calls in 1 JSONRPC request", + "thumbnail_url": null, "banner_url": null, - "twitter": "", + "twitter": null, "tags": [ - "cli", - "foundry", - "mcp-server", - "solidity-development" + "multicall" ], - "category": "Smart Contract Development & Toolchains", + "category": "Transaction & Wallet Infrastructure", "repos": [ { - "href": "https://github.com/PraneshASP/foundry-mcp-server", - "stargazers": 237, - "lastUpdated": "2026-01-17T15:25:55Z" + "href": "https://github.com/joshstevens19/ethereum-multicall", + "stargazers": 381, + "lastUpdated": "2025-12-23T11:07:33Z" } ] }, { - "id": "0xcd032b75396f45f1ef82c8a38142352afa6071fbcd840480408e10e2aab9006d", - "name": "miniapp starters", - "description": "miniapp starters is a set of open-source starter templates designed to make it easier to build Farcaster miniapps, with support for Worldcoin integrations as well.\n\nMiniapp Starters came out of our own journey building miniapps. Along the way, we found ourselves creating common patterns and components repeatedly, so we decided to turn that work into a set of reusable, community-friendly templates. Now, anyone can kickstart their own miniapp projects without reinventing the wheel.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/d5818777-1f8b-40bd-885e-22a892d7f7f7.png", - "banner_url": "https://storage.googleapis.com/op-atlas/e0127983-0358-42cb-95f7-396d8a86346a.png", - "twitter": "https://x.com/builders_garden", + "id": "0x93decae913f62c0a86519d0b0798e4a10c46c541bfc14dcff0193d6b026e9532", + "name": "LlamaPay", + "description": "Automate & stream salaries by the second", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/30c6400b-b572-4d16-8138-4dc1cba0ef06.png", + "banner_url": "https://storage.googleapis.com/op-atlas/2c2733fd-a572-4f4f-809d-def2e14b8776.png", + "twitter": "https://x.com/llamapay_io", "tags": [ - "education", - "farcaster", - "nextjs", - "tailwind-css", - "type-safe", - "analytics" + "defi", + "gas-efficient" ], - "website": "https://www.builders.garden/", - "category": "Education & Community Resources", + "website": "https://llamapay.io/", + "category": "Transaction & Wallet Infrastructure", "repos": [ { - "href": "https://github.com/builders-garden/base-minikit-starter", - "stargazers": 43, - "lastUpdated": "2025-05-25T15:44:54Z" - }, - { - "href": "https://github.com/builders-garden/farcaster-miniapp-starter", - "stargazers": 49, - "lastUpdated": "2025-12-06T15:23:06Z" - }, - { - "href": "https://github.com/builders-garden/frames-v2-starter", - "stargazers": 30, - "lastUpdated": "2025-04-22T13:15:16Z" + "href": "https://github.com/llamasubs/contracts", + "stargazers": 4, + "lastUpdated": "2024-07-21T13:42:50Z" }, { - "href": "https://github.com/builders-garden/miniapp-next-template", - "stargazers": 28, - "lastUpdated": "2025-12-16T15:04:19Z" + "href": "https://github.com/LlamaPay/llamapay", + "stargazers": 187, + "lastUpdated": "2022-06-21T08:10:50Z" } ] }, { - "id": "0xc6cac7cd3793888032cc8a9e5aef92550beeec2598f86f1ec6972ffd5b82a990", - "name": "Prettier Solidity", - "description": "A Prettier plugin for automatically formatting your Solidity code.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/0e3be68b-be6b-4833-b0ed-b53dc89a8d22.png", + "id": "0x4e13be6b98dd868cd13e9f4101431ab03d211f429b63f078fa7da260b54d256a", + "name": "Light Account", + "description": "A set of lightweight, open sourced, audited and gas-optimized ERC-4337 compatible smart contract accounts with designated ownership", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/646cd1db-23b4-4328-8a7c-6c58358a73e1.png", "banner_url": null, - "twitter": "https://x.com/prettiersol", + "twitter": "https://x.com/alchemy", "tags": [ + "wallet", + "account-abstraction", "solidity", - "code-quality" + "foundry" ], - "website": "https://github.com/prettier-solidity/prettier-plugin-solidity", - "category": "Smart Contract Development & Toolchains", + "website": "https://www.alchemy.com/", + "category": "Transaction & Wallet Infrastructure", "repos": [ { - "href": "https://github.com/prettier-solidity/prettier-plugin-solidity", - "stargazers": 748, - "lastUpdated": "2026-01-20T15:24:32Z" + "href": "https://github.com/alchemyplatform/light-account", + "stargazers": 111, + "lastUpdated": "2026-01-07T16:13:59Z" } ] }, { - "id": "0xa790f0641e8d72abc88efd13ca215e2dc7e736a4a59ca5a9e0020af29d6297f2", - "name": "Crytic-Properties", - "description": "Crytic-Properties is a suite of re-usable security tests for some of the most widely used token standards such as ERC20, ERC721, ERC4626, and more.\n", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/eebeffeb-5b4e-4e8f-a8d9-09718da38b40.png", - "banner_url": null, + "id": "0xdc3dce33fd5fb50cf932586d4257456ddf5040ba0955d97641646504c73dbd13", + "name": "Slither", + "description": "Slither is a Solidity and Vyper static analysis framework written in Python3. \n\nIt runs a suite of vulnerability detectors, prints visual information about contract details, and provides an API to easily write custom analyses. Slither enables developers to find vulnerabilities, enhance their code comprehension, and quickly prototype custom analyses.\n\nSlither has been used for many years by both security engineers and developers to secure their smart contracts. \n\nBy allowing developers to find the most common vulnerabilities on their smart contracts, Slither helps to improve the security of the Optimism ecosystem.\n\nSlither has 90+ detectors, and works on both Solidity and Vyper. In addition it provides printers, helping to review quickly features of contracts. It's python API can also be used to leverage its inbuilt analysis for custom needs.\n\nSlither can directly be run on a contract deployed on optimism, with `slither optim:0x..ADDRESS`", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/27ad6768-163c-4cc3-bd3e-ba8fd3ef5f50.png", + "banner_url": "https://storage.googleapis.com/op-atlas/1276f443-c160-4db0-ab75-33e3e01e3a47.png", "twitter": "https://x.com/trailofbits", "tags": [ "security", - "erc721", - "fuzz-testing", - "solidity" + "static-analysis", + "solidity", + "vyper", + "continuous-integration" ], "category": "Security, Testing & Formal Verification", "repos": [ { - "href": "https://github.com/crytic/properties", - "stargazers": 356, - "lastUpdated": "2025-11-29T16:59:34Z" + "href": "https://github.com/crytic/slither", + "stargazers": 6093, + "lastUpdated": "2026-01-20T18:39:50Z" } ] }, { - "id": "0x2a04bac7482169a929fd70444bbfac10654d0588e022db7527566dbfc307d2e9", - "name": "Solc-select", - "description": "Solc-select is a command line utility for quickly installing and switching between Solidity compiler versions.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/de442005-7eb7-45d9-9d69-c1f1548e855f.png", - "banner_url": null, - "twitter": "https://x.com/trailofbits", - "tags": [ - "cli", - "solidity" - ], - "category": "Smart Contract Development & Toolchains", + "id": "0x2bb095e1f297c71da8bd4ee15097abad3b99e299fe14cd6aa704df3f36d0ae22", + "name": "solidity-coverage", + "description": "solidity-coverage provides smart-contract code coverage for the Hardhat developer platform. It's highly accurate, supports full viaIR solidity compilation and a large set of solidity-specific code branch patterns. It's installed on ~230k Github projects and is downloaded ~100k times a week from NPM.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/bd692393-7f1a-4b91-9887-73f7c3250233.png", + "banner_url": "https://storage.googleapis.com/op-atlas/dcbdf6ac-f898-4dac-b9d0-087b8d289f4b.png", + "twitter": null, + "tags": [ + "hardhat", + "analytics", + "code-coverage", + "solidity", + "test-automation" + ], + "website": "https://github.com/sc-forks/solidity-coverage", + "category": "Security, Testing & Formal Verification", "repos": [ { - "href": "https://github.com/crytic/solc-select", - "stargazers": 803, - "lastUpdated": "2026-01-15T18:30:50Z" + "href": "https://github.com/sc-forks/solidity-coverage", + "stargazers": 1005, + "lastUpdated": "2025-12-11T04:00:44Z" } ] }, @@ -693,4481 +580,149 @@ ] }, { - "id": "0xdc3dce33fd5fb50cf932586d4257456ddf5040ba0955d97641646504c73dbd13", - "name": "Slither", - "description": "Slither is a Solidity and Vyper static analysis framework written in Python3. \n\nIt runs a suite of vulnerability detectors, prints visual information about contract details, and provides an API to easily write custom analyses. Slither enables developers to find vulnerabilities, enhance their code comprehension, and quickly prototype custom analyses.\n\nSlither has been used for many years by both security engineers and developers to secure their smart contracts. \n\nBy allowing developers to find the most common vulnerabilities on their smart contracts, Slither helps to improve the security of the Optimism ecosystem.\n\nSlither has 90+ detectors, and works on both Solidity and Vyper. In addition it provides printers, helping to review quickly features of contracts. It's python API can also be used to leverage its inbuilt analysis for custom needs.\n\nSlither can directly be run on a contract deployed on optimism, with `slither optim:0x..ADDRESS`", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/27ad6768-163c-4cc3-bd3e-ba8fd3ef5f50.png", - "banner_url": "https://storage.googleapis.com/op-atlas/1276f443-c160-4db0-ab75-33e3e01e3a47.png", - "twitter": "https://x.com/trailofbits", - "tags": [ - "security", - "static-analysis", - "solidity", - "vyper", - "continuous-integration" - ], - "category": "Security, Testing & Formal Verification", - "repos": [ - { - "href": "https://github.com/crytic/slither", - "stargazers": 6093, - "lastUpdated": "2026-01-20T18:39:50Z" - } - ] - }, - { - "id": "0x7cbd306b4b54416b83eb723a79b88d09554e245b1d7b29e7e4b7958ca1011d1f", - "name": "ethdebug", - "description": "Debugging deployed smart contracts today relies on guesswork. No EVM-language compiler emits enough structured debug data. As a result, debuggers must reverse-engineer arcane details of high-level language internals—a brittle, inaccurate, and hard-to-maintain process. This slows development, impedes audits, and obscures contract behavior.\n\nThe ethdebug format is a proposed standard for debugging metadata. It’s language-agnostic, tool-friendly, and designed to map EVM execution back to source locations, control flow, data structures, and developer intent. The goal is to enable reliable debugging of deployed contracts—without requiring compiler internals or custom builds.\n\nThe format is still in development. Implementations are currently underway in solc and in multiple existing debuggers. The focus is on interoperability, minimal overhead, and incremental adoption.\n\nethdebug is part of the Argot Collective, a new organization spinning out from the Ethereum Foundation. Argot's other projects include Act, hevm, Fe, Sourcify, and Solidity.\n\nThis work directly supports Optimism’s mission to fund shared public infrastructure. A common debugging standard makes smart contracts easier to understand, audit, and build on—across chains, languages, and tools.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/3ac79cce-16e1-4a59-9557-ee1f85793674.png", - "banner_url": "https://storage.googleapis.com/op-atlas/616a8719-4bc1-4e7d-b50e-d56e45019f0b.png", - "twitter": "https://twitter.com/ethdebug", - "tags": [ - "education", - "debugging-tools", - "type-safe" - ], - "website": "https://ethdebug.github.io/format/", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/ethdebug/format", - "stargazers": 76, - "lastUpdated": "2026-01-15T21:27:42Z" - } - ] - }, - { - "id": "0xcdeb1723ae43478e77b36f2b6dea33f9485963a66ca951408faad33e13452e10", - "name": "WakeUp Labs | Rollup-as-a-Service for the OP Stack", - "description": "We are WakeUp Labs, a software development company focused on building open-source infrastructure for the Ethereum ecosystem and the Superchain. Our team has been working closely with the OP Stack to deliver a fully open and modular Rollup-as-a-Service (RaaS) solution.\n\nOur RaaS tooling simplifies the deployment, management, and customization of rollups on Optimism. It includes a CLI, a web console, and deployment pipelines designed to empower developers and protocols to launch their own rollups quickly and securely—without needing to manage DevOps or low-level infra.\n\nWe believe the future of Ethereum scalability lies in modular rollups, and we're building the tools to make that future accessible to everyone. Our tools are already being used by projects and contributors in the Optimism ecosystem to explore new rollup use cases and accelerate Superchain adoption.\n\nWe’re committed to pushing forward the decentralization and usability of rollup infrastructure—aligned with Optimism’s values and mission.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/4756e689-18df-4d2f-aea1-abdf6547ee51.png", - "banner_url": "https://storage.googleapis.com/op-atlas/7ad77d50-64a1-43a4-a494-e49db0974dde.png", - "twitter": "https://x.com/wakeuplabs", - "tags": [ - "cli", - "scalability" - ], - "website": "https://www.wakeuplabs.io/", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/wakeuplabs-io/op-ruaas", - "stargazers": 6, - "lastUpdated": "2025-05-20T14:59:52Z" - } - ] - }, - { - "id": "0x77a0eb2debb3ddd73bb629ae482d24771ef1b59029d28a04e13570c9e9644c44", - "name": "Stereum L2 Optimism Integration", - "description": "Stereum is dedicated to advancing Ethereum through open-source and open development. Our commitment lies in reducing technical barriers, supporting decentralization, and enhancing security within the Ethereum(EVM) ecosystem.\nWe integrated Optimism as an Integration into our Node Setup and Maintenance Gui based tool. Everybody is now able to spin up an Optimism node connected to a Ethereum node within minutes. Enabling low infratech people to access multilayer architectures completly by themselves, decentralized, 100% free, 100% untracked, 100% auto updated. \nAfter everytthing is synced you now are able to access \n1)your own RPC endpoint \n2)your onw data api \n3) your own websockets \nboth Ethereum and Opitimism. \nAs we would love to integrate further Optimistic rollups into our software we would be honoured and feel apreaciated if you would grant us a grant ", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/47b18b46-5440-406c-8e07-bfcf27f8aa6e.png", - "banner_url": "https://storage.googleapis.com/op-atlas/a80d7697-6c6f-4f71-bfc1-7576b933dad4.png", - "twitter": "https://x.com/stereumdev", - "tags": [ - "cli", - "docker", - "api", - "privacy-focused" - ], - "website": "https://stereum.com", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/stereum-dev/ethereum-node", - "stargazers": 154, - "lastUpdated": "2026-01-20T12:36:08Z" - } - ] - }, - { - "id": "0x363b77a4022f98f4d529b8a771d22f49b1092293980aab154fff63980bd1b2bf", - "name": "viem-tracer", - "description": "Debug transactions via traces by automatically decoding them with the help of openchain.xyz!\n\n- Automatically append traces to error messages of failed eth_estimateGas and eth_sendTransaction RPC requests.\n- Add support for debug_traceCall to a Viem client with correct types!", + "id": "manually-added:hax", + "name": "hax", + "description": "hax is a tool for high assurance translations of a large subset of Rust into formal languages such as F* or Rocq.", + "website": "https://hax.cryspen.com/", "thumbnail_url": null, "banner_url": null, "twitter": null, "tags": [ - "cli", - "debugging-tools" + "formal-verification" ], - "website": "https://github.com/Rubilmax/viem-tracer", - "category": "Smart Contract Development & Toolchains", + "category": "Security, Testing & Formal Verification", "repos": [ { - "href": "https://github.com/Rubilmax/viem-tracer", - "stargazers": 25, - "lastUpdated": "2025-11-13T13:14:02Z" + "href": "https://github.com/cryspen/hax", + "stargazers": 362, + "lastUpdated": "2026-01-19T15:13:10Z" } ] }, { - "id": "0xfbecd6308658b3d40a5249d4b249d10537165f57ea528cc796aef5ce1eb1f0d8", - "name": "executooor", - "description": "Ethereum's environment evolves fast. So fast that you can't keep up writing and deploying a new contract everytime you want to do something atomically onchain (not mentioning you also have to approve this freshly deployed contract to spend your favorite ERC20/ERC721!).\n\nWelcome the Executor contract:\n\nCalculate whatever you need to submit your execution\nChain calls / delegatecalls as needed to execute whatever you want to execute atomically onchain (using viem and/or ethers-v6!)\nOptionally prepend any ERC20/ERC721 approval via a third-party bundling service (such as Flashbots)\nSubmit your execution transaction (or bundle)\nFor MEV out there: tip the bundler\nYou can even atomically populate your chain of calls if it depends on some state change! For example, you can skim ERC20 tokens after an execution by simply requesting the balance left onchain and replacing it in the onchain call.", - "thumbnail_url": null, + "id": "0xa790f0641e8d72abc88efd13ca215e2dc7e736a4a59ca5a9e0020af29d6297f2", + "name": "Crytic-Properties", + "description": "Crytic-Properties is a suite of re-usable security tests for some of the most widely used token standards such as ERC20, ERC721, ERC4626, and more.\n", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/eebeffeb-5b4e-4e8f-a8d9-09718da38b40.png", "banner_url": null, - "twitter": null, + "twitter": "https://x.com/trailofbits", "tags": [ - "defi", + "security", "erc721", - "contract-deployment", - "transaction-optimization" - ], - "website": "https://github.com/Rubilmax/executooor", - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/Rubilmax/executooor", - "stargazers": 98, - "lastUpdated": "2025-04-10T15:44:56Z" - } - ] - }, - { - "id": "0x5999c3a9311c71fd2e02078c406d417565a3d04efe52570ba294be75a5befac8", - "name": "opup", - "description": "[`opup`](https://github.com/zhiqiangxu/opup) is a one-stop installation tool for OP Stack. It has been used to deploy multiple L2 networks for Quarkchain, with the latest being available at: [Quarkchain Explorer](https://explorer.beta.testnet.l2.quarkchain.io/) .", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/43a31c8a-308e-4956-a4f4-ba61a1280c7b.png", - "banner_url": null, - "twitter": "https://x.com/EthStorage", - "tags": [ - "cli", - "docker", - "contract-management" - ], - "website": "https://ethstorage.io/", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/zhiqiangxu/opup", - "stargazers": 0, - "lastUpdated": "2025-11-13T10:10:55Z" - } - ] - }, - { - "id": "0x5c0234455c4b86b05ed0c612ac0d7e53cd2249686305af9b2184190b781b8063", - "name": "Surl", - "description": "HTTP Library for Solidity based on curl ", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/9379802f-3bc8-4e72-a0ad-f4a267ef4d42.png", - "banner_url": null, - "twitter": null, - "tags": [ - "solidity", - "foundry" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/memester-xyz/surl", - "stargazers": 332, - "lastUpdated": "2025-04-05T17:06:36Z" - } - ] - }, - { - "id": "0xf4f7d13f2ac3c9805998d8540950883b872d7c5d7c81d6254dde8655af690b2a", - "name": "evmc", - "description": "a simple cli tool to load a contract code up in your IDE instantly.", - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [ - "cli", - "support", - "contract-verification" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/joshstevens19/evmc", - "stargazers": 134, - "lastUpdated": "2025-04-05T14:41:12Z" - } - ] - }, - { - "id": "0xe01f00da2ba1f43dd0dd1e2b93bbfc5a84021ded7e6d414e86fa12a8d4eeb347", - "name": "simple-uniswap-sdk", - "description": "Uniswap SDK which handles the routes automatically for you, changes in trade quotes reactive subscriptions, exposure to formatted easy to understand information, bringing back the best trade quotes automatically, generating transactions for you and much more.", - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [ - "defi", - "sdk", - "multicall", - "user-experience" - ], - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/joshstevens19/simple-uniswap-sdk", - "stargazers": 191, - "lastUpdated": "2025-05-02T07:31:13Z" - } - ] - }, - { - "id": "0x471ef1b671bc421d04640a7fe832365c1aec2d298adc81f03d69a685b7cc894c", - "name": "Loop Decoder", - "description": "Loop Decoder is a TypeScript library with minimal external dependencies that transforms blockchain data into a human-readable format.\n\nKey Features:\n- Works in any JavaScript environment\n- Minimal external dependencies - you only need an RPC; everything else can be fetched from your own storage\n- Highly customizable - we don't force you to use a specific API or storage; instead, we provide data loaders", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/b852c74f-a247-40dd-8299-90b8c7499c8c.png", - "banner_url": "https://storage.googleapis.com/op-atlas/bb135bd2-a2b6-46b1-b327-e3c8033f2f4b.png", - "twitter": "https://x.com/3loop_io", - "tags": [ - "transaction-decoding" - ], - "website": "https://loop-decoder-web.vercel.app/", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/3loop/loop-decoder", - "stargazers": 98, - "lastUpdated": "2025-11-05T11:08:28Z" - } - ] - }, - { - "id": "0x0cc5d7a8088f227787992130b3cffe143db1c904af1ac27324f84e762b84f35c", - "name": "Solarity", - "description": "Solidity-Oriented Development Tooling", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/9e453fca-55dd-45d9-9046-c8ee58290761.png", - "banner_url": "https://storage.googleapis.com/op-atlas/cd0944ee-9bed-445f-bcb8-ba22c80d3f57.png", - "twitter": null, - "tags": [ - "hardhat", - "education", + "fuzz-testing", "solidity" ], - "website": "https://solarity.dev/", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/dl-solarity/hardhat-zkit", - "stargazers": 95, - "lastUpdated": "2026-01-03T14:04:22Z" - }, - { - "href": "https://github.com/dl-solarity/solidity-lib", - "stargazers": 391, - "lastUpdated": "2026-01-05T15:54:20Z" - } - ] - }, - { - "id": "0xb024f6abfa79f7eb7af334f56015509bb70355709991d31bc689c7bea3250f7e", - "name": "foundry-gas-diff", - "description": "Easily compare gas reports generated by Foundry automatically on each of your Pull Requests!", - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [ - "foundry", - "cli", - "analytics", - "github-actions", - "code-quality", - "test-automation", - "continuous-integration" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Rubilmax/foundry-gas-diff", - "stargazers": 207, - "lastUpdated": "2025-04-04T08:54:57Z" - } - ] - }, - { - "id": "0xfeafe16f8c1a25aebe754f3653340a17943a483a3e389464e44cf14613e210f0", - "name": "foundry-storage-check", - "description": "- Protect your Smart Contract Proxy from storage collisions upon upgrading, by running this action in a CI on each of your Pull Requests!\n- Feel safe when extending your storage layout by trusting this action to check that extended layout is zero-ed out on-chain!", - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [ - "foundry", - "cli", - "devops", - "github-actions", - "solidity", - "storage-layout", - "code-quality", - "security" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Rubilmax/foundry-storage-check", - "stargazers": 100, - "lastUpdated": "2025-04-04T08:49:44Z" - } - ] - }, - { - "id": "0x48220ef1d103189cd918e9290db4c4b99b463ae2817fb5ef0cc54556a7961b6f", - "name": "keccak256js", - "description": "A wrapper for the keccak library to compute 256 bit keccak hash in JavaScript.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/b092dff2-6e21-451c-9946-2f02e2986c8f.png", - "banner_url": "https://storage.googleapis.com/op-atlas/e3093f96-c4b6-478e-bde2-19e96a7fa7a3.png", - "twitter": null, - "tags": [ - "encryption" - ], - "website": "https://github.com/keccak256js/keccak256", - "category": "Client Libraries & SDKs (Front-End)", + "category": "Security, Testing & Formal Verification", "repos": [ { - "href": "https://github.com/keccak256js/keccak256", - "stargazers": 67, - "lastUpdated": "2025-04-03T20:01:54Z" + "href": "https://github.com/crytic/properties", + "stargazers": 356, + "lastUpdated": "2025-11-29T16:59:34Z" } ] }, { - "id": "0x3ec2d572a608cf939eaf7886402320b3b2229610c13bdb5cb0776bd097331e5a", - "name": "VSCode Solidity Inspector ", - "description": "This is a VSCode extension offering utilities for solidity smart-contract development. \n\nSome features:\n- Storage layout viz.\n- Inline highlighting in code editor for unused imports.\n- Generate and view - Foundry deployment report in a clean and concise table format.\n- Syntax highlighting of for .tree files.\n- Generate foundry test stub using bulloak's scaffold command.\n- Auto-complete path suggestions for importing files and dependencies (with forge remappings support).\n- Contract code size decorator.\n\nMore cool utilities planned to be released. ", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/1e11eb35-ddb5-4385-bf18-2231ce727db9.png", - "banner_url": null, - "twitter": null, + "id": "0xeef42373d10554d65aba9e6deb8333a4eddebba829e0afea0dc93e32d8075d2d", + "name": "ERCx: Token Test Library", + "description": "Runtime Verification is a leading formal verification company specializing in blockchain security and smart contract correctness. We've developed ERCx, the most comprehensive open-source testing library for ERC token standards, featuring over 500 individual tests across ERC-20, ERC-721, ERC-1155, and ERC-4626 implementations.\nERCx directly empowers Superchain builders by providing production-ready test suites that verify both standard compliance and security properties. Our library offers zero-configuration testing for deployed contracts via Foundry fork testing, plus simple integration for pre-deployment source code validation. With three testing tiers: Standard (EIP compliance), Security (vulnerability detection), and Features (implementation validation), developers can ship token contracts with confidence, knowing they've been thoroughly vetted against real-world attack vectors and edge cases.\nWhat makes ERCx particularly valuable for the Optimism ecosystem is its cross-chain compatibility and handling of complex deployment scenarios. The library seamlessly works across OP Stack chains and handles storage complexities that often challenge developers working with established tokens like USDC or stETH. By providing this critical testing infrastructure as open-source tooling, we're enabling safer, more reliable token implementations across the entire Superchain, directly supporting the ecosystem's growth while reducing the security risks that have historically plagued token contracts in DeFi.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/e6a6dd9b-4ace-4187-8408-0e5729bb0265.png", + "banner_url": "https://storage.googleapis.com/op-atlas/eee0738d-3735-42c8-8802-93b22a041803.png", + "twitter": "x.com/rv_inc", "tags": [ "foundry", - "vscode-extension", - "solidity-development", - "storage-layout", - "code-analysis" + "security", + "erc721", + "runtime-verification" ], - "category": "Smart Contract Development & Toolchains", + "website": "ercx.runtimeverification.com", + "category": "Security, Testing & Formal Verification", "repos": [ { - "href": "https://github.com/PraneshASP/vscode-solidity-inspector", - "stargazers": 134, - "lastUpdated": "2025-07-28T19:58:19Z" + "href": "https://github.com/runtimeverification/ercx-tests", + "stargazers": 35, + "lastUpdated": "2025-07-04T12:23:27Z" } ] }, { - "id": "0xf152ccbfb3aa63c2ddcc070dc6d4462368eb25b69c3c3137cc459189af681402", - "name": "Derive Exchange SDK and Vault Executors", - "description": "Derive's market making library provides a Client / SDK for Derive Exchange, types, automated trading algorithms, vault executors, and more. This Client SDK is open sourced and generalizable for use in market making and algo trading on hybrid orderbooks across the Superchain!\n\nDerive is one of the first op-stack rollups delivering trustless, on-chain portfolio margin for options, spot and perpetual futures as well as structured products and fixed/floating rate lending markets. Derive has cleared over $15B in notional volume and has +$100M TVL", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/50bfdcb2-8355-4480-b530-df8cdc97e3da.png", - "banner_url": "https://storage.googleapis.com/op-atlas/e2df36a1-d787-4875-a156-ffba6dcd0b5f.png", - "twitter": "https://x.com/derivexyz", + "id": "0x517eaa9c56951de89261f2d7830ea49aae92f2a903104a17d9c5c2edd4959806", + "name": "LI.FI", + "description": "One API to swap, bridge, and zap across all major blockchains and protocols. Enable trading across all DEX aggregators, bridges, and intent-systems and save hundreds of developer hours.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/4906b988-6024-421e-a706-d01bc508e736.png", + "banner_url": "https://storage.googleapis.com/op-atlas/c280e13b-3e03-47e9-8141-5fad0d51ba2b.png", + "twitter": "https://x.com/lifiprotocol", "tags": [ - "defi", - "docker", - "cli" + "cross-chain", + "api", + "dex-aggregator", + "multi-chain", + "performance-optimization" ], - "website": "https://www.derive.xyz/", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/derivexyz/cockpit", - "stargazers": 18, - "lastUpdated": "2026-01-20T18:11:33Z" - } - ] - }, - { - "id": "0xbd393d380c995845e0b26365d91e9730403baa30b4a80e955be1ab5713bba709", - "name": "Black Scholes library/compiler - go and rust ", - "description": "Derive is one of the first op-stack rollups delivering trustless, on-chain portfolio margin for options, spot and perpetual futures as well as structured products and fixed/floating rate lending markets. Derive has cleared over $15B in notional volume and has +$100M TVL\n\nDerive's Black Scholes library/compiler into go and rust, research and testing in this area has led to 1 Black Scholes equation using ~300 gas while native EVM would be ~10K gas for a 30X more efficient computation of pricing and risk of any options related logic. ", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/69edd7f3-606d-4191-b7c8-28e41246b2d0.png", - "banner_url": "https://storage.googleapis.com/op-atlas/b753d4c0-96c7-4b36-b70e-e2785f9006bd.png", - "twitter": "https://x.com/derivexyz", - "tags": [ - "defi", - "gas-optimization" - ], - "website": "https://www.derive.xyz/", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/derivexyz/op-geth", - "stargazers": 6, - "lastUpdated": "2025-06-26T19:33:46Z" - } - ] - }, - { - "id": "0x46aff4985914b8e56b8fd62a9b8c3a03e2320315a9dfd6126e5ae272173cda87", - "name": "Patterns wallet analytics & CRM", - "description": "Free public web3 CRM and wallet analytics for OP builders. Helping OP dApps & DeFis discover most valuable user groups and counteract sybils. Part of the Optimism Superchain 4337 Data Standards group.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/ee4b3aab-f2b2-4400-abbc-2383b62662a4.png", - "banner_url": "https://storage.googleapis.com/op-atlas/b3b3b9a2-81bd-4e6b-af22-c388ca45c9f5.png", - "twitter": "https://x.com/patterns_build", - "tags": [ - "analytics", - "defi", - "visualization", - "docker", - "scalability" - ], - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/tokenguardio/dapp-marvels", - "stargazers": 15, - "lastUpdated": "2025-03-21T11:37:20Z" - } - ] - }, - { - "id": "0xc66e357ad67e63954cd1eb79da4d507d8800518f06c82e423e93e8771e7b8d13", - "name": "Brahma", - "description": "Brahma provides the infrastructure for automated operations from any source with programmable accounts, specialized agents, and developer tools that keep users in control at all times.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/b62d6708-d690-41e7-b574-4c8d6c728610.png", - "banner_url": "https://storage.googleapis.com/op-atlas/fd66f5d9-996c-4b69-8c0d-d7b4d9a2dc91.png", - "twitter": "https://x.com/BrahmaFi", - "tags": [], - "website": "https://www.brahma.fi/", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Brahma-fi/console-kit", - "stargazers": 28, - "lastUpdated": "2025-07-22T11:08:29Z" - } - ] - }, - { - "id": "0x90bbb485004d99e20be133d2c26abc1f63a2c1ec8107358e87853b001bfb6597", - "name": "Updraft", - "description": "What is Cyfrin Updraft?\nCyfrin Updraft is the leading blockchain development and smart contract security education platform, offering over 100+ hours of hands-on courses that enable aspiring and experienced smart contract developers to level up their skills. Designed and taught by CEO Patrick Collins alongside industry-leading educators and researchers, our platform provides high-quality, free educational content, hands-on coding experiences, and industry-recognized Cyfrin Updraft Certifications, which verify developers’ expertise in Solidity, Vyper, DeFi, and smart contract security.\n\nUpdraft has educated millions of developers globally, equipping them with the skills necessary to build secure and scalable decentralized applications. \n\nKey Metrics:\n220K+ Updraft community members\n1M+ Monthly impressions\n60K+ Monthly active developers\n15K+ Monthly new students\nTrusted by developers from top Web3 companies and protocols\n\nWhat are the Issues with the Existing Web3 Landscape?\nDespite the rapid growth of Web3, developers face several challenges:\n- Lack of accessible, high-quality education: Most resources are either too theoretical or fragmented, making it difficult for developers to gain practical experience.\n- Security vulnerabilities: Many developers lack the knowledge to build secure smart contracts, leading to exploits and hacks that result in millions in losses.\n- High entry barriers for Web2 developers: The transition from traditional development to Web3 remains complex due to unfamiliarity with blockchain infrastructure and tooling.\n- Limited developer retention: Many developers struggle to find long-term engagement opportunities within blockchain ecosystems. \n- No standardized skill validation: Without recognized certifications, it is difficult for developers to showcase their expertise, limiting their career opportunities.\n- Lack of security best practices: Without proper training and certification, developers may unknowingly introduce vulnerabilities, increasing the risk of hacks.\n\nHow Is Cyfrin Updraft Fixing the Issue?\nCyfrin Updraft addresses these challenges by providing:\n- Comprehensive blockchain development education: Covering Solidity, Vyper, Foundry, infrastructure, security best practices, and more.\n- Project-based learning: Developers gain hands-on experience by building and deploying real-world applications.\n- Security-first approach: Courses emphasize smart contract security, audit methodologies, and best practices to prevent exploits.\n- Developer tooling and ecosystem integrations: We create open-source tools and frameworks that enhance developer efficiency and security.\n- Bridging Web2 and Web3: Providing structured learning paths to onboard Web2 developers into Optimism’s ecosystem.\n- Completely free access: Updraft courses are entirely free, ensuring that any developer, regardless of financial constraints, can access high-quality education and build the skills needed to succeed in Web3.\n- Validation of Skills: Certifications provide a standardized way to verify a developer’s expertise, helping them stand out in a competitive job market.\n\nWho is Cyfrin Updraft For?\n+ Aspiring Web3 Developers - For newcomers eager to break into blockchain development, Cyfrin Updraft provides a structured and accessible learning path. Our courses start with fundamental concepts, gradually building up to advanced smart contract development, security topics, full stack development, infrastructure development and advanced DeFi dApp development . With hands-on coding exercises, real-world project deployments, and Cyfrin Updraft Certifications, aspiring developers can establish themselves in the industry, build secure and scalable dApp, and demonstrate their skills to potential employers.\n+ Experienced Web3 Engineers - For developers already working in the Web3 space, Cyfrin Updraft serves as a hub for continuous learning and skill enhancement. Advanced courses on smart contract security, DeFi mechanisms, and protocol architecture help engineers stay ahead of industry trends. Our Cyfrin Updraft Certifications validate expertise in Solidity, Vyper, and security best practices, distinguishing top engineers in a competitive job market. \n+ Web2 Developers - Traditional software engineers looking to transition into blockchain development often struggle with understanding decentralized technologies and smart contract principles. Cyfrin Updraft bridges this gap by providing a structured, Web2-friendly onboarding experience. Our courses explain blockchain fundamentals in a way that resonates with Web2 developers, drawing parallels between familiar programming concepts and smart contract development. For example, we’ve developed a Vyper Smart Contract Development course specifically to support onboarding Web2 developers, ensuring they gain hands-on experience with secure and efficient smart contract programming. This approach aligns with Updraft’s mission to scale Web3 adoption by equipping developers with the knowledge and tools they need to seamlessly transition into the decentralized ecosystem.\n+ Protocol and dApp Teams - Organizations need skilled developers who understand smart contract security, scalability, and best practices. Cyfrin Updraft helps protocol teams and dApp builders by providing a reliable pipeline of trained, certified engineers. Through Cyfrin Updraft Certifications, hiring teams can verify a candidate’s expertise, reducing onboarding time and improving the quality of development within their projects. Additionally, protocols can collaborate with Cyfrin Updraft to develop custom training programs, ensuring their developer communities are well-versed in their technology stack.\n\nWhat is the Roadmap for Cyfrin Updraft?\nQ1 2025: Courses & Foundational Expansion\n1. Launch a Full Stack Development Course\nThis course will provide a comprehensive learning experience for developers looking to build dApps from the ground up.\nThe course covers modern frontend frameworks (React, Next.js, Svelte), Web3 libraries (ethers.js, viem, wagmi), and backend infrastructure (site hosting, event indexing, caching strategies). \nDevelopers will build real-world projects, including a basic Ethereum dApp, a decentralized NFT marketplace, and an advanced DeFi interface with account abstraction.\n2. Launch Curve Cryptoswap Course\nA deep dive into the mechanics of Curve Finance’s automated market maker (AMM) designed for stablecoin swaps.\nThe course will explore the math supporting Curve Cryptoswap’s AMM, how liquidity is concentrated, and how the AMM decides to repeg the pool's liquidity at a different price.\nDevelopers will progress through AMM function calls, state variables, swapping tokens, adding and removing liquidity, and price-repegging. The learning is supported at every stage with quizzes and exercises.\n3. Launch Uniswap V3 Course\nThis course will focus on Uniswap V3’s concentrated liquidity model, fee tiers, and capital efficiency improvements.\nAn advanced DeFi developer course designed to enable developers to build Uniswap V3-based protocols\nThe course covers Uniswap V3 math and concentrated liquidity, progressing through swaps and the factory contract, the fee algorithms, and the TWAP price oracle.\n4. Launch SSCD+ (Smart Contract Security & Development) Certifications\nSSCD+ Certification is the premier certification for Solidity developers, recognized by industry-leading protocols and university organizations. This certification validates developers’ expertise in writing, testing, deploying, and troubleshooting Solidity smart contracts.\nKey skills that developers will be tested include proficiency in Solidity development, application of industry best practices, smart contract security expertise, mastery of industry-standard development tools, protocol-specific knowledge, blockchain DevOps skills\n\nQ2 2025: Advanced Security & Infrastructure Expansion\n1. Launch an Updraft Ambassador Program\nThe program will empower university students and community leaders to advocate for Web3 and Cyfrin Updraft, engage developers, host workshops and hackathons on campuses and in developer communities.\nAmbassadors will receive early access to Updraft certifications and mentorship from the Updraft team.\nThrough Updraft's ecosystem, students will gain practical experience in blockchain education, networking opportunities, and potential internships or job placements.\n2. Blockchain and Smart Contract Curriculum for Universities\nUpdraft will collaborate with top universities to integrate blockchain and smart contract development courses into academic curriculums.\nThis will include customized coursework, hands-on projects, and guest lectures from Web3 industry leaders.\nUniversities will be able to provide blockchain education at scale, helping bridge the gap between traditional computer science education and Web3 development.\n3. Launch a Jobs Board\nThe Updraft Jobs Board will connect certified developers with leading Web3 companies and protocols.\nDevelopers who complete Updraft’s courses and certifications will have access to job listings and hiring opportunities.\nEmployers will be able to filter candidates based on certifications and project experience, making the hiring process more efficient.\n4. Launch Vyper and Smart Contract Security+ Certification Program\nVyper+ Certification is a specialized certification focused on smart contract development using Vype. This program will cover Vyper syntax, best practices, contract patterns, and optimization techniques, ensuring developers can build secure and efficient Vyper-based applications.\nSmart Contract Security+ Certification is a security-focused certification that validates a developer’s ability to audit and secure smart contracts written in Solidity. This program will cover common vulnerabilities, formal verification, attack vectors, auditing methodologies, and best practices.\n\nQ3 2025: Developer Engagement & Retention\n1. Launch an Infrastructure Development Course\nThis course will focus on blockchain infrastructure, node operations, and MEV-related optimizations.\nDevelopers will learn how to build and run their own validators, set up RPC nodes, and optimize blockchain indexing. They will also gain a deep understanding of key Web3 infrastructure components, explore Layer 2 architecture, build custom L2 solutions, and evaluate infrastructure architecture trade-offs.\n2. Launch Live Cohort Learning Model\nCyfrin Updraft will introduce 8-week intensive live cohorts, where students will work through the curriculum alongside mentors, teaching assistants, and AI-driven learning support.\nEach cohort will focus on hands-on, project-based learning, ensuring participants gain practical experience building and securing Web3 applications.\nBy the end of the cohort, students will earn Updraft certifications and have portfolio-ready projects to showcase their skills.\n\nQ4 2025: Web2 to Web3 Expansion & Industry Integration\n1. Expand Integration with Enterprise Use Cases\nUpdraft will develop tailored educational programs for enterprise developers, helping businesses adopt blockchain technology.\nThis will involve customized workshops, tooling integration guides, and real-world enterprise case studies.\nThe goal is to bridge the gap between traditional Web2 development and Web3 innovation, making it easier for institutional developers to enter the space.\n", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/6c522dd8-66e1-441b-b54c-156886a50dd1.png", - "banner_url": "https://storage.googleapis.com/op-atlas/9cca66f9-2eef-4e2b-bc3c-515f52312848.png", - "twitter": "https://x.com/CyfrinUpdraft", - "tags": [ - "education", - "defi", - "solidity-development", - "community-driven" - ], - "website": "https://www.cyfrin.io/updraft", - "category": "Education & Community Resources", - "repos": [ - { - "href": "https://github.com/Cyfrin/Updraft", - "stargazers": 111, - "lastUpdated": "2026-01-20T18:33:32Z" - } - ] - }, - { - "id": "0x62d9a8a3b602c688610abfbe3965e04ca0d19c5c506f40e79cd185cb501d2018", - "name": "noble cryptography", - "description": "noble cryptography is a high-security, easily auditable set of contained cryptographic libraries with following features:\n\n- Zero or minimal dependencies\n- Highly readable TypeScript / JS code\n- PGP-signed releases and transparent NPM builds\n\nnoble cryptography is used in most modern JS wallets, including Metamask, Rabby, Rainbow, various SDKs, and others. Essentially it empowers a huge share of ecosystem.", - "thumbnail_url": null, - "banner_url": null, - "twitter": "https://x.com/paulmillr", - "tags": [ - "wallet", - "security", - "encryption" - ], - "website": "https://paulmillr.com/noble/", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/paulmillr/noble-curves", - "stargazers": 876, - "lastUpdated": "2026-01-13T01:04:35Z" - }, - { - "href": "https://github.com/paulmillr/noble-hashes", - "stargazers": 802, - "lastUpdated": "2026-01-13T01:31:07Z" - }, - { - "href": "https://github.com/paulmillr/noble-ciphers", - "stargazers": 358, - "lastUpdated": "2026-01-13T01:07:07Z" - } - ] - }, - { - "id": "0xded45f5b4e2be2487ef301591cf49859e95ed6d2b33743a0c0b5e15c25e17694", - "name": "UTP Java Library", - "description": "A non-blocking UTP library in Java that avoids defining the transportation layer. Ready to be used using UDP or discv5. ", - "thumbnail_url": null, - "banner_url": null, - "twitter": "https://x.com/meldsun0", - "tags": [ - "networking", - "peer-to-peer", - "real-time-data" - ], - "website": "https://github.com/meldsun0/utp", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/meldsun0/utp", - "stargazers": 0, - "lastUpdated": "2025-06-14T16:08:17Z" - } - ] - }, - { - "id": "0xe9495ac0f2a00d424f4f2dca80fe34c59c78d5cbf9acad0536c4c0ede540e053", - "name": "Mobile Wallet Protocol in Unity", - "description": "MWP is a protocol to allow unity games to interact with wallet apps and access users' web3 accounts. It creates a direct channel between client and wallet apps, removing the need for an intermediary bridge or relay server.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/8ad9f3a8-ac4a-4b5d-8652-4be22cf47ea0.png", - "banner_url": null, - "twitter": null, - "tags": [ - "wallet", - "game-development", - "user-experience" - ], - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/openfort-xyz/mobile-wallet-protocol-unity-client", - "stargazers": 1, - "lastUpdated": "2025-03-25T13:01:38Z" - } - ] - }, - { - "id": "0x44ff313ae6fb57054de6d637adae710594180239badaf2bc51889d068f4cf02b", - "name": "Modular Account", - "description": "Alchemy's Modular Account is a maximally modular, upgradeable smart contract account that is compatible with ERC-4337 and ERC-6900. Alchemy's Modular Account most efficient smart account on the market with release of v2 released in feb 2025", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/ff0b8f78-e997-4a50-ae49-6aaad2273213.png", - "banner_url": "https://storage.googleapis.com/op-atlas/2e157a8d-e9e1-4dbe-a0c0-ff6d908f9040.png", - "twitter": "https://x.com/alchemy", - "tags": [ - "wallet", - "defi", - "governance", - "security", - "modular-accounts", - "upgradeable-contracts", - "developer-experience" - ], - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/alchemyplatform/modular-account", - "stargazers": 136, - "lastUpdated": "2025-12-19T00:50:46Z" - }, - { - "href": "https://github.com/alchemyplatform/multisig-plugin", - "stargazers": 8, - "lastUpdated": "2025-03-31T16:31:21Z" - }, - { - "href": "https://github.com/alchemyplatform/aa-benchmarks", - "stargazers": 35, - "lastUpdated": "2025-04-30T22:40:07Z" - } - ] - }, - { - "id": "0x4e13be6b98dd868cd13e9f4101431ab03d211f429b63f078fa7da260b54d256a", - "name": "Light Account", - "description": "A set of lightweight, open sourced, audited and gas-optimized ERC-4337 compatible smart contract accounts with designated ownership", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/646cd1db-23b4-4328-8a7c-6c58358a73e1.png", - "banner_url": null, - "twitter": "https://x.com/alchemy", - "tags": [ - "wallet", - "account-abstraction", - "solidity", - "foundry" - ], - "website": "https://www.alchemy.com/", - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/alchemyplatform/light-account", - "stargazers": 111, - "lastUpdated": "2026-01-07T16:13:59Z" - } - ] - }, - { - "id": "0x0c85267cd9d7e694e385467c9984fbc787228db0cf03e57254a5116001eac4ee", - "name": "Tachyon", - "description": "Rath's Tachyon is a high-speed, low-latency relayer and bundler supporting EOA and AA transactions.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/6d42b8ec-216a-4904-ab39-ce60a80ee867.png", - "banner_url": "https://storage.googleapis.com/op-atlas/87fd037d-1b02-4325-b910-882245e95e7b.png", - "twitter": "https://x.com/rathfinance", - "tags": [ - "performance-optimization" - ], - "website": "https://rath.fi/", - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/RathFinance/tachyon-account", - "stargazers": 1, - "lastUpdated": "2025-05-01T11:31:58Z" - }, - { - "href": "https://github.com/RathFinance/tachyon-forwarder", - "stargazers": 1, - "lastUpdated": "2025-08-04T14:55:11Z" - } - ] - }, - { - "id": "0x2ccf4b9bd6ed894c10befd9fe00c467c4bfd84ff057ee956ab708259cfa845a9", - "name": "CodeTracer", - "description": "CodeTracer is a user-friendly time-traveling debugger designed to support a wide range of web3 programming languages.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/9e4b845e-5d97-4c91-a67e-94aab4a07a24.png", - "banner_url": "https://storage.googleapis.com/op-atlas/d2d38c2e-ba3a-4338-84fb-f78873866813.png", - "twitter": null, - "tags": [ - "cli", - "education", - "event-logging", - "performance-optimization" - ], - "website": "https://www.codetracer.com", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/metacraft-labs/codetracer", - "stargazers": 1268, - "lastUpdated": "2025-12-30T18:05:01Z" - } - ] - }, - { - "id": "0x3a942492f564e13e4a3fc11e9a8b5dcd8bf0213f9dd8571d888f32db84271c5f", - "name": "evm-rpcs-list", - "description": "Easy to use package with List of EVM chains & their RPCs in one place. Sourced from chainlist.org.\n\nUsage:\n`npm i evm-rpcs-list`\n`import networksList from \"evm-rpcs-list\";`", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/9a276191-f180-425f-96b5-c51e12ef35c2.png", - "banner_url": "https://storage.googleapis.com/op-atlas/c3df0213-1859-4bde-abbb-80a949304062.png", - "twitter": null, - "tags": [ - "chains" - ], - "website": "https://www.npmjs.com/package/evm-rpcs-list", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/apoorvlathey/evm-rpcs-list", - "stargazers": 17, - "lastUpdated": "2025-05-06T13:15:29Z" - } - ] - }, - { - "id": "0xf00e745fe6d96359adc3dc45d6d811bf1140549ad830d927cda5ca0b694a3063", - "name": "EIP.Tools", - "description": "Explore all EIPs, ERCs, RIPs and CAIPs at one place! Even indexes the EIPs in WIP status that have PRs open.\n\n- Search Functionality against all Improvement Proposals by No. or Title\n- EIP_GPT to summarize & get a gist of each Proposal\n- 3D Graph to visualize the interconnected nature of all the EIPs/ERCs\n- See Trending EIPs on the homepage\n- Bookmark and share your list of Improvement Proposals with others\n- EIP of the Day: learn about a random EIP/ERC each day", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/61e344ec-18c4-4a72-9d97-40c1d8f112b1.png", - "banner_url": "https://storage.googleapis.com/op-atlas/d2dbff0b-870e-4ef7-8cb2-4661de764405.png", - "twitter": "https://x.com/EIPTools", - "tags": [ - "analytics", - "visualization", - "interactive-tools" - ], - "website": "https://eip.tools/", - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/EIPTools/eip-tools", - "stargazers": 19, - "lastUpdated": "2026-01-19T13:10:23Z" - } - ] - }, - { - "id": "0x492486eda6bcb71b4891dd39a4e150db1f7ab46f64b83f2f5a02aed82497e9ed", - "name": "forge-stack-tracer", - "description": "CLI tool that converts your Foundry test output into interactive stack traces!\n\n✨ Powered by Swiss-Knife.xyz Calldata Decoder to decode even the unverified contracts!\n\nUsage:\nSimply pipe the forge tests result into fst.\n```forge test --mt test_case -vvvv | fst```", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/ed6e47cb-2456-42fb-ad28-8e23cef7f18c.png", - "banner_url": "https://storage.googleapis.com/op-atlas/ca1ea496-ccaa-4393-86b6-d14fc1e9c8f7.png", - "twitter": null, - "tags": [ - "cli", - "foundry", - "testing" - ], - "website": "https://www.npmjs.com/package/forge-stack-tracer", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/swiss-knife-xyz/forge-stack-tracer", - "stargazers": 9, - "lastUpdated": "2025-02-26T22:00:35Z" - } - ] - }, - { - "id": "0x93c4efb5e2d7416c56ecdcd8244be8faf924194d65b514d90a7a51f6797cc012", - "name": "Swiss-Knife.xyz", - "description": "Swiss-Knife aggregates all the useful EVM tools in one place to ease developer experience while they are debugging or building new stuff.\n\nList of Tools:\n1. Explorer: Quickly view any address/ens or transaction across a variety explorers, in just a click!\n2. Calldata: Decode any calldata, and view the parameters in a human-readable format, even without having the contract ABI.\n3. Transact: Send custom bytes calldata to transact with any contract, or leave the address blank to deploy a new contract.\n4. Converter: All the essential unit converters on one-page. Convert between:\n i. Ether, wei & gwei\n ii. Hexadecimal, decimal & binary\n iii. String or hex to keccack256 hash & 4 bytes selector\n iv. Hex to 32 bytes left-padded & right-padded values\n5. Constants: Have frequently used constants at your fingertips, like Zero Address, Max Uint256, etc.\n6. Epoch-Converter: Grab unix timestamp, get timestamp x minutes/hours/days in the future, or convert timestamp to human-readable format.\n7. Storage-Slots: Query EIP-1967 slots or custom storage slot value of any contract.\n8. Uniswap: Calculator to convert UniswapV3 tick to price for any token pair addresses.\n9. Character Counter: Count the length of the input string. Also allows to select on the input text to only get the character count for the selection.\n10. Contract Address: Determine the contract address which will get deployed by an address at a particular nonce", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/1eba0c98-3ab5-4bce-b365-607e76aa8778.png", - "banner_url": "https://storage.googleapis.com/op-atlas/e07ffbf7-525f-4fd4-b5fd-bec83fd940eb.png", - "twitter": "https://x.com/swissknifexyz", - "tags": [ - "frontend", - "analytics", - "developer-experience", - "debugging-tools", - "contract-deployment", - "nextjs" - ], - "website": "https://swiss-knife.xyz/", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/swiss-knife-xyz/swiss-knife", - "stargazers": 224, - "lastUpdated": "2025-12-29T09:27:39Z" - } - ] - }, - { - "id": "0x07222a857f4522026d91faec337e3cb8cf6ec5f7afb823e0742e1a6c398b81ff", - "name": "Impersonator.xyz", - "description": "Log-in to dapps as any address via WalletConnect, iFrame or Browser Extension\n\nImpersonator has benefitted the following Optimism users:\n- Traders: With impersonator they can log-in to dapps as whale wallets and study how they have setup their positions in detail.\n\n- Dapp users: They can access dapps on-the-go in view-only mode! They no longer have to keep their Metamask or Hardware wallet nearby just to visit the dapp dashboard. Impersonator works without private-keys.\n\n- Developers:\n- They can test how their dapp would respond for users with various token balances\n- Grab the transaction calldata being generated by dapps and simulate it via tenderly", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/5e04e1b5-a4b2-4755-89cf-6a155eff4aab.png", - "banner_url": "https://storage.googleapis.com/op-atlas/0417f6b7-6016-4141-8a9e-7b47a29a3a1f.png", - "twitter": null, - "tags": [ - "wallet", - "user-experience", - "react-app" - ], - "website": "https://impersonator.xyz/", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/impersonator-eth/impersonator", - "stargazers": 317, - "lastUpdated": "2025-12-21T13:39:53Z" - }, - { - "href": "https://github.com/impersonator-eth/impersonator-extension", - "stargazers": 61, - "lastUpdated": "2025-02-26T21:39:17Z" - } - ] - }, - { - "id": "0xd35cc78b456bf11d4acc96d2c227b29fa4115ad9d93ae211a31974a408ed8303", - "name": "Diffuse Data Feeds", - "description": "Diffuse's Price Feed Oracles offer a next-generation solution for accessing real-time, verifiable pricing data on any EVM-compatible L1 or L2 blockchain. \n\nBuilt on Diffuse's zkServerless protocol, this product redefines how price data is delivered by ensuring high-speed, trustless, and cryptographically secure updates for decentralized finance (DeFi) applications and beyond.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/0835fe6c-4d7d-4d2b-9f76-00fe91acd72b.png", - "banner_url": "https://storage.googleapis.com/op-atlas/3acbc145-3b84-44d7-b62b-7a39b5f0ac7e.png", - "twitter": "https://x.com/DiffuseFi", - "tags": [ - "defi", - "real-time-data", - "cli", - "verification" - ], - "website": "diffuse.fi", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Diffuse-fi/datafeed-cli", - "stargazers": 1, - "lastUpdated": "2025-04-30T13:22:20Z" - } - ] - }, - { - "id": "0xafb4dc19ccc63057da88110df49234b311044bc73b070041bb8df03e583943ab", - "name": "Abi Ninja", - "description": "**ABI Ninja provides an intuitive frontend for contracts from the most popular EVM networks, currently supporting:**\n\n- **Verified contracts**: Fetch contract ABIs and source code directly using Etherscan's API.\n- **Unverified contracts**: Two different options are available:\n\n 1. Provide the ABI and the contract address.\n 2. Decompile using heimdall-rs.\n\n- **Proxy contracts**: Autodetects most popular proxy patterns, and allows to read and write as proxy.\n\n![UI Image 1](https://raw.githubusercontent.com/BuidlGuidl/abi.ninja/main/.github/img/ui1.png)\n\n**It includes some nice features like:**\n\n- (mainnet!) ENS resolution on address inputs.\n- Shareable URLs with cool dynamic unfurl.\n- Show TX results.\n- Friendly UI even for complex data structures, now with dark mode!\n- Custom and Local Chains Support – Add or remove networks from a large selection, manually configure custom chains, or debug local contracts on chain ID 31337 (localhost).\n\n![UI Image 2](https://raw.githubusercontent.com/BuidlGuidl/abi.ninja/main/.github/img/ui2.png)\n \n \n*OP RetroFunding Rounds reported in the Funding Source section were for BuidlGuidl itself or other BuidlGuidl projects, not directly linked to Abi Ninja.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/83588cc2-f155-4b2c-8ff1-1347f2113c4d.png", - "banner_url": "https://storage.googleapis.com/op-atlas/bbb0dc26-29e0-42f6-a114-196bd042d3f8.png", - "twitter": null, - "tags": [ - "frontend", - "contract-interaction", - "proxy-contracts" - ], - "website": "https://abi.ninja/", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/BuidlGuidl/abi.ninja", - "stargazers": 224, - "lastUpdated": "2026-01-16T06:25:16Z" - } - ] - }, - { - "id": "0xc0809225b6287417d08ec0fde8d632ecc935296e61e239e7e44559c7dd7f2495", - "name": "Crawling the Ethereum P2P network with Nebula", - "description": "The ProbeLab team has developed advanced crawl tooling to gather important information on the structure of Ethereum's P2P network. The results are published weekly on Mondays at: https://probelab.io and report results for the previous week. The primary tool used to extract these results is the well-known and widely-used Nebula crawler.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/b48a5502-4473-4614-966a-c8581279a95b.png", - "banner_url": "https://storage.googleapis.com/op-atlas/b6aa707f-e3bd-43ea-965f-aef868ce0c6d.png", - "twitter": "@yiannisbot", - "tags": [ - "analytics" - ], - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/probe-lab/website", - "stargazers": 2, - "lastUpdated": "2025-12-03T12:31:48Z" - }, - { - "href": "https://github.com/dennis-tra/nebula", - "stargazers": 368, - "lastUpdated": "2025-11-03T07:46:30Z" - } - ] - }, - { - "id": "0x7f330267969cf845a983a9d4e7b7dbcca5c700a5191269af377836d109e0bb69", - "name": "IPFS", - "description": "IPFS (InterPlanetary File System) is a peer-to-peer protocol designed to make the web faster, more open, and more resilient. By using content-addressed storage rather than location-based references, IPFS removes the need for centralized servers and allows files to be distributed and retrieved from multiple nodes around the world. This approach lowers hosting costs, improves data availability, and reduces censorship, laying the groundwork for a more secure and permanent global information network.\n\nIPFS is used in a variety of applications. While some users interact with IPFS via imported libraries in their projects, a large amount of usage comes via IPFS' HTTP Gateway API which allows users to self-host, use extensions like IPFS companion, or publicly run gateways (whether paid ones run by companies like Filebase, Pinata, etc. or the public goods services at ipfs.io and dweb.link).\n\nIPFS is a system for moving data across decentralized networks, with >11M weekly users and 250K public p2p nodes. Highlights:\n\n1. Off-chain storage. IPFS provides verifiable, off-chain storage, often used to reduce on-chain needs in Ethereum & Optimism. Examples: TrueBlocks (local IPFS-based index for EVM chains, built with grants from OP & EF), Snapshot (IPFS-based off-chain voting).\n\n2. Go-to distribution network for fully decentralized third-party app frontends (for gaming, DeFi, & more). We run gateway services that serve 900M requests/wk, and added native IPFS support to browsers like Chromium & Brave.\n\n3. NFT metadata gold standard. Over 115M NFTs are stored on IPFS, including leading platforms OpenSea (which supports Optimism NFTs), Rarible, and Zora.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/fca3aa6c-bdd5-4632-ae64-37b886d50a65.png", - "banner_url": "https://storage.googleapis.com/op-atlas/35658254-c8b6-4562-9690-db91f187a7ff.png", - "twitter": "https://x.com/ipshipyard", - "tags": [ - "peer-to-peer", - "censorship-resistant", - "cli" - ], - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/ipfs/service-worker-gateway", - "stargazers": 79, - "lastUpdated": "2026-01-20T15:43:06Z" - }, - { - "href": "https://github.com/ipfs/helia", - "stargazers": 1275, - "lastUpdated": "2026-01-16T09:45:08Z" - }, - { - "href": "https://github.com/ipfs/kubo", - "stargazers": 16881, - "lastUpdated": "2026-01-16T01:27:32Z" - }, - { - "href": "https://github.com/ipfs/boxo", - "stargazers": 277, - "lastUpdated": "2026-01-20T18:22:51Z" - }, - { - "href": "https://github.com/ipfs/js-kubo-rpc-client", - "stargazers": 50, - "lastUpdated": "2025-10-15T07:29:36Z" - }, - { - "href": "https://github.com/ipfs/protons", - "stargazers": 37, - "lastUpdated": "2025-06-25T08:34:59Z" - }, - { - "href": "https://github.com/ipfs/js-ipns", - "stargazers": 89, - "lastUpdated": "2025-10-14T10:05:10Z" - }, - { - "href": "https://github.com/ipfs/helia-delegated-routing-v1-http-api", - "stargazers": 4, - "lastUpdated": "2026-01-16T14:05:02Z" - }, - { - "href": "https://github.com/ipfs/js-stores", - "stargazers": 37, - "lastUpdated": "2026-01-08T14:46:02Z" - } - ] - }, - { - "id": "0x7697147650b4b717ce5675982f2102da7c030498628fe37e3f403f875622b7f7", - "name": "Gelato Relay SDK", - "description": "Gelato Relay SDK offers a convenient suite of functions in order to interact with the Gelato Relay API. Gelato Relay API is a service that allows users and developers to get transactions validated fast, reliably and securely, without having to deal with the low-level complexities of blockchains. As requests are submitted to Gelato Relay, a network of decentralised Gelato Executors will execute and get the transactions validated as soon as possible. EIP-712 signatures enforce the integrity of data, while gas fee payments can be handled in any of our supported payment methods. In this way, developers can rely on Gelato's battle-tested blockchain infrastructure improving the UX, costs, security and liveness of their Web3 systems.​ ", - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [ - "security", - "sdk" - ], - "website": "https://www.gelato.network/relay", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/gelatodigital/relay-sdk", - "stargazers": 36, - "lastUpdated": "2025-12-29T14:33:05Z" - } - ] - }, - { - "id": "0xa492e54cf4d492c5f8a9c16038b4e5d47cd3bac575fbea7979f5cd1f1e575482", - "name": "Gelato Automate SDK", - "description": "Automate your smart contracts using Automate SDK", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/3d382dad-0b66-475d-a13c-43fddf27d5cc.png", - "banner_url": "https://storage.googleapis.com/op-atlas/635c79ee-de4c-431e-8ce8-cb47fedb91ce.png", - "twitter": null, - "tags": [ - "sdk", - "contract-interaction" - ], - "website": "https://www.gelato.network/web3-functions", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/gelatodigital/automate-sdk", - "stargazers": 20, - "lastUpdated": "2025-04-02T13:02:53Z" - } - ] - }, - { - "id": "0x670a2982f6d7786b58a8399bcabc23246365b21e533a97945e055791fc235e64", - "name": "Hardhat", - "description": "Hardhat is a development environment to build and deploy your Ethereum software", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/4659da93-959f-4622-bce7-0bf1b3ac0f5c.png", - "banner_url": "https://storage.googleapis.com/op-atlas/ef35fb80-418b-4c0b-a933-a11f7a3749d4.png", - "twitter": "https://x.com/HardhatHQ", - "tags": [ - "cli", - "hardhat", - "code-analysis", - "devops", - "performance-optimization", - "community-driven" - ], - "website": "https://hardhat.org/", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/NomicFoundation/edr", - "stargazers": 93, - "lastUpdated": "2026-01-20T13:20:44Z" - }, - { - "href": "https://github.com/nomicfoundation/hardhat", - "stargazers": 8407, - "lastUpdated": "2026-01-20T17:56:53Z" - } - ] - }, - { - "id": "0xaec1c406b2a124ec90aeebdde35c6c0cd9a90f0c7730b0911d2f648c8b99d062", - "name": "Variance_dart", - "description": "Core Technology Development\n\nvariance_dart: Developed a comprehensive dart package enabling passwordless dApps with passkey support, reaching v0.1.9 with over 500+ weekly downloads.\n\nWeb3_signer: Created a companion package supporting EIP-1271 message signing with multiple authentication methods (passkeys, HD wallets, private keys), processing over 200+ signatures weekly.\n\nENS Normalize: Implemented the full ENSIP-15 standard in Dart. Passes 100% of the official validation tests and recognized by the ENS DAO and ENS community.\n\nIndustry Recognition & Integration\n\nENS Community Recognition: Featured in ENS DAO newsletter.\n\nDeveloper Adoption: Achieved 13+ GitHub stars and 5+ forks across repositories, with an active contributors.\n\nSDK Reliability: Maintaining 99.9% uptime with average response time under 50ms for core SDK functions\n\nStrategic Partnerships\n\nVoltage Finance (Fuseio) Integration: Powered account abstraction for their new decentralized wallet, enabling 50,000+ users to perform gasless transactions and reducing user onboarding friction by 73%\n\nLearnWay Collaboration: Implemented education-focused blockchain tools serving 2000+ students and gamers eliminating gas fees for 4 key educational interactions:\n\nClaim sign-in bonuses \nStart/join quiz sessions \nAward distributions\nReduced failed transactions by 96% compared to traditional wallet interactions\nLearnWay used to be a web2 application driving incentivized learning for the blockchain. They choose Variance to transition to the Lisk blockchain.\n\nAdditional Technical Achievements\n\nTransaction Optimization: Reduced gas consumption by 43% through batched transactions and advanced bundling techniques.\n\nCross-Chain Support: Extended functionality to 6 major EVM-compatible chains, including Ethereum, Polygon, Arbitrum, Optimism, and Base.\n\nMobile Integration: Developed native mobile SDKs for iOS and Android, reducing integration time from 2 weeks to 3 days\n\nBusiness Impact\n\nUser Onboarding: Partners using Variance tools have seen 68% higher user retention compared to traditional Web3 onboarding.\n\nTransaction Success: Improved transaction success rates from industry average of 87% to 99.3% through intelligent gas estimation and retry mechanisms.\n\nEnterprise Adoption: Secured 2 enterprise-level implementations, including a financial institution leveraging account abstraction for treasury management.\nExtended functionality to mobile platforms with native integrations for hardware features like NFC\nBuilt infrastructure supporting cross-chain operations through custom bridge solutions\n", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/fcae3c08-8e11-40f9-a738-4a8e3c5f59d7.png", - "banner_url": "https://storage.googleapis.com/op-atlas/013ad3c8-5ddc-47ed-aff1-8476d46e30b6.png", - "twitter": "https://x.com/vaariance", - "tags": [ - "wallet", - "education", - "sdk", - "account-abstraction", - "transaction-signing" - ], - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/vaariance/variance-dart", - "stargazers": 16, - "lastUpdated": "2025-11-05T16:41:21Z" - } - ] - }, - { - "id": "0xc377ed1b705bcc856a628f961f1e7c8ca943e6f3727b7c179c657e227e8e852c", - "name": "MerkleTreeJS", - "description": "A JavaScript library to construct Merkle Trees and verify proofs.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/a98b7fe6-9d08-49e4-b764-5470e14ea3aa.png", - "banner_url": "https://storage.googleapis.com/op-atlas/997e2275-906b-4535-b414-59f4bd648196.png", - "twitter": null, - "tags": [ - "merkle-trees" - ], - "website": "https://github.com/merkletreejs/merkletreejs", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/merkletreejs/merkletreejs", - "stargazers": 1230, - "lastUpdated": "2025-09-15T07:14:10Z" - } - ] - }, - { - "id": "0x17fb589e599fe05e532b90c121eccc55b1249301e783dae226bad698872322da", - "name": "The Ethernaut", - "description": "The Ethernaut is a community-driven capture-the-flag wargame that challenges developers of all levels to break smart contracts while learning common Solidity vulnerabilities. Maintained by OpenZeppelin, each level provides a gamified experience where a smart contract must be ‘hacked’ to progress. It is 100% open-source, with all levels contributed by players.\n\nIn 2024, we have continued expanding the game, adding four new advanced levels—HigherOrder, Stake, Impersonator, and Magic Animal Carousel—which explore current vulnerabilities in smart contract development. These levels introduce challenges related to low-level EVM programming, staking vulnerabilities, signature verification exploits, and bitwise manipulation attacks, pushing players to deepen their understanding of Ethereum security.\n\nBeyond new levels, we have also redesigned the UI, added support for multiple networks, and expanded language translations to make the game more accessible to a global audience.\n\nWe believe that The Ethernaut is an essential training tool for developers across the Ethereum ecosystem, including those building on the Optimism network. By continually evolving the game with new challenges and features, we strive to make smart contract security education engaging, practical, and accessible to everyone.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/06419654-6022-400a-9670-82ca6e0225fe.png", - "banner_url": "https://storage.googleapis.com/op-atlas/5aba83e1-a4f2-453c-9e64-9884d0e628d6.png", - "twitter": "https://x.com/openzeppelin", - "tags": [ - "education", - "security", - "solidity", - "community-driven", - "react-app" - ], - "website": "https://ethernaut.openzeppelin.com/", - "category": "Education & Community Resources", - "repos": [ - { - "href": "https://github.com/OpenZeppelin/ethernaut", - "stargazers": 2273, - "lastUpdated": "2025-11-19T16:57:18Z" - } - ] - }, - { - "id": "0xcc9301a401320c626839db9c4415f28a6e1f2fb3abdf38ada785b57409bdedb6", - "name": "DexKit", - "description": "DexAppBuilder provides a comprehensive kit of no-code/low-code tools and solutions, enabling anyone to easily create customized DApps for Web3.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/07bee0c5-72ce-4e1b-b474-bd9d84856718.png", - "banner_url": "https://storage.googleapis.com/op-atlas/7881f699-90d7-4178-965c-8805145a348a.png", - "twitter": "dexkit", - "tags": [ - "frontend", - "react", - "nextjs" - ], - "website": "http://dexkit.com", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/DexKit/open-nft-marketplace", - "stargazers": 94, - "lastUpdated": "2025-02-24T02:49:26Z" - }, - { - "href": "https://github.com/DexKit/dexkit-monorepo", - "stargazers": 8, - "lastUpdated": "2025-12-07T11:06:41Z" - } - ] - }, - { - "id": "0x852f6213011d0ad31206df4993d22721102dbe615bb93492d6e8be8d89676243", - "name": "foundry-devops", - "description": "A tool to get the most recent deployment from a given environment in foundry. This way, you can do scripting off previous deployments in solidity.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/578db712-b499-4084-a729-99d90ee55c7f.png", - "banner_url": null, - "twitter": null, - "tags": [ - "foundry", - "cli", - "devops", - "solidity", - "contract-deployment" - ], - "website": "https://github.com/Cyfrin/foundry-devops", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Cyfrin/foundry-devops", - "stargazers": 630, - "lastUpdated": "2025-06-13T19:13:29Z" - } - ] - }, - { - "id": "0x7e917a2d0718401c9fe2a82f43ea558f5128f251b1e658c76dc7ff9a5e9fd993", - "name": "PRBMath", - "description": "PRBMath is a smart contract library that adds support for fixed-point types and advanced math functions like logarithms and exponentials in Solidity. Operating with 18-decimal numbers, PRBMath is at the same time gas efficient and user-friendly.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/527c8bbb-c361-4521-afbf-4396cecd1e3b.png", - "banner_url": "https://storage.googleapis.com/op-atlas/dc6b5afb-2335-484a-91f5-6673bf62237a.png", - "twitter": "https://x.com/PaulRberg", - "tags": [ - "solidity", - "gas-efficient", - "developer-experience", - "foundry" - ], - "website": "https://github.com/PaulRBerg/prb-math", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/PaulRBerg/prb-math", - "stargazers": 991, - "lastUpdated": "2026-01-18T17:09:35Z" - } - ] - }, - { - "id": "0x14eab8b10f729239d63df6c0cb85f666c3eb1f2dd440ebd003c1821f186a49da", - "name": "Ethernal", - "description": "Ethernal is an open source block explorer for evm chains.\nSpinning up a fully customised explorer only takes a couple of seconds, either through the UI or the API.\nIt includes a faucet UI, a dex UI, and can be customised to cater to network specificities, like custom 3rd party libraries, or custom contract & transaction post processing.\nIt also includes advanced token & network analytics, contract verification, nft galleries, etc..", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/9ced93ba-a5ac-4d04-a054-2963c41e8dc6.png", - "banner_url": "https://storage.googleapis.com/op-atlas/c141df7d-78ea-48c9-81b1-325fa5a33bc4.png", - "twitter": "https://x.com/tryethernal", - "tags": [ - "analytics", - "block-explorer", - "chains", - "contract-verification", - "cli" - ], - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/tryethernal/ethernal", - "stargazers": 261, - "lastUpdated": "2026-01-09T19:35:35Z" - }, - { - "href": "https://github.com/tryethernal/hardhat-ethernal", - "stargazers": 105, - "lastUpdated": "2025-02-22T09:44:00Z" - }, - { - "href": "https://github.com/tryethernal/ethernal-cli", - "stargazers": 16, - "lastUpdated": "2025-02-22T09:45:29Z" - } - ] - }, - { - "id": "0x8c0365628d69981ac162a89f2b391cc4adfd224e9a424f8e985e70e2421de6d1", - "name": "SuperUI", - "description": "Fire up a personal Superchain environment to run tests, fork networks, and inspect state with complete control over how your rollup operates. The Ultimate Ethereum & Superchain Development Playground", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/2a0e6716-cdf5-4a27-9912-5e520ccd68e1.png", - "banner_url": "https://storage.googleapis.com/op-atlas/fca44e15-1ce7-422d-b22f-2f1df4f4923c.png", - "twitter": null, - "tags": [ - "frontend", - "contract-management" - ], - "website": "Superui.app", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Nerd3Lab/superUI", - "stargazers": 33, - "lastUpdated": "2025-04-08T12:39:30Z" - } - ] - }, - { - "id": "0x72d363f14ae85f47acfe748fb0a2bed73195582bb9863de18901f5dfe309b8f7", - "name": "Solodit", - "description": "What is it?\nSolodit is an open-source, community-driven platform dedicated to improving web3 security. It aggregates over 8,000 smart contract vulnerability reports, bug bounty opportunities, and security audits from top firms like Cyfrin, OpenZeppelin and Trail of Bits, alongside contributions from individual researchers. Solodit not only aggregates this information but also makes it actionable, equipping developers and auditors with tools to prevent exploits and enhance the safety of dapps.\n\nWhy is it needed?\nThe web3 ecosystem is plagued by billions of dollars in losses due to security breaches in smart contracts and protocols. Despite the availability of security knowledge, it is fragmented across various platforms and reports, making it inaccessible to most developers and security teams. There are several problems that Solodit solves:\n\nKnowledge Gap: Many teams deploy smart contracts without understanding past vulnerabilities, leading to repeat incidents.\nInefficiencies: Developers and auditors spend valuable time searching disparate sources for security insights.\nEconomic Impact: Preventable exploits undermine trust in web3, stalling adoption and investment.\n\nBy aggregating and structuring security data, Solodit enables proactive vulnerability management and risk mitigation in the Web3 ecosystem.\n\nHow is it unique?\nComprehensive Coverage: Aggregates findings from leading auditors and platforms, offering unmatched insights into vulnerabilities and bug bounties.\nActionable Insights: Goes beyond archiving reports by providing advanced search tools and tagging systems to contextualise risks and solutions.\nCommunity-Driven Enhancements: Facilitates collaboration via ratings, tagging, and leaderboards that recognise top contributors, fostering a thriving security community.\nEducational Resource: This site serves as a learning hub for developers and auditors, providing real-world case studies on blockchain security.\n\nSolodit is a multipurpose tool designed to:\nMitigate Risk: Helps developers avoid known vulnerabilities, reducing the likelihood of exploits.\nPromote Proactive Security: Enables protocols to adopt preventive measures by studying historical vulnerabilities.\nStreamline Bug Bounties: Simplifies participation in bounty programs, encouraging more ethical hackers to contribute to ecosystem security.\nFoster Skill Development: Supports auditors in honing their skills and staying updated on emerging threats.\nSupport Decision-Making: Assists protocols in evaluating auditors via its leaderboard, promoting accountability and quality audits.\n\nWho is it for?\nDevelopers: Seeking to secure their smart contracts and understand vulnerability trends.\nAuditors: Looking to access a comprehensive repository of findings and showcase their expertise.\nWhitehat Hackers: Interested in participating in bug bounty programs and contributing to web3 security.\nProtocol P&E teams: Aiming to assess risks and prevent costly exploits.\nEducators and Researchers: Teaching or studying blockchain security with real-world examples, e.g. Cyfrin Updraft. \n\nStill to come:\nUI/UX redesign\nPower Aderyn, static analysis support", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/9cf8d92d-5549-4321-b675-c25256860183.png", - "banner_url": "https://storage.googleapis.com/op-atlas/20eb90df-0dd5-41fb-a3ce-f90cf3822492.png", - "twitter": null, - "tags": [ - "security", - "education", - "analytics", - "community-driven" - ], - "website": "https://solodit.cyfrin.io/", - "category": "Education & Community Resources", - "repos": [ - { - "href": "https://github.com/solodit/solodit_content", - "stargazers": 125, - "lastUpdated": "2026-01-10T18:05:45Z" - } - ] - }, - { - "id": "0xbaccff0188ef78c1bab0c9798b0faceee552de1dee4f763d1801a9c1d5e3bca5", - "name": "Verifereum", - "description": "Verifereum is an open-source project bringing mathematical rigor to Ethereum smart contract verification using the HOL4 theorem prover. The project is building tools to prove the correctness of smart contracts and eliminate entire classes of vulnerabilities. With billions of dollars secured by smart contracts, Verifereum aims to provide the strongest formal verification security guarantees possible for the Ethereum ecosystem.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/392d496a-b4b8-464c-bf6e-fcee8146a75f.png", - "banner_url": "https://storage.googleapis.com/op-atlas/3fd3093d-6a52-44bb-a73b-cf9d6f8cae03.png", - "twitter": "https://x.com/Verifereum/", - "tags": [ - "security", - "education", - "formal-verification" - ], - "website": "https://www.verifereum.org/", - "category": "Security, Testing & Formal Verification", - "repos": [ - { - "href": "https://github.com/verifereum/verifereum", - "stargazers": 29, - "lastUpdated": "2026-01-15T23:37:44Z" - } - ] - }, - { - "id": "0x495b81a381005f49592ee02a7ac6861b8da69762b7164180d0a1e4570f2d83bf", - "name": "DEO AI: Ethereum Developer Assistant", - "description": "DEO is an AI-powered assistant is designed to help Ethereum developers efficiently query and retrieve relevant documentation, references, and best practices from official sources, forums, and technical guides. By leveraging NLP and retrieval-augmented generation (RAG), the agent will allow developers to ask natural language questions and receive precise, contextual answers from Ethereum's technical ecosystem.\n\nThe agent will integrate with major Ethereum knowledge bases such as the Ethereum Developer Portal, Solidity documentation, EIPs (Ethereum Improvement Proposals), and Web3 libraries, streamlining research and troubleshooting for developers. It will also provide code snippets, explanations, and best practices in response to queries.\n\nI am psychemist, a seasoned full-stack developer focused on building Web3 products to advance a decentralized internet and native digital money. With a strong background in Ethereum’s ecosystem, I contribute to open-source projects and develop practical tools, devtools, and blockchain applications. My expertise spans smart contract development, decentralized protocols, and AI-driven tooling. For this grant, I am leveraging my experience to build Deo, an AI-powered assistant that enhances developer efficiency by providing intelligent, context-aware access to Ethereum documentation. Through Retrieval-Augmented Generation (RAG) and scalable AI models, Deo aims to streamline research, debugging, and smart contract development, making Ethereum’s complex knowledge base more accessible.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/900648a3-44d3-4d53-8e5e-1ccbb57bf9e2.png", - "banner_url": null, - "twitter": null, - "tags": [ - "education", - "natural-language-processing", - "cli", - "vscode-extension", - "community-driven" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/psychemist/deo-ai", - "stargazers": 1, - "lastUpdated": "2025-03-05T20:36:05Z" - } - ] - }, - { - "id": "0x991062ec81edb818a542e45d7c142cc62bc06e68b582273bd2ae1b037c2d6791", - "name": "Titan Layer", - "description": "Introduction-\n\nThe exponential growth of blockchain networks has led to a fragmented ecosystem, with limited interoperability between chains. Users and developers face significant challenges when transferring assets or deploying contracts across multiple chains. Titan Layer addresses these issues by offering an easy-to-use, secure, and scalable platform that fosters cross-chain connectivity. With a focus on user experience and interoperability, Titan Layer aims to drive blockchain adoption and foster activity across networks.\n\nChallenges in Cross-Chain Interoperability\n\nFragmented Ecosystem: Users must navigate multiple wallets and bridges, leading to complexity and errors.\n\nSecurity Risks: Many existing bridges are vulnerable to hacks and exploits.\n\nScalability Issues: High gas fees and slow transaction times hinder seamless cross-chain transactions.\n\nLimited User Experience: Current solutions are often technical and unfriendly to non-technical users.\n\n\nTitan Layer's Solution-\n\nTitan Layer solves these challenges by:\n\nSimplified Bridging: A one-stop solution for transferring assets across chains with minimal steps.\n\nContract Deployer: An intuitive tool that allows users to easily deploy and interact with contracts across multiple chains.\n\nHyperlane Integration: We leverage Hyperlane for secure, decentralized ERC20 token bridging.\n\nUser-Centric Design: A streamlined user interface designed to cater to both beginners and advanced users.\n\n\nKey Features-\n\nMulti-Chain Support: Titan Layer supports major networks such as Arbitrum, Optimism, Polygon, Base, BSC, and Mantle.\n\nCustomizable Connectivity: Users can choose which chains to connect for a tailored experience.\n\nSecurity First: Robust security measures, including audits and encryption, to protect users' assets.\n\nEasy Deployment: One-click smart contract deployment across multiple chains, reducing technical barriers.\n\nReal-Time Monitoring: Dashboard for tracking transactions, bridging status, and contract interactions.\n\n\nUse Cases-\n\nDevelopers: Effortlessly deploy and interact with contracts across multiple chains.\n\nTraders: Seamlessly transfer assets across chains to capitalize on arbitrage or market opportunities.\n\nProjects: Launch multi-chain dApps with ease, expanding their reach and user base.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/35374f7e-a430-4726-b5f0-ef52e2b5115a.png", - "banner_url": "https://storage.googleapis.com/op-atlas/ba692e10-9ffd-4406-b6e7-5010ad20b2d2.png", - "twitter": "https://x.com/TitanLayer", - "tags": [ - "cross-chain", - "security" - ], - "website": "https://titanlayer.xyz/", - "category": "Cross-Chain & Interoperability", - "repos": [ - { - "href": "https://github.com/TitanLayer/contracts", - "stargazers": 0, - "lastUpdated": "2025-02-21T21:33:35Z" - } - ] - }, - { - "id": "0x154a42e5ca88d7c2732fda74d6eb611057fc88dbe6f0ff3aae7b89c2cd1666ab", - "name": "🏗️ Scaffold-ETH 2", - "description": "Scaffold-ETH 2 is an open-source toolkit for building decentralized applications on the Ethereum blockchain. It's designed to make it easier for developers to create and deploy smart contracts and build user interfaces that interact with those contracts.\n\nIt's a new version of scaffold-eth with its core functionality.\n\n- ⚙️ Built using NextJS, RainbowKit, Hardhat, Foundry, Wagmi, Viem, and Typescript.\n- ✅ Contract Hot Reload: Your frontend auto-adapts to your smart contract as you edit it.\n- 🪝 Custom hooks: Collection of React hooks wrapper around wagmi to simplify interactions with smart contracts with typescript autocompletion.\n- 🧱 Components: Collection of common web3 components to quickly build your frontend.\n- 🔥 Burner Wallet & Local Faucet: Quickly test your application with a burner wallet and local faucet.\n- 🔐 Integration with Wallet Providers: Connect to different wallet providers and interact with the Ethereum network.\n- 🔌 Extensions: Modular add-ons that provide additional functionality or serve as starter-kits for specific features.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/f8efb7c2-8fb3-4988-8511-ae6e826b687f.png", - "banner_url": "https://storage.googleapis.com/op-atlas/8b032214-48dc-4f13-b8fa-21324d9c9030.png", - "twitter": "https://x.com/ScaffoldETH", - "tags": [ - "frontend", - "nextjs", - "hardhat", - "foundry", - "cli" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/scaffold-eth/create-eth-extensions", - "stargazers": 48, - "lastUpdated": "2025-07-17T15:25:10Z" - }, - { - "href": "https://github.com/scaffold-eth/burner-connector", - "stargazers": 6, - "lastUpdated": "2025-12-17T12:12:49Z" - }, - { - "href": "https://github.com/scaffold-eth/se-2-docs", - "stargazers": 21, - "lastUpdated": "2025-12-19T08:05:18Z" - }, - { - "href": "https://github.com/scaffold-eth/create-eth", - "stargazers": 21, - "lastUpdated": "2026-01-20T10:58:36Z" - }, - { - "href": "https://github.com/scaffold-eth/scaffoldeth.io", - "stargazers": 8, - "lastUpdated": "2025-11-28T16:26:22Z" - }, - { - "href": "https://github.com/scaffold-eth/scaffold-eth-2", - "stargazers": 1944, - "lastUpdated": "2026-01-13T07:11:14Z" - } - ] - }, - { - "id": "0x63f8e1e35986862f0bb24a619b72d12459497d2b6b94d93a9f2c232d376c54dc", - "name": "RainbowKit Theme Generator", - "description": "Easily create custom RainbowKit theme from a single color that you can copy and paste into your web3 apps.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/532d50f9-524d-4934-b77a-8c85d0145bcf.png", - "banner_url": "https://storage.googleapis.com/op-atlas/a1272743-7b81-4aef-a8fd-f2fe70122b01.png", - "twitter": null, - "tags": [ - "frontend" - ], - "website": "https://rainbowkit-theme.com/", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/zwergdev/rainbowkit-theme-generator", - "stargazers": 5, - "lastUpdated": "2025-02-19T22:36:03Z" - } - ] - }, - { - "id": "0xc0615947773148cbc340b175fb9afc98dbb4e0acd31d018b1ee41a5538785abf", - "name": "Wagmi: Reactive primitives for Ethereum apps ", - "description": "Wagmi is the industry standard for building apps on Ethereum. Wagmi has deep integrations with modern web frameworks, like React.js and Vue.js, and makes it easy to connect wallets, sign messages, send transactions, and read/write on-chain data. With over 1.2M monthly downloads, Wagmi is used in production by most of the industry and is at the core of apps, like Uniswap, Optimism, Polymarket, Stripe, Zora, and Farcaster.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/4043de65-2657-4c0f-91e6-3d5aea14dc33.png", - "banner_url": "https://storage.googleapis.com/op-atlas/faafa9b3-2151-4cd7-a9f3-e9c1853e8874.png", - "twitter": "https://x.com/wevm_dev", - "tags": [ - "react", - "wallet", - "transaction-signing", - "community-driven" - ], - "website": "https://wagmi.sh", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/wevm/wagmi", - "stargazers": 6646, - "lastUpdated": "2026-01-17T20:39:56Z" - } - ] - }, - { - "id": "0xfa7d950cfda2c634b052b6c07e75daaa95dd22ac1f220b6862cfd24221d4cabc", - "name": "Solhint", - "description": "SOLHINT is the most used Solidity linter in web3 space. A tool that helps solidity devs to write standardized smart contracts code, taking care of code quality, order, readability, style guides, preventing known bugs, and giving security alerts. It is an extremely popular open source tool within Ethereum community. Our grant application aims to fund a small dedicated team of technical and marketing professionals to increase community engagement into proposing new rules, report bugs, discuss possible updates, etc.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/8a93267a-39e3-42c9-976f-225753bb43f3.png", - "banner_url": "https://storage.googleapis.com/op-atlas/cc6944d5-ceb0-416d-9e3c-befb89ef7578.png", - "twitter": "https://x.com/protofire", - "tags": [ - "security", - "education", - "code-quality", - "community-driven", - "cli" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/protofire/solhint", - "stargazers": 1115, - "lastUpdated": "2026-01-20T14:22:50Z" - } - ] - }, - { - "id": "0x202a80f0f57630d04a26464d6492b3399059ca1187943032c37652eb2468a76f", - "name": "Titanoboa", - "description": "Titanoboa is a Vyper interpreter and testing framework that provides a modern, integrated development experience for Vyper smart contracts. It enables developers to test and debug Vyper contracts directly within Python, offering features like pretty tracebacks, forking, debugging capabilities, pytest integration and out-of-the box fuzzing. Beyond its standalone capabilities, Titanoboa serves as the foundation for other popular testing frameworks like Ape and Moccasin, and is a core piece of infrastructure for the Vyper ecosystem.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/2e9723d3-7b53-473c-b93c-87b2c7a72055.png", - "banner_url": "https://storage.googleapis.com/op-atlas/801bbd29-77ab-4050-b175-f853aa9704ed.png", - "twitter": null, - "tags": [ - "vyper", - "debugging-tools" - ], - "website": "https://titanoboa.readthedocs.io/en/latest/", - "category": "Security, Testing & Formal Verification", - "repos": [ - { - "href": "https://github.com/vyperlang/titanoboa", - "stargazers": 305, - "lastUpdated": "2025-12-25T13:57:23Z" - } - ] - }, - { - "id": "0xaed5941b7a9f20de83f5c839bda507be43cbf41777fc623abf4bf05773298826", - "name": "Otterscan", - "description": "A blazingly fast, local, Ethereum block explorer built on top of Erigon for EVM chains", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/55a1fffb-dcd9-448b-8e34-9fb4b09a72f7.png", - "banner_url": "https://storage.googleapis.com/op-atlas/a0e75c22-8aff-4176-af81-6c03208c1bd3.png", - "twitter": "https://x.com/otterscan", - "tags": [ - "docker", - "block-explorer", - "chains", - "privacy-focused", - "react-app", - "json-rpc", - "visualization" - ], - "website": "https://otterscan.io/", - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/otterscan/otterscan", - "stargazers": 1396, - "lastUpdated": "2025-11-05T05:21:21Z" - } - ] - }, - { - "id": "0x67f6d1feb3b5e99caf0f2e7e4677494c57449de3980079589156e105df485488", - "name": "Moccasin", - "description": "What is it?\nMoccasin is an open source, public-good developer tool. It's a python-based Vyper smart contract development, deployment, and testing framework.\n\nWhy is it needed?\nThe Web3 Python ecosystem has been overshadowed by the Rust and Javascript ecosystems, which is a crucial misstep when all financial and AI developers use Python. Walk into any asset manager or hedge fund and ask the portfolio managers or traders what they are using, and the answer is Python. We need a fast and modern tool for Python exploration. \n\nVyper adds to smart contract language diversity, which is as important as having client diversity from the blockchain infrastructure. If one has a critical bug, we minimize the downside by having different languages.\n\nHow is it unique?\nMoccasin is the fastest Python framework and, for Vyper smart contracts, even outpaces Foundry in some instances. It achieves this speed by being built on the lightning-fast Titanoboa tool.\n\nYou can see a quick benchmark of compile time for Vyper contracts across popular frameworks like Apeworx and Foundry.\nhttps://github.com/Cyfrin/Moccasin/blob/main/docs/source/_static/stats-default.png?raw=true\n\nWhat can it do?\nEncrypt keys\nRun tests\nUnderstand deployment contexts\nAnd ideally work with the growing number of non-EVM compatible chains (ie, ZKsync, Scroll, etc)\nRun fuzzing campaigns\n\nMoccasin is a new tool, but due to its speed and developer friendliness, we expect to see its adoption skyrocket in the Python community.\nWhat really sets Moccasin apart, other than being the fastest and most developer-friendly Python tooling for Viper, is that developers can now script and perform DevOps in the user-friendly language Python.\n\nWhat is our roadmap?\nYou can see a list of 0.4.0 roadmap items (and other priority items) for Moccasin including:\nbetter multi-sig & hardware wallet integration\nin-line debugger\nSolidity support\nMedusa fuzzing\nbuillt-in halmos or HEVM support\n\nWho is it for?\nPython developers. According to the Stack Overflow 2024 survey, python is the #1 programming language for new developers.\nSo, Moccasin is for new developers.\nAccording to Upwork, Python is the #1 language for people working in AI.\nSo, Moccasin is for AI developers.\nAccording to Columbia Engineering, python is the #1 language for fintech.\nSo, Moccasin is for financial developers, including DeFi.\nThis tool is meant for both new and advanced developers - a tool that is easy to pick up and powerful enough for professional applications. (edited) \n\nWith this tool, we want to start bridging the gap between web2 and web3 developers and encourage builders to move into our industry. Allowing developers to use multiple languages and to grow the adoption of the Sueprchain. \n", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/89c06746-f49f-4a30-9843-80b431053f13.png", - "banner_url": "https://storage.googleapis.com/op-atlas/5ec5b8ee-5389-4201-8191-4a84e37f1291.png", - "twitter": null, - "tags": [ - "education", - "vyper", - "devops", - "cli", - "encryption" - ], - "website": "https://github.com/Cyfrin/moccasin", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Cyfrin/moccasin", - "stargazers": 177, - "lastUpdated": "2026-01-16T22:40:08Z" - } - ] - }, - { - "id": "0x513265758a3804184b6a0771d99c1a4b04d3267bacd4b914e89ff991de229f6a", - "name": "Create2Deployer", - "description": "Create2Deployer is a factory smart contract designed to make easier and safer usage of the `CREATE2` EVM opcode. Create2Deployer is a preinstall on the OP Stack: https://specs.optimism.io/protocol/preinstalls.html#create2deployer.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/ca4f6cbd-5b97-4c22-9e27-446b9e4cd2ff.png", - "banner_url": "https://storage.googleapis.com/op-atlas/120ab790-4407-4342-b7af-e562cf3a9c8c.png", - "twitter": null, - "tags": [ - "solidity", - "contract-deployment" - ], - "website": "https://github.com/pcaversaccio/create2deployer", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/pcaversaccio/create2deployer", - "stargazers": 305, - "lastUpdated": "2026-01-19T17:58:29Z" - } - ] - }, - { - "id": "0x537097f27d55cb52d39b95c3ed65076349ab68aac48051d742d715456e0884d8", - "name": "xdeployer", - "description": "Hardhat plugin to deploy your smart contracts across multiple EVM chains with the same deterministic address. A total of 133 EVM chains are currently supported, including (almost) all OP-stack-powered chains.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/ce1dd7d2-ed08-45f9-adf0-1934ae5dc396.png", - "banner_url": "https://storage.googleapis.com/op-atlas/4942518f-9987-4d03-9504-a7494fce0021.png", - "twitter": null, - "tags": [ - "hardhat", - "cross-chain", - "multi-chain", - "contract-deployment", - "cli" - ], - "website": "https://github.com/pcaversaccio/xdeployer", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/pcaversaccio/xdeployer", - "stargazers": 445, - "lastUpdated": "2026-01-19T18:24:30Z" - } - ] - }, - { - "id": "0x4dd10ba330a4a21459e2ba72f15fb5da2a63f7492e2b1567e6669c3d47fe6308", - "name": "Web3j", - "description": "Web3j is the Java and Android integration library for Ethereum.\n\nCreated in 2016, and still going strong in 2025 it is core plumbing to Ethereum for one of the world's most widely used development platforms, the JVM.\n\nIt has been downloaded millions of times, and is used by everyone including\n- Enterprises such as J.P. Morgan, Fnality and NTT Data\n- Web3 infrastructure companies such as Alchemy \n- The Besu Ethereum Execution client\n- It's even been integrated natively into the Android OS by Freedom Factory in ethOS which powers the upcoming Ethereum phone the DGEN1\n\nWe decided in 2024 to bring Web3j into the Hyperledger Foundation, which provides high-quality governance of open source (similar to the Apache Foundation). It's still, the same team at Web3 Labs responsible for maintaining and supporting the library for its wide and varied user base. The Hyperledger association is great for visibility, but doesn't provide any funding for the project!\n\nWe rely on grant funding to sustain this library and hopeful to qualify for this RPGF round.\n\nUnfortunately, we missed out on OP RPGF 3 as we had not realised projects were eligible for multiple rounds so did not apply following our success in OP RPGF 2.\n\n🙏🏻", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/be0b64a3-1fcb-4f95-ad91-6a2589a5315f.png", - "banner_url": "https://storage.googleapis.com/op-atlas/e1ea2162-1ef8-46ea-afdc-37f0bb4dee4a.png", - "twitter": "https://x.com/web3labs", - "tags": [ - "governance", - "cli" - ], - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/hyperledger-web3j/web3j", - "stargazers": 5378, - "lastUpdated": "2026-01-20T19:54:06Z" - }, - { - "href": "https://github.com/hyperledger-web3j/web3j-maven-plugin", - "stargazers": 127, - "lastUpdated": "2025-10-07T17:02:07Z" - }, - { - "href": "https://github.com/hyperledger-web3j/web3j-unit", - "stargazers": 27, - "lastUpdated": "2026-01-19T19:46:41Z" - }, - { - "href": "https://github.com/hyperledger-web3j/web3j-openapi-gradle-plugin", - "stargazers": 4, - "lastUpdated": "2025-04-11T07:03:23Z" - }, - { - "href": "https://github.com/hyperledger-web3j/web3j-openapi", - "stargazers": 36, - "lastUpdated": "2025-04-10T21:53:19Z" - }, - { - "href": "https://github.com/hyperledger-web3j/web3j-solidity-gradle-plugin", - "stargazers": 23, - "lastUpdated": "2026-01-16T06:21:44Z" - }, - { - "href": "https://github.com/hyperledger-web3j/web3j-docs", - "stargazers": 34, - "lastUpdated": "2025-06-09T08:35:36Z" - }, - { - "href": "https://github.com/hyperledger-web3j/web3j-installer", - "stargazers": 0, - "lastUpdated": "2025-05-22T18:33:35Z" - }, - { - "href": "https://github.com/hyperledger-web3j/web3j-cli", - "stargazers": 69, - "lastUpdated": "2025-04-11T11:54:07Z" - }, - { - "href": "https://github.com/hyperledger-web3j/web3j-gradle-plugin", - "stargazers": 41, - "lastUpdated": "2025-04-10T16:02:38Z" - }, - { - "href": "https://github.com/hyperledger-web3j/web3j-sokt", - "stargazers": 16, - "lastUpdated": "2026-01-16T05:49:46Z" - } - ] - }, - { - "id": "0x819775803938d78eaa95809971ce94cae6a54b4df58505fa36153ffa1d55e12c", - "name": "Vscode Solidity Extension", - "description": "Solidity support for Visual Studio code\nVersion Downloads Installs Rating\n\nSolidity is the language used in Ethereum to create smart contracts, this extension provides:\n\nSyntax highlighting\nSnippets\nCompilation of the current contract (Press F1 Solidity : Compile Current Solidity Contract), or F5\nCompilation of all the contracts (Press F1 Solidity : Compile all Solidity Contracts), or Ctrl + F5 or Cmd + F5\nCode completion for all contracts / libraries in the current file and all referenced imports\nGoto definition\nFind all references in project\nHover information\nCode actions / quick fixes (change compiler, format address, add sdpx license.. )\nMono repo support (identifies the project by finding the files: remappings.txt, foundry.toml, brownie-config.yaml, truffle-config.js, hardhat.config.js, hardhat.config.ts)\nDefault project structure (solidity files needs to be in the src/ directory, and libraries in the lib/ directory). Libraries will follow the same structure.\nCompilation supporting EIP82 (dappfile and dependency packages)\nSupport for different solidity versions (Remote and local)\nDownload source code and Abi from Etherscan\nCode generation using Nethereum, it includes currently the default template for Nethereum service, dtos generation. (Open 'contractName.json' after compilation from the bin folder. Press F1 and press Solidity: Code generate from compilation output..) Auto generation of Nethereum files on compilation\nLinting using Solhint or Ethlint\nIt is also available as a standalone LSP", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/006b0fd3-9e23-4192-98d6-08e561da809e.png", - "banner_url": null, - "twitter": null, - "tags": [ - "education", - "solidity" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/juanfranblanco/vscode-solidity", - "stargazers": 959, - "lastUpdated": "2025-11-04T17:05:55Z" - } - ] - }, - { - "id": "0xa3d07f453f70d844196d89d79848aa2e70a0bd8b38bf0f493cba1547bb3bca5e", - "name": "Ethers.js", - "description": "Ethers.js is a simple, compact and complete JavaScript (via TypeScript) library for interacting with Ethereum and related blockchains.\n\nIt is currently used in a very large number of Blockchain projects, including everything from block explorers to wallets (like MetaMask) and is downloaded over 7.1 million times per month (as of this writing). It is also one of the top 500 projects (by dependants) on NPM.\n\nIt was written and is maintained by me, RicMoo (Richard Moore), a random developer from Canada that is passionate about open-source and dedicates most his waking-time (and some sleeping-time) to it.\n\nHack the Planet! :)", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/f8d776ab-ca70-42ee-9e41-d4f709cd6fd4.png", - "banner_url": "https://storage.googleapis.com/op-atlas/459bdd5e-60a5-49ca-88b8-d4537ebfec16.png", - "twitter": "@ricmoo", - "tags": [ - "frontend", - "json-rpc", - "contract-interaction" - ], - "website": "https://ethers.org", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/ethers-io/ethers.js", - "stargazers": 8626, - "lastUpdated": "2025-12-03T00:49:47Z" - } - ] - }, - { - "id": "0x2bb095e1f297c71da8bd4ee15097abad3b99e299fe14cd6aa704df3f36d0ae22", - "name": "solidity-coverage", - "description": "solidity-coverage provides smart-contract code coverage for the Hardhat developer platform. It's highly accurate, supports full viaIR solidity compilation and a large set of solidity-specific code branch patterns. It's installed on ~230k Github projects and is downloaded ~100k times a week from NPM.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/bd692393-7f1a-4b91-9887-73f7c3250233.png", - "banner_url": "https://storage.googleapis.com/op-atlas/dcbdf6ac-f898-4dac-b9d0-087b8d289f4b.png", - "twitter": null, - "tags": [ - "hardhat", - "analytics", - "code-coverage", - "solidity", - "test-automation" - ], - "website": "https://github.com/sc-forks/solidity-coverage", - "category": "Security, Testing & Formal Verification", - "repos": [ - { - "href": "https://github.com/sc-forks/solidity-coverage", - "stargazers": 1005, - "lastUpdated": "2025-12-11T04:00:44Z" - } - ] - }, - { - "id": "0x4f8902ac6eba8e2243237247302ab778a1e1f496cf62e1696fbb8d57eff7701d", - "name": "blocksmith.js", - "description": "blocksmith.js is a minimal Javascript testing framework for Ethereum contract development using foundry-rs and ethers. It is a lightweight wrapper around forge and anvil, so you can script Foundry however you want. It is primarily designed for developing cross-chain applications that cannot be tested inside of a single EVM instance.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/8b8c4fda-3240-41c6-ab52-43a137e665a8.png", - "banner_url": "https://storage.googleapis.com/op-atlas/0b8f272e-b319-4744-959e-dbc36996ba31.png", - "twitter": "https://x.com/adraffy", - "tags": [ - "cli", - "foundry", - "cross-chain", - "contract-deployment" - ], - "website": "https://github.com/adraffy/blocksmith.js", - "category": "Security, Testing & Formal Verification", - "repos": [ - { - "href": "https://github.com/adraffy/blocksmith.js", - "stargazers": 11, - "lastUpdated": "2025-12-08T22:29:40Z" - } - ] - }, - { - "id": "0x939241afa4c4b9e1dda6b8250baa8f04fa8b0debce738cfd324c0b18f9926d25", - "name": "OpenZeppelin Contracts", - "description": "OpenZeppelin Contracts are the go-to library for smart contract development.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/83bab036-91bd-4b9d-a524-dbea2024aa3f.png", - "banner_url": "https://storage.googleapis.com/op-atlas/489f54b5-2035-4a94-82f5-8b41e6cbb857.png", - "twitter": "https://x.com/openzeppelin", - "tags": [ - "cross-chain", - "governance", - "erc721", - "upgradeable-contracts", - "modular-accounts", - "interactive-tools", - "merkle-trees" - ], - "website": "https://www.openzeppelin.com/", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/OpenZeppelin/openzeppelin-upgrades", - "stargazers": 648, - "lastUpdated": "2025-11-03T20:09:20Z" - }, - { - "href": "https://github.com/OpenZeppelin/openzeppelin-subgraphs", - "stargazers": 146, - "lastUpdated": "2025-02-25T15:09:17Z" - }, - { - "href": "https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades", - "stargazers": 244, - "lastUpdated": "2025-06-30T19:16:05Z" - }, - { - "href": "https://github.com/OpenZeppelin/merkle-tree", - "stargazers": 519, - "lastUpdated": "2025-02-25T02:12:49Z" - }, - { - "href": "https://github.com/openzeppelin/openzeppelin-community-contracts", - "stargazers": 80, - "lastUpdated": "2026-01-13T18:10:27Z" - }, - { - "href": "https://github.com/OpenZeppelin/openzeppelin-contracts", - "stargazers": 26929, - "lastUpdated": "2026-01-15T16:08:39Z" - }, - { - "href": "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable", - "stargazers": 1149, - "lastUpdated": "2026-01-15T16:10:26Z" - }, - { - "href": "https://github.com/OpenZeppelin/contracts-wizard", - "stargazers": 294, - "lastUpdated": "2026-01-16T15:24:19Z" - } - ] - }, - { - "id": "0x663e4d25ca3f327365240471b4831ea3c989cb132bbf6ae8f5c1e15268591795", - "name": "Blockscout open-source block explorer", - "description": "Blockscout block explorer is the #1 explorer used by Optimistic rollups and Superchain networks. Blockscout is highly customizable and available, providing advanced developer tooling for projects and blockchain transparency for users.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/3113c4b6-4e29-420c-95f8-2ae4f6098089.png", - "banner_url": "https://storage.googleapis.com/op-atlas/c08d15e7-41fd-41a7-9c04-b1e10b0c1f26.png", - "twitter": "https://x.com/blockscoutcom", - "tags": [ - "block-explorer", - "chains" - ], - "website": "http://www.blockscout.com", - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/blockscout/blockscout", - "stargazers": 4380, - "lastUpdated": "2026-01-20T19:42:29Z" - } - ] - }, - { - "id": "0x8589657542ff4b7c5071dfdeff18a041642a72344ede9acea701e9b39fb46fee", - "name": "Chimera", - "description": "Chimera is a framework to write Solidity tests in foundry and be able to reuse them with other Open Source Tools such as Echidna, Medusa, Halmos and Kontrol", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/c26c5e5d-f2aa-4150-a46c-2e9c33de343f.png", - "banner_url": "https://storage.googleapis.com/op-atlas/3e4364f9-e445-4c2d-be52-af8cf934eab6.png", - "twitter": "https://x.com/getreconxyz", - "tags": [ - "foundry", - "solidity", - "code-coverage", - "test-automation", - "vscode-extension" - ], - "category": "Security, Testing & Formal Verification", - "repos": [ - { - "href": "https://github.com/Recon-Fuzz/setup-helpers", - "stargazers": 4, - "lastUpdated": "2025-07-29T14:37:36Z" - }, - { - "href": "https://github.com/Recon-Fuzz/log-parser", - "stargazers": 4, - "lastUpdated": "2025-09-24T11:20:41Z" - }, - { - "href": "https://github.com/Recon-Fuzz/create-chimera-app", - "stargazers": 47, - "lastUpdated": "2025-07-31T13:34:09Z" - }, - { - "href": "https://github.com/Recon-Fuzz/chimera", - "stargazers": 143, - "lastUpdated": "2025-03-20T19:16:12Z" - }, - { - "href": "https://github.com/Recon-Fuzz/recon-extension", - "stargazers": 31, - "lastUpdated": "2025-12-15T15:58:31Z" - } - ] - }, - { - "id": "0xbb067b01988521110c91737f058e7301f608be231d850a72af1516bd034d161c", - "name": "Synpress", - "description": "Synpress is an end-to-end testing framework for web applications based on Cypress.io and Playwright, with support for MetaMask. It is a pioneering tool in web3 end-to-end testing with the potential to evolve into a decentralized network of test runners and continuous integration providers in the future. Synpress is easy to use, fully tested, and includes features such as MetaMask support, headless mode, integrated video recording, and many more. It is also blazingly-fast and extensible, with the ability to add custom commands and plugins. Synpress is already used by many open-source repositories.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/abf0fa5e-15f2-4963-bd73-d84d0bd4c307.png", - "banner_url": "https://storage.googleapis.com/op-atlas/0d9aecc0-dcf4-4ee0-9e6c-12d9b62325ea.png", - "twitter": "https://x.com/Synpress_", - "tags": [ - "frontend", - "continuous-integration", - "performance-optimization", - "debugging-tools" - ], - "website": "https://synpress.io/", - "category": "Security, Testing & Formal Verification", - "repos": [ - { - "href": "https://github.com/synpress-io/docs", - "stargazers": 0, - "lastUpdated": "2025-05-06T19:41:49Z" - }, - { - "href": "https://github.com/Synthetixio/synpress", - "stargazers": 873, - "lastUpdated": "2026-01-10T22:17:58Z" - } - ] - }, - { - "id": "0xb773733e55b7267302f2622ae410a65a89552689387d0b86bce0f0cb833119d0", - "name": "Callthis", - "description": "Callthis is a better transaction builder:\n- Generate an interface for any contract, even if it's unverified. (Powered by WhatsABI)\n- Build a transaction and save it as a link that can be shared and executed later.\n- Works with any EVM chain, with WalletConnect or Safe Wallets or browser-injected providers.\n- Address fields automatically resolved with ENS.\n- Supports complex contract inputs with tuples, arrays, etc.\n- No backend services required, grab the source and run it locally for privacy and censorship-resistance!\n- Permissively licensed under MIT, use it in your products.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/abe6dc50-0732-419b-a64c-463814247f78.png", - "banner_url": null, - "twitter": null, - "tags": [ - "frontend", - "wallet", - "cross-chain", - "privacy-focused", - "censorship-resistant" - ], - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/shazow/callthis", - "stargazers": 50, - "lastUpdated": "2025-12-05T15:58:59Z" - } - ] - }, - { - "id": "0x4ede10cd8332093fb0c1083828cc2e333d60f1551cef2d29bccb82bae1f5d7f7", - "name": "Candide's Smart Account Contracts", - "description": "Candide offers open-source smart contracts designed for teams that are pushing the boundaries of Ethereum UX with Account Abstraction. Our contracts includes a formally verified and audited Social Recovery module, a Paymaster contract for gas sponsorship, and a BLS Account contract. These solutions are trusted by high-profile projects like Safe, Worldcoin, and many others.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/104d6957-65bc-4d15-a5f9-2afd75482347.png", - "banner_url": "https://storage.googleapis.com/op-atlas/c120c166-68a8-4e9b-a159-b1f9e74ff105.png", - "twitter": "https://twitter.com/candidelabs", - "tags": [ - "wallet", - "governance", - "education", - "account-abstraction", - "user-experience" - ], - "website": "https://www.candide.dev/", - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/candidelabs/candide-contracts", - "stargazers": 77, - "lastUpdated": "2025-02-09T15:12:44Z" - } - ] - }, - { - "id": "0x28aec169f525d30fed96625a31fdd75ca906805d0ee4e7b1502945a9e1d29525", - "name": "AbstractionKit | Account Abstraction Library", - "description": "AbstractionKit is TypeScript Interface designed for Ethereum Account Abstraction. It simplifies the standard's complexities and provides a robust foundation for developing smart wallet applications. AbstractionKit is used in conjunction with libraries like Ethers, viem, and wagmi. It remains service-agnostic, offering compatibility with any Node, Bundler, or Paymaster provider. Key features include Passkeys Login, Gas Sponsorship and Social Recovery. AbstractionKit is used by smart wallets that are breaking new ground in Ethereum UX, such as Morpher, Unit-e, BackPack, JOIN, and many others.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/69b08a09-8fd5-498a-beef-67ad29cf01b5.png", - "banner_url": "https://storage.googleapis.com/op-atlas/75a0886a-d3a0-4595-a539-64a8a83eae3a.png", - "twitter": "https://twitter.com/candidelabs", - "tags": [ - "wallet", - "education", - "account-abstraction" - ], - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/candidelabs/abstractionkit", - "stargazers": 31, - "lastUpdated": "2025-12-05T12:12:24Z" - } - ] - }, - { - "id": "0xc7798704a6d730cea776c4866a9636bfa04c1201e29b6b0c99cc3603bc1bca25", - "name": "Cannon", - "description": "Cannon is a DevOps tool for protocols on Ethereum. It manages smart contract deployment and configuration for local development and live networks.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/8b14d1e8-d2ef-4670-83da-76368cbd50af.png", - "banner_url": "https://storage.googleapis.com/op-atlas/7ce75cc0-17f9-457a-b456-0232b9647d96.png", - "twitter": "https://x.com/usecannon", - "tags": [ - "cli", - "chains" - ], - "website": "https://usecannon.com", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/usecannon/cannon", - "stargazers": 122, - "lastUpdated": "2025-10-24T08:50:56Z" - } - ] - }, - { - "id": "0x40483b3554ae17882db98d1cfd3aae6b10ba8250736279d184fd947931ed02c3", - "name": "Superfuse", - "description": "Superfuse, is a toolchain and knowledge hub to build cross-chain contracts in Superchain Ecosystem. It includes:\n\n1) Superfuse wizard: It is a code generator/ interactive developer playground to develop a part of smart contract/deploy script/ test suites out of components from cross-chain specification. Select kind of contract that you want (eg. ERC7802, SuperchainERC20, and ERC20Votes).\n\n\n2) suerfuse-forge: a developer-friendly framework/library in solidity to build a variations of cross-chain contracts in superchain Ecosystem", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/6038b69f-0ca7-478f-a55f-002f00e3b7e7.png", - "banner_url": "https://storage.googleapis.com/op-atlas/d96837af-ba2e-44d1-9e6d-ad9b30a06c3e.png", - "twitter": "https://twitter.com/RATi_MOn", - "tags": [ - "cross-chain", - "frontend", - "solidity", - "interactive-tools", - "foundry" - ], - "website": "https://superfuse.ninja/", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Ratimon/superfuse-wizard", - "stargazers": 20, - "lastUpdated": "2025-04-12T12:17:32Z" - }, - { - "href": "https://github.com/Ratimon/superfuse-forge", - "stargazers": 19, - "lastUpdated": "2025-02-15T09:02:50Z" - } - ] - }, - { - "id": "0x166e2bfeae612e99675a055e2d3e3d02e49bdab377109bc528c32b7afe6cc920", - "name": "solid-grinder", - "description": "A 100% opensource CLI that goes along with building blocks of smart contract. This toolbox can reduce L2 gas cost by encoding calldata for dApps development to use as little bytes of calldata as possible.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/2161762e-cdb8-41be-978b-3581df50d5a4.png", - "banner_url": "https://storage.googleapis.com/op-atlas/ca2f1444-6a4f-41f2-91d4-f8059f652ccc.png", - "twitter": "https://twitter.com/RATi_MOn", - "tags": [ - "cli", - "layer-2", - "solidity", - "developer-experience", - "transaction-optimization" - ], - "website": "https://github.com/Ratimon/solid-grinder", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Ratimon/solid-grinder", - "stargazers": 100, - "lastUpdated": "2025-02-08T07:16:37Z" - } - ] - }, - { - "id": "0x37fe5886f4c77d5a5cb947deff90158c045a5d207572763187748ac4dd4bd9b9", - "name": "ethereum-multicall", - "description": "Ability to call many ethereum constant function calls in 1 JSONRPC request", - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [ - "multicall" - ], - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/joshstevens19/ethereum-multicall", - "stargazers": 381, - "lastUpdated": "2025-12-23T11:07:33Z" - } - ] - }, - { - "id": "0x4c9626843c4e3f3c96d80b0ec6b1d10b7682fc9b6d67ab61ece5a87648535b1f", - "name": "ethereum-bloom-filters", - "description": "A lightweight bloom filter client which allows you to test ethereum blooms for fast checks of set membership.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/d21bd2f0-91b0-4e80-9e33-b1c21501a4e8.png", - "banner_url": null, - "twitter": null, - "tags": [ - "performance-optimization", - "event-logging" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/joshstevens19/ethereum-bloom-filters", - "stargazers": 93, - "lastUpdated": "2025-05-02T07:29:04Z" - } - ] - }, - { - "id": "0x97525ec91080ddd917eaccabf9d383cf70a2f78839ab21eeabe1687e312f2132", - "name": "rindexer", - "description": "rindexer is an opensource powerful, high-speed indexing toolset developed in Rust, designed for compatibility with any EVM chain. This tool allows you to index chain events using a simple YAML file, requiring no additional coding. For more advanced needs, the rindexer provides foundations and advanced capabilities to build whatever you want. It's highly extendable, enabling you to construct indexing pipelines with ease and focus exclusively on the logic. rindexer out the box also gives you a GraphQL API to query the data you have indexed instantly.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/366c4940-78cc-4119-958b-b93f3c9a5845.png", - "banner_url": null, - "twitter": null, - "tags": [ - "indexing", - "cli" - ], - "website": "https://rindexer.xyz/", - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/joshstevens19/rindexer", - "stargazers": 643, - "lastUpdated": "2026-01-20T18:33:58Z" - } - ] - }, - { - "id": "0xc88dff5a8bb7326e7d9103bf84e77425e202a8275abffbbbc08954c309acf511", - "name": "Voltaire | Account Abstraction Bundler", - "description": "Voltaire Bundler is a core infrastructure component for Ethereum Account Abstraction designed to extend Ethereum nodes. It facilitates the inclusion of smart account transactions — known as UserOperations —via an alternative peer-to-peer mempool, without requiring any protocol changes. Voltaire is relied in production by Smart Wallets pushing new grounds for Ethereum UX like JOIN, BackPack, El-Dorado, Unit-e, Morpher and and many others. Voltaire is built and maintained by Candide, a small independent team that has been redefining Ethereum user experiences since 2022.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/4686b986-8bb5-4ab0-a13b-c020291b20c2.png", - "banner_url": "https://storage.googleapis.com/op-atlas/2ac896b0-1b09-40bf-a5db-7baef34ead58.png", - "twitter": "https://twitter.com/candidelabs", - "tags": [ - "wallet", - "governance", - "account-abstraction", - "bundler", - "docker", - "user-experience" - ], - "website": "https://www.candide.dev/bundler", - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/candidelabs/voltaire", - "stargazers": 56, - "lastUpdated": "2026-01-12T21:35:32Z" - } - ] - }, - { - "id": "0x4e175118c15129e6cc791203de92b23f11fef35ba4bc3fd18390f163e692c97d", - "name": "EvmTools", - "description": "Evmtools (previously zkblock) started as a boilerplate for developing zk dapps using circom (groth and plonk). But since the inception, it has grown to include variety tools required to develop zk and web3 dapps. These tools help during development of variety of dapps inlcuding zk-snarks based dapps, whitelisting contracts, contracts using EIP-712 signatures such Aave credit delegation, custom signatures, raw transaction decoder, determining contract addresses, understand on-chain slot structure etc.\n\nThe goal of evmtools is to help users to debug, build and ship web3 apps. Since, the inception we have included several features to make evmtools useful for development.\n\nWe have built whole suite of (20+) tools for developers. These tools help developers to test and debug during development. Some of the tools include-\n\nUniswap V4 Hooks tools\nMerkle Tree Generator (using secure openzeppelin libraries, provides easy debugging for whitelisting)\nEVM Transaction Decoder\nBit Manipulation, masking etc\nGeneral Utility tools\nGas converter, byte conversion, hex conversion etc.\nEpoch Converter\nGenerate burner addresses\nChecksum Formatter\n\nAll tools are available in an extension as well. ", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/c82ddf3d-3586-4552-85ce-8e9f5da907d5.png", - "banner_url": null, - "twitter": "https://x.com/evmtools_xyz", - "tags": [ - "cli", - "analytics", - "debugging-tools", - "transaction-decoding", - "merkle-trees" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Elefria-Labs/zk-block", - "stargazers": 71, - "lastUpdated": "2025-02-07T03:07:51Z" - }, - { - "href": "https://github.com/Elefria-Labs/evm-tools", - "stargazers": 14, - "lastUpdated": "2025-10-21T09:26:42Z" - } - ] - }, - { - "id": "0x754c37e401e2527ab24b9d7ca3e042bfcbfebeef54a533f8833d46242d2c3017", - "name": "Remix Project", - "description": "A rich and accessible Web3 toolset for learning, building, and testing on multiple chains", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/09d19a87-dc4f-4586-99f6-ef6c9f92f713.png", - "banner_url": "https://storage.googleapis.com/op-atlas/5286dfe0-6f4d-4782-8c59-b7ffe6579bfc.png", - "twitter": "https://x.com/EthereumRemix", - "tags": [ - "education", - "frontend", - "cross-chain", - "solidity", - "community-driven" - ], - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/remix-project-org/remix-reward", - "stargazers": 1, - "lastUpdated": "2025-02-19T13:53:14Z" - }, - { - "href": "https://github.com/ethereum/remix-project", - "stargazers": 2856, - "lastUpdated": "2026-01-19T16:48:13Z" - }, - { - "href": "https://github.com/remix-project-org/remix-challenges", - "stargazers": 0, - "lastUpdated": "2025-02-19T13:53:51Z" - }, - { - "href": "https://github.com/remix-project-org/remix-rewards-ui", - "stargazers": 1, - "lastUpdated": "2025-02-19T13:54:26Z" - } - ] - }, - { - "id": "0x5f9f1b45eb4a49e8c2482288e02c8fc1e0e60ad3e88f0ea87bbdb4932da1054d", - "name": "Diamondscaffold: Simplifying EIP-2535 Diamond Architecture Development", - "description": "Diamondscaffold is a CLI tool designed to streamline the development of EIP-2535 diamond structures. Supporting both Hardhat and Foundry, it provides ready-to-use templates for ERC20, ERC721, and a default Diamond structure, allowing developers to efficiently scaffold modular smart contracts. With JavaScript/TypeScript compatibility, automated dependency installation, and an intuitive setup process, Diamondscaffold accelerates project deployment while ensuring flexibility and scalability. By making diamond contract architecture more accessible, this tool fosters innovation within the Ethereum and Optimism ecosystems, empowering developers to build robust, upgradeable, and efficient smart contracts.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/d818a88f-eb12-4c4e-b1be-46f8284fd5d4.png", - "banner_url": "https://storage.googleapis.com/op-atlas/8d4a3113-5b39-472e-9a60-57451db585fb.png", - "twitter": "https://x.com/BAbraham_92/", - "tags": [ - "cli", - "hardhat", - "foundry", - "erc721", - "upgradeable-contracts" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/collinsadi/diamonds", - "stargazers": 34, - "lastUpdated": "2025-03-26T13:00:43Z" - } - ] - }, - { - "id": "0x5dfcf84cc8ef7eb731a8175633c8da5cd3784fe57b05409f0df745b88443c034", - "name": "Simbolik - Solidity Debugger", - "description": "We are Runtime Verification, a team specializing in formal methods and blockchain security. Simbolik is the tool we developed in-house, a powerful Solidity debugger that combines traditional breakpoint debugging with symbolic execution, enabling developers to explore every possible execution path and uncover vulnerabilities with precision.\n\nAvailable as a VSCode extension, Simbolik integrates seamlessly into existing workflows, offering breakpoint-style debugging, Solidity and EVM-level inspection, and formal verification capabilities. Adopted by organizations like Lido, Optimism, Ethereum Foundation, and others, Simbolik helps Superchain builders write more secure and reliable smart contracts.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/d2f26755-6a96-4cf7-917e-6ebeced29a15.png", - "banner_url": "https://storage.googleapis.com/op-atlas/8d0da35d-0369-4bf8-a577-60ce33236078.png", - "twitter": "https://x.com/rv_inc", - "tags": [ - "security", - "education", - "symbolic-execution", - "vscode-extension", - "runtime-verification", - "formal-verification" - ], - "website": "simbolik.runtimeverification.com", - "category": "Security, Testing & Formal Verification", - "repos": [ - { - "href": "https://github.com/runtimeverification/simbolik-examples", - "stargazers": 5, - "lastUpdated": "2026-01-14T20:21:15Z" - }, - { - "href": "https://github.com/runtimeverification/simbolik-vscode", - "stargazers": 47, - "lastUpdated": "2026-01-05T04:32:05Z" - } - ] - }, - { - "id": "0xabdfa10e699db5127100da1dd2403692afe8d86e793d57780f1c7e93437a73a0", - "name": "WhatsABI", - "description": "Extract ABI (and more) from Ethereum contract bytecode, even without source code.\n\nWhatsABI is a public good for making EVM bytecode more useful and usable on all EVM-based chains, such as mainnet and OP Stack chains.\n\nThe guiding purpose for WhatsABI is to improve decentralization, transparency, and user safety by reducing our dependence on proprietary centralized frontends for EVM contracts. \n\nWhatsABI a permissively-licensed TypeScript library that is perfect for building better contract explorers, transaction builders, smarter wallets, and for doing security research. It is designed to be small, fast, and easily embedded in wallets or runnable locally with any provider. Some things WhatsABI can do: Return selectors from bytecode, look up function signatures from selectors, provide helpers for looking up ABI and signatures from public databases (like Sourcify, Etherscan, Blockscout, OpenChain, 4Byte), resolve onchain proxies (including inspecting available diamond facets!), loading contract metadata, and more. \n\nWhatsABI is already powering many popular projects like: Otterscan, Sourcify, Rivet, Ondora, Thirdweb, and more coming soon as we collaborate on integrations upstream.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/63e11af2-345b-4977-b6da-dcaf387df081.png", - "banner_url": "https://storage.googleapis.com/op-atlas/6e45f230-2ef2-43f1-ab9d-b95e2ac0f15e.png", - "twitter": "https://x.com/shazow", - "tags": [], - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/shazow/whatsabi", - "stargazers": 1141, - "lastUpdated": "2025-12-10T20:23:39Z" - } - ] - }, - { - "id": "0x2247247c751707d897f5c0eab670426d9c1c26d84e96ac226004afbf0080cba4", - "name": "Rundler", - "description": "Rundler (Rust Bundler) is an ERC-4337 bundler implementation written in Rust. Rundler is designed to achieve high-performance and high-reliability in cloud deployments via a modular architecture. Currently, both Alchemy and Coinbase’s Base team use Rundler. It powers >70% of UOs in the Ethereum ecosystem and a vast majority of UOs in the Superchain. Rundler is OSS licensed with GPL.\n\nRundler powers the ERC-4337 ecosystem with an implementation that users can rely on to scale reliably. Rundler open source code repo has 300+ stars, more than 50 forks. \n\nOur goals with Rundler:\n\nERC-4337 Specification Compliance: Rundler strives to implement the full ERC-4337 specification and to maintain support as the specification changes and new onchain components are released. This includes new Entry Point contract support, support for the upcoming P2P mempool specification, support for alternative mempools, and more.\nBest-in-class Performance and Reliability: Rundler strives to power the most demanding workloads in cloud environments. Rust was chosen for its high performance and memory safety. Rundler's modular architecture lets providers choose to run the stateless components (RPC, builder) in a fully horizontally scalable manner connecting to the stateful components (mempool, p2p, event cache) via the network. Rundler's bundle builder is designed to be able to support the full gas throughput of the network it's building for.\nExtensibility/Chain Support: ERC-4337 is designed to support any EVM chain. However, different EVM supporting networks have different rules around how to support things like gas usage, gas fees, precompiles, etc. Rundler is designed to be extensible and easily adapted to support any EVM chain.\nModularity: Rundler is written in a modular manner, allowing its components to be run as a single integrated binary, or as a distributed system. Rundler also strives for its individual crates to be used to support future ERC-4337 tooling.\n\nIn RPGF Round 3, Alchemy was awarded a total of 74,534 $OP across Rundler, Light Account, ERC-6900, aa-sdk, and various informational pieces put out to the public domain to further adoption of smart accounts in the Superchain.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/7e5161c3-ab8c-44e9-97b9-a957fa9cb7a2.png", - "banner_url": "https://storage.googleapis.com/op-atlas/2985ee59-7f46-4626-93f4-fd91de426cd2.png", - "twitter": "twitter.com/alchemy", - "tags": [ - "docker", - "cross-chain", - "bundler", - "support", - "account-abstraction", - "scalability" - ], - "website": "www.alchemy.com", - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/alchemyplatform/rundler", - "stargazers": 369, - "lastUpdated": "2026-01-20T14:12:46Z" - } - ] - }, - { - "id": "0x740bebbc731ec56dcc17c7d429656220a73960022c3809edf324bd8120285722", - "name": "bulloak", - "description": "A smart contract test generator based on the Branching Tree Technique. ", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/73d7f842-6eb3-4a74-89df-176b8a69e4c2.png", - "banner_url": "https://storage.googleapis.com/op-atlas/b5a6613d-fb1f-439c-ba1e-e0fcd42c99b5.png", - "twitter": null, - "tags": [ - "cli", - "solidity", - "code-quality", - "code-analysis", - "test-automation", - "solidity-development", - "code-coverage" - ], - "website": "https://www.bulloak.dev/", - "category": "Security, Testing & Formal Verification", - "repos": [ - { - "href": "https://github.com/alexfertel/bulloak", - "stargazers": 342, - "lastUpdated": "2026-01-14T15:27:04Z" - } - ] - }, - { - "id": "0xe6eb4d61eff4e2dc2d8dba01ac1b84c1683bdb1e8d677a66fa44a72e3f8b1faf", - "name": "Zabi", - "description": "Zabi is a project for interacting with ethereum and the superchain written in Zig", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/e1983235-58da-4c36-86eb-63e593554d7e.png", - "banner_url": "https://storage.googleapis.com/op-atlas/467a5d29-ee97-4610-8923-18346cbc3a4e.png", - "twitter": "https://x.com/0xRaiden_", - "tags": [ - "cross-chain", - "json-rpc", - "contract-interaction", - "cli", - "abi-encoding" - ], - "website": "zabi.sh", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Raiden1411/zabi", - "stargazers": 113, - "lastUpdated": "2026-01-11T09:24:48Z" - } - ] - }, - { - "id": "0x7e5614eb46520c523562a641649be228012355d0264c9130b2c1d9872bf5bad5", - "name": "ABIExplorer", - "description": "ABI Explorer is like Postman for smart contracts; it allows developers and integrators to test and interact with smart contract functions directly using their ABIs. No need to write custom scripts or spin up a front end, just drop in your ABI, connect your wallet, and start calling functions.\n\nIt’s designed to make life easier for anyone working with smart contracts and also to:\n\nQuickly test read/write functions\n\nSimulate interactions before integrating into your dApp\n\nDebug contract behaviors on any chain, including Optimism\n\n\nWe built this to help streamline contract integration and testing workflows, especially for devs building with on-chain components.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/afd98fa3-7bf7-45a5-9d07-0f1dbea2ba61.png", - "banner_url": "https://storage.googleapis.com/op-atlas/aa144789-e6d6-4af4-9634-7956915bfc8a.png", - "twitter": null, - "tags": [ - "contract-interaction" - ], - "website": "https://abiexplorer.devligence.com/", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/CollinsMunene/abiexplorer", - "stargazers": 3, - "lastUpdated": "2025-05-12T06:35:18Z" - } - ] - }, - { - "id": "0x1e2cc195ce13784ef1e382bbd542a6b25d982b83377a8e8ac2ca593d6c310adc", - "name": "Privacy Builder Pack", - "description": "Hacker Manuals & Privacy Guidelines to help the builders deliver practical privacy-enhancing projects, turn them into products, & scale being sustainable.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/b2e8b33c-2f72-4854-b549-ea8ea9468eca.png", - "banner_url": "https://storage.googleapis.com/op-atlas/b473d908-de6b-45f1-9b19-a3027ef207fc.png", - "twitter": "https://x.com/web3privacy", - "tags": [ - "education", - "encryption" - ], - "website": "https://build.web3privacy.info", - "category": "Education & Community Resources", - "repos": [ - { - "href": "https://github.com/web3privacy/privacy-builder-pack", - "stargazers": 4, - "lastUpdated": "2025-08-05T20:29:07Z" - } - ] - }, - { - "id": "0xa38c8f4ffa48fe01222fe1b5f2bc6c95e204a4f243d67bd0c9f92887d905d3d8", - "name": "Academy", - "description": "Training, incubation, and acceleration programs for non-tech people and devs to start in the web3 privacy ecosystem.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/153bea66-bef0-481d-bb29-2882eb0e6edb.png", - "banner_url": "https://storage.googleapis.com/op-atlas/1809a100-d320-47f2-8144-94343ef5ea40.png", - "twitter": "https://x.com/web3privacy", - "tags": [ - "education" - ], - "website": "https://academy.web3privacy.info/", - "category": "Education & Community Resources", - "repos": [ - { - "href": "https://github.com/web3privacy/cypherpunkacademy", - "stargazers": 7, - "lastUpdated": "2025-02-07T18:51:24Z" - } - ] - }, - { - "id": "0xec7002ee89bf249ae4fca1ebe718a66dea7247e33cfc9319f979a3f9fb324b24", - "name": "Explorer", - "description": "Explorer is a flagship project by Web3Privacy Now that curates and maintains an extensive open-source database of privacy-enhancing tools, use cases, and research. Designed as a public good, it empowers individuals, developers, and organizations to navigate the privacy landscape with greater knowledge and autonomy. Explorer bridges the gap between users and privacy solutions by providing accessible, actionable, and up-to-date resources to foster a culture of privacy within the Web3 ecosystem.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/4b165837-402c-4f39-bc4f-fa5a0b931b8c.png", - "banner_url": "https://storage.googleapis.com/op-atlas/161c3a2f-880d-4617-afda-746e97e7586c.png", - "twitter": "https://x.com/web3privacy", - "tags": [ - "education", - "analytics", - "community-driven" - ], - "website": "https://explorer.web3privacy.info/", - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/web3privacy/explorer-app", - "stargazers": 3, - "lastUpdated": "2025-06-27T15:33:39Z" - }, - { - "href": "https://github.com/web3privacy/explorer-data", - "stargazers": 26, - "lastUpdated": "2026-01-15T03:09:10Z" - } - ] - }, - { - "id": "0xbcfa7063514406f498f2792ae6435bf488709709391cebfa260a552703b4a8f9", - "name": "GDWeb3", - "description": "GDWeb3 is a GDScript library for interacting with blockchain networks(The first support is Optimism). It will provide Web3 game developers with a powerful game development engine. For game developers in the Godot ecosystem, it will offer an SDK for developing blockchain games.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/fae7d370-79b6-48b2-9d69-785cd2edb573.png", - "banner_url": null, - "twitter": null, - "tags": [ - "game-development" - ], - "website": "https://github.com/qingfengzxr/gdscript-web3", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/qingfengzxr/gdscript-web3", - "stargazers": 29, - "lastUpdated": "2025-03-11T12:04:27Z" - } - ] - }, - { - "id": "0x4a5e771af86cf1938056b43cddbf0018dca1376d578f631f7449fe10ac4958ed", - "name": "Nethereum", - "description": "Nethereum is the .Net integration library for Ethereum, simplifying the access and smart contract interaction with Ethereum nodes both public like Geth (or your preferred client) L2 chains like Optimism, Arbitrum (or your preferred L2), any compatible EVM chain (Gnosis, etc) and permissioned chains like Quorum.", - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [ - "cross-chain", - "wallet", - "json-rpc", - "transaction-signing", - "abi-encoding" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Nethereum/Nethereum", - "stargazers": 2245, - "lastUpdated": "2026-01-11T11:50:23Z" - } - ] - }, - { - "id": "0x351967474a454b494260a488f3ceb77d993580a4fe79fb6b6d132c70634bc516", - "name": "Ponder", - "description": "Ponder is an open-source indexing framework for crypto apps focused on performance, reliability and developer experience. Dozens of apps across the Superchain use Ponder to power their websites and mobile applications. Our goal is to enable world-class user experiences that don't compromise on censorship-resistance and decentralization.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/8da31052-61ab-40c2-a9b6-18b0dd37824e.png", - "banner_url": "https://storage.googleapis.com/op-atlas/e46839dc-55fb-45c5-8c47-d3282749cedb.png", - "twitter": "https://x.com/ponder_sh", - "tags": [ - "indexing", - "support", - "developer-experience", - "censorship-resistant", - "performance-optimization", - "event-logging", - "type-safe", - "cli" - ], - "website": "https://ponder.sh", - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/ponder-sh/ponder", - "stargazers": 1023, - "lastUpdated": "2026-01-08T14:53:30Z" - } - ] - }, - { - "id": "0x812ea3d88c189f53197820e1c648dd32c5b937467d93602a3ba5d0b764124f90", - "name": "solizard", - "description": "Super easy interactive shell for interacting with smart contracts", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/401a6212-fc2a-4b46-8a96-52f597c82467.png", - "banner_url": "https://storage.googleapis.com/op-atlas/18896241-e29b-4497-9d12-e27ea0045830.png", - "twitter": "https://x.com/zsystmd", - "tags": [ - "cli", - "contract-interaction" - ], - "website": "https://github.com/zsystm/solizard", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/zsystm/solizard", - "stargazers": 66, - "lastUpdated": "2025-05-08T16:22:42Z" - } - ] - }, - { - "id": "0xbe74d6076f833da93276495074d0356db90c495d3257f8958853e75e9df8e9c8", - "name": "Web3GPT", - "description": "Web3GPT is an AI-powered platform I've developed with the help of some contributors. Web3GPT transforms smart contract development by enabling developers of all skill levels to write, deploy, and verify smart contracts across multiple EVM networks using natural language prompts—no complex configurations or IDEs required. With over 250 AI-generated smart contracts already deployed and verified across different EVM networks, it's proving its capability in the Web3 ecosystem. The platform also supports specialized AI Agents designed for specific functionalities, enhancing your development experience by making it more efficient and tailored to your needs.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/b540988e-6db1-47de-84a4-bebe987ef595.png", - "banner_url": "https://storage.googleapis.com/op-atlas/283678d8-970a-44ee-ba90-419f5359aac5.png", - "twitter": "https://x.com/w3gptai", - "tags": [ - "education", - "cli", - "contract-verification", - "natural-language-processing", - "solidity" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/markeljan/web3gpt", - "stargazers": 112, - "lastUpdated": "2026-01-07T16:16:12Z" - } - ] - }, - { - "id": "0xebe03c3d6d33cad60124b9b05ef6e2ff056293a1de3c5fa51dfbb90c86c14bf7", - "name": "web3.py", - "description": "web3.py is the open source library that connects Python developers to Ethereum. The same team maintains more than a dozen additional building blocks including py-evm, eth-account, and eth-utils.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/287d64ad-b265-41e5-9569-25807ef5bba4.png", - "banner_url": "https://storage.googleapis.com/op-atlas/c4ed28a3-a435-4725-8de3-ef463b073417.png", - "twitter": "https://x.com/EthereumPython", - "tags": [ - "transaction-signing", - "community-driven", - "testing" - ], - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/ethereum/web3.py", - "stargazers": 5472, - "lastUpdated": "2026-01-12T15:23:40Z" - }, - { - "href": "https://github.com/ethereum/py-evm", - "stargazers": 2363, - "lastUpdated": "2025-09-08T15:31:46Z" - }, - { - "href": "https://github.com/ethereum/eth-utils", - "stargazers": 334, - "lastUpdated": "2025-12-17T19:41:25Z" - }, - { - "href": "https://github.com/ethereum/eth-abi", - "stargazers": 253, - "lastUpdated": "2026-01-13T21:49:25Z" - }, - { - "href": "https://github.com/ethereum/eth-account", - "stargazers": 307, - "lastUpdated": "2025-12-19T17:51:20Z" - } - ] - }, - { - "id": "0xa903038c6a307743fdca92164f38d5c392996c2417d66d5bf33012850d0585bf", - "name": "JiffyScan", - "description": "4337 Block Explorer", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/088c8fd2-0f5c-48b2-b3b7-94c72c70cba9.png", - "banner_url": "https://storage.googleapis.com/op-atlas/1818ec80-87d0-4da1-a485-3ef2a43fadfb.png", - "twitter": "https://x.com/jiffyscan", - "tags": [], - "website": "https://www.jiffyscan.xyz/", - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/jiffy-labs/jiffyscan-frontend", - "stargazers": 23, - "lastUpdated": "2025-11-27T15:49:08Z" - } - ] - }, - { - "id": "0xaa4cf223915387f8e0cd66640f86f4f770d0c1edfc4303ce1d596a735747e673", - "name": "Farcaster Attestation", - "description": "Farcaster Attestation is bringing Farcaster wallet verification on-chain to the Optimism Mainnet. Traditionally, Farcaster wallet verification data is only accessible through the Farcaster Hub, which cannot be utilized directly on Optimism Mainnet via Solidity smart contracts. This creates a centralization issue in the Retro Funding EAS schema, limiting the authorized attester to a single wallet, as it requires verification from a centralized backend.\n\nFarcaster Attestation resolves this centralization problem by enabling anyone to attest their Farcaster data permissionlessly.\n\nWe have replicated the Retro Funding Project and Metadata Schema to test the integration with Farcaster Attestation. For more information, refer to the Links section.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/55264cac-23b0-47e1-8cfb-e6691e876eaa.png", - "banner_url": "https://storage.googleapis.com/op-atlas/c502f9bc-fcfe-4696-bf81-f90ed8d9786c.png", - "twitter": null, - "tags": [ - "governance", - "solidity", - "farcaster" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Farcaster-Attestation/op-attest", - "stargazers": 2, - "lastUpdated": "2025-02-24T08:58:05Z" - }, - { - "href": "https://github.com/Farcaster-Attestation/farcaster-resolver", - "stargazers": 2, - "lastUpdated": "2025-05-31T11:59:20Z" - }, - { - "href": "https://github.com/Farcaster-Attestation/farcaster-solidity", - "stargazers": 1, - "lastUpdated": "2025-03-10T09:05:51Z" - } - ] - }, - { - "id": "0xa38f3efb4fb8f6fcefb80f0262645ac05d5548cad0308ee49520c48c4e8cbd1f", - "name": "growthepie 🥧📏 Ethereum and Superchain Analytics", - "description": "growthepie.xyz is a public goods data platform for Ethereum and its scaling solutions, providing essential metrics, onchain data, and educational resources to empower developers and users in making informed decisions.\n\nIt aims to enhance transparency and understanding within the Ethereum ecosystem. It is entirely free to use, with no subscription fees or access limitations, funded primarily through grants and user donations. Key features include fundamental metrics and blockspace exploration, offering insights into chains' and their projects’ activity, value locked, economics, and Data Availability metrics. Our most recent addition are application-specific analytics. We have most of the Superchain covered, constantly adding more along the way. \n\ngrowthepie has been built from zero all in-house with a team of 8 people, with early funding from the Ethereum Foundation, Optimism grants and RPGF as well as Gitcoin and Octant rounds.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/33fec99f-964b-4296-a409-77c4fc4674e8.png", - "banner_url": "https://storage.googleapis.com/op-atlas/1ac64d7c-4267-4be3-80d6-c90bebb7e40c.png", - "twitter": "https://x.com/growthepie_eth", - "tags": [ - "analytics", - "education", - "visualization", - "nextjs", - "tailwind-css", - "community-driven" - ], - "website": "https://www.growthepie.xyz/", - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/growthepie/gtp-frontend", - "stargazers": 11, - "lastUpdated": "2026-01-20T15:22:46Z" - }, - { - "href": "https://github.com/growthepie/gtp-dna", - "stargazers": 4, - "lastUpdated": "2026-01-20T09:36:43Z" - }, - { - "href": "https://github.com/growthepie/gtp", - "stargazers": 28, - "lastUpdated": "2026-01-20T08:48:46Z" - } - ] - }, - { - "id": "0xab6214e09c6adc3022147ba7fffe1924f9bad3ecbe69e410f428808e91fd6f06", - "name": "Zink Language", - "description": "Rustic programming language that targets EVM", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/9b6b9753-121c-4c3f-9a39-c2c48b5cf149.png", - "banner_url": "https://storage.googleapis.com/op-atlas/0d1302f3-d1e0-4fe1-a10e-592b36cb139b.png", - "twitter": "zinkonx", - "tags": [ - "education" - ], - "website": "https://github.com/zink-lang/zink", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/zink-lang/zink", - "stargazers": 171, - "lastUpdated": "2025-04-22T15:32:48Z" - } - ] - }, - { - "id": "0x46d784ec075b98efe6a23e515cad06f1b7081f082cb0c7502c68a7a76c38c9e2", - "name": "DistriButler: Multi Token Sender for Optimism, Base & Arbitrum", - "description": "DistriButler is a powerful multi-token sender Dapp built to streamline airdrops, rewards, and bulk transfers across Optimism, Base, and Arbitrum networks. With a focus on simplicity, security, and efficiency, it allows users to effortlessly send multiple tokens to numerous addresses in a single transaction. DistriButler reduces the complexity of managing large distributions while saving on gas fees, making it an ideal tool for Web3 projects needing efficient token transfers.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/10cc25d9-eb1f-43f2-8126-7927acb952c2.png", - "banner_url": "https://storage.googleapis.com/op-atlas/d6450ca3-f77e-40cf-8799-c61244ab93e3.png", - "twitter": "https://x.com/DistriButler", - "tags": [ - "defi", - "wallet", - "nextjs" - ], - "website": "https://distributler.com/", - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/sifaw23/distributler", - "stargazers": 0, - "lastUpdated": "2025-02-05T18:11:43Z" - } - ] - }, - { - "id": "0xd63cb23c26cc3bda03b1cc2971589fd26c9d22f3bbc8f1ff2bb74613e6d1c36d", - "name": "Solidity Bytes Arrays Utils Library", - "description": "Bytes tightly packed arrays' utility library for ethereum contracts written in Solidity.\n\nThe library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\n\n-----\n\nThe Solidity Bytes Arrays Utils library is a Solidity library I initially wrote 7+ years ago, when Solidity was in its initial days, to be able to handle dynamic bytes arrays through canonical functions like concatenation and slicing.\n\nI have maintained the functional part of its code single-handedly over the years with help around documentation and ideation from a few other contributors.\n\nThis library has been used extensively over the years by some of the biggest projects in the space. Names like Aragon, Maker, Uniswap, Nomad, LayerZero, and, probably more importantly, Optimism, in its initial version.\n\n(Not all projects forked the repo. You can find a big list of forks here: https://github.com/GNSPS/solidity-bytes-utils/forks, the rest can be found by either searching \"BytesLib.sol\" on Google or just searching for parts of the code itself on GitHub.)", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/aa1c84f1-cd10-420c-a730-576e9e1ca7fd.png", - "banner_url": "https://storage.googleapis.com/op-atlas/e5f2c4cb-fb66-4473-973c-1d98a51065a0.png", - "twitter": "https://x.com/gnsps", - "tags": [ - "solidity", - "truffle" - ], - "website": "https://github.com/GNSPS/solidity-bytes-utils", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/GNSPS/solidity-bytes-utils", - "stargazers": 560, - "lastUpdated": "2025-05-22T18:04:26Z" - } - ] - }, - { - "id": "0xc6052138bbdae5976fa2866f46b0537182d4126c4bb97485738d1b43f2276134", - "name": "thirdweb", - "description": "thirdweb is a full stack, open-source web3 development platform with frontend, backend, and onchain tools to build complete web3 apps — on every EVM chain.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/278ce531-3de6-4f4c-8955-877541c7020b.png", - "banner_url": "https://storage.googleapis.com/op-atlas/c78355fc-3512-4554-a6df-70392a31cae2.png", - "twitter": "@thirdweb", - "tags": [ - "frontend", - "cross-chain", - "api", - "chains", - "real-time-data" - ], - "website": "https://www.linkedin.com/company/third-web/", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/thirdweb-dev/insight", - "stargazers": 69, - "lastUpdated": "2025-12-22T18:17:53Z" - }, - { - "href": "https://github.com/thirdweb-dev/js", - "stargazers": 616, - "lastUpdated": "2026-01-16T01:26:04Z" - }, - { - "href": "https://github.com/thirdweb-dev/contracts", - "stargazers": 1077, - "lastUpdated": "2025-08-08T08:21:00Z" - } - ] - }, - { - "id": "0xfb3ac4e5f7665c6560e461c1b77ed896d355635947a6e58e217f345af8624dcd", - "name": "Ackee", - "description": "Ackee is trusted by top-tier organizations in web3. Our mission is to contribute to a stronger blockchain ecosystem by providing security services, tooling and education.", - "thumbnail_url": "https://cdn.charmverse.io/user-content/2d6a8f50-45c2-4658-a66a-74eca1149aa3/102ec612-ed55-4da8-b9fb-0bb3f5447e84/Ackee-Blockchain-Security-logo.jpg", - "banner_url": "https://cdn.charmverse.io/user-content/2d6a8f50-45c2-4658-a66a-74eca1149aa3/f1984493-d1a1-424e-afc1-36e1fc33f573/Ackee-Blockchain-Twitter-Banner.jpeg", - "twitter": "ackeeblockchain", - "tags": [ - "education", - "security", - "solidity", - "static-analysis", - "contract-deployment", - "proxy-contracts" - ], - "category": "Security, Testing & Formal Verification", - "repos": [ - { - "href": "https://github.com/Ackee-Blockchain/solidity-for-vscode", - "stargazers": 52, - "lastUpdated": "2025-11-24T20:31:17Z" - } - ] - }, - { - "id": "0x6d30328dd0e058bdd4c55c51d5f785268770040a66edbd2830902c4d87efee9c", - "name": "Clear Wallet", - "description": "Clear EVM wallet is a fully open-source EVM browser wallet based on Ethers, Ionic, Manifest V3, and Vue. It implements Metamask API and will work as a replacement for Metamask, websites will detect it as Metamask, so select Metamask when interacting with Dapps. Websites that implement EIP-6963 will detect it as Clear EVM Wallet.\n\nIt has been public on Chrome Store since August 2022.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/4aa97110-63e2-4703-a3f5-e42bdebceaee.png", - "banner_url": "https://storage.googleapis.com/op-atlas/50e95639-885c-4657-8141-4a3357fd732e.png", - "twitter": "andrei0x309", - "tags": [ - "wallet", - "frontend", - "privacy-focused" - ], - "website": "https://clear-wallet.flashsoft.eu/", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/andrei0x309/clear-wallet", - "stargazers": 32, - "lastUpdated": "2025-09-03T11:33:28Z" - } - ] - }, - { - "id": "0x5e6c436e48e56d6d9622ba5d0be0035c314e2b29d2afc8f5f1ee8ac75cd42532", - "name": "Snapshot", - "description": "Snapshot started as a voting platform designed to allow onchain organizations to vote easily without gas fees. Its strength lies in its flexibility and high customization, catering to the diverse needs of its users. This includes options for calculating users' voting power, selecting different voting mechanisms, and managing proposal and vote validation rules.\n\nAs the gas cost dropped with the maturity of L2s and the need for more decentralized and trustless voting grew, we developed Snapshot X, an onchain voting protocol. Unlike the original Snapshot, Snapshot X operates fully onchain using a set of modular smart contracts. This shift makes Snapshot censorship resistant, with onchain and cross-chain voting power computation and trustless execution, while keeping gas costs to the minimal extent possible.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/098487bf-4f43-4e5a-8621-9c6368304124.png", - "banner_url": "https://storage.googleapis.com/op-atlas/d76ced7e-7d5e-4514-9706-ca097e3131c2.png", - "twitter": "https://x.com/SnapshotLabs", - "tags": [ - "governance", - "cross-chain", - "decentralized-governance" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/snapshot-labs/snapshot", - "stargazers": 9172, - "lastUpdated": "2025-12-03T20:46:50Z" - }, - { - "href": "https://github.com/snapshot-labs/sx-monorepo", - "stargazers": 47, - "lastUpdated": "2026-01-20T17:06:14Z" - }, - { - "href": "https://github.com/snapshot-labs/sx-evm", - "stargazers": 28, - "lastUpdated": "2025-06-17T14:09:02Z" - } - ] - }, - { - "id": "0x541b7b08401d799b87f583c102a6c94cee7105f1b29dc630de5edbbd966d7c13", - "name": "Fe Language", - "description": "Fe is a high-level language for the EVM. It is heavily inspired by Rust and implemented in it too. You can use Fe to write smart contracts for Ethereum or any EVM-equivalent platform. Currently, we are developing Fe v2, which introduces an improved type system. While it does not yet compile to EVM, users can still analyze their code using the CLI or an editor plugin.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/05ac5706-2a13-4325-8333-183a730e7797.png", - "banner_url": "https://storage.googleapis.com/op-atlas/f733c3ee-3819-40f8-9ee8-b94416a770d9.png", - "twitter": null, - "tags": [ - "cli", - "education", - "compiler", - "code-analysis", - "type-safe" - ], - "website": "fe-lang.org", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/ethereum/fe", - "stargazers": 1715, - "lastUpdated": "2026-01-19T16:09:40Z" - } - ] - }, - { - "id": "0x10e9fc6dd7d01e09bd9440d507846432333a06f779287b29199010e2f50579cd", - "name": "Token Historical Balance", - "description": "The OP Token Historical Balance is a critical tool developed by WakeUp Labs that improves the usability and functionality of the Optimism blockchain. This service empowers developers, analysts, and users by enabling them to query historical blockchain data at any specific moment in time. It supports queries for any public view function of smart contracts deployed on Optimism, from the very first block to the present. By providing access to historical state data, this project directly supports transparency, research, and analytics, which are crucial for the evolution and understanding of the Optimism ecosystem.\n\nOur project contributes to the OP Stack Tooling category by providing a fundamental utility that facilitates better decision-making, auditing, and research within the Optimism network. This tool is vital for developers who require accurate historical data to test, validate, and optimize their applications. Additionally, it promotes the growth of the Optimism ecosystem by reducing barriers to entry and fostering a more robust environment for innovation.\n\nWakeUp Labs is dedicated to advancing the capabilities of Ethereum's Layer 2 solutions, and we believe that tools like the OP Token Historical Balance are essential for driving adoption and enhancing the overall developer experience. By making Optimism's blockchain data more accessible and usable, we aim to empower the community and fuel the next wave of development on the OP Stack.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/ae73d3f5-61cc-48ef-84e9-2b553d1f0739.png", - "banner_url": "https://storage.googleapis.com/op-atlas/46c64ba6-5c38-4bc0-9ac7-d32a55a32637.png", - "twitter": "x.com/wakeuplabs", - "tags": [ - "analytics", - "layer-2", - "visualization" - ], - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/wakeuplabs/rfg1-optimism", - "stargazers": 2, - "lastUpdated": "2024-09-04T19:12:33Z" - } - ] - }, - { - "id": "0x51cda5996ef1a2ccd8fcf4ee5792337695599454c83eb1218c3ad4388dcb5bf5", - "name": "Sourcify", - "description": "Sourcify is a decentralized and open-source smart contract verification service", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/f219ada1-9d7d-4d1c-8a90-ea1b09eda31f.png", - "banner_url": "https://storage.googleapis.com/op-atlas/3d5c829b-3fc4-4dcd-995d-978aceca64dc.png", - "twitter": "https://twitter.com/sourcifyeth", - "tags": [ - "solidity", - "vyper", - "api", - "cli", - "type-safe" - ], - "website": "https://sourcify.dev", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/ethereum/sourcify", - "stargazers": 896, - "lastUpdated": "2026-01-20T07:36:20Z" - } - ] - }, - { - "id": "0xd4ed99cc6aaf73ca63b32f7a03b5427ac1d2955bf9efc31eb14f5773016988d0", - "name": "AWS KMS and YubiHSM signer for OP Stack", - "description": "We have developed a signer proxy software that enables the OP Stack chain to use an external signer (currently supporting AWS KMS and YubiHSM) through the official signer client to signer the sequencer, batcher, proposer and challenger transactions. However, the official signer client does not integrate with external signers, so we have implemented this functionality in our signer proxy.\n\nCurrently, the process outlined in the Optimism documentation for setting up a sequencer, batcher, and proposer requires using plain private keys, creating an insecure environment for mainnet deployment. Although the documentation suggests using hardware security modules (HSMs) for key management, it lacks detailed guidance beyond referencing source code. Chain operators, particularly those using bare metal setups, often prefer YubiHSM2 over cloud-based solutions like AWS KMS due to its hardware-native security.\n\nTo enhance security, mainnet chain operators are encouraged to use industry-standard hardware signers like YubiHSM2 or AWS KMS. This approach allows operators to deploy Optimism stack chains securely by protecting private keys with hardware-based solutions. Existing resources, such as the integration of YubiHSM2 into the Keplr wallet and the TMKMS YubiHSM installer, provide relevant experiences that support this approach.\n\nOur AWS KMS Signer proxy has been used by the Lisk team for their op-challenger. We are working with them to make signer proxy perfect and production ready.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/a73d46f5-87ba-4204-88eb-7ce51ab055de.png", - "banner_url": "https://storage.googleapis.com/op-atlas/ffb2a694-74be-48f3-897d-96034c088b3a.png", - "twitter": null, - "tags": [ - "security", - "docker", - "transaction-signing" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/upnodedev/signer-proxy", - "stargazers": 14, - "lastUpdated": "2025-05-02T11:55:02Z" - } - ] - }, - { - "id": "0xa0b16714baef75d97ec07fd48eaf42e79df92fe2a3c2d725d2388ede587ea54c", - "name": "Ape Framework", - "description": "The smart contract development tool for Pythonistas, Data Scientists, and Security Professionals", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/ab983e5d-4c75-4fc9-9b02-187a4f479c8a.png", - "banner_url": "https://storage.googleapis.com/op-atlas/238f7d0e-c18b-48ad-8e9a-24407ef90eaf.png", - "twitter": "https://twitter.com/ApeFramework ", - "tags": [ - "cross-chain", - "layer-2", - "cli" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/ApeWorX/silverback", - "stargazers": 128, - "lastUpdated": "2026-01-19T22:53:09Z" - }, - { - "href": "https://github.com/ApeWorX/ape", - "stargazers": 1023, - "lastUpdated": "2026-01-19T18:11:07Z" - }, - { - "href": "https://github.com/ApeWorX/ape-optimism", - "stargazers": 13, - "lastUpdated": "2025-02-07T20:11:15Z" - }, - { - "href": "https://github.com/ApeWorX/ape-base", - "stargazers": 2, - "lastUpdated": "2025-12-10T20:50:50Z" - } - ] - }, - { - "id": "0x81af86360a8e964cc907a5689a62e94231c7e42e05f49c0586716975d72e2e2e", - "name": "Upnode Deploy", - "description": "Upnode Deploy allows chain operators and developers to quickly launch their OP Stack chain with the necessary infrastructure, including an explorer, bridge, faucet, and monitoring system, by modifying a few environment variables related to the RPC endpoint, private keys, and chain information.\n\nWith a single Docker Compose command, they can launch and manage every component of the OP Stack chain, including the ability to deploy a replica node by providing `rollup.json` and `genesis.json`. Upnode Deploy also offers a user interface similar to Conduit, which simplifies the OP Stack deployment process.\n\nUnlike Conduit, Upnode Deploy provides developers and chain operators with a tool to deploy OP Stack chains on their own servers instead of relying on third-party managed servers. Upnode Deploy is free, open-source, and fully transparent, whereas Conduit is a paid, closed-source solution.\n\nUpnode Deploy supports the latest OP Stack v1.9.0 and is prepared for the upcoming migration from `pnpm` to `just`.\n\nUpnode Deploy has won Fraxtal Hackathon: https://dorahacks.io/buidl/13971\n\nVideo of docker compose deploying an OP Stack L3 on Fraxtal: https://www.youtube.com/watch?v=8dytrXGjDG4", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/91ebe6cd-12a6-42fb-b3ef-d717e79ac9b8.png", - "banner_url": "https://storage.googleapis.com/op-atlas/84ec5980-5e06-4630-92b4-16ce9e9e3f83.png", - "twitter": "https://x.com/upnodeIntern", - "tags": [ - "cli", - "docker", - "devops" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/upnodedev/opstack-cli", - "stargazers": 5, - "lastUpdated": "2025-05-13T14:31:21Z" - }, - { - "href": "https://github.com/upnodedev/opstack-bridge-ui-v2", - "stargazers": 0, - "lastUpdated": "2024-12-03T09:11:37Z" - }, - { - "href": "https://github.com/upnodedev/evm-faucet", - "stargazers": 0, - "lastUpdated": "2024-09-03T18:43:46Z" - }, - { - "href": "https://github.com/upnodedev/upnode-deploy-ui", - "stargazers": 0, - "lastUpdated": "2024-10-31T10:15:16Z" - }, - { - "href": "https://github.com/upnodedev/opstack-compose", - "stargazers": 12, - "lastUpdated": "2024-10-11T16:20:03Z" - }, - { - "href": "https://github.com/upnodedev/opstack-bridge-ui", - "stargazers": 0, - "lastUpdated": "2024-09-03T18:46:42Z" - }, - { - "href": "https://github.com/upnodedev/opstack-bridge-indexer", - "stargazers": 1, - "lastUpdated": "2024-09-03T18:49:14Z" - }, - { - "href": "https://github.com/upnodedev/opstack-bridge-indexer-v2", - "stargazers": 0, - "lastUpdated": "2024-10-29T12:59:44Z" - } - ] - }, - { - "id": "0x7504e494cb8d227193182e083128912173c14eaeecec9b90fa453de28377b269", - "name": "Hermes - a GossipSub listener and tracer for libp2p-based networks.", - "description": "The ProbeLab team has recently built Hermes, a GossipSub listener and tracer for libp2p-based networks. Hermes-based experiments aim to measure the efficiency and performance of the GossipSub message broadcasting protocol in any libp2p-based network. Acting as a light node of sorts, Hermes can help developers collect valuable data and tune their network’s protocols based on the message propagation latency, control message overhead and a variety of other metrics. Hermes currently supports the Ethereum consensus layer network.\n\nThe ProbeLab team specialises in network-layer measurements and monitoring. The team operates a variety of tools and uses the data it collects to propose network protocol optimisations.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/90c0de0c-cc0e-4959-afb7-a78ae4c9d674.png", - "banner_url": "https://storage.googleapis.com/op-atlas/e1d59a51-3f6f-4642-bc88-553026d2d067.png", - "twitter": "@yiannisbot", - "tags": [ - "governance", - "gossipsub", - "libp2p", - "cli" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/probe-lab/hermes", - "stargazers": 43, - "lastUpdated": "2025-12-04T10:35:24Z" - } - ] - }, - { - "id": "0xada9c2eabe94a7af5d96b3cb1765c8e3d6fb8a7f8e33f12ebd6d66feb1a807a3", - "name": "Curvegrid MultiBaas", - "description": "Curvegrid offers cutting-edge solutions for blockchain application development. Curvegrid's flagship product, MultiBaas, streamlines the DApp development process with a user-friendly web UI and a robust REST API. Supporting multiple EVM chains, MultiBaas accelerates time-to-market for sectors including finance, DeFi, gaming, art, and logistics.", - "thumbnail_url": "https://cdn.charmverse.io/user-content/cae02d37-eadb-4a01-a063-d72588a78203/a6dfa7b6-3b1c-4ff3-b5e5-f82624024c5e/Icon-(Color).svg", - "banner_url": "https://cdn.charmverse.io/user-content/cae02d37-eadb-4a01-a063-d72588a78203/3151e0b3-b99e-4da6-9fdf-e98c3e985c22/Curvegrid-Banner-(1).png", - "twitter": "https://x.com/curvegridinc", - "tags": [ - "defi" - ], - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/curvegrid/multibaas-sdk-go", - "stargazers": 3, - "lastUpdated": "2025-10-24T08:08:31Z" - }, - { - "href": "https://github.com/curvegrid/multibaas-sdk-typescript", - "stargazers": 5, - "lastUpdated": "2025-10-24T08:08:51Z" - }, - { - "href": "https://github.com/curvegrid/multibaas-for-google-sheets", - "stargazers": 15, - "lastUpdated": "2025-05-09T03:14:38Z" - }, - { - "href": "https://github.com/curvegrid/multibaas-sample-app", - "stargazers": 19, - "lastUpdated": "2025-09-24T11:47:38Z" - }, - { - "href": "https://github.com/curvegrid/hardhat-multibaas-plugin", - "stargazers": 11, - "lastUpdated": "2025-11-28T10:07:41Z" - }, - { - "href": "https://github.com/curvegrid/" - } - ] - }, - { - "id": "0xdd8b2e68cad9afa0701c8f27bf085302b152dbca3393083d3c664e3fc75945ab", - "name": "Redprint", - "description": "Redprint toolkit, is a toolchain and knowledge hub to improve OPStack accessibility, tailored for developer. It includes:\n\n1) Redprint wizard: It is a code generator/ interactive playground to debug/modify OPStack ’s codebase. It supports a space to experience, and build features which aren't yet available on the production at all, empowering developers to tinker, and push the boundaries of what's possible by composing their own different OPStack components together. \n\n2) redprint-forge: It is a developer-friendly framework/library in solidity to deploy OPStack ’s contracts in a modular style. It supports type-safe smart contract deployment, re-usable testing pipeline, all-Solidity-based ( no context switching), and tx Management via Safe Smart Contract Deploy Script", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/3cc6bd19-1ade-4c0d-8fe3-ec6ea6f50183.png", - "banner_url": "https://storage.googleapis.com/op-atlas/d2d120fb-11fa-456c-b7e0-b0ed52b477e0.png", - "twitter": "", - "tags": [ - "education", - "frontend", - "solidity", - "type-safe" - ], - "website": "https://redprint.ninja/", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Ratimon/redprint-forge", - "stargazers": 51, - "lastUpdated": "2025-02-15T09:07:50Z" - }, - { - "href": "https://github.com/Ratimon/redprint-wizard", - "stargazers": 55, - "lastUpdated": "2025-04-21T02:52:44Z" - } - ] - }, - { - "id": "0x11a2255f272c84328438f5081139455d8fd2a302fd35f0f08acdff1f1c0d84e6", - "name": "Node Guardians", - "description": "Node Guardians is a gamified educational platform for intermediate to advanced developers. We create lore-rich programming challenges for accomplished Solidity developers. Think of it as a skill-based RPG for developers and a platform to showcase their abilities. ", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/6878f254-b99f-47ad-8cf8-7f6cd1601300.png", - "banner_url": "https://storage.googleapis.com/op-atlas/8f285391-e69f-40f3-aa14-1456fbb92440.png", - "twitter": "https://x.com/nodeguardians", - "tags": [ - "education", - "solidity" - ], - "website": "https://nodeguardians.io/", - "category": "Education & Community Resources", - "repos": [ - { - "href": "https://github.com/Nodeguardians/optimism", - "stargazers": 0, - "lastUpdated": "2024-09-03T14:22:05Z" - } - ] - }, - { - "id": "0xcc8d03e014e121d10602eeff729b755d5dc6a317df0d6302c8a9d3b5424aaba8", - "name": "Solidity", - "description": "Solidity is an object-oriented, high-level language for implementing smart contracts.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/b6f312d0-1025-4a19-baa9-3aa218fe0833.png", - "banner_url": "https://storage.googleapis.com/op-atlas/bca65077-a87b-4fd8-bcc3-9ad0a65d9d27.png", - "twitter": "https://x.com/solidity_lang", - "tags": [ - "education", - "solidity", - "compiler", - "cli" - ], - "website": "https://soliditylang.org/", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/ethereum/solidity", - "stargazers": 25502, - "lastUpdated": "2026-01-19T23:37:55Z" - }, - { - "href": "https://github.com/ethereum/solc-js", - "stargazers": 1503, - "lastUpdated": "2025-12-18T20:41:21Z" - } - ] - }, - { - "id": "0x1aacb85f1d87039696b876ddcae98c56d38ea9eed07b265409fdb256c8f8172a", - "name": "Blockhead", - "description": "Open-source portfolio tracker and explorer interface for the decentralized web. https://blockhead.info", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/3a1343aa-8bb3-4f30-abc0-6ba02dd3787a.png", - "banner_url": "https://storage.googleapis.com/op-atlas/7c1ee7ff-ad46-4b74-a941-48cc7ddc2dbe.png", - "twitter": "https://x.com/0xBlockhead", - "tags": [ - "block-explorer" - ], - "website": "https://blockhead.info", - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/darrylyeo/blockhead", - "stargazers": 135, - "lastUpdated": "2025-05-18T04:45:05Z" - } - ] - }, - { - "id": "0xdf1bb03d08808e2d789f5eac8462bdc560f1bb5b0877f0cf8c66ab53a0bc2f5c", - "name": "Rust Libp2p", - "description": "The rust implementation of libp2p. Libp2p is a modular framework for a variety of p2p protocols. These protocols are used widely by a variety of projects to establish p2p communications in a decentralized manner.\n\nThe rust implementation is used by a variety of projects in the space including, Magi (OP Stack rollup client), Lighthouse (Ethereum consensus client) and Forest (Filecoin client). \n\nThe rust implementation specifically, is used by a variety of projects in the ", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/352a5108-5f07-4765-a43d-7ba0b4b27054.png", - "banner_url": "https://storage.googleapis.com/op-atlas/01e43966-8955-4584-b45d-84645a97dc5d.png", - "twitter": "@sigp_io", - "tags": [ - "docker", - "community-driven" - ], - "website": "https://sigmaprime.io", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/libp2p/rust-libp2p", - "stargazers": 5368, - "lastUpdated": "2026-01-19T16:03:13Z" - } - ] - }, - { - "id": "0x9b014e8a2e062401d976745d9c8aafbf36bce7931586b36ecf3b9ad708bf2970", - "name": "Blobscan", - "description": "**About Blobscan**\n\nBlobscan is the first open-source blockchain explorer designed to navigate and visualize shard blob transactions introduced in EIP-4844. It provides essential public infrastructure to help scale Ethereum, featuring:\n\n- 🔍 Advanced blob search and filtering\n- 🧠 Rich blob decoding (including Starknet and Optimism support)\n- 🗃 Multiple persistent blob storage integrations\n- 📊 A detailed analytics dashboard\n- 🔌 An API for querying blobs and metrics\n- 🐳 Docker and Kubernetes-ready deployment options\n\nOur mission is to make blob data accessible, transparent, and usable for the entire Ethereum ecosystem.\n\n**Who We Are**\n\nWe’re a small team of four developers (3 fullstack engineers and one DevOps specialist) fully committed to pushing Blobscan forward as a vital part of Ethereum’s scaling roadmap.\n\n**Recent Milestones & Updates**\n\nWe’ve shipped a number of important updates and new features, including:\n\n**🔧 Core Improvements**\n\n- Collaboration with ethPandaOps to prepare for the Dencun fork.\n- Collaboration with Load Network (prev. WeaveVM) as a new blob storage solution\n- Partnered with Ethereum Swarm, now sponsoring one year of blob storage\n- Expanded support for a total of 72 rollups.\n\n**🌐 Website Enhancements**\n\n- Introduced powerful search filters: by **slot, block, date range, and rollup**\n- Launched **rollup-level metrics** and statistics\n- Added **initial decoding support for Starknet and Optimism blobs**\n- Major improvements to the **mobile experience**\n- Numerous frontend performance and usability enhancements\n\n**🛠 DevOps & Developer Experience**\n\n- Re-architected the platform for better scalability and maintainability\n- Made Blobscan **Kubernetes-ready**\n- Improved Docker images — now **10x smaller and faster**\n- Published a **detailed deployment guide** using Kurtosis and Kubernetes\n- Revamped and expanded documentation\n\n**Funding & Outlook**\n\nBlobscan is currently supported by **Optimism RetroPGF**, and we’re incredibly grateful for this backing. We love working on Blobscan and have an exciting roadmap of improvements ahead — including deeper blob analytics, enhanced rollup-specific features, and broader ecosystem integrations.\n\nWe see Blobscan as a vital public good for Ethereum’s future and are committed to delivering the tools the ecosystem needs to thrive.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/af580f21-8a05-40b2-b839-aaed37495186.png", - "banner_url": "https://storage.googleapis.com/op-atlas/6fee849e-314e-4285-92d9-b6b27d09f4a3.png", - "twitter": "https://x.com/blobscan", - "tags": [ - "analytics", - "docker", - "frontend", - "visualization" - ], - "website": "https://blobscan.com/", - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/Blobscan/blobscan-helm-charts", - "stargazers": 0, - "lastUpdated": "2025-09-08T19:57:42Z" - }, - { - "href": "https://github.com/Blobscan/blobscan-indexer.rs", - "stargazers": 44, - "lastUpdated": "2026-01-08T02:45:59Z" - }, - { - "href": "https://github.com/Blobscan/blobscan", - "stargazers": 101, - "lastUpdated": "2026-01-15T15:23:13Z" - }, - { - "href": "https://github.com/Blobscan/blobscan-infra", - "stargazers": 3, - "lastUpdated": "2026-01-16T17:56:35Z" - } - ] - }, - { - "id": "0xd9d413772483111ca8ecfe5054737c6c80a65f03c0d289c632b05e3ec21d5680", - "name": "Opstack Kit", - "description": "Bridging hooks for OP Stack Chains\nnpm i opstack-kit | is a toolkit for all upgrades. To easily connect and interact with the OP-Stack (Superchain)\n\n📝 - Focus on Your Dapp\nEffortlessly create awesome OP-Stack (Superchain) sites with just npm i opstack-kit.\n\n🧑‍💻 - Enjoy the \"opstack-kit\"\nInstant server start, lightning fast hot updates, and leverage OP-Stack (Superchain) ecosystem.\n\n⚙️ - Customize with OP-Stack\nUse syntax and components directly in \"opstack-kit\", or build custom themes.\n\n🚀 - Ship Fast Sites\nStart creating quickly \"opstack-kit\" after that deploy it to your network.\n\nFeatures\n- Simplifies cross L1 & L2 interactions\n- Supports \"CustomGasToken\" deposit & withdrawal functions\n- Supports multi-functionality & new fault-proof feature\n- CLI command development tools (prove, finalize)", - "thumbnail_url": "https://cdn.charmverse.io/user-content/e3eb66db-408b-4e21-bc69-c2927fd15b32/552ea203-8cee-4111-9a61-82fd3da74367/ok.png", - "banner_url": "https://cdn.charmverse.io/user-content/e3eb66db-408b-4e21-bc69-c2927fd15b32/874ceabb-8637-48ef-935d-747218d514fc/opstackkit-cover.jpg", - "twitter": "opstackkit", - "tags": [ - "cli", - "cross-chain" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/opstack-kit/opstack-kit", - "stargazers": 17, - "lastUpdated": "2025-02-23T16:58:53Z" - } - ] - }, - { - "id": "0x5a7e7c7acb21521e99021d746740b368801cbfe531301e50bdbaafdc24a0aac5", - "name": "js-libp2p", - "description": "The canonical JavaScript implementation of libp2p. Js-libp2p is a collection of protocols that support a wide range of functionalities, such as; connection establishment, remote node protocol identification and negotiation (through its identify protocol), data encryption, content/peer discovery (through its Kademlia DHT component), and data transfer through its pub-sub protocol (Gossipsub).\n\nThe stakeholders of js-libp2p include the Interplanetary Shipyard team who maintain this implementation as well as projects that depend on js-libp2p like major on-chain builder apps like Farcaster. Farcaster contracts are deployed on Optimism and they rely directly on js-libp2p in Farcaster Hubs (transports and protocols like GossipSub).\n\nAdditionally, ChainSafe's Lodestar (Ethereum consensus client written in Typescript), Ocean Protocol (in their Ocean Nodes implementation), OrbitDB (a serverless, distributed, peer-to-peer database), Warden Protocol, and many more: https://github.com/libp2p/js-libp2p/tree/main#used-by and https://github.com/libp2p/js-libp2p/network/dependents.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/11d09c62-9356-40b2-9cd2-06b98f816bfb.png", - "banner_url": "https://storage.googleapis.com/op-atlas/826fafd9-28a8-49f8-9d07-0e5e57880f20.png", - "twitter": "https://x.com/ipshipyard", - "tags": [ - "libp2p", - "encryption", - "gossipsub" - ], - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/libp2p/js-libp2p", - "stargazers": 2520, - "lastUpdated": "2026-01-16T15:40:11Z" - } - ] - }, - { - "id": "0xc71faa1bcb4ceb785816c3f22823377e9e5e7c48649badd9f0a0ce491f20d4b3", - "name": "go-libp2p", - "description": "The canonical Golang implementation of libp2p. Go-libp2p is a collection of protocols that support a wide range of functionalities, such as; connection establishment, remote node protocol identification and negotiation (through its identify protocol), data encryption, content/peer discovery (through its Kademlia DHT component), and data transfer through its pub-sub protocol (Gossipsub).\n\nThe stakeholders of go-libp2p include the Interplanetary Shipyard team who maintain this implementation as well as projects that depend on go-libp2p like Optimism's op-node (the reference implementation of the rollup-node spec), the Ethereum Beacon Chain (via Prysm, the Go consensus client), Filecoin (Lotus and Venus), Celestia node, and many more: https://github.com/libp2p/go-libp2p?tab=readme-ov-file#notable-users.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/277d8353-44c4-4e16-a2bd-2dfb3fb9e65f.png", - "banner_url": "https://storage.googleapis.com/op-atlas/4c70ca4a-8b38-47ee-97d0-2a64a63700f8.png", - "twitter": "https://x.com/ipshipyard", - "tags": [ - "governance", - "libp2p", - "peer-to-peer", - "networking", - "encryption", - "gossipsub", - "community-driven" - ], - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/libp2p/go-libp2p", - "stargazers": 6683, - "lastUpdated": "2026-01-08T19:05:11Z" - } - ] - }, - { - "id": "0xa7d78d566bfa319479ec048c94c3d8c1f4d628a9344ba157fc4974dbf472dc3e", - "name": "Aderyn", - "description": "Aderyn is an open-source, public-good developer tool. It is a Rust-based solidity smart contract static analyzer designed to help protocol engineers and security researchers find vulnerabilities in Solidity code bases.\n\nAderyn integrates seamlessly into small and enterprise-level development workflows. It offers lightning-fast, command-line static analysis functionality and a framework for building custom detectors that adapt to any Solidity codebase.\n\nAderyn does three things really well:‍‍‍\nIdentify Solidity Smart contract vulnerabilities: Cyfrin Aderyn quickly identifies potential vulnerabilities in Solidity code and highlights parts of the codebase for further investigation.\n\nSupports building custom detectors to suit your needs: Protocols and security researchers can use the Cyfrin Aderyn framework to build custom vulnerability detectors for any Solidity codebase.\n\nIdentify known issues and protect OP value: Competitive auditing platforms can use Cyfrin Aderyn to detect and filter out known issues inside protocol codebases, protecting customers' and auditors' time and value.\n\nWho is it for?\n\n1. Developers\nAs a new generation of developers enters the space, we (the security community) are responsible for using our knowledge and experience to create tools that facilitate secure development practices. We need to make it easy to avoid repeating past mistakes.\n\nFrom a developer's perspective, the cost of finding bugs in Solidity code is exorbitantly high. Engaging top-tier security firms like Cyfrin Private Audits or competitive audit platforms like CodeHawks requires serious cash. That's because the security knowledge required to stamp out bugs is pooled among security firms and competitive auditors, who are in demand.\n\nWe must drive the cost of finding bugs, especially the common and known ones, towards zero by creating tools that make development secure by nature.\n\nAderyn is built for lightning-fast, open-source static analysis that hooks into the existing development workflow.\n\n2. Security Researchers\nSecurity Researchers are the knowledge guardians of the on-chain world. They are the people you engage with when you're undergoing an audit. Many auditors start every audit with a long checklist. They read through the codebase, ensuring the code doesn't violate any items on their list. If it does, it's an issue for the report. Once they've finished with this list, they get creative and try out other techniques.\n\nAderyn's detector framework enables Security Researchers to encode the patterns they look for in their checklist into Aderyn detectors. By doing this, the research community can focus on the deeper, more complex bugs, knowing that tooling has uncovered the repetitive checklist of issues so they don't have to.\n\nDevelopers write more secure code before they engage Security Researchers, and when they do, the Researchers can spend more time on complex bugs instead of manually checking for easy fixes.\n\nWhat makes Aderyn unique vs similar tools?\nSpeed: Real-time feedback as you’re coding with the upcoming vscode extension.\n\nCutting-edge detectors: The detectors are built from the latest findings from external and in-house auditors. This means developers can harness the power of an audit team at their fingertips for free!\n\n“Auditor Mode”: Helps auditors find specific areas and concepts within a codebase to dig further. For example, “Show me all of the instances in which this storage slot is altered”.\n\nOpen-source: This tool is completely open-source and will be free for all developers in perpetuity. Cyfrin does not make money directly from it.\n\nAdoption of tool: Aderyn is now used by developers across the Superchain ecosystem and we are continuously building new custom detectors for developers. \n\nImportance of tool: Security is paramount for mass adoption. Without security, adding any TVL to the Superchain is risky. We want to support developers from day zero and provide real time security analysis whilst projects are being built.\n\nSuperchain interoperability: We want to ensure that when working cross chain, builders are doing so with secure frameworks. We also include building customer detectors for interoperability. \n\nWho are Cyfrin:\nCyfrin is the industry-leading smart contract education and security company. Home to 8,000 security researchers and a community of over 100,000 students and smart contract engineers, we provide audits, tools, and education to the world's biggest decentralized protocols, institutions, and products.\n\nCyfrin works closely with Optimism and the Superchain as a whitelisted security service provider. We want to continue adding value to the Optimims ecosystem. \n\nThis project refers specifically to Cyfrin's developer tool, Aderyn.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/0c66d95b-8f82-45a2-87a8-77205bf90a96.png", - "banner_url": "https://storage.googleapis.com/op-atlas/dcb9e7e2-4619-4382-af31-a5c9a75e703f.png", - "twitter": "https://x.com/CyfrinAudits", - "tags": [ - "cli", - "security", - "education", - "solidity", - "static-analysis", - "vscode-extension", - "community-driven" - ], - "website": "https://github.com/Cyfrin/aderyn", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Cyfrin/aderyn", - "stargazers": 705, - "lastUpdated": "2026-01-19T09:07:41Z" - } - ] - }, - { - "id": "0x7348ae42266ff626319e8ea5398343b847603b3cc7101b03d8e4fb2b75ea8db3", - "name": "Kontrol - formal verification tool based on Foundry and KEVM", - "description": "Runtime Verification has been at the forefront of open-source formal verification tools for more than a decade. Our generalistic approach allows us to use our technology on multiple blockchains. While KEVM offers our verification infrastructure to all EVM-based smart contracts, Kontrol greatly reduces the barrier to entry to formal verification for Solidity smart contracts.\nOur tooling is completely open source and freely accessible to all developers of the Optimism ecosystem at no additional cost.\n\nKEVM is an EVM executable formal semantics written in the K framework. KEVM passes all Ethereum conformance tests and is the entry point for formally verifying smart contracts with the K framework. However, using plain KEVM requires ad-hoc training on the K framework to write specifications. Additionally, these specifications can be quite verbose, increasing the difficulty of writing them.\n\nKontrol solves this by allowing developers to write the formal specification of their smart contracts directly as Foundry property tests. These tests are automatically translated into KEVM specifications, keeping all the verification guarantees whilst allowing for a much more easy developer experience.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/1dce415e-060b-4f57-83ed-71ba91207614.png", - "banner_url": "https://storage.googleapis.com/op-atlas/e0035388-4b23-4215-98e3-c96e712cc18c.png", - "twitter": "https://x.com/rv_inc", - "tags": [ - "foundry", - "education", - "governance", - "formal-verification", - "solidity", - "runtime-verification", - "contract-deployment", - "static-analysis" - ], - "category": "Security, Testing & Formal Verification", - "repos": [ - { - "href": "https://github.com/runtimeverification/_audits_lidofinance_dual-governance_fork", - "stargazers": 1, - "lastUpdated": "2025-02-18T20:57:22Z" - }, - { - "href": "https://github.com/runtimeverification/yearn-v3-term-vault", - "stargazers": 0, - "lastUpdated": "2025-02-19T16:34:35Z" - }, - { - "href": "https://github.com/runtimeverification/kontrol", - "stargazers": 87, - "lastUpdated": "2025-12-19T15:44:45Z" - }, - { - "href": "https://github.com/runtimeverification/Depeg-swap", - "stargazers": 0, - "lastUpdated": "2025-02-19T16:33:07Z" - }, - { - "href": "https://github.com/runtimeverification/optimism-ci", - "stargazers": 4, - "lastUpdated": "2025-02-18T20:03:05Z" - }, - { - "href": "https://github.com/runtimeverification/_audits_Ethereum-optimism_pausability", - "stargazers": 0, - "lastUpdated": "2025-06-06T08:42:21Z" - } - ] - }, - { - "id": "0x229bbc8163bdee3891cde1c18c74ab3afc72e8683692fc7f1b767570cbe7c4a7", - "name": "EVM Explorer", - "description": "We are excited to introduce EVM Explorer, a powerful, open-source web interface designed to streamline the exploration and analysis of blockchain data across multiple EVM chains, including the Optimism ecosystem. EVM Explorer utilizes the BlockScout API and viem library to enable users to delve into transaction patterns, user behavior, and smart contract data, providing a versatile tool for efficient and insightful blockchain exploration.", - "thumbnail_url": "https://cdn.charmverse.io/user-content/9c114ea1-adb5-4858-b4f2-40050fa74370/99b90eeb-a7ea-4ca6-938e-410fff892510/Social.png", - "banner_url": "https://cdn.charmverse.io/user-content/9c114ea1-adb5-4858-b4f2-40050fa74370/b2606c27-a963-43aa-8e78-e38e89897808/pexels-mont-photographs-385313-2948636.jpg", - "twitter": "https://x.com/ExplorerEVM", - "tags": [ - "analytics", - "governance", - "chains", - "visualization" - ], - "website": "https://evmexplorer.com/", - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/Pfed-prog/NextJsExplorer", - "stargazers": 25, - "lastUpdated": "2026-01-12T18:29:39Z" - }, - { - "href": "https://github.com/Pfed-prog/EVMExplorer-Blockscout", - "stargazers": 2, - "lastUpdated": "2025-12-24T22:07:19Z" - }, - { - "href": "https://github.com/Pfed-prog/EVMExplorer-Uniswap", - "stargazers": 1, - "lastUpdated": "2025-10-07T11:46:23Z" - }, - { - "href": "https://github.com/Pfed-prog/EVMExplorer-Utility", - "stargazers": 1, - "lastUpdated": "2025-10-07T10:46:13Z" - } - ] - }, - { - "id": "0x2c97e213fef2bd3f30a71edf6ed48232640368d0083dc0a134a1b59391639bde", - "name": "hevm", - "description": "hevm is an open source, state-of-the art, fast symbolic and concrete EVM execution engine that can find issues in smart contracts. Through its symbolic execution and analysis system, hevm can symbolically, semi-concretely, or concretely execute contracts to find bugs, or compare two different contracts for discrepancies, performing equivalence checking. \n\nHevm is used in Echidna for concrete execution, mamory.xyz to detect potential (economic) MEV extraction, and by the Vyper team to help find potential bugs in compiler optimizations. Hevm can be used both as a console tool and as a library interface, allowing it to be part of high level tooling, such is the case with Echidna, where both its concrete and symbolic execution semantics are exercised.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/d7cf4059-4f9c-48aa-a37a-df2f8c81933c.png", - "banner_url": "https://storage.googleapis.com/op-atlas/020d34f6-e8bb-43b5-8508-7935d2b00583.png", - "twitter": null, - "tags": [ - "cli", - "foundry", - "security", - "symbolic-execution" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/ethereum/hevm", - "stargazers": 326, - "lastUpdated": "2026-01-20T14:44:24Z" - } - ] - }, - { - "id": "0xf2a60464d2a56fb47d2f8c13001edea71eda11ffd8fffec5f559495c6a5878d4", - "name": "Unruggable ", - "description": "Unruggable is focused on building the next generation of blockchain-based naming services. Our mission is to create secure and user-friendly solutions that enable projects and Layer 2 networks to establish their own naming systems using the Ethereum Name Service (ENS). As part of our commitment to open-source software development, we provide essential infrastructure that allows everyone to benefit from the scaling of ENS and L2 blockchains:\n\n'Unruggable Gateways' is an open source codebase that implements a complete solution for fetching proofs of data from rollup chains and verifying that data on Layer 1 Ethereum. We operate our own gateways using the codebase and are committed to supporting the trustless resolution of ENS names.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/ff2964ec-4435-4cf8-b993-e16f49b47b96.png", - "banner_url": "https://storage.googleapis.com/op-atlas/58530a8a-1957-45c8-92dd-808196c1491f.png", - "twitter": "https://x.com/unruggable_eth", - "tags": [ - "cross-chain", - "layer-2", - "verification", - "solidity", - "scalability" - ], - "website": "https://unruggable.com/", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/unruggable-labs/unruggable-gateways-examples", - "stargazers": 5, - "lastUpdated": "2025-10-13T15:50:04Z" - }, - { - "href": "https://github.com/unruggable-labs/unruggable-gateways", - "stargazers": 91, - "lastUpdated": "2025-12-08T16:34:19Z" - } - ] - }, - { - "id": "0x2704cd27b8c60b098d4fe8c5c0fbae2f8f5fe9067c687c501a4c6dc6e9887876", - "name": "Act", - "description": "Act is a smart contract specification language and toolkit for formal verification. Act specifications are a formal, high-level description of all possible behaviours of an EVM program. Act allows many existing general purpose verification tools to be leveraged to prove properties about the specification. Such tools include SMT solvers (cvc5, z3, bitwuzla), theorem provers (Coq) and economic analysis tooling (CheckMate, Open Games). Act specifications can be automatically proved equivalent to concrete implementations in EVM. For very simple contracts, Act specifications can be automatically generated from EVM bytecode.\n\nThis is an end-to-end pipeline that supports principled reasoning about high level properties of EVM bytecode. It supports reasoning about both correctness (e.g. accounting invariants) and economic properties (e.g. incentive compatibility). Act specifications serve as a high-level smart contract representation, allowing for easy integration of existing general purpose analysis and verification tooling into the EVM context.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/a08fa912-3bc7-4957-9a64-5b10bc13397e.png", - "banner_url": "https://storage.googleapis.com/op-atlas/16e8a1cb-69b1-4098-8c40-fd25a5a29b8f.png", - "twitter": null, - "tags": [ - "education", - "analytics", - "formal-verification", - "symbolic-execution" - ], - "category": "Security, Testing & Formal Verification", - "repos": [ - { - "href": "https://github.com/ethereum/act", - "stargazers": 260, - "lastUpdated": "2025-12-09T08:24:27Z" - } - ] - }, - { - "id": "0x7d3f1d8e9da32b6e81e791a440b28ce9fbd79a5396acc4039d1cdc44c609c6d3", - "name": "OP STACK DEPLOYER", - "description": "OP Stack Deployer is a comprehensive tool designed to streamline the setup and deployment of an OP Stack chain. By automating complex tasks, it offers a seamless experience for developers. Whether you're an experienced blockchain developer or a newcomer, OP Stack Deployer provides the necessary resources to quickly get your OP Stack-based EVM Rollup operational.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/90d877db-39f3-4b3c-bb8e-90f26e734254.png", - "banner_url": "https://storage.googleapis.com/op-atlas/6e5a0785-93ce-438a-af3d-d81460919f57.png", - "twitter": "", - "tags": [ - "cli", - "foundry" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Aymen-Tirchi/op-stack-deployer", - "stargazers": 19, - "lastUpdated": "2025-02-10T08:35:38Z" - } - ] - }, - { - "id": "0xb2d109759fe14e11ac5cc100ab6006321ebdd7ffdefbd2efac93a002105f8e92", - "name": "Revm", - "description": "Revm is a critical component in the Ethereum ecosystem used by builders, toolings, clients and chains.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/57aeca37-e53b-4bcb-b161-0608d09e5c62.png", - "banner_url": "https://storage.googleapis.com/op-atlas/786c9752-af70-4856-9be0-38f4141769d2.png", - "twitter": "https://x.com/rakitadragan", - "tags": [ - "community-driven" - ], - "website": "https://github.com/bluealloy/revm", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/bluealloy/revm", - "stargazers": 2115, - "lastUpdated": "2026-01-20T18:17:57Z" - } - ] - }, - { - "id": "0x6bd057da522918a4675396313ae33a2f2788a1ceeb3bd7ae228015e3eb317a7d", - "name": "Viem: TypeScript Interface for Ethereum", - "description": "Viem is the most used modern TypeScript Interface for Ethereum. Viem provides robust, performant, and type-safe modules to be the foundation for building Web Applications, TypeScript Libraries, Wallets, Backends, Indexers, Scripts, and more, on top of Ethereum (and the OP Stack). With over 3 million monthly downloads, Viem is used in production by most at-scale projects like Coinbase, Uniswap, Optimism, Polymarket, Zora, Opensea, WalletConnect, Farcaster, Rainbow, and so much more.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/171f60c2-1e3e-4b0a-998e-4015a7f468f7.png", - "banner_url": "https://storage.googleapis.com/op-atlas/64c06023-a910-4646-ba3e-81baa2d935dc.png", - "twitter": "https://x.com/wevm_dev", - "tags": [ - "json-rpc", - "type-safe", - "hardhat" - ], - "website": "https://viem.sh", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/wevm/viem", - "stargazers": 3372, - "lastUpdated": "2026-01-15T16:35:59Z" - } - ] - }, - { - "id": "0x9151666888d0ca532a529be98a50d2eb992988117e202163f865fa9a27eb7149", - "name": "Solady", - "description": "Solady is an open-source repository containing highly-optimized Solidity snippets. It offers efficient implementations of commonly-used libraries, such as MerkleProofLib, alongside cutting-edge features like LibZip.\n\nBy thoughtfully encapsulating low-level inline assembly within flexible APIs, Solady simplifies the process of writing clean and efficient Solidity code. More than just a library, Solady also serves as a learning resource and experimental laboratory for pioneering gas-optimization techniques.\n\nSolady is used in the codebases of Optimism and Coinbase.\n\nWith respect to the OP stack, Solady contributes in the following ways:\n- Provides a Solidity and JavaScript implementation of FastLZ compression algorithm, which is used for more accurate gas estimations in the Fjord upgrade. The JavaScript code is very minimal, allowing for it's easy translation into Go.\n- Various other utilities such as bytecode proxies and string operations.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/0e726459-df1e-4cea-bddb-25399f88acea.png", - "banner_url": "https://storage.googleapis.com/op-atlas/0615ef25-edbb-4b19-934d-79614daf8040.png", - "twitter": "https://twitter.com/optimizoor", - "tags": [ - "education", - "solidity", - "gas-optimization", - "foundry", - "hardhat" - ], - "website": "https://solady.org", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Vectorized/solady", - "stargazers": 3255, - "lastUpdated": "2025-12-30T14:22:09Z" - } - ] - }, - { - "id": "0x492d0bbb85672e7e5f1d439bfd8857ac0aa59a52010143bbaab1a411bf55be0c", - "name": "TurtleShell", - "description": "One day you wake up and your protocol got exploited …maybe you heard of Circuit Breakers as attempt to end that quite real nightmare.\n\nWith TurtleShell we are aiming to give every Smart Contract holding Assets the necessary bolster to prevent unintended outflow.\n\nAvailable open-source tools include:\n- Smart Contract SDK\n- Frontend SDK, for visualizing relevant security data", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/c76c04f2-a5d4-488b-b427-0d1580bcfd9e.png", - "banner_url": "https://storage.googleapis.com/op-atlas/e5114d50-c66b-41ab-b064-14802e9f927a.png", - "twitter": "https://twitter.com/turtleshell_xyz", - "tags": [ - "frontend", - "security", - "solidity", - "tailwind-css", - "hardhat", - "truffle" - ], - "website": "turtleshell.xyz", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://www.npmjs.com/package/@markeljan/circuitbreaker", - "downloads": 1 - }, - { - "href": "https://github.com/turtleshell-xyz/circuitbreaker", - "stargazers": 0, - "lastUpdated": "2024-10-18T12:29:36Z" - }, - { - "href": "https://github.com/turtleshell-xyz/frontend-boilerplates", - "stargazers": 0, - "lastUpdated": "2024-08-03T17:59:55Z" - }, - { - "href": "https://github.com/turtleshell-xyz/nomad-bridge-poc", - "stargazers": 0, - "lastUpdated": "2024-08-03T17:56:48Z" - } - ] - }, - { - "id": "0xc2d8139cd61ddc75689610ee0cca0fe37ba8bec3270beb6aac6eac91c6256f60", - "name": "hardhat-gas-reporter", - "description": "A hardhat plugin that provides gas usage analytics for smart contract test suites. It has dedicated support for OPStack chains, is a dependency in > 150k Github repos and is downloaded from NPM > 100k per week. ", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/08754b7b-75c3-436b-ad66-bdf4b4261895.png", - "banner_url": "https://storage.googleapis.com/op-atlas/a3c56a18-2e9d-4a19-ba54-892bfa062884.png", - "twitter": null, - "tags": [ - "analytics", - "hardhat", - "test-automation" - ], - "website": "https://www.npmjs.com/package/hardhat-gas-reporter", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/cgewecke/hardhat-gas-reporter", - "stargazers": 433, - "lastUpdated": "2025-06-01T00:24:43Z" - }, - { - "href": "https://www.npmjs.com/package/hardhat-gas-reporter" - } - ] - }, - { - "id": "0x9ca1f7b0e0d10d3bd2619e51a54f2e4175e029c87a2944cf1ebc89164ba77ea0", - "name": "Vyper", - "description": "Pythonic Smart Contract Language for the EVM", - "thumbnail_url": "https://cdn.charmverse.io/user-content/5302de23-eae6-4cda-97aa-25fefd829726/9aa6f15f-e32a-4bca-a40a-5b1e1122babb/2024-06-11_23-25.png", - "banner_url": "https://cdn.charmverse.io/user-content/5302de23-eae6-4cda-97aa-25fefd829726/6c137923-55fc-4dc9-9424-5dad59f82ab4/vyper-optimism.png", - "twitter": "https://x.com/vyperlang?lang=en", - "tags": [ - "compiler", - "devops" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/vyperlang/vyper", - "stargazers": 5163, - "lastUpdated": "2026-01-17T20:46:52Z" - } - ] - }, - { - "id": "0x0008577196fa6ec286440b418e2f6305fc10e62ce759625d826be272ee6b45a3", - "name": "CreateX", - "description": "CreateX is a Trustless, Universal Contract Deployer that provides everyone with an easier and safer way to use the EVM opcodes `CREATE` and `CREATE2` as well as `CREATE3`-based (i.e. without an initcode factor) contract creations. CreateX is a preinstall on the OP Stack: https://specs.optimism.io/protocol/preinstalls.html#createx.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/4e18f37a-1991-48a1-9622-c43fa3e04f3e.png", - "banner_url": "https://storage.googleapis.com/op-atlas/a508253b-4224-4c48-8519-3fefcf39fc2f.png", - "twitter": null, - "tags": [ - "cli", - "contract-deployment", - "solidity" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/pcaversaccio/createx/releases/tag/v1.0.0", - "stargazers": 524, - "lastUpdated": "2026-01-20T12:18:40Z" - }, - { - "href": "https://github.com/pcaversaccio/createx", - "stargazers": 524, - "lastUpdated": "2026-01-20T12:18:40Z" - } - ] - }, - { - "id": "0x50159544ec22884b777a997a625c75bb02e55b1dc8934aad3b78678e7c11d039", - "name": "🐍 snekmate", - "description": "State-of-the-art, highly opinionated, hyper-optimised, and secure 🐍Vyper smart contract building blocks.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/baed8e76-d872-4218-9648-9bb5700dabc9.png", - "banner_url": "https://storage.googleapis.com/op-atlas/e205286d-1799-4d72-992a-a8ebe394c59b.png", - "twitter": null, - "tags": [ - "defi", - "vyper", - "erc721", - "foundry" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://www.npmjs.com/package/snekmate" - }, - { - "href": "https://github.com/pcaversaccio/snekmate", - "stargazers": 580, - "lastUpdated": "2026-01-19T18:29:33Z" - } - ] - }, - { - "id": "0x4cba820efd9e11754eb472ca0736756f27d0ece09adb3c9651bac5b29acc9a6d", - "name": "Blockflow", - "description": "Blockflow equips devs with the data and API tools to build innovative products faster. Unlike traditional solutions like RPCs and other Data Providers, Blockflow enables you to build \"Serverless Backends\", streamlining your operations without the heavy infrastructure, and saving 70% time & resources in building & 100% in maintenance.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/dbe12049-50ea-4cfb-b3f0-8def50ea7b07.png", - "banner_url": "https://storage.googleapis.com/op-atlas/191beaf8-e92f-42be-ab94-2305d12da9a4.png", - "twitter": "https://x.com/BlockflowLabs", - "tags": [ - "cli" - ], - "website": "https://www.blockflow.network/", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/blockflowlabs/cli-examples", - "stargazers": 5, - "lastUpdated": "2024-11-21T20:06:43Z" - }, - { - "href": "https://www.npmjs.com/package/@blockflow-labs/cli/v/1.0.7-beta.1", - "downloads": 41 - } - ] - }, - { - "id": "0x1c25ae2899ab6edb1e55c8cda5b736bb861a31da22bb9aa538f3868807eb1c73", - "name": "Bonadocs ", - "description": "Bonadocs allows web3 engineering teams to collaborate and build applications in a very intuitive way. To simplify integrations, we've categorized our tooling as follows:\n\nDocgen: Docgen allows developers to go from their codebase to beautiful and interactive documentation in seconds. Using our hardhat plugin, you can generate interactive documentation to query your contract methods.\n\nWidget: Through our playground environment, you can generate widgets for your contract methods. These widgets can then be easily embedded in your docs or any react application for devs to query. This is instrumental for devrel teams, to help onboard external devs.\n\nPlayground: Our playground is a collaborative environment primarily for solidity and front-end devs to build applications. This can be used by internal engineering teams or teams across different organizations. Devrel teams can also take advantage of the playground to create a single source of truth for their protocol - making onboarding super easy for their developer community.\n\nProtocol Registry: Our protocol registry is an open-source tool that allows you to find different popular protocols and their respective playgrounds.\n\nOn a high level, bonadocs are created to simplify the documentation, interaction, and integration of smart contracts - similar to Postman and web APIs.\n\nTry it out: https://docs.bonadocs.com/\nPlayground demo: https://x.com/thisdavidboy/status/1854809292836339939", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/d334c376-0ff1-4c76-94bf-2ee675cae1d3.png", - "banner_url": "https://storage.googleapis.com/op-atlas/a21ed458-efea-4d35-8aa9-b26d5e7bafad.png", - "twitter": "x.com/bonadocs", - "tags": [ - "cli", - "frontend", - "education", - "solidity-development" - ], - "website": "bonadocs.com", - "category": "Education & Community Resources", - "repos": [ - { - "href": "https://github.com/bonadocs/protocol-registry", - "stargazers": 0, - "lastUpdated": "2025-04-29T13:04:56Z" - }, - { - "href": "https://www.npmjs.com/package/@bonadocs/zimulatoor", - "downloads": 2 - }, - { - "href": "https://www.npmjs.com/package/@bonadocs/widget", - "downloads": 6 - }, - { - "href": "https://github.com/bonadocs/docgen", - "stargazers": 0, - "lastUpdated": "2025-04-03T17:49:44Z" - }, - { - "href": "https://github.com/bonadocs/docs", - "stargazers": 0, - "lastUpdated": "2025-08-19T22:05:46Z" - }, - { - "href": "https://github.com/bonadocs/cli", - "stargazers": 0, - "lastUpdated": "2025-04-03T17:53:33Z" - }, - { - "href": "https://github.com/bonadocs/protocol-registry-web", - "stargazers": 0, - "lastUpdated": "2025-04-03T17:55:20Z" - }, - { - "href": "https://www.npmjs.com/package/@bonadocs/docgen", - "downloads": 1 - }, - { - "href": "https://www.npmjs.com/package/@bonadocs/core", - "downloads": 15 - }, - { - "href": "https://www.npmjs.com/package/@bonadocs/cli", - "downloads": 0 - } - ] - }, - { - "id": "0x62e37e96aa6e1cbfb6bd24b97c4b8f1e12cc3fe35d5388d2f041c42a12b40745", - "name": "Stargate Finance", - "description": "Stargate is a fully composable liquidity\ntransport protocol that lives at the\nheart of omnichain DeFi.\n\nWith Stargate, users & dApps can transfer native assets cross-chain while accessing\nthe protocol’s unified liquidity pools with instant guaranteed finality. ", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/3083ccee-79a8-4ff2-b017-9ecb52d13cbf.png", - "banner_url": "https://storage.googleapis.com/op-atlas/b29f1ab3-b4cf-4255-839e-e7a418e78b80.png", - "twitter": "https://x.com/StargateFinance", - "tags": [ - "cross-chain", - "defi" - ], - "website": "https://stargate.finance/", - "category": "Cross-Chain & Interoperability", - "repos": [ - { - "href": "https://github.com/stargate-protocol/stargate", - "stargazers": 314, - "lastUpdated": "2024-06-06T00:19:00Z" - } - ] - }, - { - "id": "0x0ee3defac0e2a31b995bc073ac02a2140aaf01679e141eb8d1d80409f75f90ea", - "name": "Mint Club", - "description": "Mint Club provides a seamless platform for creating bonding curve-backed tokens or NFTs, using any ERC20 token as the base asset in the bonding curve pool. It facilitates easy tokenization with a completely no-code solution, offering highly customizable bonding curve designs, adjustable creator royalties, a variety of creator tools, and a user-friendly interface for trading bonding curve assets.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/8c7d3ba8-c0bd-4acd-9ec5-7f1c90631047.png", - "banner_url": "https://storage.googleapis.com/op-atlas/9efac275-51f7-48a8-9f13-22c13b05850e.png", - "twitter": "https://x.com/MintClubPro", - "tags": [], - "website": "https://mint.club", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Steemhunt/mint.club-v2-contract", - "stargazers": 62, - "lastUpdated": "2025-12-18T08:44:45Z" - }, - { - "href": "https://www.npmjs.com/package/mint.club-v2-sdk" - }, - { - "href": "https://github.com/Steemhunt/mint.club-v2-sdk", - "stargazers": 33, - "lastUpdated": "2025-12-13T05:11:28Z" - } - ] - }, - { - "id": "0x93decae913f62c0a86519d0b0798e4a10c46c541bfc14dcff0193d6b026e9532", - "name": "LlamaPay", - "description": "Automate & stream salaries by the second", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/30c6400b-b572-4d16-8138-4dc1cba0ef06.png", - "banner_url": "https://storage.googleapis.com/op-atlas/2c2733fd-a572-4f4f-809d-def2e14b8776.png", - "twitter": "https://x.com/llamapay_io", - "tags": [ - "defi", - "gas-efficient" - ], - "website": "https://llamapay.io/", - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/llamasubs/contracts", - "stargazers": 4, - "lastUpdated": "2024-07-21T13:42:50Z" - }, - { - "href": "https://github.com/LlamaPay/llamapay", - "stargazers": 187, - "lastUpdated": "2022-06-21T08:10:50Z" - } - ] - }, - { - "id": "0x66cb156952c9cd26c329a490b1ae9a90167f3067bbea337888b5d70d374959d7", - "name": "ZK Email", - "description": "We let anyone make trustless identity proofs on-chain through intuitive, private email verification. We do this via verifying partially redacted ZK proofs of any sent or received email on chain. We provide audited open source code and SDKs to construct new ZK circuits, infrastructure to use them within front ends, and infrastructure to make proofs on chain.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/27046acd-924a-4f01-ae53-dd51cb6d8238.png", - "banner_url": "https://storage.googleapis.com/op-atlas/7caed237-2d34-4b78-a158-cf118a697d57.png", - "twitter": "@zkemail", - "tags": [ - "frontend", - "modular-accounts", - "sdk", - "privacy-focused", - "user-experience", - "solidity" - ], - "website": "https://zk.email", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/zkemail/zk-email-verify", - "stargazers": 416, - "lastUpdated": "2025-12-19T13:16:10Z" - }, - { - "href": "https://github.com/zkemail/zk-email-sdk-js", - "stargazers": 5, - "lastUpdated": "2025-12-29T14:41:54Z" - }, - { - "href": "https://www.npmjs.com/package/@zk-email/contracts", - "downloads": 27 - }, - { - "href": "https://github.com/zkemail/email-recovery", - "stargazers": 59, - "lastUpdated": "2025-06-25T16:40:55Z" - }, - { - "href": "https://github.com/zkemail/zkemail.nr", - "stargazers": 80, - "lastUpdated": "2025-10-23T14:28:02Z" - } - ] - }, - { - "id": "0x38c38455bb0fd71d2929fcf799279569ab5f5c5d3e1f92f8642ce87aa25accdf", - "name": "Decent.xyz", - "description": "Decent enables cross-chain swaps and 1-click transactions with any token across chains. ", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/1ede3a09-1878-4852-a564-f86f4f49b9fc.png", - "banner_url": "https://storage.googleapis.com/op-atlas/862dacb3-f496-4afe-ae66-70f9f9949937.png", - "twitter": "https://twitter.com/decentxyz", - "tags": [ - "cross-chain", - "nextjs", - "tailwind-css", - "foundry", - "user-experience" - ], - "category": "Cross-Chain & Interoperability", - "repos": [ - { - "href": "https://www.npmjs.com/package/@decent.xyz/box-common", - "downloads": 1230 - }, - { - "href": "https://www.npmjs.com/package/@decent.xyz/box-hooks", - "downloads": 1053 - }, - { - "href": "https://github.com/decentxyz/launch-nfts", - "stargazers": 1, - "lastUpdated": "2024-06-06T16:40:50Z" - }, - { - "href": "https://github.com/decentxyz/decentV2-contracts", - "stargazers": 2, - "lastUpdated": "2024-06-06T15:26:43Z" - }, - { - "href": "https://www.npmjs.com/package/@decent.xyz/box-ui", - "downloads": 833 - }, - { - "href": "https://www.npmjs.com/package/@decent.xyz/the-box", - "downloads": 837 - }, - { - "href": "https://github.com/decentxyz/decent-contracts-v3", - "stargazers": 1, - "lastUpdated": "2025-03-28T20:43:18Z" - } - ] - }, - { - "id": "0xae07bfec2c3c90937679f8c8c5c32e80407c09903aa03d1b5e5a075e67592b86", - "name": "DefiLlama", - "description": "- Open and transparent DeFi analytics.\n- DEX meta-aggregator\n- LlamaZIp, a router optimized for optimistic rollups", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/a9e1e4b4-45a2-411b-8f31-059269534381.png", - "banner_url": "https://storage.googleapis.com/op-atlas/7e0ec4d9-824e-46e3-ad4e-8ffaaa1f105b.png", - "twitter": "https://x.com/defillama", - "tags": [ - "analytics", - "defi", - "community-driven", - "dex-aggregator", - "visualization" - ], - "website": "https://defillama.com/", - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/DefiLlama/defillama-app", - "stargazers": 277, - "lastUpdated": "2026-01-20T20:11:36Z" - }, - { - "href": "https://github.com/0xngmi/llamazip", - "stargazers": 20, - "lastUpdated": "2024-06-05T03:14:38Z" - }, - { - "href": "https://github.com/DefiLlama/DefiLlama-Adapters", - "stargazers": 1110, - "lastUpdated": "2026-01-20T18:30:58Z" - } - ] - }, - { - "id": "0x120cdd8e43ae1efbafdf02eda876e1952c05a52870c8d5a8f56d9ec0f79f586d", - "name": "Passport XYZ | Gitcoin Passport", - "description": "Passport is the premier web3 native offering that enables ecosystems to protect, understand and organically grow what matters most – their communities. We see Passport at the confluence of a best in class identity solution, backed by the most relevant and comprehensive data analysis toolset that also offers communities the ability to ascribe reputation. ", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/0160cab5-f34b-4aa5-9442-8b6e82a02bde.png", - "banner_url": "https://storage.googleapis.com/op-atlas/55137132-f859-4640-8d98-4f7c3a8e4489.png", - "twitter": "https://x.com/gitcoinpassport", - "tags": [ - "analytics", - "gas-efficient" - ], - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/gitcoinco/passport", - "stargazers": 1207, - "lastUpdated": "2026-01-15T15:17:37Z" - }, - { - "href": "https://github.com/gitcoinco/eas-proxy", - "stargazers": 22, - "lastUpdated": "2025-09-02T16:06:03Z" - }, - { - "href": "https://github.com/passportxyz/passport-scorer", - "stargazers": 178, - "lastUpdated": "2026-01-16T15:04:54Z" - }, - { - "href": "https://github.com/passportxyz/passport", - "stargazers": 1207, - "lastUpdated": "2026-01-15T15:17:37Z" - }, - { - "href": "https://github.com/gitcoinco/id-staking-v2", - "stargazers": 4, - "lastUpdated": "2024-10-04T17:47:35Z" - }, - { - "href": "https://github.com/gitcoinco/id-staking-v2-app", - "stargazers": 3, - "lastUpdated": "2025-04-08T18:25:51Z" - }, - { - "href": "https://github.com/gitcoinco/passport-scorer", - "stargazers": 178, - "lastUpdated": "2026-01-16T15:04:54Z" - } - ] - }, - { - "id": "0x7539f43dc91f9c406c83a06339708e4033cdbf630916c6dfb9de2b5ef811affd", - "name": "Seamless Protocol", - "description": "Seamless Protocol is the largest native lending and borrowing DeFi platform on Base.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/3ab14d32-3c0e-4262-a17c-9a328dded4bc.png", - "banner_url": "https://storage.googleapis.com/op-atlas/c87cd7ac-5627-4db9-9483-a61e4743d2f0.png", - "twitter": "https://x.com/SeamlessFi", - "tags": [ - "defi", - "governance", - "foundry", - "contract-management", - "cli" - ], - "website": "https://seamlessprotocol.com", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/seamless-protocol/governance", - "stargazers": 9, - "lastUpdated": "2025-06-18T17:27:33Z" - } - ] - }, - { - "id": "0xe20f59eb1c8f9cb72e07b8d0f067bac997614fd6db06d8c031c5c9235f760dcc", - "name": "L2Pass", - "description": "Cross-Chain Super-App for effortless Multi-Chain Token Movement, Swaps and Art Performance. Powered by Layer.Zero.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/3f5f2b44-9650-483a-b5cf-1e66163bddae.png", - "banner_url": "https://storage.googleapis.com/op-atlas/41a3c848-54ca-4b30-8fa1-e82a70b18935.png", - "twitter": "https://x.com/L2_Pass", - "tags": [ - "cross-chain", - "wallet", - "multi-chain" - ], - "website": "https://l2pass.com/", - "category": "Cross-Chain & Interoperability", - "repos": [ - { - "href": "https://github.com/L2PASS/contracts", - "stargazers": 0, - "lastUpdated": "2024-05-30T20:04:34Z" - } - ] - }, - { - "id": "0xa88844cea135382e3484e39c3172033437121b35ca0bc8b10b9b8253984876b5", - "name": "Ethereum Attestation Service (EAS)", - "description": "EAS is an infrastructure public good for making attestations onchain or offchain about anything. Attestations are digital signatures on structured pieces of data used to build more trust online and onchain. Over 1M+ attestations have been made in the Superchain from over 14k+ unique attesters.\n\nEAS is natively integrated into OP Bedrock and linked by two predeploy addresses:\nhttps://github.com/ethereum-optimism/optimism/tree/3542398896d9faca6b379fe67e3985d722cf80b6/packages/contracts-bedrock/src/EAS", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/e74ff6ef-578b-4dcb-b155-e663822b2f94.png", - "banner_url": "https://storage.googleapis.com/op-atlas/a447bb2c-d43d-433c-b66c-2506c12858f4.png", - "twitter": "https://twitter.com/eas_eth", - "tags": [ - "governance", - "sdk" - ], - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/ethereum-attestation-service/eas-contracts", - "stargazers": 304, - "lastUpdated": "2025-02-17T03:21:57Z" - }, - { - "href": "https://github.com/ethereum-attestation-service/eas-sdk", - "stargazers": 133, - "lastUpdated": "2025-10-12T22:38:43Z" - }, - { - "href": "https://www.npmjs.com/package/@ethereum-attestation-service/eas-contracts", - "downloads": 6119 - } - ] - }, - { - "id": "0x8967594d2978692a35fea137ba640bb42f11cad907ca6b0bd01f3718fc4c7f5b", - "name": "Hats Protocol", - "description": "The organizational graph protocol: encode your organization's roles, agents, and permissions into a programmable graph with Hats Protocol", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/cade2fb6-a79c-4974-8b2b-fc4afcd1ec09.png", - "banner_url": "https://storage.googleapis.com/op-atlas/3a110bc1-0ea0-49d5-a38b-5a66b3484852.png", - "twitter": "https://twitter.com/hatsprotocol", - "tags": [ - "governance", - "decentralized-governance", - "solidity", - "foundry", - "proxy-contracts" - ], - "website": "https://hatsprotocol.xyz", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Hats-Protocol/hats-account", - "stargazers": 10, - "lastUpdated": "2024-06-20T21:46:07Z" - }, - { - "href": "https://github.com/Hats-Protocol/subgraph", - "stargazers": 4, - "lastUpdated": "2025-03-29T13:47:39Z" - }, - { - "href": "https://github.com/Hats-Protocol/hat-wearing-eligibility", - "stargazers": 0, - "lastUpdated": "2024-05-29T16:35:25Z" - }, - { - "href": "https://github.com/Hats-Protocol/farcaster-delegator", - "stargazers": 18, - "lastUpdated": "2024-05-29T16:10:52Z" - }, - { - "href": "https://github.com/Hats-Protocol/hats-account-sdk", - "stargazers": 1, - "lastUpdated": "2024-06-20T22:00:40Z" - }, - { - "href": "https://github.com/Hats-Protocol/hats-auth", - "stargazers": 1, - "lastUpdated": "2024-05-29T16:16:26Z" - }, - { - "href": "https://github.com/Hats-Protocol/create-hats-app", - "stargazers": 5, - "lastUpdated": "2025-11-25T14:47:41Z" - }, - { - "href": "https://github.com/Hats-Protocol/hsg-sdk", - "stargazers": 1, - "lastUpdated": "2024-07-15T20:34:51Z" - }, - { - "href": "https://github.com/Hats-Protocol/colinks-eligibility", - "stargazers": 0, - "lastUpdated": "2024-06-20T21:43:18Z" - }, - { - "href": "https://github.com/Hats-Protocol/chain-modules", - "stargazers": 1, - "lastUpdated": "2024-06-20T22:00:29Z" - }, - { - "href": "https://github.com/Hats-Protocol/allowlist-eligibility", - "stargazers": 0, - "lastUpdated": "2024-09-11T01:10:32Z" - }, - { - "href": "https://github.com/Hats-Protocol/agreement-eligibility", - "stargazers": 0, - "lastUpdated": "2024-10-14T01:14:11Z" - }, - { - "href": "https://www.npmjs.com/package/@hatsprotocol/sdk-v1-subgraph", - "downloads": 353 - }, - { - "href": "https://github.com/Hats-Protocol/hats-elections-eligibility", - "stargazers": 0, - "lastUpdated": "2024-05-29T16:12:39Z" - }, - { - "href": "https://www.npmjs.com/package/@hatsprotocol/sdk-v1-core", - "downloads": 215 - }, - { - "href": "https://github.com/Hats-Protocol/season-toggle", - "stargazers": 0, - "lastUpdated": "2024-05-29T16:35:41Z" - }, - { - "href": "https://github.com/Hats-Protocol/staking-eligibility", - "stargazers": 1, - "lastUpdated": "2024-05-29T16:35:59Z" - }, - { - "href": "https://github.com/hats-protocol/hats-module", - "stargazers": 4, - "lastUpdated": "2025-03-15T20:33:53Z" - }, - { - "href": "https://github.com/hats-protocol/hats-protocol", - "stargazers": 95, - "lastUpdated": "2024-05-29T15:50:14Z" - }, - { - "href": "https://www.npmjs.com/package/@hatsprotocol/modules-sdk", - "downloads": 145 - }, - { - "href": "https://www.npmjs.com/package/@hatsprotocol/hsg-sdk", - "downloads": 1 - }, - { - "href": "https://www.npmjs.com/package/@hatsprotocol/hats-account-sdk", - "downloads": 0 - }, - { - "href": "https://github.com/Hats-Protocol/subgraph-ancillary", - "stargazers": 0, - "lastUpdated": "2025-03-29T14:01:57Z" - }, - { - "href": "https://github.com/Hats-Protocol/hats-governor-votes", - "stargazers": 0, - "lastUpdated": "2025-02-09T18:06:36Z" - }, - { - "href": "https://github.com/Hats-Protocol/hats-module-template", - "stargazers": 2, - "lastUpdated": "2024-06-20T21:47:18Z" - }, - { - "href": "https://github.com/Hats-Protocol/modules-sdk", - "stargazers": 3, - "lastUpdated": "2025-12-01T23:35:58Z" - }, - { - "href": "https://github.com/Hats-Protocol/hats-zodiac", - "stargazers": 23, - "lastUpdated": "2024-12-19T02:24:56Z" - }, - { - "href": "https://github.com/Hats-Protocol/jokerace-eligibility", - "stargazers": 0, - "lastUpdated": "2024-08-27T19:15:52Z" - }, - { - "href": "https://github.com/Hats-Protocol/multi-claims-hatter", - "stargazers": 0, - "lastUpdated": "2024-05-29T16:36:17Z" - }, - { - "href": "https://github.com/Hats-Protocol/passthrough-modules", - "stargazers": 1, - "lastUpdated": "2024-09-14T15:21:25Z" - }, - { - "href": "https://github.com/Hats-Protocol/sdk-v1-core", - "stargazers": 3, - "lastUpdated": "2025-04-01T19:37:40Z" - } - ] - }, - { - "id": "0x24ff0fb2933e55b169a80d9bd35a00a7011795387717b27445ccdc0f8660d740", - "name": "OpenOcean", - "description": "OpenOcean is a leading DEX aggregator with best swap prices across 30+ chains.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/46d3935b-5719-4c9f-ae9b-d7f255f4c120.png", - "banner_url": "https://storage.googleapis.com/op-atlas/5082f8c7-b61a-4ac7-b829-e51fa15fdfc4.png", - "twitter": "https://x.com/OpenOceanGlobal", - "tags": [ - "defi", - "cross-chain", - "dex-aggregator", - "multi-chain" - ], - "website": "https://openocean.finance/", - "category": "Cross-Chain & Interoperability", - "repos": [ - { - "href": "https://www.npmjs.com/package/@openocean.finance/wallet", - "downloads": 396 - }, - { - "href": "https://github.com/openocean-finance/OpenOceanExchangeV2", - "stargazers": 1, - "lastUpdated": "2025-11-24T02:45:16Z" - }, - { - "href": "https://www.npmjs.com/package/@openocean.finance/openocean-sdk", - "downloads": 465 - } - ] - }, - { - "id": "0x517eaa9c56951de89261f2d7830ea49aae92f2a903104a17d9c5c2edd4959806", - "name": "LI.FI", - "description": "One API to swap, bridge, and zap across all major blockchains and protocols. Enable trading across all DEX aggregators, bridges, and intent-systems and save hundreds of developer hours.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/4906b988-6024-421e-a706-d01bc508e736.png", - "banner_url": "https://storage.googleapis.com/op-atlas/c280e13b-3e03-47e9-8141-5fad0d51ba2b.png", - "twitter": "https://x.com/lifiprotocol", - "tags": [ - "cross-chain", - "api", - "dex-aggregator", - "multi-chain", - "performance-optimization" - ], - "category": "Cross-Chain & Interoperability", - "repos": [ - { - "href": "https://www.npmjs.com/package/@lifi/sdk", - "downloads": 36632 - }, - { - "href": "https://github.com/lifinance/widget", - "stargazers": 188, - "lastUpdated": "2026-01-20T11:06:38Z" - }, - { - "href": "https://www.npmjs.com/package/@lifi/widget", - "downloads": 12583 - }, - { - "href": "https://github.com/lifinance/contracts", - "stargazers": 191, - "lastUpdated": "2026-01-16T08:38:18Z" - }, - { - "href": "https://github.com/lifinance/sdk", - "stargazers": 243, - "lastUpdated": "2026-01-20T12:52:18Z" - } - ] - }, - { - "id": "0x4d71401a0dbd9b3dd890fbc70baaf872d16db80af149e20f7ef1805fc94f6df6", - "name": "Router Protocol", - "description": "Router is an cross chain infraproject \nRouter Nitro is a trustless, ultra-low latency bridge built using Router chain’s middleware construct. It transfers user funds across chains in less than 30 seconds, and is more than 20% cheaper than the next cheapest bridge in the market. It currently supports 19 chains:\n", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/582dd2ed-214a-4289-9423-35b64c318cb2.png", - "banner_url": "https://storage.googleapis.com/op-atlas/407396e3-b660-4615-a35d-eae333379d44.png", - "twitter": "https://x.com/routerprotocol", - "tags": [ - "cross-chain", - "scalability" - ], - "category": "Cross-Chain & Interoperability", - "repos": [ - { - "href": "https://github.com/router-protocol/router-contracts", - "stargazers": 0, - "lastUpdated": "2024-10-17T04:25:33Z" - }, - { - "href": "https://www.npmjs.com/package/@routerprotocol/asset-bridge", - "downloads": 0 - }, - { - "href": "https://www.npmjs.com/package/@routerprotocol/asset-forwarder", - "downloads": 0 - }, - { - "href": "https://www.npmjs.com/package/@routerprotocol/evm-gateway-contracts", - "downloads": 5 - } - ] - }, - { - "id": "0x850df51e29f2846a5f085d88e6b6fc13fad51ad7161f8a825ed09d470668161a", - "name": "Party.app + Party Protocol", - "description": "The Party Protocol is an open-source protocol for group coordination. It provides flexible and powerful primitives for creating a shared smart contract account governed by a group of people, big or small.\n\nParty.app is the flagship UI / app built on top. It allows groups to form a small group wallet, and large on-chain DAO, or anything in-between. Party.app has built-in functionality for crowdfunding, governance, using apps via wallet connect, buying & selling NFTs, trading tokens, chatting, and much more.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/ff816d35-de0c-4768-af2c-d2c187dab1c1.png", - "banner_url": "https://storage.googleapis.com/op-atlas/87f46f2a-632b-441c-b762-fe104617d4b6.png", - "twitter": "https://x.com/prtyDAO", - "tags": [ - "wallet", - "governance" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/PartyDAO/party-protocol", - "stargazers": 183, - "lastUpdated": "2024-12-21T01:46:28Z" - } - ] - }, - { - "id": "0x08df6e20a3cfabbaf8f34d4f4d048fe7da40447c24be0f3ad513db6f13c755dd", - "name": "Velodrome Finance", - "description": "The central trading & liquidity marketplace on Superchain", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/438ea57d-059c-4327-82e4-abfc94544bad.png", - "banner_url": "https://storage.googleapis.com/op-atlas/2d33616b-bceb-449d-aa0a-b8270b1b3e3b.png", - "twitter": "https://twitter.com/VelodromeFi", - "tags": [ - "defi", - "docker", - "foundry", - "contract-verification" - ], - "website": "https://velodrome.finance", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/velodrome-finance/relay", - "stargazers": 6, - "lastUpdated": "2025-12-18T15:28:56Z" - }, - { - "href": "https://github.com/velodrome-finance/universal-router", - "stargazers": 7, - "lastUpdated": "2025-06-24T08:03:31Z" - }, - { - "href": "https://github.com/velodrome-finance/sugar-sdk", - "stargazers": 15, - "lastUpdated": "2025-08-05T11:45:53Z" - }, - { - "href": "https://github.com/velodrome-finance/sugar", - "stargazers": 84, - "lastUpdated": "2025-12-18T15:29:47Z" - }, - { - "href": "https://github.com/velodrome-finance/slipstream", - "stargazers": 42, - "lastUpdated": "2025-12-18T15:27:54Z" - }, - { - "href": "https://github.com/velodrome-finance/oracle", - "stargazers": 5, - "lastUpdated": "2024-06-05T20:09:23Z" - }, - { - "href": "https://github.com/velodrome-finance/contracts", - "stargazers": 64, - "lastUpdated": "2025-12-18T15:29:13Z" - }, - { - "href": "https://github.com/velodrome-finance/superchain-contracts", - "stargazers": 9, - "lastUpdated": "2025-12-18T15:27:19Z" - }, - { - "href": "https://github.com/velodrome-finance/superchain-slipstream", - "stargazers": 3, - "lastUpdated": "2025-12-18T15:28:24Z" - } - ] - }, - { - "id": "0xb6266f3d955040aa7583f2f346db87abe0649f545389af3cc8fe302aacfc850b", - "name": "Splits", - "description": "Splits builds software for sharing money. We provide secure contracts, intuitive interfaces, and reliable developer tools that make it easy to collaboratively receive and manage money on the internet.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/507b8200-92e0-4914-a43e-97010a0b0583.png", - "banner_url": "https://storage.googleapis.com/op-atlas/bd351554-5050-4584-9f2f-f23ea935508b.png", - "twitter": "https://x.com/0xsplits", - "tags": [], - "website": "https://splits.org/", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/0xSplits/splits-contracts-monorepo", - "stargazers": 27, - "lastUpdated": "2025-11-20T16:54:26Z" - }, - { - "href": "https://github.com/0xSplits/splits-liquid", - "stargazers": 11, - "lastUpdated": "2024-05-29T21:10:35Z" - }, - { - "href": "https://github.com/0xSplits/splits-waterfall", - "stargazers": 31, - "lastUpdated": "2025-09-18T18:54:53Z" - }, - { - "href": "https://github.com/0xSplits/splits-vesting", - "stargazers": 11, - "lastUpdated": "2025-01-21T23:36:35Z" - }, - { - "href": "https://github.com/0xSplits/splits-utils", - "stargazers": 4, - "lastUpdated": "2024-05-29T21:09:10Z" - }, - { - "href": "https://github.com/0xSplits/splits-oracle", - "stargazers": 9, - "lastUpdated": "2024-05-29T21:11:50Z" - }, - { - "href": "https://github.com/0xSplits/splits-diversifier", - "stargazers": 11, - "lastUpdated": "2024-05-29T21:06:58Z" - }, - { - "href": "https://github.com/0xSplits/splits-contracts", - "stargazers": 163, - "lastUpdated": "2024-05-28T00:13:31Z" - }, + "category": "Cross-Chain & Interoperability", + "repos": [ { - "href": "https://github.com/0xSplits/splits-swapper", - "stargazers": 14, - "lastUpdated": "2025-09-23T16:44:17Z" + "href": "https://www.npmjs.com/package/@lifi/sdk", + "downloads": 36632 }, { - "href": "https://github.com/0xSplits/splits-sdk", - "stargazers": 38, - "lastUpdated": "2026-01-07T19:15:34Z" + "href": "https://github.com/lifinance/widget", + "stargazers": 188, + "lastUpdated": "2026-01-20T11:06:38Z" }, { - "href": "https://www.npmjs.com/package/@0xsplits/splits-kit", - "downloads": 45 + "href": "https://www.npmjs.com/package/@lifi/widget", + "downloads": 12583 }, { - "href": "https://www.npmjs.com/package/@0xsplits/splits-sdk-react", - "downloads": 688 + "href": "https://github.com/lifinance/contracts", + "stargazers": 191, + "lastUpdated": "2026-01-16T08:38:18Z" }, { - "href": "https://www.npmjs.com/package/@0xsplits/splits-sdk", - "downloads": 1330 + "href": "https://github.com/lifinance/sdk", + "stargazers": 243, + "lastUpdated": "2026-01-20T12:52:18Z" } ] }, { - "id": "0xfc54b4a9c537be25238cba3f05100b733aeee83a3eb3fdae60d651b3b913390c", - "name": "Multicaller", - "description": "Multicaller is a suite of hyper-optimized contracts that allows for batched calls, while allowing \"forwarding\" the `msg.sender`.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/8362181e-8e95-40d4-bf8d-234f3edaca4c.png", - "banner_url": "https://storage.googleapis.com/op-atlas/2a702168-545c-42ec-a85f-3149a9227597.png", - "twitter": null, + "id": "0xc850d11fe786d1168bfeda108721101427dd5425d9d9e6595c35573f7616e940", + "name": "Daimo Pay", + "description": "Daimo Pay lets users interact with your app using any token on any chain - no bridging, no swapping, no friction.\nIntegrate our SDK in 15 minutes to accept deposits or execute transactions in your app with any token, from any chain, using any wallet or exchange.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/b2bd0510-b0d6-436e-a126-de05026e9418.png", + "banner_url": "https://storage.googleapis.com/op-atlas/dde6090a-600a-418b-be38-5ea73111c407.png", + "twitter": "https://x.com/daimopay", "tags": [ - "multicall", - "solidity", - "transaction-optimization", - "contract-interaction", - "foundry", - "hardhat", - "truffle" + "cross-chain" ], - "website": "https://github.com/Vectorized/multicaller", - "category": "Smart Contract Development & Toolchains", + "website": "https://pay.daimo.com/", + "category": "Cross-Chain & Interoperability", "repos": [ { - "href": "https://www.npmjs.com/package/multicaller" - }, + "href": "https://github.com/daimo-eth/pay", + "stargazers": 18, + "lastUpdated": "2026-01-20T05:09:55Z" + } + ] + }, + { + "id": "0x62e37e96aa6e1cbfb6bd24b97c4b8f1e12cc3fe35d5388d2f041c42a12b40745", + "name": "Stargate Finance", + "description": "Stargate is a fully composable liquidity\ntransport protocol that lives at the\nheart of omnichain DeFi.\n\nWith Stargate, users & dApps can transfer native assets cross-chain while accessing\nthe protocol’s unified liquidity pools with instant guaranteed finality. ", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/3083ccee-79a8-4ff2-b017-9ecb52d13cbf.png", + "banner_url": "https://storage.googleapis.com/op-atlas/b29f1ab3-b4cf-4255-839e-e7a418e78b80.png", + "twitter": "https://x.com/StargateFinance", + "tags": [ + "cross-chain", + "defi" + ], + "website": "https://stargate.finance/", + "category": "Cross-Chain & Interoperability", + "repos": [ { - "href": "https://github.com/Vectorized/multicaller", - "stargazers": 289, - "lastUpdated": "2025-01-31T03:52:41Z" + "href": "https://github.com/stargate-protocol/stargate", + "stargazers": 314, + "lastUpdated": "2024-06-06T00:19:00Z" } ] }, @@ -5233,6 +788,55 @@ } ] }, + { + "id": "0x38c38455bb0fd71d2929fcf799279569ab5f5c5d3e1f92f8642ce87aa25accdf", + "name": "Decent.xyz", + "description": "Decent enables cross-chain swaps and 1-click transactions with any token across chains. ", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/1ede3a09-1878-4852-a564-f86f4f49b9fc.png", + "banner_url": "https://storage.googleapis.com/op-atlas/862dacb3-f496-4afe-ae66-70f9f9949937.png", + "twitter": "https://twitter.com/decentxyz", + "tags": [ + "cross-chain", + "nextjs", + "tailwind-css", + "foundry", + "user-experience" + ], + "category": "Cross-Chain & Interoperability", + "repos": [ + { + "href": "https://www.npmjs.com/package/@decent.xyz/box-common", + "downloads": 1230 + }, + { + "href": "https://www.npmjs.com/package/@decent.xyz/box-hooks", + "downloads": 1053 + }, + { + "href": "https://github.com/decentxyz/launch-nfts", + "stargazers": 1, + "lastUpdated": "2024-06-06T16:40:50Z" + }, + { + "href": "https://github.com/decentxyz/decentV2-contracts", + "stargazers": 2, + "lastUpdated": "2024-06-06T15:26:43Z" + }, + { + "href": "https://www.npmjs.com/package/@decent.xyz/box-ui", + "downloads": 833 + }, + { + "href": "https://www.npmjs.com/package/@decent.xyz/the-box", + "downloads": 837 + }, + { + "href": "https://github.com/decentxyz/decent-contracts-v3", + "stargazers": 1, + "lastUpdated": "2025-03-28T20:43:18Z" + } + ] + }, { "id": "0x66cce776ce6eaa99192120fc25b91ecc7b98e03210a08f0d3bfda82f542d3e1a", "name": "OP ENS Gateway by Opti.Domains", @@ -5294,376 +898,208 @@ ] }, { - "id": "0xe40733f18903b26f7880bb2fd78c39f3992efe9f8b2e89994c2869eeb3ba4470", - "name": "Chain Abstraction with 4337", - "description": "With this setup, ecosystems can deploy tailor-made 4337 chain abstraction infrastructure. They become Liquidity Providers (LPs) for their users, sharing with them the value that would otherwise have been captured by solvers/fillers. ", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/1d22d6dc-b629-48bc-9c25-2ecc6b9aa1a5.png", - "banner_url": "https://storage.googleapis.com/op-atlas/1d511ff7-cfcf-49f8-876c-b11a324148a3.png", - "twitter": "https://x.com/openfortxyz", - "tags": [ - "defi", - "wallet", - "account-abstraction", - "multi-chain", - "analytics", - "user-experience" - ], - "website": "https://openfort.xyz", - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/openfort-xyz/openfort-contracts", - "stargazers": 33, - "lastUpdated": "2025-12-04T17:37:28Z" - }, - { - "href": "https://github.com/openfort-xyz/openfort-chain-abstraction", - "stargazers": 11, - "lastUpdated": "2025-03-11T09:03:23Z" - }, - { - "href": "https://www.npmjs.com/package/@openfort/openfort-js", - "downloads": 1549 - }, - { - "href": "https://github.com/openfort-xyz/openfort-js", - "stargazers": 12, - "lastUpdated": "2026-01-20T10:21:12Z" - } - ] - }, - { - "id": "0xa08c7ab7824d147d6cb87ffb4e86cec454a030d48b8c395bad6d64456be3d911", - "name": "Aragon OSx", - "description": "Aragon was founded in 2016 with the belief that the fate of humanity will be decided at the frontier of technological innovation and human collaboration. Aragon launched the first DAO Framework in 2017 which secures over $40 billion in TVL. Aragon’s tech stack allows anyone to launch a DAO, enabling organizations to securely govern their protocols and assets onchain.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/fe98ffd7-a327-4500-9391-5926dc7a8256.png", - "banner_url": "https://storage.googleapis.com/op-atlas/b9fed2cb-1767-436f-a605-65af61934cf1.png", - "twitter": "https://x.com/AragonProject", - "tags": [ - "governance", - "solidity", - "decentralized-governance", - "contract-management" - ], - "website": "https://aragon.org/", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/aragon/app", - "stargazers": 3, - "lastUpdated": "2026-01-19T17:35:39Z" - }, - { - "href": "https://www.npmjs.com/package/@aragon/ods", - "downloads": 18 - }, - { - "href": "https://github.com/aragon/osx", - "stargazers": 100, - "lastUpdated": "2025-10-24T15:01:29Z" - } - ] - }, - { - "id": "0x79e8bf2d699790b563aa57fd34da1722bea3191ab5ff0601ba56020687702ab9", - "name": "Etherspot", - "description": "Etherspot is a multi-chain Account & Chain Abstraction development infrastructure that provides solutions for dApps, wallets, games, operating EVM-compatible rollups, or L1/L2 chains to deliver seamless cross-chain Web3 user experience by removing usability pain points.\n\nIn addition to providing Account and Chain Abstraction features, Etherspot helps developers make their projects compatible with the latest Ethereum standards, including ERC-4337, ERC-7579, and EIP-7702, by offering a wide range of cutting-edge services such as Bundler and Paymaster services, APIs, and more.\n\nEtherspot is pioneering the ERC-4337 shared mempool innovation, which is already live on Optimism.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/b05e1c53-bace-499c-b346-ed9fa0003730.png", - "banner_url": "https://storage.googleapis.com/op-atlas/b33b4fe0-6010-470c-a2db-57636d96536d.png", - "twitter": "https://x.com/etherspot", - "tags": [ - "cross-chain", - "wallet", - "defi", - "multi-chain", - "account-abstraction", - "sdk", - "user-experience" - ], - "website": "https://etherspot.io/", - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/etherspot/etherspot-prime-contracts", - "stargazers": 55, - "lastUpdated": "2025-02-20T21:15:37Z" - }, - { - "href": "https://github.com/etherspot/etherspot-modular-sdk", - "stargazers": 22, - "lastUpdated": "2025-10-23T08:27:57Z" - }, - { - "href": "https://www.npmjs.com/package/skandha" - }, - { - "href": "https://www.npmjs.com/package/@etherspot/prime-sdk", - "downloads": 60 - }, - { - "href": "https://github.com/etherspot/skandha", - "stargazers": 610, - "lastUpdated": "2026-01-20T12:53:03Z" - } - ] - }, - { - "id": "0x9d93ec97ef2d3bd4c2b8d95abac9ce0cf43e4f3eb1f05709f8282da8200e69ee", - "name": "Frames.js", - "description": "frames.js is the leading open source javascript library and debugging environment to help developers make Frames for Farcaster, XMTP and Lens faster & easier. \n\nWe also have been building and maintaining a library for apps to adopt frames in their apps that has been integrated by the Base team in their Base names product.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/230e8ac2-cea9-4cab-8b4f-8fd58ec6553e.png", - "banner_url": "https://storage.googleapis.com/op-atlas/a2dce749-56d7-44d7-a9cc-ffc08255e0f2.png", - "twitter": null, - "tags": [ - "frontend", - "farcaster", - "react", - "nextjs" - ], - "website": "https://www.framesjs.org", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/framesjs/frames.js", - "stargazers": 382, - "lastUpdated": "2025-03-27T17:07:46Z" - } - ] - }, - { - "id": "0x3061b642db56c507e265f03029735b0413a613bda43456a31e78128baeb18754", - "name": "Aave", - "description": "Aave is DeFi's largest lending protocol and one the most used protocols on Optimism.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/dcd0600f-d9bf-439e-9915-5922ea8e9655.png", - "banner_url": "https://storage.googleapis.com/op-atlas/031491b9-252c-4b9d-b450-16f3443184d9.png", - "twitter": null, - "tags": [ - "defi", - "governance", - "foundry", - "cli", - "contract-deployment" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Aave" - } - ] - }, - { - "id": "manually-added:speedrunethereum", - "name": "SpeedrunEthereum", - "description": "Speedrun Ethereum is a hands-on series of challenges designed to help you learn by building. Each challenge delivers one key \"aha\" moment, a mental unlock about how Ethereum really works. At the same time, you'll be building your Ethereum portfolio.", - "thumbnail_url": null, - "banner_url": null, - "twitter": "https://x.com/buidlguidl", + "id": "0x663e4d25ca3f327365240471b4831ea3c989cb132bbf6ae8f5c1e15268591795", + "name": "Blockscout open-source block explorer", + "description": "Blockscout block explorer is the #1 explorer used by Optimistic rollups and Superchain networks. Blockscout is highly customizable and available, providing advanced developer tooling for projects and blockchain transparency for users.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/3113c4b6-4e29-420c-95f8-2ae4f6098089.png", + "banner_url": "https://storage.googleapis.com/op-atlas/c08d15e7-41fd-41a7-9c04-b1e10b0c1f26.png", + "twitter": "https://x.com/blockscoutcom", "tags": [ - "education", - "solidity", - "contract-deployment", - "frontend" + "block-explorer", + "chains" ], - "website": "https://speedrunethereum.com/", - "category": "Education & Community Resources", + "website": "http://www.blockscout.com", + "category": "Data, Analytics & Tracing", "repos": [ { - "href": "https://github.com/BuidlGuidl/SpeedRunEthereum-v2", - "stargazers": 26, - "lastUpdated": "2026-01-07T08:54:24Z" - }, - { - "href": "https://github.com/scaffold-eth/se-2-challenges", - "stargazers": 195, - "lastUpdated": "2026-01-07T15:43:49Z" + "href": "https://github.com/blockscout/blockscout", + "stargazers": 4380, + "lastUpdated": "2026-01-20T19:42:29Z" } ] }, { - "id": "manually-added:ethpm", - "name": "ethPM", - "description": "ethPM is the immutable package manager to consume, distribute, or manage any EVM smart contract system.", - "website": "https://www.ethpm.com/", - "thumbnail_url": null, - "banner_url": null, - "twitter": null, + "id": "0xaed5941b7a9f20de83f5c839bda507be43cbf41777fc623abf4bf05773298826", + "name": "Otterscan", + "description": "A blazingly fast, local, Ethereum block explorer built on top of Erigon for EVM chains", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/55a1fffb-dcd9-448b-8e34-9fb4b09a72f7.png", + "banner_url": "https://storage.googleapis.com/op-atlas/a0e75c22-8aff-4176-af81-6c03208c1bd3.png", + "twitter": "https://x.com/otterscan", "tags": [ - "cli", - "solidity", - "contract-management" + "docker", + "block-explorer", + "chains", + "privacy-focused", + "react-app", + "json-rpc", + "visualization" ], - "category": "Smart Contract Development & Toolchains", + "website": "https://otterscan.io/", + "category": "Data, Analytics & Tracing", "repos": [ { - "href": "https://github.com/ethpm/ethpm-cli", - "stargazers": 40, - "lastUpdated": "2020-10-29T20:31:08Z" - }, - { - "href": "https://github.com/ethpm/ethpm-spec", - "stargazers": 166, - "lastUpdated": "2022-02-10T22:25:59Z" - }, - { - "href": "https://github.com/ethpm/ethpm.js", - "stargazers": 13, - "lastUpdated": "2020-12-15T12:00:28Z" - }, - { - "href": "https://github.com/ethpm/py-ethpm", - "stargazers": 24, - "lastUpdated": "2019-12-10T16:25:17Z" + "href": "https://github.com/otterscan/otterscan", + "stargazers": 1396, + "lastUpdated": "2025-11-05T05:21:21Z" } ] }, { - "id": "manually-added:governance-onchain-paymaster", - "name": "Governance Onchain Paymaster", - "description": "Paymasters for on-chain Governance", - "website": null, - "thumbnail_url": null, + "id": "0x97525ec91080ddd917eaccabf9d383cf70a2f78839ab21eeabe1687e312f2132", + "name": "rindexer", + "description": "rindexer is an opensource powerful, high-speed indexing toolset developed in Rust, designed for compatibility with any EVM chain. This tool allows you to index chain events using a simple YAML file, requiring no additional coding. For more advanced needs, the rindexer provides foundations and advanced capabilities to build whatever you want. It's highly extendable, enabling you to construct indexing pipelines with ease and focus exclusively on the logic. rindexer out the box also gives you a GraphQL API to query the data you have indexed instantly.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/366c4940-78cc-4119-958b-b93f3c9a5845.png", "banner_url": null, "twitter": null, "tags": [ - "account-abstraction", - "developer-experience" + "indexing", + "cli" ], - "category": "Transaction & Wallet Infrastructure", + "website": "https://rindexer.xyz/", + "category": "Data, Analytics & Tracing", "repos": [ { - "href": "https://github.com/meliopolis/governance-paymaster", - "stargazers": 0, - "lastUpdated": "2024-04-24T20:45:19Z" + "href": "https://github.com/joshstevens19/rindexer", + "stargazers": 643, + "lastUpdated": "2026-01-20T18:33:58Z" } ] }, { - "id": "manually-added:fealloc", - "name": "FeAlloc", - "description": "Implementing TinyAlloc in Fe-lang for the EVM", - "website": null, - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [], - "category": "Smart Contract Development & Toolchains", + "id": "0x1aacb85f1d87039696b876ddcae98c56d38ea9eed07b265409fdb256c8f8172a", + "name": "Blockhead", + "description": "Open-source portfolio tracker and explorer interface for the decentralized web. https://blockhead.info", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/3a1343aa-8bb3-4f30-abc0-6ba02dd3787a.png", + "banner_url": "https://storage.googleapis.com/op-atlas/7c1ee7ff-ad46-4b74-a941-48cc7ddc2dbe.png", + "twitter": "https://x.com/0xBlockhead", + "tags": [ + "block-explorer" + ], + "website": "https://blockhead.info", + "category": "Data, Analytics & Tracing", "repos": [ { - "href": "https://github.com/saifalkatout/FeAlloc", - "stargazers": 0, - "lastUpdated": "2024-02-29T18:38:55Z" + "href": "https://github.com/darrylyeo/blockhead", + "stargazers": 135, + "lastUpdated": "2025-05-18T04:45:05Z" } ] }, { - "id": "manually-added:solide", - "name": "solide", - "description": "⚡Lightweight web based Smart Contract IDE", - "website": "https://evm.polearn.xyz/", - "thumbnail_url": null, - "banner_url": null, - "twitter": "https://x.com/0xProofOfLearn", + "id": "0xf9c5d092fac6ad924253d685cc7ba21d4e519813e673a3a8300f33cb3a6b4e06", + "name": "NFTScan", + "description": "NFTScan is a professional NFT Explorer tool that provides developers and users with NFT data search services for the Superchain ecosystem, including: OP Mainnet, Base, Mint blockchain and other blockchain networks.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/30fb3451-049c-4904-a109-d3c06004a731.png", + "banner_url": "https://storage.googleapis.com/op-atlas/09a998c5-5217-4937-b2c8-d994e5cfe1c7.png", + "twitter": "https://x.com/nftscan_com", "tags": [ - "solidity", - "developer-experience" + "erc721" ], - "category": "Smart Contract Development & Toolchains", + "website": "https://www.nftscan.com/", + "category": "Data, Analytics & Tracing", "repos": [ { - "href": "https://github.com/solide-project/solide", - "stargazers": 4, - "lastUpdated": "2025-04-12T07:52:29Z" + "href": "https://github.com/nftscan-official/nftscan-api-js-sdk", + "stargazers": 18, + "lastUpdated": "2025-06-13T06:21:00Z" } ] }, { - "id": "manually-added:wallet-test-framework", - "name": "Wallet Test Framework", - "description": "Wallet Testing Framework is an automated test suite for Ethereum wallets that validates the core, shared user flows—such as transfers, balance display, and basic interactions—that every wallet must support. By standardizing testing around these fundamentals, it helps wallet teams improve UX quality, reduce duplicated effort, and focus their energy on building differentiated, value-add features without compromising on reliability.", - "website": "https://wallet-test-framework.github.io/framework/", - "thumbnail_url": null, - "banner_url": null, - "twitter": null, + "id": "0x46aff4985914b8e56b8fd62a9b8c3a03e2320315a9dfd6126e5ae272173cda87", + "name": "Patterns wallet analytics & CRM", + "description": "Free public web3 CRM and wallet analytics for OP builders. Helping OP dApps & DeFis discover most valuable user groups and counteract sybils. Part of the Optimism Superchain 4337 Data Standards group.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/ee4b3aab-f2b2-4400-abbc-2383b62662a4.png", + "banner_url": "https://storage.googleapis.com/op-atlas/b3b3b9a2-81bd-4e6b-af22-c388ca45c9f5.png", + "twitter": "https://x.com/patterns_build", "tags": [ - "testing", - "wallet", - "user-experience", - "developer-experience", - "security" + "analytics", + "defi", + "visualization", + "docker", + "scalability" ], - "category": "Security, Testing & Formal Verification", + "category": "Data, Analytics & Tracing", "repos": [ { - "href": "https://github.com/wallet-test-framework/framework", - "stargazers": 27, - "lastUpdated": "2025-01-13T15:01:29Z" + "href": "https://github.com/tokenguardio/dapp-marvels", + "stargazers": 15, + "lastUpdated": "2025-03-21T11:37:20Z" } ] }, { - "id": "manually-added:edb-the-ethereum-project-debugger", - "name": "EDB: The Ethereum Project Debugger", - "description": "EDB is a source-level Ethereum debugger that bridges high-level Solidity code and low-level EVM execution. It enables step-by-step execution, local variable inspection, custom expression evaluation, and precise breakpoints and watchpoints, giving developers fine-grained control and visibility when debugging smart contracts.", - "website": null, - "thumbnail_url": null, - "banner_url": null, - "twitter": null, + "id": "0x17fb589e599fe05e532b90c121eccc55b1249301e783dae226bad698872322da", + "name": "The Ethernaut", + "description": "The Ethernaut is a community-driven capture-the-flag wargame that challenges developers of all levels to break smart contracts while learning common Solidity vulnerabilities. Maintained by OpenZeppelin, each level provides a gamified experience where a smart contract must be ‘hacked’ to progress. It is 100% open-source, with all levels contributed by players.\n\nIn 2024, we have continued expanding the game, adding four new advanced levels—HigherOrder, Stake, Impersonator, and Magic Animal Carousel—which explore current vulnerabilities in smart contract development. These levels introduce challenges related to low-level EVM programming, staking vulnerabilities, signature verification exploits, and bitwise manipulation attacks, pushing players to deepen their understanding of Ethereum security.\n\nBeyond new levels, we have also redesigned the UI, added support for multiple networks, and expanded language translations to make the game more accessible to a global audience.\n\nWe believe that The Ethernaut is an essential training tool for developers across the Ethereum ecosystem, including those building on the Optimism network. By continually evolving the game with new challenges and features, we strive to make smart contract security education engaging, practical, and accessible to everyone.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/06419654-6022-400a-9670-82ca6e0225fe.png", + "banner_url": "https://storage.googleapis.com/op-atlas/5aba83e1-a4f2-453c-9e64-9884d0e628d6.png", + "twitter": "https://x.com/openzeppelin", "tags": [ + "education", + "security", "solidity", - "debugging-tools", - "developer-experience", - "testing" + "community-driven", + "react-app" ], - "category": "Smart Contract Development & Toolchains", + "website": "https://ethernaut.openzeppelin.com/", + "category": "Education & Community Resources", "repos": [ { - "href": "https://github.com/edb-rs/edb", - "stargazers": 353, - "lastUpdated": "2026-01-16T15:08:48Z" + "href": "https://github.com/OpenZeppelin/ethernaut", + "stargazers": 2273, + "lastUpdated": "2025-11-19T16:57:18Z" } ] }, { - "id": "manually-added:txtx", - "name": "txtx", - "description": "Txtx turns the stress, pain and tears of Smart Contract Infrastructure management by introducing Crypto Infrastructure as Code. \nRunbooks are the blueprint for Engineering Excellence, setting the new standard for Web3 Infrastructures.", - "website": "https://www.txtx.sh/", - "thumbnail_url": null, - "banner_url": "https://framerusercontent.com/assets/5mR0In8TgnrDGVmhFuLEHtvz9d8.png", - "twitter": "https://x.com/Reservoir0x", + "id": "0x72d363f14ae85f47acfe748fb0a2bed73195582bb9863de18901f5dfe309b8f7", + "name": "Solodit", + "description": "What is it?\nSolodit is an open-source, community-driven platform dedicated to improving web3 security. It aggregates over 8,000 smart contract vulnerability reports, bug bounty opportunities, and security audits from top firms like Cyfrin, OpenZeppelin and Trail of Bits, alongside contributions from individual researchers. Solodit not only aggregates this information but also makes it actionable, equipping developers and auditors with tools to prevent exploits and enhance the safety of dapps.\n\nWhy is it needed?\nThe web3 ecosystem is plagued by billions of dollars in losses due to security breaches in smart contracts and protocols. Despite the availability of security knowledge, it is fragmented across various platforms and reports, making it inaccessible to most developers and security teams. There are several problems that Solodit solves:\n\nKnowledge Gap: Many teams deploy smart contracts without understanding past vulnerabilities, leading to repeat incidents.\nInefficiencies: Developers and auditors spend valuable time searching disparate sources for security insights.\nEconomic Impact: Preventable exploits undermine trust in web3, stalling adoption and investment.\n\nBy aggregating and structuring security data, Solodit enables proactive vulnerability management and risk mitigation in the Web3 ecosystem.\n\nHow is it unique?\nComprehensive Coverage: Aggregates findings from leading auditors and platforms, offering unmatched insights into vulnerabilities and bug bounties.\nActionable Insights: Goes beyond archiving reports by providing advanced search tools and tagging systems to contextualise risks and solutions.\nCommunity-Driven Enhancements: Facilitates collaboration via ratings, tagging, and leaderboards that recognise top contributors, fostering a thriving security community.\nEducational Resource: This site serves as a learning hub for developers and auditors, providing real-world case studies on blockchain security.\n\nSolodit is a multipurpose tool designed to:\nMitigate Risk: Helps developers avoid known vulnerabilities, reducing the likelihood of exploits.\nPromote Proactive Security: Enables protocols to adopt preventive measures by studying historical vulnerabilities.\nStreamline Bug Bounties: Simplifies participation in bounty programs, encouraging more ethical hackers to contribute to ecosystem security.\nFoster Skill Development: Supports auditors in honing their skills and staying updated on emerging threats.\nSupport Decision-Making: Assists protocols in evaluating auditors via its leaderboard, promoting accountability and quality audits.\n\nWho is it for?\nDevelopers: Seeking to secure their smart contracts and understand vulnerability trends.\nAuditors: Looking to access a comprehensive repository of findings and showcase their expertise.\nWhitehat Hackers: Interested in participating in bug bounty programs and contributing to web3 security.\nProtocol P&E teams: Aiming to assess risks and prevent costly exploits.\nEducators and Researchers: Teaching or studying blockchain security with real-world examples, e.g. Cyfrin Updraft. \n\nStill to come:\nUI/UX redesign\nPower Aderyn, static analysis support", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/9cf8d92d-5549-4321-b675-c25256860183.png", + "banner_url": "https://storage.googleapis.com/op-atlas/20eb90df-0dd5-41fb-a3ce-f90cf3822492.png", + "twitter": null, "tags": [ - "devops", - "contract-management", - "contract-deployment", - "developer-experience" + "security", + "education", + "analytics", + "community-driven" ], - "category": "Smart Contract Development & Toolchains", + "website": "https://solodit.cyfrin.io/", + "category": "Education & Community Resources", "repos": [ { - "href": "https://github.com/txtx/txtx", - "stargazers": 144, - "lastUpdated": "2025-12-05T18:43:56Z" + "href": "https://github.com/solodit/solodit_content", + "stargazers": 125, + "lastUpdated": "2026-01-10T18:05:45Z" } ] }, { - "id": "manually-added:orbitdb", - "name": "OrbitDB", - "description": "Peer-to-Peer Databases for the Decentralized Web", - "website": null, + "id": "manually-added:speedrunethereum", + "name": "SpeedrunEthereum", + "description": "Speedrun Ethereum is a hands-on series of challenges designed to help you learn by building. Each challenge delivers one key \"aha\" moment, a mental unlock about how Ethereum really works. At the same time, you'll be building your Ethereum portfolio.", "thumbnail_url": null, "banner_url": null, - "twitter": null, + "twitter": "https://x.com/buidlguidl", "tags": [ - "peer-to-peer", - "censorship-resistant" + "education", + "solidity", + "contract-deployment", + "frontend" ], - "category": "Client Libraries & SDKs (Front-End)", + "website": "https://speedrunethereum.com/", + "category": "Education & Community Resources", "repos": [ { - "href": "https://github.com/orbitdb/orbitdb", - "stargazers": 8720, - "lastUpdated": "2025-08-05T01:58:51Z" + "href": "https://github.com/BuidlGuidl/SpeedRunEthereum-v2", + "stargazers": 26, + "lastUpdated": "2026-01-07T08:54:24Z" + }, + { + "href": "https://github.com/scaffold-eth/se-2-challenges", + "stargazers": 195, + "lastUpdated": "2026-01-07T15:43:49Z" } ] }, @@ -5685,46 +1121,6 @@ } ] }, - { - "id": "manually-added:ethereum-rb", - "name": "ethereum.rb", - "description": "Ethereum library for the Ruby language", - "website": null, - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [ - "sdk" - ], - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/EthWorks/ethereum.rb", - "stargazers": 732, - "lastUpdated": "2022-05-11T14:28:01Z" - } - ] - }, - { - "id": "manually-added:hax", - "name": "hax", - "description": "hax is a tool for high assurance translations of a large subset of Rust into formal languages such as F* or Rocq.", - "website": "https://hax.cryspen.com/", - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [ - "formal-verification" - ], - "category": "Security, Testing & Formal Verification", - "repos": [ - { - "href": "https://github.com/cryspen/hax", - "stargazers": 362, - "lastUpdated": "2026-01-19T15:13:10Z" - } - ] - }, { "id": "manually-added:erc-4337-documentation", "name": "ERC-4337 Documentation", @@ -5747,60 +1143,23 @@ ] }, { - "id": "manually-added:intellij-solidity", - "name": "IntelliJ Solidity", - "description": "Solidity plugin for IntelliJ", - "website": "https://intellij-solidity.dev/", - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [ - "solidity", - "developer-experience", - "code-quality" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/intellij-solidity/intellij-solidity", - "stargazers": 1097, - "lastUpdated": "2026-01-19T22:20:07Z" - } - ] - }, - { - "id": "manually-added:w3pk", - "name": "w3pk", - "description": "Passwordless Web3 authentication SDK with encrypted wallets and privacy features.", - "website": "https://w3pk.w3hc.org/", - "thumbnail_url": null, - "banner_url": null, - "twitter": null, + "id": "0xa38c8f4ffa48fe01222fe1b5f2bc6c95e204a4f243d67bd0c9f92887d905d3d8", + "name": "Academy", + "description": "Training, incubation, and acceleration programs for non-tech people and devs to start in the web3 privacy ecosystem.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/153bea66-bef0-481d-bb29-2882eb0e6edb.png", + "banner_url": "https://storage.googleapis.com/op-atlas/1809a100-d320-47f2-8144-94343ef5ea40.png", + "twitter": "https://x.com/web3privacy", "tags": [ - "wallet" + "education" ], - "category": "Transaction & Wallet Infrastructure", + "website": "https://academy.web3privacy.info/", + "category": "Education & Community Resources", "repos": [ { - "href": "https://github.com/w3hc/w3pk", - "stargazers": 2, - "lastUpdated": "2025-12-30T11:30:36Z" + "href": "https://github.com/web3privacy/cypherpunkacademy", + "stargazers": 7, + "lastUpdated": "2025-02-07T18:51:24Z" } ] - }, - { - "id": "manually-added:solidity-testing-handbook", - "name": "Solidity Testing Handbook", - "description": "Solidity Testing Handbook is a comprehensive guide to testing smart contracts in the Solidity programming language. It covers the basics of testing, the different types of tests, and the tools available for testing.", - "website": "https://solidity-testing-handbook.vercel.app/", - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [ - "testing", - "education" - ], - "category": "Education & Community Resources", - "repos": [] } -] \ No newline at end of file +] From 49498659310e843882d5cb6c884daca9bebf4ee4 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Thu, 22 Jan 2026 21:10:30 -0800 Subject: [PATCH 50/74] patch: apply regex pattern filter pre-query --- src/data-layer/fetchers/fetchDeveloperToolsGitHub.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/data-layer/fetchers/fetchDeveloperToolsGitHub.ts b/src/data-layer/fetchers/fetchDeveloperToolsGitHub.ts index 2fe0a6e3b5a..fc47a03c9a2 100644 --- a/src/data-layer/fetchers/fetchDeveloperToolsGitHub.ts +++ b/src/data-layer/fetchers/fetchDeveloperToolsGitHub.ts @@ -30,7 +30,14 @@ function parseGitHubUrl(href: string): RepoInfo | null { } function buildGraphQLQuery(repos: RepoInfo[]): string { + const VALID_REPO_PATTERN = /^[a-zA-Z0-9._-]+$/ + const repoQueries = repos + .filter( + (repo) => + VALID_REPO_PATTERN.test(repo.owner) && + VALID_REPO_PATTERN.test(repo.name) + ) .map( (repo, i) => ` repo${i}: repository(owner: "${repo.owner}", name: "${repo.name}") { From fced7b936254d2600803dc929b02b514b13f7241 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Mon, 26 Jan 2026 17:43:25 -0500 Subject: [PATCH 51/74] refactor: reuse htmlElements in renderSimpleMarkdown - Remove duplicated component definitions from renderSimple.tsx - Allow extended md Paragraph with additional classes - Update AppModalContents to pass overrides explicitly --- .../apps/_components/AppModalContents.tsx | 18 ++- src/components/MdComponents/index.tsx | 6 +- src/lib/md/renderSimple.tsx | 108 ++---------------- 3 files changed, 28 insertions(+), 104 deletions(-) diff --git a/app/[locale]/developers/apps/_components/AppModalContents.tsx b/app/[locale]/developers/apps/_components/AppModalContents.tsx index 820a7f4ebeb..3ed22a8cbb7 100644 --- a/app/[locale]/developers/apps/_components/AppModalContents.tsx +++ b/app/[locale]/developers/apps/_components/AppModalContents.tsx @@ -1,9 +1,11 @@ import { Download, Star } from "lucide-react" import Image from "next/image" import { getLocale, getTranslations } from "next-intl/server" +import type { MDXRemoteProps } from "next-mdx-remote/rsc" import GitHub from "@/components/icons/github.svg" import NpmJs from "@/components/icons/npmjs.svg" +import { htmlElements } from "@/components/MdComponents" import { ButtonLink } from "@/components/ui/buttons/Button" import { Tag, TagsInlineText } from "@/components/ui/tag" @@ -23,6 +25,20 @@ const AppModalContents = async ({ app }: { app: DeveloperApp }) => { const categorySlug = DEV_APP_CATEGORY_SLUGS[app.category] + const BoldedParagraph = (props: { children?: React.ReactNode }) => ( + + ) + + const mdComponentOverrides = { + h1: BoldedParagraph, + h2: BoldedParagraph, + h3: BoldedParagraph, + h4: BoldedParagraph, + h5: BoldedParagraph, + h6: BoldedParagraph, + img: () => null, + } as unknown as MDXRemoteProps["components"] + return (
@@ -53,7 +69,7 @@ const AppModalContents = async ({ app }: { app: DeveloperApp }) => { />
- {await renderSimpleMarkdown(app.description, { img: () => null })} + {await renderSimpleMarkdown(app.description, mdComponentOverrides)}

{t("page-developers-apps-modal-links")}

diff --git a/src/components/MdComponents/index.tsx b/src/components/MdComponents/index.tsx index 25cd13d3cf2..6e909fb0085 100644 --- a/src/components/MdComponents/index.tsx +++ b/src/components/MdComponents/index.tsx @@ -102,8 +102,10 @@ export const Pre = (props: ChildOnlyProp) => ( /> ) -export const Paragraph = (props: ChildOnlyProp) => ( -

+type ParagraphProps = ChildOnlyProp & { className?: string } + +export const Paragraph = ({ className, ...props }: ParagraphProps) => ( +

) export const Blockquote = (props: ChildOnlyProp) => ( diff --git a/src/lib/md/renderSimple.tsx b/src/lib/md/renderSimple.tsx index c0f1d90370c..97a4121b15f 100644 --- a/src/lib/md/renderSimple.tsx +++ b/src/lib/md/renderSimple.tsx @@ -1,110 +1,13 @@ import { compileMDX, type MDXRemoteProps } from "next-mdx-remote/rsc" -import type { HTMLAttributes } from "react" import remarkGfm from "remark-gfm" -import InlineLink from "@/components/ui/Link" -import { ListItem, OrderedList, UnorderedList } from "@/components/ui/list" - -import { cn } from "@/lib/utils/cn" - -type ComponentProps = HTMLAttributes & { - children?: React.ReactNode -} - -/** - * Minimal markdown components for user-generated content - * Stripped down from MdComponents - no tooltips, images, or complex features - */ -const simpleComponents = { - // All headings become bold paragraphs - h1: ({ children, className, ...props }: ComponentProps) => ( -

- {children} -

- ), - h2: ({ children, className, ...props }: ComponentProps) => ( -

- {children} -

- ), - h3: ({ children, className, ...props }: ComponentProps) => ( -

- {children} -

- ), - h4: ({ children, className, ...props }: ComponentProps) => ( -

- {children} -

- ), - h5: ({ children, className, ...props }: ComponentProps) => ( -

- {children} -

- ), - h6: ({ children, className, ...props }: ComponentProps) => ( -

- {children} -

- ), - - // Basic paragraph - p: ({ children, className, ...props }: ComponentProps) => ( -

- {children} -

- ), - - // Lists - ul: (props: ComponentProps) => , - ol: (props: ComponentProps) => , - li: (props: ComponentProps) => , - - // Inline formatting - strong: ({ children, ...props }: ComponentProps) => ( - - {children} - - ), - em: ({ children, ...props }: ComponentProps) => ( - - {children} - - ), - code: ({ children, ...props }: ComponentProps) => ( - - {children} - - ), - - // Links - a: (props: React.AnchorHTMLAttributes) => ( - - ), - - // Blockquote - blockquote: ({ children, ...props }: ComponentProps) => ( -
- {children} -
- ), - - // Horizontal rule - hr: () =>
, -} +import { htmlElements } from "@/components/MdComponents" /** - * Renders simple markdown to React components - * For user-generated content like app descriptions + * Renders markdown to React components using htmlElements. * * @param markdown - The markdown string to render - * @param componentOverrides - Optional component overrides (e.g., { img: () => null }) + * @param componentOverrides - Optional component overrides * @returns React element with rendered markdown */ export async function renderSimpleMarkdown( @@ -113,7 +16,10 @@ export async function renderSimpleMarkdown( ) { const { content } = await compileMDX({ source: markdown, - components: { ...simpleComponents, ...componentOverrides }, + components: { + ...(htmlElements as unknown as MDXRemoteProps["components"]), + ...componentOverrides, + }, options: { parseFrontmatter: false, mdxOptions: { From d91ed58947e3038280f311193856bcc155db4ffa Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Mon, 26 Jan 2026 19:20:36 -0500 Subject: [PATCH 52/74] patch: type cast --- app/[locale]/developers/apps/_components/AppModalContents.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/[locale]/developers/apps/_components/AppModalContents.tsx b/app/[locale]/developers/apps/_components/AppModalContents.tsx index 3ed22a8cbb7..c4669a25d0e 100644 --- a/app/[locale]/developers/apps/_components/AppModalContents.tsx +++ b/app/[locale]/developers/apps/_components/AppModalContents.tsx @@ -37,7 +37,7 @@ const AppModalContents = async ({ app }: { app: DeveloperApp }) => { h5: BoldedParagraph, h6: BoldedParagraph, img: () => null, - } as unknown as MDXRemoteProps["components"] + } as MDXRemoteProps["components"] return (
From f1879e1c5cde12d6ace4305d13253fdd1829b699 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 27 Jan 2026 08:44:45 -0500 Subject: [PATCH 53/74] feat(ui): add fit variant to CardBanner When fit="contain", auto-generates blurred background from single child image. Co-Authored-By: Claude Opus 4.5 --- src/components/ui/card.stories.tsx | 65 ++++++++++++++++++++++++++++++ src/components/ui/card.tsx | 61 +++++++++++++++++++++++----- 2 files changed, 115 insertions(+), 11 deletions(-) create mode 100644 src/components/ui/card.stories.tsx diff --git a/src/components/ui/card.stories.tsx b/src/components/ui/card.stories.tsx new file mode 100644 index 00000000000..53459633bba --- /dev/null +++ b/src/components/ui/card.stories.tsx @@ -0,0 +1,65 @@ +import Image from "next/image" +import { Meta } from "@storybook/react" + +import { VStack } from "@/components/ui/flex" + +import { CardBanner } from "./card" + +const meta = { + title: "Atoms / Display Content / CardBanner", + component: CardBanner, +} satisfies Meta + +export default meta + +// Default (cover) - image fills, may crop +export const FitCover = { + render: () => ( + +

+ Default fit="cover" - image fills container, may be cropped +

+ + + +
+ ), +} + +// Contain - image fully visible, blur background auto-generated +export const FitContain = { + render: () => ( + +

+ fit="contain" - blur background auto-generated from single + image +

+ + + +
+ ), +} + +// Background variants +export const BackgroundVariants = { + render: () => ( + + {( + ["accent-a", "accent-b", "accent-c", "primary", "body", "none"] as const + ).map((bg) => ( +
+

background: {bg}

+ + + +
+ ))} +
+ ), +} diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx index bc4ab5e77fa..11b2f24056e 100644 --- a/src/components/ui/card.tsx +++ b/src/components/ui/card.tsx @@ -52,7 +52,7 @@ CardHeader.displayName = "CardHeader" const cardBannerVariants = cva( cn( "overflow-hidden rounded-2xl", - "[&_img]:size-full [&_img]:object-cover [&_img]:duration-200", + "[&_img]:size-full [&_img]:duration-200", "group-hover/link:[&_img]:scale-110 group-hover/link:[&_img]:duration-200 group-focus/link:[&_img]:scale-110 group-focus/link:[&_img]:duration-200" ), { @@ -73,24 +73,63 @@ const cardBannerVariants = cva( full: "h-48 w-full self-stretch", thumbnail: "size-16 shrink-0", }, + fit: { + cover: "[&_img]:object-cover", + contain: "relative [&_img]:object-contain", + }, }, defaultVariants: { background: "body", size: "full", + fit: "cover", }, } ) -const CardBanner = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes & VariantProps ->(({ className, background, size, ...props }, ref) => ( -
-)) +type CardBannerProps = React.HTMLAttributes & + VariantProps + +const CardBanner = React.forwardRef( + ({ className, background, size, fit, children, ...props }, ref) => { + // When fit="contain", auto-generate blurred background from single child image + const renderContent = () => { + if (fit === "contain" && React.Children.count(children) === 1) { + const child = React.Children.only(children) + if (React.isValidElement<{ className?: string }>(child)) { + // Blurred background + const blurredBg = React.cloneElement(child, { + className: cn( + child.props.className, + "absolute inset-0 -z-10 scale-110 !object-cover blur-xl" + ), + "aria-hidden": true, + } as React.HTMLAttributes) + // Sharp foreground + const sharpFg = React.cloneElement(child, { + className: cn(child.props.className, "!object-contain"), + }) + return ( + <> + {blurredBg} + {sharpFg} + + ) + } + } + return children + } + + return ( +
+ {renderContent()} +
+ ) + } +) CardBanner.displayName = "CardBanner" const titleVariants = cva( From f3562e0310946a9e45466b0e2b92f41c8bc71838 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 27 Jan 2026 08:45:22 -0500 Subject: [PATCH 54/74] feat: add reusable AppCard component Co-Authored-By: Claude Opus 4.5 --- src/components/AppCard/AppCard.stories.tsx | 383 +++++++++++++++++++++ src/components/AppCard/index.tsx | 203 +++++++++++ 2 files changed, 586 insertions(+) create mode 100644 src/components/AppCard/AppCard.stories.tsx create mode 100644 src/components/AppCard/index.tsx diff --git a/src/components/AppCard/AppCard.stories.tsx b/src/components/AppCard/AppCard.stories.tsx new file mode 100644 index 00000000000..e8b44c9bdd8 --- /dev/null +++ b/src/components/AppCard/AppCard.stories.tsx @@ -0,0 +1,383 @@ +import { AppWindowMac } from "lucide-react" +import Image from "next/image" +import { Meta, StoryObj } from "@storybook/react" + +import { CardBanner } from "@/components/ui/card" +import { VStack } from "@/components/ui/flex" +import { LinkBox, LinkOverlay } from "@/components/ui/link-box" +import TruncatedText from "@/components/ui/TruncatedText" + +import AppCard from "." + +const meta = { + title: "Molecules / Display Content / AppCard", + component: AppCard, + decorators: [ + (Story) => ( +
+ +
+ ), + ], +} satisfies Meta + +export default meta + +type Story = StoryObj + +// Sample data using real images +const sampleApp = { + name: "Uniswap", + description: + "Uniswap is a decentralized exchange protocol that allows users to swap tokens without intermediaries. It uses an automated market maker model.", + thumbnail: "/images/dapps/uni.png", + category: "DeFi", + categoryTagStatus: "tag" as const, + tags: ["Exchange", "AMM", "Trading"], +} + +// Layout variants +export const LayoutVertical: Story = { + args: { + ...sampleApp, + layout: "vertical", + href: "/apps/uniswap", + }, +} + +export const LayoutHorizontal: Story = { + args: { + ...sampleApp, + layout: "horizontal", + href: "/apps/uniswap", + }, +} + +export const LayoutComparison = { + render: () => ( + +
+

Vertical (default)

+ +
+
+

Horizontal

+ +
+
+ ), +} + +// Image sizes +export const ImageSizes = { + render: () => ( + + {(["xs", "small", "thumbnail", "medium", "large"] as const).map( + (size) => ( +
+

Size: {size}

+ +
+ ) + )} +
+ ), +} + +// With/without description +export const WithDescription: Story = { + args: { + ...sampleApp, // includes description + layout: "vertical", + href: "/apps/uniswap", + }, +} + +export const WithoutDescription: Story = { + args: { + name: sampleApp.name, + thumbnail: sampleApp.thumbnail, + category: sampleApp.category, + categoryTagStatus: sampleApp.categoryTagStatus, + tags: sampleApp.tags, + // No description prop = no description shown + layout: "vertical", + href: "/apps/uniswap", + }, +} + +// With/without category tag +export const WithCategoryTag: Story = { + args: { + ...sampleApp, // includes category + layout: "vertical", + href: "/apps/uniswap", + }, +} + +export const WithoutCategoryTag: Story = { + args: { + name: sampleApp.name, + description: sampleApp.description, + thumbnail: sampleApp.thumbnail, + // No category prop = no tag shown + tags: sampleApp.tags, + layout: "horizontal", + href: "/apps/uniswap", + }, +} + +// Fallback icon (when no thumbnail) +export const WithFallbackIcon: Story = { + args: { + name: "Unknown App", + description: "An app without a thumbnail image", + tags: ["Development", "Tools"], + layout: "horizontal", + imageSize: "thumbnail", + fallbackIcon: , + href: "/apps/unknown", + }, +} + +// As link vs static +export const AsLink: Story = { + args: { + ...sampleApp, + layout: "horizontal", + href: "/apps/uniswap", + }, + parameters: { + docs: { + description: { + story: + "With `href` prop - renders as a clickable link with hover effect", + }, + }, + }, +} + +export const AsStatic: Story = { + args: { + ...sampleApp, + layout: "horizontal", + }, + parameters: { + docs: { + description: { + story: + "Without `href` prop - renders as static content, no hover effect", + }, + }, + }, +} + +// Different category tag statuses +export const CategoryTagStatuses = { + render: () => ( + + {( + [ + { status: "tag", category: "DeFi" }, + { status: "success", category: "Collectible" }, + { status: "error", category: "Social" }, + { status: "warning", category: "Gaming" }, + { status: "normal", category: "Bridge" }, + ] as const + ).map(({ status, category }) => ( + + ))} + + ), +} + +// Real-world examples +export const AppsPageStyle = { + render: () => ( + +

+ As used on /apps page (vertical with description) +

+ +
+ ), +} + +export const DeveloperAppsPageStyle = { + render: () => ( + +

+ As used on /developers/apps page (horizontal, no category, no tracking) +

+ + } + href="?appId=foundry" + /> +
+ ), +} + +// Category list style (inside bordered container, no card hover) +export const CategoryListStyle = { + render: () => ( + +

+ Apps listed by category (bordered container, no card-level hover) +

+
+
+

DeFi

+
+
+ {[ + { name: "Aave", tags: ["Lending", "Borrowing"] }, + { name: "Uniswap", tags: ["Exchange", "AMM"] }, + { name: "Compound", tags: ["Lending", "Interest"] }, + ].map((app) => ( +
+ +
+ ))} +
+
+
+ ), +} + +// Highlight card style (banner + description + static AppCard) +export const HighlightCardCover = { + render: () => ( + +

+ Banner with fit="cover" - image fills and may crop +

+ + + {/* Banner image - cover crops to fill */} + + App banner + + {/* Description */} +
+ + Uniswap is a decentralized exchange protocol that allows users to + swap tokens without intermediaries. It uses an automated market + maker model for liquidity provision. + +
+ {/* Static AppCard (no href - parent handles link) */} + +
+
+
+ ), +} + +export const HighlightCardContain = { + render: () => ( + +

+ Banner with fit="contain" - image fully visible with blur + background +

+ + + {/* Banner image - contain shows full image with blur bg */} + + App banner + + {/* Description */} +
+ + Uniswap is a decentralized exchange protocol that allows users to + swap tokens without intermediaries. It uses an automated market + maker model for liquidity provision. + +
+ {/* Static AppCard (no href - parent handles link) */} + +
+
+
+ ), +} diff --git a/src/components/AppCard/index.tsx b/src/components/AppCard/index.tsx new file mode 100644 index 00000000000..b373aece90b --- /dev/null +++ b/src/components/AppCard/index.tsx @@ -0,0 +1,203 @@ +import * as React from "react" +import { cva, VariantProps } from "class-variance-authority" + +import type { MatomoEventOptions } from "@/lib/types" + +import { Image } from "@/components/Image" +import { LinkBox, LinkOverlay } from "@/components/ui/link-box" +import { Tag, TagProps, TagsInlineText } from "@/components/ui/tag" +import TruncatedText from "@/components/ui/TruncatedText" + +import { cn } from "@/lib/utils/cn" + +// Outer wrapper variants (hover behavior) +const appCardVariants = cva("group rounded-xl p-2 text-body", { + variants: { + hover: { + highlight: "hover:bg-background-highlight", + none: "", + }, + }, + defaultVariants: { + hover: "highlight", + }, +}) + +const layoutVariants = cva("flex gap-3", { + variants: { + layout: { + horizontal: "", + vertical: "flex-col", + }, + defaultVariant: { + layout: "vertical", + }, + }, +}) + +// Image size variants +const imageSizeVariants = cva("flex shrink-0 overflow-hidden rounded-xl", { + variants: { + size: { + xs: "size-10", // 40px + small: "size-12", // 48px + thumbnail: "size-14", // 56px + medium: "size-16", // 64px + large: "size-24", // 96px + }, + }, + defaultVariants: { + size: "medium", + }, +}) + +type ImageSize = "xs" | "small" | "thumbnail" | "medium" | "large" + +// Map size to pixel values for Image component +const imageSizePixels: Record = { + xs: 40, + small: 48, + thumbnail: 56, + medium: 64, + large: 96, +} + +export interface AppCardProps + extends Omit, "children">, + VariantProps, + VariantProps, + VariantProps { + // Content + name: string + description?: string + thumbnail?: string + category?: string + categoryTagStatus?: TagProps["status"] + tags?: string[] + + // Link + href?: string + + // Layout options + imageSize?: ImageSize + + // Tracking (optional) + customEventOptions?: MatomoEventOptions + descriptionTracking?: MatomoEventOptions + + // Styling + fallbackIcon?: React.ReactNode +} + +const AppCard = React.forwardRef( + ( + { + // Content + name, + description, + thumbnail, + category, + categoryTagStatus, + tags, + // Link + href, + // Layout + layout, + hover, + imageSize, + // Tracking + customEventOptions, + descriptionTracking, + // Styling + className, + fallbackIcon, + ...props + }, + ref + ) => { + const innerContent = ( +
+ {/* Image or fallback */} + {(thumbnail || fallbackIcon) && ( +
+ {thumbnail ? ( + {name} + ) : ( + fallbackIcon + )} +
+ )} + + {/* Content */} +
+ {/* Category tag - shown if category is provided */} + {category && ( + + {category} + + )} + + {/* Name - hover effect triggers when inside a group (LinkBox) */} +

+ {name} +

+ + {/* Description - shown if description is provided */} + {description && ( + + {description} + + )} + + {/* Tags */} + {tags && tags.length > 0 && ( + + )} +
+
+ ) + + // Static card (no link) - no wrapper padding, just the content + if (!href) { + return ( +
+ {innerContent} +
+ ) + } + + // Linked card - uses hover prop + return ( + + + {innerContent} + + + ) + } +) +AppCard.displayName = "AppCard" + +export default AppCard From 1cfe39f84a49877a8e53a158b3688870ca13fac9 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 27 Jan 2026 09:42:46 -0500 Subject: [PATCH 55/74] refactor: migrate /apps section to new AppCard component - Migrate all 6 /apps consumer files to new component - Delete old app/[locale]/apps/_components/AppCard.tsx Files migrated: - app/[locale]/apps/page.tsx - app/[locale]/apps/[application]/page.tsx - app/[locale]/apps/_components/AppsTable.tsx - app/[locale]/apps/_components/CommunityPicks.tsx - app/[locale]/apps/_components/AppsHighlight.tsx - app/[locale]/apps/_components/TopApps.tsx Co-Authored-By: Claude Opus 4.5 --- app/[locale]/apps/[application]/page.tsx | 30 +++-- app/[locale]/apps/_components/AppCard.tsx | 114 ------------------ .../apps/_components/AppsHighlight.tsx | 15 ++- app/[locale]/apps/_components/AppsTable.tsx | 20 +-- .../apps/_components/CommunityPicks.tsx | 65 +++++++--- app/[locale]/apps/_components/TopApps.tsx | 51 ++++---- app/[locale]/apps/page.tsx | 32 +++-- 7 files changed, 144 insertions(+), 183 deletions(-) delete mode 100644 app/[locale]/apps/_components/AppCard.tsx diff --git a/app/[locale]/apps/[application]/page.tsx b/app/[locale]/apps/[application]/page.tsx index 066a9bd41de..25307364934 100644 --- a/app/[locale]/apps/[application]/page.tsx +++ b/app/[locale]/apps/[application]/page.tsx @@ -8,6 +8,7 @@ import { import type { ChainName, CommitHistory, Lang, PageParams } from "@/lib/types" +import AppCard from "@/components/AppCard" import ChainImages from "@/components/ChainImages" import { ChevronNext } from "@/components/Chevron" import I18nProvider from "@/components/I18nProvider" @@ -41,8 +42,6 @@ import { import { slugify } from "@/lib/utils/url" import { formatStringList } from "@/lib/utils/wallets" -import AppCard from "../_components/AppCard" - import ScreenshotSwiper from "./_components/ScreenshotSwiper" import AppsAppJsonLD from "./page-jsonld" @@ -366,12 +365,27 @@ const Page = async ({ className="flex-1 lg:w-1/3 lg:flex-none" >
))} diff --git a/app/[locale]/apps/_components/AppCard.tsx b/app/[locale]/apps/_components/AppCard.tsx deleted file mode 100644 index bc499bd1a63..00000000000 --- a/app/[locale]/apps/_components/AppCard.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import { AppData } from "@/lib/types" - -import { Image } from "@/components/Image" -import { LinkBox, LinkOverlay } from "@/components/ui/link-box" -import { Tag, TagsInlineText } from "@/components/ui/tag" -import TruncatedText from "@/components/ui/TruncatedText" - -import { APP_TAG_VARIANTS } from "@/lib/utils/apps" -import { cn } from "@/lib/utils/cn" -import { slugify } from "@/lib/utils/url" - -import { SIZE_CLASS_MAPPING } from "@/lib/constants" - -interface AppCardProps { - app: AppData - imageSize: number - isVertical?: boolean - showDescription?: boolean - hideTag?: boolean - disableLink?: boolean - hoverClassName?: string - matomoCategory: string - matomoAction: string -} - -const AppCard = ({ - app, - imageSize, - isVertical = false, - showDescription = false, - hideTag = false, - disableLink = false, - hoverClassName, - matomoCategory, - matomoAction, -}: AppCardProps) => { - const cardContent = ( -
-
- {app.name} -
-
- {!hideTag && ( - - {app.category} - - )} -

- {app.name} -

- {showDescription && ( - - {app.description} - - )} - -
-
- ) - - if (disableLink) { - return cardContent - } - - return ( - - - {cardContent} - - - ) -} - -export default AppCard diff --git a/app/[locale]/apps/_components/AppsHighlight.tsx b/app/[locale]/apps/_components/AppsHighlight.tsx index df2181a400b..40487d68c0a 100644 --- a/app/[locale]/apps/_components/AppsHighlight.tsx +++ b/app/[locale]/apps/_components/AppsHighlight.tsx @@ -1,12 +1,13 @@ import { AppData } from "@/lib/types" +import AppCard from "@/components/AppCard" import { Image } from "@/components/Image" import { LinkBox, LinkOverlay } from "@/components/ui/link-box" import TruncatedText from "@/components/ui/TruncatedText" +import { APP_TAG_VARIANTS } from "@/lib/utils/apps" import { slugify } from "@/lib/utils/url" -import AppCard from "./AppCard" import AppsSwiper from "./AppsSwiper" interface AppsHighlightProps { @@ -49,11 +50,13 @@ const AppsHighlight = ({ apps, matomoCategory }: AppsHighlightProps) => {
diff --git a/app/[locale]/apps/_components/AppsTable.tsx b/app/[locale]/apps/_components/AppsTable.tsx index 0746c3b2938..e70b387cfd1 100644 --- a/app/[locale]/apps/_components/AppsTable.tsx +++ b/app/[locale]/apps/_components/AppsTable.tsx @@ -4,6 +4,7 @@ import { useMemo, useState } from "react" import { AppData } from "@/lib/types" +import AppCard from "@/components/AppCard" import { Select, SelectContent, @@ -13,8 +14,7 @@ import { } from "@/components/ui/select" import { trackCustomEvent } from "@/lib/utils/matomo" - -import AppCard from "./AppCard" +import { slugify } from "@/lib/utils/url" import useTranslation from "@/hooks/useTranslation" @@ -95,11 +95,17 @@ const AppsTable = ({ apps }: { apps: AppData[] }) => { {filteredApps.map((app) => (
))} diff --git a/app/[locale]/apps/_components/CommunityPicks.tsx b/app/[locale]/apps/_components/CommunityPicks.tsx index ccb02d4d213..3d3affe50d6 100644 --- a/app/[locale]/apps/_components/CommunityPicks.tsx +++ b/app/[locale]/apps/_components/CommunityPicks.tsx @@ -1,10 +1,13 @@ import { AppData, CommunityPick } from "@/lib/types" +import AppCard from "@/components/AppCard" import Twitter from "@/components/icons/twitter.svg" import { Image } from "@/components/Image" import { ButtonLink } from "@/components/ui/buttons/Button" -import AppCard from "./AppCard" +import { APP_TAG_VARIANTS } from "@/lib/utils/apps" +import { slugify } from "@/lib/utils/url" + import AppsSwiper from "./AppsSwiper" const CommunityPicks = ({ @@ -50,24 +53,48 @@ const CommunityPicks = ({
- {pick.app1Name && getApp(pick.app1Name) && ( - - )} - {pick.app2Name && getApp(pick.app2Name) && ( - - )} + {pick.app1Name && + getApp(pick.app1Name) && + (() => { + const app = getApp(pick.app1Name)! + return ( + + ) + })()} + {pick.app2Name && + getApp(pick.app2Name) && + (() => { + const app = getApp(pick.app2Name)! + return ( + + ) + })()}
)) diff --git a/app/[locale]/apps/_components/TopApps.tsx b/app/[locale]/apps/_components/TopApps.tsx index 9acd01e7267..b3d8f89509d 100644 --- a/app/[locale]/apps/_components/TopApps.tsx +++ b/app/[locale]/apps/_components/TopApps.tsx @@ -4,6 +4,7 @@ import { Folder } from "lucide-react" import { AppCategory, AppData } from "@/lib/types" +import AppCard, { type AppCardProps } from "@/components/AppCard" import { Button } from "@/components/ui/buttons/Button" import { LinkBox, LinkOverlay } from "@/components/ui/link-box" import { @@ -19,8 +20,6 @@ import { slugify } from "@/lib/utils/url" import { appsCategories } from "@/data/apps/categories" -import AppCard from "./AppCard" - import { useBreakpointValue } from "@/hooks/useBreakpointValue" import { useIsClient } from "@/hooks/useIsClient" import useTranslation from "@/hooks/useTranslation" @@ -32,36 +31,39 @@ interface TopAppsProps { const TopApps = ({ appsData }: TopAppsProps) => { const { t } = useTranslation("page-apps") const isClient = useIsClient() - const cardStyling = useBreakpointValue({ + const cardStyling = useBreakpointValue<{ + layout: AppCardProps["layout"] + imageSize: AppCardProps["imageSize"] + }>({ base: { - isVertical: true, - imageSize: 12, + layout: "vertical", + imageSize: "small", }, sm: { - isVertical: true, - imageSize: 12, + layout: "vertical", + imageSize: "small", }, md: { - isVertical: true, - imageSize: 12, + layout: "vertical", + imageSize: "small", }, lg: { - isVertical: false, - imageSize: 16, + layout: "horizontal", + imageSize: "medium", }, xl: { - isVertical: false, - imageSize: 16, + layout: "horizontal", + imageSize: "medium", }, "2xl": { - isVertical: false, - imageSize: 16, + layout: "horizontal", + imageSize: "medium", }, }) // Use fallback values during SSR to prevent hydration mismatch - const imageSize = isClient ? cardStyling.imageSize : 12 - const isVertical = isClient ? cardStyling.isVertical : true + const imageSize = isClient ? cardStyling.imageSize : "small" + const layout = isClient ? cardStyling.layout : "vertical" return ( @@ -140,12 +142,17 @@ const TopApps = ({ appsData }: TopAppsProps) => { {appsData[category].slice(0, 5).map((app) => (
))} diff --git a/app/[locale]/apps/page.tsx b/app/[locale]/apps/page.tsx index 3a75854e393..44a07b8f30e 100644 --- a/app/[locale]/apps/page.tsx +++ b/app/[locale]/apps/page.tsx @@ -7,20 +7,25 @@ import { import { CommitHistory, Lang, PageParams } from "@/lib/types" +import AppCard from "@/components/AppCard" import Breadcrumbs from "@/components/Breadcrumbs" import { SimpleHero } from "@/components/Hero" import I18nProvider from "@/components/I18nProvider" import MainArticle from "@/components/MainArticle" import SubpageCard from "@/components/SubpageCard" -import { getDiscoverApps, getHighlightedApps } from "@/lib/utils/apps" +import { + APP_TAG_VARIANTS, + getDiscoverApps, + getHighlightedApps, +} from "@/lib/utils/apps" import { getAppPageContributorInfo } from "@/lib/utils/contributors" import { getMetadata } from "@/lib/utils/metadata" import { getRequiredNamespacesForPage } from "@/lib/utils/translations" +import { slugify } from "@/lib/utils/url" import { appsCategories } from "@/data/apps/categories" -import AppCard from "./_components/AppCard" import AppsHighlight from "./_components/AppsHighlight" import CommunityPicks from "./_components/CommunityPicks" import SuggestAnApp from "./_components/SuggestAnApp" @@ -99,11 +104,24 @@ const Page = async ({ params }: { params: PageParams }) => { {discoverApps.map((app) => ( ))}
From a2247fbba0800f06b1a1849ed4a4bd43c5815c90 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 27 Jan 2026 10:40:16 -0500 Subject: [PATCH 56/74] feat(AppCard): add named groups and default icon - Use group/appcard for isolated hover contexts - Add AppWindowMac as default fallback icon - Auto scroll={false} for query-param links (?...) - Title responds to both parent and own group hover Co-Authored-By: Claude Opus 4.5 --- src/components/AppCard/index.tsx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/components/AppCard/index.tsx b/src/components/AppCard/index.tsx index b373aece90b..609de413227 100644 --- a/src/components/AppCard/index.tsx +++ b/src/components/AppCard/index.tsx @@ -1,5 +1,6 @@ import * as React from "react" import { cva, VariantProps } from "class-variance-authority" +import { AppWindowMac } from "lucide-react" import type { MatomoEventOptions } from "@/lib/types" @@ -11,7 +12,7 @@ import TruncatedText from "@/components/ui/TruncatedText" import { cn } from "@/lib/utils/cn" // Outer wrapper variants (hover behavior) -const appCardVariants = cva("group rounded-xl p-2 text-body", { +const appCardVariants = cva("group/appcard rounded-xl p-2 text-body", { variants: { hover: { highlight: "hover:bg-background-highlight", @@ -110,7 +111,7 @@ const AppCard = React.forwardRef( descriptionTracking, // Styling className, - fallbackIcon, + fallbackIcon = , ...props }, ref @@ -129,7 +130,7 @@ const AppCard = React.forwardRef( {name} @@ -149,7 +150,7 @@ const AppCard = React.forwardRef( )} {/* Name - hover effect triggers when inside a group (LinkBox) */} -

+

{name}

@@ -174,7 +175,11 @@ const AppCard = React.forwardRef( // Static card (no link) - no wrapper padding, just the content if (!href) { return ( -
+
{innerContent}
) @@ -189,6 +194,7 @@ const AppCard = React.forwardRef( > From 1c56ac9a0a7b2711cb90c6e81a414ba76eb04ff7 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 27 Jan 2026 10:40:50 -0500 Subject: [PATCH 57/74] refactor(developers/apps): migrate to AppCard - Replace inline card markup with AppCard component - Simplify HighlightsSection banner with fit="contain" - Use AppCard for preview, grid, and highlight cards - Remove redundant imports (Image, LinkBox, etc.) Co-Authored-By: Claude Opus 4.5 --- .../developers/apps/[category]/page.tsx | 48 ++++---------- .../apps/_components/HighlightsSection.tsx | 62 +++++-------------- app/[locale]/developers/apps/page.tsx | 47 ++++---------- 3 files changed, 40 insertions(+), 117 deletions(-) diff --git a/app/[locale]/developers/apps/[category]/page.tsx b/app/[locale]/developers/apps/[category]/page.tsx index 4dd8f8a2510..5d59dcc123d 100644 --- a/app/[locale]/developers/apps/[category]/page.tsx +++ b/app/[locale]/developers/apps/[category]/page.tsx @@ -1,16 +1,13 @@ -import { AppWindowMac } from "lucide-react" -import Image from "next/image" import { redirect } from "next/navigation" import { getTranslations, setRequestLocale } from "next-intl/server" import type { CommitHistory, Lang, PageParams } from "@/lib/types" +import AppCard from "@/components/AppCard" import { ContentHero } from "@/components/Hero" import MainArticle from "@/components/MainArticle" import SubpageCard from "@/components/SubpageCard" -import { LinkBox, LinkOverlay } from "@/components/ui/link-box" import { Section } from "@/components/ui/section" -import { TagsInlineText } from "@/components/ui/tag" import { getAppPageContributorInfo } from "@/lib/utils/contributors" import { getMetadata } from "@/lib/utils/metadata" @@ -146,39 +143,18 @@ const Page = async ({
{categoryData.map((app) => ( - - -
- {app.thumbnail_url ? ( - - ) : ( - - )} -
-
-

{app.name}

- - t(`page-developers-apps-tag-${tag}`) - )} - variant="light" - className="lowercase" - /> -
-
-
+ name={app.name} + thumbnail={app.thumbnail_url} + tags={app.tags.map((tag) => + t(`page-developers-apps-tag-${tag}`) + )} + href={buildAppLink(app.id)} + layout="horizontal" + imageSize="thumbnail" + className="h-fit p-4" + /> ))}

diff --git a/app/[locale]/developers/apps/_components/HighlightsSection.tsx b/app/[locale]/developers/apps/_components/HighlightsSection.tsx index 9b833366211..bd442816a1c 100644 --- a/app/[locale]/developers/apps/_components/HighlightsSection.tsx +++ b/app/[locale]/developers/apps/_components/HighlightsSection.tsx @@ -1,14 +1,14 @@ import Image from "next/image" import { getLocale, getTranslations } from "next-intl/server" -import { CardBanner, CardParagraph, CardTitle } from "@/components/ui/card" +import AppCard from "@/components/AppCard" +import { CardBanner, CardParagraph } from "@/components/ui/card" import { EdgeScrollContainer, EdgeScrollItem, } from "@/components/ui/edge-scroll-container" import { LinkBox, LinkOverlay } from "@/components/ui/link-box" import { Section } from "@/components/ui/section" -import { Tag, TagsInlineText } from "@/components/ui/tag" import { cn } from "@/lib/utils/cn" @@ -19,7 +19,6 @@ import { getCategoryTagStyle } from "../utils" const HighlightsSection = async ({ apps }: { apps: DeveloperApp[] }) => { const locale = await getLocale() const t = await getTranslations({ locale, namespace: "page-developers-apps" }) - const tCommon = await getTranslations({ locale, namespace: "common" }) // Don't render section if no apps to highlight if (apps.length === 0) return null @@ -52,61 +51,32 @@ const HighlightsSection = async ({ apps }: { apps: DeveloperApp[] }) => { className="space-y-6 no-underline" >
- + - {app.description}
-
- - {tCommon("item-logo", - - -
- - {t( - `page-developers-apps-category-${categorySlug}-title` - )} - - - {app.name} - - - t(`page-developers-apps-tag-${tag}`) - )} - variant="light" - className="lowercase" - /> -
-
+ + t(`page-developers-apps-tag-${tag}`) + )} + layout="horizontal" + imageSize="medium" + /> diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/apps/page.tsx index 65bd9846f75..ac53bd06ae9 100644 --- a/app/[locale]/developers/apps/page.tsx +++ b/app/[locale]/developers/apps/page.tsx @@ -1,10 +1,9 @@ -import { AppWindowMac } from "lucide-react" -import Image from "next/image" import { redirect } from "next/navigation" import { getTranslations, setRequestLocale } from "next-intl/server" import type { CommitHistory, Lang, PageParams } from "@/lib/types" +import AppCard from "@/components/AppCard" import { ContentHero } from "@/components/Hero" import MainArticle from "@/components/MainArticle" import SubpageCard from "@/components/SubpageCard" @@ -16,7 +15,6 @@ import { } from "@/components/ui/edge-scroll-container" import { LinkBox, LinkOverlay } from "@/components/ui/link-box" import { Section } from "@/components/ui/section" -import { TagsInlineText } from "@/components/ui/tag" import { getAppPageContributorInfo } from "@/lib/utils/contributors" import { getMetadata } from "@/lib/utils/metadata" @@ -122,39 +120,18 @@ const Page = async ({ {previewsByCategory[slug].map((app) => ( - - -
- {app.thumbnail_url ? ( - - ) : ( - - )} -
-
-

{app.name}

- - t(`page-developers-apps-tag-${tag}`) - )} - variant="light" - className="lowercase" - /> -
-
-
+ name={app.name} + thumbnail={app.thumbnail_url} + tags={app.tags.map((tag) => + t(`page-developers-apps-tag-${tag}`) + )} + href={`?appId=${app.id}`} + layout="horizontal" + imageSize="thumbnail" + className="rounded-none border-t p-4" + /> ))} From d262850318243c4a54b648618098e16720f69501 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 27 Jan 2026 12:13:05 -0500 Subject: [PATCH 58/74] patch: named group-hover, fixes hover on category app stack --- app/[locale]/developers/apps/_components/HighlightsSection.tsx | 2 +- src/components/AppCard/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/[locale]/developers/apps/_components/HighlightsSection.tsx b/app/[locale]/developers/apps/_components/HighlightsSection.tsx index bd442816a1c..dd6b157c3d0 100644 --- a/app/[locale]/developers/apps/_components/HighlightsSection.tsx +++ b/app/[locale]/developers/apps/_components/HighlightsSection.tsx @@ -41,7 +41,7 @@ const HighlightsSection = async ({ apps }: { apps: DeveloperApp[] }) => { > diff --git a/src/components/AppCard/index.tsx b/src/components/AppCard/index.tsx index 609de413227..10d92d17475 100644 --- a/src/components/AppCard/index.tsx +++ b/src/components/AppCard/index.tsx @@ -150,7 +150,7 @@ const AppCard = React.forwardRef( )} {/* Name - hover effect triggers when inside a group (LinkBox) */} -

+

{name}

From 715951ed23d85336c91f029976486f732dd2dde1 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 27 Jan 2026 13:50:46 -0500 Subject: [PATCH 59/74] feat(ui): add reusable FilterBar component - Add filter-bar-* i18n keys to common.json namespace - Create FilterBar component with searchable combobox (Command + Popover) - Add Storybook stories for component testing Co-Authored-By: Claude Opus 4.5 --- .../FilterBar/FilterBar.stories.tsx | 98 ++++++++++++ src/components/FilterBar/index.tsx | 146 ++++++++++++++++++ src/intl/en/common.json | 5 + 3 files changed, 249 insertions(+) create mode 100644 src/components/FilterBar/FilterBar.stories.tsx create mode 100644 src/components/FilterBar/index.tsx diff --git a/src/components/FilterBar/FilterBar.stories.tsx b/src/components/FilterBar/FilterBar.stories.tsx new file mode 100644 index 00000000000..0b237cd6cb0 --- /dev/null +++ b/src/components/FilterBar/FilterBar.stories.tsx @@ -0,0 +1,98 @@ +import { useState } from "react" +import type { Meta } from "@storybook/react" + +import FilterBar from "./" + +const meta = { + title: "Molecules / Navigation / FilterBar", + component: FilterBar, + parameters: { + layout: "fullscreen", + }, + decorators: [ + (Story) => ( +
+ +
+ ), + ], +} satisfies Meta + +export default meta + +const sampleItems = [ + { value: "defi", label: "DeFi" }, + { value: "nft", label: "NFTs" }, + { value: "gaming", label: "Gaming" }, + { value: "social", label: "Social" }, + { value: "identity", label: "Identity" }, +] + +const manyItems = [ + { value: "analytics", label: "Analytics" }, + { value: "bridges", label: "Bridges" }, + { value: "dao", label: "DAOs" }, + { value: "defi", label: "DeFi" }, + { value: "developer-tools", label: "Developer Tools" }, + { value: "gaming", label: "Gaming" }, + { value: "identity", label: "Identity" }, + { value: "infrastructure", label: "Infrastructure" }, + { value: "marketplaces", label: "Marketplaces" }, + { value: "nft", label: "NFTs" }, + { value: "payments", label: "Payments" }, + { value: "security", label: "Security" }, + { value: "social", label: "Social" }, + { value: "storage", label: "Storage" }, + { value: "wallets", label: "Wallets" }, +] + +export const Default = { + render: () => { + const [value, setValue] = useState() + const filteredCount = value ? 12 : 48 + + return ( + + ) + }, +} + +export const WithActiveFilter = { + render: () => { + const [value, setValue] = useState("defi") + const filteredCount = value ? 12 : 48 + + return ( + + ) + }, +} + +export const ManyItems = { + render: () => { + const [value, setValue] = useState() + const filteredCount = value ? 8 : 120 + + return ( + + ) + }, +} diff --git a/src/components/FilterBar/index.tsx b/src/components/FilterBar/index.tsx new file mode 100644 index 00000000000..a6b6751af66 --- /dev/null +++ b/src/components/FilterBar/index.tsx @@ -0,0 +1,146 @@ +"use client" + +import { useState } from "react" +import { Check, ChevronDown, X } from "lucide-react" +import { useTranslations } from "next-intl" + +import type { MatomoEventOptions } from "@/lib/types" + +import { Button } from "@/components/ui/buttons/Button" +import { + Command, + CommandEmpty, + CommandInput, + CommandItem, + CommandList, +} from "@/components/ui/command" +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover" + +import { trackCustomEvent } from "@/lib/utils/matomo" + +export type FilterBarProps = { + /** Items available for filtering */ + items: { value: string; label: string }[] + + /** Currently selected value (undefined = no filter) */ + value?: string + + /** Callback when selection changes */ + onValueChange: (value: string | undefined) => void + + /** Number of items after filtering */ + count: number + + /** Total number of items (unfiltered) */ + totalCount: number + + /** Optional Matomo tracking config */ + matomoEvent?: MatomoEventOptions +} + +export default function FilterBar({ + items, + value, + onValueChange, + count, + totalCount, + matomoEvent, +}: FilterBarProps) { + const t = useTranslations("common") + const [open, setOpen] = useState(false) + + const selectedLabel = items.find((item) => item.value === value)?.label + + const handleSelect = (selectedValue: string) => { + onValueChange(selectedValue) + setOpen(false) + if (matomoEvent) { + trackCustomEvent({ + ...matomoEvent, + eventName: `filter: ${selectedValue}`, + }) + } + } + + const handleClear = () => { + onValueChange(undefined) + if (matomoEvent) { + trackCustomEvent({ + ...matomoEvent, + eventName: "filter: cleared", + }) + } + } + + const COMBOBOX_ID = "filter-bar-listbox" + + const countDisplay = + count !== totalCount ? `${count}/${totalCount}` : `${count}` + + return ( +
+
+ + + + + + + + + {t("filter-bar-no-results")} + {items.map((item) => ( + handleSelect(item.value)} + className="flex items-center justify-between" + > + {item.label} + {value === item.value && ( + + )} + + ))} + + + + + + {value && ( + + )} +
+ +

+ {t("filter-bar-showing")}{" "} + ({countDisplay}) +

+
+ ) +} diff --git a/src/intl/en/common.json b/src/intl/en/common.json index 3df2a11e9e8..4558b90583c 100644 --- a/src/intl/en/common.json +++ b/src/intl/en/common.json @@ -120,6 +120,11 @@ "feedback-widget-thank-you-subtitle-ext": "If you need help, you can reach out to the community on our
Discord.", "feedback-widget-thank-you-timing": "2–3 min", "feedback-widget-thank-you-title": "Thank you for your feedback!", + "filter-bar-clear": "Clear filter", + "filter-bar-empty": "No items match the selected filter", + "filter-bar-no-results": "No results found", + "filter-bar-placeholder": "Filter by", + "filter-bar-showing": "Showing", "find-wallet": "Find wallet", "founders": "Founders", "from": "From", From 766f54e6134207bbeb45fe93cb2f0125dac07765 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 27 Jan 2026 15:26:44 -0500 Subject: [PATCH 60/74] refactor(apps): migrate AppsTable to use FilterBar component - Replace Select dropdown with reusable FilterBar Co-Authored-By: Claude Opus 4.5 --- app/[locale]/apps/_components/AppsTable.tsx | 83 +++++---------------- 1 file changed, 20 insertions(+), 63 deletions(-) diff --git a/app/[locale]/apps/_components/AppsTable.tsx b/app/[locale]/apps/_components/AppsTable.tsx index 0746c3b2938..23ecdd542ea 100644 --- a/app/[locale]/apps/_components/AppsTable.tsx +++ b/app/[locale]/apps/_components/AppsTable.tsx @@ -4,23 +4,12 @@ import { useMemo, useState } from "react" import { AppData } from "@/lib/types" -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@/components/ui/select" - -import { trackCustomEvent } from "@/lib/utils/matomo" +import FilterBar from "@/components/FilterBar" import AppCard from "./AppCard" -import useTranslation from "@/hooks/useTranslation" - const AppsTable = ({ apps }: { apps: AppData[] }) => { - const { t } = useTranslation("page-apps") - const [filterBy, setFilterBy] = useState("All") + const [filterBy, setFilterBy] = useState() const subCategories = useMemo( () => [...new Set(apps.flatMap((app) => app.subCategory))], @@ -34,63 +23,31 @@ const AppsTable = ({ apps }: { apps: AppData[] }) => { const filteredApps = useMemo( () => apps.filter((app) => { - if (filterBy === "All") return true + if (!filterBy) return true return app.subCategory.includes(filterBy) }), [apps, filterBy] ) + const filterItems = subCategories.map((subCategory) => ({ + value: subCategory, + label: `${subCategory} (${getSubCategoryCount(subCategory)})`, + })) + return (
-
-
-

{t("page-apps-filter-by")}

- -
-
-

- {t("page-apps-showing")}{" "} - - ( - {filteredApps.length === apps.length - ? apps.length - : `${filteredApps.length}/${apps.length}`} - ) - -

-
-
+
{filteredApps.map((app) => (
From 85d255d47f232eec39d9927e8f3a29addc12d8f9 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 27 Jan 2026 16:13:21 -0500 Subject: [PATCH 61/74] feat: pre-compute developer apps selections in data layer Move randomization of highlighted apps and category previews from page-level unstable_cache to data-layer (trigger.dev task). Changes: - Add DeveloperToolsDataEnvelope type with appsById lookup + selections - Pre-compute selections (mainPageHighlights, categoryHighlights, categoryPreviews) in trigger.dev task - Remove unstable_cache wrappers from utils.ts, revert unused `every` time util addition - Update page components to use pre-computed selections with O(1) lookups - Transform mock data to envelope format This fixes cache invalidation issues caused by unstable_cache creating unique keys from function arguments (searchParams). Selections now persist daily and are consistent for all users. Co-Authored-By: Claude Opus 4.5 --- .../developers/apps/[category]/page.tsx | 30 +- app/[locale]/developers/apps/page.tsx | 37 +- app/[locale]/developers/apps/types.ts | 26 + app/[locale]/developers/apps/utils.ts | 48 - .../fetchers/fetchDeveloperTools.ts | 54 +- src/data-layer/index.ts | 5 +- .../mocks/fetch-developer-tools.json | 2421 +++++++++-------- src/lib/utils/time.ts | 34 - 8 files changed, 1374 insertions(+), 1281 deletions(-) diff --git a/app/[locale]/developers/apps/[category]/page.tsx b/app/[locale]/developers/apps/[category]/page.tsx index 4dd8f8a2510..fbca24eb4d1 100644 --- a/app/[locale]/developers/apps/[category]/page.tsx +++ b/app/[locale]/developers/apps/[category]/page.tsx @@ -19,13 +19,8 @@ import AppModalContents from "../_components/AppModalContents" import AppModalWrapper from "../_components/AppModalWrapper" import HighlightsSection from "../_components/HighlightsSection" import TagFilter from "../_components/TagFilter" -import { DEV_APP_CATEGORIES } from "../constants" +import { DEV_APP_CATEGORIES, DEV_APP_CATEGORY_SLUGS } from "../constants" import type { DeveloperAppCategorySlug, DeveloperAppTag } from "../types" -import { - getCachedHighlightsByCategory, - getCategoryPageHighlights, -} from "../utils" -import { transformDeveloperAppsData } from "../utils" import DevelopersAppsCategoryJsonLD from "./page-jsonld" @@ -44,10 +39,16 @@ const Page = async ({ setRequestLocale(locale) const t = await getTranslations({ locale, namespace: "page-developers-apps" }) - const enrichedData = await getDeveloperToolsData() - if (!enrichedData) throw Error("No developer apps data available") - const dataByCategory = transformDeveloperAppsData(enrichedData) - const allCategoryData = dataByCategory[category] + const data = await getDeveloperToolsData() + if (!data) throw Error("No developer apps data available") + + const { appsById, selections } = data + + // Get all apps for this category (filter at runtime - trivial for few hundred apps) + const allApps = Object.values(appsById) + const allCategoryData = allApps.filter( + (app) => DEV_APP_CATEGORY_SLUGS[app.category] === category + ) // Extract unique tags from current category const uniqueTags = Array.from( @@ -63,7 +64,7 @@ const Page = async ({ ? allCategoryData.filter((app) => app.tags.includes(validTag)) : allCategoryData - const activeApp = enrichedData.find((app) => app.id === appId) + const activeApp = appId ? appsById[appId] : undefined // Clean up invalid searchParams by redirecting const hasInvalidTag = tag && !validTag @@ -89,9 +90,10 @@ const Page = async ({ showing: t("page-developers-apps-filter-showing"), } - // Get dynamic highlights based on stars and recent activity (cached weekly) - const highlightsByCategory = await getCachedHighlightsByCategory(enrichedData) - const highlights = getCategoryPageHighlights(highlightsByCategory, category) + // Resolve category highlight IDs to full app objects + const highlights = (selections.categoryHighlights[category] || []) + .map((id) => appsById[id]) + .filter(Boolean) // Helper to build app modal link with preserved tag param const buildAppLink = (appId: string) => { diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/apps/page.tsx index 65bd9846f75..2e795619ea7 100644 --- a/app/[locale]/developers/apps/page.tsx +++ b/app/[locale]/developers/apps/page.tsx @@ -26,12 +26,7 @@ import AppModalWrapper from "./_components/AppModalWrapper" import HighlightsSection from "./_components/HighlightsSection" import { DEV_APP_CATEGORIES } from "./constants" import DevelopersAppsJsonLD from "./page-jsonld" -import { - getCachedHighlightsByCategory, - getCachedRandomPreviewsByCategory, - getMainPageHighlights, -} from "./utils" -import { transformDeveloperAppsData } from "./utils" +import type { DeveloperAppsByCategory } from "./types" import { getDeveloperToolsData } from "@/lib/data" @@ -48,24 +43,32 @@ const Page = async ({ setRequestLocale(locale) const t = await getTranslations({ locale, namespace: "page-developers-apps" }) - const enrichedData = await getDeveloperToolsData() - if (!enrichedData) throw Error("No developer apps data available") - const dataByCategory = transformDeveloperAppsData(enrichedData) + const data = await getDeveloperToolsData() + if (!data) throw Error("No developer apps data available") + + const { appsById, selections } = data - const activeApp = enrichedData.find((app) => app.id === appId) + const activeApp = appId ? appsById[appId] : undefined // Clean up invalid appId by redirecting if (appId && !activeApp) { redirect("/developers/apps") } - // Get dynamic highlights based on stars and recent activity (cached weekly) - const highlightsByCategory = await getCachedHighlightsByCategory(enrichedData) - const highlights = getMainPageHighlights(highlightsByCategory) - - // Get randomized previews (5 apps per category) - cached daily - const previewsByCategory = - await getCachedRandomPreviewsByCategory(dataByCategory) + // Resolve highlight IDs to full app objects + const highlights = selections.mainPageHighlights + .map((id) => appsById[id]) + .filter(Boolean) + + // Resolve preview IDs per category + const previewsByCategory = Object.fromEntries( + DEV_APP_CATEGORIES.map(({ slug }) => [ + slug, + (selections.categoryPreviews[slug] || []) + .map((id) => appsById[id]) + .filter(Boolean), + ]) + ) as DeveloperAppsByCategory // Get contributor info for JSON-LD const commitHistoryCache: CommitHistory = {} diff --git a/app/[locale]/developers/apps/types.ts b/app/[locale]/developers/apps/types.ts index c11bc9ae332..e894c6b11c3 100644 --- a/app/[locale]/developers/apps/types.ts +++ b/app/[locale]/developers/apps/types.ts @@ -112,3 +112,29 @@ export type DeveloperAppsByCategory = Record< DeveloperAppCategorySlug, DeveloperApp[] > + +/** + * Pre-computed randomized selections for developer apps. + * Computed daily in the trigger.dev task to ensure all users see the same selections. + */ +export interface DeveloperAppsComputedSelections { + /** Main page highlights - top app from 3 random categories (3 IDs) */ + mainPageHighlights: string[] + /** Category page highlights - top 3 apps per category (7 categories × 3 = 21 IDs) */ + categoryHighlights: Record + /** Category preview apps - 5 random apps per category for main page cards (7 × 5 = 35 IDs) */ + categoryPreviews: Record + /** ISO date when selections were computed (for debugging) */ + computedAt: string +} + +/** + * Envelope type for developer tools data. + * Contains both the app data and pre-computed selections. + */ +export interface DeveloperToolsDataEnvelope { + /** All apps indexed by ID for quick lookup (used by app modal) */ + appsById: Record + /** Pre-computed randomized selections (refreshed daily) */ + selections: DeveloperAppsComputedSelections +} diff --git a/app/[locale]/developers/apps/utils.ts b/app/[locale]/developers/apps/utils.ts index 642134ffaef..194a5380ff5 100644 --- a/app/[locale]/developers/apps/utils.ts +++ b/app/[locale]/developers/apps/utils.ts @@ -1,9 +1,6 @@ -import { unstable_cache } from "next/cache" - import type { TagProps } from "@/components/ui/tag" import { getDayOfYear, getWeekNumber } from "@/lib/utils/date" -import { every } from "@/lib/utils/time" import { DEV_APP_CATEGORIES, DEV_APP_CATEGORY_SLUGS } from "./constants" import type { @@ -185,35 +182,6 @@ export function getMainPageHighlights( .filter(Boolean) } -/** - * Get highlights for category page - * Returns top 3 apps for the specified category - */ -export function getCategoryPageHighlights( - highlightsByCategory: Record, - category: DeveloperAppCategorySlug -): DeveloperApp[] { - return highlightsByCategory[category]?.slice(0, 3) || [] -} - -/** - * Cached version of getHighlightsByCategory - * - * Uses Next.js unstable_cache to cache the computation for 1 week. - * Since the input data (apps array) is already cached via getDeveloperToolsData(), - * this primarily caches the sorting/filtering/randomization computation. - * - * Cache key includes the function name, ensuring cache invalidation when function changes. - * Tagged for manual cache invalidation if needed via revalidateTag('developer-apps-highlights'). - */ -export const getCachedHighlightsByCategory = unstable_cache( - async (apps: DeveloperApp[]) => getHighlightsByCategory(apps), - ["highlights-by-category"], - { - revalidate: every("week"), - tags: ["developer-apps-highlights"], - } -) /** * Get randomized preview apps per category for main page cards @@ -248,22 +216,6 @@ export function getRandomPreviewsByCategory( return result } -/** - * Cached version of getRandomPreviewsByCategory - * - * Caches for 1 day (24 hours) to align with daily seed rotation. - * Simpler than highlights - no complex filtering, just randomization. - */ -export const getCachedRandomPreviewsByCategory = unstable_cache( - async (dataByCategory: DeveloperAppsByCategory) => - getRandomPreviewsByCategory(dataByCategory), - ["random-previews-by-category"], - { - revalidate: every("day"), - tags: ["developer-apps-previews"], - } -) - /** * Gets the tag style for a developer app category based on its slug. * diff --git a/src/data-layer/fetchers/fetchDeveloperTools.ts b/src/data-layer/fetchers/fetchDeveloperTools.ts index d8ef77348f8..0f7e7bef87f 100644 --- a/src/data-layer/fetchers/fetchDeveloperTools.ts +++ b/src/data-layer/fetchers/fetchDeveloperTools.ts @@ -1,4 +1,14 @@ -import type { DeveloperApp } from "../../../app/[locale]/developers/apps/types" +import type { + DeveloperApp, + DeveloperAppsComputedSelections, + DeveloperToolsDataEnvelope, +} from "../../../app/[locale]/developers/apps/types" +import { + getHighlightsByCategory, + getMainPageHighlights, + getRandomPreviewsByCategory, + transformDeveloperAppsData, +} from "../../../app/[locale]/developers/apps/utils" import { fetchDeveloperToolsBuidlGuidl } from "./fetchDeveloperToolsBuidlGuidl" import { fetchDeveloperToolsGitHub } from "./fetchDeveloperToolsGitHub" @@ -12,9 +22,12 @@ import { fetchDeveloperToolsNpmJs } from "./fetchDeveloperToolsNpmJs" * 2. GitHub GraphQL API (stargazers, last commit dates) * 3. npm API (download counts) * - * Returns fully enriched DeveloperApp[] ready for consumption. + * Also computes randomized selections for highlights and previews, + * ensuring all users see the same apps until the next daily sync. + * + * Returns envelope with appsById lookup and pre-computed selections. */ -export async function fetchDeveloperTools(): Promise { +export async function fetchDeveloperTools(): Promise { console.log("Starting developer tools data enrichment pipeline") // Step 1: Fetch base data from BuidlGuidl @@ -29,6 +42,39 @@ export async function fetchDeveloperTools(): Promise { const enrichedData = await fetchDeveloperToolsNpmJs(withGitHub) console.log("Enriched with npm data") + // Step 4: Build lookup map + const appsById: Record = Object.fromEntries( + enrichedData.map((app) => [app.id, app]) + ) + console.log(`Built appsById lookup with ${Object.keys(appsById).length} apps`) + + // Step 5: Compute randomized selections + const highlightsByCategory = getHighlightsByCategory(enrichedData) + const mainPageHighlights = getMainPageHighlights(highlightsByCategory) + const dataByCategory = transformDeveloperAppsData(enrichedData) + const categoryPreviews = getRandomPreviewsByCategory(dataByCategory) + + const selections: DeveloperAppsComputedSelections = { + mainPageHighlights: mainPageHighlights.map((app) => app.id), + categoryHighlights: Object.fromEntries( + Object.entries(highlightsByCategory).map(([cat, apps]) => [ + cat, + apps.slice(0, 3).map((app) => app.id), + ]) + ) as DeveloperAppsComputedSelections["categoryHighlights"], + categoryPreviews: Object.fromEntries( + Object.entries(categoryPreviews).map(([cat, apps]) => [ + cat, + apps.map((app) => app.id), + ]) + ) as DeveloperAppsComputedSelections["categoryPreviews"], + computedAt: new Date().toISOString(), + } + console.log( + `Computed selections: ${selections.mainPageHighlights.length} main highlights, ` + + `${Object.keys(selections.categoryHighlights).length} categories with highlights` + ) + console.log("Developer tools data enrichment complete") - return enrichedData + return { appsById, selections } } diff --git a/src/data-layer/index.ts b/src/data-layer/index.ts index 55dbdd0d7a3..9759d6f8b41 100644 --- a/src/data-layer/index.ts +++ b/src/data-layer/index.ts @@ -15,7 +15,7 @@ import type { } from "@/lib/types" import type { CommunityEventsReturnType } from "@/lib/interfaces" -import type { DeveloperApp } from "../../app/[locale]/developers/apps/types" +import type { DeveloperToolsDataEnvelope } from "../../app/[locale]/developers/apps/types" import type { BeaconChainData } from "./fetchers/fetchBeaconChain" import type { CoinGeckoCoinMarketResponse } from "./fetchers/fetchStablecoinsData" @@ -45,4 +45,5 @@ export const getStablecoinsData = () => get(KEYS.ST export const getTotalEthStakedData = () => get(KEYS.TOTAL_ETH_STAKED) export const getTotalValueLockedData = () => get(KEYS.TOTAL_VALUE_LOCKED) export const getEventsData = () => get(KEYS.EVENTS) -export const getDeveloperToolsData = () => get(KEYS.DEVELOPER_APPS) +export const getDeveloperToolsData = () => + get(KEYS.DEVELOPER_APPS) diff --git a/src/data-layer/mocks/fetch-developer-tools.json b/src/data-layer/mocks/fetch-developer-tools.json index dca8fdaaa5a..0d222648e01 100644 --- a/src/data-layer/mocks/fetch-developer-tools.json +++ b/src/data-layer/mocks/fetch-developer-tools.json @@ -1,1165 +1,1262 @@ -[ - { - "id": "0x939241afa4c4b9e1dda6b8250baa8f04fa8b0debce738cfd324c0b18f9926d25", - "name": "OpenZeppelin Contracts", - "description": "OpenZeppelin Contracts are the go-to library for smart contract development.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/83bab036-91bd-4b9d-a524-dbea2024aa3f.png", - "banner_url": "https://storage.googleapis.com/op-atlas/489f54b5-2035-4a94-82f5-8b41e6cbb857.png", - "twitter": "https://x.com/openzeppelin", - "tags": [ - "cross-chain", - "governance", - "erc721", - "upgradeable-contracts", - "modular-accounts", - "interactive-tools", - "merkle-trees" - ], - "website": "https://www.openzeppelin.com/", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/OpenZeppelin/openzeppelin-upgrades", - "stargazers": 648, - "lastUpdated": "2025-11-03T20:09:20Z" - }, - { - "href": "https://github.com/OpenZeppelin/openzeppelin-subgraphs", - "stargazers": 146, - "lastUpdated": "2025-02-25T15:09:17Z" - }, - { - "href": "https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades", - "stargazers": 244, - "lastUpdated": "2025-06-30T19:16:05Z" - }, - { - "href": "https://github.com/OpenZeppelin/merkle-tree", - "stargazers": 519, - "lastUpdated": "2025-02-25T02:12:49Z" - }, - { - "href": "https://github.com/openzeppelin/openzeppelin-community-contracts", - "stargazers": 80, - "lastUpdated": "2026-01-13T18:10:27Z" - }, - { - "href": "https://github.com/OpenZeppelin/openzeppelin-contracts", - "stargazers": 26929, - "lastUpdated": "2026-01-15T16:08:39Z" - }, - { - "href": "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable", - "stargazers": 1149, - "lastUpdated": "2026-01-15T16:10:26Z" - }, - { - "href": "https://github.com/OpenZeppelin/contracts-wizard", - "stargazers": 294, - "lastUpdated": "2026-01-16T15:24:19Z" - } - ] - }, - { - "id": "0xcc8d03e014e121d10602eeff729b755d5dc6a317df0d6302c8a9d3b5424aaba8", - "name": "Solidity", - "description": "Solidity is an object-oriented, high-level language for implementing smart contracts.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/b6f312d0-1025-4a19-baa9-3aa218fe0833.png", - "banner_url": "https://storage.googleapis.com/op-atlas/bca65077-a87b-4fd8-bcc3-9ad0a65d9d27.png", - "twitter": "https://x.com/solidity_lang", - "tags": [ - "education", - "solidity", - "compiler", - "cli" - ], - "website": "https://soliditylang.org/", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/ethereum/solidity", - "stargazers": 25502, - "lastUpdated": "2026-01-19T23:37:55Z" - }, - { - "href": "https://github.com/ethereum/solc-js", - "stargazers": 1503, - "lastUpdated": "2025-12-18T20:41:21Z" - } - ] - }, - { - "id": "0x5200a7351f8d195401dc04631fb83e4836f73a2794f316b2739c03807f30a78b", - "name": "Brownie", - "description": "A Python-based development and testing framework for smart contracts targeting the Ethereum Virtual Machine. ", - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [ - "cli", - "debugging-tools" - ], - "website": "https://github.com/eth-brownie/brownie", - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/eth-brownie/brownie", - "stargazers": 2729, - "lastUpdated": "2026-01-14T06:57:54Z" - } - ] - }, - { - "id": "0x4a5e771af86cf1938056b43cddbf0018dca1376d578f631f7449fe10ac4958ed", - "name": "Nethereum", - "description": "Nethereum is the .Net integration library for Ethereum, simplifying the access and smart contract interaction with Ethereum nodes both public like Geth (or your preferred client) L2 chains like Optimism, Arbitrum (or your preferred L2), any compatible EVM chain (Gnosis, etc) and permissioned chains like Quorum.", - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [ - "cross-chain", - "wallet", - "json-rpc", - "transaction-signing", - "abi-encoding" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/Nethereum/Nethereum", - "stargazers": 2245, - "lastUpdated": "2026-01-11T11:50:23Z" - } - ] - }, - { - "id": "manually-added:intellij-solidity", - "name": "IntelliJ Solidity", - "description": "Solidity plugin for IntelliJ", - "website": "https://intellij-solidity.dev/", - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [ - "solidity", - "developer-experience", - "code-quality" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/intellij-solidity/intellij-solidity", - "stargazers": 1097, - "lastUpdated": "2026-01-19T22:20:07Z" - } - ] - }, - { - "id": "0x819775803938d78eaa95809971ce94cae6a54b4df58505fa36153ffa1d55e12c", - "name": "Vscode Solidity Extension", - "description": "Solidity support for Visual Studio code\nVersion Downloads Installs Rating\n\nSolidity is the language used in Ethereum to create smart contracts, this extension provides:\n\nSyntax highlighting\nSnippets\nCompilation of the current contract (Press F1 Solidity : Compile Current Solidity Contract), or F5\nCompilation of all the contracts (Press F1 Solidity : Compile all Solidity Contracts), or Ctrl + F5 or Cmd + F5\nCode completion for all contracts / libraries in the current file and all referenced imports\nGoto definition\nFind all references in project\nHover information\nCode actions / quick fixes (change compiler, format address, add sdpx license.. )\nMono repo support (identifies the project by finding the files: remappings.txt, foundry.toml, brownie-config.yaml, truffle-config.js, hardhat.config.js, hardhat.config.ts)\nDefault project structure (solidity files needs to be in the src/ directory, and libraries in the lib/ directory). Libraries will follow the same structure.\nCompilation supporting EIP82 (dappfile and dependency packages)\nSupport for different solidity versions (Remote and local)\nDownload source code and Abi from Etherscan\nCode generation using Nethereum, it includes currently the default template for Nethereum service, dtos generation. (Open 'contractName.json' after compilation from the bin folder. Press F1 and press Solidity: Code generate from compilation output..) Auto generation of Nethereum files on compilation\nLinting using Solhint or Ethlint\nIt is also available as a standalone LSP", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/006b0fd3-9e23-4192-98d6-08e561da809e.png", - "banner_url": null, - "twitter": null, - "tags": [ - "education", - "solidity" - ], - "category": "Smart Contract Development & Toolchains", - "repos": [ - { - "href": "https://github.com/juanfranblanco/vscode-solidity", - "stargazers": 959, - "lastUpdated": "2025-11-04T17:05:55Z" - } - ] - }, - { - "id": "0x7f330267969cf845a983a9d4e7b7dbcca5c700a5191269af377836d109e0bb69", - "name": "IPFS", - "description": "IPFS (InterPlanetary File System) is a peer-to-peer protocol designed to make the web faster, more open, and more resilient. By using content-addressed storage rather than location-based references, IPFS removes the need for centralized servers and allows files to be distributed and retrieved from multiple nodes around the world. This approach lowers hosting costs, improves data availability, and reduces censorship, laying the groundwork for a more secure and permanent global information network.\n\nIPFS is used in a variety of applications. While some users interact with IPFS via imported libraries in their projects, a large amount of usage comes via IPFS' HTTP Gateway API which allows users to self-host, use extensions like IPFS companion, or publicly run gateways (whether paid ones run by companies like Filebase, Pinata, etc. or the public goods services at ipfs.io and dweb.link).\n\nIPFS is a system for moving data across decentralized networks, with >11M weekly users and 250K public p2p nodes. Highlights:\n\n1. Off-chain storage. IPFS provides verifiable, off-chain storage, often used to reduce on-chain needs in Ethereum & Optimism. Examples: TrueBlocks (local IPFS-based index for EVM chains, built with grants from OP & EF), Snapshot (IPFS-based off-chain voting).\n\n2. Go-to distribution network for fully decentralized third-party app frontends (for gaming, DeFi, & more). We run gateway services that serve 900M requests/wk, and added native IPFS support to browsers like Chromium & Brave.\n\n3. NFT metadata gold standard. Over 115M NFTs are stored on IPFS, including leading platforms OpenSea (which supports Optimism NFTs), Rarible, and Zora.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/fca3aa6c-bdd5-4632-ae64-37b886d50a65.png", - "banner_url": "https://storage.googleapis.com/op-atlas/35658254-c8b6-4562-9690-db91f187a7ff.png", - "twitter": "https://x.com/ipshipyard", - "tags": [ - "peer-to-peer", - "censorship-resistant", - "cli" - ], - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/ipfs/service-worker-gateway", - "stargazers": 79, - "lastUpdated": "2026-01-20T15:43:06Z" - }, - { - "href": "https://github.com/ipfs/helia", - "stargazers": 1275, - "lastUpdated": "2026-01-16T09:45:08Z" - }, - { - "href": "https://github.com/ipfs/kubo", - "stargazers": 16881, - "lastUpdated": "2026-01-16T01:27:32Z" - }, - { - "href": "https://github.com/ipfs/boxo", - "stargazers": 277, - "lastUpdated": "2026-01-20T18:22:51Z" - }, - { - "href": "https://github.com/ipfs/js-kubo-rpc-client", - "stargazers": 50, - "lastUpdated": "2025-10-15T07:29:36Z" - }, - { - "href": "https://github.com/ipfs/protons", - "stargazers": 37, - "lastUpdated": "2025-06-25T08:34:59Z" - }, - { - "href": "https://github.com/ipfs/js-ipns", - "stargazers": 89, - "lastUpdated": "2025-10-14T10:05:10Z" - }, - { - "href": "https://github.com/ipfs/helia-delegated-routing-v1-http-api", - "stargazers": 4, - "lastUpdated": "2026-01-16T14:05:02Z" - }, - { - "href": "https://github.com/ipfs/js-stores", - "stargazers": 37, - "lastUpdated": "2026-01-08T14:46:02Z" - } - ] - }, - { - "id": "0xa3d07f453f70d844196d89d79848aa2e70a0bd8b38bf0f493cba1547bb3bca5e", - "name": "Ethers.js", - "description": "Ethers.js is a simple, compact and complete JavaScript (via TypeScript) library for interacting with Ethereum and related blockchains.\n\nIt is currently used in a very large number of Blockchain projects, including everything from block explorers to wallets (like MetaMask) and is downloaded over 7.1 million times per month (as of this writing). It is also one of the top 500 projects (by dependants) on NPM.\n\nIt was written and is maintained by me, RicMoo (Richard Moore), a random developer from Canada that is passionate about open-source and dedicates most his waking-time (and some sleeping-time) to it.\n\nHack the Planet! :)", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/f8d776ab-ca70-42ee-9e41-d4f709cd6fd4.png", - "banner_url": "https://storage.googleapis.com/op-atlas/459bdd5e-60a5-49ca-88b8-d4537ebfec16.png", - "twitter": "@ricmoo", - "tags": [ - "frontend", - "json-rpc", - "contract-interaction" - ], - "website": "https://ethers.org", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/ethers-io/ethers.js", - "stargazers": 8626, - "lastUpdated": "2025-12-03T00:49:47Z" - } - ] - }, - { - "id": "manually-added:orbitdb", - "name": "OrbitDB", - "description": "Peer-to-Peer Databases for the Decentralized Web", - "website": null, - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [ - "peer-to-peer", - "censorship-resistant" - ], - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/orbitdb/orbitdb", - "stargazers": 8720, - "lastUpdated": "2025-08-05T01:58:51Z" - } - ] - }, - { - "id": "0x62d9a8a3b602c688610abfbe3965e04ca0d19c5c506f40e79cd185cb501d2018", - "name": "noble cryptography", - "description": "noble cryptography is a high-security, easily auditable set of contained cryptographic libraries with following features:\n\n- Zero or minimal dependencies\n- Highly readable TypeScript / JS code\n- PGP-signed releases and transparent NPM builds\n\nnoble cryptography is used in most modern JS wallets, including Metamask, Rabby, Rainbow, various SDKs, and others. Essentially it empowers a huge share of ecosystem.", - "thumbnail_url": null, - "banner_url": null, - "twitter": "https://x.com/paulmillr", - "tags": [ - "wallet", - "security", - "encryption" - ], - "website": "https://paulmillr.com/noble/", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/paulmillr/noble-curves", - "stargazers": 876, - "lastUpdated": "2026-01-13T01:04:35Z" - }, - { - "href": "https://github.com/paulmillr/noble-hashes", - "stargazers": 802, - "lastUpdated": "2026-01-13T01:31:07Z" - }, - { - "href": "https://github.com/paulmillr/noble-ciphers", - "stargazers": 358, - "lastUpdated": "2026-01-13T01:07:07Z" - } - ] - }, - { - "id": "manually-added:ethereum-rb", - "name": "ethereum.rb", - "description": "Ethereum library for the Ruby language", - "website": null, - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [ - "sdk" - ], - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/EthWorks/ethereum.rb", - "stargazers": 732, - "lastUpdated": "2022-05-11T14:28:01Z" - } - ] - }, - { - "id": "0x9d93ec97ef2d3bd4c2b8d95abac9ce0cf43e4f3eb1f05709f8282da8200e69ee", - "name": "Frames.js", - "description": "frames.js is the leading open source javascript library and debugging environment to help developers make Frames for Farcaster, XMTP and Lens faster & easier. \n\nWe also have been building and maintaining a library for apps to adopt frames in their apps that has been integrated by the Base team in their Base names product.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/230e8ac2-cea9-4cab-8b4f-8fd58ec6553e.png", - "banner_url": "https://storage.googleapis.com/op-atlas/a2dce749-56d7-44d7-a9cc-ffc08255e0f2.png", - "twitter": null, - "tags": [ - "frontend", - "farcaster", - "react", - "nextjs" - ], - "website": "https://www.framesjs.org", - "category": "Client Libraries & SDKs (Front-End)", - "repos": [ - { - "href": "https://github.com/framesjs/frames.js", - "stargazers": 382, - "lastUpdated": "2025-03-27T17:07:46Z" - } - ] - }, - { - "id": "0x85af258d3fae6bbd2e14ffa8f5b73b64e34b7f8efe685c40134c3f54774e8d6c", - "name": "Skandha ERC-4337 Bundler", - "description": "Etherspot's developer-friendly TypeScript ERC-4337 bundler that enhances transaction management, optimizes gas costs, and improves the overall efficiency of blockchain interactions. It supports Shared Mempool and provides built-in MEV protection. \n\nEtherspot is pioneering the ERC-4337 shared mempool innovation, which is already live on Optimism.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/c9083120-f920-426d-a33c-37ad6f5b3c3f.png", - "banner_url": "https://storage.googleapis.com/op-atlas/62d53176-085e-4084-9112-f05f62b536db.png", - "twitter": "https://x.com/etherspot", - "tags": [ - "bundler", - "transaction-management", - "gas-optimization", - "cli", - "account-abstraction" - ], - "website": "https://etherspot.io/skandha/", - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/etherspot/skandha", - "stargazers": 610, - "lastUpdated": "2026-01-20T12:53:03Z" - } - ] - }, - { - "id": "0x79e8bf2d699790b563aa57fd34da1722bea3191ab5ff0601ba56020687702ab9", - "name": "Etherspot", - "description": "Etherspot is a multi-chain Account & Chain Abstraction development infrastructure that provides solutions for dApps, wallets, games, operating EVM-compatible rollups, or L1/L2 chains to deliver seamless cross-chain Web3 user experience by removing usability pain points.\n\nIn addition to providing Account and Chain Abstraction features, Etherspot helps developers make their projects compatible with the latest Ethereum standards, including ERC-4337, ERC-7579, and EIP-7702, by offering a wide range of cutting-edge services such as Bundler and Paymaster services, APIs, and more.\n\nEtherspot is pioneering the ERC-4337 shared mempool innovation, which is already live on Optimism.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/b05e1c53-bace-499c-b346-ed9fa0003730.png", - "banner_url": "https://storage.googleapis.com/op-atlas/b33b4fe0-6010-470c-a2db-57636d96536d.png", - "twitter": "https://x.com/etherspot", - "tags": [ - "cross-chain", - "wallet", - "defi", - "multi-chain", - "account-abstraction", - "sdk", - "user-experience" - ], - "website": "https://etherspot.io/", - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/etherspot/etherspot-prime-contracts", - "stargazers": 55, - "lastUpdated": "2025-02-20T21:15:37Z" - }, - { - "href": "https://github.com/etherspot/etherspot-modular-sdk", - "stargazers": 22, - "lastUpdated": "2025-10-23T08:27:57Z" - }, - { - "href": "https://www.npmjs.com/package/skandha" - }, - { - "href": "https://www.npmjs.com/package/@etherspot/prime-sdk", - "downloads": 60 - }, - { - "href": "https://github.com/etherspot/skandha", - "stargazers": 610, - "lastUpdated": "2026-01-20T12:53:03Z" - } - ] - }, - { - "id": "0x2866fcc8ea2ad6cc691b8367023c08ba84a34a14685b0154ba4601b7d4981069", - "name": "go-ethereum-hdwallet", - "description": "Ethereum HD Wallet derivations library in Go", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/09a4acff-98eb-4c73-925e-7403d7678163.png", - "banner_url": "https://storage.googleapis.com/op-atlas/9b428229-b1e5-4f3a-b7f9-d312566a5fcd.png", - "twitter": null, - "tags": [ - "wallet", - "transaction-signing", - "cli" - ], - "website": "https://github.com/miguelmota/go-ethereum-hdwallet", - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/miguelmota/go-ethereum-hdwallet", - "stargazers": 549, - "lastUpdated": "2025-04-27T19:43:22Z" - } - ] - }, - { - "id": "0x37fe5886f4c77d5a5cb947deff90158c045a5d207572763187748ac4dd4bd9b9", - "name": "ethereum-multicall", - "description": "Ability to call many ethereum constant function calls in 1 JSONRPC request", - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [ - "multicall" - ], - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/joshstevens19/ethereum-multicall", - "stargazers": 381, - "lastUpdated": "2025-12-23T11:07:33Z" - } - ] - }, - { - "id": "0x93decae913f62c0a86519d0b0798e4a10c46c541bfc14dcff0193d6b026e9532", - "name": "LlamaPay", - "description": "Automate & stream salaries by the second", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/30c6400b-b572-4d16-8138-4dc1cba0ef06.png", - "banner_url": "https://storage.googleapis.com/op-atlas/2c2733fd-a572-4f4f-809d-def2e14b8776.png", - "twitter": "https://x.com/llamapay_io", - "tags": [ - "defi", - "gas-efficient" - ], - "website": "https://llamapay.io/", - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/llamasubs/contracts", - "stargazers": 4, - "lastUpdated": "2024-07-21T13:42:50Z" - }, - { - "href": "https://github.com/LlamaPay/llamapay", - "stargazers": 187, - "lastUpdated": "2022-06-21T08:10:50Z" - } - ] - }, - { - "id": "0x4e13be6b98dd868cd13e9f4101431ab03d211f429b63f078fa7da260b54d256a", - "name": "Light Account", - "description": "A set of lightweight, open sourced, audited and gas-optimized ERC-4337 compatible smart contract accounts with designated ownership", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/646cd1db-23b4-4328-8a7c-6c58358a73e1.png", - "banner_url": null, - "twitter": "https://x.com/alchemy", - "tags": [ - "wallet", - "account-abstraction", - "solidity", - "foundry" - ], - "website": "https://www.alchemy.com/", - "category": "Transaction & Wallet Infrastructure", - "repos": [ - { - "href": "https://github.com/alchemyplatform/light-account", - "stargazers": 111, - "lastUpdated": "2026-01-07T16:13:59Z" - } - ] - }, - { - "id": "0xdc3dce33fd5fb50cf932586d4257456ddf5040ba0955d97641646504c73dbd13", - "name": "Slither", - "description": "Slither is a Solidity and Vyper static analysis framework written in Python3. \n\nIt runs a suite of vulnerability detectors, prints visual information about contract details, and provides an API to easily write custom analyses. Slither enables developers to find vulnerabilities, enhance their code comprehension, and quickly prototype custom analyses.\n\nSlither has been used for many years by both security engineers and developers to secure their smart contracts. \n\nBy allowing developers to find the most common vulnerabilities on their smart contracts, Slither helps to improve the security of the Optimism ecosystem.\n\nSlither has 90+ detectors, and works on both Solidity and Vyper. In addition it provides printers, helping to review quickly features of contracts. It's python API can also be used to leverage its inbuilt analysis for custom needs.\n\nSlither can directly be run on a contract deployed on optimism, with `slither optim:0x..ADDRESS`", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/27ad6768-163c-4cc3-bd3e-ba8fd3ef5f50.png", - "banner_url": "https://storage.googleapis.com/op-atlas/1276f443-c160-4db0-ab75-33e3e01e3a47.png", - "twitter": "https://x.com/trailofbits", - "tags": [ - "security", - "static-analysis", - "solidity", - "vyper", - "continuous-integration" - ], - "category": "Security, Testing & Formal Verification", - "repos": [ - { - "href": "https://github.com/crytic/slither", - "stargazers": 6093, - "lastUpdated": "2026-01-20T18:39:50Z" - } - ] - }, - { - "id": "0x2bb095e1f297c71da8bd4ee15097abad3b99e299fe14cd6aa704df3f36d0ae22", - "name": "solidity-coverage", - "description": "solidity-coverage provides smart-contract code coverage for the Hardhat developer platform. It's highly accurate, supports full viaIR solidity compilation and a large set of solidity-specific code branch patterns. It's installed on ~230k Github projects and is downloaded ~100k times a week from NPM.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/bd692393-7f1a-4b91-9887-73f7c3250233.png", - "banner_url": "https://storage.googleapis.com/op-atlas/dcbdf6ac-f898-4dac-b9d0-087b8d289f4b.png", - "twitter": null, - "tags": [ - "hardhat", - "analytics", - "code-coverage", - "solidity", - "test-automation" - ], - "website": "https://github.com/sc-forks/solidity-coverage", - "category": "Security, Testing & Formal Verification", - "repos": [ - { - "href": "https://github.com/sc-forks/solidity-coverage", - "stargazers": 1005, - "lastUpdated": "2025-12-11T04:00:44Z" - } - ] - }, - { - "id": "0xb9996d35862a7c60282da2adf3447f043580f586fcb702ff6869896d15ef6344", - "name": "Medusa", - "description": "Medusa is a stateful smart contract fuzzer inspired by Echidna. It provides parallelized fuzz testing of smart contracts and the verification of advanced smart contract invariants.\n", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/69e9b03e-47d3-4770-8415-3ae65da044a4.png", - "banner_url": null, - "twitter": "https://x.com/trailofbits", - "tags": [ - "security", - "governance", - "analytics", - "fuzz-testing" - ], - "category": "Security, Testing & Formal Verification", - "repos": [ - { - "href": "https://github.com/crytic/medusa", - "stargazers": 443, - "lastUpdated": "2026-01-20T21:50:38Z" - } - ] - }, - { - "id": "manually-added:hax", - "name": "hax", - "description": "hax is a tool for high assurance translations of a large subset of Rust into formal languages such as F* or Rocq.", - "website": "https://hax.cryspen.com/", - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [ - "formal-verification" - ], - "category": "Security, Testing & Formal Verification", - "repos": [ - { - "href": "https://github.com/cryspen/hax", - "stargazers": 362, - "lastUpdated": "2026-01-19T15:13:10Z" - } - ] - }, - { - "id": "0xa790f0641e8d72abc88efd13ca215e2dc7e736a4a59ca5a9e0020af29d6297f2", - "name": "Crytic-Properties", - "description": "Crytic-Properties is a suite of re-usable security tests for some of the most widely used token standards such as ERC20, ERC721, ERC4626, and more.\n", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/eebeffeb-5b4e-4e8f-a8d9-09718da38b40.png", - "banner_url": null, - "twitter": "https://x.com/trailofbits", - "tags": [ - "security", - "erc721", - "fuzz-testing", - "solidity" - ], - "category": "Security, Testing & Formal Verification", - "repos": [ - { - "href": "https://github.com/crytic/properties", - "stargazers": 356, - "lastUpdated": "2025-11-29T16:59:34Z" - } - ] - }, - { - "id": "0xeef42373d10554d65aba9e6deb8333a4eddebba829e0afea0dc93e32d8075d2d", - "name": "ERCx: Token Test Library", - "description": "Runtime Verification is a leading formal verification company specializing in blockchain security and smart contract correctness. We've developed ERCx, the most comprehensive open-source testing library for ERC token standards, featuring over 500 individual tests across ERC-20, ERC-721, ERC-1155, and ERC-4626 implementations.\nERCx directly empowers Superchain builders by providing production-ready test suites that verify both standard compliance and security properties. Our library offers zero-configuration testing for deployed contracts via Foundry fork testing, plus simple integration for pre-deployment source code validation. With three testing tiers: Standard (EIP compliance), Security (vulnerability detection), and Features (implementation validation), developers can ship token contracts with confidence, knowing they've been thoroughly vetted against real-world attack vectors and edge cases.\nWhat makes ERCx particularly valuable for the Optimism ecosystem is its cross-chain compatibility and handling of complex deployment scenarios. The library seamlessly works across OP Stack chains and handles storage complexities that often challenge developers working with established tokens like USDC or stETH. By providing this critical testing infrastructure as open-source tooling, we're enabling safer, more reliable token implementations across the entire Superchain, directly supporting the ecosystem's growth while reducing the security risks that have historically plagued token contracts in DeFi.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/e6a6dd9b-4ace-4187-8408-0e5729bb0265.png", - "banner_url": "https://storage.googleapis.com/op-atlas/eee0738d-3735-42c8-8802-93b22a041803.png", - "twitter": "x.com/rv_inc", - "tags": [ - "foundry", - "security", - "erc721", - "runtime-verification" - ], - "website": "ercx.runtimeverification.com", - "category": "Security, Testing & Formal Verification", - "repos": [ - { - "href": "https://github.com/runtimeverification/ercx-tests", - "stargazers": 35, - "lastUpdated": "2025-07-04T12:23:27Z" - } - ] - }, - { - "id": "0x517eaa9c56951de89261f2d7830ea49aae92f2a903104a17d9c5c2edd4959806", - "name": "LI.FI", - "description": "One API to swap, bridge, and zap across all major blockchains and protocols. Enable trading across all DEX aggregators, bridges, and intent-systems and save hundreds of developer hours.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/4906b988-6024-421e-a706-d01bc508e736.png", - "banner_url": "https://storage.googleapis.com/op-atlas/c280e13b-3e03-47e9-8141-5fad0d51ba2b.png", - "twitter": "https://x.com/lifiprotocol", - "tags": [ - "cross-chain", - "api", - "dex-aggregator", - "multi-chain", - "performance-optimization" - ], - "category": "Cross-Chain & Interoperability", - "repos": [ - { - "href": "https://www.npmjs.com/package/@lifi/sdk", - "downloads": 36632 - }, - { - "href": "https://github.com/lifinance/widget", - "stargazers": 188, - "lastUpdated": "2026-01-20T11:06:38Z" - }, - { - "href": "https://www.npmjs.com/package/@lifi/widget", - "downloads": 12583 - }, - { - "href": "https://github.com/lifinance/contracts", - "stargazers": 191, - "lastUpdated": "2026-01-16T08:38:18Z" - }, - { - "href": "https://github.com/lifinance/sdk", - "stargazers": 243, - "lastUpdated": "2026-01-20T12:52:18Z" - } - ] - }, - { - "id": "0xc850d11fe786d1168bfeda108721101427dd5425d9d9e6595c35573f7616e940", - "name": "Daimo Pay", - "description": "Daimo Pay lets users interact with your app using any token on any chain - no bridging, no swapping, no friction.\nIntegrate our SDK in 15 minutes to accept deposits or execute transactions in your app with any token, from any chain, using any wallet or exchange.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/b2bd0510-b0d6-436e-a126-de05026e9418.png", - "banner_url": "https://storage.googleapis.com/op-atlas/dde6090a-600a-418b-be38-5ea73111c407.png", - "twitter": "https://x.com/daimopay", - "tags": [ - "cross-chain" - ], - "website": "https://pay.daimo.com/", - "category": "Cross-Chain & Interoperability", - "repos": [ - { - "href": "https://github.com/daimo-eth/pay", - "stargazers": 18, - "lastUpdated": "2026-01-20T05:09:55Z" - } - ] - }, - { - "id": "0x62e37e96aa6e1cbfb6bd24b97c4b8f1e12cc3fe35d5388d2f041c42a12b40745", - "name": "Stargate Finance", - "description": "Stargate is a fully composable liquidity\ntransport protocol that lives at the\nheart of omnichain DeFi.\n\nWith Stargate, users & dApps can transfer native assets cross-chain while accessing\nthe protocol’s unified liquidity pools with instant guaranteed finality. ", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/3083ccee-79a8-4ff2-b017-9ecb52d13cbf.png", - "banner_url": "https://storage.googleapis.com/op-atlas/b29f1ab3-b4cf-4255-839e-e7a418e78b80.png", - "twitter": "https://x.com/StargateFinance", - "tags": [ - "cross-chain", - "defi" - ], - "website": "https://stargate.finance/", - "category": "Cross-Chain & Interoperability", - "repos": [ - { - "href": "https://github.com/stargate-protocol/stargate", - "stargazers": 314, - "lastUpdated": "2024-06-06T00:19:00Z" - } - ] - }, - { - "id": "0xf24315614063278ba3543e1717791132a9afa79b0e65baa01a85bcccbdfa215f", - "name": "deBridge", - "description": "deBridge is DeFi's internet of liquidity, enabling real-time movement of assets and information across the DeFi landscape. Without the bottlenecks and risks of liquidity pools, deBridge can power all type of cross-chain interactions with deep liquidity, tight spreads, and guaranteed rates.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/701c36d9-3069-48b6-9aa1-b248378b35b8.png", - "banner_url": "https://storage.googleapis.com/op-atlas/929fbc88-69c7-4a75-be6d-27bf3f2dc8d1.png", - "twitter": "https://x.com/deBridgeFinance", - "tags": [ - "cross-chain", - "defi", - "transaction-optimization" - ], - "website": "https://debridge.finance/", - "category": "Cross-Chain & Interoperability", - "repos": [ - { - "href": "https://www.npmjs.com/package/@debridge-finance/debridge-protocol-evm-interfaces", - "downloads": 0 - }, - { - "href": "https://www.npmjs.com/package/@debridge-finance/legacy-dln-profitability", - "downloads": 91 - }, - { - "href": "https://www.npmjs.com/package/@debridge-finance/desdk", - "downloads": 145 - }, - { - "href": "https://www.npmjs.com/package/@debridge-finance/dln-client", - "downloads": 680 - }, - { - "href": "https://www.npmjs.com/package/@debridge-finance/dln-taker", - "downloads": 5 - }, - { - "href": "https://github.com/debridge-finance/hardhat-debridge", - "stargazers": 23, - "lastUpdated": "2024-06-04T10:44:19Z" - }, - { - "href": "https://github.com/debridge-finance/dln-taker", - "stargazers": 20, - "lastUpdated": "2024-08-30T09:10:01Z" - }, - { - "href": "https://github.com/debridge-finance/debridge-node", - "stargazers": 9, - "lastUpdated": "2025-06-25T14:37:29Z" - }, - { - "href": "https://github.com/debridge-finance/dln-contracts", - "stargazers": 2, - "lastUpdated": "2024-06-04T11:18:02Z" - }, - { - "href": "https://github.com/debridge-finance/debridge-contracts-v1", - "stargazers": 58, - "lastUpdated": "2024-10-23T15:11:09Z" - } - ] - }, - { - "id": "0x38c38455bb0fd71d2929fcf799279569ab5f5c5d3e1f92f8642ce87aa25accdf", - "name": "Decent.xyz", - "description": "Decent enables cross-chain swaps and 1-click transactions with any token across chains. ", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/1ede3a09-1878-4852-a564-f86f4f49b9fc.png", - "banner_url": "https://storage.googleapis.com/op-atlas/862dacb3-f496-4afe-ae66-70f9f9949937.png", - "twitter": "https://twitter.com/decentxyz", - "tags": [ - "cross-chain", - "nextjs", - "tailwind-css", - "foundry", - "user-experience" - ], - "category": "Cross-Chain & Interoperability", - "repos": [ - { - "href": "https://www.npmjs.com/package/@decent.xyz/box-common", - "downloads": 1230 - }, - { - "href": "https://www.npmjs.com/package/@decent.xyz/box-hooks", - "downloads": 1053 - }, - { - "href": "https://github.com/decentxyz/launch-nfts", - "stargazers": 1, - "lastUpdated": "2024-06-06T16:40:50Z" - }, - { - "href": "https://github.com/decentxyz/decentV2-contracts", - "stargazers": 2, - "lastUpdated": "2024-06-06T15:26:43Z" - }, - { - "href": "https://www.npmjs.com/package/@decent.xyz/box-ui", - "downloads": 833 - }, - { - "href": "https://www.npmjs.com/package/@decent.xyz/the-box", - "downloads": 837 - }, - { - "href": "https://github.com/decentxyz/decent-contracts-v3", - "stargazers": 1, - "lastUpdated": "2025-03-28T20:43:18Z" - } - ] - }, - { - "id": "0x66cce776ce6eaa99192120fc25b91ecc7b98e03210a08f0d3bfda82f542d3e1a", - "name": "OP ENS Gateway by Opti.Domains", - "description": "Opti.Domains has developed an ENS Gateway implementation for OP Stack chains that supports various proofs, including those from L2OutputOracle, Dispute Game, and Anchor State. The appropriate proof is automatically selected based on the configuration of the OP Stack chain.\n\nThe Opti.Domains ENS Gateway automatically upgrades in response to the OP Stack's transition from L2OutputOracle to Dispute Game, requiring no manual intervention or updates to the verifier contract or gateway server.\n\nThe ENS Gateway, specifically the EVMGateway, enables trustless cross-chain data retrieval for ENS names deployed on Layer 2 networks like Optimism with a CCIP Gateway. When an ENS name lookup occurs, the resolver reverts with OffchainLookup containing the gateway URL. The client then contacts the gateway, which returns the requested data. This data is passed to a callback function on the resolver for verification before being returned to the client as the final result of the name lookup.\n\nOur ENS Gateway has a mechanism to ensure liveliness even in the event that the respected dispute game type has suddenly changed, as seen in the recent proposal, 'Upgrade Proposal #10: Granite Network Upgrade,' by storing a backup dispute game type and only trusting its anchor state.\n\nOpti.Domains has also developed social verification and attestation to EAS in collaboration with Bored Town. We are on our way to scaling ENS to OP. We have contributed to the ENS OP Gateway development, which is currently under review by ENS core developers.\n\nThe Namespace team has expressed interest and reached out to us with questions about using our OP ENS Gateway. Additionally, several teams have participated in discussions regarding the development of our OP ENS Gateway.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/8f6ad6e0-029a-4f59-b1d2-c7885248b99a.png", - "banner_url": "https://storage.googleapis.com/op-atlas/135853fe-2393-4a0a-a959-044ff973fcf0.png", - "twitter": "https://x.com/optidomains", - "tags": [ - "cross-chain", - "governance", - "layer-2", - "verification", - "scalability" - ], - "website": "https://opti.domains", - "category": "Cross-Chain & Interoperability", - "repos": [ - { - "href": "https://www.npmjs.com/package/@optidomains/passport-discord", - "downloads": 7 - }, - { - "href": "https://github.com/Opti-domains/evmgateway", - "stargazers": 0, - "lastUpdated": "2025-01-07T16:14:06Z" - }, - { - "href": "https://github.com/Opti-domains/ens-diamond-resolver-v1", - "stargazers": 0, - "lastUpdated": "2024-05-28T02:46:59Z" - }, - { - "href": "https://github.com/Opti-domains/dispute-game-lookup", - "stargazers": 0, - "lastUpdated": "2025-02-16T18:57:17Z" - }, - { - "href": "https://www.npmjs.com/package/@optidomains/wagmi-core", - "downloads": 1 - }, - { - "href": "https://github.com/Opti-domains/optidomains-ens-contracts", - "stargazers": 0, - "lastUpdated": "2024-05-28T02:37:33Z" - }, - { - "href": "https://github.com/Opti-domains/modular-ens-contracts", - "stargazers": 2, - "lastUpdated": "2024-05-28T04:03:40Z" - }, - { - "href": "https://www.npmjs.com/package/@optidomains/wagmi", - "downloads": 1 - }, - { - "href": "https://www.npmjs.com/package/@optidomains/rainbowkit", - "downloads": 1 - } - ] - }, - { - "id": "0x663e4d25ca3f327365240471b4831ea3c989cb132bbf6ae8f5c1e15268591795", - "name": "Blockscout open-source block explorer", - "description": "Blockscout block explorer is the #1 explorer used by Optimistic rollups and Superchain networks. Blockscout is highly customizable and available, providing advanced developer tooling for projects and blockchain transparency for users.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/3113c4b6-4e29-420c-95f8-2ae4f6098089.png", - "banner_url": "https://storage.googleapis.com/op-atlas/c08d15e7-41fd-41a7-9c04-b1e10b0c1f26.png", - "twitter": "https://x.com/blockscoutcom", - "tags": [ - "block-explorer", - "chains" - ], - "website": "http://www.blockscout.com", - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/blockscout/blockscout", - "stargazers": 4380, - "lastUpdated": "2026-01-20T19:42:29Z" - } - ] - }, - { - "id": "0xaed5941b7a9f20de83f5c839bda507be43cbf41777fc623abf4bf05773298826", - "name": "Otterscan", - "description": "A blazingly fast, local, Ethereum block explorer built on top of Erigon for EVM chains", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/55a1fffb-dcd9-448b-8e34-9fb4b09a72f7.png", - "banner_url": "https://storage.googleapis.com/op-atlas/a0e75c22-8aff-4176-af81-6c03208c1bd3.png", - "twitter": "https://x.com/otterscan", - "tags": [ - "docker", - "block-explorer", - "chains", - "privacy-focused", - "react-app", - "json-rpc", - "visualization" - ], - "website": "https://otterscan.io/", - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/otterscan/otterscan", - "stargazers": 1396, - "lastUpdated": "2025-11-05T05:21:21Z" - } - ] - }, - { - "id": "0x97525ec91080ddd917eaccabf9d383cf70a2f78839ab21eeabe1687e312f2132", - "name": "rindexer", - "description": "rindexer is an opensource powerful, high-speed indexing toolset developed in Rust, designed for compatibility with any EVM chain. This tool allows you to index chain events using a simple YAML file, requiring no additional coding. For more advanced needs, the rindexer provides foundations and advanced capabilities to build whatever you want. It's highly extendable, enabling you to construct indexing pipelines with ease and focus exclusively on the logic. rindexer out the box also gives you a GraphQL API to query the data you have indexed instantly.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/366c4940-78cc-4119-958b-b93f3c9a5845.png", - "banner_url": null, - "twitter": null, - "tags": [ - "indexing", - "cli" - ], - "website": "https://rindexer.xyz/", - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/joshstevens19/rindexer", - "stargazers": 643, - "lastUpdated": "2026-01-20T18:33:58Z" - } - ] - }, - { - "id": "0x1aacb85f1d87039696b876ddcae98c56d38ea9eed07b265409fdb256c8f8172a", - "name": "Blockhead", - "description": "Open-source portfolio tracker and explorer interface for the decentralized web. https://blockhead.info", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/3a1343aa-8bb3-4f30-abc0-6ba02dd3787a.png", - "banner_url": "https://storage.googleapis.com/op-atlas/7c1ee7ff-ad46-4b74-a941-48cc7ddc2dbe.png", - "twitter": "https://x.com/0xBlockhead", - "tags": [ - "block-explorer" - ], - "website": "https://blockhead.info", - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/darrylyeo/blockhead", - "stargazers": 135, - "lastUpdated": "2025-05-18T04:45:05Z" - } - ] - }, - { - "id": "0xf9c5d092fac6ad924253d685cc7ba21d4e519813e673a3a8300f33cb3a6b4e06", - "name": "NFTScan", - "description": "NFTScan is a professional NFT Explorer tool that provides developers and users with NFT data search services for the Superchain ecosystem, including: OP Mainnet, Base, Mint blockchain and other blockchain networks.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/30fb3451-049c-4904-a109-d3c06004a731.png", - "banner_url": "https://storage.googleapis.com/op-atlas/09a998c5-5217-4937-b2c8-d994e5cfe1c7.png", - "twitter": "https://x.com/nftscan_com", - "tags": [ - "erc721" - ], - "website": "https://www.nftscan.com/", - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/nftscan-official/nftscan-api-js-sdk", - "stargazers": 18, - "lastUpdated": "2025-06-13T06:21:00Z" - } - ] - }, - { - "id": "0x46aff4985914b8e56b8fd62a9b8c3a03e2320315a9dfd6126e5ae272173cda87", - "name": "Patterns wallet analytics & CRM", - "description": "Free public web3 CRM and wallet analytics for OP builders. Helping OP dApps & DeFis discover most valuable user groups and counteract sybils. Part of the Optimism Superchain 4337 Data Standards group.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/ee4b3aab-f2b2-4400-abbc-2383b62662a4.png", - "banner_url": "https://storage.googleapis.com/op-atlas/b3b3b9a2-81bd-4e6b-af22-c388ca45c9f5.png", - "twitter": "https://x.com/patterns_build", - "tags": [ - "analytics", - "defi", - "visualization", - "docker", - "scalability" - ], - "category": "Data, Analytics & Tracing", - "repos": [ - { - "href": "https://github.com/tokenguardio/dapp-marvels", - "stargazers": 15, - "lastUpdated": "2025-03-21T11:37:20Z" - } - ] - }, - { - "id": "0x17fb589e599fe05e532b90c121eccc55b1249301e783dae226bad698872322da", - "name": "The Ethernaut", - "description": "The Ethernaut is a community-driven capture-the-flag wargame that challenges developers of all levels to break smart contracts while learning common Solidity vulnerabilities. Maintained by OpenZeppelin, each level provides a gamified experience where a smart contract must be ‘hacked’ to progress. It is 100% open-source, with all levels contributed by players.\n\nIn 2024, we have continued expanding the game, adding four new advanced levels—HigherOrder, Stake, Impersonator, and Magic Animal Carousel—which explore current vulnerabilities in smart contract development. These levels introduce challenges related to low-level EVM programming, staking vulnerabilities, signature verification exploits, and bitwise manipulation attacks, pushing players to deepen their understanding of Ethereum security.\n\nBeyond new levels, we have also redesigned the UI, added support for multiple networks, and expanded language translations to make the game more accessible to a global audience.\n\nWe believe that The Ethernaut is an essential training tool for developers across the Ethereum ecosystem, including those building on the Optimism network. By continually evolving the game with new challenges and features, we strive to make smart contract security education engaging, practical, and accessible to everyone.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/06419654-6022-400a-9670-82ca6e0225fe.png", - "banner_url": "https://storage.googleapis.com/op-atlas/5aba83e1-a4f2-453c-9e64-9884d0e628d6.png", - "twitter": "https://x.com/openzeppelin", - "tags": [ - "education", - "security", - "solidity", - "community-driven", - "react-app" - ], - "website": "https://ethernaut.openzeppelin.com/", - "category": "Education & Community Resources", - "repos": [ - { - "href": "https://github.com/OpenZeppelin/ethernaut", - "stargazers": 2273, - "lastUpdated": "2025-11-19T16:57:18Z" - } - ] - }, - { - "id": "0x72d363f14ae85f47acfe748fb0a2bed73195582bb9863de18901f5dfe309b8f7", - "name": "Solodit", - "description": "What is it?\nSolodit is an open-source, community-driven platform dedicated to improving web3 security. It aggregates over 8,000 smart contract vulnerability reports, bug bounty opportunities, and security audits from top firms like Cyfrin, OpenZeppelin and Trail of Bits, alongside contributions from individual researchers. Solodit not only aggregates this information but also makes it actionable, equipping developers and auditors with tools to prevent exploits and enhance the safety of dapps.\n\nWhy is it needed?\nThe web3 ecosystem is plagued by billions of dollars in losses due to security breaches in smart contracts and protocols. Despite the availability of security knowledge, it is fragmented across various platforms and reports, making it inaccessible to most developers and security teams. There are several problems that Solodit solves:\n\nKnowledge Gap: Many teams deploy smart contracts without understanding past vulnerabilities, leading to repeat incidents.\nInefficiencies: Developers and auditors spend valuable time searching disparate sources for security insights.\nEconomic Impact: Preventable exploits undermine trust in web3, stalling adoption and investment.\n\nBy aggregating and structuring security data, Solodit enables proactive vulnerability management and risk mitigation in the Web3 ecosystem.\n\nHow is it unique?\nComprehensive Coverage: Aggregates findings from leading auditors and platforms, offering unmatched insights into vulnerabilities and bug bounties.\nActionable Insights: Goes beyond archiving reports by providing advanced search tools and tagging systems to contextualise risks and solutions.\nCommunity-Driven Enhancements: Facilitates collaboration via ratings, tagging, and leaderboards that recognise top contributors, fostering a thriving security community.\nEducational Resource: This site serves as a learning hub for developers and auditors, providing real-world case studies on blockchain security.\n\nSolodit is a multipurpose tool designed to:\nMitigate Risk: Helps developers avoid known vulnerabilities, reducing the likelihood of exploits.\nPromote Proactive Security: Enables protocols to adopt preventive measures by studying historical vulnerabilities.\nStreamline Bug Bounties: Simplifies participation in bounty programs, encouraging more ethical hackers to contribute to ecosystem security.\nFoster Skill Development: Supports auditors in honing their skills and staying updated on emerging threats.\nSupport Decision-Making: Assists protocols in evaluating auditors via its leaderboard, promoting accountability and quality audits.\n\nWho is it for?\nDevelopers: Seeking to secure their smart contracts and understand vulnerability trends.\nAuditors: Looking to access a comprehensive repository of findings and showcase their expertise.\nWhitehat Hackers: Interested in participating in bug bounty programs and contributing to web3 security.\nProtocol P&E teams: Aiming to assess risks and prevent costly exploits.\nEducators and Researchers: Teaching or studying blockchain security with real-world examples, e.g. Cyfrin Updraft. \n\nStill to come:\nUI/UX redesign\nPower Aderyn, static analysis support", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/9cf8d92d-5549-4321-b675-c25256860183.png", - "banner_url": "https://storage.googleapis.com/op-atlas/20eb90df-0dd5-41fb-a3ce-f90cf3822492.png", - "twitter": null, - "tags": [ - "security", - "education", - "analytics", - "community-driven" - ], - "website": "https://solodit.cyfrin.io/", - "category": "Education & Community Resources", - "repos": [ - { - "href": "https://github.com/solodit/solodit_content", - "stargazers": 125, - "lastUpdated": "2026-01-10T18:05:45Z" - } - ] - }, - { - "id": "manually-added:speedrunethereum", - "name": "SpeedrunEthereum", - "description": "Speedrun Ethereum is a hands-on series of challenges designed to help you learn by building. Each challenge delivers one key \"aha\" moment, a mental unlock about how Ethereum really works. At the same time, you'll be building your Ethereum portfolio.", - "thumbnail_url": null, - "banner_url": null, - "twitter": "https://x.com/buidlguidl", - "tags": [ - "education", - "solidity", - "contract-deployment", - "frontend" - ], - "website": "https://speedrunethereum.com/", - "category": "Education & Community Resources", - "repos": [ - { - "href": "https://github.com/BuidlGuidl/SpeedRunEthereum-v2", - "stargazers": 26, - "lastUpdated": "2026-01-07T08:54:24Z" - }, - { - "href": "https://github.com/scaffold-eth/se-2-challenges", - "stargazers": 195, - "lastUpdated": "2026-01-07T15:43:49Z" - } - ] - }, - { - "id": "manually-added:ethereum-eips-ontology", - "name": "Ethereum EIPs Ontology", - "description": "An ontology of Ethereum terms extracted from the Ethereum glossaries and Ethereum Improvement Proposals (EIPs). Available in plain text and SKOS formats.", - "website": null, - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [], - "category": "Education & Community Resources", - "repos": [ - { - "href": "https://github.com/prototypo/ethereum-eips-ontology", - "stargazers": 43, - "lastUpdated": "2025-06-23T06:48:49Z" - } - ] - }, - { - "id": "manually-added:erc-4337-documentation", - "name": "ERC-4337 Documentation", - "description": "Complete guide to ERC-4337 Account Abstraction - smart accounts, bundlers, paymasters, and more", - "website": "https://docs.erc4337.io/", - "thumbnail_url": null, - "banner_url": null, - "twitter": null, - "tags": [ - "account-abstraction", - "education" - ], - "category": "Education & Community Resources", - "repos": [ - { - "href": "https://github.com/eth-infinitism/aa-mkdocs", - "stargazers": 19, - "lastUpdated": "2025-11-14T13:47:09Z" - } - ] +{ + "appsById": { + "0x939241afa4c4b9e1dda6b8250baa8f04fa8b0debce738cfd324c0b18f9926d25": { + "id": "0x939241afa4c4b9e1dda6b8250baa8f04fa8b0debce738cfd324c0b18f9926d25", + "name": "OpenZeppelin Contracts", + "description": "OpenZeppelin Contracts are the go-to library for smart contract development.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/83bab036-91bd-4b9d-a524-dbea2024aa3f.png", + "banner_url": "https://storage.googleapis.com/op-atlas/489f54b5-2035-4a94-82f5-8b41e6cbb857.png", + "twitter": "https://x.com/openzeppelin", + "tags": [ + "cross-chain", + "governance", + "erc721", + "upgradeable-contracts", + "modular-accounts", + "interactive-tools", + "merkle-trees" + ], + "website": "https://www.openzeppelin.com/", + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/OpenZeppelin/openzeppelin-upgrades", + "stargazers": 648, + "lastUpdated": "2025-11-03T20:09:20Z" + }, + { + "href": "https://github.com/OpenZeppelin/openzeppelin-subgraphs", + "stargazers": 146, + "lastUpdated": "2025-02-25T15:09:17Z" + }, + { + "href": "https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades", + "stargazers": 244, + "lastUpdated": "2025-06-30T19:16:05Z" + }, + { + "href": "https://github.com/OpenZeppelin/merkle-tree", + "stargazers": 519, + "lastUpdated": "2025-02-25T02:12:49Z" + }, + { + "href": "https://github.com/openzeppelin/openzeppelin-community-contracts", + "stargazers": 80, + "lastUpdated": "2026-01-13T18:10:27Z" + }, + { + "href": "https://github.com/OpenZeppelin/openzeppelin-contracts", + "stargazers": 26929, + "lastUpdated": "2026-01-15T16:08:39Z" + }, + { + "href": "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable", + "stargazers": 1149, + "lastUpdated": "2026-01-15T16:10:26Z" + }, + { + "href": "https://github.com/OpenZeppelin/contracts-wizard", + "stargazers": 294, + "lastUpdated": "2026-01-16T15:24:19Z" + } + ] + }, + "0xcc8d03e014e121d10602eeff729b755d5dc6a317df0d6302c8a9d3b5424aaba8": { + "id": "0xcc8d03e014e121d10602eeff729b755d5dc6a317df0d6302c8a9d3b5424aaba8", + "name": "Solidity", + "description": "Solidity is an object-oriented, high-level language for implementing smart contracts.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/b6f312d0-1025-4a19-baa9-3aa218fe0833.png", + "banner_url": "https://storage.googleapis.com/op-atlas/bca65077-a87b-4fd8-bcc3-9ad0a65d9d27.png", + "twitter": "https://x.com/solidity_lang", + "tags": [ + "education", + "solidity", + "compiler", + "cli" + ], + "website": "https://soliditylang.org/", + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/ethereum/solidity", + "stargazers": 25502, + "lastUpdated": "2026-01-19T23:37:55Z" + }, + { + "href": "https://github.com/ethereum/solc-js", + "stargazers": 1503, + "lastUpdated": "2025-12-18T20:41:21Z" + } + ] + }, + "0x5200a7351f8d195401dc04631fb83e4836f73a2794f316b2739c03807f30a78b": { + "id": "0x5200a7351f8d195401dc04631fb83e4836f73a2794f316b2739c03807f30a78b", + "name": "Brownie", + "description": "A Python-based development and testing framework for smart contracts targeting the Ethereum Virtual Machine. ", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "tags": [ + "cli", + "debugging-tools" + ], + "website": "https://github.com/eth-brownie/brownie", + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/eth-brownie/brownie", + "stargazers": 2729, + "lastUpdated": "2026-01-14T06:57:54Z" + } + ] + }, + "0x4a5e771af86cf1938056b43cddbf0018dca1376d578f631f7449fe10ac4958ed": { + "id": "0x4a5e771af86cf1938056b43cddbf0018dca1376d578f631f7449fe10ac4958ed", + "name": "Nethereum", + "description": "Nethereum is the .Net integration library for Ethereum, simplifying the access and smart contract interaction with Ethereum nodes both public like Geth (or your preferred client) L2 chains like Optimism, Arbitrum (or your preferred L2), any compatible EVM chain (Gnosis, etc) and permissioned chains like Quorum.", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "tags": [ + "cross-chain", + "wallet", + "json-rpc", + "transaction-signing", + "abi-encoding" + ], + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/Nethereum/Nethereum", + "stargazers": 2245, + "lastUpdated": "2026-01-11T11:50:23Z" + } + ] + }, + "manually-added:intellij-solidity": { + "id": "manually-added:intellij-solidity", + "name": "IntelliJ Solidity", + "description": "Solidity plugin for IntelliJ", + "website": "https://intellij-solidity.dev/", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "tags": [ + "solidity", + "developer-experience", + "code-quality" + ], + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/intellij-solidity/intellij-solidity", + "stargazers": 1097, + "lastUpdated": "2026-01-19T22:20:07Z" + } + ] + }, + "0x819775803938d78eaa95809971ce94cae6a54b4df58505fa36153ffa1d55e12c": { + "id": "0x819775803938d78eaa95809971ce94cae6a54b4df58505fa36153ffa1d55e12c", + "name": "Vscode Solidity Extension", + "description": "Solidity support for Visual Studio code\nVersion Downloads Installs Rating\n\nSolidity is the language used in Ethereum to create smart contracts, this extension provides:\n\nSyntax highlighting\nSnippets\nCompilation of the current contract (Press F1 Solidity : Compile Current Solidity Contract), or F5\nCompilation of all the contracts (Press F1 Solidity : Compile all Solidity Contracts), or Ctrl + F5 or Cmd + F5\nCode completion for all contracts / libraries in the current file and all referenced imports\nGoto definition\nFind all references in project\nHover information\nCode actions / quick fixes (change compiler, format address, add sdpx license.. )\nMono repo support (identifies the project by finding the files: remappings.txt, foundry.toml, brownie-config.yaml, truffle-config.js, hardhat.config.js, hardhat.config.ts)\nDefault project structure (solidity files needs to be in the src/ directory, and libraries in the lib/ directory). Libraries will follow the same structure.\nCompilation supporting EIP82 (dappfile and dependency packages)\nSupport for different solidity versions (Remote and local)\nDownload source code and Abi from Etherscan\nCode generation using Nethereum, it includes currently the default template for Nethereum service, dtos generation. (Open 'contractName.json' after compilation from the bin folder. Press F1 and press Solidity: Code generate from compilation output..) Auto generation of Nethereum files on compilation\nLinting using Solhint or Ethlint\nIt is also available as a standalone LSP", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/006b0fd3-9e23-4192-98d6-08e561da809e.png", + "banner_url": null, + "twitter": null, + "tags": [ + "education", + "solidity" + ], + "category": "Smart Contract Development & Toolchains", + "repos": [ + { + "href": "https://github.com/juanfranblanco/vscode-solidity", + "stargazers": 959, + "lastUpdated": "2025-11-04T17:05:55Z" + } + ] + }, + "0x7f330267969cf845a983a9d4e7b7dbcca5c700a5191269af377836d109e0bb69": { + "id": "0x7f330267969cf845a983a9d4e7b7dbcca5c700a5191269af377836d109e0bb69", + "name": "IPFS", + "description": "IPFS (InterPlanetary File System) is a peer-to-peer protocol designed to make the web faster, more open, and more resilient. By using content-addressed storage rather than location-based references, IPFS removes the need for centralized servers and allows files to be distributed and retrieved from multiple nodes around the world. This approach lowers hosting costs, improves data availability, and reduces censorship, laying the groundwork for a more secure and permanent global information network.\n\nIPFS is used in a variety of applications. While some users interact with IPFS via imported libraries in their projects, a large amount of usage comes via IPFS' HTTP Gateway API which allows users to self-host, use extensions like IPFS companion, or publicly run gateways (whether paid ones run by companies like Filebase, Pinata, etc. or the public goods services at ipfs.io and dweb.link).\n\nIPFS is a system for moving data across decentralized networks, with >11M weekly users and 250K public p2p nodes. Highlights:\n\n1. Off-chain storage. IPFS provides verifiable, off-chain storage, often used to reduce on-chain needs in Ethereum & Optimism. Examples: TrueBlocks (local IPFS-based index for EVM chains, built with grants from OP & EF), Snapshot (IPFS-based off-chain voting).\n\n2. Go-to distribution network for fully decentralized third-party app frontends (for gaming, DeFi, & more). We run gateway services that serve 900M requests/wk, and added native IPFS support to browsers like Chromium & Brave.\n\n3. NFT metadata gold standard. Over 115M NFTs are stored on IPFS, including leading platforms OpenSea (which supports Optimism NFTs), Rarible, and Zora.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/fca3aa6c-bdd5-4632-ae64-37b886d50a65.png", + "banner_url": "https://storage.googleapis.com/op-atlas/35658254-c8b6-4562-9690-db91f187a7ff.png", + "twitter": "https://x.com/ipshipyard", + "tags": [ + "peer-to-peer", + "censorship-resistant", + "cli" + ], + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/ipfs/service-worker-gateway", + "stargazers": 79, + "lastUpdated": "2026-01-20T15:43:06Z" + }, + { + "href": "https://github.com/ipfs/helia", + "stargazers": 1275, + "lastUpdated": "2026-01-16T09:45:08Z" + }, + { + "href": "https://github.com/ipfs/kubo", + "stargazers": 16881, + "lastUpdated": "2026-01-16T01:27:32Z" + }, + { + "href": "https://github.com/ipfs/boxo", + "stargazers": 277, + "lastUpdated": "2026-01-20T18:22:51Z" + }, + { + "href": "https://github.com/ipfs/js-kubo-rpc-client", + "stargazers": 50, + "lastUpdated": "2025-10-15T07:29:36Z" + }, + { + "href": "https://github.com/ipfs/protons", + "stargazers": 37, + "lastUpdated": "2025-06-25T08:34:59Z" + }, + { + "href": "https://github.com/ipfs/js-ipns", + "stargazers": 89, + "lastUpdated": "2025-10-14T10:05:10Z" + }, + { + "href": "https://github.com/ipfs/helia-delegated-routing-v1-http-api", + "stargazers": 4, + "lastUpdated": "2026-01-16T14:05:02Z" + }, + { + "href": "https://github.com/ipfs/js-stores", + "stargazers": 37, + "lastUpdated": "2026-01-08T14:46:02Z" + } + ] + }, + "0xa3d07f453f70d844196d89d79848aa2e70a0bd8b38bf0f493cba1547bb3bca5e": { + "id": "0xa3d07f453f70d844196d89d79848aa2e70a0bd8b38bf0f493cba1547bb3bca5e", + "name": "Ethers.js", + "description": "Ethers.js is a simple, compact and complete JavaScript (via TypeScript) library for interacting with Ethereum and related blockchains.\n\nIt is currently used in a very large number of Blockchain projects, including everything from block explorers to wallets (like MetaMask) and is downloaded over 7.1 million times per month (as of this writing). It is also one of the top 500 projects (by dependants) on NPM.\n\nIt was written and is maintained by me, RicMoo (Richard Moore), a random developer from Canada that is passionate about open-source and dedicates most his waking-time (and some sleeping-time) to it.\n\nHack the Planet! :)", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/f8d776ab-ca70-42ee-9e41-d4f709cd6fd4.png", + "banner_url": "https://storage.googleapis.com/op-atlas/459bdd5e-60a5-49ca-88b8-d4537ebfec16.png", + "twitter": "@ricmoo", + "tags": [ + "frontend", + "json-rpc", + "contract-interaction" + ], + "website": "https://ethers.org", + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/ethers-io/ethers.js", + "stargazers": 8626, + "lastUpdated": "2025-12-03T00:49:47Z" + } + ] + }, + "manually-added:orbitdb": { + "id": "manually-added:orbitdb", + "name": "OrbitDB", + "description": "Peer-to-Peer Databases for the Decentralized Web", + "website": null, + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "tags": [ + "peer-to-peer", + "censorship-resistant" + ], + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/orbitdb/orbitdb", + "stargazers": 8720, + "lastUpdated": "2025-08-05T01:58:51Z" + } + ] + }, + "0x62d9a8a3b602c688610abfbe3965e04ca0d19c5c506f40e79cd185cb501d2018": { + "id": "0x62d9a8a3b602c688610abfbe3965e04ca0d19c5c506f40e79cd185cb501d2018", + "name": "noble cryptography", + "description": "noble cryptography is a high-security, easily auditable set of contained cryptographic libraries with following features:\n\n- Zero or minimal dependencies\n- Highly readable TypeScript / JS code\n- PGP-signed releases and transparent NPM builds\n\nnoble cryptography is used in most modern JS wallets, including Metamask, Rabby, Rainbow, various SDKs, and others. Essentially it empowers a huge share of ecosystem.", + "thumbnail_url": null, + "banner_url": null, + "twitter": "https://x.com/paulmillr", + "tags": [ + "wallet", + "security", + "encryption" + ], + "website": "https://paulmillr.com/noble/", + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/paulmillr/noble-curves", + "stargazers": 876, + "lastUpdated": "2026-01-13T01:04:35Z" + }, + { + "href": "https://github.com/paulmillr/noble-hashes", + "stargazers": 802, + "lastUpdated": "2026-01-13T01:31:07Z" + }, + { + "href": "https://github.com/paulmillr/noble-ciphers", + "stargazers": 358, + "lastUpdated": "2026-01-13T01:07:07Z" + } + ] + }, + "manually-added:ethereum-rb": { + "id": "manually-added:ethereum-rb", + "name": "ethereum.rb", + "description": "Ethereum library for the Ruby language", + "website": null, + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "tags": [ + "sdk" + ], + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/EthWorks/ethereum.rb", + "stargazers": 732, + "lastUpdated": "2022-05-11T14:28:01Z" + } + ] + }, + "0x9d93ec97ef2d3bd4c2b8d95abac9ce0cf43e4f3eb1f05709f8282da8200e69ee": { + "id": "0x9d93ec97ef2d3bd4c2b8d95abac9ce0cf43e4f3eb1f05709f8282da8200e69ee", + "name": "Frames.js", + "description": "frames.js is the leading open source javascript library and debugging environment to help developers make Frames for Farcaster, XMTP and Lens faster & easier. \n\nWe also have been building and maintaining a library for apps to adopt frames in their apps that has been integrated by the Base team in their Base names product.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/230e8ac2-cea9-4cab-8b4f-8fd58ec6553e.png", + "banner_url": "https://storage.googleapis.com/op-atlas/a2dce749-56d7-44d7-a9cc-ffc08255e0f2.png", + "twitter": null, + "tags": [ + "frontend", + "farcaster", + "react", + "nextjs" + ], + "website": "https://www.framesjs.org", + "category": "Client Libraries & SDKs (Front-End)", + "repos": [ + { + "href": "https://github.com/framesjs/frames.js", + "stargazers": 382, + "lastUpdated": "2025-03-27T17:07:46Z" + } + ] + }, + "0x85af258d3fae6bbd2e14ffa8f5b73b64e34b7f8efe685c40134c3f54774e8d6c": { + "id": "0x85af258d3fae6bbd2e14ffa8f5b73b64e34b7f8efe685c40134c3f54774e8d6c", + "name": "Skandha ERC-4337 Bundler", + "description": "Etherspot's developer-friendly TypeScript ERC-4337 bundler that enhances transaction management, optimizes gas costs, and improves the overall efficiency of blockchain interactions. It supports Shared Mempool and provides built-in MEV protection. \n\nEtherspot is pioneering the ERC-4337 shared mempool innovation, which is already live on Optimism.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/c9083120-f920-426d-a33c-37ad6f5b3c3f.png", + "banner_url": "https://storage.googleapis.com/op-atlas/62d53176-085e-4084-9112-f05f62b536db.png", + "twitter": "https://x.com/etherspot", + "tags": [ + "bundler", + "transaction-management", + "gas-optimization", + "cli", + "account-abstraction" + ], + "website": "https://etherspot.io/skandha/", + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/etherspot/skandha", + "stargazers": 610, + "lastUpdated": "2026-01-20T12:53:03Z" + } + ] + }, + "0x79e8bf2d699790b563aa57fd34da1722bea3191ab5ff0601ba56020687702ab9": { + "id": "0x79e8bf2d699790b563aa57fd34da1722bea3191ab5ff0601ba56020687702ab9", + "name": "Etherspot", + "description": "Etherspot is a multi-chain Account & Chain Abstraction development infrastructure that provides solutions for dApps, wallets, games, operating EVM-compatible rollups, or L1/L2 chains to deliver seamless cross-chain Web3 user experience by removing usability pain points.\n\nIn addition to providing Account and Chain Abstraction features, Etherspot helps developers make their projects compatible with the latest Ethereum standards, including ERC-4337, ERC-7579, and EIP-7702, by offering a wide range of cutting-edge services such as Bundler and Paymaster services, APIs, and more.\n\nEtherspot is pioneering the ERC-4337 shared mempool innovation, which is already live on Optimism.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/b05e1c53-bace-499c-b346-ed9fa0003730.png", + "banner_url": "https://storage.googleapis.com/op-atlas/b33b4fe0-6010-470c-a2db-57636d96536d.png", + "twitter": "https://x.com/etherspot", + "tags": [ + "cross-chain", + "wallet", + "defi", + "multi-chain", + "account-abstraction", + "sdk", + "user-experience" + ], + "website": "https://etherspot.io/", + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/etherspot/etherspot-prime-contracts", + "stargazers": 55, + "lastUpdated": "2025-02-20T21:15:37Z" + }, + { + "href": "https://github.com/etherspot/etherspot-modular-sdk", + "stargazers": 22, + "lastUpdated": "2025-10-23T08:27:57Z" + }, + { + "href": "https://www.npmjs.com/package/skandha" + }, + { + "href": "https://www.npmjs.com/package/@etherspot/prime-sdk", + "downloads": 60 + }, + { + "href": "https://github.com/etherspot/skandha", + "stargazers": 610, + "lastUpdated": "2026-01-20T12:53:03Z" + } + ] + }, + "0x2866fcc8ea2ad6cc691b8367023c08ba84a34a14685b0154ba4601b7d4981069": { + "id": "0x2866fcc8ea2ad6cc691b8367023c08ba84a34a14685b0154ba4601b7d4981069", + "name": "go-ethereum-hdwallet", + "description": "Ethereum HD Wallet derivations library in Go", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/09a4acff-98eb-4c73-925e-7403d7678163.png", + "banner_url": "https://storage.googleapis.com/op-atlas/9b428229-b1e5-4f3a-b7f9-d312566a5fcd.png", + "twitter": null, + "tags": [ + "wallet", + "transaction-signing", + "cli" + ], + "website": "https://github.com/miguelmota/go-ethereum-hdwallet", + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/miguelmota/go-ethereum-hdwallet", + "stargazers": 549, + "lastUpdated": "2025-04-27T19:43:22Z" + } + ] + }, + "0x37fe5886f4c77d5a5cb947deff90158c045a5d207572763187748ac4dd4bd9b9": { + "id": "0x37fe5886f4c77d5a5cb947deff90158c045a5d207572763187748ac4dd4bd9b9", + "name": "ethereum-multicall", + "description": "Ability to call many ethereum constant function calls in 1 JSONRPC request", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "tags": [ + "multicall" + ], + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/joshstevens19/ethereum-multicall", + "stargazers": 381, + "lastUpdated": "2025-12-23T11:07:33Z" + } + ] + }, + "0x93decae913f62c0a86519d0b0798e4a10c46c541bfc14dcff0193d6b026e9532": { + "id": "0x93decae913f62c0a86519d0b0798e4a10c46c541bfc14dcff0193d6b026e9532", + "name": "LlamaPay", + "description": "Automate & stream salaries by the second", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/30c6400b-b572-4d16-8138-4dc1cba0ef06.png", + "banner_url": "https://storage.googleapis.com/op-atlas/2c2733fd-a572-4f4f-809d-def2e14b8776.png", + "twitter": "https://x.com/llamapay_io", + "tags": [ + "defi", + "gas-efficient" + ], + "website": "https://llamapay.io/", + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/llamasubs/contracts", + "stargazers": 4, + "lastUpdated": "2024-07-21T13:42:50Z" + }, + { + "href": "https://github.com/LlamaPay/llamapay", + "stargazers": 187, + "lastUpdated": "2022-06-21T08:10:50Z" + } + ] + }, + "0x4e13be6b98dd868cd13e9f4101431ab03d211f429b63f078fa7da260b54d256a": { + "id": "0x4e13be6b98dd868cd13e9f4101431ab03d211f429b63f078fa7da260b54d256a", + "name": "Light Account", + "description": "A set of lightweight, open sourced, audited and gas-optimized ERC-4337 compatible smart contract accounts with designated ownership", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/646cd1db-23b4-4328-8a7c-6c58358a73e1.png", + "banner_url": null, + "twitter": "https://x.com/alchemy", + "tags": [ + "wallet", + "account-abstraction", + "solidity", + "foundry" + ], + "website": "https://www.alchemy.com/", + "category": "Transaction & Wallet Infrastructure", + "repos": [ + { + "href": "https://github.com/alchemyplatform/light-account", + "stargazers": 111, + "lastUpdated": "2026-01-07T16:13:59Z" + } + ] + }, + "0xdc3dce33fd5fb50cf932586d4257456ddf5040ba0955d97641646504c73dbd13": { + "id": "0xdc3dce33fd5fb50cf932586d4257456ddf5040ba0955d97641646504c73dbd13", + "name": "Slither", + "description": "Slither is a Solidity and Vyper static analysis framework written in Python3. \n\nIt runs a suite of vulnerability detectors, prints visual information about contract details, and provides an API to easily write custom analyses. Slither enables developers to find vulnerabilities, enhance their code comprehension, and quickly prototype custom analyses.\n\nSlither has been used for many years by both security engineers and developers to secure their smart contracts. \n\nBy allowing developers to find the most common vulnerabilities on their smart contracts, Slither helps to improve the security of the Optimism ecosystem.\n\nSlither has 90+ detectors, and works on both Solidity and Vyper. In addition it provides printers, helping to review quickly features of contracts. It's python API can also be used to leverage its inbuilt analysis for custom needs.\n\nSlither can directly be run on a contract deployed on optimism, with `slither optim:0x..ADDRESS`", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/27ad6768-163c-4cc3-bd3e-ba8fd3ef5f50.png", + "banner_url": "https://storage.googleapis.com/op-atlas/1276f443-c160-4db0-ab75-33e3e01e3a47.png", + "twitter": "https://x.com/trailofbits", + "tags": [ + "security", + "static-analysis", + "solidity", + "vyper", + "continuous-integration" + ], + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/crytic/slither", + "stargazers": 6093, + "lastUpdated": "2026-01-20T18:39:50Z" + } + ] + }, + "0x2bb095e1f297c71da8bd4ee15097abad3b99e299fe14cd6aa704df3f36d0ae22": { + "id": "0x2bb095e1f297c71da8bd4ee15097abad3b99e299fe14cd6aa704df3f36d0ae22", + "name": "solidity-coverage", + "description": "solidity-coverage provides smart-contract code coverage for the Hardhat developer platform. It's highly accurate, supports full viaIR solidity compilation and a large set of solidity-specific code branch patterns. It's installed on ~230k Github projects and is downloaded ~100k times a week from NPM.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/bd692393-7f1a-4b91-9887-73f7c3250233.png", + "banner_url": "https://storage.googleapis.com/op-atlas/dcbdf6ac-f898-4dac-b9d0-087b8d289f4b.png", + "twitter": null, + "tags": [ + "hardhat", + "analytics", + "code-coverage", + "solidity", + "test-automation" + ], + "website": "https://github.com/sc-forks/solidity-coverage", + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/sc-forks/solidity-coverage", + "stargazers": 1005, + "lastUpdated": "2025-12-11T04:00:44Z" + } + ] + }, + "0xb9996d35862a7c60282da2adf3447f043580f586fcb702ff6869896d15ef6344": { + "id": "0xb9996d35862a7c60282da2adf3447f043580f586fcb702ff6869896d15ef6344", + "name": "Medusa", + "description": "Medusa is a stateful smart contract fuzzer inspired by Echidna. It provides parallelized fuzz testing of smart contracts and the verification of advanced smart contract invariants.\n", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/69e9b03e-47d3-4770-8415-3ae65da044a4.png", + "banner_url": null, + "twitter": "https://x.com/trailofbits", + "tags": [ + "security", + "governance", + "analytics", + "fuzz-testing" + ], + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/crytic/medusa", + "stargazers": 443, + "lastUpdated": "2026-01-20T21:50:38Z" + } + ] + }, + "manually-added:hax": { + "id": "manually-added:hax", + "name": "hax", + "description": "hax is a tool for high assurance translations of a large subset of Rust into formal languages such as F* or Rocq.", + "website": "https://hax.cryspen.com/", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "tags": [ + "formal-verification" + ], + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/cryspen/hax", + "stargazers": 362, + "lastUpdated": "2026-01-19T15:13:10Z" + } + ] + }, + "0xa790f0641e8d72abc88efd13ca215e2dc7e736a4a59ca5a9e0020af29d6297f2": { + "id": "0xa790f0641e8d72abc88efd13ca215e2dc7e736a4a59ca5a9e0020af29d6297f2", + "name": "Crytic-Properties", + "description": "Crytic-Properties is a suite of re-usable security tests for some of the most widely used token standards such as ERC20, ERC721, ERC4626, and more.\n", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/eebeffeb-5b4e-4e8f-a8d9-09718da38b40.png", + "banner_url": null, + "twitter": "https://x.com/trailofbits", + "tags": [ + "security", + "erc721", + "fuzz-testing", + "solidity" + ], + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/crytic/properties", + "stargazers": 356, + "lastUpdated": "2025-11-29T16:59:34Z" + } + ] + }, + "0xeef42373d10554d65aba9e6deb8333a4eddebba829e0afea0dc93e32d8075d2d": { + "id": "0xeef42373d10554d65aba9e6deb8333a4eddebba829e0afea0dc93e32d8075d2d", + "name": "ERCx: Token Test Library", + "description": "Runtime Verification is a leading formal verification company specializing in blockchain security and smart contract correctness. We've developed ERCx, the most comprehensive open-source testing library for ERC token standards, featuring over 500 individual tests across ERC-20, ERC-721, ERC-1155, and ERC-4626 implementations.\nERCx directly empowers Superchain builders by providing production-ready test suites that verify both standard compliance and security properties. Our library offers zero-configuration testing for deployed contracts via Foundry fork testing, plus simple integration for pre-deployment source code validation. With three testing tiers: Standard (EIP compliance), Security (vulnerability detection), and Features (implementation validation), developers can ship token contracts with confidence, knowing they've been thoroughly vetted against real-world attack vectors and edge cases.\nWhat makes ERCx particularly valuable for the Optimism ecosystem is its cross-chain compatibility and handling of complex deployment scenarios. The library seamlessly works across OP Stack chains and handles storage complexities that often challenge developers working with established tokens like USDC or stETH. By providing this critical testing infrastructure as open-source tooling, we're enabling safer, more reliable token implementations across the entire Superchain, directly supporting the ecosystem's growth while reducing the security risks that have historically plagued token contracts in DeFi.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/e6a6dd9b-4ace-4187-8408-0e5729bb0265.png", + "banner_url": "https://storage.googleapis.com/op-atlas/eee0738d-3735-42c8-8802-93b22a041803.png", + "twitter": "x.com/rv_inc", + "tags": [ + "foundry", + "security", + "erc721", + "runtime-verification" + ], + "website": "ercx.runtimeverification.com", + "category": "Security, Testing & Formal Verification", + "repos": [ + { + "href": "https://github.com/runtimeverification/ercx-tests", + "stargazers": 35, + "lastUpdated": "2025-07-04T12:23:27Z" + } + ] + }, + "0x517eaa9c56951de89261f2d7830ea49aae92f2a903104a17d9c5c2edd4959806": { + "id": "0x517eaa9c56951de89261f2d7830ea49aae92f2a903104a17d9c5c2edd4959806", + "name": "LI.FI", + "description": "One API to swap, bridge, and zap across all major blockchains and protocols. Enable trading across all DEX aggregators, bridges, and intent-systems and save hundreds of developer hours.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/4906b988-6024-421e-a706-d01bc508e736.png", + "banner_url": "https://storage.googleapis.com/op-atlas/c280e13b-3e03-47e9-8141-5fad0d51ba2b.png", + "twitter": "https://x.com/lifiprotocol", + "tags": [ + "cross-chain", + "api", + "dex-aggregator", + "multi-chain", + "performance-optimization" + ], + "category": "Cross-Chain & Interoperability", + "repos": [ + { + "href": "https://www.npmjs.com/package/@lifi/sdk", + "downloads": 36632 + }, + { + "href": "https://github.com/lifinance/widget", + "stargazers": 188, + "lastUpdated": "2026-01-20T11:06:38Z" + }, + { + "href": "https://www.npmjs.com/package/@lifi/widget", + "downloads": 12583 + }, + { + "href": "https://github.com/lifinance/contracts", + "stargazers": 191, + "lastUpdated": "2026-01-16T08:38:18Z" + }, + { + "href": "https://github.com/lifinance/sdk", + "stargazers": 243, + "lastUpdated": "2026-01-20T12:52:18Z" + } + ] + }, + "0xc850d11fe786d1168bfeda108721101427dd5425d9d9e6595c35573f7616e940": { + "id": "0xc850d11fe786d1168bfeda108721101427dd5425d9d9e6595c35573f7616e940", + "name": "Daimo Pay", + "description": "Daimo Pay lets users interact with your app using any token on any chain - no bridging, no swapping, no friction.\nIntegrate our SDK in 15 minutes to accept deposits or execute transactions in your app with any token, from any chain, using any wallet or exchange.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/b2bd0510-b0d6-436e-a126-de05026e9418.png", + "banner_url": "https://storage.googleapis.com/op-atlas/dde6090a-600a-418b-be38-5ea73111c407.png", + "twitter": "https://x.com/daimopay", + "tags": [ + "cross-chain" + ], + "website": "https://pay.daimo.com/", + "category": "Cross-Chain & Interoperability", + "repos": [ + { + "href": "https://github.com/daimo-eth/pay", + "stargazers": 18, + "lastUpdated": "2026-01-20T05:09:55Z" + } + ] + }, + "0x62e37e96aa6e1cbfb6bd24b97c4b8f1e12cc3fe35d5388d2f041c42a12b40745": { + "id": "0x62e37e96aa6e1cbfb6bd24b97c4b8f1e12cc3fe35d5388d2f041c42a12b40745", + "name": "Stargate Finance", + "description": "Stargate is a fully composable liquidity\ntransport protocol that lives at the\nheart of omnichain DeFi.\n\nWith Stargate, users & dApps can transfer native assets cross-chain while accessing\nthe protocol’s unified liquidity pools with instant guaranteed finality. ", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/3083ccee-79a8-4ff2-b017-9ecb52d13cbf.png", + "banner_url": "https://storage.googleapis.com/op-atlas/b29f1ab3-b4cf-4255-839e-e7a418e78b80.png", + "twitter": "https://x.com/StargateFinance", + "tags": [ + "cross-chain", + "defi" + ], + "website": "https://stargate.finance/", + "category": "Cross-Chain & Interoperability", + "repos": [ + { + "href": "https://github.com/stargate-protocol/stargate", + "stargazers": 314, + "lastUpdated": "2024-06-06T00:19:00Z" + } + ] + }, + "0xf24315614063278ba3543e1717791132a9afa79b0e65baa01a85bcccbdfa215f": { + "id": "0xf24315614063278ba3543e1717791132a9afa79b0e65baa01a85bcccbdfa215f", + "name": "deBridge", + "description": "deBridge is DeFi's internet of liquidity, enabling real-time movement of assets and information across the DeFi landscape. Without the bottlenecks and risks of liquidity pools, deBridge can power all type of cross-chain interactions with deep liquidity, tight spreads, and guaranteed rates.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/701c36d9-3069-48b6-9aa1-b248378b35b8.png", + "banner_url": "https://storage.googleapis.com/op-atlas/929fbc88-69c7-4a75-be6d-27bf3f2dc8d1.png", + "twitter": "https://x.com/deBridgeFinance", + "tags": [ + "cross-chain", + "defi", + "transaction-optimization" + ], + "website": "https://debridge.finance/", + "category": "Cross-Chain & Interoperability", + "repos": [ + { + "href": "https://www.npmjs.com/package/@debridge-finance/debridge-protocol-evm-interfaces", + "downloads": 0 + }, + { + "href": "https://www.npmjs.com/package/@debridge-finance/legacy-dln-profitability", + "downloads": 91 + }, + { + "href": "https://www.npmjs.com/package/@debridge-finance/desdk", + "downloads": 145 + }, + { + "href": "https://www.npmjs.com/package/@debridge-finance/dln-client", + "downloads": 680 + }, + { + "href": "https://www.npmjs.com/package/@debridge-finance/dln-taker", + "downloads": 5 + }, + { + "href": "https://github.com/debridge-finance/hardhat-debridge", + "stargazers": 23, + "lastUpdated": "2024-06-04T10:44:19Z" + }, + { + "href": "https://github.com/debridge-finance/dln-taker", + "stargazers": 20, + "lastUpdated": "2024-08-30T09:10:01Z" + }, + { + "href": "https://github.com/debridge-finance/debridge-node", + "stargazers": 9, + "lastUpdated": "2025-06-25T14:37:29Z" + }, + { + "href": "https://github.com/debridge-finance/dln-contracts", + "stargazers": 2, + "lastUpdated": "2024-06-04T11:18:02Z" + }, + { + "href": "https://github.com/debridge-finance/debridge-contracts-v1", + "stargazers": 58, + "lastUpdated": "2024-10-23T15:11:09Z" + } + ] + }, + "0x38c38455bb0fd71d2929fcf799279569ab5f5c5d3e1f92f8642ce87aa25accdf": { + "id": "0x38c38455bb0fd71d2929fcf799279569ab5f5c5d3e1f92f8642ce87aa25accdf", + "name": "Decent.xyz", + "description": "Decent enables cross-chain swaps and 1-click transactions with any token across chains. ", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/1ede3a09-1878-4852-a564-f86f4f49b9fc.png", + "banner_url": "https://storage.googleapis.com/op-atlas/862dacb3-f496-4afe-ae66-70f9f9949937.png", + "twitter": "https://twitter.com/decentxyz", + "tags": [ + "cross-chain", + "nextjs", + "tailwind-css", + "foundry", + "user-experience" + ], + "category": "Cross-Chain & Interoperability", + "repos": [ + { + "href": "https://www.npmjs.com/package/@decent.xyz/box-common", + "downloads": 1230 + }, + { + "href": "https://www.npmjs.com/package/@decent.xyz/box-hooks", + "downloads": 1053 + }, + { + "href": "https://github.com/decentxyz/launch-nfts", + "stargazers": 1, + "lastUpdated": "2024-06-06T16:40:50Z" + }, + { + "href": "https://github.com/decentxyz/decentV2-contracts", + "stargazers": 2, + "lastUpdated": "2024-06-06T15:26:43Z" + }, + { + "href": "https://www.npmjs.com/package/@decent.xyz/box-ui", + "downloads": 833 + }, + { + "href": "https://www.npmjs.com/package/@decent.xyz/the-box", + "downloads": 837 + }, + { + "href": "https://github.com/decentxyz/decent-contracts-v3", + "stargazers": 1, + "lastUpdated": "2025-03-28T20:43:18Z" + } + ] + }, + "0x66cce776ce6eaa99192120fc25b91ecc7b98e03210a08f0d3bfda82f542d3e1a": { + "id": "0x66cce776ce6eaa99192120fc25b91ecc7b98e03210a08f0d3bfda82f542d3e1a", + "name": "OP ENS Gateway by Opti.Domains", + "description": "Opti.Domains has developed an ENS Gateway implementation for OP Stack chains that supports various proofs, including those from L2OutputOracle, Dispute Game, and Anchor State. The appropriate proof is automatically selected based on the configuration of the OP Stack chain.\n\nThe Opti.Domains ENS Gateway automatically upgrades in response to the OP Stack's transition from L2OutputOracle to Dispute Game, requiring no manual intervention or updates to the verifier contract or gateway server.\n\nThe ENS Gateway, specifically the EVMGateway, enables trustless cross-chain data retrieval for ENS names deployed on Layer 2 networks like Optimism with a CCIP Gateway. When an ENS name lookup occurs, the resolver reverts with OffchainLookup containing the gateway URL. The client then contacts the gateway, which returns the requested data. This data is passed to a callback function on the resolver for verification before being returned to the client as the final result of the name lookup.\n\nOur ENS Gateway has a mechanism to ensure liveliness even in the event that the respected dispute game type has suddenly changed, as seen in the recent proposal, 'Upgrade Proposal #10: Granite Network Upgrade,' by storing a backup dispute game type and only trusting its anchor state.\n\nOpti.Domains has also developed social verification and attestation to EAS in collaboration with Bored Town. We are on our way to scaling ENS to OP. We have contributed to the ENS OP Gateway development, which is currently under review by ENS core developers.\n\nThe Namespace team has expressed interest and reached out to us with questions about using our OP ENS Gateway. Additionally, several teams have participated in discussions regarding the development of our OP ENS Gateway.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/8f6ad6e0-029a-4f59-b1d2-c7885248b99a.png", + "banner_url": "https://storage.googleapis.com/op-atlas/135853fe-2393-4a0a-a959-044ff973fcf0.png", + "twitter": "https://x.com/optidomains", + "tags": [ + "cross-chain", + "governance", + "layer-2", + "verification", + "scalability" + ], + "website": "https://opti.domains", + "category": "Cross-Chain & Interoperability", + "repos": [ + { + "href": "https://www.npmjs.com/package/@optidomains/passport-discord", + "downloads": 7 + }, + { + "href": "https://github.com/Opti-domains/evmgateway", + "stargazers": 0, + "lastUpdated": "2025-01-07T16:14:06Z" + }, + { + "href": "https://github.com/Opti-domains/ens-diamond-resolver-v1", + "stargazers": 0, + "lastUpdated": "2024-05-28T02:46:59Z" + }, + { + "href": "https://github.com/Opti-domains/dispute-game-lookup", + "stargazers": 0, + "lastUpdated": "2025-02-16T18:57:17Z" + }, + { + "href": "https://www.npmjs.com/package/@optidomains/wagmi-core", + "downloads": 1 + }, + { + "href": "https://github.com/Opti-domains/optidomains-ens-contracts", + "stargazers": 0, + "lastUpdated": "2024-05-28T02:37:33Z" + }, + { + "href": "https://github.com/Opti-domains/modular-ens-contracts", + "stargazers": 2, + "lastUpdated": "2024-05-28T04:03:40Z" + }, + { + "href": "https://www.npmjs.com/package/@optidomains/wagmi", + "downloads": 1 + }, + { + "href": "https://www.npmjs.com/package/@optidomains/rainbowkit", + "downloads": 1 + } + ] + }, + "0x663e4d25ca3f327365240471b4831ea3c989cb132bbf6ae8f5c1e15268591795": { + "id": "0x663e4d25ca3f327365240471b4831ea3c989cb132bbf6ae8f5c1e15268591795", + "name": "Blockscout open-source block explorer", + "description": "Blockscout block explorer is the #1 explorer used by Optimistic rollups and Superchain networks. Blockscout is highly customizable and available, providing advanced developer tooling for projects and blockchain transparency for users.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/3113c4b6-4e29-420c-95f8-2ae4f6098089.png", + "banner_url": "https://storage.googleapis.com/op-atlas/c08d15e7-41fd-41a7-9c04-b1e10b0c1f26.png", + "twitter": "https://x.com/blockscoutcom", + "tags": [ + "block-explorer", + "chains" + ], + "website": "http://www.blockscout.com", + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/blockscout/blockscout", + "stargazers": 4380, + "lastUpdated": "2026-01-20T19:42:29Z" + } + ] + }, + "0xaed5941b7a9f20de83f5c839bda507be43cbf41777fc623abf4bf05773298826": { + "id": "0xaed5941b7a9f20de83f5c839bda507be43cbf41777fc623abf4bf05773298826", + "name": "Otterscan", + "description": "A blazingly fast, local, Ethereum block explorer built on top of Erigon for EVM chains", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/55a1fffb-dcd9-448b-8e34-9fb4b09a72f7.png", + "banner_url": "https://storage.googleapis.com/op-atlas/a0e75c22-8aff-4176-af81-6c03208c1bd3.png", + "twitter": "https://x.com/otterscan", + "tags": [ + "docker", + "block-explorer", + "chains", + "privacy-focused", + "react-app", + "json-rpc", + "visualization" + ], + "website": "https://otterscan.io/", + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/otterscan/otterscan", + "stargazers": 1396, + "lastUpdated": "2025-11-05T05:21:21Z" + } + ] + }, + "0x97525ec91080ddd917eaccabf9d383cf70a2f78839ab21eeabe1687e312f2132": { + "id": "0x97525ec91080ddd917eaccabf9d383cf70a2f78839ab21eeabe1687e312f2132", + "name": "rindexer", + "description": "rindexer is an opensource powerful, high-speed indexing toolset developed in Rust, designed for compatibility with any EVM chain. This tool allows you to index chain events using a simple YAML file, requiring no additional coding. For more advanced needs, the rindexer provides foundations and advanced capabilities to build whatever you want. It's highly extendable, enabling you to construct indexing pipelines with ease and focus exclusively on the logic. rindexer out the box also gives you a GraphQL API to query the data you have indexed instantly.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/366c4940-78cc-4119-958b-b93f3c9a5845.png", + "banner_url": null, + "twitter": null, + "tags": [ + "indexing", + "cli" + ], + "website": "https://rindexer.xyz/", + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/joshstevens19/rindexer", + "stargazers": 643, + "lastUpdated": "2026-01-20T18:33:58Z" + } + ] + }, + "0x1aacb85f1d87039696b876ddcae98c56d38ea9eed07b265409fdb256c8f8172a": { + "id": "0x1aacb85f1d87039696b876ddcae98c56d38ea9eed07b265409fdb256c8f8172a", + "name": "Blockhead", + "description": "Open-source portfolio tracker and explorer interface for the decentralized web. https://blockhead.info", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/3a1343aa-8bb3-4f30-abc0-6ba02dd3787a.png", + "banner_url": "https://storage.googleapis.com/op-atlas/7c1ee7ff-ad46-4b74-a941-48cc7ddc2dbe.png", + "twitter": "https://x.com/0xBlockhead", + "tags": [ + "block-explorer" + ], + "website": "https://blockhead.info", + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/darrylyeo/blockhead", + "stargazers": 135, + "lastUpdated": "2025-05-18T04:45:05Z" + } + ] + }, + "0xf9c5d092fac6ad924253d685cc7ba21d4e519813e673a3a8300f33cb3a6b4e06": { + "id": "0xf9c5d092fac6ad924253d685cc7ba21d4e519813e673a3a8300f33cb3a6b4e06", + "name": "NFTScan", + "description": "NFTScan is a professional NFT Explorer tool that provides developers and users with NFT data search services for the Superchain ecosystem, including: OP Mainnet, Base, Mint blockchain and other blockchain networks.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/30fb3451-049c-4904-a109-d3c06004a731.png", + "banner_url": "https://storage.googleapis.com/op-atlas/09a998c5-5217-4937-b2c8-d994e5cfe1c7.png", + "twitter": "https://x.com/nftscan_com", + "tags": [ + "erc721" + ], + "website": "https://www.nftscan.com/", + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/nftscan-official/nftscan-api-js-sdk", + "stargazers": 18, + "lastUpdated": "2025-06-13T06:21:00Z" + } + ] + }, + "0x46aff4985914b8e56b8fd62a9b8c3a03e2320315a9dfd6126e5ae272173cda87": { + "id": "0x46aff4985914b8e56b8fd62a9b8c3a03e2320315a9dfd6126e5ae272173cda87", + "name": "Patterns wallet analytics & CRM", + "description": "Free public web3 CRM and wallet analytics for OP builders. Helping OP dApps & DeFis discover most valuable user groups and counteract sybils. Part of the Optimism Superchain 4337 Data Standards group.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/ee4b3aab-f2b2-4400-abbc-2383b62662a4.png", + "banner_url": "https://storage.googleapis.com/op-atlas/b3b3b9a2-81bd-4e6b-af22-c388ca45c9f5.png", + "twitter": "https://x.com/patterns_build", + "tags": [ + "analytics", + "defi", + "visualization", + "docker", + "scalability" + ], + "category": "Data, Analytics & Tracing", + "repos": [ + { + "href": "https://github.com/tokenguardio/dapp-marvels", + "stargazers": 15, + "lastUpdated": "2025-03-21T11:37:20Z" + } + ] + }, + "0x17fb589e599fe05e532b90c121eccc55b1249301e783dae226bad698872322da": { + "id": "0x17fb589e599fe05e532b90c121eccc55b1249301e783dae226bad698872322da", + "name": "The Ethernaut", + "description": "The Ethernaut is a community-driven capture-the-flag wargame that challenges developers of all levels to break smart contracts while learning common Solidity vulnerabilities. Maintained by OpenZeppelin, each level provides a gamified experience where a smart contract must be ‘hacked’ to progress. It is 100% open-source, with all levels contributed by players.\n\nIn 2024, we have continued expanding the game, adding four new advanced levels—HigherOrder, Stake, Impersonator, and Magic Animal Carousel—which explore current vulnerabilities in smart contract development. These levels introduce challenges related to low-level EVM programming, staking vulnerabilities, signature verification exploits, and bitwise manipulation attacks, pushing players to deepen their understanding of Ethereum security.\n\nBeyond new levels, we have also redesigned the UI, added support for multiple networks, and expanded language translations to make the game more accessible to a global audience.\n\nWe believe that The Ethernaut is an essential training tool for developers across the Ethereum ecosystem, including those building on the Optimism network. By continually evolving the game with new challenges and features, we strive to make smart contract security education engaging, practical, and accessible to everyone.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/06419654-6022-400a-9670-82ca6e0225fe.png", + "banner_url": "https://storage.googleapis.com/op-atlas/5aba83e1-a4f2-453c-9e64-9884d0e628d6.png", + "twitter": "https://x.com/openzeppelin", + "tags": [ + "education", + "security", + "solidity", + "community-driven", + "react-app" + ], + "website": "https://ethernaut.openzeppelin.com/", + "category": "Education & Community Resources", + "repos": [ + { + "href": "https://github.com/OpenZeppelin/ethernaut", + "stargazers": 2273, + "lastUpdated": "2025-11-19T16:57:18Z" + } + ] + }, + "0x72d363f14ae85f47acfe748fb0a2bed73195582bb9863de18901f5dfe309b8f7": { + "id": "0x72d363f14ae85f47acfe748fb0a2bed73195582bb9863de18901f5dfe309b8f7", + "name": "Solodit", + "description": "What is it?\nSolodit is an open-source, community-driven platform dedicated to improving web3 security. It aggregates over 8,000 smart contract vulnerability reports, bug bounty opportunities, and security audits from top firms like Cyfrin, OpenZeppelin and Trail of Bits, alongside contributions from individual researchers. Solodit not only aggregates this information but also makes it actionable, equipping developers and auditors with tools to prevent exploits and enhance the safety of dapps.\n\nWhy is it needed?\nThe web3 ecosystem is plagued by billions of dollars in losses due to security breaches in smart contracts and protocols. Despite the availability of security knowledge, it is fragmented across various platforms and reports, making it inaccessible to most developers and security teams. There are several problems that Solodit solves:\n\nKnowledge Gap: Many teams deploy smart contracts without understanding past vulnerabilities, leading to repeat incidents.\nInefficiencies: Developers and auditors spend valuable time searching disparate sources for security insights.\nEconomic Impact: Preventable exploits undermine trust in web3, stalling adoption and investment.\n\nBy aggregating and structuring security data, Solodit enables proactive vulnerability management and risk mitigation in the Web3 ecosystem.\n\nHow is it unique?\nComprehensive Coverage: Aggregates findings from leading auditors and platforms, offering unmatched insights into vulnerabilities and bug bounties.\nActionable Insights: Goes beyond archiving reports by providing advanced search tools and tagging systems to contextualise risks and solutions.\nCommunity-Driven Enhancements: Facilitates collaboration via ratings, tagging, and leaderboards that recognise top contributors, fostering a thriving security community.\nEducational Resource: This site serves as a learning hub for developers and auditors, providing real-world case studies on blockchain security.\n\nSolodit is a multipurpose tool designed to:\nMitigate Risk: Helps developers avoid known vulnerabilities, reducing the likelihood of exploits.\nPromote Proactive Security: Enables protocols to adopt preventive measures by studying historical vulnerabilities.\nStreamline Bug Bounties: Simplifies participation in bounty programs, encouraging more ethical hackers to contribute to ecosystem security.\nFoster Skill Development: Supports auditors in honing their skills and staying updated on emerging threats.\nSupport Decision-Making: Assists protocols in evaluating auditors via its leaderboard, promoting accountability and quality audits.\n\nWho is it for?\nDevelopers: Seeking to secure their smart contracts and understand vulnerability trends.\nAuditors: Looking to access a comprehensive repository of findings and showcase their expertise.\nWhitehat Hackers: Interested in participating in bug bounty programs and contributing to web3 security.\nProtocol P&E teams: Aiming to assess risks and prevent costly exploits.\nEducators and Researchers: Teaching or studying blockchain security with real-world examples, e.g. Cyfrin Updraft. \n\nStill to come:\nUI/UX redesign\nPower Aderyn, static analysis support", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/9cf8d92d-5549-4321-b675-c25256860183.png", + "banner_url": "https://storage.googleapis.com/op-atlas/20eb90df-0dd5-41fb-a3ce-f90cf3822492.png", + "twitter": null, + "tags": [ + "security", + "education", + "analytics", + "community-driven" + ], + "website": "https://solodit.cyfrin.io/", + "category": "Education & Community Resources", + "repos": [ + { + "href": "https://github.com/solodit/solodit_content", + "stargazers": 125, + "lastUpdated": "2026-01-10T18:05:45Z" + } + ] + }, + "manually-added:speedrunethereum": { + "id": "manually-added:speedrunethereum", + "name": "SpeedrunEthereum", + "description": "Speedrun Ethereum is a hands-on series of challenges designed to help you learn by building. Each challenge delivers one key \"aha\" moment, a mental unlock about how Ethereum really works. At the same time, you'll be building your Ethereum portfolio.", + "thumbnail_url": null, + "banner_url": null, + "twitter": "https://x.com/buidlguidl", + "tags": [ + "education", + "solidity", + "contract-deployment", + "frontend" + ], + "website": "https://speedrunethereum.com/", + "category": "Education & Community Resources", + "repos": [ + { + "href": "https://github.com/BuidlGuidl/SpeedRunEthereum-v2", + "stargazers": 26, + "lastUpdated": "2026-01-07T08:54:24Z" + }, + { + "href": "https://github.com/scaffold-eth/se-2-challenges", + "stargazers": 195, + "lastUpdated": "2026-01-07T15:43:49Z" + } + ] + }, + "manually-added:ethereum-eips-ontology": { + "id": "manually-added:ethereum-eips-ontology", + "name": "Ethereum EIPs Ontology", + "description": "An ontology of Ethereum terms extracted from the Ethereum glossaries and Ethereum Improvement Proposals (EIPs). Available in plain text and SKOS formats.", + "website": null, + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "tags": [], + "category": "Education & Community Resources", + "repos": [ + { + "href": "https://github.com/prototypo/ethereum-eips-ontology", + "stargazers": 43, + "lastUpdated": "2025-06-23T06:48:49Z" + } + ] + }, + "manually-added:erc-4337-documentation": { + "id": "manually-added:erc-4337-documentation", + "name": "ERC-4337 Documentation", + "description": "Complete guide to ERC-4337 Account Abstraction - smart accounts, bundlers, paymasters, and more", + "website": "https://docs.erc4337.io/", + "thumbnail_url": null, + "banner_url": null, + "twitter": null, + "tags": [ + "account-abstraction", + "education" + ], + "category": "Education & Community Resources", + "repos": [ + { + "href": "https://github.com/eth-infinitism/aa-mkdocs", + "stargazers": 19, + "lastUpdated": "2025-11-14T13:47:09Z" + } + ] + }, + "0xa38c8f4ffa48fe01222fe1b5f2bc6c95e204a4f243d67bd0c9f92887d905d3d8": { + "id": "0xa38c8f4ffa48fe01222fe1b5f2bc6c95e204a4f243d67bd0c9f92887d905d3d8", + "name": "Academy", + "description": "Training, incubation, and acceleration programs for non-tech people and devs to start in the web3 privacy ecosystem.", + "thumbnail_url": "https://storage.googleapis.com/op-atlas/153bea66-bef0-481d-bb29-2882eb0e6edb.png", + "banner_url": "https://storage.googleapis.com/op-atlas/1809a100-d320-47f2-8144-94343ef5ea40.png", + "twitter": "https://x.com/web3privacy", + "tags": [ + "education" + ], + "website": "https://academy.web3privacy.info/", + "category": "Education & Community Resources", + "repos": [ + { + "href": "https://github.com/web3privacy/cypherpunkacademy", + "stargazers": 7, + "lastUpdated": "2025-02-07T18:51:24Z" + } + ] + } }, - { - "id": "0xa38c8f4ffa48fe01222fe1b5f2bc6c95e204a4f243d67bd0c9f92887d905d3d8", - "name": "Academy", - "description": "Training, incubation, and acceleration programs for non-tech people and devs to start in the web3 privacy ecosystem.", - "thumbnail_url": "https://storage.googleapis.com/op-atlas/153bea66-bef0-481d-bb29-2882eb0e6edb.png", - "banner_url": "https://storage.googleapis.com/op-atlas/1809a100-d320-47f2-8144-94343ef5ea40.png", - "twitter": "https://x.com/web3privacy", - "tags": [ - "education" + "selections": { + "mainPageHighlights": [ + "0x62e37e96aa6e1cbfb6bd24b97c4b8f1e12cc3fe35d5388d2f041c42a12b40745", + "0x85af258d3fae6bbd2e14ffa8f5b73b64e34b7f8efe685c40134c3f54774e8d6c", + "0x663e4d25ca3f327365240471b4831ea3c989cb132bbf6ae8f5c1e15268591795" ], - "website": "https://academy.web3privacy.info/", - "category": "Education & Community Resources", - "repos": [ - { - "href": "https://github.com/web3privacy/cypherpunkacademy", - "stargazers": 7, - "lastUpdated": "2025-02-07T18:51:24Z" - } - ] + "categoryHighlights": { + "interoperability": [ + "0x62e37e96aa6e1cbfb6bd24b97c4b8f1e12cc3fe35d5388d2f041c42a12b40745", + "0x517eaa9c56951de89261f2d7830ea49aae92f2a903104a17d9c5c2edd4959806", + "0xf24315614063278ba3543e1717791132a9afa79b0e65baa01a85bcccbdfa215f" + ], + "transactions": [ + "0x85af258d3fae6bbd2e14ffa8f5b73b64e34b7f8efe685c40134c3f54774e8d6c", + "0x79e8bf2d699790b563aa57fd34da1722bea3191ab5ff0601ba56020687702ab9", + "0x2866fcc8ea2ad6cc691b8367023c08ba84a34a14685b0154ba4601b7d4981069" + ], + "analytics": [ + "0x663e4d25ca3f327365240471b4831ea3c989cb132bbf6ae8f5c1e15268591795", + "0xaed5941b7a9f20de83f5c839bda507be43cbf41777fc623abf4bf05773298826", + "0x1aacb85f1d87039696b876ddcae98c56d38ea9eed07b265409fdb256c8f8172a" + ], + "education": [ + "0x17fb589e599fe05e532b90c121eccc55b1249301e783dae226bad698872322da", + "0x72d363f14ae85f47acfe748fb0a2bed73195582bb9863de18901f5dfe309b8f7", + "0xa38c8f4ffa48fe01222fe1b5f2bc6c95e204a4f243d67bd0c9f92887d905d3d8" + ], + "sdks": [ + "0x7f330267969cf845a983a9d4e7b7dbcca5c700a5191269af377836d109e0bb69", + "0xa3d07f453f70d844196d89d79848aa2e70a0bd8b38bf0f493cba1547bb3bca5e", + "0x9d93ec97ef2d3bd4c2b8d95abac9ce0cf43e4f3eb1f05709f8282da8200e69ee" + ], + "contracts": [ + "0x939241afa4c4b9e1dda6b8250baa8f04fa8b0debce738cfd324c0b18f9926d25", + "0xcc8d03e014e121d10602eeff729b755d5dc6a317df0d6302c8a9d3b5424aaba8" + ], + "security": [ + "0xdc3dce33fd5fb50cf932586d4257456ddf5040ba0955d97641646504c73dbd13", + "0x2bb095e1f297c71da8bd4ee15097abad3b99e299fe14cd6aa704df3f36d0ae22", + "0xeef42373d10554d65aba9e6deb8333a4eddebba829e0afea0dc93e32d8075d2d" + ] + }, + "categoryPreviews": { + "interoperability": [ + "0x517eaa9c56951de89261f2d7830ea49aae92f2a903104a17d9c5c2edd4959806", + "0xc850d11fe786d1168bfeda108721101427dd5425d9d9e6595c35573f7616e940", + "0x62e37e96aa6e1cbfb6bd24b97c4b8f1e12cc3fe35d5388d2f041c42a12b40745", + "0xf24315614063278ba3543e1717791132a9afa79b0e65baa01a85bcccbdfa215f", + "0x38c38455bb0fd71d2929fcf799279569ab5f5c5d3e1f92f8642ce87aa25accdf" + ], + "transactions": [ + "0x85af258d3fae6bbd2e14ffa8f5b73b64e34b7f8efe685c40134c3f54774e8d6c", + "0x79e8bf2d699790b563aa57fd34da1722bea3191ab5ff0601ba56020687702ab9", + "0x2866fcc8ea2ad6cc691b8367023c08ba84a34a14685b0154ba4601b7d4981069", + "0x37fe5886f4c77d5a5cb947deff90158c045a5d207572763187748ac4dd4bd9b9", + "0x93decae913f62c0a86519d0b0798e4a10c46c541bfc14dcff0193d6b026e9532" + ], + "analytics": [ + "0x663e4d25ca3f327365240471b4831ea3c989cb132bbf6ae8f5c1e15268591795", + "0xaed5941b7a9f20de83f5c839bda507be43cbf41777fc623abf4bf05773298826", + "0x97525ec91080ddd917eaccabf9d383cf70a2f78839ab21eeabe1687e312f2132", + "0x1aacb85f1d87039696b876ddcae98c56d38ea9eed07b265409fdb256c8f8172a", + "0xf9c5d092fac6ad924253d685cc7ba21d4e519813e673a3a8300f33cb3a6b4e06" + ], + "education": [ + "0x17fb589e599fe05e532b90c121eccc55b1249301e783dae226bad698872322da", + "0x72d363f14ae85f47acfe748fb0a2bed73195582bb9863de18901f5dfe309b8f7", + "manually-added:speedrunethereum", + "manually-added:ethereum-eips-ontology", + "manually-added:erc-4337-documentation" + ], + "sdks": [ + "0x7f330267969cf845a983a9d4e7b7dbcca5c700a5191269af377836d109e0bb69", + "0xa3d07f453f70d844196d89d79848aa2e70a0bd8b38bf0f493cba1547bb3bca5e", + "manually-added:orbitdb", + "0x62d9a8a3b602c688610abfbe3965e04ca0d19c5c506f40e79cd185cb501d2018", + "manually-added:ethereum-rb" + ], + "contracts": [ + "0x939241afa4c4b9e1dda6b8250baa8f04fa8b0debce738cfd324c0b18f9926d25", + "0xcc8d03e014e121d10602eeff729b755d5dc6a317df0d6302c8a9d3b5424aaba8", + "0x5200a7351f8d195401dc04631fb83e4836f73a2794f316b2739c03807f30a78b", + "0x4a5e771af86cf1938056b43cddbf0018dca1376d578f631f7449fe10ac4958ed", + "manually-added:intellij-solidity" + ], + "security": [ + "0xdc3dce33fd5fb50cf932586d4257456ddf5040ba0955d97641646504c73dbd13", + "0x2bb095e1f297c71da8bd4ee15097abad3b99e299fe14cd6aa704df3f36d0ae22", + "0xb9996d35862a7c60282da2adf3447f043580f586fcb702ff6869896d15ef6344", + "manually-added:hax", + "0xa790f0641e8d72abc88efd13ca215e2dc7e736a4a59ca5a9e0020af29d6297f2" + ] + }, + "computedAt": "2026-01-27T20:48:46.213Z" } -] +} \ No newline at end of file diff --git a/src/lib/utils/time.ts b/src/lib/utils/time.ts index 4b5a34927f6..0eadcd13ad6 100644 --- a/src/lib/utils/time.ts +++ b/src/lib/utils/time.ts @@ -21,37 +21,3 @@ export const getLocaleFormattedDate = (locale: Lang, date: string) => { return new Intl.DateTimeFormat(locale).format(walletLastUpdatedDate) } - -/** - * Returns a duration in seconds for the given interval. - * - * @param interval - "minute" | "hour" | "day" | "week" | "month" - * @param multiplier - Number of intervals (default: 1) - * @returns Duration in seconds - */ -export const every = ( - interval: "minute" | "hour" | "day" | "week" | "month", - multiplier: number = 1 -): number => { - const SECOND = 1 - const MINUTE = 60 * SECOND - const HOUR = 60 * MINUTE - const DAY = 24 * HOUR - const WEEK = 7 * DAY - const MONTH = 28 * DAY // approximate - - switch (interval) { - case "minute": - return multiplier * MINUTE - case "hour": - return multiplier * HOUR - case "day": - return multiplier * DAY - case "week": - return multiplier * WEEK - case "month": - return multiplier * MONTH - default: - return multiplier * DAY - } -} From 2e8f0092b0db96afc43994e20ad85c94550a446a Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 27 Jan 2026 16:16:33 -0500 Subject: [PATCH 62/74] refactor(developers/apps): migrate category pages to FilterBar - Create CategoryAppsGrid client component using shared FilterBar - Move filtering state from URL params to client-side useState - Delete TagFilter component (replaced by FilterBar) - Simplify page.tsx by extracting grid logic to dedicated component Co-Authored-By: Claude --- .../developers/apps/[category]/page.tsx | 102 ++------------ .../apps/_components/CategoryAppsGrid.tsx | 84 ++++++++++++ .../developers/apps/_components/TagFilter.tsx | 125 ------------------ src/components/FilterBar/index.tsx | 4 +- 4 files changed, 98 insertions(+), 217 deletions(-) create mode 100644 app/[locale]/developers/apps/_components/CategoryAppsGrid.tsx delete mode 100644 app/[locale]/developers/apps/_components/TagFilter.tsx diff --git a/app/[locale]/developers/apps/[category]/page.tsx b/app/[locale]/developers/apps/[category]/page.tsx index 4dd8f8a2510..3f0a15b501d 100644 --- a/app/[locale]/developers/apps/[category]/page.tsx +++ b/app/[locale]/developers/apps/[category]/page.tsx @@ -1,5 +1,3 @@ -import { AppWindowMac } from "lucide-react" -import Image from "next/image" import { redirect } from "next/navigation" import { getTranslations, setRequestLocale } from "next-intl/server" @@ -8,24 +6,22 @@ import type { CommitHistory, Lang, PageParams } from "@/lib/types" import { ContentHero } from "@/components/Hero" import MainArticle from "@/components/MainArticle" import SubpageCard from "@/components/SubpageCard" -import { LinkBox, LinkOverlay } from "@/components/ui/link-box" import { Section } from "@/components/ui/section" -import { TagsInlineText } from "@/components/ui/tag" import { getAppPageContributorInfo } from "@/lib/utils/contributors" import { getMetadata } from "@/lib/utils/metadata" import AppModalContents from "../_components/AppModalContents" import AppModalWrapper from "../_components/AppModalWrapper" +import CategoryAppsGrid from "../_components/CategoryAppsGrid" import HighlightsSection from "../_components/HighlightsSection" -import TagFilter from "../_components/TagFilter" import { DEV_APP_CATEGORIES } from "../constants" -import type { DeveloperAppCategorySlug, DeveloperAppTag } from "../types" +import type { DeveloperAppCategorySlug } from "../types" import { getCachedHighlightsByCategory, getCategoryPageHighlights, + transformDeveloperAppsData, } from "../utils" -import { transformDeveloperAppsData } from "../utils" import DevelopersAppsCategoryJsonLD from "./page-jsonld" @@ -36,10 +32,10 @@ const Page = async ({ searchParams, }: { params: PageParams & { category: DeveloperAppCategorySlug } - searchParams: { appId?: string; tag?: string } + searchParams: { appId?: string } }) => { const { locale, category } = params - const { appId, tag } = searchParams + const { appId } = searchParams setRequestLocale(locale) const t = await getTranslations({ locale, namespace: "page-developers-apps" }) @@ -54,55 +50,22 @@ const Page = async ({ new Set(allCategoryData.flatMap((app) => app.tags)) ).sort() - // Filter by selected tag if present (validate it's a real tag) - const validTag = - tag && uniqueTags.includes(tag as DeveloperAppTag) - ? (tag as DeveloperAppTag) - : undefined - const categoryData = validTag - ? allCategoryData.filter((app) => app.tags.includes(validTag)) - : allCategoryData - const activeApp = enrichedData.find((app) => app.id === appId) - // Clean up invalid searchParams by redirecting - const hasInvalidTag = tag && !validTag - const hasInvalidAppId = appId && !activeApp - if (hasInvalidTag || hasInvalidAppId) { - const params = new URLSearchParams() - if (validTag) params.set("tag", validTag) - if (activeApp) params.set("appId", activeApp.id) - const queryString = params.toString() - redirect( - `/developers/apps/${category}${queryString ? `?${queryString}` : ""}` - ) + // Clean up invalid appId by redirecting + if (appId && !activeApp) { + redirect(`/developers/apps/${category}`) } - // Prepare translations for client component + // Prepare tag labels for client component const tagLabels = Object.fromEntries( uniqueTags.map((tag) => [tag, t(`page-developers-apps-tag-${tag}`)]) ) - const filterLabels = { - filterBy: t("page-developers-apps-filter-label"), - clearFilter: t("page-developers-apps-filter-clear"), - noTags: t("page-developers-apps-filter-no-tags"), - showing: t("page-developers-apps-filter-showing"), - } // Get dynamic highlights based on stars and recent activity (cached weekly) const highlightsByCategory = await getCachedHighlightsByCategory(enrichedData) const highlights = getCategoryPageHighlights(highlightsByCategory, category) - // Helper to build app modal link with preserved tag param - const buildAppLink = (appId: string) => { - const params = new URLSearchParams() - params.set("appId", appId) - if (validTag) { - params.set("tag", validTag) - } - return `?${params.toString()}` - } - // Get contributor info for JSON-LD const commitHistoryCache: CommitHistory = {} const { contributors } = await getAppPageContributorInfo( @@ -135,52 +98,11 @@ const Page = async ({ {t("page-developers-apps-applications-title")}

- - -
- {categoryData.map((app) => ( - - -
- {app.thumbnail_url ? ( - - ) : ( - - )} -
-
-

{app.name}

- - t(`page-developers-apps-tag-${tag}`) - )} - variant="light" - className="lowercase" - /> -
-
-
- ))} -
diff --git a/app/[locale]/developers/apps/_components/CategoryAppsGrid.tsx b/app/[locale]/developers/apps/_components/CategoryAppsGrid.tsx new file mode 100644 index 00000000000..968dc65b39e --- /dev/null +++ b/app/[locale]/developers/apps/_components/CategoryAppsGrid.tsx @@ -0,0 +1,84 @@ +"use client" + +import { useMemo, useState } from "react" +import { AppWindowMac } from "lucide-react" +import Image from "next/image" + +import FilterBar from "@/components/FilterBar" +import { LinkBox, LinkOverlay } from "@/components/ui/link-box" +import { TagsInlineText } from "@/components/ui/tag" + +import type { DeveloperApp } from "../types" + +type CategoryAppsGridProps = { + apps: DeveloperApp[] + uniqueTags: string[] + tagLabels: Record +} + +export default function CategoryAppsGrid({ + apps, + uniqueTags, + tagLabels, +}: CategoryAppsGridProps) { + const [selectedTag, setSelectedTag] = useState() + + const filteredApps = useMemo( + () => + selectedTag ? apps.filter((app) => app.tags.includes(selectedTag)) : apps, + [apps, selectedTag] + ) + + const filterItems = uniqueTags.map((tag) => ({ + value: tag, + label: tagLabels[tag], + })) + + return ( + <> + + +
+ {filteredApps.map((app) => ( + + +
+ {app.thumbnail_url ? ( + + ) : ( + + )} +
+
+

{app.name}

+ tagLabels[tag])} + variant="light" + className="lowercase" + /> +
+
+
+ ))} +
+ + ) +} diff --git a/app/[locale]/developers/apps/_components/TagFilter.tsx b/app/[locale]/developers/apps/_components/TagFilter.tsx deleted file mode 100644 index ba63e75cfe1..00000000000 --- a/app/[locale]/developers/apps/_components/TagFilter.tsx +++ /dev/null @@ -1,125 +0,0 @@ -"use client" - -import { useState } from "react" -import { ChevronDown, X } from "lucide-react" -import { useRouter, useSearchParams } from "next/navigation" - -import { Button } from "@/components/ui/buttons/Button" -import { - Command, - CommandEmpty, - CommandInput, - CommandItem, - CommandList, -} from "@/components/ui/command" -import { - Popover, - PopoverContent, - PopoverTrigger, -} from "@/components/ui/popover" - -type TagFilterProps = { - tags: string[] - tagLabels: Record - selectedTag?: string - category: string - count: number - labels: { - filterBy: string - clearFilter: string - noTags: string - showing: string - } -} - -export default function TagFilter({ - tags, - tagLabels, - selectedTag, - category, - count, - labels, -}: TagFilterProps) { - const router = useRouter() - const searchParams = useSearchParams() - const [open, setOpen] = useState(false) - - const handleSelectTag = (tag: string) => { - const params = new URLSearchParams(searchParams.toString()) - params.set("tag", tag) - router.push(`/developers/apps/${category}?${params.toString()}`, { - scroll: false, - }) - setOpen(false) - } - - const handleClearTag = () => { - const params = new URLSearchParams(searchParams.toString()) - params.delete("tag") - const queryString = params.toString() - router.push( - `/developers/apps/${category}${queryString ? `?${queryString}` : ""}`, - { scroll: false } - ) - } - - const COMBOBOX_ID = "tag-filter-listbox" - - return ( -
-
- - - - - - - - - {labels.noTags} - {tags.map((tag) => ( - handleSelectTag(tag)} - > - {tagLabels[tag]} - - ))} - - - - - - {selectedTag && ( - - )} -
- -

- {labels.showing} ({count}) -

-
- ) -} diff --git a/src/components/FilterBar/index.tsx b/src/components/FilterBar/index.tsx index a6b6751af66..02963b97f4b 100644 --- a/src/components/FilterBar/index.tsx +++ b/src/components/FilterBar/index.tsx @@ -128,8 +128,8 @@ export default function FilterBar({ {value && (
@@ -128,7 +131,7 @@ const Page = async ({ name={app.name} thumbnail={app.thumbnail_url} tags={app.tags.map((tag) => - t(`page-developers-apps-tag-${tag}`) + t(`page-developers-tools-tag-${tag}`) )} href={`?appId=${app.id}`} layout="horizontal" @@ -143,14 +146,14 @@ const Page = async ({
-

{t("page-developers-apps-categories-title")}

+

{t("page-developers-tools-categories-title")}

{DEV_APP_CATEGORIES.map(({ slug, Icon }) => ( } href={`/developers/apps/${slug}`} @@ -173,13 +176,16 @@ export async function generateMetadata({ params: { locale: string } }) { const { locale } = params - const t = await getTranslations({ locale, namespace: "page-developers-apps" }) + const t = await getTranslations({ + locale, + namespace: "page-developers-tools", + }) return await getMetadata({ locale, - slug: ["developers", "apps"], - title: t("page-developers-apps-meta-title"), - description: t("page-developers-apps-meta-description"), + slug: ["developers", "tools"], + title: t("page-developers-tools-meta-title"), + description: t("page-developers-tools-meta-description"), }) } diff --git a/src/intl/en/page-developers-apps.json b/src/intl/en/page-developers-apps.json deleted file mode 100644 index d93f642bbc6..00000000000 --- a/src/intl/en/page-developers-apps.json +++ /dev/null @@ -1,139 +0,0 @@ -{ - "page-developers-apps-applications-title": "Applications", - "page-developers-apps-categories-title-other": "Other application categories", - "page-developers-apps-categories-title": "Application categories", - "page-developers-apps-category-analytics-breadcrumb": "Analytics", - "page-developers-apps-category-analytics-description": "Indexing, querying, analytics, and tracing tools for onchain data, execution, and network activity.", - "page-developers-apps-category-analytics-meta-description": "Ethereum data analytics tools for indexing querying tracing transactions and monitoring onchain activity and execution.", - "page-developers-apps-category-analytics-title": "Data, analytics & tracing", - "page-developers-apps-category-contracts-breadcrumb": "Contracts", - "page-developers-apps-category-contracts-description": "Frameworks and tools for writing, testing, deploying, and upgrading smart contracts.", - "page-developers-apps-category-contracts-meta-description": "Ethereum smart contract tools for writing testing deploying and optimizing Solidity and Vyper contracts with modern developer workflows.", - "page-developers-apps-category-contracts-title": "Smart contract development & toolchains", - "page-developers-apps-category-education-breadcrumb": "Education", - "page-developers-apps-category-education-description": "Learning materials, documentation, tutorials, and community platforms for Ethereum builders.", - "page-developers-apps-category-education-meta-description": "Ethereum learning resources including documentation tutorials guides and community tools for builders at all levels.", - "page-developers-apps-category-education-title": "Education & community resources", - "page-developers-apps-category-interoperability-breadcrumb": "Interoperability", - "page-developers-apps-category-interoperability-description": "Tools that enable messaging, asset transfers, and shared state across Ethereum mainnet, rollups, and other blockchains.", - "page-developers-apps-category-interoperability-meta-description": "Ethereum cross chain tools for bridges messaging asset transfers rollups and interoperability across blockchain networks.", - "page-developers-apps-category-interoperability-title": "Cross-chain & interoperability", - "page-developers-apps-category-sdks-breadcrumb": "SDKs", - "page-developers-apps-category-sdks-description": "Language specific libraries and SDKs for interacting with Ethereum nodes, contracts, and protocols.", - "page-developers-apps-category-sdks-meta-description": "Ethereum client libraries and SDKs for interacting with nodes smart contracts wallets and onchain data across multiple languages.", - "page-developers-apps-category-sdks-title": "Client libraries & SDKs (front-end)", - "page-developers-apps-category-security-breadcrumb": "Security", - "page-developers-apps-category-security-description": "Auditing, testing, fuzzing, and verification tools to improve smart contract safety and correctness.", - "page-developers-apps-category-security-meta-description": "Ethereum security tools for smart contract auditing fuzz testing formal verification and improving protocol safety and correctness.", - "page-developers-apps-category-security-title": "Security, testing & formal verification", - "page-developers-apps-category-transactions-breadcrumb": "Transactions", - "page-developers-apps-category-transactions-description": "Infrastructure for building, signing, sending, simulating, and managing Ethereum transactions and wallets.", - "page-developers-apps-category-transactions-meta-description": "Tools for building Ethereum wallets signing sending simulating and managing transactions with secure wallet infrastructure.", - "page-developers-apps-category-transactions-title": "Transaction & wallet infrastructure", - "page-developers-apps-filter-label": "Filter by", - "page-developers-apps-filter-clear": "Clear filter", - "page-developers-apps-filter-empty": "No apps match the selected filter", - "page-developers-apps-filter-no-tags": "No tags found", - "page-developers-apps-filter-showing": "Showing", - "page-developers-apps-highlights": "Highlights", - "page-developers-apps-meta-description": "Discover Ethereum developer tooling including smart contract frameworks SDKs security testing analytics and wallet infrastructure to build and scale web3 apps.", - "page-developers-apps-meta-title": "Developer builder tools", - "page-developers-apps-modal-links": "Links", - "page-developers-apps-modal-social": "Social", - "page-developers-apps-modal-website": "Website", - "page-developers-apps-see-all": "See all", - "page-developers-apps-stats-downloads": "Weekly downloads", - "page-developers-apps-stats-stargazers": "GitHub stars", - "page-developers-apps-subtitle": "Find the right tools faster and help elevate the builders who create the infrastructure our ecosystem relies on.", - "page-developers-apps-tag-abi-encoding": "ABI encoding", - "page-developers-apps-tag-account-abstraction": "Account abstraction", - "page-developers-apps-tag-analytics": "Analytics", - "page-developers-apps-tag-api": "API", - "page-developers-apps-tag-authentication": "Authentication", - "page-developers-apps-tag-block-explorer": "Block explorer", - "page-developers-apps-tag-bundler": "Bundler", - "page-developers-apps-tag-censorship-resistant": "Censorship resistant", - "page-developers-apps-tag-chains": "Chains", - "page-developers-apps-tag-cli": "CLI", - "page-developers-apps-tag-code-analysis": "Code analysis", - "page-developers-apps-tag-code-coverage": "Code coverage", - "page-developers-apps-tag-code-quality": "Code quality", - "page-developers-apps-tag-community-driven": "Community driven", - "page-developers-apps-tag-compiler": "Compiler", - "page-developers-apps-tag-continuous-integration": "Continuous integration", - "page-developers-apps-tag-contract-deployment": "Contract deployment", - "page-developers-apps-tag-contract-interaction": "Contract interaction", - "page-developers-apps-tag-contract-management": "Contract management", - "page-developers-apps-tag-contract-verification": "Contract verification", - "page-developers-apps-tag-cross-chain": "Cross-chain", - "page-developers-apps-tag-debugging-tools": "Debugging tools", - "page-developers-apps-tag-decentralized-governance": "Decentralized governance", - "page-developers-apps-tag-defi": "DeFi", - "page-developers-apps-tag-developer-experience": "Developer experience", - "page-developers-apps-tag-devops": "DevOps", - "page-developers-apps-tag-dex-aggregator": "DEX aggregator", - "page-developers-apps-tag-docker": "Docker", - "page-developers-apps-tag-education": "Education", - "page-developers-apps-tag-encryption": "Encryption", - "page-developers-apps-tag-erc721": "ERC-721", - "page-developers-apps-tag-event-logging": "Event logging", - "page-developers-apps-tag-farcaster": "Farcaster", - "page-developers-apps-tag-formal-verification": "Formal verification", - "page-developers-apps-tag-foundry": "Foundry", - "page-developers-apps-tag-frontend": "Frontend", - "page-developers-apps-tag-fuzz-testing": "Fuzz testing", - "page-developers-apps-tag-game-development": "Game development", - "page-developers-apps-tag-gas-efficient": "Gas efficient", - "page-developers-apps-tag-gas-optimization": "Gas optimization", - "page-developers-apps-tag-github-actions": "GitHub actions", - "page-developers-apps-tag-gossipsub": "GossipSub", - "page-developers-apps-tag-governance": "Governance", - "page-developers-apps-tag-hardhat": "Hardhat", - "page-developers-apps-tag-indexing": "Indexing", - "page-developers-apps-tag-interactive-tools": "Interactive tools", - "page-developers-apps-tag-json-rpc": "JSON-RPC", - "page-developers-apps-tag-layer-2": "Layer 2", - "page-developers-apps-tag-libp2p": "libp2p", - "page-developers-apps-tag-mcp-server": "MCP server", - "page-developers-apps-tag-merkle-trees": "Merkle trees", - "page-developers-apps-tag-modular-accounts": "Modular accounts", - "page-developers-apps-tag-multi-chain": "Multi-chain", - "page-developers-apps-tag-multicall": "Multicall", - "page-developers-apps-tag-natural-language-processing": "Natural language processing", - "page-developers-apps-tag-networking": "Networking", - "page-developers-apps-tag-nextjs": "Next.js", - "page-developers-apps-tag-peer-to-peer": "Peer-to-peer", - "page-developers-apps-tag-performance-optimization": "Performance optimization", - "page-developers-apps-tag-privacy-focused": "Privacy focused", - "page-developers-apps-tag-proxy-contracts": "Proxy contracts", - "page-developers-apps-tag-react-app": "React app", - "page-developers-apps-tag-react": "React", - "page-developers-apps-tag-real-time-data": "Real-time data", - "page-developers-apps-tag-runtime-verification": "Runtime verification", - "page-developers-apps-tag-scalability": "Scalability", - "page-developers-apps-tag-sdk": "SDK", - "page-developers-apps-tag-security": "Security", - "page-developers-apps-tag-solidity-development": "Solidity development", - "page-developers-apps-tag-solidity": "Solidity", - "page-developers-apps-tag-static-analysis": "Static analysis", - "page-developers-apps-tag-storage-layout": "Storage layout", - "page-developers-apps-tag-support": "Support", - "page-developers-apps-tag-symbolic-execution": "Symbolic execution", - "page-developers-apps-tag-tailwind-css": "TailwindCSS", - "page-developers-apps-tag-test-automation": "Test automation", - "page-developers-apps-tag-testing": "Testing", - "page-developers-apps-tag-transaction-decoding": "Transaction decoding", - "page-developers-apps-tag-transaction-management": "Transaction management", - "page-developers-apps-tag-transaction-optimization": "Transaction optimization", - "page-developers-apps-tag-transaction-signing": "Transaction signing", - "page-developers-apps-tag-truffle": "Truffle", - "page-developers-apps-tag-type-safe": "Type-safe", - "page-developers-apps-tag-upgradeable-contracts": "Upgradeable contracts", - "page-developers-apps-tag-user-experience": "User experience", - "page-developers-apps-tag-verification": "Verification", - "page-developers-apps-tag-visualization": "Visualization", - "page-developers-apps-tag-vscode-extension": "VSCode extension", - "page-developers-apps-tag-vyper": "Vyper", - "page-developers-apps-tag-wallet": "Wallet", - "page-developers-apps-title": "Builder tools" -} diff --git a/src/intl/en/page-developers-tools.json b/src/intl/en/page-developers-tools.json new file mode 100644 index 00000000000..d3abc5d01b2 --- /dev/null +++ b/src/intl/en/page-developers-tools.json @@ -0,0 +1,139 @@ +{ + "page-developers-tools-applications-title": "Applications", + "page-developers-tools-categories-title-other": "Other application categories", + "page-developers-tools-categories-title": "Application categories", + "page-developers-tools-category-analytics-breadcrumb": "Analytics", + "page-developers-tools-category-analytics-description": "Indexing, querying, analytics, and tracing tools for onchain data, execution, and network activity.", + "page-developers-tools-category-analytics-meta-description": "Ethereum data analytics tools for indexing querying tracing transactions and monitoring onchain activity and execution.", + "page-developers-tools-category-analytics-title": "Data, analytics & tracing", + "page-developers-tools-category-contracts-breadcrumb": "Contracts", + "page-developers-tools-category-contracts-description": "Frameworks and tools for writing, testing, deploying, and upgrading smart contracts.", + "page-developers-tools-category-contracts-meta-description": "Ethereum smart contract tools for writing testing deploying and optimizing Solidity and Vyper contracts with modern developer workflows.", + "page-developers-tools-category-contracts-title": "Smart contract development & toolchains", + "page-developers-tools-category-education-breadcrumb": "Education", + "page-developers-tools-category-education-description": "Learning materials, documentation, tutorials, and community platforms for Ethereum builders.", + "page-developers-tools-category-education-meta-description": "Ethereum learning resources including documentation tutorials guides and community tools for builders at all levels.", + "page-developers-tools-category-education-title": "Education & community resources", + "page-developers-tools-category-interoperability-breadcrumb": "Interoperability", + "page-developers-tools-category-interoperability-description": "Tools that enable messaging, asset transfers, and shared state across Ethereum mainnet, rollups, and other blockchains.", + "page-developers-tools-category-interoperability-meta-description": "Ethereum cross chain tools for bridges messaging asset transfers rollups and interoperability across blockchain networks.", + "page-developers-tools-category-interoperability-title": "Cross-chain & interoperability", + "page-developers-tools-category-sdks-breadcrumb": "SDKs", + "page-developers-tools-category-sdks-description": "Language specific libraries and SDKs for interacting with Ethereum nodes, contracts, and protocols.", + "page-developers-tools-category-sdks-meta-description": "Ethereum client libraries and SDKs for interacting with nodes smart contracts wallets and onchain data across multiple languages.", + "page-developers-tools-category-sdks-title": "Client libraries & SDKs (front-end)", + "page-developers-tools-category-security-breadcrumb": "Security", + "page-developers-tools-category-security-description": "Auditing, testing, fuzzing, and verification tools to improve smart contract safety and correctness.", + "page-developers-tools-category-security-meta-description": "Ethereum security tools for smart contract auditing fuzz testing formal verification and improving protocol safety and correctness.", + "page-developers-tools-category-security-title": "Security, testing & formal verification", + "page-developers-tools-category-transactions-breadcrumb": "Transactions", + "page-developers-tools-category-transactions-description": "Infrastructure for building, signing, sending, simulating, and managing Ethereum transactions and wallets.", + "page-developers-tools-category-transactions-meta-description": "Tools for building Ethereum wallets signing sending simulating and managing transactions with secure wallet infrastructure.", + "page-developers-tools-category-transactions-title": "Transaction & wallet infrastructure", + "page-developers-tools-filter-label": "Filter by", + "page-developers-tools-filter-clear": "Clear filter", + "page-developers-tools-filter-empty": "No apps match the selected filter", + "page-developers-tools-filter-no-tags": "No tags found", + "page-developers-tools-filter-showing": "Showing", + "page-developers-tools-highlights": "Highlights", + "page-developers-tools-meta-description": "Discover Ethereum developer tooling including smart contract frameworks SDKs security testing analytics and wallet infrastructure to build and scale web3 apps.", + "page-developers-tools-meta-title": "Developer builder tools", + "page-developers-tools-modal-links": "Links", + "page-developers-tools-modal-social": "Social", + "page-developers-tools-modal-website": "Website", + "page-developers-tools-see-all": "See all", + "page-developers-tools-stats-downloads": "Weekly downloads", + "page-developers-tools-stats-stargazers": "GitHub stars", + "page-developers-tools-subtitle": "Find the right tools faster and help elevate the builders who create the infrastructure our ecosystem relies on.", + "page-developers-tools-tag-abi-encoding": "ABI encoding", + "page-developers-tools-tag-account-abstraction": "Account abstraction", + "page-developers-tools-tag-analytics": "Analytics", + "page-developers-tools-tag-api": "API", + "page-developers-tools-tag-authentication": "Authentication", + "page-developers-tools-tag-block-explorer": "Block explorer", + "page-developers-tools-tag-bundler": "Bundler", + "page-developers-tools-tag-censorship-resistant": "Censorship resistant", + "page-developers-tools-tag-chains": "Chains", + "page-developers-tools-tag-cli": "CLI", + "page-developers-tools-tag-code-analysis": "Code analysis", + "page-developers-tools-tag-code-coverage": "Code coverage", + "page-developers-tools-tag-code-quality": "Code quality", + "page-developers-tools-tag-community-driven": "Community driven", + "page-developers-tools-tag-compiler": "Compiler", + "page-developers-tools-tag-continuous-integration": "Continuous integration", + "page-developers-tools-tag-contract-deployment": "Contract deployment", + "page-developers-tools-tag-contract-interaction": "Contract interaction", + "page-developers-tools-tag-contract-management": "Contract management", + "page-developers-tools-tag-contract-verification": "Contract verification", + "page-developers-tools-tag-cross-chain": "Cross-chain", + "page-developers-tools-tag-debugging-tools": "Debugging tools", + "page-developers-tools-tag-decentralized-governance": "Decentralized governance", + "page-developers-tools-tag-defi": "DeFi", + "page-developers-tools-tag-developer-experience": "Developer experience", + "page-developers-tools-tag-devops": "DevOps", + "page-developers-tools-tag-dex-aggregator": "DEX aggregator", + "page-developers-tools-tag-docker": "Docker", + "page-developers-tools-tag-education": "Education", + "page-developers-tools-tag-encryption": "Encryption", + "page-developers-tools-tag-erc721": "ERC-721", + "page-developers-tools-tag-event-logging": "Event logging", + "page-developers-tools-tag-farcaster": "Farcaster", + "page-developers-tools-tag-formal-verification": "Formal verification", + "page-developers-tools-tag-foundry": "Foundry", + "page-developers-tools-tag-frontend": "Frontend", + "page-developers-tools-tag-fuzz-testing": "Fuzz testing", + "page-developers-tools-tag-game-development": "Game development", + "page-developers-tools-tag-gas-efficient": "Gas efficient", + "page-developers-tools-tag-gas-optimization": "Gas optimization", + "page-developers-tools-tag-github-actions": "GitHub actions", + "page-developers-tools-tag-gossipsub": "GossipSub", + "page-developers-tools-tag-governance": "Governance", + "page-developers-tools-tag-hardhat": "Hardhat", + "page-developers-tools-tag-indexing": "Indexing", + "page-developers-tools-tag-interactive-tools": "Interactive tools", + "page-developers-tools-tag-json-rpc": "JSON-RPC", + "page-developers-tools-tag-layer-2": "Layer 2", + "page-developers-tools-tag-libp2p": "libp2p", + "page-developers-tools-tag-mcp-server": "MCP server", + "page-developers-tools-tag-merkle-trees": "Merkle trees", + "page-developers-tools-tag-modular-accounts": "Modular accounts", + "page-developers-tools-tag-multi-chain": "Multi-chain", + "page-developers-tools-tag-multicall": "Multicall", + "page-developers-tools-tag-natural-language-processing": "Natural language processing", + "page-developers-tools-tag-networking": "Networking", + "page-developers-tools-tag-nextjs": "Next.js", + "page-developers-tools-tag-peer-to-peer": "Peer-to-peer", + "page-developers-tools-tag-performance-optimization": "Performance optimization", + "page-developers-tools-tag-privacy-focused": "Privacy focused", + "page-developers-tools-tag-proxy-contracts": "Proxy contracts", + "page-developers-tools-tag-react-app": "React app", + "page-developers-tools-tag-react": "React", + "page-developers-tools-tag-real-time-data": "Real-time data", + "page-developers-tools-tag-runtime-verification": "Runtime verification", + "page-developers-tools-tag-scalability": "Scalability", + "page-developers-tools-tag-sdk": "SDK", + "page-developers-tools-tag-security": "Security", + "page-developers-tools-tag-solidity-development": "Solidity development", + "page-developers-tools-tag-solidity": "Solidity", + "page-developers-tools-tag-static-analysis": "Static analysis", + "page-developers-tools-tag-storage-layout": "Storage layout", + "page-developers-tools-tag-support": "Support", + "page-developers-tools-tag-symbolic-execution": "Symbolic execution", + "page-developers-tools-tag-tailwind-css": "TailwindCSS", + "page-developers-tools-tag-test-automation": "Test automation", + "page-developers-tools-tag-testing": "Testing", + "page-developers-tools-tag-transaction-decoding": "Transaction decoding", + "page-developers-tools-tag-transaction-management": "Transaction management", + "page-developers-tools-tag-transaction-optimization": "Transaction optimization", + "page-developers-tools-tag-transaction-signing": "Transaction signing", + "page-developers-tools-tag-truffle": "Truffle", + "page-developers-tools-tag-type-safe": "Type-safe", + "page-developers-tools-tag-upgradeable-contracts": "Upgradeable contracts", + "page-developers-tools-tag-user-experience": "User experience", + "page-developers-tools-tag-verification": "Verification", + "page-developers-tools-tag-visualization": "Visualization", + "page-developers-tools-tag-vscode-extension": "VSCode extension", + "page-developers-tools-tag-vyper": "Vyper", + "page-developers-tools-tag-wallet": "Wallet", + "page-developers-tools-title": "Builder tools" +} From b4e5a13d13fbd4f912acb557921086f3d42404b6 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 3 Feb 2026 15:57:15 -0500 Subject: [PATCH 68/74] refactor: dev "apps" to "tools" --- .../developers/{apps => tools}/[category]/page-jsonld.tsx | 4 ++-- .../developers/{apps => tools}/[category]/page.tsx | 6 +++--- .../{apps => tools}/_components/AppModalContents.tsx | 0 .../{apps => tools}/_components/AppModalWrapper.tsx | 0 .../{apps => tools}/_components/CategoryAppsGrid.tsx | 0 .../{apps => tools}/_components/HighlightsSection.tsx | 0 app/[locale]/developers/{apps => tools}/constants.ts | 0 app/[locale]/developers/{apps => tools}/page-jsonld.tsx | 4 ++-- app/[locale]/developers/{apps => tools}/page.tsx | 8 ++++---- app/[locale]/developers/{apps => tools}/types.ts | 0 app/[locale]/developers/{apps => tools}/utils.ts | 0 src/components/AppCard/AppCard.stories.tsx | 2 +- src/components/Footer.tsx | 4 ++-- src/data-layer/fetchers/developer-tools/utils.ts | 4 ++-- src/lib/nav/buildNavigation.ts | 4 ++-- src/lib/types.ts | 2 +- 16 files changed, 19 insertions(+), 19 deletions(-) rename app/[locale]/developers/{apps => tools}/[category]/page-jsonld.tsx (95%) rename app/[locale]/developers/{apps => tools}/[category]/page.tsx (97%) rename app/[locale]/developers/{apps => tools}/_components/AppModalContents.tsx (100%) rename app/[locale]/developers/{apps => tools}/_components/AppModalWrapper.tsx (100%) rename app/[locale]/developers/{apps => tools}/_components/CategoryAppsGrid.tsx (100%) rename app/[locale]/developers/{apps => tools}/_components/HighlightsSection.tsx (100%) rename app/[locale]/developers/{apps => tools}/constants.ts (100%) rename app/[locale]/developers/{apps => tools}/page-jsonld.tsx (96%) rename app/[locale]/developers/{apps => tools}/page.tsx (97%) rename app/[locale]/developers/{apps => tools}/types.ts (100%) rename app/[locale]/developers/{apps => tools}/utils.ts (100%) diff --git a/app/[locale]/developers/apps/[category]/page-jsonld.tsx b/app/[locale]/developers/tools/[category]/page-jsonld.tsx similarity index 95% rename from app/[locale]/developers/apps/[category]/page-jsonld.tsx rename to app/[locale]/developers/tools/[category]/page-jsonld.tsx index 54f0570f6a8..203c225bca6 100644 --- a/app/[locale]/developers/apps/[category]/page-jsonld.tsx +++ b/app/[locale]/developers/tools/[category]/page-jsonld.tsx @@ -25,7 +25,7 @@ export default async function DevelopersAppsCategoryJsonLD({ }) { const t = await getTranslations({ namespace: "page-developers-tools" }) - const url = normalizeUrlForJsonLd(locale, `/developers/apps/${category}`) + const url = normalizeUrlForJsonLd(locale, `/developers/tools/${category}`) const contributorList = contributors.map((contributor) => ({ "@type": "Person", @@ -72,7 +72,7 @@ export default async function DevelopersAppsCategoryJsonLD({ "@type": "ListItem", position: 3, name: t("page-developers-tools-meta-title"), - item: normalizeUrlForJsonLd(locale, "/developers/apps/"), + item: normalizeUrlForJsonLd(locale, "/developers/tools/"), }, { "@type": "ListItem", diff --git a/app/[locale]/developers/apps/[category]/page.tsx b/app/[locale]/developers/tools/[category]/page.tsx similarity index 97% rename from app/[locale]/developers/apps/[category]/page.tsx rename to app/[locale]/developers/tools/[category]/page.tsx index 48c5ec2cfe7..fb0b93bd96a 100644 --- a/app/[locale]/developers/apps/[category]/page.tsx +++ b/app/[locale]/developers/tools/[category]/page.tsx @@ -58,7 +58,7 @@ const Page = async ({ // Clean up invalid appId by redirecting if (appId && !activeApp) { - redirect(`/developers/apps/${category}`) + redirect(`/developers/tools/${category}`) } // Prepare tag labels for client component @@ -74,7 +74,7 @@ const Page = async ({ // Get contributor info for JSON-LD const commitHistoryCache: CommitHistory = {} const { contributors } = await getAppPageContributorInfo( - `developers/apps/${category}`, + `developers/tools/${category}`, locale as Lang, commitHistoryCache ) @@ -124,7 +124,7 @@ const Page = async ({ `page-developers-tools-category-${slug}-description` )} icon={} - href={`/developers/apps/${slug}`} + href={`/developers/tools/${slug}`} /> ) )} diff --git a/app/[locale]/developers/apps/_components/AppModalContents.tsx b/app/[locale]/developers/tools/_components/AppModalContents.tsx similarity index 100% rename from app/[locale]/developers/apps/_components/AppModalContents.tsx rename to app/[locale]/developers/tools/_components/AppModalContents.tsx diff --git a/app/[locale]/developers/apps/_components/AppModalWrapper.tsx b/app/[locale]/developers/tools/_components/AppModalWrapper.tsx similarity index 100% rename from app/[locale]/developers/apps/_components/AppModalWrapper.tsx rename to app/[locale]/developers/tools/_components/AppModalWrapper.tsx diff --git a/app/[locale]/developers/apps/_components/CategoryAppsGrid.tsx b/app/[locale]/developers/tools/_components/CategoryAppsGrid.tsx similarity index 100% rename from app/[locale]/developers/apps/_components/CategoryAppsGrid.tsx rename to app/[locale]/developers/tools/_components/CategoryAppsGrid.tsx diff --git a/app/[locale]/developers/apps/_components/HighlightsSection.tsx b/app/[locale]/developers/tools/_components/HighlightsSection.tsx similarity index 100% rename from app/[locale]/developers/apps/_components/HighlightsSection.tsx rename to app/[locale]/developers/tools/_components/HighlightsSection.tsx diff --git a/app/[locale]/developers/apps/constants.ts b/app/[locale]/developers/tools/constants.ts similarity index 100% rename from app/[locale]/developers/apps/constants.ts rename to app/[locale]/developers/tools/constants.ts diff --git a/app/[locale]/developers/apps/page-jsonld.tsx b/app/[locale]/developers/tools/page-jsonld.tsx similarity index 96% rename from app/[locale]/developers/apps/page-jsonld.tsx rename to app/[locale]/developers/tools/page-jsonld.tsx index d43cdc5a608..47b51cd8d3d 100644 --- a/app/[locale]/developers/apps/page-jsonld.tsx +++ b/app/[locale]/developers/tools/page-jsonld.tsx @@ -21,7 +21,7 @@ export default async function DevelopersAppsJsonLD({ }) { const t = await getTranslations({ namespace: "page-developers-tools" }) - const url = normalizeUrlForJsonLd(locale, "/developers/apps/") + const url = normalizeUrlForJsonLd(locale, "/developers/tools/") const contributorList = contributors.map((contributor) => ({ "@type": "Person", @@ -90,7 +90,7 @@ export default async function DevelopersAppsJsonLD({ ), url: normalizeUrlForJsonLd( locale, - `/developers/apps/${category.slug}` + `/developers/tools/${category.slug}` ), })), }, diff --git a/app/[locale]/developers/apps/page.tsx b/app/[locale]/developers/tools/page.tsx similarity index 97% rename from app/[locale]/developers/apps/page.tsx rename to app/[locale]/developers/tools/page.tsx index 8334be65f10..91ed9412dfa 100644 --- a/app/[locale]/developers/apps/page.tsx +++ b/app/[locale]/developers/tools/page.tsx @@ -53,7 +53,7 @@ const Page = async ({ // Clean up invalid appId by redirecting if (appId && !activeApp) { - redirect("/developers/apps") + redirect("/developers/tools") } // Resolve highlight IDs to full app objects @@ -74,7 +74,7 @@ const Page = async ({ // Get contributor info for JSON-LD const commitHistoryCache: CommitHistory = {} const { contributors } = await getAppPageContributorInfo( - "developers/apps", + "developers/tools", locale as Lang, commitHistoryCache ) @@ -103,7 +103,7 @@ const Page = async ({
@@ -156,7 +156,7 @@ const Page = async ({ `page-developers-tools-category-${slug}-description` )} icon={} - href={`/developers/apps/${slug}`} + href={`/developers/tools/${slug}`} /> ))}
diff --git a/app/[locale]/developers/apps/types.ts b/app/[locale]/developers/tools/types.ts similarity index 100% rename from app/[locale]/developers/apps/types.ts rename to app/[locale]/developers/tools/types.ts diff --git a/app/[locale]/developers/apps/utils.ts b/app/[locale]/developers/tools/utils.ts similarity index 100% rename from app/[locale]/developers/apps/utils.ts rename to app/[locale]/developers/tools/utils.ts diff --git a/src/components/AppCard/AppCard.stories.tsx b/src/components/AppCard/AppCard.stories.tsx index e8b44c9bdd8..abacca8c690 100644 --- a/src/components/AppCard/AppCard.stories.tsx +++ b/src/components/AppCard/AppCard.stories.tsx @@ -236,7 +236,7 @@ export const DeveloperAppsPageStyle = { render: () => (

- As used on /developers/apps page (horizontal, no category, no tracking) + As used on /developers/tools page (horizontal, no category, no tracking)

{ text: t("documentation"), }, { - href: "/developers/apps/", + href: "/developers/tools/", text: t("start-building"), }, { - href: "/developers/apps/education/", + href: "/developers/tools/education/", text: t("learn-ethereum-development"), }, { diff --git a/src/data-layer/fetchers/developer-tools/utils.ts b/src/data-layer/fetchers/developer-tools/utils.ts index 28ddb652237..1318912ace1 100644 --- a/src/data-layer/fetchers/developer-tools/utils.ts +++ b/src/data-layer/fetchers/developer-tools/utils.ts @@ -2,7 +2,7 @@ import { getDayOfYear, getWeekNumber } from "@/lib/utils/date" // Import the base DeveloperApp type from app code (type-only import) // This is acceptable as it's a shared data contract, not a presentation dependency -import type { DeveloperApp } from "../../../../app/[locale]/developers/apps/types" +import type { DeveloperApp } from "../../../../app/[locale]/developers/tools/types" // Re-export for convenience export type { DeveloperApp } @@ -244,7 +244,7 @@ export function getHighlightsByCategory( } /** - * Get highlights for main /developers/apps page. + * Get highlights for main /developers/tools page. * Returns top app from top 3 randomly-ordered categories. * * @returns Array of 3 apps (one from each of top 3 categories) diff --git a/src/lib/nav/buildNavigation.ts b/src/lib/nav/buildNavigation.ts index 8cd41a418d9..c1279bd4e53 100644 --- a/src/lib/nav/buildNavigation.ts +++ b/src/lib/nav/buildNavigation.ts @@ -312,12 +312,12 @@ export const buildNavigation = (t: TranslateFn): NavSections => { { label: t("start-building"), description: t("nav-start-building-description"), - href: "/developers/apps/", + href: "/developers/tools/", }, { label: t("learn-ethereum-development"), description: t("nav-learn-ethereum-development-description"), - href: "/developers/apps/education/", + href: "/developers/tools/education/", }, { label: t("tutorials"), diff --git a/src/lib/types.ts b/src/lib/types.ts index 123da13e86d..6ceac4c634d 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -27,7 +27,7 @@ import allQuestionData from "@/data/quizzes/questionBank" import { DeveloperAppCategory, DeveloperAppTag, -} from "../../app/[locale]/developers/apps/types" +} from "../../app/[locale]/developers/tools/types" import { screens } from "./utils/screen" import { WALLETS_FILTERS_DEFAULT } from "./constants" From 23207e02ba023f000ff0f35f6fbc361ec1b8a19b Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 3 Feb 2026 16:15:42 -0500 Subject: [PATCH 69/74] refactor(code): dev "app(s)" -> "tool(s)" --- .../tools/[category]/page-jsonld.tsx | 24 +-- .../developers/tools/[category]/page.tsx | 66 +++---- .../tools/_components/CategoryAppsGrid.tsx | 60 ------- .../tools/_components/CategoryToolsGrid.tsx | 62 +++++++ .../tools/_components/HighlightsSection.tsx | 32 ++-- ...odalContents.tsx => ToolModalContents.tsx} | 34 ++-- ...pModalWrapper.tsx => ToolModalWrapper.tsx} | 8 +- app/[locale]/developers/tools/constants.ts | 26 +-- app/[locale]/developers/tools/page-jsonld.tsx | 12 +- app/[locale]/developers/tools/page.tsx | 46 ++--- app/[locale]/developers/tools/types.ts | 20 +-- app/[locale]/developers/tools/utils.ts | 8 +- .../developer-tools/fetchBuidlGuidl.ts | 6 +- .../fetchers/developer-tools/fetchGitHub.ts | 8 +- .../fetchers/developer-tools/fetchNpmJs.ts | 6 +- .../fetchers/developer-tools/index.ts | 38 ++-- .../fetchers/developer-tools/utils.ts | 162 +++++++++--------- src/data-layer/index.ts | 2 +- .../mocks/fetch-developer-tools.json | 2 +- src/data-layer/tasks.ts | 4 +- src/lib/types.ts | 10 +- 21 files changed, 322 insertions(+), 314 deletions(-) delete mode 100644 app/[locale]/developers/tools/_components/CategoryAppsGrid.tsx create mode 100644 app/[locale]/developers/tools/_components/CategoryToolsGrid.tsx rename app/[locale]/developers/tools/_components/{AppModalContents.tsx => ToolModalContents.tsx} (86%) rename app/[locale]/developers/tools/_components/{AppModalWrapper.tsx => ToolModalWrapper.tsx} (86%) diff --git a/app/[locale]/developers/tools/[category]/page-jsonld.tsx b/app/[locale]/developers/tools/[category]/page-jsonld.tsx index 203c225bca6..5fbc34f9cec 100644 --- a/app/[locale]/developers/tools/[category]/page-jsonld.tsx +++ b/app/[locale]/developers/tools/[category]/page-jsonld.tsx @@ -10,17 +10,17 @@ import { } from "@/lib/utils/jsonld" import { normalizeUrlForJsonLd } from "@/lib/utils/url" -import type { DeveloperApp, DeveloperAppCategorySlug } from "../types" +import type { DeveloperTool, DeveloperToolCategorySlug } from "../types" -export default async function DevelopersAppsCategoryJsonLD({ +export default async function DevelopersToolsCategoryJsonLD({ locale, category, - categoryApps, + categoryTools, contributors, }: { locale: string - category: DeveloperAppCategorySlug - categoryApps: DeveloperApp[] + category: DeveloperToolCategorySlug + categoryTools: DeveloperTool[] contributors: FileContributor[] }) { const t = await getTranslations({ namespace: "page-developers-tools" }) @@ -84,23 +84,23 @@ export default async function DevelopersAppsCategoryJsonLD({ }, publisher: ethereumFoundationOrganization, reviewedBy: ethereumFoundationOrganization, - mainEntity: { "@id": `${url}#category-apps` }, + mainEntity: { "@id": `${url}#category-tools` }, }, { "@type": "ItemList", - "@id": `${url}#category-apps`, + "@id": `${url}#category-tools`, name: t(`page-developers-tools-category-${category}-title`), description: t( `page-developers-tools-category-${category}-description` ), url: url, - numberOfItems: categoryApps.length, - itemListElement: categoryApps.slice(0, 10).map((app, index) => ({ + numberOfItems: categoryTools.length, + itemListElement: categoryTools.slice(0, 10).map((tool, index) => ({ "@type": "ListItem", position: index + 1, - name: app.name, - description: app.description, - url: app.website, + name: tool.name, + description: tool.description, + url: tool.website, })), }, ], diff --git a/app/[locale]/developers/tools/[category]/page.tsx b/app/[locale]/developers/tools/[category]/page.tsx index fb0b93bd96a..9620caa059d 100644 --- a/app/[locale]/developers/tools/[category]/page.tsx +++ b/app/[locale]/developers/tools/[category]/page.tsx @@ -11,14 +11,14 @@ import { Section } from "@/components/ui/section" import { getAppPageContributorInfo } from "@/lib/utils/contributors" import { getMetadata } from "@/lib/utils/metadata" -import AppModalContents from "../_components/AppModalContents" -import AppModalWrapper from "../_components/AppModalWrapper" -import CategoryAppsGrid from "../_components/CategoryAppsGrid" +import CategoryToolsGrid from "../_components/CategoryToolsGrid" import HighlightsSection from "../_components/HighlightsSection" -import { DEV_APP_CATEGORIES, DEV_APP_CATEGORY_SLUGS } from "../constants" -import type { DeveloperAppCategorySlug, DeveloperAppTag } from "../types" +import ToolModalContents from "../_components/ToolModalContents" +import ToolModalWrapper from "../_components/ToolModalWrapper" +import { DEV_TOOL_CATEGORIES, DEV_TOOL_CATEGORY_SLUGS } from "../constants" +import type { DeveloperToolCategorySlug, DeveloperToolTag } from "../types" -import DevelopersAppsCategoryJsonLD from "./page-jsonld" +import DevelopersToolsCategoryJsonLD from "./page-jsonld" import { getDeveloperToolsData } from "@/lib/data" @@ -26,11 +26,11 @@ const Page = async ({ params, searchParams, }: { - params: PageParams & { category: DeveloperAppCategorySlug } - searchParams: { appId?: string } + params: PageParams & { category: DeveloperToolCategorySlug } + searchParams: { toolId?: string } }) => { const { locale, category } = params - const { appId } = searchParams + const { toolId } = searchParams setRequestLocale(locale) const t = await getTranslations({ @@ -39,36 +39,36 @@ const Page = async ({ }) const data = await getDeveloperToolsData() - if (!data) throw Error("No developer apps data available") + if (!data) throw Error("No developer tools data available") - const { appsById, selections } = data + const { toolsById, selections } = data - // Get all apps for this category (filter at runtime - trivial for few hundred apps) - const allApps = Object.values(appsById) - const allCategoryData = allApps.filter( - (app) => DEV_APP_CATEGORY_SLUGS[app.category] === category + // Get all tools for this category (filter at runtime - trivial for few hundred tools) + const allTools = Object.values(toolsById) + const allCategoryData = allTools.filter( + (tool) => DEV_TOOL_CATEGORY_SLUGS[tool.category] === category ) // Extract unique tags from current category const uniqueTags = Array.from( - new Set(allCategoryData.flatMap((app) => app.tags)) + new Set(allCategoryData.flatMap((tool) => tool.tags)) ).sort() - const activeApp = appId ? appsById[appId] : undefined + const activeTool = toolId ? toolsById[toolId] : undefined - // Clean up invalid appId by redirecting - if (appId && !activeApp) { + // Clean up invalid toolId by redirecting + if (toolId && !activeTool) { redirect(`/developers/tools/${category}`) } // Prepare tag labels for client component const tagLabels = Object.fromEntries( uniqueTags.map((tag) => [tag, t(`page-developers-tools-tag-${tag}`)]) - ) as Record + ) as Record - // Resolve category highlight IDs to full app objects + // Resolve category highlight IDs to full tool objects const highlights = (selections.categoryHighlights[category] || []) - .map((id) => appsById[id]) + .map((id) => toolsById[id]) .filter(Boolean) // Get contributor info for JSON-LD @@ -81,10 +81,10 @@ const Page = async ({ return ( <> - - + -
+

{t("page-developers-tools-applications-title")}

- @@ -115,7 +115,7 @@ const Page = async ({

{t("page-developers-tools-categories-title-other")}

- {DEV_APP_CATEGORIES.filter(({ slug }) => slug !== category).map( + {DEV_TOOL_CATEGORIES.filter(({ slug }) => slug !== category).map( ({ slug, Icon }) => ( - - {activeApp && } - + + {activeTool && } + ) } export async function generateStaticParams() { - return DEV_APP_CATEGORIES.map(({ slug }) => ({ category: slug })) + return DEV_TOOL_CATEGORIES.map(({ slug }) => ({ category: slug })) } export async function generateMetadata({ diff --git a/app/[locale]/developers/tools/_components/CategoryAppsGrid.tsx b/app/[locale]/developers/tools/_components/CategoryAppsGrid.tsx deleted file mode 100644 index 1e612c829ea..00000000000 --- a/app/[locale]/developers/tools/_components/CategoryAppsGrid.tsx +++ /dev/null @@ -1,60 +0,0 @@ -"use client" - -import { useMemo, useState } from "react" - -import AppCard from "@/components/AppCard" -import FilterBar from "@/components/FilterBar" - -import type { DeveloperApp, DeveloperAppTag } from "../types" - -type CategoryAppsGridProps = { - apps: DeveloperApp[] - uniqueTags: DeveloperAppTag[] - tagLabels: Record -} - -export default function CategoryAppsGrid({ - apps, - uniqueTags, - tagLabels, -}: CategoryAppsGridProps) { - const [selectedTag, setSelectedTag] = useState() - - const filteredApps = useMemo( - () => - selectedTag ? apps.filter((app) => app.tags.includes(selectedTag)) : apps, - [apps, selectedTag] - ) - - const filterItems = uniqueTags.map((tag) => ({ - value: tag, - label: tagLabels[tag], - })) - - return ( - <> - setSelectedTag(value as DeveloperAppTag)} - count={filteredApps.length} - totalCount={apps.length} - /> - -
- {filteredApps.map((app) => ( - tagLabels[tag])} - href={`?appId=${app.id}`} - layout="horizontal" - imageSize="thumbnail" - className="h-fit p-4" - /> - ))} -
- - ) -} diff --git a/app/[locale]/developers/tools/_components/CategoryToolsGrid.tsx b/app/[locale]/developers/tools/_components/CategoryToolsGrid.tsx new file mode 100644 index 00000000000..5c837da163f --- /dev/null +++ b/app/[locale]/developers/tools/_components/CategoryToolsGrid.tsx @@ -0,0 +1,62 @@ +"use client" + +import { useMemo, useState } from "react" + +import AppCard from "@/components/AppCard" +import FilterBar from "@/components/FilterBar" + +import type { DeveloperTool, DeveloperToolTag } from "../types" + +type CategoryToolsGridProps = { + tools: DeveloperTool[] + uniqueTags: DeveloperToolTag[] + tagLabels: Record +} + +export default function CategoryToolsGrid({ + tools, + uniqueTags, + tagLabels, +}: CategoryToolsGridProps) { + const [selectedTag, setSelectedTag] = useState() + + const filteredTools = useMemo( + () => + selectedTag + ? tools.filter((tool) => tool.tags.includes(selectedTag)) + : tools, + [tools, selectedTag] + ) + + const filterItems = uniqueTags.map((tag) => ({ + value: tag, + label: tagLabels[tag], + })) + + return ( + <> + setSelectedTag(value as DeveloperToolTag)} + count={filteredTools.length} + totalCount={tools.length} + /> + +
+ {filteredTools.map((tool) => ( + tagLabels[tag])} + href={`?toolId=${tool.id}`} + layout="horizontal" + imageSize="thumbnail" + className="h-fit p-4" + /> + ))} +
+ + ) +} diff --git a/app/[locale]/developers/tools/_components/HighlightsSection.tsx b/app/[locale]/developers/tools/_components/HighlightsSection.tsx index 6c5be90667a..2e429ff0a47 100644 --- a/app/[locale]/developers/tools/_components/HighlightsSection.tsx +++ b/app/[locale]/developers/tools/_components/HighlightsSection.tsx @@ -13,33 +13,33 @@ import { Section } from "@/components/ui/section" import { cn } from "@/lib/utils/cn" import { stripMarkdown } from "@/lib/utils/md" -import { DEV_APP_CATEGORY_SLUGS } from "../constants" -import type { DeveloperApp } from "../types" +import { DEV_TOOL_CATEGORY_SLUGS } from "../constants" +import type { DeveloperTool } from "../types" import { getCategoryTagStyle } from "../utils" -const HighlightsSection = async ({ apps }: { apps: DeveloperApp[] }) => { +const HighlightsSection = async ({ tools }: { tools: DeveloperTool[] }) => { const locale = await getLocale() const t = await getTranslations({ locale, namespace: "page-developers-tools", }) - // Don't render section if no apps to highlight - if (apps.length === 0) return null + // Don't render section if no tools to highlight + if (tools.length === 0) return null return (

{t("page-developers-tools-highlights")}

- {apps.map((app) => { - // Safety check - skip apps without required images - if (!app.banner_url || !app.thumbnail_url) return null + {tools.map((tool) => { + // Safety check - skip tools without required images + if (!tool.banner_url || !tool.thumbnail_url) return null - const categorySlug = DEV_APP_CATEGORY_SLUGS[app.category] + const categorySlug = DEV_TOOL_CATEGORY_SLUGS[tool.category] return ( @@ -50,14 +50,14 @@ const HighlightsSection = async ({ apps }: { apps: DeveloperApp[] }) => { )} >
{ /> - {stripMarkdown(app.description)} + {stripMarkdown(tool.description)}
+ tags={tool.tags.map((tag) => t(`page-developers-tools-tag-${tag}`) )} layout="horizontal" diff --git a/app/[locale]/developers/tools/_components/AppModalContents.tsx b/app/[locale]/developers/tools/_components/ToolModalContents.tsx similarity index 86% rename from app/[locale]/developers/tools/_components/AppModalContents.tsx rename to app/[locale]/developers/tools/_components/ToolModalContents.tsx index 5460ce414bc..9d654fee715 100644 --- a/app/[locale]/developers/tools/_components/AppModalContents.tsx +++ b/app/[locale]/developers/tools/_components/ToolModalContents.tsx @@ -12,13 +12,13 @@ import { Tag, TagsInlineText } from "@/components/ui/tag" import { formatDate, getValidDate } from "@/lib/utils/date" import { isExternal } from "@/lib/utils/url" -import { DEV_APP_CATEGORY_SLUGS } from "../constants" -import type { DeveloperApp } from "../types" +import { DEV_TOOL_CATEGORY_SLUGS } from "../constants" +import type { DeveloperTool } from "../types" import { getCategoryTagStyle } from "../utils" import { renderSimpleMarkdown } from "@/lib/md/renderSimple" -const AppModalContents = async ({ app }: { app: DeveloperApp }) => { +const ToolModalContents = async ({ tool }: { tool: DeveloperTool }) => { const locale = await getLocale() const t = await getTranslations({ locale, @@ -26,7 +26,7 @@ const AppModalContents = async ({ app }: { app: DeveloperApp }) => { }) const tCommon = await getTranslations({ locale, namespace: "common" }) - const categorySlug = DEV_APP_CATEGORY_SLUGS[app.category] + const categorySlug = DEV_TOOL_CATEGORY_SLUGS[tool.category] const BoldedParagraph = (props: { children?: React.ReactNode }) => ( @@ -45,9 +45,9 @@ const AppModalContents = async ({ app }: { app: DeveloperApp }) => { return (
- {app.banner_url && ( + {tool.banner_url && ( { status={getCategoryTagStyle(categorySlug)} className="px-1 py-0" > - {app.category} + {tool.category} -

{app.name}

+

{tool.name}

t(`page-developers-tools-tag-${tag}`))} + list={tool.tags.map((tag) => t(`page-developers-tools-tag-${tag}`))} variant="light" className="lowercase" />
- {await renderSimpleMarkdown(app.description, mdComponentOverrides)} + {await renderSimpleMarkdown(tool.description, mdComponentOverrides)}

{t("page-developers-tools-modal-links")}

- {app.website && ( - + {tool.website && ( + {t("page-developers-tools-modal-website")} )} - {app.twitter && ( + {tool.twitter && ( {t("page-developers-tools-modal-social")} )} - {app.repos + {tool.repos .filter(({ href }) => isExternal(href)) .map(({ href, stargazers, downloads, lastUpdated }) => { const isGitHub = href.includes("https://github.com") @@ -157,4 +157,4 @@ const AppModalContents = async ({ app }: { app: DeveloperApp }) => { ) } -export default AppModalContents +export default ToolModalContents diff --git a/app/[locale]/developers/tools/_components/AppModalWrapper.tsx b/app/[locale]/developers/tools/_components/ToolModalWrapper.tsx similarity index 86% rename from app/[locale]/developers/tools/_components/AppModalWrapper.tsx rename to app/[locale]/developers/tools/_components/ToolModalWrapper.tsx index cda36c19d32..a8e5601569a 100644 --- a/app/[locale]/developers/tools/_components/AppModalWrapper.tsx +++ b/app/[locale]/developers/tools/_components/ToolModalWrapper.tsx @@ -7,7 +7,7 @@ import { type ModalProps } from "@/components/ui/dialog-modal" import { cn } from "@/lib/utils/cn" -const AppModalWrapper = (props: ModalProps) => { +const ToolModalWrapper = (props: ModalProps) => { const router = useRouter() const pathname = usePathname() const searchParams = useSearchParams() @@ -17,9 +17,9 @@ const AppModalWrapper = (props: ModalProps) => { size="lg" onOpenChange={(open) => { if (open) return - // Remove only appId param, preserve others (like tag) + // Remove only toolId param, preserve others (like tag) const params = new URLSearchParams(searchParams.toString()) - params.delete("appId") + params.delete("toolId") const queryString = params.toString() router.replace(`${pathname}${queryString ? `?${queryString}` : ""}`, { scroll: false, @@ -38,4 +38,4 @@ const AppModalWrapper = (props: ModalProps) => { ) } -export default AppModalWrapper +export default ToolModalWrapper diff --git a/app/[locale]/developers/tools/constants.ts b/app/[locale]/developers/tools/constants.ts index 82526064b4b..6c8f82a2157 100644 --- a/app/[locale]/developers/tools/constants.ts +++ b/app/[locale]/developers/tools/constants.ts @@ -11,20 +11,22 @@ import { import { TagProps } from "@/components/ui/tag" -import type { DeveloperAppCategorySlug } from "./types" +import type { DeveloperToolCategorySlug } from "./types" -export const DEV_APP_CATEGORY_SLUGS: Record = - { - "Cross-Chain & Interoperability": "interoperability", - "Transaction & Wallet Infrastructure": "transactions", - "Data, Analytics & Tracing": "analytics", - "Education & Community Resources": "education", - "Client Libraries & SDKs (Front-End)": "sdks", - "Smart Contract Development & Toolchains": "contracts", - "Security, Testing & Formal Verification": "security", - } +export const DEV_TOOL_CATEGORY_SLUGS: Record< + string, + DeveloperToolCategorySlug +> = { + "Cross-Chain & Interoperability": "interoperability", + "Transaction & Wallet Infrastructure": "transactions", + "Data, Analytics & Tracing": "analytics", + "Education & Community Resources": "education", + "Client Libraries & SDKs (Front-End)": "sdks", + "Smart Contract Development & Toolchains": "contracts", + "Security, Testing & Formal Verification": "security", +} -export const DEV_APP_CATEGORIES = [ +export const DEV_TOOL_CATEGORIES = [ { slug: "interoperability", Icon: SendToBack, tag: "accent-a" }, { slug: "transactions", Icon: ArrowLeftRight, tag: "accent-b" }, { slug: "analytics", Icon: ChartSpline, tag: "accent-c" }, diff --git a/app/[locale]/developers/tools/page-jsonld.tsx b/app/[locale]/developers/tools/page-jsonld.tsx index 47b51cd8d3d..e7ca51efe74 100644 --- a/app/[locale]/developers/tools/page-jsonld.tsx +++ b/app/[locale]/developers/tools/page-jsonld.tsx @@ -10,9 +10,9 @@ import { } from "@/lib/utils/jsonld" import { normalizeUrlForJsonLd } from "@/lib/utils/url" -import { DEV_APP_CATEGORIES } from "./constants" +import { DEV_TOOL_CATEGORIES } from "./constants" -export default async function DevelopersAppsJsonLD({ +export default async function DevelopersToolsJsonLD({ locale, contributors, }: { @@ -72,16 +72,16 @@ export default async function DevelopersAppsJsonLD({ }, publisher: ethereumFoundationOrganization, reviewedBy: ethereumFoundationOrganization, - mainEntity: { "@id": `${url}#developer-apps` }, + mainEntity: { "@id": `${url}#developer-tools` }, }, { "@type": "ItemList", - "@id": `${url}#developer-apps`, + "@id": `${url}#developer-tools`, name: t("page-developers-tools-categories-title"), description: t("page-developers-tools-meta-description"), url: url, - numberOfItems: DEV_APP_CATEGORIES.length, - itemListElement: DEV_APP_CATEGORIES.map((category, index) => ({ + numberOfItems: DEV_TOOL_CATEGORIES.length, + itemListElement: DEV_TOOL_CATEGORIES.map((category, index) => ({ "@type": "ListItem", position: index + 1, name: t(`page-developers-tools-category-${category.slug}-title`), diff --git a/app/[locale]/developers/tools/page.tsx b/app/[locale]/developers/tools/page.tsx index 91ed9412dfa..922555b4ed9 100644 --- a/app/[locale]/developers/tools/page.tsx +++ b/app/[locale]/developers/tools/page.tsx @@ -19,12 +19,12 @@ import { Section } from "@/components/ui/section" import { getAppPageContributorInfo } from "@/lib/utils/contributors" import { getMetadata } from "@/lib/utils/metadata" -import AppModalContents from "./_components/AppModalContents" -import AppModalWrapper from "./_components/AppModalWrapper" import HighlightsSection from "./_components/HighlightsSection" -import { DEV_APP_CATEGORIES } from "./constants" -import DevelopersAppsJsonLD from "./page-jsonld" -import type { DeveloperAppsByCategory } from "./types" +import ToolModalContents from "./_components/ToolModalContents" +import ToolModalWrapper from "./_components/ToolModalWrapper" +import { DEV_TOOL_CATEGORIES } from "./constants" +import DevelopersToolsJsonLD from "./page-jsonld" +import type { DeveloperToolsByCategory } from "./types" import { getDeveloperToolsData } from "@/lib/data" @@ -33,10 +33,10 @@ const Page = async ({ searchParams, }: { params: PageParams - searchParams: { appId?: string } + searchParams: { toolId?: string } }) => { const { locale } = params - const { appId } = searchParams + const { toolId } = searchParams setRequestLocale(locale) const t = await getTranslations({ @@ -47,29 +47,29 @@ const Page = async ({ const data = await getDeveloperToolsData() if (!data) throw Error("No developer apps data available") - const { appsById, selections } = data + const { toolsById, selections } = data - const activeApp = appId ? appsById[appId] : undefined + const activeApp = toolId ? toolsById[toolId] : undefined - // Clean up invalid appId by redirecting - if (appId && !activeApp) { + // Clean up invalid toolId by redirecting + if (toolId && !activeApp) { redirect("/developers/tools") } // Resolve highlight IDs to full app objects const highlights = selections.mainPageHighlights - .map((id) => appsById[id]) + .map((id) => toolsById[id]) .filter(Boolean) // Resolve preview IDs per category const previewsByCategory = Object.fromEntries( - DEV_APP_CATEGORIES.map(({ slug }) => [ + DEV_TOOL_CATEGORIES.map(({ slug }) => [ slug, (selections.categoryPreviews[slug] || []) - .map((id) => appsById[id]) + .map((id) => toolsById[id]) .filter(Boolean), ]) - ) as DeveloperAppsByCategory + ) as DeveloperToolsByCategory // Get contributor info for JSON-LD const commitHistoryCache: CommitHistory = {} @@ -81,7 +81,7 @@ const Page = async ({ return ( <> - + - +

{t("page-developers-tools-applications-title")}

- {DEV_APP_CATEGORIES.map(({ slug, Icon }) => ( + {DEV_TOOL_CATEGORIES.map(({ slug, Icon }) => ( t(`page-developers-tools-tag-${tag}`) )} - href={`?appId=${app.id}`} + href={`?toolId=${app.id}`} layout="horizontal" imageSize="thumbnail" className="rounded-none border-t p-4" @@ -148,7 +148,7 @@ const Page = async ({

{t("page-developers-tools-categories-title")}

- {DEV_APP_CATEGORIES.map(({ slug, Icon }) => ( + {DEV_TOOL_CATEGORIES.map(({ slug, Icon }) => ( - - {activeApp && } - + + {activeApp && } + ) } diff --git a/app/[locale]/developers/tools/types.ts b/app/[locale]/developers/tools/types.ts index c11bc9ae332..8908f3d903b 100644 --- a/app/[locale]/developers/tools/types.ts +++ b/app/[locale]/developers/tools/types.ts @@ -1,8 +1,8 @@ -import { DeveloperAppsResponse } from "@/lib/types" +import { DeveloperToolsResponse } from "@/lib/types" -import { DEV_APP_CATEGORIES, DEV_APP_CATEGORY_SLUGS } from "./constants" +import { DEV_TOOL_CATEGORIES, DEV_TOOL_CATEGORY_SLUGS } from "./constants" -export type DeveloperAppTag = +export type DeveloperToolTag = | "abi-encoding" | "account-abstraction" | "analytics" @@ -94,12 +94,12 @@ export type DeveloperAppTag = | "vyper" | "wallet" -export type DeveloperAppCategory = keyof typeof DEV_APP_CATEGORY_SLUGS +export type DeveloperToolCategory = keyof typeof DEV_TOOL_CATEGORY_SLUGS -export type DeveloperAppCategorySlug = - (typeof DEV_APP_CATEGORIES)[number]["slug"] +export type DeveloperToolCategorySlug = + (typeof DEV_TOOL_CATEGORIES)[number]["slug"] -export type DeveloperApp = Omit & { +export type DeveloperTool = Omit & { repos: { href: string stargazers?: number @@ -108,7 +108,7 @@ export type DeveloperApp = Omit & { }[] } -export type DeveloperAppsByCategory = Record< - DeveloperAppCategorySlug, - DeveloperApp[] +export type DeveloperToolsByCategory = Record< + DeveloperToolCategorySlug, + DeveloperTool[] > diff --git a/app/[locale]/developers/tools/utils.ts b/app/[locale]/developers/tools/utils.ts index ecf9061ee05..773e7736298 100644 --- a/app/[locale]/developers/tools/utils.ts +++ b/app/[locale]/developers/tools/utils.ts @@ -1,7 +1,7 @@ import type { TagProps } from "@/components/ui/tag" -import { DEV_APP_CATEGORIES } from "./constants" -import type { DeveloperAppCategorySlug } from "./types" +import { DEV_TOOL_CATEGORIES } from "./constants" +import type { DeveloperToolCategorySlug } from "./types" /** * Gets the tag style for a developer app category based on its slug. @@ -10,6 +10,6 @@ import type { DeveloperAppCategorySlug } from "./types" * @returns The tag status style associated with the category, or "tag" as the default fallback */ export const getCategoryTagStyle = ( - categorySlug: DeveloperAppCategorySlug + categorySlug: DeveloperToolCategorySlug ): TagProps["status"] => - DEV_APP_CATEGORIES.find(({ slug }) => slug === categorySlug)?.tag || "tag" + DEV_TOOL_CATEGORIES.find(({ slug }) => slug === categorySlug)?.tag || "tag" diff --git a/src/data-layer/fetchers/developer-tools/fetchBuidlGuidl.ts b/src/data-layer/fetchers/developer-tools/fetchBuidlGuidl.ts index b47b16b939a..c1e1b8fc07a 100644 --- a/src/data-layer/fetchers/developer-tools/fetchBuidlGuidl.ts +++ b/src/data-layer/fetchers/developer-tools/fetchBuidlGuidl.ts @@ -1,6 +1,6 @@ -import { DeveloperAppsResponse } from "@/lib/types" +import { DeveloperToolsResponse } from "@/lib/types" -export async function fetchBuidlGuidl(): Promise { +export async function fetchBuidlGuidl(): Promise { const url = "https://raw.githubusercontent.com/BuidlGuidl/Developer-Tooling/refs/heads/main/output/results.json" @@ -15,7 +15,7 @@ export async function fetchBuidlGuidl(): Promise { throw new Error(error) } - const json: DeveloperAppsResponse[] = await response.json() + const json: DeveloperToolsResponse[] = await response.json() console.log("Successfully fetched BuidlGuidl developer tooling data") diff --git a/src/data-layer/fetchers/developer-tools/fetchGitHub.ts b/src/data-layer/fetchers/developer-tools/fetchGitHub.ts index b4b916464a4..32d105cc857 100644 --- a/src/data-layer/fetchers/developer-tools/fetchGitHub.ts +++ b/src/data-layer/fetchers/developer-tools/fetchGitHub.ts @@ -1,8 +1,8 @@ -import type { DeveloperAppsResponse } from "@/lib/types" +import type { DeveloperToolsResponse } from "@/lib/types" import { retry, sleep } from "@/lib/utils/fetch" -import type { DeveloperApp } from "./utils" +import type { DeveloperTool } from "./utils" type RepoInfo = { owner: string @@ -101,8 +101,8 @@ async function fetchReposBatch( } export async function fetchGitHub( - appData: DeveloperAppsResponse[] -): Promise { + appData: DeveloperToolsResponse[] +): Promise { // Collect all unique repo URLs const allRepos: RepoInfo[] = [] const seenHrefs = new Set() diff --git a/src/data-layer/fetchers/developer-tools/fetchNpmJs.ts b/src/data-layer/fetchers/developer-tools/fetchNpmJs.ts index e75a913bce3..78e096178f5 100644 --- a/src/data-layer/fetchers/developer-tools/fetchNpmJs.ts +++ b/src/data-layer/fetchers/developer-tools/fetchNpmJs.ts @@ -1,6 +1,6 @@ import { retry, sleep } from "@/lib/utils/fetch" -import type { DeveloperApp } from "./utils" +import type { DeveloperTool } from "./utils" type ParsedNpmUrl = { packageName: string @@ -138,8 +138,8 @@ async function fetchBulkDownloads( } export async function fetchNpmJs( - appData: DeveloperApp[] -): Promise { + appData: DeveloperTool[] +): Promise { // Collect all unique npm URLs and their package names const parsedUrls: ParsedNpmUrl[] = [] const seenHrefs = new Set() diff --git a/src/data-layer/fetchers/developer-tools/index.ts b/src/data-layer/fetchers/developer-tools/index.ts index 40583ce5f1b..a91e93a065d 100644 --- a/src/data-layer/fetchers/developer-tools/index.ts +++ b/src/data-layer/fetchers/developer-tools/index.ts @@ -2,15 +2,15 @@ import { fetchBuidlGuidl } from "./fetchBuidlGuidl" import { fetchGitHub } from "./fetchGitHub" import { fetchNpmJs } from "./fetchNpmJs" import type { - DeveloperApp, - DeveloperAppsComputedSelections, + DeveloperTool, + DeveloperToolsComputedSelections, DeveloperToolsDataEnvelope, } from "./utils" import { getHighlightsByCategory, getMainPageHighlights, getRandomPreviewsByCategory, - transformDeveloperAppsData, + transformDeveloperToolsData, } from "./utils" // Re-export types for consumers @@ -25,9 +25,9 @@ export type { DeveloperToolsDataEnvelope } from "./utils" * 3. npm API (download counts) * * Also computes randomized selections for highlights and previews, - * ensuring all users see the same apps until the next daily sync. + * ensuring all users see the same tools until the next daily sync. * - * Returns envelope with appsById lookup and pre-computed selections. + * Returns envelope with toolsById lookup and pre-computed selections. */ export async function fetchDeveloperTools(): Promise { console.log("Starting developer tools data enrichment pipeline") @@ -45,31 +45,33 @@ export async function fetchDeveloperTools(): Promise console.log("Enriched with npm data") // Step 4: Build lookup map - const appsById: Record = Object.fromEntries( - enrichedData.map((app) => [app.id, app]) + const toolsById: Record = Object.fromEntries( + enrichedData.map((tool) => [tool.id, tool]) + ) + console.log( + `Built toolsById lookup with ${Object.keys(toolsById).length} tools` ) - console.log(`Built appsById lookup with ${Object.keys(appsById).length} apps`) // Step 5: Compute randomized selections const highlightsByCategory = getHighlightsByCategory(enrichedData) const mainPageHighlights = getMainPageHighlights(highlightsByCategory) - const dataByCategory = transformDeveloperAppsData(enrichedData) + const dataByCategory = transformDeveloperToolsData(enrichedData) const categoryPreviews = getRandomPreviewsByCategory(dataByCategory) - const selections: DeveloperAppsComputedSelections = { - mainPageHighlights: mainPageHighlights.map((app) => app.id), + const selections: DeveloperToolsComputedSelections = { + mainPageHighlights: mainPageHighlights.map((tool) => tool.id), categoryHighlights: Object.fromEntries( - Object.entries(highlightsByCategory).map(([cat, apps]) => [ + Object.entries(highlightsByCategory).map(([cat, tools]) => [ cat, - apps.slice(0, 3).map((app) => app.id), + tools.slice(0, 3).map((tool) => tool.id), ]) - ) as DeveloperAppsComputedSelections["categoryHighlights"], + ) as DeveloperToolsComputedSelections["categoryHighlights"], categoryPreviews: Object.fromEntries( - Object.entries(categoryPreviews).map(([cat, apps]) => [ + Object.entries(categoryPreviews).map(([cat, tools]) => [ cat, - apps.map((app) => app.id), + tools.map((tool) => tool.id), ]) - ) as DeveloperAppsComputedSelections["categoryPreviews"], + ) as DeveloperToolsComputedSelections["categoryPreviews"], computedAt: new Date().toISOString(), } console.log( @@ -78,5 +80,5 @@ export async function fetchDeveloperTools(): Promise ) console.log("Developer tools data enrichment complete") - return { appsById, selections } + return { toolsById: toolsById, selections } } diff --git a/src/data-layer/fetchers/developer-tools/utils.ts b/src/data-layer/fetchers/developer-tools/utils.ts index 1318912ace1..1468d705a29 100644 --- a/src/data-layer/fetchers/developer-tools/utils.ts +++ b/src/data-layer/fetchers/developer-tools/utils.ts @@ -1,11 +1,11 @@ import { getDayOfYear, getWeekNumber } from "@/lib/utils/date" -// Import the base DeveloperApp type from app code (type-only import) +// Import the base DeveloperTool type from tool code (type-only import) // This is acceptable as it's a shared data contract, not a presentation dependency -import type { DeveloperApp } from "../../../../app/[locale]/developers/tools/types" +import type { DeveloperTool } from "../../../../app/[locale]/developers/tools/types" // Re-export for convenience -export type { DeveloperApp } +export type { DeveloperTool } // ============================================================================= // Types @@ -13,9 +13,9 @@ export type { DeveloperApp } /** * Category slug type derived from the category mapping. - * These are URL-friendly identifiers for developer app categories. + * These are URL-friendly identifiers for developer tool categories. */ -export type DeveloperAppCategorySlug = +export type DeveloperToolCategorySlug = | "interoperability" | "transactions" | "analytics" @@ -25,37 +25,37 @@ export type DeveloperAppCategorySlug = | "security" /** - * Apps grouped by category slug. + * Tools grouped by category slug. */ -export type DeveloperAppsByCategory = Record< - DeveloperAppCategorySlug, - DeveloperApp[] +export type DeveloperToolsByCategory = Record< + DeveloperToolCategorySlug, + DeveloperTool[] > /** - * Pre-computed randomized selections for developer apps. + * Pre-computed randomized selections for developer tools. * Computed daily in the trigger.dev task to ensure all users see the same selections. */ -export interface DeveloperAppsComputedSelections { - /** Main page highlights - top app from 3 random categories (3 IDs) */ +export interface DeveloperToolsComputedSelections { + /** Main page highlights - top tool from 3 random categories (3 IDs) */ mainPageHighlights: string[] - /** Category page highlights - top 3 apps per category (7 categories × 3 = 21 IDs) */ - categoryHighlights: Record - /** Category preview apps - 5 random apps per category for main page cards (7 × 5 = 35 IDs) */ - categoryPreviews: Record + /** Category page highlights - top 3 tools per category (7 categories × 3 = 21 IDs) */ + categoryHighlights: Record + /** Category preview tools - 5 random tools per category for main page cards (7 × 5 = 35 IDs) */ + categoryPreviews: Record /** ISO date when selections were computed (for debugging) */ computedAt: string } /** * Envelope type for developer tools data. - * Contains both the app data and pre-computed selections. + * Contains both the tool data and pre-computed selections. */ export interface DeveloperToolsDataEnvelope { - /** All apps indexed by ID for quick lookup (used by app modal) */ - appsById: Record + /** All tools indexed by ID for quick lookup (used by tool modal) */ + toolsById: Record /** Pre-computed randomized selections (refreshed daily) */ - selections: DeveloperAppsComputedSelections + selections: DeveloperToolsComputedSelections } // ============================================================================= @@ -66,21 +66,23 @@ export interface DeveloperToolsDataEnvelope { * Maps human-readable category names to URL-friendly slugs. * This is the data-layer copy of the constant - no UI dependencies. */ -export const DEV_APP_CATEGORY_SLUGS: Record = - { - "Cross-Chain & Interoperability": "interoperability", - "Transaction & Wallet Infrastructure": "transactions", - "Data, Analytics & Tracing": "analytics", - "Education & Community Resources": "education", - "Client Libraries & SDKs (Front-End)": "sdks", - "Smart Contract Development & Toolchains": "contracts", - "Security, Testing & Formal Verification": "security", - } +export const DEV_TOOL_CATEGORY_SLUGS: Record< + string, + DeveloperToolCategorySlug +> = { + "Cross-Chain & Interoperability": "interoperability", + "Transaction & Wallet Infrastructure": "transactions", + "Data, Analytics & Tracing": "analytics", + "Education & Community Resources": "education", + "Client Libraries & SDKs (Front-End)": "sdks", + "Smart Contract Development & Toolchains": "contracts", + "Security, Testing & Formal Verification": "security", +} /** * List of all category slugs for iteration. */ -export const DEV_APP_CATEGORY_SLUG_LIST: DeveloperAppCategorySlug[] = [ +export const DEV_TOOL_CATEGORY_SLUG_LIST: DeveloperToolCategorySlug[] = [ "interoperability", "transactions", "analytics", @@ -90,9 +92,9 @@ export const DEV_APP_CATEGORY_SLUG_LIST: DeveloperAppCategorySlug[] = [ "security", ] -// Number of top apps to show in highlights section +// Number of top tools to show in highlights section const HIGHLIGHTS_PER_CATEGORY = 9 -// Number of preview apps to show in category cards +// Number of preview tools to show in category cards const PREVIEWS_PER_CATEGORY = 5 // ============================================================================= @@ -133,10 +135,10 @@ function seededShuffle(array: T[], seed: number): T[] { } /** - * Get maximum star count across all repos for an app. + * Get maximum star count across all repos for an tool. */ -function getMaxStarCount(app: DeveloperApp): number { - return Math.max(...app.repos.map((repo) => repo.stargazers || 0), 0) +function getMaxStarCount(tool: DeveloperTool): number { + return Math.max(...tool.repos.map((repo) => repo.stargazers || 0), 0) } /** @@ -151,55 +153,55 @@ function getCategorySeedOffset(category: string): number { // ============================================================================= /** - * Transform flat array of apps into an object grouped by category slug. + * Transform flat array of tools into an object grouped by category slug. */ -export function transformDeveloperAppsData( - data: DeveloperApp[] -): DeveloperAppsByCategory { - const initialAcc = DEV_APP_CATEGORY_SLUG_LIST.reduce((acc, slug) => { +export function transformDeveloperToolsData( + data: DeveloperTool[] +): DeveloperToolsByCategory { + const initialAcc = DEV_TOOL_CATEGORY_SLUG_LIST.reduce((acc, slug) => { acc[slug] = [] return acc - }, {} as DeveloperAppsByCategory) + }, {} as DeveloperToolsByCategory) - return data.reduce((acc, app) => { - const slug = DEV_APP_CATEGORY_SLUGS[app.category] + return data.reduce((acc, tool) => { + const slug = DEV_TOOL_CATEGORY_SLUGS[tool.category] if (slug) { - acc[slug].push(app) + acc[slug].push(tool) } return acc }, initialAcc) } /** - * Get highlighted apps grouped by category. + * Get highlighted tools grouped by category. * * Algorithm: - * 1. Filter to apps with GitHub repos updated in last 6 months + have banner/thumbnail images + * 1. Filter to tools with GitHub repos updated in last 6 months + have banner/thumbnail images * 2. Group by category slug * 3. Sort each category by highest GitHub star count - * 4. Take top 9 apps per category + * 4. Take top 9 tools per category * 5. Shuffle each category's top 9 using weekly seed for deterministic rotation * - * @returns Object mapping category slugs to arrays of up to 9 highlighted apps + * @returns Object mapping category slugs to arrays of up to 9 highlighted tools */ export function getHighlightsByCategory( - apps: DeveloperApp[], + tools: DeveloperTool[], now: Date = new Date() -): Record { +): Record { const sixMonthsAgo = new Date(now) sixMonthsAgo.setMonth(sixMonthsAgo.getMonth() - 6) - // Filter apps with GitHub repos updated in last 6 months and have required images - const recentApps = apps.filter((app) => { + // Filter tools with GitHub repos updated in last 6 months and have required images + const recentTools = tools.filter((tool) => { // Must have both banner and thumbnail images for highlights section - if (!app.banner_url || !app.thumbnail_url) return false + if (!tool.banner_url || !tool.thumbnail_url) return false - const hasGitHubRepo = app.repos.some((repo) => + const hasGitHubRepo = tool.repos.some((repo) => repo.href.includes("github.com") ) if (!hasGitHubRepo) return false - const latestUpdate = app.repos.reduce((latest, repo) => { + const latestUpdate = tool.repos.reduce((latest, repo) => { if (!repo.lastUpdated) return latest const date = new Date(repo.lastUpdated) return date > latest ? date : latest @@ -209,24 +211,24 @@ export function getHighlightsByCategory( }) // Group by category slug - const byCategory: Record = {} - for (const app of recentApps) { - const categorySlug = DEV_APP_CATEGORY_SLUGS[app.category] + const byCategory: Record = {} + for (const tool of recentTools) { + const categorySlug = DEV_TOOL_CATEGORY_SLUGS[tool.category] if (!categorySlug) continue if (!byCategory[categorySlug]) { byCategory[categorySlug] = [] } - byCategory[categorySlug].push(app) + byCategory[categorySlug].push(tool) } // Get weekly seed for deterministic randomization const weekSeed = getWeekNumber(now) // Sort by stars, take top N, randomize - const result: Record = {} - for (const [category, categoryApps] of Object.entries(byCategory)) { + const result: Record = {} + for (const [category, categoryTools] of Object.entries(byCategory)) { // Sort by highest star count - const sorted = [...categoryApps].sort((a, b) => { + const sorted = [...categoryTools].sort((a, b) => { return getMaxStarCount(b) - getMaxStarCount(a) }) @@ -240,61 +242,61 @@ export function getHighlightsByCategory( result[category] = randomized } - return result as Record + return result as Record } /** * Get highlights for main /developers/tools page. - * Returns top app from top 3 randomly-ordered categories. + * Returns top tool from top 3 randomly-ordered categories. * - * @returns Array of 3 apps (one from each of top 3 categories) + * @returns Array of 3 tools (one from each of top 3 categories) */ export function getMainPageHighlights( - highlightsByCategory: Record, + highlightsByCategory: Record, now: Date = new Date() -): DeveloperApp[] { +): DeveloperTool[] { const weekSeed = getWeekNumber(now) // Get categories with highlights const categoriesWithHighlights = Object.entries(highlightsByCategory).filter( - ([, apps]) => apps.length > 0 + ([, tools]) => tools.length > 0 ) // Randomize category order const randomizedCategories = seededShuffle(categoriesWithHighlights, weekSeed) - // Take top app from top 3 categories + // Take top tool from top 3 categories return randomizedCategories .slice(0, 3) - .map(([, apps]) => apps[0]) + .map(([, tools]) => tools[0]) .filter(Boolean) } /** - * Get randomized preview apps per category for main page cards. + * Get randomized preview tools per category for main page cards. * * Simpler than highlights: no filtering, no star sorting - just shuffle and take N. * Uses daily seed for rotation instead of weekly. * - * @param dataByCategory - Apps already grouped by category - * @returns Same structure but with max N randomized apps per category + * @param dataByCategory - Tools already grouped by category + * @returns Same structure but with max N randomized tools per category */ export function getRandomPreviewsByCategory( - dataByCategory: DeveloperAppsByCategory, + dataByCategory: DeveloperToolsByCategory, now: Date = new Date() -): DeveloperAppsByCategory { +): DeveloperToolsByCategory { const daySeed = getDayOfYear(now) - const result = {} as DeveloperAppsByCategory + const result = {} as DeveloperToolsByCategory - for (const [category, apps] of Object.entries(dataByCategory)) { + for (const [category, tools] of Object.entries(dataByCategory)) { // Shuffle with daily seed + category offset for variety const shuffled = seededShuffle( - apps, + tools, daySeed + getCategorySeedOffset(category) ) // Take first N after shuffle - result[category as DeveloperAppCategorySlug] = shuffled.slice( + result[category as DeveloperToolCategorySlug] = shuffled.slice( 0, PREVIEWS_PER_CATEGORY ) diff --git a/src/data-layer/index.ts b/src/data-layer/index.ts index 8aabeac96d9..ad42e32b925 100644 --- a/src/data-layer/index.ts +++ b/src/data-layer/index.ts @@ -44,4 +44,4 @@ export const getStablecoinsData = () => get(KEYS.ST export const getTotalEthStakedData = () => get(KEYS.TOTAL_ETH_STAKED) export const getTotalValueLockedData = () => get(KEYS.TOTAL_VALUE_LOCKED) export const getEventsData = () => get(KEYS.EVENTS) -export const getDeveloperToolsData = () => get(KEYS.DEVELOPER_APPS) +export const getDeveloperToolsData = () => get(KEYS.DEVELOPER_TOOLS) diff --git a/src/data-layer/mocks/fetch-developer-tools.json b/src/data-layer/mocks/fetch-developer-tools.json index 0d222648e01..b72587c1d67 100644 --- a/src/data-layer/mocks/fetch-developer-tools.json +++ b/src/data-layer/mocks/fetch-developer-tools.json @@ -1,5 +1,5 @@ { - "appsById": { + "toolsById": { "0x939241afa4c4b9e1dda6b8250baa8f04fa8b0debce738cfd324c0b18f9926d25": { "id": "0x939241afa4c4b9e1dda6b8250baa8f04fa8b0debce738cfd324c0b18f9926d25", "name": "OpenZeppelin Contracts", diff --git a/src/data-layer/tasks.ts b/src/data-layer/tasks.ts index 82e80e20581..8f44950be95 100644 --- a/src/data-layer/tasks.ts +++ b/src/data-layer/tasks.ts @@ -35,7 +35,7 @@ export const KEYS = { APPS: "fetch-apps", CALENDAR_EVENTS: "fetch-calendar-events", COMMUNITY_PICKS: "fetch-community-picks", - DEVELOPER_APPS: "fetch-developer-tools", + DEVELOPER_TOOLS: "fetch-developer-tools", GFIS: "fetch-gfis", GIT_HISTORY: "fetch-git-history", GROW_THE_PIE: "fetch-grow-the-pie", @@ -73,7 +73,7 @@ const DAILY: TaskDef[] = [ [KEYS.RSS, fetchRSS], [KEYS.GITHUB_REPO_DATA, fetchGithubRepoData], [KEYS.EVENTS, fetchEvents], - [KEYS.DEVELOPER_APPS, fetchDeveloperTools], + [KEYS.DEVELOPER_TOOLS, fetchDeveloperTools], ] const HOURLY: TaskDef[] = [ diff --git a/src/lib/types.ts b/src/lib/types.ts index 6ceac4c634d..fc402063c8e 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -25,8 +25,8 @@ import allQuizData from "@/data/quizzes" import allQuestionData from "@/data/quizzes/questionBank" import { - DeveloperAppCategory, - DeveloperAppTag, + DeveloperToolCategory, + DeveloperToolTag, } from "../../app/[locale]/developers/tools/types" import { screens } from "./utils/screen" @@ -1342,7 +1342,7 @@ export interface MatomoEventOptions { eventValue?: string } -export type DeveloperAppsResponse = { +export type DeveloperToolsResponse = { id: string name: string description: string @@ -1350,7 +1350,7 @@ export type DeveloperAppsResponse = { banner_url?: string twitter?: string repos: string[] - tags: DeveloperAppTag[] + tags: DeveloperToolTag[] website?: string - category: DeveloperAppCategory + category: DeveloperToolCategory } From 14e01f4e26a4d137fa5e7812f6846f6d18ff9cfb Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 3 Feb 2026 19:55:37 -0500 Subject: [PATCH 70/74] refactor: use internal Image component add allowed domain --- app/[locale]/developers/tools/_components/HighlightsSection.tsx | 2 +- app/[locale]/developers/tools/_components/ToolModalContents.tsx | 2 +- next.config.js | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/[locale]/developers/tools/_components/HighlightsSection.tsx b/app/[locale]/developers/tools/_components/HighlightsSection.tsx index 2e429ff0a47..8b5fd3db287 100644 --- a/app/[locale]/developers/tools/_components/HighlightsSection.tsx +++ b/app/[locale]/developers/tools/_components/HighlightsSection.tsx @@ -1,7 +1,7 @@ -import Image from "next/image" import { getLocale, getTranslations } from "next-intl/server" import AppCard from "@/components/AppCard" +import { Image } from "@/components/Image" import { CardBanner, CardParagraph } from "@/components/ui/card" import { EdgeScrollContainer, diff --git a/app/[locale]/developers/tools/_components/ToolModalContents.tsx b/app/[locale]/developers/tools/_components/ToolModalContents.tsx index 9d654fee715..4d0ba038dfe 100644 --- a/app/[locale]/developers/tools/_components/ToolModalContents.tsx +++ b/app/[locale]/developers/tools/_components/ToolModalContents.tsx @@ -1,10 +1,10 @@ import { Download, Star } from "lucide-react" -import Image from "next/image" import { getLocale, getTranslations } from "next-intl/server" import type { MDXRemoteProps } from "next-mdx-remote/rsc" import GitHub from "@/components/icons/github.svg" import NpmJs from "@/components/icons/npmjs.svg" +import { Image } from "@/components/Image" import { htmlElements } from "@/components/MdComponents" import { ButtonLink } from "@/components/ui/buttons/Button" import { Tag, TagsInlineText } from "@/components/ui/tag" diff --git a/next.config.js b/next.config.js index 2e49c369de0..921f6d8084d 100644 --- a/next.config.js +++ b/next.config.js @@ -98,6 +98,7 @@ module.exports = (phase, { defaultConfig }) => { }, { protocol: "https", hostname: "pvvrtckedmrkyzfxubkk.supabase.co" }, { protocol: "https", hostname: "avatars.githubusercontent.com" }, + { protocol: "https", hostname: "opengraph.githubassets.com" }, { protocol: "https", hostname: "github.com" }, { protocol: "https", hostname: "coin-images.coingecko.com" }, { protocol: "https", hostname: "i.imgur.com" }, From f1228c99bcce43c1c9cd0b11ffa8be4437651476 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 3 Feb 2026 19:55:55 -0500 Subject: [PATCH 71/74] bump(deps): @trigger.dev/sdk v4.3.3 --- package.json | 4 ++-- pnpm-lock.yaml | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index f6f0de4162b..cbfeac312ea 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "@tanstack/react-query": "^5.66.7", "@tanstack/react-table": "^8.19.3", "@tanstack/react-virtual": "^3.13.12", - "@trigger.dev/sdk": "4.3.2", + "@trigger.dev/sdk": "4.3.3", "@wagmi/core": "^2.17.3", "chart.js": "^4.4.2", "chartjs-plugin-datalabels": "^2.2.0", @@ -172,4 +172,4 @@ "sha.js": ">=2.4.12" } } -} +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6d89a30cb08..c1ea4e75b61 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -107,8 +107,8 @@ importers: specifier: ^3.13.12 version: 3.13.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@trigger.dev/sdk': - specifier: 4.3.2 - version: 4.3.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76) + specifier: 4.3.3 + version: 4.3.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76) '@wagmi/core': specifier: ^2.17.3 version: 2.17.3(@tanstack/query-core@5.80.2)(@types/react@18.2.57)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)) @@ -4088,15 +4088,15 @@ packages: peerDependencies: '@testing-library/dom': '>=7.21.4' - '@trigger.dev/core@4.3.2': - resolution: {integrity: sha512-CToEt1w1jOmpvwOh/gqgC3UKHw36nrHSxaMYRnv5csXFOMgH2BksD/fZ2M/R2Q8kNehlQGagFWoussGmItxZqw==} + '@trigger.dev/core@4.3.3': + resolution: {integrity: sha512-HPPxbesDiEEuA1U/Qi1RWXVMkQNDCNyB7zhd3cIYd6T0KUTIt6i7ZdaqSRDhkAxva2hpaWXQsQIYwr5Jnsyohw==} engines: {node: '>=18.20.0'} - '@trigger.dev/sdk@4.3.2': - resolution: {integrity: sha512-XbzWBHoVFwvW1uyEbiEmztF86gvLgt0OO/aUqgeOixBAsTXRFxI/zd/scBMHK8vE9jB1D2biI8x5of6gRPEK4g==} + '@trigger.dev/sdk@4.3.3': + resolution: {integrity: sha512-aNKbmn6O8XfAJsQ3j9A8tVUm6nr+5SktHxUs804i7S4BG//b0YX0yhrKwPUe8rUGmFCYxmb3B43OOtZ0MsPyfA==} engines: {node: '>=18.20.0'} peerDependencies: - ai: ^4.2.0 || ^5.0.0 + ai: ^4.2.0 || ^5.0.0 || ^6.0.0 zod: ^3.0.0 || ^4.0.0 peerDependenciesMeta: ai: @@ -14551,7 +14551,7 @@ snapshots: dependencies: '@testing-library/dom': 10.4.0 - '@trigger.dev/core@4.3.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': + '@trigger.dev/core@4.3.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': dependencies: '@bugsnag/cuid': 3.2.1 '@electric-sql/client': 1.0.14 @@ -14592,11 +14592,11 @@ snapshots: - typescript - utf-8-validate - '@trigger.dev/sdk@4.3.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@trigger.dev/sdk@4.3.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/semantic-conventions': 1.36.0 - '@trigger.dev/core': 4.3.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@trigger.dev/core': 4.3.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) chalk: 5.4.1 cronstrue: 2.59.0 debug: 4.4.3 From 49bdd4baba97c6e74e84f9007b9581e6e0d074a7 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Wed, 4 Feb 2026 09:45:44 -0500 Subject: [PATCH 72/74] fix: add allowed next image domains for dev-tools --- next.config.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/next.config.js b/next.config.js index 921f6d8084d..5e27317a94b 100644 --- a/next.config.js +++ b/next.config.js @@ -113,6 +113,8 @@ module.exports = (phase, { defaultConfig }) => { { protocol: "https", hostname: "img.evbuc.com" }, { protocol: "https", hostname: "storage.googleapis.com" }, { protocol: "https", hostname: "cdn.charmverse.io" }, + { protocol: "https", hostname: "ethwingman.com" }, + { protocol: "https", hostname: "eth-mcp.dev" }, ], }, async headers() { From 8ed089e40ad4ec2acfac21dc8121506e84975052 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Thu, 5 Feb 2026 13:15:55 -0500 Subject: [PATCH 73/74] patch: update redirects to /developers/tools/* --- redirects.config.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/redirects.config.js b/redirects.config.js index d570f04a287..a59930aa63b 100644 --- a/redirects.config.js +++ b/redirects.config.js @@ -36,9 +36,9 @@ module.exports = [ "/developers/docs/consensus-mechanisms/pow/mining/", ], ["/beginners", "/what-is-ethereum/"], - ["/build", "/developers/apps/education/"], - ["/developers/learning-tools", "/developers/apps/education/"], - ["/developers/local-environment", "/developers/apps/"], + ["/build", "/developers/tools/"], + ["/developers/learning-tools", "/developers/tools/education/"], + ["/developers/local-environment", "/developers/tools/"], ["/eth2/beacon-chain", "/roadmap/beacon-chain/"], ["/eth2/the-beacon-chain", "/roadmap/beacon-chain/"], ["/upgrades/the-beacon-chain", "/roadmap/beacon-chain/"], From 108f825efad6f50e53a2e75215ac34efaf0ae6d0 Mon Sep 17 00:00:00 2001 From: Paul Wackerow <54227730+wackerow@users.noreply.github.com> Date: Thu, 5 Feb 2026 14:06:04 -0500 Subject: [PATCH 74/74] fix: dynamicParams false for dev-tools category pages --- app/[locale]/developers/tools/[category]/page.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/[locale]/developers/tools/[category]/page.tsx b/app/[locale]/developers/tools/[category]/page.tsx index 9620caa059d..7842c974946 100644 --- a/app/[locale]/developers/tools/[category]/page.tsx +++ b/app/[locale]/developers/tools/[category]/page.tsx @@ -143,6 +143,8 @@ export async function generateStaticParams() { return DEV_TOOL_CATEGORIES.map(({ slug }) => ({ category: slug })) } +export const dynamicParams = false + export async function generateMetadata({ params, }: {