Create and Manage DIDs

This guide shows you how to create, resolve, update, and deactivate Decentralized Identifiers (DIDs) using TrustWeave.

Quick Example

Here’s a complete example that creates a DID, extracts the key ID, and uses it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import com.trustweave.trust.TrustWeave
import com.trustweave.trust.types.Did
import com.trustweave.did.resolver.DidResolutionResult
import com.trustweave.core.exception.TrustWeaveException
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    try {
        // Create TrustWeave instance
        val trustWeave = TrustWeave.build {
            keys {
                provider("inMemory")
                algorithm("Ed25519")
            }
            did {
                method("key") {
                    algorithm("Ed25519")
                }
            }
        }

        // Create a DID (returns type-safe Did)
        val issuerDid: Did = trustWeave.createDid {
            method("key")
            algorithm("Ed25519")
        }

        // Extract key ID for signing by resolving the DID
        val resolutionResult = trustWeave.resolveDid(issuerDid)
        val issuerDocument = when (resolutionResult) {
            is DidResolutionResult.Success -> resolutionResult.document
            else -> throw IllegalStateException("Failed to resolve issuer DID")
        }
        val verificationMethod = issuerDocument.verificationMethod.firstOrNull()
            ?: throw IllegalStateException("No verification method found")
        val issuerKeyId = verificationMethod.id.substringAfter("#")

        println("Created DID: ${issuerDid.value}")
        println("Key ID: $issuerKeyId")
} catch (error: TrustWeaveException) {
    when (error) {
        is TrustWeaveException.PluginNotFound -> {
            println("❌ DID method not registered: ${error.pluginId}")
        }
        else -> {
            println("❌ Error: ${error.message}")
        }
    }
}
}

Expected Output:

1
2
Created DID: did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK
Key ID: key-1

Note: createDid() returns a type-safe Did object. Access the string value using .value property.

Step-by-Step Guide

Step 1: Configure TrustWeave

First, create a TrustWeave instance with DID method support:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
val trustWeave = TrustWeave.build {
    keys {
        provider("inMemory")  // For testing; use production KMS in production
        algorithm("Ed25519")
    }
    did {
        method("key") {  // Register did:key method
            algorithm("Ed25519")
        }
        // Add more methods as needed
        method("web") {
            domain("example.com")
        }
    }
}

Step 2: Create a DID

Create a DID using the default method (did:key) or specify a method:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Simple: Use defaults (did:key, ED25519)
val did = trustWeave.createDid {
    method("key")
    algorithm("Ed25519")
}

// Or even simpler with default method
val didSimple = trustWeave.createDid()  // Uses "key" method by default

// With custom method
val webDid = trustWeave.createDid {
    method("web")
    domain("example.com")
}

Step 3: Extract Key ID

Extract the key ID from the DID for signing operations:

1
2
3
4
5
6
7
8
9
10
11
12
13
val did = trustWeave.createDid { method("key") }

// Resolve DID to get verification method
val resolutionResult = trustWeave.resolveDid(did)
val document = when (resolutionResult) {
    is DidResolutionResult.Success -> resolutionResult.document
    else -> throw IllegalStateException("Failed to resolve DID")
}

// Extract key ID from verification method
val verificationMethod = document.verificationMethod.firstOrNull()
    ?: throw IllegalStateException("No verification method found")
val keyId = verificationMethod.id.substringAfter("#")  // e.g., "key-1"

Step 4: Use the DID

Use the DID and key ID in credential operations:

1
2
3
4
5
6
7
val credential = trustWeave.issue {
    credential {
        issuer(did.value)
        // ... credential configuration
    }
    signedBy(issuerDid = did.value, keyId = keyId)  // keyId is already a String
}

Common Patterns

Pattern 1: Create Multiple DIDs

Create DIDs for different roles (issuer, holder, verifier):

1
2
3
4
5
6
7
val issuerDid = trustWeave.createDid { method("key") }
val holderDid = trustWeave.createDid { method("key") }
val verifierDid = trustWeave.createDid { method("key") }

println("Issuer: $issuerDid")
println("Holder: $holderDid")
println("Verifier: $verifierDid")

Pattern 2: Create DID with Error Handling

Handle errors gracefully:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
val did = try {
    trustWeave.createDid {
        method("key")
        algorithm("Ed25519")
    }
} catch (error: TrustWeaveException) {
    when (error) {
        is TrustWeaveException.PluginNotFound -> {
            println("DID method not registered: ${error.pluginId}")
            return@runBlocking
        }
        else -> {
            println("Unexpected error: ${error.message}")
            return@runBlocking
        }
    }
}

Pattern 3: Resolve a DID

Resolve a DID to get its document:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
val result = trustWeave.resolveDid("did:key:z6Mk...")

when (result) {
    is DidResolutionResult.Success -> {
        println("DID resolved: ${result.document.id}")
        println("Verification methods: ${result.document.verificationMethod.size}")
    }
    is DidResolutionResult.Failure.NotFound -> {
        println("DID not found: ${result.did}")
    }
    is DidResolutionResult.Failure.InvalidFormat -> {
        println("Invalid DID format: ${result.reason}")
    }
    is DidResolutionResult.Failure.MethodNotRegistered -> {
        println("DID method not registered: ${result.method}")
    }
    else -> {
        println("Resolution failed: ${result}")
    }
}

Pattern 4: Update a DID Document

Update a DID document to add services or verification methods:

1
2
3
4
5
6
7
8
val updated = trustWeave.updateDid {
    did("did:key:example")
    addService {
        id("${did.value}#service-1")
        type("LinkedDomains")
        endpoint("https://example.com/service")
    }
}

Pattern 5: Deactivate a DID

Deactivate a DID when it’s no longer needed:

1
2
3
4
// Note: Deactivation depends on the DID method implementation
// For did:key, deactivation is typically not supported as it's stateless
// For other methods like did:web or did:ion, use the method-specific deactivation API
// This is typically handled through updateDid with a deactivated flag

DID Methods

TrustWeave supports multiple DID methods. Choose based on your needs:

Method Use Case Network Required
did:key Testing, simple use cases No
did:web Web-based identity Yes (HTTPS)
did:ion Microsoft ION network Yes
did:ethr Ethereum-based identity Yes (Ethereum)
did:polygon Polygon-based identity Yes (Polygon)

See DID Method Integrations for complete list.

Error Handling

DID operations now return sealed result types instead of throwing exceptions. This provides type-safe, exhaustive error handling:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import com.trustweave.trust.types.DidCreationResult

val didResult = trustWeave.createDid { 
    method("key") 
}

when (didResult) {
    is DidCreationResult.Success -> {
        println("Created DID: ${didResult.did.value}")
        // Use didResult.did and didResult.document
    }
    is DidCreationResult.Failure.MethodNotRegistered -> {
        println("DID method not found: ${didResult.method}")
        println("Available methods: ${didResult.availableMethods.joinToString()}")
    }
    is DidCreationResult.Failure.KeyGenerationFailed -> {
        println("Key generation failed: ${didResult.reason}")
        didResult.cause?.printStackTrace()
    }
    is DidCreationResult.Failure.DocumentCreationFailed -> {
        println("Document creation failed: ${didResult.reason}")
    }
    is DidCreationResult.Failure.InvalidConfiguration -> {
        println("Invalid configuration: ${didResult.reason}")
    }
    is DidCreationResult.Failure.Other -> {
        println("Error: ${didResult.reason}")
        didResult.cause?.printStackTrace()
    }
}

For tests and examples, you can use the getOrFail() helper:

1
2
3
4
import com.trustweave.testkit.getOrFail

val did = trustWeave.createDid { method("key") }.getOrFail()
// Throws AssertionError on failure (suitable for tests/examples only)

Note: All I/O operations (createDid, issue, updateDid, rotateKey, wallet, revoke) now return sealed result types for exhaustive error handling. resolveDid() also returns a sealed result type.

API Reference

For complete API documentation, see:

See Also

Next Steps

Ready to issue credentials?

Want to learn more?