You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Form preview and exported apps currently use TransactionForm → DynamicFormField → bare AddressField, which shows the simple ENS forward-resolution UX (inline “Resolved to 0x…” text + optional cross-network disclaimer — see screenshot in PR #401 discussion).
Builder-specific surfaces already use Pattern A (rich preview card with avatar via AddressFieldWithResolvedPreview + ResolvedAddressFieldPreviewWithNameResolution + useWatch), e.g.:
Address book Add Alias (internal to AddressBookWidget / AddAliasDialog in ui-renderer ≥3.4.0)
Gap: end-user transaction forms (preview + export) never take the rich path because packages/renderer/src/components/fieldRegistry.ts maps blockchain-address → AddressField.
We want a form-level builder setting so users can choose:
Mode
UX
rich (new default for new forms)
Pattern A preview card (name + avatar) below address inputs
simple (current behavior; preserve for existing exports)
Inline “Resolved to 0x…” announcer
Motivation
Parity between builder preview, exported apps, and rich ENS surfaces (address book, EOA config)
User control over visual density / branding
Safe rollout: existing saved/exported forms should not change appearance unless opted in
Architecture (constitution-compliant)
Per .specify/memory/constitution.mdPrinciple I (chain-agnostic, adapter-led):
Do NOT gate on ecosystem === 'evm' or chain id strings
Do use runtime capabilities: runtime?.nameResolution (NameResolutionCapability)
Feature detection is structural per ui-types: capability.resolveName, capability.resolveAddress
When capability is absent, components degrade gracefully (existing SF-3 behavior via empty NameResolver)
Summary
Form preview and exported apps currently use
TransactionForm→DynamicFormField→ bareAddressField, which shows the simple ENS forward-resolution UX (inline “Resolved to 0x…” text + optional cross-network disclaimer — see screenshot in PR #401 discussion).Builder-specific surfaces already use Pattern A (rich preview card with avatar via
AddressFieldWithResolvedPreview+ResolvedAddressFieldPreviewWithNameResolution+useWatch), e.g.:apps/builder/src/components/fields/BlockchainAddressFieldWithRichPreview.tsxAddressBookWidget/AddAliasDialogin ui-renderer ≥3.4.0)Gap: end-user transaction forms (preview + export) never take the rich path because
packages/renderer/src/components/fieldRegistry.tsmapsblockchain-address→AddressField.We want a form-level builder setting so users can choose:
rich(new default for new forms)simple(current behavior; preserve for existing exports)Motivation
Architecture (constitution-compliant)
Per
.specify/memory/constitution.mdPrinciple I (chain-agnostic, adapter-led):ecosystem === 'evm'or chain id stringsruntime?.nameResolution(NameResolutionCapability)capability.resolveName,capability.resolveAddressNameResolver)Data flow
Capability-led UI gating (builder only)
Show the setting when the active runtime supports forward name resolution:
Optional: only advertise rich when
resolveAddressis also present; otherwise rich degrades to address-only card.Hide control when
!canResolveNames— because the adapter didn’t publish name resolution, not because of ecosystem string checks.Upstream dependency (openzeppelin-ui)
This feature requires renderer support — builder-only wrappers will not fix exported apps.
Phase 1 —
@openzeppelin/ui-typesAdd typed setting (prefer first-class field over
metadata):Phase 2 —
@openzeppelin/ui-rendererBlockchainAddressDynamicField(or equivalent) withuseWatch+ mode switchDynamicFormFieldwhenfield.type === 'blockchain-address'DynamicFormFieldrecursion (object/array/map children)TransactionFormreadsschema.ensAddressPreviewand provides contextundefined/ omitted →'simple'(backward compat for existing exports)'rich'→ Pattern A'simple'→ current announcerReference implementations:
openzeppelin-ui/examples/basic-react-app/src/components/AddressFieldDemo.tsxopenzeppelin-ui/packages/renderer/src/components/AddressBookWidget/AddAliasDialog.tsxopenzeppelin-ui/packages/renderer/src/components/ResolvedAddressFieldPreviewWithNameResolution.tsxPhase 3 — ui-builder (this repo)
BuilderFormConfig/ persist viaContractUIRecord.formConfig'rich'; treat missing field as'simple'for loaded recordsFormPreview.tsx— no structural change once renderer supports schema fieldform-component.template.tsx; updateEnsExportPins.verification.test.ts/ snapshotsBlockchainAddressFieldWithRichPreview.tsxto re-use upstream field component once availableOut of scope / anti-patterns
TransactionFormonly in builder (export diverges)fieldRegistryonly in export templates'rich'without migrationif (ecosystem === 'evm')conditionals anywhere in UIAcceptance criteria
runtime.nameResolution?.resolveNameis presentblockchain-addressfieldsformSchemaincludesensAddressPreviewand matches previewpasevin.ethRelated work
feat/ens-mainnet-l1-fallback-003)BlockchainAddressFieldWithRichPreview.tsx,AddressBookDialog.tsxSuggested sequencing
Labels
enhancement,ens,export,ui-renderer-dependency