DID Operations Tutorial
This tutorial provides a comprehensive guide to performing DID operations with TrustWeave. You’ll learn how to create, resolve, update, and deactivate DIDs using various DID methods.
1
2
3
4
5
6
dependencies {
implementation("com.trustweave:trustweave-did:1.0.0-SNAPSHOT")
implementation("com.trustweave:trustweave-kms:1.0.0-SNAPSHOT")
implementation("com.trustweave:trustweave-common:1.0.0-SNAPSHOT")
implementation("com.trustweave:trustweave-testkit:1.0.0-SNAPSHOT")
}
Result: Gives you the DID registry, DID method interfaces, KMS abstractions, and in-memory implementations used throughout this tutorial.
Tip: The runnable quick-start sample (
./gradlew :TrustWeave-examples:runQuickStartSample) mirrors the core flows below. Clone it as a starting point before wiring more advanced DID logic.
Prerequisites
- Basic understanding of Kotlin
- Familiarity with coroutines
- Understanding of DIDs
Table of Contents
- Understanding DID Methods
- Creating DIDs
- Resolving DIDs
- Updating DIDs
- Deactivating DIDs
- Working with Multiple DID Methods
- Advanced DID Operations
Understanding DID Methods
A DID method is an implementation of the DidMethod interface that supports a specific DID method (e.g., did:key, did:web, did:ion). Each DID method has its own creation, resolution, update, and deactivation logic.
1
2
3
4
5
6
7
8
9
import com.trustweave.did.*
interface DidMethod {
val method: String
suspend fun createDid(options: DidCreationOptions): DidDocument
suspend fun resolveDid(did: String): DidResolutionResult
suspend fun updateDid(did: String, updater: (DidDocument) -> DidDocument): DidDocument
suspend fun deactivateDid(did: String): Boolean
}
What this does: Defines the contract for DID operations that all DID method implementations must fulfill.
Outcome: Enables TrustWeave to support multiple DID methods through a unified interface.
Creating DIDs
Using TrustWeave DSL (Recommended)
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
// Kotlin stdlib
import kotlinx.coroutines.runBlocking
// TrustWeave core
import com.trustweave.trust.TrustWeave
import com.trustweave.trust.dsl.credential.DidMethods
import com.trustweave.trust.dsl.credential.KeyAlgorithms
// Note: TestkitDidMethodFactory is for testing/tutorials only
// In production, use appropriate DID method factories
import com.trustweave.testkit.services.*
fun main() = runBlocking {
// Build TrustWeave instance with testkit factories (for tutorials)
val trustWeave = TrustWeave.build {
factories(
didMethodFactory = TestkitDidMethodFactory() // Test-only factory
)
keys {
provider("inMemory")
algorithm(KeyAlgorithms.ED25519)
}
did {
method(DidMethods.KEY) {
algorithm(KeyAlgorithms.ED25519)
}
}
}
// Create DID using did:key method (returns sealed result)
import com.trustweave.trust.types.DidCreationResult
val didResult = trustWeave.createDid {
method(DidMethods.KEY)
algorithm(KeyAlgorithms.ED25519)
}
when (didResult) {
is DidCreationResult.Success -> {
println("Created DID: ${didResult.did.value}")
}
else -> {
println("DID creation failed: ${didResult.reason}")
}
}
}
Outcome: Creates a DID using the configured DID method. Returns a type-safe Did object - access the string value using .value.
Creating DIDs with Specific Methods
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
51
52
53
// Kotlin stdlib
import kotlinx.coroutines.runBlocking
// TrustWeave core
import com.trustweave.trust.TrustWeave
import com.trustweave.trust.dsl.credential.DidMethods
import com.trustweave.trust.dsl.credential.KeyAlgorithms
// Note: TestkitDidMethodFactory is for testing/tutorials only
// In production, use appropriate DID method factories
import com.trustweave.testkit.services.*
fun main() = runBlocking {
// Build TrustWeave instance with testkit factories (for tutorials)
val trustWeave = TrustWeave.build {
factories(didMethodFactory = TestkitDidMethodFactory()) // Test-only factory
keys { provider("inMemory"); algorithm(KeyAlgorithms.ED25519) }
did {
method(DidMethods.KEY) { algorithm(KeyAlgorithms.ED25519) }
method(DidMethods.WEB) { domain("example.com") }
}
}
// Create DID with did:key method
val keyDidResult = trustWeave.createDid {
method(DidMethods.KEY)
algorithm(KeyAlgorithms.ED25519)
}
val keyDid = when (keyDidResult) {
is DidCreationResult.Success -> keyDidResult.did
else -> {
println("Failed to create key DID: ${keyDidResult.reason}")
return@runBlocking
}
}
// Create DID with did:web method
val webDidResult = trustWeave.createDid {
method(DidMethods.WEB)
domain("example.com")
}
val webDid = when (webDidResult) {
is DidCreationResult.Success -> webDidResult.did
else -> {
println("Failed to create web DID: ${webDidResult.reason}")
return@runBlocking
}
}
println("Key DID: ${keyDid.value}")
println("Web DID: ${webDid.value}")
}
Outcome: Creates DIDs using specific DID methods with custom configuration options.
Using DID Method Registry
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
// Kotlin stdlib
import kotlinx.coroutines.runBlocking
// TrustWeave core
import com.trustweave.did.*
import com.trustweave.kms.*
import com.trustweave.testkit.kms.InMemoryKeyManagementService
fun main() = runBlocking {
// Create KMS
val kms = InMemoryKeyManagementService()
// Create DID method registry
val registry = DidMethodRegistry()
// Register did:key method
val keyMethod = /* create or discover did:key method */
registry.register("key", keyMethod)
// Create DID using registry
val options = didCreationOptions {
algorithm = KeyAlgorithm.Secp256k1
}
val method = registry.get("key")
val didDoc = method?.createDid(options)
println("Created DID: ${didDoc?.id}")
}
Outcome: Creates a DID using a manually configured DID method registry.
Resolving DIDs
Resolving DIDs with TrustWeave DSL
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
import com.trustweave.trust.TrustWeave
import com.trustweave.trust.dsl.credential.DidMethods
import com.trustweave.trust.dsl.credential.KeyAlgorithms
import com.trustweave.trust.types.Did
import com.trustweave.did.resolver.DidResolutionResult
import com.trustweave.testkit.services.*
import kotlinx.coroutines.runBlocking
fun main() = runBlocking {
val trustWeave = TrustWeave.build {
factories(didMethodFactory = TestkitDidMethodFactory())
keys { provider("inMemory"); algorithm(KeyAlgorithms.ED25519) }
did { method(DidMethods.KEY) { algorithm(KeyAlgorithms.ED25519) } }
}
val didString = "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"
val resolution = trustWeave.resolveDid(didString)
when (resolution) {
is DidResolutionResult.Success -> {
println("Resolved DID: ${resolution.document.id}")
println("Document: ${resolution.document}")
println("Verification methods: ${resolution.document.verificationMethod.size}")
}
is DidResolutionResult.Failure.NotFound -> {
println("DID not found: ${resolution.did.value}")
}
is DidResolutionResult.Failure.InvalidFormat -> {
println("Invalid DID format: ${resolution.reason}")
}
is DidResolutionResult.Failure.MethodNotRegistered -> {
println("DID method not registered: ${resolution.method}")
}
else -> {
println("Resolution failed")
}
}
}
Outcome: Resolves a DID using the appropriate DID method automatically. Returns a sealed DidResolutionResult for type-safe error handling.
Resolving DIDs with Method Registry
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Kotlin stdlib
import kotlinx.coroutines.runBlocking
// TrustWeave core
import com.trustweave.did.*
fun main() = runBlocking {
val registry = DidMethodRegistry()
// ... register methods ...
val did = "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"
val resolutionResult = registry.resolve(did)
resolutionResult.fold(
onSuccess = { result ->
println("Resolved: ${result.didDocument?.id}")
},
onFailure = { error ->
println("Resolution failed: ${error.message}")
}
)
}
Outcome: Resolves a DID using a manually configured method registry.
Updating DIDs
Updating DID Documents
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
// Kotlin stdlib
import kotlinx.coroutines.runBlocking
// TrustWeave core
import com.trustweave.trust.TrustWeave
import com.trustweave.trust.dsl.credential.DidMethods
import com.trustweave.trust.dsl.credential.KeyAlgorithms
import com.trustweave.did.*
import com.trustweave.testkit.services.*
fun main() = runBlocking {
val trustWeave = TrustWeave.build {
factories(didMethodFactory = TestkitDidMethodFactory())
keys { provider("inMemory"); algorithm(KeyAlgorithms.ED25519) }
did { method(DidMethods.KEY) { algorithm(KeyAlgorithms.ED25519) } }
}
val didString = "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"
// Update DID document
try {
val updatedDoc = trustWeave.updateDid {
did(didString)
// Add a new service endpoint
service {
id("${didString}#service-1")
type("LinkedDomains")
endpoint("https://example.com/service")
}
}
println("Updated DID: ${updatedDoc.id}")
println("Services: ${updatedDoc.service.size}")
} catch (error: Exception) {
println("Update failed: ${error.message}")
}
}
Outcome: Updates a DID document with new verification methods or services.
Deactivating DIDs
Deactivating DIDs
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
// Kotlin stdlib
import kotlinx.coroutines.runBlocking
// TrustWeave core
import com.trustweave.trust.TrustWeave
import com.trustweave.trust.dsl.credential.DidMethods
import com.trustweave.trust.dsl.credential.KeyAlgorithms
import com.trustweave.testkit.services.*
fun main() = runBlocking {
val trustWeave = TrustWeave.build {
factories(didMethodFactory = TestkitDidMethodFactory())
keys { provider("inMemory"); algorithm(KeyAlgorithms.ED25519) }
did { method(DidMethods.KEY) { algorithm(KeyAlgorithms.ED25519) } }
}
val didString = "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"
// Deactivate DID (via updateDid with deactivated flag)
try {
val updatedDoc = trustWeave.updateDid {
did(didString)
deactivated(true)
}
println("DID deactivated successfully: ${updatedDoc.id}")
} catch (error: Exception) {
println("Deactivation error: ${error.message}")
}
}
Outcome: Deactivates a DID, marking it as no longer active.
Working with Multiple DID Methods
Managing Multiple DID Methods
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
// Kotlin stdlib
import kotlinx.coroutines.runBlocking
// TrustWeave core
import com.trustweave.did.*
import com.trustweave.kms.*
fun main() = runBlocking {
val kms = InMemoryKeyManagementService()
val registry = DidMethodRegistry()
// Register multiple DID methods
registry.register("key", /* did:key method */)
registry.register("web", /* did:web method */)
registry.register("ion", /* did:ion method */)
// Create DIDs using different methods
val keyDid = registry.get("key")?.createDid(didCreationOptions {
algorithm = KeyAlgorithm.Ed25519
})
val webDid = registry.get("web")?.createDid(didCreationOptions {
domain = "example.com"
path = "/did/user/alice"
})
val ionDid = registry.get("ion")?.createDid(didCreationOptions {
// ION-specific options
})
println("Key DID: ${keyDid?.id}")
println("Web DID: ${webDid?.id}")
println("ION DID: ${ionDid?.id}")
}
Outcome: Demonstrates how to work with multiple DID methods in the same application.
Advanced DID Operations
Working with DID Documents
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
// Kotlin stdlib
import kotlinx.coroutines.runBlocking
// TrustWeave core
import com.trustweave.trust.TrustWeave
import com.trustweave.trust.dsl.credential.DidMethods
import com.trustweave.trust.dsl.credential.KeyAlgorithms
import com.trustweave.did.*
import com.trustweave.testkit.services.*
fun main() = runBlocking {
// Build TrustWeave instance with testkit factories (for tutorials)
val trustWeave = TrustWeave.build {
factories(didMethodFactory = TestkitDidMethodFactory()) // Test-only factory
keys { provider("inMemory"); algorithm(KeyAlgorithms.ED25519) }
did { method(DidMethods.KEY) { algorithm(KeyAlgorithms.ED25519) } }
}
try {
val did = trustWeave.createDid {
method(DidMethods.KEY)
algorithm(KeyAlgorithms.ED25519)
}
// Resolve DID to get document
val resolution = trustWeave.resolveDid(did)
val document = when (resolution) {
is DidResolutionResult.Success -> resolution.document
else -> throw IllegalStateException("Failed to resolve DID")
}
// Access verification methods
val verificationMethods = document.verificationMethod
println("Verification methods: ${verificationMethods.size}")
// Access services
val services = document.service
println("Services: ${services.size}")
// Access authentication methods
val authentication = document.authentication
println("Authentication methods: ${authentication.size}")
} catch (error: Exception) {
println("Error: ${error.message}")
}
}
Outcome: Shows how to access and work with DID document components.
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
31
32
33
34
35
36
37
38
39
40
41
42
43
// Kotlin stdlib
import kotlinx.coroutines.runBlocking
// TrustWeave core
import com.trustweave.trust.TrustWeave
import com.trustweave.trust.dsl.credential.DidMethods
import com.trustweave.trust.dsl.credential.KeyAlgorithms
import com.trustweave.core.exception.TrustWeaveError
import com.trustweave.testkit.services.*
fun main() = runBlocking {
// Build TrustWeave instance with testkit factories (for tutorials)
val trustWeave = TrustWeave.build {
factories(didMethodFactory = TestkitDidMethodFactory()) // Test-only factory
keys { provider("inMemory"); algorithm(KeyAlgorithms.ED25519) }
did { method(DidMethods.KEY) { algorithm(KeyAlgorithms.ED25519) } }
}
try {
val did = trustWeave.createDid {
method(DidMethods.KEY)
algorithm(KeyAlgorithms.ED25519)
}
println("Created: ${did.value}")
} catch (error: Exception) {
when (error) {
is IllegalStateException -> {
if (error.message?.contains("not configured") == true) {
println("DID method not configured: ${error.message}")
} else {
println("Error: ${error.message}")
}
}
else -> {
println("Error: ${error.message}")
}
is TrustWeaveError.DidNotFound -> {
println("DID not found: ${error.did}")
}
else -> println("Error: ${error.message}")
}
}
}
Outcome: Demonstrates structured error handling for DID operations.
Next Steps
- Review DID Concepts for deeper understanding
- Explore DID Integration Guides for specific method implementations
- See Wallet API Tutorial for credential workflows
- Check Creating Plugins to implement custom DID methods