diff --git a/bots/api/TYPES.md b/bots/api/TYPES.md index 1fcec37e57..e79f8638ad 100644 --- a/bots/api/TYPES.md +++ b/bots/api/TYPES.md @@ -14,6 +14,8 @@ This file is generated automatically. - [AutoAccept](#autoaccept) - [BadgeInfo](#badgeinfo) - [BadgeProof](#badgeproof) +- [BadgeRedeemError](#badgeredeemerror) +- [BadgeServiceErrorCode](#badgeserviceerrorcode) - [BadgeStatus](#badgestatus) - [BadgeType](#badgetype) - [BlockingInfo](#blockinginfo) @@ -433,6 +435,98 @@ Remote controller app version range (min and max as version strings). - badgeInfo: [BadgeInfo](#badgeinfo) +--- + +## BadgeRedeemError + +**Discriminated union type**: + +InvalidCode: +- type: "invalidCode" + +ServiceNotConfigured: +- type: "serviceNotConfigured" + +BadgeActive: +- type: "badgeActive" + +ServiceError: +- type: "serviceError" +- serviceError: [BadgeServiceErrorCode](#badgeserviceerrorcode) + +InvalidResponse: +- type: "invalidResponse" +- message: string + +UnknownKeyIndex: +- type: "unknownKeyIndex" + +CredentialNotVerified: +- type: "credentialNotVerified" + + +--- + +## BadgeServiceErrorCode + +**Discriminated union type**: + +BadRequest: +- type: "badRequest" + +UnsupportedVersion: +- type: "unsupportedVersion" + +UnknownPurchaseKey: +- type: "unknownPurchaseKey" + +UnknownOfferId: +- type: "unknownOfferId" + +OfferDisabled: +- type: "offerDisabled" + +OfferMismatch: +- type: "offerMismatch" + +ProductUnavailable: +- type: "productUnavailable" + +PaymentNotEntitled: +- type: "paymentNotEntitled" + +PaymentPending: +- type: "paymentPending" + +ProviderUnavailable: +- type: "providerUnavailable" + +RateLimited: +- type: "rateLimited" + +CodeInvalid: +- type: "codeInvalid" + +CodeUsed: +- type: "codeUsed" + +CodeExpired: +- type: "codeExpired" + +ReceiptInvalid: +- type: "receiptInvalid" + +ReceiptUsed: +- type: "receiptUsed" + +Internal: +- type: "internal" + +Unknown: +- type: "unknown" +- : string + + --- ## BadgeStatus @@ -1361,6 +1455,10 @@ CommandError: - type: "commandError" - message: string +BadgeRedeemError: +- type: "badgeRedeemError" +- badgeRedeemError: [BadgeRedeemError](#badgeredeemerror) + AgentCommandError: - type: "agentCommandError" - message: string diff --git a/bots/src/API/Docs/Types.hs b/bots/src/API/Docs/Types.hs index 06d3903600..70777afa21 100644 --- a/bots/src/API/Docs/Types.hs +++ b/bots/src/API/Docs/Types.hs @@ -35,6 +35,7 @@ import Simplex.Chat.Store.Shared import Simplex.Chat.Operators import Simplex.Messaging.Agent.Store.Entity (DBStored (..)) import Simplex.Chat.Badges +import Simplex.Chat.Badges.Service import Simplex.Chat.Names import Simplex.Chat.Types import Simplex.Chat.Types.Preferences @@ -49,7 +50,6 @@ import Simplex.Messaging.Parsers (dropPrefix, fstToLower) import Simplex.Messaging.Protocol (BlockingInfo (..), BlockingReason (..), CommandError (..), ErrorType (..), NameErrorType (..), NetworkError (..), ProxyError (..)) import Simplex.Messaging.Protocol.Types (ClientNotice (..)) import Simplex.Messaging.Transport -import Simplex.Chat.Remote.AppVersion (AppVersion, AppVersionRange) import Simplex.Chat.Remote.Types (CtrlAppInfo (..)) import Simplex.RemoteControl.Types import System.Console.ANSI.Types (Color (..)) @@ -216,6 +216,8 @@ chatTypesDocsData = (STI "AppVersionRange" [RecordTypeInfo "AppVersionRange" [FieldInfo "minVersion" (TIType (ST TString [])), FieldInfo "maxVersion" (TIType (ST TString []))]], STRecord, "", [], "", "Remote controller app version range (min and max as version strings)."), (sti @AutoAccept, STRecord, "", [], "", ""), (sti @BadgeProof, STRecord, "", [], "", ""), + (sti @BadgeRedeemError, STUnion, "BRE", [], "", ""), + (sti @BadgeServiceErrorCode, STUnion, "BSE", [], "", ""), (sti @BlockingInfo, STRecord, "", [], "", ""), (sti @BlockingReason, STEnum, "BR", [], "", ""), (sti @BrokerErrorType, STUnion, "", [], "", ""), @@ -450,6 +452,8 @@ deriving instance Generic AgentErrorType deriving instance Generic AgentServiceError deriving instance Generic AutoAccept deriving instance Generic BadgeProof +deriving instance Generic BadgeRedeemError +deriving instance Generic BadgeServiceErrorCode deriving instance Generic BlockingInfo deriving instance Generic BlockingReason deriving instance Generic BrokerErrorType diff --git a/packages/simplex-chat-client/types/typescript/src/types.ts b/packages/simplex-chat-client/types/typescript/src/types.ts index eff59d5c8f..170f5c5504 100644 --- a/packages/simplex-chat-client/types/typescript/src/types.ts +++ b/packages/simplex-chat-client/types/typescript/src/types.ts @@ -247,6 +247,179 @@ export interface BadgeProof { badgeInfo: BadgeInfo } +export type BadgeRedeemError = + | BadgeRedeemError.InvalidCode + | BadgeRedeemError.ServiceNotConfigured + | BadgeRedeemError.BadgeActive + | BadgeRedeemError.ServiceError + | BadgeRedeemError.InvalidResponse + | BadgeRedeemError.UnknownKeyIndex + | BadgeRedeemError.CredentialNotVerified + +export namespace BadgeRedeemError { + export type Tag = + | "invalidCode" + | "serviceNotConfigured" + | "badgeActive" + | "serviceError" + | "invalidResponse" + | "unknownKeyIndex" + | "credentialNotVerified" + + interface Interface { + type: Tag + } + + export interface InvalidCode extends Interface { + type: "invalidCode" + } + + export interface ServiceNotConfigured extends Interface { + type: "serviceNotConfigured" + } + + export interface BadgeActive extends Interface { + type: "badgeActive" + } + + export interface ServiceError extends Interface { + type: "serviceError" + serviceError: BadgeServiceErrorCode + } + + export interface InvalidResponse extends Interface { + type: "invalidResponse" + message: string + } + + export interface UnknownKeyIndex extends Interface { + type: "unknownKeyIndex" + } + + export interface CredentialNotVerified extends Interface { + type: "credentialNotVerified" + } +} + +export type BadgeServiceErrorCode = + | BadgeServiceErrorCode.BadRequest + | BadgeServiceErrorCode.UnsupportedVersion + | BadgeServiceErrorCode.UnknownPurchaseKey + | BadgeServiceErrorCode.UnknownOfferId + | BadgeServiceErrorCode.OfferDisabled + | BadgeServiceErrorCode.OfferMismatch + | BadgeServiceErrorCode.ProductUnavailable + | BadgeServiceErrorCode.PaymentNotEntitled + | BadgeServiceErrorCode.PaymentPending + | BadgeServiceErrorCode.ProviderUnavailable + | BadgeServiceErrorCode.RateLimited + | BadgeServiceErrorCode.CodeInvalid + | BadgeServiceErrorCode.CodeUsed + | BadgeServiceErrorCode.CodeExpired + | BadgeServiceErrorCode.ReceiptInvalid + | BadgeServiceErrorCode.ReceiptUsed + | BadgeServiceErrorCode.Internal + | BadgeServiceErrorCode.Unknown + +export namespace BadgeServiceErrorCode { + export type Tag = + | "badRequest" + | "unsupportedVersion" + | "unknownPurchaseKey" + | "unknownOfferId" + | "offerDisabled" + | "offerMismatch" + | "productUnavailable" + | "paymentNotEntitled" + | "paymentPending" + | "providerUnavailable" + | "rateLimited" + | "codeInvalid" + | "codeUsed" + | "codeExpired" + | "receiptInvalid" + | "receiptUsed" + | "internal" + | "unknown" + + interface Interface { + type: Tag + } + + export interface BadRequest extends Interface { + type: "badRequest" + } + + export interface UnsupportedVersion extends Interface { + type: "unsupportedVersion" + } + + export interface UnknownPurchaseKey extends Interface { + type: "unknownPurchaseKey" + } + + export interface UnknownOfferId extends Interface { + type: "unknownOfferId" + } + + export interface OfferDisabled extends Interface { + type: "offerDisabled" + } + + export interface OfferMismatch extends Interface { + type: "offerMismatch" + } + + export interface ProductUnavailable extends Interface { + type: "productUnavailable" + } + + export interface PaymentNotEntitled extends Interface { + type: "paymentNotEntitled" + } + + export interface PaymentPending extends Interface { + type: "paymentPending" + } + + export interface ProviderUnavailable extends Interface { + type: "providerUnavailable" + } + + export interface RateLimited extends Interface { + type: "rateLimited" + } + + export interface CodeInvalid extends Interface { + type: "codeInvalid" + } + + export interface CodeUsed extends Interface { + type: "codeUsed" + } + + export interface CodeExpired extends Interface { + type: "codeExpired" + } + + export interface ReceiptInvalid extends Interface { + type: "receiptInvalid" + } + + export interface ReceiptUsed extends Interface { + type: "receiptUsed" + } + + export interface Internal extends Interface { + type: "internal" + } + + export interface Unknown extends Interface { + type: "unknown" + : string + } +} + export enum BadgeStatus { Active = "active", Expired = "expired", @@ -1153,6 +1326,7 @@ export type ChatErrorType = | ChatErrorType.AgentVersion | ChatErrorType.AgentNoSubResult | ChatErrorType.CommandError + | ChatErrorType.BadgeRedeemError | ChatErrorType.AgentCommandError | ChatErrorType.InvalidFileDescription | ChatErrorType.ConnectionIncognitoChangeProhibited @@ -1232,6 +1406,7 @@ export namespace ChatErrorType { | "agentVersion" | "agentNoSubResult" | "commandError" + | "badgeRedeemError" | "agentCommandError" | "invalidFileDescription" | "connectionIncognitoChangeProhibited" @@ -1576,6 +1751,11 @@ export namespace ChatErrorType { message: string } + export interface BadgeRedeemError extends Interface { + type: "badgeRedeemError" + badgeRedeemError: BadgeRedeemError + } + export interface AgentCommandError extends Interface { type: "agentCommandError" message: string 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 15cdc842a0..38e0318af1 100644 --- a/packages/simplex-chat-python/src/simplex_chat/types/_types.py +++ b/packages/simplex-chat-python/src/simplex_chat/types/_types.py @@ -185,6 +185,119 @@ class BadgeProof(TypedDict): proof: str badgeInfo: "BadgeInfo" +class BadgeRedeemError_invalidCode(TypedDict): + type: Literal["invalidCode"] + +class BadgeRedeemError_serviceNotConfigured(TypedDict): + type: Literal["serviceNotConfigured"] + +class BadgeRedeemError_badgeActive(TypedDict): + type: Literal["badgeActive"] + +class BadgeRedeemError_serviceError(TypedDict): + type: Literal["serviceError"] + serviceError: "BadgeServiceErrorCode" + +class BadgeRedeemError_invalidResponse(TypedDict): + type: Literal["invalidResponse"] + message: str + +class BadgeRedeemError_unknownKeyIndex(TypedDict): + type: Literal["unknownKeyIndex"] + +class BadgeRedeemError_credentialNotVerified(TypedDict): + type: Literal["credentialNotVerified"] + +BadgeRedeemError = ( + BadgeRedeemError_invalidCode + | BadgeRedeemError_serviceNotConfigured + | BadgeRedeemError_badgeActive + | BadgeRedeemError_serviceError + | BadgeRedeemError_invalidResponse + | BadgeRedeemError_unknownKeyIndex + | BadgeRedeemError_credentialNotVerified +) + +BadgeRedeemError_Tag = Literal["invalidCode", "serviceNotConfigured", "badgeActive", "serviceError", "invalidResponse", "unknownKeyIndex", "credentialNotVerified"] + +class BadgeServiceErrorCode_badRequest(TypedDict): + type: Literal["badRequest"] + +class BadgeServiceErrorCode_unsupportedVersion(TypedDict): + type: Literal["unsupportedVersion"] + +class BadgeServiceErrorCode_unknownPurchaseKey(TypedDict): + type: Literal["unknownPurchaseKey"] + +class BadgeServiceErrorCode_unknownOfferId(TypedDict): + type: Literal["unknownOfferId"] + +class BadgeServiceErrorCode_offerDisabled(TypedDict): + type: Literal["offerDisabled"] + +class BadgeServiceErrorCode_offerMismatch(TypedDict): + type: Literal["offerMismatch"] + +class BadgeServiceErrorCode_productUnavailable(TypedDict): + type: Literal["productUnavailable"] + +class BadgeServiceErrorCode_paymentNotEntitled(TypedDict): + type: Literal["paymentNotEntitled"] + +class BadgeServiceErrorCode_paymentPending(TypedDict): + type: Literal["paymentPending"] + +class BadgeServiceErrorCode_providerUnavailable(TypedDict): + type: Literal["providerUnavailable"] + +class BadgeServiceErrorCode_rateLimited(TypedDict): + type: Literal["rateLimited"] + +class BadgeServiceErrorCode_codeInvalid(TypedDict): + type: Literal["codeInvalid"] + +class BadgeServiceErrorCode_codeUsed(TypedDict): + type: Literal["codeUsed"] + +class BadgeServiceErrorCode_codeExpired(TypedDict): + type: Literal["codeExpired"] + +class BadgeServiceErrorCode_receiptInvalid(TypedDict): + type: Literal["receiptInvalid"] + +class BadgeServiceErrorCode_receiptUsed(TypedDict): + type: Literal["receiptUsed"] + +class BadgeServiceErrorCode_internal(TypedDict): + type: Literal["internal"] + +class BadgeServiceErrorCode_unknown(TypedDict): + type: Literal["unknown"] + : str + +BadgeServiceErrorCode = ( + BadgeServiceErrorCode_badRequest + | BadgeServiceErrorCode_unsupportedVersion + | BadgeServiceErrorCode_unknownPurchaseKey + | BadgeServiceErrorCode_unknownOfferId + | BadgeServiceErrorCode_offerDisabled + | BadgeServiceErrorCode_offerMismatch + | BadgeServiceErrorCode_productUnavailable + | BadgeServiceErrorCode_paymentNotEntitled + | BadgeServiceErrorCode_paymentPending + | BadgeServiceErrorCode_providerUnavailable + | BadgeServiceErrorCode_rateLimited + | BadgeServiceErrorCode_codeInvalid + | BadgeServiceErrorCode_codeUsed + | BadgeServiceErrorCode_codeExpired + | BadgeServiceErrorCode_receiptInvalid + | BadgeServiceErrorCode_receiptUsed + | BadgeServiceErrorCode_internal + | BadgeServiceErrorCode_unknown +) + +BadgeServiceErrorCode_Tag = Literal["badRequest", "unsupportedVersion", "unknownPurchaseKey", "unknownOfferId", "offerDisabled", "offerMismatch", "productUnavailable", "paymentNotEntitled", "paymentPending", "providerUnavailable", "rateLimited", "codeInvalid", "codeUsed", "codeExpired", "receiptInvalid", "receiptUsed", "internal", "unknown"] + BadgeStatus = Literal["active", "expired", "expiredOld", "failed", "unknownKey"] BadgeType = Literal["supporter", "legend", "investor"] @@ -1029,6 +1142,10 @@ class ChatErrorType_commandError(TypedDict): type: Literal["commandError"] message: str +class ChatErrorType_badgeRedeemError(TypedDict): + type: Literal["badgeRedeemError"] + badgeRedeemError: "BadgeRedeemError" + class ChatErrorType_agentCommandError(TypedDict): type: Literal["agentCommandError"] message: str @@ -1127,6 +1244,7 @@ ChatErrorType = ( | ChatErrorType_agentVersion | ChatErrorType_agentNoSubResult | ChatErrorType_commandError + | ChatErrorType_badgeRedeemError | ChatErrorType_agentCommandError | ChatErrorType_invalidFileDescription | ChatErrorType_connectionIncognitoChangeProhibited @@ -1137,7 +1255,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", "simplexDomainNotReady", "notResolvedLocally", "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", "simplexDomainNotReady", "notResolvedLocally", "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", "badgeRedeemError", "agentCommandError", "invalidFileDescription", "connectionIncognitoChangeProhibited", "connectionUserChangeProhibited", "peerChatVRangeIncompatible", "relayTestError", "internalError", "exception"] ChatFeature = Literal["timedMessages", "fullDelete", "reactions", "voice", "files", "calls", "sessions"] diff --git a/src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt b/src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt index 6726d2ffaf..10cf2b93c2 100644 --- a/src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt +++ b/src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt @@ -7723,7 +7723,7 @@ Query: SELECT xgrplinkmem_received FROM group_members WHERE group_member_id = ? Plan: SEARCH group_members USING INTEGER PRIMARY KEY (rowid=?) -Query: UPDATE badge_purchases SET alert_acked_kind = ?, alert_acked_episode = ?, alert_snooze_until = ? WHERE badge_purchase_id = ? +Query: UPDATE badge_purchases SET alert_acked_kind = ?, alert_acked_episode = ?, alert_snooze_until = ? WHERE badge_purchase_id = ? AND user_id = ? Plan: SEARCH badge_purchases USING INTEGER PRIMARY KEY (rowid=?)