From 41529b3e7aa2822c8e3930ff1c5759ad451e0395 Mon Sep 17 00:00:00 2001 From: Ovi Trif Date: Wed, 26 Aug 2026 17:02:28 +0200 Subject: [PATCH 1/2] fix: ship Android R8 consumer keep rules --- bindings/android/build.gradle.kts | 46 ++++++++++++++++++++++++++++- bindings/android/consumer-rules.pro | 31 +++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 bindings/android/consumer-rules.pro diff --git a/bindings/android/build.gradle.kts b/bindings/android/build.gradle.kts index 5204a2f..af6df74 100644 --- a/bindings/android/build.gradle.kts +++ b/bindings/android/build.gradle.kts @@ -1,5 +1,6 @@ import java.io.ByteArrayOutputStream import java.io.File +import java.util.zip.ZipFile plugins { id("com.android.library") version "8.5.2" @@ -142,8 +143,51 @@ val validateReleaseNativeLibraries by tasks.registering { } } +val validateConsumerKeepRules by tasks.registering { + group = "verification" + description = "Validates Android consumer keep rules exist for R8." + + val consumerRules = layout.projectDirectory.file("consumer-rules.pro") + inputs.file(consumerRules) + + doLast { + val file = consumerRules.asFile + if (!file.isFile || file.readText().isBlank()) { + throw GradleException("Android consumer keep rules missing at '${file.path}'") + } + } +} + tasks.matching { it.name == "bundleReleaseAar" || it.name.startsWith("publish") }.configureEach { - dependsOn(validateReleaseNativeLibraries) + dependsOn(validateReleaseNativeLibraries, validateConsumerKeepRules) +} + +tasks.matching { it.name == "bundleReleaseAar" }.configureEach { + doLast { + val aars = layout.buildDirectory.dir("outputs/aar").get().asFile + .listFiles() + ?.filter { it.isFile && it.name.endsWith(".aar") && it.name.contains("release") } + .orEmpty() + + if (aars.isEmpty()) { + throw GradleException("Release AAR missing after bundleReleaseAar") + } + + aars.forEach { aar -> + ZipFile(aar).use { zip -> + val entry = zip.getEntry("proguard.txt") + ?: throw GradleException( + "Release AAR is missing consumer keep rules (proguard.txt): '${aar.path}'" + ) + val text = zip.getInputStream(entry).bufferedReader().readText() + if (text.isBlank()) { + throw GradleException( + "Release AAR consumer keep rules are empty: '${aar.path}'" + ) + } + } + } + } } afterEvaluate { diff --git a/bindings/android/consumer-rules.pro b/bindings/android/consumer-rules.pro new file mode 100644 index 0000000..7aca292 --- /dev/null +++ b/bindings/android/consumer-rules.pro @@ -0,0 +1,31 @@ +# Consumer keep rules for vss-client Android bindings. +# Packaged into the AAR and applied automatically when a consuming app enables R8. + +# JNA reads @Structure.FieldOrder and public fields by name, and constructs +# Structure, Structure$ByValue, and Structure$ByReference types reflectively. +-keepclassmembers class com.synonym.vssclient.** extends com.sun.jna.Structure { + ; + (...); +} + +# JNA looks up Callback methods by name when building native function pointers. +-keepclassmembers class com.synonym.vssclient.** implements com.sun.jna.Callback { + ; +} + +# Native.register maps remaining native methods by exact C symbol name. +-keepclasseswithmembers,allowshrinking,includedescriptorclasses class com.synonym.vssclient.UniffiLib { + native ; +} +-keepclasseswithmembers,allowshrinking,includedescriptorclasses class com.synonym.vssclient.IntegrityCheckingUniffiLib { + native ; +} + +# @Structure.FieldOrder is read at runtime. +-keepattributes RuntimeVisibleAnnotations + +# JNA's AAR references desktop AWT types that are absent on Android. +-dontwarn java.awt.Component +-dontwarn java.awt.GraphicsEnvironment +-dontwarn java.awt.HeadlessException +-dontwarn java.awt.Window From 6362a59e6836c9a5334af59fbb16710eeb0b1386 Mon Sep 17 00:00:00 2001 From: Ovi Trif Date: Wed, 26 Aug 2026 18:51:57 +0200 Subject: [PATCH 2/2] chore: bump to 0.5.24 --- Cargo.lock | 2 +- Cargo.toml | 2 +- Package.swift | 2 +- bindings/android/gradle.properties | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7353350..fadd3d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2013,7 +2013,7 @@ dependencies = [ [[package]] name = "vss-rust-client-ffi" -version = "0.5.23" +version = "0.5.24" dependencies = [ "bip39", "bitcoin", diff --git a/Cargo.toml b/Cargo.toml index b2aad89..a82da74 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "vss-rust-client-ffi" -version = "0.5.23" +version = "0.5.24" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/Package.swift b/Package.swift index 0224ca1..0b4b95f 100644 --- a/Package.swift +++ b/Package.swift @@ -3,7 +3,7 @@ import PackageDescription -let tag = "v0.5.23" +let tag = "v0.5.24" let checksum = "655f78dfce27e58ae37ab448e03d36186182cc9066d7bcf0341a5e6787330b7a" let url = "https://github.com/synonymdev/vss-rust-client-ffi/releases/download/\(tag)/VssRustClientFfi.xcframework.zip" diff --git a/bindings/android/gradle.properties b/bindings/android/gradle.properties index e89a8f6..b241cfb 100644 --- a/bindings/android/gradle.properties +++ b/bindings/android/gradle.properties @@ -3,4 +3,4 @@ android.useAndroidX=true android.nonTransitiveRClass=true kotlin.code.style=official # project settings: -version=0.5.23 +version=0.5.24