core: alerts with information about registering names (#7653)

* minimal api change

* embed status. reduce

* drop fake owner change

* no-valid-link fix

* add UX flow for name lookups

* diagram edits

* corrections

* update name lookup API

* manual renaming

* implement core + cli

* implement UI

* fix

* build iOS app blindly

* shrink diff

* fix review comments

* review iterations

* opuse 5.5 /goal iterations

* fixes EP review

* fixes

* fixes

* short goal iterations

* refactor core-UI API to NameWarning with logic in core

* diff cosmetics

* simplify and normalize diagram

* add excalidraw normalizer script and test git hook

* cosmetics

* commit wireframe collab doc to repo as README

* review round on UX coverage

* iterate on /goal

* iterate on /goal

* add tests

* iterate on /goal

* fix freshness bug with local chats: When core marks a chat verified for a name, it now first un-verifies the user's other chats of the same kind:
  - a contact name covers contacts and business chats;
  - a channel name covers channels.

* align app divergences

* docs fixes

* iterations on /goal

* align excalidraw

* align and simplify core/UI/UXcanvas

* 27 rounds of /goal

* review

* core: simplify connect plan with name lookup

* simplify

* cache names in a separate table

* cache names resolution

* wip

* all

* fix

* remove cache

* update plans

* simplify

* bot types

* change types

* simplify

* update bot types

* remove review

* update view, tests

* simplify "unverify"

* update query plan

* changes

* simplify

* test helpers

* simpler

* update query plans

* fix

* query plans

* query plans

* fixes

* query plans

---------

Co-authored-by: Alain Brenzikofer <alain@encointer.org>
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
This commit is contained in:
authored and GitHub committed 2026-10-13 17:05:15 +01:00
1 parent 2f4a443dda
commit 7306f3aeef
39 files changed
+2751 -385

No files matched your search

+38 -7
View File
@@ -93,7 +93,7 @@ import Simplex.Messaging.Crypto.Ratchet (PQEncryption)
import Simplex.Messaging.Encoding.String
import Simplex.Messaging.Notifications.Protocol (DeviceToken (..), NtfTknStatus)
import Simplex.Messaging.Parsers (defaultJSON, dropPrefix, enumJSON, parseAll, parseString, sumTypeJSON)
import Simplex.Messaging.Protocol (AProtoServerWithAuth, AProtocolType (..), MsgId, NMsgMeta (..), NtfServer, ProtocolType (..), QueueId, SMPMsgMeta (..), SubscriptionMode (..), XFTPServer)
import Simplex.Messaging.Protocol (AProtoServerWithAuth, AProtocolType (..), MsgId, NMsgMeta (..), NtfServer, ProtocolType (..), QueueId, SMPMsgMeta (..), SubscriptionMode (..), USDCents, XFTPServer)
import Simplex.Messaging.Session (SessionVar)
import Simplex.Messaging.TMap (TMap)
import Simplex.Messaging.Transport (TLS, TransportPeer (..), simplexMQVersion)
@@ -712,8 +712,8 @@ data ChatCommand
deriving (Show)
data PlanResolveMode
= PRMAllGroups -- resolve all known groups and all unknown chats
| PRMUnknown -- only resolve if chat is unknown (default)
= PRMAllGroups -- resolve names, links of known groups and of unknown chats
| PRMUnknown -- resolve names, and links of unknown chats (default)
| PRMNever -- do not resolve links and names, only do local search
deriving (Eq, Show)
@@ -987,6 +987,7 @@ data ChatEvent
| CEvtGroupLinkConnecting {user :: User, groupInfo :: GroupInfo, hostMember :: GroupMember}
| CEvtBusinessLinkConnecting {user :: User, groupInfo :: GroupInfo, hostMember :: GroupMember, fromContact :: Contact}
| CEvtContactUpdated {user :: User, fromContact :: Contact, toContact :: Contact}
| CEvtNameMoved {user :: User, contactIds :: [ContactId], groupIds :: [GroupId]}
| CEvtGroupMemberUpdated {user :: User, groupInfo :: GroupInfo, fromMember :: GroupMember, toMember :: GroupMember}
| CEvtContactDeletedByContact {user :: User, contact :: Contact}
| CEvtReceivedContactRequest {user :: User, contactRequest :: UserContactRequest, chat_ :: Maybe AChat}
@@ -1156,11 +1157,26 @@ data ChatDeleteMode
data ConnectionPlan
= CPInvitationLink {invitationLinkPlan :: InvitationLinkPlan}
| CPContactAddress {contactAddressPlan :: ContactAddressPlan}
| CPGroupLink {groupLinkPlan :: GroupLinkPlan}
| CPContactAddress {contactAddressPlan :: ContactAddressPlan, nameChange :: Maybe NameChange}
| CPGroupLink {groupLinkPlan :: GroupLinkPlan, nameChange :: Maybe NameChange}
| CPError {chatError :: ChatError}
deriving (Show)
data NameChange
= NCLapsed {nameWarning :: NameWarning}
| NCMoved {knownChat :: AChatInfo}
deriving (Show)
data NameWarning
= NWExpired {expiredAt :: UTCTime, graceUntil :: Maybe UTCTime}
| NWAvailable {price :: NamePrice}
| NWReservedForCommunity
| NWNotRegistered
deriving (Eq, Show)
data NamePrice = NamePrice {amount :: USDCents, years :: Int}
deriving (Eq, Show)
data InvitationLinkPlan
= ILPOk {contactSLinkData_ :: Maybe ContactShortLinkData, ownerVerification :: Maybe OwnerVerification}
| ILPOwnLink
@@ -1219,13 +1235,15 @@ connectionPlanProceed = \case
ILPOk {} -> True
ILPOwnLink -> True
_ -> False
CPContactAddress cap -> case cap of
CPContactAddress _ (Just NCLapsed {}) -> False
CPContactAddress cap _ -> case cap of
CAPOk {} -> True
CAPOwnLink -> True
CAPConnectingConfirmReconnect -> True
CAPContactViaAddress _ -> True
_ -> False
CPGroupLink glp -> case glp of
CPGroupLink _ (Just NCLapsed {}) -> False
CPGroupLink glp _ -> case glp of
GLPOk {} -> True
GLPOwnLink _ -> True
GLPConnectingConfirmReconnect -> True
@@ -1234,6 +1252,12 @@ connectionPlanProceed = \case
_ -> False
CPError _ -> True
connectionPlanOwnLink :: ConnectionPlan -> Bool
connectionPlanOwnLink = \case
CPContactAddress CAPOwnLink _ -> True
CPGroupLink GLPOwnLink {} _ -> True
_ -> False
data ForwardConfirmation
= FCFilesNotAccepted {fileIds :: [FileTransferId]}
| FCFilesInProgress {filesCount :: Int}
@@ -1482,6 +1506,7 @@ data ChatError
data SimplexDomainError
= SDENoValidLink -- the name's record has no usable contact/channel link
| SDEUnknownDomain -- the resolved link's profile has no name, or a different name
| SDENameWarning {nameWarning :: NameWarning}
deriving (Eq, Show)
data BadgeRedeemError
@@ -1849,6 +1874,10 @@ $(JQ.deriveJSON (sumTypeJSON $ dropPrefix "GLP") ''GroupLinkPlan)
$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "FC") ''ForwardConfirmation)
$(JQ.deriveJSON defaultJSON ''NamePrice)
$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "NW") ''NameWarning)
$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "SDE") ''SimplexDomainError)
$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "BRE") ''BadgeRedeemError)
@@ -1865,6 +1894,8 @@ $(JQ.deriveJSON (sumTypeJSON $ dropPrefix "DB") ''DatabaseError)
$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "Chat") ''ChatError)
$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "NC") ''NameChange)
$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "CP") ''ConnectionPlan)
$(JQ.deriveJSON defaultJSON ''AppFilePathsConfig)