From 0d7ea8061243240af0d9b9d51af174b09e4236ea Mon Sep 17 00:00:00 2001 From: shum Date: Fri, 5 Jun 2026 07:42:06 +0000 Subject: [PATCH] chat: register ConnectTarget + CEvtSimplexNameConflict in bot docs Bot API docs generator failed with "Undefined type: ConnectTarget" since f2394d121 (prior plan) flipped APIConnectPlan/Connect from Maybe AConnectionLink to Maybe ConnectTarget without updating bots/src/API/Docs/*. Also adds SimplexNameConflictEntity (new in cd0de9659) and documents the CEvtSimplexNameConflict event for peer-name displacement notifications. Regenerates the affected markdown / TypeScript / Python artefacts. --- bots/api/COMMANDS.md | 20 +++---- bots/api/EVENTS.md | 16 ++++++ bots/api/TYPES.md | 46 ++++++++++++++++ bots/src/API/Docs/Commands.hs | 6 +-- bots/src/API/Docs/Events.hs | 1 + bots/src/API/Docs/Types.hs | 4 ++ .../types/typescript/src/commands.ts | 12 ++--- .../types/typescript/src/events.ts | 11 ++++ .../types/typescript/src/types.ts | 53 +++++++++++++++++++ .../src/simplex_chat/types/_commands.py | 12 ++--- .../src/simplex_chat/types/_events.py | 17 +++++- .../src/simplex_chat/types/_types.py | 39 +++++++++++++- 12 files changed, 210 insertions(+), 27 deletions(-) diff --git a/bots/api/COMMANDS.md b/bots/api/COMMANDS.md index d14435cabd..67cea33777 100644 --- a/bots/api/COMMANDS.md +++ b/bots/api/COMMANDS.md @@ -1363,28 +1363,28 @@ ChatCmdError: Command error (only used in WebSockets API). ### APIConnectPlan -Determine SimpleX link type and if the bot is already connected via this link. +Determine SimpleX link type and if the bot is already connected via this link or name. *Network usage*: interactive. **Parameters**: - userId: int64 -- connectionLink: string? +- connectTarget: [ConnectTarget](./TYPES.md#connecttarget)? - resolveKnown: bool - linkOwnerSig: [LinkOwnerSig](./TYPES.md#linkownersig)? **Syntax**: ``` -/_connect plan +/_connect plan ``` ```javascript -'/_connect plan ' + userId + ' ' + connectionLink // JavaScript +'/_connect plan ' + userId + ' ' + connectTarget // JavaScript ``` ```python -'/_connect plan ' + str(userId) + ' ' + connectionLink # Python +'/_connect plan ' + str(userId) + ' ' + str(connectTarget) # Python ``` **Responses**: @@ -1455,26 +1455,26 @@ ChatCmdError: Command error (only used in WebSockets API). ### Connect -Connect via SimpleX link as string in the active user profile. +Connect via SimpleX link or name as string in the active user profile. *Network usage*: interactive. **Parameters**: - incognito: bool -- connLink_: string? +- connTarget_: [ConnectTarget](./TYPES.md#connecttarget)? **Syntax**: ``` -/connect[ ] +/connect[ ] ``` ```javascript -'/connect' + (connLink_ ? ' ' + connLink_ : '') // JavaScript +'/connect' + (connTarget_ ? ' ' + connTarget_ : '') // JavaScript ``` ```python -'/connect' + ((' ' + connLink_) if connLink_ is not None else '') # Python +'/connect' + ((' ' + str(connTarget_)) if connTarget_ is not None else '') # Python ``` **Responses**: diff --git a/bots/api/EVENTS.md b/bots/api/EVENTS.md index 947c60586a..2ac3af0133 100644 --- a/bots/api/EVENTS.md +++ b/bots/api/EVENTS.md @@ -10,6 +10,7 @@ This file is generated automatically. - [ContactDeletedByContact](#contactdeletedbycontact) - [ReceivedContactRequest](#receivedcontactrequest) - [NewMemberContactReceivedInv](#newmembercontactreceivedinv) + - [SimplexNameConflict](#simplexnameconflict) - [ContactSndReady](#contactsndready) [Message events](#message-events) @@ -160,6 +161,21 @@ This event only needs to be processed to associate contact with group, the conne --- +### SimplexNameConflict + +A peer's profile update claimed a SimpleX name (`#name.simplex` / `@name.simplex`) that was already held locally by another contact or group. The displaced row's `simplex_name` is set to NULL and the claim moves to the newer row; this event surfaces the displacement so the bot can warn the user about a possible impersonation. + +**Record type**: +- type: "simplexNameConflict" +- user: [User](./TYPES.md#user) +- simplexName: [SimplexNameInfo](./TYPES.md#simplexnameinfo) +- entity: [SimplexNameConflictEntity](./TYPES.md#simplexnameconflictentity) +- claimedBy: string +- displacedFrom: string + +--- + + ### ContactSndReady Connecting via 1-time invitation or after accepting contact request. diff --git a/bots/api/TYPES.md b/bots/api/TYPES.md index 4f277d2441..70c90d108e 100644 --- a/bots/api/TYPES.md +++ b/bots/api/TYPES.md @@ -57,6 +57,7 @@ This file is generated automatically. - [ComposedMessage](#composedmessage) - [ConnStatus](#connstatus) - [ConnType](#conntype) +- [ConnectTarget](#connecttarget) - [Connection](#connection) - [ConnectionEntity](#connectionentity) - [ConnectionErrorType](#connectionerrortype) @@ -167,6 +168,7 @@ This file is generated automatically. - [SecurityCode](#securitycode) - [SimplePreference](#simplepreference) - [SimplexLinkType](#simplexlinktype) +- [SimplexNameConflictEntity](#simplexnameconflictentity) - [SimplexNameDomain](#simplexnamedomain) - [SimplexNameInfo](#simplexnameinfo) - [SimplexNameType](#simplexnametype) @@ -1055,6 +1057,18 @@ ChatStoreChanged: InvalidConnReq: - type: "invalidConnReq" +SimplexNameNotFound: +- type: "simplexNameNotFound" +- simplexName: [SimplexNameInfo](#simplexnameinfo) + +SimplexNameUnprepared: +- type: "simplexNameUnprepared" +- simplexName: [SimplexNameInfo](#simplexnameinfo) + +SimplexNameResolverUnavailable: +- type: "simplexNameResolverUnavailable" +- simplexName: [SimplexNameInfo](#simplexnameinfo) + UnsupportedConnReq: - type: "unsupportedConnReq" @@ -1588,6 +1602,23 @@ Failed: - "user_contact" +--- + +## ConnectTarget + +Connect target: SimpleX link (`CTLink`) or SimpleX name (`CTName`). Wire form is the bare string returned by `strEncode` — `simplex:/...` for links, `#name.simplex` / `@name.simplex` for names. + +**Discriminated union type**: + +Link: +- type: "link" +- : string + +Name: +- type: "name" +- : [SimplexNameInfo](#simplexnameinfo) + + --- ## Connection @@ -1617,6 +1648,7 @@ Failed: - authErrCounter: int - quotaErrCounter: int - createdAt: UTCTime +- simplexName: [SimplexNameInfo](#simplexnameinfo)? --- @@ -1723,6 +1755,7 @@ Error: - uiThemes: [UIThemeEntityOverrides](#uithemeentityoverrides)? - chatDeleted: bool - customData: JSONObject? +- simplexName: [SimplexNameInfo](#simplexnameinfo)? --- @@ -2270,6 +2303,7 @@ MemberSupport: - membersRequireAttention: int - viaGroupLinkUri: string? - groupKeys: [GroupKeys](#groupkeys)? +- simplexName: [SimplexNameInfo](#simplexnameinfo)? --- @@ -2484,6 +2518,7 @@ UpdateRequired: - description: string? - image: string? - publicGroup: [PublicGroupProfile](#publicgroupprofile)? +- simplexName: [SimplexNameInfo](#simplexnameinfo)? - groupPreferences: [GroupPreferences](#grouppreferences)? - memberAdmission: [GroupMemberAdmission](#groupmemberadmission)? @@ -2680,6 +2715,7 @@ Unknown: - shortDescr: string? - image: string? - contactLink: string? +- simplexName: [SimplexNameInfo](#simplexnameinfo)? - preferences: [Preferences](#preferences)? - peerType: [ChatPeerType](#chatpeertype)? - localAlias: string @@ -3025,6 +3061,7 @@ count= - shortDescr: string? - image: string? - contactLink: string? +- simplexName: [SimplexNameInfo](#simplexnameinfo)? - preferences: [Preferences](#preferences)? - peerType: [ChatPeerType](#chatpeertype)? @@ -3469,6 +3506,15 @@ A_QUEUE: - "relay" +--- + +## SimplexNameConflictEntity + +**Enum type**: +- "contact" +- "group" + + --- ## SimplexNameDomain diff --git a/bots/src/API/Docs/Commands.hs b/bots/src/API/Docs/Commands.hs index 756cf8c10e..8b45d09a4e 100644 --- a/bots/src/API/Docs/Commands.hs +++ b/bots/src/API/Docs/Commands.hs @@ -135,10 +135,10 @@ chatCommandsDocsData = ( "Connection commands", "These commands may be used to create connections. Most bots do not need to use them - bot users will connect via bot address with auto-accept enabled.", [ ("APIAddContact", [], "Create 1-time invitation link.", ["CRInvitation", "CRChatCmdError"], [], Just UNInteractive, "/_connect " <> Param "userId" <> OnOffParam "incognito" "incognito" (Just False)), - -- `Maybe` in `connectionLink :: Maybe AConnectionLink` is used to signal link parsing error to the runtime (the handler returns CEInvalidConnReq on Nothing); it is NOT API-level optionality. The parameter is required from callers. - ("APIConnectPlan", [], "Determine SimpleX link type and if the bot is already connected via this link.", ["CRConnectionPlan", "CRChatCmdError"], [], Just UNInteractive, "/_connect plan " <> Param "userId" <> " " <> Param "connectionLink"), + -- `Maybe` in `connectTarget :: Maybe ConnectTarget` is used to signal parse failure to the runtime (the handler returns CEInvalidConnReq on Nothing); it is NOT API-level optionality. The parameter is required from callers. + ("APIConnectPlan", [], "Determine SimpleX link type and if the bot is already connected via this link or name.", ["CRConnectionPlan", "CRChatCmdError"], [], Just UNInteractive, "/_connect plan " <> Param "userId" <> " " <> Param "connectTarget"), ("APIConnect", [], "Connect via prepared SimpleX link. The link can be 1-time invitation link, contact address or group link.", ["CRSentConfirmation", "CRContactAlreadyExists", "CRSentInvitation", "CRChatCmdError"], [], Just UNInteractive, "/_connect " <> Param "userId" <> Optional "" (" " <> Param "$0") "preparedLink_"), - ("Connect", [], "Connect via SimpleX link as string in the active user profile.", ["CRSentConfirmation", "CRContactAlreadyExists", "CRSentInvitation", "CRChatCmdError"], [], Just UNInteractive, "/connect" <> Optional "" (" " <> Param "$0") "connLink_"), + ("Connect", [], "Connect via SimpleX link or name as string in the active user profile.", ["CRSentConfirmation", "CRContactAlreadyExists", "CRSentInvitation", "CRChatCmdError"], [], Just UNInteractive, "/connect" <> Optional "" (" " <> Param "$0") "connTarget_"), ("APIAcceptContact", ["incognito"], "Accept contact request.", ["CRAcceptingContactRequest", "CRChatCmdError"], [], Just UNInteractive, "/_accept " <> Param "contactReqId"), ("APIRejectContact", [], "Reject contact request. The user who sent the request is **not notified**.", ["CRContactRequestRejected", "CRChatCmdError"], [], Nothing, "/_reject " <> Param "contactReqId") ] diff --git a/bots/src/API/Docs/Events.hs b/bots/src/API/Docs/Events.hs index f0c9352efd..db2b2fc777 100644 --- a/bots/src/API/Docs/Events.hs +++ b/bots/src/API/Docs/Events.hs @@ -67,6 +67,7 @@ chatEventsDocsData = ("CEvtContactDeletedByContact", "Bot user's connection with another contact is deleted (conversation is kept)."), ("CEvtReceivedContactRequest", "Contact request received.\n\nThis event is only sent when auto-accept is disabled.\n\nThe request needs to be accepted using [APIAcceptContact](./COMMANDS.md#apiacceptcontact) command"), ("CEvtNewMemberContactReceivedInv", "Received invitation to connect directly with a group member.\n\nThis event only needs to be processed to associate contact with group, the connection will proceed automatically."), + ("CEvtSimplexNameConflict", "A peer's profile update claimed a SimpleX name (`#name.simplex` / `@name.simplex`) that was already held locally by another contact or group. The displaced row's `simplex_name` is set to NULL and the claim moves to the newer row; this event surfaces the displacement so the bot can warn the user about a possible impersonation."), ("CEvtContactSndReady", "Connecting via 1-time invitation or after accepting contact request.\n\nAfter this event bot can send messages to this contact.") -- JOINED ] ), diff --git a/bots/src/API/Docs/Types.hs b/bots/src/API/Docs/Types.hs index 8397503bbe..3a5633736a 100644 --- a/bots/src/API/Docs/Types.hs +++ b/bots/src/API/Docs/Types.hs @@ -245,6 +245,7 @@ chatTypesDocsData = (sti @ConnectionErrorType, STUnion, "", [], "", ""), (sti @ConnectionMode, (STEnum' $ take 3 . consLower "CM"), "", [], "", ""), (sti @ConnectionPlan, STUnion, "CP", [], "", ""), + (sti @ConnectTarget, STUnion, "CT", [], "", "Connect target: SimpleX link (`CTLink`) or SimpleX name (`CTName`). Wire form is the bare string returned by `strEncode` — `simplex:/...` for links, `#name.simplex` / `@name.simplex` for names."), (sti @ConnStatus, STUnion, "Conn", [], "", ""), (sti @ConnType, (STEnum' $ consSep "Conn" '_'), "", [], "", ""), (sti @Contact, STRecord, "", [], "", ""), @@ -347,6 +348,7 @@ chatTypesDocsData = (sti @SecurityCode, STRecord, "", [], "", ""), (sti @SimplePreference, STRecord, "", [], "", ""), (sti @SimplexLinkType, STEnum, "XL", [], "", ""), + (sti @SimplexNameConflictEntity, STEnum, "SNCE", [], "", ""), (sti @SimplexNameDomain, STRecord, "", [], "", ""), (sti @SimplexNameInfo, STRecord, "", [], "", ""), (sti @SimplexNameType, STEnum, "NT", [], "", ""), @@ -460,6 +462,7 @@ deriving instance Generic ConnectionEntity deriving instance Generic ConnectionErrorType deriving instance Generic ConnectionMode deriving instance Generic ConnectionPlan +deriving instance Generic ConnectTarget deriving instance Generic ConnStatus deriving instance Generic ConnType deriving instance Generic Contact @@ -566,6 +569,7 @@ deriving instance Generic RelayStatus deriving instance Generic ReportReason deriving instance Generic SecurityCode deriving instance Generic SimplexLinkType +deriving instance Generic SimplexNameConflictEntity deriving instance Generic SimplexNameDomain deriving instance Generic SimplexNameInfo deriving instance Generic SimplexNameType diff --git a/packages/simplex-chat-client/types/typescript/src/commands.ts b/packages/simplex-chat-client/types/typescript/src/commands.ts index d1b89ffe27..46a3d8b27b 100644 --- a/packages/simplex-chat-client/types/typescript/src/commands.ts +++ b/packages/simplex-chat-client/types/typescript/src/commands.ts @@ -495,11 +495,11 @@ export namespace APIAddContact { } } -// Determine SimpleX link type and if the bot is already connected via this link. +// Determine SimpleX link type and if the bot is already connected via this link or name. // Network usage: interactive. export interface APIConnectPlan { userId: number // int64 - connectionLink?: string + connectTarget?: T.ConnectTarget resolveKnown: boolean linkOwnerSig?: T.LinkOwnerSig } @@ -508,7 +508,7 @@ export namespace APIConnectPlan { export type Response = CR.ConnectionPlan | CR.ChatCmdError export function cmdString(self: APIConnectPlan): string { - return '/_connect plan ' + self.userId + ' ' + self.connectionLink + return '/_connect plan ' + self.userId + ' ' + self.connectTarget } } @@ -528,18 +528,18 @@ export namespace APIConnect { } } -// Connect via SimpleX link as string in the active user profile. +// Connect via SimpleX link or name as string in the active user profile. // Network usage: interactive. export interface Connect { incognito: boolean - connLink_?: string + connTarget_?: T.ConnectTarget } export namespace Connect { export type Response = CR.SentConfirmation | CR.ContactAlreadyExists | CR.SentInvitation | CR.ChatCmdError export function cmdString(self: Connect): string { - return '/connect' + (self.connLink_ ? ' ' + self.connLink_ : '') + return '/connect' + (self.connTarget_ ? ' ' + self.connTarget_ : '') } } diff --git a/packages/simplex-chat-client/types/typescript/src/events.ts b/packages/simplex-chat-client/types/typescript/src/events.ts index cc19305913..020b8077e4 100644 --- a/packages/simplex-chat-client/types/typescript/src/events.ts +++ b/packages/simplex-chat-client/types/typescript/src/events.ts @@ -9,6 +9,7 @@ export type ChatEvent = | CEvt.ContactDeletedByContact | CEvt.ReceivedContactRequest | CEvt.NewMemberContactReceivedInv + | CEvt.SimplexNameConflict | CEvt.ContactSndReady | CEvt.NewChatItems | CEvt.ChatItemReaction @@ -62,6 +63,7 @@ export namespace CEvt { | "contactDeletedByContact" | "receivedContactRequest" | "newMemberContactReceivedInv" + | "simplexNameConflict" | "contactSndReady" | "newChatItems" | "chatItemReaction" @@ -147,6 +149,15 @@ export namespace CEvt { member: T.GroupMember } + export interface SimplexNameConflict extends Interface { + type: "simplexNameConflict" + user: T.User + simplexName: T.SimplexNameInfo + entity: T.SimplexNameConflictEntity + claimedBy: string + displacedFrom: string + } + export interface ContactSndReady extends Interface { type: "contactSndReady" user: T.User diff --git a/packages/simplex-chat-client/types/typescript/src/types.ts b/packages/simplex-chat-client/types/typescript/src/types.ts index 0b58862be5..0cb27981c6 100644 --- a/packages/simplex-chat-client/types/typescript/src/types.ts +++ b/packages/simplex-chat-client/types/typescript/src/types.ts @@ -1009,6 +1009,9 @@ export type ChatErrorType = | ChatErrorType.ChatNotStopped | ChatErrorType.ChatStoreChanged | ChatErrorType.InvalidConnReq + | ChatErrorType.SimplexNameNotFound + | ChatErrorType.SimplexNameUnprepared + | ChatErrorType.SimplexNameResolverUnavailable | ChatErrorType.UnsupportedConnReq | ChatErrorType.ConnReqMessageProhibited | ChatErrorType.ContactNotReady @@ -1086,6 +1089,9 @@ export namespace ChatErrorType { | "chatNotStopped" | "chatStoreChanged" | "invalidConnReq" + | "simplexNameNotFound" + | "simplexNameUnprepared" + | "simplexNameResolverUnavailable" | "unsupportedConnReq" | "connReqMessageProhibited" | "contactNotReady" @@ -1240,6 +1246,21 @@ export namespace ChatErrorType { type: "invalidConnReq" } + export interface SimplexNameNotFound extends Interface { + type: "simplexNameNotFound" + simplexName: SimplexNameInfo + } + + export interface SimplexNameUnprepared extends Interface { + type: "simplexNameUnprepared" + simplexName: SimplexNameInfo + } + + export interface SimplexNameResolverUnavailable extends Interface { + type: "simplexNameResolverUnavailable" + simplexName: SimplexNameInfo + } + export interface UnsupportedConnReq extends Interface { type: "unsupportedConnReq" } @@ -1824,6 +1845,27 @@ export enum ConnType { Member = "member", User_contact = "user_contact", } +// Connect target: SimpleX link (`CTLink`) or SimpleX name (`CTName`). Wire form is the bare string returned by `strEncode` — `simplex:/...` for links, `#name.simplex` / `@name.simplex` for names. + +export type ConnectTarget = ConnectTarget.Link | ConnectTarget.Name + +export namespace ConnectTarget { + export type Tag = "link" | "name" + + interface Interface { + type: Tag + } + + export interface Link extends Interface { + type: "link" + : string + } + + export interface Name extends Interface { + type: "name" + : SimplexNameInfo + } +} export interface Connection { connId: number // int64 @@ -1850,6 +1892,7 @@ export interface Connection { authErrCounter: number // int quotaErrCounter: number // int createdAt: string // ISO-8601 timestamp + simplexName?: SimplexNameInfo } export type ConnectionEntity = @@ -1981,6 +2024,7 @@ export interface Contact { uiThemes?: UIThemeEntityOverrides chatDeleted: boolean customData?: object + simplexName?: SimplexNameInfo } export type ContactAddressPlan = @@ -2574,6 +2618,7 @@ export interface GroupInfo { membersRequireAttention: number // int viaGroupLinkUri?: string groupKeys?: GroupKeys + simplexName?: SimplexNameInfo } export interface GroupKeys { @@ -2760,6 +2805,7 @@ export interface GroupProfile { description?: string image?: string publicGroup?: PublicGroupProfile + simplexName?: SimplexNameInfo groupPreferences?: GroupPreferences memberAdmission?: GroupMemberAdmission } @@ -2941,6 +2987,7 @@ export interface LocalProfile { shortDescr?: string image?: string contactLink?: string + simplexName?: SimplexNameInfo preferences?: Preferences peerType?: ChatPeerType localAlias: string @@ -3292,6 +3339,7 @@ export interface Profile { shortDescr?: string image?: string contactLink?: string + simplexName?: SimplexNameInfo preferences?: Preferences peerType?: ChatPeerType } @@ -3863,6 +3911,11 @@ export enum SimplexLinkType { Relay = "relay", } +export enum SimplexNameConflictEntity { + Contact = "contact", + Group = "group", +} + export interface SimplexNameDomain { nameTLD: SimplexTLD domain: string diff --git a/packages/simplex-chat-python/src/simplex_chat/types/_commands.py b/packages/simplex-chat-python/src/simplex_chat/types/_commands.py index 3847f44811..d1ee8ec2d3 100644 --- a/packages/simplex-chat-python/src/simplex_chat/types/_commands.py +++ b/packages/simplex-chat-python/src/simplex_chat/types/_commands.py @@ -434,17 +434,17 @@ def APIAddContact_cmd_string(self: APIAddContact) -> str: APIAddContact_Response = CR.Invitation | CR.ChatCmdError -# Determine SimpleX link type and if the bot is already connected via this link. +# Determine SimpleX link type and if the bot is already connected via this link or name. # Network usage: interactive. class APIConnectPlan(TypedDict): userId: int # int64 - connectionLink: NotRequired[str] + connectTarget: NotRequired["T.ConnectTarget"] resolveKnown: bool linkOwnerSig: NotRequired["T.LinkOwnerSig"] def APIConnectPlan_cmd_string(self: APIConnectPlan) -> str: - return '/_connect plan ' + str(self['userId']) + ' ' + self.get('connectionLink') + return '/_connect plan ' + str(self['userId']) + ' ' + str(self.get('connectTarget')) APIConnectPlan_Response = CR.ConnectionPlan | CR.ChatCmdError @@ -463,15 +463,15 @@ def APIConnect_cmd_string(self: APIConnect) -> str: APIConnect_Response = CR.SentConfirmation | CR.ContactAlreadyExists | CR.SentInvitation | CR.ChatCmdError -# Connect via SimpleX link as string in the active user profile. +# Connect via SimpleX link or name as string in the active user profile. # Network usage: interactive. class Connect(TypedDict): incognito: bool - connLink_: NotRequired[str] + connTarget_: NotRequired["T.ConnectTarget"] def Connect_cmd_string(self: Connect) -> str: - return '/connect' + ((' ' + self.get('connLink_')) if self.get('connLink_') is not None else '') + return '/connect' + ((' ' + str(self.get('connTarget_'))) if self.get('connTarget_') is not None else '') Connect_Response = CR.SentConfirmation | CR.ContactAlreadyExists | CR.SentInvitation | CR.ChatCmdError diff --git a/packages/simplex-chat-python/src/simplex_chat/types/_events.py b/packages/simplex-chat-python/src/simplex_chat/types/_events.py index 7b7c724c92..9698323ce9 100644 --- a/packages/simplex-chat-python/src/simplex_chat/types/_events.py +++ b/packages/simplex-chat-python/src/simplex_chat/types/_events.py @@ -35,6 +35,14 @@ class NewMemberContactReceivedInv(TypedDict): groupInfo: "T.GroupInfo" member: "T.GroupMember" +class SimplexNameConflict(TypedDict): + type: Literal["simplexNameConflict"] + user: "T.User" + simplexName: "T.SimplexNameInfo" + entity: "T.SimplexNameConflictEntity" + claimedBy: str + displacedFrom: str + class ContactSndReady(TypedDict): type: Literal["contactSndReady"] user: "T.User" @@ -330,6 +338,7 @@ ChatEvent = ( | ContactDeletedByContact | ReceivedContactRequest | NewMemberContactReceivedInv + | SimplexNameConflict | ContactSndReady | NewChatItems | ChatItemReaction @@ -377,7 +386,7 @@ ChatEvent = ( | ChatErrors ) -ChatEvent_Tag = Literal["contactConnected", "contactUpdated", "contactDeletedByContact", "receivedContactRequest", "newMemberContactReceivedInv", "contactSndReady", "newChatItems", "chatItemReaction", "chatItemsDeleted", "chatItemUpdated", "groupChatItemsDeleted", "chatItemsStatusesUpdated", "receivedGroupInvitation", "userJoinedGroup", "groupUpdated", "joinedGroupMember", "memberRole", "deletedMember", "leftMember", "deletedMemberUser", "groupDeleted", "connectedToGroupMember", "memberAcceptedByOther", "memberBlockedForAll", "groupMemberUpdated", "groupLinkDataUpdated", "groupRelayUpdated", "rcvFileDescrReady", "rcvFileComplete", "sndFileCompleteXFTP", "rcvFileStart", "rcvFileSndCancelled", "rcvFileAccepted", "rcvFileError", "rcvFileWarning", "sndFileError", "sndFileWarning", "acceptingContactRequest", "acceptingBusinessRequest", "contactConnecting", "businessLinkConnecting", "joinedGroupMemberConnecting", "sentGroupInvitation", "groupLinkConnecting", "hostConnected", "hostDisconnected", "subscriptionStatus", "messageError", "chatError", "chatErrors"] +ChatEvent_Tag = Literal["contactConnected", "contactUpdated", "contactDeletedByContact", "receivedContactRequest", "newMemberContactReceivedInv", "simplexNameConflict", "contactSndReady", "newChatItems", "chatItemReaction", "chatItemsDeleted", "chatItemUpdated", "groupChatItemsDeleted", "chatItemsStatusesUpdated", "receivedGroupInvitation", "userJoinedGroup", "groupUpdated", "joinedGroupMember", "memberRole", "deletedMember", "leftMember", "deletedMemberUser", "groupDeleted", "connectedToGroupMember", "memberAcceptedByOther", "memberBlockedForAll", "groupMemberUpdated", "groupLinkDataUpdated", "groupRelayUpdated", "rcvFileDescrReady", "rcvFileComplete", "sndFileCompleteXFTP", "rcvFileStart", "rcvFileSndCancelled", "rcvFileAccepted", "rcvFileError", "rcvFileWarning", "sndFileError", "sndFileWarning", "acceptingContactRequest", "acceptingBusinessRequest", "contactConnecting", "businessLinkConnecting", "joinedGroupMemberConnecting", "sentGroupInvitation", "groupLinkConnecting", "hostConnected", "hostDisconnected", "subscriptionStatus", "messageError", "chatError", "chatErrors"] class OnEventDecorator(Protocol): @@ -418,6 +427,12 @@ class OnEventDecorator(Protocol): Callable[["NewMemberContactReceivedInv"], Awaitable[None]], ]: ... + @overload + def __call__(self, event: Literal["simplexNameConflict"], /) -> Callable[ + [Callable[["SimplexNameConflict"], Awaitable[None]]], + Callable[["SimplexNameConflict"], Awaitable[None]], + ]: ... + @overload def __call__(self, event: Literal["contactSndReady"], /) -> Callable[ [Callable[["ContactSndReady"], Awaitable[None]]], diff --git a/packages/simplex-chat-python/src/simplex_chat/types/_types.py b/packages/simplex-chat-python/src/simplex_chat/types/_types.py index 560d92f8e2..a049236340 100644 --- a/packages/simplex-chat-python/src/simplex_chat/types/_types.py +++ b/packages/simplex-chat-python/src/simplex_chat/types/_types.py @@ -769,6 +769,18 @@ class ChatErrorType_chatStoreChanged(TypedDict): class ChatErrorType_invalidConnReq(TypedDict): type: Literal["invalidConnReq"] +class ChatErrorType_simplexNameNotFound(TypedDict): + type: Literal["simplexNameNotFound"] + simplexName: "SimplexNameInfo" + +class ChatErrorType_simplexNameUnprepared(TypedDict): + type: Literal["simplexNameUnprepared"] + simplexName: "SimplexNameInfo" + +class ChatErrorType_simplexNameResolverUnavailable(TypedDict): + type: Literal["simplexNameResolverUnavailable"] + simplexName: "SimplexNameInfo" + class ChatErrorType_unsupportedConnReq(TypedDict): type: Literal["unsupportedConnReq"] @@ -999,6 +1011,9 @@ ChatErrorType = ( | ChatErrorType_chatNotStopped | ChatErrorType_chatStoreChanged | ChatErrorType_invalidConnReq + | ChatErrorType_simplexNameNotFound + | ChatErrorType_simplexNameUnprepared + | ChatErrorType_simplexNameResolverUnavailable | ChatErrorType_unsupportedConnReq | ChatErrorType_connReqMessageProhibited | ChatErrorType_contactNotReady @@ -1055,7 +1070,7 @@ ChatErrorType = ( | ChatErrorType_exception ) -ChatErrorType_Tag = Literal["noActiveUser", "noConnectionUser", "noSndFileUser", "noRcvFileUser", "userUnknown", "userExists", "chatRelayExists", "differentActiveUser", "cantDeleteActiveUser", "cantDeleteLastUser", "cantHideLastUser", "hiddenUserAlwaysMuted", "emptyUserPassword", "userAlreadyHidden", "userNotHidden", "invalidDisplayName", "chatNotStarted", "chatNotStopped", "chatStoreChanged", "invalidConnReq", "unsupportedConnReq", "connReqMessageProhibited", "contactNotReady", "contactNotActive", "contactDisabled", "connectionDisabled", "groupUserRole", "groupMemberInitialRole", "contactIncognitoCantInvite", "groupIncognitoCantInvite", "groupContactRole", "groupDuplicateMember", "groupDuplicateMemberId", "groupNotJoined", "groupMemberNotActive", "cantBlockMemberForSelf", "groupMemberUserRemoved", "groupMemberNotFound", "groupCantResendInvitation", "groupInternal", "fileNotFound", "fileSize", "fileAlreadyReceiving", "fileCancelled", "fileCancel", "fileAlreadyExists", "fileWrite", "fileSend", "fileRcvChunk", "fileInternal", "fileImageType", "fileImageSize", "fileNotReceived", "fileNotApproved", "fallbackToSMPProhibited", "inlineFileProhibited", "invalidForward", "invalidChatItemUpdate", "invalidChatItemDelete", "hasCurrentCall", "noCurrentCall", "callContact", "directMessagesProhibited", "agentVersion", "agentNoSubResult", "commandError", "agentCommandError", "invalidFileDescription", "connectionIncognitoChangeProhibited", "connectionUserChangeProhibited", "peerChatVRangeIncompatible", "relayTestError", "internalError", "exception"] +ChatErrorType_Tag = Literal["noActiveUser", "noConnectionUser", "noSndFileUser", "noRcvFileUser", "userUnknown", "userExists", "chatRelayExists", "differentActiveUser", "cantDeleteActiveUser", "cantDeleteLastUser", "cantHideLastUser", "hiddenUserAlwaysMuted", "emptyUserPassword", "userAlreadyHidden", "userNotHidden", "invalidDisplayName", "chatNotStarted", "chatNotStopped", "chatStoreChanged", "invalidConnReq", "simplexNameNotFound", "simplexNameUnprepared", "simplexNameResolverUnavailable", "unsupportedConnReq", "connReqMessageProhibited", "contactNotReady", "contactNotActive", "contactDisabled", "connectionDisabled", "groupUserRole", "groupMemberInitialRole", "contactIncognitoCantInvite", "groupIncognitoCantInvite", "groupContactRole", "groupDuplicateMember", "groupDuplicateMemberId", "groupNotJoined", "groupMemberNotActive", "cantBlockMemberForSelf", "groupMemberUserRemoved", "groupMemberNotFound", "groupCantResendInvitation", "groupInternal", "fileNotFound", "fileSize", "fileAlreadyReceiving", "fileCancelled", "fileCancel", "fileAlreadyExists", "fileWrite", "fileSend", "fileRcvChunk", "fileInternal", "fileImageType", "fileImageSize", "fileNotReceived", "fileNotApproved", "fallbackToSMPProhibited", "inlineFileProhibited", "invalidForward", "invalidChatItemUpdate", "invalidChatItemDelete", "hasCurrentCall", "noCurrentCall", "callContact", "directMessagesProhibited", "agentVersion", "agentNoSubResult", "commandError", "agentCommandError", "invalidFileDescription", "connectionIncognitoChangeProhibited", "connectionUserChangeProhibited", "peerChatVRangeIncompatible", "relayTestError", "internalError", "exception"] ChatFeature = Literal["timedMessages", "fullDelete", "reactions", "voice", "files", "calls", "sessions"] @@ -1273,6 +1288,20 @@ ConnStatus_Tag = Literal["new", "prepared", "joined", "requested", "accepted", " ConnType = Literal["contact", "member", "user_contact"] +# Connect target: SimpleX link (`CTLink`) or SimpleX name (`CTName`). Wire form is the bare string returned by `strEncode` — `simplex:/...` for links, `#name.simplex` / `@name.simplex` for names. + +class ConnectTarget_link(TypedDict): + type: Literal["link"] + : str + +class ConnectTarget_name(TypedDict): + type: Literal["name"] + : "SimplexNameInfo" + +ConnectTarget = ConnectTarget_link | ConnectTarget_name + +ConnectTarget_Tag = Literal["link", "name"] + class Connection(TypedDict): connId: int # int64 agentConnId: str @@ -1298,6 +1327,7 @@ class Connection(TypedDict): authErrCounter: int # int quotaErrCounter: int # int createdAt: str # ISO-8601 timestamp + simplexName: NotRequired["SimplexNameInfo"] class ConnectionEntity_rcvDirectMsgConnection(TypedDict): type: Literal["rcvDirectMsgConnection"] @@ -1398,6 +1428,7 @@ class Contact(TypedDict): uiThemes: NotRequired["UIThemeEntityOverrides"] chatDeleted: bool customData: NotRequired[dict[str, object]] + simplexName: NotRequired["SimplexNameInfo"] class ContactAddressPlan_ok(TypedDict): type: Literal["ok"] @@ -1809,6 +1840,7 @@ class GroupInfo(TypedDict): membersRequireAttention: int # int viaGroupLinkUri: NotRequired[str] groupKeys: NotRequired["GroupKeys"] + simplexName: NotRequired["SimplexNameInfo"] class GroupKeys(TypedDict): publicGroupId: str @@ -1936,6 +1968,7 @@ class GroupProfile(TypedDict): description: NotRequired[str] image: NotRequired[str] publicGroup: NotRequired["PublicGroupProfile"] + simplexName: NotRequired["SimplexNameInfo"] groupPreferences: NotRequired["GroupPreferences"] memberAdmission: NotRequired["GroupMemberAdmission"] @@ -2062,6 +2095,7 @@ class LocalProfile(TypedDict): shortDescr: NotRequired[str] image: NotRequired[str] contactLink: NotRequired[str] + simplexName: NotRequired["SimplexNameInfo"] preferences: NotRequired["Preferences"] peerType: NotRequired["ChatPeerType"] localAlias: str @@ -2313,6 +2347,7 @@ class Profile(TypedDict): shortDescr: NotRequired[str] image: NotRequired[str] contactLink: NotRequired[str] + simplexName: NotRequired["SimplexNameInfo"] preferences: NotRequired["Preferences"] peerType: NotRequired["ChatPeerType"] @@ -2700,6 +2735,8 @@ class SimplePreference(TypedDict): SimplexLinkType = Literal["contact", "invitation", "group", "channel", "relay"] +SimplexNameConflictEntity = Literal["contact", "group"] + class SimplexNameDomain(TypedDict): nameTLD: "SimplexTLD" domain: str