Send welcome event after relay acknowledgement...
This commit is contained in:
@@ -10,6 +10,9 @@ import fr.acinq.bitcoin.PublicKey
|
||||
|
||||
@Dao
|
||||
interface MarmotCommitResultDao {
|
||||
@Query("SELECT * FROM MarmotCommitResult WHERE id = :nostrEventId")
|
||||
suspend fun getMarmotCommitRequestById(nostrEventId: HexKey): MarmotCommitResult?
|
||||
|
||||
@Upsert
|
||||
suspend fun upsert(marmotCommitResult: MarmotCommitResult)
|
||||
}
|
||||
@@ -206,6 +206,7 @@ abstract class MarmotOutboundDao(
|
||||
framedCommitBytes = commitResult.preCommitExporterSecret,
|
||||
groupInfoBytes = commitResult.groupInfoBytes,
|
||||
userPublicKey = userPublicKey,
|
||||
peerKeyPackageEventId = peerKeyPackage.id,
|
||||
createdAt = Instant.fromEpochSeconds(commitEvent.createdAt)
|
||||
)
|
||||
)
|
||||
@@ -222,55 +223,66 @@ abstract class MarmotOutboundDao(
|
||||
if (isOneMemberInitialGroupCreation) {
|
||||
// Send welcome event to participant
|
||||
commitResult.welcomeBytes?.let { welcomeBytes ->
|
||||
val welcomeBase64 = Base64.encode(
|
||||
source = welcomeBytes
|
||||
)
|
||||
|
||||
// GiftWrap...
|
||||
val welcomeEvent = WelcomeEvent.build(
|
||||
welcomeBase64 = welcomeBase64,
|
||||
keyPackageEventId = peerKeyPackage.id,
|
||||
relays = relays.map { NormalizedRelayUrl(it) },
|
||||
deliveryWelcome(
|
||||
nostrGroupId = nostrGroupId,
|
||||
)
|
||||
// Compute welcomeEventId
|
||||
val welcomeEventId = EventHasher.hashId(
|
||||
pubKey = userPublicKey,
|
||||
kind = welcomeEvent.kind,
|
||||
tags = welcomeEvent.tags,
|
||||
createdAt = welcomeEvent.createdAt,
|
||||
content = welcomeEvent.content
|
||||
)
|
||||
|
||||
GiftWrapPayload(
|
||||
id = welcomeEventId,
|
||||
publicKey = userPublicKey,
|
||||
chatRoomId = nostrGroupId,
|
||||
kind = welcomeEvent.kind,
|
||||
tags = welcomeEvent.tags,
|
||||
content = welcomeEvent.content,
|
||||
createdAt = Instant.fromEpochSeconds(welcomeEvent.createdAt)
|
||||
)
|
||||
|
||||
// Save chatMessage for the invite...
|
||||
database.chatMessageDao().upsert(
|
||||
ChatMessage(
|
||||
content = "Invited participant to chat", // use profile.humanReadable...
|
||||
chatRoomId = nostrGroupId,
|
||||
senderPublicKey = userPublicKey,
|
||||
isUserMessage = true, // TODO: This is information message...
|
||||
giftWrapPayloadId = welcomeEventId,
|
||||
marmotGroupEventId = null,
|
||||
marmotInnerEventId = null
|
||||
)
|
||||
userPublicKey = userPublicKey,
|
||||
welcomeBytes = welcomeBytes,
|
||||
peerKeyPackageEventId = peerKeyPackage.id,
|
||||
relays = relays,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun deliveryWelcome(
|
||||
nostrGroupId: HexKey,
|
||||
userPublicKey: HexKey,
|
||||
welcomeBytes: ByteArray,
|
||||
peerKeyPackageEventId: HexKey,
|
||||
relays: List<String>,
|
||||
) {
|
||||
val welcomeBase64 = Base64.encode(
|
||||
source = welcomeBytes
|
||||
)
|
||||
|
||||
// GiftWrap...
|
||||
val welcomeEvent = WelcomeEvent.build(
|
||||
welcomeBase64 = welcomeBase64,
|
||||
keyPackageEventId = peerKeyPackageEventId,
|
||||
relays = relays.map { NormalizedRelayUrl(it) },
|
||||
nostrGroupId = nostrGroupId,
|
||||
)
|
||||
// Compute welcomeEventId
|
||||
val welcomeEventId = EventHasher.hashId(
|
||||
pubKey = userPublicKey,
|
||||
kind = welcomeEvent.kind,
|
||||
tags = welcomeEvent.tags,
|
||||
createdAt = welcomeEvent.createdAt,
|
||||
content = welcomeEvent.content
|
||||
)
|
||||
|
||||
GiftWrapPayload(
|
||||
id = welcomeEventId,
|
||||
publicKey = userPublicKey,
|
||||
chatRoomId = nostrGroupId,
|
||||
kind = welcomeEvent.kind,
|
||||
tags = welcomeEvent.tags,
|
||||
content = welcomeEvent.content,
|
||||
createdAt = Instant.fromEpochSeconds(welcomeEvent.createdAt)
|
||||
)
|
||||
|
||||
|
||||
// Save chatMessage for the invite...
|
||||
database.chatMessageDao().upsert(
|
||||
ChatMessage(
|
||||
content = "Invited participant to chat", // use profile.humanReadable...
|
||||
chatRoomId = nostrGroupId,
|
||||
senderPublicKey = userPublicKey,
|
||||
isUserMessage = true, // TODO: This is information message...
|
||||
giftWrapPayloadId = welcomeEventId,
|
||||
marmotGroupEventId = null,
|
||||
marmotInnerEventId = null
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun encryptedCommitEvent(
|
||||
|
||||
@@ -41,6 +41,8 @@ data class MarmotCommitResult( // TODO: Rename this to GiftWrapPayload...
|
||||
|
||||
val userPublicKey: HexKey,
|
||||
|
||||
val peerKeyPackageEventId: HexKey,
|
||||
|
||||
val chatRoomId: HexKey,
|
||||
|
||||
val isOneMemberInitialGroupCreation: Boolean,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package at.torch.compose.database.repository
|
||||
|
||||
import at.torch.compose.database.model.BroadcastNostrEventRequest
|
||||
import at.torch.compose.database.model.UnsignedNostrEvent
|
||||
import at.torch.compose.database.model.intermdiate.LocalAccount
|
||||
import at.torch.compose.nostr.Relays
|
||||
@@ -384,7 +385,7 @@ class DatabaseNostrRepository(
|
||||
}
|
||||
|
||||
override suspend fun broadcastProcessed(
|
||||
broadcastNostrEventRequest: at.torch.compose.database.model.BroadcastNostrEventRequest,
|
||||
broadcastNostrEventRequest: BroadcastNostrEventRequest,
|
||||
status: String
|
||||
) {
|
||||
database.broadcastNostrEventRequestDao().upsert(
|
||||
@@ -414,6 +415,25 @@ class DatabaseNostrRepository(
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
database.marmotCommitResultDao().getMarmotCommitRequestById(
|
||||
nostrEventId = broadcastNostrEventRequest.nostrEventId
|
||||
)?.let { marmotCommitResult ->
|
||||
if (marmotCommitResult.isOneMemberInitialGroupCreation.not()) {
|
||||
database.chatRoomDao().findChatRoomById(marmotCommitResult.chatRoomId)?.let { localChatRoom ->
|
||||
// TODO: Update status of participant Invitation.PENDING -> Invitation.SENT
|
||||
marmotCommitResult.welcomeBytes?.let { welcomeBytes ->
|
||||
database.marmotOutboundDao().deliveryWelcome(
|
||||
nostrGroupId = marmotCommitResult.chatRoomId,
|
||||
userPublicKey = marmotCommitResult.userPublicKey,
|
||||
welcomeBytes = welcomeBytes,
|
||||
peerKeyPackageEventId = marmotCommitResult.peerKeyPackageEventId,
|
||||
relays = Relays.DefaultDMRelayList.map { it.url } // TODO: Get localChatRoom relays...
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -742,7 +762,7 @@ class DatabaseNostrRepository(
|
||||
return database.relayDao().observePublicKeyRelays(publicKey)
|
||||
}
|
||||
|
||||
override suspend fun scheduleBroadcastNostrEventRequests(broadcastNostrEventRequests: List<at.torch.compose.database.model.BroadcastNostrEventRequest>) {
|
||||
override suspend fun scheduleBroadcastNostrEventRequests(broadcastNostrEventRequests: List<BroadcastNostrEventRequest>) {
|
||||
database.broadcastNostrEventRequestDao().insert(
|
||||
broadcastNostrEventRequests
|
||||
)
|
||||
|
||||
@@ -7,7 +7,13 @@ import androidx.lifecycle.viewmodel.viewModelFactory
|
||||
import at.torch.compose.database.model.SynchronizeNostrEventRequest
|
||||
import at.torch.compose.database.model.types.SynchronizationFilter
|
||||
import at.torch.compose.network.dto.toRelayDTO
|
||||
import at.torch.compose.network.relays.RelaysSocketManager
|
||||
import at.torch.compose.network.sockets.NostrIncomingMessage
|
||||
import at.torch.compose.network.sockets.NostrSocketClientFactory
|
||||
import at.torch.compose.repository.CachingImportRepository
|
||||
import at.torch.compose.repository.ChatRepository
|
||||
import at.torch.compose.repository.NostrRepository
|
||||
import at.torch.compose.repository.RelayRepository
|
||||
import co.touchlab.kermit.Logger
|
||||
import com.vitorpamplona.negentropy.Negentropy
|
||||
import com.vitorpamplona.negentropy.storage.StorageVector
|
||||
@@ -35,16 +41,16 @@ import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
class SynchronizationViewModel(
|
||||
val activeWalletStateFlow: StateFlow<ActiveWallet?>,
|
||||
val nostrRepository: at.torch.compose.repository.NostrRepository,
|
||||
val chatRepository: at.torch.compose.repository.ChatRepository,
|
||||
val relayRepository: at.torch.compose.repository.RelayRepository,
|
||||
val nostrRepository: NostrRepository,
|
||||
val chatRepository: ChatRepository,
|
||||
val relayRepository: RelayRepository,
|
||||
val scope: CoroutineScope,
|
||||
): ViewModel() {
|
||||
|
||||
val relaysSocketManager = at.torch.compose.network.relays.RelaysSocketManager(
|
||||
val relaysSocketManager = RelaysSocketManager(
|
||||
activeWalletStateFlow = activeWalletStateFlow,
|
||||
nostrSocketClientFactory = at.torch.compose.network.sockets.NostrSocketClientFactory,
|
||||
cachingImportRepository = at.torch.compose.repository.CachingImportRepository.NO_OP_CACHING_IMPORT_REPOSITORY,
|
||||
nostrSocketClientFactory = NostrSocketClientFactory,
|
||||
cachingImportRepository = CachingImportRepository.NO_OP_CACHING_IMPORT_REPOSITORY,
|
||||
relayRepository = relayRepository,
|
||||
)
|
||||
|
||||
@@ -55,9 +61,9 @@ class SynchronizationViewModel(
|
||||
|
||||
fun factory(
|
||||
activeWalletStateFlow: StateFlow<ActiveWallet?>,
|
||||
nostrRepository: at.torch.compose.repository.NostrRepository,
|
||||
chatRepository: at.torch.compose.repository.ChatRepository,
|
||||
relayRepository: at.torch.compose.repository.RelayRepository,
|
||||
nostrRepository: NostrRepository,
|
||||
chatRepository: ChatRepository,
|
||||
relayRepository: RelayRepository,
|
||||
scope: CoroutineScope,
|
||||
): ViewModelProvider.Factory = viewModelFactory {
|
||||
initializer {
|
||||
|
||||
Reference in New Issue
Block a user