Quick refactoring to abstract the name Amber for any external signers.

This commit is contained in:
Vitor Pamplona
2023-09-18 13:36:36 -04:00
parent 274e4f7498
commit 0b9fced8bc
23 changed files with 414 additions and 391 deletions
+32
View File
@@ -0,0 +1,32 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewApiLevelMustBeValid" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewFontScaleMustBeGreaterThanZero" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
</profile>
</component>
@@ -36,7 +36,7 @@ private const val DEBUG_PREFERENCES_NAME = "debug_prefs"
data class AccountInfo( data class AccountInfo(
val npub: String, val npub: String,
val hasPrivKey: Boolean, val hasPrivKey: Boolean,
val loggedInWithAmber: Boolean val loggedInWithExternalSigner: Boolean
) )
private object PrefKeys { private object PrefKeys {
@@ -75,7 +75,7 @@ private object PrefKeys {
const val THEME = "theme" const val THEME = "theme"
const val PREFERRED_LANGUAGE = "preferred_Language" const val PREFERRED_LANGUAGE = "preferred_Language"
const val AUTOMATICALLY_LOAD_URL_PREVIEW = "automatically_load_url_preview" const val AUTOMATICALLY_LOAD_URL_PREVIEW = "automatically_load_url_preview"
const val LOGIN_WITH_AMBER = "login_with_amber" const val LOGIN_WITH_EXTERNAL_SIGNER = "login_with_external_signer"
val LAST_READ: (String) -> String = { route -> "last_read_route_$route" } val LAST_READ: (String) -> String = { route -> "last_read_route_$route" }
} }
@@ -206,7 +206,7 @@ object LocalPreferences {
AccountInfo( AccountInfo(
npub, npub,
hasPrivKey(npub), hasPrivKey(npub),
getLoggedInWithAmber(npub) getLoggedInWithExternalSigner(npub)
) )
} }
} }
@@ -251,7 +251,7 @@ object LocalPreferences {
} else { } else {
putBoolean(PrefKeys.SHOW_SENSITIVE_CONTENT, account.showSensitiveContent!!) putBoolean(PrefKeys.SHOW_SENSITIVE_CONTENT, account.showSensitiveContent!!)
} }
putBoolean(PrefKeys.LOGIN_WITH_AMBER, account.loginWithAmber) putBoolean(PrefKeys.LOGIN_WITH_EXTERNAL_SIGNER, account.loginWithExternalSigner)
}.apply() }.apply()
val globalPrefs = encryptedPreferences() val globalPrefs = encryptedPreferences()
@@ -283,33 +283,19 @@ object LocalPreferences {
} }
fun getTheme(): Int { fun getTheme(): Int {
encryptedPreferences().apply { return encryptedPreferences().getInt(PrefKeys.THEME, 0)
return getInt(PrefKeys.THEME, 0)
}
} }
fun getPreferredLanguage(): String { fun getPreferredLanguage(): String {
var language = "" return encryptedPreferences().getString(PrefKeys.PREFERRED_LANGUAGE, "") ?: ""
encryptedPreferences().apply {
language = getString(PrefKeys.PREFERRED_LANGUAGE, "") ?: ""
}
return language
} }
private fun getLoggedInWithAmber(npub: String): Boolean { private fun getLoggedInWithExternalSigner(npub: String): Boolean {
var loggedInWithAmber: Boolean return encryptedPreferences(npub).getBoolean(PrefKeys.LOGIN_WITH_EXTERNAL_SIGNER, false)
encryptedPreferences(npub).apply {
loggedInWithAmber = getBoolean(PrefKeys.LOGIN_WITH_AMBER, false)
}
return loggedInWithAmber
} }
private fun hasPrivKey(npub: String): Boolean { private fun hasPrivKey(npub: String): Boolean {
var hasPrivKey: Boolean return (encryptedPreferences(npub).getString(PrefKeys.NOSTR_PRIVKEY, "") ?: "").isNotBlank()
encryptedPreferences(npub).apply {
hasPrivKey = (getString(PrefKeys.NOSTR_PRIVKEY, "") ?: "").isNotBlank()
}
return hasPrivKey
} }
fun loadFromEncryptedStorage(): Account? { fun loadFromEncryptedStorage(): Account? {
@@ -386,7 +372,7 @@ object LocalPreferences {
val useProxy = getBoolean(PrefKeys.USE_PROXY, false) val useProxy = getBoolean(PrefKeys.USE_PROXY, false)
val proxyPort = getInt(PrefKeys.PROXY_PORT, 9050) val proxyPort = getInt(PrefKeys.PROXY_PORT, 9050)
val proxy = HttpClient.initProxy(useProxy, "127.0.0.1", proxyPort) val proxy = HttpClient.initProxy(useProxy, "127.0.0.1", proxyPort)
val loginWithAmber = getBoolean(PrefKeys.LOGIN_WITH_AMBER, false) val loginWithExternalSigner = getBoolean(PrefKeys.LOGIN_WITH_EXTERNAL_SIGNER, false)
val showSensitiveContent = if (contains(PrefKeys.SHOW_SENSITIVE_CONTENT)) { val showSensitiveContent = if (contains(PrefKeys.SHOW_SENSITIVE_CONTENT)) {
getBoolean(PrefKeys.SHOW_SENSITIVE_CONTENT, false) getBoolean(PrefKeys.SHOW_SENSITIVE_CONTENT, false)
@@ -456,7 +442,7 @@ object LocalPreferences {
filterSpamFromStrangers = filterSpam, filterSpamFromStrangers = filterSpam,
lastReadPerRoute = lastReadPerRoute, lastReadPerRoute = lastReadPerRoute,
settings = settings, settings = settings,
loginWithAmber = loginWithAmber loginWithExternalSigner = loginWithExternalSigner
) )
return a return a
@@ -12,7 +12,7 @@ import coil.disk.DiskCache
import coil.util.DebugLogger import coil.util.DebugLogger
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.service.AmberUtils import com.vitorpamplona.amethyst.service.ExternalSignerUtils
import com.vitorpamplona.amethyst.service.HttpClient import com.vitorpamplona.amethyst.service.HttpClient
import com.vitorpamplona.amethyst.service.NostrAccountDataSource import com.vitorpamplona.amethyst.service.NostrAccountDataSource
import com.vitorpamplona.amethyst.service.NostrChannelDataSource import com.vitorpamplona.amethyst.service.NostrChannelDataSource
@@ -42,7 +42,7 @@ object ServiceManager {
fun start(account: Account, context: Context) { fun start(account: Account, context: Context) {
this.account = account this.account = account
AmberUtils.account = account ExternalSignerUtils.account = account
start(context) start(context)
} }
File diff suppressed because it is too large Load Diff
@@ -4,7 +4,7 @@ import android.util.Log
import androidx.compose.runtime.Stable import androidx.compose.runtime.Stable
import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.Amethyst
import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.LocalPreferences
import com.vitorpamplona.amethyst.service.AmberUtils import com.vitorpamplona.amethyst.service.ExternalSignerUtils
import com.vitorpamplona.amethyst.service.checkNotInMainThread import com.vitorpamplona.amethyst.service.checkNotInMainThread
import com.vitorpamplona.amethyst.service.relays.Relay import com.vitorpamplona.amethyst.service.relays.Relay
import com.vitorpamplona.amethyst.ui.components.BundledInsert import com.vitorpamplona.amethyst.ui.components.BundledInsert
@@ -214,7 +214,7 @@ object LocalCache {
if (hexKey != null) { if (hexKey != null) {
val pubKey = Hex.encode(hexKey) val pubKey = Hex.encode(hexKey)
if (pubKey == event.pubKey) { if (pubKey == event.pubKey) {
AmberUtils.content.remove(event.id) ExternalSignerUtils.content.remove(event.id)
} }
} }
user.updateBookmark(event) user.updateBookmark(event)
@@ -32,7 +32,7 @@ enum class SignerType {
DECRYPT_ZAP_EVENT DECRYPT_ZAP_EVENT
} }
object AmberUtils { object ExternalSignerUtils {
val content = LruCache<String, String>(10) val content = LruCache<String, String>(10)
var isActivityRunning: Boolean = false var isActivityRunning: Boolean = false
val cachedDecryptedContent = mutableMapOf<HexKey, String>() val cachedDecryptedContent = mutableMapOf<HexKey, String>()
@@ -113,7 +113,7 @@ object AmberUtils {
} }
@OptIn(DelicateCoroutinesApi::class) @OptIn(DelicateCoroutinesApi::class)
fun openAmber( fun openSigner(
data: String, data: String,
type: SignerType, type: SignerType,
intentResult: ActivityResultLauncher<Intent>, intentResult: ActivityResultLauncher<Intent>,
@@ -141,18 +141,18 @@ object AmberUtils {
intent.`package` = "com.greenart7c3.nostrsigner" intent.`package` = "com.greenart7c3.nostrsigner"
intentResult.launch(intent) intentResult.launch(intent)
} catch (e: Exception) { } catch (e: Exception) {
Log.e("Amber", "Error opening amber", e) Log.e("Signer", "Error opening Signer app", e)
GlobalScope.launch(Dispatchers.Main) { GlobalScope.launch(Dispatchers.Main) {
Toast.makeText( Toast.makeText(
Amethyst.instance, Amethyst.instance,
Amethyst.instance.getString(R.string.error_opening_amber), Amethyst.instance.getString(R.string.error_opening_external_signer),
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
} }
} }
} }
fun openAmber(event: EventInterface, columnName: String = "signature") { fun openSigner(event: EventInterface, columnName: String = "signature") {
checkNotInMainThread() checkNotInMainThread()
val result = getDataFromResolver(SignerType.SIGN_EVENT, arrayOf(event.toJson(), event.pubKey()), columnName) val result = getDataFromResolver(SignerType.SIGN_EVENT, arrayOf(event.toJson(), event.pubKey()), columnName)
@@ -163,7 +163,7 @@ object AmberUtils {
ServiceManager.shouldPauseService = false ServiceManager.shouldPauseService = false
isActivityRunning = true isActivityRunning = true
openAmber( openSigner(
event.toJson(), event.toJson(),
SignerType.SIGN_EVENT, SignerType.SIGN_EVENT,
activityResultLauncher, activityResultLauncher,
@@ -183,7 +183,7 @@ object AmberUtils {
return return
} }
isActivityRunning = true isActivityRunning = true
openAmber( openSigner(
encryptedContent, encryptedContent,
signerType, signerType,
blockListResultLauncher, blockListResultLauncher,
@@ -225,7 +225,7 @@ object AmberUtils {
} }
isActivityRunning = true isActivityRunning = true
openAmber( openSigner(
encryptedContent, encryptedContent,
signerType, signerType,
decryptResultLauncher, decryptResultLauncher,
@@ -244,7 +244,7 @@ object AmberUtils {
cachedDecryptedContent[id] = result cachedDecryptedContent[id] = result
return return
} }
openAmber( openSigner(
encryptedContent, encryptedContent,
signerType, signerType,
decryptResultLauncher, decryptResultLauncher,
@@ -260,7 +260,7 @@ object AmberUtils {
cachedDecryptedContent[id] = result cachedDecryptedContent[id] = result
return return
} }
openAmber( openSigner(
encryptedContent, encryptedContent,
signerType, signerType,
decryptResultLauncher, decryptResultLauncher,
@@ -277,7 +277,7 @@ object AmberUtils {
} }
isActivityRunning = true isActivityRunning = true
openAmber( openSigner(
decryptedContent, decryptedContent,
signerType, signerType,
activityResultLauncher, activityResultLauncher,
@@ -296,7 +296,7 @@ object AmberUtils {
cachedDecryptedContent[event.id] = result cachedDecryptedContent[event.id] = result
return return
} }
openAmber( openSigner(
event.toJson(), event.toJson(),
SignerType.DECRYPT_ZAP_EVENT, SignerType.DECRYPT_ZAP_EVENT,
decryptResultLauncher, decryptResultLauncher,
@@ -152,16 +152,16 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
event.cachedGift(privateKey)?.let { event.cachedGift(privateKey)?.let {
this.consume(it, relay) this.consume(it, relay)
} }
} else if (account.loginWithAmber) { } else if (account.loginWithExternalSigner) {
var cached = AmberUtils.cachedDecryptedContent[event.id] var cached = ExternalSignerUtils.cachedDecryptedContent[event.id]
if (cached == null) { if (cached == null) {
AmberUtils.decrypt( ExternalSignerUtils.decrypt(
event.content, event.content,
event.pubKey, event.pubKey,
event.id, event.id,
SignerType.NIP44_DECRYPT SignerType.NIP44_DECRYPT
) )
cached = AmberUtils.cachedDecryptedContent[event.id] ?: "" cached = ExternalSignerUtils.cachedDecryptedContent[event.id] ?: ""
} }
event.cachedGift(account.keyPair.pubKey, cached)?.let { event.cachedGift(account.keyPair.pubKey, cached)?.let {
this.consume(it, relay) this.consume(it, relay)
@@ -175,16 +175,16 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
event.cachedGossip(privateKey)?.let { event.cachedGossip(privateKey)?.let {
LocalCache.justConsume(it, relay) LocalCache.justConsume(it, relay)
} }
} else if (account.loginWithAmber) { } else if (account.loginWithExternalSigner) {
var cached = AmberUtils.cachedDecryptedContent[event.id] var cached = ExternalSignerUtils.cachedDecryptedContent[event.id]
if (cached == null) { if (cached == null) {
AmberUtils.decrypt( ExternalSignerUtils.decrypt(
event.content, event.content,
event.pubKey, event.pubKey,
event.id, event.id,
SignerType.NIP44_DECRYPT SignerType.NIP44_DECRYPT
) )
cached = AmberUtils.cachedDecryptedContent[event.id] ?: "" cached = ExternalSignerUtils.cachedDecryptedContent[event.id] ?: ""
} }
event.cachedGossip(account.keyPair.pubKey, cached)?.let { event.cachedGossip(account.keyPair.pubKey, cached)?.let {
LocalCache.justConsume(it, relay) LocalCache.justConsume(it, relay)
@@ -7,7 +7,7 @@ import com.vitorpamplona.amethyst.LocalPreferences
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.service.AmberUtils import com.vitorpamplona.amethyst.service.ExternalSignerUtils
import com.vitorpamplona.amethyst.service.SignerType import com.vitorpamplona.amethyst.service.SignerType
import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.sendDMNotification import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.sendDMNotification
import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.sendZapNotification import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.sendZapNotification
@@ -34,7 +34,7 @@ class EventNotificationConsumer(private val applicationContext: Context) {
// Test with all logged in accounts // Test with all logged in accounts
LocalPreferences.allSavedAccounts().forEach { LocalPreferences.allSavedAccounts().forEach {
val acc = LocalPreferences.loadFromEncryptedStorage(it.npub) val acc = LocalPreferences.loadFromEncryptedStorage(it.npub)
if (acc != null && (acc.keyPair.privKey != null || acc.loginWithAmber)) { if (acc != null && (acc.keyPair.privKey != null || acc.loginWithExternalSigner)) {
consumeIfMatchesAccount(event, acc) consumeIfMatchesAccount(event, acc)
} }
} }
@@ -42,16 +42,16 @@ class EventNotificationConsumer(private val applicationContext: Context) {
private suspend fun consumeIfMatchesAccount(pushWrappedEvent: GiftWrapEvent, account: Account) { private suspend fun consumeIfMatchesAccount(pushWrappedEvent: GiftWrapEvent, account: Account) {
val key = account.keyPair.privKey val key = account.keyPair.privKey
if (account.loginWithAmber) { if (account.loginWithExternalSigner) {
var cached = AmberUtils.cachedDecryptedContent[pushWrappedEvent.id] var cached = ExternalSignerUtils.cachedDecryptedContent[pushWrappedEvent.id]
if (cached == null) { if (cached == null) {
AmberUtils.decrypt( ExternalSignerUtils.decrypt(
pushWrappedEvent.content, pushWrappedEvent.content,
pushWrappedEvent.pubKey, pushWrappedEvent.pubKey,
pushWrappedEvent.id, pushWrappedEvent.id,
SignerType.NIP44_DECRYPT SignerType.NIP44_DECRYPT
) )
cached = AmberUtils.cachedDecryptedContent[pushWrappedEvent.id] ?: "" cached = ExternalSignerUtils.cachedDecryptedContent[pushWrappedEvent.id] ?: ""
} }
pushWrappedEvent.unwrap(cached)?.let { notificationEvent -> pushWrappedEvent.unwrap(cached)?.let { notificationEvent ->
if (!LocalCache.justVerify(notificationEvent)) return // invalid event if (!LocalCache.justVerify(notificationEvent)) return // invalid event
@@ -99,16 +99,16 @@ class EventNotificationConsumer(private val applicationContext: Context) {
event.cachedGift(key)?.let { event.cachedGift(key)?.let {
unwrapAndConsume(it, account) unwrapAndConsume(it, account)
} }
} else if (account.loginWithAmber) { } else if (account.loginWithExternalSigner) {
var cached = AmberUtils.cachedDecryptedContent[event.id] var cached = ExternalSignerUtils.cachedDecryptedContent[event.id]
if (cached == null) { if (cached == null) {
AmberUtils.decrypt( ExternalSignerUtils.decrypt(
event.content, event.content,
event.pubKey, event.pubKey,
event.id, event.id,
SignerType.NIP44_DECRYPT SignerType.NIP44_DECRYPT
) )
cached = AmberUtils.cachedDecryptedContent[event.id] ?: "" cached = ExternalSignerUtils.cachedDecryptedContent[event.id] ?: ""
} }
event.cachedGift(account.keyPair.pubKey, cached)?.let { event.cachedGift(account.keyPair.pubKey, cached)?.let {
unwrapAndConsume(it, account) unwrapAndConsume(it, account)
@@ -125,16 +125,16 @@ class EventNotificationConsumer(private val applicationContext: Context) {
LocalCache.justConsume(it, null) LocalCache.justConsume(it, null)
it it
} }
} else if (account.loginWithAmber) { } else if (account.loginWithExternalSigner) {
var cached = AmberUtils.cachedDecryptedContent[event.id] var cached = ExternalSignerUtils.cachedDecryptedContent[event.id]
if (cached == null) { if (cached == null) {
AmberUtils.decrypt( ExternalSignerUtils.decrypt(
event.content, event.content,
event.pubKey, event.pubKey,
event.id, event.id,
SignerType.NIP44_DECRYPT SignerType.NIP44_DECRYPT
) )
cached = AmberUtils.cachedDecryptedContent[event.id] ?: "" cached = ExternalSignerUtils.cachedDecryptedContent[event.id] ?: ""
} }
event.cachedGossip(account.keyPair.pubKey, cached)?.let { event.cachedGossip(account.keyPair.pubKey, cached)?.let {
LocalCache.justConsume(it, null) LocalCache.justConsume(it, null)
@@ -23,7 +23,7 @@ import androidx.core.os.LocaleListCompat
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.LocalPreferences
import com.vitorpamplona.amethyst.ServiceManager import com.vitorpamplona.amethyst.ServiceManager
import com.vitorpamplona.amethyst.service.AmberUtils import com.vitorpamplona.amethyst.service.ExternalSignerUtils
import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus
import com.vitorpamplona.amethyst.service.notifications.PushNotificationUtils import com.vitorpamplona.amethyst.service.notifications.PushNotificationUtils
import com.vitorpamplona.amethyst.ui.components.DefaultMutedSetting import com.vitorpamplona.amethyst.ui.components.DefaultMutedSetting
@@ -52,7 +52,7 @@ import java.nio.charset.StandardCharsets
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
@RequiresApi(Build.VERSION_CODES.R) @RequiresApi(Build.VERSION_CODES.R)
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
AmberUtils.start(this) ExternalSignerUtils.start(this)
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@@ -3,7 +3,7 @@ package com.vitorpamplona.amethyst.ui.dal
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.service.AmberUtils import com.vitorpamplona.amethyst.service.ExternalSignerUtils
import com.vitorpamplona.quartz.encoders.toHexKey import com.vitorpamplona.quartz.encoders.toHexKey
object BookmarkPrivateFeedFilter : FeedFilter<Note>() { object BookmarkPrivateFeedFilter : FeedFilter<Note>() {
@@ -16,12 +16,12 @@ object BookmarkPrivateFeedFilter : FeedFilter<Note>() {
override fun feed(): List<Note> { override fun feed(): List<Note> {
val bookmarks = account.userProfile().latestBookmarkList val bookmarks = account.userProfile().latestBookmarkList
if (account.loginWithAmber) { if (account.loginWithExternalSigner) {
val id = bookmarks?.id val id = bookmarks?.id
if (id != null) { if (id != null) {
val decryptedContent = AmberUtils.cachedDecryptedContent[id] val decryptedContent = ExternalSignerUtils.cachedDecryptedContent[id]
if (decryptedContent == null) { if (decryptedContent == null) {
AmberUtils.decryptBookmark( ExternalSignerUtils.decryptBookmark(
bookmarks.content, bookmarks.content,
account.keyPair.pubKey.toHexKey(), account.keyPair.pubKey.toHexKey(),
id id
@@ -30,7 +30,7 @@ object BookmarkPrivateFeedFilter : FeedFilter<Note>() {
bookmarks.decryptedContent = decryptedContent bookmarks.decryptedContent = decryptedContent
} }
} }
val decryptedContent = AmberUtils.cachedDecryptedContent[id] ?: "" val decryptedContent = ExternalSignerUtils.cachedDecryptedContent[id] ?: ""
val notes = bookmarks?.privateTaggedEvents(decryptedContent) val notes = bookmarks?.privateTaggedEvents(decryptedContent)
?.mapNotNull { LocalCache.checkGetOrCreateNote(it) } ?: emptyList() ?.mapNotNull { LocalCache.checkGetOrCreateNote(it) } ?: emptyList()
@@ -16,7 +16,7 @@ class HiddenAccountsFeedFilter(val account: Account) : FeedFilter<User>() {
override fun feed(): List<User> { override fun feed(): List<User> {
val blockList = account.getBlockList() val blockList = account.getBlockList()
val decryptedContent = blockList?.decryptedContent ?: "" val decryptedContent = blockList?.decryptedContent ?: ""
if (account.loginWithAmber) { if (account.loginWithExternalSigner) {
if (decryptedContent.isEmpty()) return emptyList() if (decryptedContent.isEmpty()) return emptyList()
return blockList return blockList
@@ -307,7 +307,7 @@ fun ZapVote(
// interactionSource = remember { MutableInteractionSource() }, // interactionSource = remember { MutableInteractionSource() },
// indication = rememberRipple(bounded = false, radius = 24.dp), // indication = rememberRipple(bounded = false, radius = 24.dp),
onClick = { onClick = {
if (!accountViewModel.isWriteable() && !accountViewModel.loggedInWithAmber()) { if (!accountViewModel.isWriteable() && !accountViewModel.loggedInWithExternalSigner()) {
scope.launch { scope.launch {
Toast Toast
.makeText( .makeText(
@@ -546,7 +546,7 @@ fun ReplyReaction(
if (accountViewModel.isWriteable()) { if (accountViewModel.isWriteable()) {
onPress() onPress()
} else { } else {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithExternalSigner()) {
onPress() onPress()
} else { } else {
scope.launch { scope.launch {
@@ -659,7 +659,7 @@ fun BoostReaction(
wantsToBoost = true wantsToBoost = true
} }
} else { } else {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithExternalSigner()) {
if (accountViewModel.hasBoosted(baseNote)) { if (accountViewModel.hasBoosted(baseNote)) {
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
accountViewModel.deleteBoostsTo(baseNote) accountViewModel.deleteBoostsTo(baseNote)
@@ -907,7 +907,7 @@ private fun likeClick(
.show() .show()
} }
} else if (!accountViewModel.isWriteable()) { } else if (!accountViewModel.isWriteable()) {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithExternalSigner()) {
onWantsToSignReaction() onWantsToSignReaction()
} else { } else {
scope.launch { scope.launch {
@@ -1122,7 +1122,7 @@ private fun zapClick(
) )
.show() .show()
} }
} else if (!accountViewModel.isWriteable() && !accountViewModel.loggedInWithAmber()) { } else if (!accountViewModel.isWriteable() && !accountViewModel.loggedInWithExternalSigner()) {
scope.launch { scope.launch {
Toast Toast
.makeText( .makeText(
@@ -43,7 +43,7 @@ import androidx.lifecycle.map
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.AmberUtils import com.vitorpamplona.amethyst.service.ExternalSignerUtils
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImage import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImage
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
@@ -478,14 +478,14 @@ fun NoteDropDownMenu(note: Note, popupExpanded: MutableState<Boolean>, accountVi
DropdownMenuItem( DropdownMenuItem(
onClick = { onClick = {
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithExternalSigner()) {
val bookmarks = accountViewModel.userProfile().latestBookmarkList val bookmarks = accountViewModel.userProfile().latestBookmarkList
AmberUtils.decrypt( ExternalSignerUtils.decrypt(
bookmarks?.content ?: "", bookmarks?.content ?: "",
accountViewModel.account.keyPair.pubKey.toHexKey(), accountViewModel.account.keyPair.pubKey.toHexKey(),
bookmarks?.id ?: "" bookmarks?.id ?: ""
) )
bookmarks?.decryptedContent = AmberUtils.cachedDecryptedContent[bookmarks?.id ?: ""] ?: "" bookmarks?.decryptedContent = ExternalSignerUtils.cachedDecryptedContent[bookmarks?.id ?: ""] ?: ""
accountViewModel.removePrivateBookmark(note, bookmarks?.decryptedContent ?: "") accountViewModel.removePrivateBookmark(note, bookmarks?.decryptedContent ?: "")
} else { } else {
accountViewModel.removePrivateBookmark(note) accountViewModel.removePrivateBookmark(note)
@@ -500,14 +500,14 @@ fun NoteDropDownMenu(note: Note, popupExpanded: MutableState<Boolean>, accountVi
DropdownMenuItem( DropdownMenuItem(
onClick = { onClick = {
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithExternalSigner()) {
val bookmarks = accountViewModel.userProfile().latestBookmarkList val bookmarks = accountViewModel.userProfile().latestBookmarkList
AmberUtils.decrypt( ExternalSignerUtils.decrypt(
bookmarks?.content ?: "", bookmarks?.content ?: "",
accountViewModel.account.keyPair.pubKey.toHexKey(), accountViewModel.account.keyPair.pubKey.toHexKey(),
bookmarks?.id ?: "" bookmarks?.id ?: ""
) )
bookmarks?.decryptedContent = AmberUtils.cachedDecryptedContent[bookmarks?.id ?: ""] ?: "" bookmarks?.decryptedContent = ExternalSignerUtils.cachedDecryptedContent[bookmarks?.id ?: ""] ?: ""
accountViewModel.addPrivateBookmark(note, bookmarks?.decryptedContent ?: "") accountViewModel.addPrivateBookmark(note, bookmarks?.decryptedContent ?: "")
} else { } else {
accountViewModel.addPrivateBookmark(note) accountViewModel.addPrivateBookmark(note)
@@ -523,14 +523,14 @@ fun NoteDropDownMenu(note: Note, popupExpanded: MutableState<Boolean>, accountVi
DropdownMenuItem( DropdownMenuItem(
onClick = { onClick = {
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithExternalSigner()) {
val bookmarks = accountViewModel.userProfile().latestBookmarkList val bookmarks = accountViewModel.userProfile().latestBookmarkList
AmberUtils.decrypt( ExternalSignerUtils.decrypt(
bookmarks?.content ?: "", bookmarks?.content ?: "",
accountViewModel.account.keyPair.pubKey.toHexKey(), accountViewModel.account.keyPair.pubKey.toHexKey(),
bookmarks?.id ?: "" bookmarks?.id ?: ""
) )
bookmarks?.decryptedContent = AmberUtils.cachedDecryptedContent[bookmarks?.id ?: ""] ?: "" bookmarks?.decryptedContent = ExternalSignerUtils.cachedDecryptedContent[bookmarks?.id ?: ""] ?: ""
accountViewModel.removePublicBookmark( accountViewModel.removePublicBookmark(
note, note,
bookmarks?.decryptedContent ?: "" bookmarks?.decryptedContent ?: ""
@@ -548,14 +548,14 @@ fun NoteDropDownMenu(note: Note, popupExpanded: MutableState<Boolean>, accountVi
DropdownMenuItem( DropdownMenuItem(
onClick = { onClick = {
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithExternalSigner()) {
val bookmarks = accountViewModel.userProfile().latestBookmarkList val bookmarks = accountViewModel.userProfile().latestBookmarkList
AmberUtils.decrypt( ExternalSignerUtils.decrypt(
bookmarks?.content ?: "", bookmarks?.content ?: "",
accountViewModel.account.keyPair.pubKey.toHexKey(), accountViewModel.account.keyPair.pubKey.toHexKey(),
bookmarks?.id ?: "" bookmarks?.id ?: ""
) )
bookmarks?.decryptedContent = AmberUtils.cachedDecryptedContent[bookmarks?.id ?: ""] ?: "" bookmarks?.decryptedContent = ExternalSignerUtils.cachedDecryptedContent[bookmarks?.id ?: ""] ?: ""
accountViewModel.addPublicBookmark( accountViewModel.addPublicBookmark(
note, note,
bookmarks?.decryptedContent ?: "" bookmarks?.decryptedContent ?: ""
@@ -211,7 +211,7 @@ fun ShowFollowingOrUnfollowingButton(
if (isFollowing) { if (isFollowing) {
UnfollowButton { UnfollowButton {
if (!accountViewModel.isWriteable()) { if (!accountViewModel.isWriteable()) {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithExternalSigner()) {
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
accountViewModel.unfollow(baseAuthor) accountViewModel.unfollow(baseAuthor)
} }
@@ -235,7 +235,7 @@ fun ShowFollowingOrUnfollowingButton(
} else { } else {
FollowButton { FollowButton {
if (!accountViewModel.isWriteable()) { if (!accountViewModel.isWriteable()) {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithExternalSigner()) {
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
accountViewModel.account.follow(baseAuthor) accountViewModel.account.follow(baseAuthor)
} }
@@ -45,21 +45,21 @@ class AccountStateViewModel(val context: Context) : ViewModel() {
} }
} }
fun startUI(key: String, useProxy: Boolean, proxyPort: Int, loginWithAmber: Boolean = false) { fun startUI(key: String, useProxy: Boolean, proxyPort: Int, loginWithExternalSigner: Boolean = false) {
val parsed = Nip19.uriToRoute(key) val parsed = Nip19.uriToRoute(key)
val pubKeyParsed = parsed?.hex?.hexToByteArray() val pubKeyParsed = parsed?.hex?.hexToByteArray()
val proxy = HttpClient.initProxy(useProxy, "127.0.0.1", proxyPort) val proxy = HttpClient.initProxy(useProxy, "127.0.0.1", proxyPort)
val account = val account =
if (key.startsWith("nsec")) { if (key.startsWith("nsec")) {
Account(KeyPair(privKey = key.bechToBytes()), proxy = proxy, proxyPort = proxyPort, loginWithAmber = loginWithAmber) Account(KeyPair(privKey = key.bechToBytes()), proxy = proxy, proxyPort = proxyPort, loginWithExternalSigner = loginWithExternalSigner)
} else if (pubKeyParsed != null) { } else if (pubKeyParsed != null) {
Account(KeyPair(pubKey = pubKeyParsed), proxy = proxy, proxyPort = proxyPort, loginWithAmber = loginWithAmber) Account(KeyPair(pubKey = pubKeyParsed), proxy = proxy, proxyPort = proxyPort, loginWithExternalSigner = loginWithExternalSigner)
} else if (EMAIL_PATTERN.matcher(key).matches()) { } else if (EMAIL_PATTERN.matcher(key).matches()) {
// Evaluate NIP-5 // Evaluate NIP-5
Account(KeyPair(), proxy = proxy, proxyPort = proxyPort, loginWithAmber = loginWithAmber) Account(KeyPair(), proxy = proxy, proxyPort = proxyPort, loginWithExternalSigner = loginWithExternalSigner)
} else { } else {
Account(KeyPair(Hex.decode(key)), proxy = proxy, proxyPort = proxyPort, loginWithAmber = loginWithAmber) Account(KeyPair(Hex.decode(key)), proxy = proxy, proxyPort = proxyPort, loginWithExternalSigner = loginWithExternalSigner)
} }
LocalPreferences.updatePrefsForLogin(account) LocalPreferences.updatePrefsForLogin(account)
@@ -97,8 +97,8 @@ class AccountViewModel(val account: Account) : ViewModel() {
return account.isWriteable() return account.isWriteable()
} }
fun loggedInWithAmber(): Boolean { fun loggedInWithExternalSigner(): Boolean {
return account.loginWithAmber return account.loginWithExternalSigner
} }
fun userProfile(): User { fun userProfile(): User {
@@ -300,9 +300,6 @@ class AccountViewModel(val account: Account) : ViewModel() {
} }
fun decrypt(note: Note): String? { fun decrypt(note: Note): String? {
if (loggedInWithAmber()) {
return account.decryptContentWithAmber(note)
}
return account.decryptContent(note) return account.decryptContent(note)
} }
@@ -171,7 +171,7 @@ fun GeoHashActionOptions(
if (isFollowingTag) { if (isFollowingTag) {
UnfollowButton { UnfollowButton {
if (!accountViewModel.isWriteable()) { if (!accountViewModel.isWriteable()) {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithExternalSigner()) {
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
accountViewModel.account.unfollowGeohash(tag) accountViewModel.account.unfollowGeohash(tag)
} }
@@ -195,7 +195,7 @@ fun GeoHashActionOptions(
} else { } else {
FollowButton { FollowButton {
if (!accountViewModel.isWriteable()) { if (!accountViewModel.isWriteable()) {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithExternalSigner()) {
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
accountViewModel.account.followGeohash(tag) accountViewModel.account.followGeohash(tag)
} }
@@ -147,7 +147,7 @@ fun HashtagActionOptions(
if (isFollowingTag) { if (isFollowingTag) {
UnfollowButton { UnfollowButton {
if (!accountViewModel.isWriteable()) { if (!accountViewModel.isWriteable()) {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithExternalSigner()) {
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
accountViewModel.account.unfollowHashtag(tag) accountViewModel.account.unfollowHashtag(tag)
} }
@@ -171,7 +171,7 @@ fun HashtagActionOptions(
} else { } else {
FollowButton { FollowButton {
if (!accountViewModel.isWriteable()) { if (!accountViewModel.isWriteable()) {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithExternalSigner()) {
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
accountViewModel.account.followHashtag(tag) accountViewModel.account.followHashtag(tag)
} }
@@ -242,7 +242,7 @@ fun FloatingButtons(
Crossfade(targetState = accountState, animationSpec = tween(durationMillis = 100)) { state -> Crossfade(targetState = accountState, animationSpec = tween(durationMillis = 100)) { state ->
when (state) { when (state) {
is AccountState.LoggedInViewOnly -> { is AccountState.LoggedInViewOnly -> {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithExternalSigner()) {
WritePermissionButtons(navEntryState, accountViewModel, nav, navScrollToTop) WritePermissionButtons(navEntryState, accountViewModel, nav, navScrollToTop)
} }
} }
@@ -748,7 +748,7 @@ private fun DisplayFollowUnfollowButton(
if (isLoggedInFollowingUser) { if (isLoggedInFollowingUser) {
UnfollowButton { UnfollowButton {
if (!accountViewModel.isWriteable()) { if (!accountViewModel.isWriteable()) {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithExternalSigner()) {
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
accountViewModel.account.unfollow(baseUser) accountViewModel.account.unfollow(baseUser)
} }
@@ -773,7 +773,7 @@ private fun DisplayFollowUnfollowButton(
if (isUserFollowingLoggedIn) { if (isUserFollowingLoggedIn) {
FollowButton(R.string.follow_back) { FollowButton(R.string.follow_back) {
if (!accountViewModel.isWriteable()) { if (!accountViewModel.isWriteable()) {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithExternalSigner()) {
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
accountViewModel.account.follow(baseUser) accountViewModel.account.follow(baseUser)
} }
@@ -797,7 +797,7 @@ private fun DisplayFollowUnfollowButton(
} else { } else {
FollowButton(R.string.follow) { FollowButton(R.string.follow) {
if (!accountViewModel.isWriteable()) { if (!accountViewModel.isWriteable()) {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithExternalSigner()) {
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
accountViewModel.account.follow(baseUser) accountViewModel.account.follow(baseUser)
} }
@@ -42,7 +42,7 @@ import androidx.compose.ui.unit.dp
import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.Amethyst
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ServiceManager import com.vitorpamplona.amethyst.ServiceManager
import com.vitorpamplona.amethyst.service.AmberUtils import com.vitorpamplona.amethyst.service.ExternalSignerUtils
import com.vitorpamplona.amethyst.service.PackageUtils import com.vitorpamplona.amethyst.service.PackageUtils
import com.vitorpamplona.amethyst.service.SignerType import com.vitorpamplona.amethyst.service.SignerType
import com.vitorpamplona.amethyst.ui.qrcode.SimpleQrCodeScanner import com.vitorpamplona.amethyst.ui.qrcode.SimpleQrCodeScanner
@@ -74,12 +74,12 @@ fun LoginPage(
val proxyPort = remember { mutableStateOf("9050") } val proxyPort = remember { mutableStateOf("9050") }
var connectOrbotDialogOpen by remember { mutableStateOf(false) } var connectOrbotDialogOpen by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
var loginWithAmber by remember { mutableStateOf(false) } var loginWithExternalSigner by remember { mutableStateOf(false) }
val activity = rememberLauncherForActivityResult( val activity = rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartActivityForResult(), contract = ActivityResultContracts.StartActivityForResult(),
onResult = { onResult = {
loginWithAmber = false loginWithExternalSigner = false
AmberUtils.isActivityRunning = false ExternalSignerUtils.isActivityRunning = false
ServiceManager.shouldPauseService = true ServiceManager.shouldPauseService = true
if (it.resultCode != Activity.RESULT_OK) { if (it.resultCode != Activity.RESULT_OK) {
scope.launch(Dispatchers.Main) { scope.launch(Dispatchers.Main) {
@@ -114,9 +114,9 @@ fun LoginPage(
} }
) )
LaunchedEffect(loginWithAmber) { LaunchedEffect(loginWithExternalSigner) {
if (loginWithAmber) { if (loginWithExternalSigner) {
AmberUtils.openAmber( ExternalSignerUtils.openSigner(
"", "",
SignerType.GET_PUBLIC_KEY, SignerType.GET_PUBLIC_KEY,
activity, activity,
@@ -357,9 +357,9 @@ fun LoginPage(
Box(modifier = Modifier.padding(40.dp, 40.dp, 40.dp, 0.dp)) { Box(modifier = Modifier.padding(40.dp, 40.dp, 40.dp, 0.dp)) {
Button( Button(
onClick = { onClick = {
val result = AmberUtils.getDataFromResolver(SignerType.GET_PUBLIC_KEY, arrayOf("login"), "") val result = ExternalSignerUtils.getDataFromResolver(SignerType.GET_PUBLIC_KEY, arrayOf("login"), "")
if (result == null) { if (result == null) {
loginWithAmber = true loginWithExternalSigner = true
return@Button return@Button
} }
key.value = TextFieldValue(result) key.value = TextFieldValue(result)
@@ -395,7 +395,7 @@ fun LoginPage(
backgroundColor = if (acceptedTerms.value) MaterialTheme.colors.primary else Color.Gray backgroundColor = if (acceptedTerms.value) MaterialTheme.colors.primary else Color.Gray
) )
) { ) {
Text(text = stringResource(R.string.login_with_amber)) Text(text = stringResource(R.string.login_with_external_signer))
} }
} }
} }
+2 -2
View File
@@ -552,7 +552,7 @@
<string name="created_at">Created at</string> <string name="created_at">Created at</string>
<string name="rules">Rules</string> <string name="rules">Rules</string>
<string name="login_with_amber">Login with Amber</string> <string name="login_with_external_signer">Login with Amber</string>
<string name="status_update">Update your status</string> <string name="status_update">Update your status</string>
@@ -588,6 +588,6 @@
<string name="lightning_wallets_not_found2">Lightning wallets not found</string> <string name="lightning_wallets_not_found2">Lightning wallets not found</string>
<string name="paid">Paid</string> <string name="paid">Paid</string>
<string name="wallet_number">Wallet %1$s</string> <string name="wallet_number">Wallet %1$s</string>
<string name="error_opening_amber">Error opening Amber</string> <string name="error_opening_external_signer">Error opening signer app</string>
<string name="sign_request_rejected">Sign request rejected</string> <string name="sign_request_rejected">Sign request rejected</string>
</resources> </resources>