Open
Conversation
…NetworkConfig; all existing tests pass
add mock provider tests for changed=0 and identityOwner=same;
Erc1056Event enum, keccak256 topic hashes, collect_events(), parse_erc1056_event(), enhanced LogFilter (topic0/topic1), MockProvider with logs support. 4 new tests.
…urns (block, event) tuples
filter events by target block, use block timestamp for validTo, populate nextVersionId/nextUpdate, genesis fallback
remove deprecated testnets, add sepolia, fix Georli→Goerli typo, backward-compat aliases for deprecated names
- Switch attribute key encoding to canonical property per VM type (e.g. secp256k1 keys use publicKeyJwk, Ed25519/X25519 use publicKeyMultibase) - Add support for Ed25519VerificationKey2020 and X25519KeyAgreementKey2020 attribute keys - Revise JsonLdContext to bind only relevant properties and VM types - Use content-keyed maps for event deduplication and revocation handling - Ensure revoked delegates/services are removed from the DID document - Update tests for new encoding, revocation, and context bindings - Add bs58 and indexmap workspace dependencies
Add visited set to break cycles when multiple registry calls in the same block cause previousChange == current_block. Follow only strictly retreating pointers (prev < current_block), taking max to avoid skipping intermediate blocks. Add test: collect_events_same_block_events_all_collected
- provider.rs: BlockRef, LogFilter, Log, EthProvider, NetworkConfig - abi.rs: ABI selectors, encode/decode helpers, formatting utils - events.rs: Erc1056Event, parse/collect logic + collect_events tests - network.rs: NetworkChain, InvalidNetwork, DecodedMethodSpecificId, parse_address_bytes - vm.rs: VerificationMethod, VerificationMethodType, Pending* structs, decode_delegate_type - resolver.rs: DIDEthr, apply_events, resolve_*, serialize_document + MockProvider tests - lib.rs: module declarations + public re-exports + offline-only tests
- re-export keccak::keccak256 instead of wrapping - network_name() returns &str to avoid clone - remove calldata.clone() (moved by value) - partition all_events in one pass via Iterator::partition
…TTP JSON-RPC - Implements EthProvider over raw HTTP using reqwest - Adds example to resolve did:ethr DIDs against real Ethereum endpoints - Updates dependencies in Cargo.toml for example support - Fixes DIDEthr instantiation for generic parameter compliance
- Accept DID and RPC URL as command-line arguments with sensible defaults - Enhance error messages for missing or malformed JSON fields - Refactor main logic into resolve_did for clarity and testability - Print input parameters and handle resolution errors gracefully
… network inference and defaults
…iry; improve uint256 decoding and multibase encoding - Fix delegate/attribute expiry logic to use the target block's timestamp, not meta_block's, for historical resolution - Make decode_uint256 return Result and handle overflows/short data - Update event decoding to propagate uint256 decode errors - Refactor account_address_hex to return Option and handle malformed keys - Add encode_multibase_multicodec for correct Ed25519/X25519 multibase encoding per spec - Add tests for historical expiry and multibase encoding - Update dependencies for ssi-multicodec and multibase
There was a problem hiding this comment.
Pull request overview
This PR refactors the Rust did:ethr resolver to align with the ERC-1056 / did:ethr spec by adding an on-chain resolution path (via an EthProvider abstraction) while retaining the existing offline “genesis document” behavior for backward compatibility.
Changes:
- Introduces
EthProvider+ per-network configuration and makesDIDEthrgeneric to support on-chain resolution. - Implements ERC-1056 event-log walking and event application to construct accurate DID Documents (including historical
?versionId=resolution and metadata). - Fixes/extends key materialization and JSON-LD context generation (including corrected multibase+multicodec encoding for Ed25519/X25519).
Reviewed changes
Copilot reviewed 14 out of 15 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
examples/resolve_with_provider.rs |
Adds a runnable JSON-RPC-based example provider and live resolution demo. |
crates/dids/src/lib.rs |
Updates the “any DID method” resolver to use DIDEthr::<()>::default() for offline mode. |
crates/dids/methods/ethr/tests/did-pk.jsonld |
Updates expected JSON-LD to include Eip712Method2021 for pubkey DIDs. |
crates/dids/methods/ethr/src/abi.rs |
Adds ERC-1056 selectors, ABI encoding/decoding helpers, and timestamp formatting. |
crates/dids/methods/ethr/src/events.rs |
Adds ERC-1056 log parsing and linked-list event collection logic (+ tests). |
crates/dids/methods/ethr/src/json_ld_context.rs |
Extends context generation to cover more VM types and properties. |
crates/dids/methods/ethr/src/lib.rs |
Restructures the crate into modules and re-exports the new public API. |
crates/dids/methods/ethr/src/network.rs |
Implements network parsing (names + hex chain IDs) and address derivation for pubkey DIDs. |
crates/dids/methods/ethr/src/provider.rs |
Introduces EthProvider, LogFilter, Log, BlockRef, and NetworkConfig. |
crates/dids/methods/ethr/src/resolver.rs |
Implements the new resolver (offline + on-chain + historical resolution) and extensive tests. |
crates/dids/methods/ethr/src/vm.rs |
Adds intermediate VM/service representations and VM type definitions. |
crates/dids/methods/ethr/Cargo.toml |
Adds dependencies needed for on-chain resolution and multibase/multicodec encoding. |
crates/dids/core/src/document.rs |
Extends DID resolution metadata with versionId/updated/nextVersionId/nextUpdate. |
crates/crypto/src/hashes/keccak.rs |
Exposes a keccak256 helper used by the resolver crate. |
Cargo.toml |
Adds workspace deps to support the new example and resolver usage. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…DID in resolve_with_provider example
…collection - Add log_index to Log struct and propagate throughout event collection - Sort events by (block_number, log_index) to maintain correct intra-block ordering - Update tests to verify intra-block order is preserved
…d test for incomplete value data
… EthProvider trait and cache per network
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Aligns the Rust did:ethr resolver with the ERC-1056 / did:ethr method spec.
The resolver is now generic over an EthProvider trait, enabling both offline (genesis document) and on-chain resolution modes.
I only kept the offline mode for some form of backward compatibility but would prefer to error if no provider is configured since the genesis document behavior alone is not spec-compliant. The on-chain resolution mode is the main new feature here, and it fully implements the ERC-1056 event processing logic to build accurate DID documents reflecting all on-chain changes.
fixes #287
What changed
DIDEthris nowDIDEthr<P = ()>— generic over an Ethereum provider.DIDEthr<()>retains the existing offline-only behavior (genesis documents). When a provider implementing EthProvider is configured, the resolver walks the ERC-1056 DIDRegistry event log to build the full document.EthProvidertrait — a minimal async trait (call,get_logs,block_timestamp) that users implement with their preferred Ethereum client (ethers, alloy, raw HTTP, etc.). A working example using a bare JSON-RPC HTTP client is inexamples/resolve_with_provider.rs.DIDEthr::add_network(). Named networks (mainnet, sepolia, etc) and hex chain IDs (0x5) are supported. Deprecated testnets (goerli, ropsten, rinkeby, etc.) still parse for backward compatibility.DIDOwnerChanged— ownership transfersDIDDelegateChanged— veriKey and sigAuth delegate typesDIDAttributeChanged— attribute-based verification methods (secp256k1, Ed25519, X25519) and service endpoints (URL and JSON)#delegate-N/#service-Nfragment IDs?versionId=Nresolves the document as of blockN, withversionId,updated,nextVersionId, andnextUpdatein document metadata.Metadatastruct extended — addedversion_id,updated,next_version_id,next_updatefields.Copyremoved (breaking — now contains String fields).Deliberate deviations from spec
DIDAttributeChangedattribute names (e.g.did/pub/secp256k1/veriKey/hex) is ignored. All attribute-based keys are materialized as JWK (publicKeyJwk) forsecp256k1ormultibaseforEd25519/X25519, regardless of the hint. This is because I plan to remove the encoding hint from the spec.Usage changes
Other changes
multibaseforEd25519/X25519encoding was inaccurate, missing thevarintprefix.Now we encode the raw key bytes as
multibase(base58btc)with a multicodec varint prefix.This matches the encoding expected by
Ed25519VerificationKey2020andX25519KeyAgreementKey2020verification method types per W3C spec.Optional section
Tested
Extensive unit test suite was added to the ethr crate and an example was added demonstrating on-chain resolution with a custom provider:
will resolve a live mainnet DID that had an owner change. The
blockchainAccountIdof of the#controllerwill show a different address than the DID identifier's address, confirming that the on-chain event processing is working correctly.You can test other DIDs and networks:
cargo run --example resolve_with_provider did:ethr:mainnet:0x0a327968f9f2592b566279357fb05e04498ac81f`I'm the maintainer of the did:ethr spec and reference implementation. Feel free to question. I'm looking for feedback from real-world usage.