diff --git a/castor/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/castor/CastorImpl.kt b/castor/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.castor/CastorImpl.kt similarity index 100% rename from castor/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/castor/CastorImpl.kt rename to castor/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.castor/CastorImpl.kt diff --git a/castor/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/castor/resolvers/LongFormPrismDIDResolver.kt b/castor/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.castor/resolvers/LongFormPrismDIDResolver.kt similarity index 94% rename from castor/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/castor/resolvers/LongFormPrismDIDResolver.kt rename to castor/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.castor/resolvers/LongFormPrismDIDResolver.kt index 844eb3303..eec889b03 100644 --- a/castor/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/castor/resolvers/LongFormPrismDIDResolver.kt +++ b/castor/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.castor/resolvers/LongFormPrismDIDResolver.kt @@ -13,7 +13,7 @@ actual class LongFormPrismDIDResolver( override suspend fun resolve(didString: String): DIDDocument { return CastorShared.resolveLongFormPrismDID( apollo = apollo, - didString = didString + didString = didString, ) } } diff --git a/castor/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/castor/resolvers/PeerDIDResolver.kt b/castor/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.castor/resolvers/PeerDIDResolver.kt similarity index 100% rename from castor/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/castor/resolvers/PeerDIDResolver.kt rename to castor/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.castor/resolvers/PeerDIDResolver.kt diff --git a/castor/src/allButJSTest/kotlin/io/iohk/atala/prism/walletsdk/castor/DIDResolverTest.kt b/castor/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.castor/DIDResolverTest.kt similarity index 100% rename from castor/src/allButJSTest/kotlin/io/iohk/atala/prism/walletsdk/castor/DIDResolverTest.kt rename to castor/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.castor/DIDResolverTest.kt diff --git a/castor/src/allButJSTest/kotlin/io/iohk/atala/prism/walletsdk/castor/DIDSignatureVerificationTest.kt b/castor/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.castor/DIDSignatureVerificationTest.kt similarity index 100% rename from castor/src/allButJSTest/kotlin/io/iohk/atala/prism/walletsdk/castor/DIDSignatureVerificationTest.kt rename to castor/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.castor/DIDSignatureVerificationTest.kt diff --git a/castor/src/allButJSTest/kotlin/io/iohk/atala/prism/walletsdk/castor/PrismDIDCreateTests.kt b/castor/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.castor/PrismDIDCreateTests.kt similarity index 100% rename from castor/src/allButJSTest/kotlin/io/iohk/atala/prism/walletsdk/castor/PrismDIDCreateTests.kt rename to castor/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.castor/PrismDIDCreateTests.kt diff --git a/castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/CastorImpl.kt b/castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/CastorImpl.kt similarity index 100% rename from castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/CastorImpl.kt rename to castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/CastorImpl.kt diff --git a/castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/DIDParser.kt b/castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/DIDParser.kt similarity index 100% rename from castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/DIDParser.kt rename to castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/DIDParser.kt diff --git a/castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/DIDParserListener.kt b/castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/DIDParserListener.kt similarity index 100% rename from castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/DIDParserListener.kt rename to castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/DIDParserListener.kt diff --git a/castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/DIDUrlParser.kt b/castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/DIDUrlParser.kt similarity index 97% rename from castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/DIDUrlParser.kt rename to castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/DIDUrlParser.kt index 9d6776f91..d6e467398 100644 --- a/castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/DIDUrlParser.kt +++ b/castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/DIDUrlParser.kt @@ -32,7 +32,7 @@ object DIDUrlParser { did, listener.path ?: emptyArray(), listener.query, - listener.fragment + listener.fragment, ) } } diff --git a/castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/DIDUrlParserListener.kt b/castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/DIDUrlParserListener.kt similarity index 100% rename from castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/DIDUrlParserListener.kt rename to castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/DIDUrlParserListener.kt diff --git a/castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/ErrorStrategy.kt b/castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/ErrorStrategy.kt similarity index 100% rename from castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/ErrorStrategy.kt rename to castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/ErrorStrategy.kt diff --git a/castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/InvalidDIDStringError.kt b/castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/InvalidDIDStringError.kt similarity index 100% rename from castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/InvalidDIDStringError.kt rename to castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/InvalidDIDStringError.kt diff --git a/castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/PrismDID/LongFormPrismDID.kt b/castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/PrismDID/LongFormPrismDID.kt similarity index 77% rename from castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/PrismDID/LongFormPrismDID.kt rename to castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/PrismDID/LongFormPrismDID.kt index bcf16b805..6a2cb9e9c 100644 --- a/castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/PrismDID/LongFormPrismDID.kt +++ b/castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/PrismDID/LongFormPrismDID.kt @@ -1,6 +1,5 @@ -package io.iohk.atala.prism.walletsdk.castor.io.iohk.atala.prism.walletsdk.castor.did.prismdid +package io.iohk.atala.prism.walletsdk.castor.did.prismdid -import io.iohk.atala.prism.walletsdk.castor.did.prismdid.PrismDIDMethodId import io.iohk.atala.prism.walletsdk.domain.models.CastorError import io.iohk.atala.prism.walletsdk.domain.models.DID @@ -12,7 +11,7 @@ LongFormPrismDID(val did: DID) { init { val methodId = PrismDIDMethodId( - did.methodId + did.methodId, ) if (methodId.sections.size !== 2) { diff --git a/castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/PrismDID/PrismDIDMethodId.kt b/castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/PrismDID/PrismDIDMethodId.kt similarity index 100% rename from castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/PrismDID/PrismDIDMethodId.kt rename to castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/PrismDID/PrismDIDMethodId.kt diff --git a/castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/PrismDID/PrismDIDPublicKey.kt b/castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/PrismDID/PrismDIDPublicKey.kt similarity index 97% rename from castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/PrismDID/PrismDIDPublicKey.kt rename to castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/PrismDID/PrismDIDPublicKey.kt index 88362837a..ce6cd4e60 100644 --- a/castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/did/PrismDID/PrismDIDPublicKey.kt +++ b/castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/did/PrismDID/PrismDIDPublicKey.kt @@ -17,7 +17,7 @@ class PrismDIDPublicKey { CAPABILITY_DELEGATION_KEY("capabilityDelegationKey"), CAPABILITY_INVOCATION_KEY("capabilityInvocationKey"), KEY_AGREEMENT_KEY("keyAgreementKey"), - UNKNOWN_KEY("unknownKey") + UNKNOWN_KEY("unknownKey"), } private val apollo: Apollo @@ -53,8 +53,8 @@ class PrismDIDPublicKey { id = id, usage = usage.toProto(), keyData = io.iohk.atala.prism.protos.PublicKey.KeyData.CompressedEcKeyData( - compressed.toProto() - ) + compressed.toProto(), + ), ) } } @@ -76,7 +76,7 @@ fun KeyUsage.fromProto(): PrismDIDPublicKey.Usage { fun CompressedPublicKey.toProto(): CompressedECKeyData { return CompressedECKeyData( curve = uncompressed.curve.curve.value, - data = ByteArr(value) + data = ByteArr(value), ) } diff --git a/castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/resolvers/LongFormPrismDIDResolver.kt b/castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/resolvers/LongFormPrismDIDResolver.kt similarity index 100% rename from castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/resolvers/LongFormPrismDIDResolver.kt rename to castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/resolvers/LongFormPrismDIDResolver.kt diff --git a/castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/resolvers/PeerDIDResolver.kt b/castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/resolvers/PeerDIDResolver.kt similarity index 100% rename from castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/resolvers/PeerDIDResolver.kt rename to castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/resolvers/PeerDIDResolver.kt diff --git a/castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/shared/CastorShared.kt b/castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/shared/CastorShared.kt similarity index 99% rename from castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/shared/CastorShared.kt rename to castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/shared/CastorShared.kt index 26773d566..6a18181b5 100644 --- a/castor/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/castor/shared/CastorShared.kt +++ b/castor/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.castor/shared/CastorShared.kt @@ -21,10 +21,10 @@ import io.iohk.atala.prism.protos.CreateDIDOperation import io.iohk.atala.prism.protos.Service import io.iohk.atala.prism.walletsdk.castor.did.DIDParser import io.iohk.atala.prism.walletsdk.castor.did.DIDUrlParser +import io.iohk.atala.prism.walletsdk.castor.did.prismdid.LongFormPrismDID import io.iohk.atala.prism.walletsdk.castor.did.prismdid.PrismDIDMethodId import io.iohk.atala.prism.walletsdk.castor.did.prismdid.PrismDIDPublicKey import io.iohk.atala.prism.walletsdk.castor.did.prismdid.defaultId -import io.iohk.atala.prism.walletsdk.castor.io.iohk.atala.prism.walletsdk.castor.did.prismdid.LongFormPrismDID import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Apollo import io.iohk.atala.prism.walletsdk.domain.models.CastorError import io.iohk.atala.prism.walletsdk.domain.models.Curve diff --git a/castor/src/jsMain/kotlin/io/iohk/atala/prism/walletsdk/castor/CastorImpl.kt b/castor/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.castor/CastorImpl.kt similarity index 100% rename from castor/src/jsMain/kotlin/io/iohk/atala/prism/walletsdk/castor/CastorImpl.kt rename to castor/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.castor/CastorImpl.kt diff --git a/castor/src/jsMain/kotlin/io/iohk/atala/prism/walletsdk/castor/resolvers/LongFormPrismDIDResolver.kt b/castor/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.castor/resolvers/LongFormPrismDIDResolver.kt similarity index 95% rename from castor/src/jsMain/kotlin/io/iohk/atala/prism/walletsdk/castor/resolvers/LongFormPrismDIDResolver.kt rename to castor/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.castor/resolvers/LongFormPrismDIDResolver.kt index 92e86d6dd..2e27ccb92 100644 --- a/castor/src/jsMain/kotlin/io/iohk/atala/prism/walletsdk/castor/resolvers/LongFormPrismDIDResolver.kt +++ b/castor/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.castor/resolvers/LongFormPrismDIDResolver.kt @@ -18,7 +18,7 @@ actual class LongFormPrismDIDResolver( return GlobalScope.promise { CastorShared.resolveLongFormPrismDID( apollo = apollo, - didString = didString + didString = didString, ) } } diff --git a/castor/src/jsMain/kotlin/io/iohk/atala/prism/walletsdk/castor/resolvers/PeerDIDResolver.kt b/castor/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.castor/resolvers/PeerDIDResolver.kt similarity index 100% rename from castor/src/jsMain/kotlin/io/iohk/atala/prism/walletsdk/castor/resolvers/PeerDIDResolver.kt rename to castor/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.castor/resolvers/PeerDIDResolver.kt diff --git a/domain/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/domain/buildingBlocks/Castor.kt b/domain/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Castor.kt similarity index 86% rename from domain/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/domain/buildingBlocks/Castor.kt rename to domain/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Castor.kt index a4103b8ae..8f0f70c01 100644 --- a/domain/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/domain/buildingBlocks/Castor.kt +++ b/domain/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Castor.kt @@ -9,12 +9,12 @@ actual interface Castor { actual fun parseDID(did: String): DID actual fun createPrismDID( masterPublicKey: PublicKey, - services: Array? + services: Array?, ): DID actual fun createPeerDID( keyPairs: Array, - services: Array + services: Array, ): DID @Throws() // TODO: Add throw classes @@ -24,6 +24,6 @@ actual interface Castor { suspend fun verifySignature( did: DID, challenge: ByteArray, - signature: ByteArray + signature: ByteArray, ): Boolean } diff --git a/domain/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Mercury.kt b/domain/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Mercury.kt new file mode 100644 index 000000000..687c7ce61 --- /dev/null +++ b/domain/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Mercury.kt @@ -0,0 +1,16 @@ +package io.iohk.atala.prism.walletsdk.domain.buildingBlocks + +import io.iohk.atala.prism.walletsdk.domain.models.Message + +actual interface Mercury { + + actual fun packMessage(message: Message): String + + actual fun unpackMessage(message: String): Message + + @Throws() // TODO: Add throw classes + suspend fun sendMessage(message: Message): ByteArray? + + @Throws() // TODO: Add throw classes + suspend fun sendMessageParseMessage(message: Message): Message? +} diff --git a/domain/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/DIDResolver.kt b/domain/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/DIDResolver.kt similarity index 100% rename from domain/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/DIDResolver.kt rename to domain/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/DIDResolver.kt diff --git a/domain/src/androidMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/Platform.kt b/domain/src/androidMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/Platform.kt similarity index 100% rename from domain/src/androidMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/Platform.kt rename to domain/src/androidMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/Platform.kt diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Castor.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Castor.kt index a8084de8e..106b3baab 100644 --- a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Castor.kt +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Castor.kt @@ -11,11 +11,11 @@ expect interface Castor { fun createPrismDID( masterPublicKey: PublicKey, - services: Array? = null + services: Array? = null, ): DID fun createPeerDID( keyPairs: Array, - services: Array + services: Array, ): DID } diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Mercury.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Mercury.kt index 267824f74..795f3d466 100644 --- a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Mercury.kt +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Mercury.kt @@ -2,17 +2,8 @@ package io.iohk.atala.prism.walletsdk.domain.buildingBlocks import io.iohk.atala.prism.walletsdk.domain.models.Message -interface Mercury { +expect interface Mercury { + fun packMessage(message: Message): String - @Throws() // TODO: Add throw classes - suspend fun packMessage(message: Message): String - - @Throws() // TODO: Add throw classes - suspend fun unpackMessage(message: String): Message - - @Throws() // TODO: Add throw classes - suspend fun sendMessage(message: Message): ByteArray? - - @Throws() // TODO: Add throw classes - suspend fun sendMessageParseMessage(message: Message): Message? + fun unpackMessage(message: String): Message } diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Pluto.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Pluto.kt index e1203ecb1..97be9c2ba 100644 --- a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Pluto.kt +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Pluto.kt @@ -2,7 +2,7 @@ package io.iohk.atala.prism.walletsdk.domain.buildingBlocks import io.iohk.atala.prism.walletsdk.domain.models.DID import io.iohk.atala.prism.walletsdk.domain.models.DIDPair -import io.iohk.atala.prism.walletsdk.domain.models.MediatorDID +import io.iohk.atala.prism.walletsdk.domain.models.Mediator import io.iohk.atala.prism.walletsdk.domain.models.Message import io.iohk.atala.prism.walletsdk.domain.models.PeerDID import io.iohk.atala.prism.walletsdk.domain.models.PrismDIDInfo @@ -77,7 +77,7 @@ interface Pluto { fun getMessage(id: String): Message? - fun getAllMediators(): Array + fun getAllMediators(): Array fun getAllCredentials(): Array } diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/DIDPair.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/DIDPair.kt index 26aff8486..a4c5b74c8 100644 --- a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/DIDPair.kt +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/DIDPair.kt @@ -8,5 +8,5 @@ import kotlin.js.JsExport data class DIDPair( val host: DID, val receiver: DID, - val name: String? + val name: String?, ) diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/DIDUrl.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/DIDUrl.kt index eb623ddfa..6f7e33982 100644 --- a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/DIDUrl.kt +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/DIDUrl.kt @@ -4,7 +4,7 @@ data class DIDUrl( val did: DID, val path: Array? = arrayOf(), val parameters: Map? = mapOf(), - val fragment: String? = null + val fragment: String? = null, ) { fun string(): String { diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/Errors.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/Errors.kt index b8fc77408..bb4e47b36 100644 --- a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/Errors.kt +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/Errors.kt @@ -72,6 +72,7 @@ sealed class PrismAgentError(message: String? = null) : Throwable(message) { class invalidRequestPresentationMessageError(message: String? = null) : PrismAgentError(message) class invalidProposePresentationMessageError(message: String? = null) : PrismAgentError(message) class invalidMediationGrantMessageError(message: String? = null) : PrismAgentError(message) + class invalidMessageError(message: String? = null) : PrismAgentError(message) class noMediatorAvailableError(message: String? = null) : PrismAgentError(message) class mediationRequestFailedError(message: String? = null) : PrismAgentError(message) } diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/JWTVerifiableCredential.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/JWTVerifiableCredential.kt index 9e253c19d..7585dc85b 100644 --- a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/JWTVerifiableCredential.kt +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/JWTVerifiableCredential.kt @@ -17,7 +17,7 @@ data class JWTVerifiableCredential( override val validFrom: VerifiableCredentialTypeContainer?, override val validUntil: VerifiableCredentialTypeContainer?, override val proof: String?, - override val aud: Set + override val aud: Set, ) : VerifiableCredential data class JWTCredentialPayload( diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/KeyPair.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/KeyPair.kt index f09ddc5e4..ea6c06c80 100644 --- a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/KeyPair.kt +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/KeyPair.kt @@ -8,7 +8,7 @@ import kotlin.js.JsExport data class KeyPair( val keyCurve: KeyCurve? = KeyCurve(Curve.SECP256K1), val privateKey: PrivateKey, - val publicKey: PublicKey + val publicKey: PublicKey, ) @Serializable @@ -20,7 +20,7 @@ data class KeyCurve(val curve: Curve, val index: Int? = 0) enum class Curve(val value: String) { X25519("X25519"), ED25519("Ed25519"), - SECP256K1("secp256k1"); + SECP256K1("secp256k1"), } @JsExport diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/MediatorDID.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/Mediator.kt similarity index 81% rename from domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/MediatorDID.kt rename to domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/Mediator.kt index cb386ece6..2436a8d1f 100644 --- a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/MediatorDID.kt +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/Mediator.kt @@ -5,9 +5,9 @@ import kotlin.js.JsExport @JsExport @Serializable -data class MediatorDID( +data class Mediator( val id: String, val mediatorDID: DID, val hostDID: DID, - val routingDID: DID + val routingDID: DID, ) diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/Message.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/Message.kt index 848f640c0..3163359ac 100644 --- a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/Message.kt +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/Message.kt @@ -17,11 +17,11 @@ data class Message( val extraHeaders: Array, val createdTime: String, val expiresTimePlus: String, - val attachments: Array, // TODO: Change to AttachmentDescriptor + val attachments: Array, val thid: String? = null, val pthid: String? = null, val ack: Array, - val direction: Direction + val direction: Direction, ) { override fun equals(other: Any?): Boolean { if (this === other) return true @@ -69,7 +69,7 @@ data class Message( enum class Direction(val value: Int) { SENT(0), - RECEIVED(1) + RECEIVED(1), } } diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/MessageAttachment.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/MessageAttachment.kt index 5594ecb5e..5dbaab916 100644 --- a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/MessageAttachment.kt +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/MessageAttachment.kt @@ -1,29 +1,43 @@ package io.iohk.atala.prism.walletsdk.domain.models +import kotlinx.serialization.Serializable +import kotlin.js.JsExport + +@JsExport interface AttachmentData +@Serializable +@JsExport data class AttachmentHeader( - val children: String + val children: String, ) : AttachmentData +@Serializable +@JsExport data class AttachmentJws( val header: AttachmentHeader, val protected: String, - val signature: String + val signature: String, ) : AttachmentData +@Serializable +@JsExport data class AttachmentJwsData( val base64: String, - val jws: AttachmentJws + val jws: AttachmentJws, ) : AttachmentData +@Serializable +@JsExport data class AttachmentBase64( - val base64: String + val base64: String, ) : AttachmentData +@Serializable +@JsExport data class AttachmentLinkData( val links: Array, - val hash: String + val hash: String, ) : AttachmentData { override fun equals(other: Any?): Boolean { if (this === other) return true @@ -44,10 +58,14 @@ data class AttachmentLinkData( } } +@Serializable +@JsExport data class AttachmentJsonData( - val data: String + val data: String, ) : AttachmentData +@Serializable +@JsExport data class AttachmentDescriptor( val id: String, val mediaType: String? = null, @@ -56,7 +74,7 @@ data class AttachmentDescriptor( val format: String? = null, val lastModTime: String? = null, // Date format val byteCount: Int? = null, - val description: String? = null + val description: String? = null, ) : AttachmentData { override fun equals(other: Any?): Boolean { if (this === other) return true diff --git a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/PeerDID.kt b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/PeerDID.kt index bb6798587..68f72cf7e 100644 --- a/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/PeerDID.kt +++ b/domain/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/PeerDID.kt @@ -5,7 +5,7 @@ import kotlin.js.JsExport @JsExport data class PeerDID( val did: DID, - val privateKeys: Array + val privateKeys: Array, ) { override fun equals(other: Any?): Boolean { if (this === other) return true diff --git a/domain/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Castor.kt b/domain/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Castor.kt index 676f4318d..8d1b2197e 100644 --- a/domain/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Castor.kt +++ b/domain/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Castor.kt @@ -12,18 +12,18 @@ actual interface Castor { actual fun parseDID(did: String): DID actual fun createPrismDID( masterPublicKey: PublicKey, - services: Array? + services: Array?, ): DID actual fun createPeerDID( keyPairs: Array, - services: Array + services: Array, ): DID fun resolveDID(did: String): Promise fun verifySignature( did: DID, challenge: ByteArray, - signature: ByteArray + signature: ByteArray, ): Promise } diff --git a/domain/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Mercury.kt b/domain/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Mercury.kt new file mode 100644 index 000000000..3856afdb6 --- /dev/null +++ b/domain/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.domain/buildingBlocks/Mercury.kt @@ -0,0 +1,16 @@ +package io.iohk.atala.prism.walletsdk.domain.buildingBlocks + +import io.iohk.atala.prism.walletsdk.domain.models.Message +import kotlin.js.Promise + +@OptIn(ExperimentalJsExport::class) +@JsExport +actual interface Mercury { + actual fun packMessage(message: Message): String + + actual fun unpackMessage(message: String): Message + + fun sendMessage(message: Message): Promise + + fun sendMessageParseMessage(message: Message): Promise +} diff --git a/domain/src/jvmMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/Platform.kt b/domain/src/jvmMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/Platform.kt similarity index 100% rename from domain/src/jvmMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/Platform.kt rename to domain/src/jvmMain/kotlin/io.iohk.atala.prism.walletsdk.domain/models/Platform.kt diff --git a/pluto/src/androidMain/kotlin/io/iohk/atala/prism/walletsdk/pluto/data/DbConnection.kt b/pluto/src/androidMain/kotlin/io.iohk.atala.prism.walletsdk.pluto/data/DbConnection.kt similarity index 100% rename from pluto/src/androidMain/kotlin/io/iohk/atala/prism/walletsdk/pluto/data/DbConnection.kt rename to pluto/src/androidMain/kotlin/io.iohk.atala.prism.walletsdk.pluto/data/DbConnection.kt diff --git a/pluto/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/pluto/PlutoImpl.kt b/pluto/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.pluto/PlutoImpl.kt similarity index 99% rename from pluto/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/pluto/PlutoImpl.kt rename to pluto/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.pluto/PlutoImpl.kt index e9e6f834a..8cbd8cf8a 100644 --- a/pluto/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/pluto/PlutoImpl.kt +++ b/pluto/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.pluto/PlutoImpl.kt @@ -6,7 +6,7 @@ import io.iohk.atala.prism.walletsdk.domain.models.CredentialType import io.iohk.atala.prism.walletsdk.domain.models.DID import io.iohk.atala.prism.walletsdk.domain.models.DIDPair import io.iohk.atala.prism.walletsdk.domain.models.JWTVerifiableCredential -import io.iohk.atala.prism.walletsdk.domain.models.MediatorDID +import io.iohk.atala.prism.walletsdk.domain.models.Mediator import io.iohk.atala.prism.walletsdk.domain.models.Message import io.iohk.atala.prism.walletsdk.domain.models.PeerDID import io.iohk.atala.prism.walletsdk.domain.models.PlutoError @@ -442,11 +442,11 @@ class PlutoImpl(private val connection: DbConnection) : Pluto { ) } - override fun getAllMediators(): Array { + override fun getAllMediators(): Array { return getInstance().mediatorQueries.fetchAllMediators() .executeAsList() .map { - MediatorDID( + Mediator( it.id, DID(it.MediatorDID), DID(it.HostDID), diff --git a/pluto/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/pluto/data/DbConnection.kt b/pluto/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.pluto/data/DbConnection.kt similarity index 100% rename from pluto/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/pluto/data/DbConnection.kt rename to pluto/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.pluto/data/DbConnection.kt diff --git a/prism-agent/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/ConnectionManager.kt b/prism-agent/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/ConnectionManager.kt new file mode 100644 index 000000000..eb3c9f94b --- /dev/null +++ b/prism-agent/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/ConnectionManager.kt @@ -0,0 +1,69 @@ +package io.iohk.atala.prism.walletsdk.prismagent + +import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Castor +import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Mercury +import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Pluto +import io.iohk.atala.prism.walletsdk.domain.models.DID +import io.iohk.atala.prism.walletsdk.domain.models.Message +import io.iohk.atala.prism.walletsdk.domain.models.PrismAgentError +import io.iohk.atala.prism.walletsdk.prismagent.mediation.MediationHandler +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.map + +actual class ConnectionManager { + private val mercury: Mercury + private val castor: Castor + private val pluto: Pluto + internal val mediationHandler: MediationHandler + + actual constructor( + mercury: Mercury, + castor: Castor, + pluto: Pluto, + mediationHandler: MediationHandler, + ) { + this.mercury = mercury + this.castor = castor + this.pluto = pluto + this.mediationHandler = mediationHandler + } + + @Throws() + suspend fun startMediator() { + mediationHandler.bootRegisteredMediator() + } + + @Throws() + suspend fun registerMediator(host: DID) { + mediationHandler.achieveMediation(host) + .first() + } + + @Throws() + suspend fun sendMessage(message: Message): Message? { + if (mediationHandler.mediator == null) { + throw PrismAgentError.noMediatorAvailableError() + } + pluto.storeMessage(message) + return mercury.sendMessageParseMessage(message) + } + + @Throws() + fun awaitMessages(): Flow> { + return mediationHandler.pickupUnreadMessages(NUMBER_OF_MESSAGES) + .map { + val messagesIds = it.map { it.first }.toTypedArray() + mediationHandler.registerMessagesAsRead(messagesIds) + it.map { it.second }.toTypedArray() + } + .map { + pluto.storeMessages(it) + it + } + } + + companion object { + const val NUMBER_OF_MESSAGES = 10 + } +} diff --git a/prism-agent/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PrismAgent.kt b/prism-agent/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/PrismAgent.kt similarity index 67% rename from prism-agent/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PrismAgent.kt rename to prism-agent/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/PrismAgent.kt index 07a744ff3..7a76a195d 100644 --- a/prism-agent/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PrismAgent.kt +++ b/prism-agent/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/PrismAgent.kt @@ -2,6 +2,7 @@ package io.iohk.atala.prism.walletsdk.prismagent import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Apollo import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Castor +import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Mercury import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Pluto import io.iohk.atala.prism.walletsdk.domain.models.Curve import io.iohk.atala.prism.walletsdk.domain.models.DID @@ -13,6 +14,7 @@ import io.iohk.atala.prism.walletsdk.domain.models.Signature import io.iohk.atala.prism.walletsdk.prismagent.helpers.Api import io.iohk.atala.prism.walletsdk.prismagent.helpers.ApiImpl import io.iohk.atala.prism.walletsdk.prismagent.helpers.HttpClient +import io.iohk.atala.prism.walletsdk.prismagent.mediation.MediationHandler import io.iohk.atala.prism.walletsdk.prismagent.models.InvitationType import io.iohk.atala.prism.walletsdk.prismagent.models.OutOfBandInvitation import io.iohk.atala.prism.walletsdk.prismagent.models.PrismOnboardingInvitation @@ -26,29 +28,65 @@ import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObject -actual class PrismAgent actual constructor( - apollo: Apollo, - castor: Castor, - pluto: Pluto, - seed: Seed?, - api: Api? -) { - actual enum class State { +class PrismAgent { + enum class State { STOPED, STARTING, RUNNING, STOPING } - actual var state: State = State.STOPED - actual val seed: Seed - actual val apollo: Apollo - actual val castor: Castor - actual val pluto: Pluto + var state: State = State.STOPED + private set + val seed: Seed + val apollo: Apollo + val castor: Castor + val pluto: Pluto + val mercury: Mercury private val api: Api + private val connectionManager: ConnectionManager + + internal constructor( + apollo: Apollo, + castor: Castor, + pluto: Pluto, + mercury: Mercury, + connectionManager: ConnectionManager, + seed: Seed?, + api: Api?, + ) { + this.apollo = apollo + this.castor = castor + this.pluto = pluto + this.mercury = mercury + this.connectionManager = connectionManager + this.seed = seed ?: apollo.createRandomSeed().second + this.api = api ?: ApiImpl( + HttpClient { + install(ContentNegotiation) { + json( + Json { + ignoreUnknownKeys = true + prettyPrint = true + isLenient = true + }, + ) + } + }, + ) + } - init { + constructor( + apollo: Apollo, + castor: Castor, + pluto: Pluto, + mercury: Mercury, + seed: Seed? = null, + api: Api? = null, + mediatorHandler: MediationHandler, + ) { this.apollo = apollo this.castor = castor this.pluto = pluto + this.mercury = mercury this.seed = seed ?: apollo.createRandomSeed().second this.api = api ?: ApiImpl( HttpClient { @@ -58,17 +96,44 @@ actual class PrismAgent actual constructor( ignoreUnknownKeys = true prettyPrint = true isLenient = true - } + }, ) } - } + }, ) + this.connectionManager = ConnectionManager(mercury, castor, pluto, mediatorHandler) + } + + @Throws() + suspend fun start() { + if (state != State.STOPED) { return } + state = State.STARTING + try { + connectionManager.startMediator() + } catch (error: PrismAgentError.noMediatorAvailableError) { + val hostDID = createNewPeerDID( + arrayOf( + DIDDocument.Service( + "#didcomm-1", + arrayOf("DIDCommMessaging"), + DIDDocument.ServiceEndpoint(connectionManager.mediationHandler.mediatorDID.toString()), + ), + ), + false, + ) + connectionManager.registerMediator(hostDID) + } + if (connectionManager.mediationHandler.mediator != null) { + state = State.RUNNING + } else { + throw PrismAgentError.mediationRequestFailedError() + } } suspend fun createNewPrismDID( keyPathIndex: Int? = null, alias: String? = null, - services: Array = emptyArray() + services: Array = emptyArray(), ): DID { val index = keyPathIndex ?: pluto.getPrismLastKeyPathIndex() val keyPair = apollo.createKeyPair(seed = seed, curve = KeyCurve(Curve.SECP256K1, index)) @@ -80,14 +145,14 @@ actual class PrismAgent actual constructor( suspend fun createNewPeerDID( services: Array = emptyArray(), - updateMediator: Boolean + updateMediator: Boolean, ): DID { val keyAgreementKeyPair = apollo.createKeyPair(seed = seed, curve = KeyCurve(Curve.X25519)) val authenticationKeyPair = apollo.createKeyPair(seed = seed, curve = KeyCurve(Curve.ED25519)) val did = castor.createPeerDID( arrayOf(keyAgreementKeyPair, authenticationKeyPair), - services = services + services = services, ) if (updateMediator) { @@ -96,7 +161,7 @@ actual class PrismAgent actual constructor( pluto.storePeerDID( did = did, - privateKeys = arrayOf(keyAgreementKeyPair.privateKey, authenticationKeyPair.privateKey) + privateKeys = arrayOf(keyAgreementKeyPair.privateKey, authenticationKeyPair.privateKey), ) return did @@ -130,7 +195,7 @@ actual class PrismAgent actual constructor( invitation.onboardEndpoint, arrayOf(), arrayOf(), - SendDID(invitation.from.toString()) + SendDID(invitation.from.toString()), ) if (response.status != 200) { @@ -155,11 +220,11 @@ actual class PrismAgent actual constructor( serviceEndpoint = DIDDocument.ServiceEndpoint( uri = url, accept = arrayOf("DIDCommMessaging"), - routingKeys = arrayOf() - ) - ) + routingKeys = arrayOf(), + ), + ), ), - true + true, ) prismOnboarding.from = did return prismOnboarding diff --git a/prism-agent/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/helpers/Api.kt b/prism-agent/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/Api.kt similarity index 95% rename from prism-agent/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/helpers/Api.kt rename to prism-agent/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/Api.kt index 5ebeaa16d..a045d433f 100644 --- a/prism-agent/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/helpers/Api.kt +++ b/prism-agent/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/Api.kt @@ -11,6 +11,6 @@ actual interface Api { url: String, urlParameters: Array, httpHeaders: Array, - body: Any? + body: Any?, ): HttpResponse } diff --git a/prism-agent/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/helpers/ApiImpl.kt b/prism-agent/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/ApiImpl.kt similarity index 91% rename from prism-agent/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/helpers/ApiImpl.kt rename to prism-agent/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/ApiImpl.kt index 348a11f04..7373a7f38 100644 --- a/prism-agent/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/helpers/ApiImpl.kt +++ b/prism-agent/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/ApiImpl.kt @@ -15,19 +15,19 @@ open class ApiImpl(override var client: HttpClient) : Api { url: String, urlParameters: Array, httpHeaders: Array, - body: Any? + body: Any?, ): HttpResponse { val request = PrismShared.getRequestBuilder( httpMethod = HttpMethod(httpMethod), url = Url(url), urlParametersArray = urlParameters, httpHeadersArray = httpHeaders, - body = body + body = body, ) val response = client.request(request) return HttpResponse( status = response.status.value, - jsonString = response.bodyAsText() + jsonString = response.bodyAsText(), ) } } diff --git a/prism-agent/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/helpers/HttpClient.kt b/prism-agent/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/HttpClient.kt similarity index 100% rename from prism-agent/src/allButJSMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/helpers/HttpClient.kt rename to prism-agent/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/HttpClient.kt diff --git a/prism-agent/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/mediation/DefaultMediationHandler.kt b/prism-agent/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/mediation/DefaultMediationHandler.kt new file mode 100644 index 000000000..9eb40b000 --- /dev/null +++ b/prism-agent/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/mediation/DefaultMediationHandler.kt @@ -0,0 +1,117 @@ +package io.iohk.atala.prism.walletsdk.prismagent.mediation + +import io.iohk.atala.prism.apollo.uuid.UUID +import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Mercury +import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Pluto +import io.iohk.atala.prism.walletsdk.domain.models.AttachmentBase64 +import io.iohk.atala.prism.walletsdk.domain.models.AttachmentDescriptor +import io.iohk.atala.prism.walletsdk.domain.models.AttachmentJsonData +import io.iohk.atala.prism.walletsdk.domain.models.DID +import io.iohk.atala.prism.walletsdk.domain.models.Mediator +import io.iohk.atala.prism.walletsdk.domain.models.Message +import io.iohk.atala.prism.walletsdk.domain.models.PrismAgentError +import io.iohk.atala.prism.walletsdk.prismagent.protocols.mediation.MediationGrant +import io.iohk.atala.prism.walletsdk.prismagent.protocols.mediation.MediationKeysUpdateList +import io.iohk.atala.prism.walletsdk.prismagent.protocols.mediation.MediationRequest +import io.iohk.atala.prism.walletsdk.prismagent.protocols.pickup.PickupDelivery +import io.iohk.atala.prism.walletsdk.prismagent.protocols.pickup.PickupReceived +import io.iohk.atala.prism.walletsdk.prismagent.protocols.pickup.PickupRequest +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.map + +final class DefaultMediationHandler( + override val mediatorDID: DID, + private val mercury: Mercury, + private val store: MediatorRepository, +) : MediationHandler { + final class PlutoMediatorRepositoryImpl(private val pluto: Pluto) : MediatorRepository { + override fun getAllMediators(): Array { + return pluto.getAllMediators() + } + + override fun storeMediator(mediator: Mediator) { + pluto.storeMediator(mediator.mediatorDID, mediator.hostDID, mediator.routingDID) + } + } + + override var mediator: Mediator? = null + private set + + init { + this.mediator = null + } + + override fun bootRegisteredMediator(): Mediator? { + if (mediator == null) { + mediator = store.getAllMediators().first() + } + return mediator + } + + override fun achieveMediation(host: DID): Flow { + val requestMessage = MediationRequest(from = host, to = mediatorDID).makeMessage() + return flow { + emit(mercury.sendMessageParseMessage(message = requestMessage)) + }.map { + val grantedMessage = it?.let { MediationGrant(it) } ?: throw PrismAgentError.mediationRequestFailedError() + val routingDID = DID(grantedMessage.body.routingDid) + Mediator( + id = UUID.randomUUID4().toString(), + mediatorDID = mediatorDID, + hostDID = host, + routingDID = routingDID, + ) + } + } + + override suspend fun updateKeyListWithDIDs(dids: Array) { + val keyListUpdateMessage = mediator?.let { + MediationKeysUpdateList( + from = it.hostDID, + to = it.mediatorDID, + recipientDids = dids, + ).makeMessage() + } ?: throw PrismAgentError.noMediatorAvailableError() + keyListUpdateMessage.let { message -> mercury.sendMessage(message) } + } + + override fun pickupUnreadMessages(limit: Int): Flow>> { + val requestMessage = mediator?.let { + PickupRequest( + from = it.hostDID, + to = it.mediatorDID, + body = PickupRequest.Body(null, limit.toString()), + ).makeMessage() + } ?: throw PrismAgentError.noMediatorAvailableError() + + return flow { + emit(mercury.sendMessageParseMessage(requestMessage)) + }.map { + val receivedMessage = it?.let { PickupDelivery(it) } + receivedMessage?.let { + it.attachments.mapNotNull { attachment: AttachmentDescriptor -> + val data = attachment.data + when (data) { + is AttachmentBase64 -> Pair(it.id, data.base64) + is AttachmentJsonData -> Pair(it.id, data.data) + else -> null + } + }.map { + Pair(it.first, mercury.unpackMessage(it.second)) + }.toTypedArray() + } ?: emptyArray() + } + } + + override suspend fun registerMessagesAsRead(ids: Array) { + val requestMessage = mediator?.let { + PickupReceived( + from = it.hostDID, + to = it.mediatorDID, + body = PickupReceived.Body(messageIdList = ids), + ).makeMessage() + } ?: throw PrismAgentError.noMediatorAvailableError() + mercury.sendMessage(requestMessage) + } +} diff --git a/prism-agent/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/mediation/MediationHandler.kt b/prism-agent/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/mediation/MediationHandler.kt new file mode 100644 index 000000000..a66fc6240 --- /dev/null +++ b/prism-agent/src/allButJSMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/mediation/MediationHandler.kt @@ -0,0 +1,26 @@ +package io.iohk.atala.prism.walletsdk.prismagent.mediation + +import io.iohk.atala.prism.walletsdk.domain.models.DID +import io.iohk.atala.prism.walletsdk.domain.models.Mediator +import io.iohk.atala.prism.walletsdk.domain.models.Message +import kotlinx.coroutines.flow.Flow + +actual interface MediationHandler { + actual val mediator: Mediator? + actual val mediatorDID: DID + + @Throws() + fun bootRegisteredMediator(): Mediator? + + @Throws() + fun achieveMediation(host: DID): Flow + + @Throws() + suspend fun updateKeyListWithDIDs(dids: Array) + + @Throws() + fun pickupUnreadMessages(limit: Int): Flow>> + + @Throws() + suspend fun registerMessagesAsRead(ids: Array) +} diff --git a/prism-agent/src/allButJSTest/kotlin/io/iohk/atala/prism/walletsdk/prismagent/ApiMock.kt b/prism-agent/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/ApiMock.kt similarity index 100% rename from prism-agent/src/allButJSTest/kotlin/io/iohk/atala/prism/walletsdk/prismagent/ApiMock.kt rename to prism-agent/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/ApiMock.kt diff --git a/prism-agent/src/allButJSTest/kotlin/io/iohk/atala/prism/walletsdk/prismagent/CastorMock.kt b/prism-agent/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/CastorMock.kt similarity index 100% rename from prism-agent/src/allButJSTest/kotlin/io/iohk/atala/prism/walletsdk/prismagent/CastorMock.kt rename to prism-agent/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/CastorMock.kt diff --git a/prism-agent/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/MediationHandlerMock.kt b/prism-agent/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/MediationHandlerMock.kt new file mode 100644 index 000000000..839e9ac57 --- /dev/null +++ b/prism-agent/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/MediationHandlerMock.kt @@ -0,0 +1,42 @@ +package io.iohk.atala.prism.walletsdk.prismagent + +import io.iohk.atala.prism.walletsdk.domain.models.DID +import io.iohk.atala.prism.walletsdk.domain.models.Mediator +import io.iohk.atala.prism.walletsdk.domain.models.Message +import io.iohk.atala.prism.walletsdk.domain.models.PrismAgentError +import io.iohk.atala.prism.walletsdk.prismagent.mediation.MediationHandler +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow + +class MediationHandlerMock( + override var mediator: Mediator? = null, + override var mediatorDID: DID = DID.testable(), +) : MediationHandler { + + var bootMediatorResponse: Mediator? = null + var achieveMediationResponse: Mediator? = null + var pickupUnreadMessagesResponse: Array> = emptyArray() + + @Throws() + override fun bootRegisteredMediator(): Mediator? { + mediator = bootMediatorResponse + return bootMediatorResponse + } + + @Throws() + override fun achieveMediation(host: DID): Flow { + mediator = achieveMediationResponse + return flow { achieveMediationResponse?.let { emit(it) } ?: throw PrismAgentError.noMediatorAvailableError() } + } + + @Throws() + override suspend fun updateKeyListWithDIDs(dids: Array) {} + + @Throws() + override fun pickupUnreadMessages(limit: Int): Flow>> { + return flow { emit(pickupUnreadMessagesResponse) } + } + + @Throws() + override suspend fun registerMessagesAsRead(ids: Array) {} +} diff --git a/prism-agent/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/MercuryMock.kt b/prism-agent/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/MercuryMock.kt new file mode 100644 index 000000000..882df66f9 --- /dev/null +++ b/prism-agent/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/MercuryMock.kt @@ -0,0 +1,30 @@ +package io.iohk.atala.prism.walletsdk.prismagent + +import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Mercury +import io.iohk.atala.prism.walletsdk.domain.models.Message +import kotlin.jvm.Throws + +class MercuryMock : Mercury { + var packMessageResponse: String? = null + var unpackMessageResponse: Message? = null + var sendMessageResponse: ByteArray? = null + var sendMessageParseMessageResponse: Message? = null + + @Throws() + override fun packMessage(message: Message): String { + return packMessageResponse ?: "" + } + + @Throws() + override fun unpackMessage(message: String): Message { + return unpackMessageResponse ?: Message.testable() + } + + override suspend fun sendMessage(message: Message): ByteArray? { + return sendMessageResponse + } + + override suspend fun sendMessageParseMessage(message: Message): Message? { + return sendMessageParseMessageResponse + } +} diff --git a/prism-agent/src/allButJSTest/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PlutoMock.kt b/prism-agent/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/PlutoMock.kt similarity index 97% rename from prism-agent/src/allButJSTest/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PlutoMock.kt rename to prism-agent/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/PlutoMock.kt index 82962cc63..7ad077bf2 100644 --- a/prism-agent/src/allButJSTest/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PlutoMock.kt +++ b/prism-agent/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/PlutoMock.kt @@ -3,7 +3,7 @@ package io.iohk.atala.prism.walletsdk.prismagent import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Pluto import io.iohk.atala.prism.walletsdk.domain.models.DID import io.iohk.atala.prism.walletsdk.domain.models.DIDPair -import io.iohk.atala.prism.walletsdk.domain.models.MediatorDID +import io.iohk.atala.prism.walletsdk.domain.models.Mediator import io.iohk.atala.prism.walletsdk.domain.models.Message import io.iohk.atala.prism.walletsdk.domain.models.PeerDID import io.iohk.atala.prism.walletsdk.domain.models.PrismDIDInfo @@ -55,7 +55,7 @@ class PlutoMock : Pluto { var getAllMessagesReceivedFromReturn: Array = emptyArray() var getAllMessagesOfTypeReturn: Array = emptyArray() var getMessageReturn: Message? = null - var getAllMediatorsReturn: Array = emptyArray() + var getAllMediatorsReturn: Array = emptyArray() var getAllCredentialsReturn: Array = emptyArray() override fun storePrismDID( @@ -185,7 +185,7 @@ class PlutoMock : Pluto { return getMessageReturn } - override fun getAllMediators(): Array { + override fun getAllMediators(): Array { wasGetAllMediatorsCalled = true return getAllMediatorsReturn } diff --git a/prism-agent/src/allButJSTest/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PrismAgentTests.kt b/prism-agent/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/PrismAgentTests.kt similarity index 81% rename from prism-agent/src/allButJSTest/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PrismAgentTests.kt rename to prism-agent/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/PrismAgentTests.kt index 7c72ddd14..584d39832 100644 --- a/prism-agent/src/allButJSTest/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PrismAgentTests.kt +++ b/prism-agent/src/allButJSTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/PrismAgentTests.kt @@ -26,12 +26,18 @@ class PrismAgentTests { lateinit var apolloMock: ApolloMock lateinit var castorMock: CastorMock lateinit var plutoMock: PlutoMock + lateinit var mercuryMock: MercuryMock + lateinit var mediationHandlerMock: MediationHandlerMock + lateinit var connectionManager: ConnectionManager @BeforeTest fun setup() { apolloMock = ApolloMock() castorMock = CastorMock() plutoMock = PlutoMock() + mercuryMock = MercuryMock() + mediationHandlerMock = MediationHandlerMock() + connectionManager = ConnectionManager(mercuryMock, castorMock, plutoMock, mediationHandlerMock) } @Test @@ -43,7 +49,10 @@ class PrismAgentTests { apollo = apolloMock, castor = castorMock, pluto = plutoMock, - seed = seed + mercury = mercuryMock, + connectionManager = connectionManager, + seed = seed, + api = null ) val newDID = agent.createNewPrismDID() assertEquals(newDID, validDID) @@ -57,7 +66,15 @@ class PrismAgentTests { fun testCreateNewPeerDID_shouldCreateNewDID_whenCalled() = runTest { val validDID = DID("did", "test", "123") castorMock.createPeerDIDReturn = validDID - val agent = PrismAgent(apolloMock, castorMock, plutoMock) + val agent = PrismAgent( + apolloMock, + castorMock, + plutoMock, + mercuryMock, + connectionManager, + null, + null + ) val newDID = agent.createNewPeerDID(services = emptyArray(), updateMediator = false) assertEquals(newDID, validDID) @@ -71,6 +88,9 @@ class PrismAgentTests { apollo = apolloMock, castor = castorMock, pluto = plutoMock, + mercury = mercuryMock, + connectionManager = connectionManager, + seed = null, api = ApiMock(HttpStatusCode.OK, "{\"success\":\"true\"}") ) var invitationString = """ @@ -91,6 +111,9 @@ class PrismAgentTests { apollo = apolloMock, castor = castorMock, pluto = plutoMock, + mercury = mercuryMock, + connectionManager = connectionManager, + seed = null, api = ApiMock(HttpStatusCode.BadRequest, "{\"success\":\"true\"}") ) var invitationString = """ @@ -112,6 +135,9 @@ class PrismAgentTests { apollo = apolloMock, castor = castorMock, pluto = plutoMock, + mercury = mercuryMock, + connectionManager = connectionManager, + seed = null, api = ApiMock(HttpStatusCode.OK, "{\"success\":\"true\"}") ) var invitationString = """ @@ -129,9 +155,13 @@ class PrismAgentTests { @Test fun testPrismAgentSignWith_whenNoPrivateKeyAvailable_thenThrowCannotFindDIDPrivateKey() = runTest { val agent = PrismAgent( - apolloMock, - castorMock, - plutoMock + apollo = apolloMock, + castor = castorMock, + pluto = plutoMock, + mercury = mercuryMock, + connectionManager = connectionManager, + seed = null, + api = null ) plutoMock.getDIDPrivateKeysReturn = null @@ -147,9 +177,13 @@ class PrismAgentTests { @Test fun testPrismAgentSignWith_whenPrivateKeyAvailable_thenSignatureReturned() = runTest { val agent = PrismAgent( - apolloMock, - castorMock, - plutoMock + apollo = apolloMock, + castor = castorMock, + pluto = plutoMock, + mercury = mercuryMock, + connectionManager = connectionManager, + seed = null, + api = null, ) val privateKeys = arrayOf(PrivateKey(KeyCurve(Curve.SECP256K1), byteArrayOf())) @@ -165,9 +199,13 @@ class PrismAgentTests { @Test fun testParseInvitation_whenOutOfBand_thenReturnsOutOfBandInvitationObject() = runTest { val agent = PrismAgent( - apolloMock, - castorMock, - plutoMock + apollo = apolloMock, + castor = castorMock, + pluto = plutoMock, + mercury = mercuryMock, + connectionManager = connectionManager, + seed = null, + api = null, ) val invitationString = """ @@ -204,9 +242,13 @@ class PrismAgentTests { @Test fun testParseInvitation_whenOutOfBandWrongBody_thenThrowsUnknownInvitationTypeError() = runTest { val agent = PrismAgent( - apolloMock, - castorMock, - plutoMock + apollo = apolloMock, + castor = castorMock, + pluto = plutoMock, + mercury = mercuryMock, + connectionManager = connectionManager, + seed = null, + api = null, ) val invitationString = """ diff --git a/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/ConnectionManager.kt b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/ConnectionManager.kt new file mode 100644 index 000000000..e24e7168d --- /dev/null +++ b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/ConnectionManager.kt @@ -0,0 +1,13 @@ +package io.iohk.atala.prism.walletsdk.prismagent + +import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Castor +import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Mercury +import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Pluto +import io.iohk.atala.prism.walletsdk.prismagent.mediation.MediationHandler + +expect class ConnectionManager( + mercury: Mercury, + castor: Castor, + pluto: Pluto, + mediationHandler: MediationHandler, +) diff --git a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/helpers/Api.kt b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/Api.kt similarity index 100% rename from prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/helpers/Api.kt rename to prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/Api.kt diff --git a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/helpers/HttpClient.kt b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/HttpClient.kt similarity index 100% rename from prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/helpers/HttpClient.kt rename to prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/HttpClient.kt diff --git a/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/mediation/MediationHandler.kt b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/mediation/MediationHandler.kt new file mode 100644 index 000000000..cec1c9c53 --- /dev/null +++ b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/mediation/MediationHandler.kt @@ -0,0 +1,9 @@ +package io.iohk.atala.prism.walletsdk.prismagent.mediation + +import io.iohk.atala.prism.walletsdk.domain.models.DID +import io.iohk.atala.prism.walletsdk.domain.models.Mediator + +expect interface MediationHandler { + val mediator: Mediator? + val mediatorDID: DID +} diff --git a/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/mediation/MediatorRepository.kt b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/mediation/MediatorRepository.kt new file mode 100644 index 000000000..2fba1f2c0 --- /dev/null +++ b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/mediation/MediatorRepository.kt @@ -0,0 +1,8 @@ +package io.iohk.atala.prism.walletsdk.prismagent.mediation + +import io.iohk.atala.prism.walletsdk.domain.models.Mediator + +interface MediatorRepository { + fun storeMediator(mediator: Mediator) + fun getAllMediators(): Array +} diff --git a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/models/InvitationType.kt b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/models/InvitationType.kt similarity index 80% rename from prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/models/InvitationType.kt rename to prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/models/InvitationType.kt index 77ff9ace5..2ddb6f619 100644 --- a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/models/InvitationType.kt +++ b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/models/InvitationType.kt @@ -1,6 +1,8 @@ package io.iohk.atala.prism.walletsdk.prismagent.models import kotlinx.serialization.Serializable +import kotlin.js.JsExport @Serializable +@JsExport sealed class InvitationType() diff --git a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/models/OutOfBandInvitation.kt b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/models/OutOfBandInvitation.kt similarity index 93% rename from prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/models/OutOfBandInvitation.kt rename to prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/models/OutOfBandInvitation.kt index 06c095285..c3ea2b9e1 100644 --- a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/models/OutOfBandInvitation.kt +++ b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/models/OutOfBandInvitation.kt @@ -5,8 +5,10 @@ import io.iohk.atala.prism.walletsdk.domain.models.DID import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.Transient +import kotlin.js.JsExport @Serializable +@JsExport data class OutOfBandInvitation( val id: String = UUID.randomUUID4().toString(), val body: Body, @@ -14,7 +16,7 @@ data class OutOfBandInvitation( private val fromString: String, @Transient var from: DID = DID(fromString), - val type: String + val type: String, ) : InvitationType() { @Serializable @@ -22,7 +24,7 @@ data class OutOfBandInvitation( @SerialName("goal_code") val goalCode: String? = null, val goal: String? = null, - val accept: Array? = null + val accept: Array? = null, ) { override fun equals(other: Any?): Boolean { if (this === other) return true diff --git a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/models/PrismOnboardingInvitation.kt b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/models/PrismOnboardingInvitation.kt similarity index 97% rename from prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/models/PrismOnboardingInvitation.kt rename to prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/models/PrismOnboardingInvitation.kt index 89951f99d..1fc28065e 100644 --- a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/models/PrismOnboardingInvitation.kt +++ b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/models/PrismOnboardingInvitation.kt @@ -14,7 +14,7 @@ data class PrismOnboardingInvitation( private val fromString: String, @Transient var from: DID? = null, - val type: String + val type: String, ) : InvitationType() { init { diff --git a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/ProtocolType.kt b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/ProtocolType.kt similarity index 99% rename from prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/ProtocolType.kt rename to prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/ProtocolType.kt index faeb0defa..8661669a2 100644 --- a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/ProtocolType.kt +++ b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/ProtocolType.kt @@ -22,7 +22,7 @@ enum class ProtocolType(val value: String) { PickupRequest("https://didcomm.org/messagepickup/3.0/delivery-request"), PickupDelivery("https://didcomm.org/messagepickup/3.0/delivery"), PickupStatus("https://didcomm.org/messagepickup/3.0/status"), - PickupReceived("https://didcomm.org/messagepickup/3.0/messages-received") + PickupReceived("https://didcomm.org/messagepickup/3.0/messages-received"), } fun findProtocolTypeByValue(string: String): ProtocolType { diff --git a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/issueCredential/CredentialFormat.kt b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/issueCredential/CredentialFormat.kt similarity index 100% rename from prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/issueCredential/CredentialFormat.kt rename to prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/issueCredential/CredentialFormat.kt diff --git a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/issueCredential/CredentialPreview.kt b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/issueCredential/CredentialPreview.kt similarity index 100% rename from prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/issueCredential/CredentialPreview.kt rename to prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/issueCredential/CredentialPreview.kt diff --git a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/MediationGrant.kt b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/mediation/MediationGrant.kt similarity index 85% rename from prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/MediationGrant.kt rename to prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/mediation/MediationGrant.kt index 967f076b4..c68506397 100644 --- a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/MediationGrant.kt +++ b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/mediation/MediationGrant.kt @@ -1,7 +1,8 @@ -package io.iohk.atala.prism.walletsdk.prismagent.protocols +package io.iohk.atala.prism.walletsdk.prismagent.protocols.mediation import io.iohk.atala.prism.apollo.uuid.UUID import io.iohk.atala.prism.walletsdk.domain.models.Message +import io.iohk.atala.prism.walletsdk.prismagent.protocols.ProtocolType import kotlinx.serialization.Serializable import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json @@ -17,7 +18,7 @@ class MediationGrant { constructor( id: String = UUID.randomUUID4().toString(), - body: Body + body: Body, ) { this.id = id this.body = body diff --git a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/MediationKeysUpdateList.kt b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/mediation/MediationKeysUpdateList.kt similarity index 81% rename from prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/MediationKeysUpdateList.kt rename to prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/mediation/MediationKeysUpdateList.kt index b99521615..2e53638c1 100644 --- a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/MediationKeysUpdateList.kt +++ b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/mediation/MediationKeysUpdateList.kt @@ -1,14 +1,15 @@ -package io.iohk.atala.prism.walletsdk.prismagent.protocols +package io.iohk.atala.prism.walletsdk.prismagent.protocols.mediation import io.iohk.atala.prism.apollo.uuid.UUID import io.iohk.atala.prism.walletsdk.domain.models.DID import io.iohk.atala.prism.walletsdk.domain.models.Message +import io.iohk.atala.prism.walletsdk.prismagent.protocols.ProtocolType import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json @Serializable -class MediationKeysUpdateList { +final class MediationKeysUpdateList { var id: String var from: DID var to: DID @@ -19,15 +20,15 @@ class MediationKeysUpdateList { id: String = UUID.randomUUID4().toString(), from: DID, to: DID, - recipientDid: DID + recipientDids: Array, ) { this.id = id this.from = from this.to = to this.body = Body( - updates = arrayOf( - Update(recipientDid = recipientDid.toString()) - ) + updates = recipientDids.map { + Update(recipientDid = it.toString()) + }.toTypedArray(), ) } @@ -46,7 +47,7 @@ class MediationKeysUpdateList { thid = null, pthid = null, ack = emptyArray(), - direction = Message.Direction.SENT + direction = Message.Direction.SENT, ) } diff --git a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/MediationRequest.kt b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/mediation/MediationRequest.kt similarity index 84% rename from prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/MediationRequest.kt rename to prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/mediation/MediationRequest.kt index 8b5c03ddc..722dc1cf6 100644 --- a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/MediationRequest.kt +++ b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/mediation/MediationRequest.kt @@ -1,22 +1,23 @@ -package io.iohk.atala.prism.walletsdk.prismagent.protocols +package io.iohk.atala.prism.walletsdk.prismagent.protocols.mediation import io.iohk.atala.prism.apollo.uuid.UUID import io.iohk.atala.prism.walletsdk.domain.models.DID import io.iohk.atala.prism.walletsdk.domain.models.Message +import io.iohk.atala.prism.walletsdk.prismagent.protocols.ProtocolType -sealed class MediationRequest( +final class MediationRequest( val id: String, val type: String = ProtocolType.DidcommMediationRequest.value, val from: DID, - val to: DID + val to: DID, ) { constructor( from: DID, - to: DID + to: DID, ) : this( id = UUID.randomUUID4().toString(), from = from, - to = to + to = to, ) fun makeMessage(): Message { @@ -34,7 +35,7 @@ sealed class MediationRequest( thid = null, pthid = null, ack = emptyArray(), - direction = Message.Direction.SENT + direction = Message.Direction.SENT, ) } diff --git a/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/pickup/PickupDelivery.kt b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/pickup/PickupDelivery.kt new file mode 100644 index 000000000..d4e525480 --- /dev/null +++ b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/pickup/PickupDelivery.kt @@ -0,0 +1,20 @@ +package io.iohk.atala.prism.walletsdk.prismagent.protocols.pickup + +import io.iohk.atala.prism.walletsdk.domain.models.AttachmentDescriptor +import io.iohk.atala.prism.walletsdk.domain.models.Message +import io.iohk.atala.prism.walletsdk.domain.models.PrismAgentError +import io.iohk.atala.prism.walletsdk.prismagent.protocols.ProtocolType + +final class PickupDelivery { + var id: String + var type = ProtocolType.PickupDelivery.value + val attachments: Array + + constructor(fromMessage: Message) { + if (fromMessage.piuri != ProtocolType.PickupDelivery.value) { + throw PrismAgentError.invalidPickupDeliveryMessageError() + } + this.id = fromMessage.id + this.attachments = fromMessage.attachments + } +} diff --git a/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/pickup/PickupReceived.kt b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/pickup/PickupReceived.kt new file mode 100644 index 000000000..1527e4603 --- /dev/null +++ b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/pickup/PickupReceived.kt @@ -0,0 +1,51 @@ +package io.iohk.atala.prism.walletsdk.prismagent.protocols.pickup + +import io.iohk.atala.prism.apollo.uuid.UUID +import io.iohk.atala.prism.walletsdk.domain.models.DID +import io.iohk.atala.prism.walletsdk.domain.models.Message +import io.iohk.atala.prism.walletsdk.prismagent.protocols.ProtocolType +import kotlinx.serialization.Serializable +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json + +final class PickupReceived { + var id: String + var type = ProtocolType.PickupReceived.value + val from: DID + val to: DID + var body: Body + + constructor( + id: String = UUID.randomUUID4().toString(), + from: DID, + to: DID, + body: Body, + ) { + this.id = id + this.from = from + this.to = to + this.body = body + } + + fun makeMessage(): Message { + return Message( + id = id, + piuri = type, + from = from, + to = to, + fromPrior = null, + body = Json.encodeToString(body), + extraHeaders = emptyArray(), + createdTime = "", + expiresTimePlus = "", + attachments = emptyArray(), + thid = null, + pthid = null, + ack = emptyArray(), + direction = Message.Direction.SENT, + ) + } + + @Serializable + data class Body(var messageIdList: Array) +} diff --git a/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/pickup/PickupRequest.kt b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/pickup/PickupRequest.kt new file mode 100644 index 000000000..bc3f27dd9 --- /dev/null +++ b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/pickup/PickupRequest.kt @@ -0,0 +1,51 @@ +package io.iohk.atala.prism.walletsdk.prismagent.protocols.pickup + +import io.iohk.atala.prism.apollo.uuid.UUID +import io.iohk.atala.prism.walletsdk.domain.models.DID +import io.iohk.atala.prism.walletsdk.domain.models.Message +import io.iohk.atala.prism.walletsdk.prismagent.protocols.ProtocolType +import kotlinx.serialization.Serializable +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json + +final class PickupRequest { + var id: String + var type = ProtocolType.PickupRequest.value + val from: DID + val to: DID + var body: Body + + constructor( + id: String = UUID.randomUUID4().toString(), + from: DID, + to: DID, + body: Body, + ) { + this.id = id + this.from = from + this.to = to + this.body = body + } + + fun makeMessage(): Message { + return Message( + id = id, + piuri = type, + from = from, + to = to, + fromPrior = null, + body = Json.encodeToString(body), + extraHeaders = emptyArray(), + createdTime = "", + expiresTimePlus = "", + attachments = emptyArray(), + thid = null, + pthid = null, + ack = emptyArray(), + direction = Message.Direction.SENT, + ) + } + + @Serializable + data class Body(var recipientKey: String?, var limit: String) +} diff --git a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/prismOnboarding/PrismOnboardingInvitation.kt b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/prismOnboarding/PrismOnboardingInvitation.kt similarity index 96% rename from prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/prismOnboarding/PrismOnboardingInvitation.kt rename to prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/prismOnboarding/PrismOnboardingInvitation.kt index 0f07ae698..ccc9690d1 100644 --- a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/prismOnboarding/PrismOnboardingInvitation.kt +++ b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/prismOnboarding/PrismOnboardingInvitation.kt @@ -11,7 +11,7 @@ class PrismOnboardingInvitation(jsonString: String) { data class Body( val type: String, val onboardEndpoint: String, - val from: String + val from: String, ) var body: Body diff --git a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/shared/KeyValue.kt b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/shared/KeyValue.kt similarity index 89% rename from prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/shared/KeyValue.kt rename to prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/shared/KeyValue.kt index 01b928625..1e574652a 100644 --- a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/shared/KeyValue.kt +++ b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/shared/KeyValue.kt @@ -7,5 +7,5 @@ import kotlin.js.JsExport @JsExport data class KeyValue( val key: String, - val value: String + val value: String, ) diff --git a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/shared/PrismShared.kt b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/shared/PrismShared.kt similarity index 98% rename from prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/shared/PrismShared.kt rename to prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/shared/PrismShared.kt index 2fd2b3a59..b0a4a28a7 100644 --- a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/shared/PrismShared.kt +++ b/prism-agent/src/commonMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/shared/PrismShared.kt @@ -25,9 +25,8 @@ class PrismShared { url: Url, urlParametersArray: Array, httpHeadersArray: Array, - body: Any? + body: Any?, ): HttpRequestBuilder { - val urlParameters: Map = mapFromKeyValueArray(urlParametersArray) val httpHeaders: Map = mapFromKeyValueArray(httpHeadersArray) diff --git a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PrismAgent.kt b/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PrismAgent.kt deleted file mode 100644 index e5a1dbbe8..000000000 --- a/prism-agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PrismAgent.kt +++ /dev/null @@ -1,25 +0,0 @@ -package io.iohk.atala.prism.walletsdk.prismagent - -import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Apollo -import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Castor -import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Pluto -import io.iohk.atala.prism.walletsdk.domain.models.Seed -import io.iohk.atala.prism.walletsdk.prismagent.helpers.Api - -expect class PrismAgent( - apollo: Apollo, - castor: Castor, - pluto: Pluto, - seed: Seed? = null, - api: Api? = null -) { - enum class State { - STOPED, STARTING, RUNNING, STOPING - } - - val seed: Seed - var state: State - val apollo: Apollo - val castor: Castor - val pluto: Pluto -} diff --git a/prism-agent/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/prismagent/ApolloMock.kt b/prism-agent/src/commonTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/ApolloMock.kt similarity index 100% rename from prism-agent/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/prismagent/ApolloMock.kt rename to prism-agent/src/commonTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/ApolloMock.kt diff --git a/prism-agent/src/commonTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/DIDMock.kt b/prism-agent/src/commonTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/DIDMock.kt new file mode 100644 index 000000000..f34414c79 --- /dev/null +++ b/prism-agent/src/commonTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/DIDMock.kt @@ -0,0 +1,11 @@ +package io.iohk.atala.prism.walletsdk.prismagent + +import io.iohk.atala.prism.walletsdk.domain.models.DID + +fun DID.Companion.testable( + schema: String = "did", + method: String = "test1", + methodId: String = "test1Id", +): DID { + return DID(schema, method, methodId) +} diff --git a/prism-agent/src/commonTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/MessageMock.kt b/prism-agent/src/commonTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/MessageMock.kt new file mode 100644 index 000000000..a5ba73d3e --- /dev/null +++ b/prism-agent/src/commonTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/MessageMock.kt @@ -0,0 +1,39 @@ +package io.iohk.atala.prism.walletsdk.prismagent + +import io.iohk.atala.prism.walletsdk.domain.models.AttachmentDescriptor +import io.iohk.atala.prism.walletsdk.domain.models.DID +import io.iohk.atala.prism.walletsdk.domain.models.Message + +fun Message.Companion.testable( + id: String = "test1", + piuri: String = "test", + from: DID? = null, + to: DID? = null, + fromPrior: String? = null, + body: String = "", + extraHeaders: Array = emptyArray(), + createdTime: String = "", + expiresTimePlus: String = "", + attachments: Array = emptyArray(), + thid: String? = null, + pthid: String? = null, + ack: Array = emptyArray(), + direction: Message.Direction = Message.Direction.RECEIVED, +): Message { + return Message( + id, + piuri, + from, + to, + fromPrior, + body, + extraHeaders, + createdTime, + expiresTimePlus, + attachments, + thid, + pthid, + ack, + direction, + ) +} diff --git a/prism-agent/src/commonTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/MediationKeysUpdateListTest.kt b/prism-agent/src/commonTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/MediationKeysUpdateListTest.kt new file mode 100644 index 000000000..bbbc991ec --- /dev/null +++ b/prism-agent/src/commonTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/protocols/MediationKeysUpdateListTest.kt @@ -0,0 +1,35 @@ +package io.iohk.atala.prism.walletsdk.prismagent.protocols + +import io.iohk.atala.prism.walletsdk.domain.models.DID +import io.iohk.atala.prism.walletsdk.prismagent.protocols.mediation.MediationKeysUpdateList +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json +import kotlin.test.Test +import kotlin.test.assertEquals + +class MediationKeysUpdateListTest { + @Test + fun makeMessageShouldReturnValidMessage() { + // given + val id = "test_id" + val from = DID("did:example:123") + val to = DID("did:example:456") + val recipientDid = DID("did:example:789") + val mediationKeysUpdateList = MediationKeysUpdateList(id, from, to, arrayOf(recipientDid)) + + // when + val message = mediationKeysUpdateList.makeMessage() + + // then + assertEquals(id, message.id) + assertEquals(ProtocolType.DidcommMediationKeysUpdate.value, message.piuri) + assertEquals(from, message.from) + assertEquals(to, message.to) + + val expectedBody = MediationKeysUpdateList.Body( + updates = arrayOf(MediationKeysUpdateList.Update(recipientDid = recipientDid.toString())) + ) + val actualBody: MediationKeysUpdateList.Body = Json.decodeFromString(message.body) + assertEquals(expectedBody, actualBody) + } +} diff --git a/prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/ConnectionManager.kt b/prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/ConnectionManager.kt new file mode 100644 index 000000000..6ca10d30f --- /dev/null +++ b/prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/ConnectionManager.kt @@ -0,0 +1,63 @@ +package io.iohk.atala.prism.walletsdk.prismagent + +import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Castor +import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Mercury +import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Pluto +import io.iohk.atala.prism.walletsdk.domain.models.DID +import io.iohk.atala.prism.walletsdk.domain.models.Mediator +import io.iohk.atala.prism.walletsdk.domain.models.Message +import io.iohk.atala.prism.walletsdk.domain.models.PrismAgentError +import io.iohk.atala.prism.walletsdk.prismagent.mediation.MediationHandler +import kotlin.js.Promise + +actual class ConnectionManager { + private val mercury: Mercury + private val castor: Castor + private val pluto: Pluto + internal val mediationHandler: MediationHandler + + actual constructor( + mercury: Mercury, + castor: Castor, + pluto: Pluto, + mediationHandler: MediationHandler, + ) { + this.mercury = mercury + this.castor = castor + this.pluto = pluto + this.mediationHandler = mediationHandler + } + + fun startMediator() { + mediationHandler.bootRegisteredMediator() + } + + fun registerMediator(host: DID): Promise { + return mediationHandler.achieveMediation(host) + } + + fun sendMessage(message: Message): Promise { + if (mediationHandler.mediator == null) { + throw PrismAgentError.noMediatorAvailableError() + } + pluto.storeMessage(message) + return mercury.sendMessageParseMessage(message) + } + + fun awaitMessages(): Promise> { + return mediationHandler.pickupUnreadMessages(NUMBER_OF_MESSAGES) + .then { + val messagesIds = it.map { it.first }.toTypedArray() + mediationHandler.registerMessagesAsRead(messagesIds) + it.map { it.second }.toTypedArray() + } + .then { + pluto.storeMessages(it) + it + } + } + + companion object { + const val NUMBER_OF_MESSAGES = 10 + } +} diff --git a/prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/PrismAgent.kt b/prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/PrismAgent.kt new file mode 100644 index 000000000..5b6668b57 --- /dev/null +++ b/prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/PrismAgent.kt @@ -0,0 +1,255 @@ +package io.iohk.atala.prism.walletsdk.prismagent + +import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Apollo +import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Castor +import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Mercury +import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Pluto +import io.iohk.atala.prism.walletsdk.domain.models.Curve +import io.iohk.atala.prism.walletsdk.domain.models.DID +import io.iohk.atala.prism.walletsdk.domain.models.DIDDocument +import io.iohk.atala.prism.walletsdk.domain.models.KeyCurve +import io.iohk.atala.prism.walletsdk.domain.models.PrismAgentError +import io.iohk.atala.prism.walletsdk.domain.models.Seed +import io.iohk.atala.prism.walletsdk.domain.models.Signature +import io.iohk.atala.prism.walletsdk.prismagent.helpers.Api +import io.iohk.atala.prism.walletsdk.prismagent.helpers.ApiImpl +import io.iohk.atala.prism.walletsdk.prismagent.helpers.HttpClient +import io.iohk.atala.prism.walletsdk.prismagent.mediation.MediationHandler +import io.iohk.atala.prism.walletsdk.prismagent.models.InvitationType +import io.iohk.atala.prism.walletsdk.prismagent.models.OutOfBandInvitation +import io.iohk.atala.prism.walletsdk.prismagent.models.PrismOnboardingInvitation +import io.iohk.atala.prism.walletsdk.prismagent.protocols.ProtocolType +import io.iohk.atala.prism.walletsdk.prismagent.protocols.findProtocolTypeByValue +import io.ktor.client.plugins.contentnegotiation.ContentNegotiation +import io.ktor.http.HttpMethod +import io.ktor.serialization.kotlinx.json.json +import kotlinx.serialization.Serializable +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonObject +import kotlin.js.Promise + +@JsExport +final class PrismAgent { + enum class State { + STOPED, STARTING, RUNNING, STOPING + } + + var state: State = State.STOPED + private set + val seed: Seed + val apollo: Apollo + val castor: Castor + val pluto: Pluto + val mercury: Mercury + + private val api: Api + private val connectionManager: ConnectionManager + + internal constructor( + apollo: Apollo, + castor: Castor, + pluto: Pluto, + mercury: Mercury, + connectionManager: ConnectionManager, + seed: Seed?, + api: Api?, + ) { + this.apollo = apollo + this.castor = castor + this.pluto = pluto + this.mercury = mercury + this.connectionManager = connectionManager + this.seed = seed ?: apollo.createRandomSeed().second + this.api = api ?: ApiImpl( + HttpClient { + install(ContentNegotiation) { + json( + Json { + ignoreUnknownKeys = true + prettyPrint = true + isLenient = true + }, + ) + } + }, + ) + } + + @JsName(name = "NewName") + constructor( + apollo: Apollo, + castor: Castor, + pluto: Pluto, + mercury: Mercury, + seed: Seed? = null, + api: Api? = null, + mediatorHandler: MediationHandler, + ) { + this.apollo = apollo + this.castor = castor + this.pluto = pluto + this.mercury = mercury + this.seed = seed ?: apollo.createRandomSeed().second + this.api = api ?: ApiImpl( + HttpClient { + install(ContentNegotiation) { + json( + Json { + ignoreUnknownKeys = true + prettyPrint = true + isLenient = true + }, + ) + } + }, + ) + this.connectionManager = ConnectionManager(mercury, castor, pluto, mediatorHandler) + } + + fun start(): Promise { + if (state != State.STOPED) { return Promise.Companion.resolve(state) } + state = State.STARTING + try { + connectionManager.startMediator() + state = State.RUNNING + return Promise.resolve(state) + } catch (error: PrismAgentError.noMediatorAvailableError) { + return createNewPeerDID( + arrayOf( + DIDDocument.Service( + "#didcomm-1", + arrayOf("DIDCommMessaging"), + DIDDocument.ServiceEndpoint(connectionManager.mediationHandler.mediatorDID.toString()), + ), + ), + false, + ).then { + connectionManager.registerMediator(it) + }.then { + if (connectionManager.mediationHandler.mediator != null) { + state = State.RUNNING + state + } else { + throw PrismAgentError.mediationRequestFailedError() + } + } + } + } + + fun createNewPrismDID( + keyPathIndex: Int? = null, + alias: String? = null, + services: Array = emptyArray(), + ): DID { + val index = keyPathIndex ?: pluto.getPrismLastKeyPathIndex() + val keyPair = apollo.createKeyPair(seed = seed, curve = KeyCurve(Curve.SECP256K1, index)) + val did = castor.createPrismDID(masterPublicKey = keyPair.publicKey, services = services) + pluto.storePrivateKeys(keyPair.privateKey, did, index) + pluto.storePrismDID(did = did, keyPathIndex = index, alias = alias) + return did + } + + fun createNewPeerDID( + services: Array = emptyArray(), + updateMediator: Boolean, + ): Promise { + val keyAgreementKeyPair = apollo.createKeyPair(seed = seed, curve = KeyCurve(Curve.X25519)) + val authenticationKeyPair = apollo.createKeyPair(seed = seed, curve = KeyCurve(Curve.ED25519)) + + val did = castor.createPeerDID( + arrayOf(keyAgreementKeyPair, authenticationKeyPair), + services = services, + ) + + if (updateMediator) { + return connectionManager + .mediationHandler + .updateKeyListWithDIDs(arrayOf(did)) + .then { + pluto.storePeerDID( + did = did, + privateKeys = arrayOf(keyAgreementKeyPair.privateKey, authenticationKeyPair.privateKey), + ) + } + .then { did } + } else { + pluto.storePeerDID( + did = did, + privateKeys = arrayOf(keyAgreementKeyPair.privateKey, authenticationKeyPair.privateKey), + ) + return Promise.resolve(did) + } + } + + fun parseInvitation(str: String): Promise { + val json = Json.decodeFromString(str) + val typeString: String = if (json.containsKey("type")) { + json["type"].toString().trim('"') + } else { + "" + } + + return when (findProtocolTypeByValue(typeString)) { + ProtocolType.PrismOnboarding -> parsePrismInvitation(str) + ProtocolType.Didcomminvitation -> Promise.resolve(parseOOBInvitation(str)) + else -> Promise.reject(PrismAgentError.unknownInvitationTypeError()) + } + } + + fun acceptInvitation(invitation: PrismOnboardingInvitation) { + @Serializable + data class SendDID(val did: String) + + val response = api.request( + HttpMethod.Post.toString(), + invitation.onboardEndpoint, + arrayOf(), + arrayOf(), + SendDID(invitation.from.toString()), + ).then { + if (it.status != 200) { + throw PrismAgentError.failedToOnboardError() + } + } + } + + fun signWith(did: DID, message: ByteArray): Signature { + val privateKey = pluto.getDIDPrivateKeysByDID(did)?.firstOrNull() ?: throw PrismAgentError.cannotFindDIDPrivateKey() + return apollo.signMessage(privateKey, message) + } + + fun parsePrismInvitation(str: String): Promise { + try { + val prismOnboarding = PrismOnboardingInvitation.prismOnboardingInvitationFromJsonString(str) + val url = prismOnboarding.onboardEndpoint + return createNewPeerDID( + arrayOf( + DIDDocument.Service( + id = "#didcomm-1", + type = arrayOf("DIDCommMessaging"), + serviceEndpoint = DIDDocument.ServiceEndpoint( + uri = url, + accept = arrayOf("DIDCommMessaging"), + routingKeys = arrayOf(), + ), + ), + ), + true, + ).then { + prismOnboarding.from = it + prismOnboarding + } + } catch (e: Exception) { + throw PrismAgentError.unknownInvitationTypeError() + } + } + + fun parseOOBInvitation(str: String): OutOfBandInvitation { + try { + return Json.decodeFromString(str) + } catch (e: Exception) { + throw PrismAgentError.unknownInvitationTypeError() + } + } +} diff --git a/prism-agent/src/jsMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/helpers/Api.kt b/prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/Api.kt similarity index 96% rename from prism-agent/src/jsMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/helpers/Api.kt rename to prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/Api.kt index 0cc784c10..e0f77a23b 100644 --- a/prism-agent/src/jsMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/helpers/Api.kt +++ b/prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/Api.kt @@ -13,6 +13,6 @@ actual interface Api { url: String, urlParameters: Array, httpHeaders: Array, - body: Any? + body: Any?, ): Promise } diff --git a/prism-agent/src/jsMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/helpers/ApiImpl.kt b/prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/ApiImpl.kt similarity index 93% rename from prism-agent/src/jsMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/helpers/ApiImpl.kt rename to prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/ApiImpl.kt index d6e51701f..85e468503 100644 --- a/prism-agent/src/jsMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/helpers/ApiImpl.kt +++ b/prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/ApiImpl.kt @@ -21,20 +21,20 @@ open class ApiImpl(override var client: HttpClient) : Api { url: String, urlParameters: Array, httpHeaders: Array, - body: Any? + body: Any?, ): Promise { val request = PrismShared.getRequestBuilder( httpMethod = HttpMethod(httpMethod), url = Url(url), urlParametersArray = urlParameters, httpHeadersArray = httpHeaders, - body = body + body = body, ) return GlobalScope.promise { val response = client.request(request) HttpResponse( status = response.status.value, - jsonString = response.bodyAsText() + jsonString = response.bodyAsText(), ) } } diff --git a/prism-agent/src/jsMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/helpers/HttpClient.kt b/prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/HttpClient.kt similarity index 100% rename from prism-agent/src/jsMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/helpers/HttpClient.kt rename to prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/HttpClient.kt diff --git a/prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/KMMPair.kt b/prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/KMMPair.kt new file mode 100644 index 000000000..9302b15fc --- /dev/null +++ b/prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/helpers/KMMPair.kt @@ -0,0 +1,12 @@ +package io.iohk.atala.prism.walletsdk.prismagent.helpers + +@OptIn(ExperimentalJsExport::class) +@JsExport +/** + * + * This class has no useful logic; it will help making a version of Kotlin *Pair* available in js. + * + * @param T the type of the first member. + * @param K the type of the second member. + */ +data class KMMPair(val first: T, val second: K) diff --git a/prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/mediation/DefaultMediationHandler.kt b/prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/mediation/DefaultMediationHandler.kt new file mode 100644 index 000000000..227c8f537 --- /dev/null +++ b/prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/mediation/DefaultMediationHandler.kt @@ -0,0 +1,117 @@ +package io.iohk.atala.prism.walletsdk.prismagent.mediation + +import io.iohk.atala.prism.apollo.uuid.UUID +import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Mercury +import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Pluto +import io.iohk.atala.prism.walletsdk.domain.models.AttachmentBase64 +import io.iohk.atala.prism.walletsdk.domain.models.AttachmentDescriptor +import io.iohk.atala.prism.walletsdk.domain.models.AttachmentJsonData +import io.iohk.atala.prism.walletsdk.domain.models.DID +import io.iohk.atala.prism.walletsdk.domain.models.Mediator +import io.iohk.atala.prism.walletsdk.domain.models.Message +import io.iohk.atala.prism.walletsdk.domain.models.PrismAgentError +import io.iohk.atala.prism.walletsdk.prismagent.helpers.KMMPair +import io.iohk.atala.prism.walletsdk.prismagent.protocols.mediation.MediationGrant +import io.iohk.atala.prism.walletsdk.prismagent.protocols.mediation.MediationKeysUpdateList +import io.iohk.atala.prism.walletsdk.prismagent.protocols.mediation.MediationRequest +import io.iohk.atala.prism.walletsdk.prismagent.protocols.pickup.PickupDelivery +import io.iohk.atala.prism.walletsdk.prismagent.protocols.pickup.PickupReceived +import io.iohk.atala.prism.walletsdk.prismagent.protocols.pickup.PickupRequest +import kotlin.js.Promise + +@OptIn(ExperimentalJsExport::class) +@JsExport +final class DefaultMediationHandler( + override val mediatorDID: DID, + private val mercury: Mercury, + private val store: MediatorRepository, +) : MediationHandler { + final class PlutoMediatorRepositoryImpl(private val pluto: Pluto) : MediatorRepository { + override fun getAllMediators(): Array { + return pluto.getAllMediators() + } + + override fun storeMediator(mediator: Mediator) { + pluto.storeMediator(mediator.mediatorDID, mediator.hostDID, mediator.routingDID) + } + } + + override var mediator: Mediator? = null + private set + + init { + this.mediator = null + } + + override fun bootRegisteredMediator(): Mediator? { + if (mediator == null) { + mediator = store.getAllMediators().first() + } + return mediator + } + + override fun achieveMediation(host: DID): Promise { + val requestMessage = MediationRequest(from = host, to = mediatorDID).makeMessage() + return mercury.sendMessageParseMessage(message = requestMessage) + .then { + val grantedMessage = it?.let { MediationGrant(it) } ?: throw PrismAgentError.mediationRequestFailedError() + val routingDID = DID(grantedMessage.body.routingDid) + Mediator( + id = UUID.randomUUID4().toString(), + mediatorDID = mediatorDID, + hostDID = host, + routingDID = routingDID, + ) + } + } + + override fun updateKeyListWithDIDs(dids: Array): Promise { + val keyListUpdateMessage = mediator?.let { + MediationKeysUpdateList( + from = it.hostDID, + to = it.mediatorDID, + recipientDids = dids, + ).makeMessage() + } ?: throw PrismAgentError.noMediatorAvailableError() + return keyListUpdateMessage + .let { message -> mercury.sendMessage(message).then { true } } + } + + override fun pickupUnreadMessages(limit: Int): Promise>> { + val requestMessage = mediator?.let { + PickupRequest( + from = it.hostDID, + to = it.mediatorDID, + body = PickupRequest.Body(null, limit.toString()), + ).makeMessage() + } ?: throw PrismAgentError.noMediatorAvailableError() + + return mercury.sendMessageParseMessage(requestMessage) + .then { + val receivedMessage = it?.let { PickupDelivery(it) } + receivedMessage?.let { delivery -> + delivery.attachments.mapNotNull { attachment: AttachmentDescriptor -> + val data = attachment.data + when (data) { + is AttachmentBase64 -> KMMPair(it.id, data.base64) + is AttachmentJsonData -> KMMPair(it.id, data.data) + else -> null + } + }.map { pair -> + KMMPair(pair.first, mercury.unpackMessage(pair.second)) + }.toTypedArray() + } ?: emptyArray() + } + } + + override fun registerMessagesAsRead(ids: Array): Promise { + val requestMessage = mediator?.let { + PickupReceived( + from = it.hostDID, + to = it.mediatorDID, + body = PickupReceived.Body(messageIdList = ids), + ).makeMessage() + } ?: throw PrismAgentError.noMediatorAvailableError() + return mercury.sendMessage(requestMessage).then { true } + } +} diff --git a/prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/mediation/MediationHandler.kt b/prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/mediation/MediationHandler.kt new file mode 100644 index 000000000..6b4d44f4b --- /dev/null +++ b/prism-agent/src/jsMain/kotlin/io.iohk.atala.prism.walletsdk.prismagent/mediation/MediationHandler.kt @@ -0,0 +1,24 @@ +package io.iohk.atala.prism.walletsdk.prismagent.mediation + +import io.iohk.atala.prism.walletsdk.domain.models.DID +import io.iohk.atala.prism.walletsdk.domain.models.Mediator +import io.iohk.atala.prism.walletsdk.domain.models.Message +import io.iohk.atala.prism.walletsdk.prismagent.helpers.KMMPair +import kotlin.js.Promise + +@OptIn(ExperimentalJsExport::class) +@JsExport +actual interface MediationHandler { + actual val mediator: Mediator? + actual val mediatorDID: DID + + fun bootRegisteredMediator(): Mediator? + + fun achieveMediation(host: DID): Promise + + fun updateKeyListWithDIDs(dids: Array): Promise + + fun pickupUnreadMessages(limit: Int): Promise>> + + fun registerMessagesAsRead(ids: Array): Promise +} diff --git a/prism-agent/src/jsMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PrismAgent.kt b/prism-agent/src/jsMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PrismAgent.kt deleted file mode 100644 index 8f8970f4a..000000000 --- a/prism-agent/src/jsMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PrismAgent.kt +++ /dev/null @@ -1,53 +0,0 @@ -package io.iohk.atala.prism.walletsdk.prismagent - -import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Apollo -import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Castor -import io.iohk.atala.prism.walletsdk.domain.buildingBlocks.Pluto -import io.iohk.atala.prism.walletsdk.domain.models.Seed -import io.iohk.atala.prism.walletsdk.prismagent.helpers.Api -import io.iohk.atala.prism.walletsdk.prismagent.helpers.ApiImpl -import io.iohk.atala.prism.walletsdk.prismagent.helpers.HttpClient -import io.ktor.client.plugins.contentnegotiation.ContentNegotiation -import io.ktor.serialization.kotlinx.json.json -import kotlinx.serialization.json.Json - -@JsExport -actual class PrismAgent actual constructor( - apollo: Apollo, - castor: Castor, - pluto: Pluto, - seed: Seed?, - api: Api? -) { - actual enum class State { - STOPED, STARTING, RUNNING, STOPING - } - - actual var state: State = State.STOPED - actual val seed: Seed - actual val apollo: Apollo - actual val castor: Castor - actual val pluto: Pluto - - private val api: Api - - init { - this.apollo = apollo - this.castor = castor - this.pluto = pluto - this.seed = seed ?: apollo.createRandomSeed().second - this.api = api ?: ApiImpl( - HttpClient { - install(ContentNegotiation) { - json( - Json { - ignoreUnknownKeys = true - prettyPrint = true - isLenient = true - } - ) - } - } - ) - } -} diff --git a/prism-agent/src/jsTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/ApiMock.kt b/prism-agent/src/jsTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/ApiMock.kt index d8e9b9252..4d069b811 100644 --- a/prism-agent/src/jsTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/ApiMock.kt +++ b/prism-agent/src/jsTest/kotlin/io.iohk.atala.prism.walletsdk.prismagent/ApiMock.kt @@ -17,9 +17,9 @@ class ApiMock(statusCode: HttpStatusCode, response: String) : ApiImpl( respond( content = response, status = statusCode, - headers = headersOf(HttpHeaders.ContentType, "application/json") + headers = headersOf(HttpHeaders.ContentType, "application/json"), ) - } + }, ) { install(ContentNegotiation) { json( @@ -27,8 +27,8 @@ class ApiMock(statusCode: HttpStatusCode, response: String) : ApiImpl( ignoreUnknownKeys = true prettyPrint = true isLenient = true - } + }, ) } - } + }, )