From 087bb882f743ed606d9f34b032133c66345f8818 Mon Sep 17 00:00:00 2001 From: Cristian G <113917899+cristianIOHK@users.noreply.github.com> Date: Tue, 9 May 2023 16:19:02 -0400 Subject: [PATCH] fix: pick up messages and mark as read (#63) --- .../prism/walletsdk/domain/models/Message.kt | 17 ++++- .../prism/walletsdk/mercury/MercuryImpl.kt | 4 +- .../mercury/resolvers/DIDCommWrapper.kt | 23 +++---- .../walletsdk/prismagent/ConnectionManager.kt | 6 +- .../prism/walletsdk/prismagent/PrismAgent.kt | 16 +++++ .../mediation/BasicMediatorHandler.kt | 22 ++---- .../mediation/MediationKeysUpdateList.kt | 4 +- .../protocols/pickup/PickupReceived.kt | 15 +---- .../protocols/pickup/PickupRunner.kt | 67 +++++++++++++++++++ .../prismagent/shared/PrismShared.kt | 11 +-- .../protocols/pickup/PickupRunnerTest.kt | 62 +++++++++++++++++ .../atala/prism/sampleapp/FirstFragment.kt | 13 +++- .../atala/prism/sampleapp/FirstViewModel.kt | 27 +++++--- 13 files changed, 218 insertions(+), 69 deletions(-) create mode 100644 atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/pickup/PickupRunner.kt create mode 100644 atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/pickup/PickupRunnerTest.kt diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/Message.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/Message.kt index 54d2a651e..48c9fd3f9 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/Message.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/Message.kt @@ -2,6 +2,7 @@ package io.iohk.atala.prism.walletsdk.domain.models import io.iohk.atala.prism.apollo.uuid.UUID import kotlinx.datetime.Clock +import kotlinx.serialization.EncodeDefault import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json @@ -12,9 +13,9 @@ import kotlin.time.Duration.Companion.days data class Message @JvmOverloads constructor( val id: String = UUID.randomUUID4().toString(), val piuri: String, - val from: DID? = null, - val to: DID? = null, - val fromPrior: String? = null, + @EncodeDefault val from: DID? = null, + @EncodeDefault val to: DID? = null, + @EncodeDefault val fromPrior: String? = null, val body: String, val extraHeaders: Array = arrayOf(), val createdTime: String = Clock.System.now().toString(), @@ -73,6 +74,16 @@ data class Message @JvmOverloads constructor( SENT(0), RECEIVED(1), } + + companion object { + fun isBase64Attachment(data: AttachmentData): Boolean { + return data is AttachmentBase64 + } + + fun isJsonAttachment(data: AttachmentData): Boolean { + return data is AttachmentJsonData + } + } } fun getDirectionByValue(value: Int): Message.Direction { diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/mercury/MercuryImpl.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/mercury/MercuryImpl.kt index d5bb90c1b..cc9896d80 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/mercury/MercuryImpl.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/mercury/MercuryImpl.kt @@ -9,6 +9,8 @@ import io.iohk.atala.prism.walletsdk.domain.models.MercuryError import io.iohk.atala.prism.walletsdk.domain.models.Message import io.iohk.atala.prism.walletsdk.mercury.forward.ForwardMessage import io.iohk.atala.prism.walletsdk.prismagent.shared.KeyValue +import io.ktor.http.HttpHeaders +import org.didcommx.didcomm.common.Typ import org.didcommx.didcomm.utils.isDID import kotlin.jvm.Throws @@ -96,7 +98,7 @@ class MercuryImpl( "POST", service.serviceEndpoint.uri, emptyArray(), - arrayOf(KeyValue("Content-type", "application/didcomm-encrypted+json")), + arrayOf(KeyValue(HttpHeaders.ContentType, Typ.Encrypted.typ)), message ) return result.jsonString.toByteArray() diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/mercury/resolvers/DIDCommWrapper.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/mercury/resolvers/DIDCommWrapper.kt index 3b7afe9bd..fd189fd41 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/mercury/resolvers/DIDCommWrapper.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/mercury/resolvers/DIDCommWrapper.kt @@ -1,5 +1,6 @@ package io.iohk.atala.prism.walletsdk.mercury.resolvers +import com.nimbusds.jose.shaded.json.JSONObject 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 @@ -32,8 +33,8 @@ import org.didcommx.didcomm.common.Typ import org.didcommx.didcomm.message.Attachment import org.didcommx.didcomm.model.PackEncryptedParams import org.didcommx.didcomm.model.UnpackParams +import org.didcommx.didcomm.utils.fromJsonToMap import java.time.Instant.now -import kotlin.jvm.Throws class DIDCommWrapper(castor: Castor, pluto: Pluto, apollo: Apollo) : DIDCommProtocol { private val didDocResolver = DIDCommDIDResolver(castor) @@ -61,20 +62,20 @@ class DIDCommWrapper(castor: Castor, pluto: Pluto, apollo: Apollo) : DIDCommProt is JsonPrimitive -> { if (it.isString) { - bodyMap[key] = it.content + array.add(it.content) } else if (it.intOrNull != null) { - bodyMap[key] = it.int + array.add(it.int) } else if (it.doubleOrNull != null) { - bodyMap[key] = it.double + array.add(it.double) } else if (it.booleanOrNull != null) { - bodyMap[key] = it.boolean + array.add(it.boolean) } else { - bodyMap[key] = it + array.add(it) } } else -> { - bodyMap[key] = it + array.add(it) } } } @@ -132,7 +133,6 @@ class DIDCommWrapper(castor: Castor, pluto: Pluto, apollo: Apollo) : DIDCommProt pleaseAck = null, customHeaders = mapOf() ) - val builder = PackEncryptedParams.builder(didCommMsg, toString).forward(false).protectSenderId(false) didCommMsg.from?.let { builder.from(it) } val params = builder.build() @@ -166,8 +166,7 @@ class DIDCommWrapper(castor: Castor, pluto: Pluto, apollo: Apollo) : DIDCommProt } if (data is AttachmentJsonData) { - val json = Json.parseToJsonElement(data.data) - return Attachment.Data.Json(json.jsonObject.toMap()) + return Attachment.Data.Json(fromJsonToMap(data.data)) } if (data is AttachmentLinkData) { @@ -243,8 +242,8 @@ class DIDCommWrapper(castor: Castor, pluto: Pluto, apollo: Apollo) : DIDCommProt } val json = jsonObj["json"] - if (json is String) { - return AttachmentJsonData(json) + if (json is JSONObject) { + return AttachmentJsonData(JSONObject.toJSONString(json as Map)) } val links = jsonObj["links"] diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/ConnectionManager.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/ConnectionManager.kt index a608b6f23..e3a5161f6 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/ConnectionManager.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/ConnectionManager.kt @@ -50,8 +50,10 @@ class ConnectionManager( messagesIds.add(pair.first) messages.add(pair.second) } - mediationHandler.registerMessagesAsRead(messagesIds.toTypedArray()) - pluto.storeMessages(messages) + if (messagesIds.isNotEmpty()) { + mediationHandler.registerMessagesAsRead(messagesIds.toTypedArray()) + pluto.storeMessages(messages) + } } } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PrismAgent.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PrismAgent.kt index 1f23fb2c5..b313e9bc0 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PrismAgent.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PrismAgent.kt @@ -29,6 +29,7 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import kotlinx.serialization.Serializable @@ -50,6 +51,11 @@ class PrismAgent { private val api: Api private val connectionManager: ConnectionManager + private val flowState = MutableSharedFlow() + + fun getFlowState(): Flow { + return flowState + } internal constructor( apollo: Apollo, @@ -60,6 +66,9 @@ class PrismAgent { seed: Seed?, api: Api? ) { + GlobalScope.launch { + flowState.emit(State.STOPPED) + } this.apollo = apollo this.castor = castor this.pluto = pluto @@ -91,6 +100,9 @@ class PrismAgent { api: Api? = null, mediatorHandler: MediationHandler ) { + GlobalScope.launch { + flowState.emit(State.STOPPED) + } this.apollo = apollo this.castor = castor this.pluto = pluto @@ -119,6 +131,7 @@ class PrismAgent { return } state = State.STARTING + flowState.emit(State.STARTING) try { connectionManager.startMediator() } catch (error: PrismAgentError.NoMediatorAvailableError) { @@ -129,6 +142,7 @@ class PrismAgent { connectionManager.registerMediator(hostDID) } if (connectionManager.mediationHandler.mediator != null) { + flowState.emit(State.RUNNING) state = State.RUNNING } else { throw PrismAgentError.MediationRequestFailedError() @@ -139,8 +153,10 @@ class PrismAgent { if (state != State.RUNNING) { return } + flowState.emit(State.STOPPING) state = State.STOPPING fetchingMessagesJob?.cancel() + flowState.emit(State.STOPPED) state = State.STOPPED } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/mediation/BasicMediatorHandler.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/mediation/BasicMediatorHandler.kt index 8eebb5599..6f6b3be8a 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/mediation/BasicMediatorHandler.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/mediation/BasicMediatorHandler.kt @@ -3,9 +3,6 @@ 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 @@ -13,9 +10,9 @@ 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 io.iohk.atala.prism.walletsdk.prismagent.protocols.pickup.PickupRunner import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flow @@ -101,20 +98,9 @@ final class BasicMediatorHandler( return flow { val message = mercury.sendMessageParseResponse(requestMessage) - val receivedMessage = message?.let { PickupDelivery(it) } - val response = 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() - emit(response) + message?.let { + emit(PickupRunner(message, mercury).run()) + } } } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/mediation/MediationKeysUpdateList.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/mediation/MediationKeysUpdateList.kt index 45b2ba668..b461cc2ec 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/mediation/MediationKeysUpdateList.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/mediation/MediationKeysUpdateList.kt @@ -4,6 +4,8 @@ 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.EncodeDefault +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json @@ -53,7 +55,7 @@ final class MediationKeysUpdateList { } @Serializable - data class Update @JvmOverloads constructor(var recipientDid: String, var action: String = "add") + data class Update @JvmOverloads constructor(@SerialName("recipient_did")var recipientDid: String, @EncodeDefault var action: String = "add") @Serializable data class Body @JvmOverloads constructor(var updates: Array = emptyArray()) { diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/pickup/PickupReceived.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/pickup/PickupReceived.kt index 69e96ce03..7a96f1e03 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/pickup/PickupReceived.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/pickup/PickupReceived.kt @@ -4,6 +4,7 @@ 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.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json @@ -30,25 +31,15 @@ final class PickupReceived { 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 + body = Json.encodeToString(body) ) } @Serializable - data class Body(var messageIdList: Array) { + data class Body(@SerialName("message_id_list") var messageIdList: Array) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/pickup/PickupRunner.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/pickup/PickupRunner.kt new file mode 100644 index 000000000..49f7152c1 --- /dev/null +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/pickup/PickupRunner.kt @@ -0,0 +1,67 @@ +package io.iohk.atala.prism.walletsdk.prismagent.protocols.pickup + +import io.iohk.atala.prism.walletsdk.domain.buildingblocks.Mercury +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.Message +import io.iohk.atala.prism.walletsdk.domain.models.PrismAgentError +import io.iohk.atala.prism.walletsdk.prismagent.protocols.ProtocolType + +class PickupRunner(message: Message, private val mercury: Mercury) { + + enum class PickupResponseType(val type: String) { + STATUS("status"), + DELIVERY("delivery") + } + + data class PickupResponse(val type: PickupResponseType, val message: Message) + + data class PickupAttachment( + val attachmentId: String, + val data: String + ) + + private val message: PickupResponse + + init { + when (message.piuri) { + ProtocolType.PickupStatus.value -> { + this.message = PickupResponse(PickupResponseType.STATUS, message) + } + + ProtocolType.PickupDelivery.value -> { + this.message = PickupResponse(PickupResponseType.DELIVERY, message) + } + + else -> { + throw PrismAgentError.InvalidPickupDeliveryMessageError() + } + } + } + + suspend fun run(): Array> { + return if (message.type == PickupResponseType.DELIVERY) { + message.message.attachments + .mapNotNull { processAttachment(it) } + .map { Pair(it.attachmentId, mercury.unpackMessage(it.data)) } + .toTypedArray() + } else { + arrayOf() + } + } + + // TODO: Clean this method + private fun processAttachment(attachment: AttachmentDescriptor): PickupAttachment? { + return if (Message.isBase64Attachment(attachment.data)) { + PickupAttachment(attachmentId = attachment.id, data = (attachment.data as AttachmentBase64).base64) + } else if (Message.isJsonAttachment(attachment.data)) { + PickupAttachment( + attachmentId = attachment.id, + data = (attachment.data as AttachmentJsonData).data + ) + } else { + null + } + } +} diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/shared/PrismShared.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/shared/PrismShared.kt index cf8f85f6a..ea4cca9c7 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/shared/PrismShared.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/shared/PrismShared.kt @@ -32,16 +32,11 @@ object PrismShared { val builder = HttpRequestBuilder() for (header in httpHeaders) { - if ( - httpMethod == HttpMethod.Get && - header.key == HttpHeaders.ContentType && - header.value.contains(ContentType.Application.Json.contentSubtype) - ) { - continue - } builder.headers.append(header.key, header.value) } - builder.contentType(ContentType.Application.Json) + if (!builder.headers.contains(HttpHeaders.ContentType)) { + builder.contentType(ContentType.Application.Json) + } body?.let { builder.setBody(body) diff --git a/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/pickup/PickupRunnerTest.kt b/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/pickup/PickupRunnerTest.kt new file mode 100644 index 000000000..716bdb36f --- /dev/null +++ b/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/prismagent/protocols/pickup/PickupRunnerTest.kt @@ -0,0 +1,62 @@ +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.AttachmentDescriptor +import io.iohk.atala.prism.walletsdk.domain.models.AttachmentJsonData +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.MercuryMock +import io.iohk.atala.prism.walletsdk.prismagent.protocols.ProtocolType +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith +import kotlin.test.assertTrue + +class PickupRunnerTest { + + lateinit var message: Message + lateinit var mercury: MercuryMock + + @Before + fun setup() { + mercury = MercuryMock() + } + + @Test + fun testPickupRun_whenPiuriNotValid_thenInvalidPickupDeliveryMessageError() { + val message = Message(piuri = ProtocolType.DidcommRequestPresentation.value, body = "") + assertFailsWith(PrismAgentError.InvalidPickupDeliveryMessageError::class) { + PickupRunner(message, mercury) + } + } + + @Test + fun testPickupRun_whenMessageIsStatus_thenEmptyArrayMessages() = runTest { + val message = Message(piuri = ProtocolType.PickupStatus.value, body = "") + val messages = PickupRunner(message, mercury).run() + assertTrue(messages.isEmpty()) + } + + @Test + fun testPickupRun_whenMessageIsDelivery_thenArrayOfMessages() = runTest { + val attachmentData = AttachmentJsonData("{\"key\":\"value\"") + val attachmentId = UUID.randomUUID4().toString() + val message = Message( + piuri = ProtocolType.PickupDelivery.value, + body = "", + attachments = arrayOf( + AttachmentDescriptor( + id = attachmentId, + data = attachmentData + ) + ) + ) + mercury.unpackMessageResponse = message + val messages = PickupRunner(message, mercury).run() + assertTrue(messages.isNotEmpty()) + assertEquals(attachmentId, messages[0].first) + assertEquals(message, messages[0].second) + } +} diff --git a/sampleapp/src/main/java/io/iohk/atala/prism/sampleapp/FirstFragment.kt b/sampleapp/src/main/java/io/iohk/atala/prism/sampleapp/FirstFragment.kt index 38e798499..7ce72e498 100644 --- a/sampleapp/src/main/java/io/iohk/atala/prism/sampleapp/FirstFragment.kt +++ b/sampleapp/src/main/java/io/iohk/atala/prism/sampleapp/FirstFragment.kt @@ -40,6 +40,7 @@ class FirstFragment : Fragment() { } binding.sendMessage.setOnClickListener { // viewModel.sendTestMessage() + viewModel.createPeerDid() } binding.createPeerDID.setOnClickListener { viewModel.createPeerDid() @@ -54,12 +55,20 @@ class FirstFragment : Fragment() { private fun setupStreamObservers() { viewModel.messageListStream().observe(this.viewLifecycleOwner) { messages -> - messages.forEach { - binding.log.append(it.body) + var text = binding.log.text + messages.forEach { message -> + var textToAppend = "${message.id}: ${message.body} \n" + message.attachments.forEach { attachment -> + textToAppend += "Attachment ID: ${attachment.id}: \n" + } + binding.log.text = "$textToAppend $text" } } viewModel.notificationListStream().observe(this.viewLifecycleOwner) { binding.log.append(it) } + viewModel.agentStateStream().observe(this.viewLifecycleOwner) { + binding.log.append("Agent state: $it \n") + } } } diff --git a/sampleapp/src/main/java/io/iohk/atala/prism/sampleapp/FirstViewModel.kt b/sampleapp/src/main/java/io/iohk/atala/prism/sampleapp/FirstViewModel.kt index 97c1cefcc..e11edeeb6 100644 --- a/sampleapp/src/main/java/io/iohk/atala/prism/sampleapp/FirstViewModel.kt +++ b/sampleapp/src/main/java/io/iohk/atala/prism/sampleapp/FirstViewModel.kt @@ -27,6 +27,7 @@ import io.iohk.atala.prism.walletsdk.prismagent.mediation.MediationHandler import io.iohk.atala.prism.walletsdk.prismagent.models.OutOfBandInvitation import io.iohk.atala.prism.walletsdk.prismagent.models.PrismOnboardingInvitation import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json @@ -42,6 +43,7 @@ class FirstViewModel : ViewModel() { private lateinit var agent: PrismAgent private val messageList: MutableLiveData> = MutableLiveData(listOf()) private val notification: MutableLiveData = MutableLiveData("") + private val agentState: MutableLiveData = MutableLiveData("") init { } @@ -57,19 +59,15 @@ class FirstViewModel : ViewModel() { initializeAgent() agent.start() - createPeerDid() -// agent.startFetchingMessages() -// agent.handleReceivedMessagesEvents().collect { messages -> -// messages.map { -// if (it.piuri == ProtocolType.PrismOnboarding.value) { -// } else if (it.piuri == ProtocolType.Didcomminvitation.value) { -// } -// } -// } + agent.startFetchingMessages() + agent.handleReceivedMessagesEvents().collect { messages -> + messageList.postValue(messages) + } } } fun stopAgent() { + // TODO: lateinit property not initialized error agent?.let { GlobalScope.launch { agent.stopFetchingMessages() @@ -86,6 +84,10 @@ class FirstViewModel : ViewModel() { return notification } + fun agentStateStream(): LiveData { + return agentState + } + fun parseAndAcceptOOB(oobUrl: String) { GlobalScope.launch { val invitationType = agent.parseInvitation(oobUrl) @@ -190,7 +192,7 @@ class FirstViewModel : ViewModel() { } private fun initializeHandler() { - // old one: DID("did:peer:2.Ez6LScuuNiWo8rwnpYy5dXbq7JnVDv6yCgsAz6viRUWCUbCJk.Vz6MkfzL1tPPvpXioYDwuGQRdpATV1qb4x7mKmcXyhCmLcUGK.SeyJpZCI6Im5ldy1pZCIsInQiOiJkbSIsInMiOiJodHRwczovL21lZGlhdG9yLmpyaWJvLmtpd2kiLCJhIjpbImRpZGNvbW0vdjIiXX0"), + // Favio's mediatorDID = DID("did:peer:2.Ez6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y.Vz6Mkhh1e5CEYYq6JBUcTZ6Cp2ranCWRrv7Yax3Le4N59R6dd.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9hbGljZS5kaWQuZm1ncC5hcHAvIiwiciI6W10sImEiOlsiZGlkY29tbS92MiJdfQ"), handler = BasicMediatorHandler( mediatorDID = DID("did:peer:2.Ez6LSiekedip45fb5uYRZ9DV1qVvf3rr6GpvTGLhw3nKJ9E7X.Vz6MksZCnX3hQVPP4wWDGe1Dzq5LCk5BnGUnPmq3YCfrPpfuk.SeyJpZCI6Im5ldy1pZCIsInQiOiJkbSIsInMiOiJodHRwczovL21lZGlhdG9yLmpyaWJvLmtpd2kiLCJhIjpbImRpZGNvbW0vdjIiXX0"), mercury = mercury, @@ -207,5 +209,10 @@ class FirstViewModel : ViewModel() { seed = seed, mediatorHandler = handler ) + GlobalScope.launch() { + agent.getFlowState().collect { + agentState.postValue(it.name) + } + } } }