Skip to content

Commit

Permalink
feat: Consent Proof
Browse files Browse the repository at this point in the history
Added handling for consent proof in new conversation
Updated protos
  • Loading branch information
Alex Risch authored and Alex Risch committed Apr 18, 2024
1 parent 78893b8 commit 7a54600
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 2 deletions.
2 changes: 1 addition & 1 deletion library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ dependencies {
implementation 'org.web3j:crypto:5.0.0'
implementation "net.java.dev.jna:jna:5.13.0@aar"
api 'com.google.protobuf:protobuf-kotlin-lite:3.22.3'
api 'org.xmtp:proto-kotlin:3.47.0'
api 'org.xmtp:proto-kotlin:3.51.0'

testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'app.cash.turbine:turbine:0.12.1'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Test
import org.junit.runner.RunWith
import org.xmtp.android.library.codecs.TextCodec
Expand Down Expand Up @@ -172,4 +173,30 @@ class ConversationsTest {
sleep(2000)
assertEquals(allMessages.size, 2)
}

@Test
fun testSendConversationWithConsentSignature() {
val bo = PrivateKeyBuilder()
val alix = PrivateKeyBuilder()
val clientOptions =
ClientOptions(api = ClientOptions.Api(env = XMTPEnvironment.LOCAL, isSecure = false))
val boClient = Client().create(bo, clientOptions)
val alixClient = Client().create(alix, clientOptions)
val signedBytes = byteArrayOf(1, 2, 3)
val privateKeyBundle = alixClient.keys
val signedPrivateKey = privateKeyBundle.identityKey
val signature = runBlocking {
val privateKey = PrivateKeyBuilder.buildFromSignedPrivateKey(signedPrivateKey)
PrivateKeyBuilder(privateKey).sign(signedBytes)
}
val boConversation =
runBlocking { boClient.conversations.newConversation(alixClient.address, null, signature.toByteArray().toHex()) }
val alixConversations = runBlocking {
alixClient.conversations.list()
}
val alixConversation = alixConversations.find {
it.topic == boConversation.topic
}
assertNotNull(alixConversation)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ data class Conversations(
suspend fun newConversation(
peerAddress: String,
context: Invitation.InvitationV1.Context? = null,
consentProofSignature: String? = null,
): Conversation {
if (peerAddress.lowercase() == client.address.lowercase()) {
throw XMTPException("Recipient is sender")
Expand Down Expand Up @@ -223,7 +224,7 @@ data class Conversations(
// We don't have an existing conversation, make a v2 one
val recipient = contact.toSignedPublicKeyBundle()
val invitation = Invitation.InvitationV1.newBuilder().build()
.createDeterministic(client.keys, recipient, context)
.createDeterministic(client.keys, recipient, context, consentProofSignature)
val sealedInvitation =
sendInvitation(recipient = recipient, invitation = invitation, created = Date())
val conversationV2 = ConversationV2.create(
Expand Down Expand Up @@ -260,7 +261,9 @@ data class Conversations(
val invitations = listInvitations(pagination = pagination)
for (sealedInvitation in invitations) {
try {
// TODO: Verify Signature and approve
newConversations.add(Conversation.V2(conversation(sealedInvitation)))
if (sealedInvitation.)
} catch (e: Exception) {
Log.d(TAG, e.message.toString())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import com.google.protobuf.kotlin.toByteString
import org.xmtp.android.library.Crypto
import org.xmtp.android.library.toHex
import org.xmtp.proto.message.contents.Invitation
import org.xmtp.proto.message.contents.Invitation.ConsentProofPayload
import org.xmtp.proto.message.contents.Invitation.InvitationV1.Context
import java.security.SecureRandom
import java.util.Date

typealias InvitationV1 = org.xmtp.proto.message.contents.Invitation.InvitationV1

Expand All @@ -16,12 +18,16 @@ class InvitationV1Builder {
topic: Topic,
context: Context? = null,
aes256GcmHkdfSha256: Invitation.InvitationV1.Aes256gcmHkdfsha256,
consentProof: ConsentProofPayload? = null
): InvitationV1 {
return InvitationV1.newBuilder().apply {
this.topic = topic.description
if (context != null) {
this.context = context
}
if (consentProof != null) {
this.consentProof = consentProof
}
this.aes256GcmHkdfSha256 = aes256GcmHkdfSha256
}.build()
}
Expand Down Expand Up @@ -60,6 +66,7 @@ fun InvitationV1.createDeterministic(
sender: PrivateKeyBundleV2,
recipient: SignedPublicKeyBundle,
context: Context? = null,
consentProofSignature: String? = null
): InvitationV1 {
val myAddress = sender.toV1().walletAddress
val theirAddress = recipient.walletAddress
Expand Down Expand Up @@ -91,10 +98,17 @@ fun InvitationV1.createDeterministic(
this.keyMaterial = keyMaterial.toByteString()
}.build()

val consentProof = ConsentProofPayload.newBuilder().apply {
this.signature = consentProofSignature
this.timestamp = Date().time * 1_000_000
this.payloadVersion = Invitation.ConsentProofPayloadVersion.CONSENT_PROOF_PAYLOAD_VERSION_1
}.build()

return InvitationV1Builder.buildFromTopic(
topic = topic,
context = inviteContext,
aes256GcmHkdfSha256 = aes256GcmHkdfSha256,
consentProof = consentProof
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.xmtp.android.library.messages
import com.google.protobuf.kotlin.toByteString
import org.xmtp.android.library.CipherText
import org.xmtp.android.library.Crypto
import org.xmtp.proto.message.contents.consentProofPayload
import java.util.Date

typealias SealedInvitation = org.xmtp.proto.message.contents.Invitation.SealedInvitation
Expand Down Expand Up @@ -36,7 +37,9 @@ class SealedInvitationBuilder {
v1 = v1.toBuilder().also {
it.headerBytes = headerBytes.toByteString()
it.ciphertext = ciphertext

}.build()
consentProofPayload { }
}.build()
}
}
Expand Down

0 comments on commit 7a54600

Please sign in to comment.