diff --git a/FlipcashCore/Sources/FlipcashCore/Clients/Payments API/Utilities/Interceptors/UserAgentInterceptor.swift b/FlipcashCore/Sources/FlipcashCore/Clients/Payments API/Utilities/Interceptors/UserAgentInterceptor.swift index 36e13f8c..2126fa7c 100644 --- a/FlipcashCore/Sources/FlipcashCore/Clients/Payments API/Utilities/Interceptors/UserAgentInterceptor.swift +++ b/FlipcashCore/Sources/FlipcashCore/Clients/Payments API/Utilities/Interceptors/UserAgentInterceptor.swift @@ -11,18 +11,34 @@ import GRPC import NIO import NIOHPACK +/// Attaches a `User-Agent` header to every outgoing gRPC request. +/// +/// The product name is derived from the RPC method path so that each +/// backend receives the user agent it expects: +/// - OCP server (`/ocp.*`) → `OpenCodeProtocol/iOS/{version}` +/// - Flipcash server → `Flipcash/iOS/{version}` class UserAgentInterceptor: ClientInterceptor, @unchecked Sendable { override func send(_ part: GRPCClientRequestPart, promise: EventLoopPromise?, context: ClientInterceptorContext) { var modifiedPart = part switch modifiedPart { case .metadata(var headers): - headers.add(.userAgent, value: "Flipcash/iOS/\(AppMeta.version)") + let product = Self.productName(for: context.path) + headers.add(.userAgent, value: "\(product)/iOS/\(AppMeta.version)") modifiedPart = .metadata(headers) default: break } context.send(modifiedPart, promise: promise) } + + /// Returns the product name for the `User-Agent` header based on + /// the gRPC method path (e.g. `/ocp.transaction.v1.Transaction/SubmitIntent`). + private static func productName(for path: String) -> String { + if path.hasPrefix("/ocp.") { + return "OpenCodeProtocol" + } + return "Flipcash" + } } // MARK: - App -