{"id":31767841,"url":"https://github.com/openzeppelin/ui-builder","last_synced_at":"2026-04-02T16:59:27.125Z","repository":{"id":309405586,"uuid":"944614692","full_name":"OpenZeppelin/ui-builder","owner":"OpenZeppelin","description":"UI Builder is an open-source blockchain development tool that helps developers and non-developers create user-friendly interfaces for smart contract interaction by providing a chain-agnostic form builder that generates standalone \"mini apps\" without requiring backend infrastructure.","archived":false,"fork":false,"pushed_at":"2026-01-11T17:58:56.000Z","size":12026,"stargazers_count":27,"open_issues_count":10,"forks_count":10,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-11T19:44:20.299Z","etag":null,"topics":["blockchain","builder","evm","forms","midnight","solana","stellar","web3"],"latest_commit_sha":null,"homepage":"https://builder.openzeppelin.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenZeppelin.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-03-07T16:56:35.000Z","updated_at":"2026-01-11T17:02:56.000Z","dependencies_parsed_at":"2025-09-10T13:27:57.953Z","dependency_job_id":"33bb3785-1e0c-4581-a442-c308e86c8de5","html_url":"https://github.com/OpenZeppelin/ui-builder","commit_stats":null,"previous_names":["openzeppelin/contracts-ui-builder","openzeppelin/ui-builder"],"tags_count":215,"template":false,"template_full_name":null,"purl":"pkg:github/OpenZeppelin/ui-builder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenZeppelin%2Fui-builder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenZeppelin%2Fui-builder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenZeppelin%2Fui-builder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenZeppelin%2Fui-builder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenZeppelin","download_url":"https://codeload.github.com/OpenZeppelin/ui-builder/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenZeppelin%2Fui-builder/sbom","scorecard":{"id":1237396,"data":{"date":"2025-09-07T04:40:00Z","repo":{"name":"github.com/OpenZeppelin/contracts-ui-builder","commit":"654b25314713934c6c42a0b8d383b7f80e288f96"},"scorecard":{"version":"v5.2.1","commit":"ab2f6e92482462fe66246d9e32f642855a691dc1"},"score":5.3,"checks":[{"name":"Maintained","score":10,"reason":"30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#maintained"}},{"name":"Code-Review","score":3,"reason":"Found 9/25 approved changesets -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#code-review"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: SECURITY.md:1","Info: Found linked content: SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: SECURITY.md:1","Info: Found text in security policy: SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#security-policy"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'contents' permission set to 'read': .github/workflows/check-versions.yml:20","Info: jobLevel 'contents' permission set to 'read': .github/workflows/ci.yml:19","Info: jobLevel 'contents' permission set to 'read': .github/workflows/coverage.yml:19","Info: jobLevel 'contents' permission set to 'read': .github/workflows/dependencies.yml:18","Info: jobLevel 'contents' permission set to 'read': .github/workflows/docker-prod.yaml:23","Info: jobLevel 'contents' permission set to 'read': .github/workflows/docker-prod.yaml:133","Warn: jobLevel 'contents' permission set to 'write': .github/workflows/docker-stg.yaml:45","Info: jobLevel 'contents' permission set to 'read': .github/workflows/docker-stg.yaml:148","Info: jobLevel 'contents' permission set to 'read': .github/workflows/docker-stg.yaml:244","Info: jobLevel 'contents' permission set to 'read': .github/workflows/export-testing.yml:24","Info: jobLevel 'contents' permission set to 'read': .github/workflows/lint.yml:18","Info: jobLevel 'contents' permission set to 'read': .github/workflows/update-dependencies.yml:18","Warn: jobLevel 'contents' permission set to 'write': .github/workflows/update-versions.yml:22","Info: topLevel 'contents' permission set to 'read': .github/workflows/check-versions.yml:14","Info: topLevel 'contents' permission set to 'read': .github/workflows/ci.yml:13","Info: topLevel 'contents' permission set to 'read': .github/workflows/coverage.yml:13","Info: topLevel 'contents' permission set to 'read': .github/workflows/dependencies.yml:12","Info: topLevel 'contents' permission set to 'read': .github/workflows/docker-prod.yaml:15","Info: topLevel 'actions' permission set to 'read': .github/workflows/docker-prod.yaml:16","Info: topLevel 'contents' permission set to 'read': .github/workflows/docker-stg.yaml:38","Info: topLevel 'actions' permission set to 'read': .github/workflows/docker-stg.yaml:39","Info: topLevel 'contents' permission set to 'read': .github/workflows/export-testing.yml:17","Info: topLevel 'contents' permission set to 'read': .github/workflows/lint.yml:11","Warn: topLevel 'contents' permission set to 'write': .github/workflows/publish.yml:18","Warn: topLevel 'actions' permission set to 'write': .github/workflows/publish.yml:23","Info: topLevel permissions set to 'read-all': .github/workflows/scorecard.yml:18","Info: topLevel 'contents' permission set to 'read': .github/workflows/update-dependencies.yml:12","Info: topLevel 'contents' permission set to 'read': .github/workflows/update-versions.yml:13"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":0,"reason":"dangerous workflow patterns detected","details":["Warn: script injection with untrusted input ' github.head_ref || github.ref_name ': .github/workflows/update-versions.yml:76"],"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":9,"reason":"dependency not pinned by hash detected -- score normalized to 9","details":["Warn: npmCommand not pinned by hash: Dockerfile:37","Warn: npmCommand not pinned by hash: Dockerfile:67","Info:  35 out of  35 GitHub-owned GitHubAction dependencies pinned","Info:  34 out of  34 third-party GitHubAction dependencies pinned","Info:   0 out of   2 npmCommand dependencies pinned","Info:   2 out of   2 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#cii-best-practices"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#signed-releases"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/docker-prod.yaml:19"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#packaging"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#fuzzing"}},{"name":"Dependency-Update-Tool","score":0,"reason":"no update tool detected","details":["Warn: no dependency update tool configurations found"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#dependency-update-tool"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: GNU Affero General Public License v3.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#license"}},{"name":"Branch-Protection","score":5,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'main'","Info: 'force pushes' disabled on branch 'main'","Warn: 'branch protection settings apply to administrators' is disabled on branch 'main'","Warn: 'stale review dismissal' is disabled on branch 'main'","Warn: required approving review count is 1 on branch 'main'","Info: codeowner review is required on branch 'main'","Warn: 'last push approval' is disabled on branch 'main'","Warn: no status checks found to merge onto branch 'main'","Info: PRs are required in order to make changes on branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":7,"reason":"3 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-3gc7-fjrx-p6mg","Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#vulnerabilities"}},{"name":"Contributors","score":6,"reason":"project has 2 contributing companies or organizations -- score normalized to 6","details":["Info: found contributions from: openzeppelin, semantic-release"],"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#contributors"}},{"name":"SAST","score":9,"reason":"SAST tool is not run on all commits -- score normalized to 9","details":["Warn: 28 commits out of 29 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#sast"}},{"name":"CI-Tests","score":9,"reason":"28 out of 29 merged PRs checked by a CI test -- score normalized to 9","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#ci-tests"}}]},"last_synced_at":"2025-09-10T15:59:49.602Z","repository_id":309405586,"created_at":"2025-09-10T15:59:49.602Z","updated_at":"2025-09-10T15:59:49.602Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28337870,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T06:09:07.588Z","status":"ssl_error","status_checked_at":"2026-01-12T06:05:18.301Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blockchain","builder","evm","forms","midnight","solana","stellar","web3"],"created_at":"2025-10-10T01:48:12.018Z","updated_at":"2026-04-02T16:59:27.118Z","avatar_url":"https://github.com/OpenZeppelin.png","language":"TypeScript","readme":"# UI Builder 🧩\n\n\u003e Spin up a front-end for any contract call in seconds. Select the function, auto-generate a React UI with wallet connect and multi-network support, and export a complete app.\n\n## Project Status\n\nThis project is currently in development.\n\n[![CI](https://github.com/OpenZeppelin/ui-builder/actions/workflows/ci.yml/badge.svg)](https://github.com/OpenZeppelin/ui-builder/actions/workflows/ci.yml)\n[![Coverage](https://github.com/OpenZeppelin/ui-builder/actions/workflows/coverage.yml/badge.svg)](https://github.com/OpenZeppelin/ui-builder/actions/workflows/coverage.yml)\n[![Dependencies](https://github.com/OpenZeppelin/ui-builder/actions/workflows/dependencies.yml/badge.svg)](https://github.com/OpenZeppelin/ui-builder/actions/workflows/dependencies.yml)\n[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/OpenZeppelin/ui-builder/badge)](https://api.securityscorecards.dev/projects/github.com/OpenZeppelin/ui-builder)\n[![License: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)\n\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-brightgreen.svg)](https://conventionalcommits.org)\n[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)\n[![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?logo=typescript\u0026logoColor=white)](https://www.typescriptlang.org/)\n[![React](https://img.shields.io/badge/React-20232A?logo=react\u0026logoColor=61DAFB)](https://reactjs.org/)\n[![Tailwind CSS](https://img.shields.io/badge/Tailwind_CSS-38B2AC?logo=tailwind-css\u0026logoColor=white)](https://tailwindcss.com/)\n[![Vite](https://img.shields.io/badge/Vite-B73BFE?logo=vite\u0026logoColor=FFD62E)](https://vitejs.dev/)\n[![pnpm](https://img.shields.io/badge/pnpm-F69220?logo=pnpm\u0026logoColor=white)](https://pnpm.io/)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com)\n\n## Table of Contents\n\n- [Repository Structure](#repository-structure)\n- [Packages](#packages)\n  - [Builder Package](#builder-package)\n  - [Adapter Packages](#adapter-packages)\n  - [Shared Packages (External)](#shared-packages-external)\n- [Features](#features)\n- [Tech Stack](#tech-stack)\n- [Getting Started](#getting-started)\n  - [Prerequisites](#prerequisites)\n  - [Installation](#installation)\n  - [Running with Docker (Recommended)](#running-with-docker-recommended)\n- [Available Scripts](#available-scripts)\n- [Project Structure](#project-structure)\n  - [Local Application](#local-application)\n  - [External Package Repositories](#external-package-repositories)\n  - [Configuration Structure](#configuration-structure)\n- [Architecture](#architecture)\n- [Project Constitution](#project-constitution)\n- [Build System](#build-system)\n- [Component Architecture](#component-architecture)\n  - [Renderer Components](#renderer-components)\n- [Code Style](#code-style)\n  - [Git Hooks](#git-hooks)\n  - [CSS Class Name Sorting](#css-class-name-sorting)\n  - [Shared Prettier Configuration](#shared-prettier-configuration)\n  - [Import Sorting](#import-sorting)\n- [Dependency Management](#dependency-management)\n  - [Exported Package Versions](#exported-package-versions)\n  - [Checking for Outdated Dependencies](#checking-for-outdated-dependencies)\n  - [Updating Dependencies](#updating-dependencies)\n  - [Automated Updates](#automated-updates)\n- [Adding New Adapters](#adding-new-adapters)\n- [Commit Convention](#commit-convention)\n- [Contributing](#contributing)\n- [Security](#security)\n- [License](#license)\n- [CI/CD Pipeline](#cicd-pipeline)\n  - [Package Publishing](#package-publishing)\n- [Monorepo Configuration](#monorepo-configuration)\n  - [Shared Configurations](#shared-configurations)\n- [Runtime Configuration](#runtime-configuration)\n  - [Builder Application Configuration (Development)](#builder-application-configuration-development)\n  - [Exported Application Configuration](#exported-application-configuration)\n\n## Repository Structure\n\nThis repository contains the Builder application plus repository-level tooling,\nworkflows, and export scripts.\n\n- **apps/builder**: The main application with the builder UI and export logic.\n\n### Shared Packages (External)\n\nCore UI packages are maintained in the [openzeppelin-ui](https://github.com/OpenZeppelin/openzeppelin-ui)\nmonorepo:\n\n- **react**: Core React context providers and hooks (AdapterProvider, WalletStateProvider, useWalletState) for managing global wallet/network state and adapter interactions.\n- **renderer**: React components for rendering blockchain transaction forms, contract state displays, execution configuration, and transaction status tracking.\n- **components**: Shared React UI components, including basic primitives (buttons, inputs, cards) and specialized form field components.\n- **storage**: Local storage services built on IndexedDB for persisting contract UI configurations, providing history, auto-save, and import/export capabilities.\n- **types**: Shared TypeScript type definitions for all packages.\n- **styles**: Centralized styling system with shared CSS variables and configurations.\n- **utils**: Shared, framework-agnostic utility functions (e.g., logger, app configuration service).\n\n## Packages\n\n### Builder Package\n\nThe main application with the builder UI, export system, and core logic.\n\nFor more details, see the [Builder README](./apps/builder/README.md).\n\n### Adapter Packages\n\nAdapter implementations live in the\n[openzeppelin-adapters](https://github.com/OpenZeppelin/openzeppelin-adapters) repository and are\npublished under the `@openzeppelin/adapter-*` namespace. Shared Vite/Vitest\nintegration for consuming apps is provided by `@openzeppelin/adapters-vite`.\n\n#### Public Adapter Packages\n\n- `@openzeppelin/adapter-evm`\n- `@openzeppelin/adapter-midnight`\n- `@openzeppelin/adapter-polkadot`\n- `@openzeppelin/adapter-solana`\n- `@openzeppelin/adapter-stellar`\n- `@openzeppelin/adapters-vite` (shared build-time integration helper)\n\n#### Internal Adapter Package\n\n- `@openzeppelin/adapter-evm-core` is an internal package bundled by the public EVM-oriented\n  adapters rather than consumed directly by Builder applications.\n\n## Features\n\n- Chain-agnostic architecture supporting multiple blockchain ecosystems\n- Adapter pattern for easily adding support for new blockchains\n- Modern React components for building transaction forms\n- Customizable UI with Tailwind CSS and shadcn/ui\n- **Local Storage \u0026 History**: Complete auto-save system with IndexedDB-based persistence for contract UI configurations\n- **Import/Export**: Save and share configurations as JSON files with built-in validation\n- **Multi-tab Synchronization**: Real-time synchronization of saved configurations across browser tabs\n- Handles wallet connection state consistently in both builder app and exported forms\n- Configure transaction execution methods (EOA, Relayer, Multisig) via a powerful Execution Strategy pattern\n- Type-safe with TypeScript\n- Fast development with Vite\n- Comprehensive test suite with Vitest\n- Automated dependency management and security checks\n\n## Tech Stack\n\n- **React**: UI library supporting both React 18 and 19 with modern hooks API\n- **TypeScript 5.8+**: Enhanced type safety with template literal types\n- **Vite 6**: Fast, modern build tool and dev server with standardized library builds\n- **Tailwind CSS v4**: Next-gen utility-first CSS framework with OKLCH color format\n- **shadcn/ui**: Unstyled, accessible component system built on Radix UI\n- **pnpm (v9 or higher)**: Fast, disk-efficient package manager\n- **Vitest**: Testing framework integrated with Vite\n- **Zustand**: Lightweight, performant state management for React\n- **GitHub Actions**: CI plus Docker deploys for staging and production (see `.github/workflows`)\n- **ESLint 9**: Modern linting with improved TypeScript support\n- **tsup**: Used for root/tooling bundles where applicable\n- **Vite**: Builder application dev server and production build\n- **Dexie.js**: Modern IndexedDB wrapper for local storage and offline capabilities\n- **@openzeppelin/relayer-sdk**: For gasless transaction support via the Relayer execution method.\n\n## Getting Started\n\n### Prerequisites\n\n- Node.js (v20.11.1 or higher)\n- pnpm (v9 or higher)\n\n### Installation\n\n1. Clone the repository:\n\n   ```bash\n   git clone https://github.com/OpenZeppelin/ui-builder.git\n   cd ui-builder\n   ```\n\n2. Install dependencies:\n\n   ```bash\n   pnpm install\n   ```\n\n3. Build all packages:\n\n   ```bash\n   pnpm build\n   ```\n\n4. Start the development server:\n\n   ```bash\n   pnpm dev\n   ```\n\n5. Open your browser and navigate to `http://localhost:5173`\n\n### Running with Docker (Recommended)\n\nFor a consistent and reliable development environment, it is highly recommended to run the application using Docker. This avoids potential issues with local Node.js, pnpm, or operating system configurations.\n\n1. **Prerequisites**: Make sure you have Docker and Docker Compose installed on your system.\n\n2. **Build and Run the Container**:\n\n   ```bash\n   docker-compose up --build\n   ```\n\n   This command will build the Docker image and start the application. Once it's running, you can access it at `http://localhost:3000`.\n\n## Available Scripts\n\n- `pnpm dev` - Start the development server\n- `pnpm build` - Build for production\n- `pnpm lint` - Run ESLint\n- `pnpm lint:fix` - Fix ESLint issues\n- `pnpm lint:all-fix` - Fix ESLint issues across all file types\n- `pnpm lint:config-files` - Lint Vite/Vitest config files (read-only; fails on issues)\n- `pnpm lint:config-files:fix` - Auto-fix lint issues in configuration files (builder app only; run via `pnpm --filter=@openzeppelin/ui-builder-app lint:config-files:fix`)\n- `pnpm format` - Format code with Prettier\n- `pnpm format:check` - Check formatting without making changes\n- `pnpm fix-all` - Run Prettier first, then ESLint to avoid conflicts with CSS class sorting\n- `pnpm preview` - Preview the production build\n- `pnpm ui:add` - Add shadcn/ui components\n- `pnpm test` - Run tests\n- `pnpm test:watch` - Run tests in watch mode\n- `pnpm test:coverage` - Run tests with coverage report\n- `pnpm commit` - Run commitizen for guided commits\n- `pnpm update-deps` - Update all monorepo dependencies to their latest versions\n- `pnpm update-deps:major` - Update dependencies including major versions\n- `pnpm check-deps` - Check for deprecated dependencies\n- `pnpm outdated` - List outdated dependencies across the monorepo\n- `pnpm export-app [cmd] [opts]` - Export a standalone form project (see `pnpm export-app --help`)\n- `pnpm update-export-versions` - Update the hardcoded versions of internal packages used in exported forms\n\n## Project Structure\n\nThis repository contains the Builder application and repository-level tooling.\n\n### Local Application\n\n- **[apps/builder/](./apps/builder/README.md)** - Main application with builder UI, export system,\n  and runtime integration code\n\n### External Package Repositories\n\n- **[openzeppelin-adapters](https://github.com/OpenZeppelin/openzeppelin-adapters)** - Adapter\n  implementations published as `@openzeppelin/adapter-*`\n- **[openzeppelin-ui](https://github.com/OpenZeppelin/openzeppelin-ui)** - Shared renderer, React,\n  components, storage, types, styles, and utils packages\n\n### Configuration Structure\n\n```text\nui-builder/\n├── .github/             # GitHub workflows and templates\n├── .husky/              # Git hooks\n├── test/                # Shared test setup and utilities\n├── packages/            # Monorepo packages (see individual READMEs for detailed structure)\n├── scripts/             # Utility scripts\n├── tailwind.config.cjs  # Central Tailwind CSS configuration\n├── postcss.config.cjs   # Central PostCSS configuration\n├── components.json      # Central shadcn/ui configuration\n├── tsconfig.base.json   # Base TypeScript configuration for all packages\n├── pnpm-workspace.yaml  # PNPM workspace configuration\n└── ...                  # Other configuration files\n```\n\nFor detailed application structure, see the Builder README linked above.\n\n## Architecture\n\nThe application uses a modular, domain-driven adapter pattern to support multiple blockchain ecosystems. For the adapter source-of-truth, please see the **[Adapter Architecture Guide](https://github.com/OpenZeppelin/openzeppelin-adapters/blob/main/docs/ADAPTER_ARCHITECTURE.md)** in the `openzeppelin-adapters` repository.\n\n**Key Components:**\n\n- **Builder**: Chain-agnostic application logic, UI components, and the export system. It includes:\n  - The `ecosystemManager.ts` for discovering network configurations and adapter capabilities.\n  - **Modular State Management**: Decomposed hook architecture with specialized responsibilities.\n  - **Application Sidebar**: Complete UI for managing saved configurations with import/export capabilities\n\n- **Storage System (`@openzeppelin/ui-storage`)**: IndexedDB-based persistence layer built on\n  Dexie.js providing:\n  - **Auto-Save Engine**: Debounced saving with in-memory caching and global coordination\n  - **Multi-Tab Synchronization**: Real-time updates across browser tabs\n  - **Import/Export**: JSON-based configuration sharing with validation\n  - **CRUD Operations**: Complete lifecycle management for contract UI configurations\n  - **Performance Optimization**: Efficient handling of 1000+ records with reactive updates\n\n- **Adapters (`@openzeppelin/adapter-*`)**: Individual packages maintained in\n  `openzeppelin-adapters` containing chain-specific implementations (for example `adapter-evm` and\n  `adapter-stellar`). Each adapter conforms to the common `ContractAdapter` interface defined in\n  `@openzeppelin/ui-types`. Adapters are instantiated with a specific `NetworkConfig`, making them\n  network-aware. The Builder app (via providers from `@openzeppelin/ui-react`) dynamically loads and\n  uses these adapters. Furthermore, adapters can optionally provide UI-specific functionalities:\n  - **React UI Context Provider** (e.g., for `wagmi/react` on EVM): `WalletStateProvider` (from `@openzeppelin/ui-react`) consumes this to set up the necessary app-wide context for the active adapter.\n  - **Facade Hooks** (e.g., `useAccount`, `useSwitchChain`): These are exposed by `WalletStateProvider` (via `useWalletState().walletFacadeHooks` from `@openzeppelin/ui-react`) for UI components to interact with wallet functionalities reactively and agnostically.\n  - **Standardized UI Components** (e.g., `ConnectButton`): These components are retrieved via `activeAdapter.getEcosystemWalletComponents()` and are expected to internally use the facade hooks.\n\n- **Renderer (`@openzeppelin/ui-renderer`)**: Shared library containing app rendering components\n  and common utilities (like logging).\n\n- **React Core (`@openzeppelin/ui-react`)**: Centralized React state management providing:\n  - **Adapter Provider**: Singleton pattern for adapter instance management\n  - **Wallet State Provider**: Global wallet/network state coordination\n  - **Context Hooks**: `useWalletState()` and `useAdapterContext()` for consistent state access\n\n- **UI Components (`@openzeppelin/ui-components`)**: Comprehensive component library including:\n  - **Basic Primitives**: Buttons, inputs, cards, dialogs following shadcn/ui patterns\n  - **Form Fields**: Specialized components for React Hook Form integration\n  - **Field Utilities**: Validation, accessibility, and layout helpers\n\n- **Types**: Shared TypeScript type definitions across all packages, including the crucial `ContractAdapter` interface and types for adapter UI enhancements.\n\n- **Styling System**: Centralized CSS variables and styling approach used across all packages.\n\nThis architecture allows for easy extension to support additional blockchain ecosystems without modifying the builder application logic. The `builder` package dynamically loads and uses adapters via `ecosystemManager.ts` and the provider model (from `@openzeppelin/ui-react`) and the export system includes the specific adapter package needed for the target chain in exported forms. It utilizes **custom Vite plugins** to create **virtual modules**, enabling reliable loading of shared assets (like configuration files between packages) across package boundaries, ensuring consistency between development, testing, and exported builds.\n\n## Project Constitution\n\nThis project is governed by the UI Builder Constitution. Please read it before contributing changes that affect architecture, adapters, or tooling:\n\n- [./.specify/memory/constitution.md](./.specify/memory/constitution.md)\n\n## Build System\n\nThe primary build target in this repository is the Builder app, while adapter package builds and\nadapter-specific validation live in `openzeppelin-adapters`.\n\nFor more detailed documentation about the adapter pattern, implementation guidelines, and validation rules, see the documentation within the [`packages/types/src/adapters/base.ts`](https://github.com/OpenZeppelin/openzeppelin-ui/blob/main/packages/types/src/adapters/base.ts) file where the `ContractAdapter` interface is defined.\n\n## Component Architecture\n\nThe project follows a structured component architecture centered around app rendering:\n\n### Renderer Components\n\nThe [`@openzeppelin/ui-renderer`](https://github.com/OpenZeppelin/openzeppelin-ui/tree/main/packages/renderer) package (maintained in the external openzeppelin-ui repo) provides:\n\n- **TransactionForm**: Core component for rendering blockchain transaction forms with dynamic field generation\n- **ContractStateWidget**: Widget for querying and displaying contract state through view functions\n- **ExecutionConfigDisplay**: Configuration UI for transaction execution methods (EOA/Relayer)\n- **TransactionStatusDisplay**: Shows transaction progress, hash display with explorer links\n- **DynamicFormField**: Renders form fields dynamically based on field type configuration\n\nThe actual UI primitives (like `TextField`, `AddressField`, `Button`, `Input`) are sourced from the `@openzeppelin/ui-components` package and work exclusively with React Hook Form.\n\n## Code Style\n\n### Git Hooks\n\nThis project uses Husky to enforce code quality using Git hooks:\n\n- **pre-commit**: Runs lint-staged to format and lint staged files (Prettier first, then ESLint)\n- **pre-push**: Runs comprehensive linting and formatting before pushing to remote\n- **commit-msg**: Enforces conventional commit message format\n\nThese hooks ensure that code pushed to the repository maintains consistent quality and style.\n\n### CSS Class Name Sorting\n\nFor consistent CSS class name sorting in Tailwind CSS, always run Prettier first, then ESLint:\n\n```bash\n# Recommended approach (runs formatting, then linting)\npnpm fix-all\n```\n\nThis approach ensures that Tailwind CSS classes are consistently sorted by the prettier-plugin-tailwindcss plugin and prevents conflicts between formatting and linting tools.\n\n### Shared Prettier Configuration\n\nThis project uses a single, shared Prettier configuration at the root of the monorepo. Individual packages **should not** include their own `.prettierrc` files. The root configuration includes:\n\n- Common code style settings (single quotes, semi-colons, etc.)\n- Tailwind CSS class sorting via prettier-plugin-tailwindcss\n- Configuration for special utility functions like `cva`, `cn`, `clsx`, and `twMerge`\n\nTo format all packages:\n\n```bash\npnpm format\n```\n\n### Import Sorting\n\nImports are automatically sorted in the following order:\n\n1. React and related packages\n2. External packages\n3. Internal packages (alias imports starting with `@/`)\n4. Parent imports (starting with `..`)\n5. Other relative imports (starting with `.`)\n6. Style imports\n7. Type imports\n\nThis ordering is enforced by ESLint and automatically fixed on commit.\n\n## Dependency Management\n\nThis project uses several tools to manage dependencies effectively:\n\n- **pnpm**: Fast, disk space efficient package manager\n- **check-deps script**: Custom utility to identify deprecated dependencies\n- **update-deps script**: Easily update all dependencies to their latest versions\n- **Dependencies workflow**: Regular checks for outdated dependencies\n- **Update Dependencies workflow**: Weekly automated updates\n\n### Exported Package Versions\n\nThe versions of internal `@openzeppelin/` packages used in exported forms are centrally managed in the `apps/builder/src/export/versions.ts` file. This ensures that all exported projects use stable, tested, and reproducible dependency versions.\n\nTo update these versions to the latest published releases, run the following command from the root of the monorepo:\n\n```bash\npnpm update-export-versions\n```\n\nThis script will fetch the latest versions from the npm registry and update the `versions.ts` file automatically.\n\n### Checking for Outdated Dependencies\n\nTo see which dependencies are outdated:\n\n```bash\npnpm outdated\n```\n\n### Updating Dependencies\n\nFor regular updates (respecting semver):\n\n```bash\npnpm update-deps\n```\n\nFor major version updates (may include breaking changes):\n\n```bash\npnpm update-deps:major\n```\n\n### Automated Updates\n\nThe project is configured with:\n\n1. **Update Dependencies workflow**: Runs weekly to check for and apply updates\n\n## Adding New Adapters\n\nNew adapter packages should be created in\n[openzeppelin-adapters](https://github.com/OpenZeppelin/openzeppelin-adapters), not in this\nrepository.\n\nTo add support for a new ecosystem end-to-end:\n\n1. Implement and publish the adapter from `openzeppelin-adapters` under `@openzeppelin/adapter-*`.\n2. Register the new package in `apps/builder/src/core/ecosystemManager.ts`.\n3. Update export configuration and tests so generated apps include the new package correctly.\n4. Verify the Builder app still builds and exports successfully.\n\n## Commit Convention\n\nThis project follows [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). See [COMMIT_CONVENTION.md](./COMMIT_CONVENTION.md) for\nmore details.\n\nExample:\n\n```text\nfeat(ui): add button component\n```\n\n## Contributing\n\nPlease read [CONTRIBUTING.md](./CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.\n\n## Security\n\nPlease read [SECURITY.md](./SECURITY.md) for details on our security policy and how to report vulnerabilities.\n\n## License\n\nThis project is licensed under the GNU Affero General Public License v3.0 - see the [LICENSE](./LICENSE) file for details.\n\n## CI/CD Pipeline\n\nThis project uses GitHub Actions for continuous integration and delivery:\n\n- **CI Workflow**: Runs tests, linting, and type checking\n- **Coverage Workflow**: Generates and uploads test coverage reports\n- **Staging / production**: Docker images are built and deployed via `.github/workflows/docker-stg.yaml` and `docker-prod.yaml`\n- **Security Workflow**: Checks for security vulnerabilities\n- **Dependencies Workflow**: Checks for outdated dependencies\n\nShared libraries (`@openzeppelin/ui-*`, `@openzeppelin/adapter-*`, etc.) are published from their own repositories; this repo ships the Builder web app only.\n\n## Monorepo Configuration\n\nThis project uses a centralized configuration approach to maintain consistency across all packages:\n\n### Shared Configurations\n\n- **tailwind.config.cjs**: Root configuration for Tailwind CSS, used by all packages\n- **postcss.config.cjs**: Root configuration for PostCSS, used by all packages\n- **components.json**: Root configuration for shadcn/ui components, referenced by packages\n\nPackages consume these root configs via:\n\n- JS proxy files (`packages/*/tailwind.config.cjs` and `packages/*/postcss.config.cjs`) that require the root configs\n- Per-package `components.json` files (regular JSON) that reference the package CSS entry (e.g., `../styles/global.css`)\n\nDuring the export process, proxy configs and JSON are included to create standalone configuration files for the exported project.\n\n## Runtime Configuration\n\nBoth the main UI Builder application and its exported forms support runtime configuration for certain parameters. This is primarily managed via an `AppConfigService` and allows customization without rebuilding the application code.\n\n### Builder Application Configuration (Development)\n\nDuring development of the builder application, configurations are typically provided via Vite environment variables defined in `.env` files (e.g., `.env.local`). These variables usually follow a prefix like `VITE_APP_CFG_...`.\n\nKey configurable items include:\n\n- **Explorer API Keys:** For services like Etherscan, PolygonScan, Routescan, etc., used by adapters to fetch ABIs. Two patterns are supported:\n  - Per-network keys: `VITE_APP_CFG_API_KEY_\u003cIDENTIFIER\u003e=\"your_key\"` (e.g., `VITE_APP_CFG_API_KEY_ETHERSCAN_MAINNET`)\n  - Global service keys: `VITE_APP_CFG_SERVICE_\u003cSERVICE\u003e_API_KEY=\"your_key\"` (e.g., `VITE_APP_CFG_SERVICE_ETHERSCANV2_API_KEY` for unified Etherscan V2, or `VITE_APP_CFG_SERVICE_ROUTESCAN_API_KEY` for Routescan)\n- **WalletConnect Project ID:** For EVM adapter's WalletConnect functionality. Example: `VITE_APP_CFG_SERVICE_WALLETCONNECT_PROJECT_ID=\"your_id\"`.\n- **RPC URL Overrides:** To use custom RPC endpoints instead of public defaults for specific networks. Example: `VITE_APP_CFG_RPC_ENDPOINT_ETHEREUM_MAINNET=\"https://your_custom_rpc.com\"`.\n- **Indexer Endpoint Overrides:** To configure GraphQL indexer endpoints for historical blockchain data queries (e.g., access control events). Example: `VITE_APP_CFG_INDEXER_ENDPOINT_STELLAR_TESTNET=\"https://your_indexer.com/graphql\"`.\n\n### Exported Application Configuration\n\nExported forms include a `public/app.config.json` file. Users of the exported form should edit this file to provide their own API keys and RPC URLs.\n\nThe structure of this JSON file includes sections for:\n\n- `networkServiceConfigs`: For per-network explorer API keys, keyed by a service identifier (e.g., `\"etherscan-mainnet\"`).\n- `globalServiceConfigs`: For global service parameters (e.g., `walletconnect.projectId`) and unified explorer API keys (e.g., `etherscanv2.apiKey` for Etherscan V2, `routescan.apiKey` for Routescan).\n- `rpcEndpoints`: For RPC URL overrides, keyed by the network ID (e.g., `\"ethereum-mainnet\"`).\n- `indexerEndpoints`: For indexer endpoint overrides, keyed by the network ID (e.g., `\"stellar-testnet\"`). Values can be strings (HTTP URL) or objects with `http` and `ws` properties.\n\nRefer to the README included with the exported application for detailed instructions on configuring `public/app.config.json`.\n\n\u003c!-- Adapter-specific guides are documented in their respective package READMEs. --\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenzeppelin%2Fui-builder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenzeppelin%2Fui-builder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenzeppelin%2Fui-builder/lists"}