Core API Reference

Complete API reference for TrustWeave’s TrustWeave API.

Version: 1.0.0-SNAPSHOT Kotlin: 2.2.21+ | Java: 21+ See CHANGELOG.md for version history and migration guides.

Note: This API reference documents the TrustWeave API, which is the primary interface for trust and identity operations in TrustWeave. The TrustWeave provides a DSL-based API for creating DIDs, issuing credentials, managing wallets, and more.

1
2
3
dependencies {
    implementation("org.trustweave:distribution-all:1.0.0-SNAPSHOT")
}

Overview

The TrustWeave provides a unified, DSL-based API for decentralized identity and trust operations. The API uses suspend functions and DSL builders for type-safe, fluent operations.

Key Concepts:

  • TrustWeave: The main entry point for trust and identity operations
  • DSL Builders: Fluent builders for configuring and performing operations (e.g., issue { }, createDid { })
  • Configuration: Configure KMS, DID methods, anchors, and more using the TrustWeave.build { } DSL
  • Context: The TrustWeaveContext provides access to underlying services when needed

Main Operations:

  • issue { }: Issue verifiable credentials using DSL
  • verify { }: Verify verifiable credentials
  • createDid { }: Create DIDs using DSL
  • updateDid { }: Update DID documents
  • wallet { }: Create and configure wallets
  • delegate { }: Delegate authority between DIDs
  • rotateKey { }: Rotate keys in DID documents

Quick Reference

Operation Method Returns
Create TrustWeave TrustWeave.build { } TrustWeave
Create DID trustWeave.createDid { } String (DID)
Update DID trustWeave.updateDid { } DidDocument
Delegate DID trustWeave.delegate { } DelegationChainResult
Rotate Key trustWeave.rotateKey { } Any
Issue Credential trustWeave.issue { } VerifiableCredential
Verify Credential trustWeave.verify { } CredentialVerificationResult
Create Wallet trustWeave.wallet { } Wallet
Trust Operations (DSL) trustWeave.trust { } Unit
Add Trust Anchor trustWeave.addTrustAnchor(did) { } Boolean
Remove Trust Anchor trustWeave.removeTrustAnchor(did) Boolean
Is Trusted Issuer trustWeave.isTrustedIssuer(did, type?) Boolean
Get Trust Path trustWeave.getTrustPath(fromDid, toDid) TrustPathResult?
Get Trusted Issuers trustWeave.getTrustedIssuers(type?) List<String>
Get DSL Context trustWeave.getDslContext() TrustWeaveContext
Get Configuration trustWeave.configuration TrustWeaveConfig
Create from Config TrustWeave.from(config) TrustWeave

TrustWeave Class

Creating TrustWeave Instances

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
import org.trustweave.trust.TrustWeave
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    // Create with defaults (in-memory KMS, did:key method)
    val trustWeave = TrustWeave.build {
        keys {
            provider(IN_MEMORY)
            algorithm(ED25519)
        }
        did {
            method(KEY) {
                algorithm(ED25519)
            }
        }
    }

    // Create with custom configuration
    val trustWeave = TrustWeave.build {
        keys {
            provider(IN_MEMORY)
            algorithm(ED25519)
        }
        did {
            method(KEY) {
                algorithm(ED25519)
            }
            method(WEB) {
                domain("example.com")
            }
        }
        anchor {
            chain("algorand:testnet") {
                provider(ALGORAND)
            }
        }
        trust {
            provider(IN_MEMORY)
        }
    }
}

Main Operations

The TrustWeave provides DSL-based operations:

  • issue { }: Issue verifiable credentials
  • verify { }: Verify verifiable credentials
  • createDid { }: Create DIDs
  • updateDid { }: Update DID documents
  • delegate { }: Delegate authority between DIDs
  • rotateKey { }: Rotate keys in DID documents
  • wallet { }: Create wallets
  • trust { }: Manage trust anchors (DSL style)
  • addTrustAnchor(): Add trust anchor (direct method)
  • removeTrustAnchor(): Remove trust anchor (direct method)
  • isTrustedIssuer(): Check if issuer is trusted
  • getTrustPath(): Find trust path between DIDs
  • getTrustedIssuers(): Get all trusted issuers
  • getDslContext(): Access underlying DSL context (advanced)
  • configuration: Access configuration (advanced)

Example:

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
import org.trustweave.trust.TrustWeave
import org.trustweave.trust.types.DidCreationResult
import org.trustweave.credential.results.IssuanceResult
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    val trustWeave = TrustWeave.build { ... }

    // Create DID
    val didResult = trustWeave.createDid {
        method(KEY)
        algorithm(ED25519)
    }
    
    val issuerDid = when (didResult) {
        is DidCreationResult.Success -> didResult.did
        else -> throw IllegalStateException("Failed to create DID")
    }

    // Issue credential
    val issuanceResult = trustWeave.issue {
        credential { ... }
        signedBy(issuerDid = issuerDid.value, keyId = "key-1")
    }
    
    val credential = when (issuanceResult) {
        is IssuanceResult.Success -> issuanceResult.credential
        else -> throw IllegalStateException("Failed to issue credential")
    }
}

// Create wallet
val wallet = trustWeave.wallet {
    holder("did:key:holder")
}

DID Operations

create

Creates a new DID using the default or specified method.

1
suspend fun createDid(block: DidBuilder.() -> Unit): DidCreationResult

Access via: trustWeave.createDid { }

Parameters:

  • method (String, optional): DID method identifier
    • Default: "key" (did:key method)
    • Format: Method name without did: prefix (e.g., "key", "web", "ion")
    • Available Methods: Use getAvailableDidMethods() to see registered methods
    • Example: "web" for did:web, "ion" for did:ion
    • Validation: Automatically validated - must be registered method
    • Common Values: "key", "web", "ion", "ethr", "polygon"
  • options (DidCreationOptions, optional): DID creation options
    • Default: DidCreationOptions() with ED25519 algorithm
    • Type: Data class with typed properties
    • Properties:
      • algorithm: Key algorithm (ED25519, SECP256K1, RSA)
      • purposes: List of key purposes (AUTHENTICATION, ASSERTION_METHOD, etc.)
      • additionalProperties: Method-specific options
    • Example: DidCreationOptions(algorithm = KeyAlgorithm.ED25519)
  • configure (DidCreationOptionsBuilder.() -> Unit, optional): Builder function
    • Alternative to: options parameter
    • Type: DSL builder function
    • Example: { algorithm = KeyAlgorithm.ED25519; purpose(KeyPurpose.AUTHENTICATION) }

Returns: DidCreationResult - Sealed result type containing:

Success Case:

  • DidCreationResult.Success containing:
    • did: The created Did object
    • document: W3C-compliant DID document containing:
      • id: The DID string (e.g., "did:key:z6Mk...")
      • verificationMethod: Array of verification methods with public keys
      • authentication: Authentication key references
      • assertionMethod: Assertion key references (for signing)
      • service: Optional service endpoints

Failure Cases:

  • DidCreationResult.Failure.MethodNotRegistered - Method is not registered (includes available methods)
  • DidCreationResult.Failure.KeyGenerationFailed - Key generation failed
  • DidCreationResult.Failure.DocumentCreationFailed - Document creation failed
  • DidCreationResult.Failure.InvalidConfiguration - Configuration validation failed
  • DidCreationResult.Failure.Other - Other error with reason and optional cause

Note: This method returns sealed results instead of throwing exceptions. Use when expressions for exhaustive error handling.

Default Behavior:

  • Uses did:key method if not specified
  • Generates ED25519 key pair
  • Creates verification method with #key-1 fragment
  • Adds key to authentication and assertionMethod arrays

Edge Cases:

  • If method not registered → TrustWeaveError.DidMethodNotRegistered with available methods list
  • If algorithm not supported by method → TrustWeaveError.ValidationFailed with reason
  • If KMS fails to generate key → TrustWeaveError.InvalidOperation with context
  • If method-specific validation fails → TrustWeaveError.ValidationFailed with field details

Performance:

  • Time complexity: O(1) for key generation (if cached)
  • Network calls: 0 (local key generation for did:key)
  • Thread-safe: ✅ Yes (suspend function, thread-safe KMS operations)

Example:

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
// Simple usage (uses defaults: did:key, ED25519)
val didResult = trustWeave.createDid {
    method(KEY)
    algorithm(ED25519)
}

when (didResult) {
    is DidCreationResult.Success -> {
        println("Created DID: ${didResult.did.value}")
        println("Document: ${didResult.document.id}")
    }
    is DidCreationResult.Failure.MethodNotRegistered -> {
        println("Method not registered: ${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, use getOrFail() helper
import org.trustweave.testkit.getOrFail

val did = trustWeave.createDid {
    method(KEY)
    algorithm(ED25519)
}.getOrFail() // Throws AssertionError on failure

// With custom method
val webDidResult = trustWeave.createDid {
    method(WEB)
    domain("example.com")
}
when (webDidResult) {
    is DidCreationResult.Success -> println("Created: ${webDidResult.did.value}")
    else -> println("Error: ${webDidResult.reason}")
}

Error Types:

  • DidCreationResult.Failure.MethodNotRegistered - Method is not registered (includes available methods)
  • DidCreationResult.Failure.KeyGenerationFailed - Key generation failed (includes reason and optional cause)
  • DidCreationResult.Failure.DocumentCreationFailed - Document creation failed (includes reason and optional cause)
  • DidCreationResult.Failure.InvalidConfiguration - Configuration validation failed (includes reason and details)
  • DidCreationResult.Failure.Other - Other error (includes reason and optional cause)

resolve

Resolves a DID to its document.

1
suspend fun resolve(did: String): DidResolutionResult

Access via: trustWeave.getDslContext().resolveDid(did) or use DID resolver directly

Parameters:

  • did (String, required): The DID string to resolve
    • Format: Must match did:<method>:<identifier> pattern
    • Example: "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"
    • Validation: Automatically validated before resolution
    • Requirements: Method must be registered in TrustWeave instance

Returns: DidResolutionResult directly (not wrapped in Result)

DidResolutionResult Structure:

1
2
3
4
5
6
7
8
9
10
11
data class DidResolutionResult(
    val document: DidDocument?,  // null if DID not found
    val metadata: DidResolutionMetadata
)

data class DidResolutionMetadata(
    val method: String,           // DID method used for resolution
    val resolvedAt: Instant,      // Resolution timestamp
    val resolverVersion: String?, // Resolver version (if available)
    val error: String?            // Error message if resolution failed
)

Properties:

  • document: The DID document if found, null if not found
  • metadata.method: The DID method that was resolved
  • metadata.resolvedAt: When the resolution occurred
  • metadata.resolverVersion: Version of resolver used (if available)
  • metadata.error: Error message if resolution failed (document will be null)

Failure Case:

  • Throws TrustWeaveError exception with specific error type
  • For error handling, wrap in try-catch or use extension functions

Edge Cases:

  • If DID format invalid → TrustWeaveError.InvalidDidFormat with reason
  • If method not registered → TrustWeaveError.DidMethodNotRegistered with available methods
  • If DID not found → TrustWeaveError.DidNotFound with DID and available methods
  • If resolution service unavailable → TrustWeaveError.InvalidOperation with context

Performance:

  • Time complexity: O(1) for local methods (did:key), O(n) for network methods where n = network latency
  • Network calls: 0 for did:key (local), 1+ for network-based methods (did:web, did:ion)
  • Thread-safe: ✅ Yes (suspend function)

Example:

1
2
3
4
5
6
7
8
9
10
11
12
import org.trustweave.did.identifiers.Did

// Simple usage - access resolver via DSL context
val context = trustWeave.getDslContext()
val resolver = context.getDidResolver()
val did = Did("did:key:z6Mk...")
val result = resolver?.resolve(did)
if (result?.document != null) {
    println("DID resolved: ${result.document.id}")
} else {
    println("DID not found")
}

Errors:

  • TrustWeaveError.InvalidDidFormat - Invalid DID format (includes reason)
  • TrustWeaveError.DidMethodNotRegistered - Method is not registered (includes available methods)
  • TrustWeaveError.DidNotFound - DID not found (includes DID and available methods)

update

Updates a DID document by applying a transformation function.

1
suspend fun updateDid(block: DidUpdateBuilder.() -> Unit): DidUpdateResult

Access via: trustWeave.updateDid { }

Parameters:

  • did (String, required): The DID to update (via DSL builder)
  • addKey { }, addService { }, etc.: DSL methods for updating the document

Returns: DidUpdateResult - Sealed result type containing:

  • Success: DidUpdateResult.Success with document: The updated DID document
  • Failure: Various failure types (DidNotFound, AuthorizationFailed, UpdateFailed, Other)

Edge Cases:

  • If DID format invalid → TrustWeaveError.InvalidDidFormat
  • If method not registered → TrustWeaveError.DidMethodNotRegistered
  • If update operation fails → TrustWeaveError.InvalidOperation

Example:

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.did.identifiers.Did

val did = Did("did:key:example")
val updateResult = trustWeave.updateDid {
    did(did.value)  // DSL builder accepts string for convenience
    addService {
        id("${did.value}#service-1")
        type("LinkedDomains")
        endpoint("https://example.com/service")
    }
}

when (updateResult) {
    is DidUpdateResult.Success -> {
        println("Updated DID document: ${updateResult.document.id}")
    }
    is DidUpdateResult.Failure.DidNotFound -> {
        println("DID not found: ${updateResult.did.value}")
    }
    is DidUpdateResult.Failure.AuthorizationFailed -> {
        println("Authorization failed: ${updateResult.reason}")
    }
    is DidUpdateResult.Failure.UpdateFailed -> {
        println("Update failed: ${updateResult.reason}")
    }
    is DidUpdateResult.Failure.Other -> {
        println("Error: ${updateResult.reason}")
    }
}

deactivate

Deactivates a DID, marking it as no longer active.

1
suspend fun deactivateDid(did: Did): Boolean

Access via: trustWeave.getDslContext().deactivateDid(did) or use DID method directly

Parameters:

  • did (Did, required): Type-safe DID identifier to deactivate

Returns: Boolean - true if deactivated successfully, false otherwise

Edge Cases:

  • If DID format invalid → TrustWeaveError.InvalidDidFormat
  • If method not registered → TrustWeaveError.DidMethodNotRegistered
  • If DID already deactivated → Returns false

Example:

1
2
3
4
5
6
7
8
9
import org.trustweave.did.identifiers.Did

// Access via DSL context
val context = trustWeave.getDslContext()
val did = Did("did:key:example")
val deactivated = context.deactivateDid(did)
if (deactivated) {
    println("DID deactivated successfully")
}

availableMethods

Gets a list of available DID method names.

1
fun availableMethods(): List<String>

Access via: trustWeave.configuration.didMethods.keys or access registry directly

Returns: List<String> - List of registered DID method names

Example:

1
2
val methods = trustWeave.configuration.didMethods.keys
println("Available methods: $methods") // ["key", "web", "ion"]

Credential Operations

issue

Issues a verifiable credential with cryptographic proof using the DSL.

1
suspend fun issue(block: IssuanceBuilder.() -> Unit): IssuanceResult

Parameters:

The DSL builder provides a fluent API for configuring the credential:

  • credential { }: Configure the credential structure
    • id(String): Set credential ID (optional, auto-generated if not provided)
    • type(String...): Add credential types (first should be “VerifiableCredential”)
    • issuer(String): Set issuer DID
    • subject { }: Build credential subject with claims
    • issued(Instant): Set issuance date
    • expires(Instant) or expires(Long, ChronoUnit): Set expiration
    • schema(String): Set credential schema
    • status { }: Configure revocation status
  • signedBy(issuerDid: String, keyId: String): Specify issuer and key for signing
    • issuerDid: The DID of the credential issuer
    • keyId: The key ID from issuer’s DID document (e.g., "$issuerDid#key-1")

Returns: IssuanceResult - Sealed result type containing:

Success Case:

  • IssuanceResult.Success containing:
    • credential: Signed VerifiableCredential with:
      • id: Auto-generated credential ID (UUID)
      • issuer: Issuer DID
      • issuanceDate: Current timestamp
      • credentialSubject: Provided subject data
      • type: Credential types
      • proof: Cryptographic proof (signature)

Failure Cases:

  • IssuanceResult.Failure.IssuerResolutionFailed - Issuer DID resolution failed
  • IssuanceResult.Failure.KeyNotFound - Key not found in issuer DID document
  • IssuanceResult.Failure.SigningFailed - Signing operation failed
  • IssuanceResult.Failure.ProofGenerationFailed - Proof generation failed
  • IssuanceResult.Failure.InvalidCredential - Credential validation failed
  • IssuanceResult.Failure.SchemaValidationFailed - Schema validation failed
  • IssuanceResult.Failure.Other - Other error with reason and optional cause

Edge Cases:

  • If issuerKeyId doesn’t exist in DID document:
    • Returns: TrustWeaveError.InvalidDidFormat with reason indicating key not found
    • Solution: Verify key exists using didDocument.verificationMethod.find { it.id == issuerKeyId }
  • If credentialSubject missing "id" field:
    • Returns: TrustWeaveError.CredentialInvalid with field = "credentialSubject.id"
    • Solution: Always include "id" field in credential subject
  • If issuer DID method not registered:
    • Returns: TrustWeaveError.DidMethodNotRegistered with available methods list
    • Solution: Register DID method or use available method
  • If issuer DID not resolvable:
    • Returns: TrustWeaveError.DidNotFound with available methods
    • Solution: Ensure DID is valid and method is registered
  • If expirationDate is invalid format:
    • Returns: TrustWeaveError.ValidationFailed with reason
    • Solution: Use ISO 8601 format (e.g., "2025-12-31T23:59:59Z")

Performance Characteristics:

  • Time Complexity:
    • O(1) for key lookup (if cached)
    • O(n) for proof generation where n = credential size
    • O(1) for DID resolution (if cached)
  • Network Calls:
    • 1 call for DID resolution (unless cached)
    • 0 calls for signing (uses local KMS)
  • Thread Safety:
    • ✅ Thread-safe (all operations are suspend functions)
    • ✅ Safe for concurrent use
  • Resource Usage:
    • Memory: O(n) where n = credential size
    • CPU: Moderate (cryptographic operations)

Example:

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
54
55
56
57
58
59
60
61
62
// Simple usage with error handling
val issuanceResult = trustWeave.issue {
    credential {
        type("VerifiableCredential", "PersonCredential")
        issuer("did:key:issuer")
        subject {
            id("did:key:subject")
            "name" to "Alice"
        }
    }
    signedBy(issuerDid = "did:key:issuer", keyId = "did:key:issuer#key-1")
}

when (issuanceResult) {
    is IssuanceResult.Success -> {
        println("Issued credential: ${issuanceResult.credential.id}")
    }
    is IssuanceResult.Failure.IssuerResolutionFailed -> {
        println("Issuer DID resolution failed: ${issuanceResult.issuerDid}")
        println("Reason: ${issuanceResult.reason}")
    }
    is IssuanceResult.Failure.KeyNotFound -> {
        println("Key not found: ${issuanceResult.keyId}")
        println("Reason: ${issuanceResult.reason}")
    }
    is IssuanceResult.Failure.SigningFailed -> {
        println("Signing failed: ${issuanceResult.reason}")
        issuanceResult.cause?.printStackTrace()
    }
    is IssuanceResult.Failure.ProofGenerationFailed -> {
        println("Proof generation failed: ${issuanceResult.reason}")
    }
    is IssuanceResult.Failure.InvalidCredential -> {
        println("Invalid credential: ${issuanceResult.reason}")
        if (issuanceResult.errors.isNotEmpty()) {
            println("Errors: ${issuanceResult.errors.joinToString()}")
        }
    }
    is IssuanceResult.Failure.SchemaValidationFailed -> {
        println("Schema validation failed: ${issuanceResult.reason}")
        println("Errors: ${issuanceResult.errors.joinToString()}")
    }
    is IssuanceResult.Failure.Other -> {
        println("Error: ${issuanceResult.reason}")
        issuanceResult.cause?.printStackTrace()
    }
}

// For tests and examples, use getOrFail() helper
import org.trustweave.testkit.getOrFail

val credential = trustWeave.issue {
    credential {
        type("VerifiableCredential", "PersonCredential")
        issuer(issuerDid)
        subject {
            id("did:key:subject")
            "name" to "Alice"
        }
    }
    signedBy(issuerDid = issuerDid, keyId = "$issuerDid#key-1")
}.getOrFail() // Throws AssertionError on failure

Error Types:

  • IssuanceResult.Failure.IssuerResolutionFailed - Issuer DID resolution failed
  • IssuanceResult.Failure.KeyNotFound - Key not found in issuer DID document
  • IssuanceResult.Failure.SigningFailed - Signing operation failed (includes reason and optional cause)
  • IssuanceResult.Failure.ProofGenerationFailed - Proof generation failed (includes reason and optional cause)
  • IssuanceResult.Failure.InvalidCredential - Credential validation failed (includes reason and errors list)
  • IssuanceResult.Failure.SchemaValidationFailed - Schema validation failed (includes reason and errors list)
  • IssuanceResult.Failure.Other - Other error (includes reason and optional cause)

verify

Verifies a verifiable credential by checking proof, issuer DID resolution, expiration, and revocation status.

1
suspend fun verify(block: VerificationBuilder.() -> Unit): CredentialVerificationResult

Access via: trustWeave.verify { }

Parameters:

The DSL builder provides a fluent API for configuring verification:

  • credential(VerifiableCredential): The credential to verify (required)
  • checkExpiration(Boolean): Check if credential has expired (default: true)
  • checkRevocation(Boolean): Check revocation status (default: true)
  • checkTrust(Boolean): Verify issuer is trusted (default: false)
  • expectedAudience(String?): Expected audience DID (default: null)

Returns: CredentialVerificationResult containing:

  • valid: Overall validity (all checks passed)
  • proofValid: Proof signature is valid
  • issuerValid: Issuer DID resolved successfully
  • notExpired: Credential has not expired (if expiration checked)
  • notRevoked: Credential is not revoked (if revocation checked)
  • errors: List of error messages if verification failed
  • warnings: List of warnings (e.g., expiring soon, missing optional fields)

Performance Characteristics:

  • Time Complexity:
    • O(1) for proof verification (cryptographic operation)
    • O(1) for DID resolution (if cached), O(N) for network-based methods
    • O(1) for expiration check
    • O(1) for revocation check (if status list cached)
  • Network Calls:
    • 1 call for issuer DID resolution (unless cached)
    • 0-1 calls for revocation status check (if enabled and not cached)
  • Thread Safety: ✅ Thread-safe, can be called concurrently
  • Resource Usage:
    • Memory: O(N) where N = credential size
    • CPU: Moderate (cryptographic operations)

Edge Cases:

  • If credential has no proof → proofValid = false, valid = false
  • If issuer DID cannot be resolved → issuerValid = false, valid = false
  • If credential expired and checkExpiration = truenotExpired = false, valid = false
  • If credential revoked and enforceStatus = truenotRevoked = false, valid = false
  • If proof signature invalid → proofValid = false, valid = false
  • If issuer DID method not registered → Returns TrustWeaveError.DidMethodNotRegistered
  • If credential structure invalid → Returns TrustWeaveError.CredentialInvalid

Example:

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
// Simple usage
val result = trustWeave.verify {
    credential(credential)
}
if (result.valid) {
    println("Credential is valid")
} else {
    println("Errors: ${result.errors}")
}

// With custom verification configuration
val result = trustWeave.verify {
    credential(credential)
    checkExpiration(true)
    checkRevocation(true)
    checkTrust(true) // Verify issuer is trusted
}

if (result.valid) {
    println("✅ Credential is valid")
    println("   Proof valid: ${result.proofValid}")
    println("   Issuer valid: ${result.issuerValid}")
    println("   Not expired: ${result.notExpired}")
    println("   Not revoked: ${result.notRevoked}")

    if (result.warnings.isNotEmpty()) {
        println("   Warnings: ${result.warnings.joinToString()}")
    }
} else {
    println("❌ Credential invalid")
    println("   Errors: ${result.errors.joinToString()}")
}

Errors:

  • TrustWeaveError.CredentialInvalid - Credential validation failed (missing fields, invalid structure)
  • TrustWeaveError.DidMethodNotRegistered - Issuer DID method not registered
  • TrustWeaveError.DidNotFound - Issuer DID cannot be resolved

Revocation and Status List Management

TrustWeave provides comprehensive revocation management with blockchain anchoring support. See Blockchain-Anchored Revocation for detailed documentation.

createStatusList

Creates a new status list for managing credential revocation or suspension.

1
2
3
4
5
6
suspend fun createStatusList(
    issuerDid: String,
    purpose: StatusPurpose,
    size: Int = 131072,
    customId: String? = null
): Result<StatusListCredential>

Parameters:

  • issuerDid: The DID of the issuer who owns this status list (required, must be resolvable)
  • purpose: StatusPurpose.REVOCATION or StatusPurpose.SUSPENSION (required)
  • size: Initial size of the status list in entries (default: 131072 = 16KB, must be power of 2)
  • customId: Optional custom ID for the status list (auto-generated UUID if null)

Returns: Result<StatusListCredential> containing:

  • id: Unique identifier for the status list
  • issuer: DID of the issuer
  • purpose: REVOCATION or SUSPENSION
  • size: Number of entries in the status list
  • credential: The status list credential document

Performance Characteristics:

  • Time Complexity: O(1) for status list creation
  • Space Complexity: O(N) where N is the size parameter
  • Network Calls: 0 (local operation)
  • Thread Safety: Thread-safe, can be called concurrently

Edge Cases:

  • If issuerDid is not resolvable, returns DidNotFound error
  • If size is not a power of 2, it may be rounded up to the nearest power of 2
  • If customId conflicts with existing status list, a new ID is generated

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
val statusList = TrustWeave.createStatusList(
    issuerDid = "did:key:issuer",
    purpose = StatusPurpose.REVOCATION,
    size = 65536  // 8KB status list
).fold(
    onSuccess = { list ->
        println("Status List ID: ${list.id}")
        println("Size: ${list.size} entries")
    },
    onFailure = { error ->
        when (error) {
            is TrustWeaveError.DidNotFound -> {
                println("Issuer DID not found: ${error.did}")
            }
            else -> println("Error: ${error.message}")
        }
    }
)

Errors:

  • TrustWeaveError.DidNotFound - Issuer DID cannot be resolved
  • TrustWeaveError.InvalidDidFormat - Invalid issuer DID format
  • TrustWeaveError.ValidationFailed - Invalid size or purpose value

revokeCredential

Revokes a credential by adding it to a status list. The credential’s index in the status list is determined by hashing the credential ID.

1
2
3
4
suspend fun revokeCredential(
    credentialId: String,
    statusListId: String
): Result<Boolean>

Parameters:

  • credentialId: The ID of the credential to revoke (required, must be a valid URI or UUID)
  • statusListId: The ID of the status list to add the credential to (required, must exist)

Returns: Result<Boolean> - true if revocation succeeded, false if already revoked

Performance Characteristics:

  • Time Complexity: O(1) for bit manipulation (hash + bit set)
  • Space Complexity: O(1) (in-place bit update)
  • Network Calls: 0 (local operation, unless using blockchain-anchored registry)
  • Thread Safety: Thread-safe, can be called concurrently

Edge Cases:

  • If credential is already revoked, returns true (idempotent operation)
  • If status list is full (all bits set), returns error
  • If statusListId doesn’t exist, returns error
  • Hash collisions are extremely rare but possible (1 in 2^64 for default size)

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
val revoked = TrustWeave.revokeCredential(
    credentialId = "urn:uuid:credential-123",
    statusListId = statusList.id
).fold(
    onSuccess = { success ->
        if (success) {
            println("Credential revoked successfully")
        } else {
            println("Credential was already revoked")
        }
    },
    onFailure = { error ->
        when (error) {
            is TrustWeaveError.ValidationFailed -> {
                println("Invalid credential ID or status list ID")
            }
            else -> println("Revocation error: ${error.message}")
        }
    }
)

Errors:

  • TrustWeaveError.ValidationFailed - Invalid credential ID or status list ID format
  • TrustWeaveError.InvalidState - Status list not found or full

suspendCredential

Suspends a credential (temporarily disables it). The credential’s index in the status list is determined by hashing the credential ID.

1
2
3
4
suspend fun suspendCredential(
    credentialId: String,
    statusListId: String
): Result<Boolean>

Parameters:

  • credentialId: The ID of the credential to suspend (required, must be a valid URI or UUID)
  • statusListId: The ID of the suspension status list (required, must exist)

Returns: Result<Boolean> - true if suspension succeeded, false if already suspended

Performance Characteristics:

  • Time Complexity: O(1) for bit manipulation (hash + bit set)
  • Space Complexity: O(1) (in-place bit update)
  • Network Calls: 0 (local operation, unless using blockchain-anchored registry)
  • Thread Safety: ✅ Thread-safe, can be called concurrently

Edge Cases:

  • If credential is already suspended, returns true (idempotent operation)
  • If status list is full (all bits set), returns error
  • If statusListId doesn’t exist, returns error
  • Hash collisions are extremely rare but possible (1 in 2^64 for default size)

Example:

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
val suspended = TrustWeave.suspendCredential(
    credentialId = "urn:uuid:credential-123",
    statusListId = suspensionList.id
).fold(
    onSuccess = { success ->
        if (success) {
            println("✅ Credential suspended successfully")
        } else {
            println("⚠️ Credential was already suspended")
        }
    },
    onFailure = { error ->
        when (error) {
            is TrustWeaveError.ValidationFailed -> {
                println("❌ Invalid credential ID or status list ID")
            }
            is TrustWeaveError.InvalidState -> {
                println("❌ Status list not found or full")
            }
            else -> {
                println("❌ Suspension error: ${error.message}")
            }
        }
    }
)

Errors:

  • TrustWeaveError.ValidationFailed - Invalid credential ID or status list ID format
  • TrustWeaveError.InvalidState - Status list not found or full

checkRevocationStatus

Checks if a credential is revoked or suspended by examining its status list entry.

1
2
3
suspend fun checkRevocationStatus(
    credential: VerifiableCredential
): Result<RevocationStatus>

Parameters:

  • credential: The credential to check (required, must have credentialStatus field if status list is used)

Returns: Result<RevocationStatus> containing:

  • revoked: Whether the credential is revoked (true if revoked, false otherwise)
  • suspended: Whether the credential is suspended (true if suspended, false otherwise)
  • statusListId: The status list ID if applicable (from credential.credentialStatus.id)
  • reason: Optional revocation reason (if provided during revocation)

Performance Characteristics:

  • Time Complexity: O(1) for bit lookup (hash + bit check)
  • Space Complexity: O(1) (no additional storage)
  • Network Calls: 0 for local status lists, 1+ for blockchain-anchored status lists (if not cached)
  • Thread Safety: ✅ Thread-safe, can be called concurrently

Edge Cases:

  • If credential has no credentialStatus field → Returns revoked = false, suspended = false
  • If status list not found → Returns TrustWeaveError.InvalidState
  • If credential ID hash collision → Extremely rare (1 in 2^64), may return incorrect status
  • If status list not accessible → Returns TrustWeaveError.InvalidOperation

Example:

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
val status = TrustWeave.checkRevocationStatus(credential).fold(
    onSuccess = { status ->
        when {
            status.revoked -> {
                println("❌ Credential is revoked")
                println("   Status List: ${status.statusListId}")
                status.reason?.let { println("   Reason: $it") }
            }
            status.suspended -> {
                println("⚠️ Credential is suspended")
                println("   Status List: ${status.statusListId}")
            }
            else -> {
                println("✅ Credential is valid (not revoked or suspended)")
            }
        }
    },
    onFailure = { error ->
        when (error) {
            is TrustWeaveError.InvalidState -> {
                println("❌ Status list not found")
            }
            is TrustWeaveError.InvalidOperation -> {
                println("❌ Cannot access status list: ${error.message}")
            }
            else -> {
                println("❌ Error checking revocation status: ${error.message}")
            }
        }
    }
)

Errors:

  • TrustWeaveError.InvalidState - Status list not found or not accessible
  • TrustWeaveError.InvalidOperation - Cannot access status list (network error, etc.)
  • TrustWeaveError.CredentialInvalid - Credential structure invalid (missing required fields)

Using BlockchainRevocationRegistry

For blockchain-anchored revocation, use BlockchainRevocationRegistry with an anchoring strategy:

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
import org.trustweave.credential.revocation.*
import java.time.Duration

// Create status list manager
val statusListManager = InMemoryStatusListManager()

// Create blockchain anchor client
val anchorClient = /* your blockchain anchor client */

// Create registry with periodic anchoring strategy
val registry = BlockchainRevocationRegistry(
    anchorClient = anchorClient,
    statusListManager = statusListManager,
    anchorStrategy = PeriodicAnchorStrategy(
        interval = Duration.ofHours(1),
        maxUpdates = 100
    ),
    chainId = "algorand:testnet"
)

// Create status list
val statusList = registry.createStatusList(
    issuerDid = "did:key:issuer",
    purpose = StatusPurpose.REVOCATION
)

// Revoke credential (automatic anchoring if threshold reached)
registry.revokeCredential("cred-123", statusList.id)

// Check pending anchors
val pending = registry.getPendingAnchor(statusList.id)
if (pending != null) {
    println("Pending updates: ${pending.updateCount}")
}

// Manual anchoring
val anchorRef = registry.anchorRevocationList(statusList, "algorand:testnet")

Anchoring Strategies:

  1. PeriodicAnchorStrategy - Anchor on schedule or after N updates
    1
    2
    3
    4
    
    PeriodicAnchorStrategy(
        interval = Duration.ofHours(1),
        maxUpdates = 100
    )
    
  2. LazyAnchorStrategy - Anchor only when verification is requested
    1
    2
    3
    
    LazyAnchorStrategy(
        maxStaleness = Duration.ofDays(1)
    )
    
  3. HybridAnchorStrategy - Combine periodic and lazy approaches
    1
    2
    3
    4
    5
    
    HybridAnchorStrategy(
        periodicInterval = Duration.ofHours(1),
        maxUpdates = 100,
        forceAnchorOnVerify = true
    )
    

See Blockchain-Anchored Revocation for complete documentation and examples.

Trust Operations

Trust operations allow you to manage trust anchors and verify issuer trust relationships. The trust registry must be configured during TrustWeave.build { }.

trust (DSL Style)

Performs trust operations using the trust DSL. Provides a fluent API for managing trust anchors and discovering trust paths.

1
suspend fun trust(block: suspend TrustBuilder.() -> Unit)

Access via: trustWeave.trust { }

Parameters:

The DSL builder provides a fluent API for trust operations:

  • addAnchor(String) { }: Add a trust anchor with metadata
  • removeAnchor(String): Remove a trust anchor
  • isTrusted(String, String?): Check if an issuer is trusted
  • getTrustPath(String, String): Find trust path between DIDs
  • getTrustedIssuers(String?): Get all trusted issuers

Returns: Unit

Edge Cases:

  • If trust registry is not configured → IllegalStateException with configuration instructions
  • If anchor already exists → Returns without error (idempotent)
  • If anchor doesn’t exist when removing → Returns without error (idempotent)

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
val trustWeave = TrustWeave.build {
    trust { provider(IN_MEMORY) }
}

// Using DSL
trustWeave.trust {
    addAnchor("did:key:university") {
        credentialTypes("EducationCredential")
        description("Trusted university")
    }

    val isTrusted = isTrusted("did:key:university", "EducationCredential")
    val path = getTrustPath("did:key:verifier", "did:key:issuer")
}

Errors:

  • IllegalStateException - Trust registry is not configured

addTrustAnchor

Adds a trust anchor to the registry. Convenience method for adding a trust anchor without using the DSL.

1
2
3
4
suspend fun addTrustAnchor(
    anchorDid: String,
    block: TrustAnchorMetadataBuilder.() -> Unit = {}
): Boolean

Access via: trustWeave.addTrustAnchor(anchorDid) { }

Parameters:

  • anchorDid (String, required): The DID of the trust anchor
  • block (TrustAnchorMetadataBuilder.() -> Unit, optional): Configuration block for trust anchor metadata
    • credentialTypes(String...): Credential types this anchor can issue
    • description(String): Human-readable description
    • metadata(Map<String, Any>): Additional metadata

Returns: Boolean - true if the anchor was added successfully, false if it already exists

Example:

1
2
3
4
5
6
7
8
9
10
val added = trustWeave.addTrustAnchor("did:key:university") {
    credentialTypes("EducationCredential", "TranscriptCredential")
    description("Trusted university")
}

if (added) {
    println("Trust anchor added")
} else {
    println("Trust anchor already exists")
}

Errors:

  • IllegalStateException - Trust registry is not configured

removeTrustAnchor

Removes a trust anchor from the registry.

1
suspend fun removeTrustAnchor(anchorDid: String): Boolean

Access via: trustWeave.removeTrustAnchor(anchorDid)

Parameters:

  • anchorDid (String, required): The DID of the trust anchor to remove

Returns: Boolean - true if the anchor was removed, false if it didn’t exist

Example:

1
2
3
4
val removed = trustWeave.removeTrustAnchor("did:key:university")
if (removed) {
    println("Trust anchor removed")
}

Errors:

  • IllegalStateException - Trust registry is not configured

isTrustedIssuer

Checks if an issuer is trusted for a specific credential type.

1
2
3
4
suspend fun isTrustedIssuer(
    issuerDid: String,
    credentialType: String? = null
): Boolean

Access via: trustWeave.isTrustedIssuer(issuerDid, credentialType)

Parameters:

  • issuerDid (String, required): The DID of the issuer to check
  • credentialType (String?, optional): The credential type (null means check for any type)

Returns: Boolean - true if the issuer is trusted, false otherwise

Example:

1
2
3
4
5
6
7
8
val isTrusted = trustWeave.isTrustedIssuer(
    issuerDid = "did:key:university",
    credentialType = "EducationCredential"
)

if (isTrusted) {
    println("Issuer is trusted for EducationCredential")
}

Errors:

  • IllegalStateException - Trust registry is not configured

getTrustPath

Finds a trust path between two DIDs.

1
suspend fun getTrustPath(fromDid: String, toDid: String): TrustPathResult?

Access via: trustWeave.getTrustPath(fromDid, toDid)

Parameters:

  • fromDid (String, required): The starting DID (typically the verifier)
  • toDid (String, required): The target DID (typically the issuer)

Returns: TrustPathResult? - Trust path if one exists, null otherwise

Example:

1
2
3
4
5
6
7
8
9
10
val path = trustWeave.getTrustPath(
    fromDid = "did:key:verifier",
    toDid = "did:key:issuer"
)

if (path != null) {
    println("Trust path found: ${path.path}")
} else {
    println("No trust path found")
}

Errors:

  • IllegalStateException - Trust registry is not configured

getTrustedIssuers

Gets all trusted issuers for a specific credential type.

1
suspend fun getTrustedIssuers(credentialType: String? = null): List<String>

Access via: trustWeave.getTrustedIssuers(credentialType)

Parameters:

  • credentialType (String?, optional): The credential type (null means all types)

Returns: List<String> - List of trusted issuer DIDs

Example:

1
2
val trustedIssuers = trustWeave.getTrustedIssuers("EducationCredential")
println("Trusted issuers: $trustedIssuers")

Errors:

  • IllegalStateException - Trust registry is not configured

Wallet Operations

wallet

Creates a wallet for storing credentials using the DSL. Wallets provide secure storage and management of verifiable credentials for a specific holder.

1
suspend fun wallet(block: WalletBuilder.() -> Unit): Wallet

Access via: trustWeave.wallet { }

Parameters:

The DSL builder provides a fluent API for configuring the wallet:

  • holder(String): The DID of the credential holder (required)
  • id(String): Unique wallet identifier (optional, auto-generated if not provided)
  • enableOrganization(): Enable collections, tags, and metadata features
  • enablePresentation(): Enable presentation and selective disclosure support

Returns: Wallet - The created wallet instance with:

  • walletId: Unique wallet identifier
  • holderDid: The holder’s DID
  • capabilities: Available wallet features (organization, presentation, etc.)

Wallet Options:

  • enableOrganization: Enable collections, tags, and metadata features (default: false)
  • enablePresentation: Enable presentation and selective disclosure support (default: false)
  • storagePath: File system or bucket path for persistent storage (required for FileSystem/S3 providers)
  • encryptionKey: Secret material for at-rest encryption (optional, recommended for production)

Performance Characteristics:

  • Time Complexity: O(1) for in-memory, O(1) for database (with index), O(1) for file system
  • Space Complexity: O(1) for wallet creation (storage grows with credentials)
  • Network Calls: 0 for InMemory, 1 for Database/S3 (connection check)
  • Thread Safety: Thread-safe creation, wallet instance may have provider-specific thread safety

Edge Cases:

  • If walletId already exists for the provider, returns WalletCreationFailed error
  • If storagePath is invalid or inaccessible, returns WalletCreationFailed error
  • If holderDid format is invalid, returns InvalidDidFormat error
  • If provider is not registered, returns WalletCreationFailed error

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Simple usage (in-memory, for testing)
val wallet = trustWeave.wallet {
    holder("did:key:holder")
}
println("Created wallet: ${wallet.walletId}")
println("Holder: ${wallet.holderDid}")

// With organization and presentation enabled
val wallet = trustWeave.wallet {
    holder("did:key:holder")
    id("my-wallet-id")
    enableOrganization()
    enablePresentation()
}

// Use wallet directly
wallet.store(credential)
val retrieved = wallet.get(credentialId)
val allCredentials = wallet.list()

Errors:

  • TrustWeaveError.WalletCreationFailed - Wallet creation failed (provider not found, configuration invalid, storage unavailable, duplicate wallet ID)
  • TrustWeaveError.InvalidDidFormat - Invalid holder DID format
  • TrustWeaveError.ValidationFailed - Invalid wallet options or configuration

Advanced TrustWeave Methods

getDslContext

Gets the DSL context for advanced operations. Use this only when you need to access lower-level services or perform operations not exposed by the TrustWeave facade.

1
fun getDslContext(): TrustWeaveContext

Access via: trustWeave.getDslContext()

Returns: TrustWeaveContext - The DSL context providing access to underlying services

When to use:

  • Accessing lower-level DID resolver directly
  • Performing advanced operations not in the facade
  • Custom service integration

Example:

1
2
3
val context = trustWeave.getDslContext()
val resolver = context.getDidResolver()
val result = resolver?.resolve("did:key:example")

Note: Most operations should be done through TrustWeave methods. Only use this for advanced use cases.

configuration

Gets the underlying configuration object. Provides access to lower-level configuration details if needed.

1
val configuration: TrustWeaveConfig

Access via: trustWeave.configuration

Returns: TrustWeaveConfig - The configuration object

When to use:

  • Inspecting registered DID methods
  • Checking configured providers
  • Advanced configuration access

Example:

1
2
3
val config = trustWeave.configuration
val didMethods = config.didMethods.keys
println("Registered DID methods: $didMethods")

Note: Most operations should be done through TrustWeave methods. Only use this for inspection or advanced use cases.

from (Companion Method)

Creates a TrustWeave from an existing TrustWeaveConfig. Useful when you already have a configuration object and want to create the facade wrapper.

1
fun from(config: TrustWeaveConfig): TrustWeave

Access via: TrustWeave.from(config)

Parameters:

  • config (TrustWeaveConfig, required): The existing configuration object

Returns: TrustWeave - A TrustWeave instance wrapping the provided config

When to use:

  • Reusing a configuration object
  • Creating multiple TrustWeave instances from the same config
  • Advanced configuration scenarios

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Create config once (using suspend function)
import org.trustweave.trust.dsl.trustWeave

val config = trustWeave("my-instance") {
    factories(
        kmsFactory = TestkitKmsFactory(),
        didMethodFactory = TestkitDidMethodFactory()
    )
    keys { provider(IN_MEMORY); algorithm(ED25519) }
    did { method(KEY) { algorithm(ED25519) } }
}

// Create multiple TrustWeave instances from the same config
val trustWeave1 = TrustWeave.from(config)
val trustWeave2 = TrustWeave.from(config)

Note: In most cases, you should use TrustWeave.build { } instead of creating a config first. This method is primarily for advanced scenarios where you need to reuse a configuration object.

Note: The configuration is shared between instances. Changes to one may affect others.

Blockchain Anchoring

anchor

Anchors data to a blockchain for tamper evidence and timestamping. The data is serialized to JSON, canonicalized, and only the digest is stored on-chain (not the full data).

1
2
3
4
5
suspend fun <T : Any> anchor(
    data: T,
    serializer: KSerializer<T>,
    chainId: String
): Result<AnchorResult>

Parameters:

  • data: The data to anchor (any serializable type, must be JSON-serializable)
  • serializer: Kotlinx Serialization serializer for the data type (required)
  • chainId: Chain ID in CAIP-2 format (e.g., "algorand:testnet", "polygon:mainnet")

Returns: Result<AnchorResult> containing:

  • ref: AnchorRef with:
    • chainId: The blockchain chain identifier
    • txHash: Transaction hash of the anchor
    • blockNumber: Block number where anchored (if available)
  • timestamp: When the data was anchored (ISO 8601 format)

Performance Characteristics:

  • Time Complexity: O(N) for serialization where N is data size, O(1) for blockchain write
  • Space Complexity: O(N) for serialization buffer
  • Network Calls: 1-2 (blockchain transaction submission + confirmation, if required)
  • Blockchain Latency: Varies by chain (Algorand: ~4s, Polygon: ~2s, Ethereum: ~15s)
  • Thread Safety: Thread-safe, can be called concurrently (each call creates separate transaction)

Edge Cases:

  • If data cannot be serialized, returns ValidationFailed error
  • If chain is not registered, returns ChainNotRegistered error
  • If blockchain transaction fails (network issue, insufficient funds), returns Unknown error with cause
  • Large data (>1MB) may require chunking or off-chain storage (implementation-dependent)

Note: The full data is NOT stored on-chain. Only a cryptographic digest (hash) is stored. To retrieve the original data, you must store it separately and use readAnchor() with the stored data.

Example:

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
// Simple usage
val myData = MyData(id = "123", value = "test")
try {
    val anchor = trustweave.blockchains.anchor(
        data = myData,
        serializer = MyData.serializer(),
        chainId = "algorand:testnet"
    )
    println("Anchored at: ${anchor.ref.txHash}")
    println("Block: ${anchor.ref.blockNumber}")
    println("Timestamp: ${anchor.timestamp}")
    // Store anchorRef for later retrieval
    saveAnchorRef(anchor.ref)
} catch (error: TrustWeaveError) {
    when (error) {
        is TrustWeaveError.ChainNotRegistered -> {
            println("Chain not registered: ${error.chainId}")
            println("Available chains: ${error.availableChains}")
        }
        else -> {
            println("Anchoring error: ${error.message}")
        }
    }
}

// With timeout handling
import kotlinx.coroutines.withTimeout

val anchor = withTimeout(30000) { // 30 second timeout
    trustweave.blockchains.anchor(
        data = data,
        serializer = serializer,
        chainId = chainId
    )
}

Errors:

  • TrustWeaveError.ChainNotRegistered - Chain ID not registered in registry
  • TrustWeaveError.ValidationFailed - Invalid chain ID format or data serialization failure
  • TrustWeaveError.Unknown - Blockchain transaction failed (network error, insufficient funds, etc.)

readAnchor

Reads anchored data from a blockchain using the anchor reference. This retrieves the data that was stored during anchor() and verifies it matches the on-chain digest.

1
2
3
4
suspend fun <T : Any> readAnchor(
    ref: AnchorRef,
    serializer: KSerializer<T>
): Result<T>

Parameters:

  • ref: AnchorRef containing chain ID and transaction hash (required, must be valid)
  • serializer: Kotlinx Serialization serializer for the data type (required, must match original type)

Returns: Result<T> containing the deserialized data matching the serializer type

Performance Characteristics:

  • Time Complexity: O(N) for deserialization where N is data size, O(1) for blockchain read
  • Space Complexity: O(N) for deserialized data
  • Network Calls: 1-2 (blockchain transaction read + data retrieval)
  • Blockchain Latency: Varies by chain (typically faster than writes)
  • Thread Safety: Thread-safe, can be called concurrently

Edge Cases:

  • If ref points to non-existent transaction, returns Unknown error
  • If data type doesn’t match serializer, deserialization fails with Unknown error
  • If on-chain digest doesn’t match data digest, returns ValidationFailed error (tamper detection)
  • If chain is not registered, returns ChainNotRegistered error

Note: This method reads the data that was stored during anchor(). The data must be stored separately (not on-chain, only digest is on-chain). If using a storage-backed anchor client, it retrieves from storage. Otherwise, you must provide the data separately and this verifies the digest matches.

Example:

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
// Simple usage
val anchorRef = AnchorRef(
    chainId = "algorand:testnet",
    txHash = "abc123..."
)
try {
    val data = trustweave.blockchains.read<MyData>(
        ref = anchorRef,
        serializer = MyData.serializer()
    )
    println("Read data: $data")
    println("Verified against on-chain digest")
} catch (error: TrustWeaveError) {
    when (error) {
        is TrustWeaveError.ChainNotRegistered -> {
            println("Chain not registered: ${error.chainId}")
            println("Available chains: ${error.availableChains}")
        }
        is TrustWeaveError.ValidationFailed -> {
            println("Data verification failed - possible tampering!")
            println("Reason: ${error.reason}")
        }
        else -> {
            println("Read error: ${error.message}")
        }
    }
}

Errors:

  • TrustWeaveError.ChainNotRegistered - Chain ID not registered in registry
  • TrustWeaveError.ValidationFailed - Data digest doesn’t match on-chain digest (tamper detected) or deserialization failed
  • TrustWeaveError.Unknown - Transaction not found or data retrieval failed

availableChains

Gets a list of available blockchain chain IDs.

1
fun availableChains(): List<String>

Access via: trustWeave.blockchains.availableChains()

Returns: List<String> - List of registered blockchain chain IDs in CAIP-2 format

Example:

1
2
val chains = trustweave.blockchains.availableChains()
println("Available chains: $chains") // ["algorand:testnet", "polygon:mainnet"]

Smart Contract Operations

The contracts service provides operations for creating, binding, and executing smart contracts.

draft

Creates a contract draft.

1
suspend fun draft(request: ContractDraftRequest): Result<SmartContract>

Access via: trustWeave.contracts.draft(request)

Parameters:

  • request (ContractDraftRequest, required): Contract draft request containing contract type, execution model, parties, terms, etc.

Returns: Result<SmartContract> - The created contract draft

Example:

1
2
3
4
5
6
7
8
9
10
val contract = trustweave.contracts.draft(
    request = ContractDraftRequest(
        contractType = ContractType.Insurance,
        executionModel = ExecutionModel.Parametric(...),
        parties = ContractParties(...),
        terms = ContractTerms(...),
        effectiveDate = Instant.now().toString(),
        contractData = buildJsonObject { ... }
    )
).getOrThrow()

bindContract

Binds a contract by issuing a credential and anchoring it to a blockchain.

1
2
3
4
5
6
suspend fun bindContract(
    contractId: String,
    issuerDid: String,
    issuerKeyId: String,
    chainId: String
): Result<BoundContract>

Access via: trustWeave.contracts.bindContract(...)

Returns: Result<BoundContract> - The bound contract with credential and anchor reference

executeContract

Executes a contract based on its execution model.

1
2
3
4
suspend fun executeContract(
    contract: SmartContract,
    executionContext: ExecutionContext
): Result<ExecutionResult>

Access via: trustWeave.contracts.executeContract(contract, executionContext)

Returns: Result<ExecutionResult> - The execution result

Other Contract Methods

  • issueCredential(contract, issuerDid, issuerKeyId): Issues a verifiable credential for a contract
  • anchorContract(contract, credential, chainId): Anchors a contract to a blockchain
  • activateContract(contractId): Activates a contract (moves from PENDING to ACTIVE)
  • evaluateConditions(contract, inputData): Evaluates contract conditions
  • updateStatus(contractId, newStatus, reason, metadata): Updates contract status
  • getContract(contractId): Gets a contract by ID
  • verifyContract(credentialId): Verifies a contract credential

See Smart Contract API for detailed documentation.

Plugin Lifecycle Management

initialize

Initializes all plugins that implement PluginLifecycle.

1
suspend fun initialize(config: Map<String, Any?> = emptyMap()): Result<Unit>

Example:

1
2
3
4
5
6
7
8
9
10
11
12
val trustweave = TrustWeave.create()

val config = mapOf(
    "database" to mapOf("url" to "jdbc:postgresql://localhost/TrustWeave")
)

try {
    trustweave.initialize(config)
    println("Plugins initialized")
} catch (error: TrustWeaveError) {
    println("Initialization error: ${error.message}")
}

start

Starts all plugins that implement PluginLifecycle.

1
suspend fun start(): Result<Unit>

Example:

1
2
3
4
5
6
try {
    trustweave.start()
    println("Plugins started")
} catch (error: TrustWeaveError) {
    println("Start error: ${error.message}")
}

stop

Stops all plugins that implement PluginLifecycle.

1
suspend fun stop(): Result<Unit>

Example:

1
2
3
4
5
6
try {
    trustweave.stop()
    println("Plugins stopped")
} catch (error: TrustWeaveError) {
    println("Stop error: ${error.message}")
}

cleanup

Cleans up all plugins that implement PluginLifecycle.

1
suspend fun cleanup(): Result<Unit>

Example:

1
2
3
4
5
6
try {
    trustweave.cleanup()
    println("Plugins cleaned up")
} catch (error: TrustWeaveError) {
    println("Cleanup error: ${error.message}")
}

Error Types

All operations can return errors of type TrustWeaveError. See Error Handling for complete error type documentation.

Common Error Types

  • TrustWeaveError.DidMethodNotRegistered - DID method not registered
  • TrustWeaveError.InvalidDidFormat - Invalid DID format
  • TrustWeaveError.CredentialInvalid - Credential validation failed
  • TrustWeaveError.ChainNotRegistered - Chain ID not registered
  • TrustWeaveError.WalletCreationFailed - Wallet creation failed
  • TrustWeaveError.PluginInitializationFailed - Plugin initialization failed

Error Handling

Exception-Based Error Handling (TrustWeave Methods)

All TrustWeave methods throw exceptions on failure. This includes:

  • createDid(), updateDid(), delegate(), rotateKey()
  • issue(), verify()
  • wallet()
  • Trust operations (addTrustAnchor(), removeTrustAnchor(), etc.)

Example:

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.core.TrustWeaveError

try {
    val trustWeave = TrustWeave.build { ... }
    val did = trustWeave.createDid {
        method(KEY)
        algorithm(ED25519)
    }
    val credential = trustWeave.issue {
        credential { ... }
        signedBy(issuerDid = did, keyId = "$did#key-1")
    }
    val wallet = trustWeave.wallet {
        holder(did)
    }
} catch (error: TrustWeaveError) {
    when (error) {
        is TrustWeaveError.DidMethodNotRegistered -> {
            println("Method not registered: ${error.method}")
            println("Available methods: ${error.availableMethods}")
        }
        is TrustWeaveError.ChainNotRegistered -> {
            println("Chain not registered: ${error.chainId}")
            println("Available chains: ${error.availableChains}")
        }
        else -> println("Error: ${error.message}")
    }
}

Result-Based Error Handling (Lower-Level APIs)

Some lower-level APIs return Result<T> directly. This includes:

  • Contract operations (when accessed via lower-level APIs)
  • Some plugin lifecycle methods
  • Custom service implementations

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
val result = someService.operation()
result.fold(
    onSuccess = { value ->
        // Handle success
        println("Success: $value")
    },
    onFailure = { error ->
        // Handle error
        when (error) {
            is TrustWeaveError.ValidationFailed -> {
                println("Validation failed: ${error.reason}")
            }
            else -> println("Error: ${error.message}")
        }
    }
)

When to use which pattern:

  • Exception-based (TrustWeave): Use for all TrustWeave facade methods. Wrap in try-catch for production code.
  • Result-based: Use when working with lower-level service APIs that explicitly return Result<T>.

Best Practice: Always handle errors explicitly. Never ignore exceptions or Result failures in production code.

Configuration

Registering DID Methods

DID methods are registered during TrustWeave creation using the DSL:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import org.trustweave.trust.TrustWeave

val trustWeave = TrustWeave.build {
    keys {
        provider(IN_MEMORY)
        algorithm(ED25519)
    }
    did {
        method(KEY) {
            algorithm(ED25519)
        }
        method(WEB) {
            domain("example.com")
        }
        method(ION) {
            // ION-specific configuration
        }
    }
}

Registering Blockchain Anchors

Blockchain anchor clients are registered during TrustWeave creation:

1
2
3
4
5
6
7
8
9
10
11
12
13
val trustWeave = TrustWeave.build {
    keys { ... }
    did { ... }
    anchor {
        chain("algorand:testnet") {
            provider(ALGORAND)
            // Chain-specific configuration
        }
        chain("polygon:mainnet") {
            provider(POLYGON)
        }
    }
}

Registering Trust Registry

Trust registry is configured during TrustWeave creation:

1
2
3
4
5
6
7
8
val trustWeave = TrustWeave.build {
    keys { ... }
    did { ... }
    trust {
        provider(IN_MEMORY)
        // Or use a custom trust registry implementation
    }
}

Note: For advanced configuration with custom services, proof generators, or credential services, you may need to configure the underlying TrustWeaveConfig directly. See Advanced Configuration for details.


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