From 1084073a4d1a4c6f141384ebdbe0a5604d6878d3 Mon Sep 17 00:00:00 2001 From: Radmir Date: Fri, 5 Jun 2026 23:07:24 +0500 Subject: [PATCH 1/2] Rename support message delivery_status to status and remove agent avatar_url Regenerate iOS/Android typeshare bindings. This also syncs the generated Support/Stream models with the already-merged core simplification (drops the stale conversationId and SupportStreamEvent left by the core-only support merge). --- .../core/primitives/generated/Stream.kt | 2 +- .../core/primitives/generated/Support.kt | 34 +------- core/crates/primitives/src/support.rs | 4 +- core/crates/support/src/chatwoot.rs | 2 +- core/crates/support/src/model.rs | 14 +--- core/crates/support/tests/model_tests.rs | 3 +- .../Primitives/Sources/Generated/Stream.swift | 4 +- .../Sources/Generated/Support.swift | 80 +------------------ 8 files changed, 16 insertions(+), 127 deletions(-) diff --git a/android/gemcore/src/main/kotlin/com/wallet/core/primitives/generated/Stream.kt b/android/gemcore/src/main/kotlin/com/wallet/core/primitives/generated/Stream.kt index bd0e534126..fb7c0b3d69 100644 --- a/android/gemcore/src/main/kotlin/com/wallet/core/primitives/generated/Stream.kt +++ b/android/gemcore/src/main/kotlin/com/wallet/core/primitives/generated/Stream.kt @@ -68,7 +68,7 @@ sealed class StreamEvent { data class FiatTransaction(val data: StreamWalletUpdate): StreamEvent() @Serializable @SerialName("support") - data class Support(val data: SupportStreamEvent): StreamEvent() + data class Support(val data: SupportMessage): StreamEvent() } @Serializable diff --git a/android/gemcore/src/main/kotlin/com/wallet/core/primitives/generated/Support.kt b/android/gemcore/src/main/kotlin/com/wallet/core/primitives/generated/Support.kt index b8490e9fc1..a69ced6011 100644 --- a/android/gemcore/src/main/kotlin/com/wallet/core/primitives/generated/Support.kt +++ b/android/gemcore/src/main/kotlin/com/wallet/core/primitives/generated/Support.kt @@ -9,26 +9,7 @@ import kotlinx.serialization.SerialName @Serializable data class SupportAgent ( - val name: String, - val avatarUrl: String? = null -) - -@Serializable -enum class SupportConversationStatus(val string: String) { - @SerialName("open") - Open("open"), - @SerialName("resolved") - Resolved("resolved"), -} - -@Serializable -data class SupportConversation ( - val id: String, - val status: SupportConversationStatus, - val firstMessage: String? = null, - val lastMessage: String? = null, - val lastActivityAt: SerializedDate, - val unreadCount: Int + val name: String ) @Serializable @@ -65,10 +46,9 @@ data class SupportMessageImage ( @Serializable data class SupportMessage ( val id: String, - val conversationId: String, val content: String, val sender: SupportMessageSender, - val deliveryStatus: SupportMessageDeliveryStatus, + val status: SupportMessageDeliveryStatus, val createdAt: SerializedDate, val images: List ) @@ -88,16 +68,6 @@ sealed class SupportAction { object LastSeen: SupportAction() } -@Serializable -sealed class SupportStreamEvent { - @Serializable - @SerialName("message") - data class Message(val data: SupportMessage): SupportStreamEvent() - @Serializable - @SerialName("conversation") - data class Conversation(val data: SupportConversation): SupportStreamEvent() -} - @Serializable enum class SupportTypingStatus(val string: String) { @SerialName("on") diff --git a/core/crates/primitives/src/support.rs b/core/crates/primitives/src/support.rs index e4c017b75f..f1ec75fac8 100644 --- a/core/crates/primitives/src/support.rs +++ b/core/crates/primitives/src/support.rs @@ -17,8 +17,6 @@ pub enum SupportMessageDeliveryStatus { #[serde(rename_all = "camelCase")] pub struct SupportAgent { pub name: String, - #[serde(skip_serializing_if = "Option::is_none")] - pub avatar_url: Option, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -70,7 +68,7 @@ pub struct SupportMessage { pub id: String, pub content: String, pub sender: SupportMessageSender, - pub delivery_status: SupportMessageDeliveryStatus, + pub status: SupportMessageDeliveryStatus, pub created_at: DateTime, pub images: Vec, } diff --git a/core/crates/support/src/chatwoot.rs b/core/crates/support/src/chatwoot.rs index ca4f950946..8def316913 100644 --- a/core/crates/support/src/chatwoot.rs +++ b/core/crates/support/src/chatwoot.rs @@ -181,7 +181,7 @@ mod tests { id: id.to_string(), content: id.to_string(), sender: SupportMessageSender::User, - delivery_status: SupportMessageDeliveryStatus::Sent, + status: SupportMessageDeliveryStatus::Sent, created_at: chrono::DateTime::from_timestamp(timestamp, 0).unwrap(), images: vec![], } diff --git a/core/crates/support/src/model.rs b/core/crates/support/src/model.rs index 785544f157..b3a847131b 100644 --- a/core/crates/support/src/model.rs +++ b/core/crates/support/src/model.rs @@ -109,8 +109,6 @@ pub struct CustomAttributes { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Sender { pub name: Option, - pub avatar_url: Option, - pub thumbnail: Option, pub custom_attributes: Option, } @@ -205,10 +203,7 @@ impl Attachment { impl Sender { fn support_agent(&self) -> Option { let name = self.name.clone()?; - Some(SupportAgent { - name, - avatar_url: self.avatar_url.clone().or_else(|| self.thumbnail.clone()).filter(|value| !value.is_empty()), - }) + Some(SupportAgent { name }) } } @@ -306,7 +301,7 @@ fn support_message( content_type: Option<&str>, private: Option, sender: SupportMessageSender, - delivery_status: SupportMessageDeliveryStatus, + status: SupportMessageDeliveryStatus, created_at: DateTime, attachments: &[Attachment], ) -> Option { @@ -328,7 +323,7 @@ fn support_message( id: id.to_string(), content, sender, - delivery_status, + status, created_at, images, }) @@ -380,10 +375,9 @@ mod tests { messages[0].sender, SupportMessageSender::Agent(SupportAgent { name: "Test Agent".to_string(), - avatar_url: None, }) ); - assert_eq!(messages[0].delivery_status, SupportMessageDeliveryStatus::Sent); + assert_eq!(messages[0].status, SupportMessageDeliveryStatus::Sent); } #[test] diff --git a/core/crates/support/tests/model_tests.rs b/core/crates/support/tests/model_tests.rs index ef5441cb94..9f55807b7b 100644 --- a/core/crates/support/tests/model_tests.rs +++ b/core/crates/support/tests/model_tests.rs @@ -43,10 +43,9 @@ fn test_support_message_mapping() { message.sender, SupportMessageSender::Agent(SupportAgent { name: "Test Agent".to_string(), - avatar_url: None, }) ); - assert_eq!(message.delivery_status, SupportMessageDeliveryStatus::Sent); + assert_eq!(message.status, SupportMessageDeliveryStatus::Sent); } #[test] diff --git a/ios/Packages/Primitives/Sources/Generated/Stream.swift b/ios/Packages/Primitives/Sources/Generated/Stream.swift index 3b77ed28a1..d436d1e7ce 100644 --- a/ios/Packages/Primitives/Sources/Generated/Stream.swift +++ b/ios/Packages/Primitives/Sources/Generated/Stream.swift @@ -67,7 +67,7 @@ public enum StreamEvent: Codable, Sendable { case perpetual(StreamWalletUpdate) case inAppNotification(StreamNotificationUpdate) case fiatTransaction(StreamWalletUpdate) - case support(SupportStreamEvent) + case support(SupportMessage) enum CodingKeys: String, CodingKey, Codable { case prices, @@ -130,7 +130,7 @@ public enum StreamEvent: Codable, Sendable { return } case .support: - if let content = try? container.decode(SupportStreamEvent.self, forKey: .data) { + if let content = try? container.decode(SupportMessage.self, forKey: .data) { self = .support(content) return } diff --git a/ios/Packages/Primitives/Sources/Generated/Support.swift b/ios/Packages/Primitives/Sources/Generated/Support.swift index cd26af62fd..c0687365af 100644 --- a/ios/Packages/Primitives/Sources/Generated/Support.swift +++ b/ios/Packages/Primitives/Sources/Generated/Support.swift @@ -6,34 +6,9 @@ import Foundation public struct SupportAgent: Codable, Equatable, Sendable { public let name: String - public let avatarUrl: String? - public init(name: String, avatarUrl: String?) { + public init(name: String) { self.name = name - self.avatarUrl = avatarUrl - } -} - -public enum SupportConversationStatus: String, Codable, CaseIterable, Equatable, Sendable { - case open - case resolved -} - -public struct SupportConversation: Codable, Equatable, Hashable, Identifiable, Sendable { - public let id: String - public let status: SupportConversationStatus - public let firstMessage: String? - public let lastMessage: String? - public let lastActivityAt: Date - public let unreadCount: Int32 - - public init(id: String, status: SupportConversationStatus, firstMessage: String?, lastMessage: String?, lastActivityAt: Date, unreadCount: Int32) { - self.id = id - self.status = status - self.firstMessage = firstMessage - self.lastMessage = lastMessage - self.lastActivityAt = lastActivityAt - self.unreadCount = unreadCount } } @@ -107,19 +82,17 @@ public struct SupportMessageImage: Codable, Equatable, Sendable { public struct SupportMessage: Codable, Equatable, Sendable { public let id: String - public let conversationId: String public let content: String public let sender: SupportMessageSender - public let deliveryStatus: SupportMessageDeliveryStatus + public let status: SupportMessageDeliveryStatus public let createdAt: Date public let images: [SupportMessageImage] - public init(id: String, conversationId: String, content: String, sender: SupportMessageSender, deliveryStatus: SupportMessageDeliveryStatus, createdAt: Date, images: [SupportMessageImage]) { + public init(id: String, content: String, sender: SupportMessageSender, status: SupportMessageDeliveryStatus, createdAt: Date, images: [SupportMessageImage]) { self.id = id - self.conversationId = conversationId self.content = content self.sender = sender - self.deliveryStatus = deliveryStatus + self.status = status self.createdAt = createdAt self.images = images } @@ -175,51 +148,6 @@ public enum SupportAction: Codable, Equatable, Sendable { } } -public enum SupportStreamEvent: Codable, Sendable { - case message(SupportMessage) - case conversation(SupportConversation) - - enum CodingKeys: String, CodingKey, Codable { - case message, - conversation - } - - private enum ContainerCodingKeys: String, CodingKey { - case type, data - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: ContainerCodingKeys.self) - if let type = try? container.decode(CodingKeys.self, forKey: .type) { - switch type { - case .message: - if let content = try? container.decode(SupportMessage.self, forKey: .data) { - self = .message(content) - return - } - case .conversation: - if let content = try? container.decode(SupportConversation.self, forKey: .data) { - self = .conversation(content) - return - } - } - } - throw DecodingError.typeMismatch(SupportStreamEvent.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for SupportStreamEvent")) - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: ContainerCodingKeys.self) - switch self { - case .message(let content): - try container.encode(CodingKeys.message, forKey: .type) - try container.encode(content, forKey: .data) - case .conversation(let content): - try container.encode(CodingKeys.conversation, forKey: .type) - try container.encode(content, forKey: .data) - } - } -} - public enum SupportTypingStatus: String, Codable, CaseIterable, Equatable, Sendable { case on case off From c40f5ebd6c668d7378149714b2baef34f4e6b036 Mon Sep 17 00:00:00 2001 From: Radmir Date: Fri, 5 Jun 2026 23:25:10 +0500 Subject: [PATCH 2/2] Remove dead support conversation API from iOS and Android The core support simplification dropped SupportConversation/conversationId, but the core-only merge left getSupportConversation and related fields referencing removed types in the apps. Regenerating bindings exposed it as a build break (CI #465). --- .../data/services/gemapi/GemDeviceApiClient.kt | 4 ---- ios/Packages/GemAPI/Sources/GemAPIService.swift | 6 ------ ios/Packages/GemAPI/Sources/GemDeviceAPI.swift | 5 ----- .../TestKit/GemAPISupportService+TestKit.swift | 13 ++----------- 4 files changed, 2 insertions(+), 26 deletions(-) diff --git a/android/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/GemDeviceApiClient.kt b/android/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/GemDeviceApiClient.kt index 2244efba1d..a255d73373 100644 --- a/android/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/GemDeviceApiClient.kt +++ b/android/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/GemDeviceApiClient.kt @@ -22,7 +22,6 @@ import com.wallet.core.primitives.Rewards import com.wallet.core.primitives.ScanTransaction import com.wallet.core.primitives.ScanTransactionPayload import com.wallet.core.primitives.SupportAction -import com.wallet.core.primitives.SupportConversation import com.wallet.core.primitives.SupportMessage import com.wallet.core.primitives.SupportMessageInput import com.wallet.core.primitives.Transaction @@ -118,9 +117,6 @@ interface GemDeviceApiClient { @POST("/v2/devices/scan/transaction") suspend fun getScanTransaction(@Body payload: ScanTransactionPayload): ScanTransaction - @GET("/v2/devices/support") - suspend fun getSupportConversation(): SupportConversation? - @GET("/v2/devices/support/messages") suspend fun getSupportMessages( @Query("from_timestamp") fromTimestamp: Long, diff --git a/ios/Packages/GemAPI/Sources/GemAPIService.swift b/ios/Packages/GemAPI/Sources/GemAPIService.swift index d690ef5195..6e8f23384d 100644 --- a/ios/Packages/GemAPI/Sources/GemAPIService.swift +++ b/ios/Packages/GemAPI/Sources/GemAPIService.swift @@ -87,7 +87,6 @@ public protocol GemAPIScanService: Sendable { } public protocol GemAPISupportService: Sendable { - func getSupportConversation() async throws -> SupportConversation? func getSupportMessages(fromTimestamp: Int) async throws -> [SupportMessage] func sendSupportMessage(input: SupportMessageInput) async throws -> SupportMessage func sendSupportImage(image: Data, fileName: String, mimeType: String) async throws -> SupportMessage @@ -308,11 +307,6 @@ extension GemAPIService: GemAPIScanService { } extension GemAPIService: GemAPISupportService { - public func getSupportConversation() async throws -> SupportConversation? { - try await requestDevice(.getSupportConversation) - .mapResponse(as: SupportConversation?.self) - } - public func getSupportMessages(fromTimestamp: Int) async throws -> [SupportMessage] { try await requestDevice(.getSupportMessages(fromTimestamp: fromTimestamp)) .mapResponse(as: [SupportMessage].self) diff --git a/ios/Packages/GemAPI/Sources/GemDeviceAPI.swift b/ios/Packages/GemAPI/Sources/GemDeviceAPI.swift index 476a75d229..579ece5b71 100644 --- a/ios/Packages/GemAPI/Sources/GemDeviceAPI.swift +++ b/ios/Packages/GemAPI/Sources/GemDeviceAPI.swift @@ -29,7 +29,6 @@ public enum GemDeviceAPI: TargetType { case scanTransaction(payload: ScanTransactionPayload) case getWalletConfiguration(walletId: WalletId) - case getSupportConversation case getSupportMessages(fromTimestamp: Int) case sendSupportMessage(input: SupportMessageInput) case sendSupportImage(image: Data, fileName: String, mimeType: String) @@ -83,7 +82,6 @@ public enum GemDeviceAPI: TargetType { .getFiatTransactions, .getNameRecord, .getWalletConfiguration, - .getSupportConversation, .getSupportMessages: .GET case .addDevice, @@ -148,8 +146,6 @@ public enum GemDeviceAPI: TargetType { return "/v2/devices/scan/transaction" case .getWalletConfiguration: return "/v2/devices/wallet_configuration" - case .getSupportConversation: - return "/v2/devices/support" case let .getSupportMessages(fromTimestamp): return "/v2/devices/support/messages?from_timestamp=\(fromTimestamp)" case .sendSupportMessage: @@ -237,7 +233,6 @@ public enum GemDeviceAPI: TargetType { .getFiatQuoteUrl, .getFiatTransactions, .getNameRecord, - .getSupportConversation, .getSupportMessages: return .plain case let .getPriceAlerts(assetId): diff --git a/ios/Packages/GemAPI/TestKit/GemAPISupportService+TestKit.swift b/ios/Packages/GemAPI/TestKit/GemAPISupportService+TestKit.swift index eef7d7ca07..12511792c6 100644 --- a/ios/Packages/GemAPI/TestKit/GemAPISupportService+TestKit.swift +++ b/ios/Packages/GemAPI/TestKit/GemAPISupportService+TestKit.swift @@ -5,7 +5,6 @@ import GemAPI import Primitives public actor GemAPISupportServiceMock: GemAPISupportService { - private let conversation: SupportConversation? private let messages: [SupportMessage] public private(set) var sentMessages: [SupportMessageInput] = [] @@ -13,17 +12,11 @@ public actor GemAPISupportServiceMock: GemAPISupportService { public private(set) var sentActions: [SupportAction] = [] public init( - conversation: SupportConversation? = nil, messages: [SupportMessage] = [], ) { - self.conversation = conversation self.messages = messages } - public func getSupportConversation() async throws -> SupportConversation? { - conversation - } - public func getSupportMessages(fromTimestamp _: Int) async throws -> [SupportMessage] { messages } @@ -32,10 +25,9 @@ public actor GemAPISupportServiceMock: GemAPISupportService { sentMessages.append(input) return SupportMessage( id: "", - conversationId: "", content: input.content, sender: .user, - deliveryStatus: .sent, + status: .sent, createdAt: Date(), images: [], ) @@ -45,10 +37,9 @@ public actor GemAPISupportServiceMock: GemAPISupportService { sentImages.append((image, fileName, mimeType)) return SupportMessage( id: "", - conversationId: "", content: "", sender: .user, - deliveryStatus: .sent, + status: .sent, createdAt: Date(), images: [], )