From 39118ed3288fe3314720049681872e6a6197dec5 Mon Sep 17 00:00:00 2001 From: "William K. Santiago" Date: Sun, 23 Aug 2026 09:23:40 -0400 Subject: [PATCH 1/3] nip55: source the batch cap from keep-mobile via nip55MaxBatchSize() (#327) --- app/src/main/kotlin/io/privkey/keep/nip55/Nip55Activity.kt | 6 ++++-- keep.version | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/main/kotlin/io/privkey/keep/nip55/Nip55Activity.kt b/app/src/main/kotlin/io/privkey/keep/nip55/Nip55Activity.kt index 3dd5d605..5f54d559 100644 --- a/app/src/main/kotlin/io/privkey/keep/nip55/Nip55Activity.kt +++ b/app/src/main/kotlin/io/privkey/keep/nip55/Nip55Activity.kt @@ -27,6 +27,7 @@ import io.privkey.keep.uniffi.Nip55RequestType import io.privkey.keep.uniffi.Nip55RelayAuthGate import io.privkey.keep.uniffi.Nip55Response import io.privkey.keep.uniffi.nip55ExtractRelayHost +import io.privkey.keep.uniffi.nip55MaxBatchSize import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -103,8 +104,9 @@ class Nip55Activity : FragmentActivity() { private const val MAX_CONTENT_LENGTH = 1024 * 1024 private const val MAX_PUBKEY_LENGTH = 128 private const val MAX_EXTRA_LENGTH = 2048 - // Mirrors keep-mobile MAX_BATCH_SIZE; bounds accumulation against a spammy caller. - private const val MAX_BATCH_SIZE = 20 + // keep-mobile owns the batch cap; read it rather than duplicate the value and + // risk drift across the RMP boundary. Bounds accumulation against a spammy caller. + private val MAX_BATCH_SIZE = nip55MaxBatchSize().toInt() } override fun onCreate(savedInstanceState: Bundle?) { diff --git a/keep.version b/keep.version index dd9c1edf..716f736e 100644 --- a/keep.version +++ b/keep.version @@ -1 +1 @@ -3a6aa55094d48465583ac653438c5f86460497c3 \ No newline at end of file +bd8ca8d3945572923e372efd43231caae2e195d9 \ No newline at end of file From 0ca29f00236836088997365ee69103d815508b50 Mon Sep 17 00:00:00 2001 From: "William K. Santiago" Date: Sun, 23 Aug 2026 13:41:26 -0400 Subject: [PATCH 2/3] Repin keep.version to merged #974 commit 750d8f5 --- keep.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keep.version b/keep.version index 716f736e..e0191ee1 100644 --- a/keep.version +++ b/keep.version @@ -1 +1 @@ -bd8ca8d3945572923e372efd43231caae2e195d9 \ No newline at end of file +750d8f5f44304b009ef1c45313999447020dbd9a \ No newline at end of file From b18f1cf6e5ff0bf01b0178b79d33231952df4f1c Mon Sep 17 00:00:00 2001 From: "William K. Santiago" Date: Sun, 23 Aug 2026 13:45:35 -0400 Subject: [PATCH 3/3] Read nip55 batch cap at use site to preserve degraded-state failure mode --- .../main/kotlin/io/privkey/keep/nip55/Nip55Activity.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/io/privkey/keep/nip55/Nip55Activity.kt b/app/src/main/kotlin/io/privkey/keep/nip55/Nip55Activity.kt index 5f54d559..33451ca6 100644 --- a/app/src/main/kotlin/io/privkey/keep/nip55/Nip55Activity.kt +++ b/app/src/main/kotlin/io/privkey/keep/nip55/Nip55Activity.kt @@ -61,7 +61,9 @@ class Nip55Activity : FragmentActivity() { // pending list, the displayed snapshot the decision binds to, and the commit lock, // and enforces the three TOCTOU guards so a late-racing request can never be folded // into the signed set (gh #372). - private val gate = BatchConsentGate(MAX_BATCH_SIZE) { it.request.requestType } + private val gate by lazy { + BatchConsentGate(MAX_BATCH_SIZE) { it.request.requestType } + } private class PendingNip55Request( val request: Nip55Request, @@ -106,7 +108,11 @@ class Nip55Activity : FragmentActivity() { private const val MAX_EXTRA_LENGTH = 2048 // keep-mobile owns the batch cap; read it rather than duplicate the value and // risk drift across the RMP boundary. Bounds accumulation against a spammy caller. - private val MAX_BATCH_SIZE = nip55MaxBatchSize().toInt() + // Computed (not a stored val) so the FFI call happens at the use site during + // request handling rather than at class-init: in the degraded state where + // initializeKeepMobile() failed, a NIP-55 intent then fails on the signing path + // as a handled error rather than an opaque ExceptionInInitializerError at load. + private val MAX_BATCH_SIZE: Int get() = nip55MaxBatchSize().toInt() } override fun onCreate(savedInstanceState: Bundle?) {