-
9d6eaa4Thanks @jwahdatehagh! - Correctness, robustness, and API hardening across the SDK.Fixes
- Sourcify v2: request the valid
runtimeBytecodefield instead ofdeployedBytecode(which the live API rejects with HTTP 400) and surfaceruntimeBytecode.onchainBytecodeasdeployedBytecode. Field selectors are validated against the known v2 field list (buildSourcifyFields,SOURCIFY_V2_FIELDS). - Repository source: chain-aware lookups —
contracts/{chainId}/{address}.jsonfirst with a flat-layout fallback; documents with a mismatchedchainIdare discarded; malformed JSON shapes (arrays, non-stringincludes) return null instead of crashingget(). merge/mergeNatspecDocsskip__proto__,constructor, andprototypekeys (prototype-pollution hardening).- ENS names are lowercased before the
.ethcheck and hashing, soVitalik.eth/VITALIK.ETHresolve correctly. - Diamond facets: NatSpec methods and derived actions are filtered to mounted selectors so unmounted facet functions can't inject actions.
- Multi-target proxy
metadataLayeris now first-target-wins, consistent with the NatSpec merge. - On-chain
name()/symbol()fill uses the bytes32-aware, sanitizing token decoder (fixes MKR/SAI-style tokens; hostile values are capped/stripped). - Calldata matching treats a missing
call.valueas0for locked value constraints. - Event/error key validation flags truncated and uppercase hex keys; the action signature grammar accepts
$identifiers, aligned betweenactions.tsandvalidate.ts. - Mixed-case addresses are EIP-55 checksum-validated and rejected with
InvalidAddressErroron mismatch.
Robustness
- JSON-RPC calls carry a 10s abort timeout.
includesresolution only followshttps:URLs; the schema base is configurable (schemaBaseUrl, defaulthttps://evmnow.github.io/contract-metadata/v1).resolveUricaps response bodies at ~1 MB and recognizes thedata:application/json;charset=utf-8,variant.- Sourcify responses are shape-validated (non-object bodies, non-record natspec, non-array ABIs).
New options & API
ContractClientConfig:schemaBaseUrl,cache(per-client memoization + in-flight dedup of repository/Sourcify fetches, default on),ensResolver(custom ENS Universal Resolver address).- New error classes:
InvalidAddressError,ChainIdMismatchError,ContractClientConfigError. - New exports:
filterSourcifyBySelectors,buildSourcifyFields,SOURCIFY_V2_FIELDS,decodeSymbol,sanitizeSymbol,normalizeEnsName,UNIVERSAL_RESOLVER,AbiItem. - New subpath exports:
./actions,./natspec,./interfaces/detect,./interfaces/erc20,./interfaces/erc721,./package.json. ContractResult.abi,ProxyResolution.compositeAbi,TargetInfo.abi, andSourcifyResult.abiare now typed asAbiItem[]instead ofunknown[].- Token info resolver fetches
decimals()andsymbol()concurrently.
- Sourcify v2: request the valid
a5c2335Thanks @jwahdatehagh! - New@evmnow/sdk/validatesubpath:semanticChecks(doc, options)runs the document-level semantic checks that the JSON Schema cannot express — cross-references (group andrelatedtargets), input-flag contracts (hidden/disabledrequireautofilland are mutually exclusive), action/event/error key formats,tokenAddress+tokenParammutual exclusion, and variant ambiguity (actions on one function with identical locked parameters, which calldata matching cannot distinguish). Pure and filesystem-free — existence checks are injected viaoptions.interfaceExists, andoptions.expectedAddressverifies the document's address. Returns structuredSemanticIssue { path, message }objects. This is the canonical implementation previously duplicated in the contract-metadata repo's validate script, which now consumes it.
-
17d370fThanks @jwahdatehagh! - Detect ERC-20/ERC-721 standards from the final ABI (after proxy composition) and apply the bundled interface metadata layer at the lowest merge priority — labeled actions, groups, and semantic types liketoken-amountfor any standard token, no curated document required. When no metadata layer providesname/symbol, they are read from the contract on-chain. Detection is reported inresult.interfacesand can be disabled viasources.interfaces. -
b56b774Thanks @jwahdatehagh! - Align amount rendering with the standard's token-resolution rules.resolveAmountDisplay/formatAmountno longer guess 18 decimals for an unresolvedtoken-amount— they returnnullso callers render the raw value (per the spec, consumers MUST NOT substitute default decimals).formatAmountrenders 2^256-1 as "Unlimited" (configurable via theunlimitedoption;MAX_UINT256is exported). New token-resolution helpers implement the spec's resolution order —tokenAddressOf,tokenParamOf, andresolveTokenAddress(explicittokenAddress→tokenParamsibling-argument reference → described contract for bare forms) — andTokenAmountTypegains the new optionaltokenParamfield. Two new subpath exports:@evmnow/sdk/token(createTokenInfoResolverreadsdecimals()/symbol()over JSON-RPC with caching, in-flight dedup, bytes32-symbol support, and hostile-symbol sanitization) and@evmnow/sdk/intent(renderIntentrenders{param}intent templates with type-formatted values, including{value},#prefixes, and token-amount resolution). The bundled ERC-20 interface types the Permit messagevaluefield astoken-amount.
-
2142b7eThanks @jwahdatehagh! - Resolve legacy ZeppelinOS (pre-EIP-1967) proxies via@1001-digital/proxies0.2.0.Contracts like Circle's USDC (
FiatTokenProxy) store their implementation atkeccak256('org.zeppelinos.proxy.implementation')and were previously not detected —client.getreturned only the proxy's own ABI. They now resolve through the standard proxy pipeline (result.proxy.pattern === 'zeppelinos'), with the implementation ABI merged into the composite ABI.Re-exports the new
detectZeppelinOs,ZEPPELINOS_IMPL_SLOT, andZEPPELINOS_ADMIN_SLOTfrom@evmnow/sdk/sources/proxy.
3e23f05Thanks @jwahdatehagh! - Support positional_Nparameter keys in action metadata:matchActionresolves constraints by ABI position (name keys win), and locked keys that match no ABI parameter fail the variant. AddsparamMetaAtandactionRequiresSenderexports.
-
#5
0a75783Thanks @jwahdatehagh! - Adopt the ABI-independent actions model from the contract-metadata spec.The
functionsdocument section becomesactions, keyed by free-form identifier with an optionalfunctionreference (bare name, signature, or 4-byte selector — defaults to the action id). NewresolveActions(abi, doc)resolves authored actions against the ABI and synthesizes a default action for every function no authored action references; authoring problems are surfaced as structured issues. NewmatchAction(actions, call)implements the spec's calldata-matching algorithm: locked parameters (hidden/disabled with a resolvable autofill) act as equality constraints against decoded arguments, the most-locked surviving candidate wins, and ties break deterministically byorderthen id. Actions may also describe the native currency attached to payable calls via avalueobject (ValueMeta), which participates in matching and validation. Sourcify NatSpec output is converted into the actions shape. -
302ed16Thanks @jwahdatehagh! - Add canonical amount formatting for theeth,gwei,amount, andtoken-amountsemantic types.New pure, dependency-free
@evmnow/sdk/formatmodule:formatAmount,parseAmount,formatUnits,parseUnits,resolveAmountDisplay,amountKind, andisAmountType. Also fixes a schema drift by adding the missing{ type: 'amount', decimals?, symbol? }variant toParamType(exported asAmountType).
- #8
af2eb8bThanks @yougogirldoteth! - Include verified source files for proxy targets wheninclude.sourcesis enabled.
f2a6f75Thanks @jwahdatehagh! - Update proxies library
0e03e1fThanks @yougogirldoteth! - Add structured not found errors for sourcify misses
6dc8182Thanks @yougogirldoteth! - Fix resolving ENS
-
7fe475bThanks @jwahdatehagh! - Initial release of@evmnow/sdk— resolve complete contract metadata from multiple sources.- Repository — curated JSON from the
contract-metadataGitHub repo. - contractURI (ERC-7572) — on-chain contractURI resolution (HTTPS, IPFS,
data:). - Sourcify v2 — ABI, NatSpec (
userdoc/devdoc), optionally sources + deployed bytecode. - On-chain proxies — every major proxy convention: ERC-2535 diamonds, EIP-1967 (transparent / UUPS + beacon), EIP-1822, EIP-1167 clones, Gnosis Safe, EIP-897. Implementation-side ABI + NatSpec are folded back into the main result.
createContractClient(config)— factory returning a client withget,fetchRepository,fetchContractURI,fetchSourcify,fetchProxy.client.get(addressOrEns)— resolves ENS, fetches every enabled source in parallel, resolvesincludes, and returns a singleContractResultwith merged metadata, ABI, NatSpec, optional sources + deployed bytecode, and detected proxy info.- Layered merge — curated repository wins over contractURI wins over Sourcify wins over implementation-derived metadata. Record sections (
functions,events,errors, …) shallow-merge per key. includesresolution — interface references (e.g.interface:erc721) are fetched from the schema base and merged left-to-right under the document.- Proxy pipeline —
detectProxyorchestrator with priority ordering; single-hop resolution;sources.proxy: falseskips detection entirely;sources.sourcify: falsealso disables per-target lookups (no hidden traffic). - ENS resolution —
.ethnames via Universal Resolver, with explicit mainnet RPC support whenchainId !== 1. - Dependency-injected
fetch— pass any fetch-compatible function; no implicit globals. - Pure/standalone exports —
merge,resolveIncludes,fetchRepository,fetchContractURI,fetchSourcify,buildSourcifyLayer,fetchProxy,detectProxy+ per-pattern detectors,enrichTargets,composeProxyResolution,buildCompositeAbi,filterAbiBySelectors,computeSelector,canonicalSignature,mergeNatspecDocs,decodeFacets,resolveUri,namehash,dnsEncode, RPC helpers — all usable without the client.
interface ContractResult { chainId: number; address: string; metadata: ContractMetadataDocument; // merged across every source abi?: unknown[]; // composite (main contract + implementation targets) natspec?: { userdoc?; devdoc? }; sources?: Record<string, string>; deployedBytecode?: string; proxy?: ProxyResolution; // pattern, targets, beacon?, admin?, … }
- Vite build with
preserveModules: truemirrorssrc/→dist/1:1 — every module is independently importable under@evmnow/sdk/...(declared inpackage.json#exports). sideEffects: falsefor aggressive tree-shaking.- Minimal runtime dependencies:
@1001-digital/proxies,@1001-digital/natspec,@noble/hashes.
- Repository — curated JSON from the