Skip to content

feat!: migrate UI Builder to composer profile runtime#382

Merged
pasevin merged 26 commits into
mainfrom
001-capability-adapters
Apr 3, 2026
Merged

feat!: migrate UI Builder to composer profile runtime#382
pasevin merged 26 commits into
mainfrom
001-capability-adapters

Conversation

@pasevin

@pasevin pasevin commented Apr 2, 2026

Copy link
Copy Markdown
Collaborator

Summary

Migrates the UI Builder app from monolithic ContractAdapter consumption to the composer profile runtime from the capability-based adapter architecture.

What changed

  • ecosystemManager.ts — uses ecosystemDefinition.createRuntime('composer', networkConfig) instead of constructing adapter classes
  • React hooks and components — all callsites consume narrow capability interfaces from EcosystemRuntime instead of ContractAdapter
  • Export system — code templates and bootstrap generation updated for runtime-based apps
  • BuilderAdapter compatibility layer removed — no more flattened adapter surface
  • Documentation — README, CONTRIBUTING.md, and constitution updated for capability-based guidance

Cross-repo coordination

Merge order:

  1. openzeppelin-adapters — adapter packages with capability exports
  2. openzeppelin-ui — shared UI packages with capability props
  3. ui-builder (this PR)
  4. role-manager — consumer app migration

Test plan

  • Builder app builds and runs against local adapter/UI tarballs
  • Existing test suite passes (pnpm test)
  • Export system generates valid apps with runtime-based templates
  • CI passes on this branch

pasevin added 8 commits April 1, 2026 00:15
Migrate builder consumers and exports onto composer runtimes and the shared
builder runtime adapter. Keep legacy createAdapter compatibility for follow-on
ecosystems so Moonbeam and other not-yet-migrated adapters can still load
without retry loops.
Align documentation and comments with the capability-adapters architecture:
AdapterProvider → RuntimeProvider, activeAdapter → activeRuntime,
getAdapter → getRuntime, AdapterContext → RuntimeContext.
…e locally

Require createRuntime in ecosystemManager; update tests.

Extend pnpmfile for adapter-evm-core local dev.
Migrate all production code and tests from the flattened
BuilderAdapter interface to capability-qualified BuilderRuntime
access. Remove BuilderAdapter type, toBuilderAdapter(),
getAdapter(), and the activeAdapter/isAdapterLoading aliases.
Add focused toTransactionFormCapabilities() bridge for the
renderer's TransactionForm component.
Drop the local EcosystemExport bootstrap shim now that the shared
contract owns getExportBootstrapFiles.
Update the builder README and contribution guide to describe capability-based
adapters, ecosystemDefinition, and createRuntime instead of ContractAdapter.
@pasevin
pasevin requested a review from a team as a code owner April 2, 2026 14:39
pasevin added 8 commits April 2, 2026 17:44
Updates dependency ranges for ui-components, ui-react, ui-renderer,
ui-types, and ui-utils. Regenerates export snapshots and version
tracking to match.
* fix(ci): include adapters-vite in staging RC resolution

adapters-vite was not resolved during staging Docker builds, so it
stayed at the lockfile version while runtime adapter packages were
overridden to their RC versions. Add it to a dedicated
STAGING_ADAPTER_PACKAGES list in resolve-staging-adapters.cjs
(separate from ADAPTER_PACKAGES which drives versions.ts sync).

* chore(tests): update export snapshot
Bump all @openzeppelin/adapter-* and adapters-vite dependencies to
^2.0.0 for the capability adapters migration.

Extend .pnpmfile.cjs to widen adapter caret ranges to include
pre-release versions during resolution, so pnpm can resolve to RC
packages when the stable version hasn't shipped yet. Once stable
2.0.0 is published, pnpm naturally resolves to it instead.
- Add `contractLoading` capability to mock BuilderRuntime objects in
  deepLinkDedupe and manualAbiLoad tests
- Update adapter type assertions from BuilderAdapter to ContractAdapter
- Regenerate export snapshots for new adapter version ranges
Replace runtime-based template with class-based ContractAdapter pattern,
remove unused BuilderAdapter wrapper, and update docs to reflect new
adapter registration approach.
… packages

The templates were incorrectly updated to reference ContractAdapter and
AdapterProvider which don't exist in the published @openzeppelin/ui-types
and @openzeppelin/ui-react packages. Reverts to the runtime-based API
(RuntimeProvider, ecosystemDefinition.createRuntime, BuilderAdapter) while
removing the unused _adapter variable that caused TS6133 in E2E tests.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Migrates the Builder app from the monolithic ContractAdapter surface to the capability-based composer runtime profile, aligning in-app contract loading/form generation, network management, and export assembly with EcosystemExport.createRuntime('composer', ...).

Changes:

  • Replace adapter usage across Builder services, hooks, and UI components with BuilderRuntime capability access (e.g., runtime.schema, runtime.typeMapping, runtime.contractLoading).
  • Update export assembly to use runtime + ecosystem definition for wallet config and bootstrap file generation; bump exported dependency pins to @openzeppelin/ui-* 2.0.0.
  • Extend local-dev / staging tooling: adapter prerelease resolution in .pnpmfile.cjs and staging install script includes @openzeppelin/adapters-vite.

Reviewed changes

Copilot reviewed 80 out of 82 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
scripts/resolve-staging-adapters.cjs Include @openzeppelin/adapters-vite when resolving staging adapter packages.
apps/builder/src/services/FormGenerator.ts Switch field generation/type mapping from adapter methods to runtime capabilities.
apps/builder/src/services/ContractLoader.ts Route contract loading + metadata loading through runtime.contractLoading.
apps/builder/src/services/ContractDefinitionService.ts Use runtime-based loader orchestration in the definition service.
apps/builder/src/hooks/useContractDefinitionComparison.ts Compare definitions via runtime.contractLoading when supported.
apps/builder/src/hooks/useContractDefinition.ts Move from useWalletState().activeAdapter to builder runtime wallet state.
apps/builder/src/hooks/useBuilderWalletState.ts Add wrapper hook exposing runtime-centric wallet state fields.
apps/builder/src/export/versions.ts Bump exported @openzeppelin/ui-* dependency pins to 2.0.0 (and storage to 1.2.1).
apps/builder/src/export/templates/typescript-react-vite/package.json Update template dependencies to @openzeppelin/ui-* ^2.0.0.
apps/builder/src/export/codeTemplates/app-component.template.tsx Update exported app template to cache runtime and adapt it for the form.
apps/builder/src/export/assemblers/generateAdapterSpecificFiles.ts Export wallet config files via runtime.uiKit capability.
apps/builder/src/export/assemblers/generateAdapterBootstrapFiles.ts Generate bootstrap files via EcosystemExport.getExportBootstrapFiles.
apps/builder/src/export/AppExportSystem.ts Resolve runtime + ecosystem definition during export; pass both into assembly.
apps/builder/src/export/tests/FormComponentTests.test.ts Minor expectation/comment updates for generated form component props.
apps/builder/src/export/tests/snapshots/ExportSnapshotTests.test.ts.snap Update snapshots for new exported app component + dependency pins.
apps/builder/src/core/runtimeAdapter.ts Add runtime→TransactionFormCapabilities flattening shim for renderer compatibility.
apps/builder/src/core/networks/service.ts Cache and return runtimes instead of adapters in NetworkService.
apps/builder/src/core/factories/FormSchemaFactory.ts Generate transforms/fields via runtime capabilities rather than adapter.
apps/builder/src/core/factories/tests/FormSchemaFactory.test.ts Update schema factory tests to mock nested runtime capabilities.
apps/builder/src/core/factories/tests/EVMAdapterIntegration.test.ts Update integration test to use runtime capability surfaces.
apps/builder/src/core/ecosystemManager.ts Introduce getRuntime using createRuntime('composer', ...); keep ecosystem definition access.
apps/builder/src/core/tests/ecosystemManager.test.ts Add tests verifying createRuntime('composer', ...) is invoked and runtime surface exists.
apps/builder/src/components/UIBuilder/StepFunctionSelector/WritableFunctionsSection.tsx Fetch function decorations from runtime.schema.
apps/builder/src/components/UIBuilder/StepFunctionSelector/types.ts Replace adapter prop types with runtime.
apps/builder/src/components/UIBuilder/StepFunctionSelector/StepFunctionSelector.tsx Thread runtime prop into writable function section.
apps/builder/src/components/UIBuilder/StepFormCustomization/utils/runtime-secret-helpers.ts Doc updates to runtime terminology for secret field metadata helper.
apps/builder/src/components/UIBuilder/StepFormCustomization/utils/fieldTypeUtils.ts Drive compatible field types from runtime.typeMapping.
apps/builder/src/components/UIBuilder/StepFormCustomization/utils/executionUtils.ts Validate addresses via runtime.addressing and update validator map types.
apps/builder/src/components/UIBuilder/StepFormCustomization/TypeWarningSection.tsx Compute recommended type via runtime.typeMapping.
apps/builder/src/components/UIBuilder/StepFormCustomization/types.ts Replace adapter props with runtime props across execution configuration types.
apps/builder/src/components/UIBuilder/StepFormCustomization/ResponsiveFieldsLayout.tsx Pass runtime through to field editor components.
apps/builder/src/components/UIBuilder/StepFormCustomization/index.tsx Use runtime wallet state; update error/loading UI to runtime wording.
apps/builder/src/components/UIBuilder/StepFormCustomization/hooks/useGetFunctionNote.ts Load function notes from runtime.schema.getFunctionDecorations.
apps/builder/src/components/UIBuilder/StepFormCustomization/hooks/useFormConfig.ts Generate/update form config using runtime; auto-add runtime secret field via runtime binding.
apps/builder/src/components/UIBuilder/StepFormCustomization/hooks/useExecutionMethodState.ts Fetch supported execution methods from runtime.execution and validate via runtime.
apps/builder/src/components/UIBuilder/StepFormCustomization/FormPreview.tsx Adapt runtime to renderer capabilities with toTransactionFormCapabilities.
apps/builder/src/components/UIBuilder/StepFormCustomization/FieldEditor.tsx Replace adapter prop threading with runtime for type selection/warnings.
apps/builder/src/components/UIBuilder/StepFormCustomization/FieldBasicSettings.tsx Use DynamicFormField with addressing/typeMapping capabilities instead of adapter.
apps/builder/src/components/UIBuilder/StepFormCustomization/FieldAdvancedSettings.tsx Read runtime secret binding config from runtime.typeMapping.
apps/builder/src/components/UIBuilder/StepFormCustomization/ExecutionMethodSettings.tsx Runtime-based execution method settings wiring.
apps/builder/src/components/UIBuilder/StepFormCustomization/components/UiKitSettings.tsx List/configure UI kits via runtime.uiKit; pass capabilities to dynamic fields.
apps/builder/src/components/UIBuilder/StepFormCustomization/components/RuntimeSecretButton.tsx Re-add runtime secret field using runtime.typeMapping.getRuntimeFieldBinding.
apps/builder/src/components/UIBuilder/StepFormCustomization/components/RelayerConfiguration/index.tsx Update relayer flow to use runtime.relayer/runtime.uiKit capabilities.
apps/builder/src/components/UIBuilder/StepFormCustomization/components/RelayerConfiguration/hooks/useRelayerFetch.ts Fetch relayers via runtime.relayer.getRelayers.
apps/builder/src/components/UIBuilder/StepFormCustomization/components/RelayerConfiguration/hooks/useRelayerDetails.ts Load rich relayer details via runtime.relayer.getRelayer.
apps/builder/src/components/UIBuilder/StepFormCustomization/components/RelayerConfiguration/hooks/useRelayerConfiguration.ts Update relayer configuration hook types to runtime.
apps/builder/src/components/UIBuilder/StepFormCustomization/components/RelayerConfiguration/components/RelayerSelectionCard.tsx Use runtime.uiLabels for relayer details card labeling.
apps/builder/src/components/UIBuilder/StepFormCustomization/components/RelayerConfiguration/components/RelayerGasConfigurationCard.tsx Render relayer options component via runtime.uiKit.
apps/builder/src/components/UIBuilder/StepFormCustomization/components/PrimaryMethodSelector.tsx Runtime availability/prop naming updates for selector + panels.
apps/builder/src/components/UIBuilder/StepFormCustomization/components/EoaConfiguration.tsx Validate/format address inputs via runtime.addressing.
apps/builder/src/components/UIBuilder/StepFormCustomization/tests/UiKitSettings.test.tsx Update UI kit settings tests to runtime-shaped mocks.
apps/builder/src/components/UIBuilder/StepContractDefinition/types.ts Replace adapter types with runtime in contract definition step types.
apps/builder/src/components/UIBuilder/StepContractDefinition/StepContractDefinition.tsx Load contract inputs/health checks/loader wiring via runtime.
apps/builder/src/components/UIBuilder/StepContractDefinition/hooks/useNetworkServiceHealthCheck.ts Test network services via runtime.relayer defaults + probes.
apps/builder/src/components/UIBuilder/StepContractDefinition/hooks/useFormSync.ts Sync required artifact inputs via runtime.contractLoading.getContractDefinitionInputs.
apps/builder/src/components/UIBuilder/StepContractDefinition/hooks/useContractLoader.ts Load schema+metadata via runtime; gate loads via runtime-required inputs + address validation.
apps/builder/src/components/UIBuilder/StepContractDefinition/hooks/useContractForm.ts Validate manual ABI/IDL definitions via runtime.contractLoading.validateContractDefinition.
apps/builder/src/components/UIBuilder/StepContractDefinition/hooks/useAutoContractLoad.ts Block auto-load until runtime-required inputs are present.
apps/builder/src/components/UIBuilder/StepContractDefinition/components/ContractSuccessStatus.tsx Build explorer links using runtime.explorer.
apps/builder/src/components/UIBuilder/StepContractDefinition/components/ContractFormFields.tsx Render contract definition inputs via capabilities-based DynamicFormField.
apps/builder/src/components/UIBuilder/StepContractDefinition/tests/useNetworkServiceHealthCheck.test.tsx Update health check tests to runtime relayer capability mocks.
apps/builder/src/components/UIBuilder/StepContractDefinition/tests/useContractForm.reset-guard.test.tsx Update reset-guard test to runtime prop naming.
apps/builder/src/components/UIBuilder/StepContractDefinition/tests/manualAbiLoad.test.tsx Update manual ABI dedupe test to mock builder runtime wallet state.
apps/builder/src/components/UIBuilder/StepContractDefinition/tests/deepLinkDedupe.test.tsx Update deep-link dedupe test to mock builder runtime wallet state.
apps/builder/src/components/UIBuilder/StepChainSelection/components/NetworkSelectionPanel.tsx Use runtime context and pass relayer capability to network settings dialog.
apps/builder/src/components/UIBuilder/index.tsx Thread runtime into wizard steps; update contract widget + network switching to capability props.
apps/builder/src/components/UIBuilder/hooks/useUIBuilderState.ts Convert UI builder state orchestration to runtime wallet state and runtime-required input gating.
apps/builder/src/components/UIBuilder/hooks/useContractWidgetState.ts Determine view functions and widget props via runtime.schema.
apps/builder/src/components/UIBuilder/hooks/builder/useBuilderNetwork.ts Auto-advance chain selection once runtime is ready.
apps/builder/src/components/UIBuilder/hooks/builder/useBuilderContract.ts Trim/persist artifacts using runtime.contractLoading policies and helpers.
apps/builder/src/components/UIBuilder/hooks/builder/useBuilderConfig.ts Reconfigure UI kit via runtime wallet state helper.
apps/builder/src/components/UIBuilder/hooks/builder/useAutoSave.ts Respect runtime artifact persistence policy and remove non-serializable artifacts pre-save.
apps/builder/src/components/Common/NetworkErrorHandler.tsx Open network settings with relayer capability via runtime context.
apps/builder/src/components/AddressBook/AddressBookDialog.tsx Resolve explorer URLs and address validation via runtime capabilities.
apps/builder/src/App.tsx Replace AdapterProvider with RuntimeProvider and resolve runtimes via getRuntime.
apps/builder/README.md Update documentation to runtime-based provider and capability terminology.
apps/builder/package.json Bump adapter/ui package deps to ^2.0.0 and @openzeppelin/adapters-vite to ^2.0.0.
apps/builder/CHANGELOG.md Update changelog wording to avoid ContractAdapter references in migrated context.
.specify/memory/constitution.md Update architecture constitution to codify runtime/capability-based guidance.
.pnpmfile.cjs Add prerelease-friendly semver rewrite for @openzeppelin/adapter* deps; extend local adapter package map.
.gitignore Ignore .collaborator file.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)

apps/builder/src/export/assemblers/generateAdapterBootstrapFiles.ts:69

  • Logging/messages still refer to an "adapter" even though this function now operates on an EcosystemExport/runtime-based bootstrap. This is misleading when troubleshooting export issues; rename the log strings (and any remaining wording) to "ecosystem" or "runtime" to match the new API surface.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/builder/src/export/codeTemplates/app-component.template.tsx
Comment thread apps/builder/src/core/runtimeAdapter.ts
- Pass effectiveRuntime (prop-or-wallet-state fallback) to useFormConfig
  so form generation works when runtime is passed via props while wallet
  state runtime is null.
- Remove configInitialized.current from useEffect dependency array since
  ref mutations don't trigger re-renders and the guard is handled inside
  the effect body.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 85 out of 87 changed files in this pull request and generated 10 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)

apps/builder/src/export/assemblers/generateAdapterBootstrapFiles.ts:69

  • Log messages still refer to "Adapter" even though this function now operates on an ecosystem definition (EcosystemExport). Update the messages to avoid confusion when debugging export bootstrap behavior (e.g., "Ecosystem returned no bootstrap files" / "from ecosystem").

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/builder/src/export/codeTemplates/main.template.tsx
Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread apps/builder/src/export/versions.ts
Comment thread apps/builder/src/export/codeTemplates/form-component.template.tsx
Comment thread .specify/memory/constitution.md Outdated
- Add missing getFunctionDecorations binding to template's toBuilderAdapter
  shim to stay in sync with runtimeAdapter.ts
- Add @ts-expect-error for placeholder import in main.template.tsx
- Fix markdown formatting in README (broken backtick-glob patterns,
  links wrapped in code spans)
- Update comment wording from "Adapter defaults" to "Runtime defaults"
  in useNetworkServiceHealthCheck
- Rename adapter -> runtime variable in EVMAdapterIntegration test
- Update constitution.md wording to reference capability-based API

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 85 out of 87 changed files in this pull request and generated 4 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .pnpmfile.cjs
Comment thread apps/builder/src/export/AppExportSystem.ts Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated
- Use execFileSync in resolve-staging-adapters to eliminate shell
  injection vectors; add dist-tag regex validation
- Dispose runtime immediately after extracting addressing capability in
  AddressBookDialog.resolveAddressing to prevent resource leaks

Mirrors fixes applied to role-manager in 42b5415.
pasevin added 2 commits April 3, 2026 16:03
- Wrap export flow in try/finally to dispose the runtime after project
  generation, preventing resource leaks in long-lived Builder sessions.
- Widen .pnpmfile.cjs prerelease rewrite to also cover adapters-vite.
- Fix remaining broken backtick-glob patterns in README.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 85 out of 87 changed files in this pull request and generated 4 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)

apps/builder/src/export/assemblers/generateAdapterBootstrapFiles.ts:69

  • This helper now accepts ecosystemDefinition (not an adapter instance), but several log lines/messages still say “Adapter …” / “from adapter”. Updating these strings will avoid confusion when debugging export assembly (especially now that bootstrap files come from the EcosystemExport, not a runtime instance).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/builder/src/components/AddressBook/AddressBookDialog.tsx Outdated
Comment thread apps/builder/src/export/versions.ts
Comment thread README.md Outdated
Comment thread README.md Outdated
pasevin added 2 commits April 3, 2026 16:21
Strip build metadata (+...) before parsing and validate that
major/minor/patch are finite numbers to avoid silent NaN comparisons.
…tting

- Keep the runtime alive in resolveAddressing so the addressing
  capability isn't invalidated before AddressBookWidget uses it.
  Return a wrapper that disposes the runtime on explicit dispose().
- Fix README markdown: indent continuation line under bullet,
  properly nest fenced code blocks under ordered list items.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 85 out of 87 changed files in this pull request and generated 5 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated
pasevin added 2 commits April 3, 2026 16:50
- pickBestVersion only prefers latest over rc when latest is a stable
  (non-prerelease) release, preventing incorrect downgrades
- allowAdapterPrereleases now computes correct caret ceiling for 0.x
  ranges (^0.3.0 -> <0.4.0 instead of <1.0.0)
- Widened prerelease match to include @openzeppelin/adapters-* packages
@pasevin
pasevin merged commit 110059c into main Apr 3, 2026
13 checks passed
@pasevin
pasevin deleted the 001-capability-adapters branch April 3, 2026 14:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants