Skip to content

Commit 71c8035

Browse files
authored
Batch query (#77)
* add api client with grpc kotlin * get api client setup with batch queries * just take a list of requests * write a test for it
1 parent effc4f5 commit 71c8035

File tree

6 files changed

+68
-1
lines changed

6 files changed

+68
-1
lines changed

library/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ dependencies {
8080
implementation 'org.web3j:crypto:5.0.0'
8181
implementation "net.java.dev.jna:jna:5.13.0@aar"
8282
api 'com.google.protobuf:protobuf-kotlin-lite:3.22.3'
83-
api 'org.xmtp:proto-kotlin:3.23.2'
83+
api 'org.xmtp:proto-kotlin:3.24.1'
8484

8585
testImplementation 'junit:junit:4.13.2'
8686
androidTestImplementation 'app.cash.turbine:turbine:0.12.1'

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

+26
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import org.xmtp.android.library.messages.generate
2020
import org.xmtp.android.library.messages.secp256K1Uncompressed
2121
import org.xmtp.android.library.messages.toPublicKeyBundle
2222
import org.xmtp.android.library.messages.walletAddress
23+
import org.xmtp.proto.message.api.v1.MessageApiOuterClass.QueryRequest
2324
import org.xmtp.proto.message.contents.Contact
2425
import org.xmtp.proto.message.contents.PrivateKeyOuterClass
2526
import java.util.Date
@@ -221,4 +222,29 @@ class LocalInstrumentedTest {
221222
val keys = PrivateKeyBundleV1Builder.buildFromBundle(bytes)
222223
Client().buildFrom(bundle = keys, options = options)
223224
}
225+
226+
@Test
227+
fun testBatchQuery() {
228+
val alice = PrivateKeyBuilder()
229+
val identity = PrivateKey.newBuilder().build().generate()
230+
val authorized = alice.createIdentity(identity)
231+
val authToken = authorized.createAuthToken()
232+
val api = GRPCApiClient(environment = XMTPEnvironment.LOCAL, secure = false)
233+
api.setAuthToken(authToken)
234+
val encryptedBundle = authorized.toBundle.encrypted(alice)
235+
val envelope = Envelope.newBuilder().also {
236+
it.contentTopic = Topic.userPrivateStoreKeyBundle(authorized.address).description
237+
it.timestampNs = Date().time * 1_000_000
238+
it.message = encryptedBundle.toByteString()
239+
}.build()
240+
runBlocking {
241+
api.publish(envelopes = listOf(envelope))
242+
}
243+
Thread.sleep(2_000)
244+
val request = QueryRequest.newBuilder().addContentTopics(Topic.userPrivateStoreKeyBundle(authorized.address).description).build()
245+
val result =
246+
runBlocking { api.batchQuery(requests = listOf(request)) }
247+
248+
assertEquals(result.responsesOrBuilderList.size, 1)
249+
}
224250
}

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

+8
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,14 @@ class FakeApiClient : ApiClient {
116116
return query(topic = topic, pagination = pagination).envelopesList
117117
}
118118

119+
override suspend fun batchQuery(requests: List<MessageApiOuterClass.QueryRequest>): MessageApiOuterClass.BatchQueryResponse {
120+
val response = query(requests.first().getContentTopics(0))
121+
122+
return MessageApiOuterClass.BatchQueryResponse.newBuilder().also {
123+
it.addResponses(response)
124+
}.build()
125+
}
126+
119127
override suspend fun query(
120128
topic: String,
121129
pagination: Pagination?,

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

+19
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import org.xmtp.android.library.messages.Pagination
1010
import org.xmtp.android.library.messages.Topic
1111
import org.xmtp.proto.message.api.v1.MessageApiGrpcKt
1212
import org.xmtp.proto.message.api.v1.MessageApiOuterClass
13+
import org.xmtp.proto.message.api.v1.MessageApiOuterClass.BatchQueryRequest
14+
import org.xmtp.proto.message.api.v1.MessageApiOuterClass.BatchQueryResponse
1315
import org.xmtp.proto.message.api.v1.MessageApiOuterClass.Cursor
1416
import org.xmtp.proto.message.api.v1.MessageApiOuterClass.Envelope
1517
import org.xmtp.proto.message.api.v1.MessageApiOuterClass.PublishRequest
@@ -29,6 +31,7 @@ interface ApiClient {
2931
): QueryResponse
3032

3133
suspend fun queryTopic(topic: Topic, pagination: Pagination? = null): QueryResponse
34+
suspend fun batchQuery(requests: List<QueryRequest>): BatchQueryResponse
3235
suspend fun envelopes(topic: String, pagination: Pagination? = null): List<Envelope>
3336
suspend fun publish(envelopes: List<Envelope>): PublishResponse
3437
suspend fun subscribe(topics: List<String>): Flow<Envelope>
@@ -126,6 +129,22 @@ data class GRPCApiClient(override val environment: XMTPEnvironment, val secure:
126129
return query(topic.description, pagination)
127130
}
128131

132+
override suspend fun batchQuery(
133+
requests: List<QueryRequest>,
134+
): BatchQueryResponse {
135+
val batchRequest = BatchQueryRequest.newBuilder().addAllRequests(requests).build()
136+
val headers = Metadata()
137+
138+
authToken?.let { token ->
139+
headers.put(AUTHORIZATION_HEADER_KEY, "Bearer $token")
140+
}
141+
headers.put(CLIENT_VERSION_HEADER_KEY, Constants.VERSION)
142+
if (appVersion != null) {
143+
headers.put(APP_VERSION_HEADER_KEY, appVersion)
144+
}
145+
return client.batchQuery(batchRequest, headers = headers)
146+
}
147+
129148
override suspend fun publish(envelopes: List<Envelope>): PublishResponse {
130149
val request = PublishRequest.newBuilder().addAllEnvelopes(envelopes).build()
131150
val headers = Metadata()

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

+6
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ import org.xmtp.android.library.messages.toPublicKeyBundle
3232
import org.xmtp.android.library.messages.toV2
3333
import org.xmtp.android.library.messages.walletAddress
3434
import org.xmtp.proto.message.api.v1.MessageApiOuterClass
35+
import org.xmtp.proto.message.api.v1.MessageApiOuterClass.BatchQueryResponse
36+
import org.xmtp.proto.message.api.v1.MessageApiOuterClass.QueryRequest
3537
import java.nio.charset.StandardCharsets
3638
import java.text.SimpleDateFormat
3739
import java.time.Instant
@@ -240,6 +242,10 @@ class Client() {
240242
return apiClient.queryTopic(topic = topic, pagination = pagination)
241243
}
242244

245+
suspend fun batchQuery(requests: List<QueryRequest>): BatchQueryResponse {
246+
return apiClient.batchQuery(requests)
247+
}
248+
243249
suspend fun subscribe(topics: List<String>): Flow<Envelope> {
244250
return apiClient.subscribe(topics = topics)
245251
}

library/src/test/java/org/xmtp/android/library/TestHelpers.kt

+8
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,14 @@ class FakeApiClient : ApiClient {
105105
return query(topic = topic.description, pagination)
106106
}
107107

108+
override suspend fun batchQuery(requests: List<MessageApiOuterClass.QueryRequest>): MessageApiOuterClass.BatchQueryResponse {
109+
val response = query(requests.first().getContentTopics(0))
110+
111+
return MessageApiOuterClass.BatchQueryResponse.newBuilder().also {
112+
it.addResponses(response)
113+
}.build()
114+
}
115+
108116
suspend fun send(envelope: Envelope) {
109117
stream.emit(envelope)
110118
}

0 commit comments

Comments
 (0)