diff --git a/authenticate-sdk/src/androidMain/AndroidManifest.xml b/authenticate-sdk/src/androidMain/AndroidManifest.xml new file mode 100644 index 000000000..e5189b493 --- /dev/null +++ b/authenticate-sdk/src/androidMain/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/build.gradle.kts b/build.gradle.kts index 4739f98b9..ea101b1ba 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -26,6 +26,7 @@ buildscript { classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.20") classpath("com.android.tools.build:gradle:7.2.2") classpath("com.google.protobuf:protobuf-gradle-plugin:0.9.1") + classpath("com.squareup.sqldelight:gradle-plugin:1.5.4") } } diff --git a/castor/src/androidMain/AndroidManifest.xml b/castor/src/androidMain/AndroidManifest.xml index 96d824081..0629c4898 100644 --- a/castor/src/androidMain/AndroidManifest.xml +++ b/castor/src/androidMain/AndroidManifest.xml @@ -1,2 +1,2 @@ - \ No newline at end of file + diff --git a/core-sdk/src/androidMain/AndroidManifest.xml b/core-sdk/src/androidMain/AndroidManifest.xml index c2511c018..b180fccf7 100644 --- a/core-sdk/src/androidMain/AndroidManifest.xml +++ b/core-sdk/src/androidMain/AndroidManifest.xml @@ -1,2 +1,2 @@ - \ No newline at end of file + diff --git a/domain/build.gradle.kts b/domain/build.gradle.kts index a3ef2434d..527851289 100644 --- a/domain/build.gradle.kts +++ b/domain/build.gradle.kts @@ -68,6 +68,7 @@ kotlin { dependencies { implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4") + implementation("com.benasher44:uuid:0.3.0") // TODO("use Apollo UUID") } } val commonTest by getting { diff --git a/domain/src/androidMain/AndroidManifest.xml b/domain/src/androidMain/AndroidManifest.xml index d03883202..e9e80b325 100644 --- a/domain/src/androidMain/AndroidManifest.xml +++ b/domain/src/androidMain/AndroidManifest.xml @@ -1,2 +1,2 @@ - \ No newline at end of file + diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/buildingBlocks/.editorconfig b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/buildingBlocks/.editorconfig new file mode 100644 index 000000000..e69de29bb diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/buildingBlocks/Castor.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/buildingBlocks/Castor.kt new file mode 100644 index 000000000..b7c5198a6 --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/buildingBlocks/Castor.kt @@ -0,0 +1,41 @@ +package io.iohk.atala.prism.domain.buildingBlocks + +import io.iohk.atala.prism.domain.models.DID +import io.iohk.atala.prism.domain.models.DIDDocument +import io.iohk.atala.prism.domain.models.KeyPair +import io.iohk.atala.prism.domain.models.PublicKey + +interface Castor { + + @Throws() + fun parseDID(did: String): DID + + @Throws() + fun createPrismDID( + masterPublicKey: PublicKey, + services: Array? = null + ): DID + + @Throws() + fun createPeerDID( + keyAgreementKeyPair: KeyPair, + authenticationKeyPair: KeyPair, + services: Array + ): DID + + @Throws() + suspend fun resolveDID(did: DID): DIDDocument + + @Throws() + suspend fun verifySignature( + did: DID, + challenge: ByteArray, + signature: ByteArray + ): Boolean + + @Throws() + fun getEcnumbasis( + did: DID, + keyPair: KeyPair + ): String +} diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/buildingBlocks/Mercury.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/buildingBlocks/Mercury.kt new file mode 100644 index 000000000..f34b6f8ab --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/buildingBlocks/Mercury.kt @@ -0,0 +1,18 @@ +package io.iohk.atala.prism.domain.buildingBlocks + +import io.iohk.atala.prism.domain.models.Message + +interface Mercury { + + @Throws() + suspend fun packMessage(message: Message): String + + @Throws() + suspend fun unpackMessage(message: String): Message + + @Throws() + suspend fun sendMessage(message: Message): ByteArray? + + @Throws() + suspend fun sendMessageParseMessage(message: Message): Message? +} diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/buildingBlocks/Pluto.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/buildingBlocks/Pluto.kt new file mode 100644 index 000000000..491e47e4c --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/buildingBlocks/Pluto.kt @@ -0,0 +1,76 @@ +package io.iohk.atala.prism.domain.buildingBlocks + +import io.iohk.atala.prism.domain.models.DID +import io.iohk.atala.prism.domain.models.DIDPair +import io.iohk.atala.prism.domain.models.MediatorDID +import io.iohk.atala.prism.domain.models.Message +import io.iohk.atala.prism.domain.models.PeerDID +import io.iohk.atala.prism.domain.models.PrismDIDInfo +import io.iohk.atala.prism.domain.models.PrivateKey +import io.iohk.atala.prism.domain.models.VerifiableCredential +import kotlinx.coroutines.flow.Flow + +interface Pluto { + + fun storePrismDID( + did: DID, + keyPairIndex: Int, + alias: String? + ) + + fun storePeerDID(did: DID, privateKeys: Array) + + fun storeDIDPair(holder: DID, other: DID, name: String) + + fun storeMessage(message: Message, direction: Message.Direction) + + fun storeMessages(messages: Map) + + fun storeMediator(peer: DID, routingDID: DID, mediatorDID: DID) + + fun storeCredential(credential: VerifiableCredential) + + fun getAllPrismDIDs(): Flow> + + fun getPrismDIDInfo(did: DID): Flow + + fun getPrismDIDInfo(alias: String): Flow> + + fun getPrismDIDKeyPairIndex(did: DID): Flow + + fun getPrismLastKeyPairIndex(): Flow + + fun getAllPeerDIDs(): Flow> + + fun getPeerDIDInfo(did: DID): Flow + + fun getPeerDIDPrivateKeys(did: DID): Flow?> + + fun getAllDidPairs(): Flow> + + fun getPair(did: DID): Flow?> + + fun getPair(name: String): Flow + + fun getAllMessages(): Flow> + + fun getAllMessages(did: DID): Flow> + + fun getAllMessagesSent(): Flow> + + fun getAllMessagesReceived(): Flow> + + fun getAllMessagesSentTo(did: DID): Flow> + + fun getAllMessagesReceivedFrom(did: DID): Flow> + + fun getAllMessagesOfType(type: String, relatedWithDID: DID?): Flow> + + fun getAllMessages(from: DID, to: DID): Flow> + + fun getMessage(id: String): Flow + + fun getAllMediators(): Flow> + + fun getAllCredentials(): Flow> +} diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/buildingBlocks/Pollux.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/buildingBlocks/Pollux.kt new file mode 100644 index 000000000..68b4a10f3 --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/buildingBlocks/Pollux.kt @@ -0,0 +1,9 @@ +package io.iohk.atala.prism.domain.buildingBlocks + +import io.iohk.atala.prism.domain.models.VerifiableCredential + +interface Pollux { + + @Throws + fun parseVerifiableCredential(jsonString: String): VerifiableCredential +} diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/DID.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/DID.kt new file mode 100644 index 000000000..a5e5c58b1 --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/DID.kt @@ -0,0 +1,32 @@ +package io.iohk.atala.prism.domain.models +data class DID( + val schema: String, + val method: String, + val methodId: String +) { + + constructor( + string: String + ) : this(getSchemaFromString(string), getMethodFromString(string), getMethodIdFromString(string)) + + override fun toString(): String { + return "$schema:$method:$methodId" + } + + companion object { + fun getSchemaFromString(string: String): String { + val split = string.split(":") + return split[0] + } + + fun getMethodFromString(string: String): String { + val split = string.split(":") + return split[1] + } + + fun getMethodIdFromString(string: String): String { + val split = string.split(":") + return split[2] + } + } +} diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/DIDDocument.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/DIDDocument.kt new file mode 100644 index 000000000..7b5acb8ac --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/DIDDocument.kt @@ -0,0 +1,266 @@ +package io.iohk.atala.prism.domain.models + +interface DIDDocumentCoreProperty + +data class DIDDocument( + val id: DID, + val coreProperties: Array +) { + + data class VerificationMethod( + val id: DIDUrl, + val controller: DID, + val type: String, + val publicKeyJwk: Map? = null, + val publicKeyMultibase: String? = null + ) + + data class Service( + val id: String, + val type: Array, + val serviceEndpoint: ServiceEndpoint + ) : DIDDocumentCoreProperty { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as Service + + if (id != other.id) return false + if (!type.contentEquals(other.type)) return false + if (serviceEndpoint != other.serviceEndpoint) return false + + return true + } + + override fun hashCode(): Int { + var result = id.hashCode() + result = 31 * result + (type?.contentHashCode() ?: 0) + result = 31 * result + serviceEndpoint.hashCode() + return result + } + } + + data class ServiceEndpoint( + val uri: String, + val accept: Array? = arrayOf(), + val routingKeys: Array? = arrayOf() + ) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as ServiceEndpoint + + if (uri != other.uri) return false + if (accept != null) { + if (other.accept == null) return false + if (!accept.contentEquals(other.accept)) return false + } else if (other.accept != null) return false + if (routingKeys != null) { + if (other.routingKeys == null) return false + if (!routingKeys.contentEquals(other.routingKeys)) return false + } else if (other.routingKeys != null) return false + + return true + } + + override fun hashCode(): Int { + var result = uri.hashCode() + result = 31 * result + (accept?.contentHashCode() ?: 0) + result = 31 * result + (routingKeys?.contentHashCode() ?: 0) + return result + } + } + + data class AlsoKnownAs( + val values: Array + ) : DIDDocumentCoreProperty { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as AlsoKnownAs + + if (!values.contentEquals(other.values)) return false + + return true + } + + override fun hashCode(): Int { + return values.contentHashCode() + } + } + + data class Controller( + val values: Array + ) : DIDDocumentCoreProperty { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as Controller + + if (!values.contentEquals(other.values)) return false + + return true + } + + override fun hashCode(): Int { + return values.contentHashCode() + } + } + + data class VerificationMethods( + val values: Array + ) : DIDDocumentCoreProperty { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as VerificationMethods + + if (!values.contentEquals(other.values)) return false + + return true + } + + override fun hashCode(): Int { + return values.contentHashCode() + } + } + + data class Services( + val values: Array + ) : DIDDocumentCoreProperty { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as Services + + if (!values.contentEquals(other.values)) return false + + return true + } + + override fun hashCode(): Int { + return values.contentHashCode() + } + } + + data class Authentication( + val urls: Array, + val verificationMethods: Array + ) : DIDDocumentCoreProperty { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as Authentication + + if (!urls.contentEquals(other.urls)) return false + if (!verificationMethods.contentEquals(other.verificationMethods)) return false + + return true + } + + override fun hashCode(): Int { + var result = urls.contentHashCode() + result = 31 * result + verificationMethods.contentHashCode() + return result + } + } + + data class AssertionMethod( + val urls: Array, + val verificationMethods: Array + ) : DIDDocumentCoreProperty { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as AssertionMethod + + if (!urls.contentEquals(other.urls)) return false + if (!verificationMethods.contentEquals(other.verificationMethods)) return false + + return true + } + + override fun hashCode(): Int { + var result = urls.contentHashCode() + result = 31 * result + verificationMethods.contentHashCode() + return result + } + } + + data class KeyAgreement( + val urls: Array, + val verificationMethods: Array + ) : DIDDocumentCoreProperty { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as KeyAgreement + + if (!urls.contentEquals(other.urls)) return false + if (!verificationMethods.contentEquals(other.verificationMethods)) return false + + return true + } + + override fun hashCode(): Int { + var result = urls.contentHashCode() + result = 31 * result + verificationMethods.contentHashCode() + return result + } + } + + data class CapabilityInvocation( + val urls: Array, + val verificationMethods: Array + ) : DIDDocumentCoreProperty { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as CapabilityInvocation + + if (!urls.contentEquals(other.urls)) return false + if (!verificationMethods.contentEquals(other.verificationMethods)) return false + + return true + } + + override fun hashCode(): Int { + var result = urls.contentHashCode() + result = 31 * result + verificationMethods.contentHashCode() + return result + } + } + + data class CapabilityDelegation( + val urls: Array, + val verificationMethods: Array + ) : DIDDocumentCoreProperty { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as CapabilityDelegation + + if (!urls.contentEquals(other.urls)) return false + if (!verificationMethods.contentEquals(other.verificationMethods)) return false + + return true + } + + override fun hashCode(): Int { + var result = urls.contentHashCode() + result = 31 * result + verificationMethods.contentHashCode() + return result + } + } +} diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/DIDPair.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/DIDPair.kt new file mode 100644 index 000000000..9c42cc4f3 --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/DIDPair.kt @@ -0,0 +1,7 @@ +package io.iohk.atala.prism.domain.models + +data class DIDPair( + val holder: DID, + val other: DID, + val name: String? +) diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/DIDResolverDomain.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/DIDResolverDomain.kt new file mode 100644 index 000000000..d7ed80608 --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/DIDResolverDomain.kt @@ -0,0 +1,7 @@ +package io.iohk.atala.prism.domain.models + +interface DIDResolverDomain { + val method: String + + fun resolve(did: DID): DIDDocument +} diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/DIDUrl.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/DIDUrl.kt new file mode 100644 index 000000000..09f543ff4 --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/DIDUrl.kt @@ -0,0 +1,50 @@ +package io.iohk.atala.prism.domain.models + +data class DIDUrl( + val did: DID, + val path: Array? = arrayOf(), + val parameters: Map? = mapOf(), + val fragment: String? = null +) { + + fun string(): String { + return "${did}fragmentString" + } + + fun pathString(): String { + return "/${path?.joinToString("/")}" + } + + fun queryString(): String { + return "?${parameters?.map { "${it.key}=${it.value}" }?.joinToString("&")}" + } + + fun fragmentString(): String { + return "#$fragment" + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as DIDUrl + + if (did != other.did) return false + if (path != null) { + if (other.path == null) return false + if (!path.contentEquals(other.path)) return false + } else if (other.path != null) return false + if (parameters != other.parameters) return false + if (fragment != other.fragment) return false + + return true + } + + override fun hashCode(): Int { + var result = did.hashCode() + result = 31 * result + (path?.contentHashCode() ?: 0) + result = 31 * result + (parameters?.hashCode() ?: 0) + result = 31 * result + (fragment?.hashCode() ?: 0) + return result + } +} diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/Errors.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/Errors.kt new file mode 100644 index 000000000..87a8355a3 --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/Errors.kt @@ -0,0 +1,49 @@ +package io.iohk.atala.prism.domain.models + +open class CommonError : Throwable() { + class SomethingWentWrongError : CommonError() +} + +open class ApolloError : Throwable() { + class InvalidMnemonicWord : ApolloError() + class CouldNotParseMessageString : ApolloError() +} + +open class CastorError : Throwable() { + class InvalidLongFormDID : CastorError() + class MethodIdIsDoesNotSatisfyRegex : CastorError() + class InvalidPublicKeyEncoding : CastorError() + class InvalidDIDString : CastorError() + class InitialStateOfDIDChanged : CastorError() + class NotPossibleToResolveDID : CastorError() + class InvalidJWKKeysError : CastorError() + class InvalidKeyError : CastorError() + class InvalidPeerDIDError : CastorError() +} + +open class MercuryError : Throwable() { + class InvalidURLError : MercuryError() + class NoDIDReceiverSetError : MercuryError() + class NoValidServiceFoundError : MercuryError() + class FromFieldNotSetError : MercuryError() + class UnknownAttachmentDataError : MercuryError() + class MessageAttachmentWithoutIDError : MercuryError() + class MessageInvalidBodyDataError : MercuryError() + class UnknownPackingMessageError : MercuryError() + class CouldNotResolveDIDError : MercuryError() + class DidCommError(msg: String) : MercuryError() + class UrlSessionError(statusCode: Int, error: Error?, msg: String?) : MercuryError() +} + +open class PlutoError : Throwable() { + class InvalidHolderDIDNotPersistedError : PlutoError() + class MessageMissingFromOrToDIDError : PlutoError() + class DidPairIsNotPersistedError : PlutoError() + class HolderDIDAlreadyPairingError : PlutoError() + class UnknownCredentialTypeError : PlutoError() + class InvalidCredentialJsonError : PlutoError() +} + +open class PolluxError : Throwable() { + class InvalidCredentialError : PolluxError() +} diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/JWTVerifiableCredential.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/JWTVerifiableCredential.kt new file mode 100644 index 000000000..9bcaf2552 --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/JWTVerifiableCredential.kt @@ -0,0 +1,38 @@ +package io.iohk.atala.prism.domain.models + +data class JWTVerifiableCredential( + val context: Set? = setOf(), + val type: Set? = setOf(), + val credentialSchema: VerifiableCredentialTypeContainer? = null, + val credentialSubject: String, + val credentialStatus: VerifiableCredentialTypeContainer? = null, + val refreshService: VerifiableCredentialTypeContainer? = null, + val evidence: VerifiableCredentialTypeContainer? = null, + val termsOfUse: VerifiableCredentialTypeContainer? = null +) + +data class JWTCredentialPayload( + val iss: DID, + val sub: String? = null, + val verifiableCredential: JWTVerifiableCredential, + val nbf: String, // Date type + val exp: String? = null, // Date type + val jti: String, + override val credentialType: CredentialType, + override val id: String, + override val context: Set, + override val type: Set, + override val issuer: DID, + override val issuanceDate: String, + override val expirationDate: String?, + override val credentialSchema: VerifiableCredentialTypeContainer?, + override val credentialSubject: String, + override val credentialStatus: VerifiableCredentialTypeContainer?, + override val refreshService: VerifiableCredentialTypeContainer?, + override val evidence: VerifiableCredentialTypeContainer?, + override val termsOfUse: VerifiableCredentialTypeContainer?, + override val validFrom: VerifiableCredentialTypeContainer?, + override val validUntil: VerifiableCredentialTypeContainer?, + override val proof: String?, + override val aud: Set +) : VerifiableCredential diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/KeyPair.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/KeyPair.kt new file mode 100644 index 000000000..b52ad87d3 --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/KeyPair.kt @@ -0,0 +1,12 @@ +package io.iohk.atala.prism.domain.models +data class KeyPair( + val curve: KeyCurve? = KeyCurve.SECP256K1, + val privateKey: PrivateKey, + val publicKey: PublicKey +) + +enum class KeyCurve(val value: String) { + X25519("X25519"), + ED25519("Ed25519"), + SECP256K1("secp256k1") +} diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/MediatorDID.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/MediatorDID.kt new file mode 100644 index 000000000..e3dae8589 --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/MediatorDID.kt @@ -0,0 +1,7 @@ +package io.iohk.atala.prism.domain.models + +data class MediatorDID( + val did: DID, + val routingDID: DID, + val mediatorDID: DID +) diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/Message.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/Message.kt new file mode 100644 index 000000000..97b2c10a5 --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/Message.kt @@ -0,0 +1,62 @@ +package io.iohk.atala.prism.domain.models +data class Message( + val id: String, + val piuri: String, + val from: DID?, + val to: DID?, + val fromPrior: String?, + val body: String, // TODO: Change to Data + val extraHeaders: Array, + val createdTime: String, // TODO: Change to Date + val expiresTimePlus: String, // TODO: Change to Date + val attachments: Array, // TODO: Change to AttachmentDescriptor + val thid: String? = null, + val pthid: String? = null, + val ack: Array, + val direction: Direction +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as Message + + if (id != other.id) return false + if (piuri != other.piuri) return false + if (from != other.from) return false + if (to != other.to) return false + if (fromPrior != other.fromPrior) return false + if (body != other.body) return false + if (!extraHeaders.contentEquals(other.extraHeaders)) return false + if (createdTime != other.createdTime) return false + if (expiresTimePlus != other.expiresTimePlus) return false + if (!attachments.contentEquals(other.attachments)) return false + if (thid != other.thid) return false + if (pthid != other.pthid) return false + if (!ack.contentEquals(other.ack)) return false + + return true + } + + override fun hashCode(): Int { + var result = id.hashCode() + result = 31 * result + piuri.hashCode() + result = 31 * result + (from?.hashCode() ?: 0) + result = 31 * result + (to?.hashCode() ?: 0) + result = 31 * result + (fromPrior?.hashCode() ?: 0) + result = 31 * result + body.hashCode() + result = 31 * result + extraHeaders.contentHashCode() + result = 31 * result + createdTime.hashCode() + result = 31 * result + expiresTimePlus.hashCode() + result = 31 * result + attachments.contentHashCode() + result = 31 * result + (thid?.hashCode() ?: 0) + result = 31 * result + (pthid?.hashCode() ?: 0) + result = 31 * result + ack.contentHashCode() + return result + } + + enum class Direction(val value: String) { + SENT("Sent"), + RECEIVED("Received") + } +} diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/MessageAttachment.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/MessageAttachment.kt new file mode 100644 index 000000000..13fe369c4 --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/MessageAttachment.kt @@ -0,0 +1,89 @@ +package io.iohk.atala.prism.domain.models + +interface AttachmentData +data class AttachmentHeader( + val children: String +) : AttachmentData + +data class AttachmentJws( + val header: AttachmentHeader, + val protected: String, + val signature: String +) : AttachmentData + +data class AttachmentJwsData( + val base64: String, + val jws: AttachmentJws +) : AttachmentData + +data class AttachmentBase64( + val base64: String +) : AttachmentData + +data class AttachmentLinkData( + val links: Array, + val hash: String +) : AttachmentData { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as AttachmentLinkData + + if (!links.contentEquals(other.links)) return false + if (hash != other.hash) return false + + return true + } + + override fun hashCode(): Int { + var result = links.contentHashCode() + result = 31 * result + hash.hashCode() + return result + } +} + +data class AttachmentJsonData( + val data: String +) : AttachmentData + +data class AttachmentDescriptor( + val id: String, + val mediaType: String? = null, + val data: AttachmentData, + val filename: Array, + val format: String? = null, + val lastModTime: String? = null, // Date format + val byteCount: Int? = null, + val description: String? = null +) : AttachmentData { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as AttachmentDescriptor + + if (id != other.id) return false + if (mediaType != other.mediaType) return false + if (data != other.data) return false + if (!filename.contentEquals(other.filename)) return false + if (format != other.format) return false + if (lastModTime != other.lastModTime) return false + if (byteCount != other.byteCount) return false + if (description != other.description) return false + + return true + } + + override fun hashCode(): Int { + var result = id.hashCode() + result = 31 * result + (mediaType?.hashCode() ?: 0) + result = 31 * result + data.hashCode() + result = 31 * result + filename.contentHashCode() + result = 31 * result + (format?.hashCode() ?: 0) + result = 31 * result + (lastModTime?.hashCode() ?: 0) + result = 31 * result + (byteCount ?: 0) + result = 31 * result + (description?.hashCode() ?: 0) + return result + } +} diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/PeerDID.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/PeerDID.kt new file mode 100644 index 000000000..dd3a6edef --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/PeerDID.kt @@ -0,0 +1,24 @@ +package io.iohk.atala.prism.domain.models + +data class PeerDID( + val did: DID, + val privateKeys: Array +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as PeerDID + + if (did != other.did) return false + if (!privateKeys.contentEquals(other.privateKeys)) return false + + return true + } + + override fun hashCode(): Int { + var result = did.hashCode() + result = 31 * result + privateKeys.contentHashCode() + return result + } +} diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/PrismDIDInfo.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/PrismDIDInfo.kt new file mode 100644 index 000000000..1c8a1e8e1 --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/PrismDIDInfo.kt @@ -0,0 +1,7 @@ +package io.iohk.atala.prism.domain.models + +data class PrismDIDInfo( + val did: DID, + val keyPairIndex: Int, + val alias: String? = null +) diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/PrivateKey.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/PrivateKey.kt new file mode 100644 index 000000000..0bc35132b --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/PrivateKey.kt @@ -0,0 +1,24 @@ +package io.iohk.atala.prism.domain.models + +data class PrivateKey( + val curve: KeyCurve, + val value: ByteArray +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as PrivateKey + + if (curve != other.curve) return false + if (!value.contentEquals(other.value)) return false + + return true + } + + override fun hashCode(): Int { + var result = curve.hashCode() + result = 31 * result + value.contentHashCode() + return result + } +} diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/PublicKey.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/PublicKey.kt new file mode 100644 index 000000000..fd9d96200 --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/PublicKey.kt @@ -0,0 +1,11 @@ +package io.iohk.atala.prism.domain.models + +data class PublicKey( + val curve: String, + val value: String +) + +data class CompressedPublicKey( + val uncompressed: PublicKey, + val value: String +) diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/Secret.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/Secret.kt new file mode 100644 index 000000000..b471a218b --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/Secret.kt @@ -0,0 +1,15 @@ +package io.iohk.atala.prism.domain.models + +enum class SecretMaterial(val value: String) { + JWK("JWK") +} + +enum class SecretType(val value: String) { + JsonWebKey2020("JsonWebKey2020") +} + +data class Secret( + val id: String, + val type: SecretType, + val secretMaterial: SecretMaterial +) diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/SecretResolver.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/SecretResolver.kt new file mode 100644 index 000000000..44e42a76b --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/SecretResolver.kt @@ -0,0 +1,5 @@ +package io.iohk.atala.prism.domain.models + +interface SecretResolver { + fun resolve(secretIds: Array) +} diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/Seed.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/Seed.kt new file mode 100644 index 000000000..fa9763241 --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/Seed.kt @@ -0,0 +1,5 @@ +package io.iohk.atala.prism.domain.models + +data class Seed( + val value: String +) diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/Session.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/Session.kt new file mode 100644 index 000000000..b7b378bf0 --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/Session.kt @@ -0,0 +1,9 @@ +package io.iohk.atala.prism.domain.models + +import com.benasher44.uuid.Uuid +import com.benasher44.uuid.uuid4 + +data class Session( + val uuid: Uuid = uuid4(), + val seed: Seed +) diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/Signature.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/Signature.kt new file mode 100644 index 000000000..68a0b5d77 --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/Signature.kt @@ -0,0 +1,5 @@ +package io.iohk.atala.prism.domain.models + +data class Signature( + val value: String, +) diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/VerifiableCredential.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/VerifiableCredential.kt new file mode 100644 index 000000000..204dbf6fc --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/VerifiableCredential.kt @@ -0,0 +1,32 @@ +package io.iohk.atala.prism.domain.models + +data class VerifiableCredentialTypeContainer( + val id: String, + val type: String +) + +enum class CredentialType(val type: String) { + JWT("jwt"), + W3C("w3c"), + Unknown("Unknown") +} + +interface VerifiableCredential { + val credentialType: CredentialType + val id: String + val context: Set + val type: Set + val issuer: DID + val issuanceDate: String // Date + val expirationDate: String? // Date + val credentialSchema: VerifiableCredentialTypeContainer? + val credentialSubject: String + val credentialStatus: VerifiableCredentialTypeContainer? + val refreshService: VerifiableCredentialTypeContainer? + val evidence: VerifiableCredentialTypeContainer? + val termsOfUse: VerifiableCredentialTypeContainer? + val validFrom: VerifiableCredentialTypeContainer? + val validUntil: VerifiableCredentialTypeContainer? + val proof: String? + val aud: Set +} diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/W3CVerifiableCredential.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/W3CVerifiableCredential.kt new file mode 100644 index 000000000..b33fa0a29 --- /dev/null +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.domain/models/W3CVerifiableCredential.kt @@ -0,0 +1,21 @@ +package io.iohk.atala.prism.domain.models + +data class W3CVerifiableCredential( + override val credentialType: CredentialType = CredentialType.W3C, + override val context: Set, + override val type: Set, + override val id: String, + override val issuer: DID, + override val issuanceDate: String, + override val expirationDate: String? = null, + override val credentialSchema: VerifiableCredentialTypeContainer?, + override val credentialSubject: String, + override val credentialStatus: VerifiableCredentialTypeContainer?, + override val refreshService: VerifiableCredentialTypeContainer?, + override val evidence: VerifiableCredentialTypeContainer?, + override val termsOfUse: VerifiableCredentialTypeContainer?, + override val validFrom: VerifiableCredentialTypeContainer?, + override val validUntil: VerifiableCredentialTypeContainer?, + override val proof: String?, + override val aud: Set, +) : VerifiableCredential diff --git a/mercury/src/androidMain/AndroidManifest.xml b/mercury/src/androidMain/AndroidManifest.xml index 2d72eeae7..d3bf5653a 100644 --- a/mercury/src/androidMain/AndroidManifest.xml +++ b/mercury/src/androidMain/AndroidManifest.xml @@ -1,2 +1,2 @@ - \ No newline at end of file + diff --git a/pollux/src/androidMain/AndroidManifest.xml b/pollux/src/androidMain/AndroidManifest.xml index 32cc422a6..a39cb38d1 100644 --- a/pollux/src/androidMain/AndroidManifest.xml +++ b/pollux/src/androidMain/AndroidManifest.xml @@ -1,2 +1,2 @@ - \ No newline at end of file + diff --git a/prism-agent/src/androidMain/AndroidManifest.xml b/prism-agent/src/androidMain/AndroidManifest.xml index bd3f170d2..848ee47a9 100644 --- a/prism-agent/src/androidMain/AndroidManifest.xml +++ b/prism-agent/src/androidMain/AndroidManifest.xml @@ -1,2 +1,2 @@ - \ No newline at end of file + diff --git a/wallet-sdk/src/androidMain/AndroidManifest.xml b/wallet-sdk/src/androidMain/AndroidManifest.xml index 8bbcf461c..1241db6ea 100644 --- a/wallet-sdk/src/androidMain/AndroidManifest.xml +++ b/wallet-sdk/src/androidMain/AndroidManifest.xml @@ -1,2 +1,2 @@ - \ No newline at end of file +