From 3141742168a5810a1470fc04c547f018c61b5489 Mon Sep 17 00:00:00 2001 From: Brandon McAnsh Date: Thu, 27 Aug 2026 12:16:50 -0400 Subject: [PATCH 1/2] chore(contract): sync flipcash2 protos to 0300d252 Picks up SetMinDmChatInitFee on the Profile service and the matching UserProfile.min_dm_chat_init_fee field. Additive only, so no existing field or enum case renumbers. --- .../profile_v1_model.pb.swift | 21 ++- .../profile_v1_profile_service.grpc.swift | 136 +++++++++++++++ .../profile_v1_profile_service.pb.swift | 157 ++++++++++++++++++ flipcash2.lock | 4 +- proto/profile/v1/model.proto | 6 + proto/profile/v1/profile_service.proto | 20 +++ 6 files changed, 341 insertions(+), 3 deletions(-) diff --git a/Sources/Flipcash2ClientProtocol/profile_v1_model.pb.swift b/Sources/Flipcash2ClientProtocol/profile_v1_model.pb.swift index b555f55..ab7d694 100644 --- a/Sources/Flipcash2ClientProtocol/profile_v1_model.pb.swift +++ b/Sources/Flipcash2ClientProtocol/profile_v1_model.pb.swift @@ -115,6 +115,19 @@ public struct Flipcash_Profile_V1_UserProfile: Sendable { /// Clears the value of `tipCardCustomization`. Subsequent reads from it will return its default value. public mutating func clearTipCardCustomization() {self._tipCardCustomization = nil} + /// The minimum fee another user must pay to initialize a DM chat with this + /// user. Public, so it is returned for any user, not just the caller. Unset + /// when the user hasn't set one, in which case the server default applies. + /// Update it with SetMinDmChatInitFee. + public var minDmChatInitFee: Flipcash_Common_V1_FiatPaymentAmount { + get {return _minDmChatInitFee ?? Flipcash_Common_V1_FiatPaymentAmount()} + set {_minDmChatInitFee = newValue} + } + /// Returns true if `minDmChatInitFee` has been explicitly set. + public var hasMinDmChatInitFee: Bool {return self._minDmChatInitFee != nil} + /// Clears the value of `minDmChatInitFee`. Subsequent reads from it will return its default value. + public mutating func clearMinDmChatInitFee() {self._minDmChatInitFee = nil} + public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} @@ -126,6 +139,7 @@ public struct Flipcash_Profile_V1_UserProfile: Sendable { fileprivate var _profilePicture: Flipcash_Blob_V1_Media? = nil fileprivate var _joinTs: SwiftProtobuf.Google_Protobuf_Timestamp? = nil fileprivate var _tipCardCustomization: Flipcash_Profile_V1_TipCardCustomization? = nil + fileprivate var _minDmChatInitFee: Flipcash_Common_V1_FiatPaymentAmount? = nil } public struct Flipcash_Profile_V1_SocialProfile: Sendable { @@ -256,7 +270,7 @@ fileprivate let _protobuf_package = "flipcash.profile.v1" extension Flipcash_Profile_V1_UserProfile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".UserProfile" - public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}display_name\0\u{3}social_profiles\0\u{3}phone_number\0\u{3}email_address\0\u{3}profile_picture\0\u{3}join_ts\0\u{3}tip_card_customization\0\u{1}username\0\u{3}user_id\0") + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}display_name\0\u{3}social_profiles\0\u{3}phone_number\0\u{3}email_address\0\u{3}profile_picture\0\u{3}join_ts\0\u{3}tip_card_customization\0\u{1}username\0\u{3}user_id\0\u{3}min_dm_chat_init_fee\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -273,6 +287,7 @@ extension Flipcash_Profile_V1_UserProfile: SwiftProtobuf.Message, SwiftProtobuf. case 7: try { try decoder.decodeSingularMessageField(value: &self._tipCardCustomization) }() case 8: try { try decoder.decodeSingularMessageField(value: &self._username) }() case 9: try { try decoder.decodeSingularMessageField(value: &self._userID) }() + case 10: try { try decoder.decodeSingularMessageField(value: &self._minDmChatInitFee) }() default: break } } @@ -310,6 +325,9 @@ extension Flipcash_Profile_V1_UserProfile: SwiftProtobuf.Message, SwiftProtobuf. try { if let v = self._userID { try visitor.visitSingularMessageField(value: v, fieldNumber: 9) } }() + try { if let v = self._minDmChatInitFee { + try visitor.visitSingularMessageField(value: v, fieldNumber: 10) + } }() try unknownFields.traverse(visitor: &visitor) } @@ -323,6 +341,7 @@ extension Flipcash_Profile_V1_UserProfile: SwiftProtobuf.Message, SwiftProtobuf. if lhs._profilePicture != rhs._profilePicture {return false} if lhs._joinTs != rhs._joinTs {return false} if lhs._tipCardCustomization != rhs._tipCardCustomization {return false} + if lhs._minDmChatInitFee != rhs._minDmChatInitFee {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } diff --git a/Sources/Flipcash2ClientProtocol/profile_v1_profile_service.grpc.swift b/Sources/Flipcash2ClientProtocol/profile_v1_profile_service.grpc.swift index d099b01..949d59a 100644 --- a/Sources/Flipcash2ClientProtocol/profile_v1_profile_service.grpc.swift +++ b/Sources/Flipcash2ClientProtocol/profile_v1_profile_service.grpc.swift @@ -80,6 +80,18 @@ public enum Flipcash_Profile_V1_Profile { method: "UpdateTipCard" ) } + /// Namespace for "SetMinDmChatInitFee" metadata. + public enum SetMinDmChatInitFee { + /// Request type for "SetMinDmChatInitFee". + public typealias Input = Flipcash_Profile_V1_SetMinDmChatInitFeeRequest + /// Response type for "SetMinDmChatInitFee". + public typealias Output = Flipcash_Profile_V1_SetMinDmChatInitFeeResponse + /// Descriptor for "SetMinDmChatInitFee". + public static let descriptor = GRPCCore.MethodDescriptor( + service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "flipcash.profile.v1.Profile"), + method: "SetMinDmChatInitFee" + ) + } /// Namespace for "LinkSocialAccount" metadata. public enum LinkSocialAccount { /// Request type for "LinkSocialAccount". @@ -111,6 +123,7 @@ public enum Flipcash_Profile_V1_Profile { SetUsername.descriptor, SetProfilePicture.descriptor, UpdateTipCard.descriptor, + SetMinDmChatInitFee.descriptor, LinkSocialAccount.descriptor, UnlinkSocialAccount.descriptor ] @@ -247,6 +260,30 @@ extension Flipcash_Profile_V1_Profile { onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse) async throws -> Result ) async throws -> Result where Result: Sendable + /// Call the "SetMinDmChatInitFee" method. + /// + /// > Source IDL Documentation: + /// > + /// > SetMinDmChatInitFee sets the minimum fee another user must pay to + /// > initialize a DM chat with the caller, replacing any fee already set. + /// + /// - Parameters: + /// - request: A request containing a single `Flipcash_Profile_V1_SetMinDmChatInitFeeRequest` message. + /// - serializer: A serializer for `Flipcash_Profile_V1_SetMinDmChatInitFeeRequest` messages. + /// - deserializer: A deserializer for `Flipcash_Profile_V1_SetMinDmChatInitFeeResponse` messages. + /// - options: Options to apply to this RPC. + /// - handleResponse: A closure which handles the response, the result of which is + /// returned to the caller. Returning from the closure will cancel the RPC if it + /// hasn't already finished. + /// - Returns: The result of `handleResponse`. + func setMinDmChatInitFee( + request: GRPCCore.ClientRequest, + serializer: some GRPCCore.MessageSerializer, + deserializer: some GRPCCore.MessageDeserializer, + options: GRPCCore.CallOptions, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse) async throws -> Result + ) async throws -> Result where Result: Sendable + /// Call the "LinkSocialAccount" method. /// /// > Source IDL Documentation: @@ -480,6 +517,41 @@ extension Flipcash_Profile_V1_Profile { ) } + /// Call the "SetMinDmChatInitFee" method. + /// + /// > Source IDL Documentation: + /// > + /// > SetMinDmChatInitFee sets the minimum fee another user must pay to + /// > initialize a DM chat with the caller, replacing any fee already set. + /// + /// - Parameters: + /// - request: A request containing a single `Flipcash_Profile_V1_SetMinDmChatInitFeeRequest` message. + /// - serializer: A serializer for `Flipcash_Profile_V1_SetMinDmChatInitFeeRequest` messages. + /// - deserializer: A deserializer for `Flipcash_Profile_V1_SetMinDmChatInitFeeResponse` messages. + /// - options: Options to apply to this RPC. + /// - handleResponse: A closure which handles the response, the result of which is + /// returned to the caller. Returning from the closure will cancel the RPC if it + /// hasn't already finished. + /// - Returns: The result of `handleResponse`. + public func setMinDmChatInitFee( + request: GRPCCore.ClientRequest, + serializer: some GRPCCore.MessageSerializer, + deserializer: some GRPCCore.MessageDeserializer, + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse) async throws -> Result = { response in + try response.message + } + ) async throws -> Result where Result: Sendable { + try await self.client.unary( + request: request, + descriptor: Flipcash_Profile_V1_Profile.Method.SetMinDmChatInitFee.descriptor, + serializer: serializer, + deserializer: deserializer, + options: options, + onResponse: handleResponse + ) + } + /// Call the "LinkSocialAccount" method. /// /// > Source IDL Documentation: @@ -698,6 +770,36 @@ extension Flipcash_Profile_V1_Profile.ClientProtocol { ) } + /// Call the "SetMinDmChatInitFee" method. + /// + /// > Source IDL Documentation: + /// > + /// > SetMinDmChatInitFee sets the minimum fee another user must pay to + /// > initialize a DM chat with the caller, replacing any fee already set. + /// + /// - Parameters: + /// - request: A request containing a single `Flipcash_Profile_V1_SetMinDmChatInitFeeRequest` message. + /// - options: Options to apply to this RPC. + /// - handleResponse: A closure which handles the response, the result of which is + /// returned to the caller. Returning from the closure will cancel the RPC if it + /// hasn't already finished. + /// - Returns: The result of `handleResponse`. + public func setMinDmChatInitFee( + request: GRPCCore.ClientRequest, + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse) async throws -> Result = { response in + try response.message + } + ) async throws -> Result where Result: Sendable { + try await self.setMinDmChatInitFee( + request: request, + serializer: GRPCProtobuf.ProtobufSerializer(), + deserializer: GRPCProtobuf.ProtobufDeserializer(), + options: options, + onResponse: handleResponse + ) + } + /// Call the "LinkSocialAccount" method. /// /// > Source IDL Documentation: @@ -925,6 +1027,40 @@ extension Flipcash_Profile_V1_Profile.ClientProtocol { ) } + /// Call the "SetMinDmChatInitFee" method. + /// + /// > Source IDL Documentation: + /// > + /// > SetMinDmChatInitFee sets the minimum fee another user must pay to + /// > initialize a DM chat with the caller, replacing any fee already set. + /// + /// - Parameters: + /// - message: request message to send. + /// - metadata: Additional metadata to send, defaults to empty. + /// - options: Options to apply to this RPC, defaults to `.defaults`. + /// - handleResponse: A closure which handles the response, the result of which is + /// returned to the caller. Returning from the closure will cancel the RPC if it + /// hasn't already finished. + /// - Returns: The result of `handleResponse`. + public func setMinDmChatInitFee( + _ message: Flipcash_Profile_V1_SetMinDmChatInitFeeRequest, + metadata: GRPCCore.Metadata = [:], + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse) async throws -> Result = { response in + try response.message + } + ) async throws -> Result where Result: Sendable { + let request = GRPCCore.ClientRequest( + message: message, + metadata: metadata + ) + return try await self.setMinDmChatInitFee( + request: request, + options: options, + onResponse: handleResponse + ) + } + /// Call the "LinkSocialAccount" method. /// /// > Source IDL Documentation: diff --git a/Sources/Flipcash2ClientProtocol/profile_v1_profile_service.pb.swift b/Sources/Flipcash2ClientProtocol/profile_v1_profile_service.pb.swift index 4256fac..0f34c58 100644 --- a/Sources/Flipcash2ClientProtocol/profile_v1_profile_service.pb.swift +++ b/Sources/Flipcash2ClientProtocol/profile_v1_profile_service.pb.swift @@ -516,6 +516,90 @@ public struct Flipcash_Profile_V1_UpdateTipCardResponse: Sendable { public init() {} } +public struct Flipcash_Profile_V1_SetMinDmChatInitFeeRequest: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The new minimum DM chat initialization fee to set. + public var minDmChatInitFee: Flipcash_Common_V1_FiatPaymentAmount { + get {return _minDmChatInitFee ?? Flipcash_Common_V1_FiatPaymentAmount()} + set {_minDmChatInitFee = newValue} + } + /// Returns true if `minDmChatInitFee` has been explicitly set. + public var hasMinDmChatInitFee: Bool {return self._minDmChatInitFee != nil} + /// Clears the value of `minDmChatInitFee`. Subsequent reads from it will return its default value. + public mutating func clearMinDmChatInitFee() {self._minDmChatInitFee = nil} + + public var auth: Flipcash_Common_V1_Auth { + get {return _auth ?? Flipcash_Common_V1_Auth()} + set {_auth = newValue} + } + /// Returns true if `auth` has been explicitly set. + public var hasAuth: Bool {return self._auth != nil} + /// Clears the value of `auth`. Subsequent reads from it will return its default value. + public mutating func clearAuth() {self._auth = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _minDmChatInitFee: Flipcash_Common_V1_FiatPaymentAmount? = nil + fileprivate var _auth: Flipcash_Common_V1_Auth? = nil +} + +public struct Flipcash_Profile_V1_SetMinDmChatInitFeeResponse: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var result: Flipcash_Profile_V1_SetMinDmChatInitFeeResponse.Result = .ok + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public enum Result: SwiftProtobuf.Enum, Swift.CaseIterable { + public typealias RawValue = Int + case ok // = 0 + case denied // = 1 + + /// e.g. unsupported currency, or amount outside the allowed range + case invalidAmount // = 2 + case UNRECOGNIZED(Int) + + public init() { + self = .ok + } + + public init?(rawValue: Int) { + switch rawValue { + case 0: self = .ok + case 1: self = .denied + case 2: self = .invalidAmount + default: self = .UNRECOGNIZED(rawValue) + } + } + + public var rawValue: Int { + switch self { + case .ok: return 0 + case .denied: return 1 + case .invalidAmount: return 2 + case .UNRECOGNIZED(let i): return i + } + } + + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Flipcash_Profile_V1_SetMinDmChatInitFeeResponse.Result] = [ + .ok, + .denied, + .invalidAmount, + ] + + } + + public init() {} +} + public struct Flipcash_Profile_V1_LinkSocialAccountRequest: Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for @@ -1157,6 +1241,79 @@ extension Flipcash_Profile_V1_UpdateTipCardResponse.Result: SwiftProtobuf._Proto public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0OK\0\u{1}DENIED\0\u{1}INVALID_COLOR\0") } +extension Flipcash_Profile_V1_SetMinDmChatInitFeeRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".SetMinDmChatInitFeeRequest" + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}min_dm_chat_init_fee\0\u{2}\u{9}auth\0") + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._minDmChatInitFee) }() + case 10: try { try decoder.decodeSingularMessageField(value: &self._auth) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._minDmChatInitFee { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + try { if let v = self._auth { + try visitor.visitSingularMessageField(value: v, fieldNumber: 10) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flipcash_Profile_V1_SetMinDmChatInitFeeRequest, rhs: Flipcash_Profile_V1_SetMinDmChatInitFeeRequest) -> Bool { + if lhs._minDmChatInitFee != rhs._minDmChatInitFee {return false} + if lhs._auth != rhs._auth {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flipcash_Profile_V1_SetMinDmChatInitFeeResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".SetMinDmChatInitFeeResponse" + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}result\0") + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self.result) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.result != .ok { + try visitor.visitSingularEnumField(value: self.result, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flipcash_Profile_V1_SetMinDmChatInitFeeResponse, rhs: Flipcash_Profile_V1_SetMinDmChatInitFeeResponse) -> Bool { + if lhs.result != rhs.result {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flipcash_Profile_V1_SetMinDmChatInitFeeResponse.Result: SwiftProtobuf._ProtoNameProviding { + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0OK\0\u{1}DENIED\0\u{1}INVALID_AMOUNT\0") +} + extension Flipcash_Profile_V1_LinkSocialAccountRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".LinkSocialAccountRequest" public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}linking_token\0\u{2}\u{9}auth\0") diff --git a/flipcash2.lock b/flipcash2.lock index f507d99..6f4fdf8 100644 --- a/flipcash2.lock +++ b/flipcash2.lock @@ -1,4 +1,4 @@ # Pinned upstream contract. Regenerate with scripts/sync-protos.sh . upstream: code-payments/flipcash2-protobuf-api -commit: 0410e78f0b24c1f9ecb069f969324edb96612bd5 -subject: Add username_min_balance to UserFlags (#87) +commit: 0300d252f35f3524e067aeef22382012c754902a +subject: Add the ability to set a minimum DM initialization fee (#88) diff --git a/proto/profile/v1/model.proto b/proto/profile/v1/model.proto index c02c0bb..3274fc2 100644 --- a/proto/profile/v1/model.proto +++ b/proto/profile/v1/model.proto @@ -59,6 +59,12 @@ message UserProfile { // any user, not just the caller. Always set — the server resolves defaults // for anything the user hasn't customized. Update it with UpdateTipCard. TipCardCustomization tip_card_customization = 7 [(validate.rules).message.required = true]; + + // The minimum fee another user must pay to initialize a DM chat with this + // user. Public, so it is returned for any user, not just the caller. Unset + // when the user hasn't set one, in which case the server default applies. + // Update it with SetMinDmChatInitFee. + common.v1.FiatPaymentAmount min_dm_chat_init_fee = 10; } message SocialProfile { diff --git a/proto/profile/v1/profile_service.proto b/proto/profile/v1/profile_service.proto index fb9be2f..235d1ea 100644 --- a/proto/profile/v1/profile_service.proto +++ b/proto/profile/v1/profile_service.proto @@ -34,6 +34,10 @@ service Profile { // optional; only the ones set in the request are changed. rpc UpdateTipCard(UpdateTipCardRequest) returns (UpdateTipCardResponse); + // SetMinDmChatInitFee sets the minimum fee another user must pay to + // initialize a DM chat with the caller, replacing any fee already set. + rpc SetMinDmChatInitFee(SetMinDmChatInitFeeRequest) returns (SetMinDmChatInitFeeResponse); + // LinkSocialAccount links a social account to a user rpc LinkSocialAccount(LinkSocialAccountRequest) returns (LinkSocialAccountResponse); @@ -160,6 +164,22 @@ message UpdateTipCardResponse { } } +message SetMinDmChatInitFeeRequest { + // The new minimum DM chat initialization fee to set. + common.v1.FiatPaymentAmount min_dm_chat_init_fee = 1 [(validate.rules).message.required = true]; + + common.v1.Auth auth = 10 [(validate.rules).message.required = true]; +} + +message SetMinDmChatInitFeeResponse { + Result result = 1; + enum Result { + OK = 0; + DENIED = 1; + INVALID_AMOUNT = 2; // e.g. unsupported currency, or amount outside the allowed range + } +} + message LinkSocialAccountRequest { LinkingToken linking_token = 1 [(validate.rules).message.required = true]; From 1eda95e95f72518ac82cb56b3ee04960ee745950 Mon Sep 17 00:00:00 2001 From: Brandon McAnsh Date: Thu, 27 Aug 2026 12:19:44 -0400 Subject: [PATCH 2/2] docs(changelog): describe 0.2.0 for consumers --- CHANGELOG.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1935aa9..96e480e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,28 @@ called out explicitly even when nothing else did. release notes, so a version with no entry here does not release. Write the entry in the same PR that syncs the contract, while the diff is still in front of you. +## 0.2.0 + +Synced to [`flipcash2-protobuf-api@0300d252`](https://github.com/code-payments/flipcash2-protobuf-api/commit/0300d252f35f3524e067aeef22382012c754902a). + +### Added + +- `SetMinDmChatInitFee` on the `profile.v1.Profile` service, setting the minimum fee another user + must pay to initialize a DM chat with the caller. `SetMinDmChatInitFeeRequest` takes the new fee as + a required `common.v1.FiatPaymentAmount` on field 1 and the usual required `common.v1.Auth` on + field 10. It replaces whatever fee was already set rather than merging into it. + + `SetMinDmChatInitFeeResponse.Result` is a new enum: `OK`, `DENIED`, and `INVALID_AMOUNT`, the last + covering an unsupported currency or an amount outside the allowed range. + +- `min_dm_chat_init_fee` on `profile.v1.UserProfile`, a `common.v1.FiatPaymentAmount` on field 10. + It is public, so it comes back for any user rather than only the caller, and it is unset when the + user has not set a fee, in which case the server default applies. + +Nothing existing changed. No field number or enum value moved, and `SetMinDmChatInitFeeResponse.Result` +is a new enum rather than a case added to an existing one, so upgrading from `0.1.0` needs no consumer +changes. + ## 0.1.0 First release. The Flipcash contract is now generated once here and published for both platforms,