Code Style
This guide outlines the coding conventions and style guidelines for TrustWeave.
Overview
TrustWeave follows Kotlin coding conventions with some project-specific guidelines:
- Kotlin Style Guide – follows official Kotlin style guide
- ktlint – automated formatting with ktlint
- Naming Conventions – clear, descriptive names
- Documentation – comprehensive KDoc comments
Code Formatting
ktlint Configuration
The project uses ktlint for code formatting. Format your code:
1
2
3
4
5
# Check formatting
./gradlew ktlintCheck
# Auto-format
./gradlew ktlintFormat
Format on Save
Configure your IDE to format on save:
IntelliJ IDEA:
- Install ktlint plugin
- Enable “Reformat code on save”
- Configure ktlint as formatter
Naming Conventions
Classes
Use PascalCase for class names:
1
2
3
class MyCustomDidMethod : DidMethod {
// ...
}
Functions
Use camelCase for function names:
1
2
3
suspend fun createDid(options: DidCreationOptions): DidDocument {
// ...
}
Variables
Use camelCase for variable names:
1
2
val issuerDid = "did:key:issuer"
val credentialSubject = jsonData { }
Constants
Use UPPER_SNAKE_CASE for constants:
1
2
3
4
companion object {
const val DEFAULT_TIMEOUT = 30000L
const val MAX_RETRIES = 3
}
Code Structure
File Organization
Organize files logically:
1
2
3
4
5
6
7
8
9
10
11
// Package declaration
package org.trustweave.example
// Imports
import org.trustweave.did.*
import kotlinx.coroutines.runBlocking
// Class/object definitions
class Example {
// ...
}
Function Length
Keep functions concise:
- Short functions – prefer functions under 20 lines
- Complex logic – extract to separate functions
- Single responsibility – each function should do one thing
Class Size
Keep classes focused:
- Single responsibility – each class should have one purpose
- Composition over inheritance – prefer composition
- Interfaces – use interfaces for abstractions
Documentation
KDoc Comments
Document public APIs:
1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* Creates a DID using the specified method.
*
* @param method The DID method to use (e.g., "key", "web")
* @param options Configuration options for DID creation
* @return Result containing the created DID document or error
*/
suspend fun createDid(
method: String,
options: DidCreationOptions
): Result<DidDocument> {
// ...
}
Inline Documentation
Add comments for complex logic:
1
2
// Generate identifier from public key using multibase encoding
val identifier = multibase.encode(key.publicKey)
Error Handling
Result Types
Use Result<T> for your own helpers when it fits. The TrustWeave facade and DID layer prefer sealed types (DidCreationResult, DidResolutionResult, IssuanceResult, VerificationResult, …)—handle those with when, not only Result.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
suspend fun createDid(): Result<DidDocument> {
return try {
val document: DidDocument = /* implementation */
Result.success(document)
} catch (e: Exception) {
Result.failure(
DidException.DidCreationFailed(
did = null,
reason = e.message ?: "Unknown error",
cause = e
)
)
}
}
Error types
Prefer module sealed exception hierarchies (for example org.trustweave.did.exception.DidException, org.trustweave.anchor.exceptions.BlockchainException) and the shared base org.trustweave.core.exception.TrustWeaveException instead of ad-hoc error classes.
Testing
Test Naming
Use descriptive test names:
1
2
3
4
5
6
7
8
9
@Test
fun testCreateDidWithEd25519Algorithm() = runBlocking {
// ...
}
@Test
fun testResolveDidReturnsDocument() = runBlocking {
// ...
}
Test Organization
Organize tests logically:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class DidMethodTest {
@Test
fun testCreateDid() = runBlocking {
// ...
}
@Test
fun testResolveDid() = runBlocking {
// ...
}
@Test
fun testUpdateDid() = runBlocking {
// ...
}
}
Best Practices
Immutability
Prefer immutable data:
1
2
3
4
5
6
7
8
9
// Prefer immutable data classes
data class DidDocument(
val id: String,
val verificationMethod: List<VerificationMethod>
)
// Avoid mutable state
// ❌ var document: DidDocument? = null
// ✅ val document: DidDocument? = null
Null Safety
Use Kotlin’s null safety features:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// TrustWeave: resolveDid returns sealed DidResolutionResult — branch, then use document
import org.trustweave.did.identifiers.Did
import org.trustweave.did.model.DidDocument
import org.trustweave.did.resolver.DidResolutionResult
// val trustWeave: TrustWeave = …
val didDocument: DidDocument? = when (val r = trustWeave.resolveDid(Did("did:key:…"))) {
is DidResolutionResult.Success -> r.document
is DidResolutionResult.Deactivated -> null
is DidResolutionResult.Failure -> null
}
// Safe calls on a nullable DidDocument from any layer
didDocument?.verificationMethod?.first()
// Elvis for defaults
val method = didDocument?.verificationMethod?.first() ?: throw NotFoundException()
Collapsing Deactivated to null here is fine for a “do I have a document” check, but it throws
away the distinction between “never registered” and “revoked.” Code that uses the document for
verification or authorization should branch on Deactivated separately and reject it, rather
than treating a null document as merely absent.
Extension Functions
Use extension functions for utilities:
1
2
3
fun DidDocument.toJson(): JsonObject {
// Conversion logic
}
Scope Functions
Use scope functions appropriately:
1
2
3
4
5
6
7
8
9
10
// Use `let` for null checks
didDocument?.let { document ->
// Use document
}
// Use `apply` for configuration
val config = MyConfig().apply {
endpoint = "https://example.com"
timeout = 30000L
}
Code Review Guidelines
Checklist
Before submitting code for review:
- Code is formatted (
./gradlew ktlintCheck) - All tests pass (
./gradlew test) - Public APIs are documented
- Error handling is appropriate
- Code follows naming conventions
- No hardcoded values (use constants)
- No commented-out code
Review Feedback
When reviewing code:
- Be constructive and respectful
- Focus on code quality, not style preferences
- Suggest improvements, don’t just point out issues
- Explain why changes are needed
Next Steps
- Review Development Setup for environment setup
- See Testing Guidelines for testing practices
- Check Pull Request Process for contribution workflow
- Explore existing code in TrustWeave modules for examples