OpenZeppelin / OpenZeppelin/openzeppelin-ui
feat(renderer): form-level ENS address preview mode (rich vs simple) for TransactionForm
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 7
- Forks
- 3
- Avg merge
- 20h 20m
- Merged PRs (30d)
- 26
Description
Summary
Add a form-level setting so TransactionForm / DynamicFormField can render blockchain-address fields with either:
| Mode | UX | Default when omitted |
|---|---|---|
rich |
Pattern A: AddressFieldWithResolvedPreview + ResolvedAddressFieldPreviewWithNameResolution + parent useWatch |
— |
simple |
Bare AddressField with inline “Resolved to 0x…” announcer (current behavior) |
✅ yes (backward compat) |
Today fieldRegistry maps blockchain-address → AddressField only. Rich preview exists elsewhere (Address Book AddAliasDialog, basic-react-app demos) but is not available to TransactionForm consumers (ui-builder form preview, exported apps, direct integrators).
Downstream tracking: OpenZeppelin/ui-builder#403 (Phase 2 — builder toggle, export schema, tests).
Motivation
- Single implementation path in
@openzeppelin/ui-rendererkeeps builder preview, exported apps, and anyTransactionFormconsumer aligned - Integrators can opt into rich ENS UX without custom field wrappers
- Omitted setting preserves behavior for existing serialized form schemas
Design principles
Capability-led, not ecosystem-specific. Gate behavior on EcosystemRuntime.nameResolution (resolveName / resolveAddress per NameResolutionCapability in @openzeppelin/ui-types). Do not branch on networkConfig.ecosystem === 'evm'.
When nameResolution is absent, both modes degrade to plain address input (existing useRuntimeNameResolver → EMPTY_RESOLVER behavior).
Proposed API
@openzeppelin/ui-types
export type EnsAddressPreviewMode = 'rich' | 'simple';
// On CommonFormProperties and/or RenderFormSchema:
ensAddressPreview?: EnsAddressPreviewMode;
Prefer a first-class schema field over metadata for export stability and discoverability.
@openzeppelin/ui-renderer
RenderFormSchema.ensAddressPreview
↓
TransactionForm (read schema, provide context)
↓
DynamicFormField (blockchain-address)
├─ 'rich' → BlockchainAddressDynamicField (Pattern A)
└─ 'simple' → AddressField (current)
Thread mode through recursive DynamicFormField calls so nested object/array/map address fields inherit the form-level setting.
Default: ensAddressPreview omitted → 'simple'.
Implementation tasks
ui-types
- Add
EnsAddressPreviewModetype - Add optional
ensAddressPreviewtoCommonFormProperties/RenderFormSchema - Export from package public API
ui-renderer
- Create
BlockchainAddressDynamicField(or equivalent) implementing Pattern A:useWatch→previewAddressrich:AddressFieldWithResolvedPreview+ResolvedAddressFieldPreviewWithNameResolutionsimple:AddressFieldnetworkIdfrom adapter /useAdapter()(existing patterns)
- Add React context (or prop threading) from
TransactionForm→DynamicFormFieldforensAddressPreview - Update
fieldRegistry/DynamicFormFieldswitch forblockchain-address - Graceful degradation when
nameResolutionmissing (no throws) -
richwithoutresolveAddress: forward resolution still works; preview card may be address-only
Tests
-
TransactionFormrenders rich preview whenensAddressPreview: 'rich' - Default / omitted → simple announcer (snapshot or behavioral)
- Nested
blockchain-addressfields inherit mode - Runtime without
nameResolution→ plain address field in both modes - Existing tests unaffected (default remains simple)
Docs / examples (optional but recommended)
- Note in
TransactionForm/ form schema docs - Extend
AddressFieldDemoor add minimal example showing schema flag
Acceptance criteria
-
ensAddressPreview: 'rich'onRenderFormSchemarenders Pattern A below allblockchain-addressfields inTransactionForm - Omitted or
'simple'matches currentAddressFieldannouncer behavior - No
ecosystem === 'evm'conditionals introduced - Nested fields inherit form-level mode
- Published package versions documented for ui-builder floor bump
References
Canonical Pattern A:
examples/basic-react-app/src/components/AddressFieldDemo.tsxexamples/basic-react-app/src/components/ENSResolutionDemo.tsxpackages/renderer/src/components/AddressBookWidget/AddAliasDialog.tsxpackages/renderer/src/components/ResolvedAddressFieldPreviewWithNameResolution.tsxpackages/components/src/components/AddressFieldWithResolvedPreview.tsx(verify path)
Current simple path:
packages/renderer/src/components/fieldRegistry.ts—'blockchain-address': AddressFieldpackages/renderer/src/components/TransactionForm.tsxpackages/renderer/src/components/DynamicFormField.tsx
Name resolution hooks:
packages/react/src/hooks/nameResolution/useRuntimeNameResolver.ts
Downstream:
- OpenZeppelin/ui-builder#403 — builder UI,
BuilderFormConfig, export@@FORM_SCHEMA_JSON@@ - OpenZeppelin/ui-builder#401 — ENS rollout (runtime creation options, dependency floors)
Open questions
- Should rich require
resolveAddress, or is forward-only + address card acceptable when reverse is missing? - Export
BlockchainAddressDynamicFieldfrom@openzeppelin/ui-rendererpublic API so ui-builder can dedupeBlockchainAddressFieldWithRichPreview? - Context vs explicit prop drilling for nested
DynamicFormField— prefer context to avoid signature churn on every recursive call?
Release notes (draft)
Feature:
RenderFormSchema.ensAddressPreview('rich' | 'simple') controls ENS feedback UX forblockchain-addressfields inTransactionForm. Default omitted →'simple'(no breaking change).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with packages/renderer/src/components/TransactionForm.tsx, DynamicFormField.tsx, and fieldRegistry.ts, then compare the rich-preview patterns in the listed examples and renderer components. Trace recursive fields and name-resolution hooks, run the existing TransactionForm tests, and verify that rich, simple/default, nested, and missing-capability cases meet the acceptance criteria.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100