Search…
Storing & Retrieving Relay Messages
Access the ability for your users to store and retrieve messages within their postbox.

Storing Relay Messages

Decentralized identity relays are designed to aid simplex communication as specified in Aries RFC 0046. Due to this, decentralized identity relays are built to support messages incoming to the receiver only. However, the Relay SDK is designed to also store outgoing messages from your user to peers. This lets users receive and store entire conversations in one convenient place.
Storing outgoing messages for persistence can be achieved by using the storeMessage API.
iOS
Android
To store an outgoing message, use the API storeMessage(withConnectionId:message).
connectionId is the postbox identifier, and message is the message to be stored.
​
An example of storing an outgoing message is as follows:
1
// connectionId is the existing postbox identifier
2
let message = "Hello relay!"
3
​
4
do {
5
let message = try await relayClient.storeMessage(withConnectionId: connectionId, message: message)
6
} catch {
7
// Handle error
8
}
Copied!
The storeMessage method is used to store outgoing messages in a postbox as shown below:
1
// val connectionId: String // Postbox identifier.
2
// val message: String // text to store in postbox.
3
launch {
4
try {
5
val storedMessage: RelayMessage = withContext(Dispatchers.IO) {
6
relayClient.storeMessage(connectionId, message)
7
}
8
} catch (e: SudoDIRelayClient.DIRelayException) {
9
// Handle/notify user of exception
10
}
11
}
Copied!
If an encrypted communication is used, encrypt the message before storing in the postbox.

Retrieving Relay Messages

Incoming and outgoing messages in a conversation can be retrieved using the single listMessages API.
iOS
Android
To get all messages in a postbox, use the API listMessages(withConnectionId).
​
An example of getting all messages is seen below.
1
// withConnectionId is the existing postbox identifier
2
​
3
do {
4
let messages = try await relayClient.listMessages(withConnectionId: connectionId)
5
} catch {
6
// Handle error
7
}
Copied!
The getMessages method is used to get all messages in a postbox as shown below:
1
// val connectionId: String // Postbox identifier.
2
launch {
3
try {
4
val messages: List<RelayMessage> = withContext(Dispatchers.IO) {
5
relayClient.listMessages(connectionId)
6
}
7
} catch (e: SudoDIRelayClient.DIRelayException) {
8
// Handle/notify user of exception
9
}
10
}
Copied!

Subscribing to Incoming Relay Messages

Real-time data is supported in the Relay SDK. Calling the subscription method in the SDK ensures that data relating to relay messages will be returned as they are received in the relay.
It is important to use subscriptions sparingly as they are resource intensive. It is recommended to only use them when a specific view is open. For example, it would be appropriate for the application to subscribe when a view of a list of relay messages is in the foreground. When the user navigates from this view, the application should cancel the subscription.
iOS
Android
To subscribe to real-time incoming messages, use the API subscribeToMessagesReceived(withConnectionId:resultHandler:).
Where connectionId is the postbox identifier used when instantiating the postbox.
​
An example of subscribing to incoming messages is seen below:
1
// A list of retrieved messages.
2
private var relayMessagesReceived: [RelayMessage] = []
3
​
4
// connectionId is the postbox identifier
5
do {
6
let token = try await self.relayClient.subscribeToMessagesReceived(withConnectionId: connectionId) { result in
7
switch result {
8
case .success(let message):
9
// Must keep a strong reference to keep connection open
10
self?.relayMessagesReceived.append(message)
11
// Handle the received message
12
case .failure(let error):
13
// Handle error/ present error to user
14
}
15
}
16
} catch {
17
// Handle error
18
}
Copied!
Note that for the connection to remain open, a strong reference needs to be kept of the message received.
To subscribe to incoming relay messages, use the subscribeToRelayEvents method. You must pass an identifier of the subscription and an instance of a class that implements the DIRelayEventSubscriber interface. This class will be notified of incoming messages, postbox deletion request updates, and any changes in the status of the subscription.

Setting Up A Subscription

To setup the subscription call the subscribeToRelayEvents method as so:
1
// val connectionId: String // Postbox identifier.
2
​
3
// A list of received messages
4
private var relayMessagesReceived = mutableListOf<RelayMessage>()
5
​
6
val subscriber = object : DIRelayEventSubscriber {
7
override fun messageIncoming(message: RelayMessage) {
8
// Handle incoming message.
9
relayMessagesReceived.add(message)
10
}
11
​
12
override fun postBoxDeleted(update: PostboxDeletionResult) {
13
// Handle postbox deleted update.
14
}
15
​
16
override fun connectionStatusChanged(state: DIRelayEventSubscriber.ConnectionState) {
17
// Handle changes in the state of the subscription connection
18
}
19
}
20
​
21
launch {
22
try {
23
withContext(Dispatchers.IO) {
24
relayClient.subscribeToRelayEvents(
25
connectionId,
26
subscriber
27
)
28
}
29
} catch (e: SudoDIRelayClient.DIRelayException) {
30
// Handle/notify user of exception
31
}
32
}
Copied!
There is also an extension function that allows you to pass lambdas instead of an object that implements the DIRelayEventSubscriber interface.
1
// val connectionId: String // Postbox identifier.
2
​
3
// A list of received messages
4
private var relayMessagesReceived = mutableListOf<RelayMessage>()
5
​
6
launch {
7
try {
8
withContext(Dispatchers.IO) {
9
relayClient.subscribeToRelayEvents(
10
connectionId,
11
onConnectionChange = { state: DIRelayEventSubscriber.ConnectionState ->
12
// Handle changes in the state of the subscription connection.
13
},
14
onMessageIncoming = { message: RelayMessage ->
15
// Handle incoming message.
16
relayMessagesReceived.add(message)
17
},
18
onPostboxDeleted = { update: PostboxDeletionResult ->
19
// Handle postbox deleted update.
20
}
21
)
22
}
23
} catch (e: SudoDIRelayClient.DIRelayException) {
24
// Handle/notify user of exception
25
}
26
}
Copied!

Cancelling A Subscription

To cancel a subscription, use the unsubscribeToRelayEvents or unsubscribeAll method. For example:
1
// val connectionId: String // Postbox identifier.
2
launch {
3
try {
4
withContext(Dispatchers.IO) {
5
relayClient.unsubscribeToRelayEvents(connectionId)
6
// or
7
relayClient.unsubscribeAll()
8
}
9
} catch (e: SudoDIRelayClient.DIRelayException) {
10
​
11
}
12
}
Copied!
This will ensure that the subscription is cancelled and system resources are freed.
In the Android Relay SDK, both postbox deletion and incoming message events are handled in the same subscription method.