Smart account infrastructure for ENS hardware-backed signers, built on Nexus (ERC-7579 / ERC-4337).
┌─────────────┐ deploys ┌──────────────┐
│ HCAFactory │ ─────── CREATE3 ───────▶ │ NexusProxy │
│ │ │ (per-user) │
│ setImpl() │ │ ────────── │
│ createAcct()│ │ delegatecall│
└──────┬──────┘ └──────┬───────┘
│ owns reference to │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ HCA (impl) │ ◀── delegated calls ── │ │
│ extends Nexus│ │ │
│ │ │ │
│ • locked-down│ └──────────────┘
│ module cfg │
│ • NFT reject │
│ • upgrade │
│ guard │
└──────┬───────┘
│ immutable refs
├──▶ HCAModule (default validator)
└──▶ IntentExecutor (default executor)
The account implementation. Extends Nexus with a locked-down security model:
- Immutable default validator — set at deploy time via the Nexus
_DEFAULT_VALIDATOR. All UserOp and EIP-1271 signature validation routes through this module. - Immutable default executor — the Rhinestone IntentExecutor is set as Nexus's
_DEFAULT_EXECUTOR, giving itexecuteFromExecutorpermissions without needing to be installed in the sentinel list. - Module locking —
installModuleanduninstallModulealways revert. The account's module configuration is fixed at initialization. - Upgrade guard — UUPS upgrades are restricted to the implementation currently registered on the HCAFactory. The factory owner controls which implementation accounts can upgrade to.
- NFT rejection — the fallback function reverts on
onERC721Received,onERC1155Received, andonERC1155BatchReceived, preventing the account from holding NFTs.
The constructor takes:
| Parameter | Description |
|---|---|
hcaFactory_ |
The factory managing this account's lifecycle |
entryPoint_ |
The ERC-4337 EntryPoint |
defaultValidator_ |
HCAModule address (immutable K1 validator) |
intentExecutor_ |
IntentExecutor address (immutable default executor) |
validatorInitData_ |
Template data passed to the validator at construction (blocks direct use of the implementation) |
The validator module. Extends OwnableValidator with HCA-specific constraints:
- Implements
IHCAInitDataParserso the factory can extract the primary owner from init data. - Enforces that the first owner must be permanent (
expiration == type(uint48).max). - Multi-sig with configurable k-of-n threshold and time-based owner expiration.
The base ERC-7579 validator providing:
- Multi-signature validation with configurable threshold (1-of-n to n-of-n).
- Owner expiration — each owner has a
uint48expiration timestamp. Expired owners are automatically excluded from signature validation.type(uint48).maxmeans permanent. - Dual validation modes — stateful (stored config) and stateless (config passed in calldata).
- Owner management —
updateConfigfor atomic add/remove/threshold changes,updateOwnerExpirationfor extending/reducing access. - Owners stored as packed
bytes32values:[address 160b][expiration 48b][unused 48b].
The factory that deploys HCA proxies:
- Deploys
NexusProxyinstances via CREATE3, deriving deterministic addresses from the primary owner. - Delegates to an
IHCAInitDataParser(the HCAModule) to extract the owner from init data. - The factory owner can update the implementation via
setImplementation, which controls what accounts can upgrade to. createAccountis idempotent — calling it again for the same owner forwards ETH to the existing account.
- Deploy implementation —
new HCA(factory, entryPoint, hcaModule, intentExecutor, templateInitData) - Register on factory —
factory.setImplementation(hcaImpl, hcaModule) - Create account —
factory.createAccount(initData)whereinitData = abi.encode(threshold, owners[])- Factory deploys a NexusProxy via CREATE3
- Proxy calls
HCA.initializeAccount(initData)which installs the validator with the provided owners and initializes the default executor
- Use — the account validates UserOps through HCAModule, executes intents through the default executor, and rejects any module changes
- Upgrade — factory owner sets a new implementation, then the account (via UserOp) calls
upgradeToAndCallwhich only accepts the factory's current implementation
pnpm install
forge build
forge test| Package | Source |
|---|---|
@rhinestone/nexus |
rhinestonewtf/rhinestone-nexus (branch: feat/default-executor) |
@ensdomains/contracts-v2 |
zeroknots/ens-contracts-v2 |
@rhinestone/modulekit |
rhinestonewtf/modulekit |
@rhinestone/compact-utils |
local link |
GPL-3.0