Configure TrustWeave

URL note: This page is served at how-to/configure-trustlayer/ for backward compatibility with older links. The framework name is TrustWeave only—there is no separate “TrustLayer” product.

This guide shows you how to configure TrustWeave using the declarative DSL. You’ll learn how to set up key management, DID methods, blockchain anchors, and trust registries in a simple, readable way.

Prerequisites

Before you begin, ensure you have:

  • TrustWeave dependencies added to your project
  • Basic understanding of DIDs, credentials, and blockchains
  • Kotlin coroutines knowledge (for suspend functions)

Expected Outcome

After completing this guide, you will have:

  • A fully configured TrustWeave instance
  • Multiple DID methods registered
  • Blockchain anchors configured
  • A trust registry set up
  • Understanding of the declarative DSL approach

Quick Example

Here’s a complete example showing the power of declarative configuration:

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 org.trustweave.trust.TrustWeave
import org.trustweave.trust.types.getOrThrow
import org.trustweave.trust.dsl.credential.*
import org.trustweave.testkit.services.*
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    val trustWeave = TrustWeave.build {
        keys {
            provider(IN_MEMORY)  // Auto-discovered via SPI
            algorithm(ED25519)
        }

        did {
            method(KEY) {  // Auto-discovered via SPI
                algorithm(ED25519)
            }
            method(WEB) {  // Auto-discovered via SPI
                domain("example.com")
            }
        }

        anchor {
            chain("algorand:testnet") {
                provider(ALGORAND)  // Auto-discovered via SPI
            }
        }

        trust {
            provider(IN_MEMORY)
        }
        // KMS, DID methods, anchor clients, and CredentialService all auto-created!
    }

    // Use the configured TrustWeave instance
    val (did, _) = trustWeave.createDid().getOrThrow()
    println("Created DID: ${did.value}")
}

Expected Output:

1
Created DID: did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK

Auto-Discovery via SPI

TrustWeave automatically discovers KMS, DID methods, and anchor clients via Java Service Provider Interface (SPI). When you specify a provider name, TrustWeave will automatically find and use the appropriate implementation from the classpath.

Auto-Discovered Services:

  • KMS - Automatically discovered when using keys { provider("inMemory") } or other provider names
  • DID Methods - Automatically discovered when using did { method("key") } or other method names
  • Anchor Clients - Automatically discovered when using anchor { chain(...) { provider(...) } }

Optional Factories (for services without SPI):

  • trustRegistryFactory - Optional when using trust { provider(IN_MEMORY) }
  • statusListRegistryFactory - Optional when using revocation { provider(IN_MEMORY) }
  • walletFactory - Optional when using wallet { }

For Testing: Use testkit factories from org.trustweave.testkit.services (only for services without SPI):

  • TestkitTrustRegistryFactory() - For trust registries
  • TestkitStatusListRegistryFactory() - For revocation managers
  • TestkitWalletFactory() - For wallets

Note: KMS, DID methods, and anchor clients are automatically discovered via SPI when testkit is on the classpath. No factories needed!

Step-by-Step Guide

Step 1: Start with Basic Configuration

Begin by creating a minimal TrustWeave configuration with just key management:

1
2
3
4
5
6
7
8
9
10
11
12
import org.trustweave.trust.TrustWeave
import org.trustweave.trust.types.getOrThrow
import org.trustweave.trust.dsl.credential.*
import org.trustweave.testkit.services.*

val trustWeave = TrustWeave.build {
    keys {
        provider(IN_MEMORY)  // Auto-discovered via SPI
        algorithm(ED25519)
    }
    // KMS auto-created!
}

What this does:

  • Configures an in-memory key management service
  • Sets Ed25519 as the default algorithm
  • Provides the foundation for all cryptographic operations

Expected Result: A TrustWeave instance that can generate and manage keys.


Step 2: Register DID Methods

Add DID method support to your configuration:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import org.trustweave.trust.TrustWeave
import org.trustweave.trust.types.getOrThrow
import org.trustweave.trust.dsl.credential.*
import org.trustweave.testkit.services.*

val trustWeave = TrustWeave.build {
    keys {
        provider(IN_MEMORY)  // Auto-discovered via SPI
        algorithm(ED25519)
    }

    did {
        method(KEY) {  // Auto-discovered via SPI
            algorithm(ED25519)
        }
    }
    // KMS, DID methods, and CredentialService all auto-created!
}

What this does:

  • Registers the did:key method
  • Configures it to use Ed25519 keys
  • Enables DID creation with createDid().getOrThrow() (uses default method from config)

Expected Result: You can now create did:key identifiers.


Step 3: Add Multiple DID Methods

Register additional DID methods for different use cases:

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
import org.trustweave.trust.TrustWeave
import org.trustweave.trust.types.getOrThrow
import org.trustweave.trust.dsl.credential.*
import org.trustweave.testkit.services.*

val trustWeave = TrustWeave.build {
    // KMS and DID methods auto-discovered via SPI
    keys {
        provider(IN_MEMORY)
        algorithm(ED25519)
    }

    did {
        method(KEY) {
            algorithm(ED25519)
        }
        method(WEB) {
            domain("example.com")
        }
            method(ETHR) {
            // Ethereum-specific configuration
            network("sepolia")
        }
    }
}

What this does:

  • Registers did:key for local, self-sovereign identifiers
  • Registers did:web for domain-based identifiers
  • Registers did:ethr for Ethereum-based identifiers

Expected Result: You can create DIDs using any registered method.


Step 4: Configure Blockchain Anchors

Add blockchain anchoring support for tamper evidence:

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
import org.trustweave.trust.TrustWeave
import org.trustweave.trust.types.getOrThrow
import org.trustweave.trust.dsl.credential.*
import org.trustweave.testkit.services.*

val trustWeave = TrustWeave.build {
    // KMS, DID methods, and anchor clients auto-discovered via SPI
    keys {
        provider(IN_MEMORY)
        algorithm(ED25519)
    }

    did {
        method(KEY) {
            algorithm(ED25519)
        }
    }

    anchor {
        chain("algorand:testnet") {
            provider(ALGORAND)
            // Or use inMemory for testing
            // inMemory()
        }
        chain("polygon:mainnet") {
            provider(POLYGON)
        }
    }
}

What this does:

  • Registers Algorand testnet for development
  • Registers Polygon mainnet for production
  • Uses CAIP-2 chain identifiers (standard format)

Expected Result: You can anchor data to multiple blockchains.


Step 5: Configure Trust Registry

Add trust registry for managing trusted issuers:

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
import org.trustweave.trust.TrustWeave
import org.trustweave.trust.types.getOrThrow
import org.trustweave.trust.dsl.credential.*
import org.trustweave.testkit.services.*

val trustWeave = TrustWeave.build {
    factories(
        trustRegistryFactory = TestkitTrustRegistryFactory()  // Only needed for trust registry
    )
    // KMS, DID methods, and anchor clients auto-discovered via SPI
    keys {
        provider(IN_MEMORY)
        algorithm(ED25519)
    }

    did {
        method(KEY) {
            algorithm(ED25519)
        }
    }

    anchor {
        chain("algorand:testnet") {
            provider(ALGORAND)
        }
    }

    trust {
        provider(IN_MEMORY)
    }
}

What this does:

  • Sets up an in-memory trust registry
  • Enables trust anchor management
  • Allows verification with trust checking

Expected Result: You can manage trusted issuers and verify credentials with trust validation.


Step 6: Complete Configuration

Here’s a complete production-ready configuration:

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
import org.trustweave.trust.TrustWeave
import org.trustweave.trust.types.getOrThrow
import org.trustweave.trust.dsl.credential.*
import org.trustweave.credential.model.ProofType
import org.trustweave.testkit.services.*

val trustWeave = TrustWeave.build {
    factories(
        trustRegistryFactory = TestkitTrustRegistryFactory()  // Only needed for trust registry
    )
    // KMS, DID methods, and anchor clients auto-discovered via SPI
    keys {
        provider(IN_MEMORY)  // Use "awsKms" or "azureKeyVault" in production
        algorithm(ED25519)
    }

    did {
        method(KEY) {
            algorithm(ED25519)
        }
        method(WEB) {
            domain("example.com")
        }
    }

    anchor {
        chain("algorand:testnet") {
            provider(ALGORAND)
        }
        chain("polygon:mainnet") {
            provider(POLYGON)
        }
    }

    trust {
        provider(IN_MEMORY)
    }

    credentials {
        defaultProofType(ProofType.Ed25519Signature2020)
        autoAnchor(false)
    }
}

Expected Result: A fully configured TrustWeave ready for production use.


Why This Approach is Better

Before (Imperative Style)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Verbose, imperative configuration
val kms = InMemoryKeyManagementService()
val didMethod = DidKeyMethod(kms)
val didRegistry = DidMethodRegistry()
didRegistry.register("key", didMethod)

val algorandClient = AlgorandBlockchainAnchorClient(...)
val polygonClient = PolygonBlockchainAnchorClient(...)
val anchorRegistry = BlockchainAnchorRegistry()
anchorRegistry.register("algorand:testnet", algorandClient)
anchorRegistry.register("polygon:mainnet", polygonClient)

val trustRegistry = InMemoryTrustRegistry()
val config = TrustWeaveConfig(
    kms = kms,
    didRegistry = didRegistry,
    anchorRegistry = anchorRegistry,
    trustRegistry = trustRegistry
)
val trustWeave = TrustWeave(config)

Problems:

  • 20+ lines of boilerplate
  • Hard to read and understand
  • Easy to make mistakes
  • Difficult to maintain

After (Declarative DSL)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import org.trustweave.testkit.services.*

// Declarative, readable configuration
val trustWeave = TrustWeave.build {
    factories(
        trustRegistryFactory = TestkitTrustRegistryFactory()  // Only needed for trust registry
    )
    // KMS, DID methods, and anchor clients auto-discovered via SPI
    keys { provider(IN_MEMORY); algorithm(ED25519) }
    did { method(KEY) { algorithm(ED25519) } }
    anchor {
        chain("algorand:testnet") { provider(ALGORAND) }
        chain("polygon:mainnet") { provider(POLYGON) }
    }
    trust { provider(IN_MEMORY) }
}

Benefits:

  • 80% less code
  • Reads like documentation
  • Type-safe with IDE autocomplete
  • Easy to understand and maintain

Common Patterns

Pattern 1: Development Configuration

For local development and testing:

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
import org.trustweave.trust.TrustWeave
import org.trustweave.trust.types.getOrThrow
import org.trustweave.trust.dsl.credential.*
import org.trustweave.testkit.services.*

val trustWeave = TrustWeave.build {
    factories(
        trustRegistryFactory = TestkitTrustRegistryFactory()  // Only needed for trust registry
    )
    // KMS, DID methods, and anchor clients auto-discovered via SPI
    keys {
        provider(IN_MEMORY)
        algorithm(ED25519)
    }
    did {
        method(KEY) {
            algorithm(ED25519)
        }
    }
    anchor {
        chain("algorand:testnet") {
            inMemory()
        }
    }
    trust {
        provider(IN_MEMORY)
    }
}

Pattern 2: Production Configuration

For production with real services:

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
import org.trustweave.testkit.services.*
val trustWeave = TrustWeave.build {
    keys {
        provider(AWS)  // Production KMS
        algorithm(ED25519)
    }
    did {
        method(KEY) {
            algorithm(ED25519)
        }
        method(WEB) {
            domain("yourdomain.com")
        }
    }
    anchor {
        chain("algorand:mainnet") {
            provider(ALGORAND)
            // Production client configuration
        }
        chain("polygon:mainnet") {
            provider(POLYGON)
        }
    }
    trust {
        provider("database")  // Persistent trust registry
    }
}

Pattern 3: Multi-Method Configuration

Supporting 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
import org.trustweave.trust.TrustWeave
import org.trustweave.trust.types.getOrThrow
import org.trustweave.trust.dsl.credential.*
import org.trustweave.testkit.services.*

val trustWeave = TrustWeave.build {
    // KMS and DID methods auto-discovered via SPI
    keys {
        provider(IN_MEMORY)
        algorithm(ED25519)
    }
    did {
        method(KEY) {
            algorithm(ED25519)
        }
        method(WEB) {
            domain("example.com")
        }
            method(ETHR) {
            network("sepolia")
        }
        method("polygon") {
            network("testnet")
        }
    }
}

Error Handling

Handle configuration errors gracefully:

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
import org.trustweave.core.exception.TrustWeaveException
import org.trustweave.testkit.services.*

try {
    val trustWeave = TrustWeave.build {
        keys {
            provider(IN_MEMORY)
            algorithm(ED25519)
        }
        did {
            method(KEY) {
                algorithm(ED25519)
            }
        }
    }
} catch (error: TrustWeaveException) {
    when (error) {
        is TrustWeaveException.PluginNotFound -> {
            println("Provider not found: ${error.pluginId}")
            println("Available providers: ${error.context["availablePlugins"]}")
        }
        is TrustWeaveException.PluginInitializationFailed -> {
            println("Failed to initialize: ${error.reason}")
        }
        else -> {
            println("Configuration error: ${error.message}")
        }
    }
}

Next Steps

Now that you’ve configured TrustWeave, you can:

  1. Create DIDs - Create decentralized identifiers
  2. Issue Credentials - Issue verifiable credentials
  3. Anchor to Blockchain - Anchor data for tamper evidence
  4. Manage Trust Anchors - Configure trusted issuers


This site uses Just the Docs, a documentation theme for Jekyll.