Skip to content

Commit 3ec0620

Browse files
authored
fix: Deterministic topics are directional (#111)
* fix: determinstic topics being directional * update the direction of the comparison * test: update with more confirmation
1 parent 75a9566 commit 3ec0620

File tree

2 files changed

+60
-4
lines changed

2 files changed

+60
-4
lines changed

library/src/androidTest/java/org/xmtp/android/library/InvitationTest.kt

+55-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import org.xmtp.android.library.messages.generate
2121
import org.xmtp.android.library.messages.getInvitation
2222
import org.xmtp.android.library.messages.getPublicKeyBundle
2323
import org.xmtp.android.library.messages.header
24+
import org.xmtp.android.library.messages.sharedSecret
25+
import org.xmtp.android.library.messages.toPublicKeyBundle
2426
import org.xmtp.android.library.messages.toV2
2527
import java.util.Date
2628

@@ -131,15 +133,66 @@ class InvitationTest {
131133
Numeric.hexStringToByteArray("0x0a88030ac001088cd68df7923112220a209057f8d813314a2aae74e6c4c30f909c1c496b6037ce32a12c613558a8e961681a9201088cd68df7923112440a420a40501ae9b4f75d5bb5bae3ca4ecfda4ede9edc5a9b7fc2d56dc7325b837957c23235cc3005b46bb9ef485f106404dcf71247097ed509635590f4b7987b833d03661a430a4104e61a7ae511567f4a2b5551221024b6932d6cdb8ecf3876ec64cf29be4291dd5428fc0301963cdf6939978846e2c35fd38fcb70c64296a929f166ef6e4e91045712c20108b8d68df7923112220a2027707399474d417bf6aae4baa3d73b285bf728353bc3e156b0e32461ebb48f8c1a940108b8d68df7923112460a440a40fb96fa38c3f013830abb61cf6b39776e0475eb1379c66013569c3d2daecdd48c7fbee945dcdbdc5717d1f4ffd342c4d3f1b7215912829751a94e3ae11007e0a110011a430a4104952b7158cfe819d92743a4132e2e3ae867d72f6a08292aebf471d0a7a2907f3e9947719033e20edc9ca9665874bd88c64c6b62c01928065f6069c5c80c699924")
132134
val bobKeys = PrivateKeyBundle.parseFrom(bobKeyData).v1.toV2()
133135

134-
val invite = InvitationV1.newBuilder().build().createDeterministic(
136+
val aliceInvite = InvitationV1.newBuilder().build().createDeterministic(
135137
sender = aliceKeys,
136138
recipient = bobKeys.getPublicKeyBundle(),
137139
context = InvitationV1ContextBuilder.buildFromConversation("test")
138140
)
139141

140142
assertEquals(
141-
invite.topic,
143+
aliceInvite.topic,
142144
"/xmtp/0/m-4b52be1e8567d72d0bc407debe2d3c7fca2ae93a47e58c3f9b5c5068aff80ec5/proto"
143145
)
146+
147+
val bobInvite = InvitationV1.newBuilder().build().createDeterministic(
148+
sender = bobKeys,
149+
recipient = aliceKeys.getPublicKeyBundle(),
150+
context = InvitationV1ContextBuilder.buildFromConversation("test")
151+
)
152+
153+
assertEquals(
154+
aliceInvite.topic,
155+
"/xmtp/0/m-4b52be1e8567d72d0bc407debe2d3c7fca2ae93a47e58c3f9b5c5068aff80ec5/proto"
156+
)
157+
158+
assertEquals(
159+
bobInvite.topic,
160+
"/xmtp/0/m-4b52be1e8567d72d0bc407debe2d3c7fca2ae93a47e58c3f9b5c5068aff80ec5/proto"
161+
)
162+
}
163+
164+
@Test
165+
fun testCreatesDeterministicTopicsBidirectionally() {
166+
val aliceWallet = FakeWallet.generate()
167+
val bobWallet = FakeWallet.generate()
168+
val alice = PrivateKeyBundleV1.newBuilder().build().generate(wallet = aliceWallet)
169+
val bob = PrivateKeyBundleV1.newBuilder().build().generate(wallet = bobWallet)
170+
171+
val aliceInvite = InvitationV1.newBuilder().build().createDeterministic(
172+
sender = alice.toV2(),
173+
recipient = bob.toV2().getPublicKeyBundle(),
174+
context = null
175+
)
176+
177+
val bobInvite = InvitationV1.newBuilder().build().createDeterministic(
178+
sender = bob.toV2(),
179+
recipient = alice.toV2().getPublicKeyBundle(),
180+
context = null
181+
)
182+
183+
val aliceSharedSecret = alice.sharedSecret(
184+
bob.toPublicKeyBundle(),
185+
alice.getPreKeys(0).publicKey,
186+
false
187+
)
188+
189+
val bobSharedSecret = bob.sharedSecret(
190+
alice.toPublicKeyBundle(), bob.getPreKeys(0).publicKey,
191+
true
192+
)
193+
194+
assertEquals(aliceSharedSecret.contentToString(), bobSharedSecret.contentToString())
195+
196+
assertEquals(aliceInvite.topic, bobInvite.topic)
144197
}
145198
}

library/src/main/java/org/xmtp/android/library/messages/InvitationV1.kt

+5-2
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,17 @@ fun InvitationV1.createDeterministic(
6161
recipient: SignedPublicKeyBundle,
6262
context: Context? = null,
6363
): InvitationV1 {
64+
val myAddress = sender.toV1().walletAddress
65+
val theirAddress = recipient.walletAddress
66+
6467
val inviteContext = context ?: Context.newBuilder().build()
6568
val secret = sender.sharedSecret(
6669
peer = recipient,
6770
myPreKey = sender.preKeysList[0].publicKey,
68-
isRecipient = false
71+
isRecipient = myAddress < theirAddress
6972
)
7073

71-
val addresses = arrayOf(sender.toV1().walletAddress, recipient.walletAddress)
74+
val addresses = arrayOf(myAddress, theirAddress)
7275
addresses.sort()
7376

7477
val msg = if (context != null && !context.conversationId.isNullOrBlank()) {

0 commit comments

Comments
 (0)