-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(agent): add mediation and ability to send messages
- Loading branch information
1 parent
7cc738f
commit 504dc55
Showing
18 changed files
with
419 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
....atala.prism.domain/models/MediatorDID.kt → ...ohk.atala.prism.domain/models/Mediator.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
...agent/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/ConnectionManager.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package io.iohk.atala.prism.walletsdk.prismagent | ||
|
||
import io.iohk.atala.prism.domain.buildingBlocks.Castor | ||
import io.iohk.atala.prism.domain.buildingBlocks.Mercury | ||
import io.iohk.atala.prism.domain.buildingBlocks.Pluto | ||
import io.iohk.atala.prism.domain.models.DID | ||
import io.iohk.atala.prism.domain.models.Message | ||
import io.iohk.atala.prism.domain.models.PrismAgentError | ||
import io.iohk.atala.prism.walletsdk.prismagent.mediation.MediatorHandler | ||
import kotlinx.coroutines.flow.Flow | ||
import kotlinx.coroutines.flow.first | ||
import kotlinx.coroutines.flow.map | ||
|
||
class ConnectionManager { | ||
private val mercury: Mercury | ||
private val castor: Castor | ||
private val pluto: Pluto | ||
val mediatorHandler: MediatorHandler | ||
|
||
constructor( | ||
mercury: Mercury, | ||
castor: Castor, | ||
pluto: Pluto, | ||
mediatorHandler: MediatorHandler | ||
) { | ||
this.mercury = mercury | ||
this.castor = castor | ||
this.pluto = pluto | ||
this.mediatorHandler = mediatorHandler | ||
} | ||
|
||
@Throws() | ||
suspend fun startMediator() { | ||
mediatorHandler.bootRegisteredMediator() | ||
.first() | ||
} | ||
|
||
@Throws() | ||
suspend fun registerMediator(host: DID) { | ||
mediatorHandler.achieveMediation(host) | ||
.first() | ||
} | ||
|
||
@Throws() | ||
suspend fun sendMessage(message: Message): Message? { | ||
if (mediatorHandler.mediator == null) { | ||
throw PrismAgentError.noMediatorAvailableError() | ||
} | ||
pluto.storeMessage(message) | ||
return mercury.sendMessageParseMessage(message) | ||
} | ||
|
||
@Throws() | ||
fun awaitMessages(): Flow<Array<Message>> { | ||
return mediatorHandler.pickupUnreadMessages(NUMBER_OF_MESSAGES) | ||
.map { | ||
val messagesIds = it.map { it.first }.toTypedArray() | ||
mediatorHandler.registerMessagesAsRead(messagesIds) | ||
it.map { it.second }.toTypedArray() | ||
} | ||
.map { | ||
pluto.storeMessages(it) | ||
it | ||
} | ||
} | ||
|
||
companion object { | ||
const val NUMBER_OF_MESSAGES = 10 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
118 changes: 118 additions & 0 deletions
118
...onMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/mediation/BasicMediationHandler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package io.iohk.atala.prism.walletsdk.prismagent.mediation | ||
|
||
import io.iohk.atala.prism.apollo.uuid.UUID | ||
import io.iohk.atala.prism.domain.buildingBlocks.Mercury | ||
import io.iohk.atala.prism.domain.buildingBlocks.Pluto | ||
import io.iohk.atala.prism.domain.models.AttachmentBase64 | ||
import io.iohk.atala.prism.domain.models.AttachmentJsonData | ||
import io.iohk.atala.prism.domain.models.DID | ||
import io.iohk.atala.prism.domain.models.Mediator | ||
import io.iohk.atala.prism.domain.models.Message | ||
import io.iohk.atala.prism.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 BasicMediationHandler( | ||
override val mediatorDID: DID, | ||
private val mercury: Mercury, | ||
private val store: MediatorRepository | ||
) : MediatorHandler { | ||
final class PlutoMediatorRepositoryImpl(private val pluto: Pluto) : MediatorRepository { | ||
override fun getAllMediators(): Flow<Array<Mediator>> { | ||
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(): Flow<Mediator> { | ||
return mediator?.let { flow { emit(it) } } | ||
?: store.getAllMediators().map { it.first() } | ||
} | ||
|
||
override fun achieveMediation(host: DID): Flow<Mediator> { | ||
val requestMessage = MediationRequest(from = host, to = mediatorDID).makeMessage() | ||
return flow { | ||
emit(mercury.sendMessageParseMessage(message = requestMessage)) | ||
}.map { | ||
if (it != null) { | ||
val grantedMessage = it.let { MediationGrant(it) } | ||
val routingDID = DID(grantedMessage.body.routingDid) | ||
Mediator( | ||
id = UUID.randomUUID4().toString(), | ||
mediatorDID = mediatorDID, | ||
hostDID = host, | ||
routingDID = routingDID | ||
) | ||
} else { | ||
throw PrismAgentError.mediationRequestFailedError() | ||
} | ||
} | ||
} | ||
|
||
override suspend fun updateKeyListWithDIDs(dids: Array<DID>) { | ||
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<Array<Pair<String, Message>>> { | ||
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 { | ||
val data = it.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<String>) { | ||
val requestMessage = mediator?.let { | ||
PickupReceived( | ||
from = it.hostDID, | ||
to = it.mediatorDID, | ||
body = PickupReceived.Body(messageIdList = ids) | ||
).makeMessage() | ||
} ?: throw PrismAgentError.noMediatorAvailableError() | ||
mercury.sendMessage(requestMessage) | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
...c/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/mediation/MediatorHandler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package io.iohk.atala.prism.walletsdk.prismagent.mediation | ||
|
||
import io.iohk.atala.prism.domain.models.DID | ||
import io.iohk.atala.prism.domain.models.Mediator | ||
import io.iohk.atala.prism.domain.models.Message | ||
import kotlinx.coroutines.flow.Flow | ||
|
||
interface MediatorHandler { | ||
val mediator: Mediator? | ||
val mediatorDID: DID | ||
|
||
@Throws() | ||
fun bootRegisteredMediator(): Flow<Mediator?> | ||
|
||
@Throws() | ||
fun achieveMediation(host: DID): Flow<Mediator> | ||
|
||
@Throws() | ||
suspend fun updateKeyListWithDIDs(dids: Array<DID>) | ||
|
||
@Throws() | ||
fun pickupUnreadMessages(limit: Int): Flow<Array<Pair<String, Message>>> | ||
|
||
@Throws() | ||
suspend fun registerMessagesAsRead(ids: Array<String>) | ||
} |
Oops, something went wrong.