diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
index c6930dba26e38c3f9008d04f04d1210b5be1198a..3547ecd15aece3eab425ec28bd9114494f388060 100644
--- a/.idea/jarRepositories.xml
+++ b/.idea/jarRepositories.xml
@@ -36,5 +36,10 @@
       <option name="name" value="MavenRepo" />
       <option name="url" value="https://repo.maven.apache.org/maven2/" />
     </remote-repository>
+    <remote-repository>
+      <option name="id" value="maven2" />
+      <option name="name" value="maven2" />
+      <option name="url" value="https://gitlab.futo.org/api/v4/projects/130/packages/maven" />
+    </remote-repository>
   </component>
 </project>
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index efe0b5fdb19eae369093c2806dc0357d4814ead3..d9529dbfa623c84bc5a3289ccb727bd5731b7c8b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -28,6 +28,7 @@ allprojects {
                 groups.jitpack.group.each { includeGroup it }
             }
         }
+        maven { url 'https://gitlab.futo.org/api/v4/projects/130/packages/maven' }
         google {
             content {
                 groups.google.regex.each { includeGroupByRegex it }
diff --git a/library/rustCrypto/build.gradle b/library/rustCrypto/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..8e92527ce128faed1af88cd27ef148f0d0c35dfa
--- /dev/null
+++ b/library/rustCrypto/build.gradle
@@ -0,0 +1,2 @@
+configurations.maybeCreate("default")
+artifacts.add("default", file('matrix-rust-sdk-crypto.aar'))
diff --git a/library/rustCrypto/matrix-rust-sdk-crypto.aar b/library/rustCrypto/matrix-rust-sdk-crypto.aar
new file mode 100644
index 0000000000000000000000000000000000000000..0de1c2931e3fe526947c944326df6c86f696d7b1
Binary files /dev/null and b/library/rustCrypto/matrix-rust-sdk-crypto.aar differ
diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle
index 3a58f1d961d5d6cc77ecdf41e68670ee862a96e9..55c0794d36d71afc59ffd51de7dbca101aef155d 100644
--- a/matrix-sdk-android/build.gradle
+++ b/matrix-sdk-android/build.gradle
@@ -199,8 +199,8 @@ dependencies {
     //Bcrypt
     implementation 'at.favre.lib:bcrypt:0.9.0'
 
-    rustCryptoImplementation("org.matrix.rustcomponents:crypto-android:0.3.15")
-//    rustCryptoApi project(":library:rustCrypto")
+    rustCryptoImplementation("org.futo.rustcomponents:crypto-android:0.3.15.1")
+    //rustCryptoApi project(":library:rustCrypto")
 
     testImplementation libs.tests.junit
     // Note: version sticks to 1.9.2 due to https://github.com/mockk/mockk/issues/281
diff --git a/matrix-sdk-android/gradle-publish.gradle b/matrix-sdk-android/gradle-publish.gradle
index 3a3ace66e68c3cf405379bf9f91c842f80e6e6aa..76368c3d044f1ecc78e2254aa4c1af9f50e3a0bb 100644
--- a/matrix-sdk-android/gradle-publish.gradle
+++ b/matrix-sdk-android/gradle-publish.gradle
@@ -3,7 +3,7 @@ apply plugin: 'maven-publish'
 
 def groupIdString = "org.matrix.android"
 def artifactIdString = "matrix-sdk-android-rustCrypto"
-def versionName = "1.5.30.24"
+def versionName = "1.5.30.27"
 def artifactPath = "$buildDir/outputs/aar/$artifactIdString-release.aar"
 def publicationName = "release"
 def projectId = "16"
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt
index 2b69821b603d77d2efc8d347cf7cdaded78177a6..477d970f3e4bd3bcde555b582c7b916698449710 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt
@@ -30,9 +30,7 @@ import org.matrix.android.sdk.api.session.room.members.MembershipService
 import org.matrix.android.sdk.api.session.room.members.RoomMemberQueryParams
 import org.matrix.android.sdk.api.session.room.model.Membership
 import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
-import org.matrix.android.sdk.internal.database.helper.findLatestSessionInfo
 import org.matrix.android.sdk.internal.database.mapper.asDomain
-import org.matrix.android.sdk.internal.database.model.ChunkEntity
 import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntity
 import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields
 import org.matrix.android.sdk.internal.database.model.RoomMembersLoadStatusType
@@ -157,12 +155,7 @@ internal class DefaultMembershipService @AssistedInject constructor(
     }
 
     private suspend fun sendShareHistoryKeysIfNeeded(userId: String) {
-        if (!cryptoService.isShareKeysOnInviteEnabled()) return
-        // TODO not sure it's the right way to get the latest messages in a room
-        val sessionInfo = Realm.getInstance(monarchy.realmConfiguration).use {
-            ChunkEntity.findLatestSessionInfo(it, roomId)
-        }
-        cryptoService.sendSharedHistoryKeys(roomId, userId, sessionInfo)
+        cryptoService.sendSharedHistoryKeys(roomId, userId, null)
     }
 
     override suspend fun invite3pid(threePid: ThreePid) {
diff --git a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt
index 4646d74c9a17054c0d3485abb064f3af03a21330..e70c8b2d42608765871ffe8dd102b73b90f95cf8 100644
--- a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt
+++ b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt
@@ -277,7 +277,7 @@ internal class OlmMachine @Inject constructor(
             val events = adapter.toJson(toDevice ?: ToDeviceSyncResponse())
 
             // field pass in the list of unused fallback keys here
-            val receiveSyncChanges = inner.receiveSyncChanges(events, devices, counts, deviceUnusedFallbackKeyTypes)
+            val receiveSyncChanges = inner.receiveSyncChanges(events, devices, counts, deviceUnusedFallbackKeyTypes,"").toDeviceEvents.toString()
 
             val outAdapter = moshi.adapter<List<Event>>(
                     Types.newParameterizedType(
diff --git a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt
index d5069fe01012827b7de4e04e311904c5f6b7a719..3cb7aabb8cbda48715f0420506b0fa5a8f5ef231 100755
--- a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt
+++ b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt
@@ -735,7 +735,7 @@ internal class RustCryptoService @Inject constructor(
         return true
     }
 
-    override fun supportsShareKeysOnInvite() = false
+    override fun supportsShareKeysOnInvite() = true
 
     override fun supportsKeyWithheld() = true
     override fun supportsForwardedKeyWiththeld() = false
@@ -746,7 +746,7 @@ internal class RustCryptoService @Inject constructor(
         }
     }
 
-    override fun isShareKeysOnInviteEnabled() = false
+    override fun isShareKeysOnInviteEnabled() = true
 
     override fun setRoomUnBlockUnverifiedDevices(roomId: String) {
         cryptoStore.blockUnverifiedDevicesInRoom(roomId, false)
@@ -845,9 +845,9 @@ internal class RustCryptoService @Inject constructor(
     override fun removeSessionListener(listener: NewSessionListener) {
         megolmSessionImportManager.removeListener(listener)
     }
-/* ==========================================================================================
- * DEBUG INFO
- * ========================================================================================== */
+    /* ==========================================================================================
+     * DEBUG INFO
+     * ========================================================================================== */
 
     override fun toString(): String {
         return "DefaultCryptoService of $myUserId ($deviceId)"
@@ -901,7 +901,17 @@ internal class RustCryptoService @Inject constructor(
     override suspend fun prepareToEncrypt(roomId: String) = prepareToEncrypt.invoke(roomId, ensureAllMembersAreLoaded = true)
 
     override suspend fun sendSharedHistoryKeys(roomId: String, userId: String, sessionInfoSet: Set<SessionInfo>?) {
-        // TODO("Not yet implemented")
+        val cryptoInfo = cryptoStore.getRoomCryptoInfo(roomId) ?: return
+        if (cryptoInfo.shouldShareHistory.not()) return
+        withContext(coroutineDispatchers.crypto) {
+            downloadKeysIfNeeded(listOf(userId))
+            getUserDevices(userId)
+            with(olmMachine) {
+                inner().shareRoomHistoryKeys(roomId, listOf(userId))
+                updateTrackedUsers(listOf(userId))
+                outgoingRequestsProcessor.processOutgoingRequests(olmMachine)
+            }
+        }
     }
 
     companion object {
diff --git a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/store/db/migration/rust/ExtractUtils.kt b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/store/db/migration/rust/ExtractUtils.kt
index d99403fe194b1cce1648eb281aa3b351803bf5f1..d7ee5f488f864b8c98d8e07eb76cc581a258f9fd 100644
--- a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/store/db/migration/rust/ExtractUtils.kt
+++ b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/store/db/migration/rust/ExtractUtils.kt
@@ -100,7 +100,7 @@ fun RealmToMigrate.getPickledAccount(pickleKey: ByteArray): MigrationData {
             )
             MigrationData(
                     account = pickledAccount,
-                    pickleKey = pickleKey.map { it.toUByte() },
+                    pickleKey = pickleKey,
                     crossSigning = CrossSigningKeyExport(
                             masterKey = masterKey,
                             selfSigningKey = selfSignedKey,
@@ -153,7 +153,7 @@ fun RealmToMigrate.getPickledAccount(pickleKey: ByteArray): MigrationData {
 
                 migrationData = MigrationData(
                         account = pickledAccount,
-                        pickleKey = pickleKey.map { it.toUByte() },
+                        pickleKey = pickleKey,
                         crossSigning = CrossSigningKeyExport(
                                 masterKey = masterKey,
                                 selfSigningKey = selfSignedKey,