core: names are the device's, so drop the per-profile account

A name's profile is the record it resolves to, not the key that owns it, so
the account level was carrying a mapping nothing needs. It was also the only
source of the profile to account ambiguity after a restore, of /_wallet
bind, and of the index gap and the refusal that told a visible profile an
account was held by one it cannot see. All of it goes.

Names sit in account 0 from index 1. Index 0 is left unused so neither the
names nor the profile accounts, which start at 1, claim the origin of both
dimensions. users gains no columns at all now, so the migration is one
CREATE TABLE.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rvc3HbiWBTqbAvRT45G5oX
This commit is contained in:
Alain Brenzikofer
2026-09-11 12:12:41 +00:00
co-authored by Claude Opus 5
parent 05508c0edd
commit 309358a162
11 changed files with 101 additions and 341 deletions
+3 -5
View File
@@ -68,7 +68,7 @@ import Simplex.Chat.Types
import Simplex.Chat.Types.Preferences
import Simplex.Chat.Types.Shared
import Simplex.Chat.Types.UITheme
import Simplex.Chat.Wallet (AccountIndex, NameIndex)
import Simplex.Chat.Wallet (NameIndex)
import Simplex.Chat.Util (liftIOEither)
import Simplex.FileTransfer.Description (FileDescriptionURI)
import Simplex.Messaging.Server.Information (ServerPublicInfo)
@@ -418,11 +418,10 @@ data ChatCommand
| APISendServiceRequest {userId :: UserId, sendTarget :: ConnectTarget 'CMContact, requestTimeout :: Maybe NominalDiffTime, signKey :: Maybe (C.StoredPrivateKey 'C.Ed25519), request :: J.Object}
| APISendServiceResponse {userId :: UserId, requestId :: AgentInvId, responseData :: J.Object}
| APIWallet
| APIWalletBind {boundAccountIndex :: Maybe AccountIndex}
| APIWalletCreate
| APIWalletImport {recoveryPhrase :: Text}
| APIWalletExportSeedMnemonic
| APIWalletExportDerivedSecret {accountIndex :: AccountIndex, nameIndex :: NameIndex}
| APIWalletExportDerivedSecret {nameIndex :: NameIndex}
| APIWalletDelete
| APISendCallInvitation ContactId CallType
| SendCallInvitation ContactName CallType
@@ -750,7 +749,6 @@ allowRemoteCommand = \case
ExecChatStoreSQL _ -> False
ExecAgentStoreSQL _ -> False
APIWallet -> False
APIWalletBind {} -> False
APIWalletCreate -> False
APIWalletImport _ -> False
APIWalletExportSeedMnemonic -> False
@@ -857,7 +855,7 @@ data ChatResponse
| CRContactRequestRejected {user :: User, contactRequest :: UserContactRequest, contact_ :: Maybe Contact}
| CRServiceResponse {user :: User, responseData :: J.Object}
| CRServiceReplyAccepted {user :: User, connectionId :: AgentConnId}
| CRWallet {user :: User, walletKeyExists :: Bool, walletKeyPaths :: [(Text, Text)], walletProfiles :: [Text]}
| CRWallet {user :: User, walletKeyExists :: Bool, walletKeyPaths :: [(Text, Text)]}
| CRWalletSeedMnemonic {user :: User, recoveryPhrase :: Text}
| CRWalletDerivedSecret {user :: User, keyPath :: Text, address :: Text, derivedSecret :: Text}
| CRUserAcceptedGroupSent {user :: User, groupInfo :: GroupInfo, hostContact :: Maybe Contact}