Skip to content

Commit

Permalink
chore: KMP annotation, code documentation
Browse files Browse the repository at this point in the history
Signed-off-by: Ahmed Moussa <ahmed.moussa@iohk.io>
  • Loading branch information
hamada147 committed Jun 21, 2024
1 parent c00cae6 commit fabeb00
Show file tree
Hide file tree
Showing 13 changed files with 211 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,22 +85,21 @@ class ApolloImpl : Apollo {
/**
* Creates a private key based on the provided properties.
*
* @param properties A map of properties used to create the private key. The map should contain the following keys:
* - "type" (String): The type of the key ("EC" or "Curve25519").
* - "curve" (String): The curve of the key.
* - "rawKey" (ByteArray): The raw key data (optional).
* - "index" (Int): The index for the key (only applicable for EC keys with curve "secp256k1").
* - "derivationPath" (String): The derivation path for the key (only applicable for EC keys with curve "secp256k1").
* - "seed" (String): The seed for the key (only applicable for EC keys with curve "secp256k1").
* @param properties The map of properties used to create the private key.
* The properties should include the following keys:
* - `Type`: The type of the key (e.g., "EC", "Curve25519").
* - `Curve`: The curve of the key (e.g., "ED25519", "SECP256K1", "X25519").
* - `RawKey`: The raw key data (optional).
* - `Seed`: The seed used to derive the key (optional).
* - `DerivationPath`: The derivation path used to derive the key (optional, required if seed is provided).
* - `Index`: The index used in the derivation path (optional, required if seed is provided).
*
* @return The created private key.
*
* @throws ApolloError.InvalidKeyType If the provided key type is invalid.
* @throws ApolloError.InvalidKeyCurve If the provided key curve is invalid.
* @throws IllegalArgumentException If the provided properties are invalid or insufficient to create the key.
* @throws ApolloError.InvalidKeyType If the provided key type is invalid or not supported.
* @throws ApolloError.InvalidKeyCurve If the provided key curve is invalid or not supported.
* @throws ApolloError.InvalidRawData If the provided raw key data is invalid.
* @throws ApolloError.InvalidIndex If the provided index is invalid.
* @throws ApolloError.InvalidDerivationPath If the provided derivation path is invalid.
* @throws ApolloError.InvalidSeed If the provided seed is invalid.
*/
override fun createPrivateKey(properties: Map<String, Any>): PrivateKey {
if (!properties.containsKey(TypeKey().property)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package org.hyperledger.identus.walletsdk.apollo.utils

/**
* Enumeration class representing different key usages.
*
* Each key usage is assigned a unique integer value.
*/
enum class KeyUsage(val value: Int) {
UNKNOWN_KEY(0),
MASTER_KEY(1),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ import org.hyperledger.identus.apollo.derivation.DerivationAxis
import org.hyperledger.identus.apollo.derivation.DerivationPath

/**
* m/wallet-purpose`/did-method`/did-index`/key-purpose`/key-index`
* m/29' /29' /0' /1' /$index'
* Represents the derivation path of a Prism key, used for deriving child keys from a master key.
*
* @property walletPurpose The purpose of the wallet. Default value is 29.
* @property didMethod The purpose of the DID method. Default value is 29.
* @property didIndex The index of the DID. Default value is 0.
* @property keyPurpose The purpose of the key.
* @property keyIndex The index of the key.
*/
class PrismDerivationPath(
walletPurpose: Int = 29,
Expand All @@ -15,6 +20,11 @@ class PrismDerivationPath(
keyIndex: Int
) {

/**
* The derivation path represents the path used to derive a cryptographic key.
*
* @property derivationPath The actual derivation path represented as a [DerivationPath] object.
*/
private val derivationPath: DerivationPath = DerivationPath(
listOf(
DerivationAxis.hardened(walletPurpose),
Expand All @@ -25,6 +35,15 @@ class PrismDerivationPath(
)
)

/**
* Constructs a new instance of the class.
*
* @param walletPurpose the purpose of the wallet
* @param didMethod the method used for DID (Decentralized Identifier) generation
* @param didIndex the index of the DID
* @param keyPurpose the purpose of the key
* @param keyIndex the index of the key
*/
constructor(
walletPurpose: Int = 29,
didMethod: Int = 29,
Expand All @@ -33,6 +52,10 @@ class PrismDerivationPath(
keyIndex: Int
) : this(walletPurpose, didMethod, didIndex, keyPurpose.value, keyIndex)

/**
* Returns a string representation of the object.
*
* The returned string is in the format `m/wallet-purpose`*/
override fun toString(): String {
// m/wallet-purpose`/did-method`/did-index`/key-purpose`/key-index`
return derivationPath.toString()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ data class JWTVerifiablePresentation(
val type: Array<String>,
val verifiableCredential: Array<String>
) {
/**
* This method is used to check if the current object is equal to the given object.
*
* @param other The object to compare with.
* @return True if the two objects are equal, false otherwise.
*/
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
Expand All @@ -129,6 +135,14 @@ data class JWTVerifiablePresentation(
return true
}

/**
* Computes the hash code value of this object.
*
* The hash code is generated by applying the 31 * result + contentHashCode() formula to each property,
* where result is initialized with the contentHashCode() of the context property.
*
* @return the computed hash code value of this object.
*/
override fun hashCode(): Int {
var result = context.contentHashCode()
result = 31 * result + type.contentHashCode()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ constructor(
val data: AttachmentData,
val filename: Array<String>? = null,
val format: String? = null,
// TODO(Date format)
@SerialName("lastmod_time")
@JsonNames("lastmod_time", "lastModTime")
val lastModTime: String? = null,
Expand Down Expand Up @@ -187,9 +186,47 @@ constructor(
}
}

/**
* The `AttachmentDataSerializer` is responsible for serializing and deserializing instances of `AttachmentData`.
*
* To serialize an `AttachmentData` object, use the `serialize` function. This function takes an `Encoder` and the
* `AttachmentData` object to be serialized as parameters. It delegates the serialization to the appropriate serializer
* based on the type of the `AttachmentData` object. The supported types are:
* - `AttachmentData.AttachmentHeader`
* - `AttachmentData.AttachmentJws`
* - `AttachmentData.AttachmentJwsData`
* - `AttachmentData.AttachmentBase64`
* - `AttachmentData.AttachmentLinkData`
* - `AttachmentData.AttachmentJsonData`
*
* To deserialize an `AttachmentData` object, use the `deserialize` function. This function takes a `Decoder` as a
* parameter. It first checks the JSON object read from the decoder to determine the type of the `AttachmentData`
* object. It then uses the appropriate deserializer to deserialize the JSON object into the corresponding
* `AttachmentData` subclass. The supported JSON object structures are:
* - `{ "children": ... }` for `AttachmentData.AttachmentHeader` objects
* - `{ "protected": ..., "signature": ... }` for `AttachmentData.AttachmentJws` objects
* - `{ "base64": ..., "jws": ... }` for `AttachmentData.AttachmentJwsData` objects
* - `{ "base64": ... }` for `AttachmentData.AttachmentBase64` objects
* - `{ "links": ..., "hash": ... }` for `AttachmentData.AttachmentLinkData` objects
* - `{ "data": ... }` for `AttachmentData.AttachmentJsonData` objects
*
* If the JSON object does not match any of the supported structures, a `SerializationException` is thrown.
*/
object AttachmentDataSerializer : KSerializer<AttachmentData> {
/**
* This variable represents the descriptor for the `AttachmentData` class when it is serialized and deserialized.
* It is an instance of the `SerialDescriptor` class.
*
* @see SerialDescriptor
*/
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("AttachmentData")

/**
* Serializes the given [AttachmentData] object using the provided [Encoder].
*
* @param encoder The encoder used for serialization.
* @param value The [AttachmentData] object to be serialized.
*/
override fun serialize(encoder: Encoder, value: AttachmentData) {
when (value) {
is AttachmentData.AttachmentHeader -> encoder.encodeSerializableValue(AttachmentData.AttachmentHeader.serializer(), value)
Expand All @@ -201,6 +238,13 @@ object AttachmentDataSerializer : KSerializer<AttachmentData> {
}
}

/**
* Deserializes a JSON representation of AttachmentData into an AttachmentData object.
*
* @param decoder The decoder used to decode the JSON representation.
* @return The deserialized AttachmentData object.
* @throws SerializationException if the JSON representation is of an unknown AttachmentData type.
*/
override fun deserialize(decoder: Decoder): AttachmentData {
val jsonDecoder = decoder as JsonDecoder
val json = jsonDecoder.decodeJsonElement().jsonObject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,13 @@ object InputFieldFilterSerializer : KSerializer<InputFieldFilter> {
element("value", PolymorphicSerializer(Any::class).descriptor, isOptional = true)
}

/**
* Deserializes the input data from the provided decoder into an instance of the InputFieldFilter class.
*
* @param decoder The decoder used to decode the input data.
* @return An instance of the InputFieldFilter class.
* @throws SerializationException if an unknown index is encountered during deserialization or if the "type" property is missing.
*/
@OptIn(ExperimentalSerializationApi::class)
override fun deserialize(decoder: Decoder): InputFieldFilter {
val dec: CompositeDecoder = decoder.beginStructure(descriptor)
Expand Down Expand Up @@ -262,6 +269,12 @@ object InputFieldFilterSerializer : KSerializer<InputFieldFilter> {
)
}

/**
* Serializes an [InputFieldFilter] object using the provided [Encoder].
*
* @param encoder The encoder used for serialization.
* @param value The [InputFieldFilter] object to be serialized.
*/
@OptIn(ExperimentalSerializationApi::class)
override fun serialize(encoder: Encoder, value: InputFieldFilter) {
val compositeOutput = encoder.beginStructure(descriptor)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1208,6 +1208,7 @@ class EdgeAgent {
}

// 3. Set the JWE header (algorithm and encryption)
// The following two line are needed because of a constrain in TS SDK
val backupText = "backup"
val apv = SHA256().digest(backupText.encodeToByteArray())

Expand Down Expand Up @@ -1273,11 +1274,12 @@ class EdgeAgent {
}

/**
* Creates an X25519 private key from a given seed.
* Creates a X25519PrivateKey using the provided seed and derivation path.
*
* @param seed The seed to generate the private key from.
* @return The generated X25519 private key.
* @throws UnknownError.SomethingWentWrongError If something goes wrong during the key generation process.
* @param seed The seed used to generate the private key.
* @param derivationPath The derivation path used to derive the private key with a default value of "m/0'/0'/0'"
* @return The generated X25519PrivateKey.
* @throws UnknownError.SomethingWentWrongError if an exception occurs during the private key generation.
*/
private fun createX25519PrivateKeyFrom(seed: Seed, derivationPath: String = "m/0'/0'/0'"): X25519PrivateKey {
return try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,15 @@ class BasicMediatorHandler(
}
}

/**
* Handles received messages from sockets.
*
* @param text The received message as a string.
* @return An array of pairs, where each pair consists of a string and a Message object. If the decryptedMessage's
* `piuri` value is equal to either ProtocolType.PickupStatus.value or ProtocolType.PickupDelivery.value, the
* result is obtained by calling the PickupRunner's run() method with the decryptedMessage and mercury as arguments.
* Otherwise, an empty array is returned.
*/
private suspend fun handleReceivedMessagesFromSockets(text: String): Array<Pair<String, Message>> {
val decryptedMessage = mercury.unpackMessage(text)
return if (decryptedMessage.piuri == ProtocolType.PickupStatus.value ||
Expand All @@ -248,6 +257,11 @@ class BasicMediatorHandler(
}
}

/**
* Represents a callback function for handling messages.
*
* This interface defines a single method [onMessage] that is invoked when messages are received.
*/
fun interface OnMessageCallback {
fun onMessage(messages: Array<Pair<String, Message>>)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,11 @@ class PlutoImpl(private val connection: DbConnection) : Pluto {
}
}

/**
* Retrieves all the keys for backup.
*
* @return A flow that emits a list of [BackupV0_0_1.Key] objects.
*/
override fun getAllKeysForBackUp(): Flow<List<BackupV0_0_1.Key>> {
val keysWithDID = getInstance().privateKeyQueries.fetchAllPrivateKeyWithDID()
.executeAsList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ open class PlutoRestoreTask(
*/
@OptIn(ExperimentalSerializationApi::class)
@Serializable
class AnonCredentialBackUp(
class AnonCredentialBackUp @JvmOverloads constructor(
@SerialName("schema_id")
@JsonNames("schema_id", "schemaID")
val schemaID: String,
Expand Down Expand Up @@ -371,7 +371,7 @@ open class PlutoRestoreTask(
* @property revocationCredential The R Credential string.
*/
@Serializable
class Signature(
class Signature @JvmOverloads constructor(
@SerialName("p_credential")
val primaryCredential: PrimaryCredential,
@SerialName("r_credential")
Expand Down Expand Up @@ -576,15 +576,41 @@ open class PlutoRestoreTask(
}
}

/**
* A serializer for converting JSON strings to Kotlin strings and vice versa.
*
* This serializer is used to encode a JSON string into a Kotlin string using [serialize] method,
* and decode a JSON string into a Kotlin string using [deserialize] method.
*
* @property descriptor The serial descriptor associated with this serializer.
*/
private object JsonAsStringSerializer : KSerializer<String> {
/**
* Provides the descriptor for a JSON value represented as a string.
*
* @return The serial descriptor.
*/
override val descriptor: SerialDescriptor =
PrimitiveSerialDescriptor("JsonAsString", PrimitiveKind.STRING)

/**
* Serializes a string value into an encoded format using the provided encoder.
*
* @param encoder the encoder to use for encoding the value
* @param value the string value to be serialized
*/
override fun serialize(encoder: Encoder, value: String) {
val jsonObject = Json.parseToJsonElement(value).jsonObject
encoder.encodeString(Json.encodeToString(jsonObject))
}

/**
* Deserializes a JSON string into a String object.
*
* @param decoder The decoder used to decode the JSON string.
* @return The deserialized String object.
* @throws UnknownError.SomethingWentWrongError if the JSON string is invalid.
*/
override fun deserialize(decoder: Decoder): String {
val jsonDecoder = decoder as JsonDecoder
val jsonElement = jsonDecoder.decodeJsonElement()
Expand Down Expand Up @@ -620,6 +646,12 @@ open class PlutoRestoreTask(
override val descriptor: SerialDescriptor =
PrimitiveSerialDescriptor("EpochSecondsString", PrimitiveKind.LONG)

/**
* Checks if the given epoch time is likely to be in seconds.
*
* @param epochTime The epoch time to be checked.
* @return true if the epoch time is likely in seconds, false otherwise.
*/
private fun isEpochTimeLikelySeconds(epochTime: String): Boolean {
return epochTime.length <= 10 // Epoch in seconds has up to 10 digits
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import kotlinx.serialization.Serializable
@Serializable
class BackupV0_0_1
@OptIn(ExperimentalSerializationApi::class)
@JvmOverloads
constructor(
@EncodeDefault
val version: String = "0.0.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ data class AnonCredential(
private val json: String
) : Credential {

/**
* Converts the current object to a [PlutoRestoreTask.AnonCredentialBackUp] object.
*
* @return The converted [PlutoRestoreTask.AnonCredentialBackUp] object.
*/
fun toAnonCredentialBackUp(): PlutoRestoreTask.AnonCredentialBackUp {
return PlutoRestoreTask.AnonCredentialBackUp(
schemaID = this.schemaID,
Expand Down
Loading

0 comments on commit fabeb00

Please sign in to comment.