Skip to content

feat!: migrate shared UI packages to capability-based runtime APIs#113

Merged
pasevin merged 14 commits intomainfrom
001-capability-adapters
Apr 2, 2026
Merged

feat!: migrate shared UI packages to capability-based runtime APIs#113
pasevin merged 14 commits intomainfrom
001-capability-adapters

Conversation

@pasevin
Copy link
Copy Markdown
Collaborator

@pasevin pasevin commented Apr 2, 2026

Summary

Migrates all shared UI packages from the monolithic ContractAdapter surface to the new capability-based runtime architecture introduced in openzeppelin-adapters.

What changed

  • @openzeppelin/ui-types — Replace ContractAdapter, FullContractAdapter, and ContractStateCapabilities with 13 capability interfaces, profile runtime types, EcosystemRuntime, CapabilityFactoryMap, and updated EcosystemExport
  • @openzeppelin/ui-reactRuntimeProvider / AdapterProvider now manages EcosystemRuntime instances; WalletStateProvider consumes narrow capability props; new wallet session registry for ecosystem-scoped provider caching; safe runtime handoff on network switches
  • @openzeppelin/ui-renderer — All component props migrated from ContractAdapter to narrow capability interfaces
  • @openzeppelin/ui-components — Component props updated for capability-based consumption
  • @openzeppelin/ui-utils — Helper functions updated to accept capability interfaces
  • @openzeppelin/ui-dev-cli — pnpmfile family data derived from canonical source; local adapter dev support
  • Example appbasic-react-app fully migrated to runtime/capability consumption pattern
  • Documentation — READMEs and inline docs aligned with capability terminology

Packages affected

Package Change
@openzeppelin/ui-types major — capability interfaces replace ContractAdapter
@openzeppelin/ui-react major — runtime-oriented provider and hooks
@openzeppelin/ui-renderer major — capability-based component props
@openzeppelin/ui-components major — capability-based component props
@openzeppelin/ui-utils major — capability-based helper signatures
@openzeppelin/ui-dev-cli patch — pnpmfile and local dev fixes

Cross-repo coordination

Merge and publish order:

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

Test plan

  • All packages pass pnpm test and format checks
  • Example app builds and runs with local adapter tarballs
  • CI passes on this branch
  • Changesets cover all breaking changes

pasevin added 13 commits March 31, 2026 08:55
Implements capability-based adapter architecture (US4 / Phase 2): 13 tiered
capabilities, profile runtime types, EcosystemRuntime, CapabilityFactoryMap,
runtime errors, and updated EcosystemExport. Removes ContractAdapter and
related types; shared primitives live in adapters/common.

Adds major changeset for @openzeppelin/ui-types.
replace shared ui adapter dependencies with narrow capability and runtime apis
so each package surface only requires the behavior it actually consumes.

add shared capability bundle aliases and a major changeset for the published
packages affected by the phase.

BREAKING CHANGE: shared ui packages now expose capability-based props and
runtime-oriented react exports instead of ContractAdapter and
FullContractAdapter interfaces.
Move the basic React example from ContractAdapter usage to profile-based
runtimes and capability helpers, and align wallet and ui-kit APIs with partial
ui-kit configuration. Update the shared local-dev pnpm hook to resolve internal
adapter workspace packages so the example app can run against local adapters
again.
Switch the basic example app onto the shared adapters-vite helper and add a
changeset for the local-dev and ui-kit runtime follow-up updates across
ui-dev-cli, ui-react, and ui-types.
…r caching

Introduce WalletSessionRegistry to cache provider components and facade
hooks per ecosystem, preventing wallet provider remounts on same-ecosystem
network switches. Extend DerivedAccountStatus with isConnecting,
isDisconnected, isReconnecting, and status fields. Add cross-ecosystem
transition detection to WalletConnectionUI and useWalletComponents to
suppress stale UI during ecosystem switches. Clean up verbose debug
logging in wallet connection components.
Add releaseRuntime to RuntimeProvider so WalletStateProvider can
dispose superseded runtimes after the replacement has been fully
loaded, UI-kit configured, and promoted to activeRuntime. This
prevents stale runtimes from accumulating in the registry while
preserving the ecosystem-scoped wallet session across switches.
React 19's development-mode commit phase introspects old prop values
via addObjectDiffToProperties. When a disposed runtime's proxy trap
throws RuntimeDisposedError on property access, this crashes the
commit. Deferring dispose() to the next macrotask via setTimeout(fn, 0)
lets React finish its commit cycle before the proxy becomes hostile.
… terminology

Replace leftover "adapter" references in code snippets, comments,
and UI copy with the current capability-based naming (runtime,
capabilities, contractLoading, typeMapping, relayer, etc.).
…ruth

Serialize pnpmfile STANDARD_FAMILIES from families.ts at generation
time instead of hardcoding a duplicate copy in the template string.
Extend tidy-clocks-repair changeset to cover deriving pnpmfile
STANDARD_FAMILIES from families.ts.
Restore the shared build-time bootstrap hook on EcosystemExport so
consumers and adapters can rely on the common contract instead of
local type extensions.
Refresh adapter-facing type documentation and export comments to reflect the
capability-based runtime model.

Also update the wallet state context note so its bundled-adapter example uses
the current adapter package namespace.
@pasevin pasevin requested a review from a team as a code owner April 2, 2026 14:39
@pasevin pasevin requested a review from Copilot April 2, 2026 14:59
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Migrates shared UI packages from the legacy monolithic ContractAdapter API to the new capability-based runtime model (EcosystemRuntime + per-capability interfaces), aligning components, utilities, docs, and the example app with profile-scoped capability consumption.

Changes:

  • Replaces adapter-shaped props and helpers with narrow capability interfaces across renderer/components/utils.
  • Introduces EcosystemRuntime, capability factory maps, profile runtime types, and new capability bundles in @openzeppelin/ui-types.
  • Updates @openzeppelin/ui-react to manage runtimes (provider/contexts/hooks), adds a wallet session registry, and updates the example app to the new runtime pattern.

Reviewed changes

Copilot reviewed 119 out of 120 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/utils/src/requiredInputs.ts Switches required-input snapshot logic to ContractLoadingCapability.
packages/utils/src/contractInputs.ts Migrates missing-required-input detection to ContractLoadingCapability.
packages/utils/src/tests/contractInputs.test.ts Updates utility tests to stub ContractLoadingCapability.
packages/types/src/forms/fields.ts Introduces TransactionFormCapabilities and updates TransactionFormProps to use capability intersections.
packages/types/src/common/index.ts Re-exports new capability-bundles module.
packages/types/src/common/capability-bundles.ts Adds shared capability intersection aliases and prop fragments.
packages/types/src/common/address-book-widget.ts Migrates address book widget props from adapter to addressing capability + resolver.
packages/types/src/adapters/runtime.ts Adds RuntimeCapability, EcosystemRuntime, and CapabilityFactoryMap types.
packages/types/src/adapters/profiles/viewer.ts Adds viewer profile runtime type.
packages/types/src/adapters/profiles/transactor.ts Adds transactor profile runtime type.
packages/types/src/adapters/profiles/profile-name.ts Adds ProfileName union for runtime creation.
packages/types/src/adapters/profiles/operator.ts Adds operator profile runtime type.
packages/types/src/adapters/profiles/index.ts Exports profile runtime types and ProfileName.
packages/types/src/adapters/profiles/declarative.ts Adds declarative profile runtime type.
packages/types/src/adapters/profiles/composer.ts Adds composer profile runtime type.
packages/types/src/adapters/index.ts Reworks adapter exports to capability/runtime-based surface and removes FullContractAdapter.
packages/types/src/adapters/export.ts Updates export bootstrap docs to refer to runtime/capability surface.
packages/types/src/adapters/errors.ts Adds runtime lifecycle errors (RuntimeDisposedError, UnsupportedProfileError).
packages/types/src/adapters/ecosystem-export.ts Updates EcosystemExport to expose capability factories and createRuntime.
packages/types/src/adapters/contract-state.ts Removes legacy ContractStateCapabilities.
packages/types/src/adapters/common.ts Adds shared adapter primitives for capabilities (connectors, type mapping metadata, etc.).
packages/types/src/adapters/capabilities/wallet.ts Adds wallet capability interface.
packages/types/src/adapters/capabilities/ui-labels.ts Adds UI labels capability interface.
packages/types/src/adapters/capabilities/ui-kit.ts Adds UI kit capability interface.
packages/types/src/adapters/capabilities/type-mapping.ts Adds type mapping capability interface.
packages/types/src/adapters/capabilities/schema.ts Adds schema capability interface (absorbs view-function helpers).
packages/types/src/adapters/capabilities/relayer.ts Adds relayer capability interface.
packages/types/src/adapters/capabilities/query.ts Adds query capability interface (absorbs view calls + formatting).
packages/types/src/adapters/capabilities/network-catalog.ts Adds network catalog capability interface.
packages/types/src/adapters/capabilities/index.ts Exports all capability interfaces.
packages/types/src/adapters/capabilities/explorer.ts Adds explorer capability interface.
packages/types/src/adapters/capabilities/execution.ts Adds execution capability interface.
packages/types/src/adapters/capabilities/contract-loading.ts Adds contract loading capability interface.
packages/types/src/adapters/capabilities/addressing.ts Adds addressing capability interface.
packages/types/src/adapters/capabilities/access-control.ts Adds access control capability interface.
packages/types/src/adapters/README.md Updates adapter docs to capability tiers + profiles + runtime model.
packages/types/README.md Updates package README to reflect runtime/capability types.
packages/renderer/src/utils/formUtils.ts Migrates address transforms and field transforms to AddressingCapability.
packages/renderer/src/utils/tests/formUtils.test.ts Updates renderer transform tests for AddressingCapability.
packages/renderer/src/components/transaction/TransactionStatusDisplay.tsx Migrates formatting/explorer linking to query + explorer capabilities.
packages/renderer/src/components/network/NetworkSettingsDialog.tsx Reworks network settings dialog to use RelayerCapability and external refresh callback.
packages/renderer/src/components/network/NetworkServiceSettingsPanel.tsx Migrates service form validation/testing to RelayerCapability.
packages/renderer/src/components/fieldRegistry.ts Changes field registry prop shape to DynamicFormContextProps.
packages/renderer/src/components/WalletConnectionWithSettings.tsx Uses runtime-based wallet state and reconfigures UI kit after settings changes.
packages/renderer/src/components/TransactionForm.tsx Passes specific capabilities (addressing, typeMapping, query, explorer, execution, relayer).
packages/renderer/src/components/ExecutionConfigDisplay/hooks/useExecutionValidation.ts Validates execution via ExecutionCapability.
packages/renderer/src/components/ExecutionConfigDisplay/components/RelayerConfigDetails.tsx Switches UI labels retrieval to activeRuntime.uiLabels.
packages/renderer/src/components/ExecutionConfigDisplay/ExecutionConfigDisplay.tsx Migrates execution config UI to execution + relayer capability props.
packages/renderer/src/components/DynamicFormField.tsx Migrates to DynamicFormContextProps and enforces typeMapping for nested generation.
packages/renderer/src/components/ContractStateWidget/components/ViewFunctionsPanel.tsx Migrates state queries to query and schema filtering to schema.
packages/renderer/src/components/ContractStateWidget/ContractStateWidget.tsx Migrates widget contract state logic to capability props.
packages/renderer/src/components/AddressBookWidget/AddressBookWidget.tsx Renames widget inputs to addressing + resolveAddressing.
packages/renderer/src/components/AddressBookWidget/AddAliasDialog.tsx Updates dialog to use addressing capability resolution per network.
packages/renderer/README.md Updates renderer documentation to capability-based props.
packages/react/src/index.ts Exports runtime-oriented provider/context/hook names.
packages/react/src/hooks/walletSessionRegistry.ts Adds ecosystem-scoped wallet session caching helpers.
packages/react/src/hooks/walletSessionRegistry.test.ts Adds unit tests for wallet session registry behavior.
packages/react/src/hooks/useWalletReconnectionHandler.ts Generalizes reconnection handler to any RuntimeCapability.
packages/react/src/hooks/useWalletComponents.ts Migrates wallet components resolution to runtime uiKit capability + cross-ecosystem guard.
packages/react/src/hooks/useDerivedAccountStatus.ts Expands derived wallet status shape and safe field extraction.
packages/react/src/hooks/useAdapterContext.ts Renames adapter context hook to useRuntimeContext.
packages/react/src/hooks/tests/useWalletComponents.test.tsx Updates hook tests for runtime + uiKit capability access.
packages/react/src/hooks/tests/useDerivedAccountStatus.test.tsx Adds test coverage for derived account status extraction/fallbacks.
packages/react/src/hooks/WalletStateContext.ts Migrates wallet state context from adapter to runtime terminology and fields.
packages/react/src/hooks/AdapterProvider.tsx Reworks provider to manage and dispose EcosystemRuntime instances; introduces releaseRuntime.
packages/react/src/hooks/AdapterContext.tsx Renames adapter registry/context types to runtime equivalents and adds releaseRuntime.
packages/react/src/components/WalletConnectionUI.tsx Migrates wallet UI to runtime uiKit capability with cross-ecosystem transition guard.
packages/react/src/components/WalletConnectionHeader.tsx Updates header skeleton logic to runtime loading state.
packages/react/src/components/NetworkSwitchManager.tsx Migrates network switching to WalletCapability + NetworkCatalogCapability inputs.
packages/react/README.md Updates public docs and examples to runtime providers/capabilities.
packages/dev-cli/src/lib/init.ts Derives pnpmfile family data from canonical STANDARD_FAMILIES and adds workspace fallback resolution.
packages/dev-cli/src/lib/init.test.ts Updates CLI tests for pnpmfile workspace fallback helpers.
packages/components/src/components/network-errors/useNetworkErrors.ts Migrates error reporting helper to accept RuntimeCapability.
packages/components/src/components/network-errors/NetworkErrorAwareAdapter.tsx Generalizes proxy wrapper to RuntimeCapability generics.
packages/components/src/components/fields/ObjectField.tsx Switches nested field generation to TypeMappingCapability.
packages/components/src/components/fields/ArrayObjectField.tsx Switches nested array-object generation to TypeMappingCapability.
packages/components/src/components/fields/AddressField.tsx Migrates address validation to AddressingCapability.
packages/components/src/components/contract-definition/ContractDefinitionSettingsPanel.tsx Migrates provider settings to ContractLoadingCapability.
examples/basic-react-app/src/utils/schemaMocking.ts Migrates preview schema mocking to TypeMappingCapability.
examples/basic-react-app/src/stores/index.ts Removes adapter selector export from store API.
examples/basic-react-app/src/stores/ecosystemStore.ts Makes ecosystem store runtime-agnostic; delegates runtime resolution to provider layer.
examples/basic-react-app/src/providers/AppProviders.tsx Switches app wiring to RuntimeProvider and runtime-derived demo capability bundle.
examples/basic-react-app/src/core/runtimeCapabilities.ts Adds demo helper to flatten runtime capabilities into a single object.
examples/basic-react-app/src/core/networkUtils.ts Reworks helpers to be runtime-led and adds addressing resolver.
examples/basic-react-app/src/core/ecosystemManager.ts Updates demo ecosystem loading to runtime creation/caching and runtime disposal on cache clear.
examples/basic-react-app/src/context/useEcosystem.ts Updates docs/examples to reference capabilities rather than adapter.
examples/basic-react-app/src/context/ecosystemContextDef.ts Updates context shape to include runtime and flattened demo capabilities.
examples/basic-react-app/src/context/EcosystemContext.tsx Updates standalone provider to load runtimes and derive demo capability bundle.
examples/basic-react-app/src/components/WalletDemo/config-loaders.ts Updates snippets to use reconfigureActiveUiKit.
examples/basic-react-app/src/components/WalletDemo/code-snippets.ts Updates tutorial snippets to reflect runtime + uiKit model.
examples/basic-react-app/src/components/WalletDemo/WalletStatusPanel.tsx Updates status panel to runtime-based state and isRuntimeLoading.
examples/basic-react-app/src/components/WalletDemo/WalletKitSwitcher.tsx Fetches kits via activeRuntime.uiKit and uses reconfigureActiveUiKit.
examples/basic-react-app/src/components/WalletDemo/WalletDemo.tsx Updates runtime terminology and UI kit reconfiguration calls.
examples/basic-react-app/src/components/WalletDemo/LearnSections.tsx Updates copy to runtime naming and new hook name.
examples/basic-react-app/src/components/TypeMappingDemo.tsx Migrates demo from adapter to capability bundle inputs.
examples/basic-react-app/src/components/RendererDemo.tsx Uses addressing + typeMapping demo capabilities for DynamicFormField.
examples/basic-react-app/src/components/NetworkDemo.tsx Migrates network demo settings to relayer capability usage.
examples/basic-react-app/src/components/HomeDemo.tsx Migrates address validation demo to capability-based validation.
examples/basic-react-app/src/components/FormFieldsDemo.tsx Migrates field demos to addressing capability prop.
examples/basic-react-app/src/components/EcosystemIndicator.tsx Updates loading copy to runtime naming.
examples/basic-react-app/src/components/ContractInteractionsDemo/utils.ts Migrates schema generation to TypeMappingCapability.
examples/basic-react-app/src/components/ContractInteractionsDemo/useContractLoader.ts Migrates contract loading hook to ContractLoadingCapability.
examples/basic-react-app/src/components/ContractInteractionsDemo/constants.ts Updates learning snippets to runtime/capability APIs.
examples/basic-react-app/src/components/ContractInteractionsDemo/LearnTab.tsx Updates documentation copy to reference capabilities instead of adapter methods.
examples/basic-react-app/src/components/ContractInteractionsDemo/ExecuteTransactionCard.tsx Uses TransactionFormCapabilities instead of adapter prop.
examples/basic-react-app/src/components/ContractInteractionsDemo/ContractLoadingCard.tsx Updates copy to reference contractLoading capability.
examples/basic-react-app/src/components/ContractInteractionsDemo/ContractInteractionsDemo.tsx Migrates demo to runtime + toTransactionFormCapabilities and passes query/schema capabilities.
examples/basic-react-app/src/components/ArchitectureDemo.tsx Updates architecture demo to RuntimeProvider + EcosystemRuntime model.
examples/basic-react-app/src/components/AddressDisplayDemo.tsx Uses explorer capability for explorer URLs.
examples/basic-react-app/src/components/AccountAliasDemo.tsx Migrates address book demo to addressing capability + runtime placeholders.
.specify/memory/constitution.md Updates constitution language to runtime/capability model and bumps version metadata.
.pnpmfile.cjs Adds workspace fallback package resolution for local-dev rewrites.
.changeset/tidy-clocks-repair.md Adds changeset for pnpmfile family derivation and local dev improvements.
.changeset/fresh-candles-learn.md Adds changeset for major capability/runtime migration across packages.
.changeset/capability-interface-types.md Adds changeset documenting @openzeppelin/ui-types breaking changes.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (3)

packages/renderer/src/components/transaction/TransactionStatusDisplay.tsx:1

  • The fallback explorer?.getExplorerUrl(txHash) is likely incorrect because getExplorerUrl is documented as an address URL resolver, not a transaction URL resolver. This can produce malformed links (or even a valid-but-wrong address link) when getExplorerTxUrl is not implemented. Suggestion (mandatory): only use getExplorerTxUrl for tx links; if it’s absent, fall back to the explicit explorerUrl prop (or null) rather than calling getExplorerUrl with a tx hash.
    .pnpmfile.cjs:1
  • This change now iterates over all dependencies and attempts workspace fallback resolution via directory scanning. Concretely, this can degrade install performance since resolvePackageDirectoryByName may traverse repoRoot/packages/* (and parse many package.json files) once per dependency key, including third-party deps that will never resolve. Suggestion (mandatory): restrict fallback resolution to known first-party scopes (e.g. @openzeppelin/) or to packages present in the packed manifest; and/or introduce a simple memo/cache map inside the pnpmfile for packageName -> resolvedPath|nil so each name is scanned at most once per run.
/**

packages/utils/src/contractInputs.ts:1

  • The docstring still refers to "adapter-declared" required inputs, but this utility now depends on ContractLoadingCapability. Suggestion (optional): update the comment to reflect capability terminology (e.g. "contract-loading capability-declared required inputs") to match the new public model and avoid confusion for consumers reading utility docs.

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

@pasevin pasevin merged commit 52f2823 into main Apr 2, 2026
15 of 16 checks passed
@pasevin pasevin deleted the 001-capability-adapters branch April 2, 2026 15:13
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 2, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants