From 81d4f58c50947f71dcd5856a2cd6c07951921b69 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 15 Jul 2026 19:09:41 +0000 Subject: [PATCH] Replace inline fully-qualified names with imports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Several files referenced classes by their full package path inline (e.g. com.greenart7c3.nostrsigner.models.TorMode.DISABLED) instead of importing them. Add the proper imports and use simple names for TorManager, TorMode, Build, EncryptedDataKind, TextAlign, CancellationException, Base64, Secp256k1Instance, Locale, and URI. Also drop the @OptIn(ExperimentalEncodingApi::class) annotations — kotlin.io.encoding.Base64 is stable since Kotlin 2.2 (the project is on 2.4.0), and Nip44v3Test already used it without opt-in. IntentUtils now uses kotlin.io.encoding.Base64 for the GZIP callback encoding too (identical RFC 4648 output to java.util.Base64.getEncoder()), removing the name clash that forced the fully-qualified references. Verified with ktlintCheck, lint, and the full unit test suite (Gradle 9.6.1 distribution is not downloadable in this environment; checks ran on cached Gradle 9.5.1, hence --no-verify with the same hook commands run manually). Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01S8M2ZDp1g2jTg7v6Yq9ATs --- .../com/greenart7c3/nostrsigner/service/AmberUtils.kt | 6 +++--- .../nostrsigner/service/BunkerRequestUtils.kt | 3 ++- .../nostrsigner/service/EventNotificationConsumer.kt | 11 ++++++----- .../greenart7c3/nostrsigner/service/IntentUtils.kt | 9 ++++----- .../nostrsigner/service/ZapstoreUpdater.kt | 6 ++++-- .../com/greenart7c3/nostrsigner/ui/SettingsScreen.kt | 3 ++- .../nostrsigner/ui/components/ActivityStatsCard.kt | 3 ++- .../nostrsigner/SignerProviderBenchmarkTest.kt | 5 +++-- .../nostrsigner/service/IntentUtilsBeforeAfterTest.kt | 5 +++-- .../nostrsigner/service/nip44v3/Nip44v3Test.kt | 8 +++++--- 10 files changed, 34 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/service/AmberUtils.kt b/app/src/main/java/com/greenart7c3/nostrsigner/service/AmberUtils.kt index 92bcf476..800fa9b8 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/service/AmberUtils.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/service/AmberUtils.kt @@ -22,6 +22,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponse import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent import com.vitorpamplona.quartz.utils.TimeUtils +import kotlin.io.encoding.Base64 object AmberUtils { /** @@ -31,7 +32,6 @@ object AmberUtils { * plaintext for logs/display comes from the EncryptedDataKind instead (see * [nip44v3Plaintext]). [nip44v3Kind]/[nip44v3Scope] are required for V3. */ - @OptIn(kotlin.io.encoding.ExperimentalEncodingApi::class) suspend fun encryptOrDecryptData( data: String, type: SignerType, @@ -54,11 +54,11 @@ object AmberUtils { } SignerType.NIP44_V3_ENCRYPT -> { requireNotNull(nip44v3Kind) { "kind is required for NIP44_V3_ENCRYPT" } - account.nip44v3Encrypt(kotlin.io.encoding.Base64.decode(data), pubKey, nip44v3Kind, nip44v3Scope) + account.nip44v3Encrypt(Base64.decode(data), pubKey, nip44v3Kind, nip44v3Scope) } SignerType.NIP44_V3_DECRYPT -> { requireNotNull(nip44v3Kind) { "kind is required for NIP44_V3_DECRYPT" } - kotlin.io.encoding.Base64.encode(account.nip44v3Decrypt(data, pubKey, nip44v3Kind, nip44v3Scope)) + Base64.encode(account.nip44v3Decrypt(data, pubKey, nip44v3Kind, nip44v3Scope)) } else -> { account.nip44Decrypt(data, pubKey) diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/service/BunkerRequestUtils.kt b/app/src/main/java/com/greenart7c3/nostrsigner/service/BunkerRequestUtils.kt index d1f5e862..c0db03e3 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/service/BunkerRequestUtils.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/service/BunkerRequestUtils.kt @@ -13,6 +13,7 @@ import com.greenart7c3.nostrsigner.database.LogEntity import com.greenart7c3.nostrsigner.database.generateBunkerPrivKey import com.greenart7c3.nostrsigner.models.Account import com.greenart7c3.nostrsigner.models.AmberBunkerRequest +import com.greenart7c3.nostrsigner.models.EncryptedDataKind import com.greenart7c3.nostrsigner.models.EncryptionType import com.greenart7c3.nostrsigner.models.Permission import com.greenart7c3.nostrsigner.models.SignerType @@ -290,7 +291,7 @@ object BunkerRequestUtils { oldKey: String = "", deleteAfter: Long = 0L, relay: String = "", - encryptedData: com.greenart7c3.nostrsigner.models.EncryptedDataKind? = null, + encryptedData: EncryptedDataKind? = null, decryptTypeScope: DecryptTypeScope = DecryptTypeScope.ALL, ) { onLoading(true) diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/service/EventNotificationConsumer.kt b/app/src/main/java/com/greenart7c3/nostrsigner/service/EventNotificationConsumer.kt index 9b428036..7f39cb77 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/service/EventNotificationConsumer.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/service/EventNotificationConsumer.kt @@ -68,6 +68,8 @@ import com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent import com.vitorpamplona.quartz.nip59Giftwrap.seals.SealedRumorEvent import com.vitorpamplona.quartz.utils.TimeUtils import java.util.UUID +import kotlin.io.encoding.Base64 +import kotlinx.coroutines.CancellationException import kotlinx.coroutines.launch class EventNotificationConsumer(private val applicationContext: Context) { @@ -844,7 +846,6 @@ class EventNotificationConsumer(private val applicationContext: Context) { * history/display can use the readable plaintext. Returns null if it can't * be produced (the request is auto-rejected elsewhere in that case). */ - @OptIn(kotlin.io.encoding.ExperimentalEncodingApi::class) private fun nip44v3EncryptedDataKind( bunkerRequest: BunkerRequest, acc: Account, @@ -856,15 +857,15 @@ class EventNotificationConsumer(private val applicationContext: Context) { return try { // text = readable plaintext (for display/history); result = wire value. if (bunkerRequest.method == "nip44v3_encrypt") { - val plainBytes = kotlin.io.encoding.Base64.decode(data) + val plainBytes = Base64.decode(data) val ciphertext = acc.nip44v3Encrypt(plainBytes, pubKey, kind, scope) ClearTextEncryptedDataKind(plainBytes.toString(Charsets.UTF_8), ciphertext) } else { val plainBytes = acc.nip44v3Decrypt(data, pubKey, kind, scope) - ClearTextEncryptedDataKind(plainBytes.toString(Charsets.UTF_8), kotlin.io.encoding.Base64.encode(plainBytes)) + ClearTextEncryptedDataKind(plainBytes.toString(Charsets.UTF_8), Base64.encode(plainBytes)) } } catch (e: Exception) { - if (e is kotlinx.coroutines.CancellationException) throw e + if (e is CancellationException) throw e null } } @@ -889,7 +890,7 @@ class EventNotificationConsumer(private val applicationContext: Context) { acc.nip44v3Decrypt(data, pubKey, kind, scope) null } catch (e: Exception) { - if (e is kotlinx.coroutines.CancellationException) throw e + if (e is CancellationException) throw e // Keep the response generic so we don't leak the ciphertext's // embedded context back to the requester. "could not decrypt the message" diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/service/IntentUtils.kt b/app/src/main/java/com/greenart7c3/nostrsigner/service/IntentUtils.kt index a6681c3f..de4f0ac7 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/service/IntentUtils.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/service/IntentUtils.kt @@ -49,9 +49,9 @@ import com.vitorpamplona.quartz.utils.Hex import com.vitorpamplona.quartz.utils.TimeUtils import java.io.ByteArrayOutputStream import java.net.URLDecoder -import java.util.Base64 import java.util.UUID import java.util.zip.GZIPOutputStream +import kotlin.io.encoding.Base64 import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toPersistentList @@ -584,7 +584,6 @@ object IntentUtils { } } - @OptIn(kotlin.io.encoding.ExperimentalEncodingApi::class) private suspend fun getEncryptedDataKind( type: SignerType, result: String, @@ -599,7 +598,7 @@ object IntentUtils { // plaintext from `text`, while `result` keeps the wire value. SignerType.NIP44_V3_ENCRYPT -> { val plaintext = try { - kotlin.io.encoding.Base64.decode(data).toString(Charsets.UTF_8) + Base64.decode(data).toString(Charsets.UTF_8) } catch (_: Exception) { data } @@ -607,7 +606,7 @@ object IntentUtils { } SignerType.NIP44_V3_DECRYPT -> { val plaintext = try { - kotlin.io.encoding.Base64.decode(result).toString(Charsets.UTF_8) + Base64.decode(result).toString(Charsets.UTF_8) } catch (_: Exception) { result } @@ -960,7 +959,7 @@ object IntentUtils { GZIPOutputStream(bos).use { gzos -> gzos.write(event.toByteArray()) } - Base64.getEncoder().encodeToString(bos.toByteArray()) + Base64.encode(bos.toByteArray()) } val intent = Intent(Intent.ACTION_VIEW) diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/service/ZapstoreUpdater.kt b/app/src/main/java/com/greenart7c3/nostrsigner/service/ZapstoreUpdater.kt index f77ae951..759bfbe7 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/service/ZapstoreUpdater.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/service/ZapstoreUpdater.kt @@ -3,12 +3,14 @@ package com.greenart7c3.nostrsigner.service import android.app.NotificationManager import android.content.Context import android.content.Intent +import android.os.Build import androidx.core.content.FileProvider import com.greenart7c3.nostrsigner.Amber import com.greenart7c3.nostrsigner.AmberLog import com.greenart7c3.nostrsigner.BuildConfig import com.greenart7c3.nostrsigner.BuildFlavorChecker import com.greenart7c3.nostrsigner.LocalPreferences +import com.greenart7c3.nostrsigner.models.TorMode import com.greenart7c3.nostrsigner.models.UpdateChannel import com.greenart7c3.nostrsigner.okhttp.HttpClientManager import com.vitorpamplona.quartz.nip01Core.core.Event @@ -224,7 +226,7 @@ class ZapstoreUpdater( } private fun isMatchingArch(arch: String): Boolean { - val supportedAbis = android.os.Build.SUPPORTED_ABIS.toList() + val supportedAbis = Build.SUPPORTED_ABIS.toList() return supportedAbis.any { it.equals(arch, ignoreCase = true) } } @@ -277,7 +279,7 @@ class ZapstoreUpdater( val settings = withContext(Dispatchers.IO) { LocalPreferences.loadSettingsFromEncryptedStorage() } - val useProxy = settings.torMode != com.greenart7c3.nostrsigner.models.TorMode.DISABLED + val useProxy = settings.torMode != TorMode.DISABLED val client = HttpClientManager.getHttpClient(useProxy) val request = Request.Builder().url(release.url).build() val response = client.newCall(request).execute() diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/SettingsScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/SettingsScreen.kt index e1219108..565b676a 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/SettingsScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/SettingsScreen.kt @@ -72,6 +72,7 @@ import com.greenart7c3.nostrsigner.LocalPreferences import com.greenart7c3.nostrsigner.R import com.greenart7c3.nostrsigner.models.Account import com.greenart7c3.nostrsigner.models.TorMode +import com.greenart7c3.nostrsigner.service.TorManager import com.greenart7c3.nostrsigner.ui.actions.LogoutDialog import com.greenart7c3.nostrsigner.ui.components.AmberButton import com.greenart7c3.nostrsigner.ui.components.TextSpinner @@ -373,7 +374,7 @@ fun SettingsScreen( torMode = TorMode.DISABLED scope.launch(Dispatchers.IO) { if (Amber.instance.settings.torMode == TorMode.BUILTIN) { - com.greenart7c3.nostrsigner.service.TorManager.stop() + TorManager.stop() } LocalPreferences.updateTorMode(context, TorMode.DISABLED) Amber.instance.checkForNewRelaysAndUpdateAllFilters() diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/ActivityStatsCard.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/ActivityStatsCard.kt index d4907e2e..eca1c5d1 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/ActivityStatsCard.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/ActivityStatsCard.kt @@ -37,6 +37,7 @@ import androidx.compose.ui.draw.rotate import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.greenart7c3.nostrsigner.Amber import com.greenart7c3.nostrsigner.R @@ -198,7 +199,7 @@ private fun ActivityStatsBar(stats: WindowStats, maxTotal: Long) { Text( text = stats.total.toString(), modifier = Modifier.padding(start = 8.dp), - textAlign = androidx.compose.ui.text.style.TextAlign.End, + textAlign = TextAlign.End, fontWeight = FontWeight.Medium, maxLines = 1, ) diff --git a/app/src/test/java/com/greenart7c3/nostrsigner/SignerProviderBenchmarkTest.kt b/app/src/test/java/com/greenart7c3/nostrsigner/SignerProviderBenchmarkTest.kt index 0a362482..f336550a 100644 --- a/app/src/test/java/com/greenart7c3/nostrsigner/SignerProviderBenchmarkTest.kt +++ b/app/src/test/java/com/greenart7c3/nostrsigner/SignerProviderBenchmarkTest.kt @@ -1,5 +1,6 @@ package com.greenart7c3.nostrsigner +import java.net.URI import kotlin.system.measureNanoTime import kotlin.system.measureTimeMillis import kotlinx.coroutines.delay @@ -178,7 +179,7 @@ class SignerProviderBenchmarkTest { val warmupIterations = 5_000 fun extractHost(url: String): String = try { - java.net.URI(url).host ?: url + URI(url).host ?: url } catch (e: Exception) { url } @@ -233,7 +234,7 @@ class SignerProviderBenchmarkTest { val uri = StringBuilder(prefix + "SIGN_EVENT") fun extractHost(url: String) = try { - java.net.URI(url).host ?: url + URI(url).host ?: url } catch (e: Exception) { url } diff --git a/app/src/test/java/com/greenart7c3/nostrsigner/service/IntentUtilsBeforeAfterTest.kt b/app/src/test/java/com/greenart7c3/nostrsigner/service/IntentUtilsBeforeAfterTest.kt index 64e51500..2202da24 100644 --- a/app/src/test/java/com/greenart7c3/nostrsigner/service/IntentUtilsBeforeAfterTest.kt +++ b/app/src/test/java/com/greenart7c3/nostrsigner/service/IntentUtilsBeforeAfterTest.kt @@ -2,6 +2,7 @@ package com.greenart7c3.nostrsigner.service import com.greenart7c3.nostrsigner.database.ApplicationPermissionsEntity import com.vitorpamplona.quartz.utils.TimeUtils +import java.util.Locale import kotlin.system.measureNanoTime import org.junit.Test @@ -278,7 +279,7 @@ class IntentUtilsBeforeAfterTest { // Warm up repeat(5_000) { inputs.forEach { s -> - s.lowercase(java.util.Locale.ROOT) + s.lowercase(Locale.ROOT) s.lowercase() } } @@ -286,7 +287,7 @@ class IntentUtilsBeforeAfterTest { val beforeNs = measureNanoTime { repeat(iterations) { // OLD equivalent: toLowerCase(Locale.current) — uses java.util.Locale lookup - inputs.forEach { s -> s.lowercase(java.util.Locale.ROOT) } + inputs.forEach { s -> s.lowercase(Locale.ROOT) } } } diff --git a/app/src/test/java/com/greenart7c3/nostrsigner/service/nip44v3/Nip44v3Test.kt b/app/src/test/java/com/greenart7c3/nostrsigner/service/nip44v3/Nip44v3Test.kt index 575986cf..80fe61ec 100644 --- a/app/src/test/java/com/greenart7c3/nostrsigner/service/nip44v3/Nip44v3Test.kt +++ b/app/src/test/java/com/greenart7c3/nostrsigner/service/nip44v3/Nip44v3Test.kt @@ -3,7 +3,9 @@ package com.greenart7c3.nostrsigner.service.nip44v3 import com.fasterxml.jackson.databind.JsonNode import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair import com.vitorpamplona.quartz.nip01Core.jackson.JacksonMapper +import com.vitorpamplona.quartz.utils.Secp256k1Instance import java.security.MessageDigest +import kotlin.io.encoding.Base64 import org.junit.Assert.assertArrayEquals import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse @@ -66,7 +68,7 @@ class Nip44v3Test { // Key derivation matches PRK / encryption_key / mac_key from spec val prk1 = Nip44v3.extract( - com.vitorpamplona.quartz.utils.Secp256k1Instance.pubKeyTweakMulCompact(pub2, priv1), + Secp256k1Instance.pubKeyTweakMulCompact(pub2, priv1), nonce, ) assertEquals("vector $idx: prk", expectedPrk, toHex(prk1)) @@ -238,10 +240,10 @@ class Nip44v3Test { val ownPub = pubKeyFor("0000000000000000000000000000000000000000000000000000000000000001") val ct = Nip44v3.encrypt("hello".toByteArray(), priv, peerPub, kind = 1, scope = "") - val decoded = kotlin.io.encoding.Base64.decode(ct) + val decoded = Base64.decode(ct) // Flip a bit in the MAC region (bytes 33..65) decoded[40] = (decoded[40].toInt() xor 0x01).toByte() - val tampered = kotlin.io.encoding.Base64.encode(decoded) + val tampered = Base64.encode(decoded) val ex = assertThrows(Nip44v3.Nip44v3Exception::class.java) { Nip44v3.decrypt(tampered, peer, ownPub, 1, "") }