From 5e8381936d93bc6c2473e1f7545b15f4b9c02eb5 Mon Sep 17 00:00:00 2001 From: Aleksandr Pasevin Date: Wed, 22 Jul 2026 13:09:39 +0100 Subject: [PATCH 1/2] Document 17 capabilities, ENS name resolution, and RWA caps. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update ecosystem-adapter and UIKit docs for the expanded capability model (13→17), add ENS UX documentation, and correct per-adapter support counts. Co-authored-by: Cursor --- content/ecosystem-adapters/architecture.mdx | 19 +- .../building-an-adapter.mdx | 13 +- content/ecosystem-adapters/index.mdx | 6 +- .../supported-ecosystems.mdx | 24 +- content/tools/uikit/architecture.mdx | 14 +- content/tools/uikit/components.mdx | 11 +- content/tools/uikit/index.mdx | 1 + content/tools/uikit/name-resolution.mdx | 205 ++++++++++++++++++ content/tools/uikit/react-integration.mdx | 1 + .../shared/developer-libraries.json | 5 + 10 files changed, 275 insertions(+), 24 deletions(-) create mode 100644 content/tools/uikit/name-resolution.mdx diff --git a/content/ecosystem-adapters/architecture.mdx b/content/ecosystem-adapters/architecture.mdx index f9a6e011..6ff00285 100644 --- a/content/ecosystem-adapters/architecture.mdx +++ b/content/ecosystem-adapters/architecture.mdx @@ -31,20 +31,20 @@ flowchart TD style Core fill:#fff3e0,stroke:#ef6c00,color:#000 ``` -- **`@openzeppelin/ui-types`** defines all 13 capability interfaces. It is the single source of truth. +- **`@openzeppelin/ui-types`** defines all 17 capability interfaces. It is the single source of truth. - **`adapter-runtime-utils`** provides profile composition, lazy capability instantiation, and staged disposal. - **`adapter-evm-core`** centralizes reusable EVM implementations shared by `adapter-evm` and `adapter-polkadot`. - Each public adapter exposes an `ecosystemDefinition` conforming to `EcosystemExport`. ## Capability Tiers -Adapter functionality is decomposed into **13 capability interfaces** organized across **3 tiers**. The tiers reflect increasing levels of runtime requirements: stateless metadata, network-aware schema operations, and stateful wallet-dependent interactions. +Adapter functionality is decomposed into **17 capability interfaces** organized across **3 tiers**. The tiers reflect increasing levels of runtime requirements: stateless metadata, network-aware schema operations, and stateful wallet-dependent interactions. | Tier | Category | Network | Wallet | Capabilities | | --- | --- | --- | --- | --- | | **1** | Lightweight | No | No | `Addressing`, `Explorer`, `NetworkCatalog`, `UiLabels` | -| **2** | Schema | Yes | No | `ContractLoading`, `Schema`, `TypeMapping`, `Query` | -| **3** | Runtime | Yes | Yes | `Execution`, `Wallet`, `UiKit`, `Relayer`, `AccessControl` | +| **2** | Schema | Yes | No | `NameResolution`, `ContractLoading`, `Schema`, `TypeMapping`, `Query` | +| **3** | Runtime | Yes | Yes | `Execution`, `Wallet`, `UiKit`, `Relayer`, `AccessControl`, `ERC3643`, `ERC4626`, `IRS` | ### Tier Import Rules @@ -64,6 +64,7 @@ This means importing `@openzeppelin/adapter-evm/addressing` will never pull in w | Explorer | `ExplorerCapability` | 1 | `getExplorerUrl`, `getExplorerTxUrl` | | NetworkCatalog | `NetworkCatalogCapability` | 1 | `getNetworks` | | UiLabels | `UiLabelsCapability` | 1 | `getUiLabels` | +| NameResolution | `NameResolutionCapability` | 2 | `isValidName`, `resolveName`, `resolveAddress` | | ContractLoading | `ContractLoadingCapability` | 2 | `loadContract`, `getContractDefinitionInputs` | | Schema | `SchemaCapability` | 2 | `isViewFunction`, `getWritableFunctions` | | TypeMapping | `TypeMappingCapability` | 2 | `mapParameterTypeToFieldType`, `getTypeMappingInfo` | @@ -73,6 +74,13 @@ This means importing `@openzeppelin/adapter-evm/addressing` will never pull in w | UiKit | `UiKitCapability` | 3 | `getAvailableUiKits`, `configureUiKit` | | Relayer | `RelayerCapability` | 3 | `getRelayers`, `getNetworkServiceForms` | | AccessControl | `AccessControlCapability` | 3 | `registerContract`, `grantRole`, and 17 more | +| ERC3643 | `ERC3643Capability` | 3 | `balanceOf`, `isVerified`, `simulateTransfer`, `mint`, `transfer`, `freeze`, and more | +| ERC4626 | `ERC4626Capability` | 3 | `convertToAssets`, `convertToShares`, `totalAssets`, `deposit`, `withdraw` | +| IRS | `IRSCapability` | 3 | `getOnchainId`, `isVerified`, `buildClaimPayload`, `deployOnchainId`, `registerIdentity`, and more | + + +**Optional capabilities.** `NameResolution` is gated on factory presence and surfaces on every profile when the adapter provides it — it is not a profile requirement. `ERC3643`, `ERC4626`, and `IRS` are EVM-only, opt-in capabilities imported via dedicated sub-path exports (`@openzeppelin/adapter-evm/erc3643`, etc.); they are not assembled into standard profile runtimes. + ## Profiles @@ -88,6 +96,7 @@ Each profile is a strict superset of Declarative. Higher profiles add capabiliti | `Explorer` | ✅ | ✅ | ✅ | ✅ | ✅ | | `NetworkCatalog` | ✅ | ✅ | ✅ | ✅ | ✅ | | `UiLabels` | ✅ | ✅ | ✅ | ✅ | ✅ | +| `NameResolution` | ✅* | ✅* | ✅* | ✅* | ✅* | | `ContractLoading` | | ✅ | ✅ | ✅ | ✅ | | `Schema` | | ✅ | ✅ | ✅ | ✅ | | `TypeMapping` | | ✅ | ✅ | ✅ | ✅ | @@ -98,6 +107,8 @@ Each profile is a strict superset of Declarative. Higher profiles add capabiliti | `Relayer` | | | | ✅ | | | `AccessControl` | | | | | ✅ | +\* `NameResolution` is optional and adapter-gated. When the adapter's `CapabilityFactoryMap` includes `nameResolution`, the capability is exposed on every profile; adapters without it leave `runtime.nameResolution` undefined. + ### Profile Selection Guide | If your application needs to… | Choose | diff --git a/content/ecosystem-adapters/building-an-adapter.mdx b/content/ecosystem-adapters/building-an-adapter.mdx index b6687b65..8d917a07 100644 --- a/content/ecosystem-adapters/building-an-adapter.mdx +++ b/content/ecosystem-adapters/building-an-adapter.mdx @@ -6,14 +6,14 @@ This guide walks through implementing a new ecosystem adapter from scratch. By t ## How Much Do You Need to Implement? -Adapters are **incrementally adoptable**. You don't need to implement all 13 capabilities to ship a useful adapter. Start small and add capabilities as your ecosystem's support matures. +Adapters are **incrementally adoptable**. You don't need to implement all 17 capabilities to ship a useful adapter. Start small and add capabilities as your ecosystem's support matures. ```mermaid flowchart TD Start["Start Here"] --> T1["Implement Tier 1\n(4 capabilities)"] T1 -->|"Unlocks"| Dec["Declarative Profile\nAddress validation, explorer links,\nnetwork catalogs"] - T1 --> T2["Add Tier 2\n(4 capabilities)"] + T1 --> T2["Add Tier 2\n(5 capabilities)"] T2 -->|"Unlocks"| View["Viewer Profile\nContract reading, schema parsing,\ntype mapping, queries"] T2 --> T3a["Add Execution + Wallet"] @@ -25,6 +25,9 @@ flowchart TD T3a --> T3c["Add UiKit + AccessControl"] T3c -->|"Unlocks"| Op["Operator Profile\nRole and permission\nmanagement"] + T3a --> T3d["Add RWA caps (optional)"] + T3d -->|"Unlocks"| RWA["ERC3643 / ERC4626 / IRS\nRegulated-asset workflows\n(EVM sub-path exports)"] + style Start fill:#e8eaf6,stroke:#3f51b5,color:#000 style T1 fill:#e3f2fd,stroke:#1976d2,color:#000 style T2 fill:#fff3e0,stroke:#f57c00,color:#000 @@ -50,7 +53,8 @@ packages/adapter-/ │ │ ├── explorer.ts │ │ ├── network-catalog.ts │ │ ├── ui-labels.ts -│ │ ├── contract-loading.ts # Tier 2+ +│ │ ├── name-resolution.ts # Tier 2 (optional) +│ │ ├── contract-loading.ts # Tier 2+ │ │ ├── schema.ts │ │ ├── type-mapping.ts │ │ ├── query.ts @@ -59,6 +63,9 @@ packages/adapter-/ │ │ ├── ui-kit.ts │ │ ├── relayer.ts │ │ ├── access-control.ts +│ │ ├── erc3643.ts # Tier 3 (opt-in sub-path) +│ │ ├── erc4626.ts +│ │ ├── irs.ts │ │ └── index.ts │ ├── profiles/ # Profile runtime factories │ │ ├── shared-state.ts diff --git a/content/ecosystem-adapters/index.mdx b/content/ecosystem-adapters/index.mdx index 14eba64b..9d8a2c6e 100644 --- a/content/ecosystem-adapters/index.mdx +++ b/content/ecosystem-adapters/index.mdx @@ -2,7 +2,7 @@ title: Ecosystem Adapters --- -**OpenZeppelin Ecosystem Adapters** are a set of modular, chain-specific integration packages that let applications interact with any supported blockchain through a single, unified interface. Built on 13 composable capability interfaces organized in 3 tiers, each adapter encapsulates contract loading, type mapping, transaction execution, wallet connection, and network configuration in one place, while keeping consuming applications completely chain-agnostic. +**OpenZeppelin Ecosystem Adapters** are a set of modular, chain-specific integration packages that let applications interact with any supported blockchain through a single, unified interface. Built on 17 composable capability interfaces organized in 3 tiers, each adapter encapsulates contract loading, type mapping, transaction execution, wallet connection, and network configuration in one place, while keeping consuming applications completely chain-agnostic. **Source code**: The adapters are open-source. Browse the implementation, open issues, and contribute at [**github.com/OpenZeppelin/openzeppelin-adapters**](https://github.com/OpenZeppelin/openzeppelin-adapters). @@ -31,8 +31,8 @@ Building cross-chain tooling traditionally forces developers into one of two tra flowchart LR App["Your Application"] --> Runtime["EcosystemRuntime"] Runtime --> T1["Tier 1 (Lightweight)\n4 capabilities\nAddressing, Explorer, ..."] - Runtime --> T2["Tier 2 (Schema)\n4 capabilities\nContractLoading, Query, ..."] - Runtime --> T3["Tier 3 (Runtime)\n5 capabilities\nExecution, Wallet, ..."] + Runtime --> T2["Tier 2 (Schema)\n5 capabilities\nNameResolution, ContractLoading, ..."] + Runtime --> T3["Tier 3 (Runtime)\n8 capabilities\nExecution, Wallet, ERC3643, ..."] style T1 fill:#e3f2fd,stroke:#1976d2,color:#000 style T2 fill:#fff3e0,stroke:#f57c00,color:#000 diff --git a/content/ecosystem-adapters/supported-ecosystems.mdx b/content/ecosystem-adapters/supported-ecosystems.mdx index 6da1d002..627efb32 100644 --- a/content/ecosystem-adapters/supported-ecosystems.mdx +++ b/content/ecosystem-adapters/supported-ecosystems.mdx @@ -2,19 +2,19 @@ title: Supported Ecosystems --- -Each adapter implements the subset of the [13 capability interfaces](/ecosystem-adapters/architecture#capability-tiers) that its blockchain supports. This page summarizes what each production adapter provides. +Each adapter implements the subset of the [17 capability interfaces](/ecosystem-adapters/architecture#capability-tiers) that its blockchain supports. This page summarizes what each production adapter provides. | Adapter | Networks | Capabilities | Status | | --- | --- | --- | --- | -| **EVM** | Ethereum, Polygon, Arbitrum, Base, Optimism, ... | 13/13 | Production | -| **Stellar** | Stellar Public, Stellar Testnet | 13/13 | Production | -| **Polkadot** | Polkadot Hub, Moonbeam, Moonriver | 13/13 (EVM path) | Production | -| **Midnight** | Midnight Testnet | 11/13 | Production | -| **Solana** | Devnet, Testnet, Mainnet Beta | 4/13 (Tier 1 only) | Scaffolding | +| **EVM** | Ethereum, Polygon, Arbitrum, Base, Optimism, ... | 17/17 | Production | +| **Stellar** | Stellar Public, Stellar Testnet | 13/17 | Production | +| **Polkadot** | Polkadot Hub, Moonbeam, Moonriver | 13/17 (EVM path) | Production | +| **Midnight** | Midnight Testnet | 12/17 | Production | +| **Solana** | Devnet, Testnet, Mainnet Beta | 4/17 (Tier 1 only) | Scaffolding | ## EVM (`@openzeppelin/adapter-evm`) -The EVM adapter targets Ethereum and all EVM-compatible chains. It implements the full set of 13 capabilities and supports all 5 profiles. +The EVM adapter targets Ethereum and all EVM-compatible chains. It implements all 17 capabilities and supports all 5 profiles. Standard `createRuntime` profiles expose 14 capabilities (including `nameResolution`); the three RWA/token-standard capabilities (`erc3643`, `erc4626`, `irs`) are available as dedicated sub-path exports for opt-in composition. **Supported Networks**: Ethereum Mainnet, Sepolia, Polygon, Polygon Amoy, Arbitrum One, Arbitrum Sepolia, Base, Base Sepolia, Optimism, Optimism Sepolia, and more. @@ -22,11 +22,13 @@ The EVM adapter targets Ethereum and all EVM-compatible chains. It implements th ### Highlights +- **Name Resolution**: Forward and reverse ENS resolution via viem and the Universal Resolver. Network-scoped, with optional mainnet-L1 miss-fallback for testnets. - **Contract Loading**: Fetches ABIs from Etherscan and Sourcify with automatic fallback ordering. Detects proxy contracts and resolves implementation ABIs. - **Type Mapping**: Maps all Solidity types (`uint256`, `address`, `bytes32`, tuples, dynamic arrays) to UI-friendly form fields. - **Execution Strategies**: Pluggable EOA (direct wallet signing via Wagmi/Viem) and OpenZeppelin Relayer strategies. - **Wallet Integration**: Built on Wagmi and RainbowKit with React context providers and hooks. - **Access Control**: Full role management including `grantRole`, `revokeRole`, `renounceRole`, ownership transfers, and role enumeration. +- **RWA / Token Standards** (sub-path exports): `erc3643` (T-REX permissioned tokens), `erc4626` (tokenized vaults), and `irs` (ONCHAINID / Identity Registry Storage) for regulated-asset workflows. ### Configuration Resolution @@ -53,7 +55,7 @@ The EVM adapter resolves RPC URLs and explorer API keys through a layered priori ## Stellar (`@openzeppelin/adapter-stellar`) -The Stellar adapter provides a complete Soroban implementation with all 13 capabilities. +The Stellar adapter provides a complete Soroban implementation with 13 of 17 capabilities (all profile capabilities except `nameResolution` and the EVM-only RWA trio). **Supported Networks**: Stellar Public, Stellar Testnet @@ -138,6 +140,7 @@ The Operator profile is explicitly unsupported. Calling `createRuntime('operator | Explorer | ✅ | ✅ | ✅ | ✅ | ✅ | | NetworkCatalog | ✅ | ✅ | ✅ | ✅ | ✅ | | UiLabels | ✅ | ✅ | ✅ | ✅ | ✅ | +| NameResolution | ✅ | - | - | - | - | | ContractLoading | ✅ | ✅ | ✅ | ✅ | - | | Schema | ✅ | ✅ | ✅ | ✅ | - | | TypeMapping | ✅ | ✅ | ✅ | ✅ | - | @@ -147,3 +150,8 @@ The Operator profile is explicitly unsupported. Calling `createRuntime('operator | UiKit | ✅ | ✅ | ✅ | ✅ | - | | Relayer | ✅ | ✅ | ✅ | - | - | | AccessControl | ✅ | ✅ | ✅ | - | - | +| ERC3643 | ✅† | - | - | - | - | +| ERC4626 | ✅† | - | - | - | - | +| IRS | ✅† | - | - | - | - | + +† EVM-only. Available via `@openzeppelin/adapter-evm/erc3643`, `/erc4626`, and `/irs` sub-path exports; not assembled into standard profile runtimes. diff --git a/content/tools/uikit/architecture.mdx b/content/tools/uikit/architecture.mdx index 0177eaad..ab5a07b3 100644 --- a/content/tools/uikit/architecture.mdx +++ b/content/tools/uikit/architecture.mdx @@ -50,7 +50,7 @@ flowchart TD ## Capabilities -The UIKit type system defines 13 **capabilities**: small, focused interfaces that describe what an adapter can do. +The UIKit type system defines 17 **capabilities**: small, focused interfaces that describe what an adapter can do. Capabilities are organized into three tiers based on their requirements: @@ -58,8 +58,8 @@ Capabilities are organized into three tiers based on their requirements: %%{init: {'flowchart': {'nodeSpacing': 30, 'rankSpacing': 30}} }%% flowchart TD T1["Tier 1 (Lightweight)
Addressing · Explorer · NetworkCatalog · UiLabels"] - T2["Tier 2 (Network-Aware)
ContractLoading · Schema · TypeMapping · Query"] - T3["Tier 3 (Stateful)
Execution · Wallet · UiKit · Relayer · AccessControl"] + T2["Tier 2 (Network-Aware)
NameResolution · ContractLoading · Schema · TypeMapping · Query"] + T3["Tier 3 (Stateful)
Execution · Wallet · UiKit · Relayer · AccessControl · ERC3643 · ERC4626 · IRS"] T1 --"may import"--> T2 --"may import"--> T3 @@ -76,6 +76,7 @@ flowchart TD | `Explorer` | 1 | Block explorer URL generation | | `NetworkCatalog` | 1 | Available network listing and metadata | | `UiLabels` | 1 | Human-readable labels for ecosystem-specific terms | +| `NameResolution` | 2 | Forward (name → address) and reverse (address → name) resolution | | `ContractLoading` | 2 | Fetch and parse contract ABIs/IDLs | | `Schema` | 2 | Transform contract definitions into form-renderable schemas | | `TypeMapping` | 2 | Map blockchain types (e.g. `uint256`) to form field types | @@ -85,6 +86,13 @@ flowchart TD | `UiKit` | 3 | Ecosystem-specific React components and hooks | | `Relayer` | 3 | Gas-sponsored transaction execution via relayers | | `AccessControl` | 3 | Role-based access control queries and snapshots | +| `ERC3643` | 3 | ERC-3643 (T-REX) permissioned token reads and writes | +| `ERC4626` | 3 | ERC-4626 tokenized-vault reads and writes | +| `IRS` | 3 | ONCHAINID / Identity Registry Storage onboarding flows | + + +`NameResolution` is optional and adapter-gated — when present it surfaces on every profile runtime. `ERC3643`, `ERC4626`, and `IRS` are EVM-only opt-in capabilities imported via adapter sub-path exports; see [Supported Ecosystems](/ecosystem-adapters/supported-ecosystems#capability-support-matrix). + ### Capability Bundles diff --git a/content/tools/uikit/components.mdx b/content/tools/uikit/components.mdx index 7c26f952..a174a2fc 100644 --- a/content/tools/uikit/components.mdx +++ b/content/tools/uikit/components.mdx @@ -45,7 +45,7 @@ OpenZeppelin UIKit ships two categories of components: **UI primitives** from `@ | `NetworkStatusBadge` | Colored badge showing network status (e.g. connected, syncing) | | `EcosystemDropdown` | Ecosystem selection with chain icons | | `EcosystemIcon` | Chain-specific icons (Ethereum, Stellar, Polkadot, etc.) | -| `AddressDisplay` | Formatted address with optional alias labels and edit controls | +| `AddressDisplay` | Formatted address with optional ENS reverse resolution and alias labels | | `ViewContractStateButton` | Quick-action button to open the contract state widget | | `OverflowMenu` | Compact "..." dropdown for secondary actions | @@ -77,7 +77,8 @@ The field components are designed for use with [react-hook-form](https://react-h | Field | Input Type | Use Case | | --- | --- | --- | -| `AddressField` | Blockchain address | Contract addresses, recipient addresses; validates format per ecosystem | +| `AddressField` | Blockchain address | Contract addresses, recipient addresses; validates format per ecosystem; resolves ENS names when `NameResolverProvider` is mounted | +| `AddressFieldWithResolvedPreview` | Blockchain address + preview card | Same as `AddressField` with a reverse-lookup preview slot (see [Name Resolution](/tools/uikit/name-resolution)) | | `AmountField` | Token amounts | Token transfers; handles decimals and BigInt formatting | | `BigIntField` | Large integers | Raw `uint256` values, timestamps, token IDs | | `BytesField` | Hex byte strings | Calldata, hashes, signatures | @@ -132,12 +133,16 @@ function TransferForm() { ### Address Label & Suggestion Contexts -UIKit provides context-driven address resolution that works automatically with `AddressField` and `AddressDisplay`: +UIKit provides context-driven **address-book aliases** that work automatically with `AddressField` and `AddressDisplay`: - **`AddressLabelProvider`**: When mounted, all `AddressDisplay` instances in the subtree auto-resolve human-readable labels (e.g. "Treasury Multisig" instead of `0x1234...abcd`). - **`AddressSuggestionProvider`**: When mounted, all `AddressField` instances show autocomplete suggestions as the user types. - **`useAddressLabel(address, networkId?)`**: Hook to resolve a label from the nearest provider. + +Address-book aliases are **not** ENS. For on-chain name resolution (forward/reverse), mount `NameResolverProvider` instead — see [Name Resolution (ENS)](/tools/uikit/name-resolution). + + ## Renderer Widgets `@openzeppelin/ui-renderer` provides high-level, ready-to-use widgets for common blockchain UI patterns. These compose the lower-level components with adapter capabilities. diff --git a/content/tools/uikit/index.mdx b/content/tools/uikit/index.mdx index 1ebcf511..1ab1cc07 100644 --- a/content/tools/uikit/index.mdx +++ b/content/tools/uikit/index.mdx @@ -15,6 +15,7 @@ A modular React component library for building blockchain transaction interfaces + diff --git a/content/tools/uikit/name-resolution.mdx b/content/tools/uikit/name-resolution.mdx new file mode 100644 index 00000000..6056eb9c --- /dev/null +++ b/content/tools/uikit/name-resolution.mdx @@ -0,0 +1,205 @@ +--- +title: Name Resolution (ENS) +--- + +OpenZeppelin UIKit ships first-class support for **forward** (name → address) and **reverse** (address → name) resolution on networks where the active adapter exposes the `nameResolution` capability. On EVM chains this powers ENS-aware address inputs and displays without forking form fields. + + +**Live example**: See forward and reverse resolution, network-scoped hooks, and preview cards in the [**basic-react-app**](https://github.com/OpenZeppelin/openzeppelin-ui/tree/main/examples/basic-react-app) (`ENSResolutionDemo`) and at [**openzeppelin-ui.netlify.app**](https://openzeppelin-ui.netlify.app). + + +## Name resolution vs. address aliases + +UIKit exposes two distinct systems for showing human-readable names next to addresses. They solve different problems and must not be conflated: + +| Concern | Name resolution (ENS) | Address aliases (Address Book) | +| --- | --- | --- | +| **Source** | On-chain naming (ENS, Universal Resolver) via adapter `nameResolution` | User-defined labels in IndexedDB via `@openzeppelin/ui-storage` | +| **Providers** | `NameResolverProvider` (`@openzeppelin/ui-components`) fed by `useRuntimeNameResolver` (`@openzeppelin/ui-react`) | `AddressLabelProvider`, `AddressSuggestionProvider` | +| **Hooks** | `useResolveName`, `useResolveAddress` | `useAliasLabelResolver`, `useAliasSuggestionResolver` | +| **Typical input** | User types `vitalik.eth`; field resolves to hex before submit | User picks a saved alias from suggestions or sees a stored label on `AddressDisplay` | +| **Persistence** | None — resolution is live against the selected network | Local address book entries survive reloads | + +An app can use **both**: mount `NameResolverProvider` for ENS and `AddressLabelProvider` for saved aliases. The basic-react-app wires both via separate bridge components. + +## Architecture + +```mermaid +flowchart TD + Runtime["EcosystemRuntime.nameResolution"] + Hook["useRuntimeNameResolver()"] + Provider["NameResolverProvider"] + Field["AddressField / AddressDisplay"] + Engine["useResolveName / useResolveAddress"] + + Runtime --> Hook --> Provider --> Field + Engine --> Runtime + + style Runtime fill:#fff3e0,stroke:#f57c00,color:#000 + style Provider fill:#e0f2f1,stroke:#26a69a,color:#004d40 + style Field fill:#e8eaf6,stroke:#5c6bc0,color:#000 +``` + +1. The adapter builds a **network-scoped** `NameResolutionCapability` when `createRuntime` runs (EVM: ENS via viem + Universal Resolver). +2. `useRuntimeNameResolver` projects `activeRuntime.nameResolution` into the `NameResolver` seam consumed by UI components. +3. `NameResolverProvider` makes that resolver available to every `AddressField` and `AddressDisplay` in the subtree. +4. `useResolveName` / `useResolveAddress` expose the same capability to custom UI with debouncing, caching, and typed errors. + +Resolution is always **bound to the active network** (or an explicitly passed `network` for network-scoped hooks). Results carry **provenance** metadata (ENS system, external gateway, cross-network fallback) for display and submit gating. + +## Provider wiring + +### Ambient wiring (recommended) + +Mirror the pattern from `examples/basic-react-app/src/providers/AppProviders.tsx`: + +```tsx +import { NameResolverProvider } from '@openzeppelin/ui-components'; +import { RuntimeProvider, useRuntimeNameResolver, useWalletState, WalletStateProvider } from '@openzeppelin/ui-react'; +import type { CreateRuntimeOptions, NetworkConfig } from '@openzeppelin/ui-types'; + +const runtimeCreationOptions: CreateRuntimeOptions = { + // Opt-in: after a definitive miss on the bound chain (e.g. Sepolia), consult mainnet L1 once. + nameResolution: { enableMainnetL1MissFallback: true }, +}; + +function NameResolverBridge({ children }: { children: React.ReactNode }) { + const resolver = useRuntimeNameResolver(); + const { activeNetworkId, activeNetworkConfig } = useWalletState(); + + return ( + + {children} + + ); +} + +function App() { + return ( + + ecosystemDefinition.createRuntime('composer', nc, runtimeCreationOptions) + } + > + + + + + + + ); +} +``` + +`TransactionForm` from `@openzeppelin/ui-renderer` mounts its own `NameResolverProvider` internally when rendered under `WalletStateProvider`, so schema-driven forms gain ENS on every `blockchain-address` field with no registry swap. + +### Network-scoped resolution + +When a field must resolve against a **specific** network (not the wallet-global active network), pass a `NetworkConfig` into the hook: + +```tsx +import { useRuntimeNameResolver } from '@openzeppelin/ui-react'; +import { NameResolverProvider } from '@openzeppelin/ui-components'; + +function NetworkScopedField({ dialogNetwork }: { dialogNetwork: NetworkConfig }) { + const resolver = useRuntimeNameResolver(dialogNetwork); + + return ( + + + + ); +} +``` + +The same `network` option is available on `useResolveAddress(address, { network })`. + +## Hooks + +| Hook | Package | Purpose | +| --- | --- | --- | +| `useRuntimeNameResolver(network?)` | `@openzeppelin/ui-react` | Stable `NameResolver` object for `NameResolverProvider` | +| `useResolveName(name, options?)` | `@openzeppelin/ui-react` | Async forward resolution with debounce and cache | +| `useResolveAddress(address, options?)` | `@openzeppelin/ui-react` | Async reverse resolution with debounce and cache | + +`useResolveName` returns a status union (`idle`, `loading`, `debouncing`, `success`, `error`) and never throws for expected failures (`NAME_NOT_FOUND`, `UNSUPPORTED_NETWORK`, etc.). + +## Address fields and preview cards + +### `AddressField` (forward) + +Once `NameResolverProvider` is mounted, the base `AddressField` resolves typed names inline. The form value is always the **resolved hex** on success; unresolved names gate submit. + +```tsx +import { AddressField } from '@openzeppelin/ui-components'; + + +``` + +### `AddressFieldWithResolvedPreview` + reverse preview + +For a live reverse-lookup card under the input, compose the preview slot with `ResolvedAddressFieldPreviewWithNameResolution`: + +```tsx +import { useWatch } from 'react-hook-form'; +import { AddressFieldWithResolvedPreview } from '@openzeppelin/ui-components'; +import { ResolvedAddressFieldPreviewWithNameResolution } from '@openzeppelin/ui-renderer'; + +function RecipientField({ control, addressing, networkId, network }) { + const previewAddress = useWatch({ control, name: 'recipient' }); + + return ( + + } + /> + ); +} +``` + +### `AddressDisplay` (reverse) + +`AddressDisplay` inherits reverse resolution from the same `NameResolverProvider`. When `resolveAddress` is available on the active runtime, verified names render inline with optional cross-network fallback disclaimers. + +## Runtime options (EVM) + +| Option | Default | Effect | +| --- | --- | --- | +| `nameResolution.enableMainnetL1MissFallback` | `false` | When `true`, after a definitive `NAME_NOT_FOUND` on a bound chain with its own Universal Resolver, attempt one mainnet L1 lookup (useful for testnets resolving mainnet-only names). | + +Pass options as the third argument to `ecosystemDefinition.createRuntime(profile, networkConfig, options)`. + +## Degradation behavior + +When no `WalletStateProvider` is mounted, the runtime lacks `nameResolution`, or the capability omits `resolveName`, fields **degrade safely**: + +- Hex addresses behave exactly as before. +- Typed names surface `UNSUPPORTED_NETWORK` with submit gated — never a silent coercion to hex. + +## Next steps + +- [React Integration](/tools/uikit/react-integration): `RuntimeProvider`, `WalletStateProvider`, and wallet hooks +- [Storage](/tools/uikit/storage): address-book aliases (`AddressLabelProvider`) — separate from ENS +- [Architecture](/ecosystem-adapters/architecture#capability-reference): `NameResolution` capability reference +- [Supported Ecosystems](/ecosystem-adapters/supported-ecosystems): per-adapter name-resolution support diff --git a/content/tools/uikit/react-integration.mdx b/content/tools/uikit/react-integration.mdx index 3a745821..a1e59f30 100644 --- a/content/tools/uikit/react-integration.mdx +++ b/content/tools/uikit/react-integration.mdx @@ -267,6 +267,7 @@ sequenceDiagram ## Next Steps +- [Name Resolution (ENS)](/tools/uikit/name-resolution): Wire `NameResolverProvider`, hooks, and address-field preview cards - [Components](/tools/uikit/components): Browse all available components and form fields - [Theming & Styling](/tools/uikit/theming): Customize the visual design - [Building an adapter](/ecosystem-adapters/building-an-adapter): Background on adapter packages and ecosystem integrations diff --git a/src/navigation/shared/developer-libraries.json b/src/navigation/shared/developer-libraries.json index 4528e322..b08c0abb 100644 --- a/src/navigation/shared/developer-libraries.json +++ b/src/navigation/shared/developer-libraries.json @@ -63,6 +63,11 @@ "name": "React Integration", "url": "/tools/uikit/react-integration" }, + { + "type": "page", + "name": "Name Resolution (ENS)", + "url": "/tools/uikit/name-resolution" + }, { "type": "page", "name": "Theming & Styling", From fcaaf2df7174de56115a4de065fea1afda2d8230 Mon Sep 17 00:00:00 2001 From: Aleksandr Pasevin Date: Wed, 22 Jul 2026 15:35:39 +0100 Subject: [PATCH 2/2] Address Copilot review: Tier 2 wording and adapter matrix accuracy. Relabel Tier 2 as Network-Aware, reconcile per-adapter counts with CapabilityFactoryMap checkmarks, and document Solana's 12/17 scaffolding factories. Co-authored-by: Cursor --- content/ecosystem-adapters/architecture.mdx | 4 +-- content/ecosystem-adapters/index.mdx | 2 +- .../supported-ecosystems.mdx | 28 ++++++++++--------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/content/ecosystem-adapters/architecture.mdx b/content/ecosystem-adapters/architecture.mdx index 6ff00285..d673f930 100644 --- a/content/ecosystem-adapters/architecture.mdx +++ b/content/ecosystem-adapters/architecture.mdx @@ -38,12 +38,12 @@ flowchart TD ## Capability Tiers -Adapter functionality is decomposed into **17 capability interfaces** organized across **3 tiers**. The tiers reflect increasing levels of runtime requirements: stateless metadata, network-aware schema operations, and stateful wallet-dependent interactions. +Adapter functionality is decomposed into **17 capability interfaces** organized across **3 tiers**. The tiers reflect increasing levels of runtime requirements: stateless metadata, network-aware operations (schema parsing, read-only queries, and name resolution), and stateful wallet-dependent interactions. | Tier | Category | Network | Wallet | Capabilities | | --- | --- | --- | --- | --- | | **1** | Lightweight | No | No | `Addressing`, `Explorer`, `NetworkCatalog`, `UiLabels` | -| **2** | Schema | Yes | No | `NameResolution`, `ContractLoading`, `Schema`, `TypeMapping`, `Query` | +| **2** | Network-Aware | Yes | No | `NameResolution`, `ContractLoading`, `Schema`, `TypeMapping`, `Query` | | **3** | Runtime | Yes | Yes | `Execution`, `Wallet`, `UiKit`, `Relayer`, `AccessControl`, `ERC3643`, `ERC4626`, `IRS` | ### Tier Import Rules diff --git a/content/ecosystem-adapters/index.mdx b/content/ecosystem-adapters/index.mdx index 9d8a2c6e..d0040182 100644 --- a/content/ecosystem-adapters/index.mdx +++ b/content/ecosystem-adapters/index.mdx @@ -31,7 +31,7 @@ Building cross-chain tooling traditionally forces developers into one of two tra flowchart LR App["Your Application"] --> Runtime["EcosystemRuntime"] Runtime --> T1["Tier 1 (Lightweight)\n4 capabilities\nAddressing, Explorer, ..."] - Runtime --> T2["Tier 2 (Schema)\n5 capabilities\nNameResolution, ContractLoading, ..."] + Runtime --> T2["Tier 2 (Network-Aware)\n5 capabilities\nNameResolution, ContractLoading, ..."] Runtime --> T3["Tier 3 (Runtime)\n8 capabilities\nExecution, Wallet, ERC3643, ..."] style T1 fill:#e3f2fd,stroke:#1976d2,color:#000 diff --git a/content/ecosystem-adapters/supported-ecosystems.mdx b/content/ecosystem-adapters/supported-ecosystems.mdx index 627efb32..ea13fe52 100644 --- a/content/ecosystem-adapters/supported-ecosystems.mdx +++ b/content/ecosystem-adapters/supported-ecosystems.mdx @@ -2,7 +2,7 @@ title: Supported Ecosystems --- -Each adapter implements the subset of the [17 capability interfaces](/ecosystem-adapters/architecture#capability-tiers) that its blockchain supports. This page summarizes what each production adapter provides. +Each adapter implements the subset of the [17 capability interfaces](/ecosystem-adapters/architecture#capability-tiers) that its blockchain supports. Summary counts match the [capability matrix](#capability-support-matrix) below: one checkmark per implemented factory in the adapter's `CapabilityFactoryMap`, plus EVM-only RWA capabilities available as sub-path exports. | Adapter | Networks | Capabilities | Status | | --- | --- | --- | --- | @@ -10,7 +10,7 @@ Each adapter implements the subset of the [17 capability interfaces](/ecosystem- | **Stellar** | Stellar Public, Stellar Testnet | 13/17 | Production | | **Polkadot** | Polkadot Hub, Moonbeam, Moonriver | 13/17 (EVM path) | Production | | **Midnight** | Midnight Testnet | 12/17 | Production | -| **Solana** | Devnet, Testnet, Mainnet Beta | 4/17 (Tier 1 only) | Scaffolding | +| **Solana** | Devnet, Testnet, Mainnet Beta | 12/17 (scaffolding) | In Progress | ## EVM (`@openzeppelin/adapter-evm`) @@ -91,7 +91,7 @@ Non-EVM execution paths (native Substrate) are not yet implemented. Requesting a ## Midnight (`@openzeppelin/adapter-midnight`) -The Midnight adapter enables browser-based interaction with Midnight contracts using zero-knowledge proof workflows. +The Midnight adapter enables browser-based interaction with Midnight contracts using zero-knowledge proof workflows. It implements **12 of 17** capabilities: all profile capabilities except `nameResolution`, `accessControl`, and the EVM-only RWA trio (`erc3643`, `erc4626`, `irs`). **Supported Networks**: Midnight Testnet @@ -124,11 +124,11 @@ const adapterConfigs = await loadOpenZeppelinAdapterViteConfig({ The Solana adapter is scaffolding only and is not yet production-ready.
-The Solana package defines the package boundaries and network configurations for a future adapter. It currently provides: +The Solana package defines the package boundaries and network configurations for a future adapter. Its `CapabilityFactoryMap` currently registers **12 of 17** capabilities (Tier 1 through `relayer`); `nameResolution`, `accessControl`, and the EVM-only RWA trio are absent. Tier 2–3 factories exist as scaffolding stubs and are not production-ready. - Solana network configurations (Devnet, Testnet, Mainnet Beta) - Package structure and sub-path export scaffolding -- Tier 1 capability implementations (Addressing, Explorer, NetworkCatalog, UiLabels) +- Tier 1 capability implementations (Addressing, Explorer, NetworkCatalog, UiLabels) plus stub Tier 2–3 factories The Operator profile is explicitly unsupported. Calling `createRuntime('operator', ...)` throws `UnsupportedProfileError` because `accessControl` factories are not yet implemented. @@ -141,17 +141,19 @@ The Operator profile is explicitly unsupported. Calling `createRuntime('operator | NetworkCatalog | ✅ | ✅ | ✅ | ✅ | ✅ | | UiLabels | ✅ | ✅ | ✅ | ✅ | ✅ | | NameResolution | ✅ | - | - | - | - | -| ContractLoading | ✅ | ✅ | ✅ | ✅ | - | -| Schema | ✅ | ✅ | ✅ | ✅ | - | -| TypeMapping | ✅ | ✅ | ✅ | ✅ | - | -| Query | ✅ | ✅ | ✅ | ✅ | - | -| Execution | ✅ | ✅ | ✅ (EVM) | ✅ | - | -| Wallet | ✅ | ✅ | ✅ | ✅ | - | -| UiKit | ✅ | ✅ | ✅ | ✅ | - | -| Relayer | ✅ | ✅ | ✅ | - | - | +| ContractLoading | ✅ | ✅ | ✅ | ✅ | ✅ | +| Schema | ✅ | ✅ | ✅ | ✅ | ✅ | +| TypeMapping | ✅ | ✅ | ✅ | ✅ | ✅ | +| Query | ✅ | ✅ | ✅ | ✅ | ✅ | +| Execution | ✅ | ✅ | ✅ (EVM) | ✅ | ✅ | +| Wallet | ✅ | ✅ | ✅ | ✅ | ✅ | +| UiKit | ✅ | ✅ | ✅ | ✅ | ✅ | +| Relayer | ✅ | ✅ | ✅ | ✅ | ✅ | | AccessControl | ✅ | ✅ | ✅ | - | - | | ERC3643 | ✅† | - | - | - | - | | ERC4626 | ✅† | - | - | - | - | | IRS | ✅† | - | - | - | - | † EVM-only. Available via `@openzeppelin/adapter-evm/erc3643`, `/erc4626`, and `/irs` sub-path exports; not assembled into standard profile runtimes. + +Counts are derived from each adapter's `CapabilityFactoryMap` in `openzeppelin-adapters` (`profiles/shared*.ts`), plus the three EVM RWA sub-path factories. Midnight is missing `nameResolution`, `accessControl`, and the RWA trio (12 ✅). Solana registers stub Tier 2–3 factories but remains scaffolding.