ENS DID (did:ens) Integration
This guide covers the did:ens method integration for TrustWeave. The did:ens plugin provides human-readable DID resolution using Ethereum Name Service (ENS).
Overview
The did/plugins/ens module provides an implementation of TrustWeave’s DidMethod interface using the Ethereum Name Service (ENS) resolver. This integration enables you to:
Resolve human-readable DID identifiers (e.g., did:ens:example.eth)
Map ENS domain names to Ethereum addresses
Integrate with ENS resolver contracts
Convert ENS names to did:ethr DIDs for resolution
Installation
Add the did:ens module to your dependencies:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
dependencies {
implementation ( "com.trustweave.did:ens:1.0.0-SNAPSHOT" )
implementation ( "com.trustweave:trustweave-did:1.0.0-SNAPSHOT" )
implementation ( "com.trustweave.did:base:1.0.0-SNAPSHOT" )
implementation ( "com.trustweave.did:ethr:1.0.0-SNAPSHOT" )
implementation ( "com.trustweave:trustweave-anchor:1.0.0-SNAPSHOT" )
implementation ( "com.trustweave:trustweave-core:1.0.0-SNAPSHOT" )
// Web3j for Ethereum blockchain
implementation ( "org.web3j:core:4.10.0" )
// Optional: Polygon client for EVM-compatible chains
implementation ( "com.trustweave.chains:polygon:1.0.0-SNAPSHOT" )
}
Configuration
Basic Configuration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import com.trustweave.ensdid.*
import com.trustweave.anchor.*
import com.trustweave.polygon.PolygonBlockchainAnchorClient
import com.trustweave.kms.*
// Create configuration
val config = EnsDidConfig . builder ()
. ensRegistryAddress ( "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e" ) // Mainnet ENS registry
. rpcUrl ( "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY" )
. chainId ( "eip155:1" ) // Mainnet
. privateKey ( "0x..." ) // Optional: for transactions
. build ()
// Create blockchain anchor client
val anchorClient = PolygonBlockchainAnchorClient ( config . chainId , config . toMap ())
// Create KMS
val kms = InMemoryKeyManagementService ()
// Create did:ens method
val method = EnsDidMethod ( kms , anchorClient , config )
1
2
3
4
5
// Ethereum mainnet
val mainnetConfig = EnsDidConfig . mainnet (
rpcUrl = "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY" ,
privateKey = "0x..." // Optional
)
SPI Auto-Discovery
When the module is on the classpath, did:ens is automatically available:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import com.trustweave.did.*
import com.trustweave.anchor.*
import java.util.ServiceLoader
// Discover did:ens provider
val providers = ServiceLoader . load ( DidMethodProvider :: class . java )
val ensProvider = providers . find { it . supportedMethods . contains ( "ens" ) }
// Create method with required options
val options = didCreationOptions {
property ( "ensRegistryAddress" , "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e" )
property ( "rpcUrl" , "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY" )
property ( "chainId" , "eip155:1" )
property ( "anchorClient" , anchorClient ) // Required: provide anchor client
}
val method = ensProvider ?. create ( "ens" , options )
Usage Examples
Resolving a did:ens
Note: did:ens does not support DID creation. You must first register an ENS domain name and link it to an Ethereum address that has a did:ethr DID.
1
2
3
4
5
6
7
8
9
10
11
12
val config = EnsDidConfig . mainnet ( "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY" )
val anchorClient = PolygonBlockchainAnchorClient ( config . chainId , config . toMap ())
val kms = InMemoryKeyManagementService ()
val method = EnsDidMethod ( kms , anchorClient , config )
// Resolve ENS domain to DID document
val result = method . resolveDid ( "did:ens:example.eth" )
result . document ?. let { doc ->
println ( "Resolved: ${doc.id}" )
println ( "Verification methods: ${doc.verificationMethod.size}" )
} ?: println ( "Not found" )
How it Works
Extract ENS domain : From did:ens:example.eth, extract example.eth
Resolve ENS to address : Query ENS registry to resolve example.eth to Ethereum address
Convert to did:ethr : Convert Ethereum address to did:ethr:0x...
Resolve did:ethr : Use did:ethr method to resolve the DID document
Return did:ens document : Return document with did:ens:example.eth as the ID
ENS Domain DID
1
2
3
did:ens:example.eth
did:ens:alice.eth
did:ens:organization.eth
The DID identifier is the ENS domain name. The method resolves the domain to an Ethereum address and then resolves it as a did:ethr DID.
Limitations
No DID Creation
did:ens does not support creating DIDs. You must:
Register an ENS domain name (via ENS registrar)
Link it to an Ethereum address
Ensure that address has a did:ethr DID
Then resolve it as did:ens
No DID Updates/Deactivation
did:ens does not support updating or deactivating DIDs directly. You must:
Update : Update the underlying did:ethr DID
Deactivate : Deactivate the underlying did:ethr DID
ENS Resolution Process
Query ENS Registry : Resolve ENS domain to Ethereum address
Convert Format : Convert address to did:ethr format
Resolve did:ethr : Use did:ethr resolver to get DID document
Replace ID : Replace did:ethr ID with did:ens ID in document
Configuration Options
EnsDidConfig
1
2
3
4
5
6
7
val config = EnsDidConfig . builder ()
. ensRegistryAddress ( "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e" ) // Required: ENS registry
. rpcUrl ( "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY" ) // Required: RPC endpoint
. chainId ( "eip155:1" ) // Required: Chain ID
. privateKey ( "0x..." ) // Optional: for transactions
. network ( "mainnet" ) // Optional: network name
. build ()
ENS Registry Addresses
Network
Registry Address
Ethereum Mainnet
0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
Sepolia Testnet
0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
Integration with TrustWeave
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import com.trustweave.TrustWeave
import com.trustweave.ensdid.*
import com.trustweave.anchor.*
import com.trustweave.polygon.PolygonBlockchainAnchorClient
val config = EnsDidConfig . mainnet ( "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY" )
val anchorClient = PolygonBlockchainAnchorClient ( config . chainId , config . toMap ())
val TrustWeave = TrustWeave . create {
kms = InMemoryKeyManagementService ()
blockchain {
register ( config . chainId , anchorClient )
}
didMethods {
+ EnsDidMethod ( kms !! , anchorClient , config )
}
}
// Resolve did:ens
val resolved = TrustWeave . resolveDid ( "did:ens:example.eth" ). getOrThrow ()
Error Handling
Common errors and solutions:
Error
Cause
Solution
ensRegistryAddress is required
Missing ENS registry
Provide ENS registry contract address
rpcUrl is required
Missing RPC endpoint
Provide Ethereum RPC URL
chainId is required
Missing chain ID
Specify chain ID (eip155:1, etc.)
did:ens does not support DID creation
Trying to create DID
Register ENS domain first, then resolve
ENS domain not found
Domain not registered
Verify ENS domain exists and is registered
DID document not found
Address has no did:ethr
Ensure address has a did:ethr DID
Testing
For testing without actual ENS resolution:
1
2
3
4
5
6
7
8
import com.trustweave.testkit.anchor.InMemoryBlockchainAnchorClient
val config = EnsDidConfig . mainnet ( "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY" )
val anchorClient = InMemoryBlockchainAnchorClient ( config . chainId )
val method = EnsDidMethod ( kms , anchorClient , config )
// Note: ENS resolution requires actual ENS registry interaction
// For full testing, use a testnet or local Ethereum node
Best Practices
Use ENS for readability : did:ens provides human-readable identifiers
Link to did:ethr : Ensure ENS domain is linked to an address with did:ethr DID
Test on testnets : Use Sepolia testnet for development
Cache resolutions : Cache ENS-to-address mappings for performance
Error handling : Handle cases where ENS domain doesn’t exist or isn’t linked
Use Cases
Human-Readable DIDs
1
2
3
4
5
6
7
// Instead of:
did : ethr : 0x1234567890123456789012345678901234567890
// Use:
did : ens : example . eth
did : ens : alice . eth
did : ens : company . eth
Organizational DIDs
Use ENS for organizational identities:
1
2
3
did : ens : TrustWeave . eth // Company DID
did : ens : engineering . eth // Department DID
did : ens : alice . eth // Employee DID
Troubleshooting
ENS Domain Not Resolving
Verify domain is registered on ENS
Check domain is linked to an Ethereum address
Ensure address has a valid did:ethr DID
Verify RPC endpoint can access Ethereum mainnet
Address Not Found
Ensure Ethereum address has a did:ethr DID document
Verify did:ethr resolution works for the address
Check blockchain connectivity
Next Steps
References