Skip to content

Commit 4252ee9

Browse files
committed
Adding the proper way to manage the codec changes
1 parent e4b5e10 commit 4252ee9

File tree

8 files changed

+121
-51
lines changed

8 files changed

+121
-51
lines changed

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

+28
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import org.xmtp.android.library.codecs.ContentTypeIdBuilder
1212
import org.xmtp.android.library.codecs.DecodedComposite
1313
import org.xmtp.android.library.codecs.EncodedContent
1414
import org.xmtp.android.library.codecs.TextCodec
15+
import org.xmtp.android.library.messages.MessageV2Builder
1516
import org.xmtp.android.library.messages.walletAddress
1617

1718
data class NumberCodec(
@@ -112,4 +113,31 @@ class CodecTest {
112113
assertEquals("sup", part1.content())
113114
assertEquals(3.14, part2.content())
114115
}
116+
117+
@Test
118+
fun testCanGetPushInfoBeforeDecoded() {
119+
val codec = NumberCodec()
120+
Client.register(codec = codec)
121+
val fixtures = fixtures()
122+
val aliceClient = fixtures.aliceClient!!
123+
val aliceConversation =
124+
aliceClient.conversations.newConversation(fixtures.bob.walletAddress)
125+
aliceConversation.send(
126+
content = 3.14,
127+
options = SendOptions(contentType = codec.contentType),
128+
)
129+
val messages = aliceConversation.messages()
130+
assert(messages.isNotEmpty())
131+
132+
val message = MessageV2Builder.buildEncode(
133+
client = aliceClient,
134+
encodedContent = messages[0].encodedContent,
135+
topic = aliceConversation.topic,
136+
keyMaterial = aliceConversation.keyMaterial!!,
137+
codec = codec,
138+
)
139+
140+
assertEquals(false, message.shouldPush)
141+
assertEquals(true, message.senderHmac?.isNotEmpty())
142+
}
115143
}

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ class ConversationTest {
590590
encodedContent,
591591
topic = conversation.topic,
592592
keyMaterial = conversation.keyMaterial!!,
593-
shouldPush = true,
593+
codec = encoder,
594594
).messageV2,
595595
).toByteArray(),
596596
),
@@ -854,7 +854,6 @@ class ConversationTest {
854854
val directMessageV1 = Topic.directMessageV1(invalidId, "sd").description
855855
val directMessageV2 = Topic.directMessageV2(invalidId).description
856856
val preferenceList = Topic.preferenceList(invalidId).description
857-
val conversations = bobClient.conversations
858857

859858
// check if validation of topics no accept all types with invalid topic
860859
assertFalse(Topic.isValidTopic(privateStore))

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

+17-17
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class MessageTest {
5353
sender = alice,
5454
recipient = bob.toPublicKeyBundle(),
5555
message = content,
56-
timestamp = Date()
56+
timestamp = Date(),
5757
)
5858
assertEquals(aliceWallet.getPrivateKey().walletAddress, message1.senderAddress)
5959
assertEquals(bobWallet.getPrivateKey().walletAddress, message1.recipientAddress)
@@ -77,13 +77,13 @@ class MessageTest {
7777
InvitationV1.newBuilder().build().createDeterministic(
7878
sender = alice.toV2(),
7979
recipient = bob.toV2().getPublicKeyBundle(),
80-
context = invitationContext
80+
context = invitationContext,
8181
)
8282
val sealedInvitation = SealedInvitationBuilder.buildFromV1(
8383
sender = alice.toV2(),
8484
recipient = bob.toV2().getPublicKeyBundle(),
8585
created = Date(),
86-
invitation = invitationv1
86+
invitation = invitationv1,
8787
)
8888
val encoder = TextCodec()
8989
val encodedContent = encoder.encode(content = "Yo!")
@@ -92,14 +92,14 @@ class MessageTest {
9292
encodedContent,
9393
topic = invitationv1.topic,
9494
keyMaterial = invitationv1.aes256GcmHkdfSha256.keyMaterial.toByteArray(),
95-
shouldPush = true,
95+
codec = encoder,
9696
)
9797
val decoded = MessageV2Builder.buildDecode(
9898
id = "",
9999
client = client,
100100
message = message1.messageV2,
101101
keyMaterial = invitationv1.aes256GcmHkdfSha256.keyMaterial.toByteArray(),
102-
topic = invitationv1.topic
102+
topic = invitationv1.topic,
103103
)
104104
val result: String? = decoded.content()
105105
assertEquals(result, "Yo!")
@@ -119,7 +119,7 @@ class MessageTest {
119119
Numeric.hexStringToByteArray("d752fb09ee0390fe5902a1bd7b2f530da7e5b3a2bd91bad9df8fa284ab63327b86a59620fd3e2d2cf9183f46bd0fe75bda3caca893420c38416b1f")
120120
val additionalData =
121121
Numeric.hexStringToByteArray(
122-
"0aac020a940108d995eeadcc3012460a440a408f20c9fc03909edeb21538b0a568c423f8829e95c0270779ca704f72a45f02416f6071f6faaf421cac3bacc6bb432fc4b5f92bc4391349953c7c98f12253cdd710011a430a4104b7eb7b56059a4f08bf3dd8f1b329e21d486e39822f17db15bad0d7f689f6c8081ae2800b9014fc9ef355a39e10503fddfdfa0b07ccc1946c2275b10e660d5ded12920108e995eeadcc3012440a420a40da669aa014468ffe34d5b962443d8b1e353b1e39f252bbcffa5c6c70adf9f7d2484de944213f345bac869e8c1942657b9c59f6fc12d139171b22789bc76ffb971a430a4104901d3a7f728bde1f871bcf46d44dcf34eead4c532135913583268d35bd93ca0a1571a8cb6546ab333f2d77c3bb9839be7e8f27795ea4d6e979b6670dec20636d12aa020a920108bad3eaadcc3012440a420a4016d83a6e44ee8b9764f18fbb390f2a4049d92ff904ebd75c76a71d58a7f943744f8bed7d3696f9fb41ce450c5ab9f4a7f9a83e3d10f401bbe85e3992c5156d491a430a41047cebe3a23e573672363665d13220d368d37776e10232de9bd382d5af36392956dbd806f8b78bec5cdc111763e4ef4aff7dee65a8a15fee8d338c387320c5b23912920108bad3eaadcc3012440a420a404a751f28001f34a4136529a99e738279856da6b32a1ee9dba20849d9cd84b6165166a6abeae1139ed8df8be3b4594d9701309075f2b8d5d4de1f713fb62ae37e1a430a41049c45e552ac9f69c083bd358acac31a2e3cf7d9aa9298fef11b43252730949a39c68272302a61b548b13452e19272c119b5189a5d7b5c3283a37d5d9db5ed0c6818b286deaecc30"
122+
"0aac020a940108d995eeadcc3012460a440a408f20c9fc03909edeb21538b0a568c423f8829e95c0270779ca704f72a45f02416f6071f6faaf421cac3bacc6bb432fc4b5f92bc4391349953c7c98f12253cdd710011a430a4104b7eb7b56059a4f08bf3dd8f1b329e21d486e39822f17db15bad0d7f689f6c8081ae2800b9014fc9ef355a39e10503fddfdfa0b07ccc1946c2275b10e660d5ded12920108e995eeadcc3012440a420a40da669aa014468ffe34d5b962443d8b1e353b1e39f252bbcffa5c6c70adf9f7d2484de944213f345bac869e8c1942657b9c59f6fc12d139171b22789bc76ffb971a430a4104901d3a7f728bde1f871bcf46d44dcf34eead4c532135913583268d35bd93ca0a1571a8cb6546ab333f2d77c3bb9839be7e8f27795ea4d6e979b6670dec20636d12aa020a920108bad3eaadcc3012440a420a4016d83a6e44ee8b9764f18fbb390f2a4049d92ff904ebd75c76a71d58a7f943744f8bed7d3696f9fb41ce450c5ab9f4a7f9a83e3d10f401bbe85e3992c5156d491a430a41047cebe3a23e573672363665d13220d368d37776e10232de9bd382d5af36392956dbd806f8b78bec5cdc111763e4ef4aff7dee65a8a15fee8d338c387320c5b23912920108bad3eaadcc3012440a420a404a751f28001f34a4136529a99e738279856da6b32a1ee9dba20849d9cd84b6165166a6abeae1139ed8df8be3b4594d9701309075f2b8d5d4de1f713fb62ae37e1a430a41049c45e552ac9f69c083bd358acac31a2e3cf7d9aa9298fef11b43252730949a39c68272302a61b548b13452e19272c119b5189a5d7b5c3283a37d5d9db5ed0c6818b286deaecc30",
123123
)
124124
val ciphertext = CipherText.newBuilder().apply {
125125
aes256GcmHkdfSha256 = aes256GcmHkdfSha256.toBuilder().also {
@@ -198,7 +198,7 @@ class MessageTest {
198198
val convo = client.conversations.list()[0]
199199
convo.send(
200200
text = "hello deflate from kotlin again",
201-
SendOptions(compression = EncodedContentCompression.DEFLATE)
201+
SendOptions(compression = EncodedContentCompression.DEFLATE),
202202
)
203203
val message = convo.messages().lastOrNull()!!
204204
assertEquals("hello deflate from kotlin again", message.content())
@@ -240,7 +240,7 @@ class MessageTest {
240240
val convo = ConversationV1(
241241
client = client,
242242
peerAddress = "0xf4BF19Ed562651837bc11ff975472ABd239D35B5",
243-
sentAt = Date()
243+
sentAt = Date(),
244244
)
245245
convo.send(text = "hello from kotlin")
246246
val messages = convo.messages()
@@ -255,7 +255,7 @@ class MessageTest {
255255
val client = Client().create(account = wallet)
256256
val convo = client.conversations.newConversation(
257257
"0xf4BF19Ed562651837bc11ff975472ABd239D35B5",
258-
InvitationV1ContextBuilder.buildFromConversation("https://example.com/4")
258+
InvitationV1ContextBuilder.buildFromConversation("https://example.com/4"),
259259
)
260260

261261
convo.send(content = "hello from kotlin")
@@ -280,7 +280,7 @@ class MessageTest {
280280
fun testGetsV2ID() {
281281
val envelopeMessageData =
282282
Numeric.hexStringToByteArray(
283-
"12bf040a470880dedf9dafc0ff9e17123b2f786d74702f302f6d2d32536b644e355161305a6d694649357433524662667749532d4f4c76356a7573716e6465656e544c764e672f70726f746f12f3030af0030a20439174a205643a50af33c7670341338526dbb9c1cf0560687ff8a742e957282d120c090ba2b385b40639867493ce1abd037648c947f72e5c62e8691d7748e78f9a346ff401c97a628ebecf627d722829ff9cfb7d7c3e0b9e26b5801f2b5a39fd58757cc5771427bfefad6243f52cfc84b384fa042873ebeb90948aa80ca34f26ff883d64720c9228ed6bcd1a5c46953a12ae8732fd70260651455674e2e2c23bc8d64ed35562fef4cdfc55d38e72ad9cf2d597e68f48b6909967b0f5d0b4f33c0af3efce55c739fbc93888d20b833df15811823970a356b26622936564d830434d3ecde9a013f7433142e366f1df5589131e440251be54d5d6deef9aaaa9facac26eb54fb7b74eb48c5a2a9a2e2956633b123cc5b91dec03e4dba30683be03bd7510f16103d3f81712dccf2be003f2f77f9e1f162bc47f6c1c38a1068abd3403952bef31d75e8024e7a62d9a8cbd48f1872a0156abb559d01de689b4370a28454658957061c46f47fc5594808d15753876d4b5408b3a3410d0555c016e427dfceae9c05a4a21fd7ce4cfbb11b2a696170443cf310e0083b0a48e357fc2f00c688c0b56821c8a14c2bb44ddfa31d680dfc85efe4811e86c6aa3adfc373ad5731ddab83960774d98d60075b8fd70228da5d748bfb7a5334bd07e1cc4a9fbf3d5de50860d0684bb27786b5b4e00d415"
283+
"12bf040a470880dedf9dafc0ff9e17123b2f786d74702f302f6d2d32536b644e355161305a6d694649357433524662667749532d4f4c76356a7573716e6465656e544c764e672f70726f746f12f3030af0030a20439174a205643a50af33c7670341338526dbb9c1cf0560687ff8a742e957282d120c090ba2b385b40639867493ce1abd037648c947f72e5c62e8691d7748e78f9a346ff401c97a628ebecf627d722829ff9cfb7d7c3e0b9e26b5801f2b5a39fd58757cc5771427bfefad6243f52cfc84b384fa042873ebeb90948aa80ca34f26ff883d64720c9228ed6bcd1a5c46953a12ae8732fd70260651455674e2e2c23bc8d64ed35562fef4cdfc55d38e72ad9cf2d597e68f48b6909967b0f5d0b4f33c0af3efce55c739fbc93888d20b833df15811823970a356b26622936564d830434d3ecde9a013f7433142e366f1df5589131e440251be54d5d6deef9aaaa9facac26eb54fb7b74eb48c5a2a9a2e2956633b123cc5b91dec03e4dba30683be03bd7510f16103d3f81712dccf2be003f2f77f9e1f162bc47f6c1c38a1068abd3403952bef31d75e8024e7a62d9a8cbd48f1872a0156abb559d01de689b4370a28454658957061c46f47fc5594808d15753876d4b5408b3a3410d0555c016e427dfceae9c05a4a21fd7ce4cfbb11b2a696170443cf310e0083b0a48e357fc2f00c688c0b56821c8a14c2bb44ddfa31d680dfc85efe4811e86c6aa3adfc373ad5731ddab83960774d98d60075b8fd70228da5d748bfb7a5334bd07e1cc4a9fbf3d5de50860d0684bb27786b5b4e00d415",
284284
)
285285
val envelope = MessageApiOuterClass.Envelope.newBuilder().also {
286286
it.contentTopic = "/xmtp/0/m-2SkdN5Qa0ZmiFI5t3RFbfwIS-OLv5jusqndeenTLvNg/proto"
@@ -289,7 +289,7 @@ class MessageTest {
289289
}.build()
290290
val ints = arrayOf(
291291
80, 84, 15, 126, 14, 105, 216, 8, 61, 147, 153, 232, 103, 69, 219, 13,
292-
99, 118, 68, 56, 160, 94, 58, 22, 140, 247, 221, 172, 14, 188, 52, 88
292+
99, 118, 68, 56, 160, 94, 58, 22, 140, 247, 221, 172, 14, 188, 52, 88,
293293
)
294294
val bytes =
295295
ints.foldIndexed(ByteArray(ints.size)) { i, a, v -> a.apply { set(i, v.toByte()) } }
@@ -311,7 +311,7 @@ class MessageTest {
311311
val client = Client().buildFrom(bundle = keyBundle.v1)
312312
val conversationJSON =
313313
(""" {"version":"v2","topic":"/xmtp/0/m-2SkdN5Qa0ZmiFI5t3RFbfwIS-OLv5jusqndeenTLvNg/proto","keyMaterial":"ATA1L0O2aTxHmskmlGKCudqfGqwA1H+bad3W/GpGOr8=","peerAddress":"0x436D906d1339fC4E951769b1699051f020373D04","createdAt":"2023-01-26T22:58:45.068Z","context":{"conversationId":"pat/messageid","metadata":{}}} """).toByteArray(
314-
UTF_8
314+
UTF_8,
315315
)
316316
val decodedConversation = client.importConversation(conversationJSON)
317317
val conversation = ConversationV2(
@@ -320,12 +320,12 @@ class MessageTest {
320320
context = Context.newBuilder().build(),
321321
peerAddress = decodedConversation.peerAddress,
322322
client = client,
323-
header = Invitation.SealedInvitationHeaderV1.newBuilder().build()
323+
header = Invitation.SealedInvitationHeaderV1.newBuilder().build(),
324324
)
325325
val decodedMessage = conversation.decodeEnvelope(envelope)
326326
assertEquals(
327327
decodedMessage.id,
328-
"e42a7dd44d0e1214824eab093cb89cfe6f666298d0af2d54fe0c914c8b72eff3"
328+
"e42a7dd44d0e1214824eab093cb89cfe6f666298d0af2d54fe0c914c8b72eff3",
329329
)
330330
}
331331

@@ -366,12 +366,12 @@ class MessageTest {
366366
val aliceSharedSecret = alicePrivateBundle.sharedSecret(
367367
peer = bobPublicBundle,
368368
myPreKey = alicePublicBundle.preKey,
369-
isRecipient = true
369+
isRecipient = true,
370370
)
371371
val bobSharedSecret = bobPrivateBundle.sharedSecret(
372372
peer = alicePublicBundle,
373373
myPreKey = bobPublicBundle.preKey,
374-
isRecipient = false
374+
isRecipient = false,
375375
)
376376
assert(aliceSharedSecret.contentEquals(bobSharedSecret))
377377
}
@@ -390,7 +390,7 @@ class MessageTest {
390390
val secret = meBundle.sharedSecret(
391391
peer = youBundlePublic,
392392
myPreKey = meBundle.preKeysList[0].publicKey,
393-
isRecipient = true
393+
isRecipient = true,
394394
)
395395
assert(secretData.contentEquals(secret))
396396
}

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

+50-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import org.xmtp.android.library.codecs.Reaction
1111
import org.xmtp.android.library.codecs.ReactionAction
1212
import org.xmtp.android.library.codecs.ReactionCodec
1313
import org.xmtp.android.library.codecs.ReactionSchema
14+
import org.xmtp.android.library.messages.MessageV2Builder
1415
import org.xmtp.android.library.messages.walletAddress
1516

1617
@RunWith(AndroidJUnit4::class)
@@ -42,7 +43,7 @@ class ReactionTest {
4243
"action" to "added",
4344
"reference" to "abc123",
4445
"schema" to "shortcode",
45-
)
46+
),
4647
)
4748
it.content = "smile".toByteStringUtf8()
4849
}.build()
@@ -77,7 +78,7 @@ class ReactionTest {
7778
reference = messageToReact.id,
7879
action = ReactionAction.Added,
7980
content = "U+1F603",
80-
schema = ReactionSchema.Unicode
81+
schema = ReactionSchema.Unicode,
8182
)
8283

8384
aliceConversation.send(
@@ -94,4 +95,51 @@ class ReactionTest {
9495
assertEquals(ReactionSchema.Unicode, content?.schema)
9596
}
9697
}
98+
99+
@Test
100+
fun testShouldPushMustBeTrue() {
101+
Client.register(codec = ReactionCodec())
102+
103+
val fixtures = fixtures()
104+
val aliceClient = fixtures.aliceClient
105+
val aliceConversation =
106+
aliceClient.conversations.newConversation(fixtures.bob.walletAddress)
107+
108+
aliceConversation.send(text = "hey alice 2 bob")
109+
110+
val messageToReact = aliceConversation.messages()[0]
111+
112+
val attachment = Reaction(
113+
reference = messageToReact.id,
114+
action = ReactionAction.Added,
115+
content = "U+1F603",
116+
schema = ReactionSchema.Unicode,
117+
)
118+
119+
aliceConversation.send(
120+
content = attachment,
121+
options = SendOptions(contentType = ContentTypeReaction),
122+
)
123+
val messages = aliceConversation.messages()
124+
assertEquals(messages.size, 2)
125+
126+
val message = MessageV2Builder.buildEncode(
127+
client = aliceClient,
128+
encodedContent = messages[0].encodedContent,
129+
topic = aliceConversation.topic,
130+
keyMaterial = aliceConversation.keyMaterial!!,
131+
codec = ReactionCodec(),
132+
)
133+
134+
if (messages.size == 2) {
135+
val content: Reaction? = messages.first().content()
136+
assertEquals("U+1F603", content?.content)
137+
assertEquals(messageToReact.id, content?.reference)
138+
assertEquals(ReactionAction.Added, content?.action)
139+
assertEquals(ReactionSchema.Unicode, content?.schema)
140+
}
141+
142+
assertEquals(true, message.shouldPush)
143+
assertEquals(true, message.senderHmac?.isNotEmpty())
144+
}
97145
}

library/src/main/java/org/xmtp/android/library/Conversation.kt

+1-5
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,7 @@ sealed class Conversation {
140140
}
141141

142142
is V2 -> {
143-
conversationV2.prepareMessage(
144-
encodedContent = encodedContent,
145-
options = options,
146-
false,
147-
)
143+
conversationV2.prepareMessage(encodedContent = encodedContent, options = options)
148144
}
149145
}
150146
}

library/src/main/java/org/xmtp/android/library/ConversationV2.kt

+5-19
Original file line numberDiff line numberDiff line change
@@ -184,12 +184,7 @@ data class ConversationV2(
184184
}
185185

186186
fun send(encodedContent: EncodedContent, options: SendOptions?): String {
187-
val codec = Client.codecRegistry.find(options?.contentType)
188-
val preparedMessage = prepareMessage(
189-
encodedContent = encodedContent,
190-
options = options,
191-
shouldPush = shouldPush(codec, encodedContent.content.toStringUtf8()),
192-
)
187+
val preparedMessage = prepareMessage(encodedContent = encodedContent, options = options)
193188
return send(preparedMessage)
194189
}
195190

@@ -208,7 +203,7 @@ data class ConversationV2(
208203
encodedContent = encodedContent,
209204
topic = topic,
210205
keyMaterial = keyMaterial,
211-
shouldPush = shouldPush(codec, content),
206+
codec = codec,
212207
)
213208
val envelope = EnvelopeBuilder.buildFromString(
214209
topic = topic,
@@ -218,15 +213,6 @@ data class ConversationV2(
218213
return envelope.toByteArray()
219214
}
220215

221-
fun <Codec : ContentCodec<T>, T> shouldPush(codec: Codec, content: Any?): Boolean {
222-
val contentType = content as? T
223-
if (contentType != null) {
224-
return codec.shouldPush(content = content)
225-
} else {
226-
throw XMTPException("Codec invalid content")
227-
}
228-
}
229-
230216
fun <T> prepareMessage(content: T, options: SendOptions?): PreparedMessage {
231217
val codec = Client.codecRegistry.find(options?.contentType)
232218

@@ -250,20 +236,20 @@ data class ConversationV2(
250236
if (compression != null) {
251237
encoded = encoded.compress(compression)
252238
}
253-
return prepareMessage(encoded, options = options, shouldPush = shouldPush(codec, content))
239+
return prepareMessage(encoded, options = options)
254240
}
255241

256242
fun prepareMessage(
257243
encodedContent: EncodedContent,
258244
options: SendOptions?,
259-
shouldPush: Boolean,
260245
): PreparedMessage {
246+
val codec = Client.codecRegistry.find(options?.contentType)
261247
val message = MessageV2Builder.buildEncode(
262248
client = client,
263249
encodedContent = encodedContent,
264250
topic = topic,
265251
keyMaterial = keyMaterial,
266-
shouldPush = shouldPush,
252+
codec = codec,
267253
)
268254

269255
val newTopic = if (options?.ephemeral == true) ephemeralTopic else topic

library/src/main/java/org/xmtp/android/library/codecs/ReactionCodec.kt

+1-2
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,7 @@ data class ReactionCodec(override var contentType: ContentTypeId = ContentTypeRe
9898

9999
override fun shouldPush(content: Reaction): Boolean = when (content.action) {
100100
ReactionAction.Added -> true
101-
ReactionAction.Removed -> false
102-
ReactionAction.Unknown -> false
101+
else -> false
103102
}
104103
}
105104

0 commit comments

Comments
 (0)