-
Notifications
You must be signed in to change notification settings - Fork 15
Description
This additional metadata adds latency and cost to calculate. It should only be calculated and returned if explicitly requested through an optional param.
Background info: Contracts were proposed to be added to the Contracts data files in ENSAwards that weren't actually contracts. An investigation revealed they were actually EOAs. ENSAwards already has a suite of unit tests that aim to protect against bad data. If the primary name lookup APIs in ENSApi made it easy to query this additional metadata, it could support improved data quality in ENSAwards. More broadly, I can see a number of other special use cases where returning this metadata could be helpful.
Note: The following spec was quickly generated using ChatGPT.
Spec: Add viem-based account classification (EOA-like vs Contract)
Goal
Implement a small utility to classify an on-chain account as EOA-like (no deployed runtime bytecode) or Contract (has runtime bytecode), using viem PublicClient.getBytecode() on the chain specified by chainId.
Requirements
1) Define AccountClassification enum
- Create an enum named
AccountClassification - It must have exactly two values:
EOALikeContract
Example shape (TypeScript):
AccountClassification.EOALikeAccountClassification.Contract
2) Define classifyAccount function
Create an async function:
Name: classifyAccount
Inputs:
account: object containing:chainId: numberaddress: Address(from viem)
clientsByChainId:Map<number, PublicClient>(from viem)
Output:
Promise<AccountClassification>
3) Error if chainId missing
- If
account.chainIdis not present as a key inclientsByChainId, the function must throw an Error. - Error message should be explicit and include the missing chainId (e.g.,
"No PublicClient configured for chainId=XXXX").
4) Error if classification fails
- If anything fails during classification (e.g., RPC error, invalid params, viem throws, unexpected response), the function must throw an Error.
- The thrown error should:
- Preserve the original error as the
causewhen possible (Node/TS supportsnew Error(msg, { cause })). - Include enough context to debug (at minimum:
chainIdandaddress).
- Preserve the original error as the
No “UNKNOWN” / fallback return values—fail hard.
5) Use getBytecode to classify
- Use the correct
PublicClientfromclientsByChainIdfor the givenchainId. - Call
publicClient.getBytecode({ address }). - Classification rules:
- If bytecode is exactly
'0x'(orundefinedif viem returns that for empty code), returnAccountClassification.EOALike. - Otherwise, return
AccountClassification.Contract.
- If bytecode is exactly
Acceptance Criteria
- ✅ Enum exists with only
EOALikeandContract. - ✅
classifyAccount(account, clientsByChainId)returns the expected enum value for:- An EOA address on that chain (returns
EOALike) - A deployed contract address on that chain (returns
Contract)
- An EOA address on that chain (returns
- ✅ Missing chainId in the map throws an error.
- ✅ Any RPC/viem failure during
getBytecodethrows an error with chain/address context. - ✅ Uses viem
getBytecodevia the chain-specificPublicClient.
Notes / Non-goals
- This utility does not attempt to distinguish “true EOA” vs “self-destructed contract” / “counterfactual address”; it only classifies based on current deployed bytecode.
- No caching required in this initial implementation.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status