mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-06 03:38:23 +00:00
refactor: clear three small jvmAndroid dependencies of Account's group
- DefaultSignerPermissions moves from model/AccountSettings.kt to ExternalSignerButton, its only user. It is the NIP-55 permission request sent to an Android signer app at login, built from quartz androidMain types (CommandType, Permission); AccountSettings never read it. - GeohashIdentitySecrets, a plain data class, moves out of the jvmAndroid AccountSecrets.kt (which is jvmAndroid for its DataStore keys and legacy readers) into its own commonMain file, same package. - OnchainWalletState moves from commons jvmAndroid to commonMain. It only needed kotlinx.coroutines.IO and kotlin.concurrent.Volatile imports; every quartz type it uses is already commonMain. No behaviour change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S7FuNBSKiyVecARSoE4B9P
This commit is contained in:
@@ -62,9 +62,7 @@ import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.DmRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.list.PublicChatListEvent
|
||||
import com.vitorpamplona.quartz.nip37Drafts.DraftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip37Drafts.privateOutbox.PrivateOutboxRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip42RelayAuth.RelayAuthEvent
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.Nip47WalletConnect
|
||||
import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.favoriteAlgoFeedsList.FavoriteAlgoFeedsListEvent
|
||||
@@ -76,8 +74,6 @@ import com.vitorpamplona.quartz.nip51Lists.relayLists.FavoriteRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.IndexerRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.TrustedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.simpleGroupList.SimpleGroupListEvent
|
||||
import com.vitorpamplona.quartz.nip55AndroidSigner.api.CommandType
|
||||
import com.vitorpamplona.quartz.nip55AndroidSigner.api.permission.Permission
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import com.vitorpamplona.quartz.nip60Cashu.wallet.CashuWalletEvent
|
||||
import com.vitorpamplona.quartz.nip61Nutzaps.info.NutzapInfoEvent
|
||||
@@ -97,17 +93,6 @@ import kotlinx.serialization.Serializable
|
||||
import kotlin.uuid.ExperimentalUuidApi
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
val DefaultSignerPermissions =
|
||||
listOf(
|
||||
Permission(CommandType.SIGN_EVENT, RelayAuthEvent.KIND),
|
||||
Permission(CommandType.SIGN_EVENT, DraftWrapEvent.KIND),
|
||||
Permission(CommandType.NIP04_ENCRYPT),
|
||||
Permission(CommandType.NIP04_DECRYPT),
|
||||
Permission(CommandType.NIP44_DECRYPT),
|
||||
Permission(CommandType.NIP44_DECRYPT),
|
||||
Permission(CommandType.DECRYPT_ZAP_EVENT),
|
||||
)
|
||||
|
||||
@Stable
|
||||
class AccountSettings(
|
||||
val keyPair: KeyPair,
|
||||
|
||||
+16
-1
@@ -64,9 +64,12 @@ import com.vitorpamplona.amethyst.commons.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.commons.ui.theme.Size0dp
|
||||
import com.vitorpamplona.amethyst.commons.ui.theme.Size20dp
|
||||
import com.vitorpamplona.amethyst.commons.ui.theme.Size40dp
|
||||
import com.vitorpamplona.amethyst.model.DefaultSignerPermissions
|
||||
import com.vitorpamplona.quartz.nip37Drafts.DraftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip42RelayAuth.RelayAuthEvent
|
||||
import com.vitorpamplona.quartz.nip55AndroidSigner.api.CommandType
|
||||
import com.vitorpamplona.quartz.nip55AndroidSigner.api.PubKeyResult
|
||||
import com.vitorpamplona.quartz.nip55AndroidSigner.api.SignerResult
|
||||
import com.vitorpamplona.quartz.nip55AndroidSigner.api.permission.Permission
|
||||
import com.vitorpamplona.quartz.nip55AndroidSigner.client.ExternalSignerLogin
|
||||
import com.vitorpamplona.quartz.nip55AndroidSigner.client.getExternalSignersInstalled
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
@@ -196,3 +199,15 @@ fun ExternalSignerButton(loginViewModel: LoginViewModel) {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** What Amethyst asks a NIP-55 signer app to pre-approve when the user logs in with it. */
|
||||
val DefaultSignerPermissions =
|
||||
listOf(
|
||||
Permission(CommandType.SIGN_EVENT, RelayAuthEvent.KIND),
|
||||
Permission(CommandType.SIGN_EVENT, DraftWrapEvent.KIND),
|
||||
Permission(CommandType.NIP04_ENCRYPT),
|
||||
Permission(CommandType.NIP04_DECRYPT),
|
||||
Permission(CommandType.NIP44_DECRYPT),
|
||||
Permission(CommandType.NIP44_DECRYPT),
|
||||
Permission(CommandType.DECRYPT_ZAP_EVENT),
|
||||
)
|
||||
|
||||
+2
@@ -31,12 +31,14 @@ import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.IO
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlin.concurrent.Volatile
|
||||
|
||||
/**
|
||||
* A snapshot of the account's NIP-BC on-chain wallet: what is sitting on the
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.model.preferences
|
||||
|
||||
/**
|
||||
* The account's location-chat identity: the seed its per-geohash throwaway keys
|
||||
* come from, and the handle it posts under.
|
||||
*
|
||||
* # Why this is not two more fields on [AccountSecrets]
|
||||
*
|
||||
* Every account save mirrors a whole [AccountSecrets], built field by field from
|
||||
* `AccountSettings` — which does not hold these, because they are owned by
|
||||
* `GeohashChatIdentityState` rather than by the settings object. Folding them in
|
||||
* would make each save write null over them, and the group save uses
|
||||
* `putOrRemove`, so null *deletes*. The seed would vanish on the next unrelated
|
||||
* save and every geohash identity the user has would silently change. A separate
|
||||
* group with its own save path cannot be wiped by a save that does not know
|
||||
* about it.
|
||||
*
|
||||
* # Why encrypted
|
||||
*
|
||||
* The whole point of the seed is that the identities derived from it are
|
||||
* unlinkable to the npub. Anyone who can read it can link every cell the user
|
||||
* has ever posted in, to each other and to the device, which is exactly what the
|
||||
* feature exists to prevent. It was in an encrypted file before; it stays in one.
|
||||
*/
|
||||
data class GeohashIdentitySecrets(
|
||||
val deviceSeed: String? = null,
|
||||
val nickname: String? = null,
|
||||
)
|
||||
-27
@@ -152,33 +152,6 @@ fun readLegacyAccountSecrets(source: LegacyPreferenceSource) =
|
||||
legacyZapPaymentRequestServer = source.getString(LegacyAccountSecretNames.ZAP_PAYMENT_REQUEST_SERVER),
|
||||
)
|
||||
|
||||
/**
|
||||
* The account's location-chat identity: the seed its per-geohash throwaway keys
|
||||
* come from, and the handle it posts under.
|
||||
*
|
||||
* # Why this is not two more fields on [AccountSecrets]
|
||||
*
|
||||
* Every account save mirrors a whole [AccountSecrets], built field by field from
|
||||
* `AccountSettings` — which does not hold these, because they are owned by
|
||||
* `GeohashChatIdentityState` rather than by the settings object. Folding them in
|
||||
* would make each save write null over them, and the group save uses
|
||||
* `putOrRemove`, so null *deletes*. The seed would vanish on the next unrelated
|
||||
* save and every geohash identity the user has would silently change. A separate
|
||||
* group with its own save path cannot be wiped by a save that does not know
|
||||
* about it.
|
||||
*
|
||||
* # Why encrypted
|
||||
*
|
||||
* The whole point of the seed is that the identities derived from it are
|
||||
* unlinkable to the npub. Anyone who can read it can link every cell the user
|
||||
* has ever posted in, to each other and to the device, which is exactly what the
|
||||
* feature exists to prevent. It was in an encrypted file before; it stays in one.
|
||||
*/
|
||||
data class GeohashIdentitySecrets(
|
||||
val deviceSeed: String? = null,
|
||||
val nickname: String? = null,
|
||||
)
|
||||
|
||||
/** Keys for [GeohashIdentitySecrets] inside an [EncryptedDataStore]. */
|
||||
internal object GeohashIdentityKeys {
|
||||
val deviceSeed = stringPreferencesKey(LegacyAccountSecretNames.GEOHASH_DEVICE_SEED)
|
||||
|
||||
Reference in New Issue
Block a user