Skip to content

Commit 4d4c0f7

Browse files
Merge branch 'main' into gg/enhancement/add_sender_hmac_to_message_v2
2 parents 4252ee9 + 165f2b2 commit 4d4c0f7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1403
-216
lines changed

.github/workflows/lint.yml

+4-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ jobs:
1515
runs-on: ubuntu-latest
1616
steps:
1717
- uses: actions/checkout@v3
18-
18+
- uses: actions/setup-java@v3
19+
with:
20+
distribution: 'adopt'
21+
java-version: '17'
1922
- name: Gradle Run ktlint
2023
run: ./gradlew ktlintCheck --continue
2124
- uses: actions/upload-artifact@v2

.github/workflows/release.yml

+7-4
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,16 @@ jobs:
1010
runs-on: ubuntu-latest
1111
steps:
1212
- name: Checkout project sources
13-
uses: actions/checkout@v3
13+
uses: actions/checkout@v4
1414
with:
1515
fetch-depth: 0
16+
- name: Configure JDK
17+
uses: actions/setup-java@v4
18+
with:
19+
distribution: 'adopt'
20+
java-version: '17'
1621
- name: Setup Gradle
17-
uses: gradle/gradle-build-action@v2
18-
- name: Validate Gradle Wrapper
19-
uses: gradle/wrapper-validation-action@v1
22+
uses: gradle/actions/setup-gradle@v3
2023
- name: Run build with Gradle Wrapper
2124
run: ./gradlew build
2225
- name: Bump version and push tag

.github/workflows/test.yml

+22-26
Original file line numberDiff line numberDiff line change
@@ -15,46 +15,42 @@ jobs:
1515
runs-on: ubuntu-latest
1616
steps:
1717
- name: Checkout project sources
18-
uses: actions/checkout@v3
19-
- uses: actions/setup-java@v3
18+
uses: actions/checkout@v4
19+
- uses: actions/setup-java@v4
2020
with:
2121
distribution: 'adopt'
22-
java-version: '11'
22+
java-version: '17'
2323
- name: Setup Gradle
24-
uses: gradle/gradle-build-action@v2
25-
- name: Validate Gradle Wrapper
26-
uses: gradle/wrapper-validation-action@v1
27-
- name: Start local test server
28-
run: docker-compose -p xmtp -f dev/local/docker-compose.yml up -d
24+
uses: gradle/actions/setup-gradle@v3
25+
- name: Start Docker containers
26+
run: dev/up
2927
- name: Gradle Run Unit Tests
3028
run: ./gradlew library:testDebug
31-
- name: Stop local test server
32-
run: docker-compose -p xmtp -f dev/local/docker-compose.yml down
3329
library-integration:
3430
name: Library (Integration Tests)
35-
runs-on: macos-latest
31+
runs-on: ubuntu-latest
3632
steps:
37-
- name: Checkout project sources
38-
uses: actions/checkout@v3
39-
- uses: actions/setup-java@v3
33+
- name: Checkout
34+
uses: actions/checkout@v4
35+
with:
36+
fetch-depth: 0
37+
- name: Configure JDK
38+
uses: actions/setup-java@v4
4039
with:
4140
distribution: 'adopt'
42-
java-version: '11'
41+
java-version: '17'
42+
- name: Enable KVM group perms
43+
run: |
44+
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
45+
sudo udevadm control --reload-rules
46+
sudo udevadm trigger --name-match=kvm
4347
- name: Setup Gradle
44-
uses: gradle/gradle-build-action@v2
45-
- name: Validate Gradle Wrapper
46-
uses: gradle/wrapper-validation-action@v1
47-
- name: Set up Docker
48-
run: brew install docker docker-compose
49-
- name: Start Colima
50-
run: colima start
51-
- name: Start local test server
52-
run: docker-compose -p xmtp -f dev/local/docker-compose.yml up -d
48+
uses: gradle/actions/setup-gradle@v3
49+
- name: Start Docker containers
50+
run: dev/up
5351
- name: Gradle Run Integration Tests
5452
uses: reactivecircus/android-emulator-runner@v2
5553
with:
5654
api-level: 29
5755
script: ./gradlew connectedCheck
58-
- name: Stop local test server
59-
run: docker-compose -p xmtp -f dev/local/docker-compose.yml down
6056

build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
//}
1010

1111
plugins {
12-
id 'com.android.application' version '7.3.1' apply false
13-
id 'com.android.library' version '7.3.1' apply false
12+
id 'com.android.application' version '8.0.0' apply false
13+
id 'com.android.library' version '8.0.0' apply false
1414
id 'org.jetbrains.kotlin.android' version '1.8.0' apply false
1515
id 'io.github.gradle-nexus.publish-plugin' version "1.2.0"
1616
id "org.jetbrains.dokka" version "1.8.10"

dev/local/compose

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/bash
2+
set -eou pipefail
3+
4+
docker-compose -f dev/local/docker-compose.yml -p "xmtp-android" "$@"

dev/local/docker-compose.yml

+16-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
services:
2-
waku-node:
2+
node:
33
image: xmtp/node-go:latest
44
platform: linux/amd64
55
environment:
@@ -8,14 +8,27 @@ services:
88
- --store.enable
99
- --store.db-connection-string=postgres://postgres:xmtp@db:5432/postgres?sslmode=disable
1010
- --store.reader-db-connection-string=postgres://postgres:xmtp@db:5432/postgres?sslmode=disable
11+
- --mls-store.db-connection-string=postgres://postgres:xmtp@mlsdb:5432/postgres?sslmode=disable
12+
- --mls-validation.grpc-address=validation:50051
13+
- --api.enable-mls
1114
- --wait-for-db=30s
1215
- --api.authn.enable
1316
ports:
14-
- 9001:9001
1517
- 5555:5555
18+
- 5556:5556
1619
depends_on:
1720
- db
21+
22+
validation:
23+
image: ghcr.io/xmtp/mls-validation-service:main
24+
platform: linux/amd64
25+
1826
db:
1927
image: postgres:13
2028
environment:
21-
POSTGRES_PASSWORD: xmtp
29+
POSTGRES_PASSWORD: xmtp
30+
31+
mlsdb:
32+
image: postgres:13
33+
environment:
34+
POSTGRES_PASSWORD: xmtp

dev/local/up

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/bash
2+
set -eou pipefail
3+
script_dir="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
4+
5+
"${script_dir}"/compose pull
6+
"${script_dir}"/compose up -d --build

dev/up

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/bash
2+
set -eou pipefail
3+
4+
if [[ "${OSTYPE}" == "darwin"* ]]; then
5+
if ! which buf &>/dev/null; then brew install buf; fi
6+
if ! which shellcheck &>/dev/null; then brew install shellcheck; fi
7+
if ! which markdownlint &>/dev/null; then brew install markdownlint-cli; fi
8+
if ! java -version &>/dev/null; then
9+
brew install java
10+
sudo ln -sfn /opt/homebrew/opt/openjdk/libexec/openjdk.jdk \
11+
/Library/Java/JavaVirtualMachines/
12+
fi
13+
if ! kotlinc -version &>/dev/null; then brew install kotlin; fi
14+
fi
15+
16+
rustup update
17+
18+
dev/local/up

example/build.gradle

+11-14
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
buildscript {
22
ext {
3-
lifecycle_version = '2.6.0'
3+
lifecycle_version = '2.7.0'
44
}
55

66
}
@@ -36,34 +36,31 @@ android {
3636
}
3737
}
3838
compileOptions {
39-
sourceCompatibility JavaVersion.VERSION_11
40-
targetCompatibility JavaVersion.VERSION_11
39+
sourceCompatibility JavaVersion.VERSION_17
40+
targetCompatibility JavaVersion.VERSION_17
4141
}
4242
kotlinOptions {
43-
jvmTarget = '11'
43+
jvmTarget = '17'
4444
}
4545
buildFeatures {
4646
viewBinding true
4747
}
48-
configurations {
49-
all*.exclude module: "bcprov-jdk15to18" // Needed for dev.pinkroom.walletconnectkit
50-
}
5148
}
5249

5350
dependencies {
5451
implementation project(':library')
55-
implementation 'androidx.core:core-ktx:1.9.0'
52+
implementation 'androidx.core:core-ktx:1.12.0'
5653
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
5754
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
5855
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
5956
implementation 'androidx.appcompat:appcompat:1.6.1'
60-
implementation 'com.google.android.material:material:1.8.0'
61-
implementation 'com.google.firebase:firebase-messaging:23.1.2'
57+
implementation 'com.google.android.material:material:1.11.0'
58+
implementation 'com.google.firebase:firebase-messaging:23.4.0'
6259
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
63-
implementation 'androidx.fragment:fragment-ktx:1.5.5'
64-
implementation 'androidx.activity:activity-ktx:1.6.1'
60+
implementation 'androidx.fragment:fragment-ktx:1.6.2'
61+
implementation 'androidx.activity:activity-ktx:1.8.2'
6562
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
66-
implementation 'androidx.recyclerview:recyclerview:1.3.0'
63+
implementation 'androidx.recyclerview:recyclerview:1.3.2'
6764
implementation 'org.web3j:crypto:5.0.0'
6865

6966
// WalletConnect V2: core library + WalletConnectModal
@@ -72,7 +69,7 @@ dependencies {
7269
implementation("com.walletconnect:walletconnect-modal")
7370

7471
//Navigation Component
75-
def nav_version = "2.7.5"
72+
def nav_version = "2.7.6"
7673
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
7774
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
7875

example/src/main/java/org/xmtp/android/example/ClientManager.kt

+16-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.xmtp.android.example
22

3+
import android.content.Context
34
import androidx.annotation.UiThread
45
import kotlinx.coroutines.Dispatchers
56
import kotlinx.coroutines.GlobalScope
@@ -10,10 +11,21 @@ import org.xmtp.android.library.Client
1011
import org.xmtp.android.library.ClientOptions
1112
import org.xmtp.android.library.XMTPEnvironment
1213
import org.xmtp.android.library.messages.PrivateKeyBundleV1Builder
14+
import uniffi.xmtpv3.org.xmtp.android.library.codecs.GroupMembershipChangeCodec
1315

1416
object ClientManager {
1517

16-
val CLIENT_OPTIONS = ClientOptions(api = ClientOptions.Api(XMTPEnvironment.DEV, appVersion = "XMTPAndroidExample/v1.0.0"))
18+
fun clientOptions(appContext: Context?): ClientOptions {
19+
return ClientOptions(
20+
api = ClientOptions.Api(
21+
XMTPEnvironment.DEV,
22+
appVersion = "XMTPAndroidExample/v1.0.0",
23+
isSecure = true
24+
),
25+
enableAlphaMls = true,
26+
appContext = appContext
27+
)
28+
}
1729

1830
private val _clientState = MutableStateFlow<ClientState>(ClientState.Unknown)
1931
val clientState: StateFlow<ClientState> = _clientState
@@ -28,13 +40,14 @@ object ClientManager {
2840
}
2941

3042
@UiThread
31-
fun createClient(encodedPrivateKeyData: String) {
43+
fun createClient(encodedPrivateKeyData: String, appContext: Context) {
3244
if (clientState.value is ClientState.Ready) return
3345
GlobalScope.launch(Dispatchers.IO) {
3446
try {
3547
val v1Bundle =
3648
PrivateKeyBundleV1Builder.fromEncodedData(data = encodedPrivateKeyData)
37-
_client = Client().buildFrom(v1Bundle, CLIENT_OPTIONS)
49+
_client = Client().buildFrom(v1Bundle, clientOptions(appContext))
50+
Client.register(codec = GroupMembershipChangeCodec())
3851
_clientState.value = ClientState.Ready
3952
} catch (e: Exception) {
4053
_clientState.value = ClientState.Error(e.localizedMessage.orEmpty())

example/src/main/java/org/xmtp/android/example/MainActivity.kt

+16-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import org.xmtp.android.example.conversation.ConversationDetailActivity
2222
import org.xmtp.android.example.conversation.ConversationsAdapter
2323
import org.xmtp.android.example.conversation.ConversationsClickListener
2424
import org.xmtp.android.example.conversation.NewConversationBottomSheet
25+
import org.xmtp.android.example.conversation.NewGroupBottomSheet
2526
import org.xmtp.android.example.databinding.ActivityMainBinding
2627
import org.xmtp.android.example.pushnotifications.PushNotificationTokenManager
2728
import org.xmtp.android.example.utils.KeyUtil
@@ -35,6 +36,7 @@ class MainActivity : AppCompatActivity(),
3536
private lateinit var accountManager: AccountManager
3637
private lateinit var adapter: ConversationsAdapter
3738
private var bottomSheet: NewConversationBottomSheet? = null
39+
private var groupBottomSheet: NewGroupBottomSheet? = null
3840

3941
override fun onCreate(savedInstanceState: Bundle?) {
4042
super.onCreate(savedInstanceState)
@@ -48,7 +50,7 @@ class MainActivity : AppCompatActivity(),
4850
return
4951
}
5052

51-
ClientManager.createClient(keys)
53+
ClientManager.createClient(keys, this)
5254

5355
binding = ActivityMainBinding.inflate(layoutInflater)
5456
setContentView(binding.root)
@@ -67,6 +69,10 @@ class MainActivity : AppCompatActivity(),
6769
openConversationDetail()
6870
}
6971

72+
binding.groupFab.setOnClickListener {
73+
openGroupDetail()
74+
}
75+
7076
lifecycleScope.launch {
7177
repeatOnLifecycle(Lifecycle.State.STARTED) {
7278
ClientManager.clientState.collect(::ensureClientState)
@@ -86,6 +92,7 @@ class MainActivity : AppCompatActivity(),
8692

8793
override fun onDestroy() {
8894
bottomSheet?.dismiss()
95+
groupBottomSheet?.dismiss()
8996
super.onDestroy()
9097
}
9198

@@ -127,6 +134,7 @@ class MainActivity : AppCompatActivity(),
127134
is ClientManager.ClientState.Ready -> {
128135
viewModel.fetchConversations()
129136
binding.fab.visibility = View.VISIBLE
137+
binding.groupFab.visibility = View.VISIBLE
130138
}
131139
is ClientManager.ClientState.Error -> showError(clientState.message)
132140
is ClientManager.ClientState.Unknown -> Unit
@@ -193,4 +201,11 @@ class MainActivity : AppCompatActivity(),
193201
NewConversationBottomSheet.TAG
194202
)
195203
}
204+
private fun openGroupDetail() {
205+
groupBottomSheet = NewGroupBottomSheet.newInstance()
206+
groupBottomSheet?.show(
207+
supportFragmentManager,
208+
NewGroupBottomSheet.TAG
209+
)
210+
}
196211
}

example/src/main/java/org/xmtp/android/example/MainViewModel.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class MainViewModel : ViewModel() {
4242
viewModelScope.launch(Dispatchers.IO) {
4343
val listItems = mutableListOf<MainListItem>()
4444
try {
45-
val conversations = ClientManager.client.conversations.list()
45+
val conversations = ClientManager.client.conversations.list(includeGroups = true)
4646
PushNotificationTokenManager.xmtpPush.subscribe(conversations.map { it.topic })
4747
listItems.addAll(
4848
conversations.map { conversation ->
@@ -77,7 +77,7 @@ class MainViewModel : ViewModel() {
7777
val stream: StateFlow<MainListItem?> =
7878
stateFlow(viewModelScope, null) { subscriptionCount ->
7979
if (ClientManager.clientState.value is ClientManager.ClientState.Ready) {
80-
ClientManager.client.conversations.stream()
80+
ClientManager.client.conversations.streamAll()
8181
.flowWhileShared(
8282
subscriptionCount,
8383
SharingStarted.WhileSubscribed(1000L)

0 commit comments

Comments
 (0)